Skip to contentSkip to conversation

assortment of tegra fixes/enhancements

PATCH Superseded Marcel Ziswiler 5 participants 35 messages Jul 20, 2015 – Aug 5, 2015

Subsystems (4)

v2 of 5 Superseded Latest is v5 →

lore
Share & tools
lore
#0 lore raw

v2 cover assortment of tegra fixes/enhancements

From: Marcel Ziswiler <[email protected]>

This patch set is an assortment of tegra fixes/enhancements distilled straight from our downstream integration work.

Changes in v2:
- dropped Colibri T20 specific ONFI detection enablement patch (formerly
9) as I noticed this already being done globally as part of tegra20-common.h
- enable UBI/UBIFS support (11)
- limit TFTP block size (13) on Colibri T20 to 1536 due to issues observed otherwise
- drop unrelated clean-up in (3) to be done as part of a separate patch (14)
- new patch (15) fixing nRESET_OUT
- new patch (16) fixing USB DM regression on Apalis/Colibri T30

Marcel Ziswiler (15):
ARM: tegra: allow custom usb manufacturer/product/vendor ids/strings
ARM: tegra: allow reading recovery mode boot type apalis/colibri_t20/t30: integrate recovery mode detection
colibri_t20: fix device-tree compatible node
colibri_t20: add lcd display support
colibri_t20: add i2c support
colibri_t20: disable PMIC sleep mode on low supply voltage
tegra: nand: fix read_byte required for proper onfi detection mtd/nand/tegra: alignment workaround
colibri_t20: enable mtdparts support
colibri_t20: enable ubi/ubifs support apalis/colibri_t20/t30: enable raw initrd support apalis/colibri_t20/30: clean-up
colibri_t20: fix reset out pin
apalis/colibri_t30: fix usb dm regression

Max Krummenacher (1):
apalis/colibri_t20/t30: increase tftp blocksize

 arch/arm/dts/tegra20-colibri.dts          |  63 ++++++++++++++-
 arch/arm/dts/tegra30-apalis.dts           |   2 +-
 arch/arm/dts/tegra30-colibri.dts          |   4 +-
 arch/arm/include/asm/arch-tegra/tegra.h   |   2 +
 board/toradex/apalis_t30/apalis_t30.c     |  15 +++-
 board/toradex/colibri_t20/colibri_t20.c   |  68 +++++++++++++++++
 board/toradex/colibri_t30/colibri_t30.c   |  18 ++++-
 drivers/mtd/nand/tegra_nand.c             | 122 ++++++++++--------------------
 include/configs/apalis_t30.h              |  16 +++-
 include/configs/colibri_t20.h             |  56 ++++++++++++--
 include/configs/colibri_t30.h             |  16 +++-
 include/configs/tegra-common-usb-gadget.h |   6 ++
 12 files changed, 287 insertions(+), 101 deletions(-)
Signature · 1 line
2.4.3
#1 lore raw

PATCH v2 1/16 ARM: tegra: allow custom usb manufacturer/product/vendor ids/strings

From: Marcel Ziswiler <[email protected]>

Allow for optional custom USB gadget manufacturer/product/vendor IDs/strings to be specified.

---
 include/configs/tegra-common-usb-gadget.h | 6 ++++++
 1 file changed, 6 insertions(+)
include/configs/tegra-common-usb-gadget.h +6 -0
index 287460c..645d965 100644
@@ -15,9 +15,15 @@
 #define CONFIG_CI_UDC
 #define CONFIG_CI_UDC_HAS_HOSTPC
 #define CONFIG_USB_GADGET_DUALSPEED
+#ifndef CONFIG_G_DNL_VENDOR_NUM
 #define CONFIG_G_DNL_VENDOR_NUM 0x0955
+#endif
+#ifndef CONFIG_G_DNL_PRODUCT_NUM
 #define CONFIG_G_DNL_PRODUCT_NUM 0x701A
+#endif
+#ifndef CONFIG_G_DNL_MANUFACTURER
 #define CONFIG_G_DNL_MANUFACTURER "NVIDIA"
+#endif
 #define CONFIG_USBDOWNLOAD_GADGET
 /* USB mass storage protocol */
 #define CONFIG_USB_GADGET_MASS_STORAGE
Signature · 1 line
2.4.3
#2 lore raw

PATCH v2 2/16 ARM: tegra: allow reading recovery mode boot type

In reply to Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Add defines to allow reading recovery mode (RCM) boot type from the boot information table (BIT) written by the boot ROM (BR) to the IRAM.

---
Changes in v2: Reword commit mesage as per Simon's suggestion.

 arch/arm/include/asm/arch-tegra/tegra.h | 2 ++
 1 file changed, 2 insertions(+)
arch/arm/include/asm/arch-tegra/tegra.h +2 -0
index d63af0e..9ff0831 100644
@@ -56,6 +56,8 @@ struct timerus {
 /* Address at which WB code runs, it must not overlap Bootrom's IRAM usage */
 #define NV_WB_RUN_ADDRESS	0x40020000
 
+#define NVBOOTTYPE_RECOVERY	2	/* BR entered RCM */
+#define NVBOOTINFOTABLE_BOOTTYPE 0xC	/* Boot type in BIT in IRAM */
 #define NVBOOTINFOTABLE_BCTSIZE	0x38	/* BCT size in BIT in IRAM */
 #define NVBOOTINFOTABLE_BCTPTR	0x3C	/* BCT pointer in BIT in IRAM */
 
Signature · 1 line
2.4.3
#3 lore raw

PATCH v2 3/16 apalis/colibri_t20/t30: integrate recovery mode detection

In reply to Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Allow detecting whether or not U-Boot was launched through the recovery mode of the resp. NVIDIA SoC.

Make use of a board specific arch_misc_init() and enable the same via CONFIG_ARCH_MISC_INIT configuration option.

---
Changes in v2:
Drop unrelated clean-up to be done as part of a separate patch.

 board/toradex/apalis_t30/apalis_t30.c   | 12 ++++++++++++
 board/toradex/colibri_t20/colibri_t20.c | 12 ++++++++++++
 board/toradex/colibri_t30/colibri_t30.c | 12 ++++++++++++
 include/configs/apalis_t30.h            |  2 ++
 include/configs/colibri_t20.h           |  2 ++
 include/configs/colibri_t30.h           |  2 ++
 6 files changed, 42 insertions(+)
board/toradex/apalis_t30/apalis_t30.c +12 -0
index 6244214..b7a2219 100644
@@ -9,7 +9,10 @@
 #include <dm.h>
 #include <asm/arch/gp_padctrl.h>
 #include <asm/arch/pinmux.h>
+#include <asm/arch-tegra/ap.h>
+#include <asm/arch-tegra/tegra.h>
 #include <asm/gpio.h>
+#include <asm/io.h>
 #include <i2c.h>
 #include <netdev.h>
 
@@ -18,6 +21,15 @@
 #define PMU_I2C_ADDRESS		0x2D
 #define MAX_I2C_RETRY		3
 
+int arch_misc_init(void)
+{
+	if (readl(NV_PA_BASE_SRAM + NVBOOTINFOTABLE_BOOTTYPE) ==
+	    NVBOOTTYPE_RECOVERY)
+		printf("USB recovery mode\n");
+
+	return 0;
+}
+
 /*
  * Routine: pinmux_init
  * Description: Do individual peripheral pinmux configs
board/toradex/colibri_t20/colibri_t20.c +12 -0
index 8ae9ccf..7210a8a 100644
@@ -8,8 +8,20 @@
 #include <asm/arch/clock.h>
 #include <asm/arch/funcmux.h>
 #include <asm/arch/pinmux.h>
+#include <asm/arch-tegra/ap.h>
 #include <asm/arch-tegra/board.h>
+#include <asm/arch-tegra/tegra.h>
 #include <asm/gpio.h>
+#include <asm/io.h>
+
+int arch_misc_init(void)
+{
+	if (readl(NV_PA_BASE_SRAM + NVBOOTINFOTABLE_BOOTTYPE) ==
+	    NVBOOTTYPE_RECOVERY)
+		printf("USB recovery mode\n");
+
+	return 0;
+}
 
 #ifdef CONFIG_TEGRA_MMC
 /*
board/toradex/colibri_t30/colibri_t30.c +12 -0
index f4bc7d8..7ca79eb 100644
@@ -8,10 +8,22 @@
 #include <common.h>
 #include <asm/arch/pinmux.h>
 #include <asm/arch/gp_padctrl.h>
+#include <asm/arch-tegra/ap.h>
+#include <asm/arch-tegra/tegra.h>
+#include <asm/io.h>
 #include "pinmux-config-colibri_t30.h"
 #include <i2c.h>
 #include <asm/gpio.h>
 
+int arch_misc_init(void)
+{
+	if (readl(NV_PA_BASE_SRAM + NVBOOTINFOTABLE_BOOTTYPE) ==
+	    NVBOOTTYPE_RECOVERY)
+		printf("USB recovery mode\n");
+
+	return 0;
+}
+
 /*
  * Routine: pinmux_init
  * Description: Do individual peripheral pinmux configs
include/configs/apalis_t30.h +2 -0
index aba9ba6..283b002 100644
@@ -11,6 +11,8 @@
 
 #include "tegra30-common.h"
 
+#define CONFIG_ARCH_MISC_INIT
+
 /* High-level configuration options */
 #define V_PROMPT			"Apalis T30 # "
 #define CONFIG_TEGRA_BOARD_STRING	"Toradex Apalis T30"
include/configs/colibri_t20.h +2 -0
index 8228e42..d80d352 100644
@@ -9,6 +9,8 @@
 
 #include "tegra20-common.h"
 
+#define CONFIG_ARCH_MISC_INIT
+
 /* High-level configuration options */
 #define V_PROMPT			"Colibri T20 # "
 #define CONFIG_TEGRA_BOARD_STRING	"Toradex Colibri T20"
include/configs/colibri_t30.h +2 -0
index 4655668..249b5c0 100644
@@ -11,6 +11,8 @@
 
 #include "tegra30-common.h"
 
+#define CONFIG_ARCH_MISC_INIT
+
 /* High-level configuration options */
 #define V_PROMPT			"Colibri T30 # "
 #define CONFIG_TEGRA_BOARD_STRING	"Toradex Colibri T30"
Signature · 1 line
2.4.3
#4 lore raw

PATCH v2 4/16 colibri_t20: fix device-tree compatible node

In reply to Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Use toradex,colibri_t20 as the device-tree compatible node value rather than toradex,t20 in accordance to our Apalis/Colibri T30 products.

---
 arch/arm/dts/tegra20-colibri.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/dts/tegra20-colibri.dts +1 -1
index 3131b92..257ca27 100644
@@ -4,7 +4,7 @@
 
 / {
 	model = "Toradex Colibri T20";
-	compatible = "toradex,t20", "nvidia,tegra20";
+	compatible = "toradex,colibri_t20", "nvidia,tegra20";
 
 	chosen {
 		stdout-path = &uarta;
Signature · 1 line
2.4.3
#5 lore raw

PATCH v2 5/16 colibri_t20: add lcd display support

In reply to Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Add LCD display support defaulting to VESA VGA resolution. Different resolutions configurable via device tree.

---
Changes in v2: fixed PWM instance

 arch/arm/dts/tegra20-colibri.dts        | 29 +++++++++++++++++++++++++++++
 board/toradex/colibri_t20/colibri_t20.c | 18 ++++++++++++++++++
 include/configs/colibri_t20.h           | 10 ++++++++++
 3 files changed, 57 insertions(+)
arch/arm/dts/tegra20-colibri.dts +29 -0
index 257ca27..bf14c6b 100644
@@ -17,6 +17,17 @@
 		sdhci0 = "/sdhci at c8000600";
 	};
 
+	host1x {
+		status = "okay";
+		dc at 54200000 {
+			status = "okay";
+			rgb {
+				status = "okay";
+				nvidia,panel = <&lcd_panel>;
+			};
+		};
+	};
+
 	usb at c5000000 {
 		dr_mode = "otg";
 	};
@@ -46,4 +57,22 @@
 		cd-gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_LOW>;
 		bus-width = <4>;
 	};
+
+	lcd_panel: panel {
+		clock = <25175000>;
+		xres = <640>;
+		yres = <480>;
+		left-margin = <48>;	/* horizontal back porch */
+		right-margin = <16>;	/* horizontal front porch */
+		hsync-len = <96>;
+		lower-margin = <11>;	/* vertical front porch */
+		upper-margin = <31>;	/* vertical back porch */
+		vsync-len = <2>;
+		hsync-active-high;
+		vsync-active-high;
+		nvidia,bits-per-pixel = <16>;
+		nvidia,pwm = <&pwm 0 0>;
+		nvidia,backlight-enable-gpios = <&gpio TEGRA_GPIO(T, 4) GPIO_ACTIVE_HIGH>;
+		nvidia,panel-timings = <0 0 0 0>;
+	};
 };
board/toradex/colibri_t20/colibri_t20.c +18 -0
index 7210a8a..81d344c 100644
@@ -75,3 +75,21 @@ void pin_mux_usb(void)
 	pinmux_tristate_disable(PMUX_PINGRP_SPIG);
 }
 #endif
+
+#ifdef CONFIG_VIDEO_TEGRA
+/*
+ * Routine: pin_mux_display
+ * Description: setup the pin muxes/tristate values for the LCD interface)
+ */
+void pin_mux_display(void)
+{
+	/*
+	 * Manually untristate BL_ON (PT4 - SODIMM 71) as specified through
+	 * device-tree
+	 */
+	pinmux_tristate_disable(PMUX_PINGRP_DTA);
+
+	pinmux_set_func(PMUX_PINGRP_SDC, PMUX_FUNC_PWM);
+	pinmux_tristate_disable(PMUX_PINGRP_SDC);
+}
+#endif
include/configs/colibri_t20.h +10 -0
index d80d352..82a887b 100644
@@ -45,6 +45,16 @@
 /* General networking support */
 #define CONFIG_CMD_DHCP
 
+/* LCD support */
+#define CONFIG_LCD
+#define CONFIG_PWM_TEGRA
+#define CONFIG_VIDEO_TEGRA
+#define LCD_BPP				LCD_COLOR16
+#define CONFIG_SYS_WHITE_ON_BLACK
+#define CONFIG_CONSOLE_SCROLL_LINES	10
+#define CONFIG_CMD_BMP
+#define CONFIG_LCD_LOGO
+
 /* NAND support */
 #define CONFIG_CMD_NAND
 #define CONFIG_TEGRA_NAND
Signature · 1 line
2.4.3
#6 lore raw

PATCH v2 6/16 colibri_t20: add i2c support

In reply to Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Add I2C support in order to subsequently allow disabling the PMIC sleep mode on low supply voltage.

---
 arch/arm/dts/tegra20-colibri.dts | 28 ++++++++++++++++++++++++++++
 include/configs/colibri_t20.h    |  4 ++++
 2 files changed, 32 insertions(+)
arch/arm/dts/tegra20-colibri.dts +28 -0
index bf14c6b..8eaac4f 100644
@@ -11,6 +11,9 @@
 	};
 
 	aliases {
+		i2c0 = "/i2c at 7000d000";
+		i2c1 = "/i2c at 7000c000";
+		i2c2 = "/i2c at 7000c400";
 		usb0 = "/usb at c5008000";
 		usb1 = "/usb at c5000000";
 		usb2 = "/usb at c5004000";
@@ -52,6 +55,31 @@
 		};
 	};
 
+	/*
+	 * GEN1_I2C: I2C_SDA/SCL on SODIMM pin 194/196 (e.g. RTC on carrier
+	 * board)
+	 */
+	i2c at 7000c000 {
+		status = "okay";
+		clock-frequency = <100000>;
+	};
+
+	/* GEN2_I2C: unused */
+
+	/* DDC_CLOCK/DATA on X3 pin 15/16 (e.g. display EDID) */
+	i2c at 7000c400 {
+		status = "okay";
+		clock-frequency = <100000>;
+	};
+
+	/*
+	 * PWR_I2C: power I2C to PMIC and temperature sensor
+	 */
+	i2c at 7000d000 {
+		status = "okay";
+		clock-frequency = <100000>;
+	};
+
 	sdhci at c8000600 {
 		status = "okay";
 		cd-gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_LOW>;
include/configs/colibri_t20.h +4 -0
index 82a887b..24880c3 100644
@@ -23,6 +23,10 @@
 
 #define CONFIG_MACH_TYPE		MACH_TYPE_COLIBRI_T20
 
+/* I2C */
+#define CONFIG_SYS_I2C_TEGRA
+#define CONFIG_CMD_I2C
+
 /* SD/MMC support */
 #define CONFIG_MMC
 #define CONFIG_GENERIC_MMC
Signature · 1 line
2.4.3
#7 lore raw

PATCH v2 7/16 colibri_t20: disable PMIC sleep mode on low supply voltage

In reply to Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

The Colibri T20's PMIC enters a sleep mode on low supply voltage < 3.0V ?2.5% (2.92...3.08V). Rising the main supply voltage again does not bring it back to regular operation. Not even a full reset does bring the module back. A full power cycle was required to reboot the system. A long positive pulse on the PMICs resume pin also reboots the system but this pin is only accessible as a test point on the module.

This patch configures the PMIC through I2C to not enter this sleep mode plus force it to normal state upon sleep request exit should this ever happen.

---
 board/toradex/colibri_t20/colibri_t20.c | 35 +++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)
board/toradex/colibri_t20/colibri_t20.c +35 -0
index 81d344c..42b293d 100644
@@ -13,9 +13,44 @@
 #include <asm/arch-tegra/tegra.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
+#include <i2c.h>
+
+#define PMU_I2C_ADDRESS		0x34
+#define MAX_I2C_RETRY		3
+#define PMU_SUPPLYENE		0x14
+#define PMU_SUPPLYENE_SYSINEN	(1<<5)
+#define PMU_SUPPLYENE_EXITSLREQ	(1<<1)
 
 int arch_misc_init(void)
 {
+	/* Disable PMIC sleep mode on low supply voltage */
+	struct udevice *dev;
+	u8 addr, data[1];
+	int err;
+
+	err = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, 1, &dev);
+	if (err) {
+		debug("%s: Cannot find PMIC I2C chip\n", __func__);
+		return err;
+	}
+
+	addr = PMU_SUPPLYENE;
+
+	err = dm_i2c_read(dev, addr, data, 1);
+	if (err) {
+		debug("failed to get PMU_SUPPLYENE\n");
+		return err;
+	}
+
+	data[0] &= ~PMU_SUPPLYENE_SYSINEN;
+	data[0] |= PMU_SUPPLYENE_EXITSLREQ;
+
+	err = dm_i2c_write(dev, addr, data, 1);
+	if (err) {
+		debug("failed to set PMU_SUPPLYENE\n");
+		return err;
+	}
+
 	if (readl(NV_PA_BASE_SRAM + NVBOOTINFOTABLE_BOOTTYPE) ==
 	    NVBOOTTYPE_RECOVERY)
 		printf("USB recovery mode\n");
Signature · 1 line
2.4.3
#8 lore raw

PATCH v2 8/16 tegra: nand: fix read_byte required for proper onfi detection

In reply to Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Fix PIO read_byte() implementation not only used for the legacy READ ID but also the PARAM command now required for proper ONFI detection.

This fix is inspired by Lucas Stach's Linux Tegra NAND driver of late.

While at it also disable subpage writes.

---
 drivers/mtd/nand/tegra_nand.c | 39 +++++++++------------------------------
 1 file changed, 9 insertions(+), 30 deletions(-)
drivers/mtd/nand/tegra_nand.c +10 -31
index b660f3b..9c90634 100644
@@ -86,16 +86,6 @@ struct fdt_nand {
 
 struct nand_drv {
 	struct nand_ctlr *reg;
-
-	/*
-	* When running in PIO mode to get READ ID bytes from register
-	* RESP_0, we need this variable as an index to know which byte in
-	* register RESP_0 should be read.
-	* Because common code in nand_base.c invokes read_byte function two
-	* times for NAND_CMD_READID.
-	* And our controller returns 4 bytes at once in register RESP_0.
-	*/
-	int pio_byte_index;
 	struct fdt_nand config;
 };
 
@@ -181,25 +171,16 @@ static int nand_waitfor_cmd_completion(struct nand_ctlr *reg)
 static uint8_t read_byte(struct mtd_info *mtd)
 {
 	struct nand_chip *chip = mtd->priv;
-	u32 dword_read;
 	struct nand_drv *info;
 
 	info = (struct nand_drv *)chip->priv;
 
-	/* In PIO mode, only 4 bytes can be transferred with single CMD_GO. */
-	if (info->pio_byte_index > 3) {
-		info->pio_byte_index = 0;
-		writel(CMD_GO | CMD_PIO
-			| CMD_RX | CMD_CE0,
-			&info->reg->command);
-		if (!nand_waitfor_cmd_completion(info->reg))
-			printf("Command timeout\n");
-	}
+	writel(CMD_GO | CMD_PIO | CMD_RX | CMD_CE0 | CMD_A_VALID,
+	       &info->reg->command);
+	if (!nand_waitfor_cmd_completion(info->reg))
+		printf("Command timeout\n");
 
-	dword_read = readl(&info->reg->resp);
-	dword_read = dword_read >> (8 * info->pio_byte_index);
-	info->pio_byte_index++;
-	return (uint8_t)dword_read;
+	return (uint8_t)readl(&info->reg->resp);
 }
 
 /**
@@ -314,6 +295,9 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
 	if (column != -1 && (chip->options & NAND_BUSWIDTH_16))
 		column >>= 1;
 
+	/* Disable subpage writes as we do not provide ecc->hwctl */
+	chip->options |= NAND_NO_SUBPAGE_WRITE;
+
 	nand_clear_interrupt_status(info->reg);
 
 	/* Stop DMA engine, clear DMA completion status */
@@ -330,12 +314,8 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
 	case NAND_CMD_READID:
 		writel(NAND_CMD_READID, &info->reg->cmd_reg1);
 		writel(column & 0xFF, &info->reg->addr_reg1);
-		writel(CMD_GO | CMD_CLE | CMD_ALE | CMD_PIO
-			| CMD_RX |
-			((4 - 1) << CMD_TRANS_SIZE_SHIFT)
-			| CMD_CE0,
-			&info->reg->command);
+		writel(CMD_GO | CMD_CLE | CMD_ALE | CMD_CE0,
+		       &info->reg->command);
-		info->pio_byte_index = 0;
 		break;
 	case NAND_CMD_PARAM:
 		writel(NAND_CMD_PARAM, &info->reg->cmd_reg1);
@@ -376,7 +356,6 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
 			| ((1 - 0) << CMD_TRANS_SIZE_SHIFT)
 			| CMD_CE0,
 			&info->reg->command);
-		info->pio_byte_index = 0;
 		break;
 	case NAND_CMD_RESET:
 		writel(NAND_CMD_RESET, &info->reg->cmd_reg1);
Signature · 1 line
2.4.3
#9 lore raw

PATCH v2 8/16 tegra: nand: fix read_byte required for proper onfi detection

Quoted 6 lines · Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Fix PIO read_byte() implementation not only used for the legacy READ ID but also the PARAM command now required for proper ONFI detection.

This fix is inspired by Lucas Stach's Linux Tegra NAND driver of late.

Could you explain a bit more how this fixes issues with READ PARAM?

Quoted 1 line

While at it also disable subpage writes.

Why are these two changes combined?

-Scott

#10 lore raw

PATCH v2 8/16 tegra: nand: fix read_byte required for proper onfi detection

Quoted 11 lines · Scott Wood
Quoted 3 lines · Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Fix PIO read_byte() implementation not only used for the legacy READ

ID

Quoted 3 lines

but also the PARAM command now required for proper ONFI detection.

This fix is inspired by Lucas Stach's Linux Tegra NAND driver of

late.

Could you explain a bit more how this fixes issues with READ PARAM?

I vaguely remember that those commands are special on 16-bit bus NAND (e.g. always return 8-bit data regardless) and later Linux MTD fixed/changed the way this is handled which in turn broke once U-Boot pulled that in. Which as explained in my commit message this fixes by doing what Lucas does in Linux (not mainline yet but getting there soon I hope).

Quoted 3 lines
Quoted 1 line

While at it also disable subpage writes.

Why are these two changes combined?

Well just because it's a one line fix but if required I can split that in a separate patch as well.

#11 lore raw

PATCH v2 8/16 tegra: nand: fix read_byte required for proper onfi detection

Quoted 11 lines · Marcel Ziswiler
Quoted 10 lines · Scott Wood
Quoted 3 lines · Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Fix PIO read_byte() implementation not only used for the legacy READ

ID

Quoted 3 lines

but also the PARAM command now required for proper ONFI detection.

This fix is inspired by Lucas Stach's Linux Tegra NAND driver of

late.

Quoted 7 lines
Quoted 1 line

Could you explain a bit more how this fixes issues with READ PARAM?

I vaguely remember that those commands are special on 16-bit bus NAND (e.g. always return 8-bit data regardless) and later Linux MTD fixed/changed the way this is handled which in turn broke once U-Boot pulled that in. Which as explained in my commit message this fixes by doing what Lucas does in Linux (not mainline yet but getting there soon I hope).

The more detail about this you can put in the changelog (describing what it is that Lucas does and how it helps), the better.

Quoted 6 lines
Quoted 3 lines
Quoted 1 line

While at it also disable subpage writes.

Why are these two changes combined?

Well just because it's a one line fix but if required I can split that in a separate patch as well.

I think it should be separate, at least so it gets a separate changelog explaining why.

-Scott

#12 lore raw

PATCH v2 9/16 mtd/nand/tegra: alignment workaround

In reply to Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Integrate cache alignment bounce buffer to workaround issues as follows:

Loading file '/boot/zImage' to addr 0x01000000 with size 4499152 (0x0044a6d0)...
ERROR: v7_dcache_inval_range - start address is not aligned - 0x1f7f0108
ERROR: v7_dcache_inval_range - stop address is not aligned - 0x1f7f1108 Done
Kernel image @ 0x1000000 [ 0x000000 - 0x44a6d0 ]

Starting kernel ...

undefined instruction

pc : [<005ff03c>]          lr : [<0000800c>]

sp : 0144b6e8 ip : 01000188 fp : 0144a6c8
r10: 00000000 r9 : 411fc090 r8 : 00000100
r7 : 00000cfb r6 : 0144a6d0 r5 : 00000000 r4 : 00008000
r3 : 0000000c r2 : 00000100 r1 : 00000cfb r0 : 00000000
Flags: nZCv IRQs off FIQs off Mode SVC_32
Resetting CPU ...

---
Changes in v2:
Migrated to using generic bounce buffer implementation as suggested by Simon.

 drivers/mtd/nand/tegra_nand.c | 83 +++++++++++++++++--------------------------
 1 file changed, 32 insertions(+), 51 deletions(-)
drivers/mtd/nand/tegra_nand.c +36 -51
index 9f90683..02d8aed 100644
@@ -16,6 +16,7 @@
 #include <asm/errno.h>
 #include <asm/gpio.h>
 #include <fdtdec.h>
+#include <bouncebuf.h>
 #include "tegra_nand.h"
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -93,35 +94,6 @@ static struct nand_drv nand_ctrl;
 static struct mtd_info *our_mtd;
 static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE];
 
-#ifdef CONFIG_SYS_DCACHE_OFF
-static inline void dma_prepare(void *start, unsigned long length,
-			       int is_writing)
-{
-}
-#else
-/**
- * Prepare for a DMA transaction
- *
- * For a write we flush out our data. For a read we invalidate, since we
- * need to do this before we read from the buffer after the DMA has
- * completed, so may as well do it now.
- *
- * @param start		Start address for DMA buffer (should be cache-aligned)
- * @param length	Length of DMA buffer in bytes
- * @param is_writing	0 if reading, non-zero if writing
- */
-static void dma_prepare(void *start, unsigned long length, int is_writing)
-{
-	unsigned long addr = (unsigned long)start;
-
-	length = ALIGN(length, ARCH_DMA_MINALIGN);
-	if (is_writing)
-		flush_dcache_range(addr, addr + length);
-	else
-		invalidate_dcache_range(addr, addr + length);
-}
-#endif
-
 /**
  * Wait for command completion
  *
@@ -534,6 +506,8 @@ static int nand_rw_page(struct mtd_info *mtd, struct nand_chip *chip,
 	char *tag_ptr;
 	struct nand_drv *info;
 	struct fdt_nand *config;
+	unsigned int bbflags;
+	struct bounce_buffer bbstate, bbstate_oob;
 
 	if ((uintptr_t)buf & 0x03) {
 		printf("buf %p has to be 4-byte aligned\n", buf);
@@ -550,21 +524,21 @@ static int nand_rw_page(struct mtd_info *mtd, struct nand_chip *chip,
 
 	stop_command(info->reg);
 
+	if (is_writing)
+		bbflags = GEN_BB_READ;
+	else
+		bbflags = GEN_BB_WRITE;
+
+	bounce_buffer_start(&bbstate, (void *)buf, 1 << chip->page_shift,
+			    bbflags);
 	writel((1 << chip->page_shift) - 1, &info->reg->dma_cfg_a);
-	writel(virt_to_phys(buf), &info->reg->data_block_ptr);
+	writel((u32)bbstate.bounce_buffer, &info->reg->data_block_ptr);
 
+	/* Set ECC selection, configure ECC settings */
 	if (with_ecc) {
-		writel(virt_to_phys(tag_ptr), &info->reg->tag_ptr);
 		if (is_writing)
 			memcpy(tag_ptr, chip->oob_poi + free->offset,
-				chip->ecc.layout->oobavail +
-				TAG_ECC_BYTES);
-	} else {
-		writel(virt_to_phys(chip->oob_poi), &info->reg->tag_ptr);
-	}
-
-	/* Set ECC selection, configure ECC settings */
-	if (with_ecc) {
+			       chip->ecc.layout->oobavail + TAG_ECC_BYTES);
 		tag_size = chip->ecc.layout->oobavail + TAG_ECC_BYTES;
 		reg_val |= (CFG_SKIP_SPARE_SEL_4
 			| CFG_SKIP_SPARE_ENABLE
@@ -577,7 +551,8 @@ static int nand_rw_page(struct mtd_info *mtd, struct nand_chip *chip,
 
 		if (!is_writing)
 			tag_size += SKIPPED_SPARE_BYTES;
-		dma_prepare(tag_ptr, tag_size, is_writing);
+		bounce_buffer_start(&bbstate_oob, (void *)tag_ptr, tag_size,
+				    bbflags);
 	} else {
 		tag_size = mtd->oobsize;
 		reg_val |= (CFG_SKIP_SPARE_DISABLE
@@ -585,14 +560,12 @@ static int nand_rw_page(struct mtd_info *mtd, struct nand_chip *chip,
 			| CFG_ECC_EN_TAG_DISABLE
 			| CFG_HW_ECC_DISABLE
 			| (tag_size - 1));
-		dma_prepare(chip->oob_poi, tag_size, is_writing);
+		bounce_buffer_start(&bbstate_oob, (void *)chip->oob_poi,
+				    tag_size, bbflags);
 	}
 	writel(reg_val, &info->reg->config);
-
-	dma_prepare(buf, 1 << chip->page_shift, is_writing);
-
+	writel((u32)bbstate_oob.bounce_buffer, &info->reg->tag_ptr);
 	writel(BCH_CONFIG_BCH_ECC_DISABLE, &info->reg->bch_config);
-
 	writel(tag_size - 1, &info->reg->dma_cfg_b);
 
 	nand_clear_interrupt_status(info->reg);
@@ -638,6 +611,9 @@ static int nand_rw_page(struct mtd_info *mtd, struct nand_chip *chip,
 		return -EIO;
 	}
 
+	bounce_buffer_stop(&bbstate_oob);
+	bounce_buffer_stop(&bbstate);
+
 	if (with_ecc && !is_writing) {
 		memcpy(chip->oob_poi, tag_ptr,
 			SKIPPED_SPARE_BYTES);
@@ -755,6 +731,8 @@ static int nand_rw_oob(struct mtd_info *mtd, struct nand_chip *chip,
 	int tag_size;
 	struct nand_oobfree *free = chip->ecc.layout->oobfree;
 	struct nand_drv *info;
+	unsigned int bbflags;
+	struct bounce_buffer bbstate_oob;
 
 	if (((int)chip->oob_poi) & 0x03)
 		return -EINVAL;
@@ -764,8 +742,6 @@ static int nand_rw_oob(struct mtd_info *mtd, struct nand_chip *chip,
 
 	stop_command(info->reg);
 
-	writel(virt_to_phys(chip->oob_poi), &info->reg->tag_ptr);
-
 	/* Set ECC selection */
 	tag_size = mtd->oobsize;
 	if (with_ecc)
@@ -779,13 +755,20 @@ static int nand_rw_oob(struct mtd_info *mtd, struct nand_chip *chip,
 		CFG_HW_ECC_DISABLE);
 	writel(reg_val, &info->reg->config);
 
-	dma_prepare(chip->oob_poi, tag_size, is_writing);
-
-	writel(BCH_CONFIG_BCH_ECC_DISABLE, &info->reg->bch_config);
-
 	if (is_writing && with_ecc)
 		tag_size -= TAG_ECC_BYTES;
 
+	if (is_writing)
+		bbflags = GEN_BB_READ;
+	else
+		bbflags = GEN_BB_WRITE;
+
+	bounce_buffer_start(&bbstate_oob, (void *)chip->oob_poi, tag_size,
+			    bbflags);
+	writel((u32)bbstate_oob.bounce_buffer, &info->reg->tag_ptr);
+
+	writel(BCH_CONFIG_BCH_ECC_DISABLE, &info->reg->bch_config);
+
 	writel(tag_size - 1, &info->reg->dma_cfg_b);
 
 	nand_clear_interrupt_status(info->reg);
@@ -822,6 +805,8 @@ static int nand_rw_oob(struct mtd_info *mtd, struct nand_chip *chip,
 		return -EIO;
 	}
 
+	bounce_buffer_stop(&bbstate_oob);
+
 	if (with_ecc && !is_writing) {
 		reg_val = (u32)check_ecc_error(info->reg, 0, 0,
 			(u8 *)(chip->oob_poi + free->offset),
Signature · 1 line
2.4.3
#13 lore raw

PATCH v2 9/16 mtd/nand/tegra: alignment workaround

Quoted 22 lines · Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Integrate cache alignment bounce buffer to workaround issues as follows:

Loading file '/boot/zImage' to addr 0x01000000 with size 4499152 (0x0044a6d0)...
ERROR: v7_dcache_inval_range - start address is not aligned - 0x1f7f0108
ERROR: v7_dcache_inval_range - stop address is not aligned - 0x1f7f1108 Done
Kernel image @ 0x1000000 [ 0x000000 - 0x44a6d0 ]

Starting kernel ...

undefined instruction

pc : [<005ff03c>]          lr : [<0000800c>]

sp : 0144b6e8 ip : 01000188 fp : 0144a6c8
r10: 00000000 r9 : 411fc090 r8 : 00000100
r7 : 00000cfb r6 : 0144a6d0 r5 : 00000000 r4 : 00008000
r3 : 0000000c r2 : 00000100 r1 : 00000cfb r0 : 00000000
Flags: nZCv IRQs off FIQs off Mode SVC_32
Resetting CPU ...

Quoted 5 lines

---
Changes in v2:
Migrated to using generic bounce buffer implementation as suggested by Simon.

I didn't see Simon's suggestion, but what is the general policy in U-Boot supposed to be for I/O alignment? Responsibility of the API user, or of the driver? Are there other drivers with the same problem?

drivers/mtd/nand/tegra_nand.c static int nand_rw_page(struct mtd_info *mtd, struct nand_chip *chip, · line 535

Quoted 2 lines
drivers/mtd/nand/tegra_nand.c +1 -1
-     writel(virt_to_phys(buf), &info->reg->data_block_ptr);
+     writel((u32)bbstate.bounce_buffer, &info->reg->data_block_ptr);

Why are you converting usage of virt_to_phys() into a u32 cast?

-Scott

#14 lore raw

PATCH v2 9/16 mtd/nand/tegra: alignment workaround

Hi Scott,

Quoted 29 lines · Scott Wood
Quoted 22 lines · Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Integrate cache alignment bounce buffer to workaround issues as follows:

Loading file '/boot/zImage' to addr 0x01000000 with size 4499152 (0x0044a6d0)...
ERROR: v7_dcache_inval_range - start address is not aligned - 0x1f7f0108
ERROR: v7_dcache_inval_range - stop address is not aligned - 0x1f7f1108 Done
Kernel image @ 0x1000000 [ 0x000000 - 0x44a6d0 ]

Starting kernel ...

undefined instruction

pc : [<005ff03c>]          lr : [<0000800c>]

sp : 0144b6e8 ip : 01000188 fp : 0144a6c8
r10: 00000000 r9 : 411fc090 r8 : 00000100
r7 : 00000cfb r6 : 0144a6d0 r5 : 00000000 r4 : 00008000
r3 : 0000000c r2 : 00000100 r1 : 00000cfb r0 : 00000000
Flags: nZCv IRQs off FIQs off Mode SVC_32
Resetting CPU ...

Quoted 5 lines

---
Changes in v2:
Migrated to using generic bounce buffer implementation as suggested by Simon.

Quoted 3 lines

I didn't see Simon's suggestion, but what is the general policy in U-Boot supposed to be for I/O alignment? Responsibility of the API user, or of the driver? Are there other drivers with the same problem?

MMC has it. I feel that in general we should be able to ask the higher-level systems to do the right thing and align their data. Otherwise it introduces inefficiencies into the stack. But at least if we do introduce this, we should use common infrastructure, hence my request.

Quoted 8 lines

drivers/mtd/nand/tegra_nand.c static int nand_rw_page(struct mtd_info *mtd, struct nand_chip *chip, · line 535

Quoted 3 lines
drivers/mtd/nand/tegra_nand.c +1 -1
-     writel(virt_to_phys(buf), &info->reg->data_block_ptr);
+     writel((u32)bbstate.bounce_buffer, &info->reg->data_block_ptr);

Why are you converting usage of virt_to_phys() into a u32 cast?

-Scott

Regards,
Simon

#15 lore raw

PATCH v2 9/16 mtd/nand/tegra: alignment workaround

Quoted 37 lines · Simon Glass

Hi Scott,

Quoted 29 lines · Scott Wood
Quoted 22 lines · Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Integrate cache alignment bounce buffer to workaround issues as follows:

Loading file '/boot/zImage' to addr 0x01000000 with size 4499152 (0x0044a6d0)...
ERROR: v7_dcache_inval_range - start address is not aligned - 0x1f7f0108
ERROR: v7_dcache_inval_range - stop address is not aligned - 0x1f7f1108 Done
Kernel image @ 0x1000000 [ 0x000000 - 0x44a6d0 ]

Starting kernel ...

undefined instruction

pc : [<005ff03c>]          lr : [<0000800c>]

sp : 0144b6e8 ip : 01000188 fp : 0144a6c8
r10: 00000000 r9 : 411fc090 r8 : 00000100
r7 : 00000cfb r6 : 0144a6d0 r5 : 00000000 r4 : 00008000
r3 : 0000000c r2 : 00000100 r1 : 00000cfb r0 : 00000000
Flags: nZCv IRQs off FIQs off Mode SVC_32
Resetting CPU ...

Quoted 5 lines

---
Changes in v2:
Migrated to using generic bounce buffer implementation as suggested by Simon.

Quoted 4 lines

I didn't see Simon's suggestion, but what is the general policy in U-Boot supposed to be for I/O alignment? Responsibility of the API user, or of the
driver? Are there other drivers with the same problem?

Quoted 5 lines

MMC has it. I feel that in general we should be able to ask the higher-level systems to do the right thing and align their data. Otherwise it introduces inefficiencies into the stack. But at least if we do introduce this, we should use common infrastructure, hence my request.

OK, so your request wasn't to move this into the driver, just about how to implement it if it's done in the driver? Marcel, why did you change to handling this in the driver?

-Scott

#16 lore raw

PATCH v2 9/16 mtd/nand/tegra: alignment workaround

Quoted 48 lines · Scott Wood
Quoted 7 lines · Simon Glass

Hi Scott,

Quoted 4 lines · Scott Wood
Quoted 3 lines · Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Integrate cache alignment bounce buffer to workaround issues as

follows:

Quoted 4 lines
Quoted 4 lines
Quoted 4 lines

Loading file '/boot/zImage' to addr 0x01000000 with size 4499152 (0x0044a6d0)...
ERROR: v7_dcache_inval_range - start address is not aligned -

0x1f7f0108

Quoted 1 line
Quoted 1 line
Quoted 1 line

ERROR: v7_dcache_inval_range - stop address is not aligned -

0x1f7f1108

Quoted 14 lines
Quoted 14 lines
Quoted 14 lines

Done
Kernel image @ 0x1000000 [ 0x000000 - 0x44a6d0 ]

Starting kernel ...

undefined instruction

pc : [<005ff03c>]          lr : [<0000800c>]

sp : 0144b6e8 ip : 01000188 fp : 0144a6c8
r10: 00000000 r9 : 411fc090 r8 : 00000100
r7 : 00000cfb r6 : 0144a6d0 r5 : 00000000 r4 : 00008000
r3 : 0000000c r2 : 00000100 r1 : 00000cfb r0 : 00000000
Flags: nZCv IRQs off FIQs off Mode SVC_32
Resetting CPU ...

Quoted 4 lines
Quoted 4 lines
Quoted 4 lines

---
Changes in v2:
Migrated to using generic bounce buffer implementation as

suggested by

Quoted 3 lines
Quoted 3 lines
Quoted 1 line

Simon.

I didn't see Simon's suggestion, but what is the general policy in

U-Boot

Quoted 1 line
Quoted 1 line

supposed to be for I/O alignment? Responsibility of the API user,

or of

Quoted 6 lines
Quoted 2 lines

the
driver? Are there other drivers with the same problem?

MMC has it. I feel that in general we should be able to ask the higher-level systems to do the right thing and align their data. Otherwise it introduces inefficiencies into the stack. But at least

if

Quoted 8 lines
Quoted 2 lines

we do introduce this, we should use common infrastructure, hence my request.

OK, so your request wasn't to move this into the driver, just about how to
implement it if it's done in the driver? Marcel, why did you change to

handling this in the driver?

Maybe because U-Boot is deeply broken in that respect. Please also see my comment in my previous post.

#17 lore raw

PATCH v2 9/16 mtd/nand/tegra: alignment workaround

In reply to Scott Wood
Quoted 30 lines · Scott Wood
Quoted 3 lines · Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Integrate cache alignment bounce buffer to workaround issues as

follows:

Quoted 4 lines

Loading file '/boot/zImage' to addr 0x01000000 with size 4499152 (0x0044a6d0)...
ERROR: v7_dcache_inval_range - start address is not aligned -

0x1f7f0108

Quoted 1 line

ERROR: v7_dcache_inval_range - stop address is not aligned -

0x1f7f1108

Quoted 14 lines

Done
Kernel image @ 0x1000000 [ 0x000000 - 0x44a6d0 ]

Starting kernel ...

undefined instruction

pc : [<005ff03c>]          lr : [<0000800c>]

sp : 0144b6e8 ip : 01000188 fp : 0144a6c8
r10: 00000000 r9 : 411fc090 r8 : 00000100
r7 : 00000cfb r6 : 0144a6d0 r5 : 00000000 r4 : 00008000
r3 : 0000000c r2 : 00000100 r1 : 00000cfb r0 : 00000000
Flags: nZCv IRQs off FIQs off Mode SVC_32
Resetting CPU ...

Quoted 4 lines

---
Changes in v2:
Migrated to using generic bounce buffer implementation as suggested

Quoted 8 lines

by

Quoted 1 line

Simon.

I didn't see Simon's suggestion, but what is the general policy in U-Boot
supposed to be for I/O alignment? Responsibility of the API user, or of the
driver? Are there other drivers with the same problem?

Well, well. You got us into some ruff terrain right there. Remember I have some other alignment patches awaiting acceptance (e.g U-Boot's MTD and most possibly other subsystems are deeply broken in that respect) but even with those I failed booting a kernel loaded from UBIFS so I started having my doubts whether or not this is truly possible without bouncing. At least Tegra's MMC driver just bounces as well.

Quoted 4 lines

drivers/mtd/nand/tegra_nand.c static int nand_rw_page(struct mtd_info *mtd, struct nand_chip *chip, · line 535

Quoted 2 lines
drivers/mtd/nand/tegra_nand.c +1 -1
-     writel(virt_to_phys(buf), &info->reg->data_block_ptr);
+     writel((u32)bbstate.bounce_buffer, &info->reg->data_block_ptr);

Why are you converting usage of virt_to_phys() into a u32 cast?

Good question. I believe this I took straight from the MMC driver but will double check it again for a v3.

#18 lore raw

PATCH v2 9/16 mtd/nand/tegra: alignment workaround

Quoted 40 lines · Marcel Ziswiler
Quoted 30 lines · Scott Wood
Quoted 3 lines · Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Integrate cache alignment bounce buffer to workaround issues as

follows:

Quoted 4 lines

Loading file '/boot/zImage' to addr 0x01000000 with size 4499152 (0x0044a6d0)...
ERROR: v7_dcache_inval_range - start address is not aligned -

0x1f7f0108

Quoted 1 line

ERROR: v7_dcache_inval_range - stop address is not aligned -

0x1f7f1108

Quoted 14 lines

Done
Kernel image @ 0x1000000 [ 0x000000 - 0x44a6d0 ]

Starting kernel ...

undefined instruction

pc : [<005ff03c>]          lr : [<0000800c>]

sp : 0144b6e8 ip : 01000188 fp : 0144a6c8
r10: 00000000 r9 : 411fc090 r8 : 00000100
r7 : 00000cfb r6 : 0144a6d0 r5 : 00000000 r4 : 00008000
r3 : 0000000c r2 : 00000100 r1 : 00000cfb r0 : 00000000
Flags: nZCv IRQs off FIQs off Mode SVC_32
Resetting CPU ...

Quoted 4 lines

---
Changes in v2:
Migrated to using generic bounce buffer implementation as suggested

Quoted 8 lines

by

Quoted 1 line

Simon.

I didn't see Simon's suggestion, but what is the general policy in U-Boot
supposed to be for I/O alignment? Responsibility of the API user, or of the
driver? Are there other drivers with the same problem?

Quoted 6 lines

Well, well. You got us into some ruff terrain right there. Remember I have some other alignment patches awaiting acceptance (e.g U-Boot's MTD and most possibly other subsystems are deeply broken in that respect) but even with those I failed booting a kernel loaded from UBIFS so I started having my doubts whether or not this is truly possible without bouncing. At least Tegra's MMC driver just bounces as well.

OK. With users such as UBI that are shared with kernel code, it might be difficult to enforce a caller-aligns model.

-Scott

#19 lore raw

PATCH v2 9/16 mtd/nand/tegra: alignment workaround

In reply to Marcel Ziswiler
Quoted 11 lines · Marcel Ziswiler
Quoted 5 lines · Scott Wood

Review

Quoted 3 lines
(quoted diff) +1 -2
-     writel(virt_to_phys(buf), &info->reg->data_block_ptr);
+     writel((u32)bbstate.bounce_buffer, &info->reg
->data_block_ptr);

Why are you converting usage of virt_to_phys() into a u32 cast?

Good question. I believe this I took straight from the MMC driver but will double check it again for a v3.

Yes, the MMC driver actually even does a double cast. Don't knowexactly what that should bring but that's how it looks there:
writel((u32)(unsigned long)bbstate->bounce_buffer, &host->reg->sysad);
http://git.denx.de/?p=u-boot.git;a=blob;f=drivers/mmc/tegra_mmc.c;hb=HEAD#l70
Nonetheless I changed it back to using virt_to_phys() for the v3 to beposted soon.

#20 lore raw

PATCH v2 9/16 mtd/nand/tegra: alignment workaround

Quoted 13 lines · Marcel Ziswiler
Quoted 11 lines · Marcel Ziswiler
Quoted 5 lines · Scott Wood

Review

Quoted 3 lines
(quoted diff) +1 -2
-     writel(virt_to_phys(buf), &info->reg->data_block_ptr);
+     writel((u32)bbstate.bounce_buffer, &info->reg
->data_block_ptr);

Why are you converting usage of virt_to_phys() into a u32 cast?

Good question. I believe this I took straight from the MMC driver but will double check it again for a v3.

Quoted 6 lines

Yes, the MMC driver actually even does a double cast. Don't knowexactly what that should bring but that's how it looks there:
writel((u32)(unsigned long)bbstate->bounce_buffer, &host->reg->sysad);
http://git.denx.de/?p=u-boot.git;a=blob;f=drivers/mmc/tegra_mmc.c;hb=HEAD#l70
Nonetheless I changed it back to using virt_to_phys() for the v3 to beposted soon.

The double cast suppresses a warning in 64-bit builds (converting directly from a pointer to an integer of a different size), but ideally virt_to_phys() should be used.

-Scott

#21 lore raw

PATCH v2 10/16 colibri_t20: enable mtdparts support

In reply to Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Enable mtdparts aka dynamic MTD partition support.

---
Changes in v2:
Actually set mtdparts environment variable as part of the board extra ones.

 include/configs/colibri_t20.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
include/configs/colibri_t20.h +14 -0
index 24880c3..a5f0a35 100644
@@ -64,6 +64,17 @@
 #define CONFIG_TEGRA_NAND
 #define CONFIG_SYS_MAX_NAND_DEVICE     1
 
+/* Dynamic MTD partition support */
+#define CONFIG_CMD_MTDPARTS	/* Enable 'mtdparts' command line support */
+#define CONFIG_MTD_PARTITIONS
+#define CONFIG_MTD_DEVICE	/* needed for mtdparts commands */
+#define MTDIDS_DEFAULT		"nand0=tegra_nand"
+#define MTDPARTS_DEFAULT	"mtdparts=tegra_nand:"		\
+				"2m(u-boot)ro,"			\
+				"1m(u-boot-env),"		\
+				"1m(cfgblock)ro,"		\
+				"-(ubi)"
+
 /* Environment in NAND, 64K is a bit excessive but erase block is 512K anyway */
 #define CONFIG_ENV_IS_IN_NAND
 #define CONFIG_ENV_OFFSET              (SZ_2M)
@@ -76,6 +87,9 @@
 /* Miscellaneous commands */
 #define CONFIG_FAT_WRITE
 
+#define BOARD_EXTRA_ENV_SETTINGS \
+	"mtdparts=" MTDPARTS_DEFAULT "\0"
+
 /* Increase console I/O buffer size */
 #undef CONFIG_SYS_CBSIZE
 #define CONFIG_SYS_CBSIZE		1024
Signature · 1 line
2.4.3
#22 lore raw

PATCH v2 11/16 colibri_t20: enable ubi/ubifs support

In reply to Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Now as all is in place actually enable UBI/UBIFS support to be able to boot the Linux kernel and root file system from NAND.

---
 include/configs/colibri_t20.h | 8 ++++++++
 1 file changed, 8 insertions(+)
include/configs/colibri_t20.h +8 -0
index a5f0a35..72a328f 100644
@@ -81,6 +81,14 @@
 #undef  CONFIG_ENV_SIZE /* undef size from tegra20-common.h */
 #define CONFIG_ENV_SIZE                (SZ_64K)
 
+/* UBI */
+#define CONFIG_CMD_BOOTZ
+#define CONFIG_CMD_UBI
+#define CONFIG_CMD_UBIFS	/* increases size by almost 60 KB */
+#define CONFIG_LZO
+#define CONFIG_MTD_UBI_FASTMAP
+#define CONFIG_RBTREE
+
 /* Debug commands */
 #define CONFIG_CMD_CACHE
 
Signature · 1 line
2.4.3
#23 lore raw

PATCH v2 12/16 apalis/colibri_t20/t30: enable raw initrd support

In reply to Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Enable optional raw initrd support to allow boot using an initrd.

---
 include/configs/apalis_t30.h  | 3 +++
 include/configs/colibri_t20.h | 3 +++
 include/configs/colibri_t30.h | 3 +++
 3 files changed, 9 insertions(+)
include/configs/apalis_t30.h +3 -0
index 283b002..898ccdf 100644
@@ -79,6 +79,9 @@
 #undef CONFIG_SYS_MAXARGS
 #define CONFIG_SYS_MAXARGS		32
 
+#define CONFIG_SUPPORT_RAW_INITRD
+#define CONFIG_SYS_BOOT_RAMDISK_HIGH
+
 #include "tegra-common-usb-gadget.h"
 #include "tegra-common-post.h"
 
include/configs/colibri_t20.h +3 -0
index 72a328f..4c45ef8 100644
@@ -113,6 +113,9 @@
 #undef CONFIG_SYS_MAXARGS
 #define CONFIG_SYS_MAXARGS		32
 
+#define CONFIG_SUPPORT_RAW_INITRD
+#define CONFIG_SYS_BOOT_RAMDISK_HIGH
+
 #include "tegra-common-usb-gadget.h"
 #include "tegra-common-post.h"
 
include/configs/colibri_t30.h +3 -0
index 249b5c0..3ef4778 100644
@@ -72,6 +72,9 @@
 #undef CONFIG_SYS_MAXARGS
 #define CONFIG_SYS_MAXARGS		32
 
+#define CONFIG_SUPPORT_RAW_INITRD
+#define CONFIG_SYS_BOOT_RAMDISK_HIGH
+
 #include "tegra-common-usb-gadget.h"
 #include "tegra-common-post.h"
 
Signature · 1 line
2.4.3
#24 lore raw

PATCH v2 12/16 apalis/colibri_t20/t30: enable raw initrd support

include/configs/apalis_t30.h

Quoted 7 lines · Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Enable optional raw initrd support to allow boot using an initrd.

include/configs/apalis_t30.h +1 -0
 
+#define CONFIG_SYS_BOOT_RAMDISK_HIGH

Doesn't arch/arm/include/asm/config.h set this already?

#25 lore raw

PATCH v2 12/16 apalis/colibri_t20/t30: enable raw initrd support

Quoted 11 lines · Stephen Warren

Review

Quoted 5 lines · Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Enable optional raw initrd support to allow boot using an initrd.

(quoted diff) +0 -0

b/include/configs/apalis_t30.h

Quoted 1 line

+#define CONFIG_SYS_BOOT_RAMDISK_HIGH

Doesn't arch/arm/include/asm/config.h set this already?

Wow wasn't aware of that one yet. Yes, I believe you are right. I will drop this one then in an upcoming v3.

#26 lore raw

PATCH v2 13/16 apalis/colibri_t20/t30: increase tftp blocksize

In reply to Marcel Ziswiler

From: Max Krummenacher <[email protected]>

Enable CONFIG_IP_DEFRAG and set CONFIG_TFTP_BLOCKSIZE to 16384. This increases the tftp download speed considerably.

While at it enable CONFIG_TFTP_TSIZE which limits the progress bar to fifty '#' independent of the downloaded file size.

---
Changes in v2:
Only limit it to 1536 bytes on Colibri T20 to avoid issues observed otherwise.

 include/configs/apalis_t30.h  | 3 +++
 include/configs/colibri_t20.h | 3 +++
 include/configs/colibri_t30.h | 3 +++
 3 files changed, 9 insertions(+)
include/configs/apalis_t30.h +3 -0
index 898ccdf..8f7f833 100644
@@ -60,6 +60,9 @@
 
 /* General networking support */
 #define CONFIG_CMD_DHCP
+#define CONFIG_IP_DEFRAG
+#define CONFIG_TFTP_BLOCKSIZE		16384
+#define CONFIG_TFTP_TSIZE
 
 /* Miscellaneous commands */
 #define CONFIG_FAT_WRITE
include/configs/colibri_t20.h +3 -0
index 4c45ef8..65c4bee 100644
@@ -48,6 +48,9 @@
 
 /* General networking support */
 #define CONFIG_CMD_DHCP
+#define CONFIG_IP_DEFRAG
+#define CONFIG_TFTP_BLOCKSIZE		1536
+#define CONFIG_TFTP_TSIZE
 
 /* LCD support */
 #define CONFIG_LCD
include/configs/colibri_t30.h +3 -0
index 3ef4778..f91c2e2 100644
@@ -53,6 +53,9 @@
 
 /* General networking support */
 #define CONFIG_CMD_DHCP
+#define CONFIG_IP_DEFRAG
+#define CONFIG_TFTP_BLOCKSIZE		16384
+#define CONFIG_TFTP_TSIZE
 
 /* Miscellaneous commands */
 #define CONFIG_FAT_WRITE
Signature · 1 line
2.4.3
#27 lore raw

PATCH v2 13/16 apalis/colibri_t20/t30: increase tftp blocksize

Quoted 7 lines · Marcel Ziswiler

From: Max Krummenacher <[email protected]>

Enable CONFIG_IP_DEFRAG and set CONFIG_TFTP_BLOCKSIZE to 16384. This increases the tftp download speed considerably.

While at it enable CONFIG_TFTP_TSIZE which limits the progress bar to fifty '#' independent of the downloaded file size.

Does it make sense to enable this feature for all Tegra boards? No point in speeding up just a couple of boards ut leaving everything else slow.

#28 lore raw

PATCH v2 13/16 apalis/colibri_t20/t30: increase tftp blocksize

Quoted 6 lines · Stephen Warren
Quoted 5 lines · Marcel Ziswiler

From: Max Krummenacher <[email protected]>

Enable CONFIG_IP_DEFRAG and set CONFIG_TFTP_BLOCKSIZE to 16384. This increases the tftp download speed considerably.

Quoted 6 lines
Quoted 2 lines

While at it enable CONFIG_TFTP_TSIZE which limits the progress bar to fifty '#' independent of the downloaded file size.

Does it make sense to enable this feature for all Tegra boards? No point
in speeding up just a couple of boards ut leaving everything else slow.

I do agree but unfortunately the same 16 k size does not seem to work on Colibri T20 despite using the exact same ASIX USB to Ethernet chip. I tried to pinpoint the exact reason behind this but so far could not figure it out. I fear it has something to do with this Gizmo/bus arbitration stuff on T20 which has been fixed/improved on T30. Would be interesting to try on a Trimslice but unfortunately we never got our iron back from service.

#29 lore raw

PATCH v2 14/16 apalis/colibri_t20/30: clean-up

In reply to Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Various clean-ups either in comments, order or spacing without any functional impact:
- Add some comments in the device trees resp. reorder some parameters for consistency across all our modules.
- Sort some include files alphabetically (while leaving common.h on top of course).
- Streamline some comments in the configuration files and fix the spacing from using spaces to tabs.

---
 arch/arm/dts/tegra20-colibri.dts        |  4 +++-
 arch/arm/dts/tegra30-colibri.dts        |  2 +-
 board/toradex/apalis_t30/apalis_t30.c   |  3 ++-
 board/toradex/colibri_t30/colibri_t30.c |  6 +++---
 include/configs/apalis_t30.h            |  8 +++++---
 include/configs/colibri_t20.h           | 12 +++++++-----
 include/configs/colibri_t30.h           |  8 +++++---
 7 files changed, 26 insertions(+), 17 deletions(-)
arch/arm/dts/tegra20-colibri.dts +3 -1
index 8eaac4f..f058d45 100644
@@ -36,11 +36,13 @@
 	};
 
 	usb at c5004000 {
+		/* VBUS_LAN */
 		nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1) GPIO_ACTIVE_HIGH>;
 		nvidia,vbus-gpio = <&gpio TEGRA_GPIO(BB, 1) GPIO_ACTIVE_HIGH>;
 	};
 
 	usb at c5008000 {
+		/* USBH_PEN */
 		nvidia,vbus-gpio = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_LOW>;
 	};
 
@@ -82,8 +84,8 @@
 
 	sdhci at c8000600 {
 		status = "okay";
-		cd-gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_LOW>;
 		bus-width = <4>;
+		cd-gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_LOW>;
 	};
 
 	lcd_panel: panel {
arch/arm/dts/tegra30-colibri.dts +1 -1
index 36533dc..1da7260 100644
@@ -82,9 +82,9 @@
 	/* EHCI instance 1: USB2_DP/N -> AX88772B */
 	usb at 7d004000 {
 		status = "okay";
-		phy_type = "utmi";
 		/* VBUS_LAN */
 		nvidia,vbus-gpio = <&gpio TEGRA_GPIO(DD, 2) GPIO_ACTIVE_HIGH>;
+		phy_type = "utmi";
 	};
 
 	/* EHCI instance 2: USB3_DP/N -> USBH_P/N */
board/toradex/apalis_t30/apalis_t30.c +2 -1
index b7a2219..879006f 100644
@@ -6,13 +6,13 @@
  */
 
 #include <common.h>
-#include <dm.h>
 #include <asm/arch/gp_padctrl.h>
 #include <asm/arch/pinmux.h>
 #include <asm/arch-tegra/ap.h>
 #include <asm/arch-tegra/tegra.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
+#include <dm.h>
 #include <i2c.h>
 #include <netdev.h>
 
@@ -59,6 +59,7 @@ int tegra_pcie_board_init(void)
 		debug("%s: Cannot find PMIC I2C chip\n", __func__);
 		return err;
 	}
+
 	/* TPS659110: VDD2_OP_REG = 1.05V */
 	data[0] = 0x27;
 	addr = 0x25;
board/toradex/colibri_t30/colibri_t30.c +3 -3
index 7ca79eb..44b5beb 100644
@@ -6,14 +6,14 @@
  */
 
 #include <common.h>
-#include <asm/arch/pinmux.h>
 #include <asm/arch/gp_padctrl.h>
+#include <asm/arch/pinmux.h>
 #include <asm/arch-tegra/ap.h>
 #include <asm/arch-tegra/tegra.h>
+#include <asm/gpio.h>
 #include <asm/io.h>
-#include "pinmux-config-colibri_t30.h"
 #include <i2c.h>
-#include <asm/gpio.h>
+#include "pinmux-config-colibri_t30.h"
 
 int arch_misc_init(void)
 {
include/configs/apalis_t30.h +5 -3
index 8f7f833..7fc4bd9 100644
@@ -1,6 +1,8 @@
 /*
  * Copyright (c) 2014-2015 Marcel Ziswiler
  *
+ * Configuration settings for the Toradex Apalis T30 modules.
+ *
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
@@ -28,7 +30,7 @@
 #define CONFIG_SYS_I2C_TEGRA
 #define CONFIG_CMD_I2C
 
-/* SD/MMC */
+/* SD/MMC support */
 #define CONFIG_MMC
 #define CONFIG_GENERIC_MMC
 #define CONFIG_TEGRA_MMC
@@ -40,10 +42,10 @@
 #define CONFIG_SYS_MMC_ENV_DEV		0
 #define CONFIG_SYS_MMC_ENV_PART		2
 
-/* USB Host support */
+/* USB host support */
 #define CONFIG_USB_EHCI
 #define CONFIG_USB_EHCI_TEGRA
-#define CONFIG_USB_MAX_CONTROLLER_COUNT 3
+#define CONFIG_USB_MAX_CONTROLLER_COUNT	3
 #define CONFIG_USB_STORAGE
 #define CONFIG_CMD_USB
 
include/configs/colibri_t20.h +7 -5
index 65c4bee..f068cfa 100644
@@ -1,6 +1,8 @@
 /*
  * Copyright (C) 2012 Lucas Stach
  *
+ * Configuration settings for the Toradex Colibri T20 modules.
+ *
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
@@ -38,7 +40,7 @@
 #define CONFIG_USB_EHCI_TEGRA
 #define CONFIG_USB_ULPI
 #define CONFIG_USB_ULPI_VIEWPORT
-#define CONFIG_USB_MAX_CONTROLLER_COUNT 3
+#define CONFIG_USB_MAX_CONTROLLER_COUNT	3
 #define CONFIG_USB_STORAGE
 #define CONFIG_CMD_USB
 
@@ -65,7 +67,7 @@
 /* NAND support */
 #define CONFIG_CMD_NAND
 #define CONFIG_TEGRA_NAND
-#define CONFIG_SYS_MAX_NAND_DEVICE     1
+#define CONFIG_SYS_MAX_NAND_DEVICE	1
 
 /* Dynamic MTD partition support */
 #define CONFIG_CMD_MTDPARTS	/* Enable 'mtdparts' command line support */
@@ -80,9 +82,9 @@
 
 /* Environment in NAND, 64K is a bit excessive but erase block is 512K anyway */
 #define CONFIG_ENV_IS_IN_NAND
-#define CONFIG_ENV_OFFSET              (SZ_2M)
-#undef  CONFIG_ENV_SIZE /* undef size from tegra20-common.h */
-#define CONFIG_ENV_SIZE                (SZ_64K)
+#define CONFIG_ENV_OFFSET		(SZ_2M)
+#undef CONFIG_ENV_SIZE		/* undef size from tegra20-common.h */
+#define CONFIG_ENV_SIZE			(SZ_64K)
 
 /* UBI */
 #define CONFIG_CMD_BOOTZ
include/configs/colibri_t30.h +5 -3
index f91c2e2..04fdc48 100644
@@ -1,6 +1,8 @@
 /*
  * Copyright (c) 2013-2015 Stefan Agner
  *
+ * Configuration settings for the Toradex Colibri T30 modules.
+ *
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
@@ -28,7 +30,7 @@
 #define CONFIG_SYS_I2C_TEGRA
 #define CONFIG_CMD_I2C
 
-/* SD/MMC */
+/* SD/MMC support */
 #define CONFIG_MMC
 #define CONFIG_GENERIC_MMC
 #define CONFIG_TEGRA_MMC
@@ -40,10 +42,10 @@
 #define CONFIG_SYS_MMC_ENV_DEV		0
 #define CONFIG_SYS_MMC_ENV_PART		2
 
-/* USB Host support */
+/* USB host support */
 #define CONFIG_USB_EHCI
 #define CONFIG_USB_EHCI_TEGRA
-#define CONFIG_USB_MAX_CONTROLLER_COUNT 3
+#define CONFIG_USB_MAX_CONTROLLER_COUNT	3
 #define CONFIG_USB_STORAGE
 #define CONFIG_CMD_USB
 
Signature · 1 line
2.4.3
#30 lore raw

PATCH v2 15/16 colibri_t20: fix reset out pin

In reply to Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Make sure SODIMM pin 87 nRESET_OUT is released properly by explicitly setting its pin mux function to GMI. This solves some issues with e.g. USB not being fully operational on carrier boards with USB hubs connected to reset if U-Boot got loaded via recovery mode aka rcm.

---
 board/toradex/colibri_t20/colibri_t20.c | 3 +++
 1 file changed, 3 insertions(+)
board/toradex/colibri_t20/colibri_t20.c +3 -0
index 42b293d..83e1ddc 100644
@@ -51,6 +51,9 @@ int arch_misc_init(void)
 		return err;
 	}
 
+	/* make sure SODIMM pin 87 nRESET_OUT is released properly */
+	pinmux_set_func(PMUX_PINGRP_ATA, PMUX_FUNC_GMI);
+
 	if (readl(NV_PA_BASE_SRAM + NVBOOTINFOTABLE_BOOTTYPE) ==
 	    NVBOOTTYPE_RECOVERY)
 		printf("USB recovery mode\n");
Signature · 1 line
2.4.3
#31 lore raw

PATCH v2 16/16 apalis/colibri_t30: fix usb dm regression

In reply to Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Unfortunately currently both Apalis T30 as well as Colibri T30 crash upon starting USB host support. This is due to the following patch not having taken into account that our T30 device trees were defaulting to peripheral only mode instead of otg:

commit ddb9a502d18008e845d5a8fa03ec48630fa77fb7
dm: usb: tegra: Move most of init/uninit into a function

This patch fixes this by defaulting to otg now.

---
 arch/arm/dts/tegra30-apalis.dts  | 2 +-
 arch/arm/dts/tegra30-colibri.dts | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
arch/arm/dts/tegra30-apalis.dts +1 -1
index 13ab42b..3e0545c 100644
@@ -267,7 +267,7 @@
 	/* EHCI instance 0: USB1_DP/N -> USBO1_DP/N */
 	usb at 7d000000 {
 		status = "okay";
-		dr_mode = "peripheral";
+		dr_mode = "otg";
 		/* USBO1_EN */
 		nvidia,vbus-gpio = <&gpio TEGRA_GPIO(T, 5) GPIO_ACTIVE_HIGH>;
 	};
arch/arm/dts/tegra30-colibri.dts +1 -1
index 1da7260..487e1f6 100644
@@ -76,7 +76,7 @@
 	/* EHCI instance 0: USB1_DP/N -> USBC_P/N */
 	usb at 7d000000 {
 		status = "okay";
-		dr_mode = "peripheral";
+		dr_mode = "otg";
 	};
 
 	/* EHCI instance 1: USB2_DP/N -> AX88772B */
Signature · 1 line
2.4.3
#32 lore raw

PATCH v2 16/16 apalis/colibri_t30: fix usb dm regression

Quoted 11 lines · Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Unfortunately currently both Apalis T30 as well as Colibri T30 crash upon starting USB host support. This is due to the following patch not having taken into account that our T30 device trees were defaulting to peripheral only mode instead of otg:

commit ddb9a502d18008e845d5a8fa03ec48630fa77fb7
dm: usb: tegra: Move most of init/uninit into a function

arch/arm/dts/tegra30-colibri.dts line 80

Quoted 7 lines
arch/arm/dts/tegra30-colibri.dts +1 -1
 
  	/* EHCI instance 0: USB1_DP/N -> USBC_P/N */
  	usb at 7d000000 {
  		status = "okay";
-		dr_mode = "peripheral";
+		dr_mode = "otg";
  	};

Is there SW control over driving VBUS for this port? If not, I don't think switching to otg is correct/possible.

It seems better to fix the crash in the code?

#33 lore raw

PATCH v2 16/16 apalis/colibri_t30: fix usb dm regression

Quoted 16 lines · Stephen Warren
Quoted 4 lines · Marcel Ziswiler

From: Marcel Ziswiler <[email protected]>

Unfortunately currently both Apalis T30 as well as Colibri T30 crash upon starting USB host support. This is due to the following patch

not

Quoted 1 line

having taken into account that our T30 device trees were defaulting

to

Review

Quoted 6 lines

peripheral only mode instead of otg:

commit ddb9a502d18008e845d5a8fa03ec48630fa77fb7
dm: usb: tegra: Move most of init/uninit into a function

(quoted diff) +0 -0

b/arch/arm/dts/tegra30-colibri.dts

Quoted 9 lines

arch/arm/dts/tegra30-apalis.dts line 273

Quoted 6 lines
  	/* EHCI instance 0: USB1_DP/N -> USBC_P/N */
  	usb at 7d000000 {
  		status = "okay";
arch/arm/dts/tegra30-apalis.dts +1 -1
-		dr_mode = "peripheral";
+		dr_mode = "otg";
  	};

Is there SW control over driving VBUS for this port? If not, I don't think switching to otg is correct/possible.

Yes, on Apalis T30 it is software controlled while on Colibri T30 it is hardware controlled (e.g. resp. cable decides). So this actually does work.

Quoted 1 line

It seems better to fix the crash in the code?

I kind of agree but this is outside the scope of this patch which just changes this to what everybody else does which actually works.