|
@@ -248,11 +248,29 @@ static void _osd_set_rec601_attenuation(struct osd_state *sd,
|
|
osd_modify(sd, OSD_OSDWIN0MD_ATN0E,
|
|
osd_modify(sd, OSD_OSDWIN0MD_ATN0E,
|
|
enable ? OSD_OSDWIN0MD_ATN0E : 0,
|
|
enable ? OSD_OSDWIN0MD_ATN0E : 0,
|
|
OSD_OSDWIN0MD);
|
|
OSD_OSDWIN0MD);
|
|
|
|
+ if (sd->vpbe_type == VPBE_VERSION_1)
|
|
|
|
+ osd_modify(sd, OSD_OSDWIN0MD_ATN0E,
|
|
|
|
+ enable ? OSD_OSDWIN0MD_ATN0E : 0,
|
|
|
|
+ OSD_OSDWIN0MD);
|
|
|
|
+ else if ((sd->vpbe_type == VPBE_VERSION_3) ||
|
|
|
|
+ (sd->vpbe_type == VPBE_VERSION_2))
|
|
|
|
+ osd_modify(sd, OSD_EXTMODE_ATNOSD0EN,
|
|
|
|
+ enable ? OSD_EXTMODE_ATNOSD0EN : 0,
|
|
|
|
+ OSD_EXTMODE);
|
|
break;
|
|
break;
|
|
case OSDWIN_OSD1:
|
|
case OSDWIN_OSD1:
|
|
osd_modify(sd, OSD_OSDWIN1MD_ATN1E,
|
|
osd_modify(sd, OSD_OSDWIN1MD_ATN1E,
|
|
enable ? OSD_OSDWIN1MD_ATN1E : 0,
|
|
enable ? OSD_OSDWIN1MD_ATN1E : 0,
|
|
OSD_OSDWIN1MD);
|
|
OSD_OSDWIN1MD);
|
|
|
|
+ if (sd->vpbe_type == VPBE_VERSION_1)
|
|
|
|
+ osd_modify(sd, OSD_OSDWIN1MD_ATN1E,
|
|
|
|
+ enable ? OSD_OSDWIN1MD_ATN1E : 0,
|
|
|
|
+ OSD_OSDWIN1MD);
|
|
|
|
+ else if ((sd->vpbe_type == VPBE_VERSION_3) ||
|
|
|
|
+ (sd->vpbe_type == VPBE_VERSION_2))
|
|
|
|
+ osd_modify(sd, OSD_EXTMODE_ATNOSD1EN,
|
|
|
|
+ enable ? OSD_EXTMODE_ATNOSD1EN : 0,
|
|
|
|
+ OSD_EXTMODE);
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -273,15 +291,71 @@ static void _osd_set_blending_factor(struct osd_state *sd,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void _osd_enable_rgb888_pixblend(struct osd_state *sd,
|
|
|
|
+ enum osd_win_layer osdwin)
|
|
|
|
+{
|
|
|
|
+
|
|
|
|
+ osd_modify(sd, OSD_MISCCTL_BLDSEL, 0, OSD_MISCCTL);
|
|
|
|
+ switch (osdwin) {
|
|
|
|
+ case OSDWIN_OSD0:
|
|
|
|
+ osd_modify(sd, OSD_EXTMODE_OSD0BLDCHR,
|
|
|
|
+ OSD_EXTMODE_OSD0BLDCHR, OSD_EXTMODE);
|
|
|
|
+ break;
|
|
|
|
+ case OSDWIN_OSD1:
|
|
|
|
+ osd_modify(sd, OSD_EXTMODE_OSD1BLDCHR,
|
|
|
|
+ OSD_EXTMODE_OSD1BLDCHR, OSD_EXTMODE);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
static void _osd_enable_color_key(struct osd_state *sd,
|
|
static void _osd_enable_color_key(struct osd_state *sd,
|
|
enum osd_win_layer osdwin,
|
|
enum osd_win_layer osdwin,
|
|
unsigned colorkey,
|
|
unsigned colorkey,
|
|
enum osd_pix_format pixfmt)
|
|
enum osd_pix_format pixfmt)
|
|
{
|
|
{
|
|
switch (pixfmt) {
|
|
switch (pixfmt) {
|
|
|
|
+ case PIXFMT_1BPP:
|
|
|
|
+ case PIXFMT_2BPP:
|
|
|
|
+ case PIXFMT_4BPP:
|
|
|
|
+ case PIXFMT_8BPP:
|
|
|
|
+ if (sd->vpbe_type == VPBE_VERSION_3) {
|
|
|
|
+ switch (osdwin) {
|
|
|
|
+ case OSDWIN_OSD0:
|
|
|
|
+ osd_modify(sd, OSD_TRANSPBMPIDX_BMP0,
|
|
|
|
+ colorkey <<
|
|
|
|
+ OSD_TRANSPBMPIDX_BMP0_SHIFT,
|
|
|
|
+ OSD_TRANSPBMPIDX);
|
|
|
|
+ break;
|
|
|
|
+ case OSDWIN_OSD1:
|
|
|
|
+ osd_modify(sd, OSD_TRANSPBMPIDX_BMP1,
|
|
|
|
+ colorkey <<
|
|
|
|
+ OSD_TRANSPBMPIDX_BMP1_SHIFT,
|
|
|
|
+ OSD_TRANSPBMPIDX);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
case PIXFMT_RGB565:
|
|
case PIXFMT_RGB565:
|
|
- osd_write(sd, colorkey & OSD_TRANSPVAL_RGBTRANS,
|
|
|
|
- OSD_TRANSPVAL);
|
|
|
|
|
|
+ if (sd->vpbe_type == VPBE_VERSION_1)
|
|
|
|
+ osd_write(sd, colorkey & OSD_TRANSPVAL_RGBTRANS,
|
|
|
|
+ OSD_TRANSPVAL);
|
|
|
|
+ else if (sd->vpbe_type == VPBE_VERSION_3)
|
|
|
|
+ osd_write(sd, colorkey & OSD_TRANSPVALL_RGBL,
|
|
|
|
+ OSD_TRANSPVALL);
|
|
|
|
+ break;
|
|
|
|
+ case PIXFMT_YCbCrI:
|
|
|
|
+ case PIXFMT_YCrCbI:
|
|
|
|
+ if (sd->vpbe_type == VPBE_VERSION_3)
|
|
|
|
+ osd_modify(sd, OSD_TRANSPVALU_Y, colorkey,
|
|
|
|
+ OSD_TRANSPVALU);
|
|
|
|
+ break;
|
|
|
|
+ case PIXFMT_RGB888:
|
|
|
|
+ if (sd->vpbe_type == VPBE_VERSION_3) {
|
|
|
|
+ osd_write(sd, colorkey & OSD_TRANSPVALL_RGBL,
|
|
|
|
+ OSD_TRANSPVALL);
|
|
|
|
+ osd_modify(sd, OSD_TRANSPVALU_RGBU, colorkey >> 16,
|
|
|
|
+ OSD_TRANSPVALU);
|
|
|
|
+ }
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
break;
|
|
break;
|
|
@@ -470,23 +544,188 @@ static int osd_enable_layer(struct osd_state *sd, enum osd_layer layer,
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#define OSD_SRC_ADDR_HIGH4 0x7800000
|
|
|
|
+#define OSD_SRC_ADDR_HIGH7 0x7F0000
|
|
|
|
+#define OSD_SRCADD_OFSET_SFT 23
|
|
|
|
+#define OSD_SRCADD_ADD_SFT 16
|
|
|
|
+#define OSD_WINADL_MASK 0xFFFF
|
|
|
|
+#define OSD_WINOFST_MASK 0x1000
|
|
|
|
+#define VPBE_REG_BASE 0x80000000
|
|
|
|
+
|
|
static void _osd_start_layer(struct osd_state *sd, enum osd_layer layer,
|
|
static void _osd_start_layer(struct osd_state *sd, enum osd_layer layer,
|
|
unsigned long fb_base_phys,
|
|
unsigned long fb_base_phys,
|
|
unsigned long cbcr_ofst)
|
|
unsigned long cbcr_ofst)
|
|
{
|
|
{
|
|
- switch (layer) {
|
|
|
|
- case WIN_OSD0:
|
|
|
|
- osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN0ADR);
|
|
|
|
- break;
|
|
|
|
- case WIN_VID0:
|
|
|
|
- osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN0ADR);
|
|
|
|
- break;
|
|
|
|
- case WIN_OSD1:
|
|
|
|
- osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN1ADR);
|
|
|
|
- break;
|
|
|
|
- case WIN_VID1:
|
|
|
|
- osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN1ADR);
|
|
|
|
- break;
|
|
|
|
|
|
+
|
|
|
|
+ if (sd->vpbe_type == VPBE_VERSION_1) {
|
|
|
|
+ switch (layer) {
|
|
|
|
+ case WIN_OSD0:
|
|
|
|
+ osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN0ADR);
|
|
|
|
+ break;
|
|
|
|
+ case WIN_VID0:
|
|
|
|
+ osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN0ADR);
|
|
|
|
+ break;
|
|
|
|
+ case WIN_OSD1:
|
|
|
|
+ osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN1ADR);
|
|
|
|
+ break;
|
|
|
|
+ case WIN_VID1:
|
|
|
|
+ osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN1ADR);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ } else if (sd->vpbe_type == VPBE_VERSION_3) {
|
|
|
|
+ unsigned long fb_offset_32 =
|
|
|
|
+ (fb_base_phys - VPBE_REG_BASE) >> 5;
|
|
|
|
+
|
|
|
|
+ switch (layer) {
|
|
|
|
+ case WIN_OSD0:
|
|
|
|
+ osd_modify(sd, OSD_OSDWINADH_O0AH,
|
|
|
|
+ fb_offset_32 >> (OSD_SRCADD_ADD_SFT -
|
|
|
|
+ OSD_OSDWINADH_O0AH_SHIFT),
|
|
|
|
+ OSD_OSDWINADH);
|
|
|
|
+ osd_write(sd, fb_offset_32 & OSD_OSDWIN0ADL_O0AL,
|
|
|
|
+ OSD_OSDWIN0ADL);
|
|
|
|
+ break;
|
|
|
|
+ case WIN_VID0:
|
|
|
|
+ osd_modify(sd, OSD_VIDWINADH_V0AH,
|
|
|
|
+ fb_offset_32 >> (OSD_SRCADD_ADD_SFT -
|
|
|
|
+ OSD_VIDWINADH_V0AH_SHIFT),
|
|
|
|
+ OSD_VIDWINADH);
|
|
|
|
+ osd_write(sd, fb_offset_32 & OSD_VIDWIN0ADL_V0AL,
|
|
|
|
+ OSD_VIDWIN0ADL);
|
|
|
|
+ break;
|
|
|
|
+ case WIN_OSD1:
|
|
|
|
+ osd_modify(sd, OSD_OSDWINADH_O1AH,
|
|
|
|
+ fb_offset_32 >> (OSD_SRCADD_ADD_SFT -
|
|
|
|
+ OSD_OSDWINADH_O1AH_SHIFT),
|
|
|
|
+ OSD_OSDWINADH);
|
|
|
|
+ osd_write(sd, fb_offset_32 & OSD_OSDWIN1ADL_O1AL,
|
|
|
|
+ OSD_OSDWIN1ADL);
|
|
|
|
+ break;
|
|
|
|
+ case WIN_VID1:
|
|
|
|
+ osd_modify(sd, OSD_VIDWINADH_V1AH,
|
|
|
|
+ fb_offset_32 >> (OSD_SRCADD_ADD_SFT -
|
|
|
|
+ OSD_VIDWINADH_V1AH_SHIFT),
|
|
|
|
+ OSD_VIDWINADH);
|
|
|
|
+ osd_write(sd, fb_offset_32 & OSD_VIDWIN1ADL_V1AL,
|
|
|
|
+ OSD_VIDWIN1ADL);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ } else if (sd->vpbe_type == VPBE_VERSION_2) {
|
|
|
|
+ struct osd_window_state *win = &sd->win[layer];
|
|
|
|
+ unsigned long fb_offset_32, cbcr_offset_32;
|
|
|
|
+
|
|
|
|
+ fb_offset_32 = fb_base_phys - VPBE_REG_BASE;
|
|
|
|
+ if (cbcr_ofst)
|
|
|
|
+ cbcr_offset_32 = cbcr_ofst;
|
|
|
|
+ else
|
|
|
|
+ cbcr_offset_32 = win->lconfig.line_length *
|
|
|
|
+ win->lconfig.ysize;
|
|
|
|
+ cbcr_offset_32 += fb_offset_32;
|
|
|
|
+ fb_offset_32 = fb_offset_32 >> 5;
|
|
|
|
+ cbcr_offset_32 = cbcr_offset_32 >> 5;
|
|
|
|
+ /*
|
|
|
|
+ * DM365: start address is 27-bit long address b26 - b23 are
|
|
|
|
+ * in offset register b12 - b9, and * bit 26 has to be '1'
|
|
|
|
+ */
|
|
|
|
+ if (win->lconfig.pixfmt == PIXFMT_NV12) {
|
|
|
|
+ switch (layer) {
|
|
|
|
+ case WIN_VID0:
|
|
|
|
+ case WIN_VID1:
|
|
|
|
+ /* Y is in VID0 */
|
|
|
|
+ osd_modify(sd, OSD_VIDWIN0OFST_V0AH,
|
|
|
|
+ ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
|
|
|
|
+ (OSD_SRCADD_OFSET_SFT -
|
|
|
|
+ OSD_WINOFST_AH_SHIFT)) |
|
|
|
|
+ OSD_WINOFST_MASK, OSD_VIDWIN0OFST);
|
|
|
|
+ osd_modify(sd, OSD_VIDWINADH_V0AH,
|
|
|
|
+ (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
|
|
|
|
+ (OSD_SRCADD_ADD_SFT -
|
|
|
|
+ OSD_VIDWINADH_V0AH_SHIFT),
|
|
|
|
+ OSD_VIDWINADH);
|
|
|
|
+ osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
|
|
|
|
+ OSD_VIDWIN0ADL);
|
|
|
|
+ /* CbCr is in VID1 */
|
|
|
|
+ osd_modify(sd, OSD_VIDWIN1OFST_V1AH,
|
|
|
|
+ ((cbcr_offset_32 &
|
|
|
|
+ OSD_SRC_ADDR_HIGH4) >>
|
|
|
|
+ (OSD_SRCADD_OFSET_SFT -
|
|
|
|
+ OSD_WINOFST_AH_SHIFT)) |
|
|
|
|
+ OSD_WINOFST_MASK, OSD_VIDWIN1OFST);
|
|
|
|
+ osd_modify(sd, OSD_VIDWINADH_V1AH,
|
|
|
|
+ (cbcr_offset_32 &
|
|
|
|
+ OSD_SRC_ADDR_HIGH7) >>
|
|
|
|
+ (OSD_SRCADD_ADD_SFT -
|
|
|
|
+ OSD_VIDWINADH_V1AH_SHIFT),
|
|
|
|
+ OSD_VIDWINADH);
|
|
|
|
+ osd_write(sd, cbcr_offset_32 & OSD_WINADL_MASK,
|
|
|
|
+ OSD_VIDWIN1ADL);
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ switch (layer) {
|
|
|
|
+ case WIN_OSD0:
|
|
|
|
+ osd_modify(sd, OSD_OSDWIN0OFST_O0AH,
|
|
|
|
+ ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
|
|
|
|
+ (OSD_SRCADD_OFSET_SFT -
|
|
|
|
+ OSD_WINOFST_AH_SHIFT)) | OSD_WINOFST_MASK,
|
|
|
|
+ OSD_OSDWIN0OFST);
|
|
|
|
+ osd_modify(sd, OSD_OSDWINADH_O0AH,
|
|
|
|
+ (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
|
|
|
|
+ (OSD_SRCADD_ADD_SFT -
|
|
|
|
+ OSD_OSDWINADH_O0AH_SHIFT), OSD_OSDWINADH);
|
|
|
|
+ osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
|
|
|
|
+ OSD_OSDWIN0ADL);
|
|
|
|
+ break;
|
|
|
|
+ case WIN_VID0:
|
|
|
|
+ if (win->lconfig.pixfmt != PIXFMT_NV12) {
|
|
|
|
+ osd_modify(sd, OSD_VIDWIN0OFST_V0AH,
|
|
|
|
+ ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
|
|
|
|
+ (OSD_SRCADD_OFSET_SFT -
|
|
|
|
+ OSD_WINOFST_AH_SHIFT)) |
|
|
|
|
+ OSD_WINOFST_MASK, OSD_VIDWIN0OFST);
|
|
|
|
+ osd_modify(sd, OSD_VIDWINADH_V0AH,
|
|
|
|
+ (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
|
|
|
|
+ (OSD_SRCADD_ADD_SFT -
|
|
|
|
+ OSD_VIDWINADH_V0AH_SHIFT),
|
|
|
|
+ OSD_VIDWINADH);
|
|
|
|
+ osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
|
|
|
|
+ OSD_VIDWIN0ADL);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ case WIN_OSD1:
|
|
|
|
+ osd_modify(sd, OSD_OSDWIN1OFST_O1AH,
|
|
|
|
+ ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
|
|
|
|
+ (OSD_SRCADD_OFSET_SFT -
|
|
|
|
+ OSD_WINOFST_AH_SHIFT)) | OSD_WINOFST_MASK,
|
|
|
|
+ OSD_OSDWIN1OFST);
|
|
|
|
+ osd_modify(sd, OSD_OSDWINADH_O1AH,
|
|
|
|
+ (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
|
|
|
|
+ (OSD_SRCADD_ADD_SFT -
|
|
|
|
+ OSD_OSDWINADH_O1AH_SHIFT),
|
|
|
|
+ OSD_OSDWINADH);
|
|
|
|
+ osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
|
|
|
|
+ OSD_OSDWIN1ADL);
|
|
|
|
+ break;
|
|
|
|
+ case WIN_VID1:
|
|
|
|
+ if (win->lconfig.pixfmt != PIXFMT_NV12) {
|
|
|
|
+ osd_modify(sd, OSD_VIDWIN1OFST_V1AH,
|
|
|
|
+ ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
|
|
|
|
+ (OSD_SRCADD_OFSET_SFT -
|
|
|
|
+ OSD_WINOFST_AH_SHIFT)) |
|
|
|
|
+ OSD_WINOFST_MASK, OSD_VIDWIN1OFST);
|
|
|
|
+ osd_modify(sd, OSD_VIDWINADH_V1AH,
|
|
|
|
+ (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
|
|
|
|
+ (OSD_SRCADD_ADD_SFT -
|
|
|
|
+ OSD_VIDWINADH_V1AH_SHIFT),
|
|
|
|
+ OSD_VIDWINADH);
|
|
|
|
+ osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
|
|
|
|
+ OSD_VIDWIN1ADL);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -545,7 +784,7 @@ static int try_layer_config(struct osd_state *sd, enum osd_layer layer,
|
|
{
|
|
{
|
|
struct osd_state *osd = sd;
|
|
struct osd_state *osd = sd;
|
|
struct osd_window_state *win = &osd->win[layer];
|
|
struct osd_window_state *win = &osd->win[layer];
|
|
- int bad_config;
|
|
|
|
|
|
+ int bad_config = 0;
|
|
|
|
|
|
/* verify that the pixel format is compatible with the layer */
|
|
/* verify that the pixel format is compatible with the layer */
|
|
switch (lconfig->pixfmt) {
|
|
switch (lconfig->pixfmt) {
|
|
@@ -554,17 +793,25 @@ static int try_layer_config(struct osd_state *sd, enum osd_layer layer,
|
|
case PIXFMT_4BPP:
|
|
case PIXFMT_4BPP:
|
|
case PIXFMT_8BPP:
|
|
case PIXFMT_8BPP:
|
|
case PIXFMT_RGB565:
|
|
case PIXFMT_RGB565:
|
|
- bad_config = !is_osd_win(layer);
|
|
|
|
|
|
+ if (osd->vpbe_type == VPBE_VERSION_1)
|
|
|
|
+ bad_config = !is_vid_win(layer);
|
|
break;
|
|
break;
|
|
case PIXFMT_YCbCrI:
|
|
case PIXFMT_YCbCrI:
|
|
case PIXFMT_YCrCbI:
|
|
case PIXFMT_YCrCbI:
|
|
bad_config = !is_vid_win(layer);
|
|
bad_config = !is_vid_win(layer);
|
|
break;
|
|
break;
|
|
case PIXFMT_RGB888:
|
|
case PIXFMT_RGB888:
|
|
- bad_config = !is_vid_win(layer);
|
|
|
|
|
|
+ if (osd->vpbe_type == VPBE_VERSION_1)
|
|
|
|
+ bad_config = !is_vid_win(layer);
|
|
|
|
+ else if ((osd->vpbe_type == VPBE_VERSION_3) ||
|
|
|
|
+ (osd->vpbe_type == VPBE_VERSION_2))
|
|
|
|
+ bad_config = !is_osd_win(layer);
|
|
break;
|
|
break;
|
|
case PIXFMT_NV12:
|
|
case PIXFMT_NV12:
|
|
- bad_config = 1;
|
|
|
|
|
|
+ if (osd->vpbe_type != VPBE_VERSION_2)
|
|
|
|
+ bad_config = 1;
|
|
|
|
+ else
|
|
|
|
+ bad_config = is_osd_win(layer);
|
|
break;
|
|
break;
|
|
case PIXFMT_OSD_ATTR:
|
|
case PIXFMT_OSD_ATTR:
|
|
bad_config = (layer != WIN_OSD1);
|
|
bad_config = (layer != WIN_OSD1);
|
|
@@ -584,7 +831,8 @@ static int try_layer_config(struct osd_state *sd, enum osd_layer layer,
|
|
|
|
|
|
/* DM6446: */
|
|
/* DM6446: */
|
|
/* only one OSD window at a time can use RGB pixel formats */
|
|
/* only one OSD window at a time can use RGB pixel formats */
|
|
- if (is_osd_win(layer) && is_rgb_pixfmt(lconfig->pixfmt)) {
|
|
|
|
|
|
+ if ((osd->vpbe_type == VPBE_VERSION_1) &&
|
|
|
|
+ is_osd_win(layer) && is_rgb_pixfmt(lconfig->pixfmt)) {
|
|
enum osd_pix_format pixfmt;
|
|
enum osd_pix_format pixfmt;
|
|
if (layer == WIN_OSD0)
|
|
if (layer == WIN_OSD0)
|
|
pixfmt = osd->win[WIN_OSD1].lconfig.pixfmt;
|
|
pixfmt = osd->win[WIN_OSD1].lconfig.pixfmt;
|
|
@@ -602,7 +850,8 @@ static int try_layer_config(struct osd_state *sd, enum osd_layer layer,
|
|
}
|
|
}
|
|
|
|
|
|
/* DM6446: only one video window at a time can use RGB888 */
|
|
/* DM6446: only one video window at a time can use RGB888 */
|
|
- if (is_vid_win(layer) && lconfig->pixfmt == PIXFMT_RGB888) {
|
|
|
|
|
|
+ if ((osd->vpbe_type == VPBE_VERSION_1) && is_vid_win(layer) &&
|
|
|
|
+ lconfig->pixfmt == PIXFMT_RGB888) {
|
|
enum osd_pix_format pixfmt;
|
|
enum osd_pix_format pixfmt;
|
|
|
|
|
|
if (layer == WIN_VID0)
|
|
if (layer == WIN_VID0)
|
|
@@ -652,7 +901,8 @@ static void _osd_disable_vid_rgb888(struct osd_state *sd)
|
|
* The caller must ensure that neither video window is currently
|
|
* The caller must ensure that neither video window is currently
|
|
* configured for RGB888 pixel format.
|
|
* configured for RGB888 pixel format.
|
|
*/
|
|
*/
|
|
- osd_clear(sd, OSD_MISCCTL_RGBEN, OSD_MISCCTL);
|
|
|
|
|
|
+ if (sd->vpbe_type == VPBE_VERSION_1)
|
|
|
|
+ osd_clear(sd, OSD_MISCCTL_RGBEN, OSD_MISCCTL);
|
|
}
|
|
}
|
|
|
|
|
|
static void _osd_enable_vid_rgb888(struct osd_state *sd,
|
|
static void _osd_enable_vid_rgb888(struct osd_state *sd,
|
|
@@ -665,13 +915,14 @@ static void _osd_enable_vid_rgb888(struct osd_state *sd,
|
|
* currently configured for RGB888 pixel format, as this routine will
|
|
* currently configured for RGB888 pixel format, as this routine will
|
|
* disable RGB888 pixel format for the other window.
|
|
* disable RGB888 pixel format for the other window.
|
|
*/
|
|
*/
|
|
- if (layer == WIN_VID0) {
|
|
|
|
- osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN,
|
|
|
|
- OSD_MISCCTL_RGBEN, OSD_MISCCTL);
|
|
|
|
- } else if (layer == WIN_VID1) {
|
|
|
|
- osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN,
|
|
|
|
- OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN,
|
|
|
|
- OSD_MISCCTL);
|
|
|
|
|
|
+ if (sd->vpbe_type == VPBE_VERSION_1) {
|
|
|
|
+ if (layer == WIN_VID0)
|
|
|
|
+ osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN,
|
|
|
|
+ OSD_MISCCTL_RGBEN, OSD_MISCCTL);
|
|
|
|
+ else if (layer == WIN_VID1)
|
|
|
|
+ osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN,
|
|
|
|
+ OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN,
|
|
|
|
+ OSD_MISCCTL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -697,9 +948,30 @@ static void _osd_set_layer_config(struct osd_state *sd, enum osd_layer layer,
|
|
|
|
|
|
switch (layer) {
|
|
switch (layer) {
|
|
case WIN_OSD0:
|
|
case WIN_OSD0:
|
|
- winmd_mask |= OSD_OSDWIN0MD_RGB0E;
|
|
|
|
- if (lconfig->pixfmt == PIXFMT_RGB565)
|
|
|
|
- winmd |= OSD_OSDWIN0MD_RGB0E;
|
|
|
|
|
|
+ if (sd->vpbe_type == VPBE_VERSION_1) {
|
|
|
|
+ winmd_mask |= OSD_OSDWIN0MD_RGB0E;
|
|
|
|
+ if (lconfig->pixfmt == PIXFMT_RGB565)
|
|
|
|
+ winmd |= OSD_OSDWIN0MD_RGB0E;
|
|
|
|
+ } else if ((sd->vpbe_type == VPBE_VERSION_3) ||
|
|
|
|
+ (sd->vpbe_type == VPBE_VERSION_2)) {
|
|
|
|
+ winmd_mask |= OSD_OSDWIN0MD_BMP0MD;
|
|
|
|
+ switch (lconfig->pixfmt) {
|
|
|
|
+ case PIXFMT_RGB565:
|
|
|
|
+ winmd |= (1 <<
|
|
|
|
+ OSD_OSDWIN0MD_BMP0MD_SHIFT);
|
|
|
|
+ break;
|
|
|
|
+ case PIXFMT_RGB888:
|
|
|
|
+ winmd |= (2 << OSD_OSDWIN0MD_BMP0MD_SHIFT);
|
|
|
|
+ _osd_enable_rgb888_pixblend(sd, OSDWIN_OSD0);
|
|
|
|
+ break;
|
|
|
|
+ case PIXFMT_YCbCrI:
|
|
|
|
+ case PIXFMT_YCrCbI:
|
|
|
|
+ winmd |= (3 << OSD_OSDWIN0MD_BMP0MD_SHIFT);
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
winmd_mask |= OSD_OSDWIN0MD_BMW0 | OSD_OSDWIN0MD_OFF0;
|
|
winmd_mask |= OSD_OSDWIN0MD_BMW0 | OSD_OSDWIN0MD_OFF0;
|
|
|
|
|
|
@@ -749,12 +1021,59 @@ static void _osd_set_layer_config(struct osd_state *sd, enum osd_layer layer,
|
|
* For YUV420P format the register contents are
|
|
* For YUV420P format the register contents are
|
|
* duplicated in both VID registers
|
|
* duplicated in both VID registers
|
|
*/
|
|
*/
|
|
|
|
+ if ((sd->vpbe_type == VPBE_VERSION_2) &&
|
|
|
|
+ (lconfig->pixfmt == PIXFMT_NV12)) {
|
|
|
|
+ /* other window also */
|
|
|
|
+ if (lconfig->interlaced) {
|
|
|
|
+ winmd_mask |= OSD_VIDWINMD_VFF1;
|
|
|
|
+ winmd |= OSD_VIDWINMD_VFF1;
|
|
|
|
+ osd_modify(sd, winmd_mask, winmd,
|
|
|
|
+ OSD_VIDWINMD);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ osd_modify(sd, OSD_MISCCTL_S420D,
|
|
|
|
+ OSD_MISCCTL_S420D, OSD_MISCCTL);
|
|
|
|
+ osd_write(sd, lconfig->line_length >> 5,
|
|
|
|
+ OSD_VIDWIN1OFST);
|
|
|
|
+ osd_write(sd, lconfig->xpos, OSD_VIDWIN1XP);
|
|
|
|
+ osd_write(sd, lconfig->xsize, OSD_VIDWIN1XL);
|
|
|
|
+ /*
|
|
|
|
+ * if NV21 pixfmt and line length not 32B
|
|
|
|
+ * aligned (e.g. NTSC), Need to set window
|
|
|
|
+ * X pixel size to be 32B aligned as well
|
|
|
|
+ */
|
|
|
|
+ if (lconfig->xsize % 32) {
|
|
|
|
+ osd_write(sd,
|
|
|
|
+ ((lconfig->xsize + 31) & ~31),
|
|
|
|
+ OSD_VIDWIN1XL);
|
|
|
|
+ osd_write(sd,
|
|
|
|
+ ((lconfig->xsize + 31) & ~31),
|
|
|
|
+ OSD_VIDWIN0XL);
|
|
|
|
+ }
|
|
|
|
+ } else if ((sd->vpbe_type == VPBE_VERSION_2) &&
|
|
|
|
+ (lconfig->pixfmt != PIXFMT_NV12)) {
|
|
|
|
+ osd_modify(sd, OSD_MISCCTL_S420D, ~OSD_MISCCTL_S420D,
|
|
|
|
+ OSD_MISCCTL);
|
|
|
|
+ }
|
|
|
|
+
|
|
if (lconfig->interlaced) {
|
|
if (lconfig->interlaced) {
|
|
osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN0YP);
|
|
osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN0YP);
|
|
osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN0YL);
|
|
osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN0YL);
|
|
|
|
+ if ((sd->vpbe_type == VPBE_VERSION_2) &&
|
|
|
|
+ lconfig->pixfmt == PIXFMT_NV12) {
|
|
|
|
+ osd_write(sd, lconfig->ypos >> 1,
|
|
|
|
+ OSD_VIDWIN1YP);
|
|
|
|
+ osd_write(sd, lconfig->ysize >> 1,
|
|
|
|
+ OSD_VIDWIN1YL);
|
|
|
|
+ }
|
|
} else {
|
|
} else {
|
|
osd_write(sd, lconfig->ypos, OSD_VIDWIN0YP);
|
|
osd_write(sd, lconfig->ypos, OSD_VIDWIN0YP);
|
|
osd_write(sd, lconfig->ysize, OSD_VIDWIN0YL);
|
|
osd_write(sd, lconfig->ysize, OSD_VIDWIN0YL);
|
|
|
|
+ if ((sd->vpbe_type == VPBE_VERSION_2) &&
|
|
|
|
+ lconfig->pixfmt == PIXFMT_NV12) {
|
|
|
|
+ osd_write(sd, lconfig->ypos, OSD_VIDWIN1YP);
|
|
|
|
+ osd_write(sd, lconfig->ysize, OSD_VIDWIN1YL);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
case WIN_OSD1:
|
|
case WIN_OSD1:
|
|
@@ -764,14 +1083,43 @@ static void _osd_set_layer_config(struct osd_state *sd, enum osd_layer layer,
|
|
* attribute mode to a normal mode.
|
|
* attribute mode to a normal mode.
|
|
*/
|
|
*/
|
|
if (lconfig->pixfmt == PIXFMT_OSD_ATTR) {
|
|
if (lconfig->pixfmt == PIXFMT_OSD_ATTR) {
|
|
- winmd_mask |=
|
|
|
|
- OSD_OSDWIN1MD_ATN1E | OSD_OSDWIN1MD_RGB1E |
|
|
|
|
- OSD_OSDWIN1MD_CLUTS1 |
|
|
|
|
- OSD_OSDWIN1MD_BLND1 | OSD_OSDWIN1MD_TE1;
|
|
|
|
|
|
+ if (sd->vpbe_type == VPBE_VERSION_1) {
|
|
|
|
+ winmd_mask |= OSD_OSDWIN1MD_ATN1E |
|
|
|
|
+ OSD_OSDWIN1MD_RGB1E | OSD_OSDWIN1MD_CLUTS1 |
|
|
|
|
+ OSD_OSDWIN1MD_BLND1 | OSD_OSDWIN1MD_TE1;
|
|
|
|
+ } else {
|
|
|
|
+ winmd_mask |= OSD_OSDWIN1MD_BMP1MD |
|
|
|
|
+ OSD_OSDWIN1MD_CLUTS1 | OSD_OSDWIN1MD_BLND1 |
|
|
|
|
+ OSD_OSDWIN1MD_TE1;
|
|
|
|
+ }
|
|
} else {
|
|
} else {
|
|
- winmd_mask |= OSD_OSDWIN1MD_RGB1E;
|
|
|
|
- if (lconfig->pixfmt == PIXFMT_RGB565)
|
|
|
|
- winmd |= OSD_OSDWIN1MD_RGB1E;
|
|
|
|
|
|
+ if (sd->vpbe_type == VPBE_VERSION_1) {
|
|
|
|
+ winmd_mask |= OSD_OSDWIN1MD_RGB1E;
|
|
|
|
+ if (lconfig->pixfmt == PIXFMT_RGB565)
|
|
|
|
+ winmd |= OSD_OSDWIN1MD_RGB1E;
|
|
|
|
+ } else if ((sd->vpbe_type == VPBE_VERSION_3)
|
|
|
|
+ || (sd->vpbe_type == VPBE_VERSION_2)) {
|
|
|
|
+ winmd_mask |= OSD_OSDWIN1MD_BMP1MD;
|
|
|
|
+ switch (lconfig->pixfmt) {
|
|
|
|
+ case PIXFMT_RGB565:
|
|
|
|
+ winmd |=
|
|
|
|
+ (1 << OSD_OSDWIN1MD_BMP1MD_SHIFT);
|
|
|
|
+ break;
|
|
|
|
+ case PIXFMT_RGB888:
|
|
|
|
+ winmd |=
|
|
|
|
+ (2 << OSD_OSDWIN1MD_BMP1MD_SHIFT);
|
|
|
|
+ _osd_enable_rgb888_pixblend(sd,
|
|
|
|
+ OSDWIN_OSD1);
|
|
|
|
+ break;
|
|
|
|
+ case PIXFMT_YCbCrI:
|
|
|
|
+ case PIXFMT_YCrCbI:
|
|
|
|
+ winmd |=
|
|
|
|
+ (3 << OSD_OSDWIN1MD_BMP1MD_SHIFT);
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
winmd_mask |= OSD_OSDWIN1MD_BMW1;
|
|
winmd_mask |= OSD_OSDWIN1MD_BMW1;
|
|
switch (lconfig->pixfmt) {
|
|
switch (lconfig->pixfmt) {
|
|
@@ -822,15 +1170,45 @@ static void _osd_set_layer_config(struct osd_state *sd, enum osd_layer layer,
|
|
* For YUV420P format the register contents are
|
|
* For YUV420P format the register contents are
|
|
* duplicated in both VID registers
|
|
* duplicated in both VID registers
|
|
*/
|
|
*/
|
|
- osd_modify(sd, OSD_MISCCTL_S420D, ~OSD_MISCCTL_S420D,
|
|
|
|
- OSD_MISCCTL);
|
|
|
|
|
|
+ if (sd->vpbe_type == VPBE_VERSION_2) {
|
|
|
|
+ if (lconfig->pixfmt == PIXFMT_NV12) {
|
|
|
|
+ /* other window also */
|
|
|
|
+ if (lconfig->interlaced) {
|
|
|
|
+ winmd_mask |= OSD_VIDWINMD_VFF0;
|
|
|
|
+ winmd |= OSD_VIDWINMD_VFF0;
|
|
|
|
+ osd_modify(sd, winmd_mask, winmd,
|
|
|
|
+ OSD_VIDWINMD);
|
|
|
|
+ }
|
|
|
|
+ osd_modify(sd, OSD_MISCCTL_S420D,
|
|
|
|
+ OSD_MISCCTL_S420D, OSD_MISCCTL);
|
|
|
|
+ osd_write(sd, lconfig->line_length >> 5,
|
|
|
|
+ OSD_VIDWIN0OFST);
|
|
|
|
+ osd_write(sd, lconfig->xpos, OSD_VIDWIN0XP);
|
|
|
|
+ osd_write(sd, lconfig->xsize, OSD_VIDWIN0XL);
|
|
|
|
+ } else {
|
|
|
|
+ osd_modify(sd, OSD_MISCCTL_S420D,
|
|
|
|
+ ~OSD_MISCCTL_S420D, OSD_MISCCTL);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
if (lconfig->interlaced) {
|
|
if (lconfig->interlaced) {
|
|
osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN1YP);
|
|
osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN1YP);
|
|
osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN1YL);
|
|
osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN1YL);
|
|
|
|
+ if ((sd->vpbe_type == VPBE_VERSION_2) &&
|
|
|
|
+ lconfig->pixfmt == PIXFMT_NV12) {
|
|
|
|
+ osd_write(sd, lconfig->ypos >> 1,
|
|
|
|
+ OSD_VIDWIN0YP);
|
|
|
|
+ osd_write(sd, lconfig->ysize >> 1,
|
|
|
|
+ OSD_VIDWIN0YL);
|
|
|
|
+ }
|
|
} else {
|
|
} else {
|
|
osd_write(sd, lconfig->ypos, OSD_VIDWIN1YP);
|
|
osd_write(sd, lconfig->ypos, OSD_VIDWIN1YP);
|
|
osd_write(sd, lconfig->ysize, OSD_VIDWIN1YL);
|
|
osd_write(sd, lconfig->ysize, OSD_VIDWIN1YL);
|
|
|
|
+ if ((sd->vpbe_type == VPBE_VERSION_2) &&
|
|
|
|
+ lconfig->pixfmt == PIXFMT_NV12) {
|
|
|
|
+ osd_write(sd, lconfig->ypos, OSD_VIDWIN0YP);
|
|
|
|
+ osd_write(sd, lconfig->ysize, OSD_VIDWIN0YL);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
@@ -1089,6 +1467,11 @@ static void _osd_init(struct osd_state *sd)
|
|
osd_write(sd, 0, OSD_OSDWIN1MD);
|
|
osd_write(sd, 0, OSD_OSDWIN1MD);
|
|
osd_write(sd, 0, OSD_RECTCUR);
|
|
osd_write(sd, 0, OSD_RECTCUR);
|
|
osd_write(sd, 0, OSD_MISCCTL);
|
|
osd_write(sd, 0, OSD_MISCCTL);
|
|
|
|
+ if (sd->vpbe_type == VPBE_VERSION_3) {
|
|
|
|
+ osd_write(sd, 0, OSD_VBNDRY);
|
|
|
|
+ osd_write(sd, 0, OSD_EXTMODE);
|
|
|
|
+ osd_write(sd, OSD_MISCCTL_DMANG, OSD_MISCCTL);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
static void osd_set_left_margin(struct osd_state *sd, u32 val)
|
|
static void osd_set_left_margin(struct osd_state *sd, u32 val)
|
|
@@ -1110,6 +1493,14 @@ static int osd_initialize(struct osd_state *osd)
|
|
/* set default Cb/Cr order */
|
|
/* set default Cb/Cr order */
|
|
osd->yc_pixfmt = PIXFMT_YCbCrI;
|
|
osd->yc_pixfmt = PIXFMT_YCbCrI;
|
|
|
|
|
|
|
|
+ if (osd->vpbe_type == VPBE_VERSION_3) {
|
|
|
|
+ /*
|
|
|
|
+ * ROM CLUT1 on the DM355 is similar (identical?) to ROM CLUT0
|
|
|
|
+ * on the DM6446, so make ROM_CLUT1 the default on the DM355.
|
|
|
|
+ */
|
|
|
|
+ osd->rom_clut = ROM_CLUT1;
|
|
|
|
+ }
|
|
|
|
+
|
|
_osd_set_field_inversion(osd, osd->field_inversion);
|
|
_osd_set_field_inversion(osd, osd->field_inversion);
|
|
_osd_set_rom_clut(osd, osd->rom_clut);
|
|
_osd_set_rom_clut(osd, osd->rom_clut);
|
|
|
|
|