aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorArchit Taneja <archit@ti.com>2012-09-26 07:30:37 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2012-09-26 07:58:49 -0400
commit8ba85306ba0fd87a3c15a02fe83d817832705a7d (patch)
tree2e736e1cd5210f0705f863b6fdcfa24ff59650fb /drivers/video
parent3e8a6ff2489510f529364f3c3f8b8881d599fd5c (diff)
OMAPDSS: DIPSC: Relax scaling limitations when in memory to memory mode
The scalers of overlays and writeback do not have any constraints on downscale ratio when operating in memory to memory mode. This is because in memory to memory mode, we aren't connected to a display which needs data output at the rate of pixel clock. The scalers can perform as much downscaling as needed, the rate at which the scaler outputs is adjusted accordingly. Relax constraints related to downscaling based on whether the input overlays are connected to writeback in memory to memory mode. We pass a mem_to_mem boolean parameter to dispc_ovl_setup() from APPLY. This is currently set to false, this will later be configured to the correct value based on whether the overlay is connected to writeback or not. Do the same later for writeback when writeback is configured. In the scaling calculation code, we calculate the minimum amount of core clock we need to achieve the required downscaling. If we are in memory to memory mode, we set this to a very small value(1 in this case), this value would always be lesser than the actual DISPC core clock value, and hence the scaling checks would succeed. We take care that pixel clock isn't calculated for writeback and the overlays connected to it when in memory to memory mode. A pixel clock in such cases doesn't make sense. Signed-off-by: Archit Taneja <archit@ti.com>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/omap2/dss/apply.c2
-rw-r--r--drivers/video/omap2/dss/dispc.c59
-rw-r--r--drivers/video/omap2/dss/dss.h3
3 files changed, 43 insertions, 21 deletions
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 2b1fa851a8b9..19d66f471b4b 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -584,7 +584,7 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
584 584
585 replication = dss_ovl_use_replication(mp->lcd_config, oi->color_mode); 585 replication = dss_ovl_use_replication(mp->lcd_config, oi->color_mode);
586 586
587 r = dispc_ovl_setup(ovl->id, oi, replication, &mp->timings); 587 r = dispc_ovl_setup(ovl->id, oi, replication, &mp->timings, false);
588 if (r) { 588 if (r) {
589 /* 589 /*
590 * We can't do much here, as this function can be called from 590 * We can't do much here, as this function can be called from
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}
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index e71a6f16fc4d..322a2be7b4c6 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -445,7 +445,8 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
445 u32 *fifo_low, u32 *fifo_high, bool use_fifomerge, 445 u32 *fifo_low, u32 *fifo_high, bool use_fifomerge,
446 bool manual_update); 446 bool manual_update);
447int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, 447int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
448 bool replication, const struct omap_video_timings *mgr_timings); 448 bool replication, const struct omap_video_timings *mgr_timings,
449 bool mem_to_mem);
449int dispc_ovl_enable(enum omap_plane plane, bool enable); 450int dispc_ovl_enable(enum omap_plane plane, bool enable);
450void dispc_ovl_set_channel_out(enum omap_plane plane, 451void dispc_ovl_set_channel_out(enum omap_plane plane,
451 enum omap_channel channel); 452 enum omap_channel channel);