Merge branch '2019-07-26-ti-imports'
- Bring in the rest of the J271E platform - Various OMAP3/AM3517, DA850 fixes
This commit is contained in:
@@ -87,11 +87,18 @@ struct ti_sci_info {
|
||||
struct mbox_chan chan_notify;
|
||||
struct ti_sci_xfer xfer;
|
||||
struct list_head list;
|
||||
struct list_head dev_list;
|
||||
bool is_secure;
|
||||
u8 host_id;
|
||||
u8 seq;
|
||||
};
|
||||
|
||||
struct ti_sci_exclusive_dev {
|
||||
u32 id;
|
||||
u32 count;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
#define handle_to_ti_sci_info(h) container_of(h, struct ti_sci_info, handle)
|
||||
|
||||
/**
|
||||
@@ -101,7 +108,8 @@ struct ti_sci_info {
|
||||
* @msg_flags: Flag to set for the message
|
||||
* @buf: Buffer to be send to mailbox channel
|
||||
* @tx_message_size: transmit message size
|
||||
* @rx_message_size: receive message size
|
||||
* @rx_message_size: receive message size. may be set to zero for send-only
|
||||
* transactions.
|
||||
*
|
||||
* Helper function which is used by various command functions that are
|
||||
* exposed to clients of this driver for allocating a message traffic event.
|
||||
@@ -121,7 +129,8 @@ static struct ti_sci_xfer *ti_sci_setup_one_xfer(struct ti_sci_info *info,
|
||||
/* Ensure we have sane transfer sizes */
|
||||
if (rx_message_size > info->desc->max_msg_size ||
|
||||
tx_message_size > info->desc->max_msg_size ||
|
||||
rx_message_size < sizeof(*hdr) || tx_message_size < sizeof(*hdr))
|
||||
(rx_message_size > 0 && rx_message_size < sizeof(*hdr)) ||
|
||||
tx_message_size < sizeof(*hdr))
|
||||
return ERR_PTR(-ERANGE);
|
||||
|
||||
info->seq = ~info->seq;
|
||||
@@ -219,7 +228,9 @@ static inline int ti_sci_do_xfer(struct ti_sci_info *info,
|
||||
|
||||
xfer->tx_message.buf = (u32 *)secure_buf;
|
||||
xfer->tx_message.len += sizeof(secure_hdr);
|
||||
xfer->rx_len += sizeof(secure_hdr);
|
||||
|
||||
if (xfer->rx_len)
|
||||
xfer->rx_len += sizeof(secure_hdr);
|
||||
}
|
||||
|
||||
/* Send the message */
|
||||
@@ -230,7 +241,11 @@ static inline int ti_sci_do_xfer(struct ti_sci_info *info,
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ti_sci_get_response(info, xfer, &info->chan_rx);
|
||||
/* Get response if requested */
|
||||
if (xfer->rx_len)
|
||||
ret = ti_sci_get_response(info, xfer, &info->chan_rx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -419,6 +434,47 @@ static int ti_sci_cmd_set_board_config_pm(const struct ti_sci_handle *handle,
|
||||
addr, size);
|
||||
}
|
||||
|
||||
static struct ti_sci_exclusive_dev
|
||||
*ti_sci_get_exclusive_dev(struct list_head *dev_list, u32 id)
|
||||
{
|
||||
struct ti_sci_exclusive_dev *dev;
|
||||
|
||||
list_for_each_entry(dev, dev_list, list)
|
||||
if (dev->id == id)
|
||||
return dev;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void ti_sci_add_exclusive_dev(struct ti_sci_info *info, u32 id)
|
||||
{
|
||||
struct ti_sci_exclusive_dev *dev;
|
||||
|
||||
dev = ti_sci_get_exclusive_dev(&info->dev_list, id);
|
||||
if (dev) {
|
||||
dev->count++;
|
||||
return;
|
||||
}
|
||||
|
||||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
dev->id = id;
|
||||
dev->count = 1;
|
||||
INIT_LIST_HEAD(&dev->list);
|
||||
list_add_tail(&dev->list, &info->dev_list);
|
||||
}
|
||||
|
||||
static void ti_sci_delete_exclusive_dev(struct ti_sci_info *info, u32 id)
|
||||
{
|
||||
struct ti_sci_exclusive_dev *dev;
|
||||
|
||||
dev = ti_sci_get_exclusive_dev(&info->dev_list, id);
|
||||
if (!dev)
|
||||
return;
|
||||
|
||||
if (dev->count > 0)
|
||||
dev->count--;
|
||||
}
|
||||
|
||||
/**
|
||||
* ti_sci_set_device_state() - Set device state helper
|
||||
* @handle: pointer to TI SCI handle
|
||||
@@ -466,6 +522,54 @@ static int ti_sci_set_device_state(const struct ti_sci_handle *handle,
|
||||
if (!ti_sci_is_response_ack(resp))
|
||||
return -ENODEV;
|
||||
|
||||
if (state == MSG_DEVICE_SW_STATE_AUTO_OFF)
|
||||
ti_sci_delete_exclusive_dev(info, id);
|
||||
else if (flags & MSG_FLAG_DEVICE_EXCLUSIVE)
|
||||
ti_sci_add_exclusive_dev(info, id);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ti_sci_set_device_state_no_wait() - Set device state helper without
|
||||
* requesting or waiting for a response.
|
||||
* @handle: pointer to TI SCI handle
|
||||
* @id: Device identifier
|
||||
* @flags: flags to setup for the device
|
||||
* @state: State to move the device to
|
||||
*
|
||||
* Return: 0 if all went well, else returns appropriate error value.
|
||||
*/
|
||||
static int ti_sci_set_device_state_no_wait(const struct ti_sci_handle *handle,
|
||||
u32 id, u32 flags, u8 state)
|
||||
{
|
||||
struct ti_sci_msg_req_set_device_state req;
|
||||
struct ti_sci_info *info;
|
||||
struct ti_sci_xfer *xfer;
|
||||
int ret = 0;
|
||||
|
||||
if (IS_ERR(handle))
|
||||
return PTR_ERR(handle);
|
||||
if (!handle)
|
||||
return -EINVAL;
|
||||
|
||||
info = handle_to_ti_sci_info(handle);
|
||||
|
||||
xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SET_DEVICE_STATE,
|
||||
flags | TI_SCI_FLAG_REQ_GENERIC_NORESPONSE,
|
||||
(u32 *)&req, sizeof(req), 0);
|
||||
if (IS_ERR(xfer)) {
|
||||
ret = PTR_ERR(xfer);
|
||||
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
req.id = id;
|
||||
req.state = state;
|
||||
|
||||
ret = ti_sci_do_xfer(info, xfer);
|
||||
if (ret)
|
||||
dev_err(info->dev, "Mbox send fail %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -547,8 +651,14 @@ static int ti_sci_get_device_state(const struct ti_sci_handle *handle,
|
||||
*/
|
||||
static int ti_sci_cmd_get_device(const struct ti_sci_handle *handle, u32 id)
|
||||
{
|
||||
return ti_sci_set_device_state(handle, id,
|
||||
MSG_FLAG_DEVICE_EXCLUSIVE,
|
||||
return ti_sci_set_device_state(handle, id, 0,
|
||||
MSG_DEVICE_SW_STATE_ON);
|
||||
}
|
||||
|
||||
static int ti_sci_cmd_get_device_exclusive(const struct ti_sci_handle *handle,
|
||||
u32 id)
|
||||
{
|
||||
return ti_sci_set_device_state(handle, id, MSG_FLAG_DEVICE_EXCLUSIVE,
|
||||
MSG_DEVICE_SW_STATE_ON);
|
||||
}
|
||||
|
||||
@@ -566,7 +676,14 @@ static int ti_sci_cmd_get_device(const struct ti_sci_handle *handle, u32 id)
|
||||
static int ti_sci_cmd_idle_device(const struct ti_sci_handle *handle, u32 id)
|
||||
{
|
||||
return ti_sci_set_device_state(handle, id,
|
||||
MSG_FLAG_DEVICE_EXCLUSIVE,
|
||||
0,
|
||||
MSG_DEVICE_SW_STATE_RETENTION);
|
||||
}
|
||||
|
||||
static int ti_sci_cmd_idle_device_exclusive(const struct ti_sci_handle *handle,
|
||||
u32 id)
|
||||
{
|
||||
return ti_sci_set_device_state(handle, id, MSG_FLAG_DEVICE_EXCLUSIVE,
|
||||
MSG_DEVICE_SW_STATE_RETENTION);
|
||||
}
|
||||
|
||||
@@ -583,8 +700,27 @@ static int ti_sci_cmd_idle_device(const struct ti_sci_handle *handle, u32 id)
|
||||
*/
|
||||
static int ti_sci_cmd_put_device(const struct ti_sci_handle *handle, u32 id)
|
||||
{
|
||||
return ti_sci_set_device_state(handle, id,
|
||||
0, MSG_DEVICE_SW_STATE_AUTO_OFF);
|
||||
return ti_sci_set_device_state(handle, id, 0,
|
||||
MSG_DEVICE_SW_STATE_AUTO_OFF);
|
||||
}
|
||||
|
||||
static
|
||||
int ti_sci_cmd_release_exclusive_devices(const struct ti_sci_handle *handle)
|
||||
{
|
||||
struct ti_sci_exclusive_dev *dev, *tmp;
|
||||
struct ti_sci_info *info;
|
||||
int i, cnt;
|
||||
|
||||
info = handle_to_ti_sci_info(handle);
|
||||
|
||||
list_for_each_entry_safe(dev, tmp, &info->dev_list, list) {
|
||||
cnt = dev->count;
|
||||
debug("%s: id = %d, cnt = %d\n", __func__, dev->id, cnt);
|
||||
for (i = 0; i < cnt; i++)
|
||||
ti_sci_cmd_put_device(handle, dev->id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2026,6 +2162,137 @@ static int ti_sci_cmd_get_proc_boot_status(const struct ti_sci_handle *handle,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ti_sci_proc_wait_boot_status_no_wait() - Helper function to wait for a
|
||||
* processor boot status without requesting or
|
||||
* waiting for a response.
|
||||
* @proc_id: Processor ID this request is for
|
||||
* @num_wait_iterations: Total number of iterations we will check before
|
||||
* we will timeout and give up
|
||||
* @num_match_iterations: How many iterations should we have continued
|
||||
* status to account for status bits glitching.
|
||||
* This is to make sure that match occurs for
|
||||
* consecutive checks. This implies that the
|
||||
* worst case should consider that the stable
|
||||
* time should at the worst be num_wait_iterations
|
||||
* num_match_iterations to prevent timeout.
|
||||
* @delay_per_iteration_us: Specifies how long to wait (in micro seconds)
|
||||
* between each status checks. This is the minimum
|
||||
* duration, and overhead of register reads and
|
||||
* checks are on top of this and can vary based on
|
||||
* varied conditions.
|
||||
* @delay_before_iterations_us: Specifies how long to wait (in micro seconds)
|
||||
* before the very first check in the first
|
||||
* iteration of status check loop. This is the
|
||||
* minimum duration, and overhead of register
|
||||
* reads and checks are.
|
||||
* @status_flags_1_set_all_wait:If non-zero, Specifies that all bits of the
|
||||
* status matching this field requested MUST be 1.
|
||||
* @status_flags_1_set_any_wait:If non-zero, Specifies that at least one of the
|
||||
* bits matching this field requested MUST be 1.
|
||||
* @status_flags_1_clr_all_wait:If non-zero, Specifies that all bits of the
|
||||
* status matching this field requested MUST be 0.
|
||||
* @status_flags_1_clr_any_wait:If non-zero, Specifies that at least one of the
|
||||
* bits matching this field requested MUST be 0.
|
||||
*
|
||||
* Return: 0 if all goes well, else appropriate error message
|
||||
*/
|
||||
static int
|
||||
ti_sci_proc_wait_boot_status_no_wait(const struct ti_sci_handle *handle,
|
||||
u8 proc_id,
|
||||
u8 num_wait_iterations,
|
||||
u8 num_match_iterations,
|
||||
u8 delay_per_iteration_us,
|
||||
u8 delay_before_iterations_us,
|
||||
u32 status_flags_1_set_all_wait,
|
||||
u32 status_flags_1_set_any_wait,
|
||||
u32 status_flags_1_clr_all_wait,
|
||||
u32 status_flags_1_clr_any_wait)
|
||||
{
|
||||
struct ti_sci_msg_req_wait_proc_boot_status req;
|
||||
struct ti_sci_info *info;
|
||||
struct ti_sci_xfer *xfer;
|
||||
int ret = 0;
|
||||
|
||||
if (IS_ERR(handle))
|
||||
return PTR_ERR(handle);
|
||||
if (!handle)
|
||||
return -EINVAL;
|
||||
|
||||
info = handle_to_ti_sci_info(handle);
|
||||
|
||||
xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_WAIT_PROC_BOOT_STATUS,
|
||||
TI_SCI_FLAG_REQ_GENERIC_NORESPONSE,
|
||||
(u32 *)&req, sizeof(req), 0);
|
||||
if (IS_ERR(xfer)) {
|
||||
ret = PTR_ERR(xfer);
|
||||
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
req.processor_id = proc_id;
|
||||
req.num_wait_iterations = num_wait_iterations;
|
||||
req.num_match_iterations = num_match_iterations;
|
||||
req.delay_per_iteration_us = delay_per_iteration_us;
|
||||
req.delay_before_iterations_us = delay_before_iterations_us;
|
||||
req.status_flags_1_set_all_wait = status_flags_1_set_all_wait;
|
||||
req.status_flags_1_set_any_wait = status_flags_1_set_any_wait;
|
||||
req.status_flags_1_clr_all_wait = status_flags_1_clr_all_wait;
|
||||
req.status_flags_1_clr_any_wait = status_flags_1_clr_any_wait;
|
||||
|
||||
ret = ti_sci_do_xfer(info, xfer);
|
||||
if (ret)
|
||||
dev_err(info->dev, "Mbox send fail %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ti_sci_cmd_proc_shutdown_no_wait() - Command to shutdown a core without
|
||||
* requesting or waiting for a response. Note that this API call
|
||||
* should be followed by placing the respective processor into
|
||||
* either WFE or WFI mode.
|
||||
* @handle: Pointer to TI SCI handle
|
||||
* @proc_id: Processor ID this request is for
|
||||
*
|
||||
* Return: 0 if all went well, else returns appropriate error value.
|
||||
*/
|
||||
static int ti_sci_cmd_proc_shutdown_no_wait(const struct ti_sci_handle *handle,
|
||||
u8 proc_id)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Send the core boot status wait message waiting for either WFE or
|
||||
* WFI without requesting or waiting for a TISCI response with the
|
||||
* maximum wait time to give us the best chance to get to the WFE/WFI
|
||||
* command that should follow the invocation of this API before the
|
||||
* DMSC-internal processing of this command times out. Note that
|
||||
* waiting for the R5 WFE/WFI flags will also work on an ARMV8 type
|
||||
* core as the related flag bit positions are the same.
|
||||
*/
|
||||
ret = ti_sci_proc_wait_boot_status_no_wait(handle, proc_id,
|
||||
U8_MAX, 100, U8_MAX, U8_MAX,
|
||||
0, PROC_BOOT_STATUS_FLAG_R5_WFE | PROC_BOOT_STATUS_FLAG_R5_WFI,
|
||||
0, 0);
|
||||
if (ret) {
|
||||
dev_err(info->dev, "Sending core %u wait message fail %d\n",
|
||||
proc_id, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Release a processor managed by TISCI without requesting or waiting
|
||||
* for a response.
|
||||
*/
|
||||
ret = ti_sci_set_device_state_no_wait(handle, proc_id, 0,
|
||||
MSG_DEVICE_SW_STATE_AUTO_OFF);
|
||||
if (ret)
|
||||
dev_err(info->dev, "Sending core %u shutdown message fail %d\n",
|
||||
proc_id, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ti_sci_cmd_ring_config() - configure RA ring
|
||||
* @handle: pointer to TI SCI handle
|
||||
@@ -2632,7 +2899,9 @@ static void ti_sci_setup_ops(struct ti_sci_info *info)
|
||||
bops->board_config_pm = ti_sci_cmd_set_board_config_pm;
|
||||
|
||||
dops->get_device = ti_sci_cmd_get_device;
|
||||
dops->get_device_exclusive = ti_sci_cmd_get_device_exclusive;
|
||||
dops->idle_device = ti_sci_cmd_idle_device;
|
||||
dops->idle_device_exclusive = ti_sci_cmd_idle_device_exclusive;
|
||||
dops->put_device = ti_sci_cmd_put_device;
|
||||
dops->is_valid = ti_sci_cmd_dev_is_valid;
|
||||
dops->get_context_loss_count = ti_sci_cmd_dev_get_clcnt;
|
||||
@@ -2642,6 +2911,7 @@ static void ti_sci_setup_ops(struct ti_sci_info *info)
|
||||
dops->is_transitioning = ti_sci_cmd_dev_is_trans;
|
||||
dops->set_device_resets = ti_sci_cmd_set_device_resets;
|
||||
dops->get_device_resets = ti_sci_cmd_get_device_resets;
|
||||
dops->release_exclusive_devices = ti_sci_cmd_release_exclusive_devices;
|
||||
|
||||
cops->get_clock = ti_sci_cmd_get_clock;
|
||||
cops->idle_clock = ti_sci_cmd_idle_clock;
|
||||
@@ -2672,6 +2942,7 @@ static void ti_sci_setup_ops(struct ti_sci_info *info)
|
||||
pops->set_proc_boot_ctrl = ti_sci_cmd_set_proc_boot_ctrl;
|
||||
pops->proc_auth_boot_image = ti_sci_cmd_proc_auth_boot_image;
|
||||
pops->get_proc_boot_status = ti_sci_cmd_get_proc_boot_status;
|
||||
pops->proc_shutdown_no_wait = ti_sci_cmd_proc_shutdown_no_wait;
|
||||
|
||||
rops->config = ti_sci_cmd_ring_config;
|
||||
rops->get_config = ti_sci_cmd_ring_get_config;
|
||||
@@ -2835,6 +3106,8 @@ static int ti_sci_probe(struct udevice *dev)
|
||||
|
||||
ret = ti_sci_cmd_get_revision(&info->handle);
|
||||
|
||||
INIT_LIST_HEAD(&info->dev_list);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#define TISCI_MSG_SET_PROC_BOOT_CTRL 0xc101
|
||||
#define TISCI_MSG_PROC_AUTH_BOOT_IMIAGE 0xc120
|
||||
#define TISCI_MSG_GET_PROC_BOOT_STATUS 0xc400
|
||||
#define TISCI_MSG_WAIT_PROC_BOOT_STATUS 0xc401
|
||||
|
||||
/* Resource Management Requests */
|
||||
#define TI_SCI_MSG_GET_RESOURCE_RANGE 0x1500
|
||||
@@ -772,6 +773,55 @@ struct ti_sci_msg_resp_get_proc_boot_status {
|
||||
u32 status_flags;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct ti_sci_msg_req_wait_proc_boot_status - Wait for a processor
|
||||
* boot status
|
||||
* @hdr: Generic Header
|
||||
* @processor_id: ID of processor
|
||||
* @num_wait_iterations: Total number of iterations we will check before
|
||||
* we will timeout and give up
|
||||
* @num_match_iterations: How many iterations should we have continued
|
||||
* status to account for status bits glitching.
|
||||
* This is to make sure that match occurs for
|
||||
* consecutive checks. This implies that the
|
||||
* worst case should consider that the stable
|
||||
* time should at the worst be num_wait_iterations
|
||||
* num_match_iterations to prevent timeout.
|
||||
* @delay_per_iteration_us: Specifies how long to wait (in micro seconds)
|
||||
* between each status checks. This is the minimum
|
||||
* duration, and overhead of register reads and
|
||||
* checks are on top of this and can vary based on
|
||||
* varied conditions.
|
||||
* @delay_before_iterations_us: Specifies how long to wait (in micro seconds)
|
||||
* before the very first check in the first
|
||||
* iteration of status check loop. This is the
|
||||
* minimum duration, and overhead of register
|
||||
* reads and checks are.
|
||||
* @status_flags_1_set_all_wait:If non-zero, Specifies that all bits of the
|
||||
* status matching this field requested MUST be 1.
|
||||
* @status_flags_1_set_any_wait:If non-zero, Specifies that at least one of the
|
||||
* bits matching this field requested MUST be 1.
|
||||
* @status_flags_1_clr_all_wait:If non-zero, Specifies that all bits of the
|
||||
* status matching this field requested MUST be 0.
|
||||
* @status_flags_1_clr_any_wait:If non-zero, Specifies that at least one of the
|
||||
* bits matching this field requested MUST be 0.
|
||||
*
|
||||
* Request type is TISCI_MSG_WAIT_PROC_BOOT_STATUS, response is appropriate
|
||||
* message, or NACK in case of inability to satisfy request.
|
||||
*/
|
||||
struct ti_sci_msg_req_wait_proc_boot_status {
|
||||
struct ti_sci_msg_hdr hdr;
|
||||
u8 processor_id;
|
||||
u8 num_wait_iterations;
|
||||
u8 num_match_iterations;
|
||||
u8 delay_per_iteration_us;
|
||||
u8 delay_before_iterations_us;
|
||||
u32 status_flags_1_set_all_wait;
|
||||
u32 status_flags_1_set_any_wait;
|
||||
u32 status_flags_1_clr_all_wait;
|
||||
u32 status_flags_1_clr_any_wait;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct ti_sci_msg_rm_ring_cfg_req - Configure a Navigator Subsystem ring
|
||||
*
|
||||
|
||||
@@ -72,6 +72,8 @@ struct am654_sdhci_plat {
|
||||
u32 otap_del_sel;
|
||||
u32 trm_icp;
|
||||
u32 drv_strength;
|
||||
u32 flags;
|
||||
#define DLL_PRESENT (1 << 0)
|
||||
bool dll_on;
|
||||
};
|
||||
|
||||
@@ -162,6 +164,10 @@ const struct sdhci_ops am654_sdhci_ops = {
|
||||
.set_control_reg = &am654_sdhci_set_control_reg,
|
||||
};
|
||||
|
||||
const struct sdhci_ops j721e_4bit_sdhci_ops = {
|
||||
.set_control_reg = &am654_sdhci_set_control_reg,
|
||||
};
|
||||
|
||||
int am654_sdhci_init(struct am654_sdhci_plat *plat)
|
||||
{
|
||||
u32 ctl_cfg_2 = 0;
|
||||
@@ -172,25 +178,29 @@ int am654_sdhci_init(struct am654_sdhci_plat *plat)
|
||||
mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
|
||||
regmap_update_bits(plat->base, PHY_CTRL4, mask, 0x0);
|
||||
|
||||
regmap_read(plat->base, PHY_STAT1, &val);
|
||||
if (~val & CALDONE_MASK) {
|
||||
/* Calibrate IO lines */
|
||||
regmap_update_bits(plat->base, PHY_CTRL1, PDB_MASK, PDB_MASK);
|
||||
ret = regmap_read_poll_timeout(plat->base, PHY_STAT1, val,
|
||||
val & CALDONE_MASK, 1, 20);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (plat->flags & DLL_PRESENT) {
|
||||
regmap_read(plat->base, PHY_STAT1, &val);
|
||||
if (~val & CALDONE_MASK) {
|
||||
/* Calibrate IO lines */
|
||||
regmap_update_bits(plat->base, PHY_CTRL1, PDB_MASK,
|
||||
PDB_MASK);
|
||||
ret = regmap_read_poll_timeout(plat->base, PHY_STAT1,
|
||||
val, val & CALDONE_MASK,
|
||||
1, 20);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Configure DLL TRIM */
|
||||
mask = DLL_TRIM_ICP_MASK;
|
||||
val = plat->trm_icp << DLL_TRIM_ICP_SHIFT;
|
||||
|
||||
/* Configure DLL driver strength */
|
||||
mask |= DR_TY_MASK;
|
||||
val |= plat->drv_strength << DR_TY_SHIFT;
|
||||
regmap_update_bits(plat->base, PHY_CTRL1, mask, val);
|
||||
}
|
||||
|
||||
/* Configure DLL TRIM */
|
||||
mask = DLL_TRIM_ICP_MASK;
|
||||
val = plat->trm_icp << DLL_TRIM_ICP_SHIFT;
|
||||
|
||||
/* Configure DLL driver strength */
|
||||
mask |= DR_TY_MASK;
|
||||
val |= plat->drv_strength << DR_TY_SHIFT;
|
||||
regmap_update_bits(plat->base, PHY_CTRL1, mask, val);
|
||||
|
||||
/* Enable pins by setting IO mux to 0 */
|
||||
regmap_update_bits(plat->base, PHY_CTRL1, IOMUX_ENABLE_MASK, 0);
|
||||
|
||||
@@ -245,7 +255,7 @@ static int am654_sdhci_probe(struct udevice *dev)
|
||||
AM654_SDHCI_MIN_FREQ);
|
||||
if (ret)
|
||||
return ret;
|
||||
host->ops = &am654_sdhci_ops;
|
||||
host->ops = (struct sdhci_ops *)dev_get_driver_data(dev);
|
||||
host->mmc->priv = host;
|
||||
upriv->mmc = host->mmc;
|
||||
|
||||
@@ -268,37 +278,44 @@ static int am654_sdhci_ofdata_to_platdata(struct udevice *dev)
|
||||
host->ioaddr = (void *)dev_read_addr(dev);
|
||||
plat->non_removable = dev_read_bool(dev, "non-removable");
|
||||
|
||||
ret = dev_read_u32(dev, "ti,trm-icp", &plat->trm_icp);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (device_is_compatible(dev, "ti,am654-sdhci-5.1") ||
|
||||
device_is_compatible(dev, "ti,j721e-sdhci-8bit"))
|
||||
plat->flags |= DLL_PRESENT;
|
||||
|
||||
ret = dev_read_u32(dev, "ti,otap-del-sel", &plat->otap_del_sel);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = dev_read_u32(dev, "ti,driver-strength-ohm", &drv_strength);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (plat->flags & DLL_PRESENT) {
|
||||
ret = dev_read_u32(dev, "ti,trm-icp", &plat->trm_icp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (drv_strength) {
|
||||
case 50:
|
||||
plat->drv_strength = DRIVER_STRENGTH_50_OHM;
|
||||
break;
|
||||
case 33:
|
||||
plat->drv_strength = DRIVER_STRENGTH_33_OHM;
|
||||
break;
|
||||
case 66:
|
||||
plat->drv_strength = DRIVER_STRENGTH_66_OHM;
|
||||
break;
|
||||
case 100:
|
||||
plat->drv_strength = DRIVER_STRENGTH_100_OHM;
|
||||
break;
|
||||
case 40:
|
||||
plat->drv_strength = DRIVER_STRENGTH_40_OHM;
|
||||
break;
|
||||
default:
|
||||
dev_err(dev, "Invalid driver strength\n");
|
||||
return -EINVAL;
|
||||
ret = dev_read_u32(dev, "ti,driver-strength-ohm",
|
||||
&drv_strength);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (drv_strength) {
|
||||
case 50:
|
||||
plat->drv_strength = DRIVER_STRENGTH_50_OHM;
|
||||
break;
|
||||
case 33:
|
||||
plat->drv_strength = DRIVER_STRENGTH_33_OHM;
|
||||
break;
|
||||
case 66:
|
||||
plat->drv_strength = DRIVER_STRENGTH_66_OHM;
|
||||
break;
|
||||
case 100:
|
||||
plat->drv_strength = DRIVER_STRENGTH_100_OHM;
|
||||
break;
|
||||
case 40:
|
||||
plat->drv_strength = DRIVER_STRENGTH_40_OHM;
|
||||
break;
|
||||
default:
|
||||
dev_err(dev, "Invalid driver strength\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
ret = mmc_of_parse(dev, cfg);
|
||||
@@ -316,7 +333,18 @@ static int am654_sdhci_bind(struct udevice *dev)
|
||||
}
|
||||
|
||||
static const struct udevice_id am654_sdhci_ids[] = {
|
||||
{ .compatible = "ti,am654-sdhci-5.1" },
|
||||
{
|
||||
.compatible = "ti,am654-sdhci-5.1",
|
||||
.data = (ulong)&am654_sdhci_ops,
|
||||
},
|
||||
{
|
||||
.compatible = "ti,j721e-sdhci-8bit",
|
||||
.data = (ulong)&am654_sdhci_ops,
|
||||
},
|
||||
{
|
||||
.compatible = "ti,j721e-sdhci-4bit",
|
||||
.data = (ulong)&j721e_4bit_sdhci_ops,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <errno.h>
|
||||
#include <power-domain-uclass.h>
|
||||
#include <linux/soc/ti/ti_sci_protocol.h>
|
||||
#include <dt-bindings/soc/ti,sci_pm_domain.h>
|
||||
|
||||
/**
|
||||
* struct ti_sci_power_domain_data - pm domain controller information structure
|
||||
@@ -56,11 +57,16 @@ static int ti_sci_power_domain_on(struct power_domain *pd)
|
||||
struct ti_sci_power_domain_data *data = dev_get_priv(pd->dev);
|
||||
const struct ti_sci_handle *sci = data->sci;
|
||||
const struct ti_sci_dev_ops *dops = &sci->ops.dev_ops;
|
||||
u8 flags = (uintptr_t)pd->priv;
|
||||
int ret;
|
||||
|
||||
debug("%s(pd=%p)\n", __func__, pd);
|
||||
|
||||
ret = dops->get_device(sci, pd->id);
|
||||
if (flags & TI_SCI_PD_EXCLUSIVE)
|
||||
ret = dops->get_device_exclusive(sci, pd->id);
|
||||
else
|
||||
ret = dops->get_device(sci, pd->id);
|
||||
|
||||
if (ret)
|
||||
dev_err(power_domain->dev, "%s: get_device failed (%d)\n",
|
||||
__func__, ret);
|
||||
@@ -85,6 +91,28 @@ static int ti_sci_power_domain_off(struct power_domain *pd)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ti_sci_power_domain_of_xlate(struct power_domain *pd,
|
||||
struct ofnode_phandle_args *args)
|
||||
{
|
||||
u8 flags;
|
||||
|
||||
debug("%s(power_domain=%p)\n", __func__, pd);
|
||||
|
||||
if (args->args_count < 1) {
|
||||
debug("Invalid args_count: %d\n", args->args_count);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pd->id = args->args[0];
|
||||
/* By default request for device exclusive */
|
||||
flags = TI_SCI_PD_EXCLUSIVE;
|
||||
if (args->args_count == 2)
|
||||
flags = args->args[1] & TI_SCI_PD_EXCLUSIVE;
|
||||
pd->priv = (void *)(uintptr_t)flags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id ti_sci_power_domain_of_match[] = {
|
||||
{ .compatible = "ti,sci-pm-domain" },
|
||||
{ /* sentinel */ }
|
||||
@@ -95,6 +123,7 @@ static struct power_domain_ops ti_sci_power_domain_ops = {
|
||||
.free = ti_sci_power_domain_free,
|
||||
.on = ti_sci_power_domain_on,
|
||||
.off = ti_sci_power_domain_off,
|
||||
.of_xlate = ti_sci_power_domain_of_xlate,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(ti_sci_pm_domains) = {
|
||||
|
||||
@@ -22,15 +22,6 @@ config K3_SYSTEM_CONTROLLER
|
||||
help
|
||||
Say 'y' here to add support for TI' K3 System Controller.
|
||||
|
||||
config REMOTEPROC_K3
|
||||
bool "Support for TI's K3 based remoteproc driver"
|
||||
select REMOTEPROC
|
||||
depends on DM
|
||||
depends on ARCH_K3
|
||||
depends on OF_CONTROL
|
||||
help
|
||||
Say 'y' here to add support for TI' K3 remoteproc driver.
|
||||
|
||||
config REMOTEPROC_SANDBOX
|
||||
bool "Support for Test processor for Sandbox"
|
||||
select REMOTEPROC
|
||||
@@ -50,6 +41,17 @@ config REMOTEPROC_STM32_COPRO
|
||||
Say 'y' here to add support for STM32 Cortex-M4 coprocessors via the
|
||||
remoteproc framework.
|
||||
|
||||
config REMOTEPROC_TI_K3_ARM64
|
||||
bool "Support for TI's K3 based ARM64 remoteproc driver"
|
||||
select REMOTEPROC
|
||||
depends on DM
|
||||
depends on ARCH_K3
|
||||
depends on OF_CONTROL
|
||||
help
|
||||
Say y here to support TI's ARM64 processor subsystems
|
||||
on various TI K3 family of SoCs through the remote processor
|
||||
framework.
|
||||
|
||||
config REMOTEPROC_TI_POWER
|
||||
bool "Support for TI Power processor"
|
||||
select REMOTEPROC
|
||||
|
||||
@@ -8,7 +8,7 @@ obj-$(CONFIG_$(SPL_)REMOTEPROC) += rproc-uclass.o rproc-elf-loader.o
|
||||
|
||||
# Remote proc drivers - Please keep this list alphabetically sorted.
|
||||
obj-$(CONFIG_K3_SYSTEM_CONTROLLER) += k3_system_controller.o
|
||||
obj-$(CONFIG_REMOTEPROC_K3) += k3_rproc.o
|
||||
obj-$(CONFIG_REMOTEPROC_SANDBOX) += sandbox_testproc.o
|
||||
obj-$(CONFIG_REMOTEPROC_STM32_COPRO) += stm32_copro.o
|
||||
obj-$(CONFIG_REMOTEPROC_TI_K3_ARM64) += ti_k3_arm64_rproc.o
|
||||
obj-$(CONFIG_REMOTEPROC_TI_POWER) += ti_power_proc.o
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Texas Instruments' K3 Remoteproc driver
|
||||
* Texas Instruments' K3 ARM64 Remoteproc driver
|
||||
*
|
||||
* Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* Lokesh Vutla <lokeshvutla@ti.com>
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <asm/io.h>
|
||||
#include <power-domain.h>
|
||||
#include <linux/soc/ti/ti_sci_protocol.h>
|
||||
#include "ti_sci_proc.h"
|
||||
|
||||
#define INVALID_ID 0xffff
|
||||
|
||||
@@ -23,68 +24,53 @@
|
||||
#define GTC_CNTR_EN 0x3
|
||||
|
||||
/**
|
||||
* struct k3_rproc_privdata - Structure representing Remote processor data.
|
||||
* struct k3_arm64_privdata - Structure representing Remote processor data.
|
||||
* @rproc_pwrdmn: rproc power domain data
|
||||
* @rproc_rst: rproc reset control data
|
||||
* @sci: Pointer to TISCI handle
|
||||
* @tsp: TISCI processor control helper structure
|
||||
* @gtc_base: Timer base address.
|
||||
* @proc_id: TISCI processor ID
|
||||
* @host_id: TISCI host id to which the processor gets assigned to.
|
||||
*/
|
||||
struct k3_rproc_privdata {
|
||||
struct k3_arm64_privdata {
|
||||
struct power_domain rproc_pwrdmn;
|
||||
struct power_domain gtc_pwrdmn;
|
||||
struct reset_ctl rproc_rst;
|
||||
const struct ti_sci_handle *sci;
|
||||
struct ti_sci_proc tsp;
|
||||
void *gtc_base;
|
||||
u16 proc_id;
|
||||
u16 host_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* k3_rproc_load() - Load up the Remote processor image
|
||||
* k3_arm64_load() - Load up the Remote processor image
|
||||
* @dev: rproc device pointer
|
||||
* @addr: Address at which image is available
|
||||
* @size: size of the image
|
||||
*
|
||||
* Return: 0 if all goes good, else appropriate error message.
|
||||
*/
|
||||
static int k3_rproc_load(struct udevice *dev, ulong addr, ulong size)
|
||||
static int k3_arm64_load(struct udevice *dev, ulong addr, ulong size)
|
||||
{
|
||||
struct k3_rproc_privdata *rproc = dev_get_priv(dev);
|
||||
const struct ti_sci_proc_ops *pops = &rproc->sci->ops.proc_ops;
|
||||
struct k3_arm64_privdata *rproc = dev_get_priv(dev);
|
||||
int ret;
|
||||
|
||||
dev_dbg(dev, "%s addr = 0x%lx, size = 0x%lx\n", __func__, addr, size);
|
||||
|
||||
/* request for the processor */
|
||||
ret = pops->proc_request(rproc->sci, rproc->proc_id);
|
||||
if (ret) {
|
||||
dev_err(dev, "Requesting processor failed %d\n", ret);
|
||||
ret = ti_sci_proc_request(&rproc->tsp);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = pops->set_proc_boot_cfg(rproc->sci, rproc->proc_id, addr, 0, 0);
|
||||
if (ret) {
|
||||
dev_err(dev, "set_proc_boot_cfg failed %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "%s: rproc successfully loaded\n", __func__);
|
||||
|
||||
return 0;
|
||||
return ti_sci_proc_set_config(&rproc->tsp, addr, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* k3_rproc_start() - Start the remote processor
|
||||
* k3_arm64_start() - Start the remote processor
|
||||
* @dev: rproc device pointer
|
||||
*
|
||||
* Return: 0 if all went ok, else return appropriate error
|
||||
*/
|
||||
static int k3_rproc_start(struct udevice *dev)
|
||||
static int k3_arm64_start(struct udevice *dev)
|
||||
{
|
||||
struct k3_rproc_privdata *rproc = dev_get_priv(dev);
|
||||
const struct ti_sci_proc_ops *pops = &rproc->sci->ops.proc_ops;
|
||||
struct k3_arm64_privdata *rproc = dev_get_priv(dev);
|
||||
int ret;
|
||||
|
||||
dev_dbg(dev, "%s\n", __func__);
|
||||
@@ -109,33 +95,16 @@ static int k3_rproc_start(struct udevice *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (rproc->host_id != INVALID_ID) {
|
||||
ret = pops->proc_handover(rproc->sci, rproc->proc_id,
|
||||
rproc->host_id);
|
||||
if (ret) {
|
||||
dev_err(dev, "Handover processor failed %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
ret = pops->proc_release(rproc->sci, rproc->proc_id);
|
||||
if (ret) {
|
||||
dev_err(dev, "Processor release failed %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
dev_dbg(dev, "%s: rproc successfully started\n", __func__);
|
||||
|
||||
return 0;
|
||||
return ti_sci_proc_release(&rproc->tsp);
|
||||
}
|
||||
|
||||
/**
|
||||
* k3_rproc_init() - Initialize the remote processor
|
||||
* k3_arm64_init() - Initialize the remote processor
|
||||
* @dev: rproc device pointer
|
||||
*
|
||||
* Return: 0 if all went ok, else return appropriate error
|
||||
*/
|
||||
static int k3_rproc_init(struct udevice *dev)
|
||||
static int k3_arm64_init(struct udevice *dev)
|
||||
{
|
||||
dev_dbg(dev, "%s\n", __func__);
|
||||
|
||||
@@ -145,12 +114,33 @@ static int k3_rproc_init(struct udevice *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dm_rproc_ops k3_rproc_ops = {
|
||||
.init = k3_rproc_init,
|
||||
.load = k3_rproc_load,
|
||||
.start = k3_rproc_start,
|
||||
static const struct dm_rproc_ops k3_arm64_ops = {
|
||||
.init = k3_arm64_init,
|
||||
.load = k3_arm64_load,
|
||||
.start = k3_arm64_start,
|
||||
};
|
||||
|
||||
static int ti_sci_proc_of_to_priv(struct udevice *dev, struct ti_sci_proc *tsp)
|
||||
{
|
||||
dev_dbg(dev, "%s\n", __func__);
|
||||
|
||||
tsp->sci = ti_sci_get_by_phandle(dev, "ti,sci");
|
||||
if (IS_ERR(tsp->sci)) {
|
||||
dev_err(dev, "ti_sci get failed: %ld\n", PTR_ERR(tsp->sci));
|
||||
return PTR_ERR(tsp->sci);
|
||||
}
|
||||
|
||||
tsp->proc_id = dev_read_u32_default(dev, "ti,sci-proc-id", INVALID_ID);
|
||||
if (tsp->proc_id == INVALID_ID) {
|
||||
dev_err(dev, "proc id not populated\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
tsp->host_id = dev_read_u32_default(dev, "ti,sci-host-id", INVALID_ID);
|
||||
tsp->ops = &tsp->sci->ops.proc_ops;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* k3_of_to_priv() - generate private data from device tree
|
||||
* @dev: corresponding k3 remote processor device
|
||||
@@ -158,8 +148,8 @@ static const struct dm_rproc_ops k3_rproc_ops = {
|
||||
*
|
||||
* Return: 0 if all goes good, else appropriate error message.
|
||||
*/
|
||||
static int k3_rproc_of_to_priv(struct udevice *dev,
|
||||
struct k3_rproc_privdata *rproc)
|
||||
static int k3_arm64_of_to_priv(struct udevice *dev,
|
||||
struct k3_arm64_privdata *rproc)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -183,11 +173,9 @@ static int k3_rproc_of_to_priv(struct udevice *dev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
rproc->sci = ti_sci_get_by_phandle(dev, "ti,sci");
|
||||
if (IS_ERR(rproc->sci)) {
|
||||
dev_err(dev, "ti_sci get failed: %d\n", ret);
|
||||
return PTR_ERR(rproc->sci);
|
||||
}
|
||||
ret = ti_sci_proc_of_to_priv(dev, &rproc->tsp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
rproc->gtc_base = dev_read_addr_ptr(dev);
|
||||
if (!rproc->gtc_base) {
|
||||
@@ -195,30 +183,25 @@ static int k3_rproc_of_to_priv(struct udevice *dev,
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
rproc->proc_id = dev_read_u32_default(dev, "ti,sci-proc-id",
|
||||
INVALID_ID);
|
||||
rproc->host_id = dev_read_u32_default(dev, "ti,sci-host-id",
|
||||
INVALID_ID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* k3_rproc_probe() - Basic probe
|
||||
* k3_arm64_probe() - Basic probe
|
||||
* @dev: corresponding k3 remote processor device
|
||||
*
|
||||
* Return: 0 if all goes good, else appropriate error message.
|
||||
*/
|
||||
static int k3_rproc_probe(struct udevice *dev)
|
||||
static int k3_arm64_probe(struct udevice *dev)
|
||||
{
|
||||
struct k3_rproc_privdata *priv;
|
||||
struct k3_arm64_privdata *priv;
|
||||
int ret;
|
||||
|
||||
dev_dbg(dev, "%s\n", __func__);
|
||||
|
||||
priv = dev_get_priv(dev);
|
||||
|
||||
ret = k3_rproc_of_to_priv(dev, priv);
|
||||
ret = k3_arm64_of_to_priv(dev, priv);
|
||||
if (ret) {
|
||||
dev_dbg(dev, "%s: Probe failed with error %d\n", __func__, ret);
|
||||
return ret;
|
||||
@@ -229,16 +212,17 @@ static int k3_rproc_probe(struct udevice *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id k3_rproc_ids[] = {
|
||||
static const struct udevice_id k3_arm64_ids[] = {
|
||||
{ .compatible = "ti,am654-arm64"},
|
||||
{ .compatible = "ti,am654-rproc"},
|
||||
{}
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(k3_rproc) = {
|
||||
.name = "k3_rproc",
|
||||
.of_match = k3_rproc_ids,
|
||||
U_BOOT_DRIVER(k3_arm64) = {
|
||||
.name = "k3_arm64",
|
||||
.of_match = k3_arm64_ids,
|
||||
.id = UCLASS_REMOTEPROC,
|
||||
.ops = &k3_rproc_ops,
|
||||
.probe = k3_rproc_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct k3_rproc_privdata),
|
||||
.ops = &k3_arm64_ops,
|
||||
.probe = k3_arm64_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct k3_arm64_privdata),
|
||||
};
|
||||
121
drivers/remoteproc/ti_sci_proc.h
Normal file
121
drivers/remoteproc/ti_sci_proc.h
Normal file
@@ -0,0 +1,121 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Texas Instruments TI-SCI Processor Controller Helper Functions
|
||||
*
|
||||
* Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* Lokesh Vutla <lokeshvutla@ti.com>
|
||||
* Suman Anna <s-anna@ti.com>
|
||||
*/
|
||||
|
||||
#ifndef REMOTEPROC_TI_SCI_PROC_H
|
||||
#define REMOTEPROC_TI_SCI_PROC_H
|
||||
|
||||
#define TISCI_INVALID_HOST 0xff
|
||||
|
||||
/**
|
||||
* struct ti_sci_proc - structure representing a processor control client
|
||||
* @sci: cached TI-SCI protocol handle
|
||||
* @ops: cached TI-SCI proc ops
|
||||
* @proc_id: processor id for the consumer remoteproc device
|
||||
* @host_id: host id to pass the control over for this consumer remoteproc
|
||||
* device
|
||||
*/
|
||||
struct ti_sci_proc {
|
||||
const struct ti_sci_handle *sci;
|
||||
const struct ti_sci_proc_ops *ops;
|
||||
u8 proc_id;
|
||||
u8 host_id;
|
||||
};
|
||||
|
||||
static inline int ti_sci_proc_request(struct ti_sci_proc *tsp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
debug("%s: proc_id = %d\n", __func__, tsp->proc_id);
|
||||
|
||||
ret = tsp->ops->proc_request(tsp->sci, tsp->proc_id);
|
||||
if (ret)
|
||||
pr_err("ti-sci processor request failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int ti_sci_proc_release(struct ti_sci_proc *tsp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
debug("%s: proc_id = %d\n", __func__, tsp->proc_id);
|
||||
|
||||
if (tsp->host_id != TISCI_INVALID_HOST)
|
||||
ret = tsp->ops->proc_handover(tsp->sci, tsp->proc_id,
|
||||
tsp->host_id);
|
||||
else
|
||||
ret = tsp->ops->proc_release(tsp->sci, tsp->proc_id);
|
||||
|
||||
if (ret)
|
||||
pr_err("ti-sci processor release failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int ti_sci_proc_handover(struct ti_sci_proc *tsp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
debug("%s: proc_id = %d\n", __func__, tsp->proc_id);
|
||||
|
||||
ret = tsp->ops->proc_handover(tsp->sci, tsp->proc_id, tsp->host_id);
|
||||
if (ret)
|
||||
pr_err("ti-sci processor handover of %d to %d failed: %d\n",
|
||||
tsp->proc_id, tsp->host_id, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int ti_sci_proc_get_status(struct ti_sci_proc *tsp,
|
||||
u64 *boot_vector, u32 *cfg_flags,
|
||||
u32 *ctrl_flags, u32 *status_flags)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = tsp->ops->get_proc_boot_status(tsp->sci, tsp->proc_id,
|
||||
boot_vector, cfg_flags, ctrl_flags,
|
||||
status_flags);
|
||||
if (ret)
|
||||
pr_err("ti-sci processor get_status failed: %d\n", ret);
|
||||
|
||||
debug("%s: proc_id = %d, boot_vector = 0x%llx, cfg_flags = 0x%x, ctrl_flags = 0x%x, sts = 0x%x\n",
|
||||
__func__, tsp->proc_id, *boot_vector, *cfg_flags, *ctrl_flags,
|
||||
*status_flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int ti_sci_proc_set_config(struct ti_sci_proc *tsp,
|
||||
u64 boot_vector,
|
||||
u32 cfg_set, u32 cfg_clr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
debug("%s: proc_id = %d, boot_vector = 0x%llx, cfg_set = 0x%x, cfg_clr = 0x%x\n",
|
||||
__func__, tsp->proc_id, boot_vector, cfg_set, cfg_clr);
|
||||
|
||||
ret = tsp->ops->set_proc_boot_cfg(tsp->sci, tsp->proc_id, boot_vector,
|
||||
cfg_set, cfg_clr);
|
||||
if (ret)
|
||||
pr_err("ti-sci processor set_config failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int ti_sci_proc_set_control(struct ti_sci_proc *tsp,
|
||||
u32 ctrl_set, u32 ctrl_clr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
debug("%s: proc_id = %d, ctrl_set = 0x%x, ctrl_clr = 0x%x\n", __func__,
|
||||
tsp->proc_id, ctrl_set, ctrl_clr);
|
||||
|
||||
ret = tsp->ops->set_proc_boot_ctrl(tsp->sci, tsp->proc_id, ctrl_set,
|
||||
ctrl_clr);
|
||||
if (ret)
|
||||
pr_err("ti-sci processor set_control failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* REMOTEPROC_TI_SCI_PROC_H */
|
||||
Reference in New Issue
Block a user