All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nikita Kiryanov <nikita@compulab.co.il>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH V3 12/18] arm: mx6: add support for Compulab cm-fx6 CoM
Date: Tue, 19 Aug 2014 18:17:52 +0300	[thread overview]
Message-ID: <53F36AA0.3000409@compulab.co.il> (raw)
In-Reply-To: <53EB6038.4050408@compulab.co.il>

Hi Igor,

On 13/08/14 15:55, Igor Grinberg wrote:
>> +#ifdef CONFIG_FSL_ESDHC
>> +int board_mmc_init(bd_t *bis)
>> +{
>> +	int i;
>> +
>> +	cm_fx6_set_usdhc_iomux();
>> +	for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
>> +		usdhc_cfg[i].sdhc_clk = mxc_get_clock(usdhc_clk[i]);
>> +		usdhc_cfg[i].max_bus_width = 4;
>> +		fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
>> +		enable_usdhc_clk(1, i);
>
> Why does the board code needs to handle the mmc clocks?
> Can't this be handled in the common code?

It (probably) can, but it currently isn't. If we were to change this
I would prefer it to be done outside of this patch series.

>
>> +	}
>> +
>> +	return 0;
>> +}
>> +#endif
>> +
>> +int board_init(void)
>> +{
>> +	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
>> +	return 0;
>> +}
>> +
>> +int checkboard(void)
>> +{
>> +	puts("Board: CM-FX6\n");
>> +	return 0;
>> +}
>> +
>> +static ulong bank1_size;
>> +static ulong bank2_size;
>> +
>> +void dram_init_banksize(void)
>> +{
>> +	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
>> +	gd->bd->bi_dram[0].size = bank1_size;
>> +	gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
>> +	gd->bd->bi_dram[1].size = bank2_size;
>> +}
>> +
>> +int dram_init(void)
>> +{
>> +	gd->ram_size = imx_ddr_size();
>> +	switch (gd->ram_size) {
>> +	case 0x10000000: /* DDR_16BIT_256MB */
>> +		bank1_size = 0x10000000;
>> +		bank2_size = 0;
>> +		break;
>> +	case 0x20000000: /* DDR_32BIT_512MB */
>> +		bank1_size = 0x20000000;
>> +		bank2_size = 0;
>> +		break;
>> +	case 0x40000000:
>> +		if (is_cpu_type(MXC_CPU_MX6SOLO)) { /* DDR_32BIT_1GB */
>> +			bank1_size = 0x20000000;
>> +			bank2_size = 0x20000000;
>> +		} else { /* DDR_64BIT_1GB */
>> +			bank1_size = 0x40000000;
>> +			bank2_size = 0;
>
> You don't need to init bank2_size to zero in all above cases.

Actually, I'm going to refactor and eliminate these variables, because
I see that bss is not yet ready at this stage in the boot.

>
>> +		}
>> +		break;
>> +	case 0x80000000: /* DDR_64BIT_2GB */
>> +		bank1_size = 0x40000000;
>> +		bank2_size = 0x40000000;
>> +		break;
>> +	case 0xF0000000: /* DDR_64BIT_4GB */
>> +		bank1_size = 0x70000000;
>> +		bank2_size = 0x7FF00000;
>> +		gd->ram_size -= 0x100000;
>> +		break;
>> +	default:
>> +		printf("ERROR: Unsupported DRAM size 0x%lx\n", gd->ram_size);
>> +		return -1;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +u32 get_board_rev(void)
>> +{
>> +	return 100;
>
> Hmmm... cl_eeprom_get_board_rev()?

There's no I2C support in this patch.
I'll remove this function and reintroduce it later per your suggestion
in a different patch.

>> +static __maybe_unused enum mxc_clock usdhc_clk[3] = {
>> +	MXC_ESDHC_CLK,
>> +	MXC_ESDHC2_CLK,
>> +	MXC_ESDHC3_CLK,
>> +};
>
> Why do you need the above structures defined here in .h file?
> Can they live in .c file that is using them?
> I think cm_fx6.c is the appropriate place for these.

I'll move them to cm_fx6.c. The code reuse was minimal anyway..

>> +static void spl_mx6s_dram_setup_iomux(void)
>> +{
>> +	struct mx6sdl_iomux_ddr_regs ddr_iomux;
>> +	struct mx6sdl_iomux_grp_regs grp_iomux;
>> +
>> +	ddr_iomux.dram_sdqs0	= 0x00000038;
>> +	ddr_iomux.dram_sdqs1	= 0x00000038;
>> +	ddr_iomux.dram_sdqs2	= 0x00000038;
>> +	ddr_iomux.dram_sdqs3	= 0x00000038;
>> +	ddr_iomux.dram_sdqs4	= 0x00000038;
>> +	ddr_iomux.dram_sdqs5	= 0x00000038;
>> +	ddr_iomux.dram_sdqs6	= 0x00000038;
>> +	ddr_iomux.dram_sdqs7	= 0x00000038;
>> +	ddr_iomux.dram_dqm0	= 0x00000038;
>> +	ddr_iomux.dram_dqm1	= 0x00000038;
>> +	ddr_iomux.dram_dqm2	= 0x00000038;
>> +	ddr_iomux.dram_dqm3	= 0x00000038;
>> +	ddr_iomux.dram_dqm4	= 0x00000038;
>> +	ddr_iomux.dram_dqm5	= 0x00000038;
>> +	ddr_iomux.dram_dqm6	= 0x00000038;
>> +	ddr_iomux.dram_dqm7	= 0x00000038;
>> +	ddr_iomux.dram_cas	= 0x00000038;
>> +	ddr_iomux.dram_ras	= 0x00000038;
>> +	ddr_iomux.dram_sdclk_0	= 0x00000038;
>> +	ddr_iomux.dram_sdclk_1	= 0x00000038;
>> +	ddr_iomux.dram_sdcke0	= 0x00003000;
>> +	ddr_iomux.dram_sdcke1	= 0x00003000;
>> +	/*
>> +	 * Below DRAM_RESET[DDR_SEL] = 0 which is incorrect according to
>> +	 * Freescale QRM, but this is exactly the value used by the automatic
>> +	 * calibration script and it works also in all our tests, so we leave
>> +	 * it as is at this point.
>> +	 */
>> +	ddr_iomux.dram_reset	= 0x00000038;
>> +	ddr_iomux.dram_sdba2	= 0x00000000;
>> +	ddr_iomux.dram_sdodt0	= 0x00000038;
>> +	ddr_iomux.dram_sdodt1	= 0x00000038;
>> +	grp_iomux.grp_b0ds	= 0x00000038;
>> +	grp_iomux.grp_b1ds	= 0x00000038;
>> +	grp_iomux.grp_b2ds	= 0x00000038;
>> +	grp_iomux.grp_b3ds	= 0x00000038;
>> +	grp_iomux.grp_b4ds	= 0x00000038;
>> +	grp_iomux.grp_b5ds	= 0x00000038;
>> +	grp_iomux.grp_b6ds	= 0x00000038;
>> +	grp_iomux.grp_b7ds	= 0x00000038;
>> +	grp_iomux.grp_addds	= 0x00000038;
>> +	grp_iomux.grp_ddrmode_ctl = 0x00020000;
>> +	grp_iomux.grp_ddrpke	= 0x00000000;
>> +	grp_iomux.grp_ddrmode	= 0x00020000;
>> +	grp_iomux.grp_ctlds	= 0x00000038;
>> +	grp_iomux.grp_ddr_type	= 0x000C0000;
>
> Hmmm... Can we do the above initializations statically?

Yes.

> I mean, define the structures outside of the function and initialize
> them statically, and then only pass the structures to the below
> function. Moreover, this way, you will not need this function at all,
> but call the below from cm_fx6_spl_dram_init().

Will do (here and below)..

>
>> +	mx6sdl_dram_iocfg(64, &ddr_iomux, &grp_iomux);
>> +}
>> +
>> +static void spl_mx6q_dram_setup_iomux(void)
>> +{
>> +	struct mx6dq_iomux_ddr_regs ddr_iomux;
>> +	struct mx6dq_iomux_grp_regs grp_iomux;
>> +

[..]

>> +	mx6dq_dram_iocfg(64, &ddr_iomux, &grp_iomux);
>> +}
>> +
>> +static void spl_mx6s_dram_init(enum ddr_config dram_config, int reset)
>
> I think we have bool type in U-Boot, right?
> If so, it would be more descriptive to have bool reset.

OK

>
>> +{
>> +	struct mx6_mmdc_calibration calib;
>> +	struct mx6_ddr_sysinfo sysinfo;
>> +	struct mx6_ddr3_cfg ddr3_cfg;
>> +
>> +	if (reset)
>> +		((struct mmdc_p_regs *)MX6_MMDC_P0_MDCTL)->mdmisc = 2;
>> +
>> +	calib.p0_mpwldectrl0	= 0x005B0061;
>> +	calib.p0_mpwldectrl1	= 0x004F0055;


[..]

>> +
>> +static int cm_fx6_spl_dram_init(void)
>> +{
>> +	u32 cpurev, imxtype;
>> +	unsigned long bank1_size, bank2_size;
>> +
>> +	cpurev = get_cpu_rev();
>> +	imxtype = (cpurev & 0xFF000) >> 12;
>
> I would expect here at least cpu_type() usage instead of open coding.
> Or may be to spare the above construct, it is worth introducing
> a kind of get_cpu_type()? like:
>
> #define get_cpu_type() (cpu_type(get_cpu_rev()))
>
> in arch/arm/include/asm/arch-mx6/sys_proto.h
> And then you can use get_imx_cpu_type() inside the switch below.
> What do you think?

Good idea. Will add it.

>
>> +
>> +	switch (imxtype) {
>> +	case MXC_CPU_MX6SOLO:
>> +		spl_mx6s_dram_setup_iomux();
>> +
>> +		spl_mx6s_dram_init(DDR_32BIT_1GB, 0);
>> +		bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000);
>> +		if (bank1_size == 0x40000000)
>> +			return 0;
>> +
>> +		if (bank1_size == 0x20000000) {
>> +			spl_mx6s_dram_init(DDR_32BIT_512MB, 1);
>> +			return 0;
>> +		}
>> +
>> +		spl_mx6s_dram_init(DDR_16BIT_256MB, 1);
>> +		bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000);
>> +		if (bank1_size == 0x10000000)
>> +			return 0;
>> +
>> +		break;
>> +	case MXC_CPU_MX6D:
>> +	case MXC_CPU_MX6Q:
>> +		spl_mx6q_dram_setup_iomux();
>> +
>> +		spl_mx6q_dram_init(DDR_64BIT_4GB, 0);
>> +		bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000);
>> +		if (bank1_size == 0x80000000)
>> +			return 0;
>> +
>> +		if (bank1_size == 0x40000000) {
>> +			bank2_size = get_ram_size((long int *)PHYS_SDRAM_2,
>> +								0x80000000);
>> +			if (bank2_size == 0x40000000) {
>> +				/* Don't do a full reset here */
>> +				spl_mx6q_dram_init(DDR_64BIT_2GB, 0);
>> +			} else {
>> +				spl_mx6q_dram_init(DDR_64BIT_1GB, 1);
>> +			}
>> +
>> +			return 0;
>> +		}
>> +
>> +		spl_mx6q_dram_init(DDR_32BIT_512MB, 1);
>> +		bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000);
>> +		if (bank1_size == 0x20000000)
>> +			return 0;
>> +
>> +		spl_mx6q_dram_init(DDR_16BIT_256MB, 1);
>> +		bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000);
>> +		if (bank1_size == 0x10000000)
>> +			return 0;
>> +
>> +		break;
>> +	}
>> +
>> +	return -1;
>> +}
>> +
>> +static iomux_v3_cfg_t const uart4_pads[] = {
>> +	IOMUX_PADS(PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
>> +	IOMUX_PADS(PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
>> +};
>> +
>> +static void cm_fx6_setup_uart(void)
>> +{
>> +	SETUP_IOMUX_PADS(uart4_pads);
>> +	enable_uart_clk(1);
>> +}
>> +
>> +#ifdef CONFIG_SPL_SPI_SUPPORT
>> +static void cm_fx6_setup_ecspi(void)
>> +{
>> +	enable_cspi_clock(1, 0);
>> +	cm_fx6_set_ecspi_iomux();
>
> It does not really meter, but it will lok better if the sequence
> will be the same as for uart: mux and then clock...

Can do..

>
>> +}
>> +#else
>> +static void cm_fx6_setup_ecspi(void) { }
>> +#endif
>> +
>> +void board_init_f(ulong dummy)
>> +{
>> +	gd = &gdata;
>> +	enable_usdhc_clk(1, 2);
>
> can this be done inside board_mmc_init() or even in a common location
> like fsl_esdhc_initialize()?
>
>> +	arch_cpu_init();
>> +	timer_init();
>> +	cm_fx6_setup_ecspi();
>> +	cm_fx6_setup_uart();
>> +	get_clocks();
>> +	preloader_console_init();
>> +	gpio_direction_output(CM_FX6_GREEN_LED, 1);
>> +	if (cm_fx6_spl_dram_init()) {
>> +		puts("!!!ERROR!!! DRAM detection failed!!!\n");
>> +		hang();
>
> Hmmm... why hang? may be reset the cpu/board and try again?

I prefer the hang because it seems safer to me; better to not
boot than boot with bad RAM.

>
>> +	}
>> +
>> +	memset(__bss_start, 0, __bss_end - __bss_start);
>> +	board_init_r(NULL, 0);
>> +}
>> +
>> +void spl_board_init(void)
>> +{
>> +	uint soc_sbmr = readl(SRC_BASE_ADDR + 0x4);
>> +	uint bt_mem_ctl = (soc_sbmr & 0x000000FF) >> 4;
>> +	uint bt_mem_type = (soc_sbmr & 0x00000008) >> 3;
>> +
>> +	if (bt_mem_ctl == 0x3 && !bt_mem_type)
>> +		puts("Booting from SPI flash\n");
>> +	else if (bt_mem_ctl == 0x4 || bt_mem_ctl == 0x5)
>> +		puts("Booting from MMC\n");
>> +	else
>> +		puts("Unknown boot device\n");
>
> Can we call spl_boot_device() here instead?

Sure

>
>> +}
>> +
>> +#ifdef CONFIG_SPL_MMC_SUPPORT
>> +int board_mmc_init(bd_t *bis)
>> +{
>> +	cm_fx6_set_usdhc_iomux();
>> +
>> +	usdhc_cfg[2].sdhc_clk = mxc_get_clock(usdhc_clk[2]);
>> +	usdhc_cfg[2].max_bus_width = 4;
>
> You use only one member of that array...
> It is not likely to change.
> Can we just define one instance on the stack and
> hardcode its initialization?
> This will eliminate the need for sharing the same definition
> of that array between SPL and U-Boot and thus make things simpler.

Agreed.

>> diff --git a/include/configs/cm_fx6.h b/include/configs/cm_fx6.h
>> new file mode 100644
>> index 0000000..b877b65
>> --- /dev/null
>> +++ b/include/configs/cm_fx6.h
>> @@ -0,0 +1,211 @@
>> +/*
>> + * Config file for Compulab CM-FX6 board
>> + *
>> + * Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/
>> + *
>> + * Author: Nikita Kiryanov <nikita@compulab.co.il>
>> + *
>> + * SPDX-License-Identifier:	GPL-2.0+
>> + */
>> +
>> +#ifndef __CONFIG_CM_FX6_H
>> +#define __CONFIG_CM_FX6_H
>> +
>> +#include <asm/arch/imx-regs.h>
>> +#include <config_distro_defaults.h>
>> +
>> +#define CONFIG_SYS_L2CACHE_OFF
>
> Hmmm... Is there a problem using cache on i.MX6 currently?
>

This define can be removed.

>
>> +#define CONFIG_EXTRA_ENV_SETTINGS \
>> +	"kernel=uImage-cm-fx6\0" \
>> +	"autoload=no\0" \
>> +	"loadaddr=0x10800000\0" \
>> +	"fdtaddr=0x11000000\0" \
>> +	"console=ttymxc3,115200\0" \
>> +	"ethprime=FEC0\0" \
>> +	"bootscr=boot.scr\0" \
>> +	"bootm_low=18000000\0" \
>> +	"video_hdmi=mxcfb0:dev=hdmi,1920x1080M-32 at 50,if=RGB32\0" \
>> +	"video_dvi=mxcfb0:dev=dvi,1280x800M-32 at 50,if=RGB32\0" \
>> +	"fdtfile=cm-fx6.dtb\0" \
>> +	"doboot=bootm ${loadaddr}\0" \
>> +	"loadfdt=false\0" \
>> +	"setboottypez=setenv kernel zImage-cm-fx6;" \
>> +		"setenv doboot bootz ${loadaddr} - ${fdtaddr};" \
>> +		"setenv loadfdt true;\0" \
>> +	"setboottypem=setenv kernel uImage-cm-fx6;" \
>> +		"setenv doboot bootm ${loadaddr};" \
>> +		"setenv loadfdt false;\0"\
>> +	"run_eboot=echo Starting EBOOT ...; "\
>> +		"mmc dev ${mmcdev} && " \
>> +		"mmc rescan && mmc read 10042000 a 400 && go 10042000\0" \
>> +	"mmcdev=2\0" \
>> +	"mmcroot=/dev/mmcblk0p2 rw rootwait\0" \
>> +	"loadmmcbootscript=fatload mmc ${mmcdev} ${loadaddr} ${bootscr}\0" \
>
> Can we switch to use load instead of fatload?
>

Yes

  parent reply	other threads:[~2014-08-19 15:17 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-10 17:12 [U-Boot] [PATCH V2 00/18] Introduce cm-fx6 board (partial V2 cont.) Nikita Kiryanov
2014-08-10 17:12 ` [U-Boot] [PATCH V2 10/18] arm: mx6: ddr: configure MMDC for slow_pd Nikita Kiryanov
2014-08-12 11:29   ` Igor Grinberg
2014-08-10 17:12 ` [U-Boot] [PATCH V2 11/18] arm: mx6: ddr: fix cs0_end calculation Nikita Kiryanov
2014-08-10 17:12 ` [U-Boot] [PATCH V2 12/18] arm: mx6: add support for Compulab cm-fx6 CoM Nikita Kiryanov
2014-08-10 20:53   ` Marek Vasut
2014-08-11 16:22   ` [U-Boot] [PATCH V3 " Nikita Kiryanov
2014-08-12 14:48     ` Simon Glass
2014-08-13 10:57       ` Nikita Kiryanov
2014-08-13 12:55     ` Igor Grinberg
2014-08-14  7:16       ` Igor Grinberg
2014-08-19 15:19         ` Nikita Kiryanov
2014-08-19 15:17       ` Nikita Kiryanov [this message]
2014-08-20 11:23       ` Nikita Kiryanov
2014-08-10 17:12 ` [U-Boot] [PATCH V2 13/18] arm: mx6: cm_fx6: add nand support Nikita Kiryanov
2014-08-13 14:29   ` Igor Grinberg
2014-08-10 17:12 ` [U-Boot] [PATCH V2 14/18] arm: mx6: cm_fx6: add ethernet support Nikita Kiryanov
2014-08-13 13:53   ` Igor Grinberg
2014-08-10 17:12 ` [U-Boot] [PATCH V2 15/18] arm: mx6: cm_fx6: add usb support Nikita Kiryanov
2014-08-13 14:04   ` Igor Grinberg
2014-08-19 14:49     ` Nikita Kiryanov
2014-08-10 17:12 ` [U-Boot] [PATCH V2 16/18] arm: mx6: cm_fx6: add i2c support Nikita Kiryanov
2014-08-14  6:55   ` Igor Grinberg
2014-08-10 17:12 ` [U-Boot] [PATCH V2 17/18] arm: mx6: cm_fx6: use eeprom Nikita Kiryanov
2014-08-14  6:59   ` Igor Grinberg
2014-08-10 17:13 ` [U-Boot] [PATCH V2 18/18] arm: mx6: cm_fx6: add sata support Nikita Kiryanov
2014-08-14  7:10   ` Igor Grinberg
2014-08-19 14:51     ` Nikita Kiryanov
2014-08-11  0:11 ` [U-Boot] [PATCH V2 00/18] Introduce cm-fx6 board (partial V2 cont.) Simon Glass
2014-08-11  8:05   ` Igor Grinberg
2014-08-11  8:20   ` Nikita Kiryanov
2014-08-11 14:15     ` Simon Glass
2014-08-11 14:39       ` Nikita Kiryanov
2014-08-12 14:39         ` Simon Glass

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=53F36AA0.3000409@compulab.co.il \
    --to=nikita@compulab.co.il \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.