Chinaunix首页 | 论坛 | 博客
  • 博客访问: 96780
  • 博文数量: 54
  • 博客积分: 1920
  • 博客等级: 上尉
  • 技术积分: 480
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-08 13:46
文章分类

全部博文(54)

文章存档

2011年(1)

2010年(8)

2009年(45)

我的朋友

分类: LINUX

2010-01-04 16:52:10

 

{

       s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));

       s3c24xx_init_clocks(0);

       s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));

}

 

 

3c24xx/cpu.c

3c24xx_init_clocks(int xtal)

{

       if (xtal == 0)

              xtal = 12*1000*1000;

 

       if (cpu == NULL)

              panic("s3c24xx_init_clocks: no cpu setup?\n");

 

       if (cpu->init_clocks == NULL)

              panic("s3c24xx_init_clocks: cpu has no clock init\n");

       else

              (cpu->init_clocks)(xtal);

}

 

       {

              .idcode           = 0x32410000,

              .idmask          = 0xffffffff,

              .map_io          = s3c2410_map_io,

              .init_clocks     = s3c2410_init_clocks,

              .init_uarts       = s3c2410_init_uarts,

              .init         = s3c2410_init,

              .name             = name_s3c2410

       },

       {

              .idcode           = 0x32410002,

              .idmask          = 0xffffffff,

              .map_io          = s3c2410_map_io,

              .init_clocks     = s3c2410_init_clocks,

              .init_uarts       = s3c2410_init_uarts,

              .init         = s3c2410_init,

              .name             = name_s3c2410a

       },

       {

              .idcode           = 0x32440000,

              .idmask          = 0xffffffff,

              .map_io          = s3c244x_map_io,

              .init_clocks    = s3c244x_init_clocks,

              .init_uarts       = s3c244x_init_uarts,

              .init         = s3c2440_init,

              .name             = name_s3c2440

       },

};

 

3c24xx/s3c244x.c

3c244x_init_clocks(int xtal)

{

       unsigned long clkdiv;

       unsigned long camdiv;

       unsigned long hclk, fclk, pclk;

       int hdiv = 1;

   

       /* now we've got our machine bits initialised, work out what

        * clocks we've got */

 

       unsigned long delay=0;

    __raw_writel(__raw_readl(S3C2410_UPLLCON),S3C2410_UPLLCON);

    while(delay<10) delay++;

   

    delay=0;

   

    __raw_writel(S3C2410_PLLVAL(125,1,1),S3C2410_MPLLCON);

    while(delay<100) delay++;

   

       fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal) * 2;

 

       clkdiv = __raw_readl(S3C2410_CLKDIVN);

       camdiv = __raw_readl(S3C2440_CAMDIVN);

 

       /* work out clock scalings */

 

       switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {

       case S3C2440_CLKDIVN_HDIVN_1:

              hdiv = 1;

              break;

 

       case S3C2440_CLKDIVN_HDIVN_2:

              hdiv = 2;

              break;

 

       case S3C2440_CLKDIVN_HDIVN_4_8:

              hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;

              break;

 

       case S3C2440_CLKDIVN_HDIVN_3_6:

              hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;

              break;

       }

 

       hclk = fclk / hdiv;

       pclk = hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN)? 2:1);

 

       /* print brief summary of clocks, etc */

 

       printk("S3C244X: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",

              print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));

 

       /* initialise the clocks here, to allow other things like the

        * console to use them, and to add new ones after the initialisation

        */

 

       s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);

       s3c2410_baseclk_add();

}

3c24xx/clock.c

 

/* base clocks */

 

struct clk clk_xtal = {

       .name             = "xtal",

       .id           = -1,

       .rate        = 0,

       .parent           = NULL,

       .ctrlbit     = 0,

};

 

struct clk clk_mpll = {

       .name             = "mpll",

       .id           = -1,

};

 

struct clk clk_upll = {

       .name             = "upll",

       .id           = -1,

       .parent           = NULL,

       .ctrlbit     = 0,

};

 

struct clk clk_f = {

       .name             = "fclk",

       .id           = -1,

       .rate        = 0,

       .parent           = &clk_mpll,

       .ctrlbit     = 0,

};

 

struct clk clk_h = {

       .name             = "hclk",

       .id           = -1,

       .rate        = 0,

       .parent           = NULL,

       .ctrlbit     = 0,

};

 

struct clk clk_p = {

       .name             = "pclk",

       .id           = -1,

       .rate        = 0,

       .parent           = NULL,

       .ctrlbit     = 0,

};

 

struct clk clk_usb_bus = {

       .name             = "usb-bus",

       .id           = -1,

       .rate        = 0,

       .parent           = &clk_upll,

};

 

int s3c24xx_register_clock(struct clk *clk)

{

       clk->owner = THIS_MODULE;

 

       if (clk->enable == NULL)

              clk->enable = clk_null_enable;

 

       /* add to the list of available clocks */

 

       mutex_lock(&clocks_mutex);

       list_add(&clk->list, &clocks);

       mutex_unlock(&clocks_mutex);

 

       return 0;

}

3c24xx_setup_clocks(unsigned long xtal,

                      unsigned long fclk,

                      unsigned long hclk,

                      unsigned long pclk)

{

       printk(KERN_INFO "S3C24XX Clocks, (c) 2004 Simtec Electronics\n");

 

       /* initialise the main system clocks */

 

       clk_xtal.rate = xtal;

       clk_upll.rate = s3c2410_get_pll(__raw_readl(S3C2410_UPLLCON), xtal);

 

       clk_mpll.rate = fclk;

       clk_h.rate = hclk;

       clk_p.rate = pclk;

       clk_f.rate = fclk;

 

       /* assume uart clocks are correctly setup */

 

       /* register our clocks */

 

       if (s3c24xx_register_clock(&clk_xtal) < 0)

              printk(KERN_ERR "failed to register master xtal\n");

 

       if (s3c24xx_register_clock(&clk_mpll) < 0)

              printk(KERN_ERR "failed to register mpll clock\n");

 

       if (s3c24xx_register_clock(&clk_upll) < 0)

              printk(KERN_ERR "failed to register upll clock\n");

 

       if (s3c24xx_register_clock(&clk_f) < 0)

              printk(KERN_ERR "failed to register cpu fclk\n");

 

       if (s3c24xx_register_clock(&clk_h) < 0)

              printk(KERN_ERR "failed to register cpu hclk\n");

 

       if (s3c24xx_register_clock(&clk_p) < 0)

              printk(KERN_ERR "failed to register cpu pclk\n");

 

       return 0;

}

3c2410/clock.c

3c2410_clkcon_enable(struct clk *clk, int enable)

{

       unsigned int clocks = clk->ctrlbit;

       unsigned long clkcon;

 

       clkcon = __raw_readl(S3C2410_CLKCON);

 

       if (enable)

              clkcon |= clocks;

       else

              clkcon &= ~clocks;

 

       /* ensure none of the special function bits set */

       clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER);

 

       __raw_writel(clkcon, S3C2410_CLKCON);

 

       return 0;

}

 

3c2410_upll_enable(struct clk *clk, int enable)

{

       unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);

       unsigned long orig = clkslow;

 

       if (enable)

              clkslow &= ~S3C2410_CLKSLOW_UCLK_OFF;

       else

              clkslow |= S3C2410_CLKSLOW_UCLK_OFF;

 

       __raw_writel(clkslow, S3C2410_CLKSLOW);

 

       /* if we started the UPLL, then allow to settle */

 

       if (enable && (orig & S3C2410_CLKSLOW_UCLK_OFF))

              udelay(200);

 

       return 0;

}

 

/* standard clock definitions */

 

static struct clk init_clocks_disable[] = {

       {

              .name             = "nand",

              .id           = -1,

              .parent           = &clk_h,

              .enable           = s3c2410_clkcon_enable,

              .ctrlbit     = S3C2410_CLKCON_NAND,

       }, {

              .name             = "sdi",

              .id           = -1,

              .parent           = &clk_p,

              .enable           = s3c2410_clkcon_enable,

              .ctrlbit     = S3C2410_CLKCON_SDI,

       }, {

              .name             = "adc",

              .id           = -1,

              .parent           = &clk_p,

              .enable           = s3c2410_clkcon_enable,

              .ctrlbit     = S3C2410_CLKCON_ADC,

       }, {

              .name             = "i2c",

              .id           = -1,

              .parent           = &clk_p,

              .enable           = s3c2410_clkcon_enable,

              .ctrlbit     = S3C2410_CLKCON_IIC,

       }, {

              .name             = "iis",

              .id           = -1,

              .parent           = &clk_p,

              .enable           = s3c2410_clkcon_enable,

              .ctrlbit     = S3C2410_CLKCON_IIS,

       }, {

              .name             = "spi",

              .id           = -1,

              .parent           = &clk_p,

              .enable           = s3c2410_clkcon_enable,

              .ctrlbit     = S3C2410_CLKCON_SPI,

       }

};

 

static struct clk init_clocks[] = {

       {

              .name             = "lcd",

              .id           = -1,

              .parent           = &clk_h,

              .enable           = s3c2410_clkcon_enable,

              .ctrlbit     = S3C2410_CLKCON_LCDC,

       }, {

              .name             = "gpio",

              .id           = -1,

              .parent           = &clk_p,

              .enable           = s3c2410_clkcon_enable,

              .ctrlbit     = S3C2410_CLKCON_GPIO,

       }, {

              .name             = "usb-host",

              .id           = -1,

              .parent           = &clk_h,

              .enable           = s3c2410_clkcon_enable,

              .ctrlbit     = S3C2410_CLKCON_USBH,

       }, {

              .name             = "usb-device",

              .id           = -1,

              .parent           = &clk_h,

              .enable           = s3c2410_clkcon_enable,

              .ctrlbit     = S3C2410_CLKCON_USBD,

       }, {

              .name             = "timers",

              .id           = -1,

              .parent           = &clk_p,

              .enable           = s3c2410_clkcon_enable,

              .ctrlbit     = S3C2410_CLKCON_PWMT,

       }, {

              .name             = "uart",

              .id           = 0,

              .parent           = &clk_p,

              .enable           = s3c2410_clkcon_enable,

              .ctrlbit     = S3C2410_CLKCON_UART0,

       }, {

              .name             = "uart",

              .id           = 1,

              .parent           = &clk_p,

              .enable           = s3c2410_clkcon_enable,

              .ctrlbit     = S3C2410_CLKCON_UART1,

       }, {

              .name             = "uart",

              .id           = 2,

              .parent           = &clk_p,

              .enable           = s3c2410_clkcon_enable,

              .ctrlbit     = S3C2410_CLKCON_UART2,

       }, {

              .name             = "rtc",

              .id           = -1,

              .parent           = &clk_p,

              .enable           = s3c2410_clkcon_enable,

              .ctrlbit     = S3C2410_CLKCON_RTC,

       }, {

              .name             = "watchdog",

              .id           = -1,

              .parent           = &clk_p,

              .ctrlbit     = 0,

       }, {

              .name             = "usb-bus-host",

              .id           = -1,

              .parent           = &clk_usb_bus,

       }, {

              .name             = "usb-bus-gadget",

              .id           = -1,

              .parent           = &clk_usb_bus,

       },

};

 

/* s3c2410_baseclk_add()

 *

 * Add all the clocks used by the s3c2410 or compatible CPUs

 * such as the S3C2440 and S3C2442.

 *

 * We cannot use a system device as we are needed before any

 * of the init-calls that initialise the devices are actually

 * done.

*/

 

3c2410_baseclk_add(void)

{

       unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);

       unsigned long clkcon  = __raw_readl(S3C2410_CLKCON);

       struct clk *clkp;

       struct clk *xtal;

       int ret;

       int ptr;

 

       clk_upll.enable = s3c2410_upll_enable;

 

       if (s3c24xx_register_clock(&clk_usb_bus) < 0)

              printk(KERN_ERR "failed to register usb bus clock\n");

 

       /* register clocks from clock array */

 

       clkp = init_clocks;

       for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {

              /* ensure that we note the clock state */

 

              clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0;

 

              ret = s3c24xx_register_clock(clkp);

              if (ret < 0) {

                     printk(KERN_ERR "Failed to register clock %s (%d)\n",

                            clkp->name, ret);

              }

       }

 

       /* We must be careful disabling the clocks we are not intending to

        * be using at boot time, as subsystems such as the LCD which do

        * their own DMA requests to the bus can cause the system to lockup

        * if they where in the middle of requesting bus access.

        *

        * Disabling the LCD clock if the LCD is active is very dangerous,

        * and therefore the bootloader should be careful to not enable

        * the LCD clock if it is not needed.

       */

 

       /* install (and disable) the clocks we do not need immediately */

 

       clkp = init_clocks_disable;

       for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {

 

              ret = s3c24xx_register_clock(clkp);

              if (ret < 0) {

                     printk(KERN_ERR "Failed to register clock %s (%d)\n",

                            clkp->name, ret);

              }

 

              s3c2410_clkcon_enable(clkp, 0);

       }

 

       /* show the clock-slow value */

 

       xtal = clk_get(NULL, "xtal");

 

       printk("CLOCK: Slow mode (%ld.%ld MHz), %s, MPLL %s, UPLL %s\n",

              print_mhz(clk_get_rate(xtal) /

                      ( 2 * S3C2410_CLKSLOW_GET_SLOWVAL(clkslow))),

              (clkslow & S3C2410_CLKSLOW_SLOW) ? "slow" : "fast",

              (clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on",

              (clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on");

 

       return 0;

}

CPU S3C2440A (id 0x32440001)

S3C244X: core 405.000 MHz, memory 101.250 MHz, peripheral 50.625 MHz

S3C24XX Clocks, (c) 2004 Simtec Electronics

CLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL on

 

阅读(934) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~