u16 sw_max;
        u16 vp_max;
        u16 hp_max;
-       int (*calc_scaling) (enum omap_channel channel,
+       int (*calc_scaling) (enum omap_plane plane,
                const struct omap_video_timings *mgr_timings,
                u16 width, u16 height, u16 out_width, u16 out_height,
                enum omap_color_mode color_mode, bool *five_taps,
                int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
                u16 pos_x, unsigned long *core_clk);
-       unsigned long (*calc_core_clk) (enum omap_channel channel,
+       unsigned long (*calc_core_clk) (enum omap_plane plane,
                u16 width, u16 height, u16 out_width, u16 out_height);
        u8 num_fifos;
 
 };
 
 static void _omap_dispc_set_irqs(void);
+static unsigned long dispc_plane_pclk_rate(enum omap_plane plane);
+static unsigned long dispc_plane_lclk_rate(enum omap_plane plane);
 
 static inline void dispc_write_reg(const u16 idx, u32 val)
 {
  * This function is used to avoid synclosts in OMAP3, because of some
  * undocumented horizontal position and timing related limitations.
  */
-static int check_horiz_timing_omap3(enum omap_channel channel,
+static int check_horiz_timing_omap3(enum omap_plane plane,
                const struct omap_video_timings *t, u16 pos_x,
                u16 width, u16 height, u16 out_width, u16 out_height)
 {
        int DS = DIV_ROUND_UP(height, out_height);
-       unsigned long nonactive, lclk, pclk;
+       unsigned long nonactive;
        static const u8 limits[3] = { 8, 10, 20 };
        u64 val, blank;
+       unsigned long pclk = dispc_plane_pclk_rate(plane);
+       unsigned long lclk = dispc_plane_lclk_rate(plane);
        int i;
 
        nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width;
-       pclk = dispc_mgr_pclk_rate(channel);
-       if (dss_mgr_is_lcd(channel))
-               lclk = dispc_mgr_lclk_rate(channel);
-       else
-               lclk = dispc_fclk_rate();
 
        i = 0;
        if (out_height < height)
        return 0;
 }
 
-static unsigned long calc_core_clk_five_taps(enum omap_channel channel,
+static unsigned long calc_core_clk_five_taps(enum omap_plane plane,
                const struct omap_video_timings *mgr_timings, u16 width,
                u16 height, u16 out_width, u16 out_height,
                enum omap_color_mode color_mode)
 {
        u32 core_clk = 0;
-       u64 tmp, pclk = dispc_mgr_pclk_rate(channel);
+       u64 tmp;
+       unsigned long pclk = dispc_plane_pclk_rate(plane);
 
        if (height <= out_height && width <= out_width)
                return (unsigned long) pclk;
        return core_clk;
 }
 
-static unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width,
+static unsigned long calc_core_clk_24xx(enum omap_plane plane, u16 width,
                u16 height, u16 out_width, u16 out_height)
 {
-       unsigned long pclk = dispc_mgr_pclk_rate(channel);
+       unsigned long pclk = dispc_plane_pclk_rate(plane);
 
        if (height > out_height && width > out_width)
                return pclk * 4;
                return pclk * 2;
 }
 
-static unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width,
+static unsigned long calc_core_clk_34xx(enum omap_plane plane, u16 width,
                u16 height, u16 out_width, u16 out_height)
 {
        unsigned int hf, vf;
-       unsigned long pclk = dispc_mgr_pclk_rate(channel);
+       unsigned long pclk = dispc_plane_pclk_rate(plane);
 
        /*
         * FIXME how to determine the 'A' factor
        return pclk * vf * hf;
 }
 
-static unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width,
+static unsigned long calc_core_clk_44xx(enum omap_plane plane, u16 width,
                u16 height, u16 out_width, u16 out_height)
 {
-       unsigned long pclk = dispc_mgr_pclk_rate(channel);
+       unsigned long pclk = dispc_plane_pclk_rate(plane);
 
        if (width > out_width)
                return DIV_ROUND_UP(pclk, out_width) * width;
                return pclk;
 }
 
-static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
+static int dispc_ovl_calc_scaling_24xx(enum omap_plane plane,
                const struct omap_video_timings *mgr_timings,
                u16 width, u16 height, u16 out_width, u16 out_height,
                enum omap_color_mode color_mode, bool *five_taps,
        int min_factor = min(*decim_x, *decim_y);
        const int maxsinglelinewidth =
                        dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
        *five_taps = false;
 
        do {
                in_height = DIV_ROUND_UP(height, *decim_y);
                in_width = DIV_ROUND_UP(width, *decim_x);
-               *core_clk = dispc.feat->calc_core_clk(channel, in_width,
+               *core_clk = dispc.feat->calc_core_clk(plane, in_width,
                                in_height, out_width, out_height);
                error = (in_width > maxsinglelinewidth || !*core_clk ||
                        *core_clk > dispc_core_clk_rate());
        return 0;
 }
 
-static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
+static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane,
                const struct omap_video_timings *mgr_timings,
                u16 width, u16 height, u16 out_width, u16 out_height,
                enum omap_color_mode color_mode, bool *five_taps,
        do {
                in_height = DIV_ROUND_UP(height, *decim_y);
                in_width = DIV_ROUND_UP(width, *decim_x);
-               *core_clk = calc_core_clk_five_taps(channel, mgr_timings,
+               *core_clk = calc_core_clk_five_taps(plane, mgr_timings,
                        in_width, in_height, out_width, out_height, color_mode);
 
-               error = check_horiz_timing_omap3(channel, mgr_timings, pos_x,
-                       in_width, in_height, out_width, out_height);
+               error = check_horiz_timing_omap3(plane, mgr_timings,
+                               pos_x, in_width, in_height, out_width,
+                               out_height);
 
                if (in_width > maxsinglelinewidth)
                        if (in_height > out_height &&
                                                in_height < out_height * 2)
                                *five_taps = false;
                if (!*five_taps)
-                       *core_clk = dispc.feat->calc_core_clk(channel, in_width,
+                       *core_clk = dispc.feat->calc_core_clk(plane, in_width,
                                        in_height, out_width, out_height);
 
                error = (error || in_width > maxsinglelinewidth * 2 ||
                }
        } while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
 
-       if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width, height,
+       if (check_horiz_timing_omap3(plane, mgr_timings, pos_x, width, height,
                out_width, out_height)){
                        DSSERR("horizontal timing too tight\n");
                        return -EINVAL;
        return 0;
 }
 
-static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
+static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane,
                const struct omap_video_timings *mgr_timings,
                u16 width, u16 height, u16 out_width, u16 out_height,
                enum omap_color_mode color_mode, bool *five_taps,
        u16 in_height = DIV_ROUND_UP(height, *decim_y);
        const int maxsinglelinewidth =
                                dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+       unsigned long pclk = dispc_plane_pclk_rate(plane);
+
+       in_width_max = dispc_core_clk_rate() / DIV_ROUND_UP(pclk, out_width);
 
-       in_width_max = dispc_core_clk_rate() /
-                       DIV_ROUND_UP(dispc_mgr_pclk_rate(channel), out_width);
        *decim_x = DIV_ROUND_UP(width, in_width_max);
 
        *decim_x = *decim_x > decim_x_min ? *decim_x : decim_x_min;
                return -EINVAL;
        }
 
-       *core_clk = dispc.feat->calc_core_clk(channel, in_width, in_height,
+       *core_clk = dispc.feat->calc_core_clk(plane, in_width, in_height,
                                out_width, out_height);
        return 0;
 }
 
 static int dispc_ovl_calc_scaling(enum omap_plane plane,
-               enum omap_overlay_caps caps, enum omap_channel channel,
+               enum omap_overlay_caps caps,
                const struct omap_video_timings *mgr_timings,
                u16 width, u16 height, u16 out_width, u16 out_height,
                enum omap_color_mode color_mode, bool *five_taps,
        if (decim_y > *y_predecim || out_height > height * 8)
                return -EINVAL;
 
-       ret = dispc.feat->calc_scaling(channel, mgr_timings, width, height,
-               out_width, out_height, color_mode, five_taps, x_predecim,
-               y_predecim, &decim_x, &decim_y, pos_x, &core_clk);
+       ret = dispc.feat->calc_scaling(plane, mgr_timings, width, height,
+               out_width, out_height, color_mode, five_taps,
+               x_predecim, y_predecim, &decim_x, &decim_y, pos_x, &core_clk);
        if (ret)
                return ret;
 
 }
 
 static int dispc_ovl_setup_common(enum omap_plane plane,
-               enum omap_channel channel, enum omap_overlay_caps caps,
-               u32 paddr, u32 p_uv_addr, u16 screen_width, int pos_x,
-               int pos_y, u16 width, u16 height, u16 out_width, u16 out_height,
-               enum omap_color_mode color_mode, u8 rotation, bool mirror,
-               u8 zorder, u8 pre_mult_alpha, u8 global_alpha,
-               enum omap_dss_rotation_type rotation_type,
+               enum omap_overlay_caps caps, u32 paddr, u32 p_uv_addr,
+               u16 screen_width, int pos_x, int pos_y, u16 width, u16 height,
+               u16 out_width, u16 out_height, enum omap_color_mode color_mode,
+               u8 rotation, bool mirror, u8 zorder, u8 pre_mult_alpha,
+               u8 global_alpha, enum omap_dss_rotation_type rotation_type,
                bool replication, const struct omap_video_timings *mgr_timings)
 {
        bool five_taps = true;
        if (!dss_feat_color_mode_supported(plane, color_mode))
                return -EINVAL;
 
-       r = dispc_ovl_calc_scaling(plane, caps, channel, mgr_timings, in_width,
+       r = dispc_ovl_calc_scaling(plane, caps, mgr_timings, in_width,
                        in_height, out_width, out_height, color_mode,
                        &five_taps, &x_predecim, &y_predecim, pos_x,
                        rotation_type);
                oi->pos_y, oi->width, oi->height, oi->out_width, oi->out_height,
                oi->color_mode, oi->rotation, oi->mirror, channel, replication);
 
-       r = dispc_ovl_setup_common(plane, channel, ovl->caps, oi->paddr,
-               oi->p_uv_addr, oi->screen_width, oi->pos_x, oi->pos_y,
-               oi->width, oi->height, oi->out_width, oi->out_height,
-               oi->color_mode, oi->rotation, oi->mirror, oi->zorder,
-               oi->pre_mult_alpha, oi->global_alpha, oi->rotation_type,
-               replication, mgr_timings);
+       r = dispc_ovl_setup_common(plane, ovl->caps, oi->paddr, oi->p_uv_addr,
+               oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height,
+               oi->out_width, oi->out_height, oi->color_mode, oi->rotation,
+               oi->mirror, oi->zorder, oi->pre_mult_alpha, oi->global_alpha,
+               oi->rotation_type, replication, mgr_timings);
 
        return r;
 }
        return fclk / lcd;
 }
 
+static unsigned long dispc_plane_pclk_rate(enum omap_plane plane)
+{
+       enum omap_channel channel = dispc_ovl_get_channel_out(plane);
+
+       return dispc_mgr_pclk_rate(channel);
+}
+
+static unsigned long dispc_plane_lclk_rate(enum omap_plane plane)
+{
+       enum omap_channel channel = dispc_ovl_get_channel_out(plane);
+
+       if (dss_mgr_is_lcd(channel))
+               return dispc_mgr_lclk_rate(channel);
+       else
+               return dispc_fclk_rate();
+
+}
 static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel channel)
 {
        int lcd, pcd;