示例#1
0
static void
octeon_gpio_pin_configure(struct octeon_gpio_softc *sc, struct gpio_pin *pin,
                          unsigned int flags)
{
    uint32_t mask;
    cvmx_gpio_bit_cfgx_t gpio_cfgx;

    mask = 1 << pin->gp_pin;
    GPIO_LOCK(sc);

    /*
     * Manage input/output
     */
    if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
        gpio_cfgx.u64 = cvmx_read_csr(CVMX_GPIO_BIT_CFGX(pin->gp_pin));
        pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT);
        if (flags & GPIO_PIN_OUTPUT) {
            pin->gp_flags |= GPIO_PIN_OUTPUT;
            gpio_cfgx.s.tx_oe = 1;
        }
        else {
            pin->gp_flags |= GPIO_PIN_INPUT;
            gpio_cfgx.s.tx_oe = 0;
        }
        if (flags & GPIO_PIN_INVIN)
            gpio_cfgx.s.rx_xor = 1;
        else
            gpio_cfgx.s.rx_xor = 0;
        cvmx_write_csr(CVMX_GPIO_BIT_CFGX(pin->gp_pin), gpio_cfgx.u64);
    }

    GPIO_UNLOCK(sc);
}
示例#2
0
static inline void pll_reset (void)
{
	/* load M,N */
	udelay (40000000); /* delay CPU clock */

	/* set GPIO13 to write  (Reset PLL) */
	cvmx_write_csr (CVMX_GPIO_BIT_CFGX(13), GPIO_WRITE_EN);

	/* set GPIO13 output 1 */
	cvmx_write_csr (CVMX_GPIO_TX_SET, GPIO_13_BIT);
}
示例#3
0
static int
octeon_gpio_filter(void *arg)
{
    cvmx_gpio_bit_cfgx_t gpio_cfgx;
    void **cookie = arg;
    struct octeon_gpio_softc *sc = *cookie;
    long int irq = (cookie - sc->gpio_intr_cookies);

    if ((irq < 0) || (irq >= OCTEON_GPIO_IRQS))
        return (FILTER_STRAY);

    gpio_cfgx.u64 = cvmx_read_csr(CVMX_GPIO_BIT_CFGX(irq));
    /* Clear rising edge detector */
    if (gpio_cfgx.s.int_type == OCTEON_GPIO_IRQ_EDGE)
        cvmx_gpio_interrupt_clear(1 << irq);
    /* disable interrupt  */
    gpio_cfgx.s.int_en = 0;
    cvmx_write_csr(CVMX_GPIO_BIT_CFGX(irq), gpio_cfgx.u64);

    return (FILTER_SCHEDULE_THREAD);
}
示例#4
0
static void
octeon_gpio_intr(void *arg)
{
    cvmx_gpio_bit_cfgx_t gpio_cfgx;
    void **cookie = arg;
    struct octeon_gpio_softc *sc = *cookie;
    long int irq = (cookie - sc->gpio_intr_cookies);

    if ((irq < 0) || (irq >= OCTEON_GPIO_IRQS)) {
        printf("%s: invalid GPIO IRQ: %ld\n",
               __func__, irq);
        return;
    }

    GPIO_LOCK(sc);
    gpio_cfgx.u64 = cvmx_read_csr(CVMX_GPIO_BIT_CFGX(irq));
    /* disable interrupt  */
    gpio_cfgx.s.int_en = 1;
    cvmx_write_csr(CVMX_GPIO_BIT_CFGX(irq), gpio_cfgx.u64);

    /* TODO: notify bus here or something */
    printf("GPIO IRQ for pin %ld\n", irq);
    GPIO_UNLOCK(sc);
}
示例#5
0
/* simple bus use octeon GPIO 9 (CK) GPIO 10 (DA)  GPIO 11 (EN) as signal. */
static inline void init_bus (void)
{
	/* set GPIO  9 to write  (CK) */
	cvmx_write_csr (CVMX_GPIO_BIT_CFGX(9), cvmx_read_csr (CVMX_GPIO_BIT_CFGX(9))
				       | GPIO_WRITE_EN);
	/* set GPIO9 output 0 */
	cvmx_write_csr (CVMX_GPIO_TX_CLR, GPIO_9_BIT);

	/* set GPIO 10 to write  (DA) */
	cvmx_write_csr (CVMX_GPIO_BIT_CFGX(10), cvmx_read_csr (CVMX_GPIO_BIT_CFGX(10))
					| GPIO_WRITE_EN);


	/* set GPIO10 output 0 */
	cvmx_write_csr (CVMX_GPIO_TX_CLR, GPIO_10_BIT);

	/* set GPIO 11 to write  (EN) */
	cvmx_write_csr (CVMX_GPIO_BIT_CFGX(11), cvmx_read_csr (CVMX_GPIO_BIT_CFGX(11))
					| GPIO_WRITE_EN);

	/* set GPIO11 output 0 */
	cvmx_write_csr (CVMX_GPIO_TX_CLR, GPIO_11_BIT);
}
示例#6
0
static int
octeon_gpio_attach(device_t dev)
{
    struct octeon_gpio_softc *sc = device_get_softc(dev);
    struct octeon_gpio_pin *pinp;
    cvmx_gpio_bit_cfgx_t gpio_cfgx;

    int i;

    KASSERT((device_get_unit(dev) == 0),
            ("octeon_gpio: Only one gpio module supported"));

    mtx_init(&sc->gpio_mtx, device_get_nameunit(dev), NULL, MTX_DEF);

    for ( i = 0; i < OCTEON_GPIO_IRQS; i++) {
        if ((sc->gpio_irq_res[i] = bus_alloc_resource(dev,
                                   SYS_RES_IRQ, &sc->gpio_irq_rid[i],
                                   OCTEON_IRQ_GPIO0 + i, OCTEON_IRQ_GPIO0 + i, 1,
                                   RF_SHAREABLE | RF_ACTIVE)) == NULL) {
            device_printf(dev, "unable to allocate IRQ resource\n");
            return (ENXIO);
        }

        sc->gpio_intr_cookies[i] = sc;
        if ((bus_setup_intr(dev, sc->gpio_irq_res[i], INTR_TYPE_MISC,
                            octeon_gpio_filter, octeon_gpio_intr,
                            &(sc->gpio_intr_cookies[i]), &sc->gpio_ih[i]))) {
            device_printf(dev,
                          "WARNING: unable to register interrupt handler\n");
            return (ENXIO);
        }
    }

    sc->dev = dev;
    /* Configure all pins as input */
    /* disable interrupts for all pins */
    pinp = octeon_gpio_pins;
    i = 0;
    while (pinp->name) {
        strncpy(sc->gpio_pins[i].gp_name, pinp->name, GPIOMAXNAME);
        sc->gpio_pins[i].gp_pin = pinp->pin;
        sc->gpio_pins[i].gp_caps = DEFAULT_CAPS;
        sc->gpio_pins[i].gp_flags = 0;
        octeon_gpio_pin_configure(sc, &sc->gpio_pins[i], pinp->flags);
        pinp++;
        i++;
    }

    sc->gpio_npins = i;

#if 0
    /*
     * Sample: how to enable edge-triggered interrupt
     * for GPIO pin
     */
    gpio_cfgx.u64 = cvmx_read_csr(CVMX_GPIO_BIT_CFGX(7));
    gpio_cfgx.s.int_en = 1;
    gpio_cfgx.s.int_type = OCTEON_GPIO_IRQ_EDGE;
    cvmx_write_csr(CVMX_GPIO_BIT_CFGX(7), gpio_cfgx.u64);
#endif

    if (bootverbose) {
        for (i = 0; i < 16; i++) {
            gpio_cfgx.u64 = cvmx_read_csr(CVMX_GPIO_BIT_CFGX(i));
            device_printf(dev, "[pin%d] output=%d, invinput=%d, intr=%d, intr_type=%s\n",
                          i, gpio_cfgx.s.tx_oe, gpio_cfgx.s.rx_xor,
                          gpio_cfgx.s.int_en, gpio_cfgx.s.int_type ? "rising edge" : "level");
        }
    }

    device_add_child(dev, "gpioc", device_get_unit(dev));
    device_add_child(dev, "gpiobus", device_get_unit(dev));
    return (bus_generic_attach(dev));
}