1 /* 2 * Copyright 2013 Red Hat Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: Ben Skeggs <bskeggs@redhat.com> 23 */ 24 #include "ctxgf100.h" 25 26 #include <subdev/fb.h> 27 #include <subdev/mc.h> 28 29 /******************************************************************************* 30 * PGRAPH context register lists 31 ******************************************************************************/ 32 33 static const struct gf100_gr_init 34 gf117_grctx_init_ds_0[] = { 35 { 0x405800, 1, 0x04, 0x0f8000bf }, 36 { 0x405830, 1, 0x04, 0x02180324 }, 37 { 0x405834, 1, 0x04, 0x08000000 }, 38 { 0x405838, 1, 0x04, 0x00000000 }, 39 { 0x405854, 1, 0x04, 0x00000000 }, 40 { 0x405870, 4, 0x04, 0x00000001 }, 41 { 0x405a00, 2, 0x04, 0x00000000 }, 42 { 0x405a18, 1, 0x04, 0x00000000 }, 43 {} 44 }; 45 46 static const struct gf100_gr_init 47 gf117_grctx_init_pd_0[] = { 48 { 0x406020, 1, 0x04, 0x000103c1 }, 49 { 0x406028, 4, 0x04, 0x00000001 }, 50 { 0x4064a8, 1, 0x04, 0x00000000 }, 51 { 0x4064ac, 1, 0x04, 0x00003fff }, 52 { 0x4064b4, 3, 0x04, 0x00000000 }, 53 { 0x4064c0, 1, 0x04, 0x801a0078 }, 54 { 0x4064c4, 1, 0x04, 0x00c9ffff }, 55 { 0x4064d0, 8, 0x04, 0x00000000 }, 56 {} 57 }; 58 59 static const struct gf100_gr_pack 60 gf117_grctx_pack_hub[] = { 61 { gf100_grctx_init_main_0 }, 62 { gf119_grctx_init_fe_0 }, 63 { gf100_grctx_init_pri_0 }, 64 { gf100_grctx_init_memfmt_0 }, 65 { gf117_grctx_init_ds_0 }, 66 { gf117_grctx_init_pd_0 }, 67 { gf100_grctx_init_rstr2d_0 }, 68 { gf100_grctx_init_scc_0 }, 69 { gf119_grctx_init_be_0 }, 70 {} 71 }; 72 73 static const struct gf100_gr_init 74 gf117_grctx_init_setup_0[] = { 75 { 0x418800, 1, 0x04, 0x7006860a }, 76 { 0x418808, 3, 0x04, 0x00000000 }, 77 { 0x418828, 1, 0x04, 0x00008442 }, 78 { 0x418830, 1, 0x04, 0x10000001 }, 79 { 0x4188d8, 1, 0x04, 0x00000008 }, 80 { 0x4188e0, 1, 0x04, 0x01000000 }, 81 { 0x4188e8, 5, 0x04, 0x00000000 }, 82 { 0x4188fc, 1, 0x04, 0x20100018 }, 83 {} 84 }; 85 86 static const struct gf100_gr_pack 87 gf117_grctx_pack_gpc_0[] = { 88 { gf100_grctx_init_gpc_unk_0 }, 89 { gf119_grctx_init_prop_0 }, 90 { gf119_grctx_init_gpc_unk_1 }, 91 { gf117_grctx_init_setup_0 }, 92 { gf100_grctx_init_zcull_0 }, 93 {} 94 }; 95 96 const struct gf100_gr_pack 97 gf117_grctx_pack_gpc_1[] = { 98 { gf119_grctx_init_crstr_0 }, 99 { gf108_grctx_init_gpm_0 }, 100 { gf100_grctx_init_gcc_0 }, 101 {} 102 }; 103 104 const struct gf100_gr_init 105 gf117_grctx_init_pe_0[] = { 106 { 0x419848, 1, 0x04, 0x00000000 }, 107 { 0x419864, 1, 0x04, 0x00000129 }, 108 { 0x419888, 1, 0x04, 0x00000000 }, 109 {} 110 }; 111 112 static const struct gf100_gr_init 113 gf117_grctx_init_tex_0[] = { 114 { 0x419a00, 1, 0x04, 0x000001f0 }, 115 { 0x419a04, 1, 0x04, 0x00000001 }, 116 { 0x419a08, 1, 0x04, 0x00000023 }, 117 { 0x419a0c, 1, 0x04, 0x00020000 }, 118 { 0x419a10, 1, 0x04, 0x00000000 }, 119 { 0x419a14, 1, 0x04, 0x00000200 }, 120 { 0x419a1c, 1, 0x04, 0x00008000 }, 121 { 0x419a20, 1, 0x04, 0x00000800 }, 122 { 0x419ac4, 1, 0x04, 0x0017f440 }, 123 {} 124 }; 125 126 static const struct gf100_gr_init 127 gf117_grctx_init_mpc_0[] = { 128 { 0x419c00, 1, 0x04, 0x0000000a }, 129 { 0x419c04, 1, 0x04, 0x00000006 }, 130 { 0x419c08, 1, 0x04, 0x00000002 }, 131 { 0x419c20, 1, 0x04, 0x00000000 }, 132 { 0x419c24, 1, 0x04, 0x00084210 }, 133 { 0x419c28, 1, 0x04, 0x3efbefbe }, 134 {} 135 }; 136 137 static const struct gf100_gr_pack 138 gf117_grctx_pack_tpc[] = { 139 { gf117_grctx_init_pe_0 }, 140 { gf117_grctx_init_tex_0 }, 141 { gf117_grctx_init_mpc_0 }, 142 { gf104_grctx_init_l1c_0 }, 143 { gf119_grctx_init_sm_0 }, 144 {} 145 }; 146 147 static const struct gf100_gr_init 148 gf117_grctx_init_pes_0[] = { 149 { 0x41be24, 1, 0x04, 0x00000002 }, 150 {} 151 }; 152 153 static const struct gf100_gr_init 154 gf117_grctx_init_cbm_0[] = { 155 { 0x41bec0, 1, 0x04, 0x12180000 }, 156 { 0x41bec4, 1, 0x04, 0x00003fff }, 157 { 0x41bee4, 1, 0x04, 0x03240218 }, 158 {} 159 }; 160 161 const struct gf100_gr_init 162 gf117_grctx_init_wwdx_0[] = { 163 { 0x41bf00, 1, 0x04, 0x0a418820 }, 164 { 0x41bf04, 1, 0x04, 0x062080e6 }, 165 { 0x41bf08, 1, 0x04, 0x020398a4 }, 166 { 0x41bf0c, 1, 0x04, 0x0e629062 }, 167 { 0x41bf10, 1, 0x04, 0x0a418820 }, 168 { 0x41bf14, 1, 0x04, 0x000000e6 }, 169 { 0x41bfd0, 1, 0x04, 0x00900103 }, 170 { 0x41bfe0, 1, 0x04, 0x00400001 }, 171 { 0x41bfe4, 1, 0x04, 0x00000000 }, 172 {} 173 }; 174 175 static const struct gf100_gr_pack 176 gf117_grctx_pack_ppc[] = { 177 { gf117_grctx_init_pes_0 }, 178 { gf117_grctx_init_cbm_0 }, 179 { gf117_grctx_init_wwdx_0 }, 180 {} 181 }; 182 183 /******************************************************************************* 184 * PGRAPH context implementation 185 ******************************************************************************/ 186 187 void 188 gf117_grctx_generate_dist_skip_table(struct gf100_gr *gr) 189 { 190 struct nvkm_device *device = gr->base.engine.subdev.device; 191 int i; 192 193 for (i = 0; i < 8; i++) 194 nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000); 195 } 196 197 void 198 gf117_grctx_generate_rop_mapping(struct gf100_gr *gr) 199 { 200 struct nvkm_device *device = gr->base.engine.subdev.device; 201 u32 data[6] = {}, data2[2] = {}; 202 u8 shift, ntpcv; 203 int i; 204 205 /* Pack tile map into register format. */ 206 for (i = 0; i < 32; i++) 207 data[i / 6] |= (gr->tile[i] & 0x07) << ((i % 6) * 5); 208 209 /* Magic. */ 210 shift = 0; 211 ntpcv = gr->tpc_total; 212 while (!(ntpcv & (1 << 4))) { 213 ntpcv <<= 1; 214 shift++; 215 } 216 217 data2[0] = (ntpcv << 16); 218 data2[0] |= (shift << 21); 219 data2[0] |= (((1 << (0 + 5)) % ntpcv) << 24); 220 for (i = 1; i < 7; i++) 221 data2[1] |= ((1 << (i + 5)) % ntpcv) << ((i - 1) * 5); 222 223 /* GPC_BROADCAST */ 224 nvkm_wr32(device, 0x418bb8, (gr->tpc_total << 8) | 225 gr->screen_tile_row_offset); 226 for (i = 0; i < 6; i++) 227 nvkm_wr32(device, 0x418b08 + (i * 4), data[i]); 228 229 /* GPC_BROADCAST.TP_BROADCAST */ 230 nvkm_wr32(device, 0x41bfd0, (gr->tpc_total << 8) | 231 gr->screen_tile_row_offset | data2[0]); 232 nvkm_wr32(device, 0x41bfe4, data2[1]); 233 for (i = 0; i < 6; i++) 234 nvkm_wr32(device, 0x41bf00 + (i * 4), data[i]); 235 236 /* UNK78xx */ 237 nvkm_wr32(device, 0x4078bc, (gr->tpc_total << 8) | 238 gr->screen_tile_row_offset); 239 for (i = 0; i < 6; i++) 240 nvkm_wr32(device, 0x40780c + (i * 4), data[i]); 241 } 242 243 void 244 gf117_grctx_generate_attrib(struct gf100_grctx *info) 245 { 246 struct gf100_gr *gr = info->gr; 247 const struct gf100_grctx_func *grctx = gr->func->grctx; 248 const u32 alpha = grctx->alpha_nr; 249 const u32 beta = grctx->attrib_nr; 250 const u32 size = 0x20 * (grctx->attrib_nr_max + grctx->alpha_nr_max); 251 const int s = 12; 252 const int b = mmio_vram(info, size * gr->tpc_total, (1 << s), false); 253 const int timeslice_mode = 1; 254 const int max_batches = 0xffff; 255 u32 bo = 0; 256 u32 ao = bo + grctx->attrib_nr_max * gr->tpc_total; 257 int gpc, ppc; 258 259 mmio_refn(info, 0x418810, 0x80000000, s, b); 260 mmio_refn(info, 0x419848, 0x10000000, s, b); 261 mmio_wr32(info, 0x405830, (beta << 16) | alpha); 262 mmio_wr32(info, 0x4064c4, ((alpha / 4) << 16) | max_batches); 263 264 for (gpc = 0; gpc < gr->gpc_nr; gpc++) { 265 for (ppc = 0; ppc < gr->ppc_nr[gpc]; ppc++) { 266 const u32 a = alpha * gr->ppc_tpc_nr[gpc][ppc]; 267 const u32 b = beta * gr->ppc_tpc_nr[gpc][ppc]; 268 const u32 t = timeslice_mode; 269 const u32 o = PPC_UNIT(gpc, ppc, 0); 270 if (!(gr->ppc_mask[gpc] & (1 << ppc))) 271 continue; 272 mmio_skip(info, o + 0xc0, (t << 28) | (b << 16) | ++bo); 273 mmio_wr32(info, o + 0xc0, (t << 28) | (b << 16) | --bo); 274 bo += grctx->attrib_nr_max * gr->ppc_tpc_nr[gpc][ppc]; 275 mmio_wr32(info, o + 0xe4, (a << 16) | ao); 276 ao += grctx->alpha_nr_max * gr->ppc_tpc_nr[gpc][ppc]; 277 } 278 } 279 } 280 281 const struct gf100_grctx_func 282 gf117_grctx = { 283 .main = gf100_grctx_generate_main, 284 .unkn = gk104_grctx_generate_unkn, 285 .hub = gf117_grctx_pack_hub, 286 .gpc_0 = gf117_grctx_pack_gpc_0, 287 .gpc_1 = gf117_grctx_pack_gpc_1, 288 .zcull = gf100_grctx_pack_zcull, 289 .tpc = gf117_grctx_pack_tpc, 290 .ppc = gf117_grctx_pack_ppc, 291 .icmd = gf119_grctx_pack_icmd, 292 .mthd = gf119_grctx_pack_mthd, 293 .bundle = gf100_grctx_generate_bundle, 294 .bundle_size = 0x1800, 295 .pagepool = gf100_grctx_generate_pagepool, 296 .pagepool_size = 0x8000, 297 .attrib = gf117_grctx_generate_attrib, 298 .attrib_nr_max = 0x324, 299 .attrib_nr = 0x218, 300 .alpha_nr_max = 0x7ff, 301 .alpha_nr = 0x324, 302 .sm_id = gf100_grctx_generate_sm_id, 303 .tpc_nr = gf100_grctx_generate_tpc_nr, 304 .r4060a8 = gf100_grctx_generate_r4060a8, 305 .rop_mapping = gf117_grctx_generate_rop_mapping, 306 .alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables, 307 .max_ways_evict = gf100_grctx_generate_max_ways_evict, 308 .dist_skip_table = gf117_grctx_generate_dist_skip_table, 309 .r419cb8 = gf100_grctx_generate_r419cb8, 310 }; 311