Add a DRM plane property "color_mode" for panels that support 3-color (black/white/red) display modes.
The property allows runtime selection between: - bw (black/white): R1 format represents black (0) and white (1) - 3color: R1 format represents red ink (1) on white background This property is only created on panels with red_supported = true. The default is set from the panel configuration's default_color_mode field (typically BW for monochrome panels). Signed-off-by: Devarsh Thakkar <[email protected]> --- Changes from v1: - Extracted color mode property into dedicated patch as plane property drivers/gpu/drm/solomon/ssd16xx.c | 42 +++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/gpu/drm/solomon/ssd16xx.c b/drivers/gpu/drm/solomon/ssd16xx.c index dc2b8fe536af..3815af0cee5c 100644 --- a/drivers/gpu/drm/solomon/ssd16xx.c +++ b/drivers/gpu/drm/solomon/ssd16xx.c @@ -401,6 +401,7 @@ struct ssd16xx_device { struct drm_framebuffer *last_fb; /* Last drawn FB for reinit redraws */ struct drm_property *refresh_mode_property; + struct drm_property *color_mode_property; }; /* Plane state subclass: refresh_mode lives on the plane, not the connector, @@ -409,6 +410,7 @@ struct ssd16xx_device { struct ssd16xx_plane_state { struct drm_shadow_plane_state base; enum ssd16xx_refresh_mode refresh_mode; /* Pending refresh mode */ + enum ssd16xx_color_mode color_mode; /* Pending color mode */ }; #define to_ssd16xx_plane_state(s) \ @@ -1423,6 +1425,7 @@ static struct drm_plane_state *ssd16xx_plane_atomic_create_state(struct drm_plan __drm_gem_shadow_plane_state_init(plane, &ssd_state->base); ssd_state->refresh_mode = device->refresh_mode; + ssd_state->color_mode = device->color_mode; return &ssd_state->base.base; } @@ -1465,6 +1468,10 @@ static int ssd16xx_plane_atomic_get_property(struct drm_plane *plane, *val = ssd_state->refresh_mode; return 0; } + if (property == device->color_mode_property) { + *val = ssd_state->color_mode; + return 0; + } return -EINVAL; } @@ -1482,6 +1489,18 @@ static int ssd16xx_plane_atomic_set_property(struct drm_plane *plane, ssd_state->refresh_mode = val; return 0; } + if (property == device->color_mode_property) { + if (val > SSD16XX_COLOR_MODE_3COLOR) + return -EINVAL; + if (val == SSD16XX_COLOR_MODE_3COLOR && + !device->device_cfg->red_supported) { + drm_dbg(&device->drm, + "3-color not supported by this panel\n"); + return -EINVAL; + } + ssd_state->color_mode = val; + return 0; + } return -EINVAL; } @@ -1568,6 +1587,7 @@ static void ssd16xx_plane_atomic_update(struct drm_plane *plane, } device->refresh_mode = new_ssd->refresh_mode; + device->color_mode = new_ssd->color_mode; /* * When refresh_mode_init was set, use the specified mode for this first @@ -1872,6 +1892,11 @@ static const struct drm_prop_enum_list ssd16xx_refresh_mode_enum[] = { { SSD16XX_REFRESH_FAST, "fast" }, }; +static const struct drm_prop_enum_list ssd16xx_color_mode_enum[] = { + { SSD16XX_COLOR_MODE_BW, "black-white" }, + { SSD16XX_COLOR_MODE_3COLOR, "3-color" }, +}; + static int ssd16xx_plane_create_properties(struct ssd16xx_device *device) { struct drm_device *drm = &device->drm; @@ -1886,6 +1911,23 @@ static int ssd16xx_plane_create_properties(struct ssd16xx_device *device) drm_object_attach_property(plane_obj, device->refresh_mode_property, device->refresh_mode); + + /* + * Color mode: for BW-only panels the property exists but only + * "black-white" is selectable; the 3-color option is restricted + * to panels with a physical red plane. + */ + device->color_mode_property = + drm_property_create_enum(drm, 0, "color_mode", + ssd16xx_color_mode_enum, + device->device_cfg->red_supported + ? ARRAY_SIZE(ssd16xx_color_mode_enum) + : 1); + if (!device->color_mode_property) + return -ENOMEM; + drm_object_attach_property(plane_obj, + device->color_mode_property, + device->color_mode); return 0; } static const struct drm_connector_funcs ssd16xx_connector_funcs = { -- 2.39.1
