Skip to content

Commit 5bc1cf1

Browse files
shawnguo2joergroedel
authored andcommitted
iommu/qcom: add optional 'tbu' clock for TLB invalidate
On some SoCs like MSM8939 with A405 adreno, there is a gfx_tbu clock needs to be on while doing TLB invalidate. Otherwise, TLBSYNC status will not be correctly reflected, causing the system to go into a bad state. Add it as an optional clock, so that platforms that have this clock can pass it over DT. While adding the third clock, let's switch to bulk clk API to simplify the enable/disable calls. clk_bulk_get() cannot used because the existing two clocks are required while the new one is optional. Signed-off-by: Shawn Guo <[email protected]> Reviewed-by: Bjorn Andersson <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent 6a8b55e commit 5bc1cf1

File tree

1 file changed

+26
-36
lines changed

1 file changed

+26
-36
lines changed

drivers/iommu/qcom_iommu.c

Lines changed: 26 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,20 @@
3737

3838
#define SMMU_INTR_SEL_NS 0x2000
3939

40+
enum qcom_iommu_clk {
41+
CLK_IFACE,
42+
CLK_BUS,
43+
CLK_TBU,
44+
CLK_NUM,
45+
};
46+
4047
struct qcom_iommu_ctx;
4148

4249
struct qcom_iommu_dev {
4350
/* IOMMU core code handle */
4451
struct iommu_device iommu;
4552
struct device *dev;
46-
struct clk *iface_clk;
47-
struct clk *bus_clk;
53+
struct clk_bulk_data clks[CLK_NUM];
4854
void __iomem *local_base;
4955
u32 sec_id;
5056
u8 num_ctxs;
@@ -626,32 +632,6 @@ static const struct iommu_ops qcom_iommu_ops = {
626632
.pgsize_bitmap = SZ_4K | SZ_64K | SZ_1M | SZ_16M,
627633
};
628634

629-
static int qcom_iommu_enable_clocks(struct qcom_iommu_dev *qcom_iommu)
630-
{
631-
int ret;
632-
633-
ret = clk_prepare_enable(qcom_iommu->iface_clk);
634-
if (ret) {
635-
dev_err(qcom_iommu->dev, "Couldn't enable iface_clk\n");
636-
return ret;
637-
}
638-
639-
ret = clk_prepare_enable(qcom_iommu->bus_clk);
640-
if (ret) {
641-
dev_err(qcom_iommu->dev, "Couldn't enable bus_clk\n");
642-
clk_disable_unprepare(qcom_iommu->iface_clk);
643-
return ret;
644-
}
645-
646-
return 0;
647-
}
648-
649-
static void qcom_iommu_disable_clocks(struct qcom_iommu_dev *qcom_iommu)
650-
{
651-
clk_disable_unprepare(qcom_iommu->bus_clk);
652-
clk_disable_unprepare(qcom_iommu->iface_clk);
653-
}
654-
655635
static int qcom_iommu_sec_ptbl_init(struct device *dev)
656636
{
657637
size_t psize = 0;
@@ -808,6 +788,7 @@ static int qcom_iommu_device_probe(struct platform_device *pdev)
808788
struct qcom_iommu_dev *qcom_iommu;
809789
struct device *dev = &pdev->dev;
810790
struct resource *res;
791+
struct clk *clk;
811792
int ret, max_asid = 0;
812793

813794
/* find the max asid (which is 1:1 to ctx bank idx), so we know how
@@ -827,17 +808,26 @@ static int qcom_iommu_device_probe(struct platform_device *pdev)
827808
if (res)
828809
qcom_iommu->local_base = devm_ioremap_resource(dev, res);
829810

830-
qcom_iommu->iface_clk = devm_clk_get(dev, "iface");
831-
if (IS_ERR(qcom_iommu->iface_clk)) {
811+
clk = devm_clk_get(dev, "iface");
812+
if (IS_ERR(clk)) {
832813
dev_err(dev, "failed to get iface clock\n");
833-
return PTR_ERR(qcom_iommu->iface_clk);
814+
return PTR_ERR(clk);
834815
}
816+
qcom_iommu->clks[CLK_IFACE].clk = clk;
835817

836-
qcom_iommu->bus_clk = devm_clk_get(dev, "bus");
837-
if (IS_ERR(qcom_iommu->bus_clk)) {
818+
clk = devm_clk_get(dev, "bus");
819+
if (IS_ERR(clk)) {
838820
dev_err(dev, "failed to get bus clock\n");
839-
return PTR_ERR(qcom_iommu->bus_clk);
821+
return PTR_ERR(clk);
822+
}
823+
qcom_iommu->clks[CLK_BUS].clk = clk;
824+
825+
clk = devm_clk_get_optional(dev, "tbu");
826+
if (IS_ERR(clk)) {
827+
dev_err(dev, "failed to get tbu clock\n");
828+
return PTR_ERR(clk);
840829
}
830+
qcom_iommu->clks[CLK_TBU].clk = clk;
841831

842832
if (of_property_read_u32(dev->of_node, "qcom,iommu-secure-id",
843833
&qcom_iommu->sec_id)) {
@@ -909,14 +899,14 @@ static int __maybe_unused qcom_iommu_resume(struct device *dev)
909899
{
910900
struct qcom_iommu_dev *qcom_iommu = dev_get_drvdata(dev);
911901

912-
return qcom_iommu_enable_clocks(qcom_iommu);
902+
return clk_bulk_prepare_enable(CLK_NUM, qcom_iommu->clks);
913903
}
914904

915905
static int __maybe_unused qcom_iommu_suspend(struct device *dev)
916906
{
917907
struct qcom_iommu_dev *qcom_iommu = dev_get_drvdata(dev);
918908

919-
qcom_iommu_disable_clocks(qcom_iommu);
909+
clk_bulk_disable_unprepare(CLK_NUM, qcom_iommu->clks);
920910

921911
return 0;
922912
}

0 commit comments

Comments
 (0)