summaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/boards/chumby_falconwing/falconwing.c8
-rw-r--r--arch/arm/boards/crystalfontz-cfa10036/cfa10036.c24
-rw-r--r--arch/arm/boards/duckbill/lowlevel.c7
-rw-r--r--arch/arm/boards/freescale-mx23-evk/mx23-evk.c8
-rw-r--r--arch/arm/boards/freescale-mx28-evk/lowlevel.c8
-rw-r--r--arch/arm/boards/freescale-mx28-evk/mx28-evk.c8
-rw-r--r--arch/arm/boards/imx233-olinuxino/imx23-olinuxino.c8
-rw-r--r--arch/arm/boards/imx233-olinuxino/lowlevel.c4
-rw-r--r--arch/arm/boards/karo-tx28/lowlevel.c8
-rw-r--r--arch/arm/boards/karo-tx28/tx28.c8
-rw-r--r--arch/arm/mach-mxs/include/mach/imx23.h29
-rw-r--r--arch/arm/mach-mxs/include/mach/imx28.h30
-rw-r--r--arch/arm/mach-mxs/include/mach/init.h53
-rw-r--r--arch/arm/mach-mxs/mem-init.c28
-rw-r--r--arch/arm/mach-mxs/power-init.c162
-rw-r--r--arch/arm/mach-mxs/soc-imx23.c4
-rw-r--r--arch/arm/mach-mxs/soc-imx28.c4
17 files changed, 242 insertions, 159 deletions
diff --git a/arch/arm/boards/chumby_falconwing/falconwing.c b/arch/arm/boards/chumby_falconwing/falconwing.c
index c866043e8b..5554b78d6d 100644
--- a/arch/arm/boards/chumby_falconwing/falconwing.c
+++ b/arch/arm/boards/chumby_falconwing/falconwing.c
@@ -258,14 +258,6 @@ static const uint32_t pad_setup[] = {
GPMI_RDY3_GPIO | GPIO_IN | PULLUP(1),
};
-static int falconwing_mem_init(void)
-{
- arm_add_mem_device("ram0", IMX_MEMORY_BASE, 64 * 1024 * 1024);
-
- return 0;
-}
-mem_initcall(falconwing_mem_init);
-
#define GPIO_USB_HUB_RESET 29
#define GPIO_USB_HUB_POWER 26
diff --git a/arch/arm/boards/crystalfontz-cfa10036/cfa10036.c b/arch/arm/boards/crystalfontz-cfa10036/cfa10036.c
index 947db7cff6..dcf560432d 100644
--- a/arch/arm/boards/crystalfontz-cfa10036/cfa10036.c
+++ b/arch/arm/boards/crystalfontz-cfa10036/cfa10036.c
@@ -89,30 +89,6 @@ static struct i2c_gpio_platform_data i2c_gpio_pdata = {
.udelay = 5, /* ~100 kHz */
};
-void v5_mmu_cache_flush(void);
-long cfa10036_get_ram_size(void)
-{
- volatile u32 *base = (void *)IMX_MEMORY_BASE;
- volatile u32 *ofs = base + SZ_128M / sizeof(u32);
-
- *base = *ofs = 0xdeadbeef;
- *ofs = 0xbaadcafe;
-
- v5_mmu_cache_flush();
- if (*base == 0xbaadcafe)
- return SZ_128M;
- else
- return SZ_256M;
-}
-
-static int cfa10036_mem_init(void)
-{
- arm_add_mem_device("ram0", IMX_MEMORY_BASE, cfa10036_get_ram_size());
-
- return 0;
-}
-mem_initcall(cfa10036_mem_init);
-
static int cfa10036_devices_init(void)
{
int i;
diff --git a/arch/arm/boards/duckbill/lowlevel.c b/arch/arm/boards/duckbill/lowlevel.c
index 2922e40f2a..22987a6cdb 100644
--- a/arch/arm/boards/duckbill/lowlevel.c
+++ b/arch/arm/boards/duckbill/lowlevel.c
@@ -51,11 +51,14 @@ static noinline void duckbill_init(void)
pr_debug("initializing power...\n");
- mx28_power_init(0, 0, 1);
+ mx28_power_init(POWER_USE_5V, &mx28_power_default);
pr_debug("initializing SDRAM...\n");
- mx28_mem_init(mx28_dram_vals_default);
+ /* EMI_CLK of 480 / 2 * (18/21) = 205.7 MHz */
+ mxs_mem_init_clock(2, 21);
+ mx28_mem_init(PINCTRL_EMI_DS_CTRL_DDR_MODE_DDR2,
+ mx28_dram_vals_default);
pr_debug("DONE\n");
}
diff --git a/arch/arm/boards/freescale-mx23-evk/mx23-evk.c b/arch/arm/boards/freescale-mx23-evk/mx23-evk.c
index dd8048851b..a3587db063 100644
--- a/arch/arm/boards/freescale-mx23-evk/mx23-evk.c
+++ b/arch/arm/boards/freescale-mx23-evk/mx23-evk.c
@@ -53,14 +53,6 @@ static struct fsl_usb2_platform_data usb_pdata = {
};
#endif
-static int mx23_evk_mem_init(void)
-{
- arm_add_mem_device("ram0", IMX_MEMORY_BASE, 32 * 1024 * 1024);
-
- return 0;
-}
-mem_initcall(mx23_evk_mem_init);
-
/**
* Try to register an environment storage on the attached MCI card
* @return 0 on success
diff --git a/arch/arm/boards/freescale-mx28-evk/lowlevel.c b/arch/arm/boards/freescale-mx28-evk/lowlevel.c
index 4d45a03ba2..22cae1374c 100644
--- a/arch/arm/boards/freescale-mx28-evk/lowlevel.c
+++ b/arch/arm/boards/freescale-mx28-evk/lowlevel.c
@@ -43,11 +43,15 @@ static noinline void freescale_mx28evk_init(void)
pr_debug("initializing power...\n");
- mx28_power_init(0, 1, 0);
+ mx28_power_init(POWER_USE_BATTERY_INPUT | POWER_ENABLE_4P2,
+ &mx28_power_default);
pr_debug("initializing SDRAM...\n");
- mx28_mem_init(mx28_dram_vals_default);
+ /* EMI_CLK of 480 / 2 * (18/21) = 205.7 MHz */
+ mxs_mem_init_clock(2, 21);
+ mx28_mem_init(PINCTRL_EMI_DS_CTRL_DDR_MODE_DDR2,
+ mx28_dram_vals_default);
pr_debug("DONE\n");
}
diff --git a/arch/arm/boards/freescale-mx28-evk/mx28-evk.c b/arch/arm/boards/freescale-mx28-evk/mx28-evk.c
index 9e5d612bda..06a2c21a47 100644
--- a/arch/arm/boards/freescale-mx28-evk/mx28-evk.c
+++ b/arch/arm/boards/freescale-mx28-evk/mx28-evk.c
@@ -232,14 +232,6 @@ static struct imx_fb_platformdata mx28_evk_fb_pdata = {
.enable = mx28_evk_fb_enable,
};
-static int mx28_evk_mem_init(void)
-{
- arm_add_mem_device("ram0", IMX_MEMORY_BASE, 128 * 1024 * 1024);
-
- return 0;
-}
-mem_initcall(mx28_evk_mem_init);
-
static const struct spi_board_info mx28evk_spi_board_info[] = {
{
.name = "m25p80",
diff --git a/arch/arm/boards/imx233-olinuxino/imx23-olinuxino.c b/arch/arm/boards/imx233-olinuxino/imx23-olinuxino.c
index b87a6764f3..c06779ddf6 100644
--- a/arch/arm/boards/imx233-olinuxino/imx23-olinuxino.c
+++ b/arch/arm/boards/imx233-olinuxino/imx23-olinuxino.c
@@ -40,14 +40,6 @@ static struct mxs_mci_platform_data mci_pdata = {
.f_min = 400000,
};
-static int imx23_olinuxino_mem_init(void)
-{
- arm_add_mem_device("ram0", IMX_MEMORY_BASE, 64 * 1024 * 1024);
-
- return 0;
-}
-mem_initcall(imx23_olinuxino_mem_init);
-
static void olinuxino_init_usb(void)
{
imx23_usb_phy_enable();
diff --git a/arch/arm/boards/imx233-olinuxino/lowlevel.c b/arch/arm/boards/imx233-olinuxino/lowlevel.c
index 63a65230b0..5f36c17e52 100644
--- a/arch/arm/boards/imx233-olinuxino/lowlevel.c
+++ b/arch/arm/boards/imx233-olinuxino/lowlevel.c
@@ -154,11 +154,13 @@ static noinline void imx23_olinuxino_init(void)
pr_debug("initializing power...\n");
- mx23_power_init(0, 0, 1);
+ mx23_power_init(POWER_USE_5V, &mx23_power_default);
pr_debug("initializing SDRAM...\n");
imx23_olinuxino_adjust_memory_params(mx23_dram_vals);
+ /* EMI_CLK of 480 / 2 * (18/33) = 130.90 MHz */
+ mxs_mem_init_clock(2, 33);
mx23_mem_init();
pr_debug("DONE\n");
diff --git a/arch/arm/boards/karo-tx28/lowlevel.c b/arch/arm/boards/karo-tx28/lowlevel.c
index d072637de7..1a93be747d 100644
--- a/arch/arm/boards/karo-tx28/lowlevel.c
+++ b/arch/arm/boards/karo-tx28/lowlevel.c
@@ -43,11 +43,15 @@ static noinline void karo_tx28_init(void)
pr_debug("initializing power...\n");
- mx28_power_init(0, 1, 0);
+ mx28_power_init(POWER_USE_BATTERY_INPUT | POWER_ENABLE_4P2,
+ &mx28_power_default);
pr_debug("initializing SDRAM...\n");
- mx28_mem_init(mx28_dram_vals_default);
+ /* EMI_CLK of 480 / 2 * (18/21) = 205.7 MHz */
+ mxs_mem_init_clock(2, 21);
+ mx28_mem_init(PINCTRL_EMI_DS_CTRL_DDR_MODE_DDR2,
+ mx28_dram_vals_default);
pr_debug("DONE\n");
}
diff --git a/arch/arm/boards/karo-tx28/tx28.c b/arch/arm/boards/karo-tx28/tx28.c
index 26dbc00790..47cac21307 100644
--- a/arch/arm/boards/karo-tx28/tx28.c
+++ b/arch/arm/boards/karo-tx28/tx28.c
@@ -73,14 +73,6 @@ static const uint32_t tx28_pad_setup[] = {
extern void base_board_init(void);
-static int tx28_mem_init(void)
-{
- arm_add_mem_device("ram0", IMX_MEMORY_BASE, 128 * 1024 * 1024);
-
- return 0;
-}
-mem_initcall(tx28_mem_init);
-
static int tx28_devices_init(void)
{
int i;
diff --git a/arch/arm/mach-mxs/include/mach/imx23.h b/arch/arm/mach-mxs/include/mach/imx23.h
new file mode 100644
index 0000000000..56e76d5f50
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/imx23.h
@@ -0,0 +1,29 @@
+#ifndef __MACH_IMX23_H
+#define __MACH_IMX23_H
+
+#include <linux/bitfield.h>
+#include <io.h>
+
+#define DRAM_CTL14_CS0_EN BIT(0)
+#define DRAM_CTL14_CS1_EN BIT(1)
+#define DRAM_CTL11_COLUMNS_DIFF GENMASK(10, 8)
+#define DRAM_CTL10_ROWS_DIFF GENMASK(18, 16)
+
+#define DRAM_CTL(n) (IMX_SDRAMC_BASE + 4 * (n))
+
+static inline u32 imx23_get_memsize(void)
+{
+ u32 ctl10 = readl(DRAM_CTL(10));
+ u32 ctl11 = readl(DRAM_CTL(11));
+ u32 ctl14 = readl(DRAM_CTL(14));
+ int rows, columns, banks = 4, cs0, cs1;
+
+ columns = 12 - FIELD_GET(DRAM_CTL11_COLUMNS_DIFF, ctl11);
+ rows = 13 - FIELD_GET(DRAM_CTL10_ROWS_DIFF, ctl10);
+ cs0 = FIELD_GET(DRAM_CTL14_CS0_EN, ctl14);
+ cs1 = FIELD_GET(DRAM_CTL14_CS1_EN, ctl14);
+
+ return (1 << columns) * (1 << rows) * banks * (cs0 + cs1);
+}
+
+#endif /* __MACH_IMX23_H */ \ No newline at end of file
diff --git a/arch/arm/mach-mxs/include/mach/imx28.h b/arch/arm/mach-mxs/include/mach/imx28.h
new file mode 100644
index 0000000000..5816625c89
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/imx28.h
@@ -0,0 +1,30 @@
+#ifndef __MACH_IMX28_H
+#define __MACH_IMX28_H
+
+#include <linux/bitfield.h>
+#include <io.h>
+
+#define DRAM_CTL29_CS0_EN BIT(24)
+#define DRAM_CTL29_CS1_EN BIT(25)
+#define DRAM_CTL29_COLUMNS_DIFF GENMASK(18, 16)
+#define DRAM_CTL29_ROWS_DIFF GENMASK(10, 8)
+#define DRAM_CTL31_EIGHT_BANKS BIT(16)
+
+#define DRAM_CTL(n) (IMX_SDRAMC_BASE + 4 * (n))
+
+static inline u32 imx28_get_memsize(void)
+{
+ u32 ctl29 = readl(DRAM_CTL(29));
+ u32 ctl31 = readl(DRAM_CTL(31));
+ int rows, columns, banks, cs0, cs1;
+
+ columns = 12 - FIELD_GET(DRAM_CTL29_COLUMNS_DIFF, ctl29);
+ rows = 15 - FIELD_GET(DRAM_CTL29_ROWS_DIFF, ctl29);
+ banks = FIELD_GET(DRAM_CTL31_EIGHT_BANKS, ctl31) ? 8 : 4;
+ cs0 = FIELD_GET(DRAM_CTL29_CS0_EN, ctl29);
+ cs1 = FIELD_GET(DRAM_CTL29_CS1_EN, ctl29);
+
+ return (1 << columns) * (1 << rows) * banks * (cs0 + cs1);
+}
+
+#endif /* __MACH_IMX28_H */ \ No newline at end of file
diff --git a/arch/arm/mach-mxs/include/mach/init.h b/arch/arm/mach-mxs/include/mach/init.h
index 6526d303a1..53c1e05634 100644
--- a/arch/arm/mach-mxs/include/mach/init.h
+++ b/arch/arm/mach-mxs/include/mach/init.h
@@ -12,20 +12,61 @@
void mxs_early_delay(int delay);
-void mx23_power_init(int __has_battery, int __use_battery_input,
- int __use_5v_input);
-void mx28_power_init(int __has_battery, int __use_battery_input,
- int __use_5v_input);
+/**
+ * Power configuration of the system:
+ * - POWER_USE_5V: use 5V input as power supply
+ * - POWER_USE_BATTERY: use battery input when the system is supplied by a battery
+ * - POWER_USE_BATTERY_INPUT: use battery input when the system is supplied by
+ * a DC source (instead of a real battery) on the battery input
+ * - POWER_ENABLE_4P2: power up the 4P2 regulator (implied for POWER_USE_5V)
+ */
+enum mxs_power_config {
+ POWER_USE_5V = 0b00000000,
+ POWER_USE_BATTERY = 0b00000001,
+ POWER_USE_BATTERY_INPUT = 0b00000010,
+ POWER_ENABLE_4P2 = 0b00000100,
+};
+extern int power_config;
+static inline enum mxs_power_config mxs_power_config_get_use(void) {
+ return (power_config & 0b00000011);
+}
+
+
+struct mxs_power_ctrl {
+ uint32_t target; /*< target voltage */
+ uint32_t brownout; /*< brownout threshhold */
+};
+struct mxs_power_ctrls {
+ struct mxs_power_ctrl * vdda; /*< if non-null, set values for VDDA */
+ struct mxs_power_ctrl * vddd; /*< if non-null, set values for VDDD */
+ struct mxs_power_ctrl * vddio; /*< if non-null, set values for VDDIO */
+ struct mxs_power_ctrl * vddmem; /*< if non-null, set values for VDDMEM */
+};
+
+extern struct mxs_power_ctrl mxs_vddio_default;
+extern struct mxs_power_ctrl mxs_vddd_default;
+extern struct mxs_power_ctrl mxs_vdda_default;
+extern struct mxs_power_ctrl mx23_vddmem_default;
+extern struct mxs_power_ctrls mx23_power_default;
+extern struct mxs_power_ctrls mx28_power_default;
+
+void mx23_power_init(const int config, struct mxs_power_ctrls *ctrls);
+void mx28_power_init(const int config, struct mxs_power_ctrls *ctrls);
void mxs_power_wait_pswitch(void);
extern const uint32_t mx28_dram_vals_default[190];
extern uint32_t mx23_dram_vals[];
+#define PINCTRL_EMI_DS_CTRL_DDR_MODE_LPDDR1 (0b00 << 16)
+#define PINCTRL_EMI_DS_CTRL_DDR_MODE_LVDDR2 (0b10 << 16)
+#define PINCTRL_EMI_DS_CTRL_DDR_MODE_DDR2 (0b11 << 16)
+
void mx23_mem_init(void);
-void mx28_mem_init(const uint32_t dram_vals[190]);
+void mx28_mem_init(const int emi_ds_ctrl_ddr_mode,
+ const uint32_t dram_vals[190]);
void mxs_mem_setup_cpu_and_hbus(void);
void mxs_mem_setup_vdda(void);
-void mxs_mem_init_clock(unsigned char divider);
+void mxs_mem_init_clock(const uint8_t clk_emi_div, const uint8_t clk_emi_frac);
void mxs_lradc_init(void);
void mxs_lradc_enable_batt_measurement(void);
diff --git a/arch/arm/mach-mxs/mem-init.c b/arch/arm/mach-mxs/mem-init.c
index ac8bfee18e..568db81302 100644
--- a/arch/arm/mach-mxs/mem-init.c
+++ b/arch/arm/mach-mxs/mem-init.c
@@ -192,7 +192,12 @@ static void mx23_initialize_dram_values(void)
writel((1 << 24), IMX_SDRAMC_BASE + (4 * 8));
}
-void mxs_mem_init_clock(unsigned char divider)
+/**
+ * Set up the EMI clock.
+ * @clk_emi_div: integer divider (prescaler), the DIV_EMI field in HW_CLKCTRL_EMI
+ * @clk_emi_frac: fractional divider, the EMIFRAC field in HW_CLKCTRL_FRAC0
+ */
+void mxs_mem_init_clock(const uint8_t clk_emi_div, const uint8_t clk_emi_frac)
{
struct mxs_clkctrl_regs *clkctrl_regs =
(struct mxs_clkctrl_regs *)IMX_CCM_BASE;
@@ -202,7 +207,7 @@ void mxs_mem_init_clock(unsigned char divider)
&clkctrl_regs->hw_clkctrl_frac0_set[CLKCTRL_FRAC0_EMI]);
/* Set fractional divider for ref_emi */
- writeb(CLKCTRL_FRAC_CLKGATE | (divider & CLKCTRL_FRAC_FRAC_MASK),
+ writeb(CLKCTRL_FRAC_CLKGATE | (clk_emi_frac & CLKCTRL_FRAC_FRAC_MASK),
&clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_EMI]);
/* Ungate EMI clock */
@@ -211,8 +216,8 @@ void mxs_mem_init_clock(unsigned char divider)
mxs_early_delay(11000);
- /* Set EMI clock divider for EMI clock to 411 / 2 = 205MHz */
- writel((2 << CLKCTRL_EMI_DIV_EMI_OFFSET) |
+ /* Set EMI clock prescaler */
+ writel(((clk_emi_div & CLKCTRL_EMI_DIV_EMI_MASK) << CLKCTRL_EMI_DIV_EMI_OFFSET) |
(1 << CLKCTRL_EMI_DIV_XTAL_OFFSET),
&clkctrl_regs->hw_clkctrl_emi);
@@ -273,9 +278,6 @@ void mx23_mem_init(void)
{
mxs_early_delay(11000);
- /* Fractional divider for ref_emi is 33 ; 480 * 18 / 33 = 266MHz */
- mxs_mem_init_clock(33);
-
/*
* Reset/ungate the EMI block. This is essential, otherwise the system
* suffers from memory instability. This thing is mx23 specific and is
@@ -318,18 +320,12 @@ void mx23_mem_init(void)
mxs_mem_setup_cpu_and_hbus();
}
-#define PINCTRL_EMI_DS_CTRL_DDR_MODE_DDR2 (0x3 << 16)
-
-void mx28_mem_init(const uint32_t dram_vals[190])
+void mx28_mem_init(const int emi_ds_ctrl_ddr_mode, const uint32_t dram_vals[190])
{
mxs_early_delay(11000);
- /* Fractional divider for ref_emi is 21 ; 480 * 18 / 21 = 411MHz */
- mxs_mem_init_clock(21);
-
- /* Set DDR2 mode */
- writel(PINCTRL_EMI_DS_CTRL_DDR_MODE_DDR2,
- IMX_IOMUXC_BASE + 0x1b80);
+ /* Set DDR mode */
+ writel(emi_ds_ctrl_ddr_mode, IMX_IOMUXC_BASE + 0x1b80);
/*
* Configure the DRAM registers
diff --git a/arch/arm/mach-mxs/power-init.c b/arch/arm/mach-mxs/power-init.c
index 595b51c5ba..ca7c349d7f 100644
--- a/arch/arm/mach-mxs/power-init.c
+++ b/arch/arm/mach-mxs/power-init.c
@@ -24,21 +24,7 @@
#include <mach/regs-rtc.h>
#include <mach/regs-lradc.h>
-/*
- * has_battery - true when this board has a battery.
- */
-static int has_battery;
-
-/*
- * use_battery_input - true when this board is supplied from the
- * battery input, but has a DC source instead of a real battery
- */
-static int use_battery_input;
-
-/*
- * use_5v_input - true when this board can use the 5V input
- */
-static int use_5v_input;
+int power_config;
static void mxs_power_status(void)
{
@@ -51,27 +37,30 @@ static void mxs_power_status(void)
uint32_t vddd = readl(&power_regs->hw_power_vdddctrl);
uint32_t vddmem = readl(&power_regs->hw_power_vddmemctrl);
- printf("vddio: %dmV (BO -%dmV), Linreg enabled, Linreg offset: %d, FET %sabled\n",
- (vddio & 0x1f) * 50 + 2800,
- ((vddio >> 8) & 0x7) * 50,
- linregofs[((vdda >> 12) & 0x3)],
- (vddio & (1 << 16)) ? "dis" : "en");
- printf("vdda: %dmV (BO -%dmV), Linreg %sabled, Linreg offset: %d, FET %sabled\n",
- (vdda & 0x1f) * 25 + 1500,
- ((vdda >> 8) & 0x7) * 25,
- (vdda & (1 << 17)) ? "en" : "dis",
- linregofs[((vdda >> 12) & 0x3)],
- (vdda & (1 << 16)) ? "dis" : "en");
- printf("vddd: %dmV (BO -%dmV), Linreg %sabled, Linreg offset: %d, FET %sabled\n",
- (vddd & 0x1f) * 25 + 800,
- ((vddd >> 8) & 0x7) * 25,
- (vddd & (1 << 21)) ? "en" : "dis",
- linregofs[((vdda >> 16) & 0x3)],
- (vdda & (1 << 20)) ? "dis" : "en");
- printf("vddmem: %dmV (BO -%dmV), Linreg %sabled\n",
- (vddmem & 0x1f) * 25 + 1100,
- ((vddmem >> 5) & 0x7) * 25,
- (vddmem & (1 << 8)) ? "en" : "dis");
+#define __REG_BITS(value, fieldname) (((value) & fieldname##_MASK) >> fieldname##_OFFSET)
+
+ printf("vddio: %4dmV (BO -%3dmV), Linreg enabled, Linreg offset: %1d, FET %sabled\n",
+ __REG_BITS(vddio, POWER_VDDIOCTRL_TRG) * 50 + 2800,
+ __REG_BITS(vddio, POWER_VDDIOCTRL_BO_OFFSET) * 50,
+ linregofs[__REG_BITS(vddio, POWER_VDDIOCTRL_LINREG_OFFSET)],
+ (vddio & POWER_VDDIOCTRL_DISABLE_FET) ? "dis" : " en");
+ printf("vdda: %4dmV (BO -%3dmV), Linreg %sabled, Linreg offset: %1d, FET %sabled\n",
+ __REG_BITS(vdda, POWER_VDDACTRL_TRG) * 25 + 1500,
+ __REG_BITS(vdda, POWER_VDDACTRL_BO_OFFSET) * 25,
+ (vdda & POWER_VDDACTRL_ENABLE_LINREG) ? " en" : "dis",
+ linregofs[__REG_BITS(vdda, POWER_VDDACTRL_LINREG_OFFSET)],
+ (vdda & POWER_VDDACTRL_DISABLE_FET) ? "dis" : " en");
+ printf("vddd: %4dmV (BO -%3dmV), Linreg %sabled, Linreg offset: %1d, FET %sabled\n",
+ __REG_BITS(vddd, POWER_VDDDCTRL_TRG) * 25 + 800,
+ __REG_BITS(vddd, POWER_VDDDCTRL_BO_OFFSET) * 25,
+ (vddd & POWER_VDDDCTRL_ENABLE_LINREG) ? " en" : "dis",
+ linregofs[__REG_BITS(vddd, POWER_VDDDCTRL_LINREG_OFFSET)],
+ (vddd & POWER_VDDDCTRL_DISABLE_FET) ? "dis" : " en");
+ printf("vddmem: %4dmV (BO -%3dmV), Linreg %sabled\n",
+ __REG_BITS(vddmem, POWER_VDDMEMCTRL_TRG) * 25 + 1100,
+ /* Note: this area is reserved on i.MX23, yielding 0: */
+ __REG_BITS(vddmem, MX28_POWER_VDDMEMCTRL_BO_OFFSET) * 25,
+ (vddmem & POWER_VDDMEMCTRL_ENABLE_LINREG) ? " en" : "dis");
}
/*
@@ -514,7 +503,8 @@ static void mxs_power_enable_4p2(void)
POWER_5VCTRL_HEADROOM_ADJ_MASK,
0x4 << POWER_5VCTRL_HEADROOM_ADJ_OFFSET);
- if (has_battery || use_battery_input)
+ if (mxs_power_config_get_use() == POWER_USE_BATTERY ||
+ mxs_power_config_get_use() == POWER_USE_BATTERY_INPUT)
dropout_ctrl = POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL;
else
dropout_ctrl = POWER_DCDC4P2_DROPOUT_CTRL_SRC_4P2;
@@ -730,7 +720,8 @@ static void mxs_enable_battery_input(void)
POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
0x8 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
- mxs_power_enable_4p2();
+ if (power_config & POWER_ENABLE_4P2)
+ mxs_power_enable_4p2();
}
/**
@@ -1078,7 +1069,7 @@ static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg,
{
struct mxs_power_regs *power_regs =
(struct mxs_power_regs *)IMX_POWER_BASE;
- uint32_t cur_target, diff, bo_int = 0;
+ uint32_t cur_target, diff, prev_bo_enirq = 0;
uint32_t powered_by_linreg = 0;
int adjust_up, tmp;
@@ -1094,9 +1085,11 @@ static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg,
powered_by_linreg = cfg->powered_by_linreg();
if (adjust_up && cfg->bo_irq) {
+ /* temporarily disable brownout to prevent it from taking
+ effect prematurely during the adjustment */
if (powered_by_linreg) {
- bo_int = readl(cfg->reg);
- clrbits_le32(cfg->reg, cfg->bo_enirq);
+ prev_bo_enirq = readl(&power_regs->hw_power_ctrl) & cfg->bo_enirq;
+ writel(cfg->bo_enirq, &power_regs->hw_power_ctrl_clr);
}
setbits_le32(cfg->reg, cfg->bo_offset_mask);
}
@@ -1136,9 +1129,11 @@ static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg,
if (cfg->bo_irq) {
if (adjust_up && powered_by_linreg) {
+ /* clear brownout IRQ flag in case it fired */
writel(cfg->bo_irq, &power_regs->hw_power_ctrl_clr);
- if (bo_int & cfg->bo_enirq)
- setbits_le32(cfg->reg, cfg->bo_enirq);
+ if (prev_bo_enirq)
+ /* re-enable brownout IRQ after adjustment has finished */
+ writel(cfg->bo_enirq, &power_regs->hw_power_ctrl_set);
}
clrsetbits_le32(cfg->reg, cfg->bo_offset_mask,
@@ -1177,21 +1172,32 @@ static void mx23_ungate_power(void)
writel(MX23_POWER_CTRL_CLKGATE, &power_regs->hw_power_ctrl_clr);
}
+struct mxs_power_ctrl mxs_vddd_default = { .target = 1500, .brownout = 1325 };
+struct mxs_power_ctrl mxs_vdda_default = { .target = 1800, .brownout = 1650 };
+struct mxs_power_ctrl mxs_vddio_default = { .target = 3300, .brownout = 3150 };
+struct mxs_power_ctrl mx23_vddmem_default = { .target = 2500, .brownout = 1700 };
+struct mxs_power_ctrls mx23_power_default = {
+ .vdda = &mxs_vdda_default,
+ .vddd = &mxs_vddd_default,
+ .vddio = &mxs_vddio_default,
+ .vddmem = &mx23_vddmem_default,
+};
+
/**
* mx23_power_init() - The power block init main function
*
* This function calls all the power block initialization functions in
* proper sequence to start the power block.
+ *
+ * @config: see enum mxs_power_config for possible options
+ * @ctrls: a mxs_power_ctrls struct, or use &mx23_power_default for default values
*/
-void mx23_power_init(int __has_battery, int __use_battery_input,
- int __use_5v_input)
+void mx23_power_init(const int config, struct mxs_power_ctrls *ctrls)
{
struct mxs_power_regs *power_regs =
(struct mxs_power_regs *)IMX_POWER_BASE;
- has_battery = __has_battery;
- use_battery_input = __use_battery_input;
- use_5v_input = __use_5v_input;
+ power_config = config;
mx23_ungate_power();
@@ -1204,11 +1210,11 @@ void mx23_power_init(int __has_battery, int __use_battery_input,
mxs_src_power_init();
- if (has_battery)
+ if (mxs_power_config_get_use() == POWER_USE_BATTERY)
mxs_power_configure_power_source();
- else if (use_battery_input)
+ else if (mxs_power_config_get_use() == POWER_USE_BATTERY_INPUT)
mxs_enable_battery_input();
- else if (use_5v_input)
+ else if (mxs_power_config_get_use() == POWER_USE_5V)
mxs_boot_valid_5v();
mxs_power_clock2pll();
@@ -1223,10 +1229,18 @@ void mx23_power_init(int __has_battery, int __use_battery_input,
mxs_enable_output_rail_protection();
- mxs_power_set_vddx(&mx23_vddio_cfg, 3300, 3150);
- mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1325);
- mxs_power_set_vddx(&mxs_vddmem_cfg, 2500, 1700);
- mxs_power_set_vddx(&mxs_vdda_cfg, 1800, 1650);
+ if (ctrls->vddio)
+ mxs_power_set_vddx(&mx23_vddio_cfg, ctrls->vddio->target,
+ ctrls->vddio->brownout);
+ if (ctrls->vddd)
+ mxs_power_set_vddx(&mxs_vddd_cfg, ctrls->vddd->target,
+ ctrls->vddd->brownout);
+ if (ctrls->vddmem)
+ mxs_power_set_vddx(&mxs_vddmem_cfg, ctrls->vddmem->target,
+ ctrls->vddmem->brownout);
+ if (ctrls->vdda)
+ mxs_power_set_vddx(&mxs_vdda_cfg, ctrls->vdda->target,
+ ctrls->vdda->brownout);
writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ |
@@ -1238,21 +1252,28 @@ void mx23_power_init(int __has_battery, int __use_battery_input,
mxs_early_delay(1000);
}
+struct mxs_power_ctrls mx28_power_default = {
+ .vdda = &mxs_vdda_default,
+ .vddd = &mxs_vddd_default,
+ .vddio = &mxs_vddio_default,
+ .vddmem = NULL,
+};
+
/**
* mx28_power_init() - The power block init main function
*
* This function calls all the power block initialization functions in
* proper sequence to start the power block.
+ *
+ * @config: see enum mxs_power_config for possible options
+ * @ctrls: a mxs_power_ctrls struct, or use &mx28_power_default for default values
*/
-void mx28_power_init(int __has_battery, int __use_battery_input,
- int __use_5v_input)
+void mx28_power_init(const int config, struct mxs_power_ctrls *ctrls)
{
struct mxs_power_regs *power_regs =
(struct mxs_power_regs *)IMX_POWER_BASE;
- has_battery = __has_battery;
- use_battery_input = __use_battery_input;
- use_5v_input = __use_5v_input;
+ power_config = config;
mxs_power_status();
mxs_power_clock2xtal();
@@ -1264,11 +1285,11 @@ void mx28_power_init(int __has_battery, int __use_battery_input,
mxs_src_power_init();
- if (has_battery)
+ if (mxs_power_config_get_use() == POWER_USE_BATTERY)
mxs_power_configure_power_source();
- else if (use_battery_input)
+ else if (mxs_power_config_get_use() == POWER_USE_BATTERY_INPUT)
mxs_enable_battery_input();
- else if (use_5v_input)
+ else if (mxs_power_config_get_use() == POWER_USE_5V)
mxs_boot_valid_5v();
mxs_power_clock2pll();
@@ -1279,9 +1300,18 @@ void mx28_power_init(int __has_battery, int __use_battery_input,
mxs_enable_output_rail_protection();
- mxs_power_set_vddx(&mx28_vddio_cfg, 3300, 3150);
- mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1325);
- mxs_power_set_vddx(&mxs_vdda_cfg, 1800, 1650);
+ if (ctrls->vddio)
+ mxs_power_set_vddx(&mx28_vddio_cfg, ctrls->vddio->target,
+ ctrls->vddio->brownout);
+ if (ctrls->vddd)
+ mxs_power_set_vddx(&mxs_vddd_cfg, ctrls->vddd->target,
+ ctrls->vddd->brownout);
+ if (ctrls->vddmem)
+ mxs_power_set_vddx(&mxs_vddmem_cfg, ctrls->vddmem->target,
+ ctrls->vddmem->brownout);
+ if (ctrls->vdda)
+ mxs_power_set_vddx(&mxs_vdda_cfg, ctrls->vdda->target,
+ ctrls->vdda->brownout);
writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ |
diff --git a/arch/arm/mach-mxs/soc-imx23.c b/arch/arm/mach-mxs/soc-imx23.c
index d471c8eb5c..f25fff18c3 100644
--- a/arch/arm/mach-mxs/soc-imx23.c
+++ b/arch/arm/mach-mxs/soc-imx23.c
@@ -19,6 +19,8 @@
#include <restart.h>
#include <mach/imx23-regs.h>
#include <io.h>
+#include <asm/memory.h>
+#include <mach/imx23.h>
#define HW_CLKCTRL_RESET 0x120
# define HW_CLKCTRL_RESET_CHIP (1 << 1)
@@ -37,6 +39,8 @@ static void __noreturn imx23_restart_soc(struct restart_handler *rst)
static int imx23_devices_init(void)
{
+ arm_add_mem_device("ram0", IMX_MEMORY_BASE, imx23_get_memsize());
+
if (of_get_root_node())
return 0;
diff --git a/arch/arm/mach-mxs/soc-imx28.c b/arch/arm/mach-mxs/soc-imx28.c
index dc6020aa36..49f870b5bf 100644
--- a/arch/arm/mach-mxs/soc-imx28.c
+++ b/arch/arm/mach-mxs/soc-imx28.c
@@ -19,6 +19,8 @@
#include <restart.h>
#include <mach/imx28-regs.h>
#include <io.h>
+#include <asm/memory.h>
+#include <mach/imx28.h>
#define HW_CLKCTRL_RESET 0x1e0
# define HW_CLKCTRL_RESET_CHIP (1 << 1)
@@ -51,6 +53,8 @@ static int imx28_init(void)
restart_handler_register_fn(imx28_restart_soc);
+ arm_add_mem_device("ram0", IMX_MEMORY_BASE, imx28_get_memsize());
+
return 0;
}
postcore_initcall(imx28_init);