示例#1
0
/* The decrementer counts at the system bus clock frequency
 * divided by four.  The most accurate time base is connected to the
 * rtc.  We read the decrementer change during one rtc tick
 * and multiply by 4 to get the system bus clock frequency. Since a
 * rtc tick is one seconds, and that's pretty long, we change the rtc
 * dividers temporarly to set them 64x faster ;)
 */
static int
mpc52xx_ipbfreq(void)
{
    struct mpc52xx_rtc __iomem *rtc =
        (struct mpc52xx_rtc __iomem *) MPC52xx_PA(MPC52xx_RTC_OFFSET);
    struct mpc52xx_cdm __iomem *cdm =
        (struct mpc52xx_cdm __iomem *) MPC52xx_PA(MPC52xx_CDM_OFFSET);
    int current_time, previous_time;
    int tbl_start, tbl_end;
    int xlbfreq, ipbfreq;

    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 */

    xlbfreq = (tbl_end - tbl_start) << 8;
    ipbfreq = (in_8(&cdm->ipb_clk_sel) & 1) ? xlbfreq / 2 : xlbfreq;

    return ipbfreq;
}
示例#2
0
void __init
mpc52xx_init_irq(void)
{
	int i;
	u32 intr_ctrl;

	/* Remap the necessary zones */
	intr = ioremap(MPC52xx_PA(MPC52xx_INTR_OFFSET), MPC52xx_INTR_SIZE);
	sdma = ioremap(MPC52xx_PA(MPC52xx_SDMA_OFFSET), MPC52xx_SDMA_SIZE);

	if ((intr==NULL) || (sdma==NULL))
		panic("Can't ioremap PIC/SDMA register for init_irq !");

	/* Disable all interrupt sources. */
	out_be32(&sdma->IntPend, 0xffffffff);	/* 1 means clear pending */
	out_be32(&sdma->IntMask, 0xffffffff);	/* 1 means disabled */
	out_be32(&intr->per_mask, 0x7ffffc00);	/* 1 means disabled */
	out_be32(&intr->main_mask, 0x00010fff);	/* 1 means disabled */
	intr_ctrl = in_be32(&intr->ctrl);
	intr_ctrl &=    0x00ff0000;	/* Keeps IRQ[0-3] config */
	intr_ctrl |=	0x0f000000 |	/* clear IRQ 0-3 */
			0x00001000 |	/* MEE master external enable */
			0x00000000 |	/* 0 means disable IRQ 0-3 */
			0x00000001;	/* CEb route critical normally */
	out_be32(&intr->ctrl, intr_ctrl);

	/* Zero a bunch of the priority settings.  */
	out_be32(&intr->per_pri1, 0);
	out_be32(&intr->per_pri2, 0);
	out_be32(&intr->per_pri3, 0);
	out_be32(&intr->main_pri1, 0);
	out_be32(&intr->main_pri2, 0);

	/* Initialize irq_desc[i].chip's with mpc52xx_ic. */
	for (i = 0; i < NR_IRQS; i++) {
		irq_desc[i].chip = &mpc52xx_ic;
		irq_desc[i].status = IRQ_LEVEL;
	}

	#define IRQn_MODE(intr_ctrl,irq) (((intr_ctrl) >> (22-(i<<1))) & 0x03)
	for (i=0 ; i<4 ; i++) {
		int mode;
		mode = IRQn_MODE(intr_ctrl,i);
		if ((mode == 0x1) || (mode == 0x2))
			irq_desc[i?MPC52xx_IRQ1+i-1:MPC52xx_IRQ0].status = 0;
	}
}
示例#3
0
void __init
mpc52xx_setup_cpu(void)
{
    struct mpc52xx_cdm  __iomem *cdm;
    struct mpc52xx_xlb  __iomem *xlb;

    /* Map zones */
    cdm  = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
    xlb  = ioremap(MPC52xx_PA(MPC52xx_XLB_OFFSET), MPC52xx_XLB_SIZE);

    if (!cdm || !xlb) {
        printk(KERN_ERR __FILE__ ": "
               "Error while mapping CDM/XLB during "
               "mpc52xx_setup_cpu\n");
        goto unmap_regs;
    }

    /* Use internal 48 Mhz */
    out_8(&cdm->ext_48mhz_en, 0x00);
    out_8(&cdm->fd_enable, 0x01);
    if (in_be32(&cdm->rstcfg) & 0x40)	/* Assumes 33Mhz clock */
        out_be16(&cdm->fd_counters, 0x0001);
    else
        out_be16(&cdm->fd_counters, 0x5555);

    /* Configure the XLB Arbiter priorities */
    out_be32(&xlb->master_pri_enable, 0xff);
    out_be32(&xlb->master_priority, 0x11111111);

    /* Enable ram snooping for 1GB window */
    out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_SNOOP);
    out_be32(&xlb->snoop_window, MPC52xx_PCI_TARGET_MEM | 0x1d);

    /* Disable XLB pipelining */
    /* (cfr errata 292. We could do this only just before ATA PIO
        transaction and re-enable it after ...) */
    out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_PLDIS);

    /* Unmap reg zone */
unmap_regs:
    if (cdm)  iounmap(cdm);
    if (xlb)  iounmap(xlb);
}
示例#4
0
unsigned long
serial_init(int ignored, void *ignored2)
{
    struct mpc52xx_gpio __iomem *gpio =
        (struct mpc52xx_gpio __iomem *) MPC52xx_PA(MPC52xx_GPIO_OFFSET);
    int divisor;
    int mode1;
    int mode2;
    u32 val32;

    static int been_here = 0;

    if (been_here)
        return 0;

    been_here = 1;

    val32 = in_be32(&gpio->port_config);
    val32 &= ~(0x7 << MPC52xx_PSC_CONFIG_SHIFT);
    val32 |= MPC52xx_GPIO_PSC_CONFIG_UART_WITHOUT_CD
             << MPC52xx_PSC_CONFIG_SHIFT;
    out_be32(&gpio->port_config, val32);

    out_8(&psc->command, MPC52xx_PSC_RST_TX
          | MPC52xx_PSC_RX_DISABLE | MPC52xx_PSC_TX_ENABLE);
    out_8(&psc->command, MPC52xx_PSC_RST_RX);

    out_be32(&psc->sicr, 0x0);
    out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00);
    out_be16(&psc->tfalarm, 0xf8);

    out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1
          | MPC52xx_PSC_RX_ENABLE
          | MPC52xx_PSC_TX_ENABLE);

    divisor = ((mpc52xx_ipbfreq()
                / (CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD * 16)) + 1) >> 1;

    mode1 = MPC52xx_PSC_MODE_8_BITS | MPC52xx_PSC_MODE_PARNONE
            | MPC52xx_PSC_MODE_ERR;
    mode2 = MPC52xx_PSC_MODE_ONE_STOP;

    out_8(&psc->ctur, divisor>>8);
    out_8(&psc->ctlr, divisor);
    out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1);
    out_8(&psc->mode, mode1);
    out_8(&psc->mode, mode2);

    return 0;	/* ignored */
}
示例#5
0
int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv)
{
    static DEFINE_SPINLOCK(lock);
    struct mpc52xx_cdm __iomem *cdm;
    unsigned long flags;
    u16 mclken_div;
    u16 __iomem *reg;
    u32 mask;

    cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
    if (!cdm) {
        printk(KERN_ERR __FILE__ ": Error mapping CDM\n");
        return -ENODEV;
    }

    mclken_div = 0x8000 | (clkdiv & 0x1FF);
    switch (psc_id) {
    case 1:
        reg = &cdm->mclken_div_psc1;
        mask = 0x20;
        break;
    case 2:
        reg = &cdm->mclken_div_psc2;
        mask = 0x40;
        break;
    case 3:
        reg = &cdm->mclken_div_psc3;
        mask = 0x80;
        break;
    case 6:
        reg = &cdm->mclken_div_psc6;
        mask = 0x10;
        break;
    default:
        return -ENODEV;
    }

    /* Set the rate and enable the clock */
    spin_lock_irqsave(&lock, flags);
    out_be16(reg, mclken_div);
    out_be32(&cdm->clk_enables, in_be32(&cdm->clk_enables) | mask);
    spin_unlock_irqrestore(&lock, flags);

    iounmap(cdm);
    return 0;
}
示例#6
0
void __init
mpc52xx_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);
}
示例#7
0
#include <asm/mpc52xx.h>
#include <asm/mpc52xx_psc.h>
#include <asm/serial.h>
#include <asm/io.h>
#include <asm/time.h>


#ifdef MPC52xx_PF_CONSOLE_PORT
#define MPC52xx_CONSOLE MPC52xx_PSCx_OFFSET(MPC52xx_PF_CONSOLE_PORT)
#define MPC52xx_PSC_CONFIG_SHIFT ((MPC52xx_PF_CONSOLE_PORT-1)<<2)
#else
#error "MPC52xx_PF_CONSOLE_PORT not defined"
#endif

static struct mpc52xx_psc __iomem *psc =
    (struct mpc52xx_psc __iomem *) MPC52xx_PA(MPC52xx_CONSOLE);

/* The decrementer counts at the system bus clock frequency
 * divided by four.  The most accurate time base is connected to the
 * rtc.  We read the decrementer change during one rtc tick
 * and multiply by 4 to get the system bus clock frequency. Since a
 * rtc tick is one seconds, and that's pretty long, we change the rtc
 * dividers temporarly to set them 64x faster ;)
 */
static int
mpc52xx_ipbfreq(void)
{
    struct mpc52xx_rtc __iomem *rtc =
        (struct mpc52xx_rtc __iomem *) MPC52xx_PA(MPC52xx_RTC_OFFSET);
    struct mpc52xx_cdm __iomem *cdm =
        (struct mpc52xx_cdm __iomem *) MPC52xx_PA(MPC52xx_CDM_OFFSET);
static void __init
lite5200_setup_cpu(void)
{
    struct mpc52xx_cdm  __iomem *cdm;
    struct mpc52xx_gpio __iomem *gpio;
    struct mpc52xx_intr __iomem *intr;
    struct mpc52xx_xlb  __iomem *xlb;

    u32 port_config;
    u32 intr_ctrl;

    /* Map zones */
    cdm  = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
    gpio = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE);
    xlb  = ioremap(MPC52xx_PA(MPC52xx_XLB_OFFSET), MPC52xx_XLB_SIZE);
    intr = ioremap(MPC52xx_PA(MPC52xx_INTR_OFFSET), MPC52xx_INTR_SIZE);

    if (!cdm || !gpio || !xlb || !intr) {
        printk("lite5200.c: Error while mapping CDM/GPIO/XLB/INTR during"
               "lite5200_setup_cpu\n");
        goto unmap_regs;
    }

    /* Use internal 48 Mhz */
    out_8(&cdm->ext_48mhz_en, 0x00);
    out_8(&cdm->fd_enable, 0x01);
    if (in_be32(&cdm->rstcfg) & 0x40)	/* Assumes 33Mhz clock */
        out_be16(&cdm->fd_counters, 0x0001);
    else
        out_be16(&cdm->fd_counters, 0x5555);

    /* Get port mux config */
    port_config = in_be32(&gpio->port_config);

    /* 48Mhz internal, pin is GPIO */
    port_config &= ~0x00800000;

    /* USB port */
    port_config &= ~0x00007000;	/* Differential mode - USB1 only */
    port_config |=  0x00001000;

    /* Commit port config */
    out_be32(&gpio->port_config, port_config);

    /* Configure the XLB Arbiter */
    out_be32(&xlb->master_pri_enable, 0xff);
    out_be32(&xlb->master_priority, 0x11111111);

    /* Enable ram snooping for 1GB window */
    out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_SNOOP);
    out_be32(&xlb->snoop_window, MPC52xx_PCI_TARGET_MEM | 0x1d);

    /* IRQ[0-3] setup : IRQ0     - Level Active Low  */
    /*                  IRQ[1-3] - Level Active High */
    intr_ctrl = in_be32(&intr->ctrl);
    intr_ctrl &= ~0x00ff0000;
    intr_ctrl |=  0x00c00000;
    out_be32(&intr->ctrl, intr_ctrl);

    /* Unmap reg zone */
unmap_regs:
    if (cdm)  iounmap(cdm);
    if (gpio) iounmap(gpio);
    if (xlb)  iounmap(xlb);
    if (intr) iounmap(intr);
}