QUERY: How to handle SOC Configuration (Peripheral Multiplexing) in linux
Hello everybody,
In our SOC's (SPEArxxx), we have many peripheral sharing PL_GPIO pins and so only few peripherals can be selected in a configuration. This is configurable using a set of registers. Now the problem is to make following work:
1. How to do this selection in kernel in a simple way?
2. Based on this selection hardware registers needs to be configured.
I propose following solution to solve this issue, but i am not sure if it is acceptable by community.
Please see if it is fine. Or if there is any other way people may already be following for similar issues.
I have provided this selection from "make menuconfig", based on selection I configure hardware at initialization time. Basically these selections will decide which device is present in the system when it boots.
There are modes in which SOC can be configured and in these modes peripherals can be selected.
file: arch/arm/mach-spear3xx/Kconfig300
#
# SPEAr300 machine configuration file
#
if MACH_SPEAR300
choice
prompt "SPEAr300 Boards"
default BOARD_SPEAR300_EVB
config BOARD_SPEAR300_EVB
bool "SPEAr300 Evaluation Board"
help
Supports ST SPEAr300 Evaluation Board
endchoice
# SOC configuration for SPEAr 300 machine
menu "SPEAr300 SOC Configuration"
# Operation modes
choice
prompt "Select Operation Mode"
default PHOTO_FRAME_MODE
config NAND_MODE
bool "NAND Mode"
help
This mode will enable NAND Mode of SPEAr300 SOC.
config NOR_MODE
bool "NOR Mode"
help
This mode will enable NOR Mode of SPEAr300 SOC.
config PHOTO_FRAME_MODE
bool "PHOTO FRAME Mode"
help
This mode will enable PHOTO FRAME Mode of SPEAr300 SOC.
config LEND_IP_PHONE_MODE
bool "LEND IP PHONE (LOW END IP PHONE mode)" help
This mode will enable LEND IP PHONE Mode of SPEAr300 SOC.
config HEND_IP_PHONE_MODE
bool "HEND IP PHONE (HIGH END IP PHONE mode)" help
This mode will enable HEND IP PHONE Mode of SPEAr300 SOC.
config LEND_WIFI_PHONE_MODE
bool "LEND WIFI PHONE (LOW END WI-FI PHONE mode)" help
This mode will enable LEND WIFI PHONE Mode of SPEAr300 SOC.
config HEND_WIFI_PHONE_MODE
bool "HEND WIFI PHONE (HIGH END WI-FI PHONE mode)" help
This mode will enable HEND WIFI PHONE Mode of SPEAr300 SOC.
config ATA_PABX_wI2S_MODE
bool "ATA PABX wI2S (ATA PABX without I2S) mode" help
This mode will enable ATA PABX wI2S Mode of SPEAr300 SOC.
config ATA_PABX_I2S_MODE
bool "ATA PABX I2S (ATA PABX with I2S) Mode" help
This mode will enable ATA PABX I2S Mode of SPEAr300 SOC.
config CAMl_LCDw_MODE
bool "CAMl LCDw (8 bit CAMERA without LCD) Mode" help
This mode will enable CAMl LCDw Mode of SPEAr300 SOC.
config CAMu_LCD_MODE
bool "CAMu LCD (14 bit CAMERA with LCD) Mode" help
This mode will enable CAMu LCD Mode of SPEAr300 SOC.
config CAMu_wLCD_MODE
bool "CAMu wLCD (14 bit CAMERA without LCD) Mode" help
This mode will enable CAMu wLCD Mode of SPEAr300 SOC.
config CAMl_LCD_MODE
bool "CAMl LCD (8 bit CAMERA with LCD) Mode" help
This mode will enable CAMl LCD Mode of SPEAr300 SOC.
endchoice #Select Operation Mode
#mode specific peripherals
#FSMC
config FSMC_2_CHIPS
bool "FSMC 2 CHIPS - Disables FIRDA" depends on NAND_MODE || NOR_MODE || PHOTO_FRAME_MODE || \ ATA_PABX_wI2S_MODE || ATA_PABX_I2S_MODE depends on !FSMC_4_CHIPS default n
config FSMC_4_CHIPS
bool "FSMC 4 CHIPS - Disables UART and FIRDA" depends on NAND_MODE || NOR_MODE || PHOTO_FRAME_MODE || \ ATA_PABX_wI2S_MODE || ATA_PABX_I2S_MODE default n
#Keyboard
config KEYBOARD
bool "Keyboard" depends on LEND_IP_PHONE_MODE || HEND_IP_PHONE_MODE || \ LEND_WIFI_PHONE_MODE || HEND_WIFI_PHONE_MODE || CAMl_LCDw_MODE || \ CAMu_LCD_MODE || CAMu_wLCD_MODE || CAMl_LCD_MODE default y
#CLCD
config CLCD_1
bool "CLCD - Disables TIMER 1-2 and TIMER 3-4" depends on PHOTO_FRAME_MODE
default n
config CLCD_2
bool "CLCD - Disables TIMER 3-4" depends on HEND_IP_PHONE_MODE || HEND_WIFI_PHONE_MODE || \ CAMu_LCD_MODE || CAMl_LCD_MODE default n
#Telecom_GPIO Combinations
config TL_GPIO_1
bool "Telecom GPIO - Disables GMAC" depends on PHOTO_FRAME_MODE || CAMu_LCD_MODE || CAMl_LCD_MODE default n
config TL_GPIO_2
bool "Telecom GPIO - Disables TIMER 1-2, Timer 3-4 and GMAC" depends on LEND_IP_PHONE_MODE || LEND_WIFI_PHONE_MODE default n
config TL_GPIO_3
bool "Telecom GPIO - Disables TIMER 3-4 and GMAC" depends on ATA_PABX_I2S_MODE || CAMl_LCDw_MODE || CAMu_wLCD_MODE default n
config TL_GPIO_4
bool "Telecom GPIO - Disables TIMER 1-2 and GMAC" depends on HEND_IP_PHONE_MODE || HEND_WIFI_PHONE_MODE default n
config TL_GPIO_5
bool "Telecom GPIO - Disables TIMER 1-2-3-4, UART MODEM and GMAC" depends on ATA_PABX_wI2S_MODE
default n
#TL_TDM Combinations
config TL_TDM
bool "Telecom TDM - Disables UART MODEM and SSP CHIP SELECTS" depends on PHOTO_FRAME_MODE || LEND_IP_PHONE_MODE || \ HEND_IP_PHONE_MODE || LEND_WIFI_PHONE_MODE || HEND_WIFI_PHONE_MODE || \ ATA_PABX_wI2S_MODE || ATA_PABX_I2S_MODE || CAMl_LCDw_MODE || \ CAMu_LCD_MODE || CAMu_wLCD_MODE || CAMl_LCD_MODE default n
#TL_SPI_I2C Combinations
config TL_SPI_I2C
bool "Telecom SPI-CS I2C-CLK - Disables TIMER 1-2 and TIMER 3-4" depends on LEND_IP_PHONE_MODE || HEND_IP_PHONE_MODE || \ LEND_WIFI_PHONE_MODE || HEND_WIFI_PHONE_MODE || ATA_PABX_wI2S_MODE || \ ATA_PABX_I2S_MODE || CAMl_LCDw_MODE || CAMl_LCD_MODE default n
#TL_CAMERA Combinations
config TL_CAMERA_1
bool "Telecom CAMERA - Disables GMAC" depends on CAMl_LCDw_MODE || CAMl_LCD_MODE default n
config TL_CAMERA_2
bool "Telecom CAMERA - Disables TIMER 1-2, TIMER 3-4 and GMAC" depends on CAMu_LCD_MODE || CAMu_wLCD_MODE default n
#TL_DAC Combinations
config TL_DAC
bool "Telecom DAC - Disables Timer A" depends on ATA_PABX_I2S_MODE || CAMl_LCDw_MODE || \ CAMu_LCD_MODE || CAMu_wLCD_MODE || CAMl_LCD_MODE default n
#TL_I2S Combinations
config TL_I2S
bool "Telecom I2S - Disables UART MODEM and SDIO" depends on LEND_IP_PHONE_MODE || HEND_IP_PHONE_MODE || \ LEND_WIFI_PHONE_MODE || HEND_WIFI_PHONE_MODE || \ ATA_PABX_I2S_MODE || CAMl_LCDw_MODE || CAMu_LCD_MODE || \ CAMu_wLCD_MODE || CAMl_LCD_MODE depends on !SDIO_1_4 && !SDIO_8 default n
#Boot Pins Combinations
config BOOT_PINS
bool "BOOT PINS - Disables UART MODEM, TIMER 1-2 and TIMER 3-4" depends on NAND_MODE || NOR_MODE default n
#SDIO Combinations
config SDIO_1_4
bool "SDIO 1-4 Bit - Enable GPIO1 and Disables GPIO0 Pin 0 TO 5 and I2S" depends on PHOTO_FRAME_MODE || LEND_IP_PHONE_MODE || \ HEND_IP_PHONE_MODE || LEND_WIFI_PHONE_MODE || \ HEND_WIFI_PHONE_MODE || CAMl_LCDw_MODE || \ CAMu_LCD_MODE || CAMu_wLCD_MODE || CAMl_LCD_MODE || \ ATA_PABX_wI2S_MODE || ATA_PABX_I2S_MODE depends on !SDIO_8 select GPIO1 default n
config SDIO_8
bool "SDIO 8 bit - Enable GPIO1 and Disables GPIO0 Pin 0 TO 5, GMAC and I2S" depends on PHOTO_FRAME_MODE || LEND_IP_PHONE_MODE || \ HEND_IP_PHONE_MODE || LEND_WIFI_PHONE_MODE || \ HEND_WIFI_PHONE_MODE || CAMl_LCDw_MODE || \ CAMu_LCD_MODE || CAMu_wLCD_MODE || CAMl_LCD_MODE select GPIO1 default n
#GPIO Combinations
config GPIO1
bool "GPIO1 - Disables UART MODEM, TIMER 1-2 and TIMER 3-4" depends on PHOTO_FRAME_MODE
default n
#peripherals available in all modes
config FIRDA
bool "FIRDA" depends on !FSMC_4_CHIPS && !FSMC_2_CHIPS default y
config I2C
bool "I2C" default y
config SSP
bool "SSP"
default y
config SSP_CHIP_SELECTS
bool "SSP CHIP SELECTS"
depends on !TL_TDM
default y
config GMAC
bool "GMAC" depends on !TL_GPIO_1 && !TL_GPIO_2 && !TL_GPIO_3 && !TL_GPIO_4 && \ !TL_GPIO_5 && !TL_CAMERA_1 && !TL_CAMERA_2 && !SDIO_8 default y
config GPIO0_PIN_0_TO_5
bool "GPIO0 Pin 0 TO 5" depends on !SDIO_1_4 && !SDIO_8 default y
config UART
bool "UART"
depends on !FSMC_4_CHIPS
default y
config UART_MODEM
bool "UART MODEM" depends on !TL_GPIO_5 && !TL_TDM && !TL_I2S && !BOOT_PINS && !GPIO1 default y
config TIMER_1_2
bool "TIMER 1-2" depends on !CLCD_1 && !TL_GPIO_2 && !TL_GPIO_4 && !TL_GPIO_5 && \ !TL_SPI_I2C && !TL_CAMERA_2 && !TL_DAC && !BOOT_PINS && !GPIO1 default y
config TIMER_3_4
bool "TIMER 3-4" depends on !CLCD_1 && !CLCD_2 && !TL_GPIO_2 && !TL_GPIO_3 && \ !TL_GPIO_5 && !TL_SPI_I2C && !BOOT_PINS && !GPIO1 && !TL_CAMERA_2 default y
endmenu #SOC Configuration
endif #MACH_SPEAR300
file: arch/arm/mach-spear3xx/spear300.c
/* macros with configuration values for modes */
#define S300_NAND_MODE 1
#define S300_NOR_MODE 2
#define S300_PHOTO_FRAME_MODE 3
#define S300_LEND_IP_PHONE_MODE 4
#define S300_HEND_IP_PHONE_MODE 5
#define S300_LEND_WIFI_PHONE_MODE 6
#define S300_HEND_WIFI_PHONE_MODE 7
#define S300_ATA_PABX_wI2S_MODE 8
#define S300_ATA_PABX_I2S_MODE 9
#define S300_CAMl_LCDw_MODE 10
#define S300_CAMu_LCD_MODE 11
#define S300_CAMu_LCDw_MODE 12
#define S300_CAMl_LCD_MOD 13
/* macros with configuration values for peripherals */
#define S300_FIRDA ~0x00004000
#define S300_I2C ~0x00002000
#define S300_SSP_ENHANCED ~0x00001000
#define S300_SSP_BASIC ~0x00000800
#define S300_MII ~0x00000400
#define S300_LEG_GPIO ~0x000003f0
#define S300_UART_ENHANCED ~0x00000008
#define S300_UART_BASIC ~0x00000004
#define S300_TIMER_B ~0x00000002
#define S300_TIMER_A ~0x00000000
void spear300_configure(void)
{
/* two variables to temporarily store values of two registers */
volatile unsigned int *config_reg1;
volatile unsigned int *config_reg2;#ifndef CONFIG_FIRDA *config_reg1 &= FIRDA; #endif #ifndef CONFIG_I2C *config_reg1 &= I2C; #endif #ifndef CONFIG_SSP_CHIP_SELECTS *config_reg1 &= SSP_CHIP_SELECTS; #endif #ifndef CONFIG_SSP *config_reg1 &= SSP; #endif #ifndef CONFIG_GMAC *config_reg1 &= GMAC; #endif #ifndef CONFIG_GPIO0_PIN_0_TO_5 *config_reg1 &= GPIO0_PIN_0_TO_5; #endif #ifndef CONFIG_UART_MODEM *config_reg1 &= UART_MODEM; #endif #ifndef CONFIG_UART *config_reg1 &= UART; #endif #ifndef CONFIG_TIMER_3_4 *config_reg1 &= TIMER_3_4; #endif #ifndef CONFIG_TIMER_1_2 *config_reg1 &= TIMER_1_2;
#endif
#ifdef CONFIG_NAND_MODE *config_reg2 = NAND_MODE; #endif #ifdef CONFIG_NOR_MODE *config_reg2 = NOR_MODE; #endif #ifdef CONFIG_PHOTO_FRAME_MODE *config_reg2 = PHOTO_FRAME_MODE; #endif #ifdef CONFIG_LEND_IP_PHONE_MODE *config_reg2 = LEND_IP_PHONE_MODE; #endif #ifdef CONFIG_HEND_IP_PHONE_MODE *config_reg2 = HEND_IP_PHONE_MODE; #endif #ifdef CONFIG_LEND_WIFI_PHONE_MODE *config_reg2 = LEND_WIFI_PHONE_MODE; #endif #ifdef CONFIG_HEND_WIFI_PHONE_MODE *config_reg2 = HEND_WIFI_PHONE_MODE; #endif #ifdef CONFIG_ATA_PABX_wI2S_MODE *config_reg2 = ATA_PABX_wI2S_MODE; #endif #ifdef CONFIG_ATA_PABX_I2S_MODE *config_reg2 = ATA_PABX_I2S_MODE; #endif #ifdef CONFIG_CAMl_LCDw_MODE *config_reg2 = CAMl_LCDw_MODE; #endif #ifdef CONFIG_CAMu_LCD_MODE *config_reg2 = CAMu_LCD_MODE; #endif #ifdef CONFIG_CAMu_wLCD_MODE *config_reg2 = CAMu_LCDw_MODE; #endif #ifdef CONFIG_CAMl_LCD_MODE *config_reg2 = CAMl_LCD_MODE;
#endif
/* At the end we can write these values to actual registers */ }
regards,
viresh kumar.
Quoted 6 lines · Viresh KUMAR
In our SOC's (SPEArxxx), we have many peripheral sharing
PL_GPIOpins and so only few peripherals can be selected in a configuration. This is configurable using a set of registers. Now the problem is to make following work:1. How to do this selection in kernel in a simple way?
2. Based on this selection hardware registers needs to be configured.
Why can't you make the drivers acquire and setup the necessary pins during probe?
Among other benefits, it enables you to use the same kernel image and device drivers as modules -- if a GPIO can be used by two different device controllers, you
can switch the 'mode' of the board by simple rmmod-insmod
Hello Jassi,
Quoted 5 lines · jassi brar
Quoted 4 lines · Viresh KUMAR
In our SOC's (SPEArxxx), we have many peripheral sharing
PL_GPIOpins and so only few peripherals can be selected in a configuration. This is configurable using a set of registers. Now the problem is to make following work:
Quoted 8 lines
Quoted 2 lines
1. How to do this selection in kernel in a simple way?
2. Based on this selection hardware registers needs to be configured.Why can't you make the drivers acquire and setup the necessary pins during probe?
Among other benefits, it enables you to use the same kernel image and device drivers as modules -- if a GPIO can be used by two different device controllers, you
can switch the 'mode' of the board by simple rmmod-insmod
I think the problem is we cannot change the standard drivers (already in the mainline). So if the standard driver doesn't support this in its probe, then how should we manage this?
Further these configurations are board dependent, so I think driver must be independent of this.
regards
Shiraz
Quoted 17 lines · Shiraz HASHIM
Hello Jassi,
Quoted 5 lines · jassi brar
Quoted 4 lines · Viresh KUMAR
In our SOC's (SPEArxxx), we have many peripheral sharing
PL_GPIOpins and so only few peripherals can be selected in a configuration. This is configurable using a set of registers. Now the problem is to make following work:Quoted 8 lines
Quoted 2 lines
1. How to do this selection in kernel in a simple way?
2. Based on this selection hardware registers needs to be configured.Why can't you make the drivers acquire and setup the necessary pins during probe?
Among other benefits, it enables you to use the same kernel image and device drivers as modules -- if a GPIO can be used by two different device controllers, you
can switch the 'mode' of the board by simple rmmod-insmod
Quoted 3 lines
I think the problem is we cannot change the standard drivers (already in the mainline). So if the standard driver doesn't support this in its probe, then how should we manage this?
Though the drivers should already have done that, but still you can always submit patches to improve.
Quoted 2 lines
Further these configurations are board dependent, so I think driver must be independent of this.
Don't really understand this. Viresh said that the SoC can configure GPIOs for a controller or the other, which is quite common and is handled during probe. Also, it's desirable to have one kernel image run on many machines with the same SOC.
Quoted 24 lines · jassi brar
Quoted 17 lines · Shiraz HASHIM
Hello Jassi,
Quoted 5 lines · jassi brar
Quoted 4 lines · Viresh KUMAR
In our SOC's (SPEArxxx), we have many peripheral sharing
PL_GPIOpins and so only few peripherals can be selected in a configuration. This is configurable using a set of registers. Now the problem is to make following work:Quoted 8 lines
Quoted 2 lines
1. How to do this selection in kernel in a simple way?
2. Based on this selection hardware registers needs to be configured.Why can't you make the drivers acquire and setup the necessary pins during probe?
Among other benefits, it enables you to use the same kernel image and device drivers as modules -- if a GPIO can be used by two different device controllers, you
can switch the 'mode' of the board by simple rmmod-insmodQuoted 3 lines
I think the problem is we cannot change the standard drivers (already in the mainline). So if the standard driver doesn't support this in its probe, then how should we manage this?
Though the drivers should already have done that, but still you can always submit patches to improve.
Quoted 7 lines
Quoted 2 lines
Further these configurations are board dependent, so I think driver must be independent of this.
Don't really understand this. Viresh said that the SoC can configure GPIOs for a controller or the other, which is quite common and is handled during probe. Also, it's desirable to have one kernel image run on many machines with the same SOC.
Actually, different peripherals share IO Pads (PL_GPIOs) and GPIO lines. Sending patch for drivers to support this doesn't look a great idea to me. Further this may cause problems to users, for example: User have entered a inserted a module and by mistake or lack of knowledge, he disables already working IP. Now with Kconfig concept this is taken care of at the beginning only. User can't select peripherals which can't be enabled simultaneously.
Quoted 27 lines · Viresh KUMAR
Quoted 26 lines · jassi brar
Quoted 17 lines · Shiraz HASHIM
Hello Jassi,
Quoted 5 lines · jassi brar
Quoted 4 lines · Viresh KUMAR
In our SOC's (SPEArxxx), we have many peripheral sharing
PL_GPIOpins and so only few peripherals can be selected in a configuration. This is configurable using a set of registers. Now the problem is to make following work:Quoted 8 lines
Quoted 2 lines
1. How to do this selection in kernel in a simple way?
2. Based on this selection hardware registers needs to be configured.Why can't you make the drivers acquire and setup the necessary pins during probe?
Among other benefits, it enables you to use the same kernel image and device drivers as modules -- if a GPIO can be used by two different device controllers, you
can switch the 'mode' of the board by simple rmmod-insmodQuoted 3 lines
I think the problem is we cannot change the standard drivers (already in the mainline). So if the standard driver doesn't support this in its probe, then how should we manage this?
Though the drivers should already have done that, but still you can always submit patches to improve.
Quoted 2 lines
Further these configurations are board dependent, so I think driver must be independent of this.
Quoted 7 lines
Quoted 5 lines
Don't really understand this. Viresh said that the SoC can configure GPIOs for a controller or the other, which is quite common and is handled during probe. Also, it's desirable to have one kernel image run on many machines with the same SOC.
Actually, different peripherals share IO Pads (
PL_GPIOs) and GPIO lines. Sending patch for drivers to support this doesn't look a great idea to me.
I didn't suggest your driver be GPIO specific.
A callback can be provided by platform layer(SoC specific) and the set of GPIOs to use with a controller can be provided by the machine layer(board specific). The driver only needs to make a call during probe time.
Quoted 5 lines
Further this
may cause problems to users, for example: User have entered a inserted a module and by mistake or lack of knowledge, he disables already working IP. Now withKconfigconcept this is taken care of at the beginning only. User can't select peripherals which can't be enabled simultaneously.
For a particular device only relevant modules will be loaded at boot-time. If two mutually exclusive functionalities are possible only then rmmod-insmod is needed -- say, AC97 or I2S audio mode.
Quoted 7 lines · Viresh KUMAR
Actually, different peripherals share IO Pads (
PL_GPIOs) and GPIO lines. Sending patch for drivers to support this doesn't look a great idea to me. Further this may cause problems to users, for example: User have entered a inserted a module and by mistake or lack of knowledge, he disables already working IP. Now withKconfigconcept this is taken care of at the beginning only. User can't select peripherals which can't be enabled simultaneously.
Better to leave that knowledge out of the drivers and Kconfig, and just let the system "blow up" at runtime if a bad combination is attempted. Making the system any smarter than that leads to drivers that are really difficult to reuse elsewhere.
The "blow up" scenario isn't usually literal, of course, and the problem is almost always spotted very early in the development effort. So it doesn't lead to problems. The alternatives do.
b.g.
Signature · 4 lines
Bill Gatliff Embedded systems training and consulting http://billgatliff.com bgat at billgatliff.com
Quoted 5 lines · Viresh KUMAR
Actually, different peripherals share IO Pads (
PL_GPIOs) and GPIO lines. Sending patch for drivers to support this doesn't look a great idea to me. Further this may cause problems to users, for example: User have entered a inserted a module and by mistake or lack of knowledge, he disables already working IP.
That's a _very_ bad idea - for the reasons Bill and you have pointed out. Moreover, what's the situation if a needed driver is left out?
If the pins are left floating, then your current consumption increases - the standard CMOS input configuration is two MOS transistors, and with their 'gate' (input) floating at half supply, both are partially turned on, and power flows from positive, through both transistors to ground.
Floating inputs are very bad news for power consumption - you really want to avoid them at all cost.
That means if you leave the configuration of pins to modular drivers, pins are left unconfigured, and you could have some of them floating increasing your power consumption.
Most normal boards dedicate the function of pins at board design time; they generally don't change at run time. For the majority of cases, it makes sense to configure all MUX pins at kernel boot time in the board support code, which ensures that everything is correctly set for the entire board in one central, easy to verify place.
Quoted 3 lines · Russell King - ARM Linux
Most normal boards dedicate the function of pins at board design time;
Agreed.
As I see it, the IRQF_SHARED thing is just a convenience hack for PC motherboards, and for platform authors who haven't gotten around to demultiplexing all their shared interrupts. :)
b.g.
Signature · 4 lines
Bill Gatliff Embedded systems training and consulting http://billgatliff.com bgat at billgatliff.com
Quoted 4 lines · Russell King - ARM Linux
On Mon, Mar 15, 2010 at 12:02:14PM +0530, Viresh KUMAR wrote:
That means if you leave the configuration of pins to modular drivers, pins are left unconfigured, and you could have some of them floating increasing your power consumption.
Thanks for the invaluable insight.
Sometimes, I wish there was some mechanism to automatically compile such advices, from experts in long and numerous threads of discussion, into some checklist/faq for developers.
Quoted 8 lines · Shiraz HASHIM
I think the problem is we cannot change the standard drivers (already in the mainline). So if the standard driver doesn't support this in its probe, then how should we manage this?
Further these configurations are board dependent, so I think driver must be independent of this.
What I think you really want is for your board-specific code (or some helper code elsewhere in your mach-* directory) to do the pin assignments, and the drivers just assume that the pins are all right. That's the approach used in OMAP2 and AT91, among others, and it seems to work out just fine.
If you assume that the driver "just knows" what the multiplexer settings need to be, then sooner or later that same peripheral gets used in a different SoC and that assumption has to get tossed out. That's happening some with the AT91 drivers that can also be used on AVR32 chips. Best to avoid that extra work by putting the platform-specific knowledge where it belongs: in the platform-specific code.
b.g.
Signature · 4 lines
Bill Gatliff Embedded systems training and consulting http://billgatliff.com bgat at billgatliff.com
Quoted 7 lines
What I think you really want is for your board-specific code (or some helper code elsewhere in your mach-* directory) to do the pin assignments, and the drivers just assume that the pins are all right. That's the approach used in OMAP2 and AT91, among others, and it seems to work out just fine.
Bill,
What you and Russell are saying is a little bit different from what I got since
now, with people suggesting to implement a single linux image which is then configured at runtime thru (for example) bootargs.
Now you both are saying that compile time options are better, correct?
So, we have two choices:
1. Stay as it is, which means to use menuconfig options.
2. Provide board-specific code in the mach-spear directory.
You are suggesting 2, which also seems to be the pin_config stuff inside mach-pxa. Am I aligned?
If so, I think we can proceed in the suggested way. It looks to me very clean.
Quoted 7 lines
If you assume that the driver "just knows" what the multiplexer settings need to be, then sooner or later that same peripheral gets used in a different SoC and that assumption has to get tossed out. That's happening some with the AT91 drivers that can also be used on AVR32 chips. Best to avoid that extra work by putting the platform-specific knowledge where it belongs: in the platform-specific code.
Correct.
I think this has never been our intention anyway.
The drivers shouldn't know anything about platform-specific stuff, as they are expected to work across multiple platform.
Thx,
Arm
Signature · 8 lines
-- "Every step appears to be the unavoidable consequence of the -- preceding one." (A. Einstein) -- Armando Visconti Mobile: (+39) 346 8879146 Senior SW Engineer Fax: (+39) 02 93519290 CPG Work: (+39) 02 93519683 Computer System Division e-mail: armando.visconti at st.com ST Microelectronics TINA: 051 4683
Quoted 8 lines · Armando VISCONTI
Quoted 7 lines
What I think you really want is for your board-specific code (or some helper code elsewhere in your mach-* directory) to do the pin assignments, and the drivers just assume that the pins are all right. That's the approach used in OMAP2 and AT91, among others, and it seems to work out just fine.
Quoted 8 lines
Bill,
What you and Russell are saying is a little bit different from what I got since
now, with people suggesting to implement a single linux image which is then configured at runtime thru (for example) bootargs.Now you both are saying that compile time options are better, correct?
No.
Quoted 7 lines
So, we have two choices:
1. Stay as it is, which means to use menuconfig options.
2. Provide board-specific code in the mach-spear directory.You are suggesting 2, which also seems to be the
pin_configstuff inside mach-pxa. Am I aligned?
Yes. Another good example that you might have a look at is arch/arm/mach-kirkwood/*-setup.c. Those files are defining what and how each of those particular machine targets should be configured. And for the multiplexed pin config, there is a mpp.h which statically defines all the possible combinations for each pin, including the function type (GPIO or dedicated function), the direction, and a bitmask of specific SOC versions each definition may apply to. Then a list of those is passed to kirkwood_mpp_conf() which performs the appropriate validation and configuration.
Please take the time to look at a couple examples like those. You should get a good idea of the overall strategy and one of those might be a better example than the others to follow for your particular hardware.
Nicolas
Quoted 2 lines · Armando VISCONTI
Now you both are saying that compile time options are better, correct?
That's what I'm saying, yes. Rmk will have to speak for himself. :)
Quoted 8 lines
So, we have two choices:
1. Stay as it is, which means to use menuconfig options.
2. Provide board-specific code in the mach-spear directory.You are suggesting 2, which also seems to be the
pin_configstuff inside mach-pxa. Am I aligned?
Yes, though the mach-pxa guys aren't the only ones handling pin muxes--- see also at91 and omap2. There are lots of different ways to set up the API for this functionality. I have no idea which one is better, I just take what I'm given. :)
Quoted 7 lines
Quoted 7 lines
If you assume that the driver "just knows" what the multiplexer settings need to be, then sooner or later that same peripheral gets used in a different SoC and that assumption has to get tossed out. That's happening some with the AT91 drivers that can also be used on AVR32 chips. Best to avoid that extra work by putting the platform-specific knowledge where it belongs: in the platform-specific code.
Quoted 5 lines
Correct.
I think this has never been our intention anyway.
The drivers shouldn't know anything about platform-specific stuff, as they are expected to work across multiple platform.
Keep in mind that to the driver, anything non-driver is "platform-specific". For a driver to be truly reusable, then, it can't assume anything about where its pins are, what interrupt channel it's tied to, or anything else like that. All those things are subject to change as the peripheral gets re-used across SoCs. Don't let them sneak into the driver code.
It's true that for a specific SoC, you *do* know such things. So you handle that the way the at91 guys have done: you provide a at91sam9263_devices.c:at91_add_device_usbh(struct at91_usbh_data *data), and _that_ function sets up pins, etc. before it registers the generic platform device. The driver is always a generic platform one, and gets its information only from ordinary resource specifications. It can assume that SoC-specific stuff like pin mux setup, etc. has been taken care of already--- it's completely platform-agnostic.
Later on, a module can do all the pin mux stuff itself and then register the "at91_ohci" platform device if for some reason it doesn't like the way existing code does things. There's no specific need to modify kernel code just because you've provided an SoC-specific "wrapper" around the platform device registration, it's just a convenience function that you can choose to use, or not.
HTH,
b.g.
Signature · 4 lines
Bill Gatliff Embedded systems training and consulting http://billgatliff.com bgat at billgatliff.com
Quoted 5 lines · Bill Gatliff
It's true that for a specific SoC, you *do* know such things. So you handle that the way the at91 guys have done: you provide a at91sam9263_devices.c:at91_add_device_usbh(struct
at91_usbh_data*data), and _that_ function sets up pins, etc. before it registers the generic platform device. The driver is always a generic platform one, and gets
That does depend on the SoC, at least for the pin muxing - with some SoCs there's a lot of options for where the signals are brought out so the pin mux configuration really does need to be board specific.
Quoted 11 lines · Mark Brown
Quoted 5 lines · Bill Gatliff
It's true that for a specific SoC, you *do* know such things. So you handle that the way the at91 guys have done: you provide a at91sam9263_devices.c:at91_add_device_usbh(struct
at91_usbh_data*data), and _that_ function sets up pins, etc. before it registers the generic platform device. The driver is always a generic platform one, and getsThat does depend on the SoC, at least for the pin muxing - with some SoCs there's a lot of options for where the signals are brought out so the pin mux configuration really does need to be board specific.
Additionally the muxing needs to be done dynamically in some cases.
For example, the GPIO pins need to be dynamically remuxed for the PM idle modes on omaps.
Tony
Quoted 7 lines · Tony Lindgren
Quoted 4 lines · Mark Brown
That does depend on the SoC, at least for the pin muxing - with some SoCs there's a lot of options for where the signals are brought out so the pin mux configuration really does need to be board specific.
Quoted 5 lines
Additionally the muxing needs to be done dynamically in some cases.
For example, the GPIO pins need to be dynamically remuxed for the PM idle modes on omaps.
It's times like this I recall just how deliciously simple the at91 chips are. :)
b.g.
Signature · 4 lines
Bill Gatliff Embedded systems training and consulting http://billgatliff.com bgat at billgatliff.com
Quoted 8 lines · Armando VISCONTI
Quoted 7 lines
What I think you really want is for your board-specific code (or some helper code elsewhere in your mach-* directory) to do the pin assignments, and the drivers just assume that the pins are all right. That's the approach used in OMAP2 and AT91, among others, and it seems to work out just fine.
Quoted 6 lines
Bill,
What you and Russell are saying is a little bit different from what I got since
now, with people suggesting to implement a single linux image which is then configured at runtime thru (for example) bootargs.
No, we're suggesting the same thing.
Quoted 1 line
Now you both are saying that compile time options are better, correct?
No. We're suggesting that you put platform specific details in their own .c file like everything else does on ARM and use the mechanisms already provided for supporting multi-platform kernels.
It's actually extremely difficult to avoid the multi-platform support.
Eg, see arch/arm/mach-pxa/palm*.c - PXA kernels can support all those Palm platforms from one kernel image.
The compile time options concern whether to include support for a particular board. However, the ultimate decision about how to configure the PXA chip is made at run time.
Quoted 23 lines
-----Original Message-----
From: linux-arm-kernel-bounces at lists.infradead.org [mailto:linux-arm-kernel- bounces at lists.infradead.org] On Behalf Of Viresh KUMAR
Sent: Monday, March 15, 2010 10:02 AM
To: linux-arm-kernel at lists.infradead.org
Cc: Armando VISCONTI; 'Shiraz HASHIM'
Subject: QUERY: How to handle SOC Configuration (Peripheral Multiplexing) in linuxHello everybody,
In our SOC's (SPEArxxx), we have many peripheral sharing
PL_GPIOpins and so only few peripherals can be selected in a configuration. This is configurable using a set of registers. Now the problem is to make following work:1. How to do this selection in kernel in a simple way?
2. Based on this selection hardware registers needs to be configured.I propose following solution to solve this issue, but i am not sure if it is acceptable by community.
Please see if it is fine. Or if there is any other way people may already be following for similar issues.
Quoted 7 lines
I have provided this selection from "make menuconfig", based on selection I configure hardware at initialization time. Basically these selections will decide which device is present in the system when it boots.
There are modes in which SOC can be configured and in these modes peripherals can be selected.
Since the data is board dependent, why don't you make this information as platform data for devices and pass that information from board files depending on board type.
This gives you flexibility as well and you don't need unnecessary cluttering of Kconfig entries.
- Santosh
Hello Santosh,
Quoted 27 lines · Santosh
Quoted 27 lines
-----Original Message-----
From: linux-arm-kernel-bounces at lists.infradead.org [mailto:linux-arm-kernel- bounces at lists.infradead.org] On Behalf Of Viresh KUMAR
Sent: Monday, March 15, 2010 10:02 AM
To: linux-arm-kernel at lists.infradead.org
Cc: Armando VISCONTI; 'Shiraz HASHIM'
Subject: QUERY: How to handle SOC Configuration (Peripheral Multiplexing) in linuxHello everybody,
In our SOC's (SPEArxxx), we have many peripheral sharing
PL_GPIOpins and so only few peripherals can be selected in a configuration. This is configurable using a set of registers. Now the problem is to make following work:1. How to do this selection in kernel in a simple way?
2. Based on this selection hardware registers needs to be configured.I propose following solution to solve this issue, but i am not sure if it is acceptable by community.
Please see if it is fine. Or if there is any other way people may already be following for similar issues.
I have provided this selection from "make menuconfig", based on selection I configure hardware at initialization time. Basically these selections will decide which device is present in the system when it boots.
Quoted 8 lines
Quoted 3 lines
There are modes in which SOC can be configured and in these modes peripherals can be selected.
Since the data is board dependent, why don't you make this information as platform data for devices and pass that information from board files depending on board type.
This gives you flexibility as well and you don't need unnecessary cluttering of
Kconfigentries.
But the standard drivers which are already in mainline may not support these platform data.
regards
Shiraz
Quoted 40 lines
-----Original Message-----
From: Shiraz HASHIM [mailto:shiraz.hashim at st.com]
Sent: Monday, March 15, 2010 10:46 AM
To: Shilimkar, Santosh
Cc: Viresh KUMAR; linux-arm-kernel at lists.infradead.org; Armando VISCONTI
Subject: Re: QUERY: How to handle SOC Configuration (Peripheral Multiplexing) in linuxHello Santosh,
Quoted 30 lines · Santosh
Quoted 30 lines
-----Original Message-----
From: linux-arm-kernel-bounces at lists.infradead.org [mailto:linux-arm-kernel- bounces at lists.infradead.org] On Behalf Of Viresh KUMAR
Sent: Monday, March 15, 2010 10:02 AM
To: linux-arm-kernel at lists.infradead.org
Cc: Armando VISCONTI; 'Shiraz HASHIM'
Subject: QUERY: How to handle SOC Configuration (Peripheral Multiplexing) in linuxHello everybody,
In our SOC's (SPEArxxx), we have many peripheral sharing
PL_GPIOpins and so only few peripherals can be selected in a configuration. This is configurable using a set of registers. Now the problem is to make following work:1. How to do this selection in kernel in a simple way?
2. Based on this selection hardware registers needs to be configured.I propose following solution to solve this issue, but i am not sure if it is acceptable by community.
Please see if it is fine. Or if there is any other way people may already be following for similar issues.
I have provided this selection from "make menuconfig", based on selection I configure hardware at initialization time. Basically these selections will decide which device is present in the system when it boots.
There are modes in which SOC can be configured and in these modes peripherals can be selected.
Quoted 9 lines
Quoted 5 lines
Since the data is board dependent, why don't you make this information as platform data for devices and pass that information from board files depending on board type.
This gives you flexibility as well and you don't need unnecessary cluttering of
Kconfigentries.But the standard drivers which are already in mainline may not support these platform data.
Driver won't change major way. I was saying passing additional information via platform data to drivers. Even with Kconfig stuff, you need to touch drivers to take care of your exceptions.
Am I missing something?
- Santosh
Quoted 8 lines · Santosh
Quoted 3 lines
Quoted 3 lines
But the standard drivers which are already in mainline may not support these platform data.
Driver won't change major way. I was saying passing additional information via platform data to drivers. Even with
Kconfigstuff, you need to touch drivers to take care of your exceptions.Am I missing something?
We need only a platform specific function (spear300_configure), that will take care of this. We don't need to change anything in driver for this. I feel Driver is not supposed to know what platform specific configuration is required to enable the device.
Quoted 12 lines · Viresh KUMAR
Hello everybody,
In our SOC's (SPEArxxx), we have many peripheral sharing
PL_GPIOpins and so only few peripherals can be selected in a configuration. This is configurable using a set of registers. Now the problem is to make following work:1. How to do this selection in kernel in a simple way?
2. Based on this selection hardware registers needs to be configured.I propose following solution to solve this issue, but i am not sure if it is acceptable by community.
Quoted 6 lines
Please see if it is fine. Or if there is any other way people may already be following for similar issues.
I have provided this selection from "make menuconfig", based on selection I configure hardware at initialization time. Basically these selections will decide which device is present in the system when it boots.
This is really bad idea, what happens if you have a selection of boards with mutually-exclusive peripheral sets? Making these sorts of decisions at compile time is always a bad idea, it leaves people making distributitions a lot of extra work.
My first idea would be to add a function which is given a bitmap or list of devices to register, and this function sorts out what hardware bits to set as needed and then register if the selection is possible.
Quoted 412 lines
There are modes in which SOC can be configured and in these modes peripherals can be selected.
file:
arch/arm/mach-spear3xx/Kconfig300#
# SPEAr300 machine configuration file
#
ifMACH_SPEAR300choice
prompt "SPEAr300 Boards"
defaultBOARD_SPEAR300_EVBconfig
BOARD_SPEAR300_EVB
bool "SPEAr300 Evaluation Board"
help
Supports ST SPEAr300 Evaluation Boardendchoice
# SOC configuration for SPEAr 300 machine
menu "SPEAr300 SOC Configuration"# Operation modes
choice
prompt "Select Operation Mode"
defaultPHOTO_FRAME_MODEconfig
NAND_MODE
bool "NAND Mode"
help
This mode will enable NAND Mode of SPEAr300 SOC.config
NOR_MODE
bool "NOR Mode"
help
This mode will enable NOR Mode of SPEAr300 SOC.config
PHOTO_FRAME_MODE
bool "PHOTO FRAME Mode"
help
This mode will enable PHOTO FRAME Mode of SPEAr300 SOC.config
LEND_IP_PHONE_MODE
bool "LEND IP PHONE (LOW END IP PHONE mode)" help
This mode will enable LEND IP PHONE Mode of SPEAr300 SOC.config
HEND_IP_PHONE_MODE
bool "HEND IP PHONE (HIGH END IP PHONE mode)" help
This mode will enable HEND IP PHONE Mode of SPEAr300 SOC.config
LEND_WIFI_PHONE_MODE
bool "LEND WIFI PHONE (LOW END WI-FI PHONE mode)" help
This mode will enable LEND WIFI PHONE Mode of SPEAr300 SOC.config
HEND_WIFI_PHONE_MODE
bool "HEND WIFI PHONE (HIGH END WI-FI PHONE mode)" help
This mode will enable HEND WIFI PHONE Mode of SPEAr300 SOC.config
ATA_PABX_wI2S_MODE
bool "ATA PABX wI2S (ATA PABX without I2S) mode" help
This mode will enable ATA PABX wI2S Mode of SPEAr300 SOC.config
ATA_PABX_I2S_MODE
bool "ATA PABX I2S (ATA PABX with I2S) Mode" help
This mode will enable ATA PABX I2S Mode of SPEAr300 SOC.config
CAMl_LCDw_MODE
bool "CAMl LCDw (8 bit CAMERA without LCD) Mode" help
This mode will enable CAMl LCDw Mode of SPEAr300 SOC.config
CAMu_LCD_MODE
bool "CAMu LCD (14 bit CAMERA with LCD) Mode" help
This mode will enable CAMu LCD Mode of SPEAr300 SOC.config
CAMu_wLCD_MODE
bool "CAMu wLCD (14 bit CAMERA without LCD) Mode" help
This mode will enable CAMu wLCD Mode of SPEAr300 SOC.config
CAMl_LCD_MODE
bool "CAMl LCD (8 bit CAMERA with LCD) Mode" help
This mode will enable CAMl LCD Mode of SPEAr300 SOC.endchoice #Select Operation Mode
#mode specific peripherals
#FSMC
configFSMC_2_CHIPSbool "FSMC 2 CHIPS - Disables FIRDA" depends on NAND_MODE || NOR_MODE || PHOTO_FRAME_MODE || \ ATA_PABX_wI2S_MODE || ATA_PABX_I2S_MODE depends on !FSMC_4_CHIPS default nconfig
FSMC_4_CHIPSbool "FSMC 4 CHIPS - Disables UART and FIRDA" depends on NAND_MODE || NOR_MODE || PHOTO_FRAME_MODE || \ ATA_PABX_wI2S_MODE || ATA_PABX_I2S_MODE default n#Keyboard
config KEYBOARDbool "Keyboard" depends on LEND_IP_PHONE_MODE || HEND_IP_PHONE_MODE || \ LEND_WIFI_PHONE_MODE || HEND_WIFI_PHONE_MODE || CAMl_LCDw_MODE || \ CAMu_LCD_MODE || CAMu_wLCD_MODE || CAMl_LCD_MODE default y#CLCD
configCLCD_1
bool "CLCD - Disables TIMER 1-2 and TIMER 3-4" depends onPHOTO_FRAME_MODE
default nconfig
CLCD_2bool "CLCD - Disables TIMER 3-4" depends on HEND_IP_PHONE_MODE || HEND_WIFI_PHONE_MODE || \ CAMu_LCD_MODE || CAMl_LCD_MODE default n#Telecom_GPIO Combinations
configTL_GPIO_1bool "Telecom GPIO - Disables GMAC" depends on PHOTO_FRAME_MODE || CAMu_LCD_MODE || CAMl_LCD_MODE default nconfig
TL_GPIO_2bool "Telecom GPIO - Disables TIMER 1-2, Timer 3-4 and GMAC" depends on LEND_IP_PHONE_MODE || LEND_WIFI_PHONE_MODE default nconfig
TL_GPIO_3bool "Telecom GPIO - Disables TIMER 3-4 and GMAC" depends on ATA_PABX_I2S_MODE || CAMl_LCDw_MODE || CAMu_wLCD_MODE default nconfig
TL_GPIO_4bool "Telecom GPIO - Disables TIMER 1-2 and GMAC" depends on HEND_IP_PHONE_MODE || HEND_WIFI_PHONE_MODE default nconfig
TL_GPIO_5
bool "Telecom GPIO - Disables TIMER 1-2-3-4, UART MODEM and GMAC" depends onATA_PABX_wI2S_MODE
default n#TL_TDM Combinations
configTL_TDMbool "Telecom TDM - Disables UART MODEM and SSP CHIP SELECTS" depends on PHOTO_FRAME_MODE || LEND_IP_PHONE_MODE || \ HEND_IP_PHONE_MODE || LEND_WIFI_PHONE_MODE || HEND_WIFI_PHONE_MODE || \ ATA_PABX_wI2S_MODE || ATA_PABX_I2S_MODE || CAMl_LCDw_MODE || \ CAMu_LCD_MODE || CAMu_wLCD_MODE || CAMl_LCD_MODE default n#TL_SPI_I2C Combinations
configTL_SPI_I2Cbool "Telecom SPI-CS I2C-CLK - Disables TIMER 1-2 and TIMER 3-4" depends on LEND_IP_PHONE_MODE || HEND_IP_PHONE_MODE || \ LEND_WIFI_PHONE_MODE || HEND_WIFI_PHONE_MODE || ATA_PABX_wI2S_MODE || \ ATA_PABX_I2S_MODE || CAMl_LCDw_MODE || CAMl_LCD_MODE default n#TL_CAMERA Combinations
configTL_CAMERA_1bool "Telecom CAMERA - Disables GMAC" depends on CAMl_LCDw_MODE || CAMl_LCD_MODE default nconfig
TL_CAMERA_2bool "Telecom CAMERA - Disables TIMER 1-2, TIMER 3-4 and GMAC" depends on CAMu_LCD_MODE || CAMu_wLCD_MODE default n#TL_DAC Combinations
configTL_DACbool "Telecom DAC - Disables Timer A" depends on ATA_PABX_I2S_MODE || CAMl_LCDw_MODE || \ CAMu_LCD_MODE || CAMu_wLCD_MODE || CAMl_LCD_MODE default n#TL_I2S Combinations
configTL_I2Sbool "Telecom I2S - Disables UART MODEM and SDIO" depends on LEND_IP_PHONE_MODE || HEND_IP_PHONE_MODE || \ LEND_WIFI_PHONE_MODE || HEND_WIFI_PHONE_MODE || \ ATA_PABX_I2S_MODE || CAMl_LCDw_MODE || CAMu_LCD_MODE || \ CAMu_wLCD_MODE || CAMl_LCD_MODE depends on !SDIO_1_4 && !SDIO_8 default n#Boot Pins Combinations
configBOOT_PINSbool "BOOT PINS - Disables UART MODEM, TIMER 1-2 and TIMER 3-4" depends on NAND_MODE || NOR_MODE default n#SDIO Combinations
configSDIO_1_4bool "SDIO 1-4 Bit - Enable GPIO1 and Disables GPIO0 Pin 0 TO 5 and I2S" depends on PHOTO_FRAME_MODE || LEND_IP_PHONE_MODE || \ HEND_IP_PHONE_MODE || LEND_WIFI_PHONE_MODE || \ HEND_WIFI_PHONE_MODE || CAMl_LCDw_MODE || \ CAMu_LCD_MODE || CAMu_wLCD_MODE || CAMl_LCD_MODE || \ ATA_PABX_wI2S_MODE || ATA_PABX_I2S_MODE depends on !SDIO_8 select GPIO1 default nconfig
SDIO_8bool "SDIO 8 bit - Enable GPIO1 and Disables GPIO0 Pin 0 TO 5, GMAC and I2S" depends on PHOTO_FRAME_MODE || LEND_IP_PHONE_MODE || \ HEND_IP_PHONE_MODE || LEND_WIFI_PHONE_MODE || \ HEND_WIFI_PHONE_MODE || CAMl_LCDw_MODE || \ CAMu_LCD_MODE || CAMu_wLCD_MODE || CAMl_LCD_MODE select GPIO1 default n#GPIO Combinations
config GPIO1
bool "GPIO1 - Disables UART MODEM, TIMER 1-2 and TIMER 3-4" depends onPHOTO_FRAME_MODE
default n#peripherals available in all modes
config FIRDAbool "FIRDA" depends on !FSMC_4_CHIPS && !FSMC_2_CHIPS default yconfig I2C
bool "I2C" default yconfig SSP
bool "SSP"
default yconfig
SSP_CHIP_SELECTS
bool "SSP CHIP SELECTS"
depends on !TL_TDM
default yconfig GMAC
bool "GMAC" depends on !TL_GPIO_1 && !TL_GPIO_2 && !TL_GPIO_3 && !TL_GPIO_4 && \ !TL_GPIO_5 && !TL_CAMERA_1 && !TL_CAMERA_2 && !SDIO_8 default yconfig
GPIO0_PIN_0_TO_5bool "GPIO0 Pin 0 TO 5" depends on !SDIO_1_4 && !SDIO_8 default yconfig UART
bool "UART"
depends on !FSMC_4_CHIPS
default yconfig
UART_MODEMbool "UART MODEM" depends on !TL_GPIO_5 && !TL_TDM && !TL_I2S && !BOOT_PINS && !GPIO1 default yconfig
TIMER_1_2bool "TIMER 1-2" depends on !CLCD_1 && !TL_GPIO_2 && !TL_GPIO_4 && !TL_GPIO_5 && \ !TL_SPI_I2C && !TL_CAMERA_2 && !TL_DAC && !BOOT_PINS && !GPIO1 default yconfig
TIMER_3_4bool "TIMER 3-4" depends on !CLCD_1 && !CLCD_2 && !TL_GPIO_2 && !TL_GPIO_3 && \ !TL_GPIO_5 && !TL_SPI_I2C && !BOOT_PINS && !GPIO1 && !TL_CAMERA_2 default yendmenu #SOC Configuration
endif #MACH_SPEAR300
file:
arch/arm/mach-spear3xx/spear300.c/* macros with configuration values for modes */
#defineS300_NAND_MODE1
#defineS300_NOR_MODE2
#defineS300_PHOTO_FRAME_MODE3
#defineS300_LEND_IP_PHONE_MODE4
#defineS300_HEND_IP_PHONE_MODE5
#defineS300_LEND_WIFI_PHONE_MODE6
#defineS300_HEND_WIFI_PHONE_MODE7
#defineS300_ATA_PABX_wI2S_MODE8
#defineS300_ATA_PABX_I2S_MODE9
#defineS300_CAMl_LCDw_MODE10
#defineS300_CAMu_LCD_MODE11
#defineS300_CAMu_LCDw_MODE12
#defineS300_CAMl_LCD_MOD13/* macros with configuration values for peripherals */
#defineS300_FIRDA~0x00004000
#defineS300_I2C~0x00002000
#defineS300_SSP_ENHANCED~0x00001000
#defineS300_SSP_BASIC~0x00000800
#defineS300_MII~0x00000400
#defineS300_LEG_GPIO~0x000003f0
#defineS300_UART_ENHANCED~0x00000008
#defineS300_UART_BASIC~0x00000004
#defineS300_TIMER_B~0x00000002
#defineS300_TIMER_A~0x00000000void
spear300_configure(void){ /* two variables to temporarily store values of two registers */ volatile unsigned int *config_reg1; volatile unsigned int *config_reg2;#ifndef CONFIG_FIRDA *config_reg1 &= FIRDA; #endif #ifndef CONFIG_I2C *config_reg1 &= I2C; #endif #ifndef CONFIG_SSP_CHIP_SELECTS *config_reg1 &= SSP_CHIP_SELECTS; #endif #ifndef CONFIG_SSP *config_reg1 &= SSP; #endif #ifndef CONFIG_GMAC *config_reg1 &= GMAC; #endif #ifndef CONFIG_GPIO0_PIN_0_TO_5 *config_reg1 &= GPIO0_PIN_0_TO_5; #endif #ifndef CONFIG_UART_MODEM *config_reg1 &= UART_MODEM; #endif #ifndef CONFIG_UART *config_reg1 &= UART; #endif #ifndef CONFIG_TIMER_3_4 *config_reg1 &= TIMER_3_4; #endif #ifndef CONFIG_TIMER_1_2 *config_reg1 &= TIMER_1_2;#endif
#ifdef CONFIG_NAND_MODE *config_reg2 = NAND_MODE; #endif #ifdef CONFIG_NOR_MODE *config_reg2 = NOR_MODE; #endif #ifdef CONFIG_PHOTO_FRAME_MODE *config_reg2 = PHOTO_FRAME_MODE; #endif #ifdef CONFIG_LEND_IP_PHONE_MODE *config_reg2 = LEND_IP_PHONE_MODE; #endif #ifdef CONFIG_HEND_IP_PHONE_MODE *config_reg2 = HEND_IP_PHONE_MODE; #endif #ifdef CONFIG_LEND_WIFI_PHONE_MODE *config_reg2 = LEND_WIFI_PHONE_MODE; #endif #ifdef CONFIG_HEND_WIFI_PHONE_MODE *config_reg2 = HEND_WIFI_PHONE_MODE; #endif #ifdef CONFIG_ATA_PABX_wI2S_MODE *config_reg2 = ATA_PABX_wI2S_MODE; #endif #ifdef CONFIG_ATA_PABX_I2S_MODE *config_reg2 = ATA_PABX_I2S_MODE; #endif #ifdef CONFIG_CAMl_LCDw_MODE *config_reg2 = CAMl_LCDw_MODE; #endif #ifdef CONFIG_CAMu_LCD_MODE *config_reg2 = CAMu_LCD_MODE; #endif #ifdef CONFIG_CAMu_wLCD_MODE *config_reg2 = CAMu_LCDw_MODE; #endif #ifdef CONFIG_CAMl_LCD_MODE *config_reg2 = CAMl_LCD_MODE;#endif
/* At the end we can write these values to actual registers */ }regards,
viresh kumar._______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Signature · 5 lines
-- Ben Q: What's a light-year? A: One-third less calories than a regular year.
Ben,
Quoted 12 lines · Ben Dooks
Quoted 3 lines
Quoted 3 lines
I have provided this selection from "make menuconfig", based on selection I configure hardware at initialization time. Basically these selections will decide which device is present in the system when it boots.
This is really bad idea, what happens if you have a selection of boards with mutually-exclusive peripheral sets? Making these sorts of decisions at compile time is always a bad idea, it leaves people making distributitions a lot of extra work.
My first idea would be to add a function which is given a bitmap or list of devices to register, and this function sorts out what hardware bits to set as needed and then register if the selection is possible.
I agree with your idea to pass a bitmap to kernel at some time (probably at boot time), so that it can configure all required peripherals.
Now, For this we need some interface or channel through which we provide this information to kernel. This is what precisely i have done. The channel i provided is through Kconfig and the function "s300_configure", accepts this bitmap and configures hardware.
Isn't it correct?
regards,
viresh kumar.
Viresh,
Quoted 5 lines
Now, For this we need some interface or channel through which we provide this information to kernel. This is what precisely i have done. The channel i provided is through
Kconfigand the function "s300_configure", accepts this bitmap and configures hardware.
I'm not getting this point.
If you do it thru Kconfig still it would be fixed a compilation time. Do you agree or am I missing something?
So, probably the correct way is passing peripheral selection information thru
bootargs.
What do you think?
Armando
Armando,
Quoted 7 lines · Armando VISCONTI
Quoted 6 lines
Now, For this we need some interface or channel through which we provide this information to kernel. This is what precisely i have done. The channel i
provided is throughKconfigand the function "s300_configure", accepts this bitmap and configures hardware.I'm not getting this point.
yes, Actually this is what we are saying. Seemingly the best option is to do it during compilation time, except if we have some standard way at booting.
Quoted 2 lines
If you do it thru
Kconfigstill it would be fixed a compilation time. Do you agree or am I missing something?
yes, and if you see, should any one require it dynamically? Each user would have his own board with static devices. This configuration (of selecting multiplexed devices) depends on his board configuration, which is the responsibility of the board configuration file.
Quoted 4 lines
So, probably the correct way is passing peripheral selection information thru
bootargs.
What do you think?
This is very specific to how an SoC provides multiplexing options and will vary greatly. Which option of bootargs are you talking about?
regards
Shiraz
Quoted 4 lines · Shiraz HASHIM
yes, and if you see, should any one require it dynamically? Each user would have his own board with static devices. This configuration (of selecting multiplexed devices) depends on his board configuration, which is the responsibility of the board configuration file.
sorry for barging in but ...
usually device makers(that release product versions with same SoC but different devices)
want a single kernel image that detects the machine type and accordingly populate the
device support. Managing separate images for similar devices is considered inefficient.
Jassi,
Quoted 6 lines · jassi brar
Quoted 4 lines · Shiraz HASHIM
Quoted 4 lines
yes, and if you see, should any one require it dynamically? Each user would have his own board with static devices. This configuration (of selecting multiplexed devices) depends on his board configuration, which is the responsibility of the board configuration file.
sorry for barging in but ...
your comments are most welcome.
Quoted 6 lines
usually device makers(that release product versions with same SoC but different devices)
want a single kernel image that detects the machine type and accordingly populate the
device support. Managing separate images for similar devices is considered inefficient.
Actually you have pointed to right thing and this is really important. Some architectures (I think ppc) have device tree option to pass the hardware configuration to the kernel from bootloader.
I dont know such option exists for arm. Lets hear others' opinions.
Following link exactly targets this
http://ols.fedoraproject.org/OLS/Reprints-2008/likely2-reprint.pdf
regards
Shiraz
Quoted 11 lines · Shiraz HASHIM
Quoted 6 lines
usually device makers(that release product versions with same SoC but different devices)
want a single kernel image that detects the machine type and accordingly populate the
device support. Managing separate images for similar devices is considered inefficient.Actually you have pointed to right thing and this is really important. Some architectures (I think ppc) have device tree option to pass the hardware configuration to the kernel from bootloader.
I dont know such option exists for arm. Lets hear others' opinions.
I don't think you can't do without device-trees.
Quoted 8 lines · jassi brar
Quoted 7 lines · Shiraz HASHIM
Quoted 6 lines
usually device makers(that release product versions with same SoC but different devices)
want a single kernel image that detects the machine type and accordingly populate the
device support. Managing separate images for similar devices is considered inefficient.
Quoted 5 lines
Quoted 4 lines
Actually you have pointed to right thing and this is really important. Some architectures (I think ppc) have device tree option to pass the hardware configuration to the kernel from bootloader.
I dont know such option exists for arm. Lets hear others' opinions.I don't think you can't do without device-trees.
When there are problems in boot loaders, people _always_ want to work around them in the kernel, because they do not want to fix the boot loader and risk bricking their board.
We've seen this with the passing of machine IDs, we've seen it with passing ATAG lists to the kernel - where boot loaders can't even get the termination of the ATAG list (zero size tag with a NULL id) right.
Since boot loaders can't get this kind of simple stuff right, I'm absolutely horrified by the idea of passing a much larger structure from the boot loader to the kernel - the chances of that being correct are infinitessimally small.
However, there is some work in progress for ARM device tree support, but it's very slow going and doesn't seem to attract very much support from within the ARM community.
What we have instead is a system of machine types, which allows the kernel to select the correct board support file. The board support file declares platform devices and other data relevant to the board, and is responsible for various initialization tasks. Have a look at PXA to see how this is done.
For the most part, it works very well, and cuts down on the boot loader dependencies to _just_ ensuring that it passes a correct machine ID number, an ATAG list describing the memory layout and kernel command line.
Until ARM DT support has matured, I suggest following this long established and well proven approach.
Quoted 4 lines · Shiraz HASHIM
Actually you have pointed to right thing and this is really important. Some architectures (I think ppc) have device tree option to pass the hardware configuration to the kernel from bootloader.
I dont know such option exists for arm. Lets hear others' opinions.
We don't have support for DT yet.
Currently, we handle most of the platform dependencies via machine types and having individual board support C files provide the necessary device structures and pin muxing information to core support.
Shiraz,
Quoted 9 lines
Quoted 3 lines
If you do it thru
Kconfigstill it would be fixed a compilation time. Do you agree or am I missing something?yes, and if you see, should any one require it dynamically? Each user would have his own board with static devices. This configuration (of selecting multiplexed devices) depends on his board configuration, which is the responsibility of the board configuration file.
This was also my understanding at the beginning.
But looking at the response from the community it looks that it is better to have a single image for all boards which is capable at runtime to be configured in the proper way.
Quoted 9 lines
Quoted 5 lines
So, probably the correct way is passing peripheral selection information thru
bootargs.
What do you think?This is very specific to how an SoC provides multiplexing options and will vary greatly. Which option of bootargs are you talking about?
Of course not a standard bootargs option.
I was more talking about a new specific option that is passed thru bootargs and directed to a specific SPEAr function that can apply the proper cfg and register setting, like someone (Ben?) was suggesting.
In this option you should pass a bitmap or something like that.
Let me know your opinion on it.
Armando
Quoted 41 lines · Shiraz HASHIM
Armando,
Quoted 9 lines · Armando VISCONTI
Quoted 7 lines
Now, For this we need some interface or channel through which we provide this information to kernel. This is what precisely i have done. The channel i
provided is throughKconfigand the function "s300_configure", accepts this bitmap and configures hardware.I'm not getting this point.
yes, Actually this is what we are saying. Seemingly the best option is to do it during compilation time, except if we have some standard way at booting.
Quoted 3 lines
If you do it thru
Kconfigstill it would be fixed a compilation time. Do you agree or am I missing something?yes, and if you see, should any one require it dynamically? Each user would have his own board with static devices. This configuration (of selecting multiplexed devices) depends on his board configuration, which is the responsibility of the board configuration file.
Quoted 5 lines
So, probably the correct way is passing peripheral selection information thru
bootargs.
What do you think?This is very specific to how an SoC provides multiplexing options and will vary greatly. Which option of bootargs are you talking about?
regards
Shiraz
Signature · 8 lines
-- "Every step appears to be the unavoidable consequence of the -- preceding one." (A. Einstein) -- Armando Visconti Mobile: (+39) 346 8879146 Senior SW Engineer Fax: (+39) 02 93519290 CPG Work: (+39) 02 93519683 Computer System Division e-mail: armando.visconti at st.com ST Microelectronics TINA: 051 4683
Armando,
Quoted 16 lines · Armando VISCONTI
Quoted 10 lines
Quoted 5 lines
So, probably the correct way is passing peripheral selection information thru
bootargs.
What do you think?This is very specific to how an SoC provides multiplexing options and will
vary greatly. Which option of bootargs are you talking about?Of course not a standard bootargs option.
I was more talking about a new specific option that is passed thru bootargs and directed to a specific SPEAr function that can apply the proper cfg and register setting, like someone (Ben?) was suggesting.
Quoted 3 lines
In this option you should pass a bitmap or something like that.
Let me know your opinion on it.
You may be right.
Please see my other reply on device tree option.
regards
Shiraz
Ben,
Quoted 5 lines · Ben Dooks
Quoted 3 lines
Quoted 3 lines
I have provided this selection from "make menuconfig", based on selection I configure hardware at initialization time. Basically these selections will decide which device is present in the system when it boots.
This is really bad idea, what happens if you have a selection of boards with mutually-exclusive peripheral sets?
In this case, we can have different defconfig files for different boards.
Quoted 4 lines
Making these sorts of
decisions at compile time is always a bad idea, it leaves people making distributitions a lot of extra work.
I agree with this point but what is the other way for this.
Doing this at runtime will have following issue:
User have inserted a module and by mistake or lack of knowledge,
he disabled already working IP(due to multiplexing). Now with Kconfig concept this is taken care of at the beginning only. User can't select peripherals which can't be enabled simultaneously.
regards,
viresh kumar.
Quoted 10 lines · Viresh KUMAR
Ben,
Quoted 5 lines · Ben Dooks
Quoted 3 lines
Quoted 3 lines
I have provided this selection from "make menuconfig", based on selection I configure hardware at initialization time. Basically these selections will decide which device is present in the system when it boots.
This is really bad idea, what happens if you have a selection of boards with mutually-exclusive peripheral sets?
In this case, we can have different defconfig files for different boards.
That is not acceptable, it makes life difficult for things like the autobuilder (more configurations to process), for people trying to package software distributions (each kernel requires a package, a set of modules, requiring time to build and space to store).
The configuration is known to the board initialisation code in the kernel, and thus it should be requesting a set of features from the core SoC implementation saying what it wants. This can then ensure that the configuration is mutually exclusive, ensure any resources such as GPIO are correctly configured, etc.
Note, currently the s3c2410_defconfig builds 123Mbyte of modules. Think about having m-machines' worth of those littering your development system.
Quoted 5 lines
Quoted 4 lines
Making these sorts of
decisions at compile time is always a bad idea, it leaves people making distributitions a lot of extra work.
Quoted 8 lines
I agree with this point but what is the other way for this.
Doing this at runtime will have following issue:
User have inserted a module and by mistake or lack of knowledge,
he disabled already working IP(due to multiplexing). Now withKconfigconcept this is taken care of at the beginning only. User can't select peripherals which can't be enabled simultaneously.
Generally, all devices are registered at initialisation time. If there is the chance of dynamically loading drivers afterwards, either you'll have to do one of the following:
1) Change the driver to call the SoC code in the probe() code to ensure that it can get the required SoC resources
2) Ensure the board has reseved the SoC resources for the device at start time
Note, also unless you have very specific modules, your Kconfig approach will break down if you forget to update the root-fs when changing the kernel, otherwise modules you can't load will be left around.
Generally, runtime controls are much better than build time.
Signature · 4 lines
Ben Q: What's a light-year? A: One-third less calories than a regular year.
Quoted 48 lines · Ben Dooks
Quoted 10 lines · Viresh KUMAR
Ben,
Quoted 5 lines · Ben Dooks
Quoted 3 lines
Quoted 3 lines
I have provided this selection from "make menuconfig", based on selection I configure hardware at initialization time. Basically these selections will decide which device is present in the system when it boots.
This is really bad idea, what happens if you have a selection of boards with mutually-exclusive peripheral sets?
In this case, we can have different defconfig files for different boards.
That is not acceptable, it makes life difficult for things like the autobuilder (more configurations to process), for people trying to package software distributions (each kernel requires a package, a set of modules, requiring time to build and space to store).
The configuration is known to the board initialisation code in the kernel, and thus it should be requesting a set of features from the core SoC implementation saying what it wants. This can then ensure that the configuration is mutually exclusive, ensure any resources such as GPIO are correctly configured, etc.
Note, currently the
s3c2410_defconfigbuilds 123Mbyte of modules. Think about having m-machines' worth of those littering your development system.Quoted 5 lines
Quoted 4 lines
Making these sorts of
decisions at compile time is always a bad idea, it leaves people making distributitions a lot of extra work.Quoted 8 lines
I agree with this point but what is the other way for this.
Doing this at runtime will have following issue:
User have inserted a module and by mistake or lack of knowledge,
he disabled already working IP(due to multiplexing). Now withKconfigconcept this is taken care of at the beginning only. User can't select peripherals which can't be enabled simultaneously.Generally, all devices are registered at initialisation time. If there is the chance of dynamically loading drivers afterwards, either you'll have to do one of the following:
1) Change the driver to call the SoC code in the
probe()code to ensure that it can get the required SoC resources
Quoted 9 lines
2) Ensure the board has reseved the SoC resources for the device at start time
Note, also unless you have very specific modules, your
Kconfigapproach will break down if you forget to update the root-fs when changing the kernel, otherwise modules you can't load will be left around.Generally, runtime controls are much better than build time.
Thanks guys.
All of you gave great inputs, this discussion helped me a lot.
This is what I understood,
1. Mux config decision must be done at run time.
2. Mux config will be board dependent.
3. Mux config should be one time and should be discouraged to be done again as this can cause board failures or more power consumption.
thanks,
viresh kumar.
2010/3/15 Viresh KUMAR <[email protected]>:
Quoted 6 lines
In our SOC's (SPEArxxx), we have many peripheral sharing
PL_GPIOpins and so only few peripherals can be selected in a configuration. This is configurable using a set of registers. Now the problem is to make following work:1. How to do this selection in kernel in a simple way?
2. Based on this selection hardware registers needs to be configured.
Please contemplate arch/arm/mach-u300/padmux.[c|h] if you have time. We have there a runtime padmuxing API similar to what is used for regulators and clocks. E.g in arch/arm/mach-u300/mmc.c:
/*
* Setup padmuxing for MMC. Since this must always be
* compiled into the kernel, pmx is never released. */
pmx = pmx_get(mmcsd_device, U300_APP_PMX_MMC_SETTING);
if (IS_ERR(pmx))
pr_warning("Could not get padmux handle\n");
else {
ret = pmx_activate(mmcsd_device, pmx);
if (IS_ERR_VALUE(ret))
pr_warning("Could not activate padmuxing\n");
}This API can be used to switch in/out padmux settings in runtime. I think these things will always be platform-specific because people will always have their favourite way of configuring GPIO pins etc. (Note: we're not *just* muxing GPIO with this framework, far from, as you see above also the entire MMC/SD block connections can be muxed in/out.)
We've actually seen usecases where you need to dynamically remux while drivers are running but these have been rare and on older chips I think.
Yours,
Linus Walleij
Hello Linus,
Quoted 18 lines · Linus Walleij
Please contemplate arch/arm/mach-u300/padmux.[c|h] if you have time. We have there a runtime padmuxing API similar to what is used for regulators and clocks. E.g in
arch/arm/mach-u300/mmc.c:/*
* Setup padmuxing for MMC. Since this must always be
* compiled into the kernel, pmx is never released. */
pmx =pmx_get(mmcsd_device, U300_APP_PMX_MMC_SETTING);if (
IS_ERR(pmx))pr_warning("Could not get padmux handle\n"); else { ret = pmx_activate(mmcsd_device, pmx); if (IS_ERR_VALUE(ret)) pr_warning("Could not activate padmuxing\n"); }
Quoted 5 lines
This API can be used to switch in/out padmux settings in runtime. I think these things will always be platform-specific because people will always have their favourite way of configuring GPIO pins etc. (Note: we're not *just* muxing GPIO with this framework, far from, as you see above also the entire MMC/SD block connections can be muxed in/out.)
I was trying to go through u300 code and it looks clean enough. I need your help in understanding it better. In your case you try to configure the pin mux and then, even if it fails the device (through amba_device_register) is registered. Now if the driver is enabled in the kernel (or it is insmod) then the driver in its "probe" would stuck somewhere.
Do we need to handle such scenarios. Am I missing something?
Further, if you can describe what is onmask field (of pmx) and what devices/options are multiplexed with (say) spi, it would help me better understand the code.
Quoted 2 lines
We've actually seen usecases where you need to dynamically remux while drivers are running but these have been rare and on older chips I think.
You mean to say dynamically remapping pins to achieve some function with the same driver? or taking out one driver and inserting another after changing mux config.
In any case one of the objective is to keep same linux image for different configurations/boards. Isn't it ?
thanks a lot.
regards
Shiraz
(CC to Martin who wrote the nice padmux code in case he wants to add something.)
2010/3/16 Shiraz HASHIM <[email protected]>:
Quoted 5 lines
I was trying to go through u300 code and it looks clean enough. I need your help in understanding it better. In your case you try to configure the pin mux and then, even if it fails the device (through
amba_device_register) is registered. Now if the driver is enabled in the kernel (or it is insmod) then the driver in its "probe" would stuck somewhere.
Yep it's because it's not going to fail in current system configs. We request to mux in MMC/SD + SPI pins, then the rest of the settings (which are vast) are left untouched.
Quoted 1 line
Do we need to handle such scenarios. Am I missing something?
No you're correct, but these circumstances does not occur currently on the U300. But the framework is prepared to handle them.
Quoted 3 lines
Further, if you can describe what is onmask field (of pmx) and what devices/options are multiplexed with (say) spi, it would help me better understand the code.
.onmask should be something like .bits really, it's tuples of mask+bits to be set in registers to activate the selected padmux setting. It's all specific to the DB3xxx system controller, nothing you should worry too much about really.
Quoted 6 lines
Quoted 2 lines
We've actually seen usecases where you need to dynamically remux while drivers are running but these have been rare and on older chips I think.
You mean to say dynamically remapping pins to achieve some function with the same driver? or taking out one driver and inserting another after changing mux config.
Actually switching back and forth between using pins in one way and then in another way for different usecases. Not like every microsecond, but on minute interval. We tried to avoid it and on the Linux port this was never the case.
Quoted 2 lines
In any case one of the objective is to keep same linux image for different configurations/boards. Isn't it ?
That's more of a side effect. We did have compile-time dependencies that cannot even be avoided with the devicetree code. For example the U300 series had physical RAM at different addresses depending on model, that can *never* be handled with a single kernel image, so we could just give up that idea immediately....
Linus