0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/of_address.h>
0012 #include <linux/of_platform.h>
0013 #include <linux/pm_domain.h>
0014 #include <linux/soc/actions/owl-sps.h>
0015 #include <dt-bindings/power/owl-s500-powergate.h>
0016 #include <dt-bindings/power/owl-s700-powergate.h>
0017 #include <dt-bindings/power/owl-s900-powergate.h>
0018
0019 struct owl_sps_domain_info {
0020 const char *name;
0021 int pwr_bit;
0022 int ack_bit;
0023 unsigned int genpd_flags;
0024 };
0025
0026 struct owl_sps_info {
0027 unsigned num_domains;
0028 const struct owl_sps_domain_info *domains;
0029 };
0030
0031 struct owl_sps {
0032 struct device *dev;
0033 const struct owl_sps_info *info;
0034 void __iomem *base;
0035 struct genpd_onecell_data genpd_data;
0036 struct generic_pm_domain *domains[];
0037 };
0038
0039 #define to_owl_pd(gpd) container_of(gpd, struct owl_sps_domain, genpd)
0040
0041 struct owl_sps_domain {
0042 struct generic_pm_domain genpd;
0043 const struct owl_sps_domain_info *info;
0044 struct owl_sps *sps;
0045 };
0046
0047 static int owl_sps_set_power(struct owl_sps_domain *pd, bool enable)
0048 {
0049 u32 pwr_mask, ack_mask;
0050
0051 ack_mask = BIT(pd->info->ack_bit);
0052 pwr_mask = BIT(pd->info->pwr_bit);
0053
0054 return owl_sps_set_pg(pd->sps->base, pwr_mask, ack_mask, enable);
0055 }
0056
0057 static int owl_sps_power_on(struct generic_pm_domain *domain)
0058 {
0059 struct owl_sps_domain *pd = to_owl_pd(domain);
0060
0061 dev_dbg(pd->sps->dev, "%s power on", pd->info->name);
0062
0063 return owl_sps_set_power(pd, true);
0064 }
0065
0066 static int owl_sps_power_off(struct generic_pm_domain *domain)
0067 {
0068 struct owl_sps_domain *pd = to_owl_pd(domain);
0069
0070 dev_dbg(pd->sps->dev, "%s power off", pd->info->name);
0071
0072 return owl_sps_set_power(pd, false);
0073 }
0074
0075 static int owl_sps_init_domain(struct owl_sps *sps, int index)
0076 {
0077 struct owl_sps_domain *pd;
0078
0079 pd = devm_kzalloc(sps->dev, sizeof(*pd), GFP_KERNEL);
0080 if (!pd)
0081 return -ENOMEM;
0082
0083 pd->info = &sps->info->domains[index];
0084 pd->sps = sps;
0085
0086 pd->genpd.name = pd->info->name;
0087 pd->genpd.power_on = owl_sps_power_on;
0088 pd->genpd.power_off = owl_sps_power_off;
0089 pd->genpd.flags = pd->info->genpd_flags;
0090 pm_genpd_init(&pd->genpd, NULL, false);
0091
0092 sps->genpd_data.domains[index] = &pd->genpd;
0093
0094 return 0;
0095 }
0096
0097 static int owl_sps_probe(struct platform_device *pdev)
0098 {
0099 const struct of_device_id *match;
0100 const struct owl_sps_info *sps_info;
0101 struct owl_sps *sps;
0102 int i, ret;
0103
0104 if (!pdev->dev.of_node) {
0105 dev_err(&pdev->dev, "no device node\n");
0106 return -ENODEV;
0107 }
0108
0109 match = of_match_device(pdev->dev.driver->of_match_table, &pdev->dev);
0110 if (!match || !match->data) {
0111 dev_err(&pdev->dev, "unknown compatible or missing data\n");
0112 return -EINVAL;
0113 }
0114
0115 sps_info = match->data;
0116
0117 sps = devm_kzalloc(&pdev->dev,
0118 struct_size(sps, domains, sps_info->num_domains),
0119 GFP_KERNEL);
0120 if (!sps)
0121 return -ENOMEM;
0122
0123 sps->base = of_io_request_and_map(pdev->dev.of_node, 0, "owl-sps");
0124 if (IS_ERR(sps->base)) {
0125 dev_err(&pdev->dev, "failed to map sps registers\n");
0126 return PTR_ERR(sps->base);
0127 }
0128
0129 sps->dev = &pdev->dev;
0130 sps->info = sps_info;
0131 sps->genpd_data.domains = sps->domains;
0132 sps->genpd_data.num_domains = sps_info->num_domains;
0133
0134 for (i = 0; i < sps_info->num_domains; i++) {
0135 ret = owl_sps_init_domain(sps, i);
0136 if (ret)
0137 return ret;
0138 }
0139
0140 ret = of_genpd_add_provider_onecell(pdev->dev.of_node, &sps->genpd_data);
0141 if (ret) {
0142 dev_err(&pdev->dev, "failed to add provider (%d)", ret);
0143 return ret;
0144 }
0145
0146 return 0;
0147 }
0148
0149 static const struct owl_sps_domain_info s500_sps_domains[] = {
0150 [S500_PD_VDE] = {
0151 .name = "VDE",
0152 .pwr_bit = 0,
0153 .ack_bit = 16,
0154 },
0155 [S500_PD_VCE_SI] = {
0156 .name = "VCE_SI",
0157 .pwr_bit = 1,
0158 .ack_bit = 17,
0159 },
0160 [S500_PD_USB2_1] = {
0161 .name = "USB2_1",
0162 .pwr_bit = 2,
0163 .ack_bit = 18,
0164 },
0165 [S500_PD_CPU2] = {
0166 .name = "CPU2",
0167 .pwr_bit = 5,
0168 .ack_bit = 21,
0169 .genpd_flags = GENPD_FLAG_ALWAYS_ON,
0170 },
0171 [S500_PD_CPU3] = {
0172 .name = "CPU3",
0173 .pwr_bit = 6,
0174 .ack_bit = 22,
0175 .genpd_flags = GENPD_FLAG_ALWAYS_ON,
0176 },
0177 [S500_PD_DMA] = {
0178 .name = "DMA",
0179 .pwr_bit = 8,
0180 .ack_bit = 12,
0181 },
0182 [S500_PD_DS] = {
0183 .name = "DS",
0184 .pwr_bit = 9,
0185 .ack_bit = 13,
0186 },
0187 [S500_PD_USB3] = {
0188 .name = "USB3",
0189 .pwr_bit = 10,
0190 .ack_bit = 14,
0191 },
0192 [S500_PD_USB2_0] = {
0193 .name = "USB2_0",
0194 .pwr_bit = 11,
0195 .ack_bit = 15,
0196 },
0197 };
0198
0199 static const struct owl_sps_info s500_sps_info = {
0200 .num_domains = ARRAY_SIZE(s500_sps_domains),
0201 .domains = s500_sps_domains,
0202 };
0203
0204 static const struct owl_sps_domain_info s700_sps_domains[] = {
0205 [S700_PD_VDE] = {
0206 .name = "VDE",
0207 .pwr_bit = 0,
0208 },
0209 [S700_PD_VCE_SI] = {
0210 .name = "VCE_SI",
0211 .pwr_bit = 1,
0212 },
0213 [S700_PD_USB2_1] = {
0214 .name = "USB2_1",
0215 .pwr_bit = 2,
0216 },
0217 [S700_PD_HDE] = {
0218 .name = "HDE",
0219 .pwr_bit = 7,
0220 },
0221 [S700_PD_DMA] = {
0222 .name = "DMA",
0223 .pwr_bit = 8,
0224 },
0225 [S700_PD_DS] = {
0226 .name = "DS",
0227 .pwr_bit = 9,
0228 },
0229 [S700_PD_USB3] = {
0230 .name = "USB3",
0231 .pwr_bit = 10,
0232 },
0233 [S700_PD_USB2_0] = {
0234 .name = "USB2_0",
0235 .pwr_bit = 11,
0236 },
0237 };
0238
0239 static const struct owl_sps_info s700_sps_info = {
0240 .num_domains = ARRAY_SIZE(s700_sps_domains),
0241 .domains = s700_sps_domains,
0242 };
0243
0244 static const struct owl_sps_domain_info s900_sps_domains[] = {
0245 [S900_PD_GPU_B] = {
0246 .name = "GPU_B",
0247 .pwr_bit = 3,
0248 },
0249 [S900_PD_VCE] = {
0250 .name = "VCE",
0251 .pwr_bit = 4,
0252 },
0253 [S900_PD_SENSOR] = {
0254 .name = "SENSOR",
0255 .pwr_bit = 5,
0256 },
0257 [S900_PD_VDE] = {
0258 .name = "VDE",
0259 .pwr_bit = 6,
0260 },
0261 [S900_PD_HDE] = {
0262 .name = "HDE",
0263 .pwr_bit = 7,
0264 },
0265 [S900_PD_USB3] = {
0266 .name = "USB3",
0267 .pwr_bit = 8,
0268 },
0269 [S900_PD_DDR0] = {
0270 .name = "DDR0",
0271 .pwr_bit = 9,
0272 },
0273 [S900_PD_DDR1] = {
0274 .name = "DDR1",
0275 .pwr_bit = 10,
0276 },
0277 [S900_PD_DE] = {
0278 .name = "DE",
0279 .pwr_bit = 13,
0280 },
0281 [S900_PD_NAND] = {
0282 .name = "NAND",
0283 .pwr_bit = 14,
0284 },
0285 [S900_PD_USB2_H0] = {
0286 .name = "USB2_H0",
0287 .pwr_bit = 15,
0288 },
0289 [S900_PD_USB2_H1] = {
0290 .name = "USB2_H1",
0291 .pwr_bit = 16,
0292 },
0293 };
0294
0295 static const struct owl_sps_info s900_sps_info = {
0296 .num_domains = ARRAY_SIZE(s900_sps_domains),
0297 .domains = s900_sps_domains,
0298 };
0299
0300 static const struct of_device_id owl_sps_of_matches[] = {
0301 { .compatible = "actions,s500-sps", .data = &s500_sps_info },
0302 { .compatible = "actions,s700-sps", .data = &s700_sps_info },
0303 { .compatible = "actions,s900-sps", .data = &s900_sps_info },
0304 { }
0305 };
0306
0307 static struct platform_driver owl_sps_platform_driver = {
0308 .probe = owl_sps_probe,
0309 .driver = {
0310 .name = "owl-sps",
0311 .of_match_table = owl_sps_of_matches,
0312 .suppress_bind_attrs = true,
0313 },
0314 };
0315
0316 static int __init owl_sps_init(void)
0317 {
0318 return platform_driver_register(&owl_sps_platform_driver);
0319 }
0320 postcore_initcall(owl_sps_init);