Răsfoiți Sursa

msm: eva: mmrm integration

integrated mmrm api
added make file and kbuild support
code ready, enable flow.

Change-Id: Ic7da142bc68e60312ee9a12128847be8ed27a685
Signed-off-by: Yu SI <[email protected]>
Yu SI 4 ani în urmă
părinte
comite
9871416e79

+ 16 - 4
Android.mk

@@ -1,7 +1,6 @@
 ifneq ($(TARGET_PRODUCT), qssi)
 ifeq ($(call is-board-platform-in-list, $(TARGET_BOARD_PLATFORM)),true)
 
-# Test dlkm
 DLKM_DIR   := device/qcom/common/dlkm
 
 LOCAL_PATH := $(call my-dir)
@@ -9,13 +8,26 @@ LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
 # For incremental compilation
 LOCAL_SRC_FILES   := $(wildcard $(LOCAL_PATH)/**/*) $(wildcard $(LOCAL_PATH)/*)
-# LOCAL_SRC_FILES   := $(wildcard $(LOCAL_PATH)/msm/eva/*)
 LOCAL_MODULE      := msm-eva.ko
 LOCAL_MODULE_KBUILD_NAME := msm/msm-eva.ko
 LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
-# Include msm-eva.ko in the /vendor/lib/modules
-# BOARD_VENDOR_KERNEL_MODULES += $(LOCAL_MODULE_PATH)/$(LOCAL_MODULE)
+
 LOCAL_ADDITIONAL_DEPENDENCY      := synx-driver.ko
+
+# export to kbuild
+KBUILD_OPTIONS += KBUILD_EXTRA_SYMBOLS=$(shell pwd)/$(call intermediates-dir-for,DLKM,mmrm-module-symvers)/Module.symvers
+
+LOCAL_REQUIRED_MODULES    := mmrm-module-symvers
+LOCAL_ADDITIONAL_DEPENDENCIES := $(call intermediates-dir-for,DLKM,mmrm-module-symvers)/Module.symvers
+
+# print out variables
+$(info KBUILD_OPTIONS = $(KBUILD_OPTIONS))
+$(info intermediates mmrm symvers path = $(call intermediates-dir-for,DLKM,mmrm-module-symvers))
+$(info LOCAL_ADDITIONAL_DEPENDENCY = $(LOCAL_ADDITIONAL_DEPENDENCY))
+$(info LOCAL_ADDITIONAL_DEPENDENCIES = $(LOCAL_ADDITIONAL_DEPENDENCIES))
+$(info LOCAL_REQUIRED_MODULES = $(LOCAL_REQUIRED_MODULES))
+$(info DLKM_DIR = $(DLKM_DIR))
+
 include $(DLKM_DIR)/Build_external_kernelmodule.mk
 
 endif # End of check for board platform

+ 7 - 1
msm/Kbuild

@@ -4,10 +4,16 @@ LINUXINCLUDE    += -I$(EVA_ROOT)/include \
 
 #srctree is /kernel_platform/common/
 
-#ccflags-m not working,  why?
 ccflags-y += -I$(srctree)/techpack/eva/msm/eva/ \
     -I$(srctree)/drivers/media/platform/msm/synx/
 
+# add flag to compile mmrm actual implementatio instead of stub version.
+# to follow up with mmrm team if techpack users need to define this for long term?
+KBUILD_CPPFLAGS += -DCONFIG_MSM_MMRM
+
+# ported from Android.mk
+$(info within KBUILD file KBUILD_EXTRA_SYMBOLS = $(KBUILD_EXTRA_SYMBOLS))
+
 msm-eva-objs := eva/cvp.o \
         eva/msm_cvp_ioctl.o \
         eva/msm_cvp_platform.o \

+ 1 - 0
msm/eva/cvp.c

@@ -638,4 +638,5 @@ static void __exit msm_cvp_exit(void)
 module_init(msm_cvp_init);
 module_exit(msm_cvp_exit);
 
+MODULE_SOFTDEP("pre: msm-mmrm");
 MODULE_LICENSE("GPL v2");

+ 3 - 0
msm/eva/cvp_core_hfi.h

@@ -11,6 +11,7 @@
 #include <linux/platform_device.h>
 #include <linux/pm_qos.h>
 #include <linux/spinlock.h>
+#include <linux/soc/qcom/msm_mmrm.h>
 #include "cvp_hfi_api.h"
 #include "cvp_hfi_helper.h"
 #include "cvp_hfi_api.h"
@@ -251,6 +252,8 @@ struct iris_hfi_device {
 	int reg_count;
 	struct iris_resources resources;
 	struct msm_cvp_platform_resources *res;
+	struct mmrm_client_desc mmrm_cvp_desc;
+	struct mmrm_client *mmrm_cvp;
 	enum iris_hfi_state state;
 	struct cvp_hfi_packetization_ops *pkt_ops;
 	enum hfi_packetization_type packetization_type;

+ 63 - 13
msm/eva/cvp_hfi.c

@@ -29,6 +29,7 @@
 #include "cvp_hfi_helper.h"
 #include "cvp_hfi_io.h"
 #include "msm_cvp_dsp.h"
+#include "msm_cvp_clocks.h"
 
 #define FIRMWARE_SIZE			0X00A00000
 #define REG_ADDR_OFFSET_BITMASK	0x000FFFFF
@@ -1250,7 +1251,6 @@ static int iris_hfi_resume(void *dev)
 	return rc;
 }
 
-
 static int iris_hfi_suspend(void *dev)
 {
 	int rc = 0;
@@ -1349,16 +1349,31 @@ static int __set_clocks(struct iris_hfi_device *device, u32 freq)
 			freq = freq * factorsrc2clk;
 			dprintk(CVP_PWR, "%s: clock source rate set to: %ld\n", __func__, freq);
 
-			rc = clk_set_rate(cl->clk, freq);
-			if (rc) {
-				dprintk(CVP_ERR,
-					"Failed to set clock rate %u %s: %d %s\n",
-					freq, cl->name, rc, __func__);
-				return rc;
-			}
-
-			dprintk(CVP_PWR, "Scaling clock %s to %u\n",
+			if (device->mmrm_cvp != NULL) {
+				/* set min freq as the value stored as 1st element in the table */
+				rc = msm_cvp_mmrm_set_value_in_range(device,
+					device->res->allowed_clks_tbl[0].clock_rate * factorsrc2clk,
+					freq);
+				if (rc) {
+					dprintk(CVP_ERR,
+						"%s: Failed to set clock rate for %s: %d\n",
+						__func__, cl->name, rc);
+					return rc;
+				}
+			} else {
+				dprintk(CVP_PWR, "%s: set clock rate with clk_set_rate\n",
+					__func__);
+				rc = clk_set_rate(cl->clk, freq);
+				if (rc) {
+					dprintk(CVP_ERR,
+						"Failed to set clock rate %u %s: %d %s\n",
+						freq, cl->name, rc, __func__);
+					return rc;
+				}
+
+				dprintk(CVP_PWR, "Scaling clock %s to %u\n",
 					cl->name, freq);
+			}
 		}
 	}
 
@@ -2123,6 +2138,15 @@ static int iris_hfi_core_init(void *device)
 		cpu_latency_qos_add_request(&dev->qos,
 				dev->res->pm_qos_latency_us);
 
+	/* mmrm registration */
+	if (msm_cvp_mmrm_enabled) {
+		rc = msm_cvp_mmrm_register(device);
+		if (rc) {
+			dprintk(CVP_ERR, "Failed to register mmrm client\n");
+			goto err_core_init;
+		}
+	}
+
 	mutex_unlock(&dev->lock);
 
 	cvp_dsp_send_hfi_queue();
@@ -2162,6 +2186,21 @@ static int iris_hfi_core_release(void *dev)
 
 	__dsp_shutdown(device, 0);
 
+	if (msm_cvp_mmrm_enabled) {
+		rc = mmrm_client_deregister(device->mmrm_cvp);
+		if (rc) {
+			dprintk(CVP_ERR,
+				"%s: Failed mmrm_client_deregister with rc: %d\n",
+				__func__, rc);
+		} else {
+			dprintk(CVP_PWR,
+				"%s: Succeed mmrm_client_deregister for mmrm_cvp:%p, type:%d, uid:%ld\n",
+				__func__, device->mmrm_cvp, device->mmrm_cvp->client_type,
+				device->mmrm_cvp->client_uid);
+			device->mmrm_cvp = NULL;
+		}
+	}
+
 	__unload_fw(device);
 
 	/* unlink all sessions from device */
@@ -3474,9 +3513,20 @@ static inline int __prepare_enable_clks(struct iris_hfi_device *device)
 		 * them.  Since we don't really have a load at this point, scale
 		 * it to the lowest frequency possible
 		 */
-		if (cl->has_scaling)
-			clk_set_rate(cl->clk, clk_round_rate(cl->clk, 0));
-
+		if (cl->has_scaling) {
+			if (device->mmrm_cvp != NULL) {
+				// set min freq and cur freq to 0;
+				rc = msm_cvp_mmrm_set_value_in_range(device, 0, 0);
+				if (rc)
+					dprintk(CVP_ERR,
+						"%s Failed to set clock rate for %s: %d\n",
+						__func__, cl->name, rc);
+			} else {
+				dprintk(CVP_PWR, "%s: set clock rate with clk_set_rate\n",
+					__func__);
+				clk_set_rate(cl->clk, clk_round_rate(cl->clk, 0));
+			}
+		}
 		rc = clk_prepare_enable(cl->clk);
 		if (rc) {
 			dprintk(CVP_ERR, "Failed to enable clocks\n");

+ 79 - 0
msm/eva/msm_cvp_clocks.c

@@ -23,3 +23,82 @@ int msm_cvp_set_clocks(struct msm_cvp_core *core)
 		hdev->hfi_device_data, core->curr_freq);
 	return rc;
 }
+
+int msm_cvp_mmrm_register(struct iris_hfi_device *device)
+{
+	int rc = 0;
+	struct clock_info *cl = NULL;
+	char *name = (char *)device->mmrm_cvp_desc.client_info.desc.name;
+
+	if (!device) {
+		dprintk(CVP_ERR, "%s invalid device\n", __func__);
+		return -EINVAL;
+	}
+
+	device->mmrm_cvp = NULL;
+	device->mmrm_cvp_desc.client_type = MMRM_CLIENT_CLOCK;
+	device->mmrm_cvp_desc.client_info.desc.client_domain = MMRM_CLIENT_DOMAIN_CVP;
+	/* TODO: use proper way to retrieve client id via dtsi */
+	device->mmrm_cvp_desc.client_info.desc.client_id = 8;
+
+	iris_hfi_for_each_clock(device, cl) {
+		if (cl->has_scaling) {	/* only clk source enabled in dtsi */
+			device->mmrm_cvp_desc.client_info.desc.clk = cl->clk;
+			strlcpy(name, cl->name,
+				sizeof(device->mmrm_cvp_desc.client_info.desc.name));
+		}
+	}
+	device->mmrm_cvp_desc.priority = MMRM_CLIENT_PRIOR_LOW;
+
+	dprintk(CVP_PWR,
+		"%s: Register for %s\n",
+		__func__, device->mmrm_cvp_desc.client_info.desc.name);
+
+	device->mmrm_cvp = mmrm_client_register(&(device->mmrm_cvp_desc));
+	if (device->mmrm_cvp == NULL) {
+		dprintk(CVP_ERR, "%s: Failed mmrm_client_register with mmrm_cvp: %p\n",
+			__func__, device->mmrm_cvp);
+		rc = -ENOENT;
+	} else {
+		dprintk(CVP_PWR,
+			"%s: Succeed mmrm_client_register with mmrm_cvp: %p, type :%d, uid: %ld\n",
+			__func__, device->mmrm_cvp,
+			device->mmrm_cvp->client_type, device->mmrm_cvp->client_uid);
+	}
+
+	return rc;
+}
+
+int msm_cvp_mmrm_set_value_in_range(struct iris_hfi_device *device, u32 freq_min, u32 freq_cur)
+{
+	int rc = 0;
+	struct mmrm_client_res_value val;
+	struct mmrm_client_data data;
+
+	if (!device) {
+		dprintk(CVP_ERR, "%s invalid device\n", __func__);
+		return -EINVAL;
+	}
+
+	dprintk(CVP_PWR,
+		"%s: set clock rate for mmrm_cvp: %p, type :%d, uid: %ld\n",
+		__func__, device->mmrm_cvp,
+		device->mmrm_cvp->client_type, device->mmrm_cvp->client_uid);
+
+	val.min = freq_min;
+	val.cur = freq_cur;
+	data.num_hw_blocks = 1;
+	data.flags = 0;		/* Not MMRM_CLIENT_DATA_FLAG_RESERVE_ONLY */
+
+	dprintk(CVP_PWR,
+		"%s: set clock rate to min %u cur %u: %d\n",
+		__func__, val.min, val.cur, rc);
+
+	rc = mmrm_client_set_value_in_range(device->mmrm_cvp, &data, &val);
+	if (rc) {
+		dprintk(CVP_ERR,
+			"%s: Failed to set clock rate to min %u cur %u: %d\n",
+			__func__, val.min, val.cur, rc);
+	}
+	return rc;
+}

+ 4 - 0
msm/eva/msm_cvp_clocks.h

@@ -7,6 +7,10 @@
 #ifndef _MSM_CVP_CLOCKS_H_
 #define _MSM_CVP_CLOCKS_H_
 #include "msm_cvp_internal.h"
+#include "cvp_core_hfi.h"
 
 int msm_cvp_set_clocks(struct msm_cvp_core *core);
+int msm_cvp_mmrm_register(struct iris_hfi_device *device);
+int msm_cvp_mmrm_set_value_in_range(struct iris_hfi_device *device, u32 freq_min, u32 freq_cur);
+
 #endif

+ 1 - 0
msm/eva/msm_cvp_debug.c

@@ -27,6 +27,7 @@ bool msm_cvp_cacheop_disabled = !true;
 int msm_cvp_clock_voting = !1;
 bool msm_cvp_syscache_disable = !true;
 bool msm_cvp_dsp_disable = !true;
+bool msm_cvp_mmrm_enabled = true;
 
 #define MAX_DBG_BUF_SIZE 4096
 

+ 1 - 0
msm/eva/msm_cvp_debug.h

@@ -63,6 +63,7 @@ extern bool msm_cvp_cacheop_disabled;
 extern int msm_cvp_clock_voting;
 extern bool msm_cvp_syscache_disable;
 extern bool msm_cvp_dsp_disable;
+extern bool msm_cvp_mmrm_enabled;
 
 #define dprintk(__level, __fmt, arg...)	\
 	do { \