| /* |
| * Copyright (C) 2018 Synaptics Incorporated. All rights reserved. |
| * (C) Copyright 2010 Marvell Semiconductor <www.marvell.com> |
| * |
| * Written-by: Qingchao Qiu <qcqiu@marvell.com> |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 as |
| * published by the Free Software Foundation. |
| * |
| * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND |
| * SYNAPTICS EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, |
| * INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE, AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY |
| * INTELLECTUAL PROPERTY RIGHTS. IN NO EVENT SHALL SYNAPTICS BE LIABLE |
| * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, PUNITIVE, OR |
| * CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION WITH THE USE |
| * OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED AND |
| * BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
| * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS |
| * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF |
| * COMPETENT JURISDICTION DOES NOT PERMIT THE DISCLAIMER OF DIRECT |
| * DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS' TOTAL CUMULATIVE LIABILITY |
| * TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S. DOLLARS. |
| */ |
| |
| #include <common.h> |
| #include "usb.h" |
| #include "ehci.h" |
| #include "ehci-core.h" |
| #include "apb_perif_base.h" |
| #include <io.h> |
| #include <global.h> |
| #include "gpio.h" |
| #include "timer.h" |
| |
| #define USB_PHY_REG_BASE_USB0 0xF7B74000 |
| #define USB_PHY_REG_BASE_USB1 0xF7B78000 |
| #define USB_PHY_PLL_REG 0x04 |
| #define USB_PHY_PLL_CONTROL_REG 0x08 |
| #define USB_PHY_ANALOG_REG 0x34 |
| #define USB_PHY_RX_CTRL_REG 0x20 |
| #define USB_PLL_READY (1<<15) |
| #define USBMODE_OFFSET 0x1a8 |
| #define USBMODE_CM_HOST 3 |
| #define MV_SBUSCFG 0x90 |
| |
| #define USB2_OTG_REG0 52 |
| #define USB2_CHARGER_REG0 56 |
| #define USB2_PLL_REG0 0 |
| #define USB2_PLL_REG1 4 |
| #define USB2_CAL_CTRL 8 |
| #define USB2_DIG_REG0 28 |
| #define USB2_TX_CH_CTRL0 12 |
| #define USB2_DIG_REG1 0x20 |
| |
| int berlin_cdp_reinit_phy(u32 base) |
| { |
| u32 data, timeout; |
| |
| //reset |
| data = 0; |
| data |= MSK32Gbl_ResetTrigger_usb0SyncReset; |
| ehci_writel((MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_ResetTrigger), data); |
| udelay(1000); // add some delay |
| |
| /* powering up OTG */ |
| data = ehci_readl( base + USB2_OTG_REG0); |
| data |= 1<<4; |
| ehci_writel((base + USB2_OTG_REG0), data); |
| |
| /* powering Charger detector circuit */ |
| data = ehci_readl( base + USB2_CHARGER_REG0); |
| data |= 1<<5; |
| ehci_writel((base + USB2_CHARGER_REG0), data); |
| |
| data = ehci_readl( base + USB2_DIG_REG1); |
| data |= 1<<10; |
| ehci_writel((base + USB2_DIG_REG1), data); |
| |
| /* Power up analog port */ |
| data = 0x03BE7F6F; |
| ehci_writel((base + USB2_TX_CH_CTRL0), data); |
| |
| // Squelch setting |
| data = 0xC39816CE; |
| ehci_writel((base + USB2_DIG_REG0), data); |
| |
| // Impedance calibration |
| data = 0xf5930488; |
| ehci_writel((base + USB2_CAL_CTRL), data); |
| |
| /* Configuring FBDIV for SOC Clk 25 Mhz */ |
| data = ehci_readl( base + USB2_PLL_REG0); |
| data &= 0xffffff80; |
| data |= 5; |
| data &= 0xfe00ffff; |
| data |= 0x60<<16; |
| data &= 0xcfffffff; |
| data |= 0<<28; |
| ehci_writel((base + USB2_PLL_REG0), data); |
| |
| /* Power up PLL, Reset, Suspen_en disable */ |
| ehci_writel((base + USB2_PLL_REG1), 0x407); |
| udelay(100); |
| |
| /* Deassert Reset */ |
| ehci_writel((base + USB2_PLL_REG1), 0x403); |
| |
| /* Wait for PLL Lock */ |
| timeout = 0x1000000; |
| do { |
| data = ehci_readl( base + USB2_PLL_REG0); |
| if (!--timeout) |
| break; |
| } while ( !(data&0x80000000)); |
| |
| if (!timeout) { |
| debug("ERROR: USB PHY PLL NOT LOCKED!\n"); |
| } |
| |
| return 0; |
| } |
| |
| |
| /* |
| * Create the appropriate control structures to manage |
| * a new EHCI host controller. |
| */ |
| int ehci_hcd_init(void) |
| { |
| u32 base_addr; |
| |
| berlin_cdp_reinit_phy(USB_PHY_REG_BASE_USB0); |
| base_addr = MEMMAP_USB0_REG_BASE; |
| /* set USBMODE to host mode */ |
| ehci_writel(base_addr + USBMODE_OFFSET, USBMODE_CM_HOST); |
| ehci_writel(base_addr + MV_SBUSCFG, 0x07); |
| |
| hccr = (struct ehci_hccr *)((uintmax_t)base_addr + 0x100); |
| hcor = (struct ehci_hcor *)((uintmax_t) hccr |
| + HC_LENGTH(ehci_readl(&hccr->cr_capbase))); |
| |
| debug("Berlin-ehci: init hccr %x and hcor %x hc_length %d\n", |
| (u32)hccr, (u32)hcor, |
| (u32)HC_LENGTH(ehci_readl(&hccr->cr_capbase))); |
| |
| return 0; |
| } |
| |
| /* |
| * Destroy the appropriate control structures corresponding |
| * the the EHCI host controller. |
| */ |
| int ehci_hcd_stop(void) |
| { |
| return 0; |
| } |