SR(CONTROL);
SR(CONFIG);
SR(LINE_NUMBER);
- if (dss_has_feature(FEAT_GLOBAL_ALPHA))
+ if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER) ||
+ dss_has_feature(FEAT_ALPHA_FREE_ZORDER))
SR(GLOBAL_ALPHA);
if (dss_has_feature(FEAT_MGR_LCD2)) {
SR(CONTROL2);
/*RR(CONTROL);*/
RR(CONFIG);
RR(LINE_NUMBER);
- if (dss_has_feature(FEAT_GLOBAL_ALPHA))
+ if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER) ||
+ dss_has_feature(FEAT_ALPHA_FREE_ZORDER))
RR(GLOBAL_ALPHA);
if (dss_has_feature(FEAT_MGR_LCD2))
RR(CONFIG2);
dispc_write_reg(DISPC_OVL_SIZE(plane), val);
}
+static void dispc_ovl_set_zorder(enum omap_plane plane, u8 zorder)
+{
+ struct omap_overlay *ovl = omap_dss_get_overlay(plane);
+
+ if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
+ return;
+
+ REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), zorder, 27, 26);
+}
+
+static void dispc_ovl_enable_zorder_planes(void)
+{
+ int i;
+
+ if (!dss_has_feature(FEAT_ALPHA_FREE_ZORDER))
+ return;
+
+ for (i = 0; i < dss_feat_get_num_ovls(); i++)
+ REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25);
+}
+
static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane, bool enable)
{
struct omap_overlay *ovl = omap_dss_get_overlay(plane);
static void dispc_ovl_setup_global_alpha(enum omap_plane plane, u8 global_alpha)
{
- static const unsigned shifts[] = { 0, 8, 16, };
+ static const unsigned shifts[] = { 0, 8, 16, 24, };
int shift;
struct omap_overlay *ovl = omap_dss_get_overlay(plane);
break;
case OMAP_DSS_VIDEO1:
case OMAP_DSS_VIDEO2:
+ case OMAP_DSS_VIDEO3:
shift = 16;
break;
default:
static void dispc_ovl_set_burst_size(enum omap_plane plane,
enum omap_burst_size burst_size)
{
- static const unsigned shifts[] = { 6, 14, 14, };
+ static const unsigned shifts[] = { 6, 14, 14, 14, };
int shift;
shift = shifts[plane];
static void dispc_ovl_enable_replication(enum omap_plane plane, bool enable)
{
- static const unsigned shifts[] = { 5, 10, 10 };
+ static const unsigned shifts[] = { 5, 10, 10, 10 };
int shift;
shift = shifts[plane];
return dispc_mgr_pclk_rate(channel) * vf * hf;
}
+static int dispc_ovl_calc_scaling(enum omap_plane plane,
+ enum omap_channel channel, u16 width, u16 height,
+ u16 out_width, u16 out_height,
+ enum omap_color_mode color_mode, bool *five_taps)
+{
+ struct omap_overlay *ovl = omap_dss_get_overlay(plane);
+ const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
+ unsigned long fclk = 0;
+
+ if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
+ if (width != out_width || height != out_height)
+ return -EINVAL;
+ else
+ return 0;
+ }
+
+ if (out_width < width / maxdownscale ||
+ out_width > width * 8)
+ return -EINVAL;
+
+ if (out_height < height / maxdownscale ||
+ out_height > height * 8)
+ return -EINVAL;
+
+ /* Must use 5-tap filter? */
+ *five_taps = height > out_height * 2;
+
+ if (!*five_taps) {
+ fclk = calc_fclk(channel, width, height, out_width,
+ out_height);
+
+ /* Try 5-tap filter if 3-tap fclk is too high */
+ if (cpu_is_omap34xx() && height > out_height &&
+ fclk > dispc_fclk_rate())
+ *five_taps = true;
+ }
+
+ if (width > (2048 >> *five_taps)) {
+ DSSERR("failed to set up scaling, fclk too low\n");
+ return -EINVAL;
+ }
+
+ if (*five_taps)
+ fclk = calc_fclk_five_taps(channel, width, height,
+ out_width, out_height, color_mode);
+
+ DSSDBG("required fclk rate = %lu Hz\n", fclk);
+ DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate());
+
+ if (!fclk || fclk > dispc_fclk_rate()) {
+ DSSERR("failed to set up scaling, "
+ "required fclk rate = %lu Hz, "
+ "current fclk rate = %lu Hz\n",
+ fclk, dispc_fclk_rate());
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
bool ilace, enum omap_channel channel, bool replication,
u32 fifo_low, u32 fifo_high)
{
- const int maxdownscale = cpu_is_omap34xx() ? 4 : 2;
- bool five_taps = 0;
+ struct omap_overlay *ovl = omap_dss_get_overlay(plane);
+ bool five_taps = false;
bool fieldmode = 0;
- int cconv = 0;
+ int r, cconv = 0;
unsigned offset0, offset1;
s32 row_inc;
s32 pix_inc;
if (!dss_feat_color_mode_supported(plane, oi->color_mode))
return -EINVAL;
- if (plane == OMAP_DSS_GFX) {
- if (oi->width != oi->out_width || oi->height != oi->out_height)
- return -EINVAL;
- } else {
- /* video plane */
-
- unsigned long fclk = 0;
-
- if (oi->out_width < oi->width / maxdownscale ||
- oi->out_width > oi->width * 8)
- return -EINVAL;
-
- if (oi->out_height < oi->height / maxdownscale ||
- oi->out_height > oi->height * 8)
- return -EINVAL;
-
- if (oi->color_mode == OMAP_DSS_COLOR_YUV2 ||
- oi->color_mode == OMAP_DSS_COLOR_UYVY ||
- oi->color_mode == OMAP_DSS_COLOR_NV12)
- cconv = 1;
-
- /* Must use 5-tap filter? */
- five_taps = oi->height > oi->out_height * 2;
-
- if (!five_taps) {
- fclk = calc_fclk(channel, oi->width, oi->height,
- oi->out_width, oi->out_height);
-
- /* Try 5-tap filter if 3-tap fclk is too high */
- if (cpu_is_omap34xx() && oi->height > oi->out_height &&
- fclk > dispc_fclk_rate())
- five_taps = true;
- }
-
- if (oi->width > (2048 >> five_taps)) {
- DSSERR("failed to set up scaling, fclk too low\n");
- return -EINVAL;
- }
-
- if (five_taps)
- fclk = calc_fclk_five_taps(channel, oi->width,
- oi->height, oi->out_width,
- oi->out_height, oi->color_mode);
-
- DSSDBG("required fclk rate = %lu Hz\n", fclk);
- DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate());
+ r = dispc_ovl_calc_scaling(plane, channel, oi->width, oi->height,
+ oi->out_width, oi->out_height, oi->color_mode,
+ &five_taps);
+ if (r)
+ return r;
- if (!fclk || fclk > dispc_fclk_rate()) {
- DSSERR("failed to set up scaling, "
- "required fclk rate = %lu Hz, "
- "current fclk rate = %lu Hz\n",
- fclk, dispc_fclk_rate());
- return -EINVAL;
- }
- }
+ if (oi->color_mode == OMAP_DSS_COLOR_YUV2 ||
+ oi->color_mode == OMAP_DSS_COLOR_UYVY ||
+ oi->color_mode == OMAP_DSS_COLOR_NV12)
+ cconv = 1;
if (ilace && !fieldmode) {
/*
dispc_ovl_set_pic_size(plane, oi->width, oi->height);
- if (plane != OMAP_DSS_GFX) {
+ if (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) {
dispc_ovl_set_scaling(plane, oi->width, oi->height,
oi->out_width, oi->out_height,
ilace, five_taps, fieldmode,
dispc_ovl_set_rotation_attrs(plane, oi->rotation, oi->mirror,
oi->color_mode);
+ dispc_ovl_set_zorder(plane, oi->zorder);
dispc_ovl_set_pre_mult_alpha(plane, oi->pre_mult_alpha);
dispc_ovl_setup_global_alpha(plane, oi->global_alpha);
else /* OMAP_DSS_CHANNEL_LCD2 */
REG_FLD_MOD(DISPC_CONFIG2, enable, 10, 10);
}
-void dispc_mgr_enable_alpha_blending(enum omap_channel ch, bool enable)
+
+void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, bool enable)
{
- if (!dss_has_feature(FEAT_GLOBAL_ALPHA))
+ if (!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER))
return;
if (ch == OMAP_DSS_CHANNEL_LCD)
REG_FLD_MOD(DISPC_CONFIG, enable, 18, 18);
else if (ch == OMAP_DSS_CHANNEL_DIGIT)
REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19);
- else /* OMAP_DSS_CHANNEL_LCD2 */
- REG_FLD_MOD(DISPC_CONFIG2, enable, 18, 18);
}
-bool dispc_mgr_alpha_blending_enabled(enum omap_channel ch)
+
+bool dispc_mgr_alpha_fixed_zorder_enabled(enum omap_channel ch)
{
bool enabled;
- if (!dss_has_feature(FEAT_GLOBAL_ALPHA))
+ if (!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER))
return false;
if (ch == OMAP_DSS_CHANNEL_LCD)
enabled = REG_GET(DISPC_CONFIG, 18, 18);
else if (ch == OMAP_DSS_CHANNEL_DIGIT)
enabled = REG_GET(DISPC_CONFIG, 19, 19);
- else if (ch == OMAP_DSS_CHANNEL_LCD2)
- enabled = REG_GET(DISPC_CONFIG2, 18, 18);
else
BUG();
return enabled;
}
-
bool dispc_mgr_trans_key_enabled(enum omap_channel ch)
{
bool enabled;
PIS(VID1_END_WIN);
PIS(VID2_FIFO_UNDERFLOW);
PIS(VID2_END_WIN);
+ if (dss_feat_get_num_ovls() > 3) {
+ PIS(VID3_FIFO_UNDERFLOW);
+ PIS(VID3_END_WIN);
+ }
PIS(SYNC_LOST);
PIS(SYNC_LOST_DIGIT);
PIS(WAKEUP);
[OMAP_DSS_GFX] = "GFX",
[OMAP_DSS_VIDEO1] = "VID1",
[OMAP_DSS_VIDEO2] = "VID2",
+ [OMAP_DSS_VIDEO3] = "VID3",
};
const char **p_names;
DUMPREG(DISPC_CAPABLE);
DUMPREG(DISPC_LINE_STATUS);
DUMPREG(DISPC_LINE_NUMBER);
- if (dss_has_feature(FEAT_GLOBAL_ALPHA))
+ if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER) ||
+ dss_has_feature(FEAT_ALPHA_FREE_ZORDER))
DUMPREG(DISPC_GLOBAL_ALPHA);
if (dss_has_feature(FEAT_MGR_LCD2)) {
DUMPREG(DISPC_CONTROL2);
PIS(OCP_ERR);
PIS(VID1_FIFO_UNDERFLOW);
PIS(VID2_FIFO_UNDERFLOW);
+ if (dss_feat_get_num_ovls() > 3)
+ PIS(VID3_FIFO_UNDERFLOW);
PIS(SYNC_LOST);
PIS(SYNC_LOST_DIGIT);
if (dss_has_feature(FEAT_MGR_LCD2))
DISPC_IRQ_GFX_FIFO_UNDERFLOW,
DISPC_IRQ_VID1_FIFO_UNDERFLOW,
DISPC_IRQ_VID2_FIFO_UNDERFLOW,
+ DISPC_IRQ_VID3_FIFO_UNDERFLOW,
};
static const unsigned sync_lost_bits[] = {
dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR;
if (dss_has_feature(FEAT_MGR_LCD2))
dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2;
+ if (dss_feat_get_num_ovls() > 3)
+ dispc.irq_error_mask |= DISPC_IRQ_VID3_FIFO_UNDERFLOW;
/* there's SYNC_LOST_DIGIT waiting after enabling the DSS,
* so clear it */
dispc_read_plane_fifo_sizes();
dispc_configure_burst_sizes();
+
+ dispc_ovl_enable_zorder_planes();
}
/* DISPC HW IP initialisation */