Lines Matching +full:8 +full:- +full:cx +full:- +full:mx +full:- +full:supply
1 // SPDX-License-Identifier: GPL-2.0-only
7 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
47 #define WCNSS_PMU_IRIS_RESET_STS BIT(8) /* 1: in progress, 0: done */
120 .pd_names = { "cx", "mx" },
134 .pd_names = { "cx", "mx" },
148 .pd_names = { "mx", "cx" },
157 struct qcom_wcnss *wcnss = rproc->priv; in wcnss_load()
160 ret = qcom_mdt_load(wcnss->dev, fw, rproc->firmware, WCNSS_PAS_ID, in wcnss_load()
161 wcnss->mem_region, wcnss->mem_phys, in wcnss_load()
162 wcnss->mem_size, &wcnss->mem_reloc); in wcnss_load()
166 qcom_pil_info_store("wcnss", wcnss->mem_phys, wcnss->mem_size); in wcnss_load()
176 val = readl(wcnss->spare_out); in wcnss_indicate_nv_download()
178 writel(val, wcnss->spare_out); in wcnss_indicate_nv_download()
186 writel(0, wcnss->pmu_cfg); in wcnss_configure_iris()
189 writel(val, wcnss->pmu_cfg); in wcnss_configure_iris()
193 if (wcnss->use_48mhz_xo) in wcnss_configure_iris()
197 writel(val, wcnss->pmu_cfg); in wcnss_configure_iris()
201 writel(val, wcnss->pmu_cfg); in wcnss_configure_iris()
204 while (readl(wcnss->pmu_cfg) & WCNSS_PMU_IRIS_RESET_STS) in wcnss_configure_iris()
209 writel(val, wcnss->pmu_cfg); in wcnss_configure_iris()
213 writel(val, wcnss->pmu_cfg); in wcnss_configure_iris()
216 while (readl(wcnss->pmu_cfg) & WCNSS_PMU_IRIS_XO_CFG_STS) in wcnss_configure_iris()
222 writel(val, wcnss->pmu_cfg); in wcnss_configure_iris()
230 struct qcom_wcnss *wcnss = rproc->priv; in wcnss_start()
233 mutex_lock(&wcnss->iris_lock); in wcnss_start()
234 if (!wcnss->iris) { in wcnss_start()
235 dev_err(wcnss->dev, "no iris registered\n"); in wcnss_start()
236 ret = -EINVAL; in wcnss_start()
240 for (i = 0; i < wcnss->num_pds; i++) { in wcnss_start()
241 dev_pm_genpd_set_performance_state(wcnss->pds[i], INT_MAX); in wcnss_start()
242 ret = pm_runtime_get_sync(wcnss->pds[i]); in wcnss_start()
244 pm_runtime_put_noidle(wcnss->pds[i]); in wcnss_start()
249 ret = regulator_bulk_enable(wcnss->num_vregs, wcnss->vregs); in wcnss_start()
253 ret = qcom_iris_enable(wcnss->iris); in wcnss_start()
262 dev_err(wcnss->dev, in wcnss_start()
267 ret = wait_for_completion_timeout(&wcnss->start_done, in wcnss_start()
269 if (wcnss->ready_irq > 0 && ret == 0) { in wcnss_start()
271 dev_err(wcnss->dev, "start timed out\n"); in wcnss_start()
273 ret = -ETIMEDOUT; in wcnss_start()
280 qcom_iris_disable(wcnss->iris); in wcnss_start()
282 regulator_bulk_disable(wcnss->num_vregs, wcnss->vregs); in wcnss_start()
284 for (i--; i >= 0; i--) { in wcnss_start()
285 pm_runtime_put(wcnss->pds[i]); in wcnss_start()
286 dev_pm_genpd_set_performance_state(wcnss->pds[i], 0); in wcnss_start()
289 mutex_unlock(&wcnss->iris_lock); in wcnss_start()
296 struct qcom_wcnss *wcnss = rproc->priv; in wcnss_stop()
299 if (wcnss->state) { in wcnss_stop()
300 qcom_smem_state_update_bits(wcnss->state, in wcnss_stop()
301 BIT(wcnss->stop_bit), in wcnss_stop()
302 BIT(wcnss->stop_bit)); in wcnss_stop()
304 ret = wait_for_completion_timeout(&wcnss->stop_done, in wcnss_stop()
307 dev_err(wcnss->dev, "timed out on wait\n"); in wcnss_stop()
309 qcom_smem_state_update_bits(wcnss->state, in wcnss_stop()
310 BIT(wcnss->stop_bit), in wcnss_stop()
316 dev_err(wcnss->dev, "failed to shutdown: %d\n", ret); in wcnss_stop()
323 struct qcom_wcnss *wcnss = rproc->priv; in wcnss_da_to_va()
326 offset = da - wcnss->mem_reloc; in wcnss_da_to_va()
327 if (offset < 0 || offset + len > wcnss->mem_size) in wcnss_da_to_va()
330 return wcnss->mem_region + offset; in wcnss_da_to_va()
345 rproc_report_crash(wcnss->rproc, RPROC_WATCHDOG); in wcnss_wdog_interrupt()
358 dev_err(wcnss->dev, "fatal error received: %s\n", msg); in wcnss_fatal_interrupt()
360 rproc_report_crash(wcnss->rproc, RPROC_FATAL_ERROR); in wcnss_fatal_interrupt()
369 complete(&wcnss->start_done); in wcnss_ready_interrupt()
392 complete(&wcnss->stop_done); in wcnss_stop_ack_interrupt()
400 struct device *dev = wcnss->dev; in wcnss_init_pds()
404 if (dev->pm_domain) { in wcnss_init_pds()
405 wcnss->pds[0] = dev; in wcnss_init_pds()
406 wcnss->num_pds = 1; in wcnss_init_pds()
415 wcnss->pds[i] = dev_pm_domain_attach_by_name(wcnss->dev, pd_names[i]); in wcnss_init_pds()
416 if (IS_ERR_OR_NULL(wcnss->pds[i])) { in wcnss_init_pds()
417 ret = PTR_ERR(wcnss->pds[i]) ? : -ENODATA; in wcnss_init_pds()
418 for (i--; i >= 0; i--) in wcnss_init_pds()
419 dev_pm_domain_detach(wcnss->pds[i], false); in wcnss_init_pds()
423 wcnss->num_pds = i; in wcnss_init_pds()
430 struct device *dev = wcnss->dev; in wcnss_release_pds()
434 if (wcnss->num_pds == 1 && dev->pm_domain) { in wcnss_release_pds()
439 for (i = 0; i < wcnss->num_pds; i++) in wcnss_release_pds()
440 dev_pm_domain_detach(wcnss->pds[i], false); in wcnss_release_pds()
456 if (wcnss->num_pds) { in wcnss_init_regulators()
457 info += wcnss->num_pds; in wcnss_init_regulators()
459 if (wcnss->num_pds < num_pd_vregs) in wcnss_init_regulators()
460 num_vregs += num_pd_vregs - wcnss->num_pds; in wcnss_init_regulators()
465 bulk = devm_kcalloc(wcnss->dev, in wcnss_init_regulators()
469 return -ENOMEM; in wcnss_init_regulators()
472 bulk[i].supply = info[i].name; in wcnss_init_regulators()
474 ret = devm_regulator_bulk_get(wcnss->dev, num_vregs, bulk); in wcnss_init_regulators()
488 wcnss->vregs = bulk; in wcnss_init_regulators()
489 wcnss->num_vregs = num_vregs; in wcnss_init_regulators()
505 dev_dbg(&pdev->dev, "no %s IRQ defined, ignoring\n", name); in wcnss_request_irq()
508 dev_err(&pdev->dev, "no %s IRQ defined\n", name); in wcnss_request_irq()
514 ret = devm_request_threaded_irq(&pdev->dev, ret, in wcnss_request_irq()
519 dev_err(&pdev->dev, "request %s IRQ failed\n", name); in wcnss_request_irq()
532 node = of_parse_phandle(wcnss->dev->of_node, "memory-region", 0); in wcnss_alloc_memory_region()
538 dev_err(wcnss->dev, "unable to resolve memory-region\n"); in wcnss_alloc_memory_region()
539 return -EINVAL; in wcnss_alloc_memory_region()
542 wcnss->mem_phys = wcnss->mem_reloc = rmem->base; in wcnss_alloc_memory_region()
543 wcnss->mem_size = rmem->size; in wcnss_alloc_memory_region()
544 wcnss->mem_region = devm_ioremap_wc(wcnss->dev, wcnss->mem_phys, wcnss->mem_size); in wcnss_alloc_memory_region()
545 if (!wcnss->mem_region) { in wcnss_alloc_memory_region()
546 dev_err(wcnss->dev, "unable to map memory region: %pa+%zx\n", in wcnss_alloc_memory_region()
547 &rmem->base, wcnss->mem_size); in wcnss_alloc_memory_region()
548 return -EBUSY; in wcnss_alloc_memory_region()
563 data = of_device_get_match_data(&pdev->dev); in wcnss_probe()
566 return -EPROBE_DEFER; in wcnss_probe()
569 dev_err(&pdev->dev, "PAS is not available for WCNSS\n"); in wcnss_probe()
570 return -ENXIO; in wcnss_probe()
573 ret = of_property_read_string(pdev->dev.of_node, "firmware-name", in wcnss_probe()
575 if (ret < 0 && ret != -EINVAL) in wcnss_probe()
578 rproc = devm_rproc_alloc(&pdev->dev, pdev->name, &wcnss_ops, in wcnss_probe()
581 dev_err(&pdev->dev, "unable to allocate remoteproc\n"); in wcnss_probe()
582 return -ENOMEM; in wcnss_probe()
586 wcnss = rproc->priv; in wcnss_probe()
587 wcnss->dev = &pdev->dev; in wcnss_probe()
588 wcnss->rproc = rproc; in wcnss_probe()
591 init_completion(&wcnss->start_done); in wcnss_probe()
592 init_completion(&wcnss->stop_done); in wcnss_probe()
594 mutex_init(&wcnss->iris_lock); in wcnss_probe()
604 wcnss->pmu_cfg = mmio + data->pmu_offset; in wcnss_probe()
605 wcnss->spare_out = mmio + data->spare_offset; in wcnss_probe()
611 ret = wcnss_init_pds(wcnss, data->pd_names); in wcnss_probe()
612 if (ret && (ret != -ENODATA || !data->num_pd_vregs)) in wcnss_probe()
615 ret = wcnss_init_regulators(wcnss, data->vregs, data->num_vregs, in wcnss_probe()
616 data->num_pd_vregs); in wcnss_probe()
623 wcnss->wdog_irq = ret; in wcnss_probe()
628 wcnss->fatal_irq = ret; in wcnss_probe()
633 wcnss->ready_irq = ret; in wcnss_probe()
638 wcnss->handover_irq = ret; in wcnss_probe()
640 ret = wcnss_request_irq(wcnss, pdev, "stop-ack", true, wcnss_stop_ack_interrupt); in wcnss_probe()
643 wcnss->stop_ack_irq = ret; in wcnss_probe()
645 if (wcnss->stop_ack_irq) { in wcnss_probe()
646 wcnss->state = devm_qcom_smem_state_get(&pdev->dev, "stop", in wcnss_probe()
647 &wcnss->stop_bit); in wcnss_probe()
648 if (IS_ERR(wcnss->state)) { in wcnss_probe()
649 ret = PTR_ERR(wcnss->state); in wcnss_probe()
654 qcom_add_smd_subdev(rproc, &wcnss->smd_subdev); in wcnss_probe()
655 wcnss->sysmon = qcom_add_sysmon_subdev(rproc, "wcnss", WCNSS_SSCTL_ID); in wcnss_probe()
656 if (IS_ERR(wcnss->sysmon)) { in wcnss_probe()
657 ret = PTR_ERR(wcnss->sysmon); in wcnss_probe()
661 wcnss->iris = qcom_iris_probe(&pdev->dev, &wcnss->use_48mhz_xo); in wcnss_probe()
662 if (IS_ERR(wcnss->iris)) { in wcnss_probe()
663 ret = PTR_ERR(wcnss->iris); in wcnss_probe()
674 qcom_iris_remove(wcnss->iris); in wcnss_probe()
685 qcom_iris_remove(wcnss->iris); in wcnss_remove()
687 rproc_del(wcnss->rproc); in wcnss_remove()
689 qcom_remove_sysmon_subdev(wcnss->sysmon); in wcnss_remove()
690 qcom_remove_smd_subdev(wcnss->rproc, &wcnss->smd_subdev); in wcnss_remove()
695 { .compatible = "qcom,riva-pil", &riva_data },
696 { .compatible = "qcom,pronto-v1-pil", &pronto_v1_data },
697 { .compatible = "qcom,pronto-v2-pil", &pronto_v2_data },
698 { .compatible = "qcom,pronto-v3-pil", &pronto_v3_data },
707 .name = "qcom-wcnss-pil",