824 lines
17 KiB
C
824 lines
17 KiB
C
/*
|
|
* GSC3280 SoC Clock Controller Driver
|
|
*
|
|
* Copyright (C) 2013 BLX IC Design Corp.,Ltd.
|
|
* Author: LiuJianhua <liujianhua@china-cpu.com>
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU General Public
|
|
* License. See the file "COPYING" in the main directory of this archive
|
|
* for more details.
|
|
*/
|
|
|
|
#include <linux/cpufreq.h>
|
|
#include <linux/platform_device.h>
|
|
|
|
//#include <asm/clock.h>
|
|
#include <gsc3280/sysctl.h>
|
|
|
|
#include <loongson.h>
|
|
static LIST_HEAD(clock_list);
|
|
static unsigned long ref_clk=12*1000*1000;
|
|
static unsigned long sysctl_base;
|
|
|
|
extern void serial_get_clk(void);
|
|
|
|
struct clk
|
|
{
|
|
char name[32];
|
|
short mod;
|
|
unsigned short div_offset;
|
|
unsigned int max_div;
|
|
int iomux;
|
|
|
|
struct list_head list;
|
|
struct clk *parent;
|
|
|
|
unsigned long (*get_rate)(struct clk *clk);
|
|
unsigned long (*set_rate)(struct clk *clk, unsigned long rate);
|
|
};
|
|
|
|
unsigned long pll_get_rate(struct clk *clk);
|
|
unsigned long pll_set_rate(struct clk *clk, unsigned long rate);
|
|
|
|
unsigned long integral_get_rate(struct clk *clk);
|
|
unsigned long integral_set_rate(struct clk *clk, unsigned long rate);
|
|
|
|
unsigned long even_get_rate(struct clk *clk);
|
|
unsigned long even_set_rate(struct clk *clk, unsigned long rate);
|
|
|
|
unsigned long same_get_rate(struct clk *clk);
|
|
unsigned long same_set_rate(struct clk *clk, unsigned long rate);
|
|
|
|
unsigned long aclk_get_rate(struct clk *clk);
|
|
unsigned long aclk_set_rate(struct clk *clk, unsigned long rate);
|
|
unsigned long cpu_set_rate(struct clk *clk, unsigned long rate);
|
|
|
|
|
|
static struct clk pll =
|
|
{
|
|
.name = "pll",
|
|
//.flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES,
|
|
.mod = -1,
|
|
.iomux = -1,
|
|
.get_rate = pll_get_rate,
|
|
.set_rate = pll_set_rate,
|
|
};
|
|
static struct clk pll_clkout =
|
|
{
|
|
.name = "pll_clkout",
|
|
.div_offset = 0x94,
|
|
.max_div = 512,
|
|
.mod = SYSCTL_MOD_CLKOUT,
|
|
.iomux = SYSCTL_IOMUX_CLKOUT,
|
|
.get_rate = integral_get_rate,
|
|
.set_rate = integral_set_rate,
|
|
};
|
|
static struct clk aclk =
|
|
{
|
|
.name = "aclk",
|
|
.mod = -1,
|
|
.iomux = -1,
|
|
.get_rate = aclk_get_rate,
|
|
.set_rate = aclk_set_rate,
|
|
};
|
|
static struct clk cpu =
|
|
{
|
|
.name = "cpu",
|
|
.mod = -1,
|
|
.iomux = -1,
|
|
.get_rate = aclk_get_rate,
|
|
.set_rate = cpu_set_rate,
|
|
};
|
|
static struct clk ddr2 =
|
|
{
|
|
.name = "ddr2",
|
|
.mod = SYSCTL_MOD_DDR2,
|
|
.iomux = -1,
|
|
.get_rate = aclk_get_rate,
|
|
.set_rate = aclk_set_rate,
|
|
};
|
|
static struct clk hclk =
|
|
{
|
|
.name = "hclk",
|
|
.div_offset = 0x18,
|
|
.max_div = 8,
|
|
.iomux = -1,
|
|
.get_rate = integral_get_rate,
|
|
.set_rate = integral_set_rate,
|
|
};
|
|
static struct clk sdio =
|
|
{
|
|
.name = "sdio",
|
|
.div_offset = 0x20,
|
|
.max_div = 64,
|
|
.mod = SYSCTL_MOD_SDIO,
|
|
.iomux = SYSCTL_IOMUX_SDIO,
|
|
.get_rate = even_get_rate,
|
|
.set_rate = even_set_rate,
|
|
};
|
|
static struct clk lcdc =
|
|
{
|
|
.name = "lcd",
|
|
.div_offset = 0x24,
|
|
.max_div = 64,
|
|
.mod = SYSCTL_MOD_LCDC,
|
|
.iomux = SYSCTL_IOMUX_LCDC,
|
|
.get_rate = integral_get_rate,
|
|
.set_rate = integral_set_rate,
|
|
|
|
};
|
|
static struct clk ddr2phy =
|
|
{
|
|
.name = "ddr2phy",
|
|
.mod = -1,
|
|
.iomux = -1,
|
|
.get_rate = same_get_rate,
|
|
.set_rate = same_set_rate,
|
|
};
|
|
static struct clk i2s =
|
|
{
|
|
.name = "i2s",
|
|
.div_offset = 0x2c,
|
|
.max_div = 32,
|
|
.mod = SYSCTL_MOD_I2S,
|
|
.iomux = SYSCTL_IOMUX_I2S,
|
|
.get_rate = integral_get_rate,
|
|
.set_rate = integral_set_rate,
|
|
};
|
|
static struct clk i2c =
|
|
{
|
|
.name = "i2c",
|
|
.div_offset = 0x28,
|
|
.max_div = 64,
|
|
.mod = SYSCTL_MOD_I2C,
|
|
.iomux = SYSCTL_IOMUX_I2C,
|
|
.get_rate = integral_get_rate,
|
|
.set_rate = integral_set_rate,
|
|
};
|
|
|
|
static struct clk spi1 =
|
|
{
|
|
.name = "spi1",
|
|
.div_offset = 0x38,
|
|
.max_div = 64,
|
|
.mod = SYSCTL_MOD_SPI1,
|
|
.iomux = SYSCTL_IOMUX_SPI1,
|
|
.get_rate = integral_get_rate,
|
|
.set_rate = integral_set_rate,
|
|
};
|
|
# if 0
|
|
static struct clk misc =
|
|
{
|
|
.name = "misc",
|
|
.mod = -1,
|
|
.get_rate = same_get_rate,
|
|
.set_rate = same_set_rate,
|
|
};
|
|
#endif
|
|
static struct clk dma =
|
|
{
|
|
.name = "dma",
|
|
.mod = SYSCTL_MOD_DMA,
|
|
.iomux = -1,
|
|
.get_rate = same_get_rate,
|
|
.set_rate = same_set_rate,
|
|
};
|
|
static struct clk ictl =
|
|
{
|
|
.name = "ictl",
|
|
.mod = SYSCTL_MOD_ICTL,
|
|
.iomux = -1,
|
|
.get_rate = same_get_rate,
|
|
.set_rate = same_set_rate,
|
|
};
|
|
static struct clk nfc =
|
|
{
|
|
.name = "nfc",
|
|
.mod = SYSCTL_MOD_NFC,
|
|
.iomux = SYSCTL_IOMUX_NFC,
|
|
.get_rate = same_get_rate,
|
|
.set_rate = same_set_rate,
|
|
};
|
|
static struct clk sysctl =
|
|
{
|
|
.name = "sysctl",
|
|
.mod = SYSCTL_MOD_SYSCTL,
|
|
.iomux = -1,
|
|
.get_rate = same_get_rate,
|
|
.set_rate = same_set_rate,
|
|
};
|
|
static struct clk emi =
|
|
{
|
|
.name = "emi",
|
|
.mod = SYSCTL_MOD_EMI,
|
|
.iomux = -1,
|
|
.get_rate = same_get_rate,
|
|
.set_rate = same_set_rate,
|
|
};
|
|
static struct clk pclk =
|
|
{
|
|
.name = "pclk",
|
|
.div_offset = 0x1c,
|
|
.max_div = 8,
|
|
.mod = SYSCTL_MOD_APB,
|
|
.iomux = -1,
|
|
.get_rate = integral_get_rate,
|
|
.set_rate = integral_set_rate,
|
|
};
|
|
static struct clk ps2_0 =
|
|
{
|
|
.name = "ps2_0",
|
|
.div_offset = 0x58,
|
|
.max_div = 1024,
|
|
.mod = SYSCTL_MOD_PS2_0,
|
|
.iomux = SYSCTL_IOMUX_PS2_0,
|
|
.get_rate = even_get_rate,
|
|
.set_rate = even_set_rate,
|
|
};
|
|
static struct clk ps2_1 =
|
|
{
|
|
.name = "ps2_1",
|
|
.div_offset = 0x5c,
|
|
.max_div = 1024,
|
|
.mod = SYSCTL_MOD_PS2_1,
|
|
.iomux = SYSCTL_IOMUX_PS2_1,
|
|
.get_rate = even_get_rate,
|
|
.set_rate = even_set_rate,
|
|
};
|
|
static struct clk spi0 =
|
|
{
|
|
.name = "spi0",
|
|
.div_offset = 0x34,
|
|
.max_div = 32,
|
|
.mod = SYSCTL_MOD_SPI0,
|
|
.iomux = SYSCTL_IOMUX_SPI0,
|
|
.get_rate = integral_get_rate,
|
|
.set_rate = integral_set_rate,
|
|
};
|
|
static struct clk keypad =
|
|
{
|
|
.name = "keypad",
|
|
.div_offset = 0x3c,
|
|
.max_div = 1024,
|
|
.mod = SYSCTL_MOD_KPD,
|
|
.iomux = SYSCTL_IOMUX_KEYPAD,
|
|
.get_rate = even_get_rate,
|
|
.set_rate = even_set_rate,
|
|
};
|
|
static struct clk wdt =
|
|
{
|
|
.name = "wdt",
|
|
.mod = SYSCTL_MOD_WDT,
|
|
.iomux = -1,
|
|
.get_rate = same_get_rate,
|
|
.set_rate = same_set_rate,
|
|
};
|
|
static struct clk sci0 =
|
|
{
|
|
.name = "sci0",
|
|
.div_offset = 0x40,
|
|
.max_div = 64,
|
|
.mod = SYSCTL_MOD_SCI0,
|
|
.iomux = SYSCTL_IOMUX_SCI0,
|
|
.get_rate = even_get_rate,
|
|
.set_rate = even_set_rate,
|
|
};
|
|
static struct clk sci1 =
|
|
{
|
|
.name = "sci1",
|
|
.div_offset = 0x44,
|
|
.max_div = 64,
|
|
.mod = SYSCTL_MOD_SCI1,
|
|
.iomux = -1/*SYSCTL_IOMUX_SCI1_1*/,
|
|
.get_rate = even_get_rate,
|
|
.set_rate = even_set_rate,
|
|
};
|
|
static struct clk can =
|
|
{
|
|
.name = "can",
|
|
.div_offset = 0x30,
|
|
.max_div = 32,
|
|
.mod = SYSCTL_MOD_CAN,
|
|
.iomux = -1,
|
|
.get_rate = integral_get_rate,
|
|
.set_rate = integral_set_rate,
|
|
};
|
|
|
|
static struct clk uart0 =
|
|
{
|
|
.name = "uart0",
|
|
.div_offset = 0x60,
|
|
.max_div = 64,
|
|
.mod = SYSCTL_MOD_UART0,
|
|
.iomux = SYSCTL_IOMUX_UART0,
|
|
.get_rate = integral_get_rate,
|
|
.set_rate = integral_set_rate,
|
|
};
|
|
static struct clk uart1 =
|
|
{
|
|
.name = "uart1",
|
|
.div_offset = 0x64,
|
|
.max_div = 64,
|
|
.mod = SYSCTL_MOD_UART1,
|
|
.iomux = SYSCTL_IOMUX_UART1,
|
|
.get_rate = integral_get_rate,
|
|
.set_rate = integral_set_rate,
|
|
};
|
|
static struct clk uart2 =
|
|
{
|
|
.name = "uart2",
|
|
.div_offset = 0x68,
|
|
.max_div = 64,
|
|
.mod = SYSCTL_MOD_UART2,
|
|
.iomux = SYSCTL_IOMUX_UART2,
|
|
.get_rate = integral_get_rate,
|
|
.set_rate = integral_set_rate,
|
|
};
|
|
static struct clk uart3 =
|
|
{
|
|
.name = "uart3",
|
|
.div_offset = 0x6c,
|
|
.max_div = 128,
|
|
.mod = SYSCTL_MOD_UART3,
|
|
.iomux = -1 /*SYSCTL_IOMUX_UART3_1*/,
|
|
.get_rate = integral_get_rate,
|
|
.set_rate = integral_set_rate,
|
|
};
|
|
static struct clk uart4 =
|
|
{
|
|
.name = "uart4",
|
|
.div_offset = 0x70,
|
|
.max_div = 128,
|
|
.mod = SYSCTL_MOD_UART4,
|
|
.iomux = -1/*SYSCTL_IOMUX_UART4_1*/,
|
|
.get_rate = integral_get_rate,
|
|
.set_rate = integral_set_rate,
|
|
};
|
|
static struct clk uart5 =
|
|
{
|
|
.name = "uart5",
|
|
.div_offset = 0x74,
|
|
.max_div = 128,
|
|
.mod = SYSCTL_MOD_UART5,
|
|
.iomux = -1/*SYSCTL_IOMUX_UART5*/,
|
|
.get_rate = integral_get_rate,
|
|
.set_rate = integral_set_rate,
|
|
};
|
|
static struct clk uart6 =
|
|
{
|
|
.name = "uart6",
|
|
.div_offset = 0x78,
|
|
.max_div = 64,
|
|
.mod = SYSCTL_MOD_UART6,
|
|
.iomux = SYSCTL_IOMUX_UART6,
|
|
.get_rate = integral_get_rate,
|
|
.set_rate = integral_set_rate,
|
|
};
|
|
static struct clk uart7 =
|
|
{
|
|
.name = "uart7",
|
|
.div_offset = 0x7c,
|
|
.max_div = 64,
|
|
.mod = SYSCTL_MOD_UART7,
|
|
.iomux = SYSCTL_IOMUX_UART7,
|
|
.get_rate = integral_get_rate,
|
|
.set_rate = integral_set_rate,
|
|
};
|
|
static struct clk gpio =
|
|
{
|
|
.name = "gpio",
|
|
.mod = SYSCTL_MOD_GPIO,
|
|
.iomux = -1,
|
|
.get_rate = same_get_rate,
|
|
.set_rate = same_set_rate,
|
|
};
|
|
static struct clk gpiodb =
|
|
{
|
|
.name = "gpiodb",
|
|
.div_offset = 0x90,
|
|
.max_div = 128,
|
|
.mod = -1,
|
|
.iomux = -1,
|
|
.get_rate = even_get_rate,
|
|
.set_rate = even_set_rate,
|
|
};
|
|
static struct clk timer0 =
|
|
{
|
|
.name = "timer0",
|
|
.div_offset = 0x80,
|
|
.max_div = 1024,
|
|
.mod = SYSCTL_MOD_TIMER0,
|
|
.iomux = -1,
|
|
.get_rate = even_get_rate,
|
|
.set_rate = even_set_rate,
|
|
};
|
|
static struct clk timer1 =
|
|
{
|
|
.name = "timer1",
|
|
.div_offset = 0x84,
|
|
.max_div = 1024,
|
|
.mod = SYSCTL_MOD_TIMER1,
|
|
.iomux = -1,
|
|
.get_rate = even_get_rate,
|
|
.set_rate = even_set_rate,
|
|
};
|
|
static struct clk timer2 =
|
|
{
|
|
.name = "timer2",
|
|
.div_offset = 0x88,
|
|
.max_div = 1024,
|
|
.mod = SYSCTL_MOD_TIMER2,
|
|
.iomux = -1,
|
|
.get_rate = even_get_rate,
|
|
.set_rate = even_set_rate,
|
|
};
|
|
static struct clk timer3 =
|
|
{
|
|
.name = "timer3",
|
|
.div_offset = 0x8c,
|
|
.max_div = 1024,
|
|
.mod = SYSCTL_MOD_TIMER3,
|
|
.iomux = -1,
|
|
.get_rate = even_get_rate,
|
|
.set_rate = even_set_rate,
|
|
};
|
|
static struct clk pwm0 =
|
|
{
|
|
.name = "pwm0",
|
|
.div_offset = 0x48,
|
|
.max_div = 64,
|
|
.mod = SYSCTL_MOD_PWM0,
|
|
.iomux = -1/*SYSCTL_IOMUX_PWM*/,
|
|
.get_rate = integral_get_rate,
|
|
.set_rate = integral_set_rate,
|
|
};
|
|
|
|
static struct clk pwm1 =
|
|
{
|
|
.name = "pwm1",
|
|
.div_offset = 0x4c,
|
|
.max_div = 64,
|
|
.mod = SYSCTL_MOD_PWM1,
|
|
.iomux = -1/*SYSCTL_IOMUX_PWM*/,
|
|
.get_rate = integral_get_rate,
|
|
.set_rate = integral_set_rate,
|
|
};
|
|
static struct clk pwm2 =
|
|
{
|
|
.name = "pwm2",
|
|
.div_offset = 0x50,
|
|
.max_div = 64,
|
|
.mod = SYSCTL_MOD_PWM2,
|
|
.iomux = -1/*SYSCTL_IOMUX_PWM*/,
|
|
.get_rate = integral_get_rate,
|
|
.set_rate = integral_set_rate,
|
|
};
|
|
static struct clk pwmr =
|
|
{
|
|
.name = "pwmr",
|
|
.div_offset = 0x54,
|
|
.max_div = 64,
|
|
.mod = SYSCTL_MOD_PWMR,
|
|
.iomux = -1/*SYSCTL_IOMUX_PWM*/,
|
|
.get_rate = integral_get_rate,
|
|
.set_rate = integral_set_rate,
|
|
};
|
|
|
|
unsigned long pll_get_rate(struct clk *clk)
|
|
{
|
|
unsigned long M,N,OD;
|
|
unsigned long freq;
|
|
|
|
freq = *(unsigned int *)sysctl_base;
|
|
M = freq & 0x7f;
|
|
N = (freq >> 7) & 0xf;
|
|
OD = (freq >> 11) & 0x2;
|
|
OD = ((OD == 0)?1:(2<<OD));
|
|
|
|
//printk("M=%ld N=%ld OD=%ld\n",M,N,OD);
|
|
if ((N == 0) || (OD == 0))
|
|
return 0;
|
|
|
|
//printk("pll=%ld\n",ref_clk*M/(N*OD));
|
|
|
|
return (ref_clk * M/(N * OD));
|
|
}
|
|
|
|
void set_pll(unsigned int pll_freq)
|
|
{
|
|
|
|
__asm__ __volatile__ (
|
|
".set push\n\t"
|
|
".set noreorder\n\t"
|
|
);
|
|
|
|
*(volatile unsigned int *) (0xbc113004UL) = 0x3;
|
|
while (((*(volatile unsigned int *)(0xbc113008UL)) & 0x7) != 0x5);
|
|
|
|
*(volatile unsigned int *)(0xbc04a000UL) = pll_freq;
|
|
|
|
*(volatile unsigned int *) (0xbc113004UL) = 0x4;
|
|
while (((*(volatile unsigned int *)(0xbc113008UL)) & 0x7) != 0x3);
|
|
|
|
__asm__ __volatile__(
|
|
".set pop\n\t"
|
|
);
|
|
}
|
|
|
|
void (*nocache_set_pll)(unsigned int);
|
|
|
|
unsigned long pll_set_rate(struct clk *clk, unsigned long rate)
|
|
{
|
|
unsigned int pll_freq;
|
|
unsigned long flags;
|
|
|
|
switch (rate) {
|
|
case 600*1000*1000:
|
|
pll_freq = 0x964;
|
|
break;
|
|
case 534*1000*1000:
|
|
pll_freq = 0x959;
|
|
break;
|
|
case 500*1000*1000:
|
|
pll_freq = 0x9fd;
|
|
break;
|
|
case 468*1000*1000:
|
|
pll_freq = 0x9f5;
|
|
break;
|
|
case 400*1000*1000:
|
|
pll_freq = 0x9e4;
|
|
break;
|
|
case 333*1000*1000:
|
|
pll_freq = 0xa6f;
|
|
break;
|
|
case 267*1000*1000:
|
|
pll_freq = 0x1159;
|
|
break;
|
|
case 200*1000*1000:
|
|
pll_freq = 0x11e4;
|
|
break;
|
|
default:
|
|
return 0;
|
|
}
|
|
|
|
local_irq_save(flags);
|
|
|
|
memcpy((void *)0xbfc00000,&set_pll,0x100);
|
|
|
|
barrier();
|
|
|
|
nocache_set_pll(pll_freq);
|
|
|
|
serial_get_clk();
|
|
|
|
local_irq_restore(flags);
|
|
|
|
return rate;
|
|
}
|
|
|
|
|
|
|
|
unsigned long same_get_rate(struct clk *clk)
|
|
{
|
|
return clk->parent->get_rate(clk->parent);
|
|
}
|
|
|
|
unsigned long aclk_get_rate(struct clk *clk)
|
|
{
|
|
return (clk->parent->get_rate(clk->parent)>>1);
|
|
}
|
|
|
|
unsigned long integral_get_rate(struct clk *clk)
|
|
{
|
|
unsigned int div;
|
|
div = *(unsigned int *)(sysctl_base + clk->div_offset);
|
|
return clk->parent->get_rate(clk->parent)/(div + 1);
|
|
}
|
|
|
|
unsigned long even_get_rate(struct clk *clk)
|
|
{
|
|
unsigned int div;
|
|
div = *(unsigned int*)(sysctl_base + clk->div_offset);
|
|
return clk->parent->get_rate(clk->parent)/((div+1)<<1);
|
|
}
|
|
|
|
unsigned long same_set_rate(struct clk *clk, unsigned long rate)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
unsigned long aclk_set_rate(struct clk *clk, unsigned long rate)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
unsigned long cpu_set_rate(struct clk *clk, unsigned long rate)
|
|
{
|
|
return (clk->parent->set_rate(clk->parent, rate<<1))>>1;
|
|
}
|
|
|
|
unsigned long integral_set_rate(struct clk *clk, unsigned long rate)
|
|
{
|
|
unsigned int div;
|
|
unsigned long parent_rate;
|
|
parent_rate = clk->parent->get_rate(clk->parent);
|
|
div = parent_rate/rate;
|
|
if (div > clk->max_div)
|
|
div = clk->max_div;
|
|
if (div < 2)
|
|
div = 2;
|
|
*(unsigned int *)(sysctl_base + clk->div_offset) = div-1;
|
|
return parent_rate/div;
|
|
}
|
|
|
|
unsigned long even_set_rate(struct clk *clk, unsigned long rate)
|
|
{
|
|
unsigned int div;
|
|
unsigned int parent_rate;
|
|
parent_rate = clk->parent->get_rate(clk->parent);
|
|
div = parent_rate/(rate<<1);
|
|
if (div > clk->max_div)
|
|
div = clk->max_div;
|
|
if (div < 2)
|
|
div = 2;
|
|
|
|
*(unsigned int *)(sysctl_base + clk->div_offset) = (div >> 1) - 1;
|
|
|
|
return parent_rate/(div<<1);
|
|
}
|
|
|
|
struct clk *clk_get(struct device *dev, const char *id)
|
|
{
|
|
struct clk *pos;
|
|
if (id == NULL)
|
|
return NULL;
|
|
list_for_each_entry_reverse(pos,&clock_list,list) {
|
|
if (!strcmp(pos->name,id)) {
|
|
return pos;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
EXPORT_SYMBOL(clk_get);
|
|
|
|
int clk_enable(struct clk *clk)
|
|
{
|
|
int ret = 0;
|
|
if (clk && (clk->mod >= 0)) {
|
|
sysctl_mod_enable(clk->mod);
|
|
if (clk->iomux >= 0)
|
|
ret = sysctl_iomux_enable(clk->iomux);
|
|
|
|
}
|
|
else
|
|
ret = -EACCES;
|
|
return ret;
|
|
}
|
|
EXPORT_SYMBOL(clk_enable);
|
|
|
|
void clk_disable(struct clk *clk)
|
|
{
|
|
if (clk && (clk->mod >= 0)) {
|
|
sysctl_mod_disable(clk->mod);
|
|
if (clk->iomux >= 0)
|
|
sysctl_iomux_disable(clk->iomux);
|
|
}
|
|
|
|
}
|
|
EXPORT_SYMBOL(clk_disable);
|
|
|
|
unsigned long clk_get_rate(struct clk *clk)
|
|
{
|
|
#ifndef CONFIG_BLX_GSC3280_FPGA
|
|
if (clk->get_rate)
|
|
return (unsigned long)clk->get_rate(clk);
|
|
return 0;
|
|
#else
|
|
return 50000000;
|
|
#endif
|
|
}
|
|
EXPORT_SYMBOL(clk_get_rate);
|
|
|
|
void clk_put(struct clk *clk)
|
|
{
|
|
}
|
|
EXPORT_SYMBOL(clk_put);
|
|
|
|
int clk_set_rate(struct clk *clk, unsigned long rate)
|
|
{
|
|
if (clk->set_rate)
|
|
return clk->set_rate(clk,rate);
|
|
return -EACCES;
|
|
}
|
|
EXPORT_SYMBOL_GPL(clk_set_rate);
|
|
|
|
void __init clk_init(void)
|
|
{
|
|
list_add_tail(&(pll.list),&clock_list);
|
|
pll_clkout.parent = &pll;
|
|
list_add_tail(&(pll_clkout.list),&clock_list);
|
|
aclk.parent = &pll;
|
|
list_add_tail(&(aclk.list),&clock_list);
|
|
cpu.parent = &pll;
|
|
list_add_tail(&(cpu.list),&clock_list);
|
|
ddr2.parent = &pll;
|
|
list_add_tail(&(ddr2.list),&clock_list);
|
|
hclk.parent = &pll;
|
|
list_add_tail(&(hclk.list),&clock_list);
|
|
sdio.parent = &pll;
|
|
list_add_tail(&(sdio.list),&clock_list);
|
|
lcdc.parent = &pll;
|
|
list_add_tail(&(lcdc.list),&clock_list);
|
|
ddr2phy.parent = &pll;
|
|
list_add_tail(&(ddr2phy.list),&clock_list);
|
|
i2s.parent = &pll_clkout;
|
|
list_add_tail(&(i2s.list),&clock_list);
|
|
i2c.parent = &hclk;
|
|
list_add_tail(&(i2c.list),&clock_list);
|
|
uart3.parent = &hclk;
|
|
list_add_tail(&(uart3.list),&clock_list);
|
|
uart4.parent = &hclk;
|
|
list_add_tail(&(uart4.list),&clock_list);
|
|
uart5.parent = &hclk;
|
|
list_add_tail(&(uart5.list),&clock_list);
|
|
spi1.parent = &hclk;
|
|
list_add_tail(&(spi1.list),&clock_list);
|
|
dma.parent = &hclk;
|
|
list_add_tail(&(dma.list),&clock_list);
|
|
ictl.parent = &hclk;
|
|
list_add_tail(&(ictl.list),&clock_list);
|
|
nfc.parent = &hclk;
|
|
list_add_tail(&(nfc.list),&clock_list);
|
|
sysctl.parent = &hclk;
|
|
list_add_tail(&(sysctl.list),&clock_list);
|
|
emi.parent = &hclk;
|
|
list_add_tail(&(emi.list),&clock_list);
|
|
pclk.parent = &hclk;
|
|
list_add_tail(&(pclk.list),&clock_list);
|
|
ps2_0.parent = &pclk;
|
|
list_add_tail(&(ps2_0.list),&clock_list);
|
|
ps2_1.parent = &pclk;
|
|
list_add_tail(&(ps2_1.list),&clock_list);
|
|
spi0.parent = &pclk;
|
|
list_add_tail(&(spi0.list),&clock_list);
|
|
keypad.parent = &pclk;
|
|
list_add_tail(&(keypad.list),&clock_list);
|
|
wdt.parent = &pclk;
|
|
list_add_tail(&(wdt.list),&clock_list);
|
|
sci0.parent = &pclk;
|
|
list_add_tail(&(sci0.list),&clock_list);
|
|
sci1.parent = &pclk;
|
|
list_add_tail(&(sci1.list),&clock_list);
|
|
can.parent = &pclk;
|
|
list_add_tail(&(can.list),&clock_list);
|
|
uart0.parent = &pclk;
|
|
list_add_tail(&(uart0.list),&clock_list);
|
|
uart1.parent = &pclk;
|
|
list_add_tail(&(uart1.list),&clock_list);
|
|
uart2.parent = &pclk;
|
|
list_add_tail(&(uart2.list),&clock_list);
|
|
uart6.parent = &pclk;
|
|
list_add_tail(&(uart6.list),&clock_list);
|
|
uart7.parent = &pclk;
|
|
list_add_tail(&(uart7.list),&clock_list);
|
|
gpio.parent = &pclk;
|
|
list_add_tail(&(gpio.list),&clock_list);
|
|
gpiodb.parent = &pclk;
|
|
list_add_tail(&(gpiodb.list),&clock_list);
|
|
timer0.parent = &pclk;
|
|
list_add_tail(&(timer0.list),&clock_list);
|
|
timer1.parent = &pclk;
|
|
list_add_tail(&(timer1.list),&clock_list);
|
|
timer2.parent = &pclk;
|
|
list_add_tail(&(timer2.list),&clock_list);
|
|
timer3.parent = &pclk;
|
|
list_add_tail(&(timer3.list),&clock_list);
|
|
pwm0.parent = &pclk;
|
|
list_add_tail(&(pwm0.list),&clock_list);
|
|
pwm1.parent = &pclk;
|
|
list_add_tail(&(pwm1.list),&clock_list);
|
|
pwm2.parent = &pclk;
|
|
list_add_tail(&(pwm2.list),&clock_list);
|
|
pwmr.parent = &pclk;
|
|
list_add_tail(&(pwmr.list),&clock_list);
|
|
sysctl_base = 0xbc04a000UL;
|
|
|
|
if (!sysctl_mod_is_enabled(SYSCTL_MOD_SYSCTL))
|
|
sysctl_mod_enable(SYSCTL_MOD_SYSCTL);
|
|
|
|
nocache_set_pll = (void *)0xbfc00000;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(clk_init);
|
|
|
|
/*
|
|
* This is the simple version of Loongson-2 wait, Maybe we need do this in
|
|
* interrupt disabled content
|
|
*/
|
|
MODULE_AUTHOR("LiuJianhua <liujianhua@china-cpu.com>");
|
|
MODULE_DESCRIPTION("clk for gsc3280");
|
|
MODULE_LICENSE("GPL");
|