summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/zte/zx_vou.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/zte/zx_vou.c')
-rw-r--r--drivers/gpu/drm/zte/zx_vou.c36
1 files changed, 31 insertions, 5 deletions
diff --git a/drivers/gpu/drm/zte/zx_vou.c b/drivers/gpu/drm/zte/zx_vou.c
index b500c8dd0d9d..5fbd10b60ee5 100644
--- a/drivers/gpu/drm/zte/zx_vou.c
+++ b/drivers/gpu/drm/zte/zx_vou.c
@@ -23,6 +23,7 @@
#include <drm/drm_plane_helper.h>
#include <drm/drmP.h>
+#include "zx_common_regs.h"
#include "zx_drm_drv.h"
#include "zx_plane.h"
#include "zx_vou.h"
@@ -122,6 +123,8 @@ struct zx_crtc {
struct drm_plane *primary;
struct zx_vou_hw *vou;
void __iomem *chnreg;
+ void __iomem *chncsc;
+ void __iomem *dither;
const struct zx_crtc_regs *regs;
const struct zx_crtc_bits *bits;
enum vou_chn_type chn_type;
@@ -204,6 +207,11 @@ static struct vou_inf vou_infs[] = {
.clocks_en_bits = BIT(15),
.clocks_sel_bits = BIT(11) | BIT(0),
},
+ [VOU_VGA] = {
+ .data_sel = VOU_RGB_888,
+ .clocks_en_bits = BIT(1),
+ .clocks_sel_bits = BIT(10),
+ },
};
static inline struct zx_vou_hw *crtc_to_vou(struct drm_crtc *crtc)
@@ -227,9 +235,26 @@ void vou_inf_enable(enum vou_inf_id id, struct drm_crtc *crtc)
struct zx_crtc *zcrtc = to_zx_crtc(crtc);
struct zx_vou_hw *vou = zcrtc->vou;
struct vou_inf *inf = &vou_infs[id];
+ void __iomem *dither = zcrtc->dither;
+ void __iomem *csc = zcrtc->chncsc;
bool is_main = zcrtc->chn_type == VOU_CHN_MAIN;
u32 data_sel_shift = id << 1;
+ if (inf->data_sel != VOU_YUV444) {
+ /* Enable channel CSC for RGB output */
+ zx_writel_mask(csc + CSC_CTRL0, CSC_COV_MODE_MASK,
+ CSC_BT709_IMAGE_YCBCR2RGB << CSC_COV_MODE_SHIFT);
+ zx_writel_mask(csc + CSC_CTRL0, CSC_WORK_ENABLE,
+ CSC_WORK_ENABLE);
+
+ /* Bypass Dither block for RGB output */
+ zx_writel_mask(dither + OSD_DITHER_CTRL0, DITHER_BYSPASS,
+ DITHER_BYSPASS);
+ } else {
+ zx_writel_mask(csc + CSC_CTRL0, CSC_WORK_ENABLE, 0);
+ zx_writel_mask(dither + OSD_DITHER_CTRL0, DITHER_BYSPASS, 0);
+ }
+
/* Select data format */
zx_writel_mask(vou->vouctl + VOU_INF_DATA_SEL, 0x3 << data_sel_shift,
inf->data_sel << data_sel_shift);
@@ -525,20 +550,24 @@ static int zx_crtc_init(struct drm_device *drm, struct zx_vou_hw *vou,
if (chn_type == VOU_CHN_MAIN) {
zplane->layer = vou->osd + MAIN_GL_OFFSET;
- zplane->csc = vou->osd + MAIN_CSC_OFFSET;
+ zplane->csc = vou->osd + MAIN_GL_CSC_OFFSET;
zplane->hbsc = vou->osd + MAIN_HBSC_OFFSET;
zplane->rsz = vou->otfppu + MAIN_RSZ_OFFSET;
zplane->bits = &zx_gl_bits[0];
zcrtc->chnreg = vou->osd + OSD_MAIN_CHN;
+ zcrtc->chncsc = vou->osd + MAIN_CHN_CSC_OFFSET;
+ zcrtc->dither = vou->osd + MAIN_DITHER_OFFSET;
zcrtc->regs = &main_crtc_regs;
zcrtc->bits = &main_crtc_bits;
} else {
zplane->layer = vou->osd + AUX_GL_OFFSET;
- zplane->csc = vou->osd + AUX_CSC_OFFSET;
+ zplane->csc = vou->osd + AUX_GL_CSC_OFFSET;
zplane->hbsc = vou->osd + AUX_HBSC_OFFSET;
zplane->rsz = vou->otfppu + AUX_RSZ_OFFSET;
zplane->bits = &zx_gl_bits[1];
zcrtc->chnreg = vou->osd + OSD_AUX_CHN;
+ zcrtc->chncsc = vou->osd + AUX_CHN_CSC_OFFSET;
+ zcrtc->dither = vou->osd + AUX_DITHER_OFFSET;
zcrtc->regs = &aux_crtc_regs;
zcrtc->bits = &aux_crtc_bits;
}
@@ -705,9 +734,6 @@ static void vou_hw_init(struct zx_vou_hw *vou)
/* Release reset for all VOU modules */
zx_writel(vou->vouctl + VOU_SOFT_RST, ~0);
- /* Enable clock auto-gating for all VOU modules */
- zx_writel(vou->vouctl + VOU_CLK_REQEN, ~0);
-
/* Enable all VOU module clocks */
zx_writel(vou->vouctl + VOU_CLK_EN, ~0);