1/* 2 * OMAP2 Remote Frame Buffer Interface support 3 * 4 * Copyright (C) 2005 Nokia Corporation 5 * Author: Juha Yrj�l� <juha.yrjola@nokia.com> 6 * Imre Deak <imre.deak@nokia.com> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License along 19 * with this program; if not, write to the Free Software Foundation, Inc., 20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 21 */ 22#include <linux/module.h> 23#include <linux/delay.h> 24#include <linux/i2c.h> 25#include <linux/err.h> 26#include <linux/interrupt.h> 27#include <linux/clk.h> 28#include <linux/io.h> 29#include <linux/platform_device.h> 30 31#include "omapfb.h" 32#include "dispc.h" 33 34#define OMAP_RFBI_RATE_LIMIT 1 35 36#define RFBI_BASE 0x48050800 37#define RFBI_REVISION 0x0000 38#define RFBI_SYSCONFIG 0x0010 39#define RFBI_SYSSTATUS 0x0014 40#define RFBI_CONTROL 0x0040 41#define RFBI_PIXEL_CNT 0x0044 42#define RFBI_LINE_NUMBER 0x0048 43#define RFBI_CMD 0x004c 44#define RFBI_PARAM 0x0050 45#define RFBI_DATA 0x0054 46#define RFBI_READ 0x0058 47#define RFBI_STATUS 0x005c 48#define RFBI_CONFIG0 0x0060 49#define RFBI_ONOFF_TIME0 0x0064 50#define RFBI_CYCLE_TIME0 0x0068 51#define RFBI_DATA_CYCLE1_0 0x006c 52#define RFBI_DATA_CYCLE2_0 0x0070 53#define RFBI_DATA_CYCLE3_0 0x0074 54#define RFBI_VSYNC_WIDTH 0x0090 55#define RFBI_HSYNC_WIDTH 0x0094 56 57#define DISPC_BASE 0x48050400 58#define DISPC_CONTROL 0x0040 59#define DISPC_IRQ_FRAMEMASK 0x0001 60 61static struct { 62 void __iomem *base; 63 void (*lcdc_callback)(void *data); 64 void *lcdc_callback_data; 65 unsigned long l4_khz; 66 int bits_per_cycle; 67 struct omapfb_device *fbdev; 68 struct clk *dss_ick; 69 struct clk *dss1_fck; 70 unsigned tearsync_pin_cnt; 71 unsigned tearsync_mode; 72} rfbi; 73 74static inline void rfbi_write_reg(int idx, u32 val) 75{ 76 __raw_writel(val, rfbi.base + idx); 77} 78 79static inline u32 rfbi_read_reg(int idx) 80{ 81 return __raw_readl(rfbi.base + idx); 82} 83 84static int rfbi_get_clocks(void) 85{ 86 rfbi.dss_ick = clk_get(&rfbi.fbdev->dssdev->dev, "ick"); 87 if (IS_ERR(rfbi.dss_ick)) { 88 dev_err(rfbi.fbdev->dev, "can't get ick\n"); 89 return PTR_ERR(rfbi.dss_ick); 90 } 91 92 rfbi.dss1_fck = clk_get(&rfbi.fbdev->dssdev->dev, "dss1_fck"); 93 if (IS_ERR(rfbi.dss1_fck)) { 94 dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n"); 95 clk_put(rfbi.dss_ick); 96 return PTR_ERR(rfbi.dss1_fck); 97 } 98 99 return 0; 100} 101 102static void rfbi_put_clocks(void) 103{ 104 clk_put(rfbi.dss1_fck); 105 clk_put(rfbi.dss_ick); 106} 107 108static void rfbi_enable_clocks(int enable) 109{ 110 if (enable) { 111 clk_enable(rfbi.dss_ick); 112 clk_enable(rfbi.dss1_fck); 113 } else { 114 clk_disable(rfbi.dss1_fck); 115 clk_disable(rfbi.dss_ick); 116 } 117} 118 119 120#ifdef VERBOSE 121static void rfbi_print_timings(void) 122{ 123 u32 l; 124 u32 time; 125 126 l = rfbi_read_reg(RFBI_CONFIG0); 127 time = 1000000000 / rfbi.l4_khz; 128 if (l & (1 << 4)) 129 time *= 2; 130 131 dev_dbg(rfbi.fbdev->dev, "Tick time %u ps\n", time); 132 l = rfbi_read_reg(RFBI_ONOFF_TIME0); 133 dev_dbg(rfbi.fbdev->dev, 134 "CSONTIME %d, CSOFFTIME %d, WEONTIME %d, WEOFFTIME %d, " 135 "REONTIME %d, REOFFTIME %d\n", 136 l & 0x0f, (l >> 4) & 0x3f, (l >> 10) & 0x0f, (l >> 14) & 0x3f, 137 (l >> 20) & 0x0f, (l >> 24) & 0x3f); 138 139 l = rfbi_read_reg(RFBI_CYCLE_TIME0); 140 dev_dbg(rfbi.fbdev->dev, 141 "WECYCLETIME %d, RECYCLETIME %d, CSPULSEWIDTH %d, " 142 "ACCESSTIME %d\n", 143 (l & 0x3f), (l >> 6) & 0x3f, (l >> 12) & 0x3f, 144 (l >> 22) & 0x3f); 145} 146#else 147static void rfbi_print_timings(void) {} 148#endif 149 150static void rfbi_set_timings(const struct extif_timings *t) 151{ 152 u32 l; 153 154 BUG_ON(!t->converted); 155 156 rfbi_enable_clocks(1); 157 rfbi_write_reg(RFBI_ONOFF_TIME0, t->tim[0]); 158 rfbi_write_reg(RFBI_CYCLE_TIME0, t->tim[1]); 159 160 l = rfbi_read_reg(RFBI_CONFIG0); 161 l &= ~(1 << 4); 162 l |= (t->tim[2] ? 1 : 0) << 4; 163 rfbi_write_reg(RFBI_CONFIG0, l); 164 165 rfbi_print_timings(); 166 rfbi_enable_clocks(0); 167} 168 169static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div) 170{ 171 *clk_period = 1000000000 / rfbi.l4_khz; 172 *max_clk_div = 2; 173} 174 175static int ps_to_rfbi_ticks(int time, int div) 176{ 177 unsigned long tick_ps; 178 int ret; 179 180 /* Calculate in picosecs to yield more exact results */ 181 tick_ps = 1000000000 / (rfbi.l4_khz) * div; 182 183 ret = (time + tick_ps - 1) / tick_ps; 184 185 return ret; 186} 187 188#ifdef OMAP_RFBI_RATE_LIMIT 189static unsigned long rfbi_get_max_tx_rate(void) 190{ 191 unsigned long l4_rate, dss1_rate; 192 int min_l4_ticks = 0; 193 int i; 194 195 /* According to TI this can't be calculated so make the 196 * adjustments for a couple of known frequencies and warn for 197 * others. 198 */ 199 static const struct { 200 unsigned long l4_clk; /* HZ */ 201 unsigned long dss1_clk; /* HZ */ 202 unsigned long min_l4_ticks; 203 } ftab[] = { 204 { 55, 132, 7, }, /* 7.86 MPix/s */ 205 { 110, 110, 12, }, /* 9.16 MPix/s */ 206 { 110, 132, 10, }, /* 11 Mpix/s */ 207 { 120, 120, 10, }, /* 12 Mpix/s */ 208 { 133, 133, 10, }, /* 13.3 Mpix/s */ 209 }; 210 211 l4_rate = rfbi.l4_khz / 1000; 212 dss1_rate = clk_get_rate(rfbi.dss1_fck) / 1000000; 213 214 for (i = 0; i < ARRAY_SIZE(ftab); i++) { 215 /* Use a window instead of an exact match, to account 216 * for different DPLL multiplier / divider pairs. 217 */ 218 if (abs(ftab[i].l4_clk - l4_rate) < 3 && 219 abs(ftab[i].dss1_clk - dss1_rate) < 3) { 220 min_l4_ticks = ftab[i].min_l4_ticks; 221 break; 222 } 223 } 224 if (i == ARRAY_SIZE(ftab)) { 225 /* Can't be sure, return anyway the maximum not 226 * rate-limited. This might cause a problem only for the 227 * tearing synchronisation. 228 */ 229 dev_err(rfbi.fbdev->dev, 230 "can't determine maximum RFBI transfer rate\n"); 231 return rfbi.l4_khz * 1000; 232 } 233 return rfbi.l4_khz * 1000 / min_l4_ticks; 234} 235#else 236static int rfbi_get_max_tx_rate(void) 237{ 238 return rfbi.l4_khz * 1000; 239} 240#endif 241 242 243static int rfbi_convert_timings(struct extif_timings *t) 244{ 245 u32 l; 246 int reon, reoff, weon, weoff, cson, csoff, cs_pulse; 247 int actim, recyc, wecyc; 248 int div = t->clk_div; 249 250 if (div <= 0 || div > 2) 251 return -1; 252 253 /* Make sure that after conversion it still holds that: 254 * weoff > weon, reoff > reon, recyc >= reoff, wecyc >= weoff, 255 * csoff > cson, csoff >= max(weoff, reoff), actim > reon 256 */ 257 weon = ps_to_rfbi_ticks(t->we_on_time, div); 258 weoff = ps_to_rfbi_ticks(t->we_off_time, div); 259 if (weoff <= weon) 260 weoff = weon + 1; 261 if (weon > 0x0f) 262 return -1; 263 if (weoff > 0x3f) 264 return -1; 265 266 reon = ps_to_rfbi_ticks(t->re_on_time, div); 267 reoff = ps_to_rfbi_ticks(t->re_off_time, div); 268 if (reoff <= reon) 269 reoff = reon + 1; 270 if (reon > 0x0f) 271 return -1; 272 if (reoff > 0x3f) 273 return -1; 274 275 cson = ps_to_rfbi_ticks(t->cs_on_time, div); 276 csoff = ps_to_rfbi_ticks(t->cs_off_time, div); 277 if (csoff <= cson) 278 csoff = cson + 1; 279 if (csoff < max(weoff, reoff)) 280 csoff = max(weoff, reoff); 281 if (cson > 0x0f) 282 return -1; 283 if (csoff > 0x3f) 284 return -1; 285 286 l = cson; 287 l |= csoff << 4; 288 l |= weon << 10; 289 l |= weoff << 14; 290 l |= reon << 20; 291 l |= reoff << 24; 292 293 t->tim[0] = l; 294 295 actim = ps_to_rfbi_ticks(t->access_time, div); 296 if (actim <= reon) 297 actim = reon + 1; 298 if (actim > 0x3f) 299 return -1; 300 301 wecyc = ps_to_rfbi_ticks(t->we_cycle_time, div); 302 if (wecyc < weoff) 303 wecyc = weoff; 304 if (wecyc > 0x3f) 305 return -1; 306 307 recyc = ps_to_rfbi_ticks(t->re_cycle_time, div); 308 if (recyc < reoff) 309 recyc = reoff; 310 if (recyc > 0x3f) 311 return -1; 312 313 cs_pulse = ps_to_rfbi_ticks(t->cs_pulse_width, div); 314 if (cs_pulse > 0x3f) 315 return -1; 316 317 l = wecyc; 318 l |= recyc << 6; 319 l |= cs_pulse << 12; 320 l |= actim << 22; 321 322 t->tim[1] = l; 323 324 t->tim[2] = div - 1; 325 326 t->converted = 1; 327 328 return 0; 329} 330 331static int rfbi_setup_tearsync(unsigned pin_cnt, 332 unsigned hs_pulse_time, unsigned vs_pulse_time, 333 int hs_pol_inv, int vs_pol_inv, int extif_div) 334{ 335 int hs, vs; 336 int min; 337 u32 l; 338 339 if (pin_cnt != 1 && pin_cnt != 2) 340 return -EINVAL; 341 342 hs = ps_to_rfbi_ticks(hs_pulse_time, 1); 343 vs = ps_to_rfbi_ticks(vs_pulse_time, 1); 344 if (hs < 2) 345 return -EDOM; 346 if (pin_cnt == 2) 347 min = 2; 348 else 349 min = 4; 350 if (vs < min) 351 return -EDOM; 352 if (vs == hs) 353 return -EINVAL; 354 rfbi.tearsync_pin_cnt = pin_cnt; 355 dev_dbg(rfbi.fbdev->dev, 356 "setup_tearsync: pins %d hs %d vs %d hs_inv %d vs_inv %d\n", 357 pin_cnt, hs, vs, hs_pol_inv, vs_pol_inv); 358 359 rfbi_enable_clocks(1); 360 rfbi_write_reg(RFBI_HSYNC_WIDTH, hs); 361 rfbi_write_reg(RFBI_VSYNC_WIDTH, vs); 362 363 l = rfbi_read_reg(RFBI_CONFIG0); 364 if (hs_pol_inv) 365 l &= ~(1 << 21); 366 else 367 l |= 1 << 21; 368 if (vs_pol_inv) 369 l &= ~(1 << 20); 370 else 371 l |= 1 << 20; 372 rfbi_enable_clocks(0); 373 374 return 0; 375} 376 377static int rfbi_enable_tearsync(int enable, unsigned line) 378{ 379 u32 l; 380 381 dev_dbg(rfbi.fbdev->dev, "tearsync %d line %d mode %d\n", 382 enable, line, rfbi.tearsync_mode); 383 if (line > (1 << 11) - 1) 384 return -EINVAL; 385 386 rfbi_enable_clocks(1); 387 l = rfbi_read_reg(RFBI_CONFIG0); 388 l &= ~(0x3 << 2); 389 if (enable) { 390 rfbi.tearsync_mode = rfbi.tearsync_pin_cnt; 391 l |= rfbi.tearsync_mode << 2; 392 } else 393 rfbi.tearsync_mode = 0; 394 rfbi_write_reg(RFBI_CONFIG0, l); 395 rfbi_write_reg(RFBI_LINE_NUMBER, line); 396 rfbi_enable_clocks(0); 397 398 return 0; 399} 400 401static void rfbi_write_command(const void *buf, unsigned int len) 402{ 403 rfbi_enable_clocks(1); 404 if (rfbi.bits_per_cycle == 16) { 405 const u16 *w = buf; 406 BUG_ON(len & 1); 407 for (; len; len -= 2) 408 rfbi_write_reg(RFBI_CMD, *w++); 409 } else { 410 const u8 *b = buf; 411 BUG_ON(rfbi.bits_per_cycle != 8); 412 for (; len; len--) 413 rfbi_write_reg(RFBI_CMD, *b++); 414 } 415 rfbi_enable_clocks(0); 416} 417 418static void rfbi_read_data(void *buf, unsigned int len) 419{ 420 rfbi_enable_clocks(1); 421 if (rfbi.bits_per_cycle == 16) { 422 u16 *w = buf; 423 BUG_ON(len & ~1); 424 for (; len; len -= 2) { 425 rfbi_write_reg(RFBI_READ, 0); 426 *w++ = rfbi_read_reg(RFBI_READ); 427 } 428 } else { 429 u8 *b = buf; 430 BUG_ON(rfbi.bits_per_cycle != 8); 431 for (; len; len--) { 432 rfbi_write_reg(RFBI_READ, 0); 433 *b++ = rfbi_read_reg(RFBI_READ); 434 } 435 } 436 rfbi_enable_clocks(0); 437} 438 439static void rfbi_write_data(const void *buf, unsigned int len) 440{ 441 rfbi_enable_clocks(1); 442 if (rfbi.bits_per_cycle == 16) { 443 const u16 *w = buf; 444 BUG_ON(len & 1); 445 for (; len; len -= 2) 446 rfbi_write_reg(RFBI_PARAM, *w++); 447 } else { 448 const u8 *b = buf; 449 BUG_ON(rfbi.bits_per_cycle != 8); 450 for (; len; len--) 451 rfbi_write_reg(RFBI_PARAM, *b++); 452 } 453 rfbi_enable_clocks(0); 454} 455 456static void rfbi_transfer_area(int width, int height, 457 void (callback)(void * data), void *data) 458{ 459 u32 w; 460 461 BUG_ON(callback == NULL); 462 463 rfbi_enable_clocks(1); 464 omap_dispc_set_lcd_size(width, height); 465 466 rfbi.lcdc_callback = callback; 467 rfbi.lcdc_callback_data = data; 468 469 rfbi_write_reg(RFBI_PIXEL_CNT, width * height); 470 471 w = rfbi_read_reg(RFBI_CONTROL); 472 w |= 1; /* enable */ 473 if (!rfbi.tearsync_mode) 474 w |= 1 << 4; /* internal trigger, reset by HW */ 475 rfbi_write_reg(RFBI_CONTROL, w); 476 477 omap_dispc_enable_lcd_out(1); 478} 479 480static inline void _stop_transfer(void) 481{ 482 u32 w; 483 484 w = rfbi_read_reg(RFBI_CONTROL); 485 rfbi_write_reg(RFBI_CONTROL, w & ~(1 << 0)); 486 rfbi_enable_clocks(0); 487} 488 489static void rfbi_dma_callback(void *data) 490{ 491 _stop_transfer(); 492 rfbi.lcdc_callback(rfbi.lcdc_callback_data); 493} 494 495static void rfbi_set_bits_per_cycle(int bpc) 496{ 497 u32 l; 498 499 rfbi_enable_clocks(1); 500 l = rfbi_read_reg(RFBI_CONFIG0); 501 l &= ~(0x03 << 0); 502 503 switch (bpc) { 504 case 8: 505 break; 506 case 16: 507 l |= 3; 508 break; 509 default: 510 BUG(); 511 } 512 rfbi_write_reg(RFBI_CONFIG0, l); 513 rfbi.bits_per_cycle = bpc; 514 rfbi_enable_clocks(0); 515} 516 517static int rfbi_init(struct omapfb_device *fbdev) 518{ 519 u32 l; 520 int r; 521 522 rfbi.fbdev = fbdev; 523 rfbi.base = ioremap(RFBI_BASE, SZ_1K); 524 if (!rfbi.base) { 525 dev_err(fbdev->dev, "can't ioremap RFBI\n"); 526 return -ENOMEM; 527 } 528 529 if ((r = rfbi_get_clocks()) < 0) 530 return r; 531 rfbi_enable_clocks(1); 532 533 rfbi.l4_khz = clk_get_rate(rfbi.dss_ick) / 1000; 534 535 /* Reset */ 536 rfbi_write_reg(RFBI_SYSCONFIG, 1 << 1); 537 while (!(rfbi_read_reg(RFBI_SYSSTATUS) & (1 << 0))); 538 539 l = rfbi_read_reg(RFBI_SYSCONFIG); 540 /* Enable autoidle and smart-idle */ 541 l |= (1 << 0) | (2 << 3); 542 rfbi_write_reg(RFBI_SYSCONFIG, l); 543 544 /* 16-bit interface, ITE trigger mode, 16-bit data */ 545 l = (0x03 << 0) | (0x00 << 2) | (0x01 << 5) | (0x02 << 7); 546 l |= (0 << 9) | (1 << 20) | (1 << 21); 547 rfbi_write_reg(RFBI_CONFIG0, l); 548 549 rfbi_write_reg(RFBI_DATA_CYCLE1_0, 0x00000010); 550 551 l = rfbi_read_reg(RFBI_CONTROL); 552 /* Select CS0, clear bypass mode */ 553 l = (0x01 << 2); 554 rfbi_write_reg(RFBI_CONTROL, l); 555 556 r = omap_dispc_request_irq(DISPC_IRQ_FRAMEMASK, rfbi_dma_callback, 557 NULL); 558 if (r < 0) { 559 dev_err(fbdev->dev, "can't get DISPC irq\n"); 560 rfbi_enable_clocks(0); 561 return r; 562 } 563 564 l = rfbi_read_reg(RFBI_REVISION); 565 pr_info("omapfb: RFBI version %d.%d initialized\n", 566 (l >> 4) & 0x0f, l & 0x0f); 567 568 rfbi_enable_clocks(0); 569 570 return 0; 571} 572 573static void rfbi_cleanup(void) 574{ 575 omap_dispc_free_irq(DISPC_IRQ_FRAMEMASK, rfbi_dma_callback, NULL); 576 rfbi_put_clocks(); 577 iounmap(rfbi.base); 578} 579 580const struct lcd_ctrl_extif omap2_ext_if = { 581 .init = rfbi_init, 582 .cleanup = rfbi_cleanup, 583 .get_clk_info = rfbi_get_clk_info, 584 .get_max_tx_rate = rfbi_get_max_tx_rate, 585 .set_bits_per_cycle = rfbi_set_bits_per_cycle, 586 .convert_timings = rfbi_convert_timings, 587 .set_timings = rfbi_set_timings, 588 .write_command = rfbi_write_command, 589 .read_data = rfbi_read_data, 590 .write_data = rfbi_write_data, 591 .transfer_area = rfbi_transfer_area, 592 .setup_tearsync = rfbi_setup_tearsync, 593 .enable_tearsync = rfbi_enable_tearsync, 594 595 .max_transmit_size = (u32) ~0, 596}; 597