forked from MIrrors/gasket-driver
Apex performance ioctl
Change-Id: Id3ae759f748b3f8c6f6a5320a5088c43fad0e812
This commit is contained in:
15
apex.h
15
apex.h
@@ -77,6 +77,19 @@ struct apex_gate_clock_ioctl {
|
||||
u64 force_idle;
|
||||
};
|
||||
|
||||
/* Performance expectation ioctl. */
|
||||
enum apex_performance_expectation {
|
||||
APEX_PERFORMANCE_LOW = 0,
|
||||
APEX_PERFORMANCE_MED = 1,
|
||||
APEX_PERFORMANCE_HIGH = 2,
|
||||
APEX_PERFORMANCE_MAX = 3,
|
||||
};
|
||||
|
||||
struct apex_performance_expectation_ioctl {
|
||||
/* Expected performance from apex. */
|
||||
uint32_t performance;
|
||||
};
|
||||
|
||||
/* Base number for all Apex-common IOCTLs */
|
||||
#define APEX_IOCTL_BASE 0x7F
|
||||
|
||||
@@ -84,4 +97,6 @@ struct apex_gate_clock_ioctl {
|
||||
#define APEX_IOCTL_GATE_CLOCK \
|
||||
_IOW(APEX_IOCTL_BASE, 0, struct apex_gate_clock_ioctl)
|
||||
|
||||
#define APEX_IOCTL_PERFORMANCE_EXPECTATION _IOW(APEX_IOCTL_BASE, 1, struct apex_performance_expectation_ioctl)
|
||||
|
||||
#endif /* __APEX_H__ */
|
||||
|
||||
@@ -146,6 +146,8 @@ static long apex_ioctl(struct file *file, uint cmd, ulong arg);
|
||||
|
||||
static long apex_clock_gating(struct gasket_dev *gasket_dev, ulong arg);
|
||||
|
||||
static long apex_set_performance_expectation(struct gasket_dev *gasket_dev, ulong arg);
|
||||
|
||||
static int apex_enter_reset(struct gasket_dev *gasket_dev, uint type);
|
||||
|
||||
static int apex_quit_reset(struct gasket_dev *gasket_dev, uint type);
|
||||
@@ -652,6 +654,8 @@ static long apex_ioctl(struct file *filp, uint cmd, ulong arg)
|
||||
switch (cmd) {
|
||||
case APEX_IOCTL_GATE_CLOCK:
|
||||
return apex_clock_gating(gasket_dev, arg);
|
||||
case APEX_IOCTL_PERFORMANCE_EXPECTATION:
|
||||
return apex_set_performance_expectation(gasket_dev, arg);
|
||||
default:
|
||||
return -ENOTTY; /* unknown command */
|
||||
}
|
||||
@@ -697,6 +701,72 @@ static long apex_clock_gating(struct gasket_dev *gasket_dev, ulong arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* apex_set_performance_expectation: Adjust clock rates for Apex.
|
||||
* @gasket_dev: device pointer.
|
||||
* @arg: User ioctl arg, in this case to an apex_performance_expectation_ioctl struct.
|
||||
*/
|
||||
static long apex_set_performance_expectation(struct gasket_dev *gasket_dev, ulong arg)
|
||||
{
|
||||
struct apex_performance_expectation_ioctl ibuf;
|
||||
uint32_t rg_gcb_clk_div = 0;
|
||||
uint32_t rg_axi_clk_125m = 0;
|
||||
const int AXI_CLK_125M_SHIFT = 2;
|
||||
const int MCU_CLK_250M_SHIFT = 3;
|
||||
|
||||
// 8051 clock is always 250 MHz for PCIe, as it's not used at all.
|
||||
const uint32_t rg_8051_clk_250m = 1;
|
||||
|
||||
if (bypass_top_level)
|
||||
return 0;
|
||||
|
||||
if (copy_from_user(&ibuf, (void __user *)arg, sizeof(ibuf)))
|
||||
return -EFAULT;
|
||||
|
||||
switch (ibuf.performance) {
|
||||
case APEX_PERFORMANCE_LOW:
|
||||
// - GCB clock: 62.5 MHz
|
||||
// - AXI clock: 125 MHz
|
||||
rg_gcb_clk_div = 3;
|
||||
rg_axi_clk_125m = 0;
|
||||
break;
|
||||
|
||||
case APEX_PERFORMANCE_MED:
|
||||
// - GCB clock: 125 MHz
|
||||
// - AXI clock: 125 MHz
|
||||
rg_gcb_clk_div = 2;
|
||||
rg_axi_clk_125m = 0;
|
||||
break;
|
||||
|
||||
case APEX_PERFORMANCE_HIGH:
|
||||
// - GCB clock: 250 MHz
|
||||
// - AXI clock: 125 MHz
|
||||
rg_gcb_clk_div = 1;
|
||||
rg_axi_clk_125m = 0;
|
||||
break;
|
||||
|
||||
case APEX_PERFORMANCE_MAX:
|
||||
// - GCB clock: 500 MHz
|
||||
// - AXI clock: 125 MHz
|
||||
rg_gcb_clk_div = 0;
|
||||
rg_axi_clk_125m = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set clock rates for GCB, AXI, and 8051:
|
||||
*/
|
||||
gasket_read_modify_write_32(
|
||||
gasket_dev, APEX_BAR_INDEX, APEX_BAR2_REG_SCU_3,
|
||||
(rg_gcb_clk_div | (rg_axi_clk_125m << AXI_CLK_125M_SHIFT) | (rg_8051_clk_250m << MCU_CLK_250M_SHIFT)),
|
||||
/*mask_width=*/4, /*mask_shift=*/28);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Display driver sysfs entries.
|
||||
* @device: Kernel device structure.
|
||||
|
||||
Reference in New Issue
Block a user