Skip to contentSkip to conversation

usb: add device connection/disconnection detection

PATCH New Simon Glass 8 participants 76 messages May 4, 2015 – May 12, 2015

Subsystems (12)
lore
Share & tools
lore
#0 lore raw

PATCH 1/24 usb: add device connection/disconnection detection

From: Vincent Palatin <[email protected]>

Provide a function to detect USB device insertion/removal in order to avoid having to do USB enumeration in a tight loop when trying to detect peripheral hotplugging.

---

 common/usb.c     | 26 ++++++++++++++++++++++++++
 common/usb_hub.c |  2 +-
 include/usb.h    |  2 ++
 3 files changed, 29 insertions(+), 1 deletion(-)
common/usb.c +26 -0
index a4820d3..bde8f31 100644
@@ -148,6 +148,32 @@ int usb_stop(void)
 	return 0;
 }
 
+/******************************************************************************
+ * Detect if a USB device has been plugged or unplugged.
+ */
+int usb_detect_change(void)
+{
+	int i, j;
+	int change = 0;
+
+	for (j = 0; j < USB_MAX_DEVICE; j++) {
+		for (i = 0; i < usb_dev[j].maxchild; i++) {
+			struct usb_port_status status;
+
+			if (usb_get_port_status(&usb_dev[j], i + 1,
+						&status) < 0)
+				/* USB request failed */
+				continue;
+
+			if (le16_to_cpu(status.wPortChange) &
+			    USB_PORT_STAT_C_CONNECTION)
+				change++;
+		}
+	}
+
+	return change;
+}
+
 /*
  * disables the asynch behaviour of the control message. This is used for data
  * transfers that uses the exclusiv access to the control and bulk messages.
common/usb_hub.c +1 -1
index c9be530..bbed1c8 100644
@@ -79,7 +79,7 @@ static int usb_get_hub_status(struct usb_device *dev, void *data)
 			data, sizeof(struct usb_hub_status), USB_CNTL_TIMEOUT);
 }
 
-static int usb_get_port_status(struct usb_device *dev, int port, void *data)
+int usb_get_port_status(struct usb_device *dev, int port, void *data)
 {
 	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
 			USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port,
include/usb.h +2 -0
index 1984e8f..25dddb8 100644
@@ -265,6 +265,7 @@ int usb_kbd_deregister(int force);
 /* routines */
 int usb_init(void); /* initialize the USB Controller */
 int usb_stop(void); /* stop the USB Controller */
+int usb_detect_change(void); /* detect if a USB device has been (un)plugged */
 
 
 int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol);
@@ -290,6 +291,7 @@ int usb_get_class_descriptor(struct usb_device *dev, int ifnum,
 int usb_clear_halt(struct usb_device *dev, int pipe);
 int usb_string(struct usb_device *dev, int index, char *buf, size_t size);
 int usb_set_interface(struct usb_device *dev, int interface, int alternate);
+int usb_get_port_status(struct usb_device *dev, int port, void *data);
 
 /* big endian -> little endian conversion */
 /* some CPUs are already little endian e.g. the ARM920T */
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#1 lore raw

PATCH 1/24 usb: add device connection/disconnection detection

Quoted 12 lines · Simon Glass

From: Vincent Palatin <[email protected]>

Provide a function to detect USB device insertion/removal in order to avoid having to do USB enumeration in a tight loop when trying to detect peripheral hotplugging.

Quoted 6 lines

---

 common/usb.c     | 26 ++++++++++++++++++++++++++
 common/usb_hub.c |  2 +-
 include/usb.h    |  2 ++
 3 files changed, 29 insertions(+), 1 deletion(-)

Applied to u-boot-dm, thanks Vincent.

#2 lore raw

PATCH 2/24 dm: usb: Implement usb_detect_change() for driver model

In reply to Simon Glass

Support this function with driver model also (CONFIG_DM_USB).

---

 drivers/usb/host/usb-uclass.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)
drivers/usb/host/usb-uclass.c +43 -0
index 714bc0e..8445a42 100644
@@ -555,6 +555,49 @@ int usb_scan_device(struct udevice *parent, int port,
 	return 0;
 }
 
+/*
+ * Detect if a USB device has been plugged or unplugged.
+ */
+int usb_detect_change(void)
+{
+	struct udevice *hub;
+	struct uclass *uc;
+	int change = 0;
+	int ret;
+
+	ret = uclass_get(UCLASS_USB_HUB, &uc);
+	if (ret)
+		return ret;
+
+	uclass_foreach_dev(hub, uc) {
+		struct usb_device *udev;
+		struct udevice *dev;
+
+		if (!device_active(hub))
+			continue;
+		for (device_find_first_child(hub, &dev);
+		     dev;
+		     device_find_next_child(&dev)) {
+			struct usb_port_status status;
+
+			if (!device_active(hub))
+				continue;
+
+			udev = dev_get_parentdata(hub);
+			if (usb_get_port_status(udev, udev->portnr, &status)
+					< 0)
+				/* USB request failed */
+				continue;
+
+			if (le16_to_cpu(status.wPortChange) &
+			    USB_PORT_STAT_C_CONNECTION)
+				change++;
+		}
+	}
+
+	return change;
+}
+
 int usb_child_post_bind(struct udevice *dev)
 {
 	struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#3 lore raw

PATCH 2/24 dm: usb: Implement usb_detect_change() for driver model

Hi Simon,

Quoted 26 lines · Simon Glass

Support this function with driver model also (CONFIG_DM_USB).

---

 drivers/usb/host/usb-uclass.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)
drivers/usb/host/usb-uclass.c +10 -0
index 714bc0e..8445a42 100644
@@ -555,6 +555,49 @@ int usb_scan_device(struct udevice *parent, int port,
        return 0;
 }
 
+/*
+ * Detect if a USB device has been plugged or unplugged.
+ */
+int usb_detect_change(void)
+{
+       struct udevice *hub;
+       struct uclass *uc;
+       int change = 0;
+       int ret;
+

drivers/usb/host/usb-uclass.c int usb_scan_device(struct udevice *parent, int port, · line 577

Quoted 10 lines
drivers/usb/host/usb-uclass.c +10 -0
+       ret = uclass_get(UCLASS_USB_HUB, &uc);
+       if (ret)
+               return ret;
+
+       uclass_foreach_dev(hub, uc) {
+               struct usb_device *udev;
+               struct udevice *dev;
+
+               if (!device_active(hub))
+                       continue;

You check this here.

drivers/usb/host/usb-uclass.c int usb_scan_device(struct udevice *parent, int port, · line 584

Quoted 7 lines
drivers/usb/host/usb-uclass.c +7 -0
+               for (device_find_first_child(hub, &dev);
+                    dev;
+                    device_find_next_child(&dev)) {
+                       struct usb_port_status status;
+
+                       if (!device_active(hub))
+                               continue;

How can this be true here? Maybe you meant to check if the "dev" was active?

drivers/usb/host/usb-uclass.c int usb_scan_device(struct udevice *parent, int port, · line 586

Quoted 2 lines
drivers/usb/host/usb-uclass.c +2 -0
+
+                       udev = dev_get_parentdata(hub);

Why parent of the hub? Looking for an upstream hub?

Quoted 8 lines
drivers/usb/host/usb-uclass.c +8 -0
+                       if (usb_get_port_status(udev, udev->portnr, &status)
+                                       < 0)
+                               /* USB request failed */
+                               continue;
+
+                       if (le16_to_cpu(status.wPortChange) &
+                           USB_PORT_STAT_C_CONNECTION)
+                               change++;

drivers/usb/host/usb-uclass.c int usb_scan_device(struct udevice *parent, int port,

Quoted 10 lines
drivers/usb/host/usb-uclass.c +6 -1
+               }
+       }
+
+       return change;
+}
+
 int usb_child_post_bind(struct udevice *dev)
 {
        struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
--

Thanks,
-Joe

#4 lore raw

PATCH 3/24 bootstage: Add IDs for SPI flash reading and decompression

In reply to Simon Glass

We maintain an accumulator for time spent reading from SPI flash, since this can be significant on some platforms. Also add one for decompression time.

---

 include/bootstage.h | 2 ++
 1 file changed, 2 insertions(+)
include/bootstage.h +2 -0
index be44014..fe30ab6 100644
@@ -195,6 +195,8 @@ enum bootstage_id {
 
 	BOOTSTAGE_ID_ACCUM_LCD,
 	BOOTSTAGE_ID_ACCUM_SCSI,
+	BOOTSTAGE_ID_ACCUM_SPI,
+	BOOTSTAGE_ID_ACCUM_DECOMP,
 
 	/* a few spare for the user, from here */
 	BOOTSTAGE_ID_USER,
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#6 lore raw

PATCH 3/24 bootstage: Add IDs for SPI flash reading and decompression

Quoted 10 lines · Joe Hershberger

Hi Simon,

Quoted 6 lines · Simon Glass

We maintain an accumulator for time spent reading from SPI flash, since this can be significant on some platforms. Also add one for decompression time.

---

Signature · 2 lines
Jagan Teki,
Openedev.
#7 lore raw

PATCH 3/24 bootstage: Add IDs for SPI flash reading and decompression

Quoted 8 lines · Jagan Teki
Quoted 7 lines · Joe Hershberger

Hi Simon,

Quoted 4 lines · Simon Glass

We maintain an accumulator for time spent reading from SPI flash, since this can be significant on some platforms. Also add one for decompression time.

Quoted 5 lines
Quoted 3 lines
Quoted 2 lines

---

Applied to u-boot-dm.

#8 lore raw

PATCH 4/24 dm: i2c: Implement 'i2c bus' command for driver model

In reply to Simon Glass

This command was missed in the conversion. Add it back for driver model.

---

 common/cmd_i2c.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 55 insertions(+), 8 deletions(-)
common/cmd_i2c.c +55 -8
index ad38cbf..1bc0db8 100644
@@ -1623,6 +1623,27 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 }
 #endif /* CONFIG_I2C_EDID */
 
+#ifdef CONFIG_DM_I2C
+static void show_bus(struct udevice *bus)
+{
+	struct udevice *dev;
+
+	printf("Bus %d:\t%s", bus->req_seq, bus->name);
+	if (device_active(bus))
+		printf("  (active %d)", bus->seq);
+	printf("\n");
+	for (device_find_first_child(bus, &dev);
+	     dev;
+	     device_find_next_child(&dev)) {
+		struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
+
+		printf("   %02x: %s, offset len %x, flags %x\n",
+		       chip->chip_addr, dev->name, chip->offset_len,
+		       chip->flags);
+	}
+}
+#endif
+
 /**
  * do_i2c_show_bus() - Handle the "i2c bus" command-line command
  * @cmdtp:	Command data struct pointer
@@ -1632,20 +1653,30 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
  *
  * Returns zero always.
  */
-#if defined(CONFIG_SYS_I2C)
+#if defined(CONFIG_SYS_I2C) || defined(CONFIG_DM_I2C)
 static int do_i2c_show_bus(cmd_tbl_t *cmdtp, int flag, int argc,
 				char * const argv[])
 {
-	int	i;
-#ifndef CONFIG_SYS_I2C_DIRECT_BUS
-	int	j;
-#endif
-
 	if (argc == 1) {
 		/* show all busses */
+#ifdef CONFIG_DM_I2C
+		struct udevice *bus;
+		struct uclass *uc;
+		int ret;
+
+		ret = uclass_get(UCLASS_I2C, &uc);
+		if (ret)
+			return CMD_RET_FAILURE;
+		uclass_foreach_dev(bus, uc)
+			show_bus(bus);
+#else
+		int i;
+
 		for (i = 0; i < CONFIG_SYS_NUM_I2C_BUSES; i++) {
 			printf("Bus %d:\t%s", i, I2C_ADAP_NR(i)->name);
 #ifndef CONFIG_SYS_I2C_DIRECT_BUS
+			int j;
+
 			for (j = 0; j < CONFIG_SYS_I2C_MAX_HOPS; j++) {
 				if (i2c_bus[i].next_hop[j].chip == 0)
 					break;
@@ -1657,15 +1688,30 @@ static int do_i2c_show_bus(cmd_tbl_t *cmdtp, int flag, int argc,
 #endif
 			printf("\n");
 		}
+#endif
 	} else {
+		int i;
+
 		/* show specific bus */
 		i = simple_strtoul(argv[1], NULL, 10);
+#ifdef CONFIG_DM_I2C
+		struct udevice *bus;
+		int ret;
+
+		ret = uclass_get_device_by_seq(UCLASS_I2C, i, &bus);
+		if (ret) {
+			printf("Invalid bus %d: err=%d\n", i, ret);
+			return CMD_RET_FAILURE;
+		}
+		show_bus(bus);
+#else
 		if (i >= CONFIG_SYS_NUM_I2C_BUSES) {
 			printf("Invalid bus %d\n", i);
 			return -1;
 		}
 		printf("Bus %d:\t%s", i, I2C_ADAP_NR(i)->name);
 #ifndef CONFIG_SYS_I2C_DIRECT_BUS
+			int j;
 			for (j = 0; j < CONFIG_SYS_I2C_MAX_HOPS; j++) {
 				if (i2c_bus[i].next_hop[j].chip == 0)
 					break;
@@ -1676,6 +1722,7 @@ static int do_i2c_show_bus(cmd_tbl_t *cmdtp, int flag, int argc,
 			}
 #endif
 		printf("\n");
+#endif
 	}
 
 	return 0;
@@ -1835,7 +1882,7 @@ static int do_i2c_reset(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv
 }
 
 static cmd_tbl_t cmd_i2c_sub[] = {
-#if defined(CONFIG_SYS_I2C)
+#if defined(CONFIG_SYS_I2C) || defined(CONFIG_DM_I2C)
 	U_BOOT_CMD_MKENT(bus, 1, 1, do_i2c_show_bus, "", ""),
 #endif
 	U_BOOT_CMD_MKENT(crc32, 3, 1, do_i2c_crc, "", ""),
@@ -1902,7 +1949,7 @@ static int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 /***************************************************/
 #ifdef CONFIG_SYS_LONGHELP
 static char i2c_help_text[] =
-#if defined(CONFIG_SYS_I2C)
+#if defined(CONFIG_SYS_I2C) || defined(CONFIG_DM_I2C)
 	"bus [muxtype:muxaddr:muxchannel] - show I2C bus info\n"
 #endif
 	"crc32 chip address[.0, .1, .2] count - compute CRC32 checksum\n"
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#9 lore raw

PATCH 4/24 dm: i2c: Implement 'i2c bus' command for driver model

Hi Simon,

Quoted 4 lines · Simon Glass

This command was missed in the conversion. Add it back for driver model.

---

Quoted 113 lines
 common/cmd_i2c.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 55 insertions(+), 8 deletions(-)
common/cmd_i2c.c +53 -6
index ad38cbf..1bc0db8 100644
@@ -1623,6 +1623,27 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 }
 #endif /* CONFIG_I2C_EDID */
 
+#ifdef CONFIG_DM_I2C
+static void show_bus(struct udevice *bus)
+{
+       struct udevice *dev;
+
+       printf("Bus %d:\t%s", bus->req_seq, bus->name);
+       if (device_active(bus))
+               printf("  (active %d)", bus->seq);
+       printf("\n");
+       for (device_find_first_child(bus, &dev);
+            dev;
+            device_find_next_child(&dev)) {
+               struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
+
+               printf("   %02x: %s, offset len %x, flags %x\n",
+                      chip->chip_addr, dev->name, chip->offset_len,
+                      chip->flags);
+       }
+}
+#endif
+
 /**
  * do_i2c_show_bus() - Handle the "i2c bus" command-line command
  * @cmdtp:     Command data struct pointer
@@ -1632,20 +1653,30 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
  *
  * Returns zero always.
  */
-#if defined(CONFIG_SYS_I2C)
+#if defined(CONFIG_SYS_I2C) || defined(CONFIG_DM_I2C)
 static int do_i2c_show_bus(cmd_tbl_t *cmdtp, int flag, int argc,
                                char * const argv[])
 {
-       int     i;
-#ifndef CONFIG_SYS_I2C_DIRECT_BUS
-       int     j;
-#endif
-
        if (argc == 1) {
                /* show all busses */
+#ifdef CONFIG_DM_I2C
+               struct udevice *bus;
+               struct uclass *uc;
+               int ret;
+
+               ret = uclass_get(UCLASS_I2C, &uc);
+               if (ret)
+                       return CMD_RET_FAILURE;
+               uclass_foreach_dev(bus, uc)
+                       show_bus(bus);
+#else
+               int i;
+
                for (i = 0; i < CONFIG_SYS_NUM_I2C_BUSES; i++) {
                        printf("Bus %d:\t%s", i, I2C_ADAP_NR(i)->name);
 #ifndef CONFIG_SYS_I2C_DIRECT_BUS
+                       int j;
+
                        for (j = 0; j < CONFIG_SYS_I2C_MAX_HOPS; j++) {
                                if (i2c_bus[i].next_hop[j].chip == 0)
                                        break;
@@ -1657,15 +1688,30 @@ static int do_i2c_show_bus(cmd_tbl_t *cmdtp, int flag, int argc,
 #endif
                        printf("\n");
                }
+#endif
        } else {
+               int i;
+
                /* show specific bus */
                i = simple_strtoul(argv[1], NULL, 10);
+#ifdef CONFIG_DM_I2C
+               struct udevice *bus;
+               int ret;
+
+               ret = uclass_get_device_by_seq(UCLASS_I2C, i, &bus);
+               if (ret) {
+                       printf("Invalid bus %d: err=%d\n", i, ret);
+                       return CMD_RET_FAILURE;
+               }
+               show_bus(bus);
+#else
                if (i >= CONFIG_SYS_NUM_I2C_BUSES) {
                        printf("Invalid bus %d\n", i);
                        return -1;
                }
                printf("Bus %d:\t%s", i, I2C_ADAP_NR(i)->name);
 #ifndef CONFIG_SYS_I2C_DIRECT_BUS
+                       int j;
                        for (j = 0; j < CONFIG_SYS_I2C_MAX_HOPS; j++) {
                                if (i2c_bus[i].next_hop[j].chip == 0)
                                        break;
@@ -1676,6 +1722,7 @@ static int do_i2c_show_bus(cmd_tbl_t *cmdtp, int flag, int argc,
                        }
 #endif
                printf("\n");
+#endif
        }
 
        return 0;

common/cmd_i2c.c static int do_i2c_reset(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv · line 1885

Quoted 5 lines
common/cmd_i2c.c +1 -1
@@ -1835,7 +1882,7 @@ static int do_i2c_reset(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv
 }
 
 static cmd_tbl_t cmd_i2c_sub[] = {
-#if defined(CONFIG_SYS_I2C)
+#if defined(CONFIG_SYS_I2C) || defined(CONFIG_DM_I2C)

It's too bad we are already on a 3rd model for I2C and the 1st is still kicking around. We have the same problem on the Ethernet phy drivers as soon as I add DM support. I intend to address that one at some point before too long... maybe even before I add DM support. Maybe we need a deadline for this in I2C like we had for common board?

Quoted 13 lines
common/cmd_i2c.c +1 -2
        U_BOOT_CMD_MKENT(bus, 1, 1, do_i2c_show_bus, "", ""),
 #endif
        U_BOOT_CMD_MKENT(crc32, 3, 1, do_i2c_crc, "", ""),
@@ -1902,7 +1949,7 @@ static int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 /***************************************************/
 #ifdef CONFIG_SYS_LONGHELP
 static char i2c_help_text[] =
-#if defined(CONFIG_SYS_I2C)
+#if defined(CONFIG_SYS_I2C) || defined(CONFIG_DM_I2C)
        "bus [muxtype:muxaddr:muxchannel] - show I2C bus info\n"
 #endif
        "crc32 chip address[.0, .1, .2] count - compute CRC32 checksum\n"
--
Quoted 1 line

2.2.0.rc0.207.ga3a616c

Cheers,
-Joe

#10 lore raw

PATCH 4/24 dm: i2c: Implement 'i2c bus' command for driver model

In reply to Simon Glass

Hello Simon,

Am 04.05.2015 19:30, schrieb Simon Glass:

Quoted 64 lines

This command was missed in the conversion. Add it back for driver model.

---

  common/cmd_i2c.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++-------
  1 file changed, 55 insertions(+), 8 deletions(-)
common/cmd_i2c.c +30 -6
index ad38cbf..1bc0db8 100644
@@ -1623,6 +1623,27 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
  }
  #endif /* CONFIG_I2C_EDID */
 
+#ifdef CONFIG_DM_I2C
+static void show_bus(struct udevice *bus)
+{
+	struct udevice *dev;
+
+	printf("Bus %d:\t%s", bus->req_seq, bus->name);
+	if (device_active(bus))
+		printf("  (active %d)", bus->seq);
+	printf("\n");
+	for (device_find_first_child(bus, &dev);
+	     dev;
+	     device_find_next_child(&dev)) {
+		struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
+
+		printf("   %02x: %s, offset len %x, flags %x\n",
+		       chip->chip_addr, dev->name, chip->offset_len,
+		       chip->flags);
+	}
+}
+#endif
+
  /**
   * do_i2c_show_bus() - Handle the "i2c bus" command-line command
   * @cmdtp:	Command data struct pointer
@@ -1632,20 +1653,30 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
   *
   * Returns zero always.
   */
-#if defined(CONFIG_SYS_I2C)
+#if defined(CONFIG_SYS_I2C) || defined(CONFIG_DM_I2C)
  static int do_i2c_show_bus(cmd_tbl_t *cmdtp, int flag, int argc,
  				char * const argv[])
  {
-	int	i;
-#ifndef CONFIG_SYS_I2C_DIRECT_BUS
-	int	j;
-#endif
-
  	if (argc == 1) {
  		/* show all busses */
+#ifdef CONFIG_DM_I2C
+		struct udevice *bus;
+		struct uclass *uc;
+		int ret;
+
+		ret = uclass_get(UCLASS_I2C, &uc);
+		if (ret)
+			return CMD_RET_FAILURE;

common/cmd_i2c.c int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) · line 1679

Quoted 10 lines
common/cmd_i2c.c +7 -0
+		uclass_foreach_dev(bus, uc)
+			show_bus(bus);
+#else
+		int i;
+
  		for (i = 0; i < CONFIG_SYS_NUM_I2C_BUSES; i++) {
  			printf("Bus %d:\t%s", i, I2C_ADAP_NR(i)->name);
  #ifndef CONFIG_SYS_I2C_DIRECT_BUS
+			int j;
+

I thought this drops an error, because var j is declared in the middle of code, but just tried it with gcc 4.7.2 and gcc 4.8.1 vor the mgcoge board, drops no warning, so:

Thanks!

bye,
Heiko

Quoted 61 lines
common/cmd_i2c.c +18 -2
  			for (j = 0; j < CONFIG_SYS_I2C_MAX_HOPS; j++) {
  				if (i2c_bus[i].next_hop[j].chip == 0)
  					break;
@@ -1657,15 +1688,30 @@ static int do_i2c_show_bus(cmd_tbl_t *cmdtp, int flag, int argc,
  #endif
  			printf("\n");
  		}
+#endif
  	} else {
+		int i;
+
  		/* show specific bus */
  		i = simple_strtoul(argv[1], NULL, 10);
+#ifdef CONFIG_DM_I2C
+		struct udevice *bus;
+		int ret;
+
+		ret = uclass_get_device_by_seq(UCLASS_I2C, i, &bus);
+		if (ret) {
+			printf("Invalid bus %d: err=%d\n", i, ret);
+			return CMD_RET_FAILURE;
+		}
+		show_bus(bus);
+#else
  		if (i >= CONFIG_SYS_NUM_I2C_BUSES) {
  			printf("Invalid bus %d\n", i);
  			return -1;
  		}
  		printf("Bus %d:\t%s", i, I2C_ADAP_NR(i)->name);
  #ifndef CONFIG_SYS_I2C_DIRECT_BUS
+			int j;
  			for (j = 0; j < CONFIG_SYS_I2C_MAX_HOPS; j++) {
  				if (i2c_bus[i].next_hop[j].chip == 0)
  					break;
@@ -1676,6 +1722,7 @@ static int do_i2c_show_bus(cmd_tbl_t *cmdtp, int flag, int argc,
  			}
  #endif
  		printf("\n");
+#endif
  	}
 
  	return 0;
@@ -1835,7 +1882,7 @@ static int do_i2c_reset(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv
  }
 
  static cmd_tbl_t cmd_i2c_sub[] = {
-#if defined(CONFIG_SYS_I2C)
+#if defined(CONFIG_SYS_I2C) || defined(CONFIG_DM_I2C)
  	U_BOOT_CMD_MKENT(bus, 1, 1, do_i2c_show_bus, "", ""),
  #endif
  	U_BOOT_CMD_MKENT(crc32, 3, 1, do_i2c_crc, "", ""),
@@ -1902,7 +1949,7 @@ static int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
  /***************************************************/
  #ifdef CONFIG_SYS_LONGHELP
  static char i2c_help_text[] =
-#if defined(CONFIG_SYS_I2C)
+#if defined(CONFIG_SYS_I2C) || defined(CONFIG_DM_I2C)
  	"bus [muxtype:muxaddr:muxchannel] - show I2C bus info\n"
  #endif
  	"crc32 chip address[.0, .1, .2] count - compute CRC32 checksum\n"
Signature · 2 lines
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
#11 lore raw

PATCH 4/24 dm: i2c: Implement 'i2c bus' command for driver model

Hi Heiko,

Quoted 88 lines · Heiko Schocher

Hello Simon,

Am 04.05.2015 19:30, schrieb Simon Glass:

Quoted 68 lines

This command was missed in the conversion. Add it back for driver model.

---

  common/cmd_i2c.c | 63
+++++++++++++++++++++++++++++++++++++++++++++++++-------
  1 file changed, 55 insertions(+), 8 deletions(-)
common/cmd_i2c.c +21 -0
index ad38cbf..1bc0db8 100644
@@ -1623,6 +1623,27 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc,
 char *const argv[])
  }
  #endif /* CONFIG_I2C_EDID */
 
+#ifdef CONFIG_DM_I2C
+static void show_bus(struct udevice *bus)
+{
+       struct udevice *dev;
+
+       printf("Bus %d:\t%s", bus->req_seq, bus->name);
+       if (device_active(bus))
+               printf("  (active %d)", bus->seq);
+       printf("\n");
+       for (device_find_first_child(bus, &dev);
+            dev;
+            device_find_next_child(&dev)) {
+               struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
+
+               printf("   %02x: %s, offset len %x, flags %x\n",
+                      chip->chip_addr, dev->name, chip->offset_len,
+                      chip->flags);
+       }
+}
+#endif
+
  /**
   * do_i2c_show_bus() - Handle the "i2c bus" command-line command

* @cmdtp: Command data struct pointer

common/cmd_i2c.c +9 -6
@@ -1632,20 +1653,30 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc,
 char *const argv[])
   *
   * Returns zero always.
   */
-#if defined(CONFIG_SYS_I2C)
+#if defined(CONFIG_SYS_I2C) || defined(CONFIG_DM_I2C)
  static int do_i2c_show_bus(cmd_tbl_t *cmdtp, int flag, int argc,
                                char * const argv[])
  {
-       int     i;
-#ifndef CONFIG_SYS_I2C_DIRECT_BUS
-       int     j;
-#endif
-
        if (argc == 1) {
                /* show all busses */
+#ifdef CONFIG_DM_I2C
+               struct udevice *bus;
+               struct uclass *uc;
+               int ret;
+
+               ret = uclass_get(UCLASS_I2C, &uc);
+               if (ret)
+                       return CMD_RET_FAILURE;

common/cmd_i2c.c int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, · line 1680

Quoted 10 lines
common/cmd_i2c.c +7 -0
+               uclass_foreach_dev(bus, uc)
+                       show_bus(bus);
+#else
+               int i;
+
                for (i = 0; i < CONFIG_SYS_NUM_I2C_BUSES; i++) {
                        printf("Bus %d:\t%s", i, I2C_ADAP_NR(i)->name);
  #ifndef CONFIG_SYS_I2C_DIRECT_BUS
+                       int j;
+

I thought this drops an error, because var j is declared in the middle of code, but just tried it with gcc 4.7.2 and gcc 4.8.1 vor the mgcoge board, drops no warning, so:

Quoted 1 line

Yes, I probably shouldn't do that.

[snip]

Regards,
Simon

#12 lore raw

PATCH 4/24 dm: i2c: Implement 'i2c bus' command for driver model

Quoted 91 lines · Simon Glass

Hi Heiko,

Quoted 88 lines · Heiko Schocher

Hello Simon,

Am 04.05.2015 19:30, schrieb Simon Glass:

Quoted 68 lines

This command was missed in the conversion. Add it back for driver model.

---

  common/cmd_i2c.c | 63
+++++++++++++++++++++++++++++++++++++++++++++++++-------
  1 file changed, 55 insertions(+), 8 deletions(-)
common/cmd_i2c.c +21 -0
index ad38cbf..1bc0db8 100644
@@ -1623,6 +1623,27 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc,
 char *const argv[])
  }
  #endif /* CONFIG_I2C_EDID */
 
+#ifdef CONFIG_DM_I2C
+static void show_bus(struct udevice *bus)
+{
+       struct udevice *dev;
+
+       printf("Bus %d:\t%s", bus->req_seq, bus->name);
+       if (device_active(bus))
+               printf("  (active %d)", bus->seq);
+       printf("\n");
+       for (device_find_first_child(bus, &dev);
+            dev;
+            device_find_next_child(&dev)) {
+               struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
+
+               printf("   %02x: %s, offset len %x, flags %x\n",
+                      chip->chip_addr, dev->name, chip->offset_len,
+                      chip->flags);
+       }
+}
+#endif
+
  /**
   * do_i2c_show_bus() - Handle the "i2c bus" command-line command

* @cmdtp: Command data struct pointer

common/cmd_i2c.c +9 -6
@@ -1632,20 +1653,30 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc,
 char *const argv[])
   *
   * Returns zero always.
   */
-#if defined(CONFIG_SYS_I2C)
+#if defined(CONFIG_SYS_I2C) || defined(CONFIG_DM_I2C)
  static int do_i2c_show_bus(cmd_tbl_t *cmdtp, int flag, int argc,
                                char * const argv[])
  {
-       int     i;
-#ifndef CONFIG_SYS_I2C_DIRECT_BUS
-       int     j;
-#endif
-
        if (argc == 1) {
                /* show all busses */
+#ifdef CONFIG_DM_I2C
+               struct udevice *bus;
+               struct uclass *uc;
+               int ret;
+
+               ret = uclass_get(UCLASS_I2C, &uc);
+               if (ret)
+                       return CMD_RET_FAILURE;

common/cmd_i2c.c int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, · line 1680

Quoted 10 lines
common/cmd_i2c.c +7 -0
+               uclass_foreach_dev(bus, uc)
+                       show_bus(bus);
+#else
+               int i;
+
                for (i = 0; i < CONFIG_SYS_NUM_I2C_BUSES; i++) {
                        printf("Bus %d:\t%s", i, I2C_ADAP_NR(i)->name);
  #ifndef CONFIG_SYS_I2C_DIRECT_BUS
+                       int j;
+

I thought this drops an error, because var j is declared in the middle of code, but just tried it with gcc 4.7.2 and gcc 4.8.1 vor the mgcoge board, drops no warning, so:

Quoted 8 lines
Quoted 1 line

Yes, I probably shouldn't do that.

[snip]

Regards,
Simon

Actually this is OK because it is not really in the middle of the code, due to the #ifdef.

Applied to u-boot-dm.

#13 lore raw

PATCH 5/24 dm: i2c: Add a function to find out the chip offset length

In reply to Simon Glass

We can currently set this but there is no API function to get it. Add one.

---

 drivers/i2c/i2c-uclass.c | 7 +++++++
 include/i2c.h            | 9 ++++++++-
 2 files changed, 15 insertions(+), 1 deletion(-)
drivers/i2c/i2c-uclass.c +7 -0
index f2e95c0..2dfb435 100644
@@ -396,6 +396,13 @@ int i2c_set_chip_offset_len(struct udevice *dev, uint offset_len)
 	return 0;
 }
 
+int i2c_get_chip_offset_len(struct udevice *dev)
+{
+	struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
+
+	return chip->offset_len;
+}
+
 int i2c_deblock(struct udevice *bus)
 {
 	struct dm_i2c_ops *ops = i2c_get_ops(bus);
include/i2c.h +8 -1
index 6fd73fa..9a9e4f7 100644
@@ -171,8 +171,15 @@ int i2c_get_chip_flags(struct udevice *dev, uint *flagsp);
  *
  * @offset_len:	New offset length value (typically 1 or 2)
  */
-
 int i2c_set_chip_offset_len(struct udevice *dev, uint offset_len);
+
+/**
+ * i2c_get_offset_len() - get the offset length for a chip
+ *
+ * @return:	Current offset length value (typically 1 or 2)
+ */
+int i2c_get_chip_offset_len(struct udevice *dev);
+
 /**
  * i2c_deblock() - recover a bus that is in an unknown state
  *
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#15 lore raw

PATCH 5/24 dm: i2c: Add a function to find out the chip offset length

In reply to Simon Glass

Hello Simon,

Am 04.05.2015 19:30, schrieb Simon Glass:

Quoted 8 lines

We can currently set this but there is no API function to get it. Add one.

---

  drivers/i2c/i2c-uclass.c | 7 +++++++
  include/i2c.h            | 9 ++++++++-
  2 files changed, 15 insertions(+), 1 deletion(-)

Thanks!

bye,
Heiko

Quoted 41 lines
drivers/i2c/i2c-uclass.c +7 -0
index f2e95c0..2dfb435 100644
@@ -396,6 +396,13 @@ int i2c_set_chip_offset_len(struct udevice *dev, uint offset_len)
  	return 0;
  }
 
+int i2c_get_chip_offset_len(struct udevice *dev)
+{
+	struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
+
+	return chip->offset_len;
+}
+
  int i2c_deblock(struct udevice *bus)
  {
  	struct dm_i2c_ops *ops = i2c_get_ops(bus);
include/i2c.h +8 -1
index 6fd73fa..9a9e4f7 100644
@@ -171,8 +171,15 @@ int i2c_get_chip_flags(struct udevice *dev, uint *flagsp);
   *
   * @offset_len:	New offset length value (typically 1 or 2)
   */
-
  int i2c_set_chip_offset_len(struct udevice *dev, uint offset_len);
+
+/**
+ * i2c_get_offset_len() - get the offset length for a chip
+ *
+ * @return:	Current offset length value (typically 1 or 2)
+ */
+int i2c_get_chip_offset_len(struct udevice *dev);
+
  /**
   * i2c_deblock() - recover a bus that is in an unknown state
   *
Signature · 2 lines
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
#16 lore raw

PATCH 5/24 dm: i2c: Add a function to find out the chip offset length

Quoted 9 lines · Heiko Schocher

Hello Simon,

Am 04.05.2015 19:30, schrieb Simon Glass:

Quoted 6 lines

We can currently set this but there is no API function to get it. Add one.

---

Quoted 8 lines
Quoted 3 lines
  drivers/i2c/i2c-uclass.c | 7 +++++++
  include/i2c.h            | 9 ++++++++-
  2 files changed, 15 insertions(+), 1 deletion(-)

Thanks!

Applied to u-boot-dm.

#17 lore raw

PATCH 6/24 tpm: Support using driver model with I2C

In reply to Simon Glass

As a first step towards converting the TPM system to driver model, allow it to work with CONFIG_DM_I2C.

---

 drivers/tpm/tpm.c         |  89 +++++++++++++++++++++++++-----
 drivers/tpm/tpm_private.h |   3 ++
 drivers/tpm/tpm_tis_i2c.c | 134 +++++++++++++++++++++++++++++++---------------
 3 files changed, 170 insertions(+), 56 deletions(-)
drivers/tpm/tpm.c +77 -12
index 31761ec..a650892 100644
@@ -34,6 +34,7 @@
 
 #include <config.h>
 #include <common.h>
+#include <dm.h>
 #include <linux/compiler.h>
 #include <fdtdec.h>
 #include <i2c.h>
@@ -48,10 +49,14 @@ DECLARE_GLOBAL_DATA_PTR;
 
 /* TPM configuration */
 struct tpm {
+#ifdef CONFIG_DM_I2C
+	struct udevice *dev;
+#else
 	int i2c_bus;
 	int slave_addr;
-	char inited;
 	int old_bus;
+#endif
+	char inited;
 } tpm;
 
 /* Global structure for tpm chip data */
@@ -372,7 +377,7 @@ static unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
 
 static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
 {
-	ssize_t rc;
+	int rc;
 	u32 count, ordinal;
 	unsigned long start, stop;
 
@@ -391,9 +396,11 @@ static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
 		return -E2BIG;
 	}
 
+	debug("Calling send\n");
 	rc = chip->vendor.send(chip, (u8 *)buf, count);
+	debug("   ... done calling send\n");
 	if (rc < 0) {
-		error("tpm_transmit: tpm_send: error %zd\n", rc);
+		error("tpm_transmit: tpm_send: error %d\n", rc);
 		goto out;
 	}
 
@@ -403,7 +410,7 @@ static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
 	start = get_timer(0);
 	stop = tpm_calc_ordinal_duration(chip, ordinal);
 	do {
-		debug("waiting for status...\n");
+		debug("waiting for status... %ld %ld\n", start, stop);
 		u8 status = chip->vendor.status(chip);
 		if ((status & chip->vendor.req_complete_mask) ==
 		    chip->vendor.req_complete_val) {
@@ -428,15 +435,30 @@ out_recv:
 	debug("out_recv: reading response...\n");
 	rc = chip->vendor.recv(chip, (u8 *)buf, TPM_BUFSIZE);
 	if (rc < 0)
-		error("tpm_transmit: tpm_recv: error %zd\n", rc);
+		error("tpm_transmit: tpm_recv: error %d\n", rc);
 
 out:
 	return rc;
 }
 
+#ifdef CONFIG_DM_I2C
+static int tpm_open_dev(struct udevice *dev)
+{
+	int rc;
+
+	debug("%s: start\n", __func__);
+	if (g_chip.is_open)
+		return -EBUSY;
+	rc = tpm_vendor_init_dev(dev);
+	if (rc < 0)
+		g_chip.is_open = 0;
+	return rc;
+}
+#else
 static int tpm_open(uint32_t dev_addr)
 {
 	int rc;
+
 	if (g_chip.is_open)
 		return -EBUSY;
 	rc = tpm_vendor_init(dev_addr);
@@ -444,7 +466,7 @@ static int tpm_open(uint32_t dev_addr)
 		g_chip.is_open = 0;
 	return rc;
 }
-
+#endif
 static void tpm_close(void)
 {
 	if (g_chip.is_open) {
@@ -455,6 +477,7 @@ static void tpm_close(void)
 
 static int tpm_select(void)
 {
+#ifndef CONFIG_DM_I2C
 	int ret;
 
 	tpm.old_bus = i2c_get_bus_num();
@@ -466,11 +489,13 @@ static int tpm_select(void)
 			return -1;
 		}
 	}
+#endif
 	return 0;
 }
 
 static int tpm_deselect(void)
 {
+#ifndef CONFIG_DM_I2C
 	int ret;
 
 	if (tpm.old_bus != i2c_get_bus_num()) {
@@ -482,6 +507,7 @@ static int tpm_deselect(void)
 		}
 	}
 	tpm.old_bus = -1;
+#endif
 	return 0;
 }
 
@@ -493,10 +519,9 @@ static int tpm_deselect(void)
  */
 static int tpm_decode_config(struct tpm *dev)
 {
-#ifdef CONFIG_OF_CONTROL
 	const void *blob = gd->fdt_blob;
-	int node, parent;
-	int i2c_bus;
+	int parent;
+	int node;
 
 	node = fdtdec_next_compatible(blob, 0, COMPAT_INFINEON_SLB9635_TPM);
 	if (node < 0) {
@@ -512,15 +537,48 @@ static int tpm_decode_config(struct tpm *dev)
 		debug("%s: Cannot find node parent\n", __func__);
 		return -1;
 	}
+#ifdef CONFIG_DM_I2C
+	struct udevice *bus;
+	int chip_addr;
+	int ret;
+
+	/*
+	 * TODO(sjg at chromium.org): Remove this when driver model supports
+	 * TPMs
+	 */
+	ret = uclass_get_device_by_of_offset(UCLASS_I2C, parent, &bus);
+	if (ret) {
+		debug("Cannot find bus for node '%s: ret=%d'\n",
+		      fdt_get_name(blob, parent, NULL), ret);
+		return ret;
+	}
+
+	chip_addr = fdtdec_get_int(blob, node, "reg", -1);
+	if (chip_addr == -1) {
+		debug("Cannot find reg property for node '%s: ret=%d'\n",
+		      fdt_get_name(blob, node, NULL), ret);
+		return ret;
+	}
+	/*
+	 * TODO([email protected]): Older TPMs will need to use the older method
+	 * in iic_tpm_read() so the offset length needs to be 0 here.
+	 */
+	ret = i2c_get_chip(bus, chip_addr, 1, &dev->dev);
+	if (ret) {
+		debug("Cannot find device for node '%s: ret=%d'\n",
+		      fdt_get_name(blob, node, NULL), ret);
+		return ret;
+	}
+#else
+	int i2c_bus;
+
 	i2c_bus = i2c_get_bus_num_fdt(parent);
 	if (i2c_bus < 0)
 		return -1;
 	dev->i2c_bus = i2c_bus;
 	dev->slave_addr = fdtdec_get_addr(blob, node, "reg");
-#else
-	dev->i2c_bus = CONFIG_TPM_TIS_I2C_BUS_NUMBER;
-	dev->slave_addr = CONFIG_TPM_TIS_I2C_SLAVE_ADDRESS;
 #endif
+
 	return 0;
 }
 
@@ -547,6 +605,7 @@ int tis_init(void)
 	if (tpm_select())
 		return -1;
 
+#ifndef CONFIG_DM_I2C
 	/*
 	 * Probe TPM twice; the first probing might fail because TPM is asleep,
 	 * and the probing can wake up TPM.
@@ -556,8 +615,10 @@ int tis_init(void)
 		      tpm.slave_addr);
 		return -1;
 	}
+#endif
 
 	tpm_deselect();
+	debug("%s: done\n", __func__);
 
 	tpm.inited = 1;
 
@@ -574,7 +635,11 @@ int tis_open(void)
 	if (tpm_select())
 		return -1;
 
+#ifdef CONFIG_DM_I2C
+	rc = tpm_open_dev(tpm.dev);
+#else
 	rc = tpm_open(tpm.slave_addr);
+#endif
 
 	tpm_deselect();
 
drivers/tpm/tpm_private.h +3 -0
index 888a074..8894c98 100644
@@ -131,6 +131,9 @@ struct tpm_chip *tpm_register_hardware(const struct tpm_vendor_specific *);
 
 int tpm_vendor_init(uint32_t dev_addr);
 
+struct udevice;
+int tpm_vendor_init_dev(struct udevice *dev);
+
 void tpm_vendor_cleanup(struct tpm_chip *chip);
 
 
drivers/tpm/tpm_tis_i2c.c +90 -44

288 lines not on this page · raw message

Signature · 1 line
2.2.0.rc0.207.ga3a616c
#18 lore raw

PATCH 6/24 tpm: Support using driver model with I2C

Quoted 10 lines · Simon Glass

As a first step towards converting the TPM system to driver model, allow it to work with CONFIG_DM_I2C.

---

 drivers/tpm/tpm.c         |  89 +++++++++++++++++++++++++-----
 drivers/tpm/tpm_private.h |   3 ++
 drivers/tpm/tpm_tis_i2c.c | 134 +++++++++++++++++++++++++++++++---------------
 3 files changed, 170 insertions(+), 56 deletions(-)

Applied to u-boot-dm.

#19 lore raw

PATCH 7/24 tpm: Rename Infineon TPM to slb9645tt

In reply to Simon Glass

This name is used in Linux, so use it in U-Boot.

---

 arch/arm/dts/exynos5420-peach-pit.dts | 2 +-
 arch/arm/dts/exynos5800-peach-pi.dts  | 2 +-
 lib/fdtdec.c                          | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)
arch/arm/dts/exynos5420-peach-pit.dts +1 -1
index 7d8fa28..6fe762d 100644
@@ -79,7 +79,7 @@
 	i2c at 12e10000 { /* i2c9 */
 		clock-frequency = <400000>;
                 tpm at 20 {
-                        compatible = "infineon,slb9645-tpm";
+                        compatible = "infineon,slb9645tt";
                         reg = <0x20>;
 		};
 	};
arch/arm/dts/exynos5800-peach-pi.dts +1 -1
index 8c1f616..176ce55 100644
@@ -72,7 +72,7 @@
 	i2c at 12e10000 { /* i2c9 */
 		clock-frequency = <400000>;
                 tpm at 20 {
-                        compatible = "infineon,slb9645-tpm";
+                        compatible = "infineon,slb9645tt";
                         reg = <0x20>;
 		};
 	};
lib/fdtdec.c +1 -1
index 14984b7..30573c2 100644
@@ -65,7 +65,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
 	COMPAT(GENERIC_SPI_FLASH, "spi-flash"),
 	COMPAT(MAXIM_98095_CODEC, "maxim,max98095-codec"),
 	COMPAT(INFINEON_SLB9635_TPM, "infineon,slb9635-tpm"),
-	COMPAT(INFINEON_SLB9645_TPM, "infineon,slb9645-tpm"),
+	COMPAT(INFINEON_SLB9645_TPM, "infineon,slb9645tt"),
 	COMPAT(SAMSUNG_EXYNOS5_I2C, "samsung,exynos5-hsi2c"),
 	COMPAT(SANDBOX_LCD_SDL, "sandbox,lcd-sdl"),
 	COMPAT(TI_TPS65090, "ti,tps65090"),
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#20 lore raw

PATCH 7/24 tpm: Rename Infineon TPM to slb9645tt

Quoted 9 lines · Simon Glass

This name is used in Linux, so use it in U-Boot.

---

 arch/arm/dts/exynos5420-peach-pit.dts | 2 +-
 arch/arm/dts/exynos5800-peach-pi.dts  | 2 +-
 lib/fdtdec.c                          | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

Applied to u-boot-dm.

#21 lore raw

PATCH 8/24 dm: gpio: Fix comment typo in GPIOD_IS_IN

In reply to Simon Glass

This should say 'in', not 'out'.

---

 include/asm-generic/gpio.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/asm-generic/gpio.h +1 -1
index 4752ea4..519bb0b 100644
@@ -115,7 +115,7 @@ struct gpio_desc {
 	unsigned long flags;
 #define GPIOD_REQUESTED		(1 << 0)	/* Requested/claimed */
 #define GPIOD_IS_OUT		(1 << 1)	/* GPIO is an output */
-#define GPIOD_IS_IN		(1 << 2)	/* GPIO is an output */
+#define GPIOD_IS_IN		(1 << 2)	/* GPIO is an input */
 #define GPIOD_ACTIVE_LOW	(1 << 3)	/* value has active low */
 #define GPIOD_IS_OUT_ACTIVE	(1 << 4)	/* set output active */
 
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#22 lore raw

PATCH 8/24 dm: gpio: Fix comment typo in GPIOD_IS_IN

Quoted 7 lines · Simon Glass

This should say 'in', not 'out'.

---

 include/asm-generic/gpio.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Applied to u-boot-dm.

#23 lore raw

PATCH 9/24 arm: Include the .got section in the binary

In reply to Simon Glass

Commit 47ed5dd0 dropped the .got section from U-Boot binaries. This is needed for some relocations, and causes failures if missing. Add it back.

---

 arch/arm/config.mk | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm/config.mk +2 -1
index c005ce4..0550225 100644
@@ -112,7 +112,8 @@ endif
 ifdef CONFIG_ARM64
 OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
 else
-OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .hash -j .data -j .got.plt -j .u_boot_list -j .rel.dyn
+OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .hash -j .data -j \
+	.got -j .got.plt -j .u_boot_list -j .rel.dyn
 endif
 
 ifdef CONFIG_OF_EMBED
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#24 lore raw

PATCH 9/24 arm: Include the .got section in the binary

Quoted 9 lines · Simon Glass

Commit 47ed5dd0 dropped the .got section from U-Boot binaries. This is needed for some relocations, and causes failures if missing. Add it back.

---

 arch/arm/config.mk | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Applied to u-boot-dm.

#25 lore raw

PATCH 10/24 arm: Add a prototype for save_boot_params_ret()

In reply to Simon Glass

It is convenient for some boards to implement save_boot_params() in C rather than assembler. Provide a way to return in this case.

---

 arch/arm/include/asm/system.h | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
arch/arm/include/asm/system.h +16 -0
index 2a5bed2..e584c3b 100644
@@ -158,6 +158,22 @@ void flush_l3_cache(void);
  * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3);
  */
 
+/**
+ * save_boot_params_ret() - Return from save_boot_params()
+ *
+ * If you provide save_boot_params(), then you should jump back to this
+ * function when done. Try to preserve all registers.
+ *
+ * If your implementation of save_boot_params() is in C then it is acceptable
+ * to simply call save_boot_params_ret() at the end of your function. Since
+ * there is no link register set up, you cannot just exit the function. U-Boot
+ * will return to the (initialised) value of lr, and likely crash/hang.
+ *
+ * If your implementation of save_boot_params() is in assembler then you
+ * should use 'b' or 'bx' to return to save_boot_params_ret.
+ */
+void save_boot_params_ret(void);
+
 #define isb() __asm__ __volatile__ ("" : : : "memory")
 
 #define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#28 lore raw

PATCH 11/24 arm: spl: Enable detecting when U-Boot is started from SPL

In reply to Simon Glass

For secure boot systems it is common to have a read-only U-Boot which starts the machine and jumps to a read-write U-Boot for actual booting the OS. This allows the read-write U-Boot to be upgraded without risk of permanently bricking the machine. In the event that the read-write U-Boot is corrupted, the read-only U-Boot can detect this with a checksum and boot into a recovery flow.

To support this, add a way to detect when U-Boot is run from SPL as opposed to some other method, such as booted directly (no SPL) or started from another source (e.g. a primary U-Boot). This works by putting a special value in r0.

For now we rely on board-specific code to actually check the register and set a flag. At some point this could be generalised, perhaps by using a spare register and passing a flag to _main and/or board_init_f().

---

 include/spl.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)
include/spl.h +13 -0
index b2e5bf7..cdd63a7 100644
@@ -11,6 +11,8 @@
 #include <linux/compiler.h>
 #include <asm/spl.h>
 
+/* Value in r0 indicates we booted from U-Boot */
+#define SPL_RUNNING_FROM_UBOOT	0x13578642
 
 /* Boot type */
 #define MMCSD_MODE_UNDEFINED	0
@@ -82,4 +84,15 @@ int spl_load_image_ext_os(block_dev_desc_t *block_dev, int partition);
 #ifdef CONFIG_SPL_BOARD_INIT
 void spl_board_init(void);
 #endif
+
+/**
+ * spl_was_boot_source() - check if U-Boot booted from SPL
+ *
+ * This will normally be true, but if U-Boot jumps to second U-Boot, it will
+ * be false. This should be implemented by board-specific code.
+ *
+ * @return true if U-Boot booted from SPL, else false
+ */
+bool spl_was_boot_source(void);
+
 #endif
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#29 lore raw

PATCH 11/24 arm: spl: Enable detecting when U-Boot is started from SPL

Hi Simon,

Quoted 16 lines · Simon Glass

For secure boot systems it is common to have a read-only U-Boot which starts the machine and jumps to a read-write U-Boot for actual booting the OS. This allows the read-write U-Boot to be upgraded without risk of permanently bricking the machine. In the event that the read-write U-Boot is corrupted, the read-only U-Boot can detect this with a checksum and boot into a recovery flow.

To support this, add a way to detect when U-Boot is run from SPL as opposed to some other method, such as booted directly (no SPL) or started from another source (e.g. a primary U-Boot). This works by putting a special value in r0.

For now we rely on board-specific code to actually check the register and set a flag. At some point this could be generalised, perhaps by using a spare register and passing a flag to _main and/or board_init_f().

Quoted 5 lines

---

 include/spl.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)

Part of this patch seems to be missing. I don't see how these changes can accomplish what is described in the commit log.

Quoted 20 lines
include/spl.h +5 -0
index b2e5bf7..cdd63a7 100644
@@ -11,6 +11,8 @@
 #include <linux/compiler.h>
 #include <asm/spl.h>
 
+/* Value in r0 indicates we booted from U-Boot */
+#define SPL_RUNNING_FROM_UBOOT 0x13578642
 
 /* Boot type */
 #define MMCSD_MODE_UNDEFINED   0
@@ -82,4 +84,15 @@ int spl_load_image_ext_os(block_dev_desc_t *block_dev, int partition);
 #ifdef CONFIG_SPL_BOARD_INIT
 void spl_board_init(void);
 #endif
+
+/**
+ * spl_was_boot_source() - check if U-Boot booted from SPL

include/spl.h int spl_load_image_ext_os(block_dev_desc_t *block_dev, int partition);

Quoted 10 lines
include/spl.h +8 -1
+ *
+ * This will normally be true, but if U-Boot jumps to second U-Boot, it will
+ * be false. This should be implemented by board-specific code.
+ *
+ * @return true if U-Boot booted from SPL, else false
+ */
+bool spl_was_boot_source(void);
+
 #endif
--

Thanks,
-Joe

#30 lore raw

PATCH 12/24 arm: Allow cleanup_before_linux() without disabling caches

In reply to Simon Glass

This function is used before jumping to U-Boot, but in that case we don't always want to disable caches.

---

 arch/arm/cpu/armv7/cpu.c | 47 +++++++++++++++++++++++++++++------------------
 include/common.h         | 15 +++++++++++++++
 2 files changed, 44 insertions(+), 18 deletions(-)
arch/arm/cpu/armv7/cpu.c +29 -18
index c56417d..0b0e500 100644
@@ -24,7 +24,7 @@
 
 void __weak cpu_cache_initialization(void){}
 
-int cleanup_before_linux(void)
+int cleanup_before_linux_select(int flags)
 {
 	/*
 	 * this function is called just before we call linux
@@ -42,24 +42,30 @@ int cleanup_before_linux(void)
 	icache_disable();
 	invalidate_icache_all();
 
-	/*
-	 * turn off D-cache
-	 * dcache_disable() in turn flushes the d-cache and disables MMU
-	 */
-	dcache_disable();
-	v7_outer_cache_disable();
+	if (flags & CBL_DISABLE_CACHES) {
+		/*
+		* turn off D-cache
+		* dcache_disable() in turn flushes the d-cache and disables MMU
+		*/
+		dcache_disable();
+		v7_outer_cache_disable();
 
-	/*
-	 * After D-cache is flushed and before it is disabled there may
-	 * be some new valid entries brought into the cache. We are sure
-	 * that these lines are not dirty and will not affect our execution.
-	 * (because unwinding the call-stack and setting a bit in CP15 SCTLR
-	 * is all we did during this. We have not pushed anything on to the
-	 * stack. Neither have we affected any static data)
-	 * So just invalidate the entire d-cache again to avoid coherency
-	 * problems for kernel
-	 */
-	invalidate_dcache_all();
+		/*
+		* After D-cache is flushed and before it is disabled there may
+		* be some new valid entries brought into the cache. We are
+		* sure that these lines are not dirty and will not affect our
+		* execution. (because unwinding the call-stack and setting a
+		* bit in CP15 SCTRL is all we did during this. We have not
+		* pushed anything on to the stack. Neither have we affected
+		* any static data) So just invalidate the entire d-cache again
+		* to avoid coherency problems for kernel
+		*/
+		invalidate_dcache_all();
+	} else {
+		flush_dcache_all();
+		invalidate_icache_all();
+		icache_enable();
+	}
 
 	/*
 	 * Some CPU need more cache attention before starting the kernel.
@@ -68,3 +74,8 @@ int cleanup_before_linux(void)
 
 	return 0;
 }
+
+int cleanup_before_linux(void)
+{
+	return cleanup_before_linux_select(CBL_ALL);
+}
include/common.h +15 -0
index cde3474..0b21599 100644
@@ -728,6 +728,21 @@ void	invalidate_dcache_range(unsigned long start, unsigned long stop);
 void	invalidate_dcache_all(void);
 void	invalidate_icache_all(void);
 
+enum {
+	/* Disable caches (else flush caches but leave them active) */
+	CBL_DISABLE_CACHES		= 1 << 0,
+	CBL_SHOW_BOOTSTAGE_REPORT	= 1 << 1,
+
+	CBL_ALL				= 3,
+};
+
+/**
+ * Clean up ready for linux
+ *
+ * @param flags		Flags to control what is done
+ */
+int cleanup_before_linux_select(int flags);
+
 /* arch/$(ARCH)/lib/ticks.S */
 uint64_t get_ticks(void);
 void	wait_ticks    (unsigned long);
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#32 lore raw

PATCH 12/24 arm: Allow cleanup_before_linux() without disabling caches

Hi Marek,

Quoted 8 lines · Marek Vasut
Quoted 5 lines · Simon Glass

This function is used before jumping to U-Boot, but in that case we don't always want to disable caches.

In which usecase exactly is this applicable please ? :)

This is sort-of related to "Enable detecting when U-Boot is started from SPL" so there are some details there.

I was able to get SPL to enable the cache and leave it on all the way through the verified boot flow (read-only and read-write U-Boot) and it saved about 600ms. So in short this refactor allows you to jump into U-Boot with the cache still enabled.

Regards,
Simon

#33 lore raw

PATCH 12/24 arm: Allow cleanup_before_linux() without disabling caches

Quoted 1 line · Simon Glass

Hi Marek,

Hi Simon,

Quoted 10 lines · Marek Vasut
Quoted 8 lines · Simon Glass
Quoted 5 lines

This function is used before jumping to U-Boot, but in that case we don't always want to disable caches.

In which usecase exactly is this applicable please ? :)

Quoted 7 lines

This is sort-of related to "Enable detecting when U-Boot is started from SPL" so there are some details there.

I was able to get SPL to enable the cache and leave it on all the way through the verified boot flow (read-only and read-write U-Boot) and it saved about 600ms. So in short this refactor allows you to jump into U-Boot with the cache still enabled.

Sounds good, thanks for clarifying !

Best regards,
Marek Vasut

#34 lore raw

PATCH 13/24 sandbox: Add an implementation for cleanup_before_linux_select()

In reply to Simon Glass

Support this function so we can use Chrome OS verified boot with sandbox.

---

 arch/sandbox/cpu/cpu.c | 5 +++++
 1 file changed, 5 insertions(+)
arch/sandbox/cpu/cpu.c +5 -0
index 168f2ef..4646f07 100644
@@ -55,6 +55,11 @@ int cleanup_before_linux(void)
 	return 0;
 }
 
+int cleanup_before_linux_select(int flags)
+{
+	return 0;
+}
+
 void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
 {
 #ifdef CONFIG_PCI
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#35 lore raw

PATCH 14/24 sandbox: Correct error handling in state_read_file()

In reply to Simon Glass

This function should return a useful error for U-Boot, rather than -1.

---

 arch/sandbox/cpu/state.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/sandbox/cpu/state.c +1 -1
index 033958c..cae731c 100644
@@ -51,7 +51,7 @@ static int state_read_file(struct sandbox_state *state, const char *fname)
 	ret = os_get_filesize(fname, &size);
 	if (ret < 0) {
 		printf("Cannot find sandbox state file '%s'\n", fname);
-		return ret;
+		return -ENOENT;
 	}
 	state->state_fdt = os_malloc(size);
 	if (!state->state_fdt) {
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#38 lore raw

PATCH 15/24 sandbox: Add missing errno.h includes in a few files

In reply to Simon Glass

These files use error numbering, so add the include.

---

 arch/sandbox/cpu/start.c       | 1 +
 drivers/misc/i2c_eeprom_emul.c | 1 +
 drivers/misc/swap_case.c       | 1 +
 3 files changed, 3 insertions(+)
arch/sandbox/cpu/start.c +1 -0
index ec01040..0707256 100644
@@ -4,6 +4,7 @@
  */
 
 #include <common.h>
+#include <errno.h>
 #include <os.h>
 #include <cli.h>
 #include <malloc.h>
drivers/misc/i2c_eeprom_emul.c +1 -0
index 7343445..4410d03 100644
@@ -8,6 +8,7 @@
 
 #include <common.h>
 #include <dm.h>
+#include <errno.h>
 #include <fdtdec.h>
 #include <i2c.h>
 #include <malloc.h>
drivers/misc/swap_case.c +1 -0
index f6028ba..3b8aa48 100644
@@ -9,6 +9,7 @@
 
 #include <common.h>
 #include <dm.h>
+#include <errno.h>
 #include <pci.h>
 #include <asm/test.h>
 #include <linux/ctype.h>
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#39 lore raw

PATCH 15/24 sandbox: Add missing errno.h includes in a few files

Quoted 9 lines · Simon Glass

These files use error numbering, so add the include.

---

 arch/sandbox/cpu/start.c       | 1 +
 drivers/misc/i2c_eeprom_emul.c | 1 +
 drivers/misc/swap_case.c       | 1 +
 3 files changed, 3 insertions(+)

Applied to u-boot-dm.

#40 lore raw

PATCH 16/24 sandbox: cros_ec: Support EC_CMD_ENTERING_MODE emulation

In reply to Simon Glass

Emualate this function which is used with Chrome OS verified boot.

---

 drivers/misc/cros_ec_sandbox.c |  2 ++
 include/ec_commands.h          | 15 +++++++++++++++
 2 files changed, 17 insertions(+)
drivers/misc/cros_ec_sandbox.c +2 -0
index df41e82..7509612 100644
@@ -459,6 +459,8 @@ static int process_cmd(struct ec_state *ec,
 	case EC_CMD_MKBP_STATE:
 		len = cros_ec_keyscan(ec, resp_data);
 		break;
+	case EC_CMD_ENTERING_MODE:
+		break;
 	default:
 		printf("   ** Unknown EC command %#02x\n", req_hdr->command);
 		return -1;
include/ec_commands.h +15 -0
index 78baab1..7605066 100644
@@ -1555,6 +1555,21 @@ struct ec_params_sb_wr_block {
 	uint16_t data[32];
 } __packed;
 
+/*
+ * Entering Verified Boot Mode Command
+ * Default mode is VBOOT_MODE_NORMAL if EC did not receive this command.
+ * Valid Modes are: normal, developer, and recovery.
+ */
+#define EC_CMD_ENTERING_MODE 0xb6
+
+struct ec_params_entering_mode {
+	int vboot_mode;
+} __packed;
+
+#define VBOOT_MODE_NORMAL    0
+#define VBOOT_MODE_DEVELOPER 1
+#define VBOOT_MODE_RECOVERY  2
+
 /*****************************************************************************/
 /* System commands */
 
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#41 lore raw

PATCH 16/24 sandbox: cros_ec: Support EC_CMD_ENTERING_MODE emulation

Quoted 9 lines · Simon Glass

Emualate this function which is used with Chrome OS verified boot.

---

 drivers/misc/cros_ec_sandbox.c |  2 ++
 include/ec_commands.h          | 15 +++++++++++++++
 2 files changed, 17 insertions(+)

Applied to u-boot-dm.

#42 lore raw

PATCH 17/24 sandbox: spi: Add newline to printf() in sandbox_sf_probe

In reply to Simon Glass

This printf() should have a newline at the end. Add it.

---

 drivers/mtd/spi/sandbox.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mtd/spi/sandbox.c +1 -1
index d576d31..895604d 100644
@@ -129,7 +129,7 @@ static int sandbox_sf_probe(struct udevice *dev)
 		}
 	}
 	if (cs == -1) {
-		printf("Error: Unknown chip select for device '%s'",
+		printf("Error: Unknown chip select for device '%s'\n",
 		       dev->name);
 		return -EINVAL;
 	}
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#46 lore raw

PATCH 18/24 sandbox: Fix warning in display_options

In reply to Simon Glass

This fixes a warning in the print_buffer() function with some toolchains.

---

 lib/display_options.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
lib/display_options.c +1 -1
index d5d17b2..495a547 100644
@@ -123,7 +123,7 @@ int print_buffer(ulong addr, const void *data, uint width, uint count,
 			else
 				x = lb.uc[i] = *(volatile uint8_t *)data;
 #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
-			printf(" %0*" PRIx64, width * 2, x);
+			printf(" %0*llx", width * 2, (long long)x);
 #else
 			printf(" %0*x", width * 2, x);
 #endif
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#49 lore raw

PATCH 19/24 sandbox: Support wide-screen LCD emulation

In reply to Simon Glass

Increase the LCD size to 1366x768.

---

 arch/sandbox/dts/sandbox.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/sandbox/dts/sandbox.dts +2 -2
index efa2097..6bfa735 100644
@@ -70,8 +70,8 @@
 
 	lcd {
 		compatible = "sandbox,lcd-sdl";
-		xres = <800>;
-		yres = <600>;
+		xres = <1366>;
+		yres = <768>;
 	};
 
 	gpio_a: gpios at 0 {
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#50 lore raw

PATCH 19/24 sandbox: Support wide-screen LCD emulation

Hi Simon,

Quoted 4 lines · Simon Glass

Increase the LCD size to 1366x768.

---

Is this actually emulated somehow? Maybe I just don't see it since I'm SSH'ed into my build machine?

Thanks,
-Joe

#51 lore raw

PATCH 19/24 sandbox: Support wide-screen LCD emulation

Hi Joe,

Quoted 10 lines · Joe Hershberger

Hi Simon,

Quoted 4 lines · Simon Glass

Increase the LCD size to 1366x768.

---

Is this actually emulated somehow? Maybe I just don't see it since I'm SSH'ed into my build machine?

Yes, plus you need the -l option.

Regards,
Simon

#52 lore raw

PATCH 19/24 sandbox: Support wide-screen LCD emulation

Quoted 11 lines · Simon Glass

Hi Joe,

Quoted 8 lines · Joe Hershberger

Hi Simon,

Quoted 4 lines · Simon Glass

Increase the LCD size to 1366x768.

---

Quoted 7 lines
Quoted 2 lines

Is this actually emulated somehow? Maybe I just don't see it since I'm SSH'ed into my build machine?

Yes, plus you need the -l option.

Regards,
Simon

Applied to u-boot-dm.

#53 lore raw

PATCH 20/24 lcd: Support colour lookup table on 16bpp display in BMP images

In reply to Simon Glass

For 16-bit-per-pixel displays it is useful to support 8 bit-per-pixel images to reduce image size. Add support for this when drawing BMP images.

---

 common/lcd.c         | 23 ++++++++++++++++++++---
 include/bmp_layout.h |  4 ++--
 2 files changed, 22 insertions(+), 5 deletions(-)
common/lcd.c +20 -3
index 055c366..2d11578 100644
@@ -578,6 +578,8 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
 	unsigned long width, height, byte_width;
 	unsigned long pwidth = panel_info.vl_col;
 	unsigned colors, bpix, bmp_bpix;
+	int hdr_size;
+	bmp_color_table_entry_t *palette = bmp->color_table;
 
 	if (!bmp || !(bmp->header.signature[0] == 'B' &&
 		bmp->header.signature[1] == 'M')) {
@@ -589,6 +591,8 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
 	width = get_unaligned_le32(&bmp->header.width);
 	height = get_unaligned_le32(&bmp->header.height);
 	bmp_bpix = get_unaligned_le16(&bmp->header.bit_count);
+	hdr_size = get_unaligned_le16(&bmp->header.size);
+	debug("hdr_size=%d, bmp_bpix=%d\n", hdr_size, bmp_bpix);
 
 	colors = 1 << bmp_bpix;
 
@@ -613,8 +617,8 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
 		return 1;
 	}
 
-	debug("Display-bmp: %d x %d  with %d colors\n",
-		(int)width, (int)height, (int)colors);
+	debug("Display-bmp: %d x %d  with %d colors, display %d\n",
+	      (int)width, (int)height, (int)colors, 1 << bpix);
 
 	if (bmp_bpix == 8)
 		lcd_set_cmap(bmp, colors);
@@ -641,6 +645,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
 		cmap_base = configuration_get_cmap();
 #ifdef CONFIG_LCD_BMP_RLE8
 		u32 compression = get_unaligned_le32(&bmp->header.compression);
+		debug("compressed %d %d\n", compression, BMP_BI_RLE8);
 		if (compression == BMP_BI_RLE8) {
 			if (bpix != 16) {
 				/* TODO implement render code for bpix != 16 */
@@ -663,7 +668,19 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
 				if (bpix != 16) {
 					fb_put_byte(&fb, &bmap);
 				} else {
-					*(uint16_t *)fb = cmap_base[*(bmap++)];
+					struct bmp_color_table_entry *entry;
+					uint val;
+
+					if (cmap_base) {
+						val = cmap_base[*bmap];
+					} else {
+						entry = &palette[*bmap];
+						val = entry->blue >> 3 |
+							entry->green >> 2 << 5 |
+							entry->red >> 3 << 11;
+					}
+					*(uint16_t *)fb = val;
+					bmap++;
 					fb += sizeof(uint16_t) / sizeof(*fb);
 				}
 			}
include/bmp_layout.h +2 -2
index 22b1fbc..47f505c 100644
@@ -11,12 +11,12 @@
 #ifndef _BMP_H_
 #define _BMP_H_
 
-typedef struct bmp_color_table_entry {
+typedef struct __packed bmp_color_table_entry {
 	__u8	blue;
 	__u8	green;
 	__u8	red;
 	__u8	reserved;
-} __attribute__ ((packed)) bmp_color_table_entry_t;
+} bmp_color_table_entry_t;
 
 /* When accessing these fields, remember that they are stored in little
    endian format, so use linux macros, e.g. le32_to_cpu(width)          */
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#54 lore raw

PATCH 20/24 lcd: Support colour lookup table on 16bpp display in BMP images

Hi Simon,

Quoted 77 lines · Simon Glass

For 16-bit-per-pixel displays it is useful to support 8 bit-per-pixel images to reduce image size. Add support for this when drawing BMP images.

---

 common/lcd.c         | 23 ++++++++++++++++++++---
 include/bmp_layout.h |  4 ++--
 2 files changed, 22 insertions(+), 5 deletions(-)
common/lcd.c +20 -3
index 055c366..2d11578 100644
@@ -578,6 +578,8 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
        unsigned long width, height, byte_width;
        unsigned long pwidth = panel_info.vl_col;
        unsigned colors, bpix, bmp_bpix;
+       int hdr_size;
+       bmp_color_table_entry_t *palette = bmp->color_table;
 
        if (!bmp || !(bmp->header.signature[0] == 'B' &&
                bmp->header.signature[1] == 'M')) {
@@ -589,6 +591,8 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
        width = get_unaligned_le32(&bmp->header.width);
        height = get_unaligned_le32(&bmp->header.height);
        bmp_bpix = get_unaligned_le16(&bmp->header.bit_count);
+       hdr_size = get_unaligned_le16(&bmp->header.size);
+       debug("hdr_size=%d, bmp_bpix=%d\n", hdr_size, bmp_bpix);
 
        colors = 1 << bmp_bpix;
 
@@ -613,8 +617,8 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
                return 1;
        }
 
-       debug("Display-bmp: %d x %d  with %d colors\n",
-               (int)width, (int)height, (int)colors);
+       debug("Display-bmp: %d x %d  with %d colors, display %d\n",
+             (int)width, (int)height, (int)colors, 1 << bpix);
 
        if (bmp_bpix == 8)
                lcd_set_cmap(bmp, colors);
@@ -641,6 +645,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
                cmap_base = configuration_get_cmap();
 #ifdef CONFIG_LCD_BMP_RLE8
                u32 compression = get_unaligned_le32(&bmp->header.compression);
+               debug("compressed %d %d\n", compression, BMP_BI_RLE8);
                if (compression == BMP_BI_RLE8) {
                        if (bpix != 16) {
                                /* TODO implement render code for bpix != 16 */
@@ -663,7 +668,19 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
                                if (bpix != 16) {
                                        fb_put_byte(&fb, &bmap);
                                } else {
-                                       *(uint16_t *)fb = cmap_base[*(bmap++)];
+                                       struct bmp_color_table_entry *entry;
+                                       uint val;
+
+                                       if (cmap_base) {
+                                               val = cmap_base[*bmap];
+                                       } else {
+                                               entry = &palette[*bmap];
+                                               val = entry->blue >> 3 |
+                                                       entry->green >> 2 << 5 |
+                                                       entry->red >> 3 << 11;
+                                       }
+                                       *(uint16_t *)fb = val;
+                                       bmap++;
                                        fb += sizeof(uint16_t) / sizeof(*fb);
                                }
                        }
include/bmp_layout.h +0 -0
index 22b1fbc..47f505c 100644

include/bmp_layout.h line 14

Quoted 5 lines
include/bmp_layout.h +1 -1
@@ -11,12 +11,12 @@
 #ifndef _BMP_H_
 #define _BMP_H_
 
-typedef struct bmp_color_table_entry {
+typedef struct __packed bmp_color_table_entry {

It would be great to drop the typedef here.

include/bmp_layout.h

Quoted 10 lines
include/bmp_layout.h +1 -2
        __u8    blue;
        __u8    green;
        __u8    red;
        __u8    reserved;
-} __attribute__ ((packed)) bmp_color_table_entry_t;
+} bmp_color_table_entry_t;
 
 /* When accessing these fields, remember that they are stored in little
    endian format, so use linux macros, e.g. le32_to_cpu(width)          */
--

Cheers,
-Joe

#55 lore raw

PATCH 21/24 tegra124: Implement spl_was_boot_source()

In reply to Simon Glass

Add an implementation of this function for Tegra.

---

 arch/arm/mach-tegra/board.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
arch/arm/mach-tegra/board.c +16 -0
index 222de6a..77be211 100644
@@ -6,6 +6,7 @@
  */
 
 #include <common.h>
+#include <spl.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/funcmux.h>
@@ -29,6 +30,21 @@ enum {
 	UART_COUNT = 5,
 };
 
+static bool from_spl __attribute__ ((section(".data")));
+
+#ifndef CONFIG_SPL_BUILD
+void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3)
+{
+	from_spl = r0 != SPL_RUNNING_FROM_UBOOT;
+	save_boot_params_ret();
+}
+#endif
+
+bool spl_was_boot_source(void)
+{
+	return from_spl;
+}
+
 #if defined(CONFIG_TEGRA_SUPPORT_NON_SECURE)
 #if !defined(CONFIG_TEGRA124)
 #error tegra_cpu_is_non_secure has only been validated on Tegra124
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#56 lore raw

PATCH 21/24 tegra124: Implement spl_was_boot_source()

arch/arm/mach-tegra/board.c enum { · line 41

Quoted 11 lines · Simon Glass

Add an implementation of this function for Tegra.

arch/arm/mach-tegra/board.c +7 -0
 
+#ifndef CONFIG_SPL_BUILD
+void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3)
+{
+	from_spl = r0 != SPL_RUNNING_FROM_UBOOT;
+	save_boot_params_ret();
+}
+#endif

(Using terminology from:
https://patchwork.ozlabs.org/patch/467771/
arm: spl: Enable detecting when U-Boot is started from SPL )

That doesn't look right. Surely (at least on Tegra), if the r/o U-Boot chain-loads to the r/w U-Boot, then the chain-loaded U-Boot has no SPL and is just the main CPU build of U-Boot.

Hence, "SPL_RUNNING_FROM_UBOOT" seems incorrectly named, since the r/o U-Boot doesn't chain to SPL but rather to U-Boot.

This approach sounds a little brittle; what happens if r0 just happens to have that value. Won't the code get confused?

Why does U-Boot care whether it's been chain-loaded? Shouldn't it always behave identically in all cases, so it's independent of what caused it to run?

#57 lore raw

PATCH 21/24 tegra124: Implement spl_was_boot_source()

Hi Stephen,

Quoted 22 lines · Stephen Warren
Quoted 5 lines · Simon Glass

Add an implementation of this function for Tegra.

arch/arm/mach-tegra/board.c enum { · line 41

Quoted 9 lines
arch/arm/mach-tegra/board.c +7 -0
 
 
+#ifndef CONFIG_SPL_BUILD
+void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3)
+{
+       from_spl = r0 != SPL_RUNNING_FROM_UBOOT;
+       save_boot_params_ret();
+}
+#endif

(Using terminology from:
https://patchwork.ozlabs.org/patch/467771/
arm: spl: Enable detecting when U-Boot is started from SPL )

Quoted 6 lines

That doesn't look right. Surely (at least on Tegra), if the r/o U-Boot chain-loads to the r/w U-Boot, then the chain-loaded U-Boot has no SPL and is just the main CPU build of U-Boot.

Hence, "SPL_RUNNING_FROM_UBOOT" seems incorrectly named, since the r/o U-Boot doesn't chain to SPL but rather to U-Boot.

What name do you suggest? I was trying to add a prefix indicating that it relates to non-SPL start-up of U-Boot.

Quoted 3 lines

This approach sounds a little brittle; what happens if r0 just happens to have that value. Won't the code get confused?

Yes, but SPL does not set that value in r0, and we have control over this.

Quoted 4 lines

Why does U-Boot care whether it's been chain-loaded? Shouldn't it always behave identically in all cases, so it's independent of what caused it to run?

In the case of read-only U-Boot it must find the read-write one to jump to. In the case of read-write U-Boot it must boot a kernel.

Regards,
Simon

#58 lore raw

PATCH 21/24 tegra124: Implement spl_was_boot_source()

Quoted 29 lines · Simon Glass

Hi Stephen,

Quoted 26 lines · Stephen Warren
Quoted 5 lines · Simon Glass

Add an implementation of this function for Tegra.

arch/arm/mach-tegra/board.c enum { · line 41

Quoted 9 lines
arch/arm/mach-tegra/board.c +7 -0
 
 
+#ifndef CONFIG_SPL_BUILD
+void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3)
+{
+       from_spl = r0 != SPL_RUNNING_FROM_UBOOT;
+       save_boot_params_ret();
+}
+#endif

(Using terminology from:
https://patchwork.ozlabs.org/patch/467771/
arm: spl: Enable detecting when U-Boot is started from SPL )

That doesn't look right. Surely (at least on Tegra), if the r/o U-Boot chain-loads to the r/w U-Boot, then the chain-loaded U-Boot has no SPL and is just the main CPU build of U-Boot.

Quoted 5 lines
Quoted 2 lines

Hence, "SPL_RUNNING_FROM_UBOOT" seems incorrectly named, since the r/o U-Boot doesn't chain to SPL but rather to U-Boot.

What name do you suggest? I was trying to add a prefix indicating that it relates to non-SPL start-up of U-Boot.

Well, that name specifically states that it's SPL that's running, whereas the exact opposite is true.

Perhaps UBOOT_CHAIN_LOADED_FROM_UBOOT?

Quoted 11 lines
Quoted 2 lines

This approach sounds a little brittle; what happens if r0 just happens to have that value. Won't the code get confused?

Yes, but SPL does not set that value in r0, and we have control over this.

Quoted 3 lines

Why does U-Boot care whether it's been chain-loaded? Shouldn't it always behave identically in all cases, so it's independent of what caused it to run?

In the case of read-only U-Boot it must find the read-write one to jump to. In the case of read-write U-Boot it must boot a kernel.

Surely that should be taken care of by placing the correct boot scripts into the U-Boot environment, rather than hard-coding specific boot behaviour into the U-Boot binary?

This feature seems really use-case-specific; I wonder if it's useful/generic-enough to upstream even?

#59 lore raw

PATCH 21/24 tegra124: Implement spl_was_boot_source()

Hi Stephen,

Quoted 41 lines · Stephen Warren
Quoted 40 lines · Simon Glass

Hi Stephen,

Quoted 34 lines · Stephen Warren
Quoted 7 lines · Simon Glass

Add an implementation of this function for Tegra.

arch/arm/mach-tegra/board.c enum { · line 41

Quoted 10 lines
arch/arm/mach-tegra/board.c +7 -0
 
 
 
+#ifndef CONFIG_SPL_BUILD
+void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3)
+{
+       from_spl = r0 != SPL_RUNNING_FROM_UBOOT;
+       save_boot_params_ret();
+}
+#endif

(Using terminology from:
https://patchwork.ozlabs.org/patch/467771/
arm: spl: Enable detecting when U-Boot is started from SPL )

That doesn't look right. Surely (at least on Tegra), if the r/o U-Boot chain-loads to the r/w U-Boot, then the chain-loaded U-Boot has no SPL and
is just the main CPU build of U-Boot.

Hence, "SPL_RUNNING_FROM_UBOOT" seems incorrectly named, since the r/o U-Boot doesn't chain to SPL but rather to U-Boot.

Quoted 8 lines
Quoted 2 lines

What name do you suggest? I was trying to add a prefix indicating that it relates to non-SPL start-up of U-Boot.

Well, that name specifically states that it's SPL that's running, whereas the exact opposite is true.

Perhaps UBOOT_CHAIN_LOADED_FROM_UBOOT?

I really want to say that it is not chain-loaded from SPL. Maybe UBOOT_NOT_LOADED_FROM_SPL?

Quoted 12 lines
Quoted 12 lines
Quoted 3 lines

This approach sounds a little brittle; what happens if r0 just happens to have that value. Won't the code get confused?

Yes, but SPL does not set that value in r0, and we have control over this.

Quoted 3 lines

Why does U-Boot care whether it's been chain-loaded? Shouldn't it always behave identically in all cases, so it's independent of what caused it to run?

Quoted 7 lines
Quoted 2 lines

In the case of read-only U-Boot it must find the read-write one to jump to. In the case of read-write U-Boot it must boot a kernel.

Surely that should be taken care of by placing the correct boot scripts into the U-Boot environment, rather than hard-coding specific boot behaviour into the U-Boot binary?

Two problems here:

1. The two U-Boot will use the same environment (as they are identical after all)

2. Loading the environment is a security risk (since anyone can change it in Linux, for example) so cannot be loaded.

Quoted 2 lines

This feature seems really use-case-specific; I wonder if it's useful/generic-enough to upstream even?

I am keen to upstream this use case (upgrading U-Boot in a secure way) as I think it has wide application.

Regards,
Simon

#60 lore raw

PATCH 21/24 tegra124: Implement spl_was_boot_source()

Quoted 48 lines · Simon Glass

Hi Stephen,

Quoted 45 lines · Stephen Warren
Quoted 42 lines · Simon Glass

Hi Stephen,

Quoted 27 lines · Stephen Warren
Quoted 7 lines · Simon Glass

Add an implementation of this function for Tegra.

arch/arm/mach-tegra/board.c enum { · line 41

Quoted 10 lines
arch/arm/mach-tegra/board.c +7 -0
 
 
 
+#ifndef CONFIG_SPL_BUILD
+void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3)
+{
+       from_spl = r0 != SPL_RUNNING_FROM_UBOOT;
+       save_boot_params_ret();
+}
+#endif

(Using terminology from:
https://patchwork.ozlabs.org/patch/467771/
arm: spl: Enable detecting when U-Boot is started from SPL )

Quoted 7 lines

That doesn't look right. Surely (at least on Tegra), if the r/o U-Boot chain-loads to the r/w U-Boot, then the chain-loaded U-Boot has no SPL and
is just the main CPU build of U-Boot.

Hence, "SPL_RUNNING_FROM_UBOOT" seems incorrectly named, since the r/o U-Boot doesn't chain to SPL but rather to U-Boot.

What name do you suggest? I was trying to add a prefix indicating that it relates to non-SPL start-up of U-Boot.

Quoted 7 lines
Quoted 4 lines

Well, that name specifically states that it's SPL that's running, whereas the exact opposite is true.

Perhaps UBOOT_CHAIN_LOADED_FROM_UBOOT?

I really want to say that it is not chain-loaded from SPL. Maybe UBOOT_NOT_LOADED_FROM_SPL?

OK, that highlights that better.

Quoted 15 lines
Quoted 15 lines
Quoted 13 lines
Quoted 2 lines

This approach sounds a little brittle; what happens if r0 just happens to have that value. Won't the code get confused?

Yes, but SPL does not set that value in r0, and we have control over this.

Quoted 3 lines

Why does U-Boot care whether it's been chain-loaded? Shouldn't it always behave identically in all cases, so it's independent of what caused it to run?

In the case of read-only U-Boot it must find the read-write one to jump to. In the case of read-write U-Boot it must boot a kernel.

Quoted 8 lines
Quoted 3 lines

Surely that should be taken care of by placing the correct boot scripts into the U-Boot environment, rather than hard-coding specific boot behaviour into the U-Boot binary?

Two problems here:

1. The two U-Boot will use the same environment (as they are identical after all)

That's a design decision. There's absolutely no need for that to be true.

Quoted 2 lines

2. Loading the environment is a security risk (since anyone can change it in Linux, for example) so cannot be loaded.

Well, the environment could be the default/built-in environment and hence validated as part of the validation of the U-Boot binary. Or, even if loaded separately, could also be validated in the same way (but perhaps there's not much point in that, since a fall-back to the built-in environment would be required in case the external environment validation failed).

Quoted 5 lines
Quoted 2 lines

This feature seems really use-case-specific; I wonder if it's useful/generic-enough to upstream even?

I am keen to upstream this use case (upgrading U-Boot in a secure way) as I think it has wide application.

OK. I worry that there are many many possible ways of doing that, and the selection of the best option depends on the system use-cases, security model, and environments. We might not want to lock people into a specific method. So long as the existence of this code doesn't prevent doing things some other way if they need, or upstreaming support for other methods, nor make the code too complex, then it's probably fine.

#61 lore raw

PATCH 21/24 tegra124: Implement spl_was_boot_source()

Hi Stephen,

Quoted 100 lines · Stephen Warren
Quoted 58 lines · Simon Glass

Hi Stephen,

Quoted 54 lines · Stephen Warren
Quoted 49 lines · Simon Glass

Hi Stephen,

Quoted 32 lines · Stephen Warren
Quoted 10 lines · Simon Glass

Add an implementation of this function for Tegra.

arch/arm/mach-tegra/board.c +0 -0
 

arch/arm/mach-tegra/board.c enum { · line 41

Quoted 10 lines
arch/arm/mach-tegra/board.c +7 -0
 
 
 
+#ifndef CONFIG_SPL_BUILD
+void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3)
+{
+       from_spl = r0 != SPL_RUNNING_FROM_UBOOT;
+       save_boot_params_ret();
+}
+#endif

(Using terminology from:
https://patchwork.ozlabs.org/patch/467771/
arm: spl: Enable detecting when U-Boot is started from SPL )

Quoted 7 lines

That doesn't look right. Surely (at least on Tegra), if the r/o U-Boot chain-loads to the r/w U-Boot, then the chain-loaded U-Boot has no SPL and
is just the main CPU build of U-Boot.

Hence, "SPL_RUNNING_FROM_UBOOT" seems incorrectly named, since the r/o U-Boot doesn't chain to SPL but rather to U-Boot.

What name do you suggest? I was trying to add a prefix indicating that it relates to non-SPL start-up of U-Boot.

Quoted 8 lines
Quoted 4 lines

Well, that name specifically states that it's SPL that's running, whereas the exact opposite is true.

Perhaps UBOOT_CHAIN_LOADED_FROM_UBOOT?

I really want to say that it is not chain-loaded from SPL. Maybe UBOOT_NOT_LOADED_FROM_SPL?

OK, that highlights that better.

Quoted 29 lines
Quoted 27 lines
Quoted 17 lines
Quoted 3 lines

This approach sounds a little brittle; what happens if r0 just happens to
have that value. Won't the code get confused?

Yes, but SPL does not set that value in r0, and we have control over this.

Quoted 5 lines

Why does U-Boot care whether it's been chain-loaded? Shouldn't it always
behave identically in all cases, so it's independent of what caused it to
run?

Quoted 2 lines

In the case of read-only U-Boot it must find the read-write one to jump to. In the case of read-write U-Boot it must boot a kernel.

Surely that should be taken care of by placing the correct boot scripts into
the U-Boot environment, rather than hard-coding specific boot behaviour into
the U-Boot binary?

Quoted 7 lines
Quoted 4 lines

Two problems here:

1. The two U-Boot will use the same environment (as they are identical after all)

That's a design decision. There's absolutely no need for that to be true.

At present U-Boot has a single CONFIG for the environment type/position. Therefore we can't have the same U-Boot behave differently.

Quoted 10 lines
Quoted 3 lines

2. Loading the environment is a security risk (since anyone can change it in Linux, for example) so cannot be loaded.

Well, the environment could be the default/built-in environment and hence validated as part of the validation of the U-Boot binary. Or, even if loaded separately, could also be validated in the same way (but perhaps there's not much point in that, since a fall-back to the built-in environment would be required in case the external environment validation failed).

That's why we have the load-env device tree option, which uses the default environment. But since the RO and RW U-Boot then have the same environment, this doesn't really help.

Yes we could validate it, although it's a pain since it is one more thing to sign and hash and it's not in the FIT.

Quoted 9 lines
Quoted 7 lines
Quoted 3 lines

This feature seems really use-case-specific; I wonder if it's useful/generic-enough to upstream even?

I am keen to upstream this use case (upgrading U-Boot in a secure way) as I think it has wide application.

Quoted 6 lines

OK. I worry that there are many many possible ways of doing that, and the selection of the best option depends on the system use-cases, security model, and environments. We might not want to lock people into a specific method. So long as the existence of this code doesn't prevent doing things some other way if they need, or upstreaming support for other methods, nor make the code too complex, then it's probably fine.

This seems pretty simple to me.

Regards,
Simon

#62 lore raw

PATCH 22/24 tegra: nyan-big: Allow TPM on I2C

In reply to Simon Glass

Enable the I2C3 pins so that the TPM can be used.

---

 board/nvidia/nyan-big/pinmux-config-nyan-big.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
board/nvidia/nyan-big/pinmux-config-nyan-big.h +2 -2
index 9c5fbaa..ddf572f 100644
@@ -234,8 +234,8 @@ static const struct pmux_pingrp_config nyan_big_pingrps[] = {
 	PINCFG(SDMMC4_DAT6_PAA6,       SDMMC4,      UP,     NORMAL,   INPUT,   DEFAULT, DEFAULT),
 	PINCFG(SDMMC4_DAT7_PAA7,       SDMMC4,      UP,     NORMAL,   INPUT,   DEFAULT, DEFAULT),
 	PINCFG(PBB0,                   VGP6,        DOWN,   TRISTATE, OUTPUT,  DEFAULT, DEFAULT),
-	PINCFG(CAM_I2C_SCL_PBB1,       RSVD3,       DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(CAM_I2C_SDA_PBB2,       RSVD3,       DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
+	PINCFG(CAM_I2C_SCL_PBB1,       I2C3,        NORMAL, NORMAL,   INPUT,   ENABLE,  DEFAULT),
+	PINCFG(CAM_I2C_SDA_PBB2,       I2C3,        NORMAL, NORMAL,   INPUT,   ENABLE,  DEFAULT),
 	PINCFG(PBB3,                   VGP3,        DOWN,   TRISTATE, OUTPUT,  DEFAULT, DEFAULT),
 	PINCFG(PBB4,                   VGP4,        DOWN,   TRISTATE, OUTPUT,  DEFAULT, DEFAULT),
 	PINCFG(PBB5,                   RSVD3,       DOWN,   TRISTATE, OUTPUT,  DEFAULT, DEFAULT),
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#63 lore raw

PATCH 22/24 tegra: nyan-big: Allow TPM on I2C

Quoted 1 line · Simon Glass

Enable the I2C3 pins so that the TPM can be used.

Can you please update the configuration in tegra-pinmux-scripts and the Linux kernel DT too, then?

#64 lore raw

PATCH 23/24 tegra: mmc: Set the removable flag correctly

In reply to Simon Glass

If the mmc device is non-removable (as indicated by the device tree), set the flag so that users of the device know.

---

 drivers/mmc/tegra_mmc.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/mmc/tegra_mmc.c +8 -4
index 2cd8cf1..5c9c54a 100644
@@ -528,7 +528,7 @@ static const struct mmc_ops tegra_mmc_ops = {
 	.getcd		= tegra_mmc_getcd,
 };
 
-static int do_mmc_init(int dev_index)
+static int do_mmc_init(int dev_index, bool removable)
 {
 	struct mmc_host *host;
 	struct mmc *mmc;
@@ -573,6 +573,7 @@ static int do_mmc_init(int dev_index)
 	host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
 
 	mmc = mmc_create(&host->cfg, host);
+	mmc->block_dev.removable = removable;
 	if (mmc == NULL)
 		return -1;
 
@@ -586,7 +587,8 @@ static int do_mmc_init(int dev_index)
  * @param node		Device index (0-3)
  * @param host		Structure to fill in (reg, width, mmc_id)
  */
-static int mmc_get_config(const void *blob, int node, struct mmc_host *host)
+static int mmc_get_config(const void *blob, int node, struct mmc_host *host,
+			  bool *removablep)
 {
 	debug("%s: node = %d\n", __func__, node);
 
@@ -619,6 +621,7 @@ static int mmc_get_config(const void *blob, int node, struct mmc_host *host)
 				   GPIOD_IS_IN);
 	gpio_request_by_name_nodev(blob, node, "power-gpios", 0,
 				   &host->pwr_gpio, GPIOD_IS_OUT);
+	*removablep = !fdtdec_get_bool(blob, node, "non-removable");
 
 	debug("%s: found controller at %p, width = %d, periph_id = %d\n",
 		__func__, host->reg, host->width, host->mmc_id);
@@ -636,6 +639,7 @@ static int mmc_get_config(const void *blob, int node, struct mmc_host *host)
 static int process_nodes(const void *blob, int node_list[], int count)
 {
 	struct mmc_host *host;
+	bool removable;
 	int i, node;
 
 	debug("%s: count = %d\n", __func__, count);
@@ -649,11 +653,11 @@ static int process_nodes(const void *blob, int node_list[], int count)
 		host = &mmc_host[i];
 		host->id = i;
 
-		if (mmc_get_config(blob, node, host)) {
+		if (mmc_get_config(blob, node, host, &removable)) {
 			printf("%s: failed to decode dev %d\n",	__func__, i);
 			return -1;
 		}
-		do_mmc_init(i);
+		do_mmc_init(i, removable);
 	}
 	return 0;
 }
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#66 lore raw

PATCH 23/24 tegra: mmc: Set the removable flag correctly

In reply to Simon Glass

Hi Simon,

Quoted 75 lines · Simon Glass

If the mmc device is non-removable (as indicated by the device tree), set the flag so that users of the device know.

---

drivers/mmc/tegra_mmc.c | 12 ++++++++----

1 file changed, 8 insertions(+), 4 deletions(-)
drivers/mmc/tegra_mmc.c +8 -4
index 2cd8cf1..5c9c54a 100644
@@ -528,7 +528,7 @@ static const struct mmc_ops tegra_mmc_ops = {
 	.getcd		= tegra_mmc_getcd,
 };
 
-static int do_mmc_init(int dev_index)
+static int do_mmc_init(int dev_index, bool removable)
 {
 	struct mmc_host *host;
 	struct mmc *mmc;
@@ -573,6 +573,7 @@ static int do_mmc_init(int dev_index)
 	host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
 
 	mmc = mmc_create(&host->cfg, host);
+	mmc->block_dev.removable = removable;
 	if (mmc == NULL)
 		return -1;
 
@@ -586,7 +587,8 @@ static int do_mmc_init(int dev_index)
 * @param node		Device index (0-3)
 * @param host		Structure to fill in (reg, width, mmc_id)
 */
-static int mmc_get_config(const void *blob, int node, struct mmc_host *host)
+static int mmc_get_config(const void *blob, int node, struct mmc_host *host,
+			  bool *removablep)
 {
 	debug("%s: node = %d\n", __func__, node);
 
@@ -619,6 +621,7 @@ static int mmc_get_config(const void *blob, int node, struct mmc_host *host)
 				   GPIOD_IS_IN);
 	gpio_request_by_name_nodev(blob, node, "power-gpios", 0,
 				   &host->pwr_gpio, GPIOD_IS_OUT);
+	*removablep = !fdtdec_get_bool(blob, node, "non-removable");
 
 	debug("%s: found controller at %p, width = %d, periph_id = %d\n",
 		__func__, host->reg, host->width, host->mmc_id);
@@ -636,6 +639,7 @@ static int mmc_get_config(const void *blob, int node, struct mmc_host *host)
 static int process_nodes(const void *blob, int node_list[], int count)
 {
 	struct mmc_host *host;
+	bool removable;
 	int i, node;
 
 	debug("%s: count = %d\n", __func__, count);
@@ -649,11 +653,11 @@ static int process_nodes(const void *blob, int node_list[], int count)
 		host = &mmc_host[i];
 		host->id = i;
 
-		if (mmc_get_config(blob, node, host)) {
+		if (mmc_get_config(blob, node, host, &removable)) {
 			printf("%s: failed to decode dev %d\n",	__func__, i);
 			return -1;
 		}
-		do_mmc_init(i);
+		do_mmc_init(i, removable);
 	}
 	return 0;
 }
Signature · 1 line
2.2.0.rc0.207.ga3a616c

Applied, thanks.

? Pantelis

#67 lore raw

PATCH 24/24 tegra124: Expand SPL space by 8KB

In reply to Simon Glass

We are getting very close to running out of space in SPL, and with the currently Chrome OS gcc 4.9 we exceed the limit. Add a litle more space.

---

 include/configs/tegra124-common.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/configs/tegra124-common.h +1 -1
index f2b3774..0347132 100644
@@ -30,7 +30,7 @@
 /*-----------------------------------------------------------------------
  * Physical Memory Map
  */
-#define CONFIG_SYS_TEXT_BASE	0x8010E000
+#define CONFIG_SYS_TEXT_BASE	0x80110000
 
 /*
  * Memory layout for where various images get loaded by boot scripts:
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#68 lore raw

PATCH 24/24 tegra124: Expand SPL space by 8KB

Quoted 2 lines · Simon Glass

We are getting very close to running out of space in SPL, and with the currently Chrome OS gcc 4.9 we exceed the limit. Add a litle more space.

8K is quite a bump given we only had 24K allocated before. Why is gcc-4.9 less efficient that earlier compilers I wonder? Were we extremely close to the limit ebfore? Still, I guess this is fine.

Did you validate whether tegra-uboot-flasher still works with this change? I think it will since it only cares about the SPL TEXT_BASE and not the main U-Boot TEXT_BASE, but double-checking would be nice.

You forgot to CC Tom Warren on this Tegra patch.

#69 lore raw

PATCH 24/24 tegra124: Expand SPL space by 8KB

Hi Stephen,

Quoted 6 lines · Stephen Warren
Quoted 3 lines · Simon Glass

We are getting very close to running out of space in SPL, and with the currently Chrome OS gcc 4.9 we exceed the limit. Add a litle more space.

Quoted 7 lines

8K is quite a bump given we only had 24K allocated before. Why is gcc-4.9 less efficient that earlier compilers I wonder? Were we extremely close to the limit ebfore? Still, I guess this is fine.

Did you validate whether tegra-uboot-flasher still works with this change? I think it will since it only cares about the SPL TEXT_BASE and not the main U-Boot TEXT_BASE, but double-checking would be nice.

I tested this with USB A-A (tegrarcm). Is that what you mean?

Quoted 2 lines

You forgot to CC Tom Warren on this Tegra patch.

Ooops, I should have used a 'tegra' tag.

Regards,
Simon

#70 lore raw

PATCH 24/24 tegra124: Expand SPL space by 8KB

Quoted 13 lines · Simon Glass

Hi Stephen,

Quoted 10 lines · Stephen Warren
Quoted 3 lines · Simon Glass

We are getting very close to running out of space in SPL, and with the currently Chrome OS gcc 4.9 we exceed the limit. Add a litle more space.

8K is quite a bump given we only had 24K allocated before. Why is gcc-4.9 less efficient that earlier compilers I wonder? Were we extremely close to the limit ebfore? Still, I guess this is fine.

Quoted 5 lines
Quoted 3 lines

Did you validate whether tegra-uboot-flasher still works with this change? I think it will since it only cares about the SPL TEXT_BASE and not the main U-Boot TEXT_BASE, but double-checking would be nice.

I tested this with USB A-A (tegrarcm). Is that what you mean?

Did you just use tegrarcm, or tegra-uboot-flasher? The latter is a wrapper on top of tegrarcm, and is a bit more involved. See the various READMEs at https://github.com/NVIDIA/tegra-uboot-flasher-scripts. This doesn't support any nyan-derived boards yet, but does support Jetson TK1 which I think you have?

#71 lore raw

PATCH 24/24 tegra124: Expand SPL space by 8KB

Hi Stephen,

Quoted 14 lines · Stephen Warren
Quoted 13 lines · Simon Glass

Hi Stephen,

Quoted 9 lines · Stephen Warren
Quoted 4 lines · Simon Glass

We are getting very close to running out of space in SPL, and with the currently Chrome OS gcc 4.9 we exceed the limit. Add a litle more space.

Quoted 4 lines
Quoted 4 lines
Quoted 4 lines

8K is quite a bump given we only had 24K allocated before. Why is gcc-4.9 less efficient that earlier compilers I wonder? Were we extremely close to
the limit ebfore? Still, I guess this is fine.

We were about 1KB away, mostly due to the gcc garbage collection bug I think. The cros compiler seems even worse, not sure why.

Quoted 8 lines
Quoted 8 lines
Quoted 6 lines

Did you validate whether tegra-uboot-flasher still works with this change? I
think it will since it only cares about the SPL TEXT_BASE and not the main
U-Boot TEXT_BASE, but double-checking would be nice.

Quoted 8 lines
Quoted 1 line

I tested this with USB A-A (tegrarcm). Is that what you mean?

Did you just use tegrarcm, or tegra-uboot-flasher? The latter is a wrapper on top of tegrarcm, and is a bit more involved. See the various READMEs at
https://github.com/NVIDIA/tegra-uboot-flasher-scripts. This doesn't support any nyan-derived boards yet, but does support Jetson TK1 which I think you have?

Ah, OK. The script at:

https://github.com/NVIDIA/tegra-uboot-flasher-scripts/blob/master/tegra-uboot-flasher

looks OK to me. It does not have anything hard-coded that I can see. But I have not used it myself. It's kind-of painful that we have all this out-of-tree Tegra stuff (pin mux also) that might break when we change U-Boot. Is there any way to improve this?

Regards,
Simon

#72 lore raw

PATCH 24/24 tegra124: Expand SPL space by 8KB

Quoted 41 lines · Simon Glass

Hi Stephen,

Quoted 14 lines · Stephen Warren
Quoted 13 lines · Simon Glass

Hi Stephen,

Quoted 9 lines · Stephen Warren
Quoted 4 lines · Simon Glass

We are getting very close to running out of space in SPL, and with the currently Chrome OS gcc 4.9 we exceed the limit. Add a litle more space.

Quoted 4 lines
Quoted 4 lines
Quoted 4 lines

8K is quite a bump given we only had 24K allocated before. Why is gcc-4.9 less efficient that earlier compilers I wonder? Were we extremely close to
the limit ebfore? Still, I guess this is fine.

We were about 1KB away, mostly due to the gcc garbage collection bug I think. The cros compiler seems even worse, not sure why.

Quoted 7 lines
Quoted 7 lines
Quoted 5 lines

Did you validate whether tegra-uboot-flasher still works with this change? I
think it will since it only cares about the SPL TEXT_BASE and not the main
U-Boot TEXT_BASE, but double-checking would be nice.

Quoted 8 lines
Quoted 1 line

I tested this with USB A-A (tegrarcm). Is that what you mean?

Did you just use tegrarcm, or tegra-uboot-flasher? The latter is a wrapper on top of tegrarcm, and is a bit more involved. See the various READMEs at
https://github.com/NVIDIA/tegra-uboot-flasher-scripts. This doesn't support any nyan-derived boards yet, but does support Jetson TK1 which I think you have?

Quoted 8 lines

Ah, OK. The script at:

https://github.com/NVIDIA/tegra-uboot-flasher-scripts/blob/master/tegra-uboot-flasher

looks OK to me. It does not have anything hard-coded that I can see. But I have not used it myself. It's kind-of painful that we have all this out-of-tree Tegra stuff (pin mux also) that might break when we change U-Boot. Is there any way to improve this?

I don't think there's anything to improve; nothing is wrong.

If something changes about the way U-Boot works or must be used, then that requires changes elsewhere no matter what. Whether the externals changes are:

* Updates to documentation of how to build/use/... U-Boot.
* Updates to the command-lines/techniques people know and use.
* Updates to code/tools that interface with U-Boot.

... then in all cases, a change to U-Boot requires a change to something else. I would argue that updating an external tool is actually the easiest of the cases, since it's entirely clear what that tool does, what change to make to it, and how. Conversely, updating the command-lines/techniques that people use is much harder to propagate to all people. The update-a-document case may also be about as easy, presuming you know which documents to update (there are probably more docs than tools at least at present).

In the pinmux case, please consider the system-level implications of a change to the pinmux. There is a single correct pinmux configuration for a given HW configuration, and that's driven purely by the HW design[1]. If the pinmux that U-Boot programs is wrong and needs to be changed, the same change should be propagated to all SW to fix the bug everywhere. The existence of the external Tegra pinmux tools makes that easier; update the pinmux tool, regenerate derived files for all SW stacks, and apply the changes everywhere. Sure it's more work to do that than just updating only U-Boot. However, the tool doesn't add that extra work, rather the change to the desired pinmux makes the work. The only alternative (which does indeed reduce overall work) is to update e.g. only U-Boot's pinmux programming, and leave everything else buggy. That's certainly not a desirable situation. I introduced tegra-pinmux-scripts specifically to avoid that kind of situation.

[1] For boards with expansion headers where the end-user/... can use different pins for different things, I consider the HW configuration to include the definition of whatever the user has plugged into the expansion header.

#73 lore raw

PATCH 24/24 tegra124: Expand SPL space by 8KB

Hi Stephen,

Quoted 104 lines · Stephen Warren
Quoted 60 lines · Simon Glass

Hi Stephen,

Quoted 20 lines · Stephen Warren
Quoted 18 lines · Simon Glass

Hi Stephen,

Quoted 13 lines · Stephen Warren
Quoted 6 lines · Simon Glass

We are getting very close to running out of space in SPL, and with the currently Chrome OS gcc 4.9 we exceed the limit. Add a litle more space.

Quoted 5 lines
Quoted 5 lines
Quoted 5 lines

8K is quite a bump given we only had 24K allocated before. Why is gcc-4.9
less efficient that earlier compilers I wonder? Were we extremely close to
the limit ebfore? Still, I guess this is fine.

We were about 1KB away, mostly due to the gcc garbage collection bug I think. The cros compiler seems even worse, not sure why.

Quoted 12 lines
Quoted 9 lines
Quoted 5 lines

Did you validate whether tegra-uboot-flasher still works with this change? I
think it will since it only cares about the SPL TEXT_BASE and not the main
U-Boot TEXT_BASE, but double-checking would be nice.

I tested this with USB A-A (tegrarcm). Is that what you mean?

Quoted 9 lines

Did you just use tegrarcm, or tegra-uboot-flasher? The latter is a wrapper
on top of tegrarcm, and is a bit more involved. See the various READMEs at
https://github.com/NVIDIA/tegra-uboot-flasher-scripts. This doesn't support
any nyan-derived boards yet, but does support Jetson TK1 which I think you
have?

Ah, OK. The script at:

Quoted 6 lines

https://github.com/NVIDIA/tegra-uboot-flasher-scripts/blob/master/tegra-uboot-flasher

looks OK to me. It does not have anything hard-coded that I can see. But I have not used it myself. It's kind-of painful that we have all this out-of-tree Tegra stuff (pin mux also) that might break when we change U-Boot. Is there any way to improve this?

I don't think there's anything to improve; nothing is wrong.

If something changes about the way U-Boot works or must be used, then that requires changes elsewhere no matter what. Whether the externals changes are:

* Updates to documentation of how to build/use/... U-Boot.
* Updates to the command-lines/techniques people know and use.
* Updates to code/tools that interface with U-Boot.

... then in all cases, a change to U-Boot requires a change to something else. I would argue that updating an external tool is actually the easiest of the cases, since it's entirely clear what that tool does, what change to make to it, and how. Conversely, updating the command-lines/techniques that people use is much harder to propagate to all people. The update-a-document case may also be about as easy, presuming you know which documents to update (there are probably more docs than tools at least at present).

In the pinmux case, please consider the system-level implications of a change to the pinmux. There is a single correct pinmux configuration for a given HW configuration, and that's driven purely by the HW design[1]. If the pinmux that U-Boot programs is wrong and needs to be changed, the same change should be propagated to all SW to fix the bug everywhere. The existence of the external Tegra pinmux tools makes that easier; update the pinmux tool, regenerate derived files for all SW stacks, and apply the changes everywhere. Sure it's more work to do that than just updating only U-Boot. However, the tool doesn't add that extra work, rather the change to the desired pinmux makes the work. The only alternative (which does indeed reduce overall work) is to update e.g. only U-Boot's pinmux programming, and leave everything else buggy. That's certainly not a desirable situation. I introduced tegra-pinmux-scripts specifically to avoid that kind of situation.

Quoted 4 lines

[1] For boards with expansion headers where the end-user/... can use different pins for different things, I consider the HW configuration to include the definition of whatever the user has plugged into the expansion header.

Here I am enabling the TPM in U-Boot. There may or may not be a kernel TPM driver. Presumably if there is, then something is wrong, because it has the wrong pinmux and won't work, or someone did update it in the kernel and not in U-Boot? Actually I'm not sure that I care about it running in Linux any more than someone working in Linux cares that the TPM is working in U-Boot.

Why can't this stuff go in the device tree, which is already shared between U-Boot and Linux?

Regards,
Simon

#74 lore raw

PATCH 24/24 tegra124: Expand SPL space by 8KB

In reply to Simon Glass

+Tom Warren

Quoted 25 lines · Simon Glass

We are getting very close to running out of space in SPL, and with the currently Chrome OS gcc 4.9 we exceed the limit. Add a litle more space.

---

 include/configs/tegra124-common.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/configs/tegra124-common.h +1 -2
index f2b3774..0347132 100644
@@ -30,7 +30,7 @@
 /*-----------------------------------------------------------------------
  * Physical Memory Map
  */
-#define CONFIG_SYS_TEXT_BASE   0x8010E000
+#define CONFIG_SYS_TEXT_BASE   0x80110000
 
 /*
  * Memory layout for where various images get loaded by boot scripts:
--

2.2.0.rc0.207.ga3a616c

#75 lore raw

PATCH 24/24 tegra124: Expand SPL space by 8KB

LGTM, but it s/b 'Add a _little_ more space' in the commit msg.

Should we change the TEXT_BASE for the CPU portion in all Tegra builds?

Quoted 31 lines

-----Original Message-----
From: sjg at google.com [mailto:sjg at google.com] On Behalf Of Simon Glass
Sent: Tuesday, May 05, 2015 9:04 AM
To: U-Boot Mailing List
Cc: Simon Glass; Heiko Schocher; Tom Rini; Tom Warren
Subject: Re: [PATCH 24/24] tegra124: Expand SPL space by 8KB

+Tom Warren

Quoted 21 lines · Simon Glass

We are getting very close to running out of space in SPL, and with the currently Chrome OS gcc 4.9 we exceed the limit. Add a litle more space.

---

 include/configs/tegra124-common.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/configs/tegra124-common.h +1 -1
index f2b3774..0347132 100644
@@ -30,7 +30,7 @@
 /*-----------------------------------------------------------------------
  * Physical Memory Map
  */
-#define CONFIG_SYS_TEXT_BASE   0x8010E000
+#define CONFIG_SYS_TEXT_BASE   0x80110000
 
Quoted 5 lines
Quoted 5 lines
include/configs/tegra124-common.h +0 -1
 /*
  * Memory layout for where various images get loaded by boot scripts:
--

2.2.0.rc0.207.ga3a616c

-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain confidential information. Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------