mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-08-20 17:08:52 +09:00
![Niel Fourie](/assets/img/avatar_default.png)
Support for Phytech phyCORE AM335x R2 SOM (PCL060) on the Phytec phyBOARD-Wega AM335x. CPU : AM335X-GP rev 2.1 Model: Phytec AM335x phyBOARD-WEGA DRAM: 256 MiB NAND: 256 MiB MMC: OMAP SD/MMC: 0 eth0: ethernet@4a100000 Working: - Eth0 - i2C - MMC/SD - NAND - UART - USB (host) Device trees were taken from Linux mainline: commit 37624b58542f ("Linux 5.1-rc7") Signed-off-by: Niel Fourie <lusus@denx.de> Signed-off-by: Parthiban Nallathambi <pn@denx.de> Reviewed-by: Heiko Schocher <hs@denx.de> Reviewed-by: Tom Rini <trini@konsulko.com> Tested-by: Marek Vasut <marex@denx.de>
261 lines
5.8 KiB
C
261 lines
5.8 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* board.c
|
|
*
|
|
* Board functions for Phytec phyCORE-AM335x R2 (PCL060 / PCM060) based boards
|
|
*
|
|
* Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
|
|
* Copyright (C) 2013 Lars Poeschel, Lemonage Software GmbH
|
|
* Copyright (C) 2015 Wadim Egorov, PHYTEC Messtechnik GmbH
|
|
* Copyright (C) 2019 DENX Software Engineering GmbH
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <spl.h>
|
|
#include <asm/arch/cpu.h>
|
|
#include <asm/arch/ddr_defs.h>
|
|
#include <asm/arch/clock.h>
|
|
#include <asm/arch/sys_proto.h>
|
|
#include <power/tps65910.h>
|
|
#include <jffs2/load_kernel.h>
|
|
#include <mtd_node.h>
|
|
#include <fdt_support.h>
|
|
#include "board.h"
|
|
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
|
|
#ifdef CONFIG_SPL_BUILD
|
|
|
|
static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
|
|
|
|
/* DDR RAM defines */
|
|
#define DDR_CLK_MHZ 400 /* DDR_DPLL_MULT value */
|
|
|
|
#define OSC (V_OSCK / 1000000)
|
|
const struct dpll_params dpll_ddr = {
|
|
DDR_CLK_MHZ, OSC - 1, 1, -1, -1, -1, -1};
|
|
|
|
const struct dpll_params *get_dpll_ddr_params(void)
|
|
{
|
|
return &dpll_ddr;
|
|
}
|
|
|
|
const struct ctrl_ioregs ioregs = {
|
|
.cm0ioctl = 0x18B,
|
|
.cm1ioctl = 0x18B,
|
|
.cm2ioctl = 0x18B,
|
|
.dt0ioctl = 0x18B,
|
|
.dt1ioctl = 0x18B,
|
|
};
|
|
|
|
static const struct cmd_control ddr3_cmd_ctrl_data = {
|
|
.cmd0csratio = 0x80,
|
|
.cmd0iclkout = 0x0,
|
|
|
|
.cmd1csratio = 0x80,
|
|
.cmd1iclkout = 0x0,
|
|
|
|
.cmd2csratio = 0x80,
|
|
.cmd2iclkout = 0x0,
|
|
};
|
|
|
|
enum {
|
|
PHYCORE_R2_MT41K128M16JT_256MB,
|
|
PHYCORE_R2_MT41K256M16TW107IT_512MB,
|
|
PHYCORE_R2_MT41K512M16HA125IT_1024MB,
|
|
};
|
|
|
|
struct am335x_sdram_timings {
|
|
struct emif_regs ddr3_emif_reg_data;
|
|
struct ddr_data ddr3_data;
|
|
};
|
|
|
|
static struct am335x_sdram_timings physom_timings[] = {
|
|
[PHYCORE_R2_MT41K128M16JT_256MB] = {
|
|
.ddr3_emif_reg_data = {
|
|
.sdram_config = 0x61C052B2,
|
|
.ref_ctrl = 0x00000C30,
|
|
.sdram_tim1 = 0x0AAAD4DB,
|
|
.sdram_tim2 = 0x26437FDA,
|
|
.sdram_tim3 = 0x501F83FF,
|
|
.zq_config = 0x50074BE4,
|
|
.emif_ddr_phy_ctlr_1 = 0x7,
|
|
.ocp_config = 0x003d3d3d,
|
|
},
|
|
.ddr3_data = {
|
|
.datardsratio0 = 0x36,
|
|
.datawdsratio0 = 0x38,
|
|
.datafwsratio0 = 0x99,
|
|
.datawrsratio0 = 0x73,
|
|
},
|
|
},
|
|
[PHYCORE_R2_MT41K256M16TW107IT_512MB] = {
|
|
.ddr3_emif_reg_data = {
|
|
.sdram_config = 0x61C05332,
|
|
.ref_ctrl = 0x00000C30,
|
|
.sdram_tim1 = 0x0AAAD4DB,
|
|
.sdram_tim2 = 0x266B7FDA,
|
|
.sdram_tim3 = 0x501F867F,
|
|
.zq_config = 0x50074BE4,
|
|
.emif_ddr_phy_ctlr_1 = 0x7,
|
|
.ocp_config = 0x003d3d3d,
|
|
},
|
|
.ddr3_data = {
|
|
.datardsratio0 = 0x37,
|
|
.datawdsratio0 = 0x38,
|
|
.datafwsratio0 = 0x92,
|
|
.datawrsratio0 = 0x72,
|
|
},
|
|
},
|
|
[PHYCORE_R2_MT41K512M16HA125IT_1024MB] = {
|
|
.ddr3_emif_reg_data = {
|
|
.sdram_config = 0x61C053B2,
|
|
.ref_ctrl = 0x00000C30,
|
|
.sdram_tim1 = 0x0AAAD4DB,
|
|
.sdram_tim2 = 0x268F7FDA,
|
|
.sdram_tim3 = 0x501F88BF,
|
|
.zq_config = 0x50074BE4,
|
|
.emif_ddr_phy_ctlr_1 = 0x7,
|
|
.ocp_config = 0x003d3d3d,
|
|
},
|
|
.ddr3_data = {
|
|
.datardsratio0 = 0x38,
|
|
.datawdsratio0 = 0x4d,
|
|
.datafwsratio0 = 0x9d,
|
|
.datawrsratio0 = 0x82,
|
|
},
|
|
},
|
|
};
|
|
|
|
void sdram_init(void)
|
|
{
|
|
/* Configure memory to maximum supported size for detection */
|
|
int ram_type_index = PHYCORE_R2_MT41K512M16HA125IT_1024MB;
|
|
|
|
config_ddr(DDR_CLK_MHZ, &ioregs,
|
|
&physom_timings[ram_type_index].ddr3_data,
|
|
&ddr3_cmd_ctrl_data,
|
|
&physom_timings[ram_type_index].ddr3_emif_reg_data,
|
|
0);
|
|
|
|
/* Detect memory physically present */
|
|
gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
|
|
CONFIG_MAX_RAM_BANK_SIZE);
|
|
|
|
/* Reconfigure memory for actual detected size */
|
|
switch (gd->ram_size) {
|
|
case SZ_1G:
|
|
ram_type_index = PHYCORE_R2_MT41K512M16HA125IT_1024MB;
|
|
break;
|
|
case SZ_512M:
|
|
ram_type_index = PHYCORE_R2_MT41K256M16TW107IT_512MB;
|
|
break;
|
|
case SZ_256M:
|
|
default:
|
|
ram_type_index = PHYCORE_R2_MT41K128M16JT_256MB;
|
|
break;
|
|
}
|
|
config_ddr(DDR_CLK_MHZ, &ioregs,
|
|
&physom_timings[ram_type_index].ddr3_data,
|
|
&ddr3_cmd_ctrl_data,
|
|
&physom_timings[ram_type_index].ddr3_emif_reg_data,
|
|
0);
|
|
}
|
|
|
|
const struct dpll_params *get_dpll_mpu_params(void)
|
|
{
|
|
int ind = get_sys_clk_index();
|
|
int freq = am335x_get_efuse_mpu_max_freq(cdev);
|
|
|
|
switch (freq) {
|
|
case MPUPLL_M_1000:
|
|
return &dpll_mpu_opp[ind][5];
|
|
case MPUPLL_M_800:
|
|
return &dpll_mpu_opp[ind][4];
|
|
case MPUPLL_M_720:
|
|
return &dpll_mpu_opp[ind][3];
|
|
case MPUPLL_M_600:
|
|
return &dpll_mpu_opp[ind][2];
|
|
case MPUPLL_M_500:
|
|
return &dpll_mpu_opp100;
|
|
case MPUPLL_M_300:
|
|
return &dpll_mpu_opp[ind][0];
|
|
}
|
|
|
|
return &dpll_mpu_opp[ind][0];
|
|
}
|
|
|
|
static void scale_vcores_generic(int freq)
|
|
{
|
|
int sil_rev, mpu_vdd;
|
|
|
|
/*
|
|
* We use a TPS65910 PMIC. For all MPU frequencies we support we use a
|
|
* CORE voltage of 1.10V. For MPU voltage we need to switch based on
|
|
* the frequency we are running at.
|
|
*/
|
|
if (power_tps65910_init(0))
|
|
return;
|
|
|
|
/*
|
|
* Depending on MPU clock and PG we will need a different
|
|
* VDD to drive at that speed.
|
|
*/
|
|
sil_rev = readl(&cdev->deviceid) >> 28;
|
|
mpu_vdd = am335x_get_tps65910_mpu_vdd(sil_rev, freq);
|
|
|
|
/* Tell the TPS65910 to use i2c */
|
|
tps65910_set_i2c_control();
|
|
|
|
/* First update MPU voltage. */
|
|
if (tps65910_voltage_update(MPU, mpu_vdd))
|
|
return;
|
|
|
|
/* Second, update the CORE voltage. */
|
|
if (tps65910_voltage_update(CORE, TPS65910_OP_REG_SEL_1_1_0))
|
|
return;
|
|
}
|
|
|
|
void scale_vcores(void)
|
|
{
|
|
int freq;
|
|
|
|
freq = am335x_get_efuse_mpu_max_freq(cdev);
|
|
scale_vcores_generic(freq);
|
|
}
|
|
|
|
void set_uart_mux_conf(void)
|
|
{
|
|
enable_uart0_pin_mux();
|
|
}
|
|
|
|
void set_mux_conf_regs(void)
|
|
{
|
|
enable_i2c0_pin_mux();
|
|
enable_board_pin_mux();
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* Basic board specific setup. Pinmux has been handled already.
|
|
*/
|
|
int board_init(void)
|
|
{
|
|
gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
|
|
return 0;
|
|
}
|
|
|
|
#ifdef CONFIG_OF_BOARD_SETUP
|
|
int ft_board_setup(void *blob, bd_t *bd)
|
|
{
|
|
#ifdef CONFIG_FDT_FIXUP_PARTITIONS
|
|
static const struct node_info nodes[] = {
|
|
{ "ti,omap2-nand", MTD_DEV_TYPE_NAND, },
|
|
};
|
|
|
|
fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
|
|
#endif
|
|
return 0;
|
|
}
|
|
#endif
|