From: Tianling Shen Date: Sat, 11 Oct 2025 09:04:07 +0000 (+0800) Subject: rockchip: backport pending driver/dts updates for rk3528 X-Git-Url: http://git.openwrt.org/?a=commitdiff_plain;h=221e6c845c5770a12b9b0d0b97542813b18129b2;p=openwrt%2Fstaging%2Fxback.git rockchip: backport pending driver/dts updates for rk3528 Backport pending nvmem/thermal/usb updates for rk3528. These patches are not merged by upstream yet but worthy to have here. Signed-off-by: Tianling Shen Link: https://github.com/openwrt/openwrt/pull/20375 Signed-off-by: Hauke Mehrtens --- diff --git a/target/linux/rockchip/patches-6.12/160-01-phy-rockchip-inno-usb2-Simplify-rockchip-usbgrf-handling.patch b/target/linux/rockchip/patches-6.12/160-01-phy-rockchip-inno-usb2-Simplify-rockchip-usbgrf-handling.patch new file mode 100644 index 0000000000..98d0b2c326 --- /dev/null +++ b/target/linux/rockchip/patches-6.12/160-01-phy-rockchip-inno-usb2-Simplify-rockchip-usbgrf-handling.patch @@ -0,0 +1,218 @@ +From 4e7d472b61625804f585035a54364a6620bf803a Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 23 Jul 2025 12:23:00 +0000 +Subject: [PATCH] phy: rockchip: inno-usb2: Simplify rockchip,usbgrf handling + +The logic to decide if usbgrf or grf should be used is more complex than +it needs to be. For RK3568, RV1108 and soon RK3528 we can assign the +rockchip,usbgrf regmap directly to grf instead of doing a usbgrf and grf +dance. + +Simplify the code to only use the grf regmap and handle the logic of +what regmap should be used in driver probe instead. + +The only expected change from this is that RK3528 can be supported +because of an addition of a of_property_present() check. + +Signed-off-by: Jonas Karlman +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 68 +++++-------------- + 1 file changed, 18 insertions(+), 50 deletions(-) + +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -228,7 +228,6 @@ struct rockchip_usb2phy_port { + * struct rockchip_usb2phy - usb2.0 phy driver data. + * @dev: pointer to device. + * @grf: General Register Files regmap. +- * @usbgrf: USB General Register Files regmap. + * @clks: array of phy input clocks. + * @clk480m: clock struct of phy output clk. + * @clk480m_hw: clock struct of phy output clk management. +@@ -246,7 +245,6 @@ struct rockchip_usb2phy_port { + struct rockchip_usb2phy { + struct device *dev; + struct regmap *grf; +- struct regmap *usbgrf; + struct clk_bulk_data *clks; + struct clk *clk480m; + struct clk_hw clk480m_hw; +@@ -261,11 +259,6 @@ struct rockchip_usb2phy { + struct rockchip_usb2phy_port ports[USB2PHY_NUM_PORTS]; + }; + +-static inline struct regmap *get_reg_base(struct rockchip_usb2phy *rphy) +-{ +- return rphy->usbgrf == NULL ? rphy->grf : rphy->usbgrf; +-} +- + static inline int property_enable(struct regmap *base, + const struct usb2phy_reg *reg, bool en) + { +@@ -323,12 +316,11 @@ static int rockchip_usb2phy_clk480m_prep + { + struct rockchip_usb2phy *rphy = + container_of(hw, struct rockchip_usb2phy, clk480m_hw); +- struct regmap *base = get_reg_base(rphy); + int ret; + + /* turn on 480m clk output if it is off */ +- if (!property_enabled(base, &rphy->phy_cfg->clkout_ctl)) { +- ret = property_enable(base, &rphy->phy_cfg->clkout_ctl, true); ++ if (!property_enabled(rphy->grf, &rphy->phy_cfg->clkout_ctl)) { ++ ret = property_enable(rphy->grf, &rphy->phy_cfg->clkout_ctl, true); + if (ret) + return ret; + +@@ -343,19 +335,17 @@ static void rockchip_usb2phy_clk480m_unp + { + struct rockchip_usb2phy *rphy = + container_of(hw, struct rockchip_usb2phy, clk480m_hw); +- struct regmap *base = get_reg_base(rphy); + + /* turn off 480m clk output */ +- property_enable(base, &rphy->phy_cfg->clkout_ctl, false); ++ property_enable(rphy->grf, &rphy->phy_cfg->clkout_ctl, false); + } + + static int rockchip_usb2phy_clk480m_prepared(struct clk_hw *hw) + { + struct rockchip_usb2phy *rphy = + container_of(hw, struct rockchip_usb2phy, clk480m_hw); +- struct regmap *base = get_reg_base(rphy); + +- return property_enabled(base, &rphy->phy_cfg->clkout_ctl); ++ return property_enabled(rphy->grf, &rphy->phy_cfg->clkout_ctl); + } + + static unsigned long +@@ -577,7 +567,6 @@ static int rockchip_usb2phy_power_on(str + { + struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy); + struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent); +- struct regmap *base = get_reg_base(rphy); + int ret; + + dev_dbg(&rport->phy->dev, "port power on\n"); +@@ -589,7 +578,7 @@ static int rockchip_usb2phy_power_on(str + if (ret) + return ret; + +- ret = property_enable(base, &rport->port_cfg->phy_sus, false); ++ ret = property_enable(rphy->grf, &rport->port_cfg->phy_sus, false); + if (ret) { + clk_disable_unprepare(rphy->clk480m); + return ret; +@@ -618,7 +607,6 @@ static int rockchip_usb2phy_power_off(st + { + struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy); + struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent); +- struct regmap *base = get_reg_base(rphy); + int ret; + + dev_dbg(&rport->phy->dev, "port power off\n"); +@@ -626,7 +614,7 @@ static int rockchip_usb2phy_power_off(st + if (rport->suspended) + return 0; + +- ret = property_enable(base, &rport->port_cfg->phy_sus, true); ++ ret = property_enable(rphy->grf, &rport->port_cfg->phy_sus, true); + if (ret) + return ret; + +@@ -790,28 +778,22 @@ static const char *chg_to_string(enum po + static void rockchip_chg_enable_dcd(struct rockchip_usb2phy *rphy, + bool en) + { +- struct regmap *base = get_reg_base(rphy); +- +- property_enable(base, &rphy->phy_cfg->chg_det.rdm_pdwn_en, en); +- property_enable(base, &rphy->phy_cfg->chg_det.idp_src_en, en); ++ property_enable(rphy->grf, &rphy->phy_cfg->chg_det.rdm_pdwn_en, en); ++ property_enable(rphy->grf, &rphy->phy_cfg->chg_det.idp_src_en, en); + } + + static void rockchip_chg_enable_primary_det(struct rockchip_usb2phy *rphy, + bool en) + { +- struct regmap *base = get_reg_base(rphy); +- +- property_enable(base, &rphy->phy_cfg->chg_det.vdp_src_en, en); +- property_enable(base, &rphy->phy_cfg->chg_det.idm_sink_en, en); ++ property_enable(rphy->grf, &rphy->phy_cfg->chg_det.vdp_src_en, en); ++ property_enable(rphy->grf, &rphy->phy_cfg->chg_det.idm_sink_en, en); + } + + static void rockchip_chg_enable_secondary_det(struct rockchip_usb2phy *rphy, + bool en) + { +- struct regmap *base = get_reg_base(rphy); +- +- property_enable(base, &rphy->phy_cfg->chg_det.vdm_src_en, en); +- property_enable(base, &rphy->phy_cfg->chg_det.idp_sink_en, en); ++ property_enable(rphy->grf, &rphy->phy_cfg->chg_det.vdm_src_en, en); ++ property_enable(rphy->grf, &rphy->phy_cfg->chg_det.idp_sink_en, en); + } + + #define CHG_DCD_POLL_TIME (100 * HZ / 1000) +@@ -823,7 +805,6 @@ static void rockchip_chg_detect_work(str + struct rockchip_usb2phy_port *rport = + container_of(work, struct rockchip_usb2phy_port, chg_work.work); + struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent); +- struct regmap *base = get_reg_base(rphy); + bool is_dcd, tmout, vout; + unsigned long delay; + +@@ -834,7 +815,7 @@ static void rockchip_chg_detect_work(str + if (!rport->suspended) + rockchip_usb2phy_power_off(rport->phy); + /* put the controller in non-driving mode */ +- property_enable(base, &rphy->phy_cfg->chg_det.opmode, false); ++ property_enable(rphy->grf, &rphy->phy_cfg->chg_det.opmode, false); + /* Start DCD processing stage 1 */ + rockchip_chg_enable_dcd(rphy, true); + rphy->chg_state = USB_CHG_STATE_WAIT_FOR_DCD; +@@ -897,7 +878,7 @@ static void rockchip_chg_detect_work(str + fallthrough; + case USB_CHG_STATE_DETECTED: + /* put the controller in normal mode */ +- property_enable(base, &rphy->phy_cfg->chg_det.opmode, true); ++ property_enable(rphy->grf, &rphy->phy_cfg->chg_det.opmode, true); + rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work); + dev_dbg(&rport->phy->dev, "charger = %s\n", + chg_to_string(rphy->chg_type)); +@@ -1352,29 +1333,14 @@ static int rockchip_usb2phy_probe(struct + if (!rphy) + return -ENOMEM; + +- if (!dev->parent || !dev->parent->of_node) { ++ if (!dev->parent || !dev->parent->of_node || ++ of_property_present(np, "rockchip,usbgrf")) { + rphy->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,usbgrf"); +- if (IS_ERR(rphy->grf)) { +- dev_err(dev, "failed to locate usbgrf\n"); +- return PTR_ERR(rphy->grf); +- } +- } +- +- else { +- rphy->grf = syscon_node_to_regmap(dev->parent->of_node); +- if (IS_ERR(rphy->grf)) +- return PTR_ERR(rphy->grf); +- } +- +- if (of_device_is_compatible(np, "rockchip,rv1108-usb2phy")) { +- rphy->usbgrf = +- syscon_regmap_lookup_by_phandle(dev->of_node, +- "rockchip,usbgrf"); +- if (IS_ERR(rphy->usbgrf)) +- return PTR_ERR(rphy->usbgrf); + } else { +- rphy->usbgrf = NULL; ++ rphy->grf = syscon_node_to_regmap(dev->parent->of_node); + } ++ if (IS_ERR(rphy->grf)) ++ return PTR_ERR(rphy->grf); + + if (of_property_read_u32_index(np, "reg", 0, ®)) { + dev_err(dev, "the reg property is not assigned in %pOFn node\n", diff --git a/target/linux/rockchip/patches-6.12/160-02-phy-rockchip-inno-usb2-Add-clkout_ctl_phy-support.patch b/target/linux/rockchip/patches-6.12/160-02-phy-rockchip-inno-usb2-Add-clkout_ctl_phy-support.patch new file mode 100644 index 0000000000..eeb79f5a2f --- /dev/null +++ b/target/linux/rockchip/patches-6.12/160-02-phy-rockchip-inno-usb2-Add-clkout_ctl_phy-support.patch @@ -0,0 +1,123 @@ +From 6b767459cf9295f10ee95b8ab78fbce5991132ed Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 23 Jul 2025 12:23:02 +0000 +Subject: [PATCH] phy: rockchip: inno-usb2: Add clkout_ctl_phy support + +The 480m clk is controlled using regs in the PHY address space and not +in the USB GRF address space on e.g. RK3528 and RK3506. + +Add a clkout_ctl_phy usb2phy_reg to handle enable/disable of the 480m +clk on these SoCs. + +Signed-off-by: Jonas Karlman +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 47 +++++++++++++++---- + 1 file changed, 38 insertions(+), 9 deletions(-) + +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -179,6 +179,7 @@ struct rockchip_usb2phy_cfg { + unsigned int num_ports; + int (*phy_tuning)(struct rockchip_usb2phy *rphy); + struct usb2phy_reg clkout_ctl; ++ struct usb2phy_reg clkout_ctl_phy; + const struct rockchip_usb2phy_port_cfg port_cfgs[USB2PHY_NUM_PORTS]; + const struct rockchip_chg_det_reg chg_det; + }; +@@ -228,6 +229,7 @@ struct rockchip_usb2phy_port { + * struct rockchip_usb2phy - usb2.0 phy driver data. + * @dev: pointer to device. + * @grf: General Register Files regmap. ++ * @phy_base: USB PHY regmap. + * @clks: array of phy input clocks. + * @clk480m: clock struct of phy output clk. + * @clk480m_hw: clock struct of phy output clk management. +@@ -245,6 +247,7 @@ struct rockchip_usb2phy_port { + struct rockchip_usb2phy { + struct device *dev; + struct regmap *grf; ++ struct regmap *phy_base; + struct clk_bulk_data *clks; + struct clk *clk480m; + struct clk_hw clk480m_hw; +@@ -312,15 +315,33 @@ static void rockchip_usb2phy_clk_bulk_di + clk_bulk_disable_unprepare(rphy->num_clks, rphy->clks); + } + +-static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw) ++static void ++rockchip_usb2phy_clk480m_clkout_ctl(struct clk_hw *hw, struct regmap **base, ++ const struct usb2phy_reg **clkout_ctl) + { + struct rockchip_usb2phy *rphy = + container_of(hw, struct rockchip_usb2phy, clk480m_hw); ++ ++ if (rphy->phy_cfg->clkout_ctl_phy.enable) { ++ *base = rphy->phy_base; ++ *clkout_ctl = &rphy->phy_cfg->clkout_ctl_phy; ++ } else { ++ *base = rphy->grf; ++ *clkout_ctl = &rphy->phy_cfg->clkout_ctl; ++ } ++} ++ ++static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw) ++{ ++ const struct usb2phy_reg *clkout_ctl; ++ struct regmap *base; + int ret; + ++ rockchip_usb2phy_clk480m_clkout_ctl(hw, &base, &clkout_ctl); ++ + /* turn on 480m clk output if it is off */ +- if (!property_enabled(rphy->grf, &rphy->phy_cfg->clkout_ctl)) { +- ret = property_enable(rphy->grf, &rphy->phy_cfg->clkout_ctl, true); ++ if (!property_enabled(base, clkout_ctl)) { ++ ret = property_enable(base, clkout_ctl, true); + if (ret) + return ret; + +@@ -333,19 +354,23 @@ static int rockchip_usb2phy_clk480m_prep + + static void rockchip_usb2phy_clk480m_unprepare(struct clk_hw *hw) + { +- struct rockchip_usb2phy *rphy = +- container_of(hw, struct rockchip_usb2phy, clk480m_hw); ++ const struct usb2phy_reg *clkout_ctl; ++ struct regmap *base; ++ ++ rockchip_usb2phy_clk480m_clkout_ctl(hw, &base, &clkout_ctl); + + /* turn off 480m clk output */ +- property_enable(rphy->grf, &rphy->phy_cfg->clkout_ctl, false); ++ property_enable(base, clkout_ctl, false); + } + + static int rockchip_usb2phy_clk480m_prepared(struct clk_hw *hw) + { +- struct rockchip_usb2phy *rphy = +- container_of(hw, struct rockchip_usb2phy, clk480m_hw); ++ const struct usb2phy_reg *clkout_ctl; ++ struct regmap *base; ++ ++ rockchip_usb2phy_clk480m_clkout_ctl(hw, &base, &clkout_ctl); + +- return property_enabled(rphy->grf, &rphy->phy_cfg->clkout_ctl); ++ return property_enabled(base, clkout_ctl); + } + + static unsigned long +@@ -1335,9 +1360,13 @@ static int rockchip_usb2phy_probe(struct + + if (!dev->parent || !dev->parent->of_node || + of_property_present(np, "rockchip,usbgrf")) { ++ rphy->phy_base = device_node_to_regmap(np); ++ if (IS_ERR(rphy->phy_base)) ++ return PTR_ERR(rphy->phy_base); + rphy->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,usbgrf"); + } else { + rphy->grf = syscon_node_to_regmap(dev->parent->of_node); ++ rphy->phy_base = rphy->grf; + } + if (IS_ERR(rphy->grf)) + return PTR_ERR(rphy->grf); diff --git a/target/linux/rockchip/patches-6.12/160-03-phy-rockchip-inno-usb2-Add-support-for-RK3528.patch b/target/linux/rockchip/patches-6.12/160-03-phy-rockchip-inno-usb2-Add-support-for-RK3528.patch new file mode 100644 index 0000000000..1a77cbf751 --- /dev/null +++ b/target/linux/rockchip/patches-6.12/160-03-phy-rockchip-inno-usb2-Add-support-for-RK3528.patch @@ -0,0 +1,125 @@ +From 8faac4ef6206a1c771e1c016e205dcee8164d618 Mon Sep 17 00:00:00 2001 +From: Jianwei Zheng +Date: Wed, 23 Jul 2025 12:23:03 +0000 +Subject: [PATCH] phy: rockchip: inno-usb2: Add support for RK3528 + +The RK3528 has a single USB2PHY with a otg and host port. + +Add support for the RK3528 variant of USB2PHY. + +PHY tuning for RK3528: + +- Turn off differential receiver in suspend mode to save power + consumption. + +- Set HS eye-height to 400mV instead of default 450mV. + +- Choose the Tx fs/ls data as linestate from TX driver for otg port + which uses dwc3 controller to improve fs/ls devices compatibility with + long cables. + +This is based on vendor kernel linux-stan-6.1-rkr5 tag. + +Signed-off-by: Jianwei Zheng +Signed-off-by: Jonas Karlman +--- + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 74 +++++++++++++++++++ + 1 file changed, 74 insertions(+) + +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -1519,6 +1519,28 @@ static int rk3128_usb2phy_tuning(struct + BIT(2) << BIT_WRITEABLE_SHIFT | 0); + } + ++static int rk3528_usb2phy_tuning(struct rockchip_usb2phy *rphy) ++{ ++ int ret = 0; ++ ++ /* Turn off otg port differential receiver in suspend mode */ ++ ret |= regmap_write(rphy->phy_base, 0x30, BIT(18) | 0x0000); ++ ++ /* Turn off host port differential receiver in suspend mode */ ++ ret |= regmap_write(rphy->phy_base, 0x430, BIT(18) | 0x0000); ++ ++ /* Set otg port HS eye height to 400mv (default is 450mv) */ ++ ret |= regmap_write(rphy->phy_base, 0x30, GENMASK(22, 20) | 0x0000); ++ ++ /* Set host port HS eye height to 400mv (default is 450mv) */ ++ ret |= regmap_write(rphy->phy_base, 0x430, GENMASK(22, 20) | 0x0000); ++ ++ /* Choose the Tx fs/ls data as linestate from TX driver for otg port */ ++ ret |= regmap_write(rphy->phy_base, 0x94, GENMASK(22, 19) | 0x0018); ++ ++ return ret; ++} ++ + static int rk3576_usb2phy_tuning(struct rockchip_usb2phy *rphy) + { + int ret; +@@ -1901,6 +1923,57 @@ static const struct rockchip_usb2phy_cfg + { /* sentinel */ } + }; + ++static const struct rockchip_usb2phy_cfg rk3528_phy_cfgs[] = { ++ { ++ .reg = 0xffdf0000, ++ .num_ports = 2, ++ .phy_tuning = rk3528_usb2phy_tuning, ++ .clkout_ctl_phy = { 0x041c, 7, 2, 0, 0x27 }, ++ .port_cfgs = { ++ [USB2PHY_PORT_OTG] = { ++ .phy_sus = { 0x004c, 8, 0, 0, 0x1d1 }, ++ .bvalid_det_en = { 0x0074, 3, 2, 0, 3 }, ++ .bvalid_det_st = { 0x0078, 3, 2, 0, 3 }, ++ .bvalid_det_clr = { 0x007c, 3, 2, 0, 3 }, ++ .idfall_det_en = { 0x0074, 5, 5, 0, 1 }, ++ .idfall_det_st = { 0x0078, 5, 5, 0, 1 }, ++ .idfall_det_clr = { 0x007c, 5, 5, 0, 1 }, ++ .idrise_det_en = { 0x0074, 4, 4, 0, 1 }, ++ .idrise_det_st = { 0x0078, 4, 4, 0, 1 }, ++ .idrise_det_clr = { 0x007c, 4, 4, 0, 1 }, ++ .ls_det_en = { 0x0074, 0, 0, 0, 1 }, ++ .ls_det_st = { 0x0078, 0, 0, 0, 1 }, ++ .ls_det_clr = { 0x007c, 0, 0, 0, 1 }, ++ .utmi_avalid = { 0x006c, 1, 1, 0, 1 }, ++ .utmi_bvalid = { 0x006c, 0, 0, 0, 1 }, ++ .utmi_id = { 0x006c, 6, 6, 0, 1 }, ++ .utmi_ls = { 0x006c, 5, 4, 0, 1 }, ++ }, ++ [USB2PHY_PORT_HOST] = { ++ .phy_sus = { 0x005c, 8, 0, 0x1d2, 0x1d1 }, ++ .ls_det_en = { 0x0090, 0, 0, 0, 1 }, ++ .ls_det_st = { 0x0094, 0, 0, 0, 1 }, ++ .ls_det_clr = { 0x0098, 0, 0, 0, 1 }, ++ .utmi_ls = { 0x006c, 13, 12, 0, 1 }, ++ .utmi_hstdet = { 0x006c, 15, 15, 0, 1 }, ++ } ++ }, ++ .chg_det = { ++ .opmode = { 0x004c, 3, 0, 5, 1 }, ++ .cp_det = { 0x006c, 19, 19, 0, 1 }, ++ .dcp_det = { 0x006c, 18, 18, 0, 1 }, ++ .dp_det = { 0x006c, 20, 20, 0, 1 }, ++ .idm_sink_en = { 0x0058, 1, 1, 0, 1 }, ++ .idp_sink_en = { 0x0058, 0, 0, 0, 1 }, ++ .idp_src_en = { 0x0058, 2, 2, 0, 1 }, ++ .rdm_pdwn_en = { 0x0058, 3, 3, 0, 1 }, ++ .vdm_src_en = { 0x0058, 5, 5, 0, 1 }, ++ .vdp_src_en = { 0x0058, 4, 4, 0, 1 }, ++ }, ++ }, ++ { /* sentinel */ } ++}; ++ + static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = { + { + .reg = 0xfe8a0000, +@@ -2219,6 +2292,7 @@ static const struct of_device_id rockchi + { .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs }, + { .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs }, + { .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs }, ++ { .compatible = "rockchip,rk3528-usb2phy", .data = &rk3528_phy_cfgs }, + { .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs }, + { .compatible = "rockchip,rk3576-usb2phy", .data = &rk3576_phy_cfgs }, + { .compatible = "rockchip,rk3588-usb2phy", .data = &rk3588_phy_cfgs }, diff --git a/target/linux/rockchip/patches-6.12/160-04-phy-rockchip-naneng-combphy-Fix-PCIe-L1ss-support.patch b/target/linux/rockchip/patches-6.12/160-04-phy-rockchip-naneng-combphy-Fix-PCIe-L1ss-support.patch new file mode 100644 index 0000000000..4a55a2d18a --- /dev/null +++ b/target/linux/rockchip/patches-6.12/160-04-phy-rockchip-naneng-combphy-Fix-PCIe-L1ss-support.patch @@ -0,0 +1,45 @@ +From: Shawn Lin +To: Vinod Koul +Cc: Kishon Vijay Abraham I , + Heiko Stuebner , Yao Zi , + linux-phy@lists.infradead.org, + linux-rockchip@lists.infradead.org, + Shawn Lin +Subject: [PATCH] phy: rockchip: naneng-combphy: Fix PCIe L1ss support +Date: Thu, 13 Nov 2025 11:00:28 +0800 [thread overview] +Message-ID: <1763002828-212219-1-git-send-email-shawn.lin@rock-chips.com> (raw) + +Need to control the delay PLL turnoff time if PCIe works on +L1 PM substates. + +Fixes: bbcca4fac873 ("phy: rockchip: naneng-combphy: Add RK3528 support") +Signed-off-by: Shawn Lin +--- + + drivers/phy/rockchip/phy-rockchip-naneng-combphy.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c ++++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +@@ -21,6 +21,9 @@ + #define REF_CLOCK_100MHz (100 * HZ_PER_MHZ) + + /* RK3528 COMBO PHY REG */ ++#define RK3528_PHYREG5 0x14 ++#define RK3528_PHYREG5_GATE_TX_PCK_SEL BIT(3) ++#define RK3528_PHYREG5_GATE_TX_PCK_DLY_PLL_OFF BIT(3) + #define RK3528_PHYREG6 0x18 + #define RK3528_PHYREG6_PLL_KVCO GENMASK(12, 10) + #define RK3528_PHYREG6_PLL_KVCO_VALUE 0x2 +@@ -504,6 +507,11 @@ static int rk3528_combphy_cfg(struct roc + case REF_CLOCK_100MHz: + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); + if (priv->type == PHY_TYPE_PCIE) { ++ /* Gate_tx_pck_sel length select for L1ss support */ ++ rockchip_combphy_updatel(priv, RK3528_PHYREG5_GATE_TX_PCK_SEL, ++ RK3528_PHYREG5_GATE_TX_PCK_DLY_PLL_OFF, ++ RK3528_PHYREG5); ++ + /* PLL KVCO tuning fine */ + val = FIELD_PREP(RK3528_PHYREG6_PLL_KVCO, RK3528_PHYREG6_PLL_KVCO_VALUE); + rockchip_combphy_updatel(priv, RK3528_PHYREG6_PLL_KVCO, val, diff --git a/target/linux/rockchip/patches-6.12/161-01-thermal-rockchip-Change-to-use-bulk-clks.patch b/target/linux/rockchip/patches-6.12/161-01-thermal-rockchip-Change-to-use-bulk-clks.patch new file mode 100644 index 0000000000..a18b9a0d60 --- /dev/null +++ b/target/linux/rockchip/patches-6.12/161-01-thermal-rockchip-Change-to-use-bulk-clks.patch @@ -0,0 +1,83 @@ +From 8d3a5547b908e371998376be106fe2b5cd6aacd4 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Thu, 13 Mar 2025 17:49:33 +0000 +Subject: [PATCH] thermal: rockchip: Change to use bulk clks + +Signed-off-by: Jonas Karlman +--- + drivers/thermal/rockchip_thermal.c | 33 ++++++++++-------------------- + 1 file changed, 11 insertions(+), 22 deletions(-) + +--- a/drivers/thermal/rockchip_thermal.c ++++ b/drivers/thermal/rockchip_thermal.c +@@ -140,8 +140,8 @@ struct rockchip_thermal_sensor { + * @pdev: platform device of thermal + * @reset: the reset controller of tsadc + * @sensors: array of thermal sensors +- * @clk: the controller clock is divided by the exteral 24MHz +- * @pclk: the advanced peripherals bus clock ++ * @clks: array of clks, e.g. controller and advanced peripherals bus clock ++ * @num_clks: the number of clks + * @grf: the general register file will be used to do static set by software + * @regs: the base address of tsadc controller + * @trim_base: major component of sensor trim value, in Celsius +@@ -159,8 +159,8 @@ struct rockchip_thermal_data { + + struct rockchip_thermal_sensor *sensors; + +- struct clk *clk; +- struct clk *pclk; ++ struct clk_bulk_data *clks; ++ int num_clks; + + struct regmap *grf; + void __iomem *regs; +@@ -1741,15 +1741,11 @@ static int rockchip_thermal_probe(struct + return dev_err_probe(&pdev->dev, PTR_ERR(thermal->reset), + "failed to get tsadc reset.\n"); + +- thermal->clk = devm_clk_get_enabled(&pdev->dev, "tsadc"); +- if (IS_ERR(thermal->clk)) +- return dev_err_probe(&pdev->dev, PTR_ERR(thermal->clk), +- "failed to get tsadc clock.\n"); +- +- thermal->pclk = devm_clk_get_enabled(&pdev->dev, "apb_pclk"); +- if (IS_ERR(thermal->pclk)) +- return dev_err_probe(&pdev->dev, PTR_ERR(thermal->pclk), +- "failed to get apb_pclk clock.\n"); ++ thermal->num_clks = devm_clk_bulk_get_all_enabled(&pdev->dev, ++ &thermal->clks); ++ if (thermal->num_clks < 0) ++ return dev_err_probe(&pdev->dev, thermal->num_clks, ++ "failed to get clocks.\n"); + + rockchip_thermal_reset_controller(thermal->reset); + +@@ -1831,8 +1827,7 @@ static int __maybe_unused rockchip_therm + + thermal->chip->control(thermal->regs, false); + +- clk_disable(thermal->pclk); +- clk_disable(thermal->clk); ++ clk_bulk_disable(thermal->num_clks, thermal->clks); + + pinctrl_pm_select_sleep_state(dev); + +@@ -1848,16 +1843,10 @@ static int __maybe_unused rockchip_therm + int error; + int i; + +- error = clk_enable(thermal->clk); ++ error = clk_bulk_enable(thermal->num_clks, thermal->clks); + if (error) + return error; + +- error = clk_enable(thermal->pclk); +- if (error) { +- clk_disable(thermal->clk); +- return error; +- } +- + rockchip_thermal_reset_controller(thermal->reset); + + tsadc->initialize(thermal->grf, thermal->regs, thermal->tshut_polarity); diff --git a/target/linux/rockchip/patches-6.12/161-02-thermal-rockchip-Add-support-for-RK3528.patch b/target/linux/rockchip/patches-6.12/161-02-thermal-rockchip-Add-support-for-RK3528.patch new file mode 100644 index 0000000000..cf070b7cd2 --- /dev/null +++ b/target/linux/rockchip/patches-6.12/161-02-thermal-rockchip-Add-support-for-RK3528.patch @@ -0,0 +1,199 @@ +From ddd86340a007963e8e893555d64f66b63a174ff7 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Thu, 13 Mar 2025 22:51:45 +0000 +Subject: [PATCH] thermal: rockchip: Add support for RK3528 + +Signed-off-by: Jonas Karlman +--- + drivers/thermal/rockchip_thermal.c | 117 +++++++++++++++++++++++++++++ + 1 file changed, 117 insertions(+) + +--- a/drivers/thermal/rockchip_thermal.c ++++ b/drivers/thermal/rockchip_thermal.c +@@ -206,6 +206,7 @@ struct rockchip_thermal_data { + #define TSADCV2_AUTO_PERIOD_HT 0x6c + #define TSADCV3_AUTO_PERIOD 0x154 + #define TSADCV3_AUTO_PERIOD_HT 0x158 ++#define TSADCV9_Q_MAX 0x210 + + #define TSADCV2_AUTO_EN BIT(0) + #define TSADCV2_AUTO_EN_MASK BIT(16) +@@ -216,6 +217,7 @@ struct rockchip_thermal_data { + #define TSADCV2_AUTO_TSHUT_POLARITY_MASK BIT(24) + + #define TSADCV3_AUTO_Q_SEL_EN BIT(1) ++#define TSADCV3_AUTO_Q_SEL_EN_MASK BIT(17) + + #define TSADCV2_INT_SRC_EN(chn) BIT(chn) + #define TSADCV2_INT_SRC_EN_MASK(chn) BIT(16 + (chn)) +@@ -229,6 +231,7 @@ struct rockchip_thermal_data { + #define TSADCV2_DATA_MASK 0xfff + #define TSADCV3_DATA_MASK 0x3ff + #define TSADCV4_DATA_MASK 0x1ff ++#define TSADCV5_DATA_MASK 0x7ff + + #define TSADCV2_HIGHT_INT_DEBOUNCE_COUNT 4 + #define TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT 4 +@@ -241,6 +244,9 @@ struct rockchip_thermal_data { + #define TSADCV5_AUTO_PERIOD_HT_TIME 1622 /* 2.5ms */ + #define TSADCV6_AUTO_PERIOD_TIME 5000 /* 2.5ms */ + #define TSADCV6_AUTO_PERIOD_HT_TIME 5000 /* 2.5ms */ ++#define TSADCV7_AUTO_PERIOD_TIME 3000 /* 2.5ms */ ++#define TSADCV7_AUTO_PERIOD_HT_TIME 3000 /* 2.5ms */ ++#define TSADCV3_Q_MAX_VAL 0x7ff /* 11bit 2047 */ + + #define TSADCV2_USER_INTER_PD_SOC 0x340 /* 13 clocks */ + #define TSADCV5_USER_INTER_PD_SOC 0xfc0 /* 97us, at least 90us */ +@@ -251,6 +257,8 @@ struct rockchip_thermal_data { + + #define PX30_GRF_SOC_CON2 0x0408 + ++#define RK3528_GRF_TSADC_CON 0x0030 ++ + #define RK3568_GRF_TSADC_CON 0x0600 + #define RK3568_GRF_TSADC_ANA_REG0 (0x10001 << 0) + #define RK3568_GRF_TSADC_ANA_REG1 (0x10001 << 1) +@@ -522,6 +530,45 @@ static const struct tsadc_table rk3399_c + {TSADCV3_DATA_MASK, 125000}, + }; + ++static const struct tsadc_table rk3528_code_table[] = { ++ {0, -40000}, ++ {1410, -40000}, ++ {1419, -35000}, ++ {1428, -30000}, ++ {1436, -25000}, ++ {1445, -20000}, ++ {1454, -15000}, ++ {1463, -10000}, ++ {1471, -5000}, ++ {1480, 0}, ++ {1489, 5000}, ++ {1498, 10000}, ++ {1506, 15000}, ++ {1515, 20000}, ++ {1524, 25000}, ++ {1533, 30000}, ++ {1541, 35000}, ++ {1550, 40000}, ++ {1558, 45000}, ++ {1567, 50000}, ++ {1575, 55000}, ++ {1584, 60000}, ++ {1593, 65000}, ++ {1602, 70000}, ++ {1610, 75000}, ++ {1619, 80000}, ++ {1628, 85000}, ++ {1637, 90000}, ++ {1646, 95000}, ++ {1654, 100000}, ++ {1663, 105000}, ++ {1672, 110000}, ++ {1680, 115000}, ++ {1689, 120000}, ++ {1697, 125000}, ++ {TSADCV5_DATA_MASK, 125000}, ++}; ++ + static const struct tsadc_table rk3568_code_table[] = { + {0, -40000}, + {1584, -40000}, +@@ -859,6 +906,40 @@ static void rk_tsadcv8_initialize(struct + regs + TSADCV2_AUTO_CON); + } + ++static void rk_tsadcv11_initialize(struct regmap *grf, void __iomem *regs, ++ enum tshut_polarity tshut_polarity) ++{ ++ writel_relaxed(TSADCV7_AUTO_PERIOD_TIME, ++ regs + TSADCV3_AUTO_PERIOD); ++ writel_relaxed(TSADCV7_AUTO_PERIOD_HT_TIME, ++ regs + TSADCV3_AUTO_PERIOD_HT); ++ writel_relaxed(TSADCV2_HIGHT_INT_DEBOUNCE_COUNT, ++ regs + TSADCV3_HIGHT_INT_DEBOUNCE); ++ writel_relaxed(TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT, ++ regs + TSADCV3_HIGHT_TSHUT_DEBOUNCE); ++ writel_relaxed(TSADCV3_Q_MAX_VAL, ++ regs + TSADCV9_Q_MAX); ++ writel_relaxed(TSADCV3_AUTO_Q_SEL_EN | TSADCV3_AUTO_Q_SEL_EN_MASK, ++ regs + TSADCV2_AUTO_CON); ++ ++ if (tshut_polarity == TSHUT_HIGH_ACTIVE) ++ writel_relaxed(TSADCV2_AUTO_TSHUT_POLARITY_HIGH | ++ TSADCV2_AUTO_TSHUT_POLARITY_MASK, ++ regs + TSADCV2_AUTO_CON); ++ else ++ writel_relaxed(TSADCV2_AUTO_TSHUT_POLARITY_MASK, ++ regs + TSADCV2_AUTO_CON); ++ ++ if (!IS_ERR(grf)) { ++ regmap_write(grf, RK3528_GRF_TSADC_CON, RK3568_GRF_TSADC_TSEN); ++ udelay(15); ++ regmap_write(grf, RK3528_GRF_TSADC_CON, RK3568_GRF_TSADC_ANA_REG0); ++ regmap_write(grf, RK3528_GRF_TSADC_CON, RK3568_GRF_TSADC_ANA_REG1); ++ regmap_write(grf, RK3528_GRF_TSADC_CON, RK3568_GRF_TSADC_ANA_REG2); ++ usleep_range(100, 200); ++ } ++} ++ + static void rk_tsadcv2_irq_ack(void __iomem *regs) + { + u32 val; +@@ -1094,6 +1175,15 @@ static int rk_tsadcv2_get_trim_code(cons + return code - base_code; + } + ++static int rk_tsadcv3_get_trim_code(const struct chip_tsadc_table *table, ++ int code, int trim_base, int trim_base_frac) ++{ ++ int temp = trim_base * 1000 + trim_base_frac * 100; ++ u32 base_code = rk_tsadcv2_temp_to_code(table, temp); ++ ++ return (TSADCV3_Q_MAX_VAL - code) - base_code; ++} ++ + static const struct rockchip_tsadc_chip px30_tsadc_data = { + /* cpu, gpu */ + .chn_offset = 0, +@@ -1292,6 +1382,29 @@ static const struct rockchip_tsadc_chip + }, + }; + ++static const struct rockchip_tsadc_chip rk3528_tsadc_data = { ++ /* soc */ ++ .chn_offset = 0, ++ .chn_num = 1, /* one channel for tsadc */ ++ .tshut_mode = TSHUT_MODE_CRU, /* default TSHUT via CRU */ ++ .tshut_temp = 95000, ++ .initialize = rk_tsadcv11_initialize, ++ .irq_ack = rk_tsadcv4_irq_ack, ++ .control = rk_tsadcv4_control, ++ .get_temp = rk_tsadcv4_get_temp, ++ .set_alarm_temp = rk_tsadcv3_alarm_temp, ++ .set_tshut_temp = rk_tsadcv3_tshut_temp, ++ .set_tshut_mode = rk_tsadcv4_tshut_mode, ++ .get_trim_code = rk_tsadcv3_get_trim_code, ++ .trim_slope = 574, ++ .table = { ++ .id = rk3528_code_table, ++ .length = ARRAY_SIZE(rk3528_code_table), ++ .data_mask = TSADCV5_DATA_MASK, ++ .mode = ADC_INCREMENT, ++ }, ++}; ++ + static const struct rockchip_tsadc_chip rk3568_tsadc_data = { + /* cpu, gpu */ + .chn_offset = 0, +@@ -1396,6 +1509,10 @@ static const struct of_device_id of_rock + .data = (void *)&rk3399_tsadc_data, + }, + { ++ .compatible = "rockchip,rk3528-tsadc", ++ .data = (void *)&rk3528_tsadc_data, ++ }, ++ { + .compatible = "rockchip,rk3568-tsadc", + .data = (void *)&rk3568_tsadc_data, + }, diff --git a/target/linux/rockchip/patches-6.12/162-01-nvmem-rockchip-otp-Handle-internal-word_size-in-main.patch b/target/linux/rockchip/patches-6.12/162-01-nvmem-rockchip-otp-Handle-internal-word_size-in-main.patch new file mode 100644 index 0000000000..c339e6144d --- /dev/null +++ b/target/linux/rockchip/patches-6.12/162-01-nvmem-rockchip-otp-Handle-internal-word_size-in-main.patch @@ -0,0 +1,172 @@ +From 7f6f8fc3ee62f6eb633320c7989d4ba502787e3c Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 16 Mar 2025 19:18:58 +0000 +Subject: [PATCH] nvmem: rockchip-otp: Handle internal word_size in main + reg_read op + +Rockchip SoCs RK3576 and RK3588 read data from the OTP using 32-bit +words instead of normal 8-bit bytes. Similar RK3506, RK3528, RK3562 and +RK3568 will read data from OTP using 16-bit words. + +The nvmem core stride and word_size cannot fully be used as cells is not +always aligned. Continue to report a stride=1 and word_size=1 in +nvmem_config and instead handle use of SoC specific word_size internally +in the driver. + +Move current SoC specific word_size handling from the RK3588 read_reg +operation to the main read_reg operation to help simplify the SoC +specific read_reg operation and allow code reuse in a future RK3568 +reg_read operation. + +Signed-off-by: Jonas Karlman +Reviewed-by: Heiko Stuebner +Tested-by: Heiko Stuebner +--- + drivers/nvmem/rockchip-otp.c | 72 ++++++++++++++++++++---------------- + 1 file changed, 40 insertions(+), 32 deletions(-) + +--- a/drivers/nvmem/rockchip-otp.c ++++ b/drivers/nvmem/rockchip-otp.c +@@ -59,7 +59,6 @@ + #define RK3588_OTPC_AUTO_EN 0x08 + #define RK3588_OTPC_INT_ST 0x84 + #define RK3588_OTPC_DOUT0 0x20 +-#define RK3588_NBYTES 4 + #define RK3588_BURST_NUM 1 + #define RK3588_BURST_SHIFT 8 + #define RK3588_ADDR_SHIFT 16 +@@ -69,6 +68,7 @@ + struct rockchip_data { + int size; + int read_offset; ++ int word_size; + const char * const *clks; + int num_clks; + nvmem_reg_read_t reg_read; +@@ -185,48 +185,28 @@ read_end: + } + + static int rk3588_otp_read(void *context, unsigned int offset, +- void *val, size_t bytes) ++ void *val, size_t count) + { + struct rockchip_otp *otp = context; +- unsigned int addr_start, addr_end, addr_len; +- int ret, i = 0; +- u32 data; +- u8 *buf; +- +- addr_start = round_down(offset, RK3588_NBYTES) / RK3588_NBYTES; +- addr_end = round_up(offset + bytes, RK3588_NBYTES) / RK3588_NBYTES; +- addr_len = addr_end - addr_start; +- addr_start += otp->data->read_offset / RK3588_NBYTES; +- +- buf = kzalloc(array_size(addr_len, RK3588_NBYTES), GFP_KERNEL); +- if (!buf) +- return -ENOMEM; ++ u32 *buf = val; ++ int ret; + +- while (addr_len--) { +- writel((addr_start << RK3588_ADDR_SHIFT) | ++ while (count--) { ++ writel((offset++ << RK3588_ADDR_SHIFT) | + (RK3588_BURST_NUM << RK3588_BURST_SHIFT), + otp->base + RK3588_OTPC_AUTO_CTRL); + writel(RK3588_AUTO_EN, otp->base + RK3588_OTPC_AUTO_EN); + + ret = rockchip_otp_wait_status(otp, RK3588_OTPC_INT_ST, + RK3588_RD_DONE); +- if (ret < 0) { ++ if (ret) { + dev_err(otp->dev, "timeout during read setup\n"); +- goto read_end; ++ return ret; + } + +- data = readl(otp->base + RK3588_OTPC_DOUT0); +- memcpy(&buf[i], &data, RK3588_NBYTES); +- +- i += RK3588_NBYTES; +- addr_start++; ++ *buf++ = readl(otp->base + RK3588_OTPC_DOUT0); + } + +- memcpy(val, buf + offset % RK3588_NBYTES, bytes); +- +-read_end: +- kfree(buf); +- + return ret; + } + +@@ -234,7 +214,7 @@ static int rockchip_otp_read(void *conte + void *val, size_t bytes) + { + struct rockchip_otp *otp = context; +- int ret; ++ int ret, word_size; + + if (!otp->data || !otp->data->reg_read) + return -EINVAL; +@@ -245,8 +225,34 @@ static int rockchip_otp_read(void *conte + return ret; + } + +- ret = otp->data->reg_read(context, offset, val, bytes); ++ offset += otp->data->read_offset; ++ word_size = otp->data->word_size; ++ ++ if (word_size > 1) { ++ unsigned int addr_start, addr_end; ++ size_t count; ++ u8 *buf; ++ ++ addr_start = offset / word_size; ++ addr_end = DIV_ROUND_UP(offset + bytes, word_size); ++ count = addr_end - addr_start; ++ ++ buf = kzalloc(array_size(count, word_size), GFP_KERNEL); ++ if (!buf) { ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ ret = otp->data->reg_read(context, addr_start, buf, count); ++ if (!ret) ++ memcpy(val, buf + (offset % word_size), bytes); ++ ++ kfree(buf); ++ } else { ++ ret = otp->data->reg_read(context, offset, val, bytes); ++ } + ++err: + clk_bulk_disable_unprepare(otp->data->num_clks, otp->clks); + + return ret; +@@ -259,7 +265,7 @@ static struct nvmem_config otp_config = + .type = NVMEM_TYPE_OTP, + .read_only = true, + .stride = 1, +- .word_size = 1, ++ .word_size = sizeof(u8), + .reg_read = rockchip_otp_read, + }; + +@@ -277,6 +283,7 @@ static const struct rockchip_data px30_d + static const struct rockchip_data rk3576_data = { + .size = 0x100, + .read_offset = 0x700, ++ .word_size = sizeof(u32), + .clks = px30_otp_clocks, + .num_clks = ARRAY_SIZE(px30_otp_clocks), + .reg_read = rk3588_otp_read, +@@ -289,6 +296,7 @@ static const char * const rk3588_otp_clo + static const struct rockchip_data rk3588_data = { + .size = 0x400, + .read_offset = 0xc00, ++ .word_size = sizeof(u32), + .clks = rk3588_otp_clocks, + .num_clks = ARRAY_SIZE(rk3588_otp_clocks), + .reg_read = rk3588_otp_read, diff --git a/target/linux/rockchip/patches-6.12/162-02-nvmem-rockchip-otp-Add-support-for-RK3568.patch b/target/linux/rockchip/patches-6.12/162-02-nvmem-rockchip-otp-Add-support-for-RK3568.patch new file mode 100644 index 0000000000..98c3a31334 --- /dev/null +++ b/target/linux/rockchip/patches-6.12/162-02-nvmem-rockchip-otp-Add-support-for-RK3568.patch @@ -0,0 +1,115 @@ +From 24ddbf99c76a352cc1931ccb5118bca0656034b8 Mon Sep 17 00:00:00 2001 +From: Finley Xiao +Date: Tue, 15 Apr 2025 18:32:02 +0800 +Subject: [PATCH] nvmem: rockchip-otp: Add support for RK3568 + +This adds the necessary data for handling otp the rk3568. + +Signed-off-by: Finley Xiao +Signed-off-by: Kever Yang +Reviewed-by: Heiko Stuebner +Tested-by: Heiko Stuebner +Signed-off-by: Jonas Karlman +--- + drivers/nvmem/rockchip-otp.c | 69 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 69 insertions(+) + +--- a/drivers/nvmem/rockchip-otp.c ++++ b/drivers/nvmem/rockchip-otp.c +@@ -27,6 +27,7 @@ + #define OTPC_USER_CTRL 0x0100 + #define OTPC_USER_ADDR 0x0104 + #define OTPC_USER_ENABLE 0x0108 ++#define OTPC_USER_QP 0x0120 + #define OTPC_USER_Q 0x0124 + #define OTPC_INT_STATUS 0x0304 + #define OTPC_SBPI_CMD0_OFFSET 0x1000 +@@ -184,6 +185,58 @@ read_end: + return ret; + } + ++static int rk3568_otp_read(void *context, unsigned int offset, void *val, ++ size_t count) ++{ ++ struct rockchip_otp *otp = context; ++ u16 *buf = val; ++ u32 otp_qp; ++ int ret; ++ ++ ret = rockchip_otp_reset(otp); ++ if (ret) { ++ dev_err(otp->dev, "failed to reset otp phy\n"); ++ return ret; ++ } ++ ++ ret = rockchip_otp_ecc_enable(otp, true); ++ if (ret) { ++ dev_err(otp->dev, "rockchip_otp_ecc_enable err\n"); ++ return ret; ++ } ++ ++ writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); ++ udelay(5); ++ ++ while (count--) { ++ writel(offset++ | OTPC_USER_ADDR_MASK, ++ otp->base + OTPC_USER_ADDR); ++ writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK, ++ otp->base + OTPC_USER_ENABLE); ++ ++ ret = rockchip_otp_wait_status(otp, OTPC_INT_STATUS, ++ OTPC_USER_DONE); ++ if (ret) { ++ dev_err(otp->dev, "timeout during read setup\n"); ++ goto read_end; ++ } ++ ++ otp_qp = readl(otp->base + OTPC_USER_QP); ++ if (((otp_qp & 0xc0) == 0xc0) || (otp_qp & 0x20)) { ++ ret = -EIO; ++ dev_err(otp->dev, "ecc check error during read setup\n"); ++ goto read_end; ++ } ++ ++ *buf++ = readl(otp->base + OTPC_USER_Q); ++ } ++ ++read_end: ++ writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); ++ ++ return ret; ++} ++ + static int rk3588_otp_read(void *context, unsigned int offset, + void *val, size_t count) + { +@@ -280,6 +333,18 @@ static const struct rockchip_data px30_d + .reg_read = px30_otp_read, + }; + ++static const char * const rk3568_otp_clocks[] = { ++ "otp", "apb_pclk", "phy", "sbpi", ++}; ++ ++static const struct rockchip_data rk3568_data = { ++ .size = 0x80, ++ .word_size = sizeof(u16), ++ .clks = rk3568_otp_clocks, ++ .num_clks = ARRAY_SIZE(rk3568_otp_clocks), ++ .reg_read = rk3568_otp_read, ++}; ++ + static const struct rockchip_data rk3576_data = { + .size = 0x100, + .read_offset = 0x700, +@@ -312,6 +377,10 @@ static const struct of_device_id rockchi + .data = &px30_data, + }, + { ++ .compatible = "rockchip,rk3568-otp", ++ .data = &rk3568_data, ++ }, ++ { + .compatible = "rockchip,rk3576-otp", + .data = &rk3576_data, + }, diff --git a/target/linux/rockchip/patches-6.12/162-03-nvmem-rockchip-otp-Add-support-for-RK3528.patch b/target/linux/rockchip/patches-6.12/162-03-nvmem-rockchip-otp-Add-support-for-RK3528.patch new file mode 100644 index 0000000000..eed7271c57 --- /dev/null +++ b/target/linux/rockchip/patches-6.12/162-03-nvmem-rockchip-otp-Add-support-for-RK3528.patch @@ -0,0 +1,45 @@ +From 249b07e24d3d1d47b7ec23d5f09a56837b66d7f5 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 16 Mar 2025 00:05:45 +0000 +Subject: [PATCH] nvmem: rockchip-otp: Add support for RK3528 + +Add support for the OTP controller in RK3528. The OTPC is similar to the +OTPC in RK3562 and RK3568, exept for a missing phy clock and reset. + +Signed-off-by: Jonas Karlman +--- + drivers/nvmem/rockchip-otp.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +--- a/drivers/nvmem/rockchip-otp.c ++++ b/drivers/nvmem/rockchip-otp.c +@@ -333,6 +333,18 @@ static const struct rockchip_data px30_d + .reg_read = px30_otp_read, + }; + ++static const char * const rk3528_otp_clocks[] = { ++ "otp", "apb_pclk", "sbpi", ++}; ++ ++static const struct rockchip_data rk3528_data = { ++ .size = 0x80, ++ .word_size = sizeof(u16), ++ .clks = rk3528_otp_clocks, ++ .num_clks = ARRAY_SIZE(rk3528_otp_clocks), ++ .reg_read = rk3568_otp_read, ++}; ++ + static const char * const rk3568_otp_clocks[] = { + "otp", "apb_pclk", "phy", "sbpi", + }; +@@ -377,6 +389,10 @@ static const struct of_device_id rockchi + .data = &px30_data, + }, + { ++ .compatible = "rockchip,rk3528-otp", ++ .data = &rk3528_data, ++ }, ++ { + .compatible = "rockchip,rk3568-otp", + .data = &rk3568_data, + }, diff --git a/target/linux/rockchip/patches-6.12/163-01-arm64-dts-rockchip-Enable-OTP-controller-for-RK3528.patch b/target/linux/rockchip/patches-6.12/163-01-arm64-dts-rockchip-Enable-OTP-controller-for-RK3528.patch new file mode 100644 index 0000000000..ebd710c764 --- /dev/null +++ b/target/linux/rockchip/patches-6.12/163-01-arm64-dts-rockchip-Enable-OTP-controller-for-RK3528.patch @@ -0,0 +1,71 @@ +From 8a50a4471e4b0db33a74c01229a7ad386918344b Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 16 Mar 2025 00:06:43 +0000 +Subject: [PATCH] arm64: dts: rockchip: Enable OTP controller for RK3528 + +Enable the One Time Programmable Controller (OTPC) in RK3528 and add +an initial nvmem fixed layout. + +Signed-off-by: Jonas Karlman +--- + arch/arm64/boot/dts/rockchip/rk3528.dtsi | 49 ++++++++++++++++++++++++ + 1 file changed, 49 insertions(+) + +--- a/arch/arm64/boot/dts/rockchip/rk3528.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3528.dtsi +@@ -1190,6 +1190,55 @@ + status = "disabled"; + }; + ++ otp: nvmem@ffce0000 { ++ compatible = "rockchip,rk3528-otp"; ++ reg = <0x0 0xffce0000 0x0 0x4000>; ++ clocks = <&cru CLK_USER_OTPC_NS>, ++ <&cru PCLK_OTPC_NS>, ++ <&cru CLK_SBPI_OTPC_NS>; ++ clock-names = "otp", "apb_pclk", "sbpi"; ++ resets = <&cru SRST_USER_OTPC_NS>, ++ <&cru SRST_P_OTPC_NS>, ++ <&cru SRST_SBPI_OTPC_NS>; ++ reset-names = "otp", "apb", "sbpi"; ++ ++ nvmem-layout { ++ compatible = "fixed-layout"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ cpu_code: cpu-code@2 { ++ reg = <0x02 0x2>; ++ }; ++ ++ otp_cpu_version: cpu-version@8 { ++ reg = <0x08 0x1>; ++ bits = <3 3>; ++ }; ++ ++ otp_id: id@a { ++ reg = <0x0a 0x10>; ++ }; ++ ++ cpu_leakage: cpu-leakage@1a { ++ reg = <0x1a 0x1>; ++ }; ++ ++ logic_leakage: logic-leakage@1b { ++ reg = <0x1b 0x1>; ++ }; ++ ++ gpu_leakage: gpu-leakage@1c { ++ reg = <0x1c 0x1>; ++ }; ++ ++ tsadc_trim: tsadc-trim@44 { ++ reg = <0x44 0x2>; ++ bits = <0 10>; ++ }; ++ }; ++ }; ++ + dmac: dma-controller@ffd60000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x0 0xffd60000 0x0 0x4000>; diff --git a/target/linux/rockchip/patches-6.12/163-02-arm64-dts-rockchip-Add-USB-nodes-for-RK3528.patch b/target/linux/rockchip/patches-6.12/163-02-arm64-dts-rockchip-Add-USB-nodes-for-RK3528.patch new file mode 100644 index 0000000000..041cb4f3d1 --- /dev/null +++ b/target/linux/rockchip/patches-6.12/163-02-arm64-dts-rockchip-Add-USB-nodes-for-RK3528.patch @@ -0,0 +1,117 @@ +From a41519d8b438adc154debd433c3a1436ebb93a10 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 23 Jul 2025 12:23:05 +0000 +Subject: [PATCH] arm64: dts: rockchip: Add USB nodes for RK3528 + +Rockchip RK3528 has one USB 3.0 DWC3 controller, a USB 2.0 EHCI/OHCI +controller and uses a USB2PHY for USB 2.0. The DWC3 controller may also +use the Naneng Combo PHY for USB3. + +Add device tree nodes to describe these USB controllers along with the +USB 2.0 PHYs. + +Signed-off-by: Jonas Karlman +--- + arch/arm64/boot/dts/rockchip/rk3528.dtsi | 77 ++++++++++++++++++++++++ + 1 file changed, 77 insertions(+) + +--- a/arch/arm64/boot/dts/rockchip/rk3528.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3528.dtsi +@@ -336,6 +336,30 @@ + }; + }; + ++ usb_host0_xhci: usb@fe500000 { ++ compatible = "rockchip,rk3528-dwc3", "snps,dwc3"; ++ reg = <0x0 0xfe500000 0x0 0x400000>; ++ clocks = <&cru CLK_REF_USB3OTG>, ++ <&cru CLK_SUSPEND_USB3OTG>, ++ <&cru ACLK_USB3OTG>; ++ clock-names = "ref_clk", "suspend_clk", "bus_clk"; ++ interrupts = ; ++ power-domains = <&power RK3528_PD_VPU>; ++ resets = <&cru SRST_A_USB3OTG>; ++ dr_mode = "otg"; ++ phy_type = "utmi_wide"; ++ snps,dis_enblslpm_quirk; ++ snps,dis_rxdet_inp3_quirk; ++ snps,dis-del-phy-power-chg-quirk; ++ snps,dis-tx-ipgap-linecheck-quirk; ++ snps,dis-u1-entry-quirk; ++ snps,dis-u2-entry-quirk; ++ snps,dis-u2-freeclk-exists-quirk; ++ snps,parkmode-disable-hs-quirk; ++ snps,parkmode-disable-ss-quirk; ++ status = "disabled"; ++ }; ++ + gic: interrupt-controller@fed01000 { + compatible = "arm,gic-400"; + reg = <0x0 0xfed01000 0 0x1000>, +@@ -349,6 +373,30 @@ + #interrupt-cells = <3>; + }; + ++ usb_host0_ehci: usb@ff100000 { ++ compatible = "generic-ehci"; ++ reg = <0x0 0xff100000 0x0 0x40000>; ++ clocks = <&cru HCLK_USBHOST>, <&cru HCLK_USBHOST_ARB>, ++ <&usb2phy>; ++ interrupts = ; ++ phys = <&usb2phy_host>; ++ phy-names = "usb"; ++ power-domains = <&power RK3528_PD_VO>; ++ status = "disabled"; ++ }; ++ ++ usb_host0_ohci: usb@ff140000 { ++ compatible = "generic-ohci"; ++ reg = <0x0 0xff140000 0x0 0x40000>; ++ clocks = <&cru HCLK_USBHOST>, <&cru HCLK_USBHOST_ARB>, ++ <&usb2phy>; ++ interrupts = ; ++ phys = <&usb2phy_host>; ++ phy-names = "usb"; ++ power-domains = <&power RK3528_PD_VO>; ++ status = "disabled"; ++ }; ++ + qos_crypto_a: qos@ff200000 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff200000 0x0 0x20>; +@@ -1275,6 +1323,35 @@ + rockchip,pipe-phy-grf = <&pipe_phy_grf>; + status = "disabled"; + }; ++ ++ usb2phy: usb2phy@ffdf0000 { ++ compatible = "rockchip,rk3528-usb2phy"; ++ reg = <0x0 0xffdf0000 0x0 0x10000>; ++ clocks = <&cru CLK_REF_USBPHY>, <&cru PCLK_USBPHY>; ++ clock-names = "phyclk", "pclk"; ++ #clock-cells = <0>; ++ clock-output-names = "clk_usbphy_480m"; ++ power-domains = <&power RK3528_PD_VO>; ++ rockchip,usbgrf = <&vo_grf>; ++ status = "disabled"; ++ ++ usb2phy_otg: otg-port { ++ interrupts = , ++ , ++ ; ++ interrupt-names = "otg-bvalid", "otg-id", ++ "linestate"; ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ usb2phy_host: host-port { ++ interrupts = ; ++ interrupt-names = "linestate"; ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ }; + }; + }; + diff --git a/target/linux/rockchip/patches-6.12/163-03-arm64-dts-rockchip-Add-TSADC-controller-for-RK3528.patch b/target/linux/rockchip/patches-6.12/163-03-arm64-dts-rockchip-Add-TSADC-controller-for-RK3528.patch new file mode 100644 index 0000000000..21d609e216 --- /dev/null +++ b/target/linux/rockchip/patches-6.12/163-03-arm64-dts-rockchip-Add-TSADC-controller-for-RK3528.patch @@ -0,0 +1,146 @@ +From bcc0886b4d25cc9d82e4aa0cfa78c1268c3fcb86 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Thu, 13 Mar 2025 22:48:27 +0000 +Subject: [PATCH] arm64: dts: rockchip: Add TSADC controller for RK3528 + +Signed-off-by: Jonas Karlman +--- + arch/arm64/boot/dts/rockchip/rk3528.dtsi | 78 ++++++++++++++++++++++++ + 1 file changed, 78 insertions(+) + +--- a/arch/arm64/boot/dts/rockchip/rk3528.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3528.dtsi +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -55,6 +56,7 @@ + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_clk SCMI_CLK_CPU>; ++ #cooling-cells = <2>; + operating-points-v2 = <&cpu_opp_table>; + }; + +@@ -64,6 +66,7 @@ + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_clk SCMI_CLK_CPU>; ++ #cooling-cells = <2>; + operating-points-v2 = <&cpu_opp_table>; + }; + +@@ -73,6 +76,7 @@ + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_clk SCMI_CLK_CPU>; ++ #cooling-cells = <2>; + operating-points-v2 = <&cpu_opp_table>; + }; + +@@ -82,6 +86,7 @@ + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_clk SCMI_CLK_CPU>; ++ #cooling-cells = <2>; + operating-points-v2 = <&cpu_opp_table>; + }; + }; +@@ -255,6 +260,51 @@ + }; + }; + ++ thermal-zones { ++ soc_thermal: soc-thermal { ++ polling-delay-passive = <20>; ++ polling-delay = <1000>; ++ sustainable-power = <638>; ++ thermal-sensors = <&tsadc 0>; ++ ++ trips { ++ threshold: trip-point-0 { ++ temperature = <70000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ target: trip-point-1 { ++ temperature = <85000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ soc_crit: soc-crit { ++ temperature = <95000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ }; ++ ++ cooling-maps { ++ map0 { ++ trip = <&target>; ++ cooling-device = ++ <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ contribution = <2048>; ++ }; ++ map1 { ++ trip = <&target>; ++ cooling-device = ++ <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ contribution = <1024>; ++ }; ++ }; ++ }; ++ }; ++ + timer { + compatible = "arm,armv8-timer"; + interrupts = , +@@ -689,6 +739,7 @@ + assigned-clock-rates = <297000000>, <300000000>; + clocks = <&cru ACLK_GPU_MALI>, <&scmi_clk SCMI_CLK_GPU>; + clock-names = "bus", "core"; ++ #cooling-cells = <2>; + interrupts = , + , + , +@@ -1031,6 +1082,33 @@ + status = "disabled"; + }; + ++ tsadc: tsadc@ffad0000 { ++ compatible = "rockchip,rk3528-tsadc"; ++ reg = <0x0 0xffad0000 0x0 0x400>; ++ assigned-clocks = <&cru CLK_TSADC>, <&cru CLK_TSADC_TSEN>; ++ assigned-clock-rates = <1200000>, <12000000>; ++ clocks = <&cru CLK_TSADC>, <&cru PCLK_TSADC>, ++ <&cru CLK_TSADC_TSEN>; ++ clock-names = "tsadc", "apb_pclk", "tsen"; ++ interrupts = ; ++ power-domains = <&power RK3528_PD_VPU>; ++ resets = <&cru SRST_P_TSADC>, <&cru SRST_TSADC>; ++ reset-names = "tsadc-apb", "tsadc"; ++ rockchip,grf = <&vpu_grf>; ++ rockchip,hw-tshut-mode = <0>; ++ rockchip,hw-tshut-polarity = <0>; ++ rockchip,hw-tshut-temp = <100000>; ++ #thermal-sensor-cells = <1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ sensor@0 { ++ reg = <0>; ++ nvmem-cells = <&tsadc_trim>; ++ nvmem-cell-names = "trim"; ++ }; ++ }; ++ + saradc: adc@ffae0000 { + compatible = "rockchip,rk3528-saradc"; + reg = <0x0 0xffae0000 0x0 0x10000>;