summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHolmes Chou <holmeschou@google.com>2023-03-24 06:27:07 +0000
committerHolmes Chou <holmeschou@google.com>2023-04-14 13:33:06 +0000
commitf2d000ad8afbce771bfb056bbb613171999ff879 (patch)
tree7cc6e97272e68cfbec018f3a60bef2d5d06c7a98
parentff2dd0ff9b8c6a9995a832dedcd8ccf111d5b672 (diff)
downloadlwis-f2d000ad8afbce771bfb056bbb613171999ff879.tar.gz
LWIS: Add a new command for current LWIS_BTS_BLOCK_NAME_ENABLED on
Add a new command for current LWIS_BTS_BLOCK_NAME_ENABLED on, then user space can use this new command. After that, we can remove the LWIS_BTS_BLOCK_NAME_ENABLED flag. Bug: 272148737 Test: GCA, CTS Change-Id: I37d83e5c9f5fd466d12869d0b3afd757c3c659be Signed-off-by: Holmes Chou <holmeschou@google.com>
-rw-r--r--lwis_commands.h32
-rw-r--r--lwis_device_dpm.c10
-rw-r--r--lwis_device_dpm.h2
-rw-r--r--lwis_ioctl.c69
4 files changed, 103 insertions, 10 deletions
diff --git a/lwis_commands.h b/lwis_commands.h
index 794cfe4..caf5fcf 100644
--- a/lwis_commands.h
+++ b/lwis_commands.h
@@ -417,6 +417,25 @@ struct lwis_qos_setting {
#endif
};
+struct lwis_qos_setting_v2 {
+ // Frequency in hz.
+ int64_t frequency_hz;
+ // Device id for this vote.
+ int32_t device_id;
+ // Target clock family.
+ int32_t clock_family;
+ // read BW
+ int64_t read_bw;
+ // write BW
+ int64_t write_bw;
+ // peak BW
+ int64_t peak_bw;
+ // RT BW (total peak)
+ int64_t rt_bw;
+ // Bts client name
+ char bts_block_name[LWIS_MAX_NAME_STRING_LEN];
+};
+
struct lwis_dpm_qos_requirements {
// qos entities from user.
struct lwis_qos_setting *qos_settings;
@@ -424,6 +443,13 @@ struct lwis_dpm_qos_requirements {
size_t num_settings;
};
+struct lwis_dpm_qos_requirements_v2 {
+ // qos entities from user.
+ struct lwis_qos_setting_v2 *qos_settings;
+ // number of qos_settings.
+ size_t num_settings;
+};
+
enum lwis_cmd_id {
LWIS_CMD_ID_ECHO = 0x100,
LWIS_CMD_ID_TIME_QUERY = 0x200,
@@ -457,6 +483,7 @@ enum lwis_cmd_id {
LWIS_CMD_ID_DPM_CLK_UPDATE = 0x70000,
LWIS_CMD_ID_DPM_QOS_UPDATE = 0x70100,
+ LWIS_CMD_ID_DPM_QOS_UPDATE_V2,
LWIS_CMD_ID_DPM_GET_CLOCK = 0x70200,
LWIS_CMD_ID_FENCE_CREATE = 0x80000
@@ -558,6 +585,11 @@ struct lwis_cmd_dpm_qos_update {
struct lwis_dpm_qos_requirements reqs;
};
+struct lwis_cmd_dpm_qos_update_v2 {
+ struct lwis_cmd_pkt header;
+ struct lwis_dpm_qos_requirements_v2 reqs;
+};
+
struct lwis_cmd_dpm_clk_get {
struct lwis_cmd_pkt header;
struct lwis_qos_setting setting;
diff --git a/lwis_device_dpm.c b/lwis_device_dpm.c
index 8f9b418..909928a 100644
--- a/lwis_device_dpm.c
+++ b/lwis_device_dpm.c
@@ -38,9 +38,8 @@ static struct lwis_event_subscribe_operations dpm_subscribe_ops = {
.release = NULL,
};
-#ifdef LWIS_BTS_BLOCK_NAME_ENABLED
static int find_bts_block(struct lwis_device *lwis_dev, struct lwis_device *target_dev,
- struct lwis_qos_setting *qos_setting)
+ struct lwis_qos_setting_v2 *qos_setting)
{
int i;
@@ -64,12 +63,11 @@ static int find_bts_block(struct lwis_device *lwis_dev, struct lwis_device *targ
return -EINVAL;
}
}
-#endif
/*
* lwis_dpm_update_qos: update qos requirement for lwis device.
*/
-int lwis_dpm_update_qos(struct lwis_device *lwis_dev, struct lwis_qos_setting *qos_setting)
+int lwis_dpm_update_qos(struct lwis_device *lwis_dev, struct lwis_qos_setting_v2 *qos_setting)
{
int ret = 0, bts_block = -1;
int64_t peak_bw = 0;
@@ -106,14 +104,10 @@ int lwis_dpm_update_qos(struct lwis_device *lwis_dev, struct lwis_qos_setting *q
qos_setting->clock_family);
}
} else {
-#ifdef LWIS_BTS_BLOCK_NAME_ENABLED
bts_block = find_bts_block(lwis_dev, target_dev, qos_setting);
if (bts_block < 0) {
return bts_block;
}
-#else
- bts_block = 0;
-#endif
read_bw = qos_setting->read_bw;
write_bw = qos_setting->write_bw;
diff --git a/lwis_device_dpm.h b/lwis_device_dpm.h
index 077c056..0aeba1f 100644
--- a/lwis_device_dpm.h
+++ b/lwis_device_dpm.h
@@ -32,7 +32,7 @@ int lwis_dpm_update_clock(struct lwis_device *lwis_dev, struct lwis_clk_setting
/*
* lwis_dpm_update_qos: update qos requirement from dpm client.
*/
-int lwis_dpm_update_qos(struct lwis_device *lwis_dev, struct lwis_qos_setting *qos_setting);
+int lwis_dpm_update_qos(struct lwis_device *lwis_dev, struct lwis_qos_setting_v2 *qos_setting);
/*
* lwis_dpm_read_clock: read current IP core clock for given lwis device.
diff --git a/lwis_ioctl.c b/lwis_ioctl.c
index 2a55259..3694204 100644
--- a/lwis_ioctl.c
+++ b/lwis_ioctl.c
@@ -1433,6 +1433,67 @@ static int cmd_dpm_qos_update(struct lwis_device *lwis_dev, struct lwis_cmd_pkt
}
for (i = 0; i < k_msg.reqs.num_settings; i++) {
+ if (sizeof(struct lwis_qos_setting) != sizeof(struct lwis_qos_setting_v2)) {
+ struct lwis_qos_setting_v2 k_qos_setting_v2;
+ memcpy(&k_qos_setting_v2, &k_qos_settings[i], sizeof(struct lwis_qos_setting));
+ k_qos_setting_v2.bts_block_name[0] = '\0';
+ ret = lwis_dpm_update_qos(lwis_dev, &k_qos_setting_v2);
+ } else {
+ ret = lwis_dpm_update_qos(lwis_dev, (struct lwis_qos_setting_v2 *)&k_qos_settings[i]);
+ }
+ if (ret) {
+ dev_err(lwis_dev->dev, "Failed to apply qos setting, ret: %d\n", ret);
+ kfree(k_qos_settings);
+ goto exit;
+ }
+ }
+ kfree(k_qos_settings);
+exit:
+ header->ret_code = ret;
+ return copy_pkt_to_user(lwis_dev, u_msg, (void *)header, sizeof(*header));
+}
+
+static int cmd_dpm_qos_update_v2(struct lwis_device *lwis_dev, struct lwis_cmd_pkt *header,
+ struct lwis_cmd_dpm_qos_update_v2 __user *u_msg)
+{
+ struct lwis_cmd_dpm_qos_update_v2 k_msg;
+ struct lwis_qos_setting_v2 *k_qos_settings;
+ int ret = 0;
+ int i;
+ size_t buf_size;
+
+ if (lwis_dev->type != DEVICE_TYPE_DPM) {
+ dev_err(lwis_dev->dev, "not supported device type: %d\n", lwis_dev->type);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ if (copy_from_user((void *)&k_msg, (void __user *)u_msg, sizeof(k_msg))) {
+ dev_err(lwis_dev->dev, "Failed to copy ioctl message from user\n");
+ return -EFAULT;
+ }
+
+ // Copy qos settings from user buffer.
+ buf_size = sizeof(struct lwis_qos_setting_v2) * k_msg.reqs.num_settings;
+ if (buf_size / sizeof(struct lwis_qos_setting_v2) != k_msg.reqs.num_settings) {
+ dev_err(lwis_dev->dev, "Failed to copy qos settings due to integer overflow.\n");
+ ret = -EOVERFLOW;
+ goto exit;
+ }
+ k_qos_settings = kmalloc(buf_size, GFP_KERNEL);
+ if (!k_qos_settings) {
+ dev_err(lwis_dev->dev, "Failed to allocate qos settings\n");
+ ret = -ENOMEM;
+ goto exit;
+ }
+ if (copy_from_user(k_qos_settings, (void __user *)k_msg.reqs.qos_settings, buf_size)) {
+ dev_err(lwis_dev->dev, "Failed to copy clk settings from user\n");
+ kfree(k_qos_settings);
+ ret = -EFAULT;
+ goto exit;
+ }
+
+ for (i = 0; i < k_msg.reqs.num_settings; i++) {
ret = lwis_dpm_update_qos(lwis_dev, &k_qos_settings[i]);
if (ret) {
dev_err(lwis_dev->dev, "Failed to apply qos setting, ret: %d\n", ret);
@@ -1698,6 +1759,12 @@ static int lwis_ioctl_handle_cmd_pkt(struct lwis_client *lwis_client,
(struct lwis_cmd_dpm_qos_update __user *)user_msg);
mutex_unlock(&lwis_client->lock);
break;
+ case LWIS_CMD_ID_DPM_QOS_UPDATE_V2:
+ mutex_lock(&lwis_client->lock);
+ ret = cmd_dpm_qos_update_v2(lwis_dev, &header,
+ (struct lwis_cmd_dpm_qos_update_v2 __user *)user_msg);
+ mutex_unlock(&lwis_client->lock);
+ break;
case LWIS_CMD_ID_DPM_GET_CLOCK:
mutex_lock(&lwis_client->lock);
ret = cmd_dpm_get_clock(lwis_dev, &header,
@@ -1712,7 +1779,7 @@ static int lwis_ioctl_handle_cmd_pkt(struct lwis_client *lwis_client,
#endif
default:
dev_err_ratelimited(lwis_dev->dev, "Unknown command id\n");
- header.ret_code = -EINVAL;
+ header.ret_code = -ENOSYS;
ret = copy_pkt_to_user(lwis_dev, user_msg, (void *)&header, sizeof(header));
}
if (ret) {