Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/pl111: Support grayscale

Migrating the TI nspire calculators to use the PL111 driver for
framebuffer requires grayscale support for the elder panel
which uses 8bit grayscale only.

DRM does not support 8bit grayscale framebuffers in memory,
but by defining the bus format to be MEDIA_BUS_FMT_Y8_1X8 we
can get the hardware to turn on a grayscaling feature and
convert the RGB framebuffer to grayscale for us.

Cc: Daniel Tang <dt.tangr@gmail.com>
Cc: Fabian Vogt <fabian@ritter-vogt.de>
Tested-by: Fabian Vogt <fabian@ritter-vogt.de>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20190805085847.25554-2-linus.walleij@linaro.org

+28 -2
+27 -2
drivers/gpu/drm/pl111/pl111_display.c
··· 128 128 struct drm_framebuffer *fb = plane->state->fb; 129 129 struct drm_connector *connector = priv->connector; 130 130 struct drm_bridge *bridge = priv->bridge; 131 + bool grayscale = false; 131 132 u32 cntl; 132 133 u32 ppl, hsw, hfp, hbp; 133 134 u32 lpp, vsw, vfp, vbp; ··· 188 187 if (connector->display_info.bus_flags & 189 188 DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) 190 189 tim2 |= TIM2_IPC; 190 + 191 + if (connector->display_info.num_bus_formats == 1 && 192 + connector->display_info.bus_formats[0] == 193 + MEDIA_BUS_FMT_Y8_1X8) 194 + grayscale = true; 195 + 196 + /* 197 + * The AC pin bias frequency is set to max count when using 198 + * grayscale so at least once in a while we will reverse 199 + * polarity and get rid of any DC built up that could 200 + * damage the display. 201 + */ 202 + if (grayscale) 203 + tim2 |= TIM2_ACB_MASK; 191 204 } 192 205 193 206 if (bridge) { ··· 233 218 234 219 writel(0, priv->regs + CLCD_TIM3); 235 220 236 - /* Hard-code TFT panel */ 237 - cntl = CNTL_LCDEN | CNTL_LCDTFT | CNTL_LCDVCOMP(1); 221 + /* 222 + * Detect grayscale bus format. We do not support a grayscale mode 223 + * toward userspace, instead we expose an RGB24 buffer and then the 224 + * hardware will activate its grayscaler to convert to the grayscale 225 + * format. 226 + */ 227 + if (grayscale) 228 + cntl = CNTL_LCDEN | CNTL_LCDMONO8; 229 + else 230 + /* Else we assume TFT display */ 231 + cntl = CNTL_LCDEN | CNTL_LCDTFT | CNTL_LCDVCOMP(1); 232 + 238 233 /* On the ST Micro variant, assume all 24 bits are connected */ 239 234 if (priv->variant->st_bitmux_control) 240 235 cntl |= CNTL_ST_CDWID_24;
+1
include/linux/amba/clcd-regs.h
··· 42 42 #define TIM2_PCD_LO_MASK GENMASK(4, 0) 43 43 #define TIM2_PCD_LO_BITS 5 44 44 #define TIM2_CLKSEL (1 << 5) 45 + #define TIM2_ACB_MASK GENMASK(10, 6) 45 46 #define TIM2_IVS (1 << 11) 46 47 #define TIM2_IHS (1 << 12) 47 48 #define TIM2_IPC (1 << 13)