diff options
author | Holmes Chou <holmeschou@google.com> | 2023-03-24 06:27:07 +0000 |
---|---|---|
committer | Holmes Chou <holmeschou@google.com> | 2023-04-14 13:33:06 +0000 |
commit | f2d000ad8afbce771bfb056bbb613171999ff879 (patch) | |
tree | 7cc6e97272e68cfbec018f3a60bef2d5d06c7a98 | |
parent | ff2dd0ff9b8c6a9995a832dedcd8ccf111d5b672 (diff) | |
download | lwis-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.h | 32 | ||||
-rw-r--r-- | lwis_device_dpm.c | 10 | ||||
-rw-r--r-- | lwis_device_dpm.h | 2 | ||||
-rw-r--r-- | lwis_ioctl.c | 69 |
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) { |