xref: /openbmc/u-boot/drivers/usb/musb/am35x.c (revision e8f80a5a)
1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2dbea3242SAjay Kumar Gupta /*
3dbea3242SAjay Kumar Gupta  * am35x.c - TI's AM35x platform specific usb wrapper functions.
4dbea3242SAjay Kumar Gupta  *
5dbea3242SAjay Kumar Gupta  * Author: Ajay Kumar Gupta <ajay.gupta@ti.com>
6dbea3242SAjay Kumar Gupta  *
7dbea3242SAjay Kumar Gupta  * Based on drivers/usb/musb/da8xx.c
8dbea3242SAjay Kumar Gupta  *
9dbea3242SAjay Kumar Gupta  * Copyright (c) 2010 Texas Instruments Incorporated
10dbea3242SAjay Kumar Gupta  */
111a459660SWolfgang Denk 
12dbea3242SAjay Kumar Gupta #include <common.h>
13dbea3242SAjay Kumar Gupta 
14dbea3242SAjay Kumar Gupta #include "am35x.h"
15dbea3242SAjay Kumar Gupta 
16dbea3242SAjay Kumar Gupta /* MUSB platform configuration */
17dbea3242SAjay Kumar Gupta struct musb_config musb_cfg = {
18dbea3242SAjay Kumar Gupta 	.regs		= (struct musb_regs *)AM35X_USB_OTG_CORE_BASE,
19dbea3242SAjay Kumar Gupta 	.timeout	= AM35X_USB_OTG_TIMEOUT,
20dbea3242SAjay Kumar Gupta 	.musb_speed	= 0,
21dbea3242SAjay Kumar Gupta };
22dbea3242SAjay Kumar Gupta 
23dbea3242SAjay Kumar Gupta /*
24dbea3242SAjay Kumar Gupta  * Enable the USB phy
25dbea3242SAjay Kumar Gupta  */
phy_on(void)26dbea3242SAjay Kumar Gupta static u8 phy_on(void)
27dbea3242SAjay Kumar Gupta {
28dbea3242SAjay Kumar Gupta 	u32 devconf2;
29dbea3242SAjay Kumar Gupta 	u32 timeout;
30dbea3242SAjay Kumar Gupta 
31dbea3242SAjay Kumar Gupta 	devconf2 = readl(&am35x_scm_general_regs->devconf2);
32dbea3242SAjay Kumar Gupta 
33dbea3242SAjay Kumar Gupta 	devconf2 &= ~(DEVCONF2_RESET | DEVCONF2_PHYPWRDN | DEVCONF2_OTGPWRDN |
34dbea3242SAjay Kumar Gupta 		      DEVCONF2_OTGMODE | DEVCONF2_REFFREQ |
35dbea3242SAjay Kumar Gupta 		      DEVCONF2_PHY_GPIOMODE);
36dbea3242SAjay Kumar Gupta 	devconf2 |= DEVCONF2_SESENDEN | DEVCONF2_VBDTCTEN | DEVCONF2_PHY_PLLON |
37dbea3242SAjay Kumar Gupta 		    DEVCONF2_REFFREQ_13MHZ | DEVCONF2_DATPOL;
38dbea3242SAjay Kumar Gupta 
39dbea3242SAjay Kumar Gupta 	writel(devconf2, &am35x_scm_general_regs->devconf2);
40dbea3242SAjay Kumar Gupta 
41dbea3242SAjay Kumar Gupta 	/* wait until the USB phy is turned on */
42dbea3242SAjay Kumar Gupta 	timeout = musb_cfg.timeout;
43dbea3242SAjay Kumar Gupta 	while (timeout--)
44dbea3242SAjay Kumar Gupta 		if (readl(&am35x_scm_general_regs->devconf2) & DEVCONF2_PHYCKGD)
45dbea3242SAjay Kumar Gupta 			return 1;
46dbea3242SAjay Kumar Gupta 
47dbea3242SAjay Kumar Gupta 	/* USB phy was not turned on */
48dbea3242SAjay Kumar Gupta 	return 0;
49dbea3242SAjay Kumar Gupta }
50dbea3242SAjay Kumar Gupta 
51dbea3242SAjay Kumar Gupta /*
52dbea3242SAjay Kumar Gupta  * Disable the USB phy
53dbea3242SAjay Kumar Gupta  */
phy_off(void)54dbea3242SAjay Kumar Gupta static void phy_off(void)
55dbea3242SAjay Kumar Gupta {
56dbea3242SAjay Kumar Gupta 	u32 devconf2;
57dbea3242SAjay Kumar Gupta 
58dbea3242SAjay Kumar Gupta 	/*
59dbea3242SAjay Kumar Gupta 	 * Power down the on-chip PHY.
60dbea3242SAjay Kumar Gupta 	 */
61dbea3242SAjay Kumar Gupta 	devconf2 = readl(&am35x_scm_general_regs->devconf2);
62dbea3242SAjay Kumar Gupta 
63dbea3242SAjay Kumar Gupta 	devconf2 &= ~DEVCONF2_PHY_PLLON;
64dbea3242SAjay Kumar Gupta 	devconf2 |= DEVCONF2_PHYPWRDN | DEVCONF2_OTGPWRDN;
65dbea3242SAjay Kumar Gupta 	writel(devconf2, &am35x_scm_general_regs->devconf2);
66dbea3242SAjay Kumar Gupta }
67dbea3242SAjay Kumar Gupta 
68dbea3242SAjay Kumar Gupta /*
69dbea3242SAjay Kumar Gupta  * This function performs platform specific initialization for usb0.
70dbea3242SAjay Kumar Gupta  */
musb_platform_init(void)71dbea3242SAjay Kumar Gupta int musb_platform_init(void)
72dbea3242SAjay Kumar Gupta {
73dbea3242SAjay Kumar Gupta 	u32 revision;
74dbea3242SAjay Kumar Gupta 	u32 sw_reset;
75dbea3242SAjay Kumar Gupta 
76dbea3242SAjay Kumar Gupta 	/* global usb reset */
77dbea3242SAjay Kumar Gupta 	sw_reset = readl(&am35x_scm_general_regs->ip_sw_reset);
78dbea3242SAjay Kumar Gupta 	sw_reset |= (1 << 0);
79dbea3242SAjay Kumar Gupta 	writel(sw_reset, &am35x_scm_general_regs->ip_sw_reset);
80dbea3242SAjay Kumar Gupta 	sw_reset &= ~(1 << 0);
81dbea3242SAjay Kumar Gupta 	writel(sw_reset, &am35x_scm_general_regs->ip_sw_reset);
82dbea3242SAjay Kumar Gupta 
83dbea3242SAjay Kumar Gupta 	/* reset the controller */
84dbea3242SAjay Kumar Gupta 	writel(0x1, &am35x_usb_regs->control);
85dbea3242SAjay Kumar Gupta 	udelay(5000);
86dbea3242SAjay Kumar Gupta 
87dbea3242SAjay Kumar Gupta 	/* start the on-chip usb phy and its pll */
88dbea3242SAjay Kumar Gupta 	if (phy_on() == 0)
89dbea3242SAjay Kumar Gupta 		return -1;
90dbea3242SAjay Kumar Gupta 
91dbea3242SAjay Kumar Gupta 	/* Returns zero if e.g. not clocked */
92dbea3242SAjay Kumar Gupta 	revision = readl(&am35x_usb_regs->revision);
93dbea3242SAjay Kumar Gupta 	if (revision == 0)
94dbea3242SAjay Kumar Gupta 		return -1;
95dbea3242SAjay Kumar Gupta 
96dbea3242SAjay Kumar Gupta 	return 0;
97dbea3242SAjay Kumar Gupta }
98dbea3242SAjay Kumar Gupta 
99dbea3242SAjay Kumar Gupta /*
100dbea3242SAjay Kumar Gupta  * This function performs platform specific deinitialization for usb0.
101dbea3242SAjay Kumar Gupta  */
musb_platform_deinit(void)102dbea3242SAjay Kumar Gupta void musb_platform_deinit(void)
103dbea3242SAjay Kumar Gupta {
104dbea3242SAjay Kumar Gupta 	/* Turn off the phy */
105dbea3242SAjay Kumar Gupta 	phy_off();
106dbea3242SAjay Kumar Gupta }
1075689f4b5SAjay Kumar Gupta 
1085689f4b5SAjay Kumar Gupta /*
1095689f4b5SAjay Kumar Gupta  * This function reads data from endpoint fifo for AM35x
1105689f4b5SAjay Kumar Gupta  * which supports only 32bit read operation.
1115689f4b5SAjay Kumar Gupta  *
1125689f4b5SAjay Kumar Gupta  * ep           - endpoint number
1135689f4b5SAjay Kumar Gupta  * length       - number of bytes to read from FIFO
1145689f4b5SAjay Kumar Gupta  * fifo_data    - pointer to data buffer into which data is read
1155689f4b5SAjay Kumar Gupta  */
1165689f4b5SAjay Kumar Gupta __attribute__((weak))
read_fifo(u8 ep,u32 length,void * fifo_data)1175689f4b5SAjay Kumar Gupta void read_fifo(u8 ep, u32 length, void *fifo_data)
1185689f4b5SAjay Kumar Gupta {
1195689f4b5SAjay Kumar Gupta 	u8  *data = (u8 *)fifo_data;
1205689f4b5SAjay Kumar Gupta 	u32 val;
1215689f4b5SAjay Kumar Gupta 	int i;
1225689f4b5SAjay Kumar Gupta 
1235689f4b5SAjay Kumar Gupta 	/* select the endpoint index */
1245689f4b5SAjay Kumar Gupta 	writeb(ep, &musbr->index);
1255689f4b5SAjay Kumar Gupta 
1265689f4b5SAjay Kumar Gupta 	if (length > 4) {
1275689f4b5SAjay Kumar Gupta 		for (i = 0; i < (length >> 2); i++) {
1285689f4b5SAjay Kumar Gupta 			val = readl(&musbr->fifox[ep]);
1295689f4b5SAjay Kumar Gupta 			memcpy(data, &val, 4);
1305689f4b5SAjay Kumar Gupta 			data += 4;
1315689f4b5SAjay Kumar Gupta 		}
1325689f4b5SAjay Kumar Gupta 		length %= 4;
1335689f4b5SAjay Kumar Gupta 	}
1345689f4b5SAjay Kumar Gupta 	if (length > 0) {
1355689f4b5SAjay Kumar Gupta 		val = readl(&musbr->fifox[ep]);
1365689f4b5SAjay Kumar Gupta 		memcpy(data, &val, length);
1375689f4b5SAjay Kumar Gupta 	}
1385689f4b5SAjay Kumar Gupta }
139