Commit 3a5e6bb9 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'zxdrm-4.11' of...

Merge tag 'zxdrm-4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux into drm-next

ZTE DRM driver updates for 4.11:
 - Add missing selection of VIDEOMODE_HELPERS in Kconfig, since ZTE DRM
   driver uses drm_display_mode_to_videomode().
 - Enable HDMI audio support through SPDIF interface based on generic
   hdmi-audio-codec driver.
 - Enable VOU VL (Video Layer) to support overlay plane with scaling
   function.
 - Refine zx_vou driver a bit and then add TV Encoder output device
   support.

[airlied: fixup plane format change]

* tag 'zxdrm-4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux:
  drm: zte: add tvenc driver support
  dt: add bindings for ZTE tvenc device
  drm: zte: add function to configure vou_ctrl dividers
  drm: zte: move struct vou_inf into zx_vou driver
  drm: zte: add interlace mode support
  drm: zte: add overlay plane support
  drm: zte: add .atomic_disable hook to disable graphic layer
  drm: zte: make zx_plane accessible from zx_vou driver
  drm: zte: support hdmi audio through spdif
  drm: zte: select VIDEOMODE_HELPERS in Kconfig
parents 26431055 098988cb
...@@ -49,6 +49,15 @@ Required properties: ...@@ -49,6 +49,15 @@ Required properties:
"osc_clk" "osc_clk"
"xclk" "xclk"
* TV Encoder output device
Required properties:
- compatible: should be "zte,zx296718-tvenc"
- reg: Physical base address and length of the TVENC device IO region
- zte,tvenc-power-control: the phandle to SYSCTRL block followed by two
integer cells. The first cell is the offset of SYSCTRL register used
to control TV Encoder DAC power, and the second cell is the bit mask.
Example: Example:
vou: vou@1440000 { vou: vou@1440000 {
...@@ -81,4 +90,10 @@ vou: vou@1440000 { ...@@ -81,4 +90,10 @@ vou: vou@1440000 {
<&topcrm HDMI_XCLK>; <&topcrm HDMI_XCLK>;
clock-names = "osc_cec", "osc_clk", "xclk"; clock-names = "osc_cec", "osc_clk", "xclk";
}; };
tvenc: tvenc@2000 {
compatible = "zte,zx296718-tvenc";
reg = <0x2000 0x1000>;
zte,tvenc-power-control = <&sysctrl 0x170 0x10>;
};
}; };
...@@ -4,5 +4,7 @@ config DRM_ZTE ...@@ -4,5 +4,7 @@ config DRM_ZTE
select DRM_KMS_CMA_HELPER select DRM_KMS_CMA_HELPER
select DRM_KMS_FB_HELPER select DRM_KMS_FB_HELPER
select DRM_KMS_HELPER select DRM_KMS_HELPER
select SND_SOC_HDMI_CODEC if SND_SOC
select VIDEOMODE_HELPERS
help help
Choose this option to enable DRM on ZTE ZX SoCs. Choose this option to enable DRM on ZTE ZX SoCs.
...@@ -2,6 +2,7 @@ zxdrm-y := \ ...@@ -2,6 +2,7 @@ zxdrm-y := \
zx_drm_drv.o \ zx_drm_drv.o \
zx_hdmi.o \ zx_hdmi.o \
zx_plane.o \ zx_plane.o \
zx_tvenc.o \
zx_vou.o zx_vou.o
obj-$(CONFIG_DRM_ZTE) += zxdrm.o obj-$(CONFIG_DRM_ZTE) += zxdrm.o
...@@ -247,6 +247,7 @@ static struct platform_driver zx_drm_platform_driver = { ...@@ -247,6 +247,7 @@ static struct platform_driver zx_drm_platform_driver = {
static struct platform_driver *drivers[] = { static struct platform_driver *drivers[] = {
&zx_crtc_driver, &zx_crtc_driver,
&zx_hdmi_driver, &zx_hdmi_driver,
&zx_tvenc_driver,
&zx_drm_platform_driver, &zx_drm_platform_driver,
}; };
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
extern struct platform_driver zx_crtc_driver; extern struct platform_driver zx_crtc_driver;
extern struct platform_driver zx_hdmi_driver; extern struct platform_driver zx_hdmi_driver;
extern struct platform_driver zx_tvenc_driver;
static inline u32 zx_readl(void __iomem *reg) static inline u32 zx_readl(void __iomem *reg)
{ {
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#include <drm/drm_of.h> #include <drm/drm_of.h>
#include <drm/drmP.h> #include <drm/drmP.h>
#include <sound/hdmi-codec.h>
#include "zx_hdmi_regs.h" #include "zx_hdmi_regs.h"
#include "zx_vou.h" #include "zx_vou.h"
...@@ -49,17 +51,11 @@ struct zx_hdmi { ...@@ -49,17 +51,11 @@ struct zx_hdmi {
bool sink_is_hdmi; bool sink_is_hdmi;
bool sink_has_audio; bool sink_has_audio;
const struct vou_inf *inf; const struct vou_inf *inf;
struct platform_device *audio_pdev;
}; };
#define to_zx_hdmi(x) container_of(x, struct zx_hdmi, x) #define to_zx_hdmi(x) container_of(x, struct zx_hdmi, x)
static const struct vou_inf vou_inf_hdmi = {
.id = VOU_HDMI,
.data_sel = VOU_YUV444,
.clocks_en_bits = BIT(24) | BIT(18) | BIT(6),
.clocks_sel_bits = BIT(13) | BIT(2),
};
static inline u8 hdmi_readb(struct zx_hdmi *hdmi, u16 offset) static inline u8 hdmi_readb(struct zx_hdmi *hdmi, u16 offset)
{ {
return readl_relaxed(hdmi->mmio + offset * 4); return readl_relaxed(hdmi->mmio + offset * 4);
...@@ -238,14 +234,14 @@ static void zx_hdmi_encoder_enable(struct drm_encoder *encoder) ...@@ -238,14 +234,14 @@ static void zx_hdmi_encoder_enable(struct drm_encoder *encoder)
zx_hdmi_hw_enable(hdmi); zx_hdmi_hw_enable(hdmi);
vou_inf_enable(hdmi->inf, encoder->crtc); vou_inf_enable(VOU_HDMI, encoder->crtc);
} }
static void zx_hdmi_encoder_disable(struct drm_encoder *encoder) static void zx_hdmi_encoder_disable(struct drm_encoder *encoder)
{ {
struct zx_hdmi *hdmi = to_zx_hdmi(encoder); struct zx_hdmi *hdmi = to_zx_hdmi(encoder);
vou_inf_disable(hdmi->inf, encoder->crtc); vou_inf_disable(VOU_HDMI, encoder->crtc);
zx_hdmi_hw_disable(hdmi); zx_hdmi_hw_disable(hdmi);
...@@ -366,6 +362,142 @@ static irqreturn_t zx_hdmi_irq_handler(int irq, void *dev_id) ...@@ -366,6 +362,142 @@ static irqreturn_t zx_hdmi_irq_handler(int irq, void *dev_id)
return IRQ_NONE; return IRQ_NONE;
} }
static int zx_hdmi_audio_startup(struct device *dev, void *data)
{
struct zx_hdmi *hdmi = dev_get_drvdata(dev);
struct drm_encoder *encoder = &hdmi->encoder;
vou_inf_hdmi_audio_sel(encoder->crtc, VOU_HDMI_AUD_SPDIF);
return 0;
}
static void zx_hdmi_audio_shutdown(struct device *dev, void *data)
{
struct zx_hdmi *hdmi = dev_get_drvdata(dev);
/* Disable audio input */
hdmi_writeb_mask(hdmi, AUD_EN, AUD_IN_EN, 0);
}
static inline int zx_hdmi_audio_get_n(unsigned int fs)
{
unsigned int n;
if (fs && (fs % 44100) == 0)
n = 6272 * (fs / 44100);
else
n = fs * 128 / 1000;
return n;
}
static int zx_hdmi_audio_hw_params(struct device *dev,
void *data,
struct hdmi_codec_daifmt *daifmt,
struct hdmi_codec_params *params)
{
struct zx_hdmi *hdmi = dev_get_drvdata(dev);
struct hdmi_audio_infoframe *cea = &params->cea;
union hdmi_infoframe frame;
int n;
/* We only support spdif for now */
if (daifmt->fmt != HDMI_SPDIF) {
DRM_DEV_ERROR(hdmi->dev, "invalid daifmt %d\n", daifmt->fmt);
return -EINVAL;
}
switch (params->sample_width) {
case 16:
hdmi_writeb_mask(hdmi, TPI_AUD_CONFIG, SPDIF_SAMPLE_SIZE_MASK,
SPDIF_SAMPLE_SIZE_16BIT);
break;
case 20:
hdmi_writeb_mask(hdmi, TPI_AUD_CONFIG, SPDIF_SAMPLE_SIZE_MASK,
SPDIF_SAMPLE_SIZE_20BIT);
break;
case 24:
hdmi_writeb_mask(hdmi, TPI_AUD_CONFIG, SPDIF_SAMPLE_SIZE_MASK,
SPDIF_SAMPLE_SIZE_24BIT);
break;
default:
DRM_DEV_ERROR(hdmi->dev, "invalid sample width %d\n",
params->sample_width);
return -EINVAL;
}
/* CTS is calculated by hardware, and we only need to take care of N */
n = zx_hdmi_audio_get_n(params->sample_rate);
hdmi_writeb(hdmi, N_SVAL1, n & 0xff);
hdmi_writeb(hdmi, N_SVAL2, (n >> 8) & 0xff);
hdmi_writeb(hdmi, N_SVAL3, (n >> 16) & 0xf);
/* Enable spdif mode */
hdmi_writeb_mask(hdmi, AUD_MODE, SPDIF_EN, SPDIF_EN);
/* Enable audio input */
hdmi_writeb_mask(hdmi, AUD_EN, AUD_IN_EN, AUD_IN_EN);
memcpy(&frame.audio, cea, sizeof(*cea));
return zx_hdmi_infoframe_trans(hdmi, &frame, FSEL_AUDIO);
}
static int zx_hdmi_audio_digital_mute(struct device *dev, void *data,
bool enable)
{
struct zx_hdmi *hdmi = dev_get_drvdata(dev);
if (enable)
hdmi_writeb_mask(hdmi, TPI_AUD_CONFIG, TPI_AUD_MUTE,
TPI_AUD_MUTE);
else
hdmi_writeb_mask(hdmi, TPI_AUD_CONFIG, TPI_AUD_MUTE, 0);
return 0;
}
static int zx_hdmi_audio_get_eld(struct device *dev, void *data,
uint8_t *buf, size_t len)
{
struct zx_hdmi *hdmi = dev_get_drvdata(dev);
struct drm_connector *connector = &hdmi->connector;
memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
return 0;
}
static const struct hdmi_codec_ops zx_hdmi_codec_ops = {
.audio_startup = zx_hdmi_audio_startup,
.hw_params = zx_hdmi_audio_hw_params,
.audio_shutdown = zx_hdmi_audio_shutdown,
.digital_mute = zx_hdmi_audio_digital_mute,
.get_eld = zx_hdmi_audio_get_eld,
};
static struct hdmi_codec_pdata zx_hdmi_codec_pdata = {
.ops = &zx_hdmi_codec_ops,
.spdif = 1,
};
static int zx_hdmi_audio_register(struct zx_hdmi *hdmi)
{
struct platform_device *pdev;
pdev = platform_device_register_data(hdmi->dev, HDMI_CODEC_DRV_NAME,
PLATFORM_DEVID_AUTO,
&zx_hdmi_codec_pdata,
sizeof(zx_hdmi_codec_pdata));
if (IS_ERR(pdev))
return PTR_ERR(pdev);
hdmi->audio_pdev = pdev;
return 0;
}
static int zx_hdmi_i2c_read(struct zx_hdmi *hdmi, struct i2c_msg *msg) static int zx_hdmi_i2c_read(struct zx_hdmi *hdmi, struct i2c_msg *msg)
{ {
int len = msg->len; int len = msg->len;
...@@ -523,7 +655,6 @@ static int zx_hdmi_bind(struct device *dev, struct device *master, void *data) ...@@ -523,7 +655,6 @@ static int zx_hdmi_bind(struct device *dev, struct device *master, void *data)
hdmi->dev = dev; hdmi->dev = dev;
hdmi->drm = drm; hdmi->drm = drm;
hdmi->inf = &vou_inf_hdmi;
dev_set_drvdata(dev, hdmi); dev_set_drvdata(dev, hdmi);
...@@ -566,6 +697,12 @@ static int zx_hdmi_bind(struct device *dev, struct device *master, void *data) ...@@ -566,6 +697,12 @@ static int zx_hdmi_bind(struct device *dev, struct device *master, void *data)
return ret; return ret;
} }
ret = zx_hdmi_audio_register(hdmi);
if (ret) {
DRM_DEV_ERROR(dev, "failed to register audio: %d\n", ret);
return ret;
}
ret = zx_hdmi_register(drm, hdmi); ret = zx_hdmi_register(drm, hdmi);
if (ret) { if (ret) {
DRM_DEV_ERROR(dev, "failed to register hdmi: %d\n", ret); DRM_DEV_ERROR(dev, "failed to register hdmi: %d\n", ret);
...@@ -590,6 +727,9 @@ static void zx_hdmi_unbind(struct device *dev, struct device *master, ...@@ -590,6 +727,9 @@ static void zx_hdmi_unbind(struct device *dev, struct device *master,
hdmi->connector.funcs->destroy(&hdmi->connector); hdmi->connector.funcs->destroy(&hdmi->connector);
hdmi->encoder.funcs->destroy(&hdmi->encoder); hdmi->encoder.funcs->destroy(&hdmi->encoder);
if (hdmi->audio_pdev)
platform_device_unregister(hdmi->audio_pdev);
} }
static const struct component_ops zx_hdmi_component_ops = { static const struct component_ops zx_hdmi_component_ops = {
......
...@@ -52,5 +52,19 @@ ...@@ -52,5 +52,19 @@
#define TPI_INFO_TRANS_RPT BIT(6) #define TPI_INFO_TRANS_RPT BIT(6)
#define TPI_DDC_MASTER_EN 0x06f8 #define TPI_DDC_MASTER_EN 0x06f8
#define HW_DDC_MASTER BIT(7) #define HW_DDC_MASTER BIT(7)
#define N_SVAL1 0xa03
#define N_SVAL2 0xa04
#define N_SVAL3 0xa05
#define AUD_EN 0xa13
#define AUD_IN_EN BIT(0)
#define AUD_MODE 0xa14
#define SPDIF_EN BIT(1)
#define TPI_AUD_CONFIG 0xa62
#define SPDIF_SAMPLE_SIZE_SHIFT 6
#define SPDIF_SAMPLE_SIZE_MASK (0x3 << SPDIF_SAMPLE_SIZE_SHIFT)
#define SPDIF_SAMPLE_SIZE_16BIT (0x1 << SPDIF_SAMPLE_SIZE_SHIFT)
#define SPDIF_SAMPLE_SIZE_20BIT (0x2 << SPDIF_SAMPLE_SIZE_SHIFT)
#define SPDIF_SAMPLE_SIZE_24BIT (0x3 << SPDIF_SAMPLE_SIZE_SHIFT)
#define TPI_AUD_MUTE BIT(4)
#endif /* __ZX_HDMI_REGS_H__ */ #endif /* __ZX_HDMI_REGS_H__ */
This diff is collapsed.
...@@ -11,15 +11,19 @@ ...@@ -11,15 +11,19 @@
#ifndef __ZX_PLANE_H__ #ifndef __ZX_PLANE_H__
#define __ZX_PLANE_H__ #define __ZX_PLANE_H__
struct zx_layer_data { struct zx_plane {
struct drm_plane plane;
struct device *dev;
void __iomem *layer; void __iomem *layer;
void __iomem *csc; void __iomem *csc;
void __iomem *hbsc; void __iomem *hbsc;
void __iomem *rsz; void __iomem *rsz;
const struct vou_layer_bits *bits;
}; };
struct drm_plane *zx_plane_init(struct drm_device *drm, struct device *dev, #define to_zx_plane(plane) container_of(plane, struct zx_plane, plane)
struct zx_layer_data *data,
int zx_plane_init(struct drm_device *drm, struct zx_plane *zplane,
enum drm_plane_type type); enum drm_plane_type type);
void zx_plane_set_update(struct drm_plane *plane); void zx_plane_set_update(struct drm_plane *plane);
......
...@@ -46,6 +46,37 @@ ...@@ -46,6 +46,37 @@
#define GL_POS_X(x) (((x) << GL_POS_X_SHIFT) & GL_POS_X_MASK) #define GL_POS_X(x) (((x) << GL_POS_X_SHIFT) & GL_POS_X_MASK)
#define GL_POS_Y(x) (((x) << GL_POS_Y_SHIFT) & GL_POS_Y_MASK) #define GL_POS_Y(x) (((x) << GL_POS_Y_SHIFT) & GL_POS_Y_MASK)
/* VL registers */
#define VL_CTRL0 0x00
#define VL_UPDATE BIT(3)
#define VL_CTRL1 0x04
#define VL_YUV420_PLANAR BIT(5)
#define VL_YUV422_SHIFT 3
#define VL_YUV422_YUYV (0 << VL_YUV422_SHIFT)
#define VL_YUV422_YVYU (1 << VL_YUV422_SHIFT)
#define VL_YUV422_UYVY (2 << VL_YUV422_SHIFT)
#define VL_YUV422_VYUY (3 << VL_YUV422_SHIFT)
#define VL_FMT_YUV420 0
#define VL_FMT_YUV422 1
#define VL_FMT_YUV420_P010 2
#define VL_FMT_YUV420_HANTRO 3
#define VL_FMT_YUV444_8BIT 4
#define VL_FMT_YUV444_10BIT 5
#define VL_CTRL2 0x08
#define VL_SCALER_BYPASS_MODE BIT(0)
#define VL_STRIDE 0x0c
#define LUMA_STRIDE_SHIFT 16
#define LUMA_STRIDE_MASK (0xffff << LUMA_STRIDE_SHIFT)
#define CHROMA_STRIDE_SHIFT 0
#define CHROMA_STRIDE_MASK (0xffff << CHROMA_STRIDE_SHIFT)
#define VL_SRC_SIZE 0x10
#define VL_Y 0x14
#define VL_POS_START 0x30
#define VL_POS_END 0x34
#define LUMA_STRIDE(x) (((x) << LUMA_STRIDE_SHIFT) & LUMA_STRIDE_MASK)
#define CHROMA_STRIDE(x) (((x) << CHROMA_STRIDE_SHIFT) & CHROMA_STRIDE_MASK)
/* CSC registers */ /* CSC registers */
#define CSC_CTRL0 0x30 #define CSC_CTRL0 0x30
#define CSC_COV_MODE_SHIFT 16 #define CSC_COV_MODE_SHIFT 16
...@@ -69,6 +100,18 @@ ...@@ -69,6 +100,18 @@
#define RSZ_DEST_CFG 0x04 #define RSZ_DEST_CFG 0x04
#define RSZ_ENABLE_CFG 0x14 #define RSZ_ENABLE_CFG 0x14
#define RSZ_VL_LUMA_HOR 0x08
#define RSZ_VL_LUMA_VER 0x0c
#define RSZ_VL_CHROMA_HOR 0x10
#define RSZ_VL_CHROMA_VER 0x14
#define RSZ_VL_CTRL_CFG 0x18
#define RSZ_VL_FMT_SHIFT 3
#define RSZ_VL_FMT_MASK (0x3 << RSZ_VL_FMT_SHIFT)
#define RSZ_VL_FMT_YCBCR420 (0x0 << RSZ_VL_FMT_SHIFT)
#define RSZ_VL_FMT_YCBCR422 (0x1 << RSZ_VL_FMT_SHIFT)
#define RSZ_VL_FMT_YCBCR444 (0x2 << RSZ_VL_FMT_SHIFT)
#define RSZ_VL_ENABLE_CFG 0x1c
#define RSZ_VER_SHIFT 16 #define RSZ_VER_SHIFT 16
#define RSZ_VER_MASK (0xffff << RSZ_VER_SHIFT) #define RSZ_VER_MASK (0xffff << RSZ_VER_SHIFT)
#define RSZ_HOR_SHIFT 0 #define RSZ_HOR_SHIFT 0
...@@ -77,6 +120,14 @@ ...@@ -77,6 +120,14 @@
#define RSZ_VER(x) (((x) << RSZ_VER_SHIFT) & RSZ_VER_MASK) #define RSZ_VER(x) (((x) << RSZ_VER_SHIFT) & RSZ_VER_MASK)
#define RSZ_HOR(x) (((x) << RSZ_HOR_SHIFT) & RSZ_HOR_MASK) #define RSZ_HOR(x) (((x) << RSZ_HOR_SHIFT) & RSZ_HOR_MASK)
#define RSZ_DATA_STEP_SHIFT 16
#define RSZ_DATA_STEP_MASK (0xffff << RSZ_DATA_STEP_SHIFT)
#define RSZ_PARA_STEP_SHIFT 0
#define RSZ_PARA_STEP_MASK (0xffff << RSZ_PARA_STEP_SHIFT)
#define RSZ_DATA_STEP(x) (((x) << RSZ_DATA_STEP_SHIFT) & RSZ_DATA_STEP_MASK)
#define RSZ_PARA_STEP(x) (((x) << RSZ_PARA_STEP_SHIFT) & RSZ_PARA_STEP_MASK)
/* HBSC registers */ /* HBSC registers */
#define HBSC_SATURATION 0x00 #define HBSC_SATURATION 0x00
#define HBSC_HUE 0x04 #define HBSC_HUE 0x04
......
This diff is collapsed.
/*
* Copyright 2017 Linaro Ltd.
* Copyright 2017 ZTE Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#ifndef __ZX_TVENC_REGS_H__
#define __ZX_TVENC_REGS_H__
#define VENC_VIDEO_INFO 0x04
#define VENC_VIDEO_RES 0x08
#define VENC_FIELD1_PARAM 0x10
#define VENC_FIELD2_PARAM 0x14
#define VENC_LINE_O_1 0x18
#define VENC_LINE_E_1 0x1c
#define VENC_LINE_O_2 0x20
#define VENC_LINE_E_2 0x24
#define VENC_LINE_TIMING_PARAM 0x28
#define VENC_WEIGHT_VALUE 0x2c
#define VENC_BLANK_BLACK_LEVEL 0x30
#define VENC_BURST_LEVEL 0x34
#define VENC_CONTROL_PARAM 0x3c
#define VENC_SUB_CARRIER_PHASE1 0x40
#define VENC_PHASE_LINE_INCR_CVBS 0x48
#define VENC_ENABLE 0xa8
#endif /* __ZX_TVENC_REGS_H__ */
This diff is collapsed.
...@@ -23,24 +23,48 @@ enum vou_inf_id { ...@@ -23,24 +23,48 @@ enum vou_inf_id {
VOU_VGA = 5, VOU_VGA = 5,
}; };
enum vou_inf_data_sel { enum vou_inf_hdmi_audio {
VOU_YUV444 = 0, VOU_HDMI_AUD_SPDIF = BIT(0),
VOU_RGB_101010 = 1, VOU_HDMI_AUD_I2S = BIT(1),
VOU_RGB_888 = 2, VOU_HDMI_AUD_DSD = BIT(2),
VOU_RGB_666 = 3, VOU_HDMI_AUD_HBR = BIT(3),
VOU_HDMI_AUD_PARALLEL = BIT(4),
}; };
struct vou_inf { void vou_inf_hdmi_audio_sel(struct drm_crtc *crtc,
enum vou_inf_id id; enum vou_inf_hdmi_audio aud);
enum vou_inf_data_sel data_sel; void vou_inf_enable(enum vou_inf_id id, struct drm_crtc *crtc);
u32 clocks_en_bits; void vou_inf_disable(enum vou_inf_id id, struct drm_crtc *crtc);
u32 clocks_sel_bits;
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,
}; };
void vou_inf_enable(const struct vou_inf *inf, struct drm_crtc *crtc); struct vou_div_config {
void vou_inf_disable(const struct vou_inf *inf, struct drm_crtc *crtc); 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); int zx_vou_enable_vblank(struct drm_device *drm, unsigned int pipe);
void zx_vou_disable_vblank(struct drm_device *drm, unsigned int pipe); void zx_vou_disable_vblank(struct drm_device *drm, unsigned int pipe);
void zx_vou_layer_enable(struct drm_plane *plane);
void zx_vou_layer_disable(struct drm_plane *plane);
#endif /* __ZX_VOU_H__ */ #endif /* __ZX_VOU_H__ */
...@@ -22,6 +22,15 @@ ...@@ -22,6 +22,15 @@
#define AUX_HBSC_OFFSET 0x860 #define AUX_HBSC_OFFSET 0x860
#define AUX_RSZ_OFFSET 0x800 #define AUX_RSZ_OFFSET 0x800
#define OSD_VL0_OFFSET 0x040
#define OSD_VL_OFFSET(i) (OSD_VL0_OFFSET + 0x050 * (i))
#define HBSC_VL0_OFFSET 0x760
#define HBSC_VL_OFFSET(i) (HBSC_VL0_OFFSET + 0x040 * (i))
#define RSZ_VL1_U0 0xa00
#define RSZ_VL_OFFSET(i) (RSZ_VL1_U0 + 0x200 * (i))
/* OSD (GPC_GLOBAL) registers */ /* OSD (GPC_GLOBAL) registers */
#define OSD_INT_STA 0x04 #define OSD_INT_STA 0x04
#define OSD_INT_CLRSTA 0x08 #define OSD_INT_CLRSTA 0x08
...@@ -42,6 +51,12 @@ ...@@ -42,6 +51,12 @@
) )
#define OSD_INT_ENABLE (OSD_INT_ERROR | OSD_INT_AUX_UPT | OSD_INT_MAIN_UPT) #define OSD_INT_ENABLE (OSD_INT_ERROR | OSD_INT_AUX_UPT | OSD_INT_MAIN_UPT)
#define OSD_CTRL0 0x10 #define OSD_CTRL0 0x10
#define OSD_CTRL0_VL0_EN BIT(13)
#define OSD_CTRL0_VL0_SEL BIT(12)
#define OSD_CTRL0_VL1_EN BIT(11)
#define OSD_CTRL0_VL1_SEL BIT(10)
#define OSD_CTRL0_VL2_EN BIT(9)
#define OSD_CTRL0_VL2_SEL BIT(8)
#define OSD_CTRL0_GL0_EN BIT(7) #define OSD_CTRL0_GL0_EN BIT(7)
#define OSD_CTRL0_GL0_SEL BIT(6) #define OSD_CTRL0_GL0_SEL BIT(6)
#define OSD_CTRL0_GL1_EN BIT(5) #define OSD_CTRL0_GL1_EN BIT(5)
...@@ -60,6 +75,8 @@ ...@@ -60,6 +75,8 @@
#define CHN_SCREEN_H_SHIFT 5 #define CHN_SCREEN_H_SHIFT 5
#define CHN_SCREEN_H_MASK (0x1fff << CHN_SCREEN_H_SHIFT) #define CHN_SCREEN_H_MASK (0x1fff << CHN_SCREEN_H_SHIFT)
#define CHN_UPDATE 0x08 #define CHN_UPDATE 0x08
#define CHN_INTERLACE_BUF_CTRL 0x24
#define CHN_INTERLACE_EN BIT(2)
/* TIMING_CTRL registers */ /* TIMING_CTRL registers */
#define TIMING_TC_ENABLE 0x04 #define TIMING_TC_ENABLE 0x04
...@@ -102,6 +119,19 @@ ...@@ -102,6 +119,19 @@
#define TIMING_MAIN_SHIFT 0x2c #define TIMING_MAIN_SHIFT 0x2c
#define TIMING_AUX_SHIFT 0x30 #define TIMING_AUX_SHIFT 0x30
#define H_SHIFT_VAL 0x0048 #define H_SHIFT_VAL 0x0048
#define V_SHIFT_VAL 0x0001
#define SCAN_CTRL 0x34
#define AUX_PI_EN BIT(19)
#define MAIN_PI_EN BIT(18)
#define AUX_INTERLACE_SEL BIT(1)
#define MAIN_INTERLACE_SEL BIT(0)
#define SEC_V_ACTIVE 0x38
#define SEC_VACT_MAIN_SHIFT 0
#define SEC_VACT_MAIN_MASK (0xffff << SEC_VACT_MAIN_SHIFT)
#define SEC_VACT_AUX_SHIFT 16
#define SEC_VACT_AUX_MASK (0xffff << SEC_VACT_AUX_SHIFT)
#define SEC_MAIN_V_TIMING 0x3c
#define SEC_AUX_V_TIMING 0x40
#define TIMING_MAIN_PI_SHIFT 0x68 #define TIMING_MAIN_PI_SHIFT 0x68
#define TIMING_AUX_PI_SHIFT 0x6c #define TIMING_AUX_PI_SHIFT 0x6c
#define H_PI_SHIFT_VAL 0x000f #define H_PI_SHIFT_VAL 0x000f
...@@ -146,10 +176,31 @@ ...@@ -146,10 +176,31 @@
#define VOU_INF_DATA_SEL 0x08 #define VOU_INF_DATA_SEL 0x08
#define VOU_SOFT_RST 0x14 #define VOU_SOFT_RST 0x14
#define VOU_CLK_SEL 0x18 #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_GL1_SEL BIT(5)
#define VOU_CLK_GL0_SEL BIT(4) #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_REQEN 0x20
#define VOU_CLK_EN 0x24 #define VOU_CLK_EN 0x24
#define VOU_INF_HDMI_CTRL 0x30
#define VOU_HDMI_AUD_MASK 0x1f
/* OTFPPU_CTRL registers */ /* OTFPPU_CTRL registers */
#define OTFPPU_RSZ_DATA_SOURCE 0x04 #define OTFPPU_RSZ_DATA_SOURCE 0x04
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment