summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>2019-06-21 09:13:14 -0400
committerBartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>2019-06-21 09:13:14 -0400
commit76c47323c15106f8cbd67c722e85f2eb583b86c1 (patch)
tree73b227026d8dd51e502cadb669020733582dcfd9
parentb6bb068dbd08879ca3cc69c9ec84580b08c17b37 (diff)
video: fbdev: omap2: remove rfbi
Equivalent of drm's commit aa61321d4c08 ("drm/omap: remove rfbi"). The RFBI driver has been marked as BROKEN and has not been included in the kernel build for many years. Just remove it (it can be trivially brought back from git repository if ever needed). Cc: Tomi Valkeinen <tomi.valkeinen@ti.com> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Cc: Aaro Koskinen <aaro.koskinen@iki.fi> Cc: Tony Lindgren <tony@atomide.com> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/Kconfig12
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/Makefile1
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/core.c6
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/dss.h4
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/rfbi.c1078
-rw-r--r--include/video/omapfb_dss.h32
6 files changed, 0 insertions, 1133 deletions
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/Kconfig b/drivers/video/fbdev/omap2/omapfb/dss/Kconfig
index a34820e8ab97..36b97fee2d57 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/Kconfig
+++ b/drivers/video/fbdev/omap2/omapfb/dss/Kconfig
@@ -39,18 +39,6 @@ config FB_OMAP2_DSS_DPI
39 help 39 help
40 DPI Interface. This is the Parallel Display Interface. 40 DPI Interface. This is the Parallel Display Interface.
41 41
42config FB_OMAP2_DSS_RFBI
43 bool "RFBI support"
44 depends on BROKEN
45 help
46 MIPI DBI support (RFBI, Remote Framebuffer Interface, in Texas
47 Instrument's terminology).
48
49 DBI is a bus between the host processor and a peripheral,
50 such as a display or a framebuffer chip.
51
52 See http://www.mipi.org/ for DBI specifications.
53
54config FB_OMAP2_DSS_VENC 42config FB_OMAP2_DSS_VENC
55 bool "VENC support" 43 bool "VENC support"
56 default y 44 default y
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/Makefile b/drivers/video/fbdev/omap2/omapfb/dss/Makefile
index 7318d5260e8d..eb3689ae8d87 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/Makefile
+++ b/drivers/video/fbdev/omap2/omapfb/dss/Makefile
@@ -8,7 +8,6 @@ omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
8omapdss-y += manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o \ 8omapdss-y += manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o \
9 dispc-compat.o display-sysfs.o 9 dispc-compat.o display-sysfs.o
10omapdss-$(CONFIG_FB_OMAP2_DSS_DPI) += dpi.o 10omapdss-$(CONFIG_FB_OMAP2_DSS_DPI) += dpi.o
11omapdss-$(CONFIG_FB_OMAP2_DSS_RFBI) += rfbi.o
12omapdss-$(CONFIG_FB_OMAP2_DSS_VENC) += venc.o 11omapdss-$(CONFIG_FB_OMAP2_DSS_VENC) += venc.o
13omapdss-$(CONFIG_FB_OMAP2_DSS_SDI) += sdi.o 12omapdss-$(CONFIG_FB_OMAP2_DSS_SDI) += sdi.o
14omapdss-$(CONFIG_FB_OMAP2_DSS_DSI) += dsi.o 13omapdss-$(CONFIG_FB_OMAP2_DSS_DSI) += dsi.o
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/core.c b/drivers/video/fbdev/omap2/omapfb/dss/core.c
index b5956a1a30d4..4a35edbc545f 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/core.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/core.c
@@ -218,9 +218,6 @@ static int (*dss_output_drv_reg_funcs[])(void) __initdata = {
218#ifdef CONFIG_FB_OMAP2_DSS_SDI 218#ifdef CONFIG_FB_OMAP2_DSS_SDI
219 sdi_init_platform_driver, 219 sdi_init_platform_driver,
220#endif 220#endif
221#ifdef CONFIG_FB_OMAP2_DSS_RFBI
222 rfbi_init_platform_driver,
223#endif
224#ifdef CONFIG_FB_OMAP2_DSS_VENC 221#ifdef CONFIG_FB_OMAP2_DSS_VENC
225 venc_init_platform_driver, 222 venc_init_platform_driver,
226#endif 223#endif
@@ -242,9 +239,6 @@ static void (*dss_output_drv_unreg_funcs[])(void) = {
242#ifdef CONFIG_FB_OMAP2_DSS_VENC 239#ifdef CONFIG_FB_OMAP2_DSS_VENC
243 venc_uninit_platform_driver, 240 venc_uninit_platform_driver,
244#endif 241#endif
245#ifdef CONFIG_FB_OMAP2_DSS_RFBI
246 rfbi_uninit_platform_driver,
247#endif
248#ifdef CONFIG_FB_OMAP2_DSS_SDI 242#ifdef CONFIG_FB_OMAP2_DSS_SDI
249 sdi_uninit_platform_driver, 243 sdi_uninit_platform_driver,
250#endif 244#endif
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dss.h b/drivers/video/fbdev/omap2/omapfb/dss/dss.h
index b1a354494144..f1acead1c415 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/dss.h
+++ b/drivers/video/fbdev/omap2/omapfb/dss/dss.h
@@ -472,10 +472,6 @@ void hdmi4_uninit_platform_driver(void);
472int hdmi5_init_platform_driver(void) __init; 472int hdmi5_init_platform_driver(void) __init;
473void hdmi5_uninit_platform_driver(void); 473void hdmi5_uninit_platform_driver(void);
474 474
475/* RFBI */
476int rfbi_init_platform_driver(void) __init;
477void rfbi_uninit_platform_driver(void);
478
479 475
480#ifdef CONFIG_FB_OMAP2_DSS_COLLECT_IRQ_STATS 476#ifdef CONFIG_FB_OMAP2_DSS_COLLECT_IRQ_STATS
481static inline void dss_collect_irq_stats(u32 irqstatus, unsigned *irq_arr) 477static inline void dss_collect_irq_stats(u32 irqstatus, unsigned *irq_arr)
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/rfbi.c b/drivers/video/fbdev/omap2/omapfb/dss/rfbi.c
deleted file mode 100644
index 562b0c4ae0c6..000000000000
--- a/drivers/video/fbdev/omap2/omapfb/dss/rfbi.c
+++ /dev/null
@@ -1,1078 +0,0 @@
1/*
2 * linux/drivers/video/omap2/dss/rfbi.c
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
6 *
7 * Some code and ideas taken from drivers/video/omap/ driver
8 * by Imre Deak.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published by
12 * the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18 *
19 * You should have received a copy of the GNU General Public License along with
20 * this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23#define DSS_SUBSYS_NAME "RFBI"
24
25#include <linux/kernel.h>
26#include <linux/dma-mapping.h>
27#include <linux/export.h>
28#include <linux/vmalloc.h>
29#include <linux/clk.h>
30#include <linux/io.h>
31#include <linux/delay.h>
32#include <linux/kfifo.h>
33#include <linux/ktime.h>
34#include <linux/hrtimer.h>
35#include <linux/seq_file.h>
36#include <linux/semaphore.h>
37#include <linux/platform_device.h>
38#include <linux/pm_runtime.h>
39#include <linux/component.h>
40
41#include <video/omapfb_dss.h>
42#include "dss.h"
43
44struct rfbi_reg { u16 idx; };
45
46#define RFBI_REG(idx) ((const struct rfbi_reg) { idx })
47
48#define RFBI_REVISION RFBI_REG(0x0000)
49#define RFBI_SYSCONFIG RFBI_REG(0x0010)
50#define RFBI_SYSSTATUS RFBI_REG(0x0014)
51#define RFBI_CONTROL RFBI_REG(0x0040)
52#define RFBI_PIXEL_CNT RFBI_REG(0x0044)
53#define RFBI_LINE_NUMBER RFBI_REG(0x0048)
54#define RFBI_CMD RFBI_REG(0x004c)
55#define RFBI_PARAM RFBI_REG(0x0050)
56#define RFBI_DATA RFBI_REG(0x0054)
57#define RFBI_READ RFBI_REG(0x0058)
58#define RFBI_STATUS RFBI_REG(0x005c)
59
60#define RFBI_CONFIG(n) RFBI_REG(0x0060 + (n)*0x18)
61#define RFBI_ONOFF_TIME(n) RFBI_REG(0x0064 + (n)*0x18)
62#define RFBI_CYCLE_TIME(n) RFBI_REG(0x0068 + (n)*0x18)
63#define RFBI_DATA_CYCLE1(n) RFBI_REG(0x006c + (n)*0x18)
64#define RFBI_DATA_CYCLE2(n) RFBI_REG(0x0070 + (n)*0x18)
65#define RFBI_DATA_CYCLE3(n) RFBI_REG(0x0074 + (n)*0x18)
66
67#define RFBI_VSYNC_WIDTH RFBI_REG(0x0090)
68#define RFBI_HSYNC_WIDTH RFBI_REG(0x0094)
69
70#define REG_FLD_MOD(idx, val, start, end) \
71 rfbi_write_reg(idx, FLD_MOD(rfbi_read_reg(idx), val, start, end))
72
73enum omap_rfbi_cycleformat {
74 OMAP_DSS_RFBI_CYCLEFORMAT_1_1 = 0,
75 OMAP_DSS_RFBI_CYCLEFORMAT_2_1 = 1,
76 OMAP_DSS_RFBI_CYCLEFORMAT_3_1 = 2,
77 OMAP_DSS_RFBI_CYCLEFORMAT_3_2 = 3,
78};
79
80enum omap_rfbi_datatype {
81 OMAP_DSS_RFBI_DATATYPE_12 = 0,
82 OMAP_DSS_RFBI_DATATYPE_16 = 1,
83 OMAP_DSS_RFBI_DATATYPE_18 = 2,
84 OMAP_DSS_RFBI_DATATYPE_24 = 3,
85};
86
87enum omap_rfbi_parallelmode {
88 OMAP_DSS_RFBI_PARALLELMODE_8 = 0,
89 OMAP_DSS_RFBI_PARALLELMODE_9 = 1,
90 OMAP_DSS_RFBI_PARALLELMODE_12 = 2,
91 OMAP_DSS_RFBI_PARALLELMODE_16 = 3,
92};
93
94static int rfbi_convert_timings(struct rfbi_timings *t);
95static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div);
96
97static struct {
98 struct platform_device *pdev;
99 void __iomem *base;
100
101 unsigned long l4_khz;
102
103 enum omap_rfbi_datatype datatype;
104 enum omap_rfbi_parallelmode parallelmode;
105
106 enum omap_rfbi_te_mode te_mode;
107 int te_enabled;
108
109 void (*framedone_callback)(void *data);
110 void *framedone_callback_data;
111
112 struct omap_dss_device *dssdev[2];
113
114 struct semaphore bus_lock;
115
116 struct omap_video_timings timings;
117 int pixel_size;
118 int data_lines;
119 struct rfbi_timings intf_timings;
120
121 struct omap_dss_device output;
122} rfbi;
123
124static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
125{
126 __raw_writel(val, rfbi.base + idx.idx);
127}
128
129static inline u32 rfbi_read_reg(const struct rfbi_reg idx)
130{
131 return __raw_readl(rfbi.base + idx.idx);
132}
133
134static int rfbi_runtime_get(void)
135{
136 int r;
137
138 DSSDBG("rfbi_runtime_get\n");
139
140 r = pm_runtime_get_sync(&rfbi.pdev->dev);
141 WARN_ON(r < 0);
142 return r < 0 ? r : 0;
143}
144
145static void rfbi_runtime_put(void)
146{
147 int r;
148
149 DSSDBG("rfbi_runtime_put\n");
150
151 r = pm_runtime_put_sync(&rfbi.pdev->dev);
152 WARN_ON(r < 0 && r != -ENOSYS);
153}
154
155static void rfbi_bus_lock(void)
156{
157 down(&rfbi.bus_lock);
158}
159
160static void rfbi_bus_unlock(void)
161{
162 up(&rfbi.bus_lock);
163}
164
165static void rfbi_write_command(const void *buf, u32 len)
166{
167 switch (rfbi.parallelmode) {
168 case OMAP_DSS_RFBI_PARALLELMODE_8:
169 {
170 const u8 *b = buf;
171 for (; len; len--)
172 rfbi_write_reg(RFBI_CMD, *b++);
173 break;
174 }
175
176 case OMAP_DSS_RFBI_PARALLELMODE_16:
177 {
178 const u16 *w = buf;
179 BUG_ON(len & 1);
180 for (; len; len -= 2)
181 rfbi_write_reg(RFBI_CMD, *w++);
182 break;
183 }
184
185 case OMAP_DSS_RFBI_PARALLELMODE_9:
186 case OMAP_DSS_RFBI_PARALLELMODE_12:
187 default:
188 BUG();
189 }
190}
191
192static void rfbi_read_data(void *buf, u32 len)
193{
194 switch (rfbi.parallelmode) {
195 case OMAP_DSS_RFBI_PARALLELMODE_8:
196 {
197 u8 *b = buf;
198 for (; len; len--) {
199 rfbi_write_reg(RFBI_READ, 0);
200 *b++ = rfbi_read_reg(RFBI_READ);
201 }
202 break;
203 }
204
205 case OMAP_DSS_RFBI_PARALLELMODE_16:
206 {
207 u16 *w = buf;
208 BUG_ON(len & ~1);
209 for (; len; len -= 2) {
210 rfbi_write_reg(RFBI_READ, 0);
211 *w++ = rfbi_read_reg(RFBI_READ);
212 }
213 break;
214 }
215
216 case OMAP_DSS_RFBI_PARALLELMODE_9:
217 case OMAP_DSS_RFBI_PARALLELMODE_12:
218 default:
219 BUG();
220 }
221}
222
223static void rfbi_write_data(const void *buf, u32 len)
224{
225 switch (rfbi.parallelmode) {
226 case OMAP_DSS_RFBI_PARALLELMODE_8:
227 {
228 const u8 *b = buf;
229 for (; len; len--)
230 rfbi_write_reg(RFBI_PARAM, *b++);
231 break;
232 }
233
234 case OMAP_DSS_RFBI_PARALLELMODE_16:
235 {
236 const u16 *w = buf;
237 BUG_ON(len & 1);
238 for (; len; len -= 2)
239 rfbi_write_reg(RFBI_PARAM, *w++);
240 break;
241 }
242
243 case OMAP_DSS_RFBI_PARALLELMODE_9:
244 case OMAP_DSS_RFBI_PARALLELMODE_12:
245 default:
246 BUG();
247
248 }
249}
250
251static void rfbi_write_pixels(const void __iomem *buf, int scr_width,
252 u16 x, u16 y,
253 u16 w, u16 h)
254{
255 int start_offset = scr_width * y + x;
256 int horiz_offset = scr_width - w;
257 int i;
258
259 if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_16 &&
260 rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_8) {
261 const u16 __iomem *pd = buf;
262 pd += start_offset;
263
264 for (; h; --h) {
265 for (i = 0; i < w; ++i) {
266 const u8 __iomem *b = (const u8 __iomem *)pd;
267 rfbi_write_reg(RFBI_PARAM, __raw_readb(b+1));
268 rfbi_write_reg(RFBI_PARAM, __raw_readb(b+0));
269 ++pd;
270 }
271 pd += horiz_offset;
272 }
273 } else if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_24 &&
274 rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_8) {
275 const u32 __iomem *pd = buf;
276 pd += start_offset;
277
278 for (; h; --h) {
279 for (i = 0; i < w; ++i) {
280 const u8 __iomem *b = (const u8 __iomem *)pd;
281 rfbi_write_reg(RFBI_PARAM, __raw_readb(b+2));
282 rfbi_write_reg(RFBI_PARAM, __raw_readb(b+1));
283 rfbi_write_reg(RFBI_PARAM, __raw_readb(b+0));
284 ++pd;
285 }
286 pd += horiz_offset;
287 }
288 } else if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_16 &&
289 rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_16) {
290 const u16 __iomem *pd = buf;
291 pd += start_offset;
292
293 for (; h; --h) {
294 for (i = 0; i < w; ++i) {
295 rfbi_write_reg(RFBI_PARAM, __raw_readw(pd));
296 ++pd;
297 }
298 pd += horiz_offset;
299 }
300 } else {
301 BUG();
302 }
303}
304
305static int rfbi_transfer_area(struct omap_dss_device *dssdev,
306 void (*callback)(void *data), void *data)
307{
308 u32 l;
309 int r;
310 struct omap_overlay_manager *mgr = rfbi.output.manager;
311 u16 width = rfbi.timings.x_res;
312 u16 height = rfbi.timings.y_res;
313
314 /*BUG_ON(callback == 0);*/
315 BUG_ON(rfbi.framedone_callback != NULL);
316
317 DSSDBG("rfbi_transfer_area %dx%d\n", width, height);
318
319 dss_mgr_set_timings(mgr, &rfbi.timings);
320
321 r = dss_mgr_enable(mgr);
322 if (r)
323 return r;
324
325 rfbi.framedone_callback = callback;
326 rfbi.framedone_callback_data = data;
327
328 rfbi_write_reg(RFBI_PIXEL_CNT, width * height);
329
330 l = rfbi_read_reg(RFBI_CONTROL);
331 l = FLD_MOD(l, 1, 0, 0); /* enable */
332 if (!rfbi.te_enabled)
333 l = FLD_MOD(l, 1, 4, 4); /* ITE */
334
335 rfbi_write_reg(RFBI_CONTROL, l);
336
337 return 0;
338}
339
340static void framedone_callback(void *data)
341{
342 void (*callback)(void *data);
343
344 DSSDBG("FRAMEDONE\n");
345
346 REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0);
347
348 callback = rfbi.framedone_callback;
349 rfbi.framedone_callback = NULL;
350
351 if (callback != NULL)
352 callback(rfbi.framedone_callback_data);
353}
354
355#if 1 /* VERBOSE */
356static void rfbi_print_timings(void)
357{
358 u32 l;
359 u32 time;
360
361 l = rfbi_read_reg(RFBI_CONFIG(0));
362 time = 1000000000 / rfbi.l4_khz;
363 if (l & (1 << 4))
364 time *= 2;
365
366 DSSDBG("Tick time %u ps\n", time);
367 l = rfbi_read_reg(RFBI_ONOFF_TIME(0));
368 DSSDBG("CSONTIME %d, CSOFFTIME %d, WEONTIME %d, WEOFFTIME %d, "
369 "REONTIME %d, REOFFTIME %d\n",
370 l & 0x0f, (l >> 4) & 0x3f, (l >> 10) & 0x0f, (l >> 14) & 0x3f,
371 (l >> 20) & 0x0f, (l >> 24) & 0x3f);
372
373 l = rfbi_read_reg(RFBI_CYCLE_TIME(0));
374 DSSDBG("WECYCLETIME %d, RECYCLETIME %d, CSPULSEWIDTH %d, "
375 "ACCESSTIME %d\n",
376 (l & 0x3f), (l >> 6) & 0x3f, (l >> 12) & 0x3f,
377 (l >> 22) & 0x3f);
378}
379#else
380static void rfbi_print_timings(void) {}
381#endif
382
383
384
385
386static u32 extif_clk_period;
387
388static inline unsigned long round_to_extif_ticks(unsigned long ps, int div)
389{
390 int bus_tick = extif_clk_period * div;
391 return (ps + bus_tick - 1) / bus_tick * bus_tick;
392}
393
394static int calc_reg_timing(struct rfbi_timings *t, int div)
395{
396 t->clk_div = div;
397
398 t->cs_on_time = round_to_extif_ticks(t->cs_on_time, div);
399
400 t->we_on_time = round_to_extif_ticks(t->we_on_time, div);
401 t->we_off_time = round_to_extif_ticks(t->we_off_time, div);
402 t->we_cycle_time = round_to_extif_ticks(t->we_cycle_time, div);
403
404 t->re_on_time = round_to_extif_ticks(t->re_on_time, div);
405 t->re_off_time = round_to_extif_ticks(t->re_off_time, div);
406 t->re_cycle_time = round_to_extif_ticks(t->re_cycle_time, div);
407
408 t->access_time = round_to_extif_ticks(t->access_time, div);
409 t->cs_off_time = round_to_extif_ticks(t->cs_off_time, div);
410 t->cs_pulse_width = round_to_extif_ticks(t->cs_pulse_width, div);
411
412 DSSDBG("[reg]cson %d csoff %d reon %d reoff %d\n",
413 t->cs_on_time, t->cs_off_time, t->re_on_time, t->re_off_time);
414 DSSDBG("[reg]weon %d weoff %d recyc %d wecyc %d\n",
415 t->we_on_time, t->we_off_time, t->re_cycle_time,
416 t->we_cycle_time);
417 DSSDBG("[reg]rdaccess %d cspulse %d\n",
418 t->access_time, t->cs_pulse_width);
419
420 return rfbi_convert_timings(t);
421}
422
423static int calc_extif_timings(struct rfbi_timings *t)
424{
425 u32 max_clk_div;
426 int div;
427
428 rfbi_get_clk_info(&extif_clk_period, &max_clk_div);
429 for (div = 1; div <= max_clk_div; div++) {
430 if (calc_reg_timing(t, div) == 0)
431 break;
432 }
433
434 if (div <= max_clk_div)
435 return 0;
436
437 DSSERR("can't setup timings\n");
438 return -1;
439}
440
441
442static void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t)
443{
444 int r;
445
446 if (!t->converted) {
447 r = calc_extif_timings(t);
448 if (r < 0)
449 DSSERR("Failed to calc timings\n");
450 }
451
452 BUG_ON(!t->converted);
453
454 rfbi_write_reg(RFBI_ONOFF_TIME(rfbi_module), t->tim[0]);
455 rfbi_write_reg(RFBI_CYCLE_TIME(rfbi_module), t->tim[1]);
456
457 /* TIMEGRANULARITY */
458 REG_FLD_MOD(RFBI_CONFIG(rfbi_module),
459 (t->tim[2] ? 1 : 0), 4, 4);
460
461 rfbi_print_timings();
462}
463
464static int ps_to_rfbi_ticks(int time, int div)
465{
466 unsigned long tick_ps;
467 int ret;
468
469 /* Calculate in picosecs to yield more exact results */
470 tick_ps = 1000000000 / (rfbi.l4_khz) * div;
471
472 ret = (time + tick_ps - 1) / tick_ps;
473
474 return ret;
475}
476
477static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div)
478{
479 *clk_period = 1000000000 / rfbi.l4_khz;
480 *max_clk_div = 2;
481}
482
483static int rfbi_convert_timings(struct rfbi_timings *t)
484{
485 u32 l;
486 int reon, reoff, weon, weoff, cson, csoff, cs_pulse;
487 int actim, recyc, wecyc;
488 int div = t->clk_div;
489
490 if (div <= 0 || div > 2)
491 return -1;
492
493 /* Make sure that after conversion it still holds that:
494 * weoff > weon, reoff > reon, recyc >= reoff, wecyc >= weoff,
495 * csoff > cson, csoff >= max(weoff, reoff), actim > reon
496 */
497 weon = ps_to_rfbi_ticks(t->we_on_time, div);
498 weoff = ps_to_rfbi_ticks(t->we_off_time, div);
499 if (weoff <= weon)
500 weoff = weon + 1;
501 if (weon > 0x0f)
502 return -1;
503 if (weoff > 0x3f)
504 return -1;
505
506 reon = ps_to_rfbi_ticks(t->re_on_time, div);
507 reoff = ps_to_rfbi_ticks(t->re_off_time, div);
508 if (reoff <= reon)
509 reoff = reon + 1;
510 if (reon > 0x0f)
511 return -1;
512 if (reoff > 0x3f)
513 return -1;
514
515 cson = ps_to_rfbi_ticks(t->cs_on_time, div);
516 csoff = ps_to_rfbi_ticks(t->cs_off_time, div);
517 if (csoff <= cson)
518 csoff = cson + 1;
519 if (csoff < max(weoff, reoff))
520 csoff = max(weoff, reoff);
521 if (cson > 0x0f)
522 return -1;
523 if (csoff > 0x3f)
524 return -1;
525
526 l = cson;
527 l |= csoff << 4;
528 l |= weon << 10;
529 l |= weoff << 14;
530 l |= reon << 20;
531 l |= reoff << 24;
532
533 t->tim[0] = l;
534
535 actim = ps_to_rfbi_ticks(t->access_time, div);
536 if (actim <= reon)
537 actim = reon + 1;
538 if (actim > 0x3f)
539 return -1;
540
541 wecyc = ps_to_rfbi_ticks(t->we_cycle_time, div);
542 if (wecyc < weoff)
543 wecyc = weoff;
544 if (wecyc > 0x3f)
545 return -1;
546
547 recyc = ps_to_rfbi_ticks(t->re_cycle_time, div);
548 if (recyc < reoff)
549 recyc = reoff;
550 if (recyc > 0x3f)
551 return -1;
552
553 cs_pulse = ps_to_rfbi_ticks(t->cs_pulse_width, div);
554 if (cs_pulse > 0x3f)
555 return -1;
556
557 l = wecyc;
558 l |= recyc << 6;
559 l |= cs_pulse << 12;
560 l |= actim << 22;
561
562 t->tim[1] = l;
563
564 t->tim[2] = div - 1;
565
566 t->converted = 1;
567
568 return 0;
569}
570
571/* xxx FIX module selection missing */
572static int rfbi_setup_te(enum omap_rfbi_te_mode mode,
573 unsigned hs_pulse_time, unsigned vs_pulse_time,
574 int hs_pol_inv, int vs_pol_inv, int extif_div)
575{
576 int hs, vs;
577 int min;
578 u32 l;
579
580 hs = ps_to_rfbi_ticks(hs_pulse_time, 1);
581 vs = ps_to_rfbi_ticks(vs_pulse_time, 1);
582 if (hs < 2)
583 return -EDOM;
584 if (mode == OMAP_DSS_RFBI_TE_MODE_2)
585 min = 2;
586 else /* OMAP_DSS_RFBI_TE_MODE_1 */
587 min = 4;
588 if (vs < min)
589 return -EDOM;
590 if (vs == hs)
591 return -EINVAL;
592 rfbi.te_mode = mode;
593 DSSDBG("setup_te: mode %d hs %d vs %d hs_inv %d vs_inv %d\n",
594 mode, hs, vs, hs_pol_inv, vs_pol_inv);
595
596 rfbi_write_reg(RFBI_HSYNC_WIDTH, hs);
597 rfbi_write_reg(RFBI_VSYNC_WIDTH, vs);
598
599 l = rfbi_read_reg(RFBI_CONFIG(0));
600 if (hs_pol_inv)
601 l &= ~(1 << 21);
602 else
603 l |= 1 << 21;
604 if (vs_pol_inv)
605 l &= ~(1 << 20);
606 else
607 l |= 1 << 20;
608
609 return 0;
610}
611
612/* xxx FIX module selection missing */
613static int rfbi_enable_te(bool enable, unsigned line)
614{
615 u32 l;
616
617 DSSDBG("te %d line %d mode %d\n", enable, line, rfbi.te_mode);
618 if (line > (1 << 11) - 1)
619 return -EINVAL;
620
621 l = rfbi_read_reg(RFBI_CONFIG(0));
622 l &= ~(0x3 << 2);
623 if (enable) {
624 rfbi.te_enabled = 1;
625 l |= rfbi.te_mode << 2;
626 } else
627 rfbi.te_enabled = 0;
628 rfbi_write_reg(RFBI_CONFIG(0), l);
629 rfbi_write_reg(RFBI_LINE_NUMBER, line);
630
631 return 0;
632}
633
634static int rfbi_configure_bus(int rfbi_module, int bpp, int lines)
635{
636 u32 l;
637 int cycle1 = 0, cycle2 = 0, cycle3 = 0;
638 enum omap_rfbi_cycleformat cycleformat;
639 enum omap_rfbi_datatype datatype;
640 enum omap_rfbi_parallelmode parallelmode;
641
642 switch (bpp) {
643 case 12:
644 datatype = OMAP_DSS_RFBI_DATATYPE_12;
645 break;
646 case 16:
647 datatype = OMAP_DSS_RFBI_DATATYPE_16;
648 break;
649 case 18:
650 datatype = OMAP_DSS_RFBI_DATATYPE_18;
651 break;
652 case 24:
653 datatype = OMAP_DSS_RFBI_DATATYPE_24;
654 break;
655 default:
656 BUG();
657 return 1;
658 }
659 rfbi.datatype = datatype;
660
661 switch (lines) {
662 case 8:
663 parallelmode = OMAP_DSS_RFBI_PARALLELMODE_8;
664 break;
665 case 9:
666 parallelmode = OMAP_DSS_RFBI_PARALLELMODE_9;
667 break;
668 case 12:
669 parallelmode = OMAP_DSS_RFBI_PARALLELMODE_12;
670 break;
671 case 16:
672 parallelmode = OMAP_DSS_RFBI_PARALLELMODE_16;
673 break;
674 default:
675 BUG();
676 return 1;
677 }
678 rfbi.parallelmode = parallelmode;
679
680 if ((bpp % lines) == 0) {
681 switch (bpp / lines) {
682 case 1:
683 cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_1_1;
684 break;
685 case 2:
686 cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_2_1;
687 break;
688 case 3:
689 cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_3_1;
690 break;
691 default:
692 BUG();
693 return 1;
694 }
695 } else if ((2 * bpp % lines) == 0) {
696 if ((2 * bpp / lines) == 3)
697 cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_3_2;
698 else {
699 BUG();
700 return 1;
701 }
702 } else {
703 BUG();
704 return 1;
705 }
706
707 switch (cycleformat) {
708 case OMAP_DSS_RFBI_CYCLEFORMAT_1_1:
709 cycle1 = lines;
710 break;
711
712 case OMAP_DSS_RFBI_CYCLEFORMAT_2_1:
713 cycle1 = lines;
714 cycle2 = lines;
715 break;
716
717 case OMAP_DSS_RFBI_CYCLEFORMAT_3_1:
718 cycle1 = lines;
719 cycle2 = lines;
720 cycle3 = lines;
721 break;
722
723 case OMAP_DSS_RFBI_CYCLEFORMAT_3_2:
724 cycle1 = lines;
725 cycle2 = (lines / 2) | ((lines / 2) << 16);
726 cycle3 = (lines << 16);
727 break;
728 }
729
730 REG_FLD_MOD(RFBI_CONTROL, 0, 3, 2); /* clear CS */
731
732 l = 0;
733 l |= FLD_VAL(parallelmode, 1, 0);
734 l |= FLD_VAL(0, 3, 2); /* TRIGGERMODE: ITE */
735 l |= FLD_VAL(0, 4, 4); /* TIMEGRANULARITY */
736 l |= FLD_VAL(datatype, 6, 5);
737 /* l |= FLD_VAL(2, 8, 7); */ /* L4FORMAT, 2pix/L4 */
738 l |= FLD_VAL(0, 8, 7); /* L4FORMAT, 1pix/L4 */
739 l |= FLD_VAL(cycleformat, 10, 9);
740 l |= FLD_VAL(0, 12, 11); /* UNUSEDBITS */
741 l |= FLD_VAL(0, 16, 16); /* A0POLARITY */
742 l |= FLD_VAL(0, 17, 17); /* REPOLARITY */
743 l |= FLD_VAL(0, 18, 18); /* WEPOLARITY */
744 l |= FLD_VAL(0, 19, 19); /* CSPOLARITY */
745 l |= FLD_VAL(1, 20, 20); /* TE_VSYNC_POLARITY */
746 l |= FLD_VAL(1, 21, 21); /* HSYNCPOLARITY */
747 rfbi_write_reg(RFBI_CONFIG(rfbi_module), l);
748
749 rfbi_write_reg(RFBI_DATA_CYCLE1(rfbi_module), cycle1);
750 rfbi_write_reg(RFBI_DATA_CYCLE2(rfbi_module), cycle2);
751 rfbi_write_reg(RFBI_DATA_CYCLE3(rfbi_module), cycle3);
752
753
754 l = rfbi_read_reg(RFBI_CONTROL);
755 l = FLD_MOD(l, rfbi_module+1, 3, 2); /* Select CSx */
756 l = FLD_MOD(l, 0, 1, 1); /* clear bypass */
757 rfbi_write_reg(RFBI_CONTROL, l);
758
759
760 DSSDBG("RFBI config: bpp %d, lines %d, cycles: 0x%x 0x%x 0x%x\n",
761 bpp, lines, cycle1, cycle2, cycle3);
762
763 return 0;
764}
765
766static int rfbi_configure(struct omap_dss_device *dssdev)
767{
768 return rfbi_configure_bus(dssdev->phy.rfbi.channel, rfbi.pixel_size,
769 rfbi.data_lines);
770}
771
772static int rfbi_update(struct omap_dss_device *dssdev, void (*callback)(void *),
773 void *data)
774{
775 return rfbi_transfer_area(dssdev, callback, data);
776}
777
778static void rfbi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h)
779{
780 rfbi.timings.x_res = w;
781 rfbi.timings.y_res = h;
782}
783
784static void rfbi_set_pixel_size(struct omap_dss_device *dssdev, int pixel_size)
785{
786 rfbi.pixel_size = pixel_size;
787}
788
789static void rfbi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
790{
791 rfbi.data_lines = data_lines;
792}
793
794static void rfbi_set_interface_timings(struct omap_dss_device *dssdev,
795 struct rfbi_timings *timings)
796{
797 rfbi.intf_timings = *timings;
798}
799
800static void rfbi_dump_regs(struct seq_file *s)
801{
802#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r))
803
804 if (rfbi_runtime_get())
805 return;
806
807 DUMPREG(RFBI_REVISION);
808 DUMPREG(RFBI_SYSCONFIG);
809 DUMPREG(RFBI_SYSSTATUS);
810 DUMPREG(RFBI_CONTROL);
811 DUMPREG(RFBI_PIXEL_CNT);
812 DUMPREG(RFBI_LINE_NUMBER);
813 DUMPREG(RFBI_CMD);
814 DUMPREG(RFBI_PARAM);
815 DUMPREG(RFBI_DATA);
816 DUMPREG(RFBI_READ);
817 DUMPREG(RFBI_STATUS);
818
819 DUMPREG(RFBI_CONFIG(0));
820 DUMPREG(RFBI_ONOFF_TIME(0));
821 DUMPREG(RFBI_CYCLE_TIME(0));
822 DUMPREG(RFBI_DATA_CYCLE1(0));
823 DUMPREG(RFBI_DATA_CYCLE2(0));
824 DUMPREG(RFBI_DATA_CYCLE3(0));
825
826 DUMPREG(RFBI_CONFIG(1));
827 DUMPREG(RFBI_ONOFF_TIME(1));
828 DUMPREG(RFBI_CYCLE_TIME(1));
829 DUMPREG(RFBI_DATA_CYCLE1(1));
830 DUMPREG(RFBI_DATA_CYCLE2(1));
831 DUMPREG(RFBI_DATA_CYCLE3(1));
832
833 DUMPREG(RFBI_VSYNC_WIDTH);
834 DUMPREG(RFBI_HSYNC_WIDTH);
835
836 rfbi_runtime_put();
837#undef DUMPREG
838}
839
840static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
841{
842 struct omap_overlay_manager *mgr = rfbi.output.manager;
843 struct dss_lcd_mgr_config mgr_config;
844
845 mgr_config.io_pad_mode = DSS_IO_PAD_MODE_RFBI;
846
847 mgr_config.stallmode = true;
848 /* Do we need fifohandcheck for RFBI? */
849 mgr_config.fifohandcheck = false;
850
851 mgr_config.video_port_width = rfbi.pixel_size;
852 mgr_config.lcden_sig_polarity = 0;
853
854 dss_mgr_set_lcd_config(mgr, &mgr_config);
855
856 /*
857 * Set rfbi.timings with default values, the x_res and y_res fields
858 * are expected to be already configured by the panel driver via
859 * omapdss_rfbi_set_size()
860 */
861 rfbi.timings.hsw = 1;
862 rfbi.timings.hfp = 1;
863 rfbi.timings.hbp = 1;
864 rfbi.timings.vsw = 1;
865 rfbi.timings.vfp = 0;
866 rfbi.timings.vbp = 0;
867
868 rfbi.timings.interlace = false;
869 rfbi.timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
870 rfbi.timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
871 rfbi.timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
872 rfbi.timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
873 rfbi.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE;
874
875 dss_mgr_set_timings(mgr, &rfbi.timings);
876}
877
878static int rfbi_display_enable(struct omap_dss_device *dssdev)
879{
880 struct omap_dss_device *out = &rfbi.output;
881 int r;
882
883 if (out->manager == NULL) {
884 DSSERR("failed to enable display: no output/manager\n");
885 return -ENODEV;
886 }
887
888 r = rfbi_runtime_get();
889 if (r)
890 return r;
891
892 r = dss_mgr_register_framedone_handler(out->manager,
893 framedone_callback, NULL);
894 if (r) {
895 DSSERR("can't get FRAMEDONE irq\n");
896 goto err1;
897 }
898
899 rfbi_config_lcd_manager(dssdev);
900
901 rfbi_configure_bus(dssdev->phy.rfbi.channel, rfbi.pixel_size,
902 rfbi.data_lines);
903
904 rfbi_set_timings(dssdev->phy.rfbi.channel, &rfbi.intf_timings);
905
906 return 0;
907err1:
908 rfbi_runtime_put();
909 return r;
910}
911
912static void rfbi_display_disable(struct omap_dss_device *dssdev)
913{
914 struct omap_dss_device *out = &rfbi.output;
915
916 dss_mgr_unregister_framedone_handler(out->manager,
917 framedone_callback, NULL);
918
919 rfbi_runtime_put();
920}
921
922static int rfbi_init_display(struct omap_dss_device *dssdev)
923{
924 rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev;
925 return 0;
926}
927
928static void rfbi_init_output(struct platform_device *pdev)
929{
930 struct omap_dss_device *out = &rfbi.output;
931
932 out->dev = &pdev->dev;
933 out->id = OMAP_DSS_OUTPUT_DBI;
934 out->output_type = OMAP_DISPLAY_TYPE_DBI;
935 out->name = "rfbi.0";
936 out->dispc_channel = OMAP_DSS_CHANNEL_LCD;
937 out->owner = THIS_MODULE;
938
939 omapdss_register_output(out);
940}
941
942static void rfbi_uninit_output(struct platform_device *pdev)
943{
944 struct omap_dss_device *out = &rfbi.output;
945
946 omapdss_unregister_output(out);
947}
948
949/* RFBI HW IP initialisation */
950static int rfbi_bind(struct device *dev, struct device *master, void *data)
951{
952 struct platform_device *pdev = to_platform_device(dev);
953 u32 rev;
954 struct resource *rfbi_mem;
955 struct clk *clk;
956 int r;
957
958 rfbi.pdev = pdev;
959
960 sema_init(&rfbi.bus_lock, 1);
961
962 rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0);
963 if (!rfbi_mem) {
964 DSSERR("can't get IORESOURCE_MEM RFBI\n");
965 return -EINVAL;
966 }
967
968 rfbi.base = devm_ioremap(&pdev->dev, rfbi_mem->start,
969 resource_size(rfbi_mem));
970 if (!rfbi.base) {
971 DSSERR("can't ioremap RFBI\n");
972 return -ENOMEM;
973 }
974
975 clk = clk_get(&pdev->dev, "ick");
976 if (IS_ERR(clk)) {
977 DSSERR("can't get ick\n");
978 return PTR_ERR(clk);
979 }
980
981 rfbi.l4_khz = clk_get_rate(clk) / 1000;
982
983 clk_put(clk);
984
985 pm_runtime_enable(&pdev->dev);
986
987 r = rfbi_runtime_get();
988 if (r)
989 goto err_runtime_get;
990
991 msleep(10);
992
993 rev = rfbi_read_reg(RFBI_REVISION);
994 dev_dbg(&pdev->dev, "OMAP RFBI rev %d.%d\n",
995 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
996
997 rfbi_runtime_put();
998
999 dss_debugfs_create_file("rfbi", rfbi_dump_regs);
1000
1001 rfbi_init_output(pdev);
1002
1003 return 0;
1004
1005err_runtime_get:
1006 pm_runtime_disable(&pdev->dev);
1007 return r;
1008}
1009
1010static void rfbi_unbind(struct device *dev, struct device *master, void *data)
1011{
1012 struct platform_device *pdev = to_platform_device(dev);
1013
1014 rfbi_uninit_output(pdev);
1015
1016 pm_runtime_disable(&pdev->dev);
1017
1018 return 0;
1019}
1020
1021static const struct component_ops rfbi_component_ops = {
1022 .bind = rfbi_bind,
1023 .unbind = rfbi_unbind,
1024};
1025
1026static int rfbi_probe(struct platform_device *pdev)
1027{
1028 return component_add(&pdev->dev, &rfbi_component_ops);
1029}
1030
1031static int rfbi_remove(struct platform_device *pdev)
1032{
1033 component_del(&pdev->dev, &rfbi_component_ops);
1034 return 0;
1035}
1036
1037static int rfbi_runtime_suspend(struct device *dev)
1038{
1039 dispc_runtime_put();
1040
1041 return 0;
1042}
1043
1044static int rfbi_runtime_resume(struct device *dev)
1045{
1046 int r;
1047
1048 r = dispc_runtime_get();
1049 if (r < 0)
1050 return r;
1051
1052 return 0;
1053}
1054
1055static const struct dev_pm_ops rfbi_pm_ops = {
1056 .runtime_suspend = rfbi_runtime_suspend,
1057 .runtime_resume = rfbi_runtime_resume,
1058};
1059
1060static struct platform_driver omap_rfbihw_driver = {
1061 .probe = rfbi_probe,
1062 .remove = rfbi_remove,
1063 .driver = {
1064 .name = "omapdss_rfbi",
1065 .pm = &rfbi_pm_ops,
1066 .suppress_bind_attrs = true,
1067 },
1068};
1069
1070int __init rfbi_init_platform_driver(void)
1071{
1072 return platform_driver_register(&omap_rfbihw_driver);
1073}
1074
1075void rfbi_uninit_platform_driver(void)
1076{
1077 platform_driver_unregister(&omap_rfbihw_driver);
1078}
diff --git a/include/video/omapfb_dss.h b/include/video/omapfb_dss.h
index a167b839eccb..e8eaac2cb7b8 100644
--- a/include/video/omapfb_dss.h
+++ b/include/video/omapfb_dss.h
@@ -114,11 +114,6 @@ enum omap_dss_trans_key_type {
114 OMAP_DSS_COLOR_KEY_VID_SRC = 1, 114 OMAP_DSS_COLOR_KEY_VID_SRC = 1,
115}; 115};
116 116
117enum omap_rfbi_te_mode {
118 OMAP_DSS_RFBI_TE_MODE_1 = 1,
119 OMAP_DSS_RFBI_TE_MODE_2 = 2,
120};
121
122enum omap_dss_signal_level { 117enum omap_dss_signal_level {
123 OMAPDSS_SIG_ACTIVE_LOW, 118 OMAPDSS_SIG_ACTIVE_LOW,
124 OMAPDSS_SIG_ACTIVE_HIGH, 119 OMAPDSS_SIG_ACTIVE_HIGH,
@@ -189,27 +184,6 @@ enum omap_dss_output_id {
189 OMAP_DSS_OUTPUT_HDMI = 1 << 6, 184 OMAP_DSS_OUTPUT_HDMI = 1 << 6,
190}; 185};
191 186
192/* RFBI */
193
194struct rfbi_timings {
195 int cs_on_time;
196 int cs_off_time;
197 int we_on_time;
198 int we_off_time;
199 int re_on_time;
200 int re_off_time;
201 int we_cycle_time;
202 int re_cycle_time;
203 int cs_pulse_width;
204 int access_time;
205
206 int clk_div;
207
208 u32 tim[5]; /* set by rfbi_convert_timings() */
209
210 int converted;
211};
212
213/* DSI */ 187/* DSI */
214 188
215enum omap_dss_dsi_trans_mode { 189enum omap_dss_dsi_trans_mode {
@@ -641,11 +615,6 @@ struct omap_dss_device {
641 } dpi; 615 } dpi;
642 616
643 struct { 617 struct {
644 u8 channel;
645 u8 data_lines;
646 } rfbi;
647
648 struct {
649 u8 datapairs; 618 u8 datapairs;
650 } sdi; 619 } sdi;
651 620
@@ -668,7 +637,6 @@ struct omap_dss_device {
668 637
669 struct { 638 struct {
670 u8 pixel_size; 639 u8 pixel_size;
671 struct rfbi_timings rfbi_timings;
672 } ctrl; 640 } ctrl;
673 641
674 const char *name; 642 const char *name;