static int msm_bus_rpm_req(int ctx, uint32_t rsc_type, uint32_t key, struct msm_bus_node_hw_info *hw_info, bool valid) { struct msm_rpm_request *rpm_req; int ret = 0, msg_id; if (ctx == ACTIVE_CTX) ctx = MSM_RPM_CTX_ACTIVE_SET; else if (ctx == DUAL_CTX) ctx = MSM_RPM_CTX_SLEEP_SET; rpm_req = msm_rpm_create_request(ctx, rsc_type, hw_info->hw_id, 1); if (rpm_req == NULL) { MSM_BUS_WARN("RPM: Couldn't create RPM Request\n"); return -ENXIO; } if (valid) { ret = msm_rpm_add_kvp_data(rpm_req, key, (const uint8_t *) &hw_info->bw, (int)(sizeof(uint64_t))); if (ret) { MSM_BUS_WARN("RPM: Add KVP failed for RPM Req:%u\n", rsc_type); goto free_rpm_request; } MSM_BUS_DBG("Added Key: %d, Val: %llu, size: %zu\n", key, hw_info->bw, sizeof(uint64_t)); } else { /* Invalidate RPM requests */ ret = msm_rpm_add_kvp_data(rpm_req, 0, NULL, 0); if (ret) { MSM_BUS_WARN("RPM: Add KVP failed for RPM Req:%u\n", rsc_type); goto free_rpm_request; } } msg_id = msm_rpm_send_request(rpm_req); if (!msg_id) { MSM_BUS_WARN("RPM: No message ID for req\n"); ret = -ENXIO; goto free_rpm_request; } ret = msm_rpm_wait_for_ack(msg_id); if (ret) { MSM_BUS_WARN("RPM: Ack failed\n"); goto free_rpm_request; } free_rpm_request: msm_rpm_free_request(rpm_req); return ret; }
static int msm_bus_rpm_req(u32 rsc_type, u32 key, u32 hwid, int ctx, u32 val) { struct msm_rpm_request *rpm_req; int ret, msg_id; rpm_req = msm_rpm_create_request(ctx, rsc_type, SPDM_RES_ID, 1); if (rpm_req == NULL) { pr_err("RPM: Couldn't create RPM Request\n"); return -ENXIO; } ret = msm_rpm_add_kvp_data(rpm_req, key, (const uint8_t *)&val, (int)(sizeof(uint32_t))); if (ret) { pr_err("RPM: Add KVP failed for RPM Req:%u\n", rsc_type); goto err; } pr_debug("Added Key: %d, Val: %u, size: %zu\n", key, (uint32_t)val, sizeof(uint32_t)); msg_id = msm_rpm_send_request(rpm_req); if (!msg_id) { pr_err("RPM: No message ID for req\n"); ret = -ENXIO; goto err; } ret = msm_rpm_wait_for_ack(msg_id); if (ret) { pr_err("RPM: Ack failed\n"); goto err; } err: msm_rpm_free_request(rpm_req); return ret; }
static int msm_bus_rpm_req(int ctx, uint32_t rsc_type, uint32_t key, struct msm_bus_node_hw_info *hw_info, bool valid) { struct qcom_msm_bus_req req = { .key = key, }; int ret = 0; if (ctx == ACTIVE_CTX) ctx = QCOM_SMD_RPM_ACTIVE_STATE; else if (ctx == DUAL_CTX) ctx = QCOM_SMD_RPM_SLEEP_STATE; #if 0 rpm_req = msm_rpm_create_request(ctx, rsc_type, hw_info->hw_id, 1); if (rpm_req == NULL) { MSM_BUS_WARN("RPM: Couldn't create RPM Request\n"); return -ENXIO; } #endif if (valid) { req.value = hw_info->bw; req.nbytes = sizeof(uint64_t); #if 0 ret = msm_rpm_add_kvp_data(rpm_req, key, (const uint8_t *) &hw_info->bw, (int)(sizeof(uint64_t))); if (ret) { MSM_BUS_WARN("RPM: Add KVP failed for RPM Req:%u\n", rsc_type); goto free_rpm_request; } MSM_BUS_DBG("Added Key: %d, Val: %llu, size: %zu\n", key, hw_info->bw, sizeof(uint64_t)); #endif } else { req.value = 0; req.nbytes = 0; #if 0 /* Invalidate RPM requests */ ret = msm_rpm_add_kvp_data(rpm_req, 0, NULL, 0); if (ret) { MSM_BUS_WARN("RPM: Add KVP failed for RPM Req:%u\n", rsc_type); goto free_rpm_request; } #endif } #if 0 msg_id = msm_rpm_send_request(rpm_req); if (!msg_id) { MSM_BUS_WARN("RPM: No message ID for req\n"); ret = -ENXIO; goto free_rpm_request; } ret = msm_rpm_wait_for_ack(msg_id); if (ret) { MSM_BUS_WARN("RPM: Ack failed\n"); goto free_rpm_request; } free_rpm_request: msm_rpm_free_request(rpm_req); #endif ret = qcom_rpm_bus_send_message(ctx, rsc_type, hw_info->hw_id, &req); return ret; }
static ssize_t rsc_ops_write(struct file *fp, const char __user *user_buffer, size_t count, loff_t *position) { char buf[MAX_MSG_BUFFER], rsc_type_str[6] = {}, rpm_set[8] = {}, key_str[6] = {}; int i, pos, set = -1, nelems; char *cmp; uint32_t rsc_type, rsc_id, key, data; struct msm_rpm_request *req; count = min(count, sizeof(buf) - 1); if (copy_from_user(&buf, user_buffer, count)) return -EFAULT; buf[count] = '\0'; cmp = strstrip(buf); sscanf(cmp, "%7s %5s %u %d %n", rpm_set, rsc_type_str, &rsc_id, &nelems, &pos); if (strlen(rpm_set) > 6 || strlen(rsc_type_str) > 4) { pr_err("Invalid value of set or resource type\n"); goto err; } if (!strcmp(rpm_set, "active")) set = 0; else if (!strcmp(rpm_set, "sleep")) set = 1; rsc_type = string_to_uint(rsc_type_str); if (set < 0 || nelems < 0) { pr_err("Invalid value of set or nelems\n"); goto err; } if (nelems > MAX_KEY_VALUE_PAIRS) { pr_err("Exceeded max no of key-value entries\n"); goto err; } req = msm_rpm_create_request(set, rsc_type, rsc_id, nelems); if (!req) return -ENOMEM; for (i = 0; i < nelems; i++) { cmp += pos; sscanf(cmp, "%5s %n", key_str, &pos); if (strlen(key_str) > 4) { pr_err("Key value cannot be more than 4 charecters"); goto err; } key = string_to_uint(key_str); if (!key) { pr_err("Key values entered incorrectly\n"); goto err; } cmp += pos; sscanf(cmp, "%u %n", &data, &pos); if (msm_rpm_add_kvp_data(req, key, (void *)&data, sizeof(data))) goto err_request; } if (msm_rpm_wait_for_ack(msm_rpm_send_request(req))) pr_err("Sending the RPM message failed\n"); else pr_info("RPM message sent succesfully\n"); err_request: msm_rpm_free_request(req); err: return count; }
int ocmem_core_init(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct ocmem_plat_data *pdata = NULL; unsigned hw_ver; bool interleaved; unsigned i, j, k; unsigned rsc_type = 0; int rc = 0; pdata = platform_get_drvdata(pdev); ocmem_base = pdata->reg_base; rc = ocmem_enable_core_clock(); if (rc < 0) return rc; hw_ver = ocmem_read(ocmem_base + OC_HW_PROFILE); if (pdata->nr_regions != OCMEM_V1_REGIONS) { pr_err("Invalid number of regions (%d)\n", pdata->nr_regions); goto hw_not_supported; } num_macros = (hw_ver & NUM_MACROS_MASK) >> NUM_MACROS_SHIFT; num_ports = (hw_ver & NUM_PORTS_MASK) >> NUM_PORTS_SHIFT; if (num_macros != OCMEM_V1_MACROS) { pr_err("Invalid number of macros (%d)\n", pdata->nr_macros); goto hw_not_supported; } interleaved = (hw_ver & INTERLEAVING_MASK) >> INTERLEAVING_SHIFT; if (interleaved == false) { pr_err("Interleaving is disabled\n"); goto hw_not_supported; } num_regions = pdata->nr_regions; pdata->interleaved = true; pdata->nr_macros = num_macros; pdata->nr_ports = num_ports; macro_size = OCMEM_V1_MACRO_SZ * 2; num_banks = num_ports / 2; region_size = macro_size * num_banks; rsc_type = pdata->rpm_rsc_type; pr_debug("ocmem_core: ports %d regions %d macros %d interleaved %d\n", num_ports, num_regions, num_macros, interleaved); region_ctrl = devm_kzalloc(dev, sizeof(struct ocmem_hw_region) * num_regions, GFP_KERNEL); if (!region_ctrl) { goto err_no_mem; } mutex_init(®ion_ctrl_lock); for (i = 0 ; i < num_regions; i++) { struct ocmem_hw_region *region = ®ion_ctrl[i]; struct msm_rpm_request *req = NULL; region->interleaved = interleaved; region->mode = MODE_DEFAULT; region->r_state = REGION_DEFAULT_OFF; region->num_macros = num_banks; region->macro = devm_kzalloc(dev, sizeof(struct ocmem_hw_macro) * num_banks, GFP_KERNEL); if (!region->macro) { goto err_no_mem; } for (j = 0; j < num_banks; j++) { struct ocmem_hw_macro *m = ®ion->macro[j]; m->m_state = MACRO_OFF; for (k = 0; k < OCMEM_CLIENT_MAX; k++) { atomic_set(&m->m_on[k], 0); atomic_set(&m->m_retain[k], 0); } } if (pdata->rpm_pwr_ctrl) { rpm_power_control = true; req = msm_rpm_create_request(MSM_RPM_CTX_ACTIVE_SET, rsc_type, i, num_banks); if (!req) { pr_err("Unable to create RPM request\n"); goto region_init_error; } pr_debug("rpm request type %x (rsc: %d) with %d elements\n", rsc_type, i, num_banks); region->rpm_req = req; } if (ocmem_region_toggle(i)) { pr_err("Failed to verify region %d\n", i); goto region_init_error; } if (ocmem_region_set_default_state(i)) { pr_err("Failed to initialize region %d\n", i); goto region_init_error; } } rc = ocmem_core_set_default_state(); if (rc < 0) return rc; ocmem_disable_core_clock(); return 0; err_no_mem: pr_err("ocmem: Unable to allocate memory\n"); region_init_error: hw_not_supported: pr_err("Unsupported OCMEM h/w configuration %x\n", hw_ver); ocmem_disable_core_clock(); return -EINVAL; }