[PATCH] drivers: mfd: exynos-pmu: Add support for Exynos7
Add intial PMU settings for exynos7. This is required for future suspend-to-ram and cpuidle support. Signed-off-by: Eunseok Choi es10.c...@samsung.com Signed-off-by: Abhilash Kesavan a.kesa...@samsung.com --- This patch has been tested on an Exynos7 espresso board and is based on Kgene's tree (for-next branch). Following are the dependencies: 1) Support 64bit Cortex A57 based Exynos7 SoC http://www.spinics.net/lists/arm-kernel/msg357380.html 2) mfd: syscon: Decouple syscon interface from syscon devices http://www.spinics.net/lists/linux-samsung-soc/msg35906.html 3) ARM: EXYNOS: Add platform driver support for Exynos PMU http://lists.infradead.org/pipermail/linux-arm-kernel/2014-July/275675.html 4) ARM: EXYNOS: Move PMU specific definitions from common.h http://lists.infradead.org/pipermail/linux-arm-kernel/2014-July/270655.html 5) ARM: EXYNOS: Move pmu specific header files under linux/mfd/samsung https://lkml.org/lkml/2014/4/28/217 6) drivers: mfd: Add support for Exynos PMU driver https://lkml.org/lkml/2014/4/28/332 NOTE: The above dependencies are not final yet, especially the movement of exynos pmu driver to the mfd directory. I will re-work this patch when the final location for exynos PMU driver is decided. .../devicetree/bindings/arm/samsung/pmu.txt|1 + arch/arm64/boot/dts/exynos7.dtsi |5 + drivers/mfd/exynos-pmu.c | 285 include/linux/mfd/samsung/exynos-regs-pmu.h| 212 +++ 4 files changed, 503 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/samsung/pmu.txt b/Documentation/devicetree/bindings/arm/samsung/pmu.txt index 1e1979b..67b2113 100644 --- a/Documentation/devicetree/bindings/arm/samsung/pmu.txt +++ b/Documentation/devicetree/bindings/arm/samsung/pmu.txt @@ -10,6 +10,7 @@ Properties: - samsung,exynos5260-pmu - for Exynos5260 SoC. - samsung,exynos5410-pmu - for Exynos5410 SoC, - samsung,exynos5420-pmu - for Exynos5420 SoC. + - samsung,exynos7-pmu - for Exynos7 SoC. second value must be always syscon. - reg : offset and length of the register set. diff --git a/arch/arm64/boot/dts/exynos7.dtsi b/arch/arm64/boot/dts/exynos7.dtsi index 6b9eaf4..e2f9f85 100644 --- a/arch/arm64/boot/dts/exynos7.dtsi +++ b/arch/arm64/boot/dts/exynos7.dtsi @@ -361,6 +361,11 @@ status = disabled; }; + pmu: pmu-controller@105c { + compatible = samsung,exynos7-pmu; + reg = 0x105c 0x5000; + }; + rtc@1059 { compatible = samsung,s3c6410-rtc; reg = 0x1059 0x100; diff --git a/drivers/mfd/exynos-pmu.c b/drivers/mfd/exynos-pmu.c index bfdadbf..9af3b53 100644 --- a/drivers/mfd/exynos-pmu.c +++ b/drivers/mfd/exynos-pmu.c @@ -11,6 +11,7 @@ #include linux/io.h #include linux/of.h +#include linux/of_address.h #include linux/platform_device.h #include linux/regmap.h #include linux/mfd/syscon.h @@ -348,6 +349,185 @@ static const struct exynos_pmu_conf exynos5250_pmu_config[] = { { PMU_TABLE_END,}, }; +static const struct exynos_pmu_conf exynos7_pmu_config[] = { + /* { .addr = address, .val = { AFTR, LPA, SLEEP } } */ + { EXYNOS7_ATLAS_CPU0_SYS_PWR_REG, { 0x0, 0x0, 0x0 } }, + { EXYNOS7_DIS_IRQ_ATLAS_CPU0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0 } }, + { EXYNOS7_DIS_IRQ_ATLAS_CPU0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0 } }, + { EXYNOS7_DIS_IRQ_ATLAS_CPU0_CPUSEQUENCER_SYS_PWR_REG, { 0x0, 0x0, 0x0 } }, + { EXYNOS7_ATLAS_CPU1_SYS_PWR_REG, { 0x0, 0x0, 0x0 } }, + { EXYNOS7_DIS_IRQ_ATLAS_CPU1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0 } }, + { EXYNOS7_DIS_IRQ_ATLAS_CPU1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0 } }, + { EXYNOS7_DIS_IRQ_ATLAS_CPU1_CPUSEQUENCER_SYS_PWR_REG, { 0x0, 0x0, 0x0 } }, + { EXYNOS7_ATLAS_CPU2_SYS_PWR_REG, { 0x0, 0x0, 0x0 } }, + { EXYNOS7_DIS_IRQ_ATLAS_CPU2_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0 } }, + { EXYNOS7_DIS_IRQ_ATLAS_CPU2_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0 } }, + { EXYNOS7_DIS_IRQ_ATLAS_CPU2_CPUSEQUENCER_SYS_PWR_REG, { 0x0, 0x0, 0x0 } }, + { EXYNOS7_ATLAS_CPU3_SYS_PWR_REG, { 0x0, 0x0, 0x8 } }, + { EXYNOS7_DIS_IRQ_ATLAS_CPU3_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0 } }, + { EXYNOS7_DIS_IRQ_ATLAS_CPU3_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0 } }, + { EXYNOS7_DIS_IRQ_ATLAS_CPU3_CPUSEQUENCER_SYS_PWR_REG, { 0x0, 0x0, 0x0 } }, + { EXYNOS7_ATLAS_NONCPU_SYS_PWR_REG, { 0x0, 0x0, 0x0 } }, + { EXYNOS7_ATLAS_DBG_SYS_PWR_REG,{ 0x0, 0x0, 0x0 } }, + { EXYNOS7_ATLAS_L2_SYS_PWR_REG, { 0x0, 0x0, 0x0 } }, + { EXYNOS7_CLKSTOP_CMU_TOP_SYS_PWR_REG,
RE: [PATCH] mfd: syscon: Decouple syscon interface from syscon devices
Sorry I forgot to add maintainer into CC. +Lee Jones Any comments on this patch. As a lot of Exynos PMU patch sets are dependent on this patch. Thanks, Pankaj Dubey -Original Message- From: Pankaj Dubey [mailto:pankaj.du...@samsung.com] Sent: Friday, August 22, 2014 1:40 PM To: linux-arm-ker...@lists.infradead.org; linux-samsung-soc@vger.kernel.org; linux- ker...@vger.kernel.org Cc: kgene@samsung.com; li...@arm.linux.org.uk; a...@arndb.de; vikas.saj...@samsung.com; jo...@samsung.com; naus...@samsung.com; thomas...@samsung.com; chow@samsung.com; Tomasz Figa; Pankaj Dubey Subject: [PATCH] mfd: syscon: Decouple syscon interface from syscon devices From: Tomasz Figa t.f...@samsung.com Currently a syscon entity can be only registered directly through a platform device that binds to a dedicated driver. However in certain use cases it is desirable to make a device used with another driver a syscon interface provider. For example, certain SoCs (e.g. Exynos) contain system controller blocks which perform various functions such as power domain control, CPU power management, low power mode control, but in addition contain certain IP integration glue, such as various signal masks, coprocessor power control, etc. In such case, there is a need to have a dedicated driver for such system controller but also share registers with other drivers. The latter is where the syscon interface is helpful. This patch decouples syscon object from syscon driver, so that it can be registered from any driver in addition to the original syscon platform driver. Signed-off-by: Tomasz Figa t.f...@samsung.com Signed-off-by: Pankaj Dubey pankaj.du...@samsung.com --- RFC patch [1] was posted by Tomasz Figa. This patch addresses some of comments given by Arnd to RFC patch, and further decouples syscon from device model. It also gives flexibility of registering with syscon at early stage using device_node object. [1]: https://lkml.org/lkml/2014/6/17/331 drivers/mfd/syscon.c | 112 include/linux/mfd/syscon.h | 14 ++ 2 files changed, 86 insertions(+), 40 deletions(-) diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index ca15878..a91db30 100644 --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c @@ -14,6 +14,7 @@ #include linux/err.h #include linux/io.h +#include linux/list.h #include linux/module.h #include linux/of.h #include linux/of_address.h @@ -22,33 +23,32 @@ #include linux/platform_device.h #include linux/regmap.h #include linux/mfd/syscon.h +#include linux/slab.h -static struct platform_driver syscon_driver; +static DEFINE_SPINLOCK(syscon_list_slock); +static LIST_HEAD(syscon_list); struct syscon { + struct device_node *np; struct regmap *regmap; + struct list_head list; }; -static int syscon_match_node(struct device *dev, void *data) -{ - struct device_node *dn = data; - - return (dev-of_node == dn) ? 1 : 0; -} - struct regmap *syscon_node_to_regmap(struct device_node *np) { - struct syscon *syscon; - struct device *dev; + struct syscon *entry, *syscon = NULL; - dev = driver_find_device(syscon_driver.driver, NULL, np, - syscon_match_node); - if (!dev) - return ERR_PTR(-EPROBE_DEFER); + spin_lock(syscon_list_slock); - syscon = dev_get_drvdata(dev); + list_for_each_entry(entry, syscon_list, list) + if (entry-np == np) { + syscon = entry; + break; + } - return syscon-regmap; + spin_unlock(syscon_list_slock); + + return syscon ? syscon-regmap : ERR_PTR(-EPROBE_DEFER); } EXPORT_SYMBOL_GPL(syscon_node_to_regmap); @@ -68,24 +68,22 @@ struct regmap *syscon_regmap_lookup_by_compatible(const char *s) } EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_compatible); -static int syscon_match_pdevname(struct device *dev, void *data) -{ - return !strcmp(dev_name(dev), (const char *)data); -} - struct regmap *syscon_regmap_lookup_by_pdevname(const char *s) { - struct device *dev; - struct syscon *syscon; - - dev = driver_find_device(syscon_driver.driver, NULL, (void *)s, - syscon_match_pdevname); - if (!dev) - return ERR_PTR(-EPROBE_DEFER); - - syscon = dev_get_drvdata(dev); + struct syscon *entry, *syscon = NULL; + struct platform_device *pdev = NULL; + + spin_lock(syscon_list_slock); + list_for_each_entry(entry, syscon_list, list) { + pdev = of_find_device_by_node(entry-np); + if (pdev !strcmp(dev_name(pdev-dev), s)) { + syscon = entry; + break; + } + } + spin_unlock(syscon_list_slock); - return syscon-regmap; + return syscon ? syscon-regmap :
Re: [PATCH 10/29] drivers: add DRIVER_HAS_OWN_IOMMU_MANAGER flag
Hi Greg, On 2014-08-05 12:47, Marek Szyprowski wrote: This patch adds a new flags for device drivers. This flag instructs kernel that the device driver does it own management of IOMMU assisted IO address space translations, so no default dma-mapping structures should be initialized. Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com --- include/linux/device.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/device.h b/include/linux/device.h index 5f4ff02..2e62371 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -253,6 +253,8 @@ struct device_driver { /* disables bind/unbind via sysfs */ #define DRIVER_SUPPRESS_BIND_ATTRS(1 0) +/* driver uses own methods to manage IO address space */ +#define DRIVER_HAS_OWN_IOMMU_MANAGER (1 1) extern int __must_check driver_register(struct device_driver *drv); extern void driver_unregister(struct device_driver *drv); Could you comment if the approach of using flags in the struct driver could be accepted? I've converted suppress_bind_attrs entry to flags to avoid extending the structure, please see patch [PATCH 05/29] drivers: convert suppress_bind_attrs parameter into flags. Best regards -- Marek Szyprowski, PhD Samsung RD Institute Poland -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mmc: dw_mmc: exynos: Add support for exynos7
Hi Jaehoon, +Prabu Thangamuthu On Fri, Aug 29, 2014 at 4:14 PM, Jaehoon Chung jh80.ch...@samsung.com wrote: Hi, Abhilash. On 08/28/2014 10:18 PM, Yuvaraj Kumar C D wrote: From: Abhilash Kesavan a.kesa...@samsung.com The Exynos7 has a DWMMC controller (v2.70a) which is different from prior versions. This patch adds new compatible strings for exynos7. This patch also fixes the CLKSEL register offset on exynos7. If support the 64bit, dw-mmc.c need to modify.(according to v2.70, some offset is changed for 64-bit address) But i didn't see any patches at mailing. Do you have the plan which send patch of dw-mmc.c? We are using a rebased version of http://www.spinics.net/lists/linux-mmc/msg21742.html to handle the dwmmc side changes. We should have mentioned this dependency as the patch is required for proper functioning of dwmmc on Exynos7. Stress tests are on-going with that patch and once it looks good, we will post our results so that the original patch may be taken forward. Regards, Abhilash Best Regards, Jaehoon Chung Signed-off-by: Abhilash Kesavan a.kesa...@samsung.com Signed-off-by: Yuvaraj Kumar C D yuvaraj...@samsung.com --- .../devicetree/bindings/mmc/exynos-dw-mshc.txt |4 + drivers/mmc/host/dw_mmc-exynos.c | 91 +--- 2 files changed, 82 insertions(+), 13 deletions(-) diff --git a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt index 6cd3525..ee4fc05 100644 --- a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt +++ b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt @@ -18,6 +18,10 @@ Required Properties: specific extensions. - samsung,exynos5420-dw-mshc: for controllers with Samsung Exynos5420 specific extensions. + - samsung,exynos7-dw-mshc: for controllers with Samsung Exynos7 + specific extensions. + - samsung,exynos7-dw-mshc-smu: for controllers with Samsung Exynos7 + specific extensions having an SMU. * samsung,dw-mshc-ciu-div: Specifies the divider value for the card interface unit (ciu) clock. This property is applicable only for Exynos5 SoC's and diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c index 0fbc53a..509365c 100644 --- a/drivers/mmc/host/dw_mmc-exynos.c +++ b/drivers/mmc/host/dw_mmc-exynos.c @@ -25,6 +25,7 @@ #define NUM_PINS(x) (x + 2) #define SDMMC_CLKSEL 0x09C +#define SDMMC_CLKSEL64 0x0A8 #define SDMMC_CLKSEL_CCLK_SAMPLE(x) (((x) 7) 0) #define SDMMC_CLKSEL_CCLK_DRIVE(x) (((x) 7) 16) #define SDMMC_CLKSEL_CCLK_DIVIDER(x) (((x) 7) 24) @@ -65,6 +66,8 @@ enum dw_mci_exynos_type { DW_MCI_TYPE_EXYNOS5250, DW_MCI_TYPE_EXYNOS5420, DW_MCI_TYPE_EXYNOS5420_SMU, + DW_MCI_TYPE_EXYNOS7, + DW_MCI_TYPE_EXYNOS7_SMU, }; /* Exynos implementation specific driver private data */ @@ -95,6 +98,12 @@ static struct dw_mci_exynos_compatible { }, { .compatible = samsung,exynos5420-dw-mshc-smu, .ctrl_type = DW_MCI_TYPE_EXYNOS5420_SMU, + }, { + .compatible = samsung,exynos7-dw-mshc, + .ctrl_type = DW_MCI_TYPE_EXYNOS7, + }, { + .compatible = samsung,exynos7-dw-mshc-smu, + .ctrl_type = DW_MCI_TYPE_EXYNOS7_SMU, }, }; @@ -102,7 +111,8 @@ static int dw_mci_exynos_priv_init(struct dw_mci *host) { struct dw_mci_exynos_priv_data *priv = host-priv; - if (priv-ctrl_type == DW_MCI_TYPE_EXYNOS5420_SMU) { + if (priv-ctrl_type == DW_MCI_TYPE_EXYNOS5420_SMU || + priv-ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) { mci_writel(host, MPSBEGIN0, 0); mci_writel(host, MPSEND0, DWMCI_BLOCK_NUM); mci_writel(host, MPSCTRL0, DWMCI_MPSCTRL_SECURE_WRITE_BIT | @@ -153,11 +163,22 @@ static int dw_mci_exynos_resume(struct device *dev) static int dw_mci_exynos_resume_noirq(struct device *dev) { struct dw_mci *host = dev_get_drvdata(dev); + struct dw_mci_exynos_priv_data *priv = host-priv; u32 clksel; - clksel = mci_readl(host, CLKSEL); - if (clksel SDMMC_CLKSEL_WAKEUP_INT) - mci_writel(host, CLKSEL, clksel); + if (priv-ctrl_type == DW_MCI_TYPE_EXYNOS7 || + priv-ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) + clksel = mci_readl(host, CLKSEL64); + else + clksel = mci_readl(host, CLKSEL); + + if (clksel SDMMC_CLKSEL_WAKEUP_INT) { + if (priv-ctrl_type == DW_MCI_TYPE_EXYNOS7 || + priv-ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) + mci_writel(host, CLKSEL64, clksel); + else + mci_writel(host, CLKSEL, clksel); + } return 0; } @@ -169,6 +190,7 @@ static int