Lines Matching +full:db8500 +full:- +full:prcmu
1 // SPDX-License-Identifier: GPL-2.0-only
3 * DB8500 PRCM Unit driver
6 * Copyright (C) ST-Ericsson SA 2010
35 #include <linux/mfd/dbx500-prcmu.h>
37 #include <linux/regulator/db8500-prcmu.h>
39 #include "db8500-prcmu-regs.h"
227 #define ALL_MBOX_BITS (MBOX_BIT(NUM_MB) - 1)
272 * communication with the PRCMU firmware.
332 #define VALID_WAKEUPS (BIT(NUM_PRCMU_WAKEUP_INDICES) - 1)
347 * mb0_transfer - state needed for mailbox 0 communication.
368 * mb1_transfer - state needed for mailbox 1 communication.
387 * mb2_transfer - state needed for mailbox 2 communication.
406 * mb3_transfer - state needed for mailbox 3 communication.
418 * mb4_transfer - state needed for mailbox 4 communication.
428 * mb5_transfer - state needed for mailbox 5 communication.
580 return ver && ver->project == PRCMU_FW_PROJECT_U8420_SYSCLK; in prcmu_is_ulppll_disabled()
590 * prcmu_set_rc_a2p - This function is used to run few power state sequences
592 * Returns: 0 on success, -EINVAL on invalid argument
594 * This function is used to run the following power state sequences -
600 return -EINVAL; in prcmu_set_rc_a2p()
606 * prcmu_get_rc_p2a - This function is used to get power state sequences
609 * This function can return the following transitions-
618 * prcmu_get_xp70_current_state - Return the current XP70 power mode
628 * prcmu_config_clkout - Configure one of the programmable clock outputs.
652 return -EINVAL; in prcmu_config_clkout()
674 r = -EBUSY; in prcmu_config_clkout()
679 r = -EINVAL; in prcmu_config_clkout()
685 requests[clkout] += (div ? 1 : -1); in prcmu_config_clkout()
797 * db8500_prcmu_set_arm_opp - set the appropriate ARM OPP
799 * Returns: 0 on success, non-zero on failure
808 return -EINVAL; in db8500_prcmu_set_arm_opp()
826 r = -EIO; in db8500_prcmu_set_arm_opp()
834 * db8500_prcmu_get_arm_opp - get the current ARM OPP
844 * db8500_prcmu_get_ddr_opp - get the current DDR OPP
877 pr_err("prcmu: Bad clock divider %d in %s\n", in request_even_slower_clocks()
900 * db8500_prcmu_set_ape_opp - set the appropriate APE OPP
902 * Returns: 0 on success, non-zero on failure
934 r = -EIO; in db8500_prcmu_set_ape_opp()
949 * db8500_prcmu_get_ape_opp - get the current APE OPP
959 * db8500_prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage
978 r = -EIO; in db8500_prcmu_request_ape_opp_100_voltage()
980 } else if (1 != requests--) { in db8500_prcmu_request_ape_opp_100_voltage()
996 r = -EIO; in db8500_prcmu_request_ape_opp_100_voltage()
1005 * prcmu_release_usb_wakeup_state - release the state required by a USB wakeup
1026 r = -EIO; in prcmu_release_usb_wakeup_state()
1042 return -EINVAL; in request_pll()
1056 r = -EIO; in request_pll()
1064 * db8500_prcmu_set_epod - set the state of a EPOD (power domain)
1117 pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", in db8500_prcmu_set_epod()
1119 r = -EIO; in db8500_prcmu_set_epod()
1124 r = -EIO; in db8500_prcmu_set_epod()
1132 * prcmu_configure_auto_pm - Configure autonomous power management.
1145 sleep_cfg = (sleep->sva_auto_pm_enable & 0xF); in prcmu_configure_auto_pm()
1146 sleep_cfg = ((sleep_cfg << 4) | (sleep->sia_auto_pm_enable & 0xF)); in prcmu_configure_auto_pm()
1147 sleep_cfg = ((sleep_cfg << 8) | (sleep->sva_power_on & 0xFF)); in prcmu_configure_auto_pm()
1148 sleep_cfg = ((sleep_cfg << 8) | (sleep->sia_power_on & 0xFF)); in prcmu_configure_auto_pm()
1149 sleep_cfg = ((sleep_cfg << 4) | (sleep->sva_policy & 0xF)); in prcmu_configure_auto_pm()
1150 sleep_cfg = ((sleep_cfg << 4) | (sleep->sia_policy & 0xF)); in prcmu_configure_auto_pm()
1152 idle_cfg = (idle->sva_auto_pm_enable & 0xF); in prcmu_configure_auto_pm()
1153 idle_cfg = ((idle_cfg << 4) | (idle->sia_auto_pm_enable & 0xF)); in prcmu_configure_auto_pm()
1154 idle_cfg = ((idle_cfg << 8) | (idle->sva_power_on & 0xFF)); in prcmu_configure_auto_pm()
1155 idle_cfg = ((idle_cfg << 8) | (idle->sia_power_on & 0xFF)); in prcmu_configure_auto_pm()
1156 idle_cfg = ((idle_cfg << 4) | (idle->sva_policy & 0xF)); in prcmu_configure_auto_pm()
1157 idle_cfg = ((idle_cfg << 4) | (idle->sia_policy & 0xF)); in prcmu_configure_auto_pm()
1164 * variables - i.e. there is no need to send a message. in prcmu_configure_auto_pm()
1170 ((sleep->sva_auto_pm_enable == PRCMU_AUTO_PM_ON) || in prcmu_configure_auto_pm()
1171 (sleep->sia_auto_pm_enable == PRCMU_AUTO_PM_ON) || in prcmu_configure_auto_pm()
1172 (idle->sva_auto_pm_enable == PRCMU_AUTO_PM_ON) || in prcmu_configure_auto_pm()
1173 (idle->sia_auto_pm_enable == PRCMU_AUTO_PM_ON)); in prcmu_configure_auto_pm()
1211 pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", in request_sysclk()
1213 r = -EIO; in request_sysclk()
1322 for (i = 10; !locked && (i > 0); --i) { in request_plldsi()
1335 r = -EAGAIN; in request_plldsi()
1366 * db8500_prcmu_request_clock() - Request for a clock to be enabled or disabled.
1382 return request_dsiclk((clock - PRCMU_DSI0CLK), enable); in db8500_prcmu_request_clock()
1384 return request_dsiescclk((clock - PRCMU_DSI0ESCCLK), enable); in db8500_prcmu_request_clock()
1392 return -EINVAL; in db8500_prcmu_request_clock()
1559 return dsiclk_rate(clock - PRCMU_DSI0CLK); in prcmu_clock_rate()
1561 return dsiescclk_rate(clock - PRCMU_DSI0ESCCLK); in prcmu_clock_rate()
1677 for (r = 7; (rem > 0) && (r > 0); r--) { in round_plldsi_rate()
1696 if ((rate - d) < rem) { in round_plldsi_rate()
1697 rem = (rate - d); in round_plldsi_rate()
1820 return -EINVAL; in set_armss_rate()
1837 for (r = 7; (rem > 0) && (r > 0); r--) { in set_plldsi_rate()
1858 if ((rate - hwrate) < rem) { in set_plldsi_rate()
1859 rem = (rate - hwrate); in set_plldsi_rate()
1865 return -EINVAL; in set_plldsi_rate()
1912 set_dsiclk_rate((clock - PRCMU_DSI0CLK), rate); in prcmu_set_clock_rate()
1914 set_dsiescclk_rate((clock - PRCMU_DSI0ESCCLK), rate); in prcmu_set_clock_rate()
1922 return -EINVAL; in db8500_prcmu_config_esram0_deep_sleep()
2005 return -EINVAL; in db8500_prcmu_start_temp_sense()
2087 * prcmu_abb_read() - Read register value(s) from the ABB.
2101 return -EINVAL; in prcmu_abb_read()
2118 pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", in prcmu_abb_read()
2120 r = -EIO; in prcmu_abb_read()
2122 r = ((mb5_transfer.ack.status == I2C_RD_OK) ? 0 : -EIO); in prcmu_abb_read()
2134 * prcmu_abb_write_masked() - Write masked register value(s) to the ABB.
2151 return -EINVAL; in prcmu_abb_write_masked()
2168 pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", in prcmu_abb_write_masked()
2170 r = -EIO; in prcmu_abb_write_masked()
2172 r = ((mb5_transfer.ack.status == I2C_WR_OK) ? 0 : -EIO); in prcmu_abb_write_masked()
2181 * prcmu_abb_write() - Write register value(s) to the ABB.
2198 * prcmu_ac_wake_req - should be called whenever ARM wants to wakeup Modem
2214 * Force Modem Wake-up before hostaccess_req ping-pong. in prcmu_ac_wake_req()
2228 pr_crit("prcmu: %s timed out (5 s) waiting for a reply.\n", in prcmu_ac_wake_req()
2230 ret = -EFAULT; in prcmu_ac_wake_req()
2239 * prcmu_ac_sleep_req - called when ARM no longer needs to talk to modem
2256 pr_crit("prcmu: %s timed out (5 s) waiting for a reply.\n", in prcmu_ac_sleep_req()
2272 * db8500_prcmu_system_reset - System reset
2286 * db8500_prcmu_get_reset_code - Retrieve SW reset reason code
2297 * db8500_prcmu_modem_reset - ask the PRCMU to reset modem
2311 * No need to check return from PRCMU as modem should go in reset state in db8500_prcmu_modem_reset()
2335 pr_warn("prcmu: Unknown message header (%d) in mailbox %d\n", in print_unknown_header_warning()
2481 bits -= MBOX_BIT(n); in prcmu_irq_handler()
2512 mb0_transfer.req.dbb_irqs &= ~prcmu_irq_bit[d->hwirq]; in prcmu_irq_mask()
2516 if (d->irq != IRQ_PRCMU_CA_SLEEP) in prcmu_irq_mask()
2526 mb0_transfer.req.dbb_irqs |= prcmu_irq_bit[d->hwirq]; in prcmu_irq_unmask()
2530 if (d->irq != IRQ_PRCMU_CA_SLEEP) in prcmu_irq_unmask()
2539 .name = "prcmu",
2578 return "U8420-sysclk"; in fw_project_name()
2616 return -ENOSYS; in db8500_irq_init()
2633 pr_err("no prcmu tcpm mem region provided\n"); in dbx500_fw_version_init()
2646 pr_info("PRCMU firmware: %s(%d), version %d.%d.%d\n", in dbx500_fw_version_init()
2666 np = of_find_compatible_node(NULL, NULL, "stericsson,db8500-prcmu"); in db8500_prcmu_early_init()
2670 pr_err("%s: ioremap() of prcmu registers failed!\n", __func__); in db8500_prcmu_early_init()
2708 * Power domain switches (ePODs) modeled as regulators for the DB8500 SoC
2711 REGULATOR_SUPPLY("v-ape", NULL),
2712 REGULATOR_SUPPLY("v-i2c", "nmk-i2c.0"),
2713 REGULATOR_SUPPLY("v-i2c", "nmk-i2c.1"),
2714 REGULATOR_SUPPLY("v-i2c", "nmk-i2c.2"),
2715 REGULATOR_SUPPLY("v-i2c", "nmk-i2c.3"),
2716 REGULATOR_SUPPLY("v-i2c", "nmk-i2c.4"),
2717 /* "v-mmc" changed to "vcore" in the mainline kernel */
2723 REGULATOR_SUPPLY("v-dma", "dma40.0"),
2724 REGULATOR_SUPPLY("v-ape", "ab8500-usb.0"),
2725 /* "v-uart" changed to "vcore" in the mainline kernel */
2729 REGULATOR_SUPPLY("v-ape", "nmk-ske-keypad.0"),
2730 REGULATOR_SUPPLY("v-hsi", "ste_hsi.0"),
2735 REGULATOR_SUPPLY("musb_1v8", "ab8500-usb.0"),
2737 REGULATOR_SUPPLY("hdmi_1v8", "0-0070"),
2747 REGULATOR_SUPPLY("sva-mmdsp", "cm_control"),
2752 REGULATOR_SUPPLY("sva-pipe", "cm_control"),
2757 REGULATOR_SUPPLY("sia-mmdsp", "cm_control"),
2762 REGULATOR_SUPPLY("sia-pipe", "cm_control"),
2766 REGULATOR_SUPPLY("v-mali", NULL),
2776 REGULATOR_SUPPLY("v-esram34", "mcde"),
2784 .name = "db8500-vape",
2793 .name = "db8500-varm",
2799 .name = "db8500-vmodem",
2805 .name = "db8500-vpll",
2811 .name = "db8500-vsmps1",
2817 .name = "db8500-vsmps2",
2825 .name = "db8500-vsmps3",
2831 .name = "db8500-vrf1",
2836 /* dependency to u8500-vape is handled outside regulator framework */
2838 .name = "db8500-sva-mmdsp",
2847 .name = "db8500-sva-mmdsp-ret",
2852 /* dependency to u8500-vape is handled outside regulator framework */
2854 .name = "db8500-sva-pipe",
2861 /* dependency to u8500-vape is handled outside regulator framework */
2863 .name = "db8500-sia-mmdsp",
2871 .name = "db8500-sia-mmdsp-ret",
2876 /* dependency to u8500-vape is handled outside regulator framework */
2878 .name = "db8500-sia-pipe",
2885 .supply_regulator = "db8500-vape",
2887 .name = "db8500-sga",
2895 .supply_regulator = "db8500-vape",
2897 .name = "db8500-b2r2-mcde",
2909 .name = "db8500-esram12",
2917 .name = "db8500-esram12-ret",
2927 .name = "db8500-esram34",
2935 .name = "db8500-esram34-ret",
2943 MFD_CELL_NAME("db8500-cpuidle"),
2947 MFD_CELL_OF("db8500-prcmu-regulators", NULL,
2949 "stericsson,db8500-prcmu-regulator"),
2950 MFD_CELL_OF("db8500-thermal",
2951 NULL, NULL, 0, 0, "stericsson,db8500-thermal"),
2959 .name = "ab8500-core", in db8500_prcmu_register_ab8500()
2966 .name = "ab8505-core", in db8500_prcmu_register_ab8500()
2974 if (!parent->of_node) in db8500_prcmu_register_ab8500()
2975 return -ENODEV; in db8500_prcmu_register_ab8500()
2978 for_each_child_of_node(parent->of_node, np) { in db8500_prcmu_register_ab8500()
2990 return -ENODEV; in db8500_prcmu_register_ab8500()
2999 struct device_node *np = pdev->dev.of_node; in db8500_prcmu_probe()
3003 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "prcmu"); in db8500_prcmu_probe()
3005 dev_err(&pdev->dev, "no prcmu memory region provided\n"); in db8500_prcmu_probe()
3006 return -EINVAL; in db8500_prcmu_probe()
3008 prcmu_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); in db8500_prcmu_probe()
3010 dev_err(&pdev->dev, in db8500_prcmu_probe()
3011 "failed to ioremap prcmu register memory\n"); in db8500_prcmu_probe()
3012 return -ENOMEM; in db8500_prcmu_probe()
3015 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "prcmu-tcdm"); in db8500_prcmu_probe()
3017 dev_err(&pdev->dev, "no prcmu tcdm region provided\n"); in db8500_prcmu_probe()
3018 return -EINVAL; in db8500_prcmu_probe()
3020 tcdm_base = devm_ioremap(&pdev->dev, res->start, in db8500_prcmu_probe()
3023 dev_err(&pdev->dev, in db8500_prcmu_probe()
3024 "failed to ioremap prcmu-tcdm register memory\n"); in db8500_prcmu_probe()
3025 return -ENOMEM; in db8500_prcmu_probe()
3028 /* Clean up the mailbox interrupts after pre-kernel code. */ in db8500_prcmu_probe()
3036 prcmu_irq_thread_fn, IRQF_NO_SUSPEND, "prcmu", NULL); in db8500_prcmu_probe()
3038 pr_err("prcmu: Failed to allocate IRQ_DB8500_PRCMU1.\n"); in db8500_prcmu_probe()
3046 err = mfd_add_devices(&pdev->dev, 0, common_prcmu_devs, in db8500_prcmu_probe()
3049 pr_err("prcmu: Failed to add subdevices\n"); in db8500_prcmu_probe()
3054 if (!of_machine_is_compatible("st-ericsson,u8540")) { in db8500_prcmu_probe()
3055 err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs, in db8500_prcmu_probe()
3059 mfd_remove_devices(&pdev->dev); in db8500_prcmu_probe()
3060 pr_err("prcmu: Failed to add subdevices\n"); in db8500_prcmu_probe()
3065 err = db8500_prcmu_register_ab8500(&pdev->dev); in db8500_prcmu_probe()
3067 mfd_remove_devices(&pdev->dev); in db8500_prcmu_probe()
3068 pr_err("prcmu: Failed to add ab8500 subdevice\n"); in db8500_prcmu_probe()
3072 pr_info("DB8500 PRCMU initialized\n"); in db8500_prcmu_probe()
3076 { .compatible = "stericsson,db8500-prcmu"},
3082 .name = "db8500-prcmu",