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

#include <drm/drm_managed.h>

#include "xe_device.h"
#include "xe_gt.h"
#include "xe_gt_idle.h"
#include "xe_gt_sysfs.h"
#include "xe_guc_pc.h"
#include "regs/xe_gt_regs.h"
#include "xe_mmio.h"
#include "xe_pm.h"

/**
 * DOC: Xe GT Idle
 *
 * Contains functions that init GT idle features like C6
 *
 * device/gt#/gtidle/name - name of the state
 * device/gt#/gtidle/idle_residency_ms - Provides residency of the idle state in ms
 * device/gt#/gtidle/idle_status - Provides current idle state
 */

static struct xe_gt_idle *dev_to_gtidle(struct device *dev)
{
	struct kobject *kobj = &dev->kobj;

	return &kobj_to_gt(kobj->parent)->gtidle;
}

static struct xe_gt *gtidle_to_gt(struct xe_gt_idle *gtidle)
{
	return container_of(gtidle, struct xe_gt, gtidle);
}

static struct xe_guc_pc *gtidle_to_pc(struct xe_gt_idle *gtidle)
{
	return &gtidle_to_gt(gtidle)->uc.guc.pc;
}

static struct xe_device *
pc_to_xe(struct xe_guc_pc *pc)
{
	struct xe_guc *guc = container_of(pc, struct xe_guc, pc);
	struct xe_gt *gt = container_of(guc, struct xe_gt, uc.guc);

	return gt_to_xe(gt);
}

static const char *gt_idle_state_to_string(enum xe_gt_idle_state state)
{
	switch (state) {
	case GT_IDLE_C0:
		return "gt-c0";
	case GT_IDLE_C6:
		return "gt-c6";
	default:
		return "unknown";
	}
}

static u64 get_residency_ms(struct xe_gt_idle *gtidle, u64 cur_residency)
{
	u64 delta, overflow_residency, prev_residency;

	overflow_residency = BIT_ULL(32);

	/*
	 * Counter wrap handling
	 * Store previous hw counter values for counter wrap-around handling
	 * Relying on sufficient frequency of queries otherwise counters can still wrap.
	 */
	prev_residency = gtidle->prev_residency;
	gtidle->prev_residency = cur_residency;

	/* delta */
	if (cur_residency >= prev_residency)
		delta = cur_residency - prev_residency;
	else
		delta = cur_residency + (overflow_residency - prev_residency);

	/* Add delta to extended raw driver copy of idle residency */
	cur_residency = gtidle->cur_residency + delta;
	gtidle->cur_residency = cur_residency;

	/* residency multiplier in ns, convert to ms */
	cur_residency = mul_u64_u32_div(cur_residency, gtidle->residency_multiplier, 1e6);

	return cur_residency;
}

static ssize_t name_show(struct device *dev,
			 struct device_attribute *attr, char *buff)
{
	struct xe_gt_idle *gtidle = dev_to_gtidle(dev);
	struct xe_guc_pc *pc = gtidle_to_pc(gtidle);
	ssize_t ret;

	xe_pm_runtime_get(pc_to_xe(pc));
	ret = sysfs_emit(buff, "%s\n", gtidle->name);
	xe_pm_runtime_put(pc_to_xe(pc));

	return ret;
}
static DEVICE_ATTR_RO(name);

static ssize_t idle_status_show(struct device *dev,
				struct device_attribute *attr, char *buff)
{
	struct xe_gt_idle *gtidle = dev_to_gtidle(dev);
	struct xe_guc_pc *pc = gtidle_to_pc(gtidle);
	enum xe_gt_idle_state state;

	xe_pm_runtime_get(pc_to_xe(pc));
	state = gtidle->idle_status(pc);
	xe_pm_runtime_put(pc_to_xe(pc));

	return sysfs_emit(buff, "%s\n", gt_idle_state_to_string(state));
}
static DEVICE_ATTR_RO(idle_status);

static ssize_t idle_residency_ms_show(struct device *dev,
				      struct device_attribute *attr, char *buff)
{
	struct xe_gt_idle *gtidle = dev_to_gtidle(dev);
	struct xe_guc_pc *pc = gtidle_to_pc(gtidle);
	u64 residency;

	xe_pm_runtime_get(pc_to_xe(pc));
	residency = gtidle->idle_residency(pc);
	xe_pm_runtime_put(pc_to_xe(pc));

	return sysfs_emit(buff, "%llu\n", get_residency_ms(gtidle, residency));
}
static DEVICE_ATTR_RO(idle_residency_ms);

static const struct attribute *gt_idle_attrs[] = {
	&dev_attr_name.attr,
	&dev_attr_idle_status.attr,
	&dev_attr_idle_residency_ms.attr,
	NULL,
};

static void gt_idle_sysfs_fini(struct drm_device *drm, void *arg)
{
	struct kobject *kobj = arg;

	sysfs_remove_files(kobj, gt_idle_attrs);
	kobject_put(kobj);
}

int xe_gt_idle_sysfs_init(struct xe_gt_idle *gtidle)
{
	struct xe_gt *gt = gtidle_to_gt(gtidle);
	struct xe_device *xe = gt_to_xe(gt);
	struct kobject *kobj;
	int err;

	kobj = kobject_create_and_add("gtidle", gt->sysfs);
	if (!kobj)
		return -ENOMEM;

	if (xe_gt_is_media_type(gt)) {
		snprintf(gtidle->name, sizeof(gtidle->name), "gt%d-mc", gt->info.id);
		gtidle->idle_residency = xe_guc_pc_mc6_residency;
	} else {
		snprintf(gtidle->name, sizeof(gtidle->name), "gt%d-rc", gt->info.id);
		gtidle->idle_residency = xe_guc_pc_rc6_residency;
	}

	/* Multiplier for Residency counter in units of 1.28us */
	gtidle->residency_multiplier = 1280;
	gtidle->idle_status = xe_guc_pc_c_status;

	err = sysfs_create_files(kobj, gt_idle_attrs);
	if (err) {
		kobject_put(kobj);
		return err;
	}

	return drmm_add_action_or_reset(&xe->drm, gt_idle_sysfs_fini, kobj);
}

void xe_gt_idle_enable_c6(struct xe_gt *gt)
{
	xe_device_assert_mem_access(gt_to_xe(gt));
	xe_force_wake_assert_held(gt_to_fw(gt), XE_FW_GT);

	/* Units of 1280 ns for a total of 5s */
	xe_mmio_write32(gt, RC_IDLE_HYSTERSIS, 0x3B9ACA);
	/* Enable RC6 */
	xe_mmio_write32(gt, RC_CONTROL,
			RC_CTL_HW_ENABLE | RC_CTL_TO_MODE | RC_CTL_RC6_ENABLE);
}

void xe_gt_idle_disable_c6(struct xe_gt *gt)
{
	xe_device_assert_mem_access(gt_to_xe(gt));
	xe_force_wake_assert_held(gt_to_fw(gt), XE_FORCEWAKE_ALL);

	xe_mmio_write32(gt, PG_ENABLE, 0);
	xe_mmio_write32(gt, RC_CONTROL, 0);
	xe_mmio_write32(gt, RC_STATE, 0);
}
