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