aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss/dispc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2/dss/dispc.c')
-rw-r--r--drivers/video/omap2/dss/dispc.c59
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
2014static unsigned long calc_core_clk_24xx(enum omap_plane plane, u16 width, 2015static 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
2025static unsigned long calc_core_clk_34xx(enum omap_plane plane, u16 width, 2026static 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
2052static unsigned long calc_core_clk_44xx(enum omap_plane plane, u16 width, 2053static 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
2414int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, 2434int 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}