blob: d0ec9e42f7597f9a845452cd0060ceace037eeba [file] [log] [blame]
/*
* 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);