/** * ti_mmchs_activate - activates the driver * @dev: mmc device handle * * Maps in the register set and requests an IRQ handler for the MMC controller. * * LOCKING: * None required * * RETURNS: * 0 on sucess * ENOMEM if failed to map register set */ static int ti_mmchs_activate(device_t dev) { struct ti_mmchs_softc *sc = device_get_softc(dev); unsigned long addr; int rid; int err; /* Get the memory resource for the register mapping */ rid = 0; sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (sc->sc_mem_res == NULL) panic("%s: Cannot map registers", device_get_name(dev)); /* Allocate an IRQ resource for the MMC controller */ rid = 0; sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE | RF_SHAREABLE); if (sc->sc_irq_res == NULL) goto errout; /* Allocate DMA tags and maps */ err = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MAXPHYS, 1, MAXPHYS, BUS_DMA_ALLOCNOW, NULL, NULL, &sc->sc_dmatag); if (err != 0) goto errout; err = bus_dmamap_create(sc->sc_dmatag, 0, &sc->sc_dmamap); if (err != 0) goto errout; /* Initialise the DMA channels to be used by the controller */ err = ti_mmchs_init_dma_channels(sc); if (err != 0) goto errout; /* Set the register offset */ if (ti_chip() == CHIP_OMAP_3) sc->sc_reg_off = OMAP3_MMCHS_REG_OFFSET; else if (ti_chip() == CHIP_OMAP_4) sc->sc_reg_off = OMAP4_MMCHS_REG_OFFSET; else panic("Unknown OMAP device\n"); /* Get the physical address of the MMC data register, needed for DMA */ addr = vtophys(rman_get_start(sc->sc_mem_res)); sc->sc_data_reg_paddr = addr + sc->sc_reg_off + MMCHS_DATA; /* Set the initial power state to off */ sc->sc_cur_power_mode = power_off; return (0); errout: ti_mmchs_deactivate(dev); return (ENOMEM); }
/** * ti_mmchs_reset_controller - * @arg: caller supplied arg * @segs: array of segments (although in our case should only be one) * @nsegs: number of segments (in our case should be 1) * @error: * * * */ static void ti_mmchs_reset_controller(struct ti_mmchs_softc *sc, uint32_t bit) { unsigned long attempts; uint32_t sysctl; ti_mmchs_dbg(sc, "reseting controller - bit 0x%08x\n", bit); sysctl = ti_mmchs_read_4(sc, MMCHS_SYSCTL); ti_mmchs_write_4(sc, MMCHS_SYSCTL, sysctl | bit); /* * AM335x and OMAP4 >= ES2 have an updated reset logic. * Monitor a 0->1 transition first. */ if ((ti_chip() == CHIP_AM335X) || ((ti_chip() == CHIP_OMAP_4) && (ti_revision() > OMAP4430_REV_ES1_0))) { attempts = 10000; while (!(ti_mmchs_read_4(sc, MMCHS_SYSCTL) & bit) && (attempts-- > 0)) continue; } attempts = 10000; while ((ti_mmchs_read_4(sc, MMCHS_SYSCTL) & bit) && (attempts-- > 0)) continue; if (ti_mmchs_read_4(sc, MMCHS_SYSCTL) & bit) device_printf(sc->sc_dev, "Error - Timeout waiting on controller reset\n"); }
static int ti_pinmux_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (!ofw_bus_is_compatible(dev, "pinctrl-single")) return (ENXIO); if (ti_pinmux_sc) { printf("%s: multiple pinctrl modules in device tree data, ignoring\n", __func__); return (EEXIST); } switch (ti_chip()) { #ifdef SOC_OMAP4 case CHIP_OMAP_4: ti_pinmux_dev = &omap4_pinmux_dev; break; #endif #ifdef SOC_TI_AM335X case CHIP_AM335X: ti_pinmux_dev = &ti_am335x_pinmux_dev; break; #endif default: printf("Unknown CPU in pinmux\n"); return (ENXIO); } device_set_desc(dev, "TI Pinmux Module"); return (BUS_PROBE_DEFAULT); }
/** * ti_prcm_clk_dev - returns a pointer to the clock device with given id * @clk: the ID of the clock device to get * * Simply iterates through the clk_devmap global array and returns a pointer * to the clock device if found. * * LOCKING: * None * * RETURNS: * The pointer to the clock device on success, on failure NULL is returned. */ static struct ti_clock_dev * ti_prcm_clk_dev(clk_ident_t clk) { struct ti_clock_dev *clk_dev; /* Find the clock within the devmap - it's a bit inefficent having a for * loop for this, but this function should only called when a driver is * being activated so IMHO not a big issue. */ clk_dev = NULL; switch(ti_chip()) { #ifdef SOC_OMAP4 case CHIP_OMAP_4: clk_dev = &(ti_omap4_clk_devmap[0]); break; #endif #ifdef SOC_TI_AM335X case CHIP_AM335X: clk_dev = &(ti_am335x_clk_devmap[0]); break; #endif } if (clk_dev == NULL) panic("No clock devmap found"); while (clk_dev->id != INVALID_CLK_IDENT) { if (clk_dev->id == clk) { return (clk_dev); } clk_dev++; } /* Sanity check we managed to find the clock */ printf("ti_prcm: Failed to find clock device (%d)\n", clk); return (NULL); }
static uint32_t ti_gpio_rev(void) { switch(ti_chip()) { #ifdef SOC_OMAP4 case CHIP_OMAP_4: return (OMAP4_GPIO_REV); #endif #ifdef SOC_TI_AM335X case CHIP_AM335X: return (AM335X_GPIO_REV); #endif } return (0); }
static u_int ti_first_gpio_bank(void) { switch(ti_chip()) { #ifdef SOC_OMAP4 case CHIP_OMAP_4: return (OMAP4_FIRST_GPIO_BANK); #endif #ifdef SOC_TI_AM335X case CHIP_AM335X: return (AM335X_FIRST_GPIO_BANK); #endif } return (0); }
static u_int ti_max_gpio_intrs(void) { switch(ti_chip()) { #ifdef SOC_OMAP4 case CHIP_OMAP_4: return (OMAP4_MAX_GPIO_BANKS * OMAP4_INTR_PER_BANK); #endif #ifdef SOC_TI_AM335X case CHIP_AM335X: return (AM335X_MAX_GPIO_BANKS * AM335X_INTR_PER_BANK); #endif } return (0); }
static int omap4_gpio_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); if (ti_chip() != CHIP_OMAP_4) return (ENXIO); device_set_desc(dev, "TI OMAP4 General Purpose I/O (GPIO)"); return (0); }
static int ti_i2c_reset(struct ti_i2c_softc *sc, u_char speed) { int timeout; struct ti_i2c_clock_config *clkcfg; u_int busfreq; uint16_t fifo_trsh, reg, scll, sclh; switch (ti_chip()) { #ifdef SOC_OMAP4 case CHIP_OMAP_4: clkcfg = ti_omap4_i2c_clock_configs; break; #endif #ifdef SOC_TI_AM335X case CHIP_AM335X: clkcfg = ti_am335x_i2c_clock_configs; break; #endif default: panic("Unknown Ti SoC, unable to reset the i2c"); } /* * If we haven't attached the bus yet, just init at the default slow * speed. This lets us get the hardware initialized enough to attach * the bus which is where the real speed configuration is handled. After * the bus is attached, get the configured speed from it. Search the * configuration table for the best speed we can do that doesn't exceed * the requested speed. */ if (sc->sc_iicbus == NULL) busfreq = 100000; else busfreq = IICBUS_GET_FREQUENCY(sc->sc_iicbus, speed); for (;;) { if (clkcfg[1].frequency == 0 || clkcfg[1].frequency > busfreq) break; clkcfg++; } /* * 23.1.4.3 - HS I2C Software Reset * From OMAP4 TRM at page 4068. * * 1. Ensure that the module is disabled. */ sc->sc_con_reg = 0; ti_i2c_write_2(sc, I2C_REG_CON, sc->sc_con_reg); /* 2. Issue a softreset to the controller. */ bus_write_2(sc->sc_mem_res, I2C_REG_SYSC, I2C_REG_SYSC_SRST); /* * 3. Enable the module. * The I2Ci.I2C_SYSS[0] RDONE bit is asserted only after the module * is enabled by setting the I2Ci.I2C_CON[15] I2C_EN bit to 1. */ ti_i2c_write_2(sc, I2C_REG_CON, I2C_CON_I2C_EN); /* 4. Wait for the software reset to complete. */ timeout = 0; while ((ti_i2c_read_2(sc, I2C_REG_SYSS) & I2C_SYSS_RDONE) == 0) { if (timeout++ > 100) return (EBUSY); DELAY(100); } /* * Disable the I2C controller once again, now that the reset has * finished. */ ti_i2c_write_2(sc, I2C_REG_CON, sc->sc_con_reg); /* * The following sequence is taken from the OMAP4 TRM at page 4077. * * 1. Enable the functional and interface clocks (see Section * 23.1.5.1.1.1.1). Done at ti_i2c_activate(). * * 2. Program the prescaler to obtain an approximately 12MHz internal * sampling clock (I2Ci_INTERNAL_CLK) by programming the * corresponding value in the I2Ci.I2C_PSC[3:0] PSC field. * This value depends on the frequency of the functional clock * (I2Ci_FCLK). Because this frequency is 96MHz, the * I2Ci.I2C_PSC[7:0] PSC field value is 0x7. */ ti_i2c_write_2(sc, I2C_REG_PSC, clkcfg->psc); /* * 3. Program the I2Ci.I2C_SCLL[7:0] SCLL and I2Ci.I2C_SCLH[7:0] SCLH * bit fields to obtain a bit rate of 100 Kbps, 400 Kbps or 1Mbps. * These values depend on the internal sampling clock frequency * (see Table 23-8). */ scll = clkcfg->scll & I2C_SCLL_MASK; sclh = clkcfg->sclh & I2C_SCLH_MASK; /* * 4. (Optional) Program the I2Ci.I2C_SCLL[15:8] HSSCLL and * I2Ci.I2C_SCLH[15:8] HSSCLH fields to obtain a bit rate of * 400K bps or 3.4M bps (for the second phase of HS mode). These * values depend on the internal sampling clock frequency (see * Table 23-8). * * 5. (Optional) If a bit rate of 3.4M bps is used and the bus line * capacitance exceeds 45 pF, (see Section 18.4.8, PAD Functional * Multiplexing and Configuration). */ switch (ti_chip()) { #ifdef SOC_OMAP4 case CHIP_OMAP_4: if ((clkcfg->hsscll + clkcfg->hssclh) > 0) { scll |= clkcfg->hsscll << I2C_HSSCLL_SHIFT; sclh |= clkcfg->hssclh << I2C_HSSCLH_SHIFT; sc->sc_con_reg |= I2C_CON_OPMODE_HS; } break; #endif } /* Write the selected bit rate. */ ti_i2c_write_2(sc, I2C_REG_SCLL, scll); ti_i2c_write_2(sc, I2C_REG_SCLH, sclh); /* * 6. Configure the Own Address of the I2C controller by storing it in * the I2Ci.I2C_OA0 register. Up to four Own Addresses can be * programmed in the I2Ci.I2C_OAi registers (where i = 0, 1, 2, 3) * for each I2C controller. * * Note: For a 10-bit address, set the corresponding expand Own Address * bit in the I2Ci.I2C_CON register. * * Driver currently always in single master mode so ignore this step. */ /* * 7. Set the TX threshold (in transmitter mode) and the RX threshold * (in receiver mode) by setting the I2Ci.I2C_BUF[5:0]XTRSH field to * (TX threshold - 1) and the I2Ci.I2C_BUF[13:8]RTRSH field to (RX * threshold - 1), where the TX and RX thresholds are greater than * or equal to 1. * * The threshold is set to 5 for now. */ fifo_trsh = (sc->sc_fifo_trsh - 1) & I2C_BUF_TRSH_MASK; reg = fifo_trsh | (fifo_trsh << I2C_BUF_RXTRSH_SHIFT); ti_i2c_write_2(sc, I2C_REG_BUF, reg); /* * 8. Take the I2C controller out of reset by setting the * I2Ci.I2C_CON[15] I2C_EN bit to 1. * * 23.1.5.1.1.1.2 - Initialize the I2C Controller * * To initialize the I2C controller, perform the following steps: * * 1. Configure the I2Ci.I2C_CON register: * . For master or slave mode, set the I2Ci.I2C_CON[10] MST bit * (0: slave, 1: master). * . For transmitter or receiver mode, set the I2Ci.I2C_CON[9] TRX * bit (0: receiver, 1: transmitter). */ /* Enable the I2C controller in master mode. */ sc->sc_con_reg |= I2C_CON_I2C_EN | I2C_CON_MST; ti_i2c_write_2(sc, I2C_REG_CON, sc->sc_con_reg); /* * 2. If using an interrupt to transmit/receive data, set the * corresponding bit in the I2Ci.I2C_IE register (the I2Ci.I2C_IE[4] * XRDY_IE bit for the transmit interrupt, the I2Ci.I2C_IE[3] RRDY * bit for the receive interrupt). */ /* Set the interrupts we want to be notified. */ reg = I2C_IE_XDR | /* Transmit draining interrupt. */ I2C_IE_XRDY | /* Transmit Data Ready interrupt. */ I2C_IE_RDR | /* Receive draining interrupt. */ I2C_IE_RRDY | /* Receive Data Ready interrupt. */ I2C_IE_ARDY | /* Register Access Ready interrupt. */ I2C_IE_NACK | /* No Acknowledgment interrupt. */ I2C_IE_AL; /* Arbitration lost interrupt. */ /* Enable the interrupts. */ ti_i2c_write_2(sc, I2C_REG_IRQENABLE_SET, reg); /* * 3. If using DMA to receive/transmit data, set to 1 the corresponding * bit in the I2Ci.I2C_BUF register (the I2Ci.I2C_BUF[15] RDMA_EN * bit for the receive DMA channel, the I2Ci.I2C_BUF[7] XDMA_EN bit * for the transmit DMA channel). * * Not using DMA for now, so ignore this. */ return (0); }