diff --git a/Documentation/devicetree/bindings/display/msm/sde.txt b/Documentation/devicetree/bindings/display/msm/sde.txt index 7739a9cdef66..aaaf07588cc9 100644 --- a/Documentation/devicetree/bindings/display/msm/sde.txt +++ b/Documentation/devicetree/bindings/display/msm/sde.txt @@ -21,6 +21,7 @@ Required properties Optional properties: - clock-rate: List of clock rates in Hz. +- clock-max-rate: List of maximum clock rate in Hz that this device supports. - qcom,platform-supply-entries: A node that lists the elements of the supply. There can be more than one instance of this binding, in which case the entry would be appended with @@ -80,6 +81,7 @@ Example: "mmagic_clk", "vsync_clk"; clock-rate = <0>, <0>, <0>; + clock-max-rate= <0 320000000 0>; mmagic-supply = <&gdsc_mmagic_mdss>; vdd-supply = <&gdsc_mdss>; interrupt-parent = <&intc>; diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c index a706ef971ee9..9de81768d25f 100644 --- a/drivers/gpu/drm/msm/sde/sde_kms.c +++ b/drivers/gpu/drm/msm/sde/sde_kms.c @@ -32,8 +32,6 @@ static const char * const iommu_ports[] = { "mdp_0", }; -#define DEFAULT_MDP_SRC_CLK 300000000 - /** * Controls size of event log buffer. Specified as a power of 2. */ @@ -738,13 +736,6 @@ struct msm_kms *sde_kms_init(struct drm_device *dev) goto kms_destroy; } - rc = sde_power_clk_set_rate(&priv->phandle, "core_clk", - DEFAULT_MDP_SRC_CLK); - if (rc) { - SDE_ERROR("core clock set rate failed\n"); - goto clk_rate_err; - } - rc = sde_power_resource_enable(&priv->phandle, sde_kms->core_client, true); if (rc) { diff --git a/drivers/gpu/drm/msm/sde_power_handle.c b/drivers/gpu/drm/msm/sde_power_handle.c index 7385086b3005..cd5ee07d0cdc 100644 --- a/drivers/gpu/drm/msm/sde_power_handle.c +++ b/drivers/gpu/drm/msm/sde_power_handle.c @@ -221,6 +221,7 @@ static int sde_power_parse_dt_clock(struct platform_device *pdev, u32 i = 0, rc = 0; const char *clock_name; u32 clock_rate; + u32 clock_max_rate; if (!pdev || !mp) { pr_err("invalid input param pdev:%pK mp:%pK\n", pdev, mp); @@ -256,6 +257,11 @@ static int sde_power_parse_dt_clock(struct platform_device *pdev, mp->clk_config[i].type = DSS_CLK_AHB; else mp->clk_config[i].type = DSS_CLK_PCLK; + + clock_max_rate = 0; + of_property_read_u32_index(pdev->dev.of_node, "clock-max-rate", + i, &clock_max_rate); + mp->clk_config[i].max_rate = clock_max_rate; } clk_err: @@ -521,6 +527,10 @@ int sde_power_clk_set_rate(struct sde_power_handle *phandle, char *clock_name, for (i = 0; i < mp->num_clk; i++) { if (!strcmp(mp->clk_config[i].clk_name, clock_name)) { + if (mp->clk_config[i].max_rate && + (rate > mp->clk_config[i].max_rate)) + rate = mp->clk_config[i].max_rate; + mp->clk_config[i].rate = rate; rc = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk); break; diff --git a/include/linux/mdss_io_util.h b/include/linux/mdss_io_util.h index 6ad21e887877..5b2587b28737 100644 --- a/include/linux/mdss_io_util.h +++ b/include/linux/mdss_io_util.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012, 2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -77,6 +77,7 @@ struct dss_clk { char clk_name[32]; enum dss_clk_type type; unsigned long rate; + unsigned long max_rate; }; struct dss_module_power {