Lines Matching +full:bam +full:- +full:dmux

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Qualcomm self-authenticating modem subsystem remoteproc driver
7 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
13 #include <linux/dma-mapping.h>
304 dev_err(qproc->dev, in q6v5_regulator_enable()
315 dev_err(qproc->dev, in q6v5_regulator_enable()
323 dev_err(qproc->dev, "Regulator enable failed\n"); in q6v5_regulator_enable()
330 for (; i >= 0; i--) { in q6v5_regulator_enable()
375 for (i--; i >= 0; i--) in q6v5_clk_enable()
409 for (i--; i >= 0; i--) { in q6v5_pds_enable()
437 regmap_set_bits(qproc->conn_map, qproc->ext_bhs, EXTERNAL_BHS_ON); in q6v5_external_bhs_enable()
439 ret = regmap_read_poll_timeout(qproc->conn_map, qproc->ext_bhs, in q6v5_external_bhs_enable()
444 dev_err(qproc->dev, "External BHS timed out\n"); in q6v5_external_bhs_enable()
445 ret = -ETIMEDOUT; in q6v5_external_bhs_enable()
453 regmap_clear_bits(qproc->conn_map, qproc->ext_bhs, EXTERNAL_BHS_ON); in q6v5_external_bhs_disable()
463 if (!qproc->need_mem_protection) in q6v5_xfer_mem_ownership()
490 if (request_firmware_direct(&dp_fw, "msadp", qproc->dev)) in q6v5_debug_policy_load()
493 if (SZ_1M + dp_fw->size <= qproc->mba_size) { in q6v5_debug_policy_load()
494 memcpy(mba_region + SZ_1M, dp_fw->data, dp_fw->size); in q6v5_debug_policy_load()
495 qproc->dp_size = dp_fw->size; in q6v5_debug_policy_load()
503 struct q6v5 *qproc = rproc->priv; in q6v5_load()
507 if (fw->size > qproc->mba_size || fw->size > SZ_1M) { in q6v5_load()
508 dev_err(qproc->dev, "MBA firmware load failed\n"); in q6v5_load()
509 return -EINVAL; in q6v5_load()
512 mba_region = memremap(qproc->mba_phys, qproc->mba_size, MEMREMAP_WC); in q6v5_load()
514 dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n", in q6v5_load()
515 &qproc->mba_phys, qproc->mba_size); in q6v5_load()
516 return -EBUSY; in q6v5_load()
519 memcpy(mba_region, fw->data, fw->size); in q6v5_load()
530 if (qproc->has_alt_reset) { in q6v5_reset_assert()
531 reset_control_assert(qproc->pdc_reset); in q6v5_reset_assert()
532 ret = reset_control_reset(qproc->mss_restart); in q6v5_reset_assert()
533 reset_control_deassert(qproc->pdc_reset); in q6v5_reset_assert()
534 } else if (qproc->has_spare_reg) { in q6v5_reset_assert()
544 reset_control_assert(qproc->pdc_reset); in q6v5_reset_assert()
545 regmap_update_bits(qproc->conn_map, qproc->conn_box, in q6v5_reset_assert()
547 reset_control_assert(qproc->mss_restart); in q6v5_reset_assert()
548 reset_control_deassert(qproc->pdc_reset); in q6v5_reset_assert()
549 regmap_update_bits(qproc->conn_map, qproc->conn_box, in q6v5_reset_assert()
551 ret = reset_control_deassert(qproc->mss_restart); in q6v5_reset_assert()
552 } else if (qproc->has_ext_cntl_regs) { in q6v5_reset_assert()
553 regmap_write(qproc->conn_map, qproc->rscc_disable, 0); in q6v5_reset_assert()
554 reset_control_assert(qproc->pdc_reset); in q6v5_reset_assert()
555 reset_control_assert(qproc->mss_restart); in q6v5_reset_assert()
556 reset_control_deassert(qproc->pdc_reset); in q6v5_reset_assert()
557 ret = reset_control_deassert(qproc->mss_restart); in q6v5_reset_assert()
559 ret = reset_control_assert(qproc->mss_restart); in q6v5_reset_assert()
569 if (qproc->has_alt_reset) { in q6v5_reset_deassert()
570 reset_control_assert(qproc->pdc_reset); in q6v5_reset_deassert()
571 writel(1, qproc->rmb_base + RMB_MBA_ALT_RESET); in q6v5_reset_deassert()
572 ret = reset_control_reset(qproc->mss_restart); in q6v5_reset_deassert()
573 writel(0, qproc->rmb_base + RMB_MBA_ALT_RESET); in q6v5_reset_deassert()
574 reset_control_deassert(qproc->pdc_reset); in q6v5_reset_deassert()
575 } else if (qproc->has_spare_reg || qproc->has_ext_cntl_regs) { in q6v5_reset_deassert()
576 ret = reset_control_reset(qproc->mss_restart); in q6v5_reset_deassert()
578 ret = reset_control_deassert(qproc->mss_restart); in q6v5_reset_deassert()
591 val = readl(qproc->rmb_base + RMB_PBL_STATUS_REG); in q6v5_rmb_pbl_wait()
596 return -ETIMEDOUT; in q6v5_rmb_pbl_wait()
612 val = readl(qproc->rmb_base + RMB_MBA_STATUS_REG); in q6v5_rmb_mba_wait()
622 return -ETIMEDOUT; in q6v5_rmb_mba_wait()
632 struct rproc *rproc = qproc->rproc; in q6v5_dump_mba_logs()
636 if (!qproc->has_mba_logs) in q6v5_dump_mba_logs()
639 if (q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true, false, qproc->mba_phys, in q6v5_dump_mba_logs()
640 qproc->mba_size)) in q6v5_dump_mba_logs()
643 mba_region = memremap(qproc->mba_phys, qproc->mba_size, MEMREMAP_WC); in q6v5_dump_mba_logs()
650 dev_coredumpv(&rproc->dev, data, MBA_LOG_SIZE, GFP_KERNEL); in q6v5_dump_mba_logs()
661 if (qproc->version == MSS_SDM845) { in q6v5proc_reset()
662 val = readl(qproc->reg_base + QDSP6SS_SLEEP); in q6v5proc_reset()
664 writel(val, qproc->reg_base + QDSP6SS_SLEEP); in q6v5proc_reset()
666 ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_SLEEP, in q6v5proc_reset()
670 dev_err(qproc->dev, "QDSP6SS Sleep clock timed out\n"); in q6v5proc_reset()
671 return -ETIMEDOUT; in q6v5proc_reset()
674 /* De-assert QDSP6 stop core */ in q6v5proc_reset()
675 writel(1, qproc->reg_base + QDSP6SS_BOOT_CORE_START); in q6v5proc_reset()
677 writel(1, qproc->reg_base + QDSP6SS_BOOT_CMD); in q6v5proc_reset()
679 ret = readl_poll_timeout(qproc->rmb_base + RMB_MBA_MSS_STATUS, in q6v5proc_reset()
682 dev_err(qproc->dev, "Boot FSM failed to complete.\n"); in q6v5proc_reset()
689 } else if (qproc->version == MSS_SC7180 || qproc->version == MSS_SC7280) { in q6v5proc_reset()
690 val = readl(qproc->reg_base + QDSP6SS_SLEEP); in q6v5proc_reset()
692 writel(val, qproc->reg_base + QDSP6SS_SLEEP); in q6v5proc_reset()
694 ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_SLEEP, in q6v5proc_reset()
698 dev_err(qproc->dev, "QDSP6SS Sleep clock timed out\n"); in q6v5proc_reset()
699 return -ETIMEDOUT; in q6v5proc_reset()
703 val = readl(qproc->reg_base + QDSP6SS_XO_CBCR); in q6v5proc_reset()
705 writel(val, qproc->reg_base + QDSP6SS_XO_CBCR); in q6v5proc_reset()
707 ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_XO_CBCR, in q6v5proc_reset()
711 dev_err(qproc->dev, "QDSP6SS XO clock timed out\n"); in q6v5proc_reset()
712 return -ETIMEDOUT; in q6v5proc_reset()
715 /* Configure Q6 core CBCR to auto-enable after reset sequence */ in q6v5proc_reset()
716 val = readl(qproc->reg_base + QDSP6SS_CORE_CBCR); in q6v5proc_reset()
718 writel(val, qproc->reg_base + QDSP6SS_CORE_CBCR); in q6v5proc_reset()
720 /* De-assert the Q6 stop core signal */ in q6v5proc_reset()
721 writel(1, qproc->reg_base + QDSP6SS_BOOT_CORE_START); in q6v5proc_reset()
726 /* Trigger the boot FSM to start the Q6 out-of-reset sequence */ in q6v5proc_reset()
727 writel(1, qproc->reg_base + QDSP6SS_BOOT_CMD); in q6v5proc_reset()
730 ret = readl_poll_timeout(qproc->rmb_base + RMB_MBA_MSS_STATUS, in q6v5proc_reset()
733 dev_err(qproc->dev, "Boot FSM failed to complete.\n"); in q6v5proc_reset()
739 } else if (qproc->version == MSS_MSM8909 || in q6v5proc_reset()
740 qproc->version == MSS_MSM8953 || in q6v5proc_reset()
741 qproc->version == MSS_MSM8996 || in q6v5proc_reset()
742 qproc->version == MSS_MSM8998 || in q6v5proc_reset()
743 qproc->version == MSS_SDM660) { in q6v5proc_reset()
745 if (qproc->version != MSS_MSM8909 && in q6v5proc_reset()
746 qproc->version != MSS_MSM8953) in q6v5proc_reset()
749 qproc->reg_base + QDSP6SS_STRAP_ACC); in q6v5proc_reset()
752 val = readl(qproc->reg_base + QDSP6SS_RESET_REG); in q6v5proc_reset()
754 writel(val, qproc->reg_base + QDSP6SS_RESET_REG); in q6v5proc_reset()
757 val = readl(qproc->reg_base + QDSP6SS_XO_CBCR); in q6v5proc_reset()
759 writel(val, qproc->reg_base + QDSP6SS_XO_CBCR); in q6v5proc_reset()
762 ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_XO_CBCR, in q6v5proc_reset()
766 dev_err(qproc->dev, in q6v5proc_reset()
771 val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
773 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
774 val |= readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
777 if (qproc->version == MSS_SDM660) { in q6v5proc_reset()
778 ret = readl_relaxed_poll_timeout(qproc->reg_base + QDSP6V62SS_BHS_STATUS, in q6v5proc_reset()
781 if (ret == -ETIMEDOUT) { in q6v5proc_reset()
782 dev_err(qproc->dev, "BHS_EN_REST_ACK not set!\n"); in q6v5proc_reset()
783 return -ETIMEDOUT; in q6v5proc_reset()
789 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
791 if (qproc->version != MSS_MSM8909) { in q6v5proc_reset()
795 val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
797 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
801 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
804 if (qproc->version == MSS_MSM8953 || in q6v5proc_reset()
805 qproc->version == MSS_MSM8996) { in q6v5proc_reset()
813 val = readl(qproc->reg_base + mem_pwr_ctl); in q6v5proc_reset()
814 for (; i >= 0; i--) { in q6v5proc_reset()
816 writel(val, qproc->reg_base + mem_pwr_ctl); in q6v5proc_reset()
822 val |= readl(qproc->reg_base + mem_pwr_ctl); in q6v5proc_reset()
827 val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
830 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
835 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
840 val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
842 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
845 val = readl(qproc->reg_base + QDSP6SS_RESET_REG); in q6v5proc_reset()
847 writel(val, qproc->reg_base + QDSP6SS_RESET_REG); in q6v5proc_reset()
850 val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
852 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
853 val |= readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
859 val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
862 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
864 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
866 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
868 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
872 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
875 val = readl(qproc->reg_base + QDSP6SS_RESET_REG); in q6v5proc_reset()
877 writel(val, qproc->reg_base + QDSP6SS_RESET_REG); in q6v5proc_reset()
880 val = readl(qproc->reg_base + QDSP6SS_GFMUX_CTL_REG); in q6v5proc_reset()
882 writel(val, qproc->reg_base + QDSP6SS_GFMUX_CTL_REG); in q6v5proc_reset()
885 val = readl(qproc->reg_base + QDSP6SS_RESET_REG); in q6v5proc_reset()
887 writel(val, qproc->reg_base + QDSP6SS_RESET_REG); in q6v5proc_reset()
892 if (ret == -ETIMEDOUT) { in q6v5proc_reset()
893 dev_err(qproc->dev, "PBL boot timed out\n"); in q6v5proc_reset()
895 dev_err(qproc->dev, "PBL returned unexpected status %d\n", ret); in q6v5proc_reset()
896 ret = -EINVAL; in q6v5proc_reset()
909 if (!qproc->has_qaccept_regs) in q6v5proc_enable_qchannel()
912 if (qproc->has_ext_cntl_regs) { in q6v5proc_enable_qchannel()
913 regmap_write(qproc->conn_map, qproc->rscc_disable, 0); in q6v5proc_enable_qchannel()
914 regmap_write(qproc->conn_map, qproc->force_clk_on, 1); in q6v5proc_enable_qchannel()
916 ret = regmap_read_poll_timeout(qproc->halt_map, qproc->axim1_clk_off, val, in q6v5proc_enable_qchannel()
919 dev_err(qproc->dev, "failed to enable axim1 clock\n"); in q6v5proc_enable_qchannel()
920 return -ETIMEDOUT; in q6v5proc_enable_qchannel()
930 dev_err(qproc->dev, "qchannel enable failed\n"); in q6v5proc_enable_qchannel()
931 return -ETIMEDOUT; in q6v5proc_enable_qchannel()
944 if (!qproc->has_qaccept_regs) in q6v5proc_disable_qchannel()
948 nretry--; in q6v5proc_disable_qchannel()
954 /* Request Q-channel transaction takedown */ in q6v5proc_disable_qchannel()
958 * If the request is denied, reset the Q-channel takedown request, in q6v5proc_disable_qchannel()
964 retry--; in q6v5proc_disable_qchannel()
984 dev_err(qproc->dev, "qchannel takedown failed\n"); in q6v5proc_disable_qchannel()
1008 dev_err(qproc->dev, "port failed halt\n"); in q6v5proc_halt_axi_port()
1026 metadata = qcom_mdt_read_metadata(fw, &size, fw_name, qproc->dev); in q6v5_mpss_init_image()
1030 if (qproc->mdata_phys) { in q6v5_mpss_init_image()
1031 if (size > qproc->mdata_size) { in q6v5_mpss_init_image()
1032 ret = -EINVAL; in q6v5_mpss_init_image()
1033 dev_err(qproc->dev, "metadata size outside memory range\n"); in q6v5_mpss_init_image()
1037 phys = qproc->mdata_phys; in q6v5_mpss_init_image()
1038 ptr = memremap(qproc->mdata_phys, size, MEMREMAP_WC); in q6v5_mpss_init_image()
1040 ret = -EBUSY; in q6v5_mpss_init_image()
1041 dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n", in q6v5_mpss_init_image()
1042 &qproc->mdata_phys, size); in q6v5_mpss_init_image()
1046 ptr = dma_alloc_attrs(qproc->dev, size, &phys, GFP_KERNEL, dma_attrs); in q6v5_mpss_init_image()
1048 ret = -ENOMEM; in q6v5_mpss_init_image()
1049 dev_err(qproc->dev, "failed to allocate mdt buffer\n"); in q6v5_mpss_init_image()
1056 if (qproc->mdata_phys) in q6v5_mpss_init_image()
1064 dev_err(qproc->dev, in q6v5_mpss_init_image()
1066 ret = -EAGAIN; in q6v5_mpss_init_image()
1070 writel(phys, qproc->rmb_base + RMB_PMI_META_DATA_REG); in q6v5_mpss_init_image()
1071 writel(RMB_CMD_META_DATA_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG); in q6v5_mpss_init_image()
1074 if (ret == -ETIMEDOUT) in q6v5_mpss_init_image()
1075 dev_err(qproc->dev, "MPSS header authentication timed out\n"); in q6v5_mpss_init_image()
1077 dev_err(qproc->dev, "MPSS header authentication failed: %d\n", ret); in q6v5_mpss_init_image()
1083 dev_warn(qproc->dev, in q6v5_mpss_init_image()
1087 if (!qproc->mdata_phys) in q6v5_mpss_init_image()
1088 dma_free_attrs(qproc->dev, size, ptr, phys, dma_attrs); in q6v5_mpss_init_image()
1097 if (phdr->p_type != PT_LOAD) in q6v5_phdr_valid()
1100 if ((phdr->p_flags & QCOM_MDT_TYPE_MASK) == QCOM_MDT_TYPE_HASH) in q6v5_phdr_valid()
1103 if (!phdr->p_memsz) in q6v5_phdr_valid()
1115 ret = qcom_q6v5_prepare(&qproc->q6v5); in q6v5_mba_load()
1119 ret = q6v5_pds_enable(qproc, qproc->proxy_pds, qproc->proxy_pd_count); in q6v5_mba_load()
1121 dev_err(qproc->dev, "failed to enable proxy power domains\n"); in q6v5_mba_load()
1125 ret = q6v5_regulator_enable(qproc, qproc->fallback_proxy_regs, in q6v5_mba_load()
1126 qproc->fallback_proxy_reg_count); in q6v5_mba_load()
1128 dev_err(qproc->dev, "failed to enable fallback proxy supplies\n"); in q6v5_mba_load()
1132 ret = q6v5_regulator_enable(qproc, qproc->proxy_regs, in q6v5_mba_load()
1133 qproc->proxy_reg_count); in q6v5_mba_load()
1135 dev_err(qproc->dev, "failed to enable proxy supplies\n"); in q6v5_mba_load()
1139 ret = q6v5_clk_enable(qproc->dev, qproc->proxy_clks, in q6v5_mba_load()
1140 qproc->proxy_clk_count); in q6v5_mba_load()
1142 dev_err(qproc->dev, "failed to enable proxy clocks\n"); in q6v5_mba_load()
1146 ret = q6v5_regulator_enable(qproc, qproc->active_regs, in q6v5_mba_load()
1147 qproc->active_reg_count); in q6v5_mba_load()
1149 dev_err(qproc->dev, "failed to enable supplies\n"); in q6v5_mba_load()
1153 if (qproc->has_ext_bhs_reg) { in q6v5_mba_load()
1159 ret = q6v5_clk_enable(qproc->dev, qproc->reset_clks, in q6v5_mba_load()
1160 qproc->reset_clk_count); in q6v5_mba_load()
1162 dev_err(qproc->dev, "failed to enable reset clocks\n"); in q6v5_mba_load()
1168 dev_err(qproc->dev, "failed to deassert mss restart\n"); in q6v5_mba_load()
1172 ret = q6v5_clk_enable(qproc->dev, qproc->active_clks, in q6v5_mba_load()
1173 qproc->active_clk_count); in q6v5_mba_load()
1175 dev_err(qproc->dev, "failed to enable clocks\n"); in q6v5_mba_load()
1179 ret = q6v5proc_enable_qchannel(qproc, qproc->halt_map, qproc->qaccept_axi); in q6v5_mba_load()
1181 dev_err(qproc->dev, "failed to enable axi bridge\n"); in q6v5_mba_load()
1189 ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, false, true, in q6v5_mba_load()
1190 qproc->mpss_phys, qproc->mpss_size); in q6v5_mba_load()
1192 dev_err(qproc->dev, "assigning Q6 access to mpss memory failed: %d\n", ret); in q6v5_mba_load()
1197 ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, false, true, in q6v5_mba_load()
1198 qproc->mba_phys, qproc->mba_size); in q6v5_mba_load()
1200 dev_err(qproc->dev, in q6v5_mba_load()
1205 if (qproc->has_mba_logs) in q6v5_mba_load()
1206 qcom_pil_info_store("mba", qproc->mba_phys, MBA_LOG_SIZE); in q6v5_mba_load()
1208 writel(qproc->mba_phys, qproc->rmb_base + RMB_MBA_IMAGE_REG); in q6v5_mba_load()
1209 if (qproc->dp_size) { in q6v5_mba_load()
1210 writel(qproc->mba_phys + SZ_1M, qproc->rmb_base + RMB_PMI_CODE_START_REG); in q6v5_mba_load()
1211 writel(qproc->dp_size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG); in q6v5_mba_load()
1219 if (ret == -ETIMEDOUT) { in q6v5_mba_load()
1220 dev_err(qproc->dev, "MBA boot timed out\n"); in q6v5_mba_load()
1224 dev_err(qproc->dev, "MBA returned unexpected status %d\n", ret); in q6v5_mba_load()
1225 ret = -EINVAL; in q6v5_mba_load()
1229 qproc->dump_mba_loaded = true; in q6v5_mba_load()
1233 q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6); in q6v5_mba_load()
1234 if (qproc->has_vq6) in q6v5_mba_load()
1235 q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_vq6); in q6v5_mba_load()
1236 q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem); in q6v5_mba_load()
1237 q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc); in q6v5_mba_load()
1238 q6v5proc_disable_qchannel(qproc, qproc->halt_map, qproc->qaccept_mdm); in q6v5_mba_load()
1239 q6v5proc_disable_qchannel(qproc, qproc->halt_map, qproc->qaccept_cx); in q6v5_mba_load()
1240 q6v5proc_disable_qchannel(qproc, qproc->halt_map, qproc->qaccept_axi); in q6v5_mba_load()
1243 xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true, in q6v5_mba_load()
1244 false, qproc->mba_phys, in q6v5_mba_load()
1245 qproc->mba_size); in q6v5_mba_load()
1247 dev_err(qproc->dev, in q6v5_mba_load()
1254 q6v5_clk_disable(qproc->dev, qproc->active_clks, in q6v5_mba_load()
1255 qproc->active_clk_count); in q6v5_mba_load()
1259 q6v5_clk_disable(qproc->dev, qproc->reset_clks, in q6v5_mba_load()
1260 qproc->reset_clk_count); in q6v5_mba_load()
1262 if (qproc->has_ext_bhs_reg) in q6v5_mba_load()
1265 q6v5_regulator_disable(qproc, qproc->active_regs, in q6v5_mba_load()
1266 qproc->active_reg_count); in q6v5_mba_load()
1268 q6v5_clk_disable(qproc->dev, qproc->proxy_clks, in q6v5_mba_load()
1269 qproc->proxy_clk_count); in q6v5_mba_load()
1271 q6v5_regulator_disable(qproc, qproc->proxy_regs, in q6v5_mba_load()
1272 qproc->proxy_reg_count); in q6v5_mba_load()
1274 q6v5_regulator_disable(qproc, qproc->fallback_proxy_regs, in q6v5_mba_load()
1275 qproc->fallback_proxy_reg_count); in q6v5_mba_load()
1277 q6v5_pds_disable(qproc, qproc->proxy_pds, qproc->proxy_pd_count); in q6v5_mba_load()
1279 qcom_q6v5_unprepare(&qproc->q6v5); in q6v5_mba_load()
1289 qproc->dump_mba_loaded = false; in q6v5_mba_reclaim()
1290 qproc->dp_size = 0; in q6v5_mba_reclaim()
1292 q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6); in q6v5_mba_reclaim()
1293 if (qproc->has_vq6) in q6v5_mba_reclaim()
1294 q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_vq6); in q6v5_mba_reclaim()
1295 q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem); in q6v5_mba_reclaim()
1296 q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc); in q6v5_mba_reclaim()
1297 if (qproc->version == MSS_MSM8996) { in q6v5_mba_reclaim()
1301 val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5_mba_reclaim()
1304 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5_mba_reclaim()
1307 if (qproc->has_ext_cntl_regs) { in q6v5_mba_reclaim()
1308 regmap_write(qproc->conn_map, qproc->rscc_disable, 1); in q6v5_mba_reclaim()
1310 ret = regmap_read_poll_timeout(qproc->halt_map, qproc->axim1_clk_off, val, in q6v5_mba_reclaim()
1313 dev_err(qproc->dev, "failed to enable axim1 clock\n"); in q6v5_mba_reclaim()
1315 ret = regmap_read_poll_timeout(qproc->halt_map, qproc->crypto_clk_off, val, in q6v5_mba_reclaim()
1318 dev_err(qproc->dev, "failed to enable crypto clock\n"); in q6v5_mba_reclaim()
1321 q6v5proc_disable_qchannel(qproc, qproc->halt_map, qproc->qaccept_mdm); in q6v5_mba_reclaim()
1322 q6v5proc_disable_qchannel(qproc, qproc->halt_map, qproc->qaccept_cx); in q6v5_mba_reclaim()
1323 q6v5proc_disable_qchannel(qproc, qproc->halt_map, qproc->qaccept_axi); in q6v5_mba_reclaim()
1327 q6v5_clk_disable(qproc->dev, qproc->reset_clks, in q6v5_mba_reclaim()
1328 qproc->reset_clk_count); in q6v5_mba_reclaim()
1329 q6v5_clk_disable(qproc->dev, qproc->active_clks, in q6v5_mba_reclaim()
1330 qproc->active_clk_count); in q6v5_mba_reclaim()
1331 if (qproc->has_ext_bhs_reg) in q6v5_mba_reclaim()
1333 q6v5_regulator_disable(qproc, qproc->active_regs, in q6v5_mba_reclaim()
1334 qproc->active_reg_count); in q6v5_mba_reclaim()
1339 ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true, false, in q6v5_mba_reclaim()
1340 qproc->mba_phys, in q6v5_mba_reclaim()
1341 qproc->mba_size); in q6v5_mba_reclaim()
1344 ret = qcom_q6v5_unprepare(&qproc->q6v5); in q6v5_mba_reclaim()
1346 q6v5_pds_disable(qproc, qproc->proxy_pds, in q6v5_mba_reclaim()
1347 qproc->proxy_pd_count); in q6v5_mba_reclaim()
1348 q6v5_clk_disable(qproc->dev, qproc->proxy_clks, in q6v5_mba_reclaim()
1349 qproc->proxy_clk_count); in q6v5_mba_reclaim()
1350 q6v5_regulator_disable(qproc, qproc->fallback_proxy_regs, in q6v5_mba_reclaim()
1351 qproc->fallback_proxy_reg_count); in q6v5_mba_reclaim()
1352 q6v5_regulator_disable(qproc, qproc->proxy_regs, in q6v5_mba_reclaim()
1353 qproc->proxy_reg_count); in q6v5_mba_reclaim()
1359 struct q6v5 *qproc = rproc->priv; in q6v5_reload_mba()
1363 ret = request_firmware(&fw, rproc->firmware, qproc->dev); in q6v5_reload_mba()
1395 fw_name_len = strlen(qproc->hexagon_mdt_image); in q6v5_mpss_load()
1397 return -EINVAL; in q6v5_mpss_load()
1399 fw_name = kstrdup(qproc->hexagon_mdt_image, GFP_KERNEL); in q6v5_mpss_load()
1401 return -ENOMEM; in q6v5_mpss_load()
1403 ret = request_firmware(&fw, fw_name, qproc->dev); in q6v5_mpss_load()
1405 dev_err(qproc->dev, "unable to load %s\n", fw_name); in q6v5_mpss_load()
1410 writel(0, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG); in q6v5_mpss_load()
1412 ret = q6v5_mpss_init_image(qproc, fw, qproc->hexagon_mdt_image); in q6v5_mpss_load()
1416 ehdr = (struct elf32_hdr *)fw->data; in q6v5_mpss_load()
1419 for (i = 0; i < ehdr->e_phnum; i++) { in q6v5_mpss_load()
1425 if (phdr->p_flags & QCOM_MDT_RELOCATABLE) in q6v5_mpss_load()
1428 if (phdr->p_paddr < min_addr) in q6v5_mpss_load()
1429 min_addr = phdr->p_paddr; in q6v5_mpss_load()
1431 if (phdr->p_paddr + phdr->p_memsz > max_addr) in q6v5_mpss_load()
1432 max_addr = ALIGN(phdr->p_paddr + phdr->p_memsz, SZ_4K); in q6v5_mpss_load()
1435 if (qproc->version == MSS_MSM8953) { in q6v5_mpss_load()
1436 ret = qcom_scm_pas_mem_setup(MPSS_PAS_ID, qproc->mpss_phys, qproc->mpss_size); in q6v5_mpss_load()
1438 dev_err(qproc->dev, in q6v5_mpss_load()
1448 q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, true, false, in q6v5_mpss_load()
1449 qproc->mpss_phys, qproc->mpss_size); in q6v5_mpss_load()
1452 ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, true, true, in q6v5_mpss_load()
1453 qproc->mpss_phys, qproc->mpss_size); in q6v5_mpss_load()
1455 dev_err(qproc->dev, in q6v5_mpss_load()
1457 ret = -EAGAIN; in q6v5_mpss_load()
1461 mpss_reloc = relocate ? min_addr : qproc->mpss_phys; in q6v5_mpss_load()
1462 qproc->mpss_reloc = mpss_reloc; in q6v5_mpss_load()
1464 for (i = 0; i < ehdr->e_phnum; i++) { in q6v5_mpss_load()
1470 offset = phdr->p_paddr - mpss_reloc; in q6v5_mpss_load()
1471 if (offset < 0 || offset + phdr->p_memsz > qproc->mpss_size) { in q6v5_mpss_load()
1472 dev_err(qproc->dev, "segment outside memory range\n"); in q6v5_mpss_load()
1473 ret = -EINVAL; in q6v5_mpss_load()
1477 if (phdr->p_filesz > phdr->p_memsz) { in q6v5_mpss_load()
1478 dev_err(qproc->dev, in q6v5_mpss_load()
1481 ret = -EINVAL; in q6v5_mpss_load()
1485 ptr = memremap(qproc->mpss_phys + offset, phdr->p_memsz, MEMREMAP_WC); in q6v5_mpss_load()
1487 dev_err(qproc->dev, in q6v5_mpss_load()
1488 "unable to map memory region: %pa+%zx-%x\n", in q6v5_mpss_load()
1489 &qproc->mpss_phys, offset, phdr->p_memsz); in q6v5_mpss_load()
1493 if (phdr->p_filesz && phdr->p_offset < fw->size) { in q6v5_mpss_load()
1494 /* Firmware is large enough to be non-split */ in q6v5_mpss_load()
1495 if (phdr->p_offset + phdr->p_filesz > fw->size) { in q6v5_mpss_load()
1496 dev_err(qproc->dev, in q6v5_mpss_load()
1499 ret = -EINVAL; in q6v5_mpss_load()
1504 memcpy(ptr, fw->data + phdr->p_offset, phdr->p_filesz); in q6v5_mpss_load()
1505 } else if (phdr->p_filesz) { in q6v5_mpss_load()
1507 sprintf(fw_name + fw_name_len - 3, "b%02d", i); in q6v5_mpss_load()
1508 ret = request_firmware_into_buf(&seg_fw, fw_name, qproc->dev, in q6v5_mpss_load()
1509 ptr, phdr->p_filesz); in q6v5_mpss_load()
1511 dev_err(qproc->dev, "failed to load %s\n", fw_name); in q6v5_mpss_load()
1516 if (seg_fw->size != phdr->p_filesz) { in q6v5_mpss_load()
1517 dev_err(qproc->dev, in q6v5_mpss_load()
1520 ret = -EINVAL; in q6v5_mpss_load()
1529 if (phdr->p_memsz > phdr->p_filesz) { in q6v5_mpss_load()
1530 memset(ptr + phdr->p_filesz, 0, in q6v5_mpss_load()
1531 phdr->p_memsz - phdr->p_filesz); in q6v5_mpss_load()
1534 size += phdr->p_memsz; in q6v5_mpss_load()
1536 code_length = readl(qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG); in q6v5_mpss_load()
1538 boot_addr = relocate ? qproc->mpss_phys : min_addr; in q6v5_mpss_load()
1539 writel(boot_addr, qproc->rmb_base + RMB_PMI_CODE_START_REG); in q6v5_mpss_load()
1540 writel(RMB_CMD_LOAD_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG); in q6v5_mpss_load()
1542 writel(size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG); in q6v5_mpss_load()
1544 ret = readl(qproc->rmb_base + RMB_MBA_STATUS_REG); in q6v5_mpss_load()
1546 dev_err(qproc->dev, "MPSS authentication failed: %d\n", in q6v5_mpss_load()
1553 ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, false, true, in q6v5_mpss_load()
1554 qproc->mpss_phys, qproc->mpss_size); in q6v5_mpss_load()
1556 dev_err(qproc->dev, in q6v5_mpss_load()
1558 ret = -EAGAIN; in q6v5_mpss_load()
1563 if (ret == -ETIMEDOUT) in q6v5_mpss_load()
1564 dev_err(qproc->dev, "MPSS authentication timed out\n"); in q6v5_mpss_load()
1566 dev_err(qproc->dev, "MPSS authentication failed: %d\n", ret); in q6v5_mpss_load()
1568 qcom_pil_info_store("modem", qproc->mpss_phys, qproc->mpss_size); in q6v5_mpss_load()
1583 struct q6v5 *qproc = rproc->priv; in qcom_q6v5_dump_segment()
1584 int offset = segment->da - qproc->mpss_reloc; in qcom_q6v5_dump_segment()
1588 if (!qproc->dump_mba_loaded) { in qcom_q6v5_dump_segment()
1592 ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, in qcom_q6v5_dump_segment()
1594 qproc->mpss_phys, in qcom_q6v5_dump_segment()
1595 qproc->mpss_size); in qcom_q6v5_dump_segment()
1600 ptr = memremap(qproc->mpss_phys + offset + cp_offset, size, MEMREMAP_WC); in qcom_q6v5_dump_segment()
1609 qproc->current_dump_size += size; in qcom_q6v5_dump_segment()
1612 if (qproc->current_dump_size == qproc->total_dump_size) { in qcom_q6v5_dump_segment()
1613 if (qproc->dump_mba_loaded) { in qcom_q6v5_dump_segment()
1615 q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, in qcom_q6v5_dump_segment()
1617 qproc->mpss_phys, in qcom_q6v5_dump_segment()
1618 qproc->mpss_size); in qcom_q6v5_dump_segment()
1626 struct q6v5 *qproc = rproc->priv; in q6v5_start()
1634 dev_info(qproc->dev, "MBA booted with%s debug policy, loading mpss\n", in q6v5_start()
1635 qproc->dp_size ? "" : "out"); in q6v5_start()
1641 ret = qcom_q6v5_wait_for_start(&qproc->q6v5, msecs_to_jiffies(5000)); in q6v5_start()
1642 if (ret == -ETIMEDOUT) { in q6v5_start()
1643 dev_err(qproc->dev, "start timed out\n"); in q6v5_start()
1647 xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true, in q6v5_start()
1648 false, qproc->mba_phys, in q6v5_start()
1649 qproc->mba_size); in q6v5_start()
1651 dev_err(qproc->dev, in q6v5_start()
1655 qproc->current_dump_size = 0; in q6v5_start()
1668 struct q6v5 *qproc = rproc->priv; in q6v5_stop()
1671 ret = qcom_q6v5_request_stop(&qproc->q6v5, qproc->sysmon); in q6v5_stop()
1672 if (ret == -ETIMEDOUT) in q6v5_stop()
1673 dev_err(qproc->dev, "timed out on wait\n"); in q6v5_stop()
1687 struct q6v5 *qproc = rproc->priv; in qcom_q6v5_register_dump_segments()
1691 ret = request_firmware(&fw, qproc->hexagon_mdt_image, qproc->dev); in qcom_q6v5_register_dump_segments()
1693 dev_err(qproc->dev, "unable to load %s\n", in qcom_q6v5_register_dump_segments()
1694 qproc->hexagon_mdt_image); in qcom_q6v5_register_dump_segments()
1700 ehdr = (struct elf32_hdr *)fw->data; in qcom_q6v5_register_dump_segments()
1702 qproc->total_dump_size = 0; in qcom_q6v5_register_dump_segments()
1704 for (i = 0; i < ehdr->e_phnum; i++) { in qcom_q6v5_register_dump_segments()
1710 ret = rproc_coredump_add_custom_segment(rproc, phdr->p_paddr, in qcom_q6v5_register_dump_segments()
1711 phdr->p_memsz, in qcom_q6v5_register_dump_segments()
1717 qproc->total_dump_size += phdr->p_memsz; in qcom_q6v5_register_dump_segments()
1726 struct q6v5 *qproc = rproc->priv; in q6v5_panic()
1728 return qcom_q6v5_panic(&qproc->q6v5); in q6v5_panic()
1743 q6v5_clk_disable(qproc->dev, qproc->proxy_clks, in qcom_msa_handover()
1744 qproc->proxy_clk_count); in qcom_msa_handover()
1745 q6v5_regulator_disable(qproc, qproc->proxy_regs, in qcom_msa_handover()
1746 qproc->proxy_reg_count); in qcom_msa_handover()
1747 q6v5_regulator_disable(qproc, qproc->fallback_proxy_regs, in qcom_msa_handover()
1748 qproc->fallback_proxy_reg_count); in qcom_msa_handover()
1749 q6v5_pds_disable(qproc, qproc->proxy_pds, qproc->proxy_pd_count); in qcom_msa_handover()
1758 qproc->reg_base = devm_platform_ioremap_resource_byname(pdev, "qdsp6"); in q6v5_init_mem()
1759 if (IS_ERR(qproc->reg_base)) in q6v5_init_mem()
1760 return PTR_ERR(qproc->reg_base); in q6v5_init_mem()
1762 qproc->rmb_base = devm_platform_ioremap_resource_byname(pdev, "rmb"); in q6v5_init_mem()
1763 if (IS_ERR(qproc->rmb_base)) in q6v5_init_mem()
1764 return PTR_ERR(qproc->rmb_base); in q6v5_init_mem()
1766 if (qproc->has_vq6) in q6v5_init_mem()
1769 ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node, in q6v5_init_mem()
1770 "qcom,halt-regs", halt_cell_cnt, 0, &args); in q6v5_init_mem()
1772 dev_err(&pdev->dev, "failed to parse qcom,halt-regs\n"); in q6v5_init_mem()
1773 return -EINVAL; in q6v5_init_mem()
1776 qproc->halt_map = syscon_node_to_regmap(args.np); in q6v5_init_mem()
1778 if (IS_ERR(qproc->halt_map)) in q6v5_init_mem()
1779 return PTR_ERR(qproc->halt_map); in q6v5_init_mem()
1781 qproc->halt_q6 = args.args[0]; in q6v5_init_mem()
1782 qproc->halt_modem = args.args[1]; in q6v5_init_mem()
1783 qproc->halt_nc = args.args[2]; in q6v5_init_mem()
1785 if (qproc->has_vq6) in q6v5_init_mem()
1786 qproc->halt_vq6 = args.args[3]; in q6v5_init_mem()
1788 if (qproc->has_qaccept_regs) { in q6v5_init_mem()
1789 ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node, in q6v5_init_mem()
1790 "qcom,qaccept-regs", in q6v5_init_mem()
1793 dev_err(&pdev->dev, "failed to parse qaccept-regs\n"); in q6v5_init_mem()
1794 return -EINVAL; in q6v5_init_mem()
1797 qproc->qaccept_mdm = args.args[0]; in q6v5_init_mem()
1798 qproc->qaccept_cx = args.args[1]; in q6v5_init_mem()
1799 qproc->qaccept_axi = args.args[2]; in q6v5_init_mem()
1802 if (qproc->has_ext_bhs_reg) { in q6v5_init_mem()
1803 ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node, in q6v5_init_mem()
1804 "qcom,ext-bhs-reg", in q6v5_init_mem()
1807 dev_err(&pdev->dev, "failed to parse ext-bhs-reg index 0\n"); in q6v5_init_mem()
1808 return -EINVAL; in q6v5_init_mem()
1811 qproc->conn_map = syscon_node_to_regmap(args.np); in q6v5_init_mem()
1813 if (IS_ERR(qproc->conn_map)) in q6v5_init_mem()
1814 return PTR_ERR(qproc->conn_map); in q6v5_init_mem()
1816 qproc->ext_bhs = args.args[0]; in q6v5_init_mem()
1819 if (qproc->has_ext_cntl_regs) { in q6v5_init_mem()
1820 ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node, in q6v5_init_mem()
1821 "qcom,ext-regs", in q6v5_init_mem()
1824 dev_err(&pdev->dev, "failed to parse ext-regs index 0\n"); in q6v5_init_mem()
1825 return -EINVAL; in q6v5_init_mem()
1828 qproc->conn_map = syscon_node_to_regmap(args.np); in q6v5_init_mem()
1830 if (IS_ERR(qproc->conn_map)) in q6v5_init_mem()
1831 return PTR_ERR(qproc->conn_map); in q6v5_init_mem()
1833 qproc->force_clk_on = args.args[0]; in q6v5_init_mem()
1834 qproc->rscc_disable = args.args[1]; in q6v5_init_mem()
1836 ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node, in q6v5_init_mem()
1837 "qcom,ext-regs", in q6v5_init_mem()
1840 dev_err(&pdev->dev, "failed to parse ext-regs index 1\n"); in q6v5_init_mem()
1841 return -EINVAL; in q6v5_init_mem()
1844 qproc->axim1_clk_off = args.args[0]; in q6v5_init_mem()
1845 qproc->crypto_clk_off = args.args[1]; in q6v5_init_mem()
1848 if (qproc->has_spare_reg) { in q6v5_init_mem()
1849 ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node, in q6v5_init_mem()
1850 "qcom,spare-regs", in q6v5_init_mem()
1853 dev_err(&pdev->dev, "failed to parse spare-regs\n"); in q6v5_init_mem()
1854 return -EINVAL; in q6v5_init_mem()
1857 qproc->conn_map = syscon_node_to_regmap(args.np); in q6v5_init_mem()
1859 if (IS_ERR(qproc->conn_map)) in q6v5_init_mem()
1860 return PTR_ERR(qproc->conn_map); in q6v5_init_mem()
1862 qproc->conn_box = args.args[0]; in q6v5_init_mem()
1901 if (num_pds == 1 && dev->pm_domain) { in q6v5_pds_attach()
1910 ret = PTR_ERR(devs[i]) ? : -ENODATA; in q6v5_pds_attach()
1918 for (i--; i >= 0; i--) in q6v5_pds_attach()
1927 struct device *dev = qproc->dev; in q6v5_pds_detach()
1931 if (pd_count == 1 && dev->pm_domain) { in q6v5_pds_detach()
1942 qproc->mss_restart = devm_reset_control_get_exclusive(qproc->dev, in q6v5_init_reset()
1944 if (IS_ERR(qproc->mss_restart)) { in q6v5_init_reset()
1945 dev_err(qproc->dev, "failed to acquire mss restart\n"); in q6v5_init_reset()
1946 return PTR_ERR(qproc->mss_restart); in q6v5_init_reset()
1949 if (qproc->has_alt_reset || qproc->has_spare_reg || qproc->has_ext_cntl_regs) { in q6v5_init_reset()
1950 qproc->pdc_reset = devm_reset_control_get_exclusive(qproc->dev, in q6v5_init_reset()
1952 if (IS_ERR(qproc->pdc_reset)) { in q6v5_init_reset()
1953 dev_err(qproc->dev, "failed to acquire pdc reset\n"); in q6v5_init_reset()
1954 return PTR_ERR(qproc->pdc_reset); in q6v5_init_reset()
1968 * In the absence of mba/mpss sub-child, extract the mba and mpss in q6v5_alloc_memory_region()
1969 * reserved memory regions from device's memory-region property. in q6v5_alloc_memory_region()
1971 child = of_get_child_by_name(qproc->dev->of_node, "mba"); in q6v5_alloc_memory_region()
1973 node = of_parse_phandle(qproc->dev->of_node, in q6v5_alloc_memory_region()
1974 "memory-region", 0); in q6v5_alloc_memory_region()
1976 node = of_parse_phandle(child, "memory-region", 0); in q6v5_alloc_memory_region()
1981 dev_err(qproc->dev, "no mba memory-region specified\n"); in q6v5_alloc_memory_region()
1982 return -EINVAL; in q6v5_alloc_memory_region()
1988 dev_err(qproc->dev, "unable to resolve mba region\n"); in q6v5_alloc_memory_region()
1989 return -EINVAL; in q6v5_alloc_memory_region()
1992 qproc->mba_phys = rmem->base; in q6v5_alloc_memory_region()
1993 qproc->mba_size = rmem->size; in q6v5_alloc_memory_region()
1996 node = of_parse_phandle(qproc->dev->of_node, in q6v5_alloc_memory_region()
1997 "memory-region", 1); in q6v5_alloc_memory_region()
1999 child = of_get_child_by_name(qproc->dev->of_node, "mpss"); in q6v5_alloc_memory_region()
2000 node = of_parse_phandle(child, "memory-region", 0); in q6v5_alloc_memory_region()
2005 dev_err(qproc->dev, "no mpss memory-region specified\n"); in q6v5_alloc_memory_region()
2006 return -EINVAL; in q6v5_alloc_memory_region()
2012 dev_err(qproc->dev, "unable to resolve mpss region\n"); in q6v5_alloc_memory_region()
2013 return -EINVAL; in q6v5_alloc_memory_region()
2016 qproc->mpss_phys = qproc->mpss_reloc = rmem->base; in q6v5_alloc_memory_region()
2017 qproc->mpss_size = rmem->size; in q6v5_alloc_memory_region()
2020 node = of_parse_phandle(qproc->dev->of_node, "memory-region", 2); in q6v5_alloc_memory_region()
2022 child = of_get_child_by_name(qproc->dev->of_node, "metadata"); in q6v5_alloc_memory_region()
2023 node = of_parse_phandle(child, "memory-region", 0); in q6v5_alloc_memory_region()
2032 dev_err(qproc->dev, "unable to resolve metadata region\n"); in q6v5_alloc_memory_region()
2033 return -EINVAL; in q6v5_alloc_memory_region()
2036 qproc->mdata_phys = rmem->base; in q6v5_alloc_memory_region()
2037 qproc->mdata_size = rmem->size; in q6v5_alloc_memory_region()
2051 desc = of_device_get_match_data(&pdev->dev); in q6v5_probe()
2053 return -EINVAL; in q6v5_probe()
2055 if (desc->need_mem_protection && !qcom_scm_is_available()) in q6v5_probe()
2056 return -EPROBE_DEFER; in q6v5_probe()
2058 mba_image = desc->hexagon_mba_image; in q6v5_probe()
2059 ret = of_property_read_string_index(pdev->dev.of_node, "firmware-name", in q6v5_probe()
2061 if (ret < 0 && ret != -EINVAL) { in q6v5_probe()
2062 dev_err(&pdev->dev, "unable to read mba firmware-name\n"); in q6v5_probe()
2066 rproc = devm_rproc_alloc(&pdev->dev, pdev->name, &q6v5_ops, in q6v5_probe()
2069 dev_err(&pdev->dev, "failed to allocate rproc\n"); in q6v5_probe()
2070 return -ENOMEM; in q6v5_probe()
2073 rproc->auto_boot = false; in q6v5_probe()
2076 qproc = rproc->priv; in q6v5_probe()
2077 qproc->dev = &pdev->dev; in q6v5_probe()
2078 qproc->rproc = rproc; in q6v5_probe()
2079 qproc->hexagon_mdt_image = "modem.mdt"; in q6v5_probe()
2080 ret = of_property_read_string_index(pdev->dev.of_node, "firmware-name", in q6v5_probe()
2081 1, &qproc->hexagon_mdt_image); in q6v5_probe()
2082 if (ret < 0 && ret != -EINVAL) { in q6v5_probe()
2083 dev_err(&pdev->dev, "unable to read mpss firmware-name\n"); in q6v5_probe()
2089 qproc->has_qaccept_regs = desc->has_qaccept_regs; in q6v5_probe()
2090 qproc->has_ext_bhs_reg = desc->has_ext_bhs_reg; in q6v5_probe()
2091 qproc->has_ext_cntl_regs = desc->has_ext_cntl_regs; in q6v5_probe()
2092 qproc->has_vq6 = desc->has_vq6; in q6v5_probe()
2093 qproc->has_spare_reg = desc->has_spare_reg; in q6v5_probe()
2102 ret = q6v5_init_clocks(&pdev->dev, qproc->proxy_clks, in q6v5_probe()
2103 desc->proxy_clk_names); in q6v5_probe()
2106 qproc->proxy_clk_count = ret; in q6v5_probe()
2108 ret = q6v5_init_clocks(&pdev->dev, qproc->reset_clks, in q6v5_probe()
2109 desc->reset_clk_names); in q6v5_probe()
2112 qproc->reset_clk_count = ret; in q6v5_probe()
2114 ret = q6v5_init_clocks(&pdev->dev, qproc->active_clks, in q6v5_probe()
2115 desc->active_clk_names); in q6v5_probe()
2118 qproc->active_clk_count = ret; in q6v5_probe()
2120 ret = q6v5_regulator_init(&pdev->dev, qproc->proxy_regs, in q6v5_probe()
2121 desc->proxy_supply); in q6v5_probe()
2124 qproc->proxy_reg_count = ret; in q6v5_probe()
2126 ret = q6v5_regulator_init(&pdev->dev, qproc->active_regs, in q6v5_probe()
2127 desc->active_supply); in q6v5_probe()
2130 qproc->active_reg_count = ret; in q6v5_probe()
2132 ret = q6v5_pds_attach(&pdev->dev, qproc->proxy_pds, in q6v5_probe()
2133 desc->proxy_pd_names); in q6v5_probe()
2135 if (ret == -ENODATA && desc->fallback_proxy_supply) { in q6v5_probe()
2136 ret = q6v5_regulator_init(&pdev->dev, in q6v5_probe()
2137 qproc->fallback_proxy_regs, in q6v5_probe()
2138 desc->fallback_proxy_supply); in q6v5_probe()
2141 qproc->fallback_proxy_reg_count = ret; in q6v5_probe()
2143 dev_err(&pdev->dev, "Failed to init power domains\n"); in q6v5_probe()
2146 qproc->proxy_pd_count = ret; in q6v5_probe()
2149 qproc->has_alt_reset = desc->has_alt_reset; in q6v5_probe()
2154 qproc->version = desc->version; in q6v5_probe()
2155 qproc->need_mem_protection = desc->need_mem_protection; in q6v5_probe()
2156 qproc->has_mba_logs = desc->has_mba_logs; in q6v5_probe()
2158 ret = qcom_q6v5_init(&qproc->q6v5, pdev, rproc, MPSS_CRASH_REASON_SMEM, "modem", in q6v5_probe()
2163 qproc->mpss_perm = BIT(QCOM_SCM_VMID_HLOS); in q6v5_probe()
2164 qproc->mba_perm = BIT(QCOM_SCM_VMID_HLOS); in q6v5_probe()
2165 qcom_add_glink_subdev(rproc, &qproc->glink_subdev, "mpss"); in q6v5_probe()
2166 qcom_add_smd_subdev(rproc, &qproc->smd_subdev); in q6v5_probe()
2167 qcom_add_pdm_subdev(rproc, &qproc->pdm_subdev); in q6v5_probe()
2168 qcom_add_ssr_subdev(rproc, &qproc->ssr_subdev, "mpss"); in q6v5_probe()
2169 qproc->sysmon = qcom_add_sysmon_subdev(rproc, "modem", 0x12); in q6v5_probe()
2170 if (IS_ERR(qproc->sysmon)) { in q6v5_probe()
2171 ret = PTR_ERR(qproc->sysmon); in q6v5_probe()
2179 node = of_get_compatible_child(pdev->dev.of_node, "qcom,bam-dmux"); in q6v5_probe()
2180 qproc->bam_dmux = of_platform_device_create(node, NULL, &pdev->dev); in q6v5_probe()
2186 qcom_remove_sysmon_subdev(qproc->sysmon); in q6v5_probe()
2188 qcom_remove_ssr_subdev(rproc, &qproc->ssr_subdev); in q6v5_probe()
2189 qcom_remove_smd_subdev(rproc, &qproc->smd_subdev); in q6v5_probe()
2190 qcom_remove_glink_subdev(rproc, &qproc->glink_subdev); in q6v5_probe()
2192 q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count); in q6v5_probe()
2200 struct rproc *rproc = qproc->rproc; in q6v5_remove()
2202 if (qproc->bam_dmux) in q6v5_remove()
2203 of_platform_device_destroy(&qproc->bam_dmux->dev, NULL); in q6v5_remove()
2206 qcom_q6v5_deinit(&qproc->q6v5); in q6v5_remove()
2207 qcom_remove_sysmon_subdev(qproc->sysmon); in q6v5_remove()
2208 qcom_remove_ssr_subdev(rproc, &qproc->ssr_subdev); in q6v5_remove()
2209 qcom_remove_pdm_subdev(rproc, &qproc->pdm_subdev); in q6v5_remove()
2210 qcom_remove_smd_subdev(rproc, &qproc->smd_subdev); in q6v5_remove()
2211 qcom_remove_glink_subdev(rproc, &qproc->glink_subdev); in q6v5_remove()
2213 q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count); in q6v5_remove()
2673 { .compatible = "qcom,q6v5-pil", .data = &msm8916_mss},
2674 { .compatible = "qcom,msm8226-mss-pil", .data = &msm8226_mss},
2675 { .compatible = "qcom,msm8909-mss-pil", .data = &msm8909_mss},
2676 { .compatible = "qcom,msm8916-mss-pil", .data = &msm8916_mss},
2677 { .compatible = "qcom,msm8926-mss-pil", .data = &msm8926_mss},
2678 { .compatible = "qcom,msm8953-mss-pil", .data = &msm8953_mss},
2679 { .compatible = "qcom,msm8974-mss-pil", .data = &msm8974_mss},
2680 { .compatible = "qcom,msm8996-mss-pil", .data = &msm8996_mss},
2681 { .compatible = "qcom,msm8998-mss-pil", .data = &msm8998_mss},
2682 { .compatible = "qcom,sc7180-mss-pil", .data = &sc7180_mss},
2683 { .compatible = "qcom,sc7280-mss-pil", .data = &sc7280_mss},
2684 { .compatible = "qcom,sdm660-mss-pil", .data = &sdm660_mss},
2685 { .compatible = "qcom,sdm845-mss-pil", .data = &sdm845_mss},
2694 .name = "qcom-q6v5-mss",
2700 MODULE_DESCRIPTION("Qualcomm Self-authenticating modem remoteproc driver");