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