pxa168fb.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851
  1. /*
  2. * linux/drivers/video/pxa168fb.c -- Marvell PXA168 LCD Controller
  3. *
  4. * Copyright (C) 2008 Marvell International Ltd.
  5. * All rights reserved.
  6. *
  7. * 2009-02-16 adapted from original version for PXA168/910
  8. * Jun Nie <njun@marvell.com>
  9. *
  10. * This file is subject to the terms and conditions of the GNU General Public
  11. * License. See the file COPYING in the main directory of this archive for
  12. * more details.
  13. */
  14. #include <linux/module.h>
  15. #include <linux/kernel.h>
  16. #include <linux/sched.h>
  17. #include <linux/string.h>
  18. #include <linux/interrupt.h>
  19. #include <linux/slab.h>
  20. #include <linux/fb.h>
  21. #include <linux/delay.h>
  22. #include <linux/init.h>
  23. #include <linux/ioport.h>
  24. #include <linux/platform_device.h>
  25. #include <linux/dma-mapping.h>
  26. #include <linux/clk.h>
  27. #include <linux/err.h>
  28. #include <linux/uaccess.h>
  29. #include <video/pxa168fb.h>
  30. #include "pxa168fb.h"
  31. #define DEFAULT_REFRESH 60 /* Hz */
  32. static int determine_best_pix_fmt(struct fb_var_screeninfo *var)
  33. {
  34. /*
  35. * Pseudocolor mode?
  36. */
  37. if (var->bits_per_pixel == 8)
  38. return PIX_FMT_PSEUDOCOLOR;
  39. /*
  40. * Check for 565/1555.
  41. */
  42. if (var->bits_per_pixel == 16 && var->red.length <= 5 &&
  43. var->green.length <= 6 && var->blue.length <= 5) {
  44. if (var->transp.length == 0) {
  45. if (var->red.offset >= var->blue.offset)
  46. return PIX_FMT_RGB565;
  47. else
  48. return PIX_FMT_BGR565;
  49. }
  50. if (var->transp.length == 1 && var->green.length <= 5) {
  51. if (var->red.offset >= var->blue.offset)
  52. return PIX_FMT_RGB1555;
  53. else
  54. return PIX_FMT_BGR1555;
  55. }
  56. /* fall through */
  57. }
  58. /*
  59. * Check for 888/A888.
  60. */
  61. if (var->bits_per_pixel <= 32 && var->red.length <= 8 &&
  62. var->green.length <= 8 && var->blue.length <= 8) {
  63. if (var->bits_per_pixel == 24 && var->transp.length == 0) {
  64. if (var->red.offset >= var->blue.offset)
  65. return PIX_FMT_RGB888PACK;
  66. else
  67. return PIX_FMT_BGR888PACK;
  68. }
  69. if (var->bits_per_pixel == 32 && var->transp.length == 8) {
  70. if (var->red.offset >= var->blue.offset)
  71. return PIX_FMT_RGBA888;
  72. else
  73. return PIX_FMT_BGRA888;
  74. } else {
  75. if (var->red.offset >= var->blue.offset)
  76. return PIX_FMT_RGB888UNPACK;
  77. else
  78. return PIX_FMT_BGR888UNPACK;
  79. }
  80. /* fall through */
  81. }
  82. return -EINVAL;
  83. }
  84. static void set_pix_fmt(struct fb_var_screeninfo *var, int pix_fmt)
  85. {
  86. switch (pix_fmt) {
  87. case PIX_FMT_RGB565:
  88. var->bits_per_pixel = 16;
  89. var->red.offset = 11; var->red.length = 5;
  90. var->green.offset = 5; var->green.length = 6;
  91. var->blue.offset = 0; var->blue.length = 5;
  92. var->transp.offset = 0; var->transp.length = 0;
  93. break;
  94. case PIX_FMT_BGR565:
  95. var->bits_per_pixel = 16;
  96. var->red.offset = 0; var->red.length = 5;
  97. var->green.offset = 5; var->green.length = 6;
  98. var->blue.offset = 11; var->blue.length = 5;
  99. var->transp.offset = 0; var->transp.length = 0;
  100. break;
  101. case PIX_FMT_RGB1555:
  102. var->bits_per_pixel = 16;
  103. var->red.offset = 10; var->red.length = 5;
  104. var->green.offset = 5; var->green.length = 5;
  105. var->blue.offset = 0; var->blue.length = 5;
  106. var->transp.offset = 15; var->transp.length = 1;
  107. break;
  108. case PIX_FMT_BGR1555:
  109. var->bits_per_pixel = 16;
  110. var->red.offset = 0; var->red.length = 5;
  111. var->green.offset = 5; var->green.length = 5;
  112. var->blue.offset = 10; var->blue.length = 5;
  113. var->transp.offset = 15; var->transp.length = 1;
  114. break;
  115. case PIX_FMT_RGB888PACK:
  116. var->bits_per_pixel = 24;
  117. var->red.offset = 16; var->red.length = 8;
  118. var->green.offset = 8; var->green.length = 8;
  119. var->blue.offset = 0; var->blue.length = 8;
  120. var->transp.offset = 0; var->transp.length = 0;
  121. break;
  122. case PIX_FMT_BGR888PACK:
  123. var->bits_per_pixel = 24;
  124. var->red.offset = 0; var->red.length = 8;
  125. var->green.offset = 8; var->green.length = 8;
  126. var->blue.offset = 16; var->blue.length = 8;
  127. var->transp.offset = 0; var->transp.length = 0;
  128. break;
  129. case PIX_FMT_RGBA888:
  130. var->bits_per_pixel = 32;
  131. var->red.offset = 16; var->red.length = 8;
  132. var->green.offset = 8; var->green.length = 8;
  133. var->blue.offset = 0; var->blue.length = 8;
  134. var->transp.offset = 24; var->transp.length = 8;
  135. break;
  136. case PIX_FMT_BGRA888:
  137. var->bits_per_pixel = 32;
  138. var->red.offset = 0; var->red.length = 8;
  139. var->green.offset = 8; var->green.length = 8;
  140. var->blue.offset = 16; var->blue.length = 8;
  141. var->transp.offset = 24; var->transp.length = 8;
  142. break;
  143. case PIX_FMT_PSEUDOCOLOR:
  144. var->bits_per_pixel = 8;
  145. var->red.offset = 0; var->red.length = 8;
  146. var->green.offset = 0; var->green.length = 8;
  147. var->blue.offset = 0; var->blue.length = 8;
  148. var->transp.offset = 0; var->transp.length = 0;
  149. break;
  150. }
  151. }
  152. static void set_mode(struct pxa168fb_info *fbi, struct fb_var_screeninfo *var,
  153. struct fb_videomode *mode, int pix_fmt, int ystretch)
  154. {
  155. struct fb_info *info = fbi->info;
  156. set_pix_fmt(var, pix_fmt);
  157. var->xres = mode->xres;
  158. var->yres = mode->yres;
  159. var->xres_virtual = max(var->xres, var->xres_virtual);
  160. if (ystretch)
  161. var->yres_virtual = info->fix.smem_len /
  162. (var->xres_virtual * (var->bits_per_pixel >> 3));
  163. else
  164. var->yres_virtual = max(var->yres, var->yres_virtual);
  165. var->grayscale = 0;
  166. var->accel_flags = FB_ACCEL_NONE;
  167. var->pixclock = mode->pixclock;
  168. var->left_margin = mode->left_margin;
  169. var->right_margin = mode->right_margin;
  170. var->upper_margin = mode->upper_margin;
  171. var->lower_margin = mode->lower_margin;
  172. var->hsync_len = mode->hsync_len;
  173. var->vsync_len = mode->vsync_len;
  174. var->sync = mode->sync;
  175. var->vmode = FB_VMODE_NONINTERLACED;
  176. var->rotate = FB_ROTATE_UR;
  177. }
  178. static int pxa168fb_check_var(struct fb_var_screeninfo *var,
  179. struct fb_info *info)
  180. {
  181. struct pxa168fb_info *fbi = info->par;
  182. int pix_fmt;
  183. /*
  184. * Determine which pixel format we're going to use.
  185. */
  186. pix_fmt = determine_best_pix_fmt(var);
  187. if (pix_fmt < 0)
  188. return pix_fmt;
  189. set_pix_fmt(var, pix_fmt);
  190. fbi->pix_fmt = pix_fmt;
  191. /*
  192. * Basic geometry sanity checks.
  193. */
  194. if (var->xoffset + var->xres > var->xres_virtual)
  195. return -EINVAL;
  196. if (var->yoffset + var->yres > var->yres_virtual)
  197. return -EINVAL;
  198. if (var->xres + var->right_margin +
  199. var->hsync_len + var->left_margin > 2048)
  200. return -EINVAL;
  201. if (var->yres + var->lower_margin +
  202. var->vsync_len + var->upper_margin > 2048)
  203. return -EINVAL;
  204. /*
  205. * Check size of framebuffer.
  206. */
  207. if (var->xres_virtual * var->yres_virtual *
  208. (var->bits_per_pixel >> 3) > info->fix.smem_len)
  209. return -EINVAL;
  210. return 0;
  211. }
  212. /*
  213. * The hardware clock divider has an integer and a fractional
  214. * stage:
  215. *
  216. * clk2 = clk_in / integer_divider
  217. * clk_out = clk2 * (1 - (fractional_divider >> 12))
  218. *
  219. * Calculate integer and fractional divider for given clk_in
  220. * and clk_out.
  221. */
  222. static void set_clock_divider(struct pxa168fb_info *fbi,
  223. const struct fb_videomode *m)
  224. {
  225. int divider_int;
  226. int needed_pixclk;
  227. u64 div_result;
  228. u32 x = 0;
  229. /*
  230. * Notice: The field pixclock is used by linux fb
  231. * is in pixel second. E.g. struct fb_videomode &
  232. * struct fb_var_screeninfo
  233. */
  234. /*
  235. * Check input values.
  236. */
  237. if (!m || !m->pixclock || !m->refresh) {
  238. dev_err(fbi->dev, "Input refresh or pixclock is wrong.\n");
  239. return;
  240. }
  241. /*
  242. * Using PLL/AXI clock.
  243. */
  244. x = 0x80000000;
  245. /*
  246. * Calc divider according to refresh rate.
  247. */
  248. div_result = 1000000000000ll;
  249. do_div(div_result, m->pixclock);
  250. needed_pixclk = (u32)div_result;
  251. divider_int = clk_get_rate(fbi->clk) / needed_pixclk;
  252. /* check whether divisor is too small. */
  253. if (divider_int < 2) {
  254. dev_warn(fbi->dev, "Warning: clock source is too slow."
  255. "Try smaller resolution\n");
  256. divider_int = 2;
  257. }
  258. /*
  259. * Set setting to reg.
  260. */
  261. x |= divider_int;
  262. writel(x, fbi->reg_base + LCD_CFG_SCLK_DIV);
  263. }
  264. static void set_dma_control0(struct pxa168fb_info *fbi)
  265. {
  266. u32 x;
  267. /*
  268. * Set bit to enable graphics DMA.
  269. */
  270. x = readl(fbi->reg_base + LCD_SPU_DMA_CTRL0);
  271. x &= ~CFG_GRA_ENA_MASK;
  272. x |= fbi->active ? CFG_GRA_ENA(1) : CFG_GRA_ENA(0);
  273. /*
  274. * If we are in a pseudo-color mode, we need to enable
  275. * palette lookup.
  276. */
  277. if (fbi->pix_fmt == PIX_FMT_PSEUDOCOLOR)
  278. x |= 0x10000000;
  279. /*
  280. * Configure hardware pixel format.
  281. */
  282. x &= ~(0xF << 16);
  283. x |= (fbi->pix_fmt >> 1) << 16;
  284. /*
  285. * Check red and blue pixel swap.
  286. * 1. source data swap
  287. * 2. panel output data swap
  288. */
  289. x &= ~(1 << 12);
  290. x |= ((fbi->pix_fmt & 1) ^ (fbi->panel_rbswap)) << 12;
  291. writel(x, fbi->reg_base + LCD_SPU_DMA_CTRL0);
  292. }
  293. static void set_dma_control1(struct pxa168fb_info *fbi, int sync)
  294. {
  295. u32 x;
  296. /*
  297. * Configure default bits: vsync triggers DMA, gated clock
  298. * enable, power save enable, configure alpha registers to
  299. * display 100% graphics, and set pixel command.
  300. */
  301. x = readl(fbi->reg_base + LCD_SPU_DMA_CTRL1);
  302. x |= 0x2032ff81;
  303. /*
  304. * We trigger DMA on the falling edge of vsync if vsync is
  305. * active low, or on the rising edge if vsync is active high.
  306. */
  307. if (!(sync & FB_SYNC_VERT_HIGH_ACT))
  308. x |= 0x08000000;
  309. writel(x, fbi->reg_base + LCD_SPU_DMA_CTRL1);
  310. }
  311. static void set_graphics_start(struct fb_info *info, int xoffset, int yoffset)
  312. {
  313. struct pxa168fb_info *fbi = info->par;
  314. struct fb_var_screeninfo *var = &info->var;
  315. int pixel_offset;
  316. unsigned long addr;
  317. pixel_offset = (yoffset * var->xres_virtual) + xoffset;
  318. addr = fbi->fb_start_dma + (pixel_offset * (var->bits_per_pixel >> 3));
  319. writel(addr, fbi->reg_base + LCD_CFG_GRA_START_ADDR0);
  320. }
  321. static void set_dumb_panel_control(struct fb_info *info)
  322. {
  323. struct pxa168fb_info *fbi = info->par;
  324. struct pxa168fb_mach_info *mi = fbi->dev->platform_data;
  325. u32 x;
  326. /*
  327. * Preserve enable flag.
  328. */
  329. x = readl(fbi->reg_base + LCD_SPU_DUMB_CTRL) & 0x00000001;
  330. x |= (fbi->is_blanked ? 0x7 : mi->dumb_mode) << 28;
  331. x |= mi->gpio_output_data << 20;
  332. x |= mi->gpio_output_mask << 12;
  333. x |= mi->panel_rgb_reverse_lanes ? 0x00000080 : 0;
  334. x |= mi->invert_composite_blank ? 0x00000040 : 0;
  335. x |= (info->var.sync & FB_SYNC_COMP_HIGH_ACT) ? 0x00000020 : 0;
  336. x |= mi->invert_pix_val_ena ? 0x00000010 : 0;
  337. x |= (info->var.sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 0x00000008;
  338. x |= (info->var.sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 0x00000004;
  339. x |= mi->invert_pixclock ? 0x00000002 : 0;
  340. writel(x, fbi->reg_base + LCD_SPU_DUMB_CTRL);
  341. }
  342. static void set_dumb_screen_dimensions(struct fb_info *info)
  343. {
  344. struct pxa168fb_info *fbi = info->par;
  345. struct fb_var_screeninfo *v = &info->var;
  346. int x;
  347. int y;
  348. x = v->xres + v->right_margin + v->hsync_len + v->left_margin;
  349. y = v->yres + v->lower_margin + v->vsync_len + v->upper_margin;
  350. writel((y << 16) | x, fbi->reg_base + LCD_SPUT_V_H_TOTAL);
  351. }
  352. static int pxa168fb_set_par(struct fb_info *info)
  353. {
  354. struct pxa168fb_info *fbi = info->par;
  355. struct fb_var_screeninfo *var = &info->var;
  356. struct fb_videomode mode;
  357. u32 x;
  358. struct pxa168fb_mach_info *mi;
  359. mi = fbi->dev->platform_data;
  360. /*
  361. * Set additional mode info.
  362. */
  363. if (fbi->pix_fmt == PIX_FMT_PSEUDOCOLOR)
  364. info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
  365. else
  366. info->fix.visual = FB_VISUAL_TRUECOLOR;
  367. info->fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
  368. info->fix.ypanstep = var->yres;
  369. /*
  370. * Disable panel output while we setup the display.
  371. */
  372. x = readl(fbi->reg_base + LCD_SPU_DUMB_CTRL);
  373. writel(x & ~1, fbi->reg_base + LCD_SPU_DUMB_CTRL);
  374. /*
  375. * Configure global panel parameters.
  376. */
  377. writel((var->yres << 16) | var->xres,
  378. fbi->reg_base + LCD_SPU_V_H_ACTIVE);
  379. /*
  380. * convet var to video mode
  381. */
  382. fb_var_to_videomode(&mode, &info->var);
  383. /* Calculate clock divisor. */
  384. set_clock_divider(fbi, &mode);
  385. /* Configure dma ctrl regs. */
  386. set_dma_control0(fbi);
  387. set_dma_control1(fbi, info->var.sync);
  388. /*
  389. * Configure graphics DMA parameters.
  390. */
  391. x = readl(fbi->reg_base + LCD_CFG_GRA_PITCH);
  392. x = (x & ~0xFFFF) | ((var->xres_virtual * var->bits_per_pixel) >> 3);
  393. writel(x, fbi->reg_base + LCD_CFG_GRA_PITCH);
  394. writel((var->yres << 16) | var->xres,
  395. fbi->reg_base + LCD_SPU_GRA_HPXL_VLN);
  396. writel((var->yres << 16) | var->xres,
  397. fbi->reg_base + LCD_SPU_GZM_HPXL_VLN);
  398. /*
  399. * Configure dumb panel ctrl regs & timings.
  400. */
  401. set_dumb_panel_control(info);
  402. set_dumb_screen_dimensions(info);
  403. writel((var->left_margin << 16) | var->right_margin,
  404. fbi->reg_base + LCD_SPU_H_PORCH);
  405. writel((var->upper_margin << 16) | var->lower_margin,
  406. fbi->reg_base + LCD_SPU_V_PORCH);
  407. /*
  408. * Re-enable panel output.
  409. */
  410. x = readl(fbi->reg_base + LCD_SPU_DUMB_CTRL);
  411. writel(x | 1, fbi->reg_base + LCD_SPU_DUMB_CTRL);
  412. return 0;
  413. }
  414. static unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf)
  415. {
  416. return ((chan & 0xffff) >> (16 - bf->length)) << bf->offset;
  417. }
  418. static u32 to_rgb(u16 red, u16 green, u16 blue)
  419. {
  420. red >>= 8;
  421. green >>= 8;
  422. blue >>= 8;
  423. return (red << 16) | (green << 8) | blue;
  424. }
  425. static int
  426. pxa168fb_setcolreg(unsigned int regno, unsigned int red, unsigned int green,
  427. unsigned int blue, unsigned int trans, struct fb_info *info)
  428. {
  429. struct pxa168fb_info *fbi = info->par;
  430. u32 val;
  431. if (info->var.grayscale)
  432. red = green = blue = (19595 * red + 38470 * green +
  433. 7471 * blue) >> 16;
  434. if (info->fix.visual == FB_VISUAL_TRUECOLOR && regno < 16) {
  435. val = chan_to_field(red, &info->var.red);
  436. val |= chan_to_field(green, &info->var.green);
  437. val |= chan_to_field(blue , &info->var.blue);
  438. fbi->pseudo_palette[regno] = val;
  439. }
  440. if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR && regno < 256) {
  441. val = to_rgb(red, green, blue);
  442. writel(val, fbi->reg_base + LCD_SPU_SRAM_WRDAT);
  443. writel(0x8300 | regno, fbi->reg_base + LCD_SPU_SRAM_CTRL);
  444. }
  445. return 0;
  446. }
  447. static int pxa168fb_blank(int blank, struct fb_info *info)
  448. {
  449. struct pxa168fb_info *fbi = info->par;
  450. fbi->is_blanked = (blank == FB_BLANK_UNBLANK) ? 0 : 1;
  451. set_dumb_panel_control(info);
  452. return 0;
  453. }
  454. static int pxa168fb_pan_display(struct fb_var_screeninfo *var,
  455. struct fb_info *info)
  456. {
  457. set_graphics_start(info, var->xoffset, var->yoffset);
  458. return 0;
  459. }
  460. static irqreturn_t pxa168fb_handle_irq(int irq, void *dev_id)
  461. {
  462. struct pxa168fb_info *fbi = dev_id;
  463. u32 isr = readl(fbi->reg_base + SPU_IRQ_ISR);
  464. if ((isr & GRA_FRAME_IRQ0_ENA_MASK)) {
  465. writel(isr & (~GRA_FRAME_IRQ0_ENA_MASK),
  466. fbi->reg_base + SPU_IRQ_ISR);
  467. return IRQ_HANDLED;
  468. }
  469. return IRQ_NONE;
  470. }
  471. static struct fb_ops pxa168fb_ops = {
  472. .owner = THIS_MODULE,
  473. .fb_check_var = pxa168fb_check_var,
  474. .fb_set_par = pxa168fb_set_par,
  475. .fb_setcolreg = pxa168fb_setcolreg,
  476. .fb_blank = pxa168fb_blank,
  477. .fb_pan_display = pxa168fb_pan_display,
  478. .fb_fillrect = cfb_fillrect,
  479. .fb_copyarea = cfb_copyarea,
  480. .fb_imageblit = cfb_imageblit,
  481. };
  482. static int __devinit pxa168fb_init_mode(struct fb_info *info,
  483. struct pxa168fb_mach_info *mi)
  484. {
  485. struct pxa168fb_info *fbi = info->par;
  486. struct fb_var_screeninfo *var = &info->var;
  487. int ret = 0;
  488. u32 total_w, total_h, refresh;
  489. u64 div_result;
  490. const struct fb_videomode *m;
  491. /*
  492. * Set default value
  493. */
  494. refresh = DEFAULT_REFRESH;
  495. /* try to find best video mode. */
  496. m = fb_find_best_mode(&info->var, &info->modelist);
  497. if (m)
  498. fb_videomode_to_var(&info->var, m);
  499. /* Init settings. */
  500. var->xres_virtual = var->xres;
  501. var->yres_virtual = info->fix.smem_len /
  502. (var->xres_virtual * (var->bits_per_pixel >> 3));
  503. dev_dbg(fbi->dev, "pxa168fb: find best mode: res = %dx%d\n",
  504. var->xres, var->yres);
  505. /* correct pixclock. */
  506. total_w = var->xres + var->left_margin + var->right_margin +
  507. var->hsync_len;
  508. total_h = var->yres + var->upper_margin + var->lower_margin +
  509. var->vsync_len;
  510. div_result = 1000000000000ll;
  511. do_div(div_result, total_w * total_h * refresh);
  512. var->pixclock = (u32)div_result;
  513. return ret;
  514. }
  515. static int __devinit pxa168fb_probe(struct platform_device *pdev)
  516. {
  517. struct pxa168fb_mach_info *mi;
  518. struct fb_info *info = 0;
  519. struct pxa168fb_info *fbi = 0;
  520. struct resource *res;
  521. struct clk *clk;
  522. int irq, ret;
  523. mi = pdev->dev.platform_data;
  524. if (mi == NULL) {
  525. dev_err(&pdev->dev, "no platform data defined\n");
  526. return -EINVAL;
  527. }
  528. clk = clk_get(&pdev->dev, "LCDCLK");
  529. if (IS_ERR(clk)) {
  530. dev_err(&pdev->dev, "unable to get LCDCLK");
  531. return PTR_ERR(clk);
  532. }
  533. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  534. if (res == NULL) {
  535. dev_err(&pdev->dev, "no IO memory defined\n");
  536. ret = -ENOENT;
  537. goto failed_put_clk;
  538. }
  539. irq = platform_get_irq(pdev, 0);
  540. if (irq < 0) {
  541. dev_err(&pdev->dev, "no IRQ defined\n");
  542. ret = -ENOENT;
  543. goto failed_put_clk;
  544. }
  545. info = framebuffer_alloc(sizeof(struct pxa168fb_info), &pdev->dev);
  546. if (info == NULL) {
  547. ret = -ENOMEM;
  548. goto failed_put_clk;
  549. }
  550. /* Initialize private data */
  551. fbi = info->par;
  552. fbi->info = info;
  553. fbi->clk = clk;
  554. fbi->dev = info->dev = &pdev->dev;
  555. fbi->panel_rbswap = mi->panel_rbswap;
  556. fbi->is_blanked = 0;
  557. fbi->active = mi->active;
  558. /*
  559. * Initialise static fb parameters.
  560. */
  561. info->flags = FBINFO_DEFAULT | FBINFO_PARTIAL_PAN_OK |
  562. FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN;
  563. info->node = -1;
  564. strlcpy(info->fix.id, mi->id, 16);
  565. info->fix.type = FB_TYPE_PACKED_PIXELS;
  566. info->fix.type_aux = 0;
  567. info->fix.xpanstep = 0;
  568. info->fix.ypanstep = 0;
  569. info->fix.ywrapstep = 0;
  570. info->fix.mmio_start = res->start;
  571. info->fix.mmio_len = res->end - res->start + 1;
  572. info->fix.accel = FB_ACCEL_NONE;
  573. info->fbops = &pxa168fb_ops;
  574. info->pseudo_palette = fbi->pseudo_palette;
  575. /*
  576. * Map LCD controller registers.
  577. */
  578. fbi->reg_base = ioremap_nocache(res->start, resource_size(res));
  579. if (fbi->reg_base == NULL) {
  580. ret = -ENOMEM;
  581. goto failed_free_info;
  582. }
  583. /*
  584. * Allocate framebuffer memory.
  585. */
  586. info->fix.smem_len = PAGE_ALIGN(DEFAULT_FB_SIZE);
  587. info->screen_base = dma_alloc_writecombine(fbi->dev, info->fix.smem_len,
  588. &fbi->fb_start_dma, GFP_KERNEL);
  589. if (info->screen_base == NULL) {
  590. ret = -ENOMEM;
  591. goto failed_free_info;
  592. }
  593. info->fix.smem_start = (unsigned long)fbi->fb_start_dma;
  594. set_graphics_start(info, 0, 0);
  595. /*
  596. * Set video mode according to platform data.
  597. */
  598. set_mode(fbi, &info->var, mi->modes, mi->pix_fmt, 1);
  599. fb_videomode_to_modelist(mi->modes, mi->num_modes, &info->modelist);
  600. /*
  601. * init video mode data.
  602. */
  603. pxa168fb_init_mode(info, mi);
  604. /*
  605. * Fill in sane defaults.
  606. */
  607. ret = pxa168fb_check_var(&info->var, info);
  608. if (ret)
  609. goto failed_free_fbmem;
  610. /*
  611. * enable controller clock
  612. */
  613. clk_enable(fbi->clk);
  614. pxa168fb_set_par(info);
  615. /*
  616. * Configure default register values.
  617. */
  618. writel(0, fbi->reg_base + LCD_SPU_BLANKCOLOR);
  619. writel(mi->io_pin_allocation_mode, fbi->reg_base + SPU_IOPAD_CONTROL);
  620. writel(0, fbi->reg_base + LCD_CFG_GRA_START_ADDR1);
  621. writel(0, fbi->reg_base + LCD_SPU_GRA_OVSA_HPXL_VLN);
  622. writel(0, fbi->reg_base + LCD_SPU_SRAM_PARA0);
  623. writel(CFG_CSB_256x32(0x1)|CFG_CSB_256x24(0x1)|CFG_CSB_256x8(0x1),
  624. fbi->reg_base + LCD_SPU_SRAM_PARA1);
  625. /*
  626. * Allocate color map.
  627. */
  628. if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
  629. ret = -ENOMEM;
  630. goto failed_free_clk;
  631. }
  632. /*
  633. * Register irq handler.
  634. */
  635. ret = request_irq(irq, pxa168fb_handle_irq, IRQF_SHARED,
  636. info->fix.id, fbi);
  637. if (ret < 0) {
  638. dev_err(&pdev->dev, "unable to request IRQ\n");
  639. ret = -ENXIO;
  640. goto failed_free_cmap;
  641. }
  642. /*
  643. * Enable GFX interrupt
  644. */
  645. writel(GRA_FRAME_IRQ0_ENA(0x1), fbi->reg_base + SPU_IRQ_ENA);
  646. /*
  647. * Register framebuffer.
  648. */
  649. ret = register_framebuffer(info);
  650. if (ret < 0) {
  651. dev_err(&pdev->dev, "Failed to register pxa168-fb: %d\n", ret);
  652. ret = -ENXIO;
  653. goto failed_free_irq;
  654. }
  655. platform_set_drvdata(pdev, fbi);
  656. return 0;
  657. failed_free_irq:
  658. free_irq(irq, fbi);
  659. failed_free_cmap:
  660. fb_dealloc_cmap(&info->cmap);
  661. failed_free_clk:
  662. clk_disable(fbi->clk);
  663. failed_free_fbmem:
  664. dma_free_coherent(fbi->dev, info->fix.smem_len,
  665. info->screen_base, fbi->fb_start_dma);
  666. failed_free_info:
  667. kfree(info);
  668. failed_put_clk:
  669. clk_put(clk);
  670. dev_err(&pdev->dev, "frame buffer device init failed with %d\n", ret);
  671. return ret;
  672. }
  673. static int __devexit pxa168fb_remove(struct platform_device *pdev)
  674. {
  675. struct pxa168fb_info *fbi = platform_get_drvdata(pdev);
  676. struct fb_info *info;
  677. int irq;
  678. unsigned int data;
  679. if (!fbi)
  680. return 0;
  681. /* disable DMA transfer */
  682. data = readl(fbi->reg_base + LCD_SPU_DMA_CTRL0);
  683. data &= ~CFG_GRA_ENA_MASK;
  684. writel(data, fbi->reg_base + LCD_SPU_DMA_CTRL0);
  685. info = fbi->info;
  686. unregister_framebuffer(info);
  687. writel(GRA_FRAME_IRQ0_ENA(0x0), fbi->reg_base + SPU_IRQ_ENA);
  688. if (info->cmap.len)
  689. fb_dealloc_cmap(&info->cmap);
  690. irq = platform_get_irq(pdev, 0);
  691. free_irq(irq, fbi);
  692. dma_free_writecombine(fbi->dev, PAGE_ALIGN(info->fix.smem_len),
  693. info->screen_base, info->fix.smem_start);
  694. iounmap(fbi->reg_base);
  695. clk_disable(fbi->clk);
  696. clk_put(fbi->clk);
  697. framebuffer_release(info);
  698. return 0;
  699. }
  700. static struct platform_driver pxa168fb_driver = {
  701. .driver = {
  702. .name = "pxa168-fb",
  703. .owner = THIS_MODULE,
  704. },
  705. .probe = pxa168fb_probe,
  706. .remove = __devexit_p(pxa168fb_remove),
  707. };
  708. static int __init pxa168fb_init(void)
  709. {
  710. return platform_driver_register(&pxa168fb_driver);
  711. }
  712. module_init(pxa168fb_init);
  713. static void __exit pxa168fb_exit(void)
  714. {
  715. platform_driver_unregister(&pxa168fb_driver);
  716. }
  717. module_exit(pxa168fb_exit);
  718. MODULE_AUTHOR("Lennert Buytenhek <buytenh@marvell.com> "
  719. "Green Wan <gwan@marvell.com>");
  720. MODULE_DESCRIPTION("Framebuffer driver for PXA168/910");
  721. MODULE_LICENSE("GPL");