135b13763SJacek Lawrynowicz /* SPDX-License-Identifier: GPL-2.0-only */
235b13763SJacek Lawrynowicz /*
335b13763SJacek Lawrynowicz * Copyright (C) 2020-2023 Intel Corporation
435b13763SJacek Lawrynowicz */
535b13763SJacek Lawrynowicz
635b13763SJacek Lawrynowicz #ifndef __IVPU_HW_REG_IO_H__
735b13763SJacek Lawrynowicz #define __IVPU_HW_REG_IO_H__
835b13763SJacek Lawrynowicz
935b13763SJacek Lawrynowicz #include <linux/bitfield.h>
1035b13763SJacek Lawrynowicz #include <linux/io.h>
1135b13763SJacek Lawrynowicz #include <linux/iopoll.h>
1235b13763SJacek Lawrynowicz
1335b13763SJacek Lawrynowicz #include "ivpu_drv.h"
1435b13763SJacek Lawrynowicz
1535b13763SJacek Lawrynowicz #define REG_POLL_SLEEP_US 50
1635b13763SJacek Lawrynowicz #define REG_IO_ERROR 0xffffffff
1735b13763SJacek Lawrynowicz
1835b13763SJacek Lawrynowicz #define REGB_RD32(reg) ivpu_hw_reg_rd32(vdev, vdev->regb, (reg), #reg, __func__)
1935b13763SJacek Lawrynowicz #define REGB_RD32_SILENT(reg) readl(vdev->regb + (reg))
2035b13763SJacek Lawrynowicz #define REGB_RD64(reg) ivpu_hw_reg_rd64(vdev, vdev->regb, (reg), #reg, __func__)
2135b13763SJacek Lawrynowicz #define REGB_WR32(reg, val) ivpu_hw_reg_wr32(vdev, vdev->regb, (reg), (val), #reg, __func__)
2235b13763SJacek Lawrynowicz #define REGB_WR64(reg, val) ivpu_hw_reg_wr64(vdev, vdev->regb, (reg), (val), #reg, __func__)
2335b13763SJacek Lawrynowicz
2435b13763SJacek Lawrynowicz #define REGV_RD32(reg) ivpu_hw_reg_rd32(vdev, vdev->regv, (reg), #reg, __func__)
2535b13763SJacek Lawrynowicz #define REGV_RD32_SILENT(reg) readl(vdev->regv + (reg))
2635b13763SJacek Lawrynowicz #define REGV_RD64(reg) ivpu_hw_reg_rd64(vdev, vdev->regv, (reg), #reg, __func__)
2735b13763SJacek Lawrynowicz #define REGV_WR32(reg, val) ivpu_hw_reg_wr32(vdev, vdev->regv, (reg), (val), #reg, __func__)
2835b13763SJacek Lawrynowicz #define REGV_WR64(reg, val) ivpu_hw_reg_wr64(vdev, vdev->regv, (reg), (val), #reg, __func__)
2935b13763SJacek Lawrynowicz
3035b13763SJacek Lawrynowicz #define REGV_WR32I(reg, stride, index, val) \
3135b13763SJacek Lawrynowicz ivpu_hw_reg_wr32_index(vdev, vdev->regv, (reg), (stride), (index), (val), #reg, __func__)
3235b13763SJacek Lawrynowicz
3335b13763SJacek Lawrynowicz #define REG_FLD(REG, FLD) \
3435b13763SJacek Lawrynowicz (REG##_##FLD##_MASK)
3535b13763SJacek Lawrynowicz #define REG_FLD_NUM(REG, FLD, num) \
3635b13763SJacek Lawrynowicz FIELD_PREP(REG##_##FLD##_MASK, num)
3735b13763SJacek Lawrynowicz #define REG_GET_FLD(REG, FLD, val) \
3835b13763SJacek Lawrynowicz FIELD_GET(REG##_##FLD##_MASK, val)
3935b13763SJacek Lawrynowicz #define REG_CLR_FLD(REG, FLD, val) \
4035b13763SJacek Lawrynowicz ((val) & ~(REG##_##FLD##_MASK))
4135b13763SJacek Lawrynowicz #define REG_SET_FLD(REG, FLD, val) \
4235b13763SJacek Lawrynowicz ((val) | (REG##_##FLD##_MASK))
4335b13763SJacek Lawrynowicz #define REG_SET_FLD_NUM(REG, FLD, num, val) \
4435b13763SJacek Lawrynowicz (((val) & ~(REG##_##FLD##_MASK)) | FIELD_PREP(REG##_##FLD##_MASK, num))
4535b13763SJacek Lawrynowicz #define REG_TEST_FLD(REG, FLD, val) \
4635b13763SJacek Lawrynowicz ((REG##_##FLD##_MASK) == ((val) & (REG##_##FLD##_MASK)))
4735b13763SJacek Lawrynowicz #define REG_TEST_FLD_NUM(REG, FLD, num, val) \
4835b13763SJacek Lawrynowicz ((num) == FIELD_GET(REG##_##FLD##_MASK, val))
4935b13763SJacek Lawrynowicz
5035b13763SJacek Lawrynowicz #define REGB_POLL_FLD(reg, fld, val, timeout_us) \
5135b13763SJacek Lawrynowicz ({ \
5235b13763SJacek Lawrynowicz u32 var; \
53*74ce0f38SKrystian Pradzynski int r; \
54*74ce0f38SKrystian Pradzynski ivpu_dbg(vdev, REG, "%s : %s (0x%08x) Polling field %s started (expected 0x%x)\n", \
55*74ce0f38SKrystian Pradzynski __func__, #reg, reg, #fld, val); \
56*74ce0f38SKrystian Pradzynski r = read_poll_timeout(REGB_RD32_SILENT, var, (FIELD_GET(reg##_##fld##_MASK, var) == (val)),\
57*74ce0f38SKrystian Pradzynski REG_POLL_SLEEP_US, timeout_us, false, (reg)); \
58*74ce0f38SKrystian Pradzynski ivpu_dbg(vdev, REG, "%s : %s (0x%08x) Polling field %s %s (reg val 0x%08x)\n", \
59*74ce0f38SKrystian Pradzynski __func__, #reg, reg, #fld, r ? "ETIMEDOUT" : "OK", var); \
60*74ce0f38SKrystian Pradzynski r; \
6135b13763SJacek Lawrynowicz })
6235b13763SJacek Lawrynowicz
6335b13763SJacek Lawrynowicz #define REGV_POLL_FLD(reg, fld, val, timeout_us) \
6435b13763SJacek Lawrynowicz ({ \
6535b13763SJacek Lawrynowicz u32 var; \
66*74ce0f38SKrystian Pradzynski int r; \
67*74ce0f38SKrystian Pradzynski ivpu_dbg(vdev, REG, "%s : %s (0x%08x) Polling field %s started (expected 0x%x)\n", \
68*74ce0f38SKrystian Pradzynski __func__, #reg, reg, #fld, val); \
69*74ce0f38SKrystian Pradzynski r = read_poll_timeout(REGV_RD32_SILENT, var, (FIELD_GET(reg##_##fld##_MASK, var) == (val)),\
70*74ce0f38SKrystian Pradzynski REG_POLL_SLEEP_US, timeout_us, false, (reg)); \
71*74ce0f38SKrystian Pradzynski ivpu_dbg(vdev, REG, "%s : %s (0x%08x) Polling field %s %s (reg val 0x%08x)\n", \
72*74ce0f38SKrystian Pradzynski __func__, #reg, reg, #fld, r ? "ETIMEDOUT" : "OK", var); \
73*74ce0f38SKrystian Pradzynski r; \
7435b13763SJacek Lawrynowicz })
7535b13763SJacek Lawrynowicz
7635b13763SJacek Lawrynowicz static inline u32
ivpu_hw_reg_rd32(struct ivpu_device * vdev,void __iomem * base,u32 reg,const char * name,const char * func)7735b13763SJacek Lawrynowicz ivpu_hw_reg_rd32(struct ivpu_device *vdev, void __iomem *base, u32 reg,
7835b13763SJacek Lawrynowicz const char *name, const char *func)
7935b13763SJacek Lawrynowicz {
8035b13763SJacek Lawrynowicz u32 val = readl(base + reg);
8135b13763SJacek Lawrynowicz
82*74ce0f38SKrystian Pradzynski ivpu_dbg(vdev, REG, "%s : %s (0x%08x) RD: 0x%08x\n", func, name, reg, val);
8335b13763SJacek Lawrynowicz return val;
8435b13763SJacek Lawrynowicz }
8535b13763SJacek Lawrynowicz
8635b13763SJacek Lawrynowicz static inline u64
ivpu_hw_reg_rd64(struct ivpu_device * vdev,void __iomem * base,u32 reg,const char * name,const char * func)8735b13763SJacek Lawrynowicz ivpu_hw_reg_rd64(struct ivpu_device *vdev, void __iomem *base, u32 reg,
8835b13763SJacek Lawrynowicz const char *name, const char *func)
8935b13763SJacek Lawrynowicz {
9035b13763SJacek Lawrynowicz u64 val = readq(base + reg);
9135b13763SJacek Lawrynowicz
92*74ce0f38SKrystian Pradzynski ivpu_dbg(vdev, REG, "%s : %s (0x%08x) RD: 0x%016llx\n", func, name, reg, val);
9335b13763SJacek Lawrynowicz return val;
9435b13763SJacek Lawrynowicz }
9535b13763SJacek Lawrynowicz
9635b13763SJacek Lawrynowicz static inline void
ivpu_hw_reg_wr32(struct ivpu_device * vdev,void __iomem * base,u32 reg,u32 val,const char * name,const char * func)9735b13763SJacek Lawrynowicz ivpu_hw_reg_wr32(struct ivpu_device *vdev, void __iomem *base, u32 reg, u32 val,
9835b13763SJacek Lawrynowicz const char *name, const char *func)
9935b13763SJacek Lawrynowicz {
100*74ce0f38SKrystian Pradzynski ivpu_dbg(vdev, REG, "%s : %s (0x%08x) WR: 0x%08x\n", func, name, reg, val);
10135b13763SJacek Lawrynowicz writel(val, base + reg);
10235b13763SJacek Lawrynowicz }
10335b13763SJacek Lawrynowicz
10435b13763SJacek Lawrynowicz static inline void
ivpu_hw_reg_wr64(struct ivpu_device * vdev,void __iomem * base,u32 reg,u64 val,const char * name,const char * func)10535b13763SJacek Lawrynowicz ivpu_hw_reg_wr64(struct ivpu_device *vdev, void __iomem *base, u32 reg, u64 val,
10635b13763SJacek Lawrynowicz const char *name, const char *func)
10735b13763SJacek Lawrynowicz {
108*74ce0f38SKrystian Pradzynski ivpu_dbg(vdev, REG, "%s : %s (0x%08x) WR: 0x%016llx\n", func, name, reg, val);
10935b13763SJacek Lawrynowicz writeq(val, base + reg);
11035b13763SJacek Lawrynowicz }
11135b13763SJacek Lawrynowicz
11235b13763SJacek Lawrynowicz static inline void
ivpu_hw_reg_wr32_index(struct ivpu_device * vdev,void __iomem * base,u32 reg,u32 stride,u32 index,u32 val,const char * name,const char * func)11335b13763SJacek Lawrynowicz ivpu_hw_reg_wr32_index(struct ivpu_device *vdev, void __iomem *base, u32 reg,
11435b13763SJacek Lawrynowicz u32 stride, u32 index, u32 val, const char *name,
11535b13763SJacek Lawrynowicz const char *func)
11635b13763SJacek Lawrynowicz {
11735b13763SJacek Lawrynowicz reg += index * stride;
11835b13763SJacek Lawrynowicz
11935b13763SJacek Lawrynowicz ivpu_dbg(vdev, REG, "%s WR: %s_%d (0x%08x) <= 0x%08x\n", func, name, index, reg, val);
12035b13763SJacek Lawrynowicz writel(val, base + reg);
12135b13763SJacek Lawrynowicz }
12235b13763SJacek Lawrynowicz
12335b13763SJacek Lawrynowicz #endif /* __IVPU_HW_REG_IO_H__ */
124