[U-Boot] [PATCH] ARM: mx6: Add support for Kosagi Novena

Marek Vasut marex at denx.de
Sat Sep 27 22:19:44 CEST 2014


On Wednesday, September 24, 2014 at 06:57:06 PM, Sean Cross wrote:

[...]
> 
> > +
> > +int drv_keyboard_init(void)
> > +{
> > +	int error;
> > +	struct stdio_dev dev = {
> > +		.name	= "button",
> > +		.flags	= DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM,
> > +		.start	= novena_gpio_button_init,
> > +		.getc	= novena_gpio_button_getc,
> > +		.tstc	= novena_gpio_button_tstc,
> > +	};
> > +
> > +	error = input_init(&button_input, 0);
> > +	if (error) {
> > +		debug("%s: Cannot set up input\n", __func__);
> > +		return -1;
> > +	}
> > +	button_input.read_keys = novena_gpio_button_read_keys;
> > +
> > +	/* Register the device. init_tegra_keyboard() will be called soon */
> 
> This may have been answered already, but will the function named
> init_tegra_keyboard() be called?  Or is there some more generic name?

This was addressed already, yes.

> > +	error = input_stdio_register(&dev);
> > +	if (error)
> > +		return error;
> > +
> > +	return 0;
> > +}
> > +#endif
> > +
> 
> [...]
> 
> > +int board_early_init_f(void)
> > +{
> > +#if defined(CONFIG_VIDEO_IPUV3)
> > +	setup_display();
> > +#endif
> 
> If board_early_init_f() gets called early, then this is where you should
> set DISP0_DAT13 (GPIO5 IO13) to low, in order to ensure the FPGA is in
> reset, so it isn't pulling the DDR3 I2C lines low.

Actually, this can be done in the SPL.

> This would also be a good time to bring the sound chip out of reset, by
> driving GPIO5 IO17 high,  When the sound chip is in reset, the EEPROM
> cannot be read.

This is already done in the SPL.

[...]

> > +/* setup board specific PMIC */
> > +int power_init_board(void)
> > +{
> > +	struct pmic *p;
> > +	u32 reg;
> > +	int ret;
> > +
> > +	power_pfuze100_init(1);
> > +	p = pmic_get("PFUZE100_PMIC");
> > +	if (!p)
> > +		return -EINVAL;
> > +
> > +	ret = pmic_probe(p);
> > +	if (ret)
> > +		return ret;
> > +
> > +	pmic_reg_read(p, PFUZE100_DEVICEID, &reg);
> > +	printf("PMIC:  PFUZE100 ID=0x%02x\n", reg);
> > +
> > +	/* Set VGEN1 to 1.5V and enable */
> 
> VGEN1 is unused in this system.  VGEN5 is, however, hooked up to the
> power LED.  It defaults to ON, which allows for software to turn the
> power LED off once the system is booted.  You can leave everything alone
> except for SWBST, which is required for USB.

Removed the VGEN1 enabling.

[...]

> > +#define NOVENA_AUDIO_PWRON		IMX_GPIO_NR(5, 17)
> > +#define NOVENA_HDMI_GHOST_HPD		IMX_GPIO_NR(5, 4)
> > +#define NOVENA_PCIE_RESET_GPIO		IMX_GPIO_NR(3, 29)
> > +#define NOVENA_PCIE_POWER_ON_GPIO	IMX_GPIO_NR(7, 12)
> > +#define NOVENA_PCIE_WAKE_UP_GPIO	IMX_GPIO_NR(3, 22)
> > +#define NOVENA_PCIE_DISABLE_GPIO	IMX_GPIO_NR(2, 16)
> 
> Add NOVENA_FPGA_RESET_N_GPIO IMX_GPIO_NR(5, 7).  If the FPGA has a
> program loaded that doesn't let the I2C pins float, then the DDR3 SPD
> will be unable to be read.

Added and I am now setting this GPIO to 0 so the FPGA is in reset throughout the 
SPL operation. It can be brought out of reset in U-Boot itself and only when 
it's actually used, right ?

> > +
> > +/*
> > + * Audio
> > + */
> > +static iomux_v3_cfg_t audio_pads[] = {
> > +	/* AUD_PWRON */
> > +	MX6_PAD_DISP0_DAT23__GPIO5_IO17 | MUX_PAD_CTRL(NO_PAD_CTRL),
> > +};
> > +
> > +static void novena_spl_setup_iomux_audio(void)
> > +{
> > +	imx_iomux_v3_setup_multiple_pads(audio_pads, ARRAY_SIZE(audio_pads));
> > +	gpio_direction_output(NOVENA_AUDIO_PWRON, 1);
> > +}
> > +
> > +/*
> > + * ENET
> > + */
> > +static iomux_v3_cfg_t enet_pads1[] = {
> > +	MX6_PAD_ENET_MDIO__ENET_MDIO		| MUX_PAD_CTRL(ENET_PAD_CTRL),
> > +	MX6_PAD_ENET_MDC__ENET_MDC		| MUX_PAD_CTRL(ENET_PAD_CTRL),
> > +	MX6_PAD_RGMII_TXC__RGMII_TXC		| MUX_PAD_CTRL(ENET_PAD_CTRL),
> > +	MX6_PAD_RGMII_TD0__RGMII_TD0		| MUX_PAD_CTRL(ENET_PAD_CTRL),
> > +	MX6_PAD_RGMII_TD1__RGMII_TD1		| MUX_PAD_CTRL(ENET_PAD_CTRL),
> > +	MX6_PAD_RGMII_TD2__RGMII_TD2		| MUX_PAD_CTRL(ENET_PAD_CTRL),
> > +	MX6_PAD_RGMII_TD3__RGMII_TD3		| MUX_PAD_CTRL(ENET_PAD_CTRL),
> > +	MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL	| MUX_PAD_CTRL(ENET_PAD_CTRL),
> > +	MX6_PAD_ENET_REF_CLK__ENET_TX_CLK	| MUX_PAD_CTRL(ENET_PAD_CTRL),
> > +	/* pin 35 - 1 (PHY_AD2) on reset */
> > +	MX6_PAD_RGMII_RXC__GPIO6_IO30		| MUX_PAD_CTRL(NO_PAD_CTRL),
> > +	/* pin 32 - 1 - (MODE0) all */
> > +	MX6_PAD_RGMII_RD0__GPIO6_IO25		| MUX_PAD_CTRL(NO_PAD_CTRL),
> > +	/* pin 31 - 1 - (MODE1) all */
> > +	MX6_PAD_RGMII_RD1__GPIO6_IO27		| MUX_PAD_CTRL(NO_PAD_CTRL),
> > +	/* pin 28 - 1 - (MODE2) all */
> > +	MX6_PAD_RGMII_RD2__GPIO6_IO28		| MUX_PAD_CTRL(NO_PAD_CTRL),
> > +	/* pin 27 - 1 - (MODE3) all */
> > +	MX6_PAD_RGMII_RD3__GPIO6_IO29		| MUX_PAD_CTRL(NO_PAD_CTRL),
> > +	/* pin 33 - 1 - (CLK125_EN) 125Mhz clockout enabled */
> > +	MX6_PAD_RGMII_RX_CTL__GPIO6_IO24	| MUX_PAD_CTRL(NO_PAD_CTRL),
> > +	/* pin 42 PHY nRST */
> > +	MX6_PAD_EIM_D23__GPIO3_IO23		| MUX_PAD_CTRL(NO_PAD_CTRL),
> > +};
> > +
> > +static iomux_v3_cfg_t enet_pads2[] = {
> > +	MX6_PAD_RGMII_RXC__RGMII_RXC		| MUX_PAD_CTRL(ENET_PAD_CTRL),
> > +	MX6_PAD_RGMII_RD0__RGMII_RD0		| MUX_PAD_CTRL(ENET_PAD_CTRL),
> > +	MX6_PAD_RGMII_RD1__RGMII_RD1		| MUX_PAD_CTRL(ENET_PAD_CTRL),
> > +	MX6_PAD_RGMII_RD2__RGMII_RD2		| MUX_PAD_CTRL(ENET_PAD_CTRL),
> > +	MX6_PAD_RGMII_RD3__RGMII_RD3		| MUX_PAD_CTRL(ENET_PAD_CTRL),
> > +	MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL	| MUX_PAD_CTRL(ENET_PAD_CTRL),
> > +};
> > +
> > +static void novena_spl_setup_iomux_enet(void)
> > +{
> > +	imx_iomux_v3_setup_multiple_pads(enet_pads1, ARRAY_SIZE(enet_pads1));
> > +	imx_iomux_v3_setup_multiple_pads(enet_pads2, ARRAY_SIZE(enet_pads2));
> > +
> > +	gpio_direction_output(IMX_GPIO_NR(3, 23), 0);
> > +	gpio_direction_output(IMX_GPIO_NR(6, 30), 1);
> > +	gpio_direction_output(IMX_GPIO_NR(6, 25), 1);
> > +	gpio_direction_output(IMX_GPIO_NR(6, 27), 1);
> > +	gpio_direction_output(IMX_GPIO_NR(6, 28), 1);
> > +	gpio_direction_output(IMX_GPIO_NR(6, 29), 1);
> > +	gpio_direction_output(IMX_GPIO_NR(6, 24), 1);
> > +}
> > +
> > +/*
> > + * GPIO Button
> > + */
> > +static iomux_v3_cfg_t button_pads[] = {
> > +	/* Debug */
> > +	MX6_PAD_KEY_COL4__GPIO4_IO14 | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
> > +};
> > +
> > +static void novena_spl_setup_iomux_buttons(void)
> > +{
> > +	imx_iomux_v3_setup_multiple_pads(button_pads, ARRAY_SIZE(button_pads));
> > +}
> > +
> > +/*
> > + * I2C
> > + */
> > +/* I2C1, RAM */
> 
> This bus also contains an unused touchscreen controller, as well as an
> accelerometer, the battery board, and an RTC in the final version.

All I2C comments should be fixed.

[...]

> > +static void novena_spl_setup_iomux_spi(void)
> > +{
> > +	imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads));
> > +	gpio_direction_output(CONFIG_SF_DEFAULT_CS, 1);
> > +}
> > +#else
> > +static void novena_spl_setup_iomux_spi(void) {}
> > +#endif
> 
> It may be interesting to mux ECSPI3 here, in order to be able to blast a
> configuration file at the FPGA at boot time.  But correct, ECSPI1 is not
> used in Novena as a SPI bus.

Done.

> > +
> > +/*
> > + * UART
> > + */
> > +static iomux_v3_cfg_t const uart1_pads[] = {
> > +	MX6_PAD_SD3_DAT6__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
> > +	MX6_PAD_SD3_DAT7__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
> > +};
> > +
> > +static iomux_v3_cfg_t const uart2_pads[] = {
> > +	MX6_PAD_EIM_D26__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
> > +	MX6_PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
> > +};
> > +
> > +static void novena_spl_setup_iomux_uart(void)
> > +{
> > +	imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
> > +	imx_iomux_v3_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads));
> > +}
> > +
> 
> Novena uses uart2, uart3, and uart4.  uart2_pads is correct. uart3_pads
> should map EIM_D24 to UART3_TX_DATA and EIM_D25 to UART3_RX_DATA.
> KEY_COL0 maps to UART4_TX_DATA and KEY_ROW0 maps to UART4_RX_DATA.
> Optionally, CSI0_DAT16 maps to UART4_RTS and CSI0_DAT17 maps to UART4_CTS.

Fixed.

[...]
> > +	/* Setup IOMUX and configure basics. */
> > +	novena_spl_setup_iomux_audio();
> > +	novena_spl_setup_iomux_buttons();
> > +	novena_spl_setup_iomux_enet();
> > +	novena_spl_setup_iomux_i2c();
> > +	novena_spl_setup_iomux_pcie();
> > +	novena_spl_setup_iomux_sdhc();
> > +	novena_spl_setup_iomux_spi();
> > +	novena_spl_setup_iomux_uart();
> > +	novena_spl_setup_iomux_usb();
> > +	novena_spl_setup_iomux_video();
> 
> Should also set up the FPGA here, driving its reset pin low.

Done.

> > +
> > +	/* UART clocks enabled and gd valid - init serial console */
> > +	preloader_console_init();
> > +
> > +	/* Start the DDR DRAM */
> > +	mx6dq_dram_iocfg(64, &novena_ddr_ioregs, &novena_grp_ioregs);
> > +	mx6_dram_cfg(&novena_ddr_info, &novena_mmdc_calib, &elpida_4gib_1600);
> > +
> > +	/* Clear the BSS. */
> > +	memset(__bss_start, 0, __bss_end - __bss_start);
> > +
> > +	/* load/boot image from boot device */
> > +	board_init_r(NULL, 0);
> > +}
> > +
> > +void reset_cpu(ulong addr)
> > +{
> > +}
> 
> [...]
> 
> We just received final boards on Monday.  I will try this out and report
> back.

You should try one of the never patches .


More information about the U-Boot mailing list