Loading Documentation/devicetree/bindings/arm/msm/cpr-regulator.txt +10 −0 Original line number Diff line number Diff line Loading @@ -147,6 +147,15 @@ Optional properties: is present, and vise versa. - qti,cpr-enable: Present: CPR enabled by default. Not Present: CPR disable by default. - qti,cpr-cond-min-voltage: Minimum voltage in microvolts for SVS, NOM and TURBO mode if the fuse defined in qti,cpr-cond-min-volt-fuse has not be programmed with the expected data. - qti,cpr-cond-min-volt-fuse: Array of row number of fuse, data in that row and reading method. This property can be used to capture hardware requirements determined by the value of the mem-accel fuse. It should have index and value like this: [0]: the fuse row number [1]: high 32 bits of the expected data in that row. [2]: low 32 bits of the expected data in that row. [3]: reading method, 0 for direct reading or 1 for SCM reading Example: Loading Loading @@ -202,5 +211,6 @@ Example: qti,cpr-fuse-redun-row = <139 1>; qti,cpr-fuse-redun-target-quot = <24 12 0>; qti,cpr-fuse-redun-ro-sel = <46 36 39>; qti,cpr-cond-min-volt-fuse = <54 0xc100 0x0 1>; }; arch/arm/mach-msm/cpr-regulator.c +40 −1 Original line number Diff line number Diff line Loading @@ -138,6 +138,8 @@ #define BYTES_PER_FUSE_ROW 8 #define FLAGS_SET_MIN_VOLTAGE BIT(1) enum voltage_change_dir { NO_CHANGE, DOWN, Loading Loading @@ -209,6 +211,7 @@ struct cpr_regulator { u32 gcnt_time_us; u32 vdd_apc_step_up_limit; u32 vdd_apc_step_down_limit; u32 flags; }; #define CPR_DEBUG_MASK_IRQ BIT(0) Loading Loading @@ -1464,11 +1467,35 @@ static void cpr_efuse_free(struct cpr_regulator *cpr_vreg) iounmap(cpr_vreg->efuse_base); } static void cpr_parse_cond_min_volt_fuse(struct cpr_regulator *cpr_vreg, struct device_node *of_node) { int rc; u32 fuse[4]; u64 blown_data, fuse_data; /* * Restrict all pvs corner voltages to a minimum value of * qti,cpr-cond-min-voltage if the fuse defined in * qti,cpr-cond-min-volt-fuse does not read back with the expected * value. */ rc = of_property_read_u32_array(of_node, "qti,cpr-cond-min-volt-fuse", fuse, 4); if (!rc) { blown_data = cpr_read_efuse_row(cpr_vreg, fuse[0], fuse[3]); fuse_data = ((u64)fuse[1] << 32) | fuse[2]; if (blown_data == fuse_data) cpr_vreg->flags |= FLAGS_SET_MIN_VOLTAGE; } } static int cpr_voltage_plan_init(struct platform_device *pdev, struct cpr_regulator *cpr_vreg) { struct device_node *of_node = pdev->dev.of_node; int rc, i; int rc, i, j; u32 min_uv = 0; rc = of_property_read_u32_array(of_node, "qti,pvs-corner-ceiling-slow", Loading Loading @@ -1497,6 +1524,18 @@ static int cpr_voltage_plan_init(struct platform_device *pdev, return rc; } cpr_parse_cond_min_volt_fuse(cpr_vreg, of_node); if (cpr_vreg->flags & FLAGS_SET_MIN_VOLTAGE) { of_property_read_u32(of_node, "qti,cpr-cond-min-voltage", &min_uv); for (i = APC_PVS_SLOW; i < NUM_APC_PVS; i++) for (j = CPR_CORNER_SVS; j < CPR_CORNER_MAX; j++) if (cpr_vreg->pvs_corner_v[i][j] < min_uv) cpr_vreg->pvs_corner_v[i][j] = min_uv; } /* Set ceiling max and use it for APC_PVS_NO */ cpr_vreg->ceiling_max = cpr_vreg->pvs_corner_v[APC_PVS_SLOW][CPR_CORNER_TURBO]; Loading Loading
Documentation/devicetree/bindings/arm/msm/cpr-regulator.txt +10 −0 Original line number Diff line number Diff line Loading @@ -147,6 +147,15 @@ Optional properties: is present, and vise versa. - qti,cpr-enable: Present: CPR enabled by default. Not Present: CPR disable by default. - qti,cpr-cond-min-voltage: Minimum voltage in microvolts for SVS, NOM and TURBO mode if the fuse defined in qti,cpr-cond-min-volt-fuse has not be programmed with the expected data. - qti,cpr-cond-min-volt-fuse: Array of row number of fuse, data in that row and reading method. This property can be used to capture hardware requirements determined by the value of the mem-accel fuse. It should have index and value like this: [0]: the fuse row number [1]: high 32 bits of the expected data in that row. [2]: low 32 bits of the expected data in that row. [3]: reading method, 0 for direct reading or 1 for SCM reading Example: Loading Loading @@ -202,5 +211,6 @@ Example: qti,cpr-fuse-redun-row = <139 1>; qti,cpr-fuse-redun-target-quot = <24 12 0>; qti,cpr-fuse-redun-ro-sel = <46 36 39>; qti,cpr-cond-min-volt-fuse = <54 0xc100 0x0 1>; };
arch/arm/mach-msm/cpr-regulator.c +40 −1 Original line number Diff line number Diff line Loading @@ -138,6 +138,8 @@ #define BYTES_PER_FUSE_ROW 8 #define FLAGS_SET_MIN_VOLTAGE BIT(1) enum voltage_change_dir { NO_CHANGE, DOWN, Loading Loading @@ -209,6 +211,7 @@ struct cpr_regulator { u32 gcnt_time_us; u32 vdd_apc_step_up_limit; u32 vdd_apc_step_down_limit; u32 flags; }; #define CPR_DEBUG_MASK_IRQ BIT(0) Loading Loading @@ -1464,11 +1467,35 @@ static void cpr_efuse_free(struct cpr_regulator *cpr_vreg) iounmap(cpr_vreg->efuse_base); } static void cpr_parse_cond_min_volt_fuse(struct cpr_regulator *cpr_vreg, struct device_node *of_node) { int rc; u32 fuse[4]; u64 blown_data, fuse_data; /* * Restrict all pvs corner voltages to a minimum value of * qti,cpr-cond-min-voltage if the fuse defined in * qti,cpr-cond-min-volt-fuse does not read back with the expected * value. */ rc = of_property_read_u32_array(of_node, "qti,cpr-cond-min-volt-fuse", fuse, 4); if (!rc) { blown_data = cpr_read_efuse_row(cpr_vreg, fuse[0], fuse[3]); fuse_data = ((u64)fuse[1] << 32) | fuse[2]; if (blown_data == fuse_data) cpr_vreg->flags |= FLAGS_SET_MIN_VOLTAGE; } } static int cpr_voltage_plan_init(struct platform_device *pdev, struct cpr_regulator *cpr_vreg) { struct device_node *of_node = pdev->dev.of_node; int rc, i; int rc, i, j; u32 min_uv = 0; rc = of_property_read_u32_array(of_node, "qti,pvs-corner-ceiling-slow", Loading Loading @@ -1497,6 +1524,18 @@ static int cpr_voltage_plan_init(struct platform_device *pdev, return rc; } cpr_parse_cond_min_volt_fuse(cpr_vreg, of_node); if (cpr_vreg->flags & FLAGS_SET_MIN_VOLTAGE) { of_property_read_u32(of_node, "qti,cpr-cond-min-voltage", &min_uv); for (i = APC_PVS_SLOW; i < NUM_APC_PVS; i++) for (j = CPR_CORNER_SVS; j < CPR_CORNER_MAX; j++) if (cpr_vreg->pvs_corner_v[i][j] < min_uv) cpr_vreg->pvs_corner_v[i][j] = min_uv; } /* Set ceiling max and use it for APC_PVS_NO */ cpr_vreg->ceiling_max = cpr_vreg->pvs_corner_v[APC_PVS_SLOW][CPR_CORNER_TURBO]; Loading