blob: 8e3031dd63fcf3cd54b74108a1374bc257d0d831 [file] [log] [blame]
/*
* 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;
}