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

📄 mpc52xx_setup.c

📁 linux-2.6.15.6
💻 C
字号:
/* * arch/ppc/syslib/mpc52xx_setup.c * * Common code for the boards based on Freescale MPC52xx embedded CPU. * *  * Maintainer : Sylvain Munaut <tnt@246tNt.com> * * Support for other bootloaders than UBoot by Dale Farnsworth  * <dfarnsworth@mvista.com> *  * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com> * Copyright (C) 2003 Montavista Software, Inc *  * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any * kind, whether express or implied. */#include <linux/config.h>#include <asm/io.h>#include <asm/time.h>#include <asm/mpc52xx.h>#include <asm/mpc52xx_psc.h>#include <asm/pgtable.h>#include <asm/ppcboot.h>extern bd_t __res;static int core_mult[] = {		/* CPU Frequency multiplier, taken    */	0,  0,  0,  10, 20, 20, 25, 45,	/* from the datasheet used to compute */	30, 55, 40, 50, 0,  60, 35, 0,	/* CPU frequency from XLB freq and    */	30, 25, 65, 10, 70, 20, 75, 45,	/* external jumper config             */	0,  55, 40, 50, 80, 60, 35, 0};voidmpc52xx_restart(char *cmd){	struct mpc52xx_gpt __iomem *gpt0 = MPC52xx_VA(MPC52xx_GPTx_OFFSET(0));	local_irq_disable();	/* Turn on the watchdog and wait for it to expire. It effectively	  does a reset */	out_be32(&gpt0->count, 0x000000ff);	out_be32(&gpt0->mode, 0x00009004);	while (1);}voidmpc52xx_halt(void){	local_irq_disable();	while (1);}voidmpc52xx_power_off(void){	/* By default we don't have any way of shut down.	   If a specific board wants to, it can set the power down	   code to any hardware implementation dependent code */	mpc52xx_halt();}void __initmpc52xx_set_bat(void){	/* Set BAT 2 to map the 0xf0000000 area */	/* This mapping is used during mpc52xx_progress,	 * mpc52xx_find_end_of_memory, and UARTs/GPIO access for debug	 */	mb();	mtspr(SPRN_DBAT2U, 0xf0001ffe);	mtspr(SPRN_DBAT2L, 0xf000002a);	mb();}void __initmpc52xx_map_io(void){	/* Here we only map the MBAR */	io_block_mapping(		MPC52xx_MBAR_VIRT, MPC52xx_MBAR, MPC52xx_MBAR_SIZE, _PAGE_IO);}#ifdef CONFIG_SERIAL_TEXT_DEBUG#ifndef MPC52xx_PF_CONSOLE_PORT#error "mpc52xx PSC for console not selected"#endifstatic voidmpc52xx_psc_putc(struct mpc52xx_psc __iomem *psc, unsigned char c){	while (!(in_be16(&psc->mpc52xx_psc_status) &	         MPC52xx_PSC_SR_TXRDY));	out_8(&psc->mpc52xx_psc_buffer_8, c);}voidmpc52xx_progress(char *s, unsigned short hex){	char c;	struct mpc52xx_psc __iomem *psc;	psc = MPC52xx_VA(MPC52xx_PSCx_OFFSET(MPC52xx_PF_CONSOLE_PORT));	while ((c = *s++) != 0) {		if (c == '\n')			mpc52xx_psc_putc(psc, '\r');		mpc52xx_psc_putc(psc, c);	}	mpc52xx_psc_putc(psc, '\r');	mpc52xx_psc_putc(psc, '\n');}#endif  /* CONFIG_SERIAL_TEXT_DEBUG */unsigned long __initmpc52xx_find_end_of_memory(void){	u32 ramsize = __res.bi_memsize;	/*	 * if bootloader passed a memsize, just use it	 * else get size from sdram config registers	 */	if (ramsize == 0) {		struct mpc52xx_mmap_ctl __iomem *mmap_ctl;		u32 sdram_config_0, sdram_config_1;		/* Temp BAT2 mapping active when this is called ! */		mmap_ctl = MPC52xx_VA(MPC52xx_MMAP_CTL_OFFSET);		sdram_config_0 = in_be32(&mmap_ctl->sdram0);		sdram_config_1 = in_be32(&mmap_ctl->sdram1);		if ((sdram_config_0 & 0x1f) >= 0x13)			ramsize = 1 << ((sdram_config_0 & 0xf) + 17);		if (((sdram_config_1 & 0x1f) >= 0x13) &&				((sdram_config_1 & 0xfff00000) == ramsize))			ramsize += 1 << ((sdram_config_1 & 0xf) + 17);	}	return ramsize;}void __initmpc52xx_calibrate_decr(void){	int current_time, previous_time;	int tbl_start, tbl_end;	unsigned int xlbfreq, cpufreq, ipbfreq, pcifreq, divisor;	xlbfreq = __res.bi_busfreq;	/* if bootloader didn't pass bus frequencies, calculate them */	if (xlbfreq == 0) {		/* Get RTC & Clock manager modules */		struct mpc52xx_rtc __iomem *rtc;		struct mpc52xx_cdm __iomem *cdm;		rtc = ioremap(MPC52xx_PA(MPC52xx_RTC_OFFSET), MPC52xx_RTC_SIZE);		cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);		if ((rtc==NULL) || (cdm==NULL))			panic("Can't ioremap RTC/CDM while computing bus freq");		/* Count bus clock during 1/64 sec */		out_be32(&rtc->dividers, 0x8f1f0000);	/* Set RTC 64x faster */		previous_time = in_be32(&rtc->time);		while ((current_time = in_be32(&rtc->time)) == previous_time) ;		tbl_start = get_tbl();		previous_time = current_time;		while ((current_time = in_be32(&rtc->time)) == previous_time) ;		tbl_end = get_tbl();		out_be32(&rtc->dividers, 0xffff0000);	/* Restore RTC */		/* Compute all frequency from that & CDM settings */		xlbfreq = (tbl_end - tbl_start) << 8;		cpufreq = (xlbfreq * core_mult[in_be32(&cdm->rstcfg)&0x1f])/10;		ipbfreq = (in_8(&cdm->ipb_clk_sel) & 1) ?					xlbfreq / 2 : xlbfreq;		switch (in_8(&cdm->pci_clk_sel) & 3) {		case 0:			pcifreq = ipbfreq;			break;		case 1:			pcifreq = ipbfreq / 2;			break;		default:			pcifreq = xlbfreq / 4;			break;		}		__res.bi_busfreq = xlbfreq;		__res.bi_intfreq = cpufreq;		__res.bi_ipbfreq = ipbfreq;		__res.bi_pcifreq = pcifreq;		/* Release mapping */		iounmap(rtc);		iounmap(cdm);	}	divisor = 4;	tb_ticks_per_jiffy = xlbfreq / HZ / divisor;	tb_to_us = mulhwu_scale_factor(xlbfreq / divisor, 1000000);}int mpc52xx_match_psc_function(int psc_idx, const char *func){	struct mpc52xx_psc_func *cf = mpc52xx_psc_functions;	while ((cf->id != -1) && (cf->func != NULL)) {		if ((cf->id == psc_idx) && !strcmp(cf->func,func))			return 1;		cf++;	}	return 0;}

⌨️ 快捷键说明

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