All of lore.kernel.org
 help / color / mirror / Atom feed
From: Rob Clark <robdclark@gmail.com>
To: dri-devel@lists.freedesktop.org, linux-arm-msm@vger.kernel.org
Cc: Bjorn Andersson <bjorn.andersson@sonymobile.com>,
	Stephen Boyd <sboyd@codeaurora.org>,
	Rob Clark <robdclark@gmail.com>
Subject: [PATCH 6/6] drm/msm: add OCMEM driver
Date: Tue, 29 Sep 2015 15:48:58 -0400	[thread overview]
Message-ID: <1443556138-21085-7-git-send-email-robdclark@gmail.com> (raw)
In-Reply-To: <1443556138-21085-1-git-send-email-robdclark@gmail.com>

For now, since the GPU is the only upstream consumer, just stuff this
into drm/msm.  Eventually if we have other consumers, we'll have to
split this out and make the allocation less hard coded.  But I'll punt
on that until I better understand the non-gpu uses-cases (and whether
the allocation *really* needs to be as complicated as it is in the
downstream driver).

Signed-off-by: Rob Clark <robdclark@gmail.com>
---
 drivers/gpu/drm/msm/Makefile          |   3 +-
 drivers/gpu/drm/msm/adreno/a3xx_gpu.c |  19 +-
 drivers/gpu/drm/msm/adreno/a4xx_gpu.c |  19 +-
 drivers/gpu/drm/msm/msm_drv.c         |   2 +
 drivers/gpu/drm/msm/msm_gpu.h         |   3 +
 drivers/gpu/drm/msm/ocmem/ocmem.c     | 399 ++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/msm/ocmem/ocmem.h     |  46 ++++
 7 files changed, 463 insertions(+), 28 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/ocmem/ocmem.c
 create mode 100644 drivers/gpu/drm/msm/ocmem/ocmem.h

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 0a543eb..8ddf6fa 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -48,7 +48,8 @@ msm-y := \
 	msm_iommu.o \
 	msm_perf.o \
 	msm_rd.o \
-	msm_ringbuffer.o
+	msm_ringbuffer.o \
+	ocmem/ocmem.o
 
 msm-$(CONFIG_DRM_MSM_FBDEV) += msm_fbdev.o
 msm-$(CONFIG_COMMON_CLK) += mdp/mdp4/mdp4_lvds_pll.o
diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
index ca29688..2a8bf4c 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
@@ -17,10 +17,7 @@
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifdef CONFIG_MSM_OCMEM
-#  include <mach/ocmem.h>
-#endif
-
+#include "ocmem/ocmem.h"
 #include "a3xx_gpu.h"
 
 #define A3XX_INT0_MASK \
@@ -322,10 +319,8 @@ static void a3xx_destroy(struct msm_gpu *gpu)
 
 	adreno_gpu_cleanup(adreno_gpu);
 
-#ifdef CONFIG_MSM_OCMEM
-	if (a3xx_gpu->ocmem_base)
+	if (a3xx_gpu->ocmem_hdl)
 		ocmem_free(OCMEM_GRAPHICS, a3xx_gpu->ocmem_hdl);
-#endif
 
 	kfree(a3xx_gpu);
 }
@@ -539,6 +534,7 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev)
 	struct msm_gpu *gpu;
 	struct msm_drm_private *priv = dev->dev_private;
 	struct platform_device *pdev = priv->gpu_pdev;
+	struct ocmem_buf *ocmem_hdl;
 	int ret;
 
 	if (!pdev) {
@@ -569,18 +565,13 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev)
 		goto fail;
 
 	/* if needed, allocate gmem: */
-	if (adreno_is_a330(adreno_gpu)) {
-#ifdef CONFIG_MSM_OCMEM
-		/* TODO this is different/missing upstream: */
-		struct ocmem_buf *ocmem_hdl =
-				ocmem_allocate(OCMEM_GRAPHICS, adreno_gpu->gmem);
-
+	ocmem_hdl = ocmem_allocate(OCMEM_GRAPHICS, adreno_gpu->gmem);
+	if (!IS_ERR(ocmem_hdl)) {
 		a3xx_gpu->ocmem_hdl = ocmem_hdl;
 		a3xx_gpu->ocmem_base = ocmem_hdl->addr;
 		adreno_gpu->gmem = ocmem_hdl->len;
 		DBG("using %dK of OCMEM at 0x%08x", adreno_gpu->gmem / 1024,
 				a3xx_gpu->ocmem_base);
-#endif
 	}
 
 	if (!gpu->mmu) {
diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
index a53f1be..17f084d 100644
--- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
@@ -10,10 +10,9 @@
  * GNU General Public License for more details.
  *
  */
+
+#include "ocmem/ocmem.h"
 #include "a4xx_gpu.h"
-#ifdef CONFIG_MSM_OCMEM
-#  include <soc/qcom/ocmem.h>
-#endif
 
 #define A4XX_INT0_MASK \
 	(A4XX_INT0_RBBM_AHB_ERROR |        \
@@ -289,10 +288,8 @@ static void a4xx_destroy(struct msm_gpu *gpu)
 
 	adreno_gpu_cleanup(adreno_gpu);
 
-#ifdef CONFIG_MSM_OCMEM
-	if (a4xx_gpu->ocmem_base)
+	if (a4xx_gpu->ocmem_hdl)
 		ocmem_free(OCMEM_GRAPHICS, a4xx_gpu->ocmem_hdl);
-#endif
 
 	kfree(a4xx_gpu);
 }
@@ -538,6 +535,7 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev)
 	struct msm_gpu *gpu;
 	struct msm_drm_private *priv = dev->dev_private;
 	struct platform_device *pdev = priv->gpu_pdev;
+	struct ocmem_buf *ocmem_hdl;
 	int ret;
 
 	if (!pdev) {
@@ -568,18 +566,13 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev)
 		goto fail;
 
 	/* if needed, allocate gmem: */
-	if (adreno_is_a4xx(adreno_gpu)) {
-#ifdef CONFIG_MSM_OCMEM
-		/* TODO this is different/missing upstream: */
-		struct ocmem_buf *ocmem_hdl =
-				ocmem_allocate(OCMEM_GRAPHICS, adreno_gpu->gmem);
-
+	ocmem_hdl = ocmem_allocate(OCMEM_GRAPHICS, adreno_gpu->gmem);
+	if (!IS_ERR(ocmem_hdl)) {
 		a4xx_gpu->ocmem_hdl = ocmem_hdl;
 		a4xx_gpu->ocmem_base = ocmem_hdl->addr;
 		adreno_gpu->gmem = ocmem_hdl->len;
 		DBG("using %dK of OCMEM at 0x%08x", adreno_gpu->gmem / 1024,
 				a4xx_gpu->ocmem_base);
-#endif
 	}
 
 	if (!gpu->mmu) {
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 28c9a2a..1b02c2d 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -1165,6 +1165,7 @@ static int __init msm_drm_register(void)
 	msm_dsi_register();
 	msm_edp_register();
 	hdmi_register();
+	ocmem_register();
 	adreno_register();
 	return platform_driver_register(&msm_platform_driver);
 }
@@ -1175,6 +1176,7 @@ static void __exit msm_drm_unregister(void)
 	platform_driver_unregister(&msm_platform_driver);
 	hdmi_unregister();
 	adreno_unregister();
+	ocmem_unregister();
 	msm_edp_unregister();
 	msm_dsi_unregister();
 }
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index 2bbe85a..f042ba8 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -172,4 +172,7 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev);
 void __init adreno_register(void);
 void __exit adreno_unregister(void);
 
+void __init ocmem_register(void);
+void __exit ocmem_unregister(void);
+
 #endif /* __MSM_GPU_H__ */
diff --git a/drivers/gpu/drm/msm/ocmem/ocmem.c b/drivers/gpu/drm/msm/ocmem/ocmem.c
new file mode 100644
index 0000000..535d9f7
--- /dev/null
+++ b/drivers/gpu/drm/msm/ocmem/ocmem.c
@@ -0,0 +1,399 @@
+/*
+ * Copyright (C) 2015 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/qcom_scm.h>
+#include <linux/of_device.h>
+
+#include "msm_drv.h"
+#include "ocmem.h"
+#include "ocmem.xml.h"
+
+enum region_mode {
+	WIDE_MODE = 0x0,
+	THIN_MODE,
+	MODE_DEFAULT = WIDE_MODE,
+};
+
+enum ocmem_tz_client {
+	TZ_UNUSED = 0x0,
+	TZ_GRAPHICS,
+	TZ_VIDEO,
+	TZ_LP_AUDIO,
+	TZ_SENSORS,
+	TZ_OTHER_OS,
+	TZ_DEBUG,
+};
+
+struct ocmem_region {
+	unsigned psgsc_ctrl;
+	bool interleaved;
+	enum region_mode mode;
+	unsigned int num_macros;
+	enum ocmem_macro_state macro_state[4];
+	unsigned long macro_size;
+	unsigned long region_size;
+};
+
+struct ocmem_config {
+	uint8_t  num_regions;
+	uint32_t macro_size;
+};
+
+struct ocmem {
+	struct device *dev;
+	const struct ocmem_config *config;
+	struct resource *ocmem_mem;
+	struct clk *core_clk;
+	struct clk *iface_clk;
+	void __iomem *mmio;
+
+	unsigned num_ports;
+	unsigned num_macros;
+	bool interleaved;
+
+	struct ocmem_region *regions;
+};
+
+static struct ocmem *ocmem;
+
+static bool ocmem_exists(void);
+
+static inline void ocmem_write(struct ocmem *ocmem, u32 reg, u32 data)
+{
+	msm_writel(data, ocmem->mmio + reg);
+}
+
+static inline u32 ocmem_read(struct ocmem *ocmem, u32 reg)
+{
+	return msm_readl(ocmem->mmio + reg);
+}
+
+static int ocmem_clk_enable(struct ocmem *ocmem)
+{
+	int ret;
+
+	ret = clk_prepare_enable(ocmem->core_clk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(ocmem->iface_clk);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void ocmem_clk_disable(struct ocmem *ocmem)
+{
+	clk_disable_unprepare(ocmem->iface_clk);
+	clk_disable_unprepare(ocmem->core_clk);
+}
+
+static int ocmem_dev_remove(struct platform_device *pdev)
+{
+	ocmem_clk_disable(ocmem);
+	return 0;
+}
+
+static void update_ocmem(struct ocmem *ocmem)
+{
+	uint32_t region_mode_ctrl = 0x0;
+	unsigned pos = 0;
+	unsigned i = 0;
+
+	if (!qcom_scm_ocmem_lock_available()) {
+		for (i = 0; i < ocmem->config->num_regions; i++) {
+			struct ocmem_region *region = &ocmem->regions[i];
+			pos = i << 2;
+			if (region->mode == THIN_MODE)
+				region_mode_ctrl |= BIT(pos);
+		}
+		dev_dbg(ocmem->dev, "ocmem_region_mode_control %x\n", region_mode_ctrl);
+		ocmem_write(ocmem, REG_OCMEM_REGION_MODE_CTL, region_mode_ctrl);
+	}
+
+	for (i = 0; i < ocmem->config->num_regions; i++) {
+		struct ocmem_region *region = &ocmem->regions[i];
+
+		ocmem_write(ocmem, REG_OCMEM_PSGSC_CTL(i),
+				OCMEM_PSGSC_CTL_MACRO0_MODE(region->macro_state[0]) |
+				OCMEM_PSGSC_CTL_MACRO1_MODE(region->macro_state[1]) |
+				OCMEM_PSGSC_CTL_MACRO2_MODE(region->macro_state[2]) |
+				OCMEM_PSGSC_CTL_MACRO3_MODE(region->macro_state[3]));
+	}
+}
+
+static unsigned long phys_to_offset(unsigned long addr)
+{
+	if ((addr < ocmem->ocmem_mem->start) ||
+		(addr >= ocmem->ocmem_mem->end))
+		return 0;
+	return addr - ocmem->ocmem_mem->start;
+}
+
+static unsigned long device_address(enum ocmem_client client, unsigned long addr)
+{
+	/* TODO, gpu uses phys_to_offset, but others do not.. */
+	return phys_to_offset(addr);
+}
+
+static void update_range(struct ocmem *ocmem, struct ocmem_buf *buf,
+		enum ocmem_macro_state mstate, enum region_mode rmode)
+{
+	unsigned long offset = 0;
+	int i, j;
+
+	/*
+	 * TODO probably should assert somewhere that range is aligned
+	 * to macro boundaries..
+	 */
+
+	for (i = 0; i < ocmem->config->num_regions; i++) {
+		struct ocmem_region *region = &ocmem->regions[i];
+		if ((buf->offset <= offset) && (offset < (buf->offset + buf->len)))
+			region->mode = rmode;
+		for (j = 0; j < region->num_macros; j++) {
+			if ((buf->offset <= offset) && (offset < (buf->offset + buf->len)))
+				region->macro_state[j] = mstate;
+			offset += region->macro_size;
+		}
+	}
+
+	update_ocmem(ocmem);
+}
+
+struct ocmem_buf *ocmem_allocate(enum ocmem_client client, unsigned long size)
+{
+	struct ocmem_buf *buf;
+
+	if (!ocmem) {
+		if (ocmem_exists())
+			return ERR_PTR(-EPROBE_DEFER);
+		return ERR_PTR(-ENXIO);
+	}
+
+	buf = kzalloc(sizeof(*buf), GFP_KERNEL);
+	if (!buf)
+		return ERR_PTR(-ENOMEM);
+
+	/*
+	 * TODO less hard-coded allocation that works for more than
+	 * one user:
+	 */
+
+	buf->offset = 0;
+	buf->addr = device_address(client, buf->offset);
+	buf->len = size;
+
+	update_range(ocmem, buf, CORE_ON, WIDE_MODE);
+
+	if (qcom_scm_ocmem_lock_available()) {
+		int ret;
+		ret = qcom_scm_ocmem_lock(TZ_GRAPHICS, buf->offset, buf->len,
+				WIDE_MODE);
+		if (ret)
+			dev_err(ocmem->dev, "could not lock: %d\n", ret);
+	} else {
+		if (client == OCMEM_GRAPHICS) {
+			ocmem_write(ocmem, REG_OCMEM_GFX_MPU_START, buf->offset);
+			ocmem_write(ocmem, REG_OCMEM_GFX_MPU_END, buf->offset + buf->len);
+		}
+	}
+
+	return buf;
+}
+
+void ocmem_free(enum ocmem_client client, struct ocmem_buf *buf)
+{
+	update_range(ocmem, buf, CLK_OFF, MODE_DEFAULT);
+
+	if (qcom_scm_ocmem_lock_available()) {
+		int ret;
+		ret = qcom_scm_ocmem_unlock(TZ_GRAPHICS, buf->offset, buf->len);
+		if (ret)
+			dev_err(ocmem->dev, "could not unlock: %d\n", ret);
+	} else {
+		if (client == OCMEM_GRAPHICS) {
+			ocmem_write(ocmem, REG_OCMEM_GFX_MPU_START, 0x0);
+			ocmem_write(ocmem, REG_OCMEM_GFX_MPU_END, 0x0);
+		}
+	}
+
+	kfree(buf);
+}
+
+static const struct ocmem_config ocmem_8974_config = {
+	.num_regions = 3, .macro_size = SZ_128K,
+};
+
+static const struct of_device_id dt_match[] = {
+	{ .compatible = "qcom,ocmem-msm8974", .data = &ocmem_8974_config },
+	{}
+};
+
+static int ocmem_dev_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	const struct ocmem_config *config = NULL;
+	uint32_t reg, num_banks, region_size;
+	const struct of_device_id *match;
+	int i, j, ret;
+
+	/* we need scm to be available: */
+	if (!qcom_scm_is_available())
+		return -EPROBE_DEFER;
+
+	match = of_match_device(dt_match, dev);
+	if (match)
+		config = match->data;
+
+	if (!config) {
+		dev_err(dev, "unknown config: %s\n", dev->of_node->name);
+		return -ENXIO;
+	}
+
+	ocmem = devm_kzalloc(dev, sizeof(*ocmem), GFP_KERNEL);
+	if (!ocmem)
+		return -ENOMEM;
+
+	ocmem->dev = dev;
+	ocmem->config = config;
+
+	ocmem->core_clk = devm_clk_get(dev, "core_clk");
+	if (IS_ERR(ocmem->core_clk)) {
+		dev_err(dev, "Unable to get the core clock\n");
+		return PTR_ERR(ocmem->core_clk);
+	}
+
+	ocmem->iface_clk = devm_clk_get(dev, "iface_clk");
+	if (IS_ERR_OR_NULL(ocmem->iface_clk)) {
+		ret = PTR_ERR(ocmem->iface_clk);
+		ocmem->iface_clk = NULL;
+		/* in probe-defer case, propagate error up and try again later: */
+		if (ret == -EPROBE_DEFER)
+			goto fail;
+	}
+
+	/* The core clock is synchronous with graphics */
+	WARN_ON(clk_set_rate(ocmem->core_clk, 1000) < 0);
+
+	ocmem->mmio = msm_ioremap(pdev, "ocmem_ctrl_physical", "OCMEM");
+	if (IS_ERR(ocmem->mmio))
+		return PTR_ERR(ocmem->mmio);
+
+	ocmem->ocmem_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+			"ocmem_physical");
+	if (!ocmem->ocmem_mem) {
+		dev_err(dev, "could not get OCMEM region\n");
+		return -ENXIO;
+	}
+
+	ret = ocmem_clk_enable(ocmem);
+	if (ret)
+		goto fail;
+
+	if (qcom_scm_ocmem_secure_available()) {
+		dev_dbg(dev, "configuring scm\n");
+		ret = qcom_scm_ocmem_secure_cfg(0x5);
+		if (ret)
+			goto fail;
+	}
+
+	reg = ocmem_read(ocmem, REG_OCMEM_HW_PROFILE);
+	ocmem->num_ports = FIELD(reg, OCMEM_HW_PROFILE_NUM_PORTS);
+	ocmem->num_macros = FIELD(reg, OCMEM_HW_PROFILE_NUM_MACROS);
+	ocmem->interleaved = !!(reg & OCMEM_HW_PROFILE_INTERLEAVING);
+
+	num_banks = ocmem->num_ports / 2;
+	region_size = config->macro_size * num_banks;
+
+	dev_info(dev, "%u ports, %u regions, %u macros, %sinterleaved\n",
+			ocmem->num_ports, config->num_regions, ocmem->num_macros,
+			ocmem->interleaved ? "" : "not ");
+
+	ocmem->regions = devm_kcalloc(dev, config->num_regions,
+			sizeof(struct ocmem_region), GFP_KERNEL);
+	if (!ocmem->regions) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	for (i = 0; i < config->num_regions; i++) {
+		struct ocmem_region *region = &ocmem->regions[i];
+
+		if (WARN_ON(num_banks > ARRAY_SIZE(region->macro_state))) {
+			ret = -EINVAL;
+			goto fail;
+		}
+
+		region->mode = MODE_DEFAULT;
+		region->num_macros = num_banks;
+
+		if ((i == (config->num_regions - 1)) &&
+				(reg & OCMEM_HW_PROFILE_LAST_REGN_HALFSIZE)) {
+			region->macro_size = config->macro_size / 2;
+			region->region_size = region_size / 2;
+		} else {
+			region->macro_size = config->macro_size;
+			region->region_size = region_size;
+		}
+
+		for (j = 0; j < ARRAY_SIZE(region->macro_state); j++)
+			region->macro_state[j] = CLK_OFF;
+	}
+
+	return 0;
+
+fail:
+	dev_err(dev, "probe failed\n");
+	ocmem_dev_remove(pdev);
+	return ret;
+}
+
+static struct platform_driver ocmem_driver = {
+	.probe = ocmem_dev_probe,
+	.remove = ocmem_dev_remove,
+	.driver = {
+		.name = "ocmem",
+		.of_match_table = dt_match,
+	},
+};
+
+static bool ocmem_exists(void)
+{
+	struct device_driver *drv = &ocmem_driver.driver;
+	struct device *d;
+
+	d = bus_find_device(&platform_bus_type, NULL, drv,
+			(void *)platform_bus_type.match);
+	if (d) {
+		put_device(d);
+		return true;
+	}
+
+	return false;
+}
+
+void __init ocmem_register(void)
+{
+	platform_driver_register(&ocmem_driver);
+}
+
+void __exit ocmem_unregister(void)
+{
+	platform_driver_unregister(&ocmem_driver);
+}
diff --git a/drivers/gpu/drm/msm/ocmem/ocmem.h b/drivers/gpu/drm/msm/ocmem/ocmem.h
new file mode 100644
index 0000000..199be98
--- /dev/null
+++ b/drivers/gpu/drm/msm/ocmem/ocmem.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __OCMEM_H__
+#define __OCMEM_H__
+
+enum ocmem_client {
+	/* GMEM clients */
+	OCMEM_GRAPHICS = 0x0,
+	/* TCMEM clients */
+	OCMEM_VIDEO,
+	OCMEM_CAMERA,
+	/* Dummy Clients */
+	OCMEM_HP_AUDIO,
+	OCMEM_VOICE,
+	/* IMEM Clients */
+	OCMEM_LP_AUDIO,
+	OCMEM_SENSORS,
+	OCMEM_OTHER_OS,
+	OCMEM_CLIENT_MAX,
+};
+
+struct ocmem_buf {
+	unsigned long offset;
+	unsigned long addr;
+	unsigned long len;
+};
+
+struct ocmem_buf *ocmem_allocate(enum ocmem_client client, unsigned long size);
+void ocmem_free(enum ocmem_client client, struct ocmem_buf *buf);
+
+#endif /* __OCMEM_H__ */
-- 
2.4.3

  parent reply	other threads:[~2015-09-29 19:49 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-29 19:48 [PATCH 0/6] Add OCMEM support (v2) Rob Clark
2015-09-29 19:48 ` [PATCH 1/6] qcom-scm: fix endianess issue in __qcom_scm_is_call_available Rob Clark
2015-09-29 21:00   ` Stephen Boyd
2015-09-29 19:48 ` [PATCH 2/6] qcom-scm: fix header compile errors Rob Clark
2015-09-29 21:02   ` Stephen Boyd
2015-09-29 19:48 ` [PATCH 3/6] qcom-scm: add missing prototype for qcom_scm_is_available() Rob Clark
2015-09-29 19:48 ` [PATCH 4/6] qcom-scm: add ocmem support Rob Clark
2015-09-29 21:38   ` Stephen Boyd
2015-09-29 21:53     ` Rob Clark
2015-09-29 22:33       ` Stephen Boyd
2015-10-01 20:13         ` Rob Clark
2015-10-01 21:52           ` Stephen Boyd
2015-09-29 19:48 ` [PATCH 5/6] drm/msm: update generated headers Rob Clark
2015-09-29 19:48 ` Rob Clark [this message]
2015-09-30  7:51   ` [PATCH 6/6] drm/msm: add OCMEM driver Stanimir Varbanov
2015-09-30 11:31     ` Rob Clark
2015-09-30 11:45       ` Rob Clark
2015-10-01  8:23         ` Stanimir Varbanov
2015-10-01 18:00           ` Stephen Boyd
2015-10-01 19:25             ` Rob Clark
2015-10-02  0:26               ` Rob Clark
2015-10-02  0:59                 ` Stephen Boyd
2015-10-02  1:37                   ` Rob Clark

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1443556138-21085-7-git-send-email-robdclark@gmail.com \
    --to=robdclark@gmail.com \
    --cc=bjorn.andersson@sonymobile.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=sboyd@codeaurora.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.