mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-02 15:18:19 +00:00
soc: qcom: rpmh-rsc: Add support for RSC v3 register offsets
The SM8550 RSC has a new set of register offsets due to its version bump. So read the version from HW and use the proper register offsets based on that. Signed-off-by: Abel Vesa <abel.vesa@linaro.org> Signed-off-by: Bjorn Andersson <andersson@kernel.org> Link: https://lore.kernel.org/r/20221116112246.2640648-1-abel.vesa@linaro.org
This commit is contained in:
parent
d1d9d62bd4
commit
40482e4f73
2 changed files with 110 additions and 58 deletions
|
@ -86,6 +86,11 @@ struct rpmh_ctrlr {
|
||||||
struct list_head batch_cache;
|
struct list_head batch_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct rsc_ver {
|
||||||
|
u32 major;
|
||||||
|
u32 minor;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct rsc_drv: the Direct Resource Voter (DRV) of the
|
* struct rsc_drv: the Direct Resource Voter (DRV) of the
|
||||||
* Resource State Coordinator controller (RSC)
|
* Resource State Coordinator controller (RSC)
|
||||||
|
@ -129,6 +134,8 @@ struct rsc_drv {
|
||||||
wait_queue_head_t tcs_wait;
|
wait_queue_head_t tcs_wait;
|
||||||
struct rpmh_ctrlr client;
|
struct rpmh_ctrlr client;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
|
struct rsc_ver ver;
|
||||||
|
u32 *regs;
|
||||||
};
|
};
|
||||||
|
|
||||||
int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg);
|
int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg);
|
||||||
|
|
|
@ -36,16 +36,38 @@
|
||||||
#define CREATE_TRACE_POINTS
|
#define CREATE_TRACE_POINTS
|
||||||
#include "trace-rpmh.h"
|
#include "trace-rpmh.h"
|
||||||
|
|
||||||
#define RSC_DRV_TCS_OFFSET 672
|
|
||||||
#define RSC_DRV_CMD_OFFSET 20
|
#define RSC_DRV_ID 0
|
||||||
|
|
||||||
|
#define MAJOR_VER_MASK 0xFF
|
||||||
|
#define MAJOR_VER_SHIFT 16
|
||||||
|
#define MINOR_VER_MASK 0xFF
|
||||||
|
#define MINOR_VER_SHIFT 8
|
||||||
|
|
||||||
|
enum {
|
||||||
|
RSC_DRV_TCS_OFFSET,
|
||||||
|
RSC_DRV_CMD_OFFSET,
|
||||||
|
DRV_SOLVER_CONFIG,
|
||||||
|
DRV_PRNT_CHLD_CONFIG,
|
||||||
|
RSC_DRV_IRQ_ENABLE,
|
||||||
|
RSC_DRV_IRQ_STATUS,
|
||||||
|
RSC_DRV_IRQ_CLEAR,
|
||||||
|
RSC_DRV_CMD_WAIT_FOR_CMPL,
|
||||||
|
RSC_DRV_CONTROL,
|
||||||
|
RSC_DRV_STATUS,
|
||||||
|
RSC_DRV_CMD_ENABLE,
|
||||||
|
RSC_DRV_CMD_MSGID,
|
||||||
|
RSC_DRV_CMD_ADDR,
|
||||||
|
RSC_DRV_CMD_DATA,
|
||||||
|
RSC_DRV_CMD_STATUS,
|
||||||
|
RSC_DRV_CMD_RESP_DATA,
|
||||||
|
};
|
||||||
|
|
||||||
/* DRV HW Solver Configuration Information Register */
|
/* DRV HW Solver Configuration Information Register */
|
||||||
#define DRV_SOLVER_CONFIG 0x04
|
|
||||||
#define DRV_HW_SOLVER_MASK 1
|
#define DRV_HW_SOLVER_MASK 1
|
||||||
#define DRV_HW_SOLVER_SHIFT 24
|
#define DRV_HW_SOLVER_SHIFT 24
|
||||||
|
|
||||||
/* DRV TCS Configuration Information Register */
|
/* DRV TCS Configuration Information Register */
|
||||||
#define DRV_PRNT_CHLD_CONFIG 0x0C
|
|
||||||
#define DRV_NUM_TCS_MASK 0x3F
|
#define DRV_NUM_TCS_MASK 0x3F
|
||||||
#define DRV_NUM_TCS_SHIFT 6
|
#define DRV_NUM_TCS_SHIFT 6
|
||||||
#define DRV_NCPT_MASK 0x1F
|
#define DRV_NCPT_MASK 0x1F
|
||||||
|
@ -59,35 +81,6 @@
|
||||||
#define RSC_DRV_CTL_TCS_DATA_LO_MASK 0xFFFFFFFF
|
#define RSC_DRV_CTL_TCS_DATA_LO_MASK 0xFFFFFFFF
|
||||||
#define RSC_DRV_CTL_TCS_DATA_SIZE 32
|
#define RSC_DRV_CTL_TCS_DATA_SIZE 32
|
||||||
|
|
||||||
/* Offsets for common TCS Registers, one bit per TCS */
|
|
||||||
#define RSC_DRV_IRQ_ENABLE 0x00
|
|
||||||
#define RSC_DRV_IRQ_STATUS 0x04
|
|
||||||
#define RSC_DRV_IRQ_CLEAR 0x08 /* w/o; write 1 to clear */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Offsets for per TCS Registers.
|
|
||||||
*
|
|
||||||
* TCSes start at 0x10 from tcs_base and are stored one after another.
|
|
||||||
* Multiply tcs_id by RSC_DRV_TCS_OFFSET to find a given TCS and add one
|
|
||||||
* of the below to find a register.
|
|
||||||
*/
|
|
||||||
#define RSC_DRV_CMD_WAIT_FOR_CMPL 0x10 /* 1 bit per command */
|
|
||||||
#define RSC_DRV_CONTROL 0x14
|
|
||||||
#define RSC_DRV_STATUS 0x18 /* zero if tcs is busy */
|
|
||||||
#define RSC_DRV_CMD_ENABLE 0x1C /* 1 bit per command */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Offsets for per command in a TCS.
|
|
||||||
*
|
|
||||||
* Commands (up to 16) start at 0x30 in a TCS; multiply command index
|
|
||||||
* by RSC_DRV_CMD_OFFSET and add one of the below to find a register.
|
|
||||||
*/
|
|
||||||
#define RSC_DRV_CMD_MSGID 0x30
|
|
||||||
#define RSC_DRV_CMD_ADDR 0x34
|
|
||||||
#define RSC_DRV_CMD_DATA 0x38
|
|
||||||
#define RSC_DRV_CMD_STATUS 0x3C
|
|
||||||
#define RSC_DRV_CMD_RESP_DATA 0x40
|
|
||||||
|
|
||||||
#define TCS_AMC_MODE_ENABLE BIT(16)
|
#define TCS_AMC_MODE_ENABLE BIT(16)
|
||||||
#define TCS_AMC_MODE_TRIGGER BIT(24)
|
#define TCS_AMC_MODE_TRIGGER BIT(24)
|
||||||
|
|
||||||
|
@ -160,16 +153,54 @@ static inline unsigned long xloops_to_cycles(u64 xloops)
|
||||||
return (xloops * loops_per_jiffy * HZ) >> 32;
|
return (xloops * loops_per_jiffy * HZ) >> 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 rpmh_rsc_reg_offset_ver_2_7[] = {
|
||||||
|
[RSC_DRV_TCS_OFFSET] = 672,
|
||||||
|
[RSC_DRV_CMD_OFFSET] = 20,
|
||||||
|
[DRV_SOLVER_CONFIG] = 0x04,
|
||||||
|
[DRV_PRNT_CHLD_CONFIG] = 0x0C,
|
||||||
|
[RSC_DRV_IRQ_ENABLE] = 0x00,
|
||||||
|
[RSC_DRV_IRQ_STATUS] = 0x04,
|
||||||
|
[RSC_DRV_IRQ_CLEAR] = 0x08,
|
||||||
|
[RSC_DRV_CMD_WAIT_FOR_CMPL] = 0x10,
|
||||||
|
[RSC_DRV_CONTROL] = 0x14,
|
||||||
|
[RSC_DRV_STATUS] = 0x18,
|
||||||
|
[RSC_DRV_CMD_ENABLE] = 0x1C,
|
||||||
|
[RSC_DRV_CMD_MSGID] = 0x30,
|
||||||
|
[RSC_DRV_CMD_ADDR] = 0x34,
|
||||||
|
[RSC_DRV_CMD_DATA] = 0x38,
|
||||||
|
[RSC_DRV_CMD_STATUS] = 0x3C,
|
||||||
|
[RSC_DRV_CMD_RESP_DATA] = 0x40,
|
||||||
|
};
|
||||||
|
|
||||||
|
static u32 rpmh_rsc_reg_offset_ver_3_0[] = {
|
||||||
|
[RSC_DRV_TCS_OFFSET] = 672,
|
||||||
|
[RSC_DRV_CMD_OFFSET] = 24,
|
||||||
|
[DRV_SOLVER_CONFIG] = 0x04,
|
||||||
|
[DRV_PRNT_CHLD_CONFIG] = 0x0C,
|
||||||
|
[RSC_DRV_IRQ_ENABLE] = 0x00,
|
||||||
|
[RSC_DRV_IRQ_STATUS] = 0x04,
|
||||||
|
[RSC_DRV_IRQ_CLEAR] = 0x08,
|
||||||
|
[RSC_DRV_CMD_WAIT_FOR_CMPL] = 0x20,
|
||||||
|
[RSC_DRV_CONTROL] = 0x24,
|
||||||
|
[RSC_DRV_STATUS] = 0x28,
|
||||||
|
[RSC_DRV_CMD_ENABLE] = 0x2C,
|
||||||
|
[RSC_DRV_CMD_MSGID] = 0x34,
|
||||||
|
[RSC_DRV_CMD_ADDR] = 0x38,
|
||||||
|
[RSC_DRV_CMD_DATA] = 0x3C,
|
||||||
|
[RSC_DRV_CMD_STATUS] = 0x40,
|
||||||
|
[RSC_DRV_CMD_RESP_DATA] = 0x44,
|
||||||
|
};
|
||||||
|
|
||||||
static inline void __iomem *
|
static inline void __iomem *
|
||||||
tcs_reg_addr(const struct rsc_drv *drv, int reg, int tcs_id)
|
tcs_reg_addr(const struct rsc_drv *drv, int reg, int tcs_id)
|
||||||
{
|
{
|
||||||
return drv->tcs_base + RSC_DRV_TCS_OFFSET * tcs_id + reg;
|
return drv->tcs_base + drv->regs[RSC_DRV_TCS_OFFSET] * tcs_id + reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void __iomem *
|
static inline void __iomem *
|
||||||
tcs_cmd_addr(const struct rsc_drv *drv, int reg, int tcs_id, int cmd_id)
|
tcs_cmd_addr(const struct rsc_drv *drv, int reg, int tcs_id, int cmd_id)
|
||||||
{
|
{
|
||||||
return tcs_reg_addr(drv, reg, tcs_id) + RSC_DRV_CMD_OFFSET * cmd_id;
|
return tcs_reg_addr(drv, reg, tcs_id) + drv->regs[RSC_DRV_CMD_OFFSET] * cmd_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 read_tcs_cmd(const struct rsc_drv *drv, int reg, int tcs_id,
|
static u32 read_tcs_cmd(const struct rsc_drv *drv, int reg, int tcs_id,
|
||||||
|
@ -237,7 +268,7 @@ static void tcs_invalidate(struct rsc_drv *drv, int type)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (m = tcs->offset; m < tcs->offset + tcs->num_tcs; m++)
|
for (m = tcs->offset; m < tcs->offset + tcs->num_tcs; m++)
|
||||||
write_tcs_reg_sync(drv, RSC_DRV_CMD_ENABLE, m, 0);
|
write_tcs_reg_sync(drv, drv->regs[RSC_DRV_CMD_ENABLE], m, 0);
|
||||||
|
|
||||||
bitmap_zero(tcs->slots, MAX_TCS_SLOTS);
|
bitmap_zero(tcs->slots, MAX_TCS_SLOTS);
|
||||||
}
|
}
|
||||||
|
@ -351,24 +382,25 @@ static const struct tcs_request *get_req_from_tcs(struct rsc_drv *drv,
|
||||||
static void __tcs_set_trigger(struct rsc_drv *drv, int tcs_id, bool trigger)
|
static void __tcs_set_trigger(struct rsc_drv *drv, int tcs_id, bool trigger)
|
||||||
{
|
{
|
||||||
u32 enable;
|
u32 enable;
|
||||||
|
u32 reg = drv->regs[RSC_DRV_CONTROL];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* HW req: Clear the DRV_CONTROL and enable TCS again
|
* HW req: Clear the DRV_CONTROL and enable TCS again
|
||||||
* While clearing ensure that the AMC mode trigger is cleared
|
* While clearing ensure that the AMC mode trigger is cleared
|
||||||
* and then the mode enable is cleared.
|
* and then the mode enable is cleared.
|
||||||
*/
|
*/
|
||||||
enable = read_tcs_reg(drv, RSC_DRV_CONTROL, tcs_id);
|
enable = read_tcs_reg(drv, reg, tcs_id);
|
||||||
enable &= ~TCS_AMC_MODE_TRIGGER;
|
enable &= ~TCS_AMC_MODE_TRIGGER;
|
||||||
write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
|
write_tcs_reg_sync(drv, reg, tcs_id, enable);
|
||||||
enable &= ~TCS_AMC_MODE_ENABLE;
|
enable &= ~TCS_AMC_MODE_ENABLE;
|
||||||
write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
|
write_tcs_reg_sync(drv, reg, tcs_id, enable);
|
||||||
|
|
||||||
if (trigger) {
|
if (trigger) {
|
||||||
/* Enable the AMC mode on the TCS and then trigger the TCS */
|
/* Enable the AMC mode on the TCS and then trigger the TCS */
|
||||||
enable = TCS_AMC_MODE_ENABLE;
|
enable = TCS_AMC_MODE_ENABLE;
|
||||||
write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
|
write_tcs_reg_sync(drv, reg, tcs_id, enable);
|
||||||
enable |= TCS_AMC_MODE_TRIGGER;
|
enable |= TCS_AMC_MODE_TRIGGER;
|
||||||
write_tcs_reg(drv, RSC_DRV_CONTROL, tcs_id, enable);
|
write_tcs_reg(drv, reg, tcs_id, enable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,13 +416,14 @@ static void __tcs_set_trigger(struct rsc_drv *drv, int tcs_id, bool trigger)
|
||||||
static void enable_tcs_irq(struct rsc_drv *drv, int tcs_id, bool enable)
|
static void enable_tcs_irq(struct rsc_drv *drv, int tcs_id, bool enable)
|
||||||
{
|
{
|
||||||
u32 data;
|
u32 data;
|
||||||
|
u32 reg = drv->regs[RSC_DRV_IRQ_ENABLE];
|
||||||
|
|
||||||
data = readl_relaxed(drv->tcs_base + RSC_DRV_IRQ_ENABLE);
|
data = readl_relaxed(drv->tcs_base + reg);
|
||||||
if (enable)
|
if (enable)
|
||||||
data |= BIT(tcs_id);
|
data |= BIT(tcs_id);
|
||||||
else
|
else
|
||||||
data &= ~BIT(tcs_id);
|
data &= ~BIT(tcs_id);
|
||||||
writel_relaxed(data, drv->tcs_base + RSC_DRV_IRQ_ENABLE);
|
writel_relaxed(data, drv->tcs_base + reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -411,7 +444,7 @@ static irqreturn_t tcs_tx_done(int irq, void *p)
|
||||||
const struct tcs_request *req;
|
const struct tcs_request *req;
|
||||||
struct tcs_cmd *cmd;
|
struct tcs_cmd *cmd;
|
||||||
|
|
||||||
irq_status = readl_relaxed(drv->tcs_base + RSC_DRV_IRQ_STATUS);
|
irq_status = readl_relaxed(drv->tcs_base + drv->regs[RSC_DRV_IRQ_STATUS]);
|
||||||
|
|
||||||
for_each_set_bit(i, &irq_status, BITS_PER_TYPE(u32)) {
|
for_each_set_bit(i, &irq_status, BITS_PER_TYPE(u32)) {
|
||||||
req = get_req_from_tcs(drv, i);
|
req = get_req_from_tcs(drv, i);
|
||||||
|
@ -423,7 +456,7 @@ static irqreturn_t tcs_tx_done(int irq, void *p)
|
||||||
u32 sts;
|
u32 sts;
|
||||||
|
|
||||||
cmd = &req->cmds[j];
|
cmd = &req->cmds[j];
|
||||||
sts = read_tcs_cmd(drv, RSC_DRV_CMD_STATUS, i, j);
|
sts = read_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_STATUS], i, j);
|
||||||
if (!(sts & CMD_STATUS_ISSUED) ||
|
if (!(sts & CMD_STATUS_ISSUED) ||
|
||||||
((req->wait_for_compl || cmd->wait) &&
|
((req->wait_for_compl || cmd->wait) &&
|
||||||
!(sts & CMD_STATUS_COMPL))) {
|
!(sts & CMD_STATUS_COMPL))) {
|
||||||
|
@ -444,8 +477,8 @@ static irqreturn_t tcs_tx_done(int irq, void *p)
|
||||||
__tcs_set_trigger(drv, i, false);
|
__tcs_set_trigger(drv, i, false);
|
||||||
skip:
|
skip:
|
||||||
/* Reclaim the TCS */
|
/* Reclaim the TCS */
|
||||||
write_tcs_reg(drv, RSC_DRV_CMD_ENABLE, i, 0);
|
write_tcs_reg(drv, drv->regs[RSC_DRV_CMD_ENABLE], i, 0);
|
||||||
writel_relaxed(BIT(i), drv->tcs_base + RSC_DRV_IRQ_CLEAR);
|
writel_relaxed(BIT(i), drv->tcs_base + drv->regs[RSC_DRV_IRQ_CLEAR]);
|
||||||
spin_lock(&drv->lock);
|
spin_lock(&drv->lock);
|
||||||
clear_bit(i, drv->tcs_in_use);
|
clear_bit(i, drv->tcs_in_use);
|
||||||
/*
|
/*
|
||||||
|
@ -496,14 +529,14 @@ static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id,
|
||||||
*/
|
*/
|
||||||
msgid |= cmd->wait ? CMD_MSGID_RESP_REQ : 0;
|
msgid |= cmd->wait ? CMD_MSGID_RESP_REQ : 0;
|
||||||
|
|
||||||
write_tcs_cmd(drv, RSC_DRV_CMD_MSGID, tcs_id, j, msgid);
|
write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_MSGID], tcs_id, j, msgid);
|
||||||
write_tcs_cmd(drv, RSC_DRV_CMD_ADDR, tcs_id, j, cmd->addr);
|
write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_ADDR], tcs_id, j, cmd->addr);
|
||||||
write_tcs_cmd(drv, RSC_DRV_CMD_DATA, tcs_id, j, cmd->data);
|
write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_DATA], tcs_id, j, cmd->data);
|
||||||
trace_rpmh_send_msg(drv, tcs_id, j, msgid, cmd);
|
trace_rpmh_send_msg(drv, tcs_id, j, msgid, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_enable |= read_tcs_reg(drv, RSC_DRV_CMD_ENABLE, tcs_id);
|
cmd_enable |= read_tcs_reg(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id);
|
||||||
write_tcs_reg(drv, RSC_DRV_CMD_ENABLE, tcs_id, cmd_enable);
|
write_tcs_reg(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id, cmd_enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -535,10 +568,10 @@ static int check_for_req_inflight(struct rsc_drv *drv, struct tcs_group *tcs,
|
||||||
int i = tcs->offset;
|
int i = tcs->offset;
|
||||||
|
|
||||||
for_each_set_bit_from(i, drv->tcs_in_use, tcs->offset + tcs->num_tcs) {
|
for_each_set_bit_from(i, drv->tcs_in_use, tcs->offset + tcs->num_tcs) {
|
||||||
curr_enabled = read_tcs_reg(drv, RSC_DRV_CMD_ENABLE, i);
|
curr_enabled = read_tcs_reg(drv, drv->regs[RSC_DRV_CMD_ENABLE], i);
|
||||||
|
|
||||||
for_each_set_bit(j, &curr_enabled, MAX_CMDS_PER_TCS) {
|
for_each_set_bit(j, &curr_enabled, MAX_CMDS_PER_TCS) {
|
||||||
addr = read_tcs_cmd(drv, RSC_DRV_CMD_ADDR, i, j);
|
addr = read_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_ADDR], i, j);
|
||||||
for (k = 0; k < msg->num_cmds; k++) {
|
for (k = 0; k < msg->num_cmds; k++) {
|
||||||
if (addr == msg->cmds[k].addr)
|
if (addr == msg->cmds[k].addr)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
@ -649,7 +682,7 @@ int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg)
|
||||||
* repurposed TCS to avoid triggering them. tcs->slots will be
|
* repurposed TCS to avoid triggering them. tcs->slots will be
|
||||||
* cleaned from rpmh_flush() by invoking rpmh_rsc_invalidate()
|
* cleaned from rpmh_flush() by invoking rpmh_rsc_invalidate()
|
||||||
*/
|
*/
|
||||||
write_tcs_reg_sync(drv, RSC_DRV_CMD_ENABLE, tcs_id, 0);
|
write_tcs_reg_sync(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id, 0);
|
||||||
enable_tcs_irq(drv, tcs_id, true);
|
enable_tcs_irq(drv, tcs_id, true);
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&drv->lock, flags);
|
spin_unlock_irqrestore(&drv->lock, flags);
|
||||||
|
@ -957,7 +990,7 @@ static int rpmh_probe_tcs_config(struct platform_device *pdev, struct rsc_drv *d
|
||||||
return ret;
|
return ret;
|
||||||
drv->tcs_base = drv->base + offset;
|
drv->tcs_base = drv->base + offset;
|
||||||
|
|
||||||
config = readl_relaxed(drv->base + DRV_PRNT_CHLD_CONFIG);
|
config = readl_relaxed(drv->base + drv->regs[DRV_PRNT_CHLD_CONFIG]);
|
||||||
|
|
||||||
max_tcs = config;
|
max_tcs = config;
|
||||||
max_tcs &= DRV_NUM_TCS_MASK << (DRV_NUM_TCS_SHIFT * drv->id);
|
max_tcs &= DRV_NUM_TCS_MASK << (DRV_NUM_TCS_SHIFT * drv->id);
|
||||||
|
@ -1019,6 +1052,7 @@ static int rpmh_rsc_probe(struct platform_device *pdev)
|
||||||
char drv_id[10] = {0};
|
char drv_id[10] = {0};
|
||||||
int ret, irq;
|
int ret, irq;
|
||||||
u32 solver_config;
|
u32 solver_config;
|
||||||
|
u32 rsc_id;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Even though RPMh doesn't directly use cmd-db, all of its children
|
* Even though RPMh doesn't directly use cmd-db, all of its children
|
||||||
|
@ -1049,6 +1083,17 @@ static int rpmh_rsc_probe(struct platform_device *pdev)
|
||||||
if (IS_ERR(drv->base))
|
if (IS_ERR(drv->base))
|
||||||
return PTR_ERR(drv->base);
|
return PTR_ERR(drv->base);
|
||||||
|
|
||||||
|
rsc_id = readl_relaxed(drv->base + RSC_DRV_ID);
|
||||||
|
drv->ver.major = rsc_id & (MAJOR_VER_MASK << MAJOR_VER_SHIFT);
|
||||||
|
drv->ver.major >>= MAJOR_VER_SHIFT;
|
||||||
|
drv->ver.minor = rsc_id & (MINOR_VER_MASK << MINOR_VER_SHIFT);
|
||||||
|
drv->ver.minor >>= MINOR_VER_SHIFT;
|
||||||
|
|
||||||
|
if (drv->ver.major == 3 && drv->ver.minor == 0)
|
||||||
|
drv->regs = rpmh_rsc_reg_offset_ver_3_0;
|
||||||
|
else
|
||||||
|
drv->regs = rpmh_rsc_reg_offset_ver_2_7;
|
||||||
|
|
||||||
ret = rpmh_probe_tcs_config(pdev, drv);
|
ret = rpmh_probe_tcs_config(pdev, drv);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1072,7 +1117,7 @@ static int rpmh_rsc_probe(struct platform_device *pdev)
|
||||||
* 'HW solver' mode where they can be in autonomous mode executing low
|
* 'HW solver' mode where they can be in autonomous mode executing low
|
||||||
* power mode to power down.
|
* power mode to power down.
|
||||||
*/
|
*/
|
||||||
solver_config = readl_relaxed(drv->base + DRV_SOLVER_CONFIG);
|
solver_config = readl_relaxed(drv->base + drv->regs[DRV_SOLVER_CONFIG]);
|
||||||
solver_config &= DRV_HW_SOLVER_MASK << DRV_HW_SOLVER_SHIFT;
|
solver_config &= DRV_HW_SOLVER_MASK << DRV_HW_SOLVER_SHIFT;
|
||||||
solver_config = solver_config >> DRV_HW_SOLVER_SHIFT;
|
solver_config = solver_config >> DRV_HW_SOLVER_SHIFT;
|
||||||
if (!solver_config) {
|
if (!solver_config) {
|
||||||
|
@ -1088,7 +1133,7 @@ static int rpmh_rsc_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
/* Enable the active TCS to send requests immediately */
|
/* Enable the active TCS to send requests immediately */
|
||||||
writel_relaxed(drv->tcs[ACTIVE_TCS].mask,
|
writel_relaxed(drv->tcs[ACTIVE_TCS].mask,
|
||||||
drv->tcs_base + RSC_DRV_IRQ_ENABLE);
|
drv->tcs_base + drv->regs[RSC_DRV_IRQ_ENABLE]);
|
||||||
|
|
||||||
spin_lock_init(&drv->client.cache_lock);
|
spin_lock_init(&drv->client.cache_lock);
|
||||||
INIT_LIST_HEAD(&drv->client.cache);
|
INIT_LIST_HEAD(&drv->client.cache);
|
||||||
|
|
Loading…
Reference in a new issue