Lines Matching +full:sc7180 +full:- +full:mss

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>
273 if (rc != -EPROBE_DEFER) in q6v5_regulator_init()
297 dev_err(qproc->dev, in q6v5_regulator_enable()
308 dev_err(qproc->dev, in q6v5_regulator_enable()
316 dev_err(qproc->dev, "Regulator enable failed\n"); in q6v5_regulator_enable()
323 for (; i >= 0; i--) { in q6v5_regulator_enable()
368 for (i--; i >= 0; i--) in q6v5_clk_enable()
402 for (i--; i >= 0; i--) { in q6v5_pds_enable()
428 if (!qproc->need_mem_protection) in q6v5_xfer_mem_ownership()
455 if (request_firmware_direct(&dp_fw, "msadp", qproc->dev)) in q6v5_debug_policy_load()
458 if (SZ_1M + dp_fw->size <= qproc->mba_size) { in q6v5_debug_policy_load()
459 memcpy(mba_region + SZ_1M, dp_fw->data, dp_fw->size); in q6v5_debug_policy_load()
460 qproc->dp_size = dp_fw->size; in q6v5_debug_policy_load()
468 struct q6v5 *qproc = rproc->priv; in q6v5_load()
472 if (fw->size > qproc->mba_size || fw->size > SZ_1M) { in q6v5_load()
473 dev_err(qproc->dev, "MBA firmware load failed\n"); in q6v5_load()
474 return -EINVAL; in q6v5_load()
477 mba_region = memremap(qproc->mba_phys, qproc->mba_size, MEMREMAP_WC); in q6v5_load()
479 dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n", in q6v5_load()
480 &qproc->mba_phys, qproc->mba_size); in q6v5_load()
481 return -EBUSY; in q6v5_load()
484 memcpy(mba_region, fw->data, fw->size); in q6v5_load()
495 if (qproc->has_alt_reset) { in q6v5_reset_assert()
496 reset_control_assert(qproc->pdc_reset); in q6v5_reset_assert()
497 ret = reset_control_reset(qproc->mss_restart); in q6v5_reset_assert()
498 reset_control_deassert(qproc->pdc_reset); in q6v5_reset_assert()
499 } else if (qproc->has_spare_reg) { in q6v5_reset_assert()
505 * BIT before triggering Q6 MSS reset. AXI_GATING_VALID_OVERRIDE in q6v5_reset_assert()
506 * is withdrawn post MSS assert followed by a MSS deassert, in q6v5_reset_assert()
509 reset_control_assert(qproc->pdc_reset); in q6v5_reset_assert()
510 regmap_update_bits(qproc->conn_map, qproc->conn_box, in q6v5_reset_assert()
512 reset_control_assert(qproc->mss_restart); in q6v5_reset_assert()
513 reset_control_deassert(qproc->pdc_reset); in q6v5_reset_assert()
514 regmap_update_bits(qproc->conn_map, qproc->conn_box, in q6v5_reset_assert()
516 ret = reset_control_deassert(qproc->mss_restart); in q6v5_reset_assert()
517 } else if (qproc->has_ext_cntl_regs) { in q6v5_reset_assert()
518 regmap_write(qproc->conn_map, qproc->rscc_disable, 0); in q6v5_reset_assert()
519 reset_control_assert(qproc->pdc_reset); in q6v5_reset_assert()
520 reset_control_assert(qproc->mss_restart); in q6v5_reset_assert()
521 reset_control_deassert(qproc->pdc_reset); in q6v5_reset_assert()
522 ret = reset_control_deassert(qproc->mss_restart); in q6v5_reset_assert()
524 ret = reset_control_assert(qproc->mss_restart); in q6v5_reset_assert()
534 if (qproc->has_alt_reset) { in q6v5_reset_deassert()
535 reset_control_assert(qproc->pdc_reset); in q6v5_reset_deassert()
536 writel(1, qproc->rmb_base + RMB_MBA_ALT_RESET); in q6v5_reset_deassert()
537 ret = reset_control_reset(qproc->mss_restart); in q6v5_reset_deassert()
538 writel(0, qproc->rmb_base + RMB_MBA_ALT_RESET); in q6v5_reset_deassert()
539 reset_control_deassert(qproc->pdc_reset); in q6v5_reset_deassert()
540 } else if (qproc->has_spare_reg || qproc->has_ext_cntl_regs) { in q6v5_reset_deassert()
541 ret = reset_control_reset(qproc->mss_restart); in q6v5_reset_deassert()
543 ret = reset_control_deassert(qproc->mss_restart); in q6v5_reset_deassert()
556 val = readl(qproc->rmb_base + RMB_PBL_STATUS_REG); in q6v5_rmb_pbl_wait()
561 return -ETIMEDOUT; in q6v5_rmb_pbl_wait()
577 val = readl(qproc->rmb_base + RMB_MBA_STATUS_REG); in q6v5_rmb_mba_wait()
587 return -ETIMEDOUT; in q6v5_rmb_mba_wait()
597 struct rproc *rproc = qproc->rproc; in q6v5_dump_mba_logs()
601 if (!qproc->has_mba_logs) in q6v5_dump_mba_logs()
604 if (q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true, false, qproc->mba_phys, in q6v5_dump_mba_logs()
605 qproc->mba_size)) in q6v5_dump_mba_logs()
608 mba_region = memremap(qproc->mba_phys, qproc->mba_size, MEMREMAP_WC); in q6v5_dump_mba_logs()
615 dev_coredumpv(&rproc->dev, data, MBA_LOG_SIZE, GFP_KERNEL); in q6v5_dump_mba_logs()
626 if (qproc->version == MSS_SDM845) { in q6v5proc_reset()
627 val = readl(qproc->reg_base + QDSP6SS_SLEEP); in q6v5proc_reset()
629 writel(val, qproc->reg_base + QDSP6SS_SLEEP); in q6v5proc_reset()
631 ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_SLEEP, in q6v5proc_reset()
635 dev_err(qproc->dev, "QDSP6SS Sleep clock timed out\n"); in q6v5proc_reset()
636 return -ETIMEDOUT; in q6v5proc_reset()
639 /* De-assert QDSP6 stop core */ in q6v5proc_reset()
640 writel(1, qproc->reg_base + QDSP6SS_BOOT_CORE_START); in q6v5proc_reset()
642 writel(1, qproc->reg_base + QDSP6SS_BOOT_CMD); in q6v5proc_reset()
644 ret = readl_poll_timeout(qproc->rmb_base + RMB_MBA_MSS_STATUS, in q6v5proc_reset()
647 dev_err(qproc->dev, "Boot FSM failed to complete.\n"); in q6v5proc_reset()
654 } else if (qproc->version == MSS_SC7180 || qproc->version == MSS_SC7280) { in q6v5proc_reset()
655 val = readl(qproc->reg_base + QDSP6SS_SLEEP); in q6v5proc_reset()
657 writel(val, qproc->reg_base + QDSP6SS_SLEEP); in q6v5proc_reset()
659 ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_SLEEP, in q6v5proc_reset()
663 dev_err(qproc->dev, "QDSP6SS Sleep clock timed out\n"); in q6v5proc_reset()
664 return -ETIMEDOUT; in q6v5proc_reset()
668 val = readl(qproc->reg_base + QDSP6SS_XO_CBCR); in q6v5proc_reset()
670 writel(val, qproc->reg_base + QDSP6SS_XO_CBCR); in q6v5proc_reset()
672 ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_XO_CBCR, in q6v5proc_reset()
676 dev_err(qproc->dev, "QDSP6SS XO clock timed out\n"); in q6v5proc_reset()
677 return -ETIMEDOUT; in q6v5proc_reset()
680 /* Configure Q6 core CBCR to auto-enable after reset sequence */ in q6v5proc_reset()
681 val = readl(qproc->reg_base + QDSP6SS_CORE_CBCR); in q6v5proc_reset()
683 writel(val, qproc->reg_base + QDSP6SS_CORE_CBCR); in q6v5proc_reset()
685 /* De-assert the Q6 stop core signal */ in q6v5proc_reset()
686 writel(1, qproc->reg_base + QDSP6SS_BOOT_CORE_START); in q6v5proc_reset()
691 /* Trigger the boot FSM to start the Q6 out-of-reset sequence */ in q6v5proc_reset()
692 writel(1, qproc->reg_base + QDSP6SS_BOOT_CMD); in q6v5proc_reset()
695 ret = readl_poll_timeout(qproc->rmb_base + RMB_MBA_MSS_STATUS, in q6v5proc_reset()
698 dev_err(qproc->dev, "Boot FSM failed to complete.\n"); in q6v5proc_reset()
704 } else if (qproc->version == MSS_MSM8909 || in q6v5proc_reset()
705 qproc->version == MSS_MSM8953 || in q6v5proc_reset()
706 qproc->version == MSS_MSM8996 || in q6v5proc_reset()
707 qproc->version == MSS_MSM8998 || in q6v5proc_reset()
708 qproc->version == MSS_SDM660) { in q6v5proc_reset()
710 if (qproc->version != MSS_MSM8909 && in q6v5proc_reset()
711 qproc->version != MSS_MSM8953) in q6v5proc_reset()
714 qproc->reg_base + QDSP6SS_STRAP_ACC); in q6v5proc_reset()
717 val = readl(qproc->reg_base + QDSP6SS_RESET_REG); in q6v5proc_reset()
719 writel(val, qproc->reg_base + QDSP6SS_RESET_REG); in q6v5proc_reset()
722 val = readl(qproc->reg_base + QDSP6SS_XO_CBCR); in q6v5proc_reset()
724 writel(val, qproc->reg_base + QDSP6SS_XO_CBCR); in q6v5proc_reset()
727 ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_XO_CBCR, in q6v5proc_reset()
731 dev_err(qproc->dev, in q6v5proc_reset()
736 val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
738 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
739 val |= readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
742 if (qproc->version == MSS_SDM660) { in q6v5proc_reset()
743 ret = readl_relaxed_poll_timeout(qproc->reg_base + QDSP6V62SS_BHS_STATUS, in q6v5proc_reset()
746 if (ret == -ETIMEDOUT) { in q6v5proc_reset()
747 dev_err(qproc->dev, "BHS_EN_REST_ACK not set!\n"); in q6v5proc_reset()
748 return -ETIMEDOUT; in q6v5proc_reset()
754 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
756 if (qproc->version != MSS_MSM8909) { in q6v5proc_reset()
760 val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
762 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
766 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
769 if (qproc->version == MSS_MSM8953 || in q6v5proc_reset()
770 qproc->version == MSS_MSM8996) { in q6v5proc_reset()
778 val = readl(qproc->reg_base + mem_pwr_ctl); in q6v5proc_reset()
779 for (; i >= 0; i--) { in q6v5proc_reset()
781 writel(val, qproc->reg_base + mem_pwr_ctl); in q6v5proc_reset()
787 val |= readl(qproc->reg_base + mem_pwr_ctl); in q6v5proc_reset()
792 val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
795 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
800 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
805 val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
807 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
810 val = readl(qproc->reg_base + QDSP6SS_RESET_REG); in q6v5proc_reset()
812 writel(val, qproc->reg_base + QDSP6SS_RESET_REG); in q6v5proc_reset()
815 val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
817 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
818 val |= readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
824 val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
827 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
829 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
831 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
833 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
837 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5proc_reset()
840 val = readl(qproc->reg_base + QDSP6SS_RESET_REG); in q6v5proc_reset()
842 writel(val, qproc->reg_base + QDSP6SS_RESET_REG); in q6v5proc_reset()
845 val = readl(qproc->reg_base + QDSP6SS_GFMUX_CTL_REG); in q6v5proc_reset()
847 writel(val, qproc->reg_base + QDSP6SS_GFMUX_CTL_REG); in q6v5proc_reset()
850 val = readl(qproc->reg_base + QDSP6SS_RESET_REG); in q6v5proc_reset()
852 writel(val, qproc->reg_base + QDSP6SS_RESET_REG); in q6v5proc_reset()
857 if (ret == -ETIMEDOUT) { in q6v5proc_reset()
858 dev_err(qproc->dev, "PBL boot timed out\n"); in q6v5proc_reset()
860 dev_err(qproc->dev, "PBL returned unexpected status %d\n", ret); in q6v5proc_reset()
861 ret = -EINVAL; in q6v5proc_reset()
874 if (!qproc->has_qaccept_regs) in q6v5proc_enable_qchannel()
877 if (qproc->has_ext_cntl_regs) { in q6v5proc_enable_qchannel()
878 regmap_write(qproc->conn_map, qproc->rscc_disable, 0); in q6v5proc_enable_qchannel()
879 regmap_write(qproc->conn_map, qproc->force_clk_on, 1); in q6v5proc_enable_qchannel()
881 ret = regmap_read_poll_timeout(qproc->halt_map, qproc->axim1_clk_off, val, in q6v5proc_enable_qchannel()
884 dev_err(qproc->dev, "failed to enable axim1 clock\n"); in q6v5proc_enable_qchannel()
885 return -ETIMEDOUT; in q6v5proc_enable_qchannel()
895 dev_err(qproc->dev, "qchannel enable failed\n"); in q6v5proc_enable_qchannel()
896 return -ETIMEDOUT; in q6v5proc_enable_qchannel()
909 if (!qproc->has_qaccept_regs) in q6v5proc_disable_qchannel()
913 nretry--; in q6v5proc_disable_qchannel()
919 /* Request Q-channel transaction takedown */ in q6v5proc_disable_qchannel()
923 * If the request is denied, reset the Q-channel takedown request, in q6v5proc_disable_qchannel()
929 retry--; in q6v5proc_disable_qchannel()
949 dev_err(qproc->dev, "qchannel takedown failed\n"); in q6v5proc_disable_qchannel()
973 dev_err(qproc->dev, "port failed halt\n"); in q6v5proc_halt_axi_port()
991 metadata = qcom_mdt_read_metadata(fw, &size, fw_name, qproc->dev); in q6v5_mpss_init_image()
995 if (qproc->mdata_phys) { in q6v5_mpss_init_image()
996 if (size > qproc->mdata_size) { in q6v5_mpss_init_image()
997 ret = -EINVAL; in q6v5_mpss_init_image()
998 dev_err(qproc->dev, "metadata size outside memory range\n"); in q6v5_mpss_init_image()
1002 phys = qproc->mdata_phys; in q6v5_mpss_init_image()
1003 ptr = memremap(qproc->mdata_phys, size, MEMREMAP_WC); in q6v5_mpss_init_image()
1005 ret = -EBUSY; in q6v5_mpss_init_image()
1006 dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n", in q6v5_mpss_init_image()
1007 &qproc->mdata_phys, size); in q6v5_mpss_init_image()
1011 ptr = dma_alloc_attrs(qproc->dev, size, &phys, GFP_KERNEL, dma_attrs); in q6v5_mpss_init_image()
1013 ret = -ENOMEM; in q6v5_mpss_init_image()
1014 dev_err(qproc->dev, "failed to allocate mdt buffer\n"); in q6v5_mpss_init_image()
1021 if (qproc->mdata_phys) in q6v5_mpss_init_image()
1029 dev_err(qproc->dev, in q6v5_mpss_init_image()
1031 ret = -EAGAIN; in q6v5_mpss_init_image()
1035 writel(phys, qproc->rmb_base + RMB_PMI_META_DATA_REG); in q6v5_mpss_init_image()
1036 writel(RMB_CMD_META_DATA_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG); in q6v5_mpss_init_image()
1039 if (ret == -ETIMEDOUT) in q6v5_mpss_init_image()
1040 dev_err(qproc->dev, "MPSS header authentication timed out\n"); in q6v5_mpss_init_image()
1042 dev_err(qproc->dev, "MPSS header authentication failed: %d\n", ret); in q6v5_mpss_init_image()
1048 dev_warn(qproc->dev, in q6v5_mpss_init_image()
1052 if (!qproc->mdata_phys) in q6v5_mpss_init_image()
1053 dma_free_attrs(qproc->dev, size, ptr, phys, dma_attrs); in q6v5_mpss_init_image()
1062 if (phdr->p_type != PT_LOAD) in q6v5_phdr_valid()
1065 if ((phdr->p_flags & QCOM_MDT_TYPE_MASK) == QCOM_MDT_TYPE_HASH) in q6v5_phdr_valid()
1068 if (!phdr->p_memsz) in q6v5_phdr_valid()
1080 ret = qcom_q6v5_prepare(&qproc->q6v5); in q6v5_mba_load()
1084 ret = q6v5_pds_enable(qproc, qproc->proxy_pds, qproc->proxy_pd_count); in q6v5_mba_load()
1086 dev_err(qproc->dev, "failed to enable proxy power domains\n"); in q6v5_mba_load()
1090 ret = q6v5_regulator_enable(qproc, qproc->fallback_proxy_regs, in q6v5_mba_load()
1091 qproc->fallback_proxy_reg_count); in q6v5_mba_load()
1093 dev_err(qproc->dev, "failed to enable fallback proxy supplies\n"); in q6v5_mba_load()
1097 ret = q6v5_regulator_enable(qproc, qproc->proxy_regs, in q6v5_mba_load()
1098 qproc->proxy_reg_count); in q6v5_mba_load()
1100 dev_err(qproc->dev, "failed to enable proxy supplies\n"); in q6v5_mba_load()
1104 ret = q6v5_clk_enable(qproc->dev, qproc->proxy_clks, in q6v5_mba_load()
1105 qproc->proxy_clk_count); in q6v5_mba_load()
1107 dev_err(qproc->dev, "failed to enable proxy clocks\n"); in q6v5_mba_load()
1111 ret = q6v5_regulator_enable(qproc, qproc->active_regs, in q6v5_mba_load()
1112 qproc->active_reg_count); in q6v5_mba_load()
1114 dev_err(qproc->dev, "failed to enable supplies\n"); in q6v5_mba_load()
1118 ret = q6v5_clk_enable(qproc->dev, qproc->reset_clks, in q6v5_mba_load()
1119 qproc->reset_clk_count); in q6v5_mba_load()
1121 dev_err(qproc->dev, "failed to enable reset clocks\n"); in q6v5_mba_load()
1127 dev_err(qproc->dev, "failed to deassert mss restart\n"); in q6v5_mba_load()
1131 ret = q6v5_clk_enable(qproc->dev, qproc->active_clks, in q6v5_mba_load()
1132 qproc->active_clk_count); in q6v5_mba_load()
1134 dev_err(qproc->dev, "failed to enable clocks\n"); in q6v5_mba_load()
1138 ret = q6v5proc_enable_qchannel(qproc, qproc->halt_map, qproc->qaccept_axi); in q6v5_mba_load()
1140 dev_err(qproc->dev, "failed to enable axi bridge\n"); in q6v5_mba_load()
1148 ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, false, true, in q6v5_mba_load()
1149 qproc->mpss_phys, qproc->mpss_size); in q6v5_mba_load()
1151 dev_err(qproc->dev, "assigning Q6 access to mpss memory failed: %d\n", ret); in q6v5_mba_load()
1156 ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, false, true, in q6v5_mba_load()
1157 qproc->mba_phys, qproc->mba_size); in q6v5_mba_load()
1159 dev_err(qproc->dev, in q6v5_mba_load()
1164 if (qproc->has_mba_logs) in q6v5_mba_load()
1165 qcom_pil_info_store("mba", qproc->mba_phys, MBA_LOG_SIZE); in q6v5_mba_load()
1167 writel(qproc->mba_phys, qproc->rmb_base + RMB_MBA_IMAGE_REG); in q6v5_mba_load()
1168 if (qproc->dp_size) { in q6v5_mba_load()
1169 writel(qproc->mba_phys + SZ_1M, qproc->rmb_base + RMB_PMI_CODE_START_REG); in q6v5_mba_load()
1170 writel(qproc->dp_size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG); in q6v5_mba_load()
1178 if (ret == -ETIMEDOUT) { in q6v5_mba_load()
1179 dev_err(qproc->dev, "MBA boot timed out\n"); in q6v5_mba_load()
1183 dev_err(qproc->dev, "MBA returned unexpected status %d\n", ret); in q6v5_mba_load()
1184 ret = -EINVAL; in q6v5_mba_load()
1188 qproc->dump_mba_loaded = true; in q6v5_mba_load()
1192 q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6); in q6v5_mba_load()
1193 if (qproc->has_vq6) in q6v5_mba_load()
1194 q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_vq6); in q6v5_mba_load()
1195 q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem); in q6v5_mba_load()
1196 q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc); in q6v5_mba_load()
1197 q6v5proc_disable_qchannel(qproc, qproc->halt_map, qproc->qaccept_mdm); in q6v5_mba_load()
1198 q6v5proc_disable_qchannel(qproc, qproc->halt_map, qproc->qaccept_cx); in q6v5_mba_load()
1199 q6v5proc_disable_qchannel(qproc, qproc->halt_map, qproc->qaccept_axi); in q6v5_mba_load()
1202 xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true, in q6v5_mba_load()
1203 false, qproc->mba_phys, in q6v5_mba_load()
1204 qproc->mba_size); in q6v5_mba_load()
1206 dev_err(qproc->dev, in q6v5_mba_load()
1213 q6v5_clk_disable(qproc->dev, qproc->active_clks, in q6v5_mba_load()
1214 qproc->active_clk_count); in q6v5_mba_load()
1218 q6v5_clk_disable(qproc->dev, qproc->reset_clks, in q6v5_mba_load()
1219 qproc->reset_clk_count); in q6v5_mba_load()
1221 q6v5_regulator_disable(qproc, qproc->active_regs, in q6v5_mba_load()
1222 qproc->active_reg_count); in q6v5_mba_load()
1224 q6v5_clk_disable(qproc->dev, qproc->proxy_clks, in q6v5_mba_load()
1225 qproc->proxy_clk_count); in q6v5_mba_load()
1227 q6v5_regulator_disable(qproc, qproc->proxy_regs, in q6v5_mba_load()
1228 qproc->proxy_reg_count); in q6v5_mba_load()
1230 q6v5_regulator_disable(qproc, qproc->fallback_proxy_regs, in q6v5_mba_load()
1231 qproc->fallback_proxy_reg_count); in q6v5_mba_load()
1233 q6v5_pds_disable(qproc, qproc->proxy_pds, qproc->proxy_pd_count); in q6v5_mba_load()
1235 qcom_q6v5_unprepare(&qproc->q6v5); in q6v5_mba_load()
1245 qproc->dump_mba_loaded = false; in q6v5_mba_reclaim()
1246 qproc->dp_size = 0; in q6v5_mba_reclaim()
1248 q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6); in q6v5_mba_reclaim()
1249 if (qproc->has_vq6) in q6v5_mba_reclaim()
1250 q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_vq6); in q6v5_mba_reclaim()
1251 q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem); in q6v5_mba_reclaim()
1252 q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc); in q6v5_mba_reclaim()
1253 if (qproc->version == MSS_MSM8996) { in q6v5_mba_reclaim()
1255 * To avoid high MX current during LPASS/MSS restart. in q6v5_mba_reclaim()
1257 val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5_mba_reclaim()
1260 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); in q6v5_mba_reclaim()
1263 if (qproc->has_ext_cntl_regs) { in q6v5_mba_reclaim()
1264 regmap_write(qproc->conn_map, qproc->rscc_disable, 1); in q6v5_mba_reclaim()
1266 ret = regmap_read_poll_timeout(qproc->halt_map, qproc->axim1_clk_off, val, in q6v5_mba_reclaim()
1269 dev_err(qproc->dev, "failed to enable axim1 clock\n"); in q6v5_mba_reclaim()
1271 ret = regmap_read_poll_timeout(qproc->halt_map, qproc->crypto_clk_off, val, in q6v5_mba_reclaim()
1274 dev_err(qproc->dev, "failed to enable crypto clock\n"); in q6v5_mba_reclaim()
1277 q6v5proc_disable_qchannel(qproc, qproc->halt_map, qproc->qaccept_mdm); in q6v5_mba_reclaim()
1278 q6v5proc_disable_qchannel(qproc, qproc->halt_map, qproc->qaccept_cx); in q6v5_mba_reclaim()
1279 q6v5proc_disable_qchannel(qproc, qproc->halt_map, qproc->qaccept_axi); in q6v5_mba_reclaim()
1283 q6v5_clk_disable(qproc->dev, qproc->reset_clks, in q6v5_mba_reclaim()
1284 qproc->reset_clk_count); in q6v5_mba_reclaim()
1285 q6v5_clk_disable(qproc->dev, qproc->active_clks, in q6v5_mba_reclaim()
1286 qproc->active_clk_count); in q6v5_mba_reclaim()
1287 q6v5_regulator_disable(qproc, qproc->active_regs, in q6v5_mba_reclaim()
1288 qproc->active_reg_count); in q6v5_mba_reclaim()
1293 ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true, false, in q6v5_mba_reclaim()
1294 qproc->mba_phys, in q6v5_mba_reclaim()
1295 qproc->mba_size); in q6v5_mba_reclaim()
1298 ret = qcom_q6v5_unprepare(&qproc->q6v5); in q6v5_mba_reclaim()
1300 q6v5_pds_disable(qproc, qproc->proxy_pds, in q6v5_mba_reclaim()
1301 qproc->proxy_pd_count); in q6v5_mba_reclaim()
1302 q6v5_clk_disable(qproc->dev, qproc->proxy_clks, in q6v5_mba_reclaim()
1303 qproc->proxy_clk_count); in q6v5_mba_reclaim()
1304 q6v5_regulator_disable(qproc, qproc->fallback_proxy_regs, in q6v5_mba_reclaim()
1305 qproc->fallback_proxy_reg_count); in q6v5_mba_reclaim()
1306 q6v5_regulator_disable(qproc, qproc->proxy_regs, in q6v5_mba_reclaim()
1307 qproc->proxy_reg_count); in q6v5_mba_reclaim()
1313 struct q6v5 *qproc = rproc->priv; in q6v5_reload_mba()
1317 ret = request_firmware(&fw, rproc->firmware, qproc->dev); in q6v5_reload_mba()
1349 fw_name_len = strlen(qproc->hexagon_mdt_image); in q6v5_mpss_load()
1351 return -EINVAL; in q6v5_mpss_load()
1353 fw_name = kstrdup(qproc->hexagon_mdt_image, GFP_KERNEL); in q6v5_mpss_load()
1355 return -ENOMEM; in q6v5_mpss_load()
1357 ret = request_firmware(&fw, fw_name, qproc->dev); in q6v5_mpss_load()
1359 dev_err(qproc->dev, "unable to load %s\n", fw_name); in q6v5_mpss_load()
1364 writel(0, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG); in q6v5_mpss_load()
1366 ret = q6v5_mpss_init_image(qproc, fw, qproc->hexagon_mdt_image); in q6v5_mpss_load()
1370 ehdr = (struct elf32_hdr *)fw->data; in q6v5_mpss_load()
1373 for (i = 0; i < ehdr->e_phnum; i++) { in q6v5_mpss_load()
1379 if (phdr->p_flags & QCOM_MDT_RELOCATABLE) in q6v5_mpss_load()
1382 if (phdr->p_paddr < min_addr) in q6v5_mpss_load()
1383 min_addr = phdr->p_paddr; in q6v5_mpss_load()
1385 if (phdr->p_paddr + phdr->p_memsz > max_addr) in q6v5_mpss_load()
1386 max_addr = ALIGN(phdr->p_paddr + phdr->p_memsz, SZ_4K); in q6v5_mpss_load()
1389 if (qproc->version == MSS_MSM8953) { in q6v5_mpss_load()
1390 ret = qcom_scm_pas_mem_setup(MPSS_PAS_ID, qproc->mpss_phys, qproc->mpss_size); in q6v5_mpss_load()
1392 dev_err(qproc->dev, in q6v5_mpss_load()
1402 q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, true, false, in q6v5_mpss_load()
1403 qproc->mpss_phys, qproc->mpss_size); in q6v5_mpss_load()
1405 /* Share ownership between Linux and MSS, during segment loading */ in q6v5_mpss_load()
1406 ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, true, true, in q6v5_mpss_load()
1407 qproc->mpss_phys, qproc->mpss_size); in q6v5_mpss_load()
1409 dev_err(qproc->dev, in q6v5_mpss_load()
1411 ret = -EAGAIN; in q6v5_mpss_load()
1415 mpss_reloc = relocate ? min_addr : qproc->mpss_phys; in q6v5_mpss_load()
1416 qproc->mpss_reloc = mpss_reloc; in q6v5_mpss_load()
1418 for (i = 0; i < ehdr->e_phnum; i++) { in q6v5_mpss_load()
1424 offset = phdr->p_paddr - mpss_reloc; in q6v5_mpss_load()
1425 if (offset < 0 || offset + phdr->p_memsz > qproc->mpss_size) { in q6v5_mpss_load()
1426 dev_err(qproc->dev, "segment outside memory range\n"); in q6v5_mpss_load()
1427 ret = -EINVAL; in q6v5_mpss_load()
1431 if (phdr->p_filesz > phdr->p_memsz) { in q6v5_mpss_load()
1432 dev_err(qproc->dev, in q6v5_mpss_load()
1435 ret = -EINVAL; in q6v5_mpss_load()
1439 ptr = memremap(qproc->mpss_phys + offset, phdr->p_memsz, MEMREMAP_WC); in q6v5_mpss_load()
1441 dev_err(qproc->dev, in q6v5_mpss_load()
1442 "unable to map memory region: %pa+%zx-%x\n", in q6v5_mpss_load()
1443 &qproc->mpss_phys, offset, phdr->p_memsz); in q6v5_mpss_load()
1447 if (phdr->p_filesz && phdr->p_offset < fw->size) { in q6v5_mpss_load()
1448 /* Firmware is large enough to be non-split */ in q6v5_mpss_load()
1449 if (phdr->p_offset + phdr->p_filesz > fw->size) { in q6v5_mpss_load()
1450 dev_err(qproc->dev, in q6v5_mpss_load()
1453 ret = -EINVAL; in q6v5_mpss_load()
1458 memcpy(ptr, fw->data + phdr->p_offset, phdr->p_filesz); in q6v5_mpss_load()
1459 } else if (phdr->p_filesz) { in q6v5_mpss_load()
1461 sprintf(fw_name + fw_name_len - 3, "b%02d", i); in q6v5_mpss_load()
1462 ret = request_firmware_into_buf(&seg_fw, fw_name, qproc->dev, in q6v5_mpss_load()
1463 ptr, phdr->p_filesz); in q6v5_mpss_load()
1465 dev_err(qproc->dev, "failed to load %s\n", fw_name); in q6v5_mpss_load()
1470 if (seg_fw->size != phdr->p_filesz) { in q6v5_mpss_load()
1471 dev_err(qproc->dev, in q6v5_mpss_load()
1474 ret = -EINVAL; in q6v5_mpss_load()
1483 if (phdr->p_memsz > phdr->p_filesz) { in q6v5_mpss_load()
1484 memset(ptr + phdr->p_filesz, 0, in q6v5_mpss_load()
1485 phdr->p_memsz - phdr->p_filesz); in q6v5_mpss_load()
1488 size += phdr->p_memsz; in q6v5_mpss_load()
1490 code_length = readl(qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG); in q6v5_mpss_load()
1492 boot_addr = relocate ? qproc->mpss_phys : min_addr; in q6v5_mpss_load()
1493 writel(boot_addr, qproc->rmb_base + RMB_PMI_CODE_START_REG); in q6v5_mpss_load()
1494 writel(RMB_CMD_LOAD_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG); in q6v5_mpss_load()
1496 writel(size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG); in q6v5_mpss_load()
1498 ret = readl(qproc->rmb_base + RMB_MBA_STATUS_REG); in q6v5_mpss_load()
1500 dev_err(qproc->dev, "MPSS authentication failed: %d\n", in q6v5_mpss_load()
1507 ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, false, true, in q6v5_mpss_load()
1508 qproc->mpss_phys, qproc->mpss_size); in q6v5_mpss_load()
1510 dev_err(qproc->dev, in q6v5_mpss_load()
1512 ret = -EAGAIN; in q6v5_mpss_load()
1517 if (ret == -ETIMEDOUT) in q6v5_mpss_load()
1518 dev_err(qproc->dev, "MPSS authentication timed out\n"); in q6v5_mpss_load()
1520 dev_err(qproc->dev, "MPSS authentication failed: %d\n", ret); in q6v5_mpss_load()
1522 qcom_pil_info_store("modem", qproc->mpss_phys, qproc->mpss_size); in q6v5_mpss_load()
1537 struct q6v5 *qproc = rproc->priv; in qcom_q6v5_dump_segment()
1538 int offset = segment->da - qproc->mpss_reloc; in qcom_q6v5_dump_segment()
1542 if (!qproc->dump_mba_loaded) { in qcom_q6v5_dump_segment()
1546 ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, in qcom_q6v5_dump_segment()
1548 qproc->mpss_phys, in qcom_q6v5_dump_segment()
1549 qproc->mpss_size); in qcom_q6v5_dump_segment()
1554 ptr = memremap(qproc->mpss_phys + offset + cp_offset, size, MEMREMAP_WC); in qcom_q6v5_dump_segment()
1563 qproc->current_dump_size += size; in qcom_q6v5_dump_segment()
1566 if (qproc->current_dump_size == qproc->total_dump_size) { in qcom_q6v5_dump_segment()
1567 if (qproc->dump_mba_loaded) { in qcom_q6v5_dump_segment()
1569 q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, in qcom_q6v5_dump_segment()
1571 qproc->mpss_phys, in qcom_q6v5_dump_segment()
1572 qproc->mpss_size); in qcom_q6v5_dump_segment()
1580 struct q6v5 *qproc = rproc->priv; in q6v5_start()
1588 dev_info(qproc->dev, "MBA booted with%s debug policy, loading mpss\n", in q6v5_start()
1589 qproc->dp_size ? "" : "out"); in q6v5_start()
1595 ret = qcom_q6v5_wait_for_start(&qproc->q6v5, msecs_to_jiffies(5000)); in q6v5_start()
1596 if (ret == -ETIMEDOUT) { in q6v5_start()
1597 dev_err(qproc->dev, "start timed out\n"); in q6v5_start()
1601 xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true, in q6v5_start()
1602 false, qproc->mba_phys, in q6v5_start()
1603 qproc->mba_size); in q6v5_start()
1605 dev_err(qproc->dev, in q6v5_start()
1609 qproc->current_dump_size = 0; in q6v5_start()
1622 struct q6v5 *qproc = rproc->priv; in q6v5_stop()
1625 ret = qcom_q6v5_request_stop(&qproc->q6v5, qproc->sysmon); in q6v5_stop()
1626 if (ret == -ETIMEDOUT) in q6v5_stop()
1627 dev_err(qproc->dev, "timed out on wait\n"); in q6v5_stop()
1641 struct q6v5 *qproc = rproc->priv; in qcom_q6v5_register_dump_segments()
1645 ret = request_firmware(&fw, qproc->hexagon_mdt_image, qproc->dev); in qcom_q6v5_register_dump_segments()
1647 dev_err(qproc->dev, "unable to load %s\n", in qcom_q6v5_register_dump_segments()
1648 qproc->hexagon_mdt_image); in qcom_q6v5_register_dump_segments()
1654 ehdr = (struct elf32_hdr *)fw->data; in qcom_q6v5_register_dump_segments()
1656 qproc->total_dump_size = 0; in qcom_q6v5_register_dump_segments()
1658 for (i = 0; i < ehdr->e_phnum; i++) { in qcom_q6v5_register_dump_segments()
1664 ret = rproc_coredump_add_custom_segment(rproc, phdr->p_paddr, in qcom_q6v5_register_dump_segments()
1665 phdr->p_memsz, in qcom_q6v5_register_dump_segments()
1671 qproc->total_dump_size += phdr->p_memsz; in qcom_q6v5_register_dump_segments()
1680 struct q6v5 *qproc = rproc->priv; in q6v5_panic()
1682 return qcom_q6v5_panic(&qproc->q6v5); in q6v5_panic()
1697 q6v5_clk_disable(qproc->dev, qproc->proxy_clks, in qcom_msa_handover()
1698 qproc->proxy_clk_count); in qcom_msa_handover()
1699 q6v5_regulator_disable(qproc, qproc->proxy_regs, in qcom_msa_handover()
1700 qproc->proxy_reg_count); in qcom_msa_handover()
1701 q6v5_regulator_disable(qproc, qproc->fallback_proxy_regs, in qcom_msa_handover()
1702 qproc->fallback_proxy_reg_count); in qcom_msa_handover()
1703 q6v5_pds_disable(qproc, qproc->proxy_pds, qproc->proxy_pd_count); in qcom_msa_handover()
1712 qproc->reg_base = devm_platform_ioremap_resource_byname(pdev, "qdsp6"); in q6v5_init_mem()
1713 if (IS_ERR(qproc->reg_base)) in q6v5_init_mem()
1714 return PTR_ERR(qproc->reg_base); in q6v5_init_mem()
1716 qproc->rmb_base = devm_platform_ioremap_resource_byname(pdev, "rmb"); in q6v5_init_mem()
1717 if (IS_ERR(qproc->rmb_base)) in q6v5_init_mem()
1718 return PTR_ERR(qproc->rmb_base); in q6v5_init_mem()
1720 if (qproc->has_vq6) in q6v5_init_mem()
1723 ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node, in q6v5_init_mem()
1724 "qcom,halt-regs", halt_cell_cnt, 0, &args); in q6v5_init_mem()
1726 dev_err(&pdev->dev, "failed to parse qcom,halt-regs\n"); in q6v5_init_mem()
1727 return -EINVAL; in q6v5_init_mem()
1730 qproc->halt_map = syscon_node_to_regmap(args.np); in q6v5_init_mem()
1732 if (IS_ERR(qproc->halt_map)) in q6v5_init_mem()
1733 return PTR_ERR(qproc->halt_map); in q6v5_init_mem()
1735 qproc->halt_q6 = args.args[0]; in q6v5_init_mem()
1736 qproc->halt_modem = args.args[1]; in q6v5_init_mem()
1737 qproc->halt_nc = args.args[2]; in q6v5_init_mem()
1739 if (qproc->has_vq6) in q6v5_init_mem()
1740 qproc->halt_vq6 = args.args[3]; in q6v5_init_mem()
1742 if (qproc->has_qaccept_regs) { in q6v5_init_mem()
1743 ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node, in q6v5_init_mem()
1744 "qcom,qaccept-regs", in q6v5_init_mem()
1747 dev_err(&pdev->dev, "failed to parse qaccept-regs\n"); in q6v5_init_mem()
1748 return -EINVAL; in q6v5_init_mem()
1751 qproc->qaccept_mdm = args.args[0]; in q6v5_init_mem()
1752 qproc->qaccept_cx = args.args[1]; in q6v5_init_mem()
1753 qproc->qaccept_axi = args.args[2]; in q6v5_init_mem()
1756 if (qproc->has_ext_cntl_regs) { in q6v5_init_mem()
1757 ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node, in q6v5_init_mem()
1758 "qcom,ext-regs", in q6v5_init_mem()
1761 dev_err(&pdev->dev, "failed to parse ext-regs index 0\n"); in q6v5_init_mem()
1762 return -EINVAL; in q6v5_init_mem()
1765 qproc->conn_map = syscon_node_to_regmap(args.np); in q6v5_init_mem()
1767 if (IS_ERR(qproc->conn_map)) in q6v5_init_mem()
1768 return PTR_ERR(qproc->conn_map); in q6v5_init_mem()
1770 qproc->force_clk_on = args.args[0]; in q6v5_init_mem()
1771 qproc->rscc_disable = args.args[1]; in q6v5_init_mem()
1773 ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node, in q6v5_init_mem()
1774 "qcom,ext-regs", in q6v5_init_mem()
1777 dev_err(&pdev->dev, "failed to parse ext-regs index 1\n"); in q6v5_init_mem()
1778 return -EINVAL; in q6v5_init_mem()
1781 qproc->axim1_clk_off = args.args[0]; in q6v5_init_mem()
1782 qproc->crypto_clk_off = args.args[1]; in q6v5_init_mem()
1785 if (qproc->has_spare_reg) { in q6v5_init_mem()
1786 ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node, in q6v5_init_mem()
1787 "qcom,spare-regs", in q6v5_init_mem()
1790 dev_err(&pdev->dev, "failed to parse spare-regs\n"); in q6v5_init_mem()
1791 return -EINVAL; in q6v5_init_mem()
1794 qproc->conn_map = syscon_node_to_regmap(args.np); in q6v5_init_mem()
1796 if (IS_ERR(qproc->conn_map)) in q6v5_init_mem()
1797 return PTR_ERR(qproc->conn_map); in q6v5_init_mem()
1799 qproc->conn_box = args.args[0]; in q6v5_init_mem()
1818 if (rc != -EPROBE_DEFER) in q6v5_init_clocks()
1844 ret = PTR_ERR(devs[i]) ? : -ENODATA; in q6v5_pds_attach()
1852 for (i--; i >= 0; i--) in q6v5_pds_attach()
1869 qproc->mss_restart = devm_reset_control_get_exclusive(qproc->dev, in q6v5_init_reset()
1871 if (IS_ERR(qproc->mss_restart)) { in q6v5_init_reset()
1872 dev_err(qproc->dev, "failed to acquire mss restart\n"); in q6v5_init_reset()
1873 return PTR_ERR(qproc->mss_restart); in q6v5_init_reset()
1876 if (qproc->has_alt_reset || qproc->has_spare_reg || qproc->has_ext_cntl_regs) { in q6v5_init_reset()
1877 qproc->pdc_reset = devm_reset_control_get_exclusive(qproc->dev, in q6v5_init_reset()
1879 if (IS_ERR(qproc->pdc_reset)) { in q6v5_init_reset()
1880 dev_err(qproc->dev, "failed to acquire pdc reset\n"); in q6v5_init_reset()
1881 return PTR_ERR(qproc->pdc_reset); in q6v5_init_reset()
1895 * In the absence of mba/mpss sub-child, extract the mba and mpss in q6v5_alloc_memory_region()
1896 * reserved memory regions from device's memory-region property. in q6v5_alloc_memory_region()
1898 child = of_get_child_by_name(qproc->dev->of_node, "mba"); in q6v5_alloc_memory_region()
1900 node = of_parse_phandle(qproc->dev->of_node, in q6v5_alloc_memory_region()
1901 "memory-region", 0); in q6v5_alloc_memory_region()
1903 node = of_parse_phandle(child, "memory-region", 0); in q6v5_alloc_memory_region()
1908 dev_err(qproc->dev, "no mba memory-region specified\n"); in q6v5_alloc_memory_region()
1909 return -EINVAL; in q6v5_alloc_memory_region()
1915 dev_err(qproc->dev, "unable to resolve mba region\n"); in q6v5_alloc_memory_region()
1916 return -EINVAL; in q6v5_alloc_memory_region()
1919 qproc->mba_phys = rmem->base; in q6v5_alloc_memory_region()
1920 qproc->mba_size = rmem->size; in q6v5_alloc_memory_region()
1923 node = of_parse_phandle(qproc->dev->of_node, in q6v5_alloc_memory_region()
1924 "memory-region", 1); in q6v5_alloc_memory_region()
1926 child = of_get_child_by_name(qproc->dev->of_node, "mpss"); in q6v5_alloc_memory_region()
1927 node = of_parse_phandle(child, "memory-region", 0); in q6v5_alloc_memory_region()
1932 dev_err(qproc->dev, "no mpss memory-region specified\n"); in q6v5_alloc_memory_region()
1933 return -EINVAL; in q6v5_alloc_memory_region()
1939 dev_err(qproc->dev, "unable to resolve mpss region\n"); in q6v5_alloc_memory_region()
1940 return -EINVAL; in q6v5_alloc_memory_region()
1943 qproc->mpss_phys = qproc->mpss_reloc = rmem->base; in q6v5_alloc_memory_region()
1944 qproc->mpss_size = rmem->size; in q6v5_alloc_memory_region()
1947 node = of_parse_phandle(qproc->dev->of_node, "memory-region", 2); in q6v5_alloc_memory_region()
1949 child = of_get_child_by_name(qproc->dev->of_node, "metadata"); in q6v5_alloc_memory_region()
1950 node = of_parse_phandle(child, "memory-region", 0); in q6v5_alloc_memory_region()
1959 dev_err(qproc->dev, "unable to resolve metadata region\n"); in q6v5_alloc_memory_region()
1960 return -EINVAL; in q6v5_alloc_memory_region()
1963 qproc->mdata_phys = rmem->base; in q6v5_alloc_memory_region()
1964 qproc->mdata_size = rmem->size; in q6v5_alloc_memory_region()
1978 desc = of_device_get_match_data(&pdev->dev); in q6v5_probe()
1980 return -EINVAL; in q6v5_probe()
1982 if (desc->need_mem_protection && !qcom_scm_is_available()) in q6v5_probe()
1983 return -EPROBE_DEFER; in q6v5_probe()
1985 mba_image = desc->hexagon_mba_image; in q6v5_probe()
1986 ret = of_property_read_string_index(pdev->dev.of_node, "firmware-name", in q6v5_probe()
1988 if (ret < 0 && ret != -EINVAL) { in q6v5_probe()
1989 dev_err(&pdev->dev, "unable to read mba firmware-name\n"); in q6v5_probe()
1993 rproc = rproc_alloc(&pdev->dev, pdev->name, &q6v5_ops, in q6v5_probe()
1996 dev_err(&pdev->dev, "failed to allocate rproc\n"); in q6v5_probe()
1997 return -ENOMEM; in q6v5_probe()
2000 rproc->auto_boot = false; in q6v5_probe()
2003 qproc = rproc->priv; in q6v5_probe()
2004 qproc->dev = &pdev->dev; in q6v5_probe()
2005 qproc->rproc = rproc; in q6v5_probe()
2006 qproc->hexagon_mdt_image = "modem.mdt"; in q6v5_probe()
2007 ret = of_property_read_string_index(pdev->dev.of_node, "firmware-name", in q6v5_probe()
2008 1, &qproc->hexagon_mdt_image); in q6v5_probe()
2009 if (ret < 0 && ret != -EINVAL) { in q6v5_probe()
2010 dev_err(&pdev->dev, "unable to read mpss firmware-name\n"); in q6v5_probe()
2016 qproc->has_qaccept_regs = desc->has_qaccept_regs; in q6v5_probe()
2017 qproc->has_ext_cntl_regs = desc->has_ext_cntl_regs; in q6v5_probe()
2018 qproc->has_vq6 = desc->has_vq6; in q6v5_probe()
2019 qproc->has_spare_reg = desc->has_spare_reg; in q6v5_probe()
2028 ret = q6v5_init_clocks(&pdev->dev, qproc->proxy_clks, in q6v5_probe()
2029 desc->proxy_clk_names); in q6v5_probe()
2031 dev_err(&pdev->dev, "Failed to get proxy clocks.\n"); in q6v5_probe()
2034 qproc->proxy_clk_count = ret; in q6v5_probe()
2036 ret = q6v5_init_clocks(&pdev->dev, qproc->reset_clks, in q6v5_probe()
2037 desc->reset_clk_names); in q6v5_probe()
2039 dev_err(&pdev->dev, "Failed to get reset clocks.\n"); in q6v5_probe()
2042 qproc->reset_clk_count = ret; in q6v5_probe()
2044 ret = q6v5_init_clocks(&pdev->dev, qproc->active_clks, in q6v5_probe()
2045 desc->active_clk_names); in q6v5_probe()
2047 dev_err(&pdev->dev, "Failed to get active clocks.\n"); in q6v5_probe()
2050 qproc->active_clk_count = ret; in q6v5_probe()
2052 ret = q6v5_regulator_init(&pdev->dev, qproc->proxy_regs, in q6v5_probe()
2053 desc->proxy_supply); in q6v5_probe()
2055 dev_err(&pdev->dev, "Failed to get proxy regulators.\n"); in q6v5_probe()
2058 qproc->proxy_reg_count = ret; in q6v5_probe()
2060 ret = q6v5_regulator_init(&pdev->dev, qproc->active_regs, in q6v5_probe()
2061 desc->active_supply); in q6v5_probe()
2063 dev_err(&pdev->dev, "Failed to get active regulators.\n"); in q6v5_probe()
2066 qproc->active_reg_count = ret; in q6v5_probe()
2068 ret = q6v5_pds_attach(&pdev->dev, qproc->proxy_pds, in q6v5_probe()
2069 desc->proxy_pd_names); in q6v5_probe()
2071 if (ret == -ENODATA && desc->fallback_proxy_supply) { in q6v5_probe()
2072 ret = q6v5_regulator_init(&pdev->dev, in q6v5_probe()
2073 qproc->fallback_proxy_regs, in q6v5_probe()
2074 desc->fallback_proxy_supply); in q6v5_probe()
2076 dev_err(&pdev->dev, "Failed to get fallback proxy regulators.\n"); in q6v5_probe()
2079 qproc->fallback_proxy_reg_count = ret; in q6v5_probe()
2081 dev_err(&pdev->dev, "Failed to init power domains\n"); in q6v5_probe()
2084 qproc->proxy_pd_count = ret; in q6v5_probe()
2087 qproc->has_alt_reset = desc->has_alt_reset; in q6v5_probe()
2092 qproc->version = desc->version; in q6v5_probe()
2093 qproc->need_mem_protection = desc->need_mem_protection; in q6v5_probe()
2094 qproc->has_mba_logs = desc->has_mba_logs; in q6v5_probe()
2096 ret = qcom_q6v5_init(&qproc->q6v5, pdev, rproc, MPSS_CRASH_REASON_SMEM, "modem", in q6v5_probe()
2101 qproc->mpss_perm = BIT(QCOM_SCM_VMID_HLOS); in q6v5_probe()
2102 qproc->mba_perm = BIT(QCOM_SCM_VMID_HLOS); in q6v5_probe()
2103 qcom_add_glink_subdev(rproc, &qproc->glink_subdev, "mpss"); in q6v5_probe()
2104 qcom_add_smd_subdev(rproc, &qproc->smd_subdev); in q6v5_probe()
2105 qcom_add_ssr_subdev(rproc, &qproc->ssr_subdev, "mpss"); in q6v5_probe()
2106 qproc->sysmon = qcom_add_sysmon_subdev(rproc, "modem", 0x12); in q6v5_probe()
2107 if (IS_ERR(qproc->sysmon)) { in q6v5_probe()
2108 ret = PTR_ERR(qproc->sysmon); in q6v5_probe()
2116 node = of_get_compatible_child(pdev->dev.of_node, "qcom,bam-dmux"); in q6v5_probe()
2117 qproc->bam_dmux = of_platform_device_create(node, NULL, &pdev->dev); in q6v5_probe()
2123 qcom_remove_sysmon_subdev(qproc->sysmon); in q6v5_probe()
2125 qcom_remove_ssr_subdev(rproc, &qproc->ssr_subdev); in q6v5_probe()
2126 qcom_remove_smd_subdev(rproc, &qproc->smd_subdev); in q6v5_probe()
2127 qcom_remove_glink_subdev(rproc, &qproc->glink_subdev); in q6v5_probe()
2129 q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count); in q6v5_probe()
2139 struct rproc *rproc = qproc->rproc; in q6v5_remove()
2141 if (qproc->bam_dmux) in q6v5_remove()
2142 of_platform_device_destroy(&qproc->bam_dmux->dev, NULL); in q6v5_remove()
2145 qcom_q6v5_deinit(&qproc->q6v5); in q6v5_remove()
2146 qcom_remove_sysmon_subdev(qproc->sysmon); in q6v5_remove()
2147 qcom_remove_ssr_subdev(rproc, &qproc->ssr_subdev); in q6v5_remove()
2148 qcom_remove_smd_subdev(rproc, &qproc->smd_subdev); in q6v5_remove()
2149 qcom_remove_glink_subdev(rproc, &qproc->glink_subdev); in q6v5_remove()
2151 q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count); in q6v5_remove()
2176 "mss",
2204 "mss",
2270 "mss",
2454 "mss",
2489 .supply = "mss",
2521 { .compatible = "qcom,q6v5-pil", .data = &msm8916_mss},
2522 { .compatible = "qcom,msm8909-mss-pil", .data = &msm8909_mss},
2523 { .compatible = "qcom,msm8916-mss-pil", .data = &msm8916_mss},
2524 { .compatible = "qcom,msm8953-mss-pil", .data = &msm8953_mss},
2525 { .compatible = "qcom,msm8974-mss-pil", .data = &msm8974_mss},
2526 { .compatible = "qcom,msm8996-mss-pil", .data = &msm8996_mss},
2527 { .compatible = "qcom,msm8998-mss-pil", .data = &msm8998_mss},
2528 { .compatible = "qcom,sc7180-mss-pil", .data = &sc7180_mss},
2529 { .compatible = "qcom,sc7280-mss-pil", .data = &sc7280_mss},
2530 { .compatible = "qcom,sdm660-mss-pil", .data = &sdm660_mss},
2531 { .compatible = "qcom,sdm845-mss-pil", .data = &sdm845_mss},
2540 .name = "qcom-q6v5-mss",
2546 MODULE_DESCRIPTION("Qualcomm Self-authenticating modem remoteproc driver");