root/drivers/soc/zte/zx2967_pm_domains.c

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

DEFINITIONS

This source file includes following definitions.
  1. zx2967_power_on
  2. zx2967_power_off
  3. zx2967_pd_probe

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (C) 2017 ZTE Ltd.
   4  *
   5  * Author: Baoyou Xie <baoyou.xie@linaro.org>
   6  */
   7 
   8 #include <linux/delay.h>
   9 #include <linux/err.h>
  10 #include <linux/io.h>
  11 #include <linux/of.h>
  12 
  13 #include "zx2967_pm_domains.h"
  14 
  15 #define PCU_DM_CLKEN(zpd)       ((zpd)->reg_offset[REG_CLKEN])
  16 #define PCU_DM_ISOEN(zpd)       ((zpd)->reg_offset[REG_ISOEN])
  17 #define PCU_DM_RSTEN(zpd)       ((zpd)->reg_offset[REG_RSTEN])
  18 #define PCU_DM_PWREN(zpd)       ((zpd)->reg_offset[REG_PWREN])
  19 #define PCU_DM_ACK_SYNC(zpd)    ((zpd)->reg_offset[REG_ACK_SYNC])
  20 
  21 static void __iomem *pcubase;
  22 
  23 static int zx2967_power_on(struct generic_pm_domain *domain)
  24 {
  25         struct zx2967_pm_domain *zpd = (struct zx2967_pm_domain *)domain;
  26         unsigned long loop = 1000;
  27         u32 val;
  28 
  29         val = readl_relaxed(pcubase + PCU_DM_PWREN(zpd));
  30         if (zpd->polarity == PWREN)
  31                 val |= BIT(zpd->bit);
  32         else
  33                 val &= ~BIT(zpd->bit);
  34         writel_relaxed(val, pcubase + PCU_DM_PWREN(zpd));
  35 
  36         do {
  37                 udelay(1);
  38                 val = readl_relaxed(pcubase + PCU_DM_ACK_SYNC(zpd))
  39                                    & BIT(zpd->bit);
  40         } while (--loop && !val);
  41 
  42         if (!loop) {
  43                 pr_err("Error: %s %s fail\n", __func__, domain->name);
  44                 return -EIO;
  45         }
  46 
  47         val = readl_relaxed(pcubase + PCU_DM_RSTEN(zpd));
  48         val |= BIT(zpd->bit);
  49         writel_relaxed(val, pcubase + PCU_DM_RSTEN(zpd));
  50         udelay(5);
  51 
  52         val = readl_relaxed(pcubase + PCU_DM_ISOEN(zpd));
  53         val &= ~BIT(zpd->bit);
  54         writel_relaxed(val, pcubase + PCU_DM_ISOEN(zpd));
  55         udelay(5);
  56 
  57         val = readl_relaxed(pcubase + PCU_DM_CLKEN(zpd));
  58         val |= BIT(zpd->bit);
  59         writel_relaxed(val, pcubase + PCU_DM_CLKEN(zpd));
  60         udelay(5);
  61 
  62         pr_debug("poweron %s\n", domain->name);
  63 
  64         return 0;
  65 }
  66 
  67 static int zx2967_power_off(struct generic_pm_domain *domain)
  68 {
  69         struct zx2967_pm_domain *zpd = (struct zx2967_pm_domain *)domain;
  70         unsigned long loop = 1000;
  71         u32 val;
  72 
  73         val = readl_relaxed(pcubase + PCU_DM_CLKEN(zpd));
  74         val &= ~BIT(zpd->bit);
  75         writel_relaxed(val, pcubase + PCU_DM_CLKEN(zpd));
  76         udelay(5);
  77 
  78         val = readl_relaxed(pcubase + PCU_DM_ISOEN(zpd));
  79         val |= BIT(zpd->bit);
  80         writel_relaxed(val, pcubase + PCU_DM_ISOEN(zpd));
  81         udelay(5);
  82 
  83         val = readl_relaxed(pcubase + PCU_DM_RSTEN(zpd));
  84         val &= ~BIT(zpd->bit);
  85         writel_relaxed(val, pcubase + PCU_DM_RSTEN(zpd));
  86         udelay(5);
  87 
  88         val = readl_relaxed(pcubase + PCU_DM_PWREN(zpd));
  89         if (zpd->polarity == PWREN)
  90                 val &= ~BIT(zpd->bit);
  91         else
  92                 val |= BIT(zpd->bit);
  93         writel_relaxed(val, pcubase + PCU_DM_PWREN(zpd));
  94 
  95         do {
  96                 udelay(1);
  97                 val = readl_relaxed(pcubase + PCU_DM_ACK_SYNC(zpd))
  98                                    & BIT(zpd->bit);
  99         } while (--loop && val);
 100 
 101         if (!loop) {
 102                 pr_err("Error: %s %s fail\n", __func__, domain->name);
 103                 return -EIO;
 104         }
 105 
 106         pr_debug("poweroff %s\n", domain->name);
 107 
 108         return 0;
 109 }
 110 
 111 int zx2967_pd_probe(struct platform_device *pdev,
 112                     struct generic_pm_domain **zx_pm_domains,
 113                     int domain_num)
 114 {
 115         struct genpd_onecell_data *genpd_data;
 116         struct resource *res;
 117         int i;
 118 
 119         genpd_data = devm_kzalloc(&pdev->dev, sizeof(*genpd_data), GFP_KERNEL);
 120         if (!genpd_data)
 121                 return -ENOMEM;
 122 
 123         genpd_data->domains = zx_pm_domains;
 124         genpd_data->num_domains = domain_num;
 125 
 126         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 127         pcubase = devm_ioremap_resource(&pdev->dev, res);
 128         if (IS_ERR(pcubase))
 129                 return PTR_ERR(pcubase);
 130 
 131         for (i = 0; i < domain_num; ++i) {
 132                 zx_pm_domains[i]->power_on = zx2967_power_on;
 133                 zx_pm_domains[i]->power_off = zx2967_power_off;
 134 
 135                 pm_genpd_init(zx_pm_domains[i], NULL, false);
 136         }
 137 
 138         of_genpd_add_provider_onecell(pdev->dev.of_node, genpd_data);
 139         dev_info(&pdev->dev, "powerdomain init ok\n");
 140         return 0;
 141 }

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