commit
1254ff97ab
@ -0,0 +1,238 @@ |
||||
/*
|
||||
* (C) Copyright 2015 |
||||
* Texas Instruments Incorporated, <www.ti.com> |
||||
* |
||||
* Lokesh Vutla <lokeshvutla@ti.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/utils.h> |
||||
#include <asm/arch/dra7xx_iodelay.h> |
||||
#include <asm/arch/omap.h> |
||||
#include <asm/arch/sys_proto.h> |
||||
#include <asm/arch/clock.h> |
||||
#include <asm/arch/mux_dra7xx.h> |
||||
#include <asm/omap_common.h> |
||||
|
||||
static int isolate_io(u32 isolate) |
||||
{ |
||||
if (isolate) { |
||||
clrsetbits_le32((*ctrl)->control_pbias, SDCARD_PWRDNZ, |
||||
SDCARD_PWRDNZ); |
||||
clrsetbits_le32((*ctrl)->control_pbias, SDCARD_BIAS_PWRDNZ, |
||||
SDCARD_BIAS_PWRDNZ); |
||||
} |
||||
|
||||
/* Override control on ISOCLKIN signal to IO pad ring. */ |
||||
clrsetbits_le32((*prcm)->prm_io_pmctrl, PMCTRL_ISOCLK_OVERRIDE_MASK, |
||||
PMCTRL_ISOCLK_OVERRIDE_CTRL); |
||||
if (!wait_on_value(PMCTRL_ISOCLK_STATUS_MASK, PMCTRL_ISOCLK_STATUS_MASK, |
||||
(u32 *)(*prcm)->prm_io_pmctrl, LDELAY)) |
||||
return ERR_DEISOLATE_IO << isolate; |
||||
|
||||
/* Isolate/Deisolate IO */ |
||||
clrsetbits_le32((*ctrl)->ctrl_core_sma_sw_0, CTRL_ISOLATE_MASK, |
||||
isolate << CTRL_ISOLATE_SHIFT); |
||||
/* Dummy read to add delay t > 10ns */ |
||||
readl((*ctrl)->ctrl_core_sma_sw_0); |
||||
|
||||
/* Return control on ISOCLKIN to hardware */ |
||||
clrsetbits_le32((*prcm)->prm_io_pmctrl, PMCTRL_ISOCLK_OVERRIDE_MASK, |
||||
PMCTRL_ISOCLK_NOT_OVERRIDE_CTRL); |
||||
if (!wait_on_value(PMCTRL_ISOCLK_STATUS_MASK, |
||||
0 << PMCTRL_ISOCLK_STATUS_SHIFT, |
||||
(u32 *)(*prcm)->prm_io_pmctrl, LDELAY)) |
||||
return ERR_DEISOLATE_IO << isolate; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int calibrate_iodelay(u32 base) |
||||
{ |
||||
u32 reg; |
||||
|
||||
/* Configure REFCLK period */ |
||||
reg = readl(base + CFG_REG_2_OFFSET); |
||||
reg &= ~CFG_REG_REFCLK_PERIOD_MASK; |
||||
reg |= CFG_REG_REFCLK_PERIOD; |
||||
writel(reg, base + CFG_REG_2_OFFSET); |
||||
|
||||
/* Initiate Calibration */ |
||||
clrsetbits_le32(base + CFG_REG_0_OFFSET, CFG_REG_CALIB_STRT_MASK, |
||||
CFG_REG_CALIB_STRT << CFG_REG_CALIB_STRT_SHIFT); |
||||
if (!wait_on_value(CFG_REG_CALIB_STRT_MASK, CFG_REG_CALIB_END, |
||||
(u32 *)(base + CFG_REG_0_OFFSET), LDELAY)) |
||||
return ERR_CALIBRATE_IODELAY; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int update_delay_mechanism(u32 base) |
||||
{ |
||||
/* Initiate the reload of calibrated values. */ |
||||
clrsetbits_le32(base + CFG_REG_0_OFFSET, CFG_REG_ROM_READ_MASK, |
||||
CFG_REG_ROM_READ_START); |
||||
if (!wait_on_value(CFG_REG_ROM_READ_MASK, CFG_REG_ROM_READ_END, |
||||
(u32 *)(base + CFG_REG_0_OFFSET), LDELAY)) |
||||
return ERR_UPDATE_DELAY; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static u32 calculate_delay(u32 base, u16 offset, u16 den) |
||||
{ |
||||
u16 refclk_period, dly_cnt, ref_cnt; |
||||
u32 reg, q, r; |
||||
|
||||
refclk_period = readl(base + CFG_REG_2_OFFSET) & |
||||
CFG_REG_REFCLK_PERIOD_MASK; |
||||
|
||||
reg = readl(base + offset); |
||||
dly_cnt = (reg & CFG_REG_DLY_CNT_MASK) >> CFG_REG_DLY_CNT_SHIFT; |
||||
ref_cnt = (reg & CFG_REG_REF_CNT_MASK) >> CFG_REG_REF_CNT_SHIFT; |
||||
|
||||
if (!dly_cnt || !den) |
||||
return 0; |
||||
|
||||
/*
|
||||
* To avoid overflow and integer truncation, delay value |
||||
* is calculated as quotient + remainder. |
||||
*/ |
||||
q = 5 * ((ref_cnt * refclk_period) / (dly_cnt * den)); |
||||
r = (10 * ((ref_cnt * refclk_period) % (dly_cnt * den))) / |
||||
(2 * dly_cnt * den); |
||||
|
||||
return q + r; |
||||
} |
||||
|
||||
static u32 get_cfg_reg(u16 a_delay, u16 g_delay, u32 cpde, u32 fpde) |
||||
{ |
||||
u32 g_delay_coarse, g_delay_fine; |
||||
u32 a_delay_coarse, a_delay_fine; |
||||
u32 c_elements, f_elements; |
||||
u32 total_delay, reg = 0; |
||||
|
||||
g_delay_coarse = g_delay / 920; |
||||
g_delay_fine = ((g_delay % 920) * 10) / 60; |
||||
|
||||
a_delay_coarse = a_delay / cpde; |
||||
a_delay_fine = ((a_delay % cpde) * 10) / fpde; |
||||
|
||||
c_elements = g_delay_coarse + a_delay_coarse; |
||||
f_elements = (g_delay_fine + a_delay_fine) / 10; |
||||
|
||||
if (f_elements > 22) { |
||||
total_delay = c_elements * cpde + f_elements * fpde; |
||||
|
||||
c_elements = total_delay / cpde; |
||||
f_elements = (total_delay % cpde) / fpde; |
||||
} |
||||
|
||||
reg = (c_elements << CFG_X_COARSE_DLY_SHIFT) & CFG_X_COARSE_DLY_MASK; |
||||
reg |= (f_elements << CFG_X_FINE_DLY_SHIFT) & CFG_X_FINE_DLY_MASK; |
||||
reg |= CFG_X_SIGNATURE << CFG_X_SIGNATURE_SHIFT; |
||||
reg |= CFG_X_LOCK << CFG_X_LOCK_SHIFT; |
||||
|
||||
return reg; |
||||
} |
||||
|
||||
static int do_set_iodelay(u32 base, struct iodelay_cfg_entry const *array, |
||||
int niodelays) |
||||
{ |
||||
struct iodelay_cfg_entry *iodelay = (struct iodelay_cfg_entry *)array; |
||||
u32 reg, cpde, fpde, i; |
||||
|
||||
if (!niodelays) |
||||
return 0; |
||||
|
||||
cpde = calculate_delay((*ctrl)->iodelay_config_base, CFG_REG_3_OFFSET, |
||||
88); |
||||
if (!cpde) |
||||
return ERR_CPDE; |
||||
|
||||
fpde = calculate_delay((*ctrl)->iodelay_config_base, CFG_REG_4_OFFSET, |
||||
264); |
||||
if (!fpde) |
||||
return ERR_FPDE; |
||||
|
||||
for (i = 0; i < niodelays; i++, iodelay++) { |
||||
reg = get_cfg_reg(iodelay->a_delay, iodelay->g_delay, cpde, |
||||
fpde); |
||||
writel(reg, base + iodelay->offset); |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
void __recalibrate_iodelay(struct pad_conf_entry const *pad, int npads, |
||||
struct iodelay_cfg_entry const *iodelay, |
||||
int niodelays) |
||||
{ |
||||
int ret = 0; |
||||
|
||||
/* IO recalibration should be done only from SRAM */ |
||||
if (OMAP_INIT_CONTEXT_SPL != omap_hw_init_context()) { |
||||
puts("IODELAY recalibration called from invalid context - use only from SPL in SRAM\n"); |
||||
return; |
||||
} |
||||
|
||||
/* unlock IODELAY CONFIG registers */ |
||||
writel(CFG_IODELAY_UNLOCK_KEY, (*ctrl)->iodelay_config_base + |
||||
CFG_REG_8_OFFSET); |
||||
|
||||
ret = calibrate_iodelay((*ctrl)->iodelay_config_base); |
||||
if (ret) |
||||
goto err; |
||||
|
||||
ret = isolate_io(ISOLATE_IO); |
||||
if (ret) |
||||
goto err; |
||||
|
||||
ret = update_delay_mechanism((*ctrl)->iodelay_config_base); |
||||
if (ret) |
||||
goto err; |
||||
|
||||
/* Configure Mux settings */ |
||||
do_set_mux32((*ctrl)->control_padconf_core_base, pad, npads); |
||||
|
||||
/* Configure Manual IO timing modes */ |
||||
ret = do_set_iodelay((*ctrl)->iodelay_config_base, iodelay, niodelays); |
||||
if (ret) |
||||
goto err; |
||||
|
||||
ret = isolate_io(DEISOLATE_IO); |
||||
|
||||
err: |
||||
/* lock IODELAY CONFIG registers */ |
||||
writel(CFG_IODELAY_LOCK_KEY, (*ctrl)->iodelay_config_base + |
||||
CFG_REG_8_OFFSET); |
||||
/*
|
||||
* UART cannot be used during IO recalibration sequence as IOs are in |
||||
* isolation. So error handling and debug prints are done after |
||||
* complete IO delay recalibration sequence |
||||
*/ |
||||
switch (ret) { |
||||
case ERR_CALIBRATE_IODELAY: |
||||
puts("IODELAY: IO delay calibration sequence failed\n"); |
||||
break; |
||||
case ERR_ISOLATE_IO: |
||||
puts("IODELAY: Isolation of Device IOs failed\n"); |
||||
break; |
||||
case ERR_UPDATE_DELAY: |
||||
puts("IODELAY: Delay mechanism update with new calibrated values failed\n"); |
||||
break; |
||||
case ERR_DEISOLATE_IO: |
||||
puts("IODELAY: De-isolation of Device IOs failed\n"); |
||||
break; |
||||
case ERR_CPDE: |
||||
puts("IODELAY: CPDE calculation failed\n"); |
||||
break; |
||||
case ERR_FPDE: |
||||
puts("IODELAY: FPDE calculation failed\n"); |
||||
break; |
||||
default: |
||||
debug("IODELAY: IO delay recalibration successfully completed\n"); |
||||
} |
||||
} |
@ -0,0 +1,129 @@ |
||||
/* |
||||
* Copyright 2015 Chen-Yu Tsai |
||||
* |
||||
* Chen-Yu Tsai <wens@csie.org> |
||||
* |
||||
* This file is dual-licensed: you can use it either under the terms |
||||
* of the GPL or the X11 license, at your option. Note that this dual |
||||
* licensing only applies to this file, and not this project as a |
||||
* whole. |
||||
* |
||||
* a) This file 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 file 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. |
||||
* |
||||
* Or, alternatively, |
||||
* |
||||
* b) Permission is hereby granted, free of charge, to any person |
||||
* obtaining a copy of this software and associated documentation |
||||
* files (the "Software"), to deal in the Software without |
||||
* restriction, including without limitation the rights to use, |
||||
* copy, modify, merge, publish, distribute, sublicense, and/or |
||||
* sell copies of the Software, and to permit persons to whom the |
||||
* Software is furnished to do so, subject to the following |
||||
* conditions: |
||||
* |
||||
* The above copyright notice and this permission notice shall be |
||||
* included in all copies or substantial portions of the Software. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
||||
* OTHER DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
/dts-v1/; |
||||
#include "sun8i-a33.dtsi" |
||||
#include "sunxi-common-regulators.dtsi" |
||||
|
||||
#include <dt-bindings/gpio/gpio.h> |
||||
#include <dt-bindings/input/input.h> |
||||
#include <dt-bindings/pinctrl/sun4i-a10.h> |
||||
|
||||
/ { |
||||
model = "Sinlinx SinA33"; |
||||
compatible = "sinlinx,sina33", "allwinner,sun8i-a33"; |
||||
|
||||
aliases { |
||||
serial0 = &uart0; |
||||
}; |
||||
|
||||
chosen { |
||||
stdout-path = "serial0:115200n8"; |
||||
}; |
||||
}; |
||||
|
||||
&lradc { |
||||
vref-supply = <®_vcc3v0>; |
||||
status = "okay"; |
||||
|
||||
button@200 { |
||||
label = "Volume Up"; |
||||
linux,code = <KEY_VOLUMEUP>; |
||||
channel = <0>; |
||||
voltage = <191011>; |
||||
}; |
||||
|
||||
button@400 { |
||||
label = "Volume Down"; |
||||
linux,code = <KEY_VOLUMEDOWN>; |
||||
channel = <0>; |
||||
voltage = <391304>; |
||||
}; |
||||
|
||||
button@600 { |
||||
label = "Home"; |
||||
linux,code = <KEY_HOME>; |
||||
channel = <0>; |
||||
voltage = <600000>; |
||||
}; |
||||
}; |
||||
|
||||
&mmc0 { |
||||
pinctrl-names = "default"; |
||||
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_sina33>; |
||||
vmmc-supply = <®_vcc3v0>; |
||||
bus-width = <4>; |
||||
cd-gpios = <&pio 1 4 GPIO_ACTIVE_HIGH>; /* PB4 */ |
||||
cd-inverted; |
||||
status = "okay"; |
||||
}; |
||||
|
||||
&mmc2 { |
||||
pinctrl-names = "default"; |
||||
pinctrl-0 = <&mmc2_8bit_pins>; |
||||
vmmc-supply = <®_vcc3v0>; |
||||
bus-width = <8>; |
||||
non-removable; |
||||
status = "okay"; |
||||
}; |
||||
|
||||
&mmc2_8bit_pins { |
||||
/* eMMC is missing pull-ups */ |
||||
allwinner,pull = <SUN4I_PINCTRL_PULL_UP>; |
||||
}; |
||||
|
||||
&pio { |
||||
mmc0_cd_pin_sina33: mmc0_cd_pin@0 { |
||||
allwinner,pins = "PB4"; |
||||
allwinner,function = "gpio_in"; |
||||
allwinner,drive = <SUN4I_PINCTRL_10_MA>; |
||||
allwinner,pull = <SUN4I_PINCTRL_PULL_UP>; |
||||
}; |
||||
}; |
||||
|
||||
&uart0 { |
||||
pinctrl-names = "default"; |
||||
pinctrl-0 = <&uart0_pins_b>; |
||||
status = "okay"; |
||||
}; |
@ -0,0 +1,83 @@ |
||||
/*
|
||||
* (C) Copyright 2015 |
||||
* Texas Instruments Incorporated |
||||
* |
||||
* Lokesh Vutla <lokeshvutla@ti.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#ifndef _DRA7_IODELAY_H_ |
||||
#define _DRA7_IODELAY_H_ |
||||
|
||||
#include <common.h> |
||||
#include <asm/arch/sys_proto.h> |
||||
|
||||
/* CONFIG_REG_0 */ |
||||
#define CFG_REG_0_OFFSET 0xC |
||||
#define CFG_REG_ROM_READ_SHIFT 1 |
||||
#define CFG_REG_ROM_READ_MASK (1 << 1) |
||||
#define CFG_REG_CALIB_STRT_SHIFT 0 |
||||
#define CFG_REG_CALIB_STRT_MASK (1 << 0) |
||||
#define CFG_REG_CALIB_STRT 1 |
||||
#define CFG_REG_CALIB_END 0 |
||||
#define CFG_REG_ROM_READ_START (1 << 1) |
||||
#define CFG_REG_ROM_READ_END (0 << 1) |
||||
|
||||
/* CONFIG_REG_2 */ |
||||
#define CFG_REG_2_OFFSET 0x14 |
||||
#define CFG_REG_REFCLK_PERIOD_SHIFT 0 |
||||
#define CFG_REG_REFCLK_PERIOD_MASK (0xFFFF << 0) |
||||
#define CFG_REG_REFCLK_PERIOD 0x2EF |
||||
|
||||
/* CONFIG_REG_8 */ |
||||
#define CFG_REG_8_OFFSET 0x2C |
||||
#define CFG_IODELAY_UNLOCK_KEY 0x0000AAAA |
||||
#define CFG_IODELAY_LOCK_KEY 0x0000AAAB |
||||
|
||||
/* CONFIG_REG_3/4 */ |
||||
#define CFG_REG_3_OFFSET 0x18 |
||||
#define CFG_REG_4_OFFSET 0x1C |
||||
#define CFG_REG_DLY_CNT_SHIFT 16 |
||||
#define CFG_REG_DLY_CNT_MASK (0xFFFF << 16) |
||||
#define CFG_REG_REF_CNT_SHIFT 0 |
||||
#define CFG_REG_REF_CNT_MASK (0xFFFF << 0) |
||||
|
||||
/* CTRL_CORE_SMA_SW_0 */ |
||||
#define CTRL_ISOLATE_SHIFT 2 |
||||
#define CTRL_ISOLATE_MASK (1 << 2) |
||||
#define ISOLATE_IO 1 |
||||
#define DEISOLATE_IO 0 |
||||
|
||||
/* PRM_IO_PMCTRL */ |
||||
#define PMCTRL_ISOCLK_OVERRIDE_SHIFT 0 |
||||
#define PMCTRL_ISOCLK_OVERRIDE_MASK (1 << 0) |
||||
#define PMCTRL_ISOCLK_STATUS_SHIFT 1 |
||||
#define PMCTRL_ISOCLK_STATUS_MASK (1 << 1) |
||||
#define PMCTRL_ISOCLK_OVERRIDE_CTRL 1 |
||||
#define PMCTRL_ISOCLK_NOT_OVERRIDE_CTRL 0 |
||||
|
||||
#define ERR_CALIBRATE_IODELAY 0x1 |
||||
#define ERR_DEISOLATE_IO 0x2 |
||||
#define ERR_ISOLATE_IO 0x4 |
||||
#define ERR_UPDATE_DELAY 0x8 |
||||
#define ERR_CPDE 0x3 |
||||
#define ERR_FPDE 0x5 |
||||
|
||||
/* CFG_XXX */ |
||||
#define CFG_X_SIGNATURE_SHIFT 12 |
||||
#define CFG_X_SIGNATURE_MASK (0x3F << 12) |
||||
#define CFG_X_LOCK_SHIFT 10 |
||||
#define CFG_X_LOCK_MASK (0x1 << 10) |
||||
#define CFG_X_COARSE_DLY_SHIFT 5 |
||||
#define CFG_X_COARSE_DLY_MASK (0x1F << 5) |
||||
#define CFG_X_FINE_DLY_SHIFT 0 |
||||
#define CFG_X_FINE_DLY_MASK (0x1F << 0) |
||||
#define CFG_X_SIGNATURE 0x29 |
||||
#define CFG_X_LOCK 1 |
||||
|
||||
void __recalibrate_iodelay(struct pad_conf_entry const *pad, int npads, |
||||
struct iodelay_cfg_entry const *iodelay, |
||||
int niodelays); |
||||
|
||||
#endif |
@ -1,67 +0,0 @@ |
||||
/*
|
||||
* (C) Copyright 2015 Roy Spliet <rspliet@ultimaker.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#ifndef _SUNXI_NAND_H |
||||
#define _SUNXI_NAND_H |
||||
|
||||
#include <linux/types.h> |
||||
|
||||
struct sunxi_nand |
||||
{ |
||||
u32 ctl; /* 0x000 Configure and control */ |
||||
u32 st; /* 0x004 Status information */ |
||||
u32 intr; /* 0x008 Interrupt control */ |
||||
u32 timing_ctl; /* 0x00C Timing control */ |
||||
u32 timing_cfg; /* 0x010 Timing configure */ |
||||
u32 addr_low; /* 0x014 Low word address */ |
||||
u32 addr_high; /* 0x018 High word address */ |
||||
u32 block_num; /* 0x01C Data block number */ |
||||
u32 data_cnt; /* 0x020 Data counter for transfer */ |
||||
u32 cmd; /* 0x024 NDFC commands */ |
||||
u32 rcmd_set; /* 0x028 Read command set for vendor NAND mem */ |
||||
u32 wcmd_set; /* 0x02C Write command set */ |
||||
u32 io_data; /* 0x030 IO data */ |
||||
u32 ecc_ctl; /* 0x034 ECC configure and control */ |
||||
u32 ecc_st; /* 0x038 ECC status and operation info */ |
||||
u32 efr; /* 0x03C Enhanced feature */ |
||||
u32 err_cnt0; /* 0x040 Corrected error bit counter 0 */ |
||||
u32 err_cnt1; /* 0x044 Corrected error bit counter 1 */ |
||||
u32 user_data[16]; /* 0x050[16] User data field */ |
||||
u32 efnand_st; /* 0x090 EFNAND status */ |
||||
u32 res0[3]; |
||||
u32 spare_area; /* 0x0A0 Spare area configure */ |
||||
u32 pat_id; /* 0x0A4 Pattern ID register */ |
||||
u32 rdata_sta_ctl; /* 0x0A8 Read data status control */ |
||||
u32 rdata_sta_0; /* 0x0AC Read data status 0 */ |
||||
u32 rdata_sta_1; /* 0x0B0 Read data status 1 */ |
||||
u32 res1[3]; |
||||
u32 mdma_addr; /* 0x0C0 MBUS DMA Address */ |
||||
u32 mdma_cnt; /* 0x0C4 MBUS DMA data counter */ |
||||
}; |
||||
|
||||
#define SUNXI_NAND_CTL_EN (1 << 0) |
||||
#define SUNXI_NAND_CTL_RST (1 << 1) |
||||
#define SUNXI_NAND_CTL_PAGE_SIZE(a) ((fls(a) - 11) << 8) |
||||
#define SUNXI_NAND_CTL_RAM_METHOD_DMA (1 << 14) |
||||
|
||||
#define SUNXI_NAND_ST_CMD_INT (1 << 1) |
||||
#define SUNXI_NAND_ST_DMA_INT (1 << 2) |
||||
#define SUNXI_NAND_ST_FIFO_FULL (1 << 3) |
||||
|
||||
#define SUNXI_NAND_CMD_ADDR_CYCLES(a) ((a - 1) << 16); |
||||
#define SUNXI_NAND_CMD_SEND_CMD1 (1 << 22) |
||||
#define SUNXI_NAND_CMD_WAIT_FLAG (1 << 23) |
||||
#define SUNXI_NAND_CMD_ORDER_INTERLEAVE 0 |
||||
#define SUNXI_NAND_CMD_ORDER_SEQ (1 << 25) |
||||
|
||||
#define SUNXI_NAND_ECC_CTL_ECC_EN (1 << 0) |
||||
#define SUNXI_NAND_ECC_CTL_PIPELINE (1 << 3) |
||||
#define SUNXI_NAND_ECC_CTL_BS_512B (1 << 5) |
||||
#define SUNXI_NAND_ECC_CTL_RND_EN (1 << 9) |
||||
#define SUNXI_NAND_ECC_CTL_MODE(a) ((a) << 12) |
||||
#define SUNXI_NAND_ECC_CTL_RND_SEED(a) ((a) << 16) |
||||
|
||||
#endif /* _SUNXI_NAND_H */ |
@ -0,0 +1,218 @@ |
||||
/*
|
||||
* Copyright 2012 Calxeda, Inc. |
||||
* |
||||
* 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 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, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <ahci.h> |
||||
#include <asm/io.h> |
||||
|
||||
#define CPHY_MAP(dev, addr) ((((dev) & 0x1f) << 7) | (((addr) >> 9) & 0x7f)) |
||||
#define CPHY_ADDR(base, dev, addr) ((base) | (((addr) & 0x1ff) << 2)) |
||||
#define CPHY_BASE 0xfff58000 |
||||
#define CPHY_WIDTH 0x1000 |
||||
#define CPHY_DTE_XS 5 |
||||
#define CPHY_MII 31 |
||||
#define SERDES_CR_CTL 0x80a0 |
||||
#define SERDES_CR_ADDR 0x80a1 |
||||
#define SERDES_CR_DATA 0x80a2 |
||||
#define CR_BUSY 0x0001 |
||||
#define CR_START 0x0001 |
||||
#define CR_WR_RDN 0x0002 |
||||
#define CPHY_TX_INPUT_STS 0x2001 |
||||
#define CPHY_RX_INPUT_STS 0x2002 |
||||
#define CPHY_SATA_TX_OVERRIDE_BIT 0x8000 |
||||
#define CPHY_SATA_RX_OVERRIDE_BIT 0x4000 |
||||
#define CPHY_TX_INPUT_OVERRIDE 0x2004 |
||||
#define CPHY_RX_INPUT_OVERRIDE 0x2005 |
||||
#define SPHY_LANE 0x100 |
||||
#define SPHY_HALF_RATE 0x0001 |
||||
#define CPHY_SATA_DPLL_MODE 0x0700 |
||||
#define CPHY_SATA_DPLL_SHIFT 8 |
||||
#define CPHY_SATA_TX_ATTEN 0x1c00 |
||||
#define CPHY_SATA_TX_ATTEN_SHIFT 10 |
||||
|
||||
#define HB_SREG_SATA_ATTEN 0xfff3cf24 |
||||
|
||||
#define SATA_PORT_BASE 0xffe08000 |
||||
#define SATA_VERSIONR 0xf8 |
||||
#define SATA_HB_VERSION 0x3332302a |
||||
|
||||
static u32 __combo_phy_reg_read(u8 phy, u8 dev, u32 addr) |
||||
{ |
||||
u32 data; |
||||
writel(CPHY_MAP(dev, addr), CPHY_BASE + 0x800 + CPHY_WIDTH * phy); |
||||
data = readl(CPHY_ADDR(CPHY_BASE + CPHY_WIDTH * phy, dev, addr)); |
||||
return data; |
||||
} |
||||
|
||||
static void __combo_phy_reg_write(u8 phy, u8 dev, u32 addr, u32 data) |
||||
{ |
||||
writel(CPHY_MAP(dev, addr), CPHY_BASE + 0x800 + CPHY_WIDTH * phy); |
||||
writel(data, CPHY_ADDR(CPHY_BASE + CPHY_WIDTH * phy, dev, addr)); |
||||
} |
||||
|
||||
static u32 combo_phy_read(u8 phy, u32 addr) |
||||
{ |
||||
u8 dev = CPHY_DTE_XS; |
||||
if (phy == 5) |
||||
dev = CPHY_MII; |
||||
while (__combo_phy_reg_read(phy, dev, SERDES_CR_CTL) & CR_BUSY) |
||||
udelay(5); |
||||
__combo_phy_reg_write(phy, dev, SERDES_CR_ADDR, addr); |
||||
__combo_phy_reg_write(phy, dev, SERDES_CR_CTL, CR_START); |
||||
while (__combo_phy_reg_read(phy, dev, SERDES_CR_CTL) & CR_BUSY) |
||||
udelay(5); |
||||
return __combo_phy_reg_read(phy, dev, SERDES_CR_DATA); |
||||
} |
||||
|
||||
static void combo_phy_write(u8 phy, u32 addr, u32 data) |
||||
{ |
||||
u8 dev = CPHY_DTE_XS; |
||||
if (phy == 5) |
||||
dev = CPHY_MII; |
||||
while (__combo_phy_reg_read(phy, dev, SERDES_CR_CTL) & CR_BUSY) |
||||
udelay(5); |
||||
__combo_phy_reg_write(phy, dev, SERDES_CR_ADDR, addr); |
||||
__combo_phy_reg_write(phy, dev, SERDES_CR_DATA, data); |
||||
__combo_phy_reg_write(phy, dev, SERDES_CR_CTL, CR_WR_RDN | CR_START); |
||||
} |
||||
|
||||
static void cphy_spread_spectrum_override(u8 phy, u8 lane, u32 val) |
||||
{ |
||||
u32 tmp; |
||||
tmp = combo_phy_read(phy, CPHY_RX_INPUT_STS + lane * SPHY_LANE); |
||||
tmp &= ~CPHY_SATA_RX_OVERRIDE_BIT; |
||||
combo_phy_write(phy, CPHY_RX_INPUT_OVERRIDE + lane * SPHY_LANE, tmp); |
||||
|
||||
tmp |= CPHY_SATA_RX_OVERRIDE_BIT; |
||||
combo_phy_write(phy, CPHY_RX_INPUT_OVERRIDE + lane * SPHY_LANE, tmp); |
||||
|
||||
tmp &= ~CPHY_SATA_DPLL_MODE; |
||||
tmp |= (val << CPHY_SATA_DPLL_SHIFT) & CPHY_SATA_DPLL_MODE; |
||||
combo_phy_write(phy, CPHY_RX_INPUT_OVERRIDE + lane * SPHY_LANE, tmp); |
||||
} |
||||
|
||||
static void cphy_tx_attenuation_override(u8 phy, u8 lane) |
||||
{ |
||||
u32 val; |
||||
u32 tmp; |
||||
u8 shift; |
||||
|
||||
shift = ((phy == 5) ? 4 : lane) * 4; |
||||
|
||||
val = (readl(HB_SREG_SATA_ATTEN) >> shift) & 0xf; |
||||
|
||||
if (val & 0x8) |
||||
return; |
||||
|
||||
tmp = combo_phy_read(phy, CPHY_TX_INPUT_STS + lane * SPHY_LANE); |
||||
tmp &= ~CPHY_SATA_TX_OVERRIDE_BIT; |
||||
combo_phy_write(phy, CPHY_TX_INPUT_OVERRIDE + lane * SPHY_LANE, tmp); |
||||
|
||||
tmp |= CPHY_SATA_TX_OVERRIDE_BIT; |
||||
combo_phy_write(phy, CPHY_TX_INPUT_OVERRIDE + lane * SPHY_LANE, tmp); |
||||
|
||||
tmp |= (val << CPHY_SATA_TX_ATTEN_SHIFT) & CPHY_SATA_TX_ATTEN; |
||||
combo_phy_write(phy, CPHY_TX_INPUT_OVERRIDE + lane * SPHY_LANE, tmp); |
||||
} |
||||
|
||||
static void cphy_disable_port_overrides(u8 port) |
||||
{ |
||||
u32 tmp; |
||||
u8 lane = 0, phy = 0; |
||||
|
||||
if (port == 0) |
||||
phy = 5; |
||||
else if (port < 5) |
||||
lane = port - 1; |
||||
else |
||||
return; |
||||
tmp = combo_phy_read(phy, CPHY_RX_INPUT_STS + lane * SPHY_LANE); |
||||
tmp &= ~CPHY_SATA_RX_OVERRIDE_BIT; |
||||
combo_phy_write(phy, CPHY_RX_INPUT_OVERRIDE + lane * SPHY_LANE, tmp); |
||||
|
||||
tmp = combo_phy_read(phy, CPHY_TX_INPUT_OVERRIDE + lane * SPHY_LANE); |
||||
tmp &= ~CPHY_SATA_TX_OVERRIDE_BIT; |
||||
combo_phy_write(phy, CPHY_TX_INPUT_OVERRIDE + lane * SPHY_LANE, tmp); |
||||
} |
||||
|
||||
void cphy_disable_overrides(void) |
||||
{ |
||||
int i; |
||||
u32 port_map; |
||||
|
||||
port_map = readl(0xffe08000 + HOST_PORTS_IMPL); |
||||
for (i = 0; i < 5; i++) { |
||||
if (port_map & (1 << i)) |
||||
cphy_disable_port_overrides(i); |
||||
} |
||||
} |
||||
|
||||
static void cphy_override_lane(u8 port) |
||||
{ |
||||
u32 tmp, k = 0; |
||||
u8 lane = 0, phy = 0; |
||||
|
||||
if (port == 0) |
||||
phy = 5; |
||||
else if (port < 5) |
||||
lane = port - 1; |
||||
else |
||||
return; |
||||
|
||||
do { |
||||
tmp = combo_phy_read(0, CPHY_RX_INPUT_STS + |
||||
lane * SPHY_LANE); |
||||
} while ((tmp & SPHY_HALF_RATE) && (k++ < 1000)); |
||||
cphy_spread_spectrum_override(phy, lane, 3); |
||||
cphy_tx_attenuation_override(phy, lane); |
||||
} |
||||
|
||||
#define WAIT_MS_LINKUP 4 |
||||
|
||||
int ahci_link_up(struct ahci_probe_ent *probe_ent, int port) |
||||
{ |
||||
u32 tmp; |
||||
int j = 0; |
||||
u8 *port_mmio = (u8 *)probe_ent->port[port].port_mmio; |
||||
u32 is_highbank = readl(SATA_PORT_BASE + SATA_VERSIONR) == |
||||
SATA_HB_VERSION ? 1 : 0; |
||||
|
||||
/* Bring up SATA link.
|
||||
* SATA link bringup time is usually less than 1 ms; only very |
||||
* rarely has it taken between 1-2 ms. Never seen it above 2 ms. |
||||
*/ |
||||
while (j < WAIT_MS_LINKUP) { |
||||
if (is_highbank && (j == 0)) { |
||||
cphy_disable_port_overrides(port); |
||||
writel(0x301, port_mmio + PORT_SCR_CTL); |
||||
udelay(1000); |
||||
writel(0x300, port_mmio + PORT_SCR_CTL); |
||||
udelay(1000); |
||||
cphy_override_lane(port); |
||||
} |
||||
|
||||
tmp = readl(port_mmio + PORT_SCR_STAT); |
||||
if ((tmp & 0xf) == 0x3) |
||||
return 0; |
||||
udelay(1000); |
||||
j++; |
||||
|
||||
if ((j == WAIT_MS_LINKUP) && (tmp & 0xf)) |
||||
j = 0; /* retry phy reset */ |
||||
} |
||||
return 1; |
||||
} |
@ -0,0 +1,6 @@ |
||||
CAIRO BOARD |
||||
M: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr> |
||||
S: Maintained |
||||
F: board/quipos/cairo/ |
||||
F: include/configs/omap3_cairo.h |
||||
F: configs/cairo_defconfig |
@ -0,0 +1,92 @@ |
||||
# This is an example file to generate boot.scr - a boot script for U-Boot |
||||
# Generate boot.scr: |
||||
# ./tools/mkimage -c none -A arm -T script -d autoboot.cmd boot.scr |
||||
# |
||||
# It requires a list of environment variables to be defined before load: |
||||
# platform dependent: boardname, fdtfile, console |
||||
# system dependent: mmcbootdev, mmcbootpart, mmcrootdev, mmcrootpart, rootfstype |
||||
# |
||||
setenv fdtaddr "40800000" |
||||
setenv initrdname "uInitrd" |
||||
setenv initrdaddr "42000000" |
||||
setenv loaddtb "load mmc ${mmcbootdev}:${mmcbootpart} ${fdtaddr} ${fdtfile}" |
||||
setenv loadinitrd "load mmc ${mmcbootdev}:${mmcbootpart} ${initrdaddr} ${initrdname}" |
||||
setenv loadkernel "load mmc ${mmcbootdev}:${mmcbootpart} '${kerneladdr}' '${kernelname}'" |
||||
setenv kernel_args "setenv bootargs ${console} root=/dev/mmcblk${mmcrootdev}p${mmcrootpart} rootfstype=${rootfstype} rootwait ${opts}" |
||||
|
||||
#### Routine: check_dtb - check that target.dtb exists on boot partition |
||||
setenv check_dtb " |
||||
if test -e mmc '${mmcbootdev}':'${mmcbootpart}' '${fdtfile}'; then |
||||
run loaddtb; |
||||
setenv fdt_addr ${fdtaddr}; |
||||
else |
||||
echo Warning! Booting without DTB: '${fdtfile}'!; |
||||
setenv fdt_addr; |
||||
fi;" |
||||
|
||||
#### Routine: check_ramdisk - check that uInitrd exists on boot partition |
||||
setenv check_ramdisk " |
||||
if test -e mmc '${mmcbootdev}':'${mmcbootpart}' '${initrdname}'; then |
||||
echo "Found ramdisk image."; |
||||
run loadinitrd; |
||||
setenv initrd_addr ${initrdaddr}; |
||||
else |
||||
echo Warning! Booting without RAMDISK: '${initrdname}'!; |
||||
setenv initrd_addr -; |
||||
fi;" |
||||
|
||||
#### Routine: boot_fit - check that env $boardname is set and boot proper config of ITB image |
||||
setenv setboot_fit " |
||||
if test -e '${boardname}'; then |
||||
setenv fdt_addr ; |
||||
setenv initrd_addr ; |
||||
setenv kerneladdr 0x42000000; |
||||
setenv kernelname Image.itb; |
||||
setenv itbcfg "\"#${boardname}\""; |
||||
setenv imgbootcmd bootm; |
||||
else |
||||
echo Warning! Variable: \$boardname is undefined!; |
||||
fi" |
||||
|
||||
#### Routine: setboot_uimg - prepare env to boot uImage |
||||
setenv setboot_uimg " |
||||
setenv kerneladdr 0x40007FC0; |
||||
setenv kernelname uImage; |
||||
setenv itbcfg ; |
||||
setenv imgbootcmd bootm; |
||||
run check_dtb; |
||||
run check_ramdisk;" |
||||
|
||||
#### Routine: setboot_zimg - prepare env to boot zImage |
||||
setenv setboot_zimg " |
||||
setenv kerneladdr 0x40007FC0; |
||||
setenv kernelname zImage; |
||||
setenv itbcfg ; |
||||
setenv imgbootcmd bootz; |
||||
run check_dtb; |
||||
run check_ramdisk;" |
||||
|
||||
#### Routine: boot_img - boot the kernel after env setup |
||||
setenv boot_img " |
||||
run loadkernel; |
||||
run kernel_args; |
||||
'${imgbootcmd}' '${kerneladdr}${itbcfg}' '${initrd_addr}' '${fdt_addr}';" |
||||
|
||||
#### Routine: autoboot - choose proper boot path |
||||
setenv autoboot " |
||||
if test -e mmc 0:${mmcbootpart} Image.itb; then |
||||
echo Found kernel image: Image.itb; |
||||
run setboot_fit; |
||||
run boot_img; |
||||
elif test -e mmc 0:${mmcbootpart} zImage; then |
||||
echo Found kernel image: zImage; |
||||
run setboot_zimg; |
||||
run boot_img; |
||||
elif test -e mmc 0:${mmcbootpart} uImage; then |
||||
echo Found kernel image: uImage; |
||||
run setboot_uimg; |
||||
run boot_img; |
||||
fi;" |
||||
|
||||
#### Execute the defined autoboot macro |
||||
run autoboot |
@ -0,0 +1,10 @@ |
||||
setenv kernelname zImage; |
||||
setenv boot_kernel "setenv bootargs \"${console} root=/dev/mmcblk${mmcrootdev}p${mmcrootpart} rootfstype=${rootfstype} rootwait ${opts}\"; |
||||
load mmc ${mmcbootdev}:${mmcbootpart} 0x40007FC0 '${kernelname}'; |
||||
if load mmc ${mmcbootdev}:${mmcbootpart} 40800000 ${fdtfile}; then |
||||
bootz 0x40007FC0 - 40800000; |
||||
else |
||||
echo Warning! Booting without DTB: '${fdtfile}'!; |
||||
bootz 0x40007FC0 -; |
||||
fi;" |
||||
run boot_kernel; |
@ -0,0 +1,24 @@ |
||||
if TARGET_AM335X_BALTOS |
||||
|
||||
config SYS_BOARD |
||||
default "baltos" |
||||
|
||||
config SYS_VENDOR |
||||
default "vscom" |
||||
|
||||
config SYS_SOC |
||||
default "am33xx" |
||||
|
||||
config SYS_CONFIG_NAME |
||||
default "baltos" |
||||
|
||||
config CONS_INDEX |
||||
int "UART used for console" |
||||
range 1 6 |
||||
default 1 |
||||
help |
||||
The AM335x SoC has a total of 6 UARTs (UART0 to UART5 as referenced |
||||
in documentation, etc) available to it. Depending on your specific |
||||
board you may want something other than UART0. |
||||
|
||||
endif |
@ -0,0 +1,6 @@ |
||||
BALTOS BOARD |
||||
M: Yegor Yefremov <yegorslists@googlemail.com> |
||||
S: Maintained |
||||
F: board/vscom/baltos/ |
||||
F: include/configs/baltos.h |
||||
F: configs/am335x_baltos_defconfig |
@ -0,0 +1,13 @@ |
||||
#
|
||||
# Makefile
|
||||
#
|
||||
# Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
ifeq ($(CONFIG_SKIP_LOWLEVEL_INIT),) |
||||
obj-y := mux.o
|
||||
endif |
||||
|
||||
obj-y += board.o
|
@ -0,0 +1 @@ |
||||
BSP for VScom OnRISC Balios family devices, like Balios iR 5221. |
@ -0,0 +1,474 @@ |
||||
/*
|
||||
* board.c |
||||
* |
||||
* Board functions for TI AM335X based boards |
||||
* |
||||
* Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
|
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <errno.h> |
||||
#include <spl.h> |
||||
#include <asm/arch/cpu.h> |
||||
#include <asm/arch/hardware.h> |
||||
#include <asm/arch/omap.h> |
||||
#include <asm/arch/ddr_defs.h> |
||||
#include <asm/arch/clock.h> |
||||
#include <asm/arch/gpio.h> |
||||
#include <asm/arch/mmc_host_def.h> |
||||
#include <asm/arch/sys_proto.h> |
||||
#include <asm/arch/mem.h> |
||||
#include <asm/arch/mux.h> |
||||
#include <asm/io.h> |
||||
#include <asm/emif.h> |
||||
#include <asm/gpio.h> |
||||
#include <i2c.h> |
||||
#include <miiphy.h> |
||||
#include <cpsw.h> |
||||
#include <power/tps65217.h> |
||||
#include <power/tps65910.h> |
||||
#include <environment.h> |
||||
#include <watchdog.h> |
||||
#include "board.h" |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
/* GPIO that controls power to DDR on EVM-SK */ |
||||
#define GPIO_DDR_VTT_EN 7 |
||||
#define DIP_S1 44 |
||||
|
||||
static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE; |
||||
|
||||
static int baltos_set_console(void) |
||||
{ |
||||
int val, i, dips = 0; |
||||
char buf[7]; |
||||
|
||||
for (i = 0; i < 4; i++) { |
||||
sprintf(buf, "dip_s%d", i + 1); |
||||
|
||||
if (gpio_request(DIP_S1 + i, buf)) { |
||||
printf("failed to export GPIO %d\n", DIP_S1 + i); |
||||
return 0; |
||||
} |
||||
|
||||
if (gpio_direction_input(DIP_S1 + i)) { |
||||
printf("failed to set GPIO %d direction\n", DIP_S1 + i); |
||||
return 0; |
||||
} |
||||
|
||||
val = gpio_get_value(DIP_S1 + i); |
||||
dips |= val << i; |
||||
} |
||||
|
||||
printf("DIPs: 0x%1x\n", (~dips) & 0xf); |
||||
|
||||
if ((dips & 0xf) == 0xe) |
||||
setenv("console", "ttyUSB0,115200n8"); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int read_eeprom(BSP_VS_HWPARAM *header) |
||||
{ |
||||
i2c_set_bus_num(1); |
||||
|
||||
/* Check if baseboard eeprom is available */ |
||||
if (i2c_probe(CONFIG_SYS_I2C_EEPROM_ADDR)) { |
||||
puts("Could not probe the EEPROM; something fundamentally " |
||||
"wrong on the I2C bus.\n"); |
||||
return -ENODEV; |
||||
} |
||||
|
||||
/* read the eeprom using i2c */ |
||||
if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 1, (uchar *)header, |
||||
sizeof(BSP_VS_HWPARAM))) { |
||||
puts("Could not read the EEPROM; something fundamentally" |
||||
" wrong on the I2C bus.\n"); |
||||
return -EIO; |
||||
} |
||||
|
||||
if (header->Magic != 0xDEADBEEF) { |
||||
|
||||
printf("Incorrect magic number (0x%x) in EEPROM\n", |
||||
header->Magic); |
||||
|
||||
/* fill default values */ |
||||
header->SystemId = 211; |
||||
header->MAC1[0] = 0x00; |
||||
header->MAC1[1] = 0x00; |
||||
header->MAC1[2] = 0x00; |
||||
header->MAC1[3] = 0x00; |
||||
header->MAC1[4] = 0x00; |
||||
header->MAC1[5] = 0x01; |
||||
|
||||
header->MAC2[0] = 0x00; |
||||
header->MAC2[1] = 0x00; |
||||
header->MAC2[2] = 0x00; |
||||
header->MAC2[3] = 0x00; |
||||
header->MAC2[4] = 0x00; |
||||
header->MAC2[5] = 0x02; |
||||
|
||||
header->MAC3[0] = 0x00; |
||||
header->MAC3[1] = 0x00; |
||||
header->MAC3[2] = 0x00; |
||||
header->MAC3[3] = 0x00; |
||||
header->MAC3[4] = 0x00; |
||||
header->MAC3[5] = 0x03; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
#if defined(CONFIG_SPL_BUILD) || defined(CONFIG_NOR_BOOT) |
||||
|
||||
static const struct ddr_data ddr3_baltos_data = { |
||||
.datardsratio0 = MT41K256M16HA125E_RD_DQS, |
||||
.datawdsratio0 = MT41K256M16HA125E_WR_DQS, |
||||
.datafwsratio0 = MT41K256M16HA125E_PHY_FIFO_WE, |
||||
.datawrsratio0 = MT41K256M16HA125E_PHY_WR_DATA, |
||||
}; |
||||
|
||||
static const struct cmd_control ddr3_baltos_cmd_ctrl_data = { |
||||
.cmd0csratio = MT41K256M16HA125E_RATIO, |
||||
.cmd0iclkout = MT41K256M16HA125E_INVERT_CLKOUT, |
||||
|
||||
.cmd1csratio = MT41K256M16HA125E_RATIO, |
||||
.cmd1iclkout = MT41K256M16HA125E_INVERT_CLKOUT, |
||||
|
||||
.cmd2csratio = MT41K256M16HA125E_RATIO, |
||||
.cmd2iclkout = MT41K256M16HA125E_INVERT_CLKOUT, |
||||
}; |
||||
|
||||
static struct emif_regs ddr3_baltos_emif_reg_data = { |
||||
.sdram_config = MT41K256M16HA125E_EMIF_SDCFG, |
||||
.ref_ctrl = MT41K256M16HA125E_EMIF_SDREF, |
||||
.sdram_tim1 = MT41K256M16HA125E_EMIF_TIM1, |
||||
.sdram_tim2 = MT41K256M16HA125E_EMIF_TIM2, |
||||
.sdram_tim3 = MT41K256M16HA125E_EMIF_TIM3, |
||||
.zq_config = MT41K256M16HA125E_ZQ_CFG, |
||||
.emif_ddr_phy_ctlr_1 = MT41K256M16HA125E_EMIF_READ_LATENCY, |
||||
}; |
||||
|
||||
#ifdef CONFIG_SPL_OS_BOOT |
||||
int spl_start_uboot(void) |
||||
{ |
||||
/* break into full u-boot on 'c' */ |
||||
return (serial_tstc() && serial_getc() == 'c'); |
||||
} |
||||
#endif |
||||
|
||||
#define OSC (V_OSCK/1000000) |
||||
const struct dpll_params dpll_ddr = { |
||||
266, OSC-1, 1, -1, -1, -1, -1}; |
||||
const struct dpll_params dpll_ddr_evm_sk = { |
||||
303, OSC-1, 1, -1, -1, -1, -1}; |
||||
const struct dpll_params dpll_ddr_baltos = { |
||||
400, OSC-1, 1, -1, -1, -1, -1}; |
||||
|
||||
void am33xx_spl_board_init(void) |
||||
{ |
||||
int mpu_vdd; |
||||
int sil_rev; |
||||
|
||||
/* Get the frequency */ |
||||
dpll_mpu_opp100.m = am335x_get_efuse_mpu_max_freq(cdev); |
||||
|
||||
/*
|
||||
* The GP EVM, IDK and EVM SK use a TPS65910 PMIC. For all |
||||
* MPU frequencies we support we use a CORE voltage of |
||||
* 1.1375V. For MPU voltage we need to switch based on |
||||
* the frequency we are running at. |
||||
*/ |
||||
i2c_set_bus_num(1); |
||||
|
||||
if (i2c_probe(TPS65910_CTRL_I2C_ADDR)) { |
||||
puts("i2c: cannot access TPS65910\n"); |
||||
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, |
||||
dpll_mpu_opp100.m); |
||||
|
||||
/* 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_3)) |
||||
return; |
||||
|
||||
/* Set CORE Frequencies to OPP100 */ |
||||
do_setup_dpll(&dpll_core_regs, &dpll_core_opp100); |
||||
|
||||
/* Set MPU Frequency to what we detected now that voltages are set */ |
||||
do_setup_dpll(&dpll_mpu_regs, &dpll_mpu_opp100); |
||||
|
||||
writel(0x000010ff, PRM_DEVICE_INST + 4); |
||||
} |
||||
|
||||
const struct dpll_params *get_dpll_ddr_params(void) |
||||
{ |
||||
enable_i2c1_pin_mux(); |
||||
i2c_set_bus_num(1); |
||||
|
||||
return &dpll_ddr_baltos; |
||||
} |
||||
|
||||
void set_uart_mux_conf(void) |
||||
{ |
||||
enable_uart0_pin_mux(); |
||||
} |
||||
|
||||
void set_mux_conf_regs(void) |
||||
{ |
||||
enable_board_pin_mux(); |
||||
} |
||||
|
||||
const struct ctrl_ioregs ioregs_baltos = { |
||||
.cm0ioctl = MT41K256M16HA125E_IOCTRL_VALUE, |
||||
.cm1ioctl = MT41K256M16HA125E_IOCTRL_VALUE, |
||||
.cm2ioctl = MT41K256M16HA125E_IOCTRL_VALUE, |
||||
.dt0ioctl = MT41K256M16HA125E_IOCTRL_VALUE, |
||||
.dt1ioctl = MT41K256M16HA125E_IOCTRL_VALUE, |
||||
}; |
||||
|
||||
void sdram_init(void) |
||||
{ |
||||
gpio_request(GPIO_DDR_VTT_EN, "ddr_vtt_en"); |
||||
gpio_direction_output(GPIO_DDR_VTT_EN, 1); |
||||
|
||||
config_ddr(400, &ioregs_baltos, |
||||
&ddr3_baltos_data, |
||||
&ddr3_baltos_cmd_ctrl_data, |
||||
&ddr3_baltos_emif_reg_data, 0); |
||||
} |
||||
#endif |
||||
|
||||
/*
|
||||
* Basic board specific setup. Pinmux has been handled already. |
||||
*/ |
||||
int board_init(void) |
||||
{ |
||||
#if defined(CONFIG_HW_WATCHDOG) |
||||
hw_watchdog_init(); |
||||
#endif |
||||
|
||||
gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; |
||||
#if defined(CONFIG_NOR) || defined(CONFIG_NAND) |
||||
gpmc_init(); |
||||
#endif |
||||
return 0; |
||||
} |
||||
|
||||
int ft_board_setup(void *blob, bd_t *bd) |
||||
{ |
||||
int node, ret; |
||||
unsigned char mac_addr[6]; |
||||
BSP_VS_HWPARAM header; |
||||
|
||||
/* get production data */ |
||||
if (read_eeprom(&header)) |
||||
return 0; |
||||
|
||||
/* setup MAC1 */ |
||||
mac_addr[0] = header.MAC1[0]; |
||||
mac_addr[1] = header.MAC1[1]; |
||||
mac_addr[2] = header.MAC1[2]; |
||||
mac_addr[3] = header.MAC1[3]; |
||||
mac_addr[4] = header.MAC1[4]; |
||||
mac_addr[5] = header.MAC1[5]; |
||||
|
||||
|
||||
node = fdt_path_offset(blob, "/ocp/ethernet/slave@4a100200"); |
||||
if (node < 0) { |
||||
printf("no /soc/fman/ethernet path offset\n"); |
||||
return -ENODEV; |
||||
} |
||||
|
||||
ret = fdt_setprop(blob, node, "mac-address", &mac_addr, 6); |
||||
if (ret) { |
||||
printf("error setting local-mac-address property\n"); |
||||
return -ENODEV; |
||||
} |
||||
|
||||
/* setup MAC2 */ |
||||
mac_addr[0] = header.MAC2[0]; |
||||
mac_addr[1] = header.MAC2[1]; |
||||
mac_addr[2] = header.MAC2[2]; |
||||
mac_addr[3] = header.MAC2[3]; |
||||
mac_addr[4] = header.MAC2[4]; |
||||
mac_addr[5] = header.MAC2[5]; |
||||
|
||||
node = fdt_path_offset(blob, "/ocp/ethernet/slave@4a100300"); |
||||
if (node < 0) { |
||||
printf("no /soc/fman/ethernet path offset\n"); |
||||
return -ENODEV; |
||||
} |
||||
|
||||
ret = fdt_setprop(blob, node, "mac-address", &mac_addr, 6); |
||||
if (ret) { |
||||
printf("error setting local-mac-address property\n"); |
||||
return -ENODEV; |
||||
} |
||||
|
||||
printf("\nFDT was successfully setup\n"); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static struct module_pin_mux dip_pin_mux[] = { |
||||
{OFFSET(gpmc_ad12), (MODE(7) | RXACTIVE )}, /* GPIO1_12 */ |
||||
{OFFSET(gpmc_ad13), (MODE(7) | RXACTIVE )}, /* GPIO1_13 */ |
||||
{OFFSET(gpmc_ad14), (MODE(7) | RXACTIVE )}, /* GPIO1_14 */ |
||||
{OFFSET(gpmc_ad15), (MODE(7) | RXACTIVE )}, /* GPIO1_15 */ |
||||
{-1}, |
||||
}; |
||||
|
||||
#ifdef CONFIG_BOARD_LATE_INIT |
||||
int board_late_init(void) |
||||
{ |
||||
#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG |
||||
BSP_VS_HWPARAM header; |
||||
char model[4]; |
||||
|
||||
/* get production data */ |
||||
if (read_eeprom(&header)) { |
||||
sprintf(model, "211"); |
||||
} else { |
||||
sprintf(model, "%d", header.SystemId); |
||||
if (header.SystemId == 215) { |
||||
configure_module_pin_mux(dip_pin_mux); |
||||
baltos_set_console(); |
||||
} |
||||
} |
||||
setenv("board_name", model); |
||||
#endif |
||||
|
||||
return 0; |
||||
} |
||||
#endif |
||||
|
||||
#if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \ |
||||
(defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD)) |
||||
static void cpsw_control(int enabled) |
||||
{ |
||||
/* VTP can be added here */ |
||||
|
||||
return; |
||||
} |
||||
|
||||
static struct cpsw_slave_data cpsw_slaves[] = { |
||||
{ |
||||
.slave_reg_ofs = 0x208, |
||||
.sliver_reg_ofs = 0xd80, |
||||
.phy_addr = 0, |
||||
}, |
||||
{ |
||||
.slave_reg_ofs = 0x308, |
||||
.sliver_reg_ofs = 0xdc0, |
||||
.phy_addr = 7, |
||||
}, |
||||
}; |
||||
|
||||
static struct cpsw_platform_data cpsw_data = { |
||||
.mdio_base = CPSW_MDIO_BASE, |
||||
.cpsw_base = CPSW_BASE, |
||||
.mdio_div = 0xff, |
||||
.channels = 8, |
||||
.cpdma_reg_ofs = 0x800, |
||||
.slaves = 2, |
||||
.slave_data = cpsw_slaves, |
||||
.active_slave = 1, |
||||
.ale_reg_ofs = 0xd00, |
||||
.ale_entries = 1024, |
||||
.host_port_reg_ofs = 0x108, |
||||
.hw_stats_reg_ofs = 0x900, |
||||
.bd_ram_ofs = 0x2000, |
||||
.mac_control = (1 << 5), |
||||
.control = cpsw_control, |
||||
.host_port_num = 0, |
||||
.version = CPSW_CTRL_VERSION_2, |
||||
}; |
||||
#endif |
||||
|
||||
#if ((defined(CONFIG_SPL_ETH_SUPPORT) || defined(CONFIG_SPL_USBETH_SUPPORT)) \ |
||||
&& defined(CONFIG_SPL_BUILD)) || \
|
||||
((defined(CONFIG_DRIVER_TI_CPSW) || \
|
||||
defined(CONFIG_USB_ETHER) && defined(CONFIG_MUSB_GADGET)) && \
|
||||
!defined(CONFIG_SPL_BUILD)) |
||||
int board_eth_init(bd_t *bis) |
||||
{ |
||||
int rv, n = 0; |
||||
uint8_t mac_addr[6]; |
||||
uint32_t mac_hi, mac_lo; |
||||
__maybe_unused struct am335x_baseboard_id header; |
||||
|
||||
/*
|
||||
* Note here that we're using CPSW1 since that has a 1Gbit PHY while |
||||
* CSPW0 has a 100Mbit PHY. |
||||
* |
||||
* On product, CPSW1 maps to port labeled WAN. |
||||
*/ |
||||
|
||||
/* try reading mac address from efuse */ |
||||
mac_lo = readl(&cdev->macid1l); |
||||
mac_hi = readl(&cdev->macid1h); |
||||
mac_addr[0] = mac_hi & 0xFF; |
||||
mac_addr[1] = (mac_hi & 0xFF00) >> 8; |
||||
mac_addr[2] = (mac_hi & 0xFF0000) >> 16; |
||||
mac_addr[3] = (mac_hi & 0xFF000000) >> 24; |
||||
mac_addr[4] = mac_lo & 0xFF; |
||||
mac_addr[5] = (mac_lo & 0xFF00) >> 8; |
||||
|
||||
#if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \ |
||||
(defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD)) |
||||
if (!getenv("ethaddr")) { |
||||
printf("<ethaddr> not set. Validating first E-fuse MAC\n"); |
||||
|
||||
if (is_valid_ethaddr(mac_addr)) |
||||
eth_setenv_enetaddr("ethaddr", mac_addr); |
||||
} |
||||
|
||||
#ifdef CONFIG_DRIVER_TI_CPSW |
||||
writel((GMII1_SEL_RMII | GMII2_SEL_RGMII | RGMII2_IDMODE), &cdev->miisel); |
||||
cpsw_slaves[1].phy_if = PHY_INTERFACE_MODE_RGMII; |
||||
rv = cpsw_register(&cpsw_data); |
||||
if (rv < 0) |
||||
printf("Error %d registering CPSW switch\n", rv); |
||||
else |
||||
n += rv; |
||||
#endif |
||||
|
||||
/*
|
||||
* |
||||
* CPSW RGMII Internal Delay Mode is not supported in all PVT |
||||
* operating points. So we must set the TX clock delay feature |
||||
* in the AR8051 PHY. Since we only support a single ethernet |
||||
* device in U-Boot, we only do this for the first instance. |
||||
*/ |
||||
#define AR8051_PHY_DEBUG_ADDR_REG 0x1d |
||||
#define AR8051_PHY_DEBUG_DATA_REG 0x1e |
||||
#define AR8051_DEBUG_RGMII_CLK_DLY_REG 0x5 |
||||
#define AR8051_RGMII_TX_CLK_DLY 0x100 |
||||
const char *devname; |
||||
devname = miiphy_get_current_dev(); |
||||
|
||||
miiphy_write(devname, 0x7, AR8051_PHY_DEBUG_ADDR_REG, |
||||
AR8051_DEBUG_RGMII_CLK_DLY_REG); |
||||
miiphy_write(devname, 0x7, AR8051_PHY_DEBUG_DATA_REG, |
||||
AR8051_RGMII_TX_CLK_DLY); |
||||
#endif |
||||
return n; |
||||
} |
||||
#endif |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue