diff --git a/Android.mk b/Android.mk index 46548065d4..c9c9f556e7 100644 --- a/Android.mk +++ b/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 diff --git a/msm/Kbuild b/msm/Kbuild index a4754e1d87..f950634c31 100644 --- a/msm/Kbuild +++ b/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 \ diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index f84c55892f..5366db5013 100644 --- a/msm/eva/cvp.c +++ b/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"); diff --git a/msm/eva/cvp_core_hfi.h b/msm/eva/cvp_core_hfi.h index ae8b20470b..c7c8ca1d73 100644 --- a/msm/eva/cvp_core_hfi.h +++ b/msm/eva/cvp_core_hfi.h @@ -11,6 +11,7 @@ #include #include #include +#include #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; diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 3328d9b56f..b37e39cb24 100644 --- a/msm/eva/cvp_hfi.c +++ b/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; - } + 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", + 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"); diff --git a/msm/eva/msm_cvp_clocks.c b/msm/eva/msm_cvp_clocks.c index 5e2324e423..a545ac97e4 100644 --- a/msm/eva/msm_cvp_clocks.c +++ b/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; +} diff --git a/msm/eva/msm_cvp_clocks.h b/msm/eva/msm_cvp_clocks.h index 5a1b77331f..df6e28a25c 100644 --- a/msm/eva/msm_cvp_clocks.h +++ b/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 diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index ae35c70c58..0c0c7ab273 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/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 diff --git a/msm/eva/msm_cvp_debug.h b/msm/eva/msm_cvp_debug.h index 1d57d6c770..c1fb775663 100644 --- a/msm/eva/msm_cvp_debug.h +++ b/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 { \