diff options
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/da8xx-fb.c | 58 |
1 files changed, 47 insertions, 11 deletions
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 8d737305a43b..6beb88d7b7d7 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c | |||
@@ -243,6 +243,11 @@ static struct fb_videomode known_lcd_panels[] = { | |||
243 | }, | 243 | }, |
244 | }; | 244 | }; |
245 | 245 | ||
246 | static inline bool da8xx_fb_is_raster_enabled(void) | ||
247 | { | ||
248 | return !!(lcdc_read(LCD_RASTER_CTRL_REG) & LCD_RASTER_ENABLE); | ||
249 | } | ||
250 | |||
246 | /* Enable the Raster Engine of the LCD Controller */ | 251 | /* Enable the Raster Engine of the LCD Controller */ |
247 | static inline void lcd_enable_raster(void) | 252 | static inline void lcd_enable_raster(void) |
248 | { | 253 | { |
@@ -665,9 +670,6 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
665 | 670 | ||
666 | static void da8xx_fb_lcd_reset(void) | 671 | static void da8xx_fb_lcd_reset(void) |
667 | { | 672 | { |
668 | /* Disable the Raster if previously Enabled */ | ||
669 | lcd_disable_raster(false); | ||
670 | |||
671 | /* DMA has to be disabled */ | 673 | /* DMA has to be disabled */ |
672 | lcdc_write(0, LCD_DMA_CTRL_REG); | 674 | lcdc_write(0, LCD_DMA_CTRL_REG); |
673 | lcdc_write(0, LCD_RASTER_CTRL_REG); | 675 | lcdc_write(0, LCD_RASTER_CTRL_REG); |
@@ -720,8 +722,6 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg, | |||
720 | u32 bpp; | 722 | u32 bpp; |
721 | int ret = 0; | 723 | int ret = 0; |
722 | 724 | ||
723 | da8xx_fb_lcd_reset(); | ||
724 | |||
725 | da8xx_fb_calc_config_clk_divider(par, panel); | 725 | da8xx_fb_calc_config_clk_divider(par, panel); |
726 | 726 | ||
727 | if (panel->sync & FB_SYNC_CLK_INVERT) | 727 | if (panel->sync & FB_SYNC_CLK_INVERT) |
@@ -1201,9 +1201,50 @@ static int da8xx_pan_display(struct fb_var_screeninfo *var, | |||
1201 | return ret; | 1201 | return ret; |
1202 | } | 1202 | } |
1203 | 1203 | ||
1204 | static int da8xxfb_set_par(struct fb_info *info) | ||
1205 | { | ||
1206 | struct da8xx_fb_par *par = info->par; | ||
1207 | int ret; | ||
1208 | bool raster = da8xx_fb_is_raster_enabled(); | ||
1209 | |||
1210 | if (raster) | ||
1211 | lcd_disable_raster(true); | ||
1212 | |||
1213 | fb_var_to_videomode(&par->mode, &info->var); | ||
1214 | |||
1215 | par->cfg.bpp = info->var.bits_per_pixel; | ||
1216 | |||
1217 | info->fix.visual = (par->cfg.bpp <= 8) ? | ||
1218 | FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; | ||
1219 | info->fix.line_length = (par->mode.xres * par->cfg.bpp) / 8; | ||
1220 | |||
1221 | ret = lcd_init(par, &par->cfg, &par->mode); | ||
1222 | if (ret < 0) { | ||
1223 | dev_err(par->dev, "lcd init failed\n"); | ||
1224 | return ret; | ||
1225 | } | ||
1226 | |||
1227 | par->dma_start = info->fix.smem_start + | ||
1228 | info->var.yoffset * info->fix.line_length + | ||
1229 | info->var.xoffset * info->var.bits_per_pixel / 8; | ||
1230 | par->dma_end = par->dma_start + | ||
1231 | info->var.yres * info->fix.line_length - 1; | ||
1232 | |||
1233 | lcdc_write(par->dma_start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG); | ||
1234 | lcdc_write(par->dma_end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG); | ||
1235 | lcdc_write(par->dma_start, LCD_DMA_FRM_BUF_BASE_ADDR_1_REG); | ||
1236 | lcdc_write(par->dma_end, LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG); | ||
1237 | |||
1238 | if (raster) | ||
1239 | lcd_enable_raster(); | ||
1240 | |||
1241 | return 0; | ||
1242 | } | ||
1243 | |||
1204 | static struct fb_ops da8xx_fb_ops = { | 1244 | static struct fb_ops da8xx_fb_ops = { |
1205 | .owner = THIS_MODULE, | 1245 | .owner = THIS_MODULE, |
1206 | .fb_check_var = fb_check_var, | 1246 | .fb_check_var = fb_check_var, |
1247 | .fb_set_par = da8xxfb_set_par, | ||
1207 | .fb_setcolreg = fb_setcolreg, | 1248 | .fb_setcolreg = fb_setcolreg, |
1208 | .fb_pan_display = da8xx_pan_display, | 1249 | .fb_pan_display = da8xx_pan_display, |
1209 | .fb_ioctl = fb_ioctl, | 1250 | .fb_ioctl = fb_ioctl, |
@@ -1312,14 +1353,9 @@ static int fb_probe(struct platform_device *device) | |||
1312 | } | 1353 | } |
1313 | 1354 | ||
1314 | fb_videomode_to_var(&da8xx_fb_var, lcdc_info); | 1355 | fb_videomode_to_var(&da8xx_fb_var, lcdc_info); |
1315 | fb_var_to_videomode(&par->mode, &da8xx_fb_var); | ||
1316 | par->cfg = *lcd_cfg; | 1356 | par->cfg = *lcd_cfg; |
1317 | 1357 | ||
1318 | if (lcd_init(par, lcd_cfg, lcdc_info) < 0) { | 1358 | da8xx_fb_lcd_reset(); |
1319 | dev_err(&device->dev, "lcd_init failed\n"); | ||
1320 | ret = -EFAULT; | ||
1321 | goto err_release_fb; | ||
1322 | } | ||
1323 | 1359 | ||
1324 | /* allocate frame buffer */ | 1360 | /* allocate frame buffer */ |
1325 | par->vram_size = lcdc_info->xres * lcdc_info->yres * lcd_cfg->bpp; | 1361 | par->vram_size = lcdc_info->xres * lcdc_info->yres * lcd_cfg->bpp; |