| /* |
| * arch/arm/mach-zx297520v2/zx297520v2-clock.c |
| * |
| * Copyright (C) 2015 ZTE-TSP |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * |
| */ |
| |
| #include <linux/module.h> |
| |
| #include <asm/irq.h> |
| #include <asm/mach/arch.h> |
| #include <asm/mach/map.h> |
| #include <linux/math64.h> |
| |
| #include <linux/clkdev.h> |
| #include <mach/spinlock.h> |
| #include <mach/board.h> |
| #include <mach/iomap.h> |
| #include <linux/clk-private.h> |
| |
| #include "clk.h" |
| |
| #define DEFINE_ZX29_CLK(hwclk,clkops,num,names) \ |
| struct clk * parents_##hwclk[num]; \ |
| static struct clk hwclk##_clk = { \ |
| .name = #hwclk "_clk", \ |
| .hw = &hwclk.hw, \ |
| .ops = &clkops, \ |
| .num_parents = num, \ |
| .parent_names = names, \ |
| .parents = parents_##hwclk, \ |
| .flags = CLK_AUTO_ROUND_PARENT, \ |
| } |
| |
| #define DEFINE_ZX29_CLK_FLAG(hwclk,clkops,num,names, flag) \ |
| struct clk * parents_##hwclk[num]; \ |
| static struct clk hwclk##_clk = { \ |
| .name = #hwclk "_clk", \ |
| .hw = &hwclk.hw, \ |
| .ops = &clkops, \ |
| .num_parents = num, \ |
| .parent_names = names, \ |
| .parents = parents_##hwclk, \ |
| .flags = flag, \ |
| } |
| |
| /* |
| * enable the clk. |
| */ |
| static int zx297520v2_clk_enable(struct clk_hw *hw) |
| { |
| unsigned int data = 0; |
| void __iomem *regaddr = NULL; |
| struct zx29_hwclk *zx29clk = to_zx29_hwclk(hw); |
| |
| if(zx29clk->clk_en_reg.reg_bit_size == 0) |
| return 0; |
| |
| regaddr = zx29clk->clk_en_reg.reg_addr; |
| |
| hw_spin_lock(CLK_HWLOCK); |
| data=ioread32(regaddr); |
| data |= 1<<zx29clk->clk_en_reg.reg_bit_offset; |
| iowrite32(data,regaddr); |
| hw_spin_unlock(CLK_HWLOCK); |
| |
| return 0; |
| } |
| |
| /* |
| * disable the clk. |
| */ |
| static void zx297520v2_clk_disable(struct clk_hw *hw) |
| { |
| unsigned int data = 0; |
| void __iomem *regaddr = NULL; |
| struct zx29_hwclk *zx29clk = to_zx29_hwclk(hw); |
| |
| if(zx29clk->clk_en_reg.reg_bit_size == 0) |
| return ; |
| |
| regaddr = zx29clk->clk_en_reg.reg_addr; |
| |
| hw_spin_lock(CLK_HWLOCK); |
| data=ioread32(regaddr); |
| data &= ~(1<<zx29clk->clk_en_reg.reg_bit_offset); |
| iowrite32(data,regaddr); |
| hw_spin_unlock(CLK_HWLOCK); |
| |
| return ; |
| } |
| |
| /* |
| * get clk's enable state. |
| */ |
| static int zx297520v2_is_enabled(struct clk_hw *hw) |
| { |
| unsigned int data = 0; |
| void __iomem *regaddr = NULL; |
| struct zx29_hwclk *zx29clk = to_zx29_hwclk(hw); |
| |
| if(zx29clk->clk_en_reg.reg_bit_size == 0) |
| return 1; |
| |
| regaddr = zx29clk->clk_en_reg.reg_addr; |
| |
| data=ioread32(regaddr); |
| data>>=zx29clk->clk_en_reg.reg_bit_offset; |
| |
| if(data & 0x1) |
| return 1; |
| else |
| return 0; |
| } |
| |
| /* |
| * set the clk division for new rate. |
| * |
| * new_rate = parent->rate/(clk_div+1) |
| */ |
| static int zx297520v2_clk_set_rate(struct clk_hw *hw, unsigned long new_rate)//, unsigned long parent_rate) |
| { |
| unsigned long parent_rate = 0; |
| unsigned long clk_div = 0; |
| void __iomem *regaddr = NULL; |
| unsigned int data = 0; |
| struct zx29_hwclk *zx29clk = to_zx29_hwclk(hw); |
| |
| if(zx29clk->hw.clk == NULL || zx29clk->hw.clk->parent == NULL) |
| return -EINVAL; |
| if(zx29clk->clk_div_reg.reg_bit_size == 0) |
| return -EINVAL; |
| |
| parent_rate = zx29clk->hw.clk->parent->rate; |
| clk_div = parent_rate/new_rate; |
| /*get the max division*/ |
| if(clk_div >= (1<<zx29clk->clk_div_reg.reg_bit_size)) |
| clk_div = (1<<zx29clk->clk_div_reg.reg_bit_size); |
| |
| if(clk_div) |
| { |
| clk_div--; |
| } |
| |
| regaddr = zx29clk->clk_div_reg.reg_addr; |
| |
| hw_spin_lock(CLK_HWLOCK); |
| data=ioread32(regaddr); |
| data &= ~(((1<<(zx29clk->clk_div_reg.reg_bit_size))-1)<<zx29clk->clk_div_reg.reg_bit_offset); |
| data |= clk_div<<zx29clk->clk_div_reg.reg_bit_offset; |
| iowrite32(data,regaddr); |
| hw_spin_unlock(CLK_HWLOCK); |
| |
| return 0; |
| } |
| |
| /* |
| * get the clk's rate. |
| * |
| * new_rate = parent->rate/(clk_div+1) |
| */ |
| static unsigned long zx297520v2_clk_recalc_rate(struct clk_hw *hw, |
| unsigned long parent_rate) |
| { |
| void __iomem *regaddr = NULL; |
| unsigned int data = 0; |
| struct zx29_hwclk *zx29clk = to_zx29_hwclk(hw); |
| |
| /*if no clk division, return parent's rate */ |
| if(zx29clk->clk_div_reg.reg_bit_size == 0) { |
| if(zx29clk->hw.clk->num_parents) |
| return parent_rate; |
| else |
| return 0; |
| } |
| |
| regaddr = zx29clk->clk_div_reg.reg_addr; |
| |
| data=ioread32(regaddr); |
| data >>= zx29clk->clk_div_reg.reg_bit_offset; |
| data &= ((1<<(zx29clk->clk_div_reg.reg_bit_size))-1); |
| |
| return parent_rate/(data+1); |
| } |
| |
| #if 0 |
| /* |
| * get the clk's rate. |
| * |
| * new_rate = parent->rate/(2^clk_div) |
| */ |
| static unsigned long zx297520v2_clk_recalc_rate_x2(struct clk_hw *hw, |
| unsigned long parent_rate) |
| { |
| void __iomem *regaddr = NULL; |
| unsigned int data = 0; |
| struct zx29_hwclk *zx29clk = to_zx29_hwclk(hw); |
| |
| if(zx29clk->clk_div_reg.reg_bit_size == 0) { |
| if(zx29clk->hw.clk->num_parents) |
| return parent_rate; |
| else |
| return 0; |
| } |
| |
| regaddr = zx29clk->clk_div_reg.reg_addr; |
| |
| data=ioread32(regaddr); |
| data >>= zx29clk->clk_div_reg.reg_bit_offset; |
| data &= ((1<<(zx29clk->clk_div_reg.reg_bit_size))-1); |
| |
| return parent_rate/(0x1<<data); |
| } |
| #endif |
| |
| /* |
| * select parent from given parents. |
| * |
| * index < num_parents |
| */ |
| static int zx297520v2_clk_set_parent(struct clk_hw *hw, u8 index) |
| { |
| void __iomem *regaddr = NULL; |
| unsigned int data = 0; |
| struct zx29_hwclk *zx29clk = to_zx29_hwclk(hw); |
| |
| if(zx29clk->hw.clk->num_parents==0 || index>=zx29clk->hw.clk->num_parents) |
| return -EINVAL; |
| if(zx29clk->clk_sel_reg.reg_bit_size == 0) |
| return 0; |
| |
| regaddr = zx29clk->clk_sel_reg.reg_addr; |
| |
| hw_spin_lock(CLK_HWLOCK); |
| data=ioread32(regaddr); |
| data &= ~(((1<<(zx29clk->clk_sel_reg.reg_bit_size))-1)<<zx29clk->clk_sel_reg.reg_bit_offset); |
| data |= index<<zx29clk->clk_sel_reg.reg_bit_offset; |
| iowrite32(data,regaddr); |
| hw_spin_unlock(CLK_HWLOCK); |
| |
| return 0; |
| } |
| |
| /* |
| * get current parent select. |
| * |
| * return index begin with 0. |
| */ |
| static u8 zx297520v2_get_parent(struct clk_hw *hw) |
| { |
| unsigned int data = 0; |
| void __iomem *regaddr = NULL; |
| struct zx29_hwclk *zx29clk = to_zx29_hwclk(hw); |
| |
| if(zx29clk->hw.clk->num_parents < 2 || zx29clk->clk_sel_reg.reg_bit_size ==0) |
| return 0; |
| |
| regaddr = zx29clk->clk_sel_reg.reg_addr; |
| |
| data = ioread32(regaddr); |
| data >>= zx29clk->clk_sel_reg.reg_bit_offset; |
| data &= (1<<(zx29clk->clk_sel_reg.reg_bit_size))-1; |
| |
| return data; |
| } |
| |
| /* |
| * calc the rate we can support. |
| * |
| * rate: request rate(maybe we can not support exactly) |
| */ |
| static long zx297520v2_clk_round_rate(struct clk_hw *hw, unsigned long rate, |
| unsigned long * best_parent_rate) |
| { |
| unsigned long parent_rate = 0; |
| unsigned long clk_div = 0; |
| struct zx29_hwclk *zx29clk = to_zx29_hwclk(hw); |
| |
| if(zx29clk->hw.clk == NULL || zx29clk->hw.clk->parent == NULL) |
| return 0; |
| // if(zx29clk->clk_div_reg.reg_bit_size == 0) |
| // return 0; |
| |
| parent_rate = zx29clk->hw.clk->parent->rate; |
| clk_div = parent_rate/rate; |
| if(clk_div >= (1<<zx29clk->clk_div_reg.reg_bit_size)) |
| { |
| clk_div = (1<<zx29clk->clk_div_reg.reg_bit_size); |
| } |
| |
| if(!clk_div) |
| return parent_rate; |
| |
| if ((zx29clk->hw.clk->flags & CLK_NO_ODD_DIV) && (clk_div & 0x1) && (clk_div != 0x1)) |
| clk_div++; |
| |
| return parent_rate/(clk_div); |
| } |
| |
| /* |
| * set auto clk gate. |
| * |
| * this only set once when system start. |
| */ |
| static int zx297520v2_set_auto_gate(struct clk_hw *hw, bool enable) |
| { |
| unsigned int data = 0; |
| void __iomem *regaddr = NULL; |
| struct zx29_hwclk *zx29clk = to_zx29_hwclk(hw); |
| |
| if(zx29clk->clk_gate_reg.reg_bit_size == 0) |
| return -EINVAL; |
| |
| regaddr = zx29clk->clk_gate_reg.reg_addr; |
| |
| hw_spin_lock(CLK_HWLOCK); |
| data=ioread32(regaddr); |
| if(enable) |
| data |= 1<<zx29clk->clk_gate_reg.reg_bit_offset; |
| else |
| data &= ~(1<<zx29clk->clk_gate_reg.reg_bit_offset); |
| iowrite32(data,regaddr); |
| hw_spin_unlock(CLK_HWLOCK); |
| |
| return 0; |
| } |
| |
| /************************************************************************** |
| * peripheral clk divider new algorithm |
| * |
| * 1. default algorithm: new_rate = parent_rate/(1+clk_div) |
| * 2. new algorithm: new_rate = parent_rate/(2*(integer_num+(clk_sel+fra_div/fra_base)/2)) |
| * |
| *************************************************************************** |
| */ |
| #define CLK_FRA_DIV(a) (zx_read_reg(a)&0xff) |
| #define CLK_FRA_BASE(a) ((zx_read_reg(a)>>8)&0xff) |
| #define CLK_INTEGER_NUM(a) ((zx_read_reg(a)>>16)&0xff) |
| #define CLK_CLK_SEL(a) ((zx_read_reg(a)>>24)&1) |
| |
| /* |
| {2.0, MIX_CLK_DIVIDER(0, 0xff, 1, 0) }, |
| {2.5, MIX_CLK_DIVIDER(0x7f, 0xff, 1, 0) }, |
| {3.0, MIX_CLK_DIVIDER(0, 0xff, 1, 1) }, |
| {3.5, MIX_CLK_DIVIDER(0x7f, 0xff, 1, 1) }, |
| */ |
| /* d--fra_div b--fra_base n--integer_num s--clk_sel */ |
| #define MIX_CLK_DIVIDER(d,b,n,s) \ |
| (d|(b<<8)|(n<<16)|(s<<24)) |
| |
| #define MAX_CLK_DIVIDER 0x200//(2.0*(0xff+(1.0+0xff/0xff)/2.0)) |
| #define FLOAT_CALC_FACTOR (u64)(1000*1000) |
| |
| static void parase_float_clk_divider(u64 clk_div, |
| unsigned int *fra_div, |
| unsigned int *fra_base, |
| unsigned int *integer_num, |
| unsigned int *clk_sel) |
| { |
| *integer_num = (unsigned int)div64_u64(clk_div, FLOAT_CALC_FACTOR)/2; |
| *clk_sel = (unsigned int)div64_u64(clk_div, FLOAT_CALC_FACTOR)%2; |
| *fra_base = 0xff; |
| *fra_div = (unsigned int)div64_u64((clk_div-*integer_num*FLOAT_CALC_FACTOR*2-*clk_sel*FLOAT_CALC_FACTOR)*255, |
| FLOAT_CALC_FACTOR); |
| } |
| |
| /* |
| * set the clk division for new rate. |
| * |
| */ |
| static int zx297520v2_clk_set_rate_float(struct clk_hw *hw, unsigned long new_rate) |
| { |
| struct zx29_hwclk *zx29clk = to_zx29_hwclk(hw); |
| unsigned int fra_div = 0; |
| unsigned int fra_base = 0; |
| unsigned int integer_num = 0; |
| unsigned int clk_sel = 0; |
| u64 tmp_parent_rate; |
| u64 clk_div = 0; |
| |
| if(zx29clk->hw.clk == NULL || zx29clk->hw.clk->parent == NULL) |
| return -EINVAL; |
| if(zx29clk->clk_div_reg.reg_addr == 0) |
| return -EINVAL; |
| |
| tmp_parent_rate = zx29clk->hw.clk->parent->rate*FLOAT_CALC_FACTOR; |
| clk_div = div64_u64(tmp_parent_rate, new_rate); |
| |
| /*get the max division*/ |
| if(clk_div >= MAX_CLK_DIVIDER*FLOAT_CALC_FACTOR) |
| clk_div = MAX_CLK_DIVIDER*FLOAT_CALC_FACTOR; |
| |
| parase_float_clk_divider(clk_div, &fra_div, &fra_base, &integer_num, &clk_sel); |
| |
| hw_spin_lock(CLK_HWLOCK); |
| zx_write_reg(zx29clk->clk_div_reg.reg_addr, |
| MIX_CLK_DIVIDER(fra_div, fra_base, integer_num, clk_sel)); |
| hw_spin_unlock(CLK_HWLOCK); |
| |
| return 0; |
| } |
| |
| /* |
| * get the clk's rate. |
| * |
| * new_rate = parent_rate/(2*(integer_num+(clk_sel+fra_div/fra_base)/2)) |
| */ |
| static unsigned long zx297520v2_clk_recalc_rate_float(struct clk_hw *hw, |
| unsigned long parent_rate) |
| { |
| void __iomem *regaddr = NULL; |
| struct zx29_hwclk *zx29clk = to_zx29_hwclk(hw); |
| unsigned int fra_div = 0; |
| unsigned int fra_base = 0; |
| unsigned int clk_sel = 0; |
| unsigned int integer_num = 0; |
| u64 tmp_parent_rate = (u64)parent_rate*FLOAT_CALC_FACTOR; |
| u64 clk_div = 0; |
| |
| regaddr = zx29clk->clk_div_reg.reg_addr; |
| |
| /*if no clk division, return parent's rate */ |
| if(regaddr == 0) { |
| if(zx29clk->hw.clk->num_parents) |
| return parent_rate; |
| else |
| return 0; |
| } |
| |
| fra_div = CLK_FRA_DIV(regaddr); |
| fra_base = CLK_FRA_BASE(regaddr); |
| clk_sel = CLK_CLK_SEL(regaddr); |
| integer_num = CLK_INTEGER_NUM(regaddr); |
| |
| clk_div = (2*integer_num+clk_sel)*FLOAT_CALC_FACTOR+div64_u64(fra_div*FLOAT_CALC_FACTOR,fra_base); |
| |
| return (unsigned long)div64_u64(tmp_parent_rate, clk_div); |
| } |
| |
| /* |
| * calc the rate we can support. |
| * |
| * rate: request rate(maybe we can not support exactly) |
| */ |
| static long zx297520v2_clk_round_rate_float(struct clk_hw *hw, unsigned long rate, |
| unsigned long * best_parent_rate) |
| { |
| struct zx29_hwclk *zx29clk = to_zx29_hwclk(hw); |
| u64 tmp_parent_rate; |
| u64 clk_div = 0; |
| |
| if(zx29clk->hw.clk == NULL || zx29clk->hw.clk->parent == NULL) |
| return 0; |
| if(zx29clk->clk_div_reg.reg_addr == 0) |
| return 0; |
| |
| tmp_parent_rate = zx29clk->hw.clk->parent->rate*FLOAT_CALC_FACTOR; |
| clk_div = div64_u64(tmp_parent_rate, rate); |
| |
| if(clk_div >= MAX_CLK_DIVIDER*FLOAT_CALC_FACTOR) |
| clk_div = MAX_CLK_DIVIDER*FLOAT_CALC_FACTOR; |
| |
| if(!clk_div) |
| return (long)div64_u64(tmp_parent_rate, FLOAT_CALC_FACTOR); |
| else |
| return (long)div64_u64(tmp_parent_rate, clk_div); |
| } |
| |
| static int clk_rootclk_enable(struct clk_hw *hw) |
| { |
| return 0; |
| } |
| static void clk_rootclk_disable(struct clk_hw *hw) |
| { |
| return ; |
| } |
| |
| static int clk_rootclk_is_enabled(struct clk_hw *hw) |
| { |
| return 1; |
| } |
| |
| static int clk_rootclk_set_rate(struct clk_hw *hw, unsigned long new_rate)//, unsigned long parent_rate) |
| { |
| return 0; |
| } |
| |
| static struct clk_ops peripheral_clk_ops = |
| { |
| .enable = zx297520v2_clk_enable, |
| .disable = zx297520v2_clk_disable, |
| .set_auto_gate = zx297520v2_set_auto_gate, |
| .set_rate = zx297520v2_clk_set_rate, |
| .recalc_rate = zx297520v2_clk_recalc_rate, |
| .set_parent = zx297520v2_clk_set_parent, |
| .round_rate = zx297520v2_clk_round_rate, |
| .get_parent = zx297520v2_get_parent, |
| .is_enabled = zx297520v2_is_enabled, |
| }; |
| |
| static struct clk_ops peripheral_float_clk_ops = |
| { |
| .enable = zx297520v2_clk_enable, |
| .disable = zx297520v2_clk_disable, |
| .set_auto_gate = zx297520v2_set_auto_gate, |
| .set_rate = zx297520v2_clk_set_rate_float, |
| .recalc_rate = zx297520v2_clk_recalc_rate_float, |
| .set_parent = zx297520v2_clk_set_parent, |
| .round_rate = zx297520v2_clk_round_rate_float, |
| .get_parent = zx297520v2_get_parent, |
| .is_enabled = zx297520v2_is_enabled, |
| }; |
| |
| static struct clk_ops cpu_clk_ops = |
| { |
| .enable = zx297520v2_clk_enable, |
| .disable = zx297520v2_clk_disable, |
| .set_auto_gate = zx297520v2_set_auto_gate, |
| .set_rate = zx297520v2_clk_set_rate, |
| .recalc_rate = zx297520v2_clk_recalc_rate, |
| .set_parent = zx297520v2_clk_set_parent, |
| .round_rate = zx297520v2_clk_round_rate, |
| .get_parent = zx297520v2_get_parent, |
| .is_enabled = zx297520v2_is_enabled, |
| }; |
| |
| struct clk_ops root_clk_ops = { |
| .enable = clk_rootclk_enable, |
| .disable = clk_rootclk_disable, |
| .is_enabled = clk_rootclk_is_enabled, |
| .set_rate = clk_rootclk_set_rate, |
| }; |
| |
| |
| /* |
| * root clk |
| */ |
| DEFINE_ZX29_ROOT_CLK(main_clk_32k, 32768); |
| DEFINE_ZX29_ROOT_CLK(mpll_clk_12m, 12*1000*1000); |
| DEFINE_ZX29_ROOT_CLK(mpll_clk_39m, 39*1000*1000); |
| DEFINE_ZX29_ROOT_CLK(mpll_clk_52m, 52*1000*1000); |
| DEFINE_ZX29_ROOT_CLK(mpll_clk_78m, 78*1000*1000); |
| #if CONFIG_ARCH_ZX297520V2FPGA |
| DEFINE_ZX29_ROOT_CLK(main_clk_26m, 25*1000*1000); |
| DEFINE_ZX29_ROOT_CLK(mpll_clk_104m, 25*1000*1000); |
| #else |
| DEFINE_ZX29_ROOT_CLK(main_clk_26m, 26*1000*1000); |
| DEFINE_ZX29_ROOT_CLK(mpll_clk_104m, 104*1000*1000); |
| #endif |
| DEFINE_ZX29_ROOT_CLK(mpll_clk_124m8, 124800*1000); |
| DEFINE_ZX29_ROOT_CLK(mpll_clk_156m, 156*1000*1000); |
| DEFINE_ZX29_ROOT_CLK(mpll_clk_208m, 208*1000*1000); |
| DEFINE_ZX29_ROOT_CLK(mpll_clk_312m, 312*1000*1000); |
| DEFINE_ZX29_ROOT_CLK(mpll_clk_624m, 624*1000*1000); |
| DEFINE_ZX29_ROOT_CLK(dpll_clk_491m52, 491520*1000); |
| DEFINE_ZX29_ROOT_CLK(dpll_clk_122m88, 122880*1000); |
| DEFINE_ZX29_ROOT_CLK(dpll_clk_81m92, 81920*1000); |
| DEFINE_ZX29_ROOT_CLK(upll_clk_480m, 480*1000*1000); |
| DEFINE_ZX29_ROOT_CLK(upll_clk_96m, 96*1000*1000); |
| DEFINE_ZX29_ROOT_CLK(gpll_clk_25m, 25*1000*1000); |
| DEFINE_ZX29_ROOT_CLK(gpll_clk_50m, 50*1000*1000); |
| DEFINE_ZX29_ROOT_CLK(gpll_clk_100m, 100*1000*1000); |
| DEFINE_ZX29_ROOT_CLK(gpll_clk_178m, 178*1000*1000); |
| DEFINE_ZX29_ROOT_CLK(gpll_clk_200m, 200*1000*1000); |
| |
| |
| /* |
| * a1_uart0 |
| */ |
| char* a1_uart_wclk_parents[2] = |
| { |
| NAME_CLK(mpll_clk_104m), |
| NAME_CLK(main_clk_26m) |
| }; |
| char* lsp_uart_wclk_parents[2] = |
| { |
| NAME_CLK(main_clk_26m), |
| NAME_CLK(mpll_clk_104m) |
| }; |
| static struct zx29_hwclk uart0_apb = |
| { |
| .clk_en_reg ={ZX_TOP_CRM_BASE+0x5C, 13, 1}, |
| .clk_gate_reg ={ZX_TOP_CRM_BASE+0x5C, 14, 1}, |
| }; |
| DEFINE_ZX29_CLK(uart0_apb,peripheral_clk_ops,0,NULL); |
| |
| static struct zx29_hwclk uart0_work = |
| { |
| .clk_en_reg ={ZX_TOP_CRM_BASE+0x5C, 12, 1}, |
| .clk_sel_reg ={ZX_TOP_CRM_BASE+0x40, 2, 1}, |
| .clk_div_reg ={ZX_TOP_CRM_BASE+0x40, 0, 0}, |
| .clk_gate_reg ={ZX_TOP_CRM_BASE+0x5C, 15, 1}, |
| }; |
| DEFINE_ZX29_CLK(uart0_work,peripheral_clk_ops,2,a1_uart_wclk_parents); |
| |
| /* |
| * lsp_uart1 |
| */ |
| static struct zx29_hwclk uart1_apb = |
| { |
| .clk_en_reg ={ZX_LSP_CRPM_BASE+0x28, 0, 1}, |
| .clk_div_reg ={ZX_LSP_CRPM_BASE+0x28, 0, 0}, |
| .clk_gate_reg ={ZX_LSP_CRPM_BASE+0x28, 11, 1}, |
| }; |
| DEFINE_ZX29_CLK(uart1_apb,peripheral_clk_ops,0,NULL); |
| |
| static struct zx29_hwclk uart1_work = |
| { |
| .clk_en_reg ={ZX_LSP_CRPM_BASE+0x28, 1, 1}, |
| .clk_sel_reg ={ZX_LSP_CRPM_BASE+0x28, 4, 1}, |
| .clk_div_reg ={ZX_LSP_CRPM_BASE+0x28, 0, 0}, |
| .clk_gate_reg ={ZX_LSP_CRPM_BASE+0x28, 10, 1}, |
| }; |
| DEFINE_ZX29_CLK(uart1_work,peripheral_clk_ops,2,lsp_uart_wclk_parents); |
| |
| /* |
| * lsp_uart2 |
| */ |
| static struct zx29_hwclk uart2_apb = |
| { |
| .clk_en_reg ={ZX_LSP_CRPM_BASE+0x3c, 0, 1}, |
| .clk_div_reg ={ZX_LSP_CRPM_BASE+0x3c, 0, 0}, |
| .clk_gate_reg ={ZX_LSP_CRPM_BASE+0x3c, 11, 1}, |
| }; |
| DEFINE_ZX29_CLK(uart2_apb,peripheral_clk_ops,0,NULL); |
| |
| static struct zx29_hwclk uart2_work = |
| { |
| .clk_en_reg ={ZX_LSP_CRPM_BASE+0x3c, 1, 1}, |
| .clk_sel_reg ={ZX_LSP_CRPM_BASE+0x3c, 4, 1}, |
| .clk_div_reg ={ZX_LSP_CRPM_BASE+0x3c, 0, 0}, |
| .clk_gate_reg ={ZX_LSP_CRPM_BASE+0x3c, 10, 1}, |
| }; |
| DEFINE_ZX29_CLK(uart2_work,peripheral_clk_ops,2,lsp_uart_wclk_parents); |
| |
| /* |
| * a1_timer1 |
| */ |
| char* a1_timer_wclk_parents[2] = |
| { |
| NAME_CLK(main_clk_26m), |
| NAME_CLK(main_clk_32k) |
| }; |
| char* lsp_timer_wclk_parents[2] = |
| { |
| NAME_CLK(main_clk_32k), |
| NAME_CLK(main_clk_26m) |
| }; |
| static struct zx29_hwclk timer1_apb = |
| { |
| .clk_en_reg ={ZX_TOP_CRM_BASE+0x60, 1, 1}, |
| .clk_gate_reg ={ZX_TOP_CRM_BASE+0x60, 2, 1}, |
| }; |
| DEFINE_ZX29_CLK(timer1_apb,peripheral_clk_ops,0,NULL); |
| |
| static struct zx29_hwclk timer1_work = |
| { |
| .clk_en_reg ={ZX_TOP_CRM_BASE+0x60, 0, 1}, |
| .clk_sel_reg ={ZX_TOP_CRM_BASE+0x44, 0, 1}, |
| .clk_div_reg ={ZX_TOP_CRM_BASE+0x50, 0, 4}, |
| }; |
| DEFINE_ZX29_CLK(timer1_work,peripheral_clk_ops,2,a1_timer_wclk_parents); |
| |
| /* |
| * a1_timer2 |
| */ |
| static struct zx29_hwclk timer2_apb = |
| { |
| .clk_en_reg ={ZX_TOP_CRM_BASE+0x60, 5, 1}, |
| .clk_gate_reg ={ZX_TOP_CRM_BASE+0x60, 6, 1}, |
| }; |
| DEFINE_ZX29_CLK(timer2_apb,peripheral_clk_ops,0,NULL); |
| |
| static struct zx29_hwclk timer2_work = |
| { |
| .clk_en_reg ={ZX_TOP_CRM_BASE+0x60, 4, 1}, |
| .clk_sel_reg ={ZX_TOP_CRM_BASE+0x44, 1, 1}, |
| .clk_div_reg ={ZX_TOP_CRM_BASE+0x50, 4, 4}, |
| }; |
| DEFINE_ZX29_CLK(timer2_work,peripheral_clk_ops,2,a1_timer_wclk_parents); |
| |
| /* |
| * a1_timer3 |
| */ |
| static struct zx29_hwclk timer3_apb = |
| { |
| .clk_en_reg ={ZX_TOP_CRM_BASE+0x60, 9, 1}, |
| .clk_gate_reg ={ZX_TOP_CRM_BASE+0x60, 10, 1}, |
| }; |
| DEFINE_ZX29_CLK(timer3_apb,peripheral_clk_ops,0,NULL); |
| |
| static struct zx29_hwclk timer3_work = |
| { |
| .clk_en_reg ={ZX_TOP_CRM_BASE+0x60, 8, 1}, |
| .clk_sel_reg ={ZX_TOP_CRM_BASE+0x44, 2, 1}, |
| .clk_div_reg ={ZX_TOP_CRM_BASE+0x50, 8, 4}, |
| }; |
| DEFINE_ZX29_CLK(timer3_work,peripheral_clk_ops,2,a1_timer_wclk_parents); |
| |
| /* |
| * lsp_timer0 |
| */ |
| static struct zx29_hwclk timer0_apb = |
| { |
| .clk_en_reg ={ZX_LSP_CRPM_BASE+0x44, 0, 1}, |
| .clk_gate_reg ={ZX_LSP_CRPM_BASE+0x44, 11, 1}, |
| }; |
| DEFINE_ZX29_CLK(timer0_apb,peripheral_clk_ops,0,NULL); |
| |
| static struct zx29_hwclk timer0_work = |
| { |
| .clk_en_reg ={ZX_LSP_CRPM_BASE+0x44, 1, 1}, |
| .clk_sel_reg ={ZX_LSP_CRPM_BASE+0x44, 4, 1}, |
| .clk_div_reg ={ZX_LSP_CRPM_BASE+0x44, 12, 4}, |
| }; |
| DEFINE_ZX29_CLK(timer0_work,peripheral_clk_ops,2,lsp_timer_wclk_parents); |
| |
| /* |
| * lsp_timer4 |
| */ |
| static struct zx29_hwclk timer4_apb = |
| { |
| .clk_en_reg ={ZX_LSP_CRPM_BASE+0x4C, 0, 1}, |
| .clk_gate_reg ={ZX_LSP_CRPM_BASE+0x4C, 11, 1}, |
| }; |
| DEFINE_ZX29_CLK(timer4_apb,peripheral_clk_ops,0,NULL); |
| |
| static struct zx29_hwclk timer4_work = |
| { |
| .clk_en_reg ={ZX_LSP_CRPM_BASE+0x4C, 1, 1}, |
| .clk_sel_reg ={ZX_LSP_CRPM_BASE+0x4C, 4, 1}, |
| .clk_div_reg ={ZX_LSP_CRPM_BASE+0x4C, 12, 4}, |
| }; |
| DEFINE_ZX29_CLK(timer4_work,peripheral_clk_ops,2,lsp_timer_wclk_parents); |
| |
| |
| /************************************************************************** |
| * i2c |
| *************************************************************************** |
| */ |
| char* a1_i2c_wclk_parents[2] = |
| { |
| NAME_CLK(mpll_clk_104m), |
| NAME_CLK(main_clk_26m) |
| }; |
| char* lsp_i2c_wclk_parents[2] = |
| { |
| NAME_CLK(main_clk_26m), |
| NAME_CLK(mpll_clk_104m) |
| }; |
| |
| /* |
| * a1_i2c0 |
| */ |
| static struct zx29_hwclk i2c0_apb = |
| { |
| .clk_en_reg ={ZX_TOP_CRM_BASE+0x54, 8, 1}, |
| .clk_gate_reg ={ZX_TOP_CRM_BASE+0x54, 10, 1}, |
| }; |
| DEFINE_ZX29_CLK(i2c0_apb,peripheral_clk_ops,0,NULL); |
| |
| static struct zx29_hwclk i2c0_work = |
| { |
| .clk_en_reg ={ZX_TOP_CRM_BASE+0x54, 9, 1}, |
| .clk_sel_reg ={ZX_TOP_CRM_BASE+0x3C, 1, 1}, |
| .clk_gate_reg ={ZX_TOP_CRM_BASE+0x54, 11, 1}, |
| }; |
| DEFINE_ZX29_CLK(i2c0_work,peripheral_clk_ops,2,a1_i2c_wclk_parents); |
| /* |
| * lsp_i2c1 |
| */ |
| static struct zx29_hwclk i2c1_apb = |
| { |
| .clk_en_reg ={ZX_LSP_CRPM_BASE+0x2C, 0, 1}, |
| .clk_div_reg ={ZX_LSP_CRPM_BASE+0x2C, 0, 0}, |
| .clk_gate_reg ={ZX_LSP_CRPM_BASE+0x2C, 11, 1}, |
| }; |
| DEFINE_ZX29_CLK(i2c1_apb,peripheral_clk_ops,0,NULL); |
| |
| static struct zx29_hwclk i2c1_work = |
| { |
| .clk_en_reg ={ZX_LSP_CRPM_BASE+0x2C, 1, 1}, |
| .clk_sel_reg ={ZX_LSP_CRPM_BASE+0x2C, 4, 1}, |
| .clk_div_reg ={ZX_LSP_CRPM_BASE+0x2C, 0, 0}, |
| .clk_gate_reg ={ZX_LSP_CRPM_BASE+0x2C, 10, 1}, |
| }; |
| DEFINE_ZX29_CLK(i2c1_work,peripheral_clk_ops,2,lsp_i2c_wclk_parents); |
| |
| /************************************************************************** |
| * ssp |
| *************************************************************************** |
| */ |
| char* lsp_ssp_wclk_parents[3] = |
| { |
| NAME_CLK(mpll_clk_156m), |
| NAME_CLK(mpll_clk_104m), |
| NAME_CLK(main_clk_26m) |
| }; |
| |
| /* |
| * lsp_ssp0 |
| */ |
| static struct zx29_hwclk ssp0_apb = |
| { |
| .clk_en_reg ={ZX_LSP_CRPM_BASE+0x30, 0, 1}, |
| .clk_div_reg ={ZX_LSP_CRPM_BASE+0x30, 0, 0}, |
| .clk_gate_reg ={ZX_LSP_CRPM_BASE+0x30, 11, 1}, |
| }; |
| DEFINE_ZX29_CLK(ssp0_apb,peripheral_clk_ops,0,NULL); |
| |
| static struct zx29_hwclk ssp0_work = |
| { |
| .clk_en_reg ={ZX_LSP_CRPM_BASE+0x30, 1, 1}, |
| .clk_sel_reg ={ZX_LSP_CRPM_BASE+0x30, 4, 2}, |
| .clk_div_reg ={ZX_LSP_CRPM_BASE+0x30, 12, 4}, |
| .clk_gate_reg ={ZX_LSP_CRPM_BASE+0x30, 10, 1}, |
| }; |
| DEFINE_ZX29_CLK_FLAG(ssp0_work,peripheral_clk_ops,3,lsp_ssp_wclk_parents, (CLK_AUTO_ROUND_PARENT | CLK_NO_ODD_DIV)); |
| /* |
| * lsp_ssp1 |
| */ |
| static struct zx29_hwclk ssp1_apb = |
| { |
| .clk_en_reg ={ZX_LSP_CRPM_BASE+0x48, 0, 1}, |
| .clk_div_reg ={ZX_LSP_CRPM_BASE+0x48, 0, 0}, |
| .clk_gate_reg ={ZX_LSP_CRPM_BASE+0x48, 11, 1}, |
| }; |
| DEFINE_ZX29_CLK(ssp1_apb,peripheral_clk_ops,0,NULL); |
| |
| static struct zx29_hwclk ssp1_work = |
| { |
| .clk_en_reg ={ZX_LSP_CRPM_BASE+0x48, 1, 1}, |
| .clk_sel_reg ={ZX_LSP_CRPM_BASE+0x48, 4, 2}, |
| .clk_div_reg ={ZX_LSP_CRPM_BASE+0x48, 12, 4}, |
| .clk_gate_reg ={ZX_LSP_CRPM_BASE+0x48, 10, 1}, |
| }; |
| DEFINE_ZX29_CLK_FLAG(ssp1_work,peripheral_clk_ops,3,lsp_ssp_wclk_parents, (CLK_AUTO_ROUND_PARENT | CLK_NO_ODD_DIV)); |
| |
| /************************************************************************** |
| * ap wdt |
| *************************************************************************** |
| */ |
| char* lsp_wdt_wclk_parents[2] = |
| { |
| NAME_CLK(main_clk_32k), |
| NAME_CLK(main_clk_26m) |
| }; |
| |
| static struct zx29_hwclk ap_wdt_apb = |
| { |
| .clk_en_reg ={ZX_LSP_CRPM_BASE+0x40, 0, 1}, |
| .clk_div_reg ={ZX_LSP_CRPM_BASE+0x40, 0, 0}, |
| .clk_gate_reg ={ZX_LSP_CRPM_BASE+0x40, 11, 1}, |
| }; |
| DEFINE_ZX29_CLK(ap_wdt_apb,peripheral_clk_ops,0,NULL); |
| |
| static struct zx29_hwclk ap_wdt_work = |
| { |
| .clk_en_reg ={ZX_LSP_CRPM_BASE+0x40, 1, 1}, |
| .clk_sel_reg ={ZX_LSP_CRPM_BASE+0x40, 4, 1}, |
| .clk_div_reg ={ZX_LSP_CRPM_BASE+0x40, 12, 4}, |
| .clk_gate_reg ={ZX_LSP_CRPM_BASE+0x40, 10, 1}, |
| }; |
| DEFINE_ZX29_CLK(ap_wdt_work,peripheral_clk_ops,2,lsp_wdt_wclk_parents); |
| |
| /************************************************************************** |
| * tdm |
| *************************************************************************** |
| */ |
| char* lsp_tdm_wclk_parents[3] = |
| { |
| NAME_CLK(dpll_clk_81m92), |
| NAME_CLK(main_clk_26m), |
| NAME_CLK(mpll_clk_104m) |
| }; |
| |
| static struct zx29_hwclk tdm_apb = |
| { |
| .clk_en_reg ={ZX_LSP_CRPM_BASE+0x50, 0, 1}, |
| .clk_div_reg ={ZX_LSP_CRPM_BASE+0x50, 0, 0}, |
| .clk_gate_reg ={ZX_LSP_CRPM_BASE+0x50, 11, 1}, |
| }; |
| DEFINE_ZX29_CLK(tdm_apb,peripheral_clk_ops,0,NULL); |
| |
| static struct zx29_hwclk tdm_work = |
| { |
| .clk_en_reg ={ZX_LSP_CRPM_BASE+0x50, 1, 1}, |
| .clk_sel_reg ={ZX_MATRIX_CRM_BASE+0x50, 0, 0}, |
| .clk_div_reg ={ZX_LSP_CRPM_BASE+0x54, 24, 2}, |
| .clk_gate_reg ={ZX_LSP_CRPM_BASE+0x50, 10, 1}, |
| }; |
| DEFINE_ZX29_CLK(tdm_work,peripheral_float_clk_ops,3,lsp_tdm_wclk_parents); |
| |
| /************************************************************************** |
| * i2s |
| *************************************************************************** |
| */ |
| char* lsp_i2s_wclk_parents[2] = |
| { |
| NAME_CLK(main_clk_26m), |
| NAME_CLK(mpll_clk_104m) |
| }; |
| |
| static struct zx29_hwclk i2s0_apb = |
| { |
| .clk_en_reg ={ZX_LSP_CRPM_BASE+0x14, 0, 1}, |
| .clk_div_reg ={ZX_LSP_CRPM_BASE+0x14, 0, 0}, |
| .clk_gate_reg ={ZX_LSP_CRPM_BASE+0x14, 11, 1}, |
| }; |
| DEFINE_ZX29_CLK(i2s0_apb,peripheral_clk_ops,0,NULL); |
| |
| static struct zx29_hwclk i2s0_work = |
| { |
| .clk_en_reg ={ZX_LSP_CRPM_BASE+0x14, 1, 1}, |
| .clk_sel_reg ={ZX_LSP_CRPM_BASE+0x14, 4, 1}, |
| .clk_div_reg ={ZX_LSP_CRPM_BASE+0x18, 0, 2}, |
| .clk_gate_reg ={ZX_LSP_CRPM_BASE+0x14, 10, 1}, |
| }; |
| DEFINE_ZX29_CLK(i2s0_work,peripheral_float_clk_ops,2,lsp_i2s_wclk_parents); |
| |
| static struct zx29_hwclk i2s1_apb = |
| { |
| .clk_en_reg ={ZX_LSP_CRPM_BASE+0x1C, 0, 1}, |
| .clk_div_reg ={ZX_LSP_CRPM_BASE+0x1C, 0, 0}, |
| .clk_gate_reg ={ZX_LSP_CRPM_BASE+0x1C, 11, 1}, |
| }; |
| DEFINE_ZX29_CLK(i2s1_apb,peripheral_clk_ops,0,NULL); |
| |
| static struct zx29_hwclk i2s1_work = |
| { |
| .clk_en_reg ={ZX_LSP_CRPM_BASE+0x1C, 1, 1}, |
| .clk_sel_reg ={ZX_LSP_CRPM_BASE+0x1C, 4, 1}, |
| .clk_div_reg ={ZX_LSP_CRPM_BASE+0x20, 0, 2}, |
| .clk_gate_reg ={ZX_LSP_CRPM_BASE+0x1C, 10, 1}, |
| }; |
| DEFINE_ZX29_CLK(i2s1_work,peripheral_float_clk_ops,2,lsp_i2s_wclk_parents); |
| |
| /************************************************************************** |
| * spifc |
| *************************************************************************** |
| */ |
| char* lsp_spifc_wclk_parents[] = |
| { |
| NAME_CLK(mpll_clk_156m), |
| NAME_CLK(main_clk_26m), |
| NAME_CLK(mpll_clk_124m8), |
| NAME_CLK(mpll_clk_104m), |
| NAME_CLK(mpll_clk_78m), |
| NAME_CLK(mpll_clk_52m) |
| }; |
| |
| static struct zx29_hwclk spifc_apb = |
| { |
| .clk_en_reg ={ZX_LSP_CRPM_BASE+0x24, 0, 1}, |
| .clk_div_reg ={ZX_LSP_CRPM_BASE+0x24, 0, 0}, |
| .clk_gate_reg ={ZX_LSP_CRPM_BASE+0x24, 11, 1}, |
| }; |
| DEFINE_ZX29_CLK(spifc_apb,peripheral_clk_ops,0,NULL); |
| |
| static struct zx29_hwclk spifc_work = |
| { |
| .clk_en_reg ={ZX_LSP_CRPM_BASE+0x24, 1, 1}, |
| .clk_sel_reg ={ZX_LSP_CRPM_BASE+0x24, 4, 3}, |
| .clk_div_reg ={ZX_LSP_CRPM_BASE+0x24, 0, 0}, |
| .clk_gate_reg ={ZX_LSP_CRPM_BASE+0x24, 10, 1}, |
| }; |
| DEFINE_ZX29_CLK(spifc_work,peripheral_clk_ops,ARRAY_SIZE(lsp_spifc_wclk_parents),lsp_spifc_wclk_parents); |
| |
| /************************************************************************** |
| * kpd |
| *************************************************************************** |
| */ |
| char* kpd_wclk_parents[] = |
| { |
| NAME_CLK(main_clk_32k), |
| }; |
| |
| static struct zx29_hwclk kpd_apb = |
| { |
| .clk_en_reg ={ZX_TOP_CRM_BASE+0x5C, 17, 1}, |
| .clk_div_reg ={ZX_TOP_CRM_BASE+0x5C, 0, 0}, |
| .clk_gate_reg ={ZX_TOP_CRM_BASE+0x5C, 19, 1}, |
| }; |
| DEFINE_ZX29_CLK(kpd_apb,peripheral_clk_ops,0,NULL); |
| |
| static struct zx29_hwclk kpd_work = |
| { |
| .clk_en_reg ={ZX_TOP_CRM_BASE+0x5C, 16, 1}, |
| .clk_sel_reg ={ZX_TOP_CRM_BASE+0x5C, 0, 0}, |
| .clk_div_reg ={ZX_TOP_CRM_BASE+0x5C, 0, 0}, |
| .clk_gate_reg ={ZX_TOP_CRM_BASE+0x5C, 18, 1}, |
| }; |
| DEFINE_ZX29_CLK(kpd_work,peripheral_clk_ops,ARRAY_SIZE(kpd_wclk_parents),kpd_wclk_parents); |
| |
| /************************************************************************** |
| * rtc |
| *************************************************************************** |
| */ |
| char* rtc_wclk_parents[] = |
| { |
| NAME_CLK(main_clk_32k), |
| }; |
| |
| static struct zx29_hwclk rtc_apb = |
| { |
| .clk_en_reg ={ZX_TOP_CRM_BASE+0x54, 0, 1}, |
| |
| }; |
| DEFINE_ZX29_CLK(rtc_apb,peripheral_clk_ops,0,NULL); |
| |
| static struct zx29_hwclk rtc_work = |
| { |
| .clk_en_reg ={ZX_TOP_CRM_BASE+0x54, 1, 1}, |
| }; |
| DEFINE_ZX29_CLK(rtc_work,peripheral_clk_ops,ARRAY_SIZE(rtc_wclk_parents),rtc_wclk_parents); |
| |
| /************************************************************************** |
| * hs_ahb (parent of hsic/usb ahb clk) |
| *************************************************************************** |
| */ |
| char* hs_ahb_parents[] = |
| { |
| NAME_CLK(mpll_clk_104m), |
| NAME_CLK(main_clk_26m), |
| NAME_CLK(mpll_clk_78m), |
| NAME_CLK(mpll_clk_52m), |
| }; |
| static struct zx29_hwclk hs_ahb = |
| { |
| /* .clk_en_reg ={ZX_TOP_CRM_BASE+0x54, 12, 1}, */ |
| .clk_sel_reg ={ZX_TOP_CRM_BASE+0x3C, 4, 2}, |
| }; |
| DEFINE_ZX29_CLK(hs_ahb,peripheral_clk_ops,ARRAY_SIZE(hs_ahb_parents),hs_ahb_parents); |
| |
| /************************************************************************** |
| * usb2.0 |
| *************************************************************************** |
| */ |
| char* usb_12m_parents[] = |
| { |
| NAME_CLK(mpll_clk_12m), |
| }; |
| |
| char* usb_480m_parents[] = |
| { |
| NAME_CLK(upll_clk_480m), |
| }; |
| |
| char* usb_ahb_parents[] = |
| { |
| "hs_ahb_clk", |
| }; |
| static struct zx29_hwclk usb_ahb = |
| { |
| .clk_en_reg ={ZX_TOP_CRM_BASE+0x6C, 4, 1}, |
| }; |
| DEFINE_ZX29_CLK(usb_ahb,peripheral_clk_ops,ARRAY_SIZE(usb_ahb_parents),usb_ahb_parents); |
| |
| static struct zx29_hwclk usb_12m = |
| { |
| .clk_en_reg ={ZX_TOP_CRM_BASE+0x6C, 3, 1}, |
| }; |
| DEFINE_ZX29_CLK(usb_12m,peripheral_clk_ops,ARRAY_SIZE(usb_12m_parents),usb_12m_parents); |
| |
| /************************************************************************** |
| * HSIC |
| ************************************************************************** |
| */ |
| static struct zx29_hwclk hsic_ahb = |
| { |
| .clk_en_reg ={ZX_TOP_CRM_BASE+0x6C, 2, 1}, |
| }; |
| DEFINE_ZX29_CLK(hsic_ahb,peripheral_clk_ops,ARRAY_SIZE(usb_ahb_parents),usb_ahb_parents); |
| |
| static struct zx29_hwclk hsic_12m = |
| { |
| .clk_en_reg ={ZX_TOP_CRM_BASE+0x6C, 1, 1}, |
| }; |
| DEFINE_ZX29_CLK(hsic_12m,peripheral_clk_ops,ARRAY_SIZE(usb_12m_parents),usb_12m_parents); |
| |
| static struct zx29_hwclk hsic_480m = |
| { |
| .clk_en_reg ={ZX_TOP_CRM_BASE+0x6C, 0, 1}, |
| }; |
| DEFINE_ZX29_CLK(hsic_480m,peripheral_clk_ops,ARRAY_SIZE(usb_480m_parents),usb_480m_parents); |
| |
| /************************************************************************** |
| * GMAC |
| ************************************************************************** |
| */ |
| char* gmac_rmii_parents[] = |
| { |
| NAME_CLK(gpll_clk_50m), |
| }; |
| |
| static struct zx29_hwclk gmac_ahb = |
| { |
| .clk_en_reg ={ZX_MATRIX_CRM_BASE+0x110, 2, 1}, |
| }; |
| DEFINE_ZX29_CLK(gmac_ahb,peripheral_clk_ops,ARRAY_SIZE(usb_ahb_parents),usb_ahb_parents); |
| |
| static struct zx29_hwclk gmac_apb = |
| { |
| .clk_en_reg ={ZX_MATRIX_CRM_BASE+0x110, 1, 1}, |
| }; |
| DEFINE_ZX29_CLK(gmac_apb,peripheral_clk_ops,0,NULL); |
| |
| static struct zx29_hwclk gmac_rmii = |
| { |
| .clk_en_reg ={ZX_MATRIX_CRM_BASE+0x110, 0, 1}, |
| }; |
| DEFINE_ZX29_CLK(gmac_rmii,peripheral_clk_ops,ARRAY_SIZE(gmac_rmii_parents),gmac_rmii_parents); |
| |
| /************************************************************************** |
| * SD |
| ************************************************************************** |
| */ |
| char* sd0_work_parents[] = |
| { |
| NAME_CLK(gpll_clk_200m), |
| NAME_CLK(main_clk_26m), |
| NAME_CLK(mpll_clk_156m), |
| NAME_CLK(gpll_clk_100m), |
| NAME_CLK(mpll_clk_78m), |
| NAME_CLK(gpll_clk_50m), |
| NAME_CLK(gpll_clk_178m), |
| NAME_CLK(gpll_clk_25m), |
| |
| }; |
| char* sd1_work_parents[] = |
| { |
| NAME_CLK(gpll_clk_100m), |
| NAME_CLK(main_clk_26m), |
| NAME_CLK(mpll_clk_78m), |
| NAME_CLK(gpll_clk_50m), |
| NAME_CLK(mpll_clk_39m), |
| NAME_CLK(gpll_clk_25m), |
| }; |
| char* sd_cdet_parents[] = |
| { |
| NAME_CLK(main_clk_32k), |
| }; |
| static struct zx29_hwclk sd0_ahb = |
| { |
| .clk_en_reg ={ZX_MATRIX_CRM_BASE+0x54, 12, 1}, |
| .clk_gate_reg ={ZX_MATRIX_CRM_BASE+0x54, 16, 1}, |
| }; |
| DEFINE_ZX29_CLK(sd0_ahb,peripheral_clk_ops,ARRAY_SIZE(usb_ahb_parents),usb_ahb_parents); |
| |
| static struct zx29_hwclk sd0_work = |
| { |
| .clk_en_reg ={ZX_MATRIX_CRM_BASE+0x54, 13, 1}, |
| .clk_sel_reg ={ZX_MATRIX_CRM_BASE+0x50, 4, 3}, |
| .clk_gate_reg ={ZX_MATRIX_CRM_BASE+0x54, 17, 1}, |
| }; |
| DEFINE_ZX29_CLK(sd0_work,peripheral_clk_ops,ARRAY_SIZE(sd0_work_parents),sd0_work_parents); |
| |
| static struct zx29_hwclk sd0_cdet = |
| { |
| .clk_en_reg ={ZX_MATRIX_CRM_BASE+0x54, 14, 1}, |
| }; |
| DEFINE_ZX29_CLK(sd0_cdet,peripheral_clk_ops,ARRAY_SIZE(sd_cdet_parents),sd_cdet_parents); |
| |
| static struct zx29_hwclk sd1_ahb = |
| { |
| .clk_en_reg ={ZX_MATRIX_CRM_BASE+0x54, 4, 1}, |
| .clk_gate_reg ={ZX_MATRIX_CRM_BASE+0x54, 8, 1}, |
| }; |
| DEFINE_ZX29_CLK(sd1_ahb,peripheral_clk_ops,ARRAY_SIZE(usb_ahb_parents),usb_ahb_parents); |
| |
| static struct zx29_hwclk sd1_work = |
| { |
| .clk_en_reg ={ZX_MATRIX_CRM_BASE+0x54, 5, 1}, |
| .clk_sel_reg ={ZX_MATRIX_CRM_BASE+0x50, 8, 3}, |
| .clk_gate_reg ={ZX_MATRIX_CRM_BASE+0x54, 9, 1}, |
| }; |
| DEFINE_ZX29_CLK(sd1_work,peripheral_clk_ops,ARRAY_SIZE(sd1_work_parents),sd1_work_parents); |
| |
| static struct zx29_hwclk sd1_cdet = |
| { |
| .clk_en_reg ={ZX_MATRIX_CRM_BASE+0x54, 6, 1}, |
| }; |
| DEFINE_ZX29_CLK(sd1_cdet,peripheral_clk_ops,ARRAY_SIZE(sd_cdet_parents),sd_cdet_parents); |
| /* |
| * axi |
| * |
| * can select 156/26/122.88/104/78/52/39 |
| * can not div |
| */ |
| char* axi_clk_parents[] = |
| { |
| NAME_CLK(mpll_clk_156m), |
| NAME_CLK(main_clk_26m), |
| NAME_CLK(dpll_clk_122m88), |
| NAME_CLK(mpll_clk_104m), |
| NAME_CLK(mpll_clk_78m), |
| NAME_CLK(mpll_clk_52m), |
| NAME_CLK(mpll_clk_39m) |
| }; |
| static struct zx29_hwclk axi = { |
| /* reg_addr bit_offset bit_size */ |
| .clk_en_reg ={0, 0, 0}, |
| .clk_sel_reg={ZX_MATRIX_CRM_BASE+0x0, 0, 3}, |
| .clk_div_reg={0, 0, 0}, |
| }; |
| |
| DEFINE_ZX29_CLK(axi,peripheral_clk_ops,ARRAY_SIZE(axi_clk_parents),axi_clk_parents); |
| |
| /* |
| * ap cpu |
| * |
| * can select 26/52/78/104/208/312/491.52/624 |
| * can not div, gated with hw |
| */ |
| char* cpu_clk_parents[] = |
| { |
| NAME_CLK(mpll_clk_624m), |
| NAME_CLK(main_clk_26m), |
| NAME_CLK(dpll_clk_491m52), |
| NAME_CLK(mpll_clk_312m), |
| NAME_CLK(mpll_clk_208m), |
| NAME_CLK(mpll_clk_104m), |
| NAME_CLK(mpll_clk_78m), |
| NAME_CLK(mpll_clk_52m) |
| }; |
| static struct zx29_hwclk cpu_work = { |
| /* reg_addr bit_offset bit_size */ |
| .clk_en_reg ={0, 0, 0}, |
| .clk_sel_reg={ZX_MATRIX_CRM_BASE+0x40, 0, 3}, |
| .clk_div_reg={0, 0, 0}, |
| }; |
| DEFINE_ZX29_CLK(cpu_work,cpu_clk_ops,ARRAY_SIZE(cpu_clk_parents),cpu_clk_parents); |
| |
| /*for zx297520v2, we do not operate pll and global resource, |
| we only support periph_clocks and clk source select */ |
| struct clk_lookup periph_clocks_lookups[] = { |
| /* dev_id name clk struct */ |
| CLK_ZX29_CONFIG(NULL, NAME_CLK(main_clk_32k), &main_clk_32k), |
| CLK_ZX29_CONFIG(NULL, NAME_CLK(main_clk_26m), &main_clk_26m), |
| CLK_ZX29_CONFIG(NULL, NAME_CLK(mpll_clk_12m), &mpll_clk_12m), |
| CLK_ZX29_CONFIG(NULL, NAME_CLK(mpll_clk_39m), &mpll_clk_39m), |
| CLK_ZX29_CONFIG(NULL, NAME_CLK(mpll_clk_52m), &mpll_clk_52m), |
| CLK_ZX29_CONFIG(NULL, NAME_CLK(mpll_clk_78m), &mpll_clk_78m), |
| CLK_ZX29_CONFIG(NULL, NAME_CLK(mpll_clk_104m), &mpll_clk_104m), |
| CLK_ZX29_CONFIG(NULL, NAME_CLK(mpll_clk_124m8), &mpll_clk_124m8), |
| CLK_ZX29_CONFIG(NULL, NAME_CLK(mpll_clk_156m), &mpll_clk_156m), |
| CLK_ZX29_CONFIG(NULL, NAME_CLK(mpll_clk_208m), &mpll_clk_208m), |
| CLK_ZX29_CONFIG(NULL, NAME_CLK(mpll_clk_312m), &mpll_clk_312m), |
| CLK_ZX29_CONFIG(NULL, NAME_CLK(mpll_clk_624m), &mpll_clk_624m), |
| CLK_ZX29_CONFIG(NULL, NAME_CLK(dpll_clk_491m52), &dpll_clk_491m52), |
| CLK_ZX29_CONFIG(NULL, NAME_CLK(dpll_clk_122m88), &dpll_clk_122m88), |
| CLK_ZX29_CONFIG(NULL, NAME_CLK(dpll_clk_81m92), &dpll_clk_81m92), |
| CLK_ZX29_CONFIG(NULL, NAME_CLK(upll_clk_480m), &upll_clk_480m), |
| CLK_ZX29_CONFIG(NULL, NAME_CLK(upll_clk_96m), &upll_clk_96m), |
| CLK_ZX29_CONFIG(NULL, NAME_CLK(gpll_clk_25m), &gpll_clk_25m), |
| CLK_ZX29_CONFIG(NULL, NAME_CLK(gpll_clk_50m), &gpll_clk_50m), |
| CLK_ZX29_CONFIG(NULL, NAME_CLK(gpll_clk_100m), &gpll_clk_100m), |
| CLK_ZX29_CONFIG(NULL, NAME_CLK(gpll_clk_178m), &gpll_clk_178m), |
| CLK_ZX29_CONFIG(NULL, NAME_CLK(gpll_clk_200m), &gpll_clk_200m), |
| |
| |
| CLK_ZX29_CONFIG(NULL, "axi_clk", &axi_clk), |
| |
| CLK_ZX29_CONFIG(NULL, "cpu_clk", &cpu_work_clk), |
| |
| CLK_ZX29_CONFIG(NULL, "hs_ahb_clk", &hs_ahb_clk), |
| |
| CLK_ZX29_CONFIG("zx29_ap_wdt.0", "work_clk", &ap_wdt_work_clk), |
| CLK_ZX29_CONFIG("zx29_ap_wdt.0", "apb_clk", &ap_wdt_apb_clk), |
| |
| CLK_ZX29_CONFIG("zx29_uart.0", "work_clk", &uart0_work_clk), |
| CLK_ZX29_CONFIG("zx29_uart.0", "apb_clk", &uart0_apb_clk), |
| CLK_ZX29_CONFIG("zx29_uart.1", "work_clk", &uart1_work_clk), |
| CLK_ZX29_CONFIG("zx29_uart.1", "apb_clk", &uart1_apb_clk), |
| CLK_ZX29_CONFIG("zx29_uart.2", "work_clk", &uart2_work_clk), |
| CLK_ZX29_CONFIG("zx29_uart.2", "apb_clk", &uart2_apb_clk), |
| |
| CLK_ZX29_CONFIG("zx29_ap_timer0", "work_clk", &timer0_work_clk), |
| CLK_ZX29_CONFIG("zx29_ap_timer0", "apb_clk", &timer0_apb_clk), |
| CLK_ZX29_CONFIG("zx29_ap_timer1", "work_clk", &timer1_work_clk), |
| CLK_ZX29_CONFIG("zx29_ap_timer1", "apb_clk", &timer1_apb_clk), |
| CLK_ZX29_CONFIG("zx29_ap_timer2", "work_clk", &timer2_work_clk), |
| CLK_ZX29_CONFIG("zx29_ap_timer2", "apb_clk", &timer2_apb_clk), |
| CLK_ZX29_CONFIG("zx29_ap_timer3", "work_clk", &timer3_work_clk), |
| CLK_ZX29_CONFIG("zx29_ap_timer3", "apb_clk", &timer3_apb_clk), |
| CLK_ZX29_CONFIG("zx29_ap_timer4", "work_clk", &timer4_work_clk), |
| CLK_ZX29_CONFIG("zx29_ap_timer4", "apb_clk", &timer4_apb_clk), |
| |
| CLK_ZX29_CONFIG("zx29_i2c.0", "work_clk", &i2c0_work_clk), |
| CLK_ZX29_CONFIG("zx29_i2c.0", "apb_clk", &i2c0_apb_clk), |
| CLK_ZX29_CONFIG("zx29_i2c.1", "work_clk", &i2c1_work_clk), |
| CLK_ZX29_CONFIG("zx29_i2c.1", "apb_clk", &i2c1_apb_clk), |
| |
| CLK_ZX29_CONFIG("zx29_ssp.0", "work_clk", &ssp0_work_clk), |
| CLK_ZX29_CONFIG("zx29_ssp.0", "apb_clk", &ssp0_apb_clk), |
| CLK_ZX29_CONFIG("zx29_ssp.1", "work_clk", &ssp1_work_clk), |
| CLK_ZX29_CONFIG("zx29_ssp.1", "apb_clk", &ssp1_apb_clk), |
| |
| CLK_ZX29_CONFIG("zx29_tdm.0", "work_clk", &tdm_work_clk), |
| CLK_ZX29_CONFIG("zx29_tdm.0", "apb_clk", &tdm_apb_clk), |
| |
| CLK_ZX29_CONFIG("zx29_i2s.0", "work_clk", &i2s0_work_clk), |
| CLK_ZX29_CONFIG("zx29_i2s.0", "apb_clk", &i2s0_apb_clk), |
| CLK_ZX29_CONFIG("zx29_i2s.1", "work_clk", &i2s1_work_clk), |
| CLK_ZX29_CONFIG("zx29_i2s.1", "apb_clk", &i2s1_apb_clk), |
| |
| CLK_ZX29_CONFIG("zx29_spifc.0", "work_clk", &spifc_work_clk), |
| CLK_ZX29_CONFIG("zx29_spifc.0", "apb_clk", &spifc_apb_clk), |
| |
| CLK_ZX29_CONFIG("zx29_kpd.0", "work_clk", &kpd_work_clk), |
| CLK_ZX29_CONFIG("zx29_kpd.0", "apb_clk", &kpd_apb_clk), |
| |
| CLK_ZX29_CONFIG("zx29_rtc.0", "work_clk", &rtc_work_clk), |
| CLK_ZX29_CONFIG("zx29_rtc.0", "apb_clk", &rtc_apb_clk), |
| |
| CLK_ZX29_CONFIG("zx29_usb.0", "ahb_clk", &usb_ahb_clk), |
| CLK_ZX29_CONFIG("zx29_usb.0", "12m_clk", &usb_12m_clk), |
| |
| CLK_ZX29_CONFIG("zx29_hsic.0", "ahb_clk", &hsic_ahb_clk), |
| CLK_ZX29_CONFIG("zx29_hsic.0", "12m_clk", &hsic_12m_clk), |
| CLK_ZX29_CONFIG("zx29_hsic.0", "480m_clk", &hsic_480m_clk), |
| |
| CLK_ZX29_CONFIG("zx29_gmac.0", "ahb_clk", &gmac_ahb_clk), |
| CLK_ZX29_CONFIG("zx29_gmac.0", "apb_clk", &gmac_apb_clk), |
| CLK_ZX29_CONFIG("zx29_gmac.0", "rmii_clk", &gmac_rmii_clk), |
| |
| CLK_ZX29_CONFIG("zx29_sd.0", "ahb_clk", &sd0_ahb_clk), |
| CLK_ZX29_CONFIG("zx29_sd.0", "work_clk", &sd0_work_clk), |
| CLK_ZX29_CONFIG("zx29_sd.0", "cdet_clk", &sd0_cdet_clk), |
| |
| CLK_ZX29_CONFIG("zx29_sd.1", "ahb_clk", &sd1_ahb_clk), |
| CLK_ZX29_CONFIG("zx29_sd.1", "work_clk", &sd1_work_clk), |
| CLK_ZX29_CONFIG("zx29_sd.1", "cdet_clk", &sd1_cdet_clk), |
| |
| //wifi_bt |
| }; |
| |
| unsigned int periph_clocks_lookups_num=ARRAY_SIZE(periph_clocks_lookups); |
| |