问题描述
我这个项目的SDK比较老,移植RK628F最新驱动的调试过程,踩了很多坑,希望大家别踩坑。
解决方案:
首先在FTP上下载最新的RK628的驱动 rk628-for-all-v27-240730 版本。
下载完后 不要直接替换,不要直接替换,不要直接替换,重要的事情说三遍!!!
按照一下移植过程同步移植。
U-boot部份:
1.先将RK628\rk628-for-all\v27-240730\kernel\rk628_for_all_v27_240730\src_rk628-for-all-kernel-v26-240730\u-boot\drivers\video\drm\rk628下整个rk628文件夹复制到u-boot\drivers\video\drm下。
2.打入RK628\rk628-for-all\v27-240730\kernel\rk628_for_all_v27_240730\patch_rk628-for-all-kernel-v26-240730\u-boot下的三个补丁。
一个是Kconfig和Makefile添加编译rk628。
一个是u-boot\drivers\video\drm\dw_hdmi.c相关改动。
另外一个rk628添加文件不用管它。
3.在u-boot\configs下找到rk3566.config索引到rk3568_defconfig,添加CONFIG_DRM_ROCKCHIP_RK628=y编译 RK628驱动。
CONFIG_DRM_ROCKCHIP_LVDS=y
CONFIG_DRM_ROCKCHIP_RGB=y
+CONFIG_DRM_ROCKCHIP_RK628=y
CONFIG_ROCKCHIP_CUBIC_LUT_SIZE=9
Kernel部分:
按照如下参考这个说明:
android 路径下补丁主要是针对rk628音频部分 不加 1. kernel\arch 路径下的主要是dts 和config宏的修改 dts 是rk628的demo 作为参考。 替不替换都可以 config宏的修改一定要加上去。 2. kenrel/Documentation 不加 3. kernel/include 不加 4.kernel\drivers\clk 不加 4. kernel\drivers\misc rk628显示部分 核心文件 kernel\drivers\misc\rk628 直接替换 kernel\drivers\misc\Kconfig Makefile 参考补丁手动加进去 主要是针对rk628 编译声明 宏声明 5.kernel\drivers\media rk628 输入部分的核心文件 主要针对camera 不加 6. 以下路径文件 参考补丁手动加进去kernel\drivers\gpu hdmi强制输出固定分辨率 绕过读edid流程kernel\drivers\i2c 提前i2c设备的注册 以加快rk628的初始化 kernel\drivers\base 增加宏主要是为了实现regmap文件结点可以写628寄存器 kernel\drivers\pwm 提前pwm设备的注册 以加快rk628的初始化 kernel\drivers\video 提前backlight设备的注册 以加快rk628的初始化
1.首先打上第六点的三个补丁,分别是:
0130-rk628-for-all-Call-rockchip_pwm_driver_init-and-pwm_.patch
0001-regmap-debugfs-Allow-register-writes-through-debugfs.patch
0126-i2c-rk3x-Call-rk3x_i2c_driver_init-early-when-CONFIG.patch
2.移植第四点的rk628核心驱动。直接将
rk628-for-all\v27-240730\kernel\rk628_for_all_v27_240730\src_rk628-for-all-kernel-v26-240730\kernel\drivers\misc\rk628整个文件移植到kernel\drivers\misc下
对应kernel\drivers\miscKconfig增加如下:
source "drivers/misc/ocxl/Kconfig"
+source "drivers/misc/rk628/Kconfig"
source "drivers/misc/cardreader/Kconfig"
对应kernel\drivers\misc\Makefile增加如下:
obj-$(CONFIG_RK803) += rk803.o
obj-$(CONFIG_ENC_SW2001) += translogic.o
+obj-y += rk628/
3.打上rk628-for-all\v27-240730\kernel\rk628_for_all_v27_240730\patch_rk628-for-all-kernel-v26-240730\kernel\0190-drm-bridge-synopsys-Support-hdmi-force-output-kernel-4-19.patch补丁
涉及
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
include/drm/bridge/dw_hdmi.h
4.打上强制4K输出补丁和强制输出RGB888格式。
强制4K输出补丁:
rk3566-evb1-ddr4-v10.dts
#include "rk3566-evb1-ddr4-v10.dtsi"
#include "rk3568-android.dtsi"
++#include <dt-bindings/display/rockchip_vop.h> //图层 ID 定义头文件++&vp0 { //x 取决于使用的 vp id,如 vp0
++ rockchip,plane-mask = <(1 << ROCKCHIP_VOP2_CLUSTER0 | 1 << ROCKCHIP_VOP2_ESMART0 | 1 <<
++ ROCKCHIP_VOP2_SMART0 | 1 << ROCKCHIP_VOP2_CLUSTER1 | 1 << ROCKCHIP_VOP2_ESMART1 | 1 <<
++ ROCKCHIP_VOP2_SMART1)>;
++ rockchip,primary-plane = <ROCKCHIP_VOP2_SMART0>;
++};
rk3568 force-output 4k.txt 补丁
//u-boot:
//uboot阶段需要将hdmi版本协议切到2.0,强制打开SCRAMBLER
diff --git a/drivers/video/drm/dw_hdmi.c b/drivers/video/drm/dw_hdmi.c
index 10a593870a..cb4a4a3334 100644
--- a/drivers/video/drm/dw_hdmi.c
+++ b/drivers/video/drm/dw_hdmi.c
@@ -820,14 +820,7 @@ static const struct dw_hdmi_phy_data dw_hdmi_phys[] = {static int rockchip_dw_hdmi_scrambling_enable(struct dw_hdmi *hdmi,int enable){
- u8 stat;
-
- drm_scdc_readb(&hdmi->adap, SCDC_TMDS_CONFIG, &stat);
-
- if (stat < 0) {
- debug("Failed to read tmds config\n");
- return false;
- }
+ u8 stat = 0;if (enable == 1) {/* Write on Rx the bit Scrambling_Enable, register 0x20 */
@@ -1116,7 +1109,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,}/* Scrambling Control */
- if (hdmi_info->scdc.supported) {if (vmode->mtmdsclock > 340000000 ||(hdmi_info->scdc.scrambling.low_rates &&hdmi->scramble_low_rates)) {
@@ -1127,7 +1119,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,} else {rockchip_dw_hdmi_scrambling_enable(hdmi, 0);}
- }/* Set up horizontal active pixel width */hdmi_writeb(hdmi, hdisplay >> 8, HDMI_FC_INHACTV1);//强制输出3840x2160@60,这个vic mode为97.
@@ -2430,13 +2421,15 @@ int rockchip_dw_hdmi_get_timing(struct display_state *state)unsigned int bus_format;unsigned long enc_out_encoding;struct overscan *overscan = &conn_state->overscan;
- const u8 def_modes_vic[6] = {4, 16, 2, 17, 31, 19};
+ const u8 def_modes_vic[1] = {97};if (!hdmi)return -EFAULT;ret = drm_do_get_edid(&hdmi->adap, conn_state->edid);+ ret = -EFAULT;
+if (!ret) {hdmi->sink_is_hdmi =drm_detect_hdmi_monitor(edid);//强制修改bus_format为RGB888
@@ -2469,6 +2462,8 @@ int rockchip_dw_hdmi_get_timing(struct display_state *state)drm_rk_selete_output(&hdmi->edid_data, conn_state, &bus_format,overscan, hdmi->dev_type, hdmi->output_bus_format_rgb);+ bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+*mode = *hdmi->edid_data.preferred_mode;hdmi->vic = drm_match_cea_mode(mode);//设置为HPD为高电平。
@@ -2525,6 +2520,8 @@ int rockchip_dw_hdmi_detect(struct display_state *state)if (!hdmi)return -EFAULT;+ return connector_status_connected;
+ret = dw_hdmi_detect_hotplug(hdmi, state);return ret;//kernel:
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index ee7f83a81016..966ab224425d 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -202,40 +202,12 @@ static const u16 csc_coeff_full_to_limited[3][4] = {};static const struct drm_display_mode dw_hdmi_default_modes[] = {
- /* 4 - 1280x720@60Hz 16:9 */
- { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
- 1430, 1650, 0, 720, 725, 730, 750, 0,
- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
- .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
- /* 16 - 1920x1080@60Hz 16:9 */
- { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
- 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
- .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
- /* 31 - 1920x1080@50Hz 16:9 */
- { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
- 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
- .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
- /* 19 - 1280x720@50Hz 16:9 */
- { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1720,
- 1760, 1980, 0, 720, 725, 730, 750, 0,
- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
- .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
- /* 0x10 - 1024x768@60Hz */
- { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
- 1184, 1344, 0, 768, 771, 777, 806, 0,
- DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
- /* 17 - 720x576@50Hz 4:3 */
- { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
- 796, 864, 0, 576, 581, 586, 625, 0,
- DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
- .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
- /* 2 - 720x480@60Hz 4:3 */
- { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,
- 798, 858, 0, 480, 489, 495, 525, 0,
- DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
- .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
+ /* 97 - 3840x2160@60Hz 16:9 */
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4016,
+ 4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+};struct hdmi_vmode {//强制打开hdmi 2.0 scramble。
@@ -1478,6 +1450,10 @@ static int hdmi_phy_i2c_read(struct dw_hdmi *hdmi, unsigned char addr)static bool dw_hdmi_support_scdc(struct dw_hdmi *hdmi){struct drm_display_info *display = &hdmi->connector.display_info;
+ unsigned long mtmdsclock = hdmi->hdmi_data.video_mode.mtmdsclock;
+
+ if (mtmdsclock > HDMI14_MAX_TMDSCLK)
+ return true; /* Completely disable SCDC support for older controllers */if (hdmi->version < 0x200a)
//将状态强制设置为永久连接的状态
@@ -2722,6 +2698,8 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)connector);enum drm_connector_status result;+ return connector_status_connected;
+if (!hdmi->force_logo) {mutex_lock(&hdmi->mutex);hdmi->force = DRM_FORCE_UNSPECIFIED;
//走强制输出的流程
@@ -2792,6 +2770,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)return 0;edid = drm_get_edid(connector, hdmi->ddc);
+ edid = NULL; if (edid) {dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",edid->width_cm, edid->height_cm);
//初始化时 若rk628没有开始初始化,则phy存在没有拉高的场景
@@ -3985,7 +3964,7 @@ __dw_hdmi_probe(struct platform_device *pdev,hdmi->initialized = false;ret = hdmi_readb(hdmi, HDMI_PHY_STAT0);
- if (((ret & HDMI_PHY_TX_PHY_LOCK) && (ret & HDMI_PHY_HPD) &&
+ if (((ret & HDMI_PHY_TX_PHY_LOCK) &&hdmi_readb(hdmi, HDMI_FC_EXCTRLDUR)) || hdmi->force_logo) {hdmi->mc_clkdis = hdmi_readb(hdmi, HDMI_MC_CLKDIS);hdmi->disabled = false;//即假设在HDMI probe阶段已经将hpd脚和rxsence中断并且rk628端还没有拉高hpd脚,则hdmi会强制关闭
@@ -4072,8 +4051,6 @@ __dw_hdmi_probe(struct platform_device *pdev,}dw_hdmi_setup_i2c(hdmi);
- if (hdmi->phy.ops->setup_hpd)
- hdmi->phy.ops->setup_hpd(hdmi, hdmi->phy.data);if (hdmi->version >= 0x200a)hdmi->connector.ycbcr_420_allowed =//强制输出可能导致match不上,出现显示不了kernel logo
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 401528583682..2a36b0a07ffc 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -770,8 +770,7 @@ static int setup_initial_state(struct drm_device *drm_dev,/* we just need to focus on DRM_MODE_FLAG_ALL flag, so here* we compare mode->flags with set->flags & DRM_MODE_FLAG_ALL.*/
- mode->flags == (set->flags & DRM_MODE_FLAG_ALL) &&
- mode->picture_aspect_ratio == set->picture_aspect_ratio) {
+ mode->flags == (set->flags & DRM_MODE_FLAG_ALL)) {found = 1;match = 1;break;
强制输出RGB888格式补丁
kernel\drivers\gpu\drm\rockchip\rockchip_drm_drv.c添加
if (tmdsclock > max_tmds_clock) {if (max_tmds_clock >= 594000) {color_depth = 8;} else if (max_tmds_clock > 340000) {if (drm_mode_is_420(info, mode) || tmdsclock >= 594000)*color_format = DRM_HDMI_OUTPUT_YCBCR420;} else {color_depth = 8;if (drm_mode_is_420(info, mode) || tmdsclock >= 594000)*color_format = DRM_HDMI_OUTPUT_YCBCR420;}}++ *color_format = DRM_HDMI_OUTPUT_DEFAULT_RGB;if (*color_format == DRM_HDMI_OUTPUT_YCBCR420) {*output_mode = ROCKCHIP_OUT_MODE_YUV420;if (color_depth > 8)*bus_format = MEDIA_BUS_FMT_UYYVYY10_0_5X30;else*bus_format = MEDIA_BUS_FMT_UYYVYY8_0_5X24;*bus_width = color_depth / 2;hdmi->output_bus_format = *bus_format;} else {*output_mode = ROCKCHIP_OUT_MODE_AAAA;
5.修改 kernel/.config 编译配置
CONFIG_DRM_ROCKCHIP_RK618=y
-- CONFIG_DRM_ROCKCHIP_RK628=y
++ # CONFIG_DRM_ROCKCHIP_RK628 is not set#
# RK628 misc driver
#
++ CONFIG_RK628_MISC=y
++ CONFIG_RK628_MISC_HDMITX=y
++ CONFIG_ROCKCHIP_THUNDER_BOOT_RK628=y
6.dts配置分享
rk3566-evb1-ddr4-v10.dtsi
&i2c4_rk628 {status = "okay";// 屏背光脚panel-backlight = <&backlight>;// 屏使能光脚panel-power-supply = <&vcc3v3_lcd0_n>;// panel-enable-gpios = <&gpioX RK_PXX GPIO_ACTIVE_HIGH>;panel-reset-delay-ms = <10>;panel-enable-delay-ms = <150>;panel-prepare-delay-ms = <60>;panel-unprepare-delay-ms = <10>;panel-disable-delay-ms = <60>;// 我这里是外挂时钟 不需要24M时钟// pinctrl-names = "default";// pinctrl-0 = <&rk628_reset &refclk_pins>;// assigned-clocks = <&pmucru CLK_WIFI>;// assigned-clock-rates = <24000000>;// clocks = <&pmucru CLK_WIFI>;// clock-names = "soc_24M";rk628-hdmi-in;rk628-gvi-out {/* "rgb666"* "rgb888"* "rgb101010"* "yuyv8"* "yuyv10"*/bus-format = "rgb888";gvi,lanes = <8>;rockchip,division-mode;// rockchip, gvi-frm-rst;status = "okay";};display-timings {src-timing {clock-frequency = <594000000>;hactive = <3840>;vactive = <2160>;hback-porch = <296>;hfront-porch = <176>;vback-porch = <72>;vfront-porch = <8>;hsync-len = <88>;vsync-len = <10>;hsync-active = <1>;vsync-active = <1>;de-active = <0>;pixelclk-active = <0>;};dst-timing {clock-frequency = <594000000>;hactive = <3840>;vactive = <2160>;hback-porch = <296>;hfront-porch = <176>;vback-porch = <72>;vfront-porch = <8>;hsync-len = <88>;vsync-len = <10>;hsync-active = <0>;vsync-active = <0>;de-active = <0>;pixelclk-active = <0>;};};
};&hdmi {status = "okay";force-bus-format = <MEDIA_BUS_FMT_RGB888_1X24>;force-output;force_timing {clock-frequency = <594000000>;hactive = <3840>;vactive = <2160>;hback-porch = <296>;hfront-porch = <176>;vback-porch = <72>;vfront-porch = <8>;hsync-len = <88>;vsync-len = <10>;hsync-active = <1>;vsync-active = <1>;de-active = <0>;pixelclk-active = <0>;};
};&hdmi_in_vp0 {status = "okay";
};&hdmi_in_vp1 {status = "disabled";
};&hdmi_sound {status = "okay";
};&route_hdmi {status = "okay";bridge = <&i2c4_rk628>;force-bus-format = <MEDIA_BUS_FMT_RGB888_1X24>;force-output;force_timing {clock-frequency = <594000000>;hactive = <3840>;vactive = <2160>;hback-porch = <296>;hfront-porch = <176>;vback-porch = <72>;vfront-porch = <8>;hsync-len = <88>;vsync-len = <10>;hsync-active = <1>;vsync-active = <1>;de-active = <0>;pixelclk-active = <0>;};
};
rk3568-evb.dtsi
&i2c4 {status = "okay";pinctrl-names = "default";pinctrl-0 = <&i2c4m0_xfer>;clock-frequency = <400000>;i2c4_rk628: rk628@50 {status = "okay";compatible = "rockchip,rk628";reg = <0x50>;// INTinterrupt-parent = <&gpioX>;interrupts = <RK_PXX IRQ_TYPE_LEVEL_HIGH>;// ENABLEenable-gpios = <&gpioX RK_PCXX GPIO_ACTIVE_HIGH>;// RESETreset-gpios = <&gpioX RK_PXX GPIO_ACTIVE_LOW>;#sound-dai-cells = <0>;pinctrl-names = "default";pinctrl-0 = <&rk628_reset>;};
};&pinctrl {rk628 {rk628_reset: rk628-reset {rockchip,pins = <X RK_PXX RK_FUNC_GPIO &pcfg_pull_none>;};};
}
最后:如果开机还是黑屏,可以上下电HDMI节点:
echo off > /sys/class/drm/card0-HDMI-A-1/status
echo on > /sys/class/drm/card0-HDMI-A-1/status
上下电如果能出图,那就把dts中的route_hdmi节点disabled。