1 /* 2 * jz4740 LCD controller configuration. 3 * 4 * Copyright (C) Xiangfu Liu <xiangfu@sharism.cc> 5 * Copyright (C) 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk> 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License as 9 * published by the Free Software Foundation; either version 2 of 10 * the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 20 * Boston, MA 02110-1301, USA 21 */ 22 23 #include "sdram.h" 24 #include "jzlcd.h" 25 #include "cpu.h" 26 #include "board.h" 27 28 extern vidinfo_t panel_info; 29 30 /* Useful alignment operations. */ 31 32 static inline void align2(uint32_t *n) 33 { 34 *n = (((*n)+1)>>1)<<1; 35 } 36 37 static inline void align4(uint32_t *n) 38 { 39 *n = (((*n)+3)>>2)<<2; 40 } 41 42 static inline void align8(uint32_t *n) 43 { 44 *n = (((*n)+7)>>3)<<3; 45 } 46 47 48 49 /* Register operations. */ 50 51 static inline uint32_t lcd_ctrl_get(vidinfo_t *vid, uint32_t reg) 52 { 53 return REG32(vid->lcd + reg); 54 } 55 56 static inline void lcd_ctrl_set(vidinfo_t *vid, uint32_t reg, uint32_t value) 57 { 58 REG32(vid->lcd + reg) = value; 59 } 60 61 62 63 /* Configuration operations. */ 64 65 /* Return the number of panels available. */ 66 67 static uint8_t lcd_get_panels(vidinfo_t *vid) 68 { 69 struct jzfb_info *jzfb = vid->jz_fb; 70 return ((jzfb->cfg & MODE_MASK) == MODE_STN_MONO_DUAL) || 71 ((jzfb->cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ? 2 : 1; 72 } 73 74 /* Calculate and return the pixel clock frequency. */ 75 76 static uint32_t lcd_get_pixel_clock(vidinfo_t *vid) 77 { 78 struct jzfb_info *jzfb = vid->jz_fb; 79 uint32_t pclk, width_cycles, mode = jzfb->cfg & MODE_MASK; 80 81 /* 82 Serial mode: 3 pixel clock cycles per pixel (one per channel). 83 Parallel mode: 1 pixel clock cycle per pixel. 84 */ 85 86 if (mode == MODE_8BIT_SERIAL_TFT) 87 width_cycles = jzfb->w * 3; 88 else 89 width_cycles = jzfb->w; 90 91 /* Derive pixel clock from frame clock. */ 92 93 pclk = jzfb->fclk * 94 (width_cycles + jzfb->hsw + jzfb->elw + jzfb->blw) * 95 (jzfb->h + jzfb->vsw + jzfb->efw + jzfb->bfw); 96 97 if ((mode == MODE_STN_COLOR_SINGLE) || (mode == MODE_STN_COLOR_DUAL)) 98 pclk = (pclk * 3); 99 100 if ((mode == MODE_STN_COLOR_SINGLE) || (mode == MODE_STN_COLOR_DUAL) || 101 (mode == MODE_STN_MONO_SINGLE) || (mode == MODE_STN_MONO_DUAL)) 102 pclk = pclk >> ((jzfb->cfg & STN_DAT_PINMASK) >> 4); 103 104 if ((mode == MODE_STN_COLOR_DUAL) || (mode == MODE_STN_MONO_DUAL)) 105 pclk >>= 1; 106 107 return pclk; 108 } 109 110 111 112 /* Functions returning region sizes. */ 113 114 static uint32_t lcd_get_size(vidinfo_t *vid) 115 { 116 /* Lines must be aligned to a word boundary. */ 117 uint32_t line_length = ALIGN((vid->jz_fb->w * vid->jz_fb->bpp) / 8, sizeof(uint32_t)); 118 return line_length * vid->jz_fb->h; 119 } 120 121 static uint32_t lcd_get_aligned_size(vidinfo_t *vid) 122 { 123 /* LCD_CTRL_BST_16 requires 16-word alignment. */ 124 return ALIGN(lcd_get_size(vid), 16 * sizeof(uint32_t)); 125 } 126 127 static uint32_t lcd_get_min_size(vidinfo_t *vid) 128 { 129 /* Lines must be aligned to a word boundary. */ 130 uint32_t line_length = ALIGN((vid->jz_fb->w * 32) / 8, sizeof(uint32_t)); 131 return line_length * vid->jz_fb->h; 132 } 133 134 static uint32_t lcd_get_aligned_min_size(vidinfo_t *vid) 135 { 136 /* LCD_CTRL_BST_16 requires 16-word alignment. */ 137 return ALIGN(lcd_get_min_size(vid), 16 * sizeof(uint32_t)); 138 } 139 140 static uint32_t lcd_get_palette_size(vidinfo_t *vid) 141 { 142 /* Get a collection of two-byte entries, one per colour. */ 143 144 if (vid->jz_fb->bpp < 12) 145 return (1 << (vid->jz_fb->bpp)) * sizeof(uint16_t); 146 else 147 return 0; 148 } 149 150 static uint32_t lcd_get_aligned_palette_size(vidinfo_t *vid) 151 { 152 /* LCD_CTRL_BST_16 requires 16-word alignment. */ 153 return ALIGN(lcd_get_palette_size(vid), 16 * sizeof(uint32_t)); 154 } 155 156 static uint32_t lcd_get_descriptors_size() 157 { 158 return 3 * sizeof(struct jz_fb_dma_descriptor); 159 } 160 161 static uint32_t lcd_get_total_size(vidinfo_t *vid) 162 { 163 uint32_t size = lcd_get_aligned_size(vid) * lcd_get_panels(vid); 164 uint32_t min_size = lcd_get_aligned_min_size(vid); 165 166 /* Round up to nearest full page, or MMU section if defined. */ 167 return ALIGN((size >= min_size ? size : min_size) + lcd_get_aligned_palette_size(vid) + lcd_get_descriptors_size(), PAGE_SIZE); 168 } 169 170 171 172 /* Functions returning addresses of each data region. */ 173 174 static uint32_t lcd_get_palette(vidinfo_t *vid) 175 { 176 /* Use memory at the end of the allocated region for the palette. */ 177 178 return get_memory_size() - lcd_get_aligned_palette_size(vid); 179 } 180 181 static uint32_t lcd_get_descriptors(vidinfo_t *vid) 182 { 183 /* Use memory before the palette for the descriptor array. */ 184 185 return lcd_get_palette(vid) - lcd_get_descriptors_size(); 186 } 187 188 static uint32_t lcd_get_framebuffer(uint16_t panel, vidinfo_t *vid) 189 { 190 /* Framebuffers for panels are allocated at the start of the region. */ 191 192 return get_memory_size() - lcd_get_total_size(vid) + (panel * lcd_get_aligned_size(vid)); 193 } 194 195 196 197 /* Initialisation functions. */ 198 199 static uint32_t jz_lcd_stn_init(uint32_t stnH, vidinfo_t *vid) 200 { 201 struct jzfb_info *jzfb = vid->jz_fb; 202 uint32_t val = 0; 203 204 switch (jzfb->bpp) { 205 case 1: 206 /* val |= LCD_CTRL_PEDN; */ 207 case 2: 208 val |= LCD_CTRL_FRC_2; 209 break; 210 211 case 4: 212 val |= LCD_CTRL_FRC_4; 213 break; 214 215 case 8: 216 default: 217 val |= LCD_CTRL_FRC_16; 218 break; 219 } 220 221 switch (jzfb->cfg & STN_DAT_PINMASK) { 222 case STN_DAT_PIN1: 223 /* Do not adjust the hori-param value. */ 224 break; 225 226 case STN_DAT_PIN2: 227 align2(&jzfb->hsw); 228 align2(&jzfb->elw); 229 align2(&jzfb->blw); 230 break; 231 232 case STN_DAT_PIN4: 233 align4(&jzfb->hsw); 234 align4(&jzfb->elw); 235 align4(&jzfb->blw); 236 break; 237 238 case STN_DAT_PIN8: 239 align8(&jzfb->hsw); 240 align8(&jzfb->elw); 241 align8(&jzfb->blw); 242 break; 243 } 244 245 lcd_ctrl_set(vid, LCD_VSYNC, jzfb->vsw); 246 lcd_ctrl_set(vid, LCD_HSYNC, ((jzfb->blw + jzfb->w) << 16) | (jzfb->blw + jzfb->w + jzfb->hsw)); 247 248 /* Screen setting */ 249 lcd_ctrl_set(vid, LCD_VAT, ((jzfb->blw + jzfb->w + jzfb->hsw + jzfb->elw) << 16) | (stnH + jzfb->vsw + jzfb->bfw + jzfb->efw)); 250 lcd_ctrl_set(vid, LCD_DAH, (jzfb->blw << 16) | (jzfb->blw + jzfb->w)); 251 lcd_ctrl_set(vid, LCD_DAV, stnH); 252 253 /* AC BIAs signal */ 254 lcd_ctrl_set(vid, LCD_PS, stnH+jzfb->vsw+jzfb->efw+jzfb->bfw); 255 256 return val; 257 } 258 259 static void jz_lcd_tft_init(vidinfo_t *vid) 260 { 261 struct jzfb_info *jzfb = vid->jz_fb; 262 263 lcd_ctrl_set(vid, LCD_VSYNC, jzfb->vsw); 264 lcd_ctrl_set(vid, LCD_HSYNC, jzfb->hsw); 265 lcd_ctrl_set(vid, LCD_DAV, ((jzfb->vsw + jzfb->bfw) << 16) | (jzfb->vsw + jzfb->bfw + jzfb->h)); 266 lcd_ctrl_set(vid, LCD_DAH, ((jzfb->hsw + jzfb->blw) << 16) | (jzfb->hsw + jzfb->blw + jzfb->w)); 267 lcd_ctrl_set(vid, LCD_VAT, (((jzfb->blw + jzfb->w + jzfb->elw + jzfb->hsw)) << 16) | 268 (jzfb->vsw + jzfb->bfw + jzfb->h + jzfb->efw)); 269 } 270 271 static void jz_lcd_samsung_init(vidinfo_t *vid) 272 { 273 struct jzfb_info *jzfb = vid->jz_fb; 274 uint32_t pclk = lcd_get_pixel_clock(vid); 275 uint32_t total, tp_s, tp_e, ckv_s, ckv_e; 276 uint32_t rev_s, rev_e, inv_s, inv_e; 277 278 jz_lcd_tft_init(vid); 279 280 total = jzfb->blw + jzfb->w + jzfb->elw + jzfb->hsw; 281 tp_s = jzfb->blw + jzfb->w + 1; 282 tp_e = tp_s + 1; 283 /* ckv_s = tp_s - jz_clocks.pixclk/(1000000000/4100); */ 284 ckv_s = tp_s - pclk/(1000000000/4100); 285 ckv_e = tp_s + total; 286 rev_s = tp_s - 11; /* -11.5 clk */ 287 rev_e = rev_s + total; 288 inv_s = tp_s; 289 inv_e = inv_s + total; 290 lcd_ctrl_set(vid, LCD_CLS, (tp_s << 16) | tp_e); 291 lcd_ctrl_set(vid, LCD_PS, (ckv_s << 16) | ckv_e); 292 lcd_ctrl_set(vid, LCD_SPL, (rev_s << 16) | rev_e); 293 lcd_ctrl_set(vid, LCD_REV, (inv_s << 16) | inv_e); 294 jzfb->cfg |= STFT_REVHI | STFT_SPLHI; 295 } 296 297 static void jz_lcd_sharp_init(vidinfo_t *vid) 298 { 299 struct jzfb_info *jzfb = vid->jz_fb; 300 uint32_t total, cls_s, cls_e, ps_s, ps_e; 301 uint32_t spl_s, spl_e, rev_s, rev_e; 302 303 jz_lcd_tft_init(vid); 304 305 total = jzfb->blw + jzfb->w + jzfb->elw + jzfb->hsw; 306 spl_s = 1; 307 spl_e = spl_s + 1; 308 cls_s = 0; 309 cls_e = total - 60; /* > 4us (pclk = 80ns) */ 310 ps_s = cls_s; 311 ps_e = cls_e; 312 rev_s = total - 40; /* > 3us (pclk = 80ns) */ 313 rev_e = rev_s + total; 314 jzfb->cfg |= STFT_PSHI; 315 lcd_ctrl_set(vid, LCD_SPL, (spl_s << 16) | spl_e); 316 lcd_ctrl_set(vid, LCD_CLS, (cls_s << 16) | cls_e); 317 lcd_ctrl_set(vid, LCD_PS, (ps_s << 16) | ps_e); 318 lcd_ctrl_set(vid, LCD_REV, (rev_s << 16) | rev_e); 319 } 320 321 322 323 /* Palette initialisation. */ 324 325 static inline uint16_t rgb8_to_rgb16(uint8_t rgb) 326 { 327 return ((((rgb & 0xe0) >> 5) * 4) << 11) | ((((rgb & 0x1c) >> 2) * 9) << 6) | ((rgb & 0x03) * 10); 328 } 329 330 static inline uint16_t rgb4_to_rgb16(uint8_t rgb) 331 { 332 return ((((rgb & 8) >> 3) * 0x1f) << 11) | ((((rgb & 6) >> 1) * 0x15) << 5) | ((rgb & 1) * 0x1f); 333 } 334 335 static void lcd_init_palette(vidinfo_t *vid) 336 { 337 uint16_t *palette = (uint16_t *) vid->jz_mem.palette; 338 uint16_t *end = (uint16_t *) palette + (1 << (vid->jz_fb->bpp)); 339 uint8_t value = 0; 340 341 while (palette < end) 342 { 343 switch (vid->jz_fb->bpp) 344 { 345 case 4: 346 *palette = rgb4_to_rgb16(value); 347 break; 348 349 case 8: 350 default: 351 *palette = rgb8_to_rgb16(value); 352 break; 353 } 354 355 value++; 356 palette++; 357 } 358 } 359 360 361 362 static void jz_lcd_set_timing(vidinfo_t *vid) 363 { 364 uint32_t pclk = lcd_get_pixel_clock(vid); 365 uint32_t val; 366 367 #ifdef CONFIG_CPU_JZ4730 368 val = __cpm_get_pllout() / pclk; 369 REG_CPM_CFCR2 = val - 1; 370 val = pclk * 4 ; 371 if ( val > 150000000 ) { 372 val = 150000000; 373 } 374 val = __cpm_get_pllout() / val; 375 val--; 376 if ( val > 0xF ) 377 val = 0xF; 378 #else 379 int pll_div; 380 381 pll_div = REG_CPM_CPCCR & CPM_CPCCR_PCS; /* clock source,0:pllout/2 1: pllout */ 382 pll_div = pll_div ? 1 : 2 ; 383 val = ( __cpm_get_pllout()/pll_div ) / pclk; 384 val--; 385 if ( val > 0x1ff ) { 386 val = 0x1ff; 387 } 388 __cpm_set_pixdiv(val); 389 390 val = pclk * 3 ; /* LCDClock > 2.5*Pixclock */ 391 if ( val > 150000000 ) { 392 val = 150000000; 393 } 394 val = ( __cpm_get_pllout()/pll_div ) / val; 395 val--; 396 if ( val > 0x1f ) { 397 val = 0x1f; 398 } 399 #endif 400 __cpm_set_ldiv( val ); 401 REG_CPM_CPCCR = REG_CPM_CPCCR | CPM_CPCCR_CE; /* update divide */ 402 } 403 404 /* Initialise the LCD controller with the memory, panel and framebuffer details. 405 Return the pixel clock frequency. */ 406 407 static void jz_lcd_ctrl_init(void *lcd_base, void *fb_vaddr, vidinfo_t *vid) 408 { 409 struct jz_mem_info *fbi = &vid->jz_mem; 410 struct jz_fb_dma_descriptor *descriptors = (struct jz_fb_dma_descriptor *) lcd_get_descriptors(vid); 411 412 /* Set the LCD controller address. */ 413 414 vid->lcd = lcd_base; 415 416 /* Position framebuffer regions at the given address. */ 417 418 fbi->screen = (uint32_t) fb_vaddr; 419 420 /* Obtain the palette address. */ 421 422 fbi->palette = lcd_get_palette(vid); 423 424 /* Initialise a palette for lower colour depths. */ 425 426 if (vid->jz_fb->bpp < 12) 427 lcd_init_palette(vid); 428 429 /* Reference the descriptors in memory. */ 430 431 fbi->dmadesc_fb0 = &descriptors[0]; 432 fbi->dmadesc_fb1 = &descriptors[1]; 433 fbi->dmadesc_palette = &descriptors[2]; 434 435 /* Populate descriptors. */ 436 437 /* Provide the first framebuffer descriptor in single and dual modes. */ 438 439 fbi->dmadesc_fb0->fsadr = lcd_get_framebuffer(0, vid); 440 fbi->dmadesc_fb0->fidr = 0; 441 fbi->dmadesc_fb0->ldcmd = lcd_get_size(vid) / 4; /* length in words */ 442 443 /* Provide the second framebuffer descriptor only in dual-panel mode. */ 444 445 if (lcd_get_panels(vid) == 2) 446 { 447 fbi->dmadesc_fb1->fdadr = fbi->dmadesc_fb1; 448 fbi->dmadesc_fb1->fsadr = lcd_get_framebuffer(1, vid); 449 fbi->dmadesc_fb1->fidr = 0; 450 fbi->dmadesc_fb1->ldcmd = lcd_get_size(vid) / 4; 451 452 /* Note the address to be provided for the second channel. */ 453 454 fbi->fdadr1 = fbi->dmadesc_fb1; 455 } 456 457 /* Initialise palette descriptor details if a palette is to be used. */ 458 459 /* Assume any mode with <12 bpp is palette driven. */ 460 461 if (vid->jz_fb->bpp < 12) 462 { 463 fbi->dmadesc_palette->fsadr = fbi->palette; 464 fbi->dmadesc_palette->fidr = 0; 465 fbi->dmadesc_palette->ldcmd = (lcd_get_palette_size(vid) / 4) | LCD_CMD_PAL; 466 467 /* Flip back and forth between the palette and framebuffer. */ 468 469 fbi->dmadesc_palette->fdadr = fbi->dmadesc_fb0; 470 fbi->dmadesc_fb0->fdadr = fbi->dmadesc_palette; 471 472 /* Provide the palette descriptor address first. */ 473 474 fbi->fdadr0 = fbi->dmadesc_palette; 475 } 476 else 477 { 478 /* No palette: always use the framebuffer descriptor. */ 479 480 fbi->dmadesc_fb0->fdadr = fbi->dmadesc_fb0; 481 fbi->fdadr0 = fbi->dmadesc_fb0; 482 } 483 } 484 485 /* Initialise the LCD registers. */ 486 487 static void jz_lcd_hw_init(vidinfo_t *vid) 488 { 489 struct jzfb_info *jzfb = vid->jz_fb; 490 uint32_t val = 0; 491 492 /* Compute control register flags. */ 493 494 switch (jzfb->bpp) { 495 case 1: 496 val |= LCD_CTRL_BPP_1; 497 break; 498 499 case 2: 500 val |= LCD_CTRL_BPP_2; 501 break; 502 503 case 4: 504 val |= LCD_CTRL_BPP_4; 505 break; 506 507 case 8: 508 val |= LCD_CTRL_BPP_8; 509 break; 510 511 case 15: 512 val |= LCD_CTRL_RGB555; 513 case 16: 514 val |= LCD_CTRL_BPP_16; 515 break; 516 517 case 17 ... 32: 518 val |= LCD_CTRL_BPP_18_24; /* target is 4bytes/pixel */ 519 break; 520 521 default: 522 val |= LCD_CTRL_BPP_16; /* default to 16bpp */ 523 break; 524 } 525 526 /* Set various configuration registers for the panel. */ 527 528 switch (jzfb->cfg & MODE_MASK) { 529 case MODE_STN_MONO_DUAL: 530 case MODE_STN_COLOR_DUAL: 531 val |= jz_lcd_stn_init(jzfb->h >> 1, vid); 532 break; 533 534 case MODE_STN_MONO_SINGLE: 535 case MODE_STN_COLOR_SINGLE: 536 val |= jz_lcd_stn_init(jzfb->h, vid); 537 break; 538 539 case MODE_TFT_GEN: 540 case MODE_TFT_CASIO: 541 case MODE_8BIT_SERIAL_TFT: 542 case MODE_TFT_18BIT: 543 jz_lcd_tft_init(vid); 544 break; 545 546 case MODE_TFT_SAMSUNG: 547 jz_lcd_samsung_init(vid); 548 break; 549 550 case MODE_TFT_SHARP: 551 jz_lcd_sharp_init(vid); 552 break; 553 554 default: 555 break; 556 } 557 558 /* Further control register and panel configuration. */ 559 560 val |= LCD_CTRL_BST_16; /* Burst Length is 16WORD=64Byte */ 561 val |= LCD_CTRL_OFUP; /* OutFIFO underrun protect */ 562 563 lcd_ctrl_set(vid, LCD_CTRL, val); 564 lcd_ctrl_set(vid, LCD_CFG, jzfb->cfg); 565 } 566 567 static void jz_lcd_timing_init(vidinfo_t *vid) 568 { 569 __cpm_stop_lcd(); 570 jz_lcd_set_timing(vid); 571 __cpm_start_lcd(); 572 udelay(1000); 573 } 574 575 /* Initialise DMA for the driver. */ 576 577 static void jz_lcd_dma_init(vidinfo_t *vid) 578 { 579 struct jz_mem_info *fbi = &vid->jz_mem; 580 uint32_t mode = vid->jz_fb->cfg & MODE_MASK; 581 582 /* Configure DMA by setting frame descriptor addresses. */ 583 584 lcd_ctrl_set(vid, LCD_DA0, (uint32_t) fbi->fdadr0); 585 586 if ((mode == MODE_STN_COLOR_DUAL) || (mode == MODE_STN_MONO_DUAL)) 587 lcd_ctrl_set(vid, LCD_DA1, (uint32_t) fbi->fdadr1); 588 } 589 590 /* Set the colour depth. */ 591 592 void lcd_set_bpp(uint8_t bpp) 593 { 594 vidinfo_t *vid = &panel_info; 595 vid->jz_fb->bpp = bpp; 596 } 597 598 void lcd_enable() 599 { 600 vidinfo_t *vid = &panel_info; 601 602 /* Clear the disable bit (DIS) and set the enable bit (ENA). */ 603 604 lcd_ctrl_set(vid, LCD_CTRL, (lcd_ctrl_get(vid, LCD_CTRL) & ~LCD_CTRL_DIS) | LCD_CTRL_ENA); 605 } 606 607 void lcd_disable() 608 { 609 vidinfo_t *vid = &panel_info; 610 611 /* Set the disable bit (DIS). */ 612 613 lcd_ctrl_set(vid, LCD_CTRL, lcd_ctrl_get(vid, LCD_CTRL) | LCD_CTRL_DIS); 614 } 615 616 void lcd_quick_disable() 617 { 618 vidinfo_t *vid = &panel_info; 619 620 /* Clear the enable bit (ENA) for quick disable. */ 621 622 lcd_ctrl_set(vid, LCD_CTRL, lcd_ctrl_get(vid, LCD_CTRL) & ~LCD_CTRL_ENA); 623 } 624 625 uint32_t lcd_ctrl_init() 626 { 627 vidinfo_t *vid = &panel_info; 628 struct jz_mem_info *fbi = &vid->jz_mem; 629 void *fb_vaddr; 630 631 /* Start from the top of memory and obtain the framebuffer region. */ 632 633 fb_vaddr = (void *) lcd_get_framebuffer(0, vid); 634 635 jz_lcd_ctrl_init((void *) LCD_BASE_KSEG1, fb_vaddr, vid); 636 flush_cache_all(); 637 jz_lcd_hw_init(vid); 638 jz_lcd_timing_init(vid); 639 jz_lcd_dma_init(vid); 640 641 return fbi->screen; 642 }