aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/omapdrm
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2017-05-04 05:18:43 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2017-06-02 03:57:18 -0400
commitaa61321d4c08dd98049b8d45d5d73d87e849ed97 (patch)
tree9a7387a01ae6b79f91f1eeeac185e601b4a12d38 /drivers/gpu/drm/omapdrm
parentb42d7f511eb2e7a169e8674a4503f7e9e5ce742d (diff)
drm/omap: remove rfbi
The RFBI driver has not worked nor compiled for many years. There are very few boards out there that use RFBI, and no one has stepped up to fix it. So let's remove the RFBI code that doesn't even compile. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'drivers/gpu/drm/omapdrm')
-rw-r--r--drivers/gpu/drm/omapdrm/dss/Kconfig13
-rw-r--r--drivers/gpu/drm/omapdrm/dss/Makefile1
-rw-r--r--drivers/gpu/drm/omapdrm/dss/core.c6
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dss.h4
-rw-r--r--drivers/gpu/drm/omapdrm/dss/omapdss.h32
-rw-r--r--drivers/gpu/drm/omapdrm/dss/rfbi.c1075
6 files changed, 0 insertions, 1131 deletions
diff --git a/drivers/gpu/drm/omapdrm/dss/Kconfig b/drivers/gpu/drm/omapdrm/dss/Kconfig
index f53adb944a0d..8b87d5cf45fc 100644
--- a/drivers/gpu/drm/omapdrm/dss/Kconfig
+++ b/drivers/gpu/drm/omapdrm/dss/Kconfig
@@ -49,19 +49,6 @@ config OMAP2_DSS_DPI
49 help 49 help
50 DPI Interface. This is the Parallel Display Interface. 50 DPI Interface. This is the Parallel Display Interface.
51 51
52config OMAP2_DSS_RFBI
53 bool "RFBI support"
54 depends on BROKEN
55 default n
56 help
57 MIPI DBI support (RFBI, Remote Framebuffer Interface, in Texas
58 Instrument's terminology).
59
60 DBI is a bus between the host processor and a peripheral,
61 such as a display or a framebuffer chip.
62
63 See http://www.mipi.org/ for DBI specifications.
64
65config OMAP2_DSS_VENC 52config OMAP2_DSS_VENC
66 bool "VENC support" 53 bool "VENC support"
67 default y 54 default y
diff --git a/drivers/gpu/drm/omapdrm/dss/Makefile b/drivers/gpu/drm/omapdrm/dss/Makefile
index 75ec30f231c7..688195e448c5 100644
--- a/drivers/gpu/drm/omapdrm/dss/Makefile
+++ b/drivers/gpu/drm/omapdrm/dss/Makefile
@@ -8,7 +8,6 @@ obj-$(CONFIG_OMAP2_DSS) += omapdss.o
8omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o \ 8omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o \
9 pll.o video-pll.o 9 pll.o video-pll.o
10omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o 10omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
11omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
12omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o 11omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
13omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o 12omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
14omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o 13omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
diff --git a/drivers/gpu/drm/omapdrm/dss/core.c b/drivers/gpu/drm/omapdrm/dss/core.c
index f056bffcab73..bdce4bfdf6e0 100644
--- a/drivers/gpu/drm/omapdrm/dss/core.c
+++ b/drivers/gpu/drm/omapdrm/dss/core.c
@@ -208,9 +208,6 @@ static int (*dss_output_drv_reg_funcs[])(void) __initdata = {
208#ifdef CONFIG_OMAP2_DSS_DSI 208#ifdef CONFIG_OMAP2_DSS_DSI
209 dsi_init_platform_driver, 209 dsi_init_platform_driver,
210#endif 210#endif
211#ifdef CONFIG_OMAP2_DSS_RFBI
212 rfbi_init_platform_driver,
213#endif
214#ifdef CONFIG_OMAP2_DSS_VENC 211#ifdef CONFIG_OMAP2_DSS_VENC
215 venc_init_platform_driver, 212 venc_init_platform_driver,
216#endif 213#endif
@@ -232,9 +229,6 @@ static void (*dss_output_drv_unreg_funcs[])(void) = {
232#ifdef CONFIG_OMAP2_DSS_VENC 229#ifdef CONFIG_OMAP2_DSS_VENC
233 venc_uninit_platform_driver, 230 venc_uninit_platform_driver,
234#endif 231#endif
235#ifdef CONFIG_OMAP2_DSS_RFBI
236 rfbi_uninit_platform_driver,
237#endif
238#ifdef CONFIG_OMAP2_DSS_DSI 232#ifdef CONFIG_OMAP2_DSS_DSI
239 dsi_uninit_platform_driver, 233 dsi_uninit_platform_driver,
240#endif 234#endif
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h b/drivers/gpu/drm/omapdrm/dss/dss.h
index d8bf99a97571..8dbf35f3ab23 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.h
+++ b/drivers/gpu/drm/omapdrm/dss/dss.h
@@ -382,10 +382,6 @@ void hdmi4_uninit_platform_driver(void);
382int hdmi5_init_platform_driver(void) __init; 382int hdmi5_init_platform_driver(void) __init;
383void hdmi5_uninit_platform_driver(void); 383void hdmi5_uninit_platform_driver(void);
384 384
385/* RFBI */
386int rfbi_init_platform_driver(void) __init;
387void rfbi_uninit_platform_driver(void);
388
389 385
390#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 386#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
391static inline void dss_collect_irq_stats(u32 irqstatus, unsigned *irq_arr) 387static inline void dss_collect_irq_stats(u32 irqstatus, unsigned *irq_arr)
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 3cbc9e49aa5a..8eb8315a6c95 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -126,11 +126,6 @@ enum omap_dss_trans_key_type {
126 OMAP_DSS_COLOR_KEY_VID_SRC = 1, 126 OMAP_DSS_COLOR_KEY_VID_SRC = 1,
127}; 127};
128 128
129enum omap_rfbi_te_mode {
130 OMAP_DSS_RFBI_TE_MODE_1 = 1,
131 OMAP_DSS_RFBI_TE_MODE_2 = 2,
132};
133
134enum omap_dss_signal_level { 129enum omap_dss_signal_level {
135 OMAPDSS_SIG_ACTIVE_LOW, 130 OMAPDSS_SIG_ACTIVE_LOW,
136 OMAPDSS_SIG_ACTIVE_HIGH, 131 OMAPDSS_SIG_ACTIVE_HIGH,
@@ -220,27 +215,6 @@ enum omap_dss_output_id {
220 OMAP_DSS_OUTPUT_HDMI = 1 << 6, 215 OMAP_DSS_OUTPUT_HDMI = 1 << 6,
221}; 216};
222 217
223/* RFBI */
224
225struct rfbi_timings {
226 int cs_on_time;
227 int cs_off_time;
228 int we_on_time;
229 int we_off_time;
230 int re_on_time;
231 int re_off_time;
232 int we_cycle_time;
233 int re_cycle_time;
234 int cs_pulse_width;
235 int access_time;
236
237 int clk_div;
238
239 u32 tim[5]; /* set by rfbi_convert_timings() */
240
241 int converted;
242};
243
244/* DSI */ 218/* DSI */
245 219
246enum omap_dss_dsi_trans_mode { 220enum omap_dss_dsi_trans_mode {
@@ -624,11 +598,6 @@ struct omap_dss_device {
624 598
625 union { 599 union {
626 struct { 600 struct {
627 u8 channel;
628 u8 data_lines;
629 } rfbi;
630
631 struct {
632 int module; 601 int module;
633 } dsi; 602 } dsi;
634 } phy; 603 } phy;
@@ -642,7 +611,6 @@ struct omap_dss_device {
642 611
643 struct { 612 struct {
644 u8 pixel_size; 613 u8 pixel_size;
645 struct rfbi_timings rfbi_timings;
646 } ctrl; 614 } ctrl;
647 615
648 const char *name; 616 const char *name;
diff --git a/drivers/gpu/drm/omapdrm/dss/rfbi.c b/drivers/gpu/drm/omapdrm/dss/rfbi.c
deleted file mode 100644
index bf6b96877daf..000000000000
--- a/drivers/gpu/drm/omapdrm/dss/rfbi.c
+++ /dev/null
@@ -1,1075 +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 "omapdss.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 videomode vm;
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.vm.hactive;
312 u16 height = rfbi.vm.vactive;
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.vm);
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.vm.hactive = w;
781 rfbi.vm.vactive = 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 hactive and vactive fields
858 * are expected to be already configured by the panel driver via
859 * omapdss_rfbi_set_size()
860 */
861 rfbi.vm.hsync_len = 1;
862 rfbi.vm.hfront_porch = 1;
863 rfbi.vm.hback_porch = 1;
864 rfbi.vm.vsync_len = 1;
865 rfbi.vm.vfront_porch = 0;
866 rfbi.vm.vback_porch = 0;
867
868 rfbi.vm.flags &= ~DISPLAY_FLAGS_INTERLACED;
869 rfbi.vm.flags &= ~DISPLAY_FLAGS_HSYNC_LOW;
870 rfbi.vm.flags |= DISPLAY_FLAGS_HSYNC_HIGH;
871 rfbi.vm.flags &= ~DISPLAY_FLAGS_VSYNC_LOW;
872 rfbi.vm.flags |= DISPLAY_FLAGS_VSYNC_HIGH;
873 rfbi.vm.flags &= ~DISPLAY_FLAGS_PIXDATA_NEGEDGE;
874 rfbi.vm.flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE;
875 rfbi.vm.flags &= ~DISPLAY_FLAGS_DE_LOW;
876 rfbi.vm.flags |= DISPLAY_FLAGS_DE_HIGH;
877 rfbi.vm.flags &= ~DISPLAY_FLAGS_SYNC_POSEDGE;
878 rfbi.vm.flags |= DISPLAY_FLAGS_SYNC_NEGEDGE;
879
880 dss_mgr_set_timings(mgr, &rfbi.vm);
881}
882
883static int rfbi_display_enable(struct omap_dss_device *dssdev)
884{
885 struct omap_dss_device *out = &rfbi.output;
886 int r;
887
888 if (!out->dispc_channel_connected) {
889 DSSERR("failed to enable display: no output/manager\n");
890 return -ENODEV;
891 }
892
893 r = rfbi_runtime_get();
894 if (r)
895 return r;
896
897 r = dss_mgr_register_framedone_handler(out->manager,
898 framedone_callback, NULL);
899 if (r) {
900 DSSERR("can't get FRAMEDONE irq\n");
901 goto err1;
902 }
903
904 rfbi_config_lcd_manager(dssdev);
905
906 rfbi_configure_bus(dssdev->phy.rfbi.channel, rfbi.pixel_size,
907 rfbi.data_lines);
908
909 rfbi_set_timings(dssdev->phy.rfbi.channel, &rfbi.intf_timings);
910
911 return 0;
912err1:
913 rfbi_runtime_put();
914 return r;
915}
916
917static void rfbi_display_disable(struct omap_dss_device *dssdev)
918{
919 struct omap_dss_device *out = &rfbi.output;
920
921 dss_mgr_unregister_framedone_handler(out->manager,
922 framedone_callback, NULL);
923
924 rfbi_runtime_put();
925}
926
927static int rfbi_init_display(struct omap_dss_device *dssdev)
928{
929 rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev;
930 return 0;
931}
932
933static void rfbi_init_output(struct platform_device *pdev)
934{
935 struct omap_dss_device *out = &rfbi.output;
936
937 out->dev = &pdev->dev;
938 out->id = OMAP_DSS_OUTPUT_DBI;
939 out->output_type = OMAP_DISPLAY_TYPE_DBI;
940 out->name = "rfbi.0";
941 out->dispc_channel = OMAP_DSS_CHANNEL_LCD;
942 out->owner = THIS_MODULE;
943
944 omapdss_register_output(out);
945}
946
947static void rfbi_uninit_output(struct platform_device *pdev)
948{
949 struct omap_dss_device *out = &rfbi.output;
950
951 omapdss_unregister_output(out);
952}
953
954/* RFBI HW IP initialisation */
955static int rfbi_bind(struct device *dev, struct device *master, void *data)
956{
957 struct platform_device *pdev = to_platform_device(dev);
958 u32 rev;
959 struct resource *rfbi_mem;
960 struct clk *clk;
961 int r;
962
963 rfbi.pdev = pdev;
964
965 sema_init(&rfbi.bus_lock, 1);
966
967 rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0);
968 rfbi.base = devm_ioremap_resource(&pdev->dev, rfbi_mem);
969 if (IS_ERR(rfbi.base))
970 return PTR_ERR(rfbi.base);
971
972 clk = clk_get(&pdev->dev, "ick");
973 if (IS_ERR(clk)) {
974 DSSERR("can't get ick\n");
975 return PTR_ERR(clk);
976 }
977
978 rfbi.l4_khz = clk_get_rate(clk) / 1000;
979
980 clk_put(clk);
981
982 pm_runtime_enable(&pdev->dev);
983
984 r = rfbi_runtime_get();
985 if (r)
986 goto err_runtime_get;
987
988 msleep(10);
989
990 rev = rfbi_read_reg(RFBI_REVISION);
991 dev_dbg(&pdev->dev, "OMAP RFBI rev %d.%d\n",
992 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
993
994 rfbi_runtime_put();
995
996 dss_debugfs_create_file("rfbi", rfbi_dump_regs);
997
998 rfbi_init_output(pdev);
999
1000 return 0;
1001
1002err_runtime_get:
1003 pm_runtime_disable(&pdev->dev);
1004 return r;
1005}
1006
1007static void rfbi_unbind(struct device *dev, struct device *master, void *data)
1008{
1009 struct platform_device *pdev = to_platform_device(dev);
1010
1011 rfbi_uninit_output(pdev);
1012
1013 pm_runtime_disable(&pdev->dev);
1014
1015 return 0;
1016}
1017
1018static const struct component_ops rfbi_component_ops = {
1019 .bind = rfbi_bind,
1020 .unbind = rfbi_unbind,
1021};
1022
1023static int rfbi_probe(struct platform_device *pdev)
1024{
1025 return component_add(&pdev->dev, &rfbi_component_ops);
1026}
1027
1028static int rfbi_remove(struct platform_device *pdev)
1029{
1030 component_del(&pdev->dev, &rfbi_component_ops);
1031 return 0;
1032}
1033
1034static int rfbi_runtime_suspend(struct device *dev)
1035{
1036 dispc_runtime_put();
1037
1038 return 0;
1039}
1040
1041static int rfbi_runtime_resume(struct device *dev)
1042{
1043 int r;
1044
1045 r = dispc_runtime_get();
1046 if (r < 0)
1047 return r;
1048
1049 return 0;
1050}
1051
1052static const struct dev_pm_ops rfbi_pm_ops = {
1053 .runtime_suspend = rfbi_runtime_suspend,
1054 .runtime_resume = rfbi_runtime_resume,
1055};
1056
1057static struct platform_driver omap_rfbihw_driver = {
1058 .probe = rfbi_probe,
1059 .remove = rfbi_remove,
1060 .driver = {
1061 .name = "omapdss_rfbi",
1062 .pm = &rfbi_pm_ops,
1063 .suppress_bind_attrs = true,
1064 },
1065};
1066
1067int __init rfbi_init_platform_driver(void)
1068{
1069 return platform_driver_register(&omap_rfbihw_driver);
1070}
1071
1072void rfbi_uninit_platform_driver(void)
1073{
1074 platform_driver_unregister(&omap_rfbihw_driver);
1075}