blob: 7c4b90b8055da22d9b9a79f7312e1f04e86b8c05 [file] [log] [blame]
/*
* (C) Copyright 2010
* Marvell Semiconductor <www.marvell.com>
* Written-by: Qingchao Qiu <qcqiu@marvell.com>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#include <common.h>
#include "usb.h"
#include "ehci.h"
#include "ehci-core.h"
#include "apb_perf_base.h"
#include <io.h>
#include <global.h>
#include "gpio.h"
#include "bcm_primitive.h"
#include "timer.h"
#include "bcm_mailbox.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
int berlin_cdp_reinit_phy(u32 base)
{
u32 data, timeout;
/* 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);
/* Power up analog port */
data = ehci_readl( base + USB2_TX_CH_CTRL0);
data |= 1<<24;
ehci_writel((base + USB2_TX_CH_CTRL0), 0x03BE7F6F);
// Squelch setting
data = 0xC39F16CE;
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 &= 0xce00ff80;
data |= 5 | (0x60<<16) | (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;
/* Deinit USB device inside BCM before using USB on ARM side */
bcm_usb_console_func(EROM_TURN_OFF_USB_DEVICE);
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 *)(base_addr + 0x100);
hcor = (struct ehci_hcor *)((u32) 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;
}