From 721cabf6c6600dbe689ee2782bc087270e97e652 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 17 Feb 2017 20:02:44 +0100 Subject: soc: imx: move PGC handling to a new GPC driver This is an almost complete re-write of the previous GPC power gating control code found in the IMX architecture code. It supports both the old and the new DT binding, allowing more domains to be added later and generally makes the driver easier to extend, while keeping compatibility with existing DTBs. As the result, all functionality regarding the power gating controller gets removed from the IMX architecture GPC driver. It keeps only the IRQ controller code in the architecture, as this is closely coupled to the CPU idle implementation. Signed-off-by: Lucas Stach Signed-off-by: Shawn Guo --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) (limited to 'MAINTAINERS') diff --git a/MAINTAINERS b/MAINTAINERS index c265a5fe4848..fa6a6792ea56 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1266,6 +1266,7 @@ F: arch/arm/mach-mxs/ F: arch/arm/boot/dts/imx* F: arch/arm/configs/imx*_defconfig F: drivers/clk/imx/ +F: drivers/soc/imx/ F: include/soc/imx/ ARM/FREESCALE VYBRID ARM ARCHITECTURE -- cgit v1.2.3-59-g8ed1b From 843fc75af8f5fb690656d1529b250584d8923d2c Mon Sep 17 00:00:00 2001 From: Thor Thayer Date: Wed, 22 Feb 2017 11:10:16 -0600 Subject: dt-bindings: reset: a10sr: Add Arria10 SR Reset Controller offsets The Arria10 System Resource Chip reset controller handles the Arria10 peripheral PHYs. This patch adds the offsets for these PHYs. Signed-off-by: Thor Thayer Signed-off-by: Philipp Zabel --- MAINTAINERS | 1 + include/dt-bindings/reset/altr,rst-mgr-a10sr.h | 33 ++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 include/dt-bindings/reset/altr,rst-mgr-a10sr.h (limited to 'MAINTAINERS') diff --git a/MAINTAINERS b/MAINTAINERS index c265a5fe4848..27558d547f12 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -654,6 +654,7 @@ S: Maintained F: drivers/gpio/gpio-altera-a10sr.c F: drivers/mfd/altera-a10sr.c F: include/linux/mfd/altera-a10sr.h +F: include/dt-bindings/reset/altr,rst-mgr-a10sr.h ALTERA TRIPLE SPEED ETHERNET DRIVER M: Vince Bridgers diff --git a/include/dt-bindings/reset/altr,rst-mgr-a10sr.h b/include/dt-bindings/reset/altr,rst-mgr-a10sr.h new file mode 100644 index 000000000000..9855925e5256 --- /dev/null +++ b/include/dt-bindings/reset/altr,rst-mgr-a10sr.h @@ -0,0 +1,33 @@ +/* + * Copyright Intel Corporation (C) 2017. All Rights Reserved + * + * 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 . + * + * Reset binding definitions for Altera Arria10 MAX5 System Resource Chip + * + * Adapted from altr,rst-mgr-a10.h + */ + +#ifndef _DT_BINDINGS_RESET_ALTR_RST_MGR_A10SR_H +#define _DT_BINDINGS_RESET_ALTR_RST_MGR_A10SR_H + +/* Peripheral PHY resets */ +#define A10SR_RESET_ENET_HPS 0 +#define A10SR_RESET_PCIE 1 +#define A10SR_RESET_FILE 2 +#define A10SR_RESET_BQSPI 3 +#define A10SR_RESET_USB 4 + +#define A10SR_RESET_NUM 5 + +#endif -- cgit v1.2.3-59-g8ed1b From 627006820268f92b62b2bde486c76ccd0fadb671 Mon Sep 17 00:00:00 2001 From: Thor Thayer Date: Wed, 22 Feb 2017 11:10:17 -0600 Subject: reset: Add Altera Arria10 SR Reset Controller This patch adds the reset controller functionality for Peripheral PHYs to the Arria10 System Resource Chip. Signed-off-by: Thor Thayer Signed-off-by: Philipp Zabel --- MAINTAINERS | 1 + drivers/reset/Kconfig | 7 +++ drivers/reset/Makefile | 1 + drivers/reset/reset-a10sr.c | 138 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 147 insertions(+) create mode 100644 drivers/reset/reset-a10sr.c (limited to 'MAINTAINERS') diff --git a/MAINTAINERS b/MAINTAINERS index 27558d547f12..0f37c5a5e1c9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -653,6 +653,7 @@ M: Thor Thayer S: Maintained F: drivers/gpio/gpio-altera-a10sr.c F: drivers/mfd/altera-a10sr.c +F: drivers/reset/reset-a10sr.c F: include/linux/mfd/altera-a10sr.h F: include/dt-bindings/reset/altr,rst-mgr-a10sr.h diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index c9e74592742b..d21c07ccc94e 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -14,6 +14,13 @@ menuconfig RESET_CONTROLLER if RESET_CONTROLLER +config RESET_A10SR + tristate "Altera Arria10 System Resource Reset" + depends on MFD_ALTERA_A10SR + help + This option enables support for the external reset functions for + peripheral PHYs on the Altera Arria10 System Resource Chip. + config RESET_ATH79 bool "AR71xx Reset Driver" if COMPILE_TEST default ATH79 diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index c7ac1d6908ee..02a74db94339 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -2,6 +2,7 @@ obj-y += core.o obj-y += hisilicon/ obj-$(CONFIG_ARCH_STI) += sti/ obj-$(CONFIG_ARCH_TEGRA) += tegra/ +obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o obj-$(CONFIG_RESET_ATH79) += reset-ath79.o obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o obj-$(CONFIG_RESET_IMX7) += reset-imx7.o diff --git a/drivers/reset/reset-a10sr.c b/drivers/reset/reset-a10sr.c new file mode 100644 index 000000000000..37496bd27fa2 --- /dev/null +++ b/drivers/reset/reset-a10sr.c @@ -0,0 +1,138 @@ +/* + * Copyright Intel Corporation (C) 2017. All Rights Reserved + * + * 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 . + * + * Reset driver for Altera Arria10 MAX5 System Resource Chip + * + * Adapted from reset-socfpga.c + */ + +#include +#include +#include +#include +#include +#include + +#include + +struct a10sr_reset { + struct reset_controller_dev rcdev; + struct regmap *regmap; +}; + +static inline struct a10sr_reset *to_a10sr_rst(struct reset_controller_dev *rc) +{ + return container_of(rc, struct a10sr_reset, rcdev); +} + +static inline int a10sr_reset_shift(unsigned long id) +{ + switch (id) { + case A10SR_RESET_ENET_HPS: + return 1; + case A10SR_RESET_PCIE: + case A10SR_RESET_FILE: + case A10SR_RESET_BQSPI: + case A10SR_RESET_USB: + return id + 11; + default: + return -EINVAL; + } +} + +static int a10sr_reset_update(struct reset_controller_dev *rcdev, + unsigned long id, bool assert) +{ + struct a10sr_reset *a10r = to_a10sr_rst(rcdev); + int offset = a10sr_reset_shift(id); + u8 mask = ALTR_A10SR_REG_BIT_MASK(offset); + int index = ALTR_A10SR_HPS_RST_REG + ALTR_A10SR_REG_OFFSET(offset); + + return regmap_update_bits(a10r->regmap, index, mask, assert ? 0 : mask); +} + +static int a10sr_reset_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + return a10sr_reset_update(rcdev, id, true); +} + +static int a10sr_reset_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + return a10sr_reset_update(rcdev, id, false); +} + +static int a10sr_reset_status(struct reset_controller_dev *rcdev, + unsigned long id) +{ + int ret; + struct a10sr_reset *a10r = to_a10sr_rst(rcdev); + int offset = a10sr_reset_shift(id); + u8 mask = ALTR_A10SR_REG_BIT_MASK(offset); + int index = ALTR_A10SR_HPS_RST_REG + ALTR_A10SR_REG_OFFSET(offset); + unsigned int value; + + ret = regmap_read(a10r->regmap, index, &value); + if (ret < 0) + return ret; + + return !!(value & mask); +} + +static const struct reset_control_ops a10sr_reset_ops = { + .assert = a10sr_reset_assert, + .deassert = a10sr_reset_deassert, + .status = a10sr_reset_status, +}; + +static int a10sr_reset_probe(struct platform_device *pdev) +{ + struct altr_a10sr *a10sr = dev_get_drvdata(pdev->dev.parent); + struct a10sr_reset *a10r; + + a10r = devm_kzalloc(&pdev->dev, sizeof(struct a10sr_reset), + GFP_KERNEL); + if (!a10r) + return -ENOMEM; + + a10r->rcdev.owner = THIS_MODULE; + a10r->rcdev.nr_resets = A10SR_RESET_NUM; + a10r->rcdev.ops = &a10sr_reset_ops; + a10r->rcdev.of_node = pdev->dev.of_node; + a10r->regmap = a10sr->regmap; + + platform_set_drvdata(pdev, a10r); + + return devm_reset_controller_register(&pdev->dev, &a10r->rcdev); +} + +static const struct of_device_id a10sr_reset_of_match[] = { + { .compatible = "altr,a10sr-reset" }, + { }, +}; +MODULE_DEVICE_TABLE(of, a10sr_reset_of_match); + +static struct platform_driver a10sr_reset_driver = { + .probe = a10sr_reset_probe, + .driver = { + .name = "altr_a10sr_reset", + }, +}; +module_platform_driver(a10sr_reset_driver); + +MODULE_AUTHOR("Thor Thayer "); +MODULE_DESCRIPTION("Altera Arria10 System Resource Reset Controller Driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-59-g8ed1b From 7cc119f29b197f967161ca94c9d5cb5073b4b52b Mon Sep 17 00:00:00 2001 From: Dave Gerlach Date: Tue, 4 Apr 2017 08:59:27 -0700 Subject: dt-bindings: Add TI SCI PM Domains Add a generic power domain implementation, TI SCI PM Domains, that will hook into the genpd framework and allow the TI SCI protocol to control device power states. Also, provide macros representing each device index as understood by TI SCI to be used in the device node power-domain references. These are identifiers for the K2G devices managed by the PMMC. Acked-by: Santosh Shilimkar Reviewed-by: Ulf Hansson Acked-by: Rob Herring Signed-off-by: Nishanth Menon Signed-off-by: Dave Gerlach Signed-off-by: Santosh Shilimkar --- .../devicetree/bindings/soc/ti/sci-pm-domain.txt | 57 ++++++++++++++ MAINTAINERS | 2 + include/dt-bindings/genpd/k2g.h | 90 ++++++++++++++++++++++ 3 files changed, 149 insertions(+) create mode 100644 Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt create mode 100644 include/dt-bindings/genpd/k2g.h (limited to 'MAINTAINERS') diff --git a/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt b/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt new file mode 100644 index 000000000000..c705db07d820 --- /dev/null +++ b/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt @@ -0,0 +1,57 @@ +Texas Instruments TI-SCI Generic Power Domain +--------------------------------------------- + +Some TI SoCs contain a system controller (like the PMMC, etc...) that is +responsible for controlling the state of the IPs that are present. +Communication between the host processor running an OS and the system +controller happens through a protocol known as TI-SCI [1]. + +[1] Documentation/devicetree/bindings/arm/keystone/ti,sci.txt + +PM Domain Node +============== +The PM domain node represents the global PM domain managed by the PMMC, which +in this case is the implementation as documented by the generic PM domain +bindings in Documentation/devicetree/bindings/power/power_domain.txt. Because +this relies on the TI SCI protocol to communicate with the PMMC it must be a +child of the pmmc node. + +Required Properties: +-------------------- +- compatible: should be "ti,sci-pm-domain" +- #power-domain-cells: Must be 1 so that an id can be provided in each + device node. + +Example (K2G): +------------- + pmmc: pmmc { + compatible = "ti,k2g-sci"; + ... + + k2g_pds: power-controller { + compatible = "ti,sci-pm-domain"; + #power-domain-cells = <1>; + }; + }; + +PM Domain Consumers +=================== +Hardware blocks belonging to a PM domain should contain a "power-domains" +property that is a phandle pointing to the corresponding PM domain node +along with an index representing the device id to be passed to the PMMC +for device control. + +Required Properties: +-------------------- +- power-domains: phandle pointing to the corresponding PM domain node + and an ID representing the device. + +See dt-bindings/genpd/k2g.h for the list of valid identifiers for k2g. + +Example (K2G): +-------------------- + uart0: serial@02530c00 { + compatible = "ns16550a"; + ... + power-domains = <&k2g_pds K2G_DEV_UART0>; + }; diff --git a/MAINTAINERS b/MAINTAINERS index c776906f67a9..9057479ee607 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12382,6 +12382,8 @@ S: Maintained F: Documentation/devicetree/bindings/arm/keystone/ti,sci.txt F: drivers/firmware/ti_sci* F: include/linux/soc/ti/ti_sci_protocol.h +F: Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt +F: include/dt-bindings/genpd/k2g.h THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER M: Hans Verkuil diff --git a/include/dt-bindings/genpd/k2g.h b/include/dt-bindings/genpd/k2g.h new file mode 100644 index 000000000000..fffdb604fc7d --- /dev/null +++ b/include/dt-bindings/genpd/k2g.h @@ -0,0 +1,90 @@ +/* + * TI K2G SoC Device definitions + * + * Copyright (C) 2015-2017 Texas Instruments Incorporated - https://urldefense.proofpoint.com/v2/url?u=http-3A__www.ti.com_&d=DwIBAg&c=RoP1YumCXCgaWHvlZYR8PQcxBKCX5YTpkKY057SbK10&r=XBn1JQGPwR8CsE7xpP3wPlG6DQU7qw8ym65xieNZ4hY&m=K-anSnBVCpVU_mSaI7FWz6dwIAPBePhk6w9rCref6SI&s=UvxGRJAJRKjDVjwUuXloC2gH4uWNkMelLuW2oG01DPM&e= + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that 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. + */ + +#ifndef _DT_BINDINGS_GENPD_K2G_H +#define _DT_BINDINGS_GENPD_K2G_H + +/* Documented in https://urldefense.proofpoint.com/v2/url?u=http-3A__processors.wiki.ti.com_index.php_TISCI&d=DwIBAg&c=RoP1YumCXCgaWHvlZYR8PQcxBKCX5YTpkKY057SbK10&r=XBn1JQGPwR8CsE7xpP3wPlG6DQU7qw8ym65xieNZ4hY&m=K-anSnBVCpVU_mSaI7FWz6dwIAPBePhk6w9rCref6SI&s=OUR-PBKiUWN0Bhs-J9hzlER8kpqh_V70s09xc8Zo1iA&e= */ + +#define K2G_DEV_PMMC0 0x0000 +#define K2G_DEV_MLB0 0x0001 +#define K2G_DEV_DSS0 0x0002 +#define K2G_DEV_MCBSP0 0x0003 +#define K2G_DEV_MCASP0 0x0004 +#define K2G_DEV_MCASP1 0x0005 +#define K2G_DEV_MCASP2 0x0006 +#define K2G_DEV_DCAN0 0x0008 +#define K2G_DEV_DCAN1 0x0009 +#define K2G_DEV_EMIF0 0x000a +#define K2G_DEV_MMCHS0 0x000b +#define K2G_DEV_MMCHS1 0x000c +#define K2G_DEV_GPMC0 0x000d +#define K2G_DEV_ELM0 0x000e +#define K2G_DEV_SPI0 0x0010 +#define K2G_DEV_SPI1 0x0011 +#define K2G_DEV_SPI2 0x0012 +#define K2G_DEV_SPI3 0x0013 +#define K2G_DEV_ICSS0 0x0014 +#define K2G_DEV_ICSS1 0x0015 +#define K2G_DEV_USB0 0x0016 +#define K2G_DEV_USB1 0x0017 +#define K2G_DEV_NSS0 0x0018 +#define K2G_DEV_PCIE0 0x0019 +#define K2G_DEV_GPIO0 0x001b +#define K2G_DEV_GPIO1 0x001c +#define K2G_DEV_TIMER64_0 0x001d +#define K2G_DEV_TIMER64_1 0x001e +#define K2G_DEV_TIMER64_2 0x001f +#define K2G_DEV_TIMER64_3 0x0020 +#define K2G_DEV_TIMER64_4 0x0021 +#define K2G_DEV_TIMER64_5 0x0022 +#define K2G_DEV_TIMER64_6 0x0023 +#define K2G_DEV_MSGMGR0 0x0025 +#define K2G_DEV_BOOTCFG0 0x0026 +#define K2G_DEV_ARM_BOOTROM0 0x0027 +#define K2G_DEV_DSP_BOOTROM0 0x0029 +#define K2G_DEV_DEBUGSS0 0x002b +#define K2G_DEV_UART0 0x002c +#define K2G_DEV_UART1 0x002d +#define K2G_DEV_UART2 0x002e +#define K2G_DEV_EHRPWM0 0x002f +#define K2G_DEV_EHRPWM1 0x0030 +#define K2G_DEV_EHRPWM2 0x0031 +#define K2G_DEV_EHRPWM3 0x0032 +#define K2G_DEV_EHRPWM4 0x0033 +#define K2G_DEV_EHRPWM5 0x0034 +#define K2G_DEV_EQEP0 0x0035 +#define K2G_DEV_EQEP1 0x0036 +#define K2G_DEV_EQEP2 0x0037 +#define K2G_DEV_ECAP0 0x0038 +#define K2G_DEV_ECAP1 0x0039 +#define K2G_DEV_I2C0 0x003a +#define K2G_DEV_I2C1 0x003b +#define K2G_DEV_I2C2 0x003c +#define K2G_DEV_EDMA0 0x003f +#define K2G_DEV_SEMAPHORE0 0x0040 +#define K2G_DEV_INTC0 0x0041 +#define K2G_DEV_GIC0 0x0042 +#define K2G_DEV_QSPI0 0x0043 +#define K2G_DEV_ARM_64B_COUNTER0 0x0044 +#define K2G_DEV_TETRIS0 0x0045 +#define K2G_DEV_CGEM0 0x0046 +#define K2G_DEV_MSMC0 0x0047 +#define K2G_DEV_CBASS0 0x0049 +#define K2G_DEV_BOARD0 0x004c +#define K2G_DEV_EDMA1 0x004f + +#endif -- cgit v1.2.3-59-g8ed1b From 52835d59fc6cc7f3c3cfdb4a194ddc9ebd6c0c31 Mon Sep 17 00:00:00 2001 From: Dave Gerlach Date: Tue, 4 Apr 2017 08:59:27 -0700 Subject: soc: ti: Add ti_sci_pm_domains driver Introduce a ti_sci_pm_domains driver to act as a generic pm domain provider to allow each device to attach and associate it's ti-sci-id so that it can be controlled through the TI SCI protocol. This driver implements a simple genpd where each device node has a phandle to the power domain node and also must provide an index which represents the ID to be passed with TI SCI representing the device using a single phandle cell. The driver manually parses the phandle to get the cell value. Through this interface the genpd dev_ops start and stop hooks will use TI SCI to turn on and off each device as determined by pm_runtime usage. Reviewed-by: Kevin Hilman Acked-by: Santosh Shilimkar Reviewed-by: Ulf Hansson Signed-off-by: Keerthy Signed-off-by: Nishanth Menon Signed-off-by: Dave Gerlach Signed-off-by: Santosh Shilimkar --- MAINTAINERS | 1 + arch/arm/mach-keystone/Kconfig | 1 + drivers/soc/ti/Kconfig | 12 +++ drivers/soc/ti/Makefile | 1 + drivers/soc/ti/ti_sci_pm_domains.c | 202 +++++++++++++++++++++++++++++++++++++ 5 files changed, 217 insertions(+) create mode 100644 drivers/soc/ti/ti_sci_pm_domains.c (limited to 'MAINTAINERS') diff --git a/MAINTAINERS b/MAINTAINERS index 9057479ee607..e4ceac9f6049 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12384,6 +12384,7 @@ F: drivers/firmware/ti_sci* F: include/linux/soc/ti/ti_sci_protocol.h F: Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt F: include/dt-bindings/genpd/k2g.h +F: drivers/soc/ti/ti_sci_pm_domains.c THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER M: Hans Verkuil diff --git a/arch/arm/mach-keystone/Kconfig b/arch/arm/mach-keystone/Kconfig index 554357035f30..db122356b410 100644 --- a/arch/arm/mach-keystone/Kconfig +++ b/arch/arm/mach-keystone/Kconfig @@ -10,6 +10,7 @@ config ARCH_KEYSTONE select ARCH_SUPPORTS_BIG_ENDIAN select ZONE_DMA if ARM_LPAE select PINCTRL + select PM_GENERIC_DOMAINS if PM help Support for boards based on the Texas Instruments Keystone family of SoCs. diff --git a/drivers/soc/ti/Kconfig b/drivers/soc/ti/Kconfig index 3557c5e32a93..39e152abe6b9 100644 --- a/drivers/soc/ti/Kconfig +++ b/drivers/soc/ti/Kconfig @@ -38,4 +38,16 @@ config WKUP_M3_IPC to communicate and use the Wakeup M3 for PM features like suspend resume and boots it using wkup_m3_rproc driver. +config TI_SCI_PM_DOMAINS + tristate "TI SCI PM Domains Driver" + depends on TI_SCI_PROTOCOL + depends on PM_GENERIC_DOMAINS + help + Generic power domain implementation for TI device implementing + the TI SCI protocol. + + To compile this as a module, choose M here. The module will be + called ti_sci_pm_domains. Note this is needed early in boot before + rootfs may be available. + endif # SOC_TI diff --git a/drivers/soc/ti/Makefile b/drivers/soc/ti/Makefile index 48ff3a79634f..7d572736c86e 100644 --- a/drivers/soc/ti/Makefile +++ b/drivers/soc/ti/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_KEYSTONE_NAVIGATOR_QMSS) += knav_qmss.o knav_qmss-y := knav_qmss_queue.o knav_qmss_acc.o obj-$(CONFIG_KEYSTONE_NAVIGATOR_DMA) += knav_dma.o obj-$(CONFIG_WKUP_M3_IPC) += wkup_m3_ipc.o +obj-$(CONFIG_TI_SCI_PM_DOMAINS) += ti_sci_pm_domains.o diff --git a/drivers/soc/ti/ti_sci_pm_domains.c b/drivers/soc/ti/ti_sci_pm_domains.c new file mode 100644 index 000000000000..d9dccb0c3a2a --- /dev/null +++ b/drivers/soc/ti/ti_sci_pm_domains.c @@ -0,0 +1,202 @@ +/* + * TI SCI Generic Power Domain Driver + * + * Copyright (C) 2015-2017 Texas Instruments Incorporated - https://urldefense.proofpoint.com/v2/url?u=http-3A__www.ti.com_&d=DwIBAg&c=RoP1YumCXCgaWHvlZYR8PQcxBKCX5YTpkKY057SbK10&r=XBn1JQGPwR8CsE7xpP3wPlG6DQU7qw8ym65xieNZ4hY&m=R6qGiR9DbG1C3EF_0mL-m-qkmSO64GklbFWpUzqt8fY&s=YTWcQCWi5lnIf4XHDLq1XDd4JbZv9xpqOwdPD8xEdZE&e= + * J Keerthy + * Dave Gerlach + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * struct ti_sci_genpd_dev_data: holds data needed for every device attached + * to this genpd + * @idx: index of the device that identifies it with the system + * control processor. + */ +struct ti_sci_genpd_dev_data { + int idx; +}; + +/** + * struct ti_sci_pm_domain: TI specific data needed for power domain + * @ti_sci: handle to TI SCI protocol driver that provides ops to + * communicate with system control processor. + * @dev: pointer to dev for the driver for devm allocs + * @pd: generic_pm_domain for use with the genpd framework + */ +struct ti_sci_pm_domain { + const struct ti_sci_handle *ti_sci; + struct device *dev; + struct generic_pm_domain pd; +}; + +#define genpd_to_ti_sci_pd(gpd) container_of(gpd, struct ti_sci_pm_domain, pd) + +/** + * ti_sci_dev_id(): get prepopulated ti_sci id from struct dev + * @dev: pointer to device associated with this genpd + * + * Returns device_id stored from ti,sci_id property + */ +static int ti_sci_dev_id(struct device *dev) +{ + struct generic_pm_domain_data *genpd_data = dev_gpd_data(dev); + struct ti_sci_genpd_dev_data *sci_dev_data = genpd_data->data; + + return sci_dev_data->idx; +} + +/** + * ti_sci_dev_to_sci_handle(): get pointer to ti_sci_handle + * @dev: pointer to device associated with this genpd + * + * Returns ti_sci_handle to be used to communicate with system + * control processor. + */ +static const struct ti_sci_handle *ti_sci_dev_to_sci_handle(struct device *dev) +{ + struct generic_pm_domain *pd = pd_to_genpd(dev->pm_domain); + struct ti_sci_pm_domain *ti_sci_genpd = genpd_to_ti_sci_pd(pd); + + return ti_sci_genpd->ti_sci; +} + +/** + * ti_sci_dev_start(): genpd device start hook called to turn device on + * @dev: pointer to device associated with this genpd to be powered on + */ +static int ti_sci_dev_start(struct device *dev) +{ + const struct ti_sci_handle *ti_sci = ti_sci_dev_to_sci_handle(dev); + int idx = ti_sci_dev_id(dev); + + return ti_sci->ops.dev_ops.get_device(ti_sci, idx); +} + +/** + * ti_sci_dev_stop(): genpd device stop hook called to turn device off + * @dev: pointer to device associated with this genpd to be powered off + */ +static int ti_sci_dev_stop(struct device *dev) +{ + const struct ti_sci_handle *ti_sci = ti_sci_dev_to_sci_handle(dev); + int idx = ti_sci_dev_id(dev); + + return ti_sci->ops.dev_ops.put_device(ti_sci, idx); +} + +static int ti_sci_pd_attach_dev(struct generic_pm_domain *domain, + struct device *dev) +{ + struct device_node *np = dev->of_node; + struct of_phandle_args pd_args; + struct ti_sci_pm_domain *ti_sci_genpd = genpd_to_ti_sci_pd(domain); + const struct ti_sci_handle *ti_sci = ti_sci_genpd->ti_sci; + struct ti_sci_genpd_dev_data *sci_dev_data; + struct generic_pm_domain_data *genpd_data; + int idx, ret = 0; + + ret = of_parse_phandle_with_args(np, "power-domains", + "#power-domain-cells", 0, &pd_args); + if (ret < 0) + return ret; + + if (pd_args.args_count != 1) + return -EINVAL; + + idx = pd_args.args[0]; + + /* + * Check the validity of the requested idx, if the index is not valid + * the PMMC will return a NAK here and we will not allocate it. + */ + ret = ti_sci->ops.dev_ops.is_valid(ti_sci, idx); + if (ret) + return -EINVAL; + + sci_dev_data = kzalloc(sizeof(*sci_dev_data), GFP_KERNEL); + if (!sci_dev_data) + return -ENOMEM; + + sci_dev_data->idx = idx; + + genpd_data = dev_gpd_data(dev); + genpd_data->data = sci_dev_data; + + return 0; +} + +static void ti_sci_pd_detach_dev(struct generic_pm_domain *domain, + struct device *dev) +{ + struct generic_pm_domain_data *genpd_data = dev_gpd_data(dev); + struct ti_sci_genpd_dev_data *sci_dev_data = genpd_data->data; + + kfree(sci_dev_data); + genpd_data->data = NULL; +} + +static const struct of_device_id ti_sci_pm_domain_matches[] = { + { .compatible = "ti,sci-pm-domain", }, + { }, +}; +MODULE_DEVICE_TABLE(of, ti_sci_pm_domain_matches); + +static int ti_sci_pm_domain_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct ti_sci_pm_domain *ti_sci_pd; + int ret; + + ti_sci_pd = devm_kzalloc(dev, sizeof(*ti_sci_pd), GFP_KERNEL); + if (!ti_sci_pd) + return -ENOMEM; + + ti_sci_pd->ti_sci = devm_ti_sci_get_handle(dev); + if (IS_ERR(ti_sci_pd->ti_sci)) + return PTR_ERR(ti_sci_pd->ti_sci); + + ti_sci_pd->dev = dev; + + ti_sci_pd->pd.attach_dev = ti_sci_pd_attach_dev; + ti_sci_pd->pd.detach_dev = ti_sci_pd_detach_dev; + + ti_sci_pd->pd.dev_ops.start = ti_sci_dev_start; + ti_sci_pd->pd.dev_ops.stop = ti_sci_dev_stop; + + pm_genpd_init(&ti_sci_pd->pd, NULL, true); + + ret = of_genpd_add_provider_simple(np, &ti_sci_pd->pd); + + return ret; +} + +static struct platform_driver ti_sci_pm_domains_driver = { + .probe = ti_sci_pm_domain_probe, + .driver = { + .name = "ti_sci_pm_domains", + .of_match_table = ti_sci_pm_domain_matches, + }, +}; +module_platform_driver(ti_sci_pm_domains_driver); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("TI System Control Interface (SCI) Power Domain driver"); +MODULE_AUTHOR("Dave Gerlach"); -- cgit v1.2.3-59-g8ed1b