mirror of
https://github.com/torvalds/linux.git
synced 2026-07-31 19:47:08 +02:00
soc: qcom: llcc: Introduce APIs to support staling mode
Staling mode (Capacity-based or notification-based) is a new feature that allows for clients to influence cache replacement for their sub-cache in real time. Introducing two new APIs: - llcc_configure_staling_mode() allows for clients to configure the staling mode and specify mode-specific parameters such as the staling distance for the notification-based mode. - llcc_notif_staling_inc_counter() increments the frame staling counter that ultimately marks previously cached memory at a user-configurable frame distance for eviction. Change-Id: Ied032cd0bead377e294b568a73a713e61159ac2c Signed-off-by: Guru Das Srinagesh <quic_gurus@quicinc.com>
This commit is contained in:
parent
8c05b73745
commit
2e4da2653a
|
|
@ -47,6 +47,14 @@
|
|||
#define LLCC_TRP_ACT_CTRLn(n) (n * SZ_4K)
|
||||
#define LLCC_TRP_ACT_CLEARn(n) (8 + n * SZ_4K)
|
||||
#define LLCC_TRP_STATUSn(n) (4 + n * SZ_4K)
|
||||
|
||||
#define LLCC_TRP_STAL_ATTR0_CFGn(n) (0xC + SZ_4K * n)
|
||||
#define STALING_TRIGGER_MASK 0x1
|
||||
|
||||
#define LLCC_TRP_STAL_ATTR1_CFGn(n) (0x10 + SZ_4K * n)
|
||||
#define STALING_ENABLE_MASK 0x1
|
||||
#define STALING_NUM_FRAMES_MASK GENMASK(6, 4)
|
||||
|
||||
#define LLCC_TRP_ATTR0_CFGn(n) (0x21000 + SZ_8 * n)
|
||||
#define LLCC_TRP_ATTR1_CFGn(n) (0x21004 + SZ_8 * n)
|
||||
#define LLCC_TRP_ATTR2_CFGn(n) (0x21100 + SZ_4 * n)
|
||||
|
|
@ -678,6 +686,120 @@ size_t llcc_get_slice_size(struct llcc_slice_desc *desc)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(llcc_get_slice_size);
|
||||
|
||||
static int llcc_staling_conf_capacity(u32 sid, struct llcc_staling_mode_params *p)
|
||||
{
|
||||
u32 notif_staling_reg;
|
||||
|
||||
notif_staling_reg = LLCC_TRP_STAL_ATTR1_CFGn(sid);
|
||||
|
||||
return regmap_update_bits(drv_data->bcast_regmap, notif_staling_reg,
|
||||
STALING_ENABLE_MASK,
|
||||
LLCC_STALING_MODE_CAPACITY);
|
||||
}
|
||||
|
||||
static int llcc_staling_conf_notify(u32 sid, struct llcc_staling_mode_params *p)
|
||||
{
|
||||
u32 notif_staling_reg, staling_distance;
|
||||
int ret;
|
||||
|
||||
if (p->notify_params.op != LLCC_NOTIFY_STALING_WRITEBACK)
|
||||
return -EINVAL;
|
||||
|
||||
notif_staling_reg = LLCC_TRP_STAL_ATTR1_CFGn(sid);
|
||||
|
||||
ret = regmap_update_bits(drv_data->bcast_regmap, notif_staling_reg,
|
||||
STALING_ENABLE_MASK,
|
||||
LLCC_STALING_MODE_NOTIFY);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
staling_distance = p->notify_params.staling_distance;
|
||||
|
||||
return regmap_update_bits(drv_data->bcast_regmap, notif_staling_reg,
|
||||
STALING_NUM_FRAMES_MASK, staling_distance);
|
||||
}
|
||||
|
||||
static int (*staling_mode_ops[LLCC_STALING_MODE_MAX])(u32, struct llcc_staling_mode_params *) = {
|
||||
[LLCC_STALING_MODE_CAPACITY] = llcc_staling_conf_capacity,
|
||||
[LLCC_STALING_MODE_NOTIFY] = llcc_staling_conf_notify,
|
||||
};
|
||||
|
||||
/**
|
||||
* llcc_configure_staling_mode - Configure cache staling mode by setting the
|
||||
* staling_mode and corresponding
|
||||
* mode-specific params
|
||||
*
|
||||
* @desc: Pointer to llcc slice descriptor
|
||||
* @p: Staling mode-specific params
|
||||
*
|
||||
* Returns: zero on success or negative errno.
|
||||
*/
|
||||
int llcc_configure_staling_mode(struct llcc_slice_desc *desc,
|
||||
struct llcc_staling_mode_params *p)
|
||||
|
||||
{
|
||||
u32 sid;
|
||||
enum llcc_staling_mode m;
|
||||
|
||||
if (IS_ERR(drv_data))
|
||||
return PTR_ERR(drv_data);
|
||||
|
||||
if (drv_data->llcc_ver < 50)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (IS_ERR_OR_NULL(desc) || !p)
|
||||
return -EINVAL;
|
||||
|
||||
sid = desc->slice_id;
|
||||
m = p->staling_mode;
|
||||
|
||||
/*
|
||||
* Look up op corresponding to staling mode and call it
|
||||
* with the params passed
|
||||
*/
|
||||
return (*staling_mode_ops[m])(sid, p);
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(llcc_configure_staling_mode);
|
||||
|
||||
/**
|
||||
* llcc_notif_staling_inc_counter - Trigger the staling of the sub-cache frame.
|
||||
*
|
||||
* @desc: Pointer to llcc slice descriptor
|
||||
*
|
||||
* Returns: zero on success or negative errno.
|
||||
*/
|
||||
int llcc_notif_staling_inc_counter(struct llcc_slice_desc *desc)
|
||||
{
|
||||
u32 sid, stale_trigger_reg, discard;
|
||||
int ret;
|
||||
|
||||
if (IS_ERR(drv_data))
|
||||
return PTR_ERR(drv_data);
|
||||
|
||||
if (drv_data->llcc_ver < 50)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (IS_ERR_OR_NULL(desc))
|
||||
return -EINVAL;
|
||||
|
||||
sid = desc->slice_id;
|
||||
stale_trigger_reg = LLCC_TRP_STAL_ATTR0_CFGn(sid);
|
||||
|
||||
ret = regmap_update_bits(drv_data->bcast_regmap, stale_trigger_reg,
|
||||
STALING_TRIGGER_MASK, STALING_TRIGGER_MASK);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* stale_trigger_reg is a self-clearing reg. Read it anyway to ensure
|
||||
* that the write went through. We don't care about the value being
|
||||
* read, so discard it.
|
||||
*/
|
||||
return regmap_read(drv_data->bcast_regmap, stale_trigger_reg, &discard);
|
||||
}
|
||||
EXPORT_SYMBOL(llcc_notif_staling_inc_counter);
|
||||
|
||||
static int qcom_llcc_cfg_program(struct platform_device *pdev)
|
||||
{
|
||||
int i;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
|
|
@ -124,6 +124,32 @@ struct llcc_drv_data {
|
|||
struct llcc_slice_desc *desc;
|
||||
};
|
||||
|
||||
/**
|
||||
* Enum describing the various staling modes available for clients to use.
|
||||
*/
|
||||
enum llcc_staling_mode {
|
||||
LLCC_STALING_MODE_CAPACITY, /* Default option on reset */
|
||||
LLCC_STALING_MODE_NOTIFY,
|
||||
LLCC_STALING_MODE_MAX
|
||||
};
|
||||
|
||||
enum llcc_staling_notify_op {
|
||||
LLCC_NOTIFY_STALING_WRITEBACK,
|
||||
/* LLCC_NOTIFY_STALING_NO_WRITEBACK, */
|
||||
LLCC_NOTIFY_STALING_OPS_MAX
|
||||
};
|
||||
|
||||
struct llcc_staling_mode_params {
|
||||
enum llcc_staling_mode staling_mode;
|
||||
union {
|
||||
/* STALING_MODE_CAPACITY needs no params */
|
||||
struct staling_mode_notify_params {
|
||||
u8 staling_distance;
|
||||
enum llcc_staling_notify_op op;
|
||||
} notify_params;
|
||||
};
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_QCOM_LLCC)
|
||||
/**
|
||||
* llcc_slice_getd - get llcc slice descriptor
|
||||
|
|
@ -161,6 +187,26 @@ int llcc_slice_activate(struct llcc_slice_desc *desc);
|
|||
*/
|
||||
int llcc_slice_deactivate(struct llcc_slice_desc *desc);
|
||||
|
||||
/**
|
||||
* llcc_configure_staling_mode - Configure cache staling mode by setting the
|
||||
* staling_mode and corresponding
|
||||
* mode-specific params
|
||||
*
|
||||
* @desc: Pointer to llcc slice descriptor
|
||||
* @p: Staling mode-specific params
|
||||
*
|
||||
* Returns: zero on success or negative errno.
|
||||
*/
|
||||
int llcc_configure_staling_mode(struct llcc_slice_desc *desc,
|
||||
struct llcc_staling_mode_params *p);
|
||||
/**
|
||||
* llcc_notif_staling_inc_counter - Trigger the staling of the sub-cache frame.
|
||||
*
|
||||
* @desc: Pointer to llcc slice descriptor
|
||||
*
|
||||
* Returns: zero on success or negative errno.
|
||||
*/
|
||||
int llcc_notif_staling_inc_counter(struct llcc_slice_desc *desc);
|
||||
#else
|
||||
static inline struct llcc_slice_desc *llcc_slice_getd(u32 uid)
|
||||
{
|
||||
|
|
@ -190,6 +236,15 @@ static inline int llcc_slice_deactivate(struct llcc_slice_desc *desc)
|
|||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
static int llcc_configure_staling_mode(struct llcc_slice_desc *desc,
|
||||
struct llcc_staling_mode_params *p)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
static inline int llcc_notif_staling_inc_counter(struct llcc_slice_desc *desc)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user