diff options
author | Nicholas Troast <ntroast@codeaurora.org> | 2017-01-10 09:56:57 -0800 |
---|---|---|
committer | Nicholas Troast <ntroast@codeaurora.org> | 2017-01-17 12:21:07 -0800 |
commit | d4b9ff94dff74035e465eb341036b79e30ac3d14 (patch) | |
tree | 98db6ac604de4b255d7aeaefca29753d349f7855 /drivers/power/qcom-charger/fg-memif.c | |
parent | cbd28f4381c058201f645427771f3205b641bb4b (diff) |
power: align qcom drivers with msm-4.9 kernel
The power directory structure has changed in kernel version 4.9. Align
msm-4.4 with this new directory structure.
Change-Id: Iba729f8ef33245ea78cdc05276ba8f5593191509
Signed-off-by: Nicholas Troast <ntroast@codeaurora.org>
Diffstat (limited to 'drivers/power/qcom-charger/fg-memif.c')
-rw-r--r-- | drivers/power/qcom-charger/fg-memif.c | 704 |
1 files changed, 0 insertions, 704 deletions
diff --git a/drivers/power/qcom-charger/fg-memif.c b/drivers/power/qcom-charger/fg-memif.c deleted file mode 100644 index a98ff7d765e3..000000000000 --- a/drivers/power/qcom-charger/fg-memif.c +++ /dev/null @@ -1,704 +0,0 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#define pr_fmt(fmt) "FG: %s: " fmt, __func__ - -#include "fg-core.h" -#include "fg-reg.h" - -/* Generic definitions */ -#define RETRY_COUNT 3 -#define BYTES_PER_SRAM_WORD 4 - -enum { - FG_READ = 0, - FG_WRITE, -}; - -static int fg_set_address(struct fg_chip *chip, u16 address) -{ - u8 buffer[2]; - int rc; - - buffer[0] = address & 0xFF; - /* MSB has to be written zero */ - buffer[1] = 0; - - rc = fg_write(chip, MEM_IF_ADDR_LSB(chip), buffer, 2); - if (rc < 0) { - pr_err("failed to write to 0x%04X, rc=%d\n", - MEM_IF_ADDR_LSB(chip), rc); - return rc; - } - - return rc; -} - -static int fg_config_access_mode(struct fg_chip *chip, bool access, bool burst) -{ - int rc; - u8 intf_ctl = 0; - - intf_ctl = ((access == FG_WRITE) ? IMA_WR_EN_BIT : 0) | - (burst ? MEM_ACS_BURST_BIT : 0); - - rc = fg_masked_write(chip, MEM_IF_IMA_CTL(chip), IMA_CTL_MASK, - intf_ctl); - if (rc < 0) { - pr_err("failed to write to 0x%04x, rc=%d\n", - MEM_IF_IMA_CTL(chip), rc); - return -EIO; - } - - return rc; -} - -static int fg_run_iacs_clear_sequence(struct fg_chip *chip) -{ - u8 val, hw_sts, exp_sts; - int rc, tries = 250; - - /* - * Values to write for running IACS clear sequence comes from - * hardware documentation. - */ - rc = fg_masked_write(chip, MEM_IF_IMA_CFG(chip), - IACS_CLR_BIT | STATIC_CLK_EN_BIT, - IACS_CLR_BIT | STATIC_CLK_EN_BIT); - if (rc < 0) { - pr_err("failed to write 0x%04x, rc=%d\n", MEM_IF_IMA_CFG(chip), - rc); - return rc; - } - - rc = fg_config_access_mode(chip, FG_READ, false); - if (rc < 0) { - pr_err("failed to write to 0x%04x, rc=%d\n", - MEM_IF_IMA_CTL(chip), rc); - return rc; - } - - rc = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip), - MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT, - MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT); - if (rc < 0) { - pr_err("failed to set ima_req_access bit rc=%d\n", rc); - return rc; - } - - /* Delay for the clock to reach FG */ - usleep_range(35, 40); - - while (1) { - val = 0; - rc = fg_write(chip, MEM_IF_ADDR_MSB(chip), &val, 1); - if (rc < 0) { - pr_err("failed to write 0x%04x, rc=%d\n", - MEM_IF_ADDR_MSB(chip), rc); - return rc; - } - - val = 0; - rc = fg_write(chip, MEM_IF_WR_DATA3(chip), &val, 1); - if (rc < 0) { - pr_err("failed to write 0x%04x, rc=%d\n", - MEM_IF_WR_DATA3(chip), rc); - return rc; - } - - rc = fg_read(chip, MEM_IF_RD_DATA3(chip), &val, 1); - if (rc < 0) { - pr_err("failed to read 0x%04x, rc=%d\n", - MEM_IF_RD_DATA3(chip), rc); - return rc; - } - - /* Delay for IMA hardware to clear */ - usleep_range(35, 40); - - rc = fg_read(chip, MEM_IF_IMA_HW_STS(chip), &hw_sts, 1); - if (rc < 0) { - pr_err("failed to read ima_hw_sts rc=%d\n", rc); - return rc; - } - - if (hw_sts != 0) - continue; - - rc = fg_read(chip, MEM_IF_IMA_EXP_STS(chip), &exp_sts, 1); - if (rc < 0) { - pr_err("failed to read ima_exp_sts rc=%d\n", rc); - return rc; - } - - if (exp_sts == 0 || !(--tries)) - break; - } - - if (!tries) - pr_err("Failed to clear the error? hw_sts: %x exp_sts: %d\n", - hw_sts, exp_sts); - - rc = fg_masked_write(chip, MEM_IF_IMA_CFG(chip), IACS_CLR_BIT, 0); - if (rc < 0) { - pr_err("failed to write 0x%04x, rc=%d\n", MEM_IF_IMA_CFG(chip), - rc); - return rc; - } - - udelay(5); - - rc = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip), - MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT, 0); - if (rc < 0) { - pr_err("failed to write to 0x%04x, rc=%d\n", - MEM_IF_MEM_INTF_CFG(chip), rc); - return rc; - } - - /* Delay before next transaction is attempted */ - usleep_range(35, 40); - fg_dbg(chip, FG_SRAM_READ | FG_SRAM_WRITE, "IACS clear sequence complete\n"); - return rc; -} - -int fg_clear_dma_errors_if_any(struct fg_chip *chip) -{ - int rc; - u8 dma_sts; - - rc = fg_read(chip, MEM_IF_DMA_STS(chip), &dma_sts, 1); - if (rc < 0) { - pr_err("failed to read addr=0x%04x, rc=%d\n", - MEM_IF_DMA_STS(chip), rc); - return rc; - } - fg_dbg(chip, FG_STATUS, "dma_sts: %x\n", dma_sts); - - if (dma_sts & (DMA_WRITE_ERROR_BIT | DMA_READ_ERROR_BIT)) { - rc = fg_masked_write(chip, MEM_IF_DMA_CTL(chip), - DMA_CLEAR_LOG_BIT, DMA_CLEAR_LOG_BIT); - if (rc < 0) { - pr_err("failed to write addr=0x%04x, rc=%d\n", - MEM_IF_DMA_CTL(chip), rc); - return rc; - } - } - - return 0; -} - -int fg_clear_ima_errors_if_any(struct fg_chip *chip, bool check_hw_sts) -{ - int rc = 0; - u8 err_sts, exp_sts = 0, hw_sts = 0; - bool run_err_clr_seq = false; - - rc = fg_read(chip, MEM_IF_IMA_EXP_STS(chip), &exp_sts, 1); - if (rc < 0) { - pr_err("failed to read ima_exp_sts rc=%d\n", rc); - return rc; - } - - rc = fg_read(chip, MEM_IF_IMA_HW_STS(chip), &hw_sts, 1); - if (rc < 0) { - pr_err("failed to read ima_hw_sts rc=%d\n", rc); - return rc; - } - - rc = fg_read(chip, MEM_IF_IMA_ERR_STS(chip), &err_sts, 1); - if (rc < 0) { - pr_err("failed to read ima_err_sts rc=%d\n", rc); - return rc; - } - - fg_dbg(chip, FG_SRAM_READ | FG_SRAM_WRITE, "ima_err_sts=%x ima_exp_sts=%x ima_hw_sts=%x\n", - err_sts, exp_sts, hw_sts); - - if (check_hw_sts) { - /* - * Lower nibble should be equal to upper nibble before SRAM - * transactions begins from SW side. If they are unequal, then - * the error clear sequence should be run irrespective of IMA - * exception errors. - */ - if ((hw_sts & 0x0F) != hw_sts >> 4) { - pr_err("IMA HW not in correct state, hw_sts=%x\n", - hw_sts); - run_err_clr_seq = true; - } - } - - if (exp_sts & (IACS_ERR_BIT | XCT_TYPE_ERR_BIT | DATA_RD_ERR_BIT | - DATA_WR_ERR_BIT | ADDR_BURST_WRAP_BIT | ADDR_STABLE_ERR_BIT)) { - pr_err("IMA exception bit set, exp_sts=%x\n", exp_sts); - run_err_clr_seq = true; - } - - if (run_err_clr_seq) { - /* clear the error */ - rc = fg_run_iacs_clear_sequence(chip); - if (rc < 0) { - pr_err("failed to run iacs clear sequence rc=%d\n", rc); - return rc; - } - - /* Retry again as there was an error in the transaction */ - return -EAGAIN; - } - - return rc; -} - -static int fg_check_iacs_ready(struct fg_chip *chip) -{ - int rc = 0, tries = 250; - u8 ima_opr_sts = 0; - - /* - * Additional delay to make sure IACS ready bit is set after - * Read/Write operation. - */ - - usleep_range(30, 35); - while (1) { - rc = fg_read(chip, MEM_IF_IMA_OPR_STS(chip), &ima_opr_sts, 1); - if (rc < 0) { - pr_err("failed to read 0x%04x, rc=%d\n", - MEM_IF_IMA_OPR_STS(chip), rc); - return rc; - } - - if (ima_opr_sts & IACS_RDY_BIT) - break; - - if (!(--tries)) - break; - - /* delay for iacs_ready to be asserted */ - usleep_range(5000, 7000); - } - - if (!tries) { - pr_err("IACS_RDY not set\n"); - /* check for error condition */ - rc = fg_clear_ima_errors_if_any(chip, false); - if (rc < 0) { - pr_err("Failed to check for ima errors rc=%d\n", rc); - return rc; - } - - return -EBUSY; - } - - return 0; -} - -static int __fg_interleaved_mem_write(struct fg_chip *chip, u16 address, - int offset, u8 *val, int len) -{ - int rc = 0, i; - u8 *ptr = val, byte_enable = 0, num_bytes = 0; - - fg_dbg(chip, FG_SRAM_WRITE, "length %d addr=%02X offset=%d\n", len, - address, offset); - - while (len > 0) { - num_bytes = (offset + len) > BYTES_PER_SRAM_WORD ? - (BYTES_PER_SRAM_WORD - offset) : len; - - /* write to byte_enable */ - for (i = offset; i < (offset + num_bytes); i++) - byte_enable |= BIT(i); - - rc = fg_write(chip, MEM_IF_IMA_BYTE_EN(chip), &byte_enable, 1); - if (rc < 0) { - pr_err("Unable to write to byte_en_reg rc=%d\n", - rc); - return rc; - } - - /* write data */ - rc = fg_write(chip, MEM_IF_WR_DATA0(chip) + offset, ptr, - num_bytes); - if (rc < 0) { - pr_err("failed to write to 0x%04x, rc=%d\n", - MEM_IF_WR_DATA0(chip) + offset, rc); - return rc; - } - - /* - * The last-byte WR_DATA3 starts the write transaction. - * Write a dummy value to WR_DATA3 if it does not have - * valid data. This dummy data is not written to the - * SRAM as byte_en for WR_DATA3 is not set. - */ - if (!(byte_enable & BIT(3))) { - u8 dummy_byte = 0x0; - - rc = fg_write(chip, MEM_IF_WR_DATA3(chip), &dummy_byte, - 1); - if (rc < 0) { - pr_err("failed to write dummy-data to WR_DATA3 rc=%d\n", - rc); - return rc; - } - } - - /* check for error condition */ - rc = fg_clear_ima_errors_if_any(chip, false); - if (rc < 0) { - pr_err("Failed to check for ima errors rc=%d\n", rc); - return rc; - } - - ptr += num_bytes; - len -= num_bytes; - offset = byte_enable = 0; - - rc = fg_check_iacs_ready(chip); - if (rc < 0) { - pr_debug("IACS_RDY failed rc=%d\n", rc); - return rc; - } - } - - return rc; -} - -static int __fg_interleaved_mem_read(struct fg_chip *chip, u16 address, - int offset, u8 *val, int len) -{ - int rc = 0, total_len; - u8 *rd_data = val, num_bytes; - char str[DEBUG_PRINT_BUFFER_SIZE]; - - fg_dbg(chip, FG_SRAM_READ, "length %d addr=%02X\n", len, address); - - total_len = len; - while (len > 0) { - num_bytes = (offset + len) > BYTES_PER_SRAM_WORD ? - (BYTES_PER_SRAM_WORD - offset) : len; - rc = fg_read(chip, MEM_IF_RD_DATA0(chip) + offset, rd_data, - num_bytes); - if (rc < 0) { - pr_err("failed to read 0x%04x, rc=%d\n", - MEM_IF_RD_DATA0(chip) + offset, rc); - return rc; - } - - rd_data += num_bytes; - len -= num_bytes; - offset = 0; - - /* check for error condition */ - rc = fg_clear_ima_errors_if_any(chip, false); - if (rc < 0) { - pr_err("Failed to check for ima errors rc=%d\n", rc); - return rc; - } - - if (len && len < BYTES_PER_SRAM_WORD) { - /* - * Move to single mode. Changing address is not - * required here as it must be in burst mode. Address - * will get incremented internally by FG HW once the MSB - * of RD_DATA is read. - */ - rc = fg_config_access_mode(chip, FG_READ, 0); - if (rc < 0) { - pr_err("failed to move to single mode rc=%d\n", - rc); - return -EIO; - } - } - - rc = fg_check_iacs_ready(chip); - if (rc < 0) { - pr_debug("IACS_RDY failed rc=%d\n", rc); - return rc; - } - } - - if (*chip->debug_mask & FG_SRAM_READ) { - fill_string(str, DEBUG_PRINT_BUFFER_SIZE, val, total_len); - pr_info("data read: %s\n", str); - } - - return rc; -} - -static int fg_get_mem_access_status(struct fg_chip *chip, bool *status) -{ - int rc; - u8 mem_if_sts; - - rc = fg_read(chip, MEM_IF_MEM_INTF_CFG(chip), &mem_if_sts, 1); - if (rc < 0) { - pr_err("failed to read rif_mem status rc=%d\n", rc); - return rc; - } - - *status = mem_if_sts & MEM_ACCESS_REQ_BIT; - return 0; -} - -static bool is_mem_access_available(struct fg_chip *chip, int access) -{ - bool rif_mem_sts = true; - int rc, time_count = 0; - - while (1) { - rc = fg_get_mem_access_status(chip, &rif_mem_sts); - if (rc < 0) - return rc; - - /* This is an inverting logic */ - if (!rif_mem_sts) - break; - - fg_dbg(chip, FG_SRAM_READ | FG_SRAM_WRITE, "MEM_ACCESS_REQ is not clear yet for IMA_%s\n", - access ? "write" : "read"); - - /* - * Try this no more than 4 times. If MEM_ACCESS_REQ is not - * clear, then return an error instead of waiting for it again. - */ - if (time_count > 4) { - pr_err("Tried 4 times(~16ms) polling MEM_ACCESS_REQ\n"); - return false; - } - - /* Wait for 4ms before reading MEM_ACCESS_REQ again */ - usleep_range(4000, 4100); - time_count++; - } - return true; -} - -static int fg_interleaved_mem_config(struct fg_chip *chip, u8 *val, - u16 address, int offset, int len, bool access) -{ - int rc = 0; - - if (!is_mem_access_available(chip, access)) - return -EBUSY; - - /* configure for IMA access */ - rc = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip), - MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT, - MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT); - if (rc < 0) { - pr_err("failed to set ima_req_access bit rc=%d\n", rc); - return rc; - } - - /* configure for the read/write, single/burst mode */ - rc = fg_config_access_mode(chip, access, (offset + len) > 4); - if (rc < 0) { - pr_err("failed to set memory access rc = %d\n", rc); - return rc; - } - - rc = fg_check_iacs_ready(chip); - if (rc < 0) { - pr_err_ratelimited("IACS_RDY failed rc=%d\n", rc); - return rc; - } - - rc = fg_set_address(chip, address); - if (rc < 0) { - pr_err("failed to set address rc = %d\n", rc); - return rc; - } - - if (access == FG_READ) { - rc = fg_check_iacs_ready(chip); - if (rc < 0) { - pr_debug("IACS_RDY failed rc=%d\n", rc); - return rc; - } - } - - return rc; -} - -static int fg_get_beat_count(struct fg_chip *chip, u8 *count) -{ - int rc; - - rc = fg_read(chip, MEM_IF_FG_BEAT_COUNT(chip), count, 1); - *count &= BEAT_COUNT_MASK; - return rc; -} - -int fg_interleaved_mem_read(struct fg_chip *chip, u16 address, u8 offset, - u8 *val, int len) -{ - int rc = 0; - u8 start_beat_count, end_beat_count, count = 0; - bool retry_once = false; - - if (offset > 3) { - pr_err("offset too large %d\n", offset); - return -EINVAL; - } - -retry: - rc = fg_interleaved_mem_config(chip, val, address, offset, len, - FG_READ); - if (rc < 0) { - pr_err("failed to configure SRAM for IMA rc = %d\n", rc); - goto out; - } - - /* read the start beat count */ - rc = fg_get_beat_count(chip, &start_beat_count); - if (rc < 0) { - pr_err("failed to read beat count rc=%d\n", rc); - goto out; - } - - /* read data */ - rc = __fg_interleaved_mem_read(chip, address, offset, val, len); - if (rc < 0) { - if ((rc == -EAGAIN) && (count < RETRY_COUNT)) { - count++; - pr_err("IMA access failed retry_count = %d\n", count); - goto retry; - } - pr_err("failed to read SRAM address rc = %d\n", rc); - goto out; - } - - /* read the end beat count */ - rc = fg_get_beat_count(chip, &end_beat_count); - if (rc < 0) { - pr_err("failed to read beat count rc=%d\n", rc); - goto out; - } - - fg_dbg(chip, FG_SRAM_READ, "Start beat_count = %x End beat_count = %x\n", - start_beat_count, end_beat_count); - - if (start_beat_count != end_beat_count && !retry_once) { - fg_dbg(chip, FG_SRAM_READ, "Beat count(%d/%d) do not match - retry transaction\n", - start_beat_count, end_beat_count); - retry_once = true; - } -out: - /* Release IMA access */ - rc = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip), - MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT, 0); - if (rc < 0) { - pr_err("failed to reset IMA access bit rc = %d\n", rc); - return rc; - } - - if (retry_once) { - retry_once = false; - goto retry; - } - - return rc; -} - -int fg_interleaved_mem_write(struct fg_chip *chip, u16 address, u8 offset, - u8 *val, int len, bool atomic_access) -{ - int rc = 0; - u8 start_beat_count, end_beat_count, count = 0; - - if (offset > 3) { - pr_err("offset too large %d\n", offset); - return -EINVAL; - } - -retry: - rc = fg_interleaved_mem_config(chip, val, address, offset, len, - FG_WRITE); - if (rc < 0) { - pr_err("failed to configure SRAM for IMA rc = %d\n", rc); - goto out; - } - - /* read the start beat count */ - rc = fg_get_beat_count(chip, &start_beat_count); - if (rc < 0) { - pr_err("failed to read beat count rc=%d\n", rc); - goto out; - } - - /* write data */ - rc = __fg_interleaved_mem_write(chip, address, offset, val, len); - if (rc < 0) { - if ((rc == -EAGAIN) && (count < RETRY_COUNT)) { - count++; - pr_err("IMA access failed retry_count = %d\n", count); - goto retry; - } - pr_err("failed to write SRAM address rc = %d\n", rc); - goto out; - } - - /* read the end beat count */ - rc = fg_get_beat_count(chip, &end_beat_count); - if (rc < 0) { - pr_err("failed to read beat count rc=%d\n", rc); - goto out; - } - - if (atomic_access && start_beat_count != end_beat_count) - pr_err("Start beat_count = %x End beat_count = %x\n", - start_beat_count, end_beat_count); -out: - /* Release IMA access */ - rc = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip), - MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT, 0); - if (rc < 0) - pr_err("failed to reset IMA access bit rc = %d\n", rc); - - return rc; -} - -int fg_ima_init(struct fg_chip *chip) -{ - int rc; - - /* - * Change the FG_MEM_INT interrupt to track IACS_READY - * condition instead of end-of-transaction. This makes sure - * that the next transaction starts only after the hw is ready. - */ - rc = fg_masked_write(chip, MEM_IF_IMA_CFG(chip), IACS_INTR_SRC_SLCT_BIT, - IACS_INTR_SRC_SLCT_BIT); - if (rc < 0) { - pr_err("failed to configure interrupt source %d\n", rc); - return rc; - } - - /* Clear DMA errors if any before clearing IMA errors */ - rc = fg_clear_dma_errors_if_any(chip); - if (rc < 0) { - pr_err("Error in checking DMA errors rc:%d\n", rc); - return rc; - } - - /* Clear IMA errors if any before SRAM transactions can begin */ - rc = fg_clear_ima_errors_if_any(chip, true); - if (rc < 0 && rc != -EAGAIN) { - pr_err("Error in checking IMA errors rc:%d\n", rc); - return rc; - } - - return 0; -} |