Adds SRF calls into OMAP PM skeleton layer developed by Paul Walmsley. Signed-off-by: Rajendra Nayak <rnayak@xxxxxx> --- arch/arm/mach-omap2/Makefile | 1 arch/arm/plat-omap/Kconfig | 3 arch/arm/plat-omap/Makefile | 4 arch/arm/plat-omap/include/mach/resource.h | 1 arch/arm/plat-omap/omap-pm-srf.c | 342 +++++++++++++++++++++++++++++ 5 files changed, 350 insertions(+), 1 deletion(-) Index: linux-omap-2.6/arch/arm/plat-omap/omap-pm-srf.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-omap-2.6/arch/arm/plat-omap/omap-pm-srf.c 2008-10-16 19:20:35.000000000 +0530 @@ -0,0 +1,342 @@ +/* + * omap-pm-srf.c - OMAP power management interface implemented + * using Shared resource framework + * + * This code implements the OMAP power management interface to + * drivers, CPUIdle, CPUFreq, and DSP Bridge. It is strictly for + * debug/demonstration use, as it does nothing but printk() whenever a + * function is called (when DEBUG is defined, below) + * + * Copyright (C) 2008 Texas Instruments, Inc. + * Copyright (C) 2008 Nokia Corporation + * Paul Walmsley + * + * Interface developed by (in alphabetical order): + * Karthik Dasu, Tony Lindgren, Rajendra Nayak, Sakari Poussa, Veeramanikandan + * Raju, Anand Sawant, Igor Stoppa, Paul Walmsley, Richard Woodruff + */ + +#undef DEBUG + +#include <linux/init.h> +#include <linux/cpufreq.h> +#include <linux/device.h> + +#include <mach/omap-pm.h> +#include <mach/powerdomain.h> +#include <mach/resource.h> +/* TODO: Put this back in once tiocp layer is available */ +/* +#include <asm/arch/tiocp.h> +*/ + +static struct omap_opp *dsp_opps; +static struct omap_opp *mpu_opps; + +#define LAT_RES_POSTAMBLE "_latency" +#define MAX_LATENCY_RES_NAME 30 + +/** + * get_lat_res_name - gets the latency resource name given a power domain name + * @pwrdm_name: Name of the power domain. + * @lat_name: Buffer in which latency resource name is populated + * @size: Max size of the latency resource name + * + * Returns the latency resource name populated in lat_name. + */ +void get_lat_res_name(const char *pwrdm_name, char **lat_name, int size) +{ + strcpy(*lat_name, ""); + WARN_ON(strlen(pwrdm_name) + strlen(LAT_RES_POSTAMBLE) > size); + strcpy(*lat_name, pwrdm_name); + strcat(*lat_name, LAT_RES_POSTAMBLE); + return; +} + +/* + * Device-driver-originated constraints (via board-*.c files) + */ + +void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t) +{ + if (!dev || t < -1) { + WARN_ON(1); + return; + }; + + if (t == -1) { + pr_debug("OMAP PM: remove max MPU wakeup latency constraint: " + "dev %s\n", dev_name(dev)); + resource_release("mpu_latency", dev); + } else { + pr_debug("OMAP PM: add max MPU wakeup latency constraint: " + "dev %s, t = %ld usec\n", dev_name(dev), t); + resource_request("mpu_latency", dev, t); + } +} + +void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r) +{ + if (!dev || agent_id != OCP_INITIATOR_AGENT || + agent_id != OCP_TARGET_AGENT) { + WARN_ON(1); + return; + }; + + if (r == 0) + pr_debug("OMAP PM: remove min bus tput constraint: " + "dev %s for agent_id %d\n", dev_name(dev), agent_id); + else + pr_debug("OMAP PM: add min bus tput constraint: " + "dev %s for agent_id %d: rate %ld KiB\n", + dev_name(dev), agent_id, r); + + /* + * This code should model the interconnect and compute the + * required clock frequency, convert that to a VDD2 OPP ID, then + * set the VDD2 OPP appropriately. + * + * TI CDP code can call constraint_set here on the VDD2 OPP. + */ +} + +void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t) +{ + /* struct tiocp *tiocp_dev; */ + struct powerdomain *pwrdm_dev; + char *lat_res_name; + + if (!dev || t < -1) { + WARN_ON(1); + return; + }; + /* Look for the devices Power Domain */ + /* TODO: Put this back in once tiocp layer is available + tiocp_dev = container_of(dev, struct tiocp, dev); + pwrdm_dev = tiocp_dev->pwrdm; + */ + lat_res_name = kmalloc(MAX_LATENCY_RES_NAME, GFP_KERNEL); + if (!lat_res_name) { + printk(KERN_ERR "OMAP-PM: FATAL ERROR: kmalloc failed\n"); + return; + } + get_lat_res_name(pwrdm_dev->name, &lat_res_name, MAX_LATENCY_RES_NAME); + + if (t == -1) { + pr_debug("OMAP PM: remove max device latency constraint: " + "dev %s\n", dev_name(dev)); + resource_release(lat_res_name, dev); + } else { + pr_debug("OMAP PM: add max device latency constraint: " + "dev %s, t = %ld usec\n", dev_name(dev), t); + resource_request(lat_res_name, dev, t); + } + + kfree(lat_res_name); + return; +} + +void omap_pm_set_max_sdma_lat(struct device *dev, long t) +{ + if (!dev || t < -1) { + WARN_ON(1); + return; + }; + + if (t == -1) { + pr_debug("OMAP PM: remove max DMA latency constraint: " + "dev %s\n", dev_name(dev)); + resource_release("core_latency", dev); + } else { + pr_debug("OMAP PM: add max DMA latency constraint: " + "dev %s, t = %ld usec\n", dev_name(dev), t); + resource_request("core_latency", dev, t); + } +} + + +/* + * DSP Bridge-specific constraints + */ +const struct omap_opp *omap_pm_dsp_get_opp_table(void) +{ + pr_debug("OMAP PM: DSP request for OPP table\n"); + + /* + * Return DSP frequency table here: The final item in the + * array should have .rate = .opp_id = 0. + */ + + return NULL; +} + +void omap_pm_dsp_set_min_opp(u8 opp_id) +{ + if (opp_id == 0) { + WARN_ON(1); + return; + } + + pr_debug("OMAP PM: DSP requests minimum VDD1 OPP to be %d\n", opp_id); + + /* + * + * For l-o dev tree, our VDD1 clk is keyed on OPP ID, so we + * can just test to see which is higher, the CPU's desired OPP + * ID or the DSP's desired OPP ID, and use whichever is + * highest. + * + * In CDP12.14+, the VDD1 OPP custom clock that controls the DSP + * rate is keyed on MPU speed, not the OPP ID. So we need to + * map the OPP ID to the MPU speed for use with clk_set_rate() + * if it is higher than the current OPP clock rate. + * + */ +} + +u8 omap_pm_dsp_get_opp(void) +{ + pr_debug("OMAP PM: DSP requests current DSP OPP ID\n"); + + /* + * For l-o dev tree, call clk_get_rate() on VDD1 OPP clock + * + * CDP12.14+: + * Call clk_get_rate() on the OPP custom clock, map that to an + * OPP ID using the tables defined in board-*.c/chip-*.c files. + */ + + return 0; +} + +/* + * CPUFreq-originated constraint + * + * In the future, this should be handled by custom OPP clocktype + * functions. + */ + +struct cpufreq_frequency_table **omap_pm_cpu_get_freq_table(void) +{ + pr_debug("OMAP PM: CPUFreq request for frequency table\n"); + + /* + * Return CPUFreq frequency table here: loop over + * all VDD1 clkrates, pull out the mpu_ck frequencies, build + * table + */ + + return NULL; +} + +void omap_pm_cpu_set_freq(unsigned long f) +{ + if (f == 0) { + WARN_ON(1); + return; + } + + pr_debug("OMAP PM: CPUFreq requests CPU frequency to be set to %lu\n", + f); + + /* + * For l-o dev tree, determine whether MPU freq or DSP OPP id + * freq is higher. Find the OPP ID corresponding to the + * higher frequency. Call clk_round_rate() and clk_set_rate() + * on the OPP custom clock. + * + * CDP should just be able to set the VDD1 OPP clock rate here. + */ +} + +unsigned long omap_pm_cpu_get_freq(void) +{ + pr_debug("OMAP PM: CPUFreq requests current CPU frequency\n"); + + /* + * Call clk_get_rate() on the mpu_ck. + */ + + return 0; +} + +/* + * Device context loss tracking + */ + +int omap_pm_get_dev_context_loss_count(struct device *dev) +{ + if (!dev) { + WARN_ON(1); + return -EINVAL; + }; + + pr_debug("OMAP PM: returning context loss count for dev %s\n", + dev_name(dev)); + + /* + * Map the device to the powerdomain. Return the powerdomain + * off counter. + */ + + return 0; +} + +/* + * Powerdomain usecounting hooks + */ + +void omap_pm_pwrdm_active(struct powerdomain *pwrdm) +{ + if (!pwrdm) { + WARN_ON(1); + return; + }; + + pr_debug("OMAP PM: powerdomain %s is becoming active\n", pwrdm->name); + + /* + * CDP code apparently will need these for the enable_power_domain() + * and disable_power_domain() functions. + */ +} + +void omap_pm_pwrdm_inactive(struct powerdomain *pwrdm) +{ + if (!pwrdm) { + WARN_ON(1); + return; + }; + + pr_debug("OMAP PM: powerdomain %s is becoming inactive\n", + pwrdm->name); + + /* + * CDP code apparently will need these for the enable_power_domain() + * and disable_power_domain() functions. + */ +} + +/* + * Should be called before clk framework since clk fw will call + * omap_pm_pwrdm_{in,}active() + */ +int __init omap_pm_if_early_init(void) +{ + return 0; +} + +/* Must be called after clock framework is initialized */ +int __init omap_pm_if_init(struct omap_opp *mpu_opp_table, + struct omap_opp *dsp_opp_table) +{ + mpu_opps = mpu_opp_table; + dsp_opps = dsp_opp_table; + resource_init(resources_omap); + return 0; +} + +void omap_pm_if_exit(void) +{ + /* Deallocate CPUFreq frequency table here */ +} Index: linux-omap-2.6/arch/arm/mach-omap2/Makefile =================================================================== --- linux-omap-2.6.orig/arch/arm/mach-omap2/Makefile 2008-10-16 19:06:37.000000000 +0530 +++ linux-omap-2.6/arch/arm/mach-omap2/Makefile 2008-10-16 19:13:02.000000000 +0530 @@ -33,6 +33,7 @@ obj-$(CONFIG_OMAP_SMARTREFLEX) += smart # Clock framework obj-$(CONFIG_ARCH_OMAP2) += clock24xx.o obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o +obj-$(CONFIG_OMAP_PM_SRF) += resource34xx.o # DSP obj-$(CONFIG_OMAP_MMU_FWK) += mmu_mach.o Index: linux-omap-2.6/arch/arm/plat-omap/Kconfig =================================================================== --- linux-omap-2.6.orig/arch/arm/plat-omap/Kconfig 2008-10-08 10:51:48.000000000 +0530 +++ linux-omap-2.6/arch/arm/plat-omap/Kconfig 2008-10-16 19:13:02.000000000 +0530 @@ -258,6 +258,9 @@ config OMAP_PM_NONE config OMAP_PM_NOOP bool "No-op/debug PM layer" +config OMAP_PM_SRF + bool "PM layer implemented using SRF" + endchoice endif Index: linux-omap-2.6/arch/arm/plat-omap/Makefile =================================================================== --- linux-omap-2.6.orig/arch/arm/plat-omap/Makefile 2008-10-08 10:51:48.000000000 +0530 +++ linux-omap-2.6/arch/arm/plat-omap/Makefile 2008-10-16 19:13:02.000000000 +0530 @@ -29,4 +29,6 @@ obj-$(CONFIG_OMAP_MMU_FWK) += mmu.o # OMAP mailbox framework obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox.o -obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o \ No newline at end of file +obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o +obj-$(CONFIG_OMAP_PM_SRF) += omap-pm-srf.o \ + resource.o Index: linux-omap-2.6/arch/arm/plat-omap/include/mach/resource.h =================================================================== --- linux-omap-2.6.orig/arch/arm/plat-omap/include/mach/resource.h 2008-10-16 19:06:46.000000000 +0530 +++ linux-omap-2.6/arch/arm/plat-omap/include/mach/resource.h 2008-10-16 19:13:02.000000000 +0530 @@ -67,6 +67,7 @@ struct users_list { u8 usage; }; +extern struct shared_resource *resources_omap[]; /* Shared resource Framework API's */ void resource_init(struct shared_resource **resources); int resource_register(struct shared_resource *res); -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html