RE: am335x: system doesn't reboot after flashing NAND

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Roger, Yegor,

>From: Quadros, Roger
>>On 06/04/2014 10:45 PM, Yegor Yefremov wrote:
[...]

>>
>> The 0x80000000 address seems to be the beginning of NAND region:
>>
>> ranges = <0 0 0x08000000 0x10000000>;   /* CS0: NAND */
>>
>> I've taken this example from am335x_evm.dts. I have tried to change
>> the mapping to 0x90000000, but kernel still uses 0x80000000, Where in
>> the kernel will "ranges" be evaluated? I'm digging thorugh
>> arch/arm/mach-omap2/gpmc.c and gpmc-nand.c, but didn't really found
>> the place.
>
>Well it doesn't. It just uses whatever was setup by the bootloader or
>randomly allocated by gpmc_cs_request().
>
>I'm working on fixing this up. I should be posting v2 of the GPMC refactor
>series by this week and you should be able to map the CS region as specified
>in the DT.
>
>Till then, maybe you can pre-configure CS0 in the bootloader to wherever you want
>or alternatively call gpmc_cs_remap() after the gpmc_cs_request() in gpmc_nand_init();
>
>cheers,
>-roger

I had a fix for this gpmc_cs_remap issue, it worked for beaglebone NOR,
but havn't checked on other devices. So please see if it works for you.

However, I don't suspect XIP boot here because even if CPU is detecting
garbage data while reading from 0x80000000 it won't find a valid image
header there, and so XIP boot should have failed, and boot sequence
should fall back to MMC. It shouldn't have hung.

Still you can try below patch for gpmc_cs_remap().

---------------

From: Pekon Gupta <pekon@xxxxxx>
Date: Fri, 9 May 2014 15:17:32 +0530
Subject: [PATCH 12/14] ARM: OMAP2+: fix gpmc_cs_remap: re-allocating
 chip-select address space based on DT

Each GPMC chip-select needs to be configured for (base-address,CS-size) so that
GPMC understands the address-space allocated to device connected externally.
These chip-select configurations (base-address, CS-size) follow some basic
mapping rules like:
- The CS size is programmable from 256 MBytes to 16 MBytes (must be a power of 2)
  and is defined by the mask field. Attached memory smaller than the programmed
  CS region size is accessed through the entire CS region (aliasing).
- The programmed 'base-address' must be aligned to the 'CS-size' boundary and
  be a power of 2.
- Valid CS-size values are {256MB(max), 128MB, 64MB, 32MB and 16MB (min)}
  Any intermediate values creates holes in the chip-select memory-map.

This patch adds above checks in gpmc_cs_remap() so that any invalid value
passed by DT <reg> property can be filtered before actually allocating the
address space.

Signed-off-by: Pekon Gupta <pekon@xxxxxx>
---
 arch/arm/mach-omap2/gpmc.c | 42 +++++++++++++++++++++++++++++-------------
 1 file changed, 29 insertions(+), 13 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 4fc4963..224550e 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -521,26 +521,42 @@ static int gpmc_cs_delete_mem(int cs)
  * "base". Returns 0 on success and appropriate negative error code
  * on failure.
  */
-static int gpmc_cs_remap(int cs, u32 base)
+static int gpmc_cs_remap(int cs, u32 base, u32 size)
 {
 	int ret;
-	u32 old_base, size;
 
 	if (cs > gpmc_cs_num) {
 		pr_err("%s: requested chip-select is disabled\n", __func__);
 		return -ENODEV;
 	}
 
-	/*
-	 * Make sure we ignore any device offsets from the GPMC partition
-	 * allocated for the chip select and that the new base confirms
-	 * to the GPMC 16MB minimum granularity.
-	 */ 
-	base &= ~(SZ_16M - 1);
-
-	gpmc_cs_get_memconf(cs, &old_base, &size);
-	if (base == old_base)
-		return 0;
+	/* allocate enough address-space under GPMC chip-select to device */
+	if (size > SZ_256M) {
+		pr_err("%s: memory device > 256MB not supported\n", __func__);
+		return -ENODEV;
+	} else if (size > SZ_128M) {
+		WARN((size != SZ_256M), "cs=%d: allocating 256MB\n", cs);
+		size = SZ_256M;
+	} else if (size > SZ_64M) {
+		WARN((size != SZ_128M), "cs=%d: allocating 128MB\n", cs);
+		size = SZ_128M;
+	} else if (size > SZ_32M) {
+		WARN((size != SZ_64M), "cs=%d: allocating 64MB\n", cs);
+		size = SZ_64M;
+	} else if (size > SZ_16M) {
+		WARN((size != SZ_32M), "cs=%d: allocating 64MB\n", cs);
+		size = SZ_32M;
+	} else {
+		WARN((size != SZ_16M), "cs=%d: allocating 64MB\n", cs);
+		size = SZ_16M;
+	}
+
+	/* base address should be aligned with address-space size */
+	if (base & (size - 1)) {
+		pr_err("base-addr=%x should be aligned to size=%x", base, size);
+		return -EINVAL;
+	}
+
 	gpmc_cs_disable_mem(cs);
 	ret = gpmc_cs_delete_mem(cs);
 	if (ret < 0)
@@ -1551,7 +1567,7 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 	 * CS to this location. Once DT migration is complete should
 	 * just make gpmc_cs_request() map a specific address.
 	 */
-	ret = gpmc_cs_remap(cs, res.start);
+	ret = gpmc_cs_remap(cs, res.start, resource_size(&res));
 	if (ret < 0) {
 		dev_err(&pdev->dev, "cannot remap GPMC CS %d to %pa\n",
 			cs, &res.start);
-- 
1.8.5.1.163.gd7aced9

------------


with regards, pekon
��.n��������+%������w��{.n�����{�������ܨ}���Ơz�j:+v�����w����ޙ��&�)ߡ�a����z�ޗ���ݢj��w�f





[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux