diff options
Diffstat (limited to 'drivers/video/omap2/omapfb/omapfb-main.c')
-rw-r--r-- | drivers/video/omap2/omapfb/omapfb-main.c | 133 |
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 | ||
56 | static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi); | 56 | static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi); |
57 | static int omapfb_get_recommended_bpp(struct omapfb2_device *fbdev, | ||
58 | struct omap_dss_device *dssdev); | ||
57 | 59 | ||
58 | #ifdef DEBUG | 60 | #ifdef DEBUG |
59 | static void draw_pixel(struct fb_info *fbi, int x, int y, unsigned color) | 61 | static 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 | ||
155 | static unsigned omapfb_get_vrfb_offset(struct omapfb_info *ofbi, int rot) | 157 | static 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 | ||
182 | static u32 omapfb_get_region_rot_paddr(struct omapfb_info *ofbi, int rot) | 184 | static 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 | ||
192 | static u32 omapfb_get_region_paddr(struct omapfb_info *ofbi) | 194 | static 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 | ||
200 | static void __iomem *omapfb_get_region_vaddr(struct omapfb_info *ofbi) | 202 | static 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 | ||
781 | static unsigned calc_rotation_offset_dma(struct fb_var_screeninfo *var, | 783 | static 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 | ||
792 | static unsigned calc_rotation_offset_vrfb(struct fb_var_screeninfo *var, | 794 | static 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) | |||
1252 | exit: | 1254 | exit: |
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 | ||
2014 | static int omapfb_set_def_mode(struct omap_dss_device *display, char *mode_str) | 2017 | static 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 | ||
2044 | static 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 | |||
2038 | static int omapfb_parse_def_modes(struct omapfb2_device *fbdev) | 2059 | static 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 | } |