* [PATCH V2 1/8] arm: mxs: make get_hclk result useable for upcoming set_hclk
2012-06-14 13:20 [PATCH V2 0/8] arm: mxs: add ocotp write support Wolfram Sang
@ 2012-06-14 13:20 ` Wolfram Sang
2012-06-14 13:20 ` [PATCH V2 2/8] arm: mxs: add imx_set_hclk Wolfram Sang
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Wolfram Sang @ 2012-06-14 13:20 UTC (permalink / raw)
To: barebox; +Cc: Wolfram Sang
To avoid getting a different divider due to rounding errors when using
set_hclk later, use DIV_ROUND_UP for the returned value.
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
---
arch/arm/mach-mxs/speed-imx23.c | 5 +++--
arch/arm/mach-mxs/speed-imx28.c | 5 +++--
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-mxs/speed-imx23.c b/arch/arm/mach-mxs/speed-imx23.c
index b10c786..c9ca7ac 100644
--- a/arch/arm/mach-mxs/speed-imx23.c
+++ b/arch/arm/mach-mxs/speed-imx23.c
@@ -184,9 +184,10 @@ 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;
}
diff --git a/arch/arm/mach-mxs/speed-imx28.c b/arch/arm/mach-mxs/speed-imx28.c
index 67cdbdf..4f4db1b 100644
--- a/arch/arm/mach-mxs/speed-imx28.c
+++ b/arch/arm/mach-mxs/speed-imx28.c
@@ -251,9 +251,10 @@ 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;
}
--
1.7.10
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH V2 2/8] arm: mxs: add imx_set_hclk
2012-06-14 13:20 [PATCH V2 0/8] arm: mxs: add ocotp write support Wolfram Sang
2012-06-14 13:20 ` [PATCH V2 1/8] arm: mxs: make get_hclk result useable for upcoming set_hclk Wolfram Sang
@ 2012-06-14 13:20 ` Wolfram Sang
2012-06-14 13:21 ` [PATCH V2 3/8] arm: mxs: refactor access to power domain Wolfram Sang
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Wolfram Sang @ 2012-06-14 13:20 UTC (permalink / raw)
To: barebox; +Cc: Wolfram Sang
needed for writing the One-Time-Prgorammable
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
---
arch/arm/mach-mxs/include/mach/clock-imx23.h | 1 +
arch/arm/mach-mxs/include/mach/clock-imx28.h | 1 +
arch/arm/mach-mxs/speed-imx23.c | 21 +++++++++++++++++++++
arch/arm/mach-mxs/speed-imx28.c | 21 +++++++++++++++++++++
4 files changed, 44 insertions(+)
diff --git a/arch/arm/mach-mxs/include/mach/clock-imx23.h b/arch/arm/mach-mxs/include/mach/clock-imx23.h
index 723f343..4f20e09 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 45fb043..613c97b 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/speed-imx23.c b/arch/arm/mach-mxs/speed-imx23.c
index c9ca7ac..f41b9bc 100644
--- a/arch/arm/mach-mxs/speed-imx23.c
+++ b/arch/arm/mach-mxs/speed-imx23.c
@@ -191,6 +191,27 @@ unsigned imx_get_hclk(void)
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 4f4db1b..2641fb6 100644
--- a/arch/arm/mach-mxs/speed-imx28.c
+++ b/arch/arm/mach-mxs/speed-imx28.c
@@ -258,6 +258,27 @@ unsigned imx_get_hclk(void)
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
*/
--
1.7.10
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH V2 3/8] arm: mxs: refactor access to power domain
2012-06-14 13:20 [PATCH V2 0/8] arm: mxs: add ocotp write support Wolfram Sang
2012-06-14 13:20 ` [PATCH V2 1/8] arm: mxs: make get_hclk result useable for upcoming set_hclk Wolfram Sang
2012-06-14 13:20 ` [PATCH V2 2/8] arm: mxs: add imx_set_hclk Wolfram Sang
@ 2012-06-14 13:21 ` Wolfram Sang
2012-06-14 13:21 ` [PATCH V2 4/8] arm: mxs: add POWER_BASE for MX28, too Wolfram Sang
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Wolfram Sang @ 2012-06-14 13:21 UTC (permalink / raw)
To: barebox; +Cc: Wolfram Sang
usbphy initializaion needs to access the power supply and has this
embedded. Refactor to a seperate power.c, since we need other accesses
in the future.
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
---
arch/arm/mach-mxs/Makefile | 2 +-
arch/arm/mach-mxs/include/mach/power.h | 6 +++++
arch/arm/mach-mxs/power.c | 46 ++++++++++++++++++++++++++++++++
arch/arm/mach-mxs/usb.c | 30 ++-------------------
4 files changed, 55 insertions(+), 29 deletions(-)
create mode 100644 arch/arm/mach-mxs/include/mach/power.h
create mode 100644 arch/arm/mach-mxs/power.c
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
index 172d928..37b5b8a 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/power.h b/arch/arm/mach-mxs/include/mach/power.h
new file mode 100644
index 0000000..859a717
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/power.h
@@ -0,0 +1,6 @@
+#ifndef __MACH_POWER_H
+#define __MACH_POWER_H
+
+void imx_power_prepare_usbphy(void);
+
+#endif /* __MACH_POWER_H */
diff --git a/arch/arm/mach-mxs/power.c b/arch/arm/mach-mxs/power.c
new file mode 100644
index 0000000..4645f52
--- /dev/null
+++ b/arch/arm/mach-mxs/power.c
@@ -0,0 +1,46 @@
+/*
+ * 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 <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
+
+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/usb.c b/arch/arm/mach-mxs/usb.c
index b7a9376..aca0e7d 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);
--
1.7.10
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH V2 4/8] arm: mxs: add POWER_BASE for MX28, too
2012-06-14 13:20 [PATCH V2 0/8] arm: mxs: add ocotp write support Wolfram Sang
` (2 preceding siblings ...)
2012-06-14 13:21 ` [PATCH V2 3/8] arm: mxs: refactor access to power domain Wolfram Sang
@ 2012-06-14 13:21 ` Wolfram Sang
2012-06-14 13:21 ` [PATCH V2 5/8] arm: mxs: add functions to get/set vddio Wolfram Sang
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Wolfram Sang @ 2012-06-14 13:21 UTC (permalink / raw)
To: barebox; +Cc: Wolfram Sang
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
---
arch/arm/mach-mxs/include/mach/imx28-regs.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-mxs/include/mach/imx28-regs.h b/arch/arm/mach-mxs/include/mach/imx28-regs.h
index 9a2052c..23ac306 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
--
1.7.10
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH V2 5/8] arm: mxs: add functions to get/set vddio
2012-06-14 13:20 [PATCH V2 0/8] arm: mxs: add ocotp write support Wolfram Sang
` (3 preceding siblings ...)
2012-06-14 13:21 ` [PATCH V2 4/8] arm: mxs: add POWER_BASE for MX28, too Wolfram Sang
@ 2012-06-14 13:21 ` Wolfram Sang
2012-06-14 13:21 ` [PATCH V2 6/8] arm: mxs: refactor timeout routine for ocotp Wolfram Sang
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Wolfram Sang @ 2012-06-14 13:21 UTC (permalink / raw)
To: barebox; +Cc: Wolfram Sang
Needed for ocotp write.
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
---
arch/arm/mach-mxs/include/mach/power.h | 2 ++
arch/arm/mach-mxs/power.c | 38 ++++++++++++++++++++++++++++++++
2 files changed, 40 insertions(+)
diff --git a/arch/arm/mach-mxs/include/mach/power.h b/arch/arm/mach-mxs/include/mach/power.h
index 859a717..f429b3c 100644
--- a/arch/arm/mach-mxs/include/mach/power.h
+++ b/arch/arm/mach-mxs/include/mach/power.h
@@ -2,5 +2,7 @@
#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/power.c b/arch/arm/mach-mxs/power.c
index 4645f52..f4d0b9e 100644
--- a/arch/arm/mach-mxs/power.c
+++ b/arch/arm/mach-mxs/power.c
@@ -11,11 +11,14 @@
*/
#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
@@ -26,6 +29,41 @@
#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;
--
1.7.10
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH V2 6/8] arm: mxs: refactor timeout routine for ocotp
2012-06-14 13:20 [PATCH V2 0/8] arm: mxs: add ocotp write support Wolfram Sang
` (4 preceding siblings ...)
2012-06-14 13:21 ` [PATCH V2 5/8] arm: mxs: add functions to get/set vddio Wolfram Sang
@ 2012-06-14 13:21 ` Wolfram Sang
2012-06-14 13:21 ` [PATCH V2 7/8] arm: mxs: use consistent naming for #defines " Wolfram Sang
2012-06-14 13:21 ` [PATCH V2 8/8] arm: mxs: add write support " Wolfram Sang
7 siblings, 0 replies; 9+ messages in thread
From: Wolfram Sang @ 2012-06-14 13:21 UTC (permalink / raw)
To: barebox; +Cc: Wolfram Sang
Let's keep the timeout routine in a central place. We will need it more
often when we add write support.
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
---
arch/arm/mach-mxs/ocotp.c | 26 ++++++++++++++++----------
1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
index 38f9ffd..7f9107a 100644
--- a/arch/arm/mach-mxs/ocotp.c
+++ b/arch/arm/mach-mxs/ocotp.c
@@ -39,13 +39,24 @@ struct ocotp_priv {
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) & (BM_OCOTP_CTRL_BUSY | BM_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,
ulong offset, ulong flags)
{
struct ocotp_priv *priv = cdev->priv;
void __iomem *base = priv->base;
size_t size = min((ulong)count, cdev->size - offset);
- uint64_t start;
int i;
/*
@@ -56,11 +67,8 @@ 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);
- /* 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);
@@ -69,10 +77,8 @@ static ssize_t mxs_ocotp_cdev_read(struct cdev *cdev, void *buf, size_t count,
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 */
--
1.7.10
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH V2 7/8] arm: mxs: use consistent naming for #defines for ocotp
2012-06-14 13:20 [PATCH V2 0/8] arm: mxs: add ocotp write support Wolfram Sang
` (5 preceding siblings ...)
2012-06-14 13:21 ` [PATCH V2 6/8] arm: mxs: refactor timeout routine for ocotp Wolfram Sang
@ 2012-06-14 13:21 ` Wolfram Sang
2012-06-14 13:21 ` [PATCH V2 8/8] arm: mxs: add write support " Wolfram Sang
7 siblings, 0 replies; 9+ messages in thread
From: Wolfram Sang @ 2012-06-14 13:21 UTC (permalink / raw)
To: barebox; +Cc: Wolfram Sang
Will the code more readable, especially since future additions are
planned.
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
---
arch/arm/mach-mxs/ocotp.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
index 7f9107a..f18d066 100644
--- a/arch/arm/mach-mxs/ocotp.c
+++ b/arch/arm/mach-mxs/ocotp.c
@@ -28,11 +28,12 @@
#define DRIVERNAME "ocotp"
-#define OCOTP_WORD_OFFSET 0x20
+#define OCOTP_CTRL 0x0
+# define OCOTP_CTRL_BUSY (1 << 8)
+# define OCOTP_CTRL_ERROR (1 << 9)
+# define OCOTP_CTRL_RD_BANK_OPEN (1 << 12)
-#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;
@@ -44,7 +45,7 @@ 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) & (BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR))
+ while (readl(priv->base + OCOTP_CTRL) & (OCOTP_CTRL_BUSY | OCOTP_CTRL_ERROR))
if (is_timeout(start, MSECOND))
return -ETIMEDOUT;
@@ -65,13 +66,13 @@ 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);
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);
@@ -86,7 +87,7 @@ 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;
}
--
1.7.10
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH V2 8/8] arm: mxs: add write support for ocotp
2012-06-14 13:20 [PATCH V2 0/8] arm: mxs: add ocotp write support Wolfram Sang
` (6 preceding siblings ...)
2012-06-14 13:21 ` [PATCH V2 7/8] arm: mxs: use consistent naming for #defines " Wolfram Sang
@ 2012-06-14 13:21 ` Wolfram Sang
7 siblings, 0 replies; 9+ messages in thread
From: Wolfram Sang @ 2012-06-14 13:21 UTC (permalink / raw)
To: barebox; +Cc: Wolfram Sang
Since we now can change HCLK and VDDIO, we can now support writing to
OCOTP. Writing is done via a special data register. This is u32, so we
need to fill a temporary buffer when offset or count is not aligned. The
write is also protected by a special device variable.
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
---
arch/arm/mach-mxs/Kconfig | 11 +++++
arch/arm/mach-mxs/ocotp.c | 109 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 120 insertions(+)
diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
index 57bd556..9ce7c7a 100644
--- a/arch/arm/mach-mxs/Kconfig
+++ b/arch/arm/mach-mxs/Kconfig
@@ -81,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/ocotp.c b/arch/arm/mach-mxs/ocotp.c
index f18d066..92a287f 100644
--- a/arch/arm/mach-mxs/ocotp.c
+++ b/arch/arm/mach-mxs/ocotp.c
@@ -25,13 +25,19 @@
#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_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 OCOTP_WORD_OFFSET 0x20
@@ -92,11 +98,102 @@ static ssize_t mxs_ocotp_cdev_read(struct cdev *cdev, void *buf, size_t count,
return size;
}
+static ssize_t mxs_ocotp_cdev_write(struct cdev *cdev, const void *buf, size_t count,
+ ulong 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;
@@ -113,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;
}
--
1.7.10
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 9+ messages in thread