Merge changes I3f3013c5,Icd2bac7f into msm-4.14

* changes:
  defconfig: sdm855: enable GEN4 FG driver
  power: qpnp-fg-gen4: Add GEN4 FG driver
This commit is contained in:
Linux Build Service Account 2018-04-02 14:02:04 -07:00 committed by Gerrit - the friendly Code Review server
commit e40a6ed52a
10 changed files with 3067 additions and 21 deletions

View File

@ -0,0 +1,324 @@
Qualcomm Technologies, Inc. PMIC Fuel Gauge Gen4 Device
QTI PMIC FG Gen4 device provides interface to the clients to read properties
related to the battery. Its main function is to retrieve the State of Charge
(SOC), in percentage scale representing the amount of charge left in the
battery.
=======================
Required Node Structure
=======================
FG Gen4 device must be described in two levels of device nodes. The first
level describes the FG Gen4 device. The second level describes one or more
peripherals managed by FG Gen4 driver. All the peripheral specific parameters
such as base address, interrupts etc., should be under second level node.
====================================
First Level Node - FG Gen4 device
====================================
- compatible
Usage: required
Value type: <string>
Definition: Should be "qcom,fg-gen4".
- qcom,pmic-revid
Usage: required
Value type: <phandle>
Definition: Should specify the phandle of PMIC revid module. This is
used to identify the PMIC subtype.
- qcom,fg-cutoff-voltage
Usage: optional
Value type: <u32>
Definition: The voltage (in mV) where the fuel gauge will steer the SOC
to be zero. For example, if the cutoff voltage is set to
3400mv, the fuel gauge will try to count SoC so that the
battery SOC will be 0 when it is 3400 mV. If this property
is not specified, then the default value used will be
3000 mV.
- qcom,fg-empty-voltage
Usage: optional
Value type: <u32>
Definition: The voltage threshold (in mV) based on which the empty soc
interrupt will be triggered. When the empty soc interrupt
fires, battery soc will be set to 0 and the userspace will
be notified via the power supply framework. The userspace
will read 0% soc and immediately shutdown. If this property
is not specified, then the default value used will be
2812 mV.
- qcom,fg-sys-term-current
Usage: optional
Value type: <u32>
Definition: Battery current (in mA) at which the fuel gauge will try to
scale towards 100%. When the charge current goes above this
the SOC should be at 100%. If this property is not
specified, then the default value used will be -125 mA.
This value has to be specified in negative values for
the charging current.
- qcom,fg-cutoff-current
Usage: optional
Value type: <u32>
Definition: Minimum Battery current (in mA) used for cutoff SOC
estimate. If this property is not specified, then a default
value of 200 mA will be applied.
- qcom,fg-delta-soc-thr
Usage: optional
Value type: <u32>
Definition: Percentage of SOC increase upon which the delta monotonic &
battery SOC interrupts will be triggered. If this property
is not specified, then the default value will be 1.
Possible values are in the range of 0 to 12.
- qcom,fg-esr-timer-chg-fast
Usage: optional
Value type: <prop-encoded-array>
Definition: Number of cycles between ESR pulses while the battery is
charging for fast calibration. Array of 2 elements if
specified.
Element 0 - Retry value for timer
Element 1 - Maximum value for timer
- qcom,fg-esr-timer-dischg-fast
Usage: optional
Value type: <prop-encoded-array>
Definition: Number of cycles between ESR pulses while the battery is
discharging for fast calibration. Array of 2 elements if
specified.
Element 0 - Retry value for timer
Element 1 - Maximum value for timer
- qcom,fg-esr-timer-chg-slow
Usage: optional
Value type: <prop-encoded-array>
Definition: Number of cycles between ESR pulses while the battery is
charging for default calibration. Array of 2 elements if
specified.
Element 0 - Retry value for timer
Element 1 - Maximum value for timer
- qcom,fg-esr-timer-dischg-slow
Usage: optional
Value type: <prop-encoded-array>
Definition: Number of cycles between ESR pulses while the battery is
discharging for default calibration. Array of 2 elements if
specified.
Element 0 - Retry value for timer
Element 1 - Maximum value for timer
- qcom,fg-esr-pulse-thresh-ma
Usage: optional
Value type: <u32>
Definition: ESR pulse qualification threshold in mA. If this is not
specified, a default value of 110 mA will be configured.
Allowed values are from 1 to 1000.
- qcom,fg-esr-meas-curr-ma
Usage: optional
Value type: <u32>
Definition: ESR measurement current in mA. If this is not specified,
a default value of 120 mA will be configured. Allowed
values are 60, 120, 180 and 240.
- qcom,fg-batt-temp-delta
Usage: optional
Value type: <u32>
Definition: Battery temperature delta interrupt threshold. Possible
values are: 0, 1, 2 and 3. Unit is in Kelvin or Celsius.
- qcom,fg-batt-temp-cold-thresh
Usage: optional
Value type: <u32>
Definition: Battery temperature cold interrupt threshold. Allowed
values are from -128 to 127. Unit is in Kelvin or Celsius.
- qcom,fg-batt-temp-hot-thresh
Usage: optional
Value type: <u32>
Definition: Battery temperature hot interrupt threshold. Allowed
values are from -128 to 127. Unit is in Kelvin or Celsius.
- qcom,fg-batt-temp-hyst
Usage: optional
Value type: <u32>
Definition: Battery temperature hysteresis threshold. This will be
applicable only if the cold and hot thresholds are
specified. Possible values are: 0, 1, 2 and 3. Unit is in
Kelvin or Celsius.
- qcom,fg-force-load-profile
Usage: optional
Value type: <empty>
Definition: If set, battery profile will be force loaded if the profile
loaded earlier by bootloader doesn't match with the profile
available in the device tree.
- qcom,hold-soc-while-full
Usage: optional
Value type: <empty>
Definition: A boolean property that when defined holds SOC at 100% when
the battery is full.
- qcom,linearize-soc
Usage: optional
Value type: <empty>
Definition: A boolean property that when defined linearizes SOC when
the SOC drops after charge termination monotonically to
improve the user experience. This is applicable only if
"qcom,hold-soc-while-full" is specified.
- qcom,ki-coeff-soc-dischg
Usage: optional
Value type: <prop-encoded-array>
Definition: Array of monotonic SOC threshold values to change the ki
coefficient for medium discharge current during discharge.
This should be defined in the ascending order and in the
range of 0-100. Array limit is set to 3.
- qcom,ki-coeff-med-dischg
Usage: optional
Value type: <prop-encoded-array>
Definition: Array of ki coefficient values for medium discharge current
during discharge. These values will be applied when the
monotonic SOC goes below the SOC threshold specified under
qcom,ki-coeff-soc-dischg. Array limit is set to 3. This
property should be specified if qcom,ki-coeff-soc-dischg
is specified to make it fully functional. Value has no
unit. Allowed range is 62 to 15564 in micro units.
- qcom,ki-coeff-hi-dischg
Usage: optional
Value type: <prop-encoded-array>
Definition: Array of ki coefficient values for high discharge current
during discharge. These values will be applied when the
monotonic SOC goes below the SOC threshold specified under
qcom,ki-coeff-soc-dischg. Array limit is set to 3. This
property should be specified if qcom,ki-coeff-soc-dischg
is specified to make it fully functional. Value has no
unit. Allowed range is 62 to 15564 in micro units.
- qcom,fg-rconn-uohms
Usage: optional
Value type: <u32>
Definition: Battery connector resistance (Rconn) in microohms. If it's
already configured in bootloader, then it will not be
configured again by GEN4 FG driver.
- qcom,slope-limit-temp-threshold
Usage: optional
Value type: <u32>
Definition: Battery temperature threshold to decide when slope limit
coefficients should be applied along with charging status.
Unit is in decidegC.
- qcom,slope-limit-coeffs
Usage: optional
Value type: <prop-encoded-array>
Definition: A list of integers which holds the slope limit coefficients
in the following order. Allowed size is 4. Possible values
are from 123 to 31128. Unit is in micro-percentage.
Element 0 - Low temperature discharging
Element 1 - Low temperature charging
Element 2 - High temperature discharging
Element 3 - High temperature charging
These coefficients have to be specified along with the
property "qcom,slope-limit-temp-threshold" to make dynamic
slope limit adjustment functional.
==========================================================
Second Level Nodes - Peripherals managed by FG Gen4 driver
==========================================================
- reg
Usage: required
Value type: <prop-encoded-array>
Definition: Addresses and sizes for the specified peripheral
- interrupts
Usage: optional
Value type: <prop-encoded-array>
Definition: Interrupt mapping as per the interrupt encoding
- interrupt-names
Usage: optional
Value type: <stringlist>
Definition: Interrupt names. This list must match up 1-to-1 with the
interrupts specified in the 'interrupts' property.
========
Example
========
pm855b_fg: qpnp,fg {
compatible = "qcom,fg-gen4";
#address-cells = <1>;
#size-cells = <1>;
qcom,pmic-revid = <&pm855b_revid>;
status = "okay";
qcom,fg-batt-soc@4000 {
status = "okay";
reg = <0x4000 0x100>;
interrupts = <0x2 0x40 0x0 IRQ_TYPE_EDGE_BOTH>,
<0x2 0x40 0x1 IRQ_TYPE_EDGE_BOTH>,
<0x2 0x40 0x2 IRQ_TYPE_EDGE_RISING>,
<0x2 0x40 0x3 IRQ_TYPE_EDGE_RISING>,
<0x2 0x40 0x4 IRQ_TYPE_EDGE_BOTH>,
<0x2 0x40 0x5 IRQ_TYPE_EDGE_RISING>,
<0x2 0x40 0x6 IRQ_TYPE_EDGE_BOTH>,
<0x2 0x40 0x7 IRQ_TYPE_EDGE_BOTH>;
interrupt-names = "soc-update",
"soc-ready",
"bsoc-delta",
"msoc-delta",
"msoc-low",
"msoc-empty",
"msoc-high",
"msoc-full";
};
qcom,fg-batt-info@4100 {
status = "okay";
reg = <0x4100 0x100>;
interrupts = <0x2 0x41 0x0 IRQ_TYPE_EDGE_BOTH>,
<0x2 0x41 0x1 IRQ_TYPE_EDGE_BOTH>,
<0x2 0x41 0x3 IRQ_TYPE_EDGE_BOTH>;
interrupt-names = "vbatt-low",
"vbatt-pred-delta",
"esr-delta";
};
qcom,adc-rr@4200 {
status = "okay";
reg = <0x4200 0x100>;
interrupts = <0x2 0x42 0x0 IRQ_TYPE_EDGE_BOTH>,
<0x2 0x42 0x1 IRQ_TYPE_EDGE_BOTH>,
<0x2 0x42 0x2 IRQ_TYPE_EDGE_BOTH>,
<0x2 0x42 0x3 IRQ_TYPE_EDGE_BOTH>,
<0x2 0x42 0x4 IRQ_TYPE_EDGE_BOTH>;
interrupt-names = "batt-missing",
"batt-id",
"batt-temp-delta",
"batt-temp-hot",
"batt-temp-cold";
};
qcom,fg-memif@4300 {
status = "okay";
reg = <0x4300 0x100>;
interrupts = <0x2 0x43 0x0 IRQ_TYPE_EDGE_BOTH>,
<0x2 0x43 0x1 IRQ_TYPE_EDGE_BOTH>,
<0x2 0x43 0x2 IRQ_TYPE_EDGE_BOTH>,
<0x2 0x43 0x3 IRQ_TYPE_EDGE_BOTH>,
interrupt-names = "ima-rdy",
"ima-xcp",
"dma-xcp",
"dma-grant",
};
};

View File

@ -311,6 +311,7 @@ CONFIG_POWER_RESET_QCOM=y
CONFIG_QCOM_DLOAD_MODE=y
CONFIG_POWER_RESET_XGENE=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_QPNP_FG_GEN4=y
CONFIG_QPNP_SMB5=y
CONFIG_THERMAL=y
CONFIG_THERMAL_WRITABLE_TRIPS=y

View File

@ -320,6 +320,7 @@ CONFIG_POWER_RESET_QCOM=y
CONFIG_QCOM_DLOAD_MODE=y
CONFIG_POWER_RESET_XGENE=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_QPNP_FG_GEN4=y
CONFIG_QPNP_SMB5=y
CONFIG_THERMAL=y
CONFIG_THERMAL_WRITABLE_TRIPS=y

View File

@ -9,6 +9,16 @@ config QPNP_FG_GEN3
the fuel gauge. The state of charge is reported through a BMS power
supply property and also sends uevents when the capacity is updated.
config QPNP_FG_GEN4
tristate "QPNP GEN4 fuel gauge driver"
depends on MFD_SPMI_PMIC
help
Say Y here to enable the GEN4 Fuel Gauge driver. This adds support
for battery fuel gauging and state of charge of battery connected to
the device that has QTI PMICs like PM855B. The state of charge is
reported through a BMS power supply property and also sends uevents
when the capacity is updated.
config SMB1355_SLAVE_CHARGER
tristate "SMB1355 Slave Battery Charger"
depends on MFD_I2C_PMIC

View File

@ -1,4 +1,5 @@
obj-$(CONFIG_QPNP_FG_GEN3) += qpnp-fg-gen3.o fg-memif.o fg-util.o
obj-$(CONFIG_QPNP_FG_GEN4) += qpnp-fg-gen4.o fg-memif.o fg-util.o pmic-voter.o
obj-$(CONFIG_SMB1355_SLAVE_CHARGER) += smb1355-charger.o pmic-voter.o
obj-$(CONFIG_QPNP_SMB2) += step-chg-jeita.o battery.o qpnp-smb2.o smb-lib.o pmic-voter.o storm-watch.o
obj-$(CONFIG_SMB138X_CHARGER) += step-chg-jeita.o smb138x-charger.o smb-lib.o pmic-voter.o storm-watch.o battery.o

View File

@ -142,6 +142,13 @@ enum fg_irq_index {
MEM_XCP_IRQ,
IMA_RDY_IRQ,
FG_GEN3_IRQ_MAX,
/* GEN4 FG_MEM_IF */
DMA_XCP_IRQ,
/* GEN4 FG_ADC_RR */
BATT_TEMP_COLD_IRQ,
BATT_TEMP_HOT_IRQ,
BATT_ID_IRQ,
FG_GEN4_IRQ_MAX,
};
/*
@ -189,6 +196,8 @@ enum fg_sram_param_id {
FG_SRAM_ESR_TIGHT_FILTER,
FG_SRAM_ESR_BROAD_FILTER,
FG_SRAM_SLOPE_LIMIT,
FG_SRAM_BATT_TEMP_COLD,
FG_SRAM_BATT_TEMP_HOT,
FG_SRAM_MAX,
};
@ -231,6 +240,7 @@ enum fg_alg_flag_id {
enum fg_version {
GEN3_FG = 1,
GEN4_FG,
};
struct fg_alg_flag {
@ -242,6 +252,7 @@ struct fg_alg_flag {
enum wa_flags {
PMI8998_V1_REV_WA = BIT(0),
PM660_TSMC_OSC_WA = BIT(1),
PM855B_V1_DMA_WA = BIT(2),
};
enum slope_limit_status {
@ -270,6 +281,8 @@ struct fg_batt_props {
int float_volt_uv;
int vbatt_full_mv;
int fastchg_curr_ma;
int *therm_coeffs;
int therm_ctr_offset;
};
struct fg_cyc_ctr_data {

View File

@ -751,7 +751,7 @@ out:
static int fg_direct_mem_request(struct fg_dev *fg, bool request)
{
int rc, ret, i = 0;
u8 val, mask;
u8 val, mask, poll_bit;
mask = MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT;
val = request ? MEM_ACCESS_REQ_BIT : 0;
@ -783,6 +783,10 @@ static int fg_direct_mem_request(struct fg_dev *fg, bool request)
*/
usleep_range(40, 41);
poll_bit = MEM_GNT_BIT;
if (fg->version == GEN4_FG)
poll_bit = GEN4_MEM_GNT_BIT;
while (i < MEM_GNT_RETRIES) {
rc = fg_read(fg, MEM_IF_INT_RT_STS(fg), &val, 1);
if (rc < 0) {
@ -791,8 +795,12 @@ static int fg_direct_mem_request(struct fg_dev *fg, bool request)
goto release;
}
if (val & MEM_GNT_BIT)
if (val & poll_bit) {
/* Delay needed for PM855B V1 after DMA is granted */
if (fg->wa_flags & PM855B_V1_DMA_WA)
usleep_range(1000, 1001);
return 0;
}
usleep_range(MEM_GNT_WAIT_TIME_US, MEM_GNT_WAIT_TIME_US + 1);
i++;
@ -1005,6 +1013,9 @@ static int fg_ima_init(struct fg_dev *fg)
if (fg->version == GEN3_FG) {
fg->sram.num_bytes_per_word = 4;
fg->sram.address_max = 255;
} else if (fg->version == GEN4_FG) {
fg->sram.num_bytes_per_word = 2;
fg->sram.address_max = 480;
} else {
pr_err("Unknown FG version %d\n", fg->version);
return -ENXIO;
@ -1064,6 +1075,45 @@ static struct fg_dma_address fg_gen3_addr_map[3] = {
},
};
static struct fg_dma_address fg_gen4_addr_map[6] = {
/* system partition */
{
.partition_start = 0,
.partition_end = 63,
.spmi_addr_base = GEN4_FG_DMA0_BASE + SRAM_ADDR_OFFSET,
},
/* battery profile partition */
{
.partition_start = 64,
.partition_end = 169,
.spmi_addr_base = GEN4_FG_DMA1_BASE + SRAM_ADDR_OFFSET,
},
/* battery profile partition continued */
{
.partition_start = 170,
.partition_end = 274,
.spmi_addr_base = GEN4_FG_DMA2_BASE + SRAM_ADDR_OFFSET,
},
/* dp/SW partition */
{
.partition_start = 275,
.partition_end = 299,
.spmi_addr_base = GEN4_FG_DMA3_BASE + SRAM_ADDR_OFFSET,
},
/* wk/scratch pad partition */
{
.partition_start = 300,
.partition_end = 405,
.spmi_addr_base = GEN4_FG_DMA4_BASE + SRAM_ADDR_OFFSET,
},
/* wk/scratch pad partition continued */
{
.partition_start = 406,
.partition_end = 480,
.spmi_addr_base = GEN4_FG_DMA5_BASE + SRAM_ADDR_OFFSET,
},
};
static int fg_dma_init(struct fg_dev *fg)
{
int rc;
@ -1073,6 +1123,11 @@ static int fg_dma_init(struct fg_dev *fg)
fg->sram.num_partitions = 3;
fg->sram.num_bytes_per_word = 4;
fg->sram.address_max = 255;
} else if (fg->version == GEN4_FG) {
fg->sram.addr_map = fg_gen4_addr_map;
fg->sram.num_partitions = 6;
fg->sram.num_bytes_per_word = 2;
fg->sram.address_max = 479;
} else {
pr_err("Unknown FG version %d\n", fg->version);
return -ENXIO;

View File

@ -17,6 +17,28 @@
#define ADC_RR_FAKE_BATT_LOW_LSB(chip) (chip->rradc_base + 0x58)
#define ADC_RR_FAKE_BATT_HIGH_LSB(chip) (chip->rradc_base + 0x5A)
/* GEN4 FG definitions for FG_ADC_RR */
#define ADC_RR_INT_RT_STS(chip) (chip->rradc_base + 0x10)
#define ADC_RR_BT_MISS_BIT BIT(0)
#define ADC_RR_BATT_ID_HI_BIAS_STS(chip) (chip->rradc_base + 0x65)
#define BIAS_STS_READY BIT(0)
#define ADC_RR_BATT_ID_HI_BIAS_LSB(chip) (chip->rradc_base + 0x66)
#define ADC_RR_BATT_ID_HI_BIAS_MSB(chip) (chip->rradc_base + 0x67)
#define ADC_RR_BATT_ID_MED_BIAS_STS(chip) (chip->rradc_base + 0x6D)
#define ADC_RR_BATT_ID_MED_BIAS_LSB(chip) (chip->rradc_base + 0x6E)
#define ADC_RR_BATT_ID_MED_BIAS_MSB(chip) (chip->rradc_base + 0x6F)
#define ADC_RR_BATT_ID_LO_BIAS_STS(chip) (chip->rradc_base + 0x75)
#define ADC_RR_BATT_ID_LO_BIAS_LSB(chip) (chip->rradc_base + 0x76)
#define ADC_RR_BATT_ID_LO_BIAS_MSB(chip) (chip->rradc_base + 0x77)
#define ADC_RR_BATT_TEMP_LSB(chip) (chip->rradc_base + 0x88)
#define ADC_RR_BATT_TEMP_MSB(chip) (chip->rradc_base + 0x89)
#define GEN4_BATT_TEMP_MSB_MASK GENMASK(1, 0)
/* FG_BATT_SOC register definitions */
#define BATT_SOC_FG_ALG_STS(chip) (chip->batt_soc_base + 0x06)
#define BATT_SOC_FG_ALG_AUX_STS0(chip) (chip->batt_soc_base + 0x07)
@ -55,7 +77,6 @@
#define BATT_INFO_FG_STS(chip) (chip->batt_info_base + 0x09)
#define FG_WD_RESET_BIT BIT(7)
/* This bit is not present in v1.1 */
#define FG_CRG_TRM_BIT BIT(0)
#define BATT_INFO_INT_RT_STS(chip) (chip->batt_info_base + 0x10)
@ -67,6 +88,14 @@
#define VBT_LOW_BIT BIT(1)
#define VBT_PRD_DELTA_BIT BIT(0)
/* GEN4 bit definitions */
#define GEN4_BT_ATTN_BIT BIT(5)
#define GEN4_WDOG_EXP_BIT BIT(4)
#define GEN4_ESR_DELTA_BIT BIT(3)
#define GEN4_ESR_PULSE_PRE_BIT BIT(2)
#define GEN4_VBT_PRD_DELTA_BIT BIT(1)
#define GEN4_VBT_LOW_BIT BIT(0)
#define BATT_INFO_BATT_REM_LATCH(chip) (chip->batt_info_base + 0x4F)
#define BATT_REM_LATCH_CLR_BIT BIT(7)
@ -110,11 +139,6 @@
#define BATT_INFO_JEITA_HOT(chip) (chip->batt_info_base + 0x64)
#define BATT_INFO_JEITA_TOO_HOT(chip) (chip->batt_info_base + 0x65)
/* only for v1.1 */
#define BATT_INFO_ESR_CFG(chip) (chip->batt_info_base + 0x69)
#define CFG_ACTIVE_PD_MASK GENMASK(2, 1)
#define CFG_FCC_DEC_MASK GENMASK(4, 3)
/* starting from v2.0 */
#define BATT_INFO_ESR_GENERAL_CFG(chip) (chip->batt_info_base + 0x68)
#define ESR_DEEP_TAPER_EN_BIT BIT(0)
@ -144,6 +168,25 @@
#define ESR_FCC_6A 0x7
#define ESR_FAST_CRG_CTL_EN_BIT BIT(0)
/* GEN4 bit definitions */
#define GEN4_ESR_FAST_CRG_IVAL_MASK GENMASK(7, 4)
#define GEN4_ESR_FCC_300MA 0x0
#define GEN4_ESR_FCC_600MA 0x1
#define GEN4_ESR_FCC_1A 0x2
#define GEN4_ESR_FCC_1P5_A 0x3
#define GEN4_ESR_FCC_2A 0x4
#define GEN4_ESR_FCC_2P5_A 0x5
#define GEN4_ESR_FCC_3A 0x6
#define GEN4_ESR_FCC_3P5_A 0x7
#define GEN4_ESR_FCC_4A 0x8
#define GEN4_ESR_FCC_4P5_A 0x9
#define GEN4_ESR_FCC_5A 0xA
#define GEN4_ESR_FCC_5P5_A 0xB
#define GEN4_ESR_FCC_6A 0xC
#define GEN4_ESR_FCC_6P5_A 0xD
#define GEN4_ESR_FCC_7A 0xE
#define GEN4_ESR_FCC_7P5_A 0xF
#define BATT_INFO_BATT_MISS_CFG(chip) (chip->batt_info_base + 0x6B)
#define BM_THERM_TH_MASK GENMASK(5, 4)
#define RES_TH_0P75_MOHM 0x0
@ -226,8 +269,6 @@
#define BATT_IADC_CONV_BIT BIT(2)
#define ADC_ENABLE_REG_CTRL_BIT BIT(1)
#define WDOG_FORCE_EXP_BIT BIT(0)
/* only for v1.1 */
#define ESR_PULSE_FORCE_CTRL_BIT BIT(7)
#define BATT_INFO_TM_MISC1(chip) (chip->batt_info_base + 0xE6)
/* for v2.0 and above */
@ -238,6 +279,9 @@
#define MEM_IF_INT_RT_STS(chip) ((chip->mem_if_base) + 0x10)
#define MEM_XCP_BIT BIT(1)
#define MEM_GNT_BIT BIT(2)
#define GEN4_DMA_XCP_BIT BIT(2)
#define GEN4_MEM_GNT_BIT BIT(3)
#define GEN4_MEM_ATTN_BIT BIT(4)
#define MEM_IF_MEM_ARB_CFG(chip) ((chip->mem_if_base) + 0x40)
#define MEM_ARB_LO_LATENCY_EN_BIT BIT(1)
@ -300,4 +344,12 @@
#define FG_DMA2_BASE 0x4A00
#define FG_DMA3_BASE 0x4B00
#define SRAM_ADDR_OFFSET 0x20
/* GEN4 FG_DMAx */
#define GEN4_FG_DMA0_BASE 0x4400
#define GEN4_FG_DMA1_BASE 0x4500
#define GEN4_FG_DMA2_BASE 0x4600
#define GEN4_FG_DMA3_BASE 0x4700
#define GEN4_FG_DMA4_BASE 0x4800
#define GEN4_FG_DMA5_BASE 0x4900
#endif

View File

@ -622,10 +622,13 @@ int fg_sram_read(struct fg_dev *fg, u16 address, u8 offset,
int fg_sram_masked_write(struct fg_dev *fg, u16 address, u8 offset,
u8 mask, u8 val, int flags)
{
int rc = 0;
int rc = 0, length = 4;
u8 buf[4];
rc = fg_sram_read(fg, address, 0, buf, 4, flags);
if (fg->version == GEN4_FG)
length = 2;
rc = fg_sram_read(fg, address, 0, buf, length, flags);
if (rc < 0) {
pr_err("sram read failed: address=%03X, rc=%d\n", address, rc);
return rc;
@ -634,7 +637,7 @@ int fg_sram_masked_write(struct fg_dev *fg, u16 address, u8 offset,
buf[offset] &= ~mask;
buf[offset] |= val & mask;
rc = fg_sram_write(fg, address, 0, buf, 4, flags);
rc = fg_sram_write(fg, address, 0, buf, length, flags);
if (rc < 0) {
pr_err("sram write failed: address=%03X, rc=%d\n", address, rc);
return rc;
@ -667,17 +670,23 @@ int fg_read(struct fg_dev *fg, int addr, u8 *val, int len)
return 0;
}
static inline bool is_sec_access(struct fg_dev *fg, int addr)
{
if (fg->version != GEN3_FG)
return false;
return ((addr & 0x00FF) > 0xD0);
}
int fg_write(struct fg_dev *fg, int addr, u8 *val, int len)
{
int rc, i;
bool sec_access = false;
if (!fg || !fg->regmap)
return -ENXIO;
mutex_lock(&fg->bus_lock);
sec_access = (addr & 0x00FF) > 0xD0;
if (sec_access) {
if (is_sec_access(fg, addr)) {
rc = regmap_write(fg->regmap, (addr & 0xFF00) | 0xD0, 0xA5);
if (rc < 0) {
dev_err(fg->dev, "regmap_write failed for address %x rc=%d\n",
@ -710,14 +719,12 @@ out:
int fg_masked_write(struct fg_dev *fg, int addr, u8 mask, u8 val)
{
int rc;
bool sec_access = false;
if (!fg || !fg->regmap)
return -ENXIO;
mutex_lock(&fg->bus_lock);
sec_access = (addr & 0x00FF) > 0xD0;
if (sec_access) {
if (is_sec_access(fg, addr)) {
rc = regmap_write(fg->regmap, (addr & 0xFF00) | 0xD0, 0xA5);
if (rc < 0) {
dev_err(fg->dev, "regmap_write failed for address %x rc=%d\n",
@ -1233,8 +1240,23 @@ static int write_next_line_to_log(struct fg_trans *trans, int offset,
memcpy(data, trans->data + (offset - trans->addr), items_to_read);
*pcnt -= items_to_read;
/* address is in word now and it increments by 1. */
address = trans->addr + ((offset - trans->addr) / ITEMS_PER_LINE);
if (trans->fg->version == GEN4_FG) {
/*
* For GEN4 FG, address is in word and it increments by 1.
* Each word holds 2 bytes. To keep the SRAM dump format
* compatible, print 4 bytes per line which holds 2 words.
*/
address = trans->addr + ((offset - trans->addr) * 2 /
ITEMS_PER_LINE);
} else {
/*
* For GEN3 FG, address is in word and it increments by 1.
* Each word holds 4 bytes.
*/
address = trans->addr + ((offset - trans->addr) /
ITEMS_PER_LINE);
}
cnt = print_to_log(log, "%3.3d ", address & 0xfff);
if (cnt == 0)
goto done;

File diff suppressed because it is too large Load Diff