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