blob: 88c96bc55ec48c213664ff28ca3908353ac614d6 [file] [log] [blame]
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -07001/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
2 *
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 Narayanamurthya71c9dd2016-10-14 19:38:05 -0700224 fg_dbg(chip, FG_STATUS, "ima_err_sts=%x ima_exp_sts=%x ima_hw_sts=%x\n",
225 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 Narayanamurthy6accb262016-03-14 16:41:16 -0700292 pr_err("IACS_RDY not set\n");
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{
547 int rc = 0;
548 u8 start_beat_count, end_beat_count, count = 0;
549 bool retry_once = false;
550
551 if (offset > 3) {
552 pr_err("offset too large %d\n", offset);
553 return -EINVAL;
554 }
555
556retry:
557 rc = fg_interleaved_mem_config(chip, val, address, offset, len,
558 FG_READ);
559 if (rc < 0) {
560 pr_err("failed to configure SRAM for IMA rc = %d\n", rc);
561 goto out;
562 }
563
564 /* read the start beat count */
565 rc = fg_get_beat_count(chip, &start_beat_count);
566 if (rc < 0) {
567 pr_err("failed to read beat count rc=%d\n", rc);
568 goto out;
569 }
570
571 /* read data */
572 rc = __fg_interleaved_mem_read(chip, address, offset, val, len);
573 if (rc < 0) {
574 if ((rc == -EAGAIN) && (count < RETRY_COUNT)) {
575 count++;
576 pr_err("IMA access failed retry_count = %d\n", count);
577 goto retry;
578 }
579 pr_err("failed to read SRAM address rc = %d\n", rc);
580 goto out;
581 }
582
583 /* read the end beat count */
584 rc = fg_get_beat_count(chip, &end_beat_count);
585 if (rc < 0) {
586 pr_err("failed to read beat count rc=%d\n", rc);
587 goto out;
588 }
589
590 fg_dbg(chip, FG_SRAM_READ, "Start beat_count = %x End beat_count = %x\n",
591 start_beat_count, end_beat_count);
592
593 if (start_beat_count != end_beat_count && !retry_once) {
594 fg_dbg(chip, FG_SRAM_READ, "Beat count(%d/%d) do not match - retry transaction\n",
595 start_beat_count, end_beat_count);
596 retry_once = true;
597 }
598out:
599 /* Release IMA access */
600 rc = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip),
601 MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT, 0);
602 if (rc < 0) {
603 pr_err("failed to reset IMA access bit rc = %d\n", rc);
604 return rc;
605 }
606
Subbaraman Narayanamurthycd0a9b22016-09-14 19:20:24 -0700607 if (retry_once) {
608 retry_once = false;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700609 goto retry;
Subbaraman Narayanamurthycd0a9b22016-09-14 19:20:24 -0700610 }
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700611
612 return rc;
613}
614
615int fg_interleaved_mem_write(struct fg_chip *chip, u16 address, u8 offset,
616 u8 *val, int len, bool atomic_access)
617{
618 int rc = 0;
619 u8 start_beat_count, end_beat_count, count = 0;
620
621 if (offset > 3) {
622 pr_err("offset too large %d\n", offset);
623 return -EINVAL;
624 }
625
626retry:
627 rc = fg_interleaved_mem_config(chip, val, address, offset, len,
628 FG_WRITE);
629 if (rc < 0) {
630 pr_err("failed to configure SRAM for IMA rc = %d\n", rc);
631 goto out;
632 }
633
634 /* read the start beat count */
635 rc = fg_get_beat_count(chip, &start_beat_count);
636 if (rc < 0) {
637 pr_err("failed to read beat count rc=%d\n", rc);
638 goto out;
639 }
640
641 /* write data */
642 rc = __fg_interleaved_mem_write(chip, address, offset, val, len);
643 if (rc < 0) {
644 if ((rc == -EAGAIN) && (count < RETRY_COUNT)) {
645 count++;
646 pr_err("IMA access failed retry_count = %d\n", count);
647 goto retry;
648 }
649 pr_err("failed to write SRAM address rc = %d\n", rc);
650 goto out;
651 }
652
653 /* read the end beat count */
654 rc = fg_get_beat_count(chip, &end_beat_count);
655 if (rc < 0) {
656 pr_err("failed to read beat count rc=%d\n", rc);
657 goto out;
658 }
659
660 if (atomic_access && start_beat_count != end_beat_count)
661 pr_err("Start beat_count = %x End beat_count = %x\n",
662 start_beat_count, end_beat_count);
663out:
664 /* Release IMA access */
665 rc = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip),
666 MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT, 0);
667 if (rc < 0)
668 pr_err("failed to reset IMA access bit rc = %d\n", rc);
669
670 return rc;
671}
672
673int fg_ima_init(struct fg_chip *chip)
674{
675 int rc;
676
677 /*
678 * Change the FG_MEM_INT interrupt to track IACS_READY
679 * condition instead of end-of-transaction. This makes sure
680 * that the next transaction starts only after the hw is ready.
681 */
682 rc = fg_masked_write(chip, MEM_IF_IMA_CFG(chip), IACS_INTR_SRC_SLCT_BIT,
683 IACS_INTR_SRC_SLCT_BIT);
684 if (rc < 0) {
685 pr_err("failed to configure interrupt source %d\n", rc);
686 return rc;
687 }
688
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700689 /* Clear DMA errors if any before clearing IMA errors */
690 rc = fg_clear_dma_errors_if_any(chip);
691 if (rc < 0) {
692 pr_err("Error in checking DMA errors rc:%d\n", rc);
693 return rc;
694 }
695
696 /* Clear IMA errors if any before SRAM transactions can begin */
697 rc = fg_clear_ima_errors_if_any(chip, true);
698 if (rc < 0 && rc != -EAGAIN) {
699 pr_err("Error in checking IMA errors rc:%d\n", rc);
700 return rc;
701 }
702
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700703 return 0;
704}