Subject: [E3-hacking] [PATCH] Fix broken NAND on Amstrad Delta

From: Janusz Krzysztofik <[email-masked]>
Date: Wed, 21 Oct 2009 02:39:53 +0200

Hi,
I found that with commit 15ac408ee5a509053a765b816e9179515329369f, "OMAP:
UART: drop OMAP_TAG_UART, enable all UARTs, auto-disabled on idle", NAND got
not accessible on Amstrad Delta (E3). That seems to be caused by unnecessary
omap_cfg_reg() calls for UART ports 2 and 3, that were never used on that
machine before and now are initilalized and supposed to be auto-disabled.

I can suspect that similiar problems may exist for other OMAP1510 based
boards. Furthermore, since mux code is going to be reorganized, the right
solution would probably be to remove those cpu_is_omap1510() specific bits
completely from arch/arm/mach-omap1/serial.c and push them into board specific
files where applicable. However, not being familiar with any OMAP hardware
other that my amsdelta, I provide a patch that solves the problem for that
machine only. I have locked out the bits for UART1 as well as those look not
really required, as far as I can understand
http://focus.ti.com/lit/ds/symlink/omap5910.pdf.

Created and tested against linux-2.6.32-r5.

Thanks,
Janusz

Signed-off-by: Janusz Krzysztofik <[email-masked]>

---
--- linux-2.6.32-rc5/arch/arm/mach-omap1/serial.c.orig	2009-10-20 22:38:38.000000000 +0200
+++ linux-2.6.32-rc5/arch/arm/mach-omap1/serial.c	2009-10-21 01:26:51.000000000 +0200
@@ -143,7 +143,7 @@ void __init omap_serial_init(void)
 				if (cpu_is_omap15xx())
 					clk_set_rate(uart1_ck, 12000000);
 			}
-			if (cpu_is_omap15xx()) {
+			if (cpu_is_omap15xx() && !(machine_is_ams_delta())) {
 				omap_cfg_reg(UART1_TX);
 				omap_cfg_reg(UART1_RTS);
 				if (machine_is_omap_innovator()) {
@@ -165,7 +165,7 @@ void __init omap_serial_init(void)
 				else
 					clk_set_rate(uart2_ck, 48000000);
 			}
-			if (cpu_is_omap15xx()) {
+			if (cpu_is_omap15xx() && !(machine_is_ams_delta())) {
 				omap_cfg_reg(UART2_TX);
 				omap_cfg_reg(UART2_RTS);
 				if (machine_is_omap_innovator()) {
@@ -185,7 +185,7 @@ void __init omap_serial_init(void)
 				if (cpu_is_omap15xx())
 					clk_set_rate(uart3_ck, 12000000);
 			}
-			if (cpu_is_omap15xx()) {
+			if (cpu_is_omap15xx() && !(machine_is_ams_delta())) {
 				omap_cfg_reg(UART3_TX);
 				omap_cfg_reg(UART3_RX);
 			}

---

From: Tony Lindgren <[email-masked]>
Date: Tue, 20 Oct 2009 17:51:35 -0700

> http://focus.ti.com/lit/ds/symlink/omap5910.pdf.

Oops. That happened as a nasty side effect when we removed the OMAP_TAG_UART
in commit 15ac408ee5a509053a765b816e9179515329369f.

Let's just remove the omap_cfg_reg() calls from mach-omap1/serial.c, and
add them to the board-*.c files like you suggest above. We should be able
to find which ports to mux by looking at the enabled_uarts mask in the
commit mentioned above.

Regards,

Tony

---

From: Janusz Krzysztofik <[email-masked]>
Date: Wed, 21 Oct 2009 12:53:50 +0200

> to find which ports to mux by looking at the enabled_uarts mask in the

Tony,
I can prepare a patch if you haven't started working on it yet, but please do 
me a favour and give your comments on another, old but still not answered 
subject:

http://www.spinics.net/lists/linux-omap/msg17692.html
I have just checked that temporary solution still applies cleanly on top of 
2.6.32-rc5 and corrects the problem of otherwise unusable ASoC over McBSP1 on 
my Amstrad Delta.

Thanks,
Janusz

---

From: Tony Lindgren <[email-masked]>
Date: Wed, 21 Oct 2009 08:54:58 -0700

> me a favour and give your comments on another, old but still not answered 

Yes, please do that patch if you can!
 
> 2.6.32-rc5 and corrects the problem of otherwise unusable ASoC over McBSP1 on 

Well let's try to work that in for this coming merge window.

How about we rename it to dsp-c55x-common.c? And only do the minimal bits
to idle the DSP if called from the board-*.c file?

The rest we can move to the old dspgateway branch and rebase that to
the current kernel.

I think the right way would be to update the dspgateway to use the iommu
code, so let's not add similar code except to idle the c55x.

Regards,

Tony

---

From: Janusz Krzysztofik <[email-masked]>
Date: Wed, 21 Oct 2009 18:27:53 +0200

> to find which ports to mux by looking at the enabled_uarts mask in the

Here you are (board-*.c changes limited to those OMAP1510 based).
Created against linux-2.6.32-rc5.
Tested on Amsdtrad Delta only.

---
diff -upr linux-2.6.32-rc5.orig/arch/arm/mach-omap1/board-ams-delta.c linux-2.6.32-rc5.fixed/arch/arm/mach-omap1/board-ams-delta.c
--- linux-2.6.32-rc5.orig/arch/arm/mach-omap1/board-ams-delta.c	2009-10-16 02:41:50.000000000 +0200
+++ linux-2.6.32-rc5.fixed/arch/arm/mach-omap1/board-ams-delta.c	2009-10-21 17:41:29.000000000 +0200
@@ -219,6 +219,10 @@ static struct platform_device *ams_delta
 
 static void __init ams_delta_init(void)
 {
+	/* setup mux pins for uarts, removed from serial.c */
+	omap_cfg_reg(UART1_TX);
+	omap_cfg_reg(UART1_RTS);
+
 	iotable_init(ams_delta_io_desc, ARRAY_SIZE(ams_delta_io_desc));
 
 	omap_board_config = ams_delta_config;
diff -upr linux-2.6.32-rc5.orig/arch/arm/mach-omap1/board-generic.c linux-2.6.32-rc5.fixed/arch/arm/mach-omap1/board-generic.c
--- linux-2.6.32-rc5.orig/arch/arm/mach-omap1/board-generic.c	2009-10-16 02:41:50.000000000 +0200
+++ linux-2.6.32-rc5.fixed/arch/arm/mach-omap1/board-generic.c	2009-10-21 18:15:37.000000000 +0200
@@ -64,6 +64,14 @@ static void __init omap_generic_init(voi
 {
 #ifdef CONFIG_ARCH_OMAP15XX
 	if (cpu_is_omap15xx()) {
+		/* setup mux pins for uarts, removed from serial.c */
+		omap_cfg_reg(UART1_TX);
+		omap_cfg_reg(UART1_RTS);
+		omap_cfg_reg(UART2_TX);
+		omap_cfg_reg(UART2_RTS);
+		omap_cfg_reg(UART3_TX);
+		omap_cfg_reg(UART3_RX);
+
 		omap_usb_init(&generic1510_usb_config);
 	}
 #endif
diff -upr linux-2.6.32-rc5.orig/arch/arm/mach-omap1/board-innovator.c linux-2.6.32-rc5.fixed/arch/arm/mach-omap1/board-innovator.c
--- linux-2.6.32-rc5.orig/arch/arm/mach-omap1/board-innovator.c	2009-10-16 02:41:50.000000000 +0200
+++ linux-2.6.32-rc5.fixed/arch/arm/mach-omap1/board-innovator.c	2009-10-21 18:16:59.000000000 +0200
@@ -376,6 +376,24 @@ static void __init innovator_init(void)
 {
 #ifdef CONFIG_ARCH_OMAP15XX
 	if (cpu_is_omap1510()) {
+		/* setup mux pins for uarts, removed from serial.c */
+		omap_cfg_reg(UART1_TX);
+		omap_cfg_reg(UART1_RTS);
+		omap_cfg_reg(UART2_TX);
+		omap_cfg_reg(UART2_RTS);
+		omap_cfg_reg(UART3_TX);
+		omap_cfg_reg(UART3_RX);
+
+		reg = fpga_read(OMAP1510_FPGA_POWER);
+		reg |= OMAP1510_FPGA_PCR_COM1_EN;
+		fpga_write(reg, OMAP1510_FPGA_POWER);
+		udelay(10);
+
+		reg = fpga_read(OMAP1510_FPGA_POWER);
+		reg |= OMAP1510_FPGA_PCR_COM2_EN;
+		fpga_write(reg, OMAP1510_FPGA_POWER);
+		udelay(10);
+
 		platform_add_devices(innovator1510_devices, ARRAY_SIZE(innovator1510_devices));
 		spi_register_board_info(innovator1510_boardinfo,
 				ARRAY_SIZE(innovator1510_boardinfo));
diff -upr linux-2.6.32-rc5.orig/arch/arm/mach-omap1/board-palmte.c linux-2.6.32-rc5.fixed/arch/arm/mach-omap1/board-palmte.c
--- linux-2.6.32-rc5.orig/arch/arm/mach-omap1/board-palmte.c	2009-10-16 02:41:50.000000000 +0200
+++ linux-2.6.32-rc5.fixed/arch/arm/mach-omap1/board-palmte.c	2009-10-21 17:38:59.000000000 +0200
@@ -342,6 +342,14 @@ static void __init palmte_misc_gpio_setu
 
 static void __init omap_palmte_init(void)
 {
+	/* setup mux pins for uarts, removed from serial.c */
+	omap_cfg_reg(UART1_TX);
+	omap_cfg_reg(UART1_RTS);
+	omap_cfg_reg(UART2_TX);
+	omap_cfg_reg(UART2_RTS);
+	omap_cfg_reg(UART3_TX);
+	omap_cfg_reg(UART3_RX);
+
 	omap_board_config = palmte_config;
 	omap_board_config_size = ARRAY_SIZE(palmte_config);
 
diff -upr linux-2.6.32-rc5.orig/arch/arm/mach-omap1/board-palmtt.c linux-2.6.32-rc5.fixed/arch/arm/mach-omap1/board-palmtt.c
--- linux-2.6.32-rc5.orig/arch/arm/mach-omap1/board-palmtt.c	2009-10-16 02:41:50.000000000 +0200
+++ linux-2.6.32-rc5.fixed/arch/arm/mach-omap1/board-palmtt.c	2009-10-21 17:39:19.000000000 +0200
@@ -289,6 +289,14 @@ static void __init omap_mpu_wdt_mode(int
 
 static void __init omap_palmtt_init(void)
 {
+	/* setup mux pins for uarts, removed from serial.c */
+	omap_cfg_reg(UART1_TX);
+	omap_cfg_reg(UART1_RTS);
+	omap_cfg_reg(UART2_TX);
+	omap_cfg_reg(UART2_RTS);
+	omap_cfg_reg(UART3_TX);
+	omap_cfg_reg(UART3_RX);
+
 	omap_mpu_wdt_mode(0);
 
 	omap_board_config = palmtt_config;
diff -upr linux-2.6.32-rc5.orig/arch/arm/mach-omap1/board-palmz71.c linux-2.6.32-rc5.fixed/arch/arm/mach-omap1/board-palmz71.c
--- linux-2.6.32-rc5.orig/arch/arm/mach-omap1/board-palmz71.c	2009-10-16 02:41:50.000000000 +0200
+++ linux-2.6.32-rc5.fixed/arch/arm/mach-omap1/board-palmz71.c	2009-10-21 17:39:34.000000000 +0200
@@ -307,6 +307,14 @@ palmz71_gpio_setup(int early)
 static void __init
 omap_palmz71_init(void)
 {
+	/* setup mux pins for uarts, removed from serial.c */
+	omap_cfg_reg(UART1_TX);
+	omap_cfg_reg(UART1_RTS);
+	omap_cfg_reg(UART2_TX);
+	omap_cfg_reg(UART2_RTS);
+	omap_cfg_reg(UART3_TX);
+	omap_cfg_reg(UART3_RX);
+
 	palmz71_gpio_setup(1);
 	omap_mpu_wdt_mode(0);
 
diff -upr linux-2.6.32-rc5.orig/arch/arm/mach-omap1/board-sx1.c linux-2.6.32-rc5.fixed/arch/arm/mach-omap1/board-sx1.c
--- linux-2.6.32-rc5.orig/arch/arm/mach-omap1/board-sx1.c	2009-10-16 02:41:50.000000000 +0200
+++ linux-2.6.32-rc5.fixed/arch/arm/mach-omap1/board-sx1.c	2009-10-21 17:40:20.000000000 +0200
@@ -377,6 +377,14 @@ static struct omap_board_config_kernel s
 
 static void __init omap_sx1_init(void)
 {
+	/* setup mux pins for uarts, removed from serial.c */
+	omap_cfg_reg(UART1_TX);
+	omap_cfg_reg(UART1_RTS);
+	omap_cfg_reg(UART2_TX);
+	omap_cfg_reg(UART2_RTS);
+	omap_cfg_reg(UART3_TX);
+	omap_cfg_reg(UART3_RX);
+
 	platform_add_devices(sx1_devices, ARRAY_SIZE(sx1_devices));
 
 	omap_board_config = sx1_config;
diff -upr linux-2.6.32-rc5.orig/arch/arm/mach-omap1/board-voiceblue.c linux-2.6.32-rc5.fixed/arch/arm/mach-omap1/board-voiceblue.c
--- linux-2.6.32-rc5.orig/arch/arm/mach-omap1/board-voiceblue.c	2009-10-16 02:41:50.000000000 +0200
+++ linux-2.6.32-rc5.fixed/arch/arm/mach-omap1/board-voiceblue.c	2009-10-21 17:40:57.000000000 +0200
@@ -152,6 +152,14 @@ static void __init voiceblue_init_irq(vo
 
 static void __init voiceblue_init(void)
 {
+	/* setup mux pins for uarts, removed from serial.c */
+	omap_cfg_reg(UART1_TX);
+	omap_cfg_reg(UART1_RTS);
+	omap_cfg_reg(UART2_TX);
+	omap_cfg_reg(UART2_RTS);
+	omap_cfg_reg(UART3_TX);
+	omap_cfg_reg(UART3_RX);
+
 	/* Watchdog */
 	gpio_request(0, "Watchdog");
 	/* smc91x reset */
diff -upr linux-2.6.32-rc5.orig/arch/arm/mach-omap1/serial.c linux-2.6.32-rc5.fixed/arch/arm/mach-omap1/serial.c
--- linux-2.6.32-rc5.orig/arch/arm/mach-omap1/serial.c	2009-10-16 02:41:50.000000000 +0200
+++ linux-2.6.32-rc5.fixed/arch/arm/mach-omap1/serial.c	2009-10-21 17:53:49.000000000 +0200
@@ -143,16 +143,6 @@ void __init omap_serial_init(void)
 				if (cpu_is_omap15xx())
 					clk_set_rate(uart1_ck, 12000000);
 			}
-			if (cpu_is_omap15xx()) {
-				omap_cfg_reg(UART1_TX);
-				omap_cfg_reg(UART1_RTS);
-				if (machine_is_omap_innovator()) {
-					reg = fpga_read(OMAP1510_FPGA_POWER);
-					reg |= OMAP1510_FPGA_PCR_COM1_EN;
-					fpga_write(reg, OMAP1510_FPGA_POWER);
-					udelay(10);
-				}
-			}
 			break;
 		case 1:
 			uart2_ck = clk_get(NULL, "uart2_ck");
@@ -165,16 +155,6 @@ void __init omap_serial_init(void)
 				else
 					clk_set_rate(uart2_ck, 48000000);
 			}
-			if (cpu_is_omap15xx()) {
-				omap_cfg_reg(UART2_TX);
-				omap_cfg_reg(UART2_RTS);
-				if (machine_is_omap_innovator()) {
-					reg = fpga_read(OMAP1510_FPGA_POWER);
-					reg |= OMAP1510_FPGA_PCR_COM2_EN;
-					fpga_write(reg, OMAP1510_FPGA_POWER);
-					udelay(10);
-				}
-			}
 			break;
 		case 2:
 			uart3_ck = clk_get(NULL, "uart3_ck");
@@ -185,10 +165,6 @@ void __init omap_serial_init(void)
 				if (cpu_is_omap15xx())
 					clk_set_rate(uart3_ck, 12000000);
 			}
-			if (cpu_is_omap15xx()) {
-				omap_cfg_reg(UART3_TX);
-				omap_cfg_reg(UART3_RX);
-			}
 			break;
 		}
 		omap_serial_reset(&serial_platform_data[i]);

---

From: Tony Lindgren <[email-masked]>
Date: Thu, 22 Oct 2009 11:43:00 -0700

> Tested on Amsdtrad Delta only.

Thanks, I'll add it to the omap-fixes series for this -rc cycle with
a description on how things broke.

BTW, you might want to also take a look at adding support for powering
down the uarts with an idle timer for mach-omap1/serial.c the same
way as mach-omap2/serial.c does.

Otherwise the enabled serial ports keep the system from hitting
retention during idle.

Regards,

Tony