diff options
| -rw-r--r-- | arch/arm/boot/compressed/head.S | 2 | ||||
| -rw-r--r-- | arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi | 64 | ||||
| -rw-r--r-- | arch/arm/boot/dts/qcom/msmfalcon-rumi.dts | 26 | ||||
| -rw-r--r-- | arch/arm/boot/dts/qcom/msmfalcon-sim.dts | 26 | ||||
| -rw-r--r-- | arch/arm/boot/dts/qcom/msmfalcon.dtsi | 21 | ||||
| -rw-r--r-- | arch/arm/boot/dts/qcom/msmtriton.dtsi | 29 | ||||
| -rw-r--r-- | drivers/clk/msm/clock-osm.c | 6 | ||||
| -rw-r--r-- | drivers/clk/qcom/clk-rcg2.c | 2 | ||||
| -rw-r--r-- | drivers/clk/qcom/gpucc-msmfalcon.c | 8 | ||||
| -rw-r--r-- | drivers/platform/msm/gsi/gsi.c | 4 | ||||
| -rw-r--r-- | drivers/power/power_supply_sysfs.c | 1 | ||||
| -rw-r--r-- | drivers/power/qcom-charger/qpnp-fg-gen3.c | 33 | ||||
| -rw-r--r-- | drivers/power/qcom-charger/qpnp-smb2.c | 31 | ||||
| -rw-r--r-- | drivers/power/qcom-charger/smb-lib.c | 70 | ||||
| -rw-r--r-- | drivers/power/qcom-charger/smb-lib.h | 4 | ||||
| -rw-r--r-- | drivers/usb/pd/policy_engine.c | 187 | ||||
| -rw-r--r-- | include/linux/power_supply.h | 1 | ||||
| -rw-r--r-- | kernel/sched/hmp.c | 2 | ||||
| -rw-r--r-- | sound/usb/usb_audio_qmi_svc.c | 2 |
19 files changed, 401 insertions, 118 deletions
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index ae85dcdcb7df..d2e43b053d9b 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -776,7 +776,7 @@ __armv7_mmu_cache_on: orrne r0, r0, #1 @ MMU enabled movne r1, #0xfffffffd @ domain 0 = client bic r6, r6, #1 << 31 @ 32-bit translation system - bic r6, r6, #3 << 0 @ use only ttbr0 + bic r6, r6, #(7 << 0) | (1 << 4) @ use only ttbr0 mcrne p15, 0, r3, c2, c0, 0 @ load page table pointer mcrne p15, 0, r0, c8, c7, 0 @ flush I,D TLBs mcr p15, 0, r0, c7, c5, 4 @ ISB diff --git a/arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi index d28d09c2a527..e8c66871425d 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi @@ -48,5 +48,69 @@ output-low; }; }; + + /* SDC pin type */ + sdc1_clk_on: sdc1_clk_on { + config { + pins = "sdc1_clk"; + bias-disable; /* NO pull */ + drive-strength = <16>; /* 16 MA */ + }; + }; + + sdc1_clk_off: sdc1_clk_off { + config { + pins = "sdc1_clk"; + bias-disable; /* NO pull */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + sdc1_cmd_on: sdc1_cmd_on { + config { + pins = "sdc1_cmd"; + bias-pull-up; /* pull up */ + drive-strength = <10>; /* 10 MA */ + }; + }; + + sdc1_cmd_off: sdc1_cmd_off { + config { + pins = "sdc1_cmd"; + num-grp-pins = <1>; + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + sdc1_data_on: sdc1_data_on { + config { + pins = "sdc1_data"; + bias-pull-up; /* pull up */ + drive-strength = <10>; /* 10 MA */ + }; + }; + + sdc1_data_off: sdc1_data_off { + config { + pins = "sdc1_data"; + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + sdc1_rclk_on: sdc1_rclk_on { + config { + pins = "sdc1_rclk"; + bias-pull-down; /* pull down */ + }; + }; + + sdc1_rclk_off: sdc1_rclk_off { + config { + pins = "sdc1_rclk"; + bias-pull-down; /* pull down */ + }; + }; }; }; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts b/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts index 0d694a6cd9fa..f0ba8b115120 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts +++ b/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts @@ -27,3 +27,29 @@ pinctrl-names = "default"; pinctrl-0 = <&uart_console_active>; }; + +&sdhc_1 { + /* device core power supply */ + vdd-supply = <&pmfalcon_l4b>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <200 570000>; + + /* device communication power supply */ + vdd-io-supply = <&pmfalcon_l8a>; + qcom,vdd-io-always-on; + qcom,vdd-io-lpm-sup; + qcom,vdd-io-voltage-level = <1800000 1800000>; + qcom,vdd-io-current-level = <200 325000>; + + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on &sdc1_rclk_on>; + pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off &sdc1_rclk_off>; + + qcom,clk-rates = <400000 20000000 25000000 50000000 192000000 + 384000000>; + + qcom,nonremovable; + qcom,bus-speed-mode = "HS400_1p8v", "HS200_1p8v", "DDR_1p8v"; + + status = "ok"; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-sim.dts b/arch/arm/boot/dts/qcom/msmfalcon-sim.dts index eaaa1b407425..085419b7e108 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-sim.dts +++ b/arch/arm/boot/dts/qcom/msmfalcon-sim.dts @@ -27,3 +27,29 @@ pinctrl-names = "default"; pinctrl-0 = <&uart_console_active>; }; + +&sdhc_1 { + /* device core power supply */ + vdd-supply = <&pmfalcon_l4b>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <200 570000>; + + /* device communication power supply */ + vdd-io-supply = <&pmfalcon_l8a>; + qcom,vdd-io-always-on; + qcom,vdd-io-lpm-sup; + qcom,vdd-io-voltage-level = <1800000 1800000>; + qcom,vdd-io-current-level = <200 325000>; + + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on &sdc1_rclk_on>; + pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off &sdc1_rclk_off>; + + qcom,clk-rates = <400000 20000000 25000000 50000000 192000000 + 384000000>; + + qcom,nonremovable; + qcom,bus-speed-mode = "HS400_1p8v", "HS200_1p8v", "DDR_1p8v"; + + status = "ok"; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon.dtsi b/arch/arm/boot/dts/qcom/msmfalcon.dtsi index 10d5bbcc01e5..8e8c407734eb 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon.dtsi @@ -26,6 +26,7 @@ aliases { serial0 = &uartblsp1dm1; + sdhc1 = &sdhc_1; /* SDC1 eMMC slot */ }; chosen { @@ -403,6 +404,26 @@ #reset-cells = <1>; }; + sdhc_1: sdhci@c0c4000 { + compatible = "qcom,sdhci-msm-v5"; + reg = <0xc0c4000 0x1000>, <0xc0c5000 0x1000>; + reg-names = "hc_mem", "cmdq_mem"; + + interrupts = <0 129 0>, <0 227 0>; + interrupt-names = "hc_irq", "pwr_irq"; + + qcom,bus-width = <8>; + qcom,large-address-bus; + + qcom,devfreq,freq-table = <50000000 200000000>; + + clocks = <&clock_gcc GCC_SDCC1_AHB_CLK>, + <&clock_gcc GCC_SDCC1_APPS_CLK>; + clock-names = "iface_clk", "core_clk"; + + status = "disabled"; + }; + qcom,ipc-spinlock@1f40000 { compatible = "qcom,ipc-spinlock-sfpb"; reg = <0x1f40000 0x8000>; diff --git a/arch/arm/boot/dts/qcom/msmtriton.dtsi b/arch/arm/boot/dts/qcom/msmtriton.dtsi index 1dbefc555850..083c14af7839 100644 --- a/arch/arm/boot/dts/qcom/msmtriton.dtsi +++ b/arch/arm/boot/dts/qcom/msmtriton.dtsi @@ -580,6 +580,35 @@ qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_2_out 0 0>; status = "ok"; }; + + qcom,venus@cce0000 { + compatible = "qcom,pil-tz-generic"; + reg = <0xcce0000 0x4000>; + + vdd-supply = <&gdsc_venus>; + qcom,proxy-reg-names = "vdd"; + + clocks = <&clock_mmss MMSS_VIDEO_CORE_CLK>, + <&clock_mmss MMSS_VIDEO_AHB_CLK>, + <&clock_mmss MMSS_VIDEO_AXI_CLK>; + clock-names = "core_clk","iface_clk", + "bus_clk"; + qcom,proxy-clock-names = "core_clk", + "iface_clk","bus_clk"; + + qcom,msm-bus,name = "pil-venus"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 0 304000>; + + qcom,pas-id = <9>; + qcom,proxy-timeout-ms = <100>; + qcom,firmware-name = "venus"; + memory-region = <&venus_fw_mem>; + status = "ok"; + }; }; #include "msmtriton-ion.dtsi" diff --git a/drivers/clk/msm/clock-osm.c b/drivers/clk/msm/clock-osm.c index d29fd60719c9..a119c0b27321 100644 --- a/drivers/clk/msm/clock-osm.c +++ b/drivers/clk/msm/clock-osm.c @@ -1776,7 +1776,7 @@ static void clk_osm_setup_fsms(struct clk_osm *c) val = clk_osm_read_reg(c, DROOP_WAIT_TO_RELEASE_TIMER_CTRL0_REG); - val |= BVAL(31, 16, clk_osm_count_ns(c, 500)); + val |= BVAL(31, 16, clk_osm_count_ns(c, 250)); clk_osm_write_reg(c, val, DROOP_WAIT_TO_RELEASE_TIMER_CTRL0_REG); } @@ -1793,7 +1793,7 @@ static void clk_osm_setup_fsms(struct clk_osm *c) val = clk_osm_read_reg(c, DROOP_WAIT_TO_RELEASE_TIMER_CTRL0_REG); - val |= BVAL(15, 0, clk_osm_count_ns(c, 15000)); + val |= BVAL(15, 0, clk_osm_count_ns(c, 250)); clk_osm_write_reg(c, val, DROOP_WAIT_TO_RELEASE_TIMER_CTRL0_REG); } @@ -1807,7 +1807,7 @@ static void clk_osm_setup_fsms(struct clk_osm *c) if (c->wfx_fsm_en || c->ps_fsm_en || c->droop_fsm_en) { clk_osm_write_reg(c, 0x1, DROOP_PROG_SYNC_DELAY_REG); - clk_osm_write_reg(c, clk_osm_count_ns(c, 500), + clk_osm_write_reg(c, clk_osm_count_ns(c, 5), DROOP_RELEASE_TIMER_CTRL); clk_osm_write_reg(c, clk_osm_count_ns(c, 500), DCVS_DROOP_TIMER_CTRL); diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 933a208392bd..6d12ddb3e245 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -935,6 +935,8 @@ static int clk_gfx3d_src_set_rate_and_parent(struct clk_hw *hw, } const struct clk_ops clk_gfx3d_src_ops = { + .enable = clk_rcg2_enable, + .disable = clk_rcg2_disable, .is_enabled = clk_rcg2_is_enabled, .get_parent = clk_rcg2_get_parent, .set_parent = clk_rcg2_set_parent, diff --git a/drivers/clk/qcom/gpucc-msmfalcon.c b/drivers/clk/qcom/gpucc-msmfalcon.c index a2127e2629c7..f194abb471cd 100644 --- a/drivers/clk/qcom/gpucc-msmfalcon.c +++ b/drivers/clk/qcom/gpucc-msmfalcon.c @@ -84,12 +84,12 @@ static struct pll_vco gpu_vco[] = { { 250000000, 500000000, 3 }, }; -/* 640MHz configuration */ +/* 800MHz configuration */ static const struct pll_config gpu_pll0_config = { - .l = 0x21, + .l = 0x29, .config_ctl_val = 0x4001055b, - .alpha = 0x55555600, - .alpha_u = 0x55, + .alpha = 0xaaaaab00, + .alpha_u = 0xaa, .alpha_en_mask = BIT(24), .vco_val = 0x2 << 20, .vco_mask = 0x3 << 20, diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c index 352defe6204b..bd2132d77360 100644 --- a/drivers/platform/msm/gsi/gsi.c +++ b/drivers/platform/msm/gsi/gsi.c @@ -17,6 +17,7 @@ #include <linux/module.h> #include <linux/msm_gsi.h> #include <linux/platform_device.h> +#include <linux/delay.h> #include "gsi.h" #include "gsi_reg.h" @@ -26,6 +27,8 @@ #define GSI_MHI_ER_START 10 #define GSI_MHI_ER_END 16 +#define GSI_RESET_WA_MIN_SLEEP 1000 +#define GSI_RESET_WA_MAX_SLEEP 2000 static const struct of_device_id msm_gsi_match[] = { { .compatible = "qcom,msm_gsi", }, { }, @@ -1982,6 +1985,7 @@ reset: /* workaround: reset GSI producers again */ if (ctx->props.dir == GSI_CHAN_DIR_FROM_GSI && !reset_done) { + usleep_range(GSI_RESET_WA_MIN_SLEEP, GSI_RESET_WA_MAX_SLEEP); reset_done = true; goto reset; } diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c index ea2694c8c58d..2718ea93bd45 100644 --- a/drivers/power/power_supply_sysfs.c +++ b/drivers/power/power_supply_sysfs.c @@ -275,6 +275,7 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(charger_temp_max), POWER_SUPPLY_ATTR(parallel_disable), POWER_SUPPLY_ATTR(parallel_percent), + POWER_SUPPLY_ATTR(pe_start), /* Local extensions of type int64_t */ POWER_SUPPLY_ATTR(charge_counter_ext), /* Properties of type `const char *' */ diff --git a/drivers/power/qcom-charger/qpnp-fg-gen3.c b/drivers/power/qcom-charger/qpnp-fg-gen3.c index 30408218b7e7..c0a19ae115d0 100644 --- a/drivers/power/qcom-charger/qpnp-fg-gen3.c +++ b/drivers/power/qcom-charger/qpnp-fg-gen3.c @@ -1644,6 +1644,37 @@ out: return rc; } +static void fg_notify_charger(struct fg_chip *chip) +{ + union power_supply_propval prop = {0, }; + int rc; + + if (!is_charger_available(chip)) { + pr_warn("Charger not available yet?\n"); + return; + } + + prop.intval = chip->bp.float_volt_uv; + rc = power_supply_set_property(chip->batt_psy, + POWER_SUPPLY_PROP_VOLTAGE_MAX, &prop); + if (rc < 0) { + pr_err("Error in setting voltage_max property on batt_psy, rc=%d\n", + rc); + return; + } + + prop.intval = chip->bp.fastchg_curr_ma; + rc = power_supply_set_property(chip->batt_psy, + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, &prop); + if (rc < 0) { + pr_err("Error in setting constant_charge_current_max property on batt_psy, rc=%d\n", + rc); + return; + } + + fg_dbg(chip, FG_STATUS, "Notified charger on float voltage and FCC\n"); +} + static void profile_load_work(struct work_struct *work) { struct fg_chip *chip = container_of(work, @@ -1709,6 +1740,7 @@ done: rc); } + fg_notify_charger(chip); chip->profile_loaded = true; fg_dbg(chip, FG_STATUS, "profile loaded successfully"); out: @@ -1798,6 +1830,7 @@ static int fg_psy_get_property(struct power_supply *psy, break; case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: pval->intval = chip->bp.float_volt_uv; + break; case POWER_SUPPLY_PROP_CYCLE_COUNT: pval->intval = fg_get_cycle_count(chip); break; diff --git a/drivers/power/qcom-charger/qpnp-smb2.c b/drivers/power/qcom-charger/qpnp-smb2.c index dee554b6e150..93965dbe99ae 100644 --- a/drivers/power/qcom-charger/qpnp-smb2.c +++ b/drivers/power/qcom-charger/qpnp-smb2.c @@ -351,6 +351,7 @@ static enum power_supply_property smb2_usb_props[] = { POWER_SUPPLY_PROP_PD_ACTIVE, POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, POWER_SUPPLY_PROP_INPUT_CURRENT_NOW, + POWER_SUPPLY_PROP_PE_START, }; static int smb2_usb_get_prop(struct power_supply *psy, @@ -422,6 +423,9 @@ static int smb2_usb_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_PD_USB_SUSPEND_SUPPORTED: val->intval = chg->system_suspend_supported; break; + case POWER_SUPPLY_PROP_PE_START: + rc = smblib_get_pe_start(chg, val); + break; default: pr_err("get prop %d is not supported\n", psp); rc = -EINVAL; @@ -633,13 +637,16 @@ static enum power_supply_property smb2_batt_props[] = { POWER_SUPPLY_PROP_CHARGER_TEMP_MAX, POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED, POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_VOLTAGE_MAX, POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, POWER_SUPPLY_PROP_TEMP, POWER_SUPPLY_PROP_TECHNOLOGY, POWER_SUPPLY_PROP_STEP_CHARGING_ENABLED, POWER_SUPPLY_PROP_STEP_CHARGING_STEP, POWER_SUPPLY_PROP_CHARGE_DONE, POWER_SUPPLY_PROP_PARALLEL_DISABLE, + POWER_SUPPLY_PROP_PARALLEL_PERCENT, }; static int smb2_batt_get_prop(struct power_supply *psy, @@ -679,6 +686,7 @@ static int smb2_batt_get_prop(struct power_supply *psy, break; case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED: rc = smblib_get_prop_input_current_limited(chg, val); + break; case POWER_SUPPLY_PROP_STEP_CHARGING_ENABLED: val->intval = chg->step_chg_enabled; break; @@ -688,9 +696,16 @@ static int smb2_batt_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_VOLTAGE_NOW: rc = smblib_get_prop_batt_voltage_now(chg, val); break; + case POWER_SUPPLY_PROP_VOLTAGE_MAX: + val->intval = get_client_vote(chg->fv_votable, DEFAULT_VOTER); + break; case POWER_SUPPLY_PROP_CURRENT_NOW: rc = smblib_get_prop_batt_current_now(chg, val); break; + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: + val->intval = get_client_vote(chg->fcc_max_votable, + DEFAULT_VOTER); + break; case POWER_SUPPLY_PROP_TEMP: rc = smblib_get_prop_batt_temp(chg, val); break; @@ -704,6 +719,9 @@ static int smb2_batt_get_prop(struct power_supply *psy, val->intval = get_client_vote(chg->pl_disable_votable, USER_VOTER); break; + case POWER_SUPPLY_PROP_PARALLEL_PERCENT: + val->intval = chg->pl.slave_pct; + break; default: pr_err("batt power supply prop %d not supported\n", psp); return -EINVAL; @@ -737,6 +755,18 @@ static int smb2_batt_set_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_PARALLEL_DISABLE: vote(chg->pl_disable_votable, USER_VOTER, (bool)val->intval, 0); break; + case POWER_SUPPLY_PROP_PARALLEL_PERCENT: + if (val->intval < 0 || val->intval > 100) + return -EINVAL; + chg->pl.slave_pct = val->intval; + rerun_election(chg->fcc_votable); + break; + case POWER_SUPPLY_PROP_VOLTAGE_MAX: + vote(chg->fv_votable, DEFAULT_VOTER, true, val->intval); + break; + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: + vote(chg->fcc_max_votable, DEFAULT_VOTER, true, val->intval); + break; default: rc = -EINVAL; } @@ -752,6 +782,7 @@ static int smb2_batt_prop_is_writeable(struct power_supply *psy, case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL: case POWER_SUPPLY_PROP_CAPACITY: case POWER_SUPPLY_PROP_PARALLEL_DISABLE: + case POWER_SUPPLY_PROP_PARALLEL_PERCENT: return 1; default: break; diff --git a/drivers/power/qcom-charger/smb-lib.c b/drivers/power/qcom-charger/smb-lib.c index bcdfdd459b3d..5785e42e0140 100644 --- a/drivers/power/qcom-charger/smb-lib.c +++ b/drivers/power/qcom-charger/smb-lib.c @@ -38,8 +38,8 @@ static bool is_secure(struct smb_charger *chg, int addr) { - /* assume everything above 0xC0 is secure */ - return (bool)((addr & 0xFF) >= 0xC0); + /* assume everything above 0xA0 is secure */ + return (bool)((addr & 0xFF) >= 0xA0); } int smblib_read(struct smb_charger *chg, u16 addr, u8 *val) @@ -152,7 +152,7 @@ static void smblib_split_fcc(struct smb_charger *chg, int total_ua, int *master_ua, int *slave_ua) { int rc, jeita_cc_delta_ua, step_cc_delta_ua, effective_total_ua, - hw_cc_delta_ua = 0; + slave_limited_ua, hw_cc_delta_ua = 0; rc = smblib_get_step_cc_delta(chg, &step_cc_delta_ua); if (rc < 0) { @@ -172,7 +172,8 @@ static void smblib_split_fcc(struct smb_charger *chg, int total_ua, } effective_total_ua = max(0, total_ua + hw_cc_delta_ua); - *slave_ua = (effective_total_ua * chg->pl.slave_pct) / 100; + slave_limited_ua = min(effective_total_ua, chg->input_limited_fcc_ua); + *slave_ua = (slave_limited_ua * chg->pl.slave_pct) / 100; *slave_ua = (*slave_ua * chg->pl.taper_pct) / 100; *master_ua = max(0, total_ua - *slave_ua); } @@ -470,9 +471,8 @@ static int try_rerun_apsd_for_hvdcp(struct smb_charger *chg) return 0; } -static int smblib_update_usb_type(struct smb_charger *chg) +static const struct apsd_result *smblib_update_usb_type(struct smb_charger *chg) { - int rc = 0; const struct apsd_result *apsd_result; /* if PD is active, APSD is disabled so won't have a valid result */ @@ -483,7 +483,7 @@ static int smblib_update_usb_type(struct smb_charger *chg) apsd_result = smblib_get_apsd_result(chg); chg->usb_psy_desc.type = apsd_result->pst; - return rc; + return apsd_result; } static int smblib_notifier_call(struct notifier_block *nb, @@ -592,7 +592,7 @@ static int smblib_fcc_vote_callback(struct votable *votable, void *data, { struct smb_charger *chg = data; union power_supply_propval pval = {0, }; - int rc, master_fcc_ua = total_fcc_ua, slave_fcc_ua; + int rc, master_fcc_ua = total_fcc_ua, slave_fcc_ua = 0; if (total_fcc_ua < 0) return 0; @@ -624,6 +624,11 @@ static int smblib_fcc_vote_callback(struct votable *votable, void *data, return rc; } + smblib_dbg(chg, PR_PARALLEL, "master_fcc=%d slave_fcc=%d distribution=(%d/%d)\n", + master_fcc_ua, slave_fcc_ua, + (master_fcc_ua * 100) / total_fcc_ua, + (slave_fcc_ua * 100) / total_fcc_ua); + return 0; } @@ -833,6 +838,9 @@ static int smblib_pl_disable_vote_callback(struct votable *votable, void *data, return rc; } + smblib_dbg(chg, PR_PARALLEL, "parallel charging %s\n", + pl_disable ? "disabled" : "enabled"); + return 0; } @@ -1758,7 +1766,7 @@ int smblib_get_prop_typec_power_role(struct smb_charger *chg, int smblib_get_prop_pd_allowed(struct smb_charger *chg, union power_supply_propval *val) { - val->intval = get_effective_result_locked(chg->pd_allowed_votable); + val->intval = get_effective_result(chg->pd_allowed_votable); return 0; } @@ -1784,6 +1792,19 @@ int smblib_get_prop_pd_in_hard_reset(struct smb_charger *chg, return 0; } +int smblib_get_pe_start(struct smb_charger *chg, + union power_supply_propval *val) +{ + /* + * hvdcp timeout voter is the last one to allow pd. Use its vote + * to indicate start of pe engine + */ + val->intval + = !get_client_vote_locked(chg->pd_disallowed_votable_indirect, + HVDCP_TIMEOUT_VOTER); + return 0; +} + /******************* * USB PSY SETTERS * * *****************/ @@ -1954,6 +1975,13 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, smblib_update_usb_type(chg); power_supply_changed(chg->usb_psy); + rc = smblib_masked_write(chg, TYPE_C_CFG_3_REG, EN_TRYSINK_MODE_BIT, + chg->pd_active ? 0 : EN_TRYSINK_MODE_BIT); + if (rc < 0) { + dev_err(chg->dev, "Couldn't set TRYSINK_MODE rc=%d\n", rc); + return rc; + } + return rc; } @@ -2187,12 +2215,14 @@ skip_dpdm_float: } #define USB_WEAK_INPUT_UA 1400000 +#define EFFICIENCY_PCT 80 irqreturn_t smblib_handle_icl_change(int irq, void *data) { struct smb_irq_data *irq_data = data; struct smb_charger *chg = irq_data->parent_data; int rc, icl_ua; + smblib_dbg(chg, PR_INTERRUPT, "IRQ: %s\n", irq_data->name); rc = smblib_get_charge_param(chg, &chg->param.icl_stat, &icl_ua); if (rc < 0) { @@ -2200,11 +2230,18 @@ irqreturn_t smblib_handle_icl_change(int irq, void *data) return IRQ_HANDLED; } - if (chg->mode == PARALLEL_MASTER) - vote(chg->pl_enable_votable_indirect, USBIN_I_VOTER, - icl_ua >= USB_WEAK_INPUT_UA, 0); + if (chg->mode != PARALLEL_MASTER) + return IRQ_HANDLED; - smblib_dbg(chg, PR_INTERRUPT, "IRQ: %s\n", irq_data->name); + chg->input_limited_fcc_ua = div64_s64( + (s64)icl_ua * MICRO_5V * EFFICIENCY_PCT, + (s64)get_effective_result(chg->fv_votable) * 100); + + if (!get_effective_result(chg->pl_disable_votable)) + rerun_election(chg->fcc_votable); + + vote(chg->pl_enable_votable_indirect, USBIN_I_VOTER, + icl_ua >= USB_WEAK_INPUT_UA, 0); return IRQ_HANDLED; } @@ -2280,13 +2317,12 @@ static void smblib_handle_hvdcp_detect_done(struct smb_charger *chg, #define HVDCP_DET_MS 2500 static void smblib_handle_apsd_done(struct smb_charger *chg, bool rising) { - int rc; const struct apsd_result *apsd_result; if (!rising) return; - apsd_result = smblib_get_apsd_result(chg); + apsd_result = smblib_update_usb_type(chg); switch (apsd_result->bit) { case SDP_CHARGER_BIT: case CDP_CHARGER_BIT: @@ -2305,10 +2341,6 @@ static void smblib_handle_apsd_done(struct smb_charger *chg, bool rising) break; } - rc = smblib_update_usb_type(chg); - if (rc < 0) - smblib_err(chg, "Couldn't update usb type rc=%d\n", rc); - smblib_dbg(chg, PR_INTERRUPT, "IRQ: apsd-done rising; %s detected\n", apsd_result->name); } diff --git a/drivers/power/qcom-charger/smb-lib.h b/drivers/power/qcom-charger/smb-lib.h index 9612b740d84f..4be06ffcfb25 100644 --- a/drivers/power/qcom-charger/smb-lib.h +++ b/drivers/power/qcom-charger/smb-lib.h @@ -22,6 +22,7 @@ enum print_reason { PR_INTERRUPT = BIT(0), PR_REGISTER = BIT(1), PR_MISC = BIT(2), + PR_PARALLEL = BIT(3), }; #define DEFAULT_VOTER "DEFAULT_VOTER" @@ -190,6 +191,7 @@ struct smb_charger { bool step_chg_enabled; bool is_hdc; bool chg_done; + int input_limited_fcc_ua; /* workaround flag */ u32 wa_flags; @@ -308,6 +310,8 @@ int smblib_get_prop_input_current_settled(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_pd_in_hard_reset(struct smb_charger *chg, union power_supply_propval *val); +int smblib_get_pe_start(struct smb_charger *chg, + union power_supply_propval *val); int smblib_get_prop_charger_temp(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_charger_temp_max(struct smb_charger *chg, diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c index 26c91e0ce163..a72c874f19a5 100644 --- a/drivers/usb/pd/policy_engine.c +++ b/drivers/usb/pd/policy_engine.c @@ -299,7 +299,6 @@ struct usbpd { enum power_supply_typec_mode typec_mode; enum power_supply_type psy_type; bool vbus_present; - bool pd_allowed; enum data_role current_dr; enum power_role current_pr; @@ -498,6 +497,7 @@ static void pd_send_hard_reset(struct usbpd *pd) ret = pd_phy_signal(HARD_RESET_SIG, 5); /* tHardResetComplete */ if (!ret) pd->hard_reset = true; + pd->in_pr_swap = false; } static void kick_sm(struct usbpd *pd, int ms) @@ -828,7 +828,15 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) } } - if (!pd->pd_allowed) + ret = power_supply_get_property(pd->usb_psy, + POWER_SUPPLY_PROP_PD_ALLOWED, &val); + if (ret) { + usbpd_err(&pd->dev, "Unable to read USB PROP_PD_ALLOWED: %d\n", + ret); + break; + } + + if (!val.intval) break; /* Reset protocol layer */ @@ -906,8 +914,6 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) break; case PE_SNK_TRANSITION_TO_DEFAULT: - pd->hard_reset = false; - if (pd->current_dr != DR_UFP) { extcon_set_cable_state_(pd->extcon, EXTCON_USB_HOST, 0); @@ -1455,6 +1461,7 @@ static void usbpd_sm(struct work_struct *w) power_supply_set_property(pd->usb_psy, POWER_SUPPLY_PROP_PD_IN_HARD_RESET, &val); + pd->in_pr_swap = false; reset_vdm_state(pd); if (pd->current_pr == PR_SINK) @@ -1822,6 +1829,12 @@ static void usbpd_sm(struct work_struct *w) break; case PE_SNK_TRANSITION_TO_DEFAULT: + pd->hard_reset = false; + + val.intval = 0; + power_supply_set_property(pd->usb_psy, + POWER_SUPPLY_PROP_PD_IN_HARD_RESET, &val); + if (pd->vbus_present) { usbpd_set_state(pd, PE_SNK_STARTUP); } else { @@ -2036,41 +2049,41 @@ static int psy_changed(struct notifier_block *nb, unsigned long evt, void *ptr) struct usbpd *pd = container_of(nb, struct usbpd, psy_nb); union power_supply_propval val; enum power_supply_typec_mode typec_mode; - bool do_work = false; int ret; if (ptr != pd->usb_psy || evt != PSY_EVENT_PROP_CHANGED) return 0; ret = power_supply_get_property(pd->usb_psy, - POWER_SUPPLY_PROP_PD_ALLOWED, &val); + POWER_SUPPLY_PROP_TYPEC_MODE, &val); if (ret) { - usbpd_err(&pd->dev, "Unable to read USB PROP_PD_ALLOWED: %d\n", - ret); + usbpd_err(&pd->dev, "Unable to read USB TYPEC_MODE: %d\n", ret); return ret; } - if (pd->pd_allowed != val.intval) - do_work = true; - pd->pd_allowed = val.intval; + typec_mode = val.intval; ret = power_supply_get_property(pd->usb_psy, - POWER_SUPPLY_PROP_PRESENT, &val); + POWER_SUPPLY_PROP_PE_START, &val); if (ret) { - usbpd_err(&pd->dev, "Unable to read USB PRESENT: %d\n", ret); + usbpd_err(&pd->dev, "Unable to read USB PROP_PE_START: %d\n", + ret); return ret; } - pd->vbus_present = val.intval; + /* Don't proceed if PE_START=0 as other props may still change */ + if (!val.intval && !pd->pd_connected && + typec_mode != POWER_SUPPLY_TYPEC_NONE) + return 0; ret = power_supply_get_property(pd->usb_psy, - POWER_SUPPLY_PROP_TYPEC_MODE, &val); + POWER_SUPPLY_PROP_PRESENT, &val); if (ret) { - usbpd_err(&pd->dev, "Unable to read USB TYPEC_MODE: %d\n", ret); + usbpd_err(&pd->dev, "Unable to read USB PRESENT: %d\n", ret); return ret; } - typec_mode = val.intval; + pd->vbus_present = val.intval; ret = power_supply_get_property(pd->usb_psy, POWER_SUPPLY_PROP_TYPE, &val); @@ -2079,91 +2092,87 @@ static int psy_changed(struct notifier_block *nb, unsigned long evt, void *ptr) return ret; } - if (pd->psy_type != val.intval) - do_work = true; pd->psy_type = val.intval; + if (pd->typec_mode == typec_mode) + return 0; + + pd->typec_mode = typec_mode; + usbpd_dbg(&pd->dev, "typec mode:%d present:%d type:%d orientation:%d\n", typec_mode, pd->vbus_present, pd->psy_type, usbpd_get_plug_orientation(pd)); - if (pd->typec_mode != typec_mode) { - pd->typec_mode = typec_mode; - do_work = true; - - switch (typec_mode) { - /* Disconnect */ - case POWER_SUPPLY_TYPEC_NONE: - if (pd->in_pr_swap) { - usbpd_dbg(&pd->dev, "Ignoring disconnect due to PR swap\n"); - do_work = false; - } + switch (typec_mode) { + /* Disconnect */ + case POWER_SUPPLY_TYPEC_NONE: + if (pd->in_pr_swap) { + usbpd_dbg(&pd->dev, "Ignoring disconnect due to PR swap\n"); + return 0; + } - /* - * Workaround for PMIC HW bug. - * - * During hard reset when VBUS goes to 0 the CC logic - * will report this as a disconnection. In those cases - * it can be ignored, however the downside is that - * pd->hard_reset can be momentarily true even when a - * non-PD capable source is attached, and can't be - * distinguished from a physical disconnect. In that - * case, allow for the common case of disconnecting - * from an SDP. - * - * The less common case is a PD-capable SDP which will - * result in a hard reset getting treated like a - * disconnect. We can live with this until the HW bug - * is fixed: in which disconnection won't be reported - * on VBUS loss alone unless pullup is also removed - * from CC. - */ - if (pd->psy_type != POWER_SUPPLY_TYPE_USB && - pd->current_state == - PE_SNK_TRANSITION_TO_DEFAULT) { - usbpd_dbg(&pd->dev, "Ignoring disconnect due to hard reset\n"); - do_work = false; - } + /* + * Workaround for PMIC HW bug. + * + * During hard reset when VBUS goes to 0 the CC logic + * will report this as a disconnection. In those cases + * it can be ignored, however the downside is that + * pd->hard_reset can be momentarily true even when a + * non-PD capable source is attached, and can't be + * distinguished from a physical disconnect. In that + * case, allow for the common case of disconnecting + * from an SDP. + * + * The less common case is a PD-capable SDP which will + * result in a hard reset getting treated like a + * disconnect. We can live with this until the HW bug + * is fixed: in which disconnection won't be reported + * on VBUS loss alone unless pullup is also removed + * from CC. + */ + if (pd->psy_type != POWER_SUPPLY_TYPE_USB && + pd->current_state == + PE_SNK_TRANSITION_TO_DEFAULT) { + usbpd_dbg(&pd->dev, "Ignoring disconnect due to hard reset\n"); + return 0; + } - break; + break; - /* Sink states */ - case POWER_SUPPLY_TYPEC_SOURCE_DEFAULT: - case POWER_SUPPLY_TYPEC_SOURCE_MEDIUM: - case POWER_SUPPLY_TYPEC_SOURCE_HIGH: - usbpd_info(&pd->dev, "Type-C Source (%s) connected\n", - src_current(typec_mode)); - pd->current_pr = PR_SINK; - pd->in_pr_swap = false; - break; + /* Sink states */ + case POWER_SUPPLY_TYPEC_SOURCE_DEFAULT: + case POWER_SUPPLY_TYPEC_SOURCE_MEDIUM: + case POWER_SUPPLY_TYPEC_SOURCE_HIGH: + usbpd_info(&pd->dev, "Type-C Source (%s) connected\n", + src_current(typec_mode)); + pd->current_pr = PR_SINK; + pd->in_pr_swap = false; + break; - /* Source states */ - case POWER_SUPPLY_TYPEC_SINK_POWERED_CABLE: - case POWER_SUPPLY_TYPEC_SINK: - usbpd_info(&pd->dev, "Type-C Sink%s connected\n", - typec_mode == POWER_SUPPLY_TYPEC_SINK ? - "" : " (powered)"); - pd->current_pr = PR_SRC; - pd->in_pr_swap = false; - break; + /* Source states */ + case POWER_SUPPLY_TYPEC_SINK_POWERED_CABLE: + case POWER_SUPPLY_TYPEC_SINK: + usbpd_info(&pd->dev, "Type-C Sink%s connected\n", + typec_mode == POWER_SUPPLY_TYPEC_SINK ? + "" : " (powered)"); + pd->current_pr = PR_SRC; + pd->in_pr_swap = false; + break; - case POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY: - usbpd_info(&pd->dev, "Type-C Debug Accessory connected\n"); - break; - case POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER: - usbpd_info(&pd->dev, "Type-C Analog Audio Adapter connected\n"); - break; - default: - usbpd_warn(&pd->dev, "Unsupported typec mode:%d\n", - typec_mode); - break; - } + case POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY: + usbpd_info(&pd->dev, "Type-C Debug Accessory connected\n"); + break; + case POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER: + usbpd_info(&pd->dev, "Type-C Analog Audio Adapter connected\n"); + break; + default: + usbpd_warn(&pd->dev, "Unsupported typec mode:%d\n", + typec_mode); + break; } - /* only queue state machine if CC state or PD_ALLOWED changes */ - if (do_work) - kick_sm(pd, 0); - + /* queue state machine due to CC state change */ + kick_sm(pd, 0); return 0; } diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index a8ccecf5799a..18e1a979db76 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -224,6 +224,7 @@ enum power_supply_property { POWER_SUPPLY_PROP_CHARGER_TEMP_MAX, POWER_SUPPLY_PROP_PARALLEL_DISABLE, POWER_SUPPLY_PROP_PARALLEL_PERCENT, + POWER_SUPPLY_PROP_PE_START, /* Local extensions of type int64_t */ POWER_SUPPLY_PROP_CHARGE_COUNTER_EXT, /* Properties of type `const char *' */ diff --git a/kernel/sched/hmp.c b/kernel/sched/hmp.c index b3dad1289ed4..7039eb8f1e63 100644 --- a/kernel/sched/hmp.c +++ b/kernel/sched/hmp.c @@ -201,7 +201,7 @@ int sched_update_freq_max_load(const cpumask_t *cpumask) entry = &max_load->freqs[i]; freq = costs[i].freq; hpct = get_freq_max_load(cpu, freq); - if (hpct <= 0 && hpct > 100) + if (hpct <= 0 || hpct > 100) hpct = 100; hfreq = div64_u64((u64)freq * hpct, 100); entry->hdemand = diff --git a/sound/usb/usb_audio_qmi_svc.c b/sound/usb/usb_audio_qmi_svc.c index 8337d11bad12..3a108eba3b01 100644 --- a/sound/usb/usb_audio_qmi_svc.c +++ b/sound/usb/usb_audio_qmi_svc.c @@ -50,7 +50,7 @@ #define IOVA_XFER_RING_MAX (IOVA_XFER_BUF_BASE - PAGE_SIZE) #define IOVA_XFER_BUF_MAX (0xfffff000 - PAGE_SIZE) -#define MAX_XFER_BUFF_LEN (2 * PAGE_SIZE) +#define MAX_XFER_BUFF_LEN (24 * PAGE_SIZE) struct iova_info { struct list_head list; |
