8080
8181#define I2C_TIMEOUT_MSEC 50000
8282#define M_TX_RX_FIFO_SIZE 64
83+ #define M_RX_FIFO_MAX_THLD_VALUE (M_TX_RX_FIFO_SIZE - 1)
84+
85+ #define M_RX_MAX_READ_LEN 255
86+ #define M_RX_FIFO_THLD_VALUE 50
8387
8488enum bus_speed_index {
8589 I2C_SPD_100K = 0 ,
@@ -102,17 +106,39 @@ struct bcm_iproc_i2c_dev {
102106
103107 /* bytes that have been transferred */
104108 unsigned int tx_bytes ;
109+ /* bytes that have been read */
110+ unsigned int rx_bytes ;
111+ unsigned int thld_bytes ;
105112};
106113
107114/*
108115 * Can be expanded in the future if more interrupt status bits are utilized
109116 */
110- #define ISR_MASK (BIT(IS_M_START_BUSY_SHIFT) | BIT(IS_M_TX_UNDERRUN_SHIFT))
117+ #define ISR_MASK (BIT(IS_M_START_BUSY_SHIFT) | BIT(IS_M_TX_UNDERRUN_SHIFT)\
118+ | BIT(IS_M_RX_THLD_SHIFT))
119+
120+ static void bcm_iproc_i2c_read_valid_bytes (struct bcm_iproc_i2c_dev * iproc_i2c )
121+ {
122+ struct i2c_msg * msg = iproc_i2c -> msg ;
123+
124+ /* Read valid data from RX FIFO */
125+ while (iproc_i2c -> rx_bytes < msg -> len ) {
126+ if (!((readl (iproc_i2c -> base + M_FIFO_CTRL_OFFSET ) >> M_FIFO_RX_CNT_SHIFT )
127+ & M_FIFO_RX_CNT_MASK ))
128+ break ;
129+
130+ msg -> buf [iproc_i2c -> rx_bytes ] =
131+ (readl (iproc_i2c -> base + M_RX_OFFSET ) >>
132+ M_RX_DATA_SHIFT ) & M_RX_DATA_MASK ;
133+ iproc_i2c -> rx_bytes ++ ;
134+ }
135+ }
111136
112137static irqreturn_t bcm_iproc_i2c_isr (int irq , void * data )
113138{
114139 struct bcm_iproc_i2c_dev * iproc_i2c = data ;
115140 u32 status = readl (iproc_i2c -> base + IS_OFFSET );
141+ u32 tmp ;
116142
117143 status &= ISR_MASK ;
118144
@@ -136,8 +162,6 @@ static irqreturn_t bcm_iproc_i2c_isr(int irq, void *data)
136162
137163 /* mark the last byte */
138164 if (idx == msg -> len - 1 ) {
139- u32 tmp ;
140-
141165 val |= BIT (M_TX_WR_STATUS_SHIFT );
142166
143167 /*
@@ -156,6 +180,32 @@ static irqreturn_t bcm_iproc_i2c_isr(int irq, void *data)
156180 iproc_i2c -> tx_bytes += tx_bytes ;
157181 }
158182
183+ if (status & BIT (IS_M_RX_THLD_SHIFT )) {
184+ struct i2c_msg * msg = iproc_i2c -> msg ;
185+ u32 bytes_left ;
186+
187+ bcm_iproc_i2c_read_valid_bytes (iproc_i2c );
188+ bytes_left = msg -> len - iproc_i2c -> rx_bytes ;
189+ if (bytes_left == 0 ) {
190+ /* finished reading all data, disable rx thld event */
191+ tmp = readl (iproc_i2c -> base + IE_OFFSET );
192+ tmp &= ~BIT (IS_M_RX_THLD_SHIFT );
193+ writel (tmp , iproc_i2c -> base + IE_OFFSET );
194+ } else if (bytes_left < iproc_i2c -> thld_bytes ) {
195+ /* set bytes left as threshold */
196+ tmp = readl (iproc_i2c -> base + M_FIFO_CTRL_OFFSET );
197+ tmp &= ~(M_FIFO_RX_THLD_MASK << M_FIFO_RX_THLD_SHIFT );
198+ tmp |= (bytes_left << M_FIFO_RX_THLD_SHIFT );
199+ writel (tmp , iproc_i2c -> base + M_FIFO_CTRL_OFFSET );
200+ iproc_i2c -> thld_bytes = bytes_left ;
201+ }
202+ /*
203+ * bytes_left >= iproc_i2c->thld_bytes,
204+ * hence no need to change the THRESHOLD SET.
205+ * It will remain as iproc_i2c->thld_bytes itself
206+ */
207+ }
208+
159209 if (status & BIT (IS_M_START_BUSY_SHIFT )) {
160210 iproc_i2c -> xfer_is_done = 1 ;
161211 complete (& iproc_i2c -> done );
@@ -253,7 +303,7 @@ static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c,
253303{
254304 int ret , i ;
255305 u8 addr ;
256- u32 val ;
306+ u32 val , tmp , val_intr_en ;
257307 unsigned int tx_bytes ;
258308 unsigned long time_left = msecs_to_jiffies (I2C_TIMEOUT_MSEC );
259309
@@ -298,7 +348,7 @@ static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c,
298348 * transaction is done, i.e., the internal start_busy bit, transitions
299349 * from 1 to 0.
300350 */
301- val = BIT (IE_M_START_BUSY_SHIFT );
351+ val_intr_en = BIT (IE_M_START_BUSY_SHIFT );
302352
303353 /*
304354 * If TX data size is larger than the TX FIFO, need to enable TX
@@ -307,21 +357,35 @@ static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c,
307357 */
308358 if (!(msg -> flags & I2C_M_RD ) &&
309359 msg -> len > iproc_i2c -> tx_bytes )
310- val |= BIT (IE_M_TX_UNDERRUN_SHIFT );
311-
312- writel (val , iproc_i2c -> base + IE_OFFSET );
360+ val_intr_en |= BIT (IE_M_TX_UNDERRUN_SHIFT );
313361
314362 /*
315363 * Now we can activate the transfer. For a read operation, specify the
316364 * number of bytes to read
317365 */
318366 val = BIT (M_CMD_START_BUSY_SHIFT );
319367 if (msg -> flags & I2C_M_RD ) {
368+ iproc_i2c -> rx_bytes = 0 ;
369+ if (msg -> len > M_RX_FIFO_MAX_THLD_VALUE )
370+ iproc_i2c -> thld_bytes = M_RX_FIFO_THLD_VALUE ;
371+ else
372+ iproc_i2c -> thld_bytes = msg -> len ;
373+
374+ /* set threshold value */
375+ tmp = readl (iproc_i2c -> base + M_FIFO_CTRL_OFFSET );
376+ tmp &= ~(M_FIFO_RX_THLD_MASK << M_FIFO_RX_THLD_SHIFT );
377+ tmp |= iproc_i2c -> thld_bytes << M_FIFO_RX_THLD_SHIFT ;
378+ writel (tmp , iproc_i2c -> base + M_FIFO_CTRL_OFFSET );
379+
380+ /* enable the RX threshold interrupt */
381+ val_intr_en |= BIT (IE_M_RX_THLD_SHIFT );
382+
320383 val |= (M_CMD_PROTOCOL_BLK_RD << M_CMD_PROTOCOL_SHIFT ) |
321384 (msg -> len << M_CMD_RD_CNT_SHIFT );
322385 } else {
323386 val |= (M_CMD_PROTOCOL_BLK_WR << M_CMD_PROTOCOL_SHIFT );
324387 }
388+ writel (val_intr_en , iproc_i2c -> base + IE_OFFSET );
325389 writel (val , iproc_i2c -> base + M_CMD_OFFSET );
326390
327391 time_left = wait_for_completion_timeout (& iproc_i2c -> done , time_left );
@@ -353,17 +417,6 @@ static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c,
353417 return ret ;
354418 }
355419
356- /*
357- * For a read operation, we now need to load the data from FIFO
358- * into the memory buffer
359- */
360- if (msg -> flags & I2C_M_RD ) {
361- for (i = 0 ; i < msg -> len ; i ++ ) {
362- msg -> buf [i ] = (readl (iproc_i2c -> base + M_RX_OFFSET ) >>
363- M_RX_DATA_SHIFT ) & M_RX_DATA_MASK ;
364- }
365- }
366-
367420 return 0 ;
368421}
369422
@@ -395,9 +448,8 @@ static const struct i2c_algorithm bcm_iproc_algo = {
395448 .functionality = bcm_iproc_i2c_functionality ,
396449};
397450
398- static const struct i2c_adapter_quirks bcm_iproc_i2c_quirks = {
399- /* need to reserve one byte in the FIFO for the slave address */
400- .max_read_len = M_TX_RX_FIFO_SIZE - 1 ,
451+ static struct i2c_adapter_quirks bcm_iproc_i2c_quirks = {
452+ .max_read_len = M_RX_MAX_READ_LEN ,
401453};
402454
403455static int bcm_iproc_i2c_cfg_speed (struct bcm_iproc_i2c_dev * iproc_i2c )
0 commit comments