mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
drm/panthor: Support 64-bit endpoint_req register for Mali-G1
Add support for the 64-bit endpoint_req register introduced in CSF v4.0+ GPUs. Unlike a simple register widening, the 64-bit variant occupies the next 64 bits after the original 32-bit field, requiring version-dependent access. This change introduces helper functions to read, write, and update the endpoint_req register, ensuring correct handling on both pre-v4.0 and v4.0+ firmwares. Reviewed-by: Steven Price <steven.price@arm.com> Signed-off-by: Karunika Choo <karunika.choo@arm.com> Link: https://patch.msgid.link/20251125125548.3282320-8-karunika.choo@arm.com Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
This commit is contained in:
committed by
Boris Brezillon
parent
5140725498
commit
2008f49a63
@@ -326,6 +326,42 @@ static bool panthor_fw_has_glb_state(struct panthor_device *ptdev)
|
|||||||
return glb_iface->control->version >= CSF_IFACE_VERSION(4, 1, 0);
|
return glb_iface->control->version >= CSF_IFACE_VERSION(4, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool panthor_fw_has_64bit_ep_req(struct panthor_device *ptdev)
|
||||||
|
{
|
||||||
|
struct panthor_fw_global_iface *glb_iface = panthor_fw_get_glb_iface(ptdev);
|
||||||
|
|
||||||
|
return glb_iface->control->version >= CSF_IFACE_VERSION(4, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 panthor_fw_csg_endpoint_req_get(struct panthor_device *ptdev,
|
||||||
|
struct panthor_fw_csg_iface *csg_iface)
|
||||||
|
{
|
||||||
|
if (panthor_fw_has_64bit_ep_req(ptdev))
|
||||||
|
return csg_iface->input->endpoint_req2;
|
||||||
|
else
|
||||||
|
return csg_iface->input->endpoint_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
void panthor_fw_csg_endpoint_req_set(struct panthor_device *ptdev,
|
||||||
|
struct panthor_fw_csg_iface *csg_iface, u64 value)
|
||||||
|
{
|
||||||
|
if (panthor_fw_has_64bit_ep_req(ptdev))
|
||||||
|
csg_iface->input->endpoint_req2 = value;
|
||||||
|
else
|
||||||
|
csg_iface->input->endpoint_req = lower_32_bits(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void panthor_fw_csg_endpoint_req_update(struct panthor_device *ptdev,
|
||||||
|
struct panthor_fw_csg_iface *csg_iface, u64 value,
|
||||||
|
u64 mask)
|
||||||
|
{
|
||||||
|
if (panthor_fw_has_64bit_ep_req(ptdev))
|
||||||
|
panthor_fw_update_reqs64(csg_iface, endpoint_req2, value, mask);
|
||||||
|
else
|
||||||
|
panthor_fw_update_reqs(csg_iface, endpoint_req, lower_32_bits(value),
|
||||||
|
lower_32_bits(mask));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* panthor_fw_conv_timeout() - Convert a timeout into a cycle-count
|
* panthor_fw_conv_timeout() - Convert a timeout into a cycle-count
|
||||||
* @ptdev: Device.
|
* @ptdev: Device.
|
||||||
|
|||||||
@@ -167,10 +167,11 @@ struct panthor_fw_csg_input_iface {
|
|||||||
#define CSG_EP_REQ_TILER(x) (((x) << 16) & GENMASK(19, 16))
|
#define CSG_EP_REQ_TILER(x) (((x) << 16) & GENMASK(19, 16))
|
||||||
#define CSG_EP_REQ_EXCL_COMPUTE BIT(20)
|
#define CSG_EP_REQ_EXCL_COMPUTE BIT(20)
|
||||||
#define CSG_EP_REQ_EXCL_FRAGMENT BIT(21)
|
#define CSG_EP_REQ_EXCL_FRAGMENT BIT(21)
|
||||||
#define CSG_EP_REQ_PRIORITY(x) (((x) << 28) & GENMASK(31, 28))
|
|
||||||
#define CSG_EP_REQ_PRIORITY_MASK GENMASK(31, 28)
|
#define CSG_EP_REQ_PRIORITY_MASK GENMASK(31, 28)
|
||||||
|
#define CSG_EP_REQ_PRIORITY(x) (((x) << 28) & CSG_EP_REQ_PRIORITY_MASK)
|
||||||
|
#define CSG_EP_REQ_PRIORITY_GET(x) (((x) & CSG_EP_REQ_PRIORITY_MASK) >> 28)
|
||||||
u32 endpoint_req;
|
u32 endpoint_req;
|
||||||
u32 reserved2[2];
|
u64 endpoint_req2;
|
||||||
u64 suspend_buf;
|
u64 suspend_buf;
|
||||||
u64 protm_suspend_buf;
|
u64 protm_suspend_buf;
|
||||||
u32 config;
|
u32 config;
|
||||||
@@ -464,6 +465,16 @@ struct panthor_fw_global_iface {
|
|||||||
spin_unlock(&(__iface)->lock); \
|
spin_unlock(&(__iface)->lock); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define panthor_fw_update_reqs64(__iface, __in_reg, __val, __mask) \
|
||||||
|
do { \
|
||||||
|
u64 __cur_val, __new_val; \
|
||||||
|
spin_lock(&(__iface)->lock); \
|
||||||
|
__cur_val = READ_ONCE((__iface)->input->__in_reg); \
|
||||||
|
__new_val = (__cur_val & ~(__mask)) | ((__val) & (__mask)); \
|
||||||
|
WRITE_ONCE((__iface)->input->__in_reg, __new_val); \
|
||||||
|
spin_unlock(&(__iface)->lock); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
struct panthor_fw_global_iface *
|
struct panthor_fw_global_iface *
|
||||||
panthor_fw_get_glb_iface(struct panthor_device *ptdev);
|
panthor_fw_get_glb_iface(struct panthor_device *ptdev);
|
||||||
|
|
||||||
@@ -473,6 +484,16 @@ panthor_fw_get_csg_iface(struct panthor_device *ptdev, u32 csg_slot);
|
|||||||
struct panthor_fw_cs_iface *
|
struct panthor_fw_cs_iface *
|
||||||
panthor_fw_get_cs_iface(struct panthor_device *ptdev, u32 csg_slot, u32 cs_slot);
|
panthor_fw_get_cs_iface(struct panthor_device *ptdev, u32 csg_slot, u32 cs_slot);
|
||||||
|
|
||||||
|
u64 panthor_fw_csg_endpoint_req_get(struct panthor_device *ptdev,
|
||||||
|
struct panthor_fw_csg_iface *csg_iface);
|
||||||
|
|
||||||
|
void panthor_fw_csg_endpoint_req_set(struct panthor_device *ptdev,
|
||||||
|
struct panthor_fw_csg_iface *csg_iface, u64 value);
|
||||||
|
|
||||||
|
void panthor_fw_csg_endpoint_req_update(struct panthor_device *ptdev,
|
||||||
|
struct panthor_fw_csg_iface *csg_iface, u64 value,
|
||||||
|
u64 mask);
|
||||||
|
|
||||||
int panthor_fw_csg_wait_acks(struct panthor_device *ptdev, u32 csg_id, u32 req_mask,
|
int panthor_fw_csg_wait_acks(struct panthor_device *ptdev, u32 csg_id, u32 req_mask,
|
||||||
u32 *acked, u32 timeout_ms);
|
u32 *acked, u32 timeout_ms);
|
||||||
|
|
||||||
|
|||||||
@@ -1140,11 +1140,13 @@ csg_slot_sync_priority_locked(struct panthor_device *ptdev, u32 csg_id)
|
|||||||
{
|
{
|
||||||
struct panthor_csg_slot *csg_slot = &ptdev->scheduler->csg_slots[csg_id];
|
struct panthor_csg_slot *csg_slot = &ptdev->scheduler->csg_slots[csg_id];
|
||||||
struct panthor_fw_csg_iface *csg_iface;
|
struct panthor_fw_csg_iface *csg_iface;
|
||||||
|
u64 endpoint_req;
|
||||||
|
|
||||||
lockdep_assert_held(&ptdev->scheduler->lock);
|
lockdep_assert_held(&ptdev->scheduler->lock);
|
||||||
|
|
||||||
csg_iface = panthor_fw_get_csg_iface(ptdev, csg_id);
|
csg_iface = panthor_fw_get_csg_iface(ptdev, csg_id);
|
||||||
csg_slot->priority = (csg_iface->input->endpoint_req & CSG_EP_REQ_PRIORITY_MASK) >> 28;
|
endpoint_req = panthor_fw_csg_endpoint_req_get(ptdev, csg_iface);
|
||||||
|
csg_slot->priority = CSG_EP_REQ_PRIORITY_GET(endpoint_req);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1304,6 +1306,7 @@ csg_slot_prog_locked(struct panthor_device *ptdev, u32 csg_id, u32 priority)
|
|||||||
struct panthor_csg_slot *csg_slot;
|
struct panthor_csg_slot *csg_slot;
|
||||||
struct panthor_group *group;
|
struct panthor_group *group;
|
||||||
u32 queue_mask = 0, i;
|
u32 queue_mask = 0, i;
|
||||||
|
u64 endpoint_req;
|
||||||
|
|
||||||
lockdep_assert_held(&ptdev->scheduler->lock);
|
lockdep_assert_held(&ptdev->scheduler->lock);
|
||||||
|
|
||||||
@@ -1330,10 +1333,12 @@ csg_slot_prog_locked(struct panthor_device *ptdev, u32 csg_id, u32 priority)
|
|||||||
csg_iface->input->allow_compute = group->compute_core_mask;
|
csg_iface->input->allow_compute = group->compute_core_mask;
|
||||||
csg_iface->input->allow_fragment = group->fragment_core_mask;
|
csg_iface->input->allow_fragment = group->fragment_core_mask;
|
||||||
csg_iface->input->allow_other = group->tiler_core_mask;
|
csg_iface->input->allow_other = group->tiler_core_mask;
|
||||||
csg_iface->input->endpoint_req = CSG_EP_REQ_COMPUTE(group->max_compute_cores) |
|
endpoint_req = CSG_EP_REQ_COMPUTE(group->max_compute_cores) |
|
||||||
CSG_EP_REQ_FRAGMENT(group->max_fragment_cores) |
|
CSG_EP_REQ_FRAGMENT(group->max_fragment_cores) |
|
||||||
CSG_EP_REQ_TILER(group->max_tiler_cores) |
|
CSG_EP_REQ_TILER(group->max_tiler_cores) |
|
||||||
CSG_EP_REQ_PRIORITY(priority);
|
CSG_EP_REQ_PRIORITY(priority);
|
||||||
|
panthor_fw_csg_endpoint_req_set(ptdev, csg_iface, endpoint_req);
|
||||||
|
|
||||||
csg_iface->input->config = panthor_vm_as(group->vm);
|
csg_iface->input->config = panthor_vm_as(group->vm);
|
||||||
|
|
||||||
if (group->suspend_buf)
|
if (group->suspend_buf)
|
||||||
@@ -2231,7 +2236,7 @@ tick_ctx_apply(struct panthor_scheduler *sched, struct panthor_sched_tick_ctx *c
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
panthor_fw_update_reqs(csg_iface, endpoint_req,
|
panthor_fw_csg_endpoint_req_update(ptdev, csg_iface,
|
||||||
CSG_EP_REQ_PRIORITY(new_csg_prio),
|
CSG_EP_REQ_PRIORITY(new_csg_prio),
|
||||||
CSG_EP_REQ_PRIORITY_MASK);
|
CSG_EP_REQ_PRIORITY_MASK);
|
||||||
csgs_upd_ctx_queue_reqs(ptdev, &upd_ctx, csg_id,
|
csgs_upd_ctx_queue_reqs(ptdev, &upd_ctx, csg_id,
|
||||||
|
|||||||
Reference in New Issue
Block a user