1/* 2 * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 */ 13#include <linux/clk.h> 14#include <linux/delay.h> 15#include <linux/io.h> 16#include <linux/kernel.h> 17#include <linux/mfd/syscon.h> 18#include <linux/module.h> 19#include <linux/of_device.h> 20#include <linux/platform_device.h> 21#include <linux/pm_domain.h> 22#include <linux/regmap.h> 23#include <linux/soc/mediatek/infracfg.h> 24#include <dt-bindings/power/mt8173-power.h> 25 26#define SPM_VDE_PWR_CON 0x0210 27#define SPM_MFG_PWR_CON 0x0214 28#define SPM_VEN_PWR_CON 0x0230 29#define SPM_ISP_PWR_CON 0x0238 30#define SPM_DIS_PWR_CON 0x023c 31#define SPM_VEN2_PWR_CON 0x0298 32#define SPM_AUDIO_PWR_CON 0x029c 33#define SPM_MFG_2D_PWR_CON 0x02c0 34#define SPM_MFG_ASYNC_PWR_CON 0x02c4 35#define SPM_USB_PWR_CON 0x02cc 36#define SPM_PWR_STATUS 0x060c 37#define SPM_PWR_STATUS_2ND 0x0610 38 39#define PWR_RST_B_BIT BIT(0) 40#define PWR_ISO_BIT BIT(1) 41#define PWR_ON_BIT BIT(2) 42#define PWR_ON_2ND_BIT BIT(3) 43#define PWR_CLK_DIS_BIT BIT(4) 44 45#define PWR_STATUS_DISP BIT(3) 46#define PWR_STATUS_MFG BIT(4) 47#define PWR_STATUS_ISP BIT(5) 48#define PWR_STATUS_VDEC BIT(7) 49#define PWR_STATUS_VENC_LT BIT(20) 50#define PWR_STATUS_VENC BIT(21) 51#define PWR_STATUS_MFG_2D BIT(22) 52#define PWR_STATUS_MFG_ASYNC BIT(23) 53#define PWR_STATUS_AUDIO BIT(24) 54#define PWR_STATUS_USB BIT(25) 55 56enum clk_id { 57 MT8173_CLK_NONE, 58 MT8173_CLK_MM, 59 MT8173_CLK_MFG, 60 MT8173_CLK_VENC, 61 MT8173_CLK_VENC_LT, 62 MT8173_CLK_MAX, 63}; 64 65#define MAX_CLKS 2 66 67struct scp_domain_data { 68 const char *name; 69 u32 sta_mask; 70 int ctl_offs; 71 u32 sram_pdn_bits; 72 u32 sram_pdn_ack_bits; 73 u32 bus_prot_mask; 74 enum clk_id clk_id[MAX_CLKS]; 75 bool active_wakeup; 76}; 77 78static const struct scp_domain_data scp_domain_data[] __initconst = { 79 [MT8173_POWER_DOMAIN_VDEC] = { 80 .name = "vdec", 81 .sta_mask = PWR_STATUS_VDEC, 82 .ctl_offs = SPM_VDE_PWR_CON, 83 .sram_pdn_bits = GENMASK(11, 8), 84 .sram_pdn_ack_bits = GENMASK(12, 12), 85 .clk_id = {MT8173_CLK_MM}, 86 }, 87 [MT8173_POWER_DOMAIN_VENC] = { 88 .name = "venc", 89 .sta_mask = PWR_STATUS_VENC, 90 .ctl_offs = SPM_VEN_PWR_CON, 91 .sram_pdn_bits = GENMASK(11, 8), 92 .sram_pdn_ack_bits = GENMASK(15, 12), 93 .clk_id = {MT8173_CLK_MM, MT8173_CLK_VENC}, 94 }, 95 [MT8173_POWER_DOMAIN_ISP] = { 96 .name = "isp", 97 .sta_mask = PWR_STATUS_ISP, 98 .ctl_offs = SPM_ISP_PWR_CON, 99 .sram_pdn_bits = GENMASK(11, 8), 100 .sram_pdn_ack_bits = GENMASK(13, 12), 101 .clk_id = {MT8173_CLK_MM}, 102 }, 103 [MT8173_POWER_DOMAIN_MM] = { 104 .name = "mm", 105 .sta_mask = PWR_STATUS_DISP, 106 .ctl_offs = SPM_DIS_PWR_CON, 107 .sram_pdn_bits = GENMASK(11, 8), 108 .sram_pdn_ack_bits = GENMASK(12, 12), 109 .clk_id = {MT8173_CLK_MM}, 110 .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 | 111 MT8173_TOP_AXI_PROT_EN_MM_M1, 112 }, 113 [MT8173_POWER_DOMAIN_VENC_LT] = { 114 .name = "venc_lt", 115 .sta_mask = PWR_STATUS_VENC_LT, 116 .ctl_offs = SPM_VEN2_PWR_CON, 117 .sram_pdn_bits = GENMASK(11, 8), 118 .sram_pdn_ack_bits = GENMASK(15, 12), 119 .clk_id = {MT8173_CLK_MM, MT8173_CLK_VENC_LT}, 120 }, 121 [MT8173_POWER_DOMAIN_AUDIO] = { 122 .name = "audio", 123 .sta_mask = PWR_STATUS_AUDIO, 124 .ctl_offs = SPM_AUDIO_PWR_CON, 125 .sram_pdn_bits = GENMASK(11, 8), 126 .sram_pdn_ack_bits = GENMASK(15, 12), 127 .clk_id = {MT8173_CLK_NONE}, 128 }, 129 [MT8173_POWER_DOMAIN_USB] = { 130 .name = "usb", 131 .sta_mask = PWR_STATUS_USB, 132 .ctl_offs = SPM_USB_PWR_CON, 133 .sram_pdn_bits = GENMASK(11, 8), 134 .sram_pdn_ack_bits = GENMASK(15, 12), 135 .clk_id = {MT8173_CLK_NONE}, 136 .active_wakeup = true, 137 }, 138 [MT8173_POWER_DOMAIN_MFG_ASYNC] = { 139 .name = "mfg_async", 140 .sta_mask = PWR_STATUS_MFG_ASYNC, 141 .ctl_offs = SPM_MFG_ASYNC_PWR_CON, 142 .sram_pdn_bits = GENMASK(11, 8), 143 .sram_pdn_ack_bits = 0, 144 .clk_id = {MT8173_CLK_MFG}, 145 }, 146 [MT8173_POWER_DOMAIN_MFG_2D] = { 147 .name = "mfg_2d", 148 .sta_mask = PWR_STATUS_MFG_2D, 149 .ctl_offs = SPM_MFG_2D_PWR_CON, 150 .sram_pdn_bits = GENMASK(11, 8), 151 .sram_pdn_ack_bits = GENMASK(13, 12), 152 .clk_id = {MT8173_CLK_NONE}, 153 }, 154 [MT8173_POWER_DOMAIN_MFG] = { 155 .name = "mfg", 156 .sta_mask = PWR_STATUS_MFG, 157 .ctl_offs = SPM_MFG_PWR_CON, 158 .sram_pdn_bits = GENMASK(13, 8), 159 .sram_pdn_ack_bits = GENMASK(21, 16), 160 .clk_id = {MT8173_CLK_NONE}, 161 .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S | 162 MT8173_TOP_AXI_PROT_EN_MFG_M0 | 163 MT8173_TOP_AXI_PROT_EN_MFG_M1 | 164 MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT, 165 }, 166}; 167 168#define NUM_DOMAINS ARRAY_SIZE(scp_domain_data) 169 170struct scp; 171 172struct scp_domain { 173 struct generic_pm_domain genpd; 174 struct scp *scp; 175 struct clk *clk[MAX_CLKS]; 176 u32 sta_mask; 177 void __iomem *ctl_addr; 178 u32 sram_pdn_bits; 179 u32 sram_pdn_ack_bits; 180 u32 bus_prot_mask; 181 bool active_wakeup; 182}; 183 184struct scp { 185 struct scp_domain domains[NUM_DOMAINS]; 186 struct genpd_onecell_data pd_data; 187 struct device *dev; 188 void __iomem *base; 189 struct regmap *infracfg; 190}; 191 192static int scpsys_domain_is_on(struct scp_domain *scpd) 193{ 194 struct scp *scp = scpd->scp; 195 196 u32 status = readl(scp->base + SPM_PWR_STATUS) & scpd->sta_mask; 197 u32 status2 = readl(scp->base + SPM_PWR_STATUS_2ND) & scpd->sta_mask; 198 199 /* 200 * A domain is on when both status bits are set. If only one is set 201 * return an error. This happens while powering up a domain 202 */ 203 204 if (status && status2) 205 return true; 206 if (!status && !status2) 207 return false; 208 209 return -EINVAL; 210} 211 212static int scpsys_power_on(struct generic_pm_domain *genpd) 213{ 214 struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd); 215 struct scp *scp = scpd->scp; 216 unsigned long timeout; 217 bool expired; 218 void __iomem *ctl_addr = scpd->ctl_addr; 219 u32 sram_pdn_ack = scpd->sram_pdn_ack_bits; 220 u32 val; 221 int ret; 222 int i; 223 224 for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++) { 225 ret = clk_prepare_enable(scpd->clk[i]); 226 if (ret) { 227 for (--i; i >= 0; i--) 228 clk_disable_unprepare(scpd->clk[i]); 229 230 goto err_clk; 231 } 232 } 233 234 val = readl(ctl_addr); 235 val |= PWR_ON_BIT; 236 writel(val, ctl_addr); 237 val |= PWR_ON_2ND_BIT; 238 writel(val, ctl_addr); 239 240 /* wait until PWR_ACK = 1 */ 241 timeout = jiffies + HZ; 242 expired = false; 243 while (1) { 244 ret = scpsys_domain_is_on(scpd); 245 if (ret > 0) 246 break; 247 248 if (expired) { 249 ret = -ETIMEDOUT; 250 goto err_pwr_ack; 251 } 252 253 cpu_relax(); 254 255 if (time_after(jiffies, timeout)) 256 expired = true; 257 } 258 259 val &= ~PWR_CLK_DIS_BIT; 260 writel(val, ctl_addr); 261 262 val &= ~PWR_ISO_BIT; 263 writel(val, ctl_addr); 264 265 val |= PWR_RST_B_BIT; 266 writel(val, ctl_addr); 267 268 val &= ~scpd->sram_pdn_bits; 269 writel(val, ctl_addr); 270 271 /* wait until SRAM_PDN_ACK all 0 */ 272 timeout = jiffies + HZ; 273 expired = false; 274 while (sram_pdn_ack && (readl(ctl_addr) & sram_pdn_ack)) { 275 276 if (expired) { 277 ret = -ETIMEDOUT; 278 goto err_pwr_ack; 279 } 280 281 cpu_relax(); 282 283 if (time_after(jiffies, timeout)) 284 expired = true; 285 } 286 287 if (scpd->bus_prot_mask) { 288 ret = mtk_infracfg_clear_bus_protection(scp->infracfg, 289 scpd->bus_prot_mask); 290 if (ret) 291 goto err_pwr_ack; 292 } 293 294 return 0; 295 296err_pwr_ack: 297 for (i = MAX_CLKS - 1; i >= 0; i--) { 298 if (scpd->clk[i]) 299 clk_disable_unprepare(scpd->clk[i]); 300 } 301err_clk: 302 dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name); 303 304 return ret; 305} 306 307static int scpsys_power_off(struct generic_pm_domain *genpd) 308{ 309 struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd); 310 struct scp *scp = scpd->scp; 311 unsigned long timeout; 312 bool expired; 313 void __iomem *ctl_addr = scpd->ctl_addr; 314 u32 pdn_ack = scpd->sram_pdn_ack_bits; 315 u32 val; 316 int ret; 317 int i; 318 319 if (scpd->bus_prot_mask) { 320 ret = mtk_infracfg_set_bus_protection(scp->infracfg, 321 scpd->bus_prot_mask); 322 if (ret) 323 goto out; 324 } 325 326 val = readl(ctl_addr); 327 val |= scpd->sram_pdn_bits; 328 writel(val, ctl_addr); 329 330 /* wait until SRAM_PDN_ACK all 1 */ 331 timeout = jiffies + HZ; 332 expired = false; 333 while (pdn_ack && (readl(ctl_addr) & pdn_ack) != pdn_ack) { 334 if (expired) { 335 ret = -ETIMEDOUT; 336 goto out; 337 } 338 339 cpu_relax(); 340 341 if (time_after(jiffies, timeout)) 342 expired = true; 343 } 344 345 val |= PWR_ISO_BIT; 346 writel(val, ctl_addr); 347 348 val &= ~PWR_RST_B_BIT; 349 writel(val, ctl_addr); 350 351 val |= PWR_CLK_DIS_BIT; 352 writel(val, ctl_addr); 353 354 val &= ~PWR_ON_BIT; 355 writel(val, ctl_addr); 356 357 val &= ~PWR_ON_2ND_BIT; 358 writel(val, ctl_addr); 359 360 /* wait until PWR_ACK = 0 */ 361 timeout = jiffies + HZ; 362 expired = false; 363 while (1) { 364 ret = scpsys_domain_is_on(scpd); 365 if (ret == 0) 366 break; 367 368 if (expired) { 369 ret = -ETIMEDOUT; 370 goto out; 371 } 372 373 cpu_relax(); 374 375 if (time_after(jiffies, timeout)) 376 expired = true; 377 } 378 379 for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++) 380 clk_disable_unprepare(scpd->clk[i]); 381 382 return 0; 383 384out: 385 dev_err(scp->dev, "Failed to power off domain %s\n", genpd->name); 386 387 return ret; 388} 389 390static bool scpsys_active_wakeup(struct device *dev) 391{ 392 struct generic_pm_domain *genpd; 393 struct scp_domain *scpd; 394 395 genpd = pd_to_genpd(dev->pm_domain); 396 scpd = container_of(genpd, struct scp_domain, genpd); 397 398 return scpd->active_wakeup; 399} 400 401static int __init scpsys_probe(struct platform_device *pdev) 402{ 403 struct genpd_onecell_data *pd_data; 404 struct resource *res; 405 int i, j, ret; 406 struct scp *scp; 407 struct clk *clk[MT8173_CLK_MAX]; 408 409 scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL); 410 if (!scp) 411 return -ENOMEM; 412 413 scp->dev = &pdev->dev; 414 415 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 416 scp->base = devm_ioremap_resource(&pdev->dev, res); 417 if (IS_ERR(scp->base)) 418 return PTR_ERR(scp->base); 419 420 pd_data = &scp->pd_data; 421 422 pd_data->domains = devm_kzalloc(&pdev->dev, 423 sizeof(*pd_data->domains) * NUM_DOMAINS, GFP_KERNEL); 424 if (!pd_data->domains) 425 return -ENOMEM; 426 427 clk[MT8173_CLK_MM] = devm_clk_get(&pdev->dev, "mm"); 428 if (IS_ERR(clk[MT8173_CLK_MM])) 429 return PTR_ERR(clk[MT8173_CLK_MM]); 430 431 clk[MT8173_CLK_MFG] = devm_clk_get(&pdev->dev, "mfg"); 432 if (IS_ERR(clk[MT8173_CLK_MFG])) 433 return PTR_ERR(clk[MT8173_CLK_MFG]); 434 435 clk[MT8173_CLK_VENC] = devm_clk_get(&pdev->dev, "venc"); 436 if (IS_ERR(clk[MT8173_CLK_VENC])) 437 return PTR_ERR(clk[MT8173_CLK_VENC]); 438 439 clk[MT8173_CLK_VENC_LT] = devm_clk_get(&pdev->dev, "venc_lt"); 440 if (IS_ERR(clk[MT8173_CLK_VENC_LT])) 441 return PTR_ERR(clk[MT8173_CLK_VENC_LT]); 442 443 scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, 444 "infracfg"); 445 if (IS_ERR(scp->infracfg)) { 446 dev_err(&pdev->dev, "Cannot find infracfg controller: %ld\n", 447 PTR_ERR(scp->infracfg)); 448 return PTR_ERR(scp->infracfg); 449 } 450 451 pd_data->num_domains = NUM_DOMAINS; 452 453 for (i = 0; i < NUM_DOMAINS; i++) { 454 struct scp_domain *scpd = &scp->domains[i]; 455 struct generic_pm_domain *genpd = &scpd->genpd; 456 const struct scp_domain_data *data = &scp_domain_data[i]; 457 458 pd_data->domains[i] = genpd; 459 scpd->scp = scp; 460 461 scpd->sta_mask = data->sta_mask; 462 scpd->ctl_addr = scp->base + data->ctl_offs; 463 scpd->sram_pdn_bits = data->sram_pdn_bits; 464 scpd->sram_pdn_ack_bits = data->sram_pdn_ack_bits; 465 scpd->bus_prot_mask = data->bus_prot_mask; 466 scpd->active_wakeup = data->active_wakeup; 467 for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++) 468 scpd->clk[j] = clk[data->clk_id[j]]; 469 470 genpd->name = data->name; 471 genpd->power_off = scpsys_power_off; 472 genpd->power_on = scpsys_power_on; 473 genpd->dev_ops.active_wakeup = scpsys_active_wakeup; 474 475 /* 476 * Initially turn on all domains to make the domains usable 477 * with !CONFIG_PM and to get the hardware in sync with the 478 * software. The unused domains will be switched off during 479 * late_init time. 480 */ 481 genpd->power_on(genpd); 482 483 pm_genpd_init(genpd, NULL, false); 484 } 485 486 /* 487 * We are not allowed to fail here since there is no way to unregister 488 * a power domain. Once registered above we have to keep the domains 489 * valid. 490 */ 491 492 ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_ASYNC], 493 pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D]); 494 if (ret && IS_ENABLED(CONFIG_PM)) 495 dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret); 496 497 ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D], 498 pd_data->domains[MT8173_POWER_DOMAIN_MFG]); 499 if (ret && IS_ENABLED(CONFIG_PM)) 500 dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret); 501 502 ret = of_genpd_add_provider_onecell(pdev->dev.of_node, pd_data); 503 if (ret) 504 dev_err(&pdev->dev, "Failed to add OF provider: %d\n", ret); 505 506 return 0; 507} 508 509static const struct of_device_id of_scpsys_match_tbl[] = { 510 { 511 .compatible = "mediatek,mt8173-scpsys", 512 }, { 513 /* sentinel */ 514 } 515}; 516 517static struct platform_driver scpsys_drv = { 518 .driver = { 519 .name = "mtk-scpsys", 520 .owner = THIS_MODULE, 521 .of_match_table = of_match_ptr(of_scpsys_match_tbl), 522 }, 523}; 524 525module_platform_driver_probe(scpsys_drv, scpsys_probe); 526