blob: 0abc9df3b41c2b7f8b903cf8497c79bc03cd8040 [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
Subbaraman Narayanamurthy1dece462017-03-23 11:06:08 -070051 fg_dbg(chip, FG_SRAM_READ | FG_SRAM_WRITE, "access: %d burst: %d\n",
52 access, burst);
53
54 WARN_ON(burst && chip->use_ima_single_mode);
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -070055 intf_ctl = ((access == FG_WRITE) ? IMA_WR_EN_BIT : 0) |
56 (burst ? MEM_ACS_BURST_BIT : 0);
57
58 rc = fg_masked_write(chip, MEM_IF_IMA_CTL(chip), IMA_CTL_MASK,
59 intf_ctl);
60 if (rc < 0) {
61 pr_err("failed to write to 0x%04x, rc=%d\n",
62 MEM_IF_IMA_CTL(chip), rc);
63 return -EIO;
64 }
65
66 return rc;
67}
68
69static int fg_run_iacs_clear_sequence(struct fg_chip *chip)
70{
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -070071 u8 val, hw_sts, exp_sts;
72 int rc, tries = 250;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -070073
74 /*
75 * Values to write for running IACS clear sequence comes from
76 * hardware documentation.
77 */
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -070078 rc = fg_masked_write(chip, MEM_IF_IMA_CFG(chip),
79 IACS_CLR_BIT | STATIC_CLK_EN_BIT,
80 IACS_CLR_BIT | STATIC_CLK_EN_BIT);
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -070081 if (rc < 0) {
82 pr_err("failed to write 0x%04x, rc=%d\n", MEM_IF_IMA_CFG(chip),
83 rc);
84 return rc;
85 }
86
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -070087 rc = fg_config_access_mode(chip, FG_READ, false);
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -070088 if (rc < 0) {
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -070089 pr_err("failed to write to 0x%04x, rc=%d\n",
90 MEM_IF_IMA_CTL(chip), rc);
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -070091 return rc;
92 }
93
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -070094 rc = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip),
95 MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT,
96 MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT);
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -070097 if (rc < 0) {
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -070098 pr_err("failed to set ima_req_access bit rc=%d\n", rc);
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -070099 return rc;
100 }
101
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700102 /* Delay for the clock to reach FG */
103 usleep_range(35, 40);
104
105 while (1) {
106 val = 0;
107 rc = fg_write(chip, MEM_IF_ADDR_MSB(chip), &val, 1);
108 if (rc < 0) {
109 pr_err("failed to write 0x%04x, rc=%d\n",
110 MEM_IF_ADDR_MSB(chip), rc);
111 return rc;
112 }
113
114 val = 0;
115 rc = fg_write(chip, MEM_IF_WR_DATA3(chip), &val, 1);
116 if (rc < 0) {
117 pr_err("failed to write 0x%04x, rc=%d\n",
118 MEM_IF_WR_DATA3(chip), rc);
119 return rc;
120 }
121
122 rc = fg_read(chip, MEM_IF_RD_DATA3(chip), &val, 1);
123 if (rc < 0) {
124 pr_err("failed to read 0x%04x, rc=%d\n",
125 MEM_IF_RD_DATA3(chip), rc);
126 return rc;
127 }
128
129 /* Delay for IMA hardware to clear */
130 usleep_range(35, 40);
131
132 rc = fg_read(chip, MEM_IF_IMA_HW_STS(chip), &hw_sts, 1);
133 if (rc < 0) {
134 pr_err("failed to read ima_hw_sts rc=%d\n", rc);
135 return rc;
136 }
137
138 if (hw_sts != 0)
139 continue;
140
141 rc = fg_read(chip, MEM_IF_IMA_EXP_STS(chip), &exp_sts, 1);
142 if (rc < 0) {
143 pr_err("failed to read ima_exp_sts rc=%d\n", rc);
144 return rc;
145 }
146
147 if (exp_sts == 0 || !(--tries))
148 break;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700149 }
150
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700151 if (!tries)
152 pr_err("Failed to clear the error? hw_sts: %x exp_sts: %d\n",
153 hw_sts, exp_sts);
154
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700155 rc = fg_masked_write(chip, MEM_IF_IMA_CFG(chip), IACS_CLR_BIT, 0);
156 if (rc < 0) {
157 pr_err("failed to write 0x%04x, rc=%d\n", MEM_IF_IMA_CFG(chip),
158 rc);
159 return rc;
160 }
161
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700162 udelay(5);
163
164 rc = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip),
165 MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT, 0);
166 if (rc < 0) {
167 pr_err("failed to write to 0x%04x, rc=%d\n",
168 MEM_IF_MEM_INTF_CFG(chip), rc);
169 return rc;
170 }
171
172 /* Delay before next transaction is attempted */
173 usleep_range(35, 40);
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700174 fg_dbg(chip, FG_SRAM_READ | FG_SRAM_WRITE, "IACS clear sequence complete\n");
175 return rc;
176}
177
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700178int fg_clear_dma_errors_if_any(struct fg_chip *chip)
179{
180 int rc;
181 u8 dma_sts;
Subbaraman Narayanamurthy3f3040a2017-03-14 20:30:47 -0700182 bool error_present;
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700183
184 rc = fg_read(chip, MEM_IF_DMA_STS(chip), &dma_sts, 1);
185 if (rc < 0) {
186 pr_err("failed to read addr=0x%04x, rc=%d\n",
187 MEM_IF_DMA_STS(chip), rc);
188 return rc;
189 }
190 fg_dbg(chip, FG_STATUS, "dma_sts: %x\n", dma_sts);
191
Subbaraman Narayanamurthy3f3040a2017-03-14 20:30:47 -0700192 error_present = dma_sts & (DMA_WRITE_ERROR_BIT | DMA_READ_ERROR_BIT);
193 rc = fg_masked_write(chip, MEM_IF_DMA_CTL(chip), DMA_CLEAR_LOG_BIT,
194 error_present ? DMA_CLEAR_LOG_BIT : 0);
195 if (rc < 0) {
196 pr_err("failed to write addr=0x%04x, rc=%d\n",
197 MEM_IF_DMA_CTL(chip), rc);
198 return rc;
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700199 }
200
201 return 0;
202}
203
204int fg_clear_ima_errors_if_any(struct fg_chip *chip, bool check_hw_sts)
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700205{
206 int rc = 0;
207 u8 err_sts, exp_sts = 0, hw_sts = 0;
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700208 bool run_err_clr_seq = false;
209
210 rc = fg_read(chip, MEM_IF_IMA_EXP_STS(chip), &exp_sts, 1);
211 if (rc < 0) {
212 pr_err("failed to read ima_exp_sts rc=%d\n", rc);
213 return rc;
214 }
215
216 rc = fg_read(chip, MEM_IF_IMA_HW_STS(chip), &hw_sts, 1);
217 if (rc < 0) {
218 pr_err("failed to read ima_hw_sts rc=%d\n", rc);
219 return rc;
220 }
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700221
222 rc = fg_read(chip, MEM_IF_IMA_ERR_STS(chip), &err_sts, 1);
223 if (rc < 0) {
224 pr_err("failed to read ima_err_sts rc=%d\n", rc);
225 return rc;
226 }
227
Subbaraman Narayanamurthy03e6c612016-11-09 16:40:27 -0800228 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 -0700229 err_sts, exp_sts, hw_sts);
230
231 if (check_hw_sts) {
232 /*
233 * Lower nibble should be equal to upper nibble before SRAM
234 * transactions begins from SW side. If they are unequal, then
235 * the error clear sequence should be run irrespective of IMA
236 * exception errors.
237 */
238 if ((hw_sts & 0x0F) != hw_sts >> 4) {
239 pr_err("IMA HW not in correct state, hw_sts=%x\n",
240 hw_sts);
241 run_err_clr_seq = true;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700242 }
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700243 }
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700244
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700245 if (exp_sts & (IACS_ERR_BIT | XCT_TYPE_ERR_BIT | DATA_RD_ERR_BIT |
246 DATA_WR_ERR_BIT | ADDR_BURST_WRAP_BIT | ADDR_STABLE_ERR_BIT)) {
247 pr_err("IMA exception bit set, exp_sts=%x\n", exp_sts);
248 run_err_clr_seq = true;
249 }
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700250
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700251 if (run_err_clr_seq) {
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700252 /* clear the error */
253 rc = fg_run_iacs_clear_sequence(chip);
254 if (rc < 0) {
255 pr_err("failed to run iacs clear sequence rc=%d\n", rc);
256 return rc;
257 }
258
259 /* Retry again as there was an error in the transaction */
260 return -EAGAIN;
261 }
262
263 return rc;
264}
265
266static int fg_check_iacs_ready(struct fg_chip *chip)
267{
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700268 int rc = 0, tries = 250;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700269 u8 ima_opr_sts = 0;
270
271 /*
272 * Additional delay to make sure IACS ready bit is set after
273 * Read/Write operation.
274 */
275
276 usleep_range(30, 35);
277 while (1) {
278 rc = fg_read(chip, MEM_IF_IMA_OPR_STS(chip), &ima_opr_sts, 1);
279 if (rc < 0) {
280 pr_err("failed to read 0x%04x, rc=%d\n",
281 MEM_IF_IMA_OPR_STS(chip), rc);
282 return rc;
283 }
284
285 if (ima_opr_sts & IACS_RDY_BIT)
286 break;
287
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700288 if (!(--tries))
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700289 break;
290
291 /* delay for iacs_ready to be asserted */
292 usleep_range(5000, 7000);
293 }
294
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700295 if (!tries) {
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800296 pr_err("IACS_RDY not set, opr_sts: %d\n", ima_opr_sts);
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700297 /* check for error condition */
298 rc = fg_clear_ima_errors_if_any(chip, false);
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700299 if (rc < 0) {
Subbaraman Narayanamurthy1dece462017-03-23 11:06:08 -0700300 if (rc != -EAGAIN)
301 pr_err("Failed to check for ima errors rc=%d\n",
302 rc);
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700303 return rc;
304 }
305
306 return -EBUSY;
307 }
308
309 return 0;
310}
311
312static int __fg_interleaved_mem_write(struct fg_chip *chip, u16 address,
313 int offset, u8 *val, int len)
314{
315 int rc = 0, i;
316 u8 *ptr = val, byte_enable = 0, num_bytes = 0;
317
318 fg_dbg(chip, FG_SRAM_WRITE, "length %d addr=%02X offset=%d\n", len,
319 address, offset);
320
321 while (len > 0) {
322 num_bytes = (offset + len) > BYTES_PER_SRAM_WORD ?
323 (BYTES_PER_SRAM_WORD - offset) : len;
324
325 /* write to byte_enable */
326 for (i = offset; i < (offset + num_bytes); i++)
327 byte_enable |= BIT(i);
328
329 rc = fg_write(chip, MEM_IF_IMA_BYTE_EN(chip), &byte_enable, 1);
330 if (rc < 0) {
331 pr_err("Unable to write to byte_en_reg rc=%d\n",
332 rc);
333 return rc;
334 }
335
336 /* write data */
337 rc = fg_write(chip, MEM_IF_WR_DATA0(chip) + offset, ptr,
338 num_bytes);
339 if (rc < 0) {
340 pr_err("failed to write to 0x%04x, rc=%d\n",
341 MEM_IF_WR_DATA0(chip) + offset, rc);
342 return rc;
343 }
344
345 /*
346 * The last-byte WR_DATA3 starts the write transaction.
347 * Write a dummy value to WR_DATA3 if it does not have
348 * valid data. This dummy data is not written to the
349 * SRAM as byte_en for WR_DATA3 is not set.
350 */
351 if (!(byte_enable & BIT(3))) {
352 u8 dummy_byte = 0x0;
353
354 rc = fg_write(chip, MEM_IF_WR_DATA3(chip), &dummy_byte,
355 1);
356 if (rc < 0) {
357 pr_err("failed to write dummy-data to WR_DATA3 rc=%d\n",
358 rc);
359 return rc;
360 }
361 }
362
363 /* check for error condition */
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700364 rc = fg_clear_ima_errors_if_any(chip, false);
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700365 if (rc < 0) {
Subbaraman Narayanamurthy1dece462017-03-23 11:06:08 -0700366 if (rc == -EAGAIN)
367 pr_err("IMA error cleared, address [%d %d] len %d\n",
368 address, offset, len);
369 else
370 pr_err("Failed to check for ima errors rc=%d\n",
371 rc);
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700372 return rc;
373 }
374
375 ptr += num_bytes;
376 len -= num_bytes;
377 offset = byte_enable = 0;
378
Subbaraman Narayanamurthy1dece462017-03-23 11:06:08 -0700379 if (chip->use_ima_single_mode && len) {
380 address++;
381 rc = fg_set_address(chip, address);
382 if (rc < 0) {
383 pr_err("failed to set address rc = %d\n", rc);
384 return rc;
385 }
386 }
387
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700388 rc = fg_check_iacs_ready(chip);
389 if (rc < 0) {
390 pr_debug("IACS_RDY failed rc=%d\n", rc);
391 return rc;
392 }
393 }
394
395 return rc;
396}
397
398static int __fg_interleaved_mem_read(struct fg_chip *chip, u16 address,
399 int offset, u8 *val, int len)
400{
401 int rc = 0, total_len;
402 u8 *rd_data = val, num_bytes;
403 char str[DEBUG_PRINT_BUFFER_SIZE];
404
405 fg_dbg(chip, FG_SRAM_READ, "length %d addr=%02X\n", len, address);
406
407 total_len = len;
408 while (len > 0) {
409 num_bytes = (offset + len) > BYTES_PER_SRAM_WORD ?
410 (BYTES_PER_SRAM_WORD - offset) : len;
411 rc = fg_read(chip, MEM_IF_RD_DATA0(chip) + offset, rd_data,
412 num_bytes);
413 if (rc < 0) {
414 pr_err("failed to read 0x%04x, rc=%d\n",
415 MEM_IF_RD_DATA0(chip) + offset, rc);
416 return rc;
417 }
418
419 rd_data += num_bytes;
420 len -= num_bytes;
421 offset = 0;
422
423 /* check for error condition */
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -0700424 rc = fg_clear_ima_errors_if_any(chip, false);
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700425 if (rc < 0) {
Subbaraman Narayanamurthy1dece462017-03-23 11:06:08 -0700426 if (rc == -EAGAIN)
427 pr_err("IMA error cleared, address [%d %d] len %d\n",
428 address, offset, len);
429 else
430 pr_err("Failed to check for ima errors rc=%d\n",
431 rc);
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700432 return rc;
433 }
434
Subbaraman Narayanamurthy1dece462017-03-23 11:06:08 -0700435 if (chip->use_ima_single_mode) {
436 if (len) {
437 address++;
438 rc = fg_set_address(chip, address);
439 if (rc < 0) {
440 pr_err("failed to set address rc = %d\n",
441 rc);
442 return rc;
443 }
444 }
445 } else {
446 if (len && len < BYTES_PER_SRAM_WORD) {
447 /*
448 * Move to single mode. Changing address is not
449 * required here as it must be in burst mode.
450 * Address will get incremented internally by FG
451 * HW once the MSB of RD_DATA is read.
452 */
453 rc = fg_config_access_mode(chip, FG_READ,
454 false);
455 if (rc < 0) {
456 pr_err("failed to move to single mode rc=%d\n",
457 rc);
458 return -EIO;
459 }
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700460 }
461 }
462
463 rc = fg_check_iacs_ready(chip);
464 if (rc < 0) {
465 pr_debug("IACS_RDY failed rc=%d\n", rc);
466 return rc;
467 }
468 }
469
470 if (*chip->debug_mask & FG_SRAM_READ) {
471 fill_string(str, DEBUG_PRINT_BUFFER_SIZE, val, total_len);
472 pr_info("data read: %s\n", str);
473 }
474
475 return rc;
476}
477
478static int fg_get_mem_access_status(struct fg_chip *chip, bool *status)
479{
480 int rc;
481 u8 mem_if_sts;
482
483 rc = fg_read(chip, MEM_IF_MEM_INTF_CFG(chip), &mem_if_sts, 1);
484 if (rc < 0) {
485 pr_err("failed to read rif_mem status rc=%d\n", rc);
486 return rc;
487 }
488
489 *status = mem_if_sts & MEM_ACCESS_REQ_BIT;
490 return 0;
491}
492
493static bool is_mem_access_available(struct fg_chip *chip, int access)
494{
495 bool rif_mem_sts = true;
496 int rc, time_count = 0;
497
498 while (1) {
499 rc = fg_get_mem_access_status(chip, &rif_mem_sts);
500 if (rc < 0)
501 return rc;
502
503 /* This is an inverting logic */
504 if (!rif_mem_sts)
505 break;
506
507 fg_dbg(chip, FG_SRAM_READ | FG_SRAM_WRITE, "MEM_ACCESS_REQ is not clear yet for IMA_%s\n",
508 access ? "write" : "read");
509
510 /*
511 * Try this no more than 4 times. If MEM_ACCESS_REQ is not
512 * clear, then return an error instead of waiting for it again.
513 */
514 if (time_count > 4) {
515 pr_err("Tried 4 times(~16ms) polling MEM_ACCESS_REQ\n");
516 return false;
517 }
518
519 /* Wait for 4ms before reading MEM_ACCESS_REQ again */
520 usleep_range(4000, 4100);
521 time_count++;
522 }
523 return true;
524}
525
526static int fg_interleaved_mem_config(struct fg_chip *chip, u8 *val,
527 u16 address, int offset, int len, bool access)
528{
529 int rc = 0;
Subbaraman Narayanamurthy1dece462017-03-23 11:06:08 -0700530 bool burst_mode = false;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700531
532 if (!is_mem_access_available(chip, access))
533 return -EBUSY;
534
535 /* configure for IMA access */
536 rc = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip),
537 MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT,
538 MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT);
539 if (rc < 0) {
540 pr_err("failed to set ima_req_access bit rc=%d\n", rc);
541 return rc;
542 }
543
544 /* configure for the read/write, single/burst mode */
Subbaraman Narayanamurthy1dece462017-03-23 11:06:08 -0700545 burst_mode = chip->use_ima_single_mode ? false : ((offset + len) > 4);
546 rc = fg_config_access_mode(chip, access, burst_mode);
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700547 if (rc < 0) {
548 pr_err("failed to set memory access rc = %d\n", rc);
549 return rc;
550 }
551
552 rc = fg_check_iacs_ready(chip);
553 if (rc < 0) {
554 pr_err_ratelimited("IACS_RDY failed rc=%d\n", rc);
555 return rc;
556 }
557
558 rc = fg_set_address(chip, address);
559 if (rc < 0) {
560 pr_err("failed to set address rc = %d\n", rc);
561 return rc;
562 }
563
564 if (access == FG_READ) {
565 rc = fg_check_iacs_ready(chip);
566 if (rc < 0) {
567 pr_debug("IACS_RDY failed rc=%d\n", rc);
568 return rc;
569 }
570 }
571
572 return rc;
573}
574
575static int fg_get_beat_count(struct fg_chip *chip, u8 *count)
576{
577 int rc;
578
579 rc = fg_read(chip, MEM_IF_FG_BEAT_COUNT(chip), count, 1);
580 *count &= BEAT_COUNT_MASK;
581 return rc;
582}
583
584int fg_interleaved_mem_read(struct fg_chip *chip, u16 address, u8 offset,
585 u8 *val, int len)
586{
Subbaraman Narayanamurthy95450d62017-01-18 20:10:51 -0800587 int rc = 0, ret;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700588 u8 start_beat_count, end_beat_count, count = 0;
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800589 bool retry = false;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700590
591 if (offset > 3) {
592 pr_err("offset too large %d\n", offset);
593 return -EINVAL;
594 }
595
596retry:
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800597 if (count >= RETRY_COUNT) {
598 pr_err("Tried %d times\n", RETRY_COUNT);
599 retry = false;
600 goto out;
601 }
602
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700603 rc = fg_interleaved_mem_config(chip, val, address, offset, len,
604 FG_READ);
605 if (rc < 0) {
606 pr_err("failed to configure SRAM for IMA rc = %d\n", rc);
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800607 count++;
608 retry = true;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700609 goto out;
610 }
611
612 /* read the start beat count */
613 rc = fg_get_beat_count(chip, &start_beat_count);
614 if (rc < 0) {
615 pr_err("failed to read beat count rc=%d\n", rc);
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800616 count++;
617 retry = true;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700618 goto out;
619 }
620
621 /* read data */
622 rc = __fg_interleaved_mem_read(chip, address, offset, val, len);
623 if (rc < 0) {
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800624 count++;
625 if (rc == -EAGAIN) {
Subbaraman Narayanamurthy1dece462017-03-23 11:06:08 -0700626 pr_err("IMA read failed retry_count = %d\n", count);
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700627 goto retry;
628 }
629 pr_err("failed to read SRAM address rc = %d\n", rc);
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800630 retry = true;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700631 goto out;
632 }
633
634 /* read the end beat count */
635 rc = fg_get_beat_count(chip, &end_beat_count);
636 if (rc < 0) {
637 pr_err("failed to read beat count rc=%d\n", rc);
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800638 count++;
639 retry = true;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700640 goto out;
641 }
642
643 fg_dbg(chip, FG_SRAM_READ, "Start beat_count = %x End beat_count = %x\n",
644 start_beat_count, end_beat_count);
645
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800646 if (start_beat_count != end_beat_count) {
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700647 fg_dbg(chip, FG_SRAM_READ, "Beat count(%d/%d) do not match - retry transaction\n",
648 start_beat_count, end_beat_count);
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800649 count++;
650 retry = true;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700651 }
652out:
653 /* Release IMA access */
Subbaraman Narayanamurthy95450d62017-01-18 20:10:51 -0800654 ret = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip),
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700655 MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT, 0);
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800656 if (rc < 0 && ret < 0) {
Subbaraman Narayanamurthy95450d62017-01-18 20:10:51 -0800657 pr_err("failed to reset IMA access bit ret = %d\n", ret);
658 return ret;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700659 }
660
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800661 if (retry) {
662 retry = false;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700663 goto retry;
Subbaraman Narayanamurthycd0a9b22016-09-14 19:20:24 -0700664 }
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700665
666 return rc;
667}
668
669int fg_interleaved_mem_write(struct fg_chip *chip, u16 address, u8 offset,
670 u8 *val, int len, bool atomic_access)
671{
Subbaraman Narayanamurthy95450d62017-01-18 20:10:51 -0800672 int rc = 0, ret;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700673 u8 start_beat_count, end_beat_count, count = 0;
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800674 bool retry = false;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700675
676 if (offset > 3) {
677 pr_err("offset too large %d\n", offset);
678 return -EINVAL;
679 }
680
681retry:
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800682 if (count >= RETRY_COUNT) {
683 pr_err("Tried %d times\n", RETRY_COUNT);
684 retry = false;
685 goto out;
686 }
687
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700688 rc = fg_interleaved_mem_config(chip, val, address, offset, len,
689 FG_WRITE);
690 if (rc < 0) {
691 pr_err("failed to configure SRAM for IMA rc = %d\n", rc);
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800692 count++;
693 retry = true;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700694 goto out;
695 }
696
697 /* read the start beat count */
698 rc = fg_get_beat_count(chip, &start_beat_count);
699 if (rc < 0) {
700 pr_err("failed to read beat count rc=%d\n", rc);
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800701 count++;
702 retry = true;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700703 goto out;
704 }
705
706 /* write data */
707 rc = __fg_interleaved_mem_write(chip, address, offset, val, len);
708 if (rc < 0) {
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800709 count++;
Subbaraman Narayanamurthy1dece462017-03-23 11:06:08 -0700710 if (rc == -EAGAIN) {
711 pr_err("IMA write failed retry_count = %d\n", count);
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700712 goto retry;
713 }
714 pr_err("failed to write SRAM address rc = %d\n", rc);
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800715 retry = true;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700716 goto out;
717 }
718
719 /* read the end beat count */
720 rc = fg_get_beat_count(chip, &end_beat_count);
721 if (rc < 0) {
722 pr_err("failed to read beat count rc=%d\n", rc);
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800723 count++;
724 retry = true;
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700725 goto out;
726 }
727
728 if (atomic_access && start_beat_count != end_beat_count)
729 pr_err("Start beat_count = %x End beat_count = %x\n",
730 start_beat_count, end_beat_count);
731out:
732 /* Release IMA access */
Subbaraman Narayanamurthy95450d62017-01-18 20:10:51 -0800733 ret = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip),
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700734 MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT, 0);
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800735 if (rc < 0 && ret < 0) {
Subbaraman Narayanamurthy95450d62017-01-18 20:10:51 -0800736 pr_err("failed to reset IMA access bit ret = %d\n", ret);
737 return ret;
738 }
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700739
Subbaraman Narayanamurthyae899e22017-01-20 18:26:25 -0800740 if (retry) {
741 retry = false;
742 goto retry;
743 }
744
Subbaraman Narayanamurthy95450d62017-01-18 20:10:51 -0800745 /* Return the error we got before releasing memory access */
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -0700746 return rc;
747}
748
Subbaraman Narayanamurthy2d62e9e2017-06-02 17:40:28 -0700749#define MEM_GRANT_WAIT_MS 200
750static int fg_direct_mem_request(struct fg_chip *chip, bool request)
751{
752 int rc, ret;
753 u8 val, mask;
754 bool tried_again = false;
755
756 if (request)
757 reinit_completion(&chip->mem_grant);
758
759 mask = MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT;
760 val = request ? MEM_ACCESS_REQ_BIT : 0;
761 rc = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip), mask, val);
762 if (rc < 0) {
763 pr_err("failed to configure mem_if_mem_intf_cfg rc=%d\n", rc);
764 return rc;
765 }
766
767 mask = MEM_ARB_LO_LATENCY_EN_BIT | MEM_ARB_REQ_BIT;
768 val = request ? mask : 0;
769 rc = fg_masked_write(chip, MEM_IF_MEM_ARB_CFG(chip), mask, val);
770 if (rc < 0) {
771 pr_err("failed to configure mem_if_mem_arb_cfg rc:%d\n", rc);
772 return rc;
773 }
774
775 if (request)
776 pr_debug("requesting access\n");
777 else
778 pr_debug("releasing access\n");
779
780 if (!request)
781 return 0;
782
783wait:
784 ret = wait_for_completion_interruptible_timeout(
785 &chip->mem_grant, msecs_to_jiffies(MEM_GRANT_WAIT_MS));
786 /* If we were interrupted wait again one more time. */
787 if (ret <= 0) {
788 if ((ret == -ERESTARTSYS || ret == 0) && !tried_again) {
789 pr_debug("trying again, ret=%d\n", ret);
790 tried_again = true;
791 goto wait;
792 } else {
793 pr_err("wait for mem_grant timed out ret=%d\n",
794 ret);
795 }
796 }
797
798 if (ret <= 0) {
799 val = 0;
800 mask = MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT;
801 rc = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip), mask,
802 val);
803 if (rc < 0) {
804 pr_err("failed to configure mem_if_mem_intf_cfg rc=%d\n",
805 rc);
806 return rc;
807 }
808
809 mask = MEM_ARB_LO_LATENCY_EN_BIT | MEM_ARB_REQ_BIT;
810 rc = fg_masked_write(chip, MEM_IF_MEM_ARB_CFG(chip), mask,
811 val);
812 if (rc < 0) {
813 pr_err("failed to configure mem_if_mem_arb_cfg rc:%d\n",
814 rc);
815 return rc;
816 }
817
818 return -ETIMEDOUT;
819 }
820
821 return rc;
822}
823
824static int fg_get_dma_address(struct fg_chip *chip, u16 sram_addr, u8 offset,
825 u16 *addr)
826{
827 int i;
828 u16 start_sram_addr, end_sram_addr;
829
830 for (i = 0; i < NUM_PARTITIONS; i++) {
831 start_sram_addr = chip->addr_map[i].partition_start;
832 end_sram_addr = chip->addr_map[i].partition_end;
833 if (sram_addr >= start_sram_addr &&
834 sram_addr <= end_sram_addr) {
835 *addr = chip->addr_map[i].spmi_addr_base + offset +
836 (sram_addr - start_sram_addr) *
837 BYTES_PER_SRAM_WORD;
838 return 0;
839 }
840 }
841
842 pr_err("Couldn't find address for %d from address map\n", sram_addr);
843 return -ENXIO;
844}
845
846static int fg_get_partition_count(struct fg_chip *chip, u16 sram_addr, int len,
847 int *count)
848{
849 int i, num = 0;
850 u16 end_addr, last_addr = 0;
851
852 end_addr = sram_addr + len / BYTES_PER_SRAM_WORD;
853 if (!(len % BYTES_PER_SRAM_WORD))
854 end_addr -= 1;
855
856 if (sram_addr == end_addr) {
857 *count = 1;
858 return 0;
859 }
860
861 for (i = 0; i < NUM_PARTITIONS; i++) {
862 pr_debug("address: %d last_addr: %d\n", sram_addr, last_addr);
863 if (sram_addr >= chip->addr_map[i].partition_start
864 && sram_addr <= chip->addr_map[i].partition_end
865 && last_addr < end_addr) {
866 num++;
867 last_addr = chip->addr_map[i].partition_end;
868 sram_addr = chip->addr_map[i+1].partition_start;
869 }
870 }
871
872 if (num > 0) {
873 *count = num;
874 return 0;
875 }
876
877 pr_err("Couldn't find number of partitions for address %d\n",
878 sram_addr);
879 return -ENXIO;
880}
881
882static int fg_get_partition_avail_bytes(struct fg_chip *chip, u16 sram_addr,
883 int len, int *rem_len)
884{
885 int i, part_len = 0, temp;
886 u16 end_addr;
887
888 for (i = 0; i < NUM_PARTITIONS; i++) {
889 if (sram_addr >= chip->addr_map[i].partition_start
890 && sram_addr <= chip->addr_map[i].partition_end) {
891 part_len = (chip->addr_map[i].partition_end -
892 chip->addr_map[i].partition_start + 1);
893 part_len *= BYTES_PER_SRAM_WORD;
894 end_addr = chip->addr_map[i].partition_end;
895 break;
896 }
897 }
898
899 if (part_len <= 0) {
900 pr_err("Bad address? total_len=%d\n", part_len);
901 return -ENXIO;
902 }
903
904 temp = (end_addr - sram_addr + 1) * BYTES_PER_SRAM_WORD;
905 if (temp > part_len || !temp) {
906 pr_err("Bad length=%d\n", temp);
907 return -ENXIO;
908 }
909
910 *rem_len = temp;
911 pr_debug("address %d len %d rem_len %d\n", sram_addr, len, *rem_len);
912 return 0;
913}
914
915static int __fg_direct_mem_rw(struct fg_chip *chip, u16 sram_addr, u8 offset,
916 u8 *val, int len, bool access)
917{
918 int rc, ret, num_partitions, num_bytes = 0;
919 u16 addr;
920 u8 *ptr = val;
921 char *temp_str;
922
923 if (offset > 3) {
924 pr_err("offset too large %d\n", offset);
925 return -EINVAL;
926 }
927
928 rc = fg_get_partition_count(chip, sram_addr, len, &num_partitions);
929 if (rc < 0)
930 return rc;
931
932 pr_debug("number of partitions: %d\n", num_partitions);
933
934 rc = fg_direct_mem_request(chip, true);
935 if (rc < 0) {
936 pr_err("Error in requesting direct_mem access rc=%d\n", rc);
937 return rc;
938 }
939
940 while (num_partitions-- && len) {
941 rc = fg_get_dma_address(chip, sram_addr, offset, &addr);
942 if (rc < 0) {
943 pr_err("Incorrect address %d/offset %d\n", sram_addr,
944 offset);
945 break;
946 }
947
948 rc = fg_get_partition_avail_bytes(chip, sram_addr + offset, len,
949 &num_bytes);
950 if (rc < 0)
951 break;
952
953 if (num_bytes > len)
954 num_bytes = len;
955
956 pr_debug("reading from address: [%d %d] dma_address = %x\n",
957 sram_addr, offset, addr);
958
959 if (access == FG_READ) {
960 rc = fg_read(chip, addr, ptr, num_bytes);
961 temp_str = "read";
962 } else {
963 rc = fg_write(chip, addr, ptr, num_bytes);
964 temp_str = "write";
965 }
966
967 if (rc < 0) {
968 pr_err("Error in %sing address %d rc=%d\n", temp_str,
969 sram_addr, rc);
970 break;
971 }
972
973 ptr += num_bytes;
974 len -= num_bytes;
975 sram_addr += (num_bytes / BYTES_PER_SRAM_WORD);
976 offset = 0;
977 }
978
979 ret = fg_direct_mem_request(chip, false);
980 if (ret < 0) {
981 pr_err("Error in releasing direct_mem access rc=%d\n", rc);
982 return ret;
983 }
984
985 return rc;
986}
987
988int fg_direct_mem_read(struct fg_chip *chip, u16 sram_addr, u8 offset,
989 u8 *val, int len)
990{
991 return __fg_direct_mem_rw(chip, sram_addr, offset, val, len, FG_READ);
992}
993
994int fg_direct_mem_write(struct fg_chip *chip, u16 sram_addr, u8 offset,
995 u8 *val, int len, bool atomic_access)
996{
997 return __fg_direct_mem_rw(chip, sram_addr, offset, val, len, FG_WRITE);
998}
999
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -07001000int fg_ima_init(struct fg_chip *chip)
1001{
1002 int rc;
1003
1004 /*
1005 * Change the FG_MEM_INT interrupt to track IACS_READY
1006 * condition instead of end-of-transaction. This makes sure
1007 * that the next transaction starts only after the hw is ready.
1008 */
1009 rc = fg_masked_write(chip, MEM_IF_IMA_CFG(chip), IACS_INTR_SRC_SLCT_BIT,
1010 IACS_INTR_SRC_SLCT_BIT);
1011 if (rc < 0) {
1012 pr_err("failed to configure interrupt source %d\n", rc);
1013 return rc;
1014 }
1015
Subbaraman Narayanamurthya71c9dd2016-10-14 19:38:05 -07001016 /* Clear DMA errors if any before clearing IMA errors */
1017 rc = fg_clear_dma_errors_if_any(chip);
1018 if (rc < 0) {
1019 pr_err("Error in checking DMA errors rc:%d\n", rc);
1020 return rc;
1021 }
1022
1023 /* Clear IMA errors if any before SRAM transactions can begin */
1024 rc = fg_clear_ima_errors_if_any(chip, true);
1025 if (rc < 0 && rc != -EAGAIN) {
1026 pr_err("Error in checking IMA errors rc:%d\n", rc);
1027 return rc;
1028 }
1029
Subbaraman Narayanamurthy6accb262016-03-14 16:41:16 -07001030 return 0;
1031}
Subbaraman Narayanamurthy2d62e9e2017-06-02 17:40:28 -07001032
1033/*
1034 * This SRAM partition to DMA address partition mapping remains identical for
1035 * PMICs that use GEN3 FG.
1036 */
1037static struct fg_dma_address fg_gen3_addr_map[NUM_PARTITIONS] = {
1038 /* system partition */
1039 {
1040 .partition_start = 0,
1041 .partition_end = 23,
1042 .spmi_addr_base = FG_DMA0_BASE + SRAM_ADDR_OFFSET,
1043 },
1044 /* battery profile partition */
1045 {
1046 .partition_start = 24,
1047 .partition_end = 79,
1048 .spmi_addr_base = FG_DMA1_BASE + SRAM_ADDR_OFFSET,
1049 },
1050 /* scratch pad partition */
1051 {
1052 .partition_start = 80,
1053 .partition_end = 125,
1054 .spmi_addr_base = FG_DMA2_BASE + SRAM_ADDR_OFFSET,
1055 },
1056};
1057int fg_dma_init(struct fg_chip *chip)
1058{
1059 int rc;
1060
1061 chip->addr_map = fg_gen3_addr_map;
1062
1063 /* Clear DMA errors if any before clearing IMA errors */
1064 rc = fg_clear_dma_errors_if_any(chip);
1065 if (rc < 0) {
1066 pr_err("Error in checking DMA errors rc:%d\n", rc);
1067 return rc;
1068 }
1069
1070 /* Configure the DMA peripheral addressing to partition */
1071 rc = fg_masked_write(chip, MEM_IF_DMA_CTL(chip), ADDR_KIND_BIT,
1072 ADDR_KIND_BIT);
1073 if (rc < 0) {
1074 pr_err("failed to configure DMA_CTL rc:%d\n", rc);
1075 return rc;
1076 }
1077
1078 /* Release the DMA initially so that request can happen */
1079 rc = fg_direct_mem_request(chip, false);
1080 if (rc < 0) {
1081 pr_err("Error in releasing direct_mem access rc=%d\n",
1082 rc);
1083 return rc;
1084 }
1085
1086 return 0;
1087}