Commit 10f2889b authored by Stefan Agner's avatar Stefan Agner Committed by Dave Airlie

drm: mxsfb: use bus_format to determine LCD bus width

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: default avatarStefan Agner <stefan@agner.ch>
Acked-by: default avatarMarek Vasut <marex@denx.de>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 9813527a
...@@ -65,13 +65,11 @@ static int mxsfb_set_pixel_fmt(struct mxsfb_drm_private *mxsfb) ...@@ -65,13 +65,11 @@ static int mxsfb_set_pixel_fmt(struct mxsfb_drm_private *mxsfb)
switch (format) { switch (format) {
case DRM_FORMAT_RGB565: case DRM_FORMAT_RGB565:
dev_dbg(drm->dev, "Setting up RGB565 mode\n"); dev_dbg(drm->dev, "Setting up RGB565 mode\n");
ctrl |= CTRL_SET_BUS_WIDTH(STMLCDIF_16BIT);
ctrl |= CTRL_SET_WORD_LENGTH(0); ctrl |= CTRL_SET_WORD_LENGTH(0);
ctrl1 |= CTRL1_SET_BYTE_PACKAGING(0xf); ctrl1 |= CTRL1_SET_BYTE_PACKAGING(0xf);
break; break;
case DRM_FORMAT_XRGB8888: case DRM_FORMAT_XRGB8888:
dev_dbg(drm->dev, "Setting up XRGB8888 mode\n"); dev_dbg(drm->dev, "Setting up XRGB8888 mode\n");
ctrl |= CTRL_SET_BUS_WIDTH(STMLCDIF_24BIT);
ctrl |= CTRL_SET_WORD_LENGTH(3); ctrl |= CTRL_SET_WORD_LENGTH(3);
/* Do not use packed pixels = one pixel per word instead. */ /* Do not use packed pixels = one pixel per word instead. */
ctrl1 |= CTRL1_SET_BYTE_PACKAGING(0x7); ctrl1 |= CTRL1_SET_BYTE_PACKAGING(0x7);
...@@ -87,6 +85,36 @@ static int mxsfb_set_pixel_fmt(struct mxsfb_drm_private *mxsfb) ...@@ -87,6 +85,36 @@ static int mxsfb_set_pixel_fmt(struct mxsfb_drm_private *mxsfb)
return 0; 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;
reg = readl(mxsfb->base + LCDC_CTRL);
if (mxsfb->connector.display_info.num_bus_formats)
bus_format = mxsfb->connector.display_info.bus_formats[0];
reg &= ~CTRL_BUS_WIDTH_MASK;
switch (bus_format) {
case MEDIA_BUS_FMT_RGB565_1X16:
reg |= CTRL_SET_BUS_WIDTH(STMLCDIF_16BIT);
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);
}
static void mxsfb_enable_controller(struct mxsfb_drm_private *mxsfb) static void mxsfb_enable_controller(struct mxsfb_drm_private *mxsfb)
{ {
u32 reg; u32 reg;
...@@ -175,6 +203,8 @@ static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb) ...@@ -175,6 +203,8 @@ static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb)
writel(vdctrl0, mxsfb->base + LCDC_VDCTRL0); writel(vdctrl0, mxsfb->base + LCDC_VDCTRL0);
mxsfb_set_bus_fmt(mxsfb);
/* Frame length in lines. */ /* Frame length in lines. */
writel(m->crtc_vtotal, mxsfb->base + LCDC_VDCTRL1); writel(m->crtc_vtotal, mxsfb->base + LCDC_VDCTRL1);
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#define CTRL_DATA_SELECT (1 << 16) #define CTRL_DATA_SELECT (1 << 16)
#define CTRL_SET_BUS_WIDTH(x) (((x) & 0x3) << 10) #define CTRL_SET_BUS_WIDTH(x) (((x) & 0x3) << 10)
#define CTRL_GET_BUS_WIDTH(x) (((x) >> 10) & 0x3) #define CTRL_GET_BUS_WIDTH(x) (((x) >> 10) & 0x3)
#define CTRL_BUS_WIDTH_MASK (0x3 << 10)
#define CTRL_SET_WORD_LENGTH(x) (((x) & 0x3) << 8) #define CTRL_SET_WORD_LENGTH(x) (((x) & 0x3) << 8)
#define CTRL_GET_WORD_LENGTH(x) (((x) >> 8) & 0x3) #define CTRL_GET_WORD_LENGTH(x) (((x) >> 8) & 0x3)
#define CTRL_MASTER (1 << 5) #define CTRL_MASTER (1 << 5)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment