Re: [PATCH 2/2] media: camss: Split power domain management

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 5 Jul 2022 at 00:15, Vladimir Zapolskiy
<vladimir.zapolskiy@xxxxxxxxxx> wrote:
>
> There are three cases of power domain management on supported platforms:
> 1) CAMSS on MSM8916, where a single VFE power domain is operated outside
>    of the camss device driver,
> 2) CAMSS on MSM8996 and SDM630/SDM660, where two VFE power domains are
>    managed separately by the camss device driver, the power domains are
>    linked and unlinked on demand by their functions vfe_pm_domain_on()
>    and vfe_pm_domain_off() respectively,
> 3) CAMSS on SDM845 and SM8250 platforms, and there are two VFE power
>    domains and their parent power domain TITAN_TOP, the latter one
>    shall be turned on prior to turning on any of VFE power domains.
>
> Due to a previously missing link between TITAN_TOP and VFEx power domains
> in the latter case, which is now fixed by [1], it was decided always to
> turn on all found VFE power domains and TITAN_TOP power domain, even if
> just one particular VFE is needed to be enabled or none of VFE power domains
> are required, for instance the latter case is when vfe_lite is in use.
> This misusage becomes more incovenient and clumsy, if next generations are
> to be supported, for instance CAMSS on SM8450 has three VFE power domains.
>
> The change splits the power management support for platforms with TITAN_TOP
> parent power domain, and, since 'power-domain-names' property is not present
> in camss device tree nodes, the assumption is that the first N power domains
> from the 'power-domains' list correspond to VFE power domains, and, if the
> number of power domains is greater than number of non-lite VFEs, then the
> last power domain from the list is the TITAN_TOP power domain.
>
> Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@xxxxxxxxxx>
> ---
>  .../media/platform/qcom/camss/camss-vfe-170.c | 20 ++++++++++++-
>  .../media/platform/qcom/camss/camss-vfe-480.c | 20 ++++++++++++-
>  drivers/media/platform/qcom/camss/camss.c     | 30 ++++++++++---------
>  3 files changed, 54 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe-170.c b/drivers/media/platform/qcom/camss/camss-vfe-170.c
> index 600150cfc4f7..8e506a805d11 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe-170.c
> +++ b/drivers/media/platform/qcom/camss/camss-vfe-170.c
> @@ -687,7 +687,12 @@ static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm)
>   */
>  static void vfe_pm_domain_off(struct vfe_device *vfe)
>  {
> -       /* nop */
> +       struct camss *camss = vfe->camss;
> +
> +       if (vfe->id >= camss->vfe_num)
> +               return;
> +
> +       device_link_del(camss->genpd_link[vfe->id]);
>  }
>
>  /*
> @@ -696,6 +701,19 @@ static void vfe_pm_domain_off(struct vfe_device *vfe)
>   */
>  static int vfe_pm_domain_on(struct vfe_device *vfe)
>  {
> +       struct camss *camss = vfe->camss;
> +       enum vfe_line_id id = vfe->id;
> +
> +       if (id >= camss->vfe_num)
> +               return 0;
> +
> +       camss->genpd_link[id] = device_link_add(camss->dev, camss->genpd[id],
> +                                               DL_FLAG_STATELESS |
> +                                               DL_FLAG_PM_RUNTIME |
> +                                               DL_FLAG_RPM_ACTIVE);
> +       if (!camss->genpd_link[id])
> +               return -EINVAL;
> +
>         return 0;
>  }
>
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe-480.c b/drivers/media/platform/qcom/camss/camss-vfe-480.c
> index 129585110393..3aa962b5663b 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe-480.c
> +++ b/drivers/media/platform/qcom/camss/camss-vfe-480.c
> @@ -494,7 +494,12 @@ static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm)
>   */
>  static void vfe_pm_domain_off(struct vfe_device *vfe)
>  {
> -       /* nop */
> +       struct camss *camss = vfe->camss;
> +
> +       if (vfe->id >= camss->vfe_num)
> +               return;
> +
> +       device_link_del(camss->genpd_link[vfe->id]);
>  }
>
>  /*
> @@ -503,6 +508,19 @@ static void vfe_pm_domain_off(struct vfe_device *vfe)
>   */
>  static int vfe_pm_domain_on(struct vfe_device *vfe)
>  {
> +       struct camss *camss = vfe->camss;
> +       enum vfe_line_id id = vfe->id;
> +
> +       if (id >= camss->vfe_num)
> +               return 0;
> +
> +       camss->genpd_link[id] = device_link_add(camss->dev, camss->genpd[id],
> +                                               DL_FLAG_STATELESS |
> +                                               DL_FLAG_PM_RUNTIME |
> +                                               DL_FLAG_RPM_ACTIVE);
> +       if (!camss->genpd_link[id])
> +               return -EINVAL;
> +
>         return 0;
>  }
>
> diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
> index 795eebd9af6c..f009297ba182 100644
> --- a/drivers/media/platform/qcom/camss/camss.c
> +++ b/drivers/media/platform/qcom/camss/camss.c
> @@ -1453,7 +1453,6 @@ static const struct media_device_ops camss_media_ops = {
>  static int camss_configure_pd(struct camss *camss)
>  {
>         struct device *dev = camss->dev;
> -       int last_pm_domain = 0;
>         int i;
>         int ret;
>
> @@ -1484,32 +1483,34 @@ static int camss_configure_pd(struct camss *camss)
>         if (!camss->genpd_link)
>                 return -ENOMEM;
>
> +       /*
> +        * VFE power domains are in the beginning of the list, and while all
> +        * power domains should be attached, only if TITAN_TOP power domain is
> +        * found in the list, it should be linked over here.
> +        */
>         for (i = 0; i < camss->genpd_num; i++) {
>                 camss->genpd[i] = dev_pm_domain_attach_by_id(camss->dev, i);
>                 if (IS_ERR(camss->genpd[i])) {
>                         ret = PTR_ERR(camss->genpd[i]);
>                         goto fail_pm;
>                 }
> +       }
>
> -               camss->genpd_link[i] = device_link_add(camss->dev, camss->genpd[i],
> -                                                      DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
> -                                                      DL_FLAG_RPM_ACTIVE);
> -               if (!camss->genpd_link[i]) {
> -                       dev_pm_domain_detach(camss->genpd[i], true);
> +       if (i > camss->vfe_num) {
> +               camss->genpd_link[i - 1] = device_link_add(camss->dev, camss->genpd[i - 1],
> +                                                          DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
> +                                                          DL_FLAG_RPM_ACTIVE);
> +               if (!camss->genpd_link[i - 1]) {
>                         ret = -EINVAL;
>                         goto fail_pm;
>                 }
> -
> -               last_pm_domain = i;
>         }
>
>         return 0;
>
>  fail_pm:
> -       for (i = 0; i < last_pm_domain; i++) {
> -               device_link_del(camss->genpd_link[i]);
> +       for (--i ; i >= 0; i--)
>                 dev_pm_domain_detach(camss->genpd[i], true);
> -       }
>
>         return ret;
>  }
> @@ -1711,10 +1712,11 @@ void camss_delete(struct camss *camss)
>         if (camss->genpd_num == 1)
>                 return;
>
> -       for (i = 0; i < camss->genpd_num; i++) {
> -               device_link_del(camss->genpd_link[i]);
> +       if (camss->genpd_num > camss->vfe_num)
> +               device_link_del(camss->genpd_link[camss->genpd_num - 1]);
> +
> +       for (i = 0; i < camss->genpd_num; i++)
>                 dev_pm_domain_detach(camss->genpd[i], true);
> -       }
>  }
>
>  /*
> --
> 2.33.0
>

Reviewed-by: Robert Foss <robert.foss@xxxxxxxxxx>



[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [Linux for Sparc]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux