// SPDX-License-Identifier: MIT
/*
 * Copyright © 2026 Intel Corporation
 */

#include "xe_device.h"
#include "xe_irq.h"
#include "xe_printk.h"
#include "xe_ras.h"
#include "xe_sysctrl.h"
#include "xe_sysctrl_event_types.h"
#include "xe_sysctrl_mailbox.h"
#include "xe_sysctrl_mailbox_types.h"

static void get_pending_event(struct xe_sysctrl *sc, struct xe_sysctrl_mailbox_command *command)
{
	struct xe_sysctrl_event_response *response = command->data_out;
	struct xe_device *xe = sc_to_xe(sc);
	u32 count = XE_SYSCTRL_FLOOD_LIMIT;
	size_t len;
	int ret;

	do {
		memset(response, 0, sizeof(*response));

		ret = xe_sysctrl_send_command(sc, command, &len);
		if (ret) {
			xe_err(xe, "sysctrl: failed to get pending event %d\n", ret);
			return;
		}

		if (len != sizeof(*response)) {
			xe_err(xe, "sysctrl: unexpected event response length %zu (expected %zu)\n",
			       len, sizeof(*response));
			return;
		}

		if (response->event == XE_SYSCTRL_EVENT_THRESHOLD_CROSSED)
			xe_ras_counter_threshold_crossed(xe, response);
		else
			xe_warn(xe, "sysctrl: unexpected event %#x\n", response->event);

		if (!--count) {
			xe_err(xe, "sysctrl: event flooding\n");
			return;
		}

		xe_dbg(xe, "sysctrl: %u events pending\n", response->count);
	} while (response->count);
}

static void event_request_prepare(struct xe_device *xe, struct xe_sysctrl_app_msg_hdr *header,
				  struct xe_sysctrl_event_request *request)
{
	struct pci_dev *pdev = to_pci_dev(xe->drm.dev);

	header->data = REG_FIELD_PREP(APP_HDR_GROUP_ID_MASK, XE_SYSCTRL_GROUP_GFSP) |
		       REG_FIELD_PREP(APP_HDR_COMMAND_MASK, XE_SYSCTRL_CMD_GET_PENDING_EVENT);

	request->vector = xe_device_has_msix(xe) ? XE_IRQ_DEFAULT_MSIX : 0;
	request->fn = PCI_FUNC(pdev->devfn);
}

/**
 * xe_sysctrl_event() - Handler for System Controller events
 * @sc: System Controller instance
 *
 * Handle events generated by System Controller.
 */
void xe_sysctrl_event(struct xe_sysctrl *sc)
{
	struct xe_sysctrl_mailbox_command command = {};
	struct xe_sysctrl_event_response response = {};
	struct xe_sysctrl_event_request request = {};
	struct xe_sysctrl_app_msg_hdr header = {};

	xe_device_assert_mem_access(sc_to_xe(sc));
	event_request_prepare(sc_to_xe(sc), &header, &request);

	command.header = header;
	command.data_in = &request;
	command.data_in_len = sizeof(request);
	command.data_out = &response;
	command.data_out_len = sizeof(response);

	guard(mutex)(&sc->event_lock);
	get_pending_event(sc, &command);
}
