0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "../dev.h"
0010 #include "../debug.h"
0011 #include "../cdma.h"
0012 #include "../channel.h"
0013
0014 #define HOST1X_DEBUG_MAX_PAGE_OFFSET 102400
0015
0016 enum {
0017 HOST1X_OPCODE_SETCLASS = 0x00,
0018 HOST1X_OPCODE_INCR = 0x01,
0019 HOST1X_OPCODE_NONINCR = 0x02,
0020 HOST1X_OPCODE_MASK = 0x03,
0021 HOST1X_OPCODE_IMM = 0x04,
0022 HOST1X_OPCODE_RESTART = 0x05,
0023 HOST1X_OPCODE_GATHER = 0x06,
0024 HOST1X_OPCODE_SETSTRMID = 0x07,
0025 HOST1X_OPCODE_SETAPPID = 0x08,
0026 HOST1X_OPCODE_SETPYLD = 0x09,
0027 HOST1X_OPCODE_INCR_W = 0x0a,
0028 HOST1X_OPCODE_NONINCR_W = 0x0b,
0029 HOST1X_OPCODE_GATHER_W = 0x0c,
0030 HOST1X_OPCODE_RESTART_W = 0x0d,
0031 HOST1X_OPCODE_EXTEND = 0x0e,
0032 };
0033
0034 enum {
0035 HOST1X_OPCODE_EXTEND_ACQUIRE_MLOCK = 0x00,
0036 HOST1X_OPCODE_EXTEND_RELEASE_MLOCK = 0x01,
0037 };
0038
0039 #define INVALID_PAYLOAD 0xffffffff
0040
0041 static unsigned int show_channel_command(struct output *o, u32 val,
0042 u32 *payload)
0043 {
0044 unsigned int mask, subop, num, opcode;
0045
0046 opcode = val >> 28;
0047
0048 switch (opcode) {
0049 case HOST1X_OPCODE_SETCLASS:
0050 mask = val & 0x3f;
0051 if (mask) {
0052 host1x_debug_cont(o, "SETCL(class=%03x, offset=%03x, mask=%02x, [",
0053 val >> 6 & 0x3ff,
0054 val >> 16 & 0xfff, mask);
0055 return hweight8(mask);
0056 }
0057
0058 host1x_debug_cont(o, "SETCL(class=%03x)\n", val >> 6 & 0x3ff);
0059 return 0;
0060
0061 case HOST1X_OPCODE_INCR:
0062 num = val & 0xffff;
0063 host1x_debug_cont(o, "INCR(offset=%03x, [",
0064 val >> 16 & 0xfff);
0065 if (!num)
0066 host1x_debug_cont(o, "])\n");
0067
0068 return num;
0069
0070 case HOST1X_OPCODE_NONINCR:
0071 num = val & 0xffff;
0072 host1x_debug_cont(o, "NONINCR(offset=%03x, [",
0073 val >> 16 & 0xfff);
0074 if (!num)
0075 host1x_debug_cont(o, "])\n");
0076
0077 return num;
0078
0079 case HOST1X_OPCODE_MASK:
0080 mask = val & 0xffff;
0081 host1x_debug_cont(o, "MASK(offset=%03x, mask=%03x, [",
0082 val >> 16 & 0xfff, mask);
0083 if (!mask)
0084 host1x_debug_cont(o, "])\n");
0085
0086 return hweight16(mask);
0087
0088 case HOST1X_OPCODE_IMM:
0089 host1x_debug_cont(o, "IMM(offset=%03x, data=%03x)\n",
0090 val >> 16 & 0xfff, val & 0xffff);
0091 return 0;
0092
0093 case HOST1X_OPCODE_RESTART:
0094 host1x_debug_cont(o, "RESTART(offset=%08x)\n", val << 4);
0095 return 0;
0096
0097 case HOST1X_OPCODE_GATHER:
0098 host1x_debug_cont(o, "GATHER(offset=%03x, insert=%d, type=%d, count=%04x, addr=[",
0099 val >> 16 & 0xfff, val >> 15 & 0x1,
0100 val >> 14 & 0x1, val & 0x3fff);
0101 return 1;
0102
0103 #if HOST1X_HW >= 6
0104 case HOST1X_OPCODE_SETSTRMID:
0105 host1x_debug_cont(o, "SETSTRMID(offset=%06x)\n",
0106 val & 0x3fffff);
0107 return 0;
0108
0109 case HOST1X_OPCODE_SETAPPID:
0110 host1x_debug_cont(o, "SETAPPID(appid=%02x)\n", val & 0xff);
0111 return 0;
0112
0113 case HOST1X_OPCODE_SETPYLD:
0114 *payload = val & 0xffff;
0115 host1x_debug_cont(o, "SETPYLD(data=%04x)\n", *payload);
0116 return 0;
0117
0118 case HOST1X_OPCODE_INCR_W:
0119 case HOST1X_OPCODE_NONINCR_W:
0120 host1x_debug_cont(o, "%s(offset=%06x, ",
0121 opcode == HOST1X_OPCODE_INCR_W ?
0122 "INCR_W" : "NONINCR_W",
0123 val & 0x3fffff);
0124 if (*payload == 0) {
0125 host1x_debug_cont(o, "[])\n");
0126 return 0;
0127 } else if (*payload == INVALID_PAYLOAD) {
0128 host1x_debug_cont(o, "unknown)\n");
0129 return 0;
0130 } else {
0131 host1x_debug_cont(o, "[");
0132 return *payload;
0133 }
0134
0135 case HOST1X_OPCODE_GATHER_W:
0136 host1x_debug_cont(o, "GATHER_W(count=%04x, addr=[",
0137 val & 0x3fff);
0138 return 2;
0139 #endif
0140
0141 case HOST1X_OPCODE_EXTEND:
0142 subop = val >> 24 & 0xf;
0143 if (subop == HOST1X_OPCODE_EXTEND_ACQUIRE_MLOCK)
0144 host1x_debug_cont(o, "ACQUIRE_MLOCK(index=%d)\n",
0145 val & 0xff);
0146 else if (subop == HOST1X_OPCODE_EXTEND_RELEASE_MLOCK)
0147 host1x_debug_cont(o, "RELEASE_MLOCK(index=%d)\n",
0148 val & 0xff);
0149 else
0150 host1x_debug_cont(o, "EXTEND_UNKNOWN(%08x)\n", val);
0151 return 0;
0152
0153 default:
0154 host1x_debug_cont(o, "UNKNOWN\n");
0155 return 0;
0156 }
0157 }
0158
0159 static void show_gather(struct output *o, dma_addr_t phys_addr,
0160 unsigned int words, struct host1x_cdma *cdma,
0161 dma_addr_t pin_addr, u32 *map_addr)
0162 {
0163
0164 u32 offset = phys_addr - pin_addr;
0165 unsigned int data_count = 0, i;
0166 u32 payload = INVALID_PAYLOAD;
0167
0168
0169
0170
0171
0172
0173 if (offset > HOST1X_DEBUG_MAX_PAGE_OFFSET) {
0174 host1x_debug_output(o, "[address mismatch]\n");
0175 return;
0176 }
0177
0178 for (i = 0; i < words; i++) {
0179 dma_addr_t addr = phys_addr + i * 4;
0180 u32 val = *(map_addr + offset / 4 + i);
0181
0182 if (!data_count) {
0183 host1x_debug_output(o, " %pad: %08x: ", &addr, val);
0184 data_count = show_channel_command(o, val, &payload);
0185 } else {
0186 host1x_debug_cont(o, "%08x%s", val,
0187 data_count > 1 ? ", " : "])\n");
0188 data_count--;
0189 }
0190 }
0191 }
0192
0193 static void show_channel_gathers(struct output *o, struct host1x_cdma *cdma)
0194 {
0195 struct push_buffer *pb = &cdma->push_buffer;
0196 struct host1x_job *job;
0197
0198 list_for_each_entry(job, &cdma->sync_queue, list) {
0199 unsigned int i;
0200
0201 host1x_debug_output(o, "JOB, syncpt %u: %u timeout: %u num_slots: %u num_handles: %u\n",
0202 job->syncpt->id, job->syncpt_end, job->timeout,
0203 job->num_slots, job->num_unpins);
0204
0205 show_gather(o, pb->dma + job->first_get, job->num_slots * 2, cdma,
0206 pb->dma + job->first_get, pb->mapped + job->first_get);
0207
0208 for (i = 0; i < job->num_cmds; i++) {
0209 struct host1x_job_gather *g;
0210 u32 *mapped;
0211
0212 if (job->cmds[i].is_wait)
0213 continue;
0214
0215 g = &job->cmds[i].gather;
0216
0217 if (job->gather_copy_mapped)
0218 mapped = (u32 *)job->gather_copy_mapped;
0219 else
0220 mapped = host1x_bo_mmap(g->bo);
0221
0222 if (!mapped) {
0223 host1x_debug_output(o, "[could not mmap]\n");
0224 continue;
0225 }
0226
0227 host1x_debug_output(o, " GATHER at %pad+%#x, %d words\n",
0228 &g->base, g->offset, g->words);
0229
0230 show_gather(o, g->base + g->offset, g->words, cdma,
0231 g->base, mapped);
0232
0233 if (!job->gather_copy_mapped)
0234 host1x_bo_munmap(g->bo, mapped);
0235 }
0236 }
0237 }
0238
0239 #if HOST1X_HW >= 6
0240 #include "debug_hw_1x06.c"
0241 #else
0242 #include "debug_hw_1x01.c"
0243 #endif
0244
0245 static const struct host1x_debug_ops host1x_debug_ops = {
0246 .show_channel_cdma = host1x_debug_show_channel_cdma,
0247 .show_channel_fifo = host1x_debug_show_channel_fifo,
0248 .show_mlocks = host1x_debug_show_mlocks,
0249 };