barebox/arch/arm/mach-imx/usb-imx6.c
Sascha Hauer 59a22cb392 ARM i.MX6: Fix usb phy base addresses
What we had as usb phy1 base address is really usb phy2. Fix the names
and add the missing base address definition for usb phy1.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
2013-01-20 11:07:50 +01:00

112 lines
3.4 KiB
C

/*
* Copyright (C) 2012 Steffen Trumtrar, Pengutronix
*
* 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.
*
*/
#include <common.h>
#include <io.h>
#include <mach/imx6-regs.h>
#define SET 0x4
#define CLR 0x8
#define USBPHY_CTRL 0x30
#define USB_OTG_CTRL 0x800
#define USB_UH1_CTRL 0x804
#define USB_UH2_CTRL 0x808
#define USB_UH3_CTRL 0x80c
#define USB_UH1_USBCMD 0x340
#define USB_CMD_RUNSTOP (1 << 0)
#define USB_CMD_RESET (1 << 1)
#define USB_OVER_CUR_DIS (1 << 7)
#define USBPHY_CTRL_SFTRST (1 << 31)
#define USBPHY_CTRL_CLKGATE (1 << 30)
#define USBPHY_CTRL_ENUTMILEVEL3 (1 << 15)
#define USBPHY_CTRL_ENUTMILEVEL2 (1 << 14)
#define USBPHY1_PLL_480_CTRL_EN (1 << 13)
#define USBPHY1_PLL_480_CTRL_POWER (1 << 12)
#define USBPHY1_PLL_480_CTRL_EN_USB_CLK (1 << 6)
#define USBPHY1_PLL_480_CTRL_BYPASS (1 << 16)
int imx6_usb_phy2_disable_oc(void)
{
int val;
/* disable over current detection */
val = readl(MX6_USBOH3_USB_BASE_ADDR + USB_UH1_CTRL);
val |= USB_OVER_CUR_DIS;
writel(val, MX6_USBOH3_USB_BASE_ADDR + USB_UH1_CTRL);
val = readl(MX6_USBOH3_USB_BASE_ADDR + USB_UH2_CTRL);
val |= USB_OVER_CUR_DIS;
writel(val, MX6_USBOH3_USB_BASE_ADDR + USB_UH2_CTRL);
val = readl(MX6_USBOH3_USB_BASE_ADDR + USB_UH3_CTRL);
val |= USB_OVER_CUR_DIS;
writel(val, MX6_USBOH3_USB_BASE_ADDR + USB_UH3_CTRL);
return 0;
}
int imx6_usb_phy2_enable(void)
{
int val;
/* disable external charger detector or DP will be poor */
writel(0x00180000, MX6_ANATOP_BASE_ADDR + 0x1b0);
writel(0x00180000, MX6_ANATOP_BASE_ADDR + 0x210);
/* enable usb pll */
writel(USBPHY1_PLL_480_CTRL_EN |
USBPHY1_PLL_480_CTRL_POWER |
USBPHY1_PLL_480_CTRL_EN_USB_CLK, MX6_ANATOP_BASE_ADDR + 0x24);
/* turn OFF clk bypass */
/* at least on imx6 v1.0 this essential for usb to work */
/* FIXME: test on v1.1. Datasheet declares bit as reserved */
writel(USBPHY1_PLL_480_CTRL_BYPASS, MX6_ANATOP_BASE_ADDR + 0x28);
/* stop then reset */
val = readl(MX6_USBOH3_USB_BASE_ADDR + USB_UH1_USBCMD);
val &= ~USB_CMD_RUNSTOP;
writel(val, MX6_USBOH3_USB_BASE_ADDR + USB_UH1_USBCMD);
while (readl(MX6_USBOH3_USB_BASE_ADDR + USB_UH1_USBCMD) & USB_CMD_RUNSTOP);
val = readl(MX6_USBOH3_USB_BASE_ADDR + USB_UH1_USBCMD);
val |= USB_CMD_RESET;
writel(val, MX6_USBOH3_USB_BASE_ADDR + USB_UH1_USBCMD);
while (readl(MX6_USBOH3_USB_BASE_ADDR + USB_UH1_USBCMD) & USB_CMD_RESET);
/* reset usbphy */
writel(USBPHY_CTRL_SFTRST, MX6_USBPHY2_BASE_ADDR + USBPHY_CTRL + SET);
udelay(10);
/* clr reset and clkgate */
writel(USBPHY_CTRL_SFTRST | USBPHY_CTRL_CLKGATE, MX6_USBPHY2_BASE_ADDR + USBPHY_CTRL + CLR);
/* clr all pwd bits => power up phy */
writel(0xffffffff, MX6_USBPHY2_BASE_ADDR + CLR);
/* set utmilvl2/3 */
val = readl(MX6_USBPHY2_BASE_ADDR + USBPHY_CTRL);
val |= USBPHY_CTRL_ENUTMILEVEL3 | USBPHY_CTRL_ENUTMILEVEL2;
writel(val, MX6_USBPHY2_BASE_ADDR + USBPHY_CTRL + SET);
return 0;
}