Files
MilkV-Duo/u-boot-2021.10/board/cvitek/cv181x/board.c
wangliang.wang 607778300c [uboot] Upgrade the MMF SDK from V4.0.0 to V4.1.0
1. add cv181x functions
	2. Delete some useless files and add .gitignore

Change-Id: Iea2b2fa43b5a1152e5e99fb32b88f8d2c249251a
2023-03-10 20:42:30 +08:00

347 lines
9.1 KiB
C

/*
* (C) Copyright 2013
* David Feng <fenghua@phytium.com.cn>
* Sharma Bhupesh <bhupesh.sharma@freescale.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <malloc.h>
#include <errno.h>
#include <asm/io.h>
#include <linux/compiler.h>
#if defined(__aarch64__)
#include <asm/armv8/mmu.h>
#endif
#include <usb/dwc2_udc.h>
#include <usb.h>
#include "cv181x_reg.h"
#include "mmio.h"
#include "cv181x_reg_fmux_gpio.h"
#include "cv181x_pinlist_swconfig.h"
#include <linux/delay.h>
#include <bootstage.h>
#if defined(__riscv)
#include <asm/csr.h>
#endif
DECLARE_GLOBAL_DATA_PTR;
#define SD1_SDIO_PAD
#if defined(__aarch64__)
static struct mm_region cv181x_mem_map[] = {
{
.virt = 0x0UL,
.phys = 0x0UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
.virt = PHYS_SDRAM_1,
.phys = PHYS_SDRAM_1,
.size = PHYS_SDRAM_1_SIZE,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
}, {
/* List terminator */
0,
}
};
struct mm_region *mem_map = cv181x_mem_map;
#endif
// #define PINMUX_CONFIG(PIN_NAME, FUNC_NAME) printf ("%s\n", PIN_NAME ##_ ##FUNC_NAME);
#define PINMUX_CONFIG(PIN_NAME, FUNC_NAME) \
mmio_clrsetbits_32(PINMUX_BASE + FMUX_GPIO_FUNCSEL_##PIN_NAME, \
FMUX_GPIO_FUNCSEL_##PIN_NAME##_MASK << FMUX_GPIO_FUNCSEL_##PIN_NAME##_OFFSET, \
PIN_NAME##__##FUNC_NAME)
void pinmux_config(int io_type)
{
switch (io_type) {
case PINMUX_UART0:
PINMUX_CONFIG(UART0_RX, UART0_RX);
PINMUX_CONFIG(UART0_TX, UART0_TX);
break;
case PINMUX_SDIO0:
PINMUX_CONFIG(SD0_CD, SDIO0_CD);
PINMUX_CONFIG(SD0_PWR_EN, SDIO0_PWR_EN);
PINMUX_CONFIG(SD0_CMD, SDIO0_CMD);
PINMUX_CONFIG(SD0_CLK, SDIO0_CLK);
PINMUX_CONFIG(SD0_D0, SDIO0_D_0);
PINMUX_CONFIG(SD0_D1, SDIO0_D_1);
PINMUX_CONFIG(SD0_D2, SDIO0_D_2);
PINMUX_CONFIG(SD0_D3, SDIO0_D_3);
break;
case PINMUX_SDIO1:
#if defined(SD1_SDIO_PAD)
/*
* Name Address SD1 MIPI
* reg_sd1_phy_sel REG_0x300_0294[10] 0x0 0x1
*/
mmio_write_32(TOP_BASE + 0x294,
(mmio_read_32(TOP_BASE + 0x294) & 0xFFFFFBFF));
PINMUX_CONFIG(SD1_CMD, PWR_SD1_CMD_VO36);
PINMUX_CONFIG(SD1_CLK, PWR_SD1_CLK_VO37);
PINMUX_CONFIG(SD1_D0, PWR_SD1_D0_VO35);
PINMUX_CONFIG(SD1_D1, PWR_SD1_D1_VO34);
PINMUX_CONFIG(SD1_D2, PWR_SD1_D2_VO33);
PINMUX_CONFIG(SD1_D3, PWR_SD1_D3_VO32);
#elif defined(SD1_MIPI_PAD)
/*
* Name Address SD1 MIPI
* reg_sd1_phy_sel REG_0x300_0294[10] 0x0 0x1
*/
mmio_write_32(TOP_BASE + 0x294,
(mmio_read_32(TOP_BASE + 0x294) & 0xFFFFFBFF) | BIT(10));
PINMUX_CONFIG(PAD_MIPI_TXM4, SD1_CLK);
PINMUX_CONFIG(PAD_MIPI_TXP4, SD1_CMD);
PINMUX_CONFIG(PAD_MIPI_TXM3, SD1_D0);
PINMUX_CONFIG(PAD_MIPI_TXP3, SD1_D1);
PINMUX_CONFIG(PAD_MIPI_TXM2, SD1_D2);
PINMUX_CONFIG(PAD_MIPI_TXP2, SD1_D3);
#endif
break;
case PINMUX_EMMC:
PINMUX_CONFIG(EMMC_CLK, EMMC_CLK);
PINMUX_CONFIG(EMMC_RSTN, EMMC_RSTN);
PINMUX_CONFIG(EMMC_CMD, EMMC_CMD);
PINMUX_CONFIG(EMMC_DAT1, EMMC_DAT_1);
PINMUX_CONFIG(EMMC_DAT0, EMMC_DAT_0);
PINMUX_CONFIG(EMMC_DAT2, EMMC_DAT_2);
PINMUX_CONFIG(EMMC_DAT3, EMMC_DAT_3);
break;
case PINMUX_SPI_NAND:
PINMUX_CONFIG(EMMC_DAT2, SPINAND_HOLD);
PINMUX_CONFIG(EMMC_CLK, SPINAND_CLK);
PINMUX_CONFIG(EMMC_DAT0, SPINAND_MOSI);
PINMUX_CONFIG(EMMC_DAT3, SPINAND_WP);
PINMUX_CONFIG(EMMC_CMD, SPINAND_MISO);
PINMUX_CONFIG(EMMC_DAT1, SPINAND_CS);
break;
case PINMUX_DSI:
PINMUX_CONFIG(PAD_MIPI_TXM0, XGPIOC_12);
PINMUX_CONFIG(PAD_MIPI_TXP0, XGPIOC_13);
PINMUX_CONFIG(PAD_MIPI_TXM1, XGPIOC_14);
PINMUX_CONFIG(PAD_MIPI_TXP1, XGPIOC_15);
PINMUX_CONFIG(PAD_MIPI_TXM2, XGPIOC_16);
PINMUX_CONFIG(PAD_MIPI_TXP2, XGPIOC_17);
PINMUX_CONFIG(PAD_MIPI_TXM3, XGPIOC_20);
PINMUX_CONFIG(PAD_MIPI_TXP3, XGPIOC_21);
PINMUX_CONFIG(PAD_MIPI_TXM4, XGPIOC_18);
PINMUX_CONFIG(PAD_MIPI_TXP4, XGPIOC_19);
break;
case PINMUX_LVDS:
PINMUX_CONFIG(PAD_MIPI_TXM0, XGPIOC_12);
PINMUX_CONFIG(PAD_MIPI_TXP0, XGPIOC_13);
PINMUX_CONFIG(PAD_MIPI_TXM1, XGPIOC_14);
PINMUX_CONFIG(PAD_MIPI_TXP1, XGPIOC_15);
PINMUX_CONFIG(PAD_MIPI_TXM2, XGPIOC_16);
PINMUX_CONFIG(PAD_MIPI_TXP2, XGPIOC_17);
PINMUX_CONFIG(PAD_MIPI_TXM3, XGPIOC_20);
PINMUX_CONFIG(PAD_MIPI_TXP3, XGPIOC_21);
PINMUX_CONFIG(PAD_MIPI_TXM4, XGPIOC_18);
PINMUX_CONFIG(PAD_MIPI_TXP4, XGPIOC_19);
break;
default:
break;
}
}
#include "../cvi_board_init.c"
#if defined(CONFIG_PHY_CVITEK) /* config cvitek cv181x eth internal phy on ASIC board */
static void cv181x_ephy_id_init(void)
{
// set rg_ephy_apb_rw_sel 0x0804@[0]=1/APB by using APB interface
mmio_write_32(0x03009804, 0x0001);
// Release 0x0800[0]=0/shutdown
mmio_write_32(0x03009800, 0x0900);
// Release 0x0800[2]=1/dig_rst_n, Let mii_reg can be accessabile
mmio_write_32(0x03009800, 0x0904);
// ANA INIT (PD/EN), switch to MII-page5
mmio_write_32(0x0300907c, 0x0500);
// Release ANA_PD p5.0x10@[13:8] = 6'b001100
mmio_write_32(0x03009040, 0x0c00);
// Release ANA_EN p5.0x10@[7:0] = 8'b01111110
mmio_write_32(0x03009040, 0x0c7e);
// Wait PLL_Lock, Lock_Status p5.0x12@[15] = 1
//mdelay(1);
// Release 0x0800[1] = 1/ana_rst_n
mmio_write_32(0x03009800, 0x0906);
// ANA INIT
// @Switch to MII-page5
mmio_write_32(0x0300907c, 0x0500);
// PHY_ID
mmio_write_32(0x03009008, 0x0043);
mmio_write_32(0x0300900c, 0x5649);
// switch to MDIO control by ETH_MAC
mmio_write_32(0x03009804, 0x0000);
}
static void cv181x_ephy_led_pinmux(void)
{
// LED PAD MUX
mmio_write_32(0x030010e0, 0x05);
mmio_write_32(0x030010e4, 0x05);
//(SD1_CLK selphy)
mmio_write_32(0x050270b0, 0x11111111);
//(SD1_CMD selphy)
mmio_write_32(0x050270b4, 0x11111111);
}
#endif
void cpu_pwr_ctrl(void)
{
#if defined(CONFIG_RISCV)
mmio_write_32(0x01901008, 0x30001);// cortexa53_pwr_iso_en
#elif defined(CONFIG_ARM)
mmio_write_32(0x01901004, 0x30001);// c906_top_pwr_iso_en
#endif
}
int board_init(void)
{
#ifndef CONFIG_TARGET_CVITEK_CV181X_FPGA
extern volatile uint32_t BOOT0_START_TIME;
uint16_t start_time = DIV_ROUND_UP(BOOT0_START_TIME, SYS_COUNTER_FREQ_IN_SECOND / 1000);
// Save uboot start time. time is from boot0.h
mmio_write_16(TIME_RECORDS_FIELD_UBOOT_START, start_time);
#endif
cpu_pwr_ctrl();
#if defined(CONFIG_PHY_CVITEK) /* config cvitek cv181x eth internal phy on ASIC board */
cv181x_ephy_id_init();
cv181x_ephy_led_pinmux();
#endif
#if defined(CONFIG_NAND_SUPPORT)
pinmux_config(PINMUX_SPI_NAND);
#elif defined(CONFIG_SPI_FLASH)
pinmux_config(PINMUX_SPI_NOR);
#elif defined(CONFIG_EMMC_SUPPORT)
pinmux_config(PINMUX_EMMC);
#endif
#ifdef CONFIG_DISPLAY_CVITEK_MIPI
pinmux_config(PINMUX_DSI);
#elif defined(CONFIG_DISPLAY_CVITEK_LVDS)
pinmux_config(PINMUX_LVDS);
#endif
pinmux_config(PINMUX_SDIO1);
cvi_board_init();
return 0;
}
#if defined(__aarch64__)
int dram_init(void)
{
gd->ram_size = PHYS_SDRAM_1_SIZE;
return 0;
}
int dram_init_banksize(void)
{
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
return 0;
}
#endif
#ifdef CV_SYS_OFF
static void cv_system_off(void)
{
mmio_write_32(REG_RTC_BASE + RTC_EN_SHDN_REQ, 0x01);
while (mmio_read_32(REG_RTC_BASE + RTC_EN_SHDN_REQ) != 0x01)
;
mmio_write_32(REG_RTC_CTRL_BASE + RTC_CTRL0_UNLOCKKEY, 0xAB18);
mmio_setbits_32(REG_RTC_CTRL_BASE + RTC_CTRL0, 0xFFFF0800 | (0x1 << 0));
while (1)
;
}
#endif
void cv_system_reset(void)
{
mmio_write_32(REG_RTC_BASE + RTC_EN_WARM_RST_REQ, 0x01);
while (mmio_read_32(REG_RTC_BASE + RTC_EN_WARM_RST_REQ) != 0x01)
;
mmio_write_32(REG_RTC_CTRL_BASE + RTC_CTRL0_UNLOCKKEY, 0xAB18);
mmio_setbits_32(REG_RTC_CTRL_BASE + RTC_CTRL0, 0xFFFF0800 | (0x1 << 4));
while (1)
;
}
/*
* Board specific reset that is system reset.
*/
void reset_cpu(void)
{
cv_system_reset();
}
#ifdef CONFIG_USB_GADGET_DWC2_OTG
struct dwc2_plat_otg_data cv182x_otg_data = {
.regs_otg = USB_BASE,
.usb_gusbcfg = 0x40081400,
.rx_fifo_sz = 512,
.np_tx_fifo_sz = 512,
.tx_fifo_sz = 512,
};
int board_usb_init(int index, enum usb_init_type init)
{
uint32_t value;
value = mmio_read_32(TOP_BASE + REG_TOP_SOFT_RST) & (~BIT_TOP_SOFT_RST_USB);
mmio_write_32(TOP_BASE + REG_TOP_SOFT_RST, value);
udelay(50);
value = mmio_read_32(TOP_BASE + REG_TOP_SOFT_RST) | BIT_TOP_SOFT_RST_USB;
mmio_write_32(TOP_BASE + REG_TOP_SOFT_RST, value);
/* Set USB phy configuration */
value = mmio_read_32(REG_TOP_USB_PHY_CTRL);
mmio_write_32(REG_TOP_USB_PHY_CTRL, value | BIT_TOP_USB_PHY_CTRL_EXTVBUS
| USB_PHY_ID_OVERRIDE_ENABLE
| USB_PHY_ID_VALUE);
/* Enable ECO RXF */
mmio_write_32(REG_TOP_USB_ECO, mmio_read_32(REG_TOP_USB_ECO) | BIT_TOP_USB_ECO_RX_FLUSH);
printf("cvi_usb_hw_init done\n");
return dwc2_udc_probe(&cv182x_otg_data);
}
#endif
void board_save_time_record(uintptr_t saveaddr)
{
uint64_t boot_us = 0;
#if defined(__aarch64__)
boot_us = timer_get_boot_us();
#elif defined(__riscv)
// Read from CSR_TIME directly. RISC-V timers is initialized later.
boot_us = csr_read(CSR_TIME) / (SYS_COUNTER_FREQ_IN_SECOND / 1000000);
#else
#error "Unknown ARCH"
#endif
mmio_write_16(saveaddr, DIV_ROUND_UP(boot_us, 1000));
}