/* * Interrupt service routine. This gets called whenever an I2C interrupt * occurs. */ irqreturn_t i2c_dw_isr(int this_irq, void *dev_id) { struct dw_i2c_dev *dev = dev_id; u32 stat, enabled; enabled = dw_readl(dev, DW_IC_ENABLE); stat = dw_readl(dev, DW_IC_RAW_INTR_STAT); dev_dbg(dev->dev, "%s: %s enabled= 0x%x stat=0x%x\n", __func__, dev->adapter.name, enabled, stat); if (!enabled || !(stat & ~DW_IC_INTR_ACTIVITY)) return IRQ_NONE; stat = i2c_dw_read_clear_intrbits(dev); if (stat & DW_IC_INTR_TX_ABRT) { dev->cmd_err |= DW_IC_ERR_TX_ABRT; dev->status = STATUS_IDLE; /* * Anytime TX_ABRT is set, the contents of the tx/rx * buffers are flushed. Make sure to skip them. */ dw_writel(dev, 0, DW_IC_INTR_MASK); goto tx_aborted; } if (stat & DW_IC_INTR_RX_OVER) { dev_err(dev->dev, "i2c fifo overflow rx tl=%d,rxflr=%d,msg len=%d,txflr=%d\n", readl(dev->base + DW_IC_RX_TL),readl(dev->base+DW_IC_RXFLR),dev->msgs[dev->msg_write_idx].len, readl(dev->base + DW_IC_TXFLR)); dev->msg_err = -EINVAL; goto tx_aborted; } if (stat & DW_IC_INTR_RX_FULL) i2c_dw_read(dev); if (stat & DW_IC_INTR_TX_EMPTY) i2c_dw_xfer_msg(dev); if (stat & DW_IC_INTR_STOP_DET) { if (dev->status & STATUS_READ_IN_PROGRESS) i2c_dw_read(dev); if (dev->status !=0) { dev_err(dev->dev, "i2c transfer was stopped unexpected\n"); dev->msg_err = -EINVAL; } } /* * No need to modify or disable the interrupt mask here. * i2c_dw_xfer_msg() will take care of it according to * the current transmit status. */ tx_aborted: if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err) complete(&dev->cmd_complete); return IRQ_HANDLED; }
static void i2c_dw_read(struct dw_i2c_dev *dev) { struct i2c_msg *msgs = dev->msgs; int rx_valid; for (; dev->msg_read_idx < dev->msgs_num; dev->msg_read_idx++) { u32 len; u8 *buf; if (!(msgs[dev->msg_read_idx].flags & I2C_M_RD)) continue; if (!(dev->status & STATUS_READ_IN_PROGRESS)) { len = msgs[dev->msg_read_idx].len; buf = msgs[dev->msg_read_idx].buf; } else { len = dev->rx_buf_len; buf = dev->rx_buf; } rx_valid = dw_readl(dev, DW_IC_RXFLR); for (; len > 0 && rx_valid > 0; len--, rx_valid--) *buf++ = dw_readl(dev, DW_IC_DATA_CMD); if (len > 0) { dev->status |= STATUS_READ_IN_PROGRESS; dev->rx_buf_len = len; dev->rx_buf = buf; return; } else dev->status &= ~STATUS_READ_IN_PROGRESS; } }
static irqreturn_t interrupt_transfer(struct dw_spi *dws) { u16 irq_status = dw_readl(dws, DW_SPI_ISR); /* Error handling */ if (irq_status & (SPI_INT_TXOI | SPI_INT_RXOI | SPI_INT_RXUI)) { dw_readl(dws, DW_SPI_ICR); int_error_stop(dws, "interrupt_transfer: fifo overrun/underrun"); return IRQ_HANDLED; } dw_reader(dws); if (dws->rx_end == dws->rx) { spi_mask_intr(dws, SPI_INT_TXEI); spi_finalize_current_transfer(dws->master); return IRQ_HANDLED; } if (irq_status & SPI_INT_TXEI) { spi_mask_intr(dws, SPI_INT_TXEI); dw_writer(dws); /* Enable TX irq always, it will be disabled when RX finished */ spi_umask_intr(dws, SPI_INT_TXEI); } return IRQ_HANDLED; }
void mrfld_early_console_init(void) { u32 ctrlr0 = 0; set_fixmap_nocache(FIX_EARLYCON_MEM_BASE, MRFLD_REGBASE_SSP5); pssp = (void *)(__fix_to_virt(FIX_EARLYCON_MEM_BASE) + (MRFLD_REGBASE_SSP5 & (PAGE_SIZE - 1))); if (intel_mid_identify_sim() == INTEL_MID_CPU_SIMULATION_NONE) ssp_timing_wr = 1; /* mask interrupts, clear enable and set DSS config */ /* SSPSCLK on active transfers only */ if (intel_mid_identify_sim() != INTEL_MID_CPU_SIMULATION_SLE) { if (ssp_timing_wr) { dw_writel(pssp, ctrl0, 0xc12c0f); dw_writel(pssp, ctrl1, 0x0); } else { dw_writel(pssp, ctrl0, 0xc0000f); dw_writel(pssp, ctrl1, 0x10000000); } } dw_readl(pssp, sr); /* enable port */ if (intel_mid_identify_sim() != INTEL_MID_CPU_SIMULATION_SLE) { ctrlr0 = dw_readl(pssp, ctrl0); ctrlr0 |= 0x80; dw_writel(pssp, ctrl0, ctrlr0); } }
static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id) { struct dw_i2c_dev *dev = dev_id; u32 stat, enabled; enabled = dw_readl(dev, DW_IC_ENABLE); stat = dw_readl(dev, DW_IC_RAW_INTR_STAT); dev_dbg(dev->dev, "enabled=%#x stat=%#x\n", enabled, stat); if (!enabled || !(stat & ~DW_IC_INTR_ACTIVITY)) return IRQ_NONE; i2c_dw_irq_handler_master(dev); return IRQ_HANDLED; }
/* slave select should be called in the read/write function */ static int early_mrfld_putc(char c) { unsigned int timeout; u32 sr; timeout = MRFLD_SSP_TIMEOUT; /* early putc need make sure the TX FIFO is not full*/ while (timeout--) { sr = dw_readl(pssp, sr); if (ssp_timing_wr) { if (sr & 0xF00) cpu_relax(); else break; } else { if (!(sr & SSP_SR_TF_NOT_FULL)) cpu_relax(); else break; } } if (timeout == 0xffffffff) { pr_info("SSP: waiting timeout\n"); return -1; } max3110_ssp_write_data(c); return 0; }
static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) { struct i2c_msg *msgs = dev->msgs; u32 ic_con; /* Disable the adapter */ dw_writel(dev, 0, DW_IC_ENABLE); /* set the slave (target) address */ dw_writel(dev, msgs[dev->msg_write_idx].addr, DW_IC_TAR); /* if the slave address is ten bit address, enable 10BITADDR */ ic_con = dw_readl(dev, DW_IC_CON); if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) ic_con |= DW_IC_CON_10BITADDR_MASTER; else ic_con &= ~DW_IC_CON_10BITADDR_MASTER; dw_writel(dev, ic_con, DW_IC_CON); /* Enable the adapter */ dw_writel(dev, 1, DW_IC_ENABLE); /* Enable interrupts */ dw_writel(dev, DW_IC_INTR_DEFAULT_MASK, DW_IC_INTR_MASK); }
/* Restart the controller, disable all interrupts, clean rx fifo */ static void spi_hw_init(struct device *dev, struct dw_spi *dws) { spi_reset_chip(dws); /* * Try to detect the FIFO depth if not set by interface driver, * the depth could be from 2 to 256 from HW spec */ if (!dws->fifo_len) { u32 fifo; for (fifo = 1; fifo < 256; fifo++) { dw_writel(dws, DW_SPI_TXFLTR, fifo); if (fifo != dw_readl(dws, DW_SPI_TXFLTR)) break; } dw_writel(dws, DW_SPI_TXFLTR, 0); dws->fifo_len = (fifo == 1) ? 0 : fifo; dev_dbg(dev, "Detected FIFO size: %u bytes\n", dws->fifo_len); } /* enable HW fixup for explicit CS deselect for Amazon's alpine chip */ if (dws->cs_override) dw_writel(dws, DW_SPI_CS_OVERRIDE, 0xF); }
static void i2c_dw_read(struct dw_i2c_dev *dev) { struct i2c_msg *msgs = dev->msgs; int rx_valid; for (; dev->msg_read_idx < dev->msgs_num; dev->msg_read_idx++) { u32 len; u8 *buf; if (!(msgs[dev->msg_read_idx].flags & I2C_M_RD)) continue; if (!(dev->status & STATUS_READ_IN_PROGRESS)) { len = msgs[dev->msg_read_idx].len; buf = msgs[dev->msg_read_idx].buf; } else { len = dev->rx_buf_len; buf = dev->rx_buf; } rx_valid = dw_readl(dev, DW_IC_RXFLR); for (; len > 0 && rx_valid > 0; len--, rx_valid--) { u32 flags = msgs[dev->msg_read_idx].flags; *buf = dw_readl(dev, DW_IC_DATA_CMD); /* Ensure length byte is a valid value */ if (flags & I2C_M_RECV_LEN && *buf <= I2C_SMBUS_BLOCK_MAX && *buf > 0) { len = i2c_dw_recv_len(dev, *buf); } buf++; dev->rx_outstanding--; } if (len > 0) { dev->status |= STATUS_READ_IN_PROGRESS; dev->rx_buf_len = len; dev->rx_buf = buf; return; } else dev->status &= ~STATUS_READ_IN_PROGRESS; } }
void mrst_early_console_init(void) { u32 ctrlr0 = 0; u32 spi0_cdiv; u32 freq; /* Freqency info only need be searched once */ /* Base clk is 100 MHz, the actual clk = 100M / (clk_divider + 1) */ pclk_spi0 = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE, MRST_CLK_SPI0_REG); spi0_cdiv = ((*pclk_spi0) & 0xe00) >> 9; freq = 100000000 / (spi0_cdiv + 1); if (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_PENWELL) mrst_spi_paddr = MRST_REGBASE_SPI1; else if (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_CLOVERVIEW) mrst_spi_paddr = CLV_REGBASE_SPI1; pspi = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE, mrst_spi_paddr); /* Disable SPI controller */ dw_writel(pspi, ssienr, 0); /* Set control param, 8 bits, transmit only mode */ ctrlr0 = dw_readl(pspi, ctrl0); ctrlr0 &= 0xfcc0; ctrlr0 |= 0xf | (SPI_FRF_SPI << SPI_FRF_OFFSET) | (SPI_TMOD_TO << SPI_TMOD_OFFSET); dw_writel(pspi, ctrl0, ctrlr0); /* * Change the spi0 clk to comply with 115200 bps, use 100000 to * calculate the clk dividor to make the clock a little slower * than real baud rate. */ dw_writel(pspi, baudr, freq/100000); /* Disable all INT for early phase */ dw_writel(pspi, imr, 0x0); /* Set the cs to spi-uart */ dw_writel(pspi, ser, 0x2); /* Enable the HW, the last step for HW init */ dw_writel(pspi, ssienr, 0x1); /* Set the default configuration */ max3110_spi_write_config(); /* Register the kmsg dumper */ if (!dumper_registered) { dw_dumper.dump = dw_kmsg_dump; kmsg_dump_register(&dw_dumper); dumper_registered = 1; } }
void i2c_dw_disable(struct dw_i2c_dev *dev) { /* Disable controller */ dw_writel(dev, 0, DW_IC_ENABLE); /* Disable all interupts */ dw_writel(dev, 0, DW_IC_INTR_MASK); dw_readl(dev, DW_IC_CLR_INTR); }
static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) { struct i2c_msg *msgs = dev->msgs; u32 ic_con, ic_tar = 0; /* Disable the adapter */ __i2c_dw_disable(dev); /* If the slave address is ten bit address, enable 10BITADDR */ ic_con = dw_readl(dev, DW_IC_CON); if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) { ic_con |= DW_IC_CON_10BITADDR_MASTER; /* * If I2C_DYNAMIC_TAR_UPDATE is set, the 10-bit addressing * mode has to be enabled via bit 12 of IC_TAR register. * We set it always as I2C_DYNAMIC_TAR_UPDATE can't be * detected from registers. */ ic_tar = DW_IC_TAR_10BITADDR_MASTER; } else { ic_con &= ~DW_IC_CON_10BITADDR_MASTER; } dw_writel(dev, ic_con, DW_IC_CON); /* * Set the slave (target) address and enable 10-bit addressing mode * if applicable. */ dw_writel(dev, msgs[dev->msg_write_idx].addr | ic_tar, DW_IC_TAR); /* Enforce disabled interrupts (due to HW issues) */ i2c_dw_disable_int(dev); /* Enable the adapter */ __i2c_dw_enable(dev); /* Dummy read to avoid the register getting stuck on Bay Trail */ dw_readl(dev, DW_IC_ENABLE_STATUS); /* Clear and enable interrupts */ dw_readl(dev, DW_IC_CLR_INTR); dw_writel(dev, DW_IC_INTR_MASTER_MASK, DW_IC_INTR_MASK); }
/* * Interrupt service routine. This gets called whenever an I2C interrupt * occurs. */ irqreturn_t i2c_dw_isr(int this_irq, void *dev_id) { struct dw_i2c_dev *dev = dev_id; u32 stat, enabled; enabled = dw_readl(dev, DW_IC_ENABLE); stat = dw_readl(dev, DW_IC_RAW_INTR_STAT); dev_dbg(dev->dev, "%s: %s enabled= 0x%x stat=0x%x\n", __func__, dev->adapter.name, enabled, stat); if (!enabled || !(stat & ~DW_IC_INTR_ACTIVITY)) return IRQ_NONE; stat = i2c_dw_read_clear_intrbits(dev); if (stat & DW_IC_INTR_TX_ABRT) { dev->cmd_err |= DW_IC_ERR_TX_ABRT; dev->status = STATUS_IDLE; /* * Anytime TX_ABRT is set, the contents of the tx/rx * buffers are flushed. Make sure to skip them. */ dw_writel(dev, 0, DW_IC_INTR_MASK); goto tx_aborted; } if (stat & DW_IC_INTR_RX_FULL) i2c_dw_read(dev); if (stat & DW_IC_INTR_TX_EMPTY) i2c_dw_xfer_msg(dev); /* * No need to modify or disable the interrupt mask here. * i2c_dw_xfer_msg() will take care of it according to * the current transmit status. */ tx_aborted: if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err) complete(&dev->cmd_complete); return IRQ_HANDLED; }
/* similar to max3110_spi_write_config, but via SSP controller */ static void max3110_ssp_write_config(void) { u16 config; config = 0xc001; dw_writel(pssp, dr, config); dw_readl(pssp, dr); udelay(10); return; }
/* similar to max3110_spi_write_data, but via SSP controller */ static void max3110_ssp_write_data(char c) { u16 data; data = 0x8000 | c; dw_writel(pssp, dr, data); dw_readl(pssp, dr); udelay(10); return; }
/* * Waiting for bus not busy */ static int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev) { int timeout = TIMEOUT; while (dw_readl(dev, DW_IC_STATUS) & DW_IC_STATUS_ACTIVITY) { if (timeout <= 0) { dev_warn(dev->dev, "timeout waiting for bus ready\n"); return -ETIMEDOUT; } timeout--; mdelay(1); } return 0; }
static irqreturn_t dw_spi_irq(int irq, void *dev_id) { struct spi_controller *master = dev_id; struct dw_spi *dws = spi_controller_get_devdata(master); u16 irq_status = dw_readl(dws, DW_SPI_ISR) & 0x3f; if (!irq_status) return IRQ_NONE; if (!master->cur_msg) { spi_mask_intr(dws, SPI_INT_TXEI); return IRQ_HANDLED; } return dws->transfer_handler(dws); }
/* Return the max entries we can fill into tx fifo */ static inline u32 tx_max(struct dw_spi *dws) { u32 tx_left, tx_room, rxtx_gap; tx_left = (dws->tx_end - dws->tx) / dws->n_bytes; tx_room = dws->fifo_len - dw_readl(dws, DW_SPI_TXFLR); /* * Another concern is about the tx/rx mismatch, we * though to use (dws->fifo_len - rxflr - txflr) as * one maximum value for tx, but it doesn't cover the * data which is out of tx/rx fifo and inside the * shift registers. So a control from sw point of * view is taken. */ rxtx_gap = ((dws->rx_end - dws->rx) - (dws->tx_end - dws->tx)) / dws->n_bytes; return min3(tx_left, tx_room, (u32) (dws->fifo_len - rxtx_gap)); }
/* VLV2 PCI config space memio access to the controller is * enabled by * 1. Reset 0x804 and 0x808 offset from base address. * 2. Set 0x804 offset from base address to 0x3. */ static void vlv2_reset(struct dw_i2c_dev *dev) { int i; for (i = 0; i < 10; i++) { dw_writel(dev, 0, 0x804); dw_writel(dev, 0, 0x808); usleep_range(10, 100); dw_writel(dev, 3, 0x804); usleep_range(10, 100); if (dw_readl(dev, DW_IC_COMP_TYPE) != DW_IC_COMP_TYPE_VALUE) continue; return; } dev_warn(dev->dev, "vlv2 I2C reset failed\n"); }
/* Slave select should be called in the read/write function */ static void early_mrst_spi_putc(char c) { unsigned int timeout; u32 sr; timeout = MRST_SPI_TIMEOUT; /* Early putc needs to make sure the TX FIFO is not full */ while (--timeout) { sr = dw_readl(pspi, sr); if (!(sr & SR_TF_NOT_FULL)) cpu_relax(); else break; } if (!timeout) pr_warn("MRST earlycon: timed out\n"); else max3110_spi_write_data(c); }
/* * Interrupt service routine. This gets called whenever an I2C master interrupt * occurs. */ static int i2c_dw_irq_handler_master(struct dw_i2c_dev *dev) { u32 stat; stat = i2c_dw_read_clear_intrbits(dev); if (stat & DW_IC_INTR_TX_ABRT) { dev->cmd_err |= DW_IC_ERR_TX_ABRT; dev->status = STATUS_IDLE; /* * Anytime TX_ABRT is set, the contents of the tx/rx * buffers are flushed. Make sure to skip them. */ dw_writel(dev, 0, DW_IC_INTR_MASK); goto tx_aborted; } if (stat & DW_IC_INTR_RX_FULL) i2c_dw_read(dev); if (stat & DW_IC_INTR_TX_EMPTY) i2c_dw_xfer_msg(dev); /* * No need to modify or disable the interrupt mask here. * i2c_dw_xfer_msg() will take care of it according to * the current transmit status. */ tx_aborted: if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err) complete(&dev->cmd_complete); else if (unlikely(dev->flags & ACCESS_INTR_MASK)) { /* Workaround to trigger pending interrupt */ stat = dw_readl(dev, DW_IC_INTR_MASK); i2c_dw_disable_int(dev); dw_writel(dev, stat, DW_IC_INTR_MASK); } return 0; }
static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) { struct i2c_msg *msgs = dev->msgs; u32 ic_con; int i; /* Disable the adapter */ dw_writel(dev, 0, DW_IC_ENABLE); /* set the slave (target) address */ dw_writel(dev, msgs[dev->msg_write_idx].addr, DW_IC_TAR); /* if the slave address is ten bit address, enable 10BITADDR */ ic_con = dw_readl(dev, DW_IC_CON); if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) ic_con |= DW_IC_CON_10BITADDR_MASTER; else ic_con &= ~DW_IC_CON_10BITADDR_MASTER; dw_writel(dev, ic_con, DW_IC_CON); /* Set receive FIFO threshold level */ for (i = 0; i < dev->msgs_num; i++) { if (msgs[i].flags & I2C_M_RD) { if (msgs[i].len > dev->rx_fifo_depth) dw_writel(dev, get_max_divisor(msgs[i].len, dev->rx_fifo_depth - 2) - 1, DW_IC_RX_TL); else dw_writel(dev, msgs[i].len - 1, DW_IC_RX_TL); } } /* Enable the adapter */ dw_writel(dev, 1, DW_IC_ENABLE); /* Enable interrupts */ dw_writel(dev, DW_IC_INTR_DEFAULT_MASK, DW_IC_INTR_MASK); }
static ssize_t spi_show_regs(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct dw_spi *dws; char *buf; u32 len = 0; ssize_t ret; dws = file->private_data; buf = kzalloc(SPI_REGS_BUFSIZE, GFP_KERNEL); if (!buf) return 0; len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, "MRST SPI0 registers:\n"); len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, "=================================\n"); len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, "CTRL0: \t\t0x%08x\n", dw_readl(dws, DW_SPI_CTRL0)); len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, "CTRL1: \t\t0x%08x\n", dw_readl(dws, DW_SPI_CTRL1)); len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, "SSIENR: \t0x%08x\n", dw_readl(dws, DW_SPI_SSIENR)); len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, "SER: \t\t0x%08x\n", dw_readl(dws, DW_SPI_SER)); len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, "BAUDR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_BAUDR)); len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, "TXFTLR: \t0x%08x\n", dw_readl(dws, DW_SPI_TXFLTR)); len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, "RXFTLR: \t0x%08x\n", dw_readl(dws, DW_SPI_RXFLTR)); len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, "TXFLR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_TXFLR)); len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, "RXFLR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_RXFLR)); len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, "SR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_SR)); len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, "IMR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_IMR)); len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, "ISR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_ISR)); len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, "DMACR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_DMACR)); len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, "DMATDLR: \t0x%08x\n", dw_readl(dws, DW_SPI_DMATDLR)); len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, "DMARDLR: \t0x%08x\n", dw_readl(dws, DW_SPI_DMARDLR)); len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, "=================================\n"); ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); kfree(buf); return ret; }
void i2c_dw_clear_int(struct dw_i2c_dev *dev) { dw_readl(dev, DW_IC_CLR_INTR); }
u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev) { return dw_readl(dev, DW_IC_COMP_PARAM_1); }
/* Return the max entries we should read out of rx fifo */ static inline u32 rx_max(struct dw_spi *dws) { u32 rx_left = (dws->rx_end - dws->rx) / dws->n_bytes; return min_t(u32, rx_left, dw_readl(dws, DW_SPI_RXFLR)); }
static void i2c_dw_dump(struct dw_i2c_dev *dev) { u32 value; dev_err(dev->dev, "===== REGISTER DUMP (i2c) =====\n"); value = dw_readl(dev, DW_IC_CON); dev_err(dev->dev, "DW_IC_CON: 0x%x\n", value); value = dw_readl(dev, DW_IC_TAR); dev_err(dev->dev, "DW_IC_TAR: 0x%x\n", value); value = dw_readl(dev, DW_IC_SS_SCL_HCNT); dev_err(dev->dev, "DW_IC_SS_SCL_HCNT: 0x%x\n", value); value = dw_readl(dev, DW_IC_SS_SCL_LCNT); dev_err(dev->dev, "DW_IC_SS_SCL_LCNT: 0x%x\n", value); value = dw_readl(dev, DW_IC_FS_SCL_HCNT); dev_err(dev->dev, "DW_IC_FS_SCL_HCNT: 0x%x\n", value); value = dw_readl(dev, DW_IC_FS_SCL_LCNT); dev_err(dev->dev, "DW_IC_FS_SCL_LCNT: 0x%x\n", value); value = dw_readl(dev, DW_IC_INTR_STAT); dev_err(dev->dev, "DW_IC_INTR_STAT: 0x%x\n", value); value = dw_readl(dev, DW_IC_INTR_MASK); dev_err(dev->dev, "DW_IC_INTR_MASK: 0x%x\n", value); value = dw_readl(dev, DW_IC_RAW_INTR_STAT); dev_err(dev->dev, "DW_IC_RAW_INTR_STAT: 0x%x\n", value); value = dw_readl(dev, DW_IC_RX_TL); dev_err(dev->dev, "DW_IC_RX_TL: 0x%x\n", value); value = dw_readl(dev, DW_IC_TX_TL); dev_err(dev->dev, "DW_IC_TX_TL: 0x%x\n", value); value = dw_readl(dev, DW_IC_ENABLE); dev_err(dev->dev, "DW_IC_ENABLE: 0x%x\n", value); value = dw_readl(dev, DW_IC_STATUS); dev_err(dev->dev, "DW_IC_STATUS: 0x%x\n", value); value = dw_readl(dev, DW_IC_TXFLR); dev_err(dev->dev, "DW_IC_TXFLR: 0x%x\n", value); value = dw_readl(dev, DW_IC_RXFLR); dev_err(dev->dev, "DW_IC_RXFLR: 0x%x\n", value); value = dw_readl(dev, DW_IC_TX_ABRT_SOURCE); dev_err(dev->dev, "DW_IC_TX_ABRT_SOURCE: 0x%x\n", value); value = dw_readl(dev, DW_IC_DATA_CMD); dev_err(dev->dev, "DW_IC_DATA_CMD: 0x%x\n", value); dev_err(dev->dev, "===============================\n"); }
/* * Initiate (and continue) low level master read/write transaction. * This function is only called from i2c_dw_isr, and pumping i2c_msg * messages into the tx buffer. Even if the size of i2c_msg data is * longer than the size of the tx buffer, it handles everything. */ static void i2c_dw_xfer_msg(struct dw_i2c_dev *dev) { struct i2c_msg *msgs = dev->msgs; u32 intr_mask; int tx_limit, rx_limit; u32 addr = msgs[dev->msg_write_idx].addr; u32 buf_len = dev->tx_buf_len; u8 *buf = dev->tx_buf; bool need_restart = false; intr_mask = DW_IC_INTR_MASTER_MASK; for (; dev->msg_write_idx < dev->msgs_num; dev->msg_write_idx++) { u32 flags = msgs[dev->msg_write_idx].flags; /* * If target address has changed, we need to * reprogram the target address in the I2C * adapter when we are done with this transfer. */ if (msgs[dev->msg_write_idx].addr != addr) { dev_err(dev->dev, "%s: invalid target address\n", __func__); dev->msg_err = -EINVAL; break; } if (!(dev->status & STATUS_WRITE_IN_PROGRESS)) { /* new i2c_msg */ buf = msgs[dev->msg_write_idx].buf; buf_len = msgs[dev->msg_write_idx].len; /* If both IC_EMPTYFIFO_HOLD_MASTER_EN and * IC_RESTART_EN are set, we must manually * set restart bit between messages. */ if ((dev->master_cfg & DW_IC_CON_RESTART_EN) && (dev->msg_write_idx > 0)) need_restart = true; } tx_limit = dev->tx_fifo_depth - dw_readl(dev, DW_IC_TXFLR); rx_limit = dev->rx_fifo_depth - dw_readl(dev, DW_IC_RXFLR); while (buf_len > 0 && tx_limit > 0 && rx_limit > 0) { u32 cmd = 0; /* * If IC_EMPTYFIFO_HOLD_MASTER_EN is set we must * manually set the stop bit. However, it cannot be * detected from the registers so we set it always * when writing/reading the last byte. */ /* * i2c-core always sets the buffer length of * I2C_FUNC_SMBUS_BLOCK_DATA to 1. The length will * be adjusted when receiving the first byte. * Thus we can't stop the transaction here. */ if (dev->msg_write_idx == dev->msgs_num - 1 && buf_len == 1 && !(flags & I2C_M_RECV_LEN)) cmd |= BIT(9); if (need_restart) { cmd |= BIT(10); need_restart = false; } if (msgs[dev->msg_write_idx].flags & I2C_M_RD) { /* Avoid rx buffer overrun */ if (dev->rx_outstanding >= dev->rx_fifo_depth) break; dw_writel(dev, cmd | 0x100, DW_IC_DATA_CMD); rx_limit--; dev->rx_outstanding++; } else dw_writel(dev, cmd | *buf++, DW_IC_DATA_CMD); tx_limit--; buf_len--; } dev->tx_buf = buf; dev->tx_buf_len = buf_len; /* * Because we don't know the buffer length in the * I2C_FUNC_SMBUS_BLOCK_DATA case, we can't stop * the transaction here. */ if (buf_len > 0 || flags & I2C_M_RECV_LEN) { /* more bytes to be written */ dev->status |= STATUS_WRITE_IN_PROGRESS; break; } else dev->status &= ~STATUS_WRITE_IN_PROGRESS; } /* * If i2c_msg index search is completed, we don't need TX_EMPTY * interrupt any more. */ if (dev->msg_write_idx == dev->msgs_num) intr_mask &= ~DW_IC_INTR_TX_EMPTY; if (dev->msg_err) intr_mask = 0; dw_writel(dev, intr_mask, DW_IC_INTR_MASK); }
static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev) { u32 stat; /* * The IC_INTR_STAT register just indicates "enabled" interrupts. * Ths unmasked raw version of interrupt status bits are available * in the IC_RAW_INTR_STAT register. * * That is, * stat = dw_readl(IC_INTR_STAT); * equals to, * stat = dw_readl(IC_RAW_INTR_STAT) & dw_readl(IC_INTR_MASK); * * The raw version might be useful for debugging purposes. */ stat = dw_readl(dev, DW_IC_INTR_STAT); /* * Do not use the IC_CLR_INTR register to clear interrupts, or * you'll miss some interrupts, triggered during the period from * dw_readl(IC_INTR_STAT) to dw_readl(IC_CLR_INTR). * * Instead, use the separately-prepared IC_CLR_* registers. */ if (stat & DW_IC_INTR_RX_UNDER) dw_readl(dev, DW_IC_CLR_RX_UNDER); if (stat & DW_IC_INTR_RX_OVER) dw_readl(dev, DW_IC_CLR_RX_OVER); if (stat & DW_IC_INTR_TX_OVER) dw_readl(dev, DW_IC_CLR_TX_OVER); if (stat & DW_IC_INTR_RD_REQ) dw_readl(dev, DW_IC_CLR_RD_REQ); if (stat & DW_IC_INTR_TX_ABRT) { /* * The IC_TX_ABRT_SOURCE register is cleared whenever * the IC_CLR_TX_ABRT is read. Preserve it beforehand. */ dev->abort_source = dw_readl(dev, DW_IC_TX_ABRT_SOURCE); dw_readl(dev, DW_IC_CLR_TX_ABRT); } if (stat & DW_IC_INTR_RX_DONE) dw_readl(dev, DW_IC_CLR_RX_DONE); if (stat & DW_IC_INTR_ACTIVITY) dw_readl(dev, DW_IC_CLR_ACTIVITY); if (stat & DW_IC_INTR_STOP_DET) dw_readl(dev, DW_IC_CLR_STOP_DET); if (stat & DW_IC_INTR_START_DET) dw_readl(dev, DW_IC_CLR_START_DET); if (stat & DW_IC_INTR_GEN_CALL) dw_readl(dev, DW_IC_CLR_GEN_CALL); return stat; }
static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev) { const char *mode_str, *fp_str = ""; u32 comp_param1; u32 sda_falling_time, scl_falling_time; struct i2c_timings *t = &dev->timings; u32 ic_clk; int ret; ret = i2c_dw_acquire_lock(dev); if (ret) return ret; comp_param1 = dw_readl(dev, DW_IC_COMP_PARAM_1); i2c_dw_release_lock(dev); /* Set standard and fast speed dividers for high/low periods */ sda_falling_time = t->sda_fall_ns ?: 300; /* ns */ scl_falling_time = t->scl_fall_ns ?: 300; /* ns */ /* Calculate SCL timing parameters for standard mode if not set */ if (!dev->ss_hcnt || !dev->ss_lcnt) { ic_clk = i2c_dw_clk_rate(dev); dev->ss_hcnt = i2c_dw_scl_hcnt(ic_clk, 4000, /* tHD;STA = tHIGH = 4.0 us */ sda_falling_time, 0, /* 0: DW default, 1: Ideal */ 0); /* No offset */ dev->ss_lcnt = i2c_dw_scl_lcnt(ic_clk, 4700, /* tLOW = 4.7 us */ scl_falling_time, 0); /* No offset */ } dev_dbg(dev->dev, "Standard Mode HCNT:LCNT = %d:%d\n", dev->ss_hcnt, dev->ss_lcnt); /* * Set SCL timing parameters for fast mode or fast mode plus. Only * difference is the timing parameter values since the registers are * the same. */ if (t->bus_freq_hz == 1000000) { /* * Check are fast mode plus parameters available and use * fast mode if not. */ if (dev->fp_hcnt && dev->fp_lcnt) { dev->fs_hcnt = dev->fp_hcnt; dev->fs_lcnt = dev->fp_lcnt; fp_str = " Plus"; } } /* * Calculate SCL timing parameters for fast mode if not set. They are * needed also in high speed mode. */ if (!dev->fs_hcnt || !dev->fs_lcnt) { ic_clk = i2c_dw_clk_rate(dev); dev->fs_hcnt = i2c_dw_scl_hcnt(ic_clk, 600, /* tHD;STA = tHIGH = 0.6 us */ sda_falling_time, 0, /* 0: DW default, 1: Ideal */ 0); /* No offset */ dev->fs_lcnt = i2c_dw_scl_lcnt(ic_clk, 1300, /* tLOW = 1.3 us */ scl_falling_time, 0); /* No offset */ } dev_dbg(dev->dev, "Fast Mode%s HCNT:LCNT = %d:%d\n", fp_str, dev->fs_hcnt, dev->fs_lcnt); /* Check is high speed possible and fall back to fast mode if not */ if ((dev->master_cfg & DW_IC_CON_SPEED_MASK) == DW_IC_CON_SPEED_HIGH) { if ((comp_param1 & DW_IC_COMP_PARAM_1_SPEED_MODE_MASK) != DW_IC_COMP_PARAM_1_SPEED_MODE_HIGH) { dev_err(dev->dev, "High Speed not supported!\n"); dev->master_cfg &= ~DW_IC_CON_SPEED_MASK; dev->master_cfg |= DW_IC_CON_SPEED_FAST; dev->hs_hcnt = 0; dev->hs_lcnt = 0; } else if (dev->hs_hcnt && dev->hs_lcnt) { dev_dbg(dev->dev, "High Speed Mode HCNT:LCNT = %d:%d\n", dev->hs_hcnt, dev->hs_lcnt); } } ret = i2c_dw_set_sda_hold(dev); if (ret) goto out; switch (dev->master_cfg & DW_IC_CON_SPEED_MASK) { case DW_IC_CON_SPEED_STD: mode_str = "Standard Mode"; break; case DW_IC_CON_SPEED_HIGH: mode_str = "High Speed Mode"; break; default: mode_str = "Fast Mode"; } dev_dbg(dev->dev, "Bus speed: %s%s\n", mode_str, fp_str); out: return ret; }