Home | History | Annotate | Download | only in video
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * (C) 2015 Siarhei Siamashka <siarhei.siamashka (at) gmail.com>
      4  */
      5 
      6 /*
      7  * Support for the SSD2828 bridge chip, which can take pixel data coming
      8  * from a parallel LCD interface and translate it on the flight into MIPI DSI
      9  * interface for driving a MIPI compatible TFT display.
     10  */
     11 
     12 #include <common.h>
     13 #include <mipi_display.h>
     14 #include <asm/arch/gpio.h>
     15 #include <asm/gpio.h>
     16 
     17 #include "videomodes.h"
     18 #include "ssd2828.h"
     19 
     20 #define		SSD2828_DIR	0xB0
     21 #define		SSD2828_VICR1	0xB1
     22 #define		SSD2828_VICR2	0xB2
     23 #define		SSD2828_VICR3	0xB3
     24 #define		SSD2828_VICR4	0xB4
     25 #define		SSD2828_VICR5	0xB5
     26 #define		SSD2828_VICR6	0xB6
     27 #define		SSD2828_CFGR	0xB7
     28 #define		SSD2828_VCR	0xB8
     29 #define		SSD2828_PCR	0xB9
     30 #define		SSD2828_PLCR	0xBA
     31 #define		SSD2828_CCR	0xBB
     32 #define		SSD2828_PSCR1	0xBC
     33 #define		SSD2828_PSCR2	0xBD
     34 #define		SSD2828_PSCR3	0xBE
     35 #define		SSD2828_PDR	0xBF
     36 #define		SSD2828_OCR	0xC0
     37 #define		SSD2828_MRSR	0xC1
     38 #define		SSD2828_RDCR	0xC2
     39 #define		SSD2828_ARSR	0xC3
     40 #define		SSD2828_LCR	0xC4
     41 #define		SSD2828_ICR	0xC5
     42 #define		SSD2828_ISR	0xC6
     43 #define		SSD2828_ESR	0xC7
     44 #define		SSD2828_DAR1	0xC9
     45 #define		SSD2828_DAR2	0xCA
     46 #define		SSD2828_DAR3	0xCB
     47 #define		SSD2828_DAR4	0xCC
     48 #define		SSD2828_DAR5	0xCD
     49 #define		SSD2828_DAR6	0xCE
     50 #define		SSD2828_HTTR1	0xCF
     51 #define		SSD2828_HTTR2	0xD0
     52 #define		SSD2828_LRTR1	0xD1
     53 #define		SSD2828_LRTR2	0xD2
     54 #define		SSD2828_TSR	0xD3
     55 #define		SSD2828_LRR	0xD4
     56 #define		SSD2828_PLLR	0xD5
     57 #define		SSD2828_TR	0xD6
     58 #define		SSD2828_TECR	0xD7
     59 #define		SSD2828_ACR1	0xD8
     60 #define		SSD2828_ACR2	0xD9
     61 #define		SSD2828_ACR3	0xDA
     62 #define		SSD2828_ACR4	0xDB
     63 #define		SSD2828_IOCR	0xDC
     64 #define		SSD2828_VICR7	0xDD
     65 #define		SSD2828_LCFR	0xDE
     66 #define		SSD2828_DAR7	0xDF
     67 #define		SSD2828_PUCR1	0xE0
     68 #define		SSD2828_PUCR2	0xE1
     69 #define		SSD2828_PUCR3	0xE2
     70 #define		SSD2828_CBCR1	0xE9
     71 #define		SSD2828_CBCR2	0xEA
     72 #define		SSD2828_CBSR	0xEB
     73 #define		SSD2828_ECR	0xEC
     74 #define		SSD2828_VSDR	0xED
     75 #define		SSD2828_TMR	0xEE
     76 #define		SSD2828_GPIO1	0xEF
     77 #define		SSD2828_GPIO2	0xF0
     78 #define		SSD2828_DLYA01	0xF1
     79 #define		SSD2828_DLYA23	0xF2
     80 #define		SSD2828_DLYB01	0xF3
     81 #define		SSD2828_DLYB23	0xF4
     82 #define		SSD2828_DLYC01	0xF5
     83 #define		SSD2828_DLYC23	0xF6
     84 #define		SSD2828_ACR5	0xF7
     85 #define		SSD2828_RR	0xFF
     86 
     87 #define	SSD2828_CFGR_HS					(1 << 0)
     88 #define	SSD2828_CFGR_CKE				(1 << 1)
     89 #define	SSD2828_CFGR_SLP				(1 << 2)
     90 #define	SSD2828_CFGR_VEN				(1 << 3)
     91 #define	SSD2828_CFGR_HCLK				(1 << 4)
     92 #define	SSD2828_CFGR_CSS				(1 << 5)
     93 #define	SSD2828_CFGR_DCS				(1 << 6)
     94 #define	SSD2828_CFGR_REN				(1 << 7)
     95 #define	SSD2828_CFGR_ECD				(1 << 8)
     96 #define	SSD2828_CFGR_EOT				(1 << 9)
     97 #define	SSD2828_CFGR_LPE				(1 << 10)
     98 #define	SSD2828_CFGR_TXD				(1 << 11)
     99 
    100 #define	SSD2828_VIDEO_MODE_NON_BURST_WITH_SYNC_PULSES	(0 << 2)
    101 #define	SSD2828_VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS	(1 << 2)
    102 #define	SSD2828_VIDEO_MODE_BURST			(2 << 2)
    103 
    104 #define	SSD2828_VIDEO_PIXEL_FORMAT_16BPP		0
    105 #define	SSD2828_VIDEO_PIXEL_FORMAT_18BPP_PACKED		1
    106 #define	SSD2828_VIDEO_PIXEL_FORMAT_18BPP_LOOSELY_PACKED	2
    107 #define	SSD2828_VIDEO_PIXEL_FORMAT_24BPP		3
    108 
    109 #define	SSD2828_LP_CLOCK_DIVIDER(n)			(((n) - 1) & 0x3F)
    110 
    111 /*
    112  * SPI transfer, using the "24-bit 3 wire" mode (that's how it is called in
    113  * the SSD2828 documentation). The 'dout' input parameter specifies 24-bits
    114  * of data to be written to SSD2828. Returns the lowest 16-bits of data,
    115  * that is received back.
    116  */
    117 static u32 soft_spi_xfer_24bit_3wire(const struct ssd2828_config *drv, u32 dout)
    118 {
    119 	int j, bitlen = 24;
    120 	u32 tmpdin = 0;
    121 	/*
    122 	 * According to the "24 Bit 3 Wire SPI Interface Timing Characteristics"
    123 	 * and "TX_CLK Timing Characteristics" tables in the SSD2828 datasheet,
    124 	 * the lowest possible 'tx_clk' clock frequency is 8MHz, and SPI runs
    125 	 * at 1/8 of that after reset. So using 1 microsecond delays is safe in
    126 	 * the main loop. But the delays around chip select pin manipulations
    127 	 * need to be longer (up to 16 'tx_clk' cycles, or 2 microseconds in
    128 	 * the worst case).
    129 	 */
    130 	const int spi_delay_us = 1;
    131 	const int spi_cs_delay_us = 2;
    132 
    133 	gpio_set_value(drv->csx_pin, 0);
    134 	udelay(spi_cs_delay_us);
    135 	for (j = bitlen - 1; j >= 0; j--) {
    136 		gpio_set_value(drv->sck_pin, 0);
    137 		gpio_set_value(drv->sdi_pin, (dout & (1 << j)) != 0);
    138 		udelay(spi_delay_us);
    139 		if (drv->sdo_pin != -1)
    140 			tmpdin = (tmpdin << 1) | gpio_get_value(drv->sdo_pin);
    141 		gpio_set_value(drv->sck_pin, 1);
    142 		udelay(spi_delay_us);
    143 	}
    144 	udelay(spi_cs_delay_us);
    145 	gpio_set_value(drv->csx_pin, 1);
    146 	udelay(spi_cs_delay_us);
    147 	return tmpdin & 0xFFFF;
    148 }
    149 
    150 /*
    151  * Read from a SSD2828 hardware register (regnum >= 0xB0)
    152  */
    153 static u32 read_hw_register(const struct ssd2828_config *cfg, u8 regnum)
    154 {
    155 	soft_spi_xfer_24bit_3wire(cfg, 0x700000 | regnum);
    156 	return soft_spi_xfer_24bit_3wire(cfg, 0x730000);
    157 }
    158 
    159 /*
    160  * Write to a SSD2828 hardware register (regnum >= 0xB0)
    161  */
    162 static void write_hw_register(const struct ssd2828_config *cfg, u8 regnum,
    163 			      u16 val)
    164 {
    165 	soft_spi_xfer_24bit_3wire(cfg, 0x700000 | regnum);
    166 	soft_spi_xfer_24bit_3wire(cfg, 0x720000 | val);
    167 }
    168 
    169 /*
    170  * Send MIPI command to the LCD panel (cmdnum < 0xB0)
    171  */
    172 static void send_mipi_dcs_command(const struct ssd2828_config *cfg, u8 cmdnum)
    173 {
    174 	/* Set packet size to 1 (a single command with no parameters) */
    175 	write_hw_register(cfg, SSD2828_PSCR1, 1);
    176 	/* Send the command */
    177 	write_hw_register(cfg, SSD2828_PDR, cmdnum);
    178 }
    179 
    180 /*
    181  * Reset SSD2828
    182  */
    183 static void ssd2828_reset(const struct ssd2828_config *cfg)
    184 {
    185 	/* RESET needs 10 milliseconds according to the datasheet */
    186 	gpio_set_value(cfg->reset_pin, 0);
    187 	mdelay(10);
    188 	gpio_set_value(cfg->reset_pin, 1);
    189 	mdelay(10);
    190 }
    191 
    192 static int ssd2828_enable_gpio(const struct ssd2828_config *cfg)
    193 {
    194 	if (gpio_request(cfg->csx_pin, "ssd2828_csx")) {
    195 		printf("SSD2828: request for 'ssd2828_csx' pin failed\n");
    196 		return 1;
    197 	}
    198 	if (gpio_request(cfg->sck_pin, "ssd2828_sck")) {
    199 		gpio_free(cfg->csx_pin);
    200 		printf("SSD2828: request for 'ssd2828_sck' pin failed\n");
    201 		return 1;
    202 	}
    203 	if (gpio_request(cfg->sdi_pin, "ssd2828_sdi")) {
    204 		gpio_free(cfg->csx_pin);
    205 		gpio_free(cfg->sck_pin);
    206 		printf("SSD2828: request for 'ssd2828_sdi' pin failed\n");
    207 		return 1;
    208 	}
    209 	if (gpio_request(cfg->reset_pin, "ssd2828_reset")) {
    210 		gpio_free(cfg->csx_pin);
    211 		gpio_free(cfg->sck_pin);
    212 		gpio_free(cfg->sdi_pin);
    213 		printf("SSD2828: request for 'ssd2828_reset' pin failed\n");
    214 		return 1;
    215 	}
    216 	if (cfg->sdo_pin != -1 && gpio_request(cfg->sdo_pin, "ssd2828_sdo")) {
    217 		gpio_free(cfg->csx_pin);
    218 		gpio_free(cfg->sck_pin);
    219 		gpio_free(cfg->sdi_pin);
    220 		gpio_free(cfg->reset_pin);
    221 		printf("SSD2828: request for 'ssd2828_sdo' pin failed\n");
    222 		return 1;
    223 	}
    224 	gpio_direction_output(cfg->reset_pin, 0);
    225 	gpio_direction_output(cfg->csx_pin, 1);
    226 	gpio_direction_output(cfg->sck_pin, 1);
    227 	gpio_direction_output(cfg->sdi_pin, 1);
    228 	if (cfg->sdo_pin != -1)
    229 		gpio_direction_input(cfg->sdo_pin);
    230 
    231 	return 0;
    232 }
    233 
    234 static int ssd2828_free_gpio(const struct ssd2828_config *cfg)
    235 {
    236 	gpio_free(cfg->csx_pin);
    237 	gpio_free(cfg->sck_pin);
    238 	gpio_free(cfg->sdi_pin);
    239 	gpio_free(cfg->reset_pin);
    240 	if (cfg->sdo_pin != -1)
    241 		gpio_free(cfg->sdo_pin);
    242 	return 1;
    243 }
    244 
    245 /*
    246  * PLL configuration register settings.
    247  *
    248  * See the "PLL Configuration Register Description" in the SSD2828 datasheet.
    249  */
    250 static u32 construct_pll_config(u32 desired_pll_freq_kbps,
    251 				u32 reference_freq_khz)
    252 {
    253 	u32 div_factor = 1, mul_factor, fr = 0;
    254 	u32 output_freq_kbps;
    255 
    256 	/* The intermediate clock after division can't be less than 5MHz */
    257 	while (reference_freq_khz / (div_factor + 1) >= 5000)
    258 		div_factor++;
    259 	if (div_factor > 31)
    260 		div_factor = 31;
    261 
    262 	mul_factor = DIV_ROUND_UP(desired_pll_freq_kbps * div_factor,
    263 				  reference_freq_khz);
    264 
    265 	output_freq_kbps = reference_freq_khz * mul_factor / div_factor;
    266 
    267 	if (output_freq_kbps >= 501000)
    268 		fr = 3;
    269 	else if (output_freq_kbps >= 251000)
    270 		fr = 2;
    271 	else if (output_freq_kbps >= 126000)
    272 		fr = 1;
    273 
    274 	return (fr << 14) | (div_factor << 8) | mul_factor;
    275 }
    276 
    277 static u32 decode_pll_config(u32 pll_config, u32 reference_freq_khz)
    278 {
    279 	u32 mul_factor = pll_config & 0xFF;
    280 	u32 div_factor = (pll_config >> 8) & 0x1F;
    281 	if (mul_factor == 0)
    282 		mul_factor = 1;
    283 	if (div_factor == 0)
    284 		div_factor = 1;
    285 	return reference_freq_khz * mul_factor / div_factor;
    286 }
    287 
    288 static int ssd2828_configure_video_interface(const struct ssd2828_config *cfg,
    289 					     const struct ctfb_res_modes *mode)
    290 {
    291 	u32 val;
    292 
    293 	/* RGB Interface Control Register 1 */
    294 	write_hw_register(cfg, SSD2828_VICR1, (mode->vsync_len << 8) |
    295 					      (mode->hsync_len));
    296 
    297 	/* RGB Interface Control Register 2 */
    298 	u32 vbp = mode->vsync_len + mode->upper_margin;
    299 	u32 hbp = mode->hsync_len + mode->left_margin;
    300 	write_hw_register(cfg, SSD2828_VICR2, (vbp << 8) | hbp);
    301 
    302 	/* RGB Interface Control Register 3 */
    303 	write_hw_register(cfg, SSD2828_VICR3, (mode->lower_margin << 8) |
    304 					      (mode->right_margin));
    305 
    306 	/* RGB Interface Control Register 4 */
    307 	write_hw_register(cfg, SSD2828_VICR4, mode->xres);
    308 
    309 	/* RGB Interface Control Register 5 */
    310 	write_hw_register(cfg, SSD2828_VICR5, mode->yres);
    311 
    312 	/* RGB Interface Control Register 6 */
    313 	val = SSD2828_VIDEO_MODE_BURST;
    314 	switch (cfg->ssd2828_color_depth) {
    315 	case 16:
    316 		val |= SSD2828_VIDEO_PIXEL_FORMAT_16BPP;
    317 		break;
    318 	case 18:
    319 		val |= cfg->mipi_dsi_loosely_packed_pixel_format ?
    320 			SSD2828_VIDEO_PIXEL_FORMAT_18BPP_LOOSELY_PACKED :
    321 			SSD2828_VIDEO_PIXEL_FORMAT_18BPP_PACKED;
    322 		break;
    323 	case 24:
    324 		val |= SSD2828_VIDEO_PIXEL_FORMAT_24BPP;
    325 		break;
    326 	default:
    327 		printf("SSD2828: unsupported color depth\n");
    328 		return 1;
    329 	}
    330 	write_hw_register(cfg, SSD2828_VICR6, val);
    331 
    332 	/* Lane Configuration Register */
    333 	write_hw_register(cfg, SSD2828_LCFR,
    334 			  cfg->mipi_dsi_number_of_data_lanes - 1);
    335 
    336 	return 0;
    337 }
    338 
    339 int ssd2828_init(const struct ssd2828_config *cfg,
    340 		 const struct ctfb_res_modes *mode)
    341 {
    342 	u32 lp_div, pll_freq_kbps, reference_freq_khz, pll_config;
    343 	/* The LP clock speed is limited by 10MHz */
    344 	const u32 mipi_dsi_low_power_clk_khz = 10000;
    345 	/*
    346 	 * This is just the reset default value of CFGR register (0x301).
    347 	 * Because we are not always able to read back from SPI, have
    348 	 * it initialized here.
    349 	 */
    350 	u32 cfgr_reg = SSD2828_CFGR_EOT | /* EOT Packet Enable */
    351 		       SSD2828_CFGR_ECD | /* Disable ECC and CRC */
    352 		       SSD2828_CFGR_HS;   /* Data lanes are in HS mode */
    353 
    354 	/* Initialize the pins */
    355 	if (ssd2828_enable_gpio(cfg) != 0)
    356 		return 1;
    357 
    358 	/* Reset the chip */
    359 	ssd2828_reset(cfg);
    360 
    361 	/*
    362 	 * If there is a pin to read data back from SPI, then we are lucky. Try
    363 	 * to check if SPI is configured correctly and SSD2828 is actually able
    364 	 * to talk back.
    365 	 */
    366 	if (cfg->sdo_pin != -1) {
    367 		if (read_hw_register(cfg, SSD2828_DIR) != 0x2828 ||
    368 		    read_hw_register(cfg, SSD2828_CFGR) != cfgr_reg) {
    369 			printf("SSD2828: SPI communication failed.\n");
    370 			ssd2828_free_gpio(cfg);
    371 			return 1;
    372 		}
    373 	}
    374 
    375 	/*
    376 	 * Pick the reference clock for PLL. If we know the exact 'tx_clk'
    377 	 * clock speed, then everything is good. If not, then we can fallback
    378 	 * to 'pclk' (pixel clock from the parallel LCD interface). In the
    379 	 * case of using this fallback, it is necessary to have parallel LCD
    380 	 * already initialized and running at this point.
    381 	 */
    382 	reference_freq_khz = cfg->ssd2828_tx_clk_khz;
    383 	if (reference_freq_khz  == 0) {
    384 		reference_freq_khz = mode->pixclock_khz;
    385 		/* Use 'pclk' as the reference clock for PLL */
    386 		cfgr_reg |= SSD2828_CFGR_CSS;
    387 	}
    388 
    389 	/*
    390 	 * Setup the parallel LCD timings in the appropriate registers.
    391 	 */
    392 	if (ssd2828_configure_video_interface(cfg, mode) != 0) {
    393 		ssd2828_free_gpio(cfg);
    394 		return 1;
    395 	}
    396 
    397 	/* Configuration Register */
    398 	cfgr_reg &= ~SSD2828_CFGR_HS;  /* Data lanes are in LP mode */
    399 	cfgr_reg |= SSD2828_CFGR_CKE;  /* Clock lane is in HS mode */
    400 	cfgr_reg |= SSD2828_CFGR_DCS;  /* Only use DCS packets */
    401 	write_hw_register(cfg, SSD2828_CFGR, cfgr_reg);
    402 
    403 	/* PLL Configuration Register */
    404 	pll_config = construct_pll_config(
    405 				cfg->mipi_dsi_bitrate_per_data_lane_mbps * 1000,
    406 				reference_freq_khz);
    407 	write_hw_register(cfg, SSD2828_PLCR, pll_config);
    408 
    409 	pll_freq_kbps = decode_pll_config(pll_config, reference_freq_khz);
    410 	lp_div = DIV_ROUND_UP(pll_freq_kbps, mipi_dsi_low_power_clk_khz * 8);
    411 
    412 	/* VC Control Register */
    413 	write_hw_register(cfg, SSD2828_VCR, 0);
    414 
    415 	/* Clock Control Register */
    416 	write_hw_register(cfg, SSD2828_CCR, SSD2828_LP_CLOCK_DIVIDER(lp_div));
    417 
    418 	/* PLL Control Register */
    419 	write_hw_register(cfg, SSD2828_PCR, 1); /* Enable PLL */
    420 
    421 	/* Wait for PLL lock */
    422 	udelay(500);
    423 
    424 	send_mipi_dcs_command(cfg, MIPI_DCS_EXIT_SLEEP_MODE);
    425 	mdelay(cfg->mipi_dsi_delay_after_exit_sleep_mode_ms);
    426 
    427 	send_mipi_dcs_command(cfg, MIPI_DCS_SET_DISPLAY_ON);
    428 	mdelay(cfg->mipi_dsi_delay_after_set_display_on_ms);
    429 
    430 	cfgr_reg |= SSD2828_CFGR_HS;    /* Enable HS mode for data lanes */
    431 	cfgr_reg |= SSD2828_CFGR_VEN;   /* Enable video pipeline */
    432 	write_hw_register(cfg, SSD2828_CFGR, cfgr_reg);
    433 
    434 	return 0;
    435 }
    436