linux/drivers/remoteproc/imx_rproc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2017 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>
   4 */
   5
   6#include <linux/arm-smccc.h>
   7#include <linux/clk.h>
   8#include <linux/err.h>
   9#include <linux/interrupt.h>
  10#include <linux/kernel.h>
  11#include <linux/mailbox_client.h>
  12#include <linux/mfd/syscon.h>
  13#include <linux/module.h>
  14#include <linux/of_address.h>
  15#include <linux/of_reserved_mem.h>
  16#include <linux/of_device.h>
  17#include <linux/platform_device.h>
  18#include <linux/regmap.h>
  19#include <linux/remoteproc.h>
  20#include <linux/workqueue.h>
  21
  22#include "remoteproc_internal.h"
  23
  24#define IMX7D_SRC_SCR                   0x0C
  25#define IMX7D_ENABLE_M4                 BIT(3)
  26#define IMX7D_SW_M4P_RST                BIT(2)
  27#define IMX7D_SW_M4C_RST                BIT(1)
  28#define IMX7D_SW_M4C_NON_SCLR_RST       BIT(0)
  29
  30#define IMX7D_M4_RST_MASK               (IMX7D_ENABLE_M4 | IMX7D_SW_M4P_RST \
  31                                         | IMX7D_SW_M4C_RST \
  32                                         | IMX7D_SW_M4C_NON_SCLR_RST)
  33
  34#define IMX7D_M4_START                  (IMX7D_ENABLE_M4 | IMX7D_SW_M4P_RST \
  35                                         | IMX7D_SW_M4C_RST)
  36#define IMX7D_M4_STOP                   IMX7D_SW_M4C_NON_SCLR_RST
  37
  38/* Address: 0x020D8000 */
  39#define IMX6SX_SRC_SCR                  0x00
  40#define IMX6SX_ENABLE_M4                BIT(22)
  41#define IMX6SX_SW_M4P_RST               BIT(12)
  42#define IMX6SX_SW_M4C_NON_SCLR_RST      BIT(4)
  43#define IMX6SX_SW_M4C_RST               BIT(3)
  44
  45#define IMX6SX_M4_START                 (IMX6SX_ENABLE_M4 | IMX6SX_SW_M4P_RST \
  46                                         | IMX6SX_SW_M4C_RST)
  47#define IMX6SX_M4_STOP                  IMX6SX_SW_M4C_NON_SCLR_RST
  48#define IMX6SX_M4_RST_MASK              (IMX6SX_ENABLE_M4 | IMX6SX_SW_M4P_RST \
  49                                         | IMX6SX_SW_M4C_NON_SCLR_RST \
  50                                         | IMX6SX_SW_M4C_RST)
  51
  52#define IMX_RPROC_MEM_MAX               32
  53
  54#define IMX_SIP_RPROC                   0xC2000005
  55#define IMX_SIP_RPROC_START             0x00
  56#define IMX_SIP_RPROC_STARTED           0x01
  57#define IMX_SIP_RPROC_STOP              0x02
  58
  59/**
  60 * struct imx_rproc_mem - slim internal memory structure
  61 * @cpu_addr: MPU virtual address of the memory region
  62 * @sys_addr: Bus address used to access the memory region
  63 * @size: Size of the memory region
  64 */
  65struct imx_rproc_mem {
  66        void __iomem *cpu_addr;
  67        phys_addr_t sys_addr;
  68        size_t size;
  69};
  70
  71/* att flags */
  72/* M4 own area. Can be mapped at probe */
  73#define ATT_OWN         BIT(1)
  74
  75/* address translation table */
  76struct imx_rproc_att {
  77        u32 da; /* device address (From Cortex M4 view)*/
  78        u32 sa; /* system bus address */
  79        u32 size; /* size of reg range */
  80        int flags;
  81};
  82
  83/* Remote core start/stop method */
  84enum imx_rproc_method {
  85        IMX_RPROC_NONE,
  86        /* Through syscon regmap */
  87        IMX_RPROC_MMIO,
  88        /* Through ARM SMCCC */
  89        IMX_RPROC_SMC,
  90};
  91
  92struct imx_rproc_dcfg {
  93        u32                             src_reg;
  94        u32                             src_mask;
  95        u32                             src_start;
  96        u32                             src_stop;
  97        const struct imx_rproc_att      *att;
  98        size_t                          att_size;
  99        enum imx_rproc_method           method;
 100};
 101
 102struct imx_rproc {
 103        struct device                   *dev;
 104        struct regmap                   *regmap;
 105        struct rproc                    *rproc;
 106        const struct imx_rproc_dcfg     *dcfg;
 107        struct imx_rproc_mem            mem[IMX_RPROC_MEM_MAX];
 108        struct clk                      *clk;
 109        struct mbox_client              cl;
 110        struct mbox_chan                *tx_ch;
 111        struct mbox_chan                *rx_ch;
 112        struct work_struct              rproc_work;
 113        struct workqueue_struct         *workqueue;
 114        void __iomem                    *rsc_table;
 115};
 116
 117static const struct imx_rproc_att imx_rproc_att_imx8mn[] = {
 118        /* dev addr , sys addr  , size      , flags */
 119        /* ITCM   */
 120        { 0x00000000, 0x007E0000, 0x00020000, ATT_OWN },
 121        /* OCRAM_S */
 122        { 0x00180000, 0x00180000, 0x00009000, 0 },
 123        /* OCRAM */
 124        { 0x00900000, 0x00900000, 0x00020000, 0 },
 125        /* OCRAM */
 126        { 0x00920000, 0x00920000, 0x00020000, 0 },
 127        /* OCRAM */
 128        { 0x00940000, 0x00940000, 0x00050000, 0 },
 129        /* QSPI Code - alias */
 130        { 0x08000000, 0x08000000, 0x08000000, 0 },
 131        /* DDR (Code) - alias */
 132        { 0x10000000, 0x40000000, 0x0FFE0000, 0 },
 133        /* DTCM */
 134        { 0x20000000, 0x00800000, 0x00020000, ATT_OWN },
 135        /* OCRAM_S - alias */
 136        { 0x20180000, 0x00180000, 0x00008000, ATT_OWN },
 137        /* OCRAM */
 138        { 0x20200000, 0x00900000, 0x00020000, ATT_OWN },
 139        /* OCRAM */
 140        { 0x20220000, 0x00920000, 0x00020000, ATT_OWN },
 141        /* OCRAM */
 142        { 0x20240000, 0x00940000, 0x00040000, ATT_OWN },
 143        /* DDR (Data) */
 144        { 0x40000000, 0x40000000, 0x80000000, 0 },
 145};
 146
 147static const struct imx_rproc_att imx_rproc_att_imx8mq[] = {
 148        /* dev addr , sys addr  , size      , flags */
 149        /* TCML - alias */
 150        { 0x00000000, 0x007e0000, 0x00020000, 0 },
 151        /* OCRAM_S */
 152        { 0x00180000, 0x00180000, 0x00008000, 0 },
 153        /* OCRAM */
 154        { 0x00900000, 0x00900000, 0x00020000, 0 },
 155        /* OCRAM */
 156        { 0x00920000, 0x00920000, 0x00020000, 0 },
 157        /* QSPI Code - alias */
 158        { 0x08000000, 0x08000000, 0x08000000, 0 },
 159        /* DDR (Code) - alias */
 160        { 0x10000000, 0x80000000, 0x0FFE0000, 0 },
 161        /* TCML */
 162        { 0x1FFE0000, 0x007E0000, 0x00020000, ATT_OWN },
 163        /* TCMU */
 164        { 0x20000000, 0x00800000, 0x00020000, ATT_OWN },
 165        /* OCRAM_S */
 166        { 0x20180000, 0x00180000, 0x00008000, ATT_OWN },
 167        /* OCRAM */
 168        { 0x20200000, 0x00900000, 0x00020000, ATT_OWN },
 169        /* OCRAM */
 170        { 0x20220000, 0x00920000, 0x00020000, ATT_OWN },
 171        /* DDR (Data) */
 172        { 0x40000000, 0x40000000, 0x80000000, 0 },
 173};
 174
 175static const struct imx_rproc_att imx_rproc_att_imx8ulp[] = {
 176        {0x1FFC0000, 0x1FFC0000, 0xC0000, ATT_OWN},
 177        {0x21000000, 0x21000000, 0x10000, ATT_OWN},
 178        {0x80000000, 0x80000000, 0x60000000, 0}
 179};
 180
 181static const struct imx_rproc_att imx_rproc_att_imx7ulp[] = {
 182        {0x1FFD0000, 0x1FFD0000, 0x30000, ATT_OWN},
 183        {0x20000000, 0x20000000, 0x10000, ATT_OWN},
 184        {0x2F000000, 0x2F000000, 0x20000, ATT_OWN},
 185        {0x2F020000, 0x2F020000, 0x20000, ATT_OWN},
 186        {0x60000000, 0x60000000, 0x40000000, 0}
 187};
 188
 189static const struct imx_rproc_att imx_rproc_att_imx7d[] = {
 190        /* dev addr , sys addr  , size      , flags */
 191        /* OCRAM_S (M4 Boot code) - alias */
 192        { 0x00000000, 0x00180000, 0x00008000, 0 },
 193        /* OCRAM_S (Code) */
 194        { 0x00180000, 0x00180000, 0x00008000, ATT_OWN },
 195        /* OCRAM (Code) - alias */
 196        { 0x00900000, 0x00900000, 0x00020000, 0 },
 197        /* OCRAM_EPDC (Code) - alias */
 198        { 0x00920000, 0x00920000, 0x00020000, 0 },
 199        /* OCRAM_PXP (Code) - alias */
 200        { 0x00940000, 0x00940000, 0x00008000, 0 },
 201        /* TCML (Code) */
 202        { 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN },
 203        /* DDR (Code) - alias, first part of DDR (Data) */
 204        { 0x10000000, 0x80000000, 0x0FFF0000, 0 },
 205
 206        /* TCMU (Data) */
 207        { 0x20000000, 0x00800000, 0x00008000, ATT_OWN },
 208        /* OCRAM (Data) */
 209        { 0x20200000, 0x00900000, 0x00020000, 0 },
 210        /* OCRAM_EPDC (Data) */
 211        { 0x20220000, 0x00920000, 0x00020000, 0 },
 212        /* OCRAM_PXP (Data) */
 213        { 0x20240000, 0x00940000, 0x00008000, 0 },
 214        /* DDR (Data) */
 215        { 0x80000000, 0x80000000, 0x60000000, 0 },
 216};
 217
 218static const struct imx_rproc_att imx_rproc_att_imx6sx[] = {
 219        /* dev addr , sys addr  , size      , flags */
 220        /* TCML (M4 Boot Code) - alias */
 221        { 0x00000000, 0x007F8000, 0x00008000, 0 },
 222        /* OCRAM_S (Code) */
 223        { 0x00180000, 0x008F8000, 0x00004000, 0 },
 224        /* OCRAM_S (Code) - alias */
 225        { 0x00180000, 0x008FC000, 0x00004000, 0 },
 226        /* TCML (Code) */
 227        { 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN },
 228        /* DDR (Code) - alias, first part of DDR (Data) */
 229        { 0x10000000, 0x80000000, 0x0FFF8000, 0 },
 230
 231        /* TCMU (Data) */
 232        { 0x20000000, 0x00800000, 0x00008000, ATT_OWN },
 233        /* OCRAM_S (Data) - alias? */
 234        { 0x208F8000, 0x008F8000, 0x00004000, 0 },
 235        /* DDR (Data) */
 236        { 0x80000000, 0x80000000, 0x60000000, 0 },
 237};
 238
 239static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mn = {
 240        .att            = imx_rproc_att_imx8mn,
 241        .att_size       = ARRAY_SIZE(imx_rproc_att_imx8mn),
 242        .method         = IMX_RPROC_SMC,
 243};
 244
 245static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mq = {
 246        .src_reg        = IMX7D_SRC_SCR,
 247        .src_mask       = IMX7D_M4_RST_MASK,
 248        .src_start      = IMX7D_M4_START,
 249        .src_stop       = IMX7D_M4_STOP,
 250        .att            = imx_rproc_att_imx8mq,
 251        .att_size       = ARRAY_SIZE(imx_rproc_att_imx8mq),
 252        .method         = IMX_RPROC_MMIO,
 253};
 254
 255static const struct imx_rproc_dcfg imx_rproc_cfg_imx8ulp = {
 256        .att            = imx_rproc_att_imx8ulp,
 257        .att_size       = ARRAY_SIZE(imx_rproc_att_imx8ulp),
 258        .method         = IMX_RPROC_NONE,
 259};
 260
 261static const struct imx_rproc_dcfg imx_rproc_cfg_imx7ulp = {
 262        .att            = imx_rproc_att_imx7ulp,
 263        .att_size       = ARRAY_SIZE(imx_rproc_att_imx7ulp),
 264        .method         = IMX_RPROC_NONE,
 265};
 266
 267static const struct imx_rproc_dcfg imx_rproc_cfg_imx7d = {
 268        .src_reg        = IMX7D_SRC_SCR,
 269        .src_mask       = IMX7D_M4_RST_MASK,
 270        .src_start      = IMX7D_M4_START,
 271        .src_stop       = IMX7D_M4_STOP,
 272        .att            = imx_rproc_att_imx7d,
 273        .att_size       = ARRAY_SIZE(imx_rproc_att_imx7d),
 274        .method         = IMX_RPROC_MMIO,
 275};
 276
 277static const struct imx_rproc_dcfg imx_rproc_cfg_imx6sx = {
 278        .src_reg        = IMX6SX_SRC_SCR,
 279        .src_mask       = IMX6SX_M4_RST_MASK,
 280        .src_start      = IMX6SX_M4_START,
 281        .src_stop       = IMX6SX_M4_STOP,
 282        .att            = imx_rproc_att_imx6sx,
 283        .att_size       = ARRAY_SIZE(imx_rproc_att_imx6sx),
 284        .method         = IMX_RPROC_MMIO,
 285};
 286
 287static int imx_rproc_start(struct rproc *rproc)
 288{
 289        struct imx_rproc *priv = rproc->priv;
 290        const struct imx_rproc_dcfg *dcfg = priv->dcfg;
 291        struct device *dev = priv->dev;
 292        struct arm_smccc_res res;
 293        int ret;
 294
 295        switch (dcfg->method) {
 296        case IMX_RPROC_MMIO:
 297                ret = regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask,
 298                                         dcfg->src_start);
 299                break;
 300        case IMX_RPROC_SMC:
 301                arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_START, 0, 0, 0, 0, 0, 0, &res);
 302                ret = res.a0;
 303                break;
 304        default:
 305                return -EOPNOTSUPP;
 306        }
 307
 308        if (ret)
 309                dev_err(dev, "Failed to enable remote core!\n");
 310
 311        return ret;
 312}
 313
 314static int imx_rproc_stop(struct rproc *rproc)
 315{
 316        struct imx_rproc *priv = rproc->priv;
 317        const struct imx_rproc_dcfg *dcfg = priv->dcfg;
 318        struct device *dev = priv->dev;
 319        struct arm_smccc_res res;
 320        int ret;
 321
 322        switch (dcfg->method) {
 323        case IMX_RPROC_MMIO:
 324                ret = regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask,
 325                                         dcfg->src_stop);
 326                break;
 327        case IMX_RPROC_SMC:
 328                arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_STOP, 0, 0, 0, 0, 0, 0, &res);
 329                ret = res.a0;
 330                if (res.a1)
 331                        dev_info(dev, "Not in wfi, force stopped\n");
 332                break;
 333        default:
 334                return -EOPNOTSUPP;
 335        }
 336
 337        if (ret)
 338                dev_err(dev, "Failed to stop remote core\n");
 339
 340        return ret;
 341}
 342
 343static int imx_rproc_da_to_sys(struct imx_rproc *priv, u64 da,
 344                               size_t len, u64 *sys)
 345{
 346        const struct imx_rproc_dcfg *dcfg = priv->dcfg;
 347        int i;
 348
 349        /* parse address translation table */
 350        for (i = 0; i < dcfg->att_size; i++) {
 351                const struct imx_rproc_att *att = &dcfg->att[i];
 352
 353                if (da >= att->da && da + len < att->da + att->size) {
 354                        unsigned int offset = da - att->da;
 355
 356                        *sys = att->sa + offset;
 357                        return 0;
 358                }
 359        }
 360
 361        dev_warn(priv->dev, "Translation failed: da = 0x%llx len = 0x%zx\n",
 362                 da, len);
 363        return -ENOENT;
 364}
 365
 366static void *imx_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
 367{
 368        struct imx_rproc *priv = rproc->priv;
 369        void *va = NULL;
 370        u64 sys;
 371        int i;
 372
 373        if (len == 0)
 374                return NULL;
 375
 376        /*
 377         * On device side we have many aliases, so we need to convert device
 378         * address (M4) to system bus address first.
 379         */
 380        if (imx_rproc_da_to_sys(priv, da, len, &sys))
 381                return NULL;
 382
 383        for (i = 0; i < IMX_RPROC_MEM_MAX; i++) {
 384                if (sys >= priv->mem[i].sys_addr && sys + len <
 385                    priv->mem[i].sys_addr +  priv->mem[i].size) {
 386                        unsigned int offset = sys - priv->mem[i].sys_addr;
 387                        /* __force to make sparse happy with type conversion */
 388                        va = (__force void *)(priv->mem[i].cpu_addr + offset);
 389                        break;
 390                }
 391        }
 392
 393        dev_dbg(&rproc->dev, "da = 0x%llx len = 0x%zx va = 0x%p\n",
 394                da, len, va);
 395
 396        return va;
 397}
 398
 399static int imx_rproc_mem_alloc(struct rproc *rproc,
 400                               struct rproc_mem_entry *mem)
 401{
 402        struct device *dev = rproc->dev.parent;
 403        void *va;
 404
 405        dev_dbg(dev, "map memory: %p+%zx\n", &mem->dma, mem->len);
 406        va = ioremap_wc(mem->dma, mem->len);
 407        if (IS_ERR_OR_NULL(va)) {
 408                dev_err(dev, "Unable to map memory region: %p+%zx\n",
 409                        &mem->dma, mem->len);
 410                return -ENOMEM;
 411        }
 412
 413        /* Update memory entry va */
 414        mem->va = va;
 415
 416        return 0;
 417}
 418
 419static int imx_rproc_mem_release(struct rproc *rproc,
 420                                 struct rproc_mem_entry *mem)
 421{
 422        dev_dbg(rproc->dev.parent, "unmap memory: %pa\n", &mem->dma);
 423        iounmap(mem->va);
 424
 425        return 0;
 426}
 427
 428static int imx_rproc_prepare(struct rproc *rproc)
 429{
 430        struct imx_rproc *priv = rproc->priv;
 431        struct device_node *np = priv->dev->of_node;
 432        struct of_phandle_iterator it;
 433        struct rproc_mem_entry *mem;
 434        struct reserved_mem *rmem;
 435        u32 da;
 436
 437        /* Register associated reserved memory regions */
 438        of_phandle_iterator_init(&it, np, "memory-region", NULL, 0);
 439        while (of_phandle_iterator_next(&it) == 0) {
 440                /*
 441                 * Ignore the first memory region which will be used vdev buffer.
 442                 * No need to do extra handlings, rproc_add_virtio_dev will handle it.
 443                 */
 444                if (!strcmp(it.node->name, "vdev0buffer"))
 445                        continue;
 446
 447                rmem = of_reserved_mem_lookup(it.node);
 448                if (!rmem) {
 449                        dev_err(priv->dev, "unable to acquire memory-region\n");
 450                        return -EINVAL;
 451                }
 452
 453                /* No need to translate pa to da, i.MX use same map */
 454                da = rmem->base;
 455
 456                /* Register memory region */
 457                mem = rproc_mem_entry_init(priv->dev, NULL, (dma_addr_t)rmem->base, rmem->size, da,
 458                                           imx_rproc_mem_alloc, imx_rproc_mem_release,
 459                                           it.node->name);
 460
 461                if (mem)
 462                        rproc_coredump_add_segment(rproc, da, rmem->size);
 463                else
 464                        return -ENOMEM;
 465
 466                rproc_add_carveout(rproc, mem);
 467        }
 468
 469        return  0;
 470}
 471
 472static int imx_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
 473{
 474        int ret;
 475
 476        ret = rproc_elf_load_rsc_table(rproc, fw);
 477        if (ret)
 478                dev_info(&rproc->dev, "No resource table in elf\n");
 479
 480        return 0;
 481}
 482
 483static void imx_rproc_kick(struct rproc *rproc, int vqid)
 484{
 485        struct imx_rproc *priv = rproc->priv;
 486        int err;
 487        __u32 mmsg;
 488
 489        if (!priv->tx_ch) {
 490                dev_err(priv->dev, "No initialized mbox tx channel\n");
 491                return;
 492        }
 493
 494        /*
 495         * Send the index of the triggered virtqueue as the mu payload.
 496         * Let remote processor know which virtqueue is used.
 497         */
 498        mmsg = vqid << 16;
 499
 500        err = mbox_send_message(priv->tx_ch, (void *)&mmsg);
 501        if (err < 0)
 502                dev_err(priv->dev, "%s: failed (%d, err:%d)\n",
 503                        __func__, vqid, err);
 504}
 505
 506static int imx_rproc_attach(struct rproc *rproc)
 507{
 508        return 0;
 509}
 510
 511static struct resource_table *imx_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
 512{
 513        struct imx_rproc *priv = rproc->priv;
 514
 515        /* The resource table has already been mapped in imx_rproc_addr_init */
 516        if (!priv->rsc_table)
 517                return NULL;
 518
 519        *table_sz = SZ_1K;
 520        return (struct resource_table *)priv->rsc_table;
 521}
 522
 523static const struct rproc_ops imx_rproc_ops = {
 524        .prepare        = imx_rproc_prepare,
 525        .attach         = imx_rproc_attach,
 526        .start          = imx_rproc_start,
 527        .stop           = imx_rproc_stop,
 528        .kick           = imx_rproc_kick,
 529        .da_to_va       = imx_rproc_da_to_va,
 530        .load           = rproc_elf_load_segments,
 531        .parse_fw       = imx_rproc_parse_fw,
 532        .find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table,
 533        .get_loaded_rsc_table = imx_rproc_get_loaded_rsc_table,
 534        .sanity_check   = rproc_elf_sanity_check,
 535        .get_boot_addr  = rproc_elf_get_boot_addr,
 536};
 537
 538static int imx_rproc_addr_init(struct imx_rproc *priv,
 539                               struct platform_device *pdev)
 540{
 541        const struct imx_rproc_dcfg *dcfg = priv->dcfg;
 542        struct device *dev = &pdev->dev;
 543        struct device_node *np = dev->of_node;
 544        int a, b = 0, err, nph;
 545
 546        /* remap required addresses */
 547        for (a = 0; a < dcfg->att_size; a++) {
 548                const struct imx_rproc_att *att = &dcfg->att[a];
 549
 550                if (!(att->flags & ATT_OWN))
 551                        continue;
 552
 553                if (b >= IMX_RPROC_MEM_MAX)
 554                        break;
 555
 556                priv->mem[b].cpu_addr = devm_ioremap(&pdev->dev,
 557                                                     att->sa, att->size);
 558                if (!priv->mem[b].cpu_addr) {
 559                        dev_err(dev, "failed to remap %#x bytes from %#x\n", att->size, att->sa);
 560                        return -ENOMEM;
 561                }
 562                priv->mem[b].sys_addr = att->sa;
 563                priv->mem[b].size = att->size;
 564                b++;
 565        }
 566
 567        /* memory-region is optional property */
 568        nph = of_count_phandle_with_args(np, "memory-region", NULL);
 569        if (nph <= 0)
 570                return 0;
 571
 572        /* remap optional addresses */
 573        for (a = 0; a < nph; a++) {
 574                struct device_node *node;
 575                struct resource res;
 576
 577                node = of_parse_phandle(np, "memory-region", a);
 578                /* Not map vdev region */
 579                if (!strcmp(node->name, "vdev"))
 580                        continue;
 581                err = of_address_to_resource(node, 0, &res);
 582                if (err) {
 583                        dev_err(dev, "unable to resolve memory region\n");
 584                        return err;
 585                }
 586
 587                of_node_put(node);
 588
 589                if (b >= IMX_RPROC_MEM_MAX)
 590                        break;
 591
 592                /* Not use resource version, because we might share region */
 593                priv->mem[b].cpu_addr = devm_ioremap(&pdev->dev, res.start, resource_size(&res));
 594                if (!priv->mem[b].cpu_addr) {
 595                        dev_err(dev, "failed to remap %pr\n", &res);
 596                        return -ENOMEM;
 597                }
 598                priv->mem[b].sys_addr = res.start;
 599                priv->mem[b].size = resource_size(&res);
 600                if (!strcmp(node->name, "rsc_table"))
 601                        priv->rsc_table = priv->mem[b].cpu_addr;
 602                b++;
 603        }
 604
 605        return 0;
 606}
 607
 608static void imx_rproc_vq_work(struct work_struct *work)
 609{
 610        struct imx_rproc *priv = container_of(work, struct imx_rproc,
 611                                              rproc_work);
 612
 613        rproc_vq_interrupt(priv->rproc, 0);
 614        rproc_vq_interrupt(priv->rproc, 1);
 615}
 616
 617static void imx_rproc_rx_callback(struct mbox_client *cl, void *msg)
 618{
 619        struct rproc *rproc = dev_get_drvdata(cl->dev);
 620        struct imx_rproc *priv = rproc->priv;
 621
 622        queue_work(priv->workqueue, &priv->rproc_work);
 623}
 624
 625static int imx_rproc_xtr_mbox_init(struct rproc *rproc)
 626{
 627        struct imx_rproc *priv = rproc->priv;
 628        struct device *dev = priv->dev;
 629        struct mbox_client *cl;
 630        int ret;
 631
 632        if (!of_get_property(dev->of_node, "mbox-names", NULL))
 633                return 0;
 634
 635        cl = &priv->cl;
 636        cl->dev = dev;
 637        cl->tx_block = true;
 638        cl->tx_tout = 100;
 639        cl->knows_txdone = false;
 640        cl->rx_callback = imx_rproc_rx_callback;
 641
 642        priv->tx_ch = mbox_request_channel_byname(cl, "tx");
 643        if (IS_ERR(priv->tx_ch)) {
 644                ret = PTR_ERR(priv->tx_ch);
 645                return dev_err_probe(cl->dev, ret,
 646                                     "failed to request tx mailbox channel: %d\n", ret);
 647        }
 648
 649        priv->rx_ch = mbox_request_channel_byname(cl, "rx");
 650        if (IS_ERR(priv->rx_ch)) {
 651                mbox_free_channel(priv->tx_ch);
 652                ret = PTR_ERR(priv->rx_ch);
 653                return dev_err_probe(cl->dev, ret,
 654                                     "failed to request rx mailbox channel: %d\n", ret);
 655        }
 656
 657        return 0;
 658}
 659
 660static void imx_rproc_free_mbox(struct rproc *rproc)
 661{
 662        struct imx_rproc *priv = rproc->priv;
 663
 664        mbox_free_channel(priv->tx_ch);
 665        mbox_free_channel(priv->rx_ch);
 666}
 667
 668static int imx_rproc_detect_mode(struct imx_rproc *priv)
 669{
 670        struct regmap_config config = { .name = "imx-rproc" };
 671        const struct imx_rproc_dcfg *dcfg = priv->dcfg;
 672        struct device *dev = priv->dev;
 673        struct regmap *regmap;
 674        struct arm_smccc_res res;
 675        int ret;
 676        u32 val;
 677
 678        switch (dcfg->method) {
 679        case IMX_RPROC_NONE:
 680                priv->rproc->state = RPROC_DETACHED;
 681                return 0;
 682        case IMX_RPROC_SMC:
 683                arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_STARTED, 0, 0, 0, 0, 0, 0, &res);
 684                if (res.a0)
 685                        priv->rproc->state = RPROC_DETACHED;
 686                return 0;
 687        default:
 688                break;
 689        }
 690
 691        regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon");
 692        if (IS_ERR(regmap)) {
 693                dev_err(dev, "failed to find syscon\n");
 694                return PTR_ERR(regmap);
 695        }
 696
 697        priv->regmap = regmap;
 698        regmap_attach_dev(dev, regmap, &config);
 699
 700        ret = regmap_read(regmap, dcfg->src_reg, &val);
 701        if (ret) {
 702                dev_err(dev, "Failed to read src\n");
 703                return ret;
 704        }
 705
 706        if (!(val & dcfg->src_stop))
 707                priv->rproc->state = RPROC_DETACHED;
 708
 709        return 0;
 710}
 711
 712static int imx_rproc_clk_enable(struct imx_rproc *priv)
 713{
 714        const struct imx_rproc_dcfg *dcfg = priv->dcfg;
 715        struct device *dev = priv->dev;
 716        int ret;
 717
 718        /* Remote core is not under control of Linux */
 719        if (dcfg->method == IMX_RPROC_NONE)
 720                return 0;
 721
 722        priv->clk = devm_clk_get(dev, NULL);
 723        if (IS_ERR(priv->clk)) {
 724                dev_err(dev, "Failed to get clock\n");
 725                return PTR_ERR(priv->clk);
 726        }
 727
 728        /*
 729         * clk for M4 block including memory. Should be
 730         * enabled before .start for FW transfer.
 731         */
 732        ret = clk_prepare_enable(priv->clk);
 733        if (ret) {
 734                dev_err(dev, "Failed to enable clock\n");
 735                return ret;
 736        }
 737
 738        return 0;
 739}
 740
 741static int imx_rproc_probe(struct platform_device *pdev)
 742{
 743        struct device *dev = &pdev->dev;
 744        struct device_node *np = dev->of_node;
 745        struct imx_rproc *priv;
 746        struct rproc *rproc;
 747        const struct imx_rproc_dcfg *dcfg;
 748        int ret;
 749
 750        /* set some other name then imx */
 751        rproc = rproc_alloc(dev, "imx-rproc", &imx_rproc_ops,
 752                            NULL, sizeof(*priv));
 753        if (!rproc)
 754                return -ENOMEM;
 755
 756        dcfg = of_device_get_match_data(dev);
 757        if (!dcfg) {
 758                ret = -EINVAL;
 759                goto err_put_rproc;
 760        }
 761
 762        priv = rproc->priv;
 763        priv->rproc = rproc;
 764        priv->dcfg = dcfg;
 765        priv->dev = dev;
 766
 767        dev_set_drvdata(dev, rproc);
 768        priv->workqueue = create_workqueue(dev_name(dev));
 769        if (!priv->workqueue) {
 770                dev_err(dev, "cannot create workqueue\n");
 771                ret = -ENOMEM;
 772                goto err_put_rproc;
 773        }
 774
 775        ret = imx_rproc_xtr_mbox_init(rproc);
 776        if (ret)
 777                goto err_put_wkq;
 778
 779        ret = imx_rproc_addr_init(priv, pdev);
 780        if (ret) {
 781                dev_err(dev, "failed on imx_rproc_addr_init\n");
 782                goto err_put_mbox;
 783        }
 784
 785        ret = imx_rproc_detect_mode(priv);
 786        if (ret)
 787                goto err_put_mbox;
 788
 789        ret = imx_rproc_clk_enable(priv);
 790        if (ret)
 791                goto err_put_mbox;
 792
 793        INIT_WORK(&priv->rproc_work, imx_rproc_vq_work);
 794
 795        if (rproc->state != RPROC_DETACHED)
 796                rproc->auto_boot = of_property_read_bool(np, "fsl,auto-boot");
 797
 798        ret = rproc_add(rproc);
 799        if (ret) {
 800                dev_err(dev, "rproc_add failed\n");
 801                goto err_put_clk;
 802        }
 803
 804        return 0;
 805
 806err_put_clk:
 807        clk_disable_unprepare(priv->clk);
 808err_put_mbox:
 809        imx_rproc_free_mbox(rproc);
 810err_put_wkq:
 811        destroy_workqueue(priv->workqueue);
 812err_put_rproc:
 813        rproc_free(rproc);
 814
 815        return ret;
 816}
 817
 818static int imx_rproc_remove(struct platform_device *pdev)
 819{
 820        struct rproc *rproc = platform_get_drvdata(pdev);
 821        struct imx_rproc *priv = rproc->priv;
 822
 823        clk_disable_unprepare(priv->clk);
 824        rproc_del(rproc);
 825        imx_rproc_free_mbox(rproc);
 826        rproc_free(rproc);
 827
 828        return 0;
 829}
 830
 831static const struct of_device_id imx_rproc_of_match[] = {
 832        { .compatible = "fsl,imx7ulp-cm4", .data = &imx_rproc_cfg_imx7ulp },
 833        { .compatible = "fsl,imx7d-cm4", .data = &imx_rproc_cfg_imx7d },
 834        { .compatible = "fsl,imx6sx-cm4", .data = &imx_rproc_cfg_imx6sx },
 835        { .compatible = "fsl,imx8mq-cm4", .data = &imx_rproc_cfg_imx8mq },
 836        { .compatible = "fsl,imx8mm-cm4", .data = &imx_rproc_cfg_imx8mq },
 837        { .compatible = "fsl,imx8mn-cm7", .data = &imx_rproc_cfg_imx8mn },
 838        { .compatible = "fsl,imx8mp-cm7", .data = &imx_rproc_cfg_imx8mn },
 839        { .compatible = "fsl,imx8ulp-cm33", .data = &imx_rproc_cfg_imx8ulp },
 840        {},
 841};
 842MODULE_DEVICE_TABLE(of, imx_rproc_of_match);
 843
 844static struct platform_driver imx_rproc_driver = {
 845        .probe = imx_rproc_probe,
 846        .remove = imx_rproc_remove,
 847        .driver = {
 848                .name = "imx-rproc",
 849                .of_match_table = imx_rproc_of_match,
 850        },
 851};
 852
 853module_platform_driver(imx_rproc_driver);
 854
 855MODULE_LICENSE("GPL v2");
 856MODULE_DESCRIPTION("i.MX remote processor control driver");
 857MODULE_AUTHOR("Oleksij Rempel <o.rempel@pengutronix.de>");
 858