static int pil_mss_reset(struct pil_desc *pil) { struct q6v5_data *drv = container_of(pil, struct q6v5_data, desc); phys_addr_t start_addr = pil_get_entry_addr(pil); int ret; if (drv->mba_phys) start_addr = drv->mba_phys; /* * Bring subsystem out of reset and enable required * regulators and clocks. */ ret = pil_mss_power_up(drv); if (ret) goto err_power; /* Deassert reset to subsystem and wait for propagation */ ret = pil_mss_restart_reg(drv, 0); if (ret) goto err_restart; ret = pil_mss_enable_clks(drv); if (ret) goto err_clks; /* Program Image Address */ if (drv->self_auth) { writel_relaxed(start_addr, drv->rmb_base + RMB_MBA_IMAGE); /* * Ensure write to RMB base occurs before reset * is released. */ mb(); } else { writel_relaxed((start_addr >> 4) & 0x0FFFFFF0, drv->reg_base + QDSP6SS_RST_EVB); } ret = pil_q6v5_reset(pil); if (ret) goto err_q6v5_reset; /* Wait for MBA to start. Check for PBL and MBA errors while waiting. */ if (drv->self_auth) { ret = pil_msa_wait_for_mba_ready(drv); if (ret) goto err_q6v5_reset; } pr_info("pil: MBA boot done\n"); drv->is_booted = true; return 0; err_q6v5_reset: modem_log_rmb_regs(drv->rmb_base); pil_mss_disable_clks(drv); err_clks: pil_mss_restart_reg(drv, 1); err_restart: pil_mss_power_down(drv); err_power: return ret; }
static int pil_mss_reset(struct pil_desc *pil) { struct q6v5_data *drv = container_of(pil, struct q6v5_data, desc); phys_addr_t start_addr = pil_get_entry_addr(pil); int ret; if (drv->mba_phys) start_addr = drv->mba_phys; /* * Bring subsystem out of reset and enable required * regulators and clocks. */ ret = pil_mss_power_up(drv); if (ret) goto err_power; /* Deassert reset to subsystem and wait for propagation */ ret = pil_mss_restart_reg(drv, 0); if (ret) goto err_restart; ret = pil_mss_enable_clks(drv); if (ret) goto err_clks; if (modem_dbg_cfg) writel_relaxed(modem_dbg_cfg, drv->reg_base + QDSP6SS_DBG_CFG); /* Program Image Address */ if (drv->self_auth) { writel_relaxed(start_addr, drv->rmb_base + RMB_MBA_IMAGE); /* * Ensure write to RMB base occurs before reset * is released. */ mb(); } else { writel_relaxed((start_addr >> 4) & 0x0FFFFFF0, drv->reg_base + QDSP6SS_RST_EVB); } /* Program DP Address */ if (drv->dp_virt) { writel_relaxed(drv->dp_phys, drv->rmb_base + RMB_PMI_CODE_START); writel_relaxed(drv->dp_size, drv->rmb_base + RMB_PMI_CODE_LENGTH); } else { writel_relaxed(0, drv->rmb_base + RMB_PMI_CODE_START); writel_relaxed(0, drv->rmb_base + RMB_PMI_CODE_LENGTH); } /* Make sure RMB regs are written before bringing modem out of reset */ mb(); ret = pil_q6v5_reset(pil); if (ret) goto err_q6v5_reset; /* Wait for MBA to start. Check for PBL and MBA errors while waiting. */ if (drv->self_auth) { ret = pil_msa_wait_for_mba_ready(drv); if (ret) goto err_q6v5_reset; } dev_info(pil->dev, "MBA boot done\n"); drv->is_booted = true; return 0; err_q6v5_reset: modem_log_rmb_regs(drv->rmb_base); pil_mss_disable_clks(drv); if (drv->ahb_clk_vote) clk_disable_unprepare(drv->ahb_clk); err_clks: pil_mss_restart_reg(drv, 1); err_restart: pil_mss_power_down(drv); err_power: return ret; }