]> git.sur5r.net Git - u-boot/blob - drivers/video/ssd2828.c
mtd: spi: Correct parameters for s25fs512s flash
[u-boot] / drivers / video / ssd2828.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) 2015 Siarhei Siamashka <siarhei.siamashka@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 }