2 * Copyright 2010-2011 Freescale Semiconductor, Inc.
3 * Authors: Timur Tabi <timur@freescale.com>
5 * FSL DIU Framebuffer driver
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
15 #include <linux/ctype.h>
17 #include <stdio_dev.h>
19 #include "../common/ngpixis.h"
20 #include <fsl_diu_fb.h>
22 /* The CTL register is called 'csr' in the ngpixis_t structure */
23 #define PX_CTL_ALTACC 0x80
25 #define PX_BRDCFG0_ELBC_SPI_MASK 0xc0
26 #define PX_BRDCFG0_ELBC_SPI_ELBC 0x00
27 #define PX_BRDCFG0_ELBC_SPI_NULL 0xc0
28 #define PX_BRDCFG0_ELBC_DIU 0x02
30 #define PX_BRDCFG1_DVIEN 0x80
31 #define PX_BRDCFG1_DFPEN 0x40
32 #define PX_BRDCFG1_BACKLIGHT 0x20
34 #define PMUXCR_ELBCDIU_MASK 0xc0000000
35 #define PMUXCR_ELBCDIU_NOR16 0x80000000
36 #define PMUXCR_ELBCDIU_DIU 0x40000000
41 * Note that we need to byte-swap the value before it's written to the AD
42 * register. So even though the registers don't look like they're in the same
43 * bit positions as they are on the MPC8610, the same value is written to the
44 * AD register on the MPC8610 and on the P1022.
46 #define AD_BYTE_F 0x10000000
47 #define AD_ALPHA_C_SHIFT 25
48 #define AD_BLUE_C_SHIFT 23
49 #define AD_GREEN_C_SHIFT 21
50 #define AD_RED_C_SHIFT 19
51 #define AD_PIXEL_S_SHIFT 16
52 #define AD_COMP_3_SHIFT 12
53 #define AD_COMP_2_SHIFT 8
54 #define AD_COMP_1_SHIFT 4
55 #define AD_COMP_0_SHIFT 0
58 * Variables used by the DIU/LBC switching code. It's safe to makes these
59 * global, because the DIU requires DDR, so we'll only run this code after
64 static void *lbc_lcs0_ba;
65 static void *lbc_lcs1_ba;
66 static u32 old_br0, old_or0, old_br1, old_or1;
67 static u32 new_br0, new_or0, new_br1, new_or1;
69 void diu_set_pixel_clock(unsigned int pixclock)
71 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
72 unsigned long speed_ccb, temp;
75 speed_ccb = get_bus_freq(0);
76 temp = 1000000000 / pixclock;
78 pixval = speed_ccb / temp;
79 debug("DIU pixval = %u\n", pixval);
81 /* Modify PXCLK in GUTS CLKDVDR */
82 temp = in_be32(&gur->clkdvdr) & 0x2000FFFF;
83 out_be32(&gur->clkdvdr, temp); /* turn off clock */
84 out_be32(&gur->clkdvdr, temp | 0x80000000 | ((pixval & 0x1F) << 16));
87 int platform_diu_init(unsigned int xres, unsigned int yres, const char *port)
89 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
93 phys_addr_t phys0, phys1; /* BR0/BR1 physical addresses */
96 * Indirect mode requires both BR0 and BR1 to be set to "GPCM",
97 * otherwise writes to these addresses won't actually appear on the
98 * local bus, and so the PIXIS won't see them.
100 * In FCM mode, writes go to the NAND controller, which does not pass
101 * them to the localbus directly. So we force BR0 and BR1 into GPCM
102 * mode, since we don't care about what's behind the localbus any
103 * more. However, we save those registers first, so that we can
104 * restore them when necessary.
106 new_br0 = old_br0 = get_lbc_br(0);
107 new_br1 = old_br1 = get_lbc_br(1);
108 new_or0 = old_or0 = get_lbc_or(0);
109 new_or1 = old_or1 = get_lbc_or(1);
112 * Use the existing BRx/ORx values if it's already GPCM. Otherwise,
113 * force the values to simple 32KB GPCM windows with the most
114 * conservative timing.
116 if ((old_br0 & BR_MSEL) != BR_MS_GPCM) {
117 new_br0 = (get_lbc_br(0) & BR_BA) | BR_V;
118 new_or0 = OR_AM_32KB | 0xFF7;
119 set_lbc_br(0, new_br0);
120 set_lbc_or(0, new_or0);
122 if ((old_br1 & BR_MSEL) != BR_MS_GPCM) {
123 new_br1 = (get_lbc_br(1) & BR_BA) | BR_V;
124 new_or1 = OR_AM_32KB | 0xFF7;
125 set_lbc_br(1, new_br1);
126 set_lbc_or(1, new_or1);
130 * Determine the physical addresses for Chip Selects 0 and 1. The
131 * BR0/BR1 registers contain the truncated physical addresses for the
132 * chip selects, mapped via the localbus LAW. Since the BRx registers
133 * only contain the lower 32 bits of the address, we have to determine
134 * the upper 4 bits some other way. The proper way is to scan the LAW
135 * table looking for a matching localbus address. Instead, we cheat.
136 * We know that the upper bits are 0 for 32-bit addressing, or 0xF for
139 #ifdef CONFIG_PHYS_64BIT
140 phys0 = 0xf00000000ULL | (old_br0 & old_or0 & BR_BA);
141 phys1 = 0xf00000000ULL | (old_br1 & old_or1 & BR_BA);
143 phys0 = old_br0 & old_or0 & BR_BA;
144 phys1 = old_br1 & old_or1 & BR_BA;
147 /* Save the LBC LCS0 and LCS1 addresses for the DIU mux functions */
148 lbc_lcs0_ba = map_physmem(phys0, 1, 0);
149 lbc_lcs1_ba = map_physmem(phys1, 1, 0);
151 pixel_format = cpu_to_le32(AD_BYTE_F | (3 << AD_ALPHA_C_SHIFT) |
152 (0 << AD_BLUE_C_SHIFT) | (1 << AD_GREEN_C_SHIFT) |
153 (2 << AD_RED_C_SHIFT) | (8 << AD_COMP_3_SHIFT) |
154 (8 << AD_COMP_2_SHIFT) | (8 << AD_COMP_1_SHIFT) |
155 (8 << AD_COMP_0_SHIFT) | (3 << AD_PIXEL_S_SHIFT));
157 temp = in_8(&pixis->brdcfg1);
159 if (strncmp(port, "lvds", 4) == 0) {
160 /* Single link LVDS */
161 temp &= ~PX_BRDCFG1_DVIEN;
163 * LVDS also needs backlight enabled, otherwise the display
166 temp |= (PX_BRDCFG1_DFPEN | PX_BRDCFG1_BACKLIGHT);
167 name = "Single-Link LVDS";
169 /* Enable the DVI port, disable the DFP and the backlight */
170 temp &= ~(PX_BRDCFG1_DFPEN | PX_BRDCFG1_BACKLIGHT);
171 temp |= PX_BRDCFG1_DVIEN;
175 printf("DIU: Switching to %s monitor @ %ux%u\n", name, xres, yres);
176 out_8(&pixis->brdcfg1, temp);
179 * Enable PIXIS indirect access mode. This is a hack that allows us to
180 * access PIXIS registers even when the LBC pins have been muxed to the
183 setbits_8(&pixis->csr, PX_CTL_ALTACC);
186 * Route the LAD pins to the DIU. This will disable access to the eLBC,
187 * which means we won't be able to read/write any NOR flash addresses!
189 out_8(lbc_lcs0_ba, offsetof(ngpixis_t, brdcfg0));
190 px_brdcfg0 = in_8(lbc_lcs1_ba);
191 out_8(lbc_lcs1_ba, px_brdcfg0 | PX_BRDCFG0_ELBC_DIU);
194 /* Set PMUXCR to switch the muxed pins from the LBC to the DIU */
195 clrsetbits_be32(&gur->pmuxcr, PMUXCR_ELBCDIU_MASK, PMUXCR_ELBCDIU_DIU);
196 pmuxcr = in_be32(&gur->pmuxcr);
198 return fsl_diu_init(xres, yres, pixel_format, 0);
202 * set_mux_to_lbc - disable the DIU so that we can read/write to elbc
204 * On the Freescale P1022, the DIU video signal and the LBC address/data lines
205 * share the same pins, which means that when the DIU is active (e.g. the
206 * console is on the DVI display), NOR flash cannot be accessed. So we use the
207 * weak accessor feature of the CFI flash code to temporarily switch the pin
208 * mux from DIU to LBC whenever we want to read or write flash. This has a
209 * significant performance penalty, but it's the only way to make it work.
211 * There are two muxes: one on the chip, and one on the board. The chip mux
212 * controls whether the pins are used for the DIU or the LBC, and it is
213 * set via PMUXCR. The board mux controls whether those signals go to
214 * the video connector or the NOR flash chips, and it is set via the ngPIXIS.
216 static int set_mux_to_lbc(void)
218 ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
220 /* Switch the muxes only if they're currently set to DIU mode */
221 if ((in_be32(&gur->pmuxcr) & PMUXCR_ELBCDIU_MASK) !=
222 PMUXCR_ELBCDIU_NOR16) {
224 * In DIU mode, the PIXIS can only be accessed indirectly
225 * since we can't read/write the LBC directly.
227 /* Set the board mux to LBC. This will disable the display. */
228 out_8(lbc_lcs0_ba, offsetof(ngpixis_t, brdcfg0));
229 out_8(lbc_lcs1_ba, px_brdcfg0);
232 /* Disable indirect PIXIS mode */
233 out_8(lbc_lcs0_ba, offsetof(ngpixis_t, csr));
234 clrbits_8(lbc_lcs1_ba, PX_CTL_ALTACC);
236 /* Set the chip mux to LBC mode, so that writes go to flash. */
237 out_be32(&gur->pmuxcr, (pmuxcr & ~PMUXCR_ELBCDIU_MASK) |
238 PMUXCR_ELBCDIU_NOR16);
239 in_be32(&gur->pmuxcr);
241 /* Restore the BR0 and BR1 settings */
242 set_lbc_br(0, old_br0);
243 set_lbc_or(0, old_or0);
244 set_lbc_br(1, old_br1);
245 set_lbc_or(1, old_or1);
254 * set_mux_to_diu - re-enable the DIU muxing
256 * This function restores the chip and board muxing to point to the DIU.
258 static void set_mux_to_diu(void)
260 ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
262 /* Set BR0 and BR1 to GPCM mode */
263 set_lbc_br(0, new_br0);
264 set_lbc_or(0, new_or0);
265 set_lbc_br(1, new_br1);
266 set_lbc_or(1, new_or1);
268 /* Enable indirect PIXIS mode */
269 setbits_8(&pixis->csr, PX_CTL_ALTACC);
271 /* Set the board mux to DIU. This will enable the display. */
272 out_8(lbc_lcs0_ba, offsetof(ngpixis_t, brdcfg0));
273 out_8(lbc_lcs1_ba, px_brdcfg0 | PX_BRDCFG0_ELBC_DIU);
276 /* Set the chip mux to DIU mode. */
277 out_be32(&gur->pmuxcr, pmuxcr);
278 in_be32(&gur->pmuxcr);
282 * pixis_read - board-specific function to read from the PIXIS
284 * This function overrides the generic pixis_read() function, so that it can
285 * use PIXIS indirect mode if necessary.
287 u8 pixis_read(unsigned int reg)
289 ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
291 /* Use indirect mode if the mux is currently set to DIU mode */
292 if ((in_be32(&gur->pmuxcr) & PMUXCR_ELBCDIU_MASK) !=
293 PMUXCR_ELBCDIU_NOR16) {
294 out_8(lbc_lcs0_ba, reg);
295 return in_8(lbc_lcs1_ba);
297 void *p = (void *)PIXIS_BASE;
299 return in_8(p + reg);
304 * pixis_write - board-specific function to write to the PIXIS
306 * This function overrides the generic pixis_write() function, so that it can
307 * use PIXIS indirect mode if necessary.
309 void pixis_write(unsigned int reg, u8 value)
311 ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
313 /* Use indirect mode if the mux is currently set to DIU mode */
314 if ((in_be32(&gur->pmuxcr) & PMUXCR_ELBCDIU_MASK) !=
315 PMUXCR_ELBCDIU_NOR16) {
316 out_8(lbc_lcs0_ba, reg);
317 out_8(lbc_lcs1_ba, value);
318 /* Do a read-back to ensure the write completed */
321 void *p = (void *)PIXIS_BASE;
323 out_8(p + reg, value);
327 void pixis_bank_reset(void)
330 * For some reason, a PIXIS bank reset does not work if the PIXIS is
331 * in indirect mode, so switch to direct mode first.
335 out_8(&pixis->vctl, 0);
336 out_8(&pixis->vctl, 1);
341 #ifdef CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS
343 void flash_write8(u8 value, void *addr)
345 int sw = set_mux_to_lbc();
347 __raw_writeb(value, addr);
350 * To ensure the post-write is completed to eLBC, software must
351 * perform a dummy read from one valid address from eLBC space
352 * before changing the eLBC_DIU from NOR mode to DIU mode.
353 * set_mux_to_diu() includes a sync that will ensure the
354 * __raw_readb() completes before it switches the mux.
361 void flash_write16(u16 value, void *addr)
363 int sw = set_mux_to_lbc();
365 __raw_writew(value, addr);
368 * To ensure the post-write is completed to eLBC, software must
369 * perform a dummy read from one valid address from eLBC space
370 * before changing the eLBC_DIU from NOR mode to DIU mode.
371 * set_mux_to_diu() includes a sync that will ensure the
372 * __raw_readb() completes before it switches the mux.
379 void flash_write32(u32 value, void *addr)
381 int sw = set_mux_to_lbc();
383 __raw_writel(value, addr);
386 * To ensure the post-write is completed to eLBC, software must
387 * perform a dummy read from one valid address from eLBC space
388 * before changing the eLBC_DIU from NOR mode to DIU mode.
389 * set_mux_to_diu() includes a sync that will ensure the
390 * __raw_readb() completes before it switches the mux.
397 void flash_write64(u64 value, void *addr)
399 int sw = set_mux_to_lbc();
403 * There is no __raw_writeq(), so do the write manually. We don't trust
404 * the compiler, so we use inline assembly.
406 __asm__ __volatile__(
409 : "=m" (*p), "=m" (*(p + 1))
410 : "r" ((uint32_t) (value >> 32)), "r" ((uint32_t) (value)));
414 * To ensure the post-write is completed to eLBC, software must
415 * perform a dummy read from one valid address from eLBC space
416 * before changing the eLBC_DIU from NOR mode to DIU mode. We
417 * read addr+4 because we just wrote to addr+4, so that's how we
418 * maintain execution order. set_mux_to_diu() includes a sync
419 * that will ensure the __raw_readb() completes before it
422 __raw_readb(addr + 4);
427 u8 flash_read8(void *addr)
431 int sw = set_mux_to_lbc();
433 ret = __raw_readb(addr);
440 u16 flash_read16(void *addr)
444 int sw = set_mux_to_lbc();
446 ret = __raw_readw(addr);
453 u32 flash_read32(void *addr)
457 int sw = set_mux_to_lbc();
459 ret = __raw_readl(addr);
466 u64 flash_read64(void *addr)
470 int sw = set_mux_to_lbc();
472 /* There is no __raw_readq(), so do the read manually */
473 ret = *(volatile u64 *)addr;