Loading drivers/gpu/drm/msm/sde_power_handle.c +52 −0 Original line number Original line Diff line number Diff line Loading @@ -765,6 +765,12 @@ int sde_power_resource_init(struct platform_device *pdev, } } } } if (of_find_property(pdev->dev.of_node, "qcom,dss-cx-ipeak", NULL)) phandle->dss_cx_ipeak = cx_ipeak_register(pdev->dev.of_node, "qcom,dss-cx-ipeak"); else pr_debug("cx ipeak client parse failed\n"); INIT_LIST_HEAD(&phandle->power_client_clist); INIT_LIST_HEAD(&phandle->power_client_clist); INIT_LIST_HEAD(&phandle->event_list); INIT_LIST_HEAD(&phandle->event_list); Loading Loading @@ -829,6 +835,9 @@ void sde_power_resource_deinit(struct platform_device *pdev, } } mutex_unlock(&phandle->phandle_lock); mutex_unlock(&phandle->phandle_lock); if (phandle->dss_cx_ipeak) cx_ipeak_unregister(phandle->dss_cx_ipeak); for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++) for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++) sde_power_data_bus_unregister(&phandle->data_bus_handle[i]); sde_power_data_bus_unregister(&phandle->data_bus_handle[i]); Loading Loading @@ -1069,11 +1078,47 @@ int sde_power_resource_is_enabled(struct sde_power_handle *phandle) return phandle->current_usecase_ndx != VOTE_INDEX_DISABLE; return phandle->current_usecase_ndx != VOTE_INDEX_DISABLE; } } int sde_cx_ipeak_vote(struct sde_power_handle *phandle, struct dss_clk *clock, u64 requested_clk_rate, u64 prev_clk_rate, bool enable_vote) { int ret = 0; u64 curr_core_clk_rate, max_core_clk_rate, prev_core_clk_rate; if (phandle->dss_cx_ipeak) { pr_debug("%pS->%s: Invalid input\n", __builtin_return_address(0), __func__); return -EINVAL; } if (strcmp("core_clk", clock->clk_name)) { pr_debug("Not a core clk , cx_ipeak vote not needed\n"); return -EINVAL; } curr_core_clk_rate = clock->rate; max_core_clk_rate = clock->max_rate; prev_core_clk_rate = prev_clk_rate; if (enable_vote && requested_clk_rate == max_core_clk_rate && curr_core_clk_rate != requested_clk_rate) ret = cx_ipeak_update(phandle->dss_cx_ipeak, true); else if (!enable_vote && requested_clk_rate != max_core_clk_rate && prev_core_clk_rate == max_core_clk_rate) ret = cx_ipeak_update(phandle->dss_cx_ipeak, false); if (ret) SDE_EVT32(ret, enable_vote, requested_clk_rate, curr_core_clk_rate, prev_core_clk_rate); return ret; } int sde_power_clk_set_rate(struct sde_power_handle *phandle, char *clock_name, int sde_power_clk_set_rate(struct sde_power_handle *phandle, char *clock_name, u64 rate) u64 rate) { { int i, rc = -EINVAL; int i, rc = -EINVAL; struct dss_module_power *mp; struct dss_module_power *mp; u64 prev_clk_rate, requested_clk_rate; if (!phandle) { if (!phandle) { pr_err("invalid input power handle\n"); pr_err("invalid input power handle\n"); Loading @@ -1087,8 +1132,15 @@ int sde_power_clk_set_rate(struct sde_power_handle *phandle, char *clock_name, (rate > mp->clk_config[i].max_rate)) (rate > mp->clk_config[i].max_rate)) rate = mp->clk_config[i].max_rate; rate = mp->clk_config[i].max_rate; prev_clk_rate = mp->clk_config[i].rate; requested_clk_rate = rate; sde_cx_ipeak_vote(phandle, &mp->clk_config[i], requested_clk_rate, prev_clk_rate, true); mp->clk_config[i].rate = rate; mp->clk_config[i].rate = rate; rc = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk); rc = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk); if (!rc) sde_cx_ipeak_vote(phandle, &mp->clk_config[i], requested_clk_rate, prev_clk_rate, false); break; break; } } } } Loading drivers/gpu/drm/msm/sde_power_handle.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,7 @@ #define SDE_POWER_HANDLE_CONT_SPLASH_BUS_AB_QUOTA 1800000000 #define SDE_POWER_HANDLE_CONT_SPLASH_BUS_AB_QUOTA 1800000000 #include <linux/sde_io_util.h> #include <linux/sde_io_util.h> #include <soc/qcom/cx_ipeak.h> /* event will be triggered before power handler disable */ /* event will be triggered before power handler disable */ #define SDE_POWER_EVENT_PRE_DISABLE 0x1 #define SDE_POWER_EVENT_PRE_DISABLE 0x1 Loading Loading @@ -165,6 +166,7 @@ struct sde_power_event { * @event_list: current power handle event list * @event_list: current power handle event list * @rsc_client: sde rsc client pointer * @rsc_client: sde rsc client pointer * @rsc_client_init: boolean to control rsc client create * @rsc_client_init: boolean to control rsc client create * @dss_cx_ipeak: client pointer for cx ipeak driver */ */ struct sde_power_handle { struct sde_power_handle { struct dss_module_power mp; struct dss_module_power mp; Loading @@ -178,6 +180,7 @@ struct sde_power_handle { struct list_head event_list; struct list_head event_list; struct sde_rsc_client *rsc_client; struct sde_rsc_client *rsc_client; bool rsc_client_init; bool rsc_client_init; struct cx_ipeak_client *dss_cx_ipeak; }; }; /** /** Loading Loading
drivers/gpu/drm/msm/sde_power_handle.c +52 −0 Original line number Original line Diff line number Diff line Loading @@ -765,6 +765,12 @@ int sde_power_resource_init(struct platform_device *pdev, } } } } if (of_find_property(pdev->dev.of_node, "qcom,dss-cx-ipeak", NULL)) phandle->dss_cx_ipeak = cx_ipeak_register(pdev->dev.of_node, "qcom,dss-cx-ipeak"); else pr_debug("cx ipeak client parse failed\n"); INIT_LIST_HEAD(&phandle->power_client_clist); INIT_LIST_HEAD(&phandle->power_client_clist); INIT_LIST_HEAD(&phandle->event_list); INIT_LIST_HEAD(&phandle->event_list); Loading Loading @@ -829,6 +835,9 @@ void sde_power_resource_deinit(struct platform_device *pdev, } } mutex_unlock(&phandle->phandle_lock); mutex_unlock(&phandle->phandle_lock); if (phandle->dss_cx_ipeak) cx_ipeak_unregister(phandle->dss_cx_ipeak); for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++) for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++) sde_power_data_bus_unregister(&phandle->data_bus_handle[i]); sde_power_data_bus_unregister(&phandle->data_bus_handle[i]); Loading Loading @@ -1069,11 +1078,47 @@ int sde_power_resource_is_enabled(struct sde_power_handle *phandle) return phandle->current_usecase_ndx != VOTE_INDEX_DISABLE; return phandle->current_usecase_ndx != VOTE_INDEX_DISABLE; } } int sde_cx_ipeak_vote(struct sde_power_handle *phandle, struct dss_clk *clock, u64 requested_clk_rate, u64 prev_clk_rate, bool enable_vote) { int ret = 0; u64 curr_core_clk_rate, max_core_clk_rate, prev_core_clk_rate; if (phandle->dss_cx_ipeak) { pr_debug("%pS->%s: Invalid input\n", __builtin_return_address(0), __func__); return -EINVAL; } if (strcmp("core_clk", clock->clk_name)) { pr_debug("Not a core clk , cx_ipeak vote not needed\n"); return -EINVAL; } curr_core_clk_rate = clock->rate; max_core_clk_rate = clock->max_rate; prev_core_clk_rate = prev_clk_rate; if (enable_vote && requested_clk_rate == max_core_clk_rate && curr_core_clk_rate != requested_clk_rate) ret = cx_ipeak_update(phandle->dss_cx_ipeak, true); else if (!enable_vote && requested_clk_rate != max_core_clk_rate && prev_core_clk_rate == max_core_clk_rate) ret = cx_ipeak_update(phandle->dss_cx_ipeak, false); if (ret) SDE_EVT32(ret, enable_vote, requested_clk_rate, curr_core_clk_rate, prev_core_clk_rate); return ret; } int sde_power_clk_set_rate(struct sde_power_handle *phandle, char *clock_name, int sde_power_clk_set_rate(struct sde_power_handle *phandle, char *clock_name, u64 rate) u64 rate) { { int i, rc = -EINVAL; int i, rc = -EINVAL; struct dss_module_power *mp; struct dss_module_power *mp; u64 prev_clk_rate, requested_clk_rate; if (!phandle) { if (!phandle) { pr_err("invalid input power handle\n"); pr_err("invalid input power handle\n"); Loading @@ -1087,8 +1132,15 @@ int sde_power_clk_set_rate(struct sde_power_handle *phandle, char *clock_name, (rate > mp->clk_config[i].max_rate)) (rate > mp->clk_config[i].max_rate)) rate = mp->clk_config[i].max_rate; rate = mp->clk_config[i].max_rate; prev_clk_rate = mp->clk_config[i].rate; requested_clk_rate = rate; sde_cx_ipeak_vote(phandle, &mp->clk_config[i], requested_clk_rate, prev_clk_rate, true); mp->clk_config[i].rate = rate; mp->clk_config[i].rate = rate; rc = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk); rc = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk); if (!rc) sde_cx_ipeak_vote(phandle, &mp->clk_config[i], requested_clk_rate, prev_clk_rate, false); break; break; } } } } Loading
drivers/gpu/drm/msm/sde_power_handle.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,7 @@ #define SDE_POWER_HANDLE_CONT_SPLASH_BUS_AB_QUOTA 1800000000 #define SDE_POWER_HANDLE_CONT_SPLASH_BUS_AB_QUOTA 1800000000 #include <linux/sde_io_util.h> #include <linux/sde_io_util.h> #include <soc/qcom/cx_ipeak.h> /* event will be triggered before power handler disable */ /* event will be triggered before power handler disable */ #define SDE_POWER_EVENT_PRE_DISABLE 0x1 #define SDE_POWER_EVENT_PRE_DISABLE 0x1 Loading Loading @@ -165,6 +166,7 @@ struct sde_power_event { * @event_list: current power handle event list * @event_list: current power handle event list * @rsc_client: sde rsc client pointer * @rsc_client: sde rsc client pointer * @rsc_client_init: boolean to control rsc client create * @rsc_client_init: boolean to control rsc client create * @dss_cx_ipeak: client pointer for cx ipeak driver */ */ struct sde_power_handle { struct sde_power_handle { struct dss_module_power mp; struct dss_module_power mp; Loading @@ -178,6 +180,7 @@ struct sde_power_handle { struct list_head event_list; struct list_head event_list; struct sde_rsc_client *rsc_client; struct sde_rsc_client *rsc_client; bool rsc_client_init; bool rsc_client_init; struct cx_ipeak_client *dss_cx_ipeak; }; }; /** /** Loading