summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2012-07-02 11:00:56 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2012-07-02 11:01:46 +0200
commit1422cd1878f7c9854b9d5c5baa80eb67a0b31d47 (patch)
tree8a92c8229a1c4018ed16178c7f1ef2369268cc10 /arch
parentc9fc3209ac6d5738fd0de419bfdcdc7240ab9eb0 (diff)
parent1d3d060ab79d69c4447692e600193e9a10d7ec57 (diff)
downloadbarebox-1422cd1878f7c9854b9d5c5baa80eb67a0b31d47.tar.gz
barebox-1422cd1878f7c9854b9d5c5baa80eb67a0b31d47.tar.xz
Merge branch 'for-next/mx28-ocotp'
Conflicts: arch/arm/mach-mxs/ocotp.c
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/boards/freescale-mx28-evk/mx28-evk.c30
-rw-r--r--arch/arm/mach-mxs/Kconfig12
-rw-r--r--arch/arm/mach-mxs/Makefile2
-rw-r--r--arch/arm/mach-mxs/include/mach/clock-imx23.h1
-rw-r--r--arch/arm/mach-mxs/include/mach/clock-imx28.h1
-rw-r--r--arch/arm/mach-mxs/include/mach/imx28-regs.h1
-rw-r--r--arch/arm/mach-mxs/include/mach/power.h8
-rw-r--r--arch/arm/mach-mxs/ocotp.c150
-rw-r--r--arch/arm/mach-mxs/power.c84
-rw-r--r--arch/arm/mach-mxs/speed-imx23.c26
-rw-r--r--arch/arm/mach-mxs/speed-imx28.c26
-rw-r--r--arch/arm/mach-mxs/usb.c30
12 files changed, 319 insertions, 52 deletions
diff --git a/arch/arm/boards/freescale-mx28-evk/mx28-evk.c b/arch/arm/boards/freescale-mx28-evk/mx28-evk.c
index 9168ed8823..1283e1769a 100644
--- a/arch/arm/boards/freescale-mx28-evk/mx28-evk.c
+++ b/arch/arm/boards/freescale-mx28-evk/mx28-evk.c
@@ -22,17 +22,18 @@
#include <init.h>
#include <mci.h>
#include <io.h>
+#include <net.h>
#include <mach/clock.h>
#include <mach/imx-regs.h>
#include <mach/iomux-imx28.h>
#include <mach/mci.h>
+#include <mach/fb.h>
+#include <mach/ocotp.h>
#include <asm/armlinux.h>
#include <asm/mmu.h>
-#include <mach/fb.h>
-
#include <generated/mach-types.h>
#define MX28EVK_FEC_PHY_RESET_GPIO 141
@@ -118,6 +119,27 @@ static struct mxs_mci_platform_data mci_pdata = {
};
/* fec */
+static void mx28_evk_get_ethaddr(void)
+{
+ u8 mac_ocotp[3], mac[6];
+ int ret;
+
+ ret = mxs_ocotp_read(mac_ocotp, 3, 0);
+ if (ret != 3) {
+ pr_err("Reading MAC from OCOTP failed!\n");
+ return;
+ }
+
+ mac[0] = 0x00;
+ mac[1] = 0x04;
+ mac[2] = 0x9f;
+ mac[3] = mac_ocotp[2];
+ mac[4] = mac_ocotp[1];
+ mac[5] = mac_ocotp[0];
+
+ eth_register_ethaddr(0, mac);
+}
+
static void __init mx28_evk_fec_reset(void)
{
mdelay(1);
@@ -208,6 +230,10 @@ static int mx28_evk_devices_init(void)
add_generic_device("stmfb", 0, NULL, IMX_FB_BASE, 4096,
IORESOURCE_MEM, &mx28_evk_fb_pdata);
+ add_generic_device("ocotp", 0, NULL, IMX_OCOTP_BASE, 0,
+ IORESOURCE_MEM, NULL);
+ mx28_evk_get_ethaddr(); /* must be after registering ocotp */
+
imx_enable_enetclk();
mx28_evk_fec_reset();
add_generic_device("fec_imx", 0, NULL, IMX_FEC0_BASE, 0,
diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
index 3348a3cef7..9ce7c7a1bd 100644
--- a/arch/arm/mach-mxs/Kconfig
+++ b/arch/arm/mach-mxs/Kconfig
@@ -61,6 +61,7 @@ config MACH_TX28
config MACH_MX28EVK
bool "mx28-evk"
+ select MXS_OCOTP
help
Say Y here if you are using the Freescale i.MX28-EVK board
@@ -80,6 +81,17 @@ config MXS_OCOTP
internal view). Don't use register offsets here, the SET, CLR and
TGL registers are not mapped!
+config MXS_OCOTP_WRITABLE
+ bool "OCOTP write support"
+ depends on MXS_OCOTP
+ help
+ Enable this option to add writing to OCOTP.
+ Warning: blown bits can not be unblown. Use with care.
+
+ Before being actually able to blow the bits, you need to explicitely
+ enable writing:
+ ocotp0.permanent_write_enable=1
+
endmenu
menu "Board specific settings "
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
index 172d928128..37b5b8a037 100644
--- a/arch/arm/mach-mxs/Makefile
+++ b/arch/arm/mach-mxs/Makefile
@@ -1,4 +1,4 @@
-obj-y += imx.o iomux-imx.o reset-imx.o
+obj-y += imx.o iomux-imx.o reset-imx.o power.o
obj-$(CONFIG_DRIVER_VIDEO_STM) += imx_lcd_clk.o
obj-$(CONFIG_ARCH_IMX23) += speed-imx23.o clocksource-imx23.o usb.o
obj-$(CONFIG_ARCH_IMX28) += speed-imx28.o clocksource-imx28.o
diff --git a/arch/arm/mach-mxs/include/mach/clock-imx23.h b/arch/arm/mach-mxs/include/mach/clock-imx23.h
index 723f343566..4f20e09d3d 100644
--- a/arch/arm/mach-mxs/include/mach/clock-imx23.h
+++ b/arch/arm/mach-mxs/include/mach/clock-imx23.h
@@ -18,6 +18,7 @@ unsigned imx_get_emiclk(void);
unsigned imx_get_ioclk(void);
unsigned imx_get_armclk(void);
unsigned imx_get_hclk(void);
+unsigned imx_set_hclk(unsigned);
unsigned imx_get_xclk(void);
unsigned imx_get_sspclk(unsigned);
unsigned imx_set_sspclk(unsigned, unsigned, int);
diff --git a/arch/arm/mach-mxs/include/mach/clock-imx28.h b/arch/arm/mach-mxs/include/mach/clock-imx28.h
index 45fb043ac4..613c97b916 100644
--- a/arch/arm/mach-mxs/include/mach/clock-imx28.h
+++ b/arch/arm/mach-mxs/include/mach/clock-imx28.h
@@ -18,6 +18,7 @@ unsigned imx_get_emiclk(void);
unsigned imx_get_ioclk(unsigned);
unsigned imx_get_armclk(void);
unsigned imx_get_hclk(void);
+unsigned imx_set_hclk(unsigned);
unsigned imx_get_xclk(void);
unsigned imx_get_sspclk(unsigned);
unsigned imx_set_sspclk(unsigned, unsigned, int);
diff --git a/arch/arm/mach-mxs/include/mach/imx28-regs.h b/arch/arm/mach-mxs/include/mach/imx28-regs.h
index 9a2052c159..23ac306c8c 100644
--- a/arch/arm/mach-mxs/include/mach/imx28-regs.h
+++ b/arch/arm/mach-mxs/include/mach/imx28-regs.h
@@ -32,6 +32,7 @@
#define IMX_OCOTP_BASE 0x8002c000
#define IMX_FB_BASE 0x80030000
#define IMX_CCM_BASE 0x80040000
+#define IMX_POWER_BASE 0x80044000
#define IMX_WDT_BASE 0x80056000
#define IMX_I2C0_BASE 0x80058000
#define IMX_I2C1_BASE 0x8005a000
diff --git a/arch/arm/mach-mxs/include/mach/power.h b/arch/arm/mach-mxs/include/mach/power.h
new file mode 100644
index 0000000000..f429b3c31c
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/power.h
@@ -0,0 +1,8 @@
+#ifndef __MACH_POWER_H
+#define __MACH_POWER_H
+
+void imx_power_prepare_usbphy(void);
+int imx_get_vddio(void);
+int imx_set_vddio(int);
+
+#endif /* __MACH_POWER_H */
diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
index 86e63dc7de..78244028b9 100644
--- a/arch/arm/mach-mxs/ocotp.c
+++ b/arch/arm/mach-mxs/ocotp.c
@@ -25,27 +25,45 @@
#include <mach/generic.h>
#include <mach/ocotp.h>
#include <mach/imx-regs.h>
+#include <mach/clock-imx28.h>
+#include <mach/power.h>
#define DRIVERNAME "ocotp"
-#define OCOTP_WORD_OFFSET 0x20
+#define OCOTP_CTRL 0x0
+# define OCOTP_CTRL_ADDR_MASK 0x3f
+# define OCOTP_CTRL_BUSY (1 << 8)
+# define OCOTP_CTRL_ERROR (1 << 9)
+# define OCOTP_CTRL_RD_BANK_OPEN (1 << 12)
+# define OCOTP_CTRL_WR_UNLOCK 0x3e770000
+
+#define OCOTP_DATA 0x10
-#define BM_OCOTP_CTRL_BUSY (1 << 8)
-#define BM_OCOTP_CTRL_ERROR (1 << 9)
-#define BM_OCOTP_CTRL_RD_BANK_OPEN (1 << 12)
+#define OCOTP_WORD_OFFSET 0x20
struct ocotp_priv {
struct cdev cdev;
void __iomem *base;
};
+static int mxs_ocotp_wait_busy(struct ocotp_priv *priv)
+{
+ uint64_t start = get_time_ns();
+
+ /* check both BUSY and ERROR cleared */
+ while (readl(priv->base + OCOTP_CTRL) & (OCOTP_CTRL_BUSY | OCOTP_CTRL_ERROR))
+ if (is_timeout(start, MSECOND))
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
static ssize_t mxs_ocotp_cdev_read(struct cdev *cdev, void *buf, size_t count,
loff_t offset, ulong flags)
{
struct ocotp_priv *priv = cdev->priv;
void __iomem *base = priv->base;
size_t size = min((loff_t)count, cdev->size - offset);
- uint64_t start;
int i;
/*
@@ -54,25 +72,20 @@ static ssize_t mxs_ocotp_cdev_read(struct cdev *cdev, void *buf, size_t count,
*/
/* try to clear ERROR bit */
- writel(BM_OCOTP_CTRL_ERROR, base + BIT_CLR);
+ writel(OCOTP_CTRL_ERROR, base + OCOTP_CTRL + BIT_CLR);
- /* check both BUSY and ERROR cleared */
- start = get_time_ns();
- while (readl(base) & (BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR))
- if (is_timeout(start, MSECOND))
- return -ETIMEDOUT;
+ if (mxs_ocotp_wait_busy(priv))
+ return -ETIMEDOUT;
/* open OCOTP banks for read */
- writel(BM_OCOTP_CTRL_RD_BANK_OPEN, base + BIT_SET);
+ writel(OCOTP_CTRL_RD_BANK_OPEN, base + OCOTP_CTRL + BIT_SET);
/* approximately wait 32 hclk cycles */
udelay(1);
/* poll BUSY bit becoming cleared */
- start = get_time_ns();
- while (readl(base) & BM_OCOTP_CTRL_BUSY)
- if (is_timeout(start, MSECOND))
- return -ETIMEDOUT;
+ if (mxs_ocotp_wait_busy(priv))
+ return -ETIMEDOUT;
for (i = 0; i < size; i++)
/* When reading bytewise, we need to hop over the SET/CLR/TGL regs */
@@ -80,16 +93,107 @@ static ssize_t mxs_ocotp_cdev_read(struct cdev *cdev, void *buf, size_t count,
(((i + offset) & 0xfc) << 2) + ((i + offset) & 3));
/* close banks for power saving */
- writel(BM_OCOTP_CTRL_RD_BANK_OPEN, base + BIT_CLR);
+ writel(OCOTP_CTRL_RD_BANK_OPEN, base + OCOTP_CTRL + BIT_CLR);
return size;
}
+static ssize_t mxs_ocotp_cdev_write(struct cdev *cdev, const void *buf, size_t count,
+ loff_t offset, ulong flags)
+{
+ struct ocotp_priv *priv = cdev->priv;
+ void __iomem *base = priv->base;
+ const char *write_param;
+ unsigned int write_enabled = 0;
+ unsigned long old_hclk, aligned_offset;
+ int old_vddio, num_words, num_bytes, i, ret = 0;
+ u8 *work_buf;
+ u32 reg;
+
+ write_param = dev_get_param(cdev->dev, "permanent_write_enable");
+ if (write_param)
+ write_enabled = simple_strtoul(write_param, NULL, 0);
+
+ if (!write_param || !write_enabled)
+ return -EPERM;
+
+ /* we can only work on u32, so calc some helpers */
+ aligned_offset = offset & ~3UL;
+ num_words = DIV_ROUND_UP(offset - aligned_offset + count, 4);
+ num_bytes = num_words << 2;
+
+ /* read in all words which will be modified */
+ work_buf = xmalloc(num_bytes);
+
+ i = mxs_ocotp_cdev_read(cdev, work_buf, num_bytes, aligned_offset, 0);
+ if (i != num_bytes) {
+ ret = -ENXIO;
+ goto free_mem;
+ }
+
+ /* modify read words with to be written data */
+ for (i = 0; i < count; i++)
+ work_buf[offset - aligned_offset + i] |= ((u8 *)buf)[i];
+
+ /* prepare system for OTP write */
+ old_hclk = imx_get_hclk();
+ old_vddio = imx_get_vddio();
+
+ imx_set_hclk(24000000);
+ imx_set_vddio(2800000);
+
+ writel(OCOTP_CTRL_RD_BANK_OPEN, base + OCOTP_CTRL + BIT_CLR);
+
+ if (mxs_ocotp_wait_busy(priv)) {
+ ret = -ETIMEDOUT;
+ goto restore_system;
+ }
+
+ /* write word for word via data register */
+ for (i = 0; i < num_words; i++) {
+ reg = readl(base + OCOTP_CTRL) & ~OCOTP_CTRL_ADDR_MASK;
+ reg |= OCOTP_CTRL_WR_UNLOCK | ((aligned_offset >> 2) + i);
+ writel(reg, base + OCOTP_CTRL);
+
+ writel(((u32 *)work_buf)[i], base + OCOTP_DATA);
+
+ if (mxs_ocotp_wait_busy(priv)) {
+ ret = -ETIMEDOUT;
+ goto restore_system;
+ }
+
+ mdelay(2);
+ }
+
+restore_system:
+ imx_set_vddio(old_vddio);
+ imx_set_hclk(old_hclk);
+free_mem:
+ free(work_buf);
+
+ return ret;
+}
+
static struct file_operations mxs_ocotp_ops = {
.read = mxs_ocotp_cdev_read,
.lseek = dev_lseek_default,
};
+static int mxs_ocotp_write_enable_set(struct device_d *dev, struct param_d *param,
+ const char *val)
+{
+ unsigned long write_enable;
+
+ if (!val)
+ return -EINVAL;
+
+ write_enable = simple_strtoul(val, NULL, 0);
+ if (write_enable > 1)
+ return -EINVAL;
+
+ return dev_param_set_generic(dev, param, write_enable ? "1" : "0");
+}
+
static int mxs_ocotp_probe(struct device_d *dev)
{
int err;
@@ -106,6 +210,18 @@ static int mxs_ocotp_probe(struct device_d *dev)
if (err < 0)
return err;
+ if (IS_ENABLED(CONFIG_MXS_OCOTP_WRITABLE)) {
+ mxs_ocotp_ops.write = mxs_ocotp_cdev_write;
+
+ err = dev_add_param(dev, "permanent_write_enable",
+ mxs_ocotp_write_enable_set, NULL, 0);
+ if (err < 0)
+ return err;
+ err = dev_set_param(dev, "permanent_write_enable", "0");
+ if (err < 0)
+ return err;
+ }
+
return 0;
}
diff --git a/arch/arm/mach-mxs/power.c b/arch/arm/mach-mxs/power.c
new file mode 100644
index 0000000000..f4d0b9e3e6
--- /dev/null
+++ b/arch/arm/mach-mxs/power.c
@@ -0,0 +1,84 @@
+/*
+ * i.MX28 power related functions
+ *
+ * Copyright 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ * Copyright (C) 2012 Wolfram Sang, Pengutronix <w.sang@pengutronix.de>
+ *
+ * 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.
+ */
+#include <common.h>
+#include <io.h>
+#include <errno.h>
+#include <mach/imx-regs.h>
+
+#define POWER_CTRL (IMX_POWER_BASE + 0x0)
+#define POWER_CTRL_CLKGATE 0x40000000
+
+#define POWER_VDDIOCTRL (IMX_POWER_BASE + 0x60)
+
+#define POWER_STS (IMX_POWER_BASE + 0xc0)
+#define POWER_STS_VBUSVALID 0x00000002
+#define POWER_STS_BVALID 0x00000004
+#define POWER_STS_AVALID 0x00000008
+
+#define POWER_DEBUG (IMX_POWER_BASE + 0x110)
+#define POWER_DEBUG_BVALIDPIOLOCK 0x00000002
+#define POWER_DEBUG_AVALIDPIOLOCK 0x00000004
+#define POWER_DEBUG_VBUSVALIDPIOLOCK 0x00000008
+
+#define TRG_MASK 0x1f
+
+int imx_get_vddio(void)
+{
+ u32 val;
+
+ val = readl(POWER_VDDIOCTRL) & TRG_MASK;
+ if (val > 0x10)
+ val = 0x10;
+
+ return 2800000 + val * 50000;
+}
+
+int imx_set_vddio(int new_voltage_uV)
+{
+ u32 reg, val;
+
+ if (new_voltage_uV < 2800000 || new_voltage_uV > 3600000)
+ return -EINVAL;
+
+ val = (new_voltage_uV - 2800000) / 50000;
+ reg = readl(POWER_VDDIOCTRL) & ~TRG_MASK;
+ writel(reg | val, POWER_VDDIOCTRL);
+
+ /*
+ * Wait for power to become stable. We just wait, because DC_OK can
+ * only detect rising voltages for DCDC. For all other cases, bootlets
+ * also do simple waiting, although horribly nested. We just take the
+ * maximum value of all cases from the bootlets and then add some.
+ */
+ mdelay(30);
+
+ return 2800000 + val * 50000;
+}
+
+void imx_power_prepare_usbphy(void)
+{
+ u32 reg;
+
+ /*
+ * Set these bits so that we can force the OTG bits high
+ * so the ARC core operates properly
+ */
+ writel(POWER_CTRL_CLKGATE, POWER_CTRL + BIT_CLR);
+
+ writel(POWER_DEBUG_VBUSVALIDPIOLOCK |
+ POWER_DEBUG_AVALIDPIOLOCK |
+ POWER_DEBUG_BVALIDPIOLOCK, POWER_DEBUG + BIT_SET);
+
+ reg = readl(POWER_STS);
+ reg |= POWER_STS_BVALID | POWER_STS_AVALID | POWER_STS_VBUSVALID;
+ writel(reg, POWER_STS);
+}
diff --git a/arch/arm/mach-mxs/speed-imx23.c b/arch/arm/mach-mxs/speed-imx23.c
index b10c78643c..f41b9bc75a 100644
--- a/arch/arm/mach-mxs/speed-imx23.c
+++ b/arch/arm/mach-mxs/speed-imx23.c
@@ -184,12 +184,34 @@ unsigned imx_get_hclk(void)
if (readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x20) {
rate *= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
- rate >>= 5U; /* / 32 */
+ rate = DIV_ROUND_UP(rate, 32);
} else
- rate /= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
+ rate = DIV_ROUND_UP(rate,
+ readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f);
return rate * 1000;
}
+unsigned imx_set_hclk(unsigned nc)
+{
+ unsigned root_rate = imx_get_armclk();
+ unsigned reg, div;
+
+ div = DIV_ROUND_UP(root_rate, nc);
+ if ((div == 0) || (div >= 32))
+ return 0;
+
+ if ((root_rate < nc) && (root_rate == 64000000))
+ div = 3;
+
+ reg = readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & ~0x3f;
+ writel(reg | div, IMX_CCM_BASE + HW_CLKCTRL_HBUS);
+
+ while (readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & (1 << 31))
+ ;
+
+ return imx_get_hclk();
+}
+
/*
* Source of UART, debug UART, audio, PWM, dri, timer, digctl
*/
diff --git a/arch/arm/mach-mxs/speed-imx28.c b/arch/arm/mach-mxs/speed-imx28.c
index 67cdbdf81d..2641fb6fb2 100644
--- a/arch/arm/mach-mxs/speed-imx28.c
+++ b/arch/arm/mach-mxs/speed-imx28.c
@@ -251,12 +251,34 @@ unsigned imx_get_hclk(void)
if (readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x20) {
rate *= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
- rate /= 32;
+ rate = DIV_ROUND_UP(rate, 32);
} else
- rate /= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
+ rate = DIV_ROUND_UP(rate,
+ readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f);
return rate * 1000;
}
+unsigned imx_set_hclk(unsigned nc)
+{
+ unsigned root_rate = imx_get_armclk();
+ unsigned reg, div;
+
+ div = DIV_ROUND_UP(root_rate, nc);
+ if ((div == 0) || (div >= 32))
+ return 0;
+
+ if ((root_rate < nc) && (root_rate == 64000000))
+ div = 3;
+
+ reg = readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & ~0x3f;
+ writel(reg | div, IMX_CCM_BASE + HW_CLKCTRL_HBUS);
+
+ while (readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & (1 << 31))
+ ;
+
+ return imx_get_hclk();
+}
+
/*
* Source of UART, debug UART, audio, PWM, dri, timer, digctl
*/
diff --git a/arch/arm/mach-mxs/usb.c b/arch/arm/mach-mxs/usb.c
index b7a93769b7..aca0e7d654 100644
--- a/arch/arm/mach-mxs/usb.c
+++ b/arch/arm/mach-mxs/usb.c
@@ -20,19 +20,7 @@
#include <common.h>
#include <io.h>
#include <mach/imx-regs.h>
-
-#define POWER_CTRL (IMX_POWER_BASE + 0x0)
-#define POWER_CTRL_CLKGATE 0x40000000
-
-#define POWER_STS (IMX_POWER_BASE + 0xc0)
-#define POWER_STS_VBUSVALID 0x00000002
-#define POWER_STS_BVALID 0x00000004
-#define POWER_STS_AVALID 0x00000008
-
-#define POWER_DEBUG (IMX_POWER_BASE + 0x110)
-#define POWER_DEBUG_BVALIDPIOLOCK 0x00000002
-#define POWER_DEBUG_AVALIDPIOLOCK 0x00000004
-#define POWER_DEBUG_VBUSVALIDPIOLOCK 0x00000008
+#include <mach/power.h>
#define USBPHY_PWD (IMX_USBPHY_BASE + 0x0)
@@ -51,21 +39,7 @@
int imx_usb_phy_enable(void)
{
- u32 reg;
-
- /*
- * Set these bits so that we can force the OTG bits high
- * so the ARC core operates properly
- */
- writel(POWER_CTRL_CLKGATE, POWER_CTRL + CLR);
-
- writel(POWER_DEBUG_VBUSVALIDPIOLOCK |
- POWER_DEBUG_AVALIDPIOLOCK |
- POWER_DEBUG_BVALIDPIOLOCK, POWER_DEBUG + SET);
-
- reg = readl(POWER_STS);
- reg |= POWER_STS_BVALID | POWER_STS_AVALID | POWER_STS_VBUSVALID;
- writel(reg, POWER_STS);
+ imx_power_prepare_usbphy();
/* Reset USBPHY module */
writel(USBPHY_CTRL_SFTRST, USBPHY_CTRL + SET);