blob: 78247e6f4a720cfa199feb2c686f16a6bba48004 [file] [log] [blame]
David Brazdil0f672f62019-12-10 10:32:29 +00001// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * OMAP IOMMU quirks for various TI SoCs
4 *
5 * Copyright (C) 2015-2019 Texas Instruments Incorporated - http://www.ti.com/
6 * Suman Anna <s-anna@ti.com>
7 */
8
9#include <linux/platform_device.h>
10#include <linux/err.h>
11
12#include "omap_hwmod.h"
13#include "omap_device.h"
Olivier Deprez0e641232021-09-23 10:07:05 +020014#include "clockdomain.h"
David Brazdil0f672f62019-12-10 10:32:29 +000015#include "powerdomain.h"
16
Olivier Deprez0e641232021-09-23 10:07:05 +020017static void omap_iommu_dra7_emu_swsup_config(struct platform_device *pdev,
18 bool enable)
19{
20 static struct clockdomain *emu_clkdm;
21 static DEFINE_SPINLOCK(emu_lock);
22 static atomic_t count;
23 struct device_node *np = pdev->dev.of_node;
24
25 if (!of_device_is_compatible(np, "ti,dra7-dsp-iommu"))
26 return;
27
28 if (!emu_clkdm) {
29 emu_clkdm = clkdm_lookup("emu_clkdm");
30 if (WARN_ON_ONCE(!emu_clkdm))
31 return;
32 }
33
34 spin_lock(&emu_lock);
35
36 if (enable && (atomic_inc_return(&count) == 1))
37 clkdm_deny_idle(emu_clkdm);
38 else if (!enable && (atomic_dec_return(&count) == 0))
39 clkdm_allow_idle(emu_clkdm);
40
41 spin_unlock(&emu_lock);
42}
43
David Brazdil0f672f62019-12-10 10:32:29 +000044int omap_iommu_set_pwrdm_constraint(struct platform_device *pdev, bool request,
45 u8 *pwrst)
46{
47 struct powerdomain *pwrdm;
48 struct omap_device *od;
49 u8 next_pwrst;
Olivier Deprez0e641232021-09-23 10:07:05 +020050 int ret = 0;
David Brazdil0f672f62019-12-10 10:32:29 +000051
52 od = to_omap_device(pdev);
53 if (!od)
54 return -ENODEV;
55
56 if (od->hwmods_cnt != 1)
57 return -EINVAL;
58
59 pwrdm = omap_hwmod_get_pwrdm(od->hwmods[0]);
60 if (!pwrdm)
61 return -EINVAL;
62
Olivier Deprez0e641232021-09-23 10:07:05 +020063 if (request) {
David Brazdil0f672f62019-12-10 10:32:29 +000064 *pwrst = pwrdm_read_next_pwrst(pwrdm);
Olivier Deprez0e641232021-09-23 10:07:05 +020065 omap_iommu_dra7_emu_swsup_config(pdev, true);
66 }
David Brazdil0f672f62019-12-10 10:32:29 +000067
68 if (*pwrst > PWRDM_POWER_RET)
Olivier Deprez0e641232021-09-23 10:07:05 +020069 goto out;
David Brazdil0f672f62019-12-10 10:32:29 +000070
71 next_pwrst = request ? PWRDM_POWER_ON : *pwrst;
72
Olivier Deprez0e641232021-09-23 10:07:05 +020073 ret = pwrdm_set_next_pwrst(pwrdm, next_pwrst);
74
75out:
76 if (!request)
77 omap_iommu_dra7_emu_swsup_config(pdev, false);
78
79 return ret;
David Brazdil0f672f62019-12-10 10:32:29 +000080}