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;
}
Пример #3
0
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(&region_ctrl_lock);

	for (i = 0 ; i < num_regions; i++) {
		struct ocmem_hw_region *region = &region_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 = &region->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;
}