Merge "msm: mdss: Move bus scale table implementation to device-tree"
diff --git a/Documentation/devicetree/bindings/fb/mdss-mdp.txt b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
index f850659..a6face6 100644
--- a/Documentation/devicetree/bindings/fb/mdss-mdp.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
@@ -117,6 +117,39 @@
- "edp"
- "hdmi"
+Bus Scaling Data:
+- qcom,msm-bus,name: String property describing MDSS client.
+- qcom,msm-bus,num-cases: This is the the number of Bus Scaling use cases
+ defined in the vectors property. This must be
+ set to <3> for MDSS driver where use-case 0 is
+ used to take off MDSS BW votes from the system.
+ And use-case 1 & 2 are used in ping-pong fashion
+ to generate run-time BW requests.
+- qcom,msm-bus,active-only: A boolean flag indicating if it is active only.
+- qcom,msm-bus,num-paths: This represents the number of paths in each
+ Bus Scaling Usecase. This value depends on
+ how many number of AXI master ports are
+ dedicated to MDSS for particular chipset.
+- qcom,msm-bus,vectors-KBps: * A series of 4 cell properties, with a format
+ of (src, dst, ab, ib) which is defined at
+ Documentation/devicetree/bindings/arm/msm/msm_bus.txt
+ * Current values of src & dst are defined at
+ arch/arm/mach-msm/msm_bus_board.h
+ src values allowed for MDSS are:
+ 22 = MSM_BUS_MASTER_MDP_PORT0
+ 23 = MSM_BUS_MASTER_MDP_PORT1
+ dst values allowed for MDSS are:
+ 512 = MSM_BUS_SLAVE_EBI_CH0
+ ab: Represents aggregated bandwidth.
+ ib: Represents instantaneous bandwidth.
+ * Total number of 4 cell properties will be
+ (number of use-cases * number of paths).
+ * These values will be overridden by the driver
+ based on the run-time requirements. So initial
+ ab and ib values defined here are random and
+ bare no logic except for the use-case 0 where ab
+ and ib values needs to be 0.
+
Optional properties:
- vdd-cx-supply : Phandle for vdd CX regulator device node.
- batfet-supply : Phandle for battery FET regulator device node.
@@ -219,6 +252,15 @@
qcom,max-bandwidth-low-kbps = <2300000>;
qcom,max-bandwidth-high-kbps = <3000000>;
+ /* Bus Scale Settings */
+ qcom,msm-bus,name = "mdss_mdp";
+ qcom,msm-bus,num-cases = <3>;
+ qcom,msm-bus,num-paths = <2>;
+ qcom,msm-bus,vectors-KBps =
+ <22 512 0 0>, <23 512 0 0>,
+ <22 512 0 6400000>, <23 512 0 6400000>,
+ <22 512 0 6400000>, <23 512 0 6400000>;
+
qcom,max-clk-rate = <320000000>;
qcom,vbif-settings = <0x0004 0x00000001>,
<0x00D8 0x00000707>;
diff --git a/arch/arm/boot/dts/apq8084-mdss.dtsi b/arch/arm/boot/dts/apq8084-mdss.dtsi
index 0e771ce..bf0ea76 100644
--- a/arch/arm/boot/dts/apq8084-mdss.dtsi
+++ b/arch/arm/boot/dts/apq8084-mdss.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -24,6 +24,15 @@
qcom,max-bandwidth-low-kbps = <6000000>;
qcom,max-bandwidth-high-kbps = <6000000>;
+ /* Bus Scale Settings */
+ qcom,msm-bus,name = "mdss_mdp";
+ qcom,msm-bus,num-cases = <3>;
+ qcom,msm-bus,num-paths = <2>;
+ qcom,msm-bus,vectors-KBps =
+ <22 512 0 0>, <23 512 0 0>,
+ <22 512 0 6400000>, <23 512 0 6400000>,
+ <22 512 0 6400000>, <23 512 0 6400000>;
+
qcom,max-clk-rate = <320000000>;
qcom,mdss-pipe-vig-off = <0x00001200 0x00001600
diff --git a/arch/arm/boot/dts/msm8226-mdss.dtsi b/arch/arm/boot/dts/msm8226-mdss.dtsi
index 84bb234..1a80b4b 100644
--- a/arch/arm/boot/dts/msm8226-mdss.dtsi
+++ b/arch/arm/boot/dts/msm8226-mdss.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -21,6 +21,16 @@
qcom,max-bandwidth-low-kbps = <1660000>;
qcom,max-bandwidth-high-kbps = <1660000>;
+
+ /* Bus Scale Settings */
+ qcom,msm-bus,name = "mdss_mdp";
+ qcom,msm-bus,num-cases = <3>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <22 512 0 0>,
+ <22 512 0 6400000>,
+ <22 512 0 6400000>;
+
qcom,max-clk-rate = <200000000>;
qcom,mdss-pipe-vig-off = <0x00001200>;
qcom,mdss-pipe-rgb-off = <0x00001E00>;
diff --git a/arch/arm/boot/dts/msm8974-mdss.dtsi b/arch/arm/boot/dts/msm8974-mdss.dtsi
index bf330f3..c0241c7 100644
--- a/arch/arm/boot/dts/msm8974-mdss.dtsi
+++ b/arch/arm/boot/dts/msm8974-mdss.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -21,6 +21,16 @@
qcom,max-bandwidth-low-kbps = <2300000>;
qcom,max-bandwidth-high-kbps = <3000000>;
+
+ /* Bus Scale Settings */
+ qcom,msm-bus,name = "mdss_mdp";
+ qcom,msm-bus,num-cases = <3>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <22 512 0 0>,
+ <22 512 0 6400000>,
+ <22 512 0 6400000>;
+
qcom,max-clk-rate = <320000000>;
qcom,mdss-pipe-vig-off = <0x00001200 0x00001600
0x00001A00>;
diff --git a/drivers/video/msm/mdss/mdss.h b/drivers/video/msm/mdss/mdss.h
index 53292f8..35162ea 100644
--- a/drivers/video/msm/mdss/mdss.h
+++ b/drivers/video/msm/mdss/mdss.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -114,7 +114,6 @@
unsigned long min_mdp_clk;
u32 res_init;
- u32 bus_hdl;
u32 smp_mb_cnt;
u32 smp_mb_size;
@@ -125,6 +124,11 @@
u32 max_bw_low;
u32 max_bw_high;
+ u32 axi_port_cnt;
+ u32 curr_bw_uc_idx;
+ u32 bus_hdl;
+ struct msm_bus_scale_pdata *bus_scale_table;
+
struct mdss_hw_settings *hw_settings;
struct mdss_mdp_pipe *vig_pipes;
@@ -162,7 +166,6 @@
struct early_suspend early_suspend;
struct mdss_debug_inf debug_inf;
- int current_bus_idx;
bool mixer_switched;
struct mdss_panel_cfg pan_cfg;
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index 8fcde84..c87bc0b 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -1,7 +1,7 @@
/*
* MDSS MDP Interface (used by framebuffer core)
*
- * Copyright (c) 2007-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2007-2014, The Linux Foundation. All rights reserved.
* Copyright (C) 2007 Google Incorporated
*
* This software is licensed under the terms of the GNU General Public
@@ -82,33 +82,12 @@
static DEFINE_MUTEX(bus_bw_lock);
static DEFINE_MUTEX(mdp_iommu_lock);
-#define MDP_BUS_VECTOR_ENTRY(ab_val, ib_val) \
- { \
- .src = MSM_BUS_MASTER_MDP_PORT0, \
- .dst = MSM_BUS_SLAVE_EBI_CH0, \
- .ab = (ab_val), \
- .ib = (ib_val), \
- }
-
-static struct msm_bus_vectors mdp_bus_vectors[] = {
- MDP_BUS_VECTOR_ENTRY(0, 0),
- MDP_BUS_VECTOR_ENTRY(SZ_128M, SZ_256M),
- MDP_BUS_VECTOR_ENTRY(SZ_256M, SZ_512M),
-};
-static struct msm_bus_paths mdp_bus_usecases[ARRAY_SIZE(mdp_bus_vectors)];
-
static struct mdss_panel_intf pan_types[] = {
{"dsi", MDSS_PANEL_INTF_DSI},
{"edp", MDSS_PANEL_INTF_EDP},
{"hdmi", MDSS_PANEL_INTF_HDMI},
};
-static struct msm_bus_scale_pdata mdp_bus_scale_table = {
- .usecase = mdp_bus_usecases,
- .num_usecases = ARRAY_SIZE(mdp_bus_usecases),
- .name = "mdss_mdp",
-};
-
struct mdss_iommu_map_type mdss_iommu_map[MDSS_IOMMU_MAX_DOMAIN] = {
[MDSS_IOMMU_DOMAIN_UNSECURE] = {
.client_name = "mdp_ns",
@@ -156,6 +135,7 @@
static int mdss_mdp_parse_dt_smp(struct platform_device *pdev);
static int mdss_mdp_parse_dt_misc(struct platform_device *pdev);
static int mdss_mdp_parse_dt_ad_cfg(struct platform_device *pdev);
+static int mdss_mdp_parse_dt_bus_scale(struct platform_device *pdev);
u32 mdss_mdp_fb_stride(u32 fb_index, u32 xres, int bpp)
{
@@ -332,23 +312,17 @@
static int mdss_mdp_bus_scale_register(struct mdss_data_type *mdata)
{
if (!mdata->bus_hdl) {
- struct msm_bus_scale_pdata *bus_pdata = &mdp_bus_scale_table;
- int i;
-
- for (i = 0; i < bus_pdata->num_usecases; i++) {
- mdp_bus_usecases[i].num_paths = 1;
- mdp_bus_usecases[i].vectors = &mdp_bus_vectors[i];
- }
-
- mdata->bus_hdl = msm_bus_scale_register_client(bus_pdata);
- if (!mdata->bus_hdl) {
- pr_err("not able to get bus scale\n");
- return -ENOMEM;
+ mdata->bus_hdl =
+ msm_bus_scale_register_client(mdata->bus_scale_table);
+ if (IS_ERR_VALUE(mdata->bus_hdl)) {
+ pr_err("bus_client register failed\n");
+ return -EINVAL;
}
pr_debug("register bus_hdl=%x\n", mdata->bus_hdl);
}
- return 0;
+
+ return mdss_mdp_bus_scale_set_quota(AB_QUOTA, IB_QUOTA);
}
static void mdss_mdp_bus_scale_unregister(struct mdss_data_type *mdata)
@@ -361,7 +335,7 @@
int mdss_mdp_bus_scale_set_quota(u64 ab_quota, u64 ib_quota)
{
- int bus_idx;
+ int new_uc_idx;
if (mdss_res->bus_hdl < 1) {
pr_err("invalid bus handle %d\n", mdss_res->bus_hdl);
@@ -369,32 +343,50 @@
}
if ((ab_quota | ib_quota) == 0) {
- bus_idx = 0;
+ new_uc_idx = 0;
} else {
- int num_cases = mdp_bus_scale_table.num_usecases;
+ int i;
struct msm_bus_vectors *vect = NULL;
+ struct msm_bus_scale_pdata *bw_table =
+ mdss_res->bus_scale_table;
+ unsigned long size;
- bus_idx = (mdss_res->current_bus_idx % (num_cases - 1)) + 1;
-
- vect = mdp_bus_scale_table.usecase[mdss_res->current_bus_idx].
- vectors;
-
- /* avoid performing updates for small changes */
- if ((ALIGN(ab_quota, SZ_64M) == ALIGN(vect->ab, SZ_64M)) &&
- (ALIGN(ib_quota, SZ_64M) == ALIGN(vect->ib, SZ_64M))) {
- pr_debug("skip bus scaling, no change in vectors\n");
- return 0;
+ if (!bw_table || !mdss_res->axi_port_cnt) {
+ pr_err("invalid input\n");
+ return -EINVAL;
}
- vect = mdp_bus_scale_table.usecase[bus_idx].vectors;
- vect->ab = ab_quota;
- vect->ib = ib_quota;
+ size = SZ_64M / mdss_res->axi_port_cnt;
- pr_debug("bus scale idx=%d ab=%llu ib=%llu\n", bus_idx,
- vect->ab, vect->ib);
+ ab_quota = div_u64(ab_quota, mdss_res->axi_port_cnt);
+ ib_quota = div_u64(ib_quota, mdss_res->axi_port_cnt);
+
+ new_uc_idx = (mdss_res->curr_bw_uc_idx %
+ (bw_table->num_usecases - 1)) + 1;
+
+ for (i = 0; i < mdss_res->axi_port_cnt; i++) {
+ vect = &bw_table->usecase[mdss_res->curr_bw_uc_idx].
+ vectors[i];
+
+ /* avoid performing updates for small changes */
+ if ((ALIGN(ab_quota, size) == ALIGN(vect->ab, size)) &&
+ (ALIGN(ib_quota, size) == ALIGN(vect->ib, size))) {
+ pr_debug("skip bus scaling, no changes\n");
+ return 0;
+ }
+
+ vect = &bw_table->usecase[new_uc_idx].vectors[i];
+ vect->ab = ab_quota;
+ vect->ib = ib_quota;
+
+ pr_debug("uc_idx=%d path_idx=%d ab=%llu ib=%llu\n",
+ new_uc_idx, i, vect->ab, vect->ib);
+ }
}
- mdss_res->current_bus_idx = bus_idx;
- return msm_bus_scale_client_update_request(mdss_res->bus_hdl, bus_idx);
+ mdss_res->curr_bw_uc_idx = new_uc_idx;
+
+ return msm_bus_scale_client_update_request(mdss_res->bus_hdl,
+ new_uc_idx);
}
static inline u32 mdss_mdp_irq_mask(u32 intr_type, u32 intf_num)
@@ -654,7 +646,7 @@
} else {
pm_runtime_get_sync(&mdata->pdev->dev);
msm_bus_scale_client_update_request(
- mdata->bus_hdl, mdata->current_bus_idx);
+ mdata->bus_hdl, mdata->curr_bw_uc_idx);
if (!mdata->handoff_pending)
mdss_iommu_attach(mdata);
}
@@ -1218,7 +1210,6 @@
pr_err("unable to register bus scaling\n");
goto probe_done;
}
- mdss_mdp_bus_scale_set_quota(AB_QUOTA, IB_QUOTA);
rc = mdss_mdp_debug_init(mdata);
if (rc) {
@@ -1558,6 +1549,12 @@
return rc;
}
+ rc = mdss_mdp_parse_dt_bus_scale(pdev);
+ if (rc) {
+ pr_err("Error in device tree : bus scale\n");
+ return rc;
+ }
+
return 0;
}
@@ -2087,6 +2084,31 @@
return rc;
}
+static int mdss_mdp_parse_dt_bus_scale(struct platform_device *pdev)
+{
+ int rc;
+ struct mdss_data_type *mdata = platform_get_drvdata(pdev);
+
+ rc = of_property_read_u32(pdev->dev.of_node, "qcom,msm-bus,num-paths",
+ &mdata->axi_port_cnt);
+ if (rc) {
+ pr_err("Error. qcom,msm-bus,num-paths prop not found.rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ mdata->bus_scale_table = msm_bus_cl_get_pdata(pdev);
+ if (IS_ERR_OR_NULL(mdata->bus_scale_table)) {
+ rc = PTR_ERR(mdata->bus_scale_table);
+ if (!rc)
+ rc = -EINVAL;
+ pr_err("msm_bus_cl_get_pdata failed. rc=%d\n", rc);
+ mdata->bus_scale_table = NULL;
+ }
+
+ return rc;
+}
+
static int mdss_mdp_parse_dt_handler(struct platform_device *pdev,
char *prop_name, u32 *offsets, int len)
{