Loading Documentation/devicetree/bindings/iommu/arm,smmu.txt +3 −0 Original line number Diff line number Diff line Loading @@ -128,6 +128,9 @@ conditions. time. This should be a list of 2-tuples of the format: <offset reg_value>. - qcom,bus-master-id : The master ID of the bus, if a bus vote is needed. See include/dt-bindings/msm/msm-bus-ids.h. Example: smmu { Loading arch/arm/boot/dts/qcom/msm-arm-smmu-8996.dtsi +8 −0 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include "msm-arm-smmu.dtsi" #include "msm-arm-smmu-impl-defs-8996.dtsi" #include <dt-bindings/msm/msm-bus-ids.h> &anoc0_smmu { status = "ok"; Loading Loading @@ -91,6 +92,7 @@ "jpeg_ahb_clk", "jpeg_axi_clk", "mmssnoc_axi_clk", "mmagic_camss_axi_clk"; #clock-cells = <1>; qcom,bus-master-id = <MSM_BUS_MASTER_JPEG>; }; &vfe_smmu { Loading @@ -112,6 +114,7 @@ "vfe_ahb_clk", "vfe_axi_clk", "mmssnoc_axi_clk", "mmagic_camss_axi_clk"; #clock-cells = <1>; qcom,bus-master-id = <MSM_BUS_MASTER_VFE>; }; &cpp_fd_smmu { Loading @@ -133,6 +136,7 @@ "cpp_ahb_clk", "cpp_axi_clk", "mmssnoc_axi_clk", "mmagic_camss_axi_clk"; #clock-cells = <1>; qcom,bus-master-id = <MSM_BUS_MASTER_CPP>; }; &venus_smmu { Loading @@ -154,6 +158,7 @@ "video_ahb_clk", "video_axi_clk", "mmssnoc_axi_clk", "mmagic_video_axi_clk"; #clock-cells = <1>; qcom,bus-master-id = <MSM_BUS_MASTER_VIDEO_P0>; }; &mdp_smmu { Loading @@ -174,6 +179,7 @@ "mdp_ahb_clk", "mdp_axi_clk", "mmssnoc_axi_clk", "mmagic_mdss_axi_clk"; #clock-cells = <1>; qcom,bus-master-id = <MSM_BUS_MASTER_MDP_PORT0>; }; &rot_smmu { Loading @@ -194,7 +200,9 @@ "rot_ahb_clk", "rot_axi_clk", "mmssnoc_axi_clk", "mmagic_mdss_axi_clk"; #clock-cells = <1>; qcom,bus-master-id = <MSM_BUS_MASTER_ROTATOR>; }; &kgsl_smmu { status = "ok"; qcom,register-save; Loading drivers/iommu/arm-smmu.c +69 −1 Original line number Diff line number Diff line Loading @@ -47,6 +47,8 @@ #include <soc/qcom/secure_buffer.h> #include <linux/msm_pcie.h> #include <asm/cacheflush.h> #include <linux/msm-bus.h> #include <dt-bindings/msm/msm-bus-ids.h> #include "io-pgtable.h" Loading Loading @@ -402,6 +404,9 @@ struct arm_smmu_device { spinlock_t atos_lock; unsigned int clock_refs_count; spinlock_t clock_refs_lock; struct msm_bus_client_handle *bus_client; char *bus_client_name; }; struct arm_smmu_cfg { Loading Loading @@ -730,12 +735,27 @@ static int arm_smmu_prepare_clocks(struct arm_smmu_device *smmu) return ret; } static int arm_smmu_request_bus(struct arm_smmu_device *smmu) { if (!smmu->bus_client) return 0; return msm_bus_scale_update_bw(smmu->bus_client, 0, 1000); } static int arm_smmu_unrequest_bus(struct arm_smmu_device *smmu) { if (!smmu->bus_client) return 0; return msm_bus_scale_update_bw(smmu->bus_client, 0, 0); } static int arm_smmu_disable_regulators(struct arm_smmu_device *smmu) { if (!smmu->gdsc) return 0; arm_smmu_unprepare_clocks(smmu); arm_smmu_unrequest_bus(smmu); return regulator_disable(smmu->gdsc); } Loading @@ -749,9 +769,20 @@ static int arm_smmu_enable_regulators(struct arm_smmu_device *smmu) ret = regulator_enable(smmu->gdsc); if (ret) return ret; ret = arm_smmu_request_bus(smmu); if (ret) { regulator_disable(smmu->gdsc); goto out; } ret = arm_smmu_prepare_clocks(smmu); if (ret) if (ret) { arm_smmu_unrequest_bus(smmu); regulator_disable(smmu->gdsc); } out: return ret; } Loading Loading @@ -2749,6 +2780,37 @@ static int arm_smmu_init_clocks(struct arm_smmu_device *smmu) return 0; } static int arm_smmu_init_bus_scaling(struct platform_device *pdev, struct arm_smmu_device *smmu) { u32 master_id; if (of_property_read_u32(pdev->dev.of_node, "qcom,bus-master-id", &master_id)) { dev_dbg(smmu->dev, "No bus scaling info\n"); return 0; } smmu->bus_client_name = devm_kasprintf( smmu->dev, GFP_KERNEL, "smmu-bus-client-%s", dev_name(smmu->dev)); if (!smmu->bus_client_name) return -ENOMEM; smmu->bus_client = msm_bus_scale_register( master_id, MSM_BUS_SLAVE_EBI_CH0, smmu->bus_client_name, true); if (IS_ERR(&smmu->bus_client)) { int ret = PTR_ERR(smmu->bus_client); if (ret != -EPROBE_DEFER) dev_err(smmu->dev, "Bus client registration failed\n"); return ret; } return 0; } static int arm_smmu_parse_impl_def_registers(struct arm_smmu_device *smmu) { struct device *dev = smmu->dev; Loading Loading @@ -3047,6 +3109,10 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev) if (err) goto out_put_masters; err = arm_smmu_init_bus_scaling(pdev, smmu); if (err) goto out_put_masters; parse_driver_options(smmu); arm_smmu_enable_regulators(smmu); Loading Loading @@ -3146,6 +3212,8 @@ static int arm_smmu_device_remove(struct platform_device *pdev) arm_smmu_power_off(smmu, false); mutex_unlock(&smmu->attach_lock); msm_bus_scale_unregister(smmu->bus_client); return 0; } Loading drivers/platform/msm/msm_bus/msm_bus_client_api.c +9 −5 Original line number Diff line number Diff line Loading @@ -101,8 +101,12 @@ EXPORT_SYMBOL(msm_bus_scale_unregister_client); /** * msm_bus_scale_register() - Register the clients with the msm bus * driver * @pdata: Platform data of the client, containing src, dest, ab, ib. * Return non-zero value in case of success, 0 in case of failure. * * @mas: Master ID * @slv: Slave ID * @name: descriptive name for this client * @active_only: Whether or not this bandwidth vote should only be * effective while the application processor is active. * * Client data contains the vectors specifying arbitrated bandwidth (ab) * and instantaneous bandwidth (ib) requested between a particular Loading @@ -126,9 +130,9 @@ EXPORT_SYMBOL(msm_bus_scale_register); * msm_bus_scale_client_update_bw() - Update the request for bandwidth * from a particular client * * cl: Handle to the client * index: Index into the vector, to which the bw and clock values need to be * updated * @cl: Handle to the client * @ab: Arbitrated bandwidth being requested * @ib: Instantaneous bandwidth being requested */ int msm_bus_scale_update_bw(struct msm_bus_client_handle *cl, u64 ab, u64 ib) { Loading Loading
Documentation/devicetree/bindings/iommu/arm,smmu.txt +3 −0 Original line number Diff line number Diff line Loading @@ -128,6 +128,9 @@ conditions. time. This should be a list of 2-tuples of the format: <offset reg_value>. - qcom,bus-master-id : The master ID of the bus, if a bus vote is needed. See include/dt-bindings/msm/msm-bus-ids.h. Example: smmu { Loading
arch/arm/boot/dts/qcom/msm-arm-smmu-8996.dtsi +8 −0 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include "msm-arm-smmu.dtsi" #include "msm-arm-smmu-impl-defs-8996.dtsi" #include <dt-bindings/msm/msm-bus-ids.h> &anoc0_smmu { status = "ok"; Loading Loading @@ -91,6 +92,7 @@ "jpeg_ahb_clk", "jpeg_axi_clk", "mmssnoc_axi_clk", "mmagic_camss_axi_clk"; #clock-cells = <1>; qcom,bus-master-id = <MSM_BUS_MASTER_JPEG>; }; &vfe_smmu { Loading @@ -112,6 +114,7 @@ "vfe_ahb_clk", "vfe_axi_clk", "mmssnoc_axi_clk", "mmagic_camss_axi_clk"; #clock-cells = <1>; qcom,bus-master-id = <MSM_BUS_MASTER_VFE>; }; &cpp_fd_smmu { Loading @@ -133,6 +136,7 @@ "cpp_ahb_clk", "cpp_axi_clk", "mmssnoc_axi_clk", "mmagic_camss_axi_clk"; #clock-cells = <1>; qcom,bus-master-id = <MSM_BUS_MASTER_CPP>; }; &venus_smmu { Loading @@ -154,6 +158,7 @@ "video_ahb_clk", "video_axi_clk", "mmssnoc_axi_clk", "mmagic_video_axi_clk"; #clock-cells = <1>; qcom,bus-master-id = <MSM_BUS_MASTER_VIDEO_P0>; }; &mdp_smmu { Loading @@ -174,6 +179,7 @@ "mdp_ahb_clk", "mdp_axi_clk", "mmssnoc_axi_clk", "mmagic_mdss_axi_clk"; #clock-cells = <1>; qcom,bus-master-id = <MSM_BUS_MASTER_MDP_PORT0>; }; &rot_smmu { Loading @@ -194,7 +200,9 @@ "rot_ahb_clk", "rot_axi_clk", "mmssnoc_axi_clk", "mmagic_mdss_axi_clk"; #clock-cells = <1>; qcom,bus-master-id = <MSM_BUS_MASTER_ROTATOR>; }; &kgsl_smmu { status = "ok"; qcom,register-save; Loading
drivers/iommu/arm-smmu.c +69 −1 Original line number Diff line number Diff line Loading @@ -47,6 +47,8 @@ #include <soc/qcom/secure_buffer.h> #include <linux/msm_pcie.h> #include <asm/cacheflush.h> #include <linux/msm-bus.h> #include <dt-bindings/msm/msm-bus-ids.h> #include "io-pgtable.h" Loading Loading @@ -402,6 +404,9 @@ struct arm_smmu_device { spinlock_t atos_lock; unsigned int clock_refs_count; spinlock_t clock_refs_lock; struct msm_bus_client_handle *bus_client; char *bus_client_name; }; struct arm_smmu_cfg { Loading Loading @@ -730,12 +735,27 @@ static int arm_smmu_prepare_clocks(struct arm_smmu_device *smmu) return ret; } static int arm_smmu_request_bus(struct arm_smmu_device *smmu) { if (!smmu->bus_client) return 0; return msm_bus_scale_update_bw(smmu->bus_client, 0, 1000); } static int arm_smmu_unrequest_bus(struct arm_smmu_device *smmu) { if (!smmu->bus_client) return 0; return msm_bus_scale_update_bw(smmu->bus_client, 0, 0); } static int arm_smmu_disable_regulators(struct arm_smmu_device *smmu) { if (!smmu->gdsc) return 0; arm_smmu_unprepare_clocks(smmu); arm_smmu_unrequest_bus(smmu); return regulator_disable(smmu->gdsc); } Loading @@ -749,9 +769,20 @@ static int arm_smmu_enable_regulators(struct arm_smmu_device *smmu) ret = regulator_enable(smmu->gdsc); if (ret) return ret; ret = arm_smmu_request_bus(smmu); if (ret) { regulator_disable(smmu->gdsc); goto out; } ret = arm_smmu_prepare_clocks(smmu); if (ret) if (ret) { arm_smmu_unrequest_bus(smmu); regulator_disable(smmu->gdsc); } out: return ret; } Loading Loading @@ -2749,6 +2780,37 @@ static int arm_smmu_init_clocks(struct arm_smmu_device *smmu) return 0; } static int arm_smmu_init_bus_scaling(struct platform_device *pdev, struct arm_smmu_device *smmu) { u32 master_id; if (of_property_read_u32(pdev->dev.of_node, "qcom,bus-master-id", &master_id)) { dev_dbg(smmu->dev, "No bus scaling info\n"); return 0; } smmu->bus_client_name = devm_kasprintf( smmu->dev, GFP_KERNEL, "smmu-bus-client-%s", dev_name(smmu->dev)); if (!smmu->bus_client_name) return -ENOMEM; smmu->bus_client = msm_bus_scale_register( master_id, MSM_BUS_SLAVE_EBI_CH0, smmu->bus_client_name, true); if (IS_ERR(&smmu->bus_client)) { int ret = PTR_ERR(smmu->bus_client); if (ret != -EPROBE_DEFER) dev_err(smmu->dev, "Bus client registration failed\n"); return ret; } return 0; } static int arm_smmu_parse_impl_def_registers(struct arm_smmu_device *smmu) { struct device *dev = smmu->dev; Loading Loading @@ -3047,6 +3109,10 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev) if (err) goto out_put_masters; err = arm_smmu_init_bus_scaling(pdev, smmu); if (err) goto out_put_masters; parse_driver_options(smmu); arm_smmu_enable_regulators(smmu); Loading Loading @@ -3146,6 +3212,8 @@ static int arm_smmu_device_remove(struct platform_device *pdev) arm_smmu_power_off(smmu, false); mutex_unlock(&smmu->attach_lock); msm_bus_scale_unregister(smmu->bus_client); return 0; } Loading
drivers/platform/msm/msm_bus/msm_bus_client_api.c +9 −5 Original line number Diff line number Diff line Loading @@ -101,8 +101,12 @@ EXPORT_SYMBOL(msm_bus_scale_unregister_client); /** * msm_bus_scale_register() - Register the clients with the msm bus * driver * @pdata: Platform data of the client, containing src, dest, ab, ib. * Return non-zero value in case of success, 0 in case of failure. * * @mas: Master ID * @slv: Slave ID * @name: descriptive name for this client * @active_only: Whether or not this bandwidth vote should only be * effective while the application processor is active. * * Client data contains the vectors specifying arbitrated bandwidth (ab) * and instantaneous bandwidth (ib) requested between a particular Loading @@ -126,9 +130,9 @@ EXPORT_SYMBOL(msm_bus_scale_register); * msm_bus_scale_client_update_bw() - Update the request for bandwidth * from a particular client * * cl: Handle to the client * index: Index into the vector, to which the bw and clock values need to be * updated * @cl: Handle to the client * @ab: Arbitrated bandwidth being requested * @ib: Instantaneous bandwidth being requested */ int msm_bus_scale_update_bw(struct msm_bus_client_handle *cl, u64 ab, u64 ib) { Loading