diff options
author | Luke Go <luke.go@hardkernel.com> | 2019-06-19 11:46:06 +0900 |
---|---|---|
committer | Dongjin Kim <tobetter@gmail.com> | 2020-02-13 17:13:40 +0900 |
commit | 1823eb28b55e6d95789020a671872488c857b3dc (patch) | |
tree | ab285275e2d9eca7635358dfef900e79b960e71e | |
parent | 800d2781a0a41169b5f0a0c423fb98958fc978e0 (diff) | |
download | u-boot-odroid-c1-1823eb28b55e6d95789020a671872488c857b3dc.tar.gz |
ODROID-C4: introduce new board ODROID-C4 and its board configuration
Change-Id: I112d1c669784fd989405c6dfe788e084eb09785e
-rw-r--r-- | board/amlogic/Kconfig | 9 | ||||
-rw-r--r-- | board/hardkernel/odroidc4/Kconfig | 22 | ||||
-rw-r--r-- | board/hardkernel/odroidc4/Makefile | 3 | ||||
-rw-r--r-- | board/hardkernel/odroidc4/aml-user-key.sig | bin | 0 -> 6976 bytes | |||
-rw-r--r-- | board/hardkernel/odroidc4/firmware/scp_task/pwm_ctrl.h | 40 | ||||
-rw-r--r-- | board/hardkernel/odroidc4/firmware/scp_task/pwr_ctrl.c | 179 | ||||
-rw-r--r-- | board/hardkernel/odroidc4/firmware/timing.c | 357 | ||||
-rw-r--r-- | board/hardkernel/odroidc4/odroidc4.c | 416 | ||||
-rw-r--r-- | configs/odroidc4_defconfig | 6 | ||||
-rw-r--r-- | include/configs/odroidc4.h | 17 |
10 files changed, 1049 insertions, 0 deletions
diff --git a/board/amlogic/Kconfig b/board/amlogic/Kconfig index c2ccdf48e4..2597603959 100644 --- a/board/amlogic/Kconfig +++ b/board/amlogic/Kconfig @@ -274,6 +274,11 @@ config ODROID_N2 select ODROID_COMMON default n +config ODROID_C4 + bool "Support Hardkernel ODROID-C3 board" + select ODROID_COMMON + default n + if GXB_SKT_V1 source "board/amlogic/gxb_skt_v1/Kconfig" endif @@ -534,3 +539,7 @@ endif if ODROID_N2 source "board/hardkernel/odroidn2/Kconfig" endif + +if ODROID_C4 +source "board/hardkernel/odroidc4/Kconfig" +endif diff --git a/board/hardkernel/odroidc4/Kconfig b/board/hardkernel/odroidc4/Kconfig new file mode 100644 index 0000000000..bb3467cd68 --- /dev/null +++ b/board/hardkernel/odroidc4/Kconfig @@ -0,0 +1,22 @@ +if TARGET_MESON_G12A + +config SYS_CPU + string + default "armv8" + +config SYS_BOARD + string + default "odroidc4" + +config SYS_VENDOR + string + default "hardkernel" + +config SYS_SOC + string + default "g12a" + +config SYS_CONFIG_NAME + default "odroidc4" + +endif diff --git a/board/hardkernel/odroidc4/Makefile b/board/hardkernel/odroidc4/Makefile new file mode 100644 index 0000000000..567e550274 --- /dev/null +++ b/board/hardkernel/odroidc4/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS += -Iboard/hardkernel/odroid-common + +obj-y += $(BOARD).o diff --git a/board/hardkernel/odroidc4/aml-user-key.sig b/board/hardkernel/odroidc4/aml-user-key.sig Binary files differnew file mode 100644 index 0000000000..2ceabc16e0 --- /dev/null +++ b/board/hardkernel/odroidc4/aml-user-key.sig diff --git a/board/hardkernel/odroidc4/firmware/scp_task/pwm_ctrl.h b/board/hardkernel/odroidc4/firmware/scp_task/pwm_ctrl.h new file mode 100644 index 0000000000..11dc06b99b --- /dev/null +++ b/board/hardkernel/odroidc4/firmware/scp_task/pwm_ctrl.h @@ -0,0 +1,40 @@ +/* + * board/hardkernel/odroidc4/firmware/scp_task/pwr_ctrl.h + * table for Dynamic Voltage/Frequency Scaling + */ +#ifndef __PWM_CTRL_H__ +#define __PWM_CTRL_H__ + +static int pwm_voltage_table_ee[][2] = { + { 0x1c0000, 681}, + { 0x1b0001, 691}, + { 0x1a0002, 701}, + { 0x190003, 711}, + { 0x180004, 721}, + { 0x170005, 731}, + { 0x160006, 741}, + { 0x150007, 751}, + { 0x140008, 761}, + { 0x130009, 772}, + { 0x12000a, 782}, + { 0x11000b, 792}, + { 0x10000c, 802}, + { 0x0f000d, 812}, + { 0x0e000e, 822}, + { 0x0d000f, 832}, + { 0x0c0010, 842}, + { 0x0b0011, 852}, + { 0x0a0012, 862}, + { 0x090013, 872}, + { 0x080014, 882}, + { 0x070015, 892}, + { 0x060016, 902}, + { 0x050017, 912}, + { 0x040018, 922}, + { 0x030019, 932}, + { 0x02001a, 942}, + { 0x01001b, 952}, + { 0x00001c, 962} +}; + +#endif //__PWM_CTRL_H__ diff --git a/board/hardkernel/odroidc4/firmware/scp_task/pwr_ctrl.c b/board/hardkernel/odroidc4/firmware/scp_task/pwr_ctrl.c new file mode 100644 index 0000000000..7b782a5700 --- /dev/null +++ b/board/hardkernel/odroidc4/firmware/scp_task/pwr_ctrl.c @@ -0,0 +1,179 @@ +/* + * board/hardkernel/odroidc4/firmware/scp_task/pwr_ctrl.c + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <gpio.h> +#include "pwm_ctrl.h" + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +static void set_vddee_voltage(unsigned int target_voltage) +{ + unsigned int to; + + for (to = 0; to < ARRAY_SIZE(pwm_voltage_table_ee); to++) { + if (pwm_voltage_table_ee[to][1] >= target_voltage) { + break; + } + } + + if (to >= ARRAY_SIZE(pwm_voltage_table_ee)) { + to = ARRAY_SIZE(pwm_voltage_table_ee) - 1; + } + + writel(pwm_voltage_table_ee[to][0],AO_PWM_PWM_B); +} + +static void power_off_at_24M(unsigned int suspend_from) +{ + /*set gpioH_8 low to power off vcc 5v*/ + writel(readl(PREG_PAD_GPIO3_EN_N) & (~(1 << 8)), PREG_PAD_GPIO3_EN_N); + writel(readl(PERIPHS_PIN_MUX_C) & (~(0xf)), PERIPHS_PIN_MUX_C); + + /*set test_n low to power off vcck & vcc 3.3v*/ + writel(readl(AO_GPIO_O) & (~(1 << 31)), AO_GPIO_O); + writel(readl(AO_GPIO_O_EN_N) & (~(1 << 31)), AO_GPIO_O_EN_N); + writel(readl(AO_RTI_PIN_MUX_REG1) & (~(0xf << 28)), AO_RTI_PIN_MUX_REG1); + + /*step down ee voltage*/ + set_vddee_voltage(CONFIG_VDDEE_SLEEP_VOLTAGE); +} + +static void power_on_at_24M(unsigned int suspend_from) +{ + /*step up ee voltage*/ + set_vddee_voltage(CONFIG_VDDEE_INIT_VOLTAGE); + + /*set test_n low to power on vcck & vcc 3.3v*/ + writel(readl(AO_GPIO_O) | (1 << 31), AO_GPIO_O); + writel(readl(AO_GPIO_O_EN_N) & (~(1 << 31)), AO_GPIO_O_EN_N); + writel(readl(AO_RTI_PIN_MUX_REG1) & (~(0xf << 28)), AO_RTI_PIN_MUX_REG1); + _udelay(100); + + /*set gpioH_8 low to power on vcc 5v*/ + writel(readl(PREG_PAD_GPIO3_EN_N) | (1 << 8), PREG_PAD_GPIO3_EN_N); + writel(readl(PERIPHS_PIN_MUX_C) & (~(0xf)), PERIPHS_PIN_MUX_C); + _udelay(10000); +} + +void get_wakeup_source(void *response, unsigned int suspend_from) +{ + struct wakeup_info *p = (struct wakeup_info *)response; + struct wakeup_gpio_info *gpio; + unsigned val; + unsigned i = 0; + + p->status = RESPONSE_OK; + val = (POWER_KEY_WAKEUP_SRC | AUTO_WAKEUP_SRC | REMOTE_WAKEUP_SRC | + RTC_WAKEUP_SRC | BT_WAKEUP_SRC | ETH_PHY_GPIO_SRC); + + p->sources = val; + + /* Power Key: AO_GPIO[3]*/ + gpio = &(p->gpio_info[i]); + gpio->wakeup_id = POWER_KEY_WAKEUP_SRC; + gpio->gpio_in_idx = GPIOAO_3; + gpio->gpio_in_ao = 1; + gpio->gpio_out_idx = -1; + gpio->gpio_out_ao = -1; + gpio->irq = IRQ_AO_GPIO0_NUM; + gpio->trig_type = GPIO_IRQ_FALLING_EDGE; + p->gpio_info_count = ++i; + + /*Eth:GPIOZ_14*/ + gpio = &(p->gpio_info[i]); + gpio->wakeup_id = ETH_PHY_GPIO_SRC; + gpio->gpio_in_idx = GPIOZ_14; + gpio->gpio_in_ao = 0; + gpio->gpio_out_idx = -1; + gpio->gpio_out_ao = -1; + gpio->irq = IRQ_GPIO1_NUM; + gpio->trig_type = GPIO_IRQ_FALLING_EDGE; + p->gpio_info_count = ++i; + +} +extern void __switch_idle_task(void); + +static unsigned int detect_key(unsigned int suspend_from) +{ + int exit_reason = 0; + unsigned *irq = (unsigned *)WAKEUP_SRC_IRQ_ADDR_BASE; +#ifdef CONFIG_ADC_KEY + unsigned char adc_key_cnt = 0; + saradc_enable(); +#endif + init_remote(); + + do { + if (irq[IRQ_AO_IR_DEC] == IRQ_AO_IR_DEC_NUM) { + irq[IRQ_AO_IR_DEC] = 0xFFFFFFFF; + if (remote_detect_key()) + exit_reason = REMOTE_WAKEUP; + } + +#ifdef CONFIG_ADC_KEY + if (irq[IRQ_AO_TIMERA] == IRQ_AO_TIMERA_NUM) { + irq[IRQ_AO_TIMERA] = 0xFFFFFFFF; + if (check_adc_key_resume()) { + adc_key_cnt++; + /*using variable 'adc_key_cnt' to eliminate the dithering of the key*/ + if (2 == adc_key_cnt) + exit_reason = POWER_KEY_WAKEUP; + } else { + adc_key_cnt = 0; + } + } +#endif + +#ifdef CONFIG_GPIO_POWER_KEY + if (irq[IRQ_AO_GPIO0] == IRQ_AO_GPIO0_NUM) { + irq[IRQ_AO_GPIO0] = 0xFFFFFFFF; + if ((readl(AO_GPIO_I) & (1<<3)) == 0) + exit_reason = POWER_KEY_WAKEUP; + } +#endif + +#if 0 + if (irq[IRQ_GPIO1] == IRQ_GPIO1_NUM) { + irq[IRQ_GPIO1] = 0xFFFFFFFF; + if (!(readl(PREG_PAD_GPIO4_I) & (0x01 << 14)) + && (readl(PREG_PAD_GPIO4_EN_N) & (0x01 << 14))) + exit_reason = ETH_PHY_GPIO; + } +#endif + if (exit_reason) + break; + else + __switch_idle_task(); + } while (1); + +#ifdef CONFIG_ADC_KEY + saradc_disable(); +#endif + + return exit_reason; +} + +static void pwr_op_init(struct pwr_op *pwr_op) +{ + pwr_op->power_off_at_24M = power_off_at_24M; + pwr_op->power_on_at_24M = power_on_at_24M; + pwr_op->detect_key = detect_key; + pwr_op->get_wakeup_source = get_wakeup_source; +} diff --git a/board/hardkernel/odroidc4/firmware/timing.c b/board/hardkernel/odroidc4/firmware/timing.c new file mode 100644 index 0000000000..4dcaa6c918 --- /dev/null +++ b/board/hardkernel/odroidc4/firmware/timing.c @@ -0,0 +1,357 @@ +/* + * board/hardkernel/odroidc4/firmware/timing.c + * + * (C) Copyright 2019 Hardkernel Co., Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <asm/arch/secure_apb.h> +#include <asm/arch/timing.h> +#include <asm/arch/ddr_define.h> + + + +/* ddr config support multiple configs for boards which use same bootloader: + * config steps: + * 1. add a new data struct in __ddr_setting[] + * 2. config correct board_id, ddr_type, freq, etc.. + */ + + +/* CAUTION!! */ +/* Confirm ddr configs with hardware designer, + * if you don't know how to config, then don't edit it + */ + +/* Key configs */ +/* + * board_id: check hardware adc config + * dram_rank_config: + * #define CONFIG_DDR_CHL_AUTO 0xF + * #define CONFIG_DDR0_16BIT_CH0 0x1 + * #define CONFIG_DDR0_16BIT_RANK01_CH0 0x4 + * #define CONFIG_DDR0_32BIT_RANK0_CH0 0x2 + * #define CONFIG_DDR0_32BIT_RANK01_CH01 0x3 + * #define CONFIG_DDR0_32BIT_16BIT_RANK0_CH0 0x5 + * #define CONFIG_DDR0_32BIT_16BIT_RANK01_CH0 0x6 + * DramType: + * #define CONFIG_DDR_TYPE_DDR3 0 + * #define CONFIG_DDR_TYPE_DDR4 1 + * #define CONFIG_DDR_TYPE_LPDDR4 2 + * #define CONFIG_DDR_TYPE_LPDDR3 3 + * DRAMFreq: + * {pstate0, pstate1, pstate2, pstate3} //more than one pstate means use dynamic freq + * + */ + + +/* ddr configs */ +#define DDR_RFC_TYPE_DDR3_512Mbx1 0 +#define DDR_RFC_TYPE_DDR3_512Mbx2 1 +#define DDR_RFC_TYPE_DDR3_512Mbx4 2 +#define DDR_RFC_TYPE_DDR3_512Mbx8 3 +#define DDR_RFC_TYPE_DDR3_512Mbx16 4 +#define DDR_RFC_TYPE_DDR4_2Gbx1 5 +#define DDR_RFC_TYPE_DDR4_2Gbx2 6 +#define DDR_RFC_TYPE_DDR4_2Gbx4 7 +#define DDR_RFC_TYPE_DDR4_2Gbx8 8 + +#define DDR_RFC_TYPE_LPDDR4_2Gbx1 9 +#define DDR_RFC_TYPE_LPDDR4_3Gbx1 10 +#define DDR_RFC_TYPE_LPDDR4_4Gbx1 11 + +#define CONFIG_DDR4_DEFAULT_CLK 1320 + +ddr_set_t __ddr_setting[] = { +{ + /* odroid-c4 ddr4 : (4Gbitx2)x2, (8Gbitx2)x2 */ + .board_id = CONFIG_BOARD_ID_MASK, + .version = 1, + .dram_rank_config = CONFIG_DDR0_32BIT_RANK01_CH0, /* bus width 32bit, use cs0 cs1 */ + .DramType = CONFIG_DDR_TYPE_DDR4, + /* 912 (DDR4-1866) / 1056 (DDR4-2133) / 1200 (DDR4-2400)/ 1320 (DDR4-2666) */ + .DRAMFreq = {CONFIG_DDR4_DEFAULT_CLK, 0, 0, 0}, + .ddr_rfc_type = DDR_RFC_TYPE_DDR4_2Gbx8, + .ddr_base_addr = CFG_DDR_BASE_ADDR, + .ddr_start_offset = CFG_DDR_START_OFFSET, + .imem_load_addr = 0xFFFC0000, /* sram */ + .dmem_load_size = 0x1000, /* 4K */ + + .DisabledDbyte = 0xf0, + .Is2Ttiming = 1, + .HdtCtrl = 0xC8, + .dram_cs0_size_MB = 0xffff, + .dram_cs1_size_MB = 0xffff, + .training_SequenceCtrl = {0x31f,0x61}, /* ddr3 0x21f 0x31f */ + .phy_odt_config_rank = {0x30,0x30,0x30,0x30}, /* Odt pattern for accesses, targeting rank 0. [3:0] is used, for write ODT [7:4] is used for, read ODT */ + .dfi_odt_config = 0x0808, + .PllBypassEn = 0, /* bit0-ps0,bit1-ps1 */ + .ddr_rdbi_wr_enable = 0, + .clk_drv_ohm = 40, + .cs_drv_ohm = 40, + .ac_drv_ohm = 40, + .soc_data_drv_ohm_p = 34, + .soc_data_drv_ohm_n = 34, + .soc_data_odt_ohm_p = 60, + .soc_data_odt_ohm_n = 0, + .dram_data_drv_ohm = 48, /* ddr4 sdram only 34 or 48, skt board use 34 better */ + .dram_data_odt_ohm = 60, + .dram_ac_odt_ohm = 0, + .soc_clk_slew_rate = 0x3ff, + .soc_cs_slew_rate = 0x3ff, + .soc_ac_slew_rate = 0x3ff, + .soc_data_slew_rate = 0x2ff, + .vref_output_permil = 500, + .vref_receiver_permil = 700, + .vref_dram_permil = 700, + //.vref_reverse = 0, + .ac_trace_delay = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}, + .ac_pinmux = {00, 00}, + .ddr_dmc_remap = { + [0] = ( 5 | 7 << 5 | 8 << 10 | 9 << 15 | 10 << 20 | 11 << 25 ), + [1] = ( 12| 0 << 5 | 0 << 10 | 14 << 15 | 15 << 20 | 16 << 25 ), + [2] = ( 17| 18 << 5 | 19 << 10 | 21 << 15 | 22 << 20 | 23 << 25 ), + [3] = ( 24| 25 << 5 | 26 << 10 | 27 << 15 | 28 << 20 | 29 << 25 ), + [4] = ( 30| 13 << 5 | 20 << 10 | 6 << 15 | 0 << 20 | 0 << 25 ), + }, + .ddr_lpddr34_ca_remap = {00,00}, + .ddr_lpddr34_dq_remap = {00,00}, + .dram_rtt_nom_wr_park = {00,00}, + .pll_ssc_mode = 0, + .ddr_func = DDR_FUNC, + .magic = DRAM_CFG_MAGIC, +}, +{ + /* odroid-c4 ddr4 : 8Gbitx2 */ + .board_id = CONFIG_BOARD_ID_MASK, + .version = 1, + .dram_rank_config = CONFIG_DDR0_32BIT_RANK0_CH0, /* bus width 32bit, use cs0 only */ + .DramType = CONFIG_DDR_TYPE_DDR4, + /* 912 (DDR4-1866) / 1056 (DDR4-2133) / 1200 (DDR4-2400)/ 1320 (DDR4-2666) */ + .DRAMFreq = {CONFIG_DDR4_DEFAULT_CLK, 0, 0, 0}, + .ddr_rfc_type = DDR_RFC_TYPE_DDR4_2Gbx8, + .ddr_base_addr = CFG_DDR_BASE_ADDR, + .ddr_start_offset = CFG_DDR_START_OFFSET, + .imem_load_addr = 0xFFFC0000, /* sram */ + .dmem_load_size = 0x1000, /* 4K */ + + .DisabledDbyte = 0xf0, + .Is2Ttiming = 1, + .HdtCtrl = 0xC8, + .dram_cs0_size_MB = 0xffff, + .dram_cs1_size_MB = 0, + .training_SequenceCtrl = {0x31f,0x61}, /* ddr3 0x21f 0x31f */ + .phy_odt_config_rank = {0x30,0x30,0x30,0x30}, /* Odt pattern for accesses, targeting rank 0. [3:0] is used, for write ODT [7:4] is used for, read ODT */ + .dfi_odt_config = 0x0808, + .PllBypassEn = 0, /* bit0-ps0,bit1-ps1 */ + .ddr_rdbi_wr_enable = 0, + .clk_drv_ohm = 40, + .cs_drv_ohm = 40, + .ac_drv_ohm = 40, + .soc_data_drv_ohm_p = 34, + .soc_data_drv_ohm_n = 34, + .soc_data_odt_ohm_p = 60, + .soc_data_odt_ohm_n = 0, + .dram_data_drv_ohm = 48, /* ddr4 sdram only 34 or 48, skt board use 34 better */ + .dram_data_odt_ohm = 60, + .dram_ac_odt_ohm = 0, + .soc_clk_slew_rate = 0x3ff, + .soc_cs_slew_rate = 0x3ff, + .soc_ac_slew_rate = 0x3ff, + .soc_data_slew_rate = 0x2ff, + .vref_output_permil = 500, + .vref_receiver_permil = 700, + .vref_dram_permil = 700, + //.vref_reverse = 0, + .ac_trace_delay = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}, + .ac_pinmux = {00, 00}, + .ddr_dmc_remap = { + [0] = ( 5 | 7 << 5 | 8 << 10 | 9 << 15 | 10 << 20 | 11 << 25 ), + [1] = ( 12| 0 << 5 | 0 << 10 | 14 << 15 | 15 << 20 | 16 << 25 ), + [2] = ( 17| 18 << 5 | 19 << 10 | 21 << 15 | 22 << 20 | 23 << 25 ), + [3] = ( 24| 25 << 5 | 26 << 10 | 27 << 15 | 28 << 20 | 29 << 25 ), + [4] = ( 30| 13 << 5 | 20 << 10 | 6 << 15 | 0 << 20 | 0 << 25 ), + }, + .ddr_lpddr34_ca_remap = {00,00}, + .ddr_lpddr34_dq_remap = {00,00}, + .dram_rtt_nom_wr_park = {00,00}, + .pll_ssc_mode = 0, + .ddr_func = DDR_FUNC, + .magic = DRAM_CFG_MAGIC, +}, +}; + +pll_set_t __pll_setting = { + .cpu_clk = CONFIG_CPU_CLK / 24 * 24, +#ifdef CONFIG_PXP_EMULATOR + .pxp = 1, +#else + .pxp = 0, +#endif + .spi_ctrl = 0, + .lCustomerID = CONFIG_AML_CUSTOMER_ID, +#ifdef CONFIG_DEBUG_MODE + .debug_mode = CONFIG_DEBUG_MODE, + .ddr_clk_debug = CONFIG_DDR_CLK_DEBUG, + .cpu_clk_debug = CONFIG_CPU_CLK_DEBUG, +#endif +}; + +ddr_reg_t __ddr_reg[] = { + /* demo, user defined override register */ + {0xaabbccdd, 0, 0, 0, 0, 0}, + {0x11223344, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0}, +}; + +#define VCCK_VAL CONFIG_VCCK_INIT_VOLTAGE +#define VDDEE_VAL CONFIG_VDDEE_INIT_VOLTAGE +/* VCCK PWM table */ +#if (VCCK_VAL == 800) + #define VCCK_VAL_REG 0x00150007 +#elif (VCCK_VAL == 810) + #define VCCK_VAL_REG 0x00140008 +#elif (VCCK_VAL == 820) + #define VCCK_VAL_REG 0x00130009 +#elif (VCCK_VAL == 830) + #define VCCK_VAL_REG 0x0012000a +#elif (VCCK_VAL == 840) + #define VCCK_VAL_REG 0x0011000b +#elif (VCCK_VAL == 850) + #define VCCK_VAL_REG 0x0010000c +#elif (VCCK_VAL == 860) + #define VCCK_VAL_REG 0x000f000d +#elif (VCCK_VAL == 870) + #define VCCK_VAL_REG 0x000e000e +#elif (VCCK_VAL == 880) + #define VCCK_VAL_REG 0x000d000f +#elif (VCCK_VAL == 890) + #define VCCK_VAL_REG 0x000c0010 +#elif (VCCK_VAL == 900) + #define VCCK_VAL_REG 0x000b0011 +#elif (VCCK_VAL == 910) + #define VCCK_VAL_REG 0x000a0012 +#elif (VCCK_VAL == 920) + #define VCCK_VAL_REG 0x00090013 +#elif (VCCK_VAL == 930) + #define VCCK_VAL_REG 0x00080014 +#elif (VCCK_VAL == 940) + #define VCCK_VAL_REG 0x00070015 +#elif (VCCK_VAL == 950) + #define VCCK_VAL_REG 0x00060016 +#elif (VCCK_VAL == 960) + #define VCCK_VAL_REG 0x00050017 +#elif (VCCK_VAL == 970) + #define VCCK_VAL_REG 0x00040018 +#elif (VCCK_VAL == 980) + #define VCCK_VAL_REG 0x00030019 +#elif (VCCK_VAL == 990) + #define VCCK_VAL_REG 0x0002001a +#elif (VCCK_VAL == 1000) + #define VCCK_VAL_REG 0x0001001b +#elif (VCCK_VAL == 1010) + #define VCCK_VAL_REG 0x0000001c +#else + #error "VCCK val out of range\n" +#endif + +/* VDDEE_VAL_REG0: VDDEE PWM table 0.67v-0.97v*/ +/* VDDEE_VAL_REG1: VDDEE PWM table 0.69v-0.89v*/ +#if (VDDEE_VAL == 800) + #define VDDEE_VAL_REG0 0x0010000c + #define VDDEE_VAL_REG1 0x0008000a +#elif (VDDEE_VAL == 810) + #define VDDEE_VAL_REG0 0x000f000d + #define VDDEE_VAL_REG1 0x0007000b +#elif (VDDEE_VAL == 820) + #define VDDEE_VAL_REG0 0x000e000e + #define VDDEE_VAL_REG1 0x0006000c +#elif (VDDEE_VAL == 830) + #define VDDEE_VAL_REG0 0x000d000f + #define VDDEE_VAL_REG1 0x0005000d +#elif (VDDEE_VAL == 840) + #define VDDEE_VAL_REG0 0x000c0010 + #define VDDEE_VAL_REG1 0x0004000e +#elif (VDDEE_VAL == 850) + #define VDDEE_VAL_REG0 0x000b0011 + #define VDDEE_VAL_REG1 0x0003000f +#elif (VDDEE_VAL == 860) + #define VDDEE_VAL_REG0 0x000a0012 + #define VDDEE_VAL_REG1 0x00020010 +#elif (VDDEE_VAL == 870) + #define VDDEE_VAL_REG0 0x00090013 + #define VDDEE_VAL_REG1 0x00010011 +#elif (VDDEE_VAL == 880) + #define VDDEE_VAL_REG0 0x00080014 + #define VDDEE_VAL_REG1 0x00000012 +#else + #error "VDDEE val out of range\n" +#endif + +/* for PWM use */ +/* PWM driver check http://scgit.amlogic.com:8080/#/c/38093/ */ +#define GPIO_O_EN_N_REG3 ((0xff634400 + (0x19 << 2))) +#define GPIO_O_REG3 ((0xff634400 + (0x1a << 2))) +#define GPIO_I_REG3 ((0xff634400 + (0x1b << 2))) +#define AO_PIN_MUX_REG0 ((0xff800000 + (0x05 << 2))) +#define AO_PIN_MUX_REG1 ((0xff800000 + (0x06 << 2))) + +bl2_reg_t __bl2_reg[] = { + /* demo, user defined override register */ + /* eg: PWM init */ + + /* PWM_AO_D */ + /* VCCK_VAL_REG: check PWM table */ + {AO_PWM_PWM_D, VCCK_VAL_REG, 0xffffffff, 0, BL2_INIT_STAGE_1, 0}, + {AO_PWM_MISC_REG_CD, ((1 << 23) | (1 << 1)), (0x7f << 16), 0, BL2_INIT_STAGE_1, 0}, + {AO_PIN_MUX_REG1, (3 << 20), (0xF << 20), 0, BL2_INIT_STAGE_1, 0}, + + /* set BOOT_9 input */ + //{PAD_PULL_UP_EN_REG0, 1 << 9, 1 << 9, 0, BL2_INIT_STAGE_1, 0}, + + /* PWM_AO_B */ + /* VDDEE init start */ + /* step1: CHK HW */ + {(uint64_t)P_ASSIST_POR_CONFIG, 7, 0, 0, BL2_INIT_STAGE_PWM_CHK_HW, 0}, + + /* step2: match PWM config */ + /* GPIO9[BIT7]=H use PWM_CFG0(0.67v-0.97v), =L use PWM_CFG1(0.69v-0.89v) */ + {0x1, PWM_CFG0, 0, 0, BL2_INIT_STAGE_PWM_CFG_GROUP, 0}, + {0x0, PWM_CFG1, 0, 0, BL2_INIT_STAGE_PWM_CFG_GROUP, 0}, + + /* step3: config PWM */ + /* VDDEE_VAL_REG0: VDDEE PWM table 0.67v-0.97v*/ + {AO_PWM_PWM_B, VDDEE_VAL_REG0, 0xffffffff, 0, BL2_INIT_STAGE_PWM_INIT | PWM_CFG0, 0}, + {AO_PWM_MISC_REG_AB, ((1 << 23) | (1 << 1)), (0x7f << 16), 0, BL2_INIT_STAGE_PWM_INIT | PWM_CFG0, 0}, + {AO_PIN_MUX_REG1, (3 << 16), (0xF << 16), 0, BL2_INIT_STAGE_PWM_INIT | PWM_CFG0, 0}, + /* VDDEE_VAL_REG1: VDDEE PWM table 0.69v-0.89v*/ + {AO_PWM_PWM_B, VDDEE_VAL_REG1, 0xffffffff, 0, BL2_INIT_STAGE_PWM_INIT | PWM_CFG1, 0}, + {AO_PWM_MISC_REG_AB, ((1 << 23) | (1 << 1)), (0x7f << 16), 0, BL2_INIT_STAGE_PWM_INIT | PWM_CFG1, 0}, + {AO_PIN_MUX_REG1, (3 << 16), (0xF << 16), 0, BL2_INIT_STAGE_PWM_INIT | PWM_CFG1, 0}, + /* VDDEE init done */ + /* Enable 5V_EN */ +#if 0 // FIXME + {GPIO_O_EN_N_REG3, (0 << 8), (1 << 8), 0, BL2_INIT_STAGE_1, 0}, + {GPIO_O_REG3, (1 << 8), 0xffffffff, 0, BL2_INIT_STAGE_1, 0}, +#endif + /* Enable VCCK */ + {AO_SEC_REG0, (1 << 0), 0xffffffff, 0, BL2_INIT_STAGE_1, 0}, + {AO_GPIO_O, (1 << 31), 0xffffffff, 0, BL2_INIT_STAGE_1, 0}, + + /* Init sys led*/ + {AO_GPIO_O_EN_N, (0 << 11), (1 << 11), 0, BL2_INIT_STAGE_1, 0}, + {AO_GPIO_O, (0 << 11), (1 << 11), 0, BL2_INIT_STAGE_1, 0}, +}; diff --git a/board/hardkernel/odroidc4/odroidc4.c b/board/hardkernel/odroidc4/odroidc4.c new file mode 100644 index 0000000000..0879573cbf --- /dev/null +++ b/board/hardkernel/odroidc4/odroidc4.c @@ -0,0 +1,416 @@ +/* + * board/hardkernel/odroidc4/odroidc4.c + * + * (C) Copyright 2019 Hardkernel Co., Ltd + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <malloc.h> +#include <errno.h> +#include <environment.h> +#include <fdt_support.h> +#include <libfdt.h> +#include <asm/cpu_id.h> +#include <asm/arch/secure_apb.h> +#ifdef CONFIG_SYS_I2C_AML +#include <aml_i2c.h> +#endif +#ifdef CONFIG_AML_VPU +#include <vpu.h> +#endif +#include <vpp.h> +#ifdef CONFIG_AML_HDMITX20 +#include <amlogic/hdmi.h> +#endif +#include <asm/arch/eth_setup.h> +#include <phy.h> +#include <linux/mtd/partitions.h> +#include <linux/sizes.h> +#include <asm-generic/gpio.h> +#include <dm.h> +#ifdef CONFIG_AML_SPIFC +#include <amlogic/spifc.h> +#endif + +#include <odroid-common.h> + +DECLARE_GLOBAL_DATA_PTR; + +//new static eth setup +struct eth_board_socket* eth_board_skt; + + +int serial_set_pin_port(unsigned long port_base) +{ + //UART in "Always On Module" + //GPIOAO_0==tx,GPIOAO_1==rx + //setbits_le32(P_AO_RTI_PIN_MUX_REG,3<<11); + return 0; +} + +int dram_init(void) +{ + gd->ram_size = (((readl(AO_SEC_GP_CFG0)) & 0xFFFF0000) << 4); + return 0; +} + +/* secondary_boot_func + * this function should be write with asm, here, is is only for compiling pass + * */ +void secondary_boot_func(void) +{ +} + +#ifdef ETHERNET_EXTERNAL_PHY + +static int dwmac_meson_cfg_drive_strength(void) +{ + writel(0xaaaaaaa5, P_PAD_DS_REG4A); + return 0; +} + +static void setup_net_chip_ext(void) +{ + eth_aml_reg0_t eth_reg0; + writel(0x11111111, P_PERIPHS_PIN_MUX_6); + writel(0x111111, P_PERIPHS_PIN_MUX_7); + + eth_reg0.d32 = 0; + eth_reg0.b.phy_intf_sel = 1; + eth_reg0.b.rx_clk_rmii_invert = 0; + eth_reg0.b.rgmii_tx_clk_src = 0; + eth_reg0.b.rgmii_tx_clk_phase = 1; + eth_reg0.b.rgmii_tx_clk_ratio = 4; + eth_reg0.b.phy_ref_clk_enable = 1; + eth_reg0.b.clk_rmii_i_invert = 0; + eth_reg0.b.clk_en = 1; + eth_reg0.b.adj_enable = 0; + eth_reg0.b.adj_setup = 0; + eth_reg0.b.adj_delay = 0; + eth_reg0.b.adj_skew = 0; + eth_reg0.b.cali_start = 0; + eth_reg0.b.cali_rise = 0; + eth_reg0.b.cali_sel = 0; + eth_reg0.b.rgmii_rx_reuse = 0; + eth_reg0.b.eth_urgent = 0; + setbits_le32(P_PREG_ETH_REG0, eth_reg0.d32);// rmii mode + + setbits_le32(HHI_GCLK_MPEG1, 0x1 << 3); + /* power on memory */ + clrbits_le32(HHI_MEM_PD_REG0, (1 << 3) | (1<<2)); +} +#endif +extern struct eth_board_socket* eth_board_setup(char *name); +extern int designware_initialize(ulong base_addr, u32 interface); + +int board_eth_init(bd_t *bis) +{ +#ifdef ETHERNET_EXTERNAL_PHY + dwmac_meson_cfg_drive_strength(); + setup_net_chip_ext(); +#endif + udelay(1000); + designware_initialize(ETH_BASE, PHY_INTERFACE_MODE_RMII); + return 0; +} + +#if CONFIG_AML_SD_EMMC +#include <mmc.h> +#include <asm/arch/sd_emmc.h> +static int sd_emmc_init(unsigned port) +{ + switch (port) + { + case SDIO_PORT_A: + break; + case SDIO_PORT_B: + //todo add card detect + /* check card detect */ + clrbits_le32(P_PERIPHS_PIN_MUX_9, 0xF << 24); + setbits_le32(P_PREG_PAD_GPIO1_EN_N, 1 << 6); + setbits_le32(P_PAD_PULL_UP_EN_REG1, 1 << 6); + setbits_le32(P_PAD_PULL_UP_REG1, 1 << 6); + break; + case SDIO_PORT_C: + //enable pull up + //clrbits_le32(P_PAD_PULL_UP_REG3, 0xff<<0); + break; + default: + break; + } + + return cpu_sd_emmc_init(port); +} + +extern unsigned sd_debug_board_1bit_flag; + + +static void sd_emmc_pwr_prepare(unsigned port) +{ + cpu_sd_emmc_pwr_prepare(port); +} + +static void sd_emmc_pwr_on(unsigned port) +{ + switch (port) + { + case SDIO_PORT_A: + break; + case SDIO_PORT_B: + // clrbits_le32(P_PREG_PAD_GPIO5_O,(1<<31)); //CARD_8 + // clrbits_le32(P_PREG_PAD_GPIO5_EN_N,(1<<31)); + /// @todo NOT FINISH + break; + case SDIO_PORT_C: + break; + default: + break; + } + return; +} +static void sd_emmc_pwr_off(unsigned port) +{ + /// @todo NOT FINISH + switch (port) + { + case SDIO_PORT_A: + break; + case SDIO_PORT_B: + // setbits_le32(P_PREG_PAD_GPIO5_O,(1<<31)); //CARD_8 + // clrbits_le32(P_PREG_PAD_GPIO5_EN_N,(1<<31)); + break; + case SDIO_PORT_C: + break; + default: + break; + } + return; +} + +// #define CONFIG_TSD 1 +static void board_mmc_register(unsigned port) +{ + struct aml_card_sd_info *aml_priv=cpu_sd_emmc_get(port); + if (aml_priv == NULL) + return; + + aml_priv->sd_emmc_init=sd_emmc_init; + aml_priv->sd_emmc_detect=sd_emmc_detect; + aml_priv->sd_emmc_pwr_off=sd_emmc_pwr_off; + aml_priv->sd_emmc_pwr_on=sd_emmc_pwr_on; + aml_priv->sd_emmc_pwr_prepare=sd_emmc_pwr_prepare; + aml_priv->desc_buf = malloc(NEWSD_MAX_DESC_MUN*(sizeof(struct sd_emmc_desc_info))); + + if (NULL == aml_priv->desc_buf) + printf(" desc_buf Dma alloc Fail!\n"); + else + printf("aml_priv->desc_buf = 0x%p\n",aml_priv->desc_buf); + + sd_emmc_register(aml_priv); +} +int board_mmc_init(bd_t *bis) +{ + board_mmc_register(SDIO_PORT_C); // eMMC + board_mmc_register(SDIO_PORT_B); // SD card + + return 0; +} +#endif + +#ifdef CONFIG_SYS_I2C_AML +struct aml_i2c_platform g_aml_i2c_plat = { + .wait_count = 1000000, + .wait_ack_interval = 5, + .wait_read_interval = 5, + .wait_xfer_interval = 5, + .master_no = AML_I2C_MASTER_AO, + .use_pio = 0, + .master_i2c_speed = AML_I2C_SPPED_400K, + .master_ao_pinmux = { + .scl_reg = (unsigned long)MESON_I2C_MASTER_AO_GPIOAO_4_REG, + .scl_bit = MESON_I2C_MASTER_AO_GPIOAO_4_BIT, + .sda_reg = (unsigned long)MESON_I2C_MASTER_AO_GPIOAO_5_REG, + .sda_bit = MESON_I2C_MASTER_AO_GPIOAO_5_BIT, + } +}; +#endif + +#if defined(CONFIG_BOARD_EARLY_INIT_F) +int board_early_init_f(void){ + /*add board early init function here*/ + return 0; +} +#endif + +#ifdef CONFIG_USB_XHCI_AMLOGIC_V2 +#include <asm/arch/usb-v2.h> +#include <asm/arch/gpio.h> +#define CONFIG_GXL_USB_U2_PORT_NUM 2 + +#ifdef CONFIG_USB_XHCI_AMLOGIC_USB3_V2 +#define CONFIG_GXL_USB_U3_PORT_NUM 1 +#else +#define CONFIG_GXL_USB_U3_PORT_NUM 0 +#endif + +static void gpio_set_vbus_power(char is_power_on) +{ + int ret; + + /* USB Host power enable/disable */ + usbhost_set_power(is_power_on); + + /* usb otg power enable */ + ret = gpio_request(CONFIG_USB_GPIO_PWR, + CONFIG_USB_GPIO_PWR_NAME); + if (ret && ret != -EBUSY) { + printf("gpio: requesting pin %u failed\n", + CONFIG_USB_GPIO_PWR); + return; + } + + gpio_direction_output(CONFIG_USB_GPIO_PWR, !!is_power_on); +} + +struct amlogic_usb_config g_usb_config_GXL_skt={ + CONFIG_GXL_XHCI_BASE, + USB_ID_MODE_HARDWARE, + gpio_set_vbus_power,//gpio_set_vbus_power, //set_vbus_power + CONFIG_GXL_USB_PHY2_BASE, + CONFIG_GXL_USB_PHY3_BASE, + CONFIG_GXL_USB_U2_PORT_NUM, + CONFIG_GXL_USB_U3_PORT_NUM, + .usb_phy2_pll_base_addr = { + CONFIG_USB_PHY_20, + CONFIG_USB_PHY_21, + } +}; + +#endif /*CONFIG_USB_XHCI_AMLOGIC*/ + +#ifdef CONFIG_AML_HDMITX20 +static void hdmi_tx_set_hdmi_5v(void) +{ +} +#endif + +#ifdef CONFIG_AML_SPIFC +/* + * BOOT_3: NOR_HOLDn:reg0[15:12]=3 + * BOOT_4: NOR_D:reg0[19:16]=3 + * BOOT_5: NOR_Q:reg0[23:20]=3 + * BOOT_6: NOR_C:reg0[27:24]=3 + * BOOT_7: NOR_WPn:reg0[31:28]=3 + * BOOT_14: NOR_CS:reg1[27:24]=3 + */ +#define SPIFC_NUM_CS 1 +static int spifc_cs_gpios[SPIFC_NUM_CS] = {54}; + +static int spifc_pinctrl_enable(void *pinctrl, bool enable) +{ + unsigned int val; + + val = readl(P_PERIPHS_PIN_MUX_0); + val &= ~(0xfffff << 12); + if (enable) + val |= 0x33333 << 12; + writel(val, P_PERIPHS_PIN_MUX_0); + + val = readl(P_PERIPHS_PIN_MUX_1); + val &= ~(0xf << 24); + writel(val, P_PERIPHS_PIN_MUX_1); + return 0; +} + +static const struct spifc_platdata spifc_platdata = { + .reg = 0xffd14000, + .mem_map = 0xf6000000, + .pinctrl_enable = spifc_pinctrl_enable, + .num_chipselect = SPIFC_NUM_CS, + .cs_gpios = spifc_cs_gpios, +}; + +U_BOOT_DEVICE(spifc) = { + .name = "spifc", + .platdata = &spifc_platdata, +}; +#endif /* CONFIG_AML_SPIFC */ + +int board_init(void) +{ + board_led_alive(1); + +#ifdef CONFIG_USB_XHCI_AMLOGIC_V2 + board_usb_pll_disable(&g_usb_config_GXL_skt); + board_usb_init(&g_usb_config_GXL_skt,BOARD_USB_MODE_HOST); +#endif /*CONFIG_USB_XHCI_AMLOGIC*/ + + return 0; +} + +#if !defined(CONFIG_FASTBOOT_FLASH_MMC_DEV) +#define CONFIG_FASTBOOT_FLASH_MMC_DEV 0 +#endif + +extern void cvbs_init(void); + +#ifdef CONFIG_BOARD_LATE_INIT +int board_late_init(void) +{ +#if defined(CONFIG_FASTBOOT_FLASH_MMC_DEV) + /* select the default mmc device */ + int mmc_devnum = CONFIG_FASTBOOT_FLASH_MMC_DEV; + + if (get_boot_device() == BOOT_DEVICE_EMMC) + mmc_devnum = 0; + else if (get_boot_device() == BOOT_DEVICE_SD) + mmc_devnum = 1; + + /* select the default mmc device */ + mmc_select_hwpart(mmc_devnum, 0); +#endif +#ifdef CONFIG_AML_VPU + vpu_probe(); +#endif + vpp_init(); +#ifdef CONFIG_AML_HDMITX20 + hdmi_tx_set_hdmi_5v(); + hdmi_tx_init(); +#endif + +#ifdef CONFIG_AML_CVBS + run_command("cvbs init; cvbs output 480cvbs", 0); + board_cvbs_probe(); +#endif + + /* boot logo display - 1080p60hz */ + run_command("showlogo", 0); + + if (get_boot_device() == BOOT_DEVICE_SPI) { + setenv("bootdelay", "0"); + setenv("bootcmd", "run booting_from_spi"); + } + + usbhost_early_poweron(); + + return 0; +} +#endif + +/* SECTION_SHIFT is 29 that means 512MB size */ +#define SECTION_SHIFT 29 +phys_size_t get_effective_memsize(void) +{ + phys_size_t size_aligned; + + size_aligned = (((readl(AO_SEC_GP_CFG0)) & 0xFFFF0000) << 4); + size_aligned = ((size_aligned >> SECTION_SHIFT) << SECTION_SHIFT); + +#if defined(CONFIG_SYS_MEM_TOP_HIDE) + size_aligned = size_aligned - CONFIG_SYS_MEM_TOP_HIDE; +#endif + + return size_aligned; +} diff --git a/configs/odroidc4_defconfig b/configs/odroidc4_defconfig new file mode 100644 index 0000000000..d8e5d0234a --- /dev/null +++ b/configs/odroidc4_defconfig @@ -0,0 +1,6 @@ +CONFIG_ARM=y +CONFIG_TARGET_MESON_G12A=y +CONFIG_ODROID_C4=y +CONFIG_DM=y +CONFIG_DM_GPIO=y +CONFIG_AML_GPIO=y diff --git a/include/configs/odroidc4.h b/include/configs/odroidc4.h new file mode 100644 index 0000000000..8b6c735b34 --- /dev/null +++ b/include/configs/odroidc4.h @@ -0,0 +1,17 @@ +/* + * include/configs/odroidc4.h + * + * (C) Copyright 2018 Hardkernel Co., Ltd + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ODROID_C4_H__ +#define __ODROID_C4_H__ + +#define CONFIG_DEVICE_PRODUCT "odroidc4" +#define ODROID_BOARD_UUID "9098004a-a1dd-11e8-98d0-529269fb1459" + +#include "odroid-g12-common.h" + +#endif |