diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2010-10-15 03:53:52 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-10-15 06:00:56 -0400 |
commit | c44f9f76d26c3b5158c65201d30e96393efe2fbd (patch) | |
tree | ea66fc950cc090085f5242d8a8bcbed3ac2c0cd0 /drivers/video | |
parent | 69ce8aa4925a54de192cf64e99abd294586c1984 (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.c | 3 | ||||
-rw-r--r-- | drivers/video/sh_mobile_lcdcfb.c | 73 |
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 | |||
57 | static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = { | 60 | static 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 | ||
113 | static 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 | |||
110 | struct sh_mobile_lcdc_priv { | 130 | struct 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 */ |