diff --git a/config/bootscripts/boot-rk322x.cmd b/config/bootscripts/boot-rk322x.cmd index 278164ccf4..5174c37b9a 100644 --- a/config/bootscripts/boot-rk322x.cmd +++ b/config/bootscripts/boot-rk322x.cmd @@ -16,7 +16,7 @@ setenv docker_optimizations "on" # If gpio3 pin 25 is 0, write magic to GRF os_reg[0] register and # reset to trigger maskrom mode -if gpio input D25; then +if gpio input 121; then echo "Resetting into MASKROM mode..." mw.l 0x110005c8 0xEF08A53C 1 reset diff --git a/config/sources/families/rockchip.conf b/config/sources/families/rockchip.conf index 4566a19f8c..e06326aaf8 100644 --- a/config/sources/families/rockchip.conf +++ b/config/sources/families/rockchip.conf @@ -40,10 +40,10 @@ elif [[ "$BOOT_SOC" == "rk322x" ]]; then BOOTSCRIPT="boot-rk322x.cmd:boot.cmd" BOOTENV_FILE='rk322x.txt' OVERLAY_PREFIX='rk322x' - UBOOT_TARGET_MAP="all u-boot.itb;;u-boot-rk322x-with-spl.bin" + UBOOT_TARGET_MAP="ROCKCHIP_TPL=$SRC/packages/blobs/rockchip/rk322x_ddr_333MHz_v1.11_2t.bin TEE=$SRC/packages/blobs/rockchip/rk322x_tee.bin;;u-boot-rk322x-with-spl.bin" - BOOTBRANCH='tag:v2022.04' - BOOTPATCHDIR='v2022.04' + BOOTBRANCH='tag:v2024.01' + BOOTPATCHDIR='v2024.01' fi @@ -180,8 +180,13 @@ elif [[ "$BOOT_SOC" == "rk322x" ]]; then # tools/mkimage -n rk322x -T rksd -d tpl/u-boot-tpl.bin u-boot-rk322x-with-spl.bin # - run_host_command_logged tools/mkimage -n rk322x -T rksd -d $SRC/packages/blobs/rockchip/rk322x_ddr_333MHz_v1.11_2t.bin u-boot-rk322x-with-spl.bin - run_host_command_logged cat spl/u-boot-spl.bin ">>" u-boot-rk322x-with-spl.bin + # As of u-boot v2024.01, binman takes care of building the idbloader, so there is + # no need anymore for mkimage and cat commands to assemble the thing, but we keep + # the commands here for reference: + # - run_host_command_logged tools/mkimage -n rk322x -T rksd -d $SRC/packages/blobs/rockchip/rk322x_ddr_333MHz_v1.11_2t.bin u-boot-rk322x-with-spl.bin + # - run_host_command_logged cat spl/u-boot-spl.bin ">>" u-boot-rk322x-with-spl.bin + # + run_host_command_logged cat idbloader.img > u-boot-rk322x-with-spl.bin run_host_command_logged dd if=u-boot.itb of=u-boot-rk322x-with-spl.bin seek=$((0x200 - 0x40)) conv=notrunc } diff --git a/patch/u-boot/v2024.01/board_rk3318-box/general-rockchip-vop-enhancements.patch b/patch/u-boot/v2024.01/board_rk322x-box/driver-rockchip-vop-cleanup.patch similarity index 100% rename from patch/u-boot/v2024.01/board_rk3318-box/general-rockchip-vop-enhancements.patch rename to patch/u-boot/v2024.01/board_rk322x-box/driver-rockchip-vop-cleanup.patch diff --git a/patch/u-boot/v2024.01/board_rk3318-box/general-hdmi-vendor-phy-handling.patch b/patch/u-boot/v2024.01/board_rk322x-box/general-hdmi-01-vendor-phy-handling.patch similarity index 77% rename from patch/u-boot/v2024.01/board_rk3318-box/general-hdmi-vendor-phy-handling.patch rename to patch/u-boot/v2024.01/board_rk322x-box/general-hdmi-01-vendor-phy-handling.patch index d7255025e5..78122ce819 100644 --- a/patch/u-boot/v2024.01/board_rk3318-box/general-hdmi-vendor-phy-handling.patch +++ b/patch/u-boot/v2024.01/board_rk322x-box/general-hdmi-01-vendor-phy-handling.patch @@ -1,20 +1,21 @@ -From c6c14957e96c46f0f197f787f407f8c3c152c17a Mon Sep 17 00:00:00 2001 -From: Jagan Teki -Date: Sun, 19 Feb 2023 00:01:34 +0530 +From db428dbc58ba2788fb13d4bf1985f0540fd7f4b3 Mon Sep 17 00:00:00 2001 +From: Paolo Sabatino +Date: Tue, 30 Apr 2024 22:09:57 +0200 Subject: [PATCH] video: dw_hdmi: Add Vendor PHY handling -Signed-off-by: Jagan Teki +original work by Jagan Teki --- - drivers/video/dw_hdmi.c | 29 +++++++++++++++++++++++++++- - drivers/video/meson/meson_dw_hdmi.c | 11 ++++++++++- - drivers/video/rockchip/rk3399_hdmi.c | 8 +++++++- + drivers/video/dw_hdmi.c | 46 +++++++++++++++++++++++++++- + drivers/video/meson/meson_dw_hdmi.c | 11 ++++++- + drivers/video/rockchip/rk3399_hdmi.c | 8 ++++- drivers/video/rockchip/rk_hdmi.c | 2 +- - drivers/video/sunxi/sunxi_dw_hdmi.c | 11 ++++++++++- - include/dw_hdmi.h | 14 +++++++++++++- - 6 files changed, 69 insertions(+), 6 deletions(-) + drivers/video/rockchip/rk_hdmi.h | 3 ++ + drivers/video/sunxi/sunxi_dw_hdmi.c | 11 ++++++- + include/dw_hdmi.h | 14 ++++++++- + 7 files changed, 89 insertions(+), 6 deletions(-) diff --git a/drivers/video/dw_hdmi.c b/drivers/video/dw_hdmi.c -index c4fbb182944..ea12a094074 100644 +index c4fbb18294..fc8c8bb366 100644 --- a/drivers/video/dw_hdmi.c +++ b/drivers/video/dw_hdmi.c @@ -988,7 +988,7 @@ int dw_hdmi_enable(struct dw_hdmi *hdmi, const struct display_timing *edid) @@ -26,7 +27,7 @@ index c4fbb182944..ea12a094074 100644 if (ret) return ret; -@@ -1009,10 +1009,37 @@ int dw_hdmi_enable(struct dw_hdmi *hdmi, const struct display_timing *edid) +@@ -1009,10 +1009,54 @@ int dw_hdmi_enable(struct dw_hdmi *hdmi, const struct display_timing *edid) return 0; } @@ -55,23 +56,6 @@ index c4fbb182944..ea12a094074 100644 + hdmi->ops = hdmi->data->phy_ops; +} + - void dw_hdmi_init(struct dw_hdmi *hdmi) - { - uint ih_mute; - -+ dw_hdmi_detect_phy(hdmi); -+ - /* - * boot up defaults are: - * hdmi_ih_mute = 0x03 (disabled) -diff --git a/drivers/video/dw_hdmi.c b/drivers/video/dw_hdmi.c -index c4fbb18294..1c5ee25280 100644 ---- a/drivers/video/dw_hdmi.c -+++ b/drivers/video/dw_hdmi.c -@@ -1009,6 +1025,23 @@ int dw_hdmi_enable(struct dw_hdmi *hdmi, const struct display_timing *edid) - return 0; - } - +int dw_hdmi_disable(struct dw_hdmi *hdmi) +{ + uint clkdis; @@ -92,16 +76,22 @@ index c4fbb18294..1c5ee25280 100644 void dw_hdmi_init(struct dw_hdmi *hdmi) { uint ih_mute; + ++ dw_hdmi_detect_phy(hdmi); ++ + /* + * boot up defaults are: + * hdmi_ih_mute = 0x03 (disabled) diff --git a/drivers/video/meson/meson_dw_hdmi.c b/drivers/video/meson/meson_dw_hdmi.c -index e5f28132053..d03e8e493b7 100644 +index 5db01904b5..d0d878b6af 100644 --- a/drivers/video/meson/meson_dw_hdmi.c +++ b/drivers/video/meson/meson_dw_hdmi.c -@@ -374,6 +374,15 @@ static int meson_dw_hdmi_wait_hpd(struct dw_hdmi *hdmi) +@@ -375,6 +375,15 @@ static int meson_dw_hdmi_wait_hpd(struct dw_hdmi *hdmi) return -ETIMEDOUT; } +static const struct dw_hdmi_phy_ops dw_hdmi_meson_phy_ops = { -+ .phy_set = meson_dw_hdmi_phy_cfg, ++ .phy_set = meson_dw_hdmi_phy_init, +}; + +static const struct dw_hdmi_plat_data dw_hdmi_meson_plat_data = { @@ -112,7 +102,7 @@ index e5f28132053..d03e8e493b7 100644 static int meson_dw_hdmi_probe(struct udevice *dev) { struct meson_dw_hdmi *priv = dev_get_priv(dev); -@@ -396,7 +405,7 @@ static int meson_dw_hdmi_probe(struct udevice *dev) +@@ -397,7 +406,7 @@ static int meson_dw_hdmi_probe(struct udevice *dev) priv->hdmi.hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24; priv->hdmi.hdmi_data.enc_in_bus_format = MEDIA_BUS_FMT_YUV8_1X24; @@ -122,7 +112,7 @@ index e5f28132053..d03e8e493b7 100644 priv->hdmi.reg_io_width = 1; else { diff --git a/drivers/video/rockchip/rk3399_hdmi.c b/drivers/video/rockchip/rk3399_hdmi.c -index 3041360c6ed..b32139a8a6e 100644 +index 3041360c6e..b32139a8a6 100644 --- a/drivers/video/rockchip/rk3399_hdmi.c +++ b/drivers/video/rockchip/rk3399_hdmi.c @@ -64,8 +64,14 @@ static const struct dm_display_ops rk3399_hdmi_ops = { @@ -142,7 +132,7 @@ index 3041360c6ed..b32139a8a6e 100644 }; diff --git a/drivers/video/rockchip/rk_hdmi.c b/drivers/video/rockchip/rk_hdmi.c -index b75a1744896..e34f532cd68 100644 +index 8dcd4d5964..e545d69e3b 100644 --- a/drivers/video/rockchip/rk_hdmi.c +++ b/drivers/video/rockchip/rk_hdmi.c @@ -83,6 +83,7 @@ int rk_hdmi_of_to_plat(struct udevice *dev) @@ -161,11 +151,32 @@ index b75a1744896..e34f532cd68 100644 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); +diff --git a/drivers/video/rockchip/rk_hdmi.h b/drivers/video/rockchip/rk_hdmi.h +index 200dbaea74..dcfba3d3d7 100644 +--- a/drivers/video/rockchip/rk_hdmi.h ++++ b/drivers/video/rockchip/rk_hdmi.h +@@ -6,6 +6,8 @@ + #ifndef __RK_HDMI_H__ + #define __RK_HDMI_H__ + ++#include ++ + struct rkhdmi_driverdata { + /* configuration */ + u8 i2c_clk_high; +@@ -19,6 +21,7 @@ struct rkhdmi_driverdata { + + struct rk_hdmi_priv { + struct dw_hdmi hdmi; ++ struct phy phy; + void *grf; + }; + diff --git a/drivers/video/sunxi/sunxi_dw_hdmi.c b/drivers/video/sunxi/sunxi_dw_hdmi.c -index 19ed80b48a..8e4922c759 100644 +index 0324a050d0..f7ecbb923b 100644 --- a/drivers/video/sunxi/sunxi_dw_hdmi.c +++ b/drivers/video/sunxi/sunxi_dw_hdmi.c -@@ -322,6 +322,15 @@ static int sunxi_dw_hdmi_enable(struct udevice *dev, int panel_bpp, +@@ -328,6 +328,15 @@ static int sunxi_dw_hdmi_enable(struct udevice *dev, int panel_bpp, return 0; } @@ -181,7 +192,7 @@ index 19ed80b48a..8e4922c759 100644 static int sunxi_dw_hdmi_probe(struct udevice *dev) { struct sunxi_dw_hdmi_priv *priv = dev_get_priv(dev); -@@ -379,7 +386,7 @@ static int sunxi_dw_hdmi_of_to_plat(struct udevice *dev) +@@ -379,7 +388,7 @@ static int sunxi_dw_hdmi_of_to_plat(struct udevice *dev) hdmi->i2c_clk_high = 0xd8; hdmi->i2c_clk_low = 0xfe; hdmi->reg_io_width = 1; @@ -191,7 +202,7 @@ index 19ed80b48a..8e4922c759 100644 ret = reset_get_bulk(dev, &priv->resets); if (ret) diff --git a/include/dw_hdmi.h b/include/dw_hdmi.h -index 8acae3839fb..4ad8b39f84d 100644 +index 8acae3839f..4ad8b39f84 100644 --- a/include/dw_hdmi.h +++ b/include/dw_hdmi.h @@ -534,6 +534,17 @@ struct hdmi_data_info { @@ -223,3 +234,6 @@ index 8acae3839fb..4ad8b39f84d 100644 void (*write_reg)(struct dw_hdmi *hdmi, u8 val, int offset); u8 (*read_reg)(struct dw_hdmi *hdmi, int offset); }; +-- +2.34.1 + diff --git a/patch/u-boot/v2024.01/board_rk3318-box/general-hpd-enhancements.patch b/patch/u-boot/v2024.01/board_rk322x-box/general-hdmi-02-hpd-cleanup.patch similarity index 100% rename from patch/u-boot/v2024.01/board_rk3318-box/general-hpd-enhancements.patch rename to patch/u-boot/v2024.01/board_rk322x-box/general-hdmi-02-hpd-cleanup.patch diff --git a/patch/u-boot/v2024.01/board_rk322x-box/rk3228-hdmi-clk-fixes.patch b/patch/u-boot/v2024.01/board_rk322x-box/rk3228-hdmi-clk-fixes.patch new file mode 100644 index 0000000000..e3a8429c13 --- /dev/null +++ b/patch/u-boot/v2024.01/board_rk322x-box/rk3228-hdmi-clk-fixes.patch @@ -0,0 +1,227 @@ +From 497b401b7ec7f0fa52efa4765b8421e21b8840ff Mon Sep 17 00:00:00 2001 +From: Paolo Sabatino +Date: Mon, 29 Apr 2024 16:18:46 +0200 +Subject: [PATCH 4/4] clock entries to accomodate rk3228 HDMI features + +--- + .../include/asm/arch-rockchip/cru_rk322x.h | 14 ++ + drivers/clk/rockchip/clk_rk322x.c | 133 +++++++++++++++++- + 2 files changed, 144 insertions(+), 3 deletions(-) + +diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk322x.h b/arch/arm/include/asm/arch-rockchip/cru_rk322x.h +index cfbc7e92f7..de3c4bf310 100644 +--- a/arch/arm/include/asm/arch-rockchip/cru_rk322x.h ++++ b/arch/arm/include/asm/arch-rockchip/cru_rk322x.h +@@ -194,6 +194,10 @@ enum { + /* CRU_CLKSEL27_CON */ + VOP_DCLK_DIV_SHIFT = 8, + VOP_DCLK_DIV_MASK = 0xff << VOP_DCLK_DIV_SHIFT, ++ VOP_DCLK_PLL_SEL_SHIFT = 0, ++ VOP_DCLK_PLL_SEL_MASK = 1 << VOP_DCLK_PLL_SEL_SHIFT, ++ VOP_DCLK_SEL_GPLL = 0, ++ VOP_DCLK_SEL_CPLL = 1, + VOP_PLL_SEL_SHIFT = 1, + VOP_PLL_SEL_MASK = 1 << VOP_PLL_SEL_SHIFT, + +@@ -201,6 +205,16 @@ enum { + GMAC_CLK_SRC_SHIFT = 12, + GMAC_CLK_SRC_MASK = 1 << GMAC_CLK_SRC_SHIFT, + ++ /* CRU_CLKSEL33_CON */ ++ VOP_ACLK_DIV_SHIFT = 0, ++ VOP_ACLK_DIV_MASK = 0x1f << VOP_ACLK_DIV_SHIFT, ++ VOP_ACLK_PLL_SEL_SHIFT = 5, ++ VOP_ACLK_PLL_SEL_MASK = 3 << VOP_ACLK_PLL_SEL_SHIFT, ++ VOP_ACLK_SEL_CPLL = 0, ++ VOP_ACLK_SEL_GPLL = 1, ++ VOP_ACLK_SEL_HDMIPHY = 2, ++ VOP_ACLK_SEL_USBPHY = 3, ++ + /* CRU_SOFTRST5_CON */ + DDRCTRL_PSRST_SHIFT = 11, + DDRCTRL_SRST_SHIFT = 10, +diff --git a/drivers/clk/rockchip/clk_rk322x.c b/drivers/clk/rockchip/clk_rk322x.c +index 44b5778589..418164e63b 100644 +--- a/drivers/clk/rockchip/clk_rk322x.c ++++ b/drivers/clk/rockchip/clk_rk322x.c +@@ -371,6 +371,14 @@ static ulong rk322x_clk_get_rate(struct clk *clk) + case SCLK_SDMMC: + rate = rockchip_mmc_get_clk(priv->cru, gclk_rate, clk->id); + break; ++ case SCLK_HDMI_PHY: ++ case PCLK_HDMI_PHY: ++ case DCLK_HDMI_PHY: ++ case SCLK_HDMI_HDCP: ++ case PCLK_HDMI_CTRL: ++ case SCLK_HDMI_CEC: ++ printf("Attempt to get clk id %ld\n", clk->id); ++ return 0; + default: + return -ENOENT; + } +@@ -378,6 +386,68 @@ static ulong rk322x_clk_get_rate(struct clk *clk) + return rate; + } + ++#ifndef CONFIG_SPL_BUILD ++static ulong rk3228_vop_get_clk(struct rk322x_cru *cru, ulong clk_id) ++{ ++ u32 div, con, parent; ++ ++ switch (clk_id) { ++ case DCLK_VOP: ++ con = readl(&cru->cru_clksel_con[27]); ++ div = (con & VOP_DCLK_DIV_MASK) >> VOP_DCLK_DIV_SHIFT; ++ parent = GPLL_HZ; ++ break; ++ case ACLK_VOP: ++ con = readl(&cru->cru_clksel_con[33]); ++ div = (con & VOP_ACLK_DIV_MASK) >> VOP_ACLK_DIV_SHIFT; ++ parent = GPLL_HZ; ++ break; ++ default: ++ debug("%s: Unsupported vop get clk#%ld\n", __func__, clk_id); ++ return -ENOENT; ++ } ++ ++ return DIV_TO_RATE(parent, div); ++} ++ ++static ulong rk3228_vop_set_clk(struct rk322x_cru *cru, ++ ulong clk_id, uint hz) ++{ ++ int src_clk_div; ++ ++ src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz); ++ assert(src_clk_div - 1 < 31); ++ ++ switch (clk_id) { ++ case DCLK_VOP: ++ ++ /* ++ * Set HDMI parent clock to HDMIPHY. Normally, this is done ++ * by .set_parent, but u-boot does not seem to work well with ++ * device tree references ++ */ ++ rk_clrsetreg(&cru->cru_misc_con, BIT(13), 0); ++ ++ rk_clrsetreg(&cru->cru_clksel_con[27], ++ VOP_DCLK_DIV_MASK | VOP_DCLK_PLL_SEL_MASK, ++ VOP_DCLK_SEL_GPLL << VOP_DCLK_PLL_SEL_SHIFT | ++ (src_clk_div - 1) << VOP_DCLK_DIV_SHIFT); ++ break; ++ case ACLK_VOP: ++ rk_clrsetreg(&cru->cru_clksel_con[33], ++ VOP_ACLK_DIV_MASK | VOP_ACLK_PLL_SEL_MASK, ++ VOP_ACLK_SEL_GPLL << VOP_ACLK_PLL_SEL_SHIFT | ++ (src_clk_div - 1) << VOP_ACLK_DIV_SHIFT); ++ break; ++ default: ++ printf("%s: Unable to set vop clk#%ld\n", __func__, clk_id); ++ return -EINVAL; ++ } ++ ++ return rk3228_vop_get_clk(cru, clk_id); ++} ++#endif ++ + static ulong rk322x_clk_set_rate(struct clk *clk, ulong rate) + { + struct rk322x_clk_priv *priv = dev_get_priv(clk->dev); +@@ -400,7 +470,29 @@ static ulong rk322x_clk_set_rate(struct clk *clk, ulong rate) + new_rate = rk322x_mac_set_clk(priv->cru, rate); + break; + case PLL_GPLL: +- return 0; ++ case PLL_CPLL: ++ case ACLK_PERI: ++ case HCLK_PERI: ++ case PCLK_PERI: ++ case ACLK_CPU: ++ case HCLK_CPU: ++ case PCLK_CPU: ++ case ARMCLK: ++ case SCLK_HDMI_PHY: ++ case PCLK_HDMI_PHY: ++ case DCLK_HDMI_PHY: ++ case SCLK_HDMI_HDCP: ++ case PCLK_HDMI_CTRL: ++ case SCLK_HDMI_CEC: ++ debug("Attempt to set clkid %ld, rate=%ld\n", clk->id, rate); ++ return rate; ++#ifndef CONFIG_SPL_BUILD ++ case ACLK_VOP: ++ case DCLK_VOP: ++ debug("VOP set rate clkid %ld, rate=%ld\n", clk->id, rate); ++ rate = rk3228_vop_set_clk(priv->cru, clk->id, rate); ++ break; ++#endif + default: + return -ENOENT; + } +@@ -461,13 +553,44 @@ static int rk322x_gmac_extclk_set_parent(struct clk *clk, struct clk *parent) + return -EINVAL; + } + ++static int rk322x_hdmi_set_parent(struct clk *clk, struct clk *parent) ++{ ++ struct rk322x_clk_priv *priv = dev_get_priv(clk->dev); ++ const char *clock_output_name; ++ struct rk322x_cru *cru = priv->cru; ++ int ret; ++ ++ ret = dev_read_string_index(parent->dev, "clock-output-names", ++ parent->id, &clock_output_name); ++ if (ret < 0) ++ return -ENODATA; ++ ++ if (!strcmp(clock_output_name, "hdmiphy_phy")) { ++ debug("%s: switching hdmi_sclk to hdmiphy_phy\n", __func__); ++ rk_clrsetreg(&cru->cru_misc_con, BIT(13), 0); ++ return 0; ++ } else if (!strcmp(clock_output_name, "xin24m")) { ++ debug("%s: switching hdmi_sclk to xin24m\n", __func__); ++ rk_clrsetreg(&cru->cru_misc_con, BIT(13), BIT(13)); ++ return 0; ++ } ++ ++ return -EINVAL; ++ ++} ++ + static int rk322x_clk_set_parent(struct clk *clk, struct clk *parent) + { ++ ++ debug("%s, clkid=%ld, parent=%ld\n", __func__, clk->id, parent->id); ++ + switch (clk->id) { + case SCLK_MAC: + return rk322x_gmac_set_parent(clk, parent); + case SCLK_MAC_EXTCLK: + return rk322x_gmac_extclk_set_parent(clk, parent); ++ case SCLK_HDMI_PHY: ++ return rk322x_hdmi_set_parent(clk, parent); + } + + debug("%s: unsupported clk %ld\n", __func__, clk->id); +@@ -646,7 +773,7 @@ static int rk322x_clk_bind(struct udevice *dev) + debug("Warning: software reset driver bind failed\n"); + #endif + +- return 0; ++ return ret; + } + + static const struct udevice_id rk322x_clk_ids[] = { +@@ -655,7 +782,7 @@ static const struct udevice_id rk322x_clk_ids[] = { + }; + + U_BOOT_DRIVER(rockchip_rk322x_cru) = { +- .name = "clk_rk322x", ++ .name = "rockchip_rk322x_cru", + .id = UCLASS_CLK, + .of_match = rk322x_clk_ids, + .priv_auto = sizeof(struct rk322x_clk_priv), +-- +2.34.1 + diff --git a/patch/u-boot/v2024.01/board_rk322x-box/rk3228-hdmi-driver.patch b/patch/u-boot/v2024.01/board_rk322x-box/rk3228-hdmi-driver.patch new file mode 100644 index 0000000000..9d7e3453a7 --- /dev/null +++ b/patch/u-boot/v2024.01/board_rk322x-box/rk3228-hdmi-driver.patch @@ -0,0 +1,193 @@ +From eb306bf33a53aabf66754f70f61c01348e768d91 Mon Sep 17 00:00:00 2001 +From: Paolo Sabatino +Date: Mon, 29 Apr 2024 16:18:27 +0200 +Subject: [PATCH 3/4] rockchip rk3228 HDMI driver + +--- + drivers/video/rockchip/rk3228_hdmi.c | 161 +++++++++++++++++++++++++++ + 1 file changed, 161 insertions(+) + create mode 100644 drivers/video/rockchip/rk3228_hdmi.c + +diff --git a/drivers/video/rockchip/rk3228_hdmi.c b/drivers/video/rockchip/rk3228_hdmi.c +new file mode 100644 +index 0000000000..b07ac35ce1 +--- /dev/null ++++ b/drivers/video/rockchip/rk3228_hdmi.c +@@ -0,0 +1,161 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (c) 2023 Edgeble AI Technologies Pvt. Ltd. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "rk_hdmi.h" ++ ++#define HIWORD_UPDATE(val, mask) (val | (mask) << 16) ++ ++#define RK3228_GRF_SOC_CON2 0x0408 ++#define RK3228_GRF_SOC_CON6 0x0418 ++ ++#define RK3228_HDMI_HPD_VSEL BIT(6) ++#define RK3228_HDMI_SDA_VSEL BIT(5) ++#define RK3228_HDMI_SCL_VSEL BIT(4) ++ ++#define RK3228_HDMI_SDAIN_MSK BIT(14) ++#define RK3228_HDMI_SCLIN_MSK BIT(13) ++ ++static int rk3228_hdmi_enable(struct udevice *dev, int panel_bpp, ++ const struct display_timing *edid) ++{ ++ struct rk_hdmi_priv *priv = dev_get_priv(dev); ++ ++ return dw_hdmi_enable(&priv->hdmi, edid); ++} ++ ++static int rk3228_dw_hdmi_phy_cfg(struct dw_hdmi *hdmi, uint pixclock) ++{ ++ struct rk_hdmi_priv *priv = container_of(hdmi, struct rk_hdmi_priv, hdmi); ++ struct phy_configure_opts_inno_hdmi params; ++ int ret; ++ ++ params.pixel_clock = pixclock; ++ params.bus_width = 8; ++ ++ ret = generic_phy_configure(&priv->phy, ¶ms); ++ if (ret < 0) { ++ printf("failed to configure phy (pixel_clock=%d, bus_width=%d)\n", ++ params.pixel_clock, params.bus_width); ++ return ret; ++ } ++ ++ ret = generic_phy_power_on(&priv->phy); ++ if (ret) { ++ printf("failed to power on hdmi phy (ret=%d)\n", ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static void rk3228_dw_hdmi_setup_hpd(struct dw_hdmi *hdmi) ++{ ++ struct rk_hdmi_priv *priv = container_of(hdmi, struct rk_hdmi_priv, hdmi); ++ void *grf = priv->grf; ++ ++ /* ++ * Undocumented registers, write them to get correct access to EDID ++ */ ++ writel(HIWORD_UPDATE(RK3228_HDMI_HPD_VSEL | RK3228_HDMI_SDA_VSEL | RK3228_HDMI_SCL_VSEL, ++ RK3228_HDMI_HPD_VSEL | RK3228_HDMI_SDA_VSEL | RK3228_HDMI_SCL_VSEL), ++ grf + RK3228_GRF_SOC_CON6); ++ ++ writel(HIWORD_UPDATE(RK3228_HDMI_SDAIN_MSK | RK3228_HDMI_SCLIN_MSK, ++ RK3228_HDMI_SDAIN_MSK | RK3228_HDMI_SCLIN_MSK), ++ grf + RK3228_GRF_SOC_CON2); ++ ++} ++ ++static const struct dw_hdmi_phy_ops dw_hdmi_rk3228_phy_ops = { ++ .phy_set = rk3228_dw_hdmi_phy_cfg, ++ .setup_hpd = rk3228_dw_hdmi_setup_hpd, ++}; ++ ++static const struct dw_hdmi_plat_data dw_hdmi_rk3228_plat_data = { ++ .phy_force_vendor = true, ++ .phy_ops = &dw_hdmi_rk3228_phy_ops, ++}; ++ ++static int rk3228_hdmi_of_to_plat(struct udevice *dev) ++{ ++ struct rk_hdmi_priv *priv = dev_get_priv(dev); ++ struct dw_hdmi *hdmi = &priv->hdmi; ++ ++ hdmi->i2c_clk_high = 0x71; ++ hdmi->i2c_clk_low = 0x76; ++ ++ rk_hdmi_of_to_plat(dev); ++ ++ hdmi->data = &dw_hdmi_rk3228_plat_data; ++ ++ return 0; ++} ++ ++static int rk3228_hdmi_probe(struct udevice *dev) ++{ ++ struct rk_hdmi_priv *priv = dev_get_priv(dev); ++ int ret; ++ ++ ret = generic_phy_get_by_name(dev, "hdmi", &priv->phy); ++ if (ret) { ++ printf("failed to get hdmi phy\n"); ++ return ret; ++ }; ++ ++ ret = rk_hdmi_probe(dev); ++ if (ret) { ++ printf("failed to probe rk hdmi\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int rk3228_hdmi_remove(struct udevice *dev) ++{ ++ struct rk_hdmi_priv *priv = dev_get_priv(dev); ++ int ret; ++ ++ debug("%s\n", __func__); ++ ++ dw_hdmi_disable(&priv->hdmi); ++ ++ ret = generic_phy_power_off(&priv->phy); ++ if (ret) { ++ printf("failed to on hdmi phy (ret=%d)\n", ret); ++ } ++ ++ return 0; ++ ++} ++ ++static const struct dm_display_ops rk3228_hdmi_ops = { ++ .read_edid = rk_hdmi_read_edid, ++ .enable = rk3228_hdmi_enable, ++}; ++ ++static const struct udevice_id rk3228_hdmi_ids[] = { ++ { .compatible = "rockchip,rk3228-dw-hdmi" }, ++ { } ++}; ++ ++U_BOOT_DRIVER(rk3228_hdmi_rockchip) = { ++ .name = "rk3228_hdmi_rockchip", ++ .id = UCLASS_DISPLAY, ++ .of_match = rk3228_hdmi_ids, ++ .ops = &rk3228_hdmi_ops, ++ .of_to_plat = rk3228_hdmi_of_to_plat, ++ .probe = rk3228_hdmi_probe, ++ .priv_auto = sizeof(struct rk_hdmi_priv), ++ .remove = rk3228_hdmi_remove, ++ .flags = DM_FLAG_OS_PREPARE ++}; +diff --git a/drivers/video/rockchip/Makefile b/drivers/video/rockchip/Makefile +index 8128289cc8..10a98e8c5a 100644 +--- a/drivers/video/rockchip/Makefile ++++ b/drivers/video/rockchip/Makefile +@@ -10,6 +10,7 @@ obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399_vop.o + obj-$(CONFIG_DISPLAY_ROCKCHIP_EDP) += rk_edp.o + obj-$(CONFIG_DISPLAY_ROCKCHIP_LVDS) += rk_lvds.o + obj-hdmi-$(CONFIG_ROCKCHIP_RK3288) += rk3288_hdmi.o ++obj-hdmi-$(CONFIG_ROCKCHIP_RK322X) += rk3228_hdmi.o + obj-hdmi-$(CONFIG_ROCKCHIP_RK3399) += rk3399_hdmi.o + obj-$(CONFIG_DISPLAY_ROCKCHIP_HDMI) += rk_hdmi.o $(obj-hdmi-y) + obj-mipi-$(CONFIG_ROCKCHIP_RK3288) += rk3288_mipi.o +-- +2.34.1 + + diff --git a/patch/u-boot/v2024.01/board_rk322x-box/rk3228-vop-driver.patch b/patch/u-boot/v2024.01/board_rk322x-box/rk3228-vop-driver.patch new file mode 100644 index 0000000000..f9f5fcfdd1 --- /dev/null +++ b/patch/u-boot/v2024.01/board_rk322x-box/rk3228-vop-driver.patch @@ -0,0 +1,141 @@ +From d62c24664878bd4ca198806580a7dc9aea41db1f Mon Sep 17 00:00:00 2001 +From: Paolo Sabatino +Date: Mon, 29 Apr 2024 16:18:05 +0200 +Subject: [PATCH 2/4] rockchip rk3228 VOP driver + +--- + drivers/video/rockchip/rk3228_vop.c | 109 ++++++++++++++++++++++++++++ + 1 file changed, 109 insertions(+) + create mode 100644 drivers/video/rockchip/rk3228_vop.c + +diff --git a/drivers/video/rockchip/rk3228_vop.c b/drivers/video/rockchip/rk3228_vop.c +new file mode 100644 +index 0000000000..f09097709a +--- /dev/null ++++ b/drivers/video/rockchip/rk3228_vop.c +@@ -0,0 +1,109 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (c) 2023 Edgeble AI Technologies Pvt. Ltd. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "rk_vop.h" ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++static void rk3228_set_pin_polarity(struct udevice *dev, ++ enum vop_modes mode, u32 polarity) ++{ ++ struct rk_vop_priv *priv = dev_get_priv(dev); ++ struct rk3288_vop *regs = priv->regs; ++ ++ switch (mode) { ++ case VOP_MODE_HDMI: ++ clrsetbits_le32(®s->dsp_ctrl1, ++ M_RK3399_DSP_HDMI_POL, ++ V_RK3399_DSP_HDMI_POL(polarity)); ++ break; ++ default: ++ debug("%s: unsupported output mode %x\n", __func__, mode); ++ } ++} ++ ++static int rk3228_vop_probe(struct udevice *dev) ++{ ++ /* Before relocation we don't need to do anything */ ++ if (!(gd->flags & GD_FLG_RELOC)) ++ return 0; ++ ++ return rk_vop_probe(dev); ++} ++ ++/** ++ * Remove the device deasserting the dclk, thus disabling the VOP. ++ * This is essential to avoid iommu complaining later during kernel boot ++ * @see https://lore.kernel.org/linux-arm-kernel/20230330131746.1475514-1-jagan@amarulasolutions.com/ ++ */ ++static int rk3228_vop_remove(struct udevice *dev) ++{ ++ struct rk_vop_priv *priv = dev_get_priv(dev); ++ struct rk3288_vop *regs = priv->regs; ++ struct reset_ctl dclk_rst; ++ ++ int ret; ++ ++ debug("%s\n", __func__); ++ ++ /* set to standby */ ++ setbits_le32(®s->sys_ctrl, V_STANDBY_EN(1)); ++ clrsetbits_le32(®s->sys_ctrl, M_ALL_OUT_EN, 0x0); ++ ++ ret = reset_get_by_name(dev, "dclk", &dclk_rst); ++ if (ret) ++ printf("failed to get dclk reset (ret=%d)\n", ret); ++ ++ /* assert and deassert reset */ ++ ret = reset_assert(&dclk_rst); ++ if (ret) ++ printf("failed to assert dclk reset (ret=%d)\n", ret); ++ ++ udelay(20); ++ ++ ret = reset_deassert(&dclk_rst); ++ if (ret) ++ printf("failed to deassert dclk reset (ret=%d)\n", ret); ++ ++ return 0; ++ ++} ++ ++struct rkvop_driverdata rk3228_driverdata = { ++ .dsp_offset = 0x0, ++ .win_offset = 0x0, ++ .features = VOP_FEATURE_OUTPUT_10BIT, ++ .set_pin_polarity = rk3228_set_pin_polarity, ++}; ++ ++static const struct udevice_id rk3228_vop_ids[] = { ++ { ++ .compatible = "rockchip,rk3228-vop", ++ .data = (ulong)&rk3228_driverdata ++ }, ++ { /* sentile */ } ++}; ++ ++static const struct video_ops rk3228_vop_ops = { ++}; ++ ++U_BOOT_DRIVER(rockchip_rk3228_vop) = { ++ .name = "rockchip_rk3228_vop", ++ .id = UCLASS_VIDEO, ++ .of_match = rk3228_vop_ids, ++ .ops = &rk3228_vop_ops, ++ .bind = rk_vop_bind, ++ .probe = rk3228_vop_probe, ++ .remove = rk3228_vop_remove, ++ .priv_auto = sizeof(struct rk_vop_priv), ++ .flags = DM_FLAG_OS_PREPARE ++}; + +diff --git a/drivers/video/rockchip/Makefile b/drivers/video/rockchip/Makefile +index 8128289cc8..0e4cc65fdf 100644 +--- a/drivers/video/rockchip/Makefile ++++ b/drivers/video/rockchip/Makefile +@@ -6,6 +6,7 @@ + ifdef CONFIG_VIDEO_ROCKCHIP + obj-y += rk_vop.o + obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288_vop.o ++obj-$(CONFIG_ROCKCHIP_RK322X) += rk3228_vop.o + obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399_vop.o + obj-$(CONFIG_DISPLAY_ROCKCHIP_EDP) += rk_edp.o + obj-$(CONFIG_DISPLAY_ROCKCHIP_LVDS) += rk_lvds.o +-- +2.34.1 + diff --git a/patch/u-boot/v2024.01/board_rk322x-box/rk322x-box-add-defconfig.patch b/patch/u-boot/v2024.01/board_rk322x-box/rk322x-box-add-defconfig.patch new file mode 100644 index 0000000000..bdc4e67bae --- /dev/null +++ b/patch/u-boot/v2024.01/board_rk322x-box/rk322x-box-add-defconfig.patch @@ -0,0 +1,139 @@ +diff --git a/configs/rk322x-box_defconfig b/configs/rk322x-box_defconfig +new file mode 100644 +index 0000000000..98eec32a53 +--- /dev/null ++++ b/configs/rk322x-box_defconfig +@@ -0,0 +1,133 @@ ++CONFIG_ARM=y ++CONFIG_SKIP_LOWLEVEL_INIT=y ++CONFIG_SPL_SKIP_LOWLEVEL_INIT=y ++CONFIG_TPL_SKIP_LOWLEVEL_INIT=y ++CONFIG_SYS_ARCH_TIMER=y ++CONFIG_ARCH_ROCKCHIP=y ++CONFIG_TEXT_BASE=0x61000000 ++CONFIG_SYS_MALLOC_F_LEN=0x2000 ++CONFIG_NR_DRAM_BANKS=2 ++CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y ++CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x61100000 ++CONFIG_ENV_SIZE=0x8000 ++CONFIG_DEFAULT_DEVICE_TREE="rk322x-box" ++CONFIG_SPL_TEXT_BASE=0x60000000 ++CONFIG_OF_LIBFDT_OVERLAY=y ++CONFIG_DM_RESET=y ++CONFIG_ROCKCHIP_RK322X=y ++CONFIG_SPL_ROCKCHIP_BACK_TO_BROM=y ++CONFIG_ROCKCHIP_EXTERNAL_TPL=y ++CONFIG_SPL_MMC=y ++CONFIG_TARGET_RK322X_BOX=y ++CONFIG_SPL_STACK_R_ADDR=0x60600000 ++CONFIG_DEBUG_UART_BASE=0x11030000 ++CONFIG_DEBUG_UART_CLOCK=24000000 ++CONFIG_SYS_LOAD_ADDR=0x61800800 ++CONFIG_DEBUG_UART=y ++CONFIG_LOCALVERSION="-armbian" ++# CONFIG_LOCALVERSION_AUTO is not set ++# CONFIG_ANDROID_BOOT_IMAGE is not set ++CONFIG_FIT=y ++CONFIG_FIT_VERBOSE=y ++CONFIG_SPL_LOAD_FIT=y ++CONFIG_SD_BOOT=y ++CONFIG_BOOTDELAY=1 ++CONFIG_USE_PREBOOT=y ++CONFIG_DEFAULT_FDT_FILE="rk322x-box.dtb" ++CONFIG_SILENT_CONSOLE=y ++# CONFIG_SPL_SILENT_CONSOLE is not set ++# CONFIG_TPL_SILENT_CONSOLE is not set ++# CONFIG_DISPLAY_CPUINFO is not set ++CONFIG_DISPLAY_BOARDINFO_LATE=y ++CONFIG_BOARD_EARLY_INIT_R=y ++CONFIG_MISC_INIT_R=y ++CONFIG_SPL_MAX_SIZE=0x100000 ++CONFIG_SPL_PAD_TO=0x7f8000 ++CONFIG_SPL_NO_BSS_LIMIT=y ++# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set ++CONFIG_SPL_STACK_R=y ++CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x200 ++CONFIG_SYS_BOOTM_LEN=0x4000000 ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_GPT=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_USB=y ++CONFIG_CMD_ROCKUSB=y ++# CONFIG_CMD_SETEXPR is not set ++# CONFIG_CMD_CLS is not set ++CONFIG_CMD_TIME=y ++# CONFIG_SPL_DOS_PARTITION is not set ++# CONFIG_SPL_PARTITION_UUIDS is not set ++CONFIG_PARTITION_TYPE_GUID=y ++CONFIG_SPL_OF_CONTROL=y ++CONFIG_TPL_OF_CONTROL=y ++CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" ++CONFIG_ENV_IS_IN_EXT4=y ++CONFIG_ENV_EXT4_INTERFACE="mmc" ++CONFIG_ENV_EXT4_DEVICE_AND_PART="0:auto" ++CONFIG_ENV_EXT4_FILE="/boot/boot.env" ++CONFIG_NET_RANDOM_ETHADDR=y ++CONFIG_REGMAP=y ++CONFIG_SPL_REGMAP=y ++CONFIG_TPL_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_SPL_SYSCON=y ++CONFIG_TPL_SYSCON=y ++CONFIG_CLK=y ++CONFIG_SPL_CLK=y ++CONFIG_TPL_CLK=y ++CONFIG_CLK_CCF=y ++CONFIG_CLK_COMPOSITE_CCF=y ++CONFIG_CLK_GPIO=y ++CONFIG_FASTBOOT_BUF_SIZE=0x04000000 ++CONFIG_FASTBOOT_CMD_OEM_FORMAT=y ++CONFIG_ROCKCHIP_GPIO=y ++CONFIG_SYS_I2C_ROCKCHIP=y ++CONFIG_LED=y ++CONFIG_LED_GPIO=y ++CONFIG_MISC=y ++CONFIG_ROCKCHIP_EFUSE=y ++CONFIG_MMC_DW=y ++CONFIG_MMC_DW_ROCKCHIP=y ++CONFIG_ETH_DESIGNWARE=y ++CONFIG_GMAC_ROCKCHIP=y ++CONFIG_PHY_ROCKCHIP_INNO_HDMI=y ++CONFIG_PHY_ROCKCHIP_INNO_USB2=y ++CONFIG_PINCTRL=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_SPL_DM_REGULATOR_FIXED=y ++CONFIG_PWM_ROCKCHIP=y ++CONFIG_RAM=y ++CONFIG_SPL_RAM=y ++CONFIG_TPL_RAM=y ++# CONFIG_RAM_ROCKCHIP is not set ++CONFIG_DEBUG_UART_SHIFT=2 ++CONFIG_SYS_NS16550_MEM32=y ++CONFIG_SYSRESET=y ++CONFIG_TEE=y ++CONFIG_OPTEE=y ++CONFIG_USB=y ++# CONFIG_SPL_DM_USB is not set ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_GENERIC=y ++CONFIG_USB_OHCI_HCD=y ++CONFIG_USB_OHCI_GENERIC=y ++CONFIG_USB_DWC2=y ++CONFIG_USB_KEYBOARD=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_GADGET_PRODUCT_NUM=0x320a ++CONFIG_USB_GADGET_DWC2_OTG=y ++CONFIG_USB_GADGET_DWC2_OTG_PHY=y ++CONFIG_USB_GADGET_VBUS_DRAW=500 ++CONFIG_USB_FUNCTION_MASS_STORAGE=y ++CONFIG_USB_FUNCTION_ROCKUSB=y ++CONFIG_VIDEO=y ++# CONFIG_BACKLIGHT_PWM is not set ++# CONFIG_PANEL is not set ++CONFIG_DISPLAY=y ++CONFIG_VIDEO_ROCKCHIP=y ++CONFIG_DISPLAY_ROCKCHIP_HDMI=y ++CONFIG_FS_BTRFS=y ++CONFIG_TPL_TINY_MEMSET=y ++CONFIG_ERRNO_STR=y ++CONFIG_BOOTM_OPTEE=y diff --git a/patch/u-boot/v2024.01/board_rk322x-box/rk322x-box-add-device-tree-makefile.patch b/patch/u-boot/v2024.01/board_rk322x-box/rk322x-box-add-device-tree-makefile.patch new file mode 100644 index 0000000000..6d3fcd7712 --- /dev/null +++ b/patch/u-boot/v2024.01/board_rk322x-box/rk322x-box-add-device-tree-makefile.patch @@ -0,0 +1,247 @@ +From 9a4db18c4405d06cb3339f55463259259577d1a1 Mon Sep 17 00:00:00 2001 +From: Paolo Sabatino +Date: Thu, 25 Apr 2024 21:24:15 +0200 +Subject: [PATCH] Makefile and basic configuration for rk322x-box + +--- + arch/arm/dts/Makefile | 3 +- + arch/arm/mach-rockchip/rk322x/Kconfig | 5 ++ + board/rockchip/rk322x-box/Kconfig | 15 ++++++ + board/rockchip/rk322x-box/MAINTAINERS | 6 +++ + board/rockchip/rk322x-box/Makefile | 7 +++ + board/rockchip/rk322x-box/README | 72 ++++++++++++++++++++++++++ + board/rockchip/rk322x-box/rk322x-box.c | 21 ++++++++ + include/configs/rk322x-box.h | 27 ++++++++++ + 8 files changed, 155 insertions(+), 1 deletion(-) + create mode 100644 board/rockchip/rk322x-box/Kconfig + create mode 100644 board/rockchip/rk322x-box/MAINTAINERS + create mode 100644 board/rockchip/rk322x-box/Makefile + create mode 100644 board/rockchip/rk322x-box/README + create mode 100644 board/rockchip/rk322x-box/rk322x-box.c + create mode 100644 include/configs/rk322x-box.h + +diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile +index 9d28a485be..c26b05b948 100644 +--- a/arch/arm/dts/Makefile ++++ b/arch/arm/dts/Makefile +@@ -100,7 +100,8 @@ dtb-$(CONFIG_ROCKCHIP_RK3188) += \ + rk3188-radxarock.dtb + + dtb-$(CONFIG_ROCKCHIP_RK322X) += \ +- rk3229-evb.dtb ++ rk3229-evb.dtb \ ++ rk322x-box.dtb + + dtb-$(CONFIG_ROCKCHIP_RK3288) += \ + rk3288-evb.dtb \ +diff --git a/arch/arm/mach-rockchip/rk322x/Kconfig b/arch/arm/mach-rockchip/rk322x/Kconfig +index 9ad1f54055..f5f36b5bf4 100644 +--- a/arch/arm/mach-rockchip/rk322x/Kconfig ++++ b/arch/arm/mach-rockchip/rk322x/Kconfig +@@ -11,6 +11,10 @@ config ROCKCHIP_BOOT_MODE_REG + config ROCKCHIP_STIMER_BASE + default 0x110d0020 + ++config TARGET_RK322X_BOX ++ bool "RK322X-BOX" ++ select BOARD_LATE_INIT ++ + config SYS_SOC + default "rk322x" + +@@ -33,5 +37,6 @@ config TPL_TEXT_BASE + default 0x10081000 + + source "board/rockchip/evb_rk3229/Kconfig" ++source "board/rockchip/rk322x-box/Kconfig" + + endif +diff --git a/board/rockchip/rk322x-box/Kconfig b/board/rockchip/rk322x-box/Kconfig +new file mode 100644 +index 0000000000..db6378f6ba +--- /dev/null ++++ b/board/rockchip/rk322x-box/Kconfig +@@ -0,0 +1,15 @@ ++if TARGET_RK322X_BOX ++ ++config SYS_BOARD ++ default "rk322x-box" ++ ++config SYS_VENDOR ++ default "rockchip" ++ ++config SYS_CONFIG_NAME ++ default "rk322x-box" ++ ++config BOARD_SPECIFIC_OPTIONS # dummy ++ def_bool y ++ ++endif +diff --git a/board/rockchip/rk322x-box/MAINTAINERS b/board/rockchip/rk322x-box/MAINTAINERS +new file mode 100644 +index 0000000000..d8513d319a +--- /dev/null ++++ b/board/rockchip/rk322x-box/MAINTAINERS +@@ -0,0 +1,6 @@ ++XT-MX4VR-V10 ++M: Paolo Sabatino ++S: Out of tree ++F: board/rockchip/rk322x-box ++F: include/configs/rk322x-box.h ++F: configs/rk322x-box_defconfig +diff --git a/board/rockchip/rk322x-box/Makefile b/board/rockchip/rk322x-box/Makefile +new file mode 100644 +index 0000000000..66afec79aa +--- /dev/null ++++ b/board/rockchip/rk322x-box/Makefile +@@ -0,0 +1,7 @@ ++# ++# (C) Copyright 2015 Google, Inc ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++obj-y += rk322x-box.o +diff --git a/board/rockchip/rk322x-box/README b/board/rockchip/rk322x-box/README +new file mode 100644 +index 0000000000..86e7055051 +--- /dev/null ++++ b/board/rockchip/rk322x-box/README +@@ -0,0 +1,72 @@ ++Get the Source and prebuild binary ++================================== ++ ++ > mkdir ~/rk322x-box ++ > cd ~/rk322x-box ++ > git clone git://git.denx.de/u-boot.git ++ > git clone https://github.com/OP-TEE/optee_os.git ++ > git clone https://github.com/rockchip-linux/rkbin.git ++ > git clone https://github.com/rockchip-linux/rkdeveloptool.git ++ ++Compile the OP-TEE ++=============== ++ ++ > cd optee_os ++ > make clean ++ > make CROSS_COMPILE_ta_arm32=arm-none-eabi- PLATFORM=rockchip-rk322x ++ Get tee.bin in this step, copy it to U-Boot root dir: ++ > cp out/arm-plat-rockchip/core/tee-pager.bin ../u-boot/tee.bin ++ ++Compile the U-Boot ++================== ++ ++ > cd ../u-boot ++ > export CROSS_COMPILE=arm-linux-gnueabihf- ++ > export ARCH=arm ++ > make rk322x-box_defconfig ++ > make ++ > make u-boot.itb ++ ++ Get tpl/u-boot-tpl.bin, spl/u-boot-spl.bin and u-boot.itb in this step. ++ ++Compile the rkdeveloptool ++======================= ++ Follow instructions in latest README ++ > cd ../rkflashtool ++ > autoreconf -i ++ > ./configure ++ > make ++ > sudo make install ++ ++ Get rkdeveloptool in you Host in this step. ++ ++Both origin binaries and Tool are ready now, choose either option 1 or ++option 2 to deploy U-Boot. ++ ++Package the image ++================= ++ ++ > cd ../u-boot ++ > tools/mkimage -n rk322x -T rksd -d tpl/u-boot-spl.bin idbloader.img ++ > cat spl/u-boot-spl.bin >> idbloader.img ++ ++ Get idbloader.img in this step. ++ ++Flash the image to eMMC ++======================= ++Power on(or reset with RESET KEY) with MASKROM KEY preesed, and then: ++ > cd .. ++ > rkdeveloptool db rkbin/rk32/rk322x_loader_v1.04.232.bin ++ > rkdeveloptool wl 64 u-boot/idbloader.img ++ > rkdeveloptool wl 0x4000 u-boot/u-boot.itb ++ > rkdeveloptool rd ++ ++Flash the image to SD card ++========================== ++ > dd if=u-boot/idbloader.img of=/dev/sdb seek=64 ++ > dd if=u-boot/u-boot.itb of=/dev/sdb seek=16384 ++ ++You should be able to get U-Boot log message with OP-TEE boot info. ++ ++For more detail, please reference to: ++http://opensource.rock-chips.com/wiki_Boot_option +diff --git a/board/rockchip/rk322x-box/rk322x-box.c b/board/rockchip/rk322x-box/rk322x-box.c +new file mode 100644 +index 0000000000..ff7d8c98fe +--- /dev/null ++++ b/board/rockchip/rk322x-box/rk322x-box.c +@@ -0,0 +1,21 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * (C) Copyright 2017 Rockchip Electronics Co., Ltd ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++int board_early_init_r(void) { ++ ++ /* LED setup */ ++ //if (IS_ENABLED(CONFIG_LED)) ++ //led_default_state(); ++ ++ return 0; ++ ++} ++ +diff --git a/include/configs/rk322x-box.h b/include/configs/rk322x-box.h +new file mode 100644 +index 0000000000..994685dba3 +--- /dev/null ++++ b/include/configs/rk322x-box.h +@@ -0,0 +1,29 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * (C) Copyright 2017 Rockchip Electronics Co., Ltd ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#include ++ ++#define ROCKCHIP_DEVICE_SETTINGS \ ++ "stdin=serial,usbkbd\0" \ ++ "stdout=serial,vidconsole\0" \ ++ "stderr=serial,vidconsole\0" \ ++ "fdt_high=0xffffffff\0" \ ++ "initrd_high=0xffffffff\0" ++ ++#undef BOOT_TARGETS ++#undef CFG_EXTRA_ENV_SETTINGS ++ ++#define BOOT_TARGETS "mmc1 usb mmc0 pxe dhcp" ++ ++#define CFG_EXTRA_ENV_SETTINGS \ ++ "fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \ ++ ENV_MEM_LAYOUT_SETTINGS \ ++ ROCKCHIP_DEVICE_SETTINGS \ ++ "boot_targets=" BOOT_TARGETS "\0" ++ ++#endif +-- +2.34.1 + diff --git a/patch/u-boot/v2024.01/board_rk322x-box/rk322x-box-add-device-tree.patch b/patch/u-boot/v2024.01/board_rk322x-box/rk322x-box-add-device-tree.patch new file mode 100644 index 0000000000..24fb95ae88 --- /dev/null +++ b/patch/u-boot/v2024.01/board_rk322x-box/rk322x-box-add-device-tree.patch @@ -0,0 +1,272 @@ +diff --git a/arch/arm/dts/rk322x-box.dts b/arch/arm/dts/rk322x-box.dts +new file mode 100755 +index 0000000000..91d4afd29c +--- /dev/null ++++ b/arch/arm/dts/rk322x-box.dts +@@ -0,0 +1,266 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR X11 ++/* ++ * (C) Copyright 2019 Paolo Sabatino ++ * ++ * Generic rk322x tv box device tree include file. ++ * ++ * This dtsi covers most of the common hardware included in generic tv boxes around the market. ++ * Include this dtsi in your configuration and make the necessary adjustments there for base support. ++ * ++ */ ++ ++/dts-v1/; ++ ++#include "rk322x.dtsi" ++ ++/ { ++ model = "Generic Rockchip RK322x TV Box board"; ++ compatible = "rockchip,rk322x-box"; ++ ++ chosen { ++ bootph-all; ++ stdout-path = &uart2; ++ u-boot,spl-boot-order = "same-as-spl", &emmc, &sdmmc; ++ }; ++ ++ memory@60000000 { ++ device_type = "memory"; ++ reg = <0x60000000 0x40000000>; ++ }; ++ ++ leds: leds { ++ compatible = "gpio-leds"; ++ ++ /* ++ * Main led is available on all boards. ++ * Default state is honoured only if led_default_state() is called inside ++ * an early init hook function. ++ */ ++ main { ++ label = "working"; ++ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_LOW>; ++ default-state = "on"; ++ }; ++ ++ }; ++ ++ vcc_sys: vcc-sys-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ ++ vcc_phy: vcc-phy-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ regulator-name = "vcc_phy"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vcc_otg_vbus: otg-vbus-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&otg_vbus_drv>; ++ regulator-name = "vcc_otg_vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-boot-on; ++ // regulator-always-on; ++ enable-active-high; ++ vin-supply = <&vcc_sys>; ++ }; ++ ++ vcc_host_vbus: vcc-host-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&host_vbus_drv>; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-name = "vcc_host"; ++ // regulator-always-on; ++ regulator-boot-on; ++ enable-active-high; ++ vin-supply = <&vcc_sys>; ++ }; ++ ++}; ++ ++&gmac { ++ ++ assigned-clocks = <&cru SCLK_MAC_SRC>; ++ assigned-clock-rates = <50000000>; ++ ++ clock_in_out = "output"; ++ phy-supply = <&vcc_phy>; ++ phy-mode = "rmii"; ++ phy-is-integrated; ++ ++ tx_delay = < 0x26 >; // Default is 0x30, but original dts proposes 0x26 ++ rx_delay = < 0x11 >; // Default is 0x10, but original dts proposes 0x11 ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&phy_pins>; ++ ++ status = "okay"; ++ ++}; ++ ++&emmc { ++ ++ bootph-pre-ram; ++ clock-frequency = <50000000>; ++ clock-freq-min-max = <400000 50000000>; ++ broken-cd; ++ cap-mmc-highspeed; ++ mmc-hs200-1_8v; ++ supports-emmc; ++ disable-wp; ++ non-removable; ++ /delete-property/ pinctrl-names; ++ /delete-property/ pinctrl-0; ++ status = "okay"; ++ ++}; ++ ++&sdmmc { ++ ++ bootph-pre-ram; ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ card-detect-delay = <200>; ++ cd-gpios = <&gpio1 RK_PC1 GPIO_ACTIVE_LOW>; ++ disable-wp; ++ num-slots = <1>; ++ supports-sd; ++ ++ status = "okay"; ++ ++}; ++ ++&uart2 { ++ pinctrl-0 = <&uart21_xfer>; ++ pinctrl-names = "default"; ++ bootph-all; ++ status = "okay"; ++}; ++ ++&u2phy0 { ++ status = "okay"; ++}; ++ ++&u2phy0_otg { ++ status = "okay"; ++}; ++ ++&u2phy0_host { ++ status = "okay"; ++}; ++ ++&u2phy1 { ++ status = "okay"; ++}; ++ ++&u2phy1_otg { ++ status = "okay"; ++}; ++ ++&u2phy1_host { ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ vbus-supply = <&vcc_host_vbus>; ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ vbus-supply = <&vcc_host_vbus>; ++ status = "okay"; ++}; ++ ++&usb_host1_ehci { ++ vbus-supply = <&vcc_host_vbus>; ++ status = "okay"; ++}; ++ ++&usb_host1_ohci { ++ vbus-supply = <&vcc_host_vbus>; ++ status = "okay"; ++}; ++ ++&usb_host2_ehci { ++ vbus-supply = <&vcc_host_vbus>; ++ status = "okay"; ++}; ++ ++&usb_host2_ohci { ++ vbus-supply = <&vcc_host_vbus>; ++ status = "okay"; ++}; ++ ++&usb_otg{ ++ vbus-supply = <&vcc_otg_vbus>; ++ status = "okay"; ++}; ++ ++&pinctrl { ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gpio_leds>; ++ ++ gpio { ++ gpio_leds: gpio-leds { ++ rockchip,pins = <3 21 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ }; ++ ++ usb { ++ host_vbus_drv: host-vbus-drv { ++ rockchip,pins = <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ ++ otg_vbus_drv: otg-vbus-drv { ++ rockchip,pins = <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ }; ++ ++ uart2 { ++ uart21_xfer: uart21-xfer { ++ rockchip,pins = <1 RK_PB2 2 &pcfg_pull_up>, ++ <1 RK_PB1 2 &pcfg_pull_none>; ++ }; ++ }; ++ ++}; ++ ++&hdmi { ++ /* ++ * u-boot clk driver is not yet capable to handle parents correctly; ++ * these properties will prevent the video output features if present ++ */ ++ /delete-property/assigned-clocks; ++ /delete-property/assigned-clock-parents; ++ status = "okay"; ++}; ++ ++&hdmi_phy { ++ status = "okay"; ++}; ++ ++&vop { ++ bootph-all; ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; diff --git a/patch/u-boot/v2024.01/board_rk322x-box/u-boot-1002-support-rockchip-gmac-rmii.patch b/patch/u-boot/v2024.01/board_rk322x-box/u-boot-1002-support-rockchip-gmac-rmii.patch new file mode 100644 index 0000000000..ac1794d4ec --- /dev/null +++ b/patch/u-boot/v2024.01/board_rk322x-box/u-boot-1002-support-rockchip-gmac-rmii.patch @@ -0,0 +1,423 @@ +From f860502331f1c1700db222a80cfb9bd0026954cb Mon Sep 17 00:00:00 2001 +From: Paolo Sabatino +Date: Thu, 25 Apr 2024 21:44:55 +0200 +Subject: [PATCH] support gmac rmii phy for rk322x + +--- + arch/arm/dts/rk322x.dtsi | 8 +- + .../include/asm/arch-rockchip/cru_rk322x.h | 1 + + doc/device-tree-bindings/net/phy.txt | 13 ++ + drivers/clk/rockchip/clk_rk322x.c | 14 +- + drivers/net/gmac_rockchip.c | 186 +++++++++++++++++- + 5 files changed, 205 insertions(+), 17 deletions(-) + +diff --git a/arch/arm/dts/rk322x.dtsi b/arch/arm/dts/rk322x.dtsi +index 8eed9e3a92..e3109afa7b 100644 +--- a/arch/arm/dts/rk322x.dtsi ++++ b/arch/arm/dts/rk322x.dtsi +@@ -870,13 +870,13 @@ + clocks = <&cru SCLK_MAC>, <&cru SCLK_MAC_RX>, + <&cru SCLK_MAC_TX>, <&cru SCLK_MAC_REF>, + <&cru SCLK_MAC_REFOUT>, <&cru ACLK_GMAC>, +- <&cru PCLK_GMAC>; ++ <&cru PCLK_GMAC>, <&cru SCLK_MAC_PHY>; + clock-names = "stmmaceth", "mac_clk_rx", + "mac_clk_tx", "clk_mac_ref", + "clk_mac_refout", "aclk_mac", +- "pclk_mac"; +- resets = <&cru SRST_GMAC>; +- reset-names = "stmmaceth"; ++ "pclk_mac", "clk_macphy"; ++ resets = <&cru SRST_GMAC>, <&cru SRST_MACPHY>; ++ reset-names = "stmmaceth", "mac-phy"; + rockchip,grf = <&grf>; + status = "disabled"; + }; +diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk322x.h b/arch/arm/include/asm/arch-rockchip/cru_rk322x.h +index ee12fa831f..cfbc7e92f7 100644 +--- a/arch/arm/include/asm/arch-rockchip/cru_rk322x.h ++++ b/arch/arm/include/asm/arch-rockchip/cru_rk322x.h +@@ -10,6 +10,7 @@ + + #define APLL_HZ (600 * MHz) + #define GPLL_HZ (594 * MHz) ++#define CPLL_HZ (500 * MHz) + + #define CORE_PERI_HZ 150000000 + #define CORE_ACLK_HZ 300000000 +diff --git a/doc/device-tree-bindings/net/phy.txt b/doc/device-tree-bindings/net/phy.txt +index 6599c667b5..ca1a4a8526 100644 +--- a/doc/device-tree-bindings/net/phy.txt ++++ b/doc/device-tree-bindings/net/phy.txt +@@ -8,6 +8,19 @@ Required properties: + + - reg : The ID number for the phy, usually a small integer + ++Optional Properties: ++ ++- compatible: Compatible list, may contain ++ "ethernet-phy-ieee802.3-c22" or "ethernet-phy-ieee802.3-c45" for ++ PHYs that implement IEEE802.3 clause 22 or IEEE802.3 clause 45 ++ specifications. If neither of these are specified, the default is to ++ assume clause 22. ++ ++- phy-is-integrated: If set, indicates that the PHY is integrated into the same ++ physical package as the Ethernet MAC. If needed, muxers should be configured ++ to ensure the integrated PHY is used. The absence of this property indicates ++ the muxers should be configured so that the external PHY is used. ++ + Example: + + ethernet-phy@0 { +diff --git a/drivers/clk/rockchip/clk_rk322x.c b/drivers/clk/rockchip/clk_rk322x.c +index 28cdba7575..f6d2ca6134 100644 +--- a/drivers/clk/rockchip/clk_rk322x.c ++++ b/drivers/clk/rockchip/clk_rk322x.c +@@ -43,6 +43,7 @@ enum { + /* use integer mode*/ + static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 3, 1); + static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1); ++static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 2, 3, 1); + + static int rkclk_set_pll(struct rk322x_cru *cru, enum rk_clk_id clk_id, + const struct pll_div *div) +@@ -92,11 +93,13 @@ static void rkclk_init(struct rk322x_cru *cru) + rk_clrsetreg(&cru->cru_mode_con, + GPLL_MODE_MASK | APLL_MODE_MASK, + GPLL_MODE_SLOW << GPLL_MODE_SHIFT | +- APLL_MODE_SLOW << APLL_MODE_SHIFT); ++ APLL_MODE_SLOW << APLL_MODE_SHIFT | ++ CPLL_MODE_SLOW << CPLL_MODE_SHIFT); + + /* init pll */ + rkclk_set_pll(cru, CLK_ARM, &apll_init_cfg); + rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg); ++ rkclk_set_pll(cru, CLK_CODEC, &cpll_init_cfg); + + /* + * select apll as cpu/core clock pll source and +@@ -169,7 +172,8 @@ static void rkclk_init(struct rk322x_cru *cru) + rk_clrsetreg(&cru->cru_mode_con, + GPLL_MODE_MASK | APLL_MODE_MASK, + GPLL_MODE_NORM << GPLL_MODE_SHIFT | +- APLL_MODE_NORM << APLL_MODE_SHIFT); ++ APLL_MODE_NORM << APLL_MODE_SHIFT | ++ CPLL_MODE_NORM << CPLL_MODE_SHIFT); + } + + /* Get pll rate by id */ +@@ -259,11 +263,10 @@ static ulong rk322x_mac_set_clk(struct rk322x_cru *cru, uint freq) + ulong pll_rate; + u8 div; + +- if ((con >> MAC_PLL_SEL_SHIFT) & MAC_PLL_SEL_MASK) ++ if (con & MAC_PLL_SEL_MASK) + pll_rate = GPLL_HZ; + else +- /* CPLL is not set */ +- return -EPERM; ++ pll_rate = CPLL_HZ; + + div = DIV_ROUND_UP(pll_rate, freq) - 1; + if (div <= 0x1f) +@@ -392,6 +395,7 @@ static ulong rk322x_clk_set_rate(struct clk *clk, ulong rate) + case CLK_DDR: + new_rate = rk322x_ddr_set_clk(priv->cru, rate); + break; ++ case SCLK_MAC_SRC: + case SCLK_MAC: + new_rate = rk322x_mac_set_clk(priv->cru, rate); + break; +diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c +index 04008d2b19..7a917e09cd 100644 +--- a/drivers/net/gmac_rockchip.c ++++ b/drivers/net/gmac_rockchip.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -26,6 +27,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include "designware.h" +@@ -43,21 +46,30 @@ DECLARE_GLOBAL_DATA_PTR; + struct gmac_rockchip_plat { + struct dw_eth_pdata dw_eth_pdata; + bool clock_input; ++ bool integrated_phy; ++ struct reset_ctl phy_reset; + int tx_delay; + int rx_delay; + }; + + struct rk_gmac_ops { + int (*fix_mac_speed)(struct dw_eth_dev *priv); ++ int (*fix_rmii_speed)(struct gmac_rockchip_plat *pdata, ++ struct dw_eth_dev *priv); ++ int (*fix_rgmii_speed)(struct gmac_rockchip_plat *pdata, ++ struct dw_eth_dev *priv); + void (*set_to_rmii)(struct gmac_rockchip_plat *pdata); + void (*set_to_rgmii)(struct gmac_rockchip_plat *pdata); ++ void (*integrated_phy_powerup)(struct gmac_rockchip_plat *pdata); + }; + + + static int gmac_rockchip_of_to_plat(struct udevice *dev) + { + struct gmac_rockchip_plat *pdata = dev_get_plat(dev); ++ struct ofnode_phandle_args args; + const char *string; ++ int ret; + + string = dev_read_string(dev, "clock_in_out"); + if (!strcmp(string, "input")) +@@ -65,6 +77,25 @@ static int gmac_rockchip_of_to_plat(struct udevice *dev) + else + pdata->clock_input = false; + ++ /* If phy-handle property is passed from DT, use it as the PHY */ ++ ret = dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0, &args); ++ if (ret) { ++ debug("Cannot get phy phandle: ret=%d\n", ret); ++ pdata->integrated_phy = dev_read_bool(dev, "phy-is-integrated"); ++ } else { ++ debug("Found phy-handle subnode\n"); ++ pdata->integrated_phy = ofnode_read_bool(args.node, ++ "phy-is-integrated"); ++ } ++ ++ if (pdata->integrated_phy) { ++ ret = reset_get_by_name(dev, "mac-phy", &pdata->phy_reset); ++ if (ret) { ++ debug("No PHY reset control found: ret=%d\n", ret); ++ return ret; ++ } ++ } ++ + /* Check the new naming-style first... */ + pdata->tx_delay = dev_read_u32_default(dev, "tx_delay", -ENOENT); + pdata->rx_delay = dev_read_u32_default(dev, "rx_delay", -ENOENT); +@@ -119,7 +150,43 @@ static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int rk3228_gmac_fix_rmii_speed(struct gmac_rockchip_plat *pdata, ++ struct dw_eth_dev *priv) ++{ ++ struct rk322x_grf *grf; ++ int clk; ++ enum { ++ RK3228_GMAC_RMII_CLK_MASK = BIT(7), ++ RK3228_GMAC_RMII_CLK_2_5M = 0, ++ RK3228_GMAC_RMII_CLK_25M = BIT(7), ++ ++ RK3228_GMAC_RMII_SPEED_MASK = BIT(2), ++ RK3228_GMAC_RMII_SPEED_10 = 0, ++ RK3228_GMAC_RMII_SPEED_100 = BIT(2), ++ }; ++ ++ switch (priv->phydev->speed) { ++ case 10: ++ clk = RK3228_GMAC_RMII_CLK_2_5M | RK3228_GMAC_RMII_SPEED_10; ++ break; ++ case 100: ++ clk = RK3228_GMAC_RMII_CLK_25M | RK3228_GMAC_RMII_SPEED_100; ++ break; ++ default: ++ debug("Unknown phy speed: %d\n", priv->phydev->speed); ++ return -EINVAL; ++ } ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ rk_clrsetreg(&grf->mac_con[1], ++ RK3228_GMAC_RMII_CLK_MASK | RK3228_GMAC_RMII_SPEED_MASK, ++ clk); ++ ++ return 0; ++} ++ ++static int rk3228_gmac_fix_rgmii_speed(struct gmac_rockchip_plat *pdata, ++ struct dw_eth_dev *priv) + { + struct rk322x_grf *grf; + int clk; +@@ -361,6 +428,28 @@ static void px30_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata) + PX30_GMAC_PHY_INTF_SEL_RMII); + } + ++static void rk3228_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata) ++{ ++ struct rk322x_grf *grf; ++ enum { ++ RK3228_GRF_CON_RMII_MODE_MASK = BIT(11), ++ RK3228_GRF_CON_RMII_MODE_SEL = BIT(11), ++ RK3228_RMII_MODE_MASK = BIT(10), ++ RK3228_RMII_MODE_SEL = BIT(10), ++ RK3228_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4), ++ RK3228_GMAC_PHY_INTF_SEL_RMII = BIT(6), ++ }; ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ rk_clrsetreg(&grf->mac_con[1], ++ RK3228_GRF_CON_RMII_MODE_MASK | ++ RK3228_RMII_MODE_MASK | ++ RK3228_GMAC_PHY_INTF_SEL_MASK, ++ RK3228_GRF_CON_RMII_MODE_SEL | ++ RK3228_RMII_MODE_SEL | ++ RK3228_GMAC_PHY_INTF_SEL_RMII); ++} ++ + static void rk3228_gmac_set_to_rgmii(struct gmac_rockchip_plat *pdata) + { + struct rk322x_grf *grf; +@@ -554,6 +643,66 @@ static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata) + RV1108_GMAC_PHY_INTF_SEL_RMII); + } + ++static void rk3228_gmac_integrated_phy_powerup(struct gmac_rockchip_plat *pdata) ++{ ++ struct rk322x_grf *grf; ++ enum { ++ RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY_MASK = BIT(15), ++ RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY = BIT(15), ++ }; ++ enum { ++ RK3228_MACPHY_CFG_CLK_50M_MASK = BIT(14), ++ RK3228_MACPHY_CFG_CLK_50M = BIT(14), ++ ++ RK3228_MACPHY_RMII_MODE_MASK = GENMASK(7, 6), ++ RK3228_MACPHY_RMII_MODE = BIT(6), ++ ++ RK3228_MACPHY_ENABLE_MASK = BIT(0), ++ RK3228_MACPHY_DISENABLE = 0, ++ RK3228_MACPHY_ENABLE = BIT(0), ++ }; ++ enum { ++ RK3228_RK_GRF_CON2_MACPHY_ID_MASK = GENMASK(6, 0), ++ RK3228_RK_GRF_CON2_MACPHY_ID = 0x1234, ++ }; ++ enum { ++ RK3228_RK_GRF_CON3_MACPHY_ID_MASK = GENMASK(5, 0), ++ RK3228_RK_GRF_CON3_MACPHY_ID = 0x35, ++ }; ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ rk_clrsetreg(&grf->con_iomux, ++ RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY_MASK, ++ RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY); ++ ++ rk_clrsetreg(&grf->macphy_con[2], ++ RK3228_RK_GRF_CON2_MACPHY_ID_MASK, ++ RK3228_RK_GRF_CON2_MACPHY_ID); ++ ++ rk_clrsetreg(&grf->macphy_con[3], ++ RK3228_RK_GRF_CON3_MACPHY_ID_MASK, ++ RK3228_RK_GRF_CON3_MACPHY_ID); ++ ++ /* disabled before trying to reset it */ ++ rk_clrsetreg(&grf->macphy_con[0], ++ RK3228_MACPHY_CFG_CLK_50M_MASK | ++ RK3228_MACPHY_RMII_MODE_MASK | ++ RK3228_MACPHY_ENABLE_MASK, ++ RK3228_MACPHY_CFG_CLK_50M | ++ RK3228_MACPHY_RMII_MODE | ++ RK3228_MACPHY_DISENABLE); ++ ++ reset_assert(&pdata->phy_reset); ++ udelay(10); ++ reset_deassert(&pdata->phy_reset); ++ udelay(10); ++ ++ rk_clrsetreg(&grf->macphy_con[0], ++ RK3228_MACPHY_ENABLE_MASK, ++ RK3228_MACPHY_ENABLE); ++ udelay(30 * 1000); ++} ++ + static int gmac_rockchip_probe(struct udevice *dev) + { + struct gmac_rockchip_plat *pdata = dev_get_plat(dev); +@@ -573,6 +722,9 @@ static int gmac_rockchip_probe(struct udevice *dev) + if (ret) + return ret; + ++ if (pdata->integrated_phy && ops->integrated_phy_powerup) ++ ops->integrated_phy_powerup(pdata); ++ + switch (eth_pdata->phy_interface) { + case PHY_INTERFACE_MODE_RGMII: + /* Set to RGMII mode */ +@@ -656,7 +808,7 @@ static int gmac_rockchip_probe(struct udevice *dev) + break; + + default: +- debug("NO interface defined!\n"); ++ debug("%s: no interface defined!\n", __func__); + return -ENXIO; + } + +@@ -665,18 +817,33 @@ static int gmac_rockchip_probe(struct udevice *dev) + + static int gmac_rockchip_eth_start(struct udevice *dev) + { +- struct eth_pdata *pdata = dev_get_plat(dev); ++ struct eth_pdata *eth_pdata = dev_get_plat(dev); + struct dw_eth_dev *priv = dev_get_priv(dev); + struct rk_gmac_ops *ops = + (struct rk_gmac_ops *)dev_get_driver_data(dev); ++ struct gmac_rockchip_plat *pdata = dev_get_plat(dev); + int ret; + +- ret = designware_eth_init(priv, pdata->enetaddr); +- if (ret) +- return ret; +- ret = ops->fix_mac_speed(priv); ++ ret = designware_eth_init(priv, eth_pdata->enetaddr); + if (ret) + return ret; ++ ++ switch (eth_pdata->phy_interface) { ++ case PHY_INTERFACE_MODE_RGMII: ++ ret = ops->fix_rgmii_speed(pdata, priv); ++ if (ret) ++ return ret; ++ break; ++ case PHY_INTERFACE_MODE_RMII: ++ ret = ops->fix_rmii_speed(pdata, priv); ++ if (ret) ++ return ret; ++ break; ++ default: ++ debug("%s: no interface defined!\n", __func__); ++ return -ENXIO; ++ } ++ + ret = designware_eth_enable(priv); + if (ret) + return ret; +@@ -699,8 +866,11 @@ const struct rk_gmac_ops px30_gmac_ops = { + }; + + const struct rk_gmac_ops rk3228_gmac_ops = { +- .fix_mac_speed = rk3228_gmac_fix_mac_speed, ++ .fix_rmii_speed = rk3228_gmac_fix_rmii_speed, ++ .fix_rgmii_speed = rk3228_gmac_fix_rgmii_speed, ++ .set_to_rmii = rk3228_gmac_set_to_rmii, + .set_to_rgmii = rk3228_gmac_set_to_rgmii, ++ .integrated_phy_powerup = rk3228_gmac_integrated_phy_powerup, + }; + + const struct rk_gmac_ops rk3288_gmac_ops = { +-- +2.34.1 + diff --git a/patch/u-boot/v2024.01/board_rk322x-box/u-boot-1005-support-rockchip-tee-binary.patch b/patch/u-boot/v2024.01/board_rk322x-box/u-boot-1005-support-rockchip-tee-binary.patch new file mode 100644 index 0000000000..6c7ca96c1d --- /dev/null +++ b/patch/u-boot/v2024.01/board_rk322x-box/u-boot-1005-support-rockchip-tee-binary.patch @@ -0,0 +1,24 @@ +From 0add0274f4b7c1fbcb2c2795c3e6f5ce00e484c8 Mon Sep 17 00:00:00 2001 +From: Paolo Sabatino +Date: Thu, 25 Apr 2024 21:48:17 +0200 +Subject: [PATCH] Set register r1 to CONFIG_SYS_TEXT_BASE to support rockchip + proprietary OP-TEE binaries + +--- + common/spl/spl_optee.S | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/common/spl/spl_optee.S b/common/spl/spl_optee.S +index a269904d38..a3891f0071 100644 +--- a/common/spl/spl_optee.S ++++ b/common/spl/spl_optee.S +@@ -8,5 +8,6 @@ + + ENTRY(spl_optee_entry) + ldr lr, =CONFIG_TEXT_BASE ++ ldr r1, =CONFIG_TEXT_BASE + mov pc, r3 + ENDPROC(spl_optee_entry) +-- +2.34.1 + diff --git a/patch/u-boot/v2024.01/board_rk322x-box/u-boot-1006-usbphy-otg-ehci-support.patch b/patch/u-boot/v2024.01/board_rk322x-box/u-boot-1006-usbphy-otg-ehci-support.patch new file mode 100644 index 0000000000..61ae2deead --- /dev/null +++ b/patch/u-boot/v2024.01/board_rk322x-box/u-boot-1006-usbphy-otg-ehci-support.patch @@ -0,0 +1,230 @@ +From 62b9c5ea4a5d41f8adf122797958b202d566f735 Mon Sep 17 00:00:00 2001 +From: Paolo Sabatino +Date: Thu, 25 Apr 2024 21:59:34 +0200 +Subject: [PATCH] OTG/EHCI USB support for rk322x + +--- + arch/arm/mach-rockchip/rk322x/syscon_rk322x.c | 3 + + drivers/clk/rockchip/clk_rk322x.c | 121 ++++++++++++++++++ + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 49 +++++++ + 3 files changed, 173 insertions(+) + +diff --git a/arch/arm/mach-rockchip/rk322x/syscon_rk322x.c b/arch/arm/mach-rockchip/rk322x/syscon_rk322x.c +index 0d9dca8173..37c040950b 100644 +--- a/arch/arm/mach-rockchip/rk322x/syscon_rk322x.c ++++ b/arch/arm/mach-rockchip/rk322x/syscon_rk322x.c +@@ -17,5 +17,8 @@ static const struct udevice_id rk322x_syscon_ids[] = { + U_BOOT_DRIVER(syscon_rk322x) = { + .name = "rk322x_syscon", + .id = UCLASS_SYSCON, ++#if !CONFIG_IS_ENABLED(OF_PLATDATA) ++ .bind = dm_scan_fdt_dev, ++#endif + .of_match = rk322x_syscon_ids, + }; +diff --git a/drivers/clk/rockchip/clk_rk322x.c b/drivers/clk/rockchip/clk_rk322x.c +index f6d2ca6134..44b5778589 100644 +--- a/drivers/clk/rockchip/clk_rk322x.c ++++ b/drivers/clk/rockchip/clk_rk322x.c +@@ -474,10 +474,131 @@ static int rk322x_clk_set_parent(struct clk *clk, struct clk *parent) + return -ENOENT; + } + ++static int rk322x_clk_enable(struct clk *clk) ++{ ++ ++ struct rk322x_clk_priv *priv = dev_get_priv(clk->dev); ++ struct rk322x_cru *cru = priv->cru; ++ ++ switch (clk->id) { ++ case SCLK_OTGPHY0: ++ rk_clrreg(&cru->cru_clkgate_con[1], BIT(5)); ++ break; ++ case SCLK_OTGPHY1: ++ rk_clrreg(&cru->cru_clkgate_con[1], BIT(6)); ++ break; ++ case HCLK_OTG: ++ rk_clrreg(&cru->cru_clkgate_con[11], BIT(12)); ++ break; ++ case HCLK_HOST0: ++ rk_clrreg(&cru->cru_clkgate_con[11], BIT(6)); ++ break; ++ case HCLK_HOST1: ++ rk_clrreg(&cru->cru_clkgate_con[11], BIT(8)); ++ break; ++ case HCLK_HOST2: ++ rk_clrreg(&cru->cru_clkgate_con[11], BIT(10)); ++ break; ++ case SCLK_MAC: ++ rk_clrreg(&cru->cru_clkgate_con[1], BIT(6)); ++ break; ++ case SCLK_MAC_SRC: ++ rk_clrreg(&cru->cru_clkgate_con[1], BIT(7)); ++ break; ++ case SCLK_MAC_RX: ++ rk_clrreg(&cru->cru_clkgate_con[5], BIT(5)); ++ break; ++ case SCLK_MAC_TX: ++ rk_clrreg(&cru->cru_clkgate_con[5], BIT(6)); ++ break; ++ case SCLK_MAC_REF: ++ rk_clrreg(&cru->cru_clkgate_con[5], BIT(3)); ++ break; ++ case SCLK_MAC_REFOUT: ++ rk_clrreg(&cru->cru_clkgate_con[5], BIT(4)); ++ break; ++ case SCLK_MAC_PHY: ++ rk_clrreg(&cru->cru_clkgate_con[5], BIT(7)); ++ break; ++ case ACLK_GMAC: ++ rk_clrreg(&cru->cru_clkgate_con[11], BIT(4)); ++ break; ++ case PCLK_GMAC: ++ rk_clrreg(&cru->cru_clkgate_con[11], BIT(5)); ++ break; ++ default: ++ log_debug("%s: unsupported clk %ld\n", __func__, clk->id); ++ return -ENOENT; ++ } ++ ++ return 0; ++ ++} ++ ++static int rk322x_clk_disable(struct clk *clk) ++{ ++ ++ struct rk322x_clk_priv *priv = dev_get_priv(clk->dev); ++ struct rk322x_cru *cru = priv->cru; ++ ++ switch (clk->id) { ++ case SCLK_OTGPHY0: ++ rk_setreg(&cru->cru_clkgate_con[1], BIT(5)); ++ break; ++ case SCLK_OTGPHY1: ++ rk_setreg(&cru->cru_clkgate_con[1], BIT(6)); ++ break; ++ case HCLK_OTG: ++ rk_setreg(&cru->cru_clkgate_con[11], BIT(12)); ++ break; ++ case HCLK_HOST0: ++ rk_setreg(&cru->cru_clkgate_con[11], BIT(6)); ++ break; ++ case HCLK_HOST1: ++ rk_setreg(&cru->cru_clkgate_con[11], BIT(8)); ++ break; ++ case HCLK_HOST2: ++ rk_setreg(&cru->cru_clkgate_con[11], BIT(10)); ++ break; ++ case SCLK_MAC_SRC: ++ rk_setreg(&cru->cru_clkgate_con[1], BIT(7)); ++ break; ++ case SCLK_MAC_RX: ++ rk_setreg(&cru->cru_clkgate_con[5], BIT(5)); ++ break; ++ case SCLK_MAC_TX: ++ rk_setreg(&cru->cru_clkgate_con[5], BIT(6)); ++ break; ++ case SCLK_MAC_REF: ++ rk_setreg(&cru->cru_clkgate_con[5], BIT(3)); ++ break; ++ case SCLK_MAC_REFOUT: ++ rk_setreg(&cru->cru_clkgate_con[5], BIT(4)); ++ break; ++ case SCLK_MAC_PHY: ++ rk_setreg(&cru->cru_clkgate_con[5], BIT(7)); ++ break; ++ case ACLK_GMAC: ++ rk_setreg(&cru->cru_clkgate_con[11], BIT(4)); ++ break; ++ case PCLK_GMAC: ++ rk_setreg(&cru->cru_clkgate_con[11], BIT(5)); ++ break; ++ default: ++ log_debug("%s: unsupported clk %ld\n", __func__, clk->id); ++ return -ENOENT; ++ } ++ ++ return 0; ++ ++} ++ + static struct clk_ops rk322x_clk_ops = { + .get_rate = rk322x_clk_get_rate, + .set_rate = rk322x_clk_set_rate, + .set_parent = rk322x_clk_set_parent, ++ .enable = rk322x_clk_enable, ++ .disable = rk322x_clk_disable + }; + + static int rk322x_clk_of_to_plat(struct udevice *dev) +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +index 70e61eccb7..c905ccb8f9 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -375,6 +375,51 @@ static const struct rockchip_usb2phy_cfg rk3328_usb2phy_cfgs[] = { + { /* sentinel */ } + }; + ++static const struct rockchip_usb2phy_cfg rk3228_phy_cfgs[] = { ++ { ++ .reg = 0x760, ++ .clkout_ctl = { 0x0768, 4, 4, 1, 0 }, ++ .port_cfgs = { ++ [USB2PHY_PORT_OTG] = { ++ .phy_sus = { 0x0760, 15, 0, 0, 0x1d1 }, ++ .bvalid_det_en = { 0x0680, 3, 3, 0, 1 }, ++ .bvalid_det_st = { 0x0690, 3, 3, 0, 1 }, ++ .bvalid_det_clr = { 0x06a0, 3, 3, 0, 1 }, ++ .ls_det_en = { 0x0680, 2, 2, 0, 1 }, ++ .ls_det_st = { 0x0690, 2, 2, 0, 1 }, ++ .ls_det_clr = { 0x06a0, 2, 2, 0, 1 }, ++ .utmi_bvalid = { 0x0480, 4, 4, 0, 1 }, ++ .utmi_ls = { 0x0480, 3, 2, 0, 1 }, ++ }, ++ [USB2PHY_PORT_HOST] = { ++ .phy_sus = { 0x0764, 15, 0, 0, 0x1d1 }, ++ .ls_det_en = { 0x0680, 4, 4, 0, 1 }, ++ .ls_det_st = { 0x0690, 4, 4, 0, 1 }, ++ .ls_det_clr = { 0x06a0, 4, 4, 0, 1 } ++ } ++ }, ++ }, ++ { ++ .reg = 0x800, ++ .clkout_ctl = { 0x0808, 4, 4, 1, 0 }, ++ .port_cfgs = { ++ [USB2PHY_PORT_OTG] = { ++ .phy_sus = { 0x800, 15, 0, 0, 0x1d1 }, ++ .ls_det_en = { 0x0684, 0, 0, 0, 1 }, ++ .ls_det_st = { 0x0694, 0, 0, 0, 1 }, ++ .ls_det_clr = { 0x06a4, 0, 0, 0, 1 } ++ }, ++ [USB2PHY_PORT_HOST] = { ++ .phy_sus = { 0x804, 15, 0, 0, 0x1d1 }, ++ .ls_det_en = { 0x0684, 1, 1, 0, 1 }, ++ .ls_det_st = { 0x0694, 1, 1, 0, 1 }, ++ .ls_det_clr = { 0x06a4, 1, 1, 0, 1 } ++ } ++ }, ++ }, ++ { /* sentinel */ } ++}; ++ + static const struct rockchip_usb2phy_cfg rk3399_usb2phy_cfgs[] = { + { + .reg = 0xe450, +@@ -532,6 +577,10 @@ static const struct udevice_id rockchip_usb2phy_ids[] = { + .compatible = "rockchip,rk3328-usb2phy", + .data = (ulong)&rk3328_usb2phy_cfgs, + }, ++ { ++ .compatible = "rockchip,rk3228-usb2phy", ++ .data = (ulong)&rk3228_phy_cfgs, ++ }, + { + .compatible = "rockchip,rk3399-usb2phy", + .data = (ulong)&rk3399_usb2phy_cfgs, +-- +2.34.1 + diff --git a/patch/u-boot/v2024.01/board_rk3318-box/driver-rockchip-vop-cleanup.patch b/patch/u-boot/v2024.01/board_rk3318-box/driver-rockchip-vop-cleanup.patch new file mode 100644 index 0000000000..98e7393287 --- /dev/null +++ b/patch/u-boot/v2024.01/board_rk3318-box/driver-rockchip-vop-cleanup.patch @@ -0,0 +1,242 @@ +From dc0ea12fdeb6843839ee1a182166bc2506fa0ec7 Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Sun, 19 Feb 2023 00:47:19 +0530 +Subject: [PATCH] video: rockchip: vop: Simplify rkvop_enable + +Signed-off-by: Jagan Teki +--- + drivers/video/rockchip/rk_vop.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/video/rockchip/rk_vop.c b/drivers/video/rockchip/rk_vop.c +index bc98ab6875a..7e8ce9b29aa 100644 +--- a/drivers/video/rockchip/rk_vop.c ++++ b/drivers/video/rockchip/rk_vop.c +@@ -39,11 +39,13 @@ enum vop_pol { + DCLK_INVERT = 3 + }; + +-static void rkvop_enable(struct udevice *dev, struct rk3288_vop *regs, ulong fbbase, ++static void rkvop_enable(struct udevice *dev, ulong fbbase, + int fb_bits_per_pixel, + const struct display_timing *edid, + struct reset_ctl *dclk_rst) + { ++ struct rk_vop_priv *priv = dev_get_priv(dev); ++ struct rk3288_vop *regs = priv->regs; + u32 lb_mode; + u32 rgb_mode; + u32 hactive = edid->hactive.typ; +@@ -243,9 +245,7 @@ static void rkvop_mode_set(struct udevice *dev, + static int rk_display_init(struct udevice *dev, ulong fbbase, ofnode ep_node) + { + struct video_priv *uc_priv = dev_get_uclass_priv(dev); +- struct rk_vop_priv *priv = dev_get_priv(dev); + int vop_id, remote_vop_id; +- struct rk3288_vop *regs = priv->regs; + struct display_timing timing; + struct udevice *disp; + int ret; +@@ -379,7 +379,7 @@ static int rk_display_init(struct udevice *dev, ulong fbbase, ofnode ep_node) + return ret; + } + +- rkvop_enable(dev, regs, fbbase, 1 << l2bpp, &timing, &dclk_rst); ++ rkvop_enable(dev, fbbase, 1 << l2bpp, &timing, &dclk_rst); + + ret = display_enable(disp, 1 << l2bpp, &timing); + if (ret) +From a9b623a13c0c7ba8867875c0267deabd0fed733c Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Sun, 19 Feb 2023 00:53:06 +0530 +Subject: [PATCH] video: rockchip: vop: Add win offset support + +Signed-off-by: Jagan Teki +--- + drivers/video/rockchip/rk_vop.c | 23 ++++++++++++++--------- + drivers/video/rockchip/rk_vop.h | 2 ++ + 2 files changed, 16 insertions(+), 9 deletions(-) + +diff --git a/drivers/video/rockchip/rk_vop.c b/drivers/video/rockchip/rk_vop.c +index 7e8ce9b29aa..757fe7a4338 100644 +--- a/drivers/video/rockchip/rk_vop.c ++++ b/drivers/video/rockchip/rk_vop.c +@@ -46,6 +46,7 @@ static void rkvop_enable(struct udevice *dev, ulong fbbase, + { + struct rk_vop_priv *priv = dev_get_priv(dev); + struct rk3288_vop *regs = priv->regs; ++ struct rk3288_vop *win_regs = priv->regs + priv->win_offset; + u32 lb_mode; + u32 rgb_mode; + u32 hactive = edid->hactive.typ; +@@ -53,32 +54,33 @@ static void rkvop_enable(struct udevice *dev, ulong fbbase, + int ret; + + writel(V_ACT_WIDTH(hactive - 1) | V_ACT_HEIGHT(vactive - 1), +- ®s->win0_act_info); ++ &win_regs->win0_act_info); + + writel(V_DSP_XST(edid->hsync_len.typ + edid->hback_porch.typ) | + V_DSP_YST(edid->vsync_len.typ + edid->vback_porch.typ), +- ®s->win0_dsp_st); ++ &win_regs->win0_dsp_st); + + writel(V_DSP_WIDTH(hactive - 1) | + V_DSP_HEIGHT(vactive - 1), +- ®s->win0_dsp_info); ++ &win_regs->win0_dsp_info); + +- clrsetbits_le32(®s->win0_color_key, M_WIN0_KEY_EN | M_WIN0_KEY_COLOR, ++ clrsetbits_le32(&win_regs->win0_color_key, ++ M_WIN0_KEY_EN | M_WIN0_KEY_COLOR, + V_WIN0_KEY_EN(0) | V_WIN0_KEY_COLOR(0)); + + switch (fb_bits_per_pixel) { + case 16: + rgb_mode = RGB565; +- writel(V_RGB565_VIRWIDTH(hactive), ®s->win0_vir); ++ writel(V_RGB565_VIRWIDTH(hactive), &win_regs->win0_vir); + break; + case 24: + rgb_mode = RGB888; +- writel(V_RGB888_VIRWIDTH(hactive), ®s->win0_vir); ++ writel(V_RGB888_VIRWIDTH(hactive), &win_regs->win0_vir); + break; + case 32: + default: + rgb_mode = ARGB8888; +- writel(V_ARGB888_VIRWIDTH(hactive), ®s->win0_vir); ++ writel(V_ARGB888_VIRWIDTH(hactive), &win_regs->win0_vir); + break; + } + +@@ -91,12 +93,12 @@ static void rkvop_enable(struct udevice *dev, ulong fbbase, + else + lb_mode = LB_RGB_1280X8; + +- clrsetbits_le32(®s->win0_ctrl0, ++ clrsetbits_le32(&win_regs->win0_ctrl0, + M_WIN0_LB_MODE | M_WIN0_DATA_FMT | M_WIN0_EN, + V_WIN0_LB_MODE(lb_mode) | V_WIN0_DATA_FMT(rgb_mode) | + V_WIN0_EN(1)); + +- writel(fbbase, ®s->win0_yrgb_mst); ++ writel(fbbase, &win_regs->win0_yrgb_mst); + writel(0x01, ®s->reg_cfg_done); /* enable reg config */ + + ret = reset_assert(dclk_rst); +@@ -414,6 +416,8 @@ int rk_vop_probe(struct udevice *dev) + { + struct video_uc_plat *plat = dev_get_uclass_plat(dev); + struct rk_vop_priv *priv = dev_get_priv(dev); ++ struct rkvop_driverdata *ops = ++ (struct rkvop_driverdata *)dev_get_driver_data(dev); + int ret = 0; + ofnode port, node; + struct reset_ctl ahb_rst; +@@ -448,6 +453,8 @@ int rk_vop_probe(struct udevice *dev) + #endif + + priv->regs = dev_read_addr_ptr(dev); ++ priv->win_offset = ops->win_offset; ++ priv->dsp_offset = ops->dsp_offset; + + /* + * Try all the ports until we find one that works. In practice this +diff --git a/drivers/video/rockchip/rk_vop.h b/drivers/video/rockchip/rk_vop.h +index 0528fb23f59..909f5602e53 100644 +--- a/drivers/video/rockchip/rk_vop.h ++++ b/drivers/video/rockchip/rk_vop.h +@@ -11,6 +11,7 @@ + struct rk_vop_priv { + void *grf; + void *regs; ++ int win_offset; + }; + + enum vop_features { +@@ -18,6 +19,7 @@ enum vop_features { + }; + + struct rkvop_driverdata { ++ int win_offset; + /* configuration */ + u32 features; + /* block-specific setters/getters */ +From cd5115979e60d360e546ea683e77209e2011e752 Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Mon, 20 Feb 2023 00:52:32 +0530 +Subject: [PATCH] video: rockchip: vop: Add dsp offset support + +Signed-off-by: Jagan Teki +--- + drivers/video/rockchip/rk_vop.c | 14 ++++++++------ + drivers/video/rockchip/rk_vop.h | 2 ++ + 2 files changed, 10 insertions(+), 6 deletions(-) + +diff --git a/drivers/video/rockchip/rk_vop.c b/drivers/video/rockchip/rk_vop.c +index 757fe7a4338..f7c6b4cc25a 100644 +--- a/drivers/video/rockchip/rk_vop.c ++++ b/drivers/video/rockchip/rk_vop.c +@@ -166,6 +166,7 @@ static void rkvop_mode_set(struct udevice *dev, + { + struct rk_vop_priv *priv = dev_get_priv(dev); + struct rk3288_vop *regs = priv->regs; ++ struct rk3288_vop *dsp_regs = priv->regs + priv->dsp_offset; + struct rkvop_driverdata *data = + (struct rkvop_driverdata *)dev_get_driver_data(dev); + +@@ -199,27 +200,27 @@ static void rkvop_mode_set(struct udevice *dev, + + writel(V_HSYNC(hsync_len) | + V_HORPRD(hsync_len + hback_porch + hactive + hfront_porch), +- ®s->dsp_htotal_hs_end); ++ &dsp_regs->dsp_htotal_hs_end); + + writel(V_HEAP(hsync_len + hback_porch + hactive) | + V_HASP(hsync_len + hback_porch), +- ®s->dsp_hact_st_end); ++ &dsp_regs->dsp_hact_st_end); + + writel(V_VSYNC(vsync_len) | + V_VERPRD(vsync_len + vback_porch + vactive + vfront_porch), +- ®s->dsp_vtotal_vs_end); ++ &dsp_regs->dsp_vtotal_vs_end); + + writel(V_VAEP(vsync_len + vback_porch + vactive)| + V_VASP(vsync_len + vback_porch), +- ®s->dsp_vact_st_end); ++ &dsp_regs->dsp_vact_st_end); + + writel(V_HEAP(hsync_len + hback_porch + hactive) | + V_HASP(hsync_len + hback_porch), +- ®s->post_dsp_hact_info); ++ &dsp_regs->post_dsp_hact_info); + + writel(V_VAEP(vsync_len + vback_porch + vactive)| + V_VASP(vsync_len + vback_porch), +- ®s->post_dsp_vact_info); ++ &dsp_regs->post_dsp_vact_info); + + writel(0x01, ®s->reg_cfg_done); /* enable reg config */ + } +diff --git a/drivers/video/rockchip/rk_vop.h b/drivers/video/rockchip/rk_vop.h +index 909f5602e53..7d2581d6a78 100644 +--- a/drivers/video/rockchip/rk_vop.h ++++ b/drivers/video/rockchip/rk_vop.h +@@ -11,6 +11,7 @@ + struct rk_vop_priv { + void *grf; + void *regs; ++ int dsp_offset; + int win_offset; + }; + +@@ -19,6 +20,7 @@ enum vop_features { + }; + + struct rkvop_driverdata { ++ int dsp_offset; + int win_offset; + /* configuration */ + u32 features; diff --git a/patch/u-boot/v2024.01/board_rk3318-box/general-hdmi-01-vendor-phy-handling.patch b/patch/u-boot/v2024.01/board_rk3318-box/general-hdmi-01-vendor-phy-handling.patch new file mode 100644 index 0000000000..78122ce819 --- /dev/null +++ b/patch/u-boot/v2024.01/board_rk3318-box/general-hdmi-01-vendor-phy-handling.patch @@ -0,0 +1,239 @@ +From db428dbc58ba2788fb13d4bf1985f0540fd7f4b3 Mon Sep 17 00:00:00 2001 +From: Paolo Sabatino +Date: Tue, 30 Apr 2024 22:09:57 +0200 +Subject: [PATCH] video: dw_hdmi: Add Vendor PHY handling + +original work by Jagan Teki +--- + drivers/video/dw_hdmi.c | 46 +++++++++++++++++++++++++++- + drivers/video/meson/meson_dw_hdmi.c | 11 ++++++- + drivers/video/rockchip/rk3399_hdmi.c | 8 ++++- + drivers/video/rockchip/rk_hdmi.c | 2 +- + drivers/video/rockchip/rk_hdmi.h | 3 ++ + drivers/video/sunxi/sunxi_dw_hdmi.c | 11 ++++++- + include/dw_hdmi.h | 14 ++++++++- + 7 files changed, 89 insertions(+), 6 deletions(-) + +diff --git a/drivers/video/dw_hdmi.c b/drivers/video/dw_hdmi.c +index c4fbb18294..fc8c8bb366 100644 +--- a/drivers/video/dw_hdmi.c ++++ b/drivers/video/dw_hdmi.c +@@ -988,7 +988,7 @@ int dw_hdmi_enable(struct dw_hdmi *hdmi, const struct display_timing *edid) + + hdmi_av_composer(hdmi, edid); + +- ret = hdmi->phy_set(hdmi, edid->pixelclock.typ); ++ ret = hdmi->ops->phy_set(hdmi, edid->pixelclock.typ); + if (ret) + return ret; + +@@ -1009,10 +1009,54 @@ int dw_hdmi_enable(struct dw_hdmi *hdmi, const struct display_timing *edid) + return 0; + } + ++static const struct dw_hdmi_phy_ops dw_hdmi_synopsys_phy_ops = { ++ .phy_set = dw_hdmi_phy_cfg, ++}; ++ ++static void dw_hdmi_detect_phy(struct dw_hdmi *hdmi) ++{ ++ if (!hdmi->data) ++ return; ++ ++ /* hook Synopsys PHYs ops */ ++ if (!hdmi->data->phy_force_vendor) { ++ hdmi->ops = &dw_hdmi_synopsys_phy_ops; ++ return; ++ } ++ ++ /* Vendor HDMI PHYs must assign phy_ops in plat_data */ ++ if (!hdmi->data->phy_ops) { ++ printf("Unsupported Vendor HDMI phy_ops\n"); ++ return; ++ } ++ ++ /* hook Vendor HDMI PHYs ops */ ++ hdmi->ops = hdmi->data->phy_ops; ++} ++ ++int dw_hdmi_disable(struct dw_hdmi *hdmi) ++{ ++ uint clkdis; ++ ++ /* disable pixel clock and tmds data path */ ++ clkdis = 0x7f; ++ hdmi_write(hdmi, clkdis, HDMI_MC_CLKDIS); ++ ++ /* disable phy */ ++ hdmi_phy_sel_interface_control(hdmi, 0); ++ hdmi_phy_enable_tmds(hdmi, 0); ++ hdmi_phy_enable_power(hdmi, 0); ++ ++ return 0; ++ ++} ++ + void dw_hdmi_init(struct dw_hdmi *hdmi) + { + uint ih_mute; + ++ dw_hdmi_detect_phy(hdmi); ++ + /* + * boot up defaults are: + * hdmi_ih_mute = 0x03 (disabled) +diff --git a/drivers/video/meson/meson_dw_hdmi.c b/drivers/video/meson/meson_dw_hdmi.c +index 5db01904b5..d0d878b6af 100644 +--- a/drivers/video/meson/meson_dw_hdmi.c ++++ b/drivers/video/meson/meson_dw_hdmi.c +@@ -375,6 +375,15 @@ static int meson_dw_hdmi_wait_hpd(struct dw_hdmi *hdmi) + return -ETIMEDOUT; + } + ++static const struct dw_hdmi_phy_ops dw_hdmi_meson_phy_ops = { ++ .phy_set = meson_dw_hdmi_phy_init, ++}; ++ ++static const struct dw_hdmi_plat_data dw_hdmi_meson_plat_data = { ++ .phy_force_vendor = true, ++ .phy_ops = &dw_hdmi_meson_phy_ops, ++}; ++ + static int meson_dw_hdmi_probe(struct udevice *dev) + { + struct meson_dw_hdmi *priv = dev_get_priv(dev); +@@ -397,7 +406,7 @@ static int meson_dw_hdmi_probe(struct udevice *dev) + + priv->hdmi.hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24; + priv->hdmi.hdmi_data.enc_in_bus_format = MEDIA_BUS_FMT_YUV8_1X24; +- priv->hdmi.phy_set = meson_dw_hdmi_phy_init; ++ priv->hdmi.data = &dw_hdmi_meson_plat_data; + if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A)) + priv->hdmi.reg_io_width = 1; + else { +diff --git a/drivers/video/rockchip/rk3399_hdmi.c b/drivers/video/rockchip/rk3399_hdmi.c +index 3041360c6e..b32139a8a6 100644 +--- a/drivers/video/rockchip/rk3399_hdmi.c ++++ b/drivers/video/rockchip/rk3399_hdmi.c +@@ -64,8 +64,14 @@ static const struct dm_display_ops rk3399_hdmi_ops = { + .enable = rk3399_hdmi_enable, + }; + ++static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = { ++}; ++ + static const struct udevice_id rk3399_hdmi_ids[] = { +- { .compatible = "rockchip,rk3399-dw-hdmi" }, ++ { ++ .compatible = "rockchip,rk3399-dw-hdmi", ++ .data = (ulong)&rk3399_hdmi_drv_data ++ }, + { } + }; + +diff --git a/drivers/video/rockchip/rk_hdmi.c b/drivers/video/rockchip/rk_hdmi.c +index 8dcd4d5964..e545d69e3b 100644 +--- a/drivers/video/rockchip/rk_hdmi.c ++++ b/drivers/video/rockchip/rk_hdmi.c +@@ -83,6 +83,7 @@ int rk_hdmi_of_to_plat(struct udevice *dev) + struct rk_hdmi_priv *priv = dev_get_priv(dev); + struct dw_hdmi *hdmi = &priv->hdmi; + ++ hdmi->data = (const struct dw_hdmi_plat_data *)dev_get_driver_data(dev); + hdmi->ioaddr = (ulong)dev_read_addr(dev); + hdmi->mpll_cfg = rockchip_mpll_cfg; + hdmi->phy_cfg = rockchip_phy_config; +@@ -90,7 +91,6 @@ int rk_hdmi_of_to_plat(struct udevice *dev) + /* hdmi->i2c_clk_{high,low} are set up by the SoC driver */ + + hdmi->reg_io_width = 4; +- hdmi->phy_set = dw_hdmi_phy_cfg; + + priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); + +diff --git a/drivers/video/rockchip/rk_hdmi.h b/drivers/video/rockchip/rk_hdmi.h +index 200dbaea74..dcfba3d3d7 100644 +--- a/drivers/video/rockchip/rk_hdmi.h ++++ b/drivers/video/rockchip/rk_hdmi.h +@@ -6,6 +6,8 @@ + #ifndef __RK_HDMI_H__ + #define __RK_HDMI_H__ + ++#include ++ + struct rkhdmi_driverdata { + /* configuration */ + u8 i2c_clk_high; +@@ -19,6 +21,7 @@ struct rkhdmi_driverdata { + + struct rk_hdmi_priv { + struct dw_hdmi hdmi; ++ struct phy phy; + void *grf; + }; + +diff --git a/drivers/video/sunxi/sunxi_dw_hdmi.c b/drivers/video/sunxi/sunxi_dw_hdmi.c +index 0324a050d0..f7ecbb923b 100644 +--- a/drivers/video/sunxi/sunxi_dw_hdmi.c ++++ b/drivers/video/sunxi/sunxi_dw_hdmi.c +@@ -328,6 +328,15 @@ static int sunxi_dw_hdmi_enable(struct udevice *dev, int panel_bpp, + return 0; + } + ++static const struct dw_hdmi_phy_ops dw_hdmi_sunxi_phy_ops = { ++ .phy_set = sunxi_dw_hdmi_phy_cfg, ++}; ++ ++static const struct dw_hdmi_plat_data dw_hdmi_sunxi_plat_data = { ++ .phy_force_vendor = true, ++ .phy_ops = &dw_hdmi_sunxi_phy_ops, ++}; ++ + static int sunxi_dw_hdmi_probe(struct udevice *dev) + { + struct sunxi_dw_hdmi_priv *priv = dev_get_priv(dev); +@@ -379,7 +388,7 @@ static int sunxi_dw_hdmi_of_to_plat(struct udevice *dev) + hdmi->i2c_clk_high = 0xd8; + hdmi->i2c_clk_low = 0xfe; + hdmi->reg_io_width = 1; +- hdmi->phy_set = sunxi_dw_hdmi_phy_cfg; ++ hdmi->data = &dw_hdmi_sunxi_plat_data; + + ret = reset_get_bulk(dev, &priv->resets); + if (ret) +diff --git a/include/dw_hdmi.h b/include/dw_hdmi.h +index 8acae3839f..4ad8b39f84 100644 +--- a/include/dw_hdmi.h ++++ b/include/dw_hdmi.h +@@ -534,6 +534,17 @@ struct hdmi_data_info { + struct hdmi_vmode video_mode; + }; + ++struct dw_hdmi; ++ ++struct dw_hdmi_phy_ops { ++ int (*phy_set)(struct dw_hdmi *hdmi, uint mpixelclock); ++}; ++ ++struct dw_hdmi_plat_data { ++ bool phy_force_vendor; ++ const struct dw_hdmi_phy_ops *phy_ops; ++}; ++ + struct dw_hdmi { + ulong ioaddr; + const struct hdmi_mpll_config *mpll_cfg; +@@ -543,8 +554,9 @@ struct dw_hdmi { + u8 reg_io_width; + struct hdmi_data_info hdmi_data; + struct udevice *ddc_bus; ++ const struct dw_hdmi_phy_ops *ops; ++ const struct dw_hdmi_plat_data *data; + +- int (*phy_set)(struct dw_hdmi *hdmi, uint mpixelclock); + void (*write_reg)(struct dw_hdmi *hdmi, u8 val, int offset); + u8 (*read_reg)(struct dw_hdmi *hdmi, int offset); + }; +-- +2.34.1 + diff --git a/patch/u-boot/v2024.01/board_rk3318-box/general-hdmi-02-hpd-cleanup.patch b/patch/u-boot/v2024.01/board_rk3318-box/general-hdmi-02-hpd-cleanup.patch new file mode 100644 index 0000000000..8c45007506 --- /dev/null +++ b/patch/u-boot/v2024.01/board_rk3318-box/general-hdmi-02-hpd-cleanup.patch @@ -0,0 +1,193 @@ +From d2804380b05b4e8e6557ce7239a1680853dd5258 Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Sat, 18 Feb 2023 00:30:30 +0530 +Subject: [PATCH] video: rockchip: hdmi: Detect hpd after controller init + +Signed-off-by: Jagan Teki +--- + drivers/video/rockchip/rk_hdmi.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/video/rockchip/rk_hdmi.c b/drivers/video/rockchip/rk_hdmi.c +index 8dcd4d59645..b75a1744896 100644 +--- a/drivers/video/rockchip/rk_hdmi.c ++++ b/drivers/video/rockchip/rk_hdmi.c +@@ -112,14 +112,14 @@ int rk_hdmi_probe(struct udevice *dev) + struct dw_hdmi *hdmi = &priv->hdmi; + int ret; + ++ dw_hdmi_init(hdmi); ++ dw_hdmi_phy_init(hdmi); ++ + ret = dw_hdmi_phy_wait_for_hpd(hdmi); + if (ret < 0) { + debug("hdmi can not get hpd signal\n"); + return -1; + } + +- dw_hdmi_init(hdmi); +- dw_hdmi_phy_init(hdmi); +- + return 0; + } +From 3569108607b8569c16aa5df540cf35db2bf58b05 Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Sun, 19 Feb 2023 00:20:52 +0530 +Subject: [PATCH] video: dw_hdmi: Simplify HPD detection + +Signed-off-by: Jagan Teki +--- + drivers/video/dw_hdmi.c | 13 +++++++++++++ + drivers/video/rockchip/rk_hdmi.c | 8 +++----- + drivers/video/sunxi/sunxi_dw_hdmi.c | 8 +++----- + include/dw_hdmi.h | 1 + + 4 files changed, 20 insertions(+), 10 deletions(-) + +diff --git a/drivers/video/dw_hdmi.c b/drivers/video/dw_hdmi.c +index ea12a094074..0a597206f06 100644 +--- a/drivers/video/dw_hdmi.c ++++ b/drivers/video/dw_hdmi.c +@@ -936,6 +936,19 @@ int dw_hdmi_phy_wait_for_hpd(struct dw_hdmi *hdmi) + return -1; + } + ++int dw_hdmi_detect_hpd(struct dw_hdmi *hdmi) ++{ ++ int ret; ++ ++ ret = dw_hdmi_phy_wait_for_hpd(hdmi); ++ if (ret < 0) { ++ debug("hdmi can not get hpd signal\n"); ++ return -ENODEV; ++ } ++ ++ return 0; ++} ++ + void dw_hdmi_phy_init(struct dw_hdmi *hdmi) + { + /* enable phy i2cm done irq */ +diff --git a/drivers/video/rockchip/rk_hdmi.c b/drivers/video/rockchip/rk_hdmi.c +index e34f532cd68..8a65f2440e4 100644 +--- a/drivers/video/rockchip/rk_hdmi.c ++++ b/drivers/video/rockchip/rk_hdmi.c +@@ -115,11 +115,9 @@ int rk_hdmi_probe(struct udevice *dev) + dw_hdmi_init(hdmi); + dw_hdmi_phy_init(hdmi); + +- ret = dw_hdmi_phy_wait_for_hpd(hdmi); +- if (ret < 0) { +- debug("hdmi can not get hpd signal\n"); +- return -1; +- } ++ ret = dw_hdmi_detect_hpd(hdmi); ++ if (ret < 0) ++ return ret; + + return 0; + } +diff --git a/drivers/video/sunxi/sunxi_dw_hdmi.c b/drivers/video/sunxi/sunxi_dw_hdmi.c +index 46ad9d137b1..6738950fd00 100644 +--- a/drivers/video/sunxi/sunxi_dw_hdmi.c ++++ b/drivers/video/sunxi/sunxi_dw_hdmi.c +@@ -347,11 +347,9 @@ static int sunxi_dw_hdmi_probe(struct udevice *dev) + + sunxi_dw_hdmi_phy_init(&priv->hdmi); + +- ret = dw_hdmi_phy_wait_for_hpd(&priv->hdmi); +- if (ret < 0) { +- debug("hdmi can not get hpd signal\n"); +- return -1; +- } ++ ret = dw_hdmi_detect_hpd(&priv->hdmi); ++ if (ret < 0) ++ return ret; + + dw_hdmi_init(&priv->hdmi); + +diff --git a/include/dw_hdmi.h b/include/dw_hdmi.h +index 4ad8b39f84d..756560e0928 100644 +--- a/include/dw_hdmi.h ++++ b/include/dw_hdmi.h +@@ -554,7 +568,9 @@ int dw_hdmi_phy_wait_for_hpd(struct dw_hdmi *hdmi); + void dw_hdmi_phy_init(struct dw_hdmi *hdmi); + + int dw_hdmi_enable(struct dw_hdmi *hdmi, const struct display_timing *edid); ++int dw_hdmi_disable(struct dw_hdmi *hdmi); + int dw_hdmi_read_edid(struct dw_hdmi *hdmi, u8 *buf, int buf_size); + void dw_hdmi_init(struct dw_hdmi *hdmi); ++int dw_hdmi_detect_hpd(struct dw_hdmi *hdmi); + + #endif +From 89431ed902443d0c62e88ca71ac31059c413b4bf Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Sun, 19 Feb 2023 00:30:37 +0530 +Subject: [PATCH] video: dw_hdmi: Add read_hpd hook + +Signed-off-by: Jagan Teki +--- + drivers/video/dw_hdmi.c | 3 +++ + include/dw_hdmi.h | 1 + + 2 files changed, 4 insertions(+) + +diff --git a/drivers/video/dw_hdmi.c b/drivers/video/dw_hdmi.c +index 0a597206f06..172e6b45a60 100644 +--- a/drivers/video/dw_hdmi.c ++++ b/drivers/video/dw_hdmi.c +@@ -946,6 +946,9 @@ int dw_hdmi_detect_hpd(struct dw_hdmi *hdmi) + return -ENODEV; + } + ++ if (hdmi->ops->read_hpd) ++ hdmi->ops->read_hpd(hdmi, true); ++ + return 0; + } + +diff --git a/include/dw_hdmi.h b/include/dw_hdmi.h +index 756560e0928..d6de472cee8 100644 +--- a/include/dw_hdmi.h ++++ b/include/dw_hdmi.h +@@ -538,6 +538,7 @@ struct dw_hdmi; + + struct dw_hdmi_phy_ops { + int (*phy_set)(struct dw_hdmi *hdmi, uint mpixelclock); ++ void (*read_hpd)(struct dw_hdmi *hdmi, bool hdp_status); + }; + + struct dw_hdmi_plat_data { +From 40405cb1924f60ff27923d5d11e6558117ced815 Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Sun, 19 Feb 2023 00:33:18 +0530 +Subject: [PATCH] video: dw_hdmi: Add setup_hpd hook + +Signed-off-by: Jagan Teki +--- + drivers/video/dw_hdmi.c | 3 +++ + include/dw_hdmi.h | 1 + + 2 files changed, 4 insertions(+) + +diff --git a/drivers/video/dw_hdmi.c b/drivers/video/dw_hdmi.c +index 172e6b45a60..3e0e20e59ba 100644 +--- a/drivers/video/dw_hdmi.c ++++ b/drivers/video/dw_hdmi.c +@@ -1080,4 +1080,7 @@ void dw_hdmi_init(struct dw_hdmi *hdmi) + + /* enable i2c client nack % arbitration error irq */ + hdmi_write(hdmi, ~0x44, HDMI_I2CM_CTLINT); ++ ++ if (hdmi->ops->setup_hpd) ++ hdmi->ops->setup_hpd(hdmi); + } +diff --git a/include/dw_hdmi.h b/include/dw_hdmi.h +index d6de472cee8..9a44b9e90c3 100644 +--- a/include/dw_hdmi.h ++++ b/include/dw_hdmi.h +@@ -539,6 +539,7 @@ struct dw_hdmi; + struct dw_hdmi_phy_ops { + int (*phy_set)(struct dw_hdmi *hdmi, uint mpixelclock); + void (*read_hpd)(struct dw_hdmi *hdmi, bool hdp_status); ++ void (*setup_hpd)(struct dw_hdmi *hdmi); + }; + + struct dw_hdmi_plat_data { diff --git a/patch/u-boot/v2024.01/board_rk3318-box/rk3328-hdmi-driver.patch b/patch/u-boot/v2024.01/board_rk3318-box/rk3328-hdmi-driver.patch index 4fc3283d00..848e6009f8 100644 --- a/patch/u-boot/v2024.01/board_rk3318-box/rk3328-hdmi-driver.patch +++ b/patch/u-boot/v2024.01/board_rk3318-box/rk3328-hdmi-driver.patch @@ -187,24 +187,4 @@ index 0000000000..6f562d0ed8 + .remove = rk3328_hdmi_remove, + .flags = DM_FLAG_OS_PREPARE +}; -diff --git a/drivers/video/rockchip/rk_hdmi.h b/drivers/video/rockchip/rk_hdmi.h -index 200dbaea740..dcfba3d3d7e 100644 ---- a/drivers/video/rockchip/rk_hdmi.h -+++ b/drivers/video/rockchip/rk_hdmi.h -@@ -6,6 +6,8 @@ - #ifndef __RK_HDMI_H__ - #define __RK_HDMI_H__ - -+#include -+ - struct rkhdmi_driverdata { - /* configuration */ - u8 i2c_clk_high; -@@ -19,6 +21,7 @@ struct rkhdmi_driverdata { - - struct rk_hdmi_priv { - struct dw_hdmi hdmi; -+ struct phy phy; - void *grf; - }; diff --git a/patch/u-boot/v2024.01/board_rk3318-box/rk3328-vop-driver.patch b/patch/u-boot/v2024.01/board_rk3318-box/rk3328-vop-driver.patch index 0a46a6f1b5..d794a39c13 100644 --- a/patch/u-boot/v2024.01/board_rk3318-box/rk3328-vop-driver.patch +++ b/patch/u-boot/v2024.01/board_rk3318-box/rk3328-vop-driver.patch @@ -272,13 +272,13 @@ index b825ff4cf83..195247d9e02 100644 + case ACLK_VOP_PRE: + rk_clrsetreg(&cru->clksel_con[39], + ACLK_VOP_PLL_SEL_MASK | ACLK_VOP_DIV_CON_MASK, -+ ACLK_VOP_PLL_SEL_CPLL << ACLK_VOP_PLL_SEL_SHIFT | ++ ACLK_VOP_PLL_SEL_GPLL << ACLK_VOP_PLL_SEL_SHIFT | + (src_clk_div - 1) << ACLK_VOP_DIV_CON_SHIFT); + break; + case ACLK_VIO_PRE: + rk_clrsetreg(&cru->clksel_con[37], + ACLK_VIO_PLL_SEL_MASK | ACLK_VIO_DIV_CON_MASK, -+ ACLK_VIO_PLL_SEL_CPLL << ACLK_VIO_PLL_SEL_SHIFT | ++ ACLK_VIO_PLL_SEL_GPLL << ACLK_VIO_PLL_SEL_SHIFT | + (src_clk_div - 1) << ACLK_VIO_DIV_CON_SHIFT); + break; + case DCLK_LCDC: diff --git a/patch/u-boot/v2024.01/board_rk3318-box/general-add-inno-hdmi-phy.patch b/patch/u-boot/v2024.01/driver-rockchip-inno-hdmi-phy.patch similarity index 63% rename from patch/u-boot/v2024.01/board_rk3318-box/general-add-inno-hdmi-phy.patch rename to patch/u-boot/v2024.01/driver-rockchip-inno-hdmi-phy.patch index 518b40db8f..d68726a879 100644 --- a/patch/u-boot/v2024.01/board_rk3318-box/general-add-inno-hdmi-phy.patch +++ b/patch/u-boot/v2024.01/driver-rockchip-inno-hdmi-phy.patch @@ -44,10 +44,10 @@ index a236877234b..800d5c61ef2 100644 obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c new file mode 100644 -index 0000000000..99cf174214 +index 0000000000..207bb0acf6 --- /dev/null +++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c -@@ -0,0 +1,759 @@ +@@ -0,0 +1,989 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Rockchip Innosilicon HDMI PHY @@ -72,118 +72,97 @@ index 0000000000..99cf174214 +#define PRE_PLL_REFCLK_SEL_PCLK BIT(0) +#define PRE_PLL_REFCLK_SEL_OSCCLK 0 +/* REG: 0x01 */ -+#define BYPASS_RXSENSE_EN_MASK BIT(2) +#define BYPASS_RXSENSE_EN BIT(2) -+#define BYPASS_PWRON_EN_MASK BIT(1) +#define BYPASS_PWRON_EN BIT(1) -+#define BYPASS_PLLPD_EN_MASK BIT(0) +#define BYPASS_PLLPD_EN BIT(0) +/* REG: 0x02 */ -+#define BYPASS_PDATA_EN_MASK BIT(4) ++#define INT_POL_HIGH BIT(7) +#define BYPASS_PDATA_EN BIT(4) -+#define PDATAEN_MASK BIT(0) -+#define PDATAEN_DISABLE BIT(0) -+#define PDATAEN_ENABLE 0 ++#define RK3328_PDATA_EN BIT(0) ++#define RK3228_PDATA_EN_DISABLE BIT(0) +/* REG: 0x03 */ +#define BYPASS_AUTO_TERM_RES_CAL BIT(7) +#define AUDO_TERM_RES_CAL_SPEED_14_8(x) UPDATE(x, 6, 0) +/* REG: 0x04 */ +#define AUDO_TERM_RES_CAL_SPEED_7_0(x) UPDATE(x, 7, 0) +/* REG: 0xaa */ -+#define POST_PLL_CTRL_MASK BIT(0) +#define POST_PLL_CTRL_MANUAL BIT(0) +/* REG: 0xe0 */ -+#define POST_PLL_POWER_MASK BIT(5) -+#define POST_PLL_POWER_DOWN BIT(5) -+#define POST_PLL_POWER_UP 0 -+#define PRE_PLL_POWER_MASK BIT(4) -+#define PRE_PLL_POWER_DOWN BIT(4) -+#define PRE_PLL_POWER_UP 0 -+#define RXSENSE_CLK_CH_MASK BIT(3) -+#define RXSENSE_CLK_CH_ENABLE BIT(3) -+#define RXSENSE_DATA_CH2_MASK BIT(2) -+#define RXSENSE_DATA_CH2_ENABLE BIT(2) -+#define RXSENSE_DATA_CH1_MASK BIT(1) -+#define RXSENSE_DATA_CH1_ENABLE BIT(1) -+#define RXSENSE_DATA_CH0_MASK BIT(0) -+#define RXSENSE_DATA_CH0_ENABLE BIT(0) ++#define RK3228_POST_PLL_POWER_DOWN BIT(5) ++#define RK3228_POST_PLL_POWER_UP 0 ++#define RK3228_PRE_PLL_POWER_DOWN BIT(4) ++#define RK3228_RXSENSE_CLK_CH_MASK BIT(3) ++#define RK3228_RXSENSE_CLK_CH_ENABLE BIT(3) ++#define RK3228_RXSENSE_DATA_CH2_MASK BIT(2) ++#define RK3228_RXSENSE_DATA_CH2_ENABLE BIT(2) ++#define RK3228_RXSENSE_DATA_CH1_MASK BIT(1) ++#define RK3228_RXSENSE_DATA_CH1_ENABLE BIT(1) ++#define RK3228_RXSENSE_DATA_CH0_MASK BIT(0) ++#define RK3228_RXSENSE_DATA_CH0_ENABLE BIT(0) +/* REG: 0xe1 */ -+#define BANDGAP_MASK BIT(4) -+#define BANDGAP_ENABLE BIT(4) -+#define BANDGAP_DISABLE 0 -+#define TMDS_DRIVER_MASK GENMASK(3, 0) -+#define TMDS_DRIVER_ENABLE UPDATE(0xf, 3, 0) -+#define TMDS_DRIVER_DISABLE 0 ++#define RK3228_BANDGAP_ENABLE BIT(4) ++#define RK3228_TMDS_DRIVER_ENABLE GENMASK(3, 0) +/* REG: 0xe2 */ -+#define PRE_PLL_FB_DIV_8_MASK BIT(7) -+#define PRE_PLL_FB_DIV_8_SHIFT 7 -+#define PRE_PLL_FB_DIV_8(x) UPDATE(x, 7, 7) -+#define PCLK_VCO_DIV_5_MASK BIT(5) -+#define PCLK_VCO_DIV_5_SHIFT 5 -+#define PCLK_VCO_DIV_5(x) UPDATE(x, 5, 5) -+#define PRE_PLL_PRE_DIV_MASK GENMASK(4, 0) -+#define PRE_PLL_PRE_DIV(x) UPDATE(x, 4, 0) ++#define RK3228_PRE_PLL_FB_DIV_8_MASK BIT(7) ++#define RK3228_PRE_PLL_FB_DIV_8(x) UPDATE((x) >> 8, 7, 7) ++#define RK3228_PCLK_VCO_DIV_5_MASK BIT(5) ++#define RK3228_PCLK_VCO_DIV_5(x) UPDATE(x, 5, 5) ++#define RK3228_PRE_PLL_PRE_DIV_MASK GENMASK(4, 0) ++#define RK3228_PRE_PLL_PRE_DIV(x) UPDATE(x, 4, 0) +/* REG: 0xe3 */ -+#define PRE_PLL_FB_DIV_7_0(x) UPDATE(x, 7, 0) ++#define RK3228_PRE_PLL_FB_DIV_7_0(x) UPDATE(x, 7, 0) +/* REG: 0xe4 */ -+#define PRE_PLL_PCLK_DIV_B_MASK GENMASK(6, 5) -+#define PRE_PLL_PCLK_DIV_B_SHIFT 5 -+#define PRE_PLL_PCLK_DIV_B(x) UPDATE(x, 6, 5) -+#define PRE_PLL_PCLK_DIV_A_MASK GENMASK(4, 0) -+#define PRE_PLL_PCLK_DIV_A_SHIFT 0 -+#define PRE_PLL_PCLK_DIV_A(x) UPDATE(x, 4, 0) ++#define RK3228_PRE_PLL_PCLK_DIV_B_MASK GENMASK(6, 5) ++#define RK3228_PRE_PLL_PCLK_DIV_B_SHIFT 5 ++#define RK3228_PRE_PLL_PCLK_DIV_B(x) UPDATE(x, 6, 5) ++#define RK3228_PRE_PLL_PCLK_DIV_A_MASK GENMASK(4, 0) ++#define RK3228_PRE_PLL_PCLK_DIV_A(x) UPDATE(x, 4, 0) +/* REG: 0xe5 */ -+#define PRE_PLL_PCLK_DIV_C_MASK GENMASK(6, 5) -+#define PRE_PLL_PCLK_DIV_C_SHIFT 5 -+#define PRE_PLL_PCLK_DIV_C(x) UPDATE(x, 6, 5) -+#define PRE_PLL_PCLK_DIV_D_MASK GENMASK(4, 0) -+#define PRE_PLL_PCLK_DIV_D_SHIFT 0 -+#define PRE_PLL_PCLK_DIV_D(x) UPDATE(x, 4, 0) ++#define RK3228_PRE_PLL_PCLK_DIV_C_MASK GENMASK(6, 5) ++#define RK3228_PRE_PLL_PCLK_DIV_C(x) UPDATE(x, 6, 5) ++#define RK3228_PRE_PLL_PCLK_DIV_D_MASK GENMASK(4, 0) ++#define RK3228_PRE_PLL_PCLK_DIV_D(x) UPDATE(x, 4, 0) +/* REG: 0xe6 */ -+#define PRE_PLL_TMDSCLK_DIV_C_MASK GENMASK(5, 4) -+#define PRE_PLL_TMDSCLK_DIV_C(x) UPDATE(x, 5, 4) -+#define PRE_PLL_TMDSCLK_DIV_A_MASK GENMASK(3, 2) -+#define PRE_PLL_TMDSCLK_DIV_A(x) UPDATE(x, 3, 2) -+#define PRE_PLL_TMDSCLK_DIV_B_MASK GENMASK(1, 0) -+#define PRE_PLL_TMDSCLK_DIV_B(x) UPDATE(x, 1, 0) ++#define RK3228_PRE_PLL_TMDSCLK_DIV_C_MASK GENMASK(5, 4) ++#define RK3228_PRE_PLL_TMDSCLK_DIV_C(x) UPDATE(x, 5, 4) ++#define RK3228_PRE_PLL_TMDSCLK_DIV_A_MASK GENMASK(3, 2) ++#define RK3228_PRE_PLL_TMDSCLK_DIV_A(x) UPDATE(x, 3, 2) ++#define RK3228_PRE_PLL_TMDSCLK_DIV_B_MASK GENMASK(1, 0) ++#define RK3228_PRE_PLL_TMDSCLK_DIV_B(x) UPDATE(x, 1, 0) +/* REG: 0xe8 */ -+#define PRE_PLL_LOCK_STATUS BIT(0) ++#define RK3228_PRE_PLL_LOCK_STATUS BIT(0) +/* REG: 0xe9 */ -+#define POST_PLL_POST_DIV_EN_MASK GENMASK(7, 6) -+#define POST_PLL_POST_DIV_ENABLE UPDATE(3, 7, 6) -+#define POST_PLL_POST_DIV_DISABLE 0 -+#define POST_PLL_PRE_DIV_MASK GENMASK(4, 0) -+#define POST_PLL_PRE_DIV(x) UPDATE(x, 4, 0) ++#define RK3228_POST_PLL_POST_DIV_ENABLE UPDATE(3, 7, 6) ++#define RK3228_POST_PLL_PRE_DIV_MASK GENMASK(4, 0) ++#define RK3228_POST_PLL_PRE_DIV(x) UPDATE(x, 4, 0) +/* REG: 0xea */ -+#define POST_PLL_FB_DIV_7_0(x) UPDATE(x, 7, 0) ++#define RK3228_POST_PLL_FB_DIV_7_0(x) UPDATE(x, 7, 0) +/* REG: 0xeb */ -+#define POST_PLL_FB_DIV_8_MASK BIT(7) -+#define POST_PLL_FB_DIV_8(x) UPDATE(x, 7, 7) -+#define POST_PLL_POST_DIV_MASK GENMASK(5, 4) -+#define POST_PLL_POST_DIV(x) UPDATE(x, 5, 4) -+#define POST_PLL_LOCK_STATUS BIT(0) ++#define RK3228_POST_PLL_FB_DIV_8_MASK BIT(7) ++#define RK3228_POST_PLL_FB_DIV_8(x) UPDATE((x) >> 8, 7, 7) ++#define RK3228_POST_PLL_POST_DIV_MASK GENMASK(5, 4) ++#define RK3228_POST_PLL_POST_DIV(x) UPDATE(x, 5, 4) ++#define RK3228_POST_PLL_LOCK_STATUS BIT(0) +/* REG: 0xee */ -+#define TMDS_CH_TA_MASK GENMASK(7, 4) -+#define TMDS_CH_TA_ENABLE UPDATE(0xf, 7, 4) -+#define TMDS_CH_TA_DISABLE 0 ++#define RK3228_TMDS_CH_TA_ENABLE GENMASK(7, 4) +/* REG: 0xef */ -+#define TMDS_CLK_CH_TA(x) UPDATE(x, 7, 6) -+#define TMDS_DATA_CH2_TA(x) UPDATE(x, 5, 4) -+#define TMDS_DATA_CH1_TA(x) UPDATE(x, 3, 2) -+#define TMDS_DATA_CH0_TA(x) UPDATE(x, 1, 0) ++#define RK3228_TMDS_CLK_CH_TA(x) UPDATE(x, 7, 6) ++#define RK3228_TMDS_DATA_CH2_TA(x) UPDATE(x, 5, 4) ++#define RK3228_TMDS_DATA_CH1_TA(x) UPDATE(x, 3, 2) ++#define RK3228_TMDS_DATA_CH0_TA(x) UPDATE(x, 1, 0) +/* REG: 0xf0 */ -+#define TMDS_DATA_CH2_PRE_EMPHASIS_MASK GENMASK(5, 4) -+#define TMDS_DATA_CH2_PRE_EMPHASIS(x) UPDATE(x, 5, 4) -+#define TMDS_DATA_CH1_PRE_EMPHASIS_MASK GENMASK(3, 2) -+#define TMDS_DATA_CH1_PRE_EMPHASIS(x) UPDATE(x, 3, 2) -+#define TMDS_DATA_CH0_PRE_EMPHASIS_MASK GENMASK(1, 0) -+#define TMDS_DATA_CH0_PRE_EMPHASIS(x) UPDATE(x, 1, 0) ++#define RK3228_TMDS_DATA_CH2_PRE_EMPHASIS_MASK GENMASK(5, 4) ++#define RK3228_TMDS_DATA_CH2_PRE_EMPHASIS(x) UPDATE(x, 5, 4) ++#define RK3228_TMDS_DATA_CH1_PRE_EMPHASIS_MASK GENMASK(3, 2) ++#define RK3228_TMDS_DATA_CH1_PRE_EMPHASIS(x) UPDATE(x, 3, 2) ++#define RK3228_TMDS_DATA_CH0_PRE_EMPHASIS_MASK GENMASK(1, 0) ++#define RK3228_TMDS_DATA_CH0_PRE_EMPHASIS(x) UPDATE(x, 1, 0) +/* REG: 0xf1 */ -+#define TMDS_CLK_CH_OUTPUT_SWING(x) UPDATE(x, 7, 4) -+#define TMDS_DATA_CH2_OUTPUT_SWING(x) UPDATE(x, 3, 0) ++#define RK3228_TMDS_CLK_CH_OUTPUT_SWING(x) UPDATE(x, 7, 4) ++#define RK3228_TMDS_DATA_CH2_OUTPUT_SWING(x) UPDATE(x, 3, 0) +/* REG: 0xf2 */ -+#define TMDS_DATA_CH1_OUTPUT_SWING(x) UPDATE(x, 7, 4) -+#define TMDS_DATA_CH0_OUTPUT_SWING(x) UPDATE(x, 3, 0) ++#define RK3228_TMDS_DATA_CH1_OUTPUT_SWING(x) UPDATE(x, 7, 4) ++#define RK3228_TMDS_DATA_CH0_OUTPUT_SWING(x) UPDATE(x, 3, 0) + +struct inno_hdmi_phy; + @@ -226,9 +205,13 @@ index 0000000000..99cf174214 + const struct pre_pll_config *cfg); + unsigned long (*recalc_rate)(struct inno_hdmi_phy *inno, + unsigned long parent_rate); ++ int (*clk_is_prepared)(struct inno_hdmi_phy *inno); ++ int (*clk_prepare)(struct inno_hdmi_phy *inno); ++ +}; + +enum inno_hdmi_phy_type { ++ INNO_HDMI_PHY_RK3228, + INNO_HDMI_PHY_RK3328, +}; + @@ -295,6 +278,26 @@ index 0000000000..99cf174214 + { ~0UL, 0, 0, 0, 0} +}; + ++/* phy tuning values for an undocumented set of registers */ ++static const struct phy_config rk3228_phy_cfg[] = { ++ { 165000000, { ++ 0xaa, 0x00, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, ++ }, ++ }, { ++ 340000000, { ++ 0xaa, 0x15, 0x6a, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, ++ }, ++ }, { ++ 594000000, { ++ 0xaa, 0x15, 0x7a, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, ++ }, ++ }, { /* sentinel */ }, ++}; ++ ++/* phy tuning values for an undocumented set of registers */ +static const struct phy_config rk3328_phy_cfg[] = { + { 165000000, { + 0x07, 0x08, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x08, @@ -424,20 +427,40 @@ index 0000000000..99cf174214 + return 0; +} + -+static int inno_hdmi_phy_clk_is_prepared(struct inno_hdmi_phy *inno) ++static int inno_hdmi_phy_rk3328_clk_is_prepared(struct inno_hdmi_phy *inno) +{ + u8 status = inno_read(inno, 0xa0) & 1; + + return status ? 0 : 1; +} + -+static int inno_hdmi_phy_clk_prepare(struct inno_hdmi_phy *inno) ++static int inno_hdmi_phy_rk3328_clk_prepare(struct inno_hdmi_phy *inno) +{ + inno_update_bits(inno, 0xa0, 1, 0); + + return 0; +} + ++static int inno_hdmi_phy_rk3228_clk_is_prepared(struct inno_hdmi_phy *inno) ++{ ++ u8 status = inno_read(inno, 0xe0) & RK3228_PRE_PLL_POWER_DOWN; ++ ++ status = status ? 0 : 1; ++ ++ debug("%s: status=%d\n", __func__, status); ++ ++ return status; ++} ++ ++static int inno_hdmi_phy_rk3228_clk_prepare(struct inno_hdmi_phy *inno) ++{ ++ inno_update_bits(inno, 0xe0, RK3228_PRE_PLL_POWER_DOWN, 0); ++ ++ debug("%s\n", __func__); ++ ++ return 0; ++} ++ +static int inno_hdmi_phy_clk_set_rate(struct inno_hdmi_phy *inno, + unsigned long rate) +{ @@ -620,7 +643,7 @@ index 0000000000..99cf174214 +} + +static unsigned long -+inno_hdmi_3328_phy_pll_recalc_rate(struct inno_hdmi_phy *inno, ++inno_hdmi_phy_rk3328_pll_recalc_rate(struct inno_hdmi_phy *inno, + unsigned long parent_rate) +{ + unsigned long rate, vco, frac; @@ -661,8 +684,8 @@ index 0000000000..99cf174214 + * Use phy internal register control + * rxsense/poweron/pllpd/pdataen signal. + */ -+ inno_write(inno, 0x01, 0x07); -+ inno_write(inno, 0x02, 0x91); ++ inno_write(inno, 0x01, BYPASS_RXSENSE_EN | BYPASS_PWRON_EN | BYPASS_PLLPD_EN); ++ inno_write(inno, 0x02, INT_POL_HIGH | BYPASS_PDATA_EN | RK3328_PDATA_EN); + debug("[PHY] %s: done!\n", __func__); +} + @@ -671,7 +694,197 @@ index 0000000000..99cf174214 + .power_on = inno_hdmi_phy_rk3328_power_on, + .power_off = inno_hdmi_phy_rk3328_power_off, + .pre_pll_update = inno_hdmi_phy_rk3328_pre_pll_update, -+ .recalc_rate = inno_hdmi_3328_phy_pll_recalc_rate, ++ .recalc_rate = inno_hdmi_phy_rk3328_pll_recalc_rate, ++ .clk_is_prepared = inno_hdmi_phy_rk3328_clk_is_prepared, ++ .clk_prepare = inno_hdmi_phy_rk3328_clk_prepare ++}; ++ ++static void inno_hdmi_phy_rk3228_init(struct inno_hdmi_phy *inno) ++{ ++ debug("[PHY] %s: In?\n", __func__); ++ /* ++ * Use phy internal register control ++ * rxsense/poweron/pllpd/pdataen signal. ++ */ ++ inno_write(inno, 0x01, BYPASS_RXSENSE_EN | BYPASS_PWRON_EN | BYPASS_PLLPD_EN); ++ inno_update_bits(inno, 0x02, BYPASS_PDATA_EN, BYPASS_PDATA_EN); ++ ++ /* manual power down post-PLL */ ++ inno_update_bits(inno, 0xaa, POST_PLL_CTRL_MANUAL, POST_PLL_CTRL_MANUAL); ++ ++ debug("[PHY] %s: done!\n", __func__); ++} ++ ++static int ++inno_hdmi_phy_rk3228_power_on(struct inno_hdmi_phy *inno, ++ const struct post_pll_config *cfg, ++ const struct phy_config *phy_cfg) ++{ ++ u32 val; ++ ++ /* set pdata_en to 0 */ ++ inno_update_bits(inno, 0x02, RK3228_PDATA_EN_DISABLE, RK3228_PDATA_EN_DISABLE); ++ inno_update_bits(inno, 0xe0, RK3228_PRE_PLL_POWER_DOWN | RK3228_POST_PLL_POWER_DOWN, ++ RK3228_PRE_PLL_POWER_DOWN | RK3228_POST_PLL_POWER_DOWN); ++ ++ /* Post-PLL update */ ++ inno_update_bits(inno, 0xe9, RK3228_POST_PLL_PRE_DIV_MASK, ++ RK3228_POST_PLL_PRE_DIV(cfg->prediv)); ++ inno_update_bits(inno, 0xeb, RK3228_POST_PLL_FB_DIV_8_MASK, ++ RK3228_POST_PLL_FB_DIV_8(cfg->fbdiv)); ++ inno_write(inno, 0xea, RK3228_POST_PLL_FB_DIV_7_0(cfg->fbdiv)); ++ ++ if (cfg->postdiv == 1) { ++ inno_update_bits(inno, 0xe9, RK3228_POST_PLL_POST_DIV_ENABLE, 0); ++ } else { ++ int div = cfg->postdiv / 2 - 1; ++ ++ inno_update_bits(inno, 0xe9, RK3228_POST_PLL_POST_DIV_ENABLE, ++ RK3228_POST_PLL_POST_DIV_ENABLE); ++ inno_update_bits(inno, 0xeb, RK3228_POST_PLL_POST_DIV_MASK, ++ RK3228_POST_PLL_POST_DIV(div)); ++ } ++ ++ for (val = 0; val < 4; val++) ++ inno_write(inno, 0xef + val, phy_cfg->regs[val]); ++ ++ inno_update_bits(inno, 0xe0, RK3228_PRE_PLL_POWER_DOWN | ++ RK3228_POST_PLL_POWER_DOWN, 0); ++ inno_update_bits(inno, 0xe1, RK3228_BANDGAP_ENABLE, ++ RK3228_BANDGAP_ENABLE); ++ inno_update_bits(inno, 0xe1, RK3228_TMDS_DRIVER_ENABLE, ++ RK3228_TMDS_DRIVER_ENABLE); ++ ++ /* Wait for post PLL lock, up to 100ms */ ++ for (val = 0; val < 100; val++) { ++ if (inno_read(inno, 0xeb) & RK3228_POST_PLL_LOCK_STATUS) ++ break; ++ udelay(1000); ++ } ++ ++ if (!(inno_read(inno, 0xeb) & RK3228_POST_PLL_LOCK_STATUS)) { ++ printf("%s: HDMI PHY Post PLL unlock\n", __func__); ++ return -ETIMEDOUT; ++ } ++ ++ if (phy_cfg->tmdsclock > 340000000) ++ mdelay(100); ++ ++ /* set pdata_en_disable to 0 */ ++ inno_update_bits(inno, 0x02, RK3228_PDATA_EN_DISABLE, 0); ++ ++ return 0; ++} ++ ++static void inno_hdmi_phy_rk3228_power_off(struct inno_hdmi_phy *inno) ++{ ++ ++ debug("%s\n", __func__); ++ ++ inno_update_bits(inno, 0xe1, RK3228_TMDS_DRIVER_ENABLE, 0); ++ inno_update_bits(inno, 0xe1, RK3228_BANDGAP_ENABLE, 0); ++ inno_update_bits(inno, 0xe0, RK3228_POST_PLL_POWER_DOWN, ++ RK3228_POST_PLL_POWER_DOWN); ++} ++ ++static unsigned long ++inno_hdmi_phy_rk3228_pll_recalc_rate(struct inno_hdmi_phy *inno, ++ unsigned long parent_rate) ++{ ++ u64 rate, vco; ++ u8 nd, no_a, no_b, no_d; ++ __maybe_unused u8 no_c; ++ u16 nf; ++ ++ nd = inno_read(inno, 0xe2) & RK3228_PRE_PLL_PRE_DIV_MASK; ++ nf = (inno_read(inno, 0xe2) & RK3228_PRE_PLL_FB_DIV_8_MASK) << 1; ++ nf |= inno_read(inno, 0xe3); ++ vco = parent_rate * nf; ++ ++ if (inno_read(inno, 0xe2) & RK3228_PCLK_VCO_DIV_5_MASK) { ++ rate = vco / (nd * 5); ++ } else { ++ no_a = inno_read(inno, 0xe4) & RK3228_PRE_PLL_PCLK_DIV_A_MASK; ++ if (!no_a) ++ no_a = 1; ++ no_b = inno_read(inno, 0xe4) & RK3228_PRE_PLL_PCLK_DIV_B_MASK; ++ no_b >>= RK3228_PRE_PLL_PCLK_DIV_B_SHIFT; ++ no_b += 2; ++ no_d = inno_read(inno, 0xe5) & RK3228_PRE_PLL_PCLK_DIV_D_MASK; ++ ++ if (no_a == 1) ++ rate = vco / (nd * no_b * no_d * 2); ++ else ++ rate = vco / (nd * no_a * no_d * 2); ++ ++ } ++ ++ inno->pixclock = rate; ++ ++ debug("%s, pixclock=%llu\n", __func__, rate); ++ ++ return rate; ++} ++ ++static int ++inno_hdmi_phy_rk3228_pre_pll_update(struct inno_hdmi_phy *inno, ++ const struct pre_pll_config *cfg) ++{ ++ u32 val; ++ ++ debug("%s\n", __func__); ++ ++ /* Power down PRE-PLL */ ++ inno_update_bits(inno, 0xe0, RK3228_PRE_PLL_POWER_DOWN, ++ RK3228_PRE_PLL_POWER_DOWN); ++ ++ inno_update_bits(inno, 0xe2, RK3228_PRE_PLL_FB_DIV_8_MASK | ++ RK3228_PCLK_VCO_DIV_5_MASK | ++ RK3228_PRE_PLL_PRE_DIV_MASK, ++ RK3228_PRE_PLL_FB_DIV_8(cfg->fbdiv) | ++ RK3228_PCLK_VCO_DIV_5(cfg->vco_div_5_en) | ++ RK3228_PRE_PLL_PRE_DIV(cfg->prediv)); ++ inno_write(inno, 0xe3, RK3228_PRE_PLL_FB_DIV_7_0(cfg->fbdiv)); ++ inno_update_bits(inno, 0xe4, RK3228_PRE_PLL_PCLK_DIV_B_MASK | ++ RK3228_PRE_PLL_PCLK_DIV_A_MASK, ++ RK3228_PRE_PLL_PCLK_DIV_B(cfg->pclk_div_b) | ++ RK3228_PRE_PLL_PCLK_DIV_A(cfg->pclk_div_a)); ++ inno_update_bits(inno, 0xe5, RK3228_PRE_PLL_PCLK_DIV_C_MASK | ++ RK3228_PRE_PLL_PCLK_DIV_D_MASK, ++ RK3228_PRE_PLL_PCLK_DIV_C(cfg->pclk_div_c) | ++ RK3228_PRE_PLL_PCLK_DIV_D(cfg->pclk_div_d)); ++ inno_update_bits(inno, 0xe6, RK3228_PRE_PLL_TMDSCLK_DIV_C_MASK | ++ RK3228_PRE_PLL_TMDSCLK_DIV_A_MASK | ++ RK3228_PRE_PLL_TMDSCLK_DIV_B_MASK, ++ RK3228_PRE_PLL_TMDSCLK_DIV_C(cfg->tmds_div_c) | ++ RK3228_PRE_PLL_TMDSCLK_DIV_A(cfg->tmds_div_a) | ++ RK3228_PRE_PLL_TMDSCLK_DIV_B(cfg->tmds_div_b)); ++ ++ /* Power up PRE-PLL */ ++ inno_update_bits(inno, 0xe0, RK3228_PRE_PLL_POWER_DOWN, 0); ++ ++ /* Wait for PLL lock, up to 100ms*/ ++ for (val = 0; val < 100; val++) { ++ if (inno_read(inno, 0xe8) & RK3228_PRE_PLL_LOCK_STATUS) ++ break; ++ udelay(1000); ++ } ++ if (!(inno_read(inno, 0xe8) & RK3228_PRE_PLL_LOCK_STATUS)) { ++ printf("%s, failed to lock Pre-PLL, left unlocked\n", __func__); ++ return -ETIMEDOUT; ++ } ++ ++ return 0; ++} ++ ++static const struct inno_hdmi_phy_plat_ops rk3228_hdmi_phy_plat_ops = { ++ .init = inno_hdmi_phy_rk3228_init, ++ .power_on = inno_hdmi_phy_rk3228_power_on, ++ .power_off = inno_hdmi_phy_rk3228_power_off, ++ .pre_pll_update = inno_hdmi_phy_rk3228_pre_pll_update, ++ .recalc_rate = inno_hdmi_phy_rk3228_pll_recalc_rate, ++ .clk_is_prepared = inno_hdmi_phy_rk3228_clk_is_prepared, ++ .clk_prepare = inno_hdmi_phy_rk3228_clk_prepare +}; + +static unsigned long inno_hdmi_phy_set_pll(struct phy *phy, @@ -680,10 +893,17 @@ index 0000000000..99cf174214 + struct inno_hdmi_phy *inno = dev_get_priv(phy->dev); + + debug("[PHY] %s: In?\n", __func__); -+ inno_hdmi_phy_clk_prepare(inno); -+ inno_hdmi_phy_clk_is_prepared(inno); ++ ++ if (inno->data->plat_ops->clk_prepare) ++ inno->data->plat_ops->clk_prepare(inno); ++ ++ if (inno->data->plat_ops->clk_is_prepared) ++ inno->data->plat_ops->clk_is_prepared(inno); ++ + inno_hdmi_phy_clk_set_rate(inno, rate); ++ + debug("[PHY] %s: done!\n", __func__); ++ + return 0; +} + @@ -791,8 +1011,18 @@ index 0000000000..99cf174214 + .phy_cfg_table = rk3328_phy_cfg, +}; + ++static const struct inno_hdmi_phy_data rk3228_inno_hdmi_phy_drv_data = { ++ .phy_type = INNO_HDMI_PHY_RK3228, ++ .plat_ops = &rk3228_hdmi_phy_plat_ops, ++ .phy_cfg_table = rk3228_phy_cfg, ++}; ++ +static const struct udevice_id inno_hdmi_phy_ids[] = { + { ++ .compatible = "rockchip,rk3228-hdmi-phy", ++ .data = (ulong)&rk3228_inno_hdmi_phy_drv_data, ++ }, ++ { + .compatible = "rockchip,rk3328-hdmi-phy", + .data = (ulong)&rk3328_inno_hdmi_phy_drv_data, + }, diff --git a/patch/u-boot/v2024.01/general-dwc-otg-fix-var.patch b/patch/u-boot/v2024.01/general-dwc-otg-fix-var.patch new file mode 100644 index 0000000000..1573cdbdce --- /dev/null +++ b/patch/u-boot/v2024.01/general-dwc-otg-fix-var.patch @@ -0,0 +1,30 @@ +From ac3f6f2e9cbe96d11a0db2801699669b2941cd09 Mon Sep 17 00:00:00 2001 +From: Paolo Sabatino +Date: Mon, 29 Apr 2024 16:17:17 +0200 +Subject: [PATCH 1/4] fix borked DWC2 OTG driver + +--- + drivers/usb/gadget/dwc2_udc_otg_phy.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/drivers/usb/gadget/dwc2_udc_otg_phy.c b/drivers/usb/gadget/dwc2_udc_otg_phy.c +index 7f8e9564b9..e87f8b5e47 100644 +--- a/drivers/usb/gadget/dwc2_udc_otg_phy.c ++++ b/drivers/usb/gadget/dwc2_udc_otg_phy.c +@@ -59,12 +59,7 @@ void otg_phy_init(struct dwc2_udc *dev) + writel((readl(&phy->phypwr) &~(OTG_DISABLE_0 | ANALOG_PWRDOWN) + &~FORCE_SUSPEND_0), &phy->phypwr); + +- if (s5p_cpu_id == 0x4412) +- writel((readl(&phy->phyclk) & ~(EXYNOS4X12_ID_PULLUP0 | +- EXYNOS4X12_COMMON_ON_N0)) | EXYNOS4X12_CLK_SEL_24MHZ, +- &phy->phyclk); /* PLL 24Mhz */ +- else +- writel((readl(&phy->phyclk) & ~(ID_PULLUP0 | COMMON_ON_N0)) | ++ writel((readl(&phy->phyclk) & ~(ID_PULLUP0 | COMMON_ON_N0)) | + CLK_SEL_24MHZ, &phy->phyclk); /* PLL 24Mhz */ + + writel((readl(&phy->rstcon) &~(LINK_SW_RST | PHYLNK_SW_RST)) +-- +2.34.1 +