From 1f09f60a230edccb67fdcf02f44333a2f5d5b88a Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Thu, 23 Apr 2026 17:41:55 +0100 Subject: [PATCH 1/3] regulator: rpi-panel-v2: Cache regmap values Not all implementations of the V2 regulator support reading back the value of registers, which makes the GPIO control fail. Enable the regmap caching to avoid this. Signed-off-by: Dave Stevenson --- drivers/regulator/rpi-panel-v2-regulator.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/regulator/rpi-panel-v2-regulator.c b/drivers/regulator/rpi-panel-v2-regulator.c index f9446dd92ea6eb..119b315ac38482 100644 --- a/drivers/regulator/rpi-panel-v2-regulator.c +++ b/drivers/regulator/rpi-panel-v2-regulator.c @@ -33,6 +33,7 @@ static const struct regmap_config rpi_panel_regmap_config = { .val_bits = 8, .max_register = REG_PWM, .can_sleep = true, + .cache_type = REGCACHE_MAPLE, }; static int rpi_panel_v2_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, From 47da2652dcf153e893a7d16ed8b4a10afffd3fa8 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Thu, 23 Apr 2026 14:46:18 +0100 Subject: [PATCH 2/3] dtoverlays: Fixup ili79600 overlay for upstream regulator changes The upstream version of the regulator driver exposes a PWM device rather than backlight, and changes the compatible. Alter the overlay accordingly. Signed-off-by: Dave Stevenson --- .../vc4-kms-dsi-ili79600-10-1inch-overlay.dts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/overlays/vc4-kms-dsi-ili79600-10-1inch-overlay.dts b/arch/arm/boot/dts/overlays/vc4-kms-dsi-ili79600-10-1inch-overlay.dts index 7aec9e59fcb878..45ff5e967e9cc3 100644 --- a/arch/arm/boot/dts/overlays/vc4-kms-dsi-ili79600-10-1inch-overlay.dts +++ b/arch/arm/boot/dts/overlays/vc4-kms-dsi-ili79600-10-1inch-overlay.dts @@ -19,10 +19,11 @@ display_mcu: display_mcu@45 { - compatible = "raspberrypi,v2-touchscreen-panel-regulator"; + compatible = "raspberrypi,touchscreen-panel-regulator-v2"; reg = <0x45>; gpio-controller; #gpio-cells = <2>; + #pwm-cells = <3>; }; touch: ts@41 { @@ -57,7 +58,7 @@ reg = <0>; compatible = "raspberrypi,dsi-10-1inch"; power-supply = <&display_reg>; - backlight = <&display_mcu>; + backlight = <&backlight>; port { panel_in: endpoint { @@ -93,6 +94,14 @@ startup-delay-us = <50000>; enable-active-high; }; + + backlight: panel_backlight@1 { + compatible = "pwm-backlight"; + brightness-levels = <0 31>; + num-interpolated-steps = <31>; + default-brightness-level = <15>; + pwms = <&display_mcu 0 200000 0>; + }; }; }; @@ -121,6 +130,7 @@ dsi0 = <&dsi_frag>, "target:0=",<&dsi0>, <&i2c_frag>, "target:0=",<&i2c_csi_dsi0>, <&display_reg>, "reg:0=0", - <&display_reg>, "regulator-name=display_reg_0"; + <&display_reg>, "regulator-name=display_reg_0", + <&backlight>, "reg:0=0"; }; }; From 276aadf6b02f312e85d0807cba10aecce6fe9e45 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Thu, 28 Sep 2023 18:27:09 +0100 Subject: [PATCH 3/3] drm: Look for an alias for the displays to use as the DRM device name Allow DT aliases of eg DSI2 to force make DRM allocate the display with the requested name. Signed-off-by: Dave Stevenson --- drivers/gpu/drm/drm_connector.c | 61 ++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 82dae59606fa2e..9a5f20596126a9 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -85,6 +86,7 @@ struct drm_conn_prop_enum_list { int type; const char *name; struct ida ida; + int first_dyn_num; }; /* @@ -114,12 +116,41 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] = { { DRM_MODE_CONNECTOR_USB, "USB" }, }; +#define MAX_DT_NODE_NAME_LEN 20 +#define DT_DRM_NODE_PREFIX "drm-" + +static void drm_connector_get_of_name(int type, char *node_name, int length) +{ + int i = 0; + + strscpy(node_name, DT_DRM_NODE_PREFIX, length); + + do { + node_name[i + strlen(DT_DRM_NODE_PREFIX)] = + tolower(drm_connector_enum_list[type].name[i]); + + } while (drm_connector_enum_list[type].name[i++] && + i < length); + + node_name[length - 1] = '\0'; +} + void drm_connector_ida_init(void) { - int i; + int i, id; + char node_name[MAX_DT_NODE_NAME_LEN]; - for (i = 0; i < ARRAY_SIZE(drm_connector_enum_list); i++) + for (i = 0; i < ARRAY_SIZE(drm_connector_enum_list); i++) { ida_init(&drm_connector_enum_list[i].ida); + + drm_connector_get_of_name(i, node_name, MAX_DT_NODE_NAME_LEN); + + id = of_alias_get_highest_id(node_name); + if (id > 0) + drm_connector_enum_list[i].first_dyn_num = id + 1; + else + drm_connector_enum_list[i].first_dyn_num = 1; + } } void drm_connector_ida_destroy(void) @@ -227,7 +258,9 @@ static int drm_connector_init_only(struct drm_device *dev, struct i2c_adapter *ddc) { struct drm_mode_config *config = &dev->mode_config; + char node_name[MAX_DT_NODE_NAME_LEN]; int ret; + int id; struct ida *connector_ida = &drm_connector_enum_list[connector_type].ida; @@ -257,8 +290,28 @@ static int drm_connector_init_only(struct drm_device *dev, ret = 0; connector->connector_type = connector_type; - connector->connector_type_id = - ida_alloc_min(connector_ida, 1, GFP_KERNEL); + connector->connector_type_id = 0; + + drm_connector_get_of_name(connector_type, node_name, MAX_DT_NODE_NAME_LEN); + id = of_alias_get_id(dev->dev->of_node, node_name); + if (id > 0) { + /* Try and allocate the requested ID + * Valid range is 1 to 31, hence ignoring 0 as an error + */ + int type_id = ida_alloc_range(connector_ida, id, id, GFP_KERNEL); + + if (type_id > 0) + connector->connector_type_id = type_id; + else + drm_err(dev, "Failed to acquire type ID %d for interface type %s, ret %d\n", + id, drm_connector_enum_list[connector_type].name, + type_id); + } + if (!connector->connector_type_id) + connector->connector_type_id = + ida_alloc_min(connector_ida, + drm_connector_enum_list[connector_type].first_dyn_num, + GFP_KERNEL); if (connector->connector_type_id < 0) { ret = connector->connector_type_id; goto out_put_id;