mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [RFC 0/9] ehci-hcd.c: make it works on big-endian mips (AR9331)
@ 2015-08-27 22:24 Antony Pavlov
  2015-08-27 22:24 ` [RFC 1/9] WIP: make ehci-hcd.c happy on big-endian MIPS Antony Pavlov
                   ` (8 more replies)
  0 siblings, 9 replies; 25+ messages in thread
From: Antony Pavlov @ 2015-08-27 22:24 UTC (permalink / raw)
  To: barebox; +Cc: Peter Mamonov

This patchseries is very preliminary and has several issues:

  * USBMODE_BE bit set does not work on AR9331
    see the 'usb: ehci: add big-endian registers support' patch
  * tested on USB-flash; I have to test E100 USB Ethernet too;
  * the 'usb: ehci-hcd: add OF bindings' patch is not taken into account;
    see http://lists.infradead.org/pipermail/barebox/2015-August/024545.html

Antony Pavlov (9):
  WIP: make ehci-hcd.c happy on big-endian MIPS
  WIP: fix drivers/usb/core/usb.c
  MIPS: add virt_to_phys() and phys_to_virt()
  MIPS: add trivial dma support
  ehci-hcd.c: make it works on mips
  usb: ehci: drop unusable CONFIG_EHCI_MMIO_BIG_ENDIAN condition
  usb: ehci: add big-endian registers support
  MIPS: tplink-mr3020: select big-endian EHCI support
  MIPS: tplink-mr3020_defconfig: enable usb stuff

 arch/mips/Kconfig                         |   1 +
 arch/mips/boards/tplink-mr3020/board.c    |  55 +++++++++++
 arch/mips/configs/tplink-mr3020_defconfig |  49 ++++++----
 arch/mips/include/asm/dma-mapping.h       |   1 +
 arch/mips/include/asm/dma.h               |   5 +
 arch/mips/include/asm/io.h                |  35 +++++++
 arch/mips/lib/Makefile                    |   1 +
 arch/mips/lib/dma-default.c               |  28 ++++++
 arch/mips/mach-ath79/Kconfig              |   4 +
 drivers/usb/core/usb.c                    |   2 +-
 drivers/usb/host/Kconfig                  |   3 +
 drivers/usb/host/ehci-hcd.c               | 153 +++++++++++++++---------------
 drivers/usb/host/ehci.h                   |  55 ++++++++---
 include/linux/byteorder/big_endian.h      |   2 +-
 include/usb/ehci.h                        |   1 +
 15 files changed, 286 insertions(+), 109 deletions(-)
 create mode 100644 arch/mips/lib/dma-default.c

-- 
2.5.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [RFC 1/9] WIP: make ehci-hcd.c happy on big-endian MIPS
  2015-08-27 22:24 [RFC 0/9] ehci-hcd.c: make it works on big-endian mips (AR9331) Antony Pavlov
@ 2015-08-27 22:24 ` Antony Pavlov
  2015-08-27 22:24 ` [RFC 2/9] WIP: fix drivers/usb/core/usb.c Antony Pavlov
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 25+ messages in thread
From: Antony Pavlov @ 2015-08-27 22:24 UTC (permalink / raw)
  To: barebox; +Cc: Peter Mamonov

import __constant_cpu_to_le16() from linux.git/include/uapi/linux/byteorder/big_endian.h

Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
---
 include/linux/byteorder/big_endian.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/byteorder/big_endian.h b/include/linux/byteorder/big_endian.h
index 09fb188..11cf23e 100644
--- a/include/linux/byteorder/big_endian.h
+++ b/include/linux/byteorder/big_endian.h
@@ -19,7 +19,7 @@
 #define __constant_le64_to_cpu(x) ___swab64((x))
 #define __constant_cpu_to_le32(x) ___swab32((x))
 #define __constant_le32_to_cpu(x) ___swab32((x))
-#define __constant_cpu_to_le16(x) ___swab16((x))
+#define __constant_cpu_to_le16(x) ((__force __le16)___constant_swab16((x)))
 #define __constant_le16_to_cpu(x) ___swab16((x))
 #define __constant_cpu_to_be64(x) ((__u64)(x))
 #define __constant_be64_to_cpu(x) ((__u64)(x))
-- 
2.5.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [RFC 2/9] WIP: fix drivers/usb/core/usb.c
  2015-08-27 22:24 [RFC 0/9] ehci-hcd.c: make it works on big-endian mips (AR9331) Antony Pavlov
  2015-08-27 22:24 ` [RFC 1/9] WIP: make ehci-hcd.c happy on big-endian MIPS Antony Pavlov
@ 2015-08-27 22:24 ` Antony Pavlov
  2015-08-28  6:11   ` Sascha Hauer
  2015-08-27 22:24 ` [RFC 3/9] MIPS: add virt_to_phys() and phys_to_virt() Antony Pavlov
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 25+ messages in thread
From: Antony Pavlov @ 2015-08-27 22:24 UTC (permalink / raw)
  To: barebox; +Cc: Peter Mamonov

drivers/usb/core/usb.c: In function 'usb_parse_config':
drivers/usb/core/usb.c:194:28: error: 'struct usb_configuration' has no
member named 'wTotalLength'
  le16_to_cpus(&(dev->config.wTotalLength));
                            ^
...
scripts/Makefile.build:249: recipe for target 'drivers/usb/core/usb.o'
failed
make[3]: *** [drivers/usb/core/usb.o] Error 1
scripts/Makefile.build:387: recipe for target 'drivers/usb/core' failed
make[2]: *** [drivers/usb/core] Error 2
scripts/Makefile.build:387: recipe for target 'drivers/usb' failed
make[1]: *** [drivers/usb] Error 2
Makefile:770: recipe for target 'drivers' failed
make: *** [drivers] Error 2

see also

commit 245069bcef15ecc19db616a967501349b76c84d0
Author: Sascha Hauer <s.hauer@pengutronix.de>
Date:   Thu Jul 10 11:36:12 2014 +0200

    USB: introduce usb_interface/usb_configuration structs

    Currently we have two conflicting definitions of struct
usb_config_descriptor
    and struct usb_interface_descriptor in the tree. This is because the
USB code
    uses additional fields in the structs for internal housekeeping. Add
    struct usb_interface and struct struct usb_configuration with the
housekeeping
    data and embed the corresponding hardware structs into them. This
frees the
    way to use the definitions from ch9.h in the next step.

Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
---
 drivers/usb/core/usb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 9073fff..f8d6014 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -191,7 +191,7 @@ static int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int c
 		return -1;
 	}
 	memcpy(&dev->config, buffer, buffer[0]);
-	le16_to_cpus(&(dev->config.wTotalLength));
+	le16_to_cpus(&(dev->config.desc.wTotalLength));
 	dev->config.no_of_if = 0;
 
 	index = dev->config.desc.bLength;
-- 
2.5.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [RFC 3/9] MIPS: add virt_to_phys() and phys_to_virt()
  2015-08-27 22:24 [RFC 0/9] ehci-hcd.c: make it works on big-endian mips (AR9331) Antony Pavlov
  2015-08-27 22:24 ` [RFC 1/9] WIP: make ehci-hcd.c happy on big-endian MIPS Antony Pavlov
  2015-08-27 22:24 ` [RFC 2/9] WIP: fix drivers/usb/core/usb.c Antony Pavlov
@ 2015-08-27 22:24 ` Antony Pavlov
  2015-08-28  6:34   ` Sascha Hauer
  2015-08-27 22:24 ` [RFC 4/9] MIPS: add trivial dma support Antony Pavlov
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 25+ messages in thread
From: Antony Pavlov @ 2015-08-27 22:24 UTC (permalink / raw)
  To: barebox; +Cc: Peter Mamonov

N.B. phys_to_virt() translates phys address
to KSEG1 (uncached) address as barebox mips
has no cache support.

Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
---
 arch/mips/include/asm/io.h | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index 4832be6..26605a7 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -12,8 +12,43 @@
 
 #include <linux/compiler.h>
 #include <asm/types.h>
+#include <asm/addrspace.h>
 #include <asm/byteorder.h>
 
+/*
+ *     virt_to_phys    -       map virtual addresses to physical
+ *     @address: address to remap
+ *
+ *     The returned physical address is the physical (CPU) mapping for
+ *     the memory address given. It is only valid to use this function on
+ *     addresses directly mapped or allocated via kmalloc.
+ *
+ *     This function does not give bus mappings for DMA transfers. In
+ *     almost all conceivable cases a device driver should not be using
+ *     this function
+ */
+static inline unsigned long virt_to_phys(const void *address)
+{
+	return (unsigned long)address & 0x3fffffff;
+}
+
+/*
+ *     phys_to_virt    -       map physical address to virtual
+ *     @address: address to remap
+ *
+ *     The returned virtual address is a current CPU mapping for
+ *     the memory address given. It is only valid to use this function on
+ *     addresses that have a kernel mapping
+ *
+ *     This function does not handle bus mappings for DMA transfers. In
+ *     almost all conceivable cases a device driver should not be using
+ *     this function
+ */
+static inline void *phys_to_virt(unsigned long address)
+{
+	return (void *)(KSEG1 | (address & 0x3fffffff));
+}
+
 #define	IO_SPACE_LIMIT	0
 
 /*****************************************************************************/
-- 
2.5.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [RFC 4/9] MIPS: add trivial dma support
  2015-08-27 22:24 [RFC 0/9] ehci-hcd.c: make it works on big-endian mips (AR9331) Antony Pavlov
                   ` (2 preceding siblings ...)
  2015-08-27 22:24 ` [RFC 3/9] MIPS: add virt_to_phys() and phys_to_virt() Antony Pavlov
@ 2015-08-27 22:24 ` Antony Pavlov
  2015-08-27 22:24 ` [RFC 5/9] ehci-hcd.c: make it works on mips Antony Pavlov
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 25+ messages in thread
From: Antony Pavlov @ 2015-08-27 22:24 UTC (permalink / raw)
  To: barebox; +Cc: Antony Pavlov, Peter Mamonov

From: Antony Pavlov <antony@niisi.msk.ru>

Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
---
 arch/mips/Kconfig                   |  1 +
 arch/mips/include/asm/dma-mapping.h |  1 +
 arch/mips/include/asm/dma.h         |  5 +++++
 arch/mips/lib/Makefile              |  1 +
 arch/mips/lib/dma-default.c         | 28 ++++++++++++++++++++++++++++
 5 files changed, 36 insertions(+)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index aeb5c04..e806baa 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -6,6 +6,7 @@ config MIPS
 	select HAS_KALLSYMS
 	select HAVE_CONFIGURABLE_MEMORY_LAYOUT
 	select HAVE_CONFIGURABLE_TEXT_BASE
+	select HAS_DMA
 	default y
 
 config SYS_SUPPORTS_BIG_ENDIAN
diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h
index 6395112..eb516a1 100644
--- a/arch/mips/include/asm/dma-mapping.h
+++ b/arch/mips/include/asm/dma-mapping.h
@@ -1,6 +1,7 @@
 #ifndef _ASM_DMA_MAPPING_H
 #define _ASM_DMA_MAPPING_H
 
+#include <common.h>
 #include <xfuncs.h>
 #include <asm/addrspace.h>
 #include <asm/types.h>
diff --git a/arch/mips/include/asm/dma.h b/arch/mips/include/asm/dma.h
index 30a58c7..f68df13 100644
--- a/arch/mips/include/asm/dma.h
+++ b/arch/mips/include/asm/dma.h
@@ -10,4 +10,9 @@
 
 #include "asm/dma-mapping.h"
 
+void dma_sync_single_for_cpu(unsigned long address, size_t size,
+					   enum dma_data_direction dir);
+void dma_sync_single_for_device(unsigned long address, size_t size,
+					      enum dma_data_direction dir);
+
 #endif /* __ASM_DMA_H */
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index 71c4f6b..d2fc3f8 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -6,6 +6,7 @@ obj-y += ashrdi3.o
 obj-y += cpu-probe.o
 obj-y += traps.o
 obj-y += genex.o
+obj-y += dma-default.o
 
 obj-$(CONFIG_CPU_MIPS32) += c-r4k.o
 obj-$(CONFIG_CPU_MIPS64) += c-r4k.o
diff --git a/arch/mips/lib/dma-default.c b/arch/mips/lib/dma-default.c
new file mode 100644
index 0000000..5e77ae1
--- /dev/null
+++ b/arch/mips/lib/dma-default.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2015 Antony Pavlov <antonynpavlov@gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program 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.
+ *
+ */
+
+#include <dma.h>
+
+void dma_sync_single_for_cpu(unsigned long address, size_t size,
+			     enum dma_data_direction dir)
+{
+}
+
+void dma_sync_single_for_device(unsigned long address, size_t size,
+				enum dma_data_direction dir)
+{
+}
-- 
2.5.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [RFC 5/9] ehci-hcd.c: make it works on mips
  2015-08-27 22:24 [RFC 0/9] ehci-hcd.c: make it works on big-endian mips (AR9331) Antony Pavlov
                   ` (3 preceding siblings ...)
  2015-08-27 22:24 ` [RFC 4/9] MIPS: add trivial dma support Antony Pavlov
@ 2015-08-27 22:24 ` Antony Pavlov
  2015-08-27 22:24 ` [RFC 6/9] usb: ehci: drop unusable CONFIG_EHCI_MMIO_BIG_ENDIAN condition Antony Pavlov
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 25+ messages in thread
From: Antony Pavlov @ 2015-08-27 22:24 UTC (permalink / raw)
  To: barebox; +Cc: Peter Mamonov

On MIPS processors virtual and physical addresses are differ.
So we need to add the necessary address translation.

Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
---
 drivers/usb/host/ehci-hcd.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 25e7a3e..9ce034e 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -176,7 +176,7 @@ static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz)
 	uint32_t addr, delta, next;
 	int idx;
 
-	addr = (uint32_t) buf;
+	addr = (uint32_t)virt_to_phys(buf);
 	td->qtd_dma = addr;
 	td->length = sz;
 
@@ -229,7 +229,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 	memset(ehci->td, 0, sizeof(struct qTD) * NUM_TD);
 
 	qh = &ehci->qh_list[1];
-	qh->qh_link = cpu_to_hc32((uint32_t)ehci->qh_list | QH_LINK_TYPE_QH);
+	qh->qh_link = cpu_to_hc32((uint32_t)virt_to_phys(ehci->qh_list) | QH_LINK_TYPE_QH);
 	c = (dev->speed != USB_SPEED_HIGH &&
 	     usb_pipeendpoint(pipe) == 0) ? 1 : 0;
 	endpt = (8 << 28) |
@@ -280,7 +280,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 			dev_dbg(ehci->dev, "unable construct SETUP td\n");
 			goto fail;
 		}
-		*tdp = cpu_to_hc32((uint32_t) td);
+		*tdp = cpu_to_hc32((uint32_t)virt_to_phys(td));
 		tdp = &td->qt_next;
 
 		toggle = 1;
@@ -302,7 +302,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 			dev_err(ehci->dev, "unable construct DATA td\n");
 			goto fail;
 		}
-		*tdp = cpu_to_hc32((uint32_t) td);
+		*tdp = cpu_to_hc32((uint32_t)virt_to_phys(td));
 		tdp = &td->qt_next;
 	}
 
@@ -318,11 +318,11 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 		    (3 << 10) |
 		    ((usb_pipein(pipe) ? 0 : 1) << 8) | (0x80 << 0);
 		td->qt_token = cpu_to_hc32(token);
-		*tdp = cpu_to_hc32((uint32_t)td);
+		*tdp = cpu_to_hc32((uint32_t)virt_to_phys(td));
 		tdp = &td->qt_next;
 	}
 
-	ehci->qh_list->qh_link = cpu_to_hc32((uint32_t) qh | QH_LINK_TYPE_QH);
+	ehci->qh_list->qh_link = cpu_to_hc32((uint32_t)virt_to_phys(qh) | QH_LINK_TYPE_QH);
 
 	/* Flush dcache */
 	if (IS_ENABLED(CONFIG_MMU)) {
@@ -390,7 +390,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 		goto fail;
 	}
 
-	ehci->qh_list->qh_link = cpu_to_hc32((uint32_t)ehci->qh_list | QH_LINK_TYPE_QH);
+	ehci->qh_list->qh_link = cpu_to_hc32((uint32_t)virt_to_phys(ehci->qh_list) | QH_LINK_TYPE_QH);
 
 	token = hc32_to_cpu(qh->qt_token);
 	if (!(token & 0x80)) {
@@ -435,7 +435,7 @@ fail:
 	td = (void *)hc32_to_cpu(qh->qt_next);
 	while (td != (void *)QT_NEXT_TERMINATE) {
 		qh->qt_next = td->qt_next;
-		td = (void *)hc32_to_cpu(qh->qt_next);
+		td = phys_to_virt(hc32_to_cpu(qh->qt_next));
 	}
 	return -1;
 }
@@ -791,7 +791,8 @@ static int ehci_init(struct usb_host *host)
 	ehci->qh_list->qt_token = cpu_to_hc32(0x40);
 
 	/* Set async. queue head pointer. */
-	ehci_writel(&ehci->hcor->or_asynclistaddr, (uint32_t)ehci->qh_list);
+	ehci_writel(&ehci->hcor->or_asynclistaddr,
+			(uint32_t)virt_to_phys(ehci->qh_list));
 
 	reg = ehci_readl(&ehci->hccr->cr_hcsparams);
 	descriptor.hub.bNbrPorts = HCS_N_PORTS(reg);
-- 
2.5.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [RFC 6/9] usb: ehci: drop unusable CONFIG_EHCI_MMIO_BIG_ENDIAN condition
  2015-08-27 22:24 [RFC 0/9] ehci-hcd.c: make it works on big-endian mips (AR9331) Antony Pavlov
                   ` (4 preceding siblings ...)
  2015-08-27 22:24 ` [RFC 5/9] ehci-hcd.c: make it works on mips Antony Pavlov
@ 2015-08-27 22:24 ` Antony Pavlov
  2015-08-27 22:24 ` [RFC 7/9] usb: ehci: add big-endian registers support Antony Pavlov
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 25+ messages in thread
From: Antony Pavlov @ 2015-08-27 22:24 UTC (permalink / raw)
  To: barebox; +Cc: Peter Mamonov

The Kconfig EHCI_MMIO_BIG_ENDIAN option is nowhere defined,
so we can safely drop it.

Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
---
 drivers/usb/host/ehci-hcd.c | 3 ---
 drivers/usb/host/ehci.h     | 5 -----
 2 files changed, 8 deletions(-)

diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 9ce034e..49af642 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -162,9 +162,6 @@ static int ehci_reset(struct ehci_priv *ehci)
 		reg_ptr = (uint32_t *)((u8 *)ehci->hcor + USBMODE);
 		tmp = ehci_readl(reg_ptr);
 		tmp |= USBMODE_CM_HC;
-#if defined(CONFIG_EHCI_MMIO_BIG_ENDIAN)
-		tmp |= USBMODE_BE;
-#endif
 		ehci_writel(reg_ptr, tmp);
 	}
 out:
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index d71d056..bda669b 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -80,13 +80,8 @@ static inline unsigned int ehci_readl(__u32 __iomem *regs)
 	return readl(regs);
 }
 
-#if defined CONFIG_EHCI_MMIO_BIG_ENDIAN
-#define hc32_to_cpu(x)		be32_to_cpu((x))
-#define cpu_to_hc32(x)		cpu_to_be32((x))
-#else
 #define hc32_to_cpu(x)		le32_to_cpu((x))
 #define cpu_to_hc32(x)		cpu_to_le32((x))
-#endif
 
 #define EHCI_PS_WKOC_E		(1 << 22)	/* RW wake on over current */
 #define EHCI_PS_WKDSCNNT_E	(1 << 21)	/* RW wake on disconnect */
-- 
2.5.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [RFC 7/9] usb: ehci: add big-endian registers support
  2015-08-27 22:24 [RFC 0/9] ehci-hcd.c: make it works on big-endian mips (AR9331) Antony Pavlov
                   ` (5 preceding siblings ...)
  2015-08-27 22:24 ` [RFC 6/9] usb: ehci: drop unusable CONFIG_EHCI_MMIO_BIG_ENDIAN condition Antony Pavlov
@ 2015-08-27 22:24 ` Antony Pavlov
  2015-08-28  6:19   ` Sascha Hauer
  2015-08-27 22:24 ` [RFC 8/9] MIPS: tplink-mr3020: select big-endian EHCI support Antony Pavlov
  2015-08-27 22:24 ` [RFC 9/9] MIPS: tplink-mr3020_defconfig: enable usb stuff Antony Pavlov
  8 siblings, 1 reply; 25+ messages in thread
From: Antony Pavlov @ 2015-08-27 22:24 UTC (permalink / raw)
  To: barebox; +Cc: Peter Mamonov

Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
---
 drivers/usb/host/Kconfig    |   3 +
 drivers/usb/host/ehci-hcd.c | 133 ++++++++++++++++++++++----------------------
 drivers/usb/host/ehci.h     |  42 +++++++++++++-
 include/usb/ehci.h          |   1 +
 4 files changed, 108 insertions(+), 71 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 54eaf46..23dcf9c 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -2,6 +2,9 @@ config USB_EHCI
 	bool "EHCI driver"
 	depends on HAS_DMA
 
+config USB_EHCI_BIG_ENDIAN_MMIO
+	bool
+
 config USB_EHCI_OMAP
 	depends on ARCH_OMAP3
 	depends on USB_TWL4030
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 49af642..dd5f503 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -34,22 +34,6 @@
 
 #include "ehci.h"
 
-struct ehci_priv {
-	int rootdev;
-	struct device_d *dev;
-	struct ehci_hccr *hccr;
-	struct ehci_hcor *hcor;
-	struct usb_host host;
-	struct QH *qh_list;
-	struct qTD *td;
-	int portreset;
-	unsigned long flags;
-
-	int (*init)(void *drvdata);
-	int (*post_init)(void *drvdata);
-	void *drvdata;
-};
-
 #define to_ehci(ptr) container_of(ptr, struct ehci_priv, host)
 
 #define NUM_QH	2
@@ -123,7 +107,8 @@ static struct descriptor {
 
 #define ehci_is_TDI()	(ehci->flags & EHCI_HAS_TT)
 
-static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec)
+static int handshake(const struct ehci_priv *ehci,
+			uint32_t *ptr, uint32_t mask, uint32_t done, int usec)
 {
 	uint32_t result;
 	uint64_t start;
@@ -131,7 +116,7 @@ static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec)
 	start = get_time_ns();
 
 	while (1) {
-		result = ehci_readl(ptr);
+		result = ehci_readl(ehci, ptr);
 		if (result == ~(uint32_t)0)
 			return -1;
 		result &= mask;
@@ -149,10 +134,11 @@ static int ehci_reset(struct ehci_priv *ehci)
 	uint32_t *reg_ptr;
 	int ret = 0;
 
-	cmd = ehci_readl(&ehci->hcor->or_usbcmd);
+	cmd = ehci_readl(ehci, &ehci->hcor->or_usbcmd);
 	cmd |= CMD_RESET;
-	ehci_writel(&ehci->hcor->or_usbcmd, cmd);
-	ret = handshake(&ehci->hcor->or_usbcmd, CMD_RESET, 0, 250 * 1000);
+	ehci_writel(ehci, &ehci->hcor->or_usbcmd, cmd);
+	ret = handshake(ehci, &ehci->hcor->or_usbcmd, CMD_RESET, 0,
+			250 * 1000);
 	if (ret < 0) {
 		dev_err(ehci->dev, "fail to reset\n");
 		goto out;
@@ -160,9 +146,14 @@ static int ehci_reset(struct ehci_priv *ehci)
 
 	if (ehci_is_TDI()) {
 		reg_ptr = (uint32_t *)((u8 *)ehci->hcor + USBMODE);
-		tmp = ehci_readl(reg_ptr);
+		tmp = ehci_readl(ehci, reg_ptr);
 		tmp |= USBMODE_CM_HC;
-		ehci_writel(reg_ptr, tmp);
+		/* FIXME: does not work on AR9331 yet */
+		/*
+		if (ehci_big_endian_mmio(ehci))
+			tmp |= USBMODE_BE;
+		*/
+		ehci_writel(ehci, reg_ptr, tmp);
 	}
 out:
 	return ret;
@@ -333,15 +324,16 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 		}
 	}
 
-	usbsts = ehci_readl(&ehci->hcor->or_usbsts);
-	ehci_writel(&ehci->hcor->or_usbsts, (usbsts & 0x3f));
+	usbsts = ehci_readl(ehci, &ehci->hcor->or_usbsts);
+	ehci_writel(ehci, &ehci->hcor->or_usbsts, (usbsts & 0x3f));
 
 	/* Enable async. schedule. */
-	cmd = ehci_readl(&ehci->hcor->or_usbcmd);
+	cmd = ehci_readl(ehci, &ehci->hcor->or_usbcmd);
 	cmd |= CMD_ASE;
-	ehci_writel(&ehci->hcor->or_usbcmd, cmd);
+	ehci_writel(ehci, &ehci->hcor->or_usbcmd, cmd);
 
-	ret = handshake(&ehci->hcor->or_usbsts, STD_ASS, STD_ASS, 100 * 1000);
+	ret = handshake(ehci, &ehci->hcor->or_usbsts, STD_ASS, STD_ASS,
+			100 * 1000);
 	if (ret < 0) {
 		dev_err(ehci->dev, "fail timeout STD_ASS set\n");
 		goto fail;
@@ -355,12 +347,13 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 		token = hc32_to_cpu(vtd->qt_token);
 		if (is_timeout(start, timeout_val)) {
 			/* Disable async schedule. */
-			cmd = ehci_readl(&ehci->hcor->or_usbcmd);
+			cmd = ehci_readl(ehci, &ehci->hcor->or_usbcmd);
 			cmd &= ~CMD_ASE;
-			ehci_writel(&ehci->hcor->or_usbcmd, cmd);
+			ehci_writel(ehci, &ehci->hcor->or_usbcmd, cmd);
 
-			ret = handshake(&ehci->hcor->or_usbsts, STD_ASS, 0, 100 * 1000);
-			ehci_writel(&qh->qt_token, 0);
+			ret = handshake(ehci, &ehci->hcor->or_usbsts,
+					STD_ASS, 0, 100 * 1000);
+			ehci_writel(ehci, &qh->qt_token, 0);
 			return -ETIMEDOUT;
 		}
 	} while (token & 0x80);
@@ -376,11 +369,11 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 	}
 
 	/* Disable async schedule. */
-	cmd = ehci_readl(&ehci->hcor->or_usbcmd);
+	cmd = ehci_readl(ehci, &ehci->hcor->or_usbcmd);
 	cmd &= ~CMD_ASE;
-	ehci_writel(&ehci->hcor->or_usbcmd, cmd);
+	ehci_writel(ehci, &ehci->hcor->or_usbcmd, cmd);
 
-	ret = handshake(&ehci->hcor->or_usbsts, STD_ASS, 0,
+	ret = handshake(ehci, &ehci->hcor->or_usbsts, STD_ASS, 0,
 			100 * 1000);
 	if (ret < 0) {
 		dev_err(ehci->dev, "fail timeout STD_ASS reset\n");
@@ -420,9 +413,9 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 	} else {
 		dev->act_len = 0;
 		dev_dbg(ehci->dev, "dev=%u, usbsts=%#x, p[1]=%#x, p[2]=%#x\n",
-		      dev->devnum, ehci_readl(&ehci->hcor->or_usbsts),
-		      ehci_readl(&ehci->hcor->or_portsc[0]),
-		      ehci_readl(&ehci->hcor->or_portsc[1]));
+		      dev->devnum, ehci_readl(ehci, &ehci->hcor->or_usbsts),
+		      ehci_readl(ehci, &ehci->hcor->or_portsc[0]),
+		      ehci_readl(ehci, &ehci->hcor->or_portsc[1]));
 	}
 
 	return (dev->status != USB_ST_NOT_PROC) ? 0 : -1;
@@ -567,7 +560,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 		break;
 	case USB_REQ_GET_STATUS | ((USB_RT_PORT | USB_DIR_IN) << 8):
 		memset(tmpbuf, 0, 4);
-		reg = ehci_readl(status_reg);
+		reg = ehci_readl(ehci, status_reg);
 		if (reg & EHCI_PS_CS)
 			tmpbuf[0] |= USB_PORT_STAT_CONNECTION;
 		if (reg & EHCI_PS_PE)
@@ -581,8 +574,9 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 			int ret;
 			/* force reset to complete */
 			reg = reg & ~(EHCI_PS_PR | EHCI_PS_CLEAR);
-			ehci_writel(status_reg, reg);
-			ret = handshake(status_reg, EHCI_PS_PR, 0, 2 * 1000);
+			ehci_writel(ehci, status_reg, reg);
+			ret = handshake(ehci, status_reg, EHCI_PS_PR, 0,
+						2 * 1000);
 			if (!ret)
 				tmpbuf[0] |= USB_PORT_STAT_RESET;
 			else
@@ -621,17 +615,17 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 		srclen = 4;
 		break;
 	case USB_REQ_SET_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
-		reg = ehci_readl(status_reg);
+		reg = ehci_readl(ehci, status_reg);
 		reg &= ~EHCI_PS_CLEAR;
 		switch (le16_to_cpu(req->value)) {
 		case USB_PORT_FEAT_ENABLE:
 			reg |= EHCI_PS_PE;
-			ehci_writel(status_reg, reg);
+			ehci_writel(ehci, status_reg, reg);
 			break;
 		case USB_PORT_FEAT_POWER:
-			if (HCS_PPC(ehci_readl(&ehci->hccr->cr_hcsparams))) {
+			if (HCS_PPC(ehci_readl(ehci, &ehci->hccr->cr_hcsparams))) {
 				reg |= EHCI_PS_PP;
-				ehci_writel(status_reg, reg);
+				ehci_writel(ehci, status_reg, reg);
 			}
 			break;
 		case USB_PORT_FEAT_RESET:
@@ -642,14 +636,14 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 				dev_dbg(ehci->dev, "port %d low speed --> companion\n",
 				      port - 1);
 				reg |= EHCI_PS_PO;
-				ehci_writel(status_reg, reg);
+				ehci_writel(ehci, status_reg, reg);
 				break;
 			} else {
 				int ret;
 
 				reg |= EHCI_PS_PR;
 				reg &= ~EHCI_PS_PE;
-				ehci_writel(status_reg, reg);
+				ehci_writel(ehci, status_reg, reg);
 				/*
 				 * caller must wait, then call GetPortStatus
 				 * usb 2.0 specification say 50 ms resets on
@@ -659,13 +653,13 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 				mdelay(50);
 				ehci->portreset |= 1 << port;
 				/* terminate the reset */
-				ehci_writel(status_reg, reg & ~EHCI_PS_PR);
+				ehci_writel(ehci, status_reg, reg & ~EHCI_PS_PR);
 				/*
 				 * A host controller must terminate the reset
 				 * and stabilize the state of the port within
 				 * 2 milliseconds
 				 */
-				ret = handshake(status_reg, EHCI_PS_PR, 0,
+				ret = handshake(ehci, status_reg, EHCI_PS_PR, 0,
 						2 * 1000);
 				if (!ret)
 					ehci->portreset |=
@@ -681,10 +675,10 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 			goto unknown;
 		}
 		/* unblock posted writes */
-		(void) ehci_readl(&ehci->hcor->or_usbcmd);
+		(void) ehci_readl(ehci, &ehci->hcor->or_usbcmd);
 		break;
 	case USB_REQ_CLEAR_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
-		reg = ehci_readl(status_reg);
+		reg = ehci_readl(ehci, status_reg);
 		reg &= ~EHCI_PS_CLEAR;
 		switch (le16_to_cpu(req->value)) {
 		case USB_PORT_FEAT_ENABLE:
@@ -694,7 +688,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 			reg |= EHCI_PS_PEC;
 			break;
 		case USB_PORT_FEAT_POWER:
-			if (HCS_PPC(ehci_readl(&ehci->hccr->cr_hcsparams)))
+			if (HCS_PPC(ehci_readl(ehci, &ehci->hccr->cr_hcsparams)))
 				reg &= ~ EHCI_PS_PP;
 			break;
 		case USB_PORT_FEAT_C_CONNECTION:
@@ -710,9 +704,9 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 			dev_dbg(ehci->dev, "unknown feature %x\n", le16_to_cpu(req->value));
 			goto unknown;
 		}
-		ehci_writel(status_reg, reg);
+		ehci_writel(ehci, status_reg, reg);
 		/* unblock posted write */
-		(void) ehci_readl(&ehci->hcor->or_usbcmd);
+		(void) ehci_readl(ehci, &ehci->hcor->or_usbcmd);
 		break;
 	default:
 		dev_dbg(ehci->dev, "Unknown request\n");
@@ -743,19 +737,19 @@ unknown:
 /* force HC to halt state from unknown (EHCI spec section 2.3) */
 static int ehci_halt(struct ehci_priv *ehci)
 {
-	u32	temp = ehci_readl(&ehci->hcor->or_usbsts);
+	u32	temp = ehci_readl(ehci, &ehci->hcor->or_usbsts);
 
 	/* disable any irqs left enabled by previous code */
-	ehci_writel(&ehci->hcor->or_usbintr, 0);
+	ehci_writel(ehci, &ehci->hcor->or_usbintr, 0);
 
 	if (temp & STS_HALT)
 		return 0;
 
-	temp = ehci_readl(&ehci->hcor->or_usbcmd);
+	temp = ehci_readl(ehci, &ehci->hcor->or_usbcmd);
 	temp &= ~CMD_RUN;
-	ehci_writel(&ehci->hcor->or_usbcmd, temp);
+	ehci_writel(ehci, &ehci->hcor->or_usbcmd, temp);
 
-	return handshake(&ehci->hcor->or_usbsts,
+	return handshake(ehci, &ehci->hcor->or_usbsts,
 			  STS_HALT, STS_HALT, 16 * 125);
 }
 
@@ -788,10 +782,10 @@ static int ehci_init(struct usb_host *host)
 	ehci->qh_list->qt_token = cpu_to_hc32(0x40);
 
 	/* Set async. queue head pointer. */
-	ehci_writel(&ehci->hcor->or_asynclistaddr,
+	ehci_writel(ehci, &ehci->hcor->or_asynclistaddr,
 			(uint32_t)virt_to_phys(ehci->qh_list));
 
-	reg = ehci_readl(&ehci->hccr->cr_hcsparams);
+	reg = ehci_readl(ehci, &ehci->hccr->cr_hcsparams);
 	descriptor.hub.bNbrPorts = HCS_N_PORTS(reg);
 
 	/* Port Indicators */
@@ -802,21 +796,21 @@ static int ehci_init(struct usb_host *host)
 		descriptor.hub.wHubCharacteristics |= 0x01;
 
 	/* Start the host controller. */
-	cmd = ehci_readl(&ehci->hcor->or_usbcmd);
+	cmd = ehci_readl(ehci, &ehci->hcor->or_usbcmd);
 	/*
 	 * Philips, Intel, and maybe others need CMD_RUN before the
 	 * root hub will detect new devices (why?); NEC doesn't
 	 */
 	cmd &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET);
 	cmd |= CMD_RUN;
-	ehci_writel(&ehci->hcor->or_usbcmd, cmd);
+	ehci_writel(ehci, &ehci->hcor->or_usbcmd, cmd);
 
 	/* take control over the ports */
-	cmd = ehci_readl(&ehci->hcor->or_configflag);
+	cmd = ehci_readl(ehci, &ehci->hcor->or_configflag);
 	cmd |= FLAG_CF;
-	ehci_writel(&ehci->hcor->or_configflag, cmd);
+	ehci_writel(ehci, &ehci->hcor->or_configflag, cmd);
 	/* unblock posted write */
-	cmd = ehci_readl(&ehci->hcor->or_usbcmd);
+	cmd = ehci_readl(ehci, &ehci->hcor->or_usbcmd);
 	mdelay(5);
 
 	ehci->rootdev = 0;
@@ -890,6 +884,9 @@ int ehci_register(struct device_d *dev, struct ehci_data *data)
 	host = &ehci->host;
 	dev->priv = ehci;
 	ehci->flags = data->flags;
+	if (data->flags & EHCI_BE_MMIO)
+		ehci->big_endian_mmio = 1;
+
 	ehci->hccr = data->hccr;
 	ehci->dev = dev;
 
@@ -897,7 +894,7 @@ int ehci_register(struct device_d *dev, struct ehci_data *data)
 		ehci->hcor = data->hcor;
 	else
 		ehci->hcor = (void __iomem *)ehci->hccr +
-			HC_LENGTH(ehci_readl(&ehci->hccr->cr_capbase));
+			HC_LENGTH(ehci_readl(ehci, &ehci->hccr->cr_capbase));
 
 	ehci->drvdata = data->drvdata;
 	ehci->init = data->init;
@@ -922,7 +919,7 @@ int ehci_register(struct device_d *dev, struct ehci_data *data)
 
 	usb_register_host(host);
 
-	reg = HC_VERSION(ehci_readl(&ehci->hccr->cr_capbase));
+	reg = HC_VERSION(ehci_readl(ehci, &ehci->hccr->cr_capbase));
 	dev_info(dev, "USB EHCI %x.%02x\n", reg >> 8, reg & 0xff);
 
 	return 0;
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index bda669b..e62aca8 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -70,13 +70,49 @@ struct ehci_hcor {
 #define USBMODE_CM_HC	(3 << 0)	/* host controller mode */
 #define USBMODE_CM_IDLE	(0 << 0)	/* idle state */
 
-static inline void ehci_writel(__u32 __iomem *regs, const unsigned int val)
+struct ehci_priv {
+	int rootdev;
+	struct device_d *dev;
+	struct ehci_hccr *hccr;
+	struct ehci_hcor *hcor;
+	struct usb_host host;
+	struct QH *qh_list;
+	struct qTD *td;
+	int portreset;
+	unsigned long flags;
+	unsigned	big_endian_mmio:1;
+
+	int (*init)(void *drvdata);
+	int (*post_init)(void *drvdata);
+	void *drvdata;
+};
+
+#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
+#define ehci_big_endian_mmio(e)		((e)->big_endian_mmio)
+#else
+#define ehci_big_endian_mmio(e)		0
+#endif
+
+static inline void ehci_writel(const struct ehci_priv *ehci,
+				__u32 __iomem *regs, const unsigned int val)
 {
-	writel(val, regs);
+	if (IS_ENABLED(CONFIG_USB_EHCI_BIG_ENDIAN_MMIO)) {
+		ehci_big_endian_mmio(ehci) ?
+			iowrite32be(val, regs) :
+			writel(val, regs);
+	} else
+		writel(val, regs);
 }
 
-static inline unsigned int ehci_readl(__u32 __iomem *regs)
+static inline unsigned int ehci_readl(const struct ehci_priv *ehci,
+					__u32 __iomem *regs)
 {
+	if (IS_ENABLED(CONFIG_USB_EHCI_BIG_ENDIAN_MMIO)) {
+		return ehci_big_endian_mmio(ehci) ?
+			ioread32be(regs) :
+			readl(regs);
+	}
+
 	return readl(regs);
 }
 
diff --git a/include/usb/ehci.h b/include/usb/ehci.h
index 93f980d..0089a0c 100644
--- a/include/usb/ehci.h
+++ b/include/usb/ehci.h
@@ -2,6 +2,7 @@
 #define __USB_EHCI_H
 
 #define EHCI_HAS_TT	(1 << 0)
+#define EHCI_BE_MMIO	(1 << 1)
 
 struct ehci_platform_data {
 	unsigned long flags;
-- 
2.5.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [RFC 8/9] MIPS: tplink-mr3020: select big-endian EHCI support
  2015-08-27 22:24 [RFC 0/9] ehci-hcd.c: make it works on big-endian mips (AR9331) Antony Pavlov
                   ` (6 preceding siblings ...)
  2015-08-27 22:24 ` [RFC 7/9] usb: ehci: add big-endian registers support Antony Pavlov
@ 2015-08-27 22:24 ` Antony Pavlov
  2015-08-27 22:24 ` [RFC 9/9] MIPS: tplink-mr3020_defconfig: enable usb stuff Antony Pavlov
  8 siblings, 0 replies; 25+ messages in thread
From: Antony Pavlov @ 2015-08-27 22:24 UTC (permalink / raw)
  To: barebox; +Cc: Peter Mamonov

Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
---
 arch/mips/boards/tplink-mr3020/board.c | 55 ++++++++++++++++++++++++++++++++++
 arch/mips/mach-ath79/Kconfig           |  4 +++
 2 files changed, 59 insertions(+)

diff --git a/arch/mips/boards/tplink-mr3020/board.c b/arch/mips/boards/tplink-mr3020/board.c
index 318998c..032ad7d 100644
--- a/arch/mips/boards/tplink-mr3020/board.c
+++ b/arch/mips/boards/tplink-mr3020/board.c
@@ -25,3 +25,58 @@ static int model_hostname_init(void)
 	return 0;
 }
 postcore_initcall(model_hostname_init);
+
+#include <asm/addrspace.h>
+#include <mach/ath79.h>
+#include <usb/ehci.h>
+
+#define AR933X_RESET_REG_RESET_MODULE           0x1c
+#define AR933X_RESET_USB_HOST           BIT(5)
+#define AR933X_RESET_USB_PHY            BIT(4)
+#define AR933X_RESET_USBSUS_OVERRIDE    BIT(3)
+
+#define AR933X_EHCI_BASE	0x1b000000
+#define AR933X_EHCI_SIZE	0x1000
+
+static void ath79_device_reset_set(u32 mask)
+{
+	u32 reg;
+	u32 t;
+
+	reg = AR933X_RESET_REG_RESET_MODULE;
+	t = ath79_reset_rr(reg);
+	ath79_reset_wr(reg, t | mask);
+}
+
+static void ath79_device_reset_clear(u32 mask)
+{
+	u32 reg;
+	u32 t;
+
+	reg = AR933X_RESET_REG_RESET_MODULE;
+	t = ath79_reset_rr(reg);
+	ath79_reset_wr(reg, t & ~mask);
+}
+
+static struct ehci_platform_data ehci_pdata = {
+	.flags = EHCI_HAS_TT | EHCI_BE_MMIO,
+};
+
+static int ehci_init(void)
+{
+	ath79_device_reset_set(AR933X_RESET_USBSUS_OVERRIDE);
+	mdelay(10); mdelay(10); mdelay(10);
+
+	ath79_device_reset_clear(AR933X_RESET_USB_HOST);
+	mdelay(10); mdelay(10); mdelay(10);
+
+	ath79_device_reset_clear(AR933X_RESET_USB_PHY);
+	mdelay(10); mdelay(10); mdelay(10);
+
+	add_generic_usb_ehci_device(DEVICE_ID_DYNAMIC,
+			KSEG1ADDR(AR933X_EHCI_BASE),
+			&ehci_pdata);
+
+	return 0;
+}
+device_initcall(ehci_init);
diff --git a/arch/mips/mach-ath79/Kconfig b/arch/mips/mach-ath79/Kconfig
index f730b37..24ec078 100644
--- a/arch/mips/mach-ath79/Kconfig
+++ b/arch/mips/mach-ath79/Kconfig
@@ -12,6 +12,10 @@ config BOARD_TPLINK_MR3020
 	select HAVE_PBL_IMAGE
 	select HAVE_IMAGE_COMPRESSION
 	select HAS_NMON
+	select USB_HOST
+	select HAS_DMA
+	select USB_EHCI
+	select USB_EHCI_BIG_ENDIAN_MMIO
 
 endchoice
 
-- 
2.5.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [RFC 9/9] MIPS: tplink-mr3020_defconfig: enable usb stuff
  2015-08-27 22:24 [RFC 0/9] ehci-hcd.c: make it works on big-endian mips (AR9331) Antony Pavlov
                   ` (7 preceding siblings ...)
  2015-08-27 22:24 ` [RFC 8/9] MIPS: tplink-mr3020: select big-endian EHCI support Antony Pavlov
@ 2015-08-27 22:24 ` Antony Pavlov
  8 siblings, 0 replies; 25+ messages in thread
From: Antony Pavlov @ 2015-08-27 22:24 UTC (permalink / raw)
  To: barebox; +Cc: Peter Mamonov

Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
---
 arch/mips/configs/tplink-mr3020_defconfig | 49 +++++++++++++++++++++----------
 1 file changed, 33 insertions(+), 16 deletions(-)

diff --git a/arch/mips/configs/tplink-mr3020_defconfig b/arch/mips/configs/tplink-mr3020_defconfig
index 9f81ce3..e8e3209 100644
--- a/arch/mips/configs/tplink-mr3020_defconfig
+++ b/arch/mips/configs/tplink-mr3020_defconfig
@@ -1,34 +1,51 @@
 CONFIG_BUILTIN_DTB=y
 CONFIG_BUILTIN_DTB_NAME="tplink-mr3020"
 CONFIG_MACH_MIPS_ATH79=y
-CONFIG_LONGHELP=y
 CONFIG_CMDLINE_EDITING=y
 CONFIG_AUTO_COMPLETE=y
-CONFIG_CMD_EDIT=y
-CONFIG_CMD_SLEEP=y
-CONFIG_CMD_LET=y
-CONFIG_CMD_GLOBAL=y
+CONFIG_LONGHELP=y
+CONFIG_CMD_IOMEM=y
+CONFIG_CMD_MEMINFO=y
+# CONFIG_CMD_BOOTM is not set
+CONFIG_CMD_GO=y
 CONFIG_CMD_LOADB=y
 CONFIG_CMD_LOADY=y
-CONFIG_CMD_MEMINFO=y
-CONFIG_CMD_IOMEM=y
-CONFIG_CMD_MM=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_GLOBAL=y
 CONFIG_CMD_SHA1SUM=y
+CONFIG_CMD_LET=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_HOST=y
+CONFIG_NET_CMD_IFUP=y
+CONFIG_CMD_MIITOOL=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_TFTP=y
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_MM=y
+CONFIG_CMD_CLK=y
 CONFIG_CMD_FLASH=y
-# CONFIG_CMD_BOOTM is not set
-CONFIG_CMD_RESET=y
-CONFIG_CMD_GO=y
-CONFIG_CMD_OFTREE=y
-CONFIG_CMD_OF_PROPERTY=y
-CONFIG_CMD_OF_NODE=y
 CONFIG_CMD_SPI=y
-CONFIG_CMD_CLK=y
+CONFIG_CMD_OF_NODE=y
+CONFIG_CMD_OF_PROPERTY=y
+CONFIG_CMD_OFTREE=y
+CONFIG_NET=y
+CONFIG_NET_NFS=y
+CONFIG_NET_NETCONSOLE=y
 CONFIG_OFDEVICE=y
 CONFIG_DRIVER_SERIAL_AR933X=y
+CONFIG_NET_USB=y
+CONFIG_NET_USB_ASIX=y
+CONFIG_NET_USB_SMSC95XX=y
 CONFIG_DRIVER_SPI_ATH79=y
 CONFIG_MTD=y
 # CONFIG_MTD_OOB_DEVICE is not set
 CONFIG_MTD_M25P80=y
-CONFIG_MD5=y
+CONFIG_USB_STORAGE=y
+CONFIG_FS_EXT4=y
+CONFIG_FS_TFTP=y
+CONFIG_FS_NFS=y
+CONFIG_FS_FAT=y
+CONFIG_FS_FAT_LFN=y
 CONFIG_DIGEST_SHA224_GENERIC=y
 CONFIG_DIGEST_SHA256_GENERIC=y
-- 
2.5.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC 2/9] WIP: fix drivers/usb/core/usb.c
  2015-08-27 22:24 ` [RFC 2/9] WIP: fix drivers/usb/core/usb.c Antony Pavlov
@ 2015-08-28  6:11   ` Sascha Hauer
  2015-08-28 15:51     ` Antony Pavlov
  0 siblings, 1 reply; 25+ messages in thread
From: Sascha Hauer @ 2015-08-28  6:11 UTC (permalink / raw)
  To: Antony Pavlov; +Cc: barebox, Peter Mamonov

On Fri, Aug 28, 2015 at 01:24:03AM +0300, Antony Pavlov wrote:
> drivers/usb/core/usb.c: In function 'usb_parse_config':
> drivers/usb/core/usb.c:194:28: error: 'struct usb_configuration' has no
> member named 'wTotalLength'
>   le16_to_cpus(&(dev->config.wTotalLength));
>                             ^
> ...
> scripts/Makefile.build:249: recipe for target 'drivers/usb/core/usb.o'
> failed
> make[3]: *** [drivers/usb/core/usb.o] Error 1
> scripts/Makefile.build:387: recipe for target 'drivers/usb/core' failed
> make[2]: *** [drivers/usb/core] Error 2
> scripts/Makefile.build:387: recipe for target 'drivers/usb' failed
> make[1]: *** [drivers/usb] Error 2
> Makefile:770: recipe for target 'drivers' failed
> make: *** [drivers] Error 2
> 
> see also
> 
> commit 245069bcef15ecc19db616a967501349b76c84d0
> Author: Sascha Hauer <s.hauer@pengutronix.de>
> Date:   Thu Jul 10 11:36:12 2014 +0200
> 
>     USB: introduce usb_interface/usb_configuration structs
> 
>     Currently we have two conflicting definitions of struct
> usb_config_descriptor
>     and struct usb_interface_descriptor in the tree. This is because the
> USB code
>     uses additional fields in the structs for internal housekeeping. Add
>     struct usb_interface and struct struct usb_configuration with the
> housekeeping
>     data and embed the corresponding hardware structs into them. This
> frees the
>     way to use the definitions from ch9.h in the next step.
> 
> Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
> ---
>  drivers/usb/core/usb.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
> index 9073fff..f8d6014 100644
> --- a/drivers/usb/core/usb.c
> +++ b/drivers/usb/core/usb.c
> @@ -191,7 +191,7 @@ static int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int c
>  		return -1;
>  	}
>  	memcpy(&dev->config, buffer, buffer[0]);
> -	le16_to_cpus(&(dev->config.wTotalLength));
> +	le16_to_cpus(&(dev->config.desc.wTotalLength));
>  	dev->config.no_of_if = 0;


What's WIP in this patch? It looks 100% correct.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC 7/9] usb: ehci: add big-endian registers support
  2015-08-27 22:24 ` [RFC 7/9] usb: ehci: add big-endian registers support Antony Pavlov
@ 2015-08-28  6:19   ` Sascha Hauer
  2015-08-28 15:49     ` Antony Pavlov
  0 siblings, 1 reply; 25+ messages in thread
From: Sascha Hauer @ 2015-08-28  6:19 UTC (permalink / raw)
  To: Antony Pavlov; +Cc: barebox, Peter Mamonov

On Fri, Aug 28, 2015 at 01:24:08AM +0300, Antony Pavlov wrote:
> +
> +#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
> +#define ehci_big_endian_mmio(e)		((e)->big_endian_mmio)
> +#else
> +#define ehci_big_endian_mmio(e)		0
> +#endif
> +
> +static inline void ehci_writel(const struct ehci_priv *ehci,
> +				__u32 __iomem *regs, const unsigned int val)
>  {
> -	writel(val, regs);
> +	if (IS_ENABLED(CONFIG_USB_EHCI_BIG_ENDIAN_MMIO)) {
> +		ehci_big_endian_mmio(ehci) ?
> +			iowrite32be(val, regs) :
> +			writel(val, regs);
> +	} else
> +		writel(val, regs);
>  }

	if (ehci_big_endian_mmio(ehci))
		iowrite32be(val, regs);
	else
		writel(val, regs);

is enough.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC 3/9] MIPS: add virt_to_phys() and phys_to_virt()
  2015-08-27 22:24 ` [RFC 3/9] MIPS: add virt_to_phys() and phys_to_virt() Antony Pavlov
@ 2015-08-28  6:34   ` Sascha Hauer
  2015-08-28 15:46     ` Antony Pavlov
  0 siblings, 1 reply; 25+ messages in thread
From: Sascha Hauer @ 2015-08-28  6:34 UTC (permalink / raw)
  To: Antony Pavlov; +Cc: barebox, Peter Mamonov

On Fri, Aug 28, 2015 at 01:24:04AM +0300, Antony Pavlov wrote:
> N.B. phys_to_virt() translates phys address
> to KSEG1 (uncached) address as barebox mips
> has no cache support.

What would it take to implement cache support for mips? The u-boot mips
cache code seems quite straight forward. With cache support you could
use several drivers as they are and wouldn't have to introduce
physical/virtual translations. I'm afraid these translations will be
broken quite soon as they get tested only on Mips.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC 3/9] MIPS: add virt_to_phys() and phys_to_virt()
  2015-08-28  6:34   ` Sascha Hauer
@ 2015-08-28 15:46     ` Antony Pavlov
  2015-09-04  6:20       ` Sascha Hauer
  0 siblings, 1 reply; 25+ messages in thread
From: Antony Pavlov @ 2015-08-28 15:46 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox, Peter Mamonov

On Fri, 28 Aug 2015 08:34:32 +0200
Sascha Hauer <s.hauer@pengutronix.de> wrote:

> On Fri, Aug 28, 2015 at 01:24:04AM +0300, Antony Pavlov wrote:
> > N.B. phys_to_virt() translates phys address
> > to KSEG1 (uncached) address as barebox mips
> > has no cache support.
> 
> What would it take to implement cache support for mips?
lack of the cache support is critical problem for current barebox mips support.
I'm planning to add cache support in several weeks.
This task needs much test efforts for different boards.

Anyway I can't carry out cache adding work at one.
But adding virt_to_phys and DMA support will help to add cache support one day anyway.

> The u-boot mips
> cache code seems quite straight forward.

AFAIR u-boot has only mips L1 cache support.
AFAIK Paul Burton works on adding L2 cache support but current mainline
u-boot repo has no such code.

> With cache support you could
> use several drivers as they are and wouldn't have to introduce
> physical/virtual translations. I'm afraid these translations will be
> broken quite soon as they get tested only on Mips.

I hope somebody will test my EHCI patch on ARM :)

-- 
Best regards,
  Antony Pavlov

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC 7/9] usb: ehci: add big-endian registers support
  2015-08-28  6:19   ` Sascha Hauer
@ 2015-08-28 15:49     ` Antony Pavlov
  0 siblings, 0 replies; 25+ messages in thread
From: Antony Pavlov @ 2015-08-28 15:49 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox, Peter Mamonov

On Fri, 28 Aug 2015 08:19:00 +0200
Sascha Hauer <s.hauer@pengutronix.de> wrote:

> On Fri, Aug 28, 2015 at 01:24:08AM +0300, Antony Pavlov wrote:
> > +
> > +#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
> > +#define ehci_big_endian_mmio(e)		((e)->big_endian_mmio)
> > +#else
> > +#define ehci_big_endian_mmio(e)		0
> > +#endif
> > +
> > +static inline void ehci_writel(const struct ehci_priv *ehci,
> > +				__u32 __iomem *regs, const unsigned int val)
> >  {
> > -	writel(val, regs);
> > +	if (IS_ENABLED(CONFIG_USB_EHCI_BIG_ENDIAN_MMIO)) {
> > +		ehci_big_endian_mmio(ehci) ?
> > +			iowrite32be(val, regs) :
> > +			writel(val, regs);
> > +	} else
> > +		writel(val, regs);
> >  }
> 
> 	if (ehci_big_endian_mmio(ehci))
> 		iowrite32be(val, regs);
> 	else
> 		writel(val, regs);
> 
> is enough.

It looks you are right. :)

I have just stealed this code from linux kernel.
I have some suspicions on redundancy of this code but I didn't proposed any good solution. 
Thanks!

-- 
Best regards,
  Antony Pavlov

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC 2/9] WIP: fix drivers/usb/core/usb.c
  2015-08-28  6:11   ` Sascha Hauer
@ 2015-08-28 15:51     ` Antony Pavlov
  2015-08-31  6:45       ` Sascha Hauer
  0 siblings, 1 reply; 25+ messages in thread
From: Antony Pavlov @ 2015-08-28 15:51 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox, Peter Mamonov

On Fri, 28 Aug 2015 08:11:59 +0200
Sascha Hauer <s.hauer@pengutronix.de> wrote:

> On Fri, Aug 28, 2015 at 01:24:03AM +0300, Antony Pavlov wrote:
> > drivers/usb/core/usb.c: In function 'usb_parse_config':
> > drivers/usb/core/usb.c:194:28: error: 'struct usb_configuration' has no
> > member named 'wTotalLength'
> >   le16_to_cpus(&(dev->config.wTotalLength));
> >                             ^
> > ...
> > scripts/Makefile.build:249: recipe for target 'drivers/usb/core/usb.o'
> > failed
> > make[3]: *** [drivers/usb/core/usb.o] Error 1
> > scripts/Makefile.build:387: recipe for target 'drivers/usb/core' failed
> > make[2]: *** [drivers/usb/core] Error 2
> > scripts/Makefile.build:387: recipe for target 'drivers/usb' failed
> > make[1]: *** [drivers/usb] Error 2
> > Makefile:770: recipe for target 'drivers' failed
> > make: *** [drivers] Error 2
> > 
> > see also
> > 
> > commit 245069bcef15ecc19db616a967501349b76c84d0
> > Author: Sascha Hauer <s.hauer@pengutronix.de>
> > Date:   Thu Jul 10 11:36:12 2014 +0200
> > 
> >     USB: introduce usb_interface/usb_configuration structs
> > 
> >     Currently we have two conflicting definitions of struct
> > usb_config_descriptor
> >     and struct usb_interface_descriptor in the tree. This is because the
> > USB code
> >     uses additional fields in the structs for internal housekeeping. Add
> >     struct usb_interface and struct struct usb_configuration with the
> > housekeeping
> >     data and embed the corresponding hardware structs into them. This
> > frees the
> >     way to use the definitions from ch9.h in the next step.
> > 
> > Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
> > ---
> >  drivers/usb/core/usb.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
> > index 9073fff..f8d6014 100644
> > --- a/drivers/usb/core/usb.c
> > +++ b/drivers/usb/core/usb.c
> > @@ -191,7 +191,7 @@ static int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int c
> >  		return -1;
> >  	}
> >  	memcpy(&dev->config, buffer, buffer[0]);
> > -	le16_to_cpus(&(dev->config.wTotalLength));
> > +	le16_to_cpus(&(dev->config.desc.wTotalLength));
> >  	dev->config.no_of_if = 0;
> 
> 
> What's WIP in this patch? It looks 100% correct.

WIP means that I don't understand why nobody but me detected this build problem.
Have you any idea? 

-- 
Best regards,
  Antony Pavlov

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC 2/9] WIP: fix drivers/usb/core/usb.c
  2015-08-28 15:51     ` Antony Pavlov
@ 2015-08-31  6:45       ` Sascha Hauer
  0 siblings, 0 replies; 25+ messages in thread
From: Sascha Hauer @ 2015-08-31  6:45 UTC (permalink / raw)
  To: Antony Pavlov; +Cc: barebox, Peter Mamonov

On Fri, Aug 28, 2015 at 06:51:04PM +0300, Antony Pavlov wrote:
> On Fri, 28 Aug 2015 08:11:59 +0200
> Sascha Hauer <s.hauer@pengutronix.de> wrote:
> 
> > On Fri, Aug 28, 2015 at 01:24:03AM +0300, Antony Pavlov wrote:
> > > drivers/usb/core/usb.c: In function 'usb_parse_config':
> > > drivers/usb/core/usb.c:194:28: error: 'struct usb_configuration' has no
> > > member named 'wTotalLength'
> > >   le16_to_cpus(&(dev->config.wTotalLength));
> > >                             ^
> > > ...
> > > scripts/Makefile.build:249: recipe for target 'drivers/usb/core/usb.o'
> > > failed
> > > make[3]: *** [drivers/usb/core/usb.o] Error 1
> > > scripts/Makefile.build:387: recipe for target 'drivers/usb/core' failed
> > > make[2]: *** [drivers/usb/core] Error 2
> > > scripts/Makefile.build:387: recipe for target 'drivers/usb' failed
> > > make[1]: *** [drivers/usb] Error 2
> > > Makefile:770: recipe for target 'drivers' failed
> > > make: *** [drivers] Error 2
> > > 
> > > see also
> > > 
> > > commit 245069bcef15ecc19db616a967501349b76c84d0
> > > Author: Sascha Hauer <s.hauer@pengutronix.de>
> > > Date:   Thu Jul 10 11:36:12 2014 +0200
> > > 
> > >     USB: introduce usb_interface/usb_configuration structs
> > > 
> > >     Currently we have two conflicting definitions of struct
> > > usb_config_descriptor
> > >     and struct usb_interface_descriptor in the tree. This is because the
> > > USB code
> > >     uses additional fields in the structs for internal housekeeping. Add
> > >     struct usb_interface and struct struct usb_configuration with the
> > > housekeeping
> > >     data and embed the corresponding hardware structs into them. This
> > > frees the
> > >     way to use the definitions from ch9.h in the next step.
> > > 
> > > Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
> > > ---
> > >  drivers/usb/core/usb.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
> > > index 9073fff..f8d6014 100644
> > > --- a/drivers/usb/core/usb.c
> > > +++ b/drivers/usb/core/usb.c
> > > @@ -191,7 +191,7 @@ static int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int c
> > >  		return -1;
> > >  	}
> > >  	memcpy(&dev->config, buffer, buffer[0]);
> > > -	le16_to_cpus(&(dev->config.wTotalLength));
> > > +	le16_to_cpus(&(dev->config.desc.wTotalLength));
> > >  	dev->config.no_of_if = 0;
> > 
> > 
> > What's WIP in this patch? It looks 100% correct.
> 
> WIP means that I don't understand why nobody but me detected this build problem.
> Have you any idea?

Yeah, I wondered about this aswell at first, but it's quite easy if you
look at it. le16_to_cpus converts the content of a pointer to le16 to
cpu endianess.  On little endian systems like ARM this is a no op,
defined as:

#define le16_to_cpus __le16_to_cpus
#define __le16_to_cpus(x) do {} while (0)

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC 3/9] MIPS: add virt_to_phys() and phys_to_virt()
  2015-08-28 15:46     ` Antony Pavlov
@ 2015-09-04  6:20       ` Sascha Hauer
  2015-09-04  7:27         ` Antony Pavlov
  2015-12-06 14:50         ` Antony Pavlov
  0 siblings, 2 replies; 25+ messages in thread
From: Sascha Hauer @ 2015-09-04  6:20 UTC (permalink / raw)
  To: Antony Pavlov; +Cc: barebox, Peter Mamonov

On Fri, Aug 28, 2015 at 06:46:14PM +0300, Antony Pavlov wrote:
> On Fri, 28 Aug 2015 08:34:32 +0200
> Sascha Hauer <s.hauer@pengutronix.de> wrote:
> 
> > On Fri, Aug 28, 2015 at 01:24:04AM +0300, Antony Pavlov wrote:
> > > N.B. phys_to_virt() translates phys address
> > > to KSEG1 (uncached) address as barebox mips
> > > has no cache support.
> > 
> > What would it take to implement cache support for mips?
> lack of the cache support is critical problem for current barebox mips support.
> I'm planning to add cache support in several weeks.
> This task needs much test efforts for different boards.
> 
> Anyway I can't carry out cache adding work at one.
> But adding virt_to_phys and DMA support will help to add cache support one day anyway.

Looking at this again the virt_to_phys/phys_to_virt macros are not
necessary. dma_alloc_coherent() already returns both the virtual address
and the DMA address. It should be possible to replace DMA_ADDRESS_BROKEN
in the ehci driver with a real pointer and use it appropriatly in the
driver.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC 3/9] MIPS: add virt_to_phys() and phys_to_virt()
  2015-09-04  6:20       ` Sascha Hauer
@ 2015-09-04  7:27         ` Antony Pavlov
  2015-09-04  8:44           ` Sascha Hauer
  2015-12-06 14:50         ` Antony Pavlov
  1 sibling, 1 reply; 25+ messages in thread
From: Antony Pavlov @ 2015-09-04  7:27 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox, Peter Mamonov

On Fri, 4 Sep 2015 08:20:48 +0200
Sascha Hauer <s.hauer@pengutronix.de> wrote:

> On Fri, Aug 28, 2015 at 06:46:14PM +0300, Antony Pavlov wrote:
> > On Fri, 28 Aug 2015 08:34:32 +0200
> > Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > 
> > > On Fri, Aug 28, 2015 at 01:24:04AM +0300, Antony Pavlov wrote:
> > > > N.B. phys_to_virt() translates phys address
> > > > to KSEG1 (uncached) address as barebox mips
> > > > has no cache support.
> > > 
> > > What would it take to implement cache support for mips?
> > lack of the cache support is critical problem for current barebox mips support.
> > I'm planning to add cache support in several weeks.
> > This task needs much test efforts for different boards.
> > 
> > Anyway I can't carry out cache adding work at one.
> > But adding virt_to_phys and DMA support will help to add cache support one day anyway.
> 
> Looking at this again the virt_to_phys/phys_to_virt macros are not
> necessary. dma_alloc_coherent() already returns both the virtual address
> and the DMA address. It should be possible to replace DMA_ADDRESS_BROKEN
> in the ehci driver with a real pointer and use it appropriatly in the
> driver.

Here is a fragment of drivers/usb/host/ehci-hcd.c:

    while (td != (void *)QT_NEXT_TERMINATE) {
           qh->qt_next = td->qt_next;
           td = (void *)hc32_to_cpu(qh->qt_next);
    }


qh->qt_next contains physical memory address for EHCI controller,
so after 'td = (void *)hc32_to_cpu(qh->qt_next)' contains physical address.

But latter we can use 'td->qt_next'. If physical address != virtual address
then we will fail. So we need addition phys_to_virt() call here.

Some addition workaround is needed here because phys_to_virt(QT_NEXT_TERMINATE) != QT_NEXT_TERMINATE.


-- 
-- 
Best regards,
  Antony Pavlov

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC 3/9] MIPS: add virt_to_phys() and phys_to_virt()
  2015-09-04  7:27         ` Antony Pavlov
@ 2015-09-04  8:44           ` Sascha Hauer
  0 siblings, 0 replies; 25+ messages in thread
From: Sascha Hauer @ 2015-09-04  8:44 UTC (permalink / raw)
  To: Antony Pavlov; +Cc: barebox, Peter Mamonov

On Fri, Sep 04, 2015 at 10:27:40AM +0300, Antony Pavlov wrote:
> On Fri, 4 Sep 2015 08:20:48 +0200
> Sascha Hauer <s.hauer@pengutronix.de> wrote:
> 
> > On Fri, Aug 28, 2015 at 06:46:14PM +0300, Antony Pavlov wrote:
> > > On Fri, 28 Aug 2015 08:34:32 +0200
> > > Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > > 
> > > > On Fri, Aug 28, 2015 at 01:24:04AM +0300, Antony Pavlov wrote:
> > > > > N.B. phys_to_virt() translates phys address
> > > > > to KSEG1 (uncached) address as barebox mips
> > > > > has no cache support.
> > > > 
> > > > What would it take to implement cache support for mips?
> > > lack of the cache support is critical problem for current barebox mips support.
> > > I'm planning to add cache support in several weeks.
> > > This task needs much test efforts for different boards.
> > > 
> > > Anyway I can't carry out cache adding work at one.
> > > But adding virt_to_phys and DMA support will help to add cache support one day anyway.
> > 
> > Looking at this again the virt_to_phys/phys_to_virt macros are not
> > necessary. dma_alloc_coherent() already returns both the virtual address
> > and the DMA address. It should be possible to replace DMA_ADDRESS_BROKEN
> > in the ehci driver with a real pointer and use it appropriatly in the
> > driver.
> 
> Here is a fragment of drivers/usb/host/ehci-hcd.c:
> 
>     while (td != (void *)QT_NEXT_TERMINATE) {
>            qh->qt_next = td->qt_next;
>            td = (void *)hc32_to_cpu(qh->qt_next);
>     }
> 
> 
> qh->qt_next contains physical memory address for EHCI controller,
> so after 'td = (void *)hc32_to_cpu(qh->qt_next)' contains physical address.
> 
> But latter we can use 'td->qt_next'. If physical address != virtual address
> then we will fail. So we need addition phys_to_virt() call here.

The problem with the ehci driver is that it uses qt_next pointers in the
driver to iterate over the TDs. qt_next is meant for the ehci hardware,
not for the software. What we need is an additional struct qTD *vqt_next
field in both struct qTD and struct QH for software iteration over the
list of TDs.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC 3/9] MIPS: add virt_to_phys() and phys_to_virt()
  2015-09-04  6:20       ` Sascha Hauer
  2015-09-04  7:27         ` Antony Pavlov
@ 2015-12-06 14:50         ` Antony Pavlov
  2015-12-07 10:27           ` Sascha Hauer
  1 sibling, 1 reply; 25+ messages in thread
From: Antony Pavlov @ 2015-12-06 14:50 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox, Peter Mamonov

On Fri, 4 Sep 2015 08:20:48 +0200
Sascha Hauer <s.hauer@pengutronix.de> wrote:

> On Fri, Aug 28, 2015 at 06:46:14PM +0300, Antony Pavlov wrote:
> > On Fri, 28 Aug 2015 08:34:32 +0200
> > Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > 
> > > On Fri, Aug 28, 2015 at 01:24:04AM +0300, Antony Pavlov wrote:
> > > > N.B. phys_to_virt() translates phys address
> > > > to KSEG1 (uncached) address as barebox mips
> > > > has no cache support.
> > > 
> > > What would it take to implement cache support for mips?
> > lack of the cache support is critical problem for current barebox mips support.
> > I'm planning to add cache support in several weeks.
> > This task needs much test efforts for different boards.
> > 
> > Anyway I can't carry out cache adding work at one.
> > But adding virt_to_phys and DMA support will help to add cache support one day anyway.
> 
> Looking at this again the virt_to_phys/phys_to_virt macros are not
> necessary. dma_alloc_coherent() already returns both the virtual address
> and the DMA address. It should be possible to replace DMA_ADDRESS_BROKEN
> in the ehci driver with a real pointer and use it appropriatly in the
> driver.
> 

I have tried to get physical address from dma_alloc_coherent(),
here is a small part of my patch (just for demonstration):

--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -41,6 +41,7 @@ struct ehci_priv {
 	struct ehci_hcor *hcor;
 	struct usb_host host;
 	struct QH *qh_list;
+	dma_addr_t qh_list_dma;
 	struct qTD *td;
 	int portreset;
 	unsigned long flags;
@@ -403,7 +410,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 		goto fail;
 	}
 
-	ehci->qh_list->qh_link = cpu_to_hc32((uint32_t)ehci->qh_list | QH_LINK_TYPE_QH);
+	ehci->qh_list->qh_link = cpu_to_hc32(ehci->qh_list_dma | QH_LINK_TYPE_QH);
 
 	token = hc32_to_cpu(qh->qt_token);
 	if (!(token & 0x80)) {
@@ -1306,7 +1313,7 @@ int ehci_register(struct device_d *dev, struct ehci_data *data)
 	ehci->post_init = data->post_init;
 
 	ehci->qh_list = dma_alloc_coherent(sizeof(struct QH) * NUM_TD,
-					   DMA_ADDRESS_BROKEN);
+					   &ehci->qh_list_dma);
 	ehci->periodic_queue = dma_alloc_coherent(sizeof(struct QH),
 						  DMA_ADDRESS_BROKEN);
 	ehci->td = dma_alloc_coherent(sizeof(struct qTD) * NUM_TD,


However ehci_td_buffer() gets buf pointer outside of ehci driver (e.g. via usb_bulk_msg()),
so it is difficult to avoid virt_to_phys() in ehci_td_buffer(), e.g.:

@@ -195,7 +197,7 @@ static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz)
 
        idx = 0;
        while (idx < 5) {
-               td->qt_buffer[idx] = cpu_to_hc32(addr);
+               td->qt_buffer[idx] = cpu_to_hc32(virt_to_phys(addr));
                next = (addr + 4096) & ~4095;
                delta = next - addr;
                if (delta >= sz)

Have you any idea?

-- 
Best regards,
  Antony Pavlov

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC 3/9] MIPS: add virt_to_phys() and phys_to_virt()
  2015-12-06 14:50         ` Antony Pavlov
@ 2015-12-07 10:27           ` Sascha Hauer
  2015-12-08  9:11             ` Antony Pavlov
  2015-12-08 11:46             ` Peter Mamonov
  0 siblings, 2 replies; 25+ messages in thread
From: Sascha Hauer @ 2015-12-07 10:27 UTC (permalink / raw)
  To: Antony Pavlov; +Cc: barebox, Peter Mamonov

On Sun, Dec 06, 2015 at 05:50:51PM +0300, Antony Pavlov wrote:
> On Fri, 4 Sep 2015 08:20:48 +0200
> Sascha Hauer <s.hauer@pengutronix.de> wrote:
> 
> > On Fri, Aug 28, 2015 at 06:46:14PM +0300, Antony Pavlov wrote:
> > > On Fri, 28 Aug 2015 08:34:32 +0200
> > > Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > > 
> > > > On Fri, Aug 28, 2015 at 01:24:04AM +0300, Antony Pavlov wrote:
> > > > > N.B. phys_to_virt() translates phys address
> > > > > to KSEG1 (uncached) address as barebox mips
> > > > > has no cache support.
> > > > 
> > > > What would it take to implement cache support for mips?
> > > lack of the cache support is critical problem for current barebox mips support.
> > > I'm planning to add cache support in several weeks.
> > > This task needs much test efforts for different boards.
> > > 
> > > Anyway I can't carry out cache adding work at one.
> > > But adding virt_to_phys and DMA support will help to add cache support one day anyway.
> > 
> > Looking at this again the virt_to_phys/phys_to_virt macros are not
> > necessary. dma_alloc_coherent() already returns both the virtual address
> > and the DMA address. It should be possible to replace DMA_ADDRESS_BROKEN
> > in the ehci driver with a real pointer and use it appropriatly in the
> > driver.
> > 
> 
> I have tried to get physical address from dma_alloc_coherent(),
> here is a small part of my patch (just for demonstration):
> 
> --- a/drivers/usb/host/ehci-hcd.c
> +++ b/drivers/usb/host/ehci-hcd.c
> @@ -41,6 +41,7 @@ struct ehci_priv {
>  	struct ehci_hcor *hcor;
>  	struct usb_host host;
>  	struct QH *qh_list;
> +	dma_addr_t qh_list_dma;
>  	struct qTD *td;
>  	int portreset;
>  	unsigned long flags;
> @@ -403,7 +410,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
>  		goto fail;
>  	}
>  
> -	ehci->qh_list->qh_link = cpu_to_hc32((uint32_t)ehci->qh_list | QH_LINK_TYPE_QH);
> +	ehci->qh_list->qh_link = cpu_to_hc32(ehci->qh_list_dma | QH_LINK_TYPE_QH);
>  
>  	token = hc32_to_cpu(qh->qt_token);
>  	if (!(token & 0x80)) {
> @@ -1306,7 +1313,7 @@ int ehci_register(struct device_d *dev, struct ehci_data *data)
>  	ehci->post_init = data->post_init;
>  
>  	ehci->qh_list = dma_alloc_coherent(sizeof(struct QH) * NUM_TD,
> -					   DMA_ADDRESS_BROKEN);
> +					   &ehci->qh_list_dma);
>  	ehci->periodic_queue = dma_alloc_coherent(sizeof(struct QH),
>  						  DMA_ADDRESS_BROKEN);
>  	ehci->td = dma_alloc_coherent(sizeof(struct qTD) * NUM_TD,
> 
> 
> However ehci_td_buffer() gets buf pointer outside of ehci driver (e.g. via usb_bulk_msg()),
> so it is difficult to avoid virt_to_phys() in ehci_td_buffer(), e.g.:
> 
> @@ -195,7 +197,7 @@ static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz)
>  
>         idx = 0;
>         while (idx < 5) {
> -               td->qt_buffer[idx] = cpu_to_hc32(addr);
> +               td->qt_buffer[idx] = cpu_to_hc32(virt_to_phys(addr));
>                 next = (addr + 4096) & ~4095;
>                 delta = next - addr;
>                 if (delta >= sz)
> 
> Have you any idea?

No. Translating this addres into a physical address seems unavoidable
here. I would still prefer a real cache implementation for MIPS though.
Have you looked further into that? The current MIPS cached/uncached
memory windows seem to be a constant source of problems we could avoid.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC 3/9] MIPS: add virt_to_phys() and phys_to_virt()
  2015-12-07 10:27           ` Sascha Hauer
@ 2015-12-08  9:11             ` Antony Pavlov
  2015-12-08 11:46             ` Peter Mamonov
  1 sibling, 0 replies; 25+ messages in thread
From: Antony Pavlov @ 2015-12-08  9:11 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox, Peter Mamonov

On Mon, 7 Dec 2015 11:27:44 +0100
Sascha Hauer <s.hauer@pengutronix.de> wrote:

> On Sun, Dec 06, 2015 at 05:50:51PM +0300, Antony Pavlov wrote:
> > On Fri, 4 Sep 2015 08:20:48 +0200
> > Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > 
> > > On Fri, Aug 28, 2015 at 06:46:14PM +0300, Antony Pavlov wrote:
> > > > On Fri, 28 Aug 2015 08:34:32 +0200
> > > > Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > > > 
> > > > > On Fri, Aug 28, 2015 at 01:24:04AM +0300, Antony Pavlov wrote:
> > > > > > N.B. phys_to_virt() translates phys address
> > > > > > to KSEG1 (uncached) address as barebox mips
> > > > > > has no cache support.
> > > > > 
> > > > > What would it take to implement cache support for mips?
> > > > lack of the cache support is critical problem for current barebox mips support.
> > > > I'm planning to add cache support in several weeks.
> > > > This task needs much test efforts for different boards.
> > > > 
> > > > Anyway I can't carry out cache adding work at one.
> > > > But adding virt_to_phys and DMA support will help to add cache support one day anyway.
> > > 
> > > Looking at this again the virt_to_phys/phys_to_virt macros are not
> > > necessary. dma_alloc_coherent() already returns both the virtual address
> > > and the DMA address. It should be possible to replace DMA_ADDRESS_BROKEN
> > > in the ehci driver with a real pointer and use it appropriatly in the
> > > driver.
> > > 
> > 
> > I have tried to get physical address from dma_alloc_coherent(),
> > here is a small part of my patch (just for demonstration):
> > 
> > --- a/drivers/usb/host/ehci-hcd.c
> > +++ b/drivers/usb/host/ehci-hcd.c
> > @@ -41,6 +41,7 @@ struct ehci_priv {
> >  	struct ehci_hcor *hcor;
> >  	struct usb_host host;
> >  	struct QH *qh_list;
> > +	dma_addr_t qh_list_dma;
> >  	struct qTD *td;
> >  	int portreset;
> >  	unsigned long flags;
> > @@ -403,7 +410,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
> >  		goto fail;
> >  	}
> >  
> > -	ehci->qh_list->qh_link = cpu_to_hc32((uint32_t)ehci->qh_list | QH_LINK_TYPE_QH);
> > +	ehci->qh_list->qh_link = cpu_to_hc32(ehci->qh_list_dma | QH_LINK_TYPE_QH);
> >  
> >  	token = hc32_to_cpu(qh->qt_token);
> >  	if (!(token & 0x80)) {
> > @@ -1306,7 +1313,7 @@ int ehci_register(struct device_d *dev, struct ehci_data *data)
> >  	ehci->post_init = data->post_init;
> >  
> >  	ehci->qh_list = dma_alloc_coherent(sizeof(struct QH) * NUM_TD,
> > -					   DMA_ADDRESS_BROKEN);
> > +					   &ehci->qh_list_dma);
> >  	ehci->periodic_queue = dma_alloc_coherent(sizeof(struct QH),
> >  						  DMA_ADDRESS_BROKEN);
> >  	ehci->td = dma_alloc_coherent(sizeof(struct qTD) * NUM_TD,
> > 
> > 
> > However ehci_td_buffer() gets buf pointer outside of ehci driver (e.g. via usb_bulk_msg()),
> > so it is difficult to avoid virt_to_phys() in ehci_td_buffer(), e.g.:
> > 
> > @@ -195,7 +197,7 @@ static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz)
> >  
> >         idx = 0;
> >         while (idx < 5) {
> > -               td->qt_buffer[idx] = cpu_to_hc32(addr);
> > +               td->qt_buffer[idx] = cpu_to_hc32(virt_to_phys(addr));
> >                 next = (addr + 4096) & ~4095;
> >                 delta = next - addr;
> >                 if (delta >= sz)
> > 
> > Have you any idea?
> 
> No. Translating this addres into a physical address seems unavoidable
> here. I would still prefer a real cache implementation for MIPS though.
> Have you looked further into that? The current MIPS cached/uncached
> memory windows seem to be a constant source of problems we could avoid.

We already have Atheros AR9331 branch with cache support.
I assume that cleaned MIPS cache support patch series will be ready till Christmas.

-- 
Best regards,
  Antony Pavlov

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC 3/9] MIPS: add virt_to_phys() and phys_to_virt()
  2015-12-07 10:27           ` Sascha Hauer
  2015-12-08  9:11             ` Antony Pavlov
@ 2015-12-08 11:46             ` Peter Mamonov
  2015-12-09 13:03               ` Sascha Hauer
  1 sibling, 1 reply; 25+ messages in thread
From: Peter Mamonov @ 2015-12-08 11:46 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox

On Mon, 7 Dec 2015 11:27:44 +0100
Sascha Hauer <s.hauer@pengutronix.de> wrote:

> On Sun, Dec 06, 2015 at 05:50:51PM +0300, Antony Pavlov wrote:
> > On Fri, 4 Sep 2015 08:20:48 +0200
> > Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > 
> > > On Fri, Aug 28, 2015 at 06:46:14PM +0300, Antony Pavlov wrote:
> > > > On Fri, 28 Aug 2015 08:34:32 +0200
> > > > Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > > > 
> > > > > On Fri, Aug 28, 2015 at 01:24:04AM +0300, Antony Pavlov wrote:
> > > > > > N.B. phys_to_virt() translates phys address
> > > > > > to KSEG1 (uncached) address as barebox mips
> > > > > > has no cache support.
> > > > > 
> > > > > What would it take to implement cache support for mips?
> > > > lack of the cache support is critical problem for current
> > > > barebox mips support. I'm planning to add cache support in
> > > > several weeks. This task needs much test efforts for different
> > > > boards.
> > > > 
> > > > Anyway I can't carry out cache adding work at one.
> > > > But adding virt_to_phys and DMA support will help to add cache
> > > > support one day anyway.
> > > 
> > > Looking at this again the virt_to_phys/phys_to_virt macros are not
> > > necessary. dma_alloc_coherent() already returns both the virtual
> > > address and the DMA address. It should be possible to replace
> > > DMA_ADDRESS_BROKEN in the ehci driver with a real pointer and use
> > > it appropriatly in the driver.
> > > 
> > 
> > I have tried to get physical address from dma_alloc_coherent(),
> > here is a small part of my patch (just for demonstration):
> > 
> > --- a/drivers/usb/host/ehci-hcd.c
> > +++ b/drivers/usb/host/ehci-hcd.c
> > @@ -41,6 +41,7 @@ struct ehci_priv {
> >  	struct ehci_hcor *hcor;
> >  	struct usb_host host;
> >  	struct QH *qh_list;
> > +	dma_addr_t qh_list_dma;
> >  	struct qTD *td;
> >  	int portreset;
> >  	unsigned long flags;
> > @@ -403,7 +410,7 @@ ehci_submit_async(struct usb_device *dev,
> > unsigned long pipe, void *buffer, goto fail;
> >  	}
> >  
> > -	ehci->qh_list->qh_link =
> > cpu_to_hc32((uint32_t)ehci->qh_list | QH_LINK_TYPE_QH);
> > +	ehci->qh_list->qh_link = cpu_to_hc32(ehci->qh_list_dma |
> > QH_LINK_TYPE_QH); 
> >  	token = hc32_to_cpu(qh->qt_token);
> >  	if (!(token & 0x80)) {
> > @@ -1306,7 +1313,7 @@ int ehci_register(struct device_d *dev,
> > struct ehci_data *data) ehci->post_init = data->post_init;
> >  
> >  	ehci->qh_list = dma_alloc_coherent(sizeof(struct QH) *
> > NUM_TD,
> > -					   DMA_ADDRESS_BROKEN);
> > +					   &ehci->qh_list_dma);
> >  	ehci->periodic_queue = dma_alloc_coherent(sizeof(struct
> > QH), DMA_ADDRESS_BROKEN);
> >  	ehci->td = dma_alloc_coherent(sizeof(struct qTD) * NUM_TD,
> > 
> > 
> > However ehci_td_buffer() gets buf pointer outside of ehci driver
> > (e.g. via usb_bulk_msg()), so it is difficult to avoid
> > virt_to_phys() in ehci_td_buffer(), e.g.:
> > 
> > @@ -195,7 +197,7 @@ static int ehci_td_buffer(struct qTD *td, void
> > *buf, size_t sz) 
> >         idx = 0;
> >         while (idx < 5) {
> > -               td->qt_buffer[idx] = cpu_to_hc32(addr);
> > +               td->qt_buffer[idx] =
> > cpu_to_hc32(virt_to_phys(addr)); next = (addr + 4096) & ~4095;
> >                 delta = next - addr;
> >                 if (delta >= sz)
> > 
> > Have you any idea?
> 
> No. Translating this addres into a physical address seems unavoidable
> here. 

The other solution is to allocate private buffer using
dma_alloc_coherent(), use the returned dma address to fill the qt_buffer
field, copy data from the supplied buffer to the private buffer before
the transaction and copy back after the transaction is done.

> I would still prefer a real cache implementation for MIPS
> though. Have you looked further into that? The current MIPS
> cached/uncached memory windows seem to be a constant source of
> problems we could avoid.
> 
> Sascha
> 
> 


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC 3/9] MIPS: add virt_to_phys() and phys_to_virt()
  2015-12-08 11:46             ` Peter Mamonov
@ 2015-12-09 13:03               ` Sascha Hauer
  0 siblings, 0 replies; 25+ messages in thread
From: Sascha Hauer @ 2015-12-09 13:03 UTC (permalink / raw)
  To: Peter Mamonov; +Cc: barebox

On Tue, Dec 08, 2015 at 02:46:37PM +0300, Peter Mamonov wrote:
> On Mon, 7 Dec 2015 11:27:44 +0100
> Sascha Hauer <s.hauer@pengutronix.de> wrote:
> 
> > On Sun, Dec 06, 2015 at 05:50:51PM +0300, Antony Pavlov wrote:
> > > On Fri, 4 Sep 2015 08:20:48 +0200
> > > Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > > 
> > > > On Fri, Aug 28, 2015 at 06:46:14PM +0300, Antony Pavlov wrote:
> > > > > On Fri, 28 Aug 2015 08:34:32 +0200
> > > > > Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > > > > 
> > > > > > On Fri, Aug 28, 2015 at 01:24:04AM +0300, Antony Pavlov wrote:
> > > > > > > N.B. phys_to_virt() translates phys address
> > > > > > > to KSEG1 (uncached) address as barebox mips
> > > > > > > has no cache support.
> > > > > > 
> > > > > > What would it take to implement cache support for mips?
> > > > > lack of the cache support is critical problem for current
> > > > > barebox mips support. I'm planning to add cache support in
> > > > > several weeks. This task needs much test efforts for different
> > > > > boards.
> > > > > 
> > > > > Anyway I can't carry out cache adding work at one.
> > > > > But adding virt_to_phys and DMA support will help to add cache
> > > > > support one day anyway.
> > > > 
> > > > Looking at this again the virt_to_phys/phys_to_virt macros are not
> > > > necessary. dma_alloc_coherent() already returns both the virtual
> > > > address and the DMA address. It should be possible to replace
> > > > DMA_ADDRESS_BROKEN in the ehci driver with a real pointer and use
> > > > it appropriatly in the driver.
> > > > 
> > > 
> > > I have tried to get physical address from dma_alloc_coherent(),
> > > here is a small part of my patch (just for demonstration):
> > > 
> > > --- a/drivers/usb/host/ehci-hcd.c
> > > +++ b/drivers/usb/host/ehci-hcd.c
> > > @@ -41,6 +41,7 @@ struct ehci_priv {
> > >  	struct ehci_hcor *hcor;
> > >  	struct usb_host host;
> > >  	struct QH *qh_list;
> > > +	dma_addr_t qh_list_dma;
> > >  	struct qTD *td;
> > >  	int portreset;
> > >  	unsigned long flags;
> > > @@ -403,7 +410,7 @@ ehci_submit_async(struct usb_device *dev,
> > > unsigned long pipe, void *buffer, goto fail;
> > >  	}
> > >  
> > > -	ehci->qh_list->qh_link =
> > > cpu_to_hc32((uint32_t)ehci->qh_list | QH_LINK_TYPE_QH);
> > > +	ehci->qh_list->qh_link = cpu_to_hc32(ehci->qh_list_dma |
> > > QH_LINK_TYPE_QH); 
> > >  	token = hc32_to_cpu(qh->qt_token);
> > >  	if (!(token & 0x80)) {
> > > @@ -1306,7 +1313,7 @@ int ehci_register(struct device_d *dev,
> > > struct ehci_data *data) ehci->post_init = data->post_init;
> > >  
> > >  	ehci->qh_list = dma_alloc_coherent(sizeof(struct QH) *
> > > NUM_TD,
> > > -					   DMA_ADDRESS_BROKEN);
> > > +					   &ehci->qh_list_dma);
> > >  	ehci->periodic_queue = dma_alloc_coherent(sizeof(struct
> > > QH), DMA_ADDRESS_BROKEN);
> > >  	ehci->td = dma_alloc_coherent(sizeof(struct qTD) * NUM_TD,
> > > 
> > > 
> > > However ehci_td_buffer() gets buf pointer outside of ehci driver
> > > (e.g. via usb_bulk_msg()), so it is difficult to avoid
> > > virt_to_phys() in ehci_td_buffer(), e.g.:
> > > 
> > > @@ -195,7 +197,7 @@ static int ehci_td_buffer(struct qTD *td, void
> > > *buf, size_t sz) 
> > >         idx = 0;
> > >         while (idx < 5) {
> > > -               td->qt_buffer[idx] = cpu_to_hc32(addr);
> > > +               td->qt_buffer[idx] =
> > > cpu_to_hc32(virt_to_phys(addr)); next = (addr + 4096) & ~4095;
> > >                 delta = next - addr;
> > >                 if (delta >= sz)
> > > 
> > > Have you any idea?
> > 
> > No. Translating this addres into a physical address seems unavoidable
> > here. 
> 
> The other solution is to allocate private buffer using
> dma_alloc_coherent(), use the returned dma address to fill the qt_buffer
> field, copy data from the supplied buffer to the private buffer before
> the transaction and copy back after the transaction is done.

Yes, that would work aswell, but would is neither nice nor efficient.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2015-12-09 13:03 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-27 22:24 [RFC 0/9] ehci-hcd.c: make it works on big-endian mips (AR9331) Antony Pavlov
2015-08-27 22:24 ` [RFC 1/9] WIP: make ehci-hcd.c happy on big-endian MIPS Antony Pavlov
2015-08-27 22:24 ` [RFC 2/9] WIP: fix drivers/usb/core/usb.c Antony Pavlov
2015-08-28  6:11   ` Sascha Hauer
2015-08-28 15:51     ` Antony Pavlov
2015-08-31  6:45       ` Sascha Hauer
2015-08-27 22:24 ` [RFC 3/9] MIPS: add virt_to_phys() and phys_to_virt() Antony Pavlov
2015-08-28  6:34   ` Sascha Hauer
2015-08-28 15:46     ` Antony Pavlov
2015-09-04  6:20       ` Sascha Hauer
2015-09-04  7:27         ` Antony Pavlov
2015-09-04  8:44           ` Sascha Hauer
2015-12-06 14:50         ` Antony Pavlov
2015-12-07 10:27           ` Sascha Hauer
2015-12-08  9:11             ` Antony Pavlov
2015-12-08 11:46             ` Peter Mamonov
2015-12-09 13:03               ` Sascha Hauer
2015-08-27 22:24 ` [RFC 4/9] MIPS: add trivial dma support Antony Pavlov
2015-08-27 22:24 ` [RFC 5/9] ehci-hcd.c: make it works on mips Antony Pavlov
2015-08-27 22:24 ` [RFC 6/9] usb: ehci: drop unusable CONFIG_EHCI_MMIO_BIG_ENDIAN condition Antony Pavlov
2015-08-27 22:24 ` [RFC 7/9] usb: ehci: add big-endian registers support Antony Pavlov
2015-08-28  6:19   ` Sascha Hauer
2015-08-28 15:49     ` Antony Pavlov
2015-08-27 22:24 ` [RFC 8/9] MIPS: tplink-mr3020: select big-endian EHCI support Antony Pavlov
2015-08-27 22:24 ` [RFC 9/9] MIPS: tplink-mr3020_defconfig: enable usb stuff Antony Pavlov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox