2 * Qualcomm Peripheral Image Loader
4 * Copyright (C) 2014 Sony Mobile Communications AB
5 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/platform_device.h>
20 #include <linux/dma-mapping.h>
21 #include <linux/firmware.h>
22 #include <linux/remoteproc.h>
23 #include <linux/interrupt.h>
24 #include <linux/memblock.h>
25 #include <linux/gpio/consumer.h>
27 #include <linux/elf.h>
28 #include <linux/clk.h>
29 #include <linux/slab.h>
30 #include <linux/regulator/consumer.h>
31 #include <linux/qcom_scm.h>
32 #include <linux/soc/qcom/smem.h>
34 #include <linux/of_address.h>
35 #include <linux/delay.h>
36 #include <linux/soc/qcom/smd.h>
38 #include "remoteproc_internal.h"
40 #define PAS_INIT_IMAGE_CMD 1
41 #define PAS_MEM_SETUP_CMD 2
42 #define PAS_AUTH_AND_RESET_CMD 5
43 #define PAS_SHUTDOWN_CMD 6
44 #define PAS_IS_SUPPORTED_CMD 7
58 struct gpio_desc *stop_gpio;
61 struct regulator *pll;
63 unsigned proxy_clk_count;
65 struct clk *scm_core_clk;
66 struct clk *scm_iface_clk;
67 struct clk *scm_bus_clk;
68 struct clk *scm_src_clk;
70 struct clk **proxy_clks;
72 struct completion start_done;
73 struct completion stop_done;
75 unsigned crash_reason;
76 struct device_node *smd_edge_node;
78 phys_addr_t reloc_phys;
82 static int qproc_scm_clk_enable(struct qproc *qproc)
86 if (qproc->no_scm_clks)
89 ret = clk_prepare_enable(qproc->scm_core_clk);
92 ret = clk_prepare_enable(qproc->scm_iface_clk);
95 ret = clk_prepare_enable(qproc->scm_bus_clk);
99 ret = clk_prepare_enable(qproc->scm_src_clk);
106 clk_disable_unprepare(qproc->scm_bus_clk);
108 clk_disable_unprepare(qproc->scm_iface_clk);
110 clk_disable_unprepare(qproc->scm_core_clk);
115 static void qproc_scm_clk_disable(struct qproc *qproc)
117 if (qproc->no_scm_clks)
120 clk_disable_unprepare(qproc->scm_core_clk);
121 clk_disable_unprepare(qproc->scm_iface_clk);
122 clk_disable_unprepare(qproc->scm_bus_clk);
123 clk_disable_unprepare(qproc->scm_src_clk);
127 * struct pil_mdt - Representation of <name>.mdt file in memory
129 * @phdr: ELF32 program headers
132 struct elf32_hdr hdr;
133 struct elf32_phdr phdr[];
136 #define segment_is_hash(flag) (((flag) & (0x7 << 24)) == (0x2 << 24))
138 static int segment_is_loadable(const struct elf32_phdr *p)
140 return (p->p_type == PT_LOAD) &&
141 !segment_is_hash(p->p_flags) &&
145 static bool segment_is_relocatable(const struct elf32_phdr *p)
147 return !!(p->p_flags & BIT(27));
151 * rproc_mdt_sanity_check() - sanity check mdt firmware header
152 * @rproc: the remote processor handle
153 * @fw: the mdt header firmware image
155 static int qproc_sanity_check(struct rproc *rproc,
156 const struct firmware *fw)
158 struct elf32_hdr *ehdr;
162 dev_err(&rproc->dev, "failed to load %s\n", rproc->name);
166 if (fw->size < sizeof(struct elf32_hdr)) {
167 dev_err(&rproc->dev, "image is too small\n");
171 mdt = (struct mdt_hdr *)fw->data;
174 if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) {
175 dev_err(&rproc->dev, "image is corrupted (bad magic)\n");
179 if (ehdr->e_phnum == 0) {
180 dev_err(&rproc->dev, "no loadable segments\n");
184 if (sizeof(struct elf32_phdr) * ehdr->e_phnum +
185 sizeof(struct elf32_hdr) > fw->size) {
186 dev_err(&rproc->dev, "firmware size is too small\n");
193 static struct resource_table * qproc_find_rsc_table(struct rproc *rproc,
194 const struct firmware *fw,
197 static struct resource_table table = { .ver = 1, };
199 *tablesz = sizeof(table);
203 static int qproc_load_segment(struct rproc *rproc, const char *fw_name,
204 const struct elf32_phdr *phdr, phys_addr_t paddr)
206 const struct firmware *fw;
210 ptr = ioremap_nocache(paddr, phdr->p_memsz);
212 dev_err(&rproc->dev, "failed to ioremap segment area (%pa+0x%x)\n", &paddr, phdr->p_memsz);
216 if (phdr->p_filesz) {
217 ret = request_firmware(&fw, fw_name, &rproc->dev);
219 dev_err(&rproc->dev, "failed to load %s\n", fw_name);
223 memcpy_toio(ptr, fw->data, fw->size);
225 release_firmware(fw);
228 if (phdr->p_memsz > phdr->p_filesz)
229 memset_io(ptr + phdr->p_filesz, 0,
230 phdr->p_memsz - phdr->p_filesz);
237 static int qproc_load(struct rproc *rproc, const struct firmware *fw)
239 const struct elf32_phdr *phdr;
240 const struct elf32_hdr *ehdr;
241 const struct mdt_hdr *mdt;
242 phys_addr_t min_addr = (phys_addr_t)ULLONG_MAX;
243 phys_addr_t max_addr = 0;
244 phys_addr_t diff_addr;
245 struct qproc *qproc = rproc->priv;
250 bool relocatable = false;
253 ret = qproc_scm_clk_enable(qproc);
257 mdt = (struct mdt_hdr *)fw->data;
260 for (i = 0; i < ehdr->e_phnum; i++) {
261 phdr = &mdt->phdr[i];
263 if (!segment_is_loadable(phdr))
266 if (phdr->p_paddr < min_addr) {
267 min_addr = phdr->p_paddr;
269 if (segment_is_relocatable(phdr)) {
270 align = phdr->p_align;
275 if (phdr->p_paddr + phdr->p_memsz > max_addr)
276 max_addr = round_up(phdr->p_paddr + phdr->p_memsz, SZ_4K);
279 ret = qcom_scm_pas_init_image(qproc->pas_id, fw->data, fw->size);
281 dev_err(qproc->dev, "Invalid firmware metadata\n");
285 diff_addr = max_addr - min_addr;
286 dev_dbg(qproc->dev, "pas_mem_setup %pa, %pa\n", &min_addr, &diff_addr);
288 ret = qcom_scm_pas_mem_setup(qproc->pas_id,
289 relocatable ? qproc->reloc_phys : min_addr, max_addr - min_addr);
291 dev_err(qproc->dev, "unable to setup memory for image\n");
295 fw_name = kzalloc(strlen(qproc->name) + 5, GFP_KERNEL);
299 for (i = 0; i < ehdr->e_phnum; i++) {
300 phdr = &mdt->phdr[i];
302 if (!segment_is_loadable(phdr))
305 paddr = relocatable ?
306 (phdr->p_paddr - min_addr + qproc->reloc_phys) :
308 sprintf(fw_name, "%s.b%02d", qproc->name, i);
309 ret = qproc_load_segment(rproc, fw_name, phdr, paddr);
316 qproc_scm_clk_disable(qproc);
321 const struct rproc_fw_ops qproc_fw_ops = {
322 .find_rsc_table = qproc_find_rsc_table,
324 .sanity_check = qproc_sanity_check,
327 static int qproc_start(struct rproc *rproc)
329 struct qproc *qproc = (struct qproc *)rproc->priv;
332 ret = regulator_enable(qproc->pll);
334 dev_err(qproc->dev, "failed to enable pll supply\n");
338 ret = qproc_scm_clk_enable(qproc);
340 goto disable_regulator;
342 ret = qcom_scm_pas_auth_and_reset(qproc->pas_id);
345 "failed to authenticate image and release reset\n");
349 /* if ready irq not provided skip waiting */
350 if (qproc->ready_irq < 0)
353 ret = wait_for_completion_timeout(&qproc->start_done, msecs_to_jiffies(10000));
355 dev_err(qproc->dev, "start timed out\n");
357 qcom_scm_pas_shutdown(qproc->pas_id);
362 dev_info(qproc->dev, "start successful\n");
367 qproc_scm_clk_disable(qproc);
370 regulator_disable(qproc->pll);
375 static int qproc_stop(struct rproc *rproc)
380 static const struct rproc_ops qproc_ops = {
381 .start = qproc_start,
385 static irqreturn_t qproc_wdog_interrupt(int irq, void *dev)
387 struct qproc *qproc = dev;
389 rproc_report_crash(qproc->rproc, RPROC_WATCHDOG);
393 static irqreturn_t qproc_fatal_interrupt(int irq, void *dev)
395 struct qproc *qproc = dev;
400 msg = qcom_smem_get(-1, qproc->crash_reason, &len);
401 if (IS_ERR(msg) && len > 0 && msg[0])
402 dev_err(qproc->dev, "fatal error received: %s\n", msg);
404 rproc_report_crash(qproc->rproc, RPROC_FATAL_ERROR);
412 static irqreturn_t qproc_ready_interrupt(int irq, void *dev)
414 struct qproc *qproc = dev;
416 complete(&qproc->start_done);
421 static irqreturn_t qproc_handover_interrupt(int irq, void *dev)
423 struct qproc *qproc = dev;
425 qproc_scm_clk_disable(qproc);
426 regulator_disable(qproc->pll);
430 static irqreturn_t qproc_stop_ack_interrupt(int irq, void *dev)
432 struct qproc *qproc = dev;
434 complete(&qproc->stop_done);
438 static ssize_t qproc_boot_store(struct device *dev,
439 struct device_attribute *attr,
440 const char *buf, size_t size)
442 struct qproc *qproc = dev_get_drvdata(dev);
445 ret = rproc_boot(qproc->rproc);
449 static ssize_t qproc_shutdown_store(struct device *dev,
450 struct device_attribute *attr,
451 const char *buf, size_t size)
453 struct qproc *qproc = dev_get_drvdata(dev);
455 rproc_shutdown(qproc->rproc);
459 static const struct device_attribute qproc_attrs[] = {
460 __ATTR(boot, S_IWUSR, 0, qproc_boot_store),
461 __ATTR(shutdown, S_IWUSR, 0, qproc_shutdown_store),
464 static int qproc_init_pas(struct qproc *qproc)
470 ret = of_property_read_u32(qproc->dev->of_node, key, &qproc->pas_id);
472 dev_err(qproc->dev, "Missing or incorrect %s\n", key);
476 if (!qcom_scm_pas_supported(qproc->pas_id)) {
477 dev_err(qproc->dev, "PAS is not available for %d\n", qproc->pas_id);
484 static int qproc_init_clocks(struct qproc *qproc)
489 if (qproc->no_scm_clks)
492 qproc->scm_core_clk = devm_clk_get(qproc->dev, "scm_core_clk");
493 if (IS_ERR(qproc->scm_core_clk)) {
494 if (PTR_ERR(qproc->scm_core_clk) != -EPROBE_DEFER)
495 dev_err(qproc->dev, "failed to acquire scm_core_clk\n");
496 return PTR_ERR(qproc->scm_core_clk);
499 qproc->scm_iface_clk = devm_clk_get(qproc->dev, "scm_iface_clk");
500 if (IS_ERR(qproc->scm_iface_clk)) {
501 if (PTR_ERR(qproc->scm_iface_clk) != -EPROBE_DEFER)
502 dev_err(qproc->dev, "failed to acquire scm_iface_clk\n");
503 return PTR_ERR(qproc->scm_iface_clk);
506 qproc->scm_bus_clk = devm_clk_get(qproc->dev, "scm_bus_clk");
507 if (IS_ERR(qproc->scm_bus_clk)) {
508 if (PTR_ERR(qproc->scm_bus_clk) != -EPROBE_DEFER)
509 dev_err(qproc->dev, "failed to acquire scm_bus_clk\n");
510 return PTR_ERR(qproc->scm_bus_clk);
513 qproc->scm_src_clk = devm_clk_get(qproc->dev, "scm_src_clk");
514 if (IS_ERR(qproc->scm_src_clk)) {
515 if (PTR_ERR(qproc->scm_src_clk) != -EPROBE_DEFER)
516 dev_err(qproc->dev, "failed to acquire scm_src_clk\n");
517 return PTR_ERR(qproc->scm_src_clk);
520 ret = clk_set_rate(qproc->scm_core_clk,
521 clk_round_rate(qproc->scm_core_clk, 19200000));
522 ret = clk_set_rate(qproc->scm_bus_clk,
523 clk_round_rate(qproc->scm_bus_clk, 19200000));
524 ret = clk_set_rate(qproc->scm_iface_clk,
525 clk_round_rate(qproc->scm_iface_clk, 19200000));
526 rate = clk_round_rate(qproc->scm_core_clk, 80000000);
527 ret = clk_set_rate(qproc->scm_src_clk, rate);
529 dev_err(qproc->dev, "failed to set rate of scm_core_clk\n");
536 static int qproc_init_regulators(struct qproc *qproc)
542 qproc->pll = devm_regulator_get(qproc->dev, "qcom,pll");
543 if (IS_ERR(qproc->pll)) {
544 if (PTR_ERR(qproc->pll) != -EPROBE_DEFER)
545 dev_err(qproc->dev, "failed to aquire regulator\n");
546 return PTR_ERR(qproc->pll);
549 ret = of_property_read_u32(qproc->dev->of_node, "qcom,pll-uV", &uV);
551 dev_warn(qproc->dev, "failed to read qcom,pll_uV, skipping\n");
553 regulator_set_voltage(qproc->pll, uV, uV);
555 ret = of_property_read_u32(qproc->dev->of_node, "qcom,pll-uA", &uA);
557 dev_warn(qproc->dev, "failed to read qcom,pll_uA, skipping\n");
559 regulator_set_load(qproc->pll, uA);
564 static int qproc_request_irq(struct qproc *qproc, struct platform_device *pdev, const char *name, irq_handler_t thread_fn)
568 ret = platform_get_irq_byname(pdev, name);
570 dev_err(&pdev->dev, "no %s IRQ defined\n", name);
574 ret = devm_request_threaded_irq(&pdev->dev, ret,
576 IRQF_TRIGGER_RISING | IRQF_ONESHOT,
579 dev_err(&pdev->dev, "request %s IRQ failed\n", name);
583 static int qproc_probe(struct platform_device *pdev)
592 struct device_node *np;
596 key = "qcom,firmware-name";
597 ret = of_property_read_string(pdev->dev.of_node, key, &name);
599 dev_err(&pdev->dev, "missing or incorrect %s\n", key);
603 fw_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s.mdt", name);
607 rproc = rproc_alloc(&pdev->dev, pdev->name, &qproc_ops,
608 fw_name, sizeof(*qproc));
610 dev_err(&pdev->dev, "unable to allocate remoteproc\n");
614 rproc->fw_ops = &qproc_fw_ops;
616 qproc = (struct qproc *)rproc->priv;
617 qproc->dev = &pdev->dev;
618 qproc->rproc = rproc;
620 platform_set_drvdata(pdev, qproc);
622 init_completion(&qproc->start_done);
623 init_completion(&qproc->stop_done);
625 ret = of_property_read_u32(pdev->dev.of_node, "qcom,crash-reason",
626 &qproc->crash_reason);
628 dev_info(&pdev->dev, "no crash reason id\n");
630 qproc->smd_edge_node = of_parse_phandle(pdev->dev.of_node,
631 "qcom,smd-edges", 0);
633 qproc->no_scm_clks = of_device_is_compatible(pdev->dev.of_node,
634 "qcom,apq8064-tz-pil");
636 ret = qproc_init_pas(qproc);
640 ret = qproc_init_clocks(qproc);
644 ret = qproc_init_regulators(qproc);
648 ret = qproc_request_irq(qproc, pdev, "wdog", qproc_wdog_interrupt);
649 qproc->wdog_irq = ret;
651 ret = qproc_request_irq(qproc, pdev, "fatal", qproc_fatal_interrupt);
652 qproc->fatal_irq = ret;
654 ret = qproc_request_irq(qproc, pdev, "ready", qproc_ready_interrupt);
655 qproc->ready_irq = ret;
657 ret = qproc_request_irq(qproc, pdev, "handover", qproc_handover_interrupt);
658 qproc->handover_irq = ret;
660 ret = qproc_request_irq(qproc, pdev, "stop-ack", qproc_stop_ack_interrupt);
661 qproc->stop_ack_irq = ret;
663 for (i = 0; i < ARRAY_SIZE(qproc_attrs); i++) {
664 ret = device_create_file(&pdev->dev, &qproc_attrs[i]);
666 dev_err(&pdev->dev, "unable to create sysfs file\n");
667 goto remove_device_files;
671 np = of_parse_phandle(pdev->dev.of_node, "memory-region", 0);
673 dev_err(&pdev->dev, "No memory region specified\n");
676 ret = of_address_to_resource(np, 0, &r);
681 qproc->reloc_phys = r.start;
682 qproc->reloc_size = resource_size(&r);
684 dev_info(&pdev->dev, "Found relocation area %lu@%pad\n",
685 qproc->reloc_size, &qproc->reloc_phys);
688 ret = rproc_add(rproc);
690 goto remove_device_files;
695 for (i--; i >= 0; i--)
696 device_remove_file(&pdev->dev, &qproc_attrs[i]);
704 static int qproc_remove(struct platform_device *pdev)
706 struct qproc *qproc = platform_get_drvdata(pdev);
709 for (i = 0; i < ARRAY_SIZE(qproc_attrs); i++)
710 device_remove_file(&pdev->dev, &qproc_attrs[i]);
712 rproc_put(qproc->rproc);
717 static const struct of_device_id qproc_of_match[] = {
718 { .compatible = "qcom,tz-pil", },
722 static struct platform_driver qproc_driver = {
723 .probe = qproc_probe,
724 .remove = qproc_remove,
726 .name = "qcom-tz-pil",
727 .of_match_table = qproc_of_match,
731 module_platform_driver(qproc_driver);