Message ID | 20201018125237.16717-7-kholk11@gmail.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Add support for SDM630/660 Camera Subsystem | expand |
Looks good to me. Signed-off-by: Robert Foss <robert.foss@linaro.org> On Sun, 18 Oct 2020 at 14:53, <kholk11@gmail.com> wrote: > > From: AngeloGioacchino Del Regno <kholk11@gmail.com> > > The SDM630/660 SoCs (and variants) have another clock source > for the PHY, which must be set to a rate that's equal or > greater than the CSI PHY timer clock: failing to do this > will produce PHY overflows when trying to get a stream from > a very high bandwidth camera sensor and outputting no frame > or a partial one. > > Since I haven't found any usecase in which the csiX_phy > clock needs to be higher than the csiXphy_timer, let's just > set the same rate on both, which seems to work just perfect. > > Signed-off-by: AngeloGioacchino Del Regno <kholk11@gmail.com> > --- > .../media/platform/qcom/camss/camss-csiphy.c | 22 ++++++++++++++++--- > .../media/platform/qcom/camss/camss-csiphy.h | 1 + > 2 files changed, 20 insertions(+), 3 deletions(-) > > diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c > index c00f25aac21b..a5d717d022a5 100644 > --- a/drivers/media/platform/qcom/camss/camss-csiphy.c > +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c > @@ -113,9 +113,7 @@ static int csiphy_set_clock_rates(struct csiphy_device *csiphy) > for (i = 0; i < csiphy->nclocks; i++) { > struct camss_clock *clock = &csiphy->clock[i]; > > - if (!strcmp(clock->name, "csiphy0_timer") || > - !strcmp(clock->name, "csiphy1_timer") || > - !strcmp(clock->name, "csiphy2_timer")) { > + if (csiphy->rate_set[i]) { > u8 bpp = csiphy_get_bpp(csiphy->formats, > csiphy->nformats, > csiphy->fmt[MSM_CSIPHY_PAD_SINK].code); > @@ -611,6 +609,13 @@ int msm_csiphy_subdev_init(struct camss *camss, > if (!csiphy->clock) > return -ENOMEM; > > + csiphy->rate_set = devm_kcalloc(dev, > + csiphy->nclocks, > + sizeof(*csiphy->rate_set), > + GFP_KERNEL); > + if (!csiphy->rate_set) > + return -ENOMEM; > + > for (i = 0; i < csiphy->nclocks; i++) { > struct camss_clock *clock = &csiphy->clock[i]; > > @@ -638,6 +643,17 @@ int msm_csiphy_subdev_init(struct camss *camss, > > for (j = 0; j < clock->nfreqs; j++) > clock->freq[j] = res->clock_rate[i][j]; > + > + if (!strcmp(clock->name, "csiphy0_timer") || > + !strcmp(clock->name, "csiphy1_timer") || > + !strcmp(clock->name, "csiphy2_timer")) > + csiphy->rate_set[i] = true; > + > + if (camss->version == CAMSS_660 && > + (!strcmp(clock->name, "csi0_phy") || > + !strcmp(clock->name, "csi1_phy") || > + !strcmp(clock->name, "csi2_phy"))) > + csiphy->rate_set[i] = true; > } > > return 0; > diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h > index 376f865ad383..f7967ef836dc 100644 > --- a/drivers/media/platform/qcom/camss/camss-csiphy.h > +++ b/drivers/media/platform/qcom/camss/camss-csiphy.h > @@ -66,6 +66,7 @@ struct csiphy_device { > u32 irq; > char irq_name[30]; > struct camss_clock *clock; > + bool *rate_set; > int nclocks; > u32 timer_clk_rate; > struct csiphy_config cfg; > -- > 2.28.0 >
diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c index c00f25aac21b..a5d717d022a5 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -113,9 +113,7 @@ static int csiphy_set_clock_rates(struct csiphy_device *csiphy) for (i = 0; i < csiphy->nclocks; i++) { struct camss_clock *clock = &csiphy->clock[i]; - if (!strcmp(clock->name, "csiphy0_timer") || - !strcmp(clock->name, "csiphy1_timer") || - !strcmp(clock->name, "csiphy2_timer")) { + if (csiphy->rate_set[i]) { u8 bpp = csiphy_get_bpp(csiphy->formats, csiphy->nformats, csiphy->fmt[MSM_CSIPHY_PAD_SINK].code); @@ -611,6 +609,13 @@ int msm_csiphy_subdev_init(struct camss *camss, if (!csiphy->clock) return -ENOMEM; + csiphy->rate_set = devm_kcalloc(dev, + csiphy->nclocks, + sizeof(*csiphy->rate_set), + GFP_KERNEL); + if (!csiphy->rate_set) + return -ENOMEM; + for (i = 0; i < csiphy->nclocks; i++) { struct camss_clock *clock = &csiphy->clock[i]; @@ -638,6 +643,17 @@ int msm_csiphy_subdev_init(struct camss *camss, for (j = 0; j < clock->nfreqs; j++) clock->freq[j] = res->clock_rate[i][j]; + + if (!strcmp(clock->name, "csiphy0_timer") || + !strcmp(clock->name, "csiphy1_timer") || + !strcmp(clock->name, "csiphy2_timer")) + csiphy->rate_set[i] = true; + + if (camss->version == CAMSS_660 && + (!strcmp(clock->name, "csi0_phy") || + !strcmp(clock->name, "csi1_phy") || + !strcmp(clock->name, "csi2_phy"))) + csiphy->rate_set[i] = true; } return 0; diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h index 376f865ad383..f7967ef836dc 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.h +++ b/drivers/media/platform/qcom/camss/camss-csiphy.h @@ -66,6 +66,7 @@ struct csiphy_device { u32 irq; char irq_name[30]; struct camss_clock *clock; + bool *rate_set; int nclocks; u32 timer_clk_rate; struct csiphy_config cfg;