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的使用与调试方法 -- (一)
 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言 | Leetcode C语言题解之第136题只出现一次的数字

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<int> singleNumbers(vector<int>& nums) {int eor 0;for (int num:nums)eor ^ num;int rightOne eor & (~eor 1); // 提取出最右的1int onlyOne 0;for (int cur : nums) {if ((cur…

弘君资本今日投资参考:新能源消纳政策加码 智能网联汽车再加速

昨日&#xff0c;沪指午后在金融、酿酒等板块的带动下发力拉升&#xff0c;深证成指、创业板指走势微弱。截至收盘&#xff0c;沪指涨0.41%报3091.2点&#xff0c;深证成指涨1.05%报9469.32点&#xff0c;创业板指涨1.33%报1843.59点&#xff0c;上证50指数涨0.58%&#xff0c;…

[知识点]c++ future库 async方法

C 标准库中的 future 和 async 提供了一种便捷的方式来实现并发编程。std::async 是一个非常强大的工具&#xff0c;它可以用于启动异步任务&#xff0c;并返回一个 std::future 对象&#xff0c;该对象可以用来等待任务的结果。 std::async 的基本用法 std::async 用于启动一…

LCEDA使用:QA(不定期更新)

1. 优势&#xff1a; 器件库选择&#xff1a;可以在立创商城中选择器件库&#xff0c;操作便捷。面板切换&#xff1a;S快捷键在 画图/器件选择 面板中切换&#xff0c;不打断工作节奏。连续放置Net Label&#xff1a;连续放置net label的体验流畅。复制粘贴功能&#xff1a;复…

android-线程池3

工具类 package com.changan.incalleventservice.utils;import java.util.concurrent.Callable; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExec…

python之DeprecationWarning: invalid escape sequence ‘\/‘解决方案(亲测可用)

爬取的页面里包含很多 \ 双反斜杠&#xff0c; 想replace 出现 invalid escape sequence ‘/‘ 警告 出现警告的原因是 ‘unicode_escape’ 编码不支持 ‘/’ 这样的转义序列。&#xff0c;如果你想要处理 / 这样的转义序列&#xff0c;可以使用 ‘raw_unicode_escape’ 编码来…

论文阅读 Explainable Image Similarity Integrating Siamese Networks and Grad-CAM

给出论文&#xff08;Explainable Image Similarity Integrating Siamese Networks and Grad-CAM&#xff09;的内容解读、代码运行说明 论文链接&#xff1a;J. Imaging | Free Full-Text | Explainable Image Similarity: Integrating Siamese Networks and Grad-CAM (mdpi.c…

插入排序(排序算法)

文章目录 插入排序详细代码 插入排序 插入排序&#xff0c;类似于扑克牌的玩法一样&#xff0c;在有序的数组中&#xff0c;扫描无序的数组&#xff0c;逐一的将元素插入到有序的数组中。 实现细节&#xff1a; 从第一个元素开始&#xff0c;该元素可以认为已经被排序取出下…

Ansible-doc 命令

目录 基本用法 查看指定模块的文档 列出所有可用模块 搜索模块 显示模块参数的简单列表 显示详细的说明和示例 详细示例 查看 file 模块的文档 简略查看 copy 模块的参数 ansible-doc 是 Ansible 中的一个非常有用的命令行工具&#xff0c;它可以帮助你查找和显示Ansi…

基于ensp的园区网络搭建综合实验

核心技术介绍 1、虚拟局域网&#xff08;VLAN&#xff09; 2、链路聚合&#xff08;E-trunk&#xff09; 3、多生成树协议&#xff08;MSTP&#xff09; 4、VLANIF三层逻辑接口 5、虚拟路由冗余协议&#xff08;VRRP&#xff09; 6、开放式最短路径优先&#xff08;OSPF&…

灵动岛动效:打造沉浸式用户体验

灵动岛是专属于 iPhone 14 Pro 系列交互UI&#xff0c;通过通知消息的展示和状态的查看与硬件相结合&#xff0c;让 iPhone 14 Pro 系列的前置摄像头和传感器的“感叹号”&#xff0c;发生不同形状的变化。这样做的好处是让虚拟软件和硬件的交互变得更为流畅&#xff0c;以便让…

qt 与 x11 头文件同时引用,出现重定义的问题

qt 与 x11 头文件同时引用&#xff0c;出现重定义的问题 一、问题描述二、解决问题 一、问题描述 qt 与 x11 头文件同时引用&#xff0c;出现重定义的问题&#xff1a;expected identifier before numeric constant 二、解决问题 #include <X11/X.h> #include <X11…

vue3中使用tinymce

1.引入必要组件&#xff1a; npm install --save tinymce "tinymce/tinymce-vue" npm install --save "types/tinymce" 2.页面中引入&#xff1a; import tinymce from "tinymce/tinymce"; import Editor from "tinymce/tinymce-vue&quo…

手机建站介绍

随着科技的不断进步和移动互联网的普及&#xff0c;手机应用已经成为人们生活中最不可或缺的一部分。而手机建站作为一种新兴技术&#xff0c;在这一领域也有着广泛的应用。本文将为大家介绍手机建站的概念、优势和应用。 什么是手机建站&#xff1f; 手机建站是指将传统的网络…

AI学习指南机器学习篇-决策树算法简介

AI学习指南机器学习篇-决策树算法简介 在机器学习领域&#xff0c;决策树算法是一种常用且十分重要的分类方法。它是一种树形结构的模型&#xff0c;可以帮助我们理解数据之间的关系&#xff0c;找出规律并做出预测。本文将为大家介绍决策树算法的基本概念&#xff0c;并探讨其…

删除MongoDB索引和缓存问题

由于数据模型是拷贝的&#xff0c;忘记删除原来的索引&#xff0c;导致存入数据时MongoDB抛异常exceptionHandler { MongoError: E11000 duplicate key error collection: house_eva.wpestatecomprehensivenesses index: real_estate_name_1_city_1 dup key: { real_estate_nam…

信息系统项目管理师0144:裁剪考虑因素(9项目范围管理—9.2项目范围管理过程—9.2.2裁剪考虑因素)

点击查看专栏目录 文章目录 9.2.2 裁剪考虑因素 9.2.2 裁剪考虑因素 因为每个项目都是独特的&#xff0c;所以项目经理可能根据需要裁剪项目范围管理过程。裁剪时应考虑的因素包括&#xff1a; 知识和需求管理&#xff1a;项目经理应建立哪些指南&#xff1f;为了在未来项目中…

利用opencv-python实现图像全景拼接技术实现

这个代码的主要功能是将多张图像拼接成一张全景图。它使用了OpenCV库中的SIFT特征提取、特征匹配和图像变换等技术来实现图像拼接。 一、预览效果 二、安装依赖 contourpy1.2.1 cycler0.12.1 fonttools4.53.0 importlib_resources6.4.0 kiwisolver1.4.5 matplotlib3.9.0 numpy…

LeetCode|2331. Evaluate Boolean Binary Tree

. 题目 You are given the root of a full binary tree with the following properties: Leaf nodes have either the value 0 or 1, where 0 represents False and 1 represents True. Non-leaf nodes have either the value 2 or 3, where 2 represents the boolean OR an…

【数据结构】——线性表(顺序表)——内有代码详解

目录 一、引言 二、线性表 2.1 定义 2.2 特点 三、顺序表 3.1 顺序表的概念 3.2 顺序表的特点 3.3 顺序表的定义 3.3.1 静态定义 3.3.2 动态定义 3.4 顺序表的初始化 3.4.1 静态初始化 3.4.2 动态初始化 3.5 顺序表的销毁 3.6 顺序表元素的打印 3.7 顺序表的插入…