blob: 7c2191ae8959b88b899bf1393deebc1fa80bd8f4 [file] [log] [blame]
#include <linux/string.h>
#include "cmucal.h"
#define get_node(list, idx) (GET_IDX(list[idx].id) == idx ? \
&list[idx] : NULL)
#define get_clk_node(list, idx) (GET_IDX(list[idx].clk.id) == idx ? \
&list[idx] : NULL)
extern struct cmucal_clk_fixed_rate cmucal_fixed_rate_list[];
extern struct cmucal_clk_fixed_factor cmucal_fixed_factor_list[];
extern struct cmucal_pll cmucal_pll_list[];
extern struct cmucal_mux cmucal_mux_list[];
extern struct cmucal_div cmucal_div_list[];
extern struct cmucal_gate cmucal_gate_list[];
extern struct cmucal_qch cmucal_qch_list[];
extern struct cmucal_option cmucal_option_list[];
extern struct sfr_block cmucal_sfr_block_list[];
extern struct sfr cmucal_sfr_list[];
extern struct sfr_access cmucal_sfr_access_list[];
extern struct vclk cmucal_vclk_list[];
extern struct vclk acpm_vclk_list[];
extern struct cmucal_clkout cmucal_clkout_list[];
extern unsigned int cmucal_fixed_rate_size;
extern unsigned int cmucal_fixed_factor_size;
extern unsigned int cmucal_pll_size;
extern unsigned int cmucal_mux_size;
extern unsigned int cmucal_div_size;
extern unsigned int cmucal_gate_size;
extern unsigned int cmucal_qch_size;
extern unsigned int cmucal_option_size;
extern unsigned int cmucal_sfr_block_size;
extern unsigned int cmucal_sfr_size;
extern unsigned int cmucal_sfr_access_size;
extern unsigned int cmucal_vclk_size;
extern unsigned int acpm_vclk_size;
extern unsigned int cmucal_clkout_size;
unsigned int cmucal_get_list_size(unsigned int type)
{
switch (type) {
case FIXED_RATE_TYPE:
return cmucal_fixed_rate_size;
case FIXED_FACTOR_TYPE:
return cmucal_fixed_factor_size;
case PLL_TYPE:
return cmucal_pll_size;
case MUX_TYPE:
return cmucal_mux_size;
case DIV_TYPE:
return cmucal_div_size;
case GATE_TYPE:
return cmucal_gate_size;
case QCH_TYPE:
return cmucal_qch_size;
case OPTION_TYPE:
return cmucal_option_size;
case SFR_BLOCK_TYPE:
return cmucal_sfr_block_size;
case SFR_TYPE:
return cmucal_sfr_size;
case SFR_ACCESS_TYPE:
return cmucal_sfr_access_size;
case VCLK_TYPE:
return cmucal_vclk_size;
case CLKOUT_TYPE:
return cmucal_clkout_size;
case ACPM_VCLK_TYPE:
return acpm_vclk_size;
default:
pr_info("unsupport cmucal type %x\n", type);
}
return 0;
}
EXPORT_SYMBOL_GPL(cmucal_get_list_size);
void *cmucal_get_node(unsigned int id)
{
unsigned int type = GET_TYPE(id);
unsigned short idx = GET_IDX(id);
void *node = NULL;
switch (type) {
case FIXED_RATE_TYPE:
node = get_clk_node(cmucal_fixed_rate_list, idx);
break;
case FIXED_FACTOR_TYPE:
node = get_clk_node(cmucal_fixed_factor_list, idx);
break;
case PLL_TYPE:
node = get_clk_node(cmucal_pll_list, idx);
break;
case MUX_TYPE:
node = get_clk_node(cmucal_mux_list, idx);
break;
case DIV_TYPE:
node = get_clk_node(cmucal_div_list, idx);
break;
case GATE_TYPE:
node = get_clk_node(cmucal_gate_list, idx);
break;
case QCH_TYPE:
node = get_clk_node(cmucal_qch_list, idx);
break;
case OPTION_TYPE:
node = get_clk_node(cmucal_option_list, idx);
break;
case CLKOUT_TYPE:
node = get_clk_node(cmucal_clkout_list, idx);
break;
case VCLK_TYPE:
if (IS_ACPM_VCLK(id))
node = get_node(acpm_vclk_list, idx);
else
node = get_node(cmucal_vclk_list, idx);
break;
default:
pr_info("unsupport cmucal node %x\n", id);
}
return node;
}
EXPORT_SYMBOL_GPL(cmucal_get_node);
void * __init cmucal_get_sfr_node(unsigned int id)
{
unsigned int type = GET_TYPE(id);
unsigned short idx = GET_IDX(id);
void *node = NULL;
switch (type) {
case SFR_BLOCK_TYPE:
node = get_node(cmucal_sfr_block_list, idx);
break;
case SFR_TYPE:
node = get_node(cmucal_sfr_list, idx);
break;
case SFR_ACCESS_TYPE:
node = get_node(cmucal_sfr_access_list, idx);
break;
default:
pr_info("unsupport cmucal sfr node %x\n", id);
}
return node;
}
EXPORT_SYMBOL_GPL(cmucal_get_sfr_node);
unsigned int cmucal_get_id(char *name)
{
unsigned int id = INVALID_CLK_ID;
int i;
if (strstr(name, "MUX") || strstr(name, "MOUT")) {
for (i = 0; i < cmucal_mux_size; i++)
if (!strcmp(name, cmucal_mux_list[i].clk.name)) {
id = cmucal_mux_list[i].clk.id;
return id;
}
}
if (strstr(name, "GATE") || strstr(name, "GOUT") || strstr(name, "CLK_BLK")) {
for (i = 0; i < cmucal_gate_size; i++)
if (!strcmp(name, cmucal_gate_list[i].clk.name)) {
id = cmucal_gate_list[i].clk.id;
return id;
}
}
if (strstr(name, "DIV") || strstr(name, "DOUT") || strstr(name, "CLKCMU")) {
for (i = 0; i < cmucal_div_size; i++)
if (!strcmp(name, cmucal_div_list[i].clk.name)) {
id = cmucal_div_list[i].clk.id;
return id;
}
for (i = 0; i < cmucal_fixed_factor_size; i++)
if (!strcmp(name, cmucal_fixed_factor_list[i].clk.name)) {
id = cmucal_fixed_factor_list[i].clk.id;
return id;
}
}
if (strstr(name, "VCLK") || strstr(name, "dvfs")) {
for (i = 0; i < cmucal_vclk_size; i++)
if (!strcmp(name, cmucal_vclk_list[i].name)) {
id = cmucal_vclk_list[i].id;
return id;
}
}
if (strstr(name, "PLL")) {
for (i = 0; i < cmucal_pll_size; i++)
if (!strcmp(name, cmucal_pll_list[i].clk.name)) {
id = cmucal_pll_list[i].clk.id;
return id;
}
}
if (strstr(name, "IO") || strstr(name, "OSC")) {
for (i = 0; i < cmucal_pll_size; i++)
if (!strcmp(name, cmucal_fixed_rate_list[i].clk.name)) {
id = cmucal_fixed_rate_list[i].clk.id;
return id;
}
}
return id;
}
EXPORT_SYMBOL_GPL(cmucal_get_id);
unsigned int cmucal_get_id_by_addr(unsigned int addr)
{
unsigned int id = INVALID_CLK_ID;
unsigned int type;
int i;
type = addr & 0x3F00;
if (type == 0x1800 || type == 0x1900) {
/* DIV */
for (i = 0; i < cmucal_div_size; i++)
if (addr == cmucal_div_list[i].clk.paddr) {
id = cmucal_div_list[i].clk.id;
return id;
}
} else if (type == 0x1000 || type == 0x1100) {
/* MUX */
for (i = 0; i < cmucal_mux_size; i++)
if (addr == cmucal_mux_list[i].clk.paddr) {
id = cmucal_mux_list[i].clk.id;
return id;
}
} else if (type == 0x2000 || type == 0x2100) {
/* GATE */
for (i = 0; i < cmucal_gate_size; i++)
if (addr == cmucal_gate_list[i].clk.paddr) {
id = cmucal_gate_list[i].clk.id;
return id;
}
} else {
/* PLL */
for (i = 0; i < cmucal_pll_size; i++)
if (addr == cmucal_pll_list[i].clk.paddr) {
id = cmucal_pll_list[i].clk.id;
return id;
}
/* USER_MUX */
for (i = 0; i < cmucal_mux_size; i++)
if (addr == cmucal_mux_list[i].clk.paddr) {
id = cmucal_mux_list[i].clk.id;
return id;
}
}
return id;
}
EXPORT_SYMBOL_GPL(cmucal_get_id_by_addr);