Commit 9d95baf9 authored by Robert Foss's avatar Robert Foss Committed by Mauro Carvalho Chehab

media: camss: Make ISPIF subdevice optional

This driver supports multiple architecture versions of the Qualcomm ISP.
The CAMSS architecure which this driver is name after, and with the
introduction of this series, the Titan architecture.

The ISPIF is an IP-block that is only present in the CAMSS generation of
the architecture. In order to support the Titan generation, make the
ISPIF an optional subdevice.
Signed-off-by: default avatarRobert Foss <robert.foss@linaro.org>
Reviewed-by: default avatarAndrey Konovalov <andrey.konovalov@linaro.org>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent 96387cff
...@@ -161,6 +161,7 @@ static const u32 ispif_formats_8x96[] = { ...@@ -161,6 +161,7 @@ static const u32 ispif_formats_8x96[] = {
static irqreturn_t ispif_isr_8x96(int irq, void *dev) static irqreturn_t ispif_isr_8x96(int irq, void *dev)
{ {
struct ispif_device *ispif = dev; struct ispif_device *ispif = dev;
struct camss *camss = ispif->camss;
u32 value0, value1, value2, value3, value4, value5; u32 value0, value1, value2, value3, value4, value5;
value0 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_0(0)); value0 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_0(0));
...@@ -186,34 +187,34 @@ static irqreturn_t ispif_isr_8x96(int irq, void *dev) ...@@ -186,34 +187,34 @@ static irqreturn_t ispif_isr_8x96(int irq, void *dev)
complete(&ispif->reset_complete[1]); complete(&ispif->reset_complete[1]);
if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW)) if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW))
dev_err_ratelimited(to_device(ispif), "VFE0 pix0 overflow\n"); dev_err_ratelimited(camss->dev, "VFE0 pix0 overflow\n");
if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_RDI0_OVERFLOW)) if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_RDI0_OVERFLOW))
dev_err_ratelimited(to_device(ispif), "VFE0 rdi0 overflow\n"); dev_err_ratelimited(camss->dev, "VFE0 rdi0 overflow\n");
if (unlikely(value1 & ISPIF_VFE_m_IRQ_STATUS_1_PIX1_OVERFLOW)) if (unlikely(value1 & ISPIF_VFE_m_IRQ_STATUS_1_PIX1_OVERFLOW))
dev_err_ratelimited(to_device(ispif), "VFE0 pix1 overflow\n"); dev_err_ratelimited(camss->dev, "VFE0 pix1 overflow\n");
if (unlikely(value1 & ISPIF_VFE_m_IRQ_STATUS_1_RDI1_OVERFLOW)) if (unlikely(value1 & ISPIF_VFE_m_IRQ_STATUS_1_RDI1_OVERFLOW))
dev_err_ratelimited(to_device(ispif), "VFE0 rdi1 overflow\n"); dev_err_ratelimited(camss->dev, "VFE0 rdi1 overflow\n");
if (unlikely(value2 & ISPIF_VFE_m_IRQ_STATUS_2_RDI2_OVERFLOW)) if (unlikely(value2 & ISPIF_VFE_m_IRQ_STATUS_2_RDI2_OVERFLOW))
dev_err_ratelimited(to_device(ispif), "VFE0 rdi2 overflow\n"); dev_err_ratelimited(camss->dev, "VFE0 rdi2 overflow\n");
if (unlikely(value3 & ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW)) if (unlikely(value3 & ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW))
dev_err_ratelimited(to_device(ispif), "VFE1 pix0 overflow\n"); dev_err_ratelimited(camss->dev, "VFE1 pix0 overflow\n");
if (unlikely(value3 & ISPIF_VFE_m_IRQ_STATUS_0_RDI0_OVERFLOW)) if (unlikely(value3 & ISPIF_VFE_m_IRQ_STATUS_0_RDI0_OVERFLOW))
dev_err_ratelimited(to_device(ispif), "VFE1 rdi0 overflow\n"); dev_err_ratelimited(camss->dev, "VFE1 rdi0 overflow\n");
if (unlikely(value4 & ISPIF_VFE_m_IRQ_STATUS_1_PIX1_OVERFLOW)) if (unlikely(value4 & ISPIF_VFE_m_IRQ_STATUS_1_PIX1_OVERFLOW))
dev_err_ratelimited(to_device(ispif), "VFE1 pix1 overflow\n"); dev_err_ratelimited(camss->dev, "VFE1 pix1 overflow\n");
if (unlikely(value4 & ISPIF_VFE_m_IRQ_STATUS_1_RDI1_OVERFLOW)) if (unlikely(value4 & ISPIF_VFE_m_IRQ_STATUS_1_RDI1_OVERFLOW))
dev_err_ratelimited(to_device(ispif), "VFE1 rdi1 overflow\n"); dev_err_ratelimited(camss->dev, "VFE1 rdi1 overflow\n");
if (unlikely(value5 & ISPIF_VFE_m_IRQ_STATUS_2_RDI2_OVERFLOW)) if (unlikely(value5 & ISPIF_VFE_m_IRQ_STATUS_2_RDI2_OVERFLOW))
dev_err_ratelimited(to_device(ispif), "VFE1 rdi2 overflow\n"); dev_err_ratelimited(camss->dev, "VFE1 rdi2 overflow\n");
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -228,6 +229,7 @@ static irqreturn_t ispif_isr_8x96(int irq, void *dev) ...@@ -228,6 +229,7 @@ static irqreturn_t ispif_isr_8x96(int irq, void *dev)
static irqreturn_t ispif_isr_8x16(int irq, void *dev) static irqreturn_t ispif_isr_8x16(int irq, void *dev)
{ {
struct ispif_device *ispif = dev; struct ispif_device *ispif = dev;
struct camss *camss = ispif->camss;
u32 value0, value1, value2; u32 value0, value1, value2;
value0 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_0(0)); value0 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_0(0));
...@@ -244,30 +246,32 @@ static irqreturn_t ispif_isr_8x16(int irq, void *dev) ...@@ -244,30 +246,32 @@ static irqreturn_t ispif_isr_8x16(int irq, void *dev)
complete(&ispif->reset_complete[0]); complete(&ispif->reset_complete[0]);
if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW)) if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW))
dev_err_ratelimited(to_device(ispif), "VFE0 pix0 overflow\n"); dev_err_ratelimited(camss->dev, "VFE0 pix0 overflow\n");
if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_RDI0_OVERFLOW)) if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_RDI0_OVERFLOW))
dev_err_ratelimited(to_device(ispif), "VFE0 rdi0 overflow\n"); dev_err_ratelimited(camss->dev, "VFE0 rdi0 overflow\n");
if (unlikely(value1 & ISPIF_VFE_m_IRQ_STATUS_1_PIX1_OVERFLOW)) if (unlikely(value1 & ISPIF_VFE_m_IRQ_STATUS_1_PIX1_OVERFLOW))
dev_err_ratelimited(to_device(ispif), "VFE0 pix1 overflow\n"); dev_err_ratelimited(camss->dev, "VFE0 pix1 overflow\n");
if (unlikely(value1 & ISPIF_VFE_m_IRQ_STATUS_1_RDI1_OVERFLOW)) if (unlikely(value1 & ISPIF_VFE_m_IRQ_STATUS_1_RDI1_OVERFLOW))
dev_err_ratelimited(to_device(ispif), "VFE0 rdi1 overflow\n"); dev_err_ratelimited(camss->dev, "VFE0 rdi1 overflow\n");
if (unlikely(value2 & ISPIF_VFE_m_IRQ_STATUS_2_RDI2_OVERFLOW)) if (unlikely(value2 & ISPIF_VFE_m_IRQ_STATUS_2_RDI2_OVERFLOW))
dev_err_ratelimited(to_device(ispif), "VFE0 rdi2 overflow\n"); dev_err_ratelimited(camss->dev, "VFE0 rdi2 overflow\n");
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static int ispif_vfe_reset(struct ispif_device *ispif, u8 vfe_id) static int ispif_vfe_reset(struct ispif_device *ispif, u8 vfe_id)
{ {
struct camss *camss = ispif->camss;
unsigned long time; unsigned long time;
u32 val; u32 val;
if (vfe_id > (to_camss(ispif)->vfe_num - 1)) { if (vfe_id > (camss->vfe_num - 1)) {
dev_err(to_device(ispif), dev_err(camss->dev,
"Error: asked reset for invalid VFE%d\n", vfe_id); "Error: asked reset for invalid VFE%d\n", vfe_id);
return -ENOENT; return -ENOENT;
} }
...@@ -300,7 +304,7 @@ static int ispif_vfe_reset(struct ispif_device *ispif, u8 vfe_id) ...@@ -300,7 +304,7 @@ static int ispif_vfe_reset(struct ispif_device *ispif, u8 vfe_id)
time = wait_for_completion_timeout(&ispif->reset_complete[vfe_id], time = wait_for_completion_timeout(&ispif->reset_complete[vfe_id],
msecs_to_jiffies(ISPIF_RESET_TIMEOUT_MS)); msecs_to_jiffies(ISPIF_RESET_TIMEOUT_MS));
if (!time) { if (!time) {
dev_err(to_device(ispif), dev_err(camss->dev,
"ISPIF for VFE%d reset timeout\n", vfe_id); "ISPIF for VFE%d reset timeout\n", vfe_id);
return -EIO; return -EIO;
} }
...@@ -316,30 +320,31 @@ static int ispif_vfe_reset(struct ispif_device *ispif, u8 vfe_id) ...@@ -316,30 +320,31 @@ static int ispif_vfe_reset(struct ispif_device *ispif, u8 vfe_id)
*/ */
static int ispif_reset(struct ispif_device *ispif, u8 vfe_id) static int ispif_reset(struct ispif_device *ispif, u8 vfe_id)
{ {
struct camss *camss = ispif->camss;
int ret; int ret;
ret = camss_pm_domain_on(to_camss(ispif), PM_DOMAIN_VFE0); ret = camss_pm_domain_on(camss, PM_DOMAIN_VFE0);
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = camss_pm_domain_on(to_camss(ispif), PM_DOMAIN_VFE1); ret = camss_pm_domain_on(camss, PM_DOMAIN_VFE1);
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = camss_enable_clocks(ispif->nclocks_for_reset, ret = camss_enable_clocks(ispif->nclocks_for_reset,
ispif->clock_for_reset, ispif->clock_for_reset,
to_device(ispif)); camss->dev);
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = ispif_vfe_reset(ispif, vfe_id); ret = ispif_vfe_reset(ispif, vfe_id);
if (ret) if (ret)
dev_dbg(to_device(ispif), "ISPIF Reset failed\n"); dev_dbg(camss->dev, "ISPIF Reset failed\n");
camss_disable_clocks(ispif->nclocks_for_reset, ispif->clock_for_reset); camss_disable_clocks(ispif->nclocks_for_reset, ispif->clock_for_reset);
camss_pm_domain_off(to_camss(ispif), PM_DOMAIN_VFE0); camss_pm_domain_off(camss, PM_DOMAIN_VFE0);
camss_pm_domain_off(to_camss(ispif), PM_DOMAIN_VFE1); camss_pm_domain_off(camss, PM_DOMAIN_VFE1);
return ret; return ret;
} }
...@@ -355,7 +360,7 @@ static int ispif_set_power(struct v4l2_subdev *sd, int on) ...@@ -355,7 +360,7 @@ static int ispif_set_power(struct v4l2_subdev *sd, int on)
{ {
struct ispif_line *line = v4l2_get_subdevdata(sd); struct ispif_line *line = v4l2_get_subdevdata(sd);
struct ispif_device *ispif = line->ispif; struct ispif_device *ispif = line->ispif;
struct device *dev = to_device(ispif); struct device *dev = ispif->camss->dev;
int ret = 0; int ret = 0;
mutex_lock(&ispif->power_lock); mutex_lock(&ispif->power_lock);
...@@ -505,7 +510,7 @@ static int ispif_validate_intf_status(struct ispif_device *ispif, ...@@ -505,7 +510,7 @@ static int ispif_validate_intf_status(struct ispif_device *ispif,
} }
if ((val & 0xf) != 0xf) { if ((val & 0xf) != 0xf) {
dev_err(to_device(ispif), "%s: ispif is busy: 0x%x\n", dev_err(ispif->camss->dev, "%s: ispif is busy: 0x%x\n",
__func__, val); __func__, val);
ret = -EBUSY; ret = -EBUSY;
} }
...@@ -552,7 +557,7 @@ static int ispif_wait_for_stop(struct ispif_device *ispif, ...@@ -552,7 +557,7 @@ static int ispif_wait_for_stop(struct ispif_device *ispif,
ISPIF_TIMEOUT_SLEEP_US, ISPIF_TIMEOUT_SLEEP_US,
ISPIF_TIMEOUT_ALL_US); ISPIF_TIMEOUT_ALL_US);
if (ret < 0) if (ret < 0)
dev_err(to_device(ispif), "%s: ispif stop timeout\n", dev_err(ispif->camss->dev, "%s: ispif stop timeout\n",
__func__); __func__);
return ret; return ret;
...@@ -800,6 +805,7 @@ static int ispif_set_stream(struct v4l2_subdev *sd, int enable) ...@@ -800,6 +805,7 @@ static int ispif_set_stream(struct v4l2_subdev *sd, int enable)
{ {
struct ispif_line *line = v4l2_get_subdevdata(sd); struct ispif_line *line = v4l2_get_subdevdata(sd);
struct ispif_device *ispif = line->ispif; struct ispif_device *ispif = line->ispif;
struct camss *camss = ispif->camss;
enum ispif_intf intf = line->interface; enum ispif_intf intf = line->interface;
u8 csid = line->csid_id; u8 csid = line->csid_id;
u8 vfe = line->vfe_id; u8 vfe = line->vfe_id;
...@@ -825,8 +831,8 @@ static int ispif_set_stream(struct v4l2_subdev *sd, int enable) ...@@ -825,8 +831,8 @@ static int ispif_set_stream(struct v4l2_subdev *sd, int enable)
ispif_select_csid(ispif, intf, csid, vfe, 1); ispif_select_csid(ispif, intf, csid, vfe, 1);
ispif_select_cid(ispif, intf, cid, vfe, 1); ispif_select_cid(ispif, intf, cid, vfe, 1);
ispif_config_irq(ispif, intf, vfe, 1); ispif_config_irq(ispif, intf, vfe, 1);
if (to_camss(ispif)->version == CAMSS_8x96 || if (camss->version == CAMSS_8x96 ||
to_camss(ispif)->version == CAMSS_660) camss->version == CAMSS_660)
ispif_config_pack(ispif, ispif_config_pack(ispif,
line->fmt[MSM_ISPIF_PAD_SINK].code, line->fmt[MSM_ISPIF_PAD_SINK].code,
intf, cid, vfe, 1); intf, cid, vfe, 1);
...@@ -843,8 +849,8 @@ static int ispif_set_stream(struct v4l2_subdev *sd, int enable) ...@@ -843,8 +849,8 @@ static int ispif_set_stream(struct v4l2_subdev *sd, int enable)
return ret; return ret;
mutex_lock(&ispif->config_lock); mutex_lock(&ispif->config_lock);
if (to_camss(ispif)->version == CAMSS_8x96 || if (camss->version == CAMSS_8x96 ||
to_camss(ispif)->version == CAMSS_660) camss->version == CAMSS_660)
ispif_config_pack(ispif, ispif_config_pack(ispif,
line->fmt[MSM_ISPIF_PAD_SINK].code, line->fmt[MSM_ISPIF_PAD_SINK].code,
intf, cid, vfe, 0); intf, cid, vfe, 0);
...@@ -1088,26 +1094,32 @@ static int ispif_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) ...@@ -1088,26 +1094,32 @@ static int ispif_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
* *
* Return 0 on success or a negative error code otherwise * Return 0 on success or a negative error code otherwise
*/ */
int msm_ispif_subdev_init(struct ispif_device *ispif, int msm_ispif_subdev_init(struct camss *camss,
const struct resources_ispif *res) const struct resources_ispif *res)
{ {
struct device *dev = to_device(ispif); struct device *dev = camss->dev;
struct ispif_device *ispif = camss->ispif;
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
struct resource *r; struct resource *r;
int i; int i;
int ret; int ret;
if (!camss->ispif)
return 0;
ispif->camss = camss;
/* Number of ISPIF lines - same as number of CSID hardware modules */ /* Number of ISPIF lines - same as number of CSID hardware modules */
if (to_camss(ispif)->version == CAMSS_8x16) if (camss->version == CAMSS_8x16)
ispif->line_num = 2; ispif->line_num = 2;
else if (to_camss(ispif)->version == CAMSS_8x96 || else if (camss->version == CAMSS_8x96 ||
to_camss(ispif)->version == CAMSS_660) camss->version == CAMSS_660)
ispif->line_num = 4; ispif->line_num = 4;
else else
return -EINVAL; return -EINVAL;
ispif->line = devm_kcalloc(dev, ispif->line_num, sizeof(*ispif->line), ispif->line = devm_kcalloc(dev, ispif->line_num,
GFP_KERNEL); sizeof(*ispif->line), GFP_KERNEL);
if (!ispif->line) if (!ispif->line)
return -ENOMEM; return -ENOMEM;
...@@ -1115,12 +1127,12 @@ int msm_ispif_subdev_init(struct ispif_device *ispif, ...@@ -1115,12 +1127,12 @@ int msm_ispif_subdev_init(struct ispif_device *ispif,
ispif->line[i].ispif = ispif; ispif->line[i].ispif = ispif;
ispif->line[i].id = i; ispif->line[i].id = i;
if (to_camss(ispif)->version == CAMSS_8x16) { if (camss->version == CAMSS_8x16) {
ispif->line[i].formats = ispif_formats_8x16; ispif->line[i].formats = ispif_formats_8x16;
ispif->line[i].nformats = ispif->line[i].nformats =
ARRAY_SIZE(ispif_formats_8x16); ARRAY_SIZE(ispif_formats_8x16);
} else if (to_camss(ispif)->version == CAMSS_8x96 || } else if (camss->version == CAMSS_8x96 ||
to_camss(ispif)->version == CAMSS_660) { camss->version == CAMSS_660) {
ispif->line[i].formats = ispif_formats_8x96; ispif->line[i].formats = ispif_formats_8x96;
ispif->line[i].nformats = ispif->line[i].nformats =
ARRAY_SIZE(ispif_formats_8x96); ARRAY_SIZE(ispif_formats_8x96);
...@@ -1157,15 +1169,16 @@ int msm_ispif_subdev_init(struct ispif_device *ispif, ...@@ -1157,15 +1169,16 @@ int msm_ispif_subdev_init(struct ispif_device *ispif,
ispif->irq = r->start; ispif->irq = r->start;
snprintf(ispif->irq_name, sizeof(ispif->irq_name), "%s_%s", snprintf(ispif->irq_name, sizeof(ispif->irq_name), "%s_%s",
dev_name(dev), MSM_ISPIF_NAME); dev_name(dev), MSM_ISPIF_NAME);
if (to_camss(ispif)->version == CAMSS_8x16) if (camss->version == CAMSS_8x16)
ret = devm_request_irq(dev, ispif->irq, ispif_isr_8x16, ret = devm_request_irq(dev, ispif->irq, ispif_isr_8x16,
IRQF_TRIGGER_RISING, ispif->irq_name, ispif); IRQF_TRIGGER_RISING, ispif->irq_name, ispif);
else if (to_camss(ispif)->version == CAMSS_8x96 || else if (camss->version == CAMSS_8x96 ||
to_camss(ispif)->version == CAMSS_660) camss->version == CAMSS_660)
ret = devm_request_irq(dev, ispif->irq, ispif_isr_8x96, ret = devm_request_irq(dev, ispif->irq, ispif_isr_8x96,
IRQF_TRIGGER_RISING, ispif->irq_name, ispif); IRQF_TRIGGER_RISING, ispif->irq_name, ispif);
else else
ret = -EINVAL; ret = -EINVAL;
if (ret < 0) { if (ret < 0) {
dev_err(dev, "request_irq failed: %d\n", ret); dev_err(dev, "request_irq failed: %d\n", ret);
return ret; return ret;
...@@ -1331,10 +1344,15 @@ static const struct media_entity_operations ispif_media_ops = { ...@@ -1331,10 +1344,15 @@ static const struct media_entity_operations ispif_media_ops = {
int msm_ispif_register_entities(struct ispif_device *ispif, int msm_ispif_register_entities(struct ispif_device *ispif,
struct v4l2_device *v4l2_dev) struct v4l2_device *v4l2_dev)
{ {
struct device *dev = to_device(ispif); struct camss *camss;
int ret; int ret;
int i; int i;
if (!ispif)
return 0;
camss = ispif->camss;
for (i = 0; i < ispif->line_num; i++) { for (i = 0; i < ispif->line_num; i++) {
struct v4l2_subdev *sd = &ispif->line[i].subdev; struct v4l2_subdev *sd = &ispif->line[i].subdev;
struct media_pad *pads = ispif->line[i].pads; struct media_pad *pads = ispif->line[i].pads;
...@@ -1348,7 +1366,7 @@ int msm_ispif_register_entities(struct ispif_device *ispif, ...@@ -1348,7 +1366,7 @@ int msm_ispif_register_entities(struct ispif_device *ispif,
ret = ispif_init_formats(sd, NULL); ret = ispif_init_formats(sd, NULL);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "Failed to init format: %d\n", ret); dev_err(camss->dev, "Failed to init format: %d\n", ret);
goto error; goto error;
} }
...@@ -1360,13 +1378,15 @@ int msm_ispif_register_entities(struct ispif_device *ispif, ...@@ -1360,13 +1378,15 @@ int msm_ispif_register_entities(struct ispif_device *ispif,
ret = media_entity_pads_init(&sd->entity, MSM_ISPIF_PADS_NUM, ret = media_entity_pads_init(&sd->entity, MSM_ISPIF_PADS_NUM,
pads); pads);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "Failed to init media entity: %d\n", ret); dev_err(camss->dev, "Failed to init media entity: %d\n",
ret);
goto error; goto error;
} }
ret = v4l2_device_register_subdev(v4l2_dev, sd); ret = v4l2_device_register_subdev(v4l2_dev, sd);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "Failed to register subdev: %d\n", ret); dev_err(camss->dev, "Failed to register subdev: %d\n",
ret);
media_entity_cleanup(&sd->entity); media_entity_cleanup(&sd->entity);
goto error; goto error;
} }
...@@ -1393,6 +1413,9 @@ void msm_ispif_unregister_entities(struct ispif_device *ispif) ...@@ -1393,6 +1413,9 @@ void msm_ispif_unregister_entities(struct ispif_device *ispif)
{ {
int i; int i;
if (!ispif)
return;
mutex_destroy(&ispif->power_lock); mutex_destroy(&ispif->power_lock);
mutex_destroy(&ispif->config_lock); mutex_destroy(&ispif->config_lock);
......
...@@ -63,11 +63,12 @@ struct ispif_device { ...@@ -63,11 +63,12 @@ struct ispif_device {
struct mutex config_lock; struct mutex config_lock;
unsigned int line_num; unsigned int line_num;
struct ispif_line *line; struct ispif_line *line;
struct camss *camss;
}; };
struct resources_ispif; struct resources_ispif;
int msm_ispif_subdev_init(struct ispif_device *ispif, int msm_ispif_subdev_init(struct camss *camss,
const struct resources_ispif *res); const struct resources_ispif *res);
int msm_ispif_register_entities(struct ispif_device *ispif, int msm_ispif_register_entities(struct ispif_device *ispif,
......
...@@ -768,10 +768,10 @@ static int camss_init_subdevices(struct camss *camss) ...@@ -768,10 +768,10 @@ static int camss_init_subdevices(struct camss *camss)
} }
} }
ret = msm_ispif_subdev_init(&camss->ispif, ispif_res); ret = msm_ispif_subdev_init(camss, ispif_res);
if (ret < 0) { if (ret < 0) {
dev_err(camss->dev, "Failed to init ispif sub-device: %d\n", dev_err(camss->dev, "Failed to init ispif sub-device: %d\n",
ret); ret);
return ret; return ret;
} }
...@@ -821,10 +821,11 @@ static int camss_register_entities(struct camss *camss) ...@@ -821,10 +821,11 @@ static int camss_register_entities(struct camss *camss)
} }
} }
ret = msm_ispif_register_entities(&camss->ispif, &camss->v4l2_dev); ret = msm_ispif_register_entities(camss->ispif,
&camss->v4l2_dev);
if (ret < 0) { if (ret < 0) {
dev_err(camss->dev, "Failed to register ispif entities: %d\n", dev_err(camss->dev, "Failed to register ispif entities: %d\n",
ret); ret);
goto err_reg_ispif; goto err_reg_ispif;
} }
...@@ -858,43 +859,68 @@ static int camss_register_entities(struct camss *camss) ...@@ -858,43 +859,68 @@ static int camss_register_entities(struct camss *camss)
} }
} }
for (i = 0; i < camss->csid_num; i++) { if (camss->ispif) {
for (j = 0; j < camss->ispif.line_num; j++) { for (i = 0; i < camss->csid_num; i++) {
ret = media_create_pad_link( for (j = 0; j < camss->ispif->line_num; j++) {
&camss->csid[i].subdev.entity,
MSM_CSID_PAD_SRC,
&camss->ispif.line[j].subdev.entity,
MSM_ISPIF_PAD_SINK,
0);
if (ret < 0) {
dev_err(camss->dev,
"Failed to link %s->%s entities: %d\n",
camss->csid[i].subdev.entity.name,
camss->ispif.line[j].subdev.entity.name,
ret);
goto err_link;
}
}
}
for (i = 0; i < camss->ispif.line_num; i++)
for (k = 0; k < camss->vfe_num; k++)
for (j = 0; j < ARRAY_SIZE(camss->vfe[k].line); j++) {
ret = media_create_pad_link( ret = media_create_pad_link(
&camss->ispif.line[i].subdev.entity, &camss->csid[i].subdev.entity,
MSM_ISPIF_PAD_SRC, MSM_CSID_PAD_SRC,
&camss->vfe[k].line[j].subdev.entity, &camss->ispif->line[j].subdev.entity,
MSM_VFE_PAD_SINK, MSM_ISPIF_PAD_SINK,
0); 0);
if (ret < 0) { if (ret < 0) {
dev_err(camss->dev, dev_err(camss->dev,
"Failed to link %s->%s entities: %d\n", "Failed to link %s->%s entities: %d\n",
camss->ispif.line[i].subdev.entity.name, camss->csid[i].subdev.entity.name,
camss->vfe[k].line[j].subdev.entity.name, camss->ispif->line[j].subdev.entity.name,
ret); ret);
goto err_link; goto err_link;
} }
} }
}
for (i = 0; i < camss->ispif->line_num; i++)
for (k = 0; k < camss->vfe_num; k++)
for (j = 0; j < ARRAY_SIZE(camss->vfe[k].line); j++) {
struct v4l2_subdev *ispif = &camss->ispif->line[i].subdev;
struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev;
ret = media_create_pad_link(&ispif->entity,
MSM_ISPIF_PAD_SRC,
&vfe->entity,
MSM_VFE_PAD_SINK,
0);
if (ret < 0) {
dev_err(camss->dev,
"Failed to link %s->%s entities: %d\n",
ispif->entity.name,
vfe->entity.name,
ret);
goto err_link;
}
}
} else {
for (i = 0; i < camss->csid_num; i++)
for (k = 0; k < camss->vfe_num; k++)
for (j = 0; j < ARRAY_SIZE(camss->vfe[k].line); j++) {
struct v4l2_subdev *csid = &camss->csid[i].subdev;
struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev;
ret = media_create_pad_link(&csid->entity,
MSM_CSID_PAD_SRC,
&vfe->entity,
MSM_VFE_PAD_SINK,
0);
if (ret < 0) {
dev_err(camss->dev,
"Failed to link %s->%s entities: %d\n",
csid->entity.name,
vfe->entity.name,
ret);
goto err_link;
}
}
}
return 0; return 0;
...@@ -904,8 +930,8 @@ static int camss_register_entities(struct camss *camss) ...@@ -904,8 +930,8 @@ static int camss_register_entities(struct camss *camss)
for (i--; i >= 0; i--) for (i--; i >= 0; i--)
msm_vfe_unregister_entities(&camss->vfe[i]); msm_vfe_unregister_entities(&camss->vfe[i]);
msm_ispif_unregister_entities(&camss->ispif);
err_reg_ispif: err_reg_ispif:
msm_ispif_unregister_entities(camss->ispif);
i = camss->csid_num; i = camss->csid_num;
err_reg_csid: err_reg_csid:
...@@ -936,7 +962,7 @@ static void camss_unregister_entities(struct camss *camss) ...@@ -936,7 +962,7 @@ static void camss_unregister_entities(struct camss *camss)
for (i = 0; i < camss->csid_num; i++) for (i = 0; i < camss->csid_num; i++)
msm_csid_unregister_entity(&camss->csid[i]); msm_csid_unregister_entity(&camss->csid[i]);
msm_ispif_unregister_entities(&camss->ispif); msm_ispif_unregister_entities(camss->ispif);
for (i = 0; i < camss->vfe_num; i++) for (i = 0; i < camss->vfe_num; i++)
msm_vfe_unregister_entities(&camss->vfe[i]); msm_vfe_unregister_entities(&camss->vfe[i]);
...@@ -1067,6 +1093,15 @@ static int camss_probe(struct platform_device *pdev) ...@@ -1067,6 +1093,15 @@ static int camss_probe(struct platform_device *pdev)
goto err_free; goto err_free;
} }
if (camss->version == CAMSS_8x16 ||
camss->version == CAMSS_8x96) {
camss->ispif = devm_kcalloc(dev, 1, sizeof(*camss->ispif), GFP_KERNEL);
if (!camss->ispif) {
ret = -ENOMEM;
goto err_free;
}
}
camss->vfe = devm_kcalloc(dev, camss->vfe_num, sizeof(*camss->vfe), camss->vfe = devm_kcalloc(dev, camss->vfe_num, sizeof(*camss->vfe),
GFP_KERNEL); GFP_KERNEL);
if (!camss->vfe) { if (!camss->vfe) {
......
...@@ -79,7 +79,7 @@ struct camss { ...@@ -79,7 +79,7 @@ struct camss {
struct csiphy_device *csiphy; struct csiphy_device *csiphy;
int csid_num; int csid_num;
struct csid_device *csid; struct csid_device *csid;
struct ispif_device ispif; struct ispif_device *ispif;
int vfe_num; int vfe_num;
struct vfe_device *vfe; struct vfe_device *vfe;
atomic_t ref_count; atomic_t ref_count;
......
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