aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2010-10-15 03:53:52 -0400
committerPaul Mundt <lethal@linux-sh.org>2010-10-15 06:00:56 -0400
commitc44f9f76d26c3b5158c65201d30e96393efe2fbd (patch)
treeea66fc950cc090085f5242d8a8bcbed3ac2c0cd0 /drivers/video
parent69ce8aa4925a54de192cf64e99abd294586c1984 (diff)
fbdev: sh_mobile_lcdc: make platform videomode table optional
Add a default 720p mode to the sh_mobile_lcdc driver to be used, when no videomode is specified in the platform data. This can be used, e.g., with HDMI. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/sh_mobile_hdmi.c3
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c73
2 files changed, 51 insertions, 25 deletions
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
index 4d6ab86e9518..94a94fde2c67 100644
--- a/drivers/video/sh_mobile_hdmi.c
+++ b/drivers/video/sh_mobile_hdmi.c
@@ -1051,7 +1051,8 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
1051 goto egetclk; 1051 goto egetclk;
1052 } 1052 }
1053 1053
1054 rate = sh_hdmi_clk_configure(hdmi, pdata->lcd_chan->lcd_cfg[0].pixclock); 1054 /* Some arbitrary relaxed pixclock just to get things started */
1055 rate = sh_hdmi_clk_configure(hdmi, 37037);
1055 if (rate < 0) { 1056 if (rate < 0) {
1056 ret = rate; 1057 ret = rate;
1057 goto erate; 1058 goto erate;
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index d6e9ff512443..a777cb99739c 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -54,6 +54,9 @@ static int lcdc_shared_regs[] = {
54}; 54};
55#define NR_SHARED_REGS ARRAY_SIZE(lcdc_shared_regs) 55#define NR_SHARED_REGS ARRAY_SIZE(lcdc_shared_regs)
56 56
57#define DEFAULT_XRES 1280
58#define DEFAULT_YRES 1024
59
57static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = { 60static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = {
58 [LDDCKPAT1R] = 0x400, 61 [LDDCKPAT1R] = 0x400,
59 [LDDCKPAT2R] = 0x404, 62 [LDDCKPAT2R] = 0x404,
@@ -107,6 +110,23 @@ static unsigned long lcdc_offs_sublcd[NR_CH_REGS] = {
107#define LDRCNTR_MRC 0x00000001 110#define LDRCNTR_MRC 0x00000001
108#define LDSR_MRS 0x00000100 111#define LDSR_MRS 0x00000100
109 112
113static const struct fb_videomode default_720p = {
114 .name = "HDMI 720p",
115 .xres = 1280,
116 .yres = 720,
117
118 .left_margin = 200,
119 .right_margin = 88,
120 .hsync_len = 48,
121
122 .upper_margin = 20,
123 .lower_margin = 5,
124 .vsync_len = 5,
125
126 .pixclock = 13468,
127 .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
128};
129
110struct sh_mobile_lcdc_priv { 130struct sh_mobile_lcdc_priv {
111 void __iomem *base; 131 void __iomem *base;
112 int irq; 132 int irq;
@@ -1045,7 +1065,6 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
1045 struct fb_info *info = event->info; 1065 struct fb_info *info = event->info;
1046 struct sh_mobile_lcdc_chan *ch = info->par; 1066 struct sh_mobile_lcdc_chan *ch = info->par;
1047 struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg; 1067 struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
1048 struct fb_var_screeninfo *var;
1049 int ret; 1068 int ret;
1050 1069
1051 if (&ch->lcdc->notifier != nb) 1070 if (&ch->lcdc->notifier != nb)
@@ -1064,8 +1083,6 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
1064 sh_mobile_lcdc_stop(ch->lcdc); 1083 sh_mobile_lcdc_stop(ch->lcdc);
1065 break; 1084 break;
1066 case FB_EVENT_RESUME: 1085 case FB_EVENT_RESUME:
1067 var = &info->var;
1068
1069 mutex_lock(&ch->open_lock); 1086 mutex_lock(&ch->open_lock);
1070 sh_mobile_fb_reconfig(info); 1087 sh_mobile_fb_reconfig(info);
1071 mutex_unlock(&ch->open_lock); 1088 mutex_unlock(&ch->open_lock);
@@ -1091,7 +1108,6 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1091 struct fb_info *info; 1108 struct fb_info *info;
1092 struct sh_mobile_lcdc_priv *priv; 1109 struct sh_mobile_lcdc_priv *priv;
1093 struct sh_mobile_lcdc_info *pdata = pdev->dev.platform_data; 1110 struct sh_mobile_lcdc_info *pdata = pdev->dev.platform_data;
1094 struct sh_mobile_lcdc_chan_cfg *cfg;
1095 struct resource *res; 1111 struct resource *res;
1096 int error; 1112 int error;
1097 void *buf; 1113 void *buf;
@@ -1177,11 +1193,11 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1177 struct fb_var_screeninfo *var; 1193 struct fb_var_screeninfo *var;
1178 const struct fb_videomode *lcd_cfg, *max_cfg = NULL; 1194 const struct fb_videomode *lcd_cfg, *max_cfg = NULL;
1179 struct sh_mobile_lcdc_chan *ch = priv->ch + i; 1195 struct sh_mobile_lcdc_chan *ch = priv->ch + i;
1196 struct sh_mobile_lcdc_chan_cfg *cfg = &ch->cfg;
1197 const struct fb_videomode *mode = cfg->lcd_cfg;
1180 unsigned long max_size = 0; 1198 unsigned long max_size = 0;
1181 int k; 1199 int k;
1182 1200
1183 cfg = &ch->cfg;
1184
1185 ch->info = framebuffer_alloc(0, &pdev->dev); 1201 ch->info = framebuffer_alloc(0, &pdev->dev);
1186 if (!ch->info) { 1202 if (!ch->info) {
1187 dev_err(&pdev->dev, "unable to allocate fb_info\n"); 1203 dev_err(&pdev->dev, "unable to allocate fb_info\n");
@@ -1192,20 +1208,12 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1192 info = ch->info; 1208 info = ch->info;
1193 var = &info->var; 1209 var = &info->var;
1194 info->fbops = &sh_mobile_lcdc_ops; 1210 info->fbops = &sh_mobile_lcdc_ops;
1211 info->par = ch;
1195 1212
1196 mutex_init(&ch->open_lock); 1213 mutex_init(&ch->open_lock);
1197 1214
1198 fb_videomode_to_var(var, &cfg->lcd_cfg[0]); 1215 for (k = 0, lcd_cfg = mode;
1199 /* Default Y virtual resolution is 2x panel size */ 1216 k < cfg->num_cfg && lcd_cfg;
1200 var->yres_virtual = var->yres * 2;
1201 var->activate = FB_ACTIVATE_NOW;
1202
1203 error = sh_mobile_lcdc_set_bpp(var, cfg->bpp);
1204 if (error)
1205 break;
1206
1207 for (k = 0, lcd_cfg = cfg->lcd_cfg;
1208 k < cfg->num_cfg;
1209 k++, lcd_cfg++) { 1217 k++, lcd_cfg++) {
1210 unsigned long size = lcd_cfg->yres * lcd_cfg->xres; 1218 unsigned long size = lcd_cfg->yres * lcd_cfg->xres;
1211 1219
@@ -1215,13 +1223,27 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1215 } 1223 }
1216 } 1224 }
1217 1225
1218 dev_dbg(&pdev->dev, "Found largest videomode %ux%u\n", 1226 if (!mode)
1219 max_cfg->xres, max_cfg->yres); 1227 max_size = DEFAULT_XRES * DEFAULT_YRES;
1228 else if (max_cfg)
1229 dev_dbg(&pdev->dev, "Found largest videomode %ux%u\n",
1230 max_cfg->xres, max_cfg->yres);
1220 1231
1221 info->fix = sh_mobile_lcdc_fix; 1232 info->fix = sh_mobile_lcdc_fix;
1222 info->fix.line_length = cfg->lcd_cfg[0].xres * (cfg->bpp / 8);
1223 info->fix.smem_len = max_size * (cfg->bpp / 8) * 2; 1233 info->fix.smem_len = max_size * (cfg->bpp / 8) * 2;
1224 1234
1235 if (!mode)
1236 mode = &default_720p;
1237
1238 fb_videomode_to_var(var, mode);
1239 /* Default Y virtual resolution is 2x panel size */
1240 var->yres_virtual = var->yres * 2;
1241 var->activate = FB_ACTIVATE_NOW;
1242
1243 error = sh_mobile_lcdc_set_bpp(var, cfg->bpp);
1244 if (error)
1245 break;
1246
1225 buf = dma_alloc_coherent(&pdev->dev, info->fix.smem_len, 1247 buf = dma_alloc_coherent(&pdev->dev, info->fix.smem_len,
1226 &ch->dma_handle, GFP_KERNEL); 1248 &ch->dma_handle, GFP_KERNEL);
1227 if (!buf) { 1249 if (!buf) {
@@ -1242,9 +1264,9 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1242 } 1264 }
1243 1265
1244 info->fix.smem_start = ch->dma_handle; 1266 info->fix.smem_start = ch->dma_handle;
1267 info->fix.line_length = var->xres * (cfg->bpp / 8);
1245 info->screen_base = buf; 1268 info->screen_base = buf;
1246 info->device = &pdev->dev; 1269 info->device = &pdev->dev;
1247 info->par = ch;
1248 ch->display_var = *var; 1270 ch->display_var = *var;
1249 } 1271 }
1250 1272
@@ -1259,6 +1281,10 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1259 1281
1260 for (i = 0; i < j; i++) { 1282 for (i = 0; i < j; i++) {
1261 struct sh_mobile_lcdc_chan *ch = priv->ch + i; 1283 struct sh_mobile_lcdc_chan *ch = priv->ch + i;
1284 const struct fb_videomode *mode = ch->cfg.lcd_cfg;
1285
1286 if (!mode)
1287 mode = &default_720p;
1262 1288
1263 info = ch->info; 1289 info = ch->info;
1264 1290
@@ -1271,7 +1297,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1271 } 1297 }
1272 } 1298 }
1273 1299
1274 fb_videomode_to_modelist(ch->cfg.lcd_cfg, ch->cfg.num_cfg, &info->modelist); 1300 fb_videomode_to_modelist(mode, ch->cfg.num_cfg, &info->modelist);
1275 error = register_framebuffer(info); 1301 error = register_framebuffer(info);
1276 if (error < 0) 1302 if (error < 0)
1277 goto err1; 1303 goto err1;
@@ -1281,8 +1307,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1281 pdev->name, 1307 pdev->name,
1282 (ch->cfg.chan == LCDC_CHAN_MAINLCD) ? 1308 (ch->cfg.chan == LCDC_CHAN_MAINLCD) ?
1283 "mainlcd" : "sublcd", 1309 "mainlcd" : "sublcd",
1284 (int) ch->cfg.lcd_cfg[0].xres, 1310 info->var.xres, info->var.yres,
1285 (int) ch->cfg.lcd_cfg[0].yres,
1286 ch->cfg.bpp); 1311 ch->cfg.bpp);
1287 1312
1288 /* deferred io mode: disable clock to save power */ 1313 /* deferred io mode: disable clock to save power */