1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Epson HWA742 LCD controller driver 4 * 5 * Copyright (C) 2004-2005 Nokia Corporation 6 * Authors: Juha Yrjölä <juha.yrjola@nokia.com> 7 * Imre Deak <imre.deak@nokia.com> 8 * YUV support: Jussi Laako <jussi.laako@nokia.com> 9 */ 10 #include <linux/module.h> 11 #include <linux/mm.h> 12 #include <linux/fb.h> 13 #include <linux/delay.h> 14 #include <linux/clk.h> 15 #include <linux/interrupt.h> 16 17 #include "omapfb.h" 18 19 #define HWA742_REV_CODE_REG 0x0 20 #define HWA742_CONFIG_REG 0x2 21 #define HWA742_PLL_DIV_REG 0x4 22 #define HWA742_PLL_0_REG 0x6 23 #define HWA742_PLL_1_REG 0x8 24 #define HWA742_PLL_2_REG 0xa 25 #define HWA742_PLL_3_REG 0xc 26 #define HWA742_PLL_4_REG 0xe 27 #define HWA742_CLK_SRC_REG 0x12 28 #define HWA742_PANEL_TYPE_REG 0x14 29 #define HWA742_H_DISP_REG 0x16 30 #define HWA742_H_NDP_REG 0x18 31 #define HWA742_V_DISP_1_REG 0x1a 32 #define HWA742_V_DISP_2_REG 0x1c 33 #define HWA742_V_NDP_REG 0x1e 34 #define HWA742_HS_W_REG 0x20 35 #define HWA742_HP_S_REG 0x22 36 #define HWA742_VS_W_REG 0x24 37 #define HWA742_VP_S_REG 0x26 38 #define HWA742_PCLK_POL_REG 0x28 39 #define HWA742_INPUT_MODE_REG 0x2a 40 #define HWA742_TRANSL_MODE_REG1 0x2e 41 #define HWA742_DISP_MODE_REG 0x34 42 #define HWA742_WINDOW_TYPE 0x36 43 #define HWA742_WINDOW_X_START_0 0x38 44 #define HWA742_WINDOW_X_START_1 0x3a 45 #define HWA742_WINDOW_Y_START_0 0x3c 46 #define HWA742_WINDOW_Y_START_1 0x3e 47 #define HWA742_WINDOW_X_END_0 0x40 48 #define HWA742_WINDOW_X_END_1 0x42 49 #define HWA742_WINDOW_Y_END_0 0x44 50 #define HWA742_WINDOW_Y_END_1 0x46 51 #define HWA742_MEMORY_WRITE_LSB 0x48 52 #define HWA742_MEMORY_WRITE_MSB 0x49 53 #define HWA742_MEMORY_READ_0 0x4a 54 #define HWA742_MEMORY_READ_1 0x4c 55 #define HWA742_MEMORY_READ_2 0x4e 56 #define HWA742_POWER_SAVE 0x56 57 #define HWA742_NDP_CTRL 0x58 58 59 #define HWA742_AUTO_UPDATE_TIME (HZ / 20) 60 61 /* Reserve 4 request slots for requests in irq context */ 62 #define REQ_POOL_SIZE 24 63 #define IRQ_REQ_POOL_SIZE 4 64 65 #define REQ_FROM_IRQ_POOL 0x01 66 67 #define REQ_COMPLETE 0 68 #define REQ_PENDING 1 69 70 struct update_param { 71 int x, y, width, height; 72 int color_mode; 73 int flags; 74 }; 75 76 struct hwa742_request { 77 struct list_head entry; 78 unsigned int flags; 79 80 int (*handler)(struct hwa742_request *req); 81 void (*complete)(void *data); 82 void *complete_data; 83 84 union { 85 struct update_param update; 86 struct completion *sync; 87 } par; 88 }; 89 90 struct { 91 enum omapfb_update_mode update_mode; 92 enum omapfb_update_mode update_mode_before_suspend; 93 94 struct timer_list auto_update_timer; 95 int stop_auto_update; 96 struct omapfb_update_window auto_update_window; 97 unsigned te_connected:1; 98 unsigned vsync_only:1; 99 100 struct hwa742_request req_pool[REQ_POOL_SIZE]; 101 struct list_head pending_req_list; 102 struct list_head free_req_list; 103 struct semaphore req_sema; 104 spinlock_t req_lock; 105 106 struct extif_timings reg_timings, lut_timings; 107 108 int prev_color_mode; 109 int prev_flags; 110 int window_type; 111 112 u32 max_transmit_size; 113 u32 extif_clk_period; 114 unsigned long pix_tx_time; 115 unsigned long line_upd_time; 116 117 118 struct omapfb_device *fbdev; 119 struct lcd_ctrl_extif *extif; 120 const struct lcd_ctrl *int_ctrl; 121 122 struct clk *sys_ck; 123 } hwa742; 124 125 struct lcd_ctrl hwa742_ctrl; 126 127 static u8 hwa742_read_reg(u8 reg) 128 { 129 u8 data; 130 131 hwa742.extif->set_bits_per_cycle(8); 132 hwa742.extif->write_command(®, 1); 133 hwa742.extif->read_data(&data, 1); 134 135 return data; 136 } 137 138 static void hwa742_write_reg(u8 reg, u8 data) 139 { 140 hwa742.extif->set_bits_per_cycle(8); 141 hwa742.extif->write_command(®, 1); 142 hwa742.extif->write_data(&data, 1); 143 } 144 145 static void set_window_regs(int x_start, int y_start, int x_end, int y_end) 146 { 147 u8 tmp[8]; 148 u8 cmd; 149 150 x_end--; 151 y_end--; 152 tmp[0] = x_start; 153 tmp[1] = x_start >> 8; 154 tmp[2] = y_start; 155 tmp[3] = y_start >> 8; 156 tmp[4] = x_end; 157 tmp[5] = x_end >> 8; 158 tmp[6] = y_end; 159 tmp[7] = y_end >> 8; 160 161 hwa742.extif->set_bits_per_cycle(8); 162 cmd = HWA742_WINDOW_X_START_0; 163 164 hwa742.extif->write_command(&cmd, 1); 165 166 hwa742.extif->write_data(tmp, 8); 167 } 168 169 static void set_format_regs(int conv, int transl, int flags) 170 { 171 if (flags & OMAPFB_FORMAT_FLAG_DOUBLE) { 172 hwa742.window_type = ((hwa742.window_type & 0xfc) | 0x01); 173 #ifdef VERBOSE 174 dev_dbg(hwa742.fbdev->dev, "hwa742: enabled pixel doubling\n"); 175 #endif 176 } else { 177 hwa742.window_type = (hwa742.window_type & 0xfc); 178 #ifdef VERBOSE 179 dev_dbg(hwa742.fbdev->dev, "hwa742: disabled pixel doubling\n"); 180 #endif 181 } 182 183 hwa742_write_reg(HWA742_INPUT_MODE_REG, conv); 184 hwa742_write_reg(HWA742_TRANSL_MODE_REG1, transl); 185 hwa742_write_reg(HWA742_WINDOW_TYPE, hwa742.window_type); 186 } 187 188 static void enable_tearsync(int y, int width, int height, int screen_height, 189 int force_vsync) 190 { 191 u8 b; 192 193 b = hwa742_read_reg(HWA742_NDP_CTRL); 194 b |= 1 << 2; 195 hwa742_write_reg(HWA742_NDP_CTRL, b); 196 197 if (likely(hwa742.vsync_only || force_vsync)) { 198 hwa742.extif->enable_tearsync(1, 0); 199 return; 200 } 201 202 if (width * hwa742.pix_tx_time < hwa742.line_upd_time) { 203 hwa742.extif->enable_tearsync(1, 0); 204 return; 205 } 206 207 if ((width * hwa742.pix_tx_time / 1000) * height < 208 (y + height) * (hwa742.line_upd_time / 1000)) { 209 hwa742.extif->enable_tearsync(1, 0); 210 return; 211 } 212 213 hwa742.extif->enable_tearsync(1, y + 1); 214 } 215 216 static void disable_tearsync(void) 217 { 218 u8 b; 219 220 hwa742.extif->enable_tearsync(0, 0); 221 222 b = hwa742_read_reg(HWA742_NDP_CTRL); 223 b &= ~(1 << 2); 224 hwa742_write_reg(HWA742_NDP_CTRL, b); 225 } 226 227 static inline struct hwa742_request *alloc_req(void) 228 { 229 unsigned long flags; 230 struct hwa742_request *req; 231 int req_flags = 0; 232 233 if (!in_interrupt()) 234 down(&hwa742.req_sema); 235 else 236 req_flags = REQ_FROM_IRQ_POOL; 237 238 spin_lock_irqsave(&hwa742.req_lock, flags); 239 BUG_ON(list_empty(&hwa742.free_req_list)); 240 req = list_entry(hwa742.free_req_list.next, 241 struct hwa742_request, entry); 242 list_del(&req->entry); 243 spin_unlock_irqrestore(&hwa742.req_lock, flags); 244 245 INIT_LIST_HEAD(&req->entry); 246 req->flags = req_flags; 247 248 return req; 249 } 250 251 static inline void free_req(struct hwa742_request *req) 252 { 253 unsigned long flags; 254 255 spin_lock_irqsave(&hwa742.req_lock, flags); 256 257 list_move(&req->entry, &hwa742.free_req_list); 258 if (!(req->flags & REQ_FROM_IRQ_POOL)) 259 up(&hwa742.req_sema); 260 261 spin_unlock_irqrestore(&hwa742.req_lock, flags); 262 } 263 264 static void process_pending_requests(void) 265 { 266 unsigned long flags; 267 268 spin_lock_irqsave(&hwa742.req_lock, flags); 269 270 while (!list_empty(&hwa742.pending_req_list)) { 271 struct hwa742_request *req; 272 void (*complete)(void *); 273 void *complete_data; 274 275 req = list_entry(hwa742.pending_req_list.next, 276 struct hwa742_request, entry); 277 spin_unlock_irqrestore(&hwa742.req_lock, flags); 278 279 if (req->handler(req) == REQ_PENDING) 280 return; 281 282 complete = req->complete; 283 complete_data = req->complete_data; 284 free_req(req); 285 286 if (complete) 287 complete(complete_data); 288 289 spin_lock_irqsave(&hwa742.req_lock, flags); 290 } 291 292 spin_unlock_irqrestore(&hwa742.req_lock, flags); 293 } 294 295 static void submit_req_list(struct list_head *head) 296 { 297 unsigned long flags; 298 int process = 1; 299 300 spin_lock_irqsave(&hwa742.req_lock, flags); 301 if (likely(!list_empty(&hwa742.pending_req_list))) 302 process = 0; 303 list_splice_init(head, hwa742.pending_req_list.prev); 304 spin_unlock_irqrestore(&hwa742.req_lock, flags); 305 306 if (process) 307 process_pending_requests(); 308 } 309 310 static void request_complete(void *data) 311 { 312 struct hwa742_request *req = (struct hwa742_request *)data; 313 void (*complete)(void *); 314 void *complete_data; 315 316 complete = req->complete; 317 complete_data = req->complete_data; 318 319 free_req(req); 320 321 if (complete) 322 complete(complete_data); 323 324 process_pending_requests(); 325 } 326 327 static int send_frame_handler(struct hwa742_request *req) 328 { 329 struct update_param *par = &req->par.update; 330 int x = par->x; 331 int y = par->y; 332 int w = par->width; 333 int h = par->height; 334 int bpp; 335 int conv, transl; 336 unsigned long offset; 337 int color_mode = par->color_mode; 338 int flags = par->flags; 339 int scr_width = hwa742.fbdev->panel->x_res; 340 int scr_height = hwa742.fbdev->panel->y_res; 341 342 #ifdef VERBOSE 343 dev_dbg(hwa742.fbdev->dev, "x %d y %d w %d h %d scr_width %d " 344 "color_mode %d flags %d\n", 345 x, y, w, h, scr_width, color_mode, flags); 346 #endif 347 348 switch (color_mode) { 349 case OMAPFB_COLOR_YUV422: 350 bpp = 16; 351 conv = 0x08; 352 transl = 0x25; 353 break; 354 case OMAPFB_COLOR_YUV420: 355 bpp = 12; 356 conv = 0x09; 357 transl = 0x25; 358 break; 359 case OMAPFB_COLOR_RGB565: 360 bpp = 16; 361 conv = 0x01; 362 transl = 0x05; 363 break; 364 default: 365 return -EINVAL; 366 } 367 368 if (hwa742.prev_flags != flags || 369 hwa742.prev_color_mode != color_mode) { 370 set_format_regs(conv, transl, flags); 371 hwa742.prev_color_mode = color_mode; 372 hwa742.prev_flags = flags; 373 } 374 flags = req->par.update.flags; 375 if (flags & OMAPFB_FORMAT_FLAG_TEARSYNC) 376 enable_tearsync(y, scr_width, h, scr_height, 377 flags & OMAPFB_FORMAT_FLAG_FORCE_VSYNC); 378 else 379 disable_tearsync(); 380 381 set_window_regs(x, y, x + w, y + h); 382 383 offset = (scr_width * y + x) * bpp / 8; 384 385 hwa742.int_ctrl->setup_plane(OMAPFB_PLANE_GFX, 386 OMAPFB_CHANNEL_OUT_LCD, offset, scr_width, 0, 0, w, h, 387 color_mode); 388 389 hwa742.extif->set_bits_per_cycle(16); 390 391 hwa742.int_ctrl->enable_plane(OMAPFB_PLANE_GFX, 1); 392 hwa742.extif->transfer_area(w, h, request_complete, req); 393 394 return REQ_PENDING; 395 } 396 397 static void send_frame_complete(void *data) 398 { 399 hwa742.int_ctrl->enable_plane(OMAPFB_PLANE_GFX, 0); 400 } 401 402 #define ADD_PREQ(_x, _y, _w, _h) do { \ 403 req = alloc_req(); \ 404 req->handler = send_frame_handler; \ 405 req->complete = send_frame_complete; \ 406 req->par.update.x = _x; \ 407 req->par.update.y = _y; \ 408 req->par.update.width = _w; \ 409 req->par.update.height = _h; \ 410 req->par.update.color_mode = color_mode;\ 411 req->par.update.flags = flags; \ 412 list_add_tail(&req->entry, req_head); \ 413 } while(0) 414 415 static void create_req_list(struct omapfb_update_window *win, 416 struct list_head *req_head) 417 { 418 struct hwa742_request *req; 419 int x = win->x; 420 int y = win->y; 421 int width = win->width; 422 int height = win->height; 423 int color_mode; 424 int flags; 425 426 flags = win->format & ~OMAPFB_FORMAT_MASK; 427 color_mode = win->format & OMAPFB_FORMAT_MASK; 428 429 if (x & 1) { 430 ADD_PREQ(x, y, 1, height); 431 width--; 432 x++; 433 flags &= ~OMAPFB_FORMAT_FLAG_TEARSYNC; 434 } 435 if (width & ~1) { 436 unsigned int xspan = width & ~1; 437 unsigned int ystart = y; 438 unsigned int yspan = height; 439 440 if (xspan * height * 2 > hwa742.max_transmit_size) { 441 yspan = hwa742.max_transmit_size / (xspan * 2); 442 ADD_PREQ(x, ystart, xspan, yspan); 443 ystart += yspan; 444 yspan = height - yspan; 445 flags &= ~OMAPFB_FORMAT_FLAG_TEARSYNC; 446 } 447 448 ADD_PREQ(x, ystart, xspan, yspan); 449 x += xspan; 450 width -= xspan; 451 flags &= ~OMAPFB_FORMAT_FLAG_TEARSYNC; 452 } 453 if (width) 454 ADD_PREQ(x, y, 1, height); 455 } 456 457 static void auto_update_complete(void *data) 458 { 459 if (!hwa742.stop_auto_update) 460 mod_timer(&hwa742.auto_update_timer, 461 jiffies + HWA742_AUTO_UPDATE_TIME); 462 } 463 464 static void hwa742_update_window_auto(struct timer_list *unused) 465 { 466 LIST_HEAD(req_list); 467 struct hwa742_request *last; 468 469 create_req_list(&hwa742.auto_update_window, &req_list); 470 last = list_entry(req_list.prev, struct hwa742_request, entry); 471 472 last->complete = auto_update_complete; 473 last->complete_data = NULL; 474 475 submit_req_list(&req_list); 476 } 477 478 int hwa742_update_window_async(struct fb_info *fbi, 479 struct omapfb_update_window *win, 480 void (*complete_callback)(void *arg), 481 void *complete_callback_data) 482 { 483 LIST_HEAD(req_list); 484 struct hwa742_request *last; 485 int r = 0; 486 487 if (hwa742.update_mode != OMAPFB_MANUAL_UPDATE) { 488 dev_dbg(hwa742.fbdev->dev, "invalid update mode\n"); 489 r = -EINVAL; 490 goto out; 491 } 492 if (unlikely(win->format & 493 ~(0x03 | OMAPFB_FORMAT_FLAG_DOUBLE | 494 OMAPFB_FORMAT_FLAG_TEARSYNC | OMAPFB_FORMAT_FLAG_FORCE_VSYNC))) { 495 dev_dbg(hwa742.fbdev->dev, "invalid window flag\n"); 496 r = -EINVAL; 497 goto out; 498 } 499 500 create_req_list(win, &req_list); 501 last = list_entry(req_list.prev, struct hwa742_request, entry); 502 503 last->complete = complete_callback; 504 last->complete_data = (void *)complete_callback_data; 505 506 submit_req_list(&req_list); 507 508 out: 509 return r; 510 } 511 EXPORT_SYMBOL(hwa742_update_window_async); 512 513 static int hwa742_setup_plane(int plane, int channel_out, 514 unsigned long offset, int screen_width, 515 int pos_x, int pos_y, int width, int height, 516 int color_mode) 517 { 518 if (plane != OMAPFB_PLANE_GFX || 519 channel_out != OMAPFB_CHANNEL_OUT_LCD) 520 return -EINVAL; 521 522 return 0; 523 } 524 525 static int hwa742_enable_plane(int plane, int enable) 526 { 527 if (plane != 0) 528 return -EINVAL; 529 530 hwa742.int_ctrl->enable_plane(plane, enable); 531 532 return 0; 533 } 534 535 static int sync_handler(struct hwa742_request *req) 536 { 537 complete(req->par.sync); 538 return REQ_COMPLETE; 539 } 540 541 static void hwa742_sync(void) 542 { 543 LIST_HEAD(req_list); 544 struct hwa742_request *req; 545 struct completion comp; 546 547 req = alloc_req(); 548 549 req->handler = sync_handler; 550 req->complete = NULL; 551 init_completion(&comp); 552 req->par.sync = ∁ 553 554 list_add(&req->entry, &req_list); 555 submit_req_list(&req_list); 556 557 wait_for_completion(&comp); 558 } 559 560 static void hwa742_bind_client(struct omapfb_notifier_block *nb) 561 { 562 dev_dbg(hwa742.fbdev->dev, "update_mode %d\n", hwa742.update_mode); 563 if (hwa742.update_mode == OMAPFB_MANUAL_UPDATE) { 564 omapfb_notify_clients(hwa742.fbdev, OMAPFB_EVENT_READY); 565 } 566 } 567 568 static int hwa742_set_update_mode(enum omapfb_update_mode mode) 569 { 570 if (mode != OMAPFB_MANUAL_UPDATE && mode != OMAPFB_AUTO_UPDATE && 571 mode != OMAPFB_UPDATE_DISABLED) 572 return -EINVAL; 573 574 if (mode == hwa742.update_mode) 575 return 0; 576 577 dev_info(hwa742.fbdev->dev, "HWA742: setting update mode to %s\n", 578 mode == OMAPFB_UPDATE_DISABLED ? "disabled" : 579 (mode == OMAPFB_AUTO_UPDATE ? "auto" : "manual")); 580 581 switch (hwa742.update_mode) { 582 case OMAPFB_MANUAL_UPDATE: 583 omapfb_notify_clients(hwa742.fbdev, OMAPFB_EVENT_DISABLED); 584 break; 585 case OMAPFB_AUTO_UPDATE: 586 hwa742.stop_auto_update = 1; 587 del_timer_sync(&hwa742.auto_update_timer); 588 break; 589 case OMAPFB_UPDATE_DISABLED: 590 break; 591 } 592 593 hwa742.update_mode = mode; 594 hwa742_sync(); 595 hwa742.stop_auto_update = 0; 596 597 switch (mode) { 598 case OMAPFB_MANUAL_UPDATE: 599 omapfb_notify_clients(hwa742.fbdev, OMAPFB_EVENT_READY); 600 break; 601 case OMAPFB_AUTO_UPDATE: 602 hwa742_update_window_auto(0); 603 break; 604 case OMAPFB_UPDATE_DISABLED: 605 break; 606 } 607 608 return 0; 609 } 610 611 static enum omapfb_update_mode hwa742_get_update_mode(void) 612 { 613 return hwa742.update_mode; 614 } 615 616 static unsigned long round_to_extif_ticks(unsigned long ps, int div) 617 { 618 int bus_tick = hwa742.extif_clk_period * div; 619 return (ps + bus_tick - 1) / bus_tick * bus_tick; 620 } 621 622 static int calc_reg_timing(unsigned long sysclk, int div) 623 { 624 struct extif_timings *t; 625 unsigned long systim; 626 627 /* CSOnTime 0, WEOnTime 2 ns, REOnTime 2 ns, 628 * AccessTime 2 ns + 12.2 ns (regs), 629 * WEOffTime = WEOnTime + 1 ns, 630 * REOffTime = REOnTime + 16 ns (regs), 631 * CSOffTime = REOffTime + 1 ns 632 * ReadCycle = 2ns + 2*SYSCLK (regs), 633 * WriteCycle = 2*SYSCLK + 2 ns, 634 * CSPulseWidth = 10 ns */ 635 systim = 1000000000 / (sysclk / 1000); 636 dev_dbg(hwa742.fbdev->dev, "HWA742 systim %lu ps extif_clk_period %u ps" 637 "extif_clk_div %d\n", systim, hwa742.extif_clk_period, div); 638 639 t = &hwa742.reg_timings; 640 memset(t, 0, sizeof(*t)); 641 t->clk_div = div; 642 t->cs_on_time = 0; 643 t->we_on_time = round_to_extif_ticks(t->cs_on_time + 2000, div); 644 t->re_on_time = round_to_extif_ticks(t->cs_on_time + 2000, div); 645 t->access_time = round_to_extif_ticks(t->re_on_time + 12200, div); 646 t->we_off_time = round_to_extif_ticks(t->we_on_time + 1000, div); 647 t->re_off_time = round_to_extif_ticks(t->re_on_time + 16000, div); 648 t->cs_off_time = round_to_extif_ticks(t->re_off_time + 1000, div); 649 t->we_cycle_time = round_to_extif_ticks(2 * systim + 2000, div); 650 if (t->we_cycle_time < t->we_off_time) 651 t->we_cycle_time = t->we_off_time; 652 t->re_cycle_time = round_to_extif_ticks(2 * systim + 2000, div); 653 if (t->re_cycle_time < t->re_off_time) 654 t->re_cycle_time = t->re_off_time; 655 t->cs_pulse_width = 0; 656 657 dev_dbg(hwa742.fbdev->dev, "[reg]cson %d csoff %d reon %d reoff %d\n", 658 t->cs_on_time, t->cs_off_time, t->re_on_time, t->re_off_time); 659 dev_dbg(hwa742.fbdev->dev, "[reg]weon %d weoff %d recyc %d wecyc %d\n", 660 t->we_on_time, t->we_off_time, t->re_cycle_time, 661 t->we_cycle_time); 662 dev_dbg(hwa742.fbdev->dev, "[reg]rdaccess %d cspulse %d\n", 663 t->access_time, t->cs_pulse_width); 664 665 return hwa742.extif->convert_timings(t); 666 } 667 668 static int calc_lut_timing(unsigned long sysclk, int div) 669 { 670 struct extif_timings *t; 671 unsigned long systim; 672 673 /* CSOnTime 0, WEOnTime 2 ns, REOnTime 2 ns, 674 * AccessTime 2 ns + 4 * SYSCLK + 26 (lut), 675 * WEOffTime = WEOnTime + 1 ns, 676 * REOffTime = REOnTime + 4*SYSCLK + 26 ns (lut), 677 * CSOffTime = REOffTime + 1 ns 678 * ReadCycle = 2ns + 4*SYSCLK + 26 ns (lut), 679 * WriteCycle = 2*SYSCLK + 2 ns, 680 * CSPulseWidth = 10 ns 681 */ 682 systim = 1000000000 / (sysclk / 1000); 683 dev_dbg(hwa742.fbdev->dev, "HWA742 systim %lu ps extif_clk_period %u ps" 684 "extif_clk_div %d\n", systim, hwa742.extif_clk_period, div); 685 686 t = &hwa742.lut_timings; 687 memset(t, 0, sizeof(*t)); 688 689 t->clk_div = div; 690 691 t->cs_on_time = 0; 692 t->we_on_time = round_to_extif_ticks(t->cs_on_time + 2000, div); 693 t->re_on_time = round_to_extif_ticks(t->cs_on_time + 2000, div); 694 t->access_time = round_to_extif_ticks(t->re_on_time + 4 * systim + 695 26000, div); 696 t->we_off_time = round_to_extif_ticks(t->we_on_time + 1000, div); 697 t->re_off_time = round_to_extif_ticks(t->re_on_time + 4 * systim + 698 26000, div); 699 t->cs_off_time = round_to_extif_ticks(t->re_off_time + 1000, div); 700 t->we_cycle_time = round_to_extif_ticks(2 * systim + 2000, div); 701 if (t->we_cycle_time < t->we_off_time) 702 t->we_cycle_time = t->we_off_time; 703 t->re_cycle_time = round_to_extif_ticks(2000 + 4 * systim + 26000, div); 704 if (t->re_cycle_time < t->re_off_time) 705 t->re_cycle_time = t->re_off_time; 706 t->cs_pulse_width = 0; 707 708 dev_dbg(hwa742.fbdev->dev, "[lut]cson %d csoff %d reon %d reoff %d\n", 709 t->cs_on_time, t->cs_off_time, t->re_on_time, t->re_off_time); 710 dev_dbg(hwa742.fbdev->dev, "[lut]weon %d weoff %d recyc %d wecyc %d\n", 711 t->we_on_time, t->we_off_time, t->re_cycle_time, 712 t->we_cycle_time); 713 dev_dbg(hwa742.fbdev->dev, "[lut]rdaccess %d cspulse %d\n", 714 t->access_time, t->cs_pulse_width); 715 716 return hwa742.extif->convert_timings(t); 717 } 718 719 static int calc_extif_timings(unsigned long sysclk, int *extif_mem_div) 720 { 721 int max_clk_div; 722 int div; 723 724 hwa742.extif->get_clk_info(&hwa742.extif_clk_period, &max_clk_div); 725 for (div = 1; div < max_clk_div; div++) { 726 if (calc_reg_timing(sysclk, div) == 0) 727 break; 728 } 729 if (div >= max_clk_div) 730 goto err; 731 732 *extif_mem_div = div; 733 734 for (div = 1; div < max_clk_div; div++) { 735 if (calc_lut_timing(sysclk, div) == 0) 736 break; 737 } 738 739 if (div >= max_clk_div) 740 goto err; 741 742 return 0; 743 744 err: 745 dev_err(hwa742.fbdev->dev, "can't setup timings\n"); 746 return -1; 747 } 748 749 static void calc_hwa742_clk_rates(unsigned long ext_clk, 750 unsigned long *sys_clk, unsigned long *pix_clk) 751 { 752 int pix_clk_src; 753 int sys_div = 0, sys_mul = 0; 754 int pix_div; 755 756 pix_clk_src = hwa742_read_reg(HWA742_CLK_SRC_REG); 757 pix_div = ((pix_clk_src >> 3) & 0x1f) + 1; 758 if ((pix_clk_src & (0x3 << 1)) == 0) { 759 /* Source is the PLL */ 760 sys_div = (hwa742_read_reg(HWA742_PLL_DIV_REG) & 0x3f) + 1; 761 sys_mul = (hwa742_read_reg(HWA742_PLL_4_REG) & 0x7f) + 1; 762 *sys_clk = ext_clk * sys_mul / sys_div; 763 } else /* else source is ext clk, or oscillator */ 764 *sys_clk = ext_clk; 765 766 *pix_clk = *sys_clk / pix_div; /* HZ */ 767 dev_dbg(hwa742.fbdev->dev, 768 "ext_clk %ld pix_src %d pix_div %d sys_div %d sys_mul %d\n", 769 ext_clk, pix_clk_src & (0x3 << 1), pix_div, sys_div, sys_mul); 770 dev_dbg(hwa742.fbdev->dev, "sys_clk %ld pix_clk %ld\n", 771 *sys_clk, *pix_clk); 772 } 773 774 775 static int setup_tearsync(unsigned long pix_clk, int extif_div) 776 { 777 int hdisp, vdisp; 778 int hndp, vndp; 779 int hsw, vsw; 780 int hs, vs; 781 int hs_pol_inv, vs_pol_inv; 782 int use_hsvs, use_ndp; 783 u8 b; 784 785 hsw = hwa742_read_reg(HWA742_HS_W_REG); 786 vsw = hwa742_read_reg(HWA742_VS_W_REG); 787 hs_pol_inv = !(hsw & 0x80); 788 vs_pol_inv = !(vsw & 0x80); 789 hsw = hsw & 0x7f; 790 vsw = vsw & 0x3f; 791 792 hdisp = (hwa742_read_reg(HWA742_H_DISP_REG) & 0x7f) * 8; 793 vdisp = hwa742_read_reg(HWA742_V_DISP_1_REG) + 794 ((hwa742_read_reg(HWA742_V_DISP_2_REG) & 0x3) << 8); 795 796 hndp = hwa742_read_reg(HWA742_H_NDP_REG) & 0x7f; 797 vndp = hwa742_read_reg(HWA742_V_NDP_REG); 798 799 /* time to transfer one pixel (16bpp) in ps */ 800 hwa742.pix_tx_time = hwa742.reg_timings.we_cycle_time; 801 if (hwa742.extif->get_max_tx_rate != NULL) { 802 /* 803 * The external interface might have a rate limitation, 804 * if so, we have to maximize our transfer rate. 805 */ 806 unsigned long min_tx_time; 807 unsigned long max_tx_rate = hwa742.extif->get_max_tx_rate(); 808 809 dev_dbg(hwa742.fbdev->dev, "max_tx_rate %ld HZ\n", 810 max_tx_rate); 811 min_tx_time = 1000000000 / (max_tx_rate / 1000); /* ps */ 812 if (hwa742.pix_tx_time < min_tx_time) 813 hwa742.pix_tx_time = min_tx_time; 814 } 815 816 /* time to update one line in ps */ 817 hwa742.line_upd_time = (hdisp + hndp) * 1000000 / (pix_clk / 1000); 818 hwa742.line_upd_time *= 1000; 819 if (hdisp * hwa742.pix_tx_time > hwa742.line_upd_time) 820 /* 821 * transfer speed too low, we might have to use both 822 * HS and VS 823 */ 824 use_hsvs = 1; 825 else 826 /* decent transfer speed, we'll always use only VS */ 827 use_hsvs = 0; 828 829 if (use_hsvs && (hs_pol_inv || vs_pol_inv)) { 830 /* 831 * HS or'ed with VS doesn't work, use the active high 832 * TE signal based on HNDP / VNDP 833 */ 834 use_ndp = 1; 835 hs_pol_inv = 0; 836 vs_pol_inv = 0; 837 hs = hndp; 838 vs = vndp; 839 } else { 840 /* 841 * Use HS or'ed with VS as a TE signal if both are needed 842 * or VNDP if only vsync is needed. 843 */ 844 use_ndp = 0; 845 hs = hsw; 846 vs = vsw; 847 if (!use_hsvs) { 848 hs_pol_inv = 0; 849 vs_pol_inv = 0; 850 } 851 } 852 853 hs = hs * 1000000 / (pix_clk / 1000); /* ps */ 854 hs *= 1000; 855 856 vs = vs * (hdisp + hndp) * 1000000 / (pix_clk / 1000); /* ps */ 857 vs *= 1000; 858 859 if (vs <= hs) 860 return -EDOM; 861 /* set VS to 120% of HS to minimize VS detection time */ 862 vs = hs * 12 / 10; 863 /* minimize HS too */ 864 hs = 10000; 865 866 b = hwa742_read_reg(HWA742_NDP_CTRL); 867 b &= ~0x3; 868 b |= use_hsvs ? 1 : 0; 869 b |= (use_ndp && use_hsvs) ? 0 : 2; 870 hwa742_write_reg(HWA742_NDP_CTRL, b); 871 872 hwa742.vsync_only = !use_hsvs; 873 874 dev_dbg(hwa742.fbdev->dev, 875 "pix_clk %ld HZ pix_tx_time %ld ps line_upd_time %ld ps\n", 876 pix_clk, hwa742.pix_tx_time, hwa742.line_upd_time); 877 dev_dbg(hwa742.fbdev->dev, 878 "hs %d ps vs %d ps mode %d vsync_only %d\n", 879 hs, vs, (b & 0x3), !use_hsvs); 880 881 return hwa742.extif->setup_tearsync(1, hs, vs, 882 hs_pol_inv, vs_pol_inv, extif_div); 883 } 884 885 static void hwa742_get_caps(int plane, struct omapfb_caps *caps) 886 { 887 hwa742.int_ctrl->get_caps(plane, caps); 888 caps->ctrl |= OMAPFB_CAPS_MANUAL_UPDATE | 889 OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE; 890 if (hwa742.te_connected) 891 caps->ctrl |= OMAPFB_CAPS_TEARSYNC; 892 caps->wnd_color |= (1 << OMAPFB_COLOR_RGB565) | 893 (1 << OMAPFB_COLOR_YUV420); 894 } 895 896 static void hwa742_suspend(void) 897 { 898 hwa742.update_mode_before_suspend = hwa742.update_mode; 899 hwa742_set_update_mode(OMAPFB_UPDATE_DISABLED); 900 /* Enable sleep mode */ 901 hwa742_write_reg(HWA742_POWER_SAVE, 1 << 1); 902 clk_disable(hwa742.sys_ck); 903 } 904 905 static void hwa742_resume(void) 906 { 907 clk_enable(hwa742.sys_ck); 908 909 /* Disable sleep mode */ 910 hwa742_write_reg(HWA742_POWER_SAVE, 0); 911 while (1) { 912 /* Loop until PLL output is stabilized */ 913 if (hwa742_read_reg(HWA742_PLL_DIV_REG) & (1 << 7)) 914 break; 915 set_current_state(TASK_UNINTERRUPTIBLE); 916 schedule_timeout(msecs_to_jiffies(5)); 917 } 918 hwa742_set_update_mode(hwa742.update_mode_before_suspend); 919 } 920 921 static int hwa742_init(struct omapfb_device *fbdev, int ext_mode, 922 struct omapfb_mem_desc *req_vram) 923 { 924 int r = 0, i; 925 u8 rev, conf; 926 unsigned long ext_clk; 927 unsigned long sys_clk, pix_clk; 928 int extif_mem_div; 929 struct omapfb_platform_data *omapfb_conf; 930 931 BUG_ON(!fbdev->ext_if || !fbdev->int_ctrl); 932 933 hwa742.fbdev = fbdev; 934 hwa742.extif = fbdev->ext_if; 935 hwa742.int_ctrl = fbdev->int_ctrl; 936 937 omapfb_conf = dev_get_platdata(fbdev->dev); 938 939 hwa742.sys_ck = clk_get(NULL, "hwa_sys_ck"); 940 941 spin_lock_init(&hwa742.req_lock); 942 943 if ((r = hwa742.int_ctrl->init(fbdev, 1, req_vram)) < 0) 944 goto err1; 945 946 if ((r = hwa742.extif->init(fbdev)) < 0) 947 goto err2; 948 949 ext_clk = clk_get_rate(hwa742.sys_ck); 950 if ((r = calc_extif_timings(ext_clk, &extif_mem_div)) < 0) 951 goto err3; 952 hwa742.extif->set_timings(&hwa742.reg_timings); 953 clk_enable(hwa742.sys_ck); 954 955 calc_hwa742_clk_rates(ext_clk, &sys_clk, &pix_clk); 956 if ((r = calc_extif_timings(sys_clk, &extif_mem_div)) < 0) 957 goto err4; 958 hwa742.extif->set_timings(&hwa742.reg_timings); 959 960 rev = hwa742_read_reg(HWA742_REV_CODE_REG); 961 if ((rev & 0xfc) != 0x80) { 962 dev_err(fbdev->dev, "HWA742: invalid revision %02x\n", rev); 963 r = -ENODEV; 964 goto err4; 965 } 966 967 968 if (!(hwa742_read_reg(HWA742_PLL_DIV_REG) & 0x80)) { 969 dev_err(fbdev->dev, 970 "HWA742: controller not initialized by the bootloader\n"); 971 r = -ENODEV; 972 goto err4; 973 } 974 975 if ((r = setup_tearsync(pix_clk, extif_mem_div)) < 0) { 976 dev_err(hwa742.fbdev->dev, 977 "HWA742: can't setup tearing synchronization\n"); 978 goto err4; 979 } 980 hwa742.te_connected = 1; 981 982 hwa742.max_transmit_size = hwa742.extif->max_transmit_size; 983 984 hwa742.update_mode = OMAPFB_UPDATE_DISABLED; 985 986 hwa742.auto_update_window.x = 0; 987 hwa742.auto_update_window.y = 0; 988 hwa742.auto_update_window.width = fbdev->panel->x_res; 989 hwa742.auto_update_window.height = fbdev->panel->y_res; 990 hwa742.auto_update_window.format = 0; 991 992 timer_setup(&hwa742.auto_update_timer, hwa742_update_window_auto, 0); 993 994 hwa742.prev_color_mode = -1; 995 hwa742.prev_flags = 0; 996 997 hwa742.fbdev = fbdev; 998 999 INIT_LIST_HEAD(&hwa742.free_req_list); 1000 INIT_LIST_HEAD(&hwa742.pending_req_list); 1001 for (i = 0; i < ARRAY_SIZE(hwa742.req_pool); i++) 1002 list_add(&hwa742.req_pool[i].entry, &hwa742.free_req_list); 1003 BUG_ON(i <= IRQ_REQ_POOL_SIZE); 1004 sema_init(&hwa742.req_sema, i - IRQ_REQ_POOL_SIZE); 1005 1006 conf = hwa742_read_reg(HWA742_CONFIG_REG); 1007 dev_info(fbdev->dev, ": Epson HWA742 LCD controller rev %d " 1008 "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07); 1009 1010 return 0; 1011 err4: 1012 clk_disable(hwa742.sys_ck); 1013 err3: 1014 hwa742.extif->cleanup(); 1015 err2: 1016 hwa742.int_ctrl->cleanup(); 1017 err1: 1018 return r; 1019 } 1020 1021 static void hwa742_cleanup(void) 1022 { 1023 hwa742_set_update_mode(OMAPFB_UPDATE_DISABLED); 1024 hwa742.extif->cleanup(); 1025 hwa742.int_ctrl->cleanup(); 1026 clk_disable(hwa742.sys_ck); 1027 } 1028 1029 struct lcd_ctrl hwa742_ctrl = { 1030 .name = "hwa742", 1031 .init = hwa742_init, 1032 .cleanup = hwa742_cleanup, 1033 .bind_client = hwa742_bind_client, 1034 .get_caps = hwa742_get_caps, 1035 .set_update_mode = hwa742_set_update_mode, 1036 .get_update_mode = hwa742_get_update_mode, 1037 .setup_plane = hwa742_setup_plane, 1038 .enable_plane = hwa742_enable_plane, 1039 .update_window = hwa742_update_window_async, 1040 .sync = hwa742_sync, 1041 .suspend = hwa742_suspend, 1042 .resume = hwa742_resume, 1043 }; 1044 1045