ARM10C 93주차 후기
일시 : 2015.03.07 (93주차)
모임명 : NAVER개발자커뮤니티지원_IAMROOT.ORG_10차ARM-C
장소 : 토즈 타워점
장소지원 : NAVER 개발자 커뮤니티 지원 프로그램
참여인원 : 3명
93주차 진도
-
start_kernel() init/main.c
- ->time_init() 741 /arch/arm/kernel/time.c
- ->of_clk_init() 154 /arch/arm/kernel/time.c
- ->clk_init_cb() // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- ->exynos5420_clk_init() 3538 /drivers/clk/samsung/clk-exynos5420.c
- ->samsung_clk_register_div() 1324 /drivers/clk/samsung/clk-exynos5420.c
- ->clk_register_divider() 544 drivers/clk/clk-divider.c
- ->_register_divider() 416 drivers/clk/clk-divider.c
- ->clk_register() 379 drivers/clk/clk-divider.c
-
NOTE
- 5420 arndale board 로그에 따라서
- fout_spll : 600 Mhz 로 분석
- sclk_fimd1 : 266 Mhz 로 분석
-
sclk_fimd1 자료 참조
- // list->name: exynos5420_gate_clks[36].name: "sclk_fimd1",
- // list->parent_name: exynos5420_gate_clks[36].parent_name: "dout_fimd1",
- // list->flags: exynos5420_gate_clks[36].flags: 0x4, :
- // 0xf0050828,
- // list->bit_idx: exynos5420_gate_clks[36].bit_idx: 0,
- // list->gate_flags: exynos5420_gate_clks[36].gate_flags: 0,
- // &lock
-
init 참조
- // init.name: "sclk_fimd1"
- // init.ops: &clk_gate_ops
- // init.flags: 0x24
- // init.parent_names: "dout_fimd1"
- // init.num_parents: 1
- // (sclk_fimd1))->reg: 0xf0050828
- // (sclk_fimd1))->bit_idx: 0
- // (sclk_fimd1))->flags: 0
- // (sclk_fimd1))->lock: &lock
- // (sclk_fimd1))->hw.init: &init
-
clk_register(sclk_fimd1) 에서 한일:
- // (kmem_cache#29-oX (sclk_fimd1))->name: kmem_cache#30-oX ("sclk_fimd1")
- // (kmem_cache#29-oX (sclk_fimd1))->ops: &clk_gate_ops
- // (kmem_cache#29-oX (sclk_fimd1))->hw: &(kmem_cache#30-oX (sclk_fimd1))->hw
- // (kmem_cache#29-oX (sclk_fimd1))->flags: 0x24
- // (kmem_cache#29-oX (sclk_fimd1))->num_parents 1
- // (kmem_cache#29-oX (sclk_fimd1))->parent_names[0]: (kmem_cache#30-oX)[0]: kmem_cache#30-oX: "mout_apll"
- // (kmem_cache#29-oX (sclk_fimd1))->parent: kmem_cache#29-oX (dout_fimd1)
- // (kmem_cache#29-oX (sclk_fimd1))->rate: 266000000
- //
- // kmem_cache#30-oX (sclk_fimd1)
- // (kmem_cache#30-oX (sclk_fimd1))->reg: 0xf0050828
- // (kmem_cache#30-oX (sclk_fimd1))->bit_idx: 0
- // (kmem_cache#30-oX (sclk_fimd1))->flags: 0
- // (kmem_cache#30-oX (sclk_fimd1))->lock: &lock
- // (kmem_cache#30-oX (sclk_fimd1))->hw.init: &init
- // (kmem_cache#30-oX (sclk_fimd1))->table: NULL
start_kernel() init/main.c
- ->time_init() 741 /arch/arm/kernel/time.c
- ->of_clk_init() 154 /arch/arm/kernel/time.c
- ->clk_init_cb() // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- ->exynos5420_clk_init() 3538 /drivers/clk/samsung/clk-exynos5420.c
- ->samsung_clk_register_div() 1324 /drivers/clk/samsung/clk-exynos5420.c
- ->clk_register_divider() 544 drivers/clk/clk-divider.c
- ->_register_divider() 416 drivers/clk/clk-divider.c
- ->clk_register() 379 drivers/clk/clk-divider.c
- ->_register_divider() 416 drivers/clk/clk-divider.c
- ->clk_register_divider() 544 drivers/clk/clk-divider.c
- ->samsung_clk_register_div() 1324 /drivers/clk/samsung/clk-exynos5420.c
- ->exynos5420_clk_init() 3538 /drivers/clk/samsung/clk-exynos5420.c
- ->clk_init_cb() // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- ->of_clk_init() 154 /arch/arm/kernel/time.c
NOTE
- 5420 arndale board 로그에 따라서
- fout_spll : 600 Mhz 로 분석
- sclk_fimd1 : 266 Mhz 로 분석
sclk_fimd1 자료 참조
- // list->name: exynos5420_gate_clks[36].name: "sclk_fimd1",
- // list->parent_name: exynos5420_gate_clks[36].parent_name: "dout_fimd1",
- // list->flags: exynos5420_gate_clks[36].flags: 0x4, :
- // 0xf0050828,
- // list->bit_idx: exynos5420_gate_clks[36].bit_idx: 0,
- // list->gate_flags: exynos5420_gate_clks[36].gate_flags: 0,
- // &lock
init 참조
- // init.name: "sclk_fimd1"
- // init.ops: &clk_gate_ops
- // init.flags: 0x24
- // init.parent_names: "dout_fimd1"
- // init.num_parents: 1
- // (sclk_fimd1))->reg: 0xf0050828
- // (sclk_fimd1))->bit_idx: 0
- // (sclk_fimd1))->flags: 0
- // (sclk_fimd1))->lock: &lock
- // (sclk_fimd1))->hw.init: &init
clk_register(sclk_fimd1) 에서 한일:
- // (kmem_cache#29-oX (sclk_fimd1))->name: kmem_cache#30-oX ("sclk_fimd1")
- // (kmem_cache#29-oX (sclk_fimd1))->ops: &clk_gate_ops
- // (kmem_cache#29-oX (sclk_fimd1))->hw: &(kmem_cache#30-oX (sclk_fimd1))->hw
- // (kmem_cache#29-oX (sclk_fimd1))->flags: 0x24
- // (kmem_cache#29-oX (sclk_fimd1))->num_parents 1
- // (kmem_cache#29-oX (sclk_fimd1))->parent_names[0]: (kmem_cache#30-oX)[0]: kmem_cache#30-oX: "mout_apll"
- // (kmem_cache#29-oX (sclk_fimd1))->parent: kmem_cache#29-oX (dout_fimd1)
- // (kmem_cache#29-oX (sclk_fimd1))->rate: 266000000
- //
- // kmem_cache#30-oX (sclk_fimd1)
- // (kmem_cache#30-oX (sclk_fimd1))->reg: 0xf0050828
- // (kmem_cache#30-oX (sclk_fimd1))->bit_idx: 0
- // (kmem_cache#30-oX (sclk_fimd1))->flags: 0
- // (kmem_cache#30-oX (sclk_fimd1))->lock: &lock
- // (kmem_cache#30-oX (sclk_fimd1))->hw.init: &init
- // (kmem_cache#30-oX (sclk_fimd1))->table: NULL
start_kernel()->time_init()
- start_kernel()
asmlinkage void __init start_kernel(void)
{
...
early_irq_init();
// irq_desc 0 ~ 15 까지의 object을 할당 받고 초기화를 수행
// allocated_irqs에 bit를 1로 세팅하고 radix tree에 각 irq_desc를 노트로 추가
init_IRQ();
// gic, combiner이 사용할 메모리 할당과 자료 구조 설정,
// gic irq (0~15), combiner irq (32~63) interrupt 를 enable 시킴
tick_init();
// tick 관련 mask 변수를 0으로 초기화 수행
init_timers();
// boot_tvec_bases의 맴버 값을 초기화하고 timers_nb를 cpu_notifier 에 등록,
// softirq_vec[1] 에 run_timer_softirq 등록하여 초기화 수행
hrtimers_init();
// hrtimer_bases의 맴버 값을 초기화하고 hrtimers_nb를 cpu_notifier 에 등록,
// softirq_vec[8] 에 run_hrtimer_softirq 등록하여 초기화 수행
softirq_init();
// tasklet_vec, tasklet_hi_vec 맴버 값을 초기화하고,
// softirq_vec[6]에 tasklet_action, softirq_vec[0]에 tasklet_hi_action 등록하여 초기화 수행
timekeeping_init();
// ntp 관련 전역변수 초기화, timekeeper, shadow_timekeeper의 맴버값 초기화 수행
time_init();
- call: start_kernel()->time_init()
asmlinkage void __init start_kernel(void)
{
...
early_irq_init();
// irq_desc 0 ~ 15 까지의 object을 할당 받고 초기화를 수행
// allocated_irqs에 bit를 1로 세팅하고 radix tree에 각 irq_desc를 노트로 추가
init_IRQ();
// gic, combiner이 사용할 메모리 할당과 자료 구조 설정,
// gic irq (0~15), combiner irq (32~63) interrupt 를 enable 시킴
tick_init();
// tick 관련 mask 변수를 0으로 초기화 수행
init_timers();
// boot_tvec_bases의 맴버 값을 초기화하고 timers_nb를 cpu_notifier 에 등록,
// softirq_vec[1] 에 run_timer_softirq 등록하여 초기화 수행
hrtimers_init();
// hrtimer_bases의 맴버 값을 초기화하고 hrtimers_nb를 cpu_notifier 에 등록,
// softirq_vec[8] 에 run_hrtimer_softirq 등록하여 초기화 수행
softirq_init();
// tasklet_vec, tasklet_hi_vec 맴버 값을 초기화하고,
// softirq_vec[6]에 tasklet_action, softirq_vec[0]에 tasklet_hi_action 등록하여 초기화 수행
timekeeping_init();
// ntp 관련 전역변수 초기화, timekeeper, shadow_timekeeper의 맴버값 초기화 수행
time_init();
time_init()->of_clk_init(NULL)
- called: start_kernel()->time_init()
// ARM10C 20150103
void __init time_init(void)
{
// machine_desc->init_time: __mach_desc_EXYNOS5_DT.init_time: NULL
if (machine_desc->init_time) {
machine_desc->init_time();
} else {
#ifdef CONFIG_COMMON_CLK // CONFIG_COMMON_CLK=y
of_clk_init(NULL);
#endif
- call: start_kernel()->time_init()->of_clk_init()
// ARM10C 20150103
void __init time_init(void)
{
// machine_desc->init_time: __mach_desc_EXYNOS5_DT.init_time: NULL
if (machine_desc->init_time) {
machine_desc->init_time();
} else {
#ifdef CONFIG_COMMON_CLK // CONFIG_COMMON_CLK=y
of_clk_init(NULL);
#endif
of_clk_init()->clk_init_cb(np)
- call: start_kernel()->time_init()->of_clk_init()
const struct of_device_id *match;
struct device_node *np;
// matches: NULL
if (!matches)
// __clk_of_table:
// __clk_of_table_fixed_factor_clk
// __clk_of_table_fixed_clk
// __clk_of_table_exynos4210_audss_clk
// __clk_of_table_exynos5250_audss_clk
// __clk_of_table_exynos5420_clk
matches = __clk_of_table;
// matches:
// __clk_of_table_fixed_factor_clk
// __clk_of_table_fixed_clk
// __clk_of_table_exynos4210_audss_clk
// __clk_of_table_exynos5250_audss_clk
// __clk_of_table_exynos5420_clk
for_each_matching_node_and_match(np, matches, &match) {
// for (np = of_find_matching_node_and_match(NULL, matches, &match);
// np; np = of_find_matching_node_and_match(np, matches, &match))
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, match: __clk_of_table_exynos5420_clk
// match->data: __clk_of_table_exynos5420_clk.data: exynos5420_clk_init
of_clk_init_cb_t clk_init_cb = match->data;
// clk_init_cb: exynos5420_clk_init
// clk_init_cb: exynos5420_clk_init,
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
// exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
clk_init_cb(np);
- call: start_kernel()->time_init()->of_clk_init()->exynos5420_clk_init()
- // clk_init_cb: exynos5420_clk_init,
- // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- clk_init_cb(np);
const struct of_device_id *match;
struct device_node *np;
// matches: NULL
if (!matches)
// __clk_of_table:
// __clk_of_table_fixed_factor_clk
// __clk_of_table_fixed_clk
// __clk_of_table_exynos4210_audss_clk
// __clk_of_table_exynos5250_audss_clk
// __clk_of_table_exynos5420_clk
matches = __clk_of_table;
// matches:
// __clk_of_table_fixed_factor_clk
// __clk_of_table_fixed_clk
// __clk_of_table_exynos4210_audss_clk
// __clk_of_table_exynos5250_audss_clk
// __clk_of_table_exynos5420_clk
for_each_matching_node_and_match(np, matches, &match) {
// for (np = of_find_matching_node_and_match(NULL, matches, &match);
// np; np = of_find_matching_node_and_match(np, matches, &match))
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, match: __clk_of_table_exynos5420_clk
// match->data: __clk_of_table_exynos5420_clk.data: exynos5420_clk_init
of_clk_init_cb_t clk_init_cb = match->data;
// clk_init_cb: exynos5420_clk_init
// clk_init_cb: exynos5420_clk_init,
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
// exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
clk_init_cb(np);
- // clk_init_cb: exynos5420_clk_init,
- // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- clk_init_cb(np);
exynos5420_clk_init()
- called: start_kernel()->time_init()->of_clk_init()->exynos5420_clk_init()
- // clk_init_cb: exynos5420_clk_init,
- // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- clk_init_cb(np);
// ARM10C 20150103
typedef void (*of_clk_init_cb_t)(struct device_node *);
/* register exynos5420 clocks */
// ARM10C 20150103
// devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
static void __init exynos5420_clk_init(struct device_node *np)
{
void __iomem *reg_base;
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
if (np) {
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
// of_iomap(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, 0): 0xf0040000
reg_base = of_iomap(np, 0);
// reg_base: 0xf0040000
-
of_iomap에서 한일:
- // device tree 있는 clock node에서 node의 resource 값을 가져옴
- // of_address_to_resource에서 한일(index: 0):
- // (&res)->start: 0x10010000
- // (&res)->end: 0x1003ffff
- // (&res)->flags: IORESOURCE_MEM: 0x00000200
- // (&res)->name: "/clock-controller@10010000"
- /*
-
// alloc area (CLK) 를 만들고 rb tree에 alloc area 를 추가
-
// 가상주소 va_start 기준으로 CLK 를 RB Tree 추가한 결과
// CHID-b
// (0xF8000000)
// / \
// TMR-b PMU-b
// (0xF6300000) (0xF8180000)
// / \ / \
// GIC#1-r WDT-b CMU-b SRAM-b
// (0xF0002000) (0xF6400000) (0xF8100000) (0xF8400000)
// / \ \
// GIC#0-b CLK-b ROMC-r
// (0xF0000000) (0xF0040000) (0xF84C0000)
// / \
// COMB-r SYSC-r
// (0xF0004000) (0xF6100000)
//
- // vmap_area_list에 GIC#0 - GIC#1 - COMB - CLK - SYSC -TMR - WDT - CHID - CMU - PMU - SRAM - ROMC
- // 순서로 리스트에 연결이 됨
- //
- // (kmem_cache#30-oX (vm_struct))->flags: GFP_KERNEL: 0xD0
- // (kmem_cache#30-oX (vm_struct))->addr: 0xf0040000
- // (kmem_cache#30-oX (vm_struct))->size: 0x31000
- // (kmem_cache#30-oX (vm_struct))->caller: __builtin_return_address(0)
- //
- // (kmem_cache#30-oX (vmap_area CLK))->vm: kmem_cache#30-oX (vm_struct)
- // (kmem_cache#30-oX (vmap_area CLK))->flags: 0x04
- */
- // device tree 있는 clock node에서 node의 resource 값을 pgtable에 매핑함
- // 0xc0004780이 가리키는 pte의 시작주소에 0x10010653 값을 갱신
- // (linux pgtable과 hardware pgtable의 값 같이 갱신)
// pgd pte
// | |
// +--------------+
// | | +--------------+ +0
// | | | 0xXXXXXXXX | ---> 0x10010653 에 매칭되는 linux pgtable 값
// +- - - - - - - + | Linux pt 0 |
// | | +--------------+ +1024
// | | | |
// +--------------+ +0 | Linux pt 1 |
// | *(c0004780) |-----> +--------------+ +2048
// | | | 0x10010653 | ---> 2308
// +- - - - - - - + +4 | h/w pt 0 |
// | *(c0004784) |-----> +--------------+ +3072
// | | + +
// +--------------+ +8 | h/w pt 1 |
// | | +--------------+ +4096
- // cache의 값을 전부 메모리에 반영
- samsung_clk_init()
static void __init exynos5420_clk_init(struct device_node *np)
{
if (np) {
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
// of_iomap(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, 0): 0xf0040000
reg_base = of_iomap(np, 0);
// reg_base: 0xf0040000
// reg_base: 0xf0040000
if (!reg_base)
panic("%s: failed to map registers\n", __func__);
} else {
panic("%s: unable to determine soc\n", __func__);
}
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, reg_base: 0xf0040000, nr_clks: 769
// ARRAY_SIZE(exynos5420_clk_regs): 59
samsung_clk_init(np, reg_base, nr_clks,
exynos5420_clk_regs, ARRAY_SIZE(exynos5420_clk_regs),
NULL, 0);
-
samsung_clk_init() 에서 한일:
- // struct samsung_clk_reg_dump를 59개 만큼 메모리를 할당 받아
- // exynos5420_clk_regs의 값으로 맴버값 세팅
- // (kmem_cache#26-oX)[0...58].offset: exynos5420_clk_regs[0...58]
- //
- // syscore_ops_list의 tail에 (&samsung_clk_syscore_ops)->node 를 추가
- //
- // struct clk * 를 769개 만큼 메모리를 clk_table에 할당 받음
- // clk_table: kmem_cache#23-o0
- //
- // clk_data.clks: kmem_cache#23-o0 (clk_table)
- // clk_data.clk_num: 769
- //
- // struct of_clk_provider 의 메모리(kmem_cache#30-oX)를 할당 받고 맴버값 초기화 수행
- //
- // (kmem_cache#30-oX)->node: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // (kmem_cache#30-oX)->data: &clk_data
- // (kmem_cache#30-oX)->get: of_clk_src_onecell_get
- //
- // list인 of_clk_providers의 head에 (kmem_cache#30-oX)->link를 추가
-
samsung_clk_of_register_fixed_ext()
static void __init exynos5420_clk_init(struct device_node *np)
{
if (np) {
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
// of_iomap(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, 0): 0xf0040000
reg_base = of_iomap(np, 0);
// reg_base: 0xf0040000
// reg_base: 0xf0040000
if (!reg_base)
panic("%s: failed to map registers\n", __func__);
} else {
panic("%s: unable to determine soc\n", __func__);
}
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, reg_base: 0xf0040000, nr_clks: 769
// ARRAY_SIZE(exynos5420_clk_regs): 59
samsung_clk_init(np, reg_base, nr_clks,
exynos5420_clk_regs, ARRAY_SIZE(exynos5420_clk_regs),
NULL, 0);
// ARRAY_SIZE(exynos5420_fixed_rate_ext_clks): 1
samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,
ARRAY_SIZE(exynos5420_fixed_rate_ext_clks),
ext_clk_match);
-
samsung_clk_of_register_fixed_ext() 에서 한일:
- // devtree에서 allnext로 순회 하면서 찾은 fixed-rate-clocks node 에서
- // fixed-rate-clocks node에서 "clock-frequency" property값을 freq에 읽어옴
- // freq: 24000000
- // exynos5420_fixed_rate_ext_clks[0].fixed_rate: 24000000
- //
- // struct clk_fixed_rate 만큼 메모리를 kmem_cache#30-oX 할당 받고 struct clk_fixed_rate 의 멤버 값을 아래와 같이 초기화 수행
- //
- // (kmem_cache#30-oX)->fixed_rate: 24000000
- // (kmem_cache#30-oX)->hw.init: &init
- // (&(kmem_cache#30-oX)->hw)->clk: kmem_cache#29-oX
- //
- // struct clk 만큼 메모리를 kmem_cache#29-oX 할당 받고 struct clk 의 멤버 값을 아래와 같이 초기화 수행
- //
- // (kmem_cache#29-oX)->name: kmem_cache#30-oX ("fin_pll")
- // (kmem_cache#29-oX)->ops: &clk_fixed_rate_ops
- // (kmem_cache#29-oX)->hw: &(kmem_cache#30-oX)->hw
- // (kmem_cache#29-oX)->flags: 0x30
- // (kmem_cache#29-oX)->num_parents: 0
- // (kmem_cache#29-oX)->parent_names: ((void *)16)
- // (kmem_cache#29-oX)->parent: NULL
- // (kmem_cache#29-oX)->rate: 24000000
- //
- // (&(kmem_cache#29-oX)->child_node)->next: NULL
- // (&(kmem_cache#29-oX)->child_node)->pprev: &(&(kmem_cache#29-oX)->child_node)
- //
- // (&clk_root_list)->first: &(kmem_cache#29-oX)->child_node
- //
- // clk_table[1]: (kmem_cache#23-o0)[1]: kmem_cache#29-oX
- //
- // struct clk_lookup_alloc 의 메모리를 kmem_cache#30-oX 할당 받고
- // struct clk_lookup_alloc 맴버값 초기화 수행
- //
- // (kmem_cache#30-oX)->cl.clk: kmem_cache#29-oX
- // (kmem_cache#30-oX)->con_id: "fin_pll"
- // (kmem_cache#30-oX)->cl.con_id: (kmem_cache#30-oX)->con_id: "fin_pll"
- //
- // list clocks에 &(&(kmem_cache#30-oX)->cl)->nade를 tail로 추가
-
samsung_clk_register_pll()
static void __init exynos5420_clk_init(struct device_node *np)
{
if (np) {
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
// of_iomap(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, 0): 0xf0040000
reg_base = of_iomap(np, 0);
// reg_base: 0xf0040000
// reg_base: 0xf0040000
if (!reg_base)
panic("%s: failed to map registers\n", __func__);
} else {
panic("%s: unable to determine soc\n", __func__);
}
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, reg_base: 0xf0040000, nr_clks: 769
// ARRAY_SIZE(exynos5420_clk_regs): 59
samsung_clk_init(np, reg_base, nr_clks,
exynos5420_clk_regs, ARRAY_SIZE(exynos5420_clk_regs),
NULL, 0);
// ARRAY_SIZE(exynos5420_fixed_rate_ext_clks): 1
samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,
ARRAY_SIZE(exynos5420_fixed_rate_ext_clks),
ext_clk_match);
// ARRAY_SIZE(exynos5420_plls): 11, reg_base: 0xf0040000
samsung_clk_register_pll(exynos5420_plls, ARRAY_SIZE(exynos5420_plls),
reg_base);
-
samsung_clk_register_pll() 에서 한일:
- // exynos5420_plls에 정의되어 있는 PLL 값들을 초기화 수행
- //
- // [apll] 의 초기화 값 수행 결과:
- // struct clk_fixed_rate 만큼 메모리를 kmem_cache#30-oX (apll) 할당 받고 struct clk_fixed_rate 의 멤버 값을 아래와 같이 초기화 수행
- // pll: kmem_cache#30-oX (apll)
- //
- // (kmem_cache#30-oX (apll))->hw.init: &init
- // (kmem_cache#30-oX (apll))->type: pll_2550: 2
- // (kmem_cache#30-oX (apll))->lock_reg: 0xf0040000
- // (kmem_cache#30-oX (apll))->con_reg: 0xf0040100
- //
- // struct clk 만큼 메모리를 kmem_cache#29-oX (apll) 할당 받고 struct clk 의 멤버 값을 아래와 같이 초기화 수행
- //
- // (kmem_cache#29-oX (apll))->name: kmem_cache#30-oX ("fout_apll")
- // (kmem_cache#29-oX (apll))->ops: &samsung_pll35xx_clk_min_ops
- // (kmem_cache#29-oX (apll))->hw: &(kmem_cache#30-oX (apll))->hw
- // (kmem_cache#29-oX (apll))->flags: 0x40
- // (kmem_cache#29-oX (apll))->num_parents: 1
- // (kmem_cache#29-oX (apll))->parent_names: kmem_cache#30-oX
- // (kmem_cache#29-oX (apll))->parent_names[0]: (kmem_cache#30-oX)[0]: kmem_cache#30-oX: "fin_pll"
- // (kmem_cache#29-oX (apll))->parent: kmem_cache#29-oX (fin_pll)
- // (kmem_cache#29-oX (apll))->rate: 1000000000 (1 Ghz)
- //
- // (&(kmem_cache#29-oX (apll))->child_node)->next: NULL
- // (&(kmem_cache#29-oX (apll))->child_node)->pprev: &(&(kmem_cache#29-oX (apll))->child_node)
- //
- // (&(kmem_cache#29-oX (fin_pll))->children)->first: &(kmem_cache#29-oX (apll))->child_node
- //
- // (&(kmem_cache#30-oX (apll))->hw)->clk: kmem_cache#29-oX (apll)
- //
- // clk_table[2]: (kmem_cache#23-o0)[2]: kmem_cache#29-oX (apll)
- //
- // struct clk_lookup_alloc 의 메모리를 kmem_cache#30-oX (apll) 할당 받고
- // struct clk_lookup_alloc 맴버값 초기화 수행
- //
- // (kmem_cache#30-oX)->cl.clk: kmem_cache#29-oX (apll)
- // (kmem_cache#30-oX)->con_id: "fout_apll"
- // (kmem_cache#30-oX)->cl.con_id: (kmem_cache#30-oX)->con_id: "fout_apll"
- //
- // list clocks에 &(&(kmem_cache#30-oX (apll))->cl)->nade를 tail로 추가
- //
- // cpll, dpll, epll, rpll, ipll, spll, vpll, mpll, bpll, kpll 초기화 수행 결과는 생략.
-
samsung_clk_register_fixed_rate()
static void __init exynos5420_clk_init(struct device_node *np)
{
if (np) {
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
// of_iomap(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, 0): 0xf0040000
reg_base = of_iomap(np, 0);
// reg_base: 0xf0040000
// reg_base: 0xf0040000
if (!reg_base)
panic("%s: failed to map registers\n", __func__);
} else {
panic("%s: unable to determine soc\n", __func__);
}
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, reg_base: 0xf0040000, nr_clks: 769
// ARRAY_SIZE(exynos5420_clk_regs): 59
samsung_clk_init(np, reg_base, nr_clks,
exynos5420_clk_regs, ARRAY_SIZE(exynos5420_clk_regs),
NULL, 0);
// ARRAY_SIZE(exynos5420_fixed_rate_ext_clks): 1
samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,
ARRAY_SIZE(exynos5420_fixed_rate_ext_clks),
ext_clk_match);
// ARRAY_SIZE(exynos5420_plls): 11, reg_base: 0xf0040000
samsung_clk_register_pll(exynos5420_plls, ARRAY_SIZE(exynos5420_plls),
reg_base);
// ARRAY_SIZE(exynos5420_fixed_rate_clks): 5
samsung_clk_register_fixed_rate(exynos5420_fixed_rate_clks,
ARRAY_SIZE(exynos5420_fixed_rate_clks));
-
samsung_clk_register_fixed_rate() 에서 한일:
- // exynos5420_fixed_rate_clks에 정의되어 있는 fixed rate 값들을 초기화 수행
- //
- // sclk_hdmiphy 의 초기화 값 수행 결과
- // struct clk_fixed_rate 만큼 메모리를 kmem_cache#30-oX 할당 받고 struct clk_fixed_rate 의 멤버 값을 아래와 같이 초기화 수행
- //
- // (kmem_cache#30-oX)->fixed_rate: 24000000
- // (kmem_cache#30-oX)->hw.init: &init
- // (&(kmem_cache#30-oX)->hw)->clk: kmem_cache#29-oX
- //
- // struct clk 만큼 메모리를 kmem_cache#29-oX 할당 받고 struct clk 의 멤버 값을 아래와 같이 초기화 수행
- //
- // (kmem_cache#29-oX)->name: kmem_cache#30-oX ("sclk_hdmiphy")
- // (kmem_cache#29-oX)->ops: &clk_fixed_rate_ops
- // (kmem_cache#29-oX)->hw: &(kmem_cache#30-oX)->hw
- // (kmem_cache#29-oX)->flags: 0x30
- // (kmem_cache#29-oX)->num_parents: 0
- // (kmem_cache#29-oX)->parent_names: ((void *)16)
- // (kmem_cache#29-oX)->parent: NULL
- // (kmem_cache#29-oX)->rate: 24000000
- //
- // (&(kmem_cache#29-oX)->child_node)->next: NULL
- // (&(kmem_cache#29-oX)->child_node)->pprev: &(&(kmem_cache#29-oX)->child_node)
- //
- // (&clk_root_list)->first: &(kmem_cache#29-oX)->child_node
- //
- // clk_table[158]: (kmem_cache#23-o0)[158]: kmem_cache#29-oX
- //
- // struct clk_lookup_alloc 의 메모리를 kmem_cache#30-oX 할당 받고
- // struct clk_lookup_alloc 맴버값 초기화 수행
- //
- // (kmem_cache#30-oX)->cl.clk: kmem_cache#29-oX
- // (kmem_cache#30-oX)->con_id: "fin_pll"
- // (kmem_cache#30-oX)->cl.con_id: (kmem_cache#30-oX)->con_id: "fin_pll"
- //
- // list clocks에 &(&(kmem_cache#30-oX)->cl)->nade를 tail로 추가
- //
- // "sclk_pwi", "sclk_usbh20", "mphy_refclk_ixtal24", "sclk_usbh20_scan_clk" 초기화 수행 결과는 생략.
-
samsung_clk_register_fixed_factor()
static void __init exynos5420_clk_init(struct device_node *np)
{
if (np) {
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
// of_iomap(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, 0): 0xf0040000
reg_base = of_iomap(np, 0);
// reg_base: 0xf0040000
// reg_base: 0xf0040000
if (!reg_base)
panic("%s: failed to map registers\n", __func__);
} else {
panic("%s: unable to determine soc\n", __func__);
}
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, reg_base: 0xf0040000, nr_clks: 769
// ARRAY_SIZE(exynos5420_clk_regs): 59
samsung_clk_init(np, reg_base, nr_clks,
exynos5420_clk_regs, ARRAY_SIZE(exynos5420_clk_regs),
NULL, 0);
// ARRAY_SIZE(exynos5420_fixed_rate_ext_clks): 1
samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,
ARRAY_SIZE(exynos5420_fixed_rate_ext_clks),
ext_clk_match);
// ARRAY_SIZE(exynos5420_plls): 11, reg_base: 0xf0040000
samsung_clk_register_pll(exynos5420_plls, ARRAY_SIZE(exynos5420_plls),
reg_base);
// ARRAY_SIZE(exynos5420_fixed_rate_clks): 5
samsung_clk_register_fixed_rate(exynos5420_fixed_rate_clks,
ARRAY_SIZE(exynos5420_fixed_rate_clks));
// ARRAY_SIZE(exynos5420_fixed_factor_clks): 1
samsung_clk_register_fixed_factor(exynos5420_fixed_factor_clks,
ARRAY_SIZE(exynos5420_fixed_factor_clks));
- samsung_clk_register_fixed_factor() 에서 한일:
- // struct clk_fixed_factor 만큼 메모리를 kmem_cache#30-oX 할당 받고 struct clk_fixed_factor 의 멤버 값을 아래와 같이 초기화 수행
- //
- // (kmem_cache#30-oX)->mult: 1
- // (kmem_cache#30-oX)->div: 2
- // (kmem_cache#30-oX)->hw.init: &init
- //
- // struct clk 만큼 메모리를 kmem_cache#29-oX (sclk_hsic_12m) 할당 받고 struct clk 의 멤버 값을 아래와 같이 초기화 수행
- //
- // (kmem_cache#29-oX (sclk_hsic_12m))->name: kmem_cache#30-oX ("sclk_hsic_12m")
- // (kmem_cache#29-oX (sclk_hsic_12m))->ops: &clk_fixed_factor_ops
- // (kmem_cache#29-oX (sclk_hsic_12m))->hw: &(kmem_cache#30-oX (sclk_hsic_12m))->hw
- // (kmem_cache#29-oX (sclk_hsic_12m))->flags: 0x20
- // (kmem_cache#29-oX (sclk_hsic_12m))->num_parents: 1
- // (kmem_cache#29-oX (sclk_hsic_12m))->parent_names: kmem_cache#30-oX
- // (kmem_cache#29-oX (sclk_hsic_12m))->parent_names[0]: (kmem_cache#30-oX)[0]: kmem_cache#30-oX: "fin_pll"
- // (kmem_cache#29-oX (sclk_hsic_12m))->parent: kmem_cache#29-oX (fin_pll)
- // (kmem_cache#29-oX (sclk_hsic_12m))->rate: 12000000
- //
- // (&(kmem_cache#29-oX (sclk_hsic_12m))->child_node)->next: NULL
- // (&(kmem_cache#29-oX (sclk_hsic_12m))->child_node)->pprev: &(&(kmem_cache#29-oX (sclk_hsic_12m))->child_node)
- //
- // (&(kmem_cache#29-oX (fin_pll))->children)->first: &(kmem_cache#29-oX (sclk_hsic_12m))->child_node
- //
- // (&(kmem_cache#30-oX (sclk_hsic_12m))->hw)->clk: kmem_cache#29-oX (sclk_hsic_12m)
- //
- // clk_table[0]: (kmem_cache#23-o0)[0]: kmem_cache#29-oX (sclk_hsic_12m)
* samsung_clk_register_mux()
```clk-exynos5420.c
static void __init exynos5420_clk_init(struct device_node *np)
{
if (np) {
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
// of_iomap(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, 0): 0xf0040000
reg_base = of_iomap(np, 0);
// reg_base: 0xf0040000
// reg_base: 0xf0040000
if (!reg_base)
panic("%s: failed to map registers\n", __func__);
} else {
panic("%s: unable to determine soc\n", __func__);
}
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, reg_base: 0xf0040000, nr_clks: 769
// ARRAY_SIZE(exynos5420_clk_regs): 59
samsung_clk_init(np, reg_base, nr_clks,
exynos5420_clk_regs, ARRAY_SIZE(exynos5420_clk_regs),
NULL, 0);
// ARRAY_SIZE(exynos5420_fixed_rate_ext_clks): 1
samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,
ARRAY_SIZE(exynos5420_fixed_rate_ext_clks),
ext_clk_match);
// ARRAY_SIZE(exynos5420_plls): 11, reg_base: 0xf0040000
samsung_clk_register_pll(exynos5420_plls, ARRAY_SIZE(exynos5420_plls),
reg_base);
// ARRAY_SIZE(exynos5420_fixed_rate_clks): 5
samsung_clk_register_fixed_rate(exynos5420_fixed_rate_clks,
ARRAY_SIZE(exynos5420_fixed_rate_clks));
// ARRAY_SIZE(exynos5420_fixed_factor_clks): 1
samsung_clk_register_fixed_factor(exynos5420_fixed_factor_clks,
ARRAY_SIZE(exynos5420_fixed_factor_clks));
// ARRAY_SIZE(exynos5420_mux_clks): 85
samsung_clk_register_mux(exynos5420_mux_clks,
ARRAY_SIZE(exynos5420_mux_clks));
-
samsung_clk_register_mux() 에서 한일:
- // mout_mspll_kfc, sclk_spll를 수행한 결과:
- //
- // (mout_mspll_kfc) 에서 한일:
- // struct clk_mux 만큼 메모리를 kmem_cache#30-oX (mout_mspll_kfc) 할당 받고 struct clk_mux 의 멤버 값을 아래와 같이 초기화 수행
- //
- // (kmem_cache#30-oX)->reg: 0xf005021c
- // (kmem_cache#30-oX)->shift: 8
- // (kmem_cache#30-oX)->mask: 0x3
- // (kmem_cache#30-oX)->flags: 0
- // (kmem_cache#30-oX)->lock: &lock
- // (kmem_cache#30-oX)->table: NULL
- // (kmem_cache#30-oX)->hw.init: &init
- //
- // struct clk 만큼 메모리를 kmem_cache#29-oX (mout_mspll_kfc) 할당 받고 struct clk 의 멤버 값을 아래와 같이 초기화 수행
- //
- // (kmem_cache#29-oX (mout_mspll_kfc))->name: kmem_cache#30-oX ("mout_mspll_kfc")
- // (kmem_cache#29-oX (mout_mspll_kfc))->ops: &clk_mux_ops
- // (kmem_cache#29-oX (mout_mspll_kfc))->hw: &(kmem_cache#30-oX (mout_mspll_kfc))->hw
- // (kmem_cache#29-oX (mout_mspll_kfc))->flags: 0xa0
- // (kmem_cache#29-oX (mout_mspll_kfc))->num_parents 4
- // (kmem_cache#29-oX (mout_mspll_kfc))->parent_names: kmem_cache#30-oX
- // (kmem_cache#29-oX (mout_mspll_kfc))->parent_names[0]: (kmem_cache#30-oX)[0]: kmem_cache#30-oX: "sclk_cpll"
- // (kmem_cache#29-oX (mout_mspll_kfc))->parent_names[1]: (kmem_cache#30-oX)[1]: kmem_cache#30-oX: "sclk_dpll"
- // (kmem_cache#29-oX (mout_mspll_kfc))->parent_names[2]: (kmem_cache#30-oX)[2]: kmem_cache#30-oX: "sclk_mpll"
- // (kmem_cache#29-oX (mout_mspll_kfc))->parent_names[3]: (kmem_cache#30-oX)[3]: kmem_cache#30-oX: "sclk_spll"
- // (kmem_cache#29-oX (mout_mspll_kfc))->parent: NULL
- // (kmem_cache#29-oX (mout_mspll_kfc))->rate: 0
- //
- // (kmem_cache#29-oX (mout_mspll_kfc))->parents: kmem_cache#30-oX
- // (kmem_cache#29-oX (mout_mspll_kfc))->parents[0...3]: (kmem_cache#30-oX)[0...3]: NULL
- //
- // (&(kmem_cache#29-oX (mout_mspll_kfc))->child_node)->next: NULL
- // (&(kmem_cache#29-oX (mout_mspll_kfc))->child_node)->pprev: &(&(kmem_cache#29-oX (mout_mspll_kfc))->child_node)
- //
- // (&clk_orphan_list)->first: &(kmem_cache#29-oX (mout_mspll_kfc))->child_node
- //
- // (&(kmem_cache#30-oX (mout_mspll_kfc))->hw)->clk: kmem_cache#29-oX (mout_mspll_kfc)
- // (sclk_spll) 에서 한일:
- // struct clk_mux 만큼 메모리를 kmem_cache#30-oX (sclk_spll) 할당 받고 struct clk_mux 의 멤버 값을 아래와 같이 초기화 수행
- //
- // (kmem_cache#30-oX)->reg: 0xf0050218
- // (kmem_cache#30-oX)->shift: 8
- // (kmem_cache#30-oX)->mask: 0x3
- // (kmem_cache#30-oX)->flags: 0
- // (kmem_cache#30-oX)->lock: &lock
- // (kmem_cache#30-oX)->table: NULL
- // (kmem_cache#30-oX)->hw.init: &init
- //
- // struct clk 만큼 메모리를 kmem_cache#29-oX (sclk_spll) 할당 받고 struct clk 의 멤버 값을 아래와 같이 초기화 수행
- //
- // (kmem_cache#29-oX (sclk_spll))->name: kmem_cache#30-oX ("sclk_spll")
- // (kmem_cache#29-oX (sclk_spll))->ops: &clk_mux_ops
- // (kmem_cache#29-oX (sclk_spll))->hw: &(kmem_cache#30-oX (sclk_spll))->hw
- // (kmem_cache#29-oX (sclk_spll))->flags: 0xa0
- // (kmem_cache#29-oX (sclk_spll))->num_parents 2
- // (kmem_cache#29-oX (sclk_spll))->parent_names: kmem_cache#30-oX
- // (kmem_cache#29-oX (sclk_spll))->parent_names[0]: (kmem_cache#30-oX)[0]: kmem_cache#30-oX: "fin_pll"
- // (kmem_cache#29-oX (sclk_spll))->parent_names[1]: (kmem_cache#30-oX)[1]: kmem_cache#30-oX: "fout_spll"
- // (kmem_cache#29-oX (sclk_spll))->parent: NULL
- // (kmem_cache#29-oX (sclk_spll))->rate: 600000000
- //
- // (kmem_cache#29-oX (sclk_spll))->parents: kmem_cache#30-oX
- // (kmem_cache#29-oX (sclk_spll))->parents[0]: (kmem_cache#30-oX)[0]: kmem_cache#29-oX (fin_pll)
- // (kmem_cache#29-oX (sclk_spll))->parents[1]: (kmem_cache#30-oX)[1]: kmem_cache#29-oX (fout_spll)
- //
- // parents 인 "fin_pll", "fout_spll" 값들 중에
- // register CLK_SRC_TOP6 의 값을 읽어서 mux 할 parent clock 을 선택함
- // return된 값이 선택된 parent clock의 index 값임
- // parent clock 중에 선택된 parent clock의 이름으로 등록된 clk struct를 반환함
- //
- // (&(kmem_cache#29-oX (sclk_spll))->child_node)->next: NULL
- // (&(kmem_cache#29-oX (sclk_spll))->child_node)->pprev: &(&(kmem_cache#29-oX (sclk_spll))->child_node)
- //
- // (&(kmem_cache#29-oX (fout_spll))->children)->first: &(kmem_cache#29-oX (sclk_spll))->child_node
- //
- // (&(kmem_cache#30-oX (sclk_spll))->hw)->clk: kmem_cache#29-oX (sclk_spll)
- //
- // orphan 으로 등록된 mout_mspll_kfc의 값을 갱신
- // (&(kmem_cache#29-oX (mout_mspll_kfc))->child_node)->next: NULL
- // (&(kmem_cache#29-oX (mout_mspll_kfc))->child_node)->pprev: &(&(kmem_cache#29-oX (mout_mspll_kfc))->child_node)
- //
- // (&(kmem_cache#29-oX (sclk_spll))->children)->first: &(kmem_cache#29-oX (mout_mspll_kfc))->child_node
- //
- // (kmem_cache#29-oX (mout_mspll_kfc))->parent: kmem_cache#29-oX (sclk_spll)
- //
- // parent가 있는지 확인후 parent의 clock rate 값으로 clock rate 값을 세팅
- // (kmem_cache#29-oX (mout_mspll_kfc))->rate: 600000000
-
samsung_clk_register_div()
static void __init exynos5420_clk_init(struct device_node *np)
{
if (np) {
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
// of_iomap(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, 0): 0xf0040000
reg_base = of_iomap(np, 0);
// reg_base: 0xf0040000
// reg_base: 0xf0040000
if (!reg_base)
panic("%s: failed to map registers\n", __func__);
} else {
panic("%s: unable to determine soc\n", __func__);
}
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, reg_base: 0xf0040000, nr_clks: 769
// ARRAY_SIZE(exynos5420_clk_regs): 59
samsung_clk_init(np, reg_base, nr_clks,
exynos5420_clk_regs, ARRAY_SIZE(exynos5420_clk_regs),
NULL, 0);
// ARRAY_SIZE(exynos5420_fixed_rate_ext_clks): 1
samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,
ARRAY_SIZE(exynos5420_fixed_rate_ext_clks),
ext_clk_match);
// ARRAY_SIZE(exynos5420_plls): 11, reg_base: 0xf0040000
samsung_clk_register_pll(exynos5420_plls, ARRAY_SIZE(exynos5420_plls),
reg_base);
// ARRAY_SIZE(exynos5420_fixed_rate_clks): 5
samsung_clk_register_fixed_rate(exynos5420_fixed_rate_clks,
ARRAY_SIZE(exynos5420_fixed_rate_clks));
// ARRAY_SIZE(exynos5420_fixed_factor_clks): 1
samsung_clk_register_fixed_factor(exynos5420_fixed_factor_clks,
ARRAY_SIZE(exynos5420_fixed_factor_clks));
// ARRAY_SIZE(exynos5420_mux_clks): 85
samsung_clk_register_mux(exynos5420_mux_clks,
ARRAY_SIZE(exynos5420_mux_clks));
// ARRAY_SIZE(exynos5420_div_clks): 53
samsung_clk_register_div(exynos5420_div_clks,
ARRAY_SIZE(exynos5420_div_clks));
-
samsung_clk_register_div() 에서 한일:
- // exynos5420_div_clks의 div 들 중에 array index 1번의
- // DIV(none, "sclk_apll", "mout_apll", DIV_CPU0, 24, 3) 을 가지고 분석 진행
- //
- // struct clk_divider 만큼 메모리를 할당 받아 맴버값 초기화 수행
- // kmem_cache#30-oX (sclk_apll)
- // (kmem_cache#30-oX (sclk_apll))->reg: 0xf0040500
- // (kmem_cache#30-oX (sclk_apll))->shift: 24
- // (kmem_cache#30-oX (sclk_apll))->width: 3
- // (kmem_cache#30-oX (sclk_apll))->flags: 0
- // (kmem_cache#30-oX (sclk_apll))->lock: &lock
- // (kmem_cache#30-oX (sclk_apll))->hw.init: &init
- // (kmem_cache#30-oX (sclk_apll))->table: NULL
- //
- // struct clk 만큼 메모리를 할당 받아 맴버값 초기화 수행
- // kmem_cache#29-oX (sclk_apll)
- // (kmem_cache#29-oX (sclk_apll))->name: kmem_cache#30-oX ("sclk_apll")
- // (kmem_cache#29-oX (sclk_apll))->ops: &clk_divider_ops
- // (kmem_cache#29-oX (sclk_apll))->hw: &(kmem_cache#30-oX (sclk_apll))->hw
- // (kmem_cache#29-oX (sclk_apll))->flags: 0x0
- // (kmem_cache#29-oX (sclk_apll))->num_parents 1
- // (kmem_cache#29-oX (sclk_apll))->parent_names[0]: (kmem_cache#30-oX)[0]: kmem_cache#30-oX: "mout_apll"
- // (kmem_cache#29-oX (sclk_apll))->parent: kmem_cache#29-oX (mout_apll)
- // (kmem_cache#29-oX (sclk_apll))->rate: 800000000
- //
- // clk 의 이름이 "mout_apll"인 메모리 값을 clk_root_list 에서 찾아 리턴 수행
- //
- // (&(kmem_cache#29-oX (sclk_apll))->child_node)->next: NULL
- // (&(kmem_cache#29-oX (sclk_apll))->child_node)->pprev: &(&(kmem_cache#29-oX (sclk_apll))->child_node)
- //
- // (&(kmem_cache#29-oX (mout_apll))->children)->first: &(kmem_cache#29-oX (sclk_apll))->child_node
- //
- // exynos5420_div_clks의 idx 0, 2...52 까지 loop 수행
-
samsung_clk_register_gate()
static void __init exynos5420_clk_init(struct device_node *np)
{
if (np) {
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
// of_iomap(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, 0): 0xf0040000
reg_base = of_iomap(np, 0);
// reg_base: 0xf0040000
// reg_base: 0xf0040000
if (!reg_base)
panic("%s: failed to map registers\n", __func__);
} else {
panic("%s: unable to determine soc\n", __func__);
}
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, reg_base: 0xf0040000, nr_clks: 769
// ARRAY_SIZE(exynos5420_clk_regs): 59
samsung_clk_init(np, reg_base, nr_clks,
exynos5420_clk_regs, ARRAY_SIZE(exynos5420_clk_regs),
NULL, 0);
// ARRAY_SIZE(exynos5420_fixed_rate_ext_clks): 1
samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,
ARRAY_SIZE(exynos5420_fixed_rate_ext_clks),
ext_clk_match);
// ARRAY_SIZE(exynos5420_plls): 11, reg_base: 0xf0040000
samsung_clk_register_pll(exynos5420_plls, ARRAY_SIZE(exynos5420_plls),
reg_base);
// ARRAY_SIZE(exynos5420_fixed_rate_clks): 5
samsung_clk_register_fixed_rate(exynos5420_fixed_rate_clks,
ARRAY_SIZE(exynos5420_fixed_rate_clks));
// ARRAY_SIZE(exynos5420_fixed_factor_clks): 1
samsung_clk_register_fixed_factor(exynos5420_fixed_factor_clks,
ARRAY_SIZE(exynos5420_fixed_factor_clks));
// ARRAY_SIZE(exynos5420_mux_clks): 85
samsung_clk_register_mux(exynos5420_mux_clks,
ARRAY_SIZE(exynos5420_mux_clks));
// ARRAY_SIZE(exynos5420_div_clks): 53
samsung_clk_register_div(exynos5420_div_clks,
ARRAY_SIZE(exynos5420_div_clks));
// ARRAY_SIZE(exynos5420_gate_clks): 136
samsung_clk_register_gate(exynos5420_gate_clks,
ARRAY_SIZE(exynos5420_gate_clks));
- call: start_kernel()->time_init()->of_clk_init()->exynos5420_clk_init()
- // clk_init_cb: exynos5420_clk_init,
- // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- clk_init_cb(np);
- reg_base = of_iomap(np, 0);
- samsung_clk_init()
- samsung_clk_of_register_fixed_ext()
- samsung_clk_register_pll()
- samsung_clk_register_fixed_rate()
- samsung_clk_register_fixed_factor()
- samsung_clk_register_mux()
- samsung_clk_register_div()
- samsung_clk_register_gate()
- // clk_init_cb: exynos5420_clk_init,
- // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- clk_init_cb(np);
// ARM10C 20150103
typedef void (*of_clk_init_cb_t)(struct device_node *);
/* register exynos5420 clocks */
// ARM10C 20150103
// devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
static void __init exynos5420_clk_init(struct device_node *np)
{
void __iomem *reg_base;
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
if (np) {
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
// of_iomap(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, 0): 0xf0040000
reg_base = of_iomap(np, 0);
// reg_base: 0xf0040000
of_iomap에서 한일:
- // device tree 있는 clock node에서 node의 resource 값을 가져옴
- // of_address_to_resource에서 한일(index: 0):
- // (&res)->start: 0x10010000
- // (&res)->end: 0x1003ffff
- // (&res)->flags: IORESOURCE_MEM: 0x00000200
- // (&res)->name: "/clock-controller@10010000"
- /*
- // alloc area (CLK) 를 만들고 rb tree에 alloc area 를 추가
- // 가상주소 va_start 기준으로 CLK 를 RB Tree 추가한 결과
// CHID-b
// (0xF8000000)
// / \
// TMR-b PMU-b
// (0xF6300000) (0xF8180000)
// / \ / \
// GIC#1-r WDT-b CMU-b SRAM-b
// (0xF0002000) (0xF6400000) (0xF8100000) (0xF8400000)
// / \ \
// GIC#0-b CLK-b ROMC-r
// (0xF0000000) (0xF0040000) (0xF84C0000)
// / \
// COMB-r SYSC-r
// (0xF0004000) (0xF6100000)
//
// pgd pte
// | |
// +--------------+
// | | +--------------+ +0
// | | | 0xXXXXXXXX | ---> 0x10010653 에 매칭되는 linux pgtable 값
// +- - - - - - - + | Linux pt 0 |
// | | +--------------+ +1024
// | | | |
// +--------------+ +0 | Linux pt 1 |
// | *(c0004780) |-----> +--------------+ +2048
// | | | 0x10010653 | ---> 2308
// +- - - - - - - + +4 | h/w pt 0 |
// | *(c0004784) |-----> +--------------+ +3072
// | | + +
// +--------------+ +8 | h/w pt 1 |
// | | +--------------+ +4096
static void __init exynos5420_clk_init(struct device_node *np)
{
if (np) {
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
// of_iomap(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, 0): 0xf0040000
reg_base = of_iomap(np, 0);
// reg_base: 0xf0040000
// reg_base: 0xf0040000
if (!reg_base)
panic("%s: failed to map registers\n", __func__);
} else {
panic("%s: unable to determine soc\n", __func__);
}
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, reg_base: 0xf0040000, nr_clks: 769
// ARRAY_SIZE(exynos5420_clk_regs): 59
samsung_clk_init(np, reg_base, nr_clks,
exynos5420_clk_regs, ARRAY_SIZE(exynos5420_clk_regs),
NULL, 0);
samsung_clk_init() 에서 한일:
- // struct samsung_clk_reg_dump를 59개 만큼 메모리를 할당 받아
- // exynos5420_clk_regs의 값으로 맴버값 세팅
- // (kmem_cache#26-oX)[0...58].offset: exynos5420_clk_regs[0...58]
- //
- // syscore_ops_list의 tail에 (&samsung_clk_syscore_ops)->node 를 추가
- //
- // struct clk * 를 769개 만큼 메모리를 clk_table에 할당 받음
- // clk_table: kmem_cache#23-o0
- //
- // clk_data.clks: kmem_cache#23-o0 (clk_table)
- // clk_data.clk_num: 769
- //
- // struct of_clk_provider 의 메모리(kmem_cache#30-oX)를 할당 받고 맴버값 초기화 수행
- //
- // (kmem_cache#30-oX)->node: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // (kmem_cache#30-oX)->data: &clk_data
- // (kmem_cache#30-oX)->get: of_clk_src_onecell_get
- //
- // list인 of_clk_providers의 head에 (kmem_cache#30-oX)->link를 추가
samsung_clk_of_register_fixed_ext()
static void __init exynos5420_clk_init(struct device_node *np)
{
if (np) {
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
// of_iomap(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, 0): 0xf0040000
reg_base = of_iomap(np, 0);
// reg_base: 0xf0040000
// reg_base: 0xf0040000
if (!reg_base)
panic("%s: failed to map registers\n", __func__);
} else {
panic("%s: unable to determine soc\n", __func__);
}
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, reg_base: 0xf0040000, nr_clks: 769
// ARRAY_SIZE(exynos5420_clk_regs): 59
samsung_clk_init(np, reg_base, nr_clks,
exynos5420_clk_regs, ARRAY_SIZE(exynos5420_clk_regs),
NULL, 0);
// ARRAY_SIZE(exynos5420_fixed_rate_ext_clks): 1
samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,
ARRAY_SIZE(exynos5420_fixed_rate_ext_clks),
ext_clk_match);
samsung_clk_of_register_fixed_ext() 에서 한일:
- // devtree에서 allnext로 순회 하면서 찾은 fixed-rate-clocks node 에서
- // fixed-rate-clocks node에서 "clock-frequency" property값을 freq에 읽어옴
- // freq: 24000000
- // exynos5420_fixed_rate_ext_clks[0].fixed_rate: 24000000
- //
- // struct clk_fixed_rate 만큼 메모리를 kmem_cache#30-oX 할당 받고 struct clk_fixed_rate 의 멤버 값을 아래와 같이 초기화 수행
- //
- // (kmem_cache#30-oX)->fixed_rate: 24000000
- // (kmem_cache#30-oX)->hw.init: &init
- // (&(kmem_cache#30-oX)->hw)->clk: kmem_cache#29-oX
- //
- // struct clk 만큼 메모리를 kmem_cache#29-oX 할당 받고 struct clk 의 멤버 값을 아래와 같이 초기화 수행
- //
- // (kmem_cache#29-oX)->name: kmem_cache#30-oX ("fin_pll")
- // (kmem_cache#29-oX)->ops: &clk_fixed_rate_ops
- // (kmem_cache#29-oX)->hw: &(kmem_cache#30-oX)->hw
- // (kmem_cache#29-oX)->flags: 0x30
- // (kmem_cache#29-oX)->num_parents: 0
- // (kmem_cache#29-oX)->parent_names: ((void *)16)
- // (kmem_cache#29-oX)->parent: NULL
- // (kmem_cache#29-oX)->rate: 24000000
- //
- // (&(kmem_cache#29-oX)->child_node)->next: NULL
- // (&(kmem_cache#29-oX)->child_node)->pprev: &(&(kmem_cache#29-oX)->child_node)
- //
- // (&clk_root_list)->first: &(kmem_cache#29-oX)->child_node
- //
- // clk_table[1]: (kmem_cache#23-o0)[1]: kmem_cache#29-oX
- //
- // struct clk_lookup_alloc 의 메모리를 kmem_cache#30-oX 할당 받고
- // struct clk_lookup_alloc 맴버값 초기화 수행
- //
- // (kmem_cache#30-oX)->cl.clk: kmem_cache#29-oX
- // (kmem_cache#30-oX)->con_id: "fin_pll"
- // (kmem_cache#30-oX)->cl.con_id: (kmem_cache#30-oX)->con_id: "fin_pll"
- //
- // list clocks에 &(&(kmem_cache#30-oX)->cl)->nade를 tail로 추가
samsung_clk_register_pll()
static void __init exynos5420_clk_init(struct device_node *np)
{
if (np) {
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
// of_iomap(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, 0): 0xf0040000
reg_base = of_iomap(np, 0);
// reg_base: 0xf0040000
// reg_base: 0xf0040000
if (!reg_base)
panic("%s: failed to map registers\n", __func__);
} else {
panic("%s: unable to determine soc\n", __func__);
}
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, reg_base: 0xf0040000, nr_clks: 769
// ARRAY_SIZE(exynos5420_clk_regs): 59
samsung_clk_init(np, reg_base, nr_clks,
exynos5420_clk_regs, ARRAY_SIZE(exynos5420_clk_regs),
NULL, 0);
// ARRAY_SIZE(exynos5420_fixed_rate_ext_clks): 1
samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,
ARRAY_SIZE(exynos5420_fixed_rate_ext_clks),
ext_clk_match);
// ARRAY_SIZE(exynos5420_plls): 11, reg_base: 0xf0040000
samsung_clk_register_pll(exynos5420_plls, ARRAY_SIZE(exynos5420_plls),
reg_base);
samsung_clk_register_pll() 에서 한일:
- // exynos5420_plls에 정의되어 있는 PLL 값들을 초기화 수행
- //
- // [apll] 의 초기화 값 수행 결과:
- // struct clk_fixed_rate 만큼 메모리를 kmem_cache#30-oX (apll) 할당 받고 struct clk_fixed_rate 의 멤버 값을 아래와 같이 초기화 수행
- // pll: kmem_cache#30-oX (apll)
- //
- // (kmem_cache#30-oX (apll))->hw.init: &init
- // (kmem_cache#30-oX (apll))->type: pll_2550: 2
- // (kmem_cache#30-oX (apll))->lock_reg: 0xf0040000
- // (kmem_cache#30-oX (apll))->con_reg: 0xf0040100
- //
- // struct clk 만큼 메모리를 kmem_cache#29-oX (apll) 할당 받고 struct clk 의 멤버 값을 아래와 같이 초기화 수행
- //
- // (kmem_cache#29-oX (apll))->name: kmem_cache#30-oX ("fout_apll")
- // (kmem_cache#29-oX (apll))->ops: &samsung_pll35xx_clk_min_ops
- // (kmem_cache#29-oX (apll))->hw: &(kmem_cache#30-oX (apll))->hw
- // (kmem_cache#29-oX (apll))->flags: 0x40
- // (kmem_cache#29-oX (apll))->num_parents: 1
- // (kmem_cache#29-oX (apll))->parent_names: kmem_cache#30-oX
- // (kmem_cache#29-oX (apll))->parent_names[0]: (kmem_cache#30-oX)[0]: kmem_cache#30-oX: "fin_pll"
- // (kmem_cache#29-oX (apll))->parent: kmem_cache#29-oX (fin_pll)
- // (kmem_cache#29-oX (apll))->rate: 1000000000 (1 Ghz)
- //
- // (&(kmem_cache#29-oX (apll))->child_node)->next: NULL
- // (&(kmem_cache#29-oX (apll))->child_node)->pprev: &(&(kmem_cache#29-oX (apll))->child_node)
- //
- // (&(kmem_cache#29-oX (fin_pll))->children)->first: &(kmem_cache#29-oX (apll))->child_node
- //
- // (&(kmem_cache#30-oX (apll))->hw)->clk: kmem_cache#29-oX (apll)
- //
- // clk_table[2]: (kmem_cache#23-o0)[2]: kmem_cache#29-oX (apll)
- //
- // struct clk_lookup_alloc 의 메모리를 kmem_cache#30-oX (apll) 할당 받고
- // struct clk_lookup_alloc 맴버값 초기화 수행
- //
- // (kmem_cache#30-oX)->cl.clk: kmem_cache#29-oX (apll)
- // (kmem_cache#30-oX)->con_id: "fout_apll"
- // (kmem_cache#30-oX)->cl.con_id: (kmem_cache#30-oX)->con_id: "fout_apll"
- //
- // list clocks에 &(&(kmem_cache#30-oX (apll))->cl)->nade를 tail로 추가
- //
- // cpll, dpll, epll, rpll, ipll, spll, vpll, mpll, bpll, kpll 초기화 수행 결과는 생략.
samsung_clk_register_fixed_rate()
static void __init exynos5420_clk_init(struct device_node *np)
{
if (np) {
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
// of_iomap(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, 0): 0xf0040000
reg_base = of_iomap(np, 0);
// reg_base: 0xf0040000
// reg_base: 0xf0040000
if (!reg_base)
panic("%s: failed to map registers\n", __func__);
} else {
panic("%s: unable to determine soc\n", __func__);
}
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, reg_base: 0xf0040000, nr_clks: 769
// ARRAY_SIZE(exynos5420_clk_regs): 59
samsung_clk_init(np, reg_base, nr_clks,
exynos5420_clk_regs, ARRAY_SIZE(exynos5420_clk_regs),
NULL, 0);
// ARRAY_SIZE(exynos5420_fixed_rate_ext_clks): 1
samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,
ARRAY_SIZE(exynos5420_fixed_rate_ext_clks),
ext_clk_match);
// ARRAY_SIZE(exynos5420_plls): 11, reg_base: 0xf0040000
samsung_clk_register_pll(exynos5420_plls, ARRAY_SIZE(exynos5420_plls),
reg_base);
// ARRAY_SIZE(exynos5420_fixed_rate_clks): 5
samsung_clk_register_fixed_rate(exynos5420_fixed_rate_clks,
ARRAY_SIZE(exynos5420_fixed_rate_clks));
samsung_clk_register_fixed_rate() 에서 한일:
- // exynos5420_fixed_rate_clks에 정의되어 있는 fixed rate 값들을 초기화 수행
- //
- // sclk_hdmiphy 의 초기화 값 수행 결과
- // struct clk_fixed_rate 만큼 메모리를 kmem_cache#30-oX 할당 받고 struct clk_fixed_rate 의 멤버 값을 아래와 같이 초기화 수행
- //
- // (kmem_cache#30-oX)->fixed_rate: 24000000
- // (kmem_cache#30-oX)->hw.init: &init
- // (&(kmem_cache#30-oX)->hw)->clk: kmem_cache#29-oX
- //
- // struct clk 만큼 메모리를 kmem_cache#29-oX 할당 받고 struct clk 의 멤버 값을 아래와 같이 초기화 수행
- //
- // (kmem_cache#29-oX)->name: kmem_cache#30-oX ("sclk_hdmiphy")
- // (kmem_cache#29-oX)->ops: &clk_fixed_rate_ops
- // (kmem_cache#29-oX)->hw: &(kmem_cache#30-oX)->hw
- // (kmem_cache#29-oX)->flags: 0x30
- // (kmem_cache#29-oX)->num_parents: 0
- // (kmem_cache#29-oX)->parent_names: ((void *)16)
- // (kmem_cache#29-oX)->parent: NULL
- // (kmem_cache#29-oX)->rate: 24000000
- //
- // (&(kmem_cache#29-oX)->child_node)->next: NULL
- // (&(kmem_cache#29-oX)->child_node)->pprev: &(&(kmem_cache#29-oX)->child_node)
- //
- // (&clk_root_list)->first: &(kmem_cache#29-oX)->child_node
- //
- // clk_table[158]: (kmem_cache#23-o0)[158]: kmem_cache#29-oX
- //
- // struct clk_lookup_alloc 의 메모리를 kmem_cache#30-oX 할당 받고
- // struct clk_lookup_alloc 맴버값 초기화 수행
- //
- // (kmem_cache#30-oX)->cl.clk: kmem_cache#29-oX
- // (kmem_cache#30-oX)->con_id: "fin_pll"
- // (kmem_cache#30-oX)->cl.con_id: (kmem_cache#30-oX)->con_id: "fin_pll"
- //
- // list clocks에 &(&(kmem_cache#30-oX)->cl)->nade를 tail로 추가
- //
- // "sclk_pwi", "sclk_usbh20", "mphy_refclk_ixtal24", "sclk_usbh20_scan_clk" 초기화 수행 결과는 생략.
samsung_clk_register_fixed_factor()
static void __init exynos5420_clk_init(struct device_node *np)
{
if (np) {
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
// of_iomap(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, 0): 0xf0040000
reg_base = of_iomap(np, 0);
// reg_base: 0xf0040000
// reg_base: 0xf0040000
if (!reg_base)
panic("%s: failed to map registers\n", __func__);
} else {
panic("%s: unable to determine soc\n", __func__);
}
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, reg_base: 0xf0040000, nr_clks: 769
// ARRAY_SIZE(exynos5420_clk_regs): 59
samsung_clk_init(np, reg_base, nr_clks,
exynos5420_clk_regs, ARRAY_SIZE(exynos5420_clk_regs),
NULL, 0);
// ARRAY_SIZE(exynos5420_fixed_rate_ext_clks): 1
samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,
ARRAY_SIZE(exynos5420_fixed_rate_ext_clks),
ext_clk_match);
// ARRAY_SIZE(exynos5420_plls): 11, reg_base: 0xf0040000
samsung_clk_register_pll(exynos5420_plls, ARRAY_SIZE(exynos5420_plls),
reg_base);
// ARRAY_SIZE(exynos5420_fixed_rate_clks): 5
samsung_clk_register_fixed_rate(exynos5420_fixed_rate_clks,
ARRAY_SIZE(exynos5420_fixed_rate_clks));
// ARRAY_SIZE(exynos5420_fixed_factor_clks): 1
samsung_clk_register_fixed_factor(exynos5420_fixed_factor_clks,
ARRAY_SIZE(exynos5420_fixed_factor_clks));
- // struct clk_fixed_factor 만큼 메모리를 kmem_cache#30-oX 할당 받고 struct clk_fixed_factor 의 멤버 값을 아래와 같이 초기화 수행
- //
- // (kmem_cache#30-oX)->mult: 1
- // (kmem_cache#30-oX)->div: 2
- // (kmem_cache#30-oX)->hw.init: &init
- //
- // struct clk 만큼 메모리를 kmem_cache#29-oX (sclk_hsic_12m) 할당 받고 struct clk 의 멤버 값을 아래와 같이 초기화 수행
- //
- // (kmem_cache#29-oX (sclk_hsic_12m))->name: kmem_cache#30-oX ("sclk_hsic_12m")
- // (kmem_cache#29-oX (sclk_hsic_12m))->ops: &clk_fixed_factor_ops
- // (kmem_cache#29-oX (sclk_hsic_12m))->hw: &(kmem_cache#30-oX (sclk_hsic_12m))->hw
- // (kmem_cache#29-oX (sclk_hsic_12m))->flags: 0x20
- // (kmem_cache#29-oX (sclk_hsic_12m))->num_parents: 1
- // (kmem_cache#29-oX (sclk_hsic_12m))->parent_names: kmem_cache#30-oX
- // (kmem_cache#29-oX (sclk_hsic_12m))->parent_names[0]: (kmem_cache#30-oX)[0]: kmem_cache#30-oX: "fin_pll"
- // (kmem_cache#29-oX (sclk_hsic_12m))->parent: kmem_cache#29-oX (fin_pll)
- // (kmem_cache#29-oX (sclk_hsic_12m))->rate: 12000000
- //
- // (&(kmem_cache#29-oX (sclk_hsic_12m))->child_node)->next: NULL
- // (&(kmem_cache#29-oX (sclk_hsic_12m))->child_node)->pprev: &(&(kmem_cache#29-oX (sclk_hsic_12m))->child_node)
- //
- // (&(kmem_cache#29-oX (fin_pll))->children)->first: &(kmem_cache#29-oX (sclk_hsic_12m))->child_node
- //
- // (&(kmem_cache#30-oX (sclk_hsic_12m))->hw)->clk: kmem_cache#29-oX (sclk_hsic_12m)
- //
- // clk_table[0]: (kmem_cache#23-o0)[0]: kmem_cache#29-oX (sclk_hsic_12m)
* samsung_clk_register_mux()
```clk-exynos5420.c
static void __init exynos5420_clk_init(struct device_node *np)
{
if (np) {
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
// of_iomap(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, 0): 0xf0040000
reg_base = of_iomap(np, 0);
// reg_base: 0xf0040000
// reg_base: 0xf0040000
if (!reg_base)
panic("%s: failed to map registers\n", __func__);
} else {
panic("%s: unable to determine soc\n", __func__);
}
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, reg_base: 0xf0040000, nr_clks: 769
// ARRAY_SIZE(exynos5420_clk_regs): 59
samsung_clk_init(np, reg_base, nr_clks,
exynos5420_clk_regs, ARRAY_SIZE(exynos5420_clk_regs),
NULL, 0);
// ARRAY_SIZE(exynos5420_fixed_rate_ext_clks): 1
samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,
ARRAY_SIZE(exynos5420_fixed_rate_ext_clks),
ext_clk_match);
// ARRAY_SIZE(exynos5420_plls): 11, reg_base: 0xf0040000
samsung_clk_register_pll(exynos5420_plls, ARRAY_SIZE(exynos5420_plls),
reg_base);
// ARRAY_SIZE(exynos5420_fixed_rate_clks): 5
samsung_clk_register_fixed_rate(exynos5420_fixed_rate_clks,
ARRAY_SIZE(exynos5420_fixed_rate_clks));
// ARRAY_SIZE(exynos5420_fixed_factor_clks): 1
samsung_clk_register_fixed_factor(exynos5420_fixed_factor_clks,
ARRAY_SIZE(exynos5420_fixed_factor_clks));
// ARRAY_SIZE(exynos5420_mux_clks): 85
samsung_clk_register_mux(exynos5420_mux_clks,
ARRAY_SIZE(exynos5420_mux_clks));
samsung_clk_register_mux() 에서 한일:
- // mout_mspll_kfc, sclk_spll를 수행한 결과:
- //
- // (mout_mspll_kfc) 에서 한일:
- // struct clk_mux 만큼 메모리를 kmem_cache#30-oX (mout_mspll_kfc) 할당 받고 struct clk_mux 의 멤버 값을 아래와 같이 초기화 수행
- //
- // (kmem_cache#30-oX)->reg: 0xf005021c
- // (kmem_cache#30-oX)->shift: 8
- // (kmem_cache#30-oX)->mask: 0x3
- // (kmem_cache#30-oX)->flags: 0
- // (kmem_cache#30-oX)->lock: &lock
- // (kmem_cache#30-oX)->table: NULL
- // (kmem_cache#30-oX)->hw.init: &init
- //
- // struct clk 만큼 메모리를 kmem_cache#29-oX (mout_mspll_kfc) 할당 받고 struct clk 의 멤버 값을 아래와 같이 초기화 수행
- //
- // (kmem_cache#29-oX (mout_mspll_kfc))->name: kmem_cache#30-oX ("mout_mspll_kfc")
- // (kmem_cache#29-oX (mout_mspll_kfc))->ops: &clk_mux_ops
- // (kmem_cache#29-oX (mout_mspll_kfc))->hw: &(kmem_cache#30-oX (mout_mspll_kfc))->hw
- // (kmem_cache#29-oX (mout_mspll_kfc))->flags: 0xa0
- // (kmem_cache#29-oX (mout_mspll_kfc))->num_parents 4
- // (kmem_cache#29-oX (mout_mspll_kfc))->parent_names: kmem_cache#30-oX
- // (kmem_cache#29-oX (mout_mspll_kfc))->parent_names[0]: (kmem_cache#30-oX)[0]: kmem_cache#30-oX: "sclk_cpll"
- // (kmem_cache#29-oX (mout_mspll_kfc))->parent_names[1]: (kmem_cache#30-oX)[1]: kmem_cache#30-oX: "sclk_dpll"
- // (kmem_cache#29-oX (mout_mspll_kfc))->parent_names[2]: (kmem_cache#30-oX)[2]: kmem_cache#30-oX: "sclk_mpll"
- // (kmem_cache#29-oX (mout_mspll_kfc))->parent_names[3]: (kmem_cache#30-oX)[3]: kmem_cache#30-oX: "sclk_spll"
- // (kmem_cache#29-oX (mout_mspll_kfc))->parent: NULL
- // (kmem_cache#29-oX (mout_mspll_kfc))->rate: 0
- //
- // (kmem_cache#29-oX (mout_mspll_kfc))->parents: kmem_cache#30-oX
- // (kmem_cache#29-oX (mout_mspll_kfc))->parents[0...3]: (kmem_cache#30-oX)[0...3]: NULL
- //
- // (&(kmem_cache#29-oX (mout_mspll_kfc))->child_node)->next: NULL
- // (&(kmem_cache#29-oX (mout_mspll_kfc))->child_node)->pprev: &(&(kmem_cache#29-oX (mout_mspll_kfc))->child_node)
- //
- // (&clk_orphan_list)->first: &(kmem_cache#29-oX (mout_mspll_kfc))->child_node
- //
- // (&(kmem_cache#30-oX (mout_mspll_kfc))->hw)->clk: kmem_cache#29-oX (mout_mspll_kfc)
- // (sclk_spll) 에서 한일:
- // struct clk_mux 만큼 메모리를 kmem_cache#30-oX (sclk_spll) 할당 받고 struct clk_mux 의 멤버 값을 아래와 같이 초기화 수행
- //
- // (kmem_cache#30-oX)->reg: 0xf0050218
- // (kmem_cache#30-oX)->shift: 8
- // (kmem_cache#30-oX)->mask: 0x3
- // (kmem_cache#30-oX)->flags: 0
- // (kmem_cache#30-oX)->lock: &lock
- // (kmem_cache#30-oX)->table: NULL
- // (kmem_cache#30-oX)->hw.init: &init
- //
- // struct clk 만큼 메모리를 kmem_cache#29-oX (sclk_spll) 할당 받고 struct clk 의 멤버 값을 아래와 같이 초기화 수행
- //
- // (kmem_cache#29-oX (sclk_spll))->name: kmem_cache#30-oX ("sclk_spll")
- // (kmem_cache#29-oX (sclk_spll))->ops: &clk_mux_ops
- // (kmem_cache#29-oX (sclk_spll))->hw: &(kmem_cache#30-oX (sclk_spll))->hw
- // (kmem_cache#29-oX (sclk_spll))->flags: 0xa0
- // (kmem_cache#29-oX (sclk_spll))->num_parents 2
- // (kmem_cache#29-oX (sclk_spll))->parent_names: kmem_cache#30-oX
- // (kmem_cache#29-oX (sclk_spll))->parent_names[0]: (kmem_cache#30-oX)[0]: kmem_cache#30-oX: "fin_pll"
- // (kmem_cache#29-oX (sclk_spll))->parent_names[1]: (kmem_cache#30-oX)[1]: kmem_cache#30-oX: "fout_spll"
- // (kmem_cache#29-oX (sclk_spll))->parent: NULL
- // (kmem_cache#29-oX (sclk_spll))->rate: 600000000
- //
- // (kmem_cache#29-oX (sclk_spll))->parents: kmem_cache#30-oX
- // (kmem_cache#29-oX (sclk_spll))->parents[0]: (kmem_cache#30-oX)[0]: kmem_cache#29-oX (fin_pll)
- // (kmem_cache#29-oX (sclk_spll))->parents[1]: (kmem_cache#30-oX)[1]: kmem_cache#29-oX (fout_spll)
- //
- // parents 인 "fin_pll", "fout_spll" 값들 중에
- // register CLK_SRC_TOP6 의 값을 읽어서 mux 할 parent clock 을 선택함
- // return된 값이 선택된 parent clock의 index 값임
- // parent clock 중에 선택된 parent clock의 이름으로 등록된 clk struct를 반환함
- //
- // (&(kmem_cache#29-oX (sclk_spll))->child_node)->next: NULL
- // (&(kmem_cache#29-oX (sclk_spll))->child_node)->pprev: &(&(kmem_cache#29-oX (sclk_spll))->child_node)
- //
- // (&(kmem_cache#29-oX (fout_spll))->children)->first: &(kmem_cache#29-oX (sclk_spll))->child_node
- //
- // (&(kmem_cache#30-oX (sclk_spll))->hw)->clk: kmem_cache#29-oX (sclk_spll)
- //
- // orphan 으로 등록된 mout_mspll_kfc의 값을 갱신
- // (&(kmem_cache#29-oX (mout_mspll_kfc))->child_node)->next: NULL
- // (&(kmem_cache#29-oX (mout_mspll_kfc))->child_node)->pprev: &(&(kmem_cache#29-oX (mout_mspll_kfc))->child_node)
- //
- // (&(kmem_cache#29-oX (sclk_spll))->children)->first: &(kmem_cache#29-oX (mout_mspll_kfc))->child_node
- //
- // (kmem_cache#29-oX (mout_mspll_kfc))->parent: kmem_cache#29-oX (sclk_spll)
- //
- // parent가 있는지 확인후 parent의 clock rate 값으로 clock rate 값을 세팅
- // (kmem_cache#29-oX (mout_mspll_kfc))->rate: 600000000
samsung_clk_register_div()
static void __init exynos5420_clk_init(struct device_node *np)
{
if (np) {
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
// of_iomap(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, 0): 0xf0040000
reg_base = of_iomap(np, 0);
// reg_base: 0xf0040000
// reg_base: 0xf0040000
if (!reg_base)
panic("%s: failed to map registers\n", __func__);
} else {
panic("%s: unable to determine soc\n", __func__);
}
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, reg_base: 0xf0040000, nr_clks: 769
// ARRAY_SIZE(exynos5420_clk_regs): 59
samsung_clk_init(np, reg_base, nr_clks,
exynos5420_clk_regs, ARRAY_SIZE(exynos5420_clk_regs),
NULL, 0);
// ARRAY_SIZE(exynos5420_fixed_rate_ext_clks): 1
samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,
ARRAY_SIZE(exynos5420_fixed_rate_ext_clks),
ext_clk_match);
// ARRAY_SIZE(exynos5420_plls): 11, reg_base: 0xf0040000
samsung_clk_register_pll(exynos5420_plls, ARRAY_SIZE(exynos5420_plls),
reg_base);
// ARRAY_SIZE(exynos5420_fixed_rate_clks): 5
samsung_clk_register_fixed_rate(exynos5420_fixed_rate_clks,
ARRAY_SIZE(exynos5420_fixed_rate_clks));
// ARRAY_SIZE(exynos5420_fixed_factor_clks): 1
samsung_clk_register_fixed_factor(exynos5420_fixed_factor_clks,
ARRAY_SIZE(exynos5420_fixed_factor_clks));
// ARRAY_SIZE(exynos5420_mux_clks): 85
samsung_clk_register_mux(exynos5420_mux_clks,
ARRAY_SIZE(exynos5420_mux_clks));
// ARRAY_SIZE(exynos5420_div_clks): 53
samsung_clk_register_div(exynos5420_div_clks,
ARRAY_SIZE(exynos5420_div_clks));
samsung_clk_register_div() 에서 한일:
- // exynos5420_div_clks의 div 들 중에 array index 1번의
- // DIV(none, "sclk_apll", "mout_apll", DIV_CPU0, 24, 3) 을 가지고 분석 진행
- //
- // struct clk_divider 만큼 메모리를 할당 받아 맴버값 초기화 수행
- // kmem_cache#30-oX (sclk_apll)
- // (kmem_cache#30-oX (sclk_apll))->reg: 0xf0040500
- // (kmem_cache#30-oX (sclk_apll))->shift: 24
- // (kmem_cache#30-oX (sclk_apll))->width: 3
- // (kmem_cache#30-oX (sclk_apll))->flags: 0
- // (kmem_cache#30-oX (sclk_apll))->lock: &lock
- // (kmem_cache#30-oX (sclk_apll))->hw.init: &init
- // (kmem_cache#30-oX (sclk_apll))->table: NULL
- //
- // struct clk 만큼 메모리를 할당 받아 맴버값 초기화 수행
- // kmem_cache#29-oX (sclk_apll)
- // (kmem_cache#29-oX (sclk_apll))->name: kmem_cache#30-oX ("sclk_apll")
- // (kmem_cache#29-oX (sclk_apll))->ops: &clk_divider_ops
- // (kmem_cache#29-oX (sclk_apll))->hw: &(kmem_cache#30-oX (sclk_apll))->hw
- // (kmem_cache#29-oX (sclk_apll))->flags: 0x0
- // (kmem_cache#29-oX (sclk_apll))->num_parents 1
- // (kmem_cache#29-oX (sclk_apll))->parent_names[0]: (kmem_cache#30-oX)[0]: kmem_cache#30-oX: "mout_apll"
- // (kmem_cache#29-oX (sclk_apll))->parent: kmem_cache#29-oX (mout_apll)
- // (kmem_cache#29-oX (sclk_apll))->rate: 800000000
- //
- // clk 의 이름이 "mout_apll"인 메모리 값을 clk_root_list 에서 찾아 리턴 수행
- //
- // (&(kmem_cache#29-oX (sclk_apll))->child_node)->next: NULL
- // (&(kmem_cache#29-oX (sclk_apll))->child_node)->pprev: &(&(kmem_cache#29-oX (sclk_apll))->child_node)
- //
- // (&(kmem_cache#29-oX (mout_apll))->children)->first: &(kmem_cache#29-oX (sclk_apll))->child_node
- //
- // exynos5420_div_clks의 idx 0, 2...52 까지 loop 수행
samsung_clk_register_gate()
static void __init exynos5420_clk_init(struct device_node *np)
{
if (np) {
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
// of_iomap(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, 0): 0xf0040000
reg_base = of_iomap(np, 0);
// reg_base: 0xf0040000
// reg_base: 0xf0040000
if (!reg_base)
panic("%s: failed to map registers\n", __func__);
} else {
panic("%s: unable to determine soc\n", __func__);
}
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, reg_base: 0xf0040000, nr_clks: 769
// ARRAY_SIZE(exynos5420_clk_regs): 59
samsung_clk_init(np, reg_base, nr_clks,
exynos5420_clk_regs, ARRAY_SIZE(exynos5420_clk_regs),
NULL, 0);
// ARRAY_SIZE(exynos5420_fixed_rate_ext_clks): 1
samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,
ARRAY_SIZE(exynos5420_fixed_rate_ext_clks),
ext_clk_match);
// ARRAY_SIZE(exynos5420_plls): 11, reg_base: 0xf0040000
samsung_clk_register_pll(exynos5420_plls, ARRAY_SIZE(exynos5420_plls),
reg_base);
// ARRAY_SIZE(exynos5420_fixed_rate_clks): 5
samsung_clk_register_fixed_rate(exynos5420_fixed_rate_clks,
ARRAY_SIZE(exynos5420_fixed_rate_clks));
// ARRAY_SIZE(exynos5420_fixed_factor_clks): 1
samsung_clk_register_fixed_factor(exynos5420_fixed_factor_clks,
ARRAY_SIZE(exynos5420_fixed_factor_clks));
// ARRAY_SIZE(exynos5420_mux_clks): 85
samsung_clk_register_mux(exynos5420_mux_clks,
ARRAY_SIZE(exynos5420_mux_clks));
// ARRAY_SIZE(exynos5420_div_clks): 53
samsung_clk_register_div(exynos5420_div_clks,
ARRAY_SIZE(exynos5420_div_clks));
// ARRAY_SIZE(exynos5420_gate_clks): 136
samsung_clk_register_gate(exynos5420_gate_clks,
ARRAY_SIZE(exynos5420_gate_clks));
- // clk_init_cb: exynos5420_clk_init,
- // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- clk_init_cb(np);
- reg_base = of_iomap(np, 0);
- samsung_clk_init()
- samsung_clk_of_register_fixed_ext()
- samsung_clk_register_pll()
- samsung_clk_register_fixed_rate()
- samsung_clk_register_fixed_factor()
- samsung_clk_register_mux()
- samsung_clk_register_div()
- samsung_clk_register_gate()
samsung_clk_register_gate()
- called: start_kernel()->time_init()->of_clk_init()->exynos5420_clk_init()
- // clk_init_cb: exynos5420_clk_init,
- // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- clk_init_cb(np);
- reg_base = of_iomap(np, 0);
- samsung_clk_init()
- samsung_clk_of_register_fixed_ext()
- samsung_clk_register_pll()
- samsung_clk_register_fixed_rate()
- samsung_clk_register_fixed_factor()
- samsung_clk_register_mux()
- samsung_clk_register_div()
- samsung_clk_register_gate()
/* register a list of gate clocks */
// ARM10C 20150307
// exynos5420_gate_clks, ARRAY_SIZE(exynos5420_gate_clks): 136
void __init samsung_clk_register_gate(struct samsung_gate_clock *list,
unsigned int nr_clk)
{
struct clk *clk;
unsigned int idx, ret;
// NOTE:
// exynos5420_gate_clks의 gate 들 중에 array index 36번의
// GATE(sclk_fimd1, "sclk_fimd1", "dout_fimd1", GATE_TOP_SCLK_PERIC, 0, CLK_SET_RATE_PARENT, 0) 을 가지고 분석 진행
// nr_clk: 136
for (idx = 0; idx < nr_clk; idx++, list++) {
// idx: 36,
// list->name: exynos5420_gate_clks[36].name: "sclk_fimd1",
// list->parent_name: exynos5420_gate_clks[36].parent_name: "dout_fimd1",
// list->flags: exynos5420_gate_clks[36].flags: 0x4,
// list->offset: exynos5420_gate_clks[36].offset: 0x10828,
// list->bit_idx: exynos5420_gate_clks[36].bit_idx: 0,
// list->gate_flags: exynos5420_gate_clks[36].gate_flags: 0,
// &lock
// reg_base: 0xf0040000
// clk_register_gate(NULL, "sclk_fimd1", "dout_fimd1", 0x4, 0xf0050828, 0, 0, &lock): kmem_cache#29-oX (sclk_fimd1)
clk = clk_register_gate(NULL, list->name, list->parent_name,
list->flags, reg_base + list->offset,
list->bit_idx, list->gate_flags, &lock);
- return: start_kernel()->time_init()->of_clk_init()->exynos5420_clk_init()->clk_register_gate()
- // clk_init_cb: exynos5420_clk_init,
- // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- clk_init_cb(np);
- reg_base = of_iomap(np, 0);
- samsung_clk_init()
- samsung_clk_of_register_fixed_ext()
- samsung_clk_register_pll()
- samsung_clk_register_fixed_rate()
- samsung_clk_register_fixed_factor()
- samsung_clk_register_mux()
- samsung_clk_register_div()
- samsung_clk_register_gate()
- // clk_init_cb: exynos5420_clk_init,
- // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- clk_init_cb(np);
- reg_base = of_iomap(np, 0);
- samsung_clk_init()
- samsung_clk_of_register_fixed_ext()
- samsung_clk_register_pll()
- samsung_clk_register_fixed_rate()
- samsung_clk_register_fixed_factor()
- samsung_clk_register_mux()
- samsung_clk_register_div()
- samsung_clk_register_gate()
/* register a list of gate clocks */
// ARM10C 20150307
// exynos5420_gate_clks, ARRAY_SIZE(exynos5420_gate_clks): 136
void __init samsung_clk_register_gate(struct samsung_gate_clock *list,
unsigned int nr_clk)
{
struct clk *clk;
unsigned int idx, ret;
// NOTE:
// exynos5420_gate_clks의 gate 들 중에 array index 36번의
// GATE(sclk_fimd1, "sclk_fimd1", "dout_fimd1", GATE_TOP_SCLK_PERIC, 0, CLK_SET_RATE_PARENT, 0) 을 가지고 분석 진행
// nr_clk: 136
for (idx = 0; idx < nr_clk; idx++, list++) {
// idx: 36,
// list->name: exynos5420_gate_clks[36].name: "sclk_fimd1",
// list->parent_name: exynos5420_gate_clks[36].parent_name: "dout_fimd1",
// list->flags: exynos5420_gate_clks[36].flags: 0x4,
// list->offset: exynos5420_gate_clks[36].offset: 0x10828,
// list->bit_idx: exynos5420_gate_clks[36].bit_idx: 0,
// list->gate_flags: exynos5420_gate_clks[36].gate_flags: 0,
// &lock
// reg_base: 0xf0040000
// clk_register_gate(NULL, "sclk_fimd1", "dout_fimd1", 0x4, 0xf0050828, 0, 0, &lock): kmem_cache#29-oX (sclk_fimd1)
clk = clk_register_gate(NULL, list->name, list->parent_name,
list->flags, reg_base + list->offset,
list->bit_idx, list->gate_flags, &lock);
- // clk_init_cb: exynos5420_clk_init,
- // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- clk_init_cb(np);
- reg_base = of_iomap(np, 0);
- samsung_clk_init()
- samsung_clk_of_register_fixed_ext()
- samsung_clk_register_pll()
- samsung_clk_register_fixed_rate()
- samsung_clk_register_fixed_factor()
- samsung_clk_register_mux()
- samsung_clk_register_div()
- samsung_clk_register_gate()
exynos5420_clk_init()
- return: start_kernel()->time_init()->of_clk_init()->exynos5420_clk_init()->clk_register_gate()
- // clk_init_cb: exynos5420_clk_init,
- // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- clk_init_cb(np);
- reg_base = of_iomap(np, 0);
- samsung_clk_init()
- samsung_clk_of_register_fixed_ext()
- samsung_clk_register_pll()
- samsung_clk_register_fixed_rate()
- samsung_clk_register_fixed_factor()
- samsung_clk_register_mux()
- samsung_clk_register_div()
- samsung_clk_register_gate()
static void __init exynos5420_clk_init(struct device_node *np)
{
if (np) {
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
// of_iomap(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, 0): 0xf0040000
reg_base = of_iomap(np, 0);
// reg_base: 0xf0040000
// reg_base: 0xf0040000
if (!reg_base)
panic("%s: failed to map registers\n", __func__);
} else {
panic("%s: unable to determine soc\n", __func__);
}
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, reg_base: 0xf0040000, nr_clks: 769
// ARRAY_SIZE(exynos5420_clk_regs): 59
samsung_clk_init(np, reg_base, nr_clks,
exynos5420_clk_regs, ARRAY_SIZE(exynos5420_clk_regs),
NULL, 0);
// ARRAY_SIZE(exynos5420_fixed_rate_ext_clks): 1
samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,
ARRAY_SIZE(exynos5420_fixed_rate_ext_clks),
ext_clk_match);
// ARRAY_SIZE(exynos5420_plls): 11, reg_base: 0xf0040000
samsung_clk_register_pll(exynos5420_plls, ARRAY_SIZE(exynos5420_plls),
reg_base);
// ARRAY_SIZE(exynos5420_fixed_rate_clks): 5
samsung_clk_register_fixed_rate(exynos5420_fixed_rate_clks,
ARRAY_SIZE(exynos5420_fixed_rate_clks));
// ARRAY_SIZE(exynos5420_fixed_factor_clks): 1
samsung_clk_register_fixed_factor(exynos5420_fixed_factor_clks,
ARRAY_SIZE(exynos5420_fixed_factor_clks));
// ARRAY_SIZE(exynos5420_mux_clks): 85
samsung_clk_register_mux(exynos5420_mux_clks,
ARRAY_SIZE(exynos5420_mux_clks));
// ARRAY_SIZE(exynos5420_div_clks): 53
samsung_clk_register_div(exynos5420_div_clks,
ARRAY_SIZE(exynos5420_div_clks));
// ARRAY_SIZE(exynos5420_gate_clks): 136
samsung_clk_register_gate(exynos5420_gate_clks,
ARRAY_SIZE(exynos5420_gate_clks));
-
clk = clk_register_gate(NULL, list->name, list->parent_name,...);
- // clk_register_gate(sclk_fimd1)에서 한일:
- // struct clk_gate 만큼 메모리를 할당 받아 맴버값 초기화 수행
- / kmem_cache#30-oX (sclk_fimd1)
- // (kmem_cache#30-oX (sclk_fimd1))->reg: 0xf0050828
- // (kmem_cache#30-oX (sclk_fimd1))->bit_idx: 0
- // (kmem_cache#30-oX (sclk_fimd1))->flags: 0
- // (kmem_cache#30-oX (sclk_fimd1))->lock: &lock
- // (kmem_cache#30-oX (sclk_fimd1))->hw.init: &init
- // (kmem_cache#30-oX (sclk_fimd1))->table: NULL
- //
- // struct clk 만큼 메모리를 할당 받아 맴버값 초기화 수행
- // kmem_cache#29-oX (sclk_fimd1)
- // (kmem_cache#29-oX (sclk_fimd1))->name: kmem_cache#30-oX ("sclk_fimd1")
- // (kmem_cache#29-oX (sclk_fimd1))->ops: &clk_gate_ops
- // (kmem_cache#29-oX (sclk_fimd1))->hw: &(kmem_cache#30-oX (sclk_fimd1))->hw
- // (kmem_cache#29-oX (sclk_fimd1))->flags: 0x0
- // (kmem_cache#29-oX (sclk_fimd1))->num_parents 1
- // (kmem_cache#29-oX (sclk_fimd1))->parent_names[0]: (kmem_cache#30-oX)[0]: kmem_cache#30-oX: "mout_apll"
- // (kmem_cache#29-oX (sclk_fimd1))->parent: kmem_cache#29-oX (dout_fimd1)
- // (kmem_cache#29-oX (sclk_fimd1))->rate: 266000000
- //
- // clk 의 이름이 "dout_fimd1"인 메모리 값을 clk_root_list 에서 찾아 리턴 수행
- //
- // (&(kmem_cache#29-oX (sclk_fimd1))->child_node)->next: NULL
- // (&(kmem_cache#29-oX (sclk_fimd1))->child_node)->pprev: &(&(kmem_cache#29-oX (sclk_fimd1))->child_node)
- //
- // (&(kmem_cache#29-oX (dout_fimd1))->children)->first: &(kmem_cache#29-oX (sclk_fimd1))->child_node
-
call: start_kernel()->time_init()->of_clk_init()->exynos5420_clk_init()->clk_register_gate()->samsung_clk_add_lookup()
- // clk_init_cb: exynos5420_clk_init,
- // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- clk_init_cb(np);
- reg_base = of_iomap(np, 0);
- samsung_clk_init()
- samsung_clk_of_register_fixed_ext()
- samsung_clk_register_pll()
- samsung_clk_register_fixed_rate()
- samsung_clk_register_fixed_factor()
- samsung_clk_register_mux()
- samsung_clk_register_div()
- samsung_clk_register_gate()
- samsung_clk_add_lookup()
- // clk_init_cb: exynos5420_clk_init,
- // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- clk_init_cb(np);
- reg_base = of_iomap(np, 0);
- samsung_clk_init()
- samsung_clk_of_register_fixed_ext()
- samsung_clk_register_pll()
- samsung_clk_register_fixed_rate()
- samsung_clk_register_fixed_factor()
- samsung_clk_register_mux()
- samsung_clk_register_div()
- samsung_clk_register_gate()
static void __init exynos5420_clk_init(struct device_node *np)
{
if (np) {
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
// of_iomap(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, 0): 0xf0040000
reg_base = of_iomap(np, 0);
// reg_base: 0xf0040000
// reg_base: 0xf0040000
if (!reg_base)
panic("%s: failed to map registers\n", __func__);
} else {
panic("%s: unable to determine soc\n", __func__);
}
// np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소, reg_base: 0xf0040000, nr_clks: 769
// ARRAY_SIZE(exynos5420_clk_regs): 59
samsung_clk_init(np, reg_base, nr_clks,
exynos5420_clk_regs, ARRAY_SIZE(exynos5420_clk_regs),
NULL, 0);
// ARRAY_SIZE(exynos5420_fixed_rate_ext_clks): 1
samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,
ARRAY_SIZE(exynos5420_fixed_rate_ext_clks),
ext_clk_match);
// ARRAY_SIZE(exynos5420_plls): 11, reg_base: 0xf0040000
samsung_clk_register_pll(exynos5420_plls, ARRAY_SIZE(exynos5420_plls),
reg_base);
// ARRAY_SIZE(exynos5420_fixed_rate_clks): 5
samsung_clk_register_fixed_rate(exynos5420_fixed_rate_clks,
ARRAY_SIZE(exynos5420_fixed_rate_clks));
// ARRAY_SIZE(exynos5420_fixed_factor_clks): 1
samsung_clk_register_fixed_factor(exynos5420_fixed_factor_clks,
ARRAY_SIZE(exynos5420_fixed_factor_clks));
// ARRAY_SIZE(exynos5420_mux_clks): 85
samsung_clk_register_mux(exynos5420_mux_clks,
ARRAY_SIZE(exynos5420_mux_clks));
// ARRAY_SIZE(exynos5420_div_clks): 53
samsung_clk_register_div(exynos5420_div_clks,
ARRAY_SIZE(exynos5420_div_clks));
// ARRAY_SIZE(exynos5420_gate_clks): 136
samsung_clk_register_gate(exynos5420_gate_clks,
ARRAY_SIZE(exynos5420_gate_clks));
clk = clk_register_gate(NULL, list->name, list->parent_name,...);
- // clk_register_gate(sclk_fimd1)에서 한일:
- // struct clk_gate 만큼 메모리를 할당 받아 맴버값 초기화 수행
- / kmem_cache#30-oX (sclk_fimd1)
- // (kmem_cache#30-oX (sclk_fimd1))->reg: 0xf0050828
- // (kmem_cache#30-oX (sclk_fimd1))->bit_idx: 0
- // (kmem_cache#30-oX (sclk_fimd1))->flags: 0
- // (kmem_cache#30-oX (sclk_fimd1))->lock: &lock
- // (kmem_cache#30-oX (sclk_fimd1))->hw.init: &init
- // (kmem_cache#30-oX (sclk_fimd1))->table: NULL
- //
- // struct clk 만큼 메모리를 할당 받아 맴버값 초기화 수행
- // kmem_cache#29-oX (sclk_fimd1)
- // (kmem_cache#29-oX (sclk_fimd1))->name: kmem_cache#30-oX ("sclk_fimd1")
- // (kmem_cache#29-oX (sclk_fimd1))->ops: &clk_gate_ops
- // (kmem_cache#29-oX (sclk_fimd1))->hw: &(kmem_cache#30-oX (sclk_fimd1))->hw
- // (kmem_cache#29-oX (sclk_fimd1))->flags: 0x0
- // (kmem_cache#29-oX (sclk_fimd1))->num_parents 1
- // (kmem_cache#29-oX (sclk_fimd1))->parent_names[0]: (kmem_cache#30-oX)[0]: kmem_cache#30-oX: "mout_apll"
- // (kmem_cache#29-oX (sclk_fimd1))->parent: kmem_cache#29-oX (dout_fimd1)
- // (kmem_cache#29-oX (sclk_fimd1))->rate: 266000000
- //
- // clk 의 이름이 "dout_fimd1"인 메모리 값을 clk_root_list 에서 찾아 리턴 수행
- //
- // (&(kmem_cache#29-oX (sclk_fimd1))->child_node)->next: NULL
- // (&(kmem_cache#29-oX (sclk_fimd1))->child_node)->pprev: &(&(kmem_cache#29-oX (sclk_fimd1))->child_node)
- //
- // (&(kmem_cache#29-oX (dout_fimd1))->children)->first: &(kmem_cache#29-oX (sclk_fimd1))->child_node
call: start_kernel()->time_init()->of_clk_init()->exynos5420_clk_init()->clk_register_gate()->samsung_clk_add_lookup()
- // clk_init_cb: exynos5420_clk_init,
- // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- clk_init_cb(np);
- reg_base = of_iomap(np, 0);
- samsung_clk_init()
- samsung_clk_of_register_fixed_ext()
- samsung_clk_register_pll()
- samsung_clk_register_fixed_rate()
- samsung_clk_register_fixed_factor()
- samsung_clk_register_mux()
- samsung_clk_register_div()
- samsung_clk_register_gate()
- samsung_clk_add_lookup()
samsung_clk_add_lookup(clk, list->id);
- called: start_kernel()->time_init()->of_clk_init()->exynos5420_clk_init()->clk_register_gate()->samsung_clk_add_lookup()
- // clk_init_cb: exynos5420_clk_init,
- // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- clk_init_cb(np);
- reg_base = of_iomap(np, 0);
- samsung_clk_init()
- samsung_clk_of_register_fixed_ext()
- samsung_clk_register_pll()
- samsung_clk_register_fixed_rate()
- samsung_clk_register_fixed_factor()
- samsung_clk_register_mux()
- samsung_clk_register_div()
- samsung_clk_register_gate()
- samsung_clk_add_lookup()
/* register a list of gate clocks */
// ARM10C 20150307
// exynos5420_gate_clks, ARRAY_SIZE(exynos5420_gate_clks): 136
void __init samsung_clk_register_gate(struct samsung_gate_clock *list,
unsigned int nr_clk)
{
struct clk *clk;
unsigned int idx, ret;
// NOTE:
// exynos5420_gate_clks의 gate 들 중에 array index 36번의
// GATE(sclk_fimd1, "sclk_fimd1", "dout_fimd1", GATE_TOP_SCLK_PERIC, 0, CLK_SET_RATE_PARENT, 0) 을 가지고 분석 진행
// nr_clk: 136
for (idx = 0; idx < nr_clk; idx++, list++) {
// idx: 36,
// list->name: exynos5420_gate_clks[36].name: "sclk_fimd1",
// list->parent_name: exynos5420_gate_clks[36].parent_name: "dout_fimd1",
// list->flags: exynos5420_gate_clks[36].flags: 0x4,
// list->offset: exynos5420_gate_clks[36].offset: 0x10828,
// list->bit_idx: exynos5420_gate_clks[36].bit_idx: 0,
// list->gate_flags: exynos5420_gate_clks[36].gate_flags: 0,
// &lock
// reg_base: 0xf0040000
// clk_register_gate(NULL, "sclk_fimd1", "dout_fimd1", 0x4, 0xf0050828, 0, 0, &lock): kmem_cache#29-oX (sclk_fimd1)
clk = clk_register_gate(NULL, list->name, list->parent_name,
list->flags, reg_base + list->offset,
list->bit_idx, list->gate_flags, &lock);
// clk: kmem_cache#29-oX (sclk_fimd1)
// clk: kmem_cache#29-oX (sclk_fimd1), IS_ERR(kmem_cache#29-oX (sclk_fimd1)): 0
if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n", __func__,
list->name);
continue;
}
/* register a clock lookup only if a clock alias is specified */
// list->alias: exynos5420_gate_clks[36].alias: NULL
if (list->alias) {
ret = clk_register_clkdev(clk, list->alias,
list->dev_name);
if (ret)
pr_err("%s: failed to register lookup %s\n",
__func__, list->alias);
}
// clk: kmem_cache#29-oX (sclk_fimd1), list->id: exynos5420_gate_clks[36].id: 136
samsung_clk_add_lookup(clk, list->id);
- call: start_kernel()->time_init()->of_clk_init()->exynos5420_clk_init()
- // clk_init_cb: exynos5420_clk_init,
- // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- clk_init_cb(np);
- reg_base = of_iomap(np, 0);
- samsung_clk_init()
- samsung_clk_of_register_fixed_ext()
- samsung_clk_register_pll()
- samsung_clk_register_fixed_rate()
- samsung_clk_register_fixed_factor()
- samsung_clk_register_mux()
- samsung_clk_register_div()
- samsung_clk_register_gate()
- clk = clk_register_gate()
- samsung_clk_add_lookup()
- // clk_init_cb: exynos5420_clk_init,
- // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- clk_init_cb(np);
- reg_base = of_iomap(np, 0);
- samsung_clk_init()
- samsung_clk_of_register_fixed_ext()
- samsung_clk_register_pll()
- samsung_clk_register_fixed_rate()
- samsung_clk_register_fixed_factor()
- samsung_clk_register_mux()
- samsung_clk_register_div()
- samsung_clk_register_gate()
- samsung_clk_add_lookup()
/* register a list of gate clocks */
// ARM10C 20150307
// exynos5420_gate_clks, ARRAY_SIZE(exynos5420_gate_clks): 136
void __init samsung_clk_register_gate(struct samsung_gate_clock *list,
unsigned int nr_clk)
{
struct clk *clk;
unsigned int idx, ret;
// NOTE:
// exynos5420_gate_clks의 gate 들 중에 array index 36번의
// GATE(sclk_fimd1, "sclk_fimd1", "dout_fimd1", GATE_TOP_SCLK_PERIC, 0, CLK_SET_RATE_PARENT, 0) 을 가지고 분석 진행
// nr_clk: 136
for (idx = 0; idx < nr_clk; idx++, list++) {
// idx: 36,
// list->name: exynos5420_gate_clks[36].name: "sclk_fimd1",
// list->parent_name: exynos5420_gate_clks[36].parent_name: "dout_fimd1",
// list->flags: exynos5420_gate_clks[36].flags: 0x4,
// list->offset: exynos5420_gate_clks[36].offset: 0x10828,
// list->bit_idx: exynos5420_gate_clks[36].bit_idx: 0,
// list->gate_flags: exynos5420_gate_clks[36].gate_flags: 0,
// &lock
// reg_base: 0xf0040000
// clk_register_gate(NULL, "sclk_fimd1", "dout_fimd1", 0x4, 0xf0050828, 0, 0, &lock): kmem_cache#29-oX (sclk_fimd1)
clk = clk_register_gate(NULL, list->name, list->parent_name,
list->flags, reg_base + list->offset,
list->bit_idx, list->gate_flags, &lock);
// clk: kmem_cache#29-oX (sclk_fimd1)
// clk: kmem_cache#29-oX (sclk_fimd1), IS_ERR(kmem_cache#29-oX (sclk_fimd1)): 0
if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n", __func__,
list->name);
continue;
}
/* register a clock lookup only if a clock alias is specified */
// list->alias: exynos5420_gate_clks[36].alias: NULL
if (list->alias) {
ret = clk_register_clkdev(clk, list->alias,
list->dev_name);
if (ret)
pr_err("%s: failed to register lookup %s\n",
__func__, list->alias);
}
// clk: kmem_cache#29-oX (sclk_fimd1), list->id: exynos5420_gate_clks[36].id: 136
samsung_clk_add_lookup(clk, list->id);
- // clk_init_cb: exynos5420_clk_init,
- // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- clk_init_cb(np);
- reg_base = of_iomap(np, 0);
- samsung_clk_init()
- samsung_clk_of_register_fixed_ext()
- samsung_clk_register_pll()
- samsung_clk_register_fixed_rate()
- samsung_clk_register_fixed_factor()
- samsung_clk_register_mux()
- samsung_clk_register_div()
- samsung_clk_register_gate()
- clk = clk_register_gate()
- samsung_clk_add_lookup()
samsung_clk_add_lookup()
-
call: start_kernel()->time_init()->of_clk_init()->exynos5420_clk_init()
- // clk_init_cb: exynos5420_clk_init,
- // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- clk_init_cb(np);
- reg_base = of_iomap(np, 0);
- samsung_clk_init()
- samsung_clk_of_register_fixed_ext()
- samsung_clk_register_pll()
- samsung_clk_register_fixed_rate()
- samsung_clk_register_fixed_factor()
- samsung_clk_register_mux()
- samsung_clk_register_div()
- samsung_clk_register_gate()
- clk = clk_register_gate()
- samsung_clk_add_lookup()
-
saumsung_clk_add_lookup()
// ARM10C 20150307
// clk: kmem_cache#29-oX (sclk_fimd1), list->id: exynos5420_gate_clks[13].id: 128
void samsung_clk_add_lookup(struct clk *clk, unsigned int id)
{
// clk_table: kmem_cache#23-o0, id: 128
if (clk_table && id)
// clk_table: kmem_cache#23-o0, id: 128, clk_table[128]: (kmem_cache#23-o0)[128],
// clk: kmem_cache#29-oX (sclk_fimd1)
clk_table[id] = clk;
// clk_table[128]: (kmem_cache#23-o0)[128]: kmem_cache#29-oX (sclk_fimd1)
}
- return: start_kernel()->time_init()->of_clk_init()->exynos5420_clk_init()
- // clk_init_cb: exynos5420_clk_init,
- // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- clk_init_cb(np);
- reg_base = of_iomap(np, 0);
- samsung_clk_init()
- samsung_clk_of_register_fixed_ext()
- samsung_clk_register_pll()
- samsung_clk_register_fixed_rate()
- samsung_clk_register_fixed_factor()
- samsung_clk_register_mux()
- samsung_clk_register_div()
- samsung_clk_register_gate()
- clk = clk_register_gate()
- samsung_clk_add_lookup()
call: start_kernel()->time_init()->of_clk_init()->exynos5420_clk_init()
- // clk_init_cb: exynos5420_clk_init,
- // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- clk_init_cb(np);
- reg_base = of_iomap(np, 0);
- samsung_clk_init()
- samsung_clk_of_register_fixed_ext()
- samsung_clk_register_pll()
- samsung_clk_register_fixed_rate()
- samsung_clk_register_fixed_factor()
- samsung_clk_register_mux()
- samsung_clk_register_div()
- samsung_clk_register_gate()
- clk = clk_register_gate()
- samsung_clk_add_lookup()
saumsung_clk_add_lookup()
// ARM10C 20150307
// clk: kmem_cache#29-oX (sclk_fimd1), list->id: exynos5420_gate_clks[13].id: 128
void samsung_clk_add_lookup(struct clk *clk, unsigned int id)
{
// clk_table: kmem_cache#23-o0, id: 128
if (clk_table && id)
// clk_table: kmem_cache#23-o0, id: 128, clk_table[128]: (kmem_cache#23-o0)[128],
// clk: kmem_cache#29-oX (sclk_fimd1)
clk_table[id] = clk;
// clk_table[128]: (kmem_cache#23-o0)[128]: kmem_cache#29-oX (sclk_fimd1)
}
- // clk_init_cb: exynos5420_clk_init,
- // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- clk_init_cb(np);
- reg_base = of_iomap(np, 0);
- samsung_clk_init()
- samsung_clk_of_register_fixed_ext()
- samsung_clk_register_pll()
- samsung_clk_register_fixed_rate()
- samsung_clk_register_fixed_factor()
- samsung_clk_register_mux()
- samsung_clk_register_div()
- samsung_clk_register_gate()
- clk = clk_register_gate()
- samsung_clk_add_lookup()
samsung_clk_register_gate()
- return: start_kernel()->time_init()->of_clk_init()->exynos5420_clk_init()
- // clk_init_cb: exynos5420_clk_init,
- // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- clk_init_cb(np);
- reg_base = of_iomap(np, 0);
- samsung_clk_init()
- samsung_clk_of_register_fixed_ext()
- samsung_clk_register_pll()
- samsung_clk_register_fixed_rate()
- samsung_clk_register_fixed_factor()
- samsung_clk_register_mux()
- samsung_clk_register_div()
- samsung_clk_register_gate()
- clk = clk_register_gate()
- samsung_clk_add_lookup()
/* register a list of gate clocks */
// ARM10C 20150307
// exynos5420_gate_clks, ARRAY_SIZE(exynos5420_gate_clks): 136
void __init samsung_clk_register_gate(struct samsung_gate_clock *list,
unsigned int nr_clk)
{
struct clk *clk;
unsigned int idx, ret;
// NOTE:
// exynos5420_gate_clks의 gate 들 중에 array index 36번의
// GATE(sclk_fimd1, "sclk_fimd1", "dout_fimd1", GATE_TOP_SCLK_PERIC, 0, CLK_SET_RATE_PARENT, 0) 을 가지고 분석 진행
// nr_clk: 136
for (idx = 0; idx < nr_clk; idx++, list++) {
// idx: 36,
// list->name: exynos5420_gate_clks[36].name: "sclk_fimd1",
// list->parent_name: exynos5420_gate_clks[36].parent_name: "dout_fimd1",
// list->flags: exynos5420_gate_clks[36].flags: 0x4,
// list->offset: exynos5420_gate_clks[36].offset: 0x10828,
// list->bit_idx: exynos5420_gate_clks[36].bit_idx: 0,
// list->gate_flags: exynos5420_gate_clks[36].gate_flags: 0,
// &lock
// reg_base: 0xf0040000
// clk_register_gate(NULL, "sclk_fimd1", "dout_fimd1", 0x4, 0xf0050828, 0, 0, &lock): kmem_cache#29-oX (sclk_fimd1)
clk = clk_register_gate(NULL, list->name, list->parent_name,
list->flags, reg_base + list->offset,
list->bit_idx, list->gate_flags, &lock);
// clk: kmem_cache#29-oX (sclk_fimd1)
// clk: kmem_cache#29-oX (sclk_fimd1), IS_ERR(kmem_cache#29-oX (sclk_fimd1)): 0
if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n", __func__,
list->name);
continue;
}
/* register a clock lookup only if a clock alias is specified */
// list->alias: exynos5420_gate_clks[36].alias: NULL
if (list->alias) {
ret = clk_register_clkdev(clk, list->alias,
list->dev_name);
if (ret)
pr_err("%s: failed to register lookup %s\n",
__func__, list->alias);
}
// clk: kmem_cache#29-oX (sclk_fimd1), list->id: exynos5420_gate_clks[36].id: 136
samsung_clk_add_lookup(clk, list->id);
- samsung_clk_add_lookup() 에서 한 일:
- // clk_table[136]: (kmem_cache#23-o0)[136]: kmem_cache#29-oX (sclk_fimd1)
- // idx: 0...12...136 loop 수행
- // clk_init_cb: exynos5420_clk_init,
- // np: devtree에서 allnext로 순회 하면서 찾은 clock node의 주소
- // exynos5420_clk_init(devtree에서 allnext로 순회 하면서 찾은 clock node의 주소)
- clk_init_cb(np);
- reg_base = of_iomap(np, 0);
- samsung_clk_init()
- samsung_clk_of_register_fixed_ext()
- samsung_clk_register_pll()
- samsung_clk_register_fixed_rate()
- samsung_clk_register_fixed_factor()
- samsung_clk_register_mux()
- samsung_clk_register_div()
- samsung_clk_register_gate()
- clk = clk_register_gate()
- samsung_clk_add_lookup()
/* register a list of gate clocks */
// ARM10C 20150307
// exynos5420_gate_clks, ARRAY_SIZE(exynos5420_gate_clks): 136
void __init samsung_clk_register_gate(struct samsung_gate_clock *list,
unsigned int nr_clk)
{
struct clk *clk;
unsigned int idx, ret;
// NOTE:
// exynos5420_gate_clks의 gate 들 중에 array index 36번의
// GATE(sclk_fimd1, "sclk_fimd1", "dout_fimd1", GATE_TOP_SCLK_PERIC, 0, CLK_SET_RATE_PARENT, 0) 을 가지고 분석 진행
// nr_clk: 136
for (idx = 0; idx < nr_clk; idx++, list++) {
// idx: 36,
// list->name: exynos5420_gate_clks[36].name: "sclk_fimd1",
// list->parent_name: exynos5420_gate_clks[36].parent_name: "dout_fimd1",
// list->flags: exynos5420_gate_clks[36].flags: 0x4,
// list->offset: exynos5420_gate_clks[36].offset: 0x10828,
// list->bit_idx: exynos5420_gate_clks[36].bit_idx: 0,
// list->gate_flags: exynos5420_gate_clks[36].gate_flags: 0,
// &lock
// reg_base: 0xf0040000
// clk_register_gate(NULL, "sclk_fimd1", "dout_fimd1", 0x4, 0xf0050828, 0, 0, &lock): kmem_cache#29-oX (sclk_fimd1)
clk = clk_register_gate(NULL, list->name, list->parent_name,
list->flags, reg_base + list->offset,
list->bit_idx, list->gate_flags, &lock);
// clk: kmem_cache#29-oX (sclk_fimd1)
// clk: kmem_cache#29-oX (sclk_fimd1), IS_ERR(kmem_cache#29-oX (sclk_fimd1)): 0
if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n", __func__,
list->name);
continue;
}
/* register a clock lookup only if a clock alias is specified */
// list->alias: exynos5420_gate_clks[36].alias: NULL
if (list->alias) {
ret = clk_register_clkdev(clk, list->alias,
list->dev_name);
if (ret)
pr_err("%s: failed to register lookup %s\n",
__func__, list->alias);
}
// clk: kmem_cache#29-oX (sclk_fimd1), list->id: exynos5420_gate_clks[36].id: 136
samsung_clk_add_lookup(clk, list->id);
- // clk_table[136]: (kmem_cache#23-o0)[136]: kmem_cache#29-oX (sclk_fimd1)
- // idx: 0...12...136 loop 수행
93th log
- log
48d2c6a..8dc44c0 master -> origin/master
Updating 48d2c6a..8dc44c0
Fast-forward
arch/arm/kernel/time.c | 401 ++++++++++++++++++++++++
arch/arm/kernel/vmlinux.lds.S | 1 +
drivers/clk/clk-divider.c | 55 +++-
drivers/clk/clk-gate.c | 68 ++++-
drivers/clk/clk.c | 573 ++++++++++++++++++++++++++++++++++-
drivers/clk/samsung/clk-exynos5420.c | 102 +++++++
drivers/clk/samsung/clk.c | 102 +++++++
drivers/clk/samsung/clk.h | 39 +++
drivers/clocksource/arm_arch_timer.c | 16 +
drivers/clocksource/clksrc-of.c | 20 ++
drivers/clocksource/exynos_mct.c | 27 ++
drivers/of/base.c | 41 +++
drivers/of/irq.c | 188 +++++++++---
include/asm-generic/vmlinux.lds.h | 6 +-
include/linux/clk-private.h | 1 +
include/linux/clk-provider.h | 8 +
include/linux/clocksource.h | 3 +-
include/linux/gfp.h | 1 +
include/linux/mod_devicetable.h | 1 +
include/linux/of.h | 10 +-
include/linux/of_irq.h | 1 +
include/linux/slab.h | 2 +
22 files changed, 1622 insertions(+), 44 deletions(-)
48d2c6a..8dc44c0 master -> origin/master
Updating 48d2c6a..8dc44c0
Fast-forward
arch/arm/kernel/time.c | 401 ++++++++++++++++++++++++
arch/arm/kernel/vmlinux.lds.S | 1 +
drivers/clk/clk-divider.c | 55 +++-
drivers/clk/clk-gate.c | 68 ++++-
drivers/clk/clk.c | 573 ++++++++++++++++++++++++++++++++++-
drivers/clk/samsung/clk-exynos5420.c | 102 +++++++
drivers/clk/samsung/clk.c | 102 +++++++
drivers/clk/samsung/clk.h | 39 +++
drivers/clocksource/arm_arch_timer.c | 16 +
drivers/clocksource/clksrc-of.c | 20 ++
drivers/clocksource/exynos_mct.c | 27 ++
drivers/of/base.c | 41 +++
drivers/of/irq.c | 188 +++++++++---
include/asm-generic/vmlinux.lds.h | 6 +-
include/linux/clk-private.h | 1 +
include/linux/clk-provider.h | 8 +
include/linux/clocksource.h | 3 +-
include/linux/gfp.h | 1 +
include/linux/mod_devicetable.h | 1 +
include/linux/of.h | 10 +-
include/linux/of_irq.h | 1 +
include/linux/slab.h | 2 +
22 files changed, 1622 insertions(+), 44 deletions(-)
댓글 없음:
댓글 쓰기