root/arch/arm/mach-zx/zx296702-pm-domain.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. normal_power_off
  2. normal_power_on
  3. zx296702_pd_probe
  4. zx296702_pd_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (C) 2015 Linaro Ltd.
   4  *
   5  * Author: Jun Nie <jun.nie@linaro.org>
   6  */
   7 #include <linux/delay.h>
   8 #include <linux/err.h>
   9 #include <linux/io.h>
  10 #include <linux/of.h>
  11 #include <linux/platform_device.h>
  12 #include <linux/pm_domain.h>
  13 #include <linux/slab.h>
  14 
  15 #define PCU_DM_CLKEN        0x18
  16 #define PCU_DM_RSTEN        0x1C
  17 #define PCU_DM_ISOEN        0x20
  18 #define PCU_DM_PWRDN        0x24
  19 #define PCU_DM_ACK_SYNC     0x28
  20 
  21 enum {
  22         PCU_DM_NEON0 = 0,
  23         PCU_DM_NEON1,
  24         PCU_DM_GPU,
  25         PCU_DM_DECPPU,
  26         PCU_DM_VOU,
  27         PCU_DM_R2D,
  28         PCU_DM_TOP,
  29 };
  30 
  31 static void __iomem *pcubase;
  32 
  33 struct zx_pm_domain {
  34         struct generic_pm_domain dm;
  35         unsigned int bit;
  36 };
  37 
  38 static int normal_power_off(struct generic_pm_domain *domain)
  39 {
  40         struct zx_pm_domain *zpd = (struct zx_pm_domain *)domain;
  41         unsigned long loop = 1000;
  42         u32 tmp;
  43 
  44         tmp = readl_relaxed(pcubase + PCU_DM_CLKEN);
  45         tmp &= ~BIT(zpd->bit);
  46         writel_relaxed(tmp, pcubase + PCU_DM_CLKEN);
  47         udelay(5);
  48 
  49         tmp = readl_relaxed(pcubase + PCU_DM_ISOEN);
  50         tmp &= ~BIT(zpd->bit);
  51         writel_relaxed(tmp | BIT(zpd->bit), pcubase + PCU_DM_ISOEN);
  52         udelay(5);
  53 
  54         tmp = readl_relaxed(pcubase + PCU_DM_RSTEN);
  55         tmp &= ~BIT(zpd->bit);
  56         writel_relaxed(tmp, pcubase + PCU_DM_RSTEN);
  57         udelay(5);
  58 
  59         tmp = readl_relaxed(pcubase + PCU_DM_PWRDN);
  60         tmp &= ~BIT(zpd->bit);
  61         writel_relaxed(tmp | BIT(zpd->bit), pcubase + PCU_DM_PWRDN);
  62         do {
  63                 tmp = readl_relaxed(pcubase + PCU_DM_ACK_SYNC) & BIT(zpd->bit);
  64         } while (--loop && !tmp);
  65 
  66         if (!loop) {
  67                 pr_err("Error: %s %s fail\n", __func__, domain->name);
  68                 return -EIO;
  69         }
  70 
  71         return 0;
  72 }
  73 
  74 static int normal_power_on(struct generic_pm_domain *domain)
  75 {
  76         struct zx_pm_domain *zpd = (struct zx_pm_domain *)domain;
  77         unsigned long loop = 10000;
  78         u32 tmp;
  79 
  80         tmp = readl_relaxed(pcubase + PCU_DM_PWRDN);
  81         tmp &= ~BIT(zpd->bit);
  82         writel_relaxed(tmp, pcubase + PCU_DM_PWRDN);
  83         do {
  84                 tmp = readl_relaxed(pcubase + PCU_DM_ACK_SYNC) & BIT(zpd->bit);
  85         } while (--loop && tmp);
  86 
  87         if (!loop) {
  88                 pr_err("Error: %s %s fail\n", __func__, domain->name);
  89                 return -EIO;
  90         }
  91 
  92         tmp = readl_relaxed(pcubase + PCU_DM_RSTEN);
  93         tmp &= ~BIT(zpd->bit);
  94         writel_relaxed(tmp | BIT(zpd->bit), pcubase + PCU_DM_RSTEN);
  95         udelay(5);
  96 
  97         tmp = readl_relaxed(pcubase + PCU_DM_ISOEN);
  98         tmp &= ~BIT(zpd->bit);
  99         writel_relaxed(tmp, pcubase + PCU_DM_ISOEN);
 100         udelay(5);
 101 
 102         tmp = readl_relaxed(pcubase + PCU_DM_CLKEN);
 103         tmp &= ~BIT(zpd->bit);
 104         writel_relaxed(tmp | BIT(zpd->bit), pcubase + PCU_DM_CLKEN);
 105         udelay(5);
 106         return 0;
 107 }
 108 
 109 static struct zx_pm_domain gpu_domain = {
 110         .dm = {
 111                 .name           = "gpu_domain",
 112                 .power_off      = normal_power_off,
 113                 .power_on       = normal_power_on,
 114         },
 115         .bit = PCU_DM_GPU,
 116 };
 117 
 118 static struct zx_pm_domain decppu_domain = {
 119         .dm = {
 120                 .name           = "decppu_domain",
 121                 .power_off      = normal_power_off,
 122                 .power_on       = normal_power_on,
 123         },
 124         .bit = PCU_DM_DECPPU,
 125 };
 126 
 127 static struct zx_pm_domain vou_domain = {
 128         .dm = {
 129                 .name           = "vou_domain",
 130                 .power_off      = normal_power_off,
 131                 .power_on       = normal_power_on,
 132         },
 133         .bit = PCU_DM_VOU,
 134 };
 135 
 136 static struct zx_pm_domain r2d_domain = {
 137         .dm = {
 138                 .name           = "r2d_domain",
 139                 .power_off      = normal_power_off,
 140                 .power_on       = normal_power_on,
 141         },
 142         .bit = PCU_DM_R2D,
 143 };
 144 
 145 static struct generic_pm_domain *zx296702_pm_domains[] = {
 146         &vou_domain.dm,
 147         &gpu_domain.dm,
 148         &decppu_domain.dm,
 149         &r2d_domain.dm,
 150 };
 151 
 152 static int zx296702_pd_probe(struct platform_device *pdev)
 153 {
 154         struct genpd_onecell_data *genpd_data;
 155         struct resource *res;
 156         int i;
 157 
 158         genpd_data = devm_kzalloc(&pdev->dev, sizeof(*genpd_data), GFP_KERNEL);
 159         if (!genpd_data)
 160                 return -ENOMEM;
 161 
 162         genpd_data->domains = zx296702_pm_domains;
 163         genpd_data->num_domains = ARRAY_SIZE(zx296702_pm_domains);
 164 
 165         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 166         if (!res) {
 167                 dev_err(&pdev->dev, "no memory resource defined\n");
 168                 return -ENODEV;
 169         }
 170 
 171         pcubase = devm_ioremap_resource(&pdev->dev, res);
 172         if (IS_ERR(pcubase)) {
 173                 dev_err(&pdev->dev, "ioremap fail.\n");
 174                 return -EIO;
 175         }
 176 
 177         for (i = 0; i < ARRAY_SIZE(zx296702_pm_domains); ++i)
 178                 pm_genpd_init(zx296702_pm_domains[i], NULL, false);
 179 
 180         of_genpd_add_provider_onecell(pdev->dev.of_node, genpd_data);
 181         return 0;
 182 }
 183 
 184 static const struct of_device_id zx296702_pm_domain_matches[] __initconst = {
 185         { .compatible = "zte,zx296702-pcu", },
 186         { },
 187 };
 188 
 189 static struct platform_driver zx296702_pd_driver __initdata = {
 190         .driver = {
 191                 .name = "zx-powerdomain",
 192                 .owner = THIS_MODULE,
 193                 .of_match_table = zx296702_pm_domain_matches,
 194         },
 195         .probe = zx296702_pd_probe,
 196 };
 197 
 198 static int __init zx296702_pd_init(void)
 199 {
 200         return platform_driver_register(&zx296702_pd_driver);
 201 }
 202 subsys_initcall(zx296702_pd_init);

/* [<][>][^][v][top][bottom][index][help] */