linux/drivers/remoteproc/qcom_q6v5_pas.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Qualcomm ADSP/SLPI Peripheral Image Loader for MSM8974 and MSM8996
   4 *
   5 * Copyright (C) 2016 Linaro Ltd
   6 * Copyright (C) 2014 Sony Mobile Communications AB
   7 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
   8 */
   9
  10#include <linux/clk.h>
  11#include <linux/firmware.h>
  12#include <linux/interrupt.h>
  13#include <linux/kernel.h>
  14#include <linux/module.h>
  15#include <linux/of_address.h>
  16#include <linux/of_device.h>
  17#include <linux/platform_device.h>
  18#include <linux/pm_domain.h>
  19#include <linux/pm_runtime.h>
  20#include <linux/qcom_scm.h>
  21#include <linux/regulator/consumer.h>
  22#include <linux/remoteproc.h>
  23#include <linux/soc/qcom/mdt_loader.h>
  24#include <linux/soc/qcom/smem.h>
  25#include <linux/soc/qcom/smem_state.h>
  26
  27#include "qcom_common.h"
  28#include "qcom_pil_info.h"
  29#include "qcom_q6v5.h"
  30#include "remoteproc_internal.h"
  31
  32struct adsp_data {
  33        int crash_reason_smem;
  34        const char *firmware_name;
  35        int pas_id;
  36        unsigned int minidump_id;
  37        bool has_aggre2_clk;
  38        bool auto_boot;
  39
  40        char **active_pd_names;
  41        char **proxy_pd_names;
  42
  43        const char *ssr_name;
  44        const char *sysmon_name;
  45        int ssctl_id;
  46};
  47
  48struct qcom_adsp {
  49        struct device *dev;
  50        struct rproc *rproc;
  51
  52        struct qcom_q6v5 q6v5;
  53
  54        struct clk *xo;
  55        struct clk *aggre2_clk;
  56
  57        struct regulator *cx_supply;
  58        struct regulator *px_supply;
  59
  60        struct device *active_pds[1];
  61        struct device *proxy_pds[3];
  62
  63        int active_pd_count;
  64        int proxy_pd_count;
  65
  66        int pas_id;
  67        unsigned int minidump_id;
  68        int crash_reason_smem;
  69        bool has_aggre2_clk;
  70        const char *info_name;
  71
  72        struct completion start_done;
  73        struct completion stop_done;
  74
  75        phys_addr_t mem_phys;
  76        phys_addr_t mem_reloc;
  77        void *mem_region;
  78        size_t mem_size;
  79
  80        struct qcom_rproc_glink glink_subdev;
  81        struct qcom_rproc_subdev smd_subdev;
  82        struct qcom_rproc_ssr ssr_subdev;
  83        struct qcom_sysmon *sysmon;
  84};
  85
  86static void adsp_minidump(struct rproc *rproc)
  87{
  88        struct qcom_adsp *adsp = rproc->priv;
  89
  90        qcom_minidump(rproc, adsp->minidump_id);
  91}
  92
  93static int adsp_pds_enable(struct qcom_adsp *adsp, struct device **pds,
  94                           size_t pd_count)
  95{
  96        int ret;
  97        int i;
  98
  99        for (i = 0; i < pd_count; i++) {
 100                dev_pm_genpd_set_performance_state(pds[i], INT_MAX);
 101                ret = pm_runtime_get_sync(pds[i]);
 102                if (ret < 0) {
 103                        pm_runtime_put_noidle(pds[i]);
 104                        dev_pm_genpd_set_performance_state(pds[i], 0);
 105                        goto unroll_pd_votes;
 106                }
 107        }
 108
 109        return 0;
 110
 111unroll_pd_votes:
 112        for (i--; i >= 0; i--) {
 113                dev_pm_genpd_set_performance_state(pds[i], 0);
 114                pm_runtime_put(pds[i]);
 115        }
 116
 117        return ret;
 118};
 119
 120static void adsp_pds_disable(struct qcom_adsp *adsp, struct device **pds,
 121                             size_t pd_count)
 122{
 123        int i;
 124
 125        for (i = 0; i < pd_count; i++) {
 126                dev_pm_genpd_set_performance_state(pds[i], 0);
 127                pm_runtime_put(pds[i]);
 128        }
 129}
 130
 131static int adsp_load(struct rproc *rproc, const struct firmware *fw)
 132{
 133        struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
 134        int ret;
 135
 136        ret = qcom_mdt_load(adsp->dev, fw, rproc->firmware, adsp->pas_id,
 137                            adsp->mem_region, adsp->mem_phys, adsp->mem_size,
 138                            &adsp->mem_reloc);
 139        if (ret)
 140                return ret;
 141
 142        qcom_pil_info_store(adsp->info_name, adsp->mem_phys, adsp->mem_size);
 143
 144        return 0;
 145}
 146
 147static int adsp_start(struct rproc *rproc)
 148{
 149        struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
 150        int ret;
 151
 152        qcom_q6v5_prepare(&adsp->q6v5);
 153
 154        ret = adsp_pds_enable(adsp, adsp->active_pds, adsp->active_pd_count);
 155        if (ret < 0)
 156                goto disable_irqs;
 157
 158        ret = adsp_pds_enable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
 159        if (ret < 0)
 160                goto disable_active_pds;
 161
 162        ret = clk_prepare_enable(adsp->xo);
 163        if (ret)
 164                goto disable_proxy_pds;
 165
 166        ret = clk_prepare_enable(adsp->aggre2_clk);
 167        if (ret)
 168                goto disable_xo_clk;
 169
 170        ret = regulator_enable(adsp->cx_supply);
 171        if (ret)
 172                goto disable_aggre2_clk;
 173
 174        ret = regulator_enable(adsp->px_supply);
 175        if (ret)
 176                goto disable_cx_supply;
 177
 178        ret = qcom_scm_pas_auth_and_reset(adsp->pas_id);
 179        if (ret) {
 180                dev_err(adsp->dev,
 181                        "failed to authenticate image and release reset\n");
 182                goto disable_px_supply;
 183        }
 184
 185        ret = qcom_q6v5_wait_for_start(&adsp->q6v5, msecs_to_jiffies(5000));
 186        if (ret == -ETIMEDOUT) {
 187                dev_err(adsp->dev, "start timed out\n");
 188                qcom_scm_pas_shutdown(adsp->pas_id);
 189                goto disable_px_supply;
 190        }
 191
 192        return 0;
 193
 194disable_px_supply:
 195        regulator_disable(adsp->px_supply);
 196disable_cx_supply:
 197        regulator_disable(adsp->cx_supply);
 198disable_aggre2_clk:
 199        clk_disable_unprepare(adsp->aggre2_clk);
 200disable_xo_clk:
 201        clk_disable_unprepare(adsp->xo);
 202disable_proxy_pds:
 203        adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
 204disable_active_pds:
 205        adsp_pds_disable(adsp, adsp->active_pds, adsp->active_pd_count);
 206disable_irqs:
 207        qcom_q6v5_unprepare(&adsp->q6v5);
 208
 209        return ret;
 210}
 211
 212static void qcom_pas_handover(struct qcom_q6v5 *q6v5)
 213{
 214        struct qcom_adsp *adsp = container_of(q6v5, struct qcom_adsp, q6v5);
 215
 216        regulator_disable(adsp->px_supply);
 217        regulator_disable(adsp->cx_supply);
 218        clk_disable_unprepare(adsp->aggre2_clk);
 219        clk_disable_unprepare(adsp->xo);
 220        adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
 221}
 222
 223static int adsp_stop(struct rproc *rproc)
 224{
 225        struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
 226        int handover;
 227        int ret;
 228
 229        ret = qcom_q6v5_request_stop(&adsp->q6v5, adsp->sysmon);
 230        if (ret == -ETIMEDOUT)
 231                dev_err(adsp->dev, "timed out on wait\n");
 232
 233        ret = qcom_scm_pas_shutdown(adsp->pas_id);
 234        if (ret)
 235                dev_err(adsp->dev, "failed to shutdown: %d\n", ret);
 236
 237        adsp_pds_disable(adsp, adsp->active_pds, adsp->active_pd_count);
 238        handover = qcom_q6v5_unprepare(&adsp->q6v5);
 239        if (handover)
 240                qcom_pas_handover(&adsp->q6v5);
 241
 242        return ret;
 243}
 244
 245static void *adsp_da_to_va(struct rproc *rproc, u64 da, size_t len)
 246{
 247        struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
 248        int offset;
 249
 250        offset = da - adsp->mem_reloc;
 251        if (offset < 0 || offset + len > adsp->mem_size)
 252                return NULL;
 253
 254        return adsp->mem_region + offset;
 255}
 256
 257static unsigned long adsp_panic(struct rproc *rproc)
 258{
 259        struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
 260
 261        return qcom_q6v5_panic(&adsp->q6v5);
 262}
 263
 264static const struct rproc_ops adsp_ops = {
 265        .start = adsp_start,
 266        .stop = adsp_stop,
 267        .da_to_va = adsp_da_to_va,
 268        .parse_fw = qcom_register_dump_segments,
 269        .load = adsp_load,
 270        .panic = adsp_panic,
 271};
 272
 273static const struct rproc_ops adsp_minidump_ops = {
 274        .start = adsp_start,
 275        .stop = adsp_stop,
 276        .da_to_va = adsp_da_to_va,
 277        .load = adsp_load,
 278        .panic = adsp_panic,
 279        .coredump = adsp_minidump,
 280};
 281
 282static int adsp_init_clock(struct qcom_adsp *adsp)
 283{
 284        int ret;
 285
 286        adsp->xo = devm_clk_get(adsp->dev, "xo");
 287        if (IS_ERR(adsp->xo)) {
 288                ret = PTR_ERR(adsp->xo);
 289                if (ret != -EPROBE_DEFER)
 290                        dev_err(adsp->dev, "failed to get xo clock");
 291                return ret;
 292        }
 293
 294        if (adsp->has_aggre2_clk) {
 295                adsp->aggre2_clk = devm_clk_get(adsp->dev, "aggre2");
 296                if (IS_ERR(adsp->aggre2_clk)) {
 297                        ret = PTR_ERR(adsp->aggre2_clk);
 298                        if (ret != -EPROBE_DEFER)
 299                                dev_err(adsp->dev,
 300                                        "failed to get aggre2 clock");
 301                        return ret;
 302                }
 303        }
 304
 305        return 0;
 306}
 307
 308static int adsp_init_regulator(struct qcom_adsp *adsp)
 309{
 310        adsp->cx_supply = devm_regulator_get(adsp->dev, "cx");
 311        if (IS_ERR(adsp->cx_supply))
 312                return PTR_ERR(adsp->cx_supply);
 313
 314        regulator_set_load(adsp->cx_supply, 100000);
 315
 316        adsp->px_supply = devm_regulator_get(adsp->dev, "px");
 317        return PTR_ERR_OR_ZERO(adsp->px_supply);
 318}
 319
 320static int adsp_pds_attach(struct device *dev, struct device **devs,
 321                           char **pd_names)
 322{
 323        size_t num_pds = 0;
 324        int ret;
 325        int i;
 326
 327        if (!pd_names)
 328                return 0;
 329
 330        /* Handle single power domain */
 331        if (dev->pm_domain) {
 332                devs[0] = dev;
 333                pm_runtime_enable(dev);
 334                return 1;
 335        }
 336
 337        while (pd_names[num_pds])
 338                num_pds++;
 339
 340        for (i = 0; i < num_pds; i++) {
 341                devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]);
 342                if (IS_ERR_OR_NULL(devs[i])) {
 343                        ret = PTR_ERR(devs[i]) ? : -ENODATA;
 344                        goto unroll_attach;
 345                }
 346        }
 347
 348        return num_pds;
 349
 350unroll_attach:
 351        for (i--; i >= 0; i--)
 352                dev_pm_domain_detach(devs[i], false);
 353
 354        return ret;
 355};
 356
 357static void adsp_pds_detach(struct qcom_adsp *adsp, struct device **pds,
 358                            size_t pd_count)
 359{
 360        struct device *dev = adsp->dev;
 361        int i;
 362
 363        /* Handle single power domain */
 364        if (dev->pm_domain && pd_count) {
 365                pm_runtime_disable(dev);
 366                return;
 367        }
 368
 369        for (i = 0; i < pd_count; i++)
 370                dev_pm_domain_detach(pds[i], false);
 371}
 372
 373static int adsp_alloc_memory_region(struct qcom_adsp *adsp)
 374{
 375        struct device_node *node;
 376        struct resource r;
 377        int ret;
 378
 379        node = of_parse_phandle(adsp->dev->of_node, "memory-region", 0);
 380        if (!node) {
 381                dev_err(adsp->dev, "no memory-region specified\n");
 382                return -EINVAL;
 383        }
 384
 385        ret = of_address_to_resource(node, 0, &r);
 386        if (ret)
 387                return ret;
 388
 389        adsp->mem_phys = adsp->mem_reloc = r.start;
 390        adsp->mem_size = resource_size(&r);
 391        adsp->mem_region = devm_ioremap_wc(adsp->dev, adsp->mem_phys, adsp->mem_size);
 392        if (!adsp->mem_region) {
 393                dev_err(adsp->dev, "unable to map memory region: %pa+%zx\n",
 394                        &r.start, adsp->mem_size);
 395                return -EBUSY;
 396        }
 397
 398        return 0;
 399}
 400
 401static int adsp_probe(struct platform_device *pdev)
 402{
 403        const struct adsp_data *desc;
 404        struct qcom_adsp *adsp;
 405        struct rproc *rproc;
 406        const char *fw_name;
 407        const struct rproc_ops *ops = &adsp_ops;
 408        int ret;
 409
 410        desc = of_device_get_match_data(&pdev->dev);
 411        if (!desc)
 412                return -EINVAL;
 413
 414        if (!qcom_scm_is_available())
 415                return -EPROBE_DEFER;
 416
 417        fw_name = desc->firmware_name;
 418        ret = of_property_read_string(pdev->dev.of_node, "firmware-name",
 419                                      &fw_name);
 420        if (ret < 0 && ret != -EINVAL)
 421                return ret;
 422
 423        if (desc->minidump_id)
 424                ops = &adsp_minidump_ops;
 425
 426        rproc = rproc_alloc(&pdev->dev, pdev->name, ops, fw_name, sizeof(*adsp));
 427
 428        if (!rproc) {
 429                dev_err(&pdev->dev, "unable to allocate remoteproc\n");
 430                return -ENOMEM;
 431        }
 432
 433        rproc->auto_boot = desc->auto_boot;
 434        rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
 435
 436        adsp = (struct qcom_adsp *)rproc->priv;
 437        adsp->dev = &pdev->dev;
 438        adsp->rproc = rproc;
 439        adsp->minidump_id = desc->minidump_id;
 440        adsp->pas_id = desc->pas_id;
 441        adsp->has_aggre2_clk = desc->has_aggre2_clk;
 442        adsp->info_name = desc->sysmon_name;
 443        platform_set_drvdata(pdev, adsp);
 444
 445        device_wakeup_enable(adsp->dev);
 446
 447        ret = adsp_alloc_memory_region(adsp);
 448        if (ret)
 449                goto free_rproc;
 450
 451        ret = adsp_init_clock(adsp);
 452        if (ret)
 453                goto free_rproc;
 454
 455        ret = adsp_init_regulator(adsp);
 456        if (ret)
 457                goto free_rproc;
 458
 459        ret = adsp_pds_attach(&pdev->dev, adsp->active_pds,
 460                              desc->active_pd_names);
 461        if (ret < 0)
 462                goto free_rproc;
 463        adsp->active_pd_count = ret;
 464
 465        ret = adsp_pds_attach(&pdev->dev, adsp->proxy_pds,
 466                              desc->proxy_pd_names);
 467        if (ret < 0)
 468                goto detach_active_pds;
 469        adsp->proxy_pd_count = ret;
 470
 471        ret = qcom_q6v5_init(&adsp->q6v5, pdev, rproc, desc->crash_reason_smem,
 472                             qcom_pas_handover);
 473        if (ret)
 474                goto detach_proxy_pds;
 475
 476        qcom_add_glink_subdev(rproc, &adsp->glink_subdev, desc->ssr_name);
 477        qcom_add_smd_subdev(rproc, &adsp->smd_subdev);
 478        qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name);
 479        adsp->sysmon = qcom_add_sysmon_subdev(rproc,
 480                                              desc->sysmon_name,
 481                                              desc->ssctl_id);
 482        if (IS_ERR(adsp->sysmon)) {
 483                ret = PTR_ERR(adsp->sysmon);
 484                goto detach_proxy_pds;
 485        }
 486
 487        ret = rproc_add(rproc);
 488        if (ret)
 489                goto detach_proxy_pds;
 490
 491        return 0;
 492
 493detach_proxy_pds:
 494        adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
 495detach_active_pds:
 496        adsp_pds_detach(adsp, adsp->active_pds, adsp->active_pd_count);
 497free_rproc:
 498        rproc_free(rproc);
 499
 500        return ret;
 501}
 502
 503static int adsp_remove(struct platform_device *pdev)
 504{
 505        struct qcom_adsp *adsp = platform_get_drvdata(pdev);
 506
 507        rproc_del(adsp->rproc);
 508
 509        qcom_remove_glink_subdev(adsp->rproc, &adsp->glink_subdev);
 510        qcom_remove_sysmon_subdev(adsp->sysmon);
 511        qcom_remove_smd_subdev(adsp->rproc, &adsp->smd_subdev);
 512        qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
 513        rproc_free(adsp->rproc);
 514
 515        return 0;
 516}
 517
 518static const struct adsp_data adsp_resource_init = {
 519                .crash_reason_smem = 423,
 520                .firmware_name = "adsp.mdt",
 521                .pas_id = 1,
 522                .has_aggre2_clk = false,
 523                .auto_boot = true,
 524                .ssr_name = "lpass",
 525                .sysmon_name = "adsp",
 526                .ssctl_id = 0x14,
 527};
 528
 529static const struct adsp_data sm8150_adsp_resource = {
 530                .crash_reason_smem = 423,
 531                .firmware_name = "adsp.mdt",
 532                .pas_id = 1,
 533                .has_aggre2_clk = false,
 534                .auto_boot = true,
 535                .active_pd_names = (char*[]){
 536                        "load_state",
 537                        NULL
 538                },
 539                .proxy_pd_names = (char*[]){
 540                        "cx",
 541                        NULL
 542                },
 543                .ssr_name = "lpass",
 544                .sysmon_name = "adsp",
 545                .ssctl_id = 0x14,
 546};
 547
 548static const struct adsp_data sm8250_adsp_resource = {
 549        .crash_reason_smem = 423,
 550        .firmware_name = "adsp.mdt",
 551        .pas_id = 1,
 552        .has_aggre2_clk = false,
 553        .auto_boot = true,
 554        .active_pd_names = (char*[]){
 555                "load_state",
 556                NULL
 557        },
 558        .proxy_pd_names = (char*[]){
 559                "lcx",
 560                "lmx",
 561                NULL
 562        },
 563        .ssr_name = "lpass",
 564        .sysmon_name = "adsp",
 565        .ssctl_id = 0x14,
 566};
 567
 568static const struct adsp_data sm8350_adsp_resource = {
 569        .crash_reason_smem = 423,
 570        .firmware_name = "adsp.mdt",
 571        .pas_id = 1,
 572        .has_aggre2_clk = false,
 573        .auto_boot = true,
 574        .active_pd_names = (char*[]){
 575                "load_state",
 576                NULL
 577        },
 578        .proxy_pd_names = (char*[]){
 579                "lcx",
 580                "lmx",
 581                NULL
 582        },
 583        .ssr_name = "lpass",
 584        .sysmon_name = "adsp",
 585        .ssctl_id = 0x14,
 586};
 587
 588static const struct adsp_data msm8998_adsp_resource = {
 589                .crash_reason_smem = 423,
 590                .firmware_name = "adsp.mdt",
 591                .pas_id = 1,
 592                .has_aggre2_clk = false,
 593                .auto_boot = true,
 594                .proxy_pd_names = (char*[]){
 595                        "cx",
 596                        NULL
 597                },
 598                .ssr_name = "lpass",
 599                .sysmon_name = "adsp",
 600                .ssctl_id = 0x14,
 601};
 602
 603static const struct adsp_data cdsp_resource_init = {
 604        .crash_reason_smem = 601,
 605        .firmware_name = "cdsp.mdt",
 606        .pas_id = 18,
 607        .has_aggre2_clk = false,
 608        .auto_boot = true,
 609        .ssr_name = "cdsp",
 610        .sysmon_name = "cdsp",
 611        .ssctl_id = 0x17,
 612};
 613
 614static const struct adsp_data sm8150_cdsp_resource = {
 615        .crash_reason_smem = 601,
 616        .firmware_name = "cdsp.mdt",
 617        .pas_id = 18,
 618        .has_aggre2_clk = false,
 619        .auto_boot = true,
 620        .active_pd_names = (char*[]){
 621                "load_state",
 622                NULL
 623        },
 624        .proxy_pd_names = (char*[]){
 625                "cx",
 626                NULL
 627        },
 628        .ssr_name = "cdsp",
 629        .sysmon_name = "cdsp",
 630        .ssctl_id = 0x17,
 631};
 632
 633static const struct adsp_data sm8250_cdsp_resource = {
 634        .crash_reason_smem = 601,
 635        .firmware_name = "cdsp.mdt",
 636        .pas_id = 18,
 637        .has_aggre2_clk = false,
 638        .auto_boot = true,
 639        .active_pd_names = (char*[]){
 640                "load_state",
 641                NULL
 642        },
 643        .proxy_pd_names = (char*[]){
 644                "cx",
 645                NULL
 646        },
 647        .ssr_name = "cdsp",
 648        .sysmon_name = "cdsp",
 649        .ssctl_id = 0x17,
 650};
 651
 652static const struct adsp_data sm8350_cdsp_resource = {
 653        .crash_reason_smem = 601,
 654        .firmware_name = "cdsp.mdt",
 655        .pas_id = 18,
 656        .has_aggre2_clk = false,
 657        .auto_boot = true,
 658        .active_pd_names = (char*[]){
 659                "load_state",
 660                NULL
 661        },
 662        .proxy_pd_names = (char*[]){
 663                "cx",
 664                NULL
 665        },
 666        .ssr_name = "cdsp",
 667        .sysmon_name = "cdsp",
 668        .ssctl_id = 0x17,
 669};
 670
 671static const struct adsp_data mpss_resource_init = {
 672        .crash_reason_smem = 421,
 673        .firmware_name = "modem.mdt",
 674        .pas_id = 4,
 675        .minidump_id = 3,
 676        .has_aggre2_clk = false,
 677        .auto_boot = false,
 678        .active_pd_names = (char*[]){
 679                "load_state",
 680                NULL
 681        },
 682        .proxy_pd_names = (char*[]){
 683                "cx",
 684                "mss",
 685                NULL
 686        },
 687        .ssr_name = "mpss",
 688        .sysmon_name = "modem",
 689        .ssctl_id = 0x12,
 690};
 691
 692static const struct adsp_data slpi_resource_init = {
 693                .crash_reason_smem = 424,
 694                .firmware_name = "slpi.mdt",
 695                .pas_id = 12,
 696                .has_aggre2_clk = true,
 697                .auto_boot = true,
 698                .ssr_name = "dsps",
 699                .sysmon_name = "slpi",
 700                .ssctl_id = 0x16,
 701};
 702
 703static const struct adsp_data sm8150_slpi_resource = {
 704                .crash_reason_smem = 424,
 705                .firmware_name = "slpi.mdt",
 706                .pas_id = 12,
 707                .has_aggre2_clk = false,
 708                .auto_boot = true,
 709                .active_pd_names = (char*[]){
 710                        "load_state",
 711                        NULL
 712                },
 713                .proxy_pd_names = (char*[]){
 714                        "lcx",
 715                        "lmx",
 716                        NULL
 717                },
 718                .ssr_name = "dsps",
 719                .sysmon_name = "slpi",
 720                .ssctl_id = 0x16,
 721};
 722
 723static const struct adsp_data sm8250_slpi_resource = {
 724        .crash_reason_smem = 424,
 725        .firmware_name = "slpi.mdt",
 726        .pas_id = 12,
 727        .has_aggre2_clk = false,
 728        .auto_boot = true,
 729        .active_pd_names = (char*[]){
 730                "load_state",
 731                NULL
 732        },
 733        .proxy_pd_names = (char*[]){
 734                "lcx",
 735                "lmx",
 736                NULL
 737        },
 738        .ssr_name = "dsps",
 739        .sysmon_name = "slpi",
 740        .ssctl_id = 0x16,
 741};
 742
 743static const struct adsp_data sm8350_slpi_resource = {
 744        .crash_reason_smem = 424,
 745        .firmware_name = "slpi.mdt",
 746        .pas_id = 12,
 747        .has_aggre2_clk = false,
 748        .auto_boot = true,
 749        .active_pd_names = (char*[]){
 750                "load_state",
 751                NULL
 752        },
 753        .proxy_pd_names = (char*[]){
 754                "lcx",
 755                "lmx",
 756                NULL
 757        },
 758        .ssr_name = "dsps",
 759        .sysmon_name = "slpi",
 760        .ssctl_id = 0x16,
 761};
 762
 763static const struct adsp_data msm8998_slpi_resource = {
 764                .crash_reason_smem = 424,
 765                .firmware_name = "slpi.mdt",
 766                .pas_id = 12,
 767                .has_aggre2_clk = true,
 768                .auto_boot = true,
 769                .proxy_pd_names = (char*[]){
 770                        "ssc_cx",
 771                        NULL
 772                },
 773                .ssr_name = "dsps",
 774                .sysmon_name = "slpi",
 775                .ssctl_id = 0x16,
 776};
 777
 778static const struct adsp_data wcss_resource_init = {
 779        .crash_reason_smem = 421,
 780        .firmware_name = "wcnss.mdt",
 781        .pas_id = 6,
 782        .auto_boot = true,
 783        .ssr_name = "mpss",
 784        .sysmon_name = "wcnss",
 785        .ssctl_id = 0x12,
 786};
 787
 788static const struct of_device_id adsp_of_match[] = {
 789        { .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init},
 790        { .compatible = "qcom,msm8996-adsp-pil", .data = &adsp_resource_init},
 791        { .compatible = "qcom,msm8996-slpi-pil", .data = &slpi_resource_init},
 792        { .compatible = "qcom,msm8998-adsp-pas", .data = &msm8998_adsp_resource},
 793        { .compatible = "qcom,msm8998-slpi-pas", .data = &msm8998_slpi_resource},
 794        { .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init },
 795        { .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init },
 796        { .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init },
 797        { .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init},
 798        { .compatible = "qcom,sdm845-adsp-pas", .data = &adsp_resource_init},
 799        { .compatible = "qcom,sdm845-cdsp-pas", .data = &cdsp_resource_init},
 800        { .compatible = "qcom,sm8150-adsp-pas", .data = &sm8150_adsp_resource},
 801        { .compatible = "qcom,sm8150-cdsp-pas", .data = &sm8150_cdsp_resource},
 802        { .compatible = "qcom,sm8150-mpss-pas", .data = &mpss_resource_init},
 803        { .compatible = "qcom,sm8150-slpi-pas", .data = &sm8150_slpi_resource},
 804        { .compatible = "qcom,sm8250-adsp-pas", .data = &sm8250_adsp_resource},
 805        { .compatible = "qcom,sm8250-cdsp-pas", .data = &sm8250_cdsp_resource},
 806        { .compatible = "qcom,sm8250-slpi-pas", .data = &sm8250_slpi_resource},
 807        { .compatible = "qcom,sm8350-adsp-pas", .data = &sm8350_adsp_resource},
 808        { .compatible = "qcom,sm8350-cdsp-pas", .data = &sm8350_cdsp_resource},
 809        { .compatible = "qcom,sm8350-slpi-pas", .data = &sm8350_slpi_resource},
 810        { .compatible = "qcom,sm8350-mpss-pas", .data = &mpss_resource_init},
 811        { },
 812};
 813MODULE_DEVICE_TABLE(of, adsp_of_match);
 814
 815static struct platform_driver adsp_driver = {
 816        .probe = adsp_probe,
 817        .remove = adsp_remove,
 818        .driver = {
 819                .name = "qcom_q6v5_pas",
 820                .of_match_table = adsp_of_match,
 821        },
 822};
 823
 824module_platform_driver(adsp_driver);
 825MODULE_DESCRIPTION("Qualcomm Hexagon v5 Peripheral Authentication Service driver");
 826MODULE_LICENSE("GPL v2");
 827