static int __init sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata) { void __iomem *base = mipi->base; struct sh_mobile_lcdc_chan_cfg *ch = pdata->lcd_chan; u32 pctype, datatype, pixfmt; u32 linelength; bool yuv; /* * Select data format. MIPI DSI is not hot-pluggable, so, we just use * the default videomode. If this ever becomes a problem, We'll have to * move this to mipi_display_on() above and use info->var.xres */ switch (pdata->data_format) { case MIPI_RGB888: pctype = 0; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24; pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; linelength = ch->lcd_cfg[0].xres * 3; yuv = false; break; case MIPI_RGB565: pctype = 1; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16; pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; linelength = ch->lcd_cfg[0].xres * 2; yuv = false; break; case MIPI_RGB666_LP: pctype = 2; datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18; pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; linelength = ch->lcd_cfg[0].xres * 3; yuv = false; break; case MIPI_RGB666: pctype = 3; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18; pixfmt = MIPI_DCS_PIXEL_FMT_18BIT; linelength = (ch->lcd_cfg[0].xres * 18 + 7) / 8; yuv = false; break; case MIPI_BGR888: pctype = 8; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24; pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; linelength = ch->lcd_cfg[0].xres * 3; yuv = false; break; case MIPI_BGR565: pctype = 9; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16; pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; linelength = ch->lcd_cfg[0].xres * 2; yuv = false; break; case MIPI_BGR666_LP: pctype = 0xa; datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18; pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; linelength = ch->lcd_cfg[0].xres * 3; yuv = false; break; case MIPI_BGR666: pctype = 0xb; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18; pixfmt = MIPI_DCS_PIXEL_FMT_18BIT; linelength = (ch->lcd_cfg[0].xres * 18 + 7) / 8; yuv = false; break; case MIPI_YUYV: pctype = 4; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16; pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; linelength = ch->lcd_cfg[0].xres * 2; yuv = true; break; case MIPI_UYVY: pctype = 5; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16; pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; linelength = ch->lcd_cfg[0].xres * 2; yuv = true; break; case MIPI_YUV420_L: pctype = 6; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12; pixfmt = MIPI_DCS_PIXEL_FMT_12BIT; linelength = (ch->lcd_cfg[0].xres * 12 + 7) / 8; yuv = true; break; case MIPI_YUV420: pctype = 7; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12; pixfmt = MIPI_DCS_PIXEL_FMT_12BIT; /* Length of U/V line */ linelength = (ch->lcd_cfg[0].xres + 1) / 2; yuv = true; break; default: return -EINVAL; } if ((yuv && ch->interface_type != YUV422) || (!yuv && ch->interface_type != RGB24)) return -EINVAL; /* reset DSI link */ iowrite32(0x00000001, base); /* SYSCTRL */ /* Hold reset for 100 cycles of the slowest of bus, HS byte and LP clock */ udelay(50); iowrite32(0x00000000, base); /* SYSCTRL */ /* setup DSI link */ /* * Default = ULPS enable | * Contention detection enabled | * EoT packet transmission enable | * CRC check enable | * ECC check enable * additionally enable first two lanes */ iowrite32(0x00003703, base + 0x04); /* SYSCONF */ /* * T_wakeup = 0x7000 * T_hs-trail = 3 * T_hs-prepare = 3 * T_clk-trail = 3 * T_clk-prepare = 2 */ iowrite32(0x70003332, base + 0x08); /* TIMSET */ /* no responses requested */ iowrite32(0x00000000, base + 0x18); /* RESREQSET0 */ /* request response to packets of type 0x28 */ iowrite32(0x00000100, base + 0x1c); /* RESREQSET1 */ /* High-speed transmission timeout, default 0xffffffff */ iowrite32(0x0fffffff, base + 0x20); /* HSTTOVSET */ /* LP reception timeout, default 0xffffffff */ iowrite32(0x0fffffff, base + 0x24); /* LPRTOVSET */ /* Turn-around timeout, default 0xffffffff */ iowrite32(0x0fffffff, base + 0x28); /* TATOVSET */ /* Peripheral reset timeout, default 0xffffffff */ iowrite32(0x0fffffff, base + 0x2c); /* PRTOVSET */ /* Enable timeout counters */ iowrite32(0x00000f00, base + 0x30); /* DSICTRL */ /* Interrupts not used, disable all */ iowrite32(0, base + DSIINTE); /* DSI-Tx bias on */ iowrite32(0x00000001, base + 0x70); /* PHYCTRL */ udelay(200); /* Deassert resets, power on, set multiplier */ iowrite32(0x03070b01, base + 0x70); /* PHYCTRL */ /* setup l-bridge */ /* * Enable transmission of all packets, * transmit LPS after each HS packet completion */ iowrite32(0x00000006, base + 0x8000); /* DTCTR */ /* VSYNC width = 2 (<< 17) */ iowrite32(0x00040000 | (pctype << 12) | datatype, base + 0x8020); /* VMCTR1 */ /* * Non-burst mode with sync pulses: VSE and HSE are output, * HSA period allowed, no commands in LP */ iowrite32(0x00e00000, base + 0x8024); /* VMCTR2 */ /* * 0x660 = 1632 bytes per line (RGB24, 544 pixels: see * sh_mobile_lcdc_info.ch[0].lcd_cfg[0].xres), HSALEN = 1 - default * (unused, since VMCTR2[HSABM] = 0) */ iowrite32(1 | (linelength << 16), base + 0x8028); /* VMLEN1 */ msleep(5); /* setup LCD panel */ /* cf. drivers/video/omap/lcd_mipid.c */ sh_mipi_dcs(ch->chan, MIPI_DCS_EXIT_SLEEP_MODE); msleep(120); /* * [7] - Page Address Mode * [6] - Column Address Mode * [5] - Page / Column Address Mode * [4] - Display Device Line Refresh Order * [3] - RGB/BGR Order * [2] - Display Data Latch Data Order * [1] - Flip Horizontal * [0] - Flip Vertical */ sh_mipi_dcs_param(ch->chan, MIPI_DCS_SET_ADDRESS_MODE, 0x00); /* cf. set_data_lines() */ sh_mipi_dcs_param(ch->chan, MIPI_DCS_SET_PIXEL_FORMAT, pixfmt << 4); sh_mipi_dcs(ch->chan, MIPI_DCS_SET_DISPLAY_ON); return 0; }
static int sh_mipi_setup(struct sh_mipi *mipi, const struct fb_videomode *mode) { void __iomem *base = mipi->base; struct sh_mipi_dsi_info *pdata = mipi->pdev->dev.platform_data; u32 pctype, datatype, pixfmt, linelength, vmctr2; u32 tmp, top, bottom, delay, div; int bpp; /* * Select data format. MIPI DSI is not hot-pluggable, so, we just use * the default videomode. If this ever becomes a problem, We'll have to * move this to mipi_display_on() above and use info->var.xres */ switch (pdata->data_format) { case MIPI_RGB888: pctype = 0; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24; pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; linelength = mode->xres * 3; break; case MIPI_RGB565: pctype = 1; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16; pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; linelength = mode->xres * 2; break; case MIPI_RGB666_LP: pctype = 2; datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18; pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; linelength = mode->xres * 3; break; case MIPI_RGB666: pctype = 3; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18; pixfmt = MIPI_DCS_PIXEL_FMT_18BIT; linelength = (mode->xres * 18 + 7) / 8; break; case MIPI_BGR888: pctype = 8; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24; pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; linelength = mode->xres * 3; break; case MIPI_BGR565: pctype = 9; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16; pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; linelength = mode->xres * 2; break; case MIPI_BGR666_LP: pctype = 0xa; datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18; pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; linelength = mode->xres * 3; break; case MIPI_BGR666: pctype = 0xb; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18; pixfmt = MIPI_DCS_PIXEL_FMT_18BIT; linelength = (mode->xres * 18 + 7) / 8; break; case MIPI_YUYV: pctype = 4; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16; pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; linelength = mode->xres * 2; break; case MIPI_UYVY: pctype = 5; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16; pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; linelength = mode->xres * 2; break; case MIPI_YUV420_L: pctype = 6; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12; pixfmt = MIPI_DCS_PIXEL_FMT_12BIT; linelength = (mode->xres * 12 + 7) / 8; break; case MIPI_YUV420: pctype = 7; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12; pixfmt = MIPI_DCS_PIXEL_FMT_12BIT; /* Length of U/V line */ linelength = (mode->xres + 1) / 2; break; default: return -EINVAL; } if (!pdata->lane) return -EINVAL; /* reset DSI link */ iowrite32(0x00000001, base + SYSCTRL); /* Hold reset for 100 cycles of the slowest of bus, HS byte and LP clock */ udelay(50); iowrite32(0x00000000, base + SYSCTRL); /* setup DSI link */ /* * T_wakeup = 0x7000 * T_hs-trail = 3 * T_hs-prepare = 3 * T_clk-trail = 3 * T_clk-prepare = 2 */ iowrite32(0x70003332, base + TIMSET); /* no responses requested */ iowrite32(0x00000000, base + RESREQSET0); /* request response to packets of type 0x28 */ iowrite32(0x00000100, base + RESREQSET1); /* High-speed transmission timeout, default 0xffffffff */ iowrite32(0x0fffffff, base + HSTTOVSET); /* LP reception timeout, default 0xffffffff */ iowrite32(0x0fffffff, base + LPRTOVSET); /* Turn-around timeout, default 0xffffffff */ iowrite32(0x0fffffff, base + TATOVSET); /* Peripheral reset timeout, default 0xffffffff */ iowrite32(0x0fffffff, base + PRTOVSET); /* Interrupts not used, disable all */ iowrite32(0, base + DSIINTE); /* DSI-Tx bias on */ iowrite32(0x00000001, base + PHYCTRL); udelay(200); /* Deassert resets, power on */ iowrite32(0x03070001 | pdata->phyctrl, base + PHYCTRL); /* * Default = ULPS enable | * Contention detection enabled | * EoT packet transmission enable | * CRC check enable | * ECC check enable */ bitmap_fill((unsigned long *)&tmp, pdata->lane); tmp |= 0x00003700; iowrite32(tmp, base + SYSCONF); /* setup l-bridge */ /* * Enable transmission of all packets, * transmit LPS after each HS packet completion */ iowrite32(0x00000006, mipi->linkbase + DTCTR); /* VSYNC width = 2 (<< 17) */ iowrite32((mode->vsync_len << pdata->vsynw_offset) | (pdata->clksrc << 16) | (pctype << 12) | datatype, mipi->linkbase + VMCTR1); /* * Non-burst mode with sync pulses: VSE and HSE are output, * HSA period allowed, no commands in LP */ vmctr2 = 0; if (pdata->flags & SH_MIPI_DSI_VSEE) vmctr2 |= 1 << 23; if (pdata->flags & SH_MIPI_DSI_HSEE) vmctr2 |= 1 << 22; if (pdata->flags & SH_MIPI_DSI_HSAE) vmctr2 |= 1 << 21; if (pdata->flags & SH_MIPI_DSI_BL2E) vmctr2 |= 1 << 17; if (pdata->flags & SH_MIPI_DSI_HSABM) vmctr2 |= 1 << 5; if (pdata->flags & SH_MIPI_DSI_HBPBM) vmctr2 |= 1 << 4; if (pdata->flags & SH_MIPI_DSI_HFPBM) vmctr2 |= 1 << 3; iowrite32(vmctr2, mipi->linkbase + VMCTR2); /* * VMLEN1 = RGBLEN | HSALEN * * see * Video mode - Blanking Packet setting */ top = linelength << 16; /* RGBLEN */ bottom = 0x00000001; if (pdata->flags & SH_MIPI_DSI_HSABM) /* HSALEN */ bottom = (pdata->lane * mode->hsync_len) - 10; iowrite32(top | bottom , mipi->linkbase + VMLEN1); /* * VMLEN2 = HBPLEN | HFPLEN * * see * Video mode - Blanking Packet setting */ top = 0x00010000; bottom = 0x00000001; delay = 0; div = 1; /* HSbyteCLK is calculation base * HS4divCLK = HSbyteCLK/2 * HS6divCLK is not supported for now */ if (pdata->flags & SH_MIPI_DSI_HS4divCLK) div = 2; if (pdata->flags & SH_MIPI_DSI_HFPBM) { /* HBPLEN */ top = mode->hsync_len + mode->left_margin; top = ((pdata->lane * top / div) - 10) << 16; } if (pdata->flags & SH_MIPI_DSI_HBPBM) { /* HFPLEN */ bottom = mode->right_margin; bottom = (pdata->lane * bottom / div) - 12; } bpp = linelength / mode->xres; /* byte / pixel */ if ((pdata->lane / div) > bpp) { tmp = mode->xres / bpp; /* output cycle */ tmp = mode->xres - tmp; /* (input - output) cycle */ delay = (pdata->lane * tmp); } iowrite32(top | (bottom + delay) , mipi->linkbase + VMLEN2); msleep(5); /* setup LCD panel */ /* cf. drivers/video/omap/lcd_mipid.c */ sh_mipi_dcs(pdata->channel, MIPI_DCS_EXIT_SLEEP_MODE); msleep(120); /* * [7] - Page Address Mode * [6] - Column Address Mode * [5] - Page / Column Address Mode * [4] - Display Device Line Refresh Order * [3] - RGB/BGR Order * [2] - Display Data Latch Data Order * [1] - Flip Horizontal * [0] - Flip Vertical */ sh_mipi_dcs_param(pdata->channel, MIPI_DCS_SET_ADDRESS_MODE, 0x00); /* cf. set_data_lines() */ sh_mipi_dcs_param(pdata->channel, MIPI_DCS_SET_PIXEL_FORMAT, pixfmt << 4); sh_mipi_dcs(pdata->channel, MIPI_DCS_SET_DISPLAY_ON); /* Enable timeout counters */ iowrite32(0x00000f00, base + DSICTRL); return 0; }