2 * Qualcomm Peripheral Image Loader
4 * Copyright (C) 2016 Linaro Ltd.
5 * Copyright (C) 2014 Sony Mobile Communications AB
6 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
18 #include <linux/clk.h>
19 #include <linux/delay.h>
20 #include <linux/dma-mapping.h>
21 #include <linux/interrupt.h>
22 #include <linux/kernel.h>
23 #include <linux/mfd/syscon.h>
24 #include <linux/module.h>
25 #include <linux/of_address.h>
26 #include <linux/platform_device.h>
27 #include <linux/regmap.h>
28 #include <linux/regulator/consumer.h>
29 #include <linux/remoteproc.h>
30 #include <linux/reset.h>
31 #include <linux/soc/qcom/smem.h>
32 #include <linux/soc/qcom/smem_state.h>
34 #include "remoteproc_internal.h"
35 #include "qcom_mdt_loader.h"
37 #include <linux/qcom_scm.h>
39 #define MBA_FIRMWARE_NAME "mba.b00"
40 #define MPSS_FIRMWARE_NAME "modem.mdt"
42 #define MPSS_CRASH_REASON_SMEM 421
44 /* RMB Status Register Values */
45 #define RMB_PBL_SUCCESS 0x1
47 #define RMB_MBA_XPU_UNLOCKED 0x1
48 #define RMB_MBA_XPU_UNLOCKED_SCRIBBLED 0x2
49 #define RMB_MBA_META_DATA_AUTH_SUCCESS 0x3
50 #define RMB_MBA_AUTH_COMPLETE 0x4
52 /* PBL/MBA interface registers */
53 #define RMB_MBA_IMAGE_REG 0x00
54 #define RMB_PBL_STATUS_REG 0x04
55 #define RMB_MBA_COMMAND_REG 0x08
56 #define RMB_MBA_STATUS_REG 0x0C
57 #define RMB_PMI_META_DATA_REG 0x10
58 #define RMB_PMI_CODE_START_REG 0x14
59 #define RMB_PMI_CODE_LENGTH_REG 0x18
61 #define RMB_CMD_META_DATA_READY 0x1
62 #define RMB_CMD_LOAD_READY 0x2
64 /* QDSP6SS Register Offsets */
65 #define QDSP6SS_RESET_REG 0x014
66 #define QDSP6SS_GFMUX_CTL_REG 0x020
67 #define QDSP6SS_PWR_CTL_REG 0x030
69 /* AXI Halt Register Offsets */
70 #define AXI_HALTREQ_REG 0x0
71 #define AXI_HALTACK_REG 0x4
72 #define AXI_IDLE_REG 0x8
74 #define HALT_ACK_TIMEOUT_MS 100
77 #define Q6SS_STOP_CORE BIT(0)
78 #define Q6SS_CORE_ARES BIT(1)
79 #define Q6SS_BUS_ARES_ENABLE BIT(2)
81 /* QDSP6SS_GFMUX_CTL */
82 #define Q6SS_CLK_ENABLE BIT(1)
85 #define Q6SS_L2DATA_SLP_NRET_N_0 BIT(0)
86 #define Q6SS_L2DATA_SLP_NRET_N_1 BIT(1)
87 #define Q6SS_L2DATA_SLP_NRET_N_2 BIT(2)
88 #define Q6SS_L2TAG_SLP_NRET_N BIT(16)
89 #define Q6SS_ETB_SLP_NRET_N BIT(17)
90 #define Q6SS_L2DATA_STBY_N BIT(18)
91 #define Q6SS_SLP_RET_N BIT(19)
92 #define Q6SS_CLAMP_IO BIT(20)
93 #define QDSS_BHS_ON BIT(21)
94 #define QDSS_LDO_BYP BIT(22)
100 void __iomem
*reg_base
;
101 void __iomem
*rmb_base
;
103 struct regmap
*halt_map
;
108 struct reset_control
*mss_restart
;
110 struct qcom_smem_state
*state
;
113 struct regulator_bulk_data supply
[4];
119 struct completion start_done
;
120 struct completion stop_done
;
123 phys_addr_t mba_phys
;
127 phys_addr_t mpss_phys
;
128 phys_addr_t mpss_reloc
;
140 static int q6v5_regulator_init(struct q6v5
*qproc
)
144 qproc
->supply
[Q6V5_SUPPLY_CX
].supply
= "cx";
145 qproc
->supply
[Q6V5_SUPPLY_MX
].supply
= "mx";
146 qproc
->supply
[Q6V5_SUPPLY_MSS
].supply
= "mss";
147 qproc
->supply
[Q6V5_SUPPLY_PLL
].supply
= "pll";
149 ret
= devm_regulator_bulk_get(qproc
->dev
,
150 ARRAY_SIZE(qproc
->supply
), qproc
->supply
);
152 dev_err(qproc
->dev
, "failed to get supplies\n");
156 regulator_set_load(qproc
->supply
[Q6V5_SUPPLY_CX
].consumer
, 100000);
157 regulator_set_load(qproc
->supply
[Q6V5_SUPPLY_MSS
].consumer
, 100000);
158 regulator_set_load(qproc
->supply
[Q6V5_SUPPLY_PLL
].consumer
, 10000);
163 static int q6v5_regulator_enable(struct q6v5
*qproc
)
165 struct regulator
*mss
= qproc
->supply
[Q6V5_SUPPLY_MSS
].consumer
;
166 struct regulator
*mx
= qproc
->supply
[Q6V5_SUPPLY_MX
].consumer
;
169 /* TODO: Q6V5_SUPPLY_CX is supposed to be set to super-turbo here */
171 ret
= regulator_set_voltage(mx
, 1050000, INT_MAX
);
175 regulator_set_voltage(mss
, 1000000, 1150000);
177 return regulator_bulk_enable(ARRAY_SIZE(qproc
->supply
), qproc
->supply
);
180 static void q6v5_regulator_disable(struct q6v5
*qproc
)
182 struct regulator
*mss
= qproc
->supply
[Q6V5_SUPPLY_MSS
].consumer
;
183 struct regulator
*mx
= qproc
->supply
[Q6V5_SUPPLY_MX
].consumer
;
185 /* TODO: Q6V5_SUPPLY_CX corner votes should be released */
187 regulator_bulk_disable(ARRAY_SIZE(qproc
->supply
), qproc
->supply
);
188 regulator_set_voltage(mx
, 0, INT_MAX
);
189 regulator_set_voltage(mss
, 0, 1150000);
192 static int q6v5_load(struct rproc
*rproc
, const struct firmware
*fw
)
194 struct q6v5
*qproc
= rproc
->priv
;
196 memcpy(qproc
->mba_region
, fw
->data
, fw
->size
);
201 static const struct rproc_fw_ops q6v5_fw_ops
= {
202 .find_rsc_table
= qcom_mdt_find_rsc_table
,
206 static int q6v5_rmb_pbl_wait(struct q6v5
*qproc
, int ms
)
208 unsigned long timeout
;
211 timeout
= jiffies
+ msecs_to_jiffies(ms
);
213 val
= readl(qproc
->rmb_base
+ RMB_PBL_STATUS_REG
);
217 if (time_after(jiffies
, timeout
))
226 static int q6v5_rmb_mba_wait(struct q6v5
*qproc
, u32 status
, int ms
)
229 unsigned long timeout
;
232 timeout
= jiffies
+ msecs_to_jiffies(ms
);
234 val
= readl(qproc
->rmb_base
+ RMB_MBA_STATUS_REG
);
240 else if (status
&& val
== status
)
243 if (time_after(jiffies
, timeout
))
252 static int q6v5proc_reset(struct q6v5
*qproc
)
257 /* Assert resets, stop core */
258 val
= readl(qproc
->reg_base
+ QDSP6SS_RESET_REG
);
259 val
|= (Q6SS_CORE_ARES
| Q6SS_BUS_ARES_ENABLE
| Q6SS_STOP_CORE
);
260 writel(val
, qproc
->reg_base
+ QDSP6SS_RESET_REG
);
262 /* Enable power block headswitch, and wait for it to stabilize */
263 val
= readl(qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
264 val
|= QDSS_BHS_ON
| QDSS_LDO_BYP
;
265 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
269 * Turn on memories. L2 banks should be done individually
270 * to minimize inrush current.
272 val
= readl(qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
273 val
|= Q6SS_SLP_RET_N
| Q6SS_L2TAG_SLP_NRET_N
|
274 Q6SS_ETB_SLP_NRET_N
| Q6SS_L2DATA_STBY_N
;
275 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
276 val
|= Q6SS_L2DATA_SLP_NRET_N_2
;
277 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
278 val
|= Q6SS_L2DATA_SLP_NRET_N_1
;
279 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
280 val
|= Q6SS_L2DATA_SLP_NRET_N_0
;
281 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
283 /* Remove IO clamp */
284 val
&= ~Q6SS_CLAMP_IO
;
285 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
287 /* Bring core out of reset */
288 val
= readl(qproc
->reg_base
+ QDSP6SS_RESET_REG
);
289 val
&= ~Q6SS_CORE_ARES
;
290 writel(val
, qproc
->reg_base
+ QDSP6SS_RESET_REG
);
292 /* Turn on core clock */
293 val
= readl(qproc
->reg_base
+ QDSP6SS_GFMUX_CTL_REG
);
294 val
|= Q6SS_CLK_ENABLE
;
295 writel(val
, qproc
->reg_base
+ QDSP6SS_GFMUX_CTL_REG
);
297 /* Start core execution */
298 val
= readl(qproc
->reg_base
+ QDSP6SS_RESET_REG
);
299 val
&= ~Q6SS_STOP_CORE
;
300 writel(val
, qproc
->reg_base
+ QDSP6SS_RESET_REG
);
302 /* Wait for PBL status */
303 ret
= q6v5_rmb_pbl_wait(qproc
, 1000);
304 if (ret
== -ETIMEDOUT
) {
305 dev_err(qproc
->dev
, "PBL boot timed out\n");
306 } else if (ret
!= RMB_PBL_SUCCESS
) {
307 dev_err(qproc
->dev
, "PBL returned unexpected status %d\n", ret
);
316 static void q6v5proc_halt_axi_port(struct q6v5
*qproc
,
317 struct regmap
*halt_map
,
320 unsigned long timeout
;
324 /* Check if we're already idle */
325 ret
= regmap_read(halt_map
, offset
+ AXI_IDLE_REG
, &val
);
329 /* Assert halt request */
330 regmap_write(halt_map
, offset
+ AXI_HALTREQ_REG
, 1);
333 timeout
= jiffies
+ msecs_to_jiffies(HALT_ACK_TIMEOUT_MS
);
335 ret
= regmap_read(halt_map
, offset
+ AXI_HALTACK_REG
, &val
);
336 if (ret
|| val
|| time_after(jiffies
, timeout
))
342 ret
= regmap_read(halt_map
, offset
+ AXI_IDLE_REG
, &val
);
344 dev_err(qproc
->dev
, "port failed halt\n");
346 /* Clear halt request (port will remain halted until reset) */
347 regmap_write(halt_map
, offset
+ AXI_HALTREQ_REG
, 0);
350 static int q6v5_mpss_init_image(struct q6v5
*qproc
, const struct firmware
*fw
)
352 DEFINE_DMA_ATTRS(attrs
);
357 dma_set_attr(DMA_ATTR_FORCE_CONTIGUOUS
, &attrs
);
358 ptr
= dma_alloc_attrs(qproc
->dev
, fw
->size
, &phys
, GFP_KERNEL
, &attrs
);
360 dev_err(qproc
->dev
, "failed to allocate mdt buffer\n");
364 memcpy(ptr
, fw
->data
, fw
->size
);
366 writel(phys
, qproc
->rmb_base
+ RMB_PMI_META_DATA_REG
);
367 writel(RMB_CMD_META_DATA_READY
, qproc
->rmb_base
+ RMB_MBA_COMMAND_REG
);
369 ret
= q6v5_rmb_mba_wait(qproc
, RMB_MBA_META_DATA_AUTH_SUCCESS
, 1000);
370 if (ret
== -ETIMEDOUT
)
371 dev_err(qproc
->dev
, "MPSS header authentication timed out\n");
373 dev_err(qproc
->dev
, "MPSS header authentication failed: %d\n", ret
);
375 dma_free_attrs(qproc
->dev
, fw
->size
, ptr
, phys
, &attrs
);
377 return ret
< 0 ? ret
: 0;
380 static int q6v5_mpss_validate(struct q6v5
*qproc
, const struct firmware
*fw
)
382 const struct elf32_phdr
*phdrs
;
383 const struct elf32_phdr
*phdr
;
384 struct elf32_hdr
*ehdr
;
385 phys_addr_t boot_addr
;
392 ret
= qcom_mdt_parse(fw
, &fw_addr
, NULL
, &relocate
);
394 dev_err(qproc
->dev
, "failed to parse mdt header\n");
399 boot_addr
= qproc
->mpss_phys
;
403 ehdr
= (struct elf32_hdr
*)fw
->data
;
404 phdrs
= (struct elf32_phdr
*)(ehdr
+ 1);
405 for (i
= 0; i
< ehdr
->e_phnum
; i
++, phdr
++) {
408 if (phdr
->p_type
!= PT_LOAD
)
411 if ((phdr
->p_flags
& QCOM_MDT_TYPE_MASK
) == QCOM_MDT_TYPE_HASH
)
417 size
= readl(qproc
->rmb_base
+ RMB_PMI_CODE_LENGTH_REG
);
419 writel(boot_addr
, qproc
->rmb_base
+ RMB_PMI_CODE_START_REG
);
420 writel(RMB_CMD_LOAD_READY
, qproc
->rmb_base
+ RMB_MBA_COMMAND_REG
);
423 size
+= phdr
->p_memsz
;
424 writel(size
, qproc
->rmb_base
+ RMB_PMI_CODE_LENGTH_REG
);
427 ret
= q6v5_rmb_mba_wait(qproc
, RMB_MBA_AUTH_COMPLETE
, 10000);
428 if (ret
== -ETIMEDOUT
)
429 dev_err(qproc
->dev
, "MPSS authentication timed out\n");
431 dev_err(qproc
->dev
, "MPSS authentication failed: %d\n", ret
);
433 return ret
< 0 ? ret
: 0;
436 static int q6v5_mpss_load(struct q6v5
*qproc
)
438 const struct firmware
*fw
;
443 ret
= request_firmware(&fw
, MPSS_FIRMWARE_NAME
, qproc
->dev
);
445 dev_err(qproc
->dev
, "unable to load " MPSS_FIRMWARE_NAME
"\n");
449 ret
= qcom_mdt_parse(fw
, &fw_addr
, NULL
, &relocate
);
451 dev_err(qproc
->dev
, "failed to parse mdt header\n");
452 goto release_firmware
;
456 qproc
->mpss_reloc
= fw_addr
;
458 /* Initialize the RMB validator */
459 writel(0, qproc
->rmb_base
+ RMB_PMI_CODE_LENGTH_REG
);
461 ret
= q6v5_mpss_init_image(qproc
, fw
);
463 goto release_firmware
;
465 ret
= qcom_mdt_load(qproc
->rproc
, fw
, MPSS_FIRMWARE_NAME
);
467 goto release_firmware
;
469 ret
= q6v5_mpss_validate(qproc
, fw
);
472 release_firmware(fw
);
474 return ret
< 0 ? ret
: 0;
477 static int q6v5_start(struct rproc
*rproc
)
479 struct q6v5
*qproc
= (struct q6v5
*)rproc
->priv
;
482 ret
= q6v5_regulator_enable(qproc
);
484 dev_err(qproc
->dev
, "failed to enable supplies\n");
488 ret
= reset_control_deassert(qproc
->mss_restart
);
490 dev_err(qproc
->dev
, "failed to deassert mss restart\n");
494 ret
= clk_prepare_enable(qproc
->ahb_clk
);
498 ret
= clk_prepare_enable(qproc
->axi_clk
);
500 goto disable_ahb_clk
;
502 ret
= clk_prepare_enable(qproc
->rom_clk
);
504 goto disable_axi_clk
;
506 writel(qproc
->mba_phys
, qproc
->rmb_base
+ RMB_MBA_IMAGE_REG
);
508 ret
= q6v5proc_reset(qproc
);
512 ret
= q6v5_rmb_mba_wait(qproc
, 0, 5000);
513 if (ret
== -ETIMEDOUT
) {
514 dev_err(qproc
->dev
, "MBA boot timed out\n");
516 } else if (ret
!= RMB_MBA_XPU_UNLOCKED
&&
517 ret
!= RMB_MBA_XPU_UNLOCKED_SCRIBBLED
) {
518 dev_err(qproc
->dev
, "MBA returned unexpected status %d\n", ret
);
523 dev_info(qproc
->dev
, "MBA booted, loading mpss\n");
525 ret
= q6v5_mpss_load(qproc
);
529 ret
= wait_for_completion_timeout(&qproc
->start_done
,
530 msecs_to_jiffies(5000));
532 dev_err(qproc
->dev
, "start timed out\n");
537 qproc
->running
= true;
539 /* TODO: All done, release the handover resources */
544 q6v5proc_halt_axi_port(qproc
, qproc
->halt_map
, qproc
->halt_q6
);
545 q6v5proc_halt_axi_port(qproc
, qproc
->halt_map
, qproc
->halt_modem
);
546 q6v5proc_halt_axi_port(qproc
, qproc
->halt_map
, qproc
->halt_nc
);
548 clk_disable_unprepare(qproc
->rom_clk
);
550 clk_disable_unprepare(qproc
->axi_clk
);
552 clk_disable_unprepare(qproc
->ahb_clk
);
554 reset_control_assert(qproc
->mss_restart
);
556 q6v5_regulator_disable(qproc
);
561 static int q6v5_stop(struct rproc
*rproc
)
563 struct q6v5
*qproc
= (struct q6v5
*)rproc
->priv
;
566 qproc
->running
= false;
568 qcom_smem_state_update_bits(qproc
->state
,
569 BIT(qproc
->stop_bit
), BIT(qproc
->stop_bit
));
571 ret
= wait_for_completion_timeout(&qproc
->stop_done
,
572 msecs_to_jiffies(5000));
574 dev_err(qproc
->dev
, "timed out on wait\n");
576 qcom_smem_state_update_bits(qproc
->state
, BIT(qproc
->stop_bit
), 0);
578 q6v5proc_halt_axi_port(qproc
, qproc
->halt_map
, qproc
->halt_q6
);
579 q6v5proc_halt_axi_port(qproc
, qproc
->halt_map
, qproc
->halt_modem
);
580 q6v5proc_halt_axi_port(qproc
, qproc
->halt_map
, qproc
->halt_nc
);
582 reset_control_assert(qproc
->mss_restart
);
583 clk_disable_unprepare(qproc
->rom_clk
);
584 clk_disable_unprepare(qproc
->axi_clk
);
585 clk_disable_unprepare(qproc
->ahb_clk
);
586 q6v5_regulator_disable(qproc
);
591 static void *q6v5_da_to_va(struct rproc
*rproc
, u64 da
, int len
)
593 struct q6v5
*qproc
= rproc
->priv
;
596 offset
= da
- qproc
->mpss_reloc
;
597 if (offset
< 0 || offset
+ len
> qproc
->mpss_size
)
600 return qproc
->mpss_region
+ offset
;
603 static const struct rproc_ops q6v5_ops
= {
606 .da_to_va
= q6v5_da_to_va
,
609 static irqreturn_t
q6v5_wdog_interrupt(int irq
, void *dev
)
611 struct q6v5
*qproc
= dev
;
615 /* Sometimes the stop triggers a watchdog rather than a stop-ack */
616 if (!qproc
->running
) {
617 complete(&qproc
->stop_done
);
621 msg
= qcom_smem_get(QCOM_SMEM_HOST_ANY
, MPSS_CRASH_REASON_SMEM
, &len
);
622 if (!IS_ERR(msg
) && len
> 0 && msg
[0])
623 dev_err(qproc
->dev
, "watchdog received: %s\n", msg
);
625 dev_err(qproc
->dev
, "watchdog without message\n");
627 rproc_report_crash(qproc
->rproc
, RPROC_WATCHDOG
);
635 static irqreturn_t
q6v5_fatal_interrupt(int irq
, void *dev
)
637 struct q6v5
*qproc
= dev
;
641 msg
= qcom_smem_get(QCOM_SMEM_HOST_ANY
, MPSS_CRASH_REASON_SMEM
, &len
);
642 if (!IS_ERR(msg
) && len
> 0 && msg
[0])
643 dev_err(qproc
->dev
, "fatal error received: %s\n", msg
);
645 dev_err(qproc
->dev
, "fatal error without message\n");
647 rproc_report_crash(qproc
->rproc
, RPROC_FATAL_ERROR
);
655 static irqreturn_t
q6v5_handover_interrupt(int irq
, void *dev
)
657 struct q6v5
*qproc
= dev
;
659 complete(&qproc
->start_done
);
663 static irqreturn_t
q6v5_stop_ack_interrupt(int irq
, void *dev
)
665 struct q6v5
*qproc
= dev
;
667 complete(&qproc
->stop_done
);
671 static int q6v5_init_mem(struct q6v5
*qproc
, struct platform_device
*pdev
)
673 struct of_phandle_args args
;
674 struct resource
*res
;
677 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "qdsp6");
678 qproc
->reg_base
= devm_ioremap_resource(&pdev
->dev
, res
);
679 if (IS_ERR(qproc
->reg_base
))
680 return PTR_ERR(qproc
->reg_base
);
682 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "rmb");
683 qproc
->rmb_base
= devm_ioremap_resource(&pdev
->dev
, res
);
684 if (IS_ERR(qproc
->rmb_base
))
685 return PTR_ERR(qproc
->rmb_base
);
687 ret
= of_parse_phandle_with_fixed_args(pdev
->dev
.of_node
,
688 "qcom,halt-regs", 3, 0, &args
);
690 dev_err(&pdev
->dev
, "failed to parse qcom,halt-regs\n");
694 qproc
->halt_map
= syscon_node_to_regmap(args
.np
);
695 of_node_put(args
.np
);
696 if (IS_ERR(qproc
->halt_map
))
697 return PTR_ERR(qproc
->halt_map
);
699 qproc
->halt_q6
= args
.args
[0];
700 qproc
->halt_modem
= args
.args
[1];
701 qproc
->halt_nc
= args
.args
[2];
706 static int q6v5_init_clocks(struct q6v5
*qproc
)
708 qproc
->ahb_clk
= devm_clk_get(qproc
->dev
, "iface");
709 if (IS_ERR(qproc
->ahb_clk
)) {
710 dev_err(qproc
->dev
, "failed to get iface clock\n");
711 return PTR_ERR(qproc
->ahb_clk
);
714 qproc
->axi_clk
= devm_clk_get(qproc
->dev
, "bus");
715 if (IS_ERR(qproc
->axi_clk
)) {
716 dev_err(qproc
->dev
, "failed to get bus clock\n");
717 return PTR_ERR(qproc
->axi_clk
);
720 qproc
->rom_clk
= devm_clk_get(qproc
->dev
, "mem");
721 if (IS_ERR(qproc
->rom_clk
)) {
722 dev_err(qproc
->dev
, "failed to get mem clock\n");
723 return PTR_ERR(qproc
->rom_clk
);
729 static int q6v5_init_reset(struct q6v5
*qproc
)
731 qproc
->mss_restart
= devm_reset_control_get(qproc
->dev
, NULL
);
732 if (IS_ERR(qproc
->mss_restart
)) {
733 dev_err(qproc
->dev
, "failed to acquire mss restart\n");
734 return PTR_ERR(qproc
->mss_restart
);
740 static int q6v5_request_irq(struct q6v5
*qproc
,
741 struct platform_device
*pdev
,
743 irq_handler_t thread_fn
)
747 ret
= platform_get_irq_byname(pdev
, name
);
749 dev_err(&pdev
->dev
, "no %s IRQ defined\n", name
);
753 ret
= devm_request_threaded_irq(&pdev
->dev
, ret
,
755 IRQF_TRIGGER_RISING
| IRQF_ONESHOT
,
758 dev_err(&pdev
->dev
, "request %s IRQ failed\n", name
);
763 static int q6v5_alloc_memory_region(struct q6v5
*qproc
)
765 struct device_node
*child
;
766 struct device_node
*node
;
770 child
= of_get_child_by_name(qproc
->dev
->of_node
, "mba");
771 node
= of_parse_phandle(child
, "memory-region", 0);
772 ret
= of_address_to_resource(node
, 0, &r
);
774 dev_err(qproc
->dev
, "unable to resolve mba region\n");
778 qproc
->mba_phys
= r
.start
;
779 qproc
->mba_size
= resource_size(&r
);
780 qproc
->mba_region
= devm_ioremap_wc(qproc
->dev
, qproc
->mba_phys
, qproc
->mba_size
);
781 if (!qproc
->mba_region
) {
782 dev_err(qproc
->dev
, "unable to map memory region: %pa+%zx\n",
783 &r
.start
, qproc
->mba_size
);
787 child
= of_get_child_by_name(qproc
->dev
->of_node
, "mpss");
788 node
= of_parse_phandle(child
, "memory-region", 0);
789 ret
= of_address_to_resource(node
, 0, &r
);
791 dev_err(qproc
->dev
, "unable to resolve mpss region\n");
795 qproc
->mpss_phys
= qproc
->mpss_reloc
= r
.start
;
796 qproc
->mpss_size
= resource_size(&r
);
797 qproc
->mpss_region
= devm_ioremap_wc(qproc
->dev
, qproc
->mpss_phys
, qproc
->mpss_size
);
798 if (!qproc
->mpss_region
) {
799 dev_err(qproc
->dev
, "unable to map memory region: %pa+%zx\n",
800 &r
.start
, qproc
->mpss_size
);
807 static int q6v5_probe(struct platform_device
*pdev
)
813 rproc
= rproc_alloc(&pdev
->dev
, pdev
->name
, &q6v5_ops
,
814 MBA_FIRMWARE_NAME
, sizeof(*qproc
));
816 dev_err(&pdev
->dev
, "failed to allocate rproc\n");
820 rproc
->fw_ops
= &q6v5_fw_ops
;
822 qproc
= (struct q6v5
*)rproc
->priv
;
823 qproc
->dev
= &pdev
->dev
;
824 qproc
->rproc
= rproc
;
825 platform_set_drvdata(pdev
, qproc
);
827 init_completion(&qproc
->start_done
);
828 init_completion(&qproc
->stop_done
);
830 ret
= q6v5_init_mem(qproc
, pdev
);
834 ret
= q6v5_alloc_memory_region(qproc
);
838 ret
= q6v5_init_clocks(qproc
);
842 ret
= q6v5_regulator_init(qproc
);
846 ret
= q6v5_init_reset(qproc
);
850 ret
= q6v5_request_irq(qproc
, pdev
, "wdog", q6v5_wdog_interrupt
);
854 ret
= q6v5_request_irq(qproc
, pdev
, "fatal", q6v5_fatal_interrupt
);
858 ret
= q6v5_request_irq(qproc
, pdev
, "handover", q6v5_handover_interrupt
);
862 ret
= q6v5_request_irq(qproc
, pdev
, "stop-ack", q6v5_stop_ack_interrupt
);
866 qproc
->state
= qcom_smem_state_get(&pdev
->dev
, "stop", &qproc
->stop_bit
);
867 if (IS_ERR(qproc
->state
))
870 ret
= rproc_add(rproc
);
882 static int q6v5_remove(struct platform_device
*pdev
)
884 struct q6v5
*qproc
= platform_get_drvdata(pdev
);
886 rproc_del(qproc
->rproc
);
887 rproc_put(qproc
->rproc
);
892 static const struct of_device_id q6v5_of_match
[] = {
893 { .compatible
= "qcom,q6v5-pil", },
897 static struct platform_driver q6v5_driver
= {
899 .remove
= q6v5_remove
,
901 .name
= "qcom-q6v5-pil",
902 .of_match_table
= q6v5_of_match
,
905 module_platform_driver(q6v5_driver
);
907 MODULE_DESCRIPTION("Peripheral Image Loader for Hexagon");
908 MODULE_LICENSE("GPL v2");