您的位置:首页 > 其它

u-boot-2016.11移植u-boot.bin

2016-12-03 17:33 561 查看
https://github.com/SourceLink/S5PV210

1、修改堆栈指针

vim include/configs/smdkv210.h
#define CONFIG_SYS_LOAD_ADDR            CONFIG_SYS_SDRAM_BASE + 0x40000000              /* modied by Sourcelink */
#define CONFIG_SYS_INIT_SP_ADDR         CONFIG_SYS_LOAD_ADDR            		/* modied by Sourcelink */
#define CONFIG_SYS_SDRAM_BASE           0x20000000     					/* modied by Sourcelink */


2、添加串口
a)添加串口初始化引脚代码

vim board/samsung/smdkv210/lowlevel_init.S

ldr     r0, =0xE0200000
ldr     r1, =0X22222222
str     r1, [r0]


b)添加串口初始化配置代码

vim drivers/serial/serial_s5p.c

/*
* (C) Copyright 2009 SAMSUNG Electronics
* Minkyu Kang <mk7.kang@samsung.com>
* Heungjun Kim <riverful.kim@samsung.com>
*
* based on drivers/serial/s3c64xx.c
*
* SPDX-License-Identifier:	GPL-2.0+
*/

#include <common.h>
#include <fdtdec.h>
#include <linux/compiler.h>
#include <asm/io.h>
#include <asm/arch/uart.h>
#include <asm/arch/clk.h>
#include <serial.h>

DECLARE_GLOBAL_DATA_PTR;

#define RX_FIFO_COUNT_MASK	0xff
#define RX_FIFO_FULL_MASK	(1 << 8)
#define TX_FIFO_FULL_MASK	(1 << 24)

/* Information about a serial port */
struct fdt_serial {
u32 base_addr;  /* address of registers in physical memory */
u8 port_id;     /* uart port number */
u8 enabled;     /* 1 if enabled, 0 if disabled */
} config __attribute__ ((section(".data")));

static inline struct s5p_uart *s5p_get_base_uart(int dev_index)
{
#ifdef CONFIG_OF_CONTROL
return (struct s5p_uart *)(config.base_addr);
#else
u32 offset = dev_index * sizeof(struct s5p_uart);
return (struct s5p_uart *)(samsung_get_base_uart() + offset);
#endif
}

/*
* The coefficient, used to calculate the baudrate on S5P UARTs is
* calculated as
* C = UBRDIV * 16 + number_of_set_bits_in_UDIVSLOT
* however, section 31.6.11 of the datasheet doesn't recomment using 1 for 1,
* 3 for 2, ... (2^n - 1) for n, instead, they suggest using these constants:
*/
static const int udivslot[] = {
0,
0x0080,
0x0808,
0x0888,
0x2222,
0x4924,
0x4a52,
0x54aa,
0x5555,
0xd555,
0xd5d5,
0xddd5,
0xdddd,
0xdfdd,
0xdfdf,
0xffdf,
};

static void serial_setbrg_dev(const int dev_index)
{
struct s5p_uart *const uart = s5p_get_base_uart(dev_index);
u32 uclk = get_uart_clk(dev_index);
u32 baudrate = gd->baudrate;
u32 val;

#if defined(CONFIG_SILENT_CONSOLE) && \
defined(CONFIG_OF_CONTROL) && \
!defined(CONFIG_SPL_BUILD)
if (fdtdec_get_config_int(gd->fdt_blob, "silent_console", 0))
gd->flags |= GD_FLG_SILENT;
#endif

if (!config.enabled)
return;

val = uclk / baudrate;

writel(val / 16 - 1, &uart->ubrdiv);

if (s5p_uart_divslot())
writew(udivslot[val % 16], &uart->rest.slot);
else
writeb(val % 16, &uart->rest.value);
}

/*
* Initialise the serial port with the given baudrate. The settings
* are always 8 data bits, no parity, 1 stop bit, no start bits.
*/
static int serial_init_dev(const int dev_index)
{
struct s5p_uart *const uart = s5p_get_base_uart(dev_index);

/* enable FIFOs, auto clear Rx FIFO */
writel(0x3, &uart->ufcon);
writel(0, &uart->umcon);
/* 8N1 */
writel(0x3, &uart->ulcon);
/* No interrupts, no DMA, pure polling */
writel(0x245, &uart->ucon);

serial_setbrg_dev(dev_index);

return 0;
}

static int serial_err_check(const int dev_index, int op)
{
struct s5p_uart *const uart = s5p_get_base_uart(dev_index);
unsigned int mask;

/*
* UERSTAT
* Break Detect	[3]
* Frame Err	[2] : receive operation
* Parity Err	[1] : receive operation
* Overrun Err	[0] : receive operation
*/
if (op)
mask = 0x8;
else
mask = 0xf;

return readl(&uart->uerstat) & mask;
}

/*
* Read a single byte from the serial port. Returns 1 on success, 0
* otherwise. When the function is succesfull, the character read is
* written into its argument c.
*/
static int serial_getc_dev(const int dev_index)
{
struct s5p_uart *const uart = s5p_get_base_uart(dev_index);

if (!config.enabled)
return 0;

/* wait for character to arrive */
while (!(readl(&uart->ufstat) & (RX_FIFO_COUNT_MASK |
RX_FIFO_FULL_MASK))) {
if (serial_err_check(dev_index, 0))
return 0;
}

return (int)(readb(&uart->urxh) & 0xff);
}

/*
* Output a single byte to the serial port.
*/
static void serial_putc_dev(const char c, const int dev_index)
{
struct s5p_uart *const uart = s5p_get_base_uart(dev_index);

if (!config.enabled)
return;

/* wait for room in the tx FIFO */
while ((readl(&uart->ufstat) & TX_FIFO_FULL_MASK)) {
if (serial_err_check(dev_index, 1))
return;
}

writeb(c, &uart->utxh);

/* If \n, also do \r */
if (c == '\n')
serial_putc('\r');
}

/*
* Test whether a character is in the RX buffer
*/
static int serial_tstc_dev(const int dev_index)
{
struct s5p_uart *const uart = s5p_get_base_uart(dev_index);

if (!config.enabled)
return 0;

return (int)(readl(&uart->utrstat) & 0x1);
}

static void serial_puts_dev(const char *s, const int dev_index)
{
while (*s)
serial_putc_dev(*s++, dev_index);
}

/* Multi serial device functions */
#define DECLARE_S5P_SERIAL_FUNCTIONS(port) \
static int s5p_serial##port##_init(void) { return serial_init_dev(port); } \
static void s5p_serial##port##_setbrg(void) { serial_setbrg_dev(port); } \
static int s5p_serial##port##_getc(void) { return serial_getc_dev(port); } \
static int s5p_serial##port##_tstc(void) { return serial_tstc_dev(port); } \
static void s5p_serial##port##_putc(const char c) { serial_putc_dev(c, port); } \
static void s5p_serial##port##_puts(const char *s) { serial_puts_dev(s, port); }

#define INIT_S5P_SERIAL_STRUCTURE(port, __name) {	\
.name	= __name,				\
.start	= s5p_serial##port##_init,		\
.stop	= NULL,					\
.setbrg	= s5p_serial##port##_setbrg,		\
.getc	= s5p_serial##port##_getc,		\
.tstc	= s5p_serial##port##_tstc,		\
.putc	= s5p_serial##port##_putc,		\
.puts	= s5p_serial##port##_puts,		\
}

DECLARE_S5P_SERIAL_FUNCTIONS(0);
struct serial_device s5p_serial0_device =
INIT_S5P_SERIAL_STRUCTURE(0, "s5pser0");
DECLARE_S5P_SERIAL_FUNCTIONS(1);
struct serial_device s5p_serial1_device =
INIT_S5P_SERIAL_STRUCTURE(1, "s5pser1");
DECLARE_S5P_SERIAL_FUNCTIONS(2);
struct serial_device s5p_serial2_device =
INIT_S5P_SERIAL_STRUCTURE(2, "s5pser2");
DECLARE_S5P_SERIAL_FUNCTIONS(3);
struct serial_device s5p_serial3_device =
INIT_S5P_SERIAL_STRUCTURE(3, "s5pser3");

#ifdef CONFIG_OF_CONTROL
int fdtdec_decode_console(int *index, struct fdt_serial *uart)
{
const void *blob = gd->fdt_blob;
int node;

node = fdt_path_offset(blob, "console");
if (node < 0)
return node;

uart->base_addr = fdtdec_get_addr(blob, node, "reg");
if (uart->base_addr == FDT_ADDR_T_NONE)
return -FDT_ERR_NOTFOUND;

uart->port_id = fdtdec_get_int(blob, node, "id", -1);
uart->enabled = fdtdec_get_is_enabled(blob, node);

return 0;
}
#endif

__weak struct serial_device *default_serial_console(void)
{
#ifdef CONFIG_OF_CONTROL
int index = 0;

if ((!config.base_addr) && (fdtdec_decode_console(&index, &config))) {
debug("Cannot decode default console node\n");
return NULL;
}

switch (config.port_id) {
case 0:
return &s5p_serial0_device;
case 1:
return &s5p_serial1_device;
case 2:
return &s5p_serial2_device;
case 3:
return &s5p_serial3_device;
default:
debug("Unknown config.port_id: %d", config.port_id);
break;
}

return NULL;
#else
config.enabled = 1;
#if defined(CONFIG_SERIAL0)
return &s5p_serial0_device;
#elif defined(CONFIG_SERIAL1)
return &s5p_serial1_device;
#elif defined(CONFIG_SERIAL2)
return &s5p_serial2_device;
#elif defined(CONFIG_SERIAL3)
return &s5p_serial3_device;
#else
#error "CONFIG_SERIAL? missing."
#endif
#endif
}

void s5p_serial_initialize(void)
{
serial_register(&s5p_serial0_device);
serial_register(&s5p_serial1_device);
serial_register(&s5p_serial2_device);
serial_register(&s5p_serial3_device);
}


c)配置串口时钟

vim arch/arm/mach-s5pv210/clock.c


/* s5pv210: return PCLKs frequency */
static unsigned long get_pclk_sys(int dom)
{
struct s5pv210_clock *clk =
(struct s5pv210_clock *)samsung_get_base_clock();
unsigned long pclk;
unsigned int div;
unsigned int offset;
unsigned int pclk_sys_ratio;

div = readl(&clk->div0);

/*
* PCLK_MSYS_RATIO: [14:12]
* PCLK_DSYS_RATIO: [22:20]
* PCLK_PSYS_RATIO: [30:28]
*/
offset = 12 + (dom << 0x3);

pclk_sys_ratio = (div >> offset) & 0x7;		/* modied by Sourcelink */

pclk = get_hclk_sys(dom) / (pclk_sys_ratio + 1);

return pclk;
}


/* s5pv210: return peripheral clock frequency */
static unsigned long s5pv210_get_pclk(void)
{
/* modied by SOurcelink */
return get_pclk_sys(CLK_P);
}

/* s5pv210: return uart clock frequency */
static unsigned long s5pv210_get_uart_clk(int dev_index)
{
/* modied by SOurcelink */
return s5pv210_get_pclk();
}


3、添加led指示灯
在上一篇文章分析过u-boot.bin初始化 可以自定义指示灯指示boot启动是否正常

#if ! defined(CONFIG_SPL_BUILD)
bl coloured_LED_init
bl red_led_on
#endif


vim common/board_f.c
__weak void coloured_LED_init(void) { *(volatile unsigned long*)0xE0200060 = 0x00011000;}	/* modied by Sourcelink */
__weak void red_led_on(void) {*(volatile unsigned long*)0xE0200064 = 0x00000018;}


4、添加输出信息

vim lib/display_options.c


int display_options (void)
{
#if defined(BUILD_TAG)
printf ("\n\n%s, Build: %s\n\n", version_string, BUILD_TAG);
#else
printf ("\n\n%s\n\n", version_string);
#endif

puts("Name : Sourcelink\n");    /* add by Sourcelink */
puts("Email: Sourcelink@126.com\n");

return 0;
}


vim arch/arm/cpu/armv7/s5p-common/cpu_info.c


#ifdef CONFIG_DISPLAY_CPUINFO
int print_cpuinfo(void)
{
char buf[32];

const char *cpu_model;
int len;

/* For SoC with no real CPU ID in naming convention. */
cpu_model = fdt_getprop(gd->fdt_blob, 0, "cpu-model", &len);

/* modied by Sourcelink */
printf("CPU : %sV210@%sMHz \n", s5p_get_cpu_name(), strmhz(buf, get_arm_clk()));

return 0;
}
#endif


5、更改时钟

vim arch/arm/mach-s5pv210/clock.c


/*
* Copyright (C) 2009 Samsung Electronics
* Minkyu Kang <mk7.kang@samsung.com>
* Heungjun Kim <riverful.kim@samsung.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/

#include <common.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/clk.h>

#define CLK_M 0
#define CLK_D 1
#define CLK_P 2

/* modied by Sourcelink */
#ifndef CONFIG_SYS_CLK_FREQ_V210
#define CONFIG_SYS_CLK_FREQ_V210 12000000
#endif

/* s5pv210: return pll clock frequency (modied by Sourcelink) */
static unsigned long s5pv210_get_pll_clk(int pllreg)
{
struct s5pv210_clock *clk =
(struct s5pv210_clock *)samsung_get_base_clock();
unsigned long r, m, p, s, mask, fout;
unsigned int freq;

switch (pllreg) {
case APLL:
r = readl(&clk->apll_con0);
break;
case MPLL:
r = readl(&clk->mpll_con);
break;
case EPLL:
r = readl(&clk->epll_con0);
break;
case VPLL:
r = readl(&clk->vpll_con);
break;
default:
printf("Unsupported PLL (%d)\n", pllreg);
return 0;
}

/*
* APLL_CON: MIDV [25:16]
* MPLL_CON: MIDV [25:16]
* EPLL_CON: MIDV [24:16]
* VPLL_CON: MIDV [24:16]
*/
if (pllreg == APLL || pllreg == MPLL)
mask = 0x3ff;
else
mask = 0x1ff;

m = (r >> 16) & mask;

/* PDIV [13:8] */
p = (r >> 8) & 0x3f;
/* SDIV [2:0] */
s = r & 0x7;

freq = CONFIG_SYS_CLK_FREQ_V210;
if (pllreg == APLL) {
if (s < 1)
s = 1;
/* FOUT = MDIV * FIN / (PDIV * 2^(SDIV - 1)) */
fout = m * (freq / (p * (1 << (s - 1))));
} else
/* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */
fout = m * (freq / (p * (1 << s)));

return fout;
}

/* s5pv210: return ARM clock frequency (modied by Sourcelink) */
static unsigned long s5pv210_get_arm_clk(void)
{
struct s5pv210_clock *clk =
(struct s5pv210_clock *)samsung_get_base_clock();
unsigned long div;
unsigned long dout_apll, armclk;
unsigned int apll_ratio;

div = readl(&clk->div0);

/* ARM_RATIO: [2:0] */
apll_ratio = div & 0x7;

dout_apll = get_pll_clk(APLL) / (apll_ratio + 1);
armclk = dout_apll;

return armclk;
}

/* s5pv210: return HCLKD0 frequency */
static unsigned long get_hclk(void)
{
struct s5pv210_clock *clk =
(struct s5pv210_clock *)samsung_get_base_clock();
unsigned long hclkd0;
uint div, d0_bus_ratio;

div = readl(&clk->div0);
/* D0_BUS_RATIO: [10:8] */
d0_bus_ratio = (div >> 8) & 0x7;

hclkd0 = get_arm_clk() / (d0_bus_ratio + 1);

return hclkd0;
}

/* s5pv210: return HCLKs frequency */
static unsigned long get_hclk_sys(int dom)
{
struct s5pv210_clock *clk =
(struct s5pv210_clock *)samsung_get_base_clock();
unsigned long hclk;
unsigned int div;
unsigned int offset;
unsigned int hclk_sys_ratio;

if (dom == CLK_M)
return get_hclk();

div = readl(&clk->div0);

/*
* HCLK_MSYS_RATIO: [10:8]
* HCLK_DSYS_RATIO: [19:16]
* HCLK_PSYS_RATIO: [27:24]
*/
offset = 8 + (dom << 0x3);

hclk_sys_ratio = (div >> offset) & 0xf;

hclk = get_pll_clk(MPLL) / (hclk_sys_ratio + 1);

return hclk;
}

/* s5pv210: return PCLKs frequency */
static unsigned long get_pclk_sys(int dom)
{
struct s5pv210_clock *clk =
(struct s5pv210_clock *)samsung_get_base_clock();
unsigned long pclk;
unsigned int div;
unsigned int offset;
unsigned int pclk_sys_ratio;

div = readl(&clk->div0);

/*
* PCLK_MSYS_RATIO: [14:12]
* PCLK_DSYS_RATIO: [22:20]
* PCLK_PSYS_RATIO: [30:28]
*/
offset = 12 + (dom << 0x3);

pclk_sys_ratio = (div >> offset) & 0x7; /* moied by Sourcelink */

pclk = get_hclk_sys(dom) / (pclk_sys_ratio + 1);

return pclk;
}

/* s5pv210: return peripheral clock frequency */ static unsigned long s5pv210_get_pclk(void) { /* modied by SOurcelink */ return get_pclk_sys(CLK_P); } /* s5pv210: return uart clock frequency */ static unsigned long s5pv210_get_uart_clk(int dev_index) { /* modied by SOurcelink */ return s5pv210_get_pclk(); }
/* s5pv21: return pwm clock frequency */
static unsigned long s5pv210_get_pwm_clk(void)
{
/* modied by Sourcelink */
return s5pv210_get_pclk();
}

unsigned long get_pll_clk(int pllreg)
{
/* modied by Sourcelink */
return s5pv210_get_pll_clk(pllreg);
}

unsigned long get_arm_clk(void)
{
/* modied by Sourcelink */
return s5pv210_get_arm_clk();
}

unsigned long get_pwm_clk(void)
{
/* modied by Sourcelink */
return s5pv210_get_pwm_clk();
}

unsigned long get_uart_clk(int dev_index)
{
/* modied by Sourcelink */
return s5pv210_get_uart_clk(dev_index);
}

void set_mmc_clk(int dev_index, unsigned int div)
{
/* Do NOTHING */
}


6、更改sd复制的扇区大小
vim board/samsung/smdkv210/smdkv210.c
CopySDMMCtoMem(ch, 32, 800, (unsigned int *)CONFIG_SYS_SDRAM_BASE, 0);


7、屏蔽onenand初始化

在完成前面那么多步骤后把u-boot.bin下载到第32扇区,smdkv210-spl.bin下载到第一扇区发现程序死在了NAND: 搜索NAND:后发现 ,是死了在onenand初始化故暂时屏蔽它。

vim common/board_r.c
#ifdef CONFIG_CMD_ONENAND
//initr_onenand,                /* modied by Sourcelink */
#endif





























                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: