Message ID | 1484843100-16284-4-git-send-email-shawnguo@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Fri, Jan 20, 2017 at 12:24:58AM +0800, Shawn Guo wrote: > From: Shawn Guo <shawn.guo@linaro.org> > > The clock control module (CRM) cannot always provide desired frequency > for all VOU output devices. That's why VOU integrates a few dividers > to further divide the clocks from CRM. Let's add an interface for > configuring these dividers. > Reviewed-by: Sean Paul <seanpaul@chromium.org> > Signed-off-by: Shawn Guo <shawn.guo@linaro.org> > --- > drivers/gpu/drm/zte/zx_vou.c | 79 +++++++++++++++++++++++++++++++++++++++ > drivers/gpu/drm/zte/zx_vou.h | 25 +++++++++++++ > drivers/gpu/drm/zte/zx_vou_regs.h | 16 ++++++++ > 3 files changed, 120 insertions(+) > > diff --git a/drivers/gpu/drm/zte/zx_vou.c b/drivers/gpu/drm/zte/zx_vou.c > index c48704b4425a..98f0f51f9748 100644 > --- a/drivers/gpu/drm/zte/zx_vou.c > +++ b/drivers/gpu/drm/zte/zx_vou.c > @@ -72,6 +72,13 @@ struct zx_crtc_bits { > u32 sec_vactive_mask; > u32 interlace_select; > u32 pi_enable; > + u32 div_vga_shift; > + u32 div_pic_shift; > + u32 div_tvenc_shift; > + u32 div_hdmi_pnx_shift; > + u32 div_hdmi_shift; > + u32 div_inf_shift; > + u32 div_layer_shift; > }; > > static const struct zx_crtc_bits main_crtc_bits = { > @@ -83,6 +90,13 @@ struct zx_crtc_bits { > .sec_vactive_mask = SEC_VACT_MAIN_MASK, > .interlace_select = MAIN_INTERLACE_SEL, > .pi_enable = MAIN_PI_EN, > + .div_vga_shift = VGA_MAIN_DIV_SHIFT, > + .div_pic_shift = PIC_MAIN_DIV_SHIFT, > + .div_tvenc_shift = TVENC_MAIN_DIV_SHIFT, > + .div_hdmi_pnx_shift = HDMI_MAIN_PNX_DIV_SHIFT, > + .div_hdmi_shift = HDMI_MAIN_DIV_SHIFT, > + .div_inf_shift = INF_MAIN_DIV_SHIFT, > + .div_layer_shift = LAYER_MAIN_DIV_SHIFT, > }; > > static const struct zx_crtc_bits aux_crtc_bits = { > @@ -94,6 +108,13 @@ struct zx_crtc_bits { > .sec_vactive_mask = SEC_VACT_AUX_MASK, > .interlace_select = AUX_INTERLACE_SEL, > .pi_enable = AUX_PI_EN, > + .div_vga_shift = VGA_AUX_DIV_SHIFT, > + .div_pic_shift = PIC_AUX_DIV_SHIFT, > + .div_tvenc_shift = TVENC_AUX_DIV_SHIFT, > + .div_hdmi_pnx_shift = HDMI_AUX_PNX_DIV_SHIFT, > + .div_hdmi_shift = HDMI_AUX_DIV_SHIFT, > + .div_inf_shift = INF_AUX_DIV_SHIFT, > + .div_layer_shift = LAYER_AUX_DIV_SHIFT, > }; > > struct zx_crtc { > @@ -220,6 +241,64 @@ void vou_inf_disable(enum vou_inf_id id, struct drm_crtc *crtc) > zx_writel_mask(vou->vouctl + VOU_CLK_EN, inf->clocks_en_bits, 0); > } > > +void zx_vou_config_dividers(struct drm_crtc *crtc, > + struct vou_div_config *configs, int num) > +{ > + struct zx_crtc *zcrtc = to_zx_crtc(crtc); > + struct zx_vou_hw *vou = zcrtc->vou; > + const struct zx_crtc_bits *bits = zcrtc->bits; > + int i; > + > + /* Clear update flag bit */ > + zx_writel_mask(vou->vouctl + VOU_DIV_PARA, DIV_PARA_UPDATE, 0); > + > + for (i = 0; i < num; i++) { > + struct vou_div_config *cfg = configs + i; > + u32 reg, shift; > + > + switch (cfg->id) { > + case VOU_DIV_VGA: > + reg = VOU_CLK_SEL; > + shift = bits->div_vga_shift; > + break; > + case VOU_DIV_PIC: > + reg = VOU_CLK_SEL; > + shift = bits->div_pic_shift; > + break; > + case VOU_DIV_TVENC: > + reg = VOU_DIV_PARA; > + shift = bits->div_tvenc_shift; > + break; > + case VOU_DIV_HDMI_PNX: > + reg = VOU_DIV_PARA; > + shift = bits->div_hdmi_pnx_shift; > + break; > + case VOU_DIV_HDMI: > + reg = VOU_DIV_PARA; > + shift = bits->div_hdmi_shift; > + break; > + case VOU_DIV_INF: > + reg = VOU_DIV_PARA; > + shift = bits->div_inf_shift; > + break; > + case VOU_DIV_LAYER: > + reg = VOU_DIV_PARA; > + shift = bits->div_layer_shift; > + break; > + default: > + continue; > + } > + > + /* Each divider occupies 3 bits */ > + zx_writel_mask(vou->vouctl + reg, 0x7 << shift, > + cfg->val << shift); > + } > + > + /* Set update flag bit to get dividers effected */ > + zx_writel_mask(vou->vouctl + VOU_DIV_PARA, DIV_PARA_UPDATE, > + DIV_PARA_UPDATE); > +} > + > static inline void vou_chn_set_update(struct zx_crtc *zcrtc) > { > zx_writel(zcrtc->chnreg + CHN_UPDATE, 1); > diff --git a/drivers/gpu/drm/zte/zx_vou.h b/drivers/gpu/drm/zte/zx_vou.h > index a41a0ad49857..0dae4faefac4 100644 > --- a/drivers/gpu/drm/zte/zx_vou.h > +++ b/drivers/gpu/drm/zte/zx_vou.h > @@ -33,6 +33,31 @@ enum vou_inf_data_sel { > void vou_inf_enable(enum vou_inf_id id, struct drm_crtc *crtc); > void vou_inf_disable(enum vou_inf_id id, struct drm_crtc *crtc); > > +enum vou_div_id { > + VOU_DIV_VGA, > + VOU_DIV_PIC, > + VOU_DIV_TVENC, > + VOU_DIV_HDMI_PNX, > + VOU_DIV_HDMI, > + VOU_DIV_INF, > + VOU_DIV_LAYER, > +}; > + > +enum vou_div_val { > + VOU_DIV_1 = 0, > + VOU_DIV_2 = 1, > + VOU_DIV_4 = 3, > + VOU_DIV_8 = 7, > +}; > + > +struct vou_div_config { > + enum vou_div_id id; > + enum vou_div_val val; > +}; > + > +void zx_vou_config_dividers(struct drm_crtc *crtc, > + struct vou_div_config *configs, int num); > + > int zx_vou_enable_vblank(struct drm_device *drm, unsigned int pipe); > void zx_vou_disable_vblank(struct drm_device *drm, unsigned int pipe); > > diff --git a/drivers/gpu/drm/zte/zx_vou_regs.h b/drivers/gpu/drm/zte/zx_vou_regs.h > index e6ed844e068a..552772137cf0 100644 > --- a/drivers/gpu/drm/zte/zx_vou_regs.h > +++ b/drivers/gpu/drm/zte/zx_vou_regs.h > @@ -176,11 +176,27 @@ > #define VOU_INF_DATA_SEL 0x08 > #define VOU_SOFT_RST 0x14 > #define VOU_CLK_SEL 0x18 > +#define VGA_AUX_DIV_SHIFT 29 > +#define VGA_MAIN_DIV_SHIFT 26 > +#define PIC_MAIN_DIV_SHIFT 23 > +#define PIC_AUX_DIV_SHIFT 20 > #define VOU_CLK_VL2_SEL BIT(8) > #define VOU_CLK_VL1_SEL BIT(7) > #define VOU_CLK_VL0_SEL BIT(6) > #define VOU_CLK_GL1_SEL BIT(5) > #define VOU_CLK_GL0_SEL BIT(4) > +#define VOU_DIV_PARA 0x1c > +#define DIV_PARA_UPDATE BIT(31) > +#define TVENC_AUX_DIV_SHIFT 28 > +#define HDMI_AUX_PNX_DIV_SHIFT 25 > +#define HDMI_MAIN_PNX_DIV_SHIFT 22 > +#define HDMI_AUX_DIV_SHIFT 19 > +#define HDMI_MAIN_DIV_SHIFT 16 > +#define TVENC_MAIN_DIV_SHIFT 13 > +#define INF_AUX_DIV_SHIFT 9 > +#define INF_MAIN_DIV_SHIFT 6 > +#define LAYER_AUX_DIV_SHIFT 3 > +#define LAYER_MAIN_DIV_SHIFT 0 > #define VOU_CLK_REQEN 0x20 > #define VOU_CLK_EN 0x24 > > -- > 1.9.1 > > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel
diff --git a/drivers/gpu/drm/zte/zx_vou.c b/drivers/gpu/drm/zte/zx_vou.c index c48704b4425a..98f0f51f9748 100644 --- a/drivers/gpu/drm/zte/zx_vou.c +++ b/drivers/gpu/drm/zte/zx_vou.c @@ -72,6 +72,13 @@ struct zx_crtc_bits { u32 sec_vactive_mask; u32 interlace_select; u32 pi_enable; + u32 div_vga_shift; + u32 div_pic_shift; + u32 div_tvenc_shift; + u32 div_hdmi_pnx_shift; + u32 div_hdmi_shift; + u32 div_inf_shift; + u32 div_layer_shift; }; static const struct zx_crtc_bits main_crtc_bits = { @@ -83,6 +90,13 @@ struct zx_crtc_bits { .sec_vactive_mask = SEC_VACT_MAIN_MASK, .interlace_select = MAIN_INTERLACE_SEL, .pi_enable = MAIN_PI_EN, + .div_vga_shift = VGA_MAIN_DIV_SHIFT, + .div_pic_shift = PIC_MAIN_DIV_SHIFT, + .div_tvenc_shift = TVENC_MAIN_DIV_SHIFT, + .div_hdmi_pnx_shift = HDMI_MAIN_PNX_DIV_SHIFT, + .div_hdmi_shift = HDMI_MAIN_DIV_SHIFT, + .div_inf_shift = INF_MAIN_DIV_SHIFT, + .div_layer_shift = LAYER_MAIN_DIV_SHIFT, }; static const struct zx_crtc_bits aux_crtc_bits = { @@ -94,6 +108,13 @@ struct zx_crtc_bits { .sec_vactive_mask = SEC_VACT_AUX_MASK, .interlace_select = AUX_INTERLACE_SEL, .pi_enable = AUX_PI_EN, + .div_vga_shift = VGA_AUX_DIV_SHIFT, + .div_pic_shift = PIC_AUX_DIV_SHIFT, + .div_tvenc_shift = TVENC_AUX_DIV_SHIFT, + .div_hdmi_pnx_shift = HDMI_AUX_PNX_DIV_SHIFT, + .div_hdmi_shift = HDMI_AUX_DIV_SHIFT, + .div_inf_shift = INF_AUX_DIV_SHIFT, + .div_layer_shift = LAYER_AUX_DIV_SHIFT, }; struct zx_crtc { @@ -220,6 +241,64 @@ void vou_inf_disable(enum vou_inf_id id, struct drm_crtc *crtc) zx_writel_mask(vou->vouctl + VOU_CLK_EN, inf->clocks_en_bits, 0); } +void zx_vou_config_dividers(struct drm_crtc *crtc, + struct vou_div_config *configs, int num) +{ + struct zx_crtc *zcrtc = to_zx_crtc(crtc); + struct zx_vou_hw *vou = zcrtc->vou; + const struct zx_crtc_bits *bits = zcrtc->bits; + int i; + + /* Clear update flag bit */ + zx_writel_mask(vou->vouctl + VOU_DIV_PARA, DIV_PARA_UPDATE, 0); + + for (i = 0; i < num; i++) { + struct vou_div_config *cfg = configs + i; + u32 reg, shift; + + switch (cfg->id) { + case VOU_DIV_VGA: + reg = VOU_CLK_SEL; + shift = bits->div_vga_shift; + break; + case VOU_DIV_PIC: + reg = VOU_CLK_SEL; + shift = bits->div_pic_shift; + break; + case VOU_DIV_TVENC: + reg = VOU_DIV_PARA; + shift = bits->div_tvenc_shift; + break; + case VOU_DIV_HDMI_PNX: + reg = VOU_DIV_PARA; + shift = bits->div_hdmi_pnx_shift; + break; + case VOU_DIV_HDMI: + reg = VOU_DIV_PARA; + shift = bits->div_hdmi_shift; + break; + case VOU_DIV_INF: + reg = VOU_DIV_PARA; + shift = bits->div_inf_shift; + break; + case VOU_DIV_LAYER: + reg = VOU_DIV_PARA; + shift = bits->div_layer_shift; + break; + default: + continue; + } + + /* Each divider occupies 3 bits */ + zx_writel_mask(vou->vouctl + reg, 0x7 << shift, + cfg->val << shift); + } + + /* Set update flag bit to get dividers effected */ + zx_writel_mask(vou->vouctl + VOU_DIV_PARA, DIV_PARA_UPDATE, + DIV_PARA_UPDATE); +} + static inline void vou_chn_set_update(struct zx_crtc *zcrtc) { zx_writel(zcrtc->chnreg + CHN_UPDATE, 1); diff --git a/drivers/gpu/drm/zte/zx_vou.h b/drivers/gpu/drm/zte/zx_vou.h index a41a0ad49857..0dae4faefac4 100644 --- a/drivers/gpu/drm/zte/zx_vou.h +++ b/drivers/gpu/drm/zte/zx_vou.h @@ -33,6 +33,31 @@ enum vou_inf_data_sel { void vou_inf_enable(enum vou_inf_id id, struct drm_crtc *crtc); void vou_inf_disable(enum vou_inf_id id, struct drm_crtc *crtc); +enum vou_div_id { + VOU_DIV_VGA, + VOU_DIV_PIC, + VOU_DIV_TVENC, + VOU_DIV_HDMI_PNX, + VOU_DIV_HDMI, + VOU_DIV_INF, + VOU_DIV_LAYER, +}; + +enum vou_div_val { + VOU_DIV_1 = 0, + VOU_DIV_2 = 1, + VOU_DIV_4 = 3, + VOU_DIV_8 = 7, +}; + +struct vou_div_config { + enum vou_div_id id; + enum vou_div_val val; +}; + +void zx_vou_config_dividers(struct drm_crtc *crtc, + struct vou_div_config *configs, int num); + int zx_vou_enable_vblank(struct drm_device *drm, unsigned int pipe); void zx_vou_disable_vblank(struct drm_device *drm, unsigned int pipe); diff --git a/drivers/gpu/drm/zte/zx_vou_regs.h b/drivers/gpu/drm/zte/zx_vou_regs.h index e6ed844e068a..552772137cf0 100644 --- a/drivers/gpu/drm/zte/zx_vou_regs.h +++ b/drivers/gpu/drm/zte/zx_vou_regs.h @@ -176,11 +176,27 @@ #define VOU_INF_DATA_SEL 0x08 #define VOU_SOFT_RST 0x14 #define VOU_CLK_SEL 0x18 +#define VGA_AUX_DIV_SHIFT 29 +#define VGA_MAIN_DIV_SHIFT 26 +#define PIC_MAIN_DIV_SHIFT 23 +#define PIC_AUX_DIV_SHIFT 20 #define VOU_CLK_VL2_SEL BIT(8) #define VOU_CLK_VL1_SEL BIT(7) #define VOU_CLK_VL0_SEL BIT(6) #define VOU_CLK_GL1_SEL BIT(5) #define VOU_CLK_GL0_SEL BIT(4) +#define VOU_DIV_PARA 0x1c +#define DIV_PARA_UPDATE BIT(31) +#define TVENC_AUX_DIV_SHIFT 28 +#define HDMI_AUX_PNX_DIV_SHIFT 25 +#define HDMI_MAIN_PNX_DIV_SHIFT 22 +#define HDMI_AUX_DIV_SHIFT 19 +#define HDMI_MAIN_DIV_SHIFT 16 +#define TVENC_MAIN_DIV_SHIFT 13 +#define INF_AUX_DIV_SHIFT 9 +#define INF_MAIN_DIV_SHIFT 6 +#define LAYER_AUX_DIV_SHIFT 3 +#define LAYER_MAIN_DIV_SHIFT 0 #define VOU_CLK_REQEN 0x20 #define VOU_CLK_EN 0x24