static void guc_ct_ctb_h2g_init(struct xe_device *xe, struct guc_ctb *h2g,
struct iosys_map *map)
{
- h2g->size = CTB_H2G_BUFFER_SIZE / sizeof(u32);
- h2g->resv_space = 0;
- h2g->tail = 0;
- h2g->head = 0;
- h2g->space = CIRC_SPACE(h2g->tail, h2g->head, h2g->size) -
- h2g->resv_space;
- h2g->broken = false;
+ h2g->info.size = CTB_H2G_BUFFER_SIZE / sizeof(u32);
+ h2g->info.resv_space = 0;
+ h2g->info.tail = 0;
+ h2g->info.head = 0;
+ h2g->info.space = CIRC_SPACE(h2g->info.tail, h2g->info.head,
+ h2g->info.size) -
+ h2g->info.resv_space;
+ h2g->info.broken = false;
h2g->desc = *map;
xe_map_memset(xe, &h2g->desc, 0, 0, sizeof(struct guc_ct_buffer_desc));
static void guc_ct_ctb_g2h_init(struct xe_device *xe, struct guc_ctb *g2h,
struct iosys_map *map)
{
- g2h->size = CTB_G2H_BUFFER_SIZE / sizeof(u32);
- g2h->resv_space = G2H_ROOM_BUFFER_SIZE / sizeof(u32);
- g2h->head = 0;
- g2h->tail = 0;
- g2h->space = CIRC_SPACE(g2h->tail, g2h->head, g2h->size) -
- g2h->resv_space;
- g2h->broken = false;
+ g2h->info.size = CTB_G2H_BUFFER_SIZE / sizeof(u32);
+ g2h->info.resv_space = G2H_ROOM_BUFFER_SIZE / sizeof(u32);
+ g2h->info.head = 0;
+ g2h->info.tail = 0;
+ g2h->info.space = CIRC_SPACE(g2h->info.tail, g2h->info.head,
+ g2h->info.size) -
+ g2h->info.resv_space;
+ g2h->info.broken = false;
g2h->desc = IOSYS_MAP_INIT_OFFSET(map, CTB_DESC_SIZE);
xe_map_memset(xe, &g2h->desc, 0, 0, sizeof(struct guc_ct_buffer_desc));
desc_addr = xe_bo_ggtt_addr(ct->bo);
ctb_addr = xe_bo_ggtt_addr(ct->bo) + CTB_DESC_SIZE * 2;
- size = ct->ctbs.h2g.size * sizeof(u32);
+ size = ct->ctbs.h2g.info.size * sizeof(u32);
err = xe_guc_self_cfg64(guc,
GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR_KEY,
desc_addr = xe_bo_ggtt_addr(ct->bo) + CTB_DESC_SIZE;
ctb_addr = xe_bo_ggtt_addr(ct->bo) + CTB_DESC_SIZE * 2 +
CTB_H2G_BUFFER_SIZE;
- size = ct->ctbs.g2h.size * sizeof(u32);
+ size = ct->ctbs.g2h.info.size * sizeof(u32);
err = xe_guc_self_cfg64(guc,
GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR_KEY,
lockdep_assert_held(&ct->lock);
- if (cmd_len > h2g->space) {
- h2g->head = desc_read(ct_to_xe(ct), h2g, head);
- h2g->space = CIRC_SPACE(h2g->tail, h2g->head, h2g->size) -
- h2g->resv_space;
- if (cmd_len > h2g->space)
+ if (cmd_len > h2g->info.space) {
+ h2g->info.head = desc_read(ct_to_xe(ct), h2g, head);
+ h2g->info.space = CIRC_SPACE(h2g->info.tail, h2g->info.head,
+ h2g->info.size) -
+ h2g->info.resv_space;
+ if (cmd_len > h2g->info.space)
return false;
}
{
lockdep_assert_held(&ct->lock);
- return ct->ctbs.g2h.space > g2h_len;
+ return ct->ctbs.g2h.info.space > g2h_len;
}
static int has_room(struct xe_guc_ct *ct, u32 cmd_len, u32 g2h_len)
static void h2g_reserve_space(struct xe_guc_ct *ct, u32 cmd_len)
{
lockdep_assert_held(&ct->lock);
- ct->ctbs.h2g.space -= cmd_len;
+ ct->ctbs.h2g.info.space -= cmd_len;
}
static void g2h_reserve_space(struct xe_guc_ct *ct, u32 g2h_len, u32 num_g2h)
{
- XE_BUG_ON(g2h_len > ct->ctbs.g2h.space);
+ XE_BUG_ON(g2h_len > ct->ctbs.g2h.info.space);
if (g2h_len) {
spin_lock_irq(&ct->fast_lock);
- ct->ctbs.g2h.space -= g2h_len;
+ ct->ctbs.g2h.info.space -= g2h_len;
ct->g2h_outstanding += num_g2h;
spin_unlock_irq(&ct->fast_lock);
}
static void __g2h_release_space(struct xe_guc_ct *ct, u32 g2h_len)
{
lockdep_assert_held(&ct->fast_lock);
- XE_WARN_ON(ct->ctbs.g2h.space + g2h_len >
- ct->ctbs.g2h.size - ct->ctbs.g2h.resv_space);
+ XE_WARN_ON(ct->ctbs.g2h.info.space + g2h_len >
+ ct->ctbs.g2h.info.size - ct->ctbs.g2h.info.resv_space);
- ct->ctbs.g2h.space += g2h_len;
+ ct->ctbs.g2h.info.space += g2h_len;
--ct->g2h_outstanding;
}
u32 cmd[GUC_CTB_MSG_MAX_LEN / sizeof(u32)];
u32 cmd_len = len + GUC_CTB_HDR_LEN;
u32 cmd_idx = 0, i;
- u32 tail = h2g->tail;
+ u32 tail = h2g->info.tail;
struct iosys_map map = IOSYS_MAP_INIT_OFFSET(&h2g->cmds,
tail * sizeof(u32));
lockdep_assert_held(&ct->lock);
XE_BUG_ON(len * sizeof(u32) > GUC_CTB_MSG_MAX_LEN);
- XE_BUG_ON(tail > h2g->size);
+ XE_BUG_ON(tail > h2g->info.size);
/* Command will wrap, zero fill (NOPs), return and check credits again */
- if (tail + cmd_len > h2g->size) {
- xe_map_memset(xe, &map, 0, 0, (h2g->size - tail) * sizeof(u32));
- h2g_reserve_space(ct, (h2g->size - tail));
- h2g->tail = 0;
- desc_write(xe, h2g, tail, h2g->tail);
+ if (tail + cmd_len > h2g->info.size) {
+ xe_map_memset(xe, &map, 0, 0,
+ (h2g->info.size - tail) * sizeof(u32));
+ h2g_reserve_space(ct, (h2g->info.size - tail));
+ h2g->info.tail = 0;
+ desc_write(xe, h2g, tail, h2g->info.tail);
return -EAGAIN;
}
xe_device_wmb(ct_to_xe(ct));
/* Update local copies */
- h2g->tail = (tail + cmd_len) % h2g->size;
+ h2g->info.tail = (tail + cmd_len) % h2g->info.size;
h2g_reserve_space(ct, cmd_len);
/* Update descriptor */
- desc_write(xe, h2g, tail, h2g->tail);
+ desc_write(xe, h2g, tail, h2g->info.tail);
return 0;
}
XE_BUG_ON(!g2h_len && num_g2h);
lockdep_assert_held(&ct->lock);
- if (unlikely(ct->ctbs.h2g.broken)) {
+ if (unlikely(ct->ctbs.h2g.info.broken)) {
ret = -EPIPE;
goto out;
}
if (sleep_period_ms == 1024)
goto broken;
- trace_xe_guc_ct_h2g_flow_control(h2g->head, h2g->tail,
- h2g->size, h2g->space,
+ trace_xe_guc_ct_h2g_flow_control(h2g->info.head, h2g->info.tail,
+ h2g->info.size,
+ h2g->info.space,
len + GUC_CTB_HDR_LEN);
msleep(sleep_period_ms);
sleep_period_ms <<= 1;
struct xe_device *xe = ct_to_xe(ct);
struct guc_ctb *g2h = &ct->ctbs.g2h;
- trace_xe_guc_ct_g2h_flow_control(g2h->head,
+ trace_xe_guc_ct_g2h_flow_control(g2h->info.head,
desc_read(xe, g2h, tail),
- g2h->size, g2h->space,
+ g2h->info.size,
+ g2h->info.space,
g2h_fence ?
GUC_CTB_HXG_MSG_MAX_LEN :
g2h_len);
#define g2h_avail(ct) \
- (desc_read(ct_to_xe(ct), (&ct->ctbs.g2h), tail) != ct->ctbs.g2h.head)
+ (desc_read(ct_to_xe(ct), (&ct->ctbs.g2h), tail) != ct->ctbs.g2h.info.head)
if (!wait_event_timeout(ct->wq, !ct->g2h_outstanding ||
g2h_avail(ct), HZ))
goto broken;
broken:
drm_err(drm, "No forward process on H2G, reset required");
xe_guc_ct_print(ct, &p);
- ct->ctbs.h2g.broken = true;
+ ct->ctbs.h2g.info.broken = true;
return -EDEADLK;
}
return false;
#define ct_alive(ct) \
- (ct->enabled && !ct->ctbs.h2g.broken && !ct->ctbs.g2h.broken)
+ (ct->enabled && !ct->ctbs.h2g.info.broken && !ct->ctbs.g2h.info.broken)
if (!wait_event_interruptible_timeout(ct->wq, ct_alive(ct), HZ * 5))
return false;
#undef ct_alive
drm_err(&xe->drm,
"G2H channel broken on read, origin=%d, reset required\n",
origin);
- ct->ctbs.g2h.broken = true;
+ ct->ctbs.g2h.info.broken = true;
return -EPROTO;
}
drm_err(&xe->drm,
"G2H channel broken on read, type=%d, reset required\n",
type);
- ct->ctbs.g2h.broken = true;
+ ct->ctbs.g2h.info.broken = true;
ret = -EOPNOTSUPP;
}
if (!ct->enabled)
return -ENODEV;
- if (g2h->broken)
+ if (g2h->info.broken)
return -EPIPE;
/* Calculate DW available to read */
tail = desc_read(xe, g2h, tail);
- avail = tail - g2h->head;
+ avail = tail - g2h->info.head;
if (unlikely(avail == 0))
return 0;
if (avail < 0)
- avail += g2h->size;
+ avail += g2h->info.size;
/* Read header */
- xe_map_memcpy_from(xe, msg, &g2h->cmds, sizeof(u32) * g2h->head, sizeof(u32));
+ xe_map_memcpy_from(xe, msg, &g2h->cmds, sizeof(u32) * g2h->info.head,
+ sizeof(u32));
len = FIELD_GET(GUC_CTB_MSG_0_NUM_DWORDS, msg[0]) + GUC_CTB_MSG_MIN_LEN;
if (len > avail) {
drm_err(&xe->drm,
"G2H channel broken on read, avail=%d, len=%d, reset required\n",
avail, len);
- g2h->broken = true;
+ g2h->info.broken = true;
return -EPROTO;
}
- head = (g2h->head + 1) % g2h->size;
+ head = (g2h->info.head + 1) % g2h->info.size;
avail = len - 1;
/* Read G2H message */
- if (avail + head > g2h->size) {
- u32 avail_til_wrap = g2h->size - head;
+ if (avail + head > g2h->info.size) {
+ u32 avail_til_wrap = g2h->info.size - head;
xe_map_memcpy_from(xe, msg + 1,
&g2h->cmds, sizeof(u32) * head,
}
/* Update local / descriptor header */
- g2h->head = (head + avail) % g2h->size;
- desc_write(xe, g2h, head, g2h->head);
+ g2h->info.head = (head + avail) % g2h->info.size;
+ desc_write(xe, g2h, head, g2h->info.head);
return len;
}
{
u32 head, tail;
- drm_printf(p, "\tsize: %d\n", ctb->size);
- drm_printf(p, "\tresv_space: %d\n", ctb->resv_space);
- drm_printf(p, "\thead: %d\n", ctb->head);
- drm_printf(p, "\ttail: %d\n", ctb->tail);
- drm_printf(p, "\tspace: %d\n", ctb->space);
- drm_printf(p, "\tbroken: %d\n", ctb->broken);
+ drm_printf(p, "\tsize: %d\n", ctb->info.size);
+ drm_printf(p, "\tresv_space: %d\n", ctb->info.resv_space);
+ drm_printf(p, "\thead: %d\n", ctb->info.head);
+ drm_printf(p, "\ttail: %d\n", ctb->info.tail);
+ drm_printf(p, "\tspace: %d\n", ctb->info.space);
+ drm_printf(p, "\tbroken: %d\n", ctb->info.broken);
head = desc_read(xe, ctb, head);
tail = desc_read(xe, ctb, tail);
drm_printf(p, "\tcmd[%d]: 0x%08x\n", head,
xe_map_rd(xe, &map, 0, u32));
++head;
- if (head == ctb->size) {
+ if (head == ctb->info.size) {
head = 0;
map = ctb->cmds;
} else {
if (!ret) {
xe_guc_ct_irq_handler(ct);
msleep(200);
- if (g2h->space !=
- CIRC_SPACE(0, 0, g2h->size) - g2h->resv_space) {
+ if (g2h->info.space !=
+ CIRC_SPACE(0, 0, g2h->info.size) - g2h->info.resv_space) {
drm_printf(p, "Mismatch on space %d, %d\n",
- g2h->space,
- CIRC_SPACE(0, 0, g2h->size) -
- g2h->resv_space);
+ g2h->info.space,
+ CIRC_SPACE(0, 0, g2h->info.size) -
+ g2h->info.resv_space);
ret = -EIO;
}
if (ct->g2h_outstanding) {
/* Check failure path for blocking CTs too */
xe_guc_ct_send_block(ct, bad_action, ARRAY_SIZE(bad_action));
- if (g2h->space !=
- CIRC_SPACE(0, 0, g2h->size) - g2h->resv_space) {
+ if (g2h->info.space !=
+ CIRC_SPACE(0, 0, g2h->info.size) - g2h->info.resv_space) {
drm_printf(p, "Mismatch on space %d, %d\n",
- g2h->space,
- CIRC_SPACE(0, 0, g2h->size) -
- g2h->resv_space);
+ g2h->info.space,
+ CIRC_SPACE(0, 0, g2h->info.size) -
+ g2h->info.resv_space);
ret = -EIO;
}
if (ct->g2h_outstanding) {