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.c133
1 files changed, 76 insertions, 57 deletions
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index d17caef6915a..4a76917b7cc8 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -54,6 +54,8 @@ module_param_named(test, omapfb_test_pattern, bool, 0644);
54#endif 54#endif
55 55
56static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi); 56static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi);
57static int omapfb_get_recommended_bpp(struct omapfb2_device *fbdev,
58 struct omap_dss_device *dssdev);
57 59
58#ifdef DEBUG 60#ifdef DEBUG
59static void draw_pixel(struct fb_info *fbi, int x, int y, unsigned color) 61static void draw_pixel(struct fb_info *fbi, int x, int y, unsigned color)
@@ -152,9 +154,9 @@ static void fill_fb(struct fb_info *fbi)
152} 154}
153#endif 155#endif
154 156
155static unsigned omapfb_get_vrfb_offset(struct omapfb_info *ofbi, int rot) 157static unsigned omapfb_get_vrfb_offset(const struct omapfb_info *ofbi, int rot)
156{ 158{
157 struct vrfb *vrfb = &ofbi->region.vrfb; 159 const struct vrfb *vrfb = &ofbi->region.vrfb;
158 unsigned offset; 160 unsigned offset;
159 161
160 switch (rot) { 162 switch (rot) {
@@ -179,7 +181,7 @@ static unsigned omapfb_get_vrfb_offset(struct omapfb_info *ofbi, int rot)
179 return offset; 181 return offset;
180} 182}
181 183
182static u32 omapfb_get_region_rot_paddr(struct omapfb_info *ofbi, int rot) 184static u32 omapfb_get_region_rot_paddr(const struct omapfb_info *ofbi, int rot)
183{ 185{
184 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { 186 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
185 return ofbi->region.vrfb.paddr[rot] 187 return ofbi->region.vrfb.paddr[rot]
@@ -189,7 +191,7 @@ static u32 omapfb_get_region_rot_paddr(struct omapfb_info *ofbi, int rot)
189 } 191 }
190} 192}
191 193
192static u32 omapfb_get_region_paddr(struct omapfb_info *ofbi) 194static u32 omapfb_get_region_paddr(const struct omapfb_info *ofbi)
193{ 195{
194 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) 196 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
195 return ofbi->region.vrfb.paddr[0]; 197 return ofbi->region.vrfb.paddr[0];
@@ -197,7 +199,7 @@ static u32 omapfb_get_region_paddr(struct omapfb_info *ofbi)
197 return ofbi->region.paddr; 199 return ofbi->region.paddr;
198} 200}
199 201
200static void __iomem *omapfb_get_region_vaddr(struct omapfb_info *ofbi) 202static void __iomem *omapfb_get_region_vaddr(const struct omapfb_info *ofbi)
201{ 203{
202 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) 204 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
203 return ofbi->region.vrfb.vaddr[0]; 205 return ofbi->region.vrfb.vaddr[0];
@@ -703,9 +705,9 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
703 var->width = -1; 705 var->width = -1;
704 var->grayscale = 0; 706 var->grayscale = 0;
705 707
706 if (display && display->get_timings) { 708 if (display && display->driver->get_timings) {
707 struct omap_video_timings timings; 709 struct omap_video_timings timings;
708 display->get_timings(display, &timings); 710 display->driver->get_timings(display, &timings);
709 711
710 /* pixclock in ps, the rest in pixclock */ 712 /* pixclock in ps, the rest in pixclock */
711 var->pixclock = timings.pixel_clock != 0 ? 713 var->pixclock = timings.pixel_clock != 0 ?
@@ -778,8 +780,8 @@ static int omapfb_release(struct fb_info *fbi, int user)
778 return 0; 780 return 0;
779} 781}
780 782
781static unsigned calc_rotation_offset_dma(struct fb_var_screeninfo *var, 783static unsigned calc_rotation_offset_dma(const struct fb_var_screeninfo *var,
782 struct fb_fix_screeninfo *fix, int rotation) 784 const struct fb_fix_screeninfo *fix, int rotation)
783{ 785{
784 unsigned offset; 786 unsigned offset;
785 787
@@ -789,8 +791,8 @@ static unsigned calc_rotation_offset_dma(struct fb_var_screeninfo *var,
789 return offset; 791 return offset;
790} 792}
791 793
792static unsigned calc_rotation_offset_vrfb(struct fb_var_screeninfo *var, 794static unsigned calc_rotation_offset_vrfb(const struct fb_var_screeninfo *var,
793 struct fb_fix_screeninfo *fix, int rotation) 795 const struct fb_fix_screeninfo *fix, int rotation)
794{ 796{
795 unsigned offset; 797 unsigned offset;
796 798
@@ -1221,11 +1223,11 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
1221 if (display->state != OMAP_DSS_DISPLAY_SUSPENDED) 1223 if (display->state != OMAP_DSS_DISPLAY_SUSPENDED)
1222 goto exit; 1224 goto exit;
1223 1225
1224 if (display->resume) 1226 if (display->driver->resume)
1225 r = display->resume(display); 1227 r = display->driver->resume(display);
1226 1228
1227 if (r == 0 && display->get_update_mode && 1229 if (r == 0 && display->driver->get_update_mode &&
1228 display->get_update_mode(display) == 1230 display->driver->get_update_mode(display) ==
1229 OMAP_DSS_UPDATE_MANUAL) 1231 OMAP_DSS_UPDATE_MANUAL)
1230 do_update = 1; 1232 do_update = 1;
1231 1233
@@ -1240,8 +1242,8 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
1240 if (display->state != OMAP_DSS_DISPLAY_ACTIVE) 1242 if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
1241 goto exit; 1243 goto exit;
1242 1244
1243 if (display->suspend) 1245 if (display->driver->suspend)
1244 r = display->suspend(display); 1246 r = display->driver->suspend(display);
1245 1247
1246 break; 1248 break;
1247 1249
@@ -1252,11 +1254,11 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
1252exit: 1254exit:
1253 omapfb_unlock(fbdev); 1255 omapfb_unlock(fbdev);
1254 1256
1255 if (r == 0 && do_update && display->update) { 1257 if (r == 0 && do_update && display->driver->update) {
1256 u16 w, h; 1258 u16 w, h;
1257 display->get_resolution(display, &w, &h); 1259 display->driver->get_resolution(display, &w, &h);
1258 1260
1259 r = display->update(display, 0, 0, w, h); 1261 r = display->driver->update(display, 0, 0, w, h);
1260 } 1262 }
1261 1263
1262 return r; 1264 return r;
@@ -1404,6 +1406,7 @@ static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size,
1404 unsigned long paddr) 1406 unsigned long paddr)
1405{ 1407{
1406 struct omapfb_info *ofbi = FB2OFB(fbi); 1408 struct omapfb_info *ofbi = FB2OFB(fbi);
1409 struct omapfb2_device *fbdev = ofbi->fbdev;
1407 struct omap_dss_device *display; 1410 struct omap_dss_device *display;
1408 int bytespp; 1411 int bytespp;
1409 1412
@@ -1412,7 +1415,7 @@ static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size,
1412 if (!display) 1415 if (!display)
1413 return 0; 1416 return 0;
1414 1417
1415 switch (display->get_recommended_bpp(display)) { 1418 switch (omapfb_get_recommended_bpp(fbdev, display)) {
1416 case 16: 1419 case 16:
1417 bytespp = 2; 1420 bytespp = 2;
1418 break; 1421 break;
@@ -1427,7 +1430,7 @@ static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size,
1427 if (!size) { 1430 if (!size) {
1428 u16 w, h; 1431 u16 w, h;
1429 1432
1430 display->get_resolution(display, &w, &h); 1433 display->driver->get_resolution(display, &w, &h);
1431 1434
1432 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { 1435 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
1433 size = max(omap_vrfb_min_phys_size(w, h, bytespp), 1436 size = max(omap_vrfb_min_phys_size(w, h, bytespp),
@@ -1636,8 +1639,8 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
1636 if (old_size == size && old_type == type) 1639 if (old_size == size && old_type == type)
1637 return 0; 1640 return 0;
1638 1641
1639 if (display && display->sync) 1642 if (display && display->driver->sync)
1640 display->sync(display); 1643 display->driver->sync(display);
1641 1644
1642 omapfb_free_fbmem(fbi); 1645 omapfb_free_fbmem(fbi);
1643 1646
@@ -1745,7 +1748,7 @@ static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
1745 u16 w, h; 1748 u16 w, h;
1746 int rotation = (var->rotate + ofbi->rotation[0]) % 4; 1749 int rotation = (var->rotate + ofbi->rotation[0]) % 4;
1747 1750
1748 display->get_resolution(display, &w, &h); 1751 display->driver->get_resolution(display, &w, &h);
1749 1752
1750 if (rotation == FB_ROTATE_CW || 1753 if (rotation == FB_ROTATE_CW ||
1751 rotation == FB_ROTATE_CCW) { 1754 rotation == FB_ROTATE_CCW) {
@@ -1760,7 +1763,7 @@ static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
1760 var->yres_virtual = var->yres; 1763 var->yres_virtual = var->yres;
1761 1764
1762 if (!var->bits_per_pixel) { 1765 if (!var->bits_per_pixel) {
1763 switch (display->get_recommended_bpp(display)) { 1766 switch (omapfb_get_recommended_bpp(fbdev, display)) {
1764 case 16: 1767 case 16:
1765 var->bits_per_pixel = 16; 1768 var->bits_per_pixel = 16;
1766 break; 1769 break;
@@ -1828,7 +1831,7 @@ static void omapfb_free_resources(struct omapfb2_device *fbdev)
1828 1831
1829 for (i = 0; i < fbdev->num_displays; i++) { 1832 for (i = 0; i < fbdev->num_displays; i++) {
1830 if (fbdev->displays[i]->state != OMAP_DSS_DISPLAY_DISABLED) 1833 if (fbdev->displays[i]->state != OMAP_DSS_DISPLAY_DISABLED)
1831 fbdev->displays[i]->disable(fbdev->displays[i]); 1834 fbdev->displays[i]->driver->disable(fbdev->displays[i]);
1832 1835
1833 omap_dss_put_device(fbdev->displays[i]); 1836 omap_dss_put_device(fbdev->displays[i]);
1834 } 1837 }
@@ -2011,7 +2014,8 @@ static int omapfb_mode_to_timings(const char *mode_str,
2011 } 2014 }
2012} 2015}
2013 2016
2014static int omapfb_set_def_mode(struct omap_dss_device *display, char *mode_str) 2017static int omapfb_set_def_mode(struct omapfb2_device *fbdev,
2018 struct omap_dss_device *display, char *mode_str)
2015{ 2019{
2016 int r; 2020 int r;
2017 u8 bpp; 2021 u8 bpp;
@@ -2021,20 +2025,37 @@ static int omapfb_set_def_mode(struct omap_dss_device *display, char *mode_str)
2021 if (r) 2025 if (r)
2022 return r; 2026 return r;
2023 2027
2024 display->panel.recommended_bpp = bpp; 2028 fbdev->bpp_overrides[fbdev->num_bpp_overrides].dssdev = display;
2029 fbdev->bpp_overrides[fbdev->num_bpp_overrides].bpp = bpp;
2030 ++fbdev->num_bpp_overrides;
2025 2031
2026 if (!display->check_timings || !display->set_timings) 2032 if (!display->driver->check_timings || !display->driver->set_timings)
2027 return -EINVAL; 2033 return -EINVAL;
2028 2034
2029 r = display->check_timings(display, &timings); 2035 r = display->driver->check_timings(display, &timings);
2030 if (r) 2036 if (r)
2031 return r; 2037 return r;
2032 2038
2033 display->set_timings(display, &timings); 2039 display->driver->set_timings(display, &timings);
2034 2040
2035 return 0; 2041 return 0;
2036} 2042}
2037 2043
2044static int omapfb_get_recommended_bpp(struct omapfb2_device *fbdev,
2045 struct omap_dss_device *dssdev)
2046{
2047 int i;
2048
2049 BUG_ON(dssdev->driver->get_recommended_bpp == NULL);
2050
2051 for (i = 0; i < fbdev->num_bpp_overrides; ++i) {
2052 if (dssdev == fbdev->bpp_overrides[i].dssdev)
2053 return fbdev->bpp_overrides[i].bpp;
2054 }
2055
2056 return dssdev->driver->get_recommended_bpp(dssdev);
2057}
2058
2038static int omapfb_parse_def_modes(struct omapfb2_device *fbdev) 2059static int omapfb_parse_def_modes(struct omapfb2_device *fbdev)
2039{ 2060{
2040 char *str, *options, *this_opt; 2061 char *str, *options, *this_opt;
@@ -2073,7 +2094,7 @@ static int omapfb_parse_def_modes(struct omapfb2_device *fbdev)
2073 break; 2094 break;
2074 } 2095 }
2075 2096
2076 r = omapfb_set_def_mode(display, mode_str); 2097 r = omapfb_set_def_mode(fbdev, display, mode_str);
2077 if (r) 2098 if (r)
2078 break; 2099 break;
2079 } 2100 }
@@ -2111,18 +2132,23 @@ static int omapfb_probe(struct platform_device *pdev)
2111 fbdev->dev = &pdev->dev; 2132 fbdev->dev = &pdev->dev;
2112 platform_set_drvdata(pdev, fbdev); 2133 platform_set_drvdata(pdev, fbdev);
2113 2134
2135 r = 0;
2114 fbdev->num_displays = 0; 2136 fbdev->num_displays = 0;
2115 dssdev = NULL; 2137 dssdev = NULL;
2116 for_each_dss_dev(dssdev) { 2138 for_each_dss_dev(dssdev) {
2117 omap_dss_get_device(dssdev); 2139 omap_dss_get_device(dssdev);
2140
2118 if (!dssdev->driver) { 2141 if (!dssdev->driver) {
2119 dev_err(&pdev->dev, "no driver for display\n"); 2142 dev_err(&pdev->dev, "no driver for display\n");
2120 r = -EINVAL; 2143 r = -ENODEV;
2121 goto cleanup;
2122 } 2144 }
2145
2123 fbdev->displays[fbdev->num_displays++] = dssdev; 2146 fbdev->displays[fbdev->num_displays++] = dssdev;
2124 } 2147 }
2125 2148
2149 if (r)
2150 goto cleanup;
2151
2126 if (fbdev->num_displays == 0) { 2152 if (fbdev->num_displays == 0) {
2127 dev_err(&pdev->dev, "no displays\n"); 2153 dev_err(&pdev->dev, "no displays\n");
2128 r = -EINVAL; 2154 r = -EINVAL;
@@ -2167,35 +2193,28 @@ static int omapfb_probe(struct platform_device *pdev)
2167 } 2193 }
2168 2194
2169 if (def_display) { 2195 if (def_display) {
2170#ifndef CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE 2196 struct omap_dss_driver *dssdrv = def_display->driver;
2171 u16 w, h; 2197
2172#endif 2198 r = def_display->driver->enable(def_display);
2173 r = def_display->enable(def_display); 2199 if (r) {
2174 if (r)
2175 dev_warn(fbdev->dev, "Failed to enable display '%s'\n", 2200 dev_warn(fbdev->dev, "Failed to enable display '%s'\n",
2176 def_display->name); 2201 def_display->name);
2202 goto cleanup;
2203 }
2177 2204
2178 /* set the update mode */
2179 if (def_display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 2205 if (def_display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
2180#ifdef CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE 2206 u16 w, h;
2181 if (def_display->enable_te) 2207 if (dssdrv->enable_te)
2182 def_display->enable_te(def_display, 1); 2208 dssdrv->enable_te(def_display, 1);
2183 if (def_display->set_update_mode) 2209 if (dssdrv->set_update_mode)
2184 def_display->set_update_mode(def_display, 2210 dssdrv->set_update_mode(def_display,
2185 OMAP_DSS_UPDATE_AUTO);
2186#else /* MANUAL_UPDATE */
2187 if (def_display->enable_te)
2188 def_display->enable_te(def_display, 0);
2189 if (def_display->set_update_mode)
2190 def_display->set_update_mode(def_display,
2191 OMAP_DSS_UPDATE_MANUAL); 2211 OMAP_DSS_UPDATE_MANUAL);
2192 2212
2193 def_display->get_resolution(def_display, &w, &h); 2213 dssdrv->get_resolution(def_display, &w, &h);
2194 def_display->update(def_display, 0, 0, w, h); 2214 def_display->driver->update(def_display, 0, 0, w, h);
2195#endif
2196 } else { 2215 } else {
2197 if (def_display->set_update_mode) 2216 if (dssdrv->set_update_mode)
2198 def_display->set_update_mode(def_display, 2217 dssdrv->set_update_mode(def_display,
2199 OMAP_DSS_UPDATE_AUTO); 2218 OMAP_DSS_UPDATE_AUTO);
2200 } 2219 }
2201 } 2220 }