blob: 2f8677c1e85df62d4ed745f1db04e3e972470eaa [file] [log] [blame]
/*
* board/amlogic/txl_skt_v1/txl_skt_v1.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 <common.h>
#include <malloc.h>
#include <errno.h>
#include <environment.h>
#include <fdt_support.h>
#include <linux/libfdt.h>
#include <asm/arch/cpu_id.h>
#include <asm/arch/secure_apb.h>
#include <asm/arch/pinctrl_init.h>
#ifdef CONFIG_AML_VPU
#include <amlogic/media/vpu/vpu.h>
#endif
#ifdef CONFIG_AML_VPP
#include <amlogic/media/vpp/vpp.h>
#endif
#ifdef CONFIG_AML_V2_FACTORY_BURN
#include <amlogic/aml_v2_burning.h>
#endif// #ifdef CONFIG_AML_V2_FACTORY_BURN
#ifdef CONFIG_AML_HDMITX
#include <amlogic/media/vout/hdmitx.h>
#endif
#ifdef CONFIG_AML_LCD
#include <amlogic/media/vout/lcd/aml_lcd.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>
#include <asm/armv8/mmu.h>
DECLARE_GLOBAL_DATA_PTR;
//new static eth setup
struct eth_board_socket* eth_board_skt;
void sys_led_init(void)
{
//set GPIOAO_11 drive strength
setbits_le32(AO_PAD_DS_A,(3<<22)); //GPIOAO_11 set drive strength "3"
}
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 = PHYS_SDRAM_1_SIZE;
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_INTERNAL_PHY
void internalPhyConfig(struct phy_device *phydev)
{
}
static int dwmac_meson_cfg_pll(void)
{
writel(0x39C0040A, P_ETH_PLL_CTL0);
writel(0x927E0000, P_ETH_PLL_CTL1);
writel(0xAC5F49E5, P_ETH_PLL_CTL2);
writel(0x00000000, P_ETH_PLL_CTL3);
udelay(200);
writel(0x19C0040A, P_ETH_PLL_CTL0);
return 0;
}
static int dwmac_meson_cfg_analog(void)
{
/*Analog*/
writel(0x20200000, P_ETH_PLL_CTL5);
writel(0x0000c002, P_ETH_PLL_CTL6);
writel(0x00000023, P_ETH_PLL_CTL7);
return 0;
}
static int dwmac_meson_cfg_ctrl(void)
{
/*config phyid should between a 0~0xffffffff*/
/*please don't use 44000181, this has been used by internal phy*/
writel(0x33000180, P_ETH_PHY_CNTL0);
/*use_phy_smi | use_phy_ip | co_clkin from eth_phy_top*/
writel(0x260, P_ETH_PHY_CNTL2);
writel(0x74043, P_ETH_PHY_CNTL1);
writel(0x34043, P_ETH_PHY_CNTL1);
writel(0x74043, P_ETH_PHY_CNTL1);
return 0;
}
static void setup_net_chip(void)
{
eth_aml_reg0_t eth_reg0;
eth_reg0.d32 = 0;
eth_reg0.b.phy_intf_sel = 4;
eth_reg0.b.rx_clk_rmii_invert = 0;
eth_reg0.b.rgmii_tx_clk_src = 0;
eth_reg0.b.rgmii_tx_clk_phase = 0;
eth_reg0.b.rgmii_tx_clk_ratio = 4;
eth_reg0.b.phy_ref_clk_enable = 1;
eth_reg0.b.clk_rmii_i_invert = 1;
eth_reg0.b.clk_en = 1;
eth_reg0.b.adj_enable = 1;
eth_reg0.b.adj_setup = 0;
eth_reg0.b.adj_delay = 9;
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
dwmac_meson_cfg_pll();
dwmac_meson_cfg_analog();
dwmac_meson_cfg_ctrl();
/* eth core clock */
setbits_le32(HHI_GCLK_MPEG1, (0x1 << 3));
/* eth phy clock */
setbits_le32(HHI_GCLK_MPEG0, (0x1 << 4));
/* eth phy pll, clk50m */
setbits_le32(HHI_FIX_PLL_CNTL3, (0x1 << 5));
/* power on memory */
clrbits_le32(HHI_MEM_PD_REG0, (1 << 3) | (1<<2));
}
#endif
#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 CONFIG_ETHERNET_NONE
return 0;
#endif
#ifdef ETHERNET_EXTERNAL_PHY
dwmac_meson_cfg_drive_strength();
setup_net_chip_ext();
#endif
#ifdef ETHERNET_INTERNAL_PHY
setup_net_chip();
#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)
{
#if 0
#ifdef CONFIG_VLSI_EMULATOR
//board_mmc_register(SDIO_PORT_A);
#else
//board_mmc_register(SDIO_PORT_B);
#endif
board_mmc_register(SDIO_PORT_B);
board_mmc_register(SDIO_PORT_C);
// board_mmc_register(SDIO_PORT_B1);
#endif
return 0;
}
#endif
#if defined(CONFIG_BOARD_EARLY_INIT_F)
int board_early_init_f(void){
/*add board early init function here*/
return 0;
}
#endif
extern void aml_pwm_cal_init(int mode);
int board_init(void)
{
printf("board init\n");
//Please keep CONFIG_AML_V2_FACTORY_BURN at first place of board_init
//As NOT NEED other board init If USB BOOT MODE
#ifdef CONFIG_AML_V2_FACTORY_BURN
if ((0x1b8ec003 != readl(P_PREG_STICKY_REG2)) && (0x1b8ec004 != readl(P_PREG_STICKY_REG2))) {
aml_try_factory_usb_burning(0, gd->bd);
}
#endif// #ifdef CONFIG_AML_V2_FACTORY_BURN
pinctrl_devices_active(PIN_CONTROLLER_NUM);
#if 0
sys_led_init();
#if 0
aml_pwm_cal_init(0);
#endif//
#ifdef CONFIG_AML_NAND
extern int amlnf_init(unsigned char flag);
amlnf_init(0);
#endif
#endif
return 0;
}
/* set dts props */
void aml_config_dtb(void)
{
cpu_id_t cpuid = get_cpu_id();
run_command("fdt address $dtb_mem_addr", 0);
printf("%s %d\n", __func__, __LINE__);
if (cpuid.chip_rev == 0xA) {
printf("%s %d\n", __func__, __LINE__);
run_command("fdt set /emmc/emmc co_phase <0x2>", 0);
run_command("fdt rm /emmc/emmc caps2", 0);
run_command("fdt set /emmc/emmc f_max <0x02625a00>", 0);
run_command("fdt set /sdio status okay", 0);
run_command("fdt set /sd1 status okay", 0);
run_command("fdt set /pinctrl@ff634480/sd_clk_cmd_pins/mux drive-strength <1>", 0);
run_command("fdt set /pinctrl@ff634480/sd_clk_cmd_pins/mux1 drive-strength <1>", 0);
run_command("fdt set /pinctrl@ff634480/sd_all_pins/mux drive-strength <1>", 0);
run_command("fdt set /pinctrl@ff634480/sd_all_pins/mux1 drive-strength <1>", 0);
run_command("fdt set /pinctrl@ff634480/sdio_clk_cmd_pins/mux drive-strength <2>", 0);
run_command("fdt set /pinctrl@ff634480/sdio_all_pins/mux drive-strength <1>", 0);
/* debug */
run_command("fdt print /emmc/emmc co_phase", 0);
run_command("fdt print /emmc/emmc caps2", 0);
run_command("fdt print /emmc/emmc f_max", 0);
run_command("fdt print /sdio status", 0);
run_command("fdt print /sd1 status ", 0);
run_command("fdt print /pinctrl@ff634480/sd_clk_cmd_pins/mux drive-strength", 0);
run_command("fdt print /pinctrl@ff634480/sd_clk_cmd_pins/mux1 drive-strength", 0);
run_command("fdt print /pinctrl@ff634480/sd_all_pins/mux drive-strength", 0);
run_command("fdt print /pinctrl@ff634480/sd_all_pins/mux1 drive-strength", 0);
run_command("fdt print /pinctrl@ff634480/sdio_clk_cmd_pins/mux drive-strength", 0);
run_command("fdt print /pinctrl@ff634480/sdio_all_pins/mux drive-strength", 0);
} else {
printf("%s %d\n", __func__, __LINE__);
run_command("fdt set /emmc/emmc co_phase <0x3>", 0);
run_command("fdt set /sdio status disabled", 0);
run_command("fdt set /sd2 status okay", 0);
/* debug */
run_command("fdt print /emmc/emmc co_phase", 0);
run_command("fdt print /emmc/emmc caps2", 0);
run_command("fdt print /emmc/emmc f_max", 0);
run_command("fdt print /sdio status", 0);
run_command("fdt print /sd2 status", 0);
}
return;
}
#ifdef CONFIG_BOARD_LATE_INIT
int board_late_init(void)
{
printf("board late init\n");
#if 0
//update env before anyone using it
run_command("get_rebootmode; echo reboot_mode=${reboot_mode}; "\
"if test ${reboot_mode} = factory_reset; then "\
"defenv_reserv aml_dt;setenv upgrade_step 2;save; fi;", 0);
run_command("if itest ${upgrade_step} == 1; then "\
"defenv_reserv; setenv upgrade_step 2; saveenv; fi;", 0);
/*add board late init function here*/
#ifndef DTB_BIND_KERNEL
int ret;
ret = run_command("store dtb read $dtb_mem_addr", 1);
if (ret) {
printf("%s(): [store dtb read $dtb_mem_addr] fail\n", __func__);
#ifdef CONFIG_DTB_MEM_ADDR
char cmd[64];
printf("load dtb to %x\n", CONFIG_DTB_MEM_ADDR);
sprintf(cmd, "store dtb read %x", CONFIG_DTB_MEM_ADDR);
ret = run_command(cmd, 1);
if (ret) {
printf("%s(): %s fail\n", __func__, cmd);
}
#endif
}
#elif defined(CONFIG_DTB_MEM_ADDR)
{
char cmd[128];
int ret;
if (!getenv("dtb_mem_addr")) {
sprintf(cmd, "setenv dtb_mem_addr 0x%x", CONFIG_DTB_MEM_ADDR);
run_command(cmd, 0);
}
sprintf(cmd, "imgread dtb boot ${dtb_mem_addr}");
ret = run_command(cmd, 0);
if (ret) {
printf("%s(): cmd[%s] fail, ret=%d\n", __func__, cmd, ret);
}
}
#endif// #ifndef DTB_BIND_KERNEL
/* load unifykey */
run_command("keyunify init 0x1234", 0);
#endif
/*open vpu hdmitx and cvbs driver*/
#ifdef CONFIG_AML_VPU
vpu_probe();
#endif
#ifdef CONFIG_AML_VPP
vpp_init();
#endif
#ifdef CONFIG_AML_HDMITX
hdmi_tx_init();
#endif
#ifdef CONFIG_AML_CVBS
run_command("cvbs init", 0);
#endif
#ifdef CONFIG_AML_LCD
lcd_probe();
#endif
#if 0
/**/
aml_config_dtb();
#endif
#ifdef CONFIG_AML_V2_FACTORY_BURN
if (0x1b8ec003 == readl(P_PREG_STICKY_REG2))
aml_try_factory_usb_burning(1, gd->bd);
aml_try_factory_sdcard_burning(0, gd->bd);
#endif// #ifdef CONFIG_AML_V2_FACTORY_BURN
return 0;
}
#endif
#ifdef CONFIG_AML_TINY_USBTOOL
int usb_get_update_result(void)
{
unsigned long upgrade_step;
upgrade_step = simple_strtoul (getenv ("upgrade_step"), NULL, 16);
printf("upgrade_step = %d\n", (int)upgrade_step);
if (upgrade_step == 1)
{
run_command("defenv", 1);
run_command("setenv upgrade_step 2", 1);
run_command("saveenv", 1);
return 0;
}
else
{
return -1;
}
}
#endif
phys_size_t get_effective_memsize(void)
{
// >>16 -> MB, <<20 -> real size, so >>16<<20 = <<4
#if defined(CONFIG_SYS_MEM_TOP_HIDE)
return (((readl(AO_SEC_GP_CFG0)) & 0xFFFF0000) << 4) - CONFIG_SYS_MEM_TOP_HIDE;
#else
return (((readl(AO_SEC_GP_CFG0)) & 0xFFFF0000) << 4);
#endif
}
#ifdef CONFIG_MULTI_DTB
int checkhw(char * name)
{
/*
* read board hw id
* set and select the dts according the board hw id.
*
* hwid = 1 p321 v1
* hwid = 2 p321 v2
*/
unsigned int hwid = 1;
char loc_name[64] = {0};
/* read hwid */
hwid = (readl(P_AO_SEC_GP_CFG0) >> 8) & 0xFF;
printf("checkhw: hwid = %d\n", hwid);
switch (hwid) {
case 1:
strcpy(loc_name, "txl_p321_v1\0");
break;
case 2:
strcpy(loc_name, "txl_p321_v2\0");
break;
default:
strcpy(loc_name, "txl_p321_v1");
break;
}
strcpy(name, loc_name);
setenv("aml_dt", loc_name);
return 0;
}
#endif
static struct mm_region bd_mem_map[] = {
{
.virt = 0x0UL,
.phys = 0x0UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
}, {
.virt = 0x80000000UL,
.phys = 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 = bd_mem_map;
int print_cpuinfo(void) {
printf("print_cpuinfo\n");
return 0;
}
int mach_cpu_init(void) {
printf("mach_cpu_init\n");
return 0;
}
int ft_board_setup(void *blob, bd_t *bd)
{
/* eg: bl31/32 rsv */
return 0;
}