Re: [U-Boot] u-boot Boot issue about rk3188

2017-09-21 Thread Heiko Stuebner
Am Freitag, 22. September 2017, 08:50:49 CEST schrieb Andy Yan:
> Hi Heiko:
> 
> 
> On 2017年09月22日 08:24, Andy Yan wrote:
> > Hi Heiko:
> >
> >
> > On 2017年09月21日 22:55, Heiko Stübner wrote:
> >> Hi Andy,
> >>
> >> Am Donnerstag, 21. September 2017, 22:03:32 CEST schrieb Andy Yan:
> >>> Hi Heiko:
> >>> I try to boot the upstream u-boot-rockchip branch  on my rk3188 board
> >>> with(rock_defconfig)
> >>>
> >>> But I got this error:
> >>> early_init()
> >>> nit_and_scan() returned error -22
> >>> early_init() failed: -22
> >>> ERROR ### Please RESET the board ###
> >>>
> >>> the current commit head is: 782088d("rockchip: imply ADC and 
> >>> SARADC_ROCKCHIP
> >>> on supported SoCs") Do you ever meet something like this?
> >> that is very strange. When testing Philipp's branch, I was also 
> >> testing the
> >> commit you mention to see if anything broke since I last changed u-boot
> >> on my radxa rock. And the above commit started just fine, when starting
> >> from an sd-card.
> >>
> >> Not sure from which medium you're starting though. But from what I
> >> remember Pawel got nand working in his rk3066 series, but that is not
> >> yet merged.
> >
> > I boot from emmc, I will go on hack on it.
> >>
> 
>  I finally can boot it with the rock_defconfig. But the way to 
> package the tpl spl u-boot a little different.
> 
>  cat ${DIR}/out/tpl/u-boot-tpl.bin > tplspl.bin
>  truncate -s 1020 tplspl.bin
> sed -i "/^/{1s/^/RK31/}" tplspl.bin
> cat ${DIR}/out/spl/u-boot-spl.bin > spl.bin
> truncate -s %2048 spl.bin
> cat spl.bin >> tplspl.bin
> 
> Then the tplspl.bin + u-boot.bin should package by 
> boot_merger(tplsplb.in for FLashData, u-boot.bin for FlashBoot) from 
> rockchip downstream u-boot repo:
> ./tools/boot_merger ./tools/rk_tools/RKBOOT/RK310BMINIALL.ini
> 
> download to emmc by "upgrade_tool ul" command. According to our 
> bootrom code author, the rk31(maybe include rk30) bootrom has a 
> limitation that the idbblock
> couldn't accessed by upgrade_tool wl command.

I do have a script handling that [0]. At least for the sd-card variant
a simple "openssl rc4" works just as well as the legacy boot_merger :-)

Heiko

[0] 
https://github.com/mmind/u-boot-rockchip/commit/81458bde873d6cf588e082ccf556e818f46ad9df
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH 1/1] GPT: incomplete initialization in allocate_disk_part

2017-09-21 Thread Stefan Roese

On 21.09.2017 19:03, Heinrich Schuchardt wrote:

memset(newpart, '\0', sizeof(newpart));
only initializes the firest 4 or 8 bytes of *newpart and not the whole
structure disk_part.

We should use sizeof(struct disk_part).

Instead of malloc and memset we can use calloc.

Identified by cppcheck.

Fixes: 09a49930e41 GPT: read partition table from device into a data structure
Cc: Stefan Roese 
Signed-off-by: Heinrich Schuchardt 
---
v2
use calloc as suggested by Stefan
---
  cmd/gpt.c | 3 +--
  1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/cmd/gpt.c b/cmd/gpt.c
index 638aa19826..d4406e3120 100644
--- a/cmd/gpt.c
+++ b/cmd/gpt.c
@@ -190,10 +190,9 @@ static void del_gpt_info(void)
  static struct disk_part *allocate_disk_part(disk_partition_t *info, int 
partnum)
  {
struct disk_part *newpart;
-   newpart = malloc(sizeof(*newpart));
+   newpart = calloc(1, sizeof(struct disk_part));
if (!newpart)
return ERR_PTR(-ENOMEM);
-   memset(newpart, '\0', sizeof(newpart));
  
  	newpart->gpt_part_info.start = info->start;

newpart->gpt_part_info.size = info->size;



Reviewed-by: Stefan Roese 

Thanks,
Stefan
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH 14/14] usb: xhci: Set 'Average TRB Length' to 8 for control endpoints

2017-09-21 Thread Stefan Roese

On 18.09.2017 15:40, Bin Meng wrote:

Update the codes to conform with xHCI spec chapter 6.2.3.

Signed-off-by: Bin Meng 

---

  drivers/usb/host/xhci-mem.c | 6 ++
  drivers/usb/host/xhci.c | 6 ++
  2 files changed, 12 insertions(+)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 84982a9..0582a9b 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -850,6 +850,12 @@ void xhci_setup_addressable_virt_dev(struct xhci_ctrl 
*ctrl,
trb_64 = (uintptr_t)virt_dev->eps[0].ring->first_seg->trbs;
ep0_ctx->deq = cpu_to_le64(trb_64 | virt_dev->eps[0].ring->cycle_state);
  
+	/*

+* xHCI spec 6.2.3:
+* software shall set 'Average TRB Length' to 8 for control endpoints.
+*/
+   ep0_ctx->tx_info = cpu_to_le32(EP_AVG_TRB_LENGTH(8));
+
/* Steps 7 and 8 were done in xhci_alloc_virt_device() */
  
  	xhci_flush_cache((uintptr_t)ep0_ctx, sizeof(struct xhci_ep_ctx));

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 93737b0..4673738 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -601,6 +601,12 @@ static int xhci_set_configuration(struct usb_device *udev)
ep_ctx[ep_index]->deq = cpu_to_le64(trb_64 |
virt_dev->eps[ep_index].ring->cycle_state);
  
+		/*

+* xHCI spec 6.2.3:
+* 'Average TRB Length' should be 8 for control endpoints.
+*/
+   if (usb_endpoint_xfer_control(endpt_desc))
+   avg_trb_len = 8;
ep_ctx[ep_index]->tx_info =
cpu_to_le32(EP_MAX_ESIT_PAYLOAD_LO(max_esit_payload) |
EP_AVG_TRB_LENGTH(avg_trb_len));



Reviewed-by: Stefan Roese 
Tested-by: Stefan Roese 

Thanks,
Stefan
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH 13/14] usb: xhci: Set 'Error Count' to 0 for isoch endpoints

2017-09-21 Thread Stefan Roese

On 18.09.2017 15:40, Bin Meng wrote:

Per xHCI spec, 'Error Count' should be set to 0 for isoch endpoints.

Signed-off-by: Bin Meng 
---

  drivers/usb/host/xhci.c | 6 +-
  1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index dfb188d..93737b0 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -511,6 +511,7 @@ static int xhci_set_configuration(struct usb_device *udev)
unsigned int mult;
unsigned int max_burst;
unsigned int avg_trb_len;
+   unsigned int err_count = 0;
  
  	out_ctx = virt_dev->out_ctx;

in_ctx = virt_dev->in_ctx;
@@ -588,9 +589,12 @@ static int xhci_set_configuration(struct usb_device *udev)
cpu_to_le32(MAX_PACKET
(get_unaligned(_desc->wMaxPacketSize)));
  
+		/* Allow 3 retries for everything but isoc, set CErr = 3 */

+   if (!usb_endpoint_xfer_isoc(endpt_desc))
+   err_count = 3;
ep_ctx[ep_index]->ep_info2 |=
cpu_to_le32(MAX_BURST(max_burst) |
-   ((3 & ERROR_COUNT_MASK) << ERROR_COUNT_SHIFT));
+   ERROR_COUNT(err_count));
  
  		trb_64 = (uintptr_t)

virt_dev->eps[ep_index].ring->enqueue;



Reviewed-by: Stefan Roese 
Tested-by: Stefan Roese 

Thanks,
Stefan
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH 12/14] usb: xhci: Program max burst size for endpoint

2017-09-21 Thread Stefan Roese

On 18.09.2017 15:40, Bin Meng wrote:

The 'Max Burst Size' indicates to the xHC the maximum number of
consecutive USB transactions that should be executed per scheduling
opportunity. This is a “zero-based” value, where 0 to 15 represents
burst sizes of 1 to 16, but at present this is always set to zero.
Let's program the required value according to real needs.

Signed-off-by: Bin Meng 
---

  drivers/usb/host/xhci.c | 21 -
  1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 8aed428..dfb188d 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -395,6 +395,22 @@ static u32 xhci_get_endpoint_mult(struct usb_device *udev,
return ss_ep_comp_desc->bmAttributes;
  }
  
+static u32 xhci_get_endpoint_max_burst(struct usb_device *udev,

+   struct usb_endpoint_descriptor *endpt_desc,
+   struct usb_ss_ep_comp_descriptor *ss_ep_comp_desc)
+{
+   /* Super speed and Plus have max burst in ep companion desc */
+   if (udev->speed >= USB_SPEED_SUPER)
+   return ss_ep_comp_desc->bMaxBurst;
+
+   if (udev->speed == USB_SPEED_HIGH &&
+   (usb_endpoint_xfer_isoc(endpt_desc) ||
+usb_endpoint_xfer_int(endpt_desc)))
+   return usb_endpoint_maxp_mult(endpt_desc) - 1;
+
+   return 0;
+}
+
  /*
   * Return the maximum endpoint service interval time (ESIT) payload.
   * Basically, this is the maxpacket size, multiplied by the burst size
@@ -493,6 +509,7 @@ static int xhci_set_configuration(struct usb_device *udev)
u32 max_esit_payload;
unsigned int interval;
unsigned int mult;
+   unsigned int max_burst;
unsigned int avg_trb_len;
  
  	out_ctx = virt_dev->out_ctx;

@@ -545,6 +562,8 @@ static int xhci_set_configuration(struct usb_device *udev)
interval = xhci_get_endpoint_interval(udev, endpt_desc);
mult = xhci_get_endpoint_mult(udev, endpt_desc,
  ss_ep_comp_desc);
+   max_burst = xhci_get_endpoint_max_burst(udev, endpt_desc,
+   ss_ep_comp_desc);
avg_trb_len = max_esit_payload;
  
  		ep_index = xhci_get_ep_index(endpt_desc);

@@ -570,7 +589,7 @@ static int xhci_set_configuration(struct usb_device *udev)
(get_unaligned(_desc->wMaxPacketSize)));
  
  		ep_ctx[ep_index]->ep_info2 |=

-   cpu_to_le32(((0 & MAX_BURST_MASK) << MAX_BURST_SHIFT) |
+   cpu_to_le32(MAX_BURST(max_burst) |
((3 & ERROR_COUNT_MASK) << ERROR_COUNT_SHIFT));
  
  		trb_64 = (uintptr_t)




Reviewed-by: Stefan Roese 
Tested-by: Stefan Roese 

Thanks,
Stefan
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH 11/14] usb: xhci: Honor endpoint's interval

2017-09-21 Thread Stefan Roese

On 18.09.2017 15:40, Bin Meng wrote:

USB endpoint reports the period between consecutive requests to send
or receive data as bInverval in its endpoint descriptor. So far this
is ignored by xHCI driver and the 'Interval' field in xHC's endpoint
context is always programmed to zero which means 1ms for low speed
or full speed , or 125us for high speed or super speed. We should
honor the interval by getting it from endpoint descriptor.

Signed-off-by: Bin Meng 
---

  drivers/usb/host/xhci.c | 195 
  drivers/usb/host/xhci.h |   5 +-
  include/linux/usb/ch9.h |  20 +
  3 files changed, 218 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index ec82fa6..8aed428 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -257,6 +257,172 @@ static unsigned int xhci_get_ep_index(struct 
usb_endpoint_descriptor *desc)
return index;
  }
  
+/*

+ * Convert bInterval expressed in microframes (in 1-255 range) to exponent of
+ * microframes, rounded down to nearest power of 2.
+ */
+static unsigned int xhci_microframes_to_exponent(unsigned int desc_interval,
+unsigned int min_exponent,
+unsigned int max_exponent)
+{
+   unsigned int interval;
+
+   interval = fls(desc_interval) - 1;
+   interval = clamp_val(interval, min_exponent, max_exponent);
+   if ((1 << interval) != desc_interval)
+   debug("rounding interval to %d microframes, "\
+ "ep desc says %d microframes\n",
+ 1 << interval, desc_interval);
+
+   return interval;
+}
+
+static unsigned int xhci_parse_microframe_interval(struct usb_device *udev,
+   struct usb_endpoint_descriptor *endpt_desc)
+{
+   if (endpt_desc->bInterval == 0)
+   return 0;
+
+   return xhci_microframes_to_exponent(endpt_desc->bInterval, 0, 15);
+}
+
+static unsigned int xhci_parse_frame_interval(struct usb_device *udev,
+   struct usb_endpoint_descriptor *endpt_desc)
+{
+   return xhci_microframes_to_exponent(endpt_desc->bInterval * 8, 3, 10);
+}
+
+/*
+ * Convert interval expressed as 2^(bInterval - 1) == interval into
+ * straight exponent value 2^n == interval.
+ */
+static unsigned int xhci_parse_exponent_interval(struct usb_device *udev,
+   struct usb_endpoint_descriptor *endpt_desc)
+{
+   unsigned int interval;
+
+   interval = clamp_val(endpt_desc->bInterval, 1, 16) - 1;
+   if (interval != endpt_desc->bInterval - 1)
+   debug("ep %#x - rounding interval to %d %sframes\n",
+ endpt_desc->bEndpointAddress, 1 << interval,
+ udev->speed == USB_SPEED_FULL ? "" : "micro");
+
+   if (udev->speed == USB_SPEED_FULL) {
+   /*
+* Full speed isoc endpoints specify interval in frames,
+* not microframes. We are using microframes everywhere,
+* so adjust accordingly.
+*/
+   interval += 3;  /* 1 frame = 2^3 uframes */
+   }
+
+   return interval;
+}
+
+/*
+ * Return the polling or NAK interval.
+ *
+ * The polling interval is expressed in "microframes". If xHCI's Interval field
+ * is set to N, it will service the endpoint every 2^(Interval)*125us.
+ *
+ * The NAK interval is one NAK per 1 to 255 microframes, or no NAKs if interval
+ * is set to 0.
+ */
+static unsigned int xhci_get_endpoint_interval(struct usb_device *udev,
+   struct usb_endpoint_descriptor *endpt_desc)
+{
+   unsigned int interval = 0;
+
+   switch (udev->speed) {
+   case USB_SPEED_HIGH:
+   /* Max NAK rate */
+   if (usb_endpoint_xfer_control(endpt_desc) ||
+   usb_endpoint_xfer_bulk(endpt_desc)) {
+   interval = xhci_parse_microframe_interval(udev,
+ endpt_desc);
+   break;
+   }
+   /* Fall through - SS and HS isoc/int have same decoding */
+
+   case USB_SPEED_SUPER:
+   if (usb_endpoint_xfer_int(endpt_desc) ||
+   usb_endpoint_xfer_isoc(endpt_desc)) {
+   interval = xhci_parse_exponent_interval(udev,
+   endpt_desc);
+   }
+   break;
+
+   case USB_SPEED_FULL:
+   if (usb_endpoint_xfer_isoc(endpt_desc)) {
+   interval = xhci_parse_exponent_interval(udev,
+   endpt_desc);
+   break;
+   }
+   /*
+* Fall through for interrupt endpoint interval decoding
+* since it uses the same rules as low speed interrupt
+* endpoints.
+

Re: [U-Boot] [PATCH 10/14] usb: hub: Clear BH reset status change for a 3.0 hub

2017-09-21 Thread Stefan Roese

On 18.09.2017 15:40, Bin Meng wrote:

USB 3.0 hubs report bit[5] in the port status change response as BH
reset. The hub shall set the C_BH_PORT_RESET field for this port.

Signed-off-by: Bin Meng 
---

  common/usb_hub.c | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/common/usb_hub.c b/common/usb_hub.c
index a9d21bc..325d16d 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -494,6 +494,12 @@ static int usb_scan_port(struct usb_device_scan *usb_scan)
usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_RESET);
}
  
+	if ((portchange & USB_SS_PORT_STAT_C_BH_RESET) &&

+   usb_hub_is_superspeed(dev)) {
+   debug("port %d BH reset change\n", i + 1);
+   usb_clear_port_feature(dev, i + 1, USB_SS_PORT_FEAT_C_BH_RESET);
+   }
+
/* A new USB device is ready at this point */
debug("devnum=%d port=%d: USB dev found\n", dev->devnum, i + 1);
  



Reviewed-by: Stefan Roese 
Tested-by: Stefan Roese 

Thanks,
Stefan
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH 09/14] usb: hub: Clear port reset before usb_hub_port_connect_change()

2017-09-21 Thread Stefan Roese

On 18.09.2017 15:40, Bin Meng wrote:

During usb_hub_port_connect_change(), a port reset set feature
request is issued to the port, and later a port reset clear feature
is done to the same port before the function returns. However at
the end of usb_scan_port(), we attempt to clear port reset again
on a cached port status change variable, which should not be done.

Adjust the call to clear port reset to right before the call to
usb_hub_port_connect_change().

Signed-off-by: Bin Meng 
---

  common/usb_hub.c | 10 +-
  1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/common/usb_hub.c b/common/usb_hub.c
index 86a3477..a9d21bc 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -489,6 +489,11 @@ static int usb_scan_port(struct usb_device_scan *usb_scan)
return 0;
}
  
+	if (portchange & USB_PORT_STAT_C_RESET) {

+   debug("port %d reset change\n", i + 1);
+   usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_RESET);
+   }
+
/* A new USB device is ready at this point */
debug("devnum=%d port=%d: USB dev found\n", dev->devnum, i + 1);
  
@@ -543,11 +548,6 @@ static int usb_scan_port(struct usb_device_scan *usb_scan)

   hub->overcurrent_count[i]);
}
  
-	if (portchange & USB_PORT_STAT_C_RESET) {

-   debug("port %d reset change\n", i + 1);
-   usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_RESET);
-   }
-
/*
 * We're done with this device, so let's remove this device from
 * scanning list



Reviewed-by: Stefan Roese 
Tested-by: Stefan Roese 

Thanks,
Stefan
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH 08/14] usb: xhci: Fix max packet size for full speed device endpoint 0

2017-09-21 Thread Stefan Roese

On 18.09.2017 15:40, Bin Meng wrote:

In xhci_check_maxpacket(), the control endpoint 0 max packet size
is wrongly taken from the interface's endpoint descriptor. However
the default endpoint 0 does not come with an endpoint descriptor
hence is not included in the interface structure. Change to use
epmaxpacketin[0] instead.

The other bug in this routine is that when setting max packet size
to the xHC endpoint 0 context, it does not clear its previous value
at all before programming a new one.

Signed-off-by: Bin Meng 
---

  drivers/usb/host/xhci.c | 8 +++-
  1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 4b3d58d..ec82fa6 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -546,16 +546,13 @@ int xhci_check_maxpacket(struct usb_device *udev)
int max_packet_size;
int hw_max_packet_size;
int ret = 0;
-   struct usb_interface *ifdesc;
-
-   ifdesc = >config.if_desc[0];
  
  	out_ctx = ctrl->devs[slot_id]->out_ctx;

xhci_inval_cache((uintptr_t)out_ctx->bytes, out_ctx->size);
  
  	ep_ctx = xhci_get_ep_ctx(ctrl, out_ctx, ep_index);

hw_max_packet_size = MAX_PACKET_DECODED(le32_to_cpu(ep_ctx->ep_info2));
-   max_packet_size = usb_endpoint_maxp(>ep_desc[0]);
+   max_packet_size = udev->epmaxpacketin[0];
if (hw_max_packet_size != max_packet_size) {
debug("Max Packet Size for ep 0 changed.\n");
debug("Max packet size in usb_device = %d\n", max_packet_size);
@@ -567,7 +564,8 @@ int xhci_check_maxpacket(struct usb_device *udev)
ctrl->devs[slot_id]->out_ctx, ep_index);
in_ctx = ctrl->devs[slot_id]->in_ctx;
ep_ctx = xhci_get_ep_ctx(ctrl, in_ctx, ep_index);
-   ep_ctx->ep_info2 &= cpu_to_le32(~MAX_PACKET_MASK);
+   ep_ctx->ep_info2 &= cpu_to_le32(~((0x & MAX_PACKET_MASK)
+   << MAX_PACKET_SHIFT));
ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet_size));
  
  		/*




Reviewed-by: Stefan Roese 
Tested-by: Stefan Roese 

Thanks,
Stefan
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH 07/14] usb: Read device descriptor after device is addressed for xHCI

2017-09-21 Thread Stefan Roese

On 18.09.2017 15:40, Bin Meng wrote:

For xHCI it is not possible to read a device descriptor before it
has been assigned an address. That's why usb_setup_descriptor()
was called with 'do_read' being false. But we really need try to
read the device descriptor before starting any real communication
with the default control endpoint.

Signed-off-by: Bin Meng 
---

  common/usb.c | 11 +++
  1 file changed, 11 insertions(+)

diff --git a/common/usb.c b/common/usb.c
index 88cee81..8d27bc7 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -1052,6 +1052,17 @@ static int usb_prepare_device(struct usb_device *dev, 
int addr, bool do_read,
  
  	mdelay(10);	/* Let the SET_ADDRESS settle */
  
+	/*

+* If we haven't read device descriptor before, read it here
+* after device is assigned an address. This is only applicable
+* to xHCI so far.
+*/
+   if (!do_read) {
+   err = usb_setup_descriptor(dev, true);
+   if (err)
+   return err;
+   }
+
return 0;
  }
  



Reviewed-by: Stefan Roese 
Tested-by: Stefan Roese 

Thanks,
Stefan
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH 06/14] usb: Only get 64 bytes device descriptor for full speed devices

2017-09-21 Thread Stefan Roese

On 18.09.2017 15:40, Bin Meng wrote:

Full speed device endpoint 0 can have 8/16/32/64 bMaxPacketSize0.
Other speed devices report fixed value per USB spec. So it only
makes sense if we send a get device descriptor with 64 bytes to
full speed devices.

While we are here, update the comment block to be within 80 cols.

Signed-off-by: Bin Meng 
---

  common/usb.c | 29 +++--
  1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/common/usb.c b/common/usb.c
index 6cb92ef..88cee81 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -970,23 +970,24 @@ static int usb_setup_descriptor(struct usb_device *dev, 
bool do_read)
dev->epmaxpacketin[0] = dev->descriptor.bMaxPacketSize0;
dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;
  
-	if (do_read) {

+   if (do_read && dev->speed == USB_SPEED_FULL) {
int err;
  
  		/*

-* Validate we've received only at least 8 bytes, not that we've
-* received the entire descriptor. The reasoning is:
-* - The code only uses fields in the first 8 bytes, so that's 
all we
-*   need to have fetched at this stage.
-* - The smallest maxpacket size is 8 bytes. Before we know the 
actual
-*   maxpacket the device uses, the USB controller may only 
accept a
-*   single packet. Consequently we are only guaranteed to 
receive 1
-*   packet (at least 8 bytes) even in a non-error case.
+* Validate we've received only at least 8 bytes, not that
+* we've received the entire descriptor. The reasoning is:
+* - The code only uses fields in the first 8 bytes, so
+*   that's all we need to have fetched at this stage.
+* - The smallest maxpacket size is 8 bytes. Before we know
+*   the actual maxpacket the device uses, the USB controller
+*   may only accept a single packet. Consequently we are only
+*   guaranteed to receive 1 packet (at least 8 bytes) even in
+*   a non-error case.
 *
-* At least the DWC2 controller needs to be programmed with the 
number
-* of packets in addition to the number of bytes. A request for 
64
-* bytes of data with the maxpacket guessed as 64 (above) 
yields a
-* request for 1 packet.
+* At least the DWC2 controller needs to be programmed with
+* the number of packets in addition to the number of bytes.
+* A request for 64 bytes of data with the maxpacket guessed
+* as 64 (above) yields a request for 1 packet.
 */
err = get_descriptor_len(dev, 64, 8);
if (err)
@@ -1009,7 +1010,7 @@ static int usb_setup_descriptor(struct usb_device *dev, 
bool do_read)
dev->maxpacketsize = PACKET_SIZE_64;
break;
default:
-   printf("usb_new_device: invalid max packet size\n");
+   printf("%s: invalid max packet size\n", __func__);
return -EIO;
}
  



Reviewed-by: Stefan Roese 
Tested-by: Stefan Roese 

Thanks,
Stefan
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH 05/14] usb: xhci: Add interrupt transfer support

2017-09-21 Thread Stefan Roese

On 18.09.2017 15:40, Bin Meng wrote:

xHCI uses normal TRBs for both bulk and interrupt. This adds the
missing interrupt transfer support to xHCI so that devices like
USB keyboard that uses interrupt transfer can work.

Signed-off-by: Bin Meng 
---

  drivers/usb/host/xhci.c | 13 ++---
  1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 04eb1eb..4b3d58d 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -890,11 +890,18 @@ unknown:
  static int _xhci_submit_int_msg(struct usb_device *udev, unsigned long pipe,
void *buffer, int length, int interval)
  {
+   if (usb_pipetype(pipe) != PIPE_INTERRUPT) {
+   printf("non-interrupt pipe (type=%lu)", usb_pipetype(pipe));
+   return -EINVAL;
+   }
+
/*
-* TODO: Not addressing any interrupt type transfer requests
-* Add support for it later.
+* xHCI uses normal TRBs for both bulk and interrupt. When the
+* interrupt endpoint is to be serviced, the xHC will consume
+* (at most) one TD. A TD (comprised of sg list entries) can
+* take several service intervals to transmit.
 */
-   return -EINVAL;
+   return xhci_bulk_tx(udev, pipe, length, buffer);
  }
  
  /**




Reviewed-by: Stefan Roese 
Tested-by: Stefan Roese 

Thanks,
Stefan
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH 04/14] usb: Handle audio extension endpoint descriptor in usb_parse_config()

2017-09-21 Thread Stefan Roese

On 18.09.2017 15:40, Bin Meng wrote:

Normal endpoint descriptor size is 7, but for audio extension it is
9. Handle that correctly when parsing endpoint descriptor.

Signed-off-by: Bin Meng 
---

  common/usb.c | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/common/usb.c b/common/usb.c
index 0904259..6cb92ef 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -437,12 +437,13 @@ static int usb_parse_config(struct usb_device *dev,
}
break;
case USB_DT_ENDPOINT:
-   if (head->bLength != USB_DT_ENDPOINT_SIZE) {
+   if (head->bLength != USB_DT_ENDPOINT_SIZE &&
+   head->bLength != USB_DT_ENDPOINT_AUDIO_SIZE) {
printf("ERROR: Invalid USB EP length (%d)\n",
head->bLength);
break;
}
-   if (index + USB_DT_ENDPOINT_SIZE >
+   if (index + head->bLength >
dev->config.desc.wTotalLength) {
puts("USB EP descriptor overflowed buffer!\n");
break;



Reviewed-by: Stefan Roese 
Tested-by: Stefan Roese 

Thanks,
Stefan
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH 03/14] usb: xhci: Don't assume LS/FS devices are always behind a HS hub

2017-09-21 Thread Stefan Roese

On 18.09.2017 15:40, Bin Meng wrote:

At present xHCI driver assumes LS/FS devices are attached directly
to a HS hub. If they are connected to a LS/FS hub, the driver will
fail to perform the USB enumeration process on such devices.

This is fixed by looking from the device itself all the way up to
the HS hub where the TT that serves the device is located.

Signed-off-by: Bin Meng 
---

  drivers/usb/host/xhci-mem.c | 18 ++
  1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index d5eab3a..84982a9 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -786,12 +786,22 @@ void xhci_setup_addressable_virt_dev(struct xhci_ctrl 
*ctrl,
  #ifdef CONFIG_DM_USB
/* Set up TT fields to support FS/LS devices */
if (speed == USB_SPEED_LOW || speed == USB_SPEED_FULL) {
-   dev = dev_get_parent_priv(udev->dev);
-   if (dev->speed == USB_SPEED_HIGH) {
-   hub = dev_get_uclass_priv(udev->dev);
+   struct udevice *parent = udev->dev;
+
+   dev = udev;
+   do {
+   port_num = dev->portnr;
+   dev = dev_get_parent_priv(parent);
+   if (usb_hub_is_root_hub(dev->dev))
+   break;
+   parent = dev->dev->parent;
+   } while (dev->speed != USB_SPEED_HIGH);
+
+   if (!usb_hub_is_root_hub(dev->dev)) {
+   hub = dev_get_uclass_priv(dev->dev);
if (hub->tt.multi)
slot_ctx->dev_info |= cpu_to_le32(DEV_MTT);
-   slot_ctx->tt_info |= cpu_to_le32(TT_PORT(udev->portnr));
+   slot_ctx->tt_info |= cpu_to_le32(TT_PORT(port_num));
slot_ctx->tt_info |= cpu_to_le32(TT_SLOT(dev->slot_id));
}
}



Reviewed-by: Stefan Roese 
Tested-by: Stefan Roese 

Thanks,
Stefan
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH 02/14] dm: usb: Remove no longer needed blk_unbind_all()

2017-09-21 Thread Stefan Roese

On 18.09.2017 15:40, Bin Meng wrote:

With the root hub unbinding in usb_stop(), there is no need to do
a blk uclass specific unbind operation.

Signed-off-by: Bin Meng 
---

  drivers/usb/host/usb-uclass.c | 6 +-
  1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c
index e90614f..32c8657 100644
--- a/drivers/usb/host/usb-uclass.c
+++ b/drivers/usb/host/usb-uclass.c
@@ -193,11 +193,7 @@ int usb_stop(void)
err = ret;
}
}
-#ifdef CONFIG_BLK
-   ret = blk_unbind_all(IF_TYPE_USB);
-   if (ret && !err)
-   err = ret;
-#endif
+
  #ifdef CONFIG_SANDBOX
struct udevice *dev;
  



Reviewed-by: Stefan Roese 
Tested-by: Stefan Roese 

Thanks,
Stefan
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH 01/14] dm: usb: Fix broken usb_stop()

2017-09-21 Thread Stefan Roese

On 18.09.2017 15:40, Bin Meng wrote:

At present we only do device_remove() during usb stop. The DM API
device_remove() only marks the device state as inactivated, but
still keeps its USB topology (eg: parent, children, etc) in the DM
device structure. There is no issue if we only start USB subsystem
once and never stop it. But a big issue occurs when we do 'usb stop'
and 'usb start' multiple times.

Strange things may be observed with current implementation, like:
- the enumeration may report only 1 mass storage device is detected,
   but the total number of USB devices is correct.
- USB keyboard does not work anymore after a bunch of 'usb reset'
   even if 'usb tree' shows it is correctly identified.
- read/write flash drive via 'fatload usb' may complain "Bad device"

In fact, every time when USB host controller starts the enumeration
process, it takes random time for each USB port to show up online,
hence each USB device may appear in a different order from previous
enumeration, and gets assigned to a totally different USB address.
As a result, we end up using a stale USB topology in the DM device
structure which still reflects the previous enumeration result, and
it may create an exact same DM device name like generic_bus_0_dev_7
that is already in the DM device structure. And since the DM device
structure is there, there is no device_bind() call to bind driver to
the device during current enumeration process, eventually creating
an inconsistent software representation of the hardware topology, a
non-working USB subsystem.

The fix is to clear the unused USB topology in the usb_stop(), by
calling device_unbind() on each controller's root hub device, and
the unbinding will unbind all of its children automatically.

Signed-off-by: Bin Meng 


Reviewed-by: Stefan Roese 
Tested-by: Stefan Roese 

Thanks,
Stefan
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH v2 09/14] sunxi: imply USB_GADGET

2017-09-21 Thread Chen-Yu Tsai
On Wed, Sep 13, 2017 at 3:01 AM, Maxime Ripard
 wrote:
> A good number of our boards have USB_GADGET enabled. Imply it so that all
> the boards can benefit from it, and remove some boilerplate from our
> defconfigs.
>
> Reviewed-by: Simon Glass 
> Signed-off-by: Maxime Ripard 

This breaks builds using defconfigs where USB_MUSB_GADGET is not set.
Perhaps a better solution would be to imply USB_GADGET from USB_MUSB_GADGET?
Kconfig complains about recursive dependencies if I do

imply USB_GADGET if USB_MUSB_GADGET

under ARCH_SUNXI though.

ChenYu
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] u-boot Boot issue about rk3188

2017-09-21 Thread Andy Yan

Hi Heiko:


On 2017年09月22日 08:24, Andy Yan wrote:

Hi Heiko:


On 2017年09月21日 22:55, Heiko Stübner wrote:

Hi Andy,

Am Donnerstag, 21. September 2017, 22:03:32 CEST schrieb Andy Yan:

Hi Heiko:
I try to boot the upstream u-boot-rockchip branch  on my rk3188 board
with(rock_defconfig)

But I got this error:
early_init()
nit_and_scan() returned error -22
early_init() failed: -22
ERROR ### Please RESET the board ###

the current commit head is: 782088d("rockchip: imply ADC and 
SARADC_ROCKCHIP

on supported SoCs") Do you ever meet something like this?
that is very strange. When testing Philipp's branch, I was also 
testing the

commit you mention to see if anything broke since I last changed u-boot
on my radxa rock. And the above commit started just fine, when starting
from an sd-card.

Not sure from which medium you're starting though. But from what I
remember Pawel got nand working in his rk3066 series, but that is not
yet merged.


    I boot from emmc, I will go on hack on it.




    I finally can boot it with the rock_defconfig. But the way to 
package the tpl spl u-boot a little different.


    cat ${DIR}/out/tpl/u-boot-tpl.bin > tplspl.bin
    truncate -s 1020 tplspl.bin
   sed -i "/^/{1s/^/RK31/}" tplspl.bin
   cat ${DIR}/out/spl/u-boot-spl.bin > spl.bin
   truncate -s %2048 spl.bin
   cat spl.bin >> tplspl.bin

   Then the tplspl.bin + u-boot.bin should package by 
boot_merger(tplsplb.in for FLashData, u-boot.bin for FlashBoot) from 
rockchip downstream u-boot repo:

   ./tools/boot_merger ./tools/rk_tools/RKBOOT/RK310BMINIALL.ini

   download to emmc by "upgrade_tool ul" command. According to our 
bootrom code author, the rk31(maybe include rk30) bootrom has a 
limitation that the idbblock

couldn't accessed by upgrade_tool wl command.



Heiko








___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] Request For Comments: wget and TCP listener

2017-09-21 Thread Duncan Hare
Mods to:
cmd/net.cnet/Makefilenet/net.cinclude/net.hnet/wget.cnet/wget.hnet/ping.c
I do not know how to do patches, I'm a noobat this:
cmd/net.c
Additions
static int do_wget(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]){  
      return netboot_common(WGET, cmdtp, argc, argv);}
U_BOOT_CMD(        wget,    3,      1,      do_wget,        "boot image via 
network using HTTP protocol",        "[loadAddress] 
[[hostIPaddr:]bootfilename]");
net/Makefile addition
obj-$(CONFIG_CMD_NFS)  += wget.o

net.c  complete, look for #ifdef TCP
 /*
 *  Copied from Linux Monitor (LiMon) - Networking.
 *
 *  Copyright 1994 - 2000 Neil Russell.
 *  (See License)
 *  Copyright 2000 Roland Borde
 *  Copyright 2000 Paolo Scaffardi
 *  Copyright 2000-2002 Wolfgang Denk, w...@denx.de
 *  Copyright 2017-2018 Duncan Hare, d...@synoia.com
 *  SPDX-License-Identifier:GPL-2.0
 */
#define TCP 1
/*
 * General Desription:
 *
 * The user interface supports commands for BOOTP, RARP, and TFTP.
 * Also, we support ARP internally. Depending on available data,
 * these interact as follows:
 *
 * BOOTP:
 *
 *  Prerequisites:  - own ethernet address
 *  We want:- own IP address
 *  - TFTP server IP address
 *  - name of bootfile
 *  Next step:  ARP
 *
 * LINK_LOCAL:
 *
 *  Prerequisites:  - own ethernet address
 *  We want:- own IP address
 *  Next step:  ARP
 *
 * RARP:
 *
 *  Prerequisites:  - own ethernet address
 *  We want:- own IP address
 *  - TFTP server IP address
 *  Next step:  ARP
 *
 * ARP:
 *
 *  Prerequisites:  - own ethernet address
 *  - own IP address
 *  - TFTP server IP address
 *  We want:- TFTP server ethernet address
 *  Next step:  TFTP
 *
 * DHCP:
 *
 * Prerequisites:   - own ethernet address
 * We want: - IP, Netmask, ServerIP, Gateway IP
 *  - bootfilename, lease time
 * Next step:   - TFTP
 *
 * TFTP:
 *
 *  Prerequisites:  - own ethernet address
 *  - own IP address
 *  - TFTP server IP address
 *  - TFTP server ethernet address
 *  - name of bootfile (if unknown, we use a default name
 *derived from our own IP address)
 *  We want:- load the boot file
 *  Next step:  none
 *
 * NFS:
 *
 *  Prerequisites:  - own ethernet address
 *  - own IP address
 *  - name of bootfile (if unknown, we use a default name
 *derived from our own IP address)
 *  We want:- load the boot file
 *  Next step:  none
 *
 * SNTP:
 *
 *  Prerequisites:  - own ethernet address
 *  - own IP address
 *  We want:- network time
 *  Next step:  none
 *
 * HTTP/TCP Receiver:
 *
 *  Prequeisites:   - own ethernet adress
 *  - own IP address
 *  - Server IP address
 *  - HTP client
 *  - Bootfile path & name
 *  We want:- Load the Boot file
 *  Next Step   HTTPS?
 */
#define DEBUG_DCH_PKT 1
#define DEBUG_TCP_PKT 0

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#if defined(CONFIG_STATUS_LED)
#include 
#include 
#endif
#include 
#include 
#include "arp.h"
#include "bootp.h"
#include "cdp.h"
#if defined(CONFIG_CMD_DNS)
#include "dns.h"
#endif
#include "link_local.h"
#include "nfs.h"
#include "wget.h"
#include "ping.h"
#include "rarp.h"
#if defined(CONFIG_CMD_SNTP)
#include "sntp.h"
#endif

DECLARE_GLOBAL_DATA_PTR;

/** BOOTP EXTENTIONS **/

/* Our subnet mask (0=unknown) */
struct in_addr net_netmask;
/* Our gateways IP address */
struct in_addr net_gateway;
/* Our DNS IP address */
struct in_addr net_dns_server;
#if defined(CONFIG_BOOTP_DNS2)
/* Our 2nd DNS IP address */
struct in_addr net_dns_server2;
#endif

#ifdef CONFIG_MCAST_TFTP/* Multicast TFTP */
struct in_addr net_mcast_addr;
#endif

/** END OF BOOTP EXTENTIONS **/

/* Our ethernet address */
u8 net_ethaddr[6];
/* Boot server enet address */
u8 net_server_ethaddr[6];
/* Our IP addr (0 = unknown) */
struct in_addr  net_ip;
/* Server IP addr (0 = unknown) */
struct in_addr  net_server_ip;
/* Port numbers */
int dport;
int sport;
/* Current receive packet */
uchar *net_rx_packet;
/* Current rx max packet length */
int net_rx_packet_len;
/* IP packet ID */
static unsigned net_ip_id; 
/* Ethernet bcast address */
const u8 net_bcast_ethaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
const u8 net_null_ethaddr[6];
#if defined(CONFIG_API) || defined(CONFIG_EFI_LOADER)
void (*push_packet)(void *, int len) = 0;
#endif
/* Network loop state */
enum net_loop_state net_state;
/* Tried all network devices */
int   

[U-Boot] [PATCH 1/1] omap: Omit fastboot.userdata_size related errors

2017-09-21 Thread Sam Protsenko
When using regular $partitions variable (for Linux boot), we can see
some unwanted messages:

> ERROR: cannot find partition: 'userdata'

> at arch/arm/mach-omap2/utils.c:96/omap_mmc_get_part_size()
> Warning: fastboot.userdata_size: unable to calc

Let's remove those, as missing 'userdata' partition is correct behavior
for Linux partition, and we don't want to see some Android-related
messages in this case.

Signed-off-by: Sam Protsenko 
---
 arch/arm/mach-omap2/utils.c | 13 -
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-omap2/utils.c b/arch/arm/mach-omap2/utils.c
index 0b0bf1837c..3892853c7e 100644
--- a/arch/arm/mach-omap2/utils.c
+++ b/arch/arm/mach-omap2/utils.c
@@ -92,10 +92,8 @@ static u32 omap_mmc_get_part_size(const char *part)
}
 
res = part_get_info_by_name(dev_desc, part, );
-   if (res < 0) {
-   error("cannot find partition: '%s'\n", part);
+   if (res < 0)
return 0;
-   }
 
/* Calculate size in bytes */
sz = (info.size * (u64)info.blksz);
@@ -111,13 +109,10 @@ static void omap_set_fastboot_userdata_size(void)
u32 sz_kb;
 
sz_kb = omap_mmc_get_part_size("userdata");
-   if (sz_kb == 0) {
-   buf[0] = '\0';
-   printf("Warning: fastboot.userdata_size: unable to calc\n");
-   } else {
-   sprintf(buf, "%u", sz_kb);
-   }
+   if (sz_kb == 0)
+   return; /* probably it's not Android partition table */
 
+   sprintf(buf, "%u", sz_kb);
env_set("fastboot.userdata_size", buf);
 }
 #else
-- 
2.14.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 3/4] env: ti: boot: Extract command for eMMC Linux boot

2017-09-21 Thread Sam Protsenko
Extract commands for booting Linux from eMMC to separate command. It
seems more logical that way, and allows us to run the whole command set
from U-Boot shell with only one command.

Signed-off-by: Sam Protsenko 
---
 include/environment/ti/boot.h | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/include/environment/ti/boot.h b/include/environment/ti/boot.h
index 5b1b97bafe..2306d3cdf0 100644
--- a/include/environment/ti/boot.h
+++ b/include/environment/ti/boot.h
@@ -29,6 +29,11 @@
"partitions=" PARTS_DEFAULT "\0" \
"optargs=\0" \
"dofastboot=0\0" \
+   "emmc_linux_boot=" \
+   "setenv mmcdev 1; " \
+   "setenv bootpart 1:2; " \
+   "setenv mmcroot /dev/mmcblk0p2 rw; " \
+   "run mmcboot;\0" \
"emmc_android_boot=" \
"setenv eval_bootargs setenv bootargs $bootargs; " \
"run eval_bootargs; " \
@@ -93,10 +98,7 @@
"run findfdt; " \
"run envboot; " \
"run mmcboot;" \
-   "setenv mmcdev 1; " \
-   "setenv bootpart 1:2; " \
-   "setenv mmcroot /dev/mmcblk0p2 rw; " \
-   "run mmcboot;" \
+   "run emmc_linux_boot; " \
"run emmc_android_boot; " \
""
 
-- 
2.14.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 4/4] env: ti: boot: Show boot status information

2017-09-21 Thread Sam Protsenko
Add tracing printings to Linux/Android boot commands, so that we can see
what's going on. Helps to trace possible bugs on early stages and
improves the output for user (which is especially useful, because we
have a bunch of boot commands executing one by one).

Signed-off-by: Sam Protsenko 
---
 include/environment/ti/boot.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/environment/ti/boot.h b/include/environment/ti/boot.h
index 2306d3cdf0..799d9840aa 100644
--- a/include/environment/ti/boot.h
+++ b/include/environment/ti/boot.h
@@ -30,11 +30,13 @@
"optargs=\0" \
"dofastboot=0\0" \
"emmc_linux_boot=" \
+   "echo Trying to boot Linux from eMMC ...; " \
"setenv mmcdev 1; " \
"setenv bootpart 1:2; " \
"setenv mmcroot /dev/mmcblk0p2 rw; " \
"run mmcboot;\0" \
"emmc_android_boot=" \
+   "echo Trying to boot Android from eMMC ...; " \
"setenv eval_bootargs setenv bootargs $bootargs; " \
"run eval_bootargs; " \
"setenv mmcdev 1; " \
@@ -49,7 +51,6 @@
"part size mmc ${mmcdev} ${boot_part} boot_size; " \
"mmc read ${fdtaddr} ${fdt_start} ${fdt_size}; " \
"mmc read ${loadaddr} ${boot_start} ${boot_size}; " \
-   "echo Booting from eMMC ...; " \
"bootm $loadaddr $loadaddr $fdtaddr;\0"
 
 #ifdef CONFIG_OMAP54XX
-- 
2.14.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 2/4] arm: dra7xx: Fix Linux boot from eMMC

2017-09-21 Thread Sam Protsenko
Right now on OMAP5-based boards we have only one partition defined for
Linux boot, which is rootfs. That doesn't work with bootpart=1:2 (that
is defined in include/environment/ti/boot.h). To fix Linux boot we may
either:

 1. Change bootpart to be 1:1
 2. Or add preceding partition, so that rootfs is actually 1:2

Second choice seems more reasonable, as DFU is already using similar
partition table and can rely on bootpart to be 1:2.

This patch adds "bootloader" partition. So now eMMC layout for Linux
boot looks like this:

offset   content size  partition
(KiB)(KiB)
===

0   ++
| MBR/GPT header |   128   -
128 ++
| MLO|   256   -
384 ++
| u-boot.img |   1792  bootloader
2176++
|  hole  |   256   -
2432++
| U-Boot environment |   128   -
2560++
| U-Boot environment (redundant) |   128   -
2688++
| rootfs |   remaining rootfs
end ++

===

Guard hole appears because U-Boot environment offset was calculated for
Android partition table, which has two additional partitions in place of
that hole ("environment" and "misc" partitions).

This patch also changes rootfs offset from 2 MiB further to 2688 KiB,
so that there won't be any collisions with U-Boot environment when we
flash rootfs.

Signed-off-by: Sam Protsenko 
---
 include/configs/dra7xx_evm.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/configs/dra7xx_evm.h b/include/configs/dra7xx_evm.h
index 6c0fc35d3a..1555fc1b50 100644
--- a/include/configs/dra7xx_evm.h
+++ b/include/configs/dra7xx_evm.h
@@ -51,7 +51,8 @@
 #define PARTS_DEFAULT \
/* Linux partitions */ \
"uuid_disk=${uuid_gpt_disk};" \
-   "name=rootfs,start=2MiB,size=-,uuid=${uuid_gpt_rootfs}\0" \
+   "name=bootloader,start=384K,size=1792K,uuid=${uuid_gpt_bootloader};" \
+   "name=rootfs,start=2688K,size=-,uuid=${uuid_gpt_rootfs}\0" \
/* Android partitions */ \
"partitions_android=" \
"uuid_disk=${uuid_gpt_disk};" \
-- 
2.14.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 1/4] arm: am57xx: Fix Linux boot from eMMC

2017-09-21 Thread Sam Protsenko
Right now on OMAP5-based boards we have only one partition defined for
Linux boot, which is rootfs. That doesn't work with bootpart=1:2 (that
is defined in include/environment/ti/boot.h). To fix Linux boot we may
either:

 1. Change bootpart to be 1:1
 2. Or add preceding partition, so that rootfs is actually 1:2

Second choice seems more reasonable, as DFU is already using similar
partition table and can rely on bootpart to be 1:2.

This patch adds "bootloader" partition. So now eMMC layout for Linux
boot looks like this:

offset   content size  partition
(KiB)(KiB)
===

0   ++
| MBR/GPT header |   128   -
128 ++
| MLO|   256   -
384 ++
| u-boot.img |   1792  bootloader
2176++
|  hole  |   256   -
2432++
| U-Boot environment |   128   -
2560++
| U-Boot environment (redundant) |   128   -
2688++
| rootfs |   remaining rootfs
end ++

===

Guard hole appears because U-Boot environment offset was calculated for
Android partition table, which has two additional partitions in place of
that hole ("environment" and "misc" partitions).

This patch also changes rootfs offset from 2 MiB further to 2688 KiB,
so that there won't be any collisions with U-Boot environment when we
flash rootfs.

Signed-off-by: Sam Protsenko 
---
 include/configs/am57xx_evm.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/configs/am57xx_evm.h b/include/configs/am57xx_evm.h
index 0c70c53050..bf555ccdc2 100644
--- a/include/configs/am57xx_evm.h
+++ b/include/configs/am57xx_evm.h
@@ -44,7 +44,8 @@
 #define PARTS_DEFAULT \
/* Linux partitions */ \
"uuid_disk=${uuid_gpt_disk};" \
-   "name=rootfs,start=2MiB,size=-,uuid=${uuid_gpt_rootfs}\0" \
+   "name=bootloader,start=384K,size=1792K,uuid=${uuid_gpt_bootloader};" \
+   "name=rootfs,start=2688K,size=-,uuid=${uuid_gpt_rootfs}\0" \
/* Android partitions */ \
"partitions_android=" \
"uuid_disk=${uuid_gpt_disk};" \
-- 
2.14.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 0/4] arm: am57xx/dra7xx: Improve eMMC Linux boot

2017-09-21 Thread Sam Protsenko
This patch series makes it possible to actually run Linux from eMMC.
While at it, some small style improvements were done as well.

Sam Protsenko (4):
  arm: am57xx: Fix Linux boot from eMMC
  arm: dra7xx: Fix Linux boot from eMMC
  env: ti: boot: Extract command for eMMC Linux boot
  env: ti: boot: Show boot status information

 include/configs/am57xx_evm.h  |  3 ++-
 include/configs/dra7xx_evm.h  |  3 ++-
 include/environment/ti/boot.h | 13 -
 3 files changed, 12 insertions(+), 7 deletions(-)

-- 
2.14.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] Updated invitation: Unibuild discussion @ Thu 21 Sep 2017 12:00 - 13:30 (MDT) (u-boot@lists.denx.de)

2017-09-21 Thread Simon Glass
On 21 September 2017 at 11:38,  wrote:
>
> This event has been changed.
>
> more details »
>
> Unibuild discussion
>
> Changed: https://plus.google.com/hangouts/_/google.com/shapiroc
> Calendar
> u-boot@lists.denx.de
> Who
> •
> Simon Glass- organiser
> •
> u-boot@lists.denx.de
>
> Going?   Yes - Maybe - Nomore options »
>
> Invitation from Google Calendar
>
> You are receiving this courtesy email at the account u-boot@lists.denx.de 
> because you are an attendee of this event.
>
> To stop receiving future updates for this event, decline this event. 
> Alternatively, you can sign up for a Google account at 
> https://www.google.com/calendar/ and control your notification settings for 
> your entire calendar.
>
> Forwarding this invitation could allow any recipient to modify your RSVP 
> response. Learn More.

Very sorry, please ignore this, I'm not quite sure what happened.

- Simon
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH v2 0/3] mmc: sunxi: index hack removal

2017-09-21 Thread Maxime Ripard
On Tue, Sep 12, 2017 at 08:02:21PM +, Maxime Ripard wrote:
> Hi,
> 
> Here is an attempt at removing the hack in the sunxi code to switch
> the MMC indices depending on the boot device.
> 
> It's based on Siarhei's suggestion to go through an environment
> variable set by the code, and then having a script in our default
> bootcmd to change the boot order in order to always favour the boot
> device, instead of always picking the external MMC first.

Applied all three.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


signature.asc
Description: PGP signature
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH v2 1/1] sunxi: Add support for A20-OLinuXino-MICRO-eMMC

2017-09-21 Thread Maxime Ripard
On Thu, Sep 21, 2017 at 01:00:16PM +, Stefan Mavrodiev wrote:
> From rev.J A20-OLinuXino-MICRO has eMMC option. For now this is
> only 4GB, but in the future size may increase.
> 
> The dts file is the same from mainline kernel.
> 
> Signed-off-by: Stefan Mavrodiev 

Applied, thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


signature.asc
Description: PGP signature
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH v5 1/4] sunxi: change the DE1 video option to CONFIG_VIDEO_SUNXI

2017-09-21 Thread Maxime Ripard
On Thu, Sep 21, 2017 at 07:48:20AM +, Icenowy Zheng wrote:
> 
> 
> 于 2017年9月21日 GMT+08:00 下午3:40:23, Maxime Ripard 
>  写到:
> >Hi,
> >
> >On Wed, Sep 20, 2017 at 04:18:19PM +, Icenowy Zheng wrote:
> >> The sunxi DE1 video option used to be CONFIG_VIDEO, which has the
> >same
> >> name as the "Enable legacy video support" option in
> >> drivers/video/Kconfig.
> >> 
> >> Change the option name to CONFIG_VIDEO_SUNXI, which is really used by
> >> Makefile under drivers/video/sunxi/, and defined in sunxi-common.h
> >> when CONFIG_VIDEO is selected before this change. Now
> >CONFIG_VIDEO_SUNXI
> >> selects CONFIG_VIDEO and the usages of CONFIG_VIDEO in sunxi Kconfig
> >and
> >> config headers are all converted to use CONFIG_VIDEO_SUNXI.
> >> 
> >> Signed-off-by: Icenowy Zheng 
> >
> >The patch is fine, but you also seem to imply that it's an issue. It's
> >not, you can very well define in Kconfig the same symbol in two
> >different places, and Kconfig will merge the two by itself.
> 
> So I can drop this patch and simply add "imply VIDEO_DT_SIMPLEFB" in
> the VIDEO option at sunxi Kconfig?

I don't see anything wrong with this patch, there's no need to change it.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


signature.asc
Description: PGP signature
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [U-Boot, v2, 4/8] test/py: Import StringIO from io module for python 3.x

2017-09-21 Thread Tom Rini
On Thu, Sep 21, 2017 at 12:37:19PM -0600, Stephen Warren wrote:
> On 09/21/2017 10:38 AM, Paul Burton wrote:
> >Hi Tom,
> >
> >On Thursday, 21 September 2017 09:27:02 PDT Tom Rini wrote:
> >>On Thu, Sep 14, 2017 at 02:34:46PM -0700, Paul Burton wrote:
> >>>In python 3.x the StringIO module is gone, and instead StringIO can be
> >>>imported from the io module. Do this in order to run on python 3.x, and
> >>>fall back to importing StringIO as a module in order to continue working
> >>>with python 2.x.
> >>>
> >>>Signed-off-by: Paul Burton 
> >>>Reviewed-by: Stephen Warren 
> >>
> >>This breaks python2.7.  There we have both StringIO and io.StringIO so
> >>we succeed in 'from io import StringIO'.  But io.StringIO() needs
> >>unicode, and we don't have that by default in python2.  My quick attempt
> >>here failed.  Thanks!
> >
> >Hmm, in that case back to v1 for this patch? (ie. try the StringIO.StringIO
> >import first?)
> >
> >   https://patchwork.ozlabs.org/patch/813933/
> 
> If v1 works, that's fine by me too.

OK, thanks.  It does work and I'll grab just that.

-- 
Tom


signature.asc
Description: Digital signature
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] Updated invitation: Unibuild discussion @ Thu 21 Sep 2017 12:00 - 13:30 (MDT) (u-boot@lists.denx.de)

2017-09-21 Thread sjg
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:REQUEST
BEGIN:VEVENT
DTSTART:20170921T18Z
DTEND:20170921T193000Z
DTSTAMP:20170921T183824Z
ORGANIZER;CN=Simon Glass:mailto:s...@google.com
UID:0h19tmpd9e4dve5d7va71nk...@google.com
ATTENDEE;CUTYPE=RESOURCE;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRUE;C
 N=BLD-2525-2-Ping (8) [GVC];X-NUM-GUESTS=0:mailto:google.com_726f6f6d5f7573
 5f626c645f323532355f325f323...@resource.calendar.google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRUE
 ;CN=Simon Glass;X-NUM-GUESTS=0:mailto:s...@google.com
ATTENDEE;CUTYPE=RESOURCE;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRUE;C
 N=MTV-42-2-Porto Alegre (4) [GVC];X-NUM-GUESTS=0:mailto:google.com_726f6f6d
 5f75735f6d74765f34325f325f323...@resource.calendar.google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=
 TRUE;CN=u-boot@lists.denx.de;X-NUM-GUESTS=0:mailto:u-boot@lists.denx.de
CREATED:20170921T180953Z
DESCRIPTION:-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
 :~:~:~:~:~:~:~:~::~:~::-\nPlease do not edit this section of the descriptio
 n.\n\nThis event has a Google Hangouts video call.\nJoin: https://plus.goog
 le.com/hangouts/_/google.com/shapiroc?hceid=c2pnQGdvb2dsZS5jb20.0h19tmpd9e4
 dve5d7va71nkhqr=121\n\nView your event at https://www.google.com/calenda
 r/event?action=VIEW=MGgxOXRtcGQ5ZTRkdmU1ZDd2YTcxbmtocXIgdS1ib290QGxpc3R
 zLmRlbnguZGU=MTQjc2pnQGdvb2dsZS5jb21mNTJlYTU2NWY5NzMwODdiZTk2OTI2YmM4NT
 hhYmViYTE4NDcxZDY3=America/Denver=en_GB.\n-::~:~::~:~:~:~:~:~:~:~:~:
 ~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~::~:~::-
LAST-MODIFIED:20170921T183823Z
LOCATION:BLD-2525-2-Ping (8) [GVC]\, MTV-42-2-Porto Alegre (4) [GVC]
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Unibuild discussion
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR


invite.ics
Description: application/ics
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [U-Boot, v2, 4/8] test/py: Import StringIO from io module for python 3.x

2017-09-21 Thread Stephen Warren

On 09/21/2017 10:38 AM, Paul Burton wrote:

Hi Tom,

On Thursday, 21 September 2017 09:27:02 PDT Tom Rini wrote:

On Thu, Sep 14, 2017 at 02:34:46PM -0700, Paul Burton wrote:

In python 3.x the StringIO module is gone, and instead StringIO can be
imported from the io module. Do this in order to run on python 3.x, and
fall back to importing StringIO as a module in order to continue working
with python 2.x.

Signed-off-by: Paul Burton 
Reviewed-by: Stephen Warren 


This breaks python2.7.  There we have both StringIO and io.StringIO so
we succeed in 'from io import StringIO'.  But io.StringIO() needs
unicode, and we don't have that by default in python2.  My quick attempt
here failed.  Thanks!


Hmm, in that case back to v1 for this patch? (ie. try the StringIO.StringIO
import first?)

   https://patchwork.ozlabs.org/patch/813933/


If v1 works, that's fine by me too.
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2] imx: sys_proto: Add a prototype for board_mmc_get_env_dev()

2017-09-21 Thread Diego Dorta
When compiling with W=1 the following warning is observed:

board/freescale/mx6sabresd/mx6sabresd.c:266:5: warning:
no previous prototype for ‘board_mmc_get_env_dev’
[-Wmissing-prototypes] int board_mmc_get_env_dev(int devno)

Remove this warning by adding the function prototype into sys_proto.h file.

Signed-off-by: Diego Dorta 
---
Changes since v1:
- Add 'mmc' prefix
- Change function prototype to sys_proto.h
- Update commit log accordingly

 arch/arm/include/asm/mach-imx/sys_proto.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/include/asm/mach-imx/sys_proto.h 
b/arch/arm/include/asm/mach-imx/sys_proto.h
index 970c4ca..7036343 100644
--- a/arch/arm/include/asm/mach-imx/sys_proto.h
+++ b/arch/arm/include/asm/mach-imx/sys_proto.h
@@ -107,6 +107,8 @@ void init_aips(void);
 void init_src(void);
 void imx_set_wdog_powerdown(bool enable);
 
+int board_mmc_get_env_dev(int devno);
+
 /*
  * Initializes on-chip ethernet controllers.
  * to override, implement board_eth_init()
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] Invitation: Unibuild discussion @ Thu 21 Sep 2017 12:00 - 13:00 (MDT) (u-boot@lists.denx.de)

2017-09-21 Thread Simon Glass
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:REQUEST
BEGIN:VEVENT
DTSTART:20170921T18Z
DTEND:20170921T19Z
DTSTAMP:20170921T181034Z
ORGANIZER;CN=Simon Glass:mailto:s...@google.com
UID:0h19tmpd9e4dve5d7va71nk...@google.com
ATTENDEE;CUTYPE=RESOURCE;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRUE;C
 N=BLD-2525-2-Ping (8) [GVC];X-NUM-GUESTS=0:mailto:google.com_726f6f6d5f7573
 5f626c645f323532355f325f323...@resource.calendar.google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRUE
 ;CN=Simon Glass;X-NUM-GUESTS=0:mailto:s...@google.com
ATTENDEE;CUTYPE=RESOURCE;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRUE;C
 N=MTV-42-2-Porto Alegre (4) [GVC];X-NUM-GUESTS=0:mailto:google.com_726f6f6d
 5f75735f6d74765f34325f325f323...@resource.calendar.google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=
 TRUE;CN=u-boot@lists.denx.de;X-NUM-GUESTS=0:mailto:u-boot@lists.denx.de
CREATED:20170921T180953Z
DESCRIPTION:-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
 :~:~:~:~:~:~:~:~::~:~::-\nPlease do not edit this section of the descriptio
 n.\n\nThis event has a Google Hangouts video call.\nJoin: https://plus.goog
 le.com/hangouts/_/google.com/sjg?hceid=c2pnQGdvb2dsZS5jb20.0h19tmpd9e4dve5d
 7va71nkhqr=121\n\nView your event at https://www.google.com/calendar/eve
 nt?action=VIEW=MGgxOXRtcGQ5ZTRkdmU1ZDd2YTcxbmtocXIgdS1ib290QGxpc3RzLmRl
 bnguZGU=MTQjc2pnQGdvb2dsZS5jb21mNTJlYTU2NWY5NzMwODdiZTk2OTI2YmM4NThhYmV
 iYTE4NDcxZDY3=America/Denver=en_GB.\n-::~:~::~:~:~:~:~:~:~:~:~:~:~:~
 :~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~::~:~::-
LAST-MODIFIED:20170921T181034Z
LOCATION:BLD-2525-2-Ping (8) [GVC]\, MTV-42-2-Porto Alegre (4) [GVC]
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Unibuild discussion
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR


invite.ics
Description: application/ics
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 1/1] GPT: incomplete initialization in allocate_disk_part

2017-09-21 Thread Heinrich Schuchardt
memset(newpart, '\0', sizeof(newpart));
only initializes the firest 4 or 8 bytes of *newpart and not the whole
structure disk_part.

We should use sizeof(struct disk_part).

Instead of malloc and memset we can use calloc.

Identified by cppcheck.

Fixes: 09a49930e41 GPT: read partition table from device into a data structure
Cc: Stefan Roese 
Signed-off-by: Heinrich Schuchardt 
---
v2
use calloc as suggested by Stefan
---
 cmd/gpt.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/cmd/gpt.c b/cmd/gpt.c
index 638aa19826..d4406e3120 100644
--- a/cmd/gpt.c
+++ b/cmd/gpt.c
@@ -190,10 +190,9 @@ static void del_gpt_info(void)
 static struct disk_part *allocate_disk_part(disk_partition_t *info, int 
partnum)
 {
struct disk_part *newpart;
-   newpart = malloc(sizeof(*newpart));
+   newpart = calloc(1, sizeof(struct disk_part));
if (!newpart)
return ERR_PTR(-ENOMEM);
-   memset(newpart, '\0', sizeof(newpart));
 
newpart->gpt_part_info.start = info->start;
newpart->gpt_part_info.size = info->size;
-- 
2.11.0

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 1/2] configs: colibri_imx6: don't configure video in spl

2017-09-21 Thread Max Krummenacher
The functionality is not needed in the SPL. It allows to remove
code conditionally in the spl case in some drivers.

Signed-off-by: Max Krummenacher 
---

 include/configs/colibri_imx6.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/configs/colibri_imx6.h b/include/configs/colibri_imx6.h
index 5fd9aab..b02a291 100644
--- a/include/configs/colibri_imx6.h
+++ b/include/configs/colibri_imx6.h
@@ -94,6 +94,7 @@
 #define CONFIG_MXC_GPIO
 
 /* Framebuffer and LCD */
+#if !defined(CONFIG_SPL_BUILD)
 #define CONFIG_VIDEO_IPUV3
 #define CONFIG_SYS_CONSOLE_IS_IN_ENV
 #define CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
@@ -106,6 +107,7 @@
 #define CONFIG_CONSOLE_MUX
 #define CONFIG_IMX_HDMI
 #define CONFIG_IMX_VIDEO_SKIP
+#endif
 
 /* allow to overwrite serial and ethaddr */
 #define CONFIG_ENV_OVERWRITE
-- 
2.7.5

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 2/2] configs: apalis_imx6: don't configure video in spl

2017-09-21 Thread Max Krummenacher
The functionality is not needed in the SPL. It allows to remove
code conditionally in the spl case in some drivers.

Signed-off-by: Max Krummenacher 

---

 include/configs/apalis_imx6.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/configs/apalis_imx6.h b/include/configs/apalis_imx6.h
index 9022a9d..f55c36c 100644
--- a/include/configs/apalis_imx6.h
+++ b/include/configs/apalis_imx6.h
@@ -107,6 +107,7 @@
 /* Miscellaneous commands */
 #define CONFIG_MXC_GPIO
 
+#if !defined(CONFIG_SPL_BUILD)
 /* Framebuffer and LCD */
 #define CONFIG_VIDEO_IPUV3
 #define CONFIG_SYS_CONSOLE_IS_IN_ENV
@@ -120,6 +121,7 @@
 #define CONFIG_CONSOLE_MUX
 #define CONFIG_IMX_HDMI
 #define CONFIG_IMX_VIDEO_SKIP
+#endif
 
 /* allow to overwrite serial and ethaddr */
 #define CONFIG_ENV_OVERWRITE
-- 
2.7.5

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 0/2] configs: apalis/colibri imx6: don't configure video in spl

2017-09-21 Thread Max Krummenacher

This series remove unneeded SPL config options. This is needed
to successfully compile with the following patch applied:
https://lists.denx.de/pipermail/u-boot/2017-August/304010.html

This series is available at 
http://git.toradex.com/cgit/u-boot-toradex.git/log/?h=for-next


Max Krummenacher (2):
  configs: colibri_imx6: don't configure video in spl
  configs: apalis_imx6: don't configure video in spl

 include/configs/apalis_imx6.h  | 2 ++
 include/configs/colibri_imx6.h | 2 ++
 2 files changed, 4 insertions(+)

-- 
2.7.5

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH] Remove "no previous prototype" warning

2017-09-21 Thread Fabio Estevam
Hi Diego,

On Thu, Sep 21, 2017 at 11:47 AM, Diego Dorta  wrote:
> When compiling with W=1 the following warning is observed:
>
> board/freescale/mx6sabresd/mx6sabresd.c:266:5: warning:
> no previous prototype for ‘board_mmc_get_env_dev’
> [-Wmissing-prototypes] int board_mmc_get_env_dev(int devno)
>
> Remove this warning by adding the function prototype into mmc.h file.
>
> Signed-off-by: Diego Dorta 
> ---
>  include/mmc.h | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/include/mmc.h b/include/mmc.h
> index 010ebe0..3ddfc2d 100644
> --- a/include/mmc.h
> +++ b/include/mmc.h
> @@ -588,6 +588,7 @@ int board_mmc_init(bd_t *bis);
>  int cpu_mmc_init(bd_t *bis);
>  int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr);
>  int mmc_get_env_dev(void);
> +int board_mmc_get_env_dev(int devno);

Only imx uses this function, so I would recommend adding its prototype in:
arch/arm/include/asm/mach-imx/sys_proto.h

Thanks
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 1/1] efi_loader: call EFI_EXIT in efi_copy_mem, efi_set_mem

2017-09-21 Thread Heinrich Schuchardt
EFI_ENTRY and EFI_EXIT calls must match.

Signed-off-by: Heinrich Schuchardt 
---
 lib/efi_loader/efi_boottime.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index cbc4007f7b..2c2620a46d 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -1882,6 +1882,7 @@ static void EFIAPI efi_copy_mem(void *destination, void 
*source,
 {
EFI_ENTRY("%p, %p, %ld", destination, source, length);
memcpy(destination, source, length);
+   EFI_EXIT(EFI_SUCCESS);
 }
 
 /*
@@ -1899,6 +1900,7 @@ static void EFIAPI efi_set_mem(void *buffer, unsigned 
long size, uint8_t value)
 {
EFI_ENTRY("%p, %ld, 0x%x", buffer, size, value);
memset(buffer, value, size);
+   EFI_EXIT(EFI_SUCCESS);
 }
 
 /*
-- 
2.11.0

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [U-Boot, v2, 4/8] test/py: Import StringIO from io module for python 3.x

2017-09-21 Thread Paul Burton
Hi Tom,

On Thursday, 21 September 2017 09:27:02 PDT Tom Rini wrote:
> On Thu, Sep 14, 2017 at 02:34:46PM -0700, Paul Burton wrote:
> > In python 3.x the StringIO module is gone, and instead StringIO can be
> > imported from the io module. Do this in order to run on python 3.x, and
> > fall back to importing StringIO as a module in order to continue working
> > with python 2.x.
> > 
> > Signed-off-by: Paul Burton 
> > Reviewed-by: Stephen Warren 
> 
> This breaks python2.7.  There we have both StringIO and io.StringIO so
> we succeed in 'from io import StringIO'.  But io.StringIO() needs
> unicode, and we don't have that by default in python2.  My quick attempt
> here failed.  Thanks!

Hmm, in that case back to v1 for this patch? (ie. try the StringIO.StringIO 
import first?)

  https://patchwork.ozlabs.org/patch/813933/

Would you like me to submit a v3 or could you just take this one from v1?

Thanks,
Paul

signature.asc
Description: This is a digitally signed message part.
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] efi-next: next patches to merge

2017-09-21 Thread Heinrich Schuchardt
Hello Alex,

from my patch queue these are the next patches that I would like to see
merged to efi-next.

efi_selftest: enable CONFIG_CMD_BOOTEFI_SELFTEST
https://patchwork.ozlabs.org/patch/816412/

efi_loader: provide function comments for boot services
https://patchwork.ozlabs.org/patch/817010/

Best regards

Heinrich
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 1/1] efi_loader: provide function comments for boot services

2017-09-21 Thread Heinrich Schuchardt
Provide comments describing the boot service functions.

Signed-off-by: Heinrich Schuchardt 
---
 lib/efi_loader/efi_boottime.c | 640 +-
 1 file changed, 638 insertions(+), 2 deletions(-)

diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 9e741c3cf3..cbc4007f7b 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -161,6 +161,19 @@ static u64 efi_div10(u64 a)
return ret;
 }
 
+/*
+ * Queue an EFI event.
+ *
+ * This function queues the notification function of the event for future
+ * execution.
+ *
+ * The notification function is called if the task priority level of the
+ * event is higher than the current task priority level.
+ *
+ * For the SignalEvent service see efi_signal_event_ext.
+ *
+ * @event  event to signal
+ */
 void efi_signal_event(struct efi_event *event)
 {
if (event->notify_function) {
@@ -174,12 +187,28 @@ void efi_signal_event(struct efi_event *event)
event->queued = 0;
 }
 
+/*
+ * Write a debug message for an EPI API service that is not implemented yet.
+ *
+ * @funcname   function that is not yet implemented
+ * @return EFI_UNSUPPORTED
+ */
 static efi_status_t efi_unsupported(const char *funcname)
 {
debug("EFI: App called into unimplemented function %s\n", funcname);
return EFI_EXIT(EFI_UNSUPPORTED);
 }
 
+/*
+ * Raise the task priority level.
+ *
+ * This function implements the RaiseTpl service.
+ * See the Unified Extensible Firmware Interface (UEFI) specification
+ * for details.
+ *
+ * @new_tplnew value of the task priority level
+ * @return old value of the task priority level
+ */
 static unsigned long EFIAPI efi_raise_tpl(UINTN new_tpl)
 {
UINTN old_tpl = efi_tpl;
@@ -196,6 +225,15 @@ static unsigned long EFIAPI efi_raise_tpl(UINTN new_tpl)
return old_tpl;
 }
 
+/*
+ * Lower the task priority level.
+ *
+ * This function implements the RestoreTpl service.
+ * See the Unified Extensible Firmware Interface (UEFI) specification
+ * for details.
+ *
+ * @old_tplvalue of the task priority level to be restored
+ */
 static void EFIAPI efi_restore_tpl(UINTN old_tpl)
 {
EFI_ENTRY("0x%zx", old_tpl);
@@ -209,6 +247,19 @@ static void EFIAPI efi_restore_tpl(UINTN old_tpl)
EFI_EXIT(EFI_SUCCESS);
 }
 
+/*
+ * Allocate memory pages.
+ *
+ * This function implements the AllocatePages service.
+ * See the Unified Extensible Firmware Interface (UEFI) specification
+ * for details.
+ *
+ * @type   type of allocation to be performed
+ * @memory_typeusage type of the allocated memory
+ * @pages  number of pages to be allocated
+ * @memory allocated memory
+ * @return status code
+ */
 static efi_status_t EFIAPI efi_allocate_pages_ext(int type, int memory_type,
  unsigned long pages,
  uint64_t *memory)
@@ -220,6 +271,17 @@ static efi_status_t EFIAPI efi_allocate_pages_ext(int 
type, int memory_type,
return EFI_EXIT(r);
 }
 
+/*
+ * Free memory pages.
+ *
+ * This function implements the FreePages service.
+ * See the Unified Extensible Firmware Interface (UEFI) specification
+ * for details.
+ *
+ * @memory start of the memory area to be freed
+ * @pages  number of pages to be freed
+ * @return status code
+ */
 static efi_status_t EFIAPI efi_free_pages_ext(uint64_t memory,
  unsigned long pages)
 {
@@ -230,6 +292,21 @@ static efi_status_t EFIAPI efi_free_pages_ext(uint64_t 
memory,
return EFI_EXIT(r);
 }
 
+/*
+ * Get map describing memory usage.
+ *
+ * This function implements the GetMemoryMap service.
+ * See the Unified Extensible Firmware Interface (UEFI) specification
+ * for details.
+ *
+ * @memory_map_sizeon entry the size, in bytes, of the memory map buffer,
+ * on exit the size of the copied memory map
+ * @memory_map buffer to which the memory map is written
+ * @map_keykey for the memory map
+ * @descriptor_sizesize of an individual memory descriptor
+ * @descriptor_version version number of the memory descriptor structure
+ * @return status code
+ */
 static efi_status_t EFIAPI efi_get_memory_map_ext(
unsigned long *memory_map_size,
struct efi_mem_desc *memory_map,
@@ -246,6 +323,18 @@ static efi_status_t EFIAPI efi_get_memory_map_ext(
return EFI_EXIT(r);
 }
 
+/*
+ * Allocate memory from pool.
+ *
+ * This function implements the AllocatePool service.
+ * See the Unified Extensible Firmware Interface (UEFI) specification
+ * for details.
+ *
+ * @pool_type  type of the pool from which memory is to be allocated
+ * @size   number of bytes to be allocated
+ * @buffer allocated memory
+ * 

Re: [U-Boot] [U-Boot, v2, 4/8] test/py: Import StringIO from io module for python 3.x

2017-09-21 Thread Tom Rini
On Thu, Sep 14, 2017 at 02:34:46PM -0700, Paul Burton wrote:

> In python 3.x the StringIO module is gone, and instead StringIO can be
> imported from the io module. Do this in order to run on python 3.x, and
> fall back to importing StringIO as a module in order to continue working
> with python 2.x.
> 
> Signed-off-by: Paul Burton 
> Reviewed-by: Stephen Warren 

This breaks python2.7.  There we have both StringIO and io.StringIO so
we succeed in 'from io import StringIO'.  But io.StringIO() needs
unicode, and we don't have that by default in python2.  My quick attempt
here failed.  Thanks!

-- 
Tom


signature.asc
Description: Digital signature
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH] sun50i: h5: Add NanoPi Neo Plus2 DT initial support

2017-09-21 Thread Antony Antony
Add initial DT for NanoPi NEO Plus2 by FriendlyARM
- Allwinner quad core H5 Cortex A53 with an ARM Mali-450MP GPU
- 1 GB DDR3 RAM
- 8GB eMMC flash (Samsung KLM8G1WEPD-B031)
- micro SD card slot
- Gigabit Ethernet (external RTL8211E-VB-CG chip)
- 802.11 b/g/n WiFi, Bluetooth 4.0 (Ampak AP6212A module)
- 2x USB 2.0 host ports

Signed-off-by: Antony Antony 
Tested-by: Antony Antony 
---
 arch/arm/dts/Makefile   |   1 +
 arch/arm/dts/sun50i-h5-nanopi-neo-plus2.dts | 113 
 configs/nanopi_neo_plus2_defconfig  |  21 ++
 3 files changed, 135 insertions(+)
 create mode 100644 arch/arm/dts/sun50i-h5-nanopi-neo-plus2.dts
 create mode 100644 configs/nanopi_neo_plus2_defconfig

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index fee4680..295a675 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -333,6 +333,7 @@ dtb-$(CONFIG_MACH_SUN8I_V3S) += \
sun8i-v3s-licheepi-zero.dtb
 dtb-$(CONFIG_MACH_SUN50I_H5) += \
sun50i-h5-nanopi-neo2.dtb \
+   sun50i-h5-nanopi-neo-plus2.dtb \
sun50i-h5-orangepi-pc2.dtb \
sun50i-h5-orangepi-prime.dtb \
sun50i-h5-orangepi-zero-plus2.dtb
diff --git a/arch/arm/dts/sun50i-h5-nanopi-neo-plus2.dts 
b/arch/arm/dts/sun50i-h5-nanopi-neo-plus2.dts
new file mode 100644
index 000..7d12774
--- /dev/null
+++ b/arch/arm/dts/sun50i-h5-nanopi-neo-plus2.dts
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2017 Antony Antony 
+ * Copyright (c) 2016 ARM Ltd.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include "sun50i-h5.dtsi"
+
+#include 
+
+/ {
+   model = "FriendlyARM NanoPi NEO Plus 2";
+   compatible = "friendlyarm,nanopi-neo-plus2", "allwinner,sun50i-h5";
+
+   aliases {
+   serial0 = 
+   };
+
+   chosen {
+   stdout-path = "serial0:115200n8";
+   };
+
+   memory {
+   reg = <0x4000 0x4000>;
+   };
+
+   reg_vcc3v3: vcc3v3 {
+   compatible = "regulator-fixed";
+   regulator-name = "vcc3v3";
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   };
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   compatible = "allwinner,sun50i-h5-mmc",
+"allwinner,sun50i-a64-mmc",
+"allwinner,sun5i-a13-mmc";
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>, <_cd_pin>;
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <4>;
+   cd-gpios = < 5 6 GPIO_ACTIVE_HIGH>;
+   cd-inverted;
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_8bit_pins>;
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <8>;
+   non-removable;
+   cap-mmc-hw-reset;
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
diff --git 

Re: [U-Boot] [PATCH] py: test_gpio: Add support for GPIO pytest

2017-09-21 Thread Stephen Warren

On 09/21/2017 06:24 AM, Michal Simek wrote:

Hi Stephen,

On 20.9.2017 19:05, Stephen Warren wrote:

On 09/20/2017 01:55 AM, Michal Simek wrote:

From: Vipul Kumar 

This patch tests the gpio commands using the
gpio data from boardenv file.

Also one test will show the default status of all the gpio's
supported by the processor.


Nit: Wrap the commit description to something like 74 characters; the
text above is far too narrow.

Nit: GPIO not gpio in any free-form text (here and in comments in the
source file)

Ah, I'd briefly though about GPIO tests before, but was wondering how to
integrate e.g. a USB GPIO device to the host PC and interface that with
the target. Loopback GPIOs make this a lot easier:-)


good.




diff --git a/test/py/tests/test_gpio.py b/test/py/tests/test_gpio.py



+"""
+Note: This test relies on boardenv_* containing configuration values
to define
+which the gpio available for testing. Without this, this test will
be  automat-


Nit: Double space before automatically.


+For example:
+
+# A list of gpio's that are going to be tested in order to validate the
+# test.
+env__gpio_val = {
+ "gpio": [0,1,2],
+}


Why is this a dictionary with only one key? Better to just assign the
array directly to env__gpio_val, or put both the "gpio" and
"list_of_gpios" into a single dictionary.


+# A list of gpio's that are shorted on the hardware board and first
gpio of
+# each group is configured as input and the other as output. If the
pins are
+# not shorted properly, then the test will be fail.
+env__gpio_input_output = {
+ "list_of_gpios": [ [36, 37], [38, 39]],
+}


Let's make the examples for env__gpio_val and env__gpio_input_output use
the same GPIO numbers so that they match, and it's obvious how the two
relate to each-other. I assume they're meant to?


The reason for two values is that you do that loopback between certain
pins. It means you have to list pairs.
I have tested this on the board where I can choose whatever
configuration by external wires. Also this list is not the same with the
above one because you are choosing which one is loopback but not all can
be done as loopback.

Also I have tested that you can specify 36,37 as one pair and then 37,36
pair which simply saying which pin is used as output and which as input.

I don't think it is right to say that both of them can bidirectional
because at least in our chip with have some pins which are just output
only and input only.


Sorry, I still don't understand why there are two lists. Certainly I see 
that there's different testing applied to each list, but I don't see any 
benefit from doing that. If you test just loopback pairs, then you've 
tested all the other APIs as part of that, so you don't need a separate 
test for a separate list of GPIOs.


Also, if the code was to include logic to test pairs of loopback GPIOs 
in both directions, the code would need to be careful to set both GPIOs 
to input after each test step. Without that, when setting up the output 
GPIO for the next round of testing, both GPIOs might be outputs for a 
while which could damage HW. I don't recall whether the current code is 
safe in this case or not.

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 02/23] mmc: omap_hsmmc: cleanup omap_hsmmc_set_ios

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

No functional change. Move bus width configuration setting to a
separate function and invoke it only if there is a change in the
bus width.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
---
 drivers/mmc/omap_hsmmc.c | 29 -
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 6ef8295..bab0cef 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -62,6 +62,7 @@ struct omap_hsmmc_data {
 #if !CONFIG_IS_ENABLED(DM_MMC)
struct mmc_config cfg;
 #endif
+   uint bus_width;
uint clock;
 #ifdef OMAP_HSMMC_USE_GPIO
 #if CONFIG_IS_ENABLED(DM_MMC)
@@ -810,17 +811,9 @@ static void omap_hsmmc_set_clock(struct mmc *mmc)
omap_hsmmc_start_clock(mmc_base);
 }
 
-#if !CONFIG_IS_ENABLED(DM_MMC)
-static int omap_hsmmc_set_ios(struct mmc *mmc)
+static void omap_hsmmc_set_bus_width(struct mmc *mmc)
 {
struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
-#else
-static int omap_hsmmc_set_ios(struct udevice *dev)
-{
-   struct omap_hsmmc_data *priv = dev_get_priv(dev);
-   struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
-   struct mmc *mmc = upriv->mmc;
-#endif
struct hsmmc *mmc_base;
 
mmc_base = priv->base_addr;
@@ -847,6 +840,24 @@ static int omap_hsmmc_set_ios(struct udevice *dev)
break;
}
 
+   priv->bus_width = mmc->bus_width;
+}
+
+#if !CONFIG_IS_ENABLED(DM_MMC)
+static int omap_hsmmc_set_ios(struct mmc *mmc)
+{
+   struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
+#else
+static int omap_hsmmc_set_ios(struct udevice *dev)
+{
+   struct omap_hsmmc_data *priv = dev_get_priv(dev);
+   struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+   struct mmc *mmc = upriv->mmc;
+#endif
+
+   if (priv->bus_width != mmc->bus_width)
+   omap_hsmmc_set_bus_width(mmc);
+
if (priv->clock != mmc->clock)
omap_hsmmc_set_clock(mmc);
 
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 18/23] ARM: OMAP5: set mmc clock frequency to 192MHz

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

Now that omap_hsmmc has support for hs200 mode, change the clock
frequency to 192MHz. Also change the REFERENCE CLOCK frequency to
192MHz based on which the internal mmc clock divider is calculated.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
---
 arch/arm/include/asm/arch-omap5/clock.h |  2 +-
 arch/arm/include/asm/omap_mmc.h |  4 
 arch/arm/mach-omap2/omap5/hw_data.c | 10 +-
 3 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/arch/arm/include/asm/arch-omap5/clock.h 
b/arch/arm/include/asm/arch-omap5/clock.h
index ee2e78b..3d718c0 100644
--- a/arch/arm/include/asm/arch-omap5/clock.h
+++ b/arch/arm/include/asm/arch-omap5/clock.h
@@ -135,7 +135,7 @@
 
 /* CM_L3INIT_HSMMCn_CLKCTRL */
 #define HSMMC_CLKCTRL_CLKSEL_MASK  (1 << 24)
-#define HSMMC_CLKCTRL_CLKSEL_DIV_MASK  (1 << 25)
+#define HSMMC_CLKCTRL_CLKSEL_DIV_MASK  (3 << 25)
 
 /* CM_L3INIT_SATA_CLKCTRL */
 #define SATA_CLKCTRL_OPTFCLKEN_MASK(1 << 8)
diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h
index 6871f54..d604b79 100644
--- a/arch/arm/include/asm/omap_mmc.h
+++ b/arch/arm/include/asm/omap_mmc.h
@@ -199,7 +199,11 @@ struct omap_hsmmc_plat {
 #define MMC_CMD0   (INDEX(0)  | RSP_TYPE_NONE | DP_NO_DATA | DDIR_WRITE)
 
 /* Clock Configurations and Macros */
+#ifdef CONFIG_OMAP54XX
+#define MMC_CLOCK_REFERENCE192 /* MHz */
+#else
 #define MMC_CLOCK_REFERENCE96 /* MHz */
+#endif
 
 /* DLL */
 #define DLL_SWT(1 << 20)
diff --git a/arch/arm/mach-omap2/omap5/hw_data.c 
b/arch/arm/mach-omap2/omap5/hw_data.c
index 3bdb114..30e3b68 100644
--- a/arch/arm/mach-omap2/omap5/hw_data.c
+++ b/arch/arm/mach-omap2/omap5/hw_data.c
@@ -438,17 +438,17 @@ void enable_basic_clocks(void)
setbits_le32((*prcm)->cm_l4per_gpio4_clkctrl,
GPIO4_CLKCTRL_OPTFCLKEN_MASK);
 
-   /* Enable 96 MHz clock for MMC1 & MMC2 */
+   /* Enable 192 MHz clock for MMC1 & MMC2 */
setbits_le32((*prcm)->cm_l3init_hsmmc1_clkctrl,
HSMMC_CLKCTRL_CLKSEL_MASK);
setbits_le32((*prcm)->cm_l3init_hsmmc2_clkctrl,
HSMMC_CLKCTRL_CLKSEL_MASK);
 
/* Set the correct clock dividers for mmc */
-   setbits_le32((*prcm)->cm_l3init_hsmmc1_clkctrl,
-   HSMMC_CLKCTRL_CLKSEL_DIV_MASK);
-   setbits_le32((*prcm)->cm_l3init_hsmmc2_clkctrl,
-   HSMMC_CLKCTRL_CLKSEL_DIV_MASK);
+   clrbits_le32((*prcm)->cm_l3init_hsmmc1_clkctrl,
+HSMMC_CLKCTRL_CLKSEL_DIV_MASK);
+   clrbits_le32((*prcm)->cm_l3init_hsmmc2_clkctrl,
+HSMMC_CLKCTRL_CLKSEL_DIV_MASK);
 
/* Select 32KHz clock as the source of GPTIMER1 */
setbits_le32((*prcm)->cm_wkup_gptimer1_clkctrl,
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 20/23] ARM: dts: dra7: Add supported MMC/SD modes in MMC dt nodes

2017-09-21 Thread Jean-Jacques Hiblot
On DRA7 family SoCs, MMC1 controller supports SDR104,
SDR50, DDR50, SDR25 and SDR12 UHS modes.

MMC2 controller supports HS200 and DDR modes.

MMC3 controller supports SDR12, SDR25 and SDR50 modes.

MMC4 controller supports SDR12 and SDR25 modes.

Add these supported modes in device-tree file.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
---
 arch/arm/dts/dra7.dtsi | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm/dts/dra7.dtsi b/arch/arm/dts/dra7.dtsi
index 9061843..0f982d8 100644
--- a/arch/arm/dts/dra7.dtsi
+++ b/arch/arm/dts/dra7.dtsi
@@ -1067,6 +1067,11 @@
status = "disabled";
pbias-supply = <_mmc_reg>;
max-frequency = <19200>;
+   sd-uhs-sdr104;
+   sd-uhs-sdr50;
+   sd-uhs-ddr50;
+   sd-uhs-sdr25;
+   sd-uhs-sdr12;
};
 
mmc2: mmc@480b4000 {
@@ -1079,6 +1084,10 @@
dma-names = "tx", "rx";
status = "disabled";
max-frequency = <19200>;
+   sd-uhs-sdr25;
+   sd-uhs-sdr12;
+   mmc-hs200-1_8v;
+   mmc-ddr-1_8v;
};
 
mmc3: mmc@480ad000 {
@@ -1092,6 +1101,9 @@
status = "disabled";
/* Errata i887 limits max-frequency of MMC3 to 64 MHz */
max-frequency = <6400>;
+   sd-uhs-sdr12;
+   sd-uhs-sdr25;
+   sd-uhs-sdr50;
};
 
mmc4: mmc@480d1000 {
@@ -1104,6 +1116,8 @@
dma-names = "tx", "rx";
status = "disabled";
max-frequency = <19200>;
+   sd-uhs-sdr12;
+   sd-uhs-sdr25;
};
 
mmu0_dsp1: mmu@40d01000 {
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 03/23] mmc: omap_hsmmc: add support to set default io voltage

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

"ti,dual-volt" is used in linux kernel to set the voltage capabilities.
For host controller dt nodes that doesn't have "ti,dual-volt",
it's assumed 1.8v is the io voltage. This is not always true (like in
the case of beagle-x15 where the io lines are connected to 3.3v).
Hence if "no-1-8-v" property is set, io voltage will be set to 3v.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
---
 arch/arm/include/asm/omap_mmc.h | 12 ++--
 drivers/mmc/omap_hsmmc.c| 67 +
 2 files changed, 77 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h
index 102aec2..c4d326d 100644
--- a/arch/arm/include/asm/omap_mmc.h
+++ b/arch/arm/include/asm/omap_mmc.h
@@ -65,6 +65,7 @@ struct omap_hsmmc_plat {
struct hsmmc *base_addr;
struct mmc mmc;
bool cd_inverted;
+   u32 controller_flags;
 };
 
 /*
@@ -124,8 +125,10 @@ struct omap_hsmmc_plat {
 #define DTW_8_BITMODE   (0x1 << 5) /* CON[DW8]*/
 #define SDBP_PWROFF(0x0 << 8)
 #define SDBP_PWRON (0x1 << 8)
+#define SDVS_MASK  (0x7 << 9)
 #define SDVS_1V8   (0x5 << 9)
 #define SDVS_3V0   (0x6 << 9)
+#define SDVS_3V3   (0x7 << 9)
 #define DMA_SELECT (0x2 << 3)
 #define ICE_MASK   (0x1 << 0)
 #define ICE_STOP   (0x0 << 0)
@@ -159,8 +162,13 @@ struct omap_hsmmc_plat {
 #define IE_CERR(0x01 << 28)
 #define IE_BADA(0x01 << 29)
 
-#define VS30_3V0SUP(1 << 25)
-#define VS18_1V8SUP(1 << 26)
+#define VS33_3V3SUPBIT(24)
+#define VS30_3V0SUPBIT(25)
+#define VS18_1V8SUPBIT(26)
+
+#define IOV_3V3330
+#define IOV_3V0300
+#define IOV_1V8180
 
 /* Driver definitions */
 #define MMCSD_SECTOR_SIZE  512
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index bab0cef..e0c7067 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -74,6 +74,9 @@ struct omap_hsmmc_data {
int wp_gpio;
 #endif
 #endif
+#if CONFIG_IS_ENABLED(DM_MMC)
+   uint iov;
+#endif
u8 controller_flags;
 #ifndef CONFIG_OMAP34XX
struct omap_hsmmc_adma_desc *adma_desc_table;
@@ -111,6 +114,8 @@ struct omap_hsmmc_adma_desc {
  * that the bandwidth is always above 3MB/s).
  */
 #define DMA_TIMEOUT_PER_MB 333
+#define OMAP_HSMMC_SUPPORTS_DUAL_VOLT  BIT(0)
+#define OMAP_HSMMC_NO_1_8_VBIT(1)
 #define OMAP_HSMMC_USE_ADMABIT(2)
 
 static int mmc_read_data(struct hsmmc *mmc_base, char *buf, unsigned int size);
@@ -252,6 +257,58 @@ void mmc_init_stream(struct hsmmc *mmc_base)
writel(readl(_base->con) & ~INIT_INITSTREAM, _base->con);
 }
 
+#if CONFIG_IS_ENABLED(DM_MMC)
+static void omap_hsmmc_conf_bus_power(struct mmc *mmc)
+{
+   struct hsmmc *mmc_base;
+   struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
+   u32 val;
+
+   mmc_base = priv->base_addr;
+
+   val = readl(_base->hctl) & ~SDVS_MASK;
+
+   switch (priv->iov) {
+   case IOV_3V3:
+   val |= SDVS_3V3;
+   break;
+   case IOV_3V0:
+   val |= SDVS_3V0;
+   break;
+   case IOV_1V8:
+   val |= SDVS_1V8;
+   break;
+   }
+
+   writel(val, _base->hctl);
+}
+
+static void omap_hsmmc_set_capabilities(struct mmc *mmc)
+{
+   struct hsmmc *mmc_base;
+   struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
+   u32 val;
+
+   mmc_base = priv->base_addr;
+   val = readl(_base->capa);
+
+   if (priv->controller_flags & OMAP_HSMMC_SUPPORTS_DUAL_VOLT) {
+   val |= (VS30_3V0SUP | VS18_1V8SUP);
+   priv->iov = IOV_3V0;
+   } else if (priv->controller_flags & OMAP_HSMMC_NO_1_8_V) {
+   val |= VS30_3V0SUP;
+   val &= ~VS18_1V8SUP;
+   priv->iov = IOV_3V0;
+   } else {
+   val |= VS18_1V8SUP;
+   val &= ~VS30_3V0SUP;
+   priv->iov = IOV_1V8;
+   }
+
+   writel(val, _base->capa);
+}
+#endif
+
 static int omap_hsmmc_init_setup(struct mmc *mmc)
 {
struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
@@ -286,9 +343,15 @@ static int omap_hsmmc_init_setup(struct mmc *mmc)
if (reg_val & MADMA_EN)
priv->controller_flags |= OMAP_HSMMC_USE_ADMA;
 #endif
+
+#if CONFIG_IS_ENABLED(DM_MMC)
+   omap_hsmmc_set_capabilities(mmc);
+   omap_hsmmc_conf_bus_power(mmc);
+#else

[U-Boot] [PATCH 07/23] mmc: omap_hsmmc: Workaround for errata id i802

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

According to errata i802, DCRC error interrupts
(MMCHS_STAT[21] DCRC=0x1) can occur during the tuning procedure.

The DCRC interrupt, occurs when the last tuning block fails
(the last ratio tested). The delay from CRC check until the
interrupt is asserted is bigger than the delay until assertion
of the tuning end flag. Assertion of tuning end flag is what
masks the interrupts. Because of this race, an erroneous DCRC
interrupt occurs.

The suggested  workaround is to disable DCRC interrupts during
the tuning procedure which is implemented here.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
---
 arch/arm/include/asm/omap_mmc.h |  4 
 drivers/mmc/omap_hsmmc.c| 26 ++
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h
index 0293281..0893844 100644
--- a/arch/arm/include/asm/omap_mmc.h
+++ b/arch/arm/include/asm/omap_mmc.h
@@ -219,6 +219,10 @@ struct omap_hsmmc_plat {
 #define mmc_reg_out(addr, mask, val)\
writel((readl(addr) & (~(mask))) | ((val) & (mask)), (addr))
 
+#define INT_EN_MASK (IE_BADA | IE_CERR | IE_DEB | IE_DCRC |\
+   IE_DTO | IE_CIE | IE_CEB | IE_CCRC | IE_ADMAE | IE_CTO |\
+   IE_BRR | IE_BWR | IE_TC | IE_CC)
+
 int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
int wp_gpio);
 
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 321a091..8e42410 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -474,6 +474,25 @@ tuning_error:
 }
 #endif
 
+static void mmc_enable_irq(struct mmc *mmc, struct mmc_cmd *cmd)
+{
+   struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
+   struct hsmmc *mmc_base = priv->base_addr;
+   u32 irq_mask = INT_EN_MASK;
+
+   /*
+* TODO: Errata i802 indicates only DCRC interrupts can occur during
+* tuning procedure and DCRC should be disabled. But see occurences
+* of DEB, CIE, CEB, CCRC interupts during tuning procedure. These
+* interrupts occur along with BRR, so the data is actually in the
+* buffer. It has to be debugged why these interrutps occur
+*/
+   if (cmd && mmc_is_tuning_cmd(cmd->cmdidx))
+   irq_mask &= ~(IE_DEB | IE_DCRC | IE_CIE | IE_CEB | IE_CCRC);
+
+   writel(irq_mask, _base->ie);
+}
+
 static int omap_hsmmc_init_setup(struct mmc *mmc)
 {
struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
@@ -540,10 +559,7 @@ static int omap_hsmmc_init_setup(struct mmc *mmc)
 
writel(readl(_base->hctl) | SDBP_PWRON, _base->hctl);
 
-   writel(IE_BADA | IE_CERR | IE_DEB | IE_DCRC | IE_DTO | IE_CIE |
-   IE_CEB | IE_CCRC | IE_ADMAE | IE_CTO | IE_BRR | IE_BWR | IE_TC |
-   IE_CC, _base->ie);
-
+   mmc_enable_irq(mmc, NULL);
mmc_init_stream(mmc_base);
 
return 0;
@@ -806,6 +822,8 @@ static int omap_hsmmc_send_cmd(struct udevice *dev, struct 
mmc_cmd *cmd,
 #endif
}
 
+   mmc_enable_irq(mmc, cmd);
+
writel(cmd->cmdarg, _base->arg);
udelay(20); /* To fix "No status update" error on eMMC */
writel((cmd->cmdidx << 24) | flags, _base->cmd);
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 06/23] mmc: omap_hsmmc: Add tuning support

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

HS200/SDR104 requires tuning command to be sent to the card. Use
the mmc_send_tuning library function to send the tuning
command and configure the internal DLL.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
---
 arch/arm/include/asm/omap_mmc.h |  21 ++-
 drivers/mmc/omap_hsmmc.c| 118 
 2 files changed, 137 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h
index 341a2e2..0293281 100644
--- a/arch/arm/include/asm/omap_mmc.h
+++ b/arch/arm/include/asm/omap_mmc.h
@@ -39,7 +39,9 @@ struct hsmmc {
unsigned int sysstatus; /* 0x14 */
unsigned char res2[0x14];
unsigned int con;   /* 0x2C */
-   unsigned char res3[0xD4];
+   unsigned int pwcnt; /* 0x30 */
+   unsigned int dll;   /* 0x34 */
+   unsigned char res3[0xcc];
unsigned int blk;   /* 0x104 */
unsigned int arg;   /* 0x108 */
unsigned int cmd;   /* 0x10C */
@@ -56,7 +58,8 @@ struct hsmmc {
unsigned char res4[0x4];
unsigned int ac12;  /* 0x13C */
unsigned int capa;  /* 0x140 */
-   unsigned char res5[0x10];
+   unsigned int capa2; /* 0x144 */
+   unsigned char res5[0xc];
unsigned int admaes;/* 0x154 */
unsigned int admasal;   /* 0x158 */
 };
@@ -173,6 +176,8 @@ struct omap_hsmmc_plat {
 #define IOV_1V8180
 
 #define AC12_ET(1 << 22)
+#define AC12_V1V8_SIGEN(1 << 19)
+#define AC12_SCLK_SEL  (1 << 23)
 #define AC12_UHSMC_MASK(7 << 16)
 #define AC12_UHSMC_DDR50   (4 << 16)
 #define AC12_UHSMC_SDR104  (3 << 16)
@@ -199,6 +204,18 @@ struct omap_hsmmc_plat {
 /* Clock Configurations and Macros */
 #define MMC_CLOCK_REFERENCE96 /* MHz */
 
+/* DLL */
+#define DLL_SWT(1 << 20)
+#define DLL_FORCE_SR_C_SHIFT   13
+#define DLL_FORCE_SR_C_MASK0x7f
+#define DLL_FORCE_VALUE(1 << 12)
+#define DLL_CALIB  (1 << 1)
+
+#define MAX_PHASE_DELAY0x7c
+
+/* CAPA2 */
+#define CAPA2_TSDR50   (1 << 13)
+
 #define mmc_reg_out(addr, mask, val)\
writel((readl(addr) & (~(mask))) | ((val) & (mask)), (addr))
 
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index d5cd826..321a091 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -124,6 +124,7 @@ static int mmc_write_data(struct hsmmc *mmc_base, const 
char *buf,
unsigned int siz);
 static void omap_hsmmc_start_clock(struct hsmmc *mmc_base);
 static void omap_hsmmc_stop_clock(struct hsmmc *mmc_base);
+static void mmc_reset_controller_fsm(struct hsmmc *mmc_base, u32 bit);
 
 static inline struct omap_hsmmc_data *omap_hsmmc_get_data(struct mmc *mmc)
 {
@@ -355,6 +356,122 @@ static void omap_hsmmc_set_capabilities(struct mmc *mmc)
 
writel(val, _base->capa);
 }
+
+static void omap_hsmmc_disable_tuning(struct mmc *mmc)
+{
+   struct hsmmc *mmc_base;
+   struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
+   u32 val;
+
+   mmc_base = priv->base_addr;
+   val = readl(_base->ac12);
+   val &= ~(AC12_SCLK_SEL);
+   writel(val, _base->ac12);
+
+   val = readl(_base->dll);
+   val &= ~(DLL_FORCE_VALUE | DLL_SWT);
+   writel(val, _base->dll);
+}
+
+static void omap_hsmmc_set_dll(struct mmc *mmc, int count)
+{
+   int i;
+   struct hsmmc *mmc_base;
+   struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
+   u32 val;
+
+   mmc_base = priv->base_addr;
+   val = readl(_base->dll);
+   val |= DLL_FORCE_VALUE;
+   val &= ~(DLL_FORCE_SR_C_MASK << DLL_FORCE_SR_C_SHIFT);
+   val |= (count << DLL_FORCE_SR_C_SHIFT);
+   writel(val, _base->dll);
+
+   val |= DLL_CALIB;
+   writel(val, _base->dll);
+   for (i = 0; i < 1000; i++) {
+   if (readl(_base->dll) & DLL_CALIB)
+   break;
+   }
+   val &= ~DLL_CALIB;
+   writel(val, _base->dll);
+}
+
+static int omap_hsmmc_execute_tuning(struct udevice *dev, uint opcode)
+{
+   struct omap_hsmmc_data *priv = dev_get_priv(dev);
+   struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+   struct mmc *mmc = upriv->mmc;
+   struct hsmmc *mmc_base;
+   u32 val;
+   u8 cur_match, prev_match = 0;
+   int ret;
+   u32 phase_delay = 0;
+   u32 start_window = 0, max_window = 0;
+   u32 length = 0, max_len = 0;
+
+   mmc_base = priv->base_addr;
+   val = readl(_base->capa2);
+
+   /* clock tuning is not needed for upto 52MHz */
+   if (!((mmc->selected_mode == MMC_HS_200) 

[U-Boot] [PATCH 04/23] mmc: omap_hsmmc: set MMC mode in the UHSMS bit field

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

Use the timing parameter set in the MMC core to set the
mode in UHSMS  bit field. This is in preparation for
adding HS200 support in omap hsmmc driver.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
---
 arch/arm/include/asm/omap_mmc.h | 12 ++-
 drivers/mmc/omap_hsmmc.c| 47 +
 2 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h
index c4d326d..3f94f2e 100644
--- a/arch/arm/include/asm/omap_mmc.h
+++ b/arch/arm/include/asm/omap_mmc.h
@@ -53,7 +53,8 @@ struct hsmmc {
unsigned int sysctl;/* 0x12C */
unsigned int stat;  /* 0x130 */
unsigned int ie;/* 0x134 */
-   unsigned char res4[0x8];
+   unsigned char res4[0x4];
+   unsigned int ac12;  /* 0x13C */
unsigned int capa;  /* 0x140 */
unsigned char res5[0x10];
unsigned int admaes;/* 0x154 */
@@ -170,6 +171,15 @@ struct omap_hsmmc_plat {
 #define IOV_3V0300
 #define IOV_1V8180
 
+#define AC12_ET(1 << 22)
+#define AC12_UHSMC_MASK(7 << 16)
+#define AC12_UHSMC_DDR50   (4 << 16)
+#define AC12_UHSMC_SDR104  (3 << 16)
+#define AC12_UHSMC_SDR50   (2 << 16)
+#define AC12_UHSMC_SDR25   (1 << 16)
+#define AC12_UHSMC_SDR12   (0 << 16)
+#define AC12_UHSMC_RES (0x7 << 16)
+
 /* Driver definitions */
 #define MMCSD_SECTOR_SIZE  512
 #define MMC_CARD   0
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index e0c7067..4a65a46 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -76,6 +76,7 @@ struct omap_hsmmc_data {
 #endif
 #if CONFIG_IS_ENABLED(DM_MMC)
uint iov;
+   enum bus_mode mode;
 #endif
u8 controller_flags;
 #ifndef CONFIG_OMAP34XX
@@ -258,6 +259,48 @@ void mmc_init_stream(struct hsmmc *mmc_base)
 }
 
 #if CONFIG_IS_ENABLED(DM_MMC)
+static void omap_hsmmc_set_timing(struct mmc *mmc)
+{
+   u32 val;
+   struct hsmmc *mmc_base;
+   struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
+
+   mmc_base = priv->base_addr;
+
+   val = readl(_base->ac12);
+   val &= ~AC12_UHSMC_MASK;
+   priv->mode = mmc->selected_mode;
+
+   switch (priv->mode) {
+   case MMC_HS_200:
+   case UHS_SDR104:
+   val |= AC12_UHSMC_SDR104;
+   break;
+   case UHS_SDR50:
+   val |= AC12_UHSMC_SDR50;
+   break;
+   case MMC_DDR_52:
+   case UHS_DDR50:
+   val |= AC12_UHSMC_DDR50;
+   break;
+   case SD_HS:
+   case MMC_HS_52:
+   case UHS_SDR25:
+   val |= AC12_UHSMC_SDR25;
+   break;
+   case MMC_LEGACY:
+   case MMC_HS:
+   case SD_LEGACY:
+   case UHS_SDR12:
+   val |= AC12_UHSMC_SDR12;
+   break;
+   default:
+   val |= AC12_UHSMC_RES;
+   break;
+   }
+   writel(val, _base->ac12);
+}
+
 static void omap_hsmmc_conf_bus_power(struct mmc *mmc)
 {
struct hsmmc *mmc_base;
@@ -924,6 +967,10 @@ static int omap_hsmmc_set_ios(struct udevice *dev)
if (priv->clock != mmc->clock)
omap_hsmmc_set_clock(mmc);
 
+#if CONFIG_IS_ENABLED(DM_MMC)
+   if (priv->mode != mmc->selected_mode)
+   omap_hsmmc_set_timing(mmc);
+#endif
return 0;
 }
 
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 09/23] mmc: omap_hsmmc: use mmc_of_parse to populate mmc_config

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

Use the mmc_of_parse library function to populate mmc_config instead of
repeating the same code in host controller driver.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
---
 drivers/mmc/omap_hsmmc.c | 24 +---
 1 file changed, 5 insertions(+), 19 deletions(-)

diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 116aa31..734854b 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -1291,32 +1291,18 @@ static int omap_hsmmc_ofdata_to_platdata(struct udevice 
*dev)
struct mmc_config *cfg = >cfg;
const void *fdt = gd->fdt_blob;
int node = dev_of_offset(dev);
-   int val;
+   int ret;
 
plat->base_addr = map_physmem(devfdt_get_addr(dev),
  sizeof(struct hsmmc *),
  MAP_NOCACHE);
 
-   cfg->host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS;
-   val = fdtdec_get_int(fdt, node, "bus-width", -1);
-   if (val < 0) {
-   printf("error: bus-width property missing\n");
-   return -ENOENT;
-   }
-
-   switch (val) {
-   case 0x8:
-   cfg->host_caps |= MMC_MODE_8BIT;
-   case 0x4:
-   cfg->host_caps |= MMC_MODE_4BIT;
-   break;
-   default:
-   printf("error: invalid bus-width property\n");
-   return -ENOENT;
-   }
+   ret = mmc_of_parse(fdt, node, cfg);
+   if (ret < 0)
+   return ret;
 
+   cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
cfg->f_min = 40;
-   cfg->f_max = fdtdec_get_int(fdt, node, "max-frequency", 5200);
cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
if (fdtdec_get_bool(fdt, node, "ti,dual-volt"))
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 19/23] ARM: dts: DRA7: use new dra7-specific compatible string

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

Use the new compatible string "ti,dra7-hsmmc" that was specifically
added for dra7 and dra72. This is required since for dra7 and dra72
processors iodelay values has to be set unlike other processors.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Sekhar Nori 
Signed-off-by: Jean-Jacques Hiblot 
---
 arch/arm/dts/dra7.dtsi | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/dts/dra7.dtsi b/arch/arm/dts/dra7.dtsi
index 02a136a..9061843 100644
--- a/arch/arm/dts/dra7.dtsi
+++ b/arch/arm/dts/dra7.dtsi
@@ -1056,7 +1056,7 @@
};
 
mmc1: mmc@4809c000 {
-   compatible = "ti,omap4-hsmmc";
+   compatible = "ti,dra7-hsmmc", "ti,omap4-hsmmc";
reg = <0x4809c000 0x400>;
interrupts = ;
ti,hwmods = "mmc1";
@@ -1070,7 +1070,7 @@
};
 
mmc2: mmc@480b4000 {
-   compatible = "ti,omap4-hsmmc";
+   compatible = "ti,dra7-hsmmc", "ti,omap4-hsmmc";
reg = <0x480b4000 0x400>;
interrupts = ;
ti,hwmods = "mmc2";
@@ -1082,7 +1082,7 @@
};
 
mmc3: mmc@480ad000 {
-   compatible = "ti,omap4-hsmmc";
+   compatible = "ti,dra7-hsmmc", "ti,omap4-hsmmc";
reg = <0x480ad000 0x400>;
interrupts = ;
ti,hwmods = "mmc3";
@@ -1095,7 +1095,7 @@
};
 
mmc4: mmc@480d1000 {
-   compatible = "ti,omap4-hsmmc";
+   compatible = "ti,dra7-hsmmc", "ti,omap4-hsmmc";
reg = <0x480d1000 0x400>;
interrupts = ;
ti,hwmods = "mmc4";
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 21/23] dts: am57xx-beagle-x15: disable UHS and HS200 support

2017-09-21 Thread Jean-Jacques Hiblot
The UHS modes are not supported in beagle-x15 because it's not possible to
switch the IO lines supply voltage to 1.8v.
Also HS200 cannot be supported on mmc2, because the IO lines of mmc2 are
connected to 3.3v.

Signed-off-by: Jean-Jacques Hiblot 
---
 arch/arm/dts/am57xx-beagle-x15.dts | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/dts/am57xx-beagle-x15.dts 
b/arch/arm/dts/am57xx-beagle-x15.dts
index d668910..8d9bdf1 100644
--- a/arch/arm/dts/am57xx-beagle-x15.dts
+++ b/arch/arm/dts/am57xx-beagle-x15.dts
@@ -25,6 +25,11 @@
pinctrl-1 = <_pins_hs>;
 
vmmc-supply = <_reg>;
+   /delete-property/ sd-uhs-sdr104;
+   /delete-property/ sd-uhs-sdr50;
+   /delete-property/ sd-uhs-ddr50;
+   /delete-property/ sd-uhs-sdr25;
+   /delete-property/ sd-uhs-sdr12;
 };
 
  {
@@ -32,6 +37,7 @@
pinctrl-0 = <_pins_default>;
pinctrl-1 = <_pins_hs>;
pinctrl-2 = <_pins_ddr_3_3v_rev11 
_iodelay_ddr_3_3v_rev11_conf>;
+   /delete-property/ mmc-hs200-1_8v;
 };
 
 /* errata i880 "Ethernet RGMII2 Limited to 10/100 Mbps" */
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 15/23] mmc: omap_hsmmc: implement send_init_stream callback

2017-09-21 Thread Jean-Jacques Hiblot
This callback is used to send the 74 clock cycles after power up.

Signed-off-by: Jean-Jacques Hiblot 
---
 drivers/mmc/omap_hsmmc.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 82ec69e..0a4f8a7 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -46,6 +46,7 @@
 #include 
 #endif
 #include 
+#include 
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -562,6 +563,14 @@ tuning_error:
 
return ret;
 }
+
+static void omap_hsmmc_send_init_stream(struct udevice *dev)
+{
+   struct omap_hsmmc_data *priv = dev_get_priv(dev);
+   struct hsmmc *mmc_base = priv->base_addr;
+
+   mmc_init_stream(mmc_base);
+}
 #endif
 
 static void mmc_enable_irq(struct mmc *mmc, struct mmc_cmd *cmd)
@@ -650,7 +659,10 @@ static int omap_hsmmc_init_setup(struct mmc *mmc)
writel(readl(_base->hctl) | SDBP_PWRON, _base->hctl);
 
mmc_enable_irq(mmc, NULL);
+
+#if !CONFIG_IS_ENABLED(DM_MMC)
mmc_init_stream(mmc_base);
+#endif
 
return 0;
 }
@@ -1273,6 +1285,7 @@ static const struct dm_mmc_ops omap_hsmmc_ops = {
.get_wp = omap_hsmmc_getwp,
 #endif
.execute_tuning = omap_hsmmc_execute_tuning,
+   .send_init_stream   = omap_hsmmc_send_init_stream,
 };
 #else
 static const struct mmc_ops omap_hsmmc_ops = {
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 12/23] mmc: omap_hsmmc: Add support to get pinctrl values and max frequency for different hw revisions

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

AM572x SR1.1 requires different IODelay values to be used than that used
in AM572x SR2.0. These values are populated in device tree. Add
capability in omap_hsmmc driver to extract IOdelay values for different
silicon revision. The maximum frequency is also reduced when using a ES1.1.
To keep the ability to boot both revsions with the same dtb, those values
can be provided by the platform code.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
---
 arch/arm/include/asm/arch-omap5/sys_proto.h |  7 
 arch/arm/include/asm/omap_mmc.h |  1 +
 drivers/mmc/omap_hsmmc.c| 58 ++---
 3 files changed, 52 insertions(+), 14 deletions(-)

diff --git a/arch/arm/include/asm/arch-omap5/sys_proto.h 
b/arch/arm/include/asm/arch-omap5/sys_proto.h
index ab0e7fa..d391ee5 100644
--- a/arch/arm/include/asm/arch-omap5/sys_proto.h
+++ b/arch/arm/include/asm/arch-omap5/sys_proto.h
@@ -35,6 +35,12 @@ struct pad_conf_entry {
u32 val;
 };
 
+struct mmc_platform_fixups {
+   const char *hw_rev;
+   u32 unsupported_caps;
+   u32 max_freq;
+};
+
 struct omap_sysinfo {
char *board_string;
 };
@@ -70,6 +76,7 @@ void force_emif_self_refresh(void);
 void get_ioregs(const struct ctrl_ioregs **regs);
 void srcomp_enable(void);
 void setup_warmreset_time(void);
+const struct mmc_platform_fixups *platform_fixups_mmc(uint32_t addr);
 
 static inline u32 div_round_up(u32 num, u32 den)
 {
diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h
index 0893844..3073805 100644
--- a/arch/arm/include/asm/omap_mmc.h
+++ b/arch/arm/include/asm/omap_mmc.h
@@ -70,6 +70,7 @@ struct omap_hsmmc_plat {
struct mmc mmc;
bool cd_inverted;
u32 controller_flags;
+   const char *hw_rev;
 };
 
 /*
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 67ba31e..a83c589 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -96,6 +96,7 @@ struct omap_hsmmc_data {
struct omap_hsmmc_adma_desc *adma_desc_table;
uint desc_slot;
 #endif
+   const char *hw_rev;
 #ifdef CONFIG_IODELAY_RECALIBRATION
struct omap_hsmmc_pinctrl_state *default_pinctrl_state;
struct omap_hsmmc_pinctrl_state *hs_pinctrl_state;
@@ -1362,6 +1363,7 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, 
uint f_max, int cd_gpio,
if ((get_cpu_family() == CPU_OMAP34XX) && (get_cpu_rev() <= 
CPU_3XX_ES21))
cfg->b_max = 1;
 #endif
+
mmc = mmc_create(cfg, priv);
if (mmc == NULL)
return -1;
@@ -1581,20 +1583,28 @@ err_pinctrl_state:
return 0;
 }
 
-#define OMAP_HSMMC_SETUP_PINCTRL(capmask, mode)\
-   do {\
-   struct omap_hsmmc_pinctrl_state *s; \
-   if (!(cfg->host_caps & capmask))\
-   break;  \
-   \
-   s = omap_hsmmc_get_pinctrl_by_mode(mmc, #mode); \
-   if (!s) {   \
-   debug("%s: no pinctrl for %s\n",\
- mmc->dev->name, #mode);   \
-   cfg->host_caps &= ~(capmask);   \
-   } else {\
-   priv->mode##_pinctrl_state = s; \
-   }   \
+#define OMAP_HSMMC_SETUP_PINCTRL(capmask, mode)
\
+   do {\
+   struct omap_hsmmc_pinctrl_state *s = NULL;  \
+   char str[20];   \
+   if (!(cfg->host_caps & capmask))\
+   break;  \
+   \
+   if (priv->hw_rev) { \
+   sprintf(str, "%s-%s", #mode, priv->hw_rev); \
+   s = omap_hsmmc_get_pinctrl_by_mode(mmc, str);   \
+   }   \
+   \
+   if (!s) \
+   s = omap_hsmmc_get_pinctrl_by_mode(mmc, #mode); \
+   \
+   if (!s) {   \
+   debug("%s: no pinctrl for %s\n",\
+ 

[U-Boot] [PATCH 14/23] mmc: omap_hsmmc: update mmc->clock with the actual bus speed

2017-09-21 Thread Jean-Jacques Hiblot
When the clock is applied, compute the actual value of the clock. It may be
slightly different from the requested value (max freq, divisor threshold)

Signed-off-by: Jean-Jacques Hiblot 
---
 drivers/mmc/omap_hsmmc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 615eb4c..82ec69e 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -1143,7 +1143,8 @@ static void omap_hsmmc_set_clock(struct mmc *mmc)
}
}
 
-   priv->clock = mmc->clock;
+   priv->clock = MMC_CLOCK_REFERENCE * 100 / dsor;
+   mmc->clock = priv->clock;
omap_hsmmc_start_clock(mmc_base);
 }
 
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 23/23] ARM: DRA7x/AM57x: Add MMC/SD fixups for rev1.0 and rev 1.1

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

Since DRA7xx/AM57xx SR1.1 and SR1.0 has errata to limit the frequency of
MMC1 to 96MHz and frequency of MMC2 to 48MHz for AM572x SR1.1, limit the
frequency and disable higher speed modes for those revision.
Also use the recommended IO delays (those tagged with "rev11")

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
---
 board/ti/am57xx/board.c | 30 ++
 board/ti/dra7xx/evm.c   | 29 +
 2 files changed, 59 insertions(+)

diff --git a/board/ti/am57xx/board.c b/board/ti/am57xx/board.c
index f79aefd..4f2f8ef 100644
--- a/board/ti/am57xx/board.c
+++ b/board/ti/am57xx/board.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "../common/board_detect.h"
 #include "mux_data.h"
@@ -762,6 +763,35 @@ int board_mmc_init(bd_t *bis)
omap_mmc_init(1, 0, 0, -1, -1);
return 0;
 }
+
+static const struct mmc_platform_fixups am57x_es1_1_mmc1_fixups = {
+   .hw_rev = "rev11",
+   .unsupported_caps = MMC_CAP(MMC_HS_200) |
+   MMC_CAP(UHS_SDR104),
+   .max_freq = 9600,
+};
+
+static const struct mmc_platform_fixups am57x_es1_1_mmc23_fixups = {
+   .hw_rev = "rev11",
+   .unsupported_caps = MMC_CAP(MMC_HS_200) |
+   MMC_CAP(UHS_SDR104) |
+   MMC_CAP(UHS_SDR50),
+   .max_freq = 4800,
+};
+
+const struct mmc_platform_fixups *platform_fixups_mmc(uint32_t addr)
+{
+   switch (omap_revision()) {
+   case DRA752_ES1_0:
+   case DRA752_ES1_1:
+   if (addr == OMAP_HSMMC1_BASE)
+   return _es1_1_mmc1_fixups;
+   else
+   return _es1_1_mmc23_fixups;
+   default:
+   return NULL;
+   }
+}
 #endif
 
 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_OS_BOOT)
diff --git a/board/ti/dra7xx/evm.c b/board/ti/dra7xx/evm.c
index 97aae01..f82e4c0 100644
--- a/board/ti/dra7xx/evm.c
+++ b/board/ti/dra7xx/evm.c
@@ -846,6 +846,35 @@ void board_mmc_poweron_ldo(uint voltage)
palmas_mmc1_poweron_ldo(LDO1_VOLTAGE, LDO1_CTRL, voltage);
}
 }
+
+static const struct mmc_platform_fixups dra7x_es1_1_mmc1_fixups = {
+   .hw_rev = "rev11",
+   .unsupported_caps = MMC_CAP(MMC_HS_200) |
+   MMC_CAP(UHS_SDR104),
+   .max_freq = 9600,
+};
+
+static const struct mmc_platform_fixups dra7x_es1_1_mmc23_fixups = {
+   .hw_rev = "rev11",
+   .unsupported_caps = MMC_CAP(MMC_HS_200) |
+   MMC_CAP(UHS_SDR104) |
+   MMC_CAP(UHS_SDR50),
+   .max_freq = 4800,
+};
+
+const struct mmc_platform_fixups *platform_fixups_mmc(uint32_t addr)
+{
+   switch (omap_revision()) {
+   case DRA752_ES1_0:
+   case DRA752_ES1_1:
+   if (addr == OMAP_HSMMC1_BASE)
+   return _es1_1_mmc1_fixups;
+   else
+   return _es1_1_mmc23_fixups;
+   default:
+   return NULL;
+   }
+}
 #endif
 
 #ifdef CONFIG_USB_DWC3
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 10/23] ARM: OMAP5/DRA7: Enable iodelay recalibration to be done from uboot

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

Add a new API to perform iodelay recalibration without isolate
io to be used in uboot.

The data manual of J6/J6 Eco recommends to set different IODELAY values
depending on the mode in which the MMC/SD is enumerated in order to
ensure IO timings are met. The MMC driver can use the new API to
set the IO delay values depending on the MMC mode.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
---
 arch/arm/include/asm/arch-omap5/dra7xx_iodelay.h |  3 +++
 arch/arm/mach-omap2/omap5/dra7xx_iodelay.c   | 30 
 include/configs/am57xx_evm.h |  2 --
 include/configs/dra7xx_evm.h |  2 --
 4 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/arch/arm/include/asm/arch-omap5/dra7xx_iodelay.h 
b/arch/arm/include/asm/arch-omap5/dra7xx_iodelay.h
index c997004..a8780ee 100644
--- a/arch/arm/include/asm/arch-omap5/dra7xx_iodelay.h
+++ b/arch/arm/include/asm/arch-omap5/dra7xx_iodelay.h
@@ -83,6 +83,9 @@
 void __recalibrate_iodelay(struct pad_conf_entry const *pad, int npads,
   struct iodelay_cfg_entry const *iodelay,
   int niodelays);
+void late_recalibrate_iodelay(struct pad_conf_entry const *pad, int npads,
+ struct iodelay_cfg_entry const *iodelay,
+ int niodelays);
 int __recalibrate_iodelay_start(void);
 void __recalibrate_iodelay_end(int ret);
 
diff --git a/arch/arm/mach-omap2/omap5/dra7xx_iodelay.c 
b/arch/arm/mach-omap2/omap5/dra7xx_iodelay.c
index 8798730..a9a9f75 100644
--- a/arch/arm/mach-omap2/omap5/dra7xx_iodelay.c
+++ b/arch/arm/mach-omap2/omap5/dra7xx_iodelay.c
@@ -272,3 +272,33 @@ err:
__recalibrate_iodelay_end(ret);
 
 }
+
+void late_recalibrate_iodelay(struct pad_conf_entry const *pad, int npads,
+ struct iodelay_cfg_entry const *iodelay,
+ int niodelays)
+{
+   int ret = 0;
+
+   /* unlock IODELAY CONFIG registers */
+   writel(CFG_IODELAY_UNLOCK_KEY, (*ctrl)->iodelay_config_base +
+  CFG_REG_8_OFFSET);
+
+   ret = calibrate_iodelay((*ctrl)->iodelay_config_base);
+   if (ret)
+   goto err;
+
+   ret = update_delay_mechanism((*ctrl)->iodelay_config_base);
+
+   /* Configure Mux settings */
+   do_set_mux32((*ctrl)->control_padconf_core_base, pad, npads);
+
+   /* Configure Manual IO timing modes */
+   ret = do_set_iodelay((*ctrl)->iodelay_config_base, iodelay, niodelays);
+   if (ret)
+   goto err;
+
+err:
+   /* lock IODELAY CONFIG registers */
+   writel(CFG_IODELAY_LOCK_KEY, (*ctrl)->iodelay_config_base +
+  CFG_REG_8_OFFSET);
+}
diff --git a/include/configs/am57xx_evm.h b/include/configs/am57xx_evm.h
index 0c70c53..4125391 100644
--- a/include/configs/am57xx_evm.h
+++ b/include/configs/am57xx_evm.h
@@ -15,9 +15,7 @@
 #include 
 #include 
 
-#ifdef CONFIG_SPL_BUILD
 #define CONFIG_IODELAY_RECALIBRATION
-#endif
 
 #define CONFIG_NR_DRAM_BANKS   2
 
diff --git a/include/configs/dra7xx_evm.h b/include/configs/dra7xx_evm.h
index 6c0fc35..435284a 100644
--- a/include/configs/dra7xx_evm.h
+++ b/include/configs/dra7xx_evm.h
@@ -14,9 +14,7 @@
 
 #include 
 
-#ifdef CONFIG_SPL_BUILD
 #define CONFIG_IODELAY_RECALIBRATION
-#endif
 
 #define CONFIG_VERY_BIG_RAM
 #define CONFIG_NR_DRAM_BANKS   2
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 22/23] dts: am57xx-idk: disable HS200 support

2017-09-21 Thread Jean-Jacques Hiblot
HS200 cannot be supported on mmc2, because the IO lines of mmc2 are
connected to 3.3v.

Signed-off-by: Jean-Jacques Hiblot 
---
 arch/arm/dts/am57xx-idk-common.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/dts/am57xx-idk-common.dtsi 
b/arch/arm/dts/am57xx-idk-common.dtsi
index 97aa8e6..fa5a078 100644
--- a/arch/arm/dts/am57xx-idk-common.dtsi
+++ b/arch/arm/dts/am57xx-idk-common.dtsi
@@ -413,6 +413,8 @@
bus-width = <8>;
ti,non-removable;
max-frequency = <9600>;
+   no-1-8-v;
+   /delete-property/ mmc-hs200-1_8v;
 };
 
  {
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 17/23] mmc: omap_hsmmc: add signal voltage selection support

2017-09-21 Thread Jean-Jacques Hiblot
I/O data lines of UHS SD card operates at 1.8V when in UHS speed
mode (same is true for eMMC in DDR and HS200 modes). Add support
to switch signal voltage to 1.8V in order to support
UHS cards and eMMC HS200 and DDR modes.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
---
 arch/arm/include/asm/omap_mmc.h |  10 ++-
 drivers/mmc/omap_hsmmc.c| 162 +++-
 2 files changed, 151 insertions(+), 21 deletions(-)

diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h
index 3073805..6871f54 100644
--- a/arch/arm/include/asm/omap_mmc.h
+++ b/arch/arm/include/asm/omap_mmc.h
@@ -172,10 +172,6 @@ struct omap_hsmmc_plat {
 #define VS30_3V0SUPBIT(25)
 #define VS18_1V8SUPBIT(26)
 
-#define IOV_3V3330
-#define IOV_3V0300
-#define IOV_1V8180
-
 #define AC12_ET(1 << 22)
 #define AC12_V1V8_SIGEN(1 << 19)
 #define AC12_SCLK_SEL  (1 << 23)
@@ -224,6 +220,12 @@ struct omap_hsmmc_plat {
IE_DTO | IE_CIE | IE_CEB | IE_CCRC | IE_ADMAE | IE_CTO |\
IE_BRR | IE_BWR | IE_TC | IE_CC)
 
+#define CON_CLKEXTFREE BIT(16)
+#define CON_PADEN  BIT(15)
+#define PSTATE_CLEVBIT(24)
+#define PSTATE_DLEV(0xF << 20)
+#define PSTATE_DLEV_DAT0   (0x1 << 20)
+
 int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
int wp_gpio);
 
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index f3da446..ecf5171 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -78,6 +78,7 @@ struct omap_hsmmc_data {
 #endif
uint bus_width;
uint clock;
+   ushort last_cmd;
 #ifdef OMAP_HSMMC_USE_GPIO
 #if CONFIG_IS_ENABLED(DM_MMC)
struct gpio_desc cd_gpio;   /* Change Detect GPIO */
@@ -89,7 +90,6 @@ struct omap_hsmmc_data {
 #endif
 #endif
 #if CONFIG_IS_ENABLED(DM_MMC)
-   uint iov;
enum bus_mode mode;
 #endif
u8 controller_flags;
@@ -98,6 +98,8 @@ struct omap_hsmmc_data {
uint desc_slot;
 #endif
const char *hw_rev;
+   struct udevice *pbias_supply;
+   uint signal_voltage;
 #ifdef CONFIG_IODELAY_RECALIBRATION
struct omap_hsmmc_pinctrl_state *default_pinctrl_state;
struct omap_hsmmc_pinctrl_state *hs_pinctrl_state;
@@ -254,7 +256,8 @@ static unsigned char mmc_board_init(struct mmc *mmc)
_base->iclken1_core);
 #endif
 
-#if defined(CONFIG_OMAP54XX) || defined(CONFIG_OMAP44XX)
+#if (defined(CONFIG_OMAP54XX) || defined(CONFIG_OMAP44XX)) &&\
+   !CONFIG_IS_ENABLED(DM_REGULATOR)
/* PBIAS config needed for MMC1 only */
if (mmc_get_blk_desc(mmc)->devnum == 0)
vmmc_pbias_config(LDO_VOLT_3V0);
@@ -398,7 +401,7 @@ static void omap_hsmmc_set_timing(struct mmc *mmc)
omap_hsmmc_start_clock(mmc_base);
 }
 
-static void omap_hsmmc_conf_bus_power(struct mmc *mmc)
+static void omap_hsmmc_conf_bus_power(struct mmc *mmc, uint signal_voltage)
 {
struct hsmmc *mmc_base;
struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
@@ -408,14 +411,11 @@ static void omap_hsmmc_conf_bus_power(struct mmc *mmc)
 
val = readl(_base->hctl) & ~SDVS_MASK;
 
-   switch (priv->iov) {
-   case IOV_3V3:
-   val |= SDVS_3V3;
-   break;
-   case IOV_3V0:
+   switch (signal_voltage) {
+   case MMC_SIGNAL_VOLTAGE_330:
val |= SDVS_3V0;
break;
-   case IOV_1V8:
+   case MMC_SIGNAL_VOLTAGE_180:
val |= SDVS_1V8;
break;
}
@@ -423,7 +423,126 @@ static void omap_hsmmc_conf_bus_power(struct mmc *mmc)
writel(val, _base->hctl);
 }
 
-static void omap_hsmmc_set_capabilities(struct mmc *mmc)
+static int omap_hsmmc_wait_dat0(struct udevice *dev, int state, int timeout)
+{
+   int ret = -ETIMEDOUT;
+   u32 con;
+   bool dat0_high;
+   bool target_dat0_high = !!state;
+   struct omap_hsmmc_data *priv = dev_get_priv(dev);
+   struct hsmmc *mmc_base = priv->base_addr;
+
+   con = readl(_base->con);
+   writel(con | CON_CLKEXTFREE | CON_PADEN, _base->con);
+
+   timeout = DIV_ROUND_UP(timeout, 10); /* check every 10 us. */
+   while (timeout--)   {
+   dat0_high = !!(readl(_base->pstate) & PSTATE_DLEV_DAT0);
+   if (dat0_high == target_dat0_high) {
+   ret = 0;
+   break;
+   }
+   udelay(10);
+   }
+   writel(con, _base->con);
+
+   return ret;
+}
+
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
+static int omap_hsmmc_set_io_regulator(struct mmc *mmc, int mV)
+{
+   int ret = 0;
+   int uV = mV * 1000;
+
+   

[U-Boot] [PATCH 05/23] mmc: omap_hsmmc: Enable DDR mode support

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

In order to enable DDR mode, Dual Data Rate mode bit has to be set in
MMCHS_CON register. Set it here.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
---
 arch/arm/include/asm/omap_mmc.h | 1 +
 drivers/mmc/omap_hsmmc.c| 5 +
 2 files changed, 6 insertions(+)

diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h
index 3f94f2e..341a2e2 100644
--- a/arch/arm/include/asm/omap_mmc.h
+++ b/arch/arm/include/asm/omap_mmc.h
@@ -89,6 +89,7 @@ struct omap_hsmmc_plat {
 #define WPP_ACTIVEHIGH (0x0 << 8)
 #define RESERVED_MASK  (0x3 << 9)
 #define CTPL_MMC_SD(0x0 << 11)
+#define DDR(0x1 << 19)
 #define DMA_MASTER (0x1 << 20)
 #define BLEN_512BYTESLEN   (0x200 << 0)
 #define NBLK_STPCNT(0x0 << 16)
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 4a65a46..d5cd826 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -271,6 +271,11 @@ static void omap_hsmmc_set_timing(struct mmc *mmc)
val &= ~AC12_UHSMC_MASK;
priv->mode = mmc->selected_mode;
 
+   if (mmc_is_mode_ddr(priv->mode))
+   writel(readl(_base->con) | DDR, _base->con);
+   else
+   writel(readl(_base->con) & ~DDR, _base->con);
+
switch (priv->mode) {
case MMC_HS_200:
case UHS_SDR104:
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 11/23] mmc: omap_hsmmc: Add support to set IODELAY values

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

The data manual of J6/J6 Eco recommends to set different IODELAY values
depending on the mode in which the MMC/SD is enumerated in order to
ensure IO timings are met.

Add support to parse mux values and iodelay values from device tree
and set these depending on the enumerated MMC mode.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
---
 drivers/mmc/omap_hsmmc.c | 372 +++
 1 file changed, 372 insertions(+)

diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 734854b..67ba31e 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -34,6 +34,10 @@
 #include 
 #include 
 #include 
+#ifdef CONFIG_OMAP54XX
+#include 
+#include 
+#endif
 #if !defined(CONFIG_SOC_KEYSTONE)
 #include 
 #include 
@@ -57,6 +61,15 @@ DECLARE_GLOBAL_DATA_PTR;
 #define SYSCTL_SRC (1 << 25)
 #define SYSCTL_SRD (1 << 26)
 
+#ifdef CONFIG_IODELAY_RECALIBRATION
+struct omap_hsmmc_pinctrl_state {
+   struct pad_conf_entry *padconf;
+   int npads;
+   struct iodelay_cfg_entry *iodelay;
+   int niodelays;
+};
+#endif
+
 struct omap_hsmmc_data {
struct hsmmc *base_addr;
 #if !CONFIG_IS_ENABLED(DM_MMC)
@@ -83,6 +96,17 @@ struct omap_hsmmc_data {
struct omap_hsmmc_adma_desc *adma_desc_table;
uint desc_slot;
 #endif
+#ifdef CONFIG_IODELAY_RECALIBRATION
+   struct omap_hsmmc_pinctrl_state *default_pinctrl_state;
+   struct omap_hsmmc_pinctrl_state *hs_pinctrl_state;
+   struct omap_hsmmc_pinctrl_state *hs200_1_8v_pinctrl_state;
+   struct omap_hsmmc_pinctrl_state *ddr_1_8v_pinctrl_state;
+   struct omap_hsmmc_pinctrl_state *sdr12_pinctrl_state;
+   struct omap_hsmmc_pinctrl_state *sdr25_pinctrl_state;
+   struct omap_hsmmc_pinctrl_state *ddr50_pinctrl_state;
+   struct omap_hsmmc_pinctrl_state *sdr50_pinctrl_state;
+   struct omap_hsmmc_pinctrl_state *sdr104_pinctrl_state;
+#endif
 };
 
 #ifndef CONFIG_OMAP34XX
@@ -93,6 +117,10 @@ struct omap_hsmmc_adma_desc {
u32 addr;
 };
 
+struct omap_mmc_of_data {
+   u8 controller_flags;
+};
+
 #define ADMA_MAX_LEN   63488
 
 /* Decriptor table defines */
@@ -119,6 +147,7 @@ struct omap_hsmmc_adma_desc {
 #define OMAP_HSMMC_SUPPORTS_DUAL_VOLT  BIT(0)
 #define OMAP_HSMMC_NO_1_8_VBIT(1)
 #define OMAP_HSMMC_USE_ADMABIT(2)
+#define OMAP_HSMMC_REQUIRE_IODELAY BIT(3)
 
 static int mmc_read_data(struct hsmmc *mmc_base, char *buf, unsigned int size);
 static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
@@ -261,6 +290,56 @@ void mmc_init_stream(struct hsmmc *mmc_base)
 }
 
 #if CONFIG_IS_ENABLED(DM_MMC)
+#ifdef CONFIG_IODELAY_RECALIBRATION
+static void omap_hsmmc_io_recalibrate(struct mmc *mmc)
+{
+   struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
+   struct omap_hsmmc_pinctrl_state *pinctrl_state;
+
+   switch (priv->mode) {
+   case MMC_HS_200:
+   pinctrl_state = priv->hs200_1_8v_pinctrl_state;
+   break;
+   case UHS_SDR104:
+   pinctrl_state = priv->sdr104_pinctrl_state;
+   break;
+   case UHS_SDR50:
+   pinctrl_state = priv->sdr50_pinctrl_state;
+   break;
+   case UHS_DDR50:
+   pinctrl_state = priv->ddr50_pinctrl_state;
+   break;
+   case UHS_SDR25:
+   pinctrl_state = priv->sdr25_pinctrl_state;
+   break;
+   case UHS_SDR12:
+   pinctrl_state = priv->sdr12_pinctrl_state;
+   break;
+   case SD_HS:
+   case MMC_HS:
+   case MMC_HS_52:
+   pinctrl_state = priv->hs_pinctrl_state;
+   break;
+   case MMC_DDR_52:
+   pinctrl_state = priv->ddr_1_8v_pinctrl_state;
+   default:
+   pinctrl_state = priv->default_pinctrl_state;
+   break;
+   }
+
+   if (priv->controller_flags & OMAP_HSMMC_REQUIRE_IODELAY) {
+   if (pinctrl_state->iodelay)
+   late_recalibrate_iodelay(pinctrl_state->padconf,
+pinctrl_state->npads,
+pinctrl_state->iodelay,
+pinctrl_state->niodelays);
+   else
+   do_set_mux32((*ctrl)->control_padconf_core_base,
+pinctrl_state->padconf,
+pinctrl_state->npads);
+   }
+}
+#endif
 static void omap_hsmmc_set_timing(struct mmc *mmc)
 {
u32 val;
@@ -269,6 +348,7 @@ static void omap_hsmmc_set_timing(struct mmc *mmc)
 
mmc_base = priv->base_addr;
 
+   omap_hsmmc_stop_clock(mmc_base);
val = readl(_base->ac12);
val &= ~AC12_UHSMC_MASK;
priv->mode = 

[U-Boot] [PATCH 16/23] mmc: omap_hsmmc: allow mmc clock to be gated

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

mmc core has defined a new parameter *clk_disable* to gate the clock.
Disable the clock here if *clk_disable* is set.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
---
 drivers/mmc/omap_hsmmc.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 0a4f8a7..f3da446 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -1203,6 +1203,7 @@ static int omap_hsmmc_set_ios(struct udevice *dev)
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
struct mmc *mmc = upriv->mmc;
 #endif
+   struct hsmmc *mmc_base = priv->base_addr;
 
if (priv->bus_width != mmc->bus_width)
omap_hsmmc_set_bus_width(mmc);
@@ -1210,6 +1211,11 @@ static int omap_hsmmc_set_ios(struct udevice *dev)
if (priv->clock != mmc->clock)
omap_hsmmc_set_clock(mmc);
 
+   if (mmc->clk_disable)
+   omap_hsmmc_stop_clock(mmc_base);
+   else
+   omap_hsmmc_start_clock(mmc_base);
+
 #if CONFIG_IS_ENABLED(DM_MMC)
if (priv->mode != mmc->selected_mode)
omap_hsmmc_set_timing(mmc);
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 01/23] mmc: omap_hsmmc: cleanup clock configuration

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

Add a separate function for starting the clock, stopping the clock and
setting the clock. Starting the clock and stopping the clock can
be used irrespective of setting the clock (For example during iodelay
recalibration).
Also set the clock only if there is a change in frequency.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
---
 arch/arm/include/asm/omap_mmc.h |  2 ++
 drivers/mmc/omap_hsmmc.c| 74 -
 2 files changed, 52 insertions(+), 24 deletions(-)

diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h
index bf9de9b..102aec2 100644
--- a/arch/arm/include/asm/omap_mmc.h
+++ b/arch/arm/include/asm/omap_mmc.h
@@ -172,6 +172,8 @@ struct omap_hsmmc_plat {
 #define CLK_400KHZ 1
 #define CLK_MISC   2
 
+#define CLKD_MAX   0x3FF   /* max clock divisor: 1023 */
+
 #define RSP_TYPE_NONE  (RSP_TYPE_NORSP   | CCCE_NOCHECK | CICE_NOCHECK)
 #define MMC_CMD0   (INDEX(0)  | RSP_TYPE_NONE | DP_NO_DATA | DDIR_WRITE)
 
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 1c3d1a5..6ef8295 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -62,6 +62,7 @@ struct omap_hsmmc_data {
 #if !CONFIG_IS_ENABLED(DM_MMC)
struct mmc_config cfg;
 #endif
+   uint clock;
 #ifdef OMAP_HSMMC_USE_GPIO
 #if CONFIG_IS_ENABLED(DM_MMC)
struct gpio_desc cd_gpio;   /* Change Detect GPIO */
@@ -114,6 +115,8 @@ struct omap_hsmmc_adma_desc {
 static int mmc_read_data(struct hsmmc *mmc_base, char *buf, unsigned int size);
 static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
unsigned int siz);
+static void omap_hsmmc_start_clock(struct hsmmc *mmc_base);
+static void omap_hsmmc_stop_clock(struct hsmmc *mmc_base);
 
 static inline struct omap_hsmmc_data *omap_hsmmc_get_data(struct mmc *mmc)
 {
@@ -762,6 +765,51 @@ static int mmc_write_data(struct hsmmc *mmc_base, const 
char *buf,
return 0;
 }
 
+static void omap_hsmmc_stop_clock(struct hsmmc *mmc_base)
+{
+   writel(readl(_base->sysctl) & ~CEN_ENABLE, _base->sysctl);
+}
+
+static void omap_hsmmc_start_clock(struct hsmmc *mmc_base)
+{
+   writel(readl(_base->sysctl) | CEN_ENABLE, _base->sysctl);
+}
+
+static void omap_hsmmc_set_clock(struct mmc *mmc)
+{
+   struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
+   struct hsmmc *mmc_base;
+   unsigned int dsor = 0;
+   ulong start;
+
+   mmc_base = priv->base_addr;
+   omap_hsmmc_stop_clock(mmc_base);
+
+   /* TODO: Is setting DTO required here? */
+   mmc_reg_out(_base->sysctl, (ICE_MASK | DTO_MASK),
+   (ICE_STOP | DTO_15THDTO));
+
+   if (mmc->clock != 0) {
+   dsor = DIV_ROUND_UP(MMC_CLOCK_REFERENCE * 100, mmc->clock);
+   if (dsor > CLKD_MAX)
+   dsor = CLKD_MAX;
+   }
+
+   mmc_reg_out(_base->sysctl, ICE_MASK | CLKD_MASK,
+   (dsor << CLKD_OFFSET) | ICE_OSCILLATE);
+
+   start = get_timer(0);
+   while ((readl(_base->sysctl) & ICS_MASK) == ICS_NOTREADY) {
+   if (get_timer(0) - start > MAX_RETRY_MS) {
+   printf("%s: timedout waiting for ics!\n", __func__);
+   return;
+   }
+   }
+
+   priv->clock = mmc->clock;
+   omap_hsmmc_start_clock(mmc_base);
+}
+
 #if !CONFIG_IS_ENABLED(DM_MMC)
 static int omap_hsmmc_set_ios(struct mmc *mmc)
 {
@@ -774,8 +822,6 @@ static int omap_hsmmc_set_ios(struct udevice *dev)
struct mmc *mmc = upriv->mmc;
 #endif
struct hsmmc *mmc_base;
-   unsigned int dsor = 0;
-   ulong start;
 
mmc_base = priv->base_addr;
/* configue bus width */
@@ -801,28 +847,8 @@ static int omap_hsmmc_set_ios(struct udevice *dev)
break;
}
 
-   /* configure clock with 96Mhz system clock.
-*/
-   if (mmc->clock != 0) {
-   dsor = (MMC_CLOCK_REFERENCE * 100 / mmc->clock);
-   if ((MMC_CLOCK_REFERENCE * 100) / dsor > mmc->clock)
-   dsor++;
-   }
-
-   mmc_reg_out(_base->sysctl, (ICE_MASK | DTO_MASK | CEN_MASK),
-   (ICE_STOP | DTO_15THDTO));
-
-   mmc_reg_out(_base->sysctl, ICE_MASK | CLKD_MASK,
-   (dsor << CLKD_OFFSET) | ICE_OSCILLATE);
-
-   start = get_timer(0);
-   while ((readl(_base->sysctl) & ICS_MASK) == ICS_NOTREADY) {
-   if (get_timer(0) - start > MAX_RETRY_MS) {
-   printf("%s: timedout waiting for ics!\n", __func__);
-   return -ETIMEDOUT;
-   }
-   }
-   writel(readl(_base->sysctl) | CEN_ENABLE, _base->sysctl);
+   if (priv->clock != mmc->clock)
+   omap_hsmmc_set_clock(mmc);
 
 

[U-Boot] [PATCH 00/23] mmc: omap5: Add support for UHS and HS200 modes

2017-09-21 Thread Jean-Jacques Hiblot
This series adds the missing bit to enable the UHS, HS200 and DDR52 modes
on the omap5 platforms (DRA7 and AM57).

It relies on the following series:
* [PATCH v2 00/26] mmc: Add support for HS200 and UHS modes
* [PATCH v2 0/5] mmc: omap_hsmmc: Add support for ADMA
* [PATCH v3 0/2] power: Add a driver to handle the PBIAS cell of the TI SOCs

Enabling support for high speed modes on omap5 requires implementing:
 * io signal voltage selection
 * tuning support
 * pin configuration (IO delays)
 
The few last patches enable the high mode for all omap5 platforms except some
for which we need to disable either the UHS or the HS200 because the volatge
regulators on board would not allow using those modes. This is not a SOC
limitation.

With this in place we observe significant improvements in the performances:
on a DRA72 evm:
eMMC HS200: 124 MB/s
eMMC DDR52: 78 MB/s
sd   SDR104: 71 MB/s
sd   SDR50: 44 MB/s
For the record, the original performances were:
SD High speed: 18 MB/s
MMC High speed: 18 MB/s

This series has been tested on:
* DRA71-evm
* DRA72-evm
* DRA7x-evm
* DRA76-evm
* AM57x-evm
* Beaglebone Black
* AM335x evm
* AM437x SK

Jean-Jacques
 


Jean-Jacques Hiblot (8):
  mmc: omap_hsmmc: Reduce the max timeout for reset controller fsm
  mmc: omap_hsmmc: allow the simple HS modes to use the default pinctrl
  mmc: omap_hsmmc: update mmc->clock with the actual bus speed
  mmc: omap_hsmmc: implement send_init_stream callback
  mmc: omap_hsmmc: add signal voltage selection support
  ARM: dts: dra7: Add supported MMC/SD modes in MMC dt nodes
  dts: am57xx-beagle-x15: disable UHS and HS200 support
  dts: am57xx-idk: disable HS200 support

Kishon Vijay Abraham I (15):
  mmc: omap_hsmmc: cleanup clock configuration
  mmc: omap_hsmmc: cleanup omap_hsmmc_set_ios
  mmc: omap_hsmmc: add support to set default io voltage
  mmc: omap_hsmmc: set MMC mode in the UHSMS bit field
  mmc: omap_hsmmc: Enable DDR mode support
  mmc: omap_hsmmc: Add tuning support
  mmc: omap_hsmmc: Workaround for errata id i802
  mmc: omap_hsmmc: use mmc_of_parse to populate mmc_config
  ARM: OMAP5/DRA7: Enable iodelay recalibration to be done from uboot
  mmc: omap_hsmmc: Add support to set IODELAY values
  mmc: omap_hsmmc: Add support to get pinctrl values and max frequency
for different hw revisions
  mmc: omap_hsmmc: allow mmc clock to be gated
  ARM: OMAP5: set mmc clock frequency to 192MHz
  ARM: dts: DRA7: use new dra7-specific compatible string
  ARM: DRA7x/AM57x: Add MMC/SD fixups for rev1.0 and rev 1.1

 arch/arm/dts/am57xx-beagle-x15.dts   |   6 +
 arch/arm/dts/am57xx-idk-common.dtsi  |   2 +
 arch/arm/dts/dra7.dtsi   |  22 +-
 arch/arm/include/asm/arch-omap5/clock.h  |   2 +-
 arch/arm/include/asm/arch-omap5/dra7xx_iodelay.h |   3 +
 arch/arm/include/asm/arch-omap5/sys_proto.h  |   7 +
 arch/arm/include/asm/omap_mmc.h  |  59 +-
 arch/arm/mach-omap2/omap5/dra7xx_iodelay.c   |  30 +
 arch/arm/mach-omap2/omap5/hw_data.c  |  10 +-
 board/ti/am57xx/board.c  |  30 +
 board/ti/dra7xx/evm.c|  29 +
 drivers/mmc/omap_hsmmc.c | 940 +--
 include/configs/am57xx_evm.h |   2 -
 include/configs/dra7xx_evm.h |   2 -
 14 files changed, 1071 insertions(+), 73 deletions(-)

-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v3 0/2] power: Add a driver to handle the PBIAS cell of the TI SOCs

2017-09-21 Thread Jean-Jacques Hiblot
In the TI SOCs a PBIAS cell exists to provide a bias voltage to the MMC1
IO cells. Without this bias voltage these I/O cells can not function
properly. This bias voltage is either 1.8v or 3.0v.

The first patch adds 2 functions to the DM core: to count strings in a
stringlist and get a string from a stringlist based on its position in the
list.
The second patch implements the support for this PBIAS cell as a regulator
driver.

Jean-Jacques


changes since v2:
 * rebased on u-boot/master
 * automatically select REGMAP and SYSCON if PBIAS is selected.

changes since v1:
 - add new functions to get strings from a stringlist in DM core
 - use the dev_read_*() API to access the DT
 - automatically select the PBIAS driver if DM_REGULATOR, DM_MMC and
   MMC_OMAP_HS are set.
 - removed the patch touching the DRA7 and AM57 config files.
 

Jean-Jacques Hiblot (2):
  dm: core: Add functions to get strings and the string count from a
stringlist
  regulator: pbias: Add PBIAS regulator for proper voltage switching on
MMC1

 drivers/core/read.c   |  11 ++
 drivers/mmc/Kconfig   |   1 +
 drivers/power/regulator/Kconfig   |  13 ++
 drivers/power/regulator/Makefile  |   1 +
 drivers/power/regulator/pbias_regulator.c | 301 ++
 include/dm/read.h |  36 
 6 files changed, 363 insertions(+)
 create mode 100644 drivers/power/regulator/pbias_regulator.c

-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v3 2/2] regulator: pbias: Add PBIAS regulator for proper voltage switching on MMC1

2017-09-21 Thread Jean-Jacques Hiblot
In the TI SOCs a PBIAS cell exists to provide a bias voltage to the MMC1
IO cells. Without this bias voltage these I/O cells can not function
properly. The PBIAS cell is controlled by software.

Signed-off-by: Jean-Jacques Hiblot 
Reviewed-by: Tom Rini 
Reviewed-by: Simon Glass 
---
 drivers/mmc/Kconfig   |   1 +
 drivers/power/regulator/Kconfig   |  13 ++
 drivers/power/regulator/Makefile  |   1 +
 drivers/power/regulator/pbias_regulator.c | 301 ++
 4 files changed, 316 insertions(+)
 create mode 100644 drivers/power/regulator/pbias_regulator.c

diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 78e58d4..4b9bee0 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -159,6 +159,7 @@ config MMC_PCI
 config MMC_OMAP_HS
bool "TI OMAP High Speed Multimedia Card Interface support"
select DM_REGULATOR_PBIAS if DM_MMC && DM_REGULATOR
+   select DM_REGULATOR_PBIAS if DM_MMC && DM_REGULATOR
help
  This selects the TI OMAP High Speed Multimedia card Interface.
  If you have an omap2plus board with a Multimedia Card slot,
diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig
index c82a936..2cfade1 100644
--- a/drivers/power/regulator/Kconfig
+++ b/drivers/power/regulator/Kconfig
@@ -151,6 +151,19 @@ config DM_REGULATOR_PALMAS
features for REGULATOR PALMAS and the family of PALMAS PMICs.
The driver implements get/set api for: value and enable.
 
+config DM_REGULATOR_PBIAS
+   bool "Enable driver for PBIAS regulator"
+   depends on DM_REGULATOR
+   select REGMAP
+   select SYSCON
+   ---help---
+   This enables implementation of driver-model regulator uclass
+   features for pseudo-regulator PBIAS found in the OMAP SOCs.
+   This pseudo-regulator is used to provide a BIAS voltage to MMC1
+   signal pads and must be configured properly during a voltage switch.
+   Voltage switching is required by some operating modes of SDcards and
+   eMMC.
+
 config DM_REGULATOR_LP873X
bool "Enable driver for LP873X PMIC regulators"
 depends on PMIC_LP873X
diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile
index 18fb870..6c149a9 100644
--- a/drivers/power/regulator/Makefile
+++ b/drivers/power/regulator/Makefile
@@ -18,5 +18,6 @@ obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
 obj-$(CONFIG_DM_REGULATOR_SANDBOX) += sandbox.o
 obj-$(CONFIG_REGULATOR_TPS65090) += tps65090_regulator.o
 obj-$(CONFIG_$(SPL_)DM_REGULATOR_PALMAS) += palmas_regulator.o
+obj-$(CONFIG_$(SPL_)DM_REGULATOR_PBIAS) += pbias_regulator.o
 obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP873X) += lp873x_regulator.o
 obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP87565) += lp87565_regulator.o
diff --git a/drivers/power/regulator/pbias_regulator.c 
b/drivers/power/regulator/pbias_regulator.c
new file mode 100644
index 000..914500b
--- /dev/null
+++ b/drivers/power/regulator/pbias_regulator.c
@@ -0,0 +1,301 @@
+/*
+ * (C) Copyright 2016 Texas Instruments Incorporated, 
+ * Jean-Jacques Hiblot 
+ *
+ * SPDX-License-Identifier:GPL-2.0+
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct pbias_reg_info {
+   u32 enable;
+   u32 enable_mask;
+   u32 disable_val;
+   u32 vmode;
+   unsigned int enable_time;
+   char *name;
+};
+
+struct pbias_priv {
+   struct regmap *regmap;
+   int offset;
+};
+
+static const struct pmic_child_info pmic_children_info[] = {
+   { .prefix = "pbias", .driver = "pbias_regulator"},
+   { },
+};
+
+static int pbias_write(struct udevice *dev, uint reg, const uint8_t *buff,
+  int len)
+{
+   struct pbias_priv *priv = dev_get_priv(dev);
+   u32 val = *(u32 *)buff;
+
+   if (len != 4)
+   return -EINVAL;
+
+   return regmap_write(priv->regmap, priv->offset, val);
+}
+
+static int pbias_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
+{
+   struct pbias_priv *priv = dev_get_priv(dev);
+
+   if (len != 4)
+   return -EINVAL;
+
+   return regmap_read(priv->regmap, priv->offset, (u32 *)buff);
+}
+
+static int pbias_ofdata_to_platdata(struct udevice *dev)
+{
+   struct pbias_priv *priv = dev_get_priv(dev);
+   struct udevice *syscon;
+   struct regmap *regmap;
+   struct resource res;
+   int err;
+
+   err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
+  "syscon", );
+   if (err) {
+   error("%s: unable to find syscon device (%d)\n", __func__,
+ err);
+   return err;
+   }
+
+   regmap = syscon_get_regmap(syscon);
+   if (IS_ERR(regmap)) {
+   error("%s: unable to find regmap (%ld)\n", 

[U-Boot] [PATCH v3 1/2] dm: core: Add functions to get strings and the string count from a stringlist

2017-09-21 Thread Jean-Jacques Hiblot
dev_read_string_count() is used to get the number of strings in a
stringlist.
dev_read_string_index() is used to get a string in the stringlist based on
its position in the list.

Signed-off-by: Jean-Jacques Hiblot 
---
 drivers/core/read.c | 11 +++
 include/dm/read.h   | 36 
 2 files changed, 47 insertions(+)

diff --git a/drivers/core/read.c b/drivers/core/read.c
index 065589a..eacf171 100644
--- a/drivers/core/read.c
+++ b/drivers/core/read.c
@@ -81,6 +81,17 @@ int dev_read_stringlist_search(struct udevice *dev, const 
char *property,
return ofnode_stringlist_search(dev_ofnode(dev), property, string);
 }
 
+int dev_read_string_index(struct udevice *dev, const char *propname, int index,
+ const char **outp)
+{
+   return ofnode_read_string_index(dev_ofnode(dev), propname, index, outp);
+}
+
+int dev_read_string_count(struct udevice *dev, const char *propname)
+{
+   return ofnode_read_string_count(dev_ofnode(dev), propname);
+}
+
 int dev_read_phandle_with_args(struct udevice *dev, const char *list_name,
const char *cells_name, int cell_count,
int index,
diff --git a/include/dm/read.h b/include/dm/read.h
index e7f7125..8114037 100644
--- a/include/dm/read.h
+++ b/include/dm/read.h
@@ -166,6 +166,29 @@ int dev_read_stringlist_search(struct udevice *dev, const 
char *property,
  const char *string);
 
 /**
+ * dev_read_string_index() - obtain an indexed string from a string list
+ *
+ * @dev: device to examine
+ * @propname: name of the property containing the string list
+ * @index: index of the string to return
+ * @out: return location for the string
+ *
+ * @return:
+ *   length of string, if found or -ve error value if not found
+ */
+int dev_read_string_index(struct udevice *dev, const char *propname, int index,
+ const char **outp);
+
+/**
+ * dev_read_string_count() - find the number of strings in a string list
+ *
+ * @dev: device to examine
+ * @propname: name of the property containing the string list
+ * @return:
+ *   number of strings in the list, or -ve error value if not found
+ */
+int dev_read_string_count(struct udevice *dev, const char *propname);
+/**
  * dev_read_phandle_with_args() - Find a node pointed by phandle in a list
  *
  * This function is useful to parse lists of phandles and their arguments.
@@ -451,6 +474,19 @@ static inline int dev_read_stringlist_search(struct 
udevice *dev,
return ofnode_stringlist_search(dev_ofnode(dev), propname, string);
 }
 
+static inline int dev_read_string_index(struct udevice *dev,
+   const char *propname, int index,
+   const char **outp)
+{
+   return ofnode_read_string_index(dev_ofnode(dev), propname, index, outp);
+}
+
+static inline int dev_read_string_count(struct udevice *dev,
+   const char *propname)
+{
+   return ofnode_read_string_count(dev_ofnode(dev), propname);
+}
+
 static inline int dev_read_phandle_with_args(struct udevice *dev,
const char *list_name, const char *cells_name, int cell_count,
int index, struct ofnode_phandle_args *out_args)
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] u-boot Boot issue about rk3188

2017-09-21 Thread Heiko Stübner
Hi Andy,

Am Donnerstag, 21. September 2017, 22:03:32 CEST schrieb Andy Yan:
> Hi Heiko:
> I try to boot the upstream u-boot-rockchip branch  on my rk3188 board
> with(rock_defconfig)
> 
> But I got this error:
> early_init()
> nit_and_scan() returned error -22
> early_init() failed: -22
> ERROR ### Please RESET the board ###
> 
> the current commit head is: 782088d("rockchip: imply ADC and SARADC_ROCKCHIP
> on supported SoCs") Do you ever meet something like this?

that is very strange. When testing Philipp's branch, I was also testing the 
commit you mention to see if anything broke since I last changed u-boot
on my radxa rock. And the above commit started just fine, when starting
from an sd-card.

Not sure from which medium you're starting though. But from what I
remember Pawel got nand working in his rk3066 series, but that is not
yet merged.


Heiko
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 5/5] mmc: omap_hsmmc: Fix incorrect bit operations for disabling a bit

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

omap_hsmmc driver uses "|" in a couple of places for disabling a bit.
While it's okay to use it in "mmc_reg_out" (since mmc_reg_out has a
_mask_ argument to take care of resetting a bit), it's incorrectly used
for resetting flags in "omap_hsmmc_send_cmd".

Fix it here by using "&= ~()" to reset a bit.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
---
 arch/arm/include/asm/omap_mmc.h | 6 ++
 drivers/mmc/omap_hsmmc.c| 7 ---
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h
index 128cd81..bf9de9b 100644
--- a/arch/arm/include/asm/omap_mmc.h
+++ b/arch/arm/include/asm/omap_mmc.h
@@ -90,10 +90,9 @@ struct omap_hsmmc_plat {
 #define DMA_MASTER (0x1 << 20)
 #define BLEN_512BYTESLEN   (0x200 << 0)
 #define NBLK_STPCNT(0x0 << 16)
-#define DE_DISABLE (0x0 << 0)
-#define BCE_DISABLE(0x0 << 1)
+#define DE_ENABLE  (0x1 << 0)
 #define BCE_ENABLE (0x1 << 1)
-#define ACEN_DISABLE   (0x0 << 2)
+#define ACEN_ENABLE(0x1 << 2)
 #define DDIR_OFFSET(4)
 #define DDIR_MASK  (0x1 << 4)
 #define DDIR_WRITE (0x0 << 4)
@@ -134,7 +133,6 @@ struct omap_hsmmc_plat {
 #define ICS_NOTREADY   (0x0 << 1)
 #define ICE_OSCILLATE  (0x1 << 0)
 #define CEN_MASK   (0x1 << 2)
-#define CEN_DISABLE(0x0 << 2)
 #define CEN_ENABLE (0x1 << 2)
 #define CLKD_OFFSET(6)
 #define CLKD_MASK  (0x3FF << 6)
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index fcda0e2..1c3d1a5 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -294,7 +294,7 @@ static int omap_hsmmc_init_setup(struct mmc *mmc)
 
dsor = 240;
mmc_reg_out(_base->sysctl, (ICE_MASK | DTO_MASK | CEN_MASK),
-   (ICE_STOP | DTO_15THDTO | CEN_DISABLE));
+   (ICE_STOP | DTO_15THDTO));
mmc_reg_out(_base->sysctl, ICE_MASK | CLKD_MASK,
(dsor << CLKD_OFFSET) | ICE_OSCILLATE);
start = get_timer(0);
@@ -542,7 +542,8 @@ static int omap_hsmmc_send_cmd(struct udevice *dev, struct 
mmc_cmd *cmd,
 
/* enable default flags */
flags = flags | (CMD_TYPE_NORMAL | CICE_NOCHECK | CCCE_NOCHECK |
-   MSBS_SGLEBLK | ACEN_DISABLE | BCE_DISABLE | DE_DISABLE);
+   MSBS_SGLEBLK);
+   flags &= ~(ACEN_ENABLE | BCE_ENABLE | DE_ENABLE);
 
if (cmd->resp_type & MMC_RSP_CRC)
flags |= CCCE_CHECK;
@@ -809,7 +810,7 @@ static int omap_hsmmc_set_ios(struct udevice *dev)
}
 
mmc_reg_out(_base->sysctl, (ICE_MASK | DTO_MASK | CEN_MASK),
-   (ICE_STOP | DTO_15THDTO | CEN_DISABLE));
+   (ICE_STOP | DTO_15THDTO));
 
mmc_reg_out(_base->sysctl, ICE_MASK | CLKD_MASK,
(dsor << CLKD_OFFSET) | ICE_OSCILLATE);
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 1/5] Revert "omap_hsmmc: update struct hsmmc to accommodate omap3 from DT"

2017-09-21 Thread Jean-Jacques Hiblot
This reverts commit 46831c1a4cda75d92f7ad18d4e2b1eb196c62b2f.
This reserved area at the beginning of struct hsmm, will be used later to
support ADMA

Signed-off-by: Jean-Jacques Hiblot 
---
 arch/arm/include/asm/omap_mmc.h |  3 +++
 drivers/mmc/omap_hsmmc.c| 35 ---
 2 files changed, 7 insertions(+), 31 deletions(-)

diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h
index fd33408..297e6a7 100644
--- a/arch/arm/include/asm/omap_mmc.h
+++ b/arch/arm/include/asm/omap_mmc.h
@@ -28,6 +28,9 @@
 #include 
 
 struct hsmmc {
+#ifdef CONFIG_DM_MMC
+   unsigned char res0[0x100];
+#endif
unsigned char res1[0x10];
unsigned int sysconfig; /* 0x10 */
unsigned int sysstatus; /* 0x14 */
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index efa4389..9f38687 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -56,10 +56,6 @@ DECLARE_GLOBAL_DATA_PTR;
 #define SYSCTL_SRC (1 << 25)
 #define SYSCTL_SRD (1 << 26)
 
-struct omap2_mmc_platform_config {
-   u32 reg_offset;
-};
-
 struct omap_hsmmc_data {
struct hsmmc *base_addr;
 #if !CONFIG_IS_ENABLED(DM_MMC)
@@ -802,15 +798,13 @@ static int omap_hsmmc_ofdata_to_platdata(struct udevice 
*dev)
 {
struct omap_hsmmc_plat *plat = dev_get_platdata(dev);
struct mmc_config *cfg = >cfg;
-   struct omap2_mmc_platform_config *data =
-   (struct omap2_mmc_platform_config *)dev_get_driver_data(dev);
const void *fdt = gd->fdt_blob;
int node = dev_of_offset(dev);
int val;
 
plat->base_addr = map_physmem(devfdt_get_addr(dev),
  sizeof(struct hsmmc *),
- MAP_NOCACHE) + data->reg_offset;
+ MAP_NOCACHE);
 
cfg->host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS;
val = fdtdec_get_int(fdt, node, "bus-width", -1);
@@ -886,31 +880,10 @@ static int omap_hsmmc_probe(struct udevice *dev)
 }
 
 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
-static const struct omap2_mmc_platform_config omap3_mmc_pdata = {
-   .reg_offset = 0,
-};
-
-static const struct omap2_mmc_platform_config am33xx_mmc_pdata = {
-   .reg_offset = 0x100,
-};
-
-static const struct omap2_mmc_platform_config omap4_mmc_pdata = {
-   .reg_offset = 0x100,
-};
-
 static const struct udevice_id omap_hsmmc_ids[] = {
-   {
-   .compatible = "ti,omap3-hsmmc",
-   .data = (ulong)_mmc_pdata
-   },
-   {
-   .compatible = "ti,omap4-hsmmc",
-   .data = (ulong)_mmc_pdata
-   },
-   {
-   .compatible = "ti,am33xx-hsmmc",
-   .data = (ulong)_mmc_pdata
-   },
+   { .compatible = "ti,omap3-hsmmc" },
+   { .compatible = "ti,omap4-hsmmc" },
+   { .compatible = "ti,am33xx-hsmmc" },
{ }
 };
 #endif
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 2/5] omap: Update the base address of the MMC controllers

2017-09-21 Thread Jean-Jacques Hiblot
Align the base address defined in header files with the base address used
in the DTS. This will facilitate the introduction of the DMA support.

Of all HSMMC users, only omap3 doesn't have the 0x100 reserved region at
the top. This region will be used to determine if the controller supports
DMA transfers

Signed-off-by: Jean-Jacques Hiblot 
---
 arch/arm/include/asm/arch-am33xx/mmc_host_def.h| 4 ++--
 arch/arm/include/asm/arch-omap4/mmc_host_def.h | 6 +++---
 arch/arm/include/asm/arch-omap5/mmc_host_def.h | 6 +++---
 arch/arm/include/asm/omap_mmc.h| 2 +-
 arch/arm/mach-keystone/include/mach/mmc_host_def.h | 4 ++--
 5 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/arch/arm/include/asm/arch-am33xx/mmc_host_def.h 
b/arch/arm/include/asm/arch-am33xx/mmc_host_def.h
index 724e252..5a2ea8f 100644
--- a/arch/arm/include/asm/arch-am33xx/mmc_host_def.h
+++ b/arch/arm/include/asm/arch-am33xx/mmc_host_def.h
@@ -21,8 +21,8 @@
 /*
  * OMAP HSMMC register definitions
  */
-#define OMAP_HSMMC1_BASE   0x48060100
-#define OMAP_HSMMC2_BASE   0x481D8100
+#define OMAP_HSMMC1_BASE   0x4806
+#define OMAP_HSMMC2_BASE   0x481D8000
 
 #if defined(CONFIG_TI814X)
 #undef MMC_CLOCK_REFERENCE
diff --git a/arch/arm/include/asm/arch-omap4/mmc_host_def.h 
b/arch/arm/include/asm/arch-omap4/mmc_host_def.h
index 9c8ccb6..d067799 100644
--- a/arch/arm/include/asm/arch-omap4/mmc_host_def.h
+++ b/arch/arm/include/asm/arch-omap4/mmc_host_def.h
@@ -31,8 +31,8 @@
  * OMAP HSMMC register definitions
  */
 
-#define OMAP_HSMMC1_BASE   0x4809C100
-#define OMAP_HSMMC2_BASE   0x480B4100
-#define OMAP_HSMMC3_BASE   0x480AD100
+#define OMAP_HSMMC1_BASE   0x4809C000
+#define OMAP_HSMMC2_BASE   0x480B4000
+#define OMAP_HSMMC3_BASE   0x480AD000
 
 #endif /* MMC_HOST_DEF_H */
diff --git a/arch/arm/include/asm/arch-omap5/mmc_host_def.h 
b/arch/arm/include/asm/arch-omap5/mmc_host_def.h
index 9c8ccb6..d067799 100644
--- a/arch/arm/include/asm/arch-omap5/mmc_host_def.h
+++ b/arch/arm/include/asm/arch-omap5/mmc_host_def.h
@@ -31,8 +31,8 @@
  * OMAP HSMMC register definitions
  */
 
-#define OMAP_HSMMC1_BASE   0x4809C100
-#define OMAP_HSMMC2_BASE   0x480B4100
-#define OMAP_HSMMC3_BASE   0x480AD100
+#define OMAP_HSMMC1_BASE   0x4809C000
+#define OMAP_HSMMC2_BASE   0x480B4000
+#define OMAP_HSMMC3_BASE   0x480AD000
 
 #endif /* MMC_HOST_DEF_H */
diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h
index 297e6a7..77278a3 100644
--- a/arch/arm/include/asm/omap_mmc.h
+++ b/arch/arm/include/asm/omap_mmc.h
@@ -28,7 +28,7 @@
 #include 
 
 struct hsmmc {
-#ifdef CONFIG_DM_MMC
+#ifndef CONFIG_OMAP34XX
unsigned char res0[0x100];
 #endif
unsigned char res1[0x10];
diff --git a/arch/arm/mach-keystone/include/mach/mmc_host_def.h 
b/arch/arm/mach-keystone/include/mach/mmc_host_def.h
index a5050ac..b8eed7d 100644
--- a/arch/arm/mach-keystone/include/mach/mmc_host_def.h
+++ b/arch/arm/mach-keystone/include/mach/mmc_host_def.h
@@ -16,7 +16,7 @@
  * OMAP HSMMC register definitions
  */
 
-#define OMAP_HSMMC1_BASE   0x23000100
-#define OMAP_HSMMC2_BASE   0x23100100
+#define OMAP_HSMMC1_BASE   0x2300
+#define OMAP_HSMMC2_BASE   0x2310
 
 #endif /* K2G_MMC_HOST_DEF_H */
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 4/5] mmc: omap_hsmmc: Enable Auto command (CMD12) enable

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

Instead of sending STOP TRANSMISSION command from MMC core, enable
the auto command feature so that the Host Controller issues CMD12
automatically when last block transfer is completed.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
---
 drivers/mmc/omap_hsmmc.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 3cac6ea..fcda0e2 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -492,6 +492,10 @@ static int omap_hsmmc_send_cmd(struct udevice *dev, struct 
mmc_cmd *cmd,
ulong start;
 
mmc_base = priv->base_addr;
+
+   if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
+   return 0;
+
start = get_timer(0);
while ((readl(_base->pstate) & (DATI_MASK | CMDI_MASK)) != 0) {
if (get_timer(0) - start > MAX_RETRY_MS) {
@@ -548,7 +552,7 @@ static int omap_hsmmc_send_cmd(struct udevice *dev, struct 
mmc_cmd *cmd,
if (data) {
if ((cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK) ||
 (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK)) {
-   flags |= (MSBS_MULTIBLK | BCE_ENABLE);
+   flags |= (MSBS_MULTIBLK | BCE_ENABLE | ACEN_ENABLE);
data->blocksize = 512;
writel(data->blocksize | (data->blocks << 16),
_base->blk);
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 3/5] mmc: omap_hsmmc: Add support for DMA (ADMA2)

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

The omap hsmmc host controller can have the ADMA2 feature. It brings better
read and write throughput.
On most SOC, the capability is read from the hl_hwinfo register. On OMAP3,
DMA support is compiled out.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
---
 arch/arm/include/asm/omap_mmc.h |  12 ++-
 drivers/mmc/omap_hsmmc.c| 203 +++-
 2 files changed, 211 insertions(+), 4 deletions(-)

diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h
index 77278a3..128cd81 100644
--- a/arch/arm/include/asm/omap_mmc.h
+++ b/arch/arm/include/asm/omap_mmc.h
@@ -29,7 +29,10 @@
 
 struct hsmmc {
 #ifndef CONFIG_OMAP34XX
-   unsigned char res0[0x100];
+   unsigned int hl_rev;
+   unsigned int hl_hwinfo;
+   unsigned int hl_sysconfig;
+   unsigned char res0[0xf4];
 #endif
unsigned char res1[0x10];
unsigned int sysconfig; /* 0x10 */
@@ -52,6 +55,9 @@ struct hsmmc {
unsigned int ie;/* 0x134 */
unsigned char res4[0x8];
unsigned int capa;  /* 0x140 */
+   unsigned char res5[0x10];
+   unsigned int admaes;/* 0x154 */
+   unsigned int admasal;   /* 0x158 */
 };
 
 struct omap_hsmmc_plat {
@@ -64,6 +70,7 @@ struct omap_hsmmc_plat {
 /*
  * OMAP HS MMC Bit definitions
  */
+#define MADMA_EN   (0x1 << 0)
 #define MMC_SOFTRESET  (0x1 << 1)
 #define RESETDONE  (0x1 << 0)
 #define NOOPENDRAIN(0x0 << 0)
@@ -80,6 +87,7 @@ struct omap_hsmmc_plat {
 #define WPP_ACTIVEHIGH (0x0 << 8)
 #define RESERVED_MASK  (0x3 << 9)
 #define CTPL_MMC_SD(0x0 << 11)
+#define DMA_MASTER (0x1 << 20)
 #define BLEN_512BYTESLEN   (0x200 << 0)
 #define NBLK_STPCNT(0x0 << 16)
 #define DE_DISABLE (0x0 << 0)
@@ -119,6 +127,7 @@ struct omap_hsmmc_plat {
 #define SDBP_PWRON (0x1 << 8)
 #define SDVS_1V8   (0x5 << 9)
 #define SDVS_3V0   (0x6 << 9)
+#define DMA_SELECT (0x2 << 3)
 #define ICE_MASK   (0x1 << 0)
 #define ICE_STOP   (0x0 << 0)
 #define ICS_MASK   (0x1 << 1)
@@ -148,6 +157,7 @@ struct omap_hsmmc_plat {
 #define IE_DTO (0x01 << 20)
 #define IE_DCRC(0x01 << 21)
 #define IE_DEB (0x01 << 22)
+#define IE_ADMAE   (0x01 << 25)
 #define IE_CERR(0x01 << 28)
 #define IE_BADA(0x01 << 29)
 
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 9f38687..3cac6ea 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -71,11 +72,45 @@ struct omap_hsmmc_data {
int wp_gpio;
 #endif
 #endif
+   u8 controller_flags;
+#ifndef CONFIG_OMAP34XX
+   struct omap_hsmmc_adma_desc *adma_desc_table;
+   uint desc_slot;
+#endif
+};
+
+#ifndef CONFIG_OMAP34XX
+struct omap_hsmmc_adma_desc {
+   u8 attr;
+   u8 reserved;
+   u16 len;
+   u32 addr;
 };
 
+#define ADMA_MAX_LEN   63488
+
+/* Decriptor table defines */
+#define ADMA_DESC_ATTR_VALID   BIT(0)
+#define ADMA_DESC_ATTR_END BIT(1)
+#define ADMA_DESC_ATTR_INT BIT(2)
+#define ADMA_DESC_ATTR_ACT1BIT(4)
+#define ADMA_DESC_ATTR_ACT2BIT(5)
+
+#define ADMA_DESC_TRANSFER_DATAADMA_DESC_ATTR_ACT2
+#define ADMA_DESC_LINK_DESC(ADMA_DESC_ATTR_ACT1 | ADMA_DESC_ATTR_ACT2)
+#endif
+
 /* If we fail after 1 second wait, something is really bad */
 #define MAX_RETRY_MS   1000
 
+/* DMA transfers can take a long time if a lot a data is transfered.
+ * The timeout must take in account the amount of data. Let's assume
+ * that the time will never exceed 333 ms per MB (in other word we assume
+ * that the bandwidth is always above 3MB/s).
+ */
+#define DMA_TIMEOUT_PER_MB 333
+#define OMAP_HSMMC_USE_ADMABIT(2)
+
 static int mmc_read_data(struct hsmmc *mmc_base, char *buf, unsigned int size);
 static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
unsigned int siz);
@@ -242,6 +277,11 @@ static int omap_hsmmc_init_setup(struct mmc *mmc)
return -ETIMEDOUT;
}
}
+#ifndef CONFIG_OMAP34XX
+   reg_val = readl(_base->hl_hwinfo);
+   if (reg_val & MADMA_EN)
+   priv->controller_flags |= OMAP_HSMMC_USE_ADMA;
+#endif
writel(DTW_1_BITMODE | SDBP_PWROFF | SDVS_3V0, _base->hctl);

[U-Boot] [PATCH v2 0/5] mmc: omap_hsmmc: Add support for ADMA

2017-09-21 Thread Jean-Jacques Hiblot
This series enables the ADMA present in some OMAP SOCs. 
On a DRA7 the performances when reading from the eMMC go from 18MB/s
to 43MB/s.
Also while were at it, fix some incorrect bit operations

This series applies on top of the series that enables HS200 and UHS mode
"mmc: Add support for HS200 and UHS modes" but should be easy to use on top
of u-boot/master (just remove special handling of the tuning).

This is the first series of 3 which wille enable HS200 and UHS on the omap5
platforms (dra7 and am57).

Cheers,

Jean-Jacques

changes since v1:
 * added a timeout to terminate the DMA transfer if it takes too long
 * changed omap_hsmmc_adma_desc() and omap_hsmmc_prepare_adma_table(()
   to not return any value (void)
 * removed wrong comment about cache handling


Jean-Jacques Hiblot (2):
  Revert "omap_hsmmc: update struct hsmmc to accommodate omap3 from DT"
  omap: Update the base address of the MMC controllers

Kishon Vijay Abraham I (3):
  mmc: omap_hsmmc: Add support for DMA (ADMA2)
  mmc: omap_hsmmc: Enable Auto command (CMD12) enable
  mmc: omap_hsmmc: Fix incorrect bit operations for disabling a bit

 arch/arm/include/asm/arch-am33xx/mmc_host_def.h|   4 +-
 arch/arm/include/asm/arch-omap4/mmc_host_def.h |   6 +-
 arch/arm/include/asm/arch-omap5/mmc_host_def.h |   6 +-
 arch/arm/include/asm/omap_mmc.h|  19 +-
 arch/arm/mach-keystone/include/mach/mmc_host_def.h |   4 +-
 drivers/mmc/omap_hsmmc.c   | 251 +
 6 files changed, 238 insertions(+), 52 deletions(-)

-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH] Remove "no previous prototype" warning

2017-09-21 Thread Diego Dorta
When compiling with W=1 the following warning is observed:

board/freescale/mx6sabresd/mx6sabresd.c:266:5: warning: 
no previous prototype for ‘board_mmc_get_env_dev’
[-Wmissing-prototypes] int board_mmc_get_env_dev(int devno)

Remove this warning by adding the function prototype into mmc.h file.

Signed-off-by: Diego Dorta 
---
 include/mmc.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/mmc.h b/include/mmc.h
index 010ebe0..3ddfc2d 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -588,6 +588,7 @@ int board_mmc_init(bd_t *bis);
 int cpu_mmc_init(bd_t *bis);
 int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr);
 int mmc_get_env_dev(void);
+int board_mmc_get_env_dev(int devno);
 
 /* Set block count limit because of 16 bit register limit on some hardware*/
 #ifndef CONFIG_SYS_MMC_MAX_BLK_COUNT
-- 
2.7.4

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 15/26] mmc: add power cyle support in mmc core

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

mmc/sd specification requires vdd to be disabled for 1 ms
and then enabled again during power cycle. Add a
function in mmc core to perform power cycle and set
the io signal to it's initial state.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
---
 drivers/mmc/mmc.c | 88 ---
 1 file changed, 71 insertions(+), 17 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index fd93691..65a3d8e 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -31,6 +31,7 @@ static const unsigned int sd_au_size[] = {
 };
 
 static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage);
+static int mmc_power_cycle(struct mmc *mmc);
 
 #if CONFIG_IS_ENABLED(MMC_TINY)
 static struct mmc mmc_static;
@@ -1920,25 +1921,83 @@ static int mmc_power_init(struct mmc *mmc)
  >vqmmc_supply);
if (ret)
debug("%s: No vqmmc supply\n", mmc->dev->name);
+#endif
+#else /* !CONFIG_DM_MMC */
+   /*
+* Driver model should use a regulator, as above, rather than calling
+* out to board code.
+*/
+   board_mmc_power_init();
+#endif
+   return 0;
+}
+
+/*
+ * put the host in the initial state:
+ * - turn on Vdd (card power supply)
+ * - configure the bus width and clock to minimal values
+ */
+static void mmc_set_initial_state(struct mmc *mmc)
+{
+   int err;
+
+   /* First try to set 3.3V. If it fails set to 1.8V */
+   err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_330);
+   if (err != 0)
+   err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_180);
+   if (err != 0)
+   printf("mmc: failed to set signal voltage\n");
+
+   mmc_select_mode(mmc, MMC_LEGACY);
+   mmc_set_bus_width(mmc, 1);
+   mmc_set_clock(mmc, 0);
+}
 
+static int mmc_power_on(struct mmc *mmc)
+{
+#if CONFIG_IS_ENABLED(DM_MMC) && CONFIG_IS_ENABLED(DM_REGULATOR)
if (mmc->vmmc_supply) {
-   ret = regulator_set_enable(mmc->vmmc_supply, true);
+   int ret = regulator_set_enable(mmc->vmmc_supply, true);
+
if (ret) {
puts("Error enabling VMMC supply\n");
return ret;
}
}
 #endif
-#else /* !CONFIG_DM_MMC */
-   /*
-* Driver model should use a regulator, as above, rather than calling
-* out to board code.
-*/
-   board_mmc_power_init();
+   return 0;
+}
+
+static int mmc_power_off(struct mmc *mmc)
+{
+#if CONFIG_IS_ENABLED(DM_MMC) && CONFIG_IS_ENABLED(DM_REGULATOR)
+   if (mmc->vmmc_supply) {
+   int ret = regulator_set_enable(mmc->vmmc_supply, false);
+
+   if (ret) {
+   puts("Error disabling VMMC supply\n");
+   return ret;
+   }
+   }
 #endif
return 0;
 }
 
+static int mmc_power_cycle(struct mmc *mmc)
+{
+   int ret;
+
+   ret = mmc_power_off(mmc);
+   if (ret)
+   return ret;
+   /*
+* SD spec recommends at least 1ms of delay. Let's wait for 2ms
+* to be on the safer side.
+*/
+   udelay(2000);
+   return mmc_power_on(mmc);
+}
+
 int mmc_start_init(struct mmc *mmc)
 {
bool no_card;
@@ -1967,6 +2026,10 @@ int mmc_start_init(struct mmc *mmc)
if (err)
return err;
 
+   err = mmc_power_on(mmc);
+   if (err)
+   return err;
+
 #if CONFIG_IS_ENABLED(DM_MMC)
/* The device has already been probed ready for use */
 #else
@@ -1977,16 +2040,7 @@ int mmc_start_init(struct mmc *mmc)
 #endif
mmc->ddr_mode = 0;
 
-   /* First try to set 3.3V. If it fails set to 1.8V */
-   err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_330);
-   if (err != 0)
-   err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_180);
-   if (err != 0)
-   printf("failed to set signal voltage\n");
-
-   mmc_set_bus_width(mmc, 1);
-   mmc_set_clock(mmc, 1);
-
+   mmc_set_initial_state(mmc);
mmc_send_init_stream(mmc);
 
/* Reset the Card */
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 20/26] mmc: Add support for UHS modes

2017-09-21 Thread Jean-Jacques Hiblot
Add UHS modes to the list of supported modes, get the UHS capabilites of
the SDcard and implement the procedure to switch the voltage (UHS modes
use 1v8 IO lines)
During the voltage switch procedure, DAT0 is used by the card to signal
when it's ready. The optional card_busy() callback can be used to get this
information from the host driver.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
Reviewed-by: Simon Glass 
---
 drivers/mmc/mmc-uclass.c |  14 
 drivers/mmc/mmc.c| 176 ---
 include/mmc.h|  40 ++-
 3 files changed, 221 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c
index 60cc0ac..7856e0a 100644
--- a/drivers/mmc/mmc-uclass.c
+++ b/drivers/mmc/mmc-uclass.c
@@ -64,6 +64,20 @@ void mmc_send_init_stream(struct mmc *mmc)
dm_mmc_send_init_stream(mmc->dev);
 }
 
+int dm_mmc_wait_dat0(struct udevice *dev, int state, int timeout)
+{
+   struct dm_mmc_ops *ops = mmc_get_ops(dev);
+
+   if (!ops->wait_dat0)
+   return -ENOSYS;
+   return ops->wait_dat0(dev, state, timeout);
+}
+
+int mmc_wait_dat0(struct mmc *mmc, int state, int timeout)
+{
+   return dm_mmc_wait_dat0(mmc->dev, state, timeout);
+}
+
 int dm_mmc_get_wp(struct udevice *dev)
 {
struct dm_mmc_ops *ops = mmc_get_ops(dev);
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index c663709..ca59e28 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -57,6 +57,12 @@ struct blk_desc *mmc_get_blk_desc(struct mmc *mmc)
 #endif
 
 #if !CONFIG_IS_ENABLED(DM_MMC)
+
+static int mmc_wait_dat0(struct mmc *mmc, int state, int timeout)
+{
+   return -ENOSYS;
+}
+
 __weak int board_mmc_getwp(struct mmc *mmc)
 {
return -1;
@@ -402,7 +408,67 @@ static int mmc_go_idle(struct mmc *mmc)
return 0;
 }
 
-static int sd_send_op_cond(struct mmc *mmc)
+static int mmc_switch_voltage(struct mmc *mmc, int signal_voltage)
+{
+   struct mmc_cmd cmd;
+   int err = 0;
+
+   /*
+* Send CMD11 only if the request is to switch the card to
+* 1.8V signalling.
+*/
+   if (signal_voltage == MMC_SIGNAL_VOLTAGE_330)
+   return mmc_set_signal_voltage(mmc, signal_voltage);
+
+   cmd.cmdidx = SD_CMD_SWITCH_UHS18V;
+   cmd.cmdarg = 0;
+   cmd.resp_type = MMC_RSP_R1;
+
+   err = mmc_send_cmd(mmc, , NULL);
+   if (err)
+   return err;
+
+   if (!mmc_host_is_spi(host) && (cmd.response[0] & MMC_STATUS_ERROR))
+   return -EIO;
+
+   /*
+* The card should drive cmd and dat[0:3] low immediately
+* after the response of cmd11, but wait 100 us to be sure
+*/
+   err = mmc_wait_dat0(mmc, 0, 100);
+   if (err == -ENOSYS)
+   udelay(100);
+   else if (err)
+   return -ETIMEDOUT;
+
+   /*
+* During a signal voltage level switch, the clock must be gated
+* for 5 ms according to the SD spec
+*/
+   mmc_set_clock(mmc, mmc->clock, true);
+
+   err = mmc_set_signal_voltage(mmc, signal_voltage);
+   if (err)
+   return err;
+
+   /* Keep clock gated for at least 10 ms, though spec only says 5 ms */
+   mdelay(10);
+   mmc_set_clock(mmc, mmc->clock, false);
+
+   /*
+* Failure to switch is indicated by the card holding
+* dat[0:3] low. Wait for at least 1 ms according to spec
+*/
+   err = mmc_wait_dat0(mmc, 1, 1000);
+   if (err == -ENOSYS)
+   udelay(1000);
+   else if (err)
+   return -ETIMEDOUT;
+
+   return 0;
+}
+
+static int sd_send_op_cond(struct mmc *mmc, bool uhs_en)
 {
int timeout = 1000;
int err;
@@ -434,6 +500,9 @@ static int sd_send_op_cond(struct mmc *mmc)
if (mmc->version == SD_VERSION_2)
cmd.cmdarg |= OCR_HCS;
 
+   if (uhs_en)
+   cmd.cmdarg |= OCR_S18R;
+
err = mmc_send_cmd(mmc, , NULL);
 
if (err)
@@ -464,6 +533,13 @@ static int sd_send_op_cond(struct mmc *mmc)
 
mmc->ocr = cmd.response[0];
 
+   if (uhs_en && !(mmc_host_is_spi(mmc)) && (cmd.response[0] & 0x4100)
+   == 0x4100) {
+   err = mmc_switch_voltage(mmc, MMC_SIGNAL_VOLTAGE_180);
+   if (err)
+   return err;
+   }
+
mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
mmc->rca = 0;
 
@@ -977,6 +1053,7 @@ static int sd_get_capabilities(struct mmc *mmc)
ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
struct mmc_data data;
int timeout;
+   u32 sd3_bus_mode;
 
mmc->card_caps = MMC_MODE_1BIT;
 
@@ -1058,6 +1135,22 @@ retry_scr:
if (__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED)
mmc->card_caps |= 

[U-Boot] [PATCH v2 13/26] mmc: Enable signal voltage to be selected from mmc core

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

Add a new function *mmc_set_signal_voltage* in mmc core
which can be used during mmc initialization to select the
signal voltage. Platform driver should use the set_ios
callback function to select the signal voltage.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
---
 drivers/mmc/mmc.c | 16 
 include/mmc.h |  8 
 2 files changed, 24 insertions(+)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 536cd7f..46ec5e1 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -30,6 +30,8 @@ static const unsigned int sd_au_size[] = {
SZ_16M / 512,   (SZ_16M + SZ_8M) / 512, SZ_32M / 512,   SZ_64M / 512,
 };
 
+static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage);
+
 #if CONFIG_IS_ENABLED(MMC_TINY)
 static struct mmc mmc_static;
 struct mmc *find_mmc_device(int dev_num)
@@ -1257,6 +1259,12 @@ struct mode_width_tuning {
uint widths;
 };
 
+static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage)
+{
+   mmc->signal_voltage = signal_voltage;
+   return mmc_set_ios(mmc);
+}
+
 static const struct mode_width_tuning sd_modes_by_pref[] = {
{
.mode = SD_HS,
@@ -1964,6 +1972,14 @@ int mmc_start_init(struct mmc *mmc)
return err;
 #endif
mmc->ddr_mode = 0;
+
+   /* First try to set 3.3V. If it fails set to 1.8V */
+   err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_330);
+   if (err != 0)
+   err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_180);
+   if (err != 0)
+   printf("failed to set signal voltage\n");
+
mmc_set_bus_width(mmc, 1);
mmc_set_clock(mmc, 1);
 
diff --git a/include/mmc.h b/include/mmc.h
index 3e57887..e524963 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -272,6 +272,13 @@
 #define ENHNCD_SUPPORT (0x2)
 #define PART_ENH_ATTRIB(0x1f)
 
+enum mmc_voltage {
+   MMC_SIGNAL_VOLTAGE_000 = 0,
+   MMC_SIGNAL_VOLTAGE_120,
+   MMC_SIGNAL_VOLTAGE_180,
+   MMC_SIGNAL_VOLTAGE_330
+};
+
 /* Maximum block size for MMC */
 #define MMC_MAX_BLOCK_LEN  512
 
@@ -457,6 +464,7 @@ struct mmc {
int high_capacity;
uint bus_width;
uint clock;
+   enum mmc_voltage signal_voltage;
uint card_caps;
uint ocr;
uint dsr;
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 19/26] mmc: add HS200 support in MMC core

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

Add HS200 to the list of supported modes and introduce tuning in the MMC
startup process.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
Reviewed-by: Simon Glass 
---
 drivers/mmc/mmc.c | 22 --
 include/mmc.h | 18 ++
 2 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 3e2e549..c663709 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -621,6 +621,10 @@ static int mmc_set_card_speed(struct mmc *mmc, enum 
bus_mode mode)
case MMC_HS_52:
case MMC_DDR_52:
speed_bits = EXT_CSD_TIMING_HS;
+   break;
+   case MMC_HS_200:
+   speed_bits = EXT_CSD_TIMING_HS200;
+   break;
case MMC_LEGACY:
speed_bits = EXT_CSD_TIMING_LEGACY;
break;
@@ -667,9 +671,12 @@ static int mmc_get_capabilities(struct mmc *mmc)
 
mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
 
-   cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
+   cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0x3f;
 
-   /* High Speed is set, there are two types: 52MHz and 26MHz */
+   if (cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V |
+   EXT_CSD_CARD_TYPE_HS200_1_8V)) {
+   mmc->card_caps |= MMC_MODE_HS200;
+   }
if (cardtype & EXT_CSD_CARD_TYPE_52) {
if (cardtype & EXT_CSD_CARD_TYPE_DDR_52)
mmc->card_caps |= MMC_MODE_DDR_52MHz;
@@ -1268,6 +1275,7 @@ void mmc_dump_capabilities(const char *text, uint caps)
 struct mode_width_tuning {
enum bus_mode mode;
uint widths;
+   uint tuning;
 };
 
 static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage)
@@ -1383,6 +1391,7 @@ static const struct mode_width_tuning mmc_modes_by_pref[] 
= {
{
.mode = MMC_HS_200,
.widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
+   .tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200
},
{
.mode = MMC_DDR_52,
@@ -1484,6 +1493,15 @@ static int mmc_select_mode_and_width(struct mmc *mmc)
mmc_select_mode(mmc, mwt->mode);
mmc_set_clock(mmc, mmc->tran_speed, false);
 
+   /* execute tuning if needed */
+   if (mwt->tuning) {
+   err = mmc_execute_tuning(mmc, mwt->tuning);
+   if (err) {
+   debug("tuning failed\n");
+   goto error;
+   }
+   }
+
/* do a transfer to check the configuration */
err = mmc_read_and_compare_ext_csd(mmc);
if (!err)
diff --git a/include/mmc.h b/include/mmc.h
index 56fa869..407fddf 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -56,6 +56,7 @@
 #define MMC_MODE_HS(MMC_CAP(MMC_HS) | MMC_CAP(SD_HS))
 #define MMC_MODE_HS_52MHz  MMC_CAP(MMC_HS_52)
 #define MMC_MODE_DDR_52MHz MMC_CAP(MMC_DDR_52)
+#define MMC_MODE_HS200 MMC_CAP(MMC_HS_200)
 
 #define MMC_MODE_8BIT  BIT(30)
 #define MMC_MODE_4BIT  BIT(29)
@@ -86,6 +87,7 @@
 #define MMC_CMD_SET_BLOCKLEN   16
 #define MMC_CMD_READ_SINGLE_BLOCK  17
 #define MMC_CMD_READ_MULTIPLE_BLOCK18
+#define MMC_CMD_SEND_TUNING_BLOCK_HS20021
 #define MMC_CMD_SET_BLOCK_COUNT 23
 #define MMC_CMD_WRITE_SINGLE_BLOCK 24
 #define MMC_CMD_WRITE_MULTIPLE_BLOCK   25
@@ -113,6 +115,13 @@
 #define SD_CMD_APP_SEND_OP_COND41
 #define SD_CMD_APP_SEND_SCR51
 
+static inline bool mmc_is_tuning_cmd(uint cmdidx)
+{
+   if (cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200)
+   return true;
+   return false;
+}
+
 /* SCR definitions in different words */
 #define SD_HIGHSPEED_BUSY  0x0002
 #define SD_HIGHSPEED_SUPPORTED 0x0002
@@ -210,6 +219,13 @@
 #define EXT_CSD_CARD_TYPE_DDR_52   (EXT_CSD_CARD_TYPE_DDR_1_8V \
| EXT_CSD_CARD_TYPE_DDR_1_2V)
 
+#define EXT_CSD_CARD_TYPE_HS200_1_8V   BIT(4)  /* Card can run at 200MHz */
+   /* SDR mode @1.8V I/O */
+#define EXT_CSD_CARD_TYPE_HS200_1_2V   BIT(5)  /* Card can run at 200MHz */
+   /* SDR mode @1.2V I/O */
+#define EXT_CSD_CARD_TYPE_HS200(EXT_CSD_CARD_TYPE_HS200_1_8V | 
\
+EXT_CSD_CARD_TYPE_HS200_1_2V)
+
 #define EXT_CSD_BUS_WIDTH_10   /* Card is in 1 bit mode */
 #define EXT_CSD_BUS_WIDTH_41   /* Card is in 4 bit mode */
 #define EXT_CSD_BUS_WIDTH_82   /* Card is in 8 bit mode */
@@ -219,6 +235,8 @@
 
 #define EXT_CSD_TIMING_LEGACY  

[U-Boot] [PATCH v2 01/26] mmc: dm: get the IO-line and main voltage regulators from the dts

2017-09-21 Thread Jean-Jacques Hiblot
Get a reference to the regulator devices from the dts and store them
in the struct mmc for later use.

Signed-off-by: Jean-Jacques Hiblot 
---
 drivers/mmc/mmc.c | 24 ++--
 include/mmc.h |  4 
 2 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 38d2e07..11285be 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1618,21 +1618,25 @@ __weak void board_mmc_power_init(void)
 static int mmc_power_init(struct mmc *mmc)
 {
 #if CONFIG_IS_ENABLED(DM_MMC)
-#if defined(CONFIG_DM_REGULATOR) && !defined(CONFIG_SPL_BUILD)
-   struct udevice *vmmc_supply;
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
int ret;
 
ret = device_get_supply_regulator(mmc->dev, "vmmc-supply",
- _supply);
-   if (ret) {
+ >vmmc_supply);
+   if (ret)
debug("%s: No vmmc supply\n", mmc->dev->name);
-   return 0;
-   }
 
-   ret = regulator_set_enable(vmmc_supply, true);
-   if (ret) {
-   puts("Error enabling VMMC supply\n");
-   return ret;
+   ret = device_get_supply_regulator(mmc->dev, "vqmmc-supply",
+ >vqmmc_supply);
+   if (ret)
+   debug("%s: No vqmmc supply\n", mmc->dev->name);
+
+   if (mmc->vmmc_supply) {
+   ret = regulator_set_enable(mmc->vmmc_supply, true);
+   if (ret) {
+   puts("Error enabling VMMC supply\n");
+   return ret;
+   }
}
 #endif
 #else /* !CONFIG_DM_MMC */
diff --git a/include/mmc.h b/include/mmc.h
index 010ebe0..188dc74 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -457,6 +457,10 @@ struct mmc {
int ddr_mode;
 #if CONFIG_IS_ENABLED(DM_MMC)
struct udevice *dev;/* Device for this MMC controller */
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
+   struct udevice *vmmc_supply;/* Main voltage regulator (Vcc)*/
+   struct udevice *vqmmc_supply;   /* IO voltage regulator (Vccq)*/
+#endif
 #endif
 };
 
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 04/26] mmc: make ext_csd part of struct mmc

2017-09-21 Thread Jean-Jacques Hiblot
The ext csd is used for comparison many times. Keep a reference content
of the ext csd in the struct mmc to avoid reading multiple times

Signed-off-by: Jean-Jacques Hiblot 
Reviewed-by: Simon Glass 
---
 drivers/mmc/mmc.c | 22 +-
 include/mmc.h |  1 +
 2 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 7c100a4..cfdfd8d 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1146,9 +1146,10 @@ static int sd_select_bus_freq_width(struct mmc *mmc)
return 0;
 }
 
-static int mmc_select_bus_freq_width(struct mmc *mmc, const u8 *ext_csd)
+static int mmc_select_bus_freq_width(struct mmc *mmc)
 {
ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
+   const u8 *ext_csd = mmc->ext_csd;
/* An array of possible bus widths in order of preference */
static const unsigned int ext_csd_bits[] = {
EXT_CSD_DDR_BUS_WIDTH_8,
@@ -1184,6 +1185,11 @@ static int mmc_select_bus_freq_width(struct mmc *mmc, 
const u8 *ext_csd)
if (mmc->version < MMC_VERSION_4)
return 0;
 
+   if (!mmc->ext_csd) {
+   debug("No ext_csd found!\n"); /* this should enver happen */
+   return -ENOTSUPP;
+   }
+
for (idx = 0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
unsigned int extw = ext_csd_bits[idx];
unsigned int caps = ext_to_hostcaps[extw];
@@ -1249,16 +1255,23 @@ static int mmc_select_bus_freq_width(struct mmc *mmc, 
const u8 *ext_csd)
return err;
 }
 
-static int mmc_startup_v4(struct mmc *mmc, u8 *ext_csd)
+static int mmc_startup_v4(struct mmc *mmc)
 {
int err, i;
u64 capacity;
bool has_parts = false;
bool part_completed;
+   u8 *ext_csd;
 
if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4))
return 0;
 
+   ext_csd = malloc_cache_aligned(MMC_MAX_BLOCK_LEN);
+   if (!ext_csd)
+   return -ENOMEM;
+
+   mmc->ext_csd = ext_csd;
+
/* check  ext_csd version and capacity */
err = mmc_send_ext_csd(mmc, ext_csd);
if (err)
@@ -1418,7 +1431,6 @@ static int mmc_startup(struct mmc *mmc)
uint mult, freq;
u64 cmult, csize;
struct mmc_cmd cmd;
-   ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
struct blk_desc *bdesc;
 
 #ifdef CONFIG_MMC_SPI_CRC_ON
@@ -1567,7 +1579,7 @@ static int mmc_startup(struct mmc *mmc)
mmc->erase_grp_size = 1;
mmc->part_config = MMCPART_NOAVAILABLE;
 
-   err = mmc_startup_v4(mmc, ext_csd);
+   err = mmc_startup_v4(mmc);
if (err)
return err;
 
@@ -1578,7 +1590,7 @@ static int mmc_startup(struct mmc *mmc)
if (IS_SD(mmc))
err = sd_select_bus_freq_width(mmc);
else
-   err = mmc_select_bus_freq_width(mmc, ext_csd);
+   err = mmc_select_bus_freq_width(mmc);
 
if (err)
return err;
diff --git a/include/mmc.h b/include/mmc.h
index 188dc74..7d2b363 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -462,6 +462,7 @@ struct mmc {
struct udevice *vqmmc_supply;   /* IO voltage regulator (Vccq)*/
 #endif
 #endif
+   u8 *ext_csd;
 };
 
 struct mmc_hwpart_conf {
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 17/26] mmc: disable the mmc clock during power off

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

There is no point in having the mmc clock enabled during
power off. Disable the mmc clock. This is similar to how it's
programmed in Linux Kernel.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Vignesh R 
Signed-off-by: Jean-Jacques Hiblot 
Reviewed-by: Simon Glass 
---
 drivers/mmc/mmc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 1c941a2..1f9730e 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1971,6 +1971,7 @@ static int mmc_power_on(struct mmc *mmc)
 
 static int mmc_power_off(struct mmc *mmc)
 {
+   mmc_set_clock(mmc, 1, true);
 #if CONFIG_IS_ENABLED(DM_MMC) && CONFIG_IS_ENABLED(DM_REGULATOR)
if (mmc->vmmc_supply) {
int ret = regulator_set_enable(mmc->vmmc_supply, false);
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 11/26] mmc: refactor MMC startup to make it easier to support new modes

2017-09-21 Thread Jean-Jacques Hiblot
The MMC startup process currently handles 4 modes. To make it easier to
add support for more modes, let's make the process more generic and use a
list of the modes to try.
The major functional change is that when a mode fails we try the next one.
Not all modes are tried, only those supported by the card and the host.

Signed-off-by: Jean-Jacques Hiblot 
Reviewed-by: Simon Glass 
---
 drivers/mmc/mmc.c | 241 +-
 include/mmc.h |  11 +++
 2 files changed, 158 insertions(+), 94 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index b8e726a..7361447 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -202,6 +202,7 @@ static int mmc_select_mode(struct mmc *mmc, enum bus_mode 
mode)
 {
mmc->selected_mode = mode;
mmc->tran_speed = mmc_mode2freq(mmc, mode);
+   mmc->ddr_mode = mmc_is_mode_ddr(mode);
debug("selecting mode %s (freq : %d MHz)\n", mmc_mode_name(mode),
  mmc->tran_speed / 100);
return 0;
@@ -605,11 +606,47 @@ int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 
value)
 
 }
 
-static int mmc_change_freq(struct mmc *mmc)
+static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode)
 {
-   ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
-   char cardtype;
int err;
+   int speed_bits;
+
+   ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
+
+   switch (mode) {
+   case MMC_HS:
+   case MMC_HS_52:
+   case MMC_DDR_52:
+   speed_bits = EXT_CSD_TIMING_HS;
+   case MMC_LEGACY:
+   speed_bits = EXT_CSD_TIMING_LEGACY;
+   break;
+   default:
+   return -EINVAL;
+   }
+   err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING,
+speed_bits);
+   if (err)
+   return err;
+
+   if ((mode == MMC_HS) || (mode == MMC_HS_52)) {
+   /* Now check to see that it worked */
+   err = mmc_send_ext_csd(mmc, test_csd);
+   if (err)
+   return err;
+
+   /* No high-speed support */
+   if (!test_csd[EXT_CSD_HS_TIMING])
+   return -ENOTSUPP;
+   }
+
+   return 0;
+}
+
+static int mmc_get_capabilities(struct mmc *mmc)
+{
+   u8 *ext_csd = mmc->ext_csd;
+   char cardtype;
 
mmc->card_caps = MMC_MODE_1BIT;
 
@@ -620,38 +657,23 @@ static int mmc_change_freq(struct mmc *mmc)
if (mmc->version < MMC_VERSION_4)
return 0;
 
-   mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
-
-   err = mmc_send_ext_csd(mmc, ext_csd);
+   if (!ext_csd) {
+   error("No ext_csd found!\n"); /* this should enver happen */
+   return -ENOTSUPP;
+   }
 
-   if (err)
-   return err;
+   mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
 
cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
 
-   err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
-
-   if (err)
-   return err;
-
-   /* Now check to see that it worked */
-   err = mmc_send_ext_csd(mmc, ext_csd);
-
-   if (err)
-   return err;
-
-   /* No high-speed support */
-   if (!ext_csd[EXT_CSD_HS_TIMING])
-   return 0;
-
/* High Speed is set, there are two types: 52MHz and 26MHz */
if (cardtype & EXT_CSD_CARD_TYPE_52) {
-   if (cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V)
+   if (cardtype & EXT_CSD_CARD_TYPE_DDR_52)
mmc->card_caps |= MMC_MODE_DDR_52MHz;
-   mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
-   } else {
-   mmc->card_caps |= MMC_MODE_HS;
+   mmc->card_caps |= MMC_MODE_HS_52MHz;
}
+   if (cardtype & EXT_CSD_CARD_TYPE_26)
+   mmc->card_caps |= MMC_MODE_HS;
 
return 0;
 }
@@ -1334,33 +1356,60 @@ static int mmc_read_and_compare_ext_csd(struct mmc *mmc)
return -EBADMSG;
 }
 
-static int mmc_select_bus_freq_width(struct mmc *mmc)
+static const struct mode_width_tuning mmc_modes_by_pref[] = {
+   {
+   .mode = MMC_HS_200,
+   .widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
+   },
+   {
+   .mode = MMC_DDR_52,
+   .widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
+   },
+   {
+   .mode = MMC_HS_52,
+   .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
+   },
+   {
+   .mode = MMC_HS,
+   .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
+   },
+   {
+   .mode = MMC_LEGACY,
+   .widths = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_1BIT,
+   }
+};
+
+#define for_each_mmc_mode_by_pref(caps, mwt) \
+   for (mwt = mmc_modes_by_pref;\
+   mwt < mmc_modes_by_pref + 

[U-Boot] [PATCH v2 24/26] mmc: use the right voltage level for MMC DDR and HS200 modes

2017-09-21 Thread Jean-Jacques Hiblot
HS200 only supports 1.2v and 1.8v signal voltages. DDR52 supports 3.3v/1.8v
or 1.2v signal voltages.
Select the lowest voltage available when using those modes.

Signed-off-by: Jean-Jacques Hiblot 
---
 drivers/mmc/mmc.c | 68 ++-
 include/mmc.h | 20 +---
 2 files changed, 84 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 6d1bf94..2d447dd 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -767,6 +767,7 @@ static int mmc_get_capabilities(struct mmc *mmc)
mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
 
cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0x3f;
+   mmc->cardtype = cardtype;
 
if (cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V |
EXT_CSD_CARD_TYPE_HS200_1_8V)) {
@@ -1441,10 +1442,30 @@ struct mode_width_tuning {
uint tuning;
 };
 
+int mmc_voltage_to_mv(enum mmc_voltage voltage)
+{
+   switch (voltage) {
+   case MMC_SIGNAL_VOLTAGE_000: return 0;
+   case MMC_SIGNAL_VOLTAGE_330: return 3300;
+   case MMC_SIGNAL_VOLTAGE_180: return 1800;
+   case MMC_SIGNAL_VOLTAGE_120: return 1200;
+   }
+   return -EINVAL;
+}
+
 static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage)
 {
+   int err;
+
+   if (mmc->signal_voltage == signal_voltage)
+   return 0;
+
mmc->signal_voltage = signal_voltage;
-   return mmc_set_ios(mmc);
+   err = mmc_set_ios(mmc);
+   if (err)
+   debug("unable to set voltage (err %d)\n", err);
+
+   return err;
 }
 
 static const struct mode_width_tuning sd_modes_by_pref[] = {
@@ -1584,6 +1605,43 @@ static int mmc_read_and_compare_ext_csd(struct mmc *mmc)
return -EBADMSG;
 }
 
+static int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode,
+ uint32_t allowed_mask)
+{
+   u32 card_mask = 0;
+
+   switch (mode) {
+   case MMC_HS_200:
+   if (mmc->cardtype & EXT_CSD_CARD_TYPE_HS200_1_8V)
+   card_mask |= MMC_SIGNAL_VOLTAGE_180;
+   if (mmc->cardtype & EXT_CSD_CARD_TYPE_HS200_1_2V)
+   card_mask |= MMC_SIGNAL_VOLTAGE_120;
+   break;
+   case MMC_DDR_52:
+   if (mmc->cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V)
+   card_mask |= MMC_SIGNAL_VOLTAGE_330 |
+MMC_SIGNAL_VOLTAGE_180;
+   if (mmc->cardtype & EXT_CSD_CARD_TYPE_DDR_1_2V)
+   card_mask |= MMC_SIGNAL_VOLTAGE_120;
+   break;
+   default:
+   card_mask |= MMC_SIGNAL_VOLTAGE_330;
+   break;
+   }
+
+   while (card_mask & allowed_mask) {
+   enum mmc_voltage best_match;
+
+   best_match = 1 << (ffs(card_mask & allowed_mask) - 1);
+   if (!mmc_set_signal_voltage(mmc,  best_match))
+   return 0;
+
+   allowed_mask &= ~best_match;
+   }
+
+   return -ENOTSUPP;
+}
+
 static const struct mode_width_tuning mmc_modes_by_pref[] = {
{
.mode = MMC_HS_200,
@@ -1655,10 +1713,17 @@ static int mmc_select_mode_and_width(struct mmc *mmc, 
uint card_caps)
for_each_mmc_mode_by_pref(card_caps, mwt) {
for_each_supported_width(card_caps & mwt->widths,
 mmc_is_mode_ddr(mwt->mode), ecbw) {
+   enum mmc_voltage old_voltage;
debug("trying mode %s width %d (at %d MHz)\n",
  mmc_mode_name(mwt->mode),
  bus_width(ecbw->cap),
  mmc_mode2freq(mmc, mwt->mode) / 100);
+   old_voltage = mmc->signal_voltage;
+   err = mmc_set_lowest_voltage(mmc, mwt->mode,
+MMC_ALL_SIGNAL_VOLTAGE);
+   if (err)
+   continue;
+
/* configure the bus width (card + host) */
err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_BUS_WIDTH,
@@ -1702,6 +1767,7 @@ static int mmc_select_mode_and_width(struct mmc *mmc, 
uint card_caps)
if (!err)
return 0;
 error:
+   mmc_set_signal_voltage(mmc, old_voltage);
/* if an error occured, revert to a safer bus mode */
mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
   EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_1);
diff --git a/include/mmc.h b/include/mmc.h
index a9ebc88..c11f698 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -311,11 +311,15 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
 
 enum mmc_voltage {
MMC_SIGNAL_VOLTAGE_000 = 0,
- 

[U-Boot] [PATCH v2 16/26] mmc: add a new mmc parameter to disable mmc clock

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

mmc clock has to be disabled in certain cases like during
the voltage switch sequence. Modify mmc_set_clock function
to take disable as an argument that signifies if the
clock has to be enabled or disabled.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
---
 drivers/mmc/fsl_esdhc.c |  2 +-
 drivers/mmc/mmc.c   | 11 ++-
 include/mmc.h   | 12 +++-
 3 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index cc188c4..6b52c6a 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -665,7 +665,7 @@ static int esdhc_init_common(struct fsl_esdhc_priv *priv, 
struct mmc *mmc)
 #endif
 
/* Set the initial clock speed */
-   mmc_set_clock(mmc, 40);
+   mmc_set_clock(mmc, 40, false);
 
/* Disable the BRR and BWR bits in IRQSTAT */
esdhc_clrbits32(>irqstaten, IRQSTATEN_BRR | IRQSTATEN_BWR);
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 65a3d8e..1c941a2 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1214,7 +1214,7 @@ static int mmc_set_ios(struct mmc *mmc)
 }
 #endif
 
-int mmc_set_clock(struct mmc *mmc, uint clock)
+int mmc_set_clock(struct mmc *mmc, uint clock, bool disable)
 {
if (clock > mmc->cfg->f_max)
clock = mmc->cfg->f_max;
@@ -1223,6 +1223,7 @@ int mmc_set_clock(struct mmc *mmc, uint clock)
clock = mmc->cfg->f_min;
 
mmc->clock = clock;
+   mmc->clk_disable = disable;
 
return mmc_set_ios(mmc);
 }
@@ -1322,7 +1323,7 @@ static int sd_select_mode_and_width(struct mmc *mmc)
 
/* configure the bus mode (host) */
mmc_select_mode(mmc, mwt->mode);
-   mmc_set_clock(mmc, mmc->tran_speed);
+   mmc_set_clock(mmc, mmc->tran_speed, false);
 
err = sd_read_ssr(mmc);
if (!err)
@@ -1333,7 +1334,7 @@ static int sd_select_mode_and_width(struct mmc *mmc)
 error:
/* revert to a safer bus speed */
mmc_select_mode(mmc, SD_LEGACY);
-   mmc_set_clock(mmc, mmc->tran_speed);
+   mmc_set_clock(mmc, mmc->tran_speed, false);
}
}
}
@@ -1476,7 +1477,7 @@ static int mmc_select_mode_and_width(struct mmc *mmc)
 
/* configure the bus mode (host) */
mmc_select_mode(mmc, mwt->mode);
-   mmc_set_clock(mmc, mmc->tran_speed);
+   mmc_set_clock(mmc, mmc->tran_speed, false);
 
/* do a transfer to check the configuration */
err = mmc_read_and_compare_ext_csd(mmc);
@@ -1950,7 +1951,7 @@ static void mmc_set_initial_state(struct mmc *mmc)
 
mmc_select_mode(mmc, MMC_LEGACY);
mmc_set_bus_width(mmc, 1);
-   mmc_set_clock(mmc, 0);
+   mmc_set_clock(mmc, 0, false);
 }
 
 static int mmc_power_on(struct mmc *mmc)
diff --git a/include/mmc.h b/include/mmc.h
index bd096ae..8d6e0f8 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -472,6 +472,7 @@ struct mmc {
void *priv;
uint has_init;
int high_capacity;
+   bool clk_disable; /* true if the clock can be turned off */
uint bus_width;
uint clock;
enum mmc_voltage signal_voltage;
@@ -567,7 +568,16 @@ int mmc_unbind(struct udevice *dev);
 int mmc_initialize(bd_t *bis);
 int mmc_init(struct mmc *mmc);
 int mmc_read(struct mmc *mmc, u64 src, uchar *dst, int size);
-int mmc_set_clock(struct mmc *mmc, uint clock);
+
+/**
+ * mmc_set_clock() - change the bus clock
+ * @mmc:   MMC struct
+ * @clock: bus frequency in Hz
+ * @disable:   flag indicating if the clock must on or off
+ * @return 0 if OK, -ve on error
+ */
+int mmc_set_clock(struct mmc *mmc, uint clock, bool disable);
+
 struct mmc *find_mmc_device(int dev_num);
 int mmc_set_dev(int dev_num);
 void print_mmc_devices(char separator);
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 23/26] mmc: Retry some MMC cmds on failure

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

With certain SD cards like Kingston 8GB/16GB UHS card, it is seen that
MMC_CMD_ALL_SEND_CID cmd fails on first attempt, but succeeds
subsequently. Therefore, retry MMC_CMD_ALL_SEND_CID cmd a few time
as done in Linux kernel.
Similarly, it is seen that MMC_CMD_SET_BLOCKLEN may fail on first
attempt, therefore retry this cmd a few times as done in kernel.

To make it clear that those are optionnal workarounds, a new Kconfig
option 'MMC_QUIRKS' is added (enabled by default).

Signed-off-by: Vignesh R 
Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
---
 drivers/mmc/Kconfig |  9 +
 drivers/mmc/mmc.c   | 41 +++--
 include/mmc.h   |  4 
 3 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 3d577e0..78e58d4 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -33,6 +33,15 @@ config SPL_DM_MMC
 
 if MMC
 
+config MMC_QUIRKS
+   bool "Enable quirks"
+   default y
+   help
+ Some cards and hosts may sometimes behave unexpectedly (quirks).
+ This option enable workarounds to handle those quirks. Some of them
+ are enabled by default, other may require additionnal flags or are
+ enabled by the host driver.
+
 config MMC_VERBOSE
bool "Output more information about the MMC"
default y
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index c5eaeaf..6d1bf94 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -279,6 +279,7 @@ int mmc_send_status(struct mmc *mmc, int timeout)
 int mmc_set_blocklen(struct mmc *mmc, int len)
 {
struct mmc_cmd cmd;
+   int err;
 
if (mmc->ddr_mode)
return 0;
@@ -287,7 +288,24 @@ int mmc_set_blocklen(struct mmc *mmc, int len)
cmd.resp_type = MMC_RSP_R1;
cmd.cmdarg = len;
 
-   return mmc_send_cmd(mmc, , NULL);
+   err = mmc_send_cmd(mmc, , NULL);
+
+#ifdef CONFIG_MMC_QUIRKS
+   if (err && (mmc->quirks & MMC_QUIRK_RETRY_SET_BLOCKLEN)) {
+   int retries = 4;
+   /*
+* It has been seen that SET_BLOCKLEN may fail on the first
+* attempt, let's try a few more time
+*/
+   do {
+   err = mmc_send_cmd(mmc, , NULL);
+   if (!err)
+   break;
+   } while (retries--);
+   }
+#endif
+
+   return err;
 }
 
 static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
@@ -1881,7 +1899,6 @@ static int mmc_startup(struct mmc *mmc)
cmd.resp_type = MMC_RSP_R1;
cmd.cmdarg = 1;
err = mmc_send_cmd(mmc, , NULL);
-
if (err)
return err;
}
@@ -1895,6 +1912,21 @@ static int mmc_startup(struct mmc *mmc)
 
err = mmc_send_cmd(mmc, , NULL);
 
+#ifdef CONFIG_MMC_QUIRKS
+   if (err && (mmc->quirks & MMC_QUIRK_RETRY_SEND_CID)) {
+   int retries = 4;
+   /*
+* It has been seen that SEND_CID may fail on the first
+* attempt, let's try a few more time
+*/
+   do {
+   err = mmc_send_cmd(mmc, , NULL);
+   if (!err)
+   break;
+   } while (retries--);
+   }
+#endif
+
if (err)
return err;
 
@@ -2239,6 +2271,11 @@ int mmc_start_init(struct mmc *mmc)
if (err)
return err;
 
+#ifdef CONFIG_MMC_QUIRKS
+   mmc->quirks = MMC_QUIRK_RETRY_SET_BLOCKLEN |
+ MMC_QUIRK_RETRY_SEND_CID;
+#endif
+
err = mmc_power_cycle(mmc);
if (err) {
/*
diff --git a/include/mmc.h b/include/mmc.h
index a8901bf..a9ebc88 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -306,6 +306,9 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
 #define ENHNCD_SUPPORT (0x2)
 #define PART_ENH_ATTRIB(0x1f)
 
+#define MMC_QUIRK_RETRY_SEND_CID   BIT(0)
+#define MMC_QUIRK_RETRY_SET_BLOCKLEN   BIT(1)
+
 enum mmc_voltage {
MMC_SIGNAL_VOLTAGE_000 = 0,
MMC_SIGNAL_VOLTAGE_120,
@@ -591,6 +594,7 @@ struct mmc {
  * operating mode due to limitations when
  * accessing the boot partitions
  */
+   u32 quirks;
 };
 
 struct mmc_hwpart_conf {
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 26/26] dm: mmc: Add a library function to parse generic dt binding

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

Add a new function to parse host controller dt node and
set mmc_config. This function can be used by mmc controller
drivers to set the generic mmc_config.
This function can be extended to set other UHS mode caps
once UHS mode support is added.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
---
 drivers/mmc/mmc-uclass.c | 46 ++
 include/mmc.h|  1 +
 2 files changed, 47 insertions(+)

diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c
index 7856e0a..e30cde7 100644
--- a/drivers/mmc/mmc-uclass.c
+++ b/drivers/mmc/mmc-uclass.c
@@ -120,6 +120,52 @@ int mmc_execute_tuning(struct mmc *mmc, uint opcode)
return dm_mmc_execute_tuning(mmc->dev, opcode);
 }
 
+int mmc_of_parse(const void *fdt, int node, struct mmc_config *cfg)
+{
+   int val;
+
+   val = fdtdec_get_int(fdt, node, "bus-width", 1);
+
+   switch (val) {
+   case 0x8:
+   cfg->host_caps |= MMC_MODE_8BIT;
+   /* fall through */
+   case 0x4:
+   cfg->host_caps |= MMC_MODE_4BIT;
+   /* fall through */
+   case 0x1:
+   cfg->host_caps |= MMC_MODE_1BIT;
+   break;
+   default:
+   printf("error: %s invalid bus-width property %d\n",
+  fdt_get_name(fdt, node, NULL), val);
+   return -ENOENT;
+   }
+
+   cfg->f_max = fdtdec_get_int(fdt, node, "max-frequency", 5200);
+
+   if (fdtdec_get_bool(fdt, node, "cap-sd-highspeed"))
+   cfg->host_caps |= MMC_CAP(SD_HS);
+   if (fdtdec_get_bool(fdt, node, "cap-mmc-highspeed"))
+   cfg->host_caps |= MMC_CAP(MMC_HS);
+   if (fdtdec_get_bool(fdt, node, "sd-uhs-sdr12"))
+   cfg->host_caps |= MMC_CAP(UHS_SDR12);
+   if (fdtdec_get_bool(fdt, node, "sd-uhs-sdr25"))
+   cfg->host_caps |= MMC_CAP(UHS_SDR25);
+   if (fdtdec_get_bool(fdt, node, "sd-uhs-sdr50"))
+   cfg->host_caps |= MMC_CAP(UHS_SDR50);
+   if (fdtdec_get_bool(fdt, node, "sd-uhs-sdr104"))
+   cfg->host_caps |= MMC_CAP(UHS_SDR104);
+   if (fdtdec_get_bool(fdt, node, "sd-uhs-ddr50"))
+   cfg->host_caps |= MMC_CAP(UHS_DDR50);
+   if (fdtdec_get_bool(fdt, node, "mmc-ddr-1_8v"))
+   cfg->host_caps |= MMC_CAP(MMC_DDR_52);
+   if (fdtdec_get_bool(fdt, node, "mmc-hs200-1_8v"))
+   cfg->host_caps |= MMC_CAP(MMC_HS_200);
+
+   return 0;
+}
+
 struct mmc *mmc_get_mmc_dev(struct udevice *dev)
 {
struct mmc_uclass_priv *upriv;
diff --git a/include/mmc.h b/include/mmc.h
index 79be6b4..6230a32 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -651,6 +651,7 @@ int mmc_unbind(struct udevice *dev);
 int mmc_initialize(bd_t *bis);
 int mmc_init(struct mmc *mmc);
 int mmc_send_tuning(struct mmc *mmc, u32 opcode, int *cmd_error);
+int mmc_of_parse(const void *fdt, int node, struct mmc_config *cfg);
 int mmc_read(struct mmc *mmc, u64 src, uchar *dst, int size);
 
 /**
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 14/26] mmc: Add a new callback function to perform the 74 clocks cycle sequence

2017-09-21 Thread Jean-Jacques Hiblot
Add a new callback function *send_init_stream* which start a sequence of
at least 74 clock cycles.
The mmc core uses *mmc_send_init_stream* in order to invoke the callback
function. This will be used during power cycle where the specification
requires such a sequence after power up.

Signed-off-by: Jean-Jacques Hiblot 
---
 drivers/mmc/mmc-uclass.c | 13 +
 drivers/mmc/mmc.c|  6 ++
 include/mmc.h| 10 ++
 3 files changed, 29 insertions(+)

diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c
index 5dda20c..9c6a8ba 100644
--- a/drivers/mmc/mmc-uclass.c
+++ b/drivers/mmc/mmc-uclass.c
@@ -51,6 +51,19 @@ int mmc_set_ios(struct mmc *mmc)
return dm_mmc_set_ios(mmc->dev);
 }
 
+void dm_mmc_send_init_stream(struct udevice *dev)
+{
+   struct dm_mmc_ops *ops = mmc_get_ops(dev);
+
+   if (ops->send_init_stream)
+   ops->send_init_stream(dev);
+}
+
+void mmc_send_init_stream(struct mmc *mmc)
+{
+   dm_mmc_send_init_stream(mmc->dev);
+}
+
 int dm_mmc_get_wp(struct udevice *dev)
 {
struct dm_mmc_ops *ops = mmc_get_ops(dev);
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 46ec5e1..fd93691 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1198,6 +1198,10 @@ static inline int bus_width(uint cap)
 }
 
 #if !CONFIG_IS_ENABLED(DM_MMC)
+static void mmc_send_init_stream(struct mmc *mmc)
+{
+}
+
 static int mmc_set_ios(struct mmc *mmc)
 {
int ret = 0;
@@ -1983,6 +1987,8 @@ int mmc_start_init(struct mmc *mmc)
mmc_set_bus_width(mmc, 1);
mmc_set_clock(mmc, 1);
 
+   mmc_send_init_stream(mmc);
+
/* Reset the Card */
err = mmc_go_idle(mmc);
 
diff --git a/include/mmc.h b/include/mmc.h
index e524963..bd096ae 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -361,6 +361,14 @@ struct dm_mmc_ops {
int (*set_ios)(struct udevice *dev);
 
/**
+* send_init_stream() - send the initialization stream: 74 clock cycles
+* This is used after power up before sending the first command
+*
+* @dev:Device to update
+*/
+   void (*send_init_stream)(struct udevice *dev);
+
+   /**
 * get_cd() - See whether a card is present
 *
 * @dev:Device to check
@@ -382,11 +390,13 @@ struct dm_mmc_ops {
 int dm_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
struct mmc_data *data);
 int dm_mmc_set_ios(struct udevice *dev);
+void dm_mmc_send_init_stream(struct udevice *dev);
 int dm_mmc_get_cd(struct udevice *dev);
 int dm_mmc_get_wp(struct udevice *dev);
 
 /* Transition functions for compatibility */
 int mmc_set_ios(struct mmc *mmc);
+void mmc_send_init_stream(struct mmc *mmc);
 int mmc_getcd(struct mmc *mmc);
 int mmc_getwp(struct mmc *mmc);
 
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 22/26] mmc: Change mode when switching to a boot partition

2017-09-21 Thread Jean-Jacques Hiblot
Boot partitions do not support HS200. Changing to a lower performance mode
is required to access them.
mmc_select_mode_and_width() and sd_select_mode_and_width() are modified to
make it easier to call them outside of the initialization context.

Signed-off-by: Jean-Jacques Hiblot 
Reviewed-by: Simon Glass 
---
 drivers/mmc/mmc.c | 66 +--
 include/mmc.h |  7 +-
 2 files changed, 55 insertions(+), 18 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 31accdd..c5eaeaf 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -32,6 +32,7 @@ static const unsigned int sd_au_size[] = {
 
 static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage);
 static int mmc_power_cycle(struct mmc *mmc);
+static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps);
 
 #if CONFIG_IS_ENABLED(MMC_TINY)
 static struct mmc mmc_static;
@@ -792,10 +793,38 @@ static int mmc_set_capacity(struct mmc *mmc, int part_num)
return 0;
 }
 
+static int mmc_boot_part_access_chk(struct mmc *mmc, unsigned int part_num)
+{
+   int forbidden = 0;
+   bool change = false;
+
+   if (part_num & PART_ACCESS_MASK)
+   forbidden = MMC_CAP(MMC_HS_200);
+
+   if (MMC_CAP(mmc->selected_mode) & forbidden) {
+   debug("selected mode (%s) is forbidden for part %d\n",
+ mmc_mode_name(mmc->selected_mode), part_num);
+   change = true;
+   } else if (mmc->selected_mode != mmc->best_mode) {
+   debug("selected mode is not optimal\n");
+   change = true;
+   }
+
+   if (change)
+   return mmc_select_mode_and_width(mmc,
+mmc->card_caps & ~forbidden);
+
+   return 0;
+}
+
 int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
 {
int ret;
 
+   ret = mmc_boot_part_access_chk(mmc, part_num);
+   if (ret)
+   return ret;
+
ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
 (mmc->part_config & ~PART_ACCESS_MASK)
 | (part_num & PART_ACCESS_MASK));
@@ -1438,7 +1467,7 @@ static const struct mode_width_tuning sd_modes_by_pref[] 
= {
 mwt++) \
if (caps & MMC_CAP(mwt->mode))
 
-static int sd_select_mode_and_width(struct mmc *mmc)
+static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps)
 {
int err;
uint widths[] = {MMC_MODE_4BIT, MMC_MODE_1BIT};
@@ -1447,11 +1476,8 @@ static int sd_select_mode_and_width(struct mmc *mmc)
uint caps;
 
 
-   err = sd_get_capabilities(mmc);
-   if (err)
-   return err;
/* Restrict card's capabilities by what the host can do */
-   caps = mmc->card_caps & (mmc->host_caps | MMC_MODE_1BIT);
+   caps = card_caps & (mmc->host_caps | MMC_MODE_1BIT);
 
if (!uhs_en)
caps &= ~UHS_CAPS;
@@ -1588,18 +1614,14 @@ static const struct ext_csd_bus_width {
ecbv++) \
if ((ddr == ecbv->is_ddr) && (caps & ecbv->cap))
 
-static int mmc_select_mode_and_width(struct mmc *mmc)
+static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
 {
int err;
const struct mode_width_tuning *mwt;
const struct ext_csd_bus_width *ecbw;
 
-   err = mmc_get_capabilities(mmc);
-   if (err)
-   return err;
-
/* Restrict card's capabilities by what the host can do */
-   mmc->card_caps &= (mmc->host_caps | MMC_MODE_1BIT);
+   card_caps &= (mmc->host_caps | MMC_MODE_1BIT);
 
/* Only version 4 of MMC supports wider bus widths */
if (mmc->version < MMC_VERSION_4)
@@ -1610,8 +1632,10 @@ static int mmc_select_mode_and_width(struct mmc *mmc)
return -ENOTSUPP;
}
 
-   for_each_mmc_mode_by_pref(mmc->card_caps, mwt) {
-   for_each_supported_width(mmc->card_caps & mwt->widths,
+   mmc_set_clock(mmc, mmc->legacy_speed, false);
+
+   for_each_mmc_mode_by_pref(card_caps, mwt) {
+   for_each_supported_width(card_caps & mwt->widths,
 mmc_is_mode_ddr(mwt->mode), ecbw) {
debug("trying mode %s width %d (at %d MHz)\n",
  mmc_mode_name(mwt->mode),
@@ -2006,14 +2030,22 @@ static int mmc_startup(struct mmc *mmc)
if (err)
return err;
 
-   if (IS_SD(mmc))
-   err = sd_select_mode_and_width(mmc);
-   else
-   err = mmc_select_mode_and_width(mmc);
+   if (IS_SD(mmc)) {
+   err = sd_get_capabilities(mmc);
+   if (err)
+   return err;
+   err = sd_select_mode_and_width(mmc, mmc->card_caps);
+   } else {
+   err = mmc_get_capabilities(mmc);
+   if (err)
+ 

[U-Boot] [PATCH v2 07/26] mmc: Add a function to dump the mmc capabilities

2017-09-21 Thread Jean-Jacques Hiblot
This adds a simple helper function to display information (bus width and
mode) based on a capability mask. Useful for debug.

Signed-off-by: Jean-Jacques Hiblot 
---
 drivers/mmc/mmc.c | 24 
 include/mmc.h |  1 +
 2 files changed, 25 insertions(+)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 94b3a02..0b74e78 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1136,6 +1136,30 @@ static void mmc_set_bus_width(struct mmc *mmc, uint 
width)
mmc_set_ios(mmc);
 }
 
+#if CONFIG_IS_ENABLED(MMC_VERBOSE) || defined(DEBUG)
+/*
+ * helper function to display the capabilities in a human
+ * friendly manner. The capabilities include bus width and
+ * supported modes.
+ */
+void mmc_dump_capabilities(const char *text, uint caps)
+{
+   enum bus_mode mode;
+
+   printf("%s: widths [", text);
+   if (caps & MMC_MODE_8BIT)
+   printf("8, ");
+   if (caps & MMC_MODE_4BIT)
+   printf("4, ");
+   printf("1] modes [");
+
+   for (mode = MMC_LEGACY; mode < MMC_MODES_END; mode++)
+   if (MMC_CAP(mode) & caps)
+   printf("%s, ", mmc_mode_name(mode));
+   printf("\b\b]\n");
+}
+#endif
+
 static int sd_select_bus_freq_width(struct mmc *mmc)
 {
int err;
diff --git a/include/mmc.h b/include/mmc.h
index 76bd57a..dd83f14 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -426,6 +426,7 @@ enum bus_mode {
 };
 
 const char *mmc_mode_name(enum bus_mode mode);
+void mmc_dump_capabilities(const char *text, uint caps);
 
 /*
  * With CONFIG_DM_MMC enabled, struct mmc can be accessed from the MMC device
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 12/26] mmc: make mmc_set_ios() return status

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

set_ios callback has a return value of 'int' but the mmc_set_ios()
function ignore this. Modify mmc_set_ios() and the callers of mmc_set_ios() to
to return the error status.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
Reviewed-by: Simon Glass 
---
 drivers/mmc/mmc.c | 16 ++--
 include/mmc.h |  2 +-
 2 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 7361447..536cd7f 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1196,14 +1196,18 @@ static inline int bus_width(uint cap)
 }
 
 #if !CONFIG_IS_ENABLED(DM_MMC)
-static void mmc_set_ios(struct mmc *mmc)
+static int mmc_set_ios(struct mmc *mmc)
 {
+   int ret = 0;
+
if (mmc->cfg->ops->set_ios)
-   mmc->cfg->ops->set_ios(mmc);
+   ret = mmc->cfg->ops->set_ios(mmc);
+
+   return ret;
 }
 #endif
 
-void mmc_set_clock(struct mmc *mmc, uint clock)
+int mmc_set_clock(struct mmc *mmc, uint clock)
 {
if (clock > mmc->cfg->f_max)
clock = mmc->cfg->f_max;
@@ -1213,14 +1217,14 @@ void mmc_set_clock(struct mmc *mmc, uint clock)
 
mmc->clock = clock;
 
-   mmc_set_ios(mmc);
+   return mmc_set_ios(mmc);
 }
 
-static void mmc_set_bus_width(struct mmc *mmc, uint width)
+static int mmc_set_bus_width(struct mmc *mmc, uint width)
 {
mmc->bus_width = width;
 
-   mmc_set_ios(mmc);
+   return mmc_set_ios(mmc);
 }
 
 #if CONFIG_IS_ENABLED(MMC_VERBOSE) || defined(DEBUG)
diff --git a/include/mmc.h b/include/mmc.h
index 988bf17..3e57887 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -549,7 +549,7 @@ int mmc_unbind(struct udevice *dev);
 int mmc_initialize(bd_t *bis);
 int mmc_init(struct mmc *mmc);
 int mmc_read(struct mmc *mmc, u64 src, uchar *dst, int size);
-void mmc_set_clock(struct mmc *mmc, uint clock);
+int mmc_set_clock(struct mmc *mmc, uint clock);
 struct mmc *find_mmc_device(int dev_num);
 int mmc_set_dev(int dev_num);
 void print_mmc_devices(char separator);
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 21/26] mmc: disable UHS modes if Vcc cannot be switched on and off

2017-09-21 Thread Jean-Jacques Hiblot
If a power cycle cannot be done on Vcc, it is safer not to try the UHS
modes because we wouldn't be able to recover from an error occurring
during the UHS initialization.

Signed-off-by: Jean-Jacques Hiblot 
---
 drivers/mmc/mmc.c | 19 ---
 include/mmc.h |  1 +
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index ca59e28..31accdd 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1451,7 +1451,7 @@ static int sd_select_mode_and_width(struct mmc *mmc)
if (err)
return err;
/* Restrict card's capabilities by what the host can do */
-   caps = mmc->card_caps & (mmc->cfg->host_caps | MMC_MODE_1BIT);
+   caps = mmc->card_caps & (mmc->host_caps | MMC_MODE_1BIT);
 
if (!uhs_en)
caps &= ~UHS_CAPS;
@@ -1599,7 +1599,7 @@ static int mmc_select_mode_and_width(struct mmc *mmc)
return err;
 
/* Restrict card's capabilities by what the host can do */
-   mmc->card_caps &= (mmc->cfg->host_caps | MMC_MODE_1BIT);
+   mmc->card_caps &= (mmc->host_caps | MMC_MODE_1BIT);
 
/* Only version 4 of MMC supports wider bus widths */
if (mmc->version < MMC_VERSION_4)
@@ -2182,6 +2182,8 @@ int mmc_start_init(struct mmc *mmc)
bool uhs_en = supports_uhs(mmc->cfg->host_caps);
int err;
 
+   mmc->host_caps = mmc->cfg->host_caps;
+
/* we pretend there's no card when init is NULL */
no_card = mmc_getcd(mmc) == 0;
 #if !CONFIG_IS_ENABLED(DM_MMC)
@@ -2205,7 +2207,18 @@ int mmc_start_init(struct mmc *mmc)
if (err)
return err;
 
-   err = mmc_power_on(mmc);
+   err = mmc_power_cycle(mmc);
+   if (err) {
+   /*
+* if power cycling is not supported, we should not try
+* to use the UHS modes, because we wouldn't be able to
+* recover from an error during the UHS initialization.
+*/
+   debug("Unable to do a full power cycle. Disabling the UHS modes 
for safety\n");
+   uhs_en = false;
+   mmc->host_caps &= ~UHS_CAPS;
+   err = mmc_power_on(mmc);
+   }
if (err)
return err;
 
diff --git a/include/mmc.h b/include/mmc.h
index ba4a13e8..59ea363 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -544,6 +544,7 @@ struct mmc {
uint clock;
enum mmc_voltage signal_voltage;
uint card_caps;
+   uint host_caps;
uint ocr;
uint dsr;
uint dsr_imp;
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 18/26] mmc: Add a execute_tuning() callback to the mmc operations.

2017-09-21 Thread Jean-Jacques Hiblot
From: Kishon Vijay Abraham I 

Tuning is a mandatory step in the initialization of SDR104 and HS200 modes.
This callback execute the tuning process.

Signed-off-by: Kishon Vijay Abraham I 
Signed-off-by: Jean-Jacques Hiblot 
---
 drivers/mmc/mmc-uclass.c | 14 ++
 drivers/mmc/mmc.c|  5 +
 include/mmc.h| 11 +++
 3 files changed, 30 insertions(+)

diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c
index 9c6a8ba..60cc0ac 100644
--- a/drivers/mmc/mmc-uclass.c
+++ b/drivers/mmc/mmc-uclass.c
@@ -92,6 +92,20 @@ int mmc_getcd(struct mmc *mmc)
return dm_mmc_get_cd(mmc->dev);
 }
 
+int dm_mmc_execute_tuning(struct udevice *dev, uint opcode)
+{
+   struct dm_mmc_ops *ops = mmc_get_ops(dev);
+
+   if (!ops->execute_tuning)
+   return -ENOSYS;
+   return ops->execute_tuning(dev, opcode);
+}
+
+int mmc_execute_tuning(struct mmc *mmc, uint opcode)
+{
+   return dm_mmc_execute_tuning(mmc->dev, opcode);
+}
+
 struct mmc *mmc_get_mmc_dev(struct udevice *dev)
 {
struct mmc_uclass_priv *upriv;
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 1f9730e..3e2e549 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1199,6 +1199,11 @@ static inline int bus_width(uint cap)
 }
 
 #if !CONFIG_IS_ENABLED(DM_MMC)
+static int mmc_execute_tuning(struct mmc *mmc, uint opcode)
+{
+   return -ENOTSUPP;
+}
+
 static void mmc_send_init_stream(struct mmc *mmc)
 {
 }
diff --git a/include/mmc.h b/include/mmc.h
index 8d6e0f8..56fa869 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -383,6 +383,15 @@ struct dm_mmc_ops {
 * @return 0 if write-enabled, 1 if write-protected, -ve on error
 */
int (*get_wp)(struct udevice *dev);
+
+   /**
+* execute_tuning() - Start the tuning process
+*
+* @dev:Device to start the tuning
+* @opcode: Command opcode to send
+* @return 0 if OK, -ve on error
+*/
+   int (*execute_tuning)(struct udevice *dev, uint opcode);
 };
 
 #define mmc_get_ops(dev)((struct dm_mmc_ops *)(dev)->driver->ops)
@@ -393,12 +402,14 @@ int dm_mmc_set_ios(struct udevice *dev);
 void dm_mmc_send_init_stream(struct udevice *dev);
 int dm_mmc_get_cd(struct udevice *dev);
 int dm_mmc_get_wp(struct udevice *dev);
+int dm_mmc_execute_tuning(struct udevice *dev, uint opcode);
 
 /* Transition functions for compatibility */
 int mmc_set_ios(struct mmc *mmc);
 void mmc_send_init_stream(struct mmc *mmc);
 int mmc_getcd(struct mmc *mmc);
 int mmc_getwp(struct mmc *mmc);
+int mmc_execute_tuning(struct mmc *mmc, uint opcode);
 
 #else
 struct mmc_ops {
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 08/26] mmc: use mmc modes to select the correct bus speed

2017-09-21 Thread Jean-Jacques Hiblot
Signed-off-by: Jean-Jacques Hiblot 
Reviewed-by: Simon Glass 
---
 drivers/mmc/mmc.c | 39 ---
 1 file changed, 28 insertions(+), 11 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 0b74e78..382a9cf 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -174,9 +174,34 @@ const char *mmc_mode_name(enum bus_mode mode)
 }
 #endif
 
+static uint mmc_mode2freq(struct mmc *mmc, enum bus_mode mode)
+{
+   static const int freqs[] = {
+ [SD_LEGACY]   = 2500,
+ [MMC_HS]  = 2600,
+ [SD_HS]   = 5000,
+ [UHS_SDR12]   = 2500,
+ [UHS_SDR25]   = 5000,
+ [UHS_SDR50]   = 1,
+ [UHS_SDR104]  = 20800,
+ [UHS_DDR50]   = 5000,
+ [MMC_HS_52]   = 5200,
+ [MMC_DDR_52]  = 5200,
+ [MMC_HS_200]  = 2,
+   };
+
+   if (mode == MMC_LEGACY)
+   return mmc->legacy_speed;
+   else if (mode >= MMC_MODES_END)
+   return 0;
+   else
+   return freqs[mode];
+}
+
 static int mmc_select_mode(struct mmc *mmc, enum bus_mode mode)
 {
mmc->selected_mode = mode;
+   mmc->tran_speed = mmc_mode2freq(mmc, mode);
debug("selecting mode %s (freq : %d MHz)\n", mmc_mode_name(mode),
  mmc->tran_speed / 100);
return 0;
@@ -1195,13 +1220,10 @@ static int sd_select_bus_freq_width(struct mmc *mmc)
if (err)
return err;
 
-   if (mmc->card_caps & MMC_MODE_HS) {
+   if (mmc->card_caps & MMC_MODE_HS)
mmc_select_mode(mmc, SD_HS);
-   mmc->tran_speed = 5000;
-   } else {
+   else
mmc_select_mode(mmc, SD_LEGACY);
-   mmc->tran_speed = 2500;
-   }
 
return 0;
 }
@@ -1323,11 +1345,8 @@ static int mmc_select_bus_freq_width(struct mmc *mmc)
mmc_select_mode(mmc, MMC_DDR_52);
else
mmc_select_mode(mmc, MMC_HS_52);
-   mmc->tran_speed = 5200;
-   } else if (mmc->card_caps & MMC_MODE_HS) {
+   } else if (mmc->card_caps & MMC_MODE_HS)
mmc_select_mode(mmc, MMC_HS);
-   mmc->tran_speed = 2600;
-   }
 
return err;
 }
@@ -1599,7 +1618,6 @@ static int mmc_startup(struct mmc *mmc)
mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
 
mmc->legacy_speed = freq * mult;
-   mmc->tran_speed = mmc->legacy_speed;
mmc_select_mode(mmc, MMC_LEGACY);
 
mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
@@ -1674,7 +1692,6 @@ static int mmc_startup(struct mmc *mmc)
if (err)
return err;
 
-   mmc_set_clock(mmc, mmc->tran_speed);
 
/* Fix the block length for DDR mode */
if (mmc->ddr_mode) {
-- 
1.9.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 10/26] mmc: refactor SD startup to make it easier to support new modes

2017-09-21 Thread Jean-Jacques Hiblot
The SDcard startup process currently handles only 2 modes. To make it
easier to add support for more modes, let's make the process more generic
and use a list of the modes to try.
The major functional change is that when a mode fails we try the next one.
Not all modes are tried, only those supported by the card and the host.

Signed-off-by: Jean-Jacques Hiblot 
Reviewed-by: Simon Glass 
---
 drivers/mmc/mmc.c | 183 ++
 include/mmc.h |   1 +
 2 files changed, 130 insertions(+), 54 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 382a9cf..b8e726a 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -237,7 +237,8 @@ int mmc_send_status(struct mmc *mmc, int timeout)
(cmd.response[0] & MMC_STATUS_CURR_STATE) !=
 MMC_STATE_PRG)
break;
-   else if (cmd.response[0] & MMC_STATUS_MASK) {
+
+   if (cmd.response[0] & MMC_STATUS_MASK) {
 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
printf("Status Error: 0x%08X\n",
cmd.response[0]);
@@ -610,7 +611,7 @@ static int mmc_change_freq(struct mmc *mmc)
char cardtype;
int err;
 
-   mmc->card_caps = 0;
+   mmc->card_caps = MMC_MODE_1BIT;
 
if (mmc_host_is_spi(mmc))
return 0;
@@ -936,7 +937,7 @@ static int sd_switch(struct mmc *mmc, int mode, int group, 
u8 value, u8 *resp)
 }
 
 
-static int sd_change_freq(struct mmc *mmc)
+static int sd_get_capabilities(struct mmc *mmc)
 {
int err;
struct mmc_cmd cmd;
@@ -945,7 +946,7 @@ static int sd_change_freq(struct mmc *mmc)
struct mmc_data data;
int timeout;
 
-   mmc->card_caps = 0;
+   mmc->card_caps = MMC_MODE_1BIT;
 
if (mmc_host_is_spi(mmc))
return 0;
@@ -1022,26 +1023,53 @@ retry_scr:
}
 
/* If high-speed isn't supported, we return */
-   if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
-   return 0;
+   if (__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED)
+   mmc->card_caps |= MMC_CAP(SD_HS);
 
-   /*
-* If the host doesn't support SD_HIGHSPEED, do not switch card to
-* HIGHSPEED mode even if the card support SD_HIGHSPPED.
-* This can avoid furthur problem when the card runs in different
-* mode between the host.
-*/
-   if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) &&
-   (mmc->cfg->host_caps & MMC_MODE_HS)))
-   return 0;
+   return 0;
+}
+
+static int sd_set_card_speed(struct mmc *mmc, enum bus_mode mode)
+{
+   int err;
+
+   ALLOC_CACHE_ALIGN_BUFFER(uint, switch_status, 16);
 
err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
+   if (err)
+   return err;
+
+   if ((__be32_to_cpu(switch_status[4]) & 0x0f00) != 0x0100)
+   return -ENOTSUPP;
+
+   return 0;
+}
 
+int sd_select_bus_width(struct mmc *mmc, int w)
+{
+   int err;
+   struct mmc_cmd cmd;
+
+   if ((w != 4) && (w != 1))
+   return -EINVAL;
+
+   cmd.cmdidx = MMC_CMD_APP_CMD;
+   cmd.resp_type = MMC_RSP_R1;
+   cmd.cmdarg = mmc->rca << 16;
+
+   err = mmc_send_cmd(mmc, , NULL);
if (err)
return err;
 
-   if ((__be32_to_cpu(switch_status[4]) & 0x0f00) == 0x0100)
-   mmc->card_caps |= MMC_MODE_HS;
+   cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH;
+   cmd.resp_type = MMC_RSP_R1;
+   if (w == 4)
+   cmd.cmdarg = 2;
+   else if (w == 1)
+   cmd.cmdarg = 0;
+   err = mmc_send_cmd(mmc, , NULL);
+   if (err)
+   return err;
 
return 0;
 }
@@ -1133,6 +1161,18 @@ static const u8 multipliers[] = {
80,
 };
 
+static inline int bus_width(uint cap)
+{
+   if (cap == MMC_MODE_8BIT)
+   return 8;
+   if (cap == MMC_MODE_4BIT)
+   return 4;
+   if (cap == MMC_MODE_1BIT)
+   return 1;
+   error("invalid bus witdh capability 0x%x\n", cap);
+   return 0;
+}
+
 #if !CONFIG_IS_ENABLED(DM_MMC)
 static void mmc_set_ios(struct mmc *mmc)
 {
@@ -1176,8 +1216,9 @@ void mmc_dump_capabilities(const char *text, uint caps)
printf("8, ");
if (caps & MMC_MODE_4BIT)
printf("4, ");
-   printf("1] modes [");
-
+   if (caps & MMC_MODE_1BIT)
+   printf("1, ");
+   printf("\b\b] modes [");
for (mode = MMC_LEGACY; mode < MMC_MODES_END; mode++)
if (MMC_CAP(mode) & caps)
printf("%s, ", mmc_mode_name(mode));
@@ -1185,47 +1226,81 @@ void mmc_dump_capabilities(const char *text, uint caps)
 }
 #endif
 
-static int 

[U-Boot] [PATCH v2 06/26] mmc: introduce mmc modes

2017-09-21 Thread Jean-Jacques Hiblot
no functionnal changes.
In order to add the support for the high speed SD and MMC modes, it is
useful to track this information.

Signed-off-by: Jean-Jacques Hiblot 
Reviewed-by: Simon Glass 
---
 drivers/mmc/Kconfig | 14 ++
 drivers/mmc/mmc.c   | 56 ++---
 include/mmc.h   | 35 +++--
 3 files changed, 92 insertions(+), 13 deletions(-)

diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 6de927b..3d577e0 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -33,6 +33,20 @@ config SPL_DM_MMC
 
 if MMC
 
+config MMC_VERBOSE
+   bool "Output more information about the MMC"
+   default y
+   help
+ Enable the output of more information about the card such as the
+ operating mode.
+
+config SPL_MMC_VERBOSE
+   bool "Output more information about the MMC in SPL"
+   default n
+   help
+ Enable the output of more information about the card such as the
+ operating mode.
+
 config SPL_MMC_TINY
bool "Tiny MMC framework in SPL"
help
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index d360a1a..94b3a02 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -149,6 +149,39 @@ void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd)
 }
 #endif
 
+#if CONFIG_IS_ENABLED(MMC_VERBOSE) || defined(DEBUG)
+const char *mmc_mode_name(enum bus_mode mode)
+{
+   static const char *const names[] = {
+ [MMC_LEGACY]  = "MMC legacy",
+ [SD_LEGACY]   = "SD Legacy",
+ [MMC_HS]  = "MMC High Speed (26MHz)",
+ [SD_HS]   = "SD High Speed (50MHz)",
+ [UHS_SDR12]   = "UHS SDR12 (25MHz)",
+ [UHS_SDR25]   = "UHS SDR25 (50MHz)",
+ [UHS_SDR50]   = "UHS SDR50 (100MHz)",
+ [UHS_SDR104]  = "UHS SDR104 (208MHz)",
+ [UHS_DDR50]   = "UHS DDR50 (50MHz)",
+ [MMC_HS_52]   = "MMC High Speed (52MHz)",
+ [MMC_DDR_52]  = "MMC DDR52 (52MHz)",
+ [MMC_HS_200]  = "HS200 (200MHz)",
+   };
+
+   if (mode >= MMC_MODES_END)
+   return "Unknown mode";
+   else
+   return names[mode];
+}
+#endif
+
+static int mmc_select_mode(struct mmc *mmc, enum bus_mode mode)
+{
+   mmc->selected_mode = mode;
+   debug("selecting mode %s (freq : %d MHz)\n", mmc_mode_name(mode),
+ mmc->tran_speed / 100);
+   return 0;
+}
+
 #if !CONFIG_IS_ENABLED(DM_MMC)
 int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 {
@@ -1138,10 +1171,13 @@ static int sd_select_bus_freq_width(struct mmc *mmc)
if (err)
return err;
 
-   if (mmc->card_caps & MMC_MODE_HS)
+   if (mmc->card_caps & MMC_MODE_HS) {
+   mmc_select_mode(mmc, SD_HS);
mmc->tran_speed = 5000;
-   else
+   } else {
+   mmc_select_mode(mmc, SD_LEGACY);
mmc->tran_speed = 2500;
+   }
 
return 0;
 }
@@ -1258,11 +1294,15 @@ static int mmc_select_bus_freq_width(struct mmc *mmc)
if (err)
return err;
 
-   if (mmc->card_caps & MMC_MODE_HS) {
-   if (mmc->card_caps & MMC_MODE_HS_52MHz)
-   mmc->tran_speed = 5200;
+   if (mmc->card_caps & MMC_MODE_HS_52MHz) {
+   if (mmc->ddr_mode)
+   mmc_select_mode(mmc, MMC_DDR_52);
else
-   mmc->tran_speed = 2600;
+   mmc_select_mode(mmc, MMC_HS_52);
+   mmc->tran_speed = 5200;
+   } else if (mmc->card_caps & MMC_MODE_HS) {
+   mmc_select_mode(mmc, MMC_HS);
+   mmc->tran_speed = 2600;
}
 
return err;
@@ -1534,7 +1574,9 @@ static int mmc_startup(struct mmc *mmc)
freq = fbase[(cmd.response[0] & 0x7)];
mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
 
-   mmc->tran_speed = freq * mult;
+   mmc->legacy_speed = freq * mult;
+   mmc->tran_speed = mmc->legacy_speed;
+   mmc_select_mode(mmc, MMC_LEGACY);
 
mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
diff --git a/include/mmc.h b/include/mmc.h
index 7d2b363..76bd57a 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -52,12 +52,15 @@
 #define MMC_VERSION_5_0MAKE_MMC_VERSION(5, 0, 0)
 #define MMC_VERSION_5_1MAKE_MMC_VERSION(5, 1, 0)
 
-#define MMC_MODE_HS(1 << 0)
-#define MMC_MODE_HS_52MHz  (1 << 1)
-#define MMC_MODE_4BIT  (1 << 2)
-#define MMC_MODE_8BIT  (1 << 3)
-#define MMC_MODE_SPI   (1 << 4)
-#define MMC_MODE_DDR_52MHz (1 << 5)
+#define MMC_CAP(mode)  (1 << mode)
+#define MMC_MODE_HS(MMC_CAP(MMC_HS) | MMC_CAP(SD_HS))

  1   2   >