Loading Documentation/devicetree/bindings/regulator/cpr3-regulator.txt +21 −5 Original line number Diff line number Diff line Loading @@ -36,16 +36,16 @@ Platform independent properties: Usage: required Value type: <prop-encoded-array> Definition: Addresses and sizes for the memory of the CPR3 controller, the first fuse row, and optionally a register used to check if aging measurements are possible. the first fuse row, and optionally the SAW module and/or a register used to check if aging measurements are possible. - reg-names Usage: required Value type: <stringlist> Definition: Address names. Must include "cpr_ctrl" and "fuse_base". "aging_allowed" may also be specified. The strings must be specified in the same order as the corresponding addresses are specified in the reg property. "aging_allowed" and "saw" may also be specified. The strings must be specified in the same order as the corresponding addresses are specified in the reg property. - qcom,cpr-ctrl-name Usage: required Loading Loading @@ -216,6 +216,22 @@ Platform independent properties: as the corresponding addresses are specified in the qcom,cpr-panic-reg-addr-list property. - qcom,saw-avs-ctrl Usage: required if "saw" registers are specified by reg and reg-names properties Value type: <u32> Definition: SAW AVS_CTL register value to program at initialization time in order to allow hardware closed-loop CPR voltage change requests to reach the PMIC regulator. - qcom,saw-avs-limit Usage: required if "saw" registers are specified by reg and reg-names properties Value type: <u32> Definition: SAW AVS_LIMIT register value to program at initialization time in order to allow hardware closed-loop CPR voltage change requests to reach the PMIC regulator. ================================================= Second Level Nodes - CPR Threads for a Controller ================================================= Loading Documentation/devicetree/bindings/regulator/cprh-kbss-regulator.txt +11 −8 Original line number Diff line number Diff line Qualcomm Technologies, Inc. CPRh Regulator - KBSS Specific Bindings KBSS CPRh controllers each support one CPR thread that monitors the voltage of a single Kryo-B CPU subystem (KBSS) cluster that is powered by a single KBSS CPRh controllers each support one or more CPR threads that monitor the voltage of Kryo-B CPU subystem (KBSS) clusters that are powered by a single regulator supply. The DCVSh block interacts with the CPRh controller for full hardware DCVS support. Loading @@ -15,9 +15,9 @@ Required Node Structure ======================= CPRh regulators must be described in three levels of devices nodes. The first level describes the CPRh controller. The second level describes one hardware thread managed by the controller. The third level describes one regulator handled by the CPR thread. level describes the CPRh controller. The second level describes one or more hardware threads managed by the controller. The third level describes one regulator handled by each CPR thread. All platform independent cpr3-regulator binding guidelines defined in cpr3-regulator.txt also apply to cprh-kbss-regulator devices. Loading @@ -34,7 +34,10 @@ KBSS specific properties: "qcom,cprh-msm8998-v1-kbss-regulator", "qcom,cprh-msm8998-v2-kbss-regulator", "qcom,cprh-msm8998-kbss-regulator", "qcom,cprh-sdm660-kbss-regulator". "qcom,cprh-sdm660-kbss-regulator", "qcom,cprh-sdm845-v1-kbss-regulator", "qcom,cprh-sdm845-v2-kbss-regulator", "qcom,cprh-sdm845-kbss-regulator". If the SoC revision is not specified, then it is assumed to be the most recent revision of MSM8998, i.e. v2. Loading Loading @@ -242,7 +245,7 @@ KBSS specific properties: qcom,cpr-speed-bins number of elements. - qcom,corner-band-allow-core-count-adjustment Usage: optional Usage: optional; only allowed for CPRh thread 0 Value type: <prop-encoded-array> Definition: A list of integer tuples which each define the CPR core count adjustment feature enable state for each corner band Loading Loading @@ -271,7 +274,7 @@ KBSS specific properties: adjustments specified for this regulator's corner bands. - qcom,corner-band-allow-temp-adjustment Usage: optional Usage: optional; only allowed for CPRh thread 0 Value type: <prop-encoded-array> Definition: A list of integer tuples which each define the temperature adjustment feature enable state for each corner band Loading drivers/regulator/cpr3-regulator.c +100 −21 Original line number Diff line number Diff line Loading @@ -45,6 +45,9 @@ #define CPR3_RO_MASK GENMASK(CPR3_RO_COUNT - 1, 0) /* CPR3 registers */ #define CPR3_REG_CPR_VERSION 0x0 #define CPRH_CPR_VERSION_4P5 0x40050000 #define CPR3_REG_CPR_CTL 0x4 #define CPR3_CPR_CTL_LOOP_EN_MASK BIT(0) #define CPR3_CPR_CTL_LOOP_ENABLE BIT(0) Loading Loading @@ -228,7 +231,10 @@ #define CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK GENMASK(15, 0) /* CPRh controller specific registers and bit definitions */ #define CPRH_REG_CORNER(corner) (0x3A00 + 0x4 * (corner)) #define CPRH_REG_CORNER(thread, corner) \ ((thread)->ctrl->cpr_hw_version >= CPRH_CPR_VERSION_4P5 \ ? 0x3500 + 0xA0 * (thread)->thread_id + 0x4 * (corner) \ : 0x3A00 + 0x4 * (corner)) #define CPRH_CORNER_INIT_VOLTAGE_MASK GENMASK(7, 0) #define CPRH_CORNER_INIT_VOLTAGE_SHIFT 0 #define CPRH_CORNER_FLOOR_VOLTAGE_MASK GENMASK(15, 8) Loading @@ -244,7 +250,8 @@ #define CPRH_CORNER_FLOOR_VOLTAGE_MAX_VALUE 255 #define CPRH_CORNER_QUOT_DELTA_MAX_VALUE 511 #define CPRH_REG_CTL 0x3AA0 #define CPRH_REG_CTL(ctrl) \ ((ctrl)->cpr_hw_version >= CPRH_CPR_VERSION_4P5 ? 0x3A80 : 0x3AA0) #define CPRH_CTL_OSM_ENABLED BIT(0) #define CPRH_CTL_BASE_VOLTAGE_MASK GENMASK(10, 1) #define CPRH_CTL_BASE_VOLTAGE_SHIFT 1 Loading @@ -257,7 +264,9 @@ #define CPRH_CTL_LAST_KNOWN_VOLTAGE_MARGIN_MASK GENMASK(31, 29) #define CPRH_CTL_LAST_KNOWN_VOLTAGE_MARGIN_SHIFT 29 #define CPRH_REG_STATUS 0x3AA4 #define CPRH_REG_STATUS(thread) \ ((thread)->ctrl->cpr_hw_version >= CPRH_CPR_VERSION_4P5 \ ? 0x3A84 + 0x4 * (thread)->thread_id : 0x3AA4) #define CPRH_STATUS_CORNER GENMASK(5, 0) #define CPRH_STATUS_CORNER_LAST_VOLT_MASK GENMASK(17, 6) #define CPRH_STATUS_CORNER_LAST_VOLT_SHIFT 6 Loading @@ -271,6 +280,10 @@ ((vband) == 0 ? CPR4_REG_MARGIN_TEMP_CORE(core) \ : 0x3AB0 + 0x40 * ((vband) - 1) + 0x4 * (core)) /* SAW module registers */ #define SAW_REG_AVS_CTL 0x904 #define SAW_REG_AVS_LIMIT 0x908 /* * The amount of time to wait for the CPR controller to become idle when * performing an aging measurement. Loading Loading @@ -1173,7 +1186,7 @@ static int cpr3_regulator_init_cprh_corners(struct cpr3_regulator *vreg) i, open_loop_volt_steps, floor_volt_steps, delta_quot_steps, ctrl->base_volt, ctrl->step_volt, base_quots[ro_sel]); cpr3_write(ctrl, CPRH_REG_CORNER(i), reg); cpr3_write(ctrl, CPRH_REG_CORNER(vreg->thread, i), reg); } free_base_quots: Loading @@ -1197,6 +1210,7 @@ static int cpr3_regulator_init_cprh_corners(struct cpr3_regulator *vreg) static void cprh_controller_program_sdelta( struct cpr3_controller *ctrl) { /* Only thread 0 supports sdelta */ struct cpr3_regulator *vreg = &ctrl->thread[0].vreg[0]; struct cprh_corner_band *corner_band; struct cpr4_sdelta *sdelta; Loading @@ -1206,6 +1220,11 @@ static void cprh_controller_program_sdelta( if (!vreg->allow_core_count_adj && !vreg->allow_temp_adj) return; if (vreg->thread->thread_id != 0) { cpr3_err(vreg, "core count and temperature based adjustments are only allowed for CPR thread 0\n"); return; } cpr4_regulator_init_temp_points(ctrl); for (i = 0; i < CPRH_CORNER_BAND_MAX_COUNT; i++) { Loading Loading @@ -1287,17 +1306,21 @@ static int cpr3_regulator_init_cprh(struct cpr3_controller *ctrl) { u32 reg, pmic_step_size = 1; u64 temp; int rc; int i, rc; /* Single thread, single regulator supported */ if (ctrl->thread_count != 1) { cpr3_err(ctrl, "expected 1 thread but found %d\n", /* One or two threads each with a single regulator supported */ if (ctrl->thread_count < 1 || ctrl->thread_count > 2) { cpr3_err(ctrl, "expected 1 or 2 threads but found %d\n", ctrl->thread_count); return -EINVAL; } else if (ctrl->thread[0].vreg_count != 1) { cpr3_err(ctrl, "expected 1 regulator but found %d\n", cpr3_err(ctrl, "expected 1 regulator for thread 0 but found %d\n", ctrl->thread[0].vreg_count); return -EINVAL; } else if (ctrl->thread_count == 2 && ctrl->thread[1].vreg_count != 1) { cpr3_err(ctrl, "expected 1 regulator for thread 1 but found %d\n", ctrl->thread[1].vreg_count); return -EINVAL; } rc = cprh_regulator_aging_adjust(ctrl); Loading @@ -1312,11 +1335,13 @@ static int cpr3_regulator_init_cprh(struct cpr3_controller *ctrl) cprh_controller_program_sdelta(ctrl); rc = cpr3_regulator_init_cprh_corners(&ctrl->thread[0].vreg[0]); for (i = 0; i < ctrl->thread_count; i++) { rc = cpr3_regulator_init_cprh_corners(&ctrl->thread[i].vreg[0]); if (rc) { cpr3_err(ctrl, "failed to initialize CPRh corner registers\n"); return rc; } } if (ctrl->saw_use_unit_mV) pmic_step_size = ctrl->step_volt / 1000; Loading Loading @@ -1368,7 +1393,7 @@ static int cpr3_regulator_init_cprh(struct cpr3_controller *ctrl) * (u64)ctrl->corner_switch_delay_time; do_div(temp, 1000000000); do_div(temp, CPRH_MODE_SWITCH_DELAY_FACTOR); cpr3_masked_write(ctrl, CPRH_REG_CTL, cpr3_masked_write(ctrl, CPRH_REG_CTL(ctrl), CPRH_CTL_MODE_SWITCH_DELAY_MASK, temp << CPRH_CTL_MODE_SWITCH_DELAY_SHIFT); } Loading @@ -1386,7 +1411,7 @@ static int cpr3_regulator_init_cprh(struct cpr3_controller *ctrl) & CPRH_CTL_VOLTAGE_MULTIPLIER_MASK; /* Enable OSM block interface with CPR */ reg |= CPRH_CTL_OSM_ENABLED; cpr3_masked_write(ctrl, CPRH_REG_CTL, CPRH_CTL_BASE_VOLTAGE_MASK cpr3_masked_write(ctrl, CPRH_REG_CTL(ctrl), CPRH_CTL_BASE_VOLTAGE_MASK | CPRH_CTL_VOLTAGE_MULTIPLIER_MASK | CPRH_CTL_OSM_ENABLED, reg); Loading Loading @@ -1427,6 +1452,8 @@ static int cpr3_regulator_init_ctrl(struct cpr3_controller *ctrl) } ctrl->cpr_enabled = true; ctrl->cpr_hw_version = cpr3_read(ctrl, CPR3_REG_CPR_VERSION); /* Find all RO's used by any corner of any regulator. */ for (i = 0; i < ctrl->thread_count; i++) for (j = 0; j < ctrl->thread[i].vreg_count; j++) Loading Loading @@ -1589,6 +1616,60 @@ static int cpr3_regulator_init_ctrl(struct cpr3_controller *ctrl) return 0; } /** * cpr3_regulator_init_hw_closed_loop_dependencies() - perform hardware * initialization steps to ensure that CPR HW closed-loop voltage * change requests are able to reach the PMIC regulator * @pdev: Platform device pointer for the CPR3 controller * @ctrl: Pointer to the CPR3 controller * * Return: 0 on success, errno on failure */ static int cpr3_regulator_init_hw_closed_loop_dependencies(struct platform_device *pdev, struct cpr3_controller *ctrl) { struct resource *res; int rc = 0; u32 val; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "saw"); if (res && res->start) ctrl->saw_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (ctrl->saw_base) { /* Configure SAW registers directly. */ rc = of_property_read_u32(ctrl->dev->of_node, "qcom,saw-avs-ctrl", &val); if (rc) { cpr3_err(ctrl, "unable to read DT property qcom,saw-avs-ctrl, rc=%d\n", rc); return rc; } writel_relaxed(val, ctrl->saw_base + SAW_REG_AVS_CTL); rc = of_property_read_u32(ctrl->dev->of_node, "qcom,saw-avs-limit", &val); if (rc) { cpr3_err(ctrl, "unable to read DT property qcom,saw-avs-limit, rc=%d\n", rc); return rc; } writel_relaxed(val, ctrl->saw_base + SAW_REG_AVS_LIMIT); } else { /* Wait for SPM driver to configure SAW registers. */ rc = msm_spm_probe_done(); if (rc) { if (rc != -EPROBE_DEFER) cpr3_err(ctrl, "spm unavailable, rc=%d\n", rc); return rc; } } return 0; } /** * cpr3_regulator_set_target_quot() - configure the target quotient for each * RO of the CPR3 thread and set the RO mask Loading Loading @@ -4506,7 +4587,7 @@ static int cprh_regulator_get_voltage(struct regulator_dev *rdev) ctrl->cpr_enabled = true; } reg = cpr3_read(vreg->thread->ctrl, CPRH_REG_STATUS); reg = cpr3_read(vreg->thread->ctrl, CPRH_REG_STATUS(vreg->thread)); if (!cpr_enabled) { cpr3_clock_disable(ctrl); Loading Loading @@ -6332,12 +6413,10 @@ int cpr3_regulator_register(struct platform_device *pdev, } if (ctrl->supports_hw_closed_loop) { rc = msm_spm_probe_done(); if (rc) { if (rc != -EPROBE_DEFER) cpr3_err(ctrl, "spm unavailable, rc=%d\n", rc); rc = cpr3_regulator_init_hw_closed_loop_dependencies(pdev, ctrl); if (rc) return rc; } if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR3) { ctrl->ceiling_irq = platform_get_irq_byname(pdev, Loading drivers/regulator/cpr3-regulator.h +6 −0 Original line number Diff line number Diff line Loading @@ -550,6 +550,9 @@ struct cpr3_panic_regs_info { * that this CPR3 controller manages. * @cpr_ctrl_base: Virtual address of the CPR3 controller base register * @fuse_base: Virtual address of fuse row 0 * @saw_base: Virtual address of the SAW module base register. This * is used for CPR controllers that support HW closed-loop * on platforms which lack an SPM. * @aging_possible_reg: Virtual address of an optional platform-specific * register that must be ready to determine if it is * possible to perform an aging measurement. Loading @@ -565,6 +568,7 @@ struct cpr3_panic_regs_info { * @soc_revision: Revision number of the SoC. This may be unused by * platforms that do not have different behavior for * different SoC revisions. * @cpr_hw_version: CPR controller version register value * @lock: Mutex lock used to ensure mutual exclusion between * all of the threads associated with the controller * @vdd_regulator: Pointer to the VDD supply regulator which this CPR3 Loading Loading @@ -757,6 +761,7 @@ struct cpr3_controller { int ctrl_id; void __iomem *cpr_ctrl_base; void __iomem *fuse_base; void __iomem *saw_base; void __iomem *aging_possible_reg; struct list_head list; struct cpr3_thread *thread; Loading @@ -764,6 +769,7 @@ struct cpr3_controller { u8 *sensor_owner; int sensor_count; int soc_revision; u32 cpr_hw_version; struct mutex lock; struct regulator *vdd_regulator; struct regulator *system_regulator; Loading drivers/regulator/cprh-kbss-regulator.c +469 −69 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
Documentation/devicetree/bindings/regulator/cpr3-regulator.txt +21 −5 Original line number Diff line number Diff line Loading @@ -36,16 +36,16 @@ Platform independent properties: Usage: required Value type: <prop-encoded-array> Definition: Addresses and sizes for the memory of the CPR3 controller, the first fuse row, and optionally a register used to check if aging measurements are possible. the first fuse row, and optionally the SAW module and/or a register used to check if aging measurements are possible. - reg-names Usage: required Value type: <stringlist> Definition: Address names. Must include "cpr_ctrl" and "fuse_base". "aging_allowed" may also be specified. The strings must be specified in the same order as the corresponding addresses are specified in the reg property. "aging_allowed" and "saw" may also be specified. The strings must be specified in the same order as the corresponding addresses are specified in the reg property. - qcom,cpr-ctrl-name Usage: required Loading Loading @@ -216,6 +216,22 @@ Platform independent properties: as the corresponding addresses are specified in the qcom,cpr-panic-reg-addr-list property. - qcom,saw-avs-ctrl Usage: required if "saw" registers are specified by reg and reg-names properties Value type: <u32> Definition: SAW AVS_CTL register value to program at initialization time in order to allow hardware closed-loop CPR voltage change requests to reach the PMIC regulator. - qcom,saw-avs-limit Usage: required if "saw" registers are specified by reg and reg-names properties Value type: <u32> Definition: SAW AVS_LIMIT register value to program at initialization time in order to allow hardware closed-loop CPR voltage change requests to reach the PMIC regulator. ================================================= Second Level Nodes - CPR Threads for a Controller ================================================= Loading
Documentation/devicetree/bindings/regulator/cprh-kbss-regulator.txt +11 −8 Original line number Diff line number Diff line Qualcomm Technologies, Inc. CPRh Regulator - KBSS Specific Bindings KBSS CPRh controllers each support one CPR thread that monitors the voltage of a single Kryo-B CPU subystem (KBSS) cluster that is powered by a single KBSS CPRh controllers each support one or more CPR threads that monitor the voltage of Kryo-B CPU subystem (KBSS) clusters that are powered by a single regulator supply. The DCVSh block interacts with the CPRh controller for full hardware DCVS support. Loading @@ -15,9 +15,9 @@ Required Node Structure ======================= CPRh regulators must be described in three levels of devices nodes. The first level describes the CPRh controller. The second level describes one hardware thread managed by the controller. The third level describes one regulator handled by the CPR thread. level describes the CPRh controller. The second level describes one or more hardware threads managed by the controller. The third level describes one regulator handled by each CPR thread. All platform independent cpr3-regulator binding guidelines defined in cpr3-regulator.txt also apply to cprh-kbss-regulator devices. Loading @@ -34,7 +34,10 @@ KBSS specific properties: "qcom,cprh-msm8998-v1-kbss-regulator", "qcom,cprh-msm8998-v2-kbss-regulator", "qcom,cprh-msm8998-kbss-regulator", "qcom,cprh-sdm660-kbss-regulator". "qcom,cprh-sdm660-kbss-regulator", "qcom,cprh-sdm845-v1-kbss-regulator", "qcom,cprh-sdm845-v2-kbss-regulator", "qcom,cprh-sdm845-kbss-regulator". If the SoC revision is not specified, then it is assumed to be the most recent revision of MSM8998, i.e. v2. Loading Loading @@ -242,7 +245,7 @@ KBSS specific properties: qcom,cpr-speed-bins number of elements. - qcom,corner-band-allow-core-count-adjustment Usage: optional Usage: optional; only allowed for CPRh thread 0 Value type: <prop-encoded-array> Definition: A list of integer tuples which each define the CPR core count adjustment feature enable state for each corner band Loading Loading @@ -271,7 +274,7 @@ KBSS specific properties: adjustments specified for this regulator's corner bands. - qcom,corner-band-allow-temp-adjustment Usage: optional Usage: optional; only allowed for CPRh thread 0 Value type: <prop-encoded-array> Definition: A list of integer tuples which each define the temperature adjustment feature enable state for each corner band Loading
drivers/regulator/cpr3-regulator.c +100 −21 Original line number Diff line number Diff line Loading @@ -45,6 +45,9 @@ #define CPR3_RO_MASK GENMASK(CPR3_RO_COUNT - 1, 0) /* CPR3 registers */ #define CPR3_REG_CPR_VERSION 0x0 #define CPRH_CPR_VERSION_4P5 0x40050000 #define CPR3_REG_CPR_CTL 0x4 #define CPR3_CPR_CTL_LOOP_EN_MASK BIT(0) #define CPR3_CPR_CTL_LOOP_ENABLE BIT(0) Loading Loading @@ -228,7 +231,10 @@ #define CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK GENMASK(15, 0) /* CPRh controller specific registers and bit definitions */ #define CPRH_REG_CORNER(corner) (0x3A00 + 0x4 * (corner)) #define CPRH_REG_CORNER(thread, corner) \ ((thread)->ctrl->cpr_hw_version >= CPRH_CPR_VERSION_4P5 \ ? 0x3500 + 0xA0 * (thread)->thread_id + 0x4 * (corner) \ : 0x3A00 + 0x4 * (corner)) #define CPRH_CORNER_INIT_VOLTAGE_MASK GENMASK(7, 0) #define CPRH_CORNER_INIT_VOLTAGE_SHIFT 0 #define CPRH_CORNER_FLOOR_VOLTAGE_MASK GENMASK(15, 8) Loading @@ -244,7 +250,8 @@ #define CPRH_CORNER_FLOOR_VOLTAGE_MAX_VALUE 255 #define CPRH_CORNER_QUOT_DELTA_MAX_VALUE 511 #define CPRH_REG_CTL 0x3AA0 #define CPRH_REG_CTL(ctrl) \ ((ctrl)->cpr_hw_version >= CPRH_CPR_VERSION_4P5 ? 0x3A80 : 0x3AA0) #define CPRH_CTL_OSM_ENABLED BIT(0) #define CPRH_CTL_BASE_VOLTAGE_MASK GENMASK(10, 1) #define CPRH_CTL_BASE_VOLTAGE_SHIFT 1 Loading @@ -257,7 +264,9 @@ #define CPRH_CTL_LAST_KNOWN_VOLTAGE_MARGIN_MASK GENMASK(31, 29) #define CPRH_CTL_LAST_KNOWN_VOLTAGE_MARGIN_SHIFT 29 #define CPRH_REG_STATUS 0x3AA4 #define CPRH_REG_STATUS(thread) \ ((thread)->ctrl->cpr_hw_version >= CPRH_CPR_VERSION_4P5 \ ? 0x3A84 + 0x4 * (thread)->thread_id : 0x3AA4) #define CPRH_STATUS_CORNER GENMASK(5, 0) #define CPRH_STATUS_CORNER_LAST_VOLT_MASK GENMASK(17, 6) #define CPRH_STATUS_CORNER_LAST_VOLT_SHIFT 6 Loading @@ -271,6 +280,10 @@ ((vband) == 0 ? CPR4_REG_MARGIN_TEMP_CORE(core) \ : 0x3AB0 + 0x40 * ((vband) - 1) + 0x4 * (core)) /* SAW module registers */ #define SAW_REG_AVS_CTL 0x904 #define SAW_REG_AVS_LIMIT 0x908 /* * The amount of time to wait for the CPR controller to become idle when * performing an aging measurement. Loading Loading @@ -1173,7 +1186,7 @@ static int cpr3_regulator_init_cprh_corners(struct cpr3_regulator *vreg) i, open_loop_volt_steps, floor_volt_steps, delta_quot_steps, ctrl->base_volt, ctrl->step_volt, base_quots[ro_sel]); cpr3_write(ctrl, CPRH_REG_CORNER(i), reg); cpr3_write(ctrl, CPRH_REG_CORNER(vreg->thread, i), reg); } free_base_quots: Loading @@ -1197,6 +1210,7 @@ static int cpr3_regulator_init_cprh_corners(struct cpr3_regulator *vreg) static void cprh_controller_program_sdelta( struct cpr3_controller *ctrl) { /* Only thread 0 supports sdelta */ struct cpr3_regulator *vreg = &ctrl->thread[0].vreg[0]; struct cprh_corner_band *corner_band; struct cpr4_sdelta *sdelta; Loading @@ -1206,6 +1220,11 @@ static void cprh_controller_program_sdelta( if (!vreg->allow_core_count_adj && !vreg->allow_temp_adj) return; if (vreg->thread->thread_id != 0) { cpr3_err(vreg, "core count and temperature based adjustments are only allowed for CPR thread 0\n"); return; } cpr4_regulator_init_temp_points(ctrl); for (i = 0; i < CPRH_CORNER_BAND_MAX_COUNT; i++) { Loading Loading @@ -1287,17 +1306,21 @@ static int cpr3_regulator_init_cprh(struct cpr3_controller *ctrl) { u32 reg, pmic_step_size = 1; u64 temp; int rc; int i, rc; /* Single thread, single regulator supported */ if (ctrl->thread_count != 1) { cpr3_err(ctrl, "expected 1 thread but found %d\n", /* One or two threads each with a single regulator supported */ if (ctrl->thread_count < 1 || ctrl->thread_count > 2) { cpr3_err(ctrl, "expected 1 or 2 threads but found %d\n", ctrl->thread_count); return -EINVAL; } else if (ctrl->thread[0].vreg_count != 1) { cpr3_err(ctrl, "expected 1 regulator but found %d\n", cpr3_err(ctrl, "expected 1 regulator for thread 0 but found %d\n", ctrl->thread[0].vreg_count); return -EINVAL; } else if (ctrl->thread_count == 2 && ctrl->thread[1].vreg_count != 1) { cpr3_err(ctrl, "expected 1 regulator for thread 1 but found %d\n", ctrl->thread[1].vreg_count); return -EINVAL; } rc = cprh_regulator_aging_adjust(ctrl); Loading @@ -1312,11 +1335,13 @@ static int cpr3_regulator_init_cprh(struct cpr3_controller *ctrl) cprh_controller_program_sdelta(ctrl); rc = cpr3_regulator_init_cprh_corners(&ctrl->thread[0].vreg[0]); for (i = 0; i < ctrl->thread_count; i++) { rc = cpr3_regulator_init_cprh_corners(&ctrl->thread[i].vreg[0]); if (rc) { cpr3_err(ctrl, "failed to initialize CPRh corner registers\n"); return rc; } } if (ctrl->saw_use_unit_mV) pmic_step_size = ctrl->step_volt / 1000; Loading Loading @@ -1368,7 +1393,7 @@ static int cpr3_regulator_init_cprh(struct cpr3_controller *ctrl) * (u64)ctrl->corner_switch_delay_time; do_div(temp, 1000000000); do_div(temp, CPRH_MODE_SWITCH_DELAY_FACTOR); cpr3_masked_write(ctrl, CPRH_REG_CTL, cpr3_masked_write(ctrl, CPRH_REG_CTL(ctrl), CPRH_CTL_MODE_SWITCH_DELAY_MASK, temp << CPRH_CTL_MODE_SWITCH_DELAY_SHIFT); } Loading @@ -1386,7 +1411,7 @@ static int cpr3_regulator_init_cprh(struct cpr3_controller *ctrl) & CPRH_CTL_VOLTAGE_MULTIPLIER_MASK; /* Enable OSM block interface with CPR */ reg |= CPRH_CTL_OSM_ENABLED; cpr3_masked_write(ctrl, CPRH_REG_CTL, CPRH_CTL_BASE_VOLTAGE_MASK cpr3_masked_write(ctrl, CPRH_REG_CTL(ctrl), CPRH_CTL_BASE_VOLTAGE_MASK | CPRH_CTL_VOLTAGE_MULTIPLIER_MASK | CPRH_CTL_OSM_ENABLED, reg); Loading Loading @@ -1427,6 +1452,8 @@ static int cpr3_regulator_init_ctrl(struct cpr3_controller *ctrl) } ctrl->cpr_enabled = true; ctrl->cpr_hw_version = cpr3_read(ctrl, CPR3_REG_CPR_VERSION); /* Find all RO's used by any corner of any regulator. */ for (i = 0; i < ctrl->thread_count; i++) for (j = 0; j < ctrl->thread[i].vreg_count; j++) Loading Loading @@ -1589,6 +1616,60 @@ static int cpr3_regulator_init_ctrl(struct cpr3_controller *ctrl) return 0; } /** * cpr3_regulator_init_hw_closed_loop_dependencies() - perform hardware * initialization steps to ensure that CPR HW closed-loop voltage * change requests are able to reach the PMIC regulator * @pdev: Platform device pointer for the CPR3 controller * @ctrl: Pointer to the CPR3 controller * * Return: 0 on success, errno on failure */ static int cpr3_regulator_init_hw_closed_loop_dependencies(struct platform_device *pdev, struct cpr3_controller *ctrl) { struct resource *res; int rc = 0; u32 val; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "saw"); if (res && res->start) ctrl->saw_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (ctrl->saw_base) { /* Configure SAW registers directly. */ rc = of_property_read_u32(ctrl->dev->of_node, "qcom,saw-avs-ctrl", &val); if (rc) { cpr3_err(ctrl, "unable to read DT property qcom,saw-avs-ctrl, rc=%d\n", rc); return rc; } writel_relaxed(val, ctrl->saw_base + SAW_REG_AVS_CTL); rc = of_property_read_u32(ctrl->dev->of_node, "qcom,saw-avs-limit", &val); if (rc) { cpr3_err(ctrl, "unable to read DT property qcom,saw-avs-limit, rc=%d\n", rc); return rc; } writel_relaxed(val, ctrl->saw_base + SAW_REG_AVS_LIMIT); } else { /* Wait for SPM driver to configure SAW registers. */ rc = msm_spm_probe_done(); if (rc) { if (rc != -EPROBE_DEFER) cpr3_err(ctrl, "spm unavailable, rc=%d\n", rc); return rc; } } return 0; } /** * cpr3_regulator_set_target_quot() - configure the target quotient for each * RO of the CPR3 thread and set the RO mask Loading Loading @@ -4506,7 +4587,7 @@ static int cprh_regulator_get_voltage(struct regulator_dev *rdev) ctrl->cpr_enabled = true; } reg = cpr3_read(vreg->thread->ctrl, CPRH_REG_STATUS); reg = cpr3_read(vreg->thread->ctrl, CPRH_REG_STATUS(vreg->thread)); if (!cpr_enabled) { cpr3_clock_disable(ctrl); Loading Loading @@ -6332,12 +6413,10 @@ int cpr3_regulator_register(struct platform_device *pdev, } if (ctrl->supports_hw_closed_loop) { rc = msm_spm_probe_done(); if (rc) { if (rc != -EPROBE_DEFER) cpr3_err(ctrl, "spm unavailable, rc=%d\n", rc); rc = cpr3_regulator_init_hw_closed_loop_dependencies(pdev, ctrl); if (rc) return rc; } if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR3) { ctrl->ceiling_irq = platform_get_irq_byname(pdev, Loading
drivers/regulator/cpr3-regulator.h +6 −0 Original line number Diff line number Diff line Loading @@ -550,6 +550,9 @@ struct cpr3_panic_regs_info { * that this CPR3 controller manages. * @cpr_ctrl_base: Virtual address of the CPR3 controller base register * @fuse_base: Virtual address of fuse row 0 * @saw_base: Virtual address of the SAW module base register. This * is used for CPR controllers that support HW closed-loop * on platforms which lack an SPM. * @aging_possible_reg: Virtual address of an optional platform-specific * register that must be ready to determine if it is * possible to perform an aging measurement. Loading @@ -565,6 +568,7 @@ struct cpr3_panic_regs_info { * @soc_revision: Revision number of the SoC. This may be unused by * platforms that do not have different behavior for * different SoC revisions. * @cpr_hw_version: CPR controller version register value * @lock: Mutex lock used to ensure mutual exclusion between * all of the threads associated with the controller * @vdd_regulator: Pointer to the VDD supply regulator which this CPR3 Loading Loading @@ -757,6 +761,7 @@ struct cpr3_controller { int ctrl_id; void __iomem *cpr_ctrl_base; void __iomem *fuse_base; void __iomem *saw_base; void __iomem *aging_possible_reg; struct list_head list; struct cpr3_thread *thread; Loading @@ -764,6 +769,7 @@ struct cpr3_controller { u8 *sensor_owner; int sensor_count; int soc_revision; u32 cpr_hw_version; struct mutex lock; struct regulator *vdd_regulator; struct regulator *system_regulator; Loading
drivers/regulator/cprh-kbss-regulator.c +469 −69 File changed.Preview size limit exceeded, changes collapsed. Show changes