Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a8182394 authored by Naveen Ramaraj's avatar Naveen Ramaraj Committed by Stephen Boyd
Browse files

msm: ocmem: Add support for low power clients



Add support for low power clients to map and unmap OCMEM buffers.
These operations trigger RDM transfers using the BR/DM core which
enables low power clients to migrate segments between main memory and
OCMEM.

Also add the required APIs for supporting eviction and
restoration of buffers.

Change-Id: I6b641510f8ef27da2b347d13af468a1ed6664c9e
Signed-off-by: default avatarNaveen Ramaraj <nramaraj@codeaurora.org>
parent 7b465805
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -482,7 +482,7 @@

		partition@E0000 {
			reg = <0x120000 0x20000>;
			qcom,ocmem-part-name = "blast";
			qcom,ocmem-part-name = "other_os";
			qcom,ocmem-part-min = <0x20000>;
		};

+1 −1
Original line number Diff line number Diff line
@@ -339,7 +339,7 @@ ifdef CONFIG_VCM
obj-$(CONFIG_ARCH_MSM8X60) += board-msm8x60-vcm.o
endif
obj-$(CONFIG_MSM_OCMEM) += ocmem.o ocmem_allocator.o ocmem_notifier.o
obj-$(CONFIG_MSM_OCMEM) += ocmem_sched.o ocmem_api.o
obj-$(CONFIG_MSM_OCMEM) += ocmem_sched.o ocmem_api.o ocmem_rdm.o

obj-$(CONFIG_ARCH_MSM7X27) += gpiomux-7x27.o gpiomux-v1.o gpiomux.o
obj-$(CONFIG_ARCH_MSM7X30) += gpiomux-7x30.o gpiomux-v1.o gpiomux.o
+9 −4
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@

/* Maximum number of slots in DM */
#define OCMEM_MAX_CHUNKS 32
#define MIN_CHUNK_SIZE (SZ_1K/8)
#define MIN_CHUNK_SIZE 128

struct ocmem_notifier;

@@ -61,7 +61,7 @@ enum ocmem_client {
	/* IMEM Clients */
	OCMEM_LP_AUDIO,
	OCMEM_SENSORS,
	OCMEM_BLAST,
	OCMEM_OTHER_OS,
	OCMEM_CLIENT_MAX,
};

@@ -108,8 +108,13 @@ int ocmem_free(int client_id, struct ocmem_buf *buf);
int ocmem_shrink(int client_id, struct ocmem_buf *buf,
			unsigned long new_size);

int ocmem_expand(int client_id, struct ocmem_buf *buf,
			unsigned long new_size);
/* Transfer APIs */
int ocmem_map(int client_id, struct ocmem_buf *buffer,
			struct ocmem_map_list *list);


int ocmem_unmap(int client_id, struct ocmem_buf *buffer,
			struct ocmem_map_list *list);

/* Priority Enforcement APIs */
int ocmem_evict(int client_id);
+26 −5
Original line number Diff line number Diff line
@@ -20,12 +20,13 @@
#include "ocmem.h"
#include <mach/msm_iomap.h>
#include <asm/io.h>
#include <linux/platform_device.h>

#define OCMEM_PHYS_BASE 0xFEC00000
#define OCMEM_PHYS_SIZE 0x180000

#define TO_OCMEM 0x1
#define TO_DDR 0x2
#define TO_OCMEM 0x0
#define TO_DDR 0x1

struct ocmem_zone;

@@ -38,7 +39,7 @@ struct ocmem_zone {
	int owner;
	int active_regions;
	int max_regions;
	struct list_head region_list;
	struct list_head req_list;
	unsigned long z_start;
	unsigned long z_end;
	unsigned long z_head;
@@ -78,12 +79,24 @@ struct ocmem_plat_data {
	bool interleaved;
};

struct ocmem_eviction_data {
	struct completion completion;
	struct list_head victim_list;
	struct list_head req_list;
	struct work_struct work;
	int prio;
	int pending;
	bool passive;
};

struct ocmem_req {
	struct rw_semaphore rw_sem;
	/* Chain in sched queue */
	struct list_head sched_list;
	/* Chain in zone list */
	struct list_head zone_list;
	/* Chain in eviction list */
	struct list_head eviction_list;
	int owner;
	int prio;
	uint32_t req_id;
@@ -100,6 +113,7 @@ struct ocmem_req {
	unsigned long req_start;
	unsigned long req_end;
	unsigned long req_sz;
	struct ocmem_eviction_data *edata;
};

struct ocmem_handle {
@@ -150,13 +164,20 @@ int free_tail(struct ocmem_zone *, unsigned long, unsigned long);

int ocmem_notifier_init(void);
int check_notifier(int);
const char *get_name(int);
int check_id(int);
int dispatch_notification(int, enum ocmem_notif_type, struct ocmem_buf *);

int ocmem_sched_init(void);
int ocmem_rdm_init(struct platform_device *);
int process_allocate(int, struct ocmem_handle *, unsigned long, unsigned long,
			unsigned long, bool, bool);
int process_free(int, struct ocmem_handle *);
int process_xfer(int, struct ocmem_handle *, struct ocmem_map_list *,
			int direction);
int process_xfer(int, struct ocmem_handle *, struct ocmem_map_list *, int);
int process_evict(int);
int process_restore(int);
int process_shrink(int, struct ocmem_handle *, unsigned long);
int ocmem_rdm_transfer(int, struct ocmem_map_list *,
				unsigned long, int);
unsigned long process_quota(int);
#endif
+20 −3
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ struct ocmem_zone *get_zone(unsigned id)
static struct ocmem_plat_data *ocmem_pdata;

#define CLIENT_NAME_MAX 10

/* Must be in sync with enum ocmem_client */
static const char *client_names[OCMEM_CLIENT_MAX] = {
	"graphics",
@@ -64,7 +65,7 @@ static const char *client_names[OCMEM_CLIENT_MAX] = {
	"voice",
	"lp_audio",
	"sensors",
	"blast",
	"other_os",
};

struct ocmem_quota_table {
@@ -85,7 +86,7 @@ static struct ocmem_quota_table qt[OCMEM_CLIENT_MAX] = {
	{ "voice", OCMEM_VOICE,  0x0, 0x0, 0x0, 0 },
	{ "hp_audio", OCMEM_HP_AUDIO, 0x0, 0x0, 0x0, 0},
	{ "lp_audio", OCMEM_LP_AUDIO, 0x80000, 0xA0000, 0xA0000, 0},
	{ "blast", OCMEM_BLAST, 0x120000, 0x20000, 0x20000, 0},
	{ "other_os", OCMEM_OTHER_OS, 0x120000, 0x20000, 0x20000, 0},
	{ "sensors", OCMEM_SENSORS, 0x140000, 0x40000, 0x40000, 0},
};

@@ -99,6 +100,18 @@ static inline int get_id(const char *name)
	return -EINVAL;
}

int check_id(int id)
{
	return (id < OCMEM_CLIENT_MAX && id >= OCMEM_GRAPHICS);
}

const char *get_name(int id)
{
	if (!check_id(id))
		return NULL;
	return client_names[id];
}

inline unsigned long phys_to_offset(unsigned long addr)
{
	if (!ocmem_pdata)
@@ -455,7 +468,7 @@ static int ocmem_zone_init(struct platform_device *pdev)
		zone->owner = part->id;
		zone->active_regions = 0;
		zone->max_regions = 0;
		INIT_LIST_HEAD(&zone->region_list);
		INIT_LIST_HEAD(&zone->req_list);
		zone->z_ops = z_ops;
		if (part->p_tail) {
			z_ops->allocate = allocate_tail;
@@ -519,6 +532,10 @@ static int msm_ocmem_probe(struct platform_device *pdev)
	writel_relaxed(REGION_ENABLE, ocmem_region_vbase);
	writel_relaxed(REGION_ENABLE, ocmem_region_vbase + 4);
	writel_relaxed(REGION_ENABLE, ocmem_region_vbase + 8);

	if (ocmem_rdm_init(pdev))
		return -EBUSY;

	dev_dbg(dev, "initialized successfully\n");
	return 0;
}
Loading