162306a36Sopenharmony_ci// SPDX-License-Identifier: MIT
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci#include "crc.h"
462306a36Sopenharmony_ci#include "crcc37d.h"
562306a36Sopenharmony_ci#include "core.h"
662306a36Sopenharmony_ci#include "disp.h"
762306a36Sopenharmony_ci#include "head.h"
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <nvif/pushc37b.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <nvhw/class/clc57d.h>
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_cistatic int crcc57d_set_src(struct nv50_head *head, int or, enum nv50_crc_source_type source,
1462306a36Sopenharmony_ci			   struct nv50_crc_notifier_ctx *ctx)
1562306a36Sopenharmony_ci{
1662306a36Sopenharmony_ci	struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
1762306a36Sopenharmony_ci	const int i = head->base.index;
1862306a36Sopenharmony_ci	u32 crc_args = NVDEF(NVC57D, HEAD_SET_CRC_CONTROL, CONTROLLING_CHANNEL, CORE) |
1962306a36Sopenharmony_ci		       NVDEF(NVC57D, HEAD_SET_CRC_CONTROL, EXPECT_BUFFER_COLLAPSE, FALSE) |
2062306a36Sopenharmony_ci		       NVDEF(NVC57D, HEAD_SET_CRC_CONTROL, SECONDARY_CRC, NONE) |
2162306a36Sopenharmony_ci		       NVDEF(NVC57D, HEAD_SET_CRC_CONTROL, CRC_DURING_SNOOZE, DISABLE);
2262306a36Sopenharmony_ci	int ret;
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci	switch (source) {
2562306a36Sopenharmony_ci	case NV50_CRC_SOURCE_TYPE_SOR:
2662306a36Sopenharmony_ci		crc_args |= NVDEF(NVC57D, HEAD_SET_CRC_CONTROL, PRIMARY_CRC, SOR(or));
2762306a36Sopenharmony_ci		break;
2862306a36Sopenharmony_ci	case NV50_CRC_SOURCE_TYPE_SF:
2962306a36Sopenharmony_ci		crc_args |= NVDEF(NVC57D, HEAD_SET_CRC_CONTROL, PRIMARY_CRC, SF);
3062306a36Sopenharmony_ci		break;
3162306a36Sopenharmony_ci	default:
3262306a36Sopenharmony_ci		break;
3362306a36Sopenharmony_ci	}
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci	ret = PUSH_WAIT(push, 4);
3662306a36Sopenharmony_ci	if (ret)
3762306a36Sopenharmony_ci		return ret;
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci	if (source) {
4062306a36Sopenharmony_ci		PUSH_MTHD(push, NVC57D, HEAD_SET_CONTEXT_DMA_CRC(i), ctx->ntfy.handle);
4162306a36Sopenharmony_ci		PUSH_MTHD(push, NVC57D, HEAD_SET_CRC_CONTROL(i), crc_args);
4262306a36Sopenharmony_ci	} else {
4362306a36Sopenharmony_ci		PUSH_MTHD(push, NVC57D, HEAD_SET_CRC_CONTROL(i), 0);
4462306a36Sopenharmony_ci		PUSH_MTHD(push, NVC57D, HEAD_SET_CONTEXT_DMA_CRC(i), 0);
4562306a36Sopenharmony_ci	}
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci	return 0;
4862306a36Sopenharmony_ci}
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ciconst struct nv50_crc_func crcc57d = {
5162306a36Sopenharmony_ci	.set_src = crcc57d_set_src,
5262306a36Sopenharmony_ci	.set_ctx = crcc37d_set_ctx,
5362306a36Sopenharmony_ci	.get_entry = crcc37d_get_entry,
5462306a36Sopenharmony_ci	.ctx_finished = crcc37d_ctx_finished,
5562306a36Sopenharmony_ci	.flip_threshold = CRCC37D_FLIP_THRESHOLD,
5662306a36Sopenharmony_ci	.num_entries = CRCC37D_MAX_ENTRIES,
5762306a36Sopenharmony_ci	.notifier_len = sizeof(struct crcc37d_notifier),
5862306a36Sopenharmony_ci};
59