rk3288: add ddr driver
Supports DDR3 and LPDDR3.Supports dual channel.ddr max freq is 533mhz. ddr timing config file in src\mainboard\google\veyron\sdram_inf Remove dpll init in rk clk_init(), add rkclk_configure_ddr(unsigned int hz). BUG=chrome-os-partner:29778 TEST=Build coreboot Change-Id: I429eb0b8c365c6285fb6cfef008b41776cc9c2d9 Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Original-Commit-Id: 52838c68fe6963285c974af5dc5837e819efc321 Original-Change-Id: I6ddfe30b8585002b45060fe998c9238cbb611c05 Original-Signed-off-by: jinkun.hong <jinkun.hong@rock-chips.com> Original-Reviewed-on: https://chromium-review.googlesource.com/209465 Original-Reviewed-by: Julius Werner <jwerner@chromium.org> Original-Commit-Queue: Julius Werner <jwerner@chromium.org> Reviewed-on: http://review.coreboot.org/8865 Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org> Tested-by: build bot (Jenkins)
This commit is contained in:
committed by
Patrick Georgi
parent
d5fb66e060
commit
c33ce3554d
@@ -39,7 +39,7 @@ romstage-y += clock.c
|
||||
romstage-y += gpio.c
|
||||
romstage-y += spi.c
|
||||
romstage-y += media.c
|
||||
|
||||
romstage-y += sdram.c
|
||||
|
||||
ramstage-y += cbmem.c
|
||||
ramstage-y += timer.c
|
||||
|
@@ -70,11 +70,10 @@ static struct rk3288_cru_reg * const cru_ptr = (void *)CRU_BASE;
|
||||
(_nr * _no) == hz,\
|
||||
#hz "Hz cannot be hit with PLL divisors in " __FILE__);
|
||||
|
||||
/* apll = 816MHz, gpll = 594MHz, cpll = 384MHz, dpll = 300MHz */
|
||||
/* apll = 816MHz, gpll = 594MHz, cpll = 384MHz */
|
||||
static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 2);
|
||||
static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 4);
|
||||
static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 2, 4);
|
||||
static const struct pll_div dpll_init_cfg = PLL_DIVISORS(DPLL_HZ, 1, 4);
|
||||
|
||||
/*******************PLL CON0 BITS***************************/
|
||||
#define PLL_OD_MSK (0x0F)
|
||||
@@ -191,23 +190,21 @@ void rkclk_init(void)
|
||||
/* pll enter slow-mode */
|
||||
writel(RK_CLRSETBITS(APLL_MODE_MSK, APLL_MODE_SLOW)
|
||||
| RK_CLRSETBITS(GPLL_MODE_MSK, GPLL_MODE_SLOW)
|
||||
| RK_CLRSETBITS(CPLL_MODE_MSK, CPLL_MODE_SLOW)
|
||||
| RK_CLRSETBITS(DPLL_MODE_MSK, DPLL_MODE_SLOW),
|
||||
| RK_CLRSETBITS(CPLL_MODE_MSK, CPLL_MODE_SLOW),
|
||||
&cru_ptr->cru_mode_con);
|
||||
|
||||
/* init pll */
|
||||
rkclk_set_pll(&cru_ptr->cru_apll_con[0], &apll_init_cfg);
|
||||
rkclk_set_pll(&cru_ptr->cru_gpll_con[0], &gpll_init_cfg);
|
||||
rkclk_set_pll(&cru_ptr->cru_cpll_con[0], &cpll_init_cfg);
|
||||
rkclk_set_pll(&cru_ptr->cru_dpll_con[0], &dpll_init_cfg);
|
||||
|
||||
/* waiting for pll lock */
|
||||
while (1) {
|
||||
if ((readl(&rk3288_grf->soc_status[1])
|
||||
& (SOCSTS_APLL_LOCK | SOCSTS_CPLL_LOCK
|
||||
| SOCSTS_DPLL_LOCK | SOCSTS_GPLL_LOCK))
|
||||
| SOCSTS_GPLL_LOCK))
|
||||
== (SOCSTS_APLL_LOCK | SOCSTS_CPLL_LOCK
|
||||
| SOCSTS_GPLL_LOCK | SOCSTS_DPLL_LOCK))
|
||||
| SOCSTS_GPLL_LOCK))
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
@@ -248,12 +245,74 @@ void rkclk_init(void)
|
||||
/* PLL enter normal-mode */
|
||||
writel(RK_CLRSETBITS(APLL_MODE_MSK, APLL_MODE_NORM)
|
||||
| RK_CLRSETBITS(GPLL_MODE_MSK, GPLL_MODE_NORM)
|
||||
| RK_CLRSETBITS(CPLL_MODE_MSK, CPLL_MODE_NORM)
|
||||
| RK_CLRSETBITS(DPLL_MODE_MSK, DPLL_MODE_NORM),
|
||||
| RK_CLRSETBITS(CPLL_MODE_MSK, CPLL_MODE_NORM),
|
||||
&cru_ptr->cru_mode_con);
|
||||
|
||||
}
|
||||
|
||||
void rkclk_configure_ddr(unsigned int hz)
|
||||
{
|
||||
struct pll_div dpll_cfg;
|
||||
|
||||
if (hz <= 150000000) {
|
||||
dpll_cfg.nr = 3;
|
||||
dpll_cfg.no = 8;
|
||||
} else if (hz <= 540000000) {
|
||||
dpll_cfg.nr = 6;
|
||||
dpll_cfg.no = 4;
|
||||
} else {
|
||||
dpll_cfg.nr = 1;
|
||||
dpll_cfg.no = 1;
|
||||
}
|
||||
|
||||
dpll_cfg.nf = (hz / 1000 * dpll_cfg.nr * dpll_cfg.no) / 24000;
|
||||
assert(dpll_cfg.nf < 4096
|
||||
&& hz == dpll_cfg.nf * 24000 / (dpll_cfg.nr * dpll_cfg.no)
|
||||
* 1000);
|
||||
/* pll enter slow-mode */
|
||||
writel(RK_CLRSETBITS(DPLL_MODE_MSK, DPLL_MODE_SLOW),
|
||||
&cru_ptr->cru_mode_con);
|
||||
|
||||
rkclk_set_pll(&cru_ptr->cru_dpll_con[0], &dpll_cfg);
|
||||
|
||||
/* waiting for pll lock */
|
||||
while (1) {
|
||||
if (readl(&rk3288_grf->soc_status[1]) & SOCSTS_DPLL_LOCK)
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
/* PLL enter normal-mode */
|
||||
writel(RK_CLRSETBITS(DPLL_MODE_MSK, DPLL_MODE_NORM),
|
||||
&cru_ptr->cru_mode_con);
|
||||
}
|
||||
|
||||
void rkclk_ddr_reset(u32 ch, u32 ctl, u32 phy)
|
||||
{
|
||||
u32 phy_ctl_srstn_shift = 4 + 5 * ch;
|
||||
u32 ctl_psrstn_shift = 3 + 5 * ch;
|
||||
u32 ctl_srstn_shift = 2 + 5 * ch;
|
||||
u32 phy_psrstn_shift = 1 + 5 * ch;
|
||||
u32 phy_srstn_shift = 5 * ch;
|
||||
|
||||
writel(RK_CLRSETBITS(1 << phy_ctl_srstn_shift,
|
||||
phy << phy_ctl_srstn_shift)
|
||||
| RK_CLRSETBITS(1 << ctl_psrstn_shift, ctl << ctl_psrstn_shift)
|
||||
| RK_CLRSETBITS(1 << ctl_srstn_shift, ctl << ctl_srstn_shift)
|
||||
| RK_CLRSETBITS(1 << phy_psrstn_shift, phy << phy_psrstn_shift)
|
||||
| RK_CLRSETBITS(1 << phy_srstn_shift, phy << phy_srstn_shift),
|
||||
&cru_ptr->cru_softrst_con[10]);
|
||||
}
|
||||
|
||||
void rkclk_ddr_phy_ctl_reset(u32 ch, u32 n)
|
||||
{
|
||||
u32 phy_ctl_srstn_shift = 4 + 5 * ch;
|
||||
|
||||
writel(RK_CLRSETBITS(1 << phy_ctl_srstn_shift,
|
||||
n << phy_ctl_srstn_shift),
|
||||
&cru_ptr->cru_softrst_con[10]);
|
||||
}
|
||||
|
||||
void rkclk_configure_spi(unsigned int bus, unsigned int hz)
|
||||
{
|
||||
int src_clk_div = GPLL_HZ / hz;
|
||||
|
@@ -25,10 +25,11 @@
|
||||
#define APLL_HZ 816000000
|
||||
#define GPLL_HZ 594000000
|
||||
#define CPLL_HZ 384000000
|
||||
#define DPLL_HZ 300000000
|
||||
|
||||
void rkclk_init(void);
|
||||
void rkclk_configure_spi(unsigned int bus, unsigned int hz);
|
||||
void rkclk_ddr_reset(u32 ch, u32 ctl, u32 phy);
|
||||
void rkclk_ddr_phy_ctl_reset(u32 ch, u32 n);
|
||||
void rkclk_configure_ddr(unsigned int hz);
|
||||
|
||||
#endif /* __SOC_ROCKCHIP_RK3288_CLOCK_H__ */
|
||||
|
||||
|
@@ -20,6 +20,8 @@
|
||||
#ifndef __SOC_ROCKCHIP_RK3288_CPU_H__
|
||||
#define __SOC_ROCKCHIP_RK3288_CPU_H__
|
||||
|
||||
#include <arch/io.h>
|
||||
|
||||
#define RK_CLRSETBITS(clr, set) ((((clr) | (set)) << 16) | set)
|
||||
#define RK_SETBITS(set) RK_CLRSETBITS(0, set)
|
||||
#define RK_CLRBITS(clr) RK_CLRSETBITS(clr, 0)
|
||||
|
@@ -25,9 +25,10 @@
|
||||
#include "cpu.h"
|
||||
|
||||
struct rk3288_grf_gpio_lh {
|
||||
u32 gpiol;
|
||||
u32 gpioh;
|
||||
u32 l;
|
||||
u32 h;
|
||||
};
|
||||
check_member(rk3288_grf_gpio_lh, h, 0x4);
|
||||
|
||||
struct rk3288_grf_regs {
|
||||
u32 reserved[3];
|
||||
@@ -155,6 +156,41 @@ struct rk3288_grf_regs {
|
||||
};
|
||||
check_member(rk3288_grf_regs, soc_con16, 0x3a8);
|
||||
|
||||
struct rk3288_sgrf_regs {
|
||||
u32 soc_con0;
|
||||
u32 soc_con1;
|
||||
u32 soc_con2;
|
||||
u32 soc_con3;
|
||||
u32 soc_con4;
|
||||
u32 soc_con5;
|
||||
u32 reserved1[(0x20-0x18)/4];
|
||||
u32 busdmac_con[2];
|
||||
u32 reserved2[(0x40-0x28)/4];
|
||||
u32 cpu_con[3];
|
||||
u32 reserved3[(0x50-0x4c)/4];
|
||||
u32 soc_con6;
|
||||
u32 soc_con7;
|
||||
u32 soc_con8;
|
||||
u32 soc_con9;
|
||||
u32 soc_con10;
|
||||
u32 soc_con11;
|
||||
u32 soc_con12;
|
||||
u32 soc_con13;
|
||||
u32 soc_con14;
|
||||
u32 soc_con15;
|
||||
u32 soc_con16;
|
||||
u32 soc_con17;
|
||||
u32 soc_con18;
|
||||
u32 soc_con19;
|
||||
u32 soc_con20;
|
||||
u32 soc_con21;
|
||||
u32 reserved4[(0x100-0x90)/4];
|
||||
u32 soc_status[2];
|
||||
u32 reserved5[(0x120-0x108)/4];
|
||||
u32 fast_boot_addr;
|
||||
};
|
||||
check_member(rk3288_sgrf_regs, fast_boot_addr, 0x0120);
|
||||
|
||||
static struct rk3288_grf_regs * const rk3288_grf = (void *)GRF_BASE;
|
||||
static struct rk3288_sgrf_regs * const rk3288_sgrf = (void *)GRF_SECURE_BASE;
|
||||
|
||||
|
1046
src/soc/rockchip/rk3288/sdram.c
Normal file
1046
src/soc/rockchip/rk3288/sdram.c
Normal file
File diff suppressed because it is too large
Load Diff
104
src/soc/rockchip/rk3288/sdram.h
Normal file
104
src/soc/rockchip/rk3288/sdram.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2014 Rockchip 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; version 2 of the License.
|
||||
*
|
||||
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef __SOC_ROCKCHIP_RK3288_SDRAM_H__
|
||||
#define __SOC_ROCKCHIP_RK3288_SDRAM_H__
|
||||
|
||||
#include <arch/io.h>
|
||||
|
||||
enum {
|
||||
DDR3 = 3,
|
||||
LPDDR3 = 6,
|
||||
UNUSED = 0xFF,
|
||||
};
|
||||
|
||||
struct rk3288_sdram_channel {
|
||||
u8 rank;
|
||||
u8 col;
|
||||
u8 bk;
|
||||
u8 bw;
|
||||
u8 dbw;
|
||||
u8 row_3_4;
|
||||
u8 cs0_row;
|
||||
u8 cs1_row;
|
||||
};
|
||||
|
||||
struct rk3288_sdram_pctl_timing {
|
||||
u32 togcnt1u;
|
||||
u32 tinit;
|
||||
u32 trsth;
|
||||
u32 togcnt100n;
|
||||
u32 trefi;
|
||||
u32 tmrd;
|
||||
u32 trfc;
|
||||
u32 trp;
|
||||
u32 trtw;
|
||||
u32 tal;
|
||||
u32 tcl;
|
||||
u32 tcwl;
|
||||
u32 tras;
|
||||
u32 trc;
|
||||
u32 trcd;
|
||||
u32 trrd;
|
||||
u32 trtp;
|
||||
u32 twr;
|
||||
u32 twtr;
|
||||
u32 texsr;
|
||||
u32 txp;
|
||||
u32 txpdll;
|
||||
u32 tzqcs;
|
||||
u32 tzqcsi;
|
||||
u32 tdqs;
|
||||
u32 tcksre;
|
||||
u32 tcksrx;
|
||||
u32 tcke;
|
||||
u32 tmod;
|
||||
u32 trstl;
|
||||
u32 tzqcl;
|
||||
u32 tmrr;
|
||||
u32 tckesr;
|
||||
u32 tdpd;
|
||||
};
|
||||
check_member(rk3288_sdram_pctl_timing, tdpd, 0x144 - 0xc0);
|
||||
|
||||
struct rk3288_sdram_phy_timing {
|
||||
u32 dtpr0;
|
||||
u32 dtpr1;
|
||||
u32 dtpr2;
|
||||
u32 mr[4];
|
||||
};
|
||||
|
||||
struct rk3288_sdram_params {
|
||||
struct rk3288_sdram_channel ch[2];
|
||||
struct rk3288_sdram_pctl_timing pctl_timing;
|
||||
struct rk3288_sdram_phy_timing phy_timing;
|
||||
u32 noc_timing;
|
||||
u32 noc_activate;
|
||||
u32 ddrconfig;
|
||||
u32 ddr_freq;
|
||||
u8 dramtype;
|
||||
u8 num_channels;
|
||||
u8 stride;
|
||||
u8 odt;
|
||||
};
|
||||
|
||||
void sdram_init(const struct rk3288_sdram_params *sdram_params);
|
||||
u32 sdram_get_ram_code(void);
|
||||
const struct rk3288_sdram_params *get_sdram_config(void);
|
||||
#endif
|
Reference in New Issue
Block a user