drivers/gpu/drm/nouveau/nvkm/engine/gr/gv100.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/nouveau/nvkm/engine/gr/gv100.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/nvkm/engine/gr/gv100.c
Extension
.c
Size
10330 bytes
Lines
343
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if ((gpc == disable_gpc) && num_tpc_mask & BIT(disable_tpc)) {
			/* Safety check if a TPC is removed twice */
			if (WARN_ON(tpc_removed_gpc))
				goto done;

			/* Remove logical TPC from set */
			num_tpc_mask &= ~BIT(disable_tpc);
			tpc_removed_gpc = true;
		}

		/* track balancing of tpcs across gpcs */
		num_tpc_gpc[gpc] = hweight32(num_tpc_mask);
		average_tpcs += num_tpc_gpc[gpc];

		/* save the maximum numer of gpcs */
		max_tpc_gpc = num_tpc_gpc[gpc] > max_tpc_gpc ? num_tpc_gpc[gpc] : max_tpc_gpc;

		/*
		 * Calculate ratio between TPC count and post-FS and post-SCG
		 *
		 * ratio represents relative throughput of the GPC
		 */
		scg_gpc_pix_perf = scale_factor * num_tpc_gpc[gpc] / gr->tpc_nr[gpc];
		if (min_scg_gpc_pix_perf > scg_gpc_pix_perf)
			min_scg_gpc_pix_perf = scg_gpc_pix_perf;

		/* Calculate # of surviving PES */
		for (pes = 0; pes < gr->ppc_nr[gpc]; pes++) {
			/* Count the number of TPC on the set */
			num_tpc_mask = gr->ppc_tpc_mask[gpc][pes] & gpc_tpc_mask[gpc];

			if ((gpc == disable_gpc) && (num_tpc_mask & BIT(disable_tpc))) {
				if (WARN_ON(tpc_removed_pes))
					goto done;

				num_tpc_mask &= ~BIT(disable_tpc);
				tpc_removed_pes = true;
			}

			if (hweight32(num_tpc_mask))
				scg_num_pes++;
		}
	}

	if (WARN_ON(!tpc_removed_gpc || !tpc_removed_pes))
		goto done;

	if (max_tpc_gpc == 0) {
		*perf = 0;
		goto done_ok;
	}

	/* Now calculate perf */
	scg_world_perf = (scale_factor * scg_num_pes) / gr->ppc_total;
	deviation = 0;
	average_tpcs = scale_factor * average_tpcs / gr->gpc_nr;
	for (gpc = 0; gpc < gr->gpc_nr; gpc++) {
		diff = average_tpcs - scale_factor * num_tpc_gpc[gpc];
		if (diff < 0)
			diff = -diff;

		deviation += diff;
	}

	deviation /= gr->gpc_nr;

	norm_tpc_deviation = deviation / max_tpc_gpc;

	tpc_balance = scale_factor - norm_tpc_deviation;

	if ((tpc_balance > scale_factor)          ||
	    (scg_world_perf > scale_factor)       ||
	    (min_scg_gpc_pix_perf > scale_factor) ||
	    (norm_tpc_deviation > scale_factor)) {
		WARN_ON(1);
		goto done;
	}

	*perf = (pix_scale * min_scg_gpc_pix_perf) +
		(world_scale * scg_world_perf) +
		(tpc_scale * tpc_balance);
done_ok:
	ret = 0;
done:
	kfree(num_tpc_gpc);
	return ret;
}

int
gv100_gr_oneinit_sm_id(struct gf100_gr *gr)

Annotation

Implementation Notes