diff mbox

[2/2] ARM: OMAP2: Fix GPMC memory initialisation

Message ID 1359736726-10193-3-git-send-email-jon-hunter@ti.com (mailing list archive)
State New, archived
Headers show

Commit Message

Hunter, Jon Feb. 1, 2013, 4:38 p.m. UTC
OMAP2+ devices have an internal ROM that by default is typically mapped
to the first 1MB of the GPMC address space (0x0).

For OMAP24xx devices, GPMC chip-select 0 (CS0) may be mapped to address
0x0 instead of the internal ROM if configured for an external boot mode.
If configured for an internal boot mode then the internal ROM is mapped
to 0x0.

Currently, the function gpmc_mem_init() function reserves the first 1MB
of GPMC address space for the internal OMAP ROM with the exception of
the OMAP2 APOLLON board. This prevents any device (ethernet chip, flash
memories, etc) from using this address range. This causes the GPMC probe
to fail on the OMAP2420 H4 when NOR flash is mapped to address 0x0. Fix
this by testing the boot mode for OMAP24xx devices to see if the
SYS_BOOT3 is low, indicating an external boot, and thus GPMC CS0 is
mapped to 0x0.

Please note that for OMAP3-5 devices, when booting from NOR or NAND
memories connected to CS0, these memories are always mapped to address
0x08000000 and so reserving this memory range does not present any
problems for these devices.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/gpmc.c |   25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

Comments

Tony Lindgren Feb. 1, 2013, 9:51 p.m. UTC | #1
Hi Jon,

* Jon Hunter <jon-hunter@ti.com> [130201 08:42]:
> --- a/arch/arm/mach-omap2/gpmc.c
> +++ b/arch/arm/mach-omap2/gpmc.c
> @@ -32,6 +32,7 @@
>  
>  #include "soc.h"
>  #include "common.h"
> +#include "control.h"
>  #include "omap_device.h"
>  #include "gpmc.h"
>  
> @@ -778,18 +779,26 @@ static void gpmc_mem_exit(void)
>  static int gpmc_mem_init(void)
>  {
>  	int cs, rc;
> -	unsigned long boot_rom_space = 0;
>  
> -	/* never allocate the first page, to facilitate bug detection;
> -	 * even if we didn't boot from ROM.
> +	/*
> +	 * The first 1MB of GPMC address space is mapped to the
> +	 * internal ROM. OMAP2 devices are an exception to this
> +	 * where the first 1MB may be mapped to the GPMC.
>  	 */
> -	boot_rom_space = BOOT_ROM_SPACE;
> -	/* In apollon the CS0 is mapped as 0x0000 0000 */
> -	if (machine_is_omap_apollon())
> -		boot_rom_space = 0;

This part is going away anyways with the patch dropping apollon
board support from Kyungin.

> -	gpmc_mem_root.start = GPMC_MEM_START + boot_rom_space;
> +	gpmc_mem_root.start = GPMC_MEM_START + BOOT_ROM_SPACE;
>  	gpmc_mem_root.end = GPMC_MEM_END;
>  
> +	/*
> +	 * OMAP2 devices that boot from external memory devices, will
> +	 * map CS0 to the start of the GPMC address space (0x0). We can
> +	 * test this by checking if SYS_BOOT3 pin is set. If not set
> +	 * then CS0 is mapped to 0x0.
> +	 */
> +	if (cpu_is_omap24xx())
> +		if (!(omap_ctrl_readl(OMAP24XX_CONTROL_STATUS) &
> +		      OMAP2_SYSBOOT_3_MASK))
> +			gpmc_mem_root.start = GPMC_MEM_START;
> +
>  	/* Reserve all regions that has been set up by bootloader */
>  	for (cs = 0; cs < GPMC_CS_NUM; cs++) {
>  		u32 base, size;

How about let's fix this properly to start with so we don't add
more blockers moving this code to drivers/bus?

Looks like gpmc_mem_init() gets called from gpmc_probe() so
we can pass that information in pdev.

Regards,

Tony
Hunter, Jon Feb. 2, 2013, 1:22 a.m. UTC | #2
On 02/01/2013 03:51 PM, Tony Lindgren wrote:
> Hi Jon,
> 
> * Jon Hunter <jon-hunter@ti.com> [130201 08:42]:
>> --- a/arch/arm/mach-omap2/gpmc.c
>> +++ b/arch/arm/mach-omap2/gpmc.c
>> @@ -32,6 +32,7 @@
>>  
>>  #include "soc.h"
>>  #include "common.h"
>> +#include "control.h"
>>  #include "omap_device.h"
>>  #include "gpmc.h"
>>  
>> @@ -778,18 +779,26 @@ static void gpmc_mem_exit(void)
>>  static int gpmc_mem_init(void)
>>  {
>>  	int cs, rc;
>> -	unsigned long boot_rom_space = 0;
>>  
>> -	/* never allocate the first page, to facilitate bug detection;
>> -	 * even if we didn't boot from ROM.
>> +	/*
>> +	 * The first 1MB of GPMC address space is mapped to the
>> +	 * internal ROM. OMAP2 devices are an exception to this
>> +	 * where the first 1MB may be mapped to the GPMC.
>>  	 */
>> -	boot_rom_space = BOOT_ROM_SPACE;
>> -	/* In apollon the CS0 is mapped as 0x0000 0000 */
>> -	if (machine_is_omap_apollon())
>> -		boot_rom_space = 0;
> 
> This part is going away anyways with the patch dropping apollon
> board support from Kyungin.

Yes just saw that today.

>> -	gpmc_mem_root.start = GPMC_MEM_START + boot_rom_space;
>> +	gpmc_mem_root.start = GPMC_MEM_START + BOOT_ROM_SPACE;
>>  	gpmc_mem_root.end = GPMC_MEM_END;
>>  
>> +	/*
>> +	 * OMAP2 devices that boot from external memory devices, will
>> +	 * map CS0 to the start of the GPMC address space (0x0). We can
>> +	 * test this by checking if SYS_BOOT3 pin is set. If not set
>> +	 * then CS0 is mapped to 0x0.
>> +	 */
>> +	if (cpu_is_omap24xx())
>> +		if (!(omap_ctrl_readl(OMAP24XX_CONTROL_STATUS) &
>> +		      OMAP2_SYSBOOT_3_MASK))
>> +			gpmc_mem_root.start = GPMC_MEM_START;
>> +
>>  	/* Reserve all regions that has been set up by bootloader */
>>  	for (cs = 0; cs < GPMC_CS_NUM; cs++) {
>>  		u32 base, size;
> 
> How about let's fix this properly to start with so we don't add
> more blockers moving this code to drivers/bus?
> 
> Looks like gpmc_mem_init() gets called from gpmc_probe() so
> we can pass that information in pdev.

I wondered if you would suggest that ;-)

I definitely can and it is probably best. Things like this become
painful when we move to device-tree. We really need a generic way for
passing stuff like this to drivers for omap. Our options are auxdata or
bus notifiers. I am wondering whether we can plug pdata in the
omap_device bus notifier for device-tree. Let me know if you have any
thoughts.

Cheers
Jon
Tony Lindgren Feb. 2, 2013, 6:11 p.m. UTC | #3
* Jon Hunter <jon-hunter@ti.com> [130201 17:25]:
> 
> On 02/01/2013 03:51 PM, Tony Lindgren wrote:
> > 
> > How about let's fix this properly to start with so we don't add
> > more blockers moving this code to drivers/bus?
> > 
> > Looks like gpmc_mem_init() gets called from gpmc_probe() so
> > we can pass that information in pdev.
> 
> I wondered if you would suggest that ;-)

:)
 
> I definitely can and it is probably best. Things like this become
> painful when we move to device-tree. We really need a generic way for
> passing stuff like this to drivers for omap. Our options are auxdata or
> bus notifiers. I am wondering whether we can plug pdata in the
> omap_device bus notifier for device-tree. Let me know if you have any
> thoughts.

Hmm but in this case can't you just do it based on the compatible
flag? For legacy systems we also need to pass it in pdata.

Regarding omap_device, we should find a way to keep the dependencies
between drivers and the bus code down to minimum. So ideally things
like this would be only done using just the compatible flag. But the
pdata we cannot remove quite yet.

Regards,

Tony
Hunter, Jon Feb. 4, 2013, 3:05 p.m. UTC | #4
On 02/02/2013 12:11 PM, Tony Lindgren wrote:
> * Jon Hunter <jon-hunter@ti.com> [130201 17:25]:
>>
>> On 02/01/2013 03:51 PM, Tony Lindgren wrote:
>>>
>>> How about let's fix this properly to start with so we don't add
>>> more blockers moving this code to drivers/bus?
>>>
>>> Looks like gpmc_mem_init() gets called from gpmc_probe() so
>>> we can pass that information in pdev.
>>
>> I wondered if you would suggest that ;-)
> 
> :)
>  
>> I definitely can and it is probably best. Things like this become
>> painful when we move to device-tree. We really need a generic way for
>> passing stuff like this to drivers for omap. Our options are auxdata or
>> bus notifiers. I am wondering whether we can plug pdata in the
>> omap_device bus notifier for device-tree. Let me know if you have any
>> thoughts.
> 
> Hmm but in this case can't you just do it based on the compatible
> flag? For legacy systems we also need to pass it in pdata.

This is a boot-time configuration. So really you need to read the
control status register at boot and then determine the mapping. We could
store the address of the control status read in the pdata, but I think
that is a bit of a hack.

> Regarding omap_device, we should find a way to keep the dependencies
> between drivers and the bus code down to minimum. So ideally things
> like this would be only done using just the compatible flag. But the
> pdata we cannot remove quite yet.

Agree. However, there are several drivers today (gpio, dmtimer, mmc,
serial, dss, etc), that make use of a function pointer to
omap_pm_get_dev_context_loss_count() to determine when the peripheral's
state has been lost. When booting with DT this function pointer is not
populated and so with DT we currently have no way to determine this. I
see this as a blocker to migrating completely to DT. Ideally we would
find a way for RPM to handle this and remove the function pointer.
However, right now we still need a generic way to pass this type of
platform data to drivers.

Cheers
Jon
Tony Lindgren Feb. 4, 2013, 5:45 p.m. UTC | #5
* Jon Hunter <jon-hunter@ti.com> [130204 07:09]:
> 
> On 02/02/2013 12:11 PM, Tony Lindgren wrote:
> > * Jon Hunter <jon-hunter@ti.com> [130201 17:25]:
> >>
> >> On 02/01/2013 03:51 PM, Tony Lindgren wrote:
> >>>
> >>> How about let's fix this properly to start with so we don't add
> >>> more blockers moving this code to drivers/bus?
> >>>
> >>> Looks like gpmc_mem_init() gets called from gpmc_probe() so
> >>> we can pass that information in pdev.
> >>
> >> I wondered if you would suggest that ;-)
> > 
> > :)
> >  
> >> I definitely can and it is probably best. Things like this become
> >> painful when we move to device-tree. We really need a generic way for
> >> passing stuff like this to drivers for omap. Our options are auxdata or
> >> bus notifiers. I am wondering whether we can plug pdata in the
> >> omap_device bus notifier for device-tree. Let me know if you have any
> >> thoughts.
> > 
> > Hmm but in this case can't you just do it based on the compatible
> > flag? For legacy systems we also need to pass it in pdata.
> 
> This is a boot-time configuration. So really you need to read the
> control status register at boot and then determine the mapping. We could
> store the address of the control status read in the pdata, but I think
> that is a bit of a hack.

Ah right. Well once we have Haojian's generic pinconf patches merged for
pinctrl-single, we can set up the CONTROL_STATUS register as a
pinctrl-single,bits register and query the SYSBOOT_3 pin value directly
from the driver.

AFAIK SYSBOOT_n values reflect the boot time values of the actual SYSBOOT
pins, so using generic pinconf there makes sense. But this of course should
be checked.
 
> > Regarding omap_device, we should find a way to keep the dependencies
> > between drivers and the bus code down to minimum. So ideally things
> > like this would be only done using just the compatible flag. But the
> > pdata we cannot remove quite yet.
> 
> Agree. However, there are several drivers today (gpio, dmtimer, mmc,
> serial, dss, etc), that make use of a function pointer to
> omap_pm_get_dev_context_loss_count() to determine when the peripheral's
> state has been lost. When booting with DT this function pointer is not
> populated and so with DT we currently have no way to determine this. I
> see this as a blocker to migrating completely to DT. Ideally we would
> find a way for RPM to handle this and remove the function pointer.
> However, right now we still need a generic way to pass this type of
> platform data to drivers.

Yeah pinconf generic won't help us with the legacy boot.

Regards,

Tony
Hunter, Jon Feb. 4, 2013, 6:46 p.m. UTC | #6
On 02/04/2013 11:45 AM, Tony Lindgren wrote:
> * Jon Hunter <jon-hunter@ti.com> [130204 07:09]:
>>
>> On 02/02/2013 12:11 PM, Tony Lindgren wrote:
>>> * Jon Hunter <jon-hunter@ti.com> [130201 17:25]:
>>>>
>>>> On 02/01/2013 03:51 PM, Tony Lindgren wrote:
>>>>>
>>>>> How about let's fix this properly to start with so we don't add
>>>>> more blockers moving this code to drivers/bus?
>>>>>
>>>>> Looks like gpmc_mem_init() gets called from gpmc_probe() so
>>>>> we can pass that information in pdev.
>>>>
>>>> I wondered if you would suggest that ;-)
>>>
>>> :)
>>>  
>>>> I definitely can and it is probably best. Things like this become
>>>> painful when we move to device-tree. We really need a generic way for
>>>> passing stuff like this to drivers for omap. Our options are auxdata or
>>>> bus notifiers. I am wondering whether we can plug pdata in the
>>>> omap_device bus notifier for device-tree. Let me know if you have any
>>>> thoughts.
>>>
>>> Hmm but in this case can't you just do it based on the compatible
>>> flag? For legacy systems we also need to pass it in pdata.
>>
>> This is a boot-time configuration. So really you need to read the
>> control status register at boot and then determine the mapping. We could
>> store the address of the control status read in the pdata, but I think
>> that is a bit of a hack.
> 
> Ah right. Well once we have Haojian's generic pinconf patches merged for
> pinctrl-single, we can set up the CONTROL_STATUS register as a
> pinctrl-single,bits register and query the SYSBOOT_3 pin value directly
> from the driver.
> 
> AFAIK SYSBOOT_n values reflect the boot time values of the actual SYSBOOT
> pins, so using generic pinconf there makes sense. But this of course should
> be checked.

Not sure I am a fan of that idea. It is possible the pins could be
re-used as GPIOs after reset. Given that the state at reset is latched
in a register, it is best just to read the register directly.

>>> Regarding omap_device, we should find a way to keep the dependencies
>>> between drivers and the bus code down to minimum. So ideally things
>>> like this would be only done using just the compatible flag. But the
>>> pdata we cannot remove quite yet.
>>
>> Agree. However, there are several drivers today (gpio, dmtimer, mmc,
>> serial, dss, etc), that make use of a function pointer to
>> omap_pm_get_dev_context_loss_count() to determine when the peripheral's
>> state has been lost. When booting with DT this function pointer is not
>> populated and so with DT we currently have no way to determine this. I
>> see this as a blocker to migrating completely to DT. Ideally we would
>> find a way for RPM to handle this and remove the function pointer.
>> However, right now we still need a generic way to pass this type of
>> platform data to drivers.
> 
> Yeah pinconf generic won't help us with the legacy boot.

Right. I view all this sort of thing as system-level device information
that some drivers may need. It does not seem that we have a good way to
handle that at the moment. Any ideas?

Jon
Tony Lindgren Feb. 4, 2013, 7:15 p.m. UTC | #7
* Jon Hunter <jon-hunter@ti.com> [130204 10:49]:
> On 02/04/2013 11:45 AM, Tony Lindgren wrote:
> > 
> > AFAIK SYSBOOT_n values reflect the boot time values of the actual SYSBOOT
> > pins, so using generic pinconf there makes sense. But this of course should
> > be checked.
> 
> Not sure I am a fan of that idea. It is possible the pins could be
> re-used as GPIOs after reset. Given that the state at reset is latched
> in a register, it is best just to read the register directly.

Yes the physical SYSBOOT pins can be reused as GPIO, but that's are already
handled by the padconf and GPIO registers. This is a different register
showing the boot time pin values for some pins. So it makes sense to use
generic pinconf to make the pin values available to the client drivers
as needed.

The advantage doing it this way is that we don't need to export any omap
custom functions to the drivers from the SCM driver. This way we need zero
platform glue code, and can deal with it directly in the drivers in a
generic way. And all we need to do is just need to map the SoC specific
SYSBOOT pin register in the .dts files.

It may also make sense to export DEVICETYPE this way. At least early omaps
had the GP vs HS mode configured by pulls on some pins during the boot time.
So those bits too may reflect actual physical pins during the boot time
configured by the efuse settings?

> >>> Regarding omap_device, we should find a way to keep the dependencies
> >>> between drivers and the bus code down to minimum. So ideally things
> >>> like this would be only done using just the compatible flag. But the
> >>> pdata we cannot remove quite yet.
> >>
> >> Agree. However, there are several drivers today (gpio, dmtimer, mmc,
> >> serial, dss, etc), that make use of a function pointer to
> >> omap_pm_get_dev_context_loss_count() to determine when the peripheral's
> >> state has been lost. When booting with DT this function pointer is not
> >> populated and so with DT we currently have no way to determine this. I
> >> see this as a blocker to migrating completely to DT. Ideally we would
> >> find a way for RPM to handle this and remove the function pointer.
> >> However, right now we still need a generic way to pass this type of
> >> platform data to drivers.
> > 
> > Yeah pinconf generic won't help us with the legacy boot.
> 
> Right. I view all this sort of thing as system-level device information
> that some drivers may need. It does not seem that we have a good way to
> handle that at the moment. Any ideas?

I suggest just passing it in in pdata for now for the legacy boot. Then
I suggest we make what we can generic with pinconf in the long run.

Regards,

Tony
Hunter, Jon Feb. 4, 2013, 7:33 p.m. UTC | #8
On 02/04/2013 01:15 PM, Tony Lindgren wrote:
> * Jon Hunter <jon-hunter@ti.com> [130204 10:49]:
>> On 02/04/2013 11:45 AM, Tony Lindgren wrote:
>>>
>>> AFAIK SYSBOOT_n values reflect the boot time values of the actual SYSBOOT
>>> pins, so using generic pinconf there makes sense. But this of course should
>>> be checked.
>>
>> Not sure I am a fan of that idea. It is possible the pins could be
>> re-used as GPIOs after reset. Given that the state at reset is latched
>> in a register, it is best just to read the register directly.
> 
> Yes the physical SYSBOOT pins can be reused as GPIO, but that's are already
> handled by the padconf and GPIO registers. This is a different register
> showing the boot time pin values for some pins. So it makes sense to use
> generic pinconf to make the pin values available to the client drivers
> as needed.
> 
> The advantage doing it this way is that we don't need to export any omap
> custom functions to the drivers from the SCM driver. This way we need zero
> platform glue code, and can deal with it directly in the drivers in a
> generic way. And all we need to do is just need to map the SoC specific
> SYSBOOT pin register in the .dts files.

I see what you are saying exporting the state in control_status register
via the pinconf. That could work.

> It may also make sense to export DEVICETYPE this way. At least early omaps
> had the GP vs HS mode configured by pulls on some pins during the boot time.
> So those bits too may reflect actual physical pins during the boot time
> configured by the efuse settings?

I *believe* that was only omap1.

>>>>> Regarding omap_device, we should find a way to keep the dependencies
>>>>> between drivers and the bus code down to minimum. So ideally things
>>>>> like this would be only done using just the compatible flag. But the
>>>>> pdata we cannot remove quite yet.
>>>>
>>>> Agree. However, there are several drivers today (gpio, dmtimer, mmc,
>>>> serial, dss, etc), that make use of a function pointer to
>>>> omap_pm_get_dev_context_loss_count() to determine when the peripheral's
>>>> state has been lost. When booting with DT this function pointer is not
>>>> populated and so with DT we currently have no way to determine this. I
>>>> see this as a blocker to migrating completely to DT. Ideally we would
>>>> find a way for RPM to handle this and remove the function pointer.
>>>> However, right now we still need a generic way to pass this type of
>>>> platform data to drivers.
>>>
>>> Yeah pinconf generic won't help us with the legacy boot.
>>
>> Right. I view all this sort of thing as system-level device information
>> that some drivers may need. It does not seem that we have a good way to
>> handle that at the moment. Any ideas?
> 
> I suggest just passing it in in pdata for now for the legacy boot. Then
> I suggest we make what we can generic with pinconf in the long run.

I don't see why we would want to export a function pointer to
omap_pm_get_dev_context_loss_count() with pinconf. Have we got our wires
crossed here?

Jon
Tony Lindgren Feb. 4, 2013, 7:47 p.m. UTC | #9
* Jon Hunter <jon-hunter@ti.com> [130204 11:37]:
> 
> On 02/04/2013 01:15 PM, Tony Lindgren wrote:
> > * Jon Hunter <jon-hunter@ti.com> [130204 10:49]:
> >> On 02/04/2013 11:45 AM, Tony Lindgren wrote:
> >>>
> >>> AFAIK SYSBOOT_n values reflect the boot time values of the actual SYSBOOT
> >>> pins, so using generic pinconf there makes sense. But this of course should
> >>> be checked.
> >>
> >> Not sure I am a fan of that idea. It is possible the pins could be
> >> re-used as GPIOs after reset. Given that the state at reset is latched
> >> in a register, it is best just to read the register directly.
> > 
> > Yes the physical SYSBOOT pins can be reused as GPIO, but that's are already
> > handled by the padconf and GPIO registers. This is a different register
> > showing the boot time pin values for some pins. So it makes sense to use
> > generic pinconf to make the pin values available to the client drivers
> > as needed.
> > 
> > The advantage doing it this way is that we don't need to export any omap
> > custom functions to the drivers from the SCM driver. This way we need zero
> > platform glue code, and can deal with it directly in the drivers in a
> > generic way. And all we need to do is just need to map the SoC specific
> > SYSBOOT pin register in the .dts files.
> 
> I see what you are saying exporting the state in control_status register
> via the pinconf. That could work.
> 
> > It may also make sense to export DEVICETYPE this way. At least early omaps
> > had the GP vs HS mode configured by pulls on some pins during the boot time.
> > So those bits too may reflect actual physical pins during the boot time
> > configured by the efuse settings?
> 
> I *believe* that was only omap1.

Yeah but maybe the efuses just configure some pulls for selected pins for
later omaps?
 
> >>>>> Regarding omap_device, we should find a way to keep the dependencies
> >>>>> between drivers and the bus code down to minimum. So ideally things
> >>>>> like this would be only done using just the compatible flag. But the
> >>>>> pdata we cannot remove quite yet.
> >>>>
> >>>> Agree. However, there are several drivers today (gpio, dmtimer, mmc,
> >>>> serial, dss, etc), that make use of a function pointer to
> >>>> omap_pm_get_dev_context_loss_count() to determine when the peripheral's
> >>>> state has been lost. When booting with DT this function pointer is not
> >>>> populated and so with DT we currently have no way to determine this. I
> >>>> see this as a blocker to migrating completely to DT. Ideally we would
> >>>> find a way for RPM to handle this and remove the function pointer.
> >>>> However, right now we still need a generic way to pass this type of
> >>>> platform data to drivers.
> >>>
> >>> Yeah pinconf generic won't help us with the legacy boot.
> >>
> >> Right. I view all this sort of thing as system-level device information
> >> that some drivers may need. It does not seem that we have a good way to
> >> handle that at the moment. Any ideas?
> > 
> > I suggest just passing it in in pdata for now for the legacy boot. Then
> > I suggest we make what we can generic with pinconf in the long run.
> 
> I don't see why we would want to export a function pointer to
> omap_pm_get_dev_context_loss_count() with pinconf. Have we got our wires
> crossed here?

Yes sorry, too many muxes here. I got this topic mixed up with the sysboot
pin topic :)

We really need to find a Linux generic API to query this. Sounds like it
should be part of runtime PM?

Regards,

Tony
Hunter, Jon Feb. 4, 2013, 7:51 p.m. UTC | #10
On 02/04/2013 01:47 PM, Tony Lindgren wrote:
> * Jon Hunter <jon-hunter@ti.com> [130204 11:37]:
>>
>> On 02/04/2013 01:15 PM, Tony Lindgren wrote:
>>> * Jon Hunter <jon-hunter@ti.com> [130204 10:49]:
>>>> On 02/04/2013 11:45 AM, Tony Lindgren wrote:
>>>>>
>>>>> AFAIK SYSBOOT_n values reflect the boot time values of the actual SYSBOOT
>>>>> pins, so using generic pinconf there makes sense. But this of course should
>>>>> be checked.
>>>>
>>>> Not sure I am a fan of that idea. It is possible the pins could be
>>>> re-used as GPIOs after reset. Given that the state at reset is latched
>>>> in a register, it is best just to read the register directly.
>>>
>>> Yes the physical SYSBOOT pins can be reused as GPIO, but that's are already
>>> handled by the padconf and GPIO registers. This is a different register
>>> showing the boot time pin values for some pins. So it makes sense to use
>>> generic pinconf to make the pin values available to the client drivers
>>> as needed.
>>>
>>> The advantage doing it this way is that we don't need to export any omap
>>> custom functions to the drivers from the SCM driver. This way we need zero
>>> platform glue code, and can deal with it directly in the drivers in a
>>> generic way. And all we need to do is just need to map the SoC specific
>>> SYSBOOT pin register in the .dts files.
>>
>> I see what you are saying exporting the state in control_status register
>> via the pinconf. That could work.
>>
>>> It may also make sense to export DEVICETYPE this way. At least early omaps
>>> had the GP vs HS mode configured by pulls on some pins during the boot time.
>>> So those bits too may reflect actual physical pins during the boot time
>>> configured by the efuse settings?
>>
>> I *believe* that was only omap1.
> 
> Yeah but maybe the efuses just configure some pulls for selected pins for
> later omaps?
>  
>>>>>>> Regarding omap_device, we should find a way to keep the dependencies
>>>>>>> between drivers and the bus code down to minimum. So ideally things
>>>>>>> like this would be only done using just the compatible flag. But the
>>>>>>> pdata we cannot remove quite yet.
>>>>>>
>>>>>> Agree. However, there are several drivers today (gpio, dmtimer, mmc,
>>>>>> serial, dss, etc), that make use of a function pointer to
>>>>>> omap_pm_get_dev_context_loss_count() to determine when the peripheral's
>>>>>> state has been lost. When booting with DT this function pointer is not
>>>>>> populated and so with DT we currently have no way to determine this. I
>>>>>> see this as a blocker to migrating completely to DT. Ideally we would
>>>>>> find a way for RPM to handle this and remove the function pointer.
>>>>>> However, right now we still need a generic way to pass this type of
>>>>>> platform data to drivers.
>>>>>
>>>>> Yeah pinconf generic won't help us with the legacy boot.
>>>>
>>>> Right. I view all this sort of thing as system-level device information
>>>> that some drivers may need. It does not seem that we have a good way to
>>>> handle that at the moment. Any ideas?
>>>
>>> I suggest just passing it in in pdata for now for the legacy boot. Then
>>> I suggest we make what we can generic with pinconf in the long run.
>>
>> I don't see why we would want to export a function pointer to
>> omap_pm_get_dev_context_loss_count() with pinconf. Have we got our wires
>> crossed here?
> 
> Yes sorry, too many muxes here. I got this topic mixed up with the sysboot
> pin topic :)
> 
> We really need to find a Linux generic API to query this. Sounds like it
> should be part of runtime PM?

Ideally, yes. I had discussed with Kevin about adding a new state for
"logic state lost" and then if this could be passed to the RPM resume
callback then we could use this. May be I need to bring this up with Tero.

Cheers
Jon
diff mbox

Patch

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 441cc63..9486b8e 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -32,6 +32,7 @@ 
 
 #include "soc.h"
 #include "common.h"
+#include "control.h"
 #include "omap_device.h"
 #include "gpmc.h"
 
@@ -778,18 +779,26 @@  static void gpmc_mem_exit(void)
 static int gpmc_mem_init(void)
 {
 	int cs, rc;
-	unsigned long boot_rom_space = 0;
 
-	/* never allocate the first page, to facilitate bug detection;
-	 * even if we didn't boot from ROM.
+	/*
+	 * The first 1MB of GPMC address space is mapped to the
+	 * internal ROM. OMAP2 devices are an exception to this
+	 * where the first 1MB may be mapped to the GPMC.
 	 */
-	boot_rom_space = BOOT_ROM_SPACE;
-	/* In apollon the CS0 is mapped as 0x0000 0000 */
-	if (machine_is_omap_apollon())
-		boot_rom_space = 0;
-	gpmc_mem_root.start = GPMC_MEM_START + boot_rom_space;
+	gpmc_mem_root.start = GPMC_MEM_START + BOOT_ROM_SPACE;
 	gpmc_mem_root.end = GPMC_MEM_END;
 
+	/*
+	 * OMAP2 devices that boot from external memory devices, will
+	 * map CS0 to the start of the GPMC address space (0x0). We can
+	 * test this by checking if SYS_BOOT3 pin is set. If not set
+	 * then CS0 is mapped to 0x0.
+	 */
+	if (cpu_is_omap24xx())
+		if (!(omap_ctrl_readl(OMAP24XX_CONTROL_STATUS) &
+		      OMAP2_SYSBOOT_3_MASK))
+			gpmc_mem_root.start = GPMC_MEM_START;
+
 	/* Reserve all regions that has been set up by bootloader */
 	for (cs = 0; cs < GPMC_CS_NUM; cs++) {
 		u32 base, size;