2 * File: drivers/video/omap/omap2/rfbi.c
4 * OMAP2 Remote Frame Buffer Interface support
6 * Copyright (C) 2005 Nokia Corporation
7 * Author: Juha Yrjölä <juha.yrjola@nokia.com>
8 * Imre Deak <imre.deak@nokia.com>
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 #include <linux/module.h>
26 #include <linux/delay.h>
27 #include <linux/i2c.h>
28 #include <linux/err.h>
29 #include <linux/interrupt.h>
30 #include <linux/clk.h>
34 #include <asm/arch/omapfb.h>
38 /* #define OMAPFB_DBG 1 */
42 #define MODULE_NAME "omapfb-rfbi"
44 #define pr_err(fmt, args...) printk(KERN_ERR MODULE_NAME ": " fmt, ## args)
46 #define RFBI_BASE 0x48050800
47 #define RFBI_REVISION 0x0000
48 #define RFBI_SYSCONFIG 0x0010
49 #define RFBI_SYSSTATUS 0x0014
50 #define RFBI_CONTROL 0x0040
51 #define RFBI_PIXEL_CNT 0x0044
52 #define RFBI_LINE_NUMBER 0x0048
53 #define RFBI_CMD 0x004c
54 #define RFBI_PARAM 0x0050
55 #define RFBI_DATA 0x0054
56 #define RFBI_READ 0x0058
57 #define RFBI_STATUS 0x005c
58 #define RFBI_CONFIG0 0x0060
59 #define RFBI_ONOFF_TIME0 0x0064
60 #define RFBI_CYCLE_TIME0 0x0068
61 #define RFBI_DATA_CYCLE1_0 0x006c
62 #define RFBI_DATA_CYCLE2_0 0x0070
63 #define RFBI_DATA_CYCLE3_0 0x0074
64 #define RFBI_VSYNC_WIDTH 0x0090
65 #define RFBI_HSYNC_WIDTH 0x0094
67 #define DISPC_BASE 0x48050400
68 #define DISPC_CONTROL 0x0040
72 void (*lcdc_callback)(void *data);
73 void *lcdc_callback_data;
78 struct lcd_ctrl_extif rfbi_extif;
80 static inline void rfbi_write_reg(int idx, u32 val)
82 __raw_writel(val, rfbi.base + idx);
85 static inline u32 rfbi_read_reg(int idx)
87 return __raw_readl(rfbi.base + idx);
91 static void rfbi_print_timings(void)
96 l = rfbi_read_reg(RFBI_CONFIG0);
97 time = 1000000000 / rfbi.l4_khz;
101 DBGPRINT(1, "Tick time %u ps\n", time);
102 l = rfbi_read_reg(RFBI_ONOFF_TIME0);
103 DBGPRINT(1, "CSONTIME %d, CSOFFTIME %d, WEONTIME %d, WEOFFTIME %d, "
104 "REONTIME %d, REOFFTIME %d\n",
105 l & 0x0f, (l >> 4) & 0x3f, (l >> 10) & 0x0f, (l >> 14) & 0x3f,
106 (l >> 20) & 0x0f, (l >> 24) & 0x3f);
107 l = rfbi_read_reg(RFBI_CYCLE_TIME0);
108 DBGPRINT(1, "WECYCLETIME %d, RECYCLETIME %d, CSPULSEWIDTH %d, "
110 (l & 0x3f), (l >> 6) & 0x3f, (l >> 12) & 0x3f, (l >> 22) & 0x3f);
113 static void rfbi_print_timings(void) {}
116 static void rfbi_set_timings(const struct extif_timings *t)
120 BUG_ON(!t->converted);
122 rfbi_write_reg(RFBI_ONOFF_TIME0, t->tim[0]);
123 rfbi_write_reg(RFBI_CYCLE_TIME0, t->tim[1]);
125 l = rfbi_read_reg(RFBI_CONFIG0);
127 l |= (t->tim[2] ? 1 : 0) << 4;
128 rfbi_write_reg(RFBI_CONFIG0, l);
130 rfbi_print_timings();
133 static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div)
135 *clk_period = 1000000000 / rfbi.l4_khz;
139 static int ps_to_rfbi_ticks(int time, int div)
141 unsigned long tick_ps;
144 /* Calculate in picosecs to yield more exact results */
145 tick_ps = 1000000000 / (rfbi.l4_khz) * div;
147 ret = (time + tick_ps - 1) / tick_ps;
152 static int rfbi_convert_timings(struct extif_timings *t)
155 int reon, reoff, weon, weoff, cson, csoff, cs_pulse;
156 int actim, recyc, wecyc;
157 int div = t->clk_div;
159 if (div <= 0 || div > 2)
162 /* Make sure that after conversion it still holds that:
163 * weoff > weon, reoff > reon, recyc >= reoff, wecyc >= weoff,
164 * csoff > cson, csoff >= max(weoff, reoff), actim > reon
166 weon = ps_to_rfbi_ticks(t->we_on_time, div);
167 weoff = ps_to_rfbi_ticks(t->we_off_time, div);
175 reon = ps_to_rfbi_ticks(t->re_on_time, div);
176 reoff = ps_to_rfbi_ticks(t->re_off_time, div);
184 cson = ps_to_rfbi_ticks(t->cs_on_time, div);
185 csoff = ps_to_rfbi_ticks(t->cs_off_time, div);
188 if (csoff < max(weoff, reoff))
189 csoff = max(weoff, reoff);
204 actim = ps_to_rfbi_ticks(t->access_time, div);
210 wecyc = ps_to_rfbi_ticks(t->we_cycle_time, div);
216 recyc = ps_to_rfbi_ticks(t->re_cycle_time, div);
222 cs_pulse = ps_to_rfbi_ticks(t->cs_pulse_width, div);
240 static void rfbi_write_command(const void *buf, unsigned int len)
242 if (rfbi.bits_per_cycle == 16) {
245 for (; len; len -= 2)
246 rfbi_write_reg(RFBI_CMD, *w++);
249 BUG_ON(rfbi.bits_per_cycle != 8);
251 rfbi_write_reg(RFBI_CMD, *b++);
255 static void rfbi_read_data(void *buf, unsigned int len)
257 if (rfbi.bits_per_cycle == 16) {
260 for (; len; len -= 2) {
261 rfbi_write_reg(RFBI_READ, 0);
262 *w++ = rfbi_read_reg(RFBI_READ);
266 BUG_ON(rfbi.bits_per_cycle != 8);
268 rfbi_write_reg(RFBI_READ, 0);
269 *b++ = rfbi_read_reg(RFBI_READ);
274 static void rfbi_write_data(const void *buf, unsigned int len)
276 if (rfbi.bits_per_cycle == 16) {
279 for (; len; len -= 2)
280 rfbi_write_reg(RFBI_PARAM, *w++);
283 BUG_ON(rfbi.bits_per_cycle != 8);
285 rfbi_write_reg(RFBI_PARAM, *b++);
289 static void rfbi_transfer_area(int width, int height,
290 void (callback)(void * data), void *data)
294 BUG_ON(callback == NULL);
296 omap_dispc_set_lcd_size(width, height);
298 rfbi.lcdc_callback = callback;
299 rfbi.lcdc_callback_data = data;
301 rfbi_write_reg(RFBI_PIXEL_CNT, width * height);
303 w = rfbi_read_reg(RFBI_CONTROL);
304 /* Enable, Internal trigger */
305 rfbi_write_reg(RFBI_CONTROL, w | (1 << 0) | (1 << 4));
307 omap_dispc_enable_lcd_out(1);
310 static inline void _stop_transfer(void)
314 w = rfbi_read_reg(RFBI_CONTROL);
315 rfbi_write_reg(RFBI_CONTROL, w & ~(1 << 0));
318 static void rfbi_dma_callback(void *data)
321 rfbi.lcdc_callback(rfbi.lcdc_callback_data);
324 static void rfbi_set_bits_per_cycle(int bpc)
328 l = rfbi_read_reg(RFBI_CONFIG0);
340 rfbi_write_reg(RFBI_CONFIG0, l);
341 rfbi.bits_per_cycle = bpc;
344 static int rfbi_init(void)
350 rfbi.base = io_p2v(RFBI_BASE);
352 l = rfbi_read_reg(RFBI_REVISION);
353 pr_info(MODULE_NAME ": version %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
355 dss_ick = clk_get(NULL, "dss_ick");
356 if (IS_ERR(dss_ick)) {
357 pr_err("can't get dss_ick\n");
358 return PTR_ERR(dss_ick);
361 rfbi.l4_khz = clk_get_rate(dss_ick) / 1000;
365 rfbi_write_reg(RFBI_SYSCONFIG, 1 << 1);
366 while (!(rfbi_read_reg(RFBI_SYSSTATUS) & (1 << 0)));
368 l = rfbi_read_reg(RFBI_SYSCONFIG);
369 /* Enable autoidle and smart-idle */
370 l |= (1 << 0) | (2 << 3);
371 rfbi_write_reg(RFBI_SYSCONFIG, l);
373 /* 16-bit interface, ITE trigger mode, 16-bit data */
374 l = (0x03 << 0) | (0x00 << 2) | (0x01 << 5) | (0x02 << 7);
375 l |= (0 << 9) | (1 << 20) | (1 << 21);
376 rfbi_write_reg(RFBI_CONFIG0, l);
378 rfbi_write_reg(RFBI_DATA_CYCLE1_0, 0x00000010);
380 l = rfbi_read_reg(RFBI_CONTROL);
381 /* Select CS0, clear bypass mode */
383 rfbi_write_reg(RFBI_CONTROL, l);
385 if ((r = omap_dispc_request_irq(rfbi_dma_callback, NULL)) < 0) {
386 pr_err("can't get DISPC irq\n");
393 static void rfbi_cleanup(void)
395 omap_dispc_free_irq();
398 struct lcd_ctrl_extif rfbi_extif = {
400 .cleanup = rfbi_cleanup,
401 .get_clk_info = rfbi_get_clk_info,
402 .set_bits_per_cycle = rfbi_set_bits_per_cycle,
403 .convert_timings = rfbi_convert_timings,
404 .set_timings = rfbi_set_timings,
405 .write_command = rfbi_write_command,
406 .read_data = rfbi_read_data,
407 .write_data = rfbi_write_data,
408 .transfer_area = rfbi_transfer_area,
409 .max_transmit_size = (u32)~0,