summaryrefslogtreecommitdiff
path: root/mali_pixel
diff options
context:
space:
mode:
Diffstat (limited to 'mali_pixel')
-rw-r--r--mali_pixel/memory_group_manager.c8
-rw-r--r--mali_pixel/pixel_slc.c45
-rw-r--r--mali_pixel/pixel_slc.h8
3 files changed, 60 insertions, 1 deletions
diff --git a/mali_pixel/memory_group_manager.c b/mali_pixel/memory_group_manager.c
index 03c6f74..81abfb4 100644
--- a/mali_pixel/memory_group_manager.c
+++ b/mali_pixel/memory_group_manager.c
@@ -533,6 +533,14 @@ static vm_fault_t mgm_vmf_insert_pfn_prot(
return fault;
}
+void pixel_mgm_slc_update_signal(struct memory_group_manager_device* mgm_dev, u64 signal)
+{
+ struct mgm_groups *const data = mgm_dev->data;
+
+ slc_update_signal(&data->slc_data, signal);
+}
+EXPORT_SYMBOL_GPL(pixel_mgm_slc_update_signal);
+
void pixel_mgm_slc_inc_refcount(struct memory_group_manager_device* mgm_dev)
{
struct mgm_groups *const data = mgm_dev->data;
diff --git a/mali_pixel/pixel_slc.c b/mali_pixel/pixel_slc.c
index 78f1b74..f06d495 100644
--- a/mali_pixel/pixel_slc.c
+++ b/mali_pixel/pixel_slc.c
@@ -6,11 +6,13 @@
*/
#include <linux/atomic.h>
+#include <linux/io.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/dev_printk.h>
/* Pixel integration includes */
+#include <soc/google/acpm_ipc_ctrl.h>
#include "pixel_slc.h"
@@ -38,6 +40,7 @@
#define PBHA_BIT_MASK (0xf)
#define PARTITION_DISABLE_HYSTERESIS (msecs_to_jiffies(100))
+#define PARTITION_ENABLE_THRESHOLD (7)
/**
@@ -53,7 +56,7 @@ static bool partition_required(struct slc_partition *pt)
{
lockdep_assert_held(&pt->lock);
- return atomic_read(&pt->refcount);
+ return atomic_read(&pt->refcount) && (pt->signal >= PARTITION_ENABLE_THRESHOLD);
}
/**
@@ -225,6 +228,29 @@ void slc_dec_refcount(struct slc_data *data)
}
}
+void slc_update_signal(struct slc_data *data, u64 signal)
+{
+ struct slc_partition *pt = &data->partition;
+ unsigned long flags;
+
+ spin_lock_irqsave(&pt->lock, flags);
+
+ /* Use ACPM signal when available */
+ if (data->signal)
+ pt->signal = ioread64((u64 __iomem*)data->signal);
+ else
+ pt->signal = signal;
+
+ if (partition_required(pt))
+ /* Enable the partition immediately if it's required */
+ enable_partition(data, pt);
+ else
+ /* Lazily disable the partition if it's no longer required */
+ queue_disable_worker(data);
+
+ spin_unlock_irqrestore(&pt->lock, flags);
+}
+
/**
* init_partition - Register and initialize a partition with the SLC driver.
*
@@ -264,6 +290,7 @@ static int init_partition(struct slc_data *data, struct slc_partition *pt, u32 i
.pbha = pbha,
.enabled = false,
.refcount = ATOMIC_INIT(0),
+ .signal = 0,
};
spin_lock_init(&pt->lock);
@@ -316,6 +343,22 @@ int slc_init_data(struct slc_data *data, struct device* dev)
goto err_exit;
}
+ if (IS_ENABLED(PIXEL_GPU_SLC_ACPM_SIGNAL)) {
+ u32 size;
+
+ /* Obtain a handle to the ACPM provided GPU partition signal */
+ if ((ret = acpm_ipc_get_buffer("GPU_SIGNAL", &data->signal, &size))) {
+ dev_err(data->dev, "failed to retrieve SLC GPU signal: %d", ret);
+ goto err_exit;
+ }
+
+ /* Validate the signal buffer size */
+ if (size != sizeof(u64)) {
+ dev_err(data->dev, "SLC GPU signal size incorrect: %d", size);
+ goto err_exit;
+ }
+ }
+
if ((ret = init_partition(data, &data->partition, 0)))
goto pt_init_err_exit;
diff --git a/mali_pixel/pixel_slc.h b/mali_pixel/pixel_slc.h
index bcaf1ff..1ac3da4 100644
--- a/mali_pixel/pixel_slc.h
+++ b/mali_pixel/pixel_slc.h
@@ -51,6 +51,9 @@ struct slc_partition {
/** @lock: Lock protecting enable/disable ops on this partition */
spinlock_t lock;
+
+ /** @signal: Partition enable/disable signal from SLC governor */
+ u64 signal;
};
/**
@@ -68,6 +71,9 @@ struct slc_data {
/** @disable_work: Work item used to queue lazy SLC partition disable ops. */
struct delayed_work disable_work;
+
+ /** @signal: Partition enable/disable signal from SLC governor. */
+ char __iomem *signal;
};
int slc_init_data(struct slc_data *data, struct device* dev);
@@ -82,4 +88,6 @@ void slc_inc_refcount(struct slc_data *data);
void slc_dec_refcount(struct slc_data *data);
+void slc_update_signal(struct slc_data *data, u64 signal);
+
#endif /* _PIXEL_SLC_H_ */