20240606在Toybrick的TB-RK3588开发板的Android12下确认HDMI的驱动

20240606在Toybrick的TB-RK3588开发板的Android12下确认HDMI的驱动
2024/6/6 9:48


【原文是在RK3328的Android7.1下写的。我将它升级成为RK3588的Android12了】
RK平台主要采用 FB 和 DRM 两种显示框架。与此相对应, HDMI 也有两套驱动。
FB:
LINUX 3.10 内核主要采用传统的 FB 框架, HDMI 驱动的路径为:
kernel/drivers/video/rockchip/hdmi/

DRM:
DRM全称是 Direct Rendering Manager 是 DRI ( Direct Rendering Infrastructure ) 框架的一个
组件。LINUX 4.4/4.19 内核采用 DRM框架, HDMI 驱动的路径为:
kernel/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
kernel/drivers/gpu/drm/bridge/synopsys/

Y:\android12-rk-outside\kernel-5.10\drivers\gpu\drm\bridge\synopsys\dw-hdmi.c
Y:\android12-rk-outside\kernel-5.10\drivers\gpu\drm\drm_edid.c
Y:\android12-rk-outside\kernel-5.10\drivers\gpu\drm\rockchip\dw_hdmi-rockchip.c


RK3288_Android7.1内核为4.4,采用的DRM框架。
RK3588_Android12内核为linux-5.10,采用的DRM框架。本文只分析DRM框架下hdmi相关功能调试。
1.HDMI 软件功能配置
1.1 使能HDMI
&hdmi {
    status = "okay";
};

Y:\android12-rk-outside\kernel-5.10\arch\arm64\boot\dts\rockchip\rk3588-toybrick-x0.dtsi
Z:\rk3588-toybrick-x0-linux20240508\kernel\arch\arm64\boot\dts\rockchip\rk3588-toybrick-x0.dtsi
&hdmi0 {
    enable-gpios = <&gpio4 RK_PB1 GPIO_ACTIVE_HIGH>;
    status = "okay";
};

&hdmi0_in_vp0 {
    status = "okay";
};

&hdmi0_sound {
    status = "okay";
};

/* Should work with at least 128MB cma reserved above. */
&hdmirx_ctrler {
    status = "okay";

    /* Effective level used to trigger HPD: 0-low, 1-high */
    hpd-trigger-level = <1>;
    hdmirx-det-gpios = <&gpio2 RK_PB5 GPIO_ACTIVE_LOW>;
    pinctrl-names = "default";
    pinctrl-0 = <&hdmim1_rx &hdmirx_det>;
};

&hdptxphy_hdmi0 {
    status = "okay";
};


1.2 绑定VOP
RK3288平台存在两个 VOP:VOPB(支持 4K)、VOPL(只支持 2K),两个 VOP
可以分别与两个显示接口绑定(一个显示接口只能和一个 VOP 绑定),且可以相互交换:

当 dts 中显示设备节点打开时,显示接口对应 VOPB和 VOPL 的 ports 都会打开,所以需要关闭用不到的那个 VOP。 比如 HDMI 绑定到 VOPB 需要添加:

&hdmi_in_vopl {
    status = "disabled";
};

反之若绑定到 VOPL 则添加:

&hdmi_in_vopb {
    status = "disabled";
};


对于RK3588平台,有所修正:
&hdmi0_in_vp0 {
    status = "okay";
};


1.3 打开开机logo
如果 U-Boot logo 未开启,那 kernel 阶段也无法显示开机 logo,只能等到系统启动后才能看到显示。
在 dts 里面将 route_hdmi 使能即可打开 U-Boot logo 支持:

&route_hdmi {
    status = "okay"
};


【可能我对U-Boot的理解不同,对于我用的HDMI显示器。大概7秒钟,Buildroot直接进界面,Android显示ANDROID画面,打印都过了U-boot阶段】
对于RK3588平台:
rootroot@rootroot-desktop:~/android12-rk-outside/kernel-5.10/arch/arm64/boot/dts/rockchip$ 
rootroot@rootroot-desktop:~/android12-rk-outside/kernel-5.10/arch/arm64/boot/dts/rockchip$ grep route_hdmi . -R
./.rk3588-toybrick-x0-android.dtb.dts.tmp:   route_hdmi0: route-hdmi0 {
./.rk3588-toybrick-x0-android.dtb.dts.tmp:  route_hdmi1: route-hdmi1 {
./rk3588.dtsi:        route_hdmi1: route-hdmi1 {
./rk3588s.dtsi:            route_hdmi0: route-hdmi0 {

Binary file ./rk3588-toybrick-x0-android.dtb matches
rootroot@rootroot-desktop:~/android12-rk-outside/kernel-5.10/arch/arm64/boot/dts/rockchip$ 


Y:\android12-rk-outside\kernel-5.10\arch\arm64\boot\dts\rockchip\rk3588s.dtsi

// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
 * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
 */

#include <dt-bindings/clock/rk3588-cru.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/phy/phy.h>
#include <dt-bindings/power/rk3588-power.h>
#include <dt-bindings/soc/rockchip,boot-mode.h>
#include <dt-bindings/soc/rockchip-system-status.h>
#include <dt-bindings/suspend/rockchip-rk3588.h>
#include <dt-bindings/thermal/thermal.h>

/ {
    compatible = "rockchip,rk3588";

    interrupt-parent = <&gic>;
    #address-cells = <2>;
    #size-cells = <2>;


    display_subsystem: display-subsystem {
        compatible = "rockchip,display-subsystem";
        ports = <&vop_out>;

        route {
            route_dp0: route-dp0 {
                status = "disabled";
                logo,uboot = "logo.bmp";
                logo,kernel = "logo_kernel.bmp";
                logo,mode = "center";
                charge_logo,mode = "center";
                connect = <&vp1_out_dp0>;
            };

            route_dsi0: route-dsi0 {
                status = "disabled";
                logo,uboot = "logo.bmp";
                logo,kernel = "logo_kernel.bmp";
                logo,mode = "center";
                charge_logo,mode = "center";
                connect = <&vp3_out_dsi0>;
            };

            route_dsi1: route-dsi1 {
                status = "disabled";
                logo,uboot = "logo.bmp";
                logo,kernel = "logo_kernel.bmp";
                logo,mode = "center";
                charge_logo,mode = "center";
                connect = <&vp3_out_dsi1>;
            };

            route_edp0: route-edp0 {
                status = "disabled";
                logo,uboot = "logo.bmp";
                logo,kernel = "logo_kernel.bmp";
                logo,mode = "center";
                charge_logo,mode = "center";
                connect = <&vp2_out_edp0>;
            };

            route_edp1: route-edp1 {
                status = "disabled";
                logo,uboot = "logo.bmp";
                logo,kernel = "logo_kernel.bmp";
                logo,mode = "center";
                charge_logo,mode = "center";
            };

            route_hdmi0: route-hdmi0 {
                status = "disabled";
                logo,uboot = "logo.bmp";
                logo,kernel = "logo_kernel.bmp";
                logo,mode = "center";
                charge_logo,mode = "center";
                connect = <&vp0_out_hdmi0>;
            };

            route_rgb: route-rgb {
                status = "disabled";
                logo,uboot = "logo.bmp";
                logo,kernel = "logo_kernel.bmp";
                logo,mode = "center";
                charge_logo,mode = "center";
                connect = <&vp3_out_rgb>;
            };
        };
    };


    hdmi0: hdmi@fde80000 {
        compatible = "rockchip,rk3588-dw-hdmi";
        reg = <0x0 0xfde80000 0x0 0x20000>;
        interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>,
                 <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
                 <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>,
                 <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>,
                 <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>;
        clocks = <&cru PCLK_HDMITX0>,
             <&cru CLK_HDMIHDP0>,
             <&cru CLK_HDMITX0_EARC>,
             <&cru CLK_HDMITX0_REF>,
             <&cru MCLK_I2S5_8CH_TX>,
             <&cru DCLK_VOP0>,
             <&cru DCLK_VOP1>,
             <&cru DCLK_VOP2>,
             <&cru DCLK_VOP3>,
             <&hclk_vo1>,
             <&hdptxphy_hdmi_clk0>;
        clock-names = "pclk",
                  "hpd",
                  "earc",
                  "hdmitx_ref",
                  "aud",
                  "dclk_vp0",
                  "dclk_vp1",
                  "dclk_vp2",
                  "dclk_vp3",
                  "hclk_vo1",
                  "link_clk";
        resets = <&cru SRST_HDMITX0_REF>, <&cru SRST_HDMIHDP0>;
        reset-names = "ref", "hdp";
        power-domains = <&power RK3588_PD_VO1>;
        pinctrl-names = "default";
        pinctrl-0 = <&hdmim0_tx0_cec &hdmim0_tx0_hpd &hdmim0_tx0_scl &hdmim0_tx0_sda>;
        reg-io-width = <4>;
        rockchip,grf = <&sys_grf>;
        rockchip,vo1_grf = <&vo1_grf>;
        phys = <&hdptxphy_hdmi0>;
        phy-names = "hdmi";
        #sound-dai-cells = <0>;
        status = "disabled";

        ports {
            #address-cells = <1>;
            #size-cells = <0>;

            hdmi0_in: port@0 {
                reg = <0>;
                #address-cells = <1>;
                #size-cells = <0>;

                hdmi0_in_vp0: endpoint@0 {
                    reg = <0>;
                    remote-endpoint = <&vp0_out_hdmi0>;
                    status = "disabled";
                };

                hdmi0_in_vp1: endpoint@1 {
                    reg = <1>;
                    remote-endpoint = <&vp1_out_hdmi0>;
                    status = "disabled";
                };

                hdmi0_in_vp2: endpoint@2 {
                    reg = <2>;
                    remote-endpoint = <&vp2_out_hdmi0>;
                    status = "disabled";
                };
            };
        };
    };
};

#include "rk3588s-pinctrl.dtsi"


Y:\android12-rk-outside\kernel-5.10\arch\arm64\boot\dts\rockchip\rk3588.dtsi

// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
 * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
 */

#include <dt-bindings/phy/phy-snps-pcie3.h>
#include "rk3588s.dtsi"
#include "rk3588-vccio3-pinctrl.dtsi"

/ {
    aliases {
        csi2dphy3 = &csi2_dphy3;
        csi2dphy4 = &csi2_dphy4;
        csi2dphy5 = &csi2_dphy5;
        dp0 = &dp0;
        dp1 = &dp1;
        edp0 = &edp0;
        edp1 = &edp1;
        ethernet0 = &gmac0;
        hdptx0 = &hdptxphy0;
        hdptx1 = &hdptxphy1;
        hdptxhdmi0 = &hdptxphy_hdmi0;
        hdptxhdmi1 = &hdptxphy_hdmi1;
        hdmi0 = &hdmi0;
        hdmi1 = &hdmi1;

        hdmirx0 = &hdmirx_ctrler;
        rkcif_mipi_lvds4= &rkcif_mipi_lvds4;
        rkcif_mipi_lvds5= &rkcif_mipi_lvds5;
        usbdp0 = &usbdp_phy0;
        usbdp1 = &usbdp_phy1;
    };


    hdmi1: hdmi@fdea0000 {
        compatible = "rockchip,rk3588-dw-hdmi";
        reg = <0x0 0xfdea0000 0x0 0x20000>;
        interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>,
                 <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>,
                 <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>,
                 <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>,
                 <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>;
        clocks = <&cru PCLK_HDMITX1>,
             <&cru CLK_HDMIHDP1>,
             <&cru CLK_HDMITX1_EARC>,
             <&cru CLK_HDMITX1_REF>,
             <&cru MCLK_I2S6_8CH_TX>,
             <&cru DCLK_VOP0>,
             <&cru DCLK_VOP1>,
             <&cru DCLK_VOP2>,
             <&cru DCLK_VOP3>,
             <&hclk_vo1>,
             <&hdptxphy_hdmi_clk1>;
        clock-names = "pclk",
                  "hpd",
                  "earc",
                  "hdmitx_ref",
                  "aud",
                  "dclk_vp0",
                  "dclk_vp1",
                  "dclk_vp2",
                  "dclk_vp3",
                  "hclk_vo1",
                  "link_clk";
        resets = <&cru SRST_HDMITX1_REF>, <&cru SRST_HDMIHDP1>;
        reset-names = "ref", "hdp";
        power-domains = <&power RK3588_PD_VO1>;
        pinctrl-names = "default";
        pinctrl-0 = <&hdmim2_tx1_cec &hdmim0_tx1_hpd &hdmim1_tx1_scl &hdmim1_tx1_sda>;
        reg-io-width = <4>;
        rockchip,grf = <&sys_grf>;
        rockchip,vo1_grf = <&vo1_grf>;
        phys = <&hdptxphy_hdmi1>;
        phy-names = "hdmi";
        #sound-dai-cells = <0>;
        status = "disabled";

        ports {
            #address-cells = <1>;
            #size-cells = <0>;

            hdmi1_in: port@0 {
                reg = <0>;
                #address-cells = <1>;
                #size-cells = <0>;

                hdmi1_in_vp0: endpoint@0 {
                    reg = <0>;
                    remote-endpoint = <&vp0_out_hdmi1>;
                    status = "disabled";
                };

                hdmi1_in_vp1: endpoint@1 {
                    reg = <1>;
                    remote-endpoint = <&vp1_out_hdmi1>;
                    status = "disabled";
                };

                hdmi1_in_vp2: endpoint@2 {
                    reg = <2>;
                    remote-endpoint = <&vp2_out_hdmi1>;
                    status = "disabled";
                };
            };
        };
    };


    hdptxphy1: phy@fed70000 {
        compatible = "rockchip,rk3588-hdptx-phy";
        reg = <0x0 0xfed70000 0x0 0x2000>;
        clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX1>;
        clock-names = "ref", "apb";
        resets = <&cru SRST_P_HDPTX1>, <&cru SRST_HDPTX1_INIT>,
             <&cru SRST_HDPTX1_CMN>, <&cru SRST_HDPTX1_LANE>;
        reset-names = "apb", "init", "cmn", "lane";
        rockchip,grf = <&hdptxphy1_grf>;
        #phy-cells = <0>;
        status = "disabled";
    };


    hdptxphy_hdmi1: hdmiphy@fed70000 {
        compatible = "rockchip,rk3588-hdptx-phy-hdmi";
        reg = <0x0 0xfed70000 0x0 0x2000>;
        clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX1>;
        clock-names = "ref", "apb";
        resets = <&cru SRST_HDPTX1>, <&cru SRST_P_HDPTX1>,
             <&cru SRST_HDPTX1_INIT>, <&cru SRST_HDPTX1_CMN>,
             <&cru SRST_HDPTX1_LANE>, <&cru SRST_HDPTX1_ROPLL>,
             <&cru SRST_HDPTX1_LCPLL>;
        reset-names = "phy", "apb", "init", "cmn", "lane", "ropll",
                  "lcpll";
        rockchip,grf = <&hdptxphy1_grf>;
        #phy-cells = <0>;
        status = "disabled";

        hdptxphy_hdmi_clk1: clk-port {
            #clock-cells = <0>;
            status = "okay";
        };
    };
};


1.4 新增特殊分辨率
DRM 框架目前代码已经支持了绝大部分分辨率时序,但是部分 HDMI 屏幕旋转的场景下,可能还有一些特殊分辨率不支持。需要在 kernel\drivers\gpu\drm\drm_edid.c 中的 drm_dmt_modes 当末尾新增:

/* 0x58 - 4096x2160@59.94Hz RB */
{ DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 556188, 4096, 4104,
    4136, 4176, 0, 2160, 2208, 2216, 2222, 0,
    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },

参数    说明
4096x2160    mode name,为分辨率的 hdisplay*vdisplay
DRM_MODE_TYPE_DRIVER    mode type,配置为DRM_MODE_TYPE_DRIVER
556188    像素时钟
4096    行有效像素
4104    行同步起始像素
4136    行同步结束像素
4176    一行总像素
0    hskew,通常为 0
2160    帧有效行
2208    帧同步开始行
2216    帧同步结束行
2222    一帧总行数
0    vscan, 通常为 0
vrefresh    显示设备帧率
DRM_MODE_FLAG_PHSYNC I DRM_MODE_FLAG_NVSYNC    hsync 和 vsync 极性,flags 的定义如下:DRM_MODE_FLAG_PHSYNC (1<<0) DRM_MODE_FLAG_NHSYNC (1<<1) DRM_MODE_FLAG_PVSYNC (1<<2) DRM_MODE_FLAG_NVSYNC (1<<3) DRM_MODE_FLAG_INTERLACE (1<<4)


Y:\android12-rk-outside\kernel-5.10\drivers\gpu\drm\drm_edid.c

/*
 * Autogenerated from the DMT spec.
 * This table is copied from xfree86/modes/xf86EdidModes.c.
 */
static const struct drm_display_mode drm_dmt_modes[] = {
    /* 0x01 - 640x350@85Hz */
    { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 31500, 640, 672,
           736, 832, 0, 350, 382, 385, 445, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },

    /* 0x02 - 640x400@85Hz */
    { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 31500, 640, 672,
           736, 832, 0, 400, 401, 404, 445, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x03 - 720x400@85Hz */
    { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 756,
           828, 936, 0, 400, 401, 404, 446, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x04 - 640x480@60Hz */
    { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
           752, 800, 0, 480, 490, 492, 525, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x05 - 640x480@72Hz */
    { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664,
           704, 832, 0, 480, 489, 492, 520, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x06 - 640x480@75Hz */
    { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656,
           720, 840, 0, 480, 481, 484, 500, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x07 - 640x480@85Hz */
    { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 36000, 640, 696,
           752, 832, 0, 480, 481, 484, 509, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x08 - 800x600@56Hz */
    { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824,
           896, 1024, 0, 600, 601, 603, 625, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x09 - 800x600@60Hz */
    { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
           968, 1056, 0, 600, 601, 605, 628, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x0a - 800x600@72Hz */
    { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 50000, 800, 856,
           976, 1040, 0, 600, 637, 643, 666, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x0b - 800x600@75Hz */
    { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816,
           896, 1056, 0, 600, 601, 604, 625, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x0c - 800x600@85Hz */
    { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 56250, 800, 832,
           896, 1048, 0, 600, 601, 604, 631, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x0d - 800x600@120Hz RB */
    { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 73250, 800, 848,
           880, 960, 0, 600, 603, 607, 636, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x0e - 848x480@60Hz */
    { DRM_MODE("848x480", DRM_MODE_TYPE_DRIVER, 33750, 848, 864,
           976, 1088, 0, 480, 486, 494, 517, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x0f - 1024x768@43Hz, interlace */
    { DRM_MODE("1024x768i", DRM_MODE_TYPE_DRIVER, 44900, 1024, 1032,
           1208, 1264, 0, 768, 768, 776, 817, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
           DRM_MODE_FLAG_INTERLACE) },
    /* 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) },
    /* 0x11 - 1024x768@70Hz */
    { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048,
           1184, 1328, 0, 768, 771, 777, 806, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x12 - 1024x768@75Hz */
    { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78750, 1024, 1040,
           1136, 1312, 0, 768, 769, 772, 800, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x13 - 1024x768@85Hz */
    { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 94500, 1024, 1072,
           1168, 1376, 0, 768, 769, 772, 808, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x14 - 1024x768@120Hz RB */
    { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 115500, 1024, 1072,
           1104, 1184, 0, 768, 771, 775, 813, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x15 - 1152x864@75Hz */
    { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
           1344, 1600, 0, 864, 865, 868, 900, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x55 - 1280x720@60Hz */
    { 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) },
    /* 0x16 - 1280x768@60Hz RB */
    { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 68250, 1280, 1328,
           1360, 1440, 0, 768, 771, 778, 790, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x17 - 1280x768@60Hz */
    { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344,
           1472, 1664, 0, 768, 771, 778, 798, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x18 - 1280x768@75Hz */
    { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 102250, 1280, 1360,
           1488, 1696, 0, 768, 771, 778, 805, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x19 - 1280x768@85Hz */
    { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 117500, 1280, 1360,
           1496, 1712, 0, 768, 771, 778, 809, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x1a - 1280x768@120Hz RB */
    { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 140250, 1280, 1328,
           1360, 1440, 0, 768, 771, 778, 813, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x1b - 1280x800@60Hz RB */
    { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 71000, 1280, 1328,
           1360, 1440, 0, 800, 803, 809, 823, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x1c - 1280x800@60Hz */
    { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352,
           1480, 1680, 0, 800, 803, 809, 831, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x1d - 1280x800@75Hz */
    { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 106500, 1280, 1360,
           1488, 1696, 0, 800, 803, 809, 838, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x1e - 1280x800@85Hz */
    { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 122500, 1280, 1360,
           1496, 1712, 0, 800, 803, 809, 843, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x1f - 1280x800@120Hz RB */
    { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 146250, 1280, 1328,
           1360, 1440, 0, 800, 803, 809, 847, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x20 - 1280x960@60Hz */
    { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1376,
           1488, 1800, 0, 960, 961, 964, 1000, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x21 - 1280x960@85Hz */
    { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1344,
           1504, 1728, 0, 960, 961, 964, 1011, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x22 - 1280x960@120Hz RB */
    { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 175500, 1280, 1328,
           1360, 1440, 0, 960, 963, 967, 1017, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x23 - 1280x1024@60Hz */
    { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1328,
           1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x24 - 1280x1024@75Hz */
    { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296,
           1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x25 - 1280x1024@85Hz */
    { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 157500, 1280, 1344,
           1504, 1728, 0, 1024, 1025, 1028, 1072, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x26 - 1280x1024@120Hz RB */
    { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 187250, 1280, 1328,
           1360, 1440, 0, 1024, 1027, 1034, 1084, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x27 - 1360x768@60Hz */
    { DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 85500, 1360, 1424,
           1536, 1792, 0, 768, 771, 777, 795, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x28 - 1360x768@120Hz RB */
    { DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 148250, 1360, 1408,
           1440, 1520, 0, 768, 771, 776, 813, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x51 - 1366x768@60Hz */
    { DRM_MODE("1366x768", DRM_MODE_TYPE_DRIVER, 85500, 1366, 1436,
           1579, 1792, 0, 768, 771, 774, 798, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x56 - 1366x768@60Hz */
    { DRM_MODE("1366x768", DRM_MODE_TYPE_DRIVER, 72000, 1366, 1380,
           1436, 1500, 0, 768, 769, 772, 800, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x29 - 1400x1050@60Hz RB */
    { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 101000, 1400, 1448,
           1480, 1560, 0, 1050, 1053, 1057, 1080, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x2a - 1400x1050@60Hz */
    { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488,
           1632, 1864, 0, 1050, 1053, 1057, 1089, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x2b - 1400x1050@75Hz */
    { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 156000, 1400, 1504,
           1648, 1896, 0, 1050, 1053, 1057, 1099, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x2c - 1400x1050@85Hz */
    { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 179500, 1400, 1504,
           1656, 1912, 0, 1050, 1053, 1057, 1105, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x2d - 1400x1050@120Hz RB */
    { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 208000, 1400, 1448,
           1480, 1560, 0, 1050, 1053, 1057, 1112, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x2e - 1440x900@60Hz RB */
    { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 88750, 1440, 1488,
           1520, 1600, 0, 900, 903, 909, 926, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x2f - 1440x900@60Hz */
    { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1520,
           1672, 1904, 0, 900, 903, 909, 934, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x30 - 1440x900@75Hz */
    { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 136750, 1440, 1536,
           1688, 1936, 0, 900, 903, 909, 942, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x31 - 1440x900@85Hz */
    { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 157000, 1440, 1544,
           1696, 1952, 0, 900, 903, 909, 948, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x32 - 1440x900@120Hz RB */
    { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 182750, 1440, 1488,
           1520, 1600, 0, 900, 903, 909, 953, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x53 - 1600x900@60Hz */
    { DRM_MODE("1600x900", DRM_MODE_TYPE_DRIVER, 108000, 1600, 1624,
           1704, 1800, 0, 900, 901, 904, 1000, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x33 - 1600x1200@60Hz */
    { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, 1664,
           1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x34 - 1600x1200@65Hz */
    { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 175500, 1600, 1664,
           1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x35 - 1600x1200@70Hz */
    { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 189000, 1600, 1664,
           1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x36 - 1600x1200@75Hz */
    { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 202500, 1600, 1664,
           1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x37 - 1600x1200@85Hz */
    { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 229500, 1600, 1664,
           1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x38 - 1600x1200@120Hz RB */
    { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 268250, 1600, 1648,
           1680, 1760, 0, 1200, 1203, 1207, 1271, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x39 - 1680x1050@60Hz RB */
    { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 119000, 1680, 1728,
           1760, 1840, 0, 1050, 1053, 1059, 1080, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x3a - 1680x1050@60Hz */
    { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784,
           1960, 2240, 0, 1050, 1053, 1059, 1089, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x3b - 1680x1050@75Hz */
    { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 187000, 1680, 1800,
           1976, 2272, 0, 1050, 1053, 1059, 1099, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x3c - 1680x1050@85Hz */
    { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 214750, 1680, 1808,
           1984, 2288, 0, 1050, 1053, 1059, 1105, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x3d - 1680x1050@120Hz RB */
    { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 245500, 1680, 1728,
           1760, 1840, 0, 1050, 1053, 1059, 1112, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x3e - 1792x1344@60Hz */
    { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 204750, 1792, 1920,
           2120, 2448, 0, 1344, 1345, 1348, 1394, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x3f - 1792x1344@75Hz */
    { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 261000, 1792, 1888,
           2104, 2456, 0, 1344, 1345, 1348, 1417, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x40 - 1792x1344@120Hz RB */
    { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 333250, 1792, 1840,
           1872, 1952, 0, 1344, 1347, 1351, 1423, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x41 - 1856x1392@60Hz */
    { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 218250, 1856, 1952,
           2176, 2528, 0, 1392, 1393, 1396, 1439, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x42 - 1856x1392@75Hz */
    { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 288000, 1856, 1984,
           2208, 2560, 0, 1392, 1393, 1396, 1500, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x43 - 1856x1392@120Hz RB */
    { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 356500, 1856, 1904,
           1936, 2016, 0, 1392, 1395, 1399, 1474, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x52 - 1920x1080@60Hz */
    { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
           2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },

    /* 0x44 - 1920x1200@60Hz RB */
    { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 154000, 1920, 1968,
           2000, 2080, 0, 1200, 1203, 1209, 1235, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x45 - 1920x1200@60Hz */
    { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056,
           2256, 2592, 0, 1200, 1203, 1209, 1245, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x46 - 1920x1200@75Hz */
    { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 245250, 1920, 2056,
           2264, 2608, 0, 1200, 1203, 1209, 1255, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x47 - 1920x1200@85Hz */
    { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 281250, 1920, 2064,
           2272, 2624, 0, 1200, 1203, 1209, 1262, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x48 - 1920x1200@120Hz RB */
    { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 317000, 1920, 1968,
           2000, 2080, 0, 1200, 1203, 1209, 1271, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x49 - 1920x1440@60Hz */
    { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 234000, 1920, 2048,
           2256, 2600, 0, 1440, 1441, 1444, 1500, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x4a - 1920x1440@75Hz */
    { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2064,
           2288, 2640, 0, 1440, 1441, 1444, 1500, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x4b - 1920x1440@120Hz RB */
    { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 380500, 1920, 1968,
           2000, 2080, 0, 1440, 1443, 1447, 1525, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x54 - 2048x1152@60Hz */
    { DRM_MODE("2048x1152", DRM_MODE_TYPE_DRIVER, 162000, 2048, 2074,
           2154, 2250, 0, 1152, 1153, 1156, 1200, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x4c - 2560x1600@60Hz RB */
    { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 268500, 2560, 2608,
           2640, 2720, 0, 1600, 1603, 1609, 1646, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x4d - 2560x1600@60Hz */
    { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752,
           3032, 3504, 0, 1600, 1603, 1609, 1658, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x4e - 2560x1600@75Hz */
    { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 443250, 2560, 2768,
           3048, 3536, 0, 1600, 1603, 1609, 1672, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x4f - 2560x1600@85Hz */
    { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 505250, 2560, 2768,
           3048, 3536, 0, 1600, 1603, 1609, 1682, 0,
           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
    /* 0x50 - 2560x1600@120Hz RB */
    { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 552750, 2560, 2608,
           2640, 2720, 0, 1600, 1603, 1609, 1694, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x57 - 4096x2160@60Hz RB */
    { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 556744, 4096, 4104,
           4136, 4176, 0, 2160, 2208, 2216, 2222, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
    /* 0x58 - 4096x2160@59.94Hz RB */
    { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 556188, 4096, 4104,
           4136, 4176, 0, 2160, 2208, 2216, 2222, 0,
           DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },

};


1.5 强制输出指定分辨率
当需要无视 EDID 的限制,需要强制输出某个分辨率:

Y:\android12-rk-outside\kernel-5.10\drivers\gpu\drm\bridge\synopsys\dw-hdmi.c
Y:\android12-rk-outside\kernel-5.10\drivers\gpu\drm\drm_edid.c
Y:\android12-rk-outside\kernel-5.10\drivers\gpu\drm\rockchip\dw_hdmi-rockchip.c

diff --git a/kernel/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/kernel/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 8165851656..12137d0c68 100644
--- a/kernel/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/kernel/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2497,7 +2497,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
                          connector);
     struct edid *edid;
     struct drm_display_mode *mode;
-    const u8 def_modes[6] = {4, 16, 31, 19, 17, 2};
+    const u8 def_modes[6] = {30, 16, 31, 19, 17, 2}; //把def_mode数组的第一个值对应的是默认显示hdmi的分辨率对应的 vic(dw-hdmi.c文件中)
     struct drm_display_info *info = &connector->display_info;
     struct hdr_static_metadata *metedata =
             &connector->display_info.hdmi.hdr_panel_metadata;
@@ -2507,6 +2507,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
         return 0;
 
     edid = drm_get_edid(connector, hdmi->ddc);
+   edid = NULL; //edid = NULL; 强制进入 EDID 读取失败的流程,不管有没有读到 EDID 都强制按def_modes 的分辨率来显示。
     if (edid) {
         dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",
             edid->width_cm, edid->height_cm);
diff --git a/kernel/drivers/gpu/drm/drm_edid.c b/kernel/drivers/gpu/drm/drm_edid.c
index 3fd2dd5c4a..4cac0b7584 100644
--- a/kernel/drivers/gpu/drm/drm_edid.c
+++ b/kernel/drivers/gpu/drm/drm_edid.c
@@ -820,11 +820,11 @@ static const struct drm_display_mode edid_cea_modes[] = {
            1592, 1728, 0, 576, 581, 586, 625, 0,
            DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
       .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
-    /* 30 - 1440x576@50Hz */
-    { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464,
-           1592, 1728, 0, 576, 581, 586, 625, 0,
-           DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
-      .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+    /* 30 - 3840x1448@60Hz */
+    { DRM_MODE("3840x1448", DRM_MODE_TYPE_DRIVER, 297000, 3840, 3888,
+           3920, 4400, 0, 1448, 1451, 1456, 1538, 0,
+          DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC),
+     .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, 
     /* 31 - 1920x1080@50Hz */
     { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
            2492, 2640, 0, 1080, 1084, 1089, 1125, 0,


如果需要强制显示 4K 的分辨率,还需要注释掉以下代码,解除对 4K 分辨率的限制:

diff --git a/kernel/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/kernel/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index cabddaa6f2..8cf1b19b7c 100644
--- a/kernel/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/kernel/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -490,10 +490,12 @@ dw_hdmi_rockchip_mode_valid(struct drm_connector *connector,
      * If sink max TMDS clock < 340MHz, we should check the mode pixel
      * clock > 340MHz is YCbCr420 or not.
      */
+#if 0
     if (mode->clock > 340000 &&
         connector->display_info.max_tmds_clock < 340000 &&
         (!drm_mode_is_420(&connector->display_info, mode)|| !connector->ycbcr_420_allowed))
         return MODE_BAD;
+#endif
 
     if (!encoder) {
         const struct drm_connector_helper_funcs *funcs;


1.6 打开音频
RK3288 默认 HDMI 声卡和 Codec 公用,要确保以下配置打开:

&hdmi_analog_sound {
    status = "okay";
}


rootroot@rootroot-desktop:~/android12-rk-outside/kernel-5.10/arch/arm64/boot/dts/rockchip$ grep hdmi_analog_sound . -R
rootroot@rootroot-desktop:~/android12-rk-outside/kernel-5.10/arch/arm64/boot/dts/rockchip$ grep hdmi . -R

./rk3588-toybrick.dtsi:    hdmi0_sound: hdmi0-sound {
./rk3588-toybrick.dtsi:        compatible = "rockchip,hdmi";
./rk3588-toybrick.dtsi:        rockchip,card-name = "rockchip-hdmi0";
./rk3588-toybrick.dtsi:        rockchip,codec = <&hdmi0>;
./rk3588-toybrick.dtsi:    hdmi1_sound: hdmi1-sound {
./rk3588-toybrick.dtsi:        compatible = "rockchip,hdmi";
./rk3588-toybrick.dtsi:        rockchip,card-name = "rockchip-hdmi1";
./rk3588-toybrick.dtsi:        rockchip,codec = <&hdmi1>;
./rk3588-vccio3-pinctrl.dtsi:    hdmi {
./rk3588-vccio3-pinctrl.dtsi:        hdmim0_tx1_cec: hdmim0-tx1-cec {
./rk3588-vccio3-pinctrl.dtsi:                /* hdmim0_tx1_cec */
./rk3588-vccio3-pinctrl.dtsi:        hdmim0_tx1_scl: hdmim0-tx1-scl {
./rk3588-vccio3-pinctrl.dtsi:                /* hdmim0_tx1_scl */
./rk3588-vccio3-pinctrl.dtsi:        hdmim0_tx1_sda: hdmim0-tx1-sda {
./rk3588-vccio3-pinctrl.dtsi:                /* hdmim0_tx1_sda */
./Makefile:dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3562-evb2-ddr4-v10-sii9022-bt1120-to-hdmi.dtb
./Makefile:dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb2-lp4x-v10-bt1120-to-hdmi.dtb
./Makefile:dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb6-ddr3-v10-rk628-bt1120-to-hdmi.dtb
./Makefile:dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb6-ddr3-v10-rk628-rgb2hdmi.dtb
./Makefile:dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-evb3-lp4x-v10-sii9022-bt1120-to-hdmi.dtb
./rk3588.dtsi:        hdptxhdmi0 = &hdptxphy_hdmi0;
./rk3588.dtsi:        hdptxhdmi1 = &hdptxphy_hdmi1;
./rk3588.dtsi:        hdmi0 = &hdmi0;
./rk3588.dtsi:        hdmi1 = &hdmi1;
./rk3588.dtsi:        hdmirx0 = &hdmirx_ctrler;
./rk3588.dtsi:        rockchip,hdmi-path;
./rk3588.dtsi:    hdmi1: hdmi@fdea0000 {
./rk3588.dtsi:        compatible = "rockchip,rk3588-dw-hdmi";
./rk3588.dtsi:             <&hdptxphy_hdmi_clk1>;
./rk3588.dtsi:                  "hdmitx_ref",
./rk3588.dtsi:        pinctrl-0 = <&hdmim2_tx1_cec &hdmim0_tx1_hpd &hdmim1_tx1_scl &hdmim1_tx1_sda>;
./rk3588.dtsi:        phys = <&hdptxphy_hdmi1>;
./rk3588.dtsi:        phy-names = "hdmi";
./rk3588.dtsi:            hdmi1_in: port@0 {
./rk3588.dtsi:                hdmi1_in_vp0: endpoint@0 {
./rk3588.dtsi:                    remote-endpoint = <&vp0_out_hdmi1>;
./rk3588.dtsi:                hdmi1_in_vp1: endpoint@1 {
./rk3588.dtsi:                    remote-endpoint = <&vp1_out_hdmi1>;
./rk3588.dtsi:                hdmi1_in_vp2: endpoint@2 {
./rk3588.dtsi:                    remote-endpoint = <&vp2_out_hdmi1>;
./rk3588.dtsi:    hdmirx_ctrler: hdmirx-controller@fdee0000 {
./rk3588.dtsi:        compatible = "rockchip,rk3588-hdmirx-ctrler", "rockchip,hdmirx-ctrler";
./rk3588.dtsi:        reg-names = "hdmirx_regs";
./rk3588.dtsi:        interrupt-names = "cec", "hdmi", "dma";
./rk3588.dtsi:                  "hclk_s_hdmirx",
./rk3588.dtsi:        pinctrl-0 = <&hdmim1_rx>;
./rk3588.dtsi:    hdptxphy_hdmi1: hdmiphy@fed70000 {
./rk3588.dtsi:        compatible = "rockchip,rk3588-hdptx-phy-hdmi";
./rk3588.dtsi:        hdptxphy_hdmi_clk1: clk-port {
./rk3588.dtsi:        route_hdmi1: route-hdmi1 {
./rk3588.dtsi:            connect = <&vp1_out_hdmi1>;
./rk3588.dtsi:    vp0_out_hdmi1: endpoint@5 {
./rk3588.dtsi:        remote-endpoint = <&hdmi1_in_vp0>;
./rk3588.dtsi:    vp1_out_hdmi1: endpoint@5 {
./rk3588.dtsi:        remote-endpoint = <&hdmi1_in_vp1>;
./rk3588.dtsi:    vp2_out_hdmi1: endpoint@7 {
./rk3588.dtsi:        remote-endpoint = <&hdmi1_in_vp2>;
./rk3588s.dtsi:            route_hdmi0: route-hdmi0 {
./rk3588s.dtsi:                connect = <&vp0_out_hdmi0>;
./rk3588s.dtsi:                     <&qos_hdmirx>;
./rk3588s.dtsi:                vp0_out_hdmi0: endpoint@2 {
./rk3588s.dtsi:                    remote-endpoint = <&hdmi0_in_vp0>;
./rk3588s.dtsi:                vp1_out_hdmi0: endpoint@2 {
./rk3588s.dtsi:                    remote-endpoint = <&hdmi0_in_vp1>;
./rk3588s.dtsi:                vp2_out_hdmi0: endpoint@2 {
./rk3588s.dtsi:                    remote-endpoint = <&hdmi0_in_vp2>;
./rk3588s.dtsi:        rockchip,hdmi-path;
./rk3588s.dtsi:    hdmi0: hdmi@fde80000 {
./rk3588s.dtsi:        compatible = "rockchip,rk3588-dw-hdmi";
./rk3588s.dtsi:             <&hdptxphy_hdmi_clk0>;
./rk3588s.dtsi:                  "hdmitx_ref",
./rk3588s.dtsi:        pinctrl-0 = <&hdmim0_tx0_cec &hdmim0_tx0_hpd &hdmim0_tx0_scl &hdmim0_tx0_sda>;
./rk3588s.dtsi:        phys = <&hdptxphy_hdmi0>;
./rk3588s.dtsi:        phy-names = "hdmi";
./rk3588s.dtsi:            hdmi0_in: port@0 {
./rk3588s.dtsi:                hdmi0_in_vp0: endpoint@0 {
./rk3588s.dtsi:                    remote-endpoint = <&vp0_out_hdmi0>;
./rk3588s.dtsi:                hdmi0_in_vp1: endpoint@1 {
./rk3588s.dtsi:                    remote-endpoint = <&vp1_out_hdmi0>;
./rk3588s.dtsi:                hdmi0_in_vp2: endpoint@2 {
./rk3588s.dtsi:                    remote-endpoint = <&vp2_out_hdmi0>;
./rk3588s.dtsi:    qos_hdmirx: qos@fdf81200 {
./rk3588s.dtsi:    hdptxphy_hdmi0: hdmiphy@fed60000 {
./rk3588s.dtsi:        compatible = "rockchip,rk3588-hdptx-phy-hdmi";
./rk3588s.dtsi:        hdptxphy_hdmi_clk0: clk-port {
./rk3588-toybrick-x0.dtsi:    /* If hdmirx node is disabled, delete the reserved-memory node here. */
./rk3588-toybrick-x0.dtsi:        /* Reserve 128MB memory for hdmirx-controller@fdee0000 */
./rk3588-toybrick-x0.dtsi:    hdmiin_dc: hdmiin-dc {
./rk3588-toybrick-x0.dtsi:    hdmiin-sound {
./rk3588-toybrick-x0.dtsi:        simple-audio-card,name = "rockchip,hdmiin";
./rk3588-toybrick-x0.dtsi:            sound-dai = <&hdmiin_dc>;
./rk3588-toybrick-x0.dtsi:&hdmi0 {
./rk3588-toybrick-x0.dtsi:&hdmi0_in_vp0 {
./rk3588-toybrick-x0.dtsi:&hdmi0_sound {


2. 常用调试方法
2.1 查看 VOP 状态
cat d/dri/0/summary


【必须打开显示器才能看到信息!^_】
console:/ # 
console:/ # 
console:/ # cat d/dri/0/summary                                                
Video Port0: ACTIVE
    Connector: HDMI-A-1
    bus_format[2025]: YUV8_1X24
    overlay_mode[1] output_mode[f] color_space[3], eotf:0
    Display mode: 1920x1080p60
    clk[148500] real_clk[148500] type[48] flag[5]
    H: 1920 2008 2052 2200
    V: 1080 1084 1089 1125
    Cluster0-win0: ACTIVE
    win_id: 0
    format: AB24 little-endian (0x34324241)[AFBC] SDR[0] color_space[0] glb_alpha[0xff]
    rotate: xmirror: 0 ymirror: 0 rotate_90: 0 rotate_270: 0
    csc: y2r[0] r2y[1] csc mode[1]
    zpos: 0
    src: pos[0, 0] rect[1920 x 1080]
    dst: pos[0, 0] rect[1920 x 1080]
    buf[0]: addr: 0x0000000001e43000 pitch: 7680 offset: 0
Video Port1: DISABLED
Video Port2: DISABLED
Video Port3: DISABLED
console:/ # 


2.2 查看 Connector 状态
/sys/class/drm 目录下可以看到驱动注册的各个显卡,

可以看到注册了 card0-HDMI-A-1 和 card0-DSI-1 两种显示设备,分别表示 HDMI 和 DSI。

以 card0-HDMI-A-1 为例,其目录下有以下文件:
1.Enabled:使能状态
2.Status:连接状态
3.Mode:当前输出分辨率
4.Modes:连接设备支持的分辨率列表
5.Audioformat:连接设备支持的音频格式
6.Edid:连接设备的 EDID,可以通过命令 cat edid > /data/edid.bin 保存下来。


126|console:/ # 
126|console:/ # ls -l /sys/class/drm                                           
total 0
lrwxrwxrwx 1 root root    0 2024-05-22 10:11 card0 -> ../../devices/platform/display-subsystem/drm/card0
lrwxrwxrwx 1 root root    0 2024-05-22 10:11 card0-DP-1 -> ../../devices/platform/display-subsystem/drm/card0/card0-DP-1
lrwxrwxrwx 1 root root    0 2024-05-22 09:36 card0-HDMI-A-1 -> ../../devices/platform/display-subsystem/drm/card0/card0-HDMI-A-1
lrwxrwxrwx 1 root root    0 2024-05-22 10:11 card0-Writeback-1 -> ../../devices/platform/display-subsystem/drm/card0/card0-Writeback-1
lrwxrwxrwx 1 root root    0 2024-05-22 10:11 card1 -> ../../devices/platform/fdab0000.npu/drm/card1
lrwxrwxrwx 1 root root    0 2024-05-22 10:11 renderD128 -> ../../devices/platform/display-subsystem/drm/renderD128
lrwxrwxrwx 1 root root    0 2024-05-22 10:11 renderD129 -> ../../devices/platform/fdab0000.npu/drm/renderD129
-r--r--r-- 1 root root 4096 2024-05-22 10:11 version
console:/ # 
console:/ # cd /sys/class/dr                                                   
drm/                drm_dp_aux_dev/
console:/ # cd /sys/class/drm/c                                                
card0-DP-1/         card0-Writeback-1/  card1/
card0-HDMI-A-1/     card0/
console:/ # cd /sys/class/drm/card0-HDMI-A-1/                                  
console:/sys/class/drm/card0-HDMI-A-1 # 
console:/sys/class/drm/card0-HDMI-A-1 # ls -l
total 0
lrwxrwxrwx 1 root   root      0 2021-01-01 12:00 device -> ../../card0
-r--r--r-- 1 root   root   4096 2021-01-01 12:00 dpms
-r--r--r-- 1 root   root      0 2021-01-01 12:00 edid
-r--r--r-- 1 root   root   4096 2021-01-01 12:00 enabled
-r--r--r-- 1 root   root   4096 2021-01-01 12:00 modes
drwxr-xr-x 2 root   root      0 2021-01-01 12:00 power
-rw-r--r-- 1 system system 4096 2021-01-01 12:00 status
lrwxrwxrwx 1 root   root      0 2021-01-01 12:00 subsystem -> ../../../../../../class/drm
-rw-r--r-- 1 root   root   4096 2021-01-01 12:00 uevent
console:/sys/class/drm/card0-HDMI-A-1 # 
console:/sys/class/drm/card0-HDMI-A-1 # cat edid
??????m[Z<"x诵?UN?&
                   PT?KqO??@:q8-@X,EVQ! 
      ??5
      ?
            -?#    e 
                         :q8-@X,EVQ!q X,%VQ!rQΞ n(UVQ! 

? ??>VQ!console:/sys/class/drm/card0-HDMI-A-1 # Xshell
/system/bin/sh: Xshell: inaccessible or not found
127|console:/sys/class/drm/card0-HDMI-A-1 # 
127|console:/sys/class/drm/card0-HDMI-A-1 # [ 2345.859708][  T412] healthd: battery l=50 v=3 t=2.6 h=2 st=3 c=-1600 fc=100 chg=au

127|console:/sys/class/drm/card0-HDMI-A-1 # cat edid > /data/edid.bin
console:/sys/class/drm/card0-HDMI-A-1 # 


2.3 查看 HDMI 工作状态
使用以下命令查看当前 HDMI 输出状态:
cat /sys/kernel/debug/dw-hdmi/status


1|console:/ # 
1|console:/ # cd /sys/kernel/debug/dw-hdmi0/                                   
console:/sys/kernel/debug/dw-hdmi0 # ls -l
total 0
-rw------- 1 root root 0 1970-01-01 00:00 ctrl
-r-------- 1 root root 0 1970-01-01 00:00 status
console:/sys/kernel/debug/dw-hdmi0 # 
console:/sys/kernel/debug/dw-hdmi0 # cat status                                
PHY: enabled            Mode: HDMI
TMDS Mode Pixel Clk: 148500000Hz        TMDS Clk: 148500000Hz
ALLM: 0
Color Format: YUV444        Color Depth: 8 bit
Colorimetry: ITU.BT709        EOTF: Off

console:/sys/kernel/debug/dw-hdmi0 # 
console:/sys/kernel/debug/dw-hdmi0 # 


2.4 强制使能/禁用 HDMI
强制使能 HDMI:
echo on > /sys/class/drm/card0-HDMI-A-1/status 1

强制禁用 HDMI:
echo off > /sys/class/drm/card0-HDMI-A-1/status 1

恢复检测热插拔:
echo detect > /sys/class/drm/card0-HDMI-A-1/status


console:/sys/class/drm/card0-HDMI-A-1 # ls -l
total 0
lrwxrwxrwx 1 root   root      0 2021-01-01 12:00 device -> ../../card0
-r--r--r-- 1 root   root   4096 2021-01-01 12:00 dpms
-r--r--r-- 1 root   root      0 2021-01-01 12:00 edid
-r--r--r-- 1 root   root   4096 2021-01-01 12:00 enabled
-r--r--r-- 1 root   root   4096 2021-01-01 12:00 modes
drwxr-xr-x 2 root   root      0 2021-01-01 12:00 power
-rw-r--r-- 1 system system 4096 2021-01-01 12:00 status
lrwxrwxrwx 1 root   root      0 2021-01-01 12:00 subsystem -> ../../../../../../class/drm
-rw-r--r-- 1 root   root   4096 2021-01-01 12:00 uevent
console:/sys/class/drm/card0-HDMI-A-1 # 
console:/sys/class/drm/card0-HDMI-A-1 # 
console:/sys/class/drm/card0-HDMI-A-1 # cat status                             
connected
console:/sys/class/drm/card0-HDMI-A-1 # 
console:/sys/class/drm/card0-HDMI-A-1 # echo off > status

[ 2679.081652][  T308] type=1400 audit(1716373281.203:126): avc: denied { read } for comm="UEventObserver" name="uevent" dev="sysfs" ino=15855 scontext=u:r:system_server:s0 tcontext=u:object_r:sysfs:s0 tclass=file permissive=1
[ 2679.082072][  T308] type=1400 audit(1716373281.203:127): avc: denied { open } for comm="UEventObserver" path="/sys/devices/platform/fde80000.hdmi/uevent" dev="sysfs" ino=15855 scontext=u:r:system_server:s0 tcontext=u:object_r:sysfs:s0 tclass=file permissive=1
console:/sys/class/drm/card0-HDMI-A-1 # [ 2679.082168][  T308] type=1400 audit(1716373281.203:128): avc: denied { getattr } for comm="UEventObserver" path="/sys/devices/platform/fde80000.hdmi/uevent" dev="sysfs" ino=15855 scontext=u:r:system_server:s0 tcontext=u:object_r:sysfs:s0 tclass=file permissive=1
[ 2679.149027][  T392] rockchip-vop2 fdd90000.vop: [drm:vop2_crtc_atomic_disable] Crtc atomic disable vp0

console:/sys/class/drm/card0-HDMI-A-1 # 
console:/sys/class/drm/card0-HDMI-A-1 # cat status
disconnected
console:/sys/class/drm/card0-HDMI-A-1 # 
console:/sys/class/drm/card0-HDMI-A-1 # 
cho on > status      
                                                        <
console:/sys/class/drm/card0-HDMI-A-1 # [ 2695.412699][  T392] dwhdmi-rockchip fde80000.hdmi: use tmds mode
[ 2695.412900][  T392] rockchip-vop2 fdd90000.vop: [drm:vop2_crtc_atomic_enable] Update mode to 1920x1080p60, type: 11(if:800) for vp0 dclk: 148500000
[ 2695.413940][  T392] rockchip-vop2 fdd90000.vop: [drm:vop2_crtc_atomic_enable] dclk_out0 div: 0 dclk_core0 div: 2
[ 2695.413998][  T392] rockchip-vop2 fdd90000.vop: [drm:vop2_crtc_atomic_enable] set dclk_vop0 to 148500000, get 148500000
[ 2695.414093][  T392] rockchip-hdptx-phy-hdmi fed60000.hdmiphy: hdptx_ropll_cmn_config bus_width:16a8c8 rate:1485000
[ 2695.414472][  T392] rockchip-hdptx-phy-hdmi fed60000.hdmiphy: hdptx phy pll locked!
[ 2695.414508][  T392] dwhdmi-rockchip fde80000.hdmi: final tmdsclk = 148500000
[ 2695.414599][  T392] dwhdmi-rockchip fde80000.hdmi: don't use dsc mode
[ 2695.414628][  T392] dwhdmi-rockchip fde80000.hdmi: dw hdmi qp use tmds mode
[ 2695.414663][  T392] rockchip-hdptx-phy-hdmi fed60000.hdmiphy: bus_width:0x16a8c8,bit_rate:1485000
[ 2695.414925][  T392] rockchip-hdptx-phy-hdmi fed60000.hdmiphy: hdptx phy lane locked!
[ 2695.609047][  T371] dwhdmi-rockchip fde80000.hdmi: use tmds mode

console:/sys/class/drm/card0-HDMI-A-1 # 
console:/sys/class/drm/card0-HDMI-A-1 # cat status
connected

console:/sys/class/drm/card0-HDMI-A-1 # 

参考资料:
https://blog.csdn.net/weixin_45639314/article/details/132026699
RK3288 android7.1 HDMI的使用与调试方法 -- (一)
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/684266.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

分表策略,你真的分对了?

垂直分表方案 表的记录并不多&#xff0c;但是字段却很长&#xff0c;表占用空间很大&#xff0c;检索表的时候需要执行大量的IO&#xff0c;严重降低了性能。这时需要把大的字段拆分到另一个表&#xff0c;并且该表与原表是一对一的关系。 为什么垂直拆分之后查询性能就变快…

Django里的Form组件

Form组件提供 自动生成HTML标签和半自动读取关联数据 (“半自动”是指还得需要自己手写输入数据进来)表单验证和错误提示 要想创建并使用该组件&#xff0c;操作步骤如下&#xff1a; 在 views.py 里创建类 # 在 views.py 文件里from django import formsclass AssetForm(fo…

HDFS文件块损坏处理方案

1、问题概述 flume采集文本文件存储到hdfs中hive的ods层目录,并在hive中通过msck repair table刷新元数据,加载文本文件。报错如下: 2、问题分析 文件块BP-531411289-172.31.57.12-1539657748238出现了未知异常,导致namenode不能获取该文件块的信息,该文件块是由flume采…

JeecgBoot/SpringBoot升级Nacos(2.0.4到2.2.3)启动报错

错误如下&#xff1a; 报这种错误基本就很头大了&#xff0c;是框架不兼容的问题&#xff0c;自己找很难找到解决方法。 解决方案是把SpringBoot框架版本调高。 修改前&#xff1a; <parent><groupId>org.springframework.boot</groupId><artifactId&g…

如何在 Mac 上玩 Windows 游戏:Parallels Desktop 玩转秘籍

引言 作为一名热爱游戏的 Mac 用户&#xff0c;你可能曾为 Mac 系统的有限游戏选择感到困扰。然而&#xff0c;通过 Parallels Desktop 虚拟机软件&#xff0c;你可以在 Mac 上轻松畅玩多款 Windows 游戏&#xff0c;尽情体验游戏的乐趣。 为什么选择 Parallels Desktop&…

刷机维修进阶教程-----魅族18系列 魅族21系列机型修复基带 改写参数等 通用新机型操作 步骤解析

在前面几期博文中解析了一些老款机型修复基带 修复各项参数以及改写参数的步骤解析。通常这些步骤可以用于各种问题导致的基带丢失 串码丢失以及有些参数修复或者一些特殊场合需要改写参数的需求。今天对于一些新机型操作以上需求做一些步骤解析,明白其操作原理。可以通用于一…

LeetCode 26删除有序数组中的重复项

去重题&#xff0c;双指针&#xff0c;&#xff0c;因为题干说原地删除&#xff0c;且nums其余元素不重要。一个cur记录当前不重复的数应该插在第几位了&#xff0c;for循环里的i相当于是第二个指针&#xff08;右指针&#xff09;&#xff0c;遍历数组来找不重复的元素 class …

C#WPF数字大屏项目实战12--动态获取设备数据

1、如何获取设备实时数据 现在大屏上的数据都是静态的数据或后台构造的来源数据&#xff0c;在实际项目中现场数据应该来自现场的实时数据&#xff0c;这些数据有些是来自现场设备的动态数据&#xff0c;有些是来自其他系统推送的&#xff0c;有些需要主动查询其他业务&#xf…

基于Arduino的简易磁悬浮装置原理图和源代码分享

磁悬浮装置原理 大家可能都玩过这种磁悬浮玩具&#xff0c;它们的工作原理与此类似。 首先&#xff0c;让我们了解一下这个原理&#xff0c;其实非常简单。它主要依赖于磁力对悬浮物体的控制。基本原理如下&#xff1a;在浮子的正下方放置一个霍尔传感器。当传感器检测到浮子向…

Vue3+.NET6前后端分离式管理后台实战(二十五)

1&#xff0c;Vue3.NET6前后端分离式管理后台实战(二十五)已经在微信公众号更新&#xff0c;有兴趣的扫码关注一起交流学习。

Java面试题:Redis持久化问题

Redis持久化问题 RDB (Redis Database Backup File) Redis数据快照 将内存中的所有数据都记录到磁盘中做快照 当Redis实例故障重启时,从磁盘读取快照文件恢复数据 使用 save/bgsave命令进行手动快照 save使用主进程执行RDB,对所有命令都进行阻塞 bgsave使用子进程执行R…

多链路聚合设备在自然灾害应急能力提升工程基层防灾项目内的应用

在近几年信息技术的飞速发展&#xff0c;面对应急通信和指挥调度时需要移动化无线通信技术来做支撑&#xff0c;多链路聚合设备在中间的作用至关重要&#xff0c;实现从车到车、人到车、车到中心的多样化应用场景进行数据图像的无线传输和多节点组网方案需求&#xff0c;来满足…

(近似求π)可以使用以下公式计算 π:

package myjava; import java.math.*; public class cy {public static void main(String[]args){double pi;double sum0;double t0;int i;for(i1;i<10000;i){tMath.pow(-1,i)/(2.0*i-1.0);sumt;}System.out.println("PI"sum*4);} } 运行结果&#xff1a;

从零开始写 Docker(十七)---容器网络实现(中):为容器插上”网线“

本文为从零开始写 Docker 系列第十七篇&#xff0c;利用 linux 下的 Veth、Bridge、iptables 等等相关技术&#xff0c;构建容器网络模型&#xff0c;为容器插上”网线“。 完整代码见&#xff1a;https://github.com/lixd/mydocker 欢迎 Star 推荐阅读以下文章对 docker 基本实…

python语言中变量的作用域

def getpoint&#xff08;&#xff09;&#xff1a; x 10 y 20 return x&#xff0c;y x&#xff0c;y getpoint&#xff08;&#xff09; print &#xff08;x&#xff0c;y&#xff09; 函数内部的x&#xff0c;y和函数外面的x&#xff0c;y是同一组变量吗? 不同的变量…

AG32 MCU+FPGA 使用感受

前言&#xff1a; 笔者35了&#xff0c;10多年前开始玩单片机/FPGA啥的&#xff0c;从现在回想过去&#xff0c;眼下真的是我们国家微电子发展的好时候。各种各样的国产单片机&#xff0c;FPGA啥的&#xff0c;想想本科的时候用的Freescale&#xff0c;后来用的STM32&#xff0…

SpringCloud Gateway基础入门与使用实践总结

官网文档&#xff1a;点击查看官网文档 Cloud全家桶中有个很重要的组件就是网关&#xff0c;在1.x版本中都是采用的Zuul网关。但在2.x版本中&#xff0c;zuul的升级一直跳票&#xff0c;SpringCloud最后自己研发了一个网关替代Zuul&#xff0c;那就是SpringCloud Gateway一句话…

面试(03)————多线程

目录 一、线程和进程的区别&#xff1f; 二、并行和并发的区别&#xff1f; 三、线程创建的方式有哪些&#xff1f; 3.1、继承Thread类 3.2、实现Runnable接口 3.3、实现Callable接口 3.4、线程池 四、Runnable和Callable的区别&#xff1f; 五、在启动线程的时候&am…

git-生成SSH密钥

git-生成SSH密钥 1 打开命令窗口2 操作 1 打开命令窗口 选择"Git Bash Here"&#xff0c;打开Git命令窗口 2 操作 查看当前用户名称 git config user.name配置你的邮箱&#xff0c;“6xxxqq.com” 填写自己的邮箱 git config --global user.email "6xxxqq…

WPF真入门教程32--WPF数字大屏项目实干

1、项目背景 WPF (Windows Presentation Foundation) 是微软的一个框架&#xff0c;用于构建桌面客户端应用程序&#xff0c;它支持富互联网应用程序&#xff08;RIA&#xff09;的开发。在数字大屏应用中&#xff0c;WPF可以用来构建复杂的用户界面&#xff0c;展示庞大的数据…