mtkfb_dummy.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  1. /*#include <generated/autoconf.h>*/
  2. #include <linux/module.h>
  3. #include <linux/mm.h>
  4. #include <linux/init.h>
  5. #include <linux/fb.h>
  6. #include <linux/delay.h>
  7. #include <linux/device.h>
  8. #include <linux/platform_device.h>
  9. #include <linux/dma-mapping.h>
  10. #include <linux/kthread.h>
  11. #include <linux/vmalloc.h>
  12. #include <linux/semaphore.h>
  13. #include <linux/mutex.h>
  14. #include <linux/suspend.h>
  15. #include <linux/of_fdt.h>
  16. #include <linux/of.h>
  17. #include <linux/of_address.h>
  18. #include <linux/dma-buf.h>
  19. #include <linux/uaccess.h>
  20. #include <linux/atomic.h>
  21. #include <asm/cacheflush.h>
  22. #include <linux/io.h>
  23. #include "mtkfb.h"
  24. #include "mtkfb_info.h"
  25. #include <linux/bug.h>
  26. /* #include <linux/earlysuspend.h> */
  27. /* #include <linux/rtpm_prio.h> */
  28. /* #include "disp_assert_layer.h" */
  29. /* #include <linux/xlog.h> */
  30. /* #include <linux/leds-mt65xx.h> */
  31. /* #include <mach/dma.h> */
  32. /* #include <mach/irqs.h> */
  33. /* #include "mach/mt_boot.h" */
  34. #define DISPCHECK pr_warn
  35. #define ALIGN_TO(x, n) \
  36. (((x) + ((n) - 1)) & ~((n) - 1))
  37. #define SCREEN_WIDHT (1280)
  38. #define SCREEN_HEIGHT (720)
  39. #define MTK_FB_ALIGNMENT 32
  40. static u32 MTK_FB_XRES;
  41. static u32 MTK_FB_YRES;
  42. static u32 MTK_FB_BPP;
  43. static u32 MTK_FB_PAGES;
  44. static u32 fb_xres_update;
  45. static u32 fb_yres_update;
  46. #define MTK_FB_XRESV (ALIGN_TO(MTK_FB_XRES, MTK_FB_ALIGNMENT))
  47. #define MTK_FB_YRESV (ALIGN_TO(MTK_FB_YRES, MTK_FB_ALIGNMENT) * MTK_FB_PAGES) /* For page flipping */
  48. #define MTK_FB_BYPP ((MTK_FB_BPP + 7) >> 3)
  49. #define MTK_FB_LINE (ALIGN_TO(MTK_FB_XRES, MTK_FB_ALIGNMENT) * MTK_FB_BYPP)
  50. #define MTK_FB_SIZE (MTK_FB_LINE * ALIGN_TO(MTK_FB_YRES, MTK_FB_ALIGNMENT))
  51. #define MTK_FB_SIZEV (MTK_FB_LINE * ALIGN_TO(MTK_FB_YRES, MTK_FB_ALIGNMENT) * MTK_FB_PAGES)
  52. /* --------------------------------------------------------------------------- */
  53. /* local variables */
  54. /* --------------------------------------------------------------------------- */
  55. unsigned int fb_pa = 0;
  56. struct fb_info *mtkfb_fbi;
  57. unsigned int lcd_fps = 6000;
  58. char mtkfb_lcm_name[256] = { 0 };
  59. bool is_ipoh_bootup = false;
  60. bool is_early_suspended = false;
  61. /* --------------------------------------------------------------------------- */
  62. /* local function declarations */
  63. /* --------------------------------------------------------------------------- */
  64. int mtkfb_get_debug_state(char *stringbuf, int buf_len)
  65. {
  66. return 0;
  67. }
  68. unsigned int mtkfb_fm_auto_test(void)
  69. {
  70. return 0;
  71. }
  72. unsigned int DISP_GetVRamSizeBoot(void)
  73. {
  74. return 0x01800000;
  75. }
  76. /*
  77. * ---------------------------------------------------------------------------
  78. * fbdev framework callbacks and the ioctl interface
  79. * ---------------------------------------------------------------------------
  80. */
  81. /* Called each time the mtkfb device is opened */
  82. static int mtkfb_open(struct fb_info *info, int user)
  83. {
  84. return 0;
  85. }
  86. /* Called when the mtkfb device is closed. We make sure that any pending
  87. * gfx DMA operations are ended, before we return. */
  88. static int mtkfb_release(struct fb_info *info, int user)
  89. {
  90. return 0;
  91. }
  92. /* Store a single color palette entry into a pseudo palette or the hardware
  93. * palette if one is available. For now we support only 16bpp and thus store
  94. * the entry only to the pseudo palette.
  95. */
  96. static int mtkfb_setcolreg(u_int regno, u_int red, u_int green,
  97. u_int blue, u_int transp, struct fb_info *info)
  98. {
  99. int r = 0;
  100. unsigned bpp, m;
  101. /* NOT_REFERENCED(transp); */
  102. bpp = info->var.bits_per_pixel;
  103. m = 1 << bpp;
  104. if (regno >= m) {
  105. r = -EINVAL;
  106. goto exit;
  107. }
  108. switch (bpp) {
  109. case 16:
  110. /* RGB 565 */
  111. ((u32 *) (info->pseudo_palette))[regno] =
  112. ((red & 0xF800) | ((green & 0xFC00) >> 5) | ((blue & 0xF800) >> 11));
  113. break;
  114. case 32:
  115. /* ARGB8888 */
  116. ((u32 *) (info->pseudo_palette))[regno] =
  117. (0xff000000) |
  118. ((red & 0xFF00) << 8) | ((green & 0xFF00)) | ((blue & 0xFF00) >> 8);
  119. break;
  120. /* TODO: RGB888, BGR888, ABGR8888 */
  121. default:
  122. BUG();
  123. }
  124. exit:
  125. return r;
  126. }
  127. /* Set fb_info.fix fields and also updates fbdev.
  128. * When calling this fb_info.var must be set up already.
  129. */
  130. static void set_fb_fix(struct mtkfb_device *fbdev)
  131. {
  132. struct fb_info *fbi = fbdev->fb_info;
  133. struct fb_fix_screeninfo *fix = &fbi->fix;
  134. struct fb_var_screeninfo *var = &fbi->var;
  135. struct fb_ops *fbops = fbi->fbops;
  136. strncpy(fix->id, MTKFB_DRIVER, sizeof(fix->id));
  137. fix->type = FB_TYPE_PACKED_PIXELS;
  138. switch (var->bits_per_pixel) {
  139. case 16:
  140. case 24:
  141. case 32:
  142. fix->visual = FB_VISUAL_TRUECOLOR;
  143. break;
  144. case 1:
  145. case 2:
  146. case 4:
  147. case 8:
  148. fix->visual = FB_VISUAL_PSEUDOCOLOR;
  149. break;
  150. default:
  151. BUG();
  152. }
  153. fix->accel = FB_ACCEL_NONE;
  154. fix->line_length = ALIGN_TO(var->xres_virtual, MTK_FB_ALIGNMENT) * var->bits_per_pixel / 8;
  155. fix->smem_len = fbdev->fb_size_in_byte;
  156. fix->smem_start = fbdev->fb_pa_base;
  157. fix->xpanstep = 0;
  158. fix->ypanstep = 1;
  159. fbops->fb_fillrect = cfb_fillrect;
  160. fbops->fb_copyarea = cfb_copyarea;
  161. fbops->fb_imageblit = cfb_imageblit;
  162. }
  163. /* Switch to a new mode. The parameters for it has been check already by
  164. * mtkfb_check_var.
  165. */
  166. static int mtkfb_set_par(struct fb_info *fbi)
  167. {
  168. struct mtkfb_device *fbdev = (struct mtkfb_device *)fbi->par;
  169. set_fb_fix(fbdev);
  170. return 0;
  171. }
  172. static int mtkfb_pan_display_impl(struct fb_var_screeninfo *var, struct fb_info *info)
  173. {
  174. DISPCHECK("xoffset=%u, yoffset=%u, xres=%u, yres=%u, xresv=%u, yresv=%u\n", var->xoffset,
  175. var->yoffset, info->var.xres, info->var.yres, info->var.xres_virtual,
  176. info->var.yres_virtual);
  177. info->var.yoffset = var->yoffset;
  178. return 0;
  179. }
  180. /* Check values in var, try to adjust them in case of out of bound values if
  181. * possible, or return error.
  182. */
  183. static int mtkfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi)
  184. {
  185. unsigned int bpp;
  186. unsigned long max_frame_size;
  187. unsigned long line_size;
  188. struct mtkfb_device *fbdev = (struct mtkfb_device *)fbi->par;
  189. pr_warn("mtkfb_check_var, xres=%u, yres=%u, xres_virtual=%u, yres_virtual=%u, xoffset=%u, yoffset=%u, bits_per_pixel=%u)\n",
  190. var->xres, var->yres, var->xres_virtual, var->yres_virtual,
  191. var->xoffset, var->yoffset, var->bits_per_pixel);
  192. bpp = var->bits_per_pixel;
  193. if (bpp != 16 && bpp != 24 && bpp != 32) {
  194. DISPCHECK("[%s]unsupported bpp: %d", __func__, bpp);
  195. return -1;
  196. }
  197. switch (var->rotate) {
  198. case 0:
  199. case 180:
  200. var->xres = MTK_FB_XRES;
  201. var->yres = MTK_FB_YRES;
  202. break;
  203. case 90:
  204. case 270:
  205. var->xres = MTK_FB_YRES;
  206. var->yres = MTK_FB_XRES;
  207. break;
  208. default:
  209. return -1;
  210. }
  211. if (var->xres_virtual < var->xres)
  212. var->xres_virtual = var->xres;
  213. if (var->yres_virtual < var->yres)
  214. var->yres_virtual = var->yres;
  215. max_frame_size = fbdev->fb_size_in_byte;
  216. DISPCHECK("fbdev->fb_size_in_byte=0x%08lx\n", fbdev->fb_size_in_byte);
  217. line_size = var->xres_virtual * bpp / 8;
  218. if (line_size * var->yres_virtual > max_frame_size) {
  219. /* Try to keep yres_virtual first */
  220. line_size = max_frame_size / var->yres_virtual;
  221. var->xres_virtual = line_size * 8 / bpp;
  222. if (var->xres_virtual < var->xres) {
  223. /* Still doesn't fit. Shrink yres_virtual too */
  224. var->xres_virtual = var->xres;
  225. line_size = var->xres * bpp / 8;
  226. var->yres_virtual = max_frame_size / line_size;
  227. }
  228. }
  229. pr_warn("mtkfb_check_var, xres=%u, yres=%u, xres_virtual=%u, yres_virtual=%u, xoffset=%u, yoffset=%u, bits_per_pixel=%u)\n",
  230. var->xres, var->yres, var->xres_virtual, var->yres_virtual,
  231. var->xoffset, var->yoffset, var->bits_per_pixel);
  232. if (var->xres + var->xoffset > var->xres_virtual)
  233. var->xoffset = var->xres_virtual - var->xres;
  234. if (var->yres + var->yoffset > var->yres_virtual)
  235. var->yoffset = var->yres_virtual - var->yres;
  236. pr_warn("mtkfb_check_var, xres=%u, yres=%u, xres_virtual=%u, yres_virtual=%u, xoffset=%u, yoffset=%u, bits_per_pixel=%u)\n",
  237. var->xres, var->yres, var->xres_virtual, var->yres_virtual,
  238. var->xoffset, var->yoffset, var->bits_per_pixel);
  239. if (16 == bpp) {
  240. var->red.offset = 11;
  241. var->red.length = 5;
  242. var->green.offset = 5;
  243. var->green.length = 6;
  244. var->blue.offset = 0;
  245. var->blue.length = 5;
  246. var->transp.offset = 0;
  247. var->transp.length = 0;
  248. } else if (24 == bpp) {
  249. var->red.length = var->green.length = var->blue.length = 8;
  250. var->transp.length = 0;
  251. /* Check if format is RGB565 or BGR565 */
  252. BUG_ON(!(8 == var->green.offset));
  253. BUG_ON(!(16 == var->red.offset + var->blue.offset));
  254. BUG_ON(!(16 == var->red.offset || 0 == var->red.offset));
  255. } else if (32 == bpp) {
  256. var->red.length = var->green.length = var->blue.length = var->transp.length = 8;
  257. /* Check if format is ARGB565 or ABGR565 */
  258. BUG_ON(!(8 == var->green.offset && 24 == var->transp.offset));
  259. BUG_ON(!(16 == var->red.offset + var->blue.offset));
  260. BUG_ON(!(16 == var->red.offset || 0 == var->red.offset));
  261. }
  262. var->red.msb_right = var->green.msb_right = var->blue.msb_right = var->transp.msb_right = 0;
  263. var->activate = FB_ACTIVATE_NOW;
  264. var->height = UINT_MAX;
  265. var->width = UINT_MAX;
  266. var->grayscale = 0;
  267. var->nonstd = 0;
  268. var->pixclock = UINT_MAX;
  269. var->left_margin = UINT_MAX;
  270. var->right_margin = UINT_MAX;
  271. var->upper_margin = UINT_MAX;
  272. var->lower_margin = UINT_MAX;
  273. var->hsync_len = UINT_MAX;
  274. var->vsync_len = UINT_MAX;
  275. var->vmode = FB_VMODE_NONINTERLACED;
  276. var->sync = 0;
  277. return 0;
  278. }
  279. static int mtkfb_pan_display_proxy(struct fb_var_screeninfo *var, struct fb_info *info)
  280. {
  281. return mtkfb_pan_display_impl(var, info);
  282. }
  283. /* Callback table for the frame buffer framework. Some of these pointers
  284. * will be changed according to the current setting of fb_info->accel_flags.
  285. */
  286. static struct fb_ops mtkfb_ops = {
  287. .owner = THIS_MODULE,
  288. .fb_open = mtkfb_open,
  289. .fb_release = mtkfb_release,
  290. .fb_setcolreg = mtkfb_setcolreg,
  291. .fb_pan_display = mtkfb_pan_display_proxy,
  292. .fb_fillrect = cfb_fillrect,
  293. .fb_copyarea = cfb_copyarea,
  294. .fb_imageblit = cfb_imageblit,
  295. .fb_cursor = NULL,
  296. .fb_check_var = mtkfb_check_var,
  297. .fb_set_par = mtkfb_set_par,
  298. .fb_ioctl = NULL,
  299. };
  300. /*
  301. * ---------------------------------------------------------------------------
  302. * LDM callbacks
  303. * ---------------------------------------------------------------------------
  304. */
  305. /* Initialize system fb_info object and set the default video mode.
  306. * The frame buffer memory already allocated by lcddma_init
  307. */
  308. static int mtkfb_fbinfo_init(struct fb_info *info)
  309. {
  310. struct mtkfb_device *fbdev = (struct mtkfb_device *)info->par;
  311. struct fb_var_screeninfo var;
  312. int r = 0;
  313. BUG_ON(!fbdev->fb_va_base);
  314. info->fbops = &mtkfb_ops;
  315. info->flags = FBINFO_FLAG_DEFAULT;
  316. info->screen_base = (char *)fbdev->fb_va_base;
  317. info->screen_size = fbdev->fb_size_in_byte;
  318. info->pseudo_palette = fbdev->pseudo_palette;
  319. r = fb_alloc_cmap(&info->cmap, 32, 0);
  320. if (r != 0)
  321. DISPCHECK("unable to allocate color map memory\n");
  322. /* setup the initial video mode (RGB565) */
  323. memset(&var, 0, sizeof(var));
  324. var.xres = MTK_FB_XRES;
  325. var.yres = MTK_FB_YRES;
  326. var.xres_virtual = MTK_FB_XRESV;
  327. var.yres_virtual = MTK_FB_YRESV;
  328. /* use 32 bit framebuffer as default */
  329. var.bits_per_pixel = 32;
  330. var.transp.offset = 24;
  331. var.red.length = 8;
  332. #if 0
  333. var.red.offset = 16;
  334. var.red.length = 8;
  335. var.green.offset = 8;
  336. var.green.length = 8;
  337. var.blue.offset = 0;
  338. var.blue.length = 8;
  339. #else
  340. var.red.offset = 0;
  341. var.red.length = 8;
  342. var.green.offset = 8;
  343. var.green.length = 8;
  344. var.blue.offset = 16;
  345. var.blue.length = 8;
  346. #endif
  347. var.width = 0;
  348. var.height = 0;
  349. var.activate = FB_ACTIVATE_NOW;
  350. r = mtkfb_check_var(&var, info);
  351. if (r != 0)
  352. DISPCHECK("failed to mtkfb_check_var\n");
  353. info->var = var;
  354. r = mtkfb_set_par(info);
  355. if (r != 0)
  356. DISPCHECK("failed to mtkfb_set_par\n");
  357. return r;
  358. }
  359. /* Release the fb_info object */
  360. static void mtkfb_fbinfo_cleanup(struct mtkfb_device *fbdev)
  361. {
  362. fb_dealloc_cmap(&fbdev->fb_info->cmap);
  363. }
  364. /* Free driver resources. Can be called to rollback an aborted initialization
  365. * sequence.
  366. */
  367. static void mtkfb_free_resources(struct mtkfb_device *fbdev, int state)
  368. {
  369. int r = 0;
  370. switch (state) {
  371. case MTKFB_ACTIVE:
  372. r = unregister_framebuffer(fbdev->fb_info);
  373. BUG_ON(!(0 == r));
  374. /* lint -fallthrough */
  375. case 4:
  376. mtkfb_fbinfo_cleanup(fbdev);
  377. /* lint -fallthrough */
  378. case 2:
  379. #ifndef FPGA_EARLY_PORTING
  380. dma_free_coherent(0, fbdev->fb_size_in_byte, fbdev->fb_va_base, fbdev->fb_pa_base);
  381. #endif
  382. /* lint -fallthrough */
  383. case 1:
  384. dev_set_drvdata(fbdev->dev, NULL);
  385. framebuffer_release(fbdev->fb_info);
  386. /* lint -fallthrough */
  387. case 0:
  388. /* nothing to free */
  389. break;
  390. default:
  391. BUG();
  392. }
  393. }
  394. unsigned int vramsize = 0;
  395. #ifdef CONFIG_OF
  396. struct tag_videolfb {
  397. u64 fb_base;
  398. u32 islcmfound;
  399. u32 fps;
  400. u32 vram;
  401. char lcmname[1]; /* this is the minimum size */
  402. };
  403. unsigned int islcmconnected = 0;
  404. phys_addr_t fb_base = 0;
  405. static int is_videofb_parse_done;
  406. static unsigned long video_node;
  407. static int fb_early_init_dt_get_chosen(unsigned long node, const char *uname, int depth, void *data)
  408. {
  409. if (depth != 1 || (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
  410. return 0;
  411. video_node = node;
  412. return 1;
  413. }
  414. /* 0: success / 1: fail */
  415. int _parse_tag_videolfb(void)
  416. {
  417. int size = 0;
  418. const void *prop = NULL;
  419. const struct tag_videolfb *videolfb_tag = NULL;
  420. DISPCHECK("[DT][videolfb]isvideofb_parse_done = %d\n", is_videofb_parse_done);
  421. if (is_videofb_parse_done)
  422. return 0;
  423. if (of_scan_flat_dt(fb_early_init_dt_get_chosen, NULL) > 0) {
  424. videolfb_tag = (struct tag_videolfb *)of_get_flat_dt_prop(video_node, "atag,videolfb", NULL);
  425. if (videolfb_tag) {
  426. DISPCHECK("[DT][videolfb] find video info from lk\n");
  427. memset((void *)mtkfb_lcm_name, 0, sizeof(mtkfb_lcm_name));
  428. strcpy((char *)mtkfb_lcm_name, videolfb_tag->lcmname);
  429. mtkfb_lcm_name[strlen(videolfb_tag->lcmname)] = '\0';
  430. lcd_fps = videolfb_tag->fps;
  431. if (0 == lcd_fps)
  432. lcd_fps = 6000;
  433. islcmconnected = videolfb_tag->islcmfound;
  434. vramsize = videolfb_tag->vram;
  435. fb_base = videolfb_tag->fb_base;
  436. is_videofb_parse_done = 1;
  437. DISPCHECK("[DT][videolfb] islcmfound = %d\n", islcmconnected);
  438. DISPCHECK("[DT][videolfb] fps = %d\n", lcd_fps);
  439. DISPCHECK("[DT][videolfb] fb_base = %p\n", (void *)fb_base);
  440. DISPCHECK("[DT][videolfb] vram = %d\n", vramsize);
  441. DISPCHECK("[DT][videolfb] lcmname = %s\n", mtkfb_lcm_name);
  442. } else {
  443. DISPCHECK("[DT][videolfb] find video info from dts\n");
  444. prop = of_get_flat_dt_prop(video_node, "atag,videolfb-fb_base", NULL);
  445. if (!prop) {
  446. DISPCHECK("[DT][videolfb] fail to parse fb_base\n");
  447. return -1;
  448. }
  449. fb_base = of_read_number(prop, 1);
  450. prop = of_get_flat_dt_prop(video_node, "atag,videolfb-islcmfound", NULL);
  451. if (!prop) {
  452. DISPCHECK("[DT][videolfb] fail to parse islcmfound\n");
  453. return -1;
  454. }
  455. islcmconnected = of_read_number(prop, 1);
  456. prop = of_get_flat_dt_prop(video_node, "atag,videolfb-fps", NULL);
  457. if (!prop) {
  458. DISPCHECK("[DT][videolfb] fail to parse fps\n");
  459. return -1;
  460. }
  461. lcd_fps = of_read_number(prop, 1);
  462. if (0 == lcd_fps)
  463. lcd_fps = 6000;
  464. prop = of_get_flat_dt_prop(video_node, "atag,videolfb-vramSize", NULL);
  465. if (!prop) {
  466. DISPCHECK("[DT][videolfb] fail to parse vramSize\n");
  467. return -1;
  468. }
  469. vramsize = of_read_number(prop, 1);
  470. prop = of_get_flat_dt_prop(video_node, "atag,videolfb-lcmname", &size);
  471. if (!prop) {
  472. DISPCHECK("[DT][videolfb] fail to parse lcmname\n");
  473. return -1;
  474. }
  475. if (size >= sizeof(mtkfb_lcm_name)) {
  476. DISPCHECK("%s: error to get lcmname size=%d\n", __func__,
  477. size);
  478. return -1;
  479. }
  480. memset((void *)mtkfb_lcm_name, 0, sizeof(mtkfb_lcm_name));
  481. strncpy((char *)mtkfb_lcm_name, prop, sizeof(mtkfb_lcm_name));
  482. mtkfb_lcm_name[size] = '\0';
  483. is_videofb_parse_done = 1;
  484. DISPCHECK("[DT][videolfb] fb_base = %p\n", (void *)fb_base);
  485. DISPCHECK("[DT][videolfb] islcmfound = %d\n", islcmconnected);
  486. DISPCHECK("[DT][videolfb] fps = %d\n", lcd_fps);
  487. DISPCHECK("[DT][videolfb] vram = %d\n", vramsize);
  488. DISPCHECK("[DT][videolfb] lcmname = %s\n", mtkfb_lcm_name);
  489. }
  490. } else {
  491. DISPCHECK("[DT][videolfb] of_chosen not found\n");
  492. return 1;
  493. }
  494. return 0;
  495. }
  496. phys_addr_t mtkfb_get_fb_base(void)
  497. {
  498. _parse_tag_videolfb();
  499. return fb_base;
  500. }
  501. #endif
  502. int mtkfb_allocate_framebuffer(phys_addr_t pa_start, phys_addr_t pa_end, unsigned int *va,
  503. unsigned int *mva)
  504. {
  505. *va = (unsigned long)ioremap_nocache(pa_start, pa_end - pa_start + 1);
  506. DISPCHECK("disphal_allocate_fb, pa=%pa, va=0x%08x\n", &pa_start, *va);
  507. {
  508. *mva = pa_start & 0xffffffffULL;
  509. }
  510. return 0;
  511. }
  512. static int mtkfb_probe(struct device *dev)
  513. {
  514. struct platform_device *pdev;
  515. struct mtkfb_device *fbdev = NULL;
  516. struct fb_info *fbi;
  517. int init_state;
  518. int r = 0;
  519. DISPCHECK("mtkfb_probe begin\n");
  520. #ifdef CONFIG_OF
  521. _parse_tag_videolfb();
  522. #endif
  523. init_state = 0;
  524. pdev = to_platform_device(dev);
  525. fbi = framebuffer_alloc(sizeof(struct mtkfb_device), dev);
  526. if (!fbi) {
  527. DISPCHECK("unable to allocate memory for device info\n");
  528. r = -ENOMEM;
  529. goto cleanup;
  530. }
  531. fbdev = (struct mtkfb_device *)fbi->par;
  532. fbdev->fb_info = fbi;
  533. fbdev->dev = dev;
  534. dev_set_drvdata(dev, fbdev);
  535. {
  536. #ifdef CONFIG_OF
  537. DISPCHECK("mtkfb_probe:get FB MEM REG\n");
  538. _parse_tag_videolfb();
  539. DISPCHECK("mtkfb_probe: fb_pa = 0x%p\n", (void *)fb_base);
  540. mtkfb_allocate_framebuffer(fb_base, (fb_base + vramsize - 1),
  541. (unsigned int *)&fbdev->fb_va_base, &fb_pa);
  542. fbdev->fb_pa_base = (dma_addr_t) fb_base;
  543. #else
  544. struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  545. disp_hal_allocate_framebuffer(res->start, res->end,
  546. (unsigned int *)&fbdev->fb_va_base, &fb_pa);
  547. fbdev->fb_pa_base = res->start;
  548. #endif
  549. }
  550. init_state++; /* 1 */
  551. MTK_FB_XRES = SCREEN_WIDHT;
  552. MTK_FB_YRES = SCREEN_HEIGHT;
  553. fb_xres_update = MTK_FB_XRES;
  554. fb_yres_update = MTK_FB_YRES;
  555. MTK_FB_BPP = 32;
  556. MTK_FB_PAGES = 3;
  557. DISPCHECK
  558. ("MTK_FB_XRES=%d, MTKFB_YRES=%d, MTKFB_BPP=%d, MTK_FB_PAGES=%d, MTKFB_LINE=%d, MTKFB_SIZEV=%d\n",
  559. MTK_FB_XRES, MTK_FB_YRES, MTK_FB_BPP, MTK_FB_PAGES, MTK_FB_LINE, MTK_FB_SIZEV);
  560. fbdev->fb_size_in_byte = MTK_FB_SIZEV;
  561. /* Allocate and initialize video frame buffer */
  562. DISPCHECK("[FB Driver] fbdev->fb_pa_base = %p, fbdev->fb_va_base = %lx\n",
  563. (void *)fbdev->fb_pa_base, (unsigned long)(fbdev->fb_va_base));
  564. if (!fbdev->fb_va_base) {
  565. DISPCHECK("unable to allocate memory for frame buffer\n");
  566. r = -ENOMEM;
  567. goto cleanup;
  568. }
  569. init_state++; /* 2 */
  570. /* Register to system */
  571. r = mtkfb_fbinfo_init(fbi);
  572. if (r) {
  573. DISPCHECK("mtkfb_fbinfo_init fail, r = %d\n", r);
  574. goto cleanup;
  575. }
  576. init_state++; /* 4 */
  577. mtkfb_fbi = fbi;
  578. init_state++; /* 5 */
  579. r = register_framebuffer(fbi);
  580. if (r != 0) {
  581. DISPCHECK("register_framebuffer failed\n");
  582. goto cleanup;
  583. }
  584. fbdev->state = MTKFB_ACTIVE;
  585. DISPCHECK("mtkfb_probe end\n");
  586. return 0;
  587. cleanup:
  588. mtkfb_free_resources(fbdev, init_state);
  589. DISPCHECK("mtkfb_probe end\n");
  590. return r;
  591. }
  592. /* Called when the device is being detached from the driver */
  593. static int mtkfb_remove(struct device *dev)
  594. {
  595. struct mtkfb_device *fbdev = dev_get_drvdata(dev);
  596. enum mtkfb_state saved_state = fbdev->state;
  597. fbdev->state = MTKFB_DISABLED;
  598. mtkfb_free_resources(fbdev, saved_state);
  599. return 0;
  600. }
  601. int mtkfb_ipo_init(void)
  602. {
  603. return 0;
  604. }
  605. void mtkfb_clear_lcm(void)
  606. {
  607. ;
  608. }
  609. static const struct of_device_id mtkfb_of_ids[] = {
  610. { .compatible = "mediatek,mtkfb", },
  611. {}
  612. };
  613. static struct platform_driver mtkfb_driver = {
  614. .driver = {
  615. .name = MTKFB_DRIVER,
  616. #ifdef CONFIG_PM
  617. .pm = NULL,
  618. #endif
  619. .bus = &platform_bus_type,
  620. .probe = mtkfb_probe,
  621. .remove = mtkfb_remove,
  622. .suspend = NULL,
  623. .resume = NULL,
  624. .shutdown = NULL,
  625. .of_match_table = mtkfb_of_ids,
  626. },
  627. };
  628. /* Register both the driver and the device */
  629. int __init mtkfb_init(void)
  630. {
  631. int r = 0;
  632. DISPCHECK("mtkfb_init init");
  633. if (platform_driver_register(&mtkfb_driver)) {
  634. DISPCHECK("failed to register mtkfb driver\n");
  635. r = -ENODEV;
  636. }
  637. return r;
  638. }
  639. static void __exit mtkfb_cleanup(void)
  640. {
  641. platform_driver_unregister(&mtkfb_driver);
  642. }
  643. module_init(mtkfb_init);
  644. module_exit(mtkfb_cleanup);
  645. MODULE_DESCRIPTION("MEDIATEK framebuffer driver");
  646. MODULE_AUTHOR("Xuecheng Zhang <Xuecheng.Zhang@mediatek.com>");
  647. MODULE_LICENSE("GPL");