1 /* 2 * Copyright (C) 2007,2008 Freescale Semiconductor, Inc. All rights reserved. 3 * 4 * Author: John Rigby <jrigby@freescale.com> 5 * 6 * Description: 7 * MPC512x Shared code 8 * 9 * This is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 */ 14 15 #include <linux/kernel.h> 16 #include <linux/io.h> 17 #include <linux/irq.h> 18 #include <linux/of_platform.h> 19 #include <linux/fsl-diu-fb.h> 20 #include <linux/bootmem.h> 21 #include <sysdev/fsl_soc.h> 22 23 #include <asm/cacheflush.h> 24 #include <asm/machdep.h> 25 #include <asm/ipic.h> 26 #include <asm/prom.h> 27 #include <asm/time.h> 28 #include <asm/mpc5121.h> 29 #include <asm/mpc52xx_psc.h> 30 31 #include "mpc512x.h" 32 33 static struct mpc512x_reset_module __iomem *reset_module_base; 34 35 static void __init mpc512x_restart_init(void) 36 { 37 struct device_node *np; 38 39 np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-reset"); 40 if (!np) 41 return; 42 43 reset_module_base = of_iomap(np, 0); 44 of_node_put(np); 45 } 46 47 void mpc512x_restart(char *cmd) 48 { 49 if (reset_module_base) { 50 /* Enable software reset "RSTE" */ 51 out_be32(&reset_module_base->rpr, 0x52535445); 52 /* Set software hard reset */ 53 out_be32(&reset_module_base->rcr, 0x2); 54 } else { 55 pr_err("Restart module not mapped.\n"); 56 } 57 for (;;) 58 ; 59 } 60 61 struct fsl_diu_shared_fb { 62 u8 gamma[0x300]; /* 32-bit aligned! */ 63 struct diu_ad ad0; /* 32-bit aligned! */ 64 phys_addr_t fb_phys; 65 size_t fb_len; 66 bool in_use; 67 }; 68 69 unsigned int mpc512x_get_pixel_format(unsigned int bits_per_pixel, 70 int monitor_port) 71 { 72 switch (bits_per_pixel) { 73 case 32: 74 return 0x88883316; 75 case 24: 76 return 0x88082219; 77 case 16: 78 return 0x65053118; 79 } 80 return 0x00000400; 81 } 82 83 void mpc512x_set_gamma_table(int monitor_port, char *gamma_table_base) 84 { 85 } 86 87 void mpc512x_set_monitor_port(int monitor_port) 88 { 89 } 90 91 #define DIU_DIV_MASK 0x000000ff 92 void mpc512x_set_pixel_clock(unsigned int pixclock) 93 { 94 unsigned long bestval, bestfreq, speed, busfreq; 95 unsigned long minpixclock, maxpixclock, pixval; 96 struct mpc512x_ccm __iomem *ccm; 97 struct device_node *np; 98 u32 temp; 99 long err; 100 int i; 101 102 np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-clock"); 103 if (!np) { 104 pr_err("Can't find clock control module.\n"); 105 return; 106 } 107 108 ccm = of_iomap(np, 0); 109 of_node_put(np); 110 if (!ccm) { 111 pr_err("Can't map clock control module reg.\n"); 112 return; 113 } 114 115 np = of_find_node_by_type(NULL, "cpu"); 116 if (np) { 117 const unsigned int *prop = 118 of_get_property(np, "bus-frequency", NULL); 119 120 of_node_put(np); 121 if (prop) { 122 busfreq = *prop; 123 } else { 124 pr_err("Can't get bus-frequency property\n"); 125 return; 126 } 127 } else { 128 pr_err("Can't find 'cpu' node.\n"); 129 return; 130 } 131 132 /* Pixel Clock configuration */ 133 pr_debug("DIU: Bus Frequency = %lu\n", busfreq); 134 speed = busfreq * 4; /* DIU_DIV ratio is 4 * CSB_CLK / DIU_CLK */ 135 136 /* Calculate the pixel clock with the smallest error */ 137 /* calculate the following in steps to avoid overflow */ 138 pr_debug("DIU pixclock in ps - %d\n", pixclock); 139 temp = (1000000000 / pixclock) * 1000; 140 pixclock = temp; 141 pr_debug("DIU pixclock freq - %u\n", pixclock); 142 143 temp = temp / 20; /* pixclock * 0.05 */ 144 pr_debug("deviation = %d\n", temp); 145 minpixclock = pixclock - temp; 146 maxpixclock = pixclock + temp; 147 pr_debug("DIU minpixclock - %lu\n", minpixclock); 148 pr_debug("DIU maxpixclock - %lu\n", maxpixclock); 149 pixval = speed/pixclock; 150 pr_debug("DIU pixval = %lu\n", pixval); 151 152 err = LONG_MAX; 153 bestval = pixval; 154 pr_debug("DIU bestval = %lu\n", bestval); 155 156 bestfreq = 0; 157 for (i = -1; i <= 1; i++) { 158 temp = speed / (pixval+i); 159 pr_debug("DIU test pixval i=%d, pixval=%lu, temp freq. = %u\n", 160 i, pixval, temp); 161 if ((temp < minpixclock) || (temp > maxpixclock)) 162 pr_debug("DIU exceeds monitor range (%lu to %lu)\n", 163 minpixclock, maxpixclock); 164 else if (abs(temp - pixclock) < err) { 165 pr_debug("Entered the else if block %d\n", i); 166 err = abs(temp - pixclock); 167 bestval = pixval + i; 168 bestfreq = temp; 169 } 170 } 171 172 pr_debug("DIU chose = %lx\n", bestval); 173 pr_debug("DIU error = %ld\n NomPixClk ", err); 174 pr_debug("DIU: Best Freq = %lx\n", bestfreq); 175 /* Modify DIU_DIV in CCM SCFR1 */ 176 temp = in_be32(&ccm->scfr1); 177 pr_debug("DIU: Current value of SCFR1: 0x%08x\n", temp); 178 temp &= ~DIU_DIV_MASK; 179 temp |= (bestval & DIU_DIV_MASK); 180 out_be32(&ccm->scfr1, temp); 181 pr_debug("DIU: Modified value of SCFR1: 0x%08x\n", temp); 182 iounmap(ccm); 183 } 184 185 ssize_t mpc512x_show_monitor_port(int monitor_port, char *buf) 186 { 187 return sprintf(buf, "0 - 5121 LCD\n"); 188 } 189 190 int mpc512x_set_sysfs_monitor_port(int val) 191 { 192 return 0; 193 } 194 195 static struct fsl_diu_shared_fb __attribute__ ((__aligned__(8))) diu_shared_fb; 196 197 #if defined(CONFIG_FB_FSL_DIU) || \ 198 defined(CONFIG_FB_FSL_DIU_MODULE) 199 static inline void mpc512x_free_bootmem(struct page *page) 200 { 201 __ClearPageReserved(page); 202 BUG_ON(PageTail(page)); 203 BUG_ON(atomic_read(&page->_count) > 1); 204 atomic_set(&page->_count, 1); 205 __free_page(page); 206 totalram_pages++; 207 } 208 209 void mpc512x_release_bootmem(void) 210 { 211 unsigned long addr = diu_shared_fb.fb_phys & PAGE_MASK; 212 unsigned long size = diu_shared_fb.fb_len; 213 unsigned long start, end; 214 215 if (diu_shared_fb.in_use) { 216 start = PFN_UP(addr); 217 end = PFN_DOWN(addr + size); 218 219 for (; start < end; start++) 220 mpc512x_free_bootmem(pfn_to_page(start)); 221 222 diu_shared_fb.in_use = false; 223 } 224 diu_ops.release_bootmem = NULL; 225 } 226 #endif 227 228 /* 229 * Check if DIU was pre-initialized. If so, perform steps 230 * needed to continue displaying through the whole boot process. 231 * Move area descriptor and gamma table elsewhere, they are 232 * destroyed by bootmem allocator otherwise. The frame buffer 233 * address range will be reserved in setup_arch() after bootmem 234 * allocator is up. 235 */ 236 void __init mpc512x_init_diu(void) 237 { 238 struct device_node *np; 239 struct diu __iomem *diu_reg; 240 phys_addr_t desc; 241 void __iomem *vaddr; 242 unsigned long mode, pix_fmt, res, bpp; 243 unsigned long dst; 244 245 np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-diu"); 246 if (!np) { 247 pr_err("No DIU node\n"); 248 return; 249 } 250 251 diu_reg = of_iomap(np, 0); 252 of_node_put(np); 253 if (!diu_reg) { 254 pr_err("Can't map DIU\n"); 255 return; 256 } 257 258 mode = in_be32(&diu_reg->diu_mode); 259 if (mode != MFB_MODE1) { 260 pr_info("%s: DIU OFF\n", __func__); 261 goto out; 262 } 263 264 desc = in_be32(&diu_reg->desc[0]); 265 vaddr = ioremap(desc, sizeof(struct diu_ad)); 266 if (!vaddr) { 267 pr_err("Can't map DIU area desc.\n"); 268 goto out; 269 } 270 memcpy(&diu_shared_fb.ad0, vaddr, sizeof(struct diu_ad)); 271 /* flush fb area descriptor */ 272 dst = (unsigned long)&diu_shared_fb.ad0; 273 flush_dcache_range(dst, dst + sizeof(struct diu_ad) - 1); 274 275 res = in_be32(&diu_reg->disp_size); 276 pix_fmt = in_le32(vaddr); 277 bpp = ((pix_fmt >> 16) & 0x3) + 1; 278 diu_shared_fb.fb_phys = in_le32(vaddr + 4); 279 diu_shared_fb.fb_len = ((res & 0xfff0000) >> 16) * (res & 0xfff) * bpp; 280 diu_shared_fb.in_use = true; 281 iounmap(vaddr); 282 283 desc = in_be32(&diu_reg->gamma); 284 vaddr = ioremap(desc, sizeof(diu_shared_fb.gamma)); 285 if (!vaddr) { 286 pr_err("Can't map DIU area desc.\n"); 287 diu_shared_fb.in_use = false; 288 goto out; 289 } 290 memcpy(&diu_shared_fb.gamma, vaddr, sizeof(diu_shared_fb.gamma)); 291 /* flush gamma table */ 292 dst = (unsigned long)&diu_shared_fb.gamma; 293 flush_dcache_range(dst, dst + sizeof(diu_shared_fb.gamma) - 1); 294 295 iounmap(vaddr); 296 out_be32(&diu_reg->gamma, virt_to_phys(&diu_shared_fb.gamma)); 297 out_be32(&diu_reg->desc[1], 0); 298 out_be32(&diu_reg->desc[2], 0); 299 out_be32(&diu_reg->desc[0], virt_to_phys(&diu_shared_fb.ad0)); 300 301 out: 302 iounmap(diu_reg); 303 } 304 305 void __init mpc512x_setup_diu(void) 306 { 307 int ret; 308 309 /* 310 * We do not allocate and configure new area for bitmap buffer 311 * because it would requere copying bitmap data (splash image) 312 * and so negatively affect boot time. Instead we reserve the 313 * already configured frame buffer area so that it won't be 314 * destroyed. The starting address of the area to reserve and 315 * also it's length is passed to reserve_bootmem(). It will be 316 * freed later on first open of fbdev, when splash image is not 317 * needed any more. 318 */ 319 if (diu_shared_fb.in_use) { 320 ret = reserve_bootmem(diu_shared_fb.fb_phys, 321 diu_shared_fb.fb_len, 322 BOOTMEM_EXCLUSIVE); 323 if (ret) { 324 pr_err("%s: reserve bootmem failed\n", __func__); 325 diu_shared_fb.in_use = false; 326 } 327 } 328 329 #if defined(CONFIG_FB_FSL_DIU) || \ 330 defined(CONFIG_FB_FSL_DIU_MODULE) 331 diu_ops.get_pixel_format = mpc512x_get_pixel_format; 332 diu_ops.set_gamma_table = mpc512x_set_gamma_table; 333 diu_ops.set_monitor_port = mpc512x_set_monitor_port; 334 diu_ops.set_pixel_clock = mpc512x_set_pixel_clock; 335 diu_ops.show_monitor_port = mpc512x_show_monitor_port; 336 diu_ops.set_sysfs_monitor_port = mpc512x_set_sysfs_monitor_port; 337 diu_ops.release_bootmem = mpc512x_release_bootmem; 338 #endif 339 } 340 341 void __init mpc512x_init_IRQ(void) 342 { 343 struct device_node *np; 344 345 np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-ipic"); 346 if (!np) 347 return; 348 349 ipic_init(np, 0); 350 of_node_put(np); 351 352 /* 353 * Initialize the default interrupt mapping priorities, 354 * in case the boot rom changed something on us. 355 */ 356 ipic_set_default_priority(); 357 } 358 359 /* 360 * Nodes to do bus probe on, soc and localbus 361 */ 362 static struct of_device_id __initdata of_bus_ids[] = { 363 { .compatible = "fsl,mpc5121-immr", }, 364 { .compatible = "fsl,mpc5121-localbus", }, 365 {}, 366 }; 367 368 void __init mpc512x_declare_of_platform_devices(void) 369 { 370 struct device_node *np; 371 372 if (of_platform_bus_probe(NULL, of_bus_ids, NULL)) 373 printk(KERN_ERR __FILE__ ": " 374 "Error while probing of_platform bus\n"); 375 376 np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-nfc"); 377 if (np) { 378 of_platform_device_create(np, NULL, NULL); 379 of_node_put(np); 380 } 381 } 382 383 #define DEFAULT_FIFO_SIZE 16 384 385 static unsigned int __init get_fifo_size(struct device_node *np, 386 char *prop_name) 387 { 388 const unsigned int *fp; 389 390 fp = of_get_property(np, prop_name, NULL); 391 if (fp) 392 return *fp; 393 394 pr_warning("no %s property in %s node, defaulting to %d\n", 395 prop_name, np->full_name, DEFAULT_FIFO_SIZE); 396 397 return DEFAULT_FIFO_SIZE; 398 } 399 400 #define FIFOC(_base) ((struct mpc512x_psc_fifo __iomem *) \ 401 ((u32)(_base) + sizeof(struct mpc52xx_psc))) 402 403 /* Init PSC FIFO space for TX and RX slices */ 404 void __init mpc512x_psc_fifo_init(void) 405 { 406 struct device_node *np; 407 void __iomem *psc; 408 unsigned int tx_fifo_size; 409 unsigned int rx_fifo_size; 410 int fifobase = 0; /* current fifo address in 32 bit words */ 411 412 for_each_compatible_node(np, NULL, "fsl,mpc5121-psc") { 413 tx_fifo_size = get_fifo_size(np, "fsl,tx-fifo-size"); 414 rx_fifo_size = get_fifo_size(np, "fsl,rx-fifo-size"); 415 416 /* size in register is in 4 byte units */ 417 tx_fifo_size /= 4; 418 rx_fifo_size /= 4; 419 if (!tx_fifo_size) 420 tx_fifo_size = 1; 421 if (!rx_fifo_size) 422 rx_fifo_size = 1; 423 424 psc = of_iomap(np, 0); 425 if (!psc) { 426 pr_err("%s: Can't map %s device\n", 427 __func__, np->full_name); 428 continue; 429 } 430 431 /* FIFO space is 4KiB, check if requested size is available */ 432 if ((fifobase + tx_fifo_size + rx_fifo_size) > 0x1000) { 433 pr_err("%s: no fifo space available for %s\n", 434 __func__, np->full_name); 435 iounmap(psc); 436 /* 437 * chances are that another device requests less 438 * fifo space, so we continue. 439 */ 440 continue; 441 } 442 443 /* set tx and rx fifo size registers */ 444 out_be32(&FIFOC(psc)->txsz, (fifobase << 16) | tx_fifo_size); 445 fifobase += tx_fifo_size; 446 out_be32(&FIFOC(psc)->rxsz, (fifobase << 16) | rx_fifo_size); 447 fifobase += rx_fifo_size; 448 449 /* reset and enable the slices */ 450 out_be32(&FIFOC(psc)->txcmd, 0x80); 451 out_be32(&FIFOC(psc)->txcmd, 0x01); 452 out_be32(&FIFOC(psc)->rxcmd, 0x80); 453 out_be32(&FIFOC(psc)->rxcmd, 0x01); 454 455 iounmap(psc); 456 } 457 } 458 459 void __init mpc512x_init(void) 460 { 461 mpc512x_declare_of_platform_devices(); 462 mpc5121_clk_init(); 463 mpc512x_restart_init(); 464 mpc512x_psc_fifo_init(); 465 } 466