Skip to content

Commit 700b61e

Browse files
committed
ARM: exynos: add clock and DMC init for exynos4412
1 parent ecace78 commit 700b61e

File tree

4 files changed

+675
-269
lines changed

4 files changed

+675
-269
lines changed

arch/arm/mach-exynos/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ ifdef CONFIG_SPL_BUILD
1515
obj-$(CONFIG_EXYNOS5) += clock_init_exynos5.o
1616
obj-$(CONFIG_EXYNOS5) += dmc_common.o dmc_init_ddr3.o
1717
obj-$(CONFIG_EXYNOS4210)+= dmc_init_exynos4210.o clock_init_exynos4210.o
18-
obj-$(CONFIG_EXYNOS4) += dmc_init_exynos4412.o
18+
obj-$(CONFIG_EXYNOS4412)+= dmc_init_exynos4412.o clock_init_exynos4412.o
1919
obj-y += spl_boot.o tzpc.o
2020
obj-y += lowlevel_init.o
2121
endif
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/*
2+
* Clock initialisation for Exynos4412 based boards
3+
*
4+
* Copyright (C) 2018 Simon Shields <simon@lineageos.org>
5+
*
6+
* See file CREDITS for list of people who contributed to this
7+
* project.
8+
*
9+
* This program is free software; you can redistribute it and/or
10+
* modify it under the terms of the GNU General Public License as
11+
* published by the Free Software Foundation; either version 2 of
12+
* the License, or (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU General Public License
20+
* along with this program; if not, write to the Free Software
21+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22+
* MA 02111-1307 USA
23+
*/
24+
25+
#include <common.h>
26+
#include <config.h>
27+
#include <asm/io.h>
28+
#include <asm/arch/cpu.h>
29+
#include <asm/arch/clk.h>
30+
#include <asm/arch/clock.h>
31+
#include <asm/arch/power.h>
32+
#include "common_setup.h"
33+
#include "exynos4412_setup.h"
34+
35+
/*
36+
* TODO: change all clock sources, then change clock dividers.
37+
*/
38+
void system_clock_init(void)
39+
{
40+
struct exynos4x12_clock *clk =
41+
(struct exynos4x12_clock *)samsung_get_base_clock();
42+
struct exynos4412_power *power =
43+
(struct exynos4412_power *)samsung_get_base_power();
44+
#if 0
45+
struct exynos4_dmc *dmc = (struct exynos4_dmc *)samsung_get_base_dmc_ctrl();
46+
struct exynos4_dmc *dmc1 = (struct exynos4_dmc *)(samsung_get_base_dmc_ctrl() + DMC_OFFSET);
47+
#endif
48+
49+
/* Set up UART */
50+
51+
writel(0, &clk->src_cpu);
52+
writel(CLK_SRC_TOP0_VAL, &clk->src_top0);
53+
writel(CLK_SRC_TOP1_VAL, &clk->src_top1);
54+
writel(CLK_SRC_LEFTBUS_VAL, &clk->src_leftbus);
55+
writel(CLK_SRC_RIGHTBUS_VAL, &clk->src_rightbus);
56+
writel(CLK_SRC_PERIL0_VAL, &clk->src_peril0);
57+
58+
sdelay(0x10000);
59+
60+
writel(CLK_DIV_DMC0_VAL, &clk->div_dmc0);
61+
writel(CLK_DIV_DMC1_VAL, &clk->div_dmc1);
62+
writel(CLK_DIV_TOP_VAL, &clk->div_top);
63+
writel(CLK_DIV_LEFTBUS_VAL, &clk->div_leftbus);
64+
writel(CLK_DIV_RIGHTBUS_VAL, &clk->div_rightbus);
65+
writel(CLK_DIV_PERIL0_VAL, &clk->div_peril0);
66+
67+
/* PLLs */
68+
writel(APLL_LOCK_VAL, &clk->apll_lock);
69+
writel(MPLL_LOCK_VAL, &clk->mpll_lock);
70+
writel(EPLL_LOCK_VAL, &clk->epll_lock);
71+
writel(VPLL_LOCK_VAL, &clk->vpll_lock);
72+
73+
writel(CLK_DIV_CPU0_VAL, &clk->div_cpu0);
74+
writel(CLK_DIV_CPU1_VAL, &clk->div_cpu1);
75+
76+
/* APLL: 800MHz */
77+
writel(APLL_CON1_VAL, &clk->apll_con1);
78+
writel(APLL_CON0_VAL, &clk->apll_con0);
79+
80+
/* The iROM sets MPLL at 400MHz.
81+
* Skip increasing MPLL if it's not at 400MHz */
82+
if (readl(&clk->mpll_con0) == 0xa0640301) {
83+
/* MPLL: 800MHz */
84+
writel(MPLL_CON1_VAL, &clk->mpll_con1);
85+
writel(MPLL_CON0_VAL, &clk->mpll_con0);
86+
}
87+
88+
/* EPLL: 96MHz */
89+
/* (64) * (24000000) / (2 * (1 << 3)) */
90+
writel(EPLL_CON2_VAL, &clk->epll_con2);
91+
writel(EPLL_CON1_VAL, &clk->epll_con1);
92+
writel(EPLL_CON0_VAL, &clk->epll_con0);
93+
94+
/* VPLL: 108MHz */
95+
/* (72) * (24000000) / (2 * (1 << 3)) */
96+
writel(VPLL_CON2_VAL, &clk->vpll_con2);
97+
writel(VPLL_CON1_VAL, &clk->vpll_con1);
98+
writel(VPLL_CON0_VAL, &clk->vpll_con0);
99+
100+
/* Stabilise */
101+
sdelay(0x40000);
102+
103+
/* Now that PLLs are set up, we can set the other clocks to use them... */
104+
writel((1 << 24) | (1 << 0), &clk->src_cpu);
105+
writel((1 << 16) | (1 << 12), &clk->src_dmc);
106+
writel((1 << 8) | (1 << 4), &clk->src_top0);
107+
writel((1 << 24) | (1 << 20) | (1 << 16) | (1 << 12), &clk->src_top1);
108+
109+
sdelay(0x10000);
110+
111+
/*
112+
* In the SDMMC booting case, we need to reconfigure MMC clock
113+
* to make the iROM happy.
114+
*/
115+
u32 fsys2_div = readl(&clk->div_fsys2);
116+
/* new MMC2 div is 16 */
117+
fsys2_div |= 0xf;
118+
writel(fsys2_div, &clk->div_fsys2);
119+
120+
/*check C2C_CTRL enable bit */
121+
if ((readl(&power->c2c_ctrl) & 1) != 0)
122+
return;
123+
#if 0
124+
writel(PHYCONTROL0_VAL, &dmc->phycontrol0);
125+
writel(MEM_TERM_EN | PHY_READ_EN | CTRL_SHGATE | CTRL_REF(8) | CTRL_SHIFTC(4), &dmc->phycontrol1);
126+
writel(PHYCONTROL0_VAL | CTRL_DLL_START, &dmc->phycontrol0);
127+
sdelay(0x20000);
128+
129+
writel(CTRL_REF(8) | CTRL_SHIFTC(4), &dmc->phycontrol1);
130+
writel(CTRL_REF(8) | FP_RESYNC | CTRL_SHIFTC(4), &dmc->phycontrol1);
131+
132+
sdelay(0x20000);
133+
134+
writel(PHYCONTROL0_VAL, &dmc1->phycontrol0);
135+
writel(MEM_TERM_EN | PHY_READ_EN | CTRL_SHGATE | CTRL_REF(8) | CTRL_SHIFTC(4), &dmc1->phycontrol1);
136+
writel(PHYCONTROL0_VAL | CTRL_DLL_START, &dmc1->phycontrol0);
137+
sdelay(0x20000);
138+
139+
writel(CTRL_REF(8) | CTRL_SHIFTC(4), &dmc1->phycontrol1);
140+
writel(CTRL_REF(8) | FP_RESYNC | CTRL_SHIFTC(4), &dmc1->phycontrol1);
141+
142+
sdelay(0x20000);
143+
144+
writel(DMC_CONCONTROL, &dmc->concontrol);
145+
writel(DMC_CONCONTROL, &dmc1->concontrol);
146+
147+
writel(DMC_MEMCONTROL, &dmc->memcontrol);
148+
writel(DMC_MEMCONTROL, &dmc1->memcontrol);
149+
#endif
150+
}

arch/arm/mach-exynos/dmc_init_exynos4412.c

Lines changed: 53 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -9,103 +9,12 @@
99
#include "common_setup.h"
1010
#include "exynos4412_setup.h"
1111

12-
// TODO: 4412 and 4210 should be commonised using something like is_soc_4210
13-
void system_clock_init(void)
14-
{
15-
struct exynos4x12_clock *clk =
16-
(struct exynos4x12_clock *)samsung_get_base_clock();
17-
struct exynos4412_power *power = (struct exynos4412_power *)samsung_get_base_power();
18-
struct exynos4_dmc *dmc = (struct exynos4_dmc *)samsung_get_base_dmc_ctrl();
19-
struct exynos4_dmc *dmc1 = (struct exynos4_dmc *)(samsung_get_base_dmc_ctrl() + DMC_OFFSET);
20-
21-
// disable WDT
22-
writel(0, (unsigned int *)0x10060000);
23-
24-
writel(0, &clk->src_cpu);
25-
26-
sdelay(0x10000);
27-
28-
writel(CLK_DIV_DMC0_VAL, &clk->div_dmc0);
29-
writel(CLK_DIV_DMC1_VAL, &clk->div_dmc1);
30-
31-
writel(CLK_SRC_TOP0_VAL, &clk->src_top0);
32-
writel(CLK_SRC_TOP1_VAL, &clk->src_top1);
33-
sdelay(0x10000);
34-
writel(CLK_DIV_TOP_VAL, &clk->div_top);
35-
36-
writel(CLK_SRC_LEFTBUS_VAL, &clk->src_leftbus);
37-
sdelay(0x10000);
38-
writel(CLK_DIV_LEFTBUS_VAL, &clk->div_leftbus);
39-
40-
writel(CLK_SRC_RIGHTBUS_VAL, &clk->src_rightbus);
41-
sdelay(0x10000);
42-
writel(CLK_DIV_RIGHTBUS_VAL, &clk->div_rightbus);
43-
44-
// setup PLLs
45-
writel(0x3e8, &clk->apll_lock);
46-
writel(0x2f1, &clk->mpll_lock);
47-
writel(0x2321, &clk->epll_lock);
48-
writel(0x2321, &clk->vpll_lock);
49-
50-
writel(CLK_DIV_CPU0_VAL, &clk->div_cpu0);
51-
writel(CLK_DIV_CPU1_VAL, &clk->div_cpu1);
52-
53-
writel(APLL_CON1_VAL, &clk->apll_con1);
54-
writel(APLL_CON0_VAL, &clk->apll_con0);
55-
56-
/* don't reset MPLL in C2C case */
57-
if (readl(&clk->mpll_con1) == 0xa0640301) {
58-
writel(MPLL_CON1_VAL, &clk->mpll_con1);
59-
writel(MPLL_CON0_VAL, &clk->mpll_con0);
60-
}
61-
62-
writel(EPLL_CON2_VAL, &clk->epll_con2);
63-
writel(EPLL_CON1_VAL, &clk->epll_con1);
64-
writel(EPLL_CON0_VAL, &clk->epll_con0);
65-
66-
writel(VPLL_CON2_VAL, &clk->vpll_con2);
67-
writel(VPLL_CON1_VAL, &clk->vpll_con1);
68-
writel(VPLL_CON0_VAL, &clk->vpll_con0);
69-
70-
sdelay(0x10000);
71-
72-
/* wtf */
73-
writel(0x01000001, &clk->src_cpu);
74-
writel(0x00011000, &clk->src_dmc);
75-
writel(0x00000110, &clk->src_top0);
76-
writel(0x01111000, &clk->src_top1);
77-
78-
sdelay(0x10000);
79-
80-
if ((readl(&power->c2c_ctrl) & 1) != 0) {
81-
return;
82-
}
83-
84-
/* todo: split this out, clean it up. Or drop it entirely? */
85-
// DRAM clocks
86-
writel(0x7f10100a, &dmc->phycontrol0);
87-
writel(0xe0000084, &dmc->phycontrol1);
88-
writel(0x7f10100b, &dmc->phycontrol0);
89-
90-
sdelay(0x20000);
91-
92-
writel(0x0000008c, &dmc->phycontrol1); // force DLL resync
93-
writel(0x00000084, &dmc->phycontrol1);
94-
95-
sdelay(0x20000);
96-
97-
writel(0x0fff30fa, &dmc->concontrol);
98-
writel(0x0fff30fa, &dmc1->concontrol);
99-
100-
writel(0x00202533, &dmc->memcontrol);
101-
writel(0x00202533, &dmc1->memcontrol);
102-
}
103-
10412
void mem_ctrl_init(int reset)
10513
{
10614
struct exynos4x12_clock *clk =
10715
(struct exynos4x12_clock *)samsung_get_base_clock();
10816
struct exynos4_dmc *dmc = (struct exynos4_dmc *)samsung_get_base_dmc_ctrl();
17+
struct exynos4_dmc *dmc1 = (struct exynos4_dmc *)(samsung_get_base_dmc_ctrl() + DMC_OFFSET);
10918

11019
writel(0x00117713, &clk->div_dmc0);
11120

@@ -151,49 +60,74 @@ void mem_ctrl_init(int reset)
15160
writel(0x810, &dmc->directcmd);
15261
writel(0xc08, &dmc->directcmd);
15362

154-
dmc = (struct exynos4_dmc *)(samsung_get_base_dmc_ctrl() + DMC_OFFSET);
63+
writel(0xe3855403, &dmc1->phyzqcontrol);
64+
writel(0x71101008, &dmc1->phycontrol0);
65+
writel(0x7110100a, &dmc1->phycontrol0);
15566

156-
writel(0xe3855403, &dmc->phyzqcontrol);
157-
writel(0x71101008, &dmc->phycontrol0);
158-
writel(0x7110100a, &dmc->phycontrol0);
67+
writel(0x00000084, &dmc1->phycontrol1);
68+
writel(0x71101008, &dmc1->phycontrol0);
69+
writel(0x0000008c, &dmc1->phycontrol1);
70+
writel(0x00000084, &dmc1->phycontrol1);
71+
writel(0x0000008c, &dmc1->phycontrol1);
72+
writel(0x00000084, &dmc1->phycontrol1);
15973

160-
writel(0x00000084, &dmc->phycontrol1);
161-
writel(0x71101008, &dmc->phycontrol0);
162-
writel(0x0000008c, &dmc->phycontrol1);
163-
writel(0x00000084, &dmc->phycontrol1);
164-
writel(0x0000008c, &dmc->phycontrol1);
165-
writel(0x00000084, &dmc->phycontrol1);
166-
167-
writel(0x0fff30ca, &dmc->concontrol);
168-
writel(0x00202500, &dmc->memcontrol);
169-
writel(0x40c01323, &dmc->memconfig0);
170-
writel(0x80000000 | 0x7, &dmc->ivcontrol);
171-
writel(0x64000000, &dmc->prechconfig);
172-
writel(0x9c4000ff, &dmc->phycontrol0);
74+
writel(0x0fff30ca, &dmc1->concontrol);
75+
writel(0x00202500, &dmc1->memcontrol);
76+
writel(0x40c01323, &dmc1->memconfig0);
77+
writel(0x80000000 | 0x7, &dmc1->ivcontrol);
78+
writel(0x64000000, &dmc1->prechconfig);
79+
writel(0x9c4000ff, &dmc1->phycontrol0);
17380

174-
writel(0x5d, &dmc->timingref);
81+
writel(0x5d, &dmc1->timingref);
17582

176-
writel(0x34498691, &dmc->timingrow);
177-
writel(0x36330306, &dmc->timingdata);
178-
writel(0x50380365, &dmc->timingpower);
83+
writel(0x34498691, &dmc1->timingrow);
84+
writel(0x36330306, &dmc1->timingdata);
85+
writel(0x50380365, &dmc1->timingpower);
17986

18087
sdelay(0x100000);
18188

182-
writel(0x07000000, &dmc->directcmd);
89+
writel(0x07000000, &dmc1->directcmd);
18390

18491
sdelay(0x100000);
18592

186-
writel(0x00071c00, &dmc->directcmd);
93+
writel(0x00071c00, &dmc1->directcmd);
18794

18895
sdelay(0x100000);
18996

190-
writel(0x00010bfc, &dmc->directcmd);
97+
writel(0x00010bfc, &dmc1->directcmd);
19198

19299
sdelay(0x100000);
193100

194-
writel(0x608, &dmc->directcmd);
195-
writel(0x810, &dmc->directcmd);
196-
writel(0xc08, &dmc->directcmd);
101+
writel(0x608, &dmc1->directcmd);
102+
writel(0x810, &dmc1->directcmd);
103+
writel(0xc08, &dmc1->directcmd);
104+
105+
writel(PHYCONTROL0_VAL, &dmc->phycontrol0);
106+
writel(MEM_TERM_EN | PHY_READ_EN | CTRL_SHGATE | CTRL_REF(8) | CTRL_SHIFTC(4), &dmc->phycontrol1);
107+
writel(PHYCONTROL0_VAL | CTRL_DLL_START, &dmc->phycontrol0);
108+
sdelay(0x20000);
109+
110+
writel(CTRL_REF(8) | CTRL_SHIFTC(4), &dmc->phycontrol1);
111+
writel(CTRL_REF(8) | FP_RESYNC | CTRL_SHIFTC(4), &dmc->phycontrol1);
112+
113+
sdelay(0x20000);
114+
115+
writel(PHYCONTROL0_VAL, &dmc1->phycontrol0);
116+
writel(MEM_TERM_EN | PHY_READ_EN | CTRL_SHGATE | CTRL_REF(8) | CTRL_SHIFTC(4), &dmc1->phycontrol1);
117+
writel(PHYCONTROL0_VAL | CTRL_DLL_START, &dmc1->phycontrol0);
118+
sdelay(0x20000);
119+
120+
writel(CTRL_REF(8) | CTRL_SHIFTC(4), &dmc1->phycontrol1);
121+
writel(CTRL_REF(8) | FP_RESYNC | CTRL_SHIFTC(4), &dmc1->phycontrol1);
122+
123+
sdelay(0x20000);
124+
125+
writel(DMC_CONCONTROL, &dmc->concontrol);
126+
writel(DMC_CONCONTROL, &dmc1->concontrol);
127+
128+
writel(DMC_MEMCONTROL, &dmc->memcontrol);
129+
writel(DMC_MEMCONTROL, &dmc1->memcontrol);
130+
197131
}
198132

199133

0 commit comments

Comments
 (0)