Index: uspace/drv/infrastructure/rootamdm37x/rootamdm37x.c
===================================================================
--- uspace/drv/infrastructure/rootamdm37x/rootamdm37x.c	(revision 712a10b0c43fb640bc561b97efe87b1ca4b0fb0f)
+++ uspace/drv/infrastructure/rootamdm37x/rootamdm37x.c	(revision fb8dcb4f762a0caef5c61ef0af0a62df56143c7d)
@@ -43,8 +43,11 @@
 #include <ddi.h>
 
+#include "uhh.h"
+#include "usbtll.h"
+
 #define NAME  "rootamdm37x"
 
 /** Obtain function soft-state from DDF function node */
-#define ROOTMAC_FUN(fnode) \
+#define ROOTARM_FUN(fnode) \
 	((rootamdm37x_fun_t *) (fnode)->driver_data)
 
@@ -53,4 +56,9 @@
 } rootamdm37x_fun_t;
 
+#define OHCI_BASE_ADDRESS  0x48064400
+#define OHCI_SIZE  1024
+#define EHCI_BASE_ADDRESS  0x48064800
+#define EHCI_SIZE  1024
+
 static hw_resource_t ohci_res[] = {
 	{
@@ -58,6 +66,6 @@
 		/* See amdm37x TRM page. 3316 for these values */
 		.res.io_range = {
-			.address = 0x48064400,
-			.size = 1024,
+			.address = OHCI_BASE_ADDRESS,
+			.size = OHCI_SIZE,
 			.endianness = LITTLE_ENDIAN
 		},
@@ -66,20 +74,4 @@
 		.type = INTERRUPT,
 		.res.interrupt = { .irq = 76 },
-	},
-};
-
-static hw_resource_t ehci_res[] = {
-	{
-		.type = MEM_RANGE,
-		/* See amdm37x TRM page. 3316 for these values */
-		.res.io_range = {
-			.address = 0x48064800,
-			.size = 1024,
-			.endianness = LITTLE_ENDIAN
-		},
-	},
-	{
-		.type = INTERRUPT,
-		.res.interrupt = { .irq = 77 },
 	},
 };
@@ -92,4 +84,20 @@
 };
 
+static hw_resource_t ehci_res[] = {
+	{
+		.type = MEM_RANGE,
+		/* See amdm37x TRM page. 3316 for these values */
+		.res.io_range = {
+			.address = EHCI_BASE_ADDRESS,
+			.size = EHCI_SIZE,
+			.endianness = LITTLE_ENDIAN
+		},
+	},
+	{
+		.type = INTERRUPT,
+		.res.interrupt = { .irq = 77 },
+	},
+};
+
 static const rootamdm37x_fun_t ehci = {
 	.hw_resources = {
@@ -99,6 +107,58 @@
 };
 
-
-static ddf_dev_ops_t rootamdm37x_fun_ops;
+static hw_resource_list_t *rootamdm37x_get_resources(ddf_fun_t *fnode);
+static bool rootamdm37x_enable_interrupt(ddf_fun_t *fun);
+
+static hw_res_ops_t fun_hw_res_ops = {
+	.get_resource_list = &rootamdm37x_get_resources,
+	.enable_interrupt = &rootamdm37x_enable_interrupt,
+};
+
+static ddf_dev_ops_t rootamdm37x_fun_ops =
+{
+	.interfaces[HW_RES_DEV_IFACE] = &fun_hw_res_ops
+};
+
+static int usb_clocks(bool on)
+{
+	uint32_t *usb_host_cm = NULL;
+	uint32_t *l4_core_cm = NULL;
+
+	int ret = pio_enable((void*)0x48005400, 8192, (void**)&usb_host_cm);
+	if (ret != EOK)
+		return ret;
+
+	ret = pio_enable((void*)0x48004a00, 8192, (void**)&l4_core_cm);
+	if (ret != EOK)
+		return ret;
+
+	assert(l4_core_cm);
+	assert(usb_host_cm);
+	if (on) {
+		l4_core_cm[0xe] |= 0x4;  /* iclk */
+		l4_core_cm[0x3] |= 0x4;  /* fclk */
+
+		/* offset 0x10 (0x4 int32)[0] enables fclk,
+		 * offset 0x00 (0x0 int32)[0 and 1] enables iclk,
+		 * offset 0x30 (0xc int32)[0] enables autoidle
+		 */
+		usb_host_cm[0x4] = 0x1;
+		usb_host_cm[0x0] = 0x3;
+		usb_host_cm[0xc] = 0x1;
+	} else {
+		usb_host_cm[0xc] = 0;
+		usb_host_cm[0x0] = 0;
+		usb_host_cm[0x4] = 0;
+		l4_core_cm[0xe] &= ~0x4;
+		l4_core_cm[0x3] &= ~0x4;
+	}
+
+	return ret;
+}
+
+static int usb_tll_init()
+{
+	return EOK;
+}
 
 static bool rootamdm37x_add_fun(ddf_dev_t *dev, const char *name,
@@ -151,5 +211,5 @@
 }
 
-/** Get the root device.
+/** Add the root device.
  *
  * @param dev Device which is root of the whole device tree
@@ -161,17 +221,15 @@
 static int rootamdm37x_dev_add(ddf_dev_t *dev)
 {
-	{
-	/* Enable USB host clocks */
-	uint32_t *reg = NULL;
-	const int ret = pio_enable((void*)0x48005400, 8192, (void**)&reg);
-	assert(ret == EOK);
-	assert(reg);
-	/* offset 0x10 (0x4 int32)[0] enables fclk,
-	 * offset 0x00 (0x0 int32)[0 and 1] enables iclk,
-	 * offset 0x30 (0xc int32)[0] enables autoidle
-	 */
-	reg[0x4] = 0x1;
-	reg[0x0] = 0x3;
-	reg[0xc] = 0x1;
+	int ret = usb_clocks(true);
+	if (ret != EOK) {
+		ddf_msg(LVL_FATAL, "Failed to enable USB HC clocks!.\n");
+		return ret;
+	}
+
+	ret = usb_tll_init();
+	if (ret != EOK) {
+		ddf_msg(LVL_FATAL, "Failed to init USB TLL!.\n");
+		usb_clocks(false);
+		return ret;
 	}
 
@@ -200,7 +258,6 @@
 static hw_resource_list_t *rootamdm37x_get_resources(ddf_fun_t *fnode)
 {
-	rootamdm37x_fun_t *fun = ROOTMAC_FUN(fnode);
+	rootamdm37x_fun_t *fun = ROOTARM_FUN(fnode);
 	assert(fun != NULL);
-	
 	return &fun->hw_resources;
 }
@@ -209,12 +266,6 @@
 {
 	/* TODO */
-	
 	return false;
 }
-
-static hw_res_ops_t fun_hw_res_ops = {
-   	.get_resource_list = &rootamdm37x_get_resources,
-	.enable_interrupt = &rootamdm37x_enable_interrupt
-};
 
 int main(int argc, char *argv[])
@@ -222,5 +273,4 @@
 	printf("%s: HelenOS AM/DM37x(OMAP37x) platform driver\n", NAME);
 	ddf_log_init(NAME, LVL_ERROR);
-	rootamdm37x_fun_ops.interfaces[HW_RES_DEV_IFACE] = &fun_hw_res_ops;
 	return ddf_driver_main(&rootamdm37x_driver);
 }
