[U-Boot] [PATCH v3 2/2] arm: add initial support for Amlogic Meson and ODROID-C2

Marek Vasut marex at denx.de
Mon Apr 11 02:08:56 CEST 2016


On 04/10/2016 05:30 PM, Beniamino Galvani wrote:
> This adds platform code for the Amlogic Meson GXBaby (S905) SoC and a
> board definition for ODROID-C2. This initial submission only supports
> UART and Ethernet (through the existing Designware driver). DTS files
> are the ones submitted to Linux arm-soc for 4.7 [1].
> 
> [1] https://patchwork.ozlabs.org/patch/603583/
> 
> Signed-off-by: Beniamino Galvani <b.galvani at gmail.com>

[...]

> diff --git a/arch/arm/include/asm/arch-meson/gxbb.h b/arch/arm/include/asm/arch-meson/gxbb.h
> new file mode 100644
> index 0000000..cec06d7
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-meson/gxbb.h
> @@ -0,0 +1,77 @@
> +/*
> + * (C) Copyright 2016 - Beniamino Galvani <b.galvani at gmail.com>
> + *
> + * SPDX-License-Identifier:	GPL-2.0+
> + */
> +
> +#ifndef __GXBB_H__
> +#define __GXBB_H__
> +
> +#define GXBB_PERIPHS_BASE	0xc8834400
> +#define GXBB_PERIPHS_ADDR(off)	(GXBB_PERIPHS_BASE + ((off) << 2))
> +
> +#define GXBB_GPIO_0_EN		GXBB_PERIPHS_ADDR(0x0c)
> +#define GXBB_GPIO_0_OUT		GXBB_PERIPHS_ADDR(0x0d)
> +#define GXBB_GPIO_0_IN		GXBB_PERIPHS_ADDR(0x0e)

You can also define this as
GXBB_GPIO_EN(n)  (0xc + 3 * (n) + 0)
GXBB_GPIO_OUT(n) (0xc + 3 * (n) + 1)
GXBB_GPIO_IN(n)  (0xc + 3 * (n) + 2)

> +#define GXBB_GPIO_1_EN		GXBB_PERIPHS_ADDR(0x0f)
> +#define GXBB_GPIO_1_OUT		GXBB_PERIPHS_ADDR(0x10)
> +#define GXBB_GPIO_1_IN		GXBB_PERIPHS_ADDR(0x11)
> +#define GXBB_GPIO_2_EN		GXBB_PERIPHS_ADDR(0x12)
> +#define GXBB_GPIO_2_OUT		GXBB_PERIPHS_ADDR(0x13)
> +#define GXBB_GPIO_2_IN		GXBB_PERIPHS_ADDR(0x14)
> +#define GXBB_GPIO_3_EN		GXBB_PERIPHS_ADDR(0x15)
> +#define GXBB_GPIO_3_OUT		GXBB_PERIPHS_ADDR(0x16)
> +#define GXBB_GPIO_3_IN		GXBB_PERIPHS_ADDR(0x17)
> +#define GXBB_GPIO_4_EN		GXBB_PERIPHS_ADDR(0x18)
> +#define GXBB_GPIO_4_OUT		GXBB_PERIPHS_ADDR(0x19)
> +#define GXBB_GPIO_4_IN		GXBB_PERIPHS_ADDR(0x1a)
> +#define GXBB_GPIO_5_EN		GXBB_PERIPHS_ADDR(0x1b)
> +#define GXBB_GPIO_5_OUT		GXBB_PERIPHS_ADDR(0x1c)
> +#define GXBB_GPIO_5_IN		GXBB_PERIPHS_ADDR(0x1d)
> +#define GXBB_GPIO_6_EN		GXBB_PERIPHS_ADDR(0x08)
> +#define GXBB_GPIO_6_OUT		GXBB_PERIPHS_ADDR(0x09)
> +#define GXBB_GPIO_6_IN		GXBB_PERIPHS_ADDR(0x0a)
> +
> +#define GXBB_PINMUX_0		GXBB_PERIPHS_ADDR(0x2c)

DTTO, #define ... (0x2c + (n)) here

> +#define GXBB_PINMUX_1		GXBB_PERIPHS_ADDR(0x2d)
> +#define GXBB_PINMUX_2		GXBB_PERIPHS_ADDR(0x2e)
> +#define GXBB_PINMUX_3		GXBB_PERIPHS_ADDR(0x2f)
> +#define GXBB_PINMUX_4		GXBB_PERIPHS_ADDR(0x30)
> +#define GXBB_PINMUX_5		GXBB_PERIPHS_ADDR(0x31)
> +#define GXBB_PINMUX_6		GXBB_PERIPHS_ADDR(0x32)
> +#define GXBB_PINMUX_7		GXBB_PERIPHS_ADDR(0x33)
> +#define GXBB_PINMUX_8		GXBB_PERIPHS_ADDR(0x34)
> +#define GXBB_PINMUX_9		GXBB_PERIPHS_ADDR(0x35)
> +#define GXBB_PINMUX_10		GXBB_PERIPHS_ADDR(0x36)
> +#define GXBB_PINMUX_11		GXBB_PERIPHS_ADDR(0x37)
> +#define GXBB_PINMUX_12		GXBB_PERIPHS_ADDR(0x38)
> +
> +#define GXBB_ETH_REG_0		GXBB_PERIPHS_ADDR(0x50)
> +#define GXBB_ETH_REG_1		GXBB_PERIPHS_ADDR(0x51)
> +
> +#define GXBB_ETH_REG_0_PHY_INTF		BIT(0)
> +#define GXBB_ETH_REG_0_TX_PHASE(x)	(((x) & 3) << 5)
> +#define GXBB_ETH_REG_0_TX_RATIO(x)	(((x) & 7) << 7)
> +#define GXBB_ETH_REG_0_PHY_CLK_EN	BIT(10)
> +#define GXBB_ETH_REG_0_CLK_EN		BIT(12)
> +
> +#define GXBB_HIU_BASE		0xc883c000

It'd be nice to have base addresses somewhere at the beginning instead
of having them mixed with the bit macros, but that's a matter of taste.

> +#define GXBB_HIU_ADDR(off)	(GXBB_HIU_BASE + ((off) << 2))
> +
> +#define GXBB_MEM_PD_REG_0	GXBB_HIU_ADDR(0x40)
> +
> +/* Ethernet memory power domain */
> +#define GXBB_MEM_PD_REG_0_ETH_MASK	(BIT(2) | BIT(3))
> +
> +/* Clock gates */
> +#define GXBB_GCLK_MPEG_0	GXBB_HIU_ADDR(0x50)
> +#define GXBB_GCLK_MPEG_1	GXBB_HIU_ADDR(0x51)
> +#define GXBB_GCLK_MPEG_2	GXBB_HIU_ADDR(0x52)
> +#define GXBB_GCLK_MPEG_OTHER	GXBB_HIU_ADDR(0x53)
> +#define GXBB_GCLK_MPEG_AO	GXBB_HIU_ADDR(0x54)
> +
> +#define GXBB_GCLK_MPEG_1_ETH	BIT(3)
> +
> +#define GXBB_ETH_BASE		0xc9410000
> +
> +#endif /* __GXBB_H__ */

[...]

> diff --git a/arch/arm/mach-meson/board.c b/arch/arm/mach-meson/board.c
> new file mode 100644
> index 0000000..1d4d32e
> --- /dev/null
> +++ b/arch/arm/mach-meson/board.c
> @@ -0,0 +1,65 @@
> +/*
> + * (C) Copyright 2016 Beniamino Galvani <b.galvani at gmail.com>
> + *
> + * SPDX-License-Identifier:	GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <libfdt.h>
> +#include <linux/err.h>
> +#include <asm/arch/gxbb.h>
> +#include <asm/armv8/mmu.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +int dram_init(void)
> +{
> +	const fdt32_t *val;
> +	int offset;
> +	int len;
> +
> +	offset = fdt_path_offset(gd->fdt_blob, "/memory");
> +	if (offset < 0)
> +		return -EINVAL;
> +
> +	val = fdt_getprop(gd->fdt_blob, offset, "reg", &len);
> +	if (len < sizeof(*val) * 4)
> +		return -EINVAL;
> +
> +	/* Don't use fdt64_t to avoid unaligned access */

This looks iffy, can you elaborate on this issue ?

> +	gd->ram_size = (uint64_t)fdt32_to_cpu(val[2]) << 32;
> +	gd->ram_size |= fdt32_to_cpu(val[3]);
> +
> +	return 0;
> +}
> +
> +void dram_init_banksize(void)
> +{
> +	/* Reserve first 16 MiB of RAM */

Why ?

> +	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE + (16 * 1024 * 1024);
> +	gd->bd->bi_dram[0].size = gd->ram_size - (16 * 1024 * 1024);
> +}
> +
> +void reset_cpu(ulong addr)
> +{

How does the system reboot then ?

> +}
> +
> +static struct mm_region gxbb_mem_map[] = {
> +	{
> +		.base = 0x0UL,
> +		.size = 0x80000000UL,
> +		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
> +			 PTE_BLOCK_INNER_SHARE
> +	}, {
> +		.base = 0x80000000UL,
> +		.size = 0x80000000UL,
> +		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
> +			 PTE_BLOCK_NON_SHARE |
> +			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
> +	}, {
> +		/* List terminator */
> +		0,
> +	}
> +};
> +
> +struct mm_region *mem_map = gxbb_mem_map;

This looks super-iffy, I wouldn't be surprised if this started being
optimized away at some point.

[...]

> diff --git a/board/hardkernel/odroid-c2/odroid-c2.c b/board/hardkernel/odroid-c2/odroid-c2.c
> new file mode 100644
> index 0000000..405ccf5
> --- /dev/null
> +++ b/board/hardkernel/odroid-c2/odroid-c2.c
> @@ -0,0 +1,53 @@
> +/*
> + * (C) Copyright 2016 Beniamino Galvani <b.galvani at gmail.com>
> + *
> + * SPDX-License-Identifier:	GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <asm/arch/gxbb.h>
> +#include <dm/platdata.h>
> +#include <phy.h>
> +
> +int board_init(void)
> +{
> +	return 0;
> +}
> +
> +static const struct eth_pdata gxbb_eth_pdata = {
> +	.iobase = GXBB_ETH_BASE,
> +	.phy_interface = PHY_INTERFACE_MODE_RGMII,
> +};
> +
> +U_BOOT_DEVICE(meson_eth) = {
> +	.name = "eth_designware",
> +	.platdata = &gxbb_eth_pdata,
> +};
> +
> +#ifdef CONFIG_MISC_INIT_R
> +int misc_init_r(void)
> +{
> +	/* Select Ethernet function */
> +	setbits_le32(GXBB_PINMUX_6, 0x3fff);
> +
> +	/* Set RGMII mode */
> +	setbits_le32(GXBB_ETH_REG_0, GXBB_ETH_REG_0_PHY_INTF |
> +				     GXBB_ETH_REG_0_TX_PHASE(1) |
> +				     GXBB_ETH_REG_0_TX_RATIO(4) |
> +				     GXBB_ETH_REG_0_PHY_CLK_EN |
> +				     GXBB_ETH_REG_0_CLK_EN);
> +
> +	/* Enable power and clock gate */
> +	setbits_le32(GXBB_GCLK_MPEG_1, GXBB_GCLK_MPEG_1_ETH);
> +	clrbits_le32(GXBB_MEM_PD_REG_0, GXBB_MEM_PD_REG_0_ETH_MASK);
> +
> +	/* Reset PHY on GPIOZ_14 */
> +	clrbits_le32(GXBB_GPIO_3_EN, BIT(14));
> +	clrbits_le32(GXBB_GPIO_3_OUT, BIT(14));
> +	udelay(100000);

mdelay(100); , though that is quite some wait.

> +	setbits_le32(GXBB_GPIO_3_OUT, BIT(14));
> +
> +	return 0;
> +}
> +#endif /* CONFIG_MISC_INIT_R */

[...]

> diff --git a/drivers/serial/serial_meson.c b/drivers/serial/serial_meson.c

This should go in a separate patch.

> new file mode 100644
> index 0000000..140b2d4
> --- /dev/null
> +++ b/drivers/serial/serial_meson.c
> @@ -0,0 +1,162 @@
> +/*
> + * (C) Copyright 2016 Beniamino Galvani <b.galvani at gmail.com>
> + *
> + * SPDX-License-Identifier:	GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <errno.h>
> +#include <fdtdec.h>
> +#include <linux/compiler.h>
> +#include <serial.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +struct meson_uart {
> +	uint32_t wfifo;
> +	uint32_t rfifo;
> +	uint32_t control;
> +	uint32_t status;
> +	uint32_t misc;

u32, but you can just use #define FOO for registers.

> +};
> +
> +struct meson_serial_platdata {
> +	struct meson_uart *reg;
> +};
> +
> +/* AML_UART_STATUS bits */
> +#define AML_UART_PARITY_ERR		BIT(16)
> +#define AML_UART_FRAME_ERR		BIT(17)
> +#define AML_UART_TX_FIFO_WERR		BIT(18)
> +#define AML_UART_RX_EMPTY		BIT(20)
> +#define AML_UART_TX_FULL		BIT(21)
> +#define AML_UART_TX_EMPTY		BIT(22)
> +#define AML_UART_XMIT_BUSY		BIT(25)
> +#define AML_UART_ERR			(AML_UART_PARITY_ERR | \
> +					 AML_UART_FRAME_ERR  | \
> +					 AML_UART_TX_FIFO_WERR)
> +
> +/* AML_UART_CONTROL bits */
> +#define AML_UART_TX_EN			BIT(12)
> +#define AML_UART_RX_EN			BIT(13)
> +#define AML_UART_TX_RST			BIT(22)
> +#define AML_UART_RX_RST			BIT(23)
> +#define AML_UART_CLR_ERR		BIT(24)

[...]

-- 
Best regards,
Marek Vasut


More information about the U-Boot mailing list