Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * ST's Remote Processor Control Driver
0004  *
0005  * Copyright (C) 2015 STMicroelectronics - All Rights Reserved
0006  *
0007  * Author: Ludovic Barre <ludovic.barre@st.com>
0008  */
0009 
0010 #include <linux/clk.h>
0011 #include <linux/dma-mapping.h>
0012 #include <linux/err.h>
0013 #include <linux/interrupt.h>
0014 #include <linux/kernel.h>
0015 #include <linux/mailbox_client.h>
0016 #include <linux/mfd/syscon.h>
0017 #include <linux/module.h>
0018 #include <linux/of.h>
0019 #include <linux/of_address.h>
0020 #include <linux/of_device.h>
0021 #include <linux/of_reserved_mem.h>
0022 #include <linux/platform_device.h>
0023 #include <linux/regmap.h>
0024 #include <linux/remoteproc.h>
0025 #include <linux/reset.h>
0026 
0027 #include "remoteproc_internal.h"
0028 
0029 #define ST_RPROC_VQ0        0
0030 #define ST_RPROC_VQ1        1
0031 #define ST_RPROC_MAX_VRING  2
0032 
0033 #define MBOX_RX         0
0034 #define MBOX_TX         1
0035 #define MBOX_MAX        2
0036 
0037 struct st_rproc_config {
0038     bool            sw_reset;
0039     bool            pwr_reset;
0040     unsigned long       bootaddr_mask;
0041 };
0042 
0043 struct st_rproc {
0044     struct st_rproc_config  *config;
0045     struct reset_control    *sw_reset;
0046     struct reset_control    *pwr_reset;
0047     struct clk      *clk;
0048     u32         clk_rate;
0049     struct regmap       *boot_base;
0050     u32         boot_offset;
0051     struct mbox_chan    *mbox_chan[ST_RPROC_MAX_VRING * MBOX_MAX];
0052     struct mbox_client mbox_client_vq0;
0053     struct mbox_client mbox_client_vq1;
0054 };
0055 
0056 static void st_rproc_mbox_callback(struct device *dev, u32 msg)
0057 {
0058     struct rproc *rproc = dev_get_drvdata(dev);
0059 
0060     if (rproc_vq_interrupt(rproc, msg) == IRQ_NONE)
0061         dev_dbg(dev, "no message was found in vqid %d\n", msg);
0062 }
0063 
0064 static
0065 void st_rproc_mbox_callback_vq0(struct mbox_client *mbox_client, void *data)
0066 {
0067     st_rproc_mbox_callback(mbox_client->dev, 0);
0068 }
0069 
0070 static
0071 void st_rproc_mbox_callback_vq1(struct mbox_client *mbox_client, void *data)
0072 {
0073     st_rproc_mbox_callback(mbox_client->dev, 1);
0074 }
0075 
0076 static void st_rproc_kick(struct rproc *rproc, int vqid)
0077 {
0078     struct st_rproc *ddata = rproc->priv;
0079     struct device *dev = rproc->dev.parent;
0080     int ret;
0081 
0082     /* send the index of the triggered virtqueue in the mailbox payload */
0083     if (WARN_ON(vqid >= ST_RPROC_MAX_VRING))
0084         return;
0085 
0086     ret = mbox_send_message(ddata->mbox_chan[vqid * MBOX_MAX + MBOX_TX],
0087                 (void *)&vqid);
0088     if (ret < 0)
0089         dev_err(dev, "failed to send message via mbox: %d\n", ret);
0090 }
0091 
0092 static int st_rproc_mem_alloc(struct rproc *rproc,
0093                   struct rproc_mem_entry *mem)
0094 {
0095     struct device *dev = rproc->dev.parent;
0096     void *va;
0097 
0098     va = ioremap_wc(mem->dma, mem->len);
0099     if (!va) {
0100         dev_err(dev, "Unable to map memory region: %pa+%zx\n",
0101             &mem->dma, mem->len);
0102         return -ENOMEM;
0103     }
0104 
0105     /* Update memory entry va */
0106     mem->va = va;
0107 
0108     return 0;
0109 }
0110 
0111 static int st_rproc_mem_release(struct rproc *rproc,
0112                 struct rproc_mem_entry *mem)
0113 {
0114     iounmap(mem->va);
0115 
0116     return 0;
0117 }
0118 
0119 static int st_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
0120 {
0121     struct device *dev = rproc->dev.parent;
0122     struct device_node *np = dev->of_node;
0123     struct rproc_mem_entry *mem;
0124     struct reserved_mem *rmem;
0125     struct of_phandle_iterator it;
0126     int index = 0;
0127 
0128     of_phandle_iterator_init(&it, np, "memory-region", NULL, 0);
0129     while (of_phandle_iterator_next(&it) == 0) {
0130         rmem = of_reserved_mem_lookup(it.node);
0131         if (!rmem) {
0132             dev_err(dev, "unable to acquire memory-region\n");
0133             return -EINVAL;
0134         }
0135 
0136         /*  No need to map vdev buffer */
0137         if (strcmp(it.node->name, "vdev0buffer")) {
0138             /* Register memory region */
0139             mem = rproc_mem_entry_init(dev, NULL,
0140                            (dma_addr_t)rmem->base,
0141                            rmem->size, rmem->base,
0142                            st_rproc_mem_alloc,
0143                            st_rproc_mem_release,
0144                            it.node->name);
0145         } else {
0146             /* Register reserved memory for vdev buffer allocation */
0147             mem = rproc_of_resm_mem_entry_init(dev, index,
0148                                rmem->size,
0149                                rmem->base,
0150                                it.node->name);
0151         }
0152 
0153         if (!mem)
0154             return -ENOMEM;
0155 
0156         rproc_add_carveout(rproc, mem);
0157         index++;
0158     }
0159 
0160     return rproc_elf_load_rsc_table(rproc, fw);
0161 }
0162 
0163 static int st_rproc_start(struct rproc *rproc)
0164 {
0165     struct st_rproc *ddata = rproc->priv;
0166     int err;
0167 
0168     regmap_update_bits(ddata->boot_base, ddata->boot_offset,
0169                ddata->config->bootaddr_mask, rproc->bootaddr);
0170 
0171     err = clk_enable(ddata->clk);
0172     if (err) {
0173         dev_err(&rproc->dev, "Failed to enable clock\n");
0174         return err;
0175     }
0176 
0177     if (ddata->config->sw_reset) {
0178         err = reset_control_deassert(ddata->sw_reset);
0179         if (err) {
0180             dev_err(&rproc->dev, "Failed to deassert S/W Reset\n");
0181             goto sw_reset_fail;
0182         }
0183     }
0184 
0185     if (ddata->config->pwr_reset) {
0186         err = reset_control_deassert(ddata->pwr_reset);
0187         if (err) {
0188             dev_err(&rproc->dev, "Failed to deassert Power Reset\n");
0189             goto pwr_reset_fail;
0190         }
0191     }
0192 
0193     dev_info(&rproc->dev, "Started from 0x%llx\n", rproc->bootaddr);
0194 
0195     return 0;
0196 
0197 
0198 pwr_reset_fail:
0199     if (ddata->config->pwr_reset)
0200         reset_control_assert(ddata->sw_reset);
0201 sw_reset_fail:
0202     clk_disable(ddata->clk);
0203 
0204     return err;
0205 }
0206 
0207 static int st_rproc_stop(struct rproc *rproc)
0208 {
0209     struct st_rproc *ddata = rproc->priv;
0210     int sw_err = 0, pwr_err = 0;
0211 
0212     if (ddata->config->sw_reset) {
0213         sw_err = reset_control_assert(ddata->sw_reset);
0214         if (sw_err)
0215             dev_err(&rproc->dev, "Failed to assert S/W Reset\n");
0216     }
0217 
0218     if (ddata->config->pwr_reset) {
0219         pwr_err = reset_control_assert(ddata->pwr_reset);
0220         if (pwr_err)
0221             dev_err(&rproc->dev, "Failed to assert Power Reset\n");
0222     }
0223 
0224     clk_disable(ddata->clk);
0225 
0226     return sw_err ?: pwr_err;
0227 }
0228 
0229 static const struct rproc_ops st_rproc_ops = {
0230     .kick           = st_rproc_kick,
0231     .start          = st_rproc_start,
0232     .stop           = st_rproc_stop,
0233     .parse_fw       = st_rproc_parse_fw,
0234     .load           = rproc_elf_load_segments,
0235     .find_loaded_rsc_table  = rproc_elf_find_loaded_rsc_table,
0236     .sanity_check       = rproc_elf_sanity_check,
0237     .get_boot_addr      = rproc_elf_get_boot_addr,
0238 };
0239 
0240 /*
0241  * Fetch state of the processor: 0 is off, 1 is on.
0242  */
0243 static int st_rproc_state(struct platform_device *pdev)
0244 {
0245     struct rproc *rproc = platform_get_drvdata(pdev);
0246     struct st_rproc *ddata = rproc->priv;
0247     int reset_sw = 0, reset_pwr = 0;
0248 
0249     if (ddata->config->sw_reset)
0250         reset_sw = reset_control_status(ddata->sw_reset);
0251 
0252     if (ddata->config->pwr_reset)
0253         reset_pwr = reset_control_status(ddata->pwr_reset);
0254 
0255     if (reset_sw < 0 || reset_pwr < 0)
0256         return -EINVAL;
0257 
0258     return !reset_sw && !reset_pwr;
0259 }
0260 
0261 static const struct st_rproc_config st40_rproc_cfg = {
0262     .sw_reset = true,
0263     .pwr_reset = true,
0264     .bootaddr_mask = GENMASK(28, 1),
0265 };
0266 
0267 static const struct st_rproc_config st231_rproc_cfg = {
0268     .sw_reset = true,
0269     .pwr_reset = false,
0270     .bootaddr_mask = GENMASK(31, 6),
0271 };
0272 
0273 static const struct of_device_id st_rproc_match[] = {
0274     { .compatible = "st,st40-rproc", .data = &st40_rproc_cfg },
0275     { .compatible = "st,st231-rproc", .data = &st231_rproc_cfg },
0276     {},
0277 };
0278 MODULE_DEVICE_TABLE(of, st_rproc_match);
0279 
0280 static int st_rproc_parse_dt(struct platform_device *pdev)
0281 {
0282     struct device *dev = &pdev->dev;
0283     struct rproc *rproc = platform_get_drvdata(pdev);
0284     struct st_rproc *ddata = rproc->priv;
0285     struct device_node *np = dev->of_node;
0286     int err;
0287 
0288     if (ddata->config->sw_reset) {
0289         ddata->sw_reset = devm_reset_control_get_exclusive(dev,
0290                                    "sw_reset");
0291         if (IS_ERR(ddata->sw_reset)) {
0292             dev_err(dev, "Failed to get S/W Reset\n");
0293             return PTR_ERR(ddata->sw_reset);
0294         }
0295     }
0296 
0297     if (ddata->config->pwr_reset) {
0298         ddata->pwr_reset = devm_reset_control_get_exclusive(dev,
0299                                     "pwr_reset");
0300         if (IS_ERR(ddata->pwr_reset)) {
0301             dev_err(dev, "Failed to get Power Reset\n");
0302             return PTR_ERR(ddata->pwr_reset);
0303         }
0304     }
0305 
0306     ddata->clk = devm_clk_get(dev, NULL);
0307     if (IS_ERR(ddata->clk)) {
0308         dev_err(dev, "Failed to get clock\n");
0309         return PTR_ERR(ddata->clk);
0310     }
0311 
0312     err = of_property_read_u32(np, "clock-frequency", &ddata->clk_rate);
0313     if (err) {
0314         dev_err(dev, "failed to get clock frequency\n");
0315         return err;
0316     }
0317 
0318     ddata->boot_base = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
0319     if (IS_ERR(ddata->boot_base)) {
0320         dev_err(dev, "Boot base not found\n");
0321         return PTR_ERR(ddata->boot_base);
0322     }
0323 
0324     err = of_property_read_u32_index(np, "st,syscfg", 1,
0325                      &ddata->boot_offset);
0326     if (err) {
0327         dev_err(dev, "Boot offset not found\n");
0328         return -EINVAL;
0329     }
0330 
0331     err = clk_prepare(ddata->clk);
0332     if (err)
0333         dev_err(dev, "failed to get clock\n");
0334 
0335     return err;
0336 }
0337 
0338 static int st_rproc_probe(struct platform_device *pdev)
0339 {
0340     struct device *dev = &pdev->dev;
0341     const struct of_device_id *match;
0342     struct st_rproc *ddata;
0343     struct device_node *np = dev->of_node;
0344     struct rproc *rproc;
0345     struct mbox_chan *chan;
0346     int enabled;
0347     int ret, i;
0348 
0349     match = of_match_device(st_rproc_match, dev);
0350     if (!match || !match->data) {
0351         dev_err(dev, "No device match found\n");
0352         return -ENODEV;
0353     }
0354 
0355     rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
0356     if (!rproc)
0357         return -ENOMEM;
0358 
0359     rproc->has_iommu = false;
0360     ddata = rproc->priv;
0361     ddata->config = (struct st_rproc_config *)match->data;
0362 
0363     platform_set_drvdata(pdev, rproc);
0364 
0365     ret = st_rproc_parse_dt(pdev);
0366     if (ret)
0367         goto free_rproc;
0368 
0369     enabled = st_rproc_state(pdev);
0370     if (enabled < 0) {
0371         ret = enabled;
0372         goto free_clk;
0373     }
0374 
0375     if (enabled) {
0376         atomic_inc(&rproc->power);
0377         rproc->state = RPROC_RUNNING;
0378     } else {
0379         clk_set_rate(ddata->clk, ddata->clk_rate);
0380     }
0381 
0382     if (of_get_property(np, "mbox-names", NULL)) {
0383         ddata->mbox_client_vq0.dev      = dev;
0384         ddata->mbox_client_vq0.tx_done      = NULL;
0385         ddata->mbox_client_vq0.tx_block = false;
0386         ddata->mbox_client_vq0.knows_txdone = false;
0387         ddata->mbox_client_vq0.rx_callback  = st_rproc_mbox_callback_vq0;
0388 
0389         ddata->mbox_client_vq1.dev      = dev;
0390         ddata->mbox_client_vq1.tx_done      = NULL;
0391         ddata->mbox_client_vq1.tx_block = false;
0392         ddata->mbox_client_vq1.knows_txdone = false;
0393         ddata->mbox_client_vq1.rx_callback  = st_rproc_mbox_callback_vq1;
0394 
0395         /*
0396          * To control a co-processor without IPC mechanism.
0397          * This driver can be used without mbox and rpmsg.
0398          */
0399         chan = mbox_request_channel_byname(&ddata->mbox_client_vq0, "vq0_rx");
0400         if (IS_ERR(chan)) {
0401             dev_err(&rproc->dev, "failed to request mbox chan 0\n");
0402             ret = PTR_ERR(chan);
0403             goto free_clk;
0404         }
0405         ddata->mbox_chan[ST_RPROC_VQ0 * MBOX_MAX + MBOX_RX] = chan;
0406 
0407         chan = mbox_request_channel_byname(&ddata->mbox_client_vq0, "vq0_tx");
0408         if (IS_ERR(chan)) {
0409             dev_err(&rproc->dev, "failed to request mbox chan 0\n");
0410             ret = PTR_ERR(chan);
0411             goto free_mbox;
0412         }
0413         ddata->mbox_chan[ST_RPROC_VQ0 * MBOX_MAX + MBOX_TX] = chan;
0414 
0415         chan = mbox_request_channel_byname(&ddata->mbox_client_vq1, "vq1_rx");
0416         if (IS_ERR(chan)) {
0417             dev_err(&rproc->dev, "failed to request mbox chan 1\n");
0418             ret = PTR_ERR(chan);
0419             goto free_mbox;
0420         }
0421         ddata->mbox_chan[ST_RPROC_VQ1 * MBOX_MAX + MBOX_RX] = chan;
0422 
0423         chan = mbox_request_channel_byname(&ddata->mbox_client_vq1, "vq1_tx");
0424         if (IS_ERR(chan)) {
0425             dev_err(&rproc->dev, "failed to request mbox chan 1\n");
0426             ret = PTR_ERR(chan);
0427             goto free_mbox;
0428         }
0429         ddata->mbox_chan[ST_RPROC_VQ1 * MBOX_MAX + MBOX_TX] = chan;
0430     }
0431 
0432     ret = rproc_add(rproc);
0433     if (ret)
0434         goto free_mbox;
0435 
0436     return 0;
0437 
0438 free_mbox:
0439     for (i = 0; i < ST_RPROC_MAX_VRING * MBOX_MAX; i++)
0440         mbox_free_channel(ddata->mbox_chan[i]);
0441 free_clk:
0442     clk_unprepare(ddata->clk);
0443 free_rproc:
0444     rproc_free(rproc);
0445     return ret;
0446 }
0447 
0448 static int st_rproc_remove(struct platform_device *pdev)
0449 {
0450     struct rproc *rproc = platform_get_drvdata(pdev);
0451     struct st_rproc *ddata = rproc->priv;
0452     int i;
0453 
0454     rproc_del(rproc);
0455 
0456     clk_disable_unprepare(ddata->clk);
0457 
0458     for (i = 0; i < ST_RPROC_MAX_VRING * MBOX_MAX; i++)
0459         mbox_free_channel(ddata->mbox_chan[i]);
0460 
0461     rproc_free(rproc);
0462 
0463     return 0;
0464 }
0465 
0466 static struct platform_driver st_rproc_driver = {
0467     .probe = st_rproc_probe,
0468     .remove = st_rproc_remove,
0469     .driver = {
0470         .name = "st-rproc",
0471         .of_match_table = of_match_ptr(st_rproc_match),
0472     },
0473 };
0474 module_platform_driver(st_rproc_driver);
0475 
0476 MODULE_DESCRIPTION("ST Remote Processor Control Driver");
0477 MODULE_AUTHOR("Ludovic Barre <ludovic.barre@st.com>");
0478 MODULE_LICENSE("GPL v2");