<commit_before>/*
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: <NAME> <<EMAIL>>
 *          <NAME> <<EMAIL>>
 */
#include "drmP.h"
#include "radeon.h"
#include "avivod.h"

#define RADEON_IDLE_LOOP_MS 100
#define RADEON_RECLOCK_DELAY_MS 200
#define RADEON_WAIT_VBLANK_TIMEOUT 200

static void radeon_pm_set_clocks_locked(struct radeon_device *rdev);
static void radeon_pm_set_clocks(struct radeon_device *rdev);
static void radeon_pm_idle_work_handler(struct work_struct *work);
static int radeon_debugfs_pm_init(struct radeon_device *rdev);

static const char *pm_state_names[4] = {
	"PM_STATE_DISABLED",
	"PM_STATE_MINIMUM",
	"PM_STATE_PAUSED",
	"PM_STATE_ACTIVE"
};

static const char *pm_state_types[5] = {
	"Default",
	"Powersave",
	"Battery",
	"Balanced",
	"Performance",
};

static void radeon_print_power_mode_info(struct radeon_device *rdev)
{
	int i, j;
	bool is_default;

	DRM_INFO("%d Power State(s)\n", rdev->pm.num_power_states);
	for (i = 0; i < rdev->pm.num_power_states; i++) {
		if (rdev->pm.default_power_state == &rdev->pm.power_state[i])
			is_default = true;
		else
			is_default = false;
		DRM_INFO("State %d %s %s\n", i,
			 pm_state_types[rdev->pm.power_state[i].type],
			 is_default ? "(default)" : "");
		if ((rdev->flags & RADEON_IS_PCIE) && !(rdev->flags & RADEON_IS_IGP))
			DRM_INFO("\t%d PCIE Lanes\n", rdev->pm.power_state[i].non_clock_info.pcie_lanes);
		DRM_INFO("\t%d Clock Mode(s)\n", rdev->pm.power_state[i].num_clock_modes);
		for (j = 0; j < rdev->pm.power_state[i].num_clock_modes; j++) {
			if (rdev->flags & RADEON_IS_IGP)
				DRM_INFO("\t\t%d engine: %d\n",
					 j,
					 rdev->pm.power_state[i].clock_info[j].sclk * 10);
			else
				DRM_INFO("\t\t%d engine/memory: %d/%d\n",
					 j,
					 rdev->pm.power_state[i].clock_info[j].sclk * 10,
					 rdev->pm.power_state[i].clock_info[j].mclk * 10);
		}
	}
}

static struct radeon_power_state * radeon_pick_power_state(struct radeon_device *rdev,
							   enum radeon_pm_state_type type)
{
	int i, j;
	enum radeon_pm_state_type wanted_types[2];
	int wanted_count;

	switch (type) {
	case POWER_STATE_TYPE_DEFAULT:
	default:
		return rdev->pm.default_power_state;
	case POWER_STATE_TYPE_POWERSAVE:
		wanted_types[0] = POWER_STATE_TYPE_POWERSAVE;
		wanted_types[1] = POWER_STATE_TYPE_BATTERY;
		wanted_count = 2;
		break;
	case POWER_STATE_TYPE_BATTERY:
		wanted_types[0] = POWER_STATE_TYPE_BATTERY;
		wanted_types[1] = POWER_STATE_TYPE_POWERSAVE;
		wanted_count = 2;
		break;
	case POWER_STATE_TYPE_BALANCED:
	case POWER_STATE_TYPE_PERFORMANCE:
		wanted_types[0] = type;
		wanted_count = 1;
		break;
	}

	for (i = 0; i < wanted_count; i++) {
		for (j = 0; j < rdev->pm.num_power_states; j++) {
			if (rdev->pm.power_state[j].type == wanted_types[i])
				return &rdev->pm.power_state[j];
		}
	}

	return rdev->pm.default_power_state;
}

static struct radeon_pm_clock_info * radeon_pick_clock_mode(struct radeon_device *rdev,
							    struct radeon_power_state *power_state,
							    enum radeon_pm_clock_mode_type type)
{<commit_msg>drm/radeon/kms: for downclocking non-mobility check PERFORMANCE state<commit_after>/*
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: <NAME> <<EMAIL>>
 *          <NAME> <<EMAIL>>
 */
#include "drmP.h"
#include "radeon.h"
#include "avivod.h"

#define RADEON_IDLE_LOOP_MS 100
#define RADEON_RECLOCK_DELAY_MS 200
#define RADEON_WAIT_VBLANK_TIMEOUT 200

static void radeon_pm_set_clocks_locked(struct radeon_device *rdev);
static void radeon_pm_set_clocks(struct radeon_device *rdev);
static void radeon_pm_idle_work_handler(struct work_struct *work);
static int radeon_debugfs_pm_init(struct radeon_device *rdev);

static const char *pm_state_names[4] = {
	"PM_STATE_DISABLED",
	"PM_STATE_MINIMUM",
	"PM_STATE_PAUSED",
	"PM_STATE_ACTIVE"
};

static const char *pm_state_types[5] = {
	"Default",
	"Powersave",
	"Battery",
	"Balanced",
	"Performance",
};

static void radeon_print_power_mode_info(struct radeon_device *rdev)
{
	int i, j;
	bool is_default;

	DRM_INFO("%d Power State(s)\n", rdev->pm.num_power_states);
	for (i = 0; i < rdev->pm.num_power_states; i++) {
		if (rdev->pm.default_power_state == &rdev->pm.power_state[i])
			is_default = true;
		else
			is_default = false;
		DRM_INFO("State %d %s %s\n", i,
			 pm_state_types[rdev->pm.power_state[i].type],
			 is_default ? "(default)" : "");
		if ((rdev->flags & RADEON_IS_PCIE) && !(rdev->flags & RADEON_IS_IGP))
			DRM_INFO("\t%d PCIE Lanes\n", rdev->pm.power_state[i].non_clock_info.pcie_lanes);
		DRM_INFO("\t%d Clock Mode(s)\n", rdev->pm.power_state[i].num_clock_modes);
		for (j = 0; j < rdev->pm.power_state[i].num_clock_modes; j++) {
			if (rdev->flags & RADEON_IS_IGP)
				DRM_INFO("\t\t%d engine: %d\n",
					 j,
					 rdev->pm.power_state[i].clock_info[j].sclk * 10);
			else
				DRM_INFO("\t\t%d engine/memory: %d/%d\n",
					 j,
					 rdev->pm.power_state[i].clock_info[j].sclk * 10,
					 rdev->pm.power_state[i].clock_info[j].mclk * 10);
		}
	}
}

static struct radeon_power_state * radeon_pick_power_state(struct radeon_device *rdev,
							   enum radeon_pm_state_type type)
{
	int i, j;
	enum radeon_pm_state_type wanted_types[2];
	int wanted_count;

	switch (type) {
	case POWER_STATE_TYPE_DEFAULT:
	default:
		return rdev->pm.default_power_state;
	case POWER_STATE_TYPE_POWERSAVE:
		if (rdev->flags & RADEON_IS_MOBILITY) {
			wanted_types[0] = POWER_STATE_TYPE_POWERSAVE;
			wanted_types[1] = POWER_STATE_TYPE_BATTERY;
			wanted_count = 2;
		} else {
			wanted_types[0] = POWER_STATE_TYPE_PERFORMANCE;
			wanted_count = 1;
		}
		break;
	case POWER_STATE_TYPE_BATTERY:
		if (rdev->flags & RADEON_IS_MOBILITY) {
			wanted_types[0] = POWER_STATE_TYPE_BATTERY;
			wanted_types[1] = POWER_STATE_TYPE_POWERSAVE;
			wanted_count = 2;
		} else {
			wanted_types[0] = POWER_STATE_TYPE_PERFORMANCE;
			wanted_count = 1;
		}
		break;
	case POWER_STATE_TYPE_BALANCED:
	case POWER_STATE_TYPE_PERFORMANCE:
		wanted_types[0] = type;
		wanted_count = 1;
		break;
	}

	for (i = 0; i < wanted_count; i++) {
		for (j = 0; j < rdev->pm.num_power_states; j++) {
			if (rdev->pm.power_state[j].type == wanted_types[i])
				return &rdev->pm.power_state[j];
		}
	}

	return rdev->pm.default_power_state;
}

static struct radeon_pm_clock_info * radeon_pick_clock_mode(struct radeon_device *rdev,
							    struct radeon_power_state *power_state,
							    enum radeon_pm_clock_mode_type type)
{
{'fraction_non_alphanumeric': 0.11407652338214454, 'fraction_numerical': 0.007557864903164856, 'mean_word_length': 4.528067885117493, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2250895', 'n_tokens_mistral': 3442, 'n_tokens_neox': 3113, 'n_words': 772}