From mboxrd@z Thu Jan 1 00:00:00 1970 From: Marek Vasut Date: Mon, 11 Apr 2016 02:08:56 +0200 Subject: [U-Boot] [PATCH v3 2/2] arm: add initial support for Amlogic Meson and ODROID-C2 In-Reply-To: <1460302242-16420-3-git-send-email-b.galvani@gmail.com> References: <1460302242-16420-1-git-send-email-b.galvani@gmail.com> <1460302242-16420-3-git-send-email-b.galvani@gmail.com> Message-ID: <570AEB18.5010901@denx.de> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de 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 [...] > 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 > + * > + * 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 > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include > +#include > +#include > +#include > +#include > + > +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 > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include > +#include > +#include > +#include > +#include > + > +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 > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +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