static struct resource * mvs_alloc_resource(device_t dev, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { struct mvs_controller *ctlr = device_get_softc(dev); int unit = ((struct mvs_channel *)device_get_softc(child))->unit; struct resource *res = NULL; int offset = PORT_BASE(unit & 0x03); long st; switch (type) { case SYS_RES_MEMORY: st = rman_get_start(ctlr->r_mem); res = rman_reserve_resource(&ctlr->sc_iomem, st + offset, st + offset + PORT_SIZE - 1, PORT_SIZE, RF_ACTIVE, child); if (res) { bus_space_handle_t bsh; bus_space_tag_t bst; bsh = rman_get_bushandle(ctlr->r_mem); bst = rman_get_bustag(ctlr->r_mem); bus_space_subregion(bst, bsh, offset, PORT_SIZE, &bsh); rman_set_bushandle(res, bsh); rman_set_bustag(res, bst); } break; case SYS_RES_IRQ: if (*rid == ATA_IRQ_RID) res = ctlr->irq.r_irq; break; } return (res); }
__LINK_C error_t hw_gpio_configure_pin(pin_id_t pin_id, bool int_allowed, uint8_t mode, unsigned int out) { if((int_allowed) && (gpio_callback[GPIO_PIN(pin_id)] != 0x00)) return EBUSY; GPio_edge *TGpio = (GPio_edge*) PORT_BASE(pin_id); TGpio->dir &= (0x0ffffffff ^ (1 << GPIO_PIN(pin_id))); TGpio->dir |= (mode << GPIO_PIN(pin_id)); // mode => 0:input 1:output TGpio->out &= (0x0ffffffff ^ (1 << GPIO_PIN(pin_id))); TGpio->out |= (out << GPIO_PIN(pin_id)); return SUCCESS; }
__LINK_C error_t hw_gpio_configure_interrupt(pin_id_t pin_id, gpio_inthandler_t callback, uint8_t event_mask) { assert(PORT_BASE(pin_id.port) == PORTB); // TODO multiple ports not supported yet assert(callback != NULL); portb_interrupt_config[pin_id.pin].callback = callback; port_interrupt_config_t interrupt_config; if(event_mask == 0) interrupt_config = kPortIntDisabled; else if(event_mask & GPIO_FALLING_EDGE && event_mask & GPIO_RISING_EDGE) interrupt_config = kPortIntEitherEdge; else if(event_mask & GPIO_FALLING_EDGE) interrupt_config = kPortIntFallingEdge; else if(event_mask & GPIO_RISING_EDGE) interrupt_config = kPortIntRisingEdge; portb_interrupt_config[pin_id.pin].interrupt_config = interrupt_config; portb_interrupts &= 1 << pin_id.port; PORT_HAL_SetPinIntMode(PORT_BASE(pin_id.port), pin_id.pin, kPortIntDisabled); return SUCCESS; }
__LINK_C error_t hw_gpio_set_edge_interrupt(pin_id_t pin_id, uint8_t edge) { GPio_edge *TGpio = (GPio_edge*) PORT_BASE(pin_id); start_atomic(); TGpio->mask &= (0x0ffffffff ^ (1<<GPIO_PIN(pin_id))); TGpio->edge = 0x1; // Clear all edges TGpio->old_in = TGpio->in; TGpio->level_sel |= (1<<GPIO_PIN(pin_id)); // Select pin to interrupt if (edge == GPIO_RISING_EDGE) TGpio->rs_edge_sel = 0x1; else TGpio->fl_edge_sel = 0x1; //DPRINT ("id %04x edge %d level_sel = %02x in %02x old %02x", GPIO_PIN(pin_id), edge, gpio_edge->level_sel, gpio_edge->in, gpio_edge->old_in); end_atomic(); return SUCCESS; }
__LINK_C error_t hw_gpio_disable_interrupt(pin_id_t pin_id) { PORT_HAL_SetPinIntMode(PORT_BASE(pin_id.port), pin_id.pin, kPortIntDisabled); return SUCCESS; }
__LINK_C error_t hw_gpio_enable_interrupt(pin_id_t pin_id) { assert(portb_interrupt_config[pin_id.pin].callback != NULL); PORT_HAL_SetPinIntMode(PORT_BASE(pin_id.port), pin_id.pin, portb_interrupt_config[pin_id.pin].interrupt_config); return SUCCESS; }
static int mvs_attach(device_t dev) { struct mvs_controller *ctlr = device_get_softc(dev); device_t child; int error, unit, i; uint32_t devid, revid; soc_id(&devid, &revid); ctlr->dev = dev; i = 0; while (mvs_ids[i].id != 0 && (mvs_ids[i].id != devid || mvs_ids[i].rev > revid)) i++; ctlr->channels = mvs_ids[i].ports; ctlr->quirks = mvs_ids[i].quirks; resource_int_value(device_get_name(dev), device_get_unit(dev), "ccc", &ctlr->ccc); ctlr->cccc = 8; resource_int_value(device_get_name(dev), device_get_unit(dev), "cccc", &ctlr->cccc); if (ctlr->ccc == 0 || ctlr->cccc == 0) { ctlr->ccc = 0; ctlr->cccc = 0; } if (ctlr->ccc > 100000) ctlr->ccc = 100000; device_printf(dev, "Gen-%s, %d %sGbps ports, Port Multiplier %s%s\n", ((ctlr->quirks & MVS_Q_GENI) ? "I" : ((ctlr->quirks & MVS_Q_GENII) ? "II" : "IIe")), ctlr->channels, ((ctlr->quirks & MVS_Q_GENI) ? "1.5" : "3"), ((ctlr->quirks & MVS_Q_GENI) ? "not supported" : "supported"), ((ctlr->quirks & MVS_Q_GENIIE) ? " with FBS" : "")); mtx_init(&ctlr->mtx, "MVS controller lock", NULL, MTX_DEF); /* We should have a memory BAR(0). */ ctlr->r_rid = 0; if (!(ctlr->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &ctlr->r_rid, RF_ACTIVE))) return ENXIO; if (ATA_INL(ctlr->r_mem, PORT_BASE(0) + SATA_PHYCFG_OFS) != 0) ctlr->quirks |= MVS_Q_SOC65; /* Setup our own memory management for channels. */ ctlr->sc_iomem.rm_start = rman_get_start(ctlr->r_mem); ctlr->sc_iomem.rm_end = rman_get_end(ctlr->r_mem); ctlr->sc_iomem.rm_type = RMAN_ARRAY; ctlr->sc_iomem.rm_descr = "I/O memory addresses"; if ((error = rman_init(&ctlr->sc_iomem)) != 0) { bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem); return (error); } if ((error = rman_manage_region(&ctlr->sc_iomem, rman_get_start(ctlr->r_mem), rman_get_end(ctlr->r_mem))) != 0) { bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem); rman_fini(&ctlr->sc_iomem); return (error); } mvs_ctlr_setup(dev); /* Setup interrupts. */ if (mvs_setup_interrupt(dev)) { bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem); rman_fini(&ctlr->sc_iomem); return ENXIO; } /* Attach all channels on this controller */ for (unit = 0; unit < ctlr->channels; unit++) { child = device_add_child(dev, "mvsch", -1); if (child == NULL) device_printf(dev, "failed to add channel device\n"); else device_set_ivars(child, (void *)(intptr_t)unit); } bus_generic_attach(dev); return 0; }
__LINK_C bool hw_gpio_get_in(pin_id_t pin_id) { GPio_edge *TGpio = (GPio_edge*) PORT_BASE(pin_id); return ((TGpio->in >> GPIO_PIN(pin_id))&1); }
__LINK_C error_t hw_gpio_toggle(pin_id_t pin_id) { GPio_edge *TGpio = (GPio_edge*) PORT_BASE(pin_id); TGpio->out ^= (1<<GPIO_PIN(pin_id)); return SUCCESS; }
__LINK_C error_t hw_gpio_clr(pin_id_t pin_id) { GPio_edge *TGpio = (GPio_edge*) PORT_BASE(pin_id); TGpio->out &= (0x0ffffffff ^ (1 << GPIO_PIN(pin_id))); return SUCCESS; }
#if defined(MV_CPU_LE) printk(" LE"); #else printk(" BE"); #endif printk("\n\n"); printk(" Detected Tclk %d and SysClk %d \n",mvTclk, mvSysclk); } /***************************************************************************** * UART ****************************************************************************/ static struct resource mv_uart_resources[] = { { .start = PORT_BASE(0), .end = PORT_BASE(0) + 0xff, .flags = IORESOURCE_MEM, }, { .start = IRQ_UART(0), .end = IRQ_UART(0), .flags = IORESOURCE_IRQ, }, { .start = PORT_BASE(1), .end = PORT_BASE(1) + 0xff, .flags = IORESOURCE_MEM, }, { .start = IRQ_UART(1),