aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/omapfb/omapfb-main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2/omapfb/omapfb-main.c')
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c231
1 files changed, 131 insertions, 100 deletions
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 505ec6672049..505bc12a3031 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -30,7 +30,7 @@
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <linux/omapfb.h> 31#include <linux/omapfb.h>
32 32
33#include <plat/display.h> 33#include <video/omapdss.h>
34#include <plat/vram.h> 34#include <plat/vram.h>
35#include <plat/vrfb.h> 35#include <plat/vrfb.h>
36 36
@@ -702,8 +702,16 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
702 var->xres, var->yres, 702 var->xres, var->yres,
703 var->xres_virtual, var->yres_virtual); 703 var->xres_virtual, var->yres_virtual);
704 704
705 var->height = -1; 705 if (display && display->driver->get_dimensions) {
706 var->width = -1; 706 u32 w, h;
707 display->driver->get_dimensions(display, &w, &h);
708 var->width = DIV_ROUND_CLOSEST(w, 1000);
709 var->height = DIV_ROUND_CLOSEST(h, 1000);
710 } else {
711 var->height = -1;
712 var->width = -1;
713 }
714
707 var->grayscale = 0; 715 var->grayscale = 0;
708 716
709 if (display && display->driver->get_timings) { 717 if (display && display->driver->get_timings) {
@@ -749,35 +757,6 @@ static int omapfb_open(struct fb_info *fbi, int user)
749 757
750static int omapfb_release(struct fb_info *fbi, int user) 758static int omapfb_release(struct fb_info *fbi, int user)
751{ 759{
752#if 0
753 struct omapfb_info *ofbi = FB2OFB(fbi);
754 struct omapfb2_device *fbdev = ofbi->fbdev;
755 struct omap_dss_device *display = fb2display(fbi);
756
757 DBG("Closing fb with plane index %d\n", ofbi->id);
758
759 omapfb_lock(fbdev);
760
761 if (display && display->get_update_mode && display->update) {
762 /* XXX this update should be removed, I think. But it's
763 * good for debugging */
764 if (display->get_update_mode(display) ==
765 OMAP_DSS_UPDATE_MANUAL) {
766 u16 w, h;
767
768 if (display->sync)
769 display->sync(display);
770
771 display->get_resolution(display, &w, &h);
772 display->update(display, 0, 0, w, h);
773 }
774 }
775
776 if (display && display->sync)
777 display->sync(display);
778
779 omapfb_unlock(fbdev);
780#endif
781 return 0; 760 return 0;
782} 761}
783 762
@@ -1263,7 +1242,6 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
1263 struct omapfb_info *ofbi = FB2OFB(fbi); 1242 struct omapfb_info *ofbi = FB2OFB(fbi);
1264 struct omapfb2_device *fbdev = ofbi->fbdev; 1243 struct omapfb2_device *fbdev = ofbi->fbdev;
1265 struct omap_dss_device *display = fb2display(fbi); 1244 struct omap_dss_device *display = fb2display(fbi);
1266 int do_update = 0;
1267 int r = 0; 1245 int r = 0;
1268 1246
1269 if (!display) 1247 if (!display)
@@ -1279,11 +1257,6 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
1279 if (display->driver->resume) 1257 if (display->driver->resume)
1280 r = display->driver->resume(display); 1258 r = display->driver->resume(display);
1281 1259
1282 if (r == 0 && display->driver->get_update_mode &&
1283 display->driver->get_update_mode(display) ==
1284 OMAP_DSS_UPDATE_MANUAL)
1285 do_update = 1;
1286
1287 break; 1260 break;
1288 1261
1289 case FB_BLANK_NORMAL: 1262 case FB_BLANK_NORMAL:
@@ -1307,13 +1280,6 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
1307exit: 1280exit:
1308 omapfb_unlock(fbdev); 1281 omapfb_unlock(fbdev);
1309 1282
1310 if (r == 0 && do_update && display->driver->update) {
1311 u16 w, h;
1312 display->driver->get_resolution(display, &w, &h);
1313
1314 r = display->driver->update(display, 0, 0, w, h);
1315 }
1316
1317 return r; 1283 return r;
1318} 1284}
1319 1285
@@ -2030,9 +1996,9 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
2030static int omapfb_mode_to_timings(const char *mode_str, 1996static int omapfb_mode_to_timings(const char *mode_str,
2031 struct omap_video_timings *timings, u8 *bpp) 1997 struct omap_video_timings *timings, u8 *bpp)
2032{ 1998{
2033 struct fb_info fbi; 1999 struct fb_info *fbi;
2034 struct fb_var_screeninfo var; 2000 struct fb_var_screeninfo *var;
2035 struct fb_ops fbops; 2001 struct fb_ops *fbops;
2036 int r; 2002 int r;
2037 2003
2038#ifdef CONFIG_OMAP2_DSS_VENC 2004#ifdef CONFIG_OMAP2_DSS_VENC
@@ -2050,39 +2016,66 @@ static int omapfb_mode_to_timings(const char *mode_str,
2050 /* this is quite a hack, but I wanted to use the modedb and for 2016 /* this is quite a hack, but I wanted to use the modedb and for
2051 * that we need fb_info and var, so we create dummy ones */ 2017 * that we need fb_info and var, so we create dummy ones */
2052 2018
2053 memset(&fbi, 0, sizeof(fbi)); 2019 *bpp = 0;
2054 memset(&var, 0, sizeof(var)); 2020 fbi = NULL;
2055 memset(&fbops, 0, sizeof(fbops)); 2021 var = NULL;
2056 fbi.fbops = &fbops; 2022 fbops = NULL;
2057
2058 r = fb_find_mode(&var, &fbi, mode_str, NULL, 0, NULL, 24);
2059
2060 if (r != 0) {
2061 timings->pixel_clock = PICOS2KHZ(var.pixclock);
2062 timings->hbp = var.left_margin;
2063 timings->hfp = var.right_margin;
2064 timings->vbp = var.upper_margin;
2065 timings->vfp = var.lower_margin;
2066 timings->hsw = var.hsync_len;
2067 timings->vsw = var.vsync_len;
2068 timings->x_res = var.xres;
2069 timings->y_res = var.yres;
2070
2071 switch (var.bits_per_pixel) {
2072 case 16:
2073 *bpp = 16;
2074 break;
2075 case 24:
2076 case 32:
2077 default:
2078 *bpp = 24;
2079 break;
2080 }
2081 2023
2082 return 0; 2024 fbi = kzalloc(sizeof(*fbi), GFP_KERNEL);
2083 } else { 2025 if (fbi == NULL) {
2084 return -EINVAL; 2026 r = -ENOMEM;
2027 goto err;
2028 }
2029
2030 var = kzalloc(sizeof(*var), GFP_KERNEL);
2031 if (var == NULL) {
2032 r = -ENOMEM;
2033 goto err;
2034 }
2035
2036 fbops = kzalloc(sizeof(*fbops), GFP_KERNEL);
2037 if (fbops == NULL) {
2038 r = -ENOMEM;
2039 goto err;
2040 }
2041
2042 fbi->fbops = fbops;
2043
2044 r = fb_find_mode(var, fbi, mode_str, NULL, 0, NULL, 24);
2045 if (r == 0) {
2046 r = -EINVAL;
2047 goto err;
2048 }
2049
2050 timings->pixel_clock = PICOS2KHZ(var->pixclock);
2051 timings->hbp = var->left_margin;
2052 timings->hfp = var->right_margin;
2053 timings->vbp = var->upper_margin;
2054 timings->vfp = var->lower_margin;
2055 timings->hsw = var->hsync_len;
2056 timings->vsw = var->vsync_len;
2057 timings->x_res = var->xres;
2058 timings->y_res = var->yres;
2059
2060 switch (var->bits_per_pixel) {
2061 case 16:
2062 *bpp = 16;
2063 break;
2064 case 24:
2065 case 32:
2066 default:
2067 *bpp = 24;
2068 break;
2085 } 2069 }
2070
2071 r = 0;
2072
2073err:
2074 kfree(fbi);
2075 kfree(var);
2076 kfree(fbops);
2077
2078 return r;
2086} 2079}
2087 2080
2088static int omapfb_set_def_mode(struct omapfb2_device *fbdev, 2081static int omapfb_set_def_mode(struct omapfb2_device *fbdev,
@@ -2185,6 +2178,61 @@ static int omapfb_parse_def_modes(struct omapfb2_device *fbdev)
2185 return r; 2178 return r;
2186} 2179}
2187 2180
2181static int omapfb_init_display(struct omapfb2_device *fbdev,
2182 struct omap_dss_device *dssdev)
2183{
2184 struct omap_dss_driver *dssdrv = dssdev->driver;
2185 int r;
2186
2187 r = dssdrv->enable(dssdev);
2188 if (r) {
2189 dev_warn(fbdev->dev, "Failed to enable display '%s'\n",
2190 dssdev->name);
2191 return r;
2192 }
2193
2194 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
2195 u16 w, h;
2196 if (dssdrv->enable_te) {
2197 r = dssdrv->enable_te(dssdev, 1);
2198 if (r) {
2199 dev_err(fbdev->dev, "Failed to set TE\n");
2200 return r;
2201 }
2202 }
2203
2204 if (dssdrv->set_update_mode) {
2205 r = dssdrv->set_update_mode(dssdev,
2206 OMAP_DSS_UPDATE_MANUAL);
2207 if (r) {
2208 dev_err(fbdev->dev,
2209 "Failed to set update mode\n");
2210 return r;
2211 }
2212 }
2213
2214 dssdrv->get_resolution(dssdev, &w, &h);
2215 r = dssdrv->update(dssdev, 0, 0, w, h);
2216 if (r) {
2217 dev_err(fbdev->dev,
2218 "Failed to update display\n");
2219 return r;
2220 }
2221 } else {
2222 if (dssdrv->set_update_mode) {
2223 r = dssdrv->set_update_mode(dssdev,
2224 OMAP_DSS_UPDATE_AUTO);
2225 if (r) {
2226 dev_err(fbdev->dev,
2227 "Failed to set update mode\n");
2228 return r;
2229 }
2230 }
2231 }
2232
2233 return 0;
2234}
2235
2188static int omapfb_probe(struct platform_device *pdev) 2236static int omapfb_probe(struct platform_device *pdev)
2189{ 2237{
2190 struct omapfb2_device *fbdev = NULL; 2238 struct omapfb2_device *fbdev = NULL;
@@ -2284,30 +2332,13 @@ static int omapfb_probe(struct platform_device *pdev)
2284 } 2332 }
2285 2333
2286 if (def_display) { 2334 if (def_display) {
2287 struct omap_dss_driver *dssdrv = def_display->driver; 2335 r = omapfb_init_display(fbdev, def_display);
2288
2289 r = def_display->driver->enable(def_display);
2290 if (r) { 2336 if (r) {
2291 dev_warn(fbdev->dev, "Failed to enable display '%s'\n", 2337 dev_err(fbdev->dev,
2292 def_display->name); 2338 "failed to initialize default "
2339 "display\n");
2293 goto cleanup; 2340 goto cleanup;
2294 } 2341 }
2295
2296 if (def_display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
2297 u16 w, h;
2298 if (dssdrv->enable_te)
2299 dssdrv->enable_te(def_display, 1);
2300 if (dssdrv->set_update_mode)
2301 dssdrv->set_update_mode(def_display,
2302 OMAP_DSS_UPDATE_MANUAL);
2303
2304 dssdrv->get_resolution(def_display, &w, &h);
2305 def_display->driver->update(def_display, 0, 0, w, h);
2306 } else {
2307 if (dssdrv->set_update_mode)
2308 dssdrv->set_update_mode(def_display,
2309 OMAP_DSS_UPDATE_AUTO);
2310 }
2311 } 2342 }
2312 2343
2313 DBG("create sysfs for fbs\n"); 2344 DBG("create sysfs for fbs\n");