diff options
author | Jon Medhurst <tixy@linaro.org> | 2017-01-11 17:35:07 +0000 |
---|---|---|
committer | Jon Medhurst <tixy@linaro.org> | 2017-01-11 17:35:07 +0000 |
commit | 2b26e37a5c4c09d6605f7cf6972d87fc16ddc75e (patch) | |
tree | 7b3d33786cba5d2a1905ef2ed01dbc9f4e7a7541 | |
parent | fb269d0bd5092c3ae87f1330cfbf6c1434861ed6 (diff) | |
parent | 09a3b965c7e737ad26c15b11893f3e9b0c7f7cbe (diff) |
Merge branch '4.4-armlt' into lsk-4.4-armltlsk-4.4-armlt-20170111
-rw-r--r-- | arch/arm64/boot/dts/arm/juno-base.dtsi | 7 | ||||
-rw-r--r-- | drivers/firmware/Kconfig | 10 | ||||
-rw-r--r-- | drivers/firmware/Makefile | 1 | ||||
-rw-r--r-- | drivers/firmware/scpi_pm_domain.c | 163 | ||||
-rwxr-xr-x | drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_config_platform.h | 7 | ||||
-rwxr-xr-x | drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_runtime_pm.c | 28 | ||||
-rw-r--r-- | linaro/configs/vexpress64.conf | 5 |
7 files changed, 216 insertions, 5 deletions
diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi index a9f411891458..94567343e5da 100644 --- a/arch/arm64/boot/dts/arm/juno-base.dtsi +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi @@ -119,6 +119,12 @@ }; }; + scpi_devpd: scpi-power-domains { + compatible = "arm,scpi-power-domains"; + num-domains = <2>; + #power-domain-cells = <1>; + }; + scpi_sensors0: sensors { compatible = "arm,scpi-sensors"; #thermal-sensor-cells = <1>; @@ -369,6 +375,7 @@ interrupt-names = "JOB", "MMU", "GPU"; clocks = <&scpi_dvfs 2>; clock-names = "clk_mali"; + power-domains = <&scpi_devpd 1>; power_model { compatible = "arm,mali-simple-power-model"; voltage = <800>; diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index a6a135dfee9d..14bdb5a538b9 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -27,6 +27,16 @@ config ARM_SCPI_PROTOCOL This protocol library provides interface for all the client drivers making use of the features offered by the SCP. +config ARM_SCPI_POWER_DOMAIN + tristate "SCPI power domain driver" + depends on ARM_SCPI_PROTOCOL || COMPILE_TEST + default y + select PM_GENERIC_DOMAINS if PM + select PM_GENERIC_DOMAINS_OF if PM + help + This enables support for the SCPI power domains which can be + enabled or disabled via the SCP firmware + config ARM_SCPI_PROTOCOL_TEST tristate "Test code for SCPI Message Protocol" default ARM_SCPI_PROTOCOL diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile index 864babe21d4b..af4e23c4c883 100644 --- a/drivers/firmware/Makefile +++ b/drivers/firmware/Makefile @@ -3,6 +3,7 @@ # obj-$(CONFIG_ARM_PSCI_FW) += psci.o obj-$(CONFIG_ARM_SCPI_PROTOCOL) += arm_scpi.o +obj-$(CONFIG_ARM_SCPI_POWER_DOMAIN) += scpi_pm_domain.o obj-$(CONFIG_ARM_SCPI_PROTOCOL_TEST) += arm_scpi_test.o obj-$(CONFIG_DMI) += dmi_scan.o obj-$(CONFIG_DMI_SYSFS) += dmi-sysfs.o diff --git a/drivers/firmware/scpi_pm_domain.c b/drivers/firmware/scpi_pm_domain.c new file mode 100644 index 000000000000..f395dec27113 --- /dev/null +++ b/drivers/firmware/scpi_pm_domain.c @@ -0,0 +1,163 @@ +/* + * SCPI Generic power domain support. + * + * Copyright (C) 2016 ARM Ltd. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/err.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of_platform.h> +#include <linux/pm_domain.h> +#include <linux/scpi_protocol.h> + +struct scpi_pm_domain { + struct generic_pm_domain genpd; + struct scpi_ops *ops; + u32 domain; + char name[30]; +}; + +/* + * These device power state values are not well-defined in the specification. + * In case, different implementations use different values, we can make these + * specific to compatibles rather than getting these values from device tree. + */ +enum scpi_power_domain_state { + SCPI_PD_STATE_ON = 0, + SCPI_PD_STATE_OFF = 3, +}; + +#define to_scpi_pd(gpd) container_of(gpd, struct scpi_pm_domain, genpd) + +static int scpi_pd_power(struct scpi_pm_domain *pd, bool power_on) +{ + int ret; + enum scpi_power_domain_state state; + + if (power_on) + state = SCPI_PD_STATE_ON; + else + state = SCPI_PD_STATE_OFF; + + ret = pd->ops->device_set_power_state(pd->domain, state); + if (ret) + return ret; + + return !(state == pd->ops->device_get_power_state(pd->domain)); +} + +static int scpi_pd_power_on(struct generic_pm_domain *domain) +{ + struct scpi_pm_domain *pd = to_scpi_pd(domain); + + return scpi_pd_power(pd, true); +} + +static int scpi_pd_power_off(struct generic_pm_domain *domain) +{ + struct scpi_pm_domain *pd = to_scpi_pd(domain); + + return scpi_pd_power(pd, false); +} + +static int scpi_pm_domain_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct scpi_pm_domain *scpi_pd; + struct genpd_onecell_data *scpi_pd_data; + struct generic_pm_domain **domains; + struct scpi_ops *scpi_ops; + int ret, num_domains, i; + + scpi_ops = get_scpi_ops(); + if (!scpi_ops) + return -EPROBE_DEFER; + + if (!np) { + dev_err(dev, "device tree node not found\n"); + return -ENODEV; + } + + if (!scpi_ops->device_set_power_state || + !scpi_ops->device_get_power_state) { + dev_err(dev, "power domains not supported in the firmware\n"); + return -ENODEV; + } + + ret = of_property_read_u32(np, "num-domains", &num_domains); + if (ret) { + dev_err(dev, "number of domains not found\n"); + return -EINVAL; + } + + scpi_pd = devm_kcalloc(dev, num_domains, sizeof(*scpi_pd), GFP_KERNEL); + if (!scpi_pd) + return -ENOMEM; + + scpi_pd_data = devm_kzalloc(dev, sizeof(*scpi_pd_data), GFP_KERNEL); + if (!scpi_pd_data) + return -ENOMEM; + + domains = devm_kcalloc(dev, num_domains, sizeof(*domains), GFP_KERNEL); + if (!domains) + return -ENOMEM; + + for (i = 0; i < num_domains; i++, scpi_pd++) { + domains[i] = &scpi_pd->genpd; + + scpi_pd->domain = i; + scpi_pd->ops = scpi_ops; + sprintf(scpi_pd->name, "%s.%d", np->name, i); + scpi_pd->genpd.name = scpi_pd->name; + scpi_pd->genpd.power_off = scpi_pd_power_off; + scpi_pd->genpd.power_on = scpi_pd_power_on; + + /* + * Treat all power domains as off at boot. + * + * The SCP firmware itself may have switched on some domains, + * but for reference counting purpose, keep it this way. + */ + pm_genpd_init(&scpi_pd->genpd, NULL, true); + } + + scpi_pd_data->domains = domains; + scpi_pd_data->num_domains = num_domains; + + of_genpd_add_provider_onecell(np, scpi_pd_data); + + return 0; +} + +static const struct of_device_id scpi_power_domain_ids[] = { + { .compatible = "arm,scpi-power-domains", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, scpi_power_domain_ids); + +static struct platform_driver scpi_power_domain_driver = { + .driver = { + .name = "scpi_power_domain", + .of_match_table = scpi_power_domain_ids, + }, + .probe = scpi_pm_domain_probe, +}; +module_platform_driver(scpi_power_domain_driver); + +MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>"); +MODULE_DESCRIPTION("ARM SCPI power domain driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_config_platform.h b/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_config_platform.h index d4813f7f8a35..6a38e5657b9d 100755 --- a/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_config_platform.h +++ b/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_config_platform.h @@ -78,3 +78,10 @@ extern struct kbase_pm_callback_conf pm_callbacks; * Attached value: pointer to @ref kbase_secure_ops */ #define SECURE_CALLBACKS (NULL) + +/** + *Autosuspend delay + * + *The delay time (in milliseconds) to be used for autosuspend + */ +#define AUTO_SUSPEND_DELAY (500) diff --git a/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_runtime_pm.c b/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_runtime_pm.c index aa4376afd3ba..5549ad2aeff2 100755 --- a/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_runtime_pm.c +++ b/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_runtime_pm.c @@ -19,34 +19,54 @@ #include <mali_kbase_defs.h> #include <linux/pm_runtime.h> #include <linux/suspend.h> +#include "mali_kbase_config_platform.h" static int pm_callback_power_on(struct kbase_device *kbdev) { - int ret; + int ret = 1; /* Assume GPU has been powered off */ + int error; dev_dbg(kbdev->dev, "pm_callback_power_on %p\n", (void *)kbdev->dev->pm_domain); - ret = pm_runtime_get_sync(kbdev->dev); + error = pm_runtime_get_sync(kbdev->dev); + if (error < 0){ + dev_err(kbdev->dev, + "failed to runtime resume device: %d\n", + ret); + return ret; + } else if (error == 1) { + /* + * Let core know that the chip has not been + * powered off, so we can save on re-initialization. + */ + ret = 0; + } dev_dbg(kbdev->dev, "pm_runtime_get returned %d\n", ret); - return 1; + return ret; } static void pm_callback_power_off(struct kbase_device *kbdev) { dev_dbg(kbdev->dev, "pm_callback_power_off\n"); + pm_runtime_mark_last_busy(kbdev->dev); pm_runtime_put_autosuspend(kbdev->dev); } int kbase_device_runtime_init(struct kbase_device *kbdev) { dev_dbg(kbdev->dev, "kbase_device_runtime_init\n"); + + pm_runtime_set_autosuspend_delay(kbdev->dev, AUTO_SUSPEND_DELAY); + pm_runtime_use_autosuspend(kbdev->dev); + + pm_runtime_set_active(kbdev->dev); pm_runtime_enable(kbdev->dev); - return 0; + return !(pm_runtime_enabled(kbdev->dev) == true); } void kbase_device_runtime_disable(struct kbase_device *kbdev) diff --git a/linaro/configs/vexpress64.conf b/linaro/configs/vexpress64.conf index 0395a2bb32e0..8b2f6714104b 100644 --- a/linaro/configs/vexpress64.conf +++ b/linaro/configs/vexpress64.conf @@ -52,6 +52,7 @@ CONFIG_USB_OHCI_HCD=y CONFIG_MAILBOX=y CONFIG_ARM_MHU=y CONFIG_ARM_SCPI_PROTOCOL=y +CONFIG_ARM_SCPI_POWER_DOMAIN=y CONFIG_SENSORS_ARM_SCPI=y CONFIG_COMMON_CLK_SCPI=y CONFIG_ARM_SCPI_CPUFREQ=y @@ -82,6 +83,8 @@ CONFIG_ARM_CPUIDLE=y CONFIG_TEE=y CONFIG_OPTEE=y CONFIG_DEVMEM=y +CONFIG_PM_DEBUG=y +CONFIG_PM_RUNTIME=y CONFIG_DRM=y CONFIG_DRM_ARM=y CONFIG_DRM_HDLCD=y @@ -113,10 +116,10 @@ CONFIG_PM_DEVFREQ=y CONFIG_DEVFREQ_THERMAL=y CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y CONFIG_DEVFREQ_GOV_PERFORMANCE=y -CONFIG_MALI_DEVFREQ=y CONFIG_MALI_MIDGARD=y CONFIG_MALI_EXPERT=y CONFIG_MALI_PLATFORM_FAKE=y CONFIG_MALI_PLATFORM_THIRDPARTY=y CONFIG_MALI_PLATFORM_THIRDPARTY_NAME="juno_soc" +CONFIG_MALI_PLATFORM_DEVICETREE=y CONFIG_ION_DUMMY=y |