Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / u-boot / board / freescale / p1022ds / diu.c
1 /*
2  * Copyright 2010-2011 Freescale Semiconductor, Inc.
3  * Authors: Timur Tabi <timur@freescale.com>
4  *
5  * FSL DIU Framebuffer driver
6  *
7  * SPDX-License-Identifier:     GPL-2.0+
8  */
9
10 #include <common.h>
11 #include <command.h>
12 #include <linux/ctype.h>
13 #include <asm/io.h>
14 #include <stdio_dev.h>
15 #include <video_fb.h>
16 #include "../common/ngpixis.h"
17 #include <fsl_diu_fb.h>
18
19 /* The CTL register is called 'csr' in the ngpixis_t structure */
20 #define PX_CTL_ALTACC           0x80
21
22 #define PX_BRDCFG0_ELBC_SPI_MASK        0xc0
23 #define PX_BRDCFG0_ELBC_SPI_ELBC        0x00
24 #define PX_BRDCFG0_ELBC_SPI_NULL        0xc0
25 #define PX_BRDCFG0_ELBC_DIU             0x02
26
27 #define PX_BRDCFG1_DVIEN        0x80
28 #define PX_BRDCFG1_DFPEN        0x40
29 #define PX_BRDCFG1_BACKLIGHT    0x20
30
31 #define PMUXCR_ELBCDIU_MASK     0xc0000000
32 #define PMUXCR_ELBCDIU_NOR16    0x80000000
33 #define PMUXCR_ELBCDIU_DIU      0x40000000
34
35 /*
36  * DIU Area Descriptor
37  *
38  * Note that we need to byte-swap the value before it's written to the AD
39  * register.  So even though the registers don't look like they're in the same
40  * bit positions as they are on the MPC8610, the same value is written to the
41  * AD register on the MPC8610 and on the P1022.
42  */
43 #define AD_BYTE_F               0x10000000
44 #define AD_ALPHA_C_SHIFT        25
45 #define AD_BLUE_C_SHIFT         23
46 #define AD_GREEN_C_SHIFT        21
47 #define AD_RED_C_SHIFT          19
48 #define AD_PIXEL_S_SHIFT        16
49 #define AD_COMP_3_SHIFT         12
50 #define AD_COMP_2_SHIFT         8
51 #define AD_COMP_1_SHIFT         4
52 #define AD_COMP_0_SHIFT         0
53
54 /*
55  * Variables used by the DIU/LBC switching code.  It's safe to makes these
56  * global, because the DIU requires DDR, so we'll only run this code after
57  * relocation.
58  */
59 static u8 px_brdcfg0;
60 static u32 pmuxcr;
61 static void *lbc_lcs0_ba;
62 static void *lbc_lcs1_ba;
63 static u32 old_br0, old_or0, old_br1, old_or1;
64 static u32 new_br0, new_or0, new_br1, new_or1;
65
66 void diu_set_pixel_clock(unsigned int pixclock)
67 {
68         ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
69         unsigned long speed_ccb, temp;
70         u32 pixval;
71
72         speed_ccb = get_bus_freq(0);
73         temp = 1000000000 / pixclock;
74         temp *= 1000;
75         pixval = speed_ccb / temp;
76         debug("DIU pixval = %u\n", pixval);
77
78         /* Modify PXCLK in GUTS CLKDVDR */
79         temp = in_be32(&gur->clkdvdr) & 0x2000FFFF;
80         out_be32(&gur->clkdvdr, temp);                  /* turn off clock */
81         out_be32(&gur->clkdvdr, temp | 0x80000000 | ((pixval & 0x1F) << 16));
82 }
83
84 int platform_diu_init(unsigned int xres, unsigned int yres, const char *port)
85 {
86         ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
87         const char *name;
88         u32 pixel_format;
89         u8 temp;
90         phys_addr_t phys0, phys1; /* BR0/BR1 physical addresses */
91
92         /*
93          * Indirect mode requires both BR0 and BR1 to be set to "GPCM",
94          * otherwise writes to these addresses won't actually appear on the
95          * local bus, and so the PIXIS won't see them.
96          *
97          * In FCM mode, writes go to the NAND controller, which does not pass
98          * them to the localbus directly.  So we force BR0 and BR1 into GPCM
99          * mode, since we don't care about what's behind the localbus any
100          * more.  However, we save those registers first, so that we can
101          * restore them when necessary.
102          */
103         new_br0 = old_br0 = get_lbc_br(0);
104         new_br1 = old_br1 = get_lbc_br(1);
105         new_or0 = old_or0 = get_lbc_or(0);
106         new_or1 = old_or1 = get_lbc_or(1);
107
108         /*
109          * Use the existing BRx/ORx values if it's already GPCM. Otherwise,
110          * force the values to simple 32KB GPCM windows with the most
111          * conservative timing.
112          */
113         if ((old_br0 & BR_MSEL) != BR_MS_GPCM) {
114                 new_br0 = (get_lbc_br(0) & BR_BA) | BR_V;
115                 new_or0 = OR_AM_32KB | 0xFF7;
116                 set_lbc_br(0, new_br0);
117                 set_lbc_or(0, new_or0);
118         }
119         if ((old_br1 & BR_MSEL) != BR_MS_GPCM) {
120                 new_br1 = (get_lbc_br(1) & BR_BA) | BR_V;
121                 new_or1 = OR_AM_32KB | 0xFF7;
122                 set_lbc_br(1, new_br1);
123                 set_lbc_or(1, new_or1);
124         }
125
126         /*
127          * Determine the physical addresses for Chip Selects 0 and 1.  The
128          * BR0/BR1 registers contain the truncated physical addresses for the
129          * chip selects, mapped via the localbus LAW.  Since the BRx registers
130          * only contain the lower 32 bits of the address, we have to determine
131          * the upper 4 bits some other way.  The proper way is to scan the LAW
132          * table looking for a matching localbus address. Instead, we cheat.
133          * We know that the upper bits are 0 for 32-bit addressing, or 0xF for
134          * 36-bit addressing.
135          */
136 #ifdef CONFIG_PHYS_64BIT
137         phys0 = 0xf00000000ULL | (old_br0 & old_or0 & BR_BA);
138         phys1 = 0xf00000000ULL | (old_br1 & old_or1 & BR_BA);
139 #else
140         phys0 = old_br0 & old_or0 & BR_BA;
141         phys1 = old_br1 & old_or1 & BR_BA;
142 #endif
143
144          /* Save the LBC LCS0 and LCS1 addresses for the DIU mux functions */
145         lbc_lcs0_ba = map_physmem(phys0, 1, 0);
146         lbc_lcs1_ba = map_physmem(phys1, 1, 0);
147
148         pixel_format = cpu_to_le32(AD_BYTE_F | (3 << AD_ALPHA_C_SHIFT) |
149                 (0 << AD_BLUE_C_SHIFT) | (1 << AD_GREEN_C_SHIFT) |
150                 (2 << AD_RED_C_SHIFT) | (8 << AD_COMP_3_SHIFT) |
151                 (8 << AD_COMP_2_SHIFT) | (8 << AD_COMP_1_SHIFT) |
152                 (8 << AD_COMP_0_SHIFT) | (3 << AD_PIXEL_S_SHIFT));
153
154         temp = in_8(&pixis->brdcfg1);
155
156         if (strncmp(port, "lvds", 4) == 0) {
157                 /* Single link LVDS */
158                 temp &= ~PX_BRDCFG1_DVIEN;
159                 /*
160                  * LVDS also needs backlight enabled, otherwise the display
161                  * will be blank.
162                  */
163                 temp |= (PX_BRDCFG1_DFPEN | PX_BRDCFG1_BACKLIGHT);
164                 name = "Single-Link LVDS";
165         } else {        /* DVI */
166                 /* Enable the DVI port, disable the DFP and the backlight */
167                 temp &= ~(PX_BRDCFG1_DFPEN | PX_BRDCFG1_BACKLIGHT);
168                 temp |= PX_BRDCFG1_DVIEN;
169                 name = "DVI";
170         }
171
172         printf("DIU:   Switching to %s monitor @ %ux%u\n", name, xres, yres);
173         out_8(&pixis->brdcfg1, temp);
174
175         /*
176          * Enable PIXIS indirect access mode.  This is a hack that allows us to
177          * access PIXIS registers even when the LBC pins have been muxed to the
178          * DIU.
179          */
180         setbits_8(&pixis->csr, PX_CTL_ALTACC);
181
182         /*
183          * Route the LAD pins to the DIU.  This will disable access to the eLBC,
184          * which means we won't be able to read/write any NOR flash addresses!
185          */
186         out_8(lbc_lcs0_ba, offsetof(ngpixis_t, brdcfg0));
187         px_brdcfg0 = in_8(lbc_lcs1_ba);
188         out_8(lbc_lcs1_ba, px_brdcfg0 | PX_BRDCFG0_ELBC_DIU);
189         in_8(lbc_lcs1_ba);
190
191         /* Set PMUXCR to switch the muxed pins from the LBC to the DIU */
192         clrsetbits_be32(&gur->pmuxcr, PMUXCR_ELBCDIU_MASK, PMUXCR_ELBCDIU_DIU);
193         pmuxcr = in_be32(&gur->pmuxcr);
194
195         return fsl_diu_init(xres, yres, pixel_format, 0);
196 }
197
198 /*
199  * set_mux_to_lbc - disable the DIU so that we can read/write to elbc
200  *
201  * On the Freescale P1022, the DIU video signal and the LBC address/data lines
202  * share the same pins, which means that when the DIU is active (e.g. the
203  * console is on the DVI display), NOR flash cannot be accessed.  So we use the
204  * weak accessor feature of the CFI flash code to temporarily switch the pin
205  * mux from DIU to LBC whenever we want to read or write flash.  This has a
206  * significant performance penalty, but it's the only way to make it work.
207  *
208  * There are two muxes: one on the chip, and one on the board. The chip mux
209  * controls whether the pins are used for the DIU or the LBC, and it is
210  * set via PMUXCR.  The board mux controls whether those signals go to
211  * the video connector or the NOR flash chips, and it is set via the ngPIXIS.
212  */
213 static int set_mux_to_lbc(void)
214 {
215         ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
216
217         /* Switch the muxes only if they're currently set to DIU mode */
218         if ((in_be32(&gur->pmuxcr) & PMUXCR_ELBCDIU_MASK) !=
219             PMUXCR_ELBCDIU_NOR16) {
220                 /*
221                  * In DIU mode, the PIXIS can only be accessed indirectly
222                  * since we can't read/write the LBC directly.
223                  */
224                 /* Set the board mux to LBC.  This will disable the display. */
225                 out_8(lbc_lcs0_ba, offsetof(ngpixis_t, brdcfg0));
226                 out_8(lbc_lcs1_ba, px_brdcfg0);
227                 in_8(lbc_lcs1_ba);
228
229                 /* Disable indirect PIXIS mode */
230                 out_8(lbc_lcs0_ba, offsetof(ngpixis_t, csr));
231                 clrbits_8(lbc_lcs1_ba, PX_CTL_ALTACC);
232
233                 /* Set the chip mux to LBC mode, so that writes go to flash. */
234                 out_be32(&gur->pmuxcr, (pmuxcr & ~PMUXCR_ELBCDIU_MASK) |
235                          PMUXCR_ELBCDIU_NOR16);
236                 in_be32(&gur->pmuxcr);
237
238                 /* Restore the BR0 and BR1 settings */
239                 set_lbc_br(0, old_br0);
240                 set_lbc_or(0, old_or0);
241                 set_lbc_br(1, old_br1);
242                 set_lbc_or(1, old_or1);
243
244                 return 1;
245         }
246
247         return 0;
248 }
249
250 /*
251  * set_mux_to_diu - re-enable the DIU muxing
252  *
253  * This function restores the chip and board muxing to point to the DIU.
254  */
255 static void set_mux_to_diu(void)
256 {
257         ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
258
259         /* Set BR0 and BR1 to GPCM mode */
260         set_lbc_br(0, new_br0);
261         set_lbc_or(0, new_or0);
262         set_lbc_br(1, new_br1);
263         set_lbc_or(1, new_or1);
264
265         /* Enable indirect PIXIS mode */
266         setbits_8(&pixis->csr, PX_CTL_ALTACC);
267
268         /* Set the board mux to DIU.  This will enable the display. */
269         out_8(lbc_lcs0_ba, offsetof(ngpixis_t, brdcfg0));
270         out_8(lbc_lcs1_ba, px_brdcfg0 | PX_BRDCFG0_ELBC_DIU);
271         in_8(lbc_lcs1_ba);
272
273         /* Set the chip mux to DIU mode. */
274         out_be32(&gur->pmuxcr, pmuxcr);
275         in_be32(&gur->pmuxcr);
276 }
277
278 /*
279  * pixis_read - board-specific function to read from the PIXIS
280  *
281  * This function overrides the generic pixis_read() function, so that it can
282  * use PIXIS indirect mode if necessary.
283  */
284 u8 pixis_read(unsigned int reg)
285 {
286         ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
287
288         /* Use indirect mode if the mux is currently set to DIU mode */
289         if ((in_be32(&gur->pmuxcr) & PMUXCR_ELBCDIU_MASK) !=
290             PMUXCR_ELBCDIU_NOR16) {
291                 out_8(lbc_lcs0_ba, reg);
292                 return in_8(lbc_lcs1_ba);
293         } else {
294                 void *p = (void *)PIXIS_BASE;
295
296                 return in_8(p + reg);
297         }
298 }
299
300 /*
301  * pixis_write - board-specific function to write to the PIXIS
302  *
303  * This function overrides the generic pixis_write() function, so that it can
304  * use PIXIS indirect mode if necessary.
305  */
306 void pixis_write(unsigned int reg, u8 value)
307 {
308         ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
309
310         /* Use indirect mode if the mux is currently set to DIU mode */
311         if ((in_be32(&gur->pmuxcr) & PMUXCR_ELBCDIU_MASK) !=
312             PMUXCR_ELBCDIU_NOR16) {
313                 out_8(lbc_lcs0_ba, reg);
314                 out_8(lbc_lcs1_ba, value);
315                 /* Do a read-back to ensure the write completed */
316                 in_8(lbc_lcs1_ba);
317         } else {
318                 void *p = (void *)PIXIS_BASE;
319
320                 out_8(p + reg, value);
321         }
322 }
323
324 void pixis_bank_reset(void)
325 {
326         /*
327          * For some reason, a PIXIS bank reset does not work if the PIXIS is
328          * in indirect mode, so switch to direct mode first.
329          */
330         set_mux_to_lbc();
331
332         out_8(&pixis->vctl, 0);
333         out_8(&pixis->vctl, 1);
334
335         while (1);
336 }
337
338 #ifdef CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS
339
340 void flash_write8(u8 value, void *addr)
341 {
342         int sw = set_mux_to_lbc();
343
344         __raw_writeb(value, addr);
345         if (sw) {
346                 /*
347                  * To ensure the post-write is completed to eLBC, software must
348                  * perform a dummy read from one valid address from eLBC space
349                  * before changing the eLBC_DIU from NOR mode to DIU mode.
350                  * set_mux_to_diu() includes a sync that will ensure the
351                  * __raw_readb() completes before it switches the mux.
352                  */
353                 __raw_readb(addr);
354                 set_mux_to_diu();
355         }
356 }
357
358 void flash_write16(u16 value, void *addr)
359 {
360         int sw = set_mux_to_lbc();
361
362         __raw_writew(value, addr);
363         if (sw) {
364                 /*
365                  * To ensure the post-write is completed to eLBC, software must
366                  * perform a dummy read from one valid address from eLBC space
367                  * before changing the eLBC_DIU from NOR mode to DIU mode.
368                  * set_mux_to_diu() includes a sync that will ensure the
369                  * __raw_readb() completes before it switches the mux.
370                  */
371                 __raw_readb(addr);
372                 set_mux_to_diu();
373         }
374 }
375
376 void flash_write32(u32 value, void *addr)
377 {
378         int sw = set_mux_to_lbc();
379
380         __raw_writel(value, addr);
381         if (sw) {
382                 /*
383                  * To ensure the post-write is completed to eLBC, software must
384                  * perform a dummy read from one valid address from eLBC space
385                  * before changing the eLBC_DIU from NOR mode to DIU mode.
386                  * set_mux_to_diu() includes a sync that will ensure the
387                  * __raw_readb() completes before it switches the mux.
388                  */
389                 __raw_readb(addr);
390                 set_mux_to_diu();
391         }
392 }
393
394 void flash_write64(u64 value, void *addr)
395 {
396         int sw = set_mux_to_lbc();
397         uint32_t *p = addr;
398
399         /*
400          * There is no __raw_writeq(), so do the write manually.  We don't trust
401          * the compiler, so we use inline assembly.
402          */
403         __asm__ __volatile__(
404                 "stw%U0%X0 %2,%0;\n"
405                 "stw%U1%X1 %3,%1;\n"
406                 : "=m" (*p), "=m" (*(p + 1))
407                 : "r" ((uint32_t) (value >> 32)), "r" ((uint32_t) (value)));
408
409         if (sw) {
410                 /*
411                  * To ensure the post-write is completed to eLBC, software must
412                  * perform a dummy read from one valid address from eLBC space
413                  * before changing the eLBC_DIU from NOR mode to DIU mode.  We
414                  * read addr+4 because we just wrote to addr+4, so that's how we
415                  * maintain execution order.  set_mux_to_diu() includes a sync
416                  * that will ensure the __raw_readb() completes before it
417                  * switches the mux.
418                  */
419                 __raw_readb(addr + 4);
420                 set_mux_to_diu();
421         }
422 }
423
424 u8 flash_read8(void *addr)
425 {
426         u8 ret;
427
428         int sw = set_mux_to_lbc();
429
430         ret = __raw_readb(addr);
431         if (sw)
432                 set_mux_to_diu();
433
434         return ret;
435 }
436
437 u16 flash_read16(void *addr)
438 {
439         u16 ret;
440
441         int sw = set_mux_to_lbc();
442
443         ret = __raw_readw(addr);
444         if (sw)
445                 set_mux_to_diu();
446
447         return ret;
448 }
449
450 u32 flash_read32(void *addr)
451 {
452         u32 ret;
453
454         int sw = set_mux_to_lbc();
455
456         ret = __raw_readl(addr);
457         if (sw)
458                 set_mux_to_diu();
459
460         return ret;
461 }
462
463 u64 flash_read64(void *addr)
464 {
465         u64 ret;
466
467         int sw = set_mux_to_lbc();
468
469         /* There is no __raw_readq(), so do the read manually */
470         ret = *(volatile u64 *)addr;
471         if (sw)
472                 set_mux_to_diu();
473
474         return ret;
475 }
476
477 #endif