0617364f3584b311025acdbe35a020a3a6d8b64c
[oweals/u-boot.git] / drivers / usb / musb / am35x.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * am35x.c - TI's AM35x platform specific usb wrapper functions.
4  *
5  * Author: Ajay Kumar Gupta <ajay.gupta@ti.com>
6  *
7  * Based on drivers/usb/musb/da8xx.c
8  *
9  * Copyright (c) 2010 Texas Instruments Incorporated
10  */
11
12 #include <common.h>
13
14 #include "am35x.h"
15
16 /* MUSB platform configuration */
17 struct musb_config musb_cfg = {
18         .regs           = (struct musb_regs *)AM35X_USB_OTG_CORE_BASE,
19         .timeout        = AM35X_USB_OTG_TIMEOUT,
20         .musb_speed     = 0,
21 };
22
23 /*
24  * Enable the USB phy
25  */
26 static u8 phy_on(void)
27 {
28         u32 devconf2;
29         u32 timeout;
30
31         devconf2 = readl(&am35x_scm_general_regs->devconf2);
32
33         devconf2 &= ~(DEVCONF2_RESET | DEVCONF2_PHYPWRDN | DEVCONF2_OTGPWRDN |
34                       DEVCONF2_OTGMODE | DEVCONF2_REFFREQ |
35                       DEVCONF2_PHY_GPIOMODE);
36         devconf2 |= DEVCONF2_SESENDEN | DEVCONF2_VBDTCTEN | DEVCONF2_PHY_PLLON |
37                     DEVCONF2_REFFREQ_13MHZ | DEVCONF2_DATPOL;
38
39         writel(devconf2, &am35x_scm_general_regs->devconf2);
40
41         /* wait until the USB phy is turned on */
42         timeout = musb_cfg.timeout;
43         while (timeout--)
44                 if (readl(&am35x_scm_general_regs->devconf2) & DEVCONF2_PHYCKGD)
45                         return 1;
46
47         /* USB phy was not turned on */
48         return 0;
49 }
50
51 /*
52  * Disable the USB phy
53  */
54 static void phy_off(void)
55 {
56         u32 devconf2;
57
58         /*
59          * Power down the on-chip PHY.
60          */
61         devconf2 = readl(&am35x_scm_general_regs->devconf2);
62
63         devconf2 &= ~DEVCONF2_PHY_PLLON;
64         devconf2 |= DEVCONF2_PHYPWRDN | DEVCONF2_OTGPWRDN;
65         writel(devconf2, &am35x_scm_general_regs->devconf2);
66 }
67
68 /*
69  * This function performs platform specific initialization for usb0.
70  */
71 int musb_platform_init(void)
72 {
73         u32 revision;
74         u32 sw_reset;
75
76         /* global usb reset */
77         sw_reset = readl(&am35x_scm_general_regs->ip_sw_reset);
78         sw_reset |= (1 << 0);
79         writel(sw_reset, &am35x_scm_general_regs->ip_sw_reset);
80         sw_reset &= ~(1 << 0);
81         writel(sw_reset, &am35x_scm_general_regs->ip_sw_reset);
82
83         /* reset the controller */
84         writel(0x1, &am35x_usb_regs->control);
85         udelay(5000);
86
87         /* start the on-chip usb phy and its pll */
88         if (phy_on() == 0)
89                 return -1;
90
91         /* Returns zero if e.g. not clocked */
92         revision = readl(&am35x_usb_regs->revision);
93         if (revision == 0)
94                 return -1;
95
96         return 0;
97 }
98
99 /*
100  * This function performs platform specific deinitialization for usb0.
101  */
102 void musb_platform_deinit(void)
103 {
104         /* Turn off the phy */
105         phy_off();
106 }
107
108 /*
109  * This function reads data from endpoint fifo for AM35x
110  * which supports only 32bit read operation.
111  *
112  * ep           - endpoint number
113  * length       - number of bytes to read from FIFO
114  * fifo_data    - pointer to data buffer into which data is read
115  */
116 __attribute__((weak))
117 void read_fifo(u8 ep, u32 length, void *fifo_data)
118 {
119         u8  *data = (u8 *)fifo_data;
120         u32 val;
121         int i;
122
123         /* select the endpoint index */
124         writeb(ep, &musbr->index);
125
126         if (length > 4) {
127                 for (i = 0; i < (length >> 2); i++) {
128                         val = readl(&musbr->fifox[ep]);
129                         memcpy(data, &val, 4);
130                         data += 4;
131                 }
132                 length %= 4;
133         }
134         if (length > 0) {
135                 val = readl(&musbr->fifox[ep]);
136                 memcpy(data, &val, length);
137         }
138 }