kernel_samsung_a53x/drivers/scsi/ufs/ufs-exynos-perf.h
2024-06-15 16:02:09 -03:00

168 lines
3.7 KiB
C
Executable file

/*
* IO Performance mode with UFS
*
* Copyright (C) 2019 Samsung Electronics Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Authors:
* Kiwoong <kwmad.kim@samsung.com>
*/
#ifndef _UFS_PERF_H_
#define _UFS_PERF_H_
#include <linux/types.h>
#include <linux/kthread.h>
#include <linux/completion.h>
#include <linux/spinlock.h>
#include <linux/sched/clock.h>
#include "ufshcd.h"
#if IS_ENABLED(CONFIG_CPU_FREQ)
#include <linux/cpufreq.h>
#endif
#if IS_ENABLED(CONFIG_EXYNOS_PM_QOS) || IS_ENABLED(CONFIG_EXYNOS_PM_QOS_MODULE)
#include <soc/samsung/exynos_pm_qos.h>
#endif
#if IS_ENABLED(CONFIG_ARM_EXYNOS_ACME) || IS_ENABLED(CONFIG_ARM_FREQ_QOS_TRACER)
#include <soc/samsung/freq-qos-tracer.h>
#endif
#include "ufs-exynos-perf-v1.h"
#include "ufs-exynos-gear.h"
enum {
__TOKEN_FAIL,
__TOKEN_NUM,
};
enum __traffic {
TRAFFIC_NONE = 0,
TRAFFIC_HIGH,
TRAFFIC_LOW,
};
static const char *__res_token[__TOKEN_NUM] = {
"fail to",
};
enum ufs_perf_op {
UFS_PERF_OP_NONE = 0,
UFS_PERF_OP_R,
UFS_PERF_OP_W,
UFS_PERF_OP_S,
UFS_PERF_OP_MAX,
};
enum ufs_perf_ctrl {
UFS_PERF_CTRL_NONE = 0, /* Not used to run handler */
UFS_PERF_CTRL_LOCK,
UFS_PERF_CTRL_RELEASE,
};
enum ufs_perf_entry {
UFS_PERF_ENTRY_QUEUED = 0,
UFS_PERF_ENTRY_RESET,
};
/* private */
enum policy_res {
R_OK = 0,
R_CTRL,
};
enum {
__UPDATE_V1 = 0,
__UPDATE_GEAR,
__UPDATE_MAX,
};
#define UPDATE_V1 BIT(__UPDATE_V1)
#define UPDATE_GEAR BIT(__UPDATE_GEAR)
enum {
__CTRL_REQ_DVFS = 0,
__CTRL_REQ_WB,
__CTRL_REQ_GEAR,
__CTRL_REQ_MAX,
};
#define CTRL_REQ_DVFS BIT(__CTRL_REQ_DVFS)
#define CTRL_REQ_WB BIT(__CTRL_REQ_WB)
enum ctrl_op {
CTRL_OP_NONE = 0,
CTRL_OP_UP,
CTRL_OP_DOWN,
};
struct ufs_perf {
int id;
/* stats chosen by externals */
u32 stat_bits;
/* interface from request to control */
u32 ctrl_handle[__CTRL_REQ_MAX];
spinlock_t lock_handle;
/* handler */
struct task_struct *handler;
struct completion completion; /* wake-up source */
enum ctrl_op ctrl_state[__CTRL_REQ_MAX];
/* sysfs */
struct kobject sysfs_kobj;
struct ufs_perf_stat_v1 stat_v1;
struct ufs_perf_stat_v2 stat_v2;
enum policy_res (*update[__UPDATE_MAX])(struct ufs_perf *perf, u32 qd,
enum ufs_perf_op op,
enum ufs_perf_entry);
int (*ctrl[__CTRL_REQ_MAX])(struct ufs_perf *perf, enum ctrl_op op);
/* knobs */
#if IS_ENABLED(CONFIG_EXYNOS_PM_QOS) || IS_ENABLED(CONFIG_EXYNOS_PM_QOS_MODULE)
struct exynos_pm_qos_request pm_qos_int;
s32 val_pm_qos_int;
struct exynos_pm_qos_request pm_qos_mif;
s32 val_pm_qos_mif;
#endif
#if IS_ENABLED(CONFIG_CPU_FREQ) || IS_ENABLED(CONFIG_ARM_FREQ_QOS_TRACER)
struct notifier_block cpufreq_nb;
struct freq_qos_request pm_qos_cluster0;
s32 val_pm_qos_cluster0;
struct freq_qos_request pm_qos_cluster1;
s32 val_pm_qos_cluster1;
struct freq_qos_request pm_qos_cluster2;
s32 val_pm_qos_cluster2;
#define MAX_CLUSTERS 3
int num_clusters;
unsigned int clusters[MAX_CLUSTERS];
#endif
/* handle only for wb */
struct ufs_hba *hba;
u8 exynos_gear_scale;
};
/* EXTERNAL FUNCTIONS */
void ufs_perf_reset(void *data);
void ufs_perf_update(void *data, u32 qd, struct scsi_cmnd *cmd, enum ufs_perf_op op);
bool ufs_perf_init(void **data, struct ufs_hba *hba);
void ufs_perf_exit(void *data);
void ufs_init_cpufreq_request(struct ufs_perf *perf, bool add_noob);
/* from stats */
int ufs_perf_init_v1(struct ufs_perf *perf);
void ufs_perf_exit_v1(struct ufs_perf *perf);
void ufs_gear_scale_init(struct ufs_perf *perf);
int ufs_gear_change(struct ufs_hba *hba, bool en);
/* to stats */
void ufs_perf_complete(struct ufs_perf *perf);
#endif /* _UFS_PERF_H_ */