From: Jonas Jelonek Date: Fri, 26 Jun 2026 09:32:34 +0000 (+0000) Subject: realtek: dsa: rtl93xx: allow to adjust LED_CLK X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F23944%2Fhead;p=thirdparty%2Fopenwrt.git realtek: dsa: rtl93xx: allow to adjust LED_CLK The LED_GLB_CTRL register has a field to select the clock used for LED output, either for serial LED output or for the external auxiliary MDIO to connect a RTL8231. While the default value for the period time of 400ns is the correct one for most applications, some special devices require a dedicated setting, e.g. UniFi switches with Etherlighting. Support the generic DT property "clock-frequency" within the LED node, and read + apply during LED configuration. In case the property isn't specified, no change is applied to keep previous behavior. In case an unsupported value is supplied, the default is used as a fallback Link: https://github.com/openwrt/openwrt/pull/23944 Signed-off-by: Jonas Jelonek --- diff --git a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl930x.c b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl930x.c index 1c83510d9ef..84e00cf86b8 100644 --- a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl930x.c +++ b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl930x.c @@ -24,6 +24,11 @@ #define RTL930X_VLAN_PORT_TAG_STS_CTRL_IGR_P_ITAG_KEEP_MASK GENMASK(0, 0) #define RTL930X_LED_GLB_ACTIVE_LOW BIT(22) +#define RTL930X_LED_CLK_SEL_MASK GENMASK(17, 16) +#define RTL930X_LED_CLK_SEL_800NS 0 +#define RTL930X_LED_CLK_SEL_400NS 1 +#define RTL930X_LED_CLK_SEL_200NS 2 +#define RTL930X_LED_CLK_SEL_100NS 3 #define RTL930X_LED_SETX_0_CTRL(x) (RTL930X_LED_SET0_0_CTRL - (x * 8)) #define RTL930X_LED_SETX_1_CTRL(x) (RTL930X_LED_SETX_0_CTRL(x) - 4) @@ -2612,7 +2617,9 @@ static void rtl930x_led_init(struct rtl838x_switch_priv *priv) struct device *dev = priv->dev; u8 leds_in_set[4] = {}; u32 led_mode = 1; + u32 clk_freq; u32 pm = 0; + int ret; node = of_find_compatible_node(NULL, NULL, "realtek,rtl9300-leds"); if (!node) { @@ -2620,6 +2627,32 @@ static void rtl930x_led_init(struct rtl838x_switch_priv *priv) return; } + ret = of_property_read_u32(node, "clock-frequency", &clk_freq); + if (!ret) { + u8 clk_sel; + + switch (clk_freq) { + case 10000000: + clk_sel = RTL930X_LED_CLK_SEL_100NS; + break; + case 5000000: + clk_sel = RTL930X_LED_CLK_SEL_200NS; + break; + case 1250000: + clk_sel = RTL930X_LED_CLK_SEL_800NS; + break; + default: + dev_warn(dev, "invalid LED clock frequency, falling back to default\n"); + fallthrough; + case 2500000: + clk_sel = RTL930X_LED_CLK_SEL_400NS; + break; + } + + sw_w32_mask(RTL930X_LED_CLK_SEL_MASK, + FIELD_PREP(RTL930X_LED_CLK_SEL_MASK, clk_sel), RTL930X_LED_GLB_CTRL); + } + for (int set = 0; set < 4; set++) { char set_name[16] = {0}; u32 set_config[4]; diff --git a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl931x.c b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl931x.c index d10517c27eb..e992c45c223 100644 --- a/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl931x.c +++ b/target/linux/realtek/files-6.18/drivers/net/dsa/rtl83xx/rtl931x.c @@ -25,6 +25,12 @@ #define RTL931X_VLAN_PORT_TAG_ITPID_IDX_MASK GENMASK(2, 1) #define RTL931X_VLAN_PORT_TAG_ITPID_KEEP_MASK GENMASK(0, 0) +#define RTL931X_LED_CLK_SEL_MASK GENMASK(16, 15) +#define RTL931X_LED_CLK_SEL_800NS 0 +#define RTL931X_LED_CLK_SEL_400NS 1 +#define RTL931X_LED_CLK_SEL_200NS 2 +#define RTL931X_LED_CLK_SEL_100NS 3 + /* Definition of the RTL931X-specific template field IDs as used in the PIE */ enum template_field_id { TEMPLATE_FIELD_SPM0 = 1, @@ -1603,6 +1609,8 @@ static void rtldsa_931x_led_init(struct rtl838x_switch_priv *priv) struct device *dev = priv->dev; struct device_node *node; u8 leds_in_set[4] = {}; + u32 clk_freq; + int ret; node = of_find_compatible_node(NULL, NULL, "realtek,rtl9300-leds"); if (!node) { @@ -1610,6 +1618,32 @@ static void rtldsa_931x_led_init(struct rtl838x_switch_priv *priv) return; } + ret = of_property_read_u32(node, "clock-frequency", &clk_freq); + if (!ret) { + u8 clk_sel; + + switch (clk_freq) { + case 10000000: + clk_sel = RTL931X_LED_CLK_SEL_100NS; + break; + case 5000000: + clk_sel = RTL931X_LED_CLK_SEL_200NS; + break; + case 1250000: + clk_sel = RTL931X_LED_CLK_SEL_800NS; + break; + default: + dev_warn(dev, "invalid LED clock frequency, falling back to default\n"); + fallthrough; + case 2500000: + clk_sel = RTL931X_LED_CLK_SEL_400NS; + break; + } + + sw_w32_mask(RTL931X_LED_CLK_SEL_MASK, + FIELD_PREP(RTL931X_LED_CLK_SEL_MASK, clk_sel), RTL931X_LED_GLB_CTRL); + } + for (int set = 0; set < 4; set++) { char set_name[16] = {0}; u32 set_config[4];