linux/drivers/soc/mediatek/mtk-scpsys.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de>
   4 */
   5#include <linux/clk.h>
   6#include <linux/init.h>
   7#include <linux/io.h>
   8#include <linux/iopoll.h>
   9#include <linux/mfd/syscon.h>
  10#include <linux/of_device.h>
  11#include <linux/platform_device.h>
  12#include <linux/pm_domain.h>
  13#include <linux/regulator/consumer.h>
  14#include <linux/soc/mediatek/infracfg.h>
  15
  16#include <dt-bindings/power/mt2701-power.h>
  17#include <dt-bindings/power/mt2712-power.h>
  18#include <dt-bindings/power/mt6797-power.h>
  19#include <dt-bindings/power/mt7622-power.h>
  20#include <dt-bindings/power/mt7623a-power.h>
  21#include <dt-bindings/power/mt8173-power.h>
  22
  23#define MTK_POLL_DELAY_US   10
  24#define MTK_POLL_TIMEOUT    (jiffies_to_usecs(HZ))
  25
  26#define MTK_SCPD_ACTIVE_WAKEUP          BIT(0)
  27#define MTK_SCPD_FWAIT_SRAM             BIT(1)
  28#define MTK_SCPD_CAPS(_scpd, _x)        ((_scpd)->data->caps & (_x))
  29
  30#define SPM_VDE_PWR_CON                 0x0210
  31#define SPM_MFG_PWR_CON                 0x0214
  32#define SPM_VEN_PWR_CON                 0x0230
  33#define SPM_ISP_PWR_CON                 0x0238
  34#define SPM_DIS_PWR_CON                 0x023c
  35#define SPM_CONN_PWR_CON                0x0280
  36#define SPM_VEN2_PWR_CON                0x0298
  37#define SPM_AUDIO_PWR_CON               0x029c  /* MT8173, MT2712 */
  38#define SPM_BDP_PWR_CON                 0x029c  /* MT2701 */
  39#define SPM_ETH_PWR_CON                 0x02a0
  40#define SPM_HIF_PWR_CON                 0x02a4
  41#define SPM_IFR_MSC_PWR_CON             0x02a8
  42#define SPM_MFG_2D_PWR_CON              0x02c0
  43#define SPM_MFG_ASYNC_PWR_CON           0x02c4
  44#define SPM_USB_PWR_CON                 0x02cc
  45#define SPM_USB2_PWR_CON                0x02d4  /* MT2712 */
  46#define SPM_ETHSYS_PWR_CON              0x02e0  /* MT7622 */
  47#define SPM_HIF0_PWR_CON                0x02e4  /* MT7622 */
  48#define SPM_HIF1_PWR_CON                0x02e8  /* MT7622 */
  49#define SPM_WB_PWR_CON                  0x02ec  /* MT7622 */
  50
  51#define SPM_PWR_STATUS                  0x060c
  52#define SPM_PWR_STATUS_2ND              0x0610
  53
  54#define PWR_RST_B_BIT                   BIT(0)
  55#define PWR_ISO_BIT                     BIT(1)
  56#define PWR_ON_BIT                      BIT(2)
  57#define PWR_ON_2ND_BIT                  BIT(3)
  58#define PWR_CLK_DIS_BIT                 BIT(4)
  59
  60#define PWR_STATUS_CONN                 BIT(1)
  61#define PWR_STATUS_DISP                 BIT(3)
  62#define PWR_STATUS_MFG                  BIT(4)
  63#define PWR_STATUS_ISP                  BIT(5)
  64#define PWR_STATUS_VDEC                 BIT(7)
  65#define PWR_STATUS_BDP                  BIT(14)
  66#define PWR_STATUS_ETH                  BIT(15)
  67#define PWR_STATUS_HIF                  BIT(16)
  68#define PWR_STATUS_IFR_MSC              BIT(17)
  69#define PWR_STATUS_USB2                 BIT(19) /* MT2712 */
  70#define PWR_STATUS_VENC_LT              BIT(20)
  71#define PWR_STATUS_VENC                 BIT(21)
  72#define PWR_STATUS_MFG_2D               BIT(22) /* MT8173 */
  73#define PWR_STATUS_MFG_ASYNC            BIT(23) /* MT8173 */
  74#define PWR_STATUS_AUDIO                BIT(24) /* MT8173, MT2712 */
  75#define PWR_STATUS_USB                  BIT(25) /* MT8173, MT2712 */
  76#define PWR_STATUS_ETHSYS               BIT(24) /* MT7622 */
  77#define PWR_STATUS_HIF0                 BIT(25) /* MT7622 */
  78#define PWR_STATUS_HIF1                 BIT(26) /* MT7622 */
  79#define PWR_STATUS_WB                   BIT(27) /* MT7622 */
  80
  81enum clk_id {
  82        CLK_NONE,
  83        CLK_MM,
  84        CLK_MFG,
  85        CLK_VENC,
  86        CLK_VENC_LT,
  87        CLK_ETHIF,
  88        CLK_VDEC,
  89        CLK_HIFSEL,
  90        CLK_JPGDEC,
  91        CLK_AUDIO,
  92        CLK_MAX,
  93};
  94
  95static const char * const clk_names[] = {
  96        NULL,
  97        "mm",
  98        "mfg",
  99        "venc",
 100        "venc_lt",
 101        "ethif",
 102        "vdec",
 103        "hif_sel",
 104        "jpgdec",
 105        "audio",
 106        NULL,
 107};
 108
 109#define MAX_CLKS        3
 110
 111struct scp_domain_data {
 112        const char *name;
 113        u32 sta_mask;
 114        int ctl_offs;
 115        u32 sram_pdn_bits;
 116        u32 sram_pdn_ack_bits;
 117        u32 bus_prot_mask;
 118        enum clk_id clk_id[MAX_CLKS];
 119        u8 caps;
 120};
 121
 122struct scp;
 123
 124struct scp_domain {
 125        struct generic_pm_domain genpd;
 126        struct scp *scp;
 127        struct clk *clk[MAX_CLKS];
 128        const struct scp_domain_data *data;
 129        struct regulator *supply;
 130};
 131
 132struct scp_ctrl_reg {
 133        int pwr_sta_offs;
 134        int pwr_sta2nd_offs;
 135};
 136
 137struct scp {
 138        struct scp_domain *domains;
 139        struct genpd_onecell_data pd_data;
 140        struct device *dev;
 141        void __iomem *base;
 142        struct regmap *infracfg;
 143        struct scp_ctrl_reg ctrl_reg;
 144        bool bus_prot_reg_update;
 145};
 146
 147struct scp_subdomain {
 148        int origin;
 149        int subdomain;
 150};
 151
 152struct scp_soc_data {
 153        const struct scp_domain_data *domains;
 154        int num_domains;
 155        const struct scp_subdomain *subdomains;
 156        int num_subdomains;
 157        const struct scp_ctrl_reg regs;
 158        bool bus_prot_reg_update;
 159};
 160
 161static int scpsys_domain_is_on(struct scp_domain *scpd)
 162{
 163        struct scp *scp = scpd->scp;
 164
 165        u32 status = readl(scp->base + scp->ctrl_reg.pwr_sta_offs) &
 166                                                scpd->data->sta_mask;
 167        u32 status2 = readl(scp->base + scp->ctrl_reg.pwr_sta2nd_offs) &
 168                                                scpd->data->sta_mask;
 169
 170        /*
 171         * A domain is on when both status bits are set. If only one is set
 172         * return an error. This happens while powering up a domain
 173         */
 174
 175        if (status && status2)
 176                return true;
 177        if (!status && !status2)
 178                return false;
 179
 180        return -EINVAL;
 181}
 182
 183static int scpsys_power_on(struct generic_pm_domain *genpd)
 184{
 185        struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
 186        struct scp *scp = scpd->scp;
 187        void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs;
 188        u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
 189        u32 val;
 190        int ret, tmp;
 191        int i;
 192
 193        if (scpd->supply) {
 194                ret = regulator_enable(scpd->supply);
 195                if (ret)
 196                        return ret;
 197        }
 198
 199        for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++) {
 200                ret = clk_prepare_enable(scpd->clk[i]);
 201                if (ret) {
 202                        for (--i; i >= 0; i--)
 203                                clk_disable_unprepare(scpd->clk[i]);
 204
 205                        goto err_clk;
 206                }
 207        }
 208
 209        val = readl(ctl_addr);
 210        val |= PWR_ON_BIT;
 211        writel(val, ctl_addr);
 212        val |= PWR_ON_2ND_BIT;
 213        writel(val, ctl_addr);
 214
 215        /* wait until PWR_ACK = 1 */
 216        ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp > 0,
 217                                 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
 218        if (ret < 0)
 219                goto err_pwr_ack;
 220
 221        val &= ~PWR_CLK_DIS_BIT;
 222        writel(val, ctl_addr);
 223
 224        val &= ~PWR_ISO_BIT;
 225        writel(val, ctl_addr);
 226
 227        val |= PWR_RST_B_BIT;
 228        writel(val, ctl_addr);
 229
 230        val &= ~scpd->data->sram_pdn_bits;
 231        writel(val, ctl_addr);
 232
 233        /* Either wait until SRAM_PDN_ACK all 0 or have a force wait */
 234        if (MTK_SCPD_CAPS(scpd, MTK_SCPD_FWAIT_SRAM)) {
 235                /*
 236                 * Currently, MTK_SCPD_FWAIT_SRAM is necessary only for
 237                 * MT7622_POWER_DOMAIN_WB and thus just a trivial setup is
 238                 * applied here.
 239                 */
 240                usleep_range(12000, 12100);
 241
 242        } else {
 243                ret = readl_poll_timeout(ctl_addr, tmp, (tmp & pdn_ack) == 0,
 244                                         MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
 245                if (ret < 0)
 246                        goto err_pwr_ack;
 247        }
 248
 249        if (scpd->data->bus_prot_mask) {
 250                ret = mtk_infracfg_clear_bus_protection(scp->infracfg,
 251                                scpd->data->bus_prot_mask,
 252                                scp->bus_prot_reg_update);
 253                if (ret)
 254                        goto err_pwr_ack;
 255        }
 256
 257        return 0;
 258
 259err_pwr_ack:
 260        for (i = MAX_CLKS - 1; i >= 0; i--) {
 261                if (scpd->clk[i])
 262                        clk_disable_unprepare(scpd->clk[i]);
 263        }
 264err_clk:
 265        if (scpd->supply)
 266                regulator_disable(scpd->supply);
 267
 268        dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name);
 269
 270        return ret;
 271}
 272
 273static int scpsys_power_off(struct generic_pm_domain *genpd)
 274{
 275        struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
 276        struct scp *scp = scpd->scp;
 277        void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs;
 278        u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
 279        u32 val;
 280        int ret, tmp;
 281        int i;
 282
 283        if (scpd->data->bus_prot_mask) {
 284                ret = mtk_infracfg_set_bus_protection(scp->infracfg,
 285                                scpd->data->bus_prot_mask,
 286                                scp->bus_prot_reg_update);
 287                if (ret)
 288                        goto out;
 289        }
 290
 291        val = readl(ctl_addr);
 292        val |= scpd->data->sram_pdn_bits;
 293        writel(val, ctl_addr);
 294
 295        /* wait until SRAM_PDN_ACK all 1 */
 296        ret = readl_poll_timeout(ctl_addr, tmp, (tmp & pdn_ack) == pdn_ack,
 297                                 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
 298        if (ret < 0)
 299                goto out;
 300
 301        val |= PWR_ISO_BIT;
 302        writel(val, ctl_addr);
 303
 304        val &= ~PWR_RST_B_BIT;
 305        writel(val, ctl_addr);
 306
 307        val |= PWR_CLK_DIS_BIT;
 308        writel(val, ctl_addr);
 309
 310        val &= ~PWR_ON_BIT;
 311        writel(val, ctl_addr);
 312
 313        val &= ~PWR_ON_2ND_BIT;
 314        writel(val, ctl_addr);
 315
 316        /* wait until PWR_ACK = 0 */
 317        ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp == 0,
 318                                 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
 319        if (ret < 0)
 320                goto out;
 321
 322        for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++)
 323                clk_disable_unprepare(scpd->clk[i]);
 324
 325        if (scpd->supply)
 326                regulator_disable(scpd->supply);
 327
 328        return 0;
 329
 330out:
 331        dev_err(scp->dev, "Failed to power off domain %s\n", genpd->name);
 332
 333        return ret;
 334}
 335
 336static void init_clks(struct platform_device *pdev, struct clk **clk)
 337{
 338        int i;
 339
 340        for (i = CLK_NONE + 1; i < CLK_MAX; i++)
 341                clk[i] = devm_clk_get(&pdev->dev, clk_names[i]);
 342}
 343
 344static struct scp *init_scp(struct platform_device *pdev,
 345                        const struct scp_domain_data *scp_domain_data, int num,
 346                        const struct scp_ctrl_reg *scp_ctrl_reg,
 347                        bool bus_prot_reg_update)
 348{
 349        struct genpd_onecell_data *pd_data;
 350        struct resource *res;
 351        int i, j;
 352        struct scp *scp;
 353        struct clk *clk[CLK_MAX];
 354
 355        scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL);
 356        if (!scp)
 357                return ERR_PTR(-ENOMEM);
 358
 359        scp->ctrl_reg.pwr_sta_offs = scp_ctrl_reg->pwr_sta_offs;
 360        scp->ctrl_reg.pwr_sta2nd_offs = scp_ctrl_reg->pwr_sta2nd_offs;
 361
 362        scp->bus_prot_reg_update = bus_prot_reg_update;
 363
 364        scp->dev = &pdev->dev;
 365
 366        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 367        scp->base = devm_ioremap_resource(&pdev->dev, res);
 368        if (IS_ERR(scp->base))
 369                return ERR_CAST(scp->base);
 370
 371        scp->domains = devm_kcalloc(&pdev->dev,
 372                                num, sizeof(*scp->domains), GFP_KERNEL);
 373        if (!scp->domains)
 374                return ERR_PTR(-ENOMEM);
 375
 376        pd_data = &scp->pd_data;
 377
 378        pd_data->domains = devm_kcalloc(&pdev->dev,
 379                        num, sizeof(*pd_data->domains), GFP_KERNEL);
 380        if (!pd_data->domains)
 381                return ERR_PTR(-ENOMEM);
 382
 383        scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
 384                        "infracfg");
 385        if (IS_ERR(scp->infracfg)) {
 386                dev_err(&pdev->dev, "Cannot find infracfg controller: %ld\n",
 387                                PTR_ERR(scp->infracfg));
 388                return ERR_CAST(scp->infracfg);
 389        }
 390
 391        for (i = 0; i < num; i++) {
 392                struct scp_domain *scpd = &scp->domains[i];
 393                const struct scp_domain_data *data = &scp_domain_data[i];
 394
 395                scpd->supply = devm_regulator_get_optional(&pdev->dev, data->name);
 396                if (IS_ERR(scpd->supply)) {
 397                        if (PTR_ERR(scpd->supply) == -ENODEV)
 398                                scpd->supply = NULL;
 399                        else
 400                                return ERR_CAST(scpd->supply);
 401                }
 402        }
 403
 404        pd_data->num_domains = num;
 405
 406        init_clks(pdev, clk);
 407
 408        for (i = 0; i < num; i++) {
 409                struct scp_domain *scpd = &scp->domains[i];
 410                struct generic_pm_domain *genpd = &scpd->genpd;
 411                const struct scp_domain_data *data = &scp_domain_data[i];
 412
 413                pd_data->domains[i] = genpd;
 414                scpd->scp = scp;
 415
 416                scpd->data = data;
 417
 418                for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++) {
 419                        struct clk *c = clk[data->clk_id[j]];
 420
 421                        if (IS_ERR(c)) {
 422                                dev_err(&pdev->dev, "%s: clk unavailable\n",
 423                                        data->name);
 424                                return ERR_CAST(c);
 425                        }
 426
 427                        scpd->clk[j] = c;
 428                }
 429
 430                genpd->name = data->name;
 431                genpd->power_off = scpsys_power_off;
 432                genpd->power_on = scpsys_power_on;
 433                if (MTK_SCPD_CAPS(scpd, MTK_SCPD_ACTIVE_WAKEUP))
 434                        genpd->flags |= GENPD_FLAG_ACTIVE_WAKEUP;
 435        }
 436
 437        return scp;
 438}
 439
 440static void mtk_register_power_domains(struct platform_device *pdev,
 441                                struct scp *scp, int num)
 442{
 443        struct genpd_onecell_data *pd_data;
 444        int i, ret;
 445
 446        for (i = 0; i < num; i++) {
 447                struct scp_domain *scpd = &scp->domains[i];
 448                struct generic_pm_domain *genpd = &scpd->genpd;
 449
 450                /*
 451                 * Initially turn on all domains to make the domains usable
 452                 * with !CONFIG_PM and to get the hardware in sync with the
 453                 * software.  The unused domains will be switched off during
 454                 * late_init time.
 455                 */
 456                genpd->power_on(genpd);
 457
 458                pm_genpd_init(genpd, NULL, false);
 459        }
 460
 461        /*
 462         * We are not allowed to fail here since there is no way to unregister
 463         * a power domain. Once registered above we have to keep the domains
 464         * valid.
 465         */
 466
 467        pd_data = &scp->pd_data;
 468
 469        ret = of_genpd_add_provider_onecell(pdev->dev.of_node, pd_data);
 470        if (ret)
 471                dev_err(&pdev->dev, "Failed to add OF provider: %d\n", ret);
 472}
 473
 474/*
 475 * MT2701 power domain support
 476 */
 477
 478static const struct scp_domain_data scp_domain_data_mt2701[] = {
 479        [MT2701_POWER_DOMAIN_CONN] = {
 480                .name = "conn",
 481                .sta_mask = PWR_STATUS_CONN,
 482                .ctl_offs = SPM_CONN_PWR_CON,
 483                .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN_M |
 484                                 MT2701_TOP_AXI_PROT_EN_CONN_S,
 485                .clk_id = {CLK_NONE},
 486                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 487        },
 488        [MT2701_POWER_DOMAIN_DISP] = {
 489                .name = "disp",
 490                .sta_mask = PWR_STATUS_DISP,
 491                .ctl_offs = SPM_DIS_PWR_CON,
 492                .sram_pdn_bits = GENMASK(11, 8),
 493                .clk_id = {CLK_MM},
 494                .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_MM_M0,
 495                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 496        },
 497        [MT2701_POWER_DOMAIN_MFG] = {
 498                .name = "mfg",
 499                .sta_mask = PWR_STATUS_MFG,
 500                .ctl_offs = SPM_MFG_PWR_CON,
 501                .sram_pdn_bits = GENMASK(11, 8),
 502                .sram_pdn_ack_bits = GENMASK(12, 12),
 503                .clk_id = {CLK_MFG},
 504                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 505        },
 506        [MT2701_POWER_DOMAIN_VDEC] = {
 507                .name = "vdec",
 508                .sta_mask = PWR_STATUS_VDEC,
 509                .ctl_offs = SPM_VDE_PWR_CON,
 510                .sram_pdn_bits = GENMASK(11, 8),
 511                .sram_pdn_ack_bits = GENMASK(12, 12),
 512                .clk_id = {CLK_MM},
 513                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 514        },
 515        [MT2701_POWER_DOMAIN_ISP] = {
 516                .name = "isp",
 517                .sta_mask = PWR_STATUS_ISP,
 518                .ctl_offs = SPM_ISP_PWR_CON,
 519                .sram_pdn_bits = GENMASK(11, 8),
 520                .sram_pdn_ack_bits = GENMASK(13, 12),
 521                .clk_id = {CLK_MM},
 522                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 523        },
 524        [MT2701_POWER_DOMAIN_BDP] = {
 525                .name = "bdp",
 526                .sta_mask = PWR_STATUS_BDP,
 527                .ctl_offs = SPM_BDP_PWR_CON,
 528                .sram_pdn_bits = GENMASK(11, 8),
 529                .clk_id = {CLK_NONE},
 530                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 531        },
 532        [MT2701_POWER_DOMAIN_ETH] = {
 533                .name = "eth",
 534                .sta_mask = PWR_STATUS_ETH,
 535                .ctl_offs = SPM_ETH_PWR_CON,
 536                .sram_pdn_bits = GENMASK(11, 8),
 537                .sram_pdn_ack_bits = GENMASK(15, 12),
 538                .clk_id = {CLK_ETHIF},
 539                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 540        },
 541        [MT2701_POWER_DOMAIN_HIF] = {
 542                .name = "hif",
 543                .sta_mask = PWR_STATUS_HIF,
 544                .ctl_offs = SPM_HIF_PWR_CON,
 545                .sram_pdn_bits = GENMASK(11, 8),
 546                .sram_pdn_ack_bits = GENMASK(15, 12),
 547                .clk_id = {CLK_ETHIF},
 548                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 549        },
 550        [MT2701_POWER_DOMAIN_IFR_MSC] = {
 551                .name = "ifr_msc",
 552                .sta_mask = PWR_STATUS_IFR_MSC,
 553                .ctl_offs = SPM_IFR_MSC_PWR_CON,
 554                .clk_id = {CLK_NONE},
 555                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 556        },
 557};
 558
 559/*
 560 * MT2712 power domain support
 561 */
 562static const struct scp_domain_data scp_domain_data_mt2712[] = {
 563        [MT2712_POWER_DOMAIN_MM] = {
 564                .name = "mm",
 565                .sta_mask = PWR_STATUS_DISP,
 566                .ctl_offs = SPM_DIS_PWR_CON,
 567                .sram_pdn_bits = GENMASK(8, 8),
 568                .sram_pdn_ack_bits = GENMASK(12, 12),
 569                .clk_id = {CLK_MM},
 570                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 571        },
 572        [MT2712_POWER_DOMAIN_VDEC] = {
 573                .name = "vdec",
 574                .sta_mask = PWR_STATUS_VDEC,
 575                .ctl_offs = SPM_VDE_PWR_CON,
 576                .sram_pdn_bits = GENMASK(8, 8),
 577                .sram_pdn_ack_bits = GENMASK(12, 12),
 578                .clk_id = {CLK_MM, CLK_VDEC},
 579                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 580        },
 581        [MT2712_POWER_DOMAIN_VENC] = {
 582                .name = "venc",
 583                .sta_mask = PWR_STATUS_VENC,
 584                .ctl_offs = SPM_VEN_PWR_CON,
 585                .sram_pdn_bits = GENMASK(11, 8),
 586                .sram_pdn_ack_bits = GENMASK(15, 12),
 587                .clk_id = {CLK_MM, CLK_VENC, CLK_JPGDEC},
 588                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 589        },
 590        [MT2712_POWER_DOMAIN_ISP] = {
 591                .name = "isp",
 592                .sta_mask = PWR_STATUS_ISP,
 593                .ctl_offs = SPM_ISP_PWR_CON,
 594                .sram_pdn_bits = GENMASK(11, 8),
 595                .sram_pdn_ack_bits = GENMASK(13, 12),
 596                .clk_id = {CLK_MM},
 597                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 598        },
 599        [MT2712_POWER_DOMAIN_AUDIO] = {
 600                .name = "audio",
 601                .sta_mask = PWR_STATUS_AUDIO,
 602                .ctl_offs = SPM_AUDIO_PWR_CON,
 603                .sram_pdn_bits = GENMASK(11, 8),
 604                .sram_pdn_ack_bits = GENMASK(15, 12),
 605                .clk_id = {CLK_AUDIO},
 606                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 607        },
 608        [MT2712_POWER_DOMAIN_USB] = {
 609                .name = "usb",
 610                .sta_mask = PWR_STATUS_USB,
 611                .ctl_offs = SPM_USB_PWR_CON,
 612                .sram_pdn_bits = GENMASK(10, 8),
 613                .sram_pdn_ack_bits = GENMASK(14, 12),
 614                .clk_id = {CLK_NONE},
 615                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 616        },
 617        [MT2712_POWER_DOMAIN_USB2] = {
 618                .name = "usb2",
 619                .sta_mask = PWR_STATUS_USB2,
 620                .ctl_offs = SPM_USB2_PWR_CON,
 621                .sram_pdn_bits = GENMASK(10, 8),
 622                .sram_pdn_ack_bits = GENMASK(14, 12),
 623                .clk_id = {CLK_NONE},
 624                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 625        },
 626        [MT2712_POWER_DOMAIN_MFG] = {
 627                .name = "mfg",
 628                .sta_mask = PWR_STATUS_MFG,
 629                .ctl_offs = SPM_MFG_PWR_CON,
 630                .sram_pdn_bits = GENMASK(8, 8),
 631                .sram_pdn_ack_bits = GENMASK(16, 16),
 632                .clk_id = {CLK_MFG},
 633                .bus_prot_mask = BIT(14) | BIT(21) | BIT(23),
 634                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 635        },
 636        [MT2712_POWER_DOMAIN_MFG_SC1] = {
 637                .name = "mfg_sc1",
 638                .sta_mask = BIT(22),
 639                .ctl_offs = 0x02c0,
 640                .sram_pdn_bits = GENMASK(8, 8),
 641                .sram_pdn_ack_bits = GENMASK(16, 16),
 642                .clk_id = {CLK_NONE},
 643                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 644        },
 645        [MT2712_POWER_DOMAIN_MFG_SC2] = {
 646                .name = "mfg_sc2",
 647                .sta_mask = BIT(23),
 648                .ctl_offs = 0x02c4,
 649                .sram_pdn_bits = GENMASK(8, 8),
 650                .sram_pdn_ack_bits = GENMASK(16, 16),
 651                .clk_id = {CLK_NONE},
 652                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 653        },
 654        [MT2712_POWER_DOMAIN_MFG_SC3] = {
 655                .name = "mfg_sc3",
 656                .sta_mask = BIT(30),
 657                .ctl_offs = 0x01f8,
 658                .sram_pdn_bits = GENMASK(8, 8),
 659                .sram_pdn_ack_bits = GENMASK(16, 16),
 660                .clk_id = {CLK_NONE},
 661                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 662        },
 663};
 664
 665static const struct scp_subdomain scp_subdomain_mt2712[] = {
 666        {MT2712_POWER_DOMAIN_MM, MT2712_POWER_DOMAIN_VDEC},
 667        {MT2712_POWER_DOMAIN_MM, MT2712_POWER_DOMAIN_VENC},
 668        {MT2712_POWER_DOMAIN_MM, MT2712_POWER_DOMAIN_ISP},
 669        {MT2712_POWER_DOMAIN_MFG, MT2712_POWER_DOMAIN_MFG_SC1},
 670        {MT2712_POWER_DOMAIN_MFG_SC1, MT2712_POWER_DOMAIN_MFG_SC2},
 671        {MT2712_POWER_DOMAIN_MFG_SC2, MT2712_POWER_DOMAIN_MFG_SC3},
 672};
 673
 674/*
 675 * MT6797 power domain support
 676 */
 677
 678static const struct scp_domain_data scp_domain_data_mt6797[] = {
 679        [MT6797_POWER_DOMAIN_VDEC] = {
 680                .name = "vdec",
 681                .sta_mask = BIT(7),
 682                .ctl_offs = 0x300,
 683                .sram_pdn_bits = GENMASK(8, 8),
 684                .sram_pdn_ack_bits = GENMASK(12, 12),
 685                .clk_id = {CLK_VDEC},
 686        },
 687        [MT6797_POWER_DOMAIN_VENC] = {
 688                .name = "venc",
 689                .sta_mask = BIT(21),
 690                .ctl_offs = 0x304,
 691                .sram_pdn_bits = GENMASK(11, 8),
 692                .sram_pdn_ack_bits = GENMASK(15, 12),
 693                .clk_id = {CLK_NONE},
 694        },
 695        [MT6797_POWER_DOMAIN_ISP] = {
 696                .name = "isp",
 697                .sta_mask = BIT(5),
 698                .ctl_offs = 0x308,
 699                .sram_pdn_bits = GENMASK(9, 8),
 700                .sram_pdn_ack_bits = GENMASK(13, 12),
 701                .clk_id = {CLK_NONE},
 702        },
 703        [MT6797_POWER_DOMAIN_MM] = {
 704                .name = "mm",
 705                .sta_mask = BIT(3),
 706                .ctl_offs = 0x30C,
 707                .sram_pdn_bits = GENMASK(8, 8),
 708                .sram_pdn_ack_bits = GENMASK(12, 12),
 709                .clk_id = {CLK_MM},
 710                .bus_prot_mask = (BIT(1) | BIT(2)),
 711        },
 712        [MT6797_POWER_DOMAIN_AUDIO] = {
 713                .name = "audio",
 714                .sta_mask = BIT(24),
 715                .ctl_offs = 0x314,
 716                .sram_pdn_bits = GENMASK(11, 8),
 717                .sram_pdn_ack_bits = GENMASK(15, 12),
 718                .clk_id = {CLK_NONE},
 719        },
 720        [MT6797_POWER_DOMAIN_MFG_ASYNC] = {
 721                .name = "mfg_async",
 722                .sta_mask = BIT(13),
 723                .ctl_offs = 0x334,
 724                .sram_pdn_bits = 0,
 725                .sram_pdn_ack_bits = 0,
 726                .clk_id = {CLK_MFG},
 727        },
 728        [MT6797_POWER_DOMAIN_MJC] = {
 729                .name = "mjc",
 730                .sta_mask = BIT(20),
 731                .ctl_offs = 0x310,
 732                .sram_pdn_bits = GENMASK(8, 8),
 733                .sram_pdn_ack_bits = GENMASK(12, 12),
 734                .clk_id = {CLK_NONE},
 735        },
 736};
 737
 738#define SPM_PWR_STATUS_MT6797           0x0180
 739#define SPM_PWR_STATUS_2ND_MT6797       0x0184
 740
 741static const struct scp_subdomain scp_subdomain_mt6797[] = {
 742        {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VDEC},
 743        {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_ISP},
 744        {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VENC},
 745        {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_MJC},
 746};
 747
 748/*
 749 * MT7622 power domain support
 750 */
 751
 752static const struct scp_domain_data scp_domain_data_mt7622[] = {
 753        [MT7622_POWER_DOMAIN_ETHSYS] = {
 754                .name = "ethsys",
 755                .sta_mask = PWR_STATUS_ETHSYS,
 756                .ctl_offs = SPM_ETHSYS_PWR_CON,
 757                .sram_pdn_bits = GENMASK(11, 8),
 758                .sram_pdn_ack_bits = GENMASK(15, 12),
 759                .clk_id = {CLK_NONE},
 760                .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_ETHSYS,
 761                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 762        },
 763        [MT7622_POWER_DOMAIN_HIF0] = {
 764                .name = "hif0",
 765                .sta_mask = PWR_STATUS_HIF0,
 766                .ctl_offs = SPM_HIF0_PWR_CON,
 767                .sram_pdn_bits = GENMASK(11, 8),
 768                .sram_pdn_ack_bits = GENMASK(15, 12),
 769                .clk_id = {CLK_HIFSEL},
 770                .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF0,
 771                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 772        },
 773        [MT7622_POWER_DOMAIN_HIF1] = {
 774                .name = "hif1",
 775                .sta_mask = PWR_STATUS_HIF1,
 776                .ctl_offs = SPM_HIF1_PWR_CON,
 777                .sram_pdn_bits = GENMASK(11, 8),
 778                .sram_pdn_ack_bits = GENMASK(15, 12),
 779                .clk_id = {CLK_HIFSEL},
 780                .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF1,
 781                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 782        },
 783        [MT7622_POWER_DOMAIN_WB] = {
 784                .name = "wb",
 785                .sta_mask = PWR_STATUS_WB,
 786                .ctl_offs = SPM_WB_PWR_CON,
 787                .sram_pdn_bits = 0,
 788                .sram_pdn_ack_bits = 0,
 789                .clk_id = {CLK_NONE},
 790                .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_WB,
 791                .caps = MTK_SCPD_ACTIVE_WAKEUP | MTK_SCPD_FWAIT_SRAM,
 792        },
 793};
 794
 795/*
 796 * MT7623A power domain support
 797 */
 798
 799static const struct scp_domain_data scp_domain_data_mt7623a[] = {
 800        [MT7623A_POWER_DOMAIN_CONN] = {
 801                .name = "conn",
 802                .sta_mask = PWR_STATUS_CONN,
 803                .ctl_offs = SPM_CONN_PWR_CON,
 804                .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN_M |
 805                                 MT2701_TOP_AXI_PROT_EN_CONN_S,
 806                .clk_id = {CLK_NONE},
 807                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 808        },
 809        [MT7623A_POWER_DOMAIN_ETH] = {
 810                .name = "eth",
 811                .sta_mask = PWR_STATUS_ETH,
 812                .ctl_offs = SPM_ETH_PWR_CON,
 813                .sram_pdn_bits = GENMASK(11, 8),
 814                .sram_pdn_ack_bits = GENMASK(15, 12),
 815                .clk_id = {CLK_ETHIF},
 816                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 817        },
 818        [MT7623A_POWER_DOMAIN_HIF] = {
 819                .name = "hif",
 820                .sta_mask = PWR_STATUS_HIF,
 821                .ctl_offs = SPM_HIF_PWR_CON,
 822                .sram_pdn_bits = GENMASK(11, 8),
 823                .sram_pdn_ack_bits = GENMASK(15, 12),
 824                .clk_id = {CLK_ETHIF},
 825                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 826        },
 827        [MT7623A_POWER_DOMAIN_IFR_MSC] = {
 828                .name = "ifr_msc",
 829                .sta_mask = PWR_STATUS_IFR_MSC,
 830                .ctl_offs = SPM_IFR_MSC_PWR_CON,
 831                .clk_id = {CLK_NONE},
 832                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 833        },
 834};
 835
 836/*
 837 * MT8173 power domain support
 838 */
 839
 840static const struct scp_domain_data scp_domain_data_mt8173[] = {
 841        [MT8173_POWER_DOMAIN_VDEC] = {
 842                .name = "vdec",
 843                .sta_mask = PWR_STATUS_VDEC,
 844                .ctl_offs = SPM_VDE_PWR_CON,
 845                .sram_pdn_bits = GENMASK(11, 8),
 846                .sram_pdn_ack_bits = GENMASK(12, 12),
 847                .clk_id = {CLK_MM},
 848        },
 849        [MT8173_POWER_DOMAIN_VENC] = {
 850                .name = "venc",
 851                .sta_mask = PWR_STATUS_VENC,
 852                .ctl_offs = SPM_VEN_PWR_CON,
 853                .sram_pdn_bits = GENMASK(11, 8),
 854                .sram_pdn_ack_bits = GENMASK(15, 12),
 855                .clk_id = {CLK_MM, CLK_VENC},
 856        },
 857        [MT8173_POWER_DOMAIN_ISP] = {
 858                .name = "isp",
 859                .sta_mask = PWR_STATUS_ISP,
 860                .ctl_offs = SPM_ISP_PWR_CON,
 861                .sram_pdn_bits = GENMASK(11, 8),
 862                .sram_pdn_ack_bits = GENMASK(13, 12),
 863                .clk_id = {CLK_MM},
 864        },
 865        [MT8173_POWER_DOMAIN_MM] = {
 866                .name = "mm",
 867                .sta_mask = PWR_STATUS_DISP,
 868                .ctl_offs = SPM_DIS_PWR_CON,
 869                .sram_pdn_bits = GENMASK(11, 8),
 870                .sram_pdn_ack_bits = GENMASK(12, 12),
 871                .clk_id = {CLK_MM},
 872                .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
 873                        MT8173_TOP_AXI_PROT_EN_MM_M1,
 874        },
 875        [MT8173_POWER_DOMAIN_VENC_LT] = {
 876                .name = "venc_lt",
 877                .sta_mask = PWR_STATUS_VENC_LT,
 878                .ctl_offs = SPM_VEN2_PWR_CON,
 879                .sram_pdn_bits = GENMASK(11, 8),
 880                .sram_pdn_ack_bits = GENMASK(15, 12),
 881                .clk_id = {CLK_MM, CLK_VENC_LT},
 882        },
 883        [MT8173_POWER_DOMAIN_AUDIO] = {
 884                .name = "audio",
 885                .sta_mask = PWR_STATUS_AUDIO,
 886                .ctl_offs = SPM_AUDIO_PWR_CON,
 887                .sram_pdn_bits = GENMASK(11, 8),
 888                .sram_pdn_ack_bits = GENMASK(15, 12),
 889                .clk_id = {CLK_NONE},
 890        },
 891        [MT8173_POWER_DOMAIN_USB] = {
 892                .name = "usb",
 893                .sta_mask = PWR_STATUS_USB,
 894                .ctl_offs = SPM_USB_PWR_CON,
 895                .sram_pdn_bits = GENMASK(11, 8),
 896                .sram_pdn_ack_bits = GENMASK(15, 12),
 897                .clk_id = {CLK_NONE},
 898                .caps = MTK_SCPD_ACTIVE_WAKEUP,
 899        },
 900        [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
 901                .name = "mfg_async",
 902                .sta_mask = PWR_STATUS_MFG_ASYNC,
 903                .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
 904                .sram_pdn_bits = GENMASK(11, 8),
 905                .sram_pdn_ack_bits = 0,
 906                .clk_id = {CLK_MFG},
 907        },
 908        [MT8173_POWER_DOMAIN_MFG_2D] = {
 909                .name = "mfg_2d",
 910                .sta_mask = PWR_STATUS_MFG_2D,
 911                .ctl_offs = SPM_MFG_2D_PWR_CON,
 912                .sram_pdn_bits = GENMASK(11, 8),
 913                .sram_pdn_ack_bits = GENMASK(13, 12),
 914                .clk_id = {CLK_NONE},
 915        },
 916        [MT8173_POWER_DOMAIN_MFG] = {
 917                .name = "mfg",
 918                .sta_mask = PWR_STATUS_MFG,
 919                .ctl_offs = SPM_MFG_PWR_CON,
 920                .sram_pdn_bits = GENMASK(13, 8),
 921                .sram_pdn_ack_bits = GENMASK(21, 16),
 922                .clk_id = {CLK_NONE},
 923                .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
 924                        MT8173_TOP_AXI_PROT_EN_MFG_M0 |
 925                        MT8173_TOP_AXI_PROT_EN_MFG_M1 |
 926                        MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT,
 927        },
 928};
 929
 930static const struct scp_subdomain scp_subdomain_mt8173[] = {
 931        {MT8173_POWER_DOMAIN_MFG_ASYNC, MT8173_POWER_DOMAIN_MFG_2D},
 932        {MT8173_POWER_DOMAIN_MFG_2D, MT8173_POWER_DOMAIN_MFG},
 933};
 934
 935static const struct scp_soc_data mt2701_data = {
 936        .domains = scp_domain_data_mt2701,
 937        .num_domains = ARRAY_SIZE(scp_domain_data_mt2701),
 938        .regs = {
 939                .pwr_sta_offs = SPM_PWR_STATUS,
 940                .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
 941        },
 942        .bus_prot_reg_update = true,
 943};
 944
 945static const struct scp_soc_data mt2712_data = {
 946        .domains = scp_domain_data_mt2712,
 947        .num_domains = ARRAY_SIZE(scp_domain_data_mt2712),
 948        .subdomains = scp_subdomain_mt2712,
 949        .num_subdomains = ARRAY_SIZE(scp_subdomain_mt2712),
 950        .regs = {
 951                .pwr_sta_offs = SPM_PWR_STATUS,
 952                .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
 953        },
 954        .bus_prot_reg_update = false,
 955};
 956
 957static const struct scp_soc_data mt6797_data = {
 958        .domains = scp_domain_data_mt6797,
 959        .num_domains = ARRAY_SIZE(scp_domain_data_mt6797),
 960        .subdomains = scp_subdomain_mt6797,
 961        .num_subdomains = ARRAY_SIZE(scp_subdomain_mt6797),
 962        .regs = {
 963                .pwr_sta_offs = SPM_PWR_STATUS_MT6797,
 964                .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797
 965        },
 966        .bus_prot_reg_update = true,
 967};
 968
 969static const struct scp_soc_data mt7622_data = {
 970        .domains = scp_domain_data_mt7622,
 971        .num_domains = ARRAY_SIZE(scp_domain_data_mt7622),
 972        .regs = {
 973                .pwr_sta_offs = SPM_PWR_STATUS,
 974                .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
 975        },
 976        .bus_prot_reg_update = true,
 977};
 978
 979static const struct scp_soc_data mt7623a_data = {
 980        .domains = scp_domain_data_mt7623a,
 981        .num_domains = ARRAY_SIZE(scp_domain_data_mt7623a),
 982        .regs = {
 983                .pwr_sta_offs = SPM_PWR_STATUS,
 984                .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
 985        },
 986        .bus_prot_reg_update = true,
 987};
 988
 989static const struct scp_soc_data mt8173_data = {
 990        .domains = scp_domain_data_mt8173,
 991        .num_domains = ARRAY_SIZE(scp_domain_data_mt8173),
 992        .subdomains = scp_subdomain_mt8173,
 993        .num_subdomains = ARRAY_SIZE(scp_subdomain_mt8173),
 994        .regs = {
 995                .pwr_sta_offs = SPM_PWR_STATUS,
 996                .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
 997        },
 998        .bus_prot_reg_update = true,
 999};
1000
1001/*
1002 * scpsys driver init
1003 */
1004
1005static const struct of_device_id of_scpsys_match_tbl[] = {
1006        {
1007                .compatible = "mediatek,mt2701-scpsys",
1008                .data = &mt2701_data,
1009        }, {
1010                .compatible = "mediatek,mt2712-scpsys",
1011                .data = &mt2712_data,
1012        }, {
1013                .compatible = "mediatek,mt6797-scpsys",
1014                .data = &mt6797_data,
1015        }, {
1016                .compatible = "mediatek,mt7622-scpsys",
1017                .data = &mt7622_data,
1018        }, {
1019                .compatible = "mediatek,mt7623a-scpsys",
1020                .data = &mt7623a_data,
1021        }, {
1022                .compatible = "mediatek,mt8173-scpsys",
1023                .data = &mt8173_data,
1024        }, {
1025                /* sentinel */
1026        }
1027};
1028
1029static int scpsys_probe(struct platform_device *pdev)
1030{
1031        const struct scp_subdomain *sd;
1032        const struct scp_soc_data *soc;
1033        struct scp *scp;
1034        struct genpd_onecell_data *pd_data;
1035        int i, ret;
1036
1037        soc = of_device_get_match_data(&pdev->dev);
1038
1039        scp = init_scp(pdev, soc->domains, soc->num_domains, &soc->regs,
1040                        soc->bus_prot_reg_update);
1041        if (IS_ERR(scp))
1042                return PTR_ERR(scp);
1043
1044        mtk_register_power_domains(pdev, scp, soc->num_domains);
1045
1046        pd_data = &scp->pd_data;
1047
1048        for (i = 0, sd = soc->subdomains; i < soc->num_subdomains; i++, sd++) {
1049                ret = pm_genpd_add_subdomain(pd_data->domains[sd->origin],
1050                                             pd_data->domains[sd->subdomain]);
1051                if (ret && IS_ENABLED(CONFIG_PM))
1052                        dev_err(&pdev->dev, "Failed to add subdomain: %d\n",
1053                                ret);
1054        }
1055
1056        return 0;
1057}
1058
1059static struct platform_driver scpsys_drv = {
1060        .probe = scpsys_probe,
1061        .driver = {
1062                .name = "mtk-scpsys",
1063                .suppress_bind_attrs = true,
1064                .owner = THIS_MODULE,
1065                .of_match_table = of_match_ptr(of_scpsys_match_tbl),
1066        },
1067};
1068builtin_platform_driver(scpsys_drv);
1069