From 4ad33b21f9ca2702bfa0f1ecdbecd6bbe884325f Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 13 Aug 2018 15:02:47 +0200 Subject: scripts: mxsimage: Allow unencrypted images Normally MXS SoCs only allow to boot images which have been encrypted with a zero key. If the ENABLE_UNENCTRYPTED_BOOT fuse is blown then the SoC also allows to boot unencrypted images. Add an option to the mxsimage tool to generate such images. Signed-off-by: Sascha Hauer Signed-off-by: Roland Hieber Signed-off-by: Sascha Hauer --- scripts/mxsimage.c | 53 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/scripts/mxsimage.c b/scripts/mxsimage.c index 5c2c3079de..8a63d76939 100644 --- a/scripts/mxsimage.c +++ b/scripts/mxsimage.c @@ -337,6 +337,7 @@ struct sb_image_ctx { /* Image configuration */ unsigned int verbose_boot:1; unsigned int silent_dump:1; + unsigned int encrypted:1; const char *input_filename; const char *output_filename; const char *cfg_filename; @@ -484,6 +485,12 @@ static int sb_aes_crypt(struct sb_image_ctx *ictx, uint8_t *in_data, int ret, outlen; uint8_t *outbuf; + if (!ictx->encrypted) { + if (out_data && in_data != out_data) + memcpy(out_data, in_data, in_len); + return 0; + } + outbuf = malloc(in_len); if (!outbuf) return -ENOMEM; @@ -645,7 +652,8 @@ static int sb_encrypt_image(struct sb_image_ctx *ictx) * Key dictionary. */ sb_aes_reinit(ictx, 1); - sb_encrypt_key_dictionary_key(ictx); + if (ictx->encrypted) + sb_encrypt_key_dictionary_key(ictx); /* * Section tags. @@ -1609,10 +1617,10 @@ static int sb_prefill_image_header(struct sb_image_ctx *ictx) hdr->timestamp_us = sb_get_timestamp() * 1000000; /* FIXME -- add proper config option */ - hdr->flags = ictx->verbose_boot ? SB_IMAGE_FLAG_VERBOSE : 0, + hdr->flags = ictx->verbose_boot ? SB_IMAGE_FLAG_VERBOSE : 0; /* FIXME -- We support only default key */ - hdr->key_count = 1; + hdr->key_count = ictx->encrypted ? 1 : 0; return 0; } @@ -2450,7 +2458,7 @@ static int sb_build_image(struct sb_image_ctx *ictx) /* Calculate image size. */ uint32_t size = sizeof(*sb_header) + ictx->sect_count * sizeof(struct sb_sections_header) + - sizeof(*sb_dict_key) + sizeof(ictx->digest); + sizeof(*sb_dict_key) * sb_header->key_count + sizeof(ictx->digest); sctx = ictx->sect_head; while (sctx) { @@ -2473,8 +2481,10 @@ static int sb_build_image(struct sb_image_ctx *ictx) sctx = sctx->sect; }; - memcpy(iptr, sb_dict_key, sizeof(*sb_dict_key)); - iptr += sizeof(*sb_dict_key); + if (ictx->encrypted) { + memcpy(iptr, sb_dict_key, sizeof(*sb_dict_key)); + iptr += sizeof(*sb_dict_key); + } sctx = ictx->sect_head; while (sctx) { @@ -2516,27 +2526,20 @@ static int sb_build_image(struct sb_image_ctx *ictx) return 0; } -static int mxsimage_generate(const char *configfile, const char *imagefile) +static int mxsimage_generate(struct sb_image_ctx *ctx) { int ret; - struct sb_image_ctx ctx; - - memset(&ctx, 0, sizeof(ctx)); - ctx.cfg_filename = configfile; - ctx.output_filename = imagefile; - ctx.verbose_boot = 1; - - ret = sb_build_tree_from_cfg(&ctx); + ret = sb_build_tree_from_cfg(ctx); if (ret) goto fail; - ret = sb_encrypt_image(&ctx); + ret = sb_encrypt_image(ctx); if (!ret) - ret = sb_build_image(&ctx); + ret = sb_build_image(ctx); fail: - sb_free_image(&ctx); + sb_free_image(ctx); return ret; } @@ -2546,8 +2549,12 @@ int main(int argc, char *argv[]) int ret; int opt; char *configfile = NULL, *outfile = NULL, *verify = NULL; + struct sb_image_ctx ctx = { + .encrypted = 1, + .verbose_boot = 1, + }; - while ((opt = getopt(argc, argv, "p:b:c:o:v:")) != -1) { + while ((opt = getopt(argc, argv, "p:b:c:o:v:u")) != -1) { switch (opt) { case 'p': prepfile = optarg; @@ -2564,6 +2571,9 @@ int main(int argc, char *argv[]) case 'v': verify = optarg; break; + case 'u': + ctx.encrypted = 0; + break; default: exit(1); } @@ -2587,7 +2597,10 @@ int main(int argc, char *argv[]) exit(1); } - ret = mxsimage_generate(configfile, outfile); + ctx.cfg_filename = configfile; + ctx.output_filename = outfile; + + ret = mxsimage_generate(&ctx); if (ret) exit(1); -- cgit v1.2.3 From 3c8ec2338b7a8e4e6e23a9f7067f3ed6dcdeba12 Mon Sep 17 00:00:00 2001 From: Roland Hieber Date: Mon, 13 Aug 2018 15:02:48 +0200 Subject: images: MXS: allow generation of unencrypted bootstreams mxsimage can now build unencrypted images with -u, so make use of it in the Makefile. To keep the existing rules simple, name the generated images *.mxsbsu instead of *.mxsbs. Signed-off-by: Roland Hieber Signed-off-by: Sascha Hauer --- images/Makefile.mxs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/images/Makefile.mxs b/images/Makefile.mxs index 93d43b3529..aab883202a 100644 --- a/images/Makefile.mxs +++ b/images/Makefile.mxs @@ -10,6 +10,14 @@ quiet_cmd_mxs_bootstream = MXS-BOOTSTREAM $@ $(obj)/%.mxsbs: $(obj)/%.pblx $(obj)/prep_%.pblb FORCE $(call if_changed,mxs_bootstream) +# %.mxsbsu - convert into unencrypted MXS BootStream image +# ---------------------------------------------------------------- +quiet_cmd_mxs_bootstream_u = MXS-BOOTSTREAM-U $@ + cmd_mxs_bootstream_u = $(objtree)/scripts/mxsimage -u -c $(CFG_$(@F)) -b $< -o $@ -p $(word 2,$^) + +$(obj)/%.mxsbsu: $(obj)/%.pblx $(obj)/prep_%.pblb FORCE + $(call if_changed,mxs_bootstream_u) + # %.mxssd - convert into MXS SD card image # ---------------------------------------------------------------- quiet_cmd_mxs_sd = MXS-SD $@ -- cgit v1.2.3 From b9d14c715e75a12ac6689742982170d2f218081a Mon Sep 17 00:00:00 2001 From: Roland Hieber Date: Mon, 13 Aug 2018 15:02:49 +0200 Subject: ARM: MXS: i.MX28: allow setup of low-voltage SDRAM The PINCTRL_*_DDR_MODE_* defines are now needed in global scope, so move them to the respective include header. Signed-off-by: Roland Hieber Signed-off-by: Sascha Hauer --- arch/arm/boards/duckbill/lowlevel.c | 3 ++- arch/arm/boards/freescale-mx28-evk/lowlevel.c | 3 ++- arch/arm/boards/karo-tx28/lowlevel.c | 3 ++- arch/arm/mach-mxs/include/mach/init.h | 7 ++++++- arch/arm/mach-mxs/mem-init.c | 9 +++------ 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/arch/arm/boards/duckbill/lowlevel.c b/arch/arm/boards/duckbill/lowlevel.c index 2922e40f2a..3adda68d77 100644 --- a/arch/arm/boards/duckbill/lowlevel.c +++ b/arch/arm/boards/duckbill/lowlevel.c @@ -55,7 +55,8 @@ static noinline void duckbill_init(void) pr_debug("initializing SDRAM...\n"); - mx28_mem_init(mx28_dram_vals_default); + 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/lowlevel.c b/arch/arm/boards/freescale-mx28-evk/lowlevel.c index 4d45a03ba2..9df60210e6 100644 --- a/arch/arm/boards/freescale-mx28-evk/lowlevel.c +++ b/arch/arm/boards/freescale-mx28-evk/lowlevel.c @@ -47,7 +47,8 @@ static noinline void freescale_mx28evk_init(void) pr_debug("initializing SDRAM...\n"); - mx28_mem_init(mx28_dram_vals_default); + 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/lowlevel.c b/arch/arm/boards/karo-tx28/lowlevel.c index d072637de7..99f8a562cc 100644 --- a/arch/arm/boards/karo-tx28/lowlevel.c +++ b/arch/arm/boards/karo-tx28/lowlevel.c @@ -47,7 +47,8 @@ static noinline void karo_tx28_init(void) pr_debug("initializing SDRAM...\n"); - mx28_mem_init(mx28_dram_vals_default); + mx28_mem_init(PINCTRL_EMI_DS_CTRL_DDR_MODE_DDR2, + mx28_dram_vals_default); pr_debug("DONE\n"); } diff --git a/arch/arm/mach-mxs/include/mach/init.h b/arch/arm/mach-mxs/include/mach/init.h index 6526d303a1..7021981d41 100644 --- a/arch/arm/mach-mxs/include/mach/init.h +++ b/arch/arm/mach-mxs/include/mach/init.h @@ -21,8 +21,13 @@ 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); diff --git a/arch/arm/mach-mxs/mem-init.c b/arch/arm/mach-mxs/mem-init.c index ac8bfee18e..7bc6be00b4 100644 --- a/arch/arm/mach-mxs/mem-init.c +++ b/arch/arm/mach-mxs/mem-init.c @@ -318,18 +318,15 @@ 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 -- cgit v1.2.3 From 59871972698b5587829d3bbb0639f8ccde2587cb Mon Sep 17 00:00:00 2001 From: Roland Hieber Date: Mon, 13 Aug 2018 15:02:50 +0200 Subject: ARM: MXS: allow configuration of EMI clock prescaler Allow to set not only the fractional divider, but also the prescaler for the EMI clock in mxs_mem_init_clock(), and rename the parameters accordingly to reflect the change. Port the existing board code to set up the EMI clock explicitely with the old values. Also fix the off-by-a-half error in the comments, which did not take the prescaler of 2 into account, on which the fractional divider is applied (according to the i.MX23/i.MX28 Reference Manuals) Signed-off-by: Roland Hieber Signed-off-by: Sascha Hauer --- arch/arm/boards/duckbill/lowlevel.c | 2 ++ arch/arm/boards/freescale-mx28-evk/lowlevel.c | 2 ++ arch/arm/boards/imx233-olinuxino/lowlevel.c | 2 ++ arch/arm/boards/karo-tx28/lowlevel.c | 2 ++ arch/arm/mach-mxs/include/mach/init.h | 2 +- arch/arm/mach-mxs/mem-init.c | 19 +++++++++---------- 6 files changed, 18 insertions(+), 11 deletions(-) diff --git a/arch/arm/boards/duckbill/lowlevel.c b/arch/arm/boards/duckbill/lowlevel.c index 3adda68d77..cb60667323 100644 --- a/arch/arm/boards/duckbill/lowlevel.c +++ b/arch/arm/boards/duckbill/lowlevel.c @@ -55,6 +55,8 @@ static noinline void duckbill_init(void) pr_debug("initializing SDRAM...\n"); + /* 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); diff --git a/arch/arm/boards/freescale-mx28-evk/lowlevel.c b/arch/arm/boards/freescale-mx28-evk/lowlevel.c index 9df60210e6..2c8d27e801 100644 --- a/arch/arm/boards/freescale-mx28-evk/lowlevel.c +++ b/arch/arm/boards/freescale-mx28-evk/lowlevel.c @@ -47,6 +47,8 @@ static noinline void freescale_mx28evk_init(void) pr_debug("initializing SDRAM...\n"); + /* 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); diff --git a/arch/arm/boards/imx233-olinuxino/lowlevel.c b/arch/arm/boards/imx233-olinuxino/lowlevel.c index 63a65230b0..bfb50be717 100644 --- a/arch/arm/boards/imx233-olinuxino/lowlevel.c +++ b/arch/arm/boards/imx233-olinuxino/lowlevel.c @@ -159,6 +159,8 @@ static noinline void imx23_olinuxino_init(void) 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 99f8a562cc..abc223d3b4 100644 --- a/arch/arm/boards/karo-tx28/lowlevel.c +++ b/arch/arm/boards/karo-tx28/lowlevel.c @@ -47,6 +47,8 @@ static noinline void karo_tx28_init(void) pr_debug("initializing SDRAM...\n"); + /* 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); diff --git a/arch/arm/mach-mxs/include/mach/init.h b/arch/arm/mach-mxs/include/mach/init.h index 7021981d41..66dfd635de 100644 --- a/arch/arm/mach-mxs/include/mach/init.h +++ b/arch/arm/mach-mxs/include/mach/init.h @@ -30,7 +30,7 @@ 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 7bc6be00b4..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 @@ -322,9 +324,6 @@ 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 DDR mode */ writel(emi_ds_ctrl_ddr_mode, IMX_IOMUXC_BASE + 0x1b80); -- cgit v1.2.3 From 1c1f94ecc2cf658b751847306a913acc209af64d Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 13 Aug 2018 15:02:51 +0200 Subject: ARM: i.MX28: Add memory size detection We can detect the SDRAM automatically, no need to let the boards do it manually. This also fixes device tree based i.MX28 boards like the duckbill. These boards once had a /memory node in the device tree, but now that this was changed to /memory@40000000 barebox didn't find it anymore. Signed-off-by: Sascha Hauer Tested-by: Roland Hieber Signed-off-by: Roland Hieber Signed-off-by: Sascha Hauer --- arch/arm/boards/crystalfontz-cfa10036/cfa10036.c | 24 ------------------- arch/arm/boards/freescale-mx28-evk/mx28-evk.c | 8 ------- arch/arm/boards/karo-tx28/tx28.c | 8 ------- arch/arm/mach-mxs/include/mach/imx28.h | 30 ++++++++++++++++++++++++ arch/arm/mach-mxs/soc-imx28.c | 4 ++++ 5 files changed, 34 insertions(+), 40 deletions(-) create mode 100644 arch/arm/mach-mxs/include/mach/imx28.h 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/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/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/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 +#include + +#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/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 #include #include +#include +#include #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); -- cgit v1.2.3 From 7158c5987e6999f1fd89b7170c685a7b29bc8322 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 13 Aug 2018 15:02:52 +0200 Subject: ARM: i.MX23: Add memory size detection No need for the boards to manually add memory, we can do this automatically by reading back the memory size from the SDRAM controller. Signed-off-by: Sascha Hauer Signed-off-by: Roland Hieber Signed-off-by: Sascha Hauer --- arch/arm/boards/chumby_falconwing/falconwing.c | 8 ------ arch/arm/boards/freescale-mx23-evk/mx23-evk.c | 8 ------ arch/arm/boards/imx233-olinuxino/imx23-olinuxino.c | 8 ------ arch/arm/mach-mxs/include/mach/imx23.h | 29 ++++++++++++++++++++++ arch/arm/mach-mxs/soc-imx23.c | 4 +++ 5 files changed, 33 insertions(+), 24 deletions(-) create mode 100644 arch/arm/mach-mxs/include/mach/imx23.h 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/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/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/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 +#include + +#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/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 #include #include +#include +#include #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; -- cgit v1.2.3 From e85280472f58496f451d75ad139aedba3793ab91 Mon Sep 17 00:00:00 2001 From: Roland Hieber Date: Mon, 13 Aug 2018 15:02:53 +0200 Subject: ARM: MXS: refactor mx2*_power_init source configuration Having three ints as parameter suggests that we can use up to 2^3 power configurations for the system, but when we look at the code, the power setup is packaged in if {...} else if {...} else if {...} blocks, so setting more than one parameter to 1 is useless here. Refactor the parameters into an enum to get rid of that suggestion. Signed-off-by: Roland Hieber Signed-off-by: Sascha Hauer --- arch/arm/boards/duckbill/lowlevel.c | 2 +- arch/arm/boards/freescale-mx28-evk/lowlevel.c | 2 +- arch/arm/boards/imx233-olinuxino/lowlevel.c | 2 +- arch/arm/boards/karo-tx28/lowlevel.c | 2 +- arch/arm/mach-mxs/include/mach/init.h | 24 ++++++++++--- arch/arm/mach-mxs/power-init.c | 49 ++++++++++----------------- 6 files changed, 41 insertions(+), 40 deletions(-) diff --git a/arch/arm/boards/duckbill/lowlevel.c b/arch/arm/boards/duckbill/lowlevel.c index cb60667323..3f8e4ad271 100644 --- a/arch/arm/boards/duckbill/lowlevel.c +++ b/arch/arm/boards/duckbill/lowlevel.c @@ -51,7 +51,7 @@ static noinline void duckbill_init(void) pr_debug("initializing power...\n"); - mx28_power_init(0, 0, 1); + mx28_power_init(POWER_USE_5V); pr_debug("initializing SDRAM...\n"); diff --git a/arch/arm/boards/freescale-mx28-evk/lowlevel.c b/arch/arm/boards/freescale-mx28-evk/lowlevel.c index 2c8d27e801..b6a8793c9e 100644 --- a/arch/arm/boards/freescale-mx28-evk/lowlevel.c +++ b/arch/arm/boards/freescale-mx28-evk/lowlevel.c @@ -43,7 +43,7 @@ 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); pr_debug("initializing SDRAM...\n"); diff --git a/arch/arm/boards/imx233-olinuxino/lowlevel.c b/arch/arm/boards/imx233-olinuxino/lowlevel.c index bfb50be717..c6cf26b61d 100644 --- a/arch/arm/boards/imx233-olinuxino/lowlevel.c +++ b/arch/arm/boards/imx233-olinuxino/lowlevel.c @@ -154,7 +154,7 @@ static noinline void imx23_olinuxino_init(void) pr_debug("initializing power...\n"); - mx23_power_init(0, 0, 1); + mx23_power_init(POWER_USE_5V); pr_debug("initializing SDRAM...\n"); diff --git a/arch/arm/boards/karo-tx28/lowlevel.c b/arch/arm/boards/karo-tx28/lowlevel.c index abc223d3b4..5a6a3e3519 100644 --- a/arch/arm/boards/karo-tx28/lowlevel.c +++ b/arch/arm/boards/karo-tx28/lowlevel.c @@ -43,7 +43,7 @@ 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); pr_debug("initializing SDRAM...\n"); diff --git a/arch/arm/mach-mxs/include/mach/init.h b/arch/arm/mach-mxs/include/mach/init.h index 66dfd635de..878cf4ad62 100644 --- a/arch/arm/mach-mxs/include/mach/init.h +++ b/arch/arm/mach-mxs/include/mach/init.h @@ -12,10 +12,26 @@ 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 + */ +enum mxs_power_config { + POWER_USE_5V = 0b00000000, + POWER_USE_BATTERY = 0b00000001, + POWER_USE_BATTERY_INPUT = 0b00000010, +}; +extern int power_config; +static inline enum mxs_power_config mxs_power_config_get_use(void) { + return (power_config & 0b00000011); +} + + +void mx23_power_init(const int config); +void mx28_power_init(const int config); void mxs_power_wait_pswitch(void); extern const uint32_t mx28_dram_vals_default[190]; diff --git a/arch/arm/mach-mxs/power-init.c b/arch/arm/mach-mxs/power-init.c index 595b51c5ba..14f9b7cca7 100644 --- a/arch/arm/mach-mxs/power-init.c +++ b/arch/arm/mach-mxs/power-init.c @@ -24,21 +24,7 @@ #include #include -/* - * 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) { @@ -514,7 +500,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; @@ -1182,16 +1169,15 @@ static void mx23_ungate_power(void) * * 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 */ -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_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 +1190,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(); @@ -1243,16 +1229,15 @@ void mx23_power_init(int __has_battery, int __use_battery_input, * * 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 */ -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_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 +1249,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(); -- cgit v1.2.3 From f726f184e4dedf06dd4d1d6071f3dd4b24e82cd5 Mon Sep 17 00:00:00 2001 From: Roland Hieber Date: Mon, 13 Aug 2018 15:02:54 +0200 Subject: ARM: MXS: allow starting from battery input without 4P2 source enabled Some boards don't need the 4.2V power source at all, so allow them to keep it disabled for efficiency reasons. For backwards compatibility, don't disable the 4P2 power source on the existing boards which are supplied from battery input. The POWER_USE_5V code path however always enables it up as it is needed to supply the DC-DC converter. Signed-off-by: Roland Hieber Signed-off-by: Sascha Hauer --- arch/arm/boards/freescale-mx28-evk/lowlevel.c | 2 +- arch/arm/boards/karo-tx28/lowlevel.c | 2 +- arch/arm/mach-mxs/include/mach/init.h | 2 ++ arch/arm/mach-mxs/power-init.c | 3 ++- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/arm/boards/freescale-mx28-evk/lowlevel.c b/arch/arm/boards/freescale-mx28-evk/lowlevel.c index b6a8793c9e..fdaef959a3 100644 --- a/arch/arm/boards/freescale-mx28-evk/lowlevel.c +++ b/arch/arm/boards/freescale-mx28-evk/lowlevel.c @@ -43,7 +43,7 @@ static noinline void freescale_mx28evk_init(void) pr_debug("initializing power...\n"); - mx28_power_init(POWER_USE_BATTERY_INPUT); + mx28_power_init(POWER_USE_BATTERY_INPUT | POWER_ENABLE_4P2); pr_debug("initializing SDRAM...\n"); diff --git a/arch/arm/boards/karo-tx28/lowlevel.c b/arch/arm/boards/karo-tx28/lowlevel.c index 5a6a3e3519..a9b65167cd 100644 --- a/arch/arm/boards/karo-tx28/lowlevel.c +++ b/arch/arm/boards/karo-tx28/lowlevel.c @@ -43,7 +43,7 @@ static noinline void karo_tx28_init(void) pr_debug("initializing power...\n"); - mx28_power_init(POWER_USE_BATTERY_INPUT); + mx28_power_init(POWER_USE_BATTERY_INPUT | POWER_ENABLE_4P2); pr_debug("initializing SDRAM...\n"); diff --git a/arch/arm/mach-mxs/include/mach/init.h b/arch/arm/mach-mxs/include/mach/init.h index 878cf4ad62..aa3c68facb 100644 --- a/arch/arm/mach-mxs/include/mach/init.h +++ b/arch/arm/mach-mxs/include/mach/init.h @@ -18,11 +18,13 @@ void mxs_early_delay(int delay); * - 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) { diff --git a/arch/arm/mach-mxs/power-init.c b/arch/arm/mach-mxs/power-init.c index 14f9b7cca7..60fa0cb022 100644 --- a/arch/arm/mach-mxs/power-init.c +++ b/arch/arm/mach-mxs/power-init.c @@ -717,7 +717,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(); } /** -- cgit v1.2.3 From e3df3607a4e14bd60d67bc68b8687bb9657d183e Mon Sep 17 00:00:00 2001 From: Roland Hieber Date: Mon, 13 Aug 2018 15:02:55 +0200 Subject: ARM: MXS: make power levels configurable in mx2*_power_init Depending on the application, board code might want to configure different power levels and brownout thresholds. They can do so now with an additional struct mxs_power_ctrls* parameter to mx2*_power_init. Note that VDDMEM was not set up explicitely in mx28_power_init, but can now be configured. However, mx28_power_default->vddmem is NULL, so the old behaviour is still the case when using those default values. Signed-off-by: Roland Hieber Signed-off-by: Sascha Hauer --- arch/arm/boards/duckbill/lowlevel.c | 2 +- arch/arm/boards/freescale-mx28-evk/lowlevel.c | 3 +- arch/arm/boards/imx233-olinuxino/lowlevel.c | 2 +- arch/arm/boards/karo-tx28/lowlevel.c | 3 +- arch/arm/mach-mxs/include/mach/init.h | 22 ++++++++++- arch/arm/mach-mxs/power-init.c | 55 ++++++++++++++++++++++----- 6 files changed, 72 insertions(+), 15 deletions(-) diff --git a/arch/arm/boards/duckbill/lowlevel.c b/arch/arm/boards/duckbill/lowlevel.c index 3f8e4ad271..22987a6cdb 100644 --- a/arch/arm/boards/duckbill/lowlevel.c +++ b/arch/arm/boards/duckbill/lowlevel.c @@ -51,7 +51,7 @@ static noinline void duckbill_init(void) pr_debug("initializing power...\n"); - mx28_power_init(POWER_USE_5V); + mx28_power_init(POWER_USE_5V, &mx28_power_default); pr_debug("initializing SDRAM...\n"); diff --git a/arch/arm/boards/freescale-mx28-evk/lowlevel.c b/arch/arm/boards/freescale-mx28-evk/lowlevel.c index fdaef959a3..22cae1374c 100644 --- a/arch/arm/boards/freescale-mx28-evk/lowlevel.c +++ b/arch/arm/boards/freescale-mx28-evk/lowlevel.c @@ -43,7 +43,8 @@ static noinline void freescale_mx28evk_init(void) pr_debug("initializing power...\n"); - mx28_power_init(POWER_USE_BATTERY_INPUT | POWER_ENABLE_4P2); + mx28_power_init(POWER_USE_BATTERY_INPUT | POWER_ENABLE_4P2, + &mx28_power_default); pr_debug("initializing SDRAM...\n"); diff --git a/arch/arm/boards/imx233-olinuxino/lowlevel.c b/arch/arm/boards/imx233-olinuxino/lowlevel.c index c6cf26b61d..5f36c17e52 100644 --- a/arch/arm/boards/imx233-olinuxino/lowlevel.c +++ b/arch/arm/boards/imx233-olinuxino/lowlevel.c @@ -154,7 +154,7 @@ static noinline void imx23_olinuxino_init(void) pr_debug("initializing power...\n"); - mx23_power_init(POWER_USE_5V); + mx23_power_init(POWER_USE_5V, &mx23_power_default); pr_debug("initializing SDRAM...\n"); diff --git a/arch/arm/boards/karo-tx28/lowlevel.c b/arch/arm/boards/karo-tx28/lowlevel.c index a9b65167cd..1a93be747d 100644 --- a/arch/arm/boards/karo-tx28/lowlevel.c +++ b/arch/arm/boards/karo-tx28/lowlevel.c @@ -43,7 +43,8 @@ static noinline void karo_tx28_init(void) pr_debug("initializing power...\n"); - mx28_power_init(POWER_USE_BATTERY_INPUT | POWER_ENABLE_4P2); + mx28_power_init(POWER_USE_BATTERY_INPUT | POWER_ENABLE_4P2, + &mx28_power_default); pr_debug("initializing SDRAM...\n"); diff --git a/arch/arm/mach-mxs/include/mach/init.h b/arch/arm/mach-mxs/include/mach/init.h index aa3c68facb..53c1e05634 100644 --- a/arch/arm/mach-mxs/include/mach/init.h +++ b/arch/arm/mach-mxs/include/mach/init.h @@ -32,8 +32,26 @@ static inline enum mxs_power_config mxs_power_config_get_use(void) { } -void mx23_power_init(const int config); -void mx28_power_init(const int config); +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]; diff --git a/arch/arm/mach-mxs/power-init.c b/arch/arm/mach-mxs/power-init.c index 60fa0cb022..490ea4ba2d 100644 --- a/arch/arm/mach-mxs/power-init.c +++ b/arch/arm/mach-mxs/power-init.c @@ -1165,6 +1165,17 @@ 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 * @@ -1172,8 +1183,9 @@ static void mx23_ungate_power(void) * 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(const int config) +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; @@ -1210,10 +1222,18 @@ void mx23_power_init(const int config) 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 | @@ -1225,6 +1245,13 @@ void mx23_power_init(const int config) 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 * @@ -1232,8 +1259,9 @@ void mx23_power_init(const int config) * 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(const int config) +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; @@ -1265,9 +1293,18 @@ void mx28_power_init(const int config) 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 | -- cgit v1.2.3 From 7005932ca66cdc0a91cdae0bf99d790e0c108fe2 Mon Sep 17 00:00:00 2001 From: Roland Hieber Date: Mon, 13 Aug 2018 15:02:56 +0200 Subject: ARM: MXS: fix VDDx brownout setup logic The cfg->bo_irq and cfg->bo_enirq (i.e. VDDx_BO_IRQ and ENIRQ_VDDx_BO) flags are part of POWER_CTRL, so setting those flag in cfg->reg (i.e. POWER_VDDxCTRL) makes no sense. Fortunately, those bits are reserved in ENIRQ_VDDx_BO, so writing them did no harm, but also doesn't work as intended. Signed-off-by: Roland Hieber Signed-off-by: Sascha Hauer --- arch/arm/mach-mxs/power-init.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-mxs/power-init.c b/arch/arm/mach-mxs/power-init.c index 490ea4ba2d..6796a4491d 100644 --- a/arch/arm/mach-mxs/power-init.c +++ b/arch/arm/mach-mxs/power-init.c @@ -1083,8 +1083,8 @@ static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg, if (adjust_up && cfg->bo_irq) { if (powered_by_linreg) { - bo_int = readl(cfg->reg); - clrbits_le32(cfg->reg, cfg->bo_enirq); + bo_int = readl(&power_regs->hw_power_ctrl); + writel(cfg->bo_enirq, &power_regs->hw_power_ctrl_clr); } setbits_le32(cfg->reg, cfg->bo_offset_mask); } @@ -1126,7 +1126,7 @@ static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg, if (adjust_up && powered_by_linreg) { writel(cfg->bo_irq, &power_regs->hw_power_ctrl_clr); if (bo_int & cfg->bo_enirq) - setbits_le32(cfg->reg, cfg->bo_enirq); + writel(cfg->bo_enirq, &power_regs->hw_power_ctrl_set); } clrsetbits_le32(cfg->reg, cfg->bo_offset_mask, -- cgit v1.2.3 From 8b21dfca002ca9c7fe0906e7b9747ef392c3a9ae Mon Sep 17 00:00:00 2001 From: Roland Hieber Date: Mon, 13 Aug 2018 15:02:57 +0200 Subject: ARM: MXS: make VDDx brownout setup more understandable Rename bo_int to prev_bo_enirq to make its purpose clearer, and throw in a few comments for easier understanding. Signed-off-by: Roland Hieber Signed-off-by: Sascha Hauer --- arch/arm/mach-mxs/power-init.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-mxs/power-init.c b/arch/arm/mach-mxs/power-init.c index 6796a4491d..9ab36463e2 100644 --- a/arch/arm/mach-mxs/power-init.c +++ b/arch/arm/mach-mxs/power-init.c @@ -1066,7 +1066,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; @@ -1082,8 +1082,10 @@ 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(&power_regs->hw_power_ctrl); + 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); @@ -1124,8 +1126,10 @@ 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) + if (prev_bo_enirq) + /* re-enable brownout IRQ after adjustment has finished */ writel(cfg->bo_enirq, &power_regs->hw_power_ctrl_set); } -- cgit v1.2.3 From 6e03b1f8200b6db12c5d1268e38cbb2383673022 Mon Sep 17 00:00:00 2001 From: Roland Hieber Date: Mon, 13 Aug 2018 15:02:58 +0200 Subject: ARM: MXS: mxs_power_status: use less magic values ... and in that process fix the erroneous usage of VDDA values when printing the stats for POWER_VDDDCTRL_DISABLE_FET and all of the *LINREG_OFFSET bitfields. Signed-off-by: Roland Hieber Signed-off-by: Sascha Hauer --- arch/arm/mach-mxs/power-init.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/arch/arm/mach-mxs/power-init.c b/arch/arm/mach-mxs/power-init.c index 9ab36463e2..b3b0db666f 100644 --- a/arch/arm/mach-mxs/power-init.c +++ b/arch/arm/mach-mxs/power-init.c @@ -37,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); +#define __REG_BITS(value, fieldname) (((value) & fieldname##_MASK) >> fieldname##_OFFSET) + 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"); + __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: %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"); + __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: %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"); + __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: %dmV (BO -%dmV), Linreg %sabled\n", - (vddmem & 0x1f) * 25 + 1100, - ((vddmem >> 5) & 0x7) * 25, - (vddmem & (1 << 8)) ? "en" : "dis"); + __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"); } /* -- cgit v1.2.3 From d022e2c4677987875a5d1598271c9fad7aff899b Mon Sep 17 00:00:00 2001 From: Roland Hieber Date: Mon, 13 Aug 2018 15:02:59 +0200 Subject: ARM: MXS: mxs_power_status: align output Exemplary previous behaviour: vddio: 3100mV (BO -200mV), Linreg enabled, Linreg offset: -1, FET enabled vdda: 1800mV (BO -175mV), Linreg disabled, Linreg offset: -1, FET enabled vddd: 1200mV (BO -175mV), Linreg enabled, Linreg offset: -1, FET disabled vddmem: 1500mV (BO -25mV), Linreg disabled After this patch this looks much cleaner: vddio: 3100mV (BO -200mV), Linreg enabled, Linreg offset: -1, FET enabled vdda: 1800mV (BO -175mV), Linreg disabled, Linreg offset: -1, FET enabled vddd: 1200mV (BO -175mV), Linreg enabled, Linreg offset: -1, FET disabled vddmem: 1500mV (BO - 25mV), Linreg disabled Signed-off-by: Roland Hieber Signed-off-by: Sascha Hauer --- arch/arm/mach-mxs/power-init.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-mxs/power-init.c b/arch/arm/mach-mxs/power-init.c index b3b0db666f..ca7c349d7f 100644 --- a/arch/arm/mach-mxs/power-init.c +++ b/arch/arm/mach-mxs/power-init.c @@ -39,28 +39,28 @@ static void mxs_power_status(void) #define __REG_BITS(value, fieldname) (((value) & fieldname##_MASK) >> fieldname##_OFFSET) - printf("vddio: %dmV (BO -%dmV), Linreg enabled, Linreg offset: %d, FET %sabled\n", + 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: %dmV (BO -%dmV), Linreg %sabled, Linreg offset: %d, FET %sabled\n", + (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", + (vdda & POWER_VDDACTRL_ENABLE_LINREG) ? " en" : "dis", linregofs[__REG_BITS(vdda, POWER_VDDACTRL_LINREG_OFFSET)], - (vdda & POWER_VDDACTRL_DISABLE_FET) ? "dis" : "en"); - printf("vddd: %dmV (BO -%dmV), Linreg %sabled, Linreg offset: %d, FET %sabled\n", + (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", + (vddd & POWER_VDDDCTRL_ENABLE_LINREG) ? " en" : "dis", linregofs[__REG_BITS(vddd, POWER_VDDDCTRL_LINREG_OFFSET)], - (vddd & POWER_VDDDCTRL_DISABLE_FET) ? "dis" : "en"); - printf("vddmem: %dmV (BO -%dmV), Linreg %sabled\n", + (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"); + (vddmem & POWER_VDDMEMCTRL_ENABLE_LINREG) ? " en" : "dis"); } /* -- cgit v1.2.3 From 0079d4f1bc4005f859f55bdead10811dc70f6e28 Mon Sep 17 00:00:00 2001 From: Roland Hieber Date: Mon, 13 Aug 2018 15:03:00 +0200 Subject: Documentation: MXS: general update and improvements Go more into detail about the relationship of the prepare stage and the bootloader image, and about the generated images. Also don't use mxs-usb-loader anymore since it has been removed. Fixes: 3ca576cc4a4236a2556ab17 "scripts: imx/mxs remove mxs-usb-loader" Signed-off-by: Roland Hieber Signed-off-by: Sascha Hauer --- Documentation/boards/mxs.rst | 97 ++++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 44 deletions(-) diff --git a/Documentation/boards/mxs.rst b/Documentation/boards/mxs.rst index feb024227a..53de4c1096 100644 --- a/Documentation/boards/mxs.rst +++ b/Documentation/boards/mxs.rst @@ -3,71 +3,83 @@ Freescale MXS Freescale i.MXs or MXS are a SoC family which consists of the i.MX23 and the i.MX28. These are quite different from the regular i.MX SoCs -and thus are represented by their own architecture in both the Kernel -and barebox. +and thus are represented by their own architecture in both the kernel +and in barebox. Bootlets -------- -Traditionally These SoCs need the Freescale bootlets source and the -elf2sb2 binary to build a bootable image out of the barebox binary. -Since the bootlets are board specific and the source code is only -hardly customisable each vendor usually has his own slightly different +Traditionally these SoCs need the Freescale bootlets source and the +*elf2sb2* binary to set up the PMIC and SDRAM, and to build a bootable +image out of the barebox binary. +Since the bootlets are board-specific and the source code is only +hardly customisable, each vendor usually has their own slightly different version of the bootlets. Booting with the Freescale bootlets is not -described here, refer to the bootlet sourcecode or your vendors +described here, refer to the bootlet source code or your vendor's documentation instead. -U-Boot and barebox have a port of the bootlets integrated into their -source. The barebox bootlet code is derived from the U-Boot bootlet -code written by Marek Vasut. +Barebox has a port of the bootlets integrated into its source, which is +derived from the U-Boot bootlet code written by Marek Vasut. -Currently only the Karo TX28 is supported by the barebox bootlets, -but we recommend that this approach should be followed for new boards -and existing boards should be ported over. +Most MXS boards in the barebox tree have been ported to use barebox bootlets and +image generation, and we recommend this approach for new boards too. Booting Freescale i.MXs ----------------------- The Freescale MXS SoCs have a multi staged boot process which needs different images composed out of different binaries. The ROM executes -a so called bootstream which contains multiple executables. The first -one is executed in SRAM and the purpose of this binary is to setup -the internal PMIC and the SDRAM. The second image is usually the -bootloader itself. In case of barebox the bootstream is composed -out of the self extracting barebox image (pblx) and the prepare -stage for setting up the SDRAM. +a so called *bootstream* which can contain multiple executables. + +The first executable (the prepare stage) is only a small binary executed in +SRAM, which has a limited size of 128 KB. Its purpose is to setup the internal +PMIC and the SDRAM, and then jump back to the MXS ROM code, which then maps the +second executable (the full bootloader) into SDRAM and executes it. +In case of barebox, the bootstream (``*-bootstream.img``) is composed of the +self extracting barebox image (``*.pblx``) and the prepare stage +(``prep_*.pblb``). The file name of those images reflects the name of the +respective entry points. The bootstream image itself is useful for USB boot, but for booting from SD cards or NAND a BCB header has to be prepended to the image. In case -of SD boot the image has the .mxssd file extension in barebox. +of SD boot the image is named ``*-sd.img``. + +Bootstream images can be unencrypted or encrypted. Depending on the OCOTP fuses +of your chip, you might need the one or the other to boot the board. -Since the bootstream images are encrypted they are not suitable for -2nd stage execution. For this purpose the 2nd stage images are generated. +Since some of the bootstream images are encrypted, they are not suitable for +2nd stage execution. For this purpose a 2nd stage image with the name +``*-2nd.img`` is generated. Booting from USB ---------------- -barebox has the mxs-usb-loader tool (derived from the sbloader tool from -the rockbox project). If the board is connected to the PC and started in -USB Boot mode it should show up in lsusb:: +If enabled in *menuconfig* → *System Type*, barebox builds the *imx-usb-loader* +tool (derived from the *sbloader* tool from the rockbox project), which can +load images onto MXS SoCs over USB. (Refer to the documentation of your board +how to get it into USB boot mode.) + +If the board is connected to the PC and started in USB boot mode, it should +show up in lsusb:: Bus 001 Device 098: ID 15a2:004f Freescale Semiconductor, Inc. i.MX28 SystemOnChip in RecoveryMode -The bootstream images can be directly booted with:: +The bootstream images can then directly be booted with:: - ./scripts/mxs-usb-loader 0 images/barebox-karo-tx28-bootstream.img + ./scripts/imx-usb-loader images/barebox-karo-tx28-bootstream.img -You might require appropriate udev rules or sudo to gain the rights to +You might require appropriate udev rules or *sudo* to gain the rights to access the USB device. Booting from SD cards --------------------- -The SD images are suitable for booting from SD cards. SD cards need a special -partitioning which can be created with the following fdisk sequence (using -/dev/sdg as example):: +The SD images are suitable for booting from SD cards. The MXS SoCs require a +special partition of type 0x53 (OnTrack DM6 Aux) which contains the BCB header. +The partitioning can be created with the following fdisk sequence (using +*/dev/sdg* as an example for the SD card):: - fdisk /dev/sdg + $ fdisk /dev/sdg Welcome to fdisk (util-linux 2.25.1). Changes will remain in memory only, until you decide to write them. @@ -93,24 +105,21 @@ partitioning which can be created with the following fdisk sequence (using Hex code (type L to list all codes): 53 Changed type of partition 'Linux' to 'OnTrack DM6 Aux3'. - Command (m for help): - Command (m for help): w -After writing the new partition table the image can be written directly to -the partition:: +After writing the new partition table, the image can be written directly to +the first partition:: cat images/barebox-karo-tx28-sd.img > /dev/sdg1 -** NOTE ** +.. note:: -The MXS SoCs require a special partition of type 0x53 (OnTrack DM6 Aux) -which contains the BCB header. For some unknown reason the BCB header is -inside a partition, but contains the sector number of the raw device from -which the rest of the image is read. With standard settings booting from -SD card only works if the partition containing the bootloader starts at -sector 2048 (the standard for fdisk). See the -p parameter to the mxsboot -tool which changes this sector number in the image. + For some unknown reason the BCB header is + inside a partition, but contains the sector number of the raw device from + which the rest of the image is read. With standard settings, booting from + SD card only works if the partition containing the bootloader starts at + sector 2048 (the standard for fdisk). See the *-p* parameter to the + ``scripts/mxsboot`` tool to change this sector number in the image. Booting second stage -------------------- -- cgit v1.2.3