diff options
Diffstat (limited to 'drivers/video/omap2/dss/dispc.c')
-rw-r--r-- | drivers/video/omap2/dss/dispc.c | 59 |
1 files changed, 40 insertions, 19 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index d65568929ac8..fd932b83ce43 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c | |||
@@ -91,9 +91,10 @@ struct dispc_features { | |||
91 | u16 width, u16 height, u16 out_width, u16 out_height, | 91 | u16 width, u16 height, u16 out_width, u16 out_height, |
92 | enum omap_color_mode color_mode, bool *five_taps, | 92 | enum omap_color_mode color_mode, bool *five_taps, |
93 | int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, | 93 | int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, |
94 | u16 pos_x, unsigned long *core_clk); | 94 | u16 pos_x, unsigned long *core_clk, bool mem_to_mem); |
95 | unsigned long (*calc_core_clk) (enum omap_plane plane, | 95 | unsigned long (*calc_core_clk) (enum omap_plane plane, |
96 | u16 width, u16 height, u16 out_width, u16 out_height); | 96 | u16 width, u16 height, u16 out_width, u16 out_height, |
97 | bool mem_to_mem); | ||
97 | u8 num_fifos; | 98 | u8 num_fifos; |
98 | 99 | ||
99 | /* swap GFX & WB fifos */ | 100 | /* swap GFX & WB fifos */ |
@@ -2012,7 +2013,7 @@ static unsigned long calc_core_clk_five_taps(enum omap_plane plane, | |||
2012 | } | 2013 | } |
2013 | 2014 | ||
2014 | static unsigned long calc_core_clk_24xx(enum omap_plane plane, u16 width, | 2015 | static unsigned long calc_core_clk_24xx(enum omap_plane plane, u16 width, |
2015 | u16 height, u16 out_width, u16 out_height) | 2016 | u16 height, u16 out_width, u16 out_height, bool mem_to_mem) |
2016 | { | 2017 | { |
2017 | unsigned long pclk = dispc_plane_pclk_rate(plane); | 2018 | unsigned long pclk = dispc_plane_pclk_rate(plane); |
2018 | 2019 | ||
@@ -2023,7 +2024,7 @@ static unsigned long calc_core_clk_24xx(enum omap_plane plane, u16 width, | |||
2023 | } | 2024 | } |
2024 | 2025 | ||
2025 | static unsigned long calc_core_clk_34xx(enum omap_plane plane, u16 width, | 2026 | static unsigned long calc_core_clk_34xx(enum omap_plane plane, u16 width, |
2026 | u16 height, u16 out_width, u16 out_height) | 2027 | u16 height, u16 out_width, u16 out_height, bool mem_to_mem) |
2027 | { | 2028 | { |
2028 | unsigned int hf, vf; | 2029 | unsigned int hf, vf; |
2029 | unsigned long pclk = dispc_plane_pclk_rate(plane); | 2030 | unsigned long pclk = dispc_plane_pclk_rate(plane); |
@@ -2050,9 +2051,20 @@ static unsigned long calc_core_clk_34xx(enum omap_plane plane, u16 width, | |||
2050 | } | 2051 | } |
2051 | 2052 | ||
2052 | static unsigned long calc_core_clk_44xx(enum omap_plane plane, u16 width, | 2053 | static unsigned long calc_core_clk_44xx(enum omap_plane plane, u16 width, |
2053 | u16 height, u16 out_width, u16 out_height) | 2054 | u16 height, u16 out_width, u16 out_height, bool mem_to_mem) |
2054 | { | 2055 | { |
2055 | unsigned long pclk = dispc_plane_pclk_rate(plane); | 2056 | unsigned long pclk; |
2057 | |||
2058 | /* | ||
2059 | * If the overlay/writeback is in mem to mem mode, there are no | ||
2060 | * downscaling limitations with respect to pixel clock, return 1 as | ||
2061 | * required core clock to represent that we have sufficient enough | ||
2062 | * core clock to do maximum downscaling | ||
2063 | */ | ||
2064 | if (mem_to_mem) | ||
2065 | return 1; | ||
2066 | |||
2067 | pclk = dispc_plane_pclk_rate(plane); | ||
2056 | 2068 | ||
2057 | if (width > out_width) | 2069 | if (width > out_width) |
2058 | return DIV_ROUND_UP(pclk, out_width) * width; | 2070 | return DIV_ROUND_UP(pclk, out_width) * width; |
@@ -2065,7 +2077,7 @@ static int dispc_ovl_calc_scaling_24xx(enum omap_plane plane, | |||
2065 | u16 width, u16 height, u16 out_width, u16 out_height, | 2077 | u16 width, u16 height, u16 out_width, u16 out_height, |
2066 | enum omap_color_mode color_mode, bool *five_taps, | 2078 | enum omap_color_mode color_mode, bool *five_taps, |
2067 | int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, | 2079 | int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, |
2068 | u16 pos_x, unsigned long *core_clk) | 2080 | u16 pos_x, unsigned long *core_clk, bool mem_to_mem) |
2069 | { | 2081 | { |
2070 | int error; | 2082 | int error; |
2071 | u16 in_width, in_height; | 2083 | u16 in_width, in_height; |
@@ -2079,7 +2091,7 @@ static int dispc_ovl_calc_scaling_24xx(enum omap_plane plane, | |||
2079 | in_height = DIV_ROUND_UP(height, *decim_y); | 2091 | in_height = DIV_ROUND_UP(height, *decim_y); |
2080 | in_width = DIV_ROUND_UP(width, *decim_x); | 2092 | in_width = DIV_ROUND_UP(width, *decim_x); |
2081 | *core_clk = dispc.feat->calc_core_clk(plane, in_width, | 2093 | *core_clk = dispc.feat->calc_core_clk(plane, in_width, |
2082 | in_height, out_width, out_height); | 2094 | in_height, out_width, out_height, mem_to_mem); |
2083 | error = (in_width > maxsinglelinewidth || !*core_clk || | 2095 | error = (in_width > maxsinglelinewidth || !*core_clk || |
2084 | *core_clk > dispc_core_clk_rate()); | 2096 | *core_clk > dispc_core_clk_rate()); |
2085 | if (error) { | 2097 | if (error) { |
@@ -2106,7 +2118,7 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane, | |||
2106 | u16 width, u16 height, u16 out_width, u16 out_height, | 2118 | u16 width, u16 height, u16 out_width, u16 out_height, |
2107 | enum omap_color_mode color_mode, bool *five_taps, | 2119 | enum omap_color_mode color_mode, bool *five_taps, |
2108 | int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, | 2120 | int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, |
2109 | u16 pos_x, unsigned long *core_clk) | 2121 | u16 pos_x, unsigned long *core_clk, bool mem_to_mem) |
2110 | { | 2122 | { |
2111 | int error; | 2123 | int error; |
2112 | u16 in_width, in_height; | 2124 | u16 in_width, in_height; |
@@ -2130,7 +2142,8 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane, | |||
2130 | *five_taps = false; | 2142 | *five_taps = false; |
2131 | if (!*five_taps) | 2143 | if (!*five_taps) |
2132 | *core_clk = dispc.feat->calc_core_clk(plane, in_width, | 2144 | *core_clk = dispc.feat->calc_core_clk(plane, in_width, |
2133 | in_height, out_width, out_height); | 2145 | in_height, out_width, out_height, |
2146 | mem_to_mem); | ||
2134 | 2147 | ||
2135 | error = (error || in_width > maxsinglelinewidth * 2 || | 2148 | error = (error || in_width > maxsinglelinewidth * 2 || |
2136 | (in_width > maxsinglelinewidth && *five_taps) || | 2149 | (in_width > maxsinglelinewidth && *five_taps) || |
@@ -2171,7 +2184,7 @@ static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane, | |||
2171 | u16 width, u16 height, u16 out_width, u16 out_height, | 2184 | u16 width, u16 height, u16 out_width, u16 out_height, |
2172 | enum omap_color_mode color_mode, bool *five_taps, | 2185 | enum omap_color_mode color_mode, bool *five_taps, |
2173 | int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, | 2186 | int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, |
2174 | u16 pos_x, unsigned long *core_clk) | 2187 | u16 pos_x, unsigned long *core_clk, bool mem_to_mem) |
2175 | { | 2188 | { |
2176 | u16 in_width, in_width_max; | 2189 | u16 in_width, in_width_max; |
2177 | int decim_x_min = *decim_x; | 2190 | int decim_x_min = *decim_x; |
@@ -2179,8 +2192,13 @@ static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane, | |||
2179 | const int maxsinglelinewidth = | 2192 | const int maxsinglelinewidth = |
2180 | dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); | 2193 | dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); |
2181 | unsigned long pclk = dispc_plane_pclk_rate(plane); | 2194 | unsigned long pclk = dispc_plane_pclk_rate(plane); |
2195 | const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE); | ||
2182 | 2196 | ||
2183 | in_width_max = dispc_core_clk_rate() / DIV_ROUND_UP(pclk, out_width); | 2197 | if (mem_to_mem) |
2198 | in_width_max = DIV_ROUND_UP(out_width, maxdownscale); | ||
2199 | else | ||
2200 | in_width_max = dispc_core_clk_rate() / | ||
2201 | DIV_ROUND_UP(pclk, out_width); | ||
2184 | 2202 | ||
2185 | *decim_x = DIV_ROUND_UP(width, in_width_max); | 2203 | *decim_x = DIV_ROUND_UP(width, in_width_max); |
2186 | 2204 | ||
@@ -2199,7 +2217,7 @@ static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane, | |||
2199 | } | 2217 | } |
2200 | 2218 | ||
2201 | *core_clk = dispc.feat->calc_core_clk(plane, in_width, in_height, | 2219 | *core_clk = dispc.feat->calc_core_clk(plane, in_width, in_height, |
2202 | out_width, out_height); | 2220 | out_width, out_height, mem_to_mem); |
2203 | return 0; | 2221 | return 0; |
2204 | } | 2222 | } |
2205 | 2223 | ||
@@ -2209,7 +2227,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane, | |||
2209 | u16 width, u16 height, u16 out_width, u16 out_height, | 2227 | u16 width, u16 height, u16 out_width, u16 out_height, |
2210 | enum omap_color_mode color_mode, bool *five_taps, | 2228 | enum omap_color_mode color_mode, bool *five_taps, |
2211 | int *x_predecim, int *y_predecim, u16 pos_x, | 2229 | int *x_predecim, int *y_predecim, u16 pos_x, |
2212 | enum omap_dss_rotation_type rotation_type) | 2230 | enum omap_dss_rotation_type rotation_type, bool mem_to_mem) |
2213 | { | 2231 | { |
2214 | const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE); | 2232 | const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE); |
2215 | const int max_decim_limit = 16; | 2233 | const int max_decim_limit = 16; |
@@ -2247,7 +2265,8 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane, | |||
2247 | 2265 | ||
2248 | ret = dispc.feat->calc_scaling(plane, mgr_timings, width, height, | 2266 | ret = dispc.feat->calc_scaling(plane, mgr_timings, width, height, |
2249 | out_width, out_height, color_mode, five_taps, | 2267 | out_width, out_height, color_mode, five_taps, |
2250 | x_predecim, y_predecim, &decim_x, &decim_y, pos_x, &core_clk); | 2268 | x_predecim, y_predecim, &decim_x, &decim_y, pos_x, &core_clk, |
2269 | mem_to_mem); | ||
2251 | if (ret) | 2270 | if (ret) |
2252 | return ret; | 2271 | return ret; |
2253 | 2272 | ||
@@ -2273,7 +2292,8 @@ static int dispc_ovl_setup_common(enum omap_plane plane, | |||
2273 | u16 out_width, u16 out_height, enum omap_color_mode color_mode, | 2292 | u16 out_width, u16 out_height, enum omap_color_mode color_mode, |
2274 | u8 rotation, bool mirror, u8 zorder, u8 pre_mult_alpha, | 2293 | u8 rotation, bool mirror, u8 zorder, u8 pre_mult_alpha, |
2275 | u8 global_alpha, enum omap_dss_rotation_type rotation_type, | 2294 | u8 global_alpha, enum omap_dss_rotation_type rotation_type, |
2276 | bool replication, const struct omap_video_timings *mgr_timings) | 2295 | bool replication, const struct omap_video_timings *mgr_timings, |
2296 | bool mem_to_mem) | ||
2277 | { | 2297 | { |
2278 | bool five_taps = true; | 2298 | bool five_taps = true; |
2279 | bool fieldmode = 0; | 2299 | bool fieldmode = 0; |
@@ -2314,7 +2334,7 @@ static int dispc_ovl_setup_common(enum omap_plane plane, | |||
2314 | r = dispc_ovl_calc_scaling(plane, caps, mgr_timings, in_width, | 2334 | r = dispc_ovl_calc_scaling(plane, caps, mgr_timings, in_width, |
2315 | in_height, out_width, out_height, color_mode, | 2335 | in_height, out_width, out_height, color_mode, |
2316 | &five_taps, &x_predecim, &y_predecim, pos_x, | 2336 | &five_taps, &x_predecim, &y_predecim, pos_x, |
2317 | rotation_type); | 2337 | rotation_type, mem_to_mem); |
2318 | if (r) | 2338 | if (r) |
2319 | return r; | 2339 | return r; |
2320 | 2340 | ||
@@ -2412,7 +2432,8 @@ static int dispc_ovl_setup_common(enum omap_plane plane, | |||
2412 | } | 2432 | } |
2413 | 2433 | ||
2414 | int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, | 2434 | int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, |
2415 | bool replication, const struct omap_video_timings *mgr_timings) | 2435 | bool replication, const struct omap_video_timings *mgr_timings, |
2436 | bool mem_to_mem) | ||
2416 | { | 2437 | { |
2417 | int r; | 2438 | int r; |
2418 | struct omap_overlay *ovl = omap_dss_get_overlay(plane); | 2439 | struct omap_overlay *ovl = omap_dss_get_overlay(plane); |
@@ -2430,7 +2451,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, | |||
2430 | oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height, | 2451 | oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height, |
2431 | oi->out_width, oi->out_height, oi->color_mode, oi->rotation, | 2452 | oi->out_width, oi->out_height, oi->color_mode, oi->rotation, |
2432 | oi->mirror, oi->zorder, oi->pre_mult_alpha, oi->global_alpha, | 2453 | oi->mirror, oi->zorder, oi->pre_mult_alpha, oi->global_alpha, |
2433 | oi->rotation_type, replication, mgr_timings); | 2454 | oi->rotation_type, replication, mgr_timings, mem_to_mem); |
2434 | 2455 | ||
2435 | return r; | 2456 | return r; |
2436 | } | 2457 | } |