|
@@ -64,6 +64,22 @@ struct ti_sci_xfers_info {
|
|
|
spinlock_t xfer_lock;
|
|
spinlock_t xfer_lock;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * struct ti_sci_rm_type_map - Structure representing TISCI Resource
|
|
|
|
|
+ * management representation of dev_ids.
|
|
|
|
|
+ * @dev_id: TISCI device ID
|
|
|
|
|
+ * @type: Corresponding id as identified by TISCI RM.
|
|
|
|
|
+ *
|
|
|
|
|
+ * Note: This is used only as a work around for using RM range apis
|
|
|
|
|
+ * for AM654 SoC. For future SoCs dev_id will be used as type
|
|
|
|
|
+ * for RM range APIs. In order to maintain ABI backward compatibility
|
|
|
|
|
+ * type is not being changed for AM654 SoC.
|
|
|
|
|
+ */
|
|
|
|
|
+struct ti_sci_rm_type_map {
|
|
|
|
|
+ u32 dev_id;
|
|
|
|
|
+ u16 type;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* struct ti_sci_desc - Description of SoC integration
|
|
* struct ti_sci_desc - Description of SoC integration
|
|
|
* @default_host_id: Host identifier representing the compute entity
|
|
* @default_host_id: Host identifier representing the compute entity
|
|
@@ -71,12 +87,14 @@ struct ti_sci_xfers_info {
|
|
|
* @max_msgs: Maximum number of messages that can be pending
|
|
* @max_msgs: Maximum number of messages that can be pending
|
|
|
* simultaneously in the system
|
|
* simultaneously in the system
|
|
|
* @max_msg_size: Maximum size of data per message that can be handled.
|
|
* @max_msg_size: Maximum size of data per message that can be handled.
|
|
|
|
|
+ * @rm_type_map: RM resource type mapping structure.
|
|
|
*/
|
|
*/
|
|
|
struct ti_sci_desc {
|
|
struct ti_sci_desc {
|
|
|
u8 default_host_id;
|
|
u8 default_host_id;
|
|
|
int max_rx_timeout_ms;
|
|
int max_rx_timeout_ms;
|
|
|
int max_msgs;
|
|
int max_msgs;
|
|
|
int max_msg_size;
|
|
int max_msg_size;
|
|
|
|
|
+ struct ti_sci_rm_type_map *rm_type_map;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -1617,6 +1635,153 @@ fail:
|
|
|
return ret;
|
|
return ret;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+static int ti_sci_get_resource_type(struct ti_sci_info *info, u16 dev_id,
|
|
|
|
|
+ u16 *type)
|
|
|
|
|
+{
|
|
|
|
|
+ struct ti_sci_rm_type_map *rm_type_map = info->desc->rm_type_map;
|
|
|
|
|
+ bool found = false;
|
|
|
|
|
+ int i;
|
|
|
|
|
+
|
|
|
|
|
+ /* If map is not provided then assume dev_id is used as type */
|
|
|
|
|
+ if (!rm_type_map) {
|
|
|
|
|
+ *type = dev_id;
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ for (i = 0; rm_type_map[i].dev_id; i++) {
|
|
|
|
|
+ if (rm_type_map[i].dev_id == dev_id) {
|
|
|
|
|
+ *type = rm_type_map[i].type;
|
|
|
|
|
+ found = true;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!found)
|
|
|
|
|
+ return -EINVAL;
|
|
|
|
|
+
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * ti_sci_get_resource_range - Helper to get a range of resources assigned
|
|
|
|
|
+ * to a host. Resource is uniquely identified by
|
|
|
|
|
+ * type and subtype.
|
|
|
|
|
+ * @handle: Pointer to TISCI handle.
|
|
|
|
|
+ * @dev_id: TISCI device ID.
|
|
|
|
|
+ * @subtype: Resource assignment subtype that is being requested
|
|
|
|
|
+ * from the given device.
|
|
|
|
|
+ * @s_host: Host processor ID to which the resources are allocated
|
|
|
|
|
+ * @range_start: Start index of the resource range
|
|
|
|
|
+ * @range_num: Number of resources in the range
|
|
|
|
|
+ *
|
|
|
|
|
+ * Return: 0 if all went fine, else return appropriate error.
|
|
|
|
|
+ */
|
|
|
|
|
+static int ti_sci_get_resource_range(const struct ti_sci_handle *handle,
|
|
|
|
|
+ u32 dev_id, u8 subtype, u8 s_host,
|
|
|
|
|
+ u16 *range_start, u16 *range_num)
|
|
|
|
|
+{
|
|
|
|
|
+ struct ti_sci_msg_resp_get_resource_range *resp;
|
|
|
|
|
+ struct ti_sci_msg_req_get_resource_range *req;
|
|
|
|
|
+ struct ti_sci_xfer *xfer;
|
|
|
|
|
+ struct ti_sci_info *info;
|
|
|
|
|
+ struct device *dev;
|
|
|
|
|
+ u16 type;
|
|
|
|
|
+ int ret = 0;
|
|
|
|
|
+
|
|
|
|
|
+ if (IS_ERR(handle))
|
|
|
|
|
+ return PTR_ERR(handle);
|
|
|
|
|
+ if (!handle)
|
|
|
|
|
+ return -EINVAL;
|
|
|
|
|
+
|
|
|
|
|
+ info = handle_to_ti_sci_info(handle);
|
|
|
|
|
+ dev = info->dev;
|
|
|
|
|
+
|
|
|
|
|
+ xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_RESOURCE_RANGE,
|
|
|
|
|
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
|
|
|
|
|
+ sizeof(*req), sizeof(*resp));
|
|
|
|
|
+ if (IS_ERR(xfer)) {
|
|
|
|
|
+ ret = PTR_ERR(xfer);
|
|
|
|
|
+ dev_err(dev, "Message alloc failed(%d)\n", ret);
|
|
|
|
|
+ return ret;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ret = ti_sci_get_resource_type(info, dev_id, &type);
|
|
|
|
|
+ if (ret) {
|
|
|
|
|
+ dev_err(dev, "rm type lookup failed for %u\n", dev_id);
|
|
|
|
|
+ goto fail;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ req = (struct ti_sci_msg_req_get_resource_range *)xfer->xfer_buf;
|
|
|
|
|
+ req->secondary_host = s_host;
|
|
|
|
|
+ req->type = type & MSG_RM_RESOURCE_TYPE_MASK;
|
|
|
|
|
+ req->subtype = subtype & MSG_RM_RESOURCE_SUBTYPE_MASK;
|
|
|
|
|
+
|
|
|
|
|
+ ret = ti_sci_do_xfer(info, xfer);
|
|
|
|
|
+ if (ret) {
|
|
|
|
|
+ dev_err(dev, "Mbox send fail %d\n", ret);
|
|
|
|
|
+ goto fail;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ resp = (struct ti_sci_msg_resp_get_resource_range *)xfer->xfer_buf;
|
|
|
|
|
+
|
|
|
|
|
+ if (!ti_sci_is_response_ack(resp)) {
|
|
|
|
|
+ ret = -ENODEV;
|
|
|
|
|
+ } else if (!resp->range_start && !resp->range_num) {
|
|
|
|
|
+ ret = -ENODEV;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ *range_start = resp->range_start;
|
|
|
|
|
+ *range_num = resp->range_num;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+fail:
|
|
|
|
|
+ ti_sci_put_one_xfer(&info->minfo, xfer);
|
|
|
|
|
+
|
|
|
|
|
+ return ret;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * ti_sci_cmd_get_resource_range - Get a range of resources assigned to host
|
|
|
|
|
+ * that is same as ti sci interface host.
|
|
|
|
|
+ * @handle: Pointer to TISCI handle.
|
|
|
|
|
+ * @dev_id: TISCI device ID.
|
|
|
|
|
+ * @subtype: Resource assignment subtype that is being requested
|
|
|
|
|
+ * from the given device.
|
|
|
|
|
+ * @range_start: Start index of the resource range
|
|
|
|
|
+ * @range_num: Number of resources in the range
|
|
|
|
|
+ *
|
|
|
|
|
+ * Return: 0 if all went fine, else return appropriate error.
|
|
|
|
|
+ */
|
|
|
|
|
+static int ti_sci_cmd_get_resource_range(const struct ti_sci_handle *handle,
|
|
|
|
|
+ u32 dev_id, u8 subtype,
|
|
|
|
|
+ u16 *range_start, u16 *range_num)
|
|
|
|
|
+{
|
|
|
|
|
+ return ti_sci_get_resource_range(handle, dev_id, subtype,
|
|
|
|
|
+ TI_SCI_IRQ_SECONDARY_HOST_INVALID,
|
|
|
|
|
+ range_start, range_num);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * ti_sci_cmd_get_resource_range_from_shost - Get a range of resources
|
|
|
|
|
+ * assigned to a specified host.
|
|
|
|
|
+ * @handle: Pointer to TISCI handle.
|
|
|
|
|
+ * @dev_id: TISCI device ID.
|
|
|
|
|
+ * @subtype: Resource assignment subtype that is being requested
|
|
|
|
|
+ * from the given device.
|
|
|
|
|
+ * @s_host: Host processor ID to which the resources are allocated
|
|
|
|
|
+ * @range_start: Start index of the resource range
|
|
|
|
|
+ * @range_num: Number of resources in the range
|
|
|
|
|
+ *
|
|
|
|
|
+ * Return: 0 if all went fine, else return appropriate error.
|
|
|
|
|
+ */
|
|
|
|
|
+static
|
|
|
|
|
+int ti_sci_cmd_get_resource_range_from_shost(const struct ti_sci_handle *handle,
|
|
|
|
|
+ u32 dev_id, u8 subtype, u8 s_host,
|
|
|
|
|
+ u16 *range_start, u16 *range_num)
|
|
|
|
|
+{
|
|
|
|
|
+ return ti_sci_get_resource_range(handle, dev_id, subtype, s_host,
|
|
|
|
|
+ range_start, range_num);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/*
|
|
/*
|
|
|
* ti_sci_setup_ops() - Setup the operations structures
|
|
* ti_sci_setup_ops() - Setup the operations structures
|
|
|
* @info: pointer to TISCI pointer
|
|
* @info: pointer to TISCI pointer
|
|
@@ -1627,6 +1792,7 @@ static void ti_sci_setup_ops(struct ti_sci_info *info)
|
|
|
struct ti_sci_core_ops *core_ops = &ops->core_ops;
|
|
struct ti_sci_core_ops *core_ops = &ops->core_ops;
|
|
|
struct ti_sci_dev_ops *dops = &ops->dev_ops;
|
|
struct ti_sci_dev_ops *dops = &ops->dev_ops;
|
|
|
struct ti_sci_clk_ops *cops = &ops->clk_ops;
|
|
struct ti_sci_clk_ops *cops = &ops->clk_ops;
|
|
|
|
|
+ struct ti_sci_rm_core_ops *rm_core_ops = &ops->rm_core_ops;
|
|
|
|
|
|
|
|
core_ops->reboot_device = ti_sci_cmd_core_reboot;
|
|
core_ops->reboot_device = ti_sci_cmd_core_reboot;
|
|
|
|
|
|
|
@@ -1657,6 +1823,10 @@ static void ti_sci_setup_ops(struct ti_sci_info *info)
|
|
|
cops->get_best_match_freq = ti_sci_cmd_clk_get_match_freq;
|
|
cops->get_best_match_freq = ti_sci_cmd_clk_get_match_freq;
|
|
|
cops->set_freq = ti_sci_cmd_clk_set_freq;
|
|
cops->set_freq = ti_sci_cmd_clk_set_freq;
|
|
|
cops->get_freq = ti_sci_cmd_clk_get_freq;
|
|
cops->get_freq = ti_sci_cmd_clk_get_freq;
|
|
|
|
|
+
|
|
|
|
|
+ rm_core_ops->get_range = ti_sci_cmd_get_resource_range;
|
|
|
|
|
+ rm_core_ops->get_range_from_shost =
|
|
|
|
|
+ ti_sci_cmd_get_resource_range_from_shost;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|