Exemplo n.º 1
0
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;
}
Exemplo n.º 2
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;
}