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