brintos

brintos / linux-shallow public Read only

0
0
Text · 14.0 KiB · 8169885 Raw
601 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * AM33XX Power Management Routines4 *5 * Copyright (C) 2012-2018 Texas Instruments Incorporated - http://www.ti.com/6 *	Vaibhav Bedia, Dave Gerlach7 */8 9#include <linux/clk.h>10#include <linux/cpu.h>11#include <linux/err.h>12#include <linux/genalloc.h>13#include <linux/kernel.h>14#include <linux/init.h>15#include <linux/io.h>16#include <linux/module.h>17#include <linux/nvmem-consumer.h>18#include <linux/of.h>19#include <linux/of_address.h>20#include <linux/platform_data/pm33xx.h>21#include <linux/platform_device.h>22#include <linux/pm_runtime.h>23#include <linux/rtc.h>24#include <linux/rtc/rtc-omap.h>25#include <linux/sizes.h>26#include <linux/sram.h>27#include <linux/suspend.h>28#include <linux/ti-emif-sram.h>29#include <linux/wkup_m3_ipc.h>30 31#include <asm/proc-fns.h>32#include <asm/suspend.h>33#include <asm/system_misc.h>34 35#define AMX3_PM_SRAM_SYMBOL_OFFSET(sym) ((unsigned long)(sym) - \36					 (unsigned long)pm_sram->do_wfi)37 38#define RTC_SCRATCH_RESUME_REG	039#define RTC_SCRATCH_MAGIC_REG	140#define RTC_REG_BOOT_MAGIC	0x8cd0 /* RTC */41#define GIC_INT_SET_PENDING_BASE 0x20042#define AM43XX_GIC_DIST_BASE	0x4824100043 44static void __iomem *rtc_base_virt;45static struct clk *rtc_fck;46static u32 rtc_magic_val;47 48static int (*am33xx_do_wfi_sram)(unsigned long unused);49static phys_addr_t am33xx_do_wfi_sram_phys;50 51static struct gen_pool *sram_pool, *sram_pool_data;52static unsigned long ocmcram_location, ocmcram_location_data;53 54static struct rtc_device *omap_rtc;55static void __iomem *gic_dist_base;56 57static struct am33xx_pm_platform_data *pm_ops;58static struct am33xx_pm_sram_addr *pm_sram;59 60static struct device *pm33xx_dev;61static struct wkup_m3_ipc *m3_ipc;62 63#ifdef CONFIG_SUSPEND64static int rtc_only_idle;65static int retrigger_irq;66static unsigned long suspend_wfi_flags;67 68static struct wkup_m3_wakeup_src wakeup_src = {.irq_nr = 0,69	.src = "Unknown",70};71 72static struct wkup_m3_wakeup_src rtc_alarm_wakeup = {73	.irq_nr = 108, .src = "RTC Alarm",74};75 76static struct wkup_m3_wakeup_src rtc_ext_wakeup = {77	.irq_nr = 0, .src = "Ext wakeup",78};79#endif80 81static u32 sram_suspend_address(unsigned long addr)82{83	return ((unsigned long)am33xx_do_wfi_sram +84		AMX3_PM_SRAM_SYMBOL_OFFSET(addr));85}86 87static int am33xx_push_sram_idle(void)88{89	struct am33xx_pm_ro_sram_data ro_sram_data;90	int ret;91	u32 table_addr, ro_data_addr;92	void *copy_addr;93 94	ro_sram_data.amx3_pm_sram_data_virt = ocmcram_location_data;95	ro_sram_data.amx3_pm_sram_data_phys =96		gen_pool_virt_to_phys(sram_pool_data, ocmcram_location_data);97	ro_sram_data.rtc_base_virt = rtc_base_virt;98 99	/* Save physical address to calculate resume offset during pm init */100	am33xx_do_wfi_sram_phys = gen_pool_virt_to_phys(sram_pool,101							ocmcram_location);102 103	am33xx_do_wfi_sram = sram_exec_copy(sram_pool, (void *)ocmcram_location,104					    pm_sram->do_wfi,105					    *pm_sram->do_wfi_sz);106	if (!am33xx_do_wfi_sram) {107		dev_err(pm33xx_dev,108			"PM: %s: am33xx_do_wfi copy to sram failed\n",109			__func__);110		return -ENODEV;111	}112 113	table_addr =114		sram_suspend_address((unsigned long)pm_sram->emif_sram_table);115	ret = ti_emif_copy_pm_function_table(sram_pool, (void *)table_addr);116	if (ret) {117		dev_dbg(pm33xx_dev,118			"PM: %s: EMIF function copy failed\n", __func__);119		return -EPROBE_DEFER;120	}121 122	ro_data_addr =123		sram_suspend_address((unsigned long)pm_sram->ro_sram_data);124	copy_addr = sram_exec_copy(sram_pool, (void *)ro_data_addr,125				   &ro_sram_data,126				   sizeof(ro_sram_data));127	if (!copy_addr) {128		dev_err(pm33xx_dev,129			"PM: %s: ro_sram_data copy to sram failed\n",130			__func__);131		return -ENODEV;132	}133 134	return 0;135}136 137static int am33xx_do_sram_idle(u32 wfi_flags)138{139	if (!m3_ipc || !pm_ops)140		return 0;141 142	if (wfi_flags & WFI_FLAG_WAKE_M3)143		m3_ipc->ops->prepare_low_power(m3_ipc, WKUP_M3_IDLE);144 145	return pm_ops->cpu_suspend(am33xx_do_wfi_sram, wfi_flags);146}147 148static int __init am43xx_map_gic(void)149{150	gic_dist_base = ioremap(AM43XX_GIC_DIST_BASE, SZ_4K);151 152	if (!gic_dist_base)153		return -ENOMEM;154 155	return 0;156}157 158#ifdef CONFIG_SUSPEND159static struct wkup_m3_wakeup_src rtc_wake_src(void)160{161	u32 i;162 163	i = __raw_readl(rtc_base_virt + 0x44) & 0x40;164 165	if (i) {166		retrigger_irq = rtc_alarm_wakeup.irq_nr;167		return rtc_alarm_wakeup;168	}169 170	retrigger_irq = rtc_ext_wakeup.irq_nr;171 172	return rtc_ext_wakeup;173}174 175static int am33xx_rtc_only_idle(unsigned long wfi_flags)176{177	omap_rtc_power_off_program(&omap_rtc->dev);178	am33xx_do_wfi_sram(wfi_flags);179	return 0;180}181 182/*183 * Note that the RTC module clock must be re-enabled only for rtc+ddr suspend.184 * And looks like the module can stay in SYSC_IDLE_SMART_WKUP mode configured185 * by the interconnect code just fine for both rtc+ddr suspend and retention186 * suspend.187 */188static int am33xx_pm_suspend(suspend_state_t suspend_state)189{190	int i, ret = 0;191 192	if (suspend_state == PM_SUSPEND_MEM &&193	    pm_ops->check_off_mode_enable()) {194		ret = clk_prepare_enable(rtc_fck);195		if (ret) {196			dev_err(pm33xx_dev, "Failed to enable clock: %i\n", ret);197			return ret;198		}199 200		pm_ops->save_context();201		suspend_wfi_flags |= WFI_FLAG_RTC_ONLY;202		clk_save_context();203		ret = pm_ops->soc_suspend(suspend_state, am33xx_rtc_only_idle,204					  suspend_wfi_flags);205 206		suspend_wfi_flags &= ~WFI_FLAG_RTC_ONLY;207		dev_info(pm33xx_dev, "Entering RTC Only mode with DDR in self-refresh\n");208 209		if (!ret) {210			clk_restore_context();211			pm_ops->restore_context();212			m3_ipc->ops->set_rtc_only(m3_ipc);213			am33xx_push_sram_idle();214		}215	} else {216		ret = pm_ops->soc_suspend(suspend_state, am33xx_do_wfi_sram,217					  suspend_wfi_flags);218	}219 220	if (ret) {221		dev_err(pm33xx_dev, "PM: Kernel suspend failure\n");222	} else {223		i = m3_ipc->ops->request_pm_status(m3_ipc);224 225		switch (i) {226		case 0:227			dev_info(pm33xx_dev,228				 "PM: Successfully put all powerdomains to target state\n");229			break;230		case 1:231			dev_err(pm33xx_dev,232				"PM: Could not transition all powerdomains to target state\n");233			ret = -1;234			break;235		default:236			dev_err(pm33xx_dev,237				"PM: CM3 returned unknown result = %d\n", i);238			ret = -1;239		}240 241		/* print the wakeup reason */242		if (rtc_only_idle) {243			wakeup_src = rtc_wake_src();244			pr_info("PM: Wakeup source %s\n", wakeup_src.src);245		} else {246			pr_info("PM: Wakeup source %s\n",247				m3_ipc->ops->request_wake_src(m3_ipc));248		}249	}250 251	if (suspend_state == PM_SUSPEND_MEM && pm_ops->check_off_mode_enable())252		clk_disable_unprepare(rtc_fck);253 254	return ret;255}256 257static int am33xx_pm_enter(suspend_state_t suspend_state)258{259	int ret = 0;260 261	switch (suspend_state) {262	case PM_SUSPEND_MEM:263	case PM_SUSPEND_STANDBY:264		ret = am33xx_pm_suspend(suspend_state);265		break;266	default:267		ret = -EINVAL;268	}269 270	return ret;271}272 273static int am33xx_pm_begin(suspend_state_t state)274{275	int ret = -EINVAL;276	struct nvmem_device *nvmem;277 278	if (state == PM_SUSPEND_MEM && pm_ops->check_off_mode_enable()) {279		nvmem = devm_nvmem_device_get(&omap_rtc->dev,280					      "omap_rtc_scratch0");281		if (!IS_ERR(nvmem))282			nvmem_device_write(nvmem, RTC_SCRATCH_MAGIC_REG * 4, 4,283					   (void *)&rtc_magic_val);284		rtc_only_idle = 1;285	} else {286		rtc_only_idle = 0;287	}288 289	pm_ops->begin_suspend();290 291	switch (state) {292	case PM_SUSPEND_MEM:293		ret = m3_ipc->ops->prepare_low_power(m3_ipc, WKUP_M3_DEEPSLEEP);294		break;295	case PM_SUSPEND_STANDBY:296		ret = m3_ipc->ops->prepare_low_power(m3_ipc, WKUP_M3_STANDBY);297		break;298	}299 300	return ret;301}302 303static void am33xx_pm_end(void)304{305	u32 val = 0;306	struct nvmem_device *nvmem;307 308	nvmem = devm_nvmem_device_get(&omap_rtc->dev, "omap_rtc_scratch0");309	if (IS_ERR(nvmem))310		return;311 312	m3_ipc->ops->finish_low_power(m3_ipc);313	if (rtc_only_idle) {314		if (retrigger_irq) {315			/*316			 * 32 bits of Interrupt Set-Pending correspond to 32317			 * 32 interrupts. Compute the bit offset of the318			 * Interrupt and set that particular bit319			 * Compute the register offset by dividing interrupt320			 * number by 32 and mutiplying by 4321			 */322			writel_relaxed(1 << (retrigger_irq & 31),323				       gic_dist_base + GIC_INT_SET_PENDING_BASE324				       + retrigger_irq / 32 * 4);325		}326 327		nvmem_device_write(nvmem, RTC_SCRATCH_MAGIC_REG * 4, 4,328				   (void *)&val);329	}330 331	rtc_only_idle = 0;332 333	pm_ops->finish_suspend();334}335 336static int am33xx_pm_valid(suspend_state_t state)337{338	switch (state) {339	case PM_SUSPEND_STANDBY:340	case PM_SUSPEND_MEM:341		return 1;342	default:343		return 0;344	}345}346 347static const struct platform_suspend_ops am33xx_pm_ops = {348	.begin		= am33xx_pm_begin,349	.end		= am33xx_pm_end,350	.enter		= am33xx_pm_enter,351	.valid		= am33xx_pm_valid,352};353#endif /* CONFIG_SUSPEND */354 355static void am33xx_pm_set_ipc_ops(void)356{357	u32 resume_address;358	int temp;359 360	temp = ti_emif_get_mem_type();361	if (temp < 0) {362		dev_err(pm33xx_dev, "PM: Cannot determine memory type, no PM available\n");363		return;364	}365	m3_ipc->ops->set_mem_type(m3_ipc, temp);366 367	/* Physical resume address to be used by ROM code */368	resume_address = am33xx_do_wfi_sram_phys +369			 *pm_sram->resume_offset + 0x4;370 371	m3_ipc->ops->set_resume_address(m3_ipc, (void *)resume_address);372}373 374static void am33xx_pm_free_sram(void)375{376	gen_pool_free(sram_pool, ocmcram_location, *pm_sram->do_wfi_sz);377	gen_pool_free(sram_pool_data, ocmcram_location_data,378		      sizeof(struct am33xx_pm_ro_sram_data));379}380 381/*382 * Push the minimal suspend-resume code to SRAM383 */384static int am33xx_pm_alloc_sram(void)385{386	struct device_node *np __free(device_node) =387			of_find_compatible_node(NULL, NULL, "ti,omap3-mpu");388 389	if (!np) {390		np = of_find_compatible_node(NULL, NULL, "ti,omap4-mpu");391		if (!np)392			return dev_err_probe(pm33xx_dev, -ENODEV,393					     "PM: %s: Unable to find device node for mpu\n",394					     __func__);395	}396 397	sram_pool = of_gen_pool_get(np, "pm-sram", 0);398	if (!sram_pool)399		return dev_err_probe(pm33xx_dev, -ENODEV,400				     "PM: %s: Unable to get sram pool for ocmcram\n",401				     __func__);402 403	sram_pool_data = of_gen_pool_get(np, "pm-sram", 1);404	if (!sram_pool_data)405		return dev_err_probe(pm33xx_dev, -ENODEV,406				     "PM: %s: Unable to get sram data pool for ocmcram\n",407				     __func__);408 409	ocmcram_location = gen_pool_alloc(sram_pool, *pm_sram->do_wfi_sz);410	if (!ocmcram_location)411		return dev_err_probe(pm33xx_dev, -ENOMEM,412				     "PM: %s: Unable to allocate memory from ocmcram\n",413				     __func__);414 415	ocmcram_location_data = gen_pool_alloc(sram_pool_data,416					       sizeof(struct emif_regs_amx3));417	if (!ocmcram_location_data) {418		gen_pool_free(sram_pool, ocmcram_location, *pm_sram->do_wfi_sz);419		return dev_err_probe(pm33xx_dev, -ENOMEM,420				     "PM: Unable to allocate memory from ocmcram\n");421	}422 423	return 0;424}425 426static int am33xx_pm_rtc_setup(void)427{428	struct device_node *np;429	unsigned long val = 0;430	struct nvmem_device *nvmem;431	int error;432 433	np = of_find_node_by_name(NULL, "rtc");434 435	if (of_device_is_available(np)) {436		/* RTC interconnect target module clock */437		rtc_fck = of_clk_get_by_name(np->parent, "fck");438		if (IS_ERR(rtc_fck))439			return PTR_ERR(rtc_fck);440 441		rtc_base_virt = of_iomap(np, 0);442		if (!rtc_base_virt) {443			pr_warn("PM: could not iomap rtc\n");444			error = -ENODEV;445			goto err_clk_put;446		}447 448		omap_rtc = rtc_class_open("rtc0");449		if (!omap_rtc) {450			pr_warn("PM: rtc0 not available\n");451			error = -EPROBE_DEFER;452			goto err_iounmap;453		}454 455		nvmem = devm_nvmem_device_get(&omap_rtc->dev,456					      "omap_rtc_scratch0");457		if (!IS_ERR(nvmem)) {458			nvmem_device_read(nvmem, RTC_SCRATCH_MAGIC_REG * 4,459					  4, (void *)&rtc_magic_val);460			if ((rtc_magic_val & 0xffff) != RTC_REG_BOOT_MAGIC)461				pr_warn("PM: bootloader does not support rtc-only!\n");462 463			nvmem_device_write(nvmem, RTC_SCRATCH_MAGIC_REG * 4,464					   4, (void *)&val);465			val = pm_sram->resume_address;466			nvmem_device_write(nvmem, RTC_SCRATCH_RESUME_REG * 4,467					   4, (void *)&val);468		}469	} else {470		pr_warn("PM: no-rtc available, rtc-only mode disabled.\n");471	}472 473	return 0;474 475err_iounmap:476	iounmap(rtc_base_virt);477err_clk_put:478	clk_put(rtc_fck);479 480	return error;481}482 483static int am33xx_pm_probe(struct platform_device *pdev)484{485	struct device *dev = &pdev->dev;486	int ret;487 488	if (!of_machine_is_compatible("ti,am33xx") &&489	    !of_machine_is_compatible("ti,am43"))490		return -ENODEV;491 492	pm_ops = dev->platform_data;493	if (!pm_ops) {494		dev_err(dev, "PM: Cannot get core PM ops!\n");495		return -ENODEV;496	}497 498	ret = am43xx_map_gic();499	if (ret) {500		pr_err("PM: Could not ioremap GIC base\n");501		return ret;502	}503 504	pm_sram = pm_ops->get_sram_addrs();505	if (!pm_sram) {506		dev_err(dev, "PM: Cannot get PM asm function addresses!!\n");507		return -ENODEV;508	}509 510	m3_ipc = wkup_m3_ipc_get();511	if (!m3_ipc) {512		pr_err("PM: Cannot get wkup_m3_ipc handle\n");513		return -EPROBE_DEFER;514	}515 516	pm33xx_dev = dev;517 518	ret = am33xx_pm_alloc_sram();519	if (ret)520		goto err_wkup_m3_ipc_put;521 522	ret = am33xx_pm_rtc_setup();523	if (ret)524		goto err_free_sram;525 526	ret = am33xx_push_sram_idle();527	if (ret)528		goto err_unsetup_rtc;529 530	am33xx_pm_set_ipc_ops();531 532#ifdef CONFIG_SUSPEND533	suspend_set_ops(&am33xx_pm_ops);534 535	/*536	 * For a system suspend we must flush the caches, we want537	 * the DDR in self-refresh, we want to save the context538	 * of the EMIF, and we want the wkup_m3 to handle low-power539	 * transition.540	 */541	suspend_wfi_flags |= WFI_FLAG_FLUSH_CACHE;542	suspend_wfi_flags |= WFI_FLAG_SELF_REFRESH;543	suspend_wfi_flags |= WFI_FLAG_SAVE_EMIF;544	suspend_wfi_flags |= WFI_FLAG_WAKE_M3;545#endif /* CONFIG_SUSPEND */546 547	pm_runtime_enable(dev);548	ret = pm_runtime_resume_and_get(dev);549	if (ret < 0)550		goto err_pm_runtime_disable;551 552	ret = pm_ops->init(am33xx_do_sram_idle);553	if (ret) {554		dev_err(dev, "Unable to call core pm init!\n");555		ret = -ENODEV;556		goto err_pm_runtime_put;557	}558 559	return 0;560 561err_pm_runtime_put:562	pm_runtime_put_sync(dev);563err_pm_runtime_disable:564	pm_runtime_disable(dev);565err_unsetup_rtc:566	iounmap(rtc_base_virt);567	clk_put(rtc_fck);568err_free_sram:569	am33xx_pm_free_sram();570	pm33xx_dev = NULL;571err_wkup_m3_ipc_put:572	wkup_m3_ipc_put(m3_ipc);573	return ret;574}575 576static void am33xx_pm_remove(struct platform_device *pdev)577{578	pm_runtime_put_sync(&pdev->dev);579	pm_runtime_disable(&pdev->dev);580	if (pm_ops->deinit)581		pm_ops->deinit();582	suspend_set_ops(NULL);583	wkup_m3_ipc_put(m3_ipc);584	am33xx_pm_free_sram();585	iounmap(rtc_base_virt);586	clk_put(rtc_fck);587}588 589static struct platform_driver am33xx_pm_driver = {590	.driver = {591		.name   = "pm33xx",592	},593	.probe = am33xx_pm_probe,594	.remove_new = am33xx_pm_remove,595};596module_platform_driver(am33xx_pm_driver);597 598MODULE_ALIAS("platform:pm33xx");599MODULE_LICENSE("GPL v2");600MODULE_DESCRIPTION("am33xx power management driver");601