diff options
Diffstat (limited to 'arch/arm/mach-mediatek')
-rw-r--r-- | arch/arm/mach-mediatek/Kconfig | 39 | ||||
-rw-r--r-- | arch/arm/mach-mediatek/Makefile | 7 | ||||
-rw-r--r-- | arch/arm/mach-mediatek/cpu.c | 34 | ||||
-rw-r--r-- | arch/arm/mach-mediatek/init.h | 11 | ||||
-rw-r--r-- | arch/arm/mach-mediatek/mt7623/Makefile | 4 | ||||
-rw-r--r-- | arch/arm/mach-mediatek/mt7623/init.c | 54 | ||||
-rw-r--r-- | arch/arm/mach-mediatek/mt7623/lowlevel_init.S | 22 | ||||
-rw-r--r-- | arch/arm/mach-mediatek/mt7623/preloader.h | 99 | ||||
-rw-r--r-- | arch/arm/mach-mediatek/mt7629/Makefile | 4 | ||||
-rw-r--r-- | arch/arm/mach-mediatek/mt7629/init.c | 128 | ||||
-rw-r--r-- | arch/arm/mach-mediatek/mt7629/lowlevel_init.S | 50 | ||||
-rw-r--r-- | arch/arm/mach-mediatek/spl.c | 43 |
12 files changed, 495 insertions, 0 deletions
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig new file mode 100644 index 0000000000..7a733e95df --- /dev/null +++ b/arch/arm/mach-mediatek/Kconfig @@ -0,0 +1,39 @@ +if ARCH_MEDIATEK + +config SYS_SOC + default "mediatek" + +config SYS_VENDOR + default "mediatek" + +choice + prompt "MediaTek board select" + +config TARGET_MT7623 + bool "MediaTek MT7623 SoC" + select CPU_V7A + select ARCH_MISC_INIT + help + The MediaTek MT7623 is a ARM-based SoC with a quad-core Cortex-A7 + including NEON and GPU, Mali-450 graphics, several DDR3 options, + crypto engine, built-in Wi-Fi / Bluetooth combo chip, JPEG decoder, + video interfaces supporting HDMI and MIPI, and video codec support. + Peripherals include Gigabit Ethernet, switch, USB3.0 and OTG, PCIe, + I2S, PCM, S/PDIF, UART, SPI, I2C, IR TX/RX, and PWM. + +config TARGET_MT7629 + bool "MediaTek MT7629 SoC" + select CPU_V7A + select SPL + select ARCH_MISC_INIT + help + The MediaTek MT7629 is a ARM-based SoC with a dual-core Cortex-A7 + including DDR3, crypto engine, 3x3 11n/ac Wi-Fi, Gigabit Ethernet, + switch, USB3.0, PCIe, UART, SPI, I2C and PWM. + +endchoice + +source "board/mediatek/mt7623/Kconfig" +source "board/mediatek/mt7629/Kconfig" + +endif diff --git a/arch/arm/mach-mediatek/Makefile b/arch/arm/mach-mediatek/Makefile new file mode 100644 index 0000000000..b5d3a379bc --- /dev/null +++ b/arch/arm/mach-mediatek/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-y += cpu.o +obj-$(CONFIG_SPL_BUILD) += spl.o + +obj-$(CONFIG_TARGET_MT7623) += mt7623/ +obj-$(CONFIG_TARGET_MT7629) += mt7629/ diff --git a/arch/arm/mach-mediatek/cpu.c b/arch/arm/mach-mediatek/cpu.c new file mode 100644 index 0000000000..b37e299b74 --- /dev/null +++ b/arch/arm/mach-mediatek/cpu.c @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 MediaTek Inc. + */ + +#include <common.h> +#include <dm.h> +#include <wdt.h> +#include <dm/uclass-internal.h> + +int arch_misc_init(void) +{ + struct udevice *wdt; + int ret; + + ret = uclass_first_device_err(UCLASS_WDT, &wdt); + if (!ret) + wdt_stop(wdt); + + return 0; +} + +int arch_cpu_init(void) +{ + icache_enable(); + + return 0; +} + +void enable_caches(void) +{ + /* Enable D-cache. I-cache is already enabled in start.S */ + dcache_enable(); +} diff --git a/arch/arm/mach-mediatek/init.h b/arch/arm/mach-mediatek/init.h new file mode 100644 index 0000000000..1d896fbbf7 --- /dev/null +++ b/arch/arm/mach-mediatek/init.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2018 MediaTek Inc. + */ + +#ifndef __MEDIATEK_INIT_H_ +#define __MEDIATEK_INIT_H_ + +extern int mtk_soc_early_init(void); + +#endif /* __MEDIATEK_INIT_H_ */ diff --git a/arch/arm/mach-mediatek/mt7623/Makefile b/arch/arm/mach-mediatek/mt7623/Makefile new file mode 100644 index 0000000000..007eb4a367 --- /dev/null +++ b/arch/arm/mach-mediatek/mt7623/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-y += init.o +obj-y += lowlevel_init.o diff --git a/arch/arm/mach-mediatek/mt7623/init.c b/arch/arm/mach-mediatek/mt7623/init.c new file mode 100644 index 0000000000..0ee8c6664c --- /dev/null +++ b/arch/arm/mach-mediatek/mt7623/init.c @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 MediaTek Inc. + */ + +#include <common.h> +#include <linux/io.h> +#include <linux/sizes.h> +#include <asm/arch/misc.h> + +#include "preloader.h" + +DECLARE_GLOBAL_DATA_PTR; + +struct boot_argument *preloader_param; + +int mtk_soc_early_init(void) +{ + return 0; +} + +int dram_init(void) +{ + u32 i; + + if (((size_t)preloader_param >= CONFIG_SYS_SDRAM_BASE) && + ((size_t)preloader_param % sizeof(size_t) == 0) && + preloader_param->magic == BOOT_ARGUMENT_MAGIC && + preloader_param->dram_rank_num <= + ARRAY_SIZE(preloader_param->dram_rank_size)) { + gd->ram_size = 0; + + for (i = 0; i < preloader_param->dram_rank_num; i++) + gd->ram_size += preloader_param->dram_rank_size[i]; + } else { + gd->ram_size = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, + SZ_2G); + } + + return 0; +} + +int print_cpuinfo(void) +{ + void __iomem *chipid; + u32 swver; + + chipid = ioremap(VER_BASE, VER_SIZE); + swver = readl(chipid + APSW_VER); + + printf("CPU: MediaTek MT7623 E%d\n", (swver & 0xf) + 1); + + return 0; +} diff --git a/arch/arm/mach-mediatek/mt7623/lowlevel_init.S b/arch/arm/mach-mediatek/mt7623/lowlevel_init.S new file mode 100644 index 0000000000..afb94767ee --- /dev/null +++ b/arch/arm/mach-mediatek/mt7623/lowlevel_init.S @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2018 MediaTek Inc. + */ + +#include <linux/linkage.h> + +.extern preloader_param + +ENTRY(save_boot_params) + ldr r6, =preloader_param + str r4, [r6] + b save_boot_params_ret +ENDPROC(save_boot_params) + +ENTRY(lowlevel_init) + /* enable SMP bit */ + mrc p15, 0, r0, c1, c0, 1 + orr r0, r0, #0x40 + mcr p15, 0, r0, c1, c0, 1 + mov pc, lr +ENDPROC(lowlevel_init) diff --git a/arch/arm/mach-mediatek/mt7623/preloader.h b/arch/arm/mach-mediatek/mt7623/preloader.h new file mode 100644 index 0000000000..2d2c71ad4c --- /dev/null +++ b/arch/arm/mach-mediatek/mt7623/preloader.h @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2018 MediaTek Inc. + */ + +#ifndef __PRELOADER_H_ +#define __PRELOADER_H_ + +enum forbidden_mode { + F_FACTORY_MODE = 0x0001 +}; + +union lk_hdr { + struct { + u32 magic; + u32 size; + char name[32]; + u32 loadaddr; + }; + + u8 data[512]; +}; + +struct sec_limit { + unsigned int magic_num; + enum forbidden_mode forbid_mode; +}; + +enum bootmode { + NORMAL_BOOT = 0, + META_BOOT = 1, + RECOVERY_BOOT = 2, + SW_REBOOT = 3, + FACTORY_BOOT = 4, + ADVMETA_BOOT = 5, + ATE_FACTORY_BOOT = 6, + ALARM_BOOT = 7, + + KERNEL_POWER_OFF_CHARGING_BOOT = 8, + LOW_POWER_OFF_CHARGING_BOOT = 9, + + FAST_BOOT = 99, + DOWNLOAD_BOOT = 100, + UNKNOWN_BOOT +}; + +enum boot_reason { + BR_POWER_KEY = 0, + BR_USB, + BR_RTC, + BR_WDT, + BR_WDT_BY_PASS_PWK, + BR_TOOL_BY_PASS_PWK, + BR_2SEC_REBOOT, + BR_UNKNOWN +}; + +enum meta_com_type { + META_UNKNOWN_COM = 0, + META_UART_COM, + META_USB_COM +}; + +struct da_info_t { + u32 addr; + u32 arg1; + u32 arg2; + u32 len; + u32 sig_len; +}; + +struct boot_argument { + u32 magic; + enum bootmode boot_mode; + u32 e_flag; + u32 log_port; + u32 log_baudrate; + u8 log_enable; + u8 part_num; + u8 reserved[2]; + u32 dram_rank_num; + u32 dram_rank_size[4]; + u32 boot_reason; + enum meta_com_type meta_com_type; + u32 meta_com_id; + u32 boot_time; + struct da_info_t da_info; + struct sec_limit sec_limit; + union lk_hdr *part_info; + u8 md_type[4]; + u32 ddr_reserve_enable; + u32 ddr_reserve_success; + u32 chip_ver; + char pl_version[8]; +}; + +#define BOOT_ARGUMENT_MAGIC 0x504c504c + +#endif /* __PRELOADER_H_ */ diff --git a/arch/arm/mach-mediatek/mt7629/Makefile b/arch/arm/mach-mediatek/mt7629/Makefile new file mode 100644 index 0000000000..007eb4a367 --- /dev/null +++ b/arch/arm/mach-mediatek/mt7629/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-y += init.o +obj-y += lowlevel_init.o diff --git a/arch/arm/mach-mediatek/mt7629/init.c b/arch/arm/mach-mediatek/mt7629/init.c new file mode 100644 index 0000000000..ba91a6eaa6 --- /dev/null +++ b/arch/arm/mach-mediatek/mt7629/init.c @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 MediaTek Inc. + * Author: Ryder Lee <ryder.lee@mediatek.com> + */ + +#include <clk.h> +#include <common.h> +#include <dm.h> +#include <fdtdec.h> +#include <ram.h> +#include <asm/arch/misc.h> +#include <asm/sections.h> +#include <dm/uclass.h> +#include <linux/io.h> + +#include <dt-bindings/clock/mt7629-clk.h> + +#define L2_CFG_BASE 0x10200000 +#define L2_CFG_SIZE 0x1000 +#define L2_SHARE_CFG_MP0 0x7f0 +#define L2_SHARE_MODE_OFF BIT(8) + +DECLARE_GLOBAL_DATA_PTR; + +int mtk_pll_early_init(void) +{ + unsigned long pll_rates[] = { + [CLK_APMIXED_ARMPLL] = 1250000000, + [CLK_APMIXED_MAINPLL] = 1120000000, + [CLK_APMIXED_UNIV2PLL] = 1200000000, + [CLK_APMIXED_ETH1PLL] = 500000000, + [CLK_APMIXED_ETH2PLL] = 700000000, + [CLK_APMIXED_SGMIPLL] = 650000000, + }; + struct udevice *dev; + int ret, i; + + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_GET_DRIVER(mtk_clk_apmixedsys), &dev); + if (ret) + return ret; + + /* configure default rate then enable apmixedsys */ + for (i = 0; i < ARRAY_SIZE(pll_rates); i++) { + struct clk clk = { .id = i, .dev = dev }; + + ret = clk_set_rate(&clk, pll_rates[i]); + if (ret) + return ret; + + ret = clk_enable(&clk); + if (ret) + return ret; + } + + /* setup mcu bus */ + ret = uclass_get_device_by_driver(UCLASS_SYSCON, + DM_GET_DRIVER(mtk_mcucfg), &dev); + if (ret) + return ret; + + return 0; +} + +int mtk_soc_early_init(void) +{ + struct udevice *dev; + int ret; + + /* initialize early clocks */ + ret = mtk_pll_early_init(); + if (ret) + return ret; + + ret = uclass_first_device_err(UCLASS_RAM, &dev); + if (ret) + return ret; + + return 0; +} + +int mach_cpu_init(void) +{ + void __iomem *base; + + base = ioremap(L2_CFG_BASE, L2_CFG_SIZE); + + /* disable L2C shared mode */ + writel(L2_SHARE_MODE_OFF, base + L2_SHARE_CFG_MP0); + + return 0; +} + +int dram_init(void) +{ + struct ram_info ram; + struct udevice *dev; + int ret; + + ret = uclass_first_device_err(UCLASS_RAM, &dev); + if (ret) + return ret; + + ret = ram_get_info(dev, &ram); + if (ret) + return ret; + + debug("RAM init base=%lx, size=%x\n", ram.base, ram.size); + + gd->ram_size = ram.size; + + return 0; +} + +int print_cpuinfo(void) +{ + void __iomem *chipid; + u32 hwcode, swver; + + chipid = ioremap(VER_BASE, VER_SIZE); + hwcode = readl(chipid + APHW_CODE); + swver = readl(chipid + APSW_VER); + + printf("CPU: MediaTek MT%04x E%d\n", hwcode, (swver & 0xf) + 1); + + return 0; +} diff --git a/arch/arm/mach-mediatek/mt7629/lowlevel_init.S b/arch/arm/mach-mediatek/mt7629/lowlevel_init.S new file mode 100644 index 0000000000..90dd4ea48e --- /dev/null +++ b/arch/arm/mach-mediatek/mt7629/lowlevel_init.S @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2018 MediaTek Inc. + */ + +#include <linux/linkage.h> + +ENTRY(lowlevel_init) + +#ifndef CONFIG_SPL_BUILD + /* Return to U-Boot via saved link register */ + mov pc, lr +#else + /* + * Arch timer : + * set CNTFRQ = 20Mhz, set CNTVOFF = 0 + */ + movw r0, #0x2d00 + movt r0, #0x131 + mcr p15, 0, r0, c14, c0, 0 + + /* enable SMP bit */ + mrc p15, 0, r0, c1, c0, 1 + orr r0, r0, #0x40 + mcr p15, 0, r0, c1, c0, 1 + + /* if MP core, handle secondary cores */ + mrc p15, 0, r0, c0, c0, 5 + ands r1, r0, #0x40000000 + bne go @ Go if UP + ands r0, r0, #0x0f + beq go @ Go if core0 on primary core tile + b secondary + +go: + /* master CPU */ + mov pc, lr + +secondary: + /* read slave CPU number into r0 firstly */ + mrc p15, 0, r0, c0, c0, 5 + and r0, r0, #0x0f + +loop: + dsb + isb + wfi @Zzz... + b loop +#endif +ENDPROC(lowlevel_init) diff --git a/arch/arm/mach-mediatek/spl.c b/arch/arm/mach-mediatek/spl.c new file mode 100644 index 0000000000..9b3590ff3d --- /dev/null +++ b/arch/arm/mach-mediatek/spl.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 MediaTek Inc. + * Author: Ryder Lee <ryder.lee@mediatek.com> + */ + +#include <clk.h> +#include <common.h> +#include <spl.h> + +#include "init.h" + +void board_init_f(ulong dummy) +{ + int ret; + + ret = spl_early_init(); + if (ret) + hang(); + + /* enable console uart printing */ + preloader_console_init(); + + /* soc early initialization */ + ret = mtk_soc_early_init(); + if (ret) + hang(); +} + +u32 spl_boot_device(void) +{ +#if defined(CONFIG_SPL_SPI_SUPPORT) + return BOOT_DEVICE_SPI; +#elif defined(CONFIG_SPL_MMC_SUPPORT) + return BOOT_DEVICE_MMC1; +#elif defined(CONFIG_SPL_NAND_SUPPORT) + return BOOT_DEVICE_NAND; +#elif defined(CONFIG_SPL_NOR_SUPPORT) + return BOOT_DEVICE_NOR; +#else + return BOOT_DEVICE_NONE; +#endif +} |