aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/da8xx-fb.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-22 23:43:40 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-22 23:43:40 -0400
commit437538267b672f9320833907f1b5acbb2605f4be (patch)
treed10173b35a5b86bc037bb2ece1b406d5575a2094 /drivers/video/da8xx-fb.c
parent9586c959bfc917695893bef0102433a7d0675691 (diff)
parent6bff98b455cf3e666fd0e3d0d908eba874de0eee (diff)
Merge tag 'fbdev-updates-for-3.4' of git://github.com/schandinat/linux-2.6
Pull fbdev updates for 3.4 from Florian Tobias Schandinat: - drivers for Samsung Exynos MIPI DSI and display port - i740fb to support those old Intel chips - large updates to OMAP, viafb and sh_mobile_lcdcfb - some updates to s3c-fb and udlfb, few patches to others Fix up conflicts in drivers/video/udlfb.c due to Key Sievers' fix making it in twice. * tag 'fbdev-updates-for-3.4' of git://github.com/schandinat/linux-2.6: (156 commits) Revert "video:uvesafb: Fix oops that uvesafb try to execute NX-protected page" OMAPDSS: register dss drivers in module init video: pxafb: add clk_prepare/clk_unprepare calls fbdev: bfin_adv7393fb: Drop needless include fbdev: sh_mipi_dsi: add extra phyctrl for sh_mipi_dsi_info fbdev: remove dependency of FB_SH_MOBILE_MERAM from FB_SH_MOBILE_LCDC Revert "MAINTAINERS: add entry for exynos mipi display drivers" fbdev: da8xx: add support for SP10Q010 display fbdev: da8xx:: fix reporting of the display timing info drivers/video/pvr2fb.c: ensure arguments to request_irq and free_irq are compatible OMAPDSS: APPLY: fix clearing shadow dirty flag with manual update fbdev: sh_mobile_meram: Implement system suspend/resume fbdev: sh_mobile_meram: Remove unneeded sanity checks fbdev: sh_mobile_meram: Don't perform update in register operation arm: mach-shmobile: Constify sh_mobile_meram_cfg structures fbdev: sh_mobile_lcdc: Don't store copy of platform data fbdev: sh_mobile_meram: Remove unused sh_mobile_meram_icb_cfg fields arm: mach-shmobile: Don't set MERAM ICB numbers in platform data fbdev: sh_mobile_meram: Allocate ICBs automatically fbdev: sh_mobile_meram: Use genalloc to manage MERAM allocation ...
Diffstat (limited to 'drivers/video/da8xx-fb.c')
-rw-r--r--drivers/video/da8xx-fb.c79
1 files changed, 71 insertions, 8 deletions
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 29577bf1f559..47118c75a4c0 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -32,6 +32,7 @@
32#include <linux/console.h> 32#include <linux/console.h>
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <video/da8xx-fb.h> 34#include <video/da8xx-fb.h>
35#include <asm/div64.h>
35 36
36#define DRIVER_NAME "da8xx_lcdc" 37#define DRIVER_NAME "da8xx_lcdc"
37 38
@@ -161,6 +162,7 @@ struct da8xx_fb_par {
161 int vsync_timeout; 162 int vsync_timeout;
162#ifdef CONFIG_CPU_FREQ 163#ifdef CONFIG_CPU_FREQ
163 struct notifier_block freq_transition; 164 struct notifier_block freq_transition;
165 unsigned int lcd_fck_rate;
164#endif 166#endif
165 void (*panel_power_ctrl)(int); 167 void (*panel_power_ctrl)(int);
166}; 168};
@@ -174,7 +176,6 @@ static struct fb_var_screeninfo da8xx_fb_var __devinitdata = {
174 .activate = 0, 176 .activate = 0,
175 .height = -1, 177 .height = -1,
176 .width = -1, 178 .width = -1,
177 .pixclock = 46666, /* 46us - AUO display */
178 .accel_flags = 0, 179 .accel_flags = 0,
179 .left_margin = LEFT_MARGIN, 180 .left_margin = LEFT_MARGIN,
180 .right_margin = RIGHT_MARGIN, 181 .right_margin = RIGHT_MARGIN,
@@ -238,6 +239,20 @@ static struct da8xx_panel known_lcd_panels[] = {
238 .pxl_clk = 7833600, 239 .pxl_clk = 7833600,
239 .invert_pxl_clk = 0, 240 .invert_pxl_clk = 0,
240 }, 241 },
242 [2] = {
243 /* Hitachi SP10Q010 */
244 .name = "SP10Q010",
245 .width = 320,
246 .height = 240,
247 .hfp = 10,
248 .hbp = 10,
249 .hsw = 10,
250 .vfp = 10,
251 .vbp = 10,
252 .vsw = 10,
253 .pxl_clk = 7833600,
254 .invert_pxl_clk = 0,
255 },
241}; 256};
242 257
243/* Enable the Raster Engine of the LCD Controller */ 258/* Enable the Raster Engine of the LCD Controller */
@@ -546,7 +561,26 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
546 if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) 561 if (info->fix.visual == FB_VISUAL_DIRECTCOLOR)
547 return 1; 562 return 1;
548 563
549 if (info->var.bits_per_pixel == 8) { 564 if (info->var.bits_per_pixel == 4) {
565 if (regno > 15)
566 return 1;
567
568 if (info->var.grayscale) {
569 pal = regno;
570 } else {
571 red >>= 4;
572 green >>= 8;
573 blue >>= 12;
574
575 pal = (red & 0x0f00);
576 pal |= (green & 0x00f0);
577 pal |= (blue & 0x000f);
578 }
579 if (regno == 0)
580 pal |= 0x2000;
581 palette[regno] = pal;
582
583 } else if (info->var.bits_per_pixel == 8) {
550 red >>= 4; 584 red >>= 4;
551 green >>= 8; 585 green >>= 8;
552 blue >>= 12; 586 blue >>= 12;
@@ -801,6 +835,7 @@ static int fb_check_var(struct fb_var_screeninfo *var,
801 var->blue.length = 8; 835 var->blue.length = 8;
802 var->transp.offset = 0; 836 var->transp.offset = 0;
803 var->transp.length = 0; 837 var->transp.length = 0;
838 var->nonstd = 0;
804 break; 839 break;
805 case 4: 840 case 4:
806 var->red.offset = 0; 841 var->red.offset = 0;
@@ -811,6 +846,7 @@ static int fb_check_var(struct fb_var_screeninfo *var,
811 var->blue.length = 4; 846 var->blue.length = 4;
812 var->transp.offset = 0; 847 var->transp.offset = 0;
813 var->transp.length = 0; 848 var->transp.length = 0;
849 var->nonstd = FB_NONSTD_REV_PIX_IN_B;
814 break; 850 break;
815 case 16: /* RGB 565 */ 851 case 16: /* RGB 565 */
816 var->red.offset = 11; 852 var->red.offset = 11;
@@ -821,6 +857,7 @@ static int fb_check_var(struct fb_var_screeninfo *var,
821 var->blue.length = 5; 857 var->blue.length = 5;
822 var->transp.offset = 0; 858 var->transp.offset = 0;
823 var->transp.length = 0; 859 var->transp.length = 0;
860 var->nonstd = 0;
824 break; 861 break;
825 default: 862 default:
826 err = -EINVAL; 863 err = -EINVAL;
@@ -840,11 +877,13 @@ static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb,
840 struct da8xx_fb_par *par; 877 struct da8xx_fb_par *par;
841 878
842 par = container_of(nb, struct da8xx_fb_par, freq_transition); 879 par = container_of(nb, struct da8xx_fb_par, freq_transition);
843 if (val == CPUFREQ_PRECHANGE) { 880 if (val == CPUFREQ_POSTCHANGE) {
844 lcd_disable_raster(); 881 if (par->lcd_fck_rate != clk_get_rate(par->lcdc_clk)) {
845 } else if (val == CPUFREQ_POSTCHANGE) { 882 par->lcd_fck_rate = clk_get_rate(par->lcdc_clk);
846 lcd_calc_clk_divider(par); 883 lcd_disable_raster();
847 lcd_enable_raster(); 884 lcd_calc_clk_divider(par);
885 lcd_enable_raster();
886 }
848 } 887 }
849 888
850 return 0; 889 return 0;
@@ -1048,6 +1087,22 @@ static struct fb_ops da8xx_fb_ops = {
1048 .fb_blank = cfb_blank, 1087 .fb_blank = cfb_blank,
1049}; 1088};
1050 1089
1090/* Calculate and return pixel clock period in pico seconds */
1091static unsigned int da8xxfb_pixel_clk_period(struct da8xx_fb_par *par)
1092{
1093 unsigned int lcd_clk, div;
1094 unsigned int configured_pix_clk;
1095 unsigned long long pix_clk_period_picosec = 1000000000000ULL;
1096
1097 lcd_clk = clk_get_rate(par->lcdc_clk);
1098 div = lcd_clk / par->pxl_clk;
1099 configured_pix_clk = (lcd_clk / div);
1100
1101 do_div(pix_clk_period_picosec, configured_pix_clk);
1102
1103 return pix_clk_period_picosec;
1104}
1105
1051static int __devinit fb_probe(struct platform_device *device) 1106static int __devinit fb_probe(struct platform_device *device)
1052{ 1107{
1053 struct da8xx_lcdc_platform_data *fb_pdata = 1108 struct da8xx_lcdc_platform_data *fb_pdata =
@@ -1137,6 +1192,9 @@ static int __devinit fb_probe(struct platform_device *device)
1137 1192
1138 par = da8xx_fb_info->par; 1193 par = da8xx_fb_info->par;
1139 par->lcdc_clk = fb_clk; 1194 par->lcdc_clk = fb_clk;
1195#ifdef CONFIG_CPU_FREQ
1196 par->lcd_fck_rate = clk_get_rate(fb_clk);
1197#endif
1140 par->pxl_clk = lcdc_info->pxl_clk; 1198 par->pxl_clk = lcdc_info->pxl_clk;
1141 if (fb_pdata->panel_power_ctrl) { 1199 if (fb_pdata->panel_power_ctrl) {
1142 par->panel_power_ctrl = fb_pdata->panel_power_ctrl; 1200 par->panel_power_ctrl = fb_pdata->panel_power_ctrl;
@@ -1209,6 +1267,11 @@ static int __devinit fb_probe(struct platform_device *device)
1209 1267
1210 da8xx_fb_var.hsync_len = lcdc_info->hsw; 1268 da8xx_fb_var.hsync_len = lcdc_info->hsw;
1211 da8xx_fb_var.vsync_len = lcdc_info->vsw; 1269 da8xx_fb_var.vsync_len = lcdc_info->vsw;
1270 da8xx_fb_var.right_margin = lcdc_info->hfp;
1271 da8xx_fb_var.left_margin = lcdc_info->hbp;
1272 da8xx_fb_var.lower_margin = lcdc_info->vfp;
1273 da8xx_fb_var.upper_margin = lcdc_info->vbp;
1274 da8xx_fb_var.pixclock = da8xxfb_pixel_clk_period(par);
1212 1275
1213 /* Initialize fbinfo */ 1276 /* Initialize fbinfo */
1214 da8xx_fb_info->flags = FBINFO_FLAG_DEFAULT; 1277 da8xx_fb_info->flags = FBINFO_FLAG_DEFAULT;
@@ -1264,8 +1327,8 @@ static int __devinit fb_probe(struct platform_device *device)
1264irq_freq: 1327irq_freq:
1265#ifdef CONFIG_CPU_FREQ 1328#ifdef CONFIG_CPU_FREQ
1266 lcd_da8xx_cpufreq_deregister(par); 1329 lcd_da8xx_cpufreq_deregister(par);
1267#endif
1268err_cpu_freq: 1330err_cpu_freq:
1331#endif
1269 unregister_framebuffer(da8xx_fb_info); 1332 unregister_framebuffer(da8xx_fb_info);
1270 1333
1271err_dealloc_cmap: 1334err_dealloc_cmap: