23 #include <linux/module.h>
32 #define HWA742_REV_CODE_REG 0x0
33 #define HWA742_CONFIG_REG 0x2
34 #define HWA742_PLL_DIV_REG 0x4
35 #define HWA742_PLL_0_REG 0x6
36 #define HWA742_PLL_1_REG 0x8
37 #define HWA742_PLL_2_REG 0xa
38 #define HWA742_PLL_3_REG 0xc
39 #define HWA742_PLL_4_REG 0xe
40 #define HWA742_CLK_SRC_REG 0x12
41 #define HWA742_PANEL_TYPE_REG 0x14
42 #define HWA742_H_DISP_REG 0x16
43 #define HWA742_H_NDP_REG 0x18
44 #define HWA742_V_DISP_1_REG 0x1a
45 #define HWA742_V_DISP_2_REG 0x1c
46 #define HWA742_V_NDP_REG 0x1e
47 #define HWA742_HS_W_REG 0x20
48 #define HWA742_HP_S_REG 0x22
49 #define HWA742_VS_W_REG 0x24
50 #define HWA742_VP_S_REG 0x26
51 #define HWA742_PCLK_POL_REG 0x28
52 #define HWA742_INPUT_MODE_REG 0x2a
53 #define HWA742_TRANSL_MODE_REG1 0x2e
54 #define HWA742_DISP_MODE_REG 0x34
55 #define HWA742_WINDOW_TYPE 0x36
56 #define HWA742_WINDOW_X_START_0 0x38
57 #define HWA742_WINDOW_X_START_1 0x3a
58 #define HWA742_WINDOW_Y_START_0 0x3c
59 #define HWA742_WINDOW_Y_START_1 0x3e
60 #define HWA742_WINDOW_X_END_0 0x40
61 #define HWA742_WINDOW_X_END_1 0x42
62 #define HWA742_WINDOW_Y_END_0 0x44
63 #define HWA742_WINDOW_Y_END_1 0x46
64 #define HWA742_MEMORY_WRITE_LSB 0x48
65 #define HWA742_MEMORY_WRITE_MSB 0x49
66 #define HWA742_MEMORY_READ_0 0x4a
67 #define HWA742_MEMORY_READ_1 0x4c
68 #define HWA742_MEMORY_READ_2 0x4e
69 #define HWA742_POWER_SAVE 0x56
70 #define HWA742_NDP_CTRL 0x58
72 #define HWA742_AUTO_UPDATE_TIME (HZ / 20)
75 #define REQ_POOL_SIZE 24
76 #define IRQ_REQ_POOL_SIZE 4
78 #define REQ_FROM_IRQ_POOL 0x01
80 #define REQ_COMPLETE 0
140 static u8 hwa742_read_reg(
u8 reg)
144 hwa742.extif->set_bits_per_cycle(8);
145 hwa742.extif->write_command(®, 1);
146 hwa742.extif->read_data(&data, 1);
151 static void hwa742_write_reg(
u8 reg,
u8 data)
153 hwa742.extif->set_bits_per_cycle(8);
154 hwa742.extif->write_command(®, 1);
155 hwa742.extif->write_data(&data, 1);
158 static void set_window_regs(
int x_start,
int y_start,
int x_end,
int y_end)
166 tmp[1] = x_start >> 8;
168 tmp[3] = y_start >> 8;
174 hwa742.extif->set_bits_per_cycle(8);
177 hwa742.extif->write_command(&cmd, 1);
179 hwa742.extif->write_data(tmp, 8);
182 static void set_format_regs(
int conv,
int transl,
int flags)
185 hwa742.window_type = ((
hwa742.window_type & 0xfc) | 0x01);
187 dev_dbg(
hwa742.fbdev->dev,
"hwa742: enabled pixel doubling\n");
192 dev_dbg(
hwa742.fbdev->dev,
"hwa742: disabled pixel doubling\n");
201 static void enable_tearsync(
int y,
int width,
int height,
int screen_height,
211 hwa742.extif->enable_tearsync(1, 0);
215 if (width *
hwa742.pix_tx_time <
hwa742.line_upd_time) {
216 hwa742.extif->enable_tearsync(1, 0);
220 if ((width *
hwa742.pix_tx_time / 1000) * height <
221 (y + height) * (
hwa742.line_upd_time / 1000)) {
222 hwa742.extif->enable_tearsync(1, 0);
226 hwa742.extif->enable_tearsync(1, y + 1);
229 static void disable_tearsync(
void)
233 hwa742.extif->enable_tearsync(0, 0);
256 spin_unlock_irqrestore(&
hwa742.req_lock, flags);
258 INIT_LIST_HEAD(&req->
entry);
259 req->
flags = req_flags;
274 spin_unlock_irqrestore(&
hwa742.req_lock, flags);
277 static void process_pending_requests(
void)
283 while (!list_empty(&
hwa742.pending_req_list)) {
290 spin_unlock_irqrestore(&
hwa742.req_lock, flags);
305 spin_unlock_irqrestore(&
hwa742.req_lock, flags);
316 list_splice_init(head,
hwa742.pending_req_list.prev);
317 spin_unlock_irqrestore(&
hwa742.req_lock, flags);
320 process_pending_requests();
323 static void request_complete(
void *data)
337 process_pending_requests();
351 int flags = par->
flags;
352 int scr_width =
hwa742.fbdev->panel->x_res;
353 int scr_height =
hwa742.fbdev->panel->y_res;
356 dev_dbg(
hwa742.fbdev->dev,
"x %d y %d w %d h %d scr_width %d "
357 "color_mode %d flags %d\n",
358 x, y, w, h, scr_width, color_mode, flags);
361 switch (color_mode) {
381 if (
hwa742.prev_flags != flags ||
382 hwa742.prev_color_mode != color_mode) {
383 set_format_regs(conv, transl, flags);
389 enable_tearsync(y, scr_width, h, scr_height,
394 set_window_regs(x, y, x + w, y + h);
396 offset = (scr_width * y +
x) * bpp / 8;
402 hwa742.extif->set_bits_per_cycle(16);
405 hwa742.extif->transfer_area(w, h, request_complete, req);
410 static void send_frame_complete(
void *data)
415 #define ADD_PREQ(_x, _y, _w, _h) do { \
417 req->handler = send_frame_handler; \
418 req->complete = send_frame_complete; \
419 req->par.update.x = _x; \
420 req->par.update.y = _y; \
421 req->par.update.width = _w; \
422 req->par.update.height = _h; \
423 req->par.update.color_mode = color_mode;\
424 req->par.update.flags = flags; \
425 list_add_tail(&req->entry, req_head); \
434 int width = win->
width;
446 flags &= ~OMAPFB_FORMAT_FLAG_TEARSYNC;
449 unsigned int xspan = width & ~1;
450 unsigned int ystart =
y;
451 unsigned int yspan =
height;
453 if (xspan * height * 2 >
hwa742.max_transmit_size) {
454 yspan =
hwa742.max_transmit_size / (xspan * 2);
457 yspan = height - yspan;
458 flags &= ~OMAPFB_FORMAT_FLAG_TEARSYNC;
464 flags &= ~OMAPFB_FORMAT_FLAG_TEARSYNC;
470 static void auto_update_complete(
void *data)
472 if (!
hwa742.stop_auto_update)
477 static void hwa742_update_window_auto(
unsigned long arg)
482 create_req_list(&
hwa742.auto_update_window, &req_list);
485 last->
complete = auto_update_complete;
488 submit_req_list(&req_list);
493 void (*complete_callback)(
void *
arg),
494 void *complete_callback_data)
513 create_req_list(win, &req_list);
519 submit_req_list(&req_list);
526 static int hwa742_setup_plane(
int plane,
int channel_out,
527 unsigned long offset,
int screen_width,
528 int pos_x,
int pos_y,
int width,
int height,
538 static int hwa742_enable_plane(
int plane,
int enable)
543 hwa742.int_ctrl->enable_plane(plane, enable);
554 static void hwa742_sync(
void)
562 req->handler = sync_handler;
563 req->complete =
NULL;
564 init_completion(&comp);
565 req->par.sync = ∁
567 list_add(&req->entry, &req_list);
568 submit_req_list(&req_list);
587 if (mode ==
hwa742.update_mode)
590 dev_info(
hwa742.fbdev->dev,
"HWA742: setting update mode to %s\n",
594 switch (
hwa742.update_mode) {
599 hwa742.stop_auto_update = 1;
608 hwa742.stop_auto_update = 0;
615 hwa742_update_window_auto(0);
626 return hwa742.update_mode;
629 static unsigned long round_to_extif_ticks(
unsigned long ps,
int div)
631 int bus_tick =
hwa742.extif_clk_period *
div;
632 return (ps + bus_tick - 1) / bus_tick * bus_tick;
635 static int calc_reg_timing(
unsigned long sysclk,
int div)
638 unsigned long systim;
648 systim = 1000000000 / (sysclk / 1000);
649 dev_dbg(
hwa742.fbdev->dev,
"HWA742 systim %lu ps extif_clk_period %u ps"
650 "extif_clk_div %d\n", systim,
hwa742.extif_clk_period, div);
662 t->
we_cycle_time = round_to_extif_ticks(2 * systim + 2000, div);
665 t->
re_cycle_time = round_to_extif_ticks(2 * systim + 2000, div);
670 dev_dbg(
hwa742.fbdev->dev,
"[reg]cson %d csoff %d reon %d reoff %d\n",
672 dev_dbg(
hwa742.fbdev->dev,
"[reg]weon %d weoff %d recyc %d wecyc %d\n",
678 return hwa742.extif->convert_timings(t);
681 static int calc_lut_timing(
unsigned long sysclk,
int div)
684 unsigned long systim;
695 systim = 1000000000 / (sysclk / 1000);
696 dev_dbg(
hwa742.fbdev->dev,
"HWA742 systim %lu ps extif_clk_period %u ps"
697 "extif_clk_div %d\n", systim,
hwa742.extif_clk_period, div);
713 t->
we_cycle_time = round_to_extif_ticks(2 * systim + 2000, div);
716 t->
re_cycle_time = round_to_extif_ticks(2000 + 4 * systim + 26000, div);
721 dev_dbg(
hwa742.fbdev->dev,
"[lut]cson %d csoff %d reon %d reoff %d\n",
723 dev_dbg(
hwa742.fbdev->dev,
"[lut]weon %d weoff %d recyc %d wecyc %d\n",
729 return hwa742.extif->convert_timings(t);
732 static int calc_extif_timings(
unsigned long sysclk,
int *extif_mem_div)
737 hwa742.extif->get_clk_info(&
hwa742.extif_clk_period, &max_clk_div);
738 for (div = 1; div < max_clk_div; div++) {
739 if (calc_reg_timing(sysclk, div) == 0)
742 if (div >= max_clk_div)
745 *extif_mem_div =
div;
747 for (div = 1; div < max_clk_div; div++) {
748 if (calc_lut_timing(sysclk, div) == 0)
752 if (div >= max_clk_div)
762 static void calc_hwa742_clk_rates(
unsigned long ext_clk,
763 unsigned long *
sys_clk,
unsigned long *pix_clk)
766 int sys_div = 0, sys_mul = 0;
770 pix_div = ((pix_clk_src >> 3) & 0x1f) + 1;
771 if ((pix_clk_src & (0x3 << 1)) == 0) {
775 *sys_clk = ext_clk * sys_mul / sys_div;
779 *pix_clk = *sys_clk / pix_div;
781 "ext_clk %ld pix_src %d pix_div %d sys_div %d sys_mul %d\n",
782 ext_clk, pix_clk_src & (0x3 << 1), pix_div, sys_div, sys_mul);
788 static int setup_tearsync(
unsigned long pix_clk,
int extif_div)
794 int hs_pol_inv, vs_pol_inv;
795 int use_hsvs, use_ndp;
800 hs_pol_inv = !(hsw & 0x80);
801 vs_pol_inv = !(vsw & 0x80);
819 unsigned long min_tx_time;
820 unsigned long max_tx_rate =
hwa742.extif->get_max_tx_rate();
824 min_tx_time = 1000000000 / (max_tx_rate / 1000);
825 if (
hwa742.pix_tx_time < min_tx_time)
826 hwa742.pix_tx_time = min_tx_time;
830 hwa742.line_upd_time = (hdisp + hndp) * 1000000 / (pix_clk / 1000);
831 hwa742.line_upd_time *= 1000;
842 if (use_hsvs && (hs_pol_inv || vs_pol_inv)) {
866 hs = hs * 1000000 / (pix_clk / 1000);
869 vs = vs * (hdisp + hndp) * 1000000 / (pix_clk / 1000);
881 b |= use_hsvs ? 1 : 0;
882 b |= (use_ndp && use_hsvs) ? 0 : 2;
885 hwa742.vsync_only = !use_hsvs;
888 "pix_clk %ld HZ pix_tx_time %ld ps line_upd_time %ld ps\n",
891 "hs %d ps vs %d ps mode %d vsync_only %d\n",
892 hs, vs, (b & 0x3), !use_hsvs);
894 return hwa742.extif->setup_tearsync(1, hs, vs,
895 hs_pol_inv, vs_pol_inv, extif_div);
900 hwa742.int_ctrl->get_caps(plane, caps);
909 static void hwa742_suspend(
void)
918 static void hwa742_resume(
void)
931 hwa742_set_update_mode(
hwa742.update_mode_before_suspend);
939 unsigned long ext_clk;
940 unsigned long sys_clk, pix_clk;
950 omapfb_conf = fbdev->
dev->platform_data;
956 if ((r =
hwa742.int_ctrl->init(fbdev, 1, req_vram)) < 0)
959 if ((r =
hwa742.extif->init(fbdev)) < 0)
963 if ((r = calc_extif_timings(ext_clk, &extif_mem_div)) < 0)
968 calc_hwa742_clk_rates(ext_clk, &sys_clk, &pix_clk);
969 if ((r = calc_extif_timings(sys_clk, &extif_mem_div)) < 0)
974 if ((rev & 0xfc) != 0x80) {
975 dev_err(fbdev->
dev,
"HWA742: invalid revision %02x\n", rev);
983 "HWA742: controller not initialized by the bootloader\n");
988 if ((r = setup_tearsync(pix_clk, extif_mem_div)) < 0) {
990 "HWA742: can't setup tearing synchronization\n");
995 hwa742.max_transmit_size =
hwa742.extif->max_transmit_size;
999 hwa742.auto_update_window.x = 0;
1000 hwa742.auto_update_window.y = 0;
1001 hwa742.auto_update_window.width = fbdev->
panel->x_res;
1002 hwa742.auto_update_window.height = fbdev->
panel->y_res;
1003 hwa742.auto_update_window.format = 0;
1006 hwa742.auto_update_timer.function = hwa742_update_window_auto;
1007 hwa742.auto_update_timer.data = 0;
1009 hwa742.prev_color_mode = -1;
1014 INIT_LIST_HEAD(&
hwa742.free_req_list);
1015 INIT_LIST_HEAD(&
hwa742.pending_req_list);
1022 dev_info(fbdev->
dev,
": Epson HWA742 LCD controller rev %d "
1023 "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
1031 hwa742.int_ctrl->cleanup();
1036 static void hwa742_cleanup(
void)
1040 hwa742.int_ctrl->cleanup();
1046 .init = hwa742_init,
1047 .cleanup = hwa742_cleanup,
1048 .bind_client = hwa742_bind_client,
1049 .get_caps = hwa742_get_caps,
1050 .set_update_mode = hwa742_set_update_mode,
1051 .get_update_mode = hwa742_get_update_mode,
1052 .setup_plane = hwa742_setup_plane,
1053 .enable_plane = hwa742_enable_plane,
1055 .sync = hwa742_sync,
1056 .suspend = hwa742_suspend,
1057 .resume = hwa742_resume,