summaryrefslogtreecommitdiff
path: root/mali_kbase/hw_access/backend/mali_kbase_hw_access_model_linux.c
diff options
context:
space:
mode:
Diffstat (limited to 'mali_kbase/hw_access/backend/mali_kbase_hw_access_model_linux.c')
-rw-r--r--mali_kbase/hw_access/backend/mali_kbase_hw_access_model_linux.c151
1 files changed, 151 insertions, 0 deletions
diff --git a/mali_kbase/hw_access/backend/mali_kbase_hw_access_model_linux.c b/mali_kbase/hw_access/backend/mali_kbase_hw_access_model_linux.c
new file mode 100644
index 0000000..ca1ccbf
--- /dev/null
+++ b/mali_kbase/hw_access/backend/mali_kbase_hw_access_model_linux.c
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+/*
+ *
+ * (C) COPYRIGHT 2023 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you can access it online at
+ * http://www.gnu.org/licenses/gpl-2.0.html.
+ *
+ */
+
+#include <linux/io.h>
+#include <linux/types.h>
+
+#include <mali_kbase.h>
+#include <hw_access/mali_kbase_hw_access.h>
+#include <hw_access/mali_kbase_hw_access_regmap_legacy.h>
+#include <backend/gpu/mali_kbase_model_linux.h>
+
+u64 kbase_reg_get_gpu_id(struct kbase_device *kbdev)
+{
+ unsigned long flags;
+ u32 val[2] = { 0 };
+
+ spin_lock_irqsave(&kbdev->reg_op_lock, flags);
+ midgard_model_read_reg(kbdev->model, GPU_CONTROL_REG(GPU_ID), &val[0]);
+ spin_unlock_irqrestore(&kbdev->reg_op_lock, flags);
+
+
+ return (u64)val[0] | ((u64)val[1] << 32);
+}
+
+u32 kbase_reg_read32(struct kbase_device *kbdev, u32 reg_enum)
+{
+ unsigned long flags;
+ u32 val = 0;
+ u32 offset;
+
+ if (WARN_ON(!kbdev->pm.backend.gpu_powered))
+ return 0;
+ if (unlikely(!kbase_reg_is_accessible(kbdev, reg_enum,
+ KBASE_REGMAP_PERM_READ | KBASE_REGMAP_WIDTH_32_BIT)))
+ return 0;
+
+ offset = kbdev->regmap.regs[reg_enum] - kbdev->reg;
+
+ spin_lock_irqsave(&kbdev->reg_op_lock, flags);
+ midgard_model_read_reg(kbdev->model, offset, &val);
+ spin_unlock_irqrestore(&kbdev->reg_op_lock, flags);
+
+ return val;
+}
+KBASE_EXPORT_TEST_API(kbase_reg_read32);
+
+u64 kbase_reg_read64(struct kbase_device *kbdev, u32 reg_enum)
+{
+ unsigned long flags;
+ u32 val32[2] = { 0 };
+ u32 offset;
+
+ if (WARN_ON(!kbdev->pm.backend.gpu_powered))
+ return 0;
+ if (unlikely(!kbase_reg_is_accessible(kbdev, reg_enum,
+ KBASE_REGMAP_PERM_READ | KBASE_REGMAP_WIDTH_64_BIT)))
+ return 0;
+
+ offset = kbdev->regmap.regs[reg_enum] - kbdev->reg;
+
+ spin_lock_irqsave(&kbdev->reg_op_lock, flags);
+ midgard_model_read_reg(kbdev->model, offset, &val32[0]);
+ midgard_model_read_reg(kbdev->model, offset + 4, &val32[1]);
+ spin_unlock_irqrestore(&kbdev->reg_op_lock, flags);
+
+ return (u64)val32[0] | ((u64)val32[1] << 32);
+}
+KBASE_EXPORT_TEST_API(kbase_reg_read64);
+
+u64 kbase_reg_read64_coherent(struct kbase_device *kbdev, u32 reg_enum)
+{
+ unsigned long flags;
+ u32 hi1 = 0, hi2 = 0, lo = 0;
+ u32 offset;
+
+ if (WARN_ON(!kbdev->pm.backend.gpu_powered))
+ return 0;
+ if (unlikely(!kbase_reg_is_accessible(kbdev, reg_enum,
+ KBASE_REGMAP_PERM_READ | KBASE_REGMAP_WIDTH_64_BIT)))
+ return 0;
+
+ offset = kbdev->regmap.regs[reg_enum] - kbdev->reg;
+
+ spin_lock_irqsave(&kbdev->reg_op_lock, flags);
+ do {
+ midgard_model_read_reg(kbdev->model, offset + 4, &hi1);
+ midgard_model_read_reg(kbdev->model, offset, &lo);
+ midgard_model_read_reg(kbdev->model, offset + 4, &hi2);
+ } while (hi1 != hi2);
+ spin_unlock_irqrestore(&kbdev->reg_op_lock, flags);
+
+ return lo | (((u64)hi1) << 32);
+}
+KBASE_EXPORT_TEST_API(kbase_reg_read64_coherent);
+
+void kbase_reg_write32(struct kbase_device *kbdev, u32 reg_enum, u32 value)
+{
+ unsigned long flags;
+ u32 offset;
+
+ if (WARN_ON(!kbdev->pm.backend.gpu_powered))
+ return;
+ if (unlikely(!kbase_reg_is_accessible(kbdev, reg_enum,
+ KBASE_REGMAP_PERM_WRITE | KBASE_REGMAP_WIDTH_32_BIT)))
+ return;
+
+ offset = kbdev->regmap.regs[reg_enum] - kbdev->reg;
+
+ spin_lock_irqsave(&kbdev->reg_op_lock, flags);
+ midgard_model_write_reg(kbdev->model, offset, value);
+ spin_unlock_irqrestore(&kbdev->reg_op_lock, flags);
+}
+KBASE_EXPORT_TEST_API(kbase_reg_write32);
+
+void kbase_reg_write64(struct kbase_device *kbdev, u32 reg_enum, u64 value)
+{
+ unsigned long flags;
+ u32 offset;
+
+ if (WARN_ON(!kbdev->pm.backend.gpu_powered))
+ return;
+ if (unlikely(!kbase_reg_is_accessible(kbdev, reg_enum,
+ KBASE_REGMAP_PERM_WRITE | KBASE_REGMAP_WIDTH_64_BIT)))
+ return;
+
+ offset = kbdev->regmap.regs[reg_enum] - kbdev->reg;
+
+ spin_lock_irqsave(&kbdev->reg_op_lock, flags);
+ midgard_model_write_reg(kbdev->model, offset, value & 0xFFFFFFFF);
+ midgard_model_write_reg(kbdev->model, offset + 4, value >> 32);
+ spin_unlock_irqrestore(&kbdev->reg_op_lock, flags);
+}
+KBASE_EXPORT_TEST_API(kbase_reg_write64);