summaryrefslogtreecommitdiff
path: root/drivers/gpu/ipu-v3
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/ipu-v3')
-rw-r--r--drivers/gpu/ipu-v3/ipu-common.c12
-rw-r--r--drivers/gpu/ipu-v3/ipu-cpmem.c13
-rw-r--r--drivers/gpu/ipu-v3/ipu-csi.c26
-rw-r--r--drivers/gpu/ipu-v3/ipu-ic.c40
-rw-r--r--drivers/gpu/ipu-v3/ipu-prv.h1
5 files changed, 69 insertions, 23 deletions
diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c
index 99dcacf05b99..d230988ddb8f 100644
--- a/drivers/gpu/ipu-v3/ipu-common.c
+++ b/drivers/gpu/ipu-v3/ipu-common.c
@@ -45,6 +45,12 @@ static inline void ipu_cm_write(struct ipu_soc *ipu, u32 value, unsigned offset)
writel(value, ipu->cm_reg + offset);
}
+int ipu_get_num(struct ipu_soc *ipu)
+{
+ return ipu->id;
+}
+EXPORT_SYMBOL_GPL(ipu_get_num);
+
void ipu_srm_dp_sync_update(struct ipu_soc *ipu)
{
u32 val;
@@ -1004,14 +1010,14 @@ static struct ipu_platform_reg client_reg[] = {
.dma[0] = IPUV3_CHANNEL_CSI0,
.dma[1] = -EINVAL,
},
- .name = "imx-ipuv3-camera",
+ .name = "imx-ipuv3-csi",
}, {
.pdata = {
.csi = 1,
.dma[0] = IPUV3_CHANNEL_CSI1,
.dma[1] = -EINVAL,
},
- .name = "imx-ipuv3-camera",
+ .name = "imx-ipuv3-csi",
}, {
.pdata = {
.di = 0,
@@ -1209,6 +1215,7 @@ static int ipu_probe(struct platform_device *pdev)
{
const struct of_device_id *of_id =
of_match_device(imx_ipu_dt_ids, &pdev->dev);
+ struct device_node *np = pdev->dev.of_node;
struct ipu_soc *ipu;
struct resource *res;
unsigned long ipu_base;
@@ -1237,6 +1244,7 @@ static int ipu_probe(struct platform_device *pdev)
ipu->channel[i].ipu = ipu;
ipu->devtype = devtype;
ipu->ipu_type = devtype->type;
+ ipu->id = of_alias_get_id(np, "ipu");
spin_lock_init(&ipu->lock);
mutex_init(&ipu->channel_lock);
diff --git a/drivers/gpu/ipu-v3/ipu-cpmem.c b/drivers/gpu/ipu-v3/ipu-cpmem.c
index 6494a4d28171..fcb7dc86167b 100644
--- a/drivers/gpu/ipu-v3/ipu-cpmem.c
+++ b/drivers/gpu/ipu-v3/ipu-cpmem.c
@@ -253,6 +253,13 @@ void ipu_cpmem_set_buffer(struct ipuv3_channel *ch, int bufnum, dma_addr_t buf)
}
EXPORT_SYMBOL_GPL(ipu_cpmem_set_buffer);
+void ipu_cpmem_set_uv_offset(struct ipuv3_channel *ch, u32 u_off, u32 v_off)
+{
+ ipu_ch_param_write_field(ch, IPU_FIELD_UBO, u_off / 8);
+ ipu_ch_param_write_field(ch, IPU_FIELD_VBO, v_off / 8);
+}
+EXPORT_SYMBOL_GPL(ipu_cpmem_set_uv_offset);
+
void ipu_cpmem_interlaced_scan(struct ipuv3_channel *ch, int stride)
{
ipu_ch_param_write_field(ch, IPU_FIELD_SO, 1);
@@ -268,6 +275,12 @@ void ipu_cpmem_set_axi_id(struct ipuv3_channel *ch, u32 id)
}
EXPORT_SYMBOL_GPL(ipu_cpmem_set_axi_id);
+int ipu_cpmem_get_burstsize(struct ipuv3_channel *ch)
+{
+ return ipu_ch_param_read_field(ch, IPU_FIELD_NPB) + 1;
+}
+EXPORT_SYMBOL_GPL(ipu_cpmem_get_burstsize);
+
void ipu_cpmem_set_burstsize(struct ipuv3_channel *ch, int burstsize)
{
ipu_ch_param_write_field(ch, IPU_FIELD_NPB, burstsize - 1);
diff --git a/drivers/gpu/ipu-v3/ipu-csi.c b/drivers/gpu/ipu-v3/ipu-csi.c
index 06631ac61b04..d6e5ded24418 100644
--- a/drivers/gpu/ipu-v3/ipu-csi.c
+++ b/drivers/gpu/ipu-v3/ipu-csi.c
@@ -258,12 +258,8 @@ static int mbus_code_to_bus_cfg(struct ipu_csi_bus_config *cfg, u32 mbus_code)
cfg->data_width = IPU_CSI_DATA_WIDTH_8;
break;
case MEDIA_BUS_FMT_UYVY8_1X16:
- cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_UYVY;
- cfg->mipi_dt = MIPI_DT_YUV422;
- cfg->data_width = IPU_CSI_DATA_WIDTH_16;
- break;
case MEDIA_BUS_FMT_YUYV8_1X16:
- cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_YUYV;
+ cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER;
cfg->mipi_dt = MIPI_DT_YUV422;
cfg->data_width = IPU_CSI_DATA_WIDTH_16;
break;
@@ -365,10 +361,14 @@ int ipu_csi_init_interface(struct ipu_csi *csi,
{
struct ipu_csi_bus_config cfg;
unsigned long flags;
- u32 data = 0;
+ u32 width, height, data = 0;
fill_csi_bus_cfg(&cfg, mbus_cfg, mbus_fmt);
+ /* set default sensor frame width and height */
+ width = mbus_fmt->width;
+ height = mbus_fmt->height;
+
/* Set the CSI_SENS_CONF register remaining fields */
data |= cfg.data_width << CSI_SENS_CONF_DATA_WIDTH_SHIFT |
cfg.data_fmt << CSI_SENS_CONF_DATA_FMT_SHIFT |
@@ -386,11 +386,6 @@ int ipu_csi_init_interface(struct ipu_csi *csi,
ipu_csi_write(csi, data, CSI_SENS_CONF);
- /* Setup sensor frame size */
- ipu_csi_write(csi,
- (mbus_fmt->width - 1) | ((mbus_fmt->height - 1) << 16),
- CSI_SENS_FRM_SIZE);
-
/* Set CCIR registers */
switch (cfg.clk_mode) {
@@ -408,11 +403,12 @@ int ipu_csi_init_interface(struct ipu_csi *csi,
* Field1BlankEnd = 0x7, Field1BlankStart = 0x3,
* Field1ActiveEnd = 0x5, Field1ActiveStart = 0x1
*/
+ height = 625; /* framelines for PAL */
+
ipu_csi_write(csi, 0x40596 | CSI_CCIR_ERR_DET_EN,
CSI_CCIR_CODE_1);
ipu_csi_write(csi, 0xD07DF, CSI_CCIR_CODE_2);
ipu_csi_write(csi, 0xFF0000, CSI_CCIR_CODE_3);
-
} else if (mbus_fmt->width == 720 && mbus_fmt->height == 480) {
/*
* NTSC case
@@ -422,6 +418,8 @@ int ipu_csi_init_interface(struct ipu_csi *csi,
* Field1BlankEnd = 0x6, Field1BlankStart = 0x2,
* Field1ActiveEnd = 0x4, Field1ActiveStart = 0
*/
+ height = 525; /* framelines for NTSC */
+
ipu_csi_write(csi, 0xD07DF | CSI_CCIR_ERR_DET_EN,
CSI_CCIR_CODE_1);
ipu_csi_write(csi, 0x40596, CSI_CCIR_CODE_2);
@@ -447,6 +445,10 @@ int ipu_csi_init_interface(struct ipu_csi *csi,
break;
}
+ /* Setup sensor frame size */
+ ipu_csi_write(csi, (width - 1) | ((height - 1) << 16),
+ CSI_SENS_FRM_SIZE);
+
dev_dbg(csi->ipu->dev, "CSI_SENS_CONF = 0x%08X\n",
ipu_csi_read(csi, CSI_SENS_CONF));
dev_dbg(csi->ipu->dev, "CSI_ACT_FRM_SIZE = 0x%08X\n",
diff --git a/drivers/gpu/ipu-v3/ipu-ic.c b/drivers/gpu/ipu-v3/ipu-ic.c
index 1dcb96ccda66..1a37afcd85bd 100644
--- a/drivers/gpu/ipu-v3/ipu-ic.c
+++ b/drivers/gpu/ipu-v3/ipu-ic.c
@@ -160,6 +160,7 @@ struct ipu_ic_priv {
spinlock_t lock;
struct ipu_soc *ipu;
int use_count;
+ int irt_use_count;
struct ipu_ic task[IC_NUM_TASKS];
};
@@ -379,8 +380,6 @@ void ipu_ic_task_disable(struct ipu_ic *ic)
ipu_ic_write(ic, ic_conf, IC_CONF);
- ic->rotation = ic->graphics = false;
-
spin_unlock_irqrestore(&priv->lock, flags);
}
EXPORT_SYMBOL_GPL(ipu_ic_task_disable);
@@ -629,22 +628,41 @@ unlock:
}
EXPORT_SYMBOL_GPL(ipu_ic_task_idma_init);
+static void ipu_irt_enable(struct ipu_ic *ic)
+{
+ struct ipu_ic_priv *priv = ic->priv;
+
+ if (!priv->irt_use_count)
+ ipu_module_enable(priv->ipu, IPU_CONF_ROT_EN);
+
+ priv->irt_use_count++;
+}
+
+static void ipu_irt_disable(struct ipu_ic *ic)
+{
+ struct ipu_ic_priv *priv = ic->priv;
+
+ if (priv->irt_use_count) {
+ if (!--priv->irt_use_count)
+ ipu_module_disable(priv->ipu, IPU_CONF_ROT_EN);
+ }
+}
+
int ipu_ic_enable(struct ipu_ic *ic)
{
struct ipu_ic_priv *priv = ic->priv;
unsigned long flags;
- u32 module = IPU_CONF_IC_EN;
spin_lock_irqsave(&priv->lock, flags);
- if (ic->rotation)
- module |= IPU_CONF_ROT_EN;
-
if (!priv->use_count)
- ipu_module_enable(priv->ipu, module);
+ ipu_module_enable(priv->ipu, IPU_CONF_IC_EN);
priv->use_count++;
+ if (ic->rotation)
+ ipu_irt_enable(ic);
+
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
@@ -655,18 +673,22 @@ int ipu_ic_disable(struct ipu_ic *ic)
{
struct ipu_ic_priv *priv = ic->priv;
unsigned long flags;
- u32 module = IPU_CONF_IC_EN | IPU_CONF_ROT_EN;
spin_lock_irqsave(&priv->lock, flags);
priv->use_count--;
if (!priv->use_count)
- ipu_module_disable(priv->ipu, module);
+ ipu_module_disable(priv->ipu, IPU_CONF_IC_EN);
if (priv->use_count < 0)
priv->use_count = 0;
+ if (ic->rotation)
+ ipu_irt_disable(ic);
+
+ ic->rotation = ic->graphics = false;
+
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
diff --git a/drivers/gpu/ipu-v3/ipu-prv.h b/drivers/gpu/ipu-v3/ipu-prv.h
index bfb1e8a4483f..fd47f8f555cd 100644
--- a/drivers/gpu/ipu-v3/ipu-prv.h
+++ b/drivers/gpu/ipu-v3/ipu-prv.h
@@ -152,6 +152,7 @@ struct ipu_soc {
void __iomem *cm_reg;
void __iomem *idmac_reg;
+ int id;
int usecount;
struct clk *clk;