aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss/rfbi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2/dss/rfbi.c')
-rw-r--r--drivers/video/omap2/dss/rfbi.c176
1 files changed, 30 insertions, 146 deletions
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 5ea17f49c611..c06fbe0bc678 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -32,8 +32,9 @@
32#include <linux/ktime.h> 32#include <linux/ktime.h>
33#include <linux/hrtimer.h> 33#include <linux/hrtimer.h>
34#include <linux/seq_file.h> 34#include <linux/seq_file.h>
35#include <linux/semaphore.h>
35 36
36#include <plat/display.h> 37#include <video/omapdss.h>
37#include "dss.h" 38#include "dss.h"
38 39
39struct rfbi_reg { u16 idx; }; 40struct rfbi_reg { u16 idx; };
@@ -65,9 +66,6 @@ struct rfbi_reg { u16 idx; };
65#define REG_FLD_MOD(idx, val, start, end) \ 66#define REG_FLD_MOD(idx, val, start, end) \
66 rfbi_write_reg(idx, FLD_MOD(rfbi_read_reg(idx), val, start, end)) 67 rfbi_write_reg(idx, FLD_MOD(rfbi_read_reg(idx), val, start, end))
67 68
68/* To work around an RFBI transfer rate limitation */
69#define OMAP_RFBI_RATE_LIMIT 1
70
71enum omap_rfbi_cycleformat { 69enum omap_rfbi_cycleformat {
72 OMAP_DSS_RFBI_CYCLEFORMAT_1_1 = 0, 70 OMAP_DSS_RFBI_CYCLEFORMAT_1_1 = 0,
73 OMAP_DSS_RFBI_CYCLEFORMAT_2_1 = 1, 71 OMAP_DSS_RFBI_CYCLEFORMAT_2_1 = 1,
@@ -89,11 +87,6 @@ enum omap_rfbi_parallelmode {
89 OMAP_DSS_RFBI_PARALLELMODE_16 = 3, 87 OMAP_DSS_RFBI_PARALLELMODE_16 = 3,
90}; 88};
91 89
92enum update_cmd {
93 RFBI_CMD_UPDATE = 0,
94 RFBI_CMD_SYNC = 1,
95};
96
97static int rfbi_convert_timings(struct rfbi_timings *t); 90static int rfbi_convert_timings(struct rfbi_timings *t);
98static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div); 91static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div);
99 92
@@ -114,20 +107,9 @@ static struct {
114 107
115 struct omap_dss_device *dssdev[2]; 108 struct omap_dss_device *dssdev[2];
116 109
117 struct kfifo cmd_fifo; 110 struct semaphore bus_lock;
118 spinlock_t cmd_lock;
119 struct completion cmd_done;
120 atomic_t cmd_fifo_full;
121 atomic_t cmd_pending;
122} rfbi; 111} rfbi;
123 112
124struct update_region {
125 u16 x;
126 u16 y;
127 u16 w;
128 u16 h;
129};
130
131static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val) 113static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
132{ 114{
133 __raw_writel(val, rfbi.base + idx.idx); 115 __raw_writel(val, rfbi.base + idx.idx);
@@ -146,9 +128,20 @@ static void rfbi_enable_clocks(bool enable)
146 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 128 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
147} 129}
148 130
131void rfbi_bus_lock(void)
132{
133 down(&rfbi.bus_lock);
134}
135EXPORT_SYMBOL(rfbi_bus_lock);
136
137void rfbi_bus_unlock(void)
138{
139 up(&rfbi.bus_lock);
140}
141EXPORT_SYMBOL(rfbi_bus_unlock);
142
149void omap_rfbi_write_command(const void *buf, u32 len) 143void omap_rfbi_write_command(const void *buf, u32 len)
150{ 144{
151 rfbi_enable_clocks(1);
152 switch (rfbi.parallelmode) { 145 switch (rfbi.parallelmode) {
153 case OMAP_DSS_RFBI_PARALLELMODE_8: 146 case OMAP_DSS_RFBI_PARALLELMODE_8:
154 { 147 {
@@ -172,13 +165,11 @@ void omap_rfbi_write_command(const void *buf, u32 len)
172 default: 165 default:
173 BUG(); 166 BUG();
174 } 167 }
175 rfbi_enable_clocks(0);
176} 168}
177EXPORT_SYMBOL(omap_rfbi_write_command); 169EXPORT_SYMBOL(omap_rfbi_write_command);
178 170
179void omap_rfbi_read_data(void *buf, u32 len) 171void omap_rfbi_read_data(void *buf, u32 len)
180{ 172{
181 rfbi_enable_clocks(1);
182 switch (rfbi.parallelmode) { 173 switch (rfbi.parallelmode) {
183 case OMAP_DSS_RFBI_PARALLELMODE_8: 174 case OMAP_DSS_RFBI_PARALLELMODE_8:
184 { 175 {
@@ -206,13 +197,11 @@ void omap_rfbi_read_data(void *buf, u32 len)
206 default: 197 default:
207 BUG(); 198 BUG();
208 } 199 }
209 rfbi_enable_clocks(0);
210} 200}
211EXPORT_SYMBOL(omap_rfbi_read_data); 201EXPORT_SYMBOL(omap_rfbi_read_data);
212 202
213void omap_rfbi_write_data(const void *buf, u32 len) 203void omap_rfbi_write_data(const void *buf, u32 len)
214{ 204{
215 rfbi_enable_clocks(1);
216 switch (rfbi.parallelmode) { 205 switch (rfbi.parallelmode) {
217 case OMAP_DSS_RFBI_PARALLELMODE_8: 206 case OMAP_DSS_RFBI_PARALLELMODE_8:
218 { 207 {
@@ -237,7 +226,6 @@ void omap_rfbi_write_data(const void *buf, u32 len)
237 BUG(); 226 BUG();
238 227
239 } 228 }
240 rfbi_enable_clocks(0);
241} 229}
242EXPORT_SYMBOL(omap_rfbi_write_data); 230EXPORT_SYMBOL(omap_rfbi_write_data);
243 231
@@ -249,8 +237,6 @@ void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
249 int horiz_offset = scr_width - w; 237 int horiz_offset = scr_width - w;
250 int i; 238 int i;
251 239
252 rfbi_enable_clocks(1);
253
254 if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_16 && 240 if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_16 &&
255 rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_8) { 241 rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_8) {
256 const u16 __iomem *pd = buf; 242 const u16 __iomem *pd = buf;
@@ -295,12 +281,10 @@ void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
295 } else { 281 } else {
296 BUG(); 282 BUG();
297 } 283 }
298
299 rfbi_enable_clocks(0);
300} 284}
301EXPORT_SYMBOL(omap_rfbi_write_pixels); 285EXPORT_SYMBOL(omap_rfbi_write_pixels);
302 286
303void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width, 287static void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
304 u16 height, void (*callback)(void *data), void *data) 288 u16 height, void (*callback)(void *data), void *data)
305{ 289{
306 u32 l; 290 u32 l;
@@ -317,8 +301,6 @@ void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
317 rfbi.framedone_callback = callback; 301 rfbi.framedone_callback = callback;
318 rfbi.framedone_callback_data = data; 302 rfbi.framedone_callback_data = data;
319 303
320 rfbi_enable_clocks(1);
321
322 rfbi_write_reg(RFBI_PIXEL_CNT, width * height); 304 rfbi_write_reg(RFBI_PIXEL_CNT, width * height);
323 305
324 l = rfbi_read_reg(RFBI_CONTROL); 306 l = rfbi_read_reg(RFBI_CONTROL);
@@ -337,15 +319,11 @@ static void framedone_callback(void *data, u32 mask)
337 319
338 REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0); 320 REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0);
339 321
340 rfbi_enable_clocks(0);
341
342 callback = rfbi.framedone_callback; 322 callback = rfbi.framedone_callback;
343 rfbi.framedone_callback = NULL; 323 rfbi.framedone_callback = NULL;
344 324
345 if (callback != NULL) 325 if (callback != NULL)
346 callback(rfbi.framedone_callback_data); 326 callback(rfbi.framedone_callback_data);
347
348 atomic_set(&rfbi.cmd_pending, 0);
349} 327}
350 328
351#if 1 /* VERBOSE */ 329#if 1 /* VERBOSE */
@@ -435,7 +413,7 @@ static int calc_extif_timings(struct rfbi_timings *t)
435} 413}
436 414
437 415
438void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t) 416static void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t)
439{ 417{
440 int r; 418 int r;
441 419
@@ -447,7 +425,6 @@ void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t)
447 425
448 BUG_ON(!t->converted); 426 BUG_ON(!t->converted);
449 427
450 rfbi_enable_clocks(1);
451 rfbi_write_reg(RFBI_ONOFF_TIME(rfbi_module), t->tim[0]); 428 rfbi_write_reg(RFBI_ONOFF_TIME(rfbi_module), t->tim[0]);
452 rfbi_write_reg(RFBI_CYCLE_TIME(rfbi_module), t->tim[1]); 429 rfbi_write_reg(RFBI_CYCLE_TIME(rfbi_module), t->tim[1]);
453 430
@@ -456,7 +433,6 @@ void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t)
456 (t->tim[2] ? 1 : 0), 4, 4); 433 (t->tim[2] ? 1 : 0), 4, 4);
457 434
458 rfbi_print_timings(); 435 rfbi_print_timings();
459 rfbi_enable_clocks(0);
460} 436}
461 437
462static int ps_to_rfbi_ticks(int time, int div) 438static int ps_to_rfbi_ticks(int time, int div)
@@ -472,59 +448,6 @@ static int ps_to_rfbi_ticks(int time, int div)
472 return ret; 448 return ret;
473} 449}
474 450
475#ifdef OMAP_RFBI_RATE_LIMIT
476unsigned long rfbi_get_max_tx_rate(void)
477{
478 unsigned long l4_rate, dss1_rate;
479 int min_l4_ticks = 0;
480 int i;
481
482 /* According to TI this can't be calculated so make the
483 * adjustments for a couple of known frequencies and warn for
484 * others.
485 */
486 static const struct {
487 unsigned long l4_clk; /* HZ */
488 unsigned long dss1_clk; /* HZ */
489 unsigned long min_l4_ticks;
490 } ftab[] = {
491 { 55, 132, 7, }, /* 7.86 MPix/s */
492 { 110, 110, 12, }, /* 9.16 MPix/s */
493 { 110, 132, 10, }, /* 11 Mpix/s */
494 { 120, 120, 10, }, /* 12 Mpix/s */
495 { 133, 133, 10, }, /* 13.3 Mpix/s */
496 };
497
498 l4_rate = rfbi.l4_khz / 1000;
499 dss1_rate = dss_clk_get_rate(DSS_CLK_FCK) / 1000000;
500
501 for (i = 0; i < ARRAY_SIZE(ftab); i++) {
502 /* Use a window instead of an exact match, to account
503 * for different DPLL multiplier / divider pairs.
504 */
505 if (abs(ftab[i].l4_clk - l4_rate) < 3 &&
506 abs(ftab[i].dss1_clk - dss1_rate) < 3) {
507 min_l4_ticks = ftab[i].min_l4_ticks;
508 break;
509 }
510 }
511 if (i == ARRAY_SIZE(ftab)) {
512 /* Can't be sure, return anyway the maximum not
513 * rate-limited. This might cause a problem only for the
514 * tearing synchronisation.
515 */
516 DSSERR("can't determine maximum RFBI transfer rate\n");
517 return rfbi.l4_khz * 1000;
518 }
519 return rfbi.l4_khz * 1000 / min_l4_ticks;
520}
521#else
522int rfbi_get_max_tx_rate(void)
523{
524 return rfbi.l4_khz * 1000;
525}
526#endif
527
528static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div) 451static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div)
529{ 452{
530 *clk_period = 1000000000 / rfbi.l4_khz; 453 *clk_period = 1000000000 / rfbi.l4_khz;
@@ -644,7 +567,6 @@ int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode,
644 DSSDBG("setup_te: mode %d hs %d vs %d hs_inv %d vs_inv %d\n", 567 DSSDBG("setup_te: mode %d hs %d vs %d hs_inv %d vs_inv %d\n",
645 mode, hs, vs, hs_pol_inv, vs_pol_inv); 568 mode, hs, vs, hs_pol_inv, vs_pol_inv);
646 569
647 rfbi_enable_clocks(1);
648 rfbi_write_reg(RFBI_HSYNC_WIDTH, hs); 570 rfbi_write_reg(RFBI_HSYNC_WIDTH, hs);
649 rfbi_write_reg(RFBI_VSYNC_WIDTH, vs); 571 rfbi_write_reg(RFBI_VSYNC_WIDTH, vs);
650 572
@@ -657,7 +579,6 @@ int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode,
657 l &= ~(1 << 20); 579 l &= ~(1 << 20);
658 else 580 else
659 l |= 1 << 20; 581 l |= 1 << 20;
660 rfbi_enable_clocks(0);
661 582
662 return 0; 583 return 0;
663} 584}
@@ -672,7 +593,6 @@ int omap_rfbi_enable_te(bool enable, unsigned line)
672 if (line > (1 << 11) - 1) 593 if (line > (1 << 11) - 1)
673 return -EINVAL; 594 return -EINVAL;
674 595
675 rfbi_enable_clocks(1);
676 l = rfbi_read_reg(RFBI_CONFIG(0)); 596 l = rfbi_read_reg(RFBI_CONFIG(0));
677 l &= ~(0x3 << 2); 597 l &= ~(0x3 << 2);
678 if (enable) { 598 if (enable) {
@@ -682,50 +602,12 @@ int omap_rfbi_enable_te(bool enable, unsigned line)
682 rfbi.te_enabled = 0; 602 rfbi.te_enabled = 0;
683 rfbi_write_reg(RFBI_CONFIG(0), l); 603 rfbi_write_reg(RFBI_CONFIG(0), l);
684 rfbi_write_reg(RFBI_LINE_NUMBER, line); 604 rfbi_write_reg(RFBI_LINE_NUMBER, line);
685 rfbi_enable_clocks(0);
686 605
687 return 0; 606 return 0;
688} 607}
689EXPORT_SYMBOL(omap_rfbi_enable_te); 608EXPORT_SYMBOL(omap_rfbi_enable_te);
690 609
691#if 0 610static int rfbi_configure(int rfbi_module, int bpp, int lines)
692static void rfbi_enable_config(int enable1, int enable2)
693{
694 u32 l;
695 int cs = 0;
696
697 if (enable1)
698 cs |= 1<<0;
699 if (enable2)
700 cs |= 1<<1;
701
702 rfbi_enable_clocks(1);
703
704 l = rfbi_read_reg(RFBI_CONTROL);
705
706 l = FLD_MOD(l, cs, 3, 2);
707 l = FLD_MOD(l, 0, 1, 1);
708
709 rfbi_write_reg(RFBI_CONTROL, l);
710
711
712 l = rfbi_read_reg(RFBI_CONFIG(0));
713 l = FLD_MOD(l, 0, 3, 2); /* TRIGGERMODE: ITE */
714 /*l |= FLD_VAL(2, 8, 7); */ /* L4FORMAT, 2pix/L4 */
715 /*l |= FLD_VAL(0, 8, 7); */ /* L4FORMAT, 1pix/L4 */
716
717 l = FLD_MOD(l, 0, 16, 16); /* A0POLARITY */
718 l = FLD_MOD(l, 1, 20, 20); /* TE_VSYNC_POLARITY */
719 l = FLD_MOD(l, 1, 21, 21); /* HSYNCPOLARITY */
720
721 l = FLD_MOD(l, OMAP_DSS_RFBI_PARALLELMODE_8, 1, 0);
722 rfbi_write_reg(RFBI_CONFIG(0), l);
723
724 rfbi_enable_clocks(0);
725}
726#endif
727
728int rfbi_configure(int rfbi_module, int bpp, int lines)
729{ 611{
730 u32 l; 612 u32 l;
731 int cycle1 = 0, cycle2 = 0, cycle3 = 0; 613 int cycle1 = 0, cycle2 = 0, cycle3 = 0;
@@ -821,8 +703,6 @@ int rfbi_configure(int rfbi_module, int bpp, int lines)
821 break; 703 break;
822 } 704 }
823 705
824 rfbi_enable_clocks(1);
825
826 REG_FLD_MOD(RFBI_CONTROL, 0, 3, 2); /* clear CS */ 706 REG_FLD_MOD(RFBI_CONTROL, 0, 3, 2); /* clear CS */
827 707
828 l = 0; 708 l = 0;
@@ -856,11 +736,15 @@ int rfbi_configure(int rfbi_module, int bpp, int lines)
856 DSSDBG("RFBI config: bpp %d, lines %d, cycles: 0x%x 0x%x 0x%x\n", 736 DSSDBG("RFBI config: bpp %d, lines %d, cycles: 0x%x 0x%x 0x%x\n",
857 bpp, lines, cycle1, cycle2, cycle3); 737 bpp, lines, cycle1, cycle2, cycle3);
858 738
859 rfbi_enable_clocks(0);
860
861 return 0; 739 return 0;
862} 740}
863EXPORT_SYMBOL(rfbi_configure); 741
742int omap_rfbi_configure(struct omap_dss_device *dssdev, int pixel_size,
743 int data_lines)
744{
745 return rfbi_configure(dssdev->phy.rfbi.channel, pixel_size, data_lines);
746}
747EXPORT_SYMBOL(omap_rfbi_configure);
864 748
865int omap_rfbi_prepare_update(struct omap_dss_device *dssdev, 749int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
866 u16 *x, u16 *y, u16 *w, u16 *h) 750 u16 *x, u16 *y, u16 *w, u16 *h)
@@ -960,6 +844,8 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
960{ 844{
961 int r; 845 int r;
962 846
847 rfbi_enable_clocks(1);
848
963 r = omap_dss_start_device(dssdev); 849 r = omap_dss_start_device(dssdev);
964 if (r) { 850 if (r) {
965 DSSERR("failed to start device\n"); 851 DSSERR("failed to start device\n");
@@ -1002,6 +888,8 @@ void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev)
1002 omap_dispc_unregister_isr(framedone_callback, NULL, 888 omap_dispc_unregister_isr(framedone_callback, NULL,
1003 DISPC_IRQ_FRAMEDONE); 889 DISPC_IRQ_FRAMEDONE);
1004 omap_dss_stop_device(dssdev); 890 omap_dss_stop_device(dssdev);
891
892 rfbi_enable_clocks(0);
1005} 893}
1006EXPORT_SYMBOL(omapdss_rfbi_display_disable); 894EXPORT_SYMBOL(omapdss_rfbi_display_disable);
1007 895
@@ -1021,11 +909,7 @@ static int omap_rfbihw_probe(struct platform_device *pdev)
1021 909
1022 rfbi.pdev = pdev; 910 rfbi.pdev = pdev;
1023 911
1024 spin_lock_init(&rfbi.cmd_lock); 912 sema_init(&rfbi.bus_lock, 1);
1025
1026 init_completion(&rfbi.cmd_done);
1027 atomic_set(&rfbi.cmd_fifo_full, 0);
1028 atomic_set(&rfbi.cmd_pending, 0);
1029 913
1030 rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0); 914 rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0);
1031 if (!rfbi_mem) { 915 if (!rfbi_mem) {