309 lines · c
1/*2 * Copyright 2013 Red Hat Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * 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 OR20 * 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 lists31 ******************************************************************************/32 33static const struct gf100_gr_init34gf117_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 46static const struct gf100_gr_init47gf117_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 59static const struct gf100_gr_pack60gf117_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 73static const struct gf100_gr_init74gf117_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 86static const struct gf100_gr_pack87gf117_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 96const struct gf100_gr_pack97gf117_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 104const struct gf100_gr_init105gf117_grctx_init_pe_0[] = {106 { 0x419848, 1, 0x04, 0x00000000 },107 { 0x419864, 1, 0x04, 0x00000129 },108 { 0x419888, 1, 0x04, 0x00000000 },109 {}110};111 112static const struct gf100_gr_init113gf117_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 126static const struct gf100_gr_init127gf117_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 137static const struct gf100_gr_pack138gf117_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 147static const struct gf100_gr_init148gf117_grctx_init_pes_0[] = {149 { 0x41be24, 1, 0x04, 0x00000002 },150 {}151};152 153static const struct gf100_gr_init154gf117_grctx_init_cbm_0[] = {155 { 0x41bec0, 1, 0x04, 0x12180000 },156 { 0x41bec4, 1, 0x04, 0x00003fff },157 { 0x41bee4, 1, 0x04, 0x03240218 },158 {}159};160 161const struct gf100_gr_init162gf117_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 175static const struct gf100_gr_pack176gf117_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 implementation185 ******************************************************************************/186 187void188gf117_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 197void198gf117_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 243void244gf117_grctx_generate_attrib(struct gf100_gr_chan *chan)245{246 struct gf100_gr *gr = chan->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 int timeslice_mode = 1;251 const int max_batches = 0xffff;252 u32 bo = 0;253 u32 ao = bo + grctx->attrib_nr_max * gr->tpc_total;254 int gpc, ppc;255 256 gf100_grctx_patch_wr32(chan, 0x405830, (beta << 16) | alpha);257 gf100_grctx_patch_wr32(chan, 0x4064c4, ((alpha / 4) << 16) | max_batches);258 259 for (gpc = 0; gpc < gr->gpc_nr; gpc++) {260 for (ppc = 0; ppc < gr->func->ppc_nr; ppc++) {261 const u32 a = alpha * gr->ppc_tpc_nr[gpc][ppc];262 const u32 b = beta * gr->ppc_tpc_nr[gpc][ppc];263 const u32 t = timeslice_mode;264 const u32 o = PPC_UNIT(gpc, ppc, 0);265 266 if (!(gr->ppc_mask[gpc] & (1 << ppc)))267 continue;268 269 gf100_grctx_patch_wr32(chan, o + 0xc0, (t << 28) | (b << 16) | bo);270 bo += grctx->attrib_nr_max * gr->ppc_tpc_nr[gpc][ppc];271 gf100_grctx_patch_wr32(chan, o + 0xe4, (a << 16) | ao);272 ao += grctx->alpha_nr_max * gr->ppc_tpc_nr[gpc][ppc];273 }274 }275}276 277const struct gf100_grctx_func278gf117_grctx = {279 .main = gf100_grctx_generate_main,280 .unkn = gk104_grctx_generate_unkn,281 .hub = gf117_grctx_pack_hub,282 .gpc_0 = gf117_grctx_pack_gpc_0,283 .gpc_1 = gf117_grctx_pack_gpc_1,284 .zcull = gf100_grctx_pack_zcull,285 .tpc = gf117_grctx_pack_tpc,286 .ppc = gf117_grctx_pack_ppc,287 .icmd = gf119_grctx_pack_icmd,288 .mthd = gf119_grctx_pack_mthd,289 .bundle = gf100_grctx_generate_bundle,290 .bundle_size = 0x1800,291 .pagepool = gf100_grctx_generate_pagepool,292 .pagepool_size = 0x8000,293 .attrib_cb_size = gf100_grctx_generate_attrib_cb_size,294 .attrib_cb = gf100_grctx_generate_attrib_cb,295 .attrib = gf117_grctx_generate_attrib,296 .attrib_nr_max = 0x324,297 .attrib_nr = 0x218,298 .alpha_nr_max = 0x7ff,299 .alpha_nr = 0x324,300 .sm_id = gf100_grctx_generate_sm_id,301 .tpc_nr = gf100_grctx_generate_tpc_nr,302 .r4060a8 = gf100_grctx_generate_r4060a8,303 .rop_mapping = gf117_grctx_generate_rop_mapping,304 .alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables,305 .max_ways_evict = gf100_grctx_generate_max_ways_evict,306 .dist_skip_table = gf117_grctx_generate_dist_skip_table,307 .r419cb8 = gf100_grctx_generate_r419cb8,308};309