On 12/14/2016 09:51 PM, Stefan Agner wrote: > On 2016-12-13 23:52, Marek Vasut wrote: >> On 12/14/2016 02:02 AM, Stefan Agner wrote: >>> The LCD bus width does not need to align with the pixel format. The >>> LCDIF controller automatically converts between pixel formats and >>> bus width by padding or dropping LSBs. >>> >>> The DRM subsystem has the notion of bus_format which allows to >>> determine what bus_formats are supported by the display. Choose the >>> first available or fallback to 24 bit if none are available. >>> >>> Signed-off-by: Stefan Agner <stefan@xxxxxxxx> >> >> Minor nits below. >> >>> --- >>> Changes in v2: >>> - Use seperate function mxsfb_set_bus_fmt >>> >>> drivers/gpu/drm/mxsfb/mxsfb_crtc.c | 33 +++++++++++++++++++++++++++++++-- >>> drivers/gpu/drm/mxsfb/mxsfb_regs.h | 1 + >>> 2 files changed, 32 insertions(+), 2 deletions(-) >>> >>> diff --git a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c >>> index 4bcc8a3..956769b 100644 >>> --- a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c >>> +++ b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c >>> @@ -65,13 +65,11 @@ static int mxsfb_set_pixel_fmt(struct mxsfb_drm_private *mxsfb) >>> switch (format) { >>> case DRM_FORMAT_RGB565: >>> dev_dbg(drm->dev, "Setting up RGB565 mode\n"); >>> - ctrl |= CTRL_SET_BUS_WIDTH(STMLCDIF_16BIT); >>> ctrl |= CTRL_SET_WORD_LENGTH(0); >>> ctrl1 |= CTRL1_SET_BYTE_PACKAGING(0xf); >>> break; >>> case DRM_FORMAT_XRGB8888: >>> dev_dbg(drm->dev, "Setting up XRGB8888 mode\n"); >>> - ctrl |= CTRL_SET_BUS_WIDTH(STMLCDIF_24BIT); >>> ctrl |= CTRL_SET_WORD_LENGTH(3); >>> /* Do not use packed pixels = one pixel per word instead. */ >>> ctrl1 |= CTRL1_SET_BYTE_PACKAGING(0x7); >>> @@ -87,6 +85,35 @@ static int mxsfb_set_pixel_fmt(struct mxsfb_drm_private *mxsfb) >>> return 0; >>> } >>> >>> +static void mxsfb_set_bus_fmt(struct mxsfb_drm_private *mxsfb) >>> +{ >>> + struct drm_crtc *crtc = &mxsfb->pipe.crtc; >>> + struct drm_device *drm = crtc->dev; >>> + u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24; >>> + u32 reg; >> ^^^ this is uninitialized >> >>> + writel(CTRL_BUS_WIDTH_MASK, mxsfb->base + LCDC_CTRL + REG_CLR); >>> + >>> + if (mxsfb->connector.display_info.num_bus_formats) >>> + bus_format = mxsfb->connector.display_info.bus_formats[0]; >>> + >>> + switch (bus_format) { >>> + case MEDIA_BUS_FMT_RGB565_1X16: >>> + reg |= CTRL_SET_BUS_WIDTH(STMLCDIF_16BIT); >> ^^^ >> here you're doing operation on uninited value. >> >>> + break; >>> + case MEDIA_BUS_FMT_RGB666_1X18: >>> + reg |= CTRL_SET_BUS_WIDTH(STMLCDIF_18BIT); >>> + break; >>> + case MEDIA_BUS_FMT_RGB888_1X24: >>> + reg |= CTRL_SET_BUS_WIDTH(STMLCDIF_24BIT); >>> + break; >>> + default: >>> + dev_err(drm->dev, "Unknown media bus format %d\n", bus_format); >>> + break; >>> + } >>> + writel(reg, mxsfb->base + LCDC_CTRL + REG_SET); >> >> What I was thinking might be better is to save the calculated LCD_CRTC >> value in mxsfb_drm_private , but maybe R-M-W is good enough after all? > > Yeah I see what you are saying, however I would prefer to not cache if > there is no real reason to... OK > It is now a write to the clear and one write to the set variant of the > register, not sure if that counts as "two writes". It's two writel() calls, it does. >> Two writes are IMO not great because it unnecessarily reconfigures the >> controller twice. > > Does that matter? At this point, the RUN bit is guaranteed not to be > set... It's probably a matter of taste, although I'd be more comfortable with RMW here. -- Best regards, Marek Vasut _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel