static int scmi_power_attributes_get(const struct scmi_handle *handle, struct scmi_power_info *pi) { int ret; struct scmi_xfer *t; struct scmi_msg_resp_power_attributes *attr; ret = scmi_xfer_get_init(handle, PROTOCOL_ATTRIBUTES, SCMI_PROTOCOL_POWER, 0, sizeof(*attr), &t); if (ret) return ret; attr = t->rx.buf; ret = scmi_do_xfer(handle, t); if (!ret) { pi->num_domains = le16_to_cpu(attr->num_domains); pi->stats_addr = le32_to_cpu(attr->stats_addr_low) | (u64)le32_to_cpu(attr->stats_addr_high) << 32; pi->stats_size = le32_to_cpu(attr->stats_size); } scmi_xfer_put(handle, t); return ret; }
static int scmi_power_domain_attributes_get(const struct scmi_handle *handle, u32 domain, struct power_dom_info *dom_info) { int ret; struct scmi_xfer *t; struct scmi_msg_resp_power_domain_attributes *attr; ret = scmi_xfer_get_init(handle, POWER_DOMAIN_ATTRIBUTES, SCMI_PROTOCOL_POWER, sizeof(domain), sizeof(*attr), &t); if (ret) return ret; *(__le32 *)t->tx.buf = cpu_to_le32(domain); attr = t->rx.buf; ret = scmi_do_xfer(handle, t); if (!ret) { u32 flags = le32_to_cpu(attr->flags); dom_info->state_set_notify = SUPPORTS_STATE_SET_NOTIFY(flags); dom_info->state_set_async = SUPPORTS_STATE_SET_ASYNC(flags); dom_info->state_set_sync = SUPPORTS_STATE_SET_SYNC(flags); memcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE); } scmi_xfer_put(handle, t); return ret; }
static int scmi_sensor_reading_get(const struct scmi_handle *handle, u32 sensor_id, bool async, u64 *value) { int ret; struct scmi_xfer *t; struct scmi_msg_sensor_reading_get *sensor; ret = scmi_xfer_get_init(handle, SENSOR_READING_GET, SCMI_PROTOCOL_SENSOR, sizeof(*sensor), sizeof(u64), &t); if (ret) return ret; sensor = t->tx.buf; sensor->id = cpu_to_le32(sensor_id); sensor->flags = cpu_to_le32(async ? SENSOR_READ_ASYNC : 0); ret = scmi_do_xfer(handle, t); if (!ret) { __le32 *pval = t->rx.buf; *value = le32_to_cpu(*pval); *value |= (u64)le32_to_cpu(*(pval + 1)) << 32; } scmi_xfer_put(handle, t); return ret; }
static int scmi_sensor_attributes_get(const struct scmi_handle *handle, struct sensors_info *si) { int ret; struct scmi_xfer *t; struct scmi_msg_resp_sensor_attributes *attr; ret = scmi_xfer_get_init(handle, PROTOCOL_ATTRIBUTES, SCMI_PROTOCOL_SENSOR, 0, sizeof(*attr), &t); if (ret) return ret; attr = t->rx.buf; ret = scmi_do_xfer(handle, t); if (!ret) { si->num_sensors = le16_to_cpu(attr->num_sensors); si->max_requests = attr->max_requests; si->reg_addr = le32_to_cpu(attr->reg_addr_low) | (u64)le32_to_cpu(attr->reg_addr_high) << 32; si->reg_size = le32_to_cpu(attr->reg_size); } scmi_xfer_put(handle, t); return ret; }
static int scmi_sensor_description_get(const struct scmi_handle *handle, struct sensors_info *si) { int ret, cnt; u32 desc_index = 0; u16 num_returned, num_remaining; struct scmi_xfer *t; struct scmi_msg_resp_sensor_description *buf; ret = scmi_xfer_get_init(handle, SENSOR_DESCRIPTION_GET, SCMI_PROTOCOL_SENSOR, sizeof(__le32), 0, &t); if (ret) return ret; buf = t->rx.buf; do { /* Set the number of sensors to be skipped/already read */ *(__le32 *)t->tx.buf = cpu_to_le32(desc_index); ret = scmi_do_xfer(handle, t); if (ret) break; num_returned = le16_to_cpu(buf->num_returned); num_remaining = le16_to_cpu(buf->num_remaining); if (desc_index + num_returned > si->num_sensors) { dev_err(handle->dev, "No. of sensors can't exceed %d", si->num_sensors); break; } for (cnt = 0; cnt < num_returned; cnt++) { u32 attrh; struct scmi_sensor_info *s; attrh = le32_to_cpu(buf->desc[cnt].attributes_high); s = &si->sensors[desc_index + cnt]; s->id = le32_to_cpu(buf->desc[cnt].id); s->type = SENSOR_TYPE(attrh); strlcpy(s->name, buf->desc[cnt].name, SCMI_MAX_STR_SIZE); } desc_index += num_returned; /* * check for both returned and remaining to avoid infinite * loop due to buggy firmware */ } while (num_returned && num_remaining); scmi_xfer_put(handle, t); return ret; }
static int scmi_power_state_get(const struct scmi_handle *handle, u32 domain, u32 *state) { int ret; struct scmi_xfer *t; ret = scmi_xfer_get_init(handle, POWER_STATE_GET, SCMI_PROTOCOL_POWER, sizeof(u32), sizeof(u32), &t); if (ret) return ret; *(__le32 *)t->tx.buf = cpu_to_le32(domain); ret = scmi_do_xfer(handle, t); if (!ret) *state = le32_to_cpu(*(__le32 *)t->rx.buf); scmi_xfer_put(handle, t); return ret; }
static int scmi_clock_config_set(const struct scmi_handle *handle, u32 clk_id, u32 config) { int ret; struct scmi_xfer *t; struct scmi_clock_set_config *cfg; ret = scmi_xfer_get_init(handle, CLOCK_CONFIG_SET, SCMI_PROTOCOL_CLOCK, sizeof(*cfg), 0, &t); if (ret) return ret; cfg = t->tx.buf; cfg->id = cpu_to_le32(clk_id); cfg->attributes = cpu_to_le32(config); ret = scmi_do_xfer(handle, t); scmi_xfer_put(handle, t); return ret; }
static int scmi_power_state_set(const struct scmi_handle *handle, u32 domain, u32 state) { int ret; struct scmi_xfer *t; struct scmi_power_set_state *st; ret = scmi_xfer_get_init(handle, POWER_STATE_SET, SCMI_PROTOCOL_POWER, sizeof(*st), 0, &t); if (ret) return ret; st = t->tx.buf; st->flags = cpu_to_le32(0); st->domain = cpu_to_le32(domain); st->state = cpu_to_le32(state); ret = scmi_do_xfer(handle, t); scmi_xfer_put(handle, t); return ret; }
static int scmi_sensor_configuration_set(const struct scmi_handle *handle, u32 sensor_id) { int ret; u32 evt_cntl = BIT(0); struct scmi_xfer *t; struct scmi_msg_set_sensor_config *cfg; ret = scmi_xfer_get_init(handle, SENSOR_CONFIG_SET, SCMI_PROTOCOL_SENSOR, sizeof(*cfg), 0, &t); if (ret) return ret; cfg = t->tx.buf; cfg->id = cpu_to_le32(sensor_id); cfg->event_control = cpu_to_le32(evt_cntl); ret = scmi_do_xfer(handle, t); scmi_xfer_put(handle, t); return ret; }
static int scmi_clock_protocol_attributes_get(const struct scmi_handle *handle, struct clock_info *ci) { int ret; struct scmi_xfer *t; struct scmi_msg_resp_clock_protocol_attributes *attr; ret = scmi_xfer_get_init(handle, PROTOCOL_ATTRIBUTES, SCMI_PROTOCOL_CLOCK, 0, sizeof(*attr), &t); if (ret) return ret; attr = t->rx.buf; ret = scmi_do_xfer(handle, t); if (!ret) { ci->num_clocks = le16_to_cpu(attr->num_clocks); ci->max_async_req = attr->max_async_req; } scmi_xfer_put(handle, t); return ret; }
static int scmi_clock_rate_set(const struct scmi_handle *handle, u32 clk_id, u32 config, u64 rate) { int ret; struct scmi_xfer *t; struct scmi_clock_set_rate *cfg; ret = scmi_xfer_get_init(handle, CLOCK_RATE_SET, SCMI_PROTOCOL_CLOCK, sizeof(*cfg), 0, &t); if (ret) return ret; cfg = t->tx.buf; cfg->flags = cpu_to_le32(config); cfg->id = cpu_to_le32(clk_id); cfg->value_low = cpu_to_le32(rate & 0xffffffff); cfg->value_high = cpu_to_le32(rate >> 32); ret = scmi_do_xfer(handle, t); scmi_xfer_put(handle, t); return ret; }
static int scmi_sensor_trip_point_set(const struct scmi_handle *handle, u32 sensor_id, u8 trip_id, u64 trip_value) { int ret; u32 evt_cntl = SENSOR_TP_BOTH; struct scmi_xfer *t; struct scmi_msg_set_sensor_trip_point *trip; ret = scmi_xfer_get_init(handle, SENSOR_TRIP_POINT_SET, SCMI_PROTOCOL_SENSOR, sizeof(*trip), 0, &t); if (ret) return ret; trip = t->tx.buf; trip->id = cpu_to_le32(sensor_id); trip->event_control = cpu_to_le32(evt_cntl | SENSOR_TP_ID(trip_id)); trip->value_low = cpu_to_le32(trip_value & 0xffffffff); trip->value_high = cpu_to_le32(trip_value >> 32); ret = scmi_do_xfer(handle, t); scmi_xfer_put(handle, t); return ret; }
static int scmi_clock_attributes_get(const struct scmi_handle *handle, u32 clk_id, struct scmi_clock_info *clk) { int ret; struct scmi_xfer *t; struct scmi_msg_resp_clock_attributes *attr; ret = scmi_xfer_get_init(handle, CLOCK_ATTRIBUTES, SCMI_PROTOCOL_CLOCK, sizeof(clk_id), sizeof(*attr), &t); if (ret) return ret; *(__le32 *)t->tx.buf = cpu_to_le32(clk_id); attr = t->rx.buf; ret = scmi_do_xfer(handle, t); if (!ret) memcpy(clk->name, attr->name, SCMI_MAX_STR_SIZE); else clk->name[0] = '\0'; scmi_xfer_put(handle, t); return ret; }
static int scmi_clock_rate_get(const struct scmi_handle *handle, u32 clk_id, u64 *value) { int ret; struct scmi_xfer *t; ret = scmi_xfer_get_init(handle, CLOCK_RATE_GET, SCMI_PROTOCOL_CLOCK, sizeof(__le32), sizeof(u64), &t); if (ret) return ret; *(__le32 *)t->tx.buf = cpu_to_le32(clk_id); ret = scmi_do_xfer(handle, t); if (!ret) { __le32 *pval = t->rx.buf; *value = le32_to_cpu(*pval); *value |= (u64)le32_to_cpu(*(pval + 1)) << 32; } scmi_xfer_put(handle, t); return ret; }
static int scmi_clock_describe_rates_get(const struct scmi_handle *handle, u32 clk_id, struct scmi_clock_info *clk) { u64 *rate; int ret, cnt; bool rate_discrete = false; u32 tot_rate_cnt = 0, rates_flag; u16 num_returned, num_remaining; struct scmi_xfer *t; struct scmi_msg_clock_describe_rates *clk_desc; struct scmi_msg_resp_clock_describe_rates *rlist; ret = scmi_xfer_get_init(handle, CLOCK_DESCRIBE_RATES, SCMI_PROTOCOL_CLOCK, sizeof(*clk_desc), 0, &t); if (ret) return ret; clk_desc = t->tx.buf; rlist = t->rx.buf; do { clk_desc->id = cpu_to_le32(clk_id); /* Set the number of rates to be skipped/already read */ clk_desc->rate_index = cpu_to_le32(tot_rate_cnt); ret = scmi_do_xfer(handle, t); if (ret) goto err; rates_flag = le32_to_cpu(rlist->num_rates_flags); num_remaining = NUM_REMAINING(rates_flag); rate_discrete = RATE_DISCRETE(rates_flag); num_returned = NUM_RETURNED(rates_flag); if (tot_rate_cnt + num_returned > SCMI_MAX_NUM_RATES) { dev_err(handle->dev, "No. of rates > MAX_NUM_RATES"); break; } if (!rate_discrete) { clk->range.min_rate = RATE_TO_U64(rlist->rate[0]); clk->range.max_rate = RATE_TO_U64(rlist->rate[1]); clk->range.step_size = RATE_TO_U64(rlist->rate[2]); dev_dbg(handle->dev, "Min %llu Max %llu Step %llu Hz\n", clk->range.min_rate, clk->range.max_rate, clk->range.step_size); break; } rate = &clk->list.rates[tot_rate_cnt]; for (cnt = 0; cnt < num_returned; cnt++, rate++) { *rate = RATE_TO_U64(rlist->rate[cnt]); dev_dbg(handle->dev, "Rate %llu Hz\n", *rate); } tot_rate_cnt += num_returned; /* * check for both returned and remaining to avoid infinite * loop due to buggy firmware */ } while (num_returned && num_remaining); if (rate_discrete) clk->list.num_rates = tot_rate_cnt; err: scmi_xfer_put(handle, t); return ret; }