18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2010 Google, Inc. 48c2ecf20Sopenharmony_ci * Author: Erik Gilling <konkers@android.com> 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Copyright (C) 2011-2013 NVIDIA Corporation 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include "../dev.h" 108c2ecf20Sopenharmony_ci#include "../debug.h" 118c2ecf20Sopenharmony_ci#include "../cdma.h" 128c2ecf20Sopenharmony_ci#include "../channel.h" 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#define HOST1X_DEBUG_MAX_PAGE_OFFSET 102400 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_cienum { 178c2ecf20Sopenharmony_ci HOST1X_OPCODE_SETCLASS = 0x00, 188c2ecf20Sopenharmony_ci HOST1X_OPCODE_INCR = 0x01, 198c2ecf20Sopenharmony_ci HOST1X_OPCODE_NONINCR = 0x02, 208c2ecf20Sopenharmony_ci HOST1X_OPCODE_MASK = 0x03, 218c2ecf20Sopenharmony_ci HOST1X_OPCODE_IMM = 0x04, 228c2ecf20Sopenharmony_ci HOST1X_OPCODE_RESTART = 0x05, 238c2ecf20Sopenharmony_ci HOST1X_OPCODE_GATHER = 0x06, 248c2ecf20Sopenharmony_ci HOST1X_OPCODE_SETSTRMID = 0x07, 258c2ecf20Sopenharmony_ci HOST1X_OPCODE_SETAPPID = 0x08, 268c2ecf20Sopenharmony_ci HOST1X_OPCODE_SETPYLD = 0x09, 278c2ecf20Sopenharmony_ci HOST1X_OPCODE_INCR_W = 0x0a, 288c2ecf20Sopenharmony_ci HOST1X_OPCODE_NONINCR_W = 0x0b, 298c2ecf20Sopenharmony_ci HOST1X_OPCODE_GATHER_W = 0x0c, 308c2ecf20Sopenharmony_ci HOST1X_OPCODE_RESTART_W = 0x0d, 318c2ecf20Sopenharmony_ci HOST1X_OPCODE_EXTEND = 0x0e, 328c2ecf20Sopenharmony_ci}; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_cienum { 358c2ecf20Sopenharmony_ci HOST1X_OPCODE_EXTEND_ACQUIRE_MLOCK = 0x00, 368c2ecf20Sopenharmony_ci HOST1X_OPCODE_EXTEND_RELEASE_MLOCK = 0x01, 378c2ecf20Sopenharmony_ci}; 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci#define INVALID_PAYLOAD 0xffffffff 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_cistatic unsigned int show_channel_command(struct output *o, u32 val, 428c2ecf20Sopenharmony_ci u32 *payload) 438c2ecf20Sopenharmony_ci{ 448c2ecf20Sopenharmony_ci unsigned int mask, subop, num, opcode; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci opcode = val >> 28; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci switch (opcode) { 498c2ecf20Sopenharmony_ci case HOST1X_OPCODE_SETCLASS: 508c2ecf20Sopenharmony_ci mask = val & 0x3f; 518c2ecf20Sopenharmony_ci if (mask) { 528c2ecf20Sopenharmony_ci host1x_debug_cont(o, "SETCL(class=%03x, offset=%03x, mask=%02x, [", 538c2ecf20Sopenharmony_ci val >> 6 & 0x3ff, 548c2ecf20Sopenharmony_ci val >> 16 & 0xfff, mask); 558c2ecf20Sopenharmony_ci return hweight8(mask); 568c2ecf20Sopenharmony_ci } 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci host1x_debug_cont(o, "SETCL(class=%03x)\n", val >> 6 & 0x3ff); 598c2ecf20Sopenharmony_ci return 0; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci case HOST1X_OPCODE_INCR: 628c2ecf20Sopenharmony_ci num = val & 0xffff; 638c2ecf20Sopenharmony_ci host1x_debug_cont(o, "INCR(offset=%03x, [", 648c2ecf20Sopenharmony_ci val >> 16 & 0xfff); 658c2ecf20Sopenharmony_ci if (!num) 668c2ecf20Sopenharmony_ci host1x_debug_cont(o, "])\n"); 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci return num; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci case HOST1X_OPCODE_NONINCR: 718c2ecf20Sopenharmony_ci num = val & 0xffff; 728c2ecf20Sopenharmony_ci host1x_debug_cont(o, "NONINCR(offset=%03x, [", 738c2ecf20Sopenharmony_ci val >> 16 & 0xfff); 748c2ecf20Sopenharmony_ci if (!num) 758c2ecf20Sopenharmony_ci host1x_debug_cont(o, "])\n"); 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci return num; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci case HOST1X_OPCODE_MASK: 808c2ecf20Sopenharmony_ci mask = val & 0xffff; 818c2ecf20Sopenharmony_ci host1x_debug_cont(o, "MASK(offset=%03x, mask=%03x, [", 828c2ecf20Sopenharmony_ci val >> 16 & 0xfff, mask); 838c2ecf20Sopenharmony_ci if (!mask) 848c2ecf20Sopenharmony_ci host1x_debug_cont(o, "])\n"); 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci return hweight16(mask); 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci case HOST1X_OPCODE_IMM: 898c2ecf20Sopenharmony_ci host1x_debug_cont(o, "IMM(offset=%03x, data=%03x)\n", 908c2ecf20Sopenharmony_ci val >> 16 & 0xfff, val & 0xffff); 918c2ecf20Sopenharmony_ci return 0; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci case HOST1X_OPCODE_RESTART: 948c2ecf20Sopenharmony_ci host1x_debug_cont(o, "RESTART(offset=%08x)\n", val << 4); 958c2ecf20Sopenharmony_ci return 0; 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci case HOST1X_OPCODE_GATHER: 988c2ecf20Sopenharmony_ci host1x_debug_cont(o, "GATHER(offset=%03x, insert=%d, type=%d, count=%04x, addr=[", 998c2ecf20Sopenharmony_ci val >> 16 & 0xfff, val >> 15 & 0x1, 1008c2ecf20Sopenharmony_ci val >> 14 & 0x1, val & 0x3fff); 1018c2ecf20Sopenharmony_ci return 1; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci#if HOST1X_HW >= 6 1048c2ecf20Sopenharmony_ci case HOST1X_OPCODE_SETSTRMID: 1058c2ecf20Sopenharmony_ci host1x_debug_cont(o, "SETSTRMID(offset=%06x)\n", 1068c2ecf20Sopenharmony_ci val & 0x3fffff); 1078c2ecf20Sopenharmony_ci return 0; 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci case HOST1X_OPCODE_SETAPPID: 1108c2ecf20Sopenharmony_ci host1x_debug_cont(o, "SETAPPID(appid=%02x)\n", val & 0xff); 1118c2ecf20Sopenharmony_ci return 0; 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci case HOST1X_OPCODE_SETPYLD: 1148c2ecf20Sopenharmony_ci *payload = val & 0xffff; 1158c2ecf20Sopenharmony_ci host1x_debug_cont(o, "SETPYLD(data=%04x)\n", *payload); 1168c2ecf20Sopenharmony_ci return 0; 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci case HOST1X_OPCODE_INCR_W: 1198c2ecf20Sopenharmony_ci case HOST1X_OPCODE_NONINCR_W: 1208c2ecf20Sopenharmony_ci host1x_debug_cont(o, "%s(offset=%06x, ", 1218c2ecf20Sopenharmony_ci opcode == HOST1X_OPCODE_INCR_W ? 1228c2ecf20Sopenharmony_ci "INCR_W" : "NONINCR_W", 1238c2ecf20Sopenharmony_ci val & 0x3fffff); 1248c2ecf20Sopenharmony_ci if (*payload == 0) { 1258c2ecf20Sopenharmony_ci host1x_debug_cont(o, "[])\n"); 1268c2ecf20Sopenharmony_ci return 0; 1278c2ecf20Sopenharmony_ci } else if (*payload == INVALID_PAYLOAD) { 1288c2ecf20Sopenharmony_ci host1x_debug_cont(o, "unknown)\n"); 1298c2ecf20Sopenharmony_ci return 0; 1308c2ecf20Sopenharmony_ci } else { 1318c2ecf20Sopenharmony_ci host1x_debug_cont(o, "["); 1328c2ecf20Sopenharmony_ci return *payload; 1338c2ecf20Sopenharmony_ci } 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci case HOST1X_OPCODE_GATHER_W: 1368c2ecf20Sopenharmony_ci host1x_debug_cont(o, "GATHER_W(count=%04x, addr=[", 1378c2ecf20Sopenharmony_ci val & 0x3fff); 1388c2ecf20Sopenharmony_ci return 2; 1398c2ecf20Sopenharmony_ci#endif 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci case HOST1X_OPCODE_EXTEND: 1428c2ecf20Sopenharmony_ci subop = val >> 24 & 0xf; 1438c2ecf20Sopenharmony_ci if (subop == HOST1X_OPCODE_EXTEND_ACQUIRE_MLOCK) 1448c2ecf20Sopenharmony_ci host1x_debug_cont(o, "ACQUIRE_MLOCK(index=%d)\n", 1458c2ecf20Sopenharmony_ci val & 0xff); 1468c2ecf20Sopenharmony_ci else if (subop == HOST1X_OPCODE_EXTEND_RELEASE_MLOCK) 1478c2ecf20Sopenharmony_ci host1x_debug_cont(o, "RELEASE_MLOCK(index=%d)\n", 1488c2ecf20Sopenharmony_ci val & 0xff); 1498c2ecf20Sopenharmony_ci else 1508c2ecf20Sopenharmony_ci host1x_debug_cont(o, "EXTEND_UNKNOWN(%08x)\n", val); 1518c2ecf20Sopenharmony_ci return 0; 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci default: 1548c2ecf20Sopenharmony_ci host1x_debug_cont(o, "UNKNOWN\n"); 1558c2ecf20Sopenharmony_ci return 0; 1568c2ecf20Sopenharmony_ci } 1578c2ecf20Sopenharmony_ci} 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_cistatic void show_gather(struct output *o, phys_addr_t phys_addr, 1608c2ecf20Sopenharmony_ci unsigned int words, struct host1x_cdma *cdma, 1618c2ecf20Sopenharmony_ci phys_addr_t pin_addr, u32 *map_addr) 1628c2ecf20Sopenharmony_ci{ 1638c2ecf20Sopenharmony_ci /* Map dmaget cursor to corresponding mem handle */ 1648c2ecf20Sopenharmony_ci u32 offset = phys_addr - pin_addr; 1658c2ecf20Sopenharmony_ci unsigned int data_count = 0, i; 1668c2ecf20Sopenharmony_ci u32 payload = INVALID_PAYLOAD; 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci /* 1698c2ecf20Sopenharmony_ci * Sometimes we're given different hardware address to the same 1708c2ecf20Sopenharmony_ci * page - in these cases the offset will get an invalid number and 1718c2ecf20Sopenharmony_ci * we just have to bail out. 1728c2ecf20Sopenharmony_ci */ 1738c2ecf20Sopenharmony_ci if (offset > HOST1X_DEBUG_MAX_PAGE_OFFSET) { 1748c2ecf20Sopenharmony_ci host1x_debug_output(o, "[address mismatch]\n"); 1758c2ecf20Sopenharmony_ci return; 1768c2ecf20Sopenharmony_ci } 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci for (i = 0; i < words; i++) { 1798c2ecf20Sopenharmony_ci u32 addr = phys_addr + i * 4; 1808c2ecf20Sopenharmony_ci u32 val = *(map_addr + offset / 4 + i); 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci if (!data_count) { 1838c2ecf20Sopenharmony_ci host1x_debug_output(o, "%08x: %08x: ", addr, val); 1848c2ecf20Sopenharmony_ci data_count = show_channel_command(o, val, &payload); 1858c2ecf20Sopenharmony_ci } else { 1868c2ecf20Sopenharmony_ci host1x_debug_cont(o, "%08x%s", val, 1878c2ecf20Sopenharmony_ci data_count > 1 ? ", " : "])\n"); 1888c2ecf20Sopenharmony_ci data_count--; 1898c2ecf20Sopenharmony_ci } 1908c2ecf20Sopenharmony_ci } 1918c2ecf20Sopenharmony_ci} 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_cistatic void show_channel_gathers(struct output *o, struct host1x_cdma *cdma) 1948c2ecf20Sopenharmony_ci{ 1958c2ecf20Sopenharmony_ci struct push_buffer *pb = &cdma->push_buffer; 1968c2ecf20Sopenharmony_ci struct host1x_job *job; 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci host1x_debug_output(o, "PUSHBUF at %pad, %u words\n", 1998c2ecf20Sopenharmony_ci &pb->dma, pb->size / 4); 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci show_gather(o, pb->dma, pb->size / 4, cdma, pb->dma, pb->mapped); 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci list_for_each_entry(job, &cdma->sync_queue, list) { 2048c2ecf20Sopenharmony_ci unsigned int i; 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci host1x_debug_output(o, "\n%p: JOB, syncpt_id=%d, syncpt_val=%d, first_get=%08x, timeout=%d num_slots=%d, num_handles=%d\n", 2078c2ecf20Sopenharmony_ci job, job->syncpt_id, job->syncpt_end, 2088c2ecf20Sopenharmony_ci job->first_get, job->timeout, 2098c2ecf20Sopenharmony_ci job->num_slots, job->num_unpins); 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci for (i = 0; i < job->num_gathers; i++) { 2128c2ecf20Sopenharmony_ci struct host1x_job_gather *g = &job->gathers[i]; 2138c2ecf20Sopenharmony_ci u32 *mapped; 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci if (job->gather_copy_mapped) 2168c2ecf20Sopenharmony_ci mapped = (u32 *)job->gather_copy_mapped; 2178c2ecf20Sopenharmony_ci else 2188c2ecf20Sopenharmony_ci mapped = host1x_bo_mmap(g->bo); 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci if (!mapped) { 2218c2ecf20Sopenharmony_ci host1x_debug_output(o, "[could not mmap]\n"); 2228c2ecf20Sopenharmony_ci continue; 2238c2ecf20Sopenharmony_ci } 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci host1x_debug_output(o, " GATHER at %pad+%#x, %d words\n", 2268c2ecf20Sopenharmony_ci &g->base, g->offset, g->words); 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci show_gather(o, g->base + g->offset, g->words, cdma, 2298c2ecf20Sopenharmony_ci g->base, mapped); 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci if (!job->gather_copy_mapped) 2328c2ecf20Sopenharmony_ci host1x_bo_munmap(g->bo, mapped); 2338c2ecf20Sopenharmony_ci } 2348c2ecf20Sopenharmony_ci } 2358c2ecf20Sopenharmony_ci} 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci#if HOST1X_HW >= 6 2388c2ecf20Sopenharmony_ci#include "debug_hw_1x06.c" 2398c2ecf20Sopenharmony_ci#else 2408c2ecf20Sopenharmony_ci#include "debug_hw_1x01.c" 2418c2ecf20Sopenharmony_ci#endif 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_cistatic const struct host1x_debug_ops host1x_debug_ops = { 2448c2ecf20Sopenharmony_ci .show_channel_cdma = host1x_debug_show_channel_cdma, 2458c2ecf20Sopenharmony_ci .show_channel_fifo = host1x_debug_show_channel_fifo, 2468c2ecf20Sopenharmony_ci .show_mlocks = host1x_debug_show_mlocks, 2478c2ecf20Sopenharmony_ci}; 248