Beispiel #1
0
static void
at91_clock_init(void)
{
	struct at91_pmc_clock *clk;

	/* Update USB device port clock info */
	clk = at91_pmc_clock_ref("udpck");
	clk->pmc_mask  = PMC_SCER_UDP_SAM9;
	at91_pmc_clock_deref(clk);

	/* Update USB host port clock info */
	clk = at91_pmc_clock_ref("uhpck");
	clk->pmc_mask  = PMC_SCER_UHP_SAM9;
	at91_pmc_clock_deref(clk);

	/* Each SOC has different PLL contraints */
	clk = at91_pmc_clock_ref("plla");
	clk->pll_min_in    = SAM9260_PLL_A_MIN_IN_FREQ;		/*   1 MHz */
	clk->pll_max_in    = SAM9260_PLL_A_MAX_IN_FREQ;		/*  32 MHz */
	clk->pll_min_out   = SAM9260_PLL_A_MIN_OUT_FREQ;	/*  80 MHz */
	clk->pll_max_out   = SAM9260_PLL_A_MAX_OUT_FREQ;	/* 240 MHz */
	clk->pll_mul_shift = SAM9260_PLL_A_MUL_SHIFT;
	clk->pll_mul_mask  = SAM9260_PLL_A_MUL_MASK;
	clk->pll_div_shift = SAM9260_PLL_A_DIV_SHIFT;
	clk->pll_div_mask  = SAM9260_PLL_A_DIV_MASK;
	clk->set_outb      = at91_pll_outa;
	at91_pmc_clock_deref(clk);

	/*
	 * Fudge MAX pll in frequence down below 3.0 MHz to ensure
	 * PMC alogrithm choose the divisor that causes the input clock
	 * to be near the optimal 2 MHz per datasheet.  We know
	 * we are going to be using this for the USB clock at 96 MHz.
	 * Causes no extra frequency deviation for all recomended crystal
	 * values.  See Note 1, table 40-16 SAM9260 doc.
	 */
	clk = at91_pmc_clock_ref("pllb");
	clk->pll_min_in    = SAM9260_PLL_B_MIN_IN_FREQ;		/*   1 MHz */
	clk->pll_max_in    = SAM9260_PLL_B_MAX_IN_FREQ;		/*   5 MHz */
	clk->pll_max_in    = 2999999;				/*  ~3 MHz */
	clk->pll_min_out   = SAM9260_PLL_B_MIN_OUT_FREQ;	/*  70 MHz */
	clk->pll_max_out   = SAM9260_PLL_B_MAX_OUT_FREQ;	/* 130 MHz */
	clk->pll_mul_shift = SAM9260_PLL_B_MUL_SHIFT;
	clk->pll_mul_mask  = SAM9260_PLL_B_MUL_MASK;
	clk->pll_div_shift = SAM9260_PLL_B_DIV_SHIFT;
	clk->pll_div_mask  = SAM9260_PLL_B_DIV_MASK;
	clk->set_outb      = at91_pll_outb;
	at91_pmc_clock_deref(clk);
}
Beispiel #2
0
/*
 * Allow the master clock frequency to be changed from whatever the bootloader
 * set up, because sometimes it's harder to change/update a bootloader than it
 * is to change/update the kernel once a product is in the field.
 */
static void
master_clock_init(void)
{
	uint32_t mckr = RD4HW(AT91RM92_PMC_BASE, PMC_MCKR);
	int hintvalue = 0;
	int newmckr = 0;

	 /*
	 * If there's a hint that specifies the contents of MCKR, use it
	 * without question (it had better be right).
	 *
	 * If there's a "mckfreq" hint it might be in hertz or mhz (convert the
	 * latter to hz).  Calculate the new MCK divider.  If the CPU frequency
	 * is not a sane multiple of the hinted MCK frequency this is likely to
	 * behave badly.  The moral is: don't hint at impossibilities.
	 */

	if (resource_int_value("at91", 0, "mckr", &hintvalue) == 0) {
		newmckr = hintvalue;
	} else {
		hintvalue = 90; /* Default to 90mhz if not specified. */
		resource_int_value("at91", 0, "mckfreq", &hintvalue);
		if (hintvalue != 0) {
			if (hintvalue < 1000)
				hintvalue *= 1000000;
			if (hintvalue != at91_master_clock) {
				uint32_t divider;
				struct at91_pmc_clock * cpuclk;
				cpuclk = at91_pmc_clock_ref("cpu");
				divider = (cpuclk->hz / hintvalue) - 1;
				newmckr = (mckr & 0xFFFFFCFF) | ((divider & 0x03) << 8);
				at91_pmc_clock_deref(cpuclk);
			}
		}
	}

	/* If the new mckr value is different than what's in the register now,
	 * make the change and wait for the clocks to settle (MCKRDY status).
	 *
	 * MCKRDY will never be asserted unless either the selected clock or the
	 * prescaler value changes (but not both at once) [this is detailed in
	 * the rm9200 errata]. This code assumes the prescaler value is always
	 * zero and that by time we get to here we're running on something other
	 * than the slow clock, so to change the mckr divider we first change
	 * back to the slow clock (keeping prescaler and divider unchanged),
	 * then go back to the original selected clock with the new divider.
	 *
	 * After changing MCK, go re-init everything clock-related, and reset
	 * the baud rate generator for the console (doing this here is kind of a
	 * rude hack, but hey, you do what you have to to run MCK faster).
	 */

	if (newmckr != 0 && newmckr != mckr) {
		if (mckr & 0x03)
			change_mckr(mckr & ~0x03);
		change_mckr(newmckr);
		at91_pmc_init_clock();
		WR4HW(AT91RM92_DBGU_BASE, USART_BRGR, BAUD2DIVISOR(115200));
	}
}
Beispiel #3
0
static void
at91_clock_init(void)
{
	struct at91_pmc_clock *clk;

	/* Update USB device port clock info */
	clk = at91_pmc_clock_ref("udpck");
	clk->pmc_mask  = PMC_SCER_UDP;
	at91_pmc_clock_deref(clk);

	/* Update USB host port clock info */
	clk = at91_pmc_clock_ref("uhpck");
	clk->pmc_mask  = PMC_SCER_UHP;
	at91_pmc_clock_deref(clk);

	/* Each SOC has different PLL contraints */
	clk = at91_pmc_clock_ref("plla");
	clk->pll_min_in    = RM9200_PLL_A_MIN_IN_FREQ;		/*   1 MHz */
	clk->pll_max_in    = RM9200_PLL_A_MAX_IN_FREQ;		/*  32 MHz */
	clk->pll_min_out   = RM9200_PLL_A_MIN_OUT_FREQ;		/*  80 MHz */
	clk->pll_max_out   = RM9200_PLL_A_MAX_OUT_FREQ;		/* 180 MHz */
	clk->pll_mul_shift = RM9200_PLL_A_MUL_SHIFT;
	clk->pll_mul_mask  = RM9200_PLL_A_MUL_MASK;
	clk->pll_div_shift = RM9200_PLL_A_DIV_SHIFT;
	clk->pll_div_mask  = RM9200_PLL_A_DIV_MASK;
	clk->set_outb      = at91_pll_outb;
	at91_pmc_clock_deref(clk);

	clk = at91_pmc_clock_ref("pllb");
	clk->pll_min_in    = RM9200_PLL_B_MIN_IN_FREQ;		/* 100 KHz */
	clk->pll_max_in    = RM9200_PLL_B_MAX_IN_FREQ;		/*  32 MHz */
	clk->pll_min_out   = RM9200_PLL_B_MIN_OUT_FREQ;		/*  30 MHz */
	clk->pll_max_out   = RM9200_PLL_B_MAX_OUT_FREQ;		/* 240 MHz */
	clk->pll_mul_shift = RM9200_PLL_B_MUL_SHIFT;
	clk->pll_mul_mask  = RM9200_PLL_B_MUL_MASK;
	clk->pll_div_shift = RM9200_PLL_B_DIV_SHIFT;
	clk->pll_div_mask  = RM9200_PLL_B_DIV_MASK;
	clk->set_outb      = at91_pll_outb;
	at91_pmc_clock_deref(clk);
}
Beispiel #4
0
static void
at91_clock_init(void)
{
	struct at91_pmc_clock *clk;

	/* Update USB host port clock info */
	clk = at91_pmc_clock_ref("uhpck");
	clk->pmc_mask  = PMC_SCER_UHP_SAM9;
	at91_pmc_clock_deref(clk);

	/* Each SOC has different PLL contraints */
	clk = at91_pmc_clock_ref("plla");
	clk->pll_min_in    = SAM9G45_PLL_A_MIN_IN_FREQ;		/*   2 MHz */
	clk->pll_max_in    = SAM9G45_PLL_A_MAX_IN_FREQ;		/*  32 MHz */
	clk->pll_min_out   = SAM9G45_PLL_A_MIN_OUT_FREQ;	/* 400 MHz */
	clk->pll_max_out   = SAM9G45_PLL_A_MAX_OUT_FREQ;	/* 800 MHz */
	clk->pll_mul_shift = SAM9G45_PLL_A_MUL_SHIFT;
	clk->pll_mul_mask  = SAM9G45_PLL_A_MUL_MASK;
	clk->pll_div_shift = SAM9G45_PLL_A_DIV_SHIFT;
	clk->pll_div_mask  = SAM9G45_PLL_A_DIV_MASK;
	clk->set_outb      = at91_pmc_800mhz_plla_outb;
	at91_pmc_clock_deref(clk);
}
Beispiel #5
0
void
cpu_initclocks(void)
{
	struct at91_pmc_clock *master;

	master = at91_pmc_clock_ref("mck");
	pit_rate =  master->hz / 16;
	pit_cycle = (pit_rate + HZ/2) / HZ;	
	at91pit_timecounter.tc_frequency = pit_rate;
	WR4(PIT_MR, 0);

	while (PIT_PIV(RD4(PIT_PIVR)) != 0);
		
	WR4(PIT_MR, (pit_cycle - 1) | PIT_IEN | PIT_EN);
	tc_init(&at91pit_timecounter);
}
Beispiel #6
0
static int
at91_udp_attach(device_t dev)
{
	struct at91_udp_softc *sc = device_get_softc(dev);
	int err;
	int rid;

	/* setup AT9100 USB device controller interface softc */

	sc->sc_dci.sc_clocks_on = &at91_udp_clocks_on;
	sc->sc_dci.sc_clocks_off = &at91_udp_clocks_off;
	sc->sc_dci.sc_clocks_arg = sc;
	sc->sc_dci.sc_pull_up = &at91_udp_pull_up;
	sc->sc_dci.sc_pull_down = &at91_udp_pull_down;
	sc->sc_dci.sc_pull_arg = sc;

	/* initialise some bus fields */
	sc->sc_dci.sc_bus.parent = dev;
	sc->sc_dci.sc_bus.devices = sc->sc_dci.sc_devices;
	sc->sc_dci.sc_bus.devices_max = AT91_MAX_DEVICES;

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_dci.sc_bus,
	    USB_GET_DMA_TAG(dev), NULL)) {
		return (ENOMEM);
	}
	callout_init_mtx(&sc->sc_vbus, &sc->sc_dci.sc_bus.bus_mtx, 0);

	/*
	 * configure VBUS input pin, enable deglitch and enable
	 * interrupt :
	 */
	at91_pio_use_gpio(VBUS_BASE, VBUS_MASK);
	at91_pio_gpio_input(VBUS_BASE, VBUS_MASK);
	at91_pio_gpio_set_deglitch(VBUS_BASE, VBUS_MASK, 1);
	at91_pio_gpio_set_interrupt(VBUS_BASE, VBUS_MASK, 0);

	/*
	 * configure PULLUP output pin :
	 */
	at91_pio_use_gpio(PULLUP_BASE, PULLUP_MASK);
	at91_pio_gpio_output(PULLUP_BASE, PULLUP_MASK, 0);

	at91_udp_pull_down(sc);

	/* wait 10ms for pulldown to stabilise */
	usb_pause_mtx(NULL, hz / 100);

	sc->sc_mclk = at91_pmc_clock_ref("mck");
	sc->sc_iclk = at91_pmc_clock_ref("udc_clk");
	sc->sc_fclk = at91_pmc_clock_ref("udpck");

	rid = MEM_RID;
	sc->sc_dci.sc_io_res =
	    bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);

	if (!(sc->sc_dci.sc_io_res)) {
		err = ENOMEM;
		goto error;
	}
	sc->sc_dci.sc_io_tag = rman_get_bustag(sc->sc_dci.sc_io_res);
	sc->sc_dci.sc_io_hdl = rman_get_bushandle(sc->sc_dci.sc_io_res);
	sc->sc_dci.sc_io_size = rman_get_size(sc->sc_dci.sc_io_res);

	rid = 0;
	sc->sc_dci.sc_irq_res =
	    bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
	if (!(sc->sc_dci.sc_irq_res)) {
		goto error;
	}
	sc->sc_dci.sc_bus.bdev = device_add_child(dev, "usbus", -1);
	if (!(sc->sc_dci.sc_bus.bdev)) {
		goto error;
	}
	device_set_ivars(sc->sc_dci.sc_bus.bdev, &sc->sc_dci.sc_bus);

	err = bus_setup_intr(dev, sc->sc_dci.sc_irq_res, INTR_TYPE_TTY | INTR_MPSAFE,
	    at91dci_filter_interrupt, at91dci_interrupt, sc, &sc->sc_dci.sc_intr_hdl);
	if (err) {
		sc->sc_dci.sc_intr_hdl = NULL;
		goto error;
	}

	err = at91dci_init(&sc->sc_dci);
	if (!err) {
		err = device_probe_and_attach(sc->sc_dci.sc_bus.bdev);
	}
	if (err) {
		goto error;
	} else {
		/* poll VBUS one time */
		USB_BUS_LOCK(&sc->sc_dci.sc_bus);
		at91_vbus_poll(sc);
		USB_BUS_UNLOCK(&sc->sc_dci.sc_bus);
	}
	return (0);

error:
	at91_udp_detach(dev);
	return (ENXIO);
}
Beispiel #7
0
static int
ohci_atmelarm_attach(device_t dev)
{
    struct at91_ohci_softc *sc = device_get_softc(dev);
    int err;
    int rid;

    /* initialise some bus fields */
    sc->sc_ohci.sc_bus.parent = dev;
    sc->sc_ohci.sc_bus.devices = sc->sc_ohci.sc_devices;
    sc->sc_ohci.sc_bus.devices_max = OHCI_MAX_DEVICES;

    /* get all DMA memory */
    if (usb_bus_mem_alloc_all(&sc->sc_ohci.sc_bus,
                              USB_GET_DMA_TAG(dev), &ohci_iterate_hw_softc)) {
        return (ENOMEM);
    }
    sc->iclk = at91_pmc_clock_ref("ohci_clk");
    sc->fclk = at91_pmc_clock_ref("uhpck");

    sc->sc_ohci.sc_dev = dev;

    rid = MEM_RID;
    sc->sc_ohci.sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
                            &rid, RF_ACTIVE);

    if (!(sc->sc_ohci.sc_io_res)) {
        err = ENOMEM;
        goto error;
    }
    sc->sc_ohci.sc_io_tag = rman_get_bustag(sc->sc_ohci.sc_io_res);
    sc->sc_ohci.sc_io_hdl = rman_get_bushandle(sc->sc_ohci.sc_io_res);
    sc->sc_ohci.sc_io_size = rman_get_size(sc->sc_ohci.sc_io_res);

    rid = 0;
    sc->sc_ohci.sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
                             RF_ACTIVE);
    if (!(sc->sc_ohci.sc_irq_res)) {
        goto error;
    }
    sc->sc_ohci.sc_bus.bdev = device_add_child(dev, "usbus", -1);
    if (!(sc->sc_ohci.sc_bus.bdev)) {
        goto error;
    }
    device_set_ivars(sc->sc_ohci.sc_bus.bdev, &sc->sc_ohci.sc_bus);

    strlcpy(sc->sc_ohci.sc_vendor, "Atmel", sizeof(sc->sc_ohci.sc_vendor));

#if (__FreeBSD_version >= 700031)
    err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
                         NULL, (driver_intr_t *)ohci_interrupt, sc, &sc->sc_ohci.sc_intr_hdl);
#else
    err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
                         (driver_intr_t *)ohci_interrupt, sc, &sc->sc_ohci.sc_intr_hdl);
#endif
    if (err) {
        sc->sc_ohci.sc_intr_hdl = NULL;
        goto error;
    }
    /*
     * turn on the clocks from the AT91's point of view.  Keep the unit in reset.
     */
    at91_pmc_clock_enable(sc->iclk);
    at91_pmc_clock_enable(sc->fclk);
    bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl,
                      OHCI_CONTROL, 0);

    err = ohci_init(&sc->sc_ohci);
    if (!err) {
        err = device_probe_and_attach(sc->sc_ohci.sc_bus.bdev);
    }
    if (err) {
        goto error;
    }
    return (0);

error:
    ohci_atmelarm_detach(dev);
    return (ENXIO);
}
Beispiel #8
0
static int
at91_attach(device_t dev)
{
	struct at91_pmc_clock *clk;
	struct at91sam9_softc *sc = device_get_softc(dev);
	int i;

	struct at91_softc *at91sc = device_get_softc(device_get_parent(dev));

	sc->sc_st = at91sc->sc_st;
	sc->sc_sh = at91sc->sc_sh;
	sc->dev = dev;

	/* 
	 * XXX These values work for the RM9200, SAM926[01], and SAM9260
	 * will have to fix this when we want to support anything else. XXX
	 */
	if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9260_SYS_BASE,
	    AT91SAM9260_SYS_SIZE, &sc->sc_sys_sh) != 0)
		panic("Enable to map system registers");

	if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9260_DBGU_BASE,
	    AT91SAM9260_DBGU_SIZE, &sc->sc_dbg_sh) != 0)
		panic("Enable to map DBGU registers");

	if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9260_AIC_BASE,
	    AT91SAM9260_AIC_SIZE, &sc->sc_aic_sh) != 0)
		panic("Enable to map system registers");

	/* XXX Hack to tell atmelarm about the AIC */
	at91sc->sc_aic_sh = sc->sc_aic_sh;
	at91sc->sc_irq_system = AT91SAM9260_IRQ_SYSTEM;

	for (i = 0; i < 32; i++) {
		bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SVR + 
		    i * 4, i);
		/* Priority. */
		bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SMR + i * 4,
		    at91_irq_prio[i]);
		if (i < 8)
			bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_EOICR,
			    1);
	}

	bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SPU, 32);
	/* No debug. */
	bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_DCR, 0);
	/* Disable and clear all interrupts. */
	bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_IDCR, 0xffffffff);
	bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_ICCR, 0xffffffff);

	/* Disable all interrupts for DBGU */
	bus_space_write_4(sc->sc_st, sc->sc_dbg_sh, 0x0c, 0xffffffff);

	if (bus_space_subregion(sc->sc_st, sc->sc_sh,
	    AT91SAM9260_MATRIX_BASE, AT91SAM9260_MATRIX_SIZE,
	    &sc->sc_matrix_sh) != 0)
		panic("Enable to map matrix registers");

	/* activate NAND*/
	i = bus_space_read_4(sc->sc_st, sc->sc_matrix_sh,
	    AT91SAM9260_EBICSA);
	bus_space_write_4(sc->sc_st, sc->sc_matrix_sh,
	    AT91SAM9260_EBICSA, 
	    i | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);


	/* Update USB device port clock info */
	clk = at91_pmc_clock_ref("udpck");
	clk->pmc_mask  = PMC_SCER_UDP_SAM9;
	at91_pmc_clock_deref(clk);

	/* Update USB host port clock info */
	clk = at91_pmc_clock_ref("uhpck");
	clk->pmc_mask  = PMC_SCER_UHP_SAM9;
	at91_pmc_clock_deref(clk);

	/* Each SOC has different PLL contraints */
	clk = at91_pmc_clock_ref("plla");
	clk->pll_min_in    = SAM9260_PLL_A_MIN_IN_FREQ;		/*   1 MHz */
	clk->pll_max_in    = SAM9260_PLL_A_MAX_IN_FREQ;		/*  32 MHz */
	clk->pll_min_out   = SAM9260_PLL_A_MIN_OUT_FREQ;	/*  80 MHz */
	clk->pll_max_out   = SAM9260_PLL_A_MAX_OUT_FREQ;	/* 240 MHz */
	clk->pll_mul_shift = SAM9260_PLL_A_MUL_SHIFT;
	clk->pll_mul_mask  = SAM9260_PLL_A_MUL_MASK;
	clk->pll_div_shift = SAM9260_PLL_A_DIV_SHIFT;
	clk->pll_div_mask  = SAM9260_PLL_A_DIV_MASK;
	clk->set_outb      = at91_pll_outa;
	at91_pmc_clock_deref(clk);

	/*
	 * Fudge MAX pll in frequence down below 3.0 Mhz to ensure 
	 * PMC alogrithm choose the divisor that causes the input clock 
	 * to be near the optimal 2 Mhz per datasheet. We know
	 * we are going to be using this for the USB clock at 96 Mhz.
	 * Causes no extra frequency deviation for all recomended crystal values.
	 */
	clk = at91_pmc_clock_ref("pllb");
	clk->pll_min_in    = SAM9260_PLL_B_MIN_IN_FREQ;		/*   1 MHz */
	clk->pll_max_in    = SAM9260_PLL_B_MAX_IN_FREQ;		/*   5 MHz */
	clk->pll_max_in    = 2999999;				/*  ~3 MHz */
	clk->pll_min_out   = SAM9260_PLL_B_MIN_OUT_FREQ;	/*  70 MHz */
	clk->pll_max_out   = SAM9260_PLL_B_MAX_OUT_FREQ;	/* 130 MHz */
	clk->pll_mul_shift = SAM9260_PLL_B_MUL_SHIFT;
	clk->pll_mul_mask  = SAM9260_PLL_B_MUL_MASK;
	clk->pll_div_shift = SAM9260_PLL_B_DIV_SHIFT;
	clk->pll_div_mask  = SAM9260_PLL_B_DIV_MASK;
	clk->set_outb      = at91_pll_outb;
	at91_pmc_clock_deref(clk);
	return (0);
}
Beispiel #9
0
static int
at91_attach(device_t dev)
{
	struct at91_pmc_clock *clk;
	struct at91sam9_softc *sc = device_get_softc(dev);
	int i;

	struct at91_softc *at91sc = device_get_softc(device_get_parent(dev));

	sc->sc_st = at91sc->sc_st;
	sc->sc_sh = at91sc->sc_sh;
	sc->dev = dev;

	/* 
	 * XXX These values work for the RM9200, SAM926[01], and SAM9G20
	 * will have to fix this when we want to support anything else. XXX
	 */
	if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9G20_SYS_BASE,
	    AT91SAM9G20_SYS_SIZE, &sc->sc_sys_sh) != 0)
		panic("Enable to map system registers");

	if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9G20_DBGU_BASE,
	    AT91SAM9G20_DBGU_SIZE, &sc->sc_dbg_sh) != 0)
		panic("Enable to map DBGU registers");

	if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9G20_AIC_BASE,
	    AT91SAM9G20_AIC_SIZE, &sc->sc_aic_sh) != 0)
		panic("Enable to map system registers");

	/* XXX Hack to tell atmelarm about the AIC */
	at91sc->sc_aic_sh = sc->sc_aic_sh;
	at91sc->sc_irq_system = AT91SAM9G20_IRQ_SYSTEM;

	for (i = 0; i < 32; i++) {
		bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SVR + 
		    i * 4, i);
		/* Priority. */
		bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SMR + i * 4,
		    at91_irq_prio[i]);
		if (i < 8)
			bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_EOICR,
			    1);
	}

	bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SPU, 32);
	/* No debug. */
	bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_DCR, 0);
	/* Disable and clear all interrupts. */
	bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_IDCR, 0xffffffff);
	bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_ICCR, 0xffffffff);

	/* Disable all interrupts for DBGU */
	bus_space_write_4(sc->sc_st, sc->sc_dbg_sh, 0x0c, 0xffffffff);

	if (bus_space_subregion(sc->sc_st, sc->sc_sh,
	    AT91SAM9G20_MATRIX_BASE, AT91SAM9G20_MATRIX_SIZE,
	    &sc->sc_matrix_sh) != 0)
		panic("Enable to map matrix registers");

	/* activate NAND*/
	i = bus_space_read_4(sc->sc_st, sc->sc_matrix_sh,
	    AT91SAM9G20_EBICSA);
	bus_space_write_4(sc->sc_st, sc->sc_matrix_sh,
	    AT91SAM9G20_EBICSA, 
	    i | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);


	/* Update USB device port clock info */
	clk = at91_pmc_clock_ref("udpck");
	clk->pmc_mask  = PMC_SCER_UDP_SAM9;
	at91_pmc_clock_deref(clk);

	/* Update USB host port clock info */
	clk = at91_pmc_clock_ref("uhpck");
	clk->pmc_mask  = PMC_SCER_UHP_SAM9;
	at91_pmc_clock_deref(clk);

	/* Each SOC has different PLL contraints */
	clk = at91_pmc_clock_ref("plla");
	clk->pll_min_in    = SAM9G20_PLL_A_MIN_IN_FREQ;		/*   2 MHz */
	clk->pll_max_in    = SAM9G20_PLL_A_MAX_IN_FREQ;		/*  32 MHz */
	clk->pll_min_out   = SAM9G20_PLL_A_MIN_OUT_FREQ;	/* 400 MHz */
	clk->pll_max_out   = SAM9G20_PLL_A_MAX_OUT_FREQ;	/* 800 MHz */
	clk->pll_mul_shift = SAM9G20_PLL_A_MUL_SHIFT;
	clk->pll_mul_mask  = SAM9G20_PLL_A_MUL_MASK;
	clk->pll_div_shift = SAM9G20_PLL_A_DIV_SHIFT;
	clk->pll_div_mask  = SAM9G20_PLL_A_DIV_MASK;
	clk->set_outb      = at91_pll_outa;
	at91_pmc_clock_deref(clk);

	clk = at91_pmc_clock_ref("pllb");
	clk->pll_min_in    = SAM9G20_PLL_B_MIN_IN_FREQ;		/*   2 MHz */
	clk->pll_max_in    = SAM9G20_PLL_B_MAX_IN_FREQ;		/*  32 MHz */
	clk->pll_min_out   = SAM9G20_PLL_B_MIN_OUT_FREQ;	/*  30 MHz */
	clk->pll_max_out   = SAM9G20_PLL_B_MAX_OUT_FREQ;	/* 100 MHz */
	clk->pll_mul_shift = SAM9G20_PLL_B_MUL_SHIFT;
	clk->pll_mul_mask  = SAM9G20_PLL_B_MUL_MASK;
	clk->pll_div_shift = SAM9G20_PLL_B_DIV_SHIFT;
	clk->pll_div_mask  = SAM9G20_PLL_B_DIV_MASK;
	clk->set_outb      = at91_pll_outb;
	at91_pmc_clock_deref(clk);
	return (0);
}
Beispiel #10
0
static int
at91_attach(device_t dev)
{
	struct at91_pmc_clock *clk;
	struct at91rm92_softc *sc = device_get_softc(dev);
	int i;

	struct at91_softc *at91sc = device_get_softc(device_get_parent(dev));

	sc->sc_st = at91sc->sc_st;
	sc->sc_sh = at91sc->sc_sh;
	sc->dev = dev;

	if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91RM92_SYS_BASE,
	    AT91RM92_SYS_SIZE, &sc->sc_sys_sh) != 0)
		panic("Enable to map system registers");

	if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91RM92_DBGU_BASE,
	    AT91RM92_DBGU_SIZE, &sc->sc_dbg_sh) != 0)
		panic("Enable to map DBGU registers");

	if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91RM92_AIC_BASE,
	    AT91RM92_AIC_SIZE, &sc->sc_aic_sh) != 0)
		panic("Enable to map system registers");

	/* XXX Hack to tell atmelarm about the AIC */
	at91sc->sc_aic_sh = sc->sc_aic_sh;
	at91sc->sc_irq_system = AT91RM92_IRQ_SYSTEM;

	for (i = 0; i < 32; i++) {
		bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SVR + 
		    i * 4, i);
		/* Priority. */
		bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SMR + i * 4,
		    at91_irq_prio[i]);
		if (i < 8)
			bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_EOICR,
			    1);
	}

	bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SPU, 32);
	/* No debug. */
	bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_DCR, 0);
	/* Disable and clear all interrupts. */
	bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_IDCR, 0xffffffff);
	bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_ICCR, 0xffffffff);

	/* Disable all interrupts for RTC (0xe24 == RTC_IDR) */
	bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0xe24, 0xffffffff);

	/* Disable all interrupts for the SDRAM controller */
	bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0xfa8, 0xffffffff);

	/* Disable all interrupts for DBGU */
	bus_space_write_4(sc->sc_st, sc->sc_dbg_sh, 0x0c, 0xffffffff);

	/* Update USB device port clock info */
	clk = at91_pmc_clock_ref("udpck");
	clk->pmc_mask  = PMC_SCER_UDP;
	at91_pmc_clock_deref(clk);

	/* Update USB host port clock info */
	clk = at91_pmc_clock_ref("uhpck");
	clk->pmc_mask  = PMC_SCER_UHP;
	at91_pmc_clock_deref(clk);

	/* Each SOC has different PLL contraints */
	clk = at91_pmc_clock_ref("plla");
	clk->pll_min_in    = RM9200_PLL_A_MIN_IN_FREQ;		/*   1 MHz */
	clk->pll_max_in    = RM9200_PLL_A_MAX_IN_FREQ;		/*  32 MHz */
	clk->pll_min_out   = RM9200_PLL_A_MIN_OUT_FREQ;		/*  80 MHz */
	clk->pll_max_out   = RM9200_PLL_A_MAX_OUT_FREQ;		/* 180 MHz */
	clk->pll_mul_shift = RM9200_PLL_A_MUL_SHIFT;
	clk->pll_mul_mask  = RM9200_PLL_A_MUL_MASK;
	clk->pll_div_shift = RM9200_PLL_A_DIV_SHIFT;
	clk->pll_div_mask  = RM9200_PLL_A_DIV_MASK;
	clk->set_outb      = at91_pll_outb;
	at91_pmc_clock_deref(clk);

	clk = at91_pmc_clock_ref("pllb");
	clk->pll_min_in    = RM9200_PLL_B_MIN_IN_FREQ;		/* 100 KHz */
	clk->pll_max_in    = RM9200_PLL_B_MAX_IN_FREQ;		/*  32 MHz */
	clk->pll_min_out   = RM9200_PLL_B_MIN_OUT_FREQ;		/*  30 MHz */
	clk->pll_max_out   = RM9200_PLL_B_MAX_OUT_FREQ;		/* 240 MHz */
	clk->pll_mul_shift = RM9200_PLL_B_MUL_SHIFT;
	clk->pll_mul_mask  = RM9200_PLL_B_MUL_MASK;
	clk->pll_div_shift = RM9200_PLL_B_DIV_SHIFT;
	clk->pll_div_mask  = RM9200_PLL_B_DIV_MASK;
	clk->set_outb      = at91_pll_outb;
	at91_pmc_clock_deref(clk);

	return (0);
}