| |
| /* |
| * 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; |
| } |