int board_usb_init(const void *blob) { struct fdt_usb config; unsigned osc_freq = clock_get_rate(CLOCK_ID_OSC); enum clock_osc_freq freq; int node_list[USB_PORTS_MAX]; int node, count, i; /* Set up the USB clocks correctly based on our oscillator frequency */ freq = clock_get_osc_freq(); config_clock(usb_pll[freq]); /* count may return <0 on error */ count = fdtdec_find_aliases_for_id(blob, "usb", COMPAT_NVIDIA_TEGRA20_USB, node_list, USB_PORTS_MAX); for (i = 0; i < count; i++) { debug("USB %d: ", i); node = node_list[i]; if (!node) continue; if (fdt_decode_usb(blob, node, osc_freq, &config)) { debug("Cannot decode USB node %s\n", fdt_get_name(blob, node, NULL)); return -1; } if (add_port(&config, usb_pll[freq])) return -1; set_host_mode(&config); } return 0; }
/** * Start up the given port number (ports are numbered from 0 on each board). * This returns values for the appropriate hccr and hcor addresses to use for * USB EHCI operations. * * @param index port number to start * @param hccr returns start address of EHCI HCCR registers * @param hcor returns start address of EHCI HCOR registers * @return 0 if ok, -1 on error (generally invalid port number) */ int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor) { struct fdt_usb *config; struct usb_ctlr *usbctlr; if (index >= port_count) return -1; config = &port[index]; /* skip init, if the port is already initialized */ if (config->initialized) goto success; if (config->utmi && init_utmi_usb_controller(config)) { printf("tegrausb: Cannot init port %d\n", index); return -1; } if (config->ulpi && init_ulpi_usb_controller(config)) { printf("tegrausb: Cannot init port %d\n", index); return -1; } set_host_mode(config); config->initialized = 1; success: usbctlr = config->reg; *hccr = (struct ehci_hccr *)&usbctlr->cap_length; *hcor = (struct ehci_hcor *)&usbctlr->usb_cmd; return 0; }
int tegrausb_start_port(int portnum, u32 *hccr, u32 *hcor) { struct usb_ctlr *usbctlr; if (portnum >= port_count) return -1; set_host_mode(&port[portnum]); usbctlr = port[portnum].reg; *hccr = (u32)&usbctlr->cap_length; *hcor = (u32)&usbctlr->usb_cmd; return 0; }
/** * Start up the given port number (ports are numbered from 0 on each board). * This returns values for the appropriate hccr and hcor addresses to use for * USB EHCI operations. * * @param index port number to start * @param hccr returns start address of EHCI HCCR registers * @param hcor returns start address of EHCI HCOR registers * @return 0 if ok, -1 on error (generally invalid port number) */ int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr, struct ehci_hcor **hcor) { struct fdt_usb *config; struct usb_ctlr *usbctlr; if (index >= port_count) return -1; config = &port[index]; /* skip init, if the port is already initialized */ if (config->initialized) goto success; if (config->utmi && init_utmi_usb_controller(config)) { printf("tegrausb: Cannot init port %d\n", index); return -1; } if (config->ulpi && init_ulpi_usb_controller(config)) { printf("tegrausb: Cannot init port %d\n", index); return -1; } set_host_mode(config); config->initialized = 1; success: usbctlr = config->reg; *hccr = (struct ehci_hccr *)&usbctlr->cap_length; *hcor = (struct ehci_hcor *)&usbctlr->usb_cmd; if (controller->has_hostpc) { /* Set to Host mode after Controller Reset was done */ clrsetbits_le32(&usbctlr->usb_mode, USBMODE_CM_HC, USBMODE_CM_HC); /* Select UTMI parallel interface after setting host mode */ if (config->utmi) { clrsetbits_le32((char *)&usbctlr->usb_cmd + HOSTPC1_DEVLC, PTS_MASK, PTS_UTMI << PTS_SHIFT); clrbits_le32((char *)&usbctlr->usb_cmd + HOSTPC1_DEVLC, STS); } } return 0; }
int tegrausb_start_port(unsigned portnum, u32 *hccr, u32 *hcor) { struct usb_ctlr *usbctlr; if (portnum >= port_count) return -1; tegrausb_stop_port(); set_host_mode(&port[portnum]); usbctlr = port[portnum].reg; *hccr = (u32)&usbctlr->cap_length; *hcor = (u32)&usbctlr->usb_cmd; port_current = portnum; return 0; }
/* Put our ports into host mode */ void usb_set_host_mode(void) { if (host_dev_ctlr) set_host_mode(host_dev_ctlr); }