blob: 2dc76182ed15dc1bbd81be8529b5d9725c58e221 [file] [log] [blame]
Subbaraman Narayanamurthy95450d62017-01-18 20:10:51 -08001/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#define pr_fmt(fmt) "FG: %s: " fmt, __func__
14
15#include "fg-core.h"
16#include "fg-reg.h"
17
18/* Generic definitions */
19#define RETRY_COUNT 3
20#define BYTES_PER_SRAM_WORD 4
21
22enum {
23 FG_READ = 0,
24 FG_WRITE,
25};
26
27static int fg_set_address(struct fg_chip *chip, u16 address)
28{
29 u8 buffer[2];
30 int rc;
31
32 buffer[0] = address & 0xFF;
33 /* MSB has to be written zero */
34 buffer[1] = 0;
35
36 rc = fg_write(chip, MEM_IF_ADDR_LSB(chip), buffer, 2);
37 if (rc < 0) {
38 pr_err("failed to write to 0x%04X, rc=%d\n",
39 MEM_IF_ADDR_LSB(chip), rc);
40 return rc;
41 }
42
43 return rc;
44}
45
46static int fg_config_access_mode(struct fg_chip *chip, bool access, bool burst)
47{
48 int rc;
49 u8 intf_ctl = 0;
50
51 intf_ctl = ((access == FG_WRITE) ? IMA_WR_EN_BIT : 0) |
52 (burst ? MEM_ACS_BURST_BIT : 0);
53
54 rc = fg_masked_write(chip, MEM_IF_IMA_CTL(chip), IMA_CTL_MASK,
55 intf_ctl);
56 if (rc < 0) {
57 pr_err("failed to write to 0x%04x, rc=%d\n",
58 MEM_IF_IMA_CTL(chip), rc);
59 return -EIO;
60 }
61
62 return rc;
63}
64
65static int fg_run_iacs_clear_sequence(struct fg_chip *chip)
66{
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -070067 u8 val, hw_sts, exp_sts;
68 int rc, tries = 250;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -070069
70 /*
71 * Values to write for running IACS clear sequence comes from
72 * hardware documentation.
73 */
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -070074 rc = fg_masked_write(chip, MEM_IF_IMA_CFG(chip),
75 IACS_CLR_BIT | STATIC_CLK_EN_BIT,
76 IACS_CLR_BIT | STATIC_CLK_EN_BIT);
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -070077 if (rc < 0) {
78 pr_err("failed to write 0x%04x, rc=%d\n", MEM_IF_IMA_CFG(chip),
79 rc);
80 return rc;
81 }
82
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -070083 rc = fg_config_access_mode(chip, FG_READ, false);
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -070084 if (rc < 0) {
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -070085 pr_err("failed to write to 0x%04x, rc=%d\n",
86 MEM_IF_IMA_CTL(chip), rc);
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -070087 return rc;
88 }
89
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -070090 rc = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip),
91 MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT,
92 MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT);
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -070093 if (rc < 0) {
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -070094 pr_err("failed to set ima_req_access bit rc=%d\n", rc);
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -070095 return rc;
96 }
97
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -070098 /* Delay for the clock to reach FG */
99 usleep_range(35, 40);
100
101 while (1) {
102 val = 0;
103 rc = fg_write(chip, MEM_IF_ADDR_MSB(chip), &val, 1);
104 if (rc < 0) {
105 pr_err("failed to write 0x%04x, rc=%d\n",
106 MEM_IF_ADDR_MSB(chip), rc);
107 return rc;
108 }
109
110 val = 0;
111 rc = fg_write(chip, MEM_IF_WR_DATA3(chip), &val, 1);
112 if (rc < 0) {
113 pr_err("failed to write 0x%04x, rc=%d\n",
114 MEM_IF_WR_DATA3(chip), rc);
115 return rc;
116 }
117
118 rc = fg_read(chip, MEM_IF_RD_DATA3(chip), &val, 1);
119 if (rc < 0) {
120 pr_err("failed to read 0x%04x, rc=%d\n",
121 MEM_IF_RD_DATA3(chip), rc);
122 return rc;
123 }
124
125 /* Delay for IMA hardware to clear */
126 usleep_range(35, 40);
127
128 rc = fg_read(chip, MEM_IF_IMA_HW_STS(chip), &hw_sts, 1);
129 if (rc < 0) {
130 pr_err("failed to read ima_hw_sts rc=%d\n", rc);
131 return rc;
132 }
133
134 if (hw_sts != 0)
135 continue;
136
137 rc = fg_read(chip, MEM_IF_IMA_EXP_STS(chip), &exp_sts, 1);
138 if (rc < 0) {
139 pr_err("failed to read ima_exp_sts rc=%d\n", rc);
140 return rc;
141 }
142
143 if (exp_sts == 0 || !(--tries))
144 break;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700145 }
146
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700147 if (!tries)
148 pr_err("Failed to clear the error? hw_sts: %x exp_sts: %d\n",
149 hw_sts, exp_sts);
150
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700151 rc = fg_masked_write(chip, MEM_IF_IMA_CFG(chip), IACS_CLR_BIT, 0);
152 if (rc < 0) {
153 pr_err("failed to write 0x%04x, rc=%d\n", MEM_IF_IMA_CFG(chip),
154 rc);
155 return rc;
156 }
157
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700158 udelay(5);
159
160 rc = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip),
161 MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT, 0);
162 if (rc < 0) {
163 pr_err("failed to write to 0x%04x, rc=%d\n",
164 MEM_IF_MEM_INTF_CFG(chip), rc);
165 return rc;
166 }
167
168 /* Delay before next transaction is attempted */
169 usleep_range(35, 40);
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700170 fg_dbg(chip, FG_SRAM_READ | FG_SRAM_WRITE, "IACS clear sequence complete\n");
171 return rc;
172}
173
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700174int fg_clear_dma_errors_if_any(struct fg_chip *chip)
175{
176 int rc;
177 u8 dma_sts;
178
179 rc = fg_read(chip, MEM_IF_DMA_STS(chip), &dma_sts, 1);
180 if (rc < 0) {
181 pr_err("failed to read addr=0x%04x, rc=%d\n",
182 MEM_IF_DMA_STS(chip), rc);
183 return rc;
184 }
185 fg_dbg(chip, FG_STATUS, "dma_sts: %x\n", dma_sts);
186
187 if (dma_sts & (DMA_WRITE_ERROR_BIT | DMA_READ_ERROR_BIT)) {
188 rc = fg_masked_write(chip, MEM_IF_DMA_CTL(chip),
189 DMA_CLEAR_LOG_BIT, DMA_CLEAR_LOG_BIT);
190 if (rc < 0) {
191 pr_err("failed to write addr=0x%04x, rc=%d\n",
192 MEM_IF_DMA_CTL(chip), rc);
193 return rc;
194 }
195 }
196
197 return 0;
198}
199
200int fg_clear_ima_errors_if_any(struct fg_chip *chip, bool check_hw_sts)
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700201{
202 int rc = 0;
203 u8 err_sts, exp_sts = 0, hw_sts = 0;
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700204 bool run_err_clr_seq = false;
205
206 rc = fg_read(chip, MEM_IF_IMA_EXP_STS(chip), &exp_sts, 1);
207 if (rc < 0) {
208 pr_err("failed to read ima_exp_sts rc=%d\n", rc);
209 return rc;
210 }
211
212 rc = fg_read(chip, MEM_IF_IMA_HW_STS(chip), &hw_sts, 1);
213 if (rc < 0) {
214 pr_err("failed to read ima_hw_sts rc=%d\n", rc);
215 return rc;
216 }
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700217
218 rc = fg_read(chip, MEM_IF_IMA_ERR_STS(chip), &err_sts, 1);
219 if (rc < 0) {
220 pr_err("failed to read ima_err_sts rc=%d\n", rc);
221 return rc;
222 }
223
Subbaraman Narayanamurthy03e6c612016-11-09 16:40:27 -0800224 fg_dbg(chip, FG_SRAM_READ | FG_SRAM_WRITE, "ima_err_sts=%x ima_exp_sts=%x ima_hw_sts=%x\n",
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700225 err_sts, exp_sts, hw_sts);
226
227 if (check_hw_sts) {
228 /*
229 * Lower nibble should be equal to upper nibble before SRAM
230 * transactions begins from SW side. If they are unequal, then
231 * the error clear sequence should be run irrespective of IMA
232 * exception errors.
233 */
234 if ((hw_sts & 0x0F) != hw_sts >> 4) {
235 pr_err("IMA HW not in correct state, hw_sts=%x\n",
236 hw_sts);
237 run_err_clr_seq = true;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700238 }
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700239 }
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700240
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700241 if (exp_sts & (IACS_ERR_BIT | XCT_TYPE_ERR_BIT | DATA_RD_ERR_BIT |
242 DATA_WR_ERR_BIT | ADDR_BURST_WRAP_BIT | ADDR_STABLE_ERR_BIT)) {
243 pr_err("IMA exception bit set, exp_sts=%x\n", exp_sts);
244 run_err_clr_seq = true;
245 }
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700246
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700247 if (run_err_clr_seq) {
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700248 /* clear the error */
249 rc = fg_run_iacs_clear_sequence(chip);
250 if (rc < 0) {
251 pr_err("failed to run iacs clear sequence rc=%d\n", rc);
252 return rc;
253 }
254
255 /* Retry again as there was an error in the transaction */
256 return -EAGAIN;
257 }
258
259 return rc;
260}
261
262static int fg_check_iacs_ready(struct fg_chip *chip)
263{
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700264 int rc = 0, tries = 250;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700265 u8 ima_opr_sts = 0;
266
267 /*
268 * Additional delay to make sure IACS ready bit is set after
269 * Read/Write operation.
270 */
271
272 usleep_range(30, 35);
273 while (1) {
274 rc = fg_read(chip, MEM_IF_IMA_OPR_STS(chip), &ima_opr_sts, 1);
275 if (rc < 0) {
276 pr_err("failed to read 0x%04x, rc=%d\n",
277 MEM_IF_IMA_OPR_STS(chip), rc);
278 return rc;
279 }
280
281 if (ima_opr_sts & IACS_RDY_BIT)
282 break;
283
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700284 if (!(--tries))
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700285 break;
286
287 /* delay for iacs_ready to be asserted */
288 usleep_range(5000, 7000);
289 }
290
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700291 if (!tries) {
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800292 pr_err("IACS_RDY not set, opr_sts: %d\n", ima_opr_sts);
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700293 /* check for error condition */
294 rc = fg_clear_ima_errors_if_any(chip, false);
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700295 if (rc < 0) {
296 pr_err("Failed to check for ima errors rc=%d\n", rc);
297 return rc;
298 }
299
300 return -EBUSY;
301 }
302
303 return 0;
304}
305
306static int __fg_interleaved_mem_write(struct fg_chip *chip, u16 address,
307 int offset, u8 *val, int len)
308{
309 int rc = 0, i;
310 u8 *ptr = val, byte_enable = 0, num_bytes = 0;
311
312 fg_dbg(chip, FG_SRAM_WRITE, "length %d addr=%02X offset=%d\n", len,
313 address, offset);
314
315 while (len > 0) {
316 num_bytes = (offset + len) > BYTES_PER_SRAM_WORD ?
317 (BYTES_PER_SRAM_WORD - offset) : len;
318
319 /* write to byte_enable */
320 for (i = offset; i < (offset + num_bytes); i++)
321 byte_enable |= BIT(i);
322
323 rc = fg_write(chip, MEM_IF_IMA_BYTE_EN(chip), &byte_enable, 1);
324 if (rc < 0) {
325 pr_err("Unable to write to byte_en_reg rc=%d\n",
326 rc);
327 return rc;
328 }
329
330 /* write data */
331 rc = fg_write(chip, MEM_IF_WR_DATA0(chip) + offset, ptr,
332 num_bytes);
333 if (rc < 0) {
334 pr_err("failed to write to 0x%04x, rc=%d\n",
335 MEM_IF_WR_DATA0(chip) + offset, rc);
336 return rc;
337 }
338
339 /*
340 * The last-byte WR_DATA3 starts the write transaction.
341 * Write a dummy value to WR_DATA3 if it does not have
342 * valid data. This dummy data is not written to the
343 * SRAM as byte_en for WR_DATA3 is not set.
344 */
345 if (!(byte_enable & BIT(3))) {
346 u8 dummy_byte = 0x0;
347
348 rc = fg_write(chip, MEM_IF_WR_DATA3(chip), &dummy_byte,
349 1);
350 if (rc < 0) {
351 pr_err("failed to write dummy-data to WR_DATA3 rc=%d\n",
352 rc);
353 return rc;
354 }
355 }
356
357 /* check for error condition */
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700358 rc = fg_clear_ima_errors_if_any(chip, false);
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700359 if (rc < 0) {
360 pr_err("Failed to check for ima errors rc=%d\n", rc);
361 return rc;
362 }
363
364 ptr += num_bytes;
365 len -= num_bytes;
366 offset = byte_enable = 0;
367
368 rc = fg_check_iacs_ready(chip);
369 if (rc < 0) {
370 pr_debug("IACS_RDY failed rc=%d\n", rc);
371 return rc;
372 }
373 }
374
375 return rc;
376}
377
378static int __fg_interleaved_mem_read(struct fg_chip *chip, u16 address,
379 int offset, u8 *val, int len)
380{
381 int rc = 0, total_len;
382 u8 *rd_data = val, num_bytes;
383 char str[DEBUG_PRINT_BUFFER_SIZE];
384
385 fg_dbg(chip, FG_SRAM_READ, "length %d addr=%02X\n", len, address);
386
387 total_len = len;
388 while (len > 0) {
389 num_bytes = (offset + len) > BYTES_PER_SRAM_WORD ?
390 (BYTES_PER_SRAM_WORD - offset) : len;
391 rc = fg_read(chip, MEM_IF_RD_DATA0(chip) + offset, rd_data,
392 num_bytes);
393 if (rc < 0) {
394 pr_err("failed to read 0x%04x, rc=%d\n",
395 MEM_IF_RD_DATA0(chip) + offset, rc);
396 return rc;
397 }
398
399 rd_data += num_bytes;
400 len -= num_bytes;
401 offset = 0;
402
403 /* check for error condition */
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700404 rc = fg_clear_ima_errors_if_any(chip, false);
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700405 if (rc < 0) {
406 pr_err("Failed to check for ima errors rc=%d\n", rc);
407 return rc;
408 }
409
410 if (len && len < BYTES_PER_SRAM_WORD) {
411 /*
412 * Move to single mode. Changing address is not
413 * required here as it must be in burst mode. Address
414 * will get incremented internally by FG HW once the MSB
415 * of RD_DATA is read.
416 */
417 rc = fg_config_access_mode(chip, FG_READ, 0);
418 if (rc < 0) {
419 pr_err("failed to move to single mode rc=%d\n",
420 rc);
421 return -EIO;
422 }
423 }
424
425 rc = fg_check_iacs_ready(chip);
426 if (rc < 0) {
427 pr_debug("IACS_RDY failed rc=%d\n", rc);
428 return rc;
429 }
430 }
431
432 if (*chip->debug_mask & FG_SRAM_READ) {
433 fill_string(str, DEBUG_PRINT_BUFFER_SIZE, val, total_len);
434 pr_info("data read: %s\n", str);
435 }
436
437 return rc;
438}
439
440static int fg_get_mem_access_status(struct fg_chip *chip, bool *status)
441{
442 int rc;
443 u8 mem_if_sts;
444
445 rc = fg_read(chip, MEM_IF_MEM_INTF_CFG(chip), &mem_if_sts, 1);
446 if (rc < 0) {
447 pr_err("failed to read rif_mem status rc=%d\n", rc);
448 return rc;
449 }
450
451 *status = mem_if_sts & MEM_ACCESS_REQ_BIT;
452 return 0;
453}
454
455static bool is_mem_access_available(struct fg_chip *chip, int access)
456{
457 bool rif_mem_sts = true;
458 int rc, time_count = 0;
459
460 while (1) {
461 rc = fg_get_mem_access_status(chip, &rif_mem_sts);
462 if (rc < 0)
463 return rc;
464
465 /* This is an inverting logic */
466 if (!rif_mem_sts)
467 break;
468
469 fg_dbg(chip, FG_SRAM_READ | FG_SRAM_WRITE, "MEM_ACCESS_REQ is not clear yet for IMA_%s\n",
470 access ? "write" : "read");
471
472 /*
473 * Try this no more than 4 times. If MEM_ACCESS_REQ is not
474 * clear, then return an error instead of waiting for it again.
475 */
476 if (time_count > 4) {
477 pr_err("Tried 4 times(~16ms) polling MEM_ACCESS_REQ\n");
478 return false;
479 }
480
481 /* Wait for 4ms before reading MEM_ACCESS_REQ again */
482 usleep_range(4000, 4100);
483 time_count++;
484 }
485 return true;
486}
487
488static int fg_interleaved_mem_config(struct fg_chip *chip, u8 *val,
489 u16 address, int offset, int len, bool access)
490{
491 int rc = 0;
492
493 if (!is_mem_access_available(chip, access))
494 return -EBUSY;
495
496 /* configure for IMA access */
497 rc = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip),
498 MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT,
499 MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT);
500 if (rc < 0) {
501 pr_err("failed to set ima_req_access bit rc=%d\n", rc);
502 return rc;
503 }
504
505 /* configure for the read/write, single/burst mode */
506 rc = fg_config_access_mode(chip, access, (offset + len) > 4);
507 if (rc < 0) {
508 pr_err("failed to set memory access rc = %d\n", rc);
509 return rc;
510 }
511
512 rc = fg_check_iacs_ready(chip);
513 if (rc < 0) {
514 pr_err_ratelimited("IACS_RDY failed rc=%d\n", rc);
515 return rc;
516 }
517
518 rc = fg_set_address(chip, address);
519 if (rc < 0) {
520 pr_err("failed to set address rc = %d\n", rc);
521 return rc;
522 }
523
524 if (access == FG_READ) {
525 rc = fg_check_iacs_ready(chip);
526 if (rc < 0) {
527 pr_debug("IACS_RDY failed rc=%d\n", rc);
528 return rc;
529 }
530 }
531
532 return rc;
533}
534
535static int fg_get_beat_count(struct fg_chip *chip, u8 *count)
536{
537 int rc;
538
539 rc = fg_read(chip, MEM_IF_FG_BEAT_COUNT(chip), count, 1);
540 *count &= BEAT_COUNT_MASK;
541 return rc;
542}
543
544int fg_interleaved_mem_read(struct fg_chip *chip, u16 address, u8 offset,
545 u8 *val, int len)
546{
Subbaraman Narayanamurthy95450d62017-01-18 20:10:51 -0800547 int rc = 0, ret;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700548 u8 start_beat_count, end_beat_count, count = 0;
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800549 bool retry = false;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700550
551 if (offset > 3) {
552 pr_err("offset too large %d\n", offset);
553 return -EINVAL;
554 }
555
556retry:
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800557 if (count >= RETRY_COUNT) {
558 pr_err("Tried %d times\n", RETRY_COUNT);
559 retry = false;
560 goto out;
561 }
562
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700563 rc = fg_interleaved_mem_config(chip, val, address, offset, len,
564 FG_READ);
565 if (rc < 0) {
566 pr_err("failed to configure SRAM for IMA rc = %d\n", rc);
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800567 count++;
568 retry = true;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700569 goto out;
570 }
571
572 /* read the start beat count */
573 rc = fg_get_beat_count(chip, &start_beat_count);
574 if (rc < 0) {
575 pr_err("failed to read beat count rc=%d\n", rc);
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800576 count++;
577 retry = true;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700578 goto out;
579 }
580
581 /* read data */
582 rc = __fg_interleaved_mem_read(chip, address, offset, val, len);
583 if (rc < 0) {
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800584 count++;
585 if (rc == -EAGAIN) {
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700586 pr_err("IMA access failed retry_count = %d\n", count);
587 goto retry;
588 }
589 pr_err("failed to read SRAM address rc = %d\n", rc);
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800590 retry = true;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700591 goto out;
592 }
593
594 /* read the end beat count */
595 rc = fg_get_beat_count(chip, &end_beat_count);
596 if (rc < 0) {
597 pr_err("failed to read beat count rc=%d\n", rc);
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800598 count++;
599 retry = true;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700600 goto out;
601 }
602
603 fg_dbg(chip, FG_SRAM_READ, "Start beat_count = %x End beat_count = %x\n",
604 start_beat_count, end_beat_count);
605
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800606 if (start_beat_count != end_beat_count) {
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700607 fg_dbg(chip, FG_SRAM_READ, "Beat count(%d/%d) do not match - retry transaction\n",
608 start_beat_count, end_beat_count);
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800609 count++;
610 retry = true;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700611 }
612out:
613 /* Release IMA access */
Subbaraman Narayanamurthy95450d62017-01-18 20:10:51 -0800614 ret = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip),
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700615 MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT, 0);
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800616 if (rc < 0 && ret < 0) {
Subbaraman Narayanamurthy95450d62017-01-18 20:10:51 -0800617 pr_err("failed to reset IMA access bit ret = %d\n", ret);
618 return ret;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700619 }
620
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800621 if (retry) {
622 retry = false;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700623 goto retry;
Subbaraman Narayanamurthycd0a9b22016-09-14 19:20:24 -0700624 }
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700625
626 return rc;
627}
628
629int fg_interleaved_mem_write(struct fg_chip *chip, u16 address, u8 offset,
630 u8 *val, int len, bool atomic_access)
631{
Subbaraman Narayanamurthy95450d62017-01-18 20:10:51 -0800632 int rc = 0, ret;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700633 u8 start_beat_count, end_beat_count, count = 0;
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800634 bool retry = false;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700635
636 if (offset > 3) {
637 pr_err("offset too large %d\n", offset);
638 return -EINVAL;
639 }
640
641retry:
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800642 if (count >= RETRY_COUNT) {
643 pr_err("Tried %d times\n", RETRY_COUNT);
644 retry = false;
645 goto out;
646 }
647
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700648 rc = fg_interleaved_mem_config(chip, val, address, offset, len,
649 FG_WRITE);
650 if (rc < 0) {
651 pr_err("failed to configure SRAM for IMA rc = %d\n", rc);
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800652 count++;
653 retry = true;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700654 goto out;
655 }
656
657 /* read the start beat count */
658 rc = fg_get_beat_count(chip, &start_beat_count);
659 if (rc < 0) {
660 pr_err("failed to read beat count rc=%d\n", rc);
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800661 count++;
662 retry = true;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700663 goto out;
664 }
665
666 /* write data */
667 rc = __fg_interleaved_mem_write(chip, address, offset, val, len);
668 if (rc < 0) {
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800669 count++;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700670 if ((rc == -EAGAIN) && (count < RETRY_COUNT)) {
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700671 pr_err("IMA access failed retry_count = %d\n", count);
672 goto retry;
673 }
674 pr_err("failed to write SRAM address rc = %d\n", rc);
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800675 retry = true;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700676 goto out;
677 }
678
679 /* read the end beat count */
680 rc = fg_get_beat_count(chip, &end_beat_count);
681 if (rc < 0) {
682 pr_err("failed to read beat count rc=%d\n", rc);
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800683 count++;
684 retry = true;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700685 goto out;
686 }
687
688 if (atomic_access && start_beat_count != end_beat_count)
689 pr_err("Start beat_count = %x End beat_count = %x\n",
690 start_beat_count, end_beat_count);
691out:
692 /* Release IMA access */
Subbaraman Narayanamurthy95450d62017-01-18 20:10:51 -0800693 ret = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip),
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700694 MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT, 0);
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800695 if (rc < 0 && ret < 0) {
Subbaraman Narayanamurthy95450d62017-01-18 20:10:51 -0800696 pr_err("failed to reset IMA access bit ret = %d\n", ret);
697 return ret;
698 }
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700699
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800700 if (retry) {
701 retry = false;
702 goto retry;
703 }
704
Subbaraman Narayanamurthy95450d62017-01-18 20:10:51 -0800705 /* Return the error we got before releasing memory access */
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700706 return rc;
707}
708
709int fg_ima_init(struct fg_chip *chip)
710{
711 int rc;
712
713 /*
714 * Change the FG_MEM_INT interrupt to track IACS_READY
715 * condition instead of end-of-transaction. This makes sure
716 * that the next transaction starts only after the hw is ready.
717 */
718 rc = fg_masked_write(chip, MEM_IF_IMA_CFG(chip), IACS_INTR_SRC_SLCT_BIT,
719 IACS_INTR_SRC_SLCT_BIT);
720 if (rc < 0) {
721 pr_err("failed to configure interrupt source %d\n", rc);
722 return rc;
723 }
724
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700725 /* Clear DMA errors if any before clearing IMA errors */
726 rc = fg_clear_dma_errors_if_any(chip);
727 if (rc < 0) {
728 pr_err("Error in checking DMA errors rc:%d\n", rc);
729 return rc;
730 }
731
732 /* Clear IMA errors if any before SRAM transactions can begin */
733 rc = fg_clear_ima_errors_if_any(chip, true);
734 if (rc < 0 && rc != -EAGAIN) {
735 pr_err("Error in checking IMA errors rc:%d\n", rc);
736 return rc;
737 }
738
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700739 return 0;
740}