mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 22:40:54 -04:00
soc: qcom: dcc: Support new DCC HW feature
Add support to new register memory map, fix loop offset and dynamic number of link list. Change-Id: Ibadfa723842dae80cdd50bf08018d86c2ef30b94 Signed-off-by: Tingwei Zhang <tingwei@codeaurora.org>
This commit is contained in:
parent
de99f57c32
commit
777bece578
1 changed files with 110 additions and 48 deletions
|
|
@ -25,9 +25,9 @@
|
|||
#define BVAL(val, n) ((val & BIT(n)) >> n)
|
||||
|
||||
#define dcc_writel(drvdata, val, off) \
|
||||
__raw_writel((val), drvdata->base + off)
|
||||
__raw_writel((val), drvdata->base + dcc_offset_conv(drvdata, off))
|
||||
#define dcc_readl(drvdata, off) \
|
||||
__raw_readl(drvdata->base + off)
|
||||
__raw_readl(drvdata->base + dcc_offset_conv(drvdata, off))
|
||||
|
||||
#define dcc_sram_readl(drvdata, off) \
|
||||
__raw_readl(drvdata->ram_base + off)
|
||||
|
|
@ -37,23 +37,35 @@
|
|||
/* DCC registers */
|
||||
#define DCC_HW_VERSION (0x00)
|
||||
#define DCC_HW_INFO (0x04)
|
||||
#define DCC_EXEC_CTRL (0x08)
|
||||
#define DCC_STATUS (0x0C)
|
||||
#define DCC_CFG (0x10)
|
||||
#define DCC_FDA_CURR (0x14)
|
||||
#define DCC_LLA_CURR (0x18)
|
||||
#define DCC_LL_LOCK(m) (0x1C + 0x80 * (m + HLOS_LIST_START))
|
||||
#define DCC_LL_CFG(m) (0x20 + 0x80 * (m + HLOS_LIST_START))
|
||||
#define DCC_LL_BASE(m) (0x24 + 0x80 * (m + HLOS_LIST_START))
|
||||
#define DCC_FD_BASE(m) (0x28 + 0x80 * (m + HLOS_LIST_START))
|
||||
#define DCC_LL_TIMEOUT(m) (0x2c + 0x80 * (m + HLOS_LIST_START))
|
||||
#define DCC_LL_INT_ENABLE(m) (0x30 + 0x80 * (m + HLOS_LIST_START))
|
||||
#define DCC_LL_INT_STATUS(m) (0x34 + 0x80 * (m + HLOS_LIST_START))
|
||||
#define DCC_FDA_CAPTURED(m) (0x38 + 0x80 * (m + HLOS_LIST_START))
|
||||
#define DCC_LLA_CAPTURED(m) (0x3C + 0x80 * (m + HLOS_LIST_START))
|
||||
#define DCC_LL_CRC_CAPTURED(m) (0x40 + 0x80 * (m + HLOS_LIST_START))
|
||||
#define DCC_LL_SW_TRIGGER(m) (0x44 + 0x80 * (m + HLOS_LIST_START))
|
||||
#define DCC_LL_BUS_ACCESS_STATUS(m) (0x48 + 0x80 * (m + HLOS_LIST_START))
|
||||
#define DCC_SRAM_SIZE_INFO (0x08)
|
||||
#define DCC_APU_INFO (0x0C)
|
||||
#define DCC_LL_NUM_INFO (0x10)
|
||||
#define DCC_TIMEOUT_SIGNATURE (0x14)
|
||||
#define DCC_EXEC_CTRL (0x18)
|
||||
#define DCC_STATUS (0x1C)
|
||||
#define DCC_CFG (0x20)
|
||||
#define DCC_FDA_CURR (0x24)
|
||||
#define DCC_LLA_CURR (0x28)
|
||||
#define DCC_LL_LOCK(m) (0x2C + 0x80 * (m + HLOS_LIST_START))
|
||||
#define DCC_LL_CFG(m) (0x30 + 0x80 * (m + HLOS_LIST_START))
|
||||
#define DCC_LL_BASE(m) (0x34 + 0x80 * (m + HLOS_LIST_START))
|
||||
#define DCC_FD_BASE(m) (0x38 + 0x80 * (m + HLOS_LIST_START))
|
||||
#define DCC_LL_TIMEOUT(m) (0x3c + 0x80 * (m + HLOS_LIST_START))
|
||||
#define DCC_TRANS_TIMEOUT(m) (0x40 + 0x80 * (m + HLOS_LIST_START))
|
||||
#define DCC_LL_INT_ENABLE(m) (0x44 + 0x80 * (m + HLOS_LIST_START))
|
||||
#define DCC_LL_INT_STATUS(m) (0x48 + 0x80 * (m + HLOS_LIST_START))
|
||||
#define DCC_FDA_CAPTURED(m) (0x4C + 0x80 * (m + HLOS_LIST_START))
|
||||
#define DCC_LLA_CAPTURED(m) (0x50 + 0x80 * (m + HLOS_LIST_START))
|
||||
#define DCC_LL_CRC_CAPTURED(m) (0x54 + 0x80 * (m + HLOS_LIST_START))
|
||||
#define DCC_LL_SW_TRIGGER(m) (0x58 + 0x80 * (m + HLOS_LIST_START))
|
||||
#define DCC_LL_BUS_ACCESS_STATUS(m) (0x5C + 0x80 * (m + HLOS_LIST_START))
|
||||
|
||||
#define DCC_MAP2_LEVEL1 (0x18)
|
||||
#define DCC_MAP2_OFFSET1 (0x10)
|
||||
#define DCC_MAP2_LEVEL2 (0x44)
|
||||
#define DCC_MAP2_OFFSET2 (0x14)
|
||||
|
||||
#define DCC_FIX_LOOP_OFFSET (16)
|
||||
|
||||
#define DCC_REG_DUMP_MAGIC_V2 (0x42445953)
|
||||
#define DCC_REG_DUMP_VER (1)
|
||||
|
|
@ -129,23 +141,36 @@ struct dcc_drvdata {
|
|||
void __iomem *ram_base;
|
||||
uint32_t ram_size;
|
||||
uint32_t ram_offset;
|
||||
enum dcc_data_sink data_sink[DCC_MAX_LINK_LIST];
|
||||
enum dcc_func_type func_type[DCC_MAX_LINK_LIST];
|
||||
enum dcc_data_sink *data_sink;
|
||||
enum dcc_func_type *func_type;
|
||||
uint32_t ram_cfg;
|
||||
uint32_t ram_start;
|
||||
bool enable[DCC_MAX_LINK_LIST];
|
||||
bool configured[DCC_MAX_LINK_LIST];
|
||||
bool *enable;
|
||||
bool *configured;
|
||||
bool interrupt_disable;
|
||||
bool memory_map2;
|
||||
char *sram_node;
|
||||
struct cdev sram_dev;
|
||||
struct class *sram_class;
|
||||
struct list_head cfg_head[DCC_MAX_LINK_LIST];
|
||||
uint32_t nr_config[DCC_MAX_LINK_LIST];
|
||||
struct list_head *cfg_head;
|
||||
uint32_t *nr_config;
|
||||
uint32_t nr_link_list;
|
||||
uint8_t curr_list;
|
||||
uint8_t cti_trig;
|
||||
uint8_t loopoff;
|
||||
};
|
||||
|
||||
static uint32_t dcc_offset_conv(struct dcc_drvdata *drvdata, uint32_t off)
|
||||
{
|
||||
if (!drvdata->memory_map2) {
|
||||
if ((off & 0x7F) > DCC_MAP2_LEVEL2)
|
||||
return (off - DCC_MAP2_OFFSET2);
|
||||
else if ((off & 0x7F) > DCC_MAP2_LEVEL1)
|
||||
return (off - DCC_MAP2_OFFSET1);
|
||||
}
|
||||
return (off);
|
||||
}
|
||||
|
||||
static int dcc_sram_writel(struct dcc_drvdata *drvdata,
|
||||
uint32_t val, uint32_t off)
|
||||
{
|
||||
|
|
@ -176,7 +201,7 @@ static int dcc_read_status(struct dcc_drvdata *drvdata)
|
|||
uint32_t ll_cfg = 0;
|
||||
uint32_t tmp_ll_cfg = 0;
|
||||
|
||||
for (curr_list = 0; curr_list < DCC_MAX_LINK_LIST; curr_list++) {
|
||||
for (curr_list = 0; curr_list < drvdata->nr_link_list; curr_list++) {
|
||||
if (!drvdata->enable[curr_list])
|
||||
continue;
|
||||
|
||||
|
|
@ -211,7 +236,7 @@ static int dcc_sw_trigger(struct dcc_drvdata *drvdata)
|
|||
|
||||
mutex_lock(&drvdata->mutex);
|
||||
|
||||
for (curr_list = 0; curr_list < DCC_MAX_LINK_LIST; curr_list++) {
|
||||
for (curr_list = 0; curr_list < drvdata->nr_link_list; curr_list++) {
|
||||
if (!drvdata->enable[curr_list])
|
||||
continue;
|
||||
ll_cfg = dcc_readl(drvdata, DCC_LL_CFG(curr_list));
|
||||
|
|
@ -588,7 +613,7 @@ static int dcc_enable(struct dcc_drvdata *drvdata)
|
|||
|
||||
memset_io(drvdata->ram_base, 0xDE, drvdata->ram_size);
|
||||
|
||||
for (list = 0; list < DCC_MAX_LINK_LIST; list++) {
|
||||
for (list = 0; list < drvdata->nr_link_list; list++) {
|
||||
|
||||
if (dcc_valid_list(drvdata, list))
|
||||
continue;
|
||||
|
|
@ -652,7 +677,7 @@ static void dcc_disable(struct dcc_drvdata *drvdata)
|
|||
if (!dcc_ready(drvdata))
|
||||
dev_err(drvdata->dev, "DCC is not ready Disabling DCC...\n");
|
||||
|
||||
for (curr_list = 0; curr_list < DCC_MAX_LINK_LIST; curr_list++) {
|
||||
for (curr_list = 0; curr_list < drvdata->nr_link_list; curr_list++) {
|
||||
if (!drvdata->enable[curr_list])
|
||||
continue;
|
||||
dcc_writel(drvdata, 0, DCC_LL_CFG(curr_list));
|
||||
|
|
@ -672,7 +697,7 @@ static bool is_dcc_enabled(struct dcc_drvdata *drvdata)
|
|||
bool dcc_enable = false;
|
||||
int list;
|
||||
|
||||
for (list = 0; list < DCC_MAX_LINK_LIST; list++) {
|
||||
for (list = 0; list < drvdata->nr_link_list; list++) {
|
||||
if (drvdata->enable[list]) {
|
||||
dcc_enable = true;
|
||||
break;
|
||||
|
|
@ -713,7 +738,7 @@ static ssize_t curr_list_store(struct device *dev,
|
|||
if (kstrtoul(buf, 16, &val))
|
||||
return -EINVAL;
|
||||
|
||||
if (val >= DCC_MAX_LINK_LIST)
|
||||
if (val >= drvdata->nr_link_list)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&drvdata->mutex);
|
||||
|
|
@ -745,7 +770,7 @@ static ssize_t func_type_show(struct device *dev,
|
|||
ssize_t len = 0;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < DCC_MAX_LINK_LIST; i++)
|
||||
for (i = 0; i < drvdata->nr_link_list; i++)
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len, "%u :%s\n",
|
||||
i, str_dcc_func_type[drvdata->func_type[i]]);
|
||||
|
||||
|
|
@ -766,7 +791,7 @@ static ssize_t func_type_store(struct device *dev,
|
|||
return -EINVAL;
|
||||
|
||||
mutex_lock(&drvdata->mutex);
|
||||
if (drvdata->curr_list >= DCC_MAX_LINK_LIST) {
|
||||
if (drvdata->curr_list >= drvdata->nr_link_list) {
|
||||
dev_err(dev,
|
||||
"Select link list to program using curr_list\n");
|
||||
ret = -EINVAL;
|
||||
|
|
@ -803,7 +828,7 @@ static ssize_t data_sink_show(struct device *dev,
|
|||
ssize_t len = 0;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < DCC_MAX_LINK_LIST; i++)
|
||||
for (i = 0; i < drvdata->nr_link_list; i++)
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len, "%u :%s\n",
|
||||
i, str_dcc_data_sink[drvdata->data_sink[i]]);
|
||||
|
||||
|
|
@ -824,7 +849,7 @@ static ssize_t data_sink_store(struct device *dev,
|
|||
return -EINVAL;
|
||||
|
||||
mutex_lock(&drvdata->mutex);
|
||||
if (drvdata->curr_list >= DCC_MAX_LINK_LIST) {
|
||||
if (drvdata->curr_list >= drvdata->nr_link_list) {
|
||||
dev_err(dev,
|
||||
"Select link list to program using curr_list\n");
|
||||
ret = -EINVAL;
|
||||
|
|
@ -881,7 +906,7 @@ static ssize_t enable_show(struct device *dev,
|
|||
struct dcc_drvdata *drvdata = dev_get_drvdata(dev);
|
||||
|
||||
mutex_lock(&drvdata->mutex);
|
||||
if (drvdata->curr_list >= DCC_MAX_LINK_LIST) {
|
||||
if (drvdata->curr_list >= drvdata->nr_link_list) {
|
||||
dev_err(dev, "Select link list to program using curr_list\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
|
|
@ -931,7 +956,7 @@ static ssize_t config_show(struct device *dev,
|
|||
buf[0] = '\0';
|
||||
|
||||
mutex_lock(&drvdata->mutex);
|
||||
if (drvdata->curr_list >= DCC_MAX_LINK_LIST) {
|
||||
if (drvdata->curr_list >= drvdata->nr_link_list) {
|
||||
dev_err(dev, "Select link list to program using curr_list\n");
|
||||
count = -EINVAL;
|
||||
goto err;
|
||||
|
|
@ -987,7 +1012,7 @@ static int dcc_config_add(struct dcc_drvdata *drvdata, unsigned int addr,
|
|||
|
||||
mutex_lock(&drvdata->mutex);
|
||||
|
||||
if (drvdata->curr_list >= DCC_MAX_LINK_LIST) {
|
||||
if (drvdata->curr_list >= drvdata->nr_link_list) {
|
||||
dev_err(drvdata->dev, "Select link list to program using curr_list\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
|
|
@ -1112,7 +1137,7 @@ static void dcc_config_reset(struct dcc_drvdata *drvdata)
|
|||
|
||||
mutex_lock(&drvdata->mutex);
|
||||
|
||||
for (curr_list = 0; curr_list < DCC_MAX_LINK_LIST; curr_list++) {
|
||||
for (curr_list = 0; curr_list < drvdata->nr_link_list; curr_list++) {
|
||||
|
||||
list_for_each_entry_safe(entry, temp,
|
||||
&drvdata->cfg_head[curr_list], list) {
|
||||
|
|
@ -1150,7 +1175,7 @@ static ssize_t crc_error_show(struct device *dev,
|
|||
struct dcc_drvdata *drvdata = dev_get_drvdata(dev);
|
||||
|
||||
mutex_lock(&drvdata->mutex);
|
||||
if (drvdata->curr_list >= DCC_MAX_LINK_LIST) {
|
||||
if (drvdata->curr_list >= drvdata->nr_link_list) {
|
||||
dev_err(dev, "Select link list to program using curr_list\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
|
|
@ -1178,7 +1203,7 @@ static ssize_t ready_show(struct device *dev,
|
|||
|
||||
mutex_lock(&drvdata->mutex);
|
||||
|
||||
if (drvdata->curr_list >= DCC_MAX_LINK_LIST) {
|
||||
if (drvdata->curr_list >= drvdata->nr_link_list) {
|
||||
dev_err(dev, "Select link list to program using curr_list\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
|
|
@ -1256,7 +1281,7 @@ static ssize_t loop_store(struct device *dev,
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (drvdata->curr_list >= DCC_MAX_LINK_LIST) {
|
||||
if (drvdata->curr_list >= drvdata->nr_link_list) {
|
||||
dev_err(dev, "Select link list to program using curr_list\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
|
|
@ -1282,7 +1307,7 @@ static int dcc_rd_mod_wr_add(struct dcc_drvdata *drvdata, unsigned int mask,
|
|||
|
||||
mutex_lock(&drvdata->mutex);
|
||||
|
||||
if (drvdata->curr_list >= DCC_MAX_LINK_LIST) {
|
||||
if (drvdata->curr_list >= drvdata->nr_link_list) {
|
||||
dev_err(drvdata->dev, "Select link list to program using curr_list\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
|
|
@ -1375,7 +1400,7 @@ static ssize_t config_write_store(struct device *dev,
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (drvdata->curr_list >= DCC_MAX_LINK_LIST) {
|
||||
if (drvdata->curr_list >= drvdata->nr_link_list) {
|
||||
dev_err(dev, "Select link list to program using curr_list\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
|
|
@ -1417,7 +1442,7 @@ static ssize_t cti_trig_store(struct device *dev,
|
|||
|
||||
mutex_lock(&drvdata->mutex);
|
||||
|
||||
if (drvdata->curr_list >= DCC_MAX_LINK_LIST) {
|
||||
if (drvdata->curr_list >= drvdata->nr_link_list) {
|
||||
dev_err(dev, "Select link list to program using curr_list\n");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
|
|
@ -1612,7 +1637,7 @@ static int dcc_dt_parse(struct dcc_drvdata *drvdata, struct device_node *np)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (curr_link_list >= DCC_MAX_LINK_LIST) {
|
||||
if (curr_link_list >= drvdata->nr_link_list) {
|
||||
dev_err(drvdata->dev, "List configuration failed.\n");
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1735,11 +1760,48 @@ static int dcc_probe(struct platform_device *pdev)
|
|||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
drvdata->loopoff = get_bitmask_order((drvdata->ram_size +
|
||||
if ((dcc_readl(drvdata, DCC_HW_INFO) & 0x3F) == 0x3F) {
|
||||
drvdata->memory_map2 = true;
|
||||
drvdata->nr_link_list = dcc_readl(drvdata, DCC_LL_NUM_INFO);
|
||||
if (drvdata->nr_link_list == 0)
|
||||
return -EINVAL;
|
||||
} else {
|
||||
drvdata->memory_map2 = false;
|
||||
drvdata->nr_link_list = DCC_MAX_LINK_LIST;
|
||||
}
|
||||
|
||||
if ((dcc_readl(drvdata, DCC_HW_INFO) & BIT(6)) == BIT(6))
|
||||
drvdata->loopoff = DCC_FIX_LOOP_OFFSET;
|
||||
else
|
||||
drvdata->loopoff = get_bitmask_order((drvdata->ram_size +
|
||||
drvdata->ram_offset) / 4 - 1);
|
||||
mutex_init(&drvdata->mutex);
|
||||
drvdata->data_sink = devm_kzalloc(dev, drvdata->nr_link_list *
|
||||
sizeof(enum dcc_data_sink), GFP_KERNEL);
|
||||
if (!drvdata->data_sink)
|
||||
return -ENOMEM;
|
||||
drvdata->func_type = devm_kzalloc(dev, drvdata->nr_link_list *
|
||||
sizeof(enum dcc_func_type), GFP_KERNEL);
|
||||
if (!drvdata->func_type)
|
||||
return -ENOMEM;
|
||||
drvdata->enable = devm_kzalloc(dev, drvdata->nr_link_list *
|
||||
sizeof(bool), GFP_KERNEL);
|
||||
if (!drvdata->enable)
|
||||
return -ENOMEM;
|
||||
drvdata->configured = devm_kzalloc(dev, drvdata->nr_link_list *
|
||||
sizeof(bool), GFP_KERNEL);
|
||||
if (!drvdata->configured)
|
||||
return -ENOMEM;
|
||||
drvdata->nr_config = devm_kzalloc(dev, drvdata->nr_link_list *
|
||||
sizeof(uint32_t), GFP_KERNEL);
|
||||
if (!drvdata->nr_config)
|
||||
return -ENOMEM;
|
||||
drvdata->cfg_head = devm_kzalloc(dev, drvdata->nr_link_list *
|
||||
sizeof(struct list_head), GFP_KERNEL);
|
||||
if (!drvdata->cfg_head)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < DCC_MAX_LINK_LIST; i++) {
|
||||
for (i = 0; i < drvdata->nr_link_list; i++) {
|
||||
INIT_LIST_HEAD(&drvdata->cfg_head[i]);
|
||||
drvdata->nr_config[i] = 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue