Loading drivers/gpu/drm/msm/sde_rsc.c +70 −42 Original line number Diff line number Diff line Loading @@ -388,7 +388,7 @@ static int sde_rsc_switch_to_idle(struct sde_rsc_priv *rsc) static int sde_rsc_switch_to_cmd(struct sde_rsc_priv *rsc, struct sde_rsc_cmd_config *config, struct sde_rsc_client *caller_client, bool wait_req) struct sde_rsc_client *caller_client) { struct sde_rsc_client *client; int rc = STATE_UPDATE_NOT_ALLOWED; Loading Loading @@ -416,8 +416,8 @@ static int sde_rsc_switch_to_cmd(struct sde_rsc_priv *rsc, if (rsc->hw_ops.state_update) rc = rsc->hw_ops.state_update(rsc, SDE_RSC_CMD_STATE); /* wait for vsync */ if (!rc && wait_req) /* wait for vsync for vid to cmd state switch */ if (!rc && (rsc->current_state == SDE_RSC_VID_STATE)) drm_wait_one_vblank(rsc->master_drm, rsc->primary_client->crtc_id); end: Loading @@ -436,13 +436,19 @@ static bool sde_rsc_switch_to_clk(struct sde_rsc_priv *rsc) if (rsc->hw_ops.state_update) rc = rsc->hw_ops.state_update(rsc, SDE_RSC_CLK_STATE); /* wait for vsync for cmd to clk state switch */ if (!rc && rsc->primary_client && (rsc->current_state == SDE_RSC_CMD_STATE)) drm_wait_one_vblank(rsc->master_drm, rsc->primary_client->crtc_id); end: return rc; } static bool sde_rsc_switch_to_vid(struct sde_rsc_priv *rsc, struct sde_rsc_cmd_config *config, struct sde_rsc_client *caller_client, bool wait_req) struct sde_rsc_client *caller_client) { int rc = 0; Loading @@ -454,8 +460,9 @@ static bool sde_rsc_switch_to_vid(struct sde_rsc_priv *rsc, if (rsc->hw_ops.state_update) rc = rsc->hw_ops.state_update(rsc, SDE_RSC_VID_STATE); /* wait for vsync */ if (!rc && rsc->primary_client && wait_req) /* wait for vsync for cmd to vid state switch */ if (!rc && rsc->primary_client && (rsc->current_state == SDE_RSC_CMD_STATE)) drm_wait_one_vblank(rsc->master_drm, rsc->primary_client->crtc_id); return rc; Loading @@ -481,7 +488,6 @@ int sde_rsc_client_state_update(struct sde_rsc_client *caller_client, { int rc = 0; struct sde_rsc_priv *rsc; bool wait_requested = false; if (!caller_client) { pr_err("invalid client for rsc state update\n"); Loading Loading @@ -512,11 +518,7 @@ int sde_rsc_client_state_update(struct sde_rsc_client *caller_client, __builtin_return_address(0), rsc->current_state, caller_client->name, state); /* only switch state needs vsync wait */ wait_requested = (rsc->current_state == SDE_RSC_VID_STATE) || (rsc->current_state == SDE_RSC_CMD_STATE); if (rsc->power_collapse) if (rsc->current_state == SDE_RSC_IDLE_STATE) sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true); switch (state) { Loading @@ -526,7 +528,7 @@ int sde_rsc_client_state_update(struct sde_rsc_client *caller_client, /* video state client might be exiting; try cmd state switch */ if (rc == TRY_CMD_MODE_SWITCH) { rc = sde_rsc_switch_to_cmd(rsc, NULL, rsc->primary_client, wait_requested); rsc->primary_client); if (!rc) state = SDE_RSC_CMD_STATE; Loading @@ -539,13 +541,11 @@ int sde_rsc_client_state_update(struct sde_rsc_client *caller_client, break; case SDE_RSC_CMD_STATE: rc = sde_rsc_switch_to_cmd(rsc, config, caller_client, wait_requested); rc = sde_rsc_switch_to_cmd(rsc, config, caller_client); break; case SDE_RSC_VID_STATE: rc = sde_rsc_switch_to_vid(rsc, config, caller_client, wait_requested); rc = sde_rsc_switch_to_vid(rsc, config, caller_client); break; case SDE_RSC_CLK_STATE: Loading @@ -561,7 +561,7 @@ int sde_rsc_client_state_update(struct sde_rsc_client *caller_client, rc = 0; goto clk_disable; } else if (rc) { pr_err("state update failed rc:%d\n", rc); pr_debug("state:%d update failed rc:%d\n", state, rc); goto clk_disable; } Loading @@ -569,7 +569,7 @@ int sde_rsc_client_state_update(struct sde_rsc_client *caller_client, rsc->current_state = state; clk_disable: if (rsc->power_collapse) if (rsc->current_state == SDE_RSC_IDLE_STATE) sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false); end: mutex_unlock(&rsc->client_lock); Loading Loading @@ -615,14 +615,9 @@ int sde_rsc_client_vote(struct sde_rsc_client *caller_client, caller_client->name, ab_vote, ib_vote); mutex_lock(&rsc->client_lock); if ((caller_client->current_state == SDE_RSC_IDLE_STATE) || (rsc->current_state == SDE_RSC_IDLE_STATE)) { pr_err("invalid state: client state:%d rsc state:%d\n", caller_client->current_state, rsc->current_state); rc = -EINVAL; goto end; } rc = sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true); if (rc) goto clk_enable_fail; if (rsc->hw_ops.is_amc_mode) amc_mode = rsc->hw_ops.is_amc_mode(rsc); Loading @@ -644,14 +639,19 @@ int sde_rsc_client_vote(struct sde_rsc_client *caller_client, } } rpmh_invalidate(rsc->disp_rsc); sde_power_data_bus_set_quota(&rsc->phandle, rsc->pclient, SDE_POWER_HANDLE_DATA_BUS_CLIENT_RT, ab_vote, ib_vote); rpmh_flush(rsc->disp_rsc); if (rsc->hw_ops.tcs_use_ok) rsc->hw_ops.tcs_use_ok(rsc); end: sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false); clk_enable_fail: mutex_unlock(&rsc->client_lock); return rc; } EXPORT_SYMBOL(sde_rsc_client_vote); Loading @@ -668,6 +668,10 @@ static int _sde_debugfs_status_show(struct seq_file *s, void *data) rsc = s->private; mutex_lock(&rsc->client_lock); ret = sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true); if (ret) goto end; seq_printf(s, "rsc current state:%d\n", rsc->current_state); seq_printf(s, "wraper backoff time(ns):%d\n", rsc->timer_config.static_wakeup_time_ns); Loading @@ -691,17 +695,15 @@ static int _sde_debugfs_status_show(struct seq_file *s, void *data) seq_printf(s, "\t client:%s state:%d\n", client->name, client->current_state); sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true); if (rsc->hw_ops.debug_show) { ret = rsc->hw_ops.debug_show(s, rsc); if (ret) pr_err("sde rsc: hw debug failed ret:%d\n", ret); } sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false); mutex_unlock(&rsc->client_lock); end: mutex_unlock(&rsc->client_lock); return 0; } Loading @@ -722,20 +724,23 @@ static ssize_t _sde_debugfs_mode_ctrl_read(struct file *file, char __user *buf, { struct sde_rsc_priv *rsc = file->private_data; char buffer[MAX_BUFFER_SIZE]; int blen = 0; int blen = 0, rc; if (*ppos || !rsc || !rsc->hw_ops.mode_ctrl) return 0; mutex_lock(&rsc->client_lock); sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true); rc = sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true); if (rc) goto end; blen = rsc->hw_ops.mode_ctrl(rsc, MODE_READ, buffer, MAX_BUFFER_SIZE, 0); sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false); mutex_unlock(&rsc->client_lock); end: mutex_unlock(&rsc->client_lock); if (blen < 0) return 0; Loading @@ -752,6 +757,7 @@ static ssize_t _sde_debugfs_mode_ctrl_write(struct file *file, struct sde_rsc_priv *rsc = file->private_data; char *input, *mode; u32 mode0_state = 0, mode1_state = 0, mode2_state = 0; int rc; if (!rsc || !rsc->hw_ops.mode_ctrl) return 0; Loading @@ -767,7 +773,9 @@ static ssize_t _sde_debugfs_mode_ctrl_write(struct file *file, input[count - 1] = '\0'; mutex_lock(&rsc->client_lock); sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true); rc = sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true); if (rc) goto clk_enable_fail; mode = strnstr(input, "mode0=", strlen("mode0=")); if (mode) { Loading @@ -794,9 +802,10 @@ static ssize_t _sde_debugfs_mode_ctrl_write(struct file *file, end: sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false); clk_enable_fail: mutex_unlock(&rsc->client_lock); pr_err("req: mode0:%d mode1:%d mode2:%d\n", mode0_state, mode1_state, pr_info("req: mode0:%d mode1:%d mode2:%d\n", mode0_state, mode1_state, mode2_state); kfree(input); return count; Loading @@ -814,20 +823,23 @@ static ssize_t _sde_debugfs_vsync_mode_read(struct file *file, char __user *buf, { struct sde_rsc_priv *rsc = file->private_data; char buffer[MAX_BUFFER_SIZE]; int blen = 0; int blen = 0, rc; if (*ppos || !rsc || !rsc->hw_ops.hw_vsync) return 0; mutex_lock(&rsc->client_lock); sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true); rc = sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true); if (rc) goto end; blen = rsc->hw_ops.hw_vsync(rsc, VSYNC_READ, buffer, MAX_BUFFER_SIZE, 0); sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false); mutex_unlock(&rsc->client_lock); end: mutex_unlock(&rsc->client_lock); if (blen < 0) return 0; Loading @@ -844,6 +856,7 @@ static ssize_t _sde_debugfs_vsync_mode_write(struct file *file, struct sde_rsc_priv *rsc = file->private_data; char *input, *vsync_mode; u32 vsync_state = 0; int rc; if (!rsc || !rsc->hw_ops.hw_vsync) return 0; Loading @@ -865,7 +878,9 @@ static ssize_t _sde_debugfs_vsync_mode_write(struct file *file, } mutex_lock(&rsc->client_lock); sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true); rc = sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true); if (rc) goto end; if (vsync_state) rsc->hw_ops.hw_vsync(rsc, VSYNC_ENABLE, NULL, Loading @@ -874,8 +889,9 @@ static ssize_t _sde_debugfs_vsync_mode_write(struct file *file, rsc->hw_ops.hw_vsync(rsc, VSYNC_DISABLE, NULL, 0, 0); sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false); mutex_unlock(&rsc->client_lock); end: mutex_unlock(&rsc->client_lock); kfree(input); return count; } Loading Loading @@ -930,6 +946,8 @@ static void sde_rsc_deinit(struct platform_device *pdev, msm_dss_iounmap(&rsc->wrapper_io); if (rsc->drv_io.base) msm_dss_iounmap(&rsc->drv_io); if (rsc->disp_rsc) rpmh_release(rsc->disp_rsc); if (rsc->pclient) sde_power_client_destroy(&rsc->phandle, rsc->pclient); Loading Loading @@ -1038,6 +1056,17 @@ static int sde_rsc_probe(struct platform_device *pdev) goto sde_rsc_fail; } rsc->disp_rsc = rpmh_get_byname(pdev, "disp_rsc"); if (IS_ERR_OR_NULL(rsc->disp_rsc)) { ret = PTR_ERR(rsc->disp_rsc); rsc->disp_rsc = NULL; pr_err("sde rsc:get display rsc failed ret:%d\n", ret); goto sde_rsc_fail; } rpmh_invalidate(rsc->disp_rsc); /* call flush to disable the disp rsc interrupt */ rpmh_flush(rsc->disp_rsc); ret = msm_dss_ioremap_byname(pdev, &rsc->wrapper_io, "wrapper"); if (ret) { pr_err("sde rsc: wrapper io data mapping failed ret=%d\n", ret); Loading Loading @@ -1084,7 +1113,6 @@ static int sde_rsc_probe(struct platform_device *pdev) snprintf(name, MAX_RSC_CLIENT_NAME_LEN, "%s%d", "sde_rsc", counter); _sde_rsc_init_debugfs(rsc, name); counter++; rsc->power_collapse = true; ret = component_add(&pdev->dev, &sde_rsc_comp_ops); if (ret) Loading drivers/gpu/drm/msm/sde_rsc_hw.c +32 −13 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ #define SDE_RSCC_AMC_TCS_MODE_IRQ_STATUS_DRV0 0x1c00 #define SDE_RSCC_SOFT_WAKEUP_TIME_LO_DRV0 0xc04 #define SDE_RSCC_SOFT_WAKEUP_TIME_HI_DRV0 0xc08 #define SDE_RSCC_MAX_IDLE_DURATION_DRV0 0xc0c #define SDE_RSC_SOLVER_TIME_SLOT_TABLE_0_DRV0 0x1000 #define SDE_RSC_SOLVER_TIME_SLOT_TABLE_1_DRV0 0x1004 Loading Loading @@ -224,7 +225,9 @@ static int rsc_hw_solver_init(struct sde_rsc_priv *rsc) pr_debug("rsc solver init\n"); dss_reg_w(&rsc->drv_io, SDE_RSCC_SOFT_WAKEUP_TIME_LO_DRV0, 0x7FFFFFFF, rsc->debug_mode); 0xFFFFFFFF, rsc->debug_mode); dss_reg_w(&rsc->drv_io, SDE_RSCC_SOFT_WAKEUP_TIME_HI_DRV0, 0xFFFFFFFF, rsc->debug_mode); dss_reg_w(&rsc->drv_io, SDE_RSCC_MAX_IDLE_DURATION_DRV0, 0xEFFFFFFF, rsc->debug_mode); Loading Loading @@ -308,6 +311,15 @@ int sde_rsc_mode2_entry(struct sde_rsc_priv *rsc) rsc_event_trigger(rsc, SDE_RSC_EVENT_PRE_CORE_PC); /* update qtimers to high during clk & video mode state */ if ((rsc->current_state == SDE_RSC_VID_STATE) || (rsc->current_state == SDE_RSC_CLK_STATE)) { dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F0_QTMR_V1_CNTP_CVAL_HI, 0xffffffff, rsc->debug_mode); dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F0_QTMR_V1_CNTP_CVAL_LO, 0xffffffff, rsc->debug_mode); } wrapper_status = dss_reg_r(&rsc->wrapper_io, SDE_RSCC_WRAPPER_CTRL, rsc->debug_mode); wrapper_status |= BIT(3); Loading Loading @@ -357,8 +369,6 @@ int sde_rsc_mode2_entry(struct sde_rsc_priv *rsc) return 0; end: regulator_set_mode(rsc->fs, REGULATOR_MODE_NORMAL); rsc_event_trigger(rsc, SDE_RSC_EVENT_POST_CORE_RESTORE); return rc; Loading @@ -378,8 +388,7 @@ int sde_rsc_mode2_exit(struct sde_rsc_priv *rsc, enum sde_rsc_state state) if ((state == SDE_RSC_VID_STATE) || (state == SDE_RSC_CLK_STATE)) { reg = dss_reg_r(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL, rsc->debug_mode); reg |= BIT(8); reg &= ~(BIT(1) | BIT(0)); reg &= ~(BIT(8) | BIT(0)); dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL, reg, rsc->debug_mode); } Loading Loading @@ -411,7 +420,7 @@ int sde_rsc_mode2_exit(struct sde_rsc_priv *rsc, enum sde_rsc_state state) rc = 0; break; } usleep_range(1, 2); usleep_range(10, 100); } reg = dss_reg_r(&rsc->wrapper_io, SDE_RSCC_SPARE_PWR_EVENT, Loading @@ -419,14 +428,9 @@ int sde_rsc_mode2_exit(struct sde_rsc_priv *rsc, enum sde_rsc_state state) reg &= ~BIT(13); dss_reg_w(&rsc->wrapper_io, SDE_RSCC_SPARE_PWR_EVENT, reg, rsc->debug_mode); if (rc) pr_err("vdd reg is not enabled yet\n"); rc = regulator_set_mode(rsc->fs, REGULATOR_MODE_NORMAL); if (rc) pr_err("vdd reg normal mode set failed rc:%d\n", rc); rsc_event_trigger(rsc, SDE_RSC_EVENT_POST_CORE_RESTORE); return rc; Loading Loading @@ -454,6 +458,9 @@ static int sde_rsc_state_update(struct sde_rsc_priv *rsc, 0x1, rsc->debug_mode); dss_reg_w(&rsc->drv_io, SDE_RSCC_SOLVER_OVERRIDE_CTRL_DRV0, 0x0, rsc->debug_mode); dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_SOLVER_MODES_ENABLED_DRV0, 0x7, rsc->debug_mode); reg = dss_reg_r(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL, rsc->debug_mode); reg |= (BIT(0) | BIT(8)); Loading @@ -477,8 +484,9 @@ static int sde_rsc_state_update(struct sde_rsc_priv *rsc, reg &= ~(BIT(1) | BIT(0)); dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL, reg, rsc->debug_mode); dss_reg_w(&rsc->drv_io, SDE_RSCC_SOLVER_OVERRIDE_CTRL_DRV0, 0x1, rsc->debug_mode); dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_SOLVER_MODES_ENABLED_DRV0, 0x5, rsc->debug_mode); /* make sure that solver mode is override */ wmb(); Loading @@ -487,6 +495,17 @@ static int sde_rsc_state_update(struct sde_rsc_priv *rsc, case SDE_RSC_CLK_STATE: pr_debug("clk state handling\n"); reg = dss_reg_r(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL, rsc->debug_mode); reg &= ~(BIT(8) | BIT(0)); dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL, reg, rsc->debug_mode); dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_SOLVER_MODES_ENABLED_DRV0, 0x5, rsc->debug_mode); /* make sure that solver mode is disabled */ wmb(); break; case SDE_RSC_IDLE_STATE: Loading drivers/gpu/drm/msm/sde_rsc_priv.h +2 −0 Original line number Diff line number Diff line Loading @@ -111,6 +111,7 @@ struct sde_rsc_timer_config { * @pclient: module power client of phandle * @fs: "MDSS GDSC" handle * * @disp_rsc: display rsc handle * @drv_io: sde drv io data mapping * @wrapper_io: wrapper io data mapping * Loading Loading @@ -141,6 +142,7 @@ struct sde_rsc_priv { struct sde_power_client *pclient; struct regulator *fs; struct rpmh_client *disp_rsc; struct dss_io_data drv_io; struct dss_io_data wrapper_io; Loading Loading
drivers/gpu/drm/msm/sde_rsc.c +70 −42 Original line number Diff line number Diff line Loading @@ -388,7 +388,7 @@ static int sde_rsc_switch_to_idle(struct sde_rsc_priv *rsc) static int sde_rsc_switch_to_cmd(struct sde_rsc_priv *rsc, struct sde_rsc_cmd_config *config, struct sde_rsc_client *caller_client, bool wait_req) struct sde_rsc_client *caller_client) { struct sde_rsc_client *client; int rc = STATE_UPDATE_NOT_ALLOWED; Loading Loading @@ -416,8 +416,8 @@ static int sde_rsc_switch_to_cmd(struct sde_rsc_priv *rsc, if (rsc->hw_ops.state_update) rc = rsc->hw_ops.state_update(rsc, SDE_RSC_CMD_STATE); /* wait for vsync */ if (!rc && wait_req) /* wait for vsync for vid to cmd state switch */ if (!rc && (rsc->current_state == SDE_RSC_VID_STATE)) drm_wait_one_vblank(rsc->master_drm, rsc->primary_client->crtc_id); end: Loading @@ -436,13 +436,19 @@ static bool sde_rsc_switch_to_clk(struct sde_rsc_priv *rsc) if (rsc->hw_ops.state_update) rc = rsc->hw_ops.state_update(rsc, SDE_RSC_CLK_STATE); /* wait for vsync for cmd to clk state switch */ if (!rc && rsc->primary_client && (rsc->current_state == SDE_RSC_CMD_STATE)) drm_wait_one_vblank(rsc->master_drm, rsc->primary_client->crtc_id); end: return rc; } static bool sde_rsc_switch_to_vid(struct sde_rsc_priv *rsc, struct sde_rsc_cmd_config *config, struct sde_rsc_client *caller_client, bool wait_req) struct sde_rsc_client *caller_client) { int rc = 0; Loading @@ -454,8 +460,9 @@ static bool sde_rsc_switch_to_vid(struct sde_rsc_priv *rsc, if (rsc->hw_ops.state_update) rc = rsc->hw_ops.state_update(rsc, SDE_RSC_VID_STATE); /* wait for vsync */ if (!rc && rsc->primary_client && wait_req) /* wait for vsync for cmd to vid state switch */ if (!rc && rsc->primary_client && (rsc->current_state == SDE_RSC_CMD_STATE)) drm_wait_one_vblank(rsc->master_drm, rsc->primary_client->crtc_id); return rc; Loading @@ -481,7 +488,6 @@ int sde_rsc_client_state_update(struct sde_rsc_client *caller_client, { int rc = 0; struct sde_rsc_priv *rsc; bool wait_requested = false; if (!caller_client) { pr_err("invalid client for rsc state update\n"); Loading Loading @@ -512,11 +518,7 @@ int sde_rsc_client_state_update(struct sde_rsc_client *caller_client, __builtin_return_address(0), rsc->current_state, caller_client->name, state); /* only switch state needs vsync wait */ wait_requested = (rsc->current_state == SDE_RSC_VID_STATE) || (rsc->current_state == SDE_RSC_CMD_STATE); if (rsc->power_collapse) if (rsc->current_state == SDE_RSC_IDLE_STATE) sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true); switch (state) { Loading @@ -526,7 +528,7 @@ int sde_rsc_client_state_update(struct sde_rsc_client *caller_client, /* video state client might be exiting; try cmd state switch */ if (rc == TRY_CMD_MODE_SWITCH) { rc = sde_rsc_switch_to_cmd(rsc, NULL, rsc->primary_client, wait_requested); rsc->primary_client); if (!rc) state = SDE_RSC_CMD_STATE; Loading @@ -539,13 +541,11 @@ int sde_rsc_client_state_update(struct sde_rsc_client *caller_client, break; case SDE_RSC_CMD_STATE: rc = sde_rsc_switch_to_cmd(rsc, config, caller_client, wait_requested); rc = sde_rsc_switch_to_cmd(rsc, config, caller_client); break; case SDE_RSC_VID_STATE: rc = sde_rsc_switch_to_vid(rsc, config, caller_client, wait_requested); rc = sde_rsc_switch_to_vid(rsc, config, caller_client); break; case SDE_RSC_CLK_STATE: Loading @@ -561,7 +561,7 @@ int sde_rsc_client_state_update(struct sde_rsc_client *caller_client, rc = 0; goto clk_disable; } else if (rc) { pr_err("state update failed rc:%d\n", rc); pr_debug("state:%d update failed rc:%d\n", state, rc); goto clk_disable; } Loading @@ -569,7 +569,7 @@ int sde_rsc_client_state_update(struct sde_rsc_client *caller_client, rsc->current_state = state; clk_disable: if (rsc->power_collapse) if (rsc->current_state == SDE_RSC_IDLE_STATE) sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false); end: mutex_unlock(&rsc->client_lock); Loading Loading @@ -615,14 +615,9 @@ int sde_rsc_client_vote(struct sde_rsc_client *caller_client, caller_client->name, ab_vote, ib_vote); mutex_lock(&rsc->client_lock); if ((caller_client->current_state == SDE_RSC_IDLE_STATE) || (rsc->current_state == SDE_RSC_IDLE_STATE)) { pr_err("invalid state: client state:%d rsc state:%d\n", caller_client->current_state, rsc->current_state); rc = -EINVAL; goto end; } rc = sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true); if (rc) goto clk_enable_fail; if (rsc->hw_ops.is_amc_mode) amc_mode = rsc->hw_ops.is_amc_mode(rsc); Loading @@ -644,14 +639,19 @@ int sde_rsc_client_vote(struct sde_rsc_client *caller_client, } } rpmh_invalidate(rsc->disp_rsc); sde_power_data_bus_set_quota(&rsc->phandle, rsc->pclient, SDE_POWER_HANDLE_DATA_BUS_CLIENT_RT, ab_vote, ib_vote); rpmh_flush(rsc->disp_rsc); if (rsc->hw_ops.tcs_use_ok) rsc->hw_ops.tcs_use_ok(rsc); end: sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false); clk_enable_fail: mutex_unlock(&rsc->client_lock); return rc; } EXPORT_SYMBOL(sde_rsc_client_vote); Loading @@ -668,6 +668,10 @@ static int _sde_debugfs_status_show(struct seq_file *s, void *data) rsc = s->private; mutex_lock(&rsc->client_lock); ret = sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true); if (ret) goto end; seq_printf(s, "rsc current state:%d\n", rsc->current_state); seq_printf(s, "wraper backoff time(ns):%d\n", rsc->timer_config.static_wakeup_time_ns); Loading @@ -691,17 +695,15 @@ static int _sde_debugfs_status_show(struct seq_file *s, void *data) seq_printf(s, "\t client:%s state:%d\n", client->name, client->current_state); sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true); if (rsc->hw_ops.debug_show) { ret = rsc->hw_ops.debug_show(s, rsc); if (ret) pr_err("sde rsc: hw debug failed ret:%d\n", ret); } sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false); mutex_unlock(&rsc->client_lock); end: mutex_unlock(&rsc->client_lock); return 0; } Loading @@ -722,20 +724,23 @@ static ssize_t _sde_debugfs_mode_ctrl_read(struct file *file, char __user *buf, { struct sde_rsc_priv *rsc = file->private_data; char buffer[MAX_BUFFER_SIZE]; int blen = 0; int blen = 0, rc; if (*ppos || !rsc || !rsc->hw_ops.mode_ctrl) return 0; mutex_lock(&rsc->client_lock); sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true); rc = sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true); if (rc) goto end; blen = rsc->hw_ops.mode_ctrl(rsc, MODE_READ, buffer, MAX_BUFFER_SIZE, 0); sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false); mutex_unlock(&rsc->client_lock); end: mutex_unlock(&rsc->client_lock); if (blen < 0) return 0; Loading @@ -752,6 +757,7 @@ static ssize_t _sde_debugfs_mode_ctrl_write(struct file *file, struct sde_rsc_priv *rsc = file->private_data; char *input, *mode; u32 mode0_state = 0, mode1_state = 0, mode2_state = 0; int rc; if (!rsc || !rsc->hw_ops.mode_ctrl) return 0; Loading @@ -767,7 +773,9 @@ static ssize_t _sde_debugfs_mode_ctrl_write(struct file *file, input[count - 1] = '\0'; mutex_lock(&rsc->client_lock); sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true); rc = sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true); if (rc) goto clk_enable_fail; mode = strnstr(input, "mode0=", strlen("mode0=")); if (mode) { Loading @@ -794,9 +802,10 @@ static ssize_t _sde_debugfs_mode_ctrl_write(struct file *file, end: sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false); clk_enable_fail: mutex_unlock(&rsc->client_lock); pr_err("req: mode0:%d mode1:%d mode2:%d\n", mode0_state, mode1_state, pr_info("req: mode0:%d mode1:%d mode2:%d\n", mode0_state, mode1_state, mode2_state); kfree(input); return count; Loading @@ -814,20 +823,23 @@ static ssize_t _sde_debugfs_vsync_mode_read(struct file *file, char __user *buf, { struct sde_rsc_priv *rsc = file->private_data; char buffer[MAX_BUFFER_SIZE]; int blen = 0; int blen = 0, rc; if (*ppos || !rsc || !rsc->hw_ops.hw_vsync) return 0; mutex_lock(&rsc->client_lock); sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true); rc = sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true); if (rc) goto end; blen = rsc->hw_ops.hw_vsync(rsc, VSYNC_READ, buffer, MAX_BUFFER_SIZE, 0); sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false); mutex_unlock(&rsc->client_lock); end: mutex_unlock(&rsc->client_lock); if (blen < 0) return 0; Loading @@ -844,6 +856,7 @@ static ssize_t _sde_debugfs_vsync_mode_write(struct file *file, struct sde_rsc_priv *rsc = file->private_data; char *input, *vsync_mode; u32 vsync_state = 0; int rc; if (!rsc || !rsc->hw_ops.hw_vsync) return 0; Loading @@ -865,7 +878,9 @@ static ssize_t _sde_debugfs_vsync_mode_write(struct file *file, } mutex_lock(&rsc->client_lock); sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true); rc = sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true); if (rc) goto end; if (vsync_state) rsc->hw_ops.hw_vsync(rsc, VSYNC_ENABLE, NULL, Loading @@ -874,8 +889,9 @@ static ssize_t _sde_debugfs_vsync_mode_write(struct file *file, rsc->hw_ops.hw_vsync(rsc, VSYNC_DISABLE, NULL, 0, 0); sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false); mutex_unlock(&rsc->client_lock); end: mutex_unlock(&rsc->client_lock); kfree(input); return count; } Loading Loading @@ -930,6 +946,8 @@ static void sde_rsc_deinit(struct platform_device *pdev, msm_dss_iounmap(&rsc->wrapper_io); if (rsc->drv_io.base) msm_dss_iounmap(&rsc->drv_io); if (rsc->disp_rsc) rpmh_release(rsc->disp_rsc); if (rsc->pclient) sde_power_client_destroy(&rsc->phandle, rsc->pclient); Loading Loading @@ -1038,6 +1056,17 @@ static int sde_rsc_probe(struct platform_device *pdev) goto sde_rsc_fail; } rsc->disp_rsc = rpmh_get_byname(pdev, "disp_rsc"); if (IS_ERR_OR_NULL(rsc->disp_rsc)) { ret = PTR_ERR(rsc->disp_rsc); rsc->disp_rsc = NULL; pr_err("sde rsc:get display rsc failed ret:%d\n", ret); goto sde_rsc_fail; } rpmh_invalidate(rsc->disp_rsc); /* call flush to disable the disp rsc interrupt */ rpmh_flush(rsc->disp_rsc); ret = msm_dss_ioremap_byname(pdev, &rsc->wrapper_io, "wrapper"); if (ret) { pr_err("sde rsc: wrapper io data mapping failed ret=%d\n", ret); Loading Loading @@ -1084,7 +1113,6 @@ static int sde_rsc_probe(struct platform_device *pdev) snprintf(name, MAX_RSC_CLIENT_NAME_LEN, "%s%d", "sde_rsc", counter); _sde_rsc_init_debugfs(rsc, name); counter++; rsc->power_collapse = true; ret = component_add(&pdev->dev, &sde_rsc_comp_ops); if (ret) Loading
drivers/gpu/drm/msm/sde_rsc_hw.c +32 −13 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ #define SDE_RSCC_AMC_TCS_MODE_IRQ_STATUS_DRV0 0x1c00 #define SDE_RSCC_SOFT_WAKEUP_TIME_LO_DRV0 0xc04 #define SDE_RSCC_SOFT_WAKEUP_TIME_HI_DRV0 0xc08 #define SDE_RSCC_MAX_IDLE_DURATION_DRV0 0xc0c #define SDE_RSC_SOLVER_TIME_SLOT_TABLE_0_DRV0 0x1000 #define SDE_RSC_SOLVER_TIME_SLOT_TABLE_1_DRV0 0x1004 Loading Loading @@ -224,7 +225,9 @@ static int rsc_hw_solver_init(struct sde_rsc_priv *rsc) pr_debug("rsc solver init\n"); dss_reg_w(&rsc->drv_io, SDE_RSCC_SOFT_WAKEUP_TIME_LO_DRV0, 0x7FFFFFFF, rsc->debug_mode); 0xFFFFFFFF, rsc->debug_mode); dss_reg_w(&rsc->drv_io, SDE_RSCC_SOFT_WAKEUP_TIME_HI_DRV0, 0xFFFFFFFF, rsc->debug_mode); dss_reg_w(&rsc->drv_io, SDE_RSCC_MAX_IDLE_DURATION_DRV0, 0xEFFFFFFF, rsc->debug_mode); Loading Loading @@ -308,6 +311,15 @@ int sde_rsc_mode2_entry(struct sde_rsc_priv *rsc) rsc_event_trigger(rsc, SDE_RSC_EVENT_PRE_CORE_PC); /* update qtimers to high during clk & video mode state */ if ((rsc->current_state == SDE_RSC_VID_STATE) || (rsc->current_state == SDE_RSC_CLK_STATE)) { dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F0_QTMR_V1_CNTP_CVAL_HI, 0xffffffff, rsc->debug_mode); dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F0_QTMR_V1_CNTP_CVAL_LO, 0xffffffff, rsc->debug_mode); } wrapper_status = dss_reg_r(&rsc->wrapper_io, SDE_RSCC_WRAPPER_CTRL, rsc->debug_mode); wrapper_status |= BIT(3); Loading Loading @@ -357,8 +369,6 @@ int sde_rsc_mode2_entry(struct sde_rsc_priv *rsc) return 0; end: regulator_set_mode(rsc->fs, REGULATOR_MODE_NORMAL); rsc_event_trigger(rsc, SDE_RSC_EVENT_POST_CORE_RESTORE); return rc; Loading @@ -378,8 +388,7 @@ int sde_rsc_mode2_exit(struct sde_rsc_priv *rsc, enum sde_rsc_state state) if ((state == SDE_RSC_VID_STATE) || (state == SDE_RSC_CLK_STATE)) { reg = dss_reg_r(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL, rsc->debug_mode); reg |= BIT(8); reg &= ~(BIT(1) | BIT(0)); reg &= ~(BIT(8) | BIT(0)); dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL, reg, rsc->debug_mode); } Loading Loading @@ -411,7 +420,7 @@ int sde_rsc_mode2_exit(struct sde_rsc_priv *rsc, enum sde_rsc_state state) rc = 0; break; } usleep_range(1, 2); usleep_range(10, 100); } reg = dss_reg_r(&rsc->wrapper_io, SDE_RSCC_SPARE_PWR_EVENT, Loading @@ -419,14 +428,9 @@ int sde_rsc_mode2_exit(struct sde_rsc_priv *rsc, enum sde_rsc_state state) reg &= ~BIT(13); dss_reg_w(&rsc->wrapper_io, SDE_RSCC_SPARE_PWR_EVENT, reg, rsc->debug_mode); if (rc) pr_err("vdd reg is not enabled yet\n"); rc = regulator_set_mode(rsc->fs, REGULATOR_MODE_NORMAL); if (rc) pr_err("vdd reg normal mode set failed rc:%d\n", rc); rsc_event_trigger(rsc, SDE_RSC_EVENT_POST_CORE_RESTORE); return rc; Loading Loading @@ -454,6 +458,9 @@ static int sde_rsc_state_update(struct sde_rsc_priv *rsc, 0x1, rsc->debug_mode); dss_reg_w(&rsc->drv_io, SDE_RSCC_SOLVER_OVERRIDE_CTRL_DRV0, 0x0, rsc->debug_mode); dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_SOLVER_MODES_ENABLED_DRV0, 0x7, rsc->debug_mode); reg = dss_reg_r(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL, rsc->debug_mode); reg |= (BIT(0) | BIT(8)); Loading @@ -477,8 +484,9 @@ static int sde_rsc_state_update(struct sde_rsc_priv *rsc, reg &= ~(BIT(1) | BIT(0)); dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL, reg, rsc->debug_mode); dss_reg_w(&rsc->drv_io, SDE_RSCC_SOLVER_OVERRIDE_CTRL_DRV0, 0x1, rsc->debug_mode); dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_SOLVER_MODES_ENABLED_DRV0, 0x5, rsc->debug_mode); /* make sure that solver mode is override */ wmb(); Loading @@ -487,6 +495,17 @@ static int sde_rsc_state_update(struct sde_rsc_priv *rsc, case SDE_RSC_CLK_STATE: pr_debug("clk state handling\n"); reg = dss_reg_r(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL, rsc->debug_mode); reg &= ~(BIT(8) | BIT(0)); dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL, reg, rsc->debug_mode); dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_SOLVER_MODES_ENABLED_DRV0, 0x5, rsc->debug_mode); /* make sure that solver mode is disabled */ wmb(); break; case SDE_RSC_IDLE_STATE: Loading
drivers/gpu/drm/msm/sde_rsc_priv.h +2 −0 Original line number Diff line number Diff line Loading @@ -111,6 +111,7 @@ struct sde_rsc_timer_config { * @pclient: module power client of phandle * @fs: "MDSS GDSC" handle * * @disp_rsc: display rsc handle * @drv_io: sde drv io data mapping * @wrapper_io: wrapper io data mapping * Loading Loading @@ -141,6 +142,7 @@ struct sde_rsc_priv { struct sde_power_client *pclient; struct regulator *fs; struct rpmh_client *disp_rsc; struct dss_io_data drv_io; struct dss_io_data wrapper_io; Loading