Apex performance ioctl

Change-Id: Id3ae759f748b3f8c6f6a5320a5088c43fad0e812
This commit is contained in:
Alex Van Damme
2018-07-23 16:06:02 -07:00
parent d737e80b17
commit 237454b288
2 changed files with 85 additions and 0 deletions

View File

@@ -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.