Index: head/sys/arm/conf/ARMADA38X =================================================================== --- head/sys/arm/conf/ARMADA38X +++ head/sys/arm/conf/ARMADA38X @@ -71,6 +71,7 @@ # USB device usb device ehci +device xhci device umass device scbus device pass Index: head/sys/arm/mv/files.mv =================================================================== --- head/sys/arm/mv/files.mv +++ head/sys/arm/mv/files.mv @@ -27,5 +27,6 @@ dev/mvs/mvs_soc.c optional mvs dev/uart/uart_dev_ns8250.c optional uart dev/usb/controller/ehci_mv.c optional ehci +dev/usb/controller/xhci_mv.c optional xhci kern/kern_clocksource.c standard Index: head/sys/arm/mv/mv_common.c =================================================================== --- head/sys/arm/mv/mv_common.c +++ head/sys/arm/mv/mv_common.c @@ -79,6 +79,7 @@ static int decode_win_cpu_valid(void); #endif static int decode_win_usb_valid(void); +static int decode_win_usb3_valid(void); static int decode_win_eth_valid(void); static int decode_win_pcie_valid(void); static int decode_win_sata_valid(void); @@ -93,6 +94,7 @@ static int decode_win_sdram_fixup(void); #endif static void decode_win_usb_setup(u_long); +static void decode_win_usb3_setup(u_long); static void decode_win_eth_setup(u_long); static void decode_win_sata_setup(u_long); @@ -100,6 +102,7 @@ static void decode_win_xor_setup(u_long); static void decode_win_usb_dump(u_long); +static void decode_win_usb3_dump(u_long); static void decode_win_eth_dump(u_long base); static void decode_win_idma_dump(u_long base); static void decode_win_xor_dump(u_long base); @@ -134,6 +137,7 @@ static struct soc_node_spec soc_nodes[] = { { "mrvl,ge", &decode_win_eth_setup, &decode_win_eth_dump }, { "mrvl,usb-ehci", &decode_win_usb_setup, &decode_win_usb_dump }, + { "marvell,armada-380-xhci", &decode_win_usb3_setup, &decode_win_usb3_dump }, { "mrvl,sata", &decode_win_sata_setup, NULL }, { "mrvl,xor", &decode_win_xor_setup, &decode_win_xor_dump }, { "mrvl,idma", &decode_win_idma_setup, &decode_win_idma_dump }, @@ -559,7 +563,7 @@ if (!decode_win_cpu_valid() || !decode_win_usb_valid() || !decode_win_eth_valid() || !decode_win_idma_valid() || !decode_win_pcie_valid() || !decode_win_sata_valid() || - !decode_win_xor_valid()) + !decode_win_xor_valid() || !decode_win_usb3_valid()) return (EINVAL); decode_win_cpu_setup(); @@ -567,7 +571,7 @@ if (!decode_win_usb_valid() || !decode_win_eth_valid() || !decode_win_idma_valid() || !decode_win_pcie_valid() || !decode_win_sata_valid() || - !decode_win_xor_valid()) + !decode_win_xor_valid() || !decode_win_usb3_valid()) return (EINVAL); #endif if (MV_DUMP_WIN) @@ -600,6 +604,13 @@ WIN_REG_BASE_IDX_WR(win_usb, cr, MV_WIN_USB_CTRL) WIN_REG_BASE_IDX_WR(win_usb, br, MV_WIN_USB_BASE) +#ifdef SOC_MV_ARMADA38X +WIN_REG_BASE_IDX_RD(win_usb3, cr, MV_WIN_USB3_CTRL) +WIN_REG_BASE_IDX_RD(win_usb3, br, MV_WIN_USB3_BASE) +WIN_REG_BASE_IDX_WR(win_usb3, cr, MV_WIN_USB3_CTRL) +WIN_REG_BASE_IDX_WR(win_usb3, br, MV_WIN_USB3_BASE) +#endif + WIN_REG_BASE_IDX_RD(win_eth, br, MV_WIN_ETH_BASE) WIN_REG_BASE_IDX_RD(win_eth, sz, MV_WIN_ETH_SIZE) WIN_REG_BASE_IDX_RD(win_eth, har, MV_WIN_ETH_REMAP) @@ -1118,6 +1129,85 @@ } /************************************************************************** + * USB3 windows routines + **************************************************************************/ +#ifdef SOC_MV_ARMADA38X +static int +decode_win_usb3_valid(void) +{ + + return (decode_win_can_cover_ddr(MV_WIN_USB3_MAX)); +} + +static void +decode_win_usb3_dump(u_long base) +{ + int i; + + for (i = 0; i < MV_WIN_USB3_MAX; i++) + printf("USB3.0 window#%d: c 0x%08x, b 0x%08x\n", i, + win_usb3_cr_read(base, i), win_usb3_br_read(base, i)); +} + +/* + * Set USB3 decode windows + */ +static void +decode_win_usb3_setup(u_long base) +{ + uint32_t br, cr; + int i, j; + + for (i = 0; i < MV_WIN_USB3_MAX; i++) { + win_usb3_cr_write(base, i, 0); + win_usb3_br_write(base, i, 0); + } + + /* Only access to active DRAM banks is required */ + for (i = 0; i < MV_WIN_DDR_MAX; i++) { + if (ddr_is_active(i)) { + br = ddr_base(i); + cr = (((ddr_size(i) - 1) & + (IO_WIN_SIZE_MASK << IO_WIN_SIZE_SHIFT)) | + (ddr_attr(i) << IO_WIN_ATTR_SHIFT) | + (ddr_target(i) << IO_WIN_TGT_SHIFT) | + IO_WIN_ENA_MASK); + + /* Set the first free USB3.0 window */ + for (j = 0; j < MV_WIN_USB3_MAX; j++) { + if (win_usb3_cr_read(base, j) & IO_WIN_ENA_MASK) + continue; + + win_usb3_br_write(base, j, br); + win_usb3_cr_write(base, j, cr); + break; + } + } + } +} +#else +/* + * Provide dummy functions to satisfy the build + * for SoCs not equipped with USB3 + */ +static int +decode_win_usb3_valid(void) +{ + + return (1); +} + +static void +decode_win_usb3_setup(u_long base) +{ +} + +static void +decode_win_usb3_dump(u_long base) +{ +} +#endif +/************************************************************************** * ETH windows routines **************************************************************************/ @@ -2077,6 +2167,17 @@ return (ENXIO); child = OF_child(node); } + /* + * Next, move one more level down to internal-regs node (if + * it is present) and its children. This node also have + * "simple-bus" compatible. + */ + if ((child == 0) && (node == OF_finddevice("simple-bus"))) { + node = fdt_find_compatible(node, "simple-bus", 0); + if (node == 0) + return (0); + child = OF_child(node); + } } return (0); Index: head/sys/arm/mv/mvwin.h =================================================================== --- head/sys/arm/mv/mvwin.h +++ head/sys/arm/mv/mvwin.h @@ -242,6 +242,10 @@ #define MV_WIN_USB_BASE(n) (0x10 * (n) + 0x324) #define MV_WIN_USB_MAX 4 +#define MV_WIN_USB3_CTRL(n) (0x8 * (n)) +#define MV_WIN_USB3_BASE(n) (0x8 * (n) + 0x4) +#define MV_WIN_USB3_MAX 8 + #define MV_WIN_ETH_BASE(n) (0x8 * (n) + 0x200) #define MV_WIN_ETH_SIZE(n) (0x8 * (n) + 0x204) #define MV_WIN_ETH_REMAP(n) (0x4 * (n) + 0x280)