Merge pull request #2334 from LibreELEC/rockchip

Add Rockchip project
This commit is contained in:
Radostan Riedel 2018-03-05 06:41:45 +01:00 committed by GitHub
commit 95b9e1ff97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
73 changed files with 53377 additions and 3 deletions

View File

@ -31,7 +31,7 @@
TARGET_FPU_FLAGS="-mfloat-abi=$TARGET_FLOAT -mfpu=$TARGET_FPU"
SIMD_SUPPORT="no"
;;
cortex-a7|cortex-a15|cortex-a15.cortex-a7|cortex-a17.cortex-a7)
cortex-a7|cortex-a15|cortex-a17|cortex-a15.cortex-a7|cortex-a17.cortex-a7)
TARGET_SUBARCH=armv7ve
TARGET_ABI=eabi
TARGET_EXTRA_FLAGS="-mcpu=$TARGET_CPU"
@ -45,7 +45,7 @@
TARGET_FPU_FLAGS="-mfloat-abi=$TARGET_FLOAT -mfpu=$TARGET_FPU"
SIMD_SUPPORT="yes"
;;
cortex-a53)
cortex-a53|cortex-a72.cortex-a53)
TARGET_SUBARCH=armv8-a
TARGET_ABI=eabi
TARGET_EXTRA_FLAGS="-mcpu=${TARGET_CPU}"

View File

@ -0,0 +1,111 @@
################################################################################
# This file is part of LibreELEC - https://libreelec.tv
# Copyright (C) 2017-present Team LibreELEC
#
# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LibreELEC. If not, see <http://www.gnu.org/licenses/>.
################################################################################
PKG_NAME="mali-rockchip"
PKG_VERSION="12daf22"
PKG_SHA256="e6004e0f5a8a4aba098d301b3f964e2a9a961bb79f180d55ea6e9e73cd6eb874"
PKG_ARCH="arm aarch64"
PKG_LICENSE="nonfree"
PKG_SITE="https://github.com/rockchip-linux/libmali"
PKG_URL="https://github.com/rockchip-linux/libmali/archive/$PKG_VERSION.tar.gz"
PKG_SOURCE_DIR="libmali-$PKG_VERSION*"
PKG_SECTION="graphics"
PKG_SHORTDESC="mali-rockchip: OpenGL ES user-space binary for the ARM Mali GPU family"
PKG_LONGDESC="mali-rockchip: OpenGL ES user-space binary for the ARM Mali GPU family"
PKG_TOOLCHAIN="manual"
if [ "$TARGET_ARCH" = "arm" ]; then
PKG_MALI_ARCH="arm-linux-gnueabihf"
elif [ "$TARGET_ARCH" = "aarch64" ]; then
PKG_MALI_ARCH="aarch64-linux-gnu"
fi
if [ "$DISPLAYSERVER" = "x11" ]; then
PKG_MALI_SUFFIX=""
elif [ "$DISPLAYSERVER" = "weston" ]; then
PKG_MALI_SUFFIX="-wayland"
else
PKG_MALI_SUFFIX="-gbm"
fi
if [ "$MALI_FAMILY" = "t760" -a "$MALI_REVISION" = "r1p0" ]; then
PKG_MALI_FILE="libmali-midgard-t76x-r14p0-r1p0$PKG_MALI_SUFFIX.so"
elif [ "$MALI_FAMILY" = "t760" ]; then
PKG_MALI_FILE="libmali-midgard-t76x-r14p0-r0p0$PKG_MALI_SUFFIX.so"
elif [ "$MALI_FAMILY" = "t860" ]; then
PKG_MALI_FILE="libmali-midgard-t86x-r14p0$PKG_MALI_SUFFIX.so"
elif [ "$MALI_FAMILY" = "450" ]; then
PKG_MALI_FILE="libmali-utgard-450-r7p0$PKG_MALI_SUFFIX.so"
elif [ "$MALI_FAMILY" = "400" ]; then
PKG_MALI_FILE="libmali-utgard-400-r7p0$PKG_MALI_SUFFIX.so"
else
echo "ERROR: Unknown MALI_FAMILY '$MALI_FAMILY', aborting."
exit 1
fi
configure_target() {
if [ ! -f "$PKG_BUILD/lib/$PKG_MALI_ARCH/$PKG_MALI_FILE" ]; then
echo "ERROR: $PKG_MALI_ARCH/$PKG_MALI_FILE does not exist, aborting."
exit 1
fi
}
makeinstall_target() {
cd $PKG_BUILD
mkdir -p $SYSROOT_PREFIX/usr/include
cp -PRv include/EGL $SYSROOT_PREFIX/usr/include
cp -PRv include/GLES $SYSROOT_PREFIX/usr/include
cp -PRv include/GLES2 $SYSROOT_PREFIX/usr/include
if [ "$MALI_FAMILY" = "t760" -o "$MALI_FAMILY" = "t860" ]; then
cp -PRv include/GLES3 $SYSROOT_PREFIX/usr/include
fi
cp -PRv include/KHR $SYSROOT_PREFIX/usr/include
cp -PRv include/gbm.h $SYSROOT_PREFIX/usr/include
mkdir -p $SYSROOT_PREFIX/usr/lib/pkgconfig
cp -PRv $PKG_DIR/pkgconfig/*.pc $SYSROOT_PREFIX/usr/lib/pkgconfig
if [ "$DISPLAYSERVER" != "weston" ]; then
rm -fv $SYSROOT_PREFIX/usr/lib/pkgconfig/wayland-egl.pc
fi
mkdir -p $SYSROOT_PREFIX/usr/lib
cp -PRv lib/$PKG_MALI_ARCH/$PKG_MALI_FILE $SYSROOT_PREFIX/usr/lib
ln -sfv $PKG_MALI_FILE $SYSROOT_PREFIX/usr/lib/libmali.so
ln -sfv libmali.so $SYSROOT_PREFIX/usr/lib/libMali.so
ln -sfv libmali.so $SYSROOT_PREFIX/usr/lib/libEGL.so
ln -sfv libmali.so $SYSROOT_PREFIX/usr/lib/libGLESv2.so
ln -sfv libmali.so $SYSROOT_PREFIX/usr/lib/libgbm.so
mkdir -p $INSTALL/usr/lib
cp -PRv lib/$PKG_MALI_ARCH/$PKG_MALI_FILE $INSTALL/usr/lib
ln -sfv $PKG_MALI_FILE $INSTALL/usr/lib/libmali.so
ln -sfv libmali.so $INSTALL/usr/lib/libMali.so
ln -sfv libmali.so $INSTALL/usr/lib/libEGL.so
ln -sfv libmali.so $INSTALL/usr/lib/libEGL.so.1
ln -sfv libmali.so $INSTALL/usr/lib/libGLESv2.so
ln -sfv libmali.so $INSTALL/usr/lib/libGLESv2.so.2
ln -sfv libmali.so $INSTALL/usr/lib/libgbm.so
mkdir -p $INSTALL/usr/lib/modules-load.d
if [ "$MALI_FAMILY" = "t760" -o "$MALI_FAMILY" = "t860" ]; then
echo "midgard_kbase" > $INSTALL/usr/lib/modules-load.d/mali.conf
elif [ "$MALI_FAMILY" = "450" -o "$MALI_FAMILY" = "400" ]; then
echo "mali" > $INSTALL/usr/lib/modules-load.d/mali.conf
fi
}

View File

@ -0,0 +1,12 @@
prefix=/usr
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: egl
Description: ARM Mali implementation of EGL
Version: 1.5
Requires:
Libs: -L${libdir} -lEGL
Libs.private: -lm -lpthread
Cflags: -I${includedir}

View File

@ -0,0 +1,12 @@
prefix=/usr
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: gbm
Description: Mali GBM library
Requires.private:
Version: 10.4.0
Libs: -L${libdir} -lgbm
Libs.private:
Cflags: -I${includedir}

View File

@ -0,0 +1,12 @@
prefix=/usr
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: glesv2
Description: ARM Mali implementation of OpenGL ESv2
Version: 2.0
Requires:
Libs: -L${libdir} -lGLESv2
Libs.private: -lm -lpthread
Cflags: -I${includedir}

View File

@ -0,0 +1,12 @@
prefix=/usr
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: wayland-egl
Description: Mali EGL library
Requires.private:
Version: 7.10
Libs: -L${libdir} -lMali
Libs.private: -lm -lpthread
Cflags: -I${includedir}

View File

@ -0,0 +1 @@
options bcmdhd firmware_path=/lib/firmware/brcm/ nvram_path=/lib/firmware/brcm/

View File

@ -0,0 +1,42 @@
################################################################################
# This file is part of LibreELEC - https://libreelec.tv
# Copyright (C) 2017-present Team LibreELEC
#
# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LibreELEC. If not, see <http://www.gnu.org/licenses/>.
################################################################################
PKG_NAME="rockchip-firmware"
PKG_VERSION="firmware"
PKG_ARCH="arm aarch64"
PKG_LICENSE="nonfree"
PKG_SITE="https://github.com/rockchip-linux"
PKG_URL=""
PKG_DEPENDS_TARGET="rkbin rfkill"
PKG_SECTION="firmware"
PKG_SHORTDESC="rockchip firmware"
PKG_LONGDESC="rockchip firmware"
PKG_TOOLCHAIN="manual"
makeinstall_target() {
mkdir -p $INSTALL/usr/bin
cp -v $(get_build_dir rkbin)/firmware/bin/rtk_hciattach $INSTALL/usr/bin
mkdir -p $INSTALL/$(get_full_firmware_dir)/rtlbt
cp -v $(get_build_dir rkbin)/firmware/bluetooth/rtl8723b_* $INSTALL/$(get_full_firmware_dir)/rtlbt
mkdir -p $INSTALL/$(get_full_firmware_dir)/brcm
cp -v $(get_build_dir rkbin)/firmware/bluetooth/BCM4354A2.hcd $INSTALL/$(get_full_firmware_dir)/brcm
cp -v $(get_build_dir rkbin)/firmware/wifi/fw_bcm4356a2_ag.bin $INSTALL/$(get_full_firmware_dir)/brcm
cp -v $(get_build_dir rkbin)/firmware/wifi/nvram_ap6356.txt $INSTALL/$(get_full_firmware_dir)/brcm
}

View File

@ -0,0 +1,11 @@
[Unit]
Description=Attach /dev/ttyS0 to BlueZ stack using %I protocol
Wants=bluetooth.service
Before=bluetooth.service
After=dev-ttyS0.device
[Service]
Type=simple
ExecStartPre=/usr/sbin/rfkill unblock bluetooth
ExecStart=/usr/bin/btattach -B /dev/ttyS0 -P %I
ExecStopPost=/usr/sbin/rfkill block bluetooth

View File

@ -0,0 +1,11 @@
[Unit]
Description=Attach /dev/ttyS0 to BlueZ stack
Wants=bluetooth.service
Before=bluetooth.service
After=dev-ttyS0.device
[Service]
Type=simple
ExecStartPre=/usr/sbin/rfkill unblock bluetooth
ExecStart=/usr/bin/rtk_hciattach -n -s 115200 ttyS0 rtk_h5
ExecStopPost=/usr/sbin/rfkill block bluetooth

View File

@ -0,0 +1,11 @@
[Unit]
Description=Attach /dev/ttyS0 to BlueZ stack using %I type
Wants=bluetooth.service
Before=bluetooth.service
After=dev-ttyS0.device
[Service]
Type=simple
ExecStartPre=/usr/sbin/rfkill unblock bluetooth
ExecStart=/usr/bin/hciattach -n -s 115200 ttyS0 %I
ExecStopPost=/usr/sbin/rfkill block bluetooth

View File

@ -0,0 +1,12 @@
################################################################################
# udev rules file for loading rockchip-firmware
################################################################################
ACTION!="add", GOTO="end"
SUBSYSTEMS=="sdio", ATTRS{vendor}=="0x024c", ATTRS{device}=="0xb723", \
TAG+="systemd", ENV{SYSTEMD_WANTS}+="hciattach-realtek.service"
SUBSYSTEMS=="sdio", ATTRS{vendor}=="0x024c", ATTRS{device}=="0x0626", \
TAG+="systemd", ENV{SYSTEMD_WANTS}+="hciattach-realtek.service"
SUBSYSTEMS=="sdio", ATTRS{vendor}=="0x02d0", ATTRS{device}=="0x4356", \
TAG+="systemd", ENV{SYSTEMD_WANTS}+="hciattach@bcm43xx.service"
LABEL="end"

View File

@ -46,6 +46,13 @@ case "$LINUX" in
PKG_PATCH_DIRS="amlogic-3.14"
PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET aml-dtbtools:host"
;;
rockchip-4.4)
PKG_VERSION="eae92ae2"
PKG_SHA256="da453ca6ecefc3719a1165bc7b08fe00fc2b50ab64f6289ef6f3670a9fc1ceca"
PKG_URL="https://github.com/rockchip-linux/kernel/archive/$PKG_VERSION.tar.gz"
PKG_SOURCE_DIR="kernel-$PKG_VERSION*"
PKG_PATCH_DIRS="rockchip-4.4"
;;
*)
PKG_VERSION="4.14.20"
PKG_SHA256="4ab7f42aa6af9c1e3b00cba6b1fa305a87407666aaa2fae555f7fbdaafb6d292"

View File

@ -189,7 +189,7 @@ if [ ! "$KODIPLAYER_DRIVER" = default ]; then
PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET $KODIPLAYER_DRIVER"
if [ "$KODIPLAYER_DRIVER" = bcm2835-driver ]; then
KODI_PLAYER="-DCORE_PLATFORM_NAME=rbpi"
elif [ "$KODIPLAYER_DRIVER" = mesa ]; then
elif [ "$KODIPLAYER_DRIVER" = mesa -o "$KODIPLAYER_DRIVER" = rkmpp ]; then
KODI_PLAYER="-DCORE_PLATFORM_NAME=gbm"
CFLAGS="$CFLAGS -DMESA_EGL_NO_X11_HEADERS"
CXXFLAGS="$CXXFLAGS -DMESA_EGL_NO_X11_HEADERS"

View File

@ -47,6 +47,13 @@ else
FFMPEG_VDPAU="--disable-vdpau"
fi
if [ "$PROJECT" = "Rockchip" ]; then
PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET rkmpp"
FFMPEG_RKMPP="--enable-rkmpp --enable-libdrm --enable-version3"
else
FFMPEG_RKMPP="--disable-rkmpp"
fi
if build_with_debug; then
FFMPEG_DEBUG="--enable-debug --disable-stripping"
else
@ -149,6 +156,7 @@ configure_target() {
$FFMPEG_VAAPI \
$FFMPEG_VDPAU \
$FFMPEG_RPI \
$FFMPEG_RKMPP \
--disable-dxva2 \
--enable-runtime-cpudetect \
$FFMPEG_TABLES \

View File

@ -0,0 +1,168 @@
From ed4a91d4f4bd7ab99f2be901285b20a0cde52902 Mon Sep 17 00:00:00 2001
From: LongChair <longchair@hotmail.com>
Date: Sat, 6 Jan 2018 09:36:58 +0100
Subject: [PATCH] avcodec/rkmpp : Fix broken build due to missing control
operation
This patch is taking care of https://trac.ffmpeg.org/ticket/6834.
It seems that one of the control operations that was available to get
the free decoders input slots was removed.
There is another control operation to retrieve the used slots. Given
that the input slot count is hardcoded to 4 in mpp at this point,
replacing the old control operation by the other one.
This was tested on Rockchip ROCK64.
Signed-off-by: wm4 <nfxjfg@googlemail.com>
(cherry picked from commit c6f84106366c6f243a8b07dbffcc7880009aa904)
---
configure | 6 ++----
libavcodec/rkmppdec.c | 10 ++++++----
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/configure b/configure
index 1797c5dd4f..4db1c9b73f 100755
--- a/configure
+++ b/configure
@@ -6077,10 +6077,8 @@ enabled openssl && { use_pkg_config openssl openssl openssl/ssl.h OPEN
check_lib openssl openssl/ssl.h SSL_library_init -lssl32 -leay32 ||
check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 ||
die "ERROR: openssl not found"; }
-enabled rkmpp && { { require_pkg_config rockchip_mpp rockchip_mpp rockchip/rk_mpi.h mpp_create ||
- die "ERROR : Rockchip MPP was not found."; } &&
- { check_func_headers rockchip/rk_mpi_cmd.h "MPP_DEC_GET_FREE_PACKET_SLOT_COUNT" ||
- die "ERROR: Rockchip MPP is outdated, please get a more recent one."; } &&
+enabled rkmpp && { require_pkg_config rkmpp rockchip_mpp rockchip/rk_mpi.h mpp_create &&
+ require_pkg_config rockchip_mpp "rockchip_mpp >= 1.3.7" rockchip/rk_mpi.h mpp_create &&
{ enabled libdrm ||
die "ERROR: rkmpp requires --enable-libdrm"; }
}
diff --git a/libavcodec/rkmppdec.c b/libavcodec/rkmppdec.c
index bdf4dc4208..ebc021e3d8 100644
--- a/libavcodec/rkmppdec.c
+++ b/libavcodec/rkmppdec.c
@@ -39,6 +39,7 @@
#define RECEIVE_FRAME_TIMEOUT 100
#define FRAMEGROUP_MAX_FRAMES 16
+#define INPUT_MAX_PACKETS 4
typedef struct {
MppCtx ctx;
@@ -514,16 +515,17 @@ static int rkmpp_receive_frame(AVCodecContext *avctx, AVFrame *frame)
RKMPPDecoder *decoder = (RKMPPDecoder *)rk_context->decoder_ref->data;
int ret = MPP_NOK;
AVPacket pkt = {0};
- RK_S32 freeslots;
+ RK_S32 usedslots, freeslots;
if (!decoder->eos_reached) {
// we get the available slots in decoder
- ret = decoder->mpi->control(decoder->ctx, MPP_DEC_GET_FREE_PACKET_SLOT_COUNT, &freeslots);
+ ret = decoder->mpi->control(decoder->ctx, MPP_DEC_GET_STREAM_COUNT, &usedslots);
if (ret != MPP_OK) {
- av_log(avctx, AV_LOG_ERROR, "Failed to get decoder free slots (code = %d).\n", ret);
+ av_log(avctx, AV_LOG_ERROR, "Failed to get decoder used slots (code = %d).\n", ret);
return ret;
}
+ freeslots = INPUT_MAX_PACKETS - usedslots;
if (freeslots > 0) {
ret = ff_decode_get_packet(avctx, &pkt);
if (ret < 0 && ret != AVERROR_EOF) {
@@ -540,7 +542,7 @@ static int rkmpp_receive_frame(AVCodecContext *avctx, AVFrame *frame)
}
// make sure we keep decoder full
- if (freeslots > 1 && decoder->first_frame)
+ if (freeslots > 1)
return AVERROR(EAGAIN);
}
From 617c895d27198bb9391a001932e288d1dfe4f728 Mon Sep 17 00:00:00 2001
From: LongChair <longchair@hotmail.com>
Date: Tue, 2 Jan 2018 12:38:01 +0100
Subject: [PATCH] avcodec/rkmpp : remove stream start retries before first
frame.
those were needed because of some odd mpp behavior that seems to have
been fixed.
Makes the code cleaner.
Signed-off-by: wm4 <nfxjfg@googlemail.com>
(cherry picked from commit 2ca65fc7b74444edd51d5803a2c1e05a801a6023)
---
libavcodec/rkmppdec.c | 24 +++---------------------
1 file changed, 3 insertions(+), 21 deletions(-)
diff --git a/libavcodec/rkmppdec.c b/libavcodec/rkmppdec.c
index ebc021e3d8..9dfeb742ab 100644
--- a/libavcodec/rkmppdec.c
+++ b/libavcodec/rkmppdec.c
@@ -46,7 +46,6 @@ typedef struct {
MppApi *mpi;
MppBufferGroup frame_group;
- char first_frame;
char first_packet;
char eos_reached;
@@ -328,28 +327,14 @@ static int rkmpp_retrieve_frame(AVCodecContext *avctx, AVFrame *frame)
MppBuffer buffer = NULL;
AVDRMFrameDescriptor *desc = NULL;
AVDRMLayerDescriptor *layer = NULL;
- int retrycount = 0;
int mode;
MppFrameFormat mppformat;
uint32_t drmformat;
- // on start of decoding, MPP can return -1, which is supposed to be expected
- // this is due to some internal MPP init which is not completed, that will
- // only happen in the first few frames queries, but should not be interpreted
- // as an error, Therefore we need to retry a couple times when we get -1
- // in order to let it time to complete it's init, then we sleep a bit between retries.
-retry_get_frame:
ret = decoder->mpi->decode_get_frame(decoder->ctx, &mppframe);
- if (ret != MPP_OK && ret != MPP_ERR_TIMEOUT && !decoder->first_frame) {
- if (retrycount < 5) {
- av_log(avctx, AV_LOG_DEBUG, "Failed to get a frame, retrying (code = %d, retrycount = %d)\n", ret, retrycount);
- usleep(10000);
- retrycount++;
- goto retry_get_frame;
- } else {
- av_log(avctx, AV_LOG_ERROR, "Failed to get a frame from MPP (code = %d)\n", ret);
- goto fail;
- }
+ if (ret != MPP_OK && ret != MPP_ERR_TIMEOUT) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to get a frame from MPP (code = %d)\n", ret);
+ goto fail;
}
if (mppframe) {
@@ -365,7 +350,6 @@ retry_get_frame:
avctx->height = mpp_frame_get_height(mppframe);
decoder->mpi->control(decoder->ctx, MPP_DEC_SET_INFO_CHANGE_READY, NULL);
- decoder->first_frame = 1;
av_buffer_unref(&decoder->frames_ref);
@@ -479,7 +463,6 @@ retry_get_frame:
goto fail;
}
- decoder->first_frame = 0;
return 0;
} else {
av_log(avctx, AV_LOG_ERROR, "Failed to retrieve the frame buffer, frame is dropped (code = %d)\n", ret);
@@ -559,7 +542,6 @@ static void rkmpp_flush(AVCodecContext *avctx)
ret = decoder->mpi->reset(decoder->ctx);
if (ret == MPP_OK) {
- decoder->first_frame = 1;
decoder->first_packet = 1;
} else
av_log(avctx, AV_LOG_ERROR, "Failed to reset MPI (code = %d)\n", ret);

View File

@ -0,0 +1,48 @@
################################################################################
# This file is part of LibreELEC - https://libreelec.tv
# Copyright (C) 2017-present Team LibreELEC
#
# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LibreELEC. If not, see <http://www.gnu.org/licenses/>.
################################################################################
PKG_NAME="rkmpp"
PKG_VERSION="c8a41a6"
PKG_SHA256="01b84eecde7cae98035ecce866b48f903f9deaa7e19b048ff9cb87edf6446659"
PKG_ARCH="arm aarch64"
PKG_LICENSE="APL"
PKG_SITE="https://github.com/rockchip-linux/mpp"
PKG_URL="https://github.com/rockchip-linux/mpp/archive/$PKG_VERSION.tar.gz"
PKG_SOURCE_DIR="mpp-$PKG_VERSION*"
PKG_DEPENDS_TARGET="toolchain libdrm"
PKG_SECTION="multimedia"
PKG_SHORTDESC="rkmpp: Rockchip Media Process Platform (MPP) module"
PKG_LONGDESC="rkmpp: Rockchip Media Process Platform (MPP) module"
if [ "$DEVICE" = "RK3328" -o "$DEVICE" = "RK3399" ]; then
PKG_ENABLE_VP9D="ON"
else
PKG_ENABLE_VP9D="OFF"
fi
PKG_CMAKE_OPTS_TARGET="-DRKPLATFORM=ON \
-DENABLE_AVSD=OFF \
-DENABLE_H263D=OFF \
-DENABLE_H264D=ON \
-DENABLE_H265D=ON \
-DENABLE_MPEG2D=ON \
-DENABLE_MPEG4D=ON \
-DENABLE_VP8D=ON \
-DENABLE_VP9D=$PKG_ENABLE_VP9D \
-DENABLE_JPEGD=OFF \
-DHAVE_DRM=ON"

View File

@ -0,0 +1,30 @@
From e9c9f2619bb2344f9947ccbbdcf15be9d0f55b1f Mon Sep 17 00:00:00 2001
From: Jakob Unterwurzacher <jakob.unterwurzacher@theobroma-systems.com>
Date: Mon, 29 May 2017 14:08:43 +0200
Subject: [PATCH] fix 32-bit mmap issue on 64-bit kernels
Running 32-bit userland on a 64-bit kernel resulted in the error:
mpp_drm: mmap failed: Invalid argument
Both the pagesize_mask and the mmap call truncated the offset
value to 32 bit. This patch fixes both issues.
For details see https://github.com/rockchip-linux/kernel/issues/17
---
osal/allocator/allocator_drm.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/osal/allocator/allocator_drm.c b/osal/allocator/allocator_drm.c
index 48735c90..a3a16a55 100644
--- a/osal/allocator/allocator_drm.c
+++ b/osal/allocator/allocator_drm.c
@@ -15,6 +15,8 @@
*/
#define MODULE_TAG "mpp_drm"
+/* Enable 64-bit mmap also when compiling for 32 bit */
+#define _FILE_OFFSET_BITS 64
#include <unistd.h>
#include <string.h>

View File

@ -0,0 +1,25 @@
From 322efafd1f760c73accda1a7025b007f211916f7 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Sat, 3 Mar 2018 10:10:01 +0100
Subject: [PATCH] [mpp_dec]: sleep when there is nothing to parse
---
mpp/codec/mpp_dec.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/mpp/codec/mpp_dec.cpp b/mpp/codec/mpp_dec.cpp
index 424604e1..dded58c6 100644
--- a/mpp/codec/mpp_dec.cpp
+++ b/mpp/codec/mpp_dec.cpp
@@ -600,8 +600,10 @@ void *mpp_dec_parser_thread(void *data)
}
parser->unlock();
- if (try_proc_dec_task(mpp, &task))
+ if (try_proc_dec_task(mpp, &task)) {
+ msleep(1);
continue;
+ }
}

View File

@ -0,0 +1,25 @@
diff --git a/mpp/hal/rkdec/h265d/hal_h265d_reg.h b/mpp/hal/rkdec/h265d/hal_h265d_reg.h
index 1bccb02..432b8db 100644
--- a/mpp/hal/rkdec/h265d/hal_h265d_reg.h
+++ b/mpp/hal/rkdec/h265d/hal_h265d_reg.h
@@ -50,7 +50,8 @@ typedef struct {
struct swreg_int {
RK_U32 sw_dec_e : 1 ;
RK_U32 sw_dec_clkgate_e : 1 ;
- RK_U32 reserve0 : 2 ;
+ RK_U32 reserve0 : 1 ;
+ RK_U32 sw_timeout_mode : 1 ;
RK_U32 sw_dec_irq_dis : 1 ;
RK_U32 sw_dec_timeout_e : 1 ;
RK_U32 sw_buf_empty_en : 1 ;
@@ -61,8 +62,9 @@ typedef struct {
RK_U32 sw_dec_rdy_sta : 1 ;
RK_U32 sw_dec_bus_sta : 1 ;
RK_U32 sw_dec_error_sta : 1 ;
+ RK_U32 sw_dec_timeout_sta : 1 ;
RK_U32 sw_dec_empty_sta : 1 ;
- RK_U32 reserve4 : 4 ;
+ RK_U32 reserve3 : 3 ;
RK_U32 sw_softrst_en_p : 1 ;
RK_U32 sw_force_softreset_valid: 1 ;
RK_U32 sw_softreset_rdy : 1 ;

View File

@ -0,0 +1,29 @@
################################################################################
# This file is part of LibreELEC - https://libreelec.tv
# Copyright (C) 2017-present Team LibreELEC
#
# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LibreELEC. If not, see <http://www.gnu.org/licenses/>.
################################################################################
PKG_NAME="rfkill"
PKG_VERSION="0.5"
PKG_SHA256="e0ae3004215e39a6c5c36e0726558740728d16f67ebdb8bea621250f6091d86a"
PKG_ARCH="any"
PKG_LICENSE="GPL"
PKG_SITE="https://wireless.wiki.kernel.org/en/users/documentation/rfkill"
PKG_URL="https://www.kernel.org/pub/software/network/rfkill/$PKG_NAME-$PKG_VERSION.tar.xz"
PKG_DEPENDS_TARGET="toolchain"
PKG_SECTION="network"
PKG_SHORTDESC="rfkill: userspace tool to query the state of the rfkill switches, buttons and subsystem interfaces"
PKG_LONGDESC="rfkill is a small userspace tool to query the state of the rfkill switches, buttons and subsystem interfaces."

View File

@ -0,0 +1,23 @@
diff -Naur a/version.sh b/version.sh
--- a/version.sh
+++ b/version.sh
@@ -12,19 +12,6 @@
if test "x$SUFFIX" != 'x'; then
v="$VERSION$SUFFIX"
-elif head=`git rev-parse --verify HEAD 2>/dev/null`; then
- git update-index --refresh --unmerged > /dev/null
- descr=$(git describe 2>/dev/null || echo "v$VERSION")
-
- # on git builds check that the version number above
- # is correct...
- [ "${descr%%-*}" = "v$VERSION" ] || exit 2
-
- echo -n 'const char rfkill_version[] = "' > "$OUT"
- v="${descr#v}"
- if git diff-index --name-only HEAD | read dummy ; then
- v="$v"-dirty
- fi
else
v="$VERSION"
fi

View File

@ -0,0 +1,30 @@
################################################################################
# This file is part of LibreELEC - https://libreelec.tv
# Copyright (C) 2017-present Team LibreELEC
#
# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LibreELEC. If not, see <http://www.gnu.org/licenses/>.
################################################################################
PKG_NAME="rkbin"
PKG_VERSION="f64ded6"
PKG_SHA256="7b858ac964058da83cd96314184d2c5f834a9b2cc6b805be424a661fd9836b54"
PKG_ARCH="arm aarch64"
PKG_LICENSE="nonfree"
PKG_SITE="https://github.com/rockchip-linux/rkbin"
PKG_URL="https://github.com/rockchip-linux/rkbin/archive/$PKG_VERSION.tar.gz"
PKG_SOURCE_DIR="rkbin-$PKG_VERSION*"
PKG_SECTION="tools"
PKG_SHORTDESC="rkbin: Rockchip Firmware and Tool Binaries"
PKG_LONGDESC="rkbin: Rockchip Firmware and Tool Binaries"
PKG_TOOLCHAIN="manual"

View File

@ -0,0 +1,818 @@
From 10b2468096e88f0c68ec87be8bd26a6f3af53050 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Mon, 25 Dec 2017 15:33:57 +0100
Subject: [PATCH] rk3328: add ddr v1.08 and miniloader v2.44
---
rk33/rk3328_ddr_786MHz_v1.08.bin | Bin 0 -> 23684 bytes
rk33/rk3328_miniloader_v2.44.bin | Bin 0 -> 60164 bytes
2 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 rk33/rk3328_ddr_786MHz_v1.08.bin
create mode 100644 rk33/rk3328_miniloader_v2.44.bin
diff --git a/rk33/rk3328_ddr_786MHz_v1.08.bin b/rk33/rk3328_ddr_786MHz_v1.08.bin
new file mode 100644
index 0000000000000000000000000000000000000000..0b0ffa2ab6bf1553118baac2faf9e3a903664a9e
GIT binary patch
literal 23684
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
Vjt*$Hfn&wxadiFeaO7{1|36XHr^)~T
literal 0
HcmV?d00001
diff --git a/rk33/rk3328_miniloader_v2.44.bin b/rk33/rk3328_miniloader_v2.44.bin
new file mode 100644
index 0000000000000000000000000000000000000000..9663aa598733db25cfc1cfc0b1555f0f8269bfb5
GIT binary patch
literal 60164
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
CP?<Ua
literal 0
HcmV?d00001

File diff suppressed because it is too large Load Diff

View File

@ -32,6 +32,14 @@ PKG_NEED_UNPACK="$PROJECT_DIR/$PROJECT/bootloader"
[ -n "$DEVICE" ] && PKG_NEED_UNPACK+=" $PROJECT_DIR/$PROJECT/devices/$DEVICE/bootloader"
case "$PROJECT" in
Rockchip)
PKG_VERSION="5ecf0ee"
PKG_SHA256="fba1d26583d446a5bbb5713fe37848e05b546d125384c2c2d2883414d61b7cad"
PKG_URL="https://github.com/rockchip-linux/u-boot/archive/$PKG_VERSION.tar.gz"
PKG_PATCH_DIRS="rockchip"
PKG_DEPENDS_TARGET+=" rkbin"
PKG_NEED_UNPACK+=" $(get_pkg_directory rkbin)"
;;
*)
PKG_VERSION="2017.09"
PKG_SHA256="b2d15f2cf5f72e706025cde73d67247c6da8cd35f7e10891eefe7d9095089744"

View File

@ -0,0 +1,75 @@
From 85f5dd7511d2eaea04a6ba53dc60d1879060568b Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Sat, 2 Dec 2017 11:47:07 +0100
Subject: [PATCH] dont build libfdt
---
Makefile | 2 +-
scripts/Makefile.spl | 4 ++--
tools/Makefile | 4 ----
tools/dtoc/fdt.py | 2 +-
4 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/Makefile b/Makefile
index 8086f3c93e..4796b488ae 100644
--- a/Makefile
+++ b/Makefile
@@ -1379,7 +1379,7 @@ $(timestamp_h): $(srctree)/Makefile FORCE
$(call filechk,timestamp.h)
checkbinman: tools
- @if ! ( echo 'import libfdt' | ( PYTHONPATH=tools $(PYTHON) )); then \
+ @if ! ( echo 'from pylibfdt import libfdt' | ( python )); then \
echo >&2; \
echo >&2 '*** binman needs the Python libfdt library.'; \
echo >&2 '*** Either install it on your system, or try:'; \
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
index b86ea76bab..ea54f9098c 100644
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -246,7 +246,7 @@ quiet_cmd_fdtgrep = FDTGREP $@
$(obj)/$(SPL_BIN).dtb: dts/dt.dtb $(objtree)/tools/fdtgrep FORCE
$(call if_changed,fdtgrep)
-pythonpath = PYTHONPATH=tools
+pythonpath = python
quiet_cmd_dtocc = DTOC C $@
cmd_dtocc = $(pythonpath) $(srctree)/tools/dtoc/dtoc -d $(obj)/$(SPL_BIN).dtb -o $@ platdata
@@ -370,7 +370,7 @@ ifneq ($(cmd_files),)
endif
checkdtoc: tools
- @if ! ( echo 'import libfdt' | ( PYTHONPATH=tools $(PYTHON) )); then \
+ @if ! ( echo 'from pylibfdt import libfdt' | ( python )); then \
echo '*** dtoc needs the Python libfdt library. Either '; \
echo '*** install it on your system, or try:'; \
echo '***'; \
diff --git a/tools/Makefile b/tools/Makefile
index 8e1009bf6c..459c71ef1f 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -232,10 +232,6 @@ clean-dirs := lib common
always := $(hostprogs-y)
-# Build a libfdt Python module if swig is available
-# Use 'sudo apt-get install swig libpython-dev' to enable this
-always += $(if $(shell which swig 2> /dev/null),_libfdt.so)
-
# Generated LCD/video logo
LOGO_H = $(objtree)/include/bmp_logo.h
LOGO_DATA_H = $(objtree)/include/bmp_logo_data.h
diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py
index dbc338653b..04f3c5935c 100644
--- a/tools/dtoc/fdt.py
+++ b/tools/dtoc/fdt.py
@@ -10,7 +10,7 @@ import struct
import sys
import fdt_util
-import libfdt
+from pylibfdt import libfdt
# This deals with a device tree, presenting it as an assortment of Node and
# Prop objects, representing nodes and properties, respectively. This file

View File

@ -0,0 +1,25 @@
From 39dfedae58057500912a6f933fced3edb9376b3b Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Sun, 22 Oct 2017 12:48:24 +0200
Subject: [PATCH] rockchip: tinker: enable rockchip video driver
---
configs/tinker-rk3288_defconfig | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/configs/tinker-rk3288_defconfig b/configs/tinker-rk3288_defconfig
index 00e2d81954..62cae4f21e 100644
--- a/configs/tinker-rk3288_defconfig
+++ b/configs/tinker-rk3288_defconfig
@@ -80,6 +80,11 @@ CONFIG_G_DNL_PRODUCT_NUM=0x320a
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_ASIX=y
CONFIG_USB_ETHER_SMSC95XX=y
+CONFIG_DM_VIDEO=y
+CONFIG_DISPLAY=y
+CONFIG_VIDEO_ROCKCHIP=y
+CONFIG_DISPLAY_ROCKCHIP_HDMI=y
+CONFIG_CONSOLE_SCROLL_LINES=10
CONFIG_USE_TINY_PRINTF=y
CONFIG_CMD_DHRYSTONE=y
CONFIG_ERRNO_STR=y

View File

@ -0,0 +1,126 @@
From dd6e1ab93a92e133c41a8665f6d8aca9450bdca8 Mon Sep 17 00:00:00 2001
From: Kamil Trzcinski <ayufan@ayufan.eu>
Date: Sun, 20 Aug 2017 01:52:34 +0200
Subject: [PATCH] Add rk3328-efuse support
---
arch/arm/dts/rk3328.dtsi | 25 ++++++++++++++++++++
drivers/misc/rockchip-efuse.c | 55 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 80 insertions(+)
diff --git a/arch/arm/dts/rk3328.dtsi b/arch/arm/dts/rk3328.dtsi
index 2a4c4929d7..611a0d4b21 100644
--- a/arch/arm/dts/rk3328.dtsi
+++ b/arch/arm/dts/rk3328.dtsi
@@ -342,6 +342,31 @@
};
};
+ efuse: efuse@ff260000 {
+ compatible = "rockchip,rk3328-efuse";
+ reg = <0x0 0xff260000 0x0 0x50>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&cru SCLK_EFUSE>;
+ clock-names = "pclk_efuse";
+ rockchip,efuse-size = <0x20>;
+
+ /* Data cells */
+ efuse_id: id@7 {
+ reg = <0x07 0x10>;
+ };
+ cpu_leakage: cpu-leakage@17 {
+ reg = <0x17 0x1>;
+ };
+ logic_leakage: logic-leakage@19 {
+ reg = <0x19 0x1>;
+ };
+ efuse_cpu_version: cpu-version@1a {
+ reg = <0x1a 0x1>;
+ bits = <3 3>;
+ };
+ };
+
saradc: saradc@ff280000 {
compatible = "rockchip,rk3328-saradc", "rockchip,saradc";
reg = <0x0 0xff280000 0x0 0x100>;
diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c
index b4ad19cfe8..81b78f9b2c 100644
--- a/drivers/misc/rockchip-efuse.c
+++ b/drivers/misc/rockchip-efuse.c
@@ -16,6 +16,14 @@
#include <linux/delay.h>
#include <misc.h>
+#define RK3328_INT_CON 0x0014
+#define RK3328_INT_STATUS 0x0018
+#define RK3328_DOUT 0x0020
+#define RK3328_AUTO_CTRL 0x0024
+#define RK3328_INT_FINISH BIT(0)
+#define RK3328_AUTO_ENB BIT(0)
+#define RK3328_AUTO_RD BIT(1)
+
#define RK3399_A_SHIFT 16
#define RK3399_A_MASK 0x3ff
#define RK3399_NFUSES 32
@@ -95,6 +103,49 @@ U_BOOT_CMD(
);
#endif
+static int rockchip_rk3328_efuse_read(struct udevice *dev, int offset,
+ void *buf, int size)
+{
+ struct rockchip_efuse_platdata *plat = dev_get_platdata(dev);
+
+ unsigned int addr_start, addr_end, addr_offset;
+ u32 out_value, status;
+ u8 bytes[RK3399_NFUSES * RK3399_BYTES_PER_FUSE];
+ int i = 0;
+ u32 addr;
+
+ /* 128 Byte efuse, 96 Byte for secure, 32 Byte for non-secure */
+ offset += 96;
+
+ addr_start = offset / RK3399_BYTES_PER_FUSE;
+ addr_offset = offset % RK3399_BYTES_PER_FUSE;
+ addr_end = DIV_ROUND_UP(offset + size, RK3399_BYTES_PER_FUSE);
+
+ /* cap to the size of the efuse block */
+ if (addr_end > RK3399_NFUSES)
+ addr_end = RK3399_NFUSES;
+
+ for (addr = addr_start; addr < addr_end; addr++) {
+ writel(RK3328_AUTO_RD | RK3328_AUTO_ENB |
+ ((addr & RK3399_A_MASK) << RK3399_A_SHIFT),
+ plat->base + RK3328_AUTO_CTRL);
+ udelay(10);
+ status = readl(plat->base + RK3328_INT_STATUS);
+ if (!(status & RK3328_INT_FINISH)) {
+ return -EIO;
+ }
+ out_value = readl(plat->base + RK3328_DOUT);
+ writel(RK3328_INT_FINISH, plat->base + RK3328_INT_STATUS);
+
+ memcpy(&bytes[i], &out_value, RK3399_BYTES_PER_FUSE);
+ i += RK3399_BYTES_PER_FUSE;
+ }
+
+ memcpy(buf, bytes + addr_offset, size);
+
+ return 0;
+}
+
static int rockchip_rk3399_efuse_read(struct udevice *dev, int offset,
void *buf, int size)
{
@@ -223,6 +274,10 @@ static const struct udevice_id rockchip_efuse_ids[] = {
.compatible = "rockchip,rk322x-efuse",
.data = (ulong)&rockchip_rk3288_efuse_read,
},
+ {
+ .compatible = "rockchip,rk3328-efuse",
+ .data = (ulong)rockchip_rk3328_efuse_read,
+ },
{
.compatible = "rockchip,rk3399-efuse",
.data = (ulong)&rockchip_rk3399_efuse_read,

View File

@ -0,0 +1,184 @@
From 77349a847b0649e8ead1dba3a297607b2a674aaa Mon Sep 17 00:00:00 2001
From: Kamil Trzcinski <ayufan@ayufan.eu>
Date: Sat, 19 Aug 2017 20:38:50 +0200
Subject: [PATCH] Get serial and ethaddr from efuse
---
board/rockchip/evb_rk3328/evb-rk3328.c | 124 +++++++++++++++++++++++++++++++++
configs/evb-rk3328_defconfig | 2 +
include/configs/rk3328_common.h | 2 +
3 files changed, 128 insertions(+)
diff --git a/board/rockchip/evb_rk3328/evb-rk3328.c b/board/rockchip/evb_rk3328/evb-rk3328.c
index d6fc57cd8e..1d0f7e9c95 100644
--- a/board/rockchip/evb_rk3328/evb-rk3328.c
+++ b/board/rockchip/evb_rk3328/evb-rk3328.c
@@ -7,14 +7,20 @@
#include <common.h>
#include <asm/arch/hardware.h>
#include <asm/arch/grf_rk3328.h>
+#include <dm.h>
#include <asm/armv8/mmu.h>
#include <asm/io.h>
#include <dwc3-uboot.h>
#include <power/regulator.h>
#include <usb.h>
+#include <misc.h>
+#include <u-boot/sha256.h>
DECLARE_GLOBAL_DATA_PTR;
+#define RK3328_CPUID_OFF 0x7
+#define RK3328_CPUID_LEN 0x10
+
int board_init(void)
{
int ret;
@@ -80,3 +86,121 @@ int board_usb_cleanup(int index, enum usb_init_type init)
return 0;
}
#endif
+
+static void setup_macaddr(void)
+{
+#if CONFIG_IS_ENABLED(CMD_NET)
+ int ret;
+ const char *cpuid = env_get("cpuid#");
+ u8 hash[SHA256_SUM_LEN];
+ int size = sizeof(hash);
+ u8 mac_addr[6];
+
+ /* Only generate a MAC address, if none is set in the environment */
+ if (env_get("ethaddr"))
+ return;
+
+ if (!cpuid) {
+ debug("%s: could not retrieve 'cpuid#'\n", __func__);
+ return;
+ }
+
+ ret = hash_block("sha256", (void *)cpuid, strlen(cpuid), hash, &size);
+ if (ret) {
+ debug("%s: failed to calculate SHA256\n", __func__);
+ return;
+ }
+
+ /* Copy 6 bytes of the hash to base the MAC address on */
+ memcpy(mac_addr, hash, 6);
+
+ /* Make this a valid MAC address and set it */
+ mac_addr[0] &= 0xfe; /* clear multicast bit */
+ mac_addr[0] |= 0x02; /* set local assignment bit (IEEE802) */
+ eth_env_set_enetaddr("ethaddr", mac_addr);
+
+ /* Make a valid MAC address for eth1 */
+ mac_addr[5] += 0x20;
+ mac_addr[5] &= 0xff;
+ eth_env_set_enetaddr("eth1addr", mac_addr);
+#endif
+
+ return;
+}
+
+static void setup_serial(void)
+{
+#if CONFIG_IS_ENABLED(ROCKCHIP_EFUSE)
+ struct udevice *dev;
+ int ret, i;
+ u8 cpuid[RK3328_CPUID_LEN];
+ u8 low[RK3328_CPUID_LEN/2], high[RK3328_CPUID_LEN/2];
+ char cpuid_str[RK3328_CPUID_LEN * 2 + 1];
+ u64 serialno;
+ char serialno_str[16];
+
+ /* retrieve the device */
+ ret = uclass_get_device_by_driver(UCLASS_MISC,
+ DM_GET_DRIVER(rockchip_efuse), &dev);
+ if (ret) {
+ debug("%s: could not find efuse device\n", __func__);
+ return;
+ }
+
+ /* read the cpu_id range from the efuses */
+ ret = misc_read(dev, RK3328_CPUID_OFF, &cpuid, sizeof(cpuid));
+ if (ret) {
+ debug("%s: reading cpuid from the efuses failed\n",
+ __func__);
+ return;
+ }
+
+ memset(cpuid_str, 0, sizeof(cpuid_str));
+ for (i = 0; i < 16; i++)
+ sprintf(&cpuid_str[i * 2], "%02x", cpuid[i]);
+
+ debug("cpuid: %s\n", cpuid_str);
+
+ /*
+ * Mix the cpuid bytes using the same rules as in
+ * ${linux}/drivers/soc/rockchip/rockchip-cpuinfo.c
+ */
+ for (i = 0; i < 8; i++) {
+ low[i] = cpuid[1 + (i << 1)];
+ high[i] = cpuid[i << 1];
+ }
+
+ serialno = crc32_no_comp(0, low, 8);
+ serialno |= (u64)crc32_no_comp(serialno, high, 8) << 32;
+ snprintf(serialno_str, sizeof(serialno_str), "%llx", serialno);
+
+ env_set("cpuid#", cpuid_str);
+ env_set("serial#", serialno_str);
+#endif
+
+ return;
+}
+
+int misc_init_r(void)
+{
+ setup_serial();
+ setup_macaddr();
+
+ return 0;
+}
+
+#ifdef CONFIG_SERIAL_TAG
+void get_board_serial(struct tag_serialnr *serialnr)
+{
+ char *serial_string;
+ u64 serial = 0;
+
+ serial_string = env_get("serial#");
+
+ if (serial_string)
+ serial = simple_strtoull(serial_string, NULL, 16);
+
+ serialnr->high = (u32)(serial >> 32);
+ serialnr->low = (u32)(serial & 0xffffffff);
+}
+#endif
diff --git a/configs/evb-rk3328_defconfig b/configs/evb-rk3328_defconfig
index d4a00718c5..9107c020b7 100644
--- a/configs/evb-rk3328_defconfig
+++ b/configs/evb-rk3328_defconfig
@@ -55,6 +55,8 @@ CONFIG_SPL_CLK=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_DM_KEY=y
+CONFIG_MISC=y
+CONFIG_ROCKCHIP_EFUSE=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_ROCKCHIP=y
CONFIG_PHY=y
diff --git a/include/configs/rk3328_common.h b/include/configs/rk3328_common.h
index b7971782b5..a2af5a7989 100644
--- a/include/configs/rk3328_common.h
+++ b/include/configs/rk3328_common.h
@@ -9,6 +9,8 @@
#include "rockchip-common.h"
+#define CONFIG_MISC_INIT_R
+
#define CONFIG_SYS_MALLOC_LEN (32 << 20)
#define CONFIG_SYS_CBSIZE 1024
#define CONFIG_SKIP_LOWLEVEL_INIT

View File

@ -0,0 +1,21 @@
From b6c47bd9f6a8965ab538f168086d4fd99fcf3066 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Wed, 10 Jan 2018 19:56:16 +0100
Subject: [PATCH] rk3328-evb: add sdmmc vmmc-supply
---
arch/arm/dts/rk3328-evb.dts | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/dts/rk3328-evb.dts b/arch/arm/dts/rk3328-evb.dts
index 4b13a8da64..586c58659d 100644
--- a/arch/arm/dts/rk3328-evb.dts
+++ b/arch/arm/dts/rk3328-evb.dts
@@ -61,6 +61,7 @@
num-slots = <1>;
pinctrl-names = "default";
pinctrl-0 = <&sdmmc0_clk>, <&sdmmc0_cmd>, <&sdmmc0_dectn>, <&sdmmc0_bus4>;
+ vmmc-supply = <&vcc3v3_sdmmc>;
status = "okay";
};

View File

@ -0,0 +1,38 @@
From 0f59425a214329eda9080f186bfa82780fce75e6 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Sun, 28 Jan 2018 15:42:23 +0100
Subject: [PATCH] rk3399-evb: prefer sdcard boot
---
arch/arm/dts/rk3399-evb.dts | 2 +-
arch/arm/dts/rk3399.dtsi | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/dts/rk3399-evb.dts b/arch/arm/dts/rk3399-evb.dts
index a0ea589015..ae28bded64 100644
--- a/arch/arm/dts/rk3399-evb.dts
+++ b/arch/arm/dts/rk3399-evb.dts
@@ -17,7 +17,7 @@
chosen {
stdout-path = &uart2;
- u-boot,spl-boot-order = &sdhci, &sdmmc;
+ u-boot,spl-boot-order = &sdmmc, &sdhci;
};
vdd_center: vdd-center {
diff --git a/arch/arm/dts/rk3399.dtsi b/arch/arm/dts/rk3399.dtsi
index 68221b47f7..cfb99c9e16 100644
--- a/arch/arm/dts/rk3399.dtsi
+++ b/arch/arm/dts/rk3399.dtsi
@@ -35,8 +35,8 @@
serial2 = &uart2;
serial3 = &uart3;
serial4 = &uart4;
- mmc0 = &sdhci;
- mmc1 = &sdmmc;
+ mmc0 = &sdmmc;
+ mmc1 = &sdhci;
};
cpus {

View File

@ -0,0 +1,40 @@
# Rockchip
This project is for Rockchip SoC devices
## Devices
**RK3288**
* [ASUS Tinker Board](devices/TinkerBoard)
* [mqmaker MiQi](devices/MiQi)
**RK3328**
* [PINE64 ROCK64](devices/RK3328)
* [Popcorn Hour RockBox](devices/RK3328)
* [Popcorn Hour Transformer](devices/RK3328)
* [Firefly ROC-RK3328-CC](devices/RK3328)
**RK3399**
* [96rocks ROCK960](devices/RK3399)
* [Hardkernel ODROID-N1](devices/RK3399)
* [PINE64 RockPro64](devices/RK3399)
* [Rockchip Sapphire Board](devices/RK3399)
**My single-board computer is not listed, will it be added in the future?**<br />
If your single-board computer uses a current generation SoC listed on http://opensource.rock-chips.com/wiki_Main_Page the odds are in your favor.
**My Android device is not listed, will it be added in the future?**<br />
You may have luck if your device vendor is open source friendly, otherwise keep using Android for best support.
## Links
* https://github.com/rockchip-linux
* http://opensource.rock-chips.com
## Useful debug commands
* `cat /sys/kernel/debug/dri/0/summary`
* `cat /sys/kernel/debug/dw-hdmi/status`
* `cat /sys/kernel/debug/clk/clk_summary`
* `hexdump -C /sys/class/drm/card0-HDMI-A-1/edid`
* `edid-decode /sys/class/drm/card0-HDMI-A-1/edid`

View File

@ -0,0 +1,24 @@
################################################################################
# This file is part of LibreELEC - https://libreelec.tv
# Copyright (C) 2017-present Team LibreELEC
#
# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LibreELEC. If not, see <http://www.gnu.org/licenses/>.
################################################################################
# Allow upgrades between arm and aarch64
if [ "$1" = "@PROJECT@.arm" -o "$1" = "@PROJECT@.aarch64" ]; then
exit 0
else
exit 1
fi

View File

@ -0,0 +1,73 @@
################################################################################
# This file is part of LibreELEC - https://libreelec.tv
# Copyright (C) 2017-present Team LibreELEC
#
# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LibreELEC. If not, see <http://www.gnu.org/licenses/>.
################################################################################
PKG_RKBIN="$(get_build_dir rkbin)"
PKG_SOC=$UBOOT_SYSTEM
if [ "$DEVICE" = "RK3328" -o "$DEVICE" = "RK3399" ]; then
PKG_SOC="${DEVICE/RK/rk}"
fi
case "$PKG_SOC" in
rk3036)
PKG_DATAFILE="spl/u-boot-spl-nodtb.bin"
PKG_LOADER="u-boot-dtb.bin"
;;
rk3328)
PKG_DATAFILE="$PKG_RKBIN/rk33/rk3328_ddr_786MHz_v1.12.bin"
PKG_LOADER="$PKG_RKBIN/rk33/rk3328_miniloader_v2.44.bin"
PKG_BL31="$PKG_RKBIN/rk33/rk3328_bl31_v1.39.bin"
;;
rk3399)
PKG_DATAFILE="$PKG_RKBIN/rk33/rk3399_ddr_800MHz_v1.09.bin"
PKG_LOADER="$PKG_RKBIN/rk33/rk3399_miniloader_v1.09.bin"
PKG_BL31="$PKG_RKBIN/rk33/rk3399_bl31_v1.00.elf"
;;
*)
PKG_DATAFILE="spl/u-boot-spl-dtb.bin"
PKG_LOADER="u-boot-dtb.bin"
;;
esac
if [ -n "$PKG_DATAFILE" -a -n "$PKG_LOADER" ]; then
tools/mkimage -n $PKG_SOC -T rksd -d "$PKG_DATAFILE" idbloader.img
cat "$PKG_LOADER" >> idbloader.img
cp -av idbloader.img $INSTALL/usr/share/bootloader
fi
if [ -n "$PKG_BL31" ]; then
$PKG_RKBIN/tools/loaderimage --pack --uboot u-boot-dtb.bin uboot.img 0x200000
cp -av uboot.img $INSTALL/usr/share/bootloader
cat >trust.ini <<EOF
[BL30_OPTION]
SEC=0
[BL31_OPTION]
SEC=1
PATH=$PKG_BL31
ADDR=0x00010000
[BL32_OPTION]
SEC=0
[BL33_OPTION]
SEC=0
[OUTPUT]
PATH=trust.img
EOF
$PKG_RKBIN/tools/trust_merger --verbose trust.ini
cp -av trust.img $INSTALL/usr/share/bootloader
fi

View File

@ -0,0 +1,30 @@
################################################################################
# This file is part of LibreELEC - https://libreelec.tv
# Copyright (C) 2017-present Team LibreELEC
#
# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LibreELEC. If not, see <http://www.gnu.org/licenses/>.
################################################################################
if [ -f "$RELEASE_DIR/3rdparty/bootloader/idbloader.img" ]; then
echo "image: burn idbloader.img to image..."
dd if="$RELEASE_DIR/3rdparty/bootloader/idbloader.img" of="$DISK" bs=32k seek=1 conv=fsync,notrunc >"$SAVE_ERROR" 2>&1 || show_error
fi
if [ -f "$RELEASE_DIR/3rdparty/bootloader/uboot.img" ]; then
echo "image: burn uboot.img to image..."
dd if="$RELEASE_DIR/3rdparty/bootloader/uboot.img" of="$DISK" bs=64k seek=128 conv=fsync,notrunc >"$SAVE_ERROR" 2>&1 || show_error
fi
if [ -f "$RELEASE_DIR/3rdparty/bootloader/trust.img" ]; then
echo "image: burn trust.img to image..."
dd if="$RELEASE_DIR/3rdparty/bootloader/trust.img" of="$DISK" bs=64k seek=192 conv=fsync,notrunc >"$SAVE_ERROR" 2>&1 || show_error
fi

View File

@ -0,0 +1,38 @@
################################################################################
# This file is part of LibreELEC - https://libreelec.tv
# Copyright (C) 2017-present Team LibreELEC
#
# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LibreELEC. If not, see <http://www.gnu.org/licenses/>.
################################################################################
mkdir -p $RELEASE_DIR/3rdparty/bootloader
if [ -n "$UBOOT_SYSTEM" ]; then
BOOTLOADER_DIR=$(get_build_dir $BOOTLOADER)
if [ -f $BOOTLOADER_DIR/idbloader.img ]; then
cp -a $BOOTLOADER_DIR/idbloader.img $RELEASE_DIR/3rdparty/bootloader
fi
if [ -f $BOOTLOADER_DIR/uboot.img ]; then
cp -a $BOOTLOADER_DIR/uboot.img $RELEASE_DIR/3rdparty/bootloader
fi
if [ -f $BOOTLOADER_DIR/trust.img ]; then
cp -a $BOOTLOADER_DIR/trust.img $RELEASE_DIR/3rdparty/bootloader
fi
fi
LINUX_DTS_DIR=$(get_build_dir linux)/arch/$TARGET_KERNEL_ARCH/boot/dts
for dtb in $LINUX_DTS_DIR/*.dtb $LINUX_DTS_DIR/*/*.dtb; do
if [ -f $dtb ]; then
cp -a $dtb $RELEASE_DIR/3rdparty/bootloader
fi
done

View File

@ -0,0 +1,65 @@
################################################################################
# This file is part of LibreELEC - https://libreelec.tv
# Copyright (C) 2017-present Team LibreELEC
#
# LibreELEC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# LibreELEC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LibreELEC. If not, see <http://www.gnu.org/licenses/>.
################################################################################
[ -z "$SYSTEM_ROOT" ] && SYSTEM_ROOT=""
[ -z "$BOOT_ROOT" ] && BOOT_ROOT="/flash"
[ -z "$BOOT_PART" ] && BOOT_PART=$(df "$BOOT_ROOT" | tail -1 | awk {' print $1 '})
if [ -z "$BOOT_DISK" ]; then
case $BOOT_PART in
/dev/sd[a-z][0-9]*)
BOOT_DISK=$(echo $BOOT_PART | sed -e "s,[0-9]*,,g")
;;
/dev/mmcblk*)
BOOT_DISK=$(echo $BOOT_PART | sed -e "s,p[0-9]*,,g")
;;
esac
fi
# mount $BOOT_ROOT r/w
mount -o remount,rw $BOOT_ROOT
# update device tree
for all_dtb in $BOOT_ROOT/*.dtb; do
dtb=$(basename $all_dtb)
if [ -f $SYSTEM_ROOT/usr/share/bootloader/$dtb ]; then
echo -n "Updating $dtb... "
cp -p $SYSTEM_ROOT/usr/share/bootloader/$dtb $BOOT_ROOT
echo "done"
fi
done
# update bootloader
if [ -f $SYSTEM_ROOT/usr/share/bootloader/idbloader.img ]; then
echo -n "Updating idbloader.img... "
dd if=$SYSTEM_ROOT/usr/share/bootloader/idbloader.img of=$BOOT_DISK bs=32k seek=1 conv=fsync &>/dev/null
echo "done"
fi
if [ -f $SYSTEM_ROOT/usr/share/bootloader/uboot.img ]; then
echo -n "Updating uboot.img... "
dd if=$SYSTEM_ROOT/usr/share/bootloader/uboot.img of=$BOOT_DISK bs=64k seek=128 conv=fsync &>/dev/null
echo "done"
fi
if [ -f $SYSTEM_ROOT/usr/share/bootloader/trust.img ]; then
echo -n "Updating trust.img... "
dd if=$SYSTEM_ROOT/usr/share/bootloader/trust.img of=$BOOT_DISK bs=64k seek=192 conv=fsync &>/dev/null
echo "done"
fi
# mount $BOOT_ROOT r/o
sync
mount -o remount,ro $BOOT_ROOT

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,33 @@
################################################################################
# setup device defaults
################################################################################
# The TARGET_CPU variable controls which processor should be targeted for
# generated code.
case $TARGET_ARCH in
arm)
TARGET_FLOAT="hard"
TARGET_CPU="cortex-a17"
TARGET_FPU="neon-vfpv4"
TARGET_FEATURES="32bit neon"
;;
esac
# Configuration for u-boot
UBOOT_SYSTEM="rk3288"
# Kernel target
KERNEL_TARGET="zImage"
# Additional kernel make parameters (for example to specify the u-boot loadaddress)
KERNEL_MAKE_EXTRACMD="rk3288-miqi.dtb"
# Mali GPU family
MALI_FAMILY="t760"
MALI_REVISION="r1p0"
# kernel image name
KERNEL_NAME="zImage"
# kernel serial console
EXTRA_CMDLINE="console=uart8250,mmio32,0xff690000 console=tty0"

View File

@ -0,0 +1,18 @@
# RK3328
This is a SoC device for RK3328
**Build**
* `PROJECT=Rockchip DEVICE=RK3328 ARCH=arm UBOOT_SYSTEM=box make image`
* `PROJECT=Rockchip DEVICE=RK3328 ARCH=arm UBOOT_SYSTEM=box-trn9 make image`
* `PROJECT=Rockchip DEVICE=RK3328 ARCH=arm UBOOT_SYSTEM=box-z28 make image`
* `PROJECT=Rockchip DEVICE=RK3328 ARCH=arm UBOOT_SYSTEM=roc-cc make image`
* `PROJECT=Rockchip DEVICE=RK3328 ARCH=arm UBOOT_SYSTEM=rock64 make image`
* `PROJECT=Rockchip DEVICE=RK3328 ARCH=arm UBOOT_SYSTEM=rockbox make image`
**How to use on an Android device**
- Flash image to a sd-card
- Insert sd-card into the device
- Plug in power and LibreELEC should boot instead of Android
- Remove sd-card from device to boot into Android

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,43 @@
################################################################################
# setup device defaults
################################################################################
# The TARGET_CPU variable controls which processor should be targeted for
# generated code.
case $TARGET_ARCH in
aarch64)
TARGET_CPU="cortex-a53"
TARGET_CPU_FLAGS="+crc+crypto"
TARGET_FEATURES="64bit neon"
;;
arm)
TARGET_KERNEL_ARCH="arm64"
TARGET_PATCH_ARCH="aarch64"
TARGET_FLOAT="hard"
TARGET_CPU="cortex-a53"
TARGET_CPU_FLAGS="+crc"
TARGET_FPU="crypto-neon-fp-armv8"
TARGET_FEATURES="32bit neon"
;;
esac
# Kernel target
KERNEL_TARGET="Image"
# Additional kernel make parameters (for example to specify the u-boot loadaddress)
KERNEL_MAKE_EXTRACMD=""
KERNEL_MAKE_EXTRACMD+=" rockchip/rk3328-box.dtb"
KERNEL_MAKE_EXTRACMD+=" rockchip/rk3328-box-trn9.dtb"
KERNEL_MAKE_EXTRACMD+=" rockchip/rk3328-box-z28.dtb"
KERNEL_MAKE_EXTRACMD+=" rockchip/rk3328-roc-cc.dtb"
KERNEL_MAKE_EXTRACMD+=" rockchip/rk3328-rock64.dtb"
KERNEL_MAKE_EXTRACMD+=" rockchip/rk3328-rockbox.dtb"
# Mali GPU family
MALI_FAMILY="450"
# kernel image name
KERNEL_NAME="Image"
# kernel serial console
EXTRA_CMDLINE="console=uart8250,mmio32,0xff130000 console=tty0"

View File

@ -0,0 +1,10 @@
# RK3399
This is a SoC device for RK3399
**Build**
* `PROJECT=Rockchip DEVICE=RK3399 ARCH=arm UBOOT_SYSTEM=odroidn1 make image`
* `PROJECT=Rockchip DEVICE=RK3399 ARCH=arm UBOOT_SYSTEM=rock960 make image`
* `PROJECT=Rockchip DEVICE=RK3399 ARCH=arm UBOOT_SYSTEM=rockpro64 make image`
* `PROJECT=Rockchip DEVICE=RK3399 ARCH=arm UBOOT_SYSTEM=sapphire make image`

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,41 @@
################################################################################
# setup device defaults
################################################################################
# The TARGET_CPU variable controls which processor should be targeted for
# generated code.
case $TARGET_ARCH in
aarch64)
TARGET_CPU="cortex-a72.cortex-a53"
TARGET_CPU_FLAGS="+crc+crypto"
TARGET_FEATURES="64bit neon"
;;
arm)
TARGET_KERNEL_ARCH="arm64"
TARGET_PATCH_ARCH="aarch64"
TARGET_FLOAT="hard"
TARGET_CPU="cortex-a72.cortex-a53"
TARGET_CPU_FLAGS="+crc"
TARGET_FPU="crypto-neon-fp-armv8"
TARGET_FEATURES="32bit neon"
;;
esac
# Kernel target
KERNEL_TARGET="Image"
# Additional kernel make parameters (for example to specify the u-boot loadaddress)
KERNEL_MAKE_EXTRACMD=""
KERNEL_MAKE_EXTRACMD+=" rockchip/rk3399-odroidn1.dtb"
KERNEL_MAKE_EXTRACMD+=" rockchip/rk3399-rock960.dtb"
KERNEL_MAKE_EXTRACMD+=" rockchip/rk3399-rockpro64.dtb"
KERNEL_MAKE_EXTRACMD+=" rockchip/rk3399-sapphire.dtb"
# Mali GPU family
MALI_FAMILY="t860"
# kernel image name
KERNEL_NAME="Image"
# kernel serial console
EXTRA_CMDLINE="console=uart8250,mmio32,0xff1a0000 console=tty0"

View File

@ -0,0 +1,46 @@
# ASUS Tinker Board
This is an experimental project for the ASUS Tinker Board
**Progress**
* [x] LEDs
* [ ] ~~CEC~~
* [ ] Audio
* [x] HDMI Stereo L-PCM
* [x] HDMI Multi-channel L-PCM
* [x] HDA 3.5 mm jack
* [ ] HDMI NL-PCM (AC3/E-AC3/DTS)
* [ ] HDMI HBR (TrueHD/DTS-HD)
* [ ] Video
* [x] Software decoding
* [ ] Hardware decoding
* [x] h264 / hevc / vp8
* [ ] mpeg4 / mpeg2
* [ ] HDMI Video Format
* [x] RGB 4:4:4 Limited Range
* [ ] RGB 4:4:4 Full Range
* [ ] YCbCr 4:4:4
* [ ] YCbCr 4:2:0
* [x] WiFi
* [x] Bluetooth
**Known Issues/Limitations**
* Video output is RGB 4:4:4 8-bit limited range
* Video aspect ratio / zoom is not working for all modes
* Generic USB-Audio do not work due to a custom alsa config
* 4K resolution is limited to 30hz due to failed compliance test
* CEC is not connected to SoC
**Serial Console**
* UART2 on GPIO pin 32/33 with baud rate 115200
**Build**
* `PROJECT=Rockchip DEVICE=TinkerBoard ARCH=arm make image`
## Links
* Community Forum: https://tinkerboarding.co.uk/forum/

View File

@ -0,0 +1,21 @@
#
# Configuration for ALC4040
#
USB-Audio.pcm.default {
@args [ CARD ]
@args.CARD { type string }
type hw
card $CARD
device 2
}
<confdir:pcm/front.conf>
USB-Audio.pcm.front.0 {
@args [ CARD ]
@args.CARD { type string }
type hw
card $CARD
device 2
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@
################################################################################
# setup device defaults
################################################################################
# The TARGET_CPU variable controls which processor should be targeted for
# generated code.
case $TARGET_ARCH in
arm)
TARGET_FLOAT="hard"
TARGET_CPU="cortex-a17"
TARGET_FPU="neon-vfpv4"
TARGET_FEATURES="32bit neon"
;;
esac
# Configuration for u-boot
UBOOT_SYSTEM="rk3288"
# Kernel target
KERNEL_TARGET="zImage"
# Additional kernel make parameters (for example to specify the u-boot loadaddress)
KERNEL_MAKE_EXTRACMD="rk3288-miniarm.dtb"
# Mali GPU family
MALI_FAMILY="t760"
# kernel image name
KERNEL_NAME="zImage"
# kernel serial console
EXTRA_CMDLINE="console=uart8250,mmio32,0xff690000 console=tty0"

View File

@ -0,0 +1,287 @@
From f490b48f29fb0b976b7f3d749f14dd4bbb95705a Mon Sep 17 00:00:00 2001
From: Ziyuan Xu <xzy.xu@rock-chips.com>
Date: Fri, 23 Sep 2016 13:43:18 +0800
Subject: [PATCH] MINIARM: HACK: switch vccio_sd to 3.3v while shutdowning
Change-Id: I80d6d2b61b31f16b6b42b9ffcaab077231a7a91c
Signed-off-by: Ziyuan Xu <xzy.xu@rock-chips.com>
---
drivers/mmc/host/dw_mmc-rockchip.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
index 29e3ae99edbc..531ad93ff912 100644
--- a/drivers/mmc/host/dw_mmc-rockchip.c
+++ b/drivers/mmc/host/dw_mmc-rockchip.c
@@ -13,6 +13,7 @@
#include <linux/mmc/host.h>
#include <linux/mmc/dw_mmc.h>
#include <linux/of_address.h>
+#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include "dw_mmc.h"
@@ -285,6 +286,15 @@ static int dw_mci_rockchip_probe(struct platform_device *pdev)
return dw_mci_pltfm_register(pdev, drv_data);
}
+static void dw_mci_rockchip_platfm_shutdown(struct platform_device *pdev)
+{
+ struct dw_mci *host = platform_get_drvdata(pdev);
+ struct mmc_host *mmc = host->cur_slot->mmc;
+
+ if (!IS_ERR(mmc->supply.vqmmc))
+ regulator_set_voltage(mmc->supply.vqmmc, 3000000, 3300000);
+}
+
#ifdef CONFIG_PM_SLEEP
static int dw_mci_rockchip_suspend(struct device *dev)
{
@@ -308,6 +318,7 @@ static SIMPLE_DEV_PM_OPS(dw_mci_rockchip_pmops,
static struct platform_driver dw_mci_rockchip_pltfm_driver = {
.probe = dw_mci_rockchip_probe,
.remove = dw_mci_pltfm_remove,
+ .shutdown = dw_mci_rockchip_platfm_shutdown,
.driver = {
.name = "dwmmc_rockchip",
.of_match_table = dw_mci_rockchip_match,
From dcd64488045c2c7b54f4257a0f5e6d56f93f28f6 Mon Sep 17 00:00:00 2001
From: Ziyuan Xu <xzy.xu@rock-chips.com>
Date: Mon, 6 Feb 2017 08:39:46 +0800
Subject: [PATCH] MINIARM: HACK: mmc: dw_mmc-rockchip: enable vmmc supply for
reboot
Mmc core has already power off the vmmc since shutdown, re-enable it so
that card is active in next reboot.
Change-Id: Id64ed02844db9d834c820ed5b8c5bf7a0afe4ed5
Signed-off-by: Ziyuan Xu <xzy.xu@rock-chips.com>
---
drivers/mmc/host/dw_mmc-rockchip.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
index 531ad93ff912..eae304077e17 100644
--- a/drivers/mmc/host/dw_mmc-rockchip.c
+++ b/drivers/mmc/host/dw_mmc-rockchip.c
@@ -15,6 +15,7 @@
#include <linux/of_address.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
+#include <linux/delay.h>
#include "dw_mmc.h"
#include "dw_mmc-pltfm.h"
@@ -290,6 +291,12 @@ static void dw_mci_rockchip_platfm_shutdown(struct platform_device *pdev)
{
struct dw_mci *host = platform_get_drvdata(pdev);
struct mmc_host *mmc = host->cur_slot->mmc;
+ int ret;
+
+ mdelay(20);
+
+ if (!IS_ERR(mmc->supply.vmmc))
+ ret = regulator_enable(mmc->supply.vmmc);
if (!IS_ERR(mmc->supply.vqmmc))
regulator_set_voltage(mmc->supply.vqmmc, 3000000, 3300000);
From 6947d06a6b9bccb4fca863cb40638b3cdf487fa8 Mon Sep 17 00:00:00 2001
From: Jacob Chen <jacob-chen@iotwrt.com>
Date: Sat, 22 Jul 2017 19:55:09 +0800
Subject: [PATCH] MINIARM: drm/rockchip: update phy settings
Change-Id: I9e92a4191115e13999183a5d7656d6708adda632
Signed-off-by: Jacob Chen <jacob-chen@iotwrt.com>
---
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index bdc96cd4253d..cea7b9d6bdb3 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -347,8 +347,7 @@ static struct dw_hdmi_phy_config rockchip_phy_config[] = {
/*pixelclk symbol term vlev*/
{ 74250000, 0x8009, 0x0004, 0x0272},
{ 165000000, 0x802b, 0x0004, 0x0209},
- { 297000000, 0x8039, 0x0005, 0x028d},
- { 594000000, 0x8039, 0x0000, 0x019d},
+ { 297000000, 0x802d, 0x0001, 0x0149},
{ ~0UL, 0x0000, 0x0000, 0x0000}
};
From 8b96d29710578f258442bb7975581e30c5c1a209 Mon Sep 17 00:00:00 2001
From: Nickey Yang <nickey.yang@rock-chips.com>
Date: Mon, 17 Jul 2017 16:35:34 +0800
Subject: [PATCH] MINIARM: set npll be used for hdmi only
Change-Id: I8bebfb2cfb68e3dad172e5547d3886526ad5e912
Signed-off-by: Nickey Yang <nickey.yang@rock-chips.com>
---
arch/arm/boot/dts/rk3288.dtsi | 4 +++-
drivers/clk/rockchip/clk-rk3288.c | 6 +++---
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index b37d1954d27c..904a7955e347 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -1027,7 +1027,7 @@
<&cru PCLK_PERI>;
assigned-clock-rates = <594000000>,
<500000000>, <300000000>,
- <150000000>, <75000000>,
+ <0>, <75000000>,
<300000000>, <150000000>,
<75000000>;
};
@@ -1265,6 +1265,8 @@
resets = <&cru SRST_LCDC0_AXI>, <&cru SRST_LCDC0_AHB>, <&cru SRST_LCDC0_DCLK>;
reset-names = "axi", "ahb", "dclk";
iommus = <&vopb_mmu>;
+ assigned-clocks = <&cru DCLK_VOP0>;
+ assigned-clock-parents = <&cru PLL_NPLL>;
status = "disabled";
vopb_out: port {
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
index 4adbace24ff7..9df15059d584 100644
--- a/drivers/clk/rockchip/clk-rk3288.c
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -211,9 +211,9 @@ static struct rockchip_pll_clock rk3288_pll_clks[] __initdata = {
[cpll] = PLL(pll_rk3066, PLL_CPLL, "cpll", mux_pll_p, 0, RK3288_PLL_CON(8),
RK3288_MODE_CON, 8, 7, 0, rk3288_pll_rates),
[gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK3288_PLL_CON(12),
- RK3288_MODE_CON, 12, 8, ROCKCHIP_PLL_SYNC_RATE, rk3288_pll_rates),
+ RK3288_MODE_CON, 12, 8, 0, rk3288_pll_rates),
[npll] = PLL(pll_rk3066, PLL_NPLL, "npll", mux_pll_p, 0, RK3288_PLL_CON(16),
- RK3288_MODE_CON, 14, 9, ROCKCHIP_PLL_SYNC_RATE, rk3288_pll_rates),
+ RK3288_MODE_CON, 14, 9, 0, rk3288_pll_rates),
};
static struct clk_div_table div_hclk_cpu_t[] = {
@@ -428,7 +428,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
RK3288_CLKSEL_CON(30), 14, 2, MFLAGS, 8, 5, DFLAGS,
RK3288_CLKGATE_CON(3), 4, GFLAGS),
- COMPOSITE(DCLK_VOP0, "dclk_vop0", mux_pll_src_cpll_gpll_npll_p, 0,
+ COMPOSITE(DCLK_VOP0, "dclk_vop0", mux_pll_src_cpll_gpll_npll_p, CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
RK3288_CLKSEL_CON(27), 0, 2, MFLAGS, 8, 8, DFLAGS,
RK3288_CLKGATE_CON(3), 1, GFLAGS),
COMPOSITE(DCLK_VOP1, "dclk_vop1", mux_pll_src_cpll_gpll_npll_p, 0,
From 07d84a3e6f43def7af179d417224a610ca7aaf98 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Mon, 11 Dec 2017 23:09:54 +0100
Subject: [PATCH] clk: rockchip: rk3288: add more pixel clock rates
---
drivers/clk/rockchip/clk-rk3288.c | 79 +++++++++++++++++++++++++++++++++++++--
1 file changed, 75 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
index 9df15059d584..e1f3bd273a58 100644
--- a/drivers/clk/rockchip/clk-rk3288.c
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -84,23 +84,94 @@ static struct rockchip_pll_rate_table rk3288_pll_rates[] = {
RK3066_PLL_RATE( 742500000, 8, 495, 2),
RK3066_PLL_RATE( 696000000, 1, 58, 2),
RK3066_PLL_RATE( 600000000, 1, 50, 2),
- RK3066_PLL_RATE_NB(594000000, 1, 198, 8, 1),
+ RK3066_PLL_RATE( 594000000, 2, 99, 2),
+ RK3066_PLL_RATE( 552750000, 16, 737, 2),
RK3066_PLL_RATE( 552000000, 1, 46, 2),
+ RK3066_PLL_RATE( 505250000, 24, 2021, 4),
RK3066_PLL_RATE( 504000000, 1, 84, 4),
RK3066_PLL_RATE( 500000000, 3, 125, 2),
RK3066_PLL_RATE( 456000000, 1, 76, 4),
+ RK3066_PLL_RATE( 443250000, 8, 591, 4),
RK3066_PLL_RATE( 408000000, 1, 68, 4),
RK3066_PLL_RATE( 400000000, 3, 100, 2),
RK3066_PLL_RATE( 384000000, 2, 128, 4),
+ RK3066_PLL_RATE( 380500000, 12, 761, 4),
RK3066_PLL_RATE( 360000000, 1, 60, 4),
+ RK3066_PLL_RATE( 356500000, 8, 713, 6),
+ RK3066_PLL_RATE( 348500000, 8, 697, 6),
+ RK3066_PLL_RATE( 333250000, 16, 1333, 6),
+ RK3066_PLL_RATE( 317000000, 4, 317, 6),
+ RK3066_PLL_RATE( 312250000, 16, 1249, 6),
RK3066_PLL_RATE( 312000000, 1, 52, 4),
RK3066_PLL_RATE( 300000000, 1, 50, 4),
- RK3066_PLL_RATE( 297000000, 2, 198, 8),
+ RK3066_PLL_RATE( 297000000, 4, 297, 6),
+ RK3066_PLL_RATE( 288000000, 1, 72, 6),
+ RK3066_PLL_RATE( 281250000, 16, 1125, 6),
+ RK3066_PLL_RATE( 268500000, 2, 179, 8),
+ RK3066_PLL_RATE( 268250000, 12, 1073, 8),
+ RK3066_PLL_RATE( 261000000, 1, 87, 8),
RK3066_PLL_RATE( 252000000, 1, 84, 8),
+ RK3066_PLL_RATE( 245500000, 6, 491, 8),
+ RK3066_PLL_RATE( 245250000, 4, 327, 8),
+ RK3066_PLL_RATE( 241500000, 2, 161, 8),
+ RK3066_PLL_RATE( 234000000, 1, 78, 8),
+ RK3066_PLL_RATE( 229500000, 2, 153, 8),
+ RK3066_PLL_RATE( 218250000, 16, 1455, 10),
RK3066_PLL_RATE( 216000000, 1, 72, 8),
- RK3066_PLL_RATE( 148500000, 2, 99, 8),
+ RK3066_PLL_RATE( 214750000, 12, 859, 8),
+ RK3066_PLL_RATE( 208000000, 3, 260, 10),
+ RK3066_PLL_RATE( 204750000, 16, 1365, 10),
+ RK3066_PLL_RATE( 202500000, 8, 675, 10),
+ RK3066_PLL_RATE( 193250000, 48, 3865, 10),
+ RK3066_PLL_RATE( 189000000, 4, 315, 10),
+ RK3066_PLL_RATE( 187250000, 48, 3745, 10),
+ RK3066_PLL_RATE( 187000000, 12, 935, 10),
+ RK3066_PLL_RATE( 182750000, 8, 731, 12),
+ RK3066_PLL_RATE( 179500000, 4, 359, 12),
+ RK3066_PLL_RATE( 175500000, 4, 351, 12),
+ RK3066_PLL_RATE( 162000000, 1, 81, 12),
+ RK3066_PLL_RATE( 157500000, 4, 315, 12),
+ RK3066_PLL_RATE( 157000000, 12, 1099, 14),
+ RK3066_PLL_RATE( 156750000, 16, 1463, 14),
+ RK3066_PLL_RATE( 156000000, 1, 91, 14),
+ RK3066_PLL_RATE( 154000000, 6, 539, 14),
+ RK3066_PLL_RATE( 148500000, 8, 693, 14),
+ RK3066_PLL_RATE( 148250000, 8, 593, 12),
+ RK3066_PLL_RATE( 146250000, 16, 1365, 14),
+ RK3066_PLL_RATE( 140250000, 16, 1309, 14),
+ RK3066_PLL_RATE( 136750000, 6, 547, 16),
+ RK3066_PLL_RATE( 135000000, 1, 90, 16),
RK3066_PLL_RATE( 126000000, 1, 84, 16),
- RK3066_PLL_RATE( 48000000, 1, 64, 32),
+ RK3066_PLL_RATE( 122500000, 3, 245, 16),
+ RK3066_PLL_RATE( 121750000, 6, 487, 16),
+ RK3066_PLL_RATE( 119000000, 3, 238, 16),
+ RK3066_PLL_RATE( 117500000, 3, 235, 16),
+ RK3066_PLL_RATE( 115500000, 1, 77, 16),
+ RK3066_PLL_RATE( 108000000, 1, 72, 16),
+ RK3066_PLL_RATE( 106500000, 1, 71, 16),
+ RK3066_PLL_RATE( 102250000, 6, 409, 16),
+ RK3066_PLL_RATE( 101000000, 3, 202, 16),
+ RK3066_PLL_RATE( 94500000, 1, 63, 16),
+ RK3066_PLL_RATE( 88750000, 6, 355, 16),
+ RK3066_PLL_RATE( 85500000, 1, 57, 16),
+ RK3066_PLL_RATE( 83500000, 3, 167, 16),
+ RK3066_PLL_RATE( 79500000, 1, 53, 16),
+ RK3066_PLL_RATE( 78750000, 2, 105, 16),
+ RK3066_PLL_RATE( 75000000, 1, 50, 16),
+ RK3066_PLL_RATE( 74250000, 2, 99, 16),
+ RK3066_PLL_RATE( 73250000, 6, 293, 16),
+ RK3066_PLL_RATE( 72000000, 1, 48, 16),
+ RK3066_PLL_RATE( 71000000, 3, 142, 16),
+ RK3066_PLL_RATE( 68250000, 2, 91, 16),
+ RK3066_PLL_RATE( 65000000, 3, 130, 16),
+ RK3066_PLL_RATE( 56250000, 2, 75, 16),
+ RK3066_PLL_RATE( 50000000, 3, 100, 16),
+ RK3066_PLL_RATE( 49500000, 1, 33, 16),
+ RK3066_PLL_RATE( 40000000, 3, 80, 16),
+ RK3066_PLL_RATE( 36000000, 1, 24, 16),
+ RK3066_PLL_RATE( 35500000, 3, 71, 16),
+ RK3066_PLL_RATE( 33750000, 2, 45, 16),
+ RK3066_PLL_RATE( 31500000, 1, 21, 16),
{ /* sentinel */ },
};

View File

@ -0,0 +1,3 @@
[Sleep]
SuspendMode=false
HibernateMode=false

View File

@ -0,0 +1,24 @@
[Unit]
Description=Debug Shell on /dev/ttyS2
DefaultDependencies=no
ConditionKernelCommandLine=|console=ttyS2
ConditionKernelCommandLine=|console=uart8250,mmio32,0xff130000
ConditionKernelCommandLine=|console=uart8250,mmio32,0xff1a0000
ConditionKernelCommandLine=|console=uart8250,mmio32,0xff690000
[Service]
WorkingDirectory=/storage
Environment="ENV=/etc/profile"
ExecStartPre=/bin/sh -c 'echo -en "\033[?25h"'
ExecStart=/bin/sh
Restart=always
RestartSec=0
StandardInput=tty
TTYPath=/dev/ttyS2
KillMode=process
IgnoreSIGPIPE=no
# bash ignores SIGTERM
KillSignal=SIGHUP
[Install]
WantedBy=sysinit.target

View File

@ -0,0 +1,34 @@
#
# Configuration for HDMI
#
<confdir:pcm/hdmi.conf>
HDMI.pcm.hdmi.0 {
@args [ CARD AES0 AES1 AES2 AES3 ]
@args.CARD { type string }
@args.AES0 { type integer }
@args.AES1 { type integer }
@args.AES2 { type integer }
@args.AES3 { type integer }
type hooks
slave.pcm {
type hw
card $CARD
device 0
}
hooks.0 {
type ctl_elems
hook_args [
{
interface MIXER
name "IEC958 Playback Default"
lock true
preserve true
optional true
value [ $AES0 $AES1 $AES2 $AES3 ]
}
]
}
hint.device 0
}

View File

@ -0,0 +1,12 @@
#
# Configuration for I2S
#
<confdir:pcm/front.conf>
I2S.pcm.front.0 {
@args [ CARD ]
@args.CARD { type string }
type hw
card $CARD
}

View File

@ -0,0 +1,34 @@
#
# Configuration for SPDIF
#
<confdir:pcm/iec958.conf>
SPDIF.pcm.iec958.0 {
@args [ CARD AES0 AES1 AES2 AES3 ]
@args.CARD { type string }
@args.AES0 { type integer }
@args.AES1 { type integer }
@args.AES2 { type integer }
@args.AES3 { type integer }
type hooks
slave.pcm {
type hw
card $CARD
device 0
}
hooks.0 {
type ctl_elems
hook_args [
{
interface MIXER
name "IEC958 Playback Default"
lock true
preserve true
optional true
value [ $AES0 $AES1 $AES2 $AES3 ]
}
]
}
hint.device 0
}

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<settings version="1">
<section id="system">
<category id="display">
<group id="1">
<setting id="videoscreen.blankdisplays">
<visible>false</visible>
</setting>
<setting id="videoscreen.fakefullscreen">
<visible>false</visible>
</setting>
</group>
<group id="3">
<setting id="videoscreen.noofbuffers">
<default>2</default>
<visible>false</visible>
</setting>
</group>
</category>
<category id="logging">
<group id="1">
<setting id="debug.extralogging">
<default>false</default>
</setting>
</group>
</category>
</section>
<section id="player">
<category id="videoplayer">
<group id="2">
<setting id="videoplayer.adjustrefreshrate">
<default>2</default>
</setting>
</group>
</category>
</section>
</settings>

76
projects/Rockchip/options Normal file
View File

@ -0,0 +1,76 @@
################################################################################
# setup system defaults
################################################################################
# Bootloader to use (syslinux / u-boot / bcm2835-bootloader)
BOOTLOADER="u-boot"
# Kernel extra targets to build
KERNEL_UBOOT_EXTRA_TARGET=""
# Kernel to use. values can be:
# default: default mainline kernel
LINUX="${LINUX:-rockchip-4.4}"
################################################################################
# setup build defaults
################################################################################
# Project CFLAGS
PROJECT_CFLAGS=""
# SquashFS compression method (gzip / lzo / xz)
SQUASHFS_COMPRESSION="lzo"
################################################################################
# setup project defaults
################################################################################
# build and install ALSA Audio support (yes / no)
ALSA_SUPPORT="yes"
# OpenGL(X) implementation to use (no / mesa)
OPENGL="no"
# OpenGL-ES implementation to use (no / bcm2835-driver / gpu-viv-bin-mx6q)
OPENGLES="mali-rockchip"
# include uvesafb support (yes / no)
UVESAFB_SUPPORT="no"
# Displayserver to use (weston / no)
DISPLAYSERVER="no"
# Windowmanager to use (ratpoison / fluxbox / none)
WINDOWMANAGER="none"
# Xorg Graphic drivers to use (all / i915,i965,r200,r300,r600,nvidia)
# Space separated list is supported,
# e.g. GRAPHIC_DRIVERS="i915 i965 r300 r600 radeonsi nvidia"
GRAPHIC_DRIVERS=""
# KODI Player implementation to use (default / bcm2835-driver / libfslvpuwrap)
KODIPLAYER_DRIVER="rkmpp"
# Modules to install in initramfs for early boot
INITRAMFS_MODULES=""
# additional Firmware to use (dvb-firmware, misc-firmware, wlan-firmware)
# Space separated list is supported,
# e.g. FIRMWARE="dvb-firmware misc-firmware wlan-firmware"
FIRMWARE="misc-firmware wlan-firmware dvb-firmware rockchip-firmware"
# additional packages to install
ADDITIONAL_PACKAGES="dtc"
# build and install ATV IR remote support (yes / no)
ATVCLIENT_SUPPORT="no"
# build and install CEC framework support (yes / no)
CEC_FRAMEWORK_SUPPORT="yes"
# build with installer (yes / no)
INSTALLER_SUPPORT="no"
# Start boot partition at 16MiB, same as https://github.com/rockchip-linux/build images
SYSTEM_PART_START=32768

View File

@ -0,0 +1,16 @@
--- ./include/drm/drm_fourcc.h 2017-09-04 10:45:05.812784940 -0700
+++ ./include/drm/drm_fourcc.h 2017-09-04 10:45:27.831516420 -0700
@@ -116,6 +116,13 @@
#define DRM_FORMAT_NV24 fourcc_code('N', 'V', '2', '4') /* non-subsampled Cr:Cb plane */
#define DRM_FORMAT_NV42 fourcc_code('N', 'V', '4', '2') /* non-subsampled Cb:Cr plane */
+#define DRM_FORMAT_NV12_10 fourcc_code('N', 'A', '1', '2') /* 2x2 subsampled Cr:Cb plane */
+#define DRM_FORMAT_NV21_10 fourcc_code('N', 'A', '2', '1') /* 2x2 subsampled Cb:Cr plane */
+#define DRM_FORMAT_NV16_10 fourcc_code('N', 'A', '1', '6') /* 2x1 subsampled Cr:Cb plane */
+#define DRM_FORMAT_NV61_10 fourcc_code('N', 'A', '6', '1') /* 2x1 subsampled Cb:Cr plane */
+#define DRM_FORMAT_NV24_10 fourcc_code('N', 'A', '2', '4') /* non-subsampled Cr:Cb plane */
+#define DRM_FORMAT_NV42_10 fourcc_code('N', 'A', '4', '2') /* non-subsampled Cb:Cr plane */
+
/*
* 3 plane YCbCr
* index 0: Y plane, [7:0] Y

View File

@ -0,0 +1,27 @@
From a968000cae7b5d0c3c10b4e5a94fd187c891ee08 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Wed, 27 Dec 2017 22:01:06 +0100
Subject: [PATCH] Revert "rk: add gcc-wrapper"
This reverts part of commit 7a51384d24fe4da183fc15b2d17aa3c153b822e7.
---
Makefile | 6 ------
1 file changed, 6 deletions(-)
diff --git a/Makefile b/Makefile
index a785aeed4674..d34c20a89fb7 100644
--- a/Makefile
+++ b/Makefile
@@ -372,12 +372,6 @@ PERL = perl
PYTHON = python
CHECK = sparse
-# Use the wrapper for the compiler. This wrapper scans for new
-# warnings and causes the build to stop upon encountering them.
-ifneq ($(wildcard $(srctree)/scripts/gcc-wrapper.py),)
-CC = $(srctree)/scripts/gcc-wrapper.py $(CROSS_COMPILE)gcc
-endif
-
CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \
-Wbitwise -Wno-return-void $(CF)
CFLAGS_MODULE =

View File

@ -0,0 +1,735 @@
From 3ab7c88ff74eb4f8f1eb9a8d4e27661a8e8f2103 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Wed, 29 Mar 2017 23:51:09 +0200
Subject: [PATCH] gpu/arm/midgard: default to performance gpu governor
---
drivers/gpu/arm/midgard_for_linux/backend/gpu/mali_kbase_devfreq.c | 6 ++----
drivers/gpu/arm/midgard_for_linux/mali_kbase_config_defaults.h | 3 +--
2 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/arm/midgard_for_linux/backend/gpu/mali_kbase_devfreq.c b/drivers/gpu/arm/midgard_for_linux/backend/gpu/mali_kbase_devfreq.c
index 69b13ddad95f..6f3b654cd3fd 100644
--- a/drivers/gpu/arm/midgard_for_linux/backend/gpu/mali_kbase_devfreq.c
+++ b/drivers/gpu/arm/midgard_for_linux/backend/gpu/mali_kbase_devfreq.c
@@ -213,8 +213,7 @@ int kbase_devfreq_init(struct kbase_device *kbdev)
dp = &kbdev->devfreq_profile;
dp->initial_freq = kbdev->current_freq;
- /* .KP : set devfreq_dvfs_interval_in_ms */
- dp->polling_ms = 20;
+ dp->polling_ms = 100;
dp->target = kbase_devfreq_target;
dp->get_dev_status = kbase_devfreq_status;
dp->get_cur_freq = kbase_devfreq_cur_freq;
@@ -229,8 +228,7 @@ int kbase_devfreq_init(struct kbase_device *kbdev)
&kbdev->ondemand_data.downdifferential);
kbdev->devfreq = devfreq_add_device(kbdev->dev, dp,
- "simple_ondemand",
- &kbdev->ondemand_data);
+ "performance", NULL);
if (IS_ERR(kbdev->devfreq)) {
kbase_devfreq_term_freq_table(kbdev);
return PTR_ERR(kbdev->devfreq);
diff --git a/drivers/gpu/arm/midgard_for_linux/mali_kbase_config_defaults.h b/drivers/gpu/arm/midgard_for_linux/mali_kbase_config_defaults.h
index 9b00cce9b2b3..739ac83b484f 100644
--- a/drivers/gpu/arm/midgard_for_linux/mali_kbase_config_defaults.h
+++ b/drivers/gpu/arm/midgard_for_linux/mali_kbase_config_defaults.h
@@ -157,8 +157,7 @@ enum {
/*
* Default period for DVFS sampling
*/
-// #define DEFAULT_PM_DVFS_PERIOD 100 /* 100ms */
-#define DEFAULT_PM_DVFS_PERIOD 20 /* 20 ms */
+#define DEFAULT_PM_DVFS_PERIOD 100 /* 100ms */
/*
* Power Management poweroff tick granuality. This is in nanoseconds to
From c49efbd36cf0b4d676adee155d3c68862c93d400 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Mon, 17 Apr 2017 13:09:16 +0200
Subject: [PATCH] sound/usb/quirks-table: add Realtek ALC4040
---
sound/usb/quirks-table.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index 8a59d4782a0f..96e1e2fdc9c3 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -3277,4 +3277,13 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"),
}
},
+{
+ USB_DEVICE(0x0bda, 0x481a),
+ .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+ .vendor_name = "Realtek",
+ .product_name = "ALC4040",
+ .ifnum = QUIRK_NO_INTERFACE
+ }
+},
+
#undef USB_DEVICE_VENDOR_SPEC
From 9224460a1f2208076d8b67454603db5415dcb992 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Sun, 28 May 2017 09:08:50 +0200
Subject: [PATCH] gpu/arm/mali400: default to performance gpu governor
---
drivers/gpu/arm/mali400/mali/linux/mali_devfreq.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_devfreq.c b/drivers/gpu/arm/mali400/mali/linux/mali_devfreq.c
index 3eac07d76766..14916ea86905 100644
--- a/drivers/gpu/arm/mali400/mali/linux/mali_devfreq.c
+++ b/drivers/gpu/arm/mali400/mali/linux/mali_devfreq.c
@@ -249,7 +249,7 @@ int mali_devfreq_init(struct mali_device *mdev)
return -EFAULT;
mdev->devfreq = devfreq_add_device(mdev->dev, dp,
- "simple_ondemand", NULL);
+ "performance", NULL);
if (IS_ERR(mdev->devfreq)) {
mali_devfreq_term_freq_table(mdev);
return PTR_ERR(mdev->devfreq);
From 2d2af9eb328f709fc6b8bc63c42699dd22932e3e Mon Sep 17 00:00:00 2001
From: LongChair <LongChair@hotmail.com>
Date: Fri, 21 Apr 2017 13:39:12 +0200
Subject: [PATCH] drm/rockchip: remove unsupported 4K freqs
---
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index bdc96cd4253d..b22e7a67024f 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -508,9 +508,23 @@ dw_hdmi_rockchip_mode_valid(struct drm_connector *connector,
return MODE_BAD;
hdmi = to_rockchip_hdmi(encoder);
- if (hdmi->dev_type == RK3368_HDMI && mode->clock > 340000 &&
+ if ((hdmi->dev_type == RK3368_HDMI || hdmi->dev_type == RK3328_HDMI) &&
+ mode->clock > 340000 &&
!drm_mode_is_420(&connector->display_info, mode))
return MODE_BAD;
+
+ /* Skip bad clocks for RK3288 */
+ if (hdmi->dev_type == RK3288_HDMI && (mode->clock < 27500 || mode->clock > 340000))
+ return MODE_CLOCK_RANGE;
+
+ /* Skip 4K 50/60Hz clocks for RK3328 */
+ if (hdmi->dev_type == RK3328_HDMI && mode->clock > 340000)
+ return MODE_CLOCK_RANGE;
+
+ /* Skip 4K 50/60Hz clocks for RK3399 */
+ if (hdmi->dev_type == RK3399_HDMI && mode->clock > 340000)
+ return MODE_CLOCK_RANGE;
+
/*
* ensure all drm display mode can work, if someone want support more
* resolutions, please limit the possible_crtc, only connect to
From 66db06144315ec2212c9724f57291acadeffe8d8 Mon Sep 17 00:00:00 2001
From: xuhuicong <xhc@rock-chips.com>
Date: Fri, 23 Jun 2017 18:56:17 +0800
Subject: [PATCH] drm/rockchip: hdmi: fix no sound some time
Change-Id: Ic9f931d9a5b7bca954363293a20ca242eb0bfa6f
Signed-off-by: xuhuicong <xhc@rock-chips.com>
---
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index a7f2e381a5bd..df2f72fbf93a 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1981,10 +1981,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
HDMI_FC_INVIDCONF_IN_I_P_INTERLACED :
HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE;
- inv_val |= hdmi->sink_is_hdmi ?
- HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE :
- HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE;
-
hdmi_writeb(hdmi, inv_val, HDMI_FC_INVIDCONF);
hdisplay = mode->hdisplay;
@@ -2282,6 +2278,9 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
/* not for DVI mode */
if (hdmi->sink_is_hdmi) {
dev_dbg(hdmi->dev, "%s HDMI mode\n", __func__);
+ hdmi_modb(hdmi, HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE,
+ HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE,
+ HDMI_FC_INVIDCONF);
/* HDMI Initialization Step F - Configure AVI InfoFrame */
hdmi_config_AVI(hdmi, mode);
From 61d75a50a3eb5c9f7894d102749c1aed2cb69db8 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Fri, 25 Aug 2017 18:29:35 +0200
Subject: [PATCH] video: rockchip: vpu: partial revise for rk322xh feature
---
drivers/video/rockchip/vcodec/vcodec_service.c | 12 +++---------
1 file changed, 3 insertions(+), 9 deletions(-)
diff --git a/drivers/video/rockchip/vcodec/vcodec_service.c b/drivers/video/rockchip/vcodec/vcodec_service.c
index 9236c5e93215..bdc4722f4e3a 100644
--- a/drivers/video/rockchip/vcodec/vcodec_service.c
+++ b/drivers/video/rockchip/vcodec/vcodec_service.c
@@ -3630,21 +3630,15 @@ static irqreturn_t vdpu_irq(int irq, void *dev_id)
time_record(task, 1);
vpu_debug(DEBUG_IRQ_STATUS, "vdpu_irq dec status %08x\n",
dec_status);
- if ((dec_status & 0x40001) == 0x40001) {
- do {
- dec_status = readl_relaxed(dev->regs +
- task->reg_irq);
- } while ((dec_status & 0x40001) == 0x40001);
- }
-
- if (check_irq_err(task, dec_status))
- atomic_add(1, &pservice->reset_request);
writel_relaxed(0, dev->regs + task->reg_irq);
/* set clock gating to save power */
writel(task->gating_mask, dev->regs + task->reg_en);
+ if (check_irq_err(task, dec_status))
+ atomic_add(1, &pservice->reset_request);
+
atomic_add(1, &dev->irq_count_codec);
time_diff(task);
pservice->irq_status = raw_status;
From 336b80f1b8830171de634f41d29f6153a8ccac14 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Mon, 2 Oct 2017 21:53:19 +0200
Subject: [PATCH] drm/rockchip: use limited range
---
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index df2f72fbf93a..f603eeadaa1b 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -147,6 +147,12 @@ static const u16 csc_coeff_rgb_in_eitu709[3][4] = {
{ 0x6756, 0x78ab, 0x2000, 0x0200 }
};
+static const u16 csc_coeff_rgb_in_limited[3][4] = {
+ { 0x36f7, 0x0000, 0x0000, 0x0040 },
+ { 0x0000, 0x36f7, 0x0000, 0x0040 },
+ { 0x0000, 0x0000, 0x36f7, 0x0040 }
+};
+
struct hdmi_vmode {
bool mdataenablepolarity;
@@ -996,7 +1002,9 @@ static void hdmi_video_sample(struct dw_hdmi *hdmi)
static int is_color_space_conversion(struct dw_hdmi *hdmi)
{
- return hdmi->hdmi_data.enc_in_bus_format != hdmi->hdmi_data.enc_out_bus_format;
+ return hdmi->hdmi_data.enc_in_bus_format != hdmi->hdmi_data.enc_out_bus_format ||
+ (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_in_bus_format) &&
+ hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format));
}
static int is_color_space_decimation(struct dw_hdmi *hdmi)
@@ -1030,7 +1038,11 @@ static void dw_hdmi_update_csc_coeffs(struct dw_hdmi *hdmi)
u32 csc_scale = 1;
if (is_color_space_conversion(hdmi)) {
- if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) {
+ if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_in_bus_format) &&
+ hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) {
+ csc_coeff = &csc_coeff_rgb_in_limited;
+ csc_scale = 0;
+ } else if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) {
if (hdmi->hdmi_data.enc_out_encoding ==
V4L2_YCBCR_ENC_601)
csc_coeff = &csc_coeff_rgb_out_eitu601;
From 63c7038ff1424b8362ccaa5c8c5907ed285284fc Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Sat, 18 Nov 2017 11:09:39 +0100
Subject: [PATCH] rockchip: vop: force skip lines if image too big
---
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 3e6798b4b821..23516a195261 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1584,6 +1584,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
int ymirror, xmirror;
uint32_t val;
bool rb_swap, global_alpha_en;
+ int skip_lines = 0;
/*
* can't update plane when vop is disabled.
@@ -1597,8 +1598,14 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
}
mode = &crtc->state->adjusted_mode;
+
+ /*
+ * force skip lines if image too big.
+ */
actual_w = drm_rect_width(src) >> 16;
- actual_h = drm_rect_height(src) >> 16;
+ if (actual_w == 3840 && is_yuv_support(fb->pixel_format))
+ skip_lines = 1;
+ actual_h = drm_rect_height(src) >> (16 + skip_lines);
act_info = (actual_h - 1) << 16 | ((actual_w - 1) & 0xffff);
dsp_info = (drm_rect_height(dest) - 1) << 16;
@@ -1620,10 +1627,10 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
VOP_WIN_SET(vop, win, xmirror, xmirror);
VOP_WIN_SET(vop, win, ymirror, ymirror);
VOP_WIN_SET(vop, win, format, vop_plane_state->format);
- VOP_WIN_SET(vop, win, yrgb_vir, fb->pitches[0] >> 2);
+ VOP_WIN_SET(vop, win, yrgb_vir, fb->pitches[0] >> (2 - skip_lines));
VOP_WIN_SET(vop, win, yrgb_mst, vop_plane_state->yrgb_mst);
if (is_yuv_support(fb->pixel_format)) {
- VOP_WIN_SET(vop, win, uv_vir, fb->pitches[1] >> 2);
+ VOP_WIN_SET(vop, win, uv_vir, fb->pitches[1] >> (2 - skip_lines));
VOP_WIN_SET(vop, win, uv_mst, vop_plane_state->uv_mst);
}
VOP_WIN_SET(vop, win, fmt_10, is_yuv_10bit(fb->pixel_format));
From 2fef240b349e8adbf74f672a2203453839a59ee2 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Sat, 18 Nov 2017 23:17:24 +0100
Subject: [PATCH] gpu/arm/midgard: default to performance gpu governor
---
drivers/gpu/arm/midgard/backend/gpu/mali_kbase_devfreq.c | 5 ++---
drivers/gpu/arm/midgard/mali_kbase_config_defaults.h | 3 +--
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_devfreq.c b/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_devfreq.c
index 0bf5fcd21c03..e578bd0f92dd 100644
--- a/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_devfreq.c
+++ b/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_devfreq.c
@@ -232,8 +232,7 @@ int kbase_devfreq_init(struct kbase_device *kbdev)
dp = &kbdev->devfreq_profile;
dp->initial_freq = kbdev->current_freq;
- /* .KP : set devfreq_dvfs_interval_in_ms */
- dp->polling_ms = 20;
+ dp->polling_ms = 100;
dp->target = kbase_devfreq_target;
dp->get_dev_status = kbase_devfreq_status;
dp->get_cur_freq = kbase_devfreq_cur_freq;
@@ -243,7 +242,7 @@ int kbase_devfreq_init(struct kbase_device *kbdev)
return -EFAULT;
kbdev->devfreq = devfreq_add_device(kbdev->dev, dp,
- "simple_ondemand", NULL);
+ "performance", NULL);
if (IS_ERR(kbdev->devfreq)) {
kbase_devfreq_term_freq_table(kbdev);
return PTR_ERR(kbdev->devfreq);
diff --git a/drivers/gpu/arm/midgard/mali_kbase_config_defaults.h b/drivers/gpu/arm/midgard/mali_kbase_config_defaults.h
index e674cc2ea183..0f11388acfd7 100644
--- a/drivers/gpu/arm/midgard/mali_kbase_config_defaults.h
+++ b/drivers/gpu/arm/midgard/mali_kbase_config_defaults.h
@@ -157,8 +157,7 @@ enum {
/*
* Default period for DVFS sampling
*/
-// #define DEFAULT_PM_DVFS_PERIOD 100 /* 100ms */
-#define DEFAULT_PM_DVFS_PERIOD 20 /* 20 ms */
+#define DEFAULT_PM_DVFS_PERIOD 100 /* 100ms */
/*
* Power Management poweroff tick granuality. This is in nanoseconds to
From 0dbe82f20d885716f74242621fe96a914db03064 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Sun, 10 Dec 2017 14:16:09 +0100
Subject: [PATCH] uapi: install rockchip_drm header
---
include/uapi/drm/Kbuild | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/uapi/drm/Kbuild b/include/uapi/drm/Kbuild
index 38d437096c35..b7ae9969d41e 100644
--- a/include/uapi/drm/Kbuild
+++ b/include/uapi/drm/Kbuild
@@ -11,6 +11,7 @@ header-y += nouveau_drm.h
header-y += qxl_drm.h
header-y += r128_drm.h
header-y += radeon_drm.h
+header-y += rockchip_drm.h
header-y += savage_drm.h
header-y += sis_drm.h
header-y += tegra_drm.h
From f166ba88945f1ea7ff327bb9f22f53aed728dde3 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Sun, 10 Dec 2017 18:03:53 +0100
Subject: [PATCH] phy: rockchip-inno-hdmi-phy: add vesa dmt pixel clocks
---
drivers/phy/rockchip/phy-rockchip-inno-hdmi-phy.c | 71 +++++++++++++++++++++++
1 file changed, 71 insertions(+)
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi-phy.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi-phy.c
index ca50c8f58c50..2455c87ab5d8 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi-phy.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi-phy.c
@@ -245,6 +245,77 @@ static const struct pre_pll_config pre_pll_cfg_table[] = {
{594000000, 371250000, 4, 495, 1, 2, 0, 1, 3, 1, 1, 1, 0},
{593407000, 593407000, 1, 98, 0, 2, 0, 1, 0, 1, 1, 0, 0xE6AE6B},
{594000000, 594000000, 1, 99, 0, 2, 0, 1, 0, 1, 1, 0, 0},
+ { 25175000, 25175000, 30, 1007, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ { 31500000, 31500000, 1, 21, 1, 1, 1, 1, 2, 2, 2, 0, 0},
+ { 33750000, 33750000, 1, 45, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ { 35500000, 35500000, 3, 71, 1, 1, 1, 1, 2, 2, 2, 0, 0},
+ { 36000000, 36000000, 1, 12, 0, 1, 1, 1, 0, 2, 2, 0, 0},
+ { 49500000, 49500000, 1, 33, 1, 1, 1, 1, 2, 2, 2, 0, 0},
+ { 50000000, 50000000, 3, 50, 0, 1, 1, 1, 0, 2, 2, 0, 0},
+ { 56250000, 56250000, 1, 75, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ { 65000000, 65000000, 3, 65, 0, 1, 1, 1, 0, 2, 2, 0, 0},
+ { 68250000, 68250000, 1, 91, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ { 71000000, 71000000, 3, 71, 0, 1, 1, 1, 0, 2, 2, 0, 0},
+ { 72000000, 72000000, 1, 24, 0, 1, 1, 1, 0, 2, 2, 0, 0},
+ { 73250000, 73250000, 3, 293, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ { 75000000, 75000000, 1, 25, 0, 1, 1, 1, 0, 2, 2, 0, 0},
+ { 78750000, 78750000, 1, 105, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ { 79500000, 79500000, 1, 53, 1, 1, 1, 1, 2, 2, 2, 0, 0},
+ { 83500000, 83500000, 3, 167, 1, 1, 1, 1, 2, 2, 2, 0, 0},
+ { 85500000, 85500000, 1, 57, 1, 1, 1, 1, 2, 2, 2, 0, 0},
+ { 88750000, 88750000, 3, 355, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ { 94500000, 94500000, 1, 63, 1, 1, 1, 1, 2, 2, 2, 0, 0},
+ {101000000, 101000000, 3, 101, 0, 1, 1, 1, 0, 2, 2, 0, 0},
+ {102250000, 102250000, 3, 409, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ {106500000, 106500000, 1, 71, 1, 1, 1, 1, 2, 2, 2, 0, 0},
+ {108000000, 108000000, 1, 36, 0, 1, 1, 1, 0, 2, 2, 0, 0},
+ {115500000, 115500000, 1, 77, 1, 1, 1, 1, 2, 2, 2, 0, 0},
+ {117500000, 117500000, 3, 235, 1, 1, 1, 1, 2, 2, 2, 0, 0},
+ {119000000, 119000000, 3, 119, 0, 1, 1, 1, 0, 2, 2, 0, 0},
+ {121750000, 121750000, 3, 487, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ {122500000, 122500000, 3, 245, 1, 1, 1, 1, 2, 2, 2, 0, 0},
+ {135000000, 135000000, 1, 45, 0, 1, 1, 1, 0, 2, 2, 0, 0},
+ {136750000, 136750000, 3, 547, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ {140250000, 140250000, 1, 187, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ {146250000, 146250000, 1, 195, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ {148250000, 148250000, 3, 593, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ {154000000, 154000000, 3, 154, 0, 1, 1, 1, 0, 2, 2, 0, 0},
+ {156000000, 156000000, 1, 52, 0, 1, 1, 1, 0, 2, 2, 0, 0},
+ {156750000, 156750000, 1, 209, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ {157000000, 157000000, 3, 157, 0, 1, 1, 1, 0, 2, 2, 0, 0},
+ {157500000, 157500000, 1, 105, 1, 1, 1, 1, 2, 2, 2, 0, 0},
+ {162000000, 162000000, 1, 54, 0, 1, 1, 1, 0, 2, 2, 0, 0},
+ {175500000, 175500000, 1, 117, 1, 1, 1, 1, 2, 2, 2, 0, 0},
+ {179500000, 179500000, 3, 359, 1, 1, 1, 1, 2, 2, 2, 0, 0},
+ {182750000, 182750000, 3, 731, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ {187000000, 187000000, 3, 187, 0, 1, 1, 1, 0, 2, 2, 0, 0},
+ {187250000, 187250000, 3, 749, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ {189000000, 189000000, 1, 63, 0, 1, 1, 1, 0, 2, 2, 0, 0},
+ {193250000, 193250000, 3, 773, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ {202500000, 202500000, 1, 135, 1, 1, 1, 1, 2, 2, 2, 0, 0},
+ {204750000, 204750000, 1, 273, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ {208000000, 208000000, 3, 208, 0, 1, 1, 1, 0, 2, 2, 0, 0},
+ {214750000, 214750000, 3, 859, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ {218250000, 218250000, 1, 291, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ {229500000, 229500000, 1, 153, 1, 1, 1, 1, 2, 2, 2, 0, 0},
+ {234000000, 234000000, 1, 78, 0, 1, 1, 1, 0, 2, 2, 0, 0},
+ {241500000, 241500000, 1, 161, 1, 1, 1, 1, 2, 2, 2, 0, 0},
+ {245250000, 245250000, 1, 327, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ {245500000, 245500000, 3, 491, 1, 1, 1, 1, 2, 2, 2, 0, 0},
+ {261000000, 261000000, 1, 87, 0, 1, 1, 1, 0, 2, 2, 0, 0},
+ {268250000, 268250000, 3, 1073, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ {268500000, 268500000, 1, 179, 1, 1, 1, 1, 2, 2, 2, 0, 0},
+ {281250000, 281250000, 1, 375, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ {288000000, 288000000, 1, 96, 0, 1, 1, 1, 0, 2, 2, 0, 0},
+ {312250000, 312250000, 3, 1249, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ {317000000, 317000000, 3, 317, 0, 1, 1, 1, 0, 2, 2, 0, 0},
+ {333250000, 333250000, 3, 1333, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ {348500000, 348500000, 3, 697, 1, 1, 1, 1, 2, 2, 2, 0, 0},
+ {356500000, 356500000, 3, 713, 1, 1, 1, 1, 2, 2, 2, 0, 0},
+ {380500000, 380500000, 3, 761, 1, 1, 1, 1, 2, 2, 2, 0, 0},
+ {443250000, 443250000, 1, 591, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ {505250000, 505250000, 3, 2021, 1, 2, 2, 1, 2, 3, 4, 0, 0},
+ {552750000, 552750000, 1, 737, 1, 2, 2, 1, 2, 3, 4, 0, 0},
{ ~0UL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
From 1a99dae778ad3402f8283aa19b27ea606fdfcd4c Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Tue, 12 Dec 2017 00:37:27 +0100
Subject: [PATCH] clk: rockchip: fix round rate
---
drivers/clk/rockchip/clk-pll.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
index 80d1d4095f2e..e4f64087aa78 100644
--- a/drivers/clk/rockchip/clk-pll.c
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -299,6 +299,17 @@ static const struct rockchip_pll_rate_table *rockchip_get_pll_settings(
static long rockchip_pll_round_rate(struct clk_hw *hw,
unsigned long drate, unsigned long *prate)
{
+ struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+ const struct rockchip_pll_rate_table *rate;
+
+ /* Get required rate settings from table */
+ rate = rockchip_get_pll_settings(pll, drate);
+ if (!rate) {
+ pr_debug("%s: Invalid rate : %lu for pll clk %s\n", __func__,
+ drate, __clk_get_name(hw->clk));
+ return -EINVAL;
+ }
+
return drate;
}
From 6e9921f5c0511283de78b221cc204d6aad53e68f Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Sun, 21 Jan 2018 17:20:00 +0100
Subject: [PATCH] drm: fix HDR metadata infoframe length
HDR metadata infoframe length is 26 bytes (not 30) according to [1]
(CTA-861-G: 6.9 Dynamic Range and Mastering InfoFrame)
Fixes activation of HDR mode on my LG OLED
[1] https://standards.cta.tech/kwspub/published_docs/CTA-861-G_FINAL_revised_2017.pdf
---
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 2 +-
drivers/gpu/drm/drm_edid.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index f603eeadaa1b..affba6ab8163 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1859,7 +1859,7 @@ static void hdmi_config_hdr_infoframe(struct dw_hdmi *hdmi)
return;
}
- hdmi_writeb(hdmi, 1, HDMI_FC_DRM_HB0);
+ hdmi_writeb(hdmi, frame.version, HDMI_FC_DRM_HB0);
hdmi_writeb(hdmi, frame.length, HDMI_FC_DRM_HB1);
hdmi_writeb(hdmi, frame.eotf, HDMI_FC_DRM_PB0);
hdmi_writeb(hdmi, frame.metadata_type, HDMI_FC_DRM_PB1);
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 3e3ebdf34e9f..d06786a58ca1 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4727,10 +4727,10 @@ drm_hdmi_infoframe_set_hdr_metadata(struct hdmi_drm_infoframe *frame,
hdr_source_metadata = (struct hdr_static_metadata *)hdr_metadata;
- frame->length = sizeof(struct hdr_static_metadata);
+ frame->length = 26;
frame->eotf = hdr_source_metadata->eotf;
- frame->type = hdr_source_metadata->type;
+ frame->metadata_type = hdr_source_metadata->type;
for (i = 0; i < 3; i++) {
frame->display_primaries_x[i] =
From 83b81c3876baf020491ee497f637b01c45eef059 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Sat, 27 Jan 2018 09:39:09 +0100
Subject: [PATCH] drm: add edid detection for Hybrid Log-Gamma EOTF
---
drivers/gpu/drm/drm_edid.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index d06786a58ca1..bfd64112178a 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2737,7 +2737,7 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid,
#define TRADITIONAL_GAMMA_SDR (0x1 << 0)
#define TRADITIONAL_GAMMA_HDR (0x1 << 1)
#define SMPTE_ST2084 (0x1 << 2)
-#define FUTURE_EOTF (0x1 << 3)
+#define HYBRID_LOG_GAMMA (0x1 << 3)
#define RESERVED_EOTF (0x3 << 4)
#define STATIC_METADATA_TYPE1 (0x1 << 0)
@@ -3707,6 +3707,8 @@ static uint16_t eotf_supported(const u8 *edid_ext)
val |= TRADITIONAL_GAMMA_HDR;
if (edid_ext[2] & SMPTE_ST2084)
val |= SMPTE_ST2084;
+ if (edid_ext[2] & HYBRID_LOG_GAMMA)
+ val |= HYBRID_LOG_GAMMA;
return val;
}
From 9a00f6e3bc2a7d6f3c3783f98bf3b142a1445f00 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Sun, 11 Feb 2018 19:21:41 +0100
Subject: [PATCH] drm: bridge: dw-hdmi: default to underscan mode
---
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index affba6ab8163..1c55ff385ce4 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1693,7 +1693,7 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
break;
}
- frame.scan_mode = HDMI_SCAN_MODE_NONE;
+ frame.scan_mode = HDMI_SCAN_MODE_UNDERSCAN;
/*
* The Designware IP uses a different byte format from standard
From 8076bb526d8c6d19006d460e2f904afafdf019e2 Mon Sep 17 00:00:00 2001
From: David Carrillo-Cisneros <davidcc@google.com>
Date: Tue, 18 Jul 2017 18:18:37 -0700
Subject: [PATCH] UPSTREAM: perf tools: Add EXCLUDE_EXTLIBS and EXTRA_PERFLIBS
to makefile
The goal is to allow users to override linking of libraries that
were automatically added to PERFLIBS.
EXCLUDE_EXTLIBS contains linker flags to be removed from LIBS
while EXTRA_PERFLIBS contains linker flags to be added.
My use case is to force certain library to be build statically,
e.g. for libelf:
EXCLUDE_EXTLIBS=-lelf EXTRA_PERFLIBS=path/libelf.a
Signed-off-by: David Carrillo-Cisneros <davidcc@google.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Elena Reshetova <elena.reshetova@intel.com>
Cc: Kees Kook <keescook@chromium.org>
Cc: Paul Turner <pjt@google.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/20170719011839.99399-3-davidcc@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
(cherry picked from commit cb281fea4b0a326d2a2104f8ffae2b6895c561fd)
---
tools/perf/Makefile.perf | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index fb1c9ddc3478..9b3b9bd50d54 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -33,6 +33,11 @@ include config/utilities.mak
#
# Define EXTRA_CFLAGS=-m64 or EXTRA_CFLAGS=-m32 as appropriate for cross-builds.
#
+# Define EXCLUDE_EXTLIBS=-lmylib to exclude libmylib from the auto-generated
+# EXTLIBS.
+#
+# Define EXTRA_PERFLIBS to pass extra libraries to PERFLIBS.
+#
# Define NO_DWARF if you do not want debug-info analysis feature at all.
#
# Define WERROR=0 to disable treating any warnings as errors.
@@ -289,7 +294,8 @@ ifdef ASCIIDOC8
export ASCIIDOC8
endif
-LIBS = -Wl,--whole-archive $(PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group
+EXTLIBS := $(call filter-out,$(EXCLUDE_EXTLIBS),$(EXTLIBS))
+LIBS = -Wl,--whole-archive $(PERFLIBS) $(EXTRA_PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group
export INSTALL SHELL_PATH
From 8fb0d8531aece502c4cc3a82077ace8c09b4918a Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Tue, 27 Feb 2018 20:49:00 +0100
Subject: [PATCH] net: wireless: rockchip_wlan: rtl8723bs: do not accept all
sdio wlan id
---
drivers/net/wireless/rockchip_wlan/rtl8723bs/Makefile | 2 +-
drivers/net/wireless/rockchip_wlan/rtl8723bs/os_dep/linux/sdio_intf.c | 3 +++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bs/Makefile b/drivers/net/wireless/rockchip_wlan/rtl8723bs/Makefile
index b1403a8e22af..716f1baec373 100644
--- a/drivers/net/wireless/rockchip_wlan/rtl8723bs/Makefile
+++ b/drivers/net/wireless/rockchip_wlan/rtl8723bs/Makefile
@@ -1248,7 +1248,7 @@ EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_ANDROID -DCONFIG_PLATFO
EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT
EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE
# default setting for Power control
-EXTRA_CFLAGS += -DRTW_ENABLE_WIFI_CONTROL_FUNC
+#EXTRA_CFLAGS += -DRTW_ENABLE_WIFI_CONTROL_FUNC
#EXTRA_CFLAGS += -DRTW_SUPPORT_PLATFORM_SHUTDOWN
# default setting for Special function
EXTRA_CFLAGS += -DCONFIG_P2P_IPS
diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723bs/os_dep/linux/sdio_intf.c b/drivers/net/wireless/rockchip_wlan/rtl8723bs/os_dep/linux/sdio_intf.c
index 0c03f775eb7f..45533aacecdc 100644
--- a/drivers/net/wireless/rockchip_wlan/rtl8723bs/os_dep/linux/sdio_intf.c
+++ b/drivers/net/wireless/rockchip_wlan/rtl8723bs/os_dep/linux/sdio_intf.c
@@ -47,6 +47,9 @@ static struct mmc_host *mmc_host = NULL;
static const struct sdio_device_id sdio_ids[] =
{
#ifdef CONFIG_RTL8723B
+ { SDIO_DEVICE(0x024c, 0x0523),.driver_data = RTL8723B},
+ { SDIO_DEVICE(0x024c, 0x0623),.driver_data = RTL8723B},
+ { SDIO_DEVICE(0x024c, 0x0626),.driver_data = RTL8723B},
{ SDIO_DEVICE(0x024c, 0xB723),.driver_data = RTL8723B},
#endif
#ifdef CONFIG_RTL8188E
From dced379ed8ce510bbf781704e6ff32557fa0950c Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Fri, 2 Mar 2018 20:53:32 +0100
Subject: [PATCH] net: wireless: rockchip_wlan: bcmdhd: detect broadcom sdio
device id
---
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh_sdmmc_linux.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh_sdmmc_linux.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh_sdmmc_linux.c
index 8864582b1706..b5a388cc3cbe 100755
--- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh_sdmmc_linux.c
+++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh_sdmmc_linux.c
@@ -225,7 +225,7 @@ static const struct sdio_device_id bcmsdh_sdmmc_ids[] = {
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334) },
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4324) },
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43239) },
- { SDIO_DEVICE_CLASS(SDIO_CLASS_NONE) },
+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_ANY_ID) },
{ 0, 0, 0, 0 /* end: all zeroes */
},
};

View File

@ -0,0 +1,455 @@
From abd68c63a163f8cd1efb40087f6a8569fafe7d64 Mon Sep 17 00:00:00 2001
From: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Date: Thu, 19 Nov 2015 11:41:36 -0200
Subject: [PATCH] UPSTREAM: smsir.h: remove a now duplicated definition
(IR_DEFAULT_TIMEOUT)
This macro is now part of the core. Remove from Siano driver.
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
(cherry picked from commit 850c8a7d68a761b5f11d5b443b5ece185e8068f4)
---
drivers/media/common/siano/smsir.h | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/media/common/siano/smsir.h b/drivers/media/common/siano/smsir.h
index fc8b7925c532..d9abd96ef48b 100644
--- a/drivers/media/common/siano/smsir.h
+++ b/drivers/media/common/siano/smsir.h
@@ -30,8 +30,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <linux/input.h>
#include <media/rc-core.h>
-#define IR_DEFAULT_TIMEOUT 100
-
struct smscore_device_t;
struct ir_t {
From 8fcf408f26690b403ea41a34c419a7cf25430b4f Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Wed, 6 Sep 2017 18:39:09 +0200
Subject: [PATCH] [media] rc/keymaps: add keytable for Pine64 IR Remote
Controller
---
drivers/media/rc/keymaps/Makefile | 1 +
drivers/media/rc/keymaps/rc-pine64.c | 65 ++++++++++++++++++++++++++++++++++++
include/media/rc-map.h | 1 +
3 files changed, 67 insertions(+)
create mode 100644 drivers/media/rc/keymaps/rc-pine64.c
diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index fbbd3bbcd252..8816520600f7 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
rc-norwood.o \
rc-npgtech.o \
rc-pctv-sedna.o \
+ rc-pine64.o \
rc-pinnacle-color.o \
rc-pinnacle-grey.o \
rc-pinnacle-pctv-hd.o \
diff --git a/drivers/media/rc/keymaps/rc-pine64.c b/drivers/media/rc/keymaps/rc-pine64.c
new file mode 100644
index 000000000000..bdf3975e7445
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-pine64.c
@@ -0,0 +1,65 @@
+/* Keytable for Pine64 IR Remote Controller
+ *
+ * Copyright (c) 2017 PINE64
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+static struct rc_map_table pine64[] = {
+ { 0x404000, KEY_NUMERIC_0 },
+ { 0x404001, KEY_NUMERIC_1 },
+ { 0x404002, KEY_NUMERIC_2 },
+ { 0x404003, KEY_NUMERIC_3 },
+ { 0x404004, KEY_NUMERIC_4 },
+ { 0x404005, KEY_NUMERIC_5 },
+ { 0x404006, KEY_NUMERIC_6 },
+ { 0x404007, KEY_NUMERIC_7 },
+ { 0x404008, KEY_NUMERIC_8 },
+ { 0x404009, KEY_NUMERIC_9 },
+ { 0x40400a, KEY_MUTE },
+ { 0x40400b, KEY_UP },
+ { 0x40400c, KEY_BACKSPACE },
+ { 0x40400d, KEY_OK },
+ { 0x40400e, KEY_DOWN },
+ { 0x404010, KEY_LEFT },
+ { 0x404011, KEY_RIGHT },
+ { 0x404017, KEY_VOLUMEDOWN },
+ { 0x404018, KEY_VOLUMEUP },
+ { 0x40401a, KEY_HOME },
+ { 0x40401d, KEY_MENU },
+ { 0x40401f, KEY_WWW },
+ { 0x404045, KEY_BACK },
+ { 0x404047, KEY_INFO },
+ { 0x40404d, KEY_POWER },
+};
+
+static struct rc_map_list pine64_map = {
+ .map = {
+ .scan = pine64,
+ .size = ARRAY_SIZE(pine64),
+ .rc_type = RC_TYPE_NEC,
+ .name = RC_MAP_PINE64,
+ }
+};
+
+static int __init init_rc_map_pine64(void)
+{
+ return rc_map_register(&pine64_map);
+}
+
+static void __exit exit_rc_map_pine64(void)
+{
+ rc_map_unregister(&pine64_map);
+}
+
+module_init(init_rc_map_pine64)
+module_exit(exit_rc_map_pine64)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("PINE64");
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index 7c4bbc4dfab4..3a34a9631dd1 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -173,6 +173,7 @@ void rc_map_init(void);
#define RC_MAP_NORWOOD "rc-norwood"
#define RC_MAP_NPGTECH "rc-npgtech"
#define RC_MAP_PCTV_SEDNA "rc-pctv-sedna"
+#define RC_MAP_PINE64 "rc-pine64"
#define RC_MAP_PINNACLE_COLOR "rc-pinnacle-color"
#define RC_MAP_PINNACLE_GREY "rc-pinnacle-grey"
#define RC_MAP_PINNACLE_PCTV_HD "rc-pinnacle-pctv-hd"
From 3b5e2f781693301e6ba4b3d9dcfc23f05402251c Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Wed, 6 Sep 2017 18:39:09 +0200
Subject: [PATCH] [media] rc/keymaps: add keytable for ODROID IR Remote
Controller
---
drivers/media/rc/keymaps/Makefile | 1 +
drivers/media/rc/keymaps/rc-odroid.c | 52 ++++++++++++++++++++++++++++++++++++
include/media/rc-map.h | 1 +
3 files changed, 54 insertions(+)
create mode 100644 drivers/media/rc/keymaps/rc-odroid.c
diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index 8816520600f7..f4321cfbbc79 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
rc-nec-terratec-cinergy-xs.o \
rc-norwood.o \
rc-npgtech.o \
+ rc-odroid.o \
rc-pctv-sedna.o \
rc-pine64.o \
rc-pinnacle-color.o \
diff --git a/drivers/media/rc/keymaps/rc-odroid.c b/drivers/media/rc/keymaps/rc-odroid.c
new file mode 100644
index 000000000000..52089f0b7c1d
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-odroid.c
@@ -0,0 +1,52 @@
+/* Keytable for ODROID IR Remote Controller
+ *
+ * Copyright (c) 2017 Hardkernel co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+static struct rc_map_table odroid[] = {
+ { 0xb2dc, KEY_POWER },
+ { 0xb288, KEY_MUTE },
+ { 0xb282, KEY_HOME },
+ { 0xb2ce, KEY_OK },
+ { 0xb2ca, KEY_UP },
+ { 0xb299, KEY_LEFT },
+ { 0xb2c1, KEY_RIGHT },
+ { 0xb2d2, KEY_DOWN },
+ { 0xb2c5, KEY_MENU },
+ { 0xb29a, KEY_BACK },
+ { 0xb281, KEY_VOLUMEDOWN },
+ { 0xb280, KEY_VOLUMEUP },
+};
+
+static struct rc_map_list odroid_map = {
+ .map = {
+ .scan = odroid,
+ .size = ARRAY_SIZE(odroid),
+ .rc_type = RC_TYPE_NEC,
+ .name = RC_MAP_ODROID,
+ }
+};
+
+static int __init init_rc_map_odroid(void)
+{
+ return rc_map_register(&odroid_map);
+}
+
+static void __exit exit_rc_map_odroid(void)
+{
+ rc_map_unregister(&odroid_map);
+}
+
+module_init(init_rc_map_odroid)
+module_exit(exit_rc_map_odroid)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Hardkernel co., Ltd.");
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index 3a34a9631dd1..f1badbfbca90 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -172,6 +172,7 @@ void rc_map_init(void);
#define RC_MAP_NEC_TERRATEC_CINERGY_XS "rc-nec-terratec-cinergy-xs"
#define RC_MAP_NORWOOD "rc-norwood"
#define RC_MAP_NPGTECH "rc-npgtech"
+#define RC_MAP_ODROID "rc-odroid"
#define RC_MAP_PCTV_SEDNA "rc-pctv-sedna"
#define RC_MAP_PINE64 "rc-pine64"
#define RC_MAP_PINNACLE_COLOR "rc-pinnacle-color"
From b78470cab538b641350de506371924b48c19455e Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Wed, 6 Sep 2017 18:39:09 +0200
Subject: [PATCH] [media] rc/keymaps: add keytable for WeTek Hub Remote
Controller
---
drivers/media/rc/keymaps/Makefile | 1 +
drivers/media/rc/keymaps/rc-wetek-hub.c | 52 +++++++++++++++++++++++++++++++++
include/media/rc-map.h | 1 +
3 files changed, 54 insertions(+)
create mode 100644 drivers/media/rc/keymaps/rc-wetek-hub.c
diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index f4321cfbbc79..e8e6434cbc13 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -101,6 +101,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
rc-tt-1500.o \
rc-twinhan-dtv-cab-ci.o \
rc-twinhan1027.o \
+ rc-wetek-hub.o \
rc-videomate-m1f.o \
rc-videomate-s350.o \
rc-videomate-tv-pvr.o \
diff --git a/drivers/media/rc/keymaps/rc-wetek-hub.c b/drivers/media/rc/keymaps/rc-wetek-hub.c
new file mode 100644
index 000000000000..0955ecfcb77c
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-wetek-hub.c
@@ -0,0 +1,52 @@
+/* Keytable for WeTek Hub Remote Controller
+ *
+ * Copyright (c) 2017 WeTek
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+static struct rc_map_table wetek_hub[] = {
+ { 0x77f1, KEY_POWER },
+ { 0x77f2, KEY_HOME },
+ { 0x77f3, KEY_MUTE },
+ { 0x77f4, KEY_UP },
+ { 0x77f5, KEY_DOWN },
+ { 0x77f6, KEY_LEFT },
+ { 0x77f7, KEY_RIGHT },
+ { 0x77f8, KEY_OK },
+ { 0x77f9, KEY_BACK },
+ { 0x77fa, KEY_MENU },
+ { 0x77fb, KEY_VOLUMEUP },
+ { 0x77fc, KEY_VOLUMEDOWN },
+};
+
+static struct rc_map_list wetek_hub_map = {
+ .map = {
+ .scan = wetek_hub,
+ .size = ARRAY_SIZE(wetek_hub),
+ .rc_type = RC_TYPE_NEC,
+ .name = RC_MAP_WETEK_HUB,
+ }
+};
+
+static int __init init_rc_map_wetek_hub(void)
+{
+ return rc_map_register(&wetek_hub_map);
+}
+
+static void __exit exit_rc_map_wetek_hub(void)
+{
+ rc_map_unregister(&wetek_hub_map);
+}
+
+module_init(init_rc_map_wetek_hub)
+module_exit(exit_rc_map_wetek_hub)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("WeTek");
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index f1badbfbca90..cd8590c99e22 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -209,6 +209,7 @@ void rc_map_init(void);
#define RC_MAP_TT_1500 "rc-tt-1500"
#define RC_MAP_TWINHAN_DTV_CAB_CI "rc-twinhan-dtv-cab-ci"
#define RC_MAP_TWINHAN_VP1027_DVBS "rc-twinhan1027"
+#define RC_MAP_WETEK_HUB "rc-wetek-hub"
#define RC_MAP_VIDEOMATE_K100 "rc-videomate-k100"
#define RC_MAP_VIDEOMATE_S350 "rc-videomate-s350"
#define RC_MAP_VIDEOMATE_TV_PVR "rc-videomate-tv-pvr"
From 03250f10b133c09eb0d8793b89afe760572c1f9e Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Wed, 6 Sep 2017 18:39:09 +0200
Subject: [PATCH] [media] rc/keymaps: add keytable for WeTek Play 2 Remote
Controller
---
drivers/media/rc/keymaps/Makefile | 1 +
drivers/media/rc/keymaps/rc-wetek-play-2.c | 83 ++++++++++++++++++++++++++++++
include/media/rc-map.h | 1 +
3 files changed, 85 insertions(+)
create mode 100644 drivers/media/rc/keymaps/rc-wetek-play-2.c
diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index e8e6434cbc13..650481039f00 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -102,6 +102,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
rc-twinhan-dtv-cab-ci.o \
rc-twinhan1027.o \
rc-wetek-hub.o \
+ rc-wetek-play-2.o \
rc-videomate-m1f.o \
rc-videomate-s350.o \
rc-videomate-tv-pvr.o \
diff --git a/drivers/media/rc/keymaps/rc-wetek-play-2.c b/drivers/media/rc/keymaps/rc-wetek-play-2.c
new file mode 100644
index 000000000000..37586cedbb8a
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-wetek-play-2.c
@@ -0,0 +1,83 @@
+/* Keytable for WeTek Play 2 Remote Controller
+ *
+ * Copyright (c) 2017 WeTek
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+static struct rc_map_table wetek_play_2[] = {
+ { 0x5e5f02, KEY_POWER },
+ { 0x5e5f46, KEY_POWER2 },
+ { 0x5e5f10, KEY_MUTE },
+ { 0x5e5f22, KEY_NUMERIC_1 },
+ { 0x5e5f23, KEY_NUMERIC_2 },
+ { 0x5e5f24, KEY_NUMERIC_3 },
+ { 0x5e5f25, KEY_NUMERIC_4 },
+ { 0x5e5f26, KEY_NUMERIC_5 },
+ { 0x5e5f27, KEY_NUMERIC_6 },
+ { 0x5e5f28, KEY_NUMERIC_7 },
+ { 0x5e5f29, KEY_NUMERIC_8 },
+ { 0x5e5f30, KEY_NUMERIC_9 },
+ { 0x5e5f71, KEY_BACKSPACE },
+ { 0x5e5f21, KEY_NUMERIC_0 },
+ { 0x5e5f72, KEY_CAPSLOCK },
+ { 0x5e5f03, KEY_HOME },
+ { 0x5e5f48, KEY_MENU },
+ { 0x5e5f61, KEY_BACK },
+ { 0x5e5f83, KEY_INFO },
+ { 0x5e5f84, KEY_COMPOSE },
+ { 0x5e5f77, KEY_HELP },
+ { 0x5e5f50, KEY_UP },
+ { 0x5e5f4b, KEY_DOWN },
+ { 0x5e5f4c, KEY_LEFT },
+ { 0x5e5f4d, KEY_RIGHT },
+ { 0x5e5f47, KEY_OK },
+ { 0x5e5f44, KEY_VOLUMEUP },
+ { 0x5e5f43, KEY_VOLUMEDOWN },
+ { 0x5e5f41, KEY_CHANNELUP },
+ { 0x5e5f42, KEY_CHANNELDOWN },
+ { 0x5e5f4f, KEY_ZENKAKUHANKAKU },
+ { 0x5e5f82, KEY_TEXT },
+ { 0x5e5f73, KEY_RED },
+ { 0x5e5f74, KEY_GREEN },
+ { 0x5e5f75, KEY_YELLOW },
+ { 0x5e5f76, KEY_BLUE },
+ { 0x5e5f67, KEY_PREVIOUS },
+ { 0x5e5f79, KEY_REWIND },
+ { 0x5e5f80, KEY_FASTFORWARD },
+ { 0x5e5f81, KEY_NEXT },
+ { 0x5e5f04, KEY_RECORD },
+ { 0x5e5f2c, KEY_PLAYPAUSE },
+ { 0x5e5f2b, KEY_STOP },
+};
+
+static struct rc_map_list wetek_play_2_map = {
+ .map = {
+ .scan = wetek_play_2,
+ .size = ARRAY_SIZE(wetek_play_2),
+ .rc_type = RC_TYPE_NEC,
+ .name = RC_MAP_WETEK_PLAY_2,
+ }
+};
+
+static int __init init_rc_map_wetek_play_2(void)
+{
+ return rc_map_register(&wetek_play_2_map);
+}
+
+static void __exit exit_rc_map_wetek_play_2(void)
+{
+ rc_map_unregister(&wetek_play_2_map);
+}
+
+module_init(init_rc_map_wetek_play_2)
+module_exit(exit_rc_map_wetek_play_2)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("WeTek");
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index cd8590c99e22..93cac05a5170 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -210,6 +210,7 @@ void rc_map_init(void);
#define RC_MAP_TWINHAN_DTV_CAB_CI "rc-twinhan-dtv-cab-ci"
#define RC_MAP_TWINHAN_VP1027_DVBS "rc-twinhan1027"
#define RC_MAP_WETEK_HUB "rc-wetek-hub"
+#define RC_MAP_WETEK_PLAY_2 "rc-wetek-play-2"
#define RC_MAP_VIDEOMATE_K100 "rc-videomate-k100"
#define RC_MAP_VIDEOMATE_S350 "rc-videomate-s350"
#define RC_MAP_VIDEOMATE_TV_PVR "rc-videomate-tv-pvr"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,870 @@
From 7894722c99f2be6806a245c2db1c0df61e890096 Mon Sep 17 00:00:00 2001
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Date: Fri, 25 Nov 2016 14:12:01 +0100
Subject: [PATCH] UPSTREAM: net: phy: realtek: fix enabling of the TX-delay for
RTL8211F
The old logic always enabled the TX-delay when the phy-mode was set to
PHY_INTERFACE_MODE_RGMII. There are dedicated phy-modes which tell the
PHY driver to enable the RX and/or TX delays:
- PHY_INTERFACE_MODE_RGMII should disable the RX and TX delay in the
PHY (if required, the MAC should add the delays in this case)
- PHY_INTERFACE_MODE_RGMII_ID should enable RX and TX delay in the PHY
- PHY_INTERFACE_MODE_RGMII_TXID should enable the TX delay in the PHY
- PHY_INTERFACE_MODE_RGMII_RXID should enable the RX delay in the PHY
(currently not supported by RTL8211F)
With this patch we enable the TX delay for PHY_INTERFACE_MODE_RGMII_ID
and PHY_INTERFACE_MODE_RGMII_TXID.
Additionally we now explicity disable the TX-delay, which seems to be
enabled automatically after a hard-reset of the PHY (by triggering it's
reset pin) to get a consistent state (as defined by the phy-mode).
This fixes a compatibility problem with some SoCs where the TX-delay was
also added by the MAC. With the TX-delay being applied twice the TX
clock was off and TX traffic was broken or very slow (<10Mbit/s) on
1000Mbit/s links.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit e3230494b57ece68750e3e32d3e53d6b00917058)
---
drivers/net/phy/realtek.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 43ab691362d4..686f3b259dc0 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -102,15 +102,19 @@ static int rtl8211f_config_init(struct phy_device *phydev)
if (ret < 0)
return ret;
- if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
- /* enable TXDLY */
- phy_write(phydev, RTL8211F_PAGE_SELECT, 0xd08);
- reg = phy_read(phydev, 0x11);
+ phy_write(phydev, RTL8211F_PAGE_SELECT, 0xd08);
+ reg = phy_read(phydev, 0x11);
+
+ /* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+ phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
reg |= RTL8211F_TX_DELAY;
- phy_write(phydev, 0x11, reg);
- /* restore to default page 0 */
- phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0);
- }
+ else
+ reg &= ~RTL8211F_TX_DELAY;
+
+ phy_write(phydev, 0x11, reg);
+ /* restore to default page 0 */
+ phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0);
return 0;
}
From 91f88fe0a8ae6a575e42384236ddac74a7343f33 Mon Sep 17 00:00:00 2001
From: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
Date: Tue, 12 Sep 2017 18:54:35 +0900
Subject: [PATCH] UPSTREAM: net: phy: realtek: rename RTL8211F_PAGE_SELECT to
RTL821x_PAGE_SELECT
This renames the definition of page select register from
RTL8211F_PAGE_SELECT to RTL821x_PAGE_SELECT to use it across models.
Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 013955a6556766a76f9f2cc31e740fc6db6ecff4)
---
drivers/net/phy/realtek.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 686f3b259dc0..d58cc8f518ac 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -22,11 +22,11 @@
#define RTL821x_INER 0x12
#define RTL821x_INER_INIT 0x6400
#define RTL821x_INSR 0x13
+#define RTL821x_PAGE_SELECT 0x1f
#define RTL8211E_INER_LINK_STATUS 0x400
#define RTL8211F_INER_LINK_STATUS 0x0010
#define RTL8211F_INSR 0x1d
-#define RTL8211F_PAGE_SELECT 0x1f
#define RTL8211F_TX_DELAY 0x100
MODULE_DESCRIPTION("Realtek PHY driver");
@@ -46,10 +46,10 @@ static int rtl8211f_ack_interrupt(struct phy_device *phydev)
{
int err;
- phy_write(phydev, RTL8211F_PAGE_SELECT, 0xa43);
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0xa43);
err = phy_read(phydev, RTL8211F_INSR);
/* restore to default page 0 */
- phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0);
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
return (err < 0) ? err : 0;
}
@@ -102,7 +102,7 @@ static int rtl8211f_config_init(struct phy_device *phydev)
if (ret < 0)
return ret;
- phy_write(phydev, RTL8211F_PAGE_SELECT, 0xd08);
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0xd08);
reg = phy_read(phydev, 0x11);
/* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
@@ -114,7 +114,7 @@ static int rtl8211f_config_init(struct phy_device *phydev)
phy_write(phydev, 0x11, reg);
/* restore to default page 0 */
- phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0);
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
return 0;
}
From 418a6d18802923ffc35b9d8d40ce97a7d44f4482 Mon Sep 17 00:00:00 2001
From: Jassi Brar <jaswinder.singh@linaro.org>
Date: Tue, 12 Sep 2017 18:54:36 +0900
Subject: [PATCH] UPSTREAM: net: phy: realtek: add RTL8201F phy-id and
functions
Add RTL8201F phy-id and the related functions to the driver.
The original patch is as follows:
https://patchwork.kernel.org/patch/2538341/
Signed-off-by: Jongsung Kim <neidhard.kim@lge.com>
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 513588dd44b09bb5fdd5066a4fbc1e7443b86d1c)
---
drivers/net/phy/realtek.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index d58cc8f518ac..422cf1f6a60c 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -29,10 +29,22 @@
#define RTL8211F_INSR 0x1d
#define RTL8211F_TX_DELAY 0x100
+#define RTL8201F_ISR 0x1e
+#define RTL8201F_IER 0x13
+
MODULE_DESCRIPTION("Realtek PHY driver");
MODULE_AUTHOR("Johnson Leung");
MODULE_LICENSE("GPL");
+static int rtl8201_ack_interrupt(struct phy_device *phydev)
+{
+ int err;
+
+ err = phy_read(phydev, RTL8201F_ISR);
+
+ return (err < 0) ? err : 0;
+}
+
static int rtl821x_ack_interrupt(struct phy_device *phydev)
{
int err;
@@ -54,6 +66,25 @@ static int rtl8211f_ack_interrupt(struct phy_device *phydev)
return (err < 0) ? err : 0;
}
+static int rtl8201_config_intr(struct phy_device *phydev)
+{
+ int err;
+
+ /* switch to page 7 */
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0x7);
+
+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
+ err = phy_write(phydev, RTL8201F_IER,
+ BIT(13) | BIT(12) | BIT(11));
+ else
+ err = phy_write(phydev, RTL8201F_IER, 0);
+
+ /* restore to default page 0 */
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
+
+ return err;
+}
+
static int rtl8211b_config_intr(struct phy_device *phydev)
{
int err;
@@ -129,6 +160,18 @@ static struct phy_driver realtek_drvs[] = {
.config_aneg = &genphy_config_aneg,
.read_status = &genphy_read_status,
.driver = { .owner = THIS_MODULE,},
+ }, {
+ .phy_id = 0x001cc816,
+ .name = "RTL8201F 10/100Mbps Ethernet",
+ .phy_id_mask = 0x001fffff,
+ .features = PHY_BASIC_FEATURES,
+ .flags = PHY_HAS_INTERRUPT,
+ .config_aneg = &genphy_config_aneg,
+ .read_status = &genphy_read_status,
+ .ack_interrupt = &rtl8201_ack_interrupt,
+ .config_intr = &rtl8201_config_intr,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
}, {
.phy_id = 0x001cc912,
.name = "RTL8211B Gigabit Ethernet",
@@ -186,6 +229,7 @@ static struct phy_driver realtek_drvs[] = {
module_phy_driver(realtek_drvs);
static struct mdio_device_id __maybe_unused realtek_tbl[] = {
+ { 0x001cc816, 0x001fffff },
{ 0x001cc912, 0x001fffff },
{ 0x001cc914, 0x001fffff },
{ 0x001cc915, 0x001fffff },
From 0e7b02714fa25f16aebcb917fa7017aded5bdf06 Mon Sep 17 00:00:00 2001
From: Heiner Kallweit <hkallweit1@gmail.com>
Date: Sun, 12 Nov 2017 16:16:04 +0100
Subject: [PATCH] UPSTREAM: net: phy: realtek: fix RTL8211F interrupt mode
After commit b94d22d94ad22 "ARM64: dts: meson-gx: add external PHY
interrupt on some platforms" ethernet stopped working on my Odroid-C2
which has a RTL8211F phy.
It turned out that no interrupts were triggered. Further analysis
showed the register INER can't be altered on page 0.
Because register INSR needs to be accessed via page 0xa43 I assumed
that register INER needs to be accessed via some page too.
Some brute force check resulted in page 0xa42 being the right one.
With this patch the phy is working properly in interrupt mode.
Fixes: 3447cf2e9a11 ("net/phy: Add support for Realtek RTL8211F")
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Tested-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 3697d058b08d5b874f0253de173ef72e5d648f9a)
---
drivers/net/phy/realtek.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 422cf1f6a60c..a30d0c08c63b 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -115,11 +115,13 @@ static int rtl8211f_config_intr(struct phy_device *phydev)
{
int err;
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0xa42);
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
err = phy_write(phydev, RTL821x_INER,
RTL8211F_INER_LINK_STATUS);
else
err = phy_write(phydev, RTL821x_INER, 0);
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0);
return err;
}
From 013120bec5f5e717baf7465e0eaafd6e5141d8c6 Mon Sep 17 00:00:00 2001
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Date: Sat, 2 Dec 2017 22:51:24 +0100
Subject: [PATCH] UPSTREAM: net: phy: realtek: use the BIT and GENMASK macros
This makes it easier to compare the #defines with the datasheets.
No functional changes.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 8cc5baefbc0266b6d6c8e99cb8568f59be36a575)
---
drivers/net/phy/realtek.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index a30d0c08c63b..f8dc29a75828 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -13,21 +13,22 @@
* option) any later version.
*
*/
+#include <linux/bitops.h>
#include <linux/phy.h>
#include <linux/module.h>
#define RTL821x_PHYSR 0x11
-#define RTL821x_PHYSR_DUPLEX 0x2000
-#define RTL821x_PHYSR_SPEED 0xc000
+#define RTL821x_PHYSR_DUPLEX BIT(13)
+#define RTL821x_PHYSR_SPEED GENMASK(15, 14)
#define RTL821x_INER 0x12
#define RTL821x_INER_INIT 0x6400
#define RTL821x_INSR 0x13
#define RTL821x_PAGE_SELECT 0x1f
-#define RTL8211E_INER_LINK_STATUS 0x400
+#define RTL8211E_INER_LINK_STATUS BIT(10)
-#define RTL8211F_INER_LINK_STATUS 0x0010
+#define RTL8211F_INER_LINK_STATUS BIT(4)
#define RTL8211F_INSR 0x1d
-#define RTL8211F_TX_DELAY 0x100
+#define RTL8211F_TX_DELAY BIT(8)
#define RTL8201F_ISR 0x1e
#define RTL8201F_IER 0x13
From ac2c0298c225eacc49b74a6f723b18a99a7b4b28 Mon Sep 17 00:00:00 2001
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Date: Sat, 2 Dec 2017 22:51:25 +0100
Subject: [PATCH] UPSTREAM: net: phy: realtek: rename RTL821x_INER_INIT to
RTL8211B_INER_INIT
This macro is only used by the RTL8211B code. RTL8211E and RTL8211F both
use other bits to initialize the RTL821x_INER register.
No functional changes.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 69021e32ec3ef02170482f6ed8130febaed27357)
---
drivers/net/phy/realtek.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index f8dc29a75828..89308eac4088 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -21,7 +21,7 @@
#define RTL821x_PHYSR_DUPLEX BIT(13)
#define RTL821x_PHYSR_SPEED GENMASK(15, 14)
#define RTL821x_INER 0x12
-#define RTL821x_INER_INIT 0x6400
+#define RTL8211B_INER_INIT 0x6400
#define RTL821x_INSR 0x13
#define RTL821x_PAGE_SELECT 0x1f
#define RTL8211E_INER_LINK_STATUS BIT(10)
@@ -92,7 +92,7 @@ static int rtl8211b_config_intr(struct phy_device *phydev)
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
err = phy_write(phydev, RTL821x_INER,
- RTL821x_INER_INIT);
+ RTL8211B_INER_INIT);
else
err = phy_write(phydev, RTL821x_INER, 0);
From 68e38ec78893a72b91255eaf56e1aa5dfcf81d1f Mon Sep 17 00:00:00 2001
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Date: Sat, 2 Dec 2017 22:51:26 +0100
Subject: [PATCH] UPSTREAM: net: phy: realtek: group all register bit #defines
for RTL821x_INER
This simply moves all register bit #defines which describe the (PHY
specific) bits in the RTL821x_INER right below the RTL821x_INER register
definition. This makes it easier to spot which registers and bits belong
together.
No functional changes.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit a82f266d240d87e6111878bbfe287024fb6857c1)
---
drivers/net/phy/realtek.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 89308eac4088..df97d903d2bf 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -20,13 +20,16 @@
#define RTL821x_PHYSR 0x11
#define RTL821x_PHYSR_DUPLEX BIT(13)
#define RTL821x_PHYSR_SPEED GENMASK(15, 14)
+
#define RTL821x_INER 0x12
#define RTL8211B_INER_INIT 0x6400
+#define RTL8211E_INER_LINK_STATUS BIT(10)
+#define RTL8211F_INER_LINK_STATUS BIT(4)
+
#define RTL821x_INSR 0x13
+
#define RTL821x_PAGE_SELECT 0x1f
-#define RTL8211E_INER_LINK_STATUS BIT(10)
-#define RTL8211F_INER_LINK_STATUS BIT(4)
#define RTL8211F_INSR 0x1d
#define RTL8211F_TX_DELAY BIT(8)
From 89b955d9f11cc268626cdedbf75561ccc607bb90 Mon Sep 17 00:00:00 2001
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Date: Sat, 2 Dec 2017 22:51:27 +0100
Subject: [PATCH] UPSTREAM: net: phy: realtek: use the same indentation for all
#defines
This simply makes the code easier to read. No functional changes.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit f609ab0ed8e7bef2cd61d230bf9e83e1ec5b9ddb)
---
drivers/net/phy/realtek.c | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index df97d903d2bf..701f34ad7d8d 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -17,24 +17,25 @@
#include <linux/phy.h>
#include <linux/module.h>
-#define RTL821x_PHYSR 0x11
-#define RTL821x_PHYSR_DUPLEX BIT(13)
-#define RTL821x_PHYSR_SPEED GENMASK(15, 14)
+#define RTL821x_PHYSR 0x11
+#define RTL821x_PHYSR_DUPLEX BIT(13)
+#define RTL821x_PHYSR_SPEED GENMASK(15, 14)
-#define RTL821x_INER 0x12
-#define RTL8211B_INER_INIT 0x6400
-#define RTL8211E_INER_LINK_STATUS BIT(10)
-#define RTL8211F_INER_LINK_STATUS BIT(4)
+#define RTL821x_INER 0x12
+#define RTL8211B_INER_INIT 0x6400
+#define RTL8211E_INER_LINK_STATUS BIT(10)
+#define RTL8211F_INER_LINK_STATUS BIT(4)
-#define RTL821x_INSR 0x13
+#define RTL821x_INSR 0x13
-#define RTL821x_PAGE_SELECT 0x1f
+#define RTL821x_PAGE_SELECT 0x1f
-#define RTL8211F_INSR 0x1d
-#define RTL8211F_TX_DELAY BIT(8)
+#define RTL8211F_INSR 0x1d
-#define RTL8201F_ISR 0x1e
-#define RTL8201F_IER 0x13
+#define RTL8211F_TX_DELAY BIT(8)
+
+#define RTL8201F_ISR 0x1e
+#define RTL8201F_IER 0x13
MODULE_DESCRIPTION("Realtek PHY driver");
MODULE_AUTHOR("Johnson Leung");
From 304312f104de088682456d4cf7353732685fe455 Mon Sep 17 00:00:00 2001
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Date: Sat, 2 Dec 2017 22:51:28 +0100
Subject: [PATCH] UPSTREAM: net: phy: realtek: add utility functions to
read/write page addresses
Realtek PHYs implement the concept of so-called "extension pages". The
reason for this is probably because these PHYs expose more registers
than available in the standard address range.
After all read/write operations on such a page are done the driver
should switch back to page 0 where the standard MII registers (such as
MII_BMCR) are available.
When referring to such a register the datasheets of RTL8211E and
RTL8211F always specify:
- the page / "ext. page" which has to be written to RTL821x_PAGE_SELECT
- an address (sometimes also called reg)
These new utility functions make the existing code easier to read since
it removes some duplication (switching back to page 0 is done within the
new helpers for example).
No functional changes are intended.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 136819a6e8df374e6b9b424586ff11c9e241a1cb)
---
drivers/net/phy/realtek.c | 83 ++++++++++++++++++++++++++++++-----------------
1 file changed, 53 insertions(+), 30 deletions(-)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 701f34ad7d8d..b1d52e61d91c 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -41,6 +41,39 @@ MODULE_DESCRIPTION("Realtek PHY driver");
MODULE_AUTHOR("Johnson Leung");
MODULE_LICENSE("GPL");
+static int rtl8211x_page_read(struct phy_device *phydev, u16 page, u16 address)
+{
+ int ret;
+
+ ret = phy_write(phydev, RTL821x_PAGE_SELECT, page);
+ if (ret)
+ return ret;
+
+ ret = phy_read(phydev, address);
+
+ /* restore to default page 0 */
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
+
+ return ret;
+}
+
+static int rtl8211x_page_write(struct phy_device *phydev, u16 page,
+ u16 address, u16 val)
+{
+ int ret;
+
+ ret = phy_write(phydev, RTL821x_PAGE_SELECT, page);
+ if (ret)
+ return ret;
+
+ ret = phy_write(phydev, address, val);
+
+ /* restore to default page 0 */
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
+
+ return ret;
+}
+
static int rtl8201_ack_interrupt(struct phy_device *phydev)
{
int err;
@@ -63,31 +96,21 @@ static int rtl8211f_ack_interrupt(struct phy_device *phydev)
{
int err;
- phy_write(phydev, RTL821x_PAGE_SELECT, 0xa43);
- err = phy_read(phydev, RTL8211F_INSR);
- /* restore to default page 0 */
- phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
+ err = rtl8211x_page_read(phydev, 0xa43, RTL8211F_INSR);
return (err < 0) ? err : 0;
}
static int rtl8201_config_intr(struct phy_device *phydev)
{
- int err;
-
- /* switch to page 7 */
- phy_write(phydev, RTL821x_PAGE_SELECT, 0x7);
+ u16 val;
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
- err = phy_write(phydev, RTL8201F_IER,
- BIT(13) | BIT(12) | BIT(11));
+ val = BIT(13) | BIT(12) | BIT(11);
else
- err = phy_write(phydev, RTL8201F_IER, 0);
+ val = 0;
- /* restore to default page 0 */
- phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
-
- return err;
+ return rtl8211x_page_write(phydev, 0x7, RTL8201F_IER, val);
}
static int rtl8211b_config_intr(struct phy_device *phydev)
@@ -118,41 +141,41 @@ static int rtl8211e_config_intr(struct phy_device *phydev)
static int rtl8211f_config_intr(struct phy_device *phydev)
{
- int err;
+ u16 val;
- phy_write(phydev, RTL821x_PAGE_SELECT, 0xa42);
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
- err = phy_write(phydev, RTL821x_INER,
- RTL8211F_INER_LINK_STATUS);
+ val = RTL8211F_INER_LINK_STATUS;
else
- err = phy_write(phydev, RTL821x_INER, 0);
- phy_write(phydev, RTL821x_PAGE_SELECT, 0);
+ val = 0;
- return err;
+ return rtl8211x_page_write(phydev, 0xa42, RTL821x_INER, val);
}
static int rtl8211f_config_init(struct phy_device *phydev)
{
int ret;
- u16 reg;
+ u16 val;
ret = genphy_config_init(phydev);
if (ret < 0)
return ret;
- phy_write(phydev, RTL821x_PAGE_SELECT, 0xd08);
- reg = phy_read(phydev, 0x11);
+ ret = rtl8211x_page_read(phydev, 0xd08, 0x11);
+ if (ret < 0)
+ return ret;
+
+ val = ret & 0xffff;
/* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
- reg |= RTL8211F_TX_DELAY;
+ val |= RTL8211F_TX_DELAY;
else
- reg &= ~RTL8211F_TX_DELAY;
+ val &= ~RTL8211F_TX_DELAY;
- phy_write(phydev, 0x11, reg);
- /* restore to default page 0 */
- phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
+ ret = rtl8211x_page_write(phydev, 0xd08, 0x11, val);
+ if (ret)
+ return ret;
return 0;
}
From aa354e4db670dda7682b1c4aed23cd6ffb51f715 Mon Sep 17 00:00:00 2001
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Date: Sat, 2 Dec 2017 23:06:48 +0100
Subject: [PATCH] FROMLIST: net: phy: realtek: add support for configuring the
RX delay on RTL8211F
On RTL8211F the RX delay can also be enabled/disabled.
The overall behavior of the RX delay is similar to the behavior of the
TX delay, which was already supported by the driver.
The RX delay (similar to the TX delay) may be enabled using hardware pin
strapping. If the MAC already configures the RX delay (if required) then
the RX delay generated by the RTL8211F PHY has to be turned off.
While here, update the comment regarding the TX delay why it has to be
enabled or disabled within the driver.
Also avoid code-duplication by extracting the code to mask/unmask bits
in a paged register into a new rtl8211x_page_mask_bits helper function.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
drivers/net/phy/realtek.c | 55 ++++++++++++++++++++++++++++++++++++++---------
1 file changed, 45 insertions(+), 10 deletions(-)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index b1d52e61d91c..890ea9d18d27 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -32,7 +32,10 @@
#define RTL8211F_INSR 0x1d
-#define RTL8211F_TX_DELAY BIT(8)
+#define RTL8211F_RX_DELAY_REG 0x15
+#define RTL8211F_RX_DELAY_EN BIT(3)
+#define RTL8211F_TX_DELAY_REG 0x11
+#define RTL8211F_TX_DELAY_EN BIT(8)
#define RTL8201F_ISR 0x1e
#define RTL8201F_IER 0x13
@@ -74,6 +77,23 @@ static int rtl8211x_page_write(struct phy_device *phydev, u16 page,
return ret;
}
+static int rtl8211x_page_mask_bits(struct phy_device *phydev, u16 page,
+ u16 address, u16 mask, u16 set)
+{
+ int ret;
+ u16 val;
+
+ ret = rtl8211x_page_read(phydev, page, address);
+ if (ret < 0)
+ return ret;
+
+ val = ret & 0xffff;
+ val &= ~mask;
+ val |= (set & mask);
+
+ return rtl8211x_page_write(phydev, page, address, val);
+}
+
static int rtl8201_ack_interrupt(struct phy_device *phydev)
{
int err;
@@ -160,20 +180,35 @@ static int rtl8211f_config_init(struct phy_device *phydev)
if (ret < 0)
return ret;
- ret = rtl8211x_page_read(phydev, 0xd08, 0x11);
- if (ret < 0)
- return ret;
+ /*
+ * enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it.
+ * this is needed because it can be enabled by pin strapping and
+ * conflict with the TX-delay configured by the MAC.
+ */
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+ phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
+ val = RTL8211F_TX_DELAY_EN;
+ else
+ val = 0;
- val = ret & 0xffff;
+ ret = rtl8211x_page_mask_bits(phydev, 0xd08, RTL8211F_TX_DELAY_REG,
+ RTL8211F_TX_DELAY_EN, val);
+ if (ret)
+ return ret;
- /* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
+ /*
+ * enable RX-delay for rgmii-id and rgmii-rxid, otherwise disable it.
+ * this is needed because it can be enabled by pin strapping and
+ * conflict with the RX-delay configured by the MAC.
+ */
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
- phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
- val |= RTL8211F_TX_DELAY;
+ phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
+ val = RTL8211F_RX_DELAY_EN;
else
- val &= ~RTL8211F_TX_DELAY;
+ val = 0;
- ret = rtl8211x_page_write(phydev, 0xd08, 0x11, val);
+ ret = rtl8211x_page_mask_bits(phydev, 0xd08, RTL8211F_RX_DELAY_REG,
+ RTL8211F_RX_DELAY_EN, val);
if (ret)
return ret;
From 1503227b699167969f0c630a95f73e7760edefbc Mon Sep 17 00:00:00 2001
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Date: Sat, 2 Dec 2017 23:06:49 +0100
Subject: [PATCH] FROMLIST: net: phy: realtek: configure the INTB pin on
RTL8211F
The interrupt pin on the RTL8211F PHY can be used in two different
modes:
INTB
- the default mode of the PHY
- interrupts can be configured through page 0xa42 register RTL821x_INER
- interrupts can be ACK'ed through RTL8211F_INSR
- it acts as a level-interrupt which is active low
- Wake-on-LAN "wakeup" status is available in RTL8211F_INSR bit 7
PMEB:
- special mode for Wake-on-LAN
- interrupts configured through page 0xa42 register RTL821x_INER are
disabled
- it supports a "pulse low" waveform for the interrupt
For now we simply force the pin into INTB mode since the PHY driver does
not support Wake-on-LAN yet.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
drivers/net/phy/realtek.c | 27 +++++++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 890ea9d18d27..f307d220b49a 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -40,6 +40,9 @@
#define RTL8201F_ISR 0x1e
#define RTL8201F_IER 0x13
+#define RTL8211F_INTBCR 0x16
+#define RTL8211F_INTBCR_INTB_PMEB BIT(5)
+
MODULE_DESCRIPTION("Realtek PHY driver");
MODULE_AUTHOR("Johnson Leung");
MODULE_LICENSE("GPL");
@@ -161,12 +164,32 @@ static int rtl8211e_config_intr(struct phy_device *phydev)
static int rtl8211f_config_intr(struct phy_device *phydev)
{
+ int err;
u16 val;
- if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
+ /*
+ * The interrupt pin has two functions:
+ * 0: INTB: it acts as interrupt pin which can be configured
+ * through RTL821x_INER and the status can be read through
+ * RTL8211F_INSR
+ * 1: PMEB: a special "Power Management Event" mode for
+ * Wake-on-LAN operation (with support for a "pulse low"
+ * wave format). Interrupts configured through RTL821x_INER
+ * will not work in this mode
+ *
+ * select INTB mode in the "INTB pin control" register to
+ * ensure that the interrupt pin is in the correct mode.
+ */
+ err = rtl8211x_page_mask_bits(phydev, 0xd40, RTL8211F_INTBCR,
+ RTL8211F_INTBCR_INTB_PMEB, 0);
+ if (err)
+ return err;
+
val = RTL8211F_INER_LINK_STATUS;
- else
+ } else {
val = 0;
+ }
return rtl8211x_page_write(phydev, 0xa42, RTL821x_INER, val);
}
From 429c1855e10305c2838913a9dc074bd70831bb14 Mon Sep 17 00:00:00 2001
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Date: Sat, 2 Dec 2017 23:06:50 +0100
Subject: [PATCH] FROMLIST: net: phy: realtek: add more interrupt bits for
RTL8211E and RTL8211F
This documents a few more bits in the RTL821x_INER register for RTL8211E
and RTL8211F. These are added only to document them (as no public
datasheets are available for these PHYs), they are currently not used.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
drivers/net/phy/realtek.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index f307d220b49a..15d342eefd6d 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -24,7 +24,14 @@
#define RTL821x_INER 0x12
#define RTL8211B_INER_INIT 0x6400
#define RTL8211E_INER_LINK_STATUS BIT(10)
+#define RTL8211E_INER_ANEG_COMPLETED BIT(11)
+#define RTL8211E_INER_PAGE_RECEIVED BIT(12)
+#define RTL8211E_INER_ANEG_ERROR BIT(15)
#define RTL8211F_INER_LINK_STATUS BIT(4)
+#define RTL8211F_INER_PHY_REGISTER_ACCESSIBLE BIT(5)
+#define RTL8211F_INER_WOL_PME BIT(7)
+#define RTL8211F_INER_ALDPS_STATE_CHANGE BIT(9)
+#define RTL8211F_INER_JABBER BIT(10)
#define RTL821x_INSR 0x13

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,949 @@
From 3c894b625c24537d22213836dbc44e1973b2b1f4 Mon Sep 17 00:00:00 2001
From: Julia Lawall <Julia.Lawall@lip6.fr>
Date: Sat, 14 Nov 2015 18:05:20 +0100
Subject: [PATCH] UPSTREAM: mmc: pwrseq: constify mmc_pwrseq_ops structures
The mmc_pwrseq_ops structures are never modified, so declare them as const.
Done with the help of Coccinelle.
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
(cherry picked from commit ffedbd2210f2f4cba490a9205adc11fd1b89a852)
---
drivers/mmc/core/pwrseq.h | 2 +-
drivers/mmc/core/pwrseq_emmc.c | 2 +-
drivers/mmc/core/pwrseq_simple.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/mmc/core/pwrseq.h b/drivers/mmc/core/pwrseq.h
index 096da48c6a7e..133de0426687 100644
--- a/drivers/mmc/core/pwrseq.h
+++ b/drivers/mmc/core/pwrseq.h
@@ -16,7 +16,7 @@ struct mmc_pwrseq_ops {
};
struct mmc_pwrseq {
- struct mmc_pwrseq_ops *ops;
+ const struct mmc_pwrseq_ops *ops;
};
#ifdef CONFIG_OF
diff --git a/drivers/mmc/core/pwrseq_emmc.c b/drivers/mmc/core/pwrseq_emmc.c
index ad4f94ec7e8d..4a82bc77fe49 100644
--- a/drivers/mmc/core/pwrseq_emmc.c
+++ b/drivers/mmc/core/pwrseq_emmc.c
@@ -51,7 +51,7 @@ static void mmc_pwrseq_emmc_free(struct mmc_host *host)
kfree(pwrseq);
}
-static struct mmc_pwrseq_ops mmc_pwrseq_emmc_ops = {
+static const struct mmc_pwrseq_ops mmc_pwrseq_emmc_ops = {
.post_power_on = mmc_pwrseq_emmc_reset,
.free = mmc_pwrseq_emmc_free,
};
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c
index d10538bb5e07..2b16263458af 100644
--- a/drivers/mmc/core/pwrseq_simple.c
+++ b/drivers/mmc/core/pwrseq_simple.c
@@ -87,7 +87,7 @@ static void mmc_pwrseq_simple_free(struct mmc_host *host)
kfree(pwrseq);
}
-static struct mmc_pwrseq_ops mmc_pwrseq_simple_ops = {
+static const struct mmc_pwrseq_ops mmc_pwrseq_simple_ops = {
.pre_power_on = mmc_pwrseq_simple_pre_power_on,
.post_power_on = mmc_pwrseq_simple_post_power_on,
.power_off = mmc_pwrseq_simple_power_off,
From 11396ee87b7a090c5807c2fc2b8a640d109c30ce Mon Sep 17 00:00:00 2001
From: Martin Fuzzey <mfuzzey@parkeon.com>
Date: Wed, 20 Jan 2016 16:08:03 +0100
Subject: [PATCH] UPSTREAM: mmc: pwrseq_simple: Make reset-gpios optional to
match doc
The DT binding doc says reset-gpios is an optional property but the code
currently bails out if it is omitted.
This is a regression since it breaks previously working device trees.
Fix it by restoring the original documented behaviour.
Fixes: ce037275861e ("mmc: pwrseq_simple: use GPIO descriptors array API")
Tested-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Martin Fuzzey <mfuzzey@parkeon.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
(cherry picked from commit 64a67d4762ce3ce4c9466eadd152d825fbf84967)
---
drivers/mmc/core/pwrseq_simple.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c
index 2b16263458af..aba786daebca 100644
--- a/drivers/mmc/core/pwrseq_simple.c
+++ b/drivers/mmc/core/pwrseq_simple.c
@@ -29,15 +29,18 @@ struct mmc_pwrseq_simple {
static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq,
int value)
{
- int i;
struct gpio_descs *reset_gpios = pwrseq->reset_gpios;
- int values[reset_gpios->ndescs];
- for (i = 0; i < reset_gpios->ndescs; i++)
- values[i] = value;
+ if (!IS_ERR(reset_gpios)) {
+ int i;
+ int values[reset_gpios->ndescs];
- gpiod_set_array_value_cansleep(reset_gpios->ndescs, reset_gpios->desc,
- values);
+ for (i = 0; i < reset_gpios->ndescs; i++)
+ values[i] = value;
+
+ gpiod_set_array_value_cansleep(
+ reset_gpios->ndescs, reset_gpios->desc, values);
+ }
}
static void mmc_pwrseq_simple_pre_power_on(struct mmc_host *host)
@@ -79,7 +82,8 @@ static void mmc_pwrseq_simple_free(struct mmc_host *host)
struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq,
struct mmc_pwrseq_simple, pwrseq);
- gpiod_put_array(pwrseq->reset_gpios);
+ if (!IS_ERR(pwrseq->reset_gpios))
+ gpiod_put_array(pwrseq->reset_gpios);
if (!IS_ERR(pwrseq->ext_clk))
clk_put(pwrseq->ext_clk);
@@ -112,7 +116,9 @@ struct mmc_pwrseq *mmc_pwrseq_simple_alloc(struct mmc_host *host,
}
pwrseq->reset_gpios = gpiod_get_array(dev, "reset", GPIOD_OUT_HIGH);
- if (IS_ERR(pwrseq->reset_gpios)) {
+ if (IS_ERR(pwrseq->reset_gpios) &&
+ PTR_ERR(pwrseq->reset_gpios) != -ENOENT &&
+ PTR_ERR(pwrseq->reset_gpios) != -ENOSYS) {
ret = PTR_ERR(pwrseq->reset_gpios);
goto clk_put;
}
From eecad6e4c48e9e82ec2f8415dec690f67c7ba12b Mon Sep 17 00:00:00 2001
From: Peter Chen <peter.chen@freescale.com>
Date: Wed, 6 Jan 2016 11:34:10 +0800
Subject: [PATCH] UPSTREAM: mmc: core: pwrseq_simple: remove unused header file
Signed-off-by: Peter Chen <peter.chen@freescale.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
(cherry picked from commit 62c03ca3ffa1ddf55a66411be02f7e4678771fce)
---
drivers/mmc/core/pwrseq_simple.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c
index aba786daebca..bc173e18b71c 100644
--- a/drivers/mmc/core/pwrseq_simple.c
+++ b/drivers/mmc/core/pwrseq_simple.c
@@ -12,7 +12,6 @@
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/err.h>
-#include <linux/of_gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/mmc/host.h>
From ea74f89b7e6bb89a2824df5bf3ae94786f6b30b3 Mon Sep 17 00:00:00 2001
From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Date: Thu, 14 Apr 2016 14:02:14 +0100
Subject: [PATCH] UPSTREAM: mmc: pwrseq_simple: add to_pwrseq_simple() macro
This patch adds to_pwrseq_simple() macro to make the code more readable.
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
(cherry picked from commit 5b96fea730ab79bdf6f8071cadf8208296bf5e8d)
---
drivers/mmc/core/pwrseq_simple.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c
index bc173e18b71c..f94271bb1f6b 100644
--- a/drivers/mmc/core/pwrseq_simple.c
+++ b/drivers/mmc/core/pwrseq_simple.c
@@ -25,6 +25,8 @@ struct mmc_pwrseq_simple {
struct gpio_descs *reset_gpios;
};
+#define to_pwrseq_simple(p) container_of(p, struct mmc_pwrseq_simple, pwrseq)
+
static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq,
int value)
{
@@ -44,8 +46,7 @@ static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq,
static void mmc_pwrseq_simple_pre_power_on(struct mmc_host *host)
{
- struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq,
- struct mmc_pwrseq_simple, pwrseq);
+ struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq);
if (!IS_ERR(pwrseq->ext_clk) && !pwrseq->clk_enabled) {
clk_prepare_enable(pwrseq->ext_clk);
@@ -57,16 +58,14 @@ static void mmc_pwrseq_simple_pre_power_on(struct mmc_host *host)
static void mmc_pwrseq_simple_post_power_on(struct mmc_host *host)
{
- struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq,
- struct mmc_pwrseq_simple, pwrseq);
+ struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq);
mmc_pwrseq_simple_set_gpios_value(pwrseq, 0);
}
static void mmc_pwrseq_simple_power_off(struct mmc_host *host)
{
- struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq,
- struct mmc_pwrseq_simple, pwrseq);
+ struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq);
mmc_pwrseq_simple_set_gpios_value(pwrseq, 1);
@@ -78,8 +77,7 @@ static void mmc_pwrseq_simple_power_off(struct mmc_host *host)
static void mmc_pwrseq_simple_free(struct mmc_host *host)
{
- struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq,
- struct mmc_pwrseq_simple, pwrseq);
+ struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq);
if (!IS_ERR(pwrseq->reset_gpios))
gpiod_put_array(pwrseq->reset_gpios);
From 11bf8cedf08ee10e4053d8787268c69a0bd7419b Mon Sep 17 00:00:00 2001
From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Date: Thu, 14 Apr 2016 14:02:15 +0100
Subject: [PATCH] UPSTREAM: mmc: pwrseq_emmc: add to_pwrseq_emmc() macro
This patch adds to_pwrseq_emmc() macro to make the code more readable.
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
(cherry picked from commit f01b72d0fd53b61cafd25b16d15e18b1ef8ae065)
---
drivers/mmc/core/pwrseq_emmc.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/core/pwrseq_emmc.c b/drivers/mmc/core/pwrseq_emmc.c
index 4a82bc77fe49..c2d732aa464c 100644
--- a/drivers/mmc/core/pwrseq_emmc.c
+++ b/drivers/mmc/core/pwrseq_emmc.c
@@ -25,6 +25,8 @@ struct mmc_pwrseq_emmc {
struct gpio_desc *reset_gpio;
};
+#define to_pwrseq_emmc(p) container_of(p, struct mmc_pwrseq_emmc, pwrseq)
+
static void __mmc_pwrseq_emmc_reset(struct mmc_pwrseq_emmc *pwrseq)
{
gpiod_set_value(pwrseq->reset_gpio, 1);
@@ -35,16 +37,14 @@ static void __mmc_pwrseq_emmc_reset(struct mmc_pwrseq_emmc *pwrseq)
static void mmc_pwrseq_emmc_reset(struct mmc_host *host)
{
- struct mmc_pwrseq_emmc *pwrseq = container_of(host->pwrseq,
- struct mmc_pwrseq_emmc, pwrseq);
+ struct mmc_pwrseq_emmc *pwrseq = to_pwrseq_emmc(host->pwrseq);
__mmc_pwrseq_emmc_reset(pwrseq);
}
static void mmc_pwrseq_emmc_free(struct mmc_host *host)
{
- struct mmc_pwrseq_emmc *pwrseq = container_of(host->pwrseq,
- struct mmc_pwrseq_emmc, pwrseq);
+ struct mmc_pwrseq_emmc *pwrseq = to_pwrseq_emmc(host->pwrseq);
unregister_restart_handler(&pwrseq->reset_nb);
gpiod_put(pwrseq->reset_gpio);
From 9a32c48a17c3a0de3bd96cc6e9289d9fb8710b91 Mon Sep 17 00:00:00 2001
From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Date: Thu, 14 Apr 2016 14:02:16 +0100
Subject: [PATCH] UPSTREAM: mmc: pwrseq: convert to proper platform device
simple-pwrseq and emmc-pwrseq drivers rely on platform_device
structure from of_find_device_by_node(), this works mostly. But, as there
is no driver associated with this devices, cases like default/init pinctrl
setup would never be performed by pwrseq. This becomes problem when the
gpios used in pwrseq require pinctrl setup.
Currently most of the common pinctrl setup is done in
drivers/base/pinctrl.c by pinctrl_bind_pins().
There are two ways to solve this issue on either convert pwrseq drivers
to a proper platform drivers or copy the exact code from
pcintrl_bind_pins(). I prefer converting pwrseq to proper drivers so that
other cases like setting up clks/parents from dt would also be possible.
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
(cherry picked from commit d97a1e5d7cd2b5b0edc02a40fe6897b710c9e10f)
---
drivers/mmc/core/Kconfig | 22 ++++++++
drivers/mmc/core/Makefile | 4 +-
drivers/mmc/core/pwrseq.c | 108 ++++++++++++++++++---------------------
drivers/mmc/core/pwrseq.h | 19 ++++---
drivers/mmc/core/pwrseq_emmc.c | 75 +++++++++++++++++----------
drivers/mmc/core/pwrseq_simple.c | 79 +++++++++++++++-------------
6 files changed, 178 insertions(+), 129 deletions(-)
diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
index 87cc07dedd9f..00dfaea06003 100644
--- a/drivers/mmc/core/Kconfig
+++ b/drivers/mmc/core/Kconfig
@@ -16,3 +16,25 @@ config MMC_PARANOID_SD_INIT
about re-trying SD init requests. This can be a useful
work-around for buggy controllers and hardware. Enable
if you are experiencing issues with SD detection.
+
+config PWRSEQ_EMMC
+ tristate "HW reset support for eMMC"
+ default y
+ depends on OF
+ help
+ This selects Hardware reset support aka pwrseq-emmc for eMMC
+ devices. By default this option is set to y.
+
+ This driver can also be built as a module. If so, the module
+ will be called pwrseq_emmc.
+
+config PWRSEQ_SIMPLE
+ tristate "Simple HW reset support for MMC"
+ default y
+ depends on OF
+ help
+ This selects simple hardware reset support aka pwrseq-simple for MMC
+ devices. By default this option is set to y.
+
+ This driver can also be built as a module. If so, the module
+ will be called pwrseq_simple.
diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
index 2c25138f28b7..f007151dfdc6 100644
--- a/drivers/mmc/core/Makefile
+++ b/drivers/mmc/core/Makefile
@@ -8,5 +8,7 @@ mmc_core-y := core.o bus.o host.o \
sdio.o sdio_ops.o sdio_bus.o \
sdio_cis.o sdio_io.o sdio_irq.o \
quirks.o slot-gpio.o
-mmc_core-$(CONFIG_OF) += pwrseq.o pwrseq_simple.o pwrseq_emmc.o
+mmc_core-$(CONFIG_OF) += pwrseq.o
+obj-$(CONFIG_PWRSEQ_SIMPLE) += pwrseq_simple.o
+obj-$(CONFIG_PWRSEQ_EMMC) += pwrseq_emmc.o
mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o
diff --git a/drivers/mmc/core/pwrseq.c b/drivers/mmc/core/pwrseq.c
index 4c1d1757dbf9..9386c4771814 100644
--- a/drivers/mmc/core/pwrseq.c
+++ b/drivers/mmc/core/pwrseq.c
@@ -8,88 +8,55 @@
* MMC power sequence management
*/
#include <linux/kernel.h>
-#include <linux/platform_device.h>
#include <linux/err.h>
+#include <linux/module.h>
#include <linux/of.h>
-#include <linux/of_platform.h>
#include <linux/mmc/host.h>
#include "pwrseq.h"
-struct mmc_pwrseq_match {
- const char *compatible;
- struct mmc_pwrseq *(*alloc)(struct mmc_host *host, struct device *dev);
-};
-
-static struct mmc_pwrseq_match pwrseq_match[] = {
- {
- .compatible = "mmc-pwrseq-simple",
- .alloc = mmc_pwrseq_simple_alloc,
- }, {
- .compatible = "mmc-pwrseq-emmc",
- .alloc = mmc_pwrseq_emmc_alloc,
- },
-};
-
-static struct mmc_pwrseq_match *mmc_pwrseq_find(struct device_node *np)
-{
- struct mmc_pwrseq_match *match = ERR_PTR(-ENODEV);
- int i;
-
- for (i = 0; i < ARRAY_SIZE(pwrseq_match); i++) {
- if (of_device_is_compatible(np, pwrseq_match[i].compatible)) {
- match = &pwrseq_match[i];
- break;
- }
- }
-
- return match;
-}
+static DEFINE_MUTEX(pwrseq_list_mutex);
+static LIST_HEAD(pwrseq_list);
int mmc_pwrseq_alloc(struct mmc_host *host)
{
- struct platform_device *pdev;
struct device_node *np;
- struct mmc_pwrseq_match *match;
- struct mmc_pwrseq *pwrseq;
- int ret = 0;
+ struct mmc_pwrseq *p;
np = of_parse_phandle(host->parent->of_node, "mmc-pwrseq", 0);
if (!np)
return 0;
- pdev = of_find_device_by_node(np);
- if (!pdev) {
- ret = -ENODEV;
- goto err;
- }
+ mutex_lock(&pwrseq_list_mutex);
+ list_for_each_entry(p, &pwrseq_list, pwrseq_node) {
+ if (p->dev->of_node == np) {
+ if (!try_module_get(p->owner))
+ dev_err(host->parent,
+ "increasing module refcount failed\n");
+ else
+ host->pwrseq = p;
- match = mmc_pwrseq_find(np);
- if (IS_ERR(match)) {
- ret = PTR_ERR(match);
- goto err;
+ break;
+ }
}
- pwrseq = match->alloc(host, &pdev->dev);
- if (IS_ERR(pwrseq)) {
- ret = PTR_ERR(pwrseq);
- goto err;
- }
+ of_node_put(np);
+ mutex_unlock(&pwrseq_list_mutex);
+
+ if (!host->pwrseq)
+ return -EPROBE_DEFER;
- host->pwrseq = pwrseq;
dev_info(host->parent, "allocated mmc-pwrseq\n");
-err:
- of_node_put(np);
- return ret;
+ return 0;
}
void mmc_pwrseq_pre_power_on(struct mmc_host *host)
{
struct mmc_pwrseq *pwrseq = host->pwrseq;
- if (pwrseq && pwrseq->ops && pwrseq->ops->pre_power_on)
+ if (pwrseq && pwrseq->ops->pre_power_on)
pwrseq->ops->pre_power_on(host);
}
@@ -97,7 +64,7 @@ void mmc_pwrseq_post_power_on(struct mmc_host *host)
{
struct mmc_pwrseq *pwrseq = host->pwrseq;
- if (pwrseq && pwrseq->ops && pwrseq->ops->post_power_on)
+ if (pwrseq && pwrseq->ops->post_power_on)
pwrseq->ops->post_power_on(host);
}
@@ -105,7 +72,7 @@ void mmc_pwrseq_power_off(struct mmc_host *host)
{
struct mmc_pwrseq *pwrseq = host->pwrseq;
- if (pwrseq && pwrseq->ops && pwrseq->ops->power_off)
+ if (pwrseq && pwrseq->ops->power_off)
pwrseq->ops->power_off(host);
}
@@ -113,8 +80,31 @@ void mmc_pwrseq_free(struct mmc_host *host)
{
struct mmc_pwrseq *pwrseq = host->pwrseq;
- if (pwrseq && pwrseq->ops && pwrseq->ops->free)
- pwrseq->ops->free(host);
+ if (pwrseq) {
+ module_put(pwrseq->owner);
+ host->pwrseq = NULL;
+ }
+}
+
+int mmc_pwrseq_register(struct mmc_pwrseq *pwrseq)
+{
+ if (!pwrseq || !pwrseq->ops || !pwrseq->dev)
+ return -EINVAL;
- host->pwrseq = NULL;
+ mutex_lock(&pwrseq_list_mutex);
+ list_add(&pwrseq->pwrseq_node, &pwrseq_list);
+ mutex_unlock(&pwrseq_list_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mmc_pwrseq_register);
+
+void mmc_pwrseq_unregister(struct mmc_pwrseq *pwrseq)
+{
+ if (pwrseq) {
+ mutex_lock(&pwrseq_list_mutex);
+ list_del(&pwrseq->pwrseq_node);
+ mutex_unlock(&pwrseq_list_mutex);
+ }
}
+EXPORT_SYMBOL_GPL(mmc_pwrseq_unregister);
diff --git a/drivers/mmc/core/pwrseq.h b/drivers/mmc/core/pwrseq.h
index 133de0426687..d69e751f148b 100644
--- a/drivers/mmc/core/pwrseq.h
+++ b/drivers/mmc/core/pwrseq.h
@@ -8,32 +8,39 @@
#ifndef _MMC_CORE_PWRSEQ_H
#define _MMC_CORE_PWRSEQ_H
+#include <linux/mmc/host.h>
+
struct mmc_pwrseq_ops {
void (*pre_power_on)(struct mmc_host *host);
void (*post_power_on)(struct mmc_host *host);
void (*power_off)(struct mmc_host *host);
- void (*free)(struct mmc_host *host);
};
struct mmc_pwrseq {
const struct mmc_pwrseq_ops *ops;
+ struct device *dev;
+ struct list_head pwrseq_node;
+ struct module *owner;
};
#ifdef CONFIG_OF
+int mmc_pwrseq_register(struct mmc_pwrseq *pwrseq);
+void mmc_pwrseq_unregister(struct mmc_pwrseq *pwrseq);
+
int mmc_pwrseq_alloc(struct mmc_host *host);
void mmc_pwrseq_pre_power_on(struct mmc_host *host);
void mmc_pwrseq_post_power_on(struct mmc_host *host);
void mmc_pwrseq_power_off(struct mmc_host *host);
void mmc_pwrseq_free(struct mmc_host *host);
-struct mmc_pwrseq *mmc_pwrseq_simple_alloc(struct mmc_host *host,
- struct device *dev);
-struct mmc_pwrseq *mmc_pwrseq_emmc_alloc(struct mmc_host *host,
- struct device *dev);
-
#else
+static inline int mmc_pwrseq_register(struct mmc_pwrseq *pwrseq)
+{
+ return -ENOSYS;
+}
+static inline void mmc_pwrseq_unregister(struct mmc_pwrseq *pwrseq) {}
static inline int mmc_pwrseq_alloc(struct mmc_host *host) { return 0; }
static inline void mmc_pwrseq_pre_power_on(struct mmc_host *host) {}
static inline void mmc_pwrseq_post_power_on(struct mmc_host *host) {}
diff --git a/drivers/mmc/core/pwrseq_emmc.c b/drivers/mmc/core/pwrseq_emmc.c
index c2d732aa464c..adc9c0c614fb 100644
--- a/drivers/mmc/core/pwrseq_emmc.c
+++ b/drivers/mmc/core/pwrseq_emmc.c
@@ -9,6 +9,9 @@
*/
#include <linux/delay.h>
#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/err.h>
@@ -42,20 +45,6 @@ static void mmc_pwrseq_emmc_reset(struct mmc_host *host)
__mmc_pwrseq_emmc_reset(pwrseq);
}
-static void mmc_pwrseq_emmc_free(struct mmc_host *host)
-{
- struct mmc_pwrseq_emmc *pwrseq = to_pwrseq_emmc(host->pwrseq);
-
- unregister_restart_handler(&pwrseq->reset_nb);
- gpiod_put(pwrseq->reset_gpio);
- kfree(pwrseq);
-}
-
-static const struct mmc_pwrseq_ops mmc_pwrseq_emmc_ops = {
- .post_power_on = mmc_pwrseq_emmc_reset,
- .free = mmc_pwrseq_emmc_free,
-};
-
static int mmc_pwrseq_emmc_reset_nb(struct notifier_block *this,
unsigned long mode, void *cmd)
{
@@ -66,21 +55,22 @@ static int mmc_pwrseq_emmc_reset_nb(struct notifier_block *this,
return NOTIFY_DONE;
}
-struct mmc_pwrseq *mmc_pwrseq_emmc_alloc(struct mmc_host *host,
- struct device *dev)
+static const struct mmc_pwrseq_ops mmc_pwrseq_emmc_ops = {
+ .post_power_on = mmc_pwrseq_emmc_reset,
+};
+
+static int mmc_pwrseq_emmc_probe(struct platform_device *pdev)
{
struct mmc_pwrseq_emmc *pwrseq;
- int ret = 0;
+ struct device *dev = &pdev->dev;
- pwrseq = kzalloc(sizeof(struct mmc_pwrseq_emmc), GFP_KERNEL);
+ pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL);
if (!pwrseq)
- return ERR_PTR(-ENOMEM);
+ return -ENOMEM;
- pwrseq->reset_gpio = gpiod_get(dev, "reset", GPIOD_OUT_LOW);
- if (IS_ERR(pwrseq->reset_gpio)) {
- ret = PTR_ERR(pwrseq->reset_gpio);
- goto free;
- }
+ pwrseq->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(pwrseq->reset_gpio))
+ return PTR_ERR(pwrseq->reset_gpio);
/*
* register reset handler to ensure emmc reset also from
@@ -92,9 +82,38 @@ struct mmc_pwrseq *mmc_pwrseq_emmc_alloc(struct mmc_host *host,
register_restart_handler(&pwrseq->reset_nb);
pwrseq->pwrseq.ops = &mmc_pwrseq_emmc_ops;
+ pwrseq->pwrseq.dev = dev;
+ pwrseq->pwrseq.owner = THIS_MODULE;
+ platform_set_drvdata(pdev, pwrseq);
+
+ return mmc_pwrseq_register(&pwrseq->pwrseq);
+}
+
+static int mmc_pwrseq_emmc_remove(struct platform_device *pdev)
+{
+ struct mmc_pwrseq_emmc *pwrseq = platform_get_drvdata(pdev);
+
+ unregister_restart_handler(&pwrseq->reset_nb);
+ mmc_pwrseq_unregister(&pwrseq->pwrseq);
- return &pwrseq->pwrseq;
-free:
- kfree(pwrseq);
- return ERR_PTR(ret);
+ return 0;
}
+
+static const struct of_device_id mmc_pwrseq_emmc_of_match[] = {
+ { .compatible = "mmc-pwrseq-emmc",},
+ {/* sentinel */},
+};
+
+MODULE_DEVICE_TABLE(of, mmc_pwrseq_emmc_of_match);
+
+static struct platform_driver mmc_pwrseq_emmc_driver = {
+ .probe = mmc_pwrseq_emmc_probe,
+ .remove = mmc_pwrseq_emmc_remove,
+ .driver = {
+ .name = "pwrseq_emmc",
+ .of_match_table = mmc_pwrseq_emmc_of_match,
+ },
+};
+
+module_platform_driver(mmc_pwrseq_emmc_driver);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c
index f94271bb1f6b..450d907c6e6c 100644
--- a/drivers/mmc/core/pwrseq_simple.c
+++ b/drivers/mmc/core/pwrseq_simple.c
@@ -8,7 +8,10 @@
* Simple MMC power sequence management
*/
#include <linux/clk.h>
+#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/err.h>
@@ -75,58 +78,64 @@ static void mmc_pwrseq_simple_power_off(struct mmc_host *host)
}
}
-static void mmc_pwrseq_simple_free(struct mmc_host *host)
-{
- struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq);
-
- if (!IS_ERR(pwrseq->reset_gpios))
- gpiod_put_array(pwrseq->reset_gpios);
-
- if (!IS_ERR(pwrseq->ext_clk))
- clk_put(pwrseq->ext_clk);
-
- kfree(pwrseq);
-}
-
static const struct mmc_pwrseq_ops mmc_pwrseq_simple_ops = {
.pre_power_on = mmc_pwrseq_simple_pre_power_on,
.post_power_on = mmc_pwrseq_simple_post_power_on,
.power_off = mmc_pwrseq_simple_power_off,
- .free = mmc_pwrseq_simple_free,
};
-struct mmc_pwrseq *mmc_pwrseq_simple_alloc(struct mmc_host *host,
- struct device *dev)
+static const struct of_device_id mmc_pwrseq_simple_of_match[] = {
+ { .compatible = "mmc-pwrseq-simple",},
+ {/* sentinel */},
+};
+MODULE_DEVICE_TABLE(of, mmc_pwrseq_simple_of_match);
+
+static int mmc_pwrseq_simple_probe(struct platform_device *pdev)
{
struct mmc_pwrseq_simple *pwrseq;
- int ret = 0;
+ struct device *dev = &pdev->dev;
- pwrseq = kzalloc(sizeof(*pwrseq), GFP_KERNEL);
+ pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL);
if (!pwrseq)
- return ERR_PTR(-ENOMEM);
+ return -ENOMEM;
- pwrseq->ext_clk = clk_get(dev, "ext_clock");
- if (IS_ERR(pwrseq->ext_clk) &&
- PTR_ERR(pwrseq->ext_clk) != -ENOENT) {
- ret = PTR_ERR(pwrseq->ext_clk);
- goto free;
- }
+ pwrseq->ext_clk = devm_clk_get(dev, "ext_clock");
+ if (IS_ERR(pwrseq->ext_clk) && PTR_ERR(pwrseq->ext_clk) != -ENOENT)
+ return PTR_ERR(pwrseq->ext_clk);
- pwrseq->reset_gpios = gpiod_get_array(dev, "reset", GPIOD_OUT_HIGH);
+ pwrseq->reset_gpios = devm_gpiod_get_array(dev, "reset",
+ GPIOD_OUT_HIGH);
if (IS_ERR(pwrseq->reset_gpios) &&
PTR_ERR(pwrseq->reset_gpios) != -ENOENT &&
PTR_ERR(pwrseq->reset_gpios) != -ENOSYS) {
- ret = PTR_ERR(pwrseq->reset_gpios);
- goto clk_put;
+ return PTR_ERR(pwrseq->reset_gpios);
}
+ pwrseq->pwrseq.dev = dev;
pwrseq->pwrseq.ops = &mmc_pwrseq_simple_ops;
+ pwrseq->pwrseq.owner = THIS_MODULE;
+ platform_set_drvdata(pdev, pwrseq);
- return &pwrseq->pwrseq;
-clk_put:
- if (!IS_ERR(pwrseq->ext_clk))
- clk_put(pwrseq->ext_clk);
-free:
- kfree(pwrseq);
- return ERR_PTR(ret);
+ return mmc_pwrseq_register(&pwrseq->pwrseq);
}
+
+static int mmc_pwrseq_simple_remove(struct platform_device *pdev)
+{
+ struct mmc_pwrseq_simple *pwrseq = platform_get_drvdata(pdev);
+
+ mmc_pwrseq_unregister(&pwrseq->pwrseq);
+
+ return 0;
+}
+
+static struct platform_driver mmc_pwrseq_simple_driver = {
+ .probe = mmc_pwrseq_simple_probe,
+ .remove = mmc_pwrseq_simple_remove,
+ .driver = {
+ .name = "pwrseq_simple",
+ .of_match_table = mmc_pwrseq_simple_of_match,
+ },
+};
+
+module_platform_driver(mmc_pwrseq_simple_driver);
+MODULE_LICENSE("GPL v2");
From d94057e963bb557eb61324a2f05e5a0a743813c5 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 7 Aug 2016 21:02:38 +0200
Subject: [PATCH] UPSTREAM: mmc: pwrseq-simple: Add an optional
post-power-on-delay
Some devices need a while to boot their firmware after providing clks /
de-asserting resets before they are ready to receive sdio commands.
This commits adds a post-power-on-delay-ms devicetree property to
mmc-pwrseq-simple for use with such devices.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
(cherry picked from commit 721e0497172f0fa661eed2d63367cddf479f35e8)
---
Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt | 2 ++
drivers/mmc/core/pwrseq_simple.c | 9 +++++++++
2 files changed, 11 insertions(+)
diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
index ce0e76749671..e25436861867 100644
--- a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
+++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
@@ -16,6 +16,8 @@ Optional properties:
See ../clocks/clock-bindings.txt for details.
- clock-names : Must include the following entry:
"ext_clock" (External clock provided to the card).
+- post-power-on-delay-ms : Delay in ms after powering the card and
+ de-asserting the reset-gpios (if any)
Example:
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c
index 450d907c6e6c..1304160de168 100644
--- a/drivers/mmc/core/pwrseq_simple.c
+++ b/drivers/mmc/core/pwrseq_simple.c
@@ -16,6 +16,8 @@
#include <linux/device.h>
#include <linux/err.h>
#include <linux/gpio/consumer.h>
+#include <linux/delay.h>
+#include <linux/property.h>
#include <linux/mmc/host.h>
@@ -24,6 +26,7 @@
struct mmc_pwrseq_simple {
struct mmc_pwrseq pwrseq;
bool clk_enabled;
+ u32 post_power_on_delay_ms;
struct clk *ext_clk;
struct gpio_descs *reset_gpios;
};
@@ -64,6 +67,9 @@ static void mmc_pwrseq_simple_post_power_on(struct mmc_host *host)
struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq);
mmc_pwrseq_simple_set_gpios_value(pwrseq, 0);
+
+ if (pwrseq->post_power_on_delay_ms)
+ msleep(pwrseq->post_power_on_delay_ms);
}
static void mmc_pwrseq_simple_power_off(struct mmc_host *host)
@@ -111,6 +117,9 @@ static int mmc_pwrseq_simple_probe(struct platform_device *pdev)
return PTR_ERR(pwrseq->reset_gpios);
}
+ device_property_read_u32(dev, "post-power-on-delay-ms",
+ &pwrseq->post_power_on_delay_ms);
+
pwrseq->pwrseq.dev = dev;
pwrseq->pwrseq.ops = &mmc_pwrseq_simple_ops;
pwrseq->pwrseq.owner = THIS_MODULE;
From 50e40e09e01a67684fd3b7ef2422f194a656dd93 Mon Sep 17 00:00:00 2001
From: Ulf Hansson <ulf.hansson@linaro.org>
Date: Sat, 6 May 2017 11:41:30 +0200
Subject: [PATCH] UPSTREAM: mmc: dt: pwrseq-simple: Invent power-off-delay-us
During power off, after the GPIO pin has been asserted, some devices like
the Wifi chip from TI, Wl18xx, needs a delay before the host continues with
clock gating and turning off regulators as to follow a graceful shutdown
sequence.
Therefore invent an optional power-off-delay-us DT binding for
mmc-pwrseq-simple, to allow us to support this constraint.
Cc: devicetree@vger.kernel.org
Cc: Rob Herring <robh+dt@kernel.org>
Cc: linux-mmc@vger.kernel.org
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Acked-by: Arnd Bergmann <arnd@arndb.de>
---
Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
index e25436861867..9029b45b8a22 100644
--- a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
+++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
@@ -18,6 +18,8 @@ Optional properties:
"ext_clock" (External clock provided to the card).
- post-power-on-delay-ms : Delay in ms after powering the card and
de-asserting the reset-gpios (if any)
+- power-off-delay-us : Delay in us after asserting the reset-gpios (if any)
+ during power off of the card.
Example:
From e4960aff45ecb83728279dd1e524f4e62ec11240 Mon Sep 17 00:00:00 2001
From: Ulf Hansson <ulf.hansson@linaro.org>
Date: Sat, 6 May 2017 11:43:05 +0200
Subject: [PATCH] UPSTREAM: mmc: pwrseq_simple: Parse DTS for the
power-off-delay-us property
If the optional power-off-delay-us property is found, insert the
corresponding delay after asserting the GPIO during power off. This enables
a graceful shutdown sequence for some devices.
Cc: linux-mmc@vger.kernel.org
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Acked-by: Arnd Bergmann <arnd@arndb.de>
(cherry picked from commit e9256e142f597edf90c68cec22db4c4aebaa27de)
---
drivers/mmc/core/pwrseq_simple.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c
index 1304160de168..13ef162cf066 100644
--- a/drivers/mmc/core/pwrseq_simple.c
+++ b/drivers/mmc/core/pwrseq_simple.c
@@ -27,6 +27,7 @@ struct mmc_pwrseq_simple {
struct mmc_pwrseq pwrseq;
bool clk_enabled;
u32 post_power_on_delay_ms;
+ u32 power_off_delay_us;
struct clk *ext_clk;
struct gpio_descs *reset_gpios;
};
@@ -78,6 +79,10 @@ static void mmc_pwrseq_simple_power_off(struct mmc_host *host)
mmc_pwrseq_simple_set_gpios_value(pwrseq, 1);
+ if (pwrseq->power_off_delay_us)
+ usleep_range(pwrseq->power_off_delay_us,
+ 2 * pwrseq->power_off_delay_us);
+
if (!IS_ERR(pwrseq->ext_clk) && pwrseq->clk_enabled) {
clk_disable_unprepare(pwrseq->ext_clk);
pwrseq->clk_enabled = false;
@@ -119,6 +124,8 @@ static int mmc_pwrseq_simple_probe(struct platform_device *pdev)
device_property_read_u32(dev, "post-power-on-delay-ms",
&pwrseq->post_power_on_delay_ms);
+ device_property_read_u32(dev, "power-off-delay-us",
+ &pwrseq->power_off_delay_us);
pwrseq->pwrseq.dev = dev;
pwrseq->pwrseq.ops = &mmc_pwrseq_simple_ops;

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,25 @@ devices = {
'board_name' : { 'dtb' : 'board_name.dtb', 'config' : 'board_name_defconfig' },
},
},
'Rockchip' : {
'MiQi' : { 'rk3288' : { 'dtb' : 'rk3288-miqi.dtb', 'config' : 'miqi-rk3288_config' }, },
'RK3328' : {
'box' : { 'dtb' : 'rk3328-box.dtb', 'config' : 'evb-rk3328_defconfig' },
'box-trn9' : { 'dtb' : 'rk3328-box-trn9.dtb', 'config' : 'evb-rk3328_defconfig' },
'box-z28' : { 'dtb' : 'rk3328-box-z28.dtb', 'config' : 'evb-rk3328_defconfig' },
'roc-cc' : { 'dtb' : 'rk3328-roc-cc.dtb', 'config' : 'evb-rk3328_defconfig' },
'rock64' : { 'dtb' : 'rk3328-rock64.dtb', 'config' : 'evb-rk3328_defconfig' },
'rockbox' : { 'dtb' : 'rk3328-rockbox.dtb', 'config' : 'evb-rk3328_defconfig' },
},
'RK3399' : {
'odroidn1' : { 'dtb' : 'rk3399-odroidn1.dtb', 'config' : 'odroidn1_config' },
'rock960' : { 'dtb' : 'rk3399-rock960.dtb', 'config' : 'evb-rk3399_config' },
'rockpro64' : { 'dtb' : 'rk3399-rockpro64.dtb', 'config' : 'evb-rk3399_config' },
'sapphire' : { 'dtb' : 'rk3399-sapphire.dtb', 'config' : 'evb-rk3399_config' },
},
'TinkerBoard' : { 'rk3288' : { 'dtb' : 'rk3288-miniarm.dtb', 'config' : 'tinker-rk3288_config' }, },
},
}
def usage():