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