[BACK]Return to sapmc.c CVS log [TXT][DIR] Up to [local] / prex-old / dev / arm / cats

File: [local] / prex-old / dev / arm / cats / sapmc.c (download)

Revision 1.2, Fri Jul 25 16:09:19 2008 UTC (15 years, 9 months ago) by nbrk
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +2 -2 lines

switch CPU to its maximum frequency in machine_init();
clarify comments and prettify some messages while here

/*
 * $Id: sapmc.c,v 1.2 2008/07/25 16:09:19 nbrk Exp $
 */
/*
 * StrongARM 11x0 Power Management Controller.
 */
#include <driver.h>
#include <sys/ioctl.h>

#include "sapmc_reg.h"

int sapmc_init(void);
int sapmc_ioctl(device_t, int, u_long);
void	sapmc_setfreq(int mode);
uint32_t	sapmc_getfreq(void);

/*
 * Driver structure
 */
struct driver sapmc_drv = {
    /* name */ "SA-11x0 PMC",
    /* order */ 1,
    /* init */sapmc_init,
};

struct devio sapmc_io = {
    /* open */  NULL,
    /* close */ NULL,
    /* read */  NULL,
    /* write */ NULL,
    /* ioctl */ sapmc_ioctl,
    /* event */ NULL,
};

device_t sapmc_dev;


/*
 * XXX PLL controlled Core Clock Frequencies with 3686400 Hz oscillator.
 */
#define SAPMC_NFREQMODES	12

uint32_t	sapmc_ccfmodes[SAPMC_NFREQMODES] = {
	/* 0 */ 59000000,
	/* 1 */ 73700000,
	/* 2 */ 88500000,
	/* 3 */ 103200000,
	118000000,
	132700000,
	147500000,
	162200000,
	176900000,
	191700000,
	206400000,
	221200000
};

int
sapmc_init(void)
{
	/* register device */
	sapmc_dev = device_create(&sapmc_io, "sapmc", DF_CHR);

	return(0);
}


int
sapmc_ioctl(device_t dev, int cmd, u_long arg)
{
	/*
	 * ioctl() arg is a CCF mode (see datasheet).
	 */
	uint32_t	freq;

	switch(cmd) {
		case CPUIOC_SET_FREQ:
			umem_copyin((uint32_t *)arg, &freq, sizeof(uint32_t));
			if (freq > SAPMC_NFREQMODES)
				return(EINVAL);

			sapmc_setfreq(freq);
			break;

		case CPUIOC_GET_FREQ:
			freq = sapmc_getfreq();
			umem_copyout(&freq, (uint32_t *)arg, sizeof(uint32_t));
			break;
	}

	return(0);
}


void
sapmc_setfreq(int mode)
{
	*(volatile uint32_t *)(SAPMC_BASE + SAPMC_PPCR) = (mode & CCF);
}


uint32_t
sapmc_getfreq(void)
{
	int mode;

	mode = *(volatile uint32_t *)(SAPMC_BASE + SAPMC_PPCR);

	return(sapmc_ccfmodes[mode]);
}