⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clock.c

📁 TI达芬奇 arm+dsp双核平台Davinci 6446 EVM板的linux下的 处理器平台底层代码
💻 C
字号:
/* * linux/arch/arm/mach-davinci/clock.c * * TI DaVinci clock config file * * Copyright (C) 2006 Texas Instruments. * * ---------------------------------------------------------------------------- * * 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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * ---------------------------------------------------------------------------- * *//************************************************************************** * Included Files **************************************************************************/#include <linux/config.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/major.h>#include <linux/root_dev.h>#include <asm/setup.h>#include <asm/semaphore.h>#include <asm/hardware/clock.h>#include <asm/io.h>#include <asm/mach-types.h>#include <asm/mach/arch.h>#include <asm/mach/map.h>#include <asm/arch/hardware.h>#include "clock.h"#define DAVINCI_MAX_CLK 9#define PLL1_PLLM   __REG(0x01c40910)#define PLL2_PLLM   __REG(0x01c40D10)#define PTCMD       __REG(0x01C41120)#define PDSTAT      __REG(0x01C41200)#define PDCTL1      __REG(0x01C41304)#define EPCPR       __REG(0x01C41070)#define PTSTAT      __REG(0x01C41128)#define MDSTAT  IO_ADDRESS(0x01C41800)#define MDCTL   IO_ADDRESS(0x01C41A00)#define VDD3P3V_PWDN  __REG(0x01C40048)#define PINMUX0     __REG(0x01c40000)#define PINMUX1     __REG(0x01c40004)static LIST_HEAD(clocks);static DECLARE_MUTEX(clocks_sem);static DEFINE_RAW_SPINLOCK(clockfw_lock);static unsigned int commonrate;static unsigned int armrate;static unsigned int fixedrate = 27000000;	/* 27 MHZ *//************************************** Routine: board_setup_psc Description:  Enable/Disable a PSC domain**************************************/void board_setup_psc(unsigned int domain, unsigned int id, char enable){	volatile unsigned int *mdstat = (unsigned int *)((int)MDSTAT + 4 * id);	volatile unsigned int *mdctl = (unsigned int *)((int)MDCTL + 4 * id);	if (enable) {		*mdctl |= 0x00000003;	/* Enable Module */	} else {		*mdctl &= 0xFFFFFFF2;	/* Disable Module */	}	if ((PDSTAT & 0x00000001) == 0) {		PDCTL1 |= 0x1;		PTCMD = (1 << domain);		while ((((EPCPR >> domain) & 1) == 0)) ;		PDCTL1 |= 0x100;		while (!(((PTSTAT >> domain) & 1) == 0)) ;	} else {		PTCMD = (1 << domain);		while (!(((PTSTAT >> domain) & 1) == 0)) ;	}	if (enable) {		while (!((*mdstat & 0x0000001F) == 0x3)) ;	} else {		while (!((*mdstat & 0x0000001F) == 0x2)) ;	}}static int board_setup_peripheral(unsigned int id){	switch (id) {	case DAVINCI_LPSC_ATA:		PINMUX0 |= (1 << 17) | (1 << 16);		break;	case DAVINCI_LPSC_MMC_SD:		/* VDD power manupulations are done in U-Boot for CPMAC		 * so applies to MMC as well		 */		/*Set up the pull regiter for MMC */		VDD3P3V_PWDN = 0x0;		PINMUX1 &= (~(1 << 9));		break;	case DAVINCI_LPSC_I2C:		PINMUX1 |= (1 << 7);		break;	case DAVINCI_LPSC_McBSP:		PINMUX1 |= (1 << 10);		break;	default:		break;	}}struct clk *clk_get(struct device *dev, const char *id){	struct clk *p, *clk = ERR_PTR(-ENOENT);	down(&clocks_sem);	list_for_each_entry(p, &clocks, node) {		if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {			clk = p;			break;		}	}	up(&clocks_sem);	return clk;}EXPORT_SYMBOL(clk_get);void clk_put(struct clk *clk){	if (clk && !IS_ERR(clk))		module_put(clk->owner);}EXPORT_SYMBOL(clk_put);int __clk_enable(struct clk *clk){	if (clk->flags & ALWAYS_ENABLED)		return 0;	board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, clk->lpsc, 1);	return 0;}void __clk_disable(struct clk *clk){	if (clk->usecount)		return;	board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, clk->lpsc, 0);}void __clk_unuse(struct clk *clk){	if (clk->usecount > 0) {		--clk->usecount;	}}int __clk_use(struct clk *clk){	int ret = 0;	clk->usecount++;	return ret;}int clk_enable(struct clk *clk){	unsigned long flags;	int ret;	spin_lock_irqsave(&clockfw_lock, flags);	ret = __clk_enable(clk);	spin_unlock_irqrestore(&clockfw_lock, flags);	board_setup_peripheral(clk->lpsc);	return ret;}EXPORT_SYMBOL(clk_enable);void clk_disable(struct clk *clk){	unsigned long flags;	spin_lock_irqsave(&clockfw_lock, flags);	__clk_disable(clk);	spin_unlock_irqrestore(&clockfw_lock, flags);}EXPORT_SYMBOL(clk_disable);int clk_use(struct clk *clk){	unsigned long flags;	int ret = 0;	spin_lock_irqsave(&clockfw_lock, flags);	ret = __clk_use(clk);	spin_unlock_irqrestore(&clockfw_lock, flags);	return ret;}EXPORT_SYMBOL(clk_use);void clk_unuse(struct clk *clk){	unsigned long flags;	spin_lock_irqsave(&clockfw_lock, flags);	__clk_unuse(clk);	spin_unlock_irqrestore(&clockfw_lock, flags);}EXPORT_SYMBOL(clk_unuse);unsigned long clk_get_rate(struct clk *clk){	return *(clk->rate);}EXPORT_SYMBOL(clk_get_rate);int clk_register(struct clk *clk){	down(&clocks_sem);	list_add(&clk->node, &clocks);	up(&clocks_sem);	return 0;}EXPORT_SYMBOL(clk_register);void clk_unregister(struct clk *clk){	down(&clocks_sem);	list_del(&clk->node);	up(&clocks_sem);}EXPORT_SYMBOL(clk_unregister);static struct clk davinci_clks[DAVINCI_MAX_CLK] = {	{		.name = "ARMCLK",		.rate = &armrate,		.lpsc = -1,		.flags = ALWAYS_ENABLED,	},	{		.name = "UART",		.rate = &fixedrate,		.lpsc = DAVINCI_LPSC_UART0,		.usecount = 1,	},	{		.name = "EMACCLK",		.rate = &commonrate,		.lpsc = DAVINCI_LPSC_EMAC_WRAPPER,	},	{		.name = "I2CCLK",		.rate = &fixedrate,		.lpsc = DAVINCI_LPSC_I2C,	},	{		.name = "IDECLK",		.rate = &commonrate,		.lpsc = DAVINCI_LPSC_ATA,	},	{		.name = "McBSPCLK",		.rate = &commonrate,		.lpsc = DAVINCI_LPSC_McBSP,	},	{		.name = "MMCSDCLK",		.rate = &commonrate,		.lpsc = DAVINCI_LPSC_MMC_SD,	},	{		.name = "SPICLK",		.rate = &commonrate,		.lpsc = DAVINCI_LPSC_SPI,	},	{		.name = "AEMIFCLK",		.rate = &commonrate,		.lpsc = DAVINCI_LPSC_AEMIF,		.usecount = 1,	}};void davinci_clk_init(void){	struct clk *clkp;	int count = 0;	commonrate = ((PLL1_PLLM + 1) * 27000000) / 6;	armrate = ((PLL1_PLLM + 1) * 27000000) / 2;	for (clkp = davinci_clks; count < DAVINCI_MAX_CLK; count++, clkp++) {		clk_register(clkp);		/* Turn on clocks that have been enabled in the		 * table above */		if (clkp->usecount) {			clk_enable(clkp);		}	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -