mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-30 23:54:04 +08:00
soc: qcom: Make llcc-qcom a generic driver
This makes way for adding future llcc versions. Also pull out the llcc-qcom specific definitions from includes. Includes path now contains the only definitions that are to be exposed to other subsystems. Signed-off-by: Vivek Gautam <vivek.gautam@codeaurora.org> Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
This commit is contained in:
parent
a0e72a5ba4
commit
99356b03b4
@ -47,6 +47,100 @@
|
||||
|
||||
#define BANK_OFFSET_STRIDE 0x80000
|
||||
|
||||
/**
|
||||
* llcc_slice_config - Data associated with the llcc slice
|
||||
* @usecase_id: Unique id for the client's use case
|
||||
* @slice_id: llcc slice id for each client
|
||||
* @max_cap: The maximum capacity of the cache slice provided in KB
|
||||
* @priority: Priority of the client used to select victim line for replacement
|
||||
* @fixed_size: Boolean indicating if the slice has a fixed capacity
|
||||
* @bonus_ways: Bonus ways are additional ways to be used for any slice,
|
||||
* if client ends up using more than reserved cache ways. Bonus
|
||||
* ways are allocated only if they are not reserved for some
|
||||
* other client.
|
||||
* @res_ways: Reserved ways for the cache slice, the reserved ways cannot
|
||||
* be used by any other client than the one its assigned to.
|
||||
* @cache_mode: Each slice operates as a cache, this controls the mode of the
|
||||
* slice: normal or TCM(Tightly Coupled Memory)
|
||||
* @probe_target_ways: Determines what ways to probe for access hit. When
|
||||
* configured to 1 only bonus and reserved ways are probed.
|
||||
* When configured to 0 all ways in llcc are probed.
|
||||
* @dis_cap_alloc: Disable capacity based allocation for a client
|
||||
* @retain_on_pc: If this bit is set and client has maintained active vote
|
||||
* then the ways assigned to this client are not flushed on power
|
||||
* collapse.
|
||||
* @activate_on_init: Activate the slice immediately after it is programmed
|
||||
*/
|
||||
struct llcc_slice_config {
|
||||
u32 usecase_id;
|
||||
u32 slice_id;
|
||||
u32 max_cap;
|
||||
u32 priority;
|
||||
bool fixed_size;
|
||||
u32 bonus_ways;
|
||||
u32 res_ways;
|
||||
u32 cache_mode;
|
||||
u32 probe_target_ways;
|
||||
bool dis_cap_alloc;
|
||||
bool retain_on_pc;
|
||||
bool activate_on_init;
|
||||
};
|
||||
|
||||
/**
|
||||
* llcc_drv_data - Data associated with the llcc driver
|
||||
* @regmap: regmap associated with the llcc device
|
||||
* @bcast_regmap: regmap associated with llcc broadcast offset
|
||||
* @cfg: pointer to the data structure for slice configuration
|
||||
* @lock: mutex associated with each slice
|
||||
* @cfg_size: size of the config data table
|
||||
* @max_slices: max slices as read from device tree
|
||||
* @num_banks: Number of llcc banks
|
||||
* @bitmap: Bit map to track the active slice ids
|
||||
* @offsets: Pointer to the bank offsets array
|
||||
* @ecc_irq: interrupt for llcc cache error detection and reporting
|
||||
*/
|
||||
struct llcc_drv_data {
|
||||
struct regmap *regmap;
|
||||
struct regmap *bcast_regmap;
|
||||
const struct llcc_slice_config *cfg;
|
||||
struct mutex lock;
|
||||
u32 cfg_size;
|
||||
u32 max_slices;
|
||||
u32 num_banks;
|
||||
unsigned long *bitmap;
|
||||
u32 *offsets;
|
||||
int ecc_irq;
|
||||
};
|
||||
|
||||
/**
|
||||
* llcc_edac_reg_data - llcc edac registers data for each error type
|
||||
* @name: Name of the error
|
||||
* @synd_reg: Syndrome register address
|
||||
* @count_status_reg: Status register address to read the error count
|
||||
* @ways_status_reg: Status register address to read the error ways
|
||||
* @reg_cnt: Number of registers
|
||||
* @count_mask: Mask value to get the error count
|
||||
* @ways_mask: Mask value to get the error ways
|
||||
* @count_shift: Shift value to get the error count
|
||||
* @ways_shift: Shift value to get the error ways
|
||||
*/
|
||||
struct llcc_edac_reg_data {
|
||||
char *name;
|
||||
u64 synd_reg;
|
||||
u64 count_status_reg;
|
||||
u64 ways_status_reg;
|
||||
u32 reg_cnt;
|
||||
u32 count_mask;
|
||||
u32 ways_mask;
|
||||
u8 count_shift;
|
||||
u8 ways_shift;
|
||||
};
|
||||
|
||||
struct qcom_llcc_config {
|
||||
const struct llcc_slice_config *sct_data;
|
||||
int size;
|
||||
};
|
||||
|
||||
static struct llcc_slice_config sdm845_data[] = {
|
||||
{ LLCC_CPUSS, 1, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 1 },
|
||||
{ LLCC_VIDSC0, 2, 512, 2, 1, 0x0, 0x0f0, 0, 0, 1, 1, 0 },
|
||||
@ -68,6 +162,11 @@ static struct llcc_slice_config sdm845_data[] = {
|
||||
{ LLCC_AUDHW, 22, 1024, 1, 1, 0xffc, 0x2, 0, 0, 1, 1, 0 },
|
||||
};
|
||||
|
||||
static const struct qcom_llcc_config sdm845_cfg = {
|
||||
.sct_data = sdm845_data,
|
||||
.size = ARRAY_SIZE(sdm845_data),
|
||||
};
|
||||
|
||||
static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER;
|
||||
|
||||
static const struct regmap_config llcc_regmap_config = {
|
||||
@ -347,13 +446,15 @@ static struct regmap *qcom_llcc_init_mmio(struct platform_device *pdev,
|
||||
return devm_regmap_init_mmio(&pdev->dev, base, &llcc_regmap_config);
|
||||
}
|
||||
|
||||
static int qcom_llcc_probe(struct platform_device *pdev,
|
||||
const struct llcc_slice_config *llcc_cfg, u32 sz)
|
||||
static int qcom_llcc_probe(struct platform_device *pdev)
|
||||
{
|
||||
u32 num_banks;
|
||||
struct device *dev = &pdev->dev;
|
||||
int ret, i;
|
||||
struct platform_device *llcc_edac;
|
||||
const struct qcom_llcc_config *cfg;
|
||||
const struct llcc_slice_config *llcc_cfg;
|
||||
u32 sz;
|
||||
|
||||
drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL);
|
||||
if (!drv_data) {
|
||||
@ -383,6 +484,10 @@ static int qcom_llcc_probe(struct platform_device *pdev,
|
||||
num_banks >>= LLCC_LB_CNT_SHIFT;
|
||||
drv_data->num_banks = num_banks;
|
||||
|
||||
cfg = of_device_get_match_data(&pdev->dev);
|
||||
llcc_cfg = cfg->sct_data;
|
||||
sz = cfg->size;
|
||||
|
||||
for (i = 0; i < sz; i++)
|
||||
if (llcc_cfg[i].slice_id > drv_data->max_slices)
|
||||
drv_data->max_slices = llcc_cfg[i].slice_id;
|
||||
@ -429,30 +534,20 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sdm845_qcom_llcc_remove(struct platform_device *pdev)
|
||||
{
|
||||
return qcom_llcc_remove(pdev);
|
||||
}
|
||||
|
||||
static int sdm845_qcom_llcc_probe(struct platform_device *pdev)
|
||||
{
|
||||
return qcom_llcc_probe(pdev, sdm845_data, ARRAY_SIZE(sdm845_data));
|
||||
}
|
||||
|
||||
static const struct of_device_id sdm845_qcom_llcc_of_match[] = {
|
||||
{ .compatible = "qcom,sdm845-llcc", },
|
||||
static const struct of_device_id qcom_llcc_of_match[] = {
|
||||
{ .compatible = "qcom,sdm845-llcc", .data = &sdm845_cfg },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct platform_driver sdm845_qcom_llcc_driver = {
|
||||
static struct platform_driver qcom_llcc_driver = {
|
||||
.driver = {
|
||||
.name = "sdm845-llcc",
|
||||
.of_match_table = sdm845_qcom_llcc_of_match,
|
||||
.name = "qcom-llcc",
|
||||
.of_match_table = qcom_llcc_of_match,
|
||||
},
|
||||
.probe = sdm845_qcom_llcc_probe,
|
||||
.remove = sdm845_qcom_llcc_remove,
|
||||
.probe = qcom_llcc_probe,
|
||||
.remove = qcom_llcc_remove,
|
||||
};
|
||||
module_platform_driver(sdm845_qcom_llcc_driver);
|
||||
module_platform_driver(qcom_llcc_driver);
|
||||
|
||||
MODULE_DESCRIPTION("QCOM sdm845 LLCC driver");
|
||||
MODULE_DESCRIPTION("Qualcomm Last Level Cache Controller");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@ -37,95 +37,6 @@ struct llcc_slice_desc {
|
||||
size_t slice_size;
|
||||
};
|
||||
|
||||
/**
|
||||
* llcc_slice_config - Data associated with the llcc slice
|
||||
* @usecase_id: Unique id for the client's use case
|
||||
* @slice_id: llcc slice id for each client
|
||||
* @max_cap: The maximum capacity of the cache slice provided in KB
|
||||
* @priority: Priority of the client used to select victim line for replacement
|
||||
* @fixed_size: Boolean indicating if the slice has a fixed capacity
|
||||
* @bonus_ways: Bonus ways are additional ways to be used for any slice,
|
||||
* if client ends up using more than reserved cache ways. Bonus
|
||||
* ways are allocated only if they are not reserved for some
|
||||
* other client.
|
||||
* @res_ways: Reserved ways for the cache slice, the reserved ways cannot
|
||||
* be used by any other client than the one its assigned to.
|
||||
* @cache_mode: Each slice operates as a cache, this controls the mode of the
|
||||
* slice: normal or TCM(Tightly Coupled Memory)
|
||||
* @probe_target_ways: Determines what ways to probe for access hit. When
|
||||
* configured to 1 only bonus and reserved ways are probed.
|
||||
* When configured to 0 all ways in llcc are probed.
|
||||
* @dis_cap_alloc: Disable capacity based allocation for a client
|
||||
* @retain_on_pc: If this bit is set and client has maintained active vote
|
||||
* then the ways assigned to this client are not flushed on power
|
||||
* collapse.
|
||||
* @activate_on_init: Activate the slice immediately after it is programmed
|
||||
*/
|
||||
struct llcc_slice_config {
|
||||
u32 usecase_id;
|
||||
u32 slice_id;
|
||||
u32 max_cap;
|
||||
u32 priority;
|
||||
bool fixed_size;
|
||||
u32 bonus_ways;
|
||||
u32 res_ways;
|
||||
u32 cache_mode;
|
||||
u32 probe_target_ways;
|
||||
bool dis_cap_alloc;
|
||||
bool retain_on_pc;
|
||||
bool activate_on_init;
|
||||
};
|
||||
|
||||
/**
|
||||
* llcc_drv_data - Data associated with the llcc driver
|
||||
* @regmap: regmap associated with the llcc device
|
||||
* @bcast_regmap: regmap associated with llcc broadcast offset
|
||||
* @cfg: pointer to the data structure for slice configuration
|
||||
* @lock: mutex associated with each slice
|
||||
* @cfg_size: size of the config data table
|
||||
* @max_slices: max slices as read from device tree
|
||||
* @num_banks: Number of llcc banks
|
||||
* @bitmap: Bit map to track the active slice ids
|
||||
* @offsets: Pointer to the bank offsets array
|
||||
* @ecc_irq: interrupt for llcc cache error detection and reporting
|
||||
*/
|
||||
struct llcc_drv_data {
|
||||
struct regmap *regmap;
|
||||
struct regmap *bcast_regmap;
|
||||
const struct llcc_slice_config *cfg;
|
||||
struct mutex lock;
|
||||
u32 cfg_size;
|
||||
u32 max_slices;
|
||||
u32 num_banks;
|
||||
unsigned long *bitmap;
|
||||
u32 *offsets;
|
||||
int ecc_irq;
|
||||
};
|
||||
|
||||
/**
|
||||
* llcc_edac_reg_data - llcc edac registers data for each error type
|
||||
* @name: Name of the error
|
||||
* @synd_reg: Syndrome register address
|
||||
* @count_status_reg: Status register address to read the error count
|
||||
* @ways_status_reg: Status register address to read the error ways
|
||||
* @reg_cnt: Number of registers
|
||||
* @count_mask: Mask value to get the error count
|
||||
* @ways_mask: Mask value to get the error ways
|
||||
* @count_shift: Shift value to get the error count
|
||||
* @ways_shift: Shift value to get the error ways
|
||||
*/
|
||||
struct llcc_edac_reg_data {
|
||||
char *name;
|
||||
u64 synd_reg;
|
||||
u64 count_status_reg;
|
||||
u64 ways_status_reg;
|
||||
u32 reg_cnt;
|
||||
u32 count_mask;
|
||||
u32 ways_mask;
|
||||
u8 count_shift;
|
||||
u8 ways_shift;
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_QCOM_LLCC)
|
||||
/**
|
||||
* llcc_slice_getd - get llcc slice descriptor
|
||||
|
Loading…
Reference in New Issue
Block a user