1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2010 Google, Inc. 4 * Author: Erik Gilling <konkers@android.com> 5 * 6 * Copyright (C) 2011-2013 NVIDIA Corporation 7 */ 8 9 #include "../dev.h" 10 #include "../debug.h" 11 #include "../cdma.h" 12 #include "../channel.h" 13 14 static void host1x_debug_show_channel_cdma(struct host1x *host, 15 struct host1x_channel *ch, 16 struct output *o) 17 { 18 struct host1x_cdma *cdma = &ch->cdma; 19 u32 dmaput, dmaget, dmactrl; 20 u32 cbstat, cbread; 21 u32 val, base, baseval; 22 23 dmaput = host1x_ch_readl(ch, HOST1X_CHANNEL_DMAPUT); 24 dmaget = host1x_ch_readl(ch, HOST1X_CHANNEL_DMAGET); 25 dmactrl = host1x_ch_readl(ch, HOST1X_CHANNEL_DMACTRL); 26 cbread = host1x_sync_readl(host, HOST1X_SYNC_CBREAD(ch->id)); 27 cbstat = host1x_sync_readl(host, HOST1X_SYNC_CBSTAT(ch->id)); 28 29 host1x_debug_output(o, "%u-%s: ", ch->id, dev_name(ch->dev)); 30 31 if (HOST1X_CHANNEL_DMACTRL_DMASTOP_V(dmactrl) || 32 !ch->cdma.push_buffer.mapped) { 33 host1x_debug_output(o, "inactive\n\n"); 34 return; 35 } 36 37 if (HOST1X_SYNC_CBSTAT_CBCLASS_V(cbstat) == HOST1X_CLASS_HOST1X && 38 HOST1X_SYNC_CBSTAT_CBOFFSET_V(cbstat) == 39 HOST1X_UCLASS_WAIT_SYNCPT) 40 host1x_debug_output(o, "waiting on syncpt %d val %d\n", 41 cbread >> 24, cbread & 0xffffff); 42 else if (HOST1X_SYNC_CBSTAT_CBCLASS_V(cbstat) == 43 HOST1X_CLASS_HOST1X && 44 HOST1X_SYNC_CBSTAT_CBOFFSET_V(cbstat) == 45 HOST1X_UCLASS_WAIT_SYNCPT_BASE) { 46 base = (cbread >> 16) & 0xff; 47 baseval = 48 host1x_sync_readl(host, HOST1X_SYNC_SYNCPT_BASE(base)); 49 val = cbread & 0xffff; 50 host1x_debug_output(o, "waiting on syncpt %d val %d (base %d = %d; offset = %d)\n", 51 cbread >> 24, baseval + val, base, 52 baseval, val); 53 } else 54 host1x_debug_output(o, "active class %02x, offset %04x, val %08x\n", 55 HOST1X_SYNC_CBSTAT_CBCLASS_V(cbstat), 56 HOST1X_SYNC_CBSTAT_CBOFFSET_V(cbstat), 57 cbread); 58 59 host1x_debug_output(o, "DMAPUT %08x, DMAGET %08x, DMACTL %08x\n", 60 dmaput, dmaget, dmactrl); 61 host1x_debug_output(o, "CBREAD %08x, CBSTAT %08x\n", cbread, cbstat); 62 63 show_channel_gathers(o, cdma); 64 host1x_debug_output(o, "\n"); 65 } 66 67 static void host1x_debug_show_channel_fifo(struct host1x *host, 68 struct host1x_channel *ch, 69 struct output *o) 70 { 71 u32 val, rd_ptr, wr_ptr, start, end; 72 unsigned int data_count = 0; 73 74 host1x_debug_output(o, "%u: fifo:\n", ch->id); 75 76 val = host1x_ch_readl(ch, HOST1X_CHANNEL_FIFOSTAT); 77 host1x_debug_output(o, "FIFOSTAT %08x\n", val); 78 if (HOST1X_CHANNEL_FIFOSTAT_CFEMPTY_V(val)) { 79 host1x_debug_output(o, "[empty]\n"); 80 return; 81 } 82 83 host1x_sync_writel(host, 0x0, HOST1X_SYNC_CFPEEK_CTRL); 84 host1x_sync_writel(host, HOST1X_SYNC_CFPEEK_CTRL_ENA_F(1) | 85 HOST1X_SYNC_CFPEEK_CTRL_CHANNR_F(ch->id), 86 HOST1X_SYNC_CFPEEK_CTRL); 87 88 val = host1x_sync_readl(host, HOST1X_SYNC_CFPEEK_PTRS); 89 rd_ptr = HOST1X_SYNC_CFPEEK_PTRS_CF_RD_PTR_V(val); 90 wr_ptr = HOST1X_SYNC_CFPEEK_PTRS_CF_WR_PTR_V(val); 91 92 val = host1x_sync_readl(host, HOST1X_SYNC_CF_SETUP(ch->id)); 93 start = HOST1X_SYNC_CF_SETUP_BASE_V(val); 94 end = HOST1X_SYNC_CF_SETUP_LIMIT_V(val); 95 96 do { 97 host1x_sync_writel(host, 0x0, HOST1X_SYNC_CFPEEK_CTRL); 98 host1x_sync_writel(host, HOST1X_SYNC_CFPEEK_CTRL_ENA_F(1) | 99 HOST1X_SYNC_CFPEEK_CTRL_CHANNR_F(ch->id) | 100 HOST1X_SYNC_CFPEEK_CTRL_ADDR_F(rd_ptr), 101 HOST1X_SYNC_CFPEEK_CTRL); 102 val = host1x_sync_readl(host, HOST1X_SYNC_CFPEEK_READ); 103 104 if (!data_count) { 105 host1x_debug_output(o, "%08x: ", val); 106 data_count = show_channel_command(o, val, NULL); 107 } else { 108 host1x_debug_cont(o, "%08x%s", val, 109 data_count > 1 ? ", " : "])\n"); 110 data_count--; 111 } 112 113 if (rd_ptr == end) 114 rd_ptr = start; 115 else 116 rd_ptr++; 117 } while (rd_ptr != wr_ptr); 118 119 if (data_count) 120 host1x_debug_cont(o, ", ...])\n"); 121 host1x_debug_output(o, "\n"); 122 123 host1x_sync_writel(host, 0x0, HOST1X_SYNC_CFPEEK_CTRL); 124 } 125 126 static void host1x_debug_show_mlocks(struct host1x *host, struct output *o) 127 { 128 unsigned int i; 129 130 host1x_debug_output(o, "---- mlocks ----\n"); 131 132 for (i = 0; i < host1x_syncpt_nb_mlocks(host); i++) { 133 u32 owner = 134 host1x_sync_readl(host, HOST1X_SYNC_MLOCK_OWNER(i)); 135 if (HOST1X_SYNC_MLOCK_OWNER_CH_OWNS_V(owner)) 136 host1x_debug_output(o, "%u: locked by channel %u\n", 137 i, HOST1X_SYNC_MLOCK_OWNER_CHID_V(owner)); 138 else if (HOST1X_SYNC_MLOCK_OWNER_CPU_OWNS_V(owner)) 139 host1x_debug_output(o, "%u: locked by cpu\n", i); 140 else 141 host1x_debug_output(o, "%u: unlocked\n", i); 142 } 143 144 host1x_debug_output(o, "\n"); 145 } 146