mfd: omap: control: core system control driver
Subsystems (5)
PATCH v4 2/4 mfd: omap: control: core system control driver
This patch introduces a MFD core device driver for OMAP system control module.
The control module allows software control of various static modes supported by the device. It is composed of two control submodules: general control module and device (padconfiguration) control module.
Device driver is probed with postcore_initcall. Control module register CONTROL_STATUS that is needed by omap_type() is early mapped by postcore_initcall_sync.
--- .../devicetree/bindings/mfd/omap_control.txt | 32 ++++ arch/arm/mach-omap2/Kconfig | 1 + arch/arm/plat-omap/Kconfig | 4 + drivers/mfd/Kconfig | 6 + drivers/mfd/Makefile | 1 + drivers/mfd/omap-control-core.c | 162 ++++++++++++++++++++ include/linux/mfd/omap_control.h | 35 +++++ 7 files changed, 241 insertions(+), 0 deletions(-) create mode 100644 Documentation/devicetree/bindings/mfd/omap_control.txt create mode 100644 drivers/mfd/omap-control-core.c create mode 100644 include/linux/mfd/omap_control.h
Documentation/devicetree/bindings/mfd/omap_control.txt new file +32 -0
@@ -0,0 +1,32 @@ +* Texas Instrument OMAP System Control Module (SCM) bindings + +The control module allows software control of various static modes supported by +the device. The control module controls the settings of various device modules +through register configuration and internal signals. It also controls the pad +configuration, pin functional multiplexing, and the routing of internal signals +(such as PRCM signals or DMA requests) to output pins configured for hardware +observability. + +Required properties: +- compatible : Should be: + - "ti,omap3-control" for OMAP3 support + - "ti,omap4-control" for OMAP4 support + - "ti,omap5-control" for OMAP5 support + +OMAP specific properties: +- ti,hwmods: Name of the hwmod associated to the control module: + Should be "ctrl_module_core"; + +OMAP CONTROL_STATUS register: +reg = <0x4A0022C4 0x4>; /* CONTROL_STATUS register */ + +Examples: +ctrl_module_core: ctrl_module_core at 4A0022C4 { + compatible = "ti,omap4-control"; + #address-cells = <1>; + #size-cells = <1>; + /* ranges; */ + ti,hwmods = "ctrl_module_core"; + reg = <0x4A0022C4 0x4>; /* CONTROL_STATUS register */ +}; +
arch/arm/mach-omap2/Kconfig +1 -0
@@ -59,6 +59,7 @@ config ARCH_OMAP4 select ARM_ERRATA_720789 select ARCH_HAS_OPP select PM_RUNTIME if CPU_IDLE + select ARCH_HAS_CONTROL_MODULE select PM_OPP if PM select USB_ARCH_HAS_EHCI if USB_SUPPORT select ARM_CPU_SUSPEND if PM
arch/arm/plat-omap/Kconfig +4 -0
@@ -5,6 +5,10 @@ menu "TI OMAP Common Features" config ARCH_OMAP_OTG bool +config ARCH_HAS_CONTROL_MODULE + bool + select MFD_OMAP_CONTROL + choice prompt "OMAP System Type" default ARCH_OMAP2PLUS
drivers/mfd/Kconfig +6 -0
@@ -823,6 +823,12 @@ config MFD_WL1273_CORE driver connects the radio-wl1273 V4L2 module and the wl1273 audio codec. +config MFD_OMAP_CONTROL + bool "Texas Instruments OMAP System control module" + depends on ARCH_HAS_CONTROL_MODULE + help + This is the core driver for system control module. + config MFD_OMAP_USB_HOST bool "Support OMAP USBHS core driver" depends on USB_EHCI_HCD_OMAP || USB_OHCI_HCD_OMAP3
drivers/mfd/Makefile +1 -0
@@ -107,6 +107,7 @@ obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o obj-$(CONFIG_MFD_VX855) += vx855.o obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o +obj-$(CONFIG_MFD_OMAP_CONTROL) += omap-control-core.o obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o
drivers/mfd/omap-control-core.c new file +162 -0
162 lines not on this page · raw message
include/linux/mfd/omap_control.h new file +35 -0
@@ -0,0 +1,35 @@ +/* +* OMAP system control module header file +* +* Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ +* Contact: +* J Keerthy <[email protected]> +* Moiz Sonasath <[email protected]> +* Abraham, Kishon Vijay <[email protected]> +* Eduardo Valentin <[email protected]> +* Konstantin Baydarov <[email protected]> +* +* 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. +* +*/ + +#ifndef __DRIVERS_OMAP_CONTROL_H +#define __DRIVERS_OMAP_CONTROL_H + +#ifdef CONFIG_MFD_OMAP_CONTROL +u32 omap_control_status_read (void ); +#else +static inline u32 omap_control_status_read (void ) +{ +return 0 ; +} +#endif + +#endif /* __DRIVERS_OMAP_CONTROL_H */
Signature · 1 line
1.7.7.6
PATCH v4 2/4 mfd: omap: control: core system control driver
Hi,
Quoted 9 lines · Konstantin Baydarov
This patch introduces a MFD core device driver for OMAP system control module.
The control module allows software control of various static modes supported by the device. It is composed of two control submodules: general control module and device (padconfiguration) control module.
Quoted 8 lines
Device driver is probed with
postcore_initcall. Control module registerCONTROL_STATUSthat is needed byomap_type()is early mapped bypostcore_initcall_sync.Signed-off-by J Keerthy <[email protected]>Signed-off-by Kishon Vijay Abraham I <[email protected]>Signed-off-by Eduardo Valentin <[email protected]>Signed-off-by Konstantin Baydarov <[email protected]>
I believe this and the next 3 were authored by Eduardo. Also missing his
Quoted 1 line
From tag.
Signature · 8 lines
balbi -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120725/ee160db6/attachment.sig>
Tony Lindgren
maintainerPATCH v4 2/4 mfd: omap: control: core system control driver
In reply to Konstantin Baydarovdrivers/mfd/omap-control-core.c line 45
Quoted 5 lines · Konstantin Baydarov
drivers/mfd/omap-control-core.c new file +5
-0+ +u32 omap_control_status_read (void ) +{ +return __raw_readl (omap_control_base); +}
Ah OK it's changed here.. Sorry I was looking at the older version.
Quoted 12 lines
drivers/mfd/omap-control-core.c new file +12
-0+void __init of_omap_control_init (const struct of_device_id *matches) +{ +struct device_node *np; +struct property *pp =0 ; + +for_each_matching_node (np, matches) { + pp =of_find_property (np,"reg" ,NULL ); +if (pp) { + omap_control_phys_base = (unsigned long )be32_to_cpup (pp->value); + omap_control_mapsize = (size_t )be32_to_cpup ( (void *)((char *)pp->value +4 ) ); +/* +* Map control module register CONTROL_STATUS register:
drivers/mfd/omap-control-core.c line 135
Quoted 10 lines
drivers/mfd/omap-control-core.c new file +10
-0+* omap24xx - OMAP24XX_CONTROL_STATUS +* am33xx - AM33XX_CONTROL_STATUS +* omap34xx - OMAP343X_CONTROL_STATUS +* omap44xx - OMAP4_CTRL_MODULE_CORE_STATUS +* omap54xx - OMAP5XXX_CONTROL_STATUS +*/ + omap_control_base =ioremap (omap_control_phys_base, omap_control_mapsize); + } + } +}
You should probably add a function for setting omap_control_base separately from *set_globals* in arch/arm/mach-omap2/common.c. That way it's initialized early for id.c, and you can initialize everything else later as regular device drivers.
FYI, we want to initialize as much as possible late so we have proper debugging console set up in case things go wrong.
Regards,
Tony
Tony Lindgren
maintainerPATCH v4 2/4 mfd: omap: control: core system control driver
Quoted 38 lines · Tony Lindgren
drivers/mfd/omap-control-core.c line 45
Quoted 5 lines · Konstantin Baydarov
drivers/mfd/omap-control-core.c new file +5
-0+ +u32 omap_control_status_read (void ) +{ +return __raw_readl (omap_control_base); +}Ah OK it's changed here.. Sorry I was looking at the older version.
Quoted 12 lines
drivers/mfd/omap-control-core.c new file +12
-0+void __init of_omap_control_init (const struct of_device_id *matches) +{ +struct device_node *np; +struct property *pp =0 ; + +for_each_matching_node (np, matches) { + pp =of_find_property (np,"reg" ,NULL ); +if (pp) { + omap_control_phys_base = (unsigned long )be32_to_cpup (pp->value); + omap_control_mapsize = (size_t )be32_to_cpup ( (void *)((char *)pp->value +4 ) ); +/* +* Map control module register CONTROL_STATUS register: drivers/mfd/omap-control-core.c line 135
Quoted 10 lines
drivers/mfd/omap-control-core.c new file +10
-0+* omap24xx - OMAP24XX_CONTROL_STATUS +* am33xx - AM33XX_CONTROL_STATUS +* omap34xx - OMAP343X_CONTROL_STATUS +* omap44xx - OMAP4_CTRL_MODULE_CORE_STATUS +* omap54xx - OMAP5XXX_CONTROL_STATUS +*/ + omap_control_base =ioremap (omap_control_phys_base, omap_control_mapsize); + } + } +}You should probably add a function for setting
omap_control_baseseparately from *set_globals* inarch/arm/mach-omap2/common.c. That way it's initialized early forid.c, and you can initialize everything else later as regular device drivers.
Quoted 2 lines
FYI, we want to initialize as much as possible late so we have proper debugging console set up in case things go wrong.
Hmm it seems that omap_control_base is now only initialized for DT boot case? This will break booting on almost all systems..
Tony
Tony Lindgren
maintainerPATCH v4 2/4 mfd: omap: control: core system control driver
Quoted 39 lines · Tony Lindgren
Quoted 38 lines · Tony Lindgren
drivers/mfd/omap-control-core.c line 45
Quoted 5 lines · Konstantin Baydarov
drivers/mfd/omap-control-core.c new file +5
-0+ +u32 omap_control_status_read (void ) +{ +return __raw_readl (omap_control_base); +}Ah OK it's changed here.. Sorry I was looking at the older version.
Quoted 12 lines
drivers/mfd/omap-control-core.c new file +12
-0+void __init of_omap_control_init (const struct of_device_id *matches) +{ +struct device_node *np; +struct property *pp =0 ; + +for_each_matching_node (np, matches) { + pp =of_find_property (np,"reg" ,NULL ); +if (pp) { + omap_control_phys_base = (unsigned long )be32_to_cpup (pp->value); + omap_control_mapsize = (size_t )be32_to_cpup ( (void *)((char *)pp->value +4 ) ); +/* +* Map control module register CONTROL_STATUS register: drivers/mfd/omap-control-core.c line 135
Quoted 10 lines
drivers/mfd/omap-control-core.c new file +10
-0+* omap24xx - OMAP24XX_CONTROL_STATUS +* am33xx - AM33XX_CONTROL_STATUS +* omap34xx - OMAP343X_CONTROL_STATUS +* omap44xx - OMAP4_CTRL_MODULE_CORE_STATUS +* omap54xx - OMAP5XXX_CONTROL_STATUS +*/ + omap_control_base =ioremap (omap_control_phys_base, omap_control_mapsize); + } + } +}You should probably add a function for setting
omap_control_baseseparately from *set_globals* inarch/arm/mach-omap2/common.c. That way it's initialized early forid.c, and you can initialize everything else later as regular device drivers.
Quoted 5 lines
Quoted 2 lines
FYI, we want to initialize as much as possible late so we have proper debugging console set up in case things go wrong.
Hmm it seems that
omap_control_baseis now only initialized for DT boot case? This will break booting on almost all systems..
Looking at things more, looks like omap_type() is getting called early from timer.c. So maybe just let set_globals initialize omap_control_base and let omap_type() read that directly. That way the SCM core driver can behave like a regular device driver and it does not need to be initialized early.
Regards,
Tony
PATCH v4 2/4 mfd: omap: control: core system control driver
Hi, Tony.
Quoted 40 lines · Tony Lindgren
Quoted 39 lines · Tony Lindgren
Quoted 38 lines · Tony Lindgren
drivers/mfd/omap-control-core.c line 45
Quoted 5 lines · Konstantin Baydarov
drivers/mfd/omap-control-core.c new file +5
-0+ +u32 omap_control_status_read (void ) +{ +return __raw_readl (omap_control_base); +}Ah OK it's changed here.. Sorry I was looking at the older version.
Quoted 12 lines
drivers/mfd/omap-control-core.c new file +12
-0+void __init of_omap_control_init (const struct of_device_id *matches) +{ +struct device_node *np; +struct property *pp =0 ; + +for_each_matching_node (np, matches) { + pp =of_find_property (np,"reg" ,NULL ); +if (pp) { + omap_control_phys_base = (unsigned long )be32_to_cpup (pp->value); + omap_control_mapsize = (size_t )be32_to_cpup ( (void *)((char *)pp->value +4 ) ); +/* +* Map control module register CONTROL_STATUS register: drivers/mfd/omap-control-core.c line 135
Quoted 10 lines
drivers/mfd/omap-control-core.c new file +10
-0+* omap24xx - OMAP24XX_CONTROL_STATUS +* am33xx - AM33XX_CONTROL_STATUS +* omap34xx - OMAP343X_CONTROL_STATUS +* omap44xx - OMAP4_CTRL_MODULE_CORE_STATUS +* omap54xx - OMAP5XXX_CONTROL_STATUS +*/ + omap_control_base =ioremap (omap_control_phys_base, omap_control_mapsize); + } + } +}You should probably add a function for setting
omap_control_baseseparately from *set_globals* inarch/arm/mach-omap2/common.c. That way it's initialized early forid.c, and you can initialize everything else later as regular device drivers.FYI, we want to initialize as much as possible late so we have proper debugging console set up in case things go wrong.
Quoted 7 lines
Quoted 2 lines
Hmm it seems that
omap_control_baseis now only initialized for DT boot case? This will break booting on almost all systems..Looking at things more, looks like
omap_type()is getting called early fromtimer.c. So maybe just letset_globalsinitializeomap_control_baseand letomap_type()read that directly. That way the SCM core driver can behave like a regular device driver and it does not need to be initialized early.
Yes, omap_type() is called very early , that is why I'm using early_initcall for omap_control_base initialization.
Do you mean following?:
void __init omap2_set_globals_control(struct omap_globals *omap2_globals)
{
if (omap2_globals->ctrl)
omap2_ctrl_base = omap2_globals->ctrl;
if (omap2_globals->ctrl_pad)
omap4_ctrl_pad_base = omap2_globals->ctrl_pad;
omap_control_base = omap2_ctrl_base; // this line is added
} Or you suggest to move
void __init of_omap_control_init(const struct of_device_id *matches)
{
struct device_node *np;
struct property *pp = 0;
for_each_matching_node(np, matches) {
pp = of_find_property(np, "reg", NULL);
if(pp) {
omap_control_phys_base = (unsigned long)be32_to_cpup(pp->value);
omap_control_mapsize = (size_t)be32_to_cpup( (void*)((char*)pp->value + 4) );
/*
* Map control module register CONTROL_STATUS register:
* omap24xx - OMAP24XX_CONTROL_STATUS
* am33xx - AM33XX_CONTROL_STATUS
* omap34xx - OMAP343X_CONTROL_STATUS
* omap44xx - OMAP4_CTRL_MODULE_CORE_STATUS
* omap54xx - OMAP5XXX_CONTROL_STATUS
*/
omap_control_base = ioremap(omap_control_phys_base, omap_control_mapsize);
}
}
}into omap2_set_globals_control() ?
Also if we move omap_control_base initialization to omap2_set_globals_control(), than the initialization routine of drivers/mfd/omap-control-core.c become empty, because omap_control_base is the only thing that is initialized in omap-control-core driver.
BR,
Konstantin Baydarov.
Quoted 8 lines
Regards,
Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Tony Lindgren
maintainerPATCH v4 2/4 mfd: omap: control: core system control driver
Quoted 7 lines · Konstantin Baydarov
On 08/08/2012 06:39 PM, Tony Lindgren wrote:
Yes,
omap_type()is called very early , that is why I'm usingearly_initcallforomap_control_baseinitialization.Do you mean following?:
void__initomap2_set_globals_control(struct omap_globals *omap2_globals)
Quoted 9 lines
{
if (omap2_globals->ctrl)
omap2_ctrl_base = omap2_globals->ctrl;
if (omap2_globals->ctrl_pad)
omap4_ctrl_pad_base = omap2_globals->ctrl_pad;
omap_control_base = omap2_ctrl_base; // this line is added
}OK so we already have set_globals_control, but we're not using it.. No need for this line is added above.
Let's do the attached clean-up patch and just leave omap_control_base out of the driver for now as it's not currently needed there.
If omap_control_base is needed in the driver, then we need to pass it in the platform_data to the driver for the non-DT boot case, or parse it from DT like you're doing.
Regards,
Tony
From: Tony Lindgren <[email protected]>
Date: Wed, 8 Aug 2012 23:13:03 -0700
Subject: [PATCH] ARM: OMAP2+: Change omap_type() to use omap_ctrl_base_get()
We have the SoC specific ctrl_base already initialized in set_globals.
arch/arm/mach-omap2/id.c +9 -17
@@ -42,28 +42,20 @@ int omap_type(void) {u32 val =0 ; -if (cpu_is_omap24xx ()) { - val =omap_ctrl_readl (OMAP24XX_CONTROL_STATUS ); - }else if (soc_is_am33xx ()) { - val =omap_ctrl_readl (AM33XX_CONTROL_STATUS ); - }else if (cpu_is_omap34xx ()) { - val =omap_ctrl_readl (OMAP343X_CONTROL_STATUS ); - }else if (cpu_is_omap44xx ()) { - val =omap_ctrl_readl (OMAP4_CTRL_MODULE_CORE_STATUS ); - }else if (soc_is_omap54xx ()) { - val =omap_ctrl_readl (OMAP5XXX_CONTROL_STATUS ); + val =__raw_readl (omap_ctrl_base_get ()); +if (!val) { +pr_err ("Cannot detect omap type!\n" ); +return 0 ; + } + +if (soc_is_omap54xx ()) { val &=OMAP5_DEVICETYPE_MASK ; val >>=6 ; - goto out; }else { -pr_err ("Cannot detect omap type!\n" ); - goto out; + val &=OMAP2_DEVICETYPE_MASK ; + val >>=8 ; } - val &=OMAP2_DEVICETYPE_MASK ; - val >>=8 ; - -out:return val; }EXPORT_SYMBOL (omap_type);
PATCH v4 2/4 mfd: omap: control: core system control driver
In reply to Konstantin BaydarovHi, Tony.
Quoted 4 lines · Konstantin Baydarov
Yes,
omap_type()is called very early , that is why I'm usingearly_initcallforomap_control_baseinitialization.Do you mean following?:
void__initomap2_set_globals_control(struct omap_globals *omap2_globals)
Quoted 9 lines
{
if (omap2_globals->ctrl)
omap2_ctrl_base = omap2_globals->ctrl;
if (omap2_globals->ctrl_pad)
omap4_ctrl_pad_base = omap2_globals->ctrl_pad;
omap_control_base = omap2_ctrl_base; // this line is added
} Sorry for the confusion - the code above isn't correct. First, as omap-control-core.c driver maps only control module status register the omap_control_base should be renamed to omap_control_status_reg:
drivers/mfd/omap-control-core.c +1 -1
@@ -35,13 +35,15 @@#include <linux/of.h> #include <linux/of_address.h> -void __iomem *omap_control_base; +void __iomem *omap_control_status_reg;unsigned long omap_control_phys_base;size_t omap_control_mapsize;u32 omap_control_status_read (void )
Then, if you want to move omap_control_status_reg(omap_control_base) initialization to the omap2_set_globals_control(), it can be done following way:
arch/arm/mach-omap2/control.c +16 -0
@@ -149,6 +149,8 @@ static struct omap3_control_regs control_context;#define OMAP_CTRL_REGADDR (reg) (omap2_ctrl_base + (reg))#define OMAP4_CTRL_PAD_REGADDR (reg) (omap4_ctrl_pad_base + (reg)) +extern void __iomem *omap_control_status_reg; +void __init omap2_set_globals_control (struct omap_globals *omap2_globals) {if (omap2_globals->ctrl)
@@ -156,6 +158,20 @@ void __init omap2_set_globals_control(struct omap_globals *omap2_globals)if (omap2_globals->ctrl_pad) omap4_ctrl_pad_base = omap2_globals->ctrl_pad; + + omap_control_status_reg = omap2_ctrl_base; +if (cpu_is_omap24xx ()) + omap_control_status_reg +=OMAP24XX_CONTROL_STATUS ; +else if (soc_is_am33xx ()) + omap_control_status_reg +=AM33XX_CONTROL_STATUS ; +else if (cpu_is_omap34xx ()) + omap_control_status_reg +=OMAP343X_CONTROL_STATUS ; +else if (cpu_is_omap44xx ()) + omap_control_status_reg +=OMAP4_CTRL_MODULE_CORE_STATUS ; +else if (soc_is_omap54xx ()) + omap_control_status_reg +=OMAP5XXX_CONTROL_STATUS ; +else + omap_control_status_reg =0 ; }void __iomem *omap_ctrl_base_get (void )
Then omap_type() can be changed:
arch/arm/mach-omap2/id.c +11 -15
@@ -39,31 +39,27 @@ unsigned int omap_rev(void) }EXPORT_SYMBOL (omap_rev); +extern void __iomem *omap_control_status_reg; +int omap_type (void ) {u32 val =0 ; -if (cpu_is_omap24xx ()) { - val =omap_control_status_read (); - }else if (soc_is_am33xx ()) { - val =omap_control_status_read (); - }else if (cpu_is_omap34xx ()) { - val =omap_control_status_read (); - }else if (cpu_is_omap44xx ()) { +if (!omap_control_status_reg) { +pr_err ("Cannot detect omap type!\n" ); + goto out; + } + +if (!soc_is_omap54xx ()) { val =omap_control_status_read (); - }else if (soc_is_omap54xx ()) { + val &=OMAP2_DEVICETYPE_MASK ; + val >>=8 ; + }else { val =omap_control_status_read (); val &=OMAP5_DEVICETYPE_MASK ; val >>=6 ; - goto out; - }else { -pr_err ("Cannot detect omap type!\n" ); - goto out; } - val &=OMAP2_DEVICETYPE_MASK ; - val >>=8 ; - out:return val; }
BR,
Konstantin Baydarov.
Quoted 42 lines
Or you suggest to move
void__initof_omap_control_init(const struct of_device_id *matches){ struct device_node *np; struct property *pp = 0; for_each_matching_node(np, matches) { pp = of_find_property(np, "reg", NULL); if(pp) { omap_control_phys_base = (unsigned long)be32_to_cpup(pp->value); omap_control_mapsize = (size_t)be32_to_cpup( (void*)((char*)pp->value + 4) ); /* * Map control module register CONTROL_STATUS register: * omap24xx - OMAP24XX_CONTROL_STATUS * am33xx - AM33XX_CONTROL_STATUS * omap34xx - OMAP343X_CONTROL_STATUS * omap44xx - OMAP4_CTRL_MODULE_CORE_STATUS * omap54xx - OMAP5XXX_CONTROL_STATUS */ omap_control_base = ioremap(omap_control_phys_base, omap_control_mapsize); } } }into
omap2_set_globals_control()?Also if we move
omap_control_baseinitialization toomap2_set_globals_control(), than the initialization routine ofdrivers/mfd/omap-control-core.cbecome empty, becauseomap_control_baseis the only thing that is initialized in omap-control-core driver.BR,
Konstantin Baydarov.Quoted 7 lines
Regards,
Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Tony Lindgren
maintainerPATCH v4 2/4 mfd: omap: control: core system control driver
Quoted 11 lines · Konstantin Baydarov
Hi, Tony.
Quoted 8 lines · Konstantin Baydarov
Yes,
omap_type()is called very early , that is why I'm usingearly_initcallforomap_control_baseinitialization.Do you mean following?:
void__initomap2_set_globals_control(struct omap_globals *omap2_globals){ if (omap2_globals->ctrl) omap2_ctrl_base = omap2_globals->ctrl;
Quoted 6 lines
Quoted 5 lines
if (omap2_globals->ctrl_pad) omap4_ctrl_pad_base = omap2_globals->ctrl_pad; omap_control_base = omap2_ctrl_base; // this line is added }Sorry for the confusion - the code above isn't correct. First, as
omap-control-core.cdriver maps only control module status register theomap_control_baseshould be renamed toomap_control_status_reg:
Heh right :) And that makes the patch I posted wrong too.
Quoted 9 lines
(quoted diff) +5
-0@@ -156,6 +158,20 @@ void __init omap2_set_globals_control(struct omap_globals *omap2_globals) if (omap2_globals->ctrl_pad) omap4_ctrl_pad_base = omap2_globals->ctrl_pad; + + omap_control_status_reg = omap2_ctrl_base; + if (cpu_is_omap24xx()) + omap_control_status_reg += OMAP24XX_CONTROL_STATUS; + else if (soc_is_am33xx())
Review void __init omap2_set_globals_control(struct omap_globals *omap2_globals) · line 175
Quoted 10 lines
(quoted diff) +9
-0+ omap_control_status_reg += AM33XX_CONTROL_STATUS; + else if (cpu_is_omap34xx()) + omap_control_status_reg += OMAP343X_CONTROL_STATUS; + else if (cpu_is_omap44xx()) + omap_control_status_reg += OMAP4_CTRL_MODULE_CORE_STATUS; + else if (soc_is_omap54xx()) + omap_control_status_reg += OMAP5XXX_CONTROL_STATUS; + else + omap_control_status_reg = 0; }
We can get rid of the if else SoC check here too. And we can limit the control_status tinkering to id.c. Here's an updated clean-up patch.
Regards,
Tony
From: Tony Lindgren <[email protected]>
Date: Wed, 8 Aug 2012 23:13:03 -0700
Subject: [PATCH] ARM: OMAP2+: Initialize things for omap_type() to simplify
SoC detection
Let's rename omap2_set_globals_tap() to omap2_set_globals_id() and update the comments to remove old comments about map_io() as we don't need SoC detection for map_io() any longer.
Let's also initialize control_status_reg with omap2_set_globals_id() so we can avoid SoC tests every time omap_type() gets called.
Note that this patch sets the ti81xx to always return GP mode as the mode bits seem to be marked as reserved in ti81xx TRM.
arch/arm/mach-omap2/common.c +16 -2
@@ -31,7 +31,7 @@static void __init __omap2_set_globals (struct omap_globals *omap2_globals) { -omap2_set_globals_tap (omap2_globals); +omap2_set_globals_id (omap2_globals);omap2_set_globals_sdrc (omap2_globals);omap2_set_globals_control (omap2_globals);omap2_set_globals_prcm (omap2_globals);
@@ -45,6 +45,8 @@ static struct omap_globals omap242x_globals = { .sdrc = OMAP2_L3_IO_ADDRESS(OMAP2420_SDRC_BASE), .sms = OMAP2_L3_IO_ADDRESS(OMAP2420_SMS_BASE), .ctrl = OMAP2_L4_IO_ADDRESS(OMAP242X_CTRL_BASE), + .ctrl_status = OMAP2_L4_IO_ADDRESS(OMAP242X_CTRL_BASE) + + OMAP24XX_CONTROL_STATUS, .prm = OMAP2_L4_IO_ADDRESS(OMAP2420_PRM_BASE), .cm = OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE), };
@@ -68,6 +70,8 @@ static struct omap_globals omap243x_globals = { .sdrc = OMAP2_L3_IO_ADDRESS(OMAP243X_SDRC_BASE), .sms = OMAP2_L3_IO_ADDRESS(OMAP243X_SMS_BASE), .ctrl = OMAP2_L4_IO_ADDRESS(OMAP243X_CTRL_BASE), + .ctrl_status = OMAP2_L4_IO_ADDRESS(OMAP243X_CTRL_BASE) + + OMAP24XX_CONTROL_STATUS, .prm = OMAP2_L4_IO_ADDRESS(OMAP2430_PRM_BASE), .cm = OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE), };
@@ -91,6 +95,8 @@ static struct omap_globals omap3_globals = { .sdrc = OMAP2_L3_IO_ADDRESS(OMAP343X_SDRC_BASE), .sms = OMAP2_L3_IO_ADDRESS(OMAP343X_SMS_BASE), .ctrl = OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE), + .ctrl_status = OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE) + + OMAP343X_CONTROL_STATUS, .prm = OMAP2_L4_IO_ADDRESS(OMAP3430_PRM_BASE), .cm = OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE), };
@@ -117,6 +123,8 @@ static struct omap_globals ti81xx_globals = { .class = OMAP343X_CLASS, .tap = OMAP2_L4_IO_ADDRESS(TI81XX_TAP_BASE), .ctrl = OMAP2_L4_IO_ADDRESS(TI81XX_CTRL_BASE), + .ctrl_status = OMAP2_L4_IO_ADDRESS(TI81XX_CTRL_BASE) + + TI81XX_CONTROL_STATUS, .prm = OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE), .cm = OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE), };
@@ -140,6 +148,8 @@ static struct omap_globals am33xx_globals = { .class = AM335X_CLASS, .tap = AM33XX_L4_WK_IO_ADDRESS(AM33XX_TAP_BASE), .ctrl = AM33XX_L4_WK_IO_ADDRESS(AM33XX_CTRL_BASE), + .ctrl_status = AM33XX_L4_WK_IO_ADDRESS(AM33XX_CTRL_BASE) + + AM33XX_CONTROL_STATUS, .prm = AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE), .cm = AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE), };
@@ -160,6 +170,8 @@ static struct omap_globals omap4_globals = { .class = OMAP443X_CLASS, .tap = OMAP2_L4_IO_ADDRESS(OMAP443X_SCM_BASE), .ctrl = OMAP2_L4_IO_ADDRESS(OMAP443X_SCM_BASE), + .ctrl_status =OMAP2_L4_IO_ADDRESS (OMAP443X_SCM_BASE ) + + OMAP4_CTRL_MODULE_CORE_STATUS, .ctrl_pad = OMAP2_L4_IO_ADDRESS(OMAP443X_CTRL_BASE), .prm = OMAP2_L4_IO_ADDRESS(OMAP4430_PRM_BASE), .cm = OMAP2_L4_IO_ADDRESS(OMAP4430_CM_BASE),
@@ -183,6 +195,8 @@ static struct omap_globals omap5_globals = { .class = OMAP54XX_CLASS, .tap = OMAP2_L4_IO_ADDRESS(OMAP54XX_SCM_BASE), .ctrl = OMAP2_L4_IO_ADDRESS(OMAP54XX_SCM_BASE), + .ctrl_status =OMAP2_L4_IO_ADDRESS (OMAP54XX_SCM_BASE ) + + OMAP5XXX_CONTROL_STATUS, .ctrl_pad = OMAP2_L4_IO_ADDRESS(OMAP54XX_CTRL_BASE), .prm = OMAP2_L4_IO_ADDRESS(OMAP54XX_PRM_BASE), .cm = OMAP2_L4_IO_ADDRESS(OMAP54XX_CM_CORE_AON_BASE),
@@ -192,7 +206,7 @@ static struct omap_globals omap5_globals = {void __init omap2_set_globals_5xxx (void ) { -omap2_set_globals_tap (&omap5_globals); +omap2_set_globals_id (&omap5_globals);omap2_set_globals_control (&omap5_globals);omap2_set_globals_prcm (&omap5_globals); }
arch/arm/mach-omap2/common.h +2 -1
@@ -168,6 +168,7 @@ struct omap_globals {void __iomem *sdrc;/* SDRAM Controller */ void __iomem *sms;/* SDRAM Memory Scheduler */ void __iomem *ctrl;/* System Control Module */ +void __iomem *ctrl_status;/* Control status register */ void __iomem *ctrl_pad;/* PAD Control Module */ void __iomem *prm;/* Power and Reset Management */ void __iomem *cm;/* Clock Management */
@@ -184,7 +185,7 @@ void omap2_set_globals_ti81xx(void);void omap2_set_globals_am33xx (void );/* These get called from omap2_set_globals_xxxx(), do not call these */ -void omap2_set_globals_tap (struct omap_globals *); +void omap2_set_globals_id (struct omap_globals *);#if defined(CONFIG_SOC_HAS_OMAP2_SDRC )void omap2_set_globals_sdrc (struct omap_globals *);#else
arch/arm/mach-omap2/control.h +1 -0
@@ -59,6 +59,7 @@/* TI81XX spefic control submodules */ #define TI81XX_CONTROL_DEVCONF 0x600 +#define TI81XX_CONTROL_STATUS 0x040/* Control register offsets - read/write with omap_ctrl_{read,write}{bwl}() */
arch/arm/mach-omap2/id.c +20 -29
74 lines not on this page · raw message
PATCH v4 2/4 mfd: omap: control: core system control driver
In reply to Konstantin BaydarovHi Konstantin,
Quoted 165 lines · Konstantin Baydarov
This patch introduces a MFD core device driver for OMAP system control module.
The control module allows software control of various static modes supported by the device. It is composed of two control submodules: general control module and device (padconfiguration) control module.
Device driver is probed with
postcore_initcall. Control module registerCONTROL_STATUSthat is needed byomap_type()is early mapped bypostcore_initcall_sync.Signed-off-by J Keerthy <[email protected]>Signed-off-by Kishon Vijay Abraham I <[email protected]>Signed-off-by Eduardo Valentin <[email protected]>Signed-off-by Konstantin Baydarov <[email protected]>--- .../devicetree/bindings/mfd/omap_control.txt | 32 ++++ arch/arm/mach-omap2/Kconfig | 1 + arch/arm/plat-omap/Kconfig | 4 + drivers/mfd/Kconfig | 6 + drivers/mfd/Makefile | 1 + drivers/mfd/omap-control-core.c | 162 ++++++++++++++++++++ include/linux/mfd/omap_control.h | 35 +++++ 7 files changed, 241 insertions(+), 0 deletions(-) create mode 100644 Documentation/devicetree/bindings/mfd/omap_control.txt create mode 100644 drivers/mfd/omap-control-core.c create mode 100644 include/linux/mfd/omap_control.hDocumentation/devicetree/bindings/mfd/omap_control.txt new file +32
-0@@ -0,0 +1,32 @@ +* Texas Instrument OMAP System Control Module (SCM) bindings + +The control module allows software control of various static modes supported by +the device. The control module controls the settings of various device modules +through register configuration and internal signals. It also controls the pad +configuration, pin functional multiplexing, and the routing of internal signals +(such as PRCM signals or DMA requests) to output pins configured for hardware +observability. + +Required properties: +- compatible : Should be: + - "ti,omap3-control" for OMAP3 support + - "ti,omap4-control" for OMAP4 support + - "ti,omap5-control" for OMAP5 support + +OMAP specific properties: +- ti,hwmods: Name of the hwmod associated to the control module: + Should be "ctrl_module_core"; + +OMAP CONTROL_STATUS register: +reg = <0x4A0022C4 0x4>; /* CONTROL_STATUS register */ + +Examples: +ctrl_module_core: ctrl_module_core at 4A0022C4 { + compatible = "ti,omap4-control"; + #address-cells = <1>; + #size-cells = <1>; + /* ranges; */ + ti,hwmods = "ctrl_module_core"; + reg = <0x4A0022C4 0x4>; /* CONTROL_STATUS register */ +}; +arch/arm/mach-omap2/Kconfig +1
-0@@ -59,6 +59,7 @@ config ARCH_OMAP4 select ARM_ERRATA_720789 select ARCH_HAS_OPP select PM_RUNTIME if CPU_IDLE + select ARCH_HAS_CONTROL_MODULE select PM_OPP if PM select USB_ARCH_HAS_EHCI if USB_SUPPORT select ARM_CPU_SUSPEND if PMarch/arm/plat-omap/Kconfig +4
-0@@ -5,6 +5,10 @@ menu "TI OMAP Common Features" config ARCH_OMAP_OTG bool +config ARCH_HAS_CONTROL_MODULE + bool + select MFD_OMAP_CONTROL + choice prompt "OMAP System Type" default ARCH_OMAP2PLUSdrivers/mfd/Kconfig +6
-0@@ -823,6 +823,12 @@ config MFD_WL1273_CORE driver connects the radio-wl1273 V4L2 module and the wl1273 audio codec. +config MFD_OMAP_CONTROL + bool "Texas Instruments OMAP System control module" + depends on ARCH_HAS_CONTROL_MODULE + help + This is the core driver for system control module. + config MFD_OMAP_USB_HOST bool "Support OMAP USBHS core driver" depends on USB_EHCI_HCD_OMAP || USB_OHCI_HCD_OMAP3drivers/mfd/Makefile +1
-0@@ -107,6 +107,7 @@ obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o obj-$(CONFIG_MFD_VX855) += vx855.o obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o +obj-$(CONFIG_MFD_OMAP_CONTROL) += omap-control-core.o obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.odrivers/mfd/omap-control-core.c new file +35
-0@@ -0,0 +1,162 @@ +/* +* OMAP system control module driver file +* +* Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ +* Contacts: +* Based on original code written by: +* J Keerthy <[email protected]> +* Moiz Sonasath <[email protected]> +* MFD clean up and re-factoring: +* Eduardo Valentin <[email protected]> +* Konstantin Baydarov <[email protected]> +* +* 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 <linux/module.h> +#include <linux/export.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/err.h> +#include <linux/of_platform.h> +#include <linux/of_address.h> +#include <linux/mfd/core.h> +#include <linux/mfd/omap_control.h> + +#include <linux/of.h>
drivers/mfd/omap-control-core.c line 45
Quoted 10 lines
drivers/mfd/omap-control-core.c new file +10
-0+#include <linux/of_address.h> + +void __iomem *omap_control_base; +unsigned long omap_control_phys_base; +size_t omap_control_mapsize; + +u32 omap_control_status_read (void ) +{ +return __raw_readl (omap_control_base); +}
In AM335X, D_CAN IP uses single CONTROL module register to initialize D_CAN ram (D_CAN_RAMINIT). In order to enable D_CAN RAM we have to write to that register in sync with clock enable/disable.
How can I use this driver to handle this usecase? Similar to above API?
Currently this is handled using platform call back (example below)
In arch/arm/mach-omap2/devices.c:
static void d_can_hw_raminit(unsigned int instance, unsigned int enable)
{
u32 val;
/* Read the value */
val = readl(AM33XX_CTRL_REGADDR(AM33XX_DCAN_RAMINIT_OFFSET));
if (enable) {
/* Set to "1" */
val &= ~AM33XX_DCAN_RAMINIT_START(instance);
val |= AM33XX_DCAN_RAMINIT_START(instance);
writel(val, AM33XX_CTRL_REGADDR(AM33XX_DCAN_RAMINIT_OFFSET));
} else {
/* Set to "0" */
val &= ~AM33XX_DCAN_RAMINIT_START(instance);
writel(val, AM33XX_CTRL_REGADDR(AM33XX_DCAN_RAMINIT_OFFSET));
}
}In drivers/net/can/c_can/c_can.c:
void d_can_reset_ram(struct d_can_priv *d_can, unsigned int instance,
unsigned int enable)
{
if (d_can->ram_init)
d_can->ram_init(instance, enable);
}Thanks
AnilKumar