diff options
| author | fire855 <thefire855@gmail.com> | 2017-02-24 17:48:24 +0100 |
|---|---|---|
| committer | Mister Oyster <oysterized@gmail.com> | 2017-04-11 10:59:46 +0200 |
| commit | 504261abd2b3a69cb609ef9ccf4e58ae9ccad566 (patch) | |
| tree | eb5caf24cfcb12a7dbb2dbe38eaa1e68d4c26a3c /drivers/misc/mediatek/smi | |
| parent | d547e0f39015f8e8ec1dba8bd9d66c1beb24eb41 (diff) | |
Update m4u, smi and gud drivers
Backported from 3.18 MM kernel
Diffstat (limited to 'drivers/misc/mediatek/smi')
38 files changed, 9447 insertions, 8268 deletions
diff --git a/drivers/misc/mediatek/smi/Kconfig b/drivers/misc/mediatek/smi/Kconfig index 56d1e4f7c..7e8d39fc1 100644 --- a/drivers/misc/mediatek/smi/Kconfig +++ b/drivers/misc/mediatek/smi/Kconfig @@ -1,5 +1,11 @@ -config MTK_SMI - bool CONFIG_MTK_SMI - default n - help - CONFIG_MTK_SMI +config MTK_SMI_EXT + bool "SMI Driver" + default n + help + SMI Driver is used to arbitrate memory bandwidth of multimedia + +config MTK_SMI_VARIANT + bool "MTK SMI Tablet Code" + select MTK_SMI_EXT + help + It's for smi common tablet framework. And it will enable power-domain. diff --git a/drivers/misc/mediatek/smi/Makefile b/drivers/misc/mediatek/smi/Makefile index 804347f3e..2ff41abc7 100644 --- a/drivers/misc/mediatek/smi/Makefile +++ b/drivers/misc/mediatek/smi/Makefile @@ -1,3 +1,44 @@ +ifneq ($(CONFIG_MTK_SMI_VARIANT),y) -obj-y += $(subst ",,$(CONFIG_MTK_PLATFORM))/ +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat +ccflags-y += -I$(srctree)/drivers/misc/mediatek/m4u/$(MTK_PLATFORM)/ +ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/$(MTK_PLATFORM)/ +ccflags-y += -I$(srctree)/drivers/misc/mediatek/cmdq/ +ccflags-y += -I$(srctree)/drivers/misc/mediatek/cmdq/$(MTK_PLATFORM)/ +ccflags-y += -I$(srctree)/drivers/misc/mediatek/cmdq/$(MTK_PLATFORM)/mt6753/ +obj-y += smi_common.o +obj-y += smi_debug.o +obj-y += smi_info_util.o +obj-y += smi_config_util.o +obj-y += smi_configuration.o +obj-y += smi_internal.o +ifeq ($(CONFIG_ARCH_MT6735),y) +ccflags-y += -I$(srctree)/drivers/clk/mediatek +ccflags-y += -DSMI_D1 +obj-y += mmdvfs_mgr.o +endif + +ifeq ($(CONFIG_ARCH_MT6735M),y) +ccflags-y += -DSMI_D2 +obj-y += mmdvfs_mgr.o +endif + +ifeq ($(CONFIG_ARCH_MT6753),y) +ccflags-y += -DSMI_D3 +obj-y += mmdvfs_mgr.o +endif + +ifeq ($(CONFIG_ARCH_MT6580),y) +ccflags-y += -DSMI_R +endif + +ifeq ($(CONFIG_ARCH_MT6755),y) +ccflags-y += -DSMI_J +ccflags-y += -I$(srctree)/drivers/clk/mediatek +obj-y += mmdvfs_mgr_v2.o +endif + +else +obj-y += $(subst ",,variant)/ +endif diff --git a/drivers/misc/mediatek/smi/mmdvfs_mgr.c b/drivers/misc/mediatek/smi/mmdvfs_mgr.c new file mode 100644 index 000000000..b428c1ba9 --- /dev/null +++ b/drivers/misc/mediatek/smi/mmdvfs_mgr.c @@ -0,0 +1,708 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * 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. + */ + +#if ((defined(SMI_D1) || defined(SMI_D2) || defined(SMI_D3)) && !IS_ENABLED(CONFIG_FPGA_EARLY_PORTING)) +#define MMDVFS_ENABLE 1 +#endif + +#include <linux/uaccess.h> +#include <linux/aee.h> + +#include <mach/mt_smi.h> + +#include <linux/timer.h> +#include <linux/jiffies.h> +#include <linux/workqueue.h> +#include <linux/delay.h> + +#include <mach/mt_freqhopping.h> +#include <mach/mt_clkmgr.h> +#include <mach/mt_vcore_dvfs.h> +#include <mach/mt_freqhopping_drv.h> + + +#include "mmdvfs_mgr.h" + +#undef pr_fmt +#define pr_fmt(fmt) "[" MMDVFS_LOG_TAG "]" fmt + +#define MMDVFS_ENABLE_FLIPER_CONTROL 0 +/* #define MMDVFS_USE_APMCU_CLK_MUX_SWITCH */ + +#if MMDVFS_ENABLE_FLIPER_CONTROL +#include <mach/fliper.h> +#endif + +/* mmdvfs MM sizes */ +#define MMDVFS_PIXEL_NUM_720P (1280 * 720) +#define MMDVFS_PIXEL_NUM_2160P (3840 * 2160) +#define MMDVFS_PIXEL_NUM_1080P (2100 * 1300) +#define MMDVFS_PIXEL_NUM_2M (2100 * 1300) +/* 13M sensor */ +#define MMDVFS_PIXEL_NUM_SENSOR_FULL (13000000) +#define MMDVFS_PIXEL_NUM_SENSOR_6M (5800000) +#define MMDVFS_PIXEL_NUM_SENSOR_8M (7800000) + +/* mmdvfs display sizes */ +#define MMDVFS_DISPLAY_SIZE_HD (1280 * 832) +#define MMDVFS_DISPLAY_SIZE_FHD (1920 * 1216) + +/* + 1 for MMDVFS_CAM_MON_SCEN */ +static mmdvfs_voltage_enum g_mmdvfs_scenario_voltage[MMDVFS_SCEN_COUNT] = { +MMDVFS_VOLTAGE_DEFAULT}; +static mmdvfs_voltage_enum g_mmdvfs_current_step; +static unsigned int g_mmdvfs_concurrency; +static MTK_SMI_BWC_MM_INFO *g_mmdvfs_info; +static int g_mmdvfs_profile_id = MMDVFS_PROFILE_UNKNOWN; +static MTK_MMDVFS_CMD g_mmdvfs_cmd; + +struct mmdvfs_context_struct { + spinlock_t scen_lock; + int is_mhl_enable; + int is_mjc_enable; +}; + +/* mmdvfs_query() return value, remember to sync with user space */ +enum mmdvfs_step_enum { + MMDVFS_STEP_LOW = 0, MMDVFS_STEP_HIGH, + + MMDVFS_STEP_LOW2LOW, /* LOW */ + MMDVFS_STEP_HIGH2LOW, /* LOW */ + MMDVFS_STEP_LOW2HIGH, /* HIGH */ + MMDVFS_STEP_HIGH2HIGH, +/* HIGH */ +}; + +/* lcd size */ +enum mmdvfs_lcd_size_enum { + MMDVFS_LCD_SIZE_HD, MMDVFS_LCD_SIZE_FHD, MMDVFS_LCD_SIZE_WQHD, MMDVFS_LCD_SIZE_END_OF_ENUM +}; + +static struct mmdvfs_context_struct g_mmdvfs_mgr_cntx; +static struct mmdvfs_context_struct * const g_mmdvfs_mgr = &g_mmdvfs_mgr_cntx; + +static enum mmdvfs_lcd_size_enum mmdvfs_get_lcd_resolution(void) +{ + if (DISP_GetScreenWidth() * DISP_GetScreenHeight() + <= MMDVFS_DISPLAY_SIZE_HD) + return MMDVFS_LCD_SIZE_HD; + + return MMDVFS_LCD_SIZE_FHD; +} + +static int vdec_ctrl_func_checked(vdec_ctrl_cb func, char *msg); +static int notify_cb_func_checked(clk_switch_cb func, int ori_mmsys_clk_mode, int update_mmsys_clk_mode, char *msg); +static int mmdfvs_adjust_mmsys_clk_by_hopping(int clk_mode); +static int default_clk_switch_cb(int ori_mmsys_clk_mode, int update_mmsys_clk_mode); +static int current_mmsys_clk = MMSYS_CLK_LOW; + +static mmdvfs_voltage_enum mmdvfs_get_default_step(void) +{ + mmdvfs_voltage_enum result = MMDVFS_VOLTAGE_LOW; + + if (g_mmdvfs_profile_id == MMDVFS_PROFILE_D3) + result = MMDVFS_VOLTAGE_LOW; + else if (g_mmdvfs_profile_id == MMDVFS_PROFILE_D1_PLUS) + result = MMDVFS_VOLTAGE_LOW; + else + if (mmdvfs_get_lcd_resolution() == MMDVFS_LCD_SIZE_HD) + result = MMDVFS_VOLTAGE_LOW; + else + /* D1 FHD always HPM. do not have to trigger vcore dvfs. */ + result = MMDVFS_VOLTAGE_HIGH; + + return result; +} + +static mmdvfs_voltage_enum mmdvfs_get_current_step(void) +{ + return g_mmdvfs_current_step; +} + +static mmdvfs_voltage_enum mmdvfs_query(MTK_SMI_BWC_SCEN scenario, +MTK_MMDVFS_CMD *cmd) +{ + mmdvfs_voltage_enum step = mmdvfs_get_default_step(); + unsigned int venc_size; + MTK_MMDVFS_CMD cmd_default; + + venc_size = g_mmdvfs_info->video_record_size[0] + * g_mmdvfs_info->video_record_size[1]; + + /* use default info */ + if (cmd == NULL) { + memset(&cmd_default, 0, sizeof(MTK_MMDVFS_CMD)); + cmd_default.camera_mode = MMDVFS_CAMERA_MODE_FLAG_DEFAULT; + cmd = &cmd_default; + } + + /* collect the final information */ + if (cmd->sensor_size == 0) + cmd->sensor_size = g_mmdvfs_cmd.sensor_size; + + if (cmd->sensor_fps == 0) + cmd->sensor_fps = g_mmdvfs_cmd.sensor_fps; + + if (cmd->camera_mode == MMDVFS_CAMERA_MODE_FLAG_DEFAULT) + cmd->camera_mode = g_mmdvfs_cmd.camera_mode; + + /* HIGH level scenarios */ + switch (scenario) { +#if defined(SMI_D2) /* D2 ISP >= 6M HIGH */ + case SMI_BWC_SCEN_VR_SLOW: + case SMI_BWC_SCEN_VR: + if (cmd->sensor_size >= MMDVFS_PIXEL_NUM_SENSOR_6M) + step = MMDVFS_VOLTAGE_HIGH; + + break; +#endif + + case SMI_BWC_SCEN_ICFP: + step = MMDVFS_VOLTAGE_HIGH; + break; + /* force HPM for engineering mode */ + case SMI_BWC_SCEN_FORCE_MMDVFS: + step = MMDVFS_VOLTAGE_HIGH; + break; + default: + break; + } + + return step; +} + +static void mmdvfs_update_cmd(MTK_MMDVFS_CMD *cmd) +{ + if (cmd == NULL) + return; + + if (cmd->sensor_size) + g_mmdvfs_cmd.sensor_size = cmd->sensor_size; + + if (cmd->sensor_fps) + g_mmdvfs_cmd.sensor_fps = cmd->sensor_fps; + + MMDVFSMSG("update cm %d %d\n", cmd->camera_mode, cmd->sensor_size); + g_mmdvfs_cmd.camera_mode = cmd->camera_mode; +} + +static void mmdvfs_dump_info(void) +{ + MMDVFSMSG("CMD %d %d %d\n", g_mmdvfs_cmd.sensor_size, + g_mmdvfs_cmd.sensor_fps, g_mmdvfs_cmd.camera_mode); + MMDVFSMSG("INFO VR %d %d\n", g_mmdvfs_info->video_record_size[0], + g_mmdvfs_info->video_record_size[1]); +} + +/* delay 4 seconds to go LPM to workaround camera ZSD + PIP issue */ +#if !defined(SMI_D3) +static void mmdvfs_cam_work_handler(struct work_struct *work) +{ + MMDVFSMSG("CAM handler %d\n", jiffies_to_msecs(jiffies)); + mmdvfs_set_step(MMDVFS_CAM_MON_SCEN, mmdvfs_get_default_step()); +} + +static DECLARE_DELAYED_WORK(g_mmdvfs_cam_work, mmdvfs_cam_work_handler); + +static void mmdvfs_stop_cam_monitor(void) +{ + cancel_delayed_work_sync(&g_mmdvfs_cam_work); +} + +#define MMDVFS_CAM_MON_DELAY (4 * HZ) +static void mmdvfs_start_cam_monitor(void) +{ + mmdvfs_stop_cam_monitor(); + MMDVFSMSG("CAM start %d\n", jiffies_to_msecs(jiffies)); + mmdvfs_set_step(MMDVFS_CAM_MON_SCEN, MMDVFS_VOLTAGE_HIGH); + /* 4 seconds for PIP switch preview aspect delays... */ + schedule_delayed_work(&g_mmdvfs_cam_work, MMDVFS_CAM_MON_DELAY); +} + +#endif /* !defined(SMI_D3) */ + +int mmdvfs_set_step(MTK_SMI_BWC_SCEN scenario, mmdvfs_voltage_enum step) +{ + int i, scen_index; + unsigned int concurrency = 0; + mmdvfs_voltage_enum final_step = mmdvfs_get_default_step(); + +#if !MMDVFS_ENABLE + return 0; +#endif + + if (!is_vcorefs_can_work()) + return 0; + + /* D1 FHD always HPM. do not have to trigger vcore dvfs. */ + if (g_mmdvfs_profile_id == MMDVFS_PROFILE_D1 + && mmdvfs_get_lcd_resolution() == MMDVFS_LCD_SIZE_FHD) + return 0; + + /* D1 plus FHD only allowed DISP as the client */ + if (g_mmdvfs_profile_id == MMDVFS_PROFILE_D1_PLUS) + if (mmdvfs_get_lcd_resolution() == MMDVFS_LCD_SIZE_FHD + && scenario != (MTK_SMI_BWC_SCEN) MMDVFS_SCEN_DISP) + return 0; + + + if ((scenario >= (MTK_SMI_BWC_SCEN) MMDVFS_SCEN_COUNT) || (scenario < SMI_BWC_SCEN_NORMAL)) { + MMDVFSERR("invalid scenario\n"); + return -1; + } + + /* dump information */ + mmdvfs_dump_info(); + + /* go through all scenarios to decide the final step */ + scen_index = (int)scenario; + + spin_lock(&g_mmdvfs_mgr->scen_lock); + + g_mmdvfs_scenario_voltage[scen_index] = step; + + concurrency = 0; + for (i = 0; i < MMDVFS_SCEN_COUNT; i++) { + if (g_mmdvfs_scenario_voltage[i] == MMDVFS_VOLTAGE_HIGH) + concurrency |= 1 << i; + } + + /* one high = final high */ + for (i = 0; i < MMDVFS_SCEN_COUNT; i++) { + if (g_mmdvfs_scenario_voltage[i] == MMDVFS_VOLTAGE_HIGH) { + final_step = MMDVFS_VOLTAGE_HIGH; + break; + } + } + + g_mmdvfs_current_step = final_step; + + spin_unlock(&g_mmdvfs_mgr->scen_lock); + + MMDVFSMSG("Set vol scen:%d,step:%d,final:%d(0x%x),CMD(%d,%d,0x%x),INFO(%d,%d)\n", + scenario, step, final_step, concurrency, + g_mmdvfs_cmd.sensor_size, g_mmdvfs_cmd.sensor_fps, g_mmdvfs_cmd.camera_mode, + g_mmdvfs_info->video_record_size[0], g_mmdvfs_info->video_record_size[1]); + +#if MMDVFS_ENABLE + /* call vcore dvfs API */ + if (final_step == MMDVFS_VOLTAGE_HIGH) + vcorefs_request_dvfs_opp(KIR_MM, OPPI_PERF); + else + vcorefs_request_dvfs_opp(KIR_MM, OPPI_UNREQ); + +#endif + + return 0; +} + +void mmdvfs_handle_cmd(MTK_MMDVFS_CMD *cmd) +{ +#if !MMDVFS_ENABLE + return; +#endif + + MMDVFSMSG("MMDVFS cmd %u %d\n", cmd->type, cmd->scen); + + switch (cmd->type) { + case MTK_MMDVFS_CMD_TYPE_MMSYS_SET: + if (cmd->scen == SMI_BWC_SCEN_NORMAL) { + mmdvfs_set_mmsys_clk(cmd->scen, MMSYS_CLK_LOW); + vcorefs_request_dvfs_opp(KIR_MM, OPPI_UNREQ); + } else { + vcorefs_request_dvfs_opp(KIR_MM, OPPI_PERF); + mmdvfs_set_mmsys_clk(cmd->scen, MMSYS_CLK_HIGH); + } + break; + case MTK_MMDVFS_CMD_TYPE_SET: + /* save cmd */ + mmdvfs_update_cmd(cmd); + if (!(g_mmdvfs_concurrency & (1 << cmd->scen))) + MMDVFSMSG("invalid set scen %d\n", cmd->scen); + cmd->ret = mmdvfs_set_step(cmd->scen, + mmdvfs_query(cmd->scen, cmd)); + break; + case MTK_MMDVFS_CMD_TYPE_QUERY: { /* query with some parameters */ + if (mmdvfs_get_lcd_resolution() == MMDVFS_LCD_SIZE_FHD) { + /* QUERY ALWAYS HIGH for FHD */ + cmd->ret = (unsigned int)MMDVFS_STEP_HIGH2HIGH; + + } else { /* FHD */ + mmdvfs_voltage_enum query_voltage = mmdvfs_query(cmd->scen, cmd); + + mmdvfs_voltage_enum current_voltage = mmdvfs_get_current_step(); + + if (current_voltage < query_voltage) { + cmd->ret = (unsigned int)MMDVFS_STEP_LOW2HIGH; + } else if (current_voltage > query_voltage) { + cmd->ret = (unsigned int)MMDVFS_STEP_HIGH2LOW; + } else { + cmd->ret + = (unsigned int)(query_voltage + == MMDVFS_VOLTAGE_HIGH + ? MMDVFS_STEP_HIGH2HIGH + : MMDVFS_STEP_LOW2LOW); + } + } + + MMDVFSMSG("query %d\n", cmd->ret); + /* cmd->ret = (unsigned int)query_voltage; */ + break; + } + + default: + MMDVFSMSG("invalid mmdvfs cmd\n"); + BUG(); + break; + } +} + +void mmdvfs_notify_scenario_exit(MTK_SMI_BWC_SCEN scen) +{ +#if !MMDVFS_ENABLE + return; +#endif + + MMDVFSMSG("leave %d\n", scen); + +#if !defined(SMI_D3) /* d3 does not need this workaround because the MMCLK is always the highest */ + /* + * keep HPM for 4 seconds after exiting camera scenarios to get rid of + * cam framework will let us go to normal scenario for a short time + * (ex: STOP PREVIEW --> NORMAL --> START PREVIEW) + * where the LPM mode (low MMCLK) may cause ISP failures + */ + if ((scen == SMI_BWC_SCEN_VR) || (scen == SMI_BWC_SCEN_VR_SLOW) + || (scen == SMI_BWC_SCEN_ICFP)) { + mmdvfs_start_cam_monitor(); + } +#endif /* !defined(SMI_D3) */ + + /* reset scenario voltage to default when it exits */ + mmdvfs_set_step(scen, mmdvfs_get_default_step()); +} + +void mmdvfs_notify_scenario_enter(MTK_SMI_BWC_SCEN scen) +{ +#if !MMDVFS_ENABLE + return; +#endif + + MMDVFSMSG("enter %d\n", scen); + + /* ISP ON = high */ + switch (scen) { +#if defined(SMI_D2) /* d2 sensor > 6M */ + case SMI_BWC_SCEN_VR: + mmdvfs_set_step(scen, mmdvfs_query(scen, NULL)); + break; +#else /* default VR high */ + case SMI_BWC_SCEN_VR: +#endif + case SMI_BWC_SCEN_WFD: + case SMI_BWC_SCEN_VR_SLOW: + case SMI_BWC_SCEN_VSS: + /* Fall through */ + case SMI_BWC_SCEN_ICFP: + /* Fall through */ + case SMI_BWC_SCEN_FORCE_MMDVFS: + mmdvfs_set_step(scen, MMDVFS_VOLTAGE_HIGH); + break; + + default: + break; + } +} + +void mmdvfs_init(MTK_SMI_BWC_MM_INFO *info) +{ +#if !MMDVFS_ENABLE + return; +#endif + + spin_lock_init(&g_mmdvfs_mgr->scen_lock); + + /* set current step as the default step */ + g_mmdvfs_profile_id = mmdvfs_get_mmdvfs_profile(); + + g_mmdvfs_current_step = mmdvfs_get_default_step(); + + g_mmdvfs_info = info; +} + +void mmdvfs_mhl_enable(int enable) +{ + g_mmdvfs_mgr->is_mhl_enable = enable; +} + +void mmdvfs_mjc_enable(int enable) +{ + g_mmdvfs_mgr->is_mjc_enable = enable; +} + +void mmdvfs_notify_scenario_concurrency(unsigned int u4Concurrency) +{ + /* raise EMI monitor BW threshold in VP, VR, VR SLOW motion cases */ + /* to make sure vcore stay MMDVFS level as long as possible */ + if (u4Concurrency & ((1 << SMI_BWC_SCEN_VP) | (1 << SMI_BWC_SCEN_VR) + | (1 << SMI_BWC_SCEN_VR_SLOW))) { +#if MMDVFS_ENABLE_FLIPER_CONTROL + MMDVFSMSG("fliper high\n"); + fliper_set_bw(BW_THRESHOLD_HIGH); +#endif + } else { +#if MMDVFS_ENABLE_FLIPER_CONTROL + MMDVFSMSG("fliper normal\n"); + fliper_restore_bw(); +#endif + } + g_mmdvfs_concurrency = u4Concurrency; +} + +/* switch MM CLK callback from VCORE DVFS driver */ +void mmdvfs_mm_clock_switch_notify(int is_before, int is_to_high) +{ + /* for WQHD 1.0v, we have to dynamically switch DL/DC */ +#ifdef MMDVFS_WQHD_1_0V + int session_id; + + if (mmdvfs_get_lcd_resolution() != MMDVFS_LCD_SIZE_WQHD) + return; + + session_id = MAKE_DISP_SESSION(DISP_SESSION_PRIMARY, 0); + + if (!is_before && is_to_high) { + MMDVFSMSG("DL\n"); + /* nonblocking switch to direct link after HPM */ + primary_display_switch_mode_for_mmdvfs(DISP_SESSION_DIRECT_LINK_MODE, session_id, + 0); + } else if (is_before && !is_to_high) { + /* BLOCKING switch to decouple before switching to LPM */ + MMDVFSMSG("DC\n"); + primary_display_switch_mode_for_mmdvfs(DISP_SESSION_DECOUPLE_MODE, session_id, 1); + } +#endif /* MMDVFS_WQHD_1_0V */ +} + + +int mmdvfs_get_mmdvfs_profile(void) +{ + + int mmdvfs_profile_id = MMDVFS_PROFILE_UNKNOWN; + unsigned int segment_code = 0; + + segment_code = _GET_BITS_VAL_(31 : 25, get_devinfo_with_index(47)); + +#if defined(SMI_D1) + mmdvfs_profile_id = MMDVFS_PROFILE_D1; + if (segment_code == 0x41 || segment_code == 0x42 || + segment_code == 0x43 || segment_code == 0x49 || + segment_code == 0x51) + mmdvfs_profile_id = MMDVFS_PROFILE_D1_PLUS; + else + mmdvfs_profile_id = MMDVFS_PROFILE_D1; +#elif defined(SMI_D2) + mmdvfs_profile_id = MMDVFS_PROFILE_D2; + if (segment_code == 0x4A || segment_code == 0x4B) + mmdvfs_profile_id = MMDVFS_PROFILE_D2_M_PLUS; + else if (segment_code == 0x52 || segment_code == 0x53) + mmdvfs_profile_id = MMDVFS_PROFILE_D2_P_PLUS; + else + mmdvfs_profile_id = MMDVFS_PROFILE_D2; +#elif defined(SMI_D3) + mmdvfs_profile_id = MMDVFS_PROFILE_D3; +#elif defined(SMI_J) + mmdvfs_profile_id = MMDVFS_PROFILE_J1; +#elif defined(SMI_EV) + mmdvfs_profile_id = MMDVFS_PROFILE_E1; +#endif + + return mmdvfs_profile_id; + +} + +int is_mmdvfs_supported(void) +{ + int mmdvfs_profile_id = mmdvfs_get_mmdvfs_profile(); + + if (mmdvfs_profile_id == MMDVFS_PROFILE_D1 && mmdvfs_get_lcd_resolution() == MMDVFS_LCD_SIZE_FHD) + return 0; + else if (mmdvfs_profile_id == MMDVFS_PROFILE_UNKNOWN) + return 0; + else + return 1; +} + +static clk_switch_cb notify_cb_func = default_clk_switch_cb; +static clk_switch_cb notify_cb_func_nolock; +static vdec_ctrl_cb vdec_suspend_cb_func; +static vdec_ctrl_cb vdec_resume_cb_func; + +int register_mmclk_switch_vdec_ctrl_cb(vdec_ctrl_cb vdec_suspend_cb, +vdec_ctrl_cb vdec_resume_cb) +{ + vdec_suspend_cb_func = vdec_suspend_cb; + vdec_resume_cb_func = vdec_resume_cb; + + return 1; +} + +int register_mmclk_switch_cb(clk_switch_cb notify_cb, +clk_switch_cb notify_cb_nolock) +{ + notify_cb_func = notify_cb; + notify_cb_func_nolock = notify_cb_nolock; + + return 1; +} + + + +/* This desing is only for CLK Mux switch relate flows */ +int mmdvfs_notify_mmclk_switch_request(int event) +{ + /* This API should only be used in J1 MMDVFS profile */ + return 0; +} + + + +static int mmdfvs_adjust_mmsys_clk_by_hopping(int clk_mode) +{ + int result = 1; + + if (g_mmdvfs_profile_id != MMDVFS_PROFILE_D2_M_PLUS && + g_mmdvfs_profile_id != MMDVFS_PROFILE_D2_P_PLUS) { + result = 0; + return result; + } + + if (!is_vcorefs_can_work()) { + result = 0; + return result; + } + + if (clk_mode == MMSYS_CLK_HIGH) { + if (current_mmsys_clk == MMSYS_CLK_MEDIUM) + mt_dfs_vencpll(0xE0000); + + vdec_ctrl_func_checked(vdec_suspend_cb_func, "VDEC suspend"); + freqhopping_config(FH_VENC_PLLID , 0, false); + notify_cb_func_checked(notify_cb_func, MMSYS_CLK_LOW, MMSYS_CLK_HIGH, + "notify_cb_func"); + freqhopping_config(FH_VENC_PLLID , 0, true); + vdec_ctrl_func_checked(vdec_resume_cb_func, "VDEC resume"); + + current_mmsys_clk = MMSYS_CLK_HIGH; + + } else if (clk_mode == MMSYS_CLK_MEDIUM) { + if (current_mmsys_clk == MMSYS_CLK_HIGH) { + vdec_ctrl_func_checked(vdec_suspend_cb_func, "VDEC suspend"); + freqhopping_config(FH_VENC_PLLID , 0, false); + notify_cb_func_checked(notify_cb_func, MMSYS_CLK_HIGH, MMSYS_CLK_LOW, "notify_cb_func"); + freqhopping_config(FH_VENC_PLLID , 0, true); + vdec_ctrl_func_checked(vdec_resume_cb_func, "VDEC resume"); + } + mt_dfs_vencpll(0x1713B1); + notify_cb_func_checked(notify_cb_func, current_mmsys_clk, MMSYS_CLK_MEDIUM, + "notify_cb_func"); + current_mmsys_clk = MMSYS_CLK_MEDIUM; + } else if (clk_mode == MMSYS_CLK_LOW) { + if (current_mmsys_clk == MMSYS_CLK_HIGH) { + vdec_ctrl_func_checked(vdec_suspend_cb_func, "VDEC suspend"); + freqhopping_config(FH_VENC_PLLID , 0, false); + notify_cb_func_checked(notify_cb_func, MMSYS_CLK_HIGH, MMSYS_CLK_LOW, "notify_cb_func"); + freqhopping_config(FH_VENC_PLLID , 0, true); + vdec_ctrl_func_checked(vdec_resume_cb_func, "VDEC resume"); + } + mt_dfs_vencpll(0xE0000); + current_mmsys_clk = MMSYS_CLK_LOW; + + } else { + MMDVFSMSG("Don't change CLK: mode=%d\n", clk_mode); + result = 0; + } + + return result; +} + +int mmdvfs_set_mmsys_clk(MTK_SMI_BWC_SCEN scenario, int mmsys_clk_mode) +{ + return mmdfvs_adjust_mmsys_clk_by_hopping(mmsys_clk_mode); +} + +static int vdec_ctrl_func_checked(vdec_ctrl_cb func, char *msg) +{ + if (func == NULL) { + MMDVFSMSG("vdec_ctrl_func is NULL, not invoked: %s\n", msg); + } else { + func(); + return 1; + } + return 0; +} + +static int notify_cb_func_checked(clk_switch_cb func, int ori_mmsys_clk_mode, int update_mmsys_clk_mode, char *msg) +{ + if (func == NULL) { + MMDVFSMSG("notify_cb_func is NULL, not invoked: %s, (%d,%d)\n", msg, ori_mmsys_clk_mode, + update_mmsys_clk_mode); + } else { + if (ori_mmsys_clk_mode != update_mmsys_clk_mode) + MMDVFSMSG("notify_cb_func: %s, (%d,%d)\n", msg, ori_mmsys_clk_mode, update_mmsys_clk_mode); + + func(ori_mmsys_clk_mode, update_mmsys_clk_mode); + return 1; + } + return 0; +} + +static int mmsys_clk_switch_impl(unsigned int venc_pll_con1_val) +{ + if (g_mmdvfs_profile_id != MMDVFS_PROFILE_D2_M_PLUS + && g_mmdvfs_profile_id != MMDVFS_PROFILE_D2_P_PLUS) { + MMDVFSMSG("mmsys_clk_switch_impl is not support in profile:%d", g_mmdvfs_profile_id); + return 0; + } + +#if defined(SMI_D2) + clkmux_sel(MT_MUX_MM, 6, "SMI common"); + mt_set_vencpll_con1(venc_pll_con1_val); + udelay(20); + clkmux_sel(MT_MUX_MM, 1, "SMI common"); +#endif + + return 1; +} + +static int default_clk_switch_cb(int ori_mmsys_clk_mode, int update_mmsys_clk_mode) +{ + unsigned int venc_pll_con1_val = 0; + + if (ori_mmsys_clk_mode == MMSYS_CLK_LOW && update_mmsys_clk_mode == MMSYS_CLK_HIGH) { + if (g_mmdvfs_profile_id == MMDVFS_PROFILE_D2_M_PLUS) + venc_pll_con1_val = 0x820F0000; /* 380MHz (35M+) */ + else + venc_pll_con1_val = 0x82110000; /* 442MHz (35P+) */ + } else if (ori_mmsys_clk_mode == MMSYS_CLK_HIGH && update_mmsys_clk_mode == MMSYS_CLK_LOW) { + venc_pll_con1_val = 0x830E0000; + } else { + MMDVFSMSG("default_clk_switch_cb: by-pass (%d,%d)\n", ori_mmsys_clk_mode, update_mmsys_clk_mode); + return 1; + } + + if (venc_pll_con1_val != 0) + mmsys_clk_switch_impl(venc_pll_con1_val); + + return 1; +} diff --git a/drivers/misc/mediatek/smi/mmdvfs_mgr.h b/drivers/misc/mediatek/smi/mmdvfs_mgr.h new file mode 100644 index 000000000..f22f2a251 --- /dev/null +++ b/drivers/misc/mediatek/smi/mmdvfs_mgr.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2015 MediaTek Inc. + * + * 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. + */ + +#ifndef __MMDVFS_MGR_H__ +#define __MMDVFS_MGR_H__ + +#include <linux/aee.h> +#include <mach/mt_smi.h> + +#define MMDVFS_LOG_TAG "MMDVFS" + +#define MMDVFSMSG(string, args...) pr_debug("[pid=%d]"string, current->tgid, ##args) +#define MMDVFSMSG2(string, args...) pr_debug(string, ##args) +#define MMDVFSTMP(string, args...) pr_debug("[pid=%d]"string, current->tgid, ##args) +#define MMDVFSERR(string, args...) \ + do {\ + pr_debug("error: "string, ##args); \ + aee_kernel_warning(MMDVFS_LOG_TAG, "error: "string, ##args); \ + } while (0) + +#define _BIT_(_bit_) (unsigned)(1 << (_bit_)) +#define _BITS_(_bits_, _val_) ((((unsigned) -1 >> (31 - ((1) ? _bits_))) \ + & ~((1U << ((0) ? _bits_)) - 1)) & ((_val_)<<((0) ? _bits_))) +#define _BITMASK_(_bits_) (((unsigned) -1 >> (31 - ((1) ? _bits_))) & ~((1U << ((0) ? _bits_)) - 1)) +#define _GET_BITS_VAL_(_bits_, _val_) (((_val_) & (_BITMASK_(_bits_))) >> ((0) ? _bits_)) + +/* MMDVFS extern APIs */ +extern void mmdvfs_init(MTK_SMI_BWC_MM_INFO *info); +extern void mmdvfs_handle_cmd(MTK_MMDVFS_CMD *cmd); +extern void mmdvfs_notify_scenario_enter(MTK_SMI_BWC_SCEN scen); +extern void mmdvfs_notify_scenario_exit(MTK_SMI_BWC_SCEN scen); +extern void mmdvfs_notify_scenario_concurrency(unsigned int u4Concurrency); +extern void mmdvfs_mhl_enable(int enable); +extern void mmdvfs_mjc_enable(int enable); + +/* screen size */ +extern unsigned int DISP_GetScreenWidth(void); +extern unsigned int DISP_GetScreenHeight(void); + + +#define MMSYS_CLK_LOW (0) +#define MMSYS_CLK_HIGH (1) +#define MMSYS_CLK_MEDIUM (2) + +#define MMDVFS_EVENT_OVL_SINGLE_LAYER_ENTER 0 +#define MMDVFS_EVENT_OVL_SINGLE_LAYER_EXIT 1 +#define MMDVFS_EVENT_UI_IDLE_ENTER 2 +#define MMDVFS_EVENT_UI_IDLE_EXIT 3 + +#define MMDVFS_CLIENT_ID_ISP 0 + +typedef int (*clk_switch_cb)(int ori_mmsys_clk_mode, int update_mmsys_clk_mode); +typedef int (*vdec_ctrl_cb)(void); + +/* MMDVFS V2 only APIs */ +extern int mmdvfs_notify_mmclk_switch_request(int event); +extern int mmdvfs_raise_mmsys_by_mux(void); +extern int mmdvfs_lower_mmsys_by_mux(void); +extern int register_mmclk_switch_cb(clk_switch_cb notify_cb, +clk_switch_cb notify_cb_nolock); +extern int mmdvfs_register_mmclk_switch_cb(clk_switch_cb notify_cb, int mmdvfs_client_id); +extern void dump_mmdvfs_info(void); + + +/* Extern from other module */ +extern MTK_SMI_BWC_SCEN smi_get_current_profile(void); +extern int is_mmdvfs_freq_hopping_disabled(void); +extern int is_mmdvfs_freq_mux_disabled(void); +extern int is_force_max_mmsys_clk(void); +extern int is_force_camera_hpm(void); +extern int is_mmdvfs_disabled(void); + + +#ifdef MMDVFS_STANDALONE +#define vcorefs_request_dvfs_opp(scen, mode) do { \ + MMDVFSMSG("vcorefs_request_dvfs_opp"); \ + MMDVFSMSG("MMDVFS_STANDALONE mode enabled\n"); \ +} while (0) + +#define fliper_set_bw(BW_THRESHOLD_HIGH) do { \ + MMDVFSMSG("MMDVFS_STANDALONE mode enabled\n"); \ + MMDVFSMSG("fliper_set_bw");\ +} while (0) + +#define fliper_restore_bw() do {\ + MMDVFSMSG("MMDVFS_STANDALONE mode enabled\n"); \ + MMDVFSMSG("fliper_restore_bw(): fliper normal\n"); \ +} while (0) + +#endif /* MMDVFS_STANDALONE */ + +#ifdef MMDVFS_WQHD_1_0V +#include "disp_session.h" +extern int primary_display_switch_mode_for_mmdvfs(int sess_mode, unsigned int session, int blocking); +#endif + +/* D2 plus only */ +#if defined(SMI_D2) +extern void mt_set_vencpll_con1(int val); +extern int clkmux_sel(int id, unsigned int clksrc, char *name); +#endif + +/* D1 plus implementation only */ +extern u32 get_devinfo_with_index(u32 index); + +#define MMDVFS_PROFILE_UNKNOWN (0) +#define MMDVFS_PROFILE_R1 (1) +#define MMDVFS_PROFILE_J1 (2) +#define MMDVFS_PROFILE_D1 (3) +#define MMDVFS_PROFILE_D1_PLUS (4) +#define MMDVFS_PROFILE_D2 (5) +#define MMDVFS_PROFILE_D2_M_PLUS (6) +#define MMDVFS_PROFILE_D2_P_PLUS (7) +#define MMDVFS_PROFILE_D3 (8) +#define MMDVFS_PROFILE_E1 (9) + + +enum { + MMDVFS_CAM_MON_SCEN = SMI_BWC_SCEN_CNT, MMDVFS_SCEN_MHL, MMDVFS_SCEN_MJC, MMDVFS_SCEN_DISP, + MMDVFS_SCEN_ISP, MMDVFS_SCEN_VP_HIGH_RESOLUTION , MMDVFS_SCEN_COUNT +}; + +/* Backward compatible */ +#define SMI_BWC_SCEN_120HZ MMDVFS_SCEN_DISP + + +#ifndef CONFIG_MTK_SMI_EXT +#define mmdvfs_set_step(scenario, step) +#else +int mmdvfs_set_step(MTK_SMI_BWC_SCEN scenario, mmdvfs_voltage_enum step); +#endif /* CONFIG_MTK_SMI_EXT */ + +extern int mmdvfs_get_mmdvfs_profile(void); +extern int is_mmdvfs_supported(void); +extern int mmdvfs_set_mmsys_clk(MTK_SMI_BWC_SCEN scenario, int mmsys_clk_mode); + +#endif /* __MMDVFS_MGR_H__ */ diff --git a/drivers/misc/mediatek/smi/mmdvfs_mgr_v2.c b/drivers/misc/mediatek/smi/mmdvfs_mgr_v2.c new file mode 100644 index 000000000..fd9dc9c2d --- /dev/null +++ b/drivers/misc/mediatek/smi/mmdvfs_mgr_v2.c @@ -0,0 +1,1019 @@ +#include <linux/uaccess.h> +#include <linux/timer.h> +#include <linux/jiffies.h> +#include <linux/workqueue.h> +#include <linux/mtk_gpu_utility.h> + +#include <aee.h> +#include <mt_smi.h> + + + + +#ifndef MMDVFS_STANDALONE +#include <mt_vcorefs_manager.h> +#endif +#include <mach/mt_freqhopping.h> + + +#include "mmdvfs_mgr.h" + +#undef pr_fmt +#define pr_fmt(fmt) "[" MMDVFS_LOG_TAG "]" fmt + +/* MMDVFS SWITCH. NO MMDVFS for 6595 */ +#if IS_ENABLED(CONFIG_ARM64) +/* 6795 */ +#define MMDVFS_ENABLE 1 +#else +/* 6595 */ +#define MMDVFS_ENABLE 0 +#endif + +#if MMDVFS_ENABLE +#ifndef MMDVFS_STANDALONE +#include <mach/fliper.h> +#endif +#endif + +/* WQHD MMDVFS SWITCH */ +#define MMDVFS_ENABLE_WQHD 0 + +#define MMDVFS_GPU_LOADING_NUM 30 +#define MMDVFS_GPU_LOADING_START_INDEX 10 +#define MMDVFS_GPU_LOADING_SAMPLE_DURATION_IN_MS 100 +#define MMDVFS_GPU_LOADING_THRESHOLD 18 + +/* enable WQHD defalt 1.0v */ +/* #define MMDVFS_WQHD_1_0V */ + +#if (MMDVFS_GPU_LOADING_START_INDEX >= MMDVFS_GPU_LOADING_NUM) +#error "start index too large" +#endif + +/* mmdvfs MM sizes */ +#define MMDVFS_PIXEL_NUM_720P (1280 * 720) +#define MMDVFS_PIXEL_NUM_2160P (3840 * 2160) +#define MMDVFS_PIXEL_NUM_1080P (2100 * 1300) +#define MMDVFS_PIXEL_NUM_2M (2100 * 1300) +#define MMDVFS_PIXEL_NUM_13M (13000000) + +/* 13M sensor */ +#define MMDVFS_PIXEL_NUM_SENSOR_FULL (13000000) + +/* mmdvfs display sizes */ +#define MMDVFS_DISPLAY_SIZE_FHD (1920 * 1216) + +#define MMDVFS_CLK_SWITCH_CB_MAX 16 +#define MMDVFS_CLK_SWITCH_CLIENT_MSG_MAX 20 + +static int notify_cb_func_checked(clk_switch_cb func, int ori_mmsys_clk_mode, +int update_mmsys_clk_mode, char *msg); +static int mmdfvs_adjust_mmsys_clk_by_hopping(int clk_mode); +static int mmdvfs_set_step_with_mmsys_clk(MTK_SMI_BWC_SCEN scenario, mmdvfs_voltage_enum step, +int mmsys_clk_mode); +static void notify_mmsys_clk_change(int ori_mmsys_clk_mode, int update_mmsys_clk_mode); +static int mmsys_clk_change_notify_checked(clk_switch_cb func, int ori_mmsys_clk_mode, +int update_mmsys_clk_mode, char *msg); +static mmdvfs_voltage_enum determine_current_mmsys_clk(void); +static int is_cam_monior_work; + + +enum { + MMDVFS_CAM_MON_SCEN = SMI_BWC_SCEN_CNT, MMDVFS_SCEN_MHL, MMDVFS_SCEN_COUNT +}; + +static clk_switch_cb quick_mmclk_cbs[MMDVFS_CLK_SWITCH_CB_MAX]; +static clk_switch_cb notify_cb_func; +static clk_switch_cb notify_cb_func_nolock; +static int current_mmsys_clk = MMSYS_CLK_MEDIUM; + +/* + 1 for MMDVFS_CAM_MON_SCEN */ +static mmdvfs_voltage_enum g_mmdvfs_scenario_voltage[MMDVFS_SCEN_COUNT] = { +MMDVFS_VOLTAGE_DEFAULT}; +static mmdvfs_voltage_enum g_mmdvfs_current_step; +static unsigned int g_mmdvfs_concurrency; +static MTK_SMI_BWC_MM_INFO *g_mmdvfs_info; +static MTK_MMDVFS_CMD g_mmdvfs_cmd; + +/* mmdvfs timer for monitor gpu loading */ +typedef struct { + /* linux timer */ + struct timer_list timer; + + /* work q */ + struct workqueue_struct *work_queue; + struct work_struct work; + + /* data payload */ + unsigned int gpu_loadings[MMDVFS_GPU_LOADING_NUM]; + int gpu_loading_index; +} mmdvfs_gpu_monitor_struct; + +typedef struct { + spinlock_t scen_lock; + int is_mhl_enable; + mmdvfs_gpu_monitor_struct gpu_monitor; + +} mmdvfs_context_struct; + +/* mmdvfs_query() return value, remember to sync with user space */ +typedef enum { + MMDVFS_STEP_LOW = 0, MMDVFS_STEP_HIGH, + + MMDVFS_STEP_LOW2LOW, /* LOW */ + MMDVFS_STEP_HIGH2LOW, /* LOW */ + MMDVFS_STEP_LOW2HIGH, /* HIGH */ + MMDVFS_STEP_HIGH2HIGH, +/* HIGH */ +} mmdvfs_step_enum; + +/* lcd size */ +typedef enum { + MMDVFS_LCD_SIZE_FHD, MMDVFS_LCD_SIZE_WQHD, MMDVFS_LCD_SIZE_END_OF_ENUM +} mmdvfs_lcd_size_enum; + +static mmdvfs_context_struct g_mmdvfs_mgr_cntx; +static mmdvfs_context_struct * const g_mmdvfs_mgr = &g_mmdvfs_mgr_cntx; + +static mmdvfs_lcd_size_enum mmdvfs_get_lcd_resolution(void) +{ + if (DISP_GetScreenWidth() * DISP_GetScreenHeight() + <= MMDVFS_DISPLAY_SIZE_FHD) { + return MMDVFS_LCD_SIZE_FHD; + } + + return MMDVFS_LCD_SIZE_WQHD; +} + +static mmdvfs_voltage_enum mmdvfs_get_default_step(void) +{ +#ifdef MMDVFS_WQHD_1_0V + return MMDVFS_VOLTAGE_LOW; +#else + if (mmdvfs_get_lcd_resolution() == MMDVFS_LCD_SIZE_FHD) + return MMDVFS_VOLTAGE_LOW; + else + return MMDVFS_VOLTAGE_HIGH; +#endif +} + +static mmdvfs_voltage_enum mmdvfs_get_current_step(void) +{ + return g_mmdvfs_current_step; +} + +static int mmsys_clk_query(MTK_SMI_BWC_SCEN scenario, +MTK_MMDVFS_CMD *cmd) +{ + int step = MMSYS_CLK_MEDIUM; + + unsigned int venc_size; + MTK_MMDVFS_CMD cmd_default; + + venc_size = g_mmdvfs_info->video_record_size[0] + * g_mmdvfs_info->video_record_size[1]; + + /* use default info */ + if (cmd == NULL) { + memset(&cmd_default, 0, sizeof(MTK_MMDVFS_CMD)); + cmd_default.camera_mode = MMDVFS_CAMERA_MODE_FLAG_DEFAULT; + cmd = &cmd_default; + } + + /* collect the final information */ + if (cmd->sensor_size == 0) + cmd->sensor_size = g_mmdvfs_cmd.sensor_size; + + if (cmd->sensor_fps == 0) + cmd->sensor_fps = g_mmdvfs_cmd.sensor_fps; + + if (cmd->camera_mode == MMDVFS_CAMERA_MODE_FLAG_DEFAULT) + cmd->camera_mode = g_mmdvfs_cmd.camera_mode; + + /* HIGH level scenarios */ + switch (scenario) { + case SMI_BWC_SCEN_VR: + if (is_force_max_mmsys_clk()) + step = MMSYS_CLK_HIGH; + + if (cmd->sensor_size >= MMDVFS_PIXEL_NUM_13M) + /* 13M high */ + step = MMSYS_CLK_HIGH; + else if (cmd->camera_mode & (MMDVFS_CAMERA_MODE_FLAG_PIP | MMDVFS_CAMERA_MODE_FLAG_STEREO)) + /* PIP for ISP clock */ + step = MMSYS_CLK_HIGH; + break; + + case SMI_BWC_SCEN_VR_SLOW: + case SMI_BWC_SCEN_ICFP: + step = MMSYS_CLK_HIGH; + break; + + default: + break; + } + + return step; +} + +static mmdvfs_voltage_enum mmdvfs_query(MTK_SMI_BWC_SCEN scenario, +MTK_MMDVFS_CMD *cmd) +{ + mmdvfs_voltage_enum step = mmdvfs_get_default_step(); + unsigned int venc_size; + MTK_MMDVFS_CMD cmd_default; + + venc_size = g_mmdvfs_info->video_record_size[0] + * g_mmdvfs_info->video_record_size[1]; + + /* use default info */ + if (cmd == NULL) { + memset(&cmd_default, 0, sizeof(MTK_MMDVFS_CMD)); + cmd_default.camera_mode = MMDVFS_CAMERA_MODE_FLAG_DEFAULT; + cmd = &cmd_default; + } + + /* collect the final information */ + if (cmd->sensor_size == 0) + cmd->sensor_size = g_mmdvfs_cmd.sensor_size; + + if (cmd->sensor_fps == 0) + cmd->sensor_fps = g_mmdvfs_cmd.sensor_fps; + + if (cmd->camera_mode == MMDVFS_CAMERA_MODE_FLAG_DEFAULT) + cmd->camera_mode = g_mmdvfs_cmd.camera_mode; + + /* HIGH level scenarios */ + switch (scenario) { + + case SMI_BWC_SCEN_VR: + if (is_force_camera_hpm()) + step = MMDVFS_VOLTAGE_HIGH; + + if (cmd->sensor_size >= MMDVFS_PIXEL_NUM_13M) + /* 13M high */ + step = MMDVFS_VOLTAGE_HIGH; + else if (cmd->camera_mode & (MMDVFS_CAMERA_MODE_FLAG_PIP | MMDVFS_CAMERA_MODE_FLAG_STEREO | + MMDVFS_CAMERA_MODE_FLAG_VFB | MMDVFS_CAMERA_MODE_FLAG_EIS_2_0)) + /* PIP for ISP clock */ + step = MMDVFS_VOLTAGE_HIGH; + + break; + + case SMI_BWC_SCEN_VR_SLOW: + case SMI_BWC_SCEN_ICFP: + step = MMDVFS_VOLTAGE_HIGH; + break; + + default: + break; + } + + return step; +} + +static mmdvfs_voltage_enum determine_current_mmsys_clk(void) +{ + int i = 0; + int final_clk = MMSYS_CLK_MEDIUM; + + for (i = 0; i < MMDVFS_SCEN_COUNT; i++) { + if (g_mmdvfs_scenario_voltage[i] == MMDVFS_VOLTAGE_HIGH) { + /* Check the mmsys clk */ + switch (i) { + case SMI_BWC_SCEN_VR: + case MMDVFS_CAM_MON_SCEN: + if (is_force_max_mmsys_clk()) + final_clk = MMSYS_CLK_HIGH; + else if (g_mmdvfs_cmd.sensor_size >= MMDVFS_PIXEL_NUM_13M) + /* 13M high */ + final_clk = MMSYS_CLK_HIGH; + else if (g_mmdvfs_cmd.camera_mode & (MMDVFS_CAMERA_MODE_FLAG_PIP | + MMDVFS_CAMERA_MODE_FLAG_STEREO)) + /* PIP for ISP clock */ + final_clk = MMSYS_CLK_HIGH; + break; + case SMI_BWC_SCEN_VR_SLOW: + case SMI_BWC_SCEN_ICFP: + final_clk = MMSYS_CLK_HIGH; + break; + default: + break; + } + } + } + + return final_clk; +} + + +static void mmdvfs_update_cmd(MTK_MMDVFS_CMD *cmd) +{ + if (cmd == NULL) + return; + + if (cmd->sensor_size) + g_mmdvfs_cmd.sensor_size = cmd->sensor_size; + + if (cmd->sensor_fps) + g_mmdvfs_cmd.sensor_fps = cmd->sensor_fps; + + /* MMDVFSMSG("update cm %d\n", cmd->camera_mode); */ + + /* if (cmd->camera_mode != MMDVFS_CAMERA_MODE_FLAG_DEFAULT) { */ + g_mmdvfs_cmd.camera_mode = cmd->camera_mode; + /* } */ +} + +/* static void mmdvfs_dump_info(void) +{ + MMDVFSMSG("CMD %d %d %d\n", g_mmdvfs_cmd.sensor_size, + g_mmdvfs_cmd.sensor_fps, g_mmdvfs_cmd.camera_mode); + MMDVFSMSG("INFO VR %d %d\n", g_mmdvfs_info->video_record_size[0], + g_mmdvfs_info->video_record_size[1]); +} +*/ + +#ifdef MMDVFS_GPU_MONITOR_ENABLE +static void mmdvfs_timer_callback(unsigned long data) +{ + mmdvfs_gpu_monitor_struct *gpu_monitor = + (mmdvfs_gpu_monitor_struct *)data; + + unsigned int gpu_loading = 0; + + /* if (mtk_get_gpu_loading(&gpu_loading)) { + MMDVFSMSG("gpuload %d %ld\n", gpu_loading, jiffies_to_msecs(jiffies)); + */ + + /* store gpu loading into the array */ + gpu_monitor->gpu_loadings[gpu_monitor->gpu_loading_index++] + = gpu_loading; + + /* fire another timer until the end */ + if (gpu_monitor->gpu_loading_index < MMDVFS_GPU_LOADING_NUM - 1) { + mod_timer( + &gpu_monitor->timer, + jiffies + msecs_to_jiffies( + MMDVFS_GPU_LOADING_SAMPLE_DURATION_IN_MS)); + } else { + /* the final timer */ + int i; + int avg_loading; + unsigned int sum = 0; + + for (i = MMDVFS_GPU_LOADING_START_INDEX; i + < MMDVFS_GPU_LOADING_NUM; i++) { + sum += gpu_monitor->gpu_loadings[i]; + } + + avg_loading = sum / MMDVFS_GPU_LOADING_NUM; + + MMDVFSMSG("gpuload %d AVG %d\n", jiffies_to_msecs(jiffies), + avg_loading); + + /* drops to low step if the gpu loading is low */ + if (avg_loading <= MMDVFS_GPU_LOADING_THRESHOLD) + queue_work(gpu_monitor->work_queue, &gpu_monitor->work); + } + +} + +static void mmdvfs_gpu_monitor_work(struct work_struct *work) +{ + MMDVFSMSG("WQ %d\n", jiffies_to_msecs(jiffies)); +} + +static void mmdvfs_init_gpu_monitor(mmdvfs_gpu_monitor_struct *gm) +{ + struct timer_list *gpu_timer = &gm->timer; + + /* setup gpu monitor timer */ + setup_timer(gpu_timer, mmdvfs_timer_callback, (unsigned long)gm); + + gm->work_queue = create_singlethread_workqueue("mmdvfs_gpumon"); + INIT_WORK(&gm->work, mmdvfs_gpu_monitor_work); +} +#endif /* MMDVFS_GPU_MONITOR_ENABLE */ + +/* delay 4 seconds to go LPM to workaround camera ZSD + PIP issue */ +static void mmdvfs_cam_work_handler(struct work_struct *work) +{ + /* MMDVFSMSG("CAM handler %d\n", jiffies_to_msecs(jiffies)); */ + mmdvfs_set_step(MMDVFS_CAM_MON_SCEN, mmdvfs_get_default_step()); + + spin_lock(&g_mmdvfs_mgr->scen_lock); + is_cam_monior_work = 0; + spin_unlock(&g_mmdvfs_mgr->scen_lock); + +} + +static DECLARE_DELAYED_WORK(g_mmdvfs_cam_work, mmdvfs_cam_work_handler); + +static void mmdvfs_stop_cam_monitor(void) +{ + cancel_delayed_work_sync(&g_mmdvfs_cam_work); +} + +#define MMDVFS_CAM_MON_DELAY (6 * HZ) +static void mmdvfs_start_cam_monitor(int scen) +{ + int delayed_mmsys_state = MMSYS_CLK_MEDIUM; + + mmdvfs_stop_cam_monitor(); + + spin_lock(&g_mmdvfs_mgr->scen_lock); + is_cam_monior_work = 1; + spin_unlock(&g_mmdvfs_mgr->scen_lock); + + + if (current_mmsys_clk == MMSYS_CLK_LOW) { + MMDVFSMSG("Can't switch clk by hopping when CLK is low\n"); + delayed_mmsys_state = MMSYS_CLK_MEDIUM; + } else { + delayed_mmsys_state = current_mmsys_clk; + } + + /* MMDVFSMSG("CAM start %d\n", jiffies_to_msecs(jiffies)); */ + + if (is_force_max_mmsys_clk()) { + + mmdvfs_set_step_with_mmsys_clk(MMDVFS_CAM_MON_SCEN, MMDVFS_VOLTAGE_HIGH, MMSYS_CLK_HIGH); + + } else if (scen == SMI_BWC_SCEN_ICFP || scen == SMI_BWC_SCEN_VR_SLOW || scen == SMI_BWC_SCEN_VR) { + + if (g_mmdvfs_cmd.camera_mode & (MMDVFS_CAMERA_MODE_FLAG_PIP | MMDVFS_CAMERA_MODE_FLAG_STEREO)) + mmdvfs_set_step_with_mmsys_clk(MMDVFS_CAM_MON_SCEN, MMDVFS_VOLTAGE_HIGH, MMSYS_CLK_HIGH); + /* MMDVFSMSG("CAM monitor keep MMSYS_CLK_HIGH\n"); */ + else if (g_mmdvfs_cmd.camera_mode & (MMDVFS_CAMERA_MODE_FLAG_VFB | MMDVFS_CAMERA_MODE_FLAG_EIS_2_0)) + mmdvfs_set_step_with_mmsys_clk(MMDVFS_CAM_MON_SCEN, MMDVFS_VOLTAGE_HIGH, delayed_mmsys_state); + /* + else { + MMDVFSMSG("Keep cam monitor going so that DISP can't disable the vencpll\n"); + } + */ + + } + /* 4 seconds for PIP switch preview aspect delays... */ + schedule_delayed_work(&g_mmdvfs_cam_work, MMDVFS_CAM_MON_DELAY); +} + +#if MMDVFS_ENABLE_WQHD + +static void mmdvfs_start_gpu_monitor(mmdvfs_gpu_monitor_struct *gm) +{ + struct timer_list *gpu_timer = &gm->timer; + + gm->gpu_loading_index = 0; + memset(gm->gpu_loadings, 0, sizeof(unsigned int) * MMDVFS_GPU_LOADING_NUM); + + mod_timer(gpu_timer, jiffies + msecs_to_jiffies(MMDVFS_GPU_LOADING_SAMPLE_DURATION_IN_MS)); +} + +static void mmdvfs_stop_gpu_monitor(mmdvfs_gpu_monitor_struct *gm) +{ + struct timer_list *gpu_timer = &gm->timer; + + /* flush workqueue */ + flush_workqueue(gm->work_queue); + /* delete timer */ + del_timer(gpu_timer); +} + +#endif /* MMDVFS_ENABLE_WQHD */ + +static void mmdvfs_vcorefs_request_dvfs_opp(int mm_kicker, int mm_dvfs_opp) +{ + int vcore_enable = 0; + + vcore_enable = is_vcorefs_can_work(); + + if (vcore_enable != 1) { + MMDVFSMSG("Vcore disable: is_vcorefs_can_work = %d, (%d, %d)\n", vcore_enable, mm_kicker, mm_dvfs_opp); + } else { + /* MMDVFSMSG("Vcore trigger: is_vcorefs_can_work = %d, (%d, %d)\n", vcore_enable, + mm_kicker, mm_dvfs_opp); */ + vcorefs_request_dvfs_opp(mm_kicker, mm_dvfs_opp); + } +} + +int mmdvfs_set_step(MTK_SMI_BWC_SCEN scenario, mmdvfs_voltage_enum step) +{ + return mmdvfs_set_step_with_mmsys_clk(scenario, step, MMSYS_CLK_MEDIUM); +} + +int mmdvfs_set_step_with_mmsys_clk(MTK_SMI_BWC_SCEN smi_scenario, mmdvfs_voltage_enum step, int mmsys_clk_mode_request) +{ + int i, scen_index; + unsigned int concurrency; + unsigned int scenario = smi_scenario; + mmdvfs_voltage_enum final_step = mmdvfs_get_default_step(); + int mmsys_clk_step = MMSYS_CLK_MEDIUM; + int mmsys_clk_mode = mmsys_clk_mode_request; + + /* workaround for WFD VENC scenario*/ + if (scenario == SMI_BWC_SCEN_VENC || scenario == SMI_BWC_SCEN_VP) + return 0; + + if (step == MMDVFS_VOLTAGE_DEFAULT_STEP) + step = final_step; + +#if !MMDVFS_ENABLE + return 0; +#endif + + /* MMDVFSMSG("MMDVFS set voltage scen %d step %d\n", scenario, step); */ + + if ((scenario >= (MTK_SMI_BWC_SCEN)MMDVFS_SCEN_COUNT) || (scenario + < SMI_BWC_SCEN_NORMAL)) { + MMDVFSERR("invalid scenario\n"); + return -1; + } + + /* dump information */ + /* mmdvfs_dump_info(); */ + + /* go through all scenarios to decide the final step */ + scen_index = (int)scenario; + + spin_lock(&g_mmdvfs_mgr->scen_lock); + + g_mmdvfs_scenario_voltage[scen_index] = step; + + concurrency = 0; + for (i = 0; i < MMDVFS_SCEN_COUNT; i++) { + if (g_mmdvfs_scenario_voltage[i] == MMDVFS_VOLTAGE_HIGH) + concurrency |= 1 << i; + } + + /* one high = final high */ + for (i = 0; i < MMDVFS_SCEN_COUNT; i++) { + if (g_mmdvfs_scenario_voltage[i] == MMDVFS_VOLTAGE_HIGH) { + final_step = MMDVFS_VOLTAGE_HIGH; + break; + } + } + + mmsys_clk_step = determine_current_mmsys_clk(); + if (mmsys_clk_mode_request == MMSYS_CLK_MEDIUM && mmsys_clk_step == MMSYS_CLK_HIGH) + mmsys_clk_mode = MMSYS_CLK_HIGH; + else + mmsys_clk_mode = mmsys_clk_mode_request; + + g_mmdvfs_current_step = final_step; + + spin_unlock(&g_mmdvfs_mgr->scen_lock); + +#if MMDVFS_ENABLE + + /* call vcore dvfs API */ + /* MMDVFSMSG("FHD %d\n", final_step); */ + + + + if (final_step == MMDVFS_VOLTAGE_HIGH) { + if (scenario == MMDVFS_SCEN_MHL) + mmdvfs_vcorefs_request_dvfs_opp(KIR_MM_MHL, OPPI_PERF); + else if (scenario == SMI_BWC_SCEN_WFD) + mmdvfs_vcorefs_request_dvfs_opp(KIR_MM_WFD, OPPI_PERF); + else { + mmdvfs_vcorefs_request_dvfs_opp(KIR_MM_16MCAM, OPPI_PERF); + if (mmsys_clk_mode == MMSYS_CLK_HIGH) + mmdfvs_adjust_mmsys_clk_by_hopping(MMSYS_CLK_HIGH); + else + mmdfvs_adjust_mmsys_clk_by_hopping(MMSYS_CLK_MEDIUM); + } + } else{ + if (scenario == MMDVFS_SCEN_MHL) + mmdvfs_vcorefs_request_dvfs_opp(KIR_MM_MHL, OPPI_UNREQ); + else if (scenario == SMI_BWC_SCEN_WFD) + mmdvfs_vcorefs_request_dvfs_opp(KIR_MM_WFD, OPPI_UNREQ); + else { + /* must lower the mmsys clk before enter LPM mode */ + mmdfvs_adjust_mmsys_clk_by_hopping(MMSYS_CLK_MEDIUM); + mmdvfs_vcorefs_request_dvfs_opp(KIR_MM_16MCAM, OPPI_UNREQ); + } + } +#endif /* MMDVFS_ENABLE */ + + MMDVFSMSG("Set vol scen:%d,step:%d,final:%d(0x%x),CMD(%d,%d,0x%x),INFO(%d,%d),CLK:%d\n", + scenario, step, final_step, concurrency, + g_mmdvfs_cmd.sensor_size, g_mmdvfs_cmd.sensor_fps, g_mmdvfs_cmd.camera_mode, + g_mmdvfs_info->video_record_size[0], g_mmdvfs_info->video_record_size[1], + current_mmsys_clk); + + + return 0; +} + +void mmdvfs_handle_cmd(MTK_MMDVFS_CMD *cmd) +{ +#if !MMDVFS_ENABLE + return; +#endif + + /* MMDVFSMSG("MMDVFS handle cmd %u s %d\n", cmd->type, cmd->scen); */ + + switch (cmd->type) { + case MTK_MMDVFS_CMD_TYPE_SET: + /* save cmd */ + mmdvfs_update_cmd(cmd); + + if (!(g_mmdvfs_concurrency & (1 << cmd->scen))) { + MMDVFSMSG("invalid set scen %d\n", cmd->scen); + cmd->ret = -1; + } else { + cmd->ret = mmdvfs_set_step_with_mmsys_clk(cmd->scen, + mmdvfs_query(cmd->scen, cmd), mmsys_clk_query(cmd->scen, cmd)); + } + break; + + case MTK_MMDVFS_CMD_TYPE_QUERY: { /* query with some parameters */ +#ifndef MMDVFS_WQHD_1_0V + if (mmdvfs_get_lcd_resolution() == MMDVFS_LCD_SIZE_WQHD) { + /* QUERY ALWAYS HIGH for WQHD */ + cmd->ret = (unsigned int)MMDVFS_STEP_HIGH2HIGH; + } else +#endif + { + mmdvfs_voltage_enum query_voltage = mmdvfs_query(cmd->scen, cmd); + + mmdvfs_voltage_enum current_voltage = mmdvfs_get_current_step(); + + if (current_voltage < query_voltage) { + cmd->ret = (unsigned int)MMDVFS_STEP_LOW2HIGH; + } else if (current_voltage > query_voltage) { + cmd->ret = (unsigned int)MMDVFS_STEP_HIGH2LOW; + } else { + cmd->ret + = (unsigned int)(query_voltage + == MMDVFS_VOLTAGE_HIGH + ? MMDVFS_STEP_HIGH2HIGH + : MMDVFS_STEP_LOW2LOW); + } + } + + /* MMDVFSMSG("query %d\n", cmd->ret); */ + /* cmd->ret = (unsigned int)query_voltage; */ + break; + } + + default: + MMDVFSMSG("invalid mmdvfs cmd\n"); + BUG(); + break; + } +} + +void mmdvfs_notify_scenario_exit(MTK_SMI_BWC_SCEN scen) +{ +#if !MMDVFS_ENABLE + return; +#endif + + /* MMDVFSMSG("leave %d\n", scen); */ + + if ((scen == SMI_BWC_SCEN_VR) || (scen == SMI_BWC_SCEN_VR_SLOW) || (scen == SMI_BWC_SCEN_ICFP)) + mmdvfs_start_cam_monitor(scen); + + /* reset scenario voltage to default when it exits */ + mmdvfs_set_step(scen, mmdvfs_get_default_step()); +} + +void mmdvfs_notify_scenario_enter(MTK_SMI_BWC_SCEN scen) +{ +#if !MMDVFS_ENABLE + return; +#endif + + /* MMDVFSMSG("enter %d\n", scen); */ + + switch (scen) { + case SMI_BWC_SCEN_WFD: + mmdvfs_set_step(scen, MMDVFS_VOLTAGE_HIGH); + if (current_mmsys_clk == MMSYS_CLK_LOW) + mmdvfs_raise_mmsys_by_mux(); + break; + case SMI_BWC_SCEN_VR: + if (current_mmsys_clk == MMSYS_CLK_LOW) + mmdvfs_raise_mmsys_by_mux(); + + if (is_force_camera_hpm()) { + if (is_force_max_mmsys_clk()) + mmdvfs_set_step_with_mmsys_clk(scen, MMDVFS_VOLTAGE_HIGH, MMSYS_CLK_HIGH); + else + mmdvfs_set_step(scen, MMDVFS_VOLTAGE_HIGH); + } else { + if (g_mmdvfs_cmd.camera_mode & (MMDVFS_CAMERA_MODE_FLAG_PIP | MMDVFS_CAMERA_MODE_FLAG_STEREO)) { + mmdvfs_set_step_with_mmsys_clk(scen, MMDVFS_VOLTAGE_HIGH, MMSYS_CLK_HIGH); + } else if (g_mmdvfs_cmd.camera_mode & (MMDVFS_CAMERA_MODE_FLAG_VFB | + MMDVFS_CAMERA_MODE_FLAG_EIS_2_0)){ + mmdvfs_set_step(scen, MMDVFS_VOLTAGE_HIGH); + } + } + break; + case SMI_BWC_SCEN_VR_SLOW: + case SMI_BWC_SCEN_ICFP: + if (current_mmsys_clk == MMSYS_CLK_LOW) + mmdvfs_raise_mmsys_by_mux(); + mmdvfs_set_step_with_mmsys_clk(scen, MMDVFS_VOLTAGE_HIGH, MMSYS_CLK_HIGH); + break; + + default: + break; + } +} + +void mmdvfs_init(MTK_SMI_BWC_MM_INFO *info) +{ +#if !MMDVFS_ENABLE + return; +#endif + + spin_lock_init(&g_mmdvfs_mgr->scen_lock); + /* set current step as the default step */ + g_mmdvfs_current_step = mmdvfs_get_default_step(); + + g_mmdvfs_info = info; + +#ifdef MMDVFS_GPU_MONITOR_ENABLE + mmdvfs_init_gpu_monitor(&g_mmdvfs_mgr->gpu_monitor); +#endif /* MMDVFS_GPU_MONITOR_ENABLE */ +} + +void mmdvfs_mhl_enable(int enable) +{ + g_mmdvfs_mgr->is_mhl_enable = enable; + + if (enable) + mmdvfs_set_step(MMDVFS_SCEN_MHL, MMDVFS_VOLTAGE_HIGH); + else + mmdvfs_set_step(MMDVFS_SCEN_MHL, MMDVFS_VOLTAGE_DEFAULT_STEP); +} + +void mmdvfs_notify_scenario_concurrency(unsigned int u4Concurrency) +{ + /* + * DO NOT CALL VCORE DVFS API HERE. THIS FUNCTION IS IN SMI SPIN LOCK. + */ + + /* raise EMI monitor BW threshold in VP, VR, VR SLOW motion cases to + make sure vcore stay MMDVFS level as long as possible */ + if (u4Concurrency & ((1 << SMI_BWC_SCEN_VP) | (1 << SMI_BWC_SCEN_VR) + | (1 << SMI_BWC_SCEN_VR_SLOW))) { +#if MMDVFS_ENABLE + /* MMDVFSMSG("fliper high\n"); */ + /* fliper_set_bw(BW_THRESHOLD_HIGH); */ +#endif + } else { +#if MMDVFS_ENABLE + /* MMDVFSMSG("fliper normal\n"); */ + /* fliper_restore_bw(); */ +#endif + } + + g_mmdvfs_concurrency = u4Concurrency; +} + +int mmdvfs_is_default_step_need_perf(void) +{ + if (mmdvfs_get_default_step() == MMDVFS_VOLTAGE_LOW) + return 0; + else + return 1; +} + +/* switch MM CLK callback from VCORE DVFS driver */ +void mmdvfs_mm_clock_switch_notify(int is_before, int is_to_high) +{ + /* for WQHD 1.0v, we have to dynamically switch DL/DC */ +#ifdef MMDVFS_WQHD_1_0V + int session_id; + + if (mmdvfs_get_lcd_resolution() != MMDVFS_LCD_SIZE_WQHD) + return; + + session_id = MAKE_DISP_SESSION(DISP_SESSION_PRIMARY, 0); + + if (!is_before && is_to_high) { + MMDVFSMSG("DL\n"); + /* nonblocking switch to direct link after HPM */ + primary_display_switch_mode_for_mmdvfs(DISP_SESSION_DIRECT_LINK_MODE, session_id, 0); + } else if (is_before && !is_to_high) { + /* BLOCKING switch to decouple before switching to LPM */ + MMDVFSMSG("DC\n"); + primary_display_switch_mode_for_mmdvfs(DISP_SESSION_DECOUPLE_MODE, session_id, 1); + } +#endif /* MMDVFS_WQHD_1_0V */ +} + +static int mmdfvs_adjust_mmsys_clk_by_hopping(int clk_mode) +{ + int freq_hopping_disable = is_mmdvfs_freq_hopping_disabled(); + + int result = 0; + + if (clk_mode == MMSYS_CLK_HIGH) { + if (current_mmsys_clk == MMSYS_CLK_LOW) { + MMDVFSMSG("Doesn't allow mmsys clk adjust from low to high!\n"); + } else if (!freq_hopping_disable && current_mmsys_clk != MMSYS_CLK_HIGH) { + /* MMDVFSMSG("Freq hopping: DSS: %d\n", 0xE0000);*/ + mt_dfs_vencpll(0xE0000); + notify_cb_func_checked(notify_cb_func, current_mmsys_clk, MMSYS_CLK_HIGH, + "notify_cb_func"); + /* For common clients */ + notify_mmsys_clk_change(current_mmsys_clk, MMSYS_CLK_HIGH); + current_mmsys_clk = MMSYS_CLK_HIGH; + } else { + if (freq_hopping_disable) + MMDVFSMSG("Freq hopping disable, not trigger: DSS: %d\n", 0xE0000); + } + result = 1; + } else if (clk_mode == MMSYS_CLK_MEDIUM) { + if (!freq_hopping_disable && current_mmsys_clk != MMSYS_CLK_MEDIUM) { + /* MMDVFSMSG("Freq hopping: DSS: %d\n", 0xB0000); */ + mt_dfs_vencpll(0xB0000); + notify_cb_func_checked(notify_cb_func, current_mmsys_clk, MMSYS_CLK_MEDIUM, + "notify_cb_func"); + /* For common clients */ + notify_mmsys_clk_change(current_mmsys_clk, MMSYS_CLK_MEDIUM); + current_mmsys_clk = MMSYS_CLK_MEDIUM; + } else { + if (freq_hopping_disable) + MMDVFSMSG("Freq hopping disable, not trigger: DSS: %d\n", 0xB0000); + } + result = 1; + } else if (clk_mode == MMSYS_CLK_LOW) { + MMDVFSMSG("Doesn't support MMSYS_CLK_LOW with hopping in this platform\n"); + result = 1; + } else { + MMDVFSMSG("Don't change CLK: mode=%d\n", clk_mode); + result = 0; + } + + return result; +} + +int mmdvfs_raise_mmsys_by_mux(void) +{ + if (is_mmdvfs_freq_mux_disabled()) + return 0; + + notify_cb_func_checked(notify_cb_func, current_mmsys_clk, MMSYS_CLK_MEDIUM, + "notify_cb_func"); + current_mmsys_clk = MMSYS_CLK_MEDIUM; + return 1; + +} + +int mmdvfs_lower_mmsys_by_mux(void) +{ + if (is_mmdvfs_freq_mux_disabled()) + return 0; + + if (notify_cb_func != NULL && current_mmsys_clk != MMSYS_CLK_HIGH) { + notify_cb_func(current_mmsys_clk, MMSYS_CLK_LOW); + current_mmsys_clk = MMSYS_CLK_LOW; + } else{ + MMDVFSMSG("lower_cb_func has not been registered"); + return 0; + } + return 1; + +} + +int register_mmclk_switch_cb(clk_switch_cb notify_cb, +clk_switch_cb notify_cb_nolock) +{ + notify_cb_func = notify_cb; + notify_cb_func_nolock = notify_cb_nolock; + + return 1; +} + +static int notify_cb_func_checked(clk_switch_cb func, int ori_mmsys_clk_mode, int update_mmsys_clk_mode, char *msg) +{ + + if (is_mmdvfs_freq_mux_disabled()) { + MMDVFSMSG("notify_cb_func is disabled, not invoked: %s, (%d,%d)\n", msg, ori_mmsys_clk_mode, + update_mmsys_clk_mode); + return 0; + } + if (func == NULL) { + MMDVFSMSG("notify_cb_func is NULL, not invoked: %s, (%d,%d)\n", msg, ori_mmsys_clk_mode, + update_mmsys_clk_mode); + } else { + if (ori_mmsys_clk_mode != update_mmsys_clk_mode) + MMDVFSMSG("notify_cb_func: %s, (%d,%d)\n", msg, ori_mmsys_clk_mode, update_mmsys_clk_mode); + + func(ori_mmsys_clk_mode, update_mmsys_clk_mode); + return 1; + } + return 0; +} + +int mmdvfs_notify_mmclk_switch_request(int event) +{ + int i = 0; + MTK_SMI_BWC_SCEN current_smi_scenario = smi_get_current_profile(); + + /* Don't get the lock since there is no need to synchronize the is_cam_monior_work here*/ + if (is_cam_monior_work != 0) { + /* MMDVFSMSG("Doesn't handle disp request when cam monitor is active\n"); */ + return 0; + } + /* MMDVFSMSG("mmclk_switch_request: event=%d, current=%d", event, current_smi_scenario); */ + + /* Only in UI idle modw or VP 1 layer scenario */ + /* we can lower the mmsys clock */ + if (event == MMDVFS_EVENT_UI_IDLE_ENTER && current_smi_scenario == SMI_BWC_SCEN_NORMAL) { + for (i = 0; i < MMDVFS_SCEN_COUNT; i++) { + if (g_mmdvfs_scenario_voltage[i] == MMDVFS_VOLTAGE_HIGH) { + MMDVFSMSG("Doesn't switch to low mmsys clk; vore is still in HPM mode"); + return 0; + } + } + + /* call back from DISP so we don't need use DISP lock here */ + if (current_mmsys_clk != MMSYS_CLK_HIGH) { + /* Only disable VENC pll when clock is in 286MHz */ + notify_cb_func_checked(notify_cb_func_nolock, current_mmsys_clk, MMSYS_CLK_LOW, + "notify_cb_func_nolock"); + current_mmsys_clk = MMSYS_CLK_LOW; + return 1; + } + } else if (event == MMDVFS_EVENT_OVL_SINGLE_LAYER_EXIT || event == MMDVFS_EVENT_UI_IDLE_EXIT) { + if (current_mmsys_clk != MMSYS_CLK_HIGH) { + /* call back from DISP so we don't need use DISP lock here */ + notify_cb_func_checked(notify_cb_func_nolock, current_mmsys_clk, MMSYS_CLK_MEDIUM, + "notify_cb_func_nolock"); + current_mmsys_clk = MMSYS_CLK_MEDIUM; + return 1; + } + } else if (event == MMDVFS_EVENT_OVL_SINGLE_LAYER_ENTER && SMI_BWC_SCEN_VP) { + /* call back from DISP so we don't need use DISP lock here */ + if (current_mmsys_clk != MMSYS_CLK_HIGH) { + notify_cb_func_checked(notify_cb_func_nolock, current_mmsys_clk, MMSYS_CLK_LOW, + "notify_cb_func_nolock"); + current_mmsys_clk = MMSYS_CLK_LOW; + return 1; + } + } + return 0; +} + + +int mmdvfs_register_mmclk_switch_cb(clk_switch_cb notify_cb, int mmdvfs_client_id) +{ + if (mmdvfs_client_id >= 0 && mmdvfs_client_id < MMDVFS_CLK_SWITCH_CB_MAX) { + quick_mmclk_cbs[mmdvfs_client_id] = notify_cb; + } else{ + MMDVFSMSG("clk_switch_cb register failed: id=%d\n", mmdvfs_client_id); + return 1; + } + return 0; +} + +static int mmsys_clk_change_notify_checked(clk_switch_cb func, int ori_mmsys_clk_mode, +int update_mmsys_clk_mode, char *msg) +{ + if (func == NULL) { + MMDVFSMSG("notify_cb_func is NULL, not invoked: %s, (%d,%d)\n", msg, ori_mmsys_clk_mode, + update_mmsys_clk_mode); + } else { + MMDVFSMSG("notify_cb_func: %s, (%d,%d)\n", msg, ori_mmsys_clk_mode, update_mmsys_clk_mode); + func(ori_mmsys_clk_mode, update_mmsys_clk_mode); + return 1; + } + return 0; +} + +static void notify_mmsys_clk_change(int ori_mmsys_clk_mode, int update_mmsys_clk_mode) +{ + int i = 0; + + char msg[MMDVFS_CLK_SWITCH_CLIENT_MSG_MAX] = ""; + + for (i = 0; i < MMDVFS_CLK_SWITCH_CB_MAX; i++) { + snprintf(msg, MMDVFS_CLK_SWITCH_CLIENT_MSG_MAX, "id=%d", i); + if (quick_mmclk_cbs[i] != NULL) + mmsys_clk_change_notify_checked(quick_mmclk_cbs[i], ori_mmsys_clk_mode, + update_mmsys_clk_mode, msg); + } +} + + +void dump_mmdvfs_info(void) +{ + int i = 0; + + MMDVFSMSG("MMDVFS dump: CMD(%d,%d,0x%x),INFO VR(%d,%d),CLK: %d\n", + g_mmdvfs_cmd.sensor_size, g_mmdvfs_cmd.sensor_fps, g_mmdvfs_cmd.camera_mode, + g_mmdvfs_info->video_record_size[0], g_mmdvfs_info->video_record_size[1], + current_mmsys_clk); + + for (i = 0; i < MMDVFS_SCEN_COUNT; i++) + MMDVFSMSG("Secn:%d,vol-step:%d\n", i, g_mmdvfs_scenario_voltage[i]); + +} diff --git a/drivers/misc/mediatek/smi/mt6735/Makefile b/drivers/misc/mediatek/smi/mt6735/Makefile deleted file mode 100755 index 2f64b80f2..000000000 --- a/drivers/misc/mediatek/smi/mt6735/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -include $(srctree)/drivers/misc/mediatek/Makefile.custom - -obj-y += smi_debug.o -obj-y += mmdvfs_mgr.o - -ifeq ($(CONFIG_ARCH_MT6735),y) -obj-y += smi_common_d1.o -ccflags-y += -I$(srctree)/drivers/misc/mediatek/cmdq/$(MTK_PLATFORM)/mt6735/ -ccflags-y += -DD1 -endif - -ifeq ($(CONFIG_ARCH_MT6735M),y) -obj-y += smi_common_d2.o -ccflags-y += -I$(srctree)/drivers/misc/mediatek/cmdq/$(MTK_PLATFORM)/mt6735m/ -ccflags-y += -DD2 -endif - -ifeq ($(CONFIG_ARCH_MT6753),y) -obj-y += smi_common_d3.o -ccflags-y += -I$(srctree)/drivers/misc/mediatek/cmdq/$(MTK_PLATFORM)/mt6753/ -ccflags-y += -DD3 -endif
\ No newline at end of file diff --git a/drivers/misc/mediatek/smi/mt6735/mmdvfs_mgr.c b/drivers/misc/mediatek/smi/mt6735/mmdvfs_mgr.c deleted file mode 100644 index e4ba0e5d3..000000000 --- a/drivers/misc/mediatek/smi/mt6735/mmdvfs_mgr.c +++ /dev/null @@ -1,410 +0,0 @@ -#include <linux/uaccess.h> -#include <linux/aee.h> -#include <linux/xlog.h> -#include <mach/mt_smi.h> -#include <mach/mt_vcore_dvfs.h> -#include <linux/timer.h> -#include <linux/jiffies.h> -#include <linux/workqueue.h> - -#include <linux/mtk_gpu_utility.h> - -#include "mmdvfs_mgr.h" - -#undef pr_fmt -#define pr_fmt(fmt) "[" MMDVFS_LOG_TAG "]" fmt - -#if ((defined(D1) || defined(D2) || defined(D3)) && !IS_ENABLED(CONFIG_FPGA_EARLY_PORTING)) - #define MMDVFS_ENABLE 1 -#endif - -#if defined(D3) -#define MMDVFS_ENABLE_FLIPER_CONTROL 1 -#else -#define MMDVFS_ENABLE_FLIPER_CONTROL 0 -#endif - -#if MMDVFS_ENABLE_FLIPER_CONTROL -#include <mach/fliper.h> -#endif - -/* mmdvfs MM sizes */ -#define MMDVFS_PIXEL_NUM_720P (1280 * 720) -#define MMDVFS_PIXEL_NUM_2160P (3840 * 2160) -#define MMDVFS_PIXEL_NUM_1080P (2100 * 1300) -#define MMDVFS_PIXEL_NUM_2M (2100 * 1300) -/* 13M sensor */ -#define MMDVFS_PIXEL_NUM_SENSOR_FULL (13000000) -#define MMDVFS_PIXEL_NUM_SENSOR_6M ( 5800000) -#define MMDVFS_PIXEL_NUM_SENSOR_8M ( 7800000) - -/* mmdvfs display sizes */ -#define MMDVFS_DISPLAY_SIZE_HD (1280 * 832) -#define MMDVFS_DISPLAY_SIZE_FHD (1920 * 1216) - -/* screen size */ -extern unsigned int DISP_GetScreenWidth(void); -extern unsigned int DISP_GetScreenHeight(void); - -#define MMDVFS_CAM_MON_SCEN SMI_BWC_SCEN_CNT -#define MMDVFS_SCEN_COUNT (SMI_BWC_SCEN_CNT + 1) - -/* + 1 for MMDVFS_CAM_MON_SCEN */ -static mmdvfs_voltage_enum g_mmdvfs_scenario_voltage[MMDVFS_SCEN_COUNT] = {MMDVFS_VOLTAGE_DEFAULT}; -static mmdvfs_voltage_enum g_mmdvfs_current_step; -static MTK_SMI_BWC_MM_INFO *g_mmdvfs_info; -static MTK_MMDVFS_CMD g_mmdvfs_cmd; - -typedef struct -{ - spinlock_t scen_lock; - int is_mhl_enable; -} mmdvfs_context_struct; - -/* mmdvfs_query() return value, remember to sync with user space */ -typedef enum -{ - MMDVFS_STEP_LOW = 0, - MMDVFS_STEP_HIGH, - - MMDVFS_STEP_LOW2LOW, /* LOW */ - MMDVFS_STEP_HIGH2LOW, /* LOW */ - MMDVFS_STEP_LOW2HIGH, /* HIGH */ - MMDVFS_STEP_HIGH2HIGH, /* HIGH */ -} mmdvfs_step_enum; - -/* lcd size */ -typedef enum -{ - MMDVFS_LCD_SIZE_HD, - MMDVFS_LCD_SIZE_FHD, - MMDVFS_LCD_SIZE_WQHD, - MMDVFS_LCD_SIZE_END_OF_ENUM -} mmdvfs_lcd_size_enum; - -static mmdvfs_context_struct g_mmdvfs_mgr_cntx; -static mmdvfs_context_struct * const g_mmdvfs_mgr = &g_mmdvfs_mgr_cntx; - -static mmdvfs_lcd_size_enum mmdvfs_get_lcd_resolution(void) -{ - if (DISP_GetScreenWidth() * DISP_GetScreenHeight() <= MMDVFS_DISPLAY_SIZE_HD) { - return MMDVFS_LCD_SIZE_HD; - } - - return MMDVFS_LCD_SIZE_FHD; -} - -static mmdvfs_voltage_enum mmdvfs_get_default_step(void) -{ -#if defined(D3) - return MMDVFS_VOLTAGE_LOW; -#else /* defined(D3) */ - if (mmdvfs_get_lcd_resolution() == MMDVFS_LCD_SIZE_HD) { - return MMDVFS_VOLTAGE_LOW; - } - - return MMDVFS_VOLTAGE_HIGH; -#endif /* defined(D3) */ -} - -static mmdvfs_voltage_enum mmdvfs_get_current_step(void) -{ - return g_mmdvfs_current_step; -} - -static mmdvfs_voltage_enum mmdvfs_query(MTK_SMI_BWC_SCEN scenario, MTK_MMDVFS_CMD *cmd) -{ - mmdvfs_voltage_enum step = mmdvfs_get_default_step(); - unsigned int venc_size; - MTK_MMDVFS_CMD cmd_default; - - venc_size = g_mmdvfs_info->video_record_size[0] * g_mmdvfs_info->video_record_size[1]; - - /* use default info */ - if (cmd == NULL) { - memset(&cmd_default, 0, sizeof(MTK_MMDVFS_CMD)); - cmd_default.camera_mode = MMDVFS_CAMERA_MODE_FLAG_DEFAULT; - cmd = &cmd_default; - } - - /* collect the final information */ - if (cmd->sensor_size == 0) { - cmd->sensor_size = g_mmdvfs_cmd.sensor_size; - } - - if (cmd->sensor_fps == 0) { - cmd->sensor_fps = g_mmdvfs_cmd.sensor_fps; - } - - if (cmd->camera_mode == MMDVFS_CAMERA_MODE_FLAG_DEFAULT) { - cmd->camera_mode = g_mmdvfs_cmd.camera_mode; - } - - /* HIGH level scenarios */ - switch (scenario) { -#if defined(D2) /* D2 ISP >= 6M HIGH */ - case SMI_BWC_SCEN_VR_SLOW: - case SMI_BWC_SCEN_VR: - if (cmd->sensor_size >= MMDVFS_PIXEL_NUM_SENSOR_6M) { - step = MMDVFS_VOLTAGE_HIGH; - } - break; -#endif - /* force HPM for engineering mode */ - case SMI_BWC_SCEN_FORCE_MMDVFS: - step = MMDVFS_VOLTAGE_HIGH; - break; - default: - break; - } - - return step; -} - -static void mmdvfs_update_cmd(MTK_MMDVFS_CMD *cmd) -{ - if (cmd == NULL) { - return; - } - - if (cmd->sensor_size) { - g_mmdvfs_cmd.sensor_size = cmd->sensor_size; - } - - if (cmd->sensor_fps) { - g_mmdvfs_cmd.sensor_fps = cmd->sensor_fps; - } - - MMDVFSMSG("update cm %d %d\n", cmd->camera_mode, cmd->sensor_size); - g_mmdvfs_cmd.camera_mode = cmd->camera_mode; -} - -static void mmdvfs_dump_info(void) -{ - MMDVFSMSG("CMD %d %d %d\n", g_mmdvfs_cmd.sensor_size, g_mmdvfs_cmd.sensor_fps, g_mmdvfs_cmd.camera_mode); - MMDVFSMSG("INFO VR %d %d\n", g_mmdvfs_info->video_record_size[0], g_mmdvfs_info->video_record_size[1]); -} - -/* delay 4 seconds to go LPM to workaround camera ZSD + PIP issue */ -static void mmdvfs_cam_work_handler(struct work_struct *work) -{ - MMDVFSMSG("CAM handler %d\n", jiffies_to_msecs(jiffies)); - mmdvfs_set_step(MMDVFS_CAM_MON_SCEN, mmdvfs_get_default_step()); -} - -#if !defined(D3) - -static DECLARE_DELAYED_WORK(g_mmdvfs_cam_work, mmdvfs_cam_work_handler); - -static void mmdvfs_stop_cam_monitor(void) -{ - cancel_delayed_work_sync(&g_mmdvfs_cam_work); -} - -#define MMDVFS_CAM_MON_DELAY (4 * HZ) -static void mmdvfs_start_cam_monitor(void) -{ - mmdvfs_stop_cam_monitor(); - MMDVFSMSG("CAM start %d\n", jiffies_to_msecs(jiffies)); - mmdvfs_set_step(MMDVFS_CAM_MON_SCEN, MMDVFS_VOLTAGE_HIGH); - /* 4 seconds for PIP switch preview aspect delays... */ - schedule_delayed_work(&g_mmdvfs_cam_work, MMDVFS_CAM_MON_DELAY); -} - -#endif /* !defined(D3) */ - -int mmdvfs_set_step(MTK_SMI_BWC_SCEN scenario, mmdvfs_voltage_enum step) -{ - int i, scen_index; - mmdvfs_voltage_enum final_step = mmdvfs_get_default_step(); - -#if !MMDVFS_ENABLE - return 0; -#endif - -#if defined(D1) - /* D1 FHD always HPM. do not have to trigger vcore dvfs. */ - if (mmdvfs_get_lcd_resolution() == MMDVFS_LCD_SIZE_FHD) { - return 0; - } -#endif - - MMDVFSMSG("MMDVFS set voltage scen %d step %d\n", scenario, step); - - if ((scenario >= MMDVFS_SCEN_COUNT) || (scenario < SMI_BWC_SCEN_NORMAL)) - { - MMDVFSERR("invalid scenario\n"); - return -1; - } - - /* dump information */ - mmdvfs_dump_info(); - - /* go through all scenarios to decide the final step */ - scen_index = (int)scenario; - - spin_lock(&g_mmdvfs_mgr->scen_lock); - - g_mmdvfs_scenario_voltage[scen_index] = step; - - /* one high = final high */ - for (i = 0; i < MMDVFS_SCEN_COUNT; i++) { - if (g_mmdvfs_scenario_voltage[i] == MMDVFS_VOLTAGE_HIGH) { - final_step = MMDVFS_VOLTAGE_HIGH; - break; - } - } - - g_mmdvfs_current_step = final_step; - - spin_unlock(&g_mmdvfs_mgr->scen_lock); - - MMDVFSMSG("MMDVFS set voltage scen %d step %d final %d\n", scenario, step, final_step); - -#if MMDVFS_ENABLE - /* call vcore dvfs API */ - if (final_step == MMDVFS_VOLTAGE_HIGH) { - vcorefs_request_dvfs_opp(KIR_MM, OPPI_PERF); - } else { - vcorefs_request_dvfs_opp(KIR_MM, OPPI_UNREQ); - } -#endif - - return 0; -} - -void mmdvfs_handle_cmd(MTK_MMDVFS_CMD *cmd) -{ -#if !MMDVFS_ENABLE - return; -#endif - - MMDVFSMSG("MMDVFS cmd %u %d\n", cmd->type, cmd->scen); - - switch (cmd->type) { - case MTK_MMDVFS_CMD_TYPE_SET: - /* save cmd */ - mmdvfs_update_cmd(cmd); - cmd->ret = mmdvfs_set_step(cmd->scen, mmdvfs_query(cmd->scen, cmd)); - break; - - case MTK_MMDVFS_CMD_TYPE_QUERY: - { /* query with some parameters */ - if (mmdvfs_get_lcd_resolution() == MMDVFS_LCD_SIZE_FHD) { - /* QUERY ALWAYS HIGH for FHD */ - cmd->ret = (unsigned int)MMDVFS_STEP_HIGH2HIGH; - } else { /* FHD */ - mmdvfs_voltage_enum query_voltage = mmdvfs_query(cmd->scen, cmd); - mmdvfs_voltage_enum current_voltage = mmdvfs_get_current_step(); - - if (current_voltage < query_voltage) { - cmd->ret = (unsigned int)MMDVFS_STEP_LOW2HIGH; - } else if (current_voltage > query_voltage) { - cmd->ret = (unsigned int)MMDVFS_STEP_HIGH2LOW; - } else { - cmd->ret = (unsigned int)(query_voltage == MMDVFS_VOLTAGE_HIGH ? MMDVFS_STEP_HIGH2HIGH : MMDVFS_STEP_LOW2LOW); - } - } - - MMDVFSMSG("query %d\n", cmd->ret); - /* cmd->ret = (unsigned int)query_voltage; */ - break; - } - - default: - MMDVFSMSG("invalid mmdvfs cmd\n"); - BUG(); - break; - } -} - -void mmdvfs_notify_scenario_exit(MTK_SMI_BWC_SCEN scen) -{ -#if !MMDVFS_ENABLE - return; -#endif - - MMDVFSMSG("leave %d\n", scen); - -#if !defined(D3) /* denali-3 does not need this workaround because the MMCLK is always the highest */ - /* - * keep HPM for 4 seconds after exiting camera scenarios to get rid of - * cam framework will let us go to normal scenario for a short time (ex: STOP PREVIEW --> NORMAL --> START PREVIEW) - * where the LPM mode (low MMCLK) may cause ISP failures - */ - if ((scen == SMI_BWC_SCEN_VR) || (scen == SMI_BWC_SCEN_VR_SLOW) || (scen == SMI_BWC_SCEN_ICFP)) { - mmdvfs_start_cam_monitor(); - } -#endif /* !defined(D3) */ - - /* reset scenario voltage to default when it exits */ - mmdvfs_set_step(scen, mmdvfs_get_default_step()); -} - -void mmdvfs_notify_scenario_enter(MTK_SMI_BWC_SCEN scen) -{ -#if !MMDVFS_ENABLE - return; -#endif - - MMDVFSMSG("enter %d\n", scen); - - /* ISP ON = high */ - switch (scen) { -#if defined(D2) /* d2 sensor > 6M */ - case SMI_BWC_SCEN_VR: - mmdvfs_set_step(scen, mmdvfs_query(scen, NULL)); - break; - case SMI_BWC_SCEN_VR_SLOW: -#elif defined(D1) /* default VR high */ - case SMI_BWC_SCEN_VR: - case SMI_BWC_SCEN_VR_SLOW: -#else /* D3 */ - case SMI_BWC_SCEN_WFD: - case SMI_BWC_SCEN_VSS: -#endif - case SMI_BWC_SCEN_ICFP: - case SMI_BWC_SCEN_FORCE_MMDVFS: - mmdvfs_set_step(scen, MMDVFS_VOLTAGE_HIGH); - break; - - default: - break; - } -} - -void mmdvfs_init(MTK_SMI_BWC_MM_INFO *info) -{ -#if !MMDVFS_ENABLE - return; -#endif - - spin_lock_init(&g_mmdvfs_mgr->scen_lock); - /* set current step as the default step */ - g_mmdvfs_current_step = mmdvfs_get_default_step(); - - g_mmdvfs_info = info; -} - -void mmdvfs_mhl_enable(int enable) -{ - g_mmdvfs_mgr->is_mhl_enable = enable; -} - -void mmdvfs_notify_scenario_concurrency(unsigned int u4Concurrency) -{ - /* raise EMI monitor BW threshold in VP, VR, VR SLOW motion cases to make sure vcore stay MMDVFS level as long as possible */ - if (u4Concurrency & ((1 << SMI_BWC_SCEN_VP) | (1 << SMI_BWC_SCEN_VR) | (1 << SMI_BWC_SCEN_VR_SLOW))) { - #if MMDVFS_ENABLE_FLIPER_CONTROL - MMDVFSMSG("fliper high\n"); - fliper_set_bw(BW_THRESHOLD_HIGH); - #endif - } else { - #if MMDVFS_ENABLE_FLIPER_CONTROL - MMDVFSMSG("fliper normal\n"); - fliper_restore_bw(); - #endif - } -} - - diff --git a/drivers/misc/mediatek/smi/mt6735/mmdvfs_mgr.h b/drivers/misc/mediatek/smi/mt6735/mmdvfs_mgr.h deleted file mode 100644 index a25e4b61e..000000000 --- a/drivers/misc/mediatek/smi/mt6735/mmdvfs_mgr.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef __MMDVFS_MGR_H__ -#define __MMDVFS_MGR_H__ - -#include <linux/aee.h> - -#define MMDVFS_LOG_TAG "MMDVFS" - -#define MMDVFSMSG(string, args...) if(1){\ - pr_warn("[pid=%d]"string, current->tgid, ##args); \ - } -#define MMDVFSMSG2(string, args...) pr_warn(string, ##args) -#define MMDVFSTMP(string, args...) pr_warn("[pid=%d]"string, current->tgid, ##args) -#define MMDVFSERR(string, args...) do{\ - pr_err("error: "string, ##args); \ - aee_kernel_warning(MMDVFS_LOG_TAG, "error: "string, ##args); \ -} while(0) - - -/* MMDVFS extern APIs */ -extern void mmdvfs_init(MTK_SMI_BWC_MM_INFO *info); -extern void mmdvfs_handle_cmd(MTK_MMDVFS_CMD *cmd); -extern void mmdvfs_notify_scenario_enter(MTK_SMI_BWC_SCEN scen); -extern void mmdvfs_notify_scenario_exit(MTK_SMI_BWC_SCEN scen); -extern void mmdvfs_notify_scenario_concurrency(unsigned int u4Concurrency); - -#endif /* __MMDVFS_MGR_H__ */ - diff --git a/drivers/misc/mediatek/smi/mt6735/smi_common.h b/drivers/misc/mediatek/smi/mt6735/smi_common.h deleted file mode 100644 index 7422905ff..000000000 --- a/drivers/misc/mediatek/smi/mt6735/smi_common.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef __SMI_COMMON_H__ -#define __SMI_COMMON_H__ - -#include <linux/aee.h> -#ifdef CONFIG_MTK_CMDQ -#include "cmdq_core.h" -#endif - -#define SMIMSG(string, args...) if(1){\ - pr_warn("[pid=%d]"string, current->tgid, ##args); \ - } -#define SMIMSG2(string, args...) pr_warn(string, ##args) - -#ifdef CONFIG_MTK_CMDQ -#define SMIMSG3(onoff, string, args...) if(onoff == 1){\ -cmdq_core_save_first_dump(string, ##args);\ -}\ -SMIMSG(string, ##args) -#else -#define SMIMSG3(string, args...) SMIMSG(string, ##args) -#endif - - -#define SMITMP(string, args...) pr_warn("[pid=%d]"string, current->tgid, ##args) -#define SMIERR(string, args...) do{\ - pr_err("error: "string, ##args); \ - aee_kernel_warning(SMI_LOG_TAG, "error: "string, ##args); \ -}while(0) - -#define smi_aee_print(string, args...) do{\ - char smi_name[100];\ - snprintf(smi_name,100, "["SMI_LOG_TAG"]"string, ##args); \ - aee_kernel_warning(smi_name, "["SMI_LOG_TAG"]error:"string,##args); \ -}while(0) - - -// Please use the function to instead gLarbBaseAddr to prevent the NULL pointer access error -// when the corrosponding larb is not exist -// extern unsigned int gLarbBaseAddr[SMI_LARB_NR]; -extern unsigned long get_larb_base_addr(int larb_id); -extern char *smi_port_name[][21]; - -extern void smi_dumpDebugMsg(void); - -#define SMI_CLIENT_DISP 0 -#define SMI_CLIENT_WFD 1 - -#define SMI_EVENT_DIRECT_LINK ( 0x1 << 0 ) -#define SMI_EVENT_DECOUPLE ( 0x1 << 1 ) -#define SMI_EVENT_OVL_CASCADE ( 0x1 << 2 ) -#define SMI_EVENT_OVL1_EXTERNAL ( 0x1 << 3 ) - - -extern void smi_client_status_change_notify(int module, int mode); -// module: -// 0: DISP -// 1: WFD -// mode: -// DISP: -// SMI_EVENT_DIRECT_LINK - directlink mode -// SMI_EVENT_DECOUPLE - decouple mode -// SMI_EVENT_OVL_CASCADE - OVL cascade -// SMI_EVENT_OVL1_EXTERNAL - OVL 1 for external display - -extern void SMI_DBG_Init(void); - - -#endif - diff --git a/drivers/misc/mediatek/smi/mt6735/smi_common_d1.c b/drivers/misc/mediatek/smi/mt6735/smi_common_d1.c deleted file mode 100644 index 0cfe5570f..000000000 --- a/drivers/misc/mediatek/smi/mt6735/smi_common_d1.c +++ /dev/null @@ -1,2112 +0,0 @@ -#include <linux/of.h> -#include <linux/of_irq.h> -#include <linux/of_address.h> -#include <linux/kobject.h> - -#include <linux/uaccess.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/cdev.h> -#include <linux/mm.h> -#include <linux/vmalloc.h> -#include <linux/slab.h> -#include <linux/aee.h> -#include <linux/xlog.h> - -// We can't remove mt_clkmgr.h now since SMI needs larb monitor APIs -#include <mach/mt_clkmgr.h> - -// Define SMI_INTERNAL_CCF_SUPPORT when CCF needs to be enabled -#if !defined(CONFIG_MTK_LEGACY) - #define SMI_INTERNAL_CCF_SUPPORT -#endif - -#if defined(SMI_INTERNAL_CCF_SUPPORT) -#include <linux/clk.h> -#endif /* defined(SMI_INTERNAL_CCF_SUPPORT) */ - -#include <asm/io.h> - -#include <linux/ioctl.h> -#include <linux/fs.h> - -#if IS_ENABLED(CONFIG_COMPAT) -#include <linux/uaccess.h> -#include <linux/compat.h> -#endif - -#include <mach/mt_smi.h> - - -#include "smi_reg_d1.h" -#include "smi_common.h" -#include "smi_debug.h" - -#include "mmdvfs_mgr.h" - -#undef pr_fmt -#define pr_fmt(fmt) "[SMI]" fmt - -#define SMI_LOG_TAG "SMI" - -#define SMI_DT_SUPPORT - -#define LARB_BACKUP_REG_SIZE 128 -#define SMI_COMMON_BACKUP_REG_NUM 8 - -#define SF_HWC_PIXEL_MAX_NORMAL (1920 * 1080 * 7) -#define SF_HWC_PIXEL_MAX_VR (1920 * 1080 * 4 + 1036800) // 4.5 FHD size -#define SF_HWC_PIXEL_MAX_VP (1920 * 1080 * 7) -#define SF_HWC_PIXEL_MAX_ALWAYS_GPU (1920 * 1080 * 1) - -#define SMIDBG(level, x...) \ - do{ \ - if (smi_debug_level >= (level)) \ - SMIMSG(x); \ - } while (0) - -typedef struct { - spinlock_t SMI_lock; - unsigned int pu4ConcurrencyTable[SMI_BWC_SCEN_CNT]; //one bit represent one module -} SMI_struct; - -static SMI_struct g_SMIInfo; - -/* LARB BASE ADDRESS */ -static unsigned long gLarbBaseAddr[SMI_LARB_NR] = { 0, 0, 0, 0}; - -// DT porting -unsigned long smi_reg_base_common_ext = 0; -unsigned long smi_reg_base_barb0 = 0; -unsigned long smi_reg_base_barb1 = 0; -unsigned long smi_reg_base_barb2 = 0; -unsigned long smi_reg_base_barb3 = 0; - -#define SMI_REG_REGION_MAX 5 -#define SMI_COMMON_REG_INDX 0 -#define SMI_LARB0_REG_INDX 1 -#define SMI_LARB1_REG_INDX 2 -#define SMI_LARB2_REG_INDX 3 -#define SMI_LARB3_REG_INDX 4 - -static unsigned long gSMIBaseAddrs[SMI_REG_REGION_MAX]; -void register_base_dump( void ); - -//#ifdef SMI_DT_SUPPORT -char* smi_get_region_name( unsigned int region_indx ); -//#endif //SMI_DT_SUPPORT - -struct smi_device{ - struct device *dev; - void __iomem *regs[SMI_REG_REGION_MAX]; -#if defined(SMI_INTERNAL_CCF_SUPPORT) - struct clk *smi_common_clk; - struct clk *smi_larb0_clk; - struct clk *img_larb2_clk; - struct clk *vdec0_vdec_clk; - struct clk *vdec1_larb_clk; - struct clk *venc_larb_clk; -#endif -}; -static struct smi_device *smi_dev = NULL; - -static struct device* smiDeviceUevent = NULL; - -static struct cdev * pSmiDev = NULL; - -static const unsigned int larb_port_num[SMI_LARB_NR] = { SMI_LARB0_PORT_NUM, - SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}; - -static unsigned short int larb0_port_backup[SMI_LARB0_PORT_NUM]; -static unsigned short int larb1_port_backup[SMI_LARB1_PORT_NUM]; -static unsigned short int larb2_port_backup[SMI_LARB2_PORT_NUM]; -static unsigned short int larb3_port_backup[SMI_LARB3_PORT_NUM]; - -/* SMI COMMON register list to be backuped */ -static unsigned short -g_smi_common_backup_reg_offset[SMI_COMMON_BACKUP_REG_NUM] = { 0x100, 0x104, - 0x108, 0x10c, 0x110, 0x230, 0x234, 0x238 }; -static unsigned int g_smi_common_backup[SMI_COMMON_BACKUP_REG_NUM]; - -static unsigned char larb_vc_setting[SMI_LARB_NR] = { 0, 2, 0, 1 }; - -static unsigned short int * larb_port_backup[SMI_LARB_NR] = { - larb0_port_backup, larb1_port_backup, larb2_port_backup, larb3_port_backup }; - -// To keep the HW's init value -static int is_default_value_saved = 0; -static unsigned int default_val_smi_l1arb[SMI_LARB_NR] = { 0 }; - -static unsigned int wifi_disp_transaction = 0; - -/* debug level */ -static unsigned int smi_debug_level = 0; - -/* tuning mode, 1 for register ioctl */ -static unsigned int smi_tuning_mode = 0; - -static unsigned int smi_profile = SMI_BWC_SCEN_NORMAL; - -static unsigned int* pLarbRegBackUp[SMI_LARB_NR]; -static int g_bInited = 0; - -static MTK_SMI_BWC_MM_INFO g_smi_bwc_mm_info = { 0, 0, { 0, 0 }, { 0, 0 }, { 0, - 0 }, { 0, 0 }, 0, 0, 0, SF_HWC_PIXEL_MAX_NORMAL }; - -char *smi_port_name[][21] = { { /* 0 MMSYS */ - "disp_ovl0", "disp_rdma0", "disp_rdma1", "disp_wdma0", "disp_ovl1", - "disp_rdma2", "disp_wdma1", "disp_od_r", "disp_od_w", "mdp_rdma0", - "mdp_rdma1", "mdp_wdma", "mdp_wrot0", "mdp_wrot1" }, { /* 1 VDEC */ - "hw_vdec_mc_ext", "hw_vdec_pp_ext", "hw_vdec_ufo_ext", "hw_vdec_vld_ext", - "hw_vdec_vld2_ext", "hw_vdec_avc_mv_ext", "hw_vdec_pred_rd_ext", - "hw_vdec_pred_wr_ext", "hw_vdec_ppwrap_ext" }, { /* 2 ISP */ - "imgo", "rrzo", "aao", "lcso", "esfko", "imgo_d", "lsci", "lsci_d", "bpci", - "bpci_d", "ufdi", "imgi", "img2o", "img3o", "vipi", "vip2i", "vip3i", - "lcei", "rb", "rp", "wr" }, { /* 3 VENC */ - "venc_rcpu", "venc_rec", "venc_bsdma", "venc_sv_comv", "venc_rd_comv", - "jpgenc_bsdma", "remdc_sdma", "remdc_bsdma", "jpgenc_rdma", "jpgenc_sdma", - "jpgdec_wdma", "jpgdec_bsdma", "venc_cur_luma", "venc_cur_chroma", - "venc_ref_luma", "venc_ref_chroma", "remdc_wdma", "venc_nbm_rdma", - "venc_nbm_wdma" }, { /* 4 MJC */ - "mjc_mv_rd", "mjc_mv_wr", "mjc_dma_rd", "mjc_dma_wr" } }; - -static unsigned long smi_reg_pa_base[SMI_REG_REGION_MAX] = { 0x14016000, - 0x14015000, 0x16010000, 0x15001000, 0x17001000 }; - -static void initSetting( void ); -static void vpSetting( void ); -static void vrSetting( void ); -static void icfpSetting( void ); -static void vpWfdSetting( void ); - -static void smi_dumpLarb( unsigned int index ); -static void smi_dumpCommon( void ); - -#if defined(SMI_INTERNAL_CCF_SUPPORT) -static struct clk *get_smi_clk(char *smi_clk_name); -#endif - -extern void smi_dumpDebugMsg( void ); -#if IS_ENABLED(CONFIG_COMPAT) - long MTK_SMI_COMPAT_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); -#else - #define MTK_SMI_COMPAT_ioctl NULL -#endif - -// for slow motion force 30 fps -extern int primary_display_force_set_vsync_fps( unsigned int fps ); -extern unsigned int primary_display_get_fps( void ); - -// Use this function to get base address of Larb resgister -// to support error checking -unsigned long get_larb_base_addr( int larb_id ){ - unsigned long ret = 0; - if( larb_id > SMI_LARB_NR || larb_id < 0 ){ - ret = SMI_ERROR_ADDR; - }else{ - ret = gLarbBaseAddr[larb_id]; - } - return ret; -} - - -#if defined(SMI_INTERNAL_CCF_SUPPORT) -static struct clk *get_smi_clk(char *smi_clk_name){ - - struct clk *smi_clk_ptr = NULL; - smi_clk_ptr = devm_clk_get(smi_dev->dev, smi_clk_name); - if (IS_ERR(smi_clk_ptr)) { - SMIMSG("cannot get %s\n", smi_clk_name); - smi_clk_ptr = NULL; - } - return smi_clk_ptr; -} - -static void smi_enable_clk(struct clk *smi_clk, char * name){ - if(smi_clk!= NULL){ - int ret = 0; - ret = clk_prepare_enable(smi_clk); - if(ret){ - SMIMSG("clk_prepare_enable return error %d, %s\n", ret, name); - } - }else{ - SMIMSG("clk_prepare_enable error, smi_clk can't be NULL, %s\n", name); - } -} - -static void smi_disable_clk(struct clk *smi_clk, char * name){ - if(smi_clk!= NULL){ - clk_disable_unprepare(smi_clk); - }else{ - SMIMSG("smi_disable_clk error, smi_clk can't be NULL, %s\n", name); - } -} -#endif - -static int larb_clock_on( int larb_id ){ - -#if !defined (CONFIG_MTK_FPGA) && !defined (CONFIG_FPGA_EARLY_PORTING) - char name[30]; - sprintf(name, "smi+%d", larb_id); - - switch( larb_id ){ -#if !defined(SMI_INTERNAL_CCF_SUPPORT) - case 0: - enable_clock(MT_CG_DISP0_SMI_COMMON, name); - enable_clock(MT_CG_DISP0_SMI_LARB0, name); - break; - case 1: - enable_clock(MT_CG_DISP0_SMI_COMMON, name); - enable_clock(MT_CG_VDEC1_LARB, name); - break; - case 2: - enable_clock(MT_CG_DISP0_SMI_COMMON, name); - enable_clock(MT_CG_IMAGE_LARB2_SMI, name); - break; - case 3: - enable_clock(MT_CG_DISP0_SMI_COMMON, name); - enable_clock(MT_CG_VENC_LARB, name); - break; - //case 4: - // enable_clock(MT_CG_DISP0_SMI_COMMON, name); - // enable_clock(MT_CG_MJC_SMI_LARB, name); - // break; -#else - case 0: - smi_enable_clk(smi_dev->smi_common_clk, name); - smi_enable_clk(smi_dev->smi_larb0_clk, name); - break; - case 1: - smi_enable_clk(smi_dev->smi_common_clk, name); - smi_enable_clk(smi_dev->vdec1_larb_clk, name); - break; - case 2: - smi_enable_clk(smi_dev->smi_common_clk, name); - smi_enable_clk(smi_dev->img_larb2_clk, name); - break; - case 3: - smi_enable_clk(smi_dev->smi_common_clk, name); - smi_enable_clk(smi_dev->venc_larb_clk, name); - break; -#endif - default: - break; - } -#endif /* CONFIG_MTK_FPGA */ - - return 0; -} - -static int larb_clock_off( int larb_id ){ - -#ifndef CONFIG_MTK_FPGA - char name[30]; - sprintf(name, "smi+%d", larb_id); - - switch( larb_id ){ -#if !defined(SMI_INTERNAL_CCF_SUPPORT) - case 0: - disable_clock(MT_CG_DISP0_SMI_LARB0, name); - disable_clock(MT_CG_DISP0_SMI_COMMON, name); - break; - case 1: - disable_clock(MT_CG_VDEC1_LARB, name); - disable_clock(MT_CG_DISP0_SMI_COMMON, name); - break; - case 2: - disable_clock(MT_CG_IMAGE_LARB2_SMI, name); - disable_clock(MT_CG_DISP0_SMI_COMMON, name); - break; - case 3: - disable_clock(MT_CG_VENC_LARB, name); - disable_clock(MT_CG_DISP0_SMI_COMMON, name); - break; - //case 4: - // disable_clock(MT_CG_MJC_SMI_LARB, name); - // disable_clock(MT_CG_DISP0_SMI_COMMON, name); - // break; -#else - case 0: - smi_disable_clk(smi_dev->smi_common_clk, name); - smi_disable_clk(smi_dev->smi_larb0_clk, name); - break; - case 1: - smi_disable_clk(smi_dev->smi_common_clk, name); - smi_disable_clk(smi_dev->vdec1_larb_clk, name); - break; - case 2: - smi_disable_clk(smi_dev->smi_common_clk, name); - smi_disable_clk(smi_dev->img_larb2_clk, name); - break; - case 3: - smi_disable_clk(smi_dev->smi_common_clk, name); - smi_disable_clk(smi_dev->venc_larb_clk, name); - break; -#endif - default: - break; - } -#endif /* CONFIG_MTK_FPGA */ - - return 0; -} - -static void backup_smi_common( void ){ - int i; - - for( i = 0; i < SMI_COMMON_BACKUP_REG_NUM; i++ ){ - g_smi_common_backup[i] = M4U_ReadReg32(SMI_COMMON_EXT_BASE, - (unsigned long) g_smi_common_backup_reg_offset[i]); - } -} - -static void restore_smi_common( void ){ - int i; - - for( i = 0; i < SMI_COMMON_BACKUP_REG_NUM; i++ ){ - M4U_WriteReg32(SMI_COMMON_EXT_BASE, - (unsigned long) g_smi_common_backup_reg_offset[i], - g_smi_common_backup[i]); - } -} - -static void backup_larb_smi( int index ){ - int port_index = 0; - unsigned short int *backup_ptr = NULL; - unsigned long larb_base = gLarbBaseAddr[index]; - unsigned long larb_offset = 0x200; - int total_port_num = 0; - - // boundary check for larb_port_num and larb_port_backup access - if( index < 0 || index >= SMI_LARB_NR ){ - return; - } - - total_port_num = larb_port_num[index]; - backup_ptr = larb_port_backup[index]; - - // boundary check for port value access - if( total_port_num <= 0 || backup_ptr == NULL ){ - return; - } - - for( port_index = 0; port_index < total_port_num; port_index++ ){ - *backup_ptr = (unsigned short int) (M4U_ReadReg32(larb_base, - larb_offset)); - backup_ptr++; - larb_offset += 4; - } - - /* backup smi common along with larb0, smi common clk is guaranteed to be on when processing larbs */ - if( index == 0 ){ - backup_smi_common(); - } - - return; -} - -static void restore_larb_smi( int index ){ - int port_index = 0; - unsigned short int *backup_ptr = NULL; - unsigned long larb_base = gLarbBaseAddr[index]; - unsigned long larb_offset = 0x200; - unsigned int backup_value = 0; - int total_port_num = 0; - - // boundary check for larb_port_num and larb_port_backup access - if( index < 0 || index >= SMI_LARB_NR ){ - return; - } - total_port_num = larb_port_num[index]; - backup_ptr = larb_port_backup[index]; - - // boundary check for port value access - if( total_port_num <= 0 || backup_ptr == NULL ){ - return; - } - - /* restore smi common along with larb0, smi common clk is guaranteed to be on when processing larbs */ - if( index == 0 ){ - restore_smi_common(); - } - - for( port_index = 0; port_index < total_port_num; port_index++ ){ - backup_value = *backup_ptr; - M4U_WriteReg32(larb_base, larb_offset, backup_value); - backup_ptr++; - larb_offset += 4; - } - - /* we do not backup 0x20 because it is a fixed setting */ - M4U_WriteReg32(larb_base, 0x20, larb_vc_setting[index]); - - /* turn off EMI empty OSTD dobule, fixed setting */ - M4U_WriteReg32(larb_base, 0x2c, 4); - - return; -} - -static int larb_reg_backup( int larb ){ - unsigned int* pReg = pLarbRegBackUp[larb]; - unsigned long larb_base = gLarbBaseAddr[larb]; - - *(pReg++) = M4U_ReadReg32(larb_base, SMI_LARB_CON); - - // *(pReg++) = M4U_ReadReg32(larb_base, SMI_SHARE_EN); - // *(pReg++) = M4U_ReadReg32(larb_base, SMI_ROUTE_SEL); - - backup_larb_smi(larb); - - if( 0 == larb ){ - g_bInited = 0; - } - - return 0; -} - -static int smi_larb_init( unsigned int larb ){ - unsigned int regval = 0; - unsigned int regval1 = 0; - unsigned int regval2 = 0; - unsigned long larb_base = get_larb_base_addr(larb); - - // Clock manager enable LARB clock before call back restore already, it will be disabled after restore call back returns - // Got to enable OSTD before engine starts - regval = M4U_ReadReg32(larb_base, SMI_LARB_STAT); - - // TODO: FIX ME - // regval1 = M4U_ReadReg32(larb_base , SMI_LARB_MON_BUS_REQ0); - // regval2 = M4U_ReadReg32(larb_base , SMI_LARB_MON_BUS_REQ1); - - if( 0 == regval ){ - SMIDBG(1, "Init OSTD for larb_base: 0x%lx\n", larb_base); - M4U_WriteReg32(larb_base, SMI_LARB_OSTDL_SOFT_EN, 0xffffffff); - }else{ - SMIMSG( - "Larb: 0x%lx is busy : 0x%x , port:0x%x,0x%x ,fail to set OSTD\n", - larb_base, regval, regval1, regval2); - smi_dumpDebugMsg(); - if( smi_debug_level >= 1 ){ - SMIERR( - "DISP_MDP LARB 0x%lx OSTD cannot be set:0x%x,port:0x%x,0x%x\n", - larb_base, regval, regval1, regval2); - }else{ - dump_stack(); - } - } - - restore_larb_smi(larb); - - return 0; -} - -int larb_reg_restore( int larb ){ - unsigned long larb_base = SMI_ERROR_ADDR; - unsigned int regval = 0; - unsigned int* pReg = NULL; - - larb_base = get_larb_base_addr(larb); - - // The larb assign doesn't exist - if( larb_base == SMI_ERROR_ADDR ){ - SMIMSG("Can't find the base address for Larb%d\n", larb); - return 0; - } - - pReg = pLarbRegBackUp[larb]; - - SMIDBG(1, "+larb_reg_restore(), larb_idx=%d \n", larb); - SMIDBG(1, "m4u part restore, larb_idx=%d \n", larb); - //warning: larb_con is controlled by set/clr - regval = *(pReg++); - M4U_WriteReg32(larb_base, SMI_LARB_CON_CLR, ~(regval)); - M4U_WriteReg32(larb_base, SMI_LARB_CON_SET, (regval)); - - //M4U_WriteReg32(larb_base, SMI_SHARE_EN, *(pReg++) ); - //M4U_WriteReg32(larb_base, SMI_ROUTE_SEL, *(pReg++) ); - - smi_larb_init(larb); - - return 0; -} - -// callback after larb clock is enabled -void on_larb_power_on( struct larb_monitor *h, int larb_idx ){ - //M4ULOG("on_larb_power_on(), larb_idx=%d \n", larb_idx); - larb_reg_restore(larb_idx); - - return; -} -// callback before larb clock is disabled -void on_larb_power_off( struct larb_monitor *h, int larb_idx ){ - //M4ULOG("on_larb_power_off(), larb_idx=%d \n", larb_idx); - larb_reg_backup(larb_idx); -} - -static void restSetting( void ){ - //initialize OSTD to 1 - M4U_WriteReg32(LARB0_BASE, 0x200, 0x1); //disp_ovl0 - M4U_WriteReg32(LARB0_BASE, 0x204, 0x1); //disp_rdma0 - M4U_WriteReg32(LARB0_BASE, 0x208, 0x1); //disp_wdma0 - M4U_WriteReg32(LARB0_BASE, 0x20c, 0x1); //disp_rdma1 - M4U_WriteReg32(LARB0_BASE, 0x210, 0x1); //mdp_rdma - M4U_WriteReg32(LARB0_BASE, 0x214, 0x1); //mdp_wdma - M4U_WriteReg32(LARB0_BASE, 0x214, 0x1); //mdp_wrot - - M4U_WriteReg32(LARB1_BASE, 0x200, 0x1); //hw_vdec_mc_ext - M4U_WriteReg32(LARB1_BASE, 0x204, 0x1); //hw_vdec_pp_ext - M4U_WriteReg32(LARB1_BASE, 0x208, 0x1); //hw_vdec_avc_mv_ext - M4U_WriteReg32(LARB1_BASE, 0x20c, 0x1); //hw_vdec_pred_rd_ext - M4U_WriteReg32(LARB1_BASE, 0x210, 0x1); //hw_vdec_pred_wr_ext - M4U_WriteReg32(LARB1_BASE, 0x214, 0x1); //hw_vdec_vld_ext - M4U_WriteReg32(LARB1_BASE, 0x218, 0x1); //hw_vdec_ppwrap_ext - - M4U_WriteReg32(LARB2_BASE, 0x200, 0x1); //imgo - M4U_WriteReg32(LARB2_BASE, 0x204, 0x1); //rrzo - M4U_WriteReg32(LARB2_BASE, 0x208, 0x1); //aao - M4U_WriteReg32(LARB2_BASE, 0x20c, 0x1); //lcso - M4U_WriteReg32(LARB2_BASE, 0x210, 0x1); //esfko - M4U_WriteReg32(LARB2_BASE, 0x214, 0x1); //imgo_s - M4U_WriteReg32(LARB2_BASE, 0x218, 0x1); //lsci - M4U_WriteReg32(LARB2_BASE, 0x21c, 0x1); //lsci_d - M4U_WriteReg32(LARB2_BASE, 0x220, 0x1); //bpci - M4U_WriteReg32(LARB2_BASE, 0x224, 0x1); //bpci_d - M4U_WriteReg32(LARB2_BASE, 0x228, 0x1); //ufdi - M4U_WriteReg32(LARB2_BASE, 0x22c, 0x1); //imgi - M4U_WriteReg32(LARB2_BASE, 0x230, 0x1); //img2o - M4U_WriteReg32(LARB2_BASE, 0x234, 0x1); //img3o - M4U_WriteReg32(LARB2_BASE, 0x238, 0x1); //vipi - M4U_WriteReg32(LARB2_BASE, 0x23c, 0x1); //vip2i - M4U_WriteReg32(LARB2_BASE, 0x240, 0x1); //vip3i - M4U_WriteReg32(LARB2_BASE, 0x244, 0x1); //lcei - M4U_WriteReg32(LARB2_BASE, 0x248, 0x1); //rb - M4U_WriteReg32(LARB2_BASE, 0x24c, 0x1); //rp - M4U_WriteReg32(LARB2_BASE, 0x250, 0x1); //wr - - M4U_WriteReg32(LARB3_BASE, 0x200, 0x1); //venc_rcpu - M4U_WriteReg32(LARB3_BASE, 0x204, 0x2); //venc_rec - M4U_WriteReg32(LARB3_BASE, 0x208, 0x1); //venc_bsdma - M4U_WriteReg32(LARB3_BASE, 0x20c, 0x1); //venc_sv_comv - M4U_WriteReg32(LARB3_BASE, 0x210, 0x1); //venc_rd_comv - M4U_WriteReg32(LARB3_BASE, 0x214, 0x1); //jpgenc_rdma - M4U_WriteReg32(LARB3_BASE, 0x218, 0x1); //jpgenc_bsdma - M4U_WriteReg32(LARB3_BASE, 0x21c, 0x1); //jpgdec_wdma - M4U_WriteReg32(LARB3_BASE, 0x220, 0x1); //jpgdec_bsdma - M4U_WriteReg32(LARB3_BASE, 0x224, 0x1); //venc_cur_luma - M4U_WriteReg32(LARB3_BASE, 0x228, 0x1); //venc_cur_chroma - M4U_WriteReg32(LARB3_BASE, 0x22c, 0x1); //venc_ref_luma - M4U_WriteReg32(LARB3_BASE, 0x230, 0x1); //venc_ref_chroma -} -//Make sure clock is on -static void initSetting( void ){ - - /* save default larb regs */ - if( !is_default_value_saved ){ - SMIMSG("Save default config:\n"); - default_val_smi_l1arb[0] = M4U_ReadReg32(SMI_COMMON_EXT_BASE, - REG_OFFSET_SMI_L1ARB0); - default_val_smi_l1arb[1] = M4U_ReadReg32(SMI_COMMON_EXT_BASE, - REG_OFFSET_SMI_L1ARB1); - default_val_smi_l1arb[2] = M4U_ReadReg32(SMI_COMMON_EXT_BASE, - REG_OFFSET_SMI_L1ARB2); - default_val_smi_l1arb[3] = M4U_ReadReg32(SMI_COMMON_EXT_BASE, - REG_OFFSET_SMI_L1ARB3); - SMIMSG("l1arb[0-2]= 0x%x, 0x%x, 0x%x\n", default_val_smi_l1arb[0], - default_val_smi_l1arb[1], default_val_smi_l1arb[2]); - SMIMSG("l1arb[3]= 0x%x\n", default_val_smi_l1arb[3]); - - is_default_value_saved = 1; - } - - // Keep the HW's init setting in REG_SMI_L1ARB0 ~ REG_SMI_L1ARB4 - M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB0, - default_val_smi_l1arb[0]); - M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB1, - default_val_smi_l1arb[1]); - M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB2, - default_val_smi_l1arb[2]); - M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB3, - default_val_smi_l1arb[3]); - - - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x100, 0x1b); - // 0x220 is controlled by M4U - // M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x220, 0x1); //disp: emi0, other:emi1 - M4U_WriteReg32( - SMI_COMMON_EXT_BASE, - 0x234, - (0x1 << 31) + (0x1d << 26) + (0x1f << 21) + (0x0 << 20) + (0x3 << 15) - + (0x4 << 10) + (0x4 << 5) + 0x5); - // To be checked with DE - //M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x238, (0x2 << 25) + (0x3 << 20) + (0x4 << 15) + (0x5 << 10) + (0x6 << 5) + 0x8); - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x230, 0x1f + (0x8 << 4) + (0x7 << 9)); - - // Set VC priority: MMSYS = ISP > VENC > VDEC = MJC - M4U_WriteReg32(LARB0_BASE, 0x20, 0x0); // MMSYS - M4U_WriteReg32(LARB1_BASE, 0x20, 0x2); // VDEC - M4U_WriteReg32(LARB2_BASE, 0x20, 0x1); // ISP - M4U_WriteReg32(LARB3_BASE, 0x20, 0x1); // VENC - //M4U_WriteReg32(LARB4_BASE, 0x20, 0x2); // MJC - - // for ISP HRT - M4U_WriteReg32(LARB2_BASE, 0x24, - (M4U_ReadReg32(LARB2_BASE, 0x24) & 0xf7ffffff)); - - // for UI - restSetting(); - - //SMI common BW limiter - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x104, default_val_smi_l1arb[0]); - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x108, 0x1000); - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x10C, 0x1000); - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x110, 0x1000); - //M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x114, 0x1000); - - //LARB 0 DISP+MDP - M4U_WriteReg32(LARB0_BASE, 0x200, 31); //disp_ovl0 - M4U_WriteReg32(LARB0_BASE, 0x204, 4); //disp_rdma0 - M4U_WriteReg32(LARB0_BASE, 0x208, 6); //disp_wdma0 - M4U_WriteReg32(LARB0_BASE, 0x20c, 31); //disp_rdma1 - M4U_WriteReg32(LARB0_BASE, 0x210, 4); //mdp_rdma - M4U_WriteReg32(LARB0_BASE, 0x214, 0x1); //mdp_wdma - M4U_WriteReg32(LARB0_BASE, 0x218, 0x1); //mdp_wrot - -} - -static void icfpSetting( void ){ - vrSetting(); -} - - - -static void vrSetting( void ){ - //SMI BW limit - // vss - M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB0, 0x11F1); //LARB0, DISP+MDP - M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB1, 0x1000); //LARB1, VDEC - M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB2, 0x120A); //LARB2, ISP - M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB3, 0x11F3); //LARB3, VENC+JPG - //M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB4, 0x1000); //LARB4, MJC - - //SMI LARB config - - restSetting(); - - //LARB 0 DISP+MDP - M4U_WriteReg32(LARB0_BASE, 0x200, 0x8); //disp_ovl0 - M4U_WriteReg32(LARB0_BASE, 0x210, 0x1); //mdp_rdma - M4U_WriteReg32(LARB0_BASE, 0x214, 0x2); //mdp_wdma - M4U_WriteReg32(LARB0_BASE, 0x218, 0x4); //mdp_wrot - - M4U_WriteReg32(LARB2_BASE, 0x204, 0x4); //rrzo - M4U_WriteReg32(LARB2_BASE, 0x208, 0x1); //aao - M4U_WriteReg32(LARB2_BASE, 0x20c, 0x1); //esfko - M4U_WriteReg32(LARB2_BASE, 0x214, 0x1); //lsci - M4U_WriteReg32(LARB2_BASE, 0x21c, 0x1); //bpci - M4U_WriteReg32(LARB2_BASE, 0x228, 0x4); //imgi - M4U_WriteReg32(LARB2_BASE, 0x22c, 0x1); //img2o - M4U_WriteReg32(LARB2_BASE, 0x230, 0x2); //img3o - M4U_WriteReg32(LARB2_BASE, 0x234, 0x2); //vipi - M4U_WriteReg32(LARB2_BASE, 0x238, 0x1); //vip2i - M4U_WriteReg32(LARB2_BASE, 0x23c, 0x1); //vip3i - - M4U_WriteReg32(LARB3_BASE, 0x200, 0x1); //venc_rcpu - M4U_WriteReg32(LARB3_BASE, 0x204, 0x2); //venc_rec - M4U_WriteReg32(LARB3_BASE, 0x208, 0x1); //venc_bsdma - M4U_WriteReg32(LARB3_BASE, 0x20c, 0x1); //venc_sv_comv - M4U_WriteReg32(LARB3_BASE, 0x210, 0x1); //venc_rd_comv - M4U_WriteReg32(LARB3_BASE, 0x214, 0x1); //jpgenc_rdma - M4U_WriteReg32(LARB3_BASE, 0x218, 0x1); //jpgenc_bsdma - M4U_WriteReg32(LARB3_BASE, 0x224, 0x2); //venc_cur_luma - M4U_WriteReg32(LARB3_BASE, 0x228, 0x1); //venc_cur_chroma - M4U_WriteReg32(LARB3_BASE, 0x22c, 0x3); //venc_ref_luma - M4U_WriteReg32(LARB3_BASE, 0x230, 0x2); //venc_ref_chroma -} - -static void vpSetting( void ){ - - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x104, 0x1262); //LARB0, DISP+MDP - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x108, 0x11E9); //LARB1, VDEC - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x10C, 0x1000); //LARB2, ISP - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x110, 0x123D); //LARB3, VENC+JPG - //M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x214, 0x1000); //LARB4, MJC - - restSetting(); - - - - M4U_WriteReg32(LARB0_BASE, 0x200, 0x8); //disp_ovl0 - M4U_WriteReg32(LARB0_BASE, 0x208, 0x2); //disp_wdma0 - M4U_WriteReg32(LARB0_BASE, 0x210, 0x3); //mdp_rdma - M4U_WriteReg32(LARB0_BASE, 0x214, 0x1); //mdp_wdma - M4U_WriteReg32(LARB0_BASE, 0x218, 0x4); //mdp_wrot - - - M4U_WriteReg32(LARB1_BASE, 0x200, 0xb); //hw_vdec_mc_ext - M4U_WriteReg32(LARB1_BASE, 0x204, 0xe); //hw_vdec_pp_ext - M4U_WriteReg32(LARB1_BASE, 0x208, 0x1); //hw_vdec_avc_mv_ext - M4U_WriteReg32(LARB1_BASE, 0x214, 0x1); //hw_vdec_vld_ext - - - M4U_WriteReg32(LARB3_BASE, 0x200, 0x1); //venc_rcpu - M4U_WriteReg32(LARB3_BASE, 0x204, 0x2); //venc_rec - M4U_WriteReg32(LARB3_BASE, 0x208, 0x1); //venc_bsdma - M4U_WriteReg32(LARB3_BASE, 0x20c, 0x1); //venc_sv_comv - M4U_WriteReg32(LARB3_BASE, 0x210, 0x1); //venc_rd_comv - M4U_WriteReg32(LARB3_BASE, 0x224, 0x1); //venc_cur_luma - M4U_WriteReg32(LARB3_BASE, 0x228, 0x1); //venc_cur_chroma - M4U_WriteReg32(LARB3_BASE, 0x22c, 0x3); //venc_ref_luma - M4U_WriteReg32(LARB3_BASE, 0x230, 0x2); //venc_ref_chroma - - -} - - - - -static void vpWfdSetting( void ){ - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x104, 0x1262); //LARB0, DISP+MDP - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x108, 0x11E9); //LARB1, VDEC - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x10C, 0x1000); //LARB2, ISP - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x110, 0x123D); //LARB3, VENC+JPG - //M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x214, 0x1000); //LARB4, MJC - - restSetting(); - - - - M4U_WriteReg32(LARB0_BASE, 0x200, 0x8); //disp_ovl0 - M4U_WriteReg32(LARB0_BASE, 0x208, 0x2); //disp_wdma0 - M4U_WriteReg32(LARB0_BASE, 0x210, 0x3); //mdp_rdma - M4U_WriteReg32(LARB0_BASE, 0x214, 0x1); //mdp_wdma - M4U_WriteReg32(LARB0_BASE, 0x218, 0x4); //mdp_wrot - - - M4U_WriteReg32(LARB1_BASE, 0x200, 0xb); //hw_vdec_mc_ext - M4U_WriteReg32(LARB1_BASE, 0x204, 0xe); //hw_vdec_pp_ext - M4U_WriteReg32(LARB1_BASE, 0x208, 0x1); //hw_vdec_avc_mv_ext - M4U_WriteReg32(LARB1_BASE, 0x214, 0x1); //hw_vdec_vld_ext - - - M4U_WriteReg32(LARB3_BASE, 0x200, 0x1); //venc_rcpu - M4U_WriteReg32(LARB3_BASE, 0x204, 0x2); //venc_rec - M4U_WriteReg32(LARB3_BASE, 0x208, 0x1); //venc_bsdma - M4U_WriteReg32(LARB3_BASE, 0x20c, 0x1); //venc_sv_comv - M4U_WriteReg32(LARB3_BASE, 0x210, 0x1); //venc_rd_comv - M4U_WriteReg32(LARB3_BASE, 0x224, 0x1); //venc_cur_luma - M4U_WriteReg32(LARB3_BASE, 0x228, 0x1); //venc_cur_chroma - M4U_WriteReg32(LARB3_BASE, 0x22c, 0x3); //venc_ref_luma - M4U_WriteReg32(LARB3_BASE, 0x230, 0x2); //venc_ref_chroma -} - -// Fake mode check, e.g. WFD -static int fake_mode_handling( - MTK_SMI_BWC_CONFIG* p_conf, - unsigned int *pu4LocalCnt ){ - if( p_conf->scenario == SMI_BWC_SCEN_WFD ){ - if( p_conf->b_on_off ){ - wifi_disp_transaction = 1; - SMIMSG("Enable WFD in profile: %d\n", smi_profile); - }else{ - wifi_disp_transaction = 0; - SMIMSG("Disable WFD in profile: %d\n", smi_profile); - } - return 1; - }else{ - return 0; - } -} - -static int ovl_limit_uevent( int bwc_scenario, int ovl_pixel_limit ){ - int err = 0; - char *envp[3]; - char scenario_buf[32] = ""; - char ovl_limit_buf[32] = ""; - - // scenario_buf = kzalloc(sizeof(char)*128, GFP_KERNEL); - // ovl_limit_buf = kzalloc(sizeof(char)*128, GFP_KERNEL); - - snprintf(scenario_buf, 31, "SCEN=%d", bwc_scenario); - snprintf(ovl_limit_buf, 31, "HWOVL=%d", ovl_pixel_limit); - - envp[0] = scenario_buf; - envp[1] = ovl_limit_buf; - envp[2] = NULL; - - if( pSmiDev != NULL ){ - // err = kobject_uevent_env(&(pSmiDev->kobj), KOBJ_CHANGE, envp); - // use smi_dev->dev.lobj instead - // err = kobject_uevent_env(&(smi_dev->dev->kobj), KOBJ_CHANGE, envp); - // user smiDeviceUevent->kobj instead - err = kobject_uevent_env(&(smiDeviceUevent->kobj), KOBJ_CHANGE, envp); - SMIMSG("Notify OVL limitaion=%d, SCEN=%d", ovl_pixel_limit, - bwc_scenario); - } - //kfree(scenario_buf); - //kfree(ovl_limit_buf); - - if(err < 0) - SMIMSG(KERN_INFO "[%s] kobject_uevent_env error = %d\n", __func__, err); - - return err; -} - -static int smi_bwc_config( - MTK_SMI_BWC_CONFIG* p_conf, - unsigned int *pu4LocalCnt ){ - int i; - int result = 0; - unsigned int u4Concurrency = 0; - MTK_SMI_BWC_SCEN eFinalScen; - static MTK_SMI_BWC_SCEN ePreviousFinalScen = SMI_BWC_SCEN_CNT; - - if( smi_tuning_mode == 1 ){ - SMIMSG("Doesn't change profile in tunning mode"); - return 0; - } - //#ifdef SMI_DT_SUPPORT - //register_base_dump(); - //#endif - - spin_lock(&g_SMIInfo.SMI_lock); - result = fake_mode_handling(p_conf, pu4LocalCnt); - spin_unlock(&g_SMIInfo.SMI_lock); - - // Fake mode is not a real SMI profile, so we need to return here - if( result == 1 ){ - return 0; - } - - if( (SMI_BWC_SCEN_CNT <= p_conf->scenario) || (0 > p_conf->scenario) ){ - SMIERR("Incorrect SMI BWC config : 0x%x, how could this be...\n", - p_conf->scenario); - return -1; - } - - //Debug - S - //SMIMSG("SMI setTo%d,%s,%d\n" , p_conf->scenario , (p_conf->b_on_off ? "on" : "off") , ePreviousFinalScen); - //Debug - E - - if (p_conf->b_on_off) { - /* set mmdvfs step according to certain scenarios */ - mmdvfs_notify_scenario_enter(p_conf->scenario); - } else { - /* set mmdvfs step to default after the scenario exits */ - mmdvfs_notify_scenario_exit(p_conf->scenario); - } - - spin_lock(&g_SMIInfo.SMI_lock); - - if( p_conf->b_on_off ){ - //turn on certain scenario - g_SMIInfo.pu4ConcurrencyTable[p_conf->scenario] += 1; - - if( NULL != pu4LocalCnt ){ - pu4LocalCnt[p_conf->scenario] += 1; - } - }else{ - //turn off certain scenario - if( 0 == g_SMIInfo.pu4ConcurrencyTable[p_conf->scenario] ){ - SMIMSG("Too many turning off for global SMI profile:%d,%d\n", - p_conf->scenario, - g_SMIInfo.pu4ConcurrencyTable[p_conf->scenario]); - }else{ - g_SMIInfo.pu4ConcurrencyTable[p_conf->scenario] -= 1; - } - - if( NULL != pu4LocalCnt ){ - if( 0 == pu4LocalCnt[p_conf->scenario] ){ - SMIMSG( - "Process : %s did too many turning off for local SMI profile:%d,%d\n", - current->comm, p_conf->scenario, - pu4LocalCnt[p_conf->scenario]); - }else{ - pu4LocalCnt[p_conf->scenario] -= 1; - } - } - } - - for( i = 0; i < SMI_BWC_SCEN_CNT; i++ ){ - if( g_SMIInfo.pu4ConcurrencyTable[i] ){ - u4Concurrency |= (1 << i); - } - } - - /* notify mmdvfs concurrency */ - mmdvfs_notify_scenario_concurrency(u4Concurrency); - - if( (1 << SMI_BWC_SCEN_MM_GPU) & u4Concurrency ){ - eFinalScen = SMI_BWC_SCEN_MM_GPU; - }else if( (1 << SMI_BWC_SCEN_ICFP) & u4Concurrency ){ - eFinalScen = SMI_BWC_SCEN_ICFP; - }else if( (1 << SMI_BWC_SCEN_VR_SLOW) & u4Concurrency ){ - eFinalScen = SMI_BWC_SCEN_VR_SLOW; - }else if( (1 << SMI_BWC_SCEN_VR) & u4Concurrency ){ - eFinalScen = SMI_BWC_SCEN_VR; - }else if( (1 << SMI_BWC_SCEN_VP) & u4Concurrency ){ - eFinalScen = SMI_BWC_SCEN_VP; - }else if( (1 << SMI_BWC_SCEN_SWDEC_VP) & u4Concurrency ){ - eFinalScen = SMI_BWC_SCEN_SWDEC_VP; - }else if( (1 << SMI_BWC_SCEN_VENC) & u4Concurrency ){ - eFinalScen = SMI_BWC_SCEN_VENC; - }else{ - eFinalScen = SMI_BWC_SCEN_NORMAL; - } - - if( ePreviousFinalScen == eFinalScen ){ - SMIMSG("Scen equal%d,don't change\n", eFinalScen); - spin_unlock(&g_SMIInfo.SMI_lock); - return 0; - }else{ - ePreviousFinalScen = eFinalScen; - } - - /* turn on larb clock */ - for( i = 0; i < SMI_LARB_NR; i++ ){ - larb_clock_on(i); - } - - smi_profile = eFinalScen; - - /* Bandwidth Limiter */ - switch( eFinalScen ){ - case SMI_BWC_SCEN_VP: - SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_VP"); - if( wifi_disp_transaction ){ - vpSetting(); - }else{ - vpWfdSetting(); - } - g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_VP; - break; - - case SMI_BWC_SCEN_SWDEC_VP: - SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_SWDEC_VP"); - vpSetting(); - g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_VP; - break; - - case SMI_BWC_SCEN_ICFP: - SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_ICFP"); - icfpSetting(); - g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_VR; - break; - case SMI_BWC_SCEN_VR: - SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_VR"); - vrSetting(); - g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_VR; - break; - - case SMI_BWC_SCEN_VR_SLOW: - SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_VR"); - smi_profile = SMI_BWC_SCEN_VR_SLOW; - vrSetting(); - g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; - break; - - case SMI_BWC_SCEN_VENC: - SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_VENC"); - vrSetting(); - g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; - break; - - case SMI_BWC_SCEN_NORMAL: - SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_NORMAL"); - g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; - initSetting(); - break; - - case SMI_BWC_SCEN_MM_GPU: - SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_MM_GPU"); - g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; - initSetting(); - break; - - default: - SMIMSG("[SMI_PROFILE] : %s %d\n", "initSetting", eFinalScen); - initSetting(); - g_smi_bwc_mm_info .hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; - break; - } - - /*turn off larb clock*/ - for( i = 0; i < SMI_LARB_NR; i++ ){ - larb_clock_off(i); - } - - spin_unlock(&g_SMIInfo.SMI_lock); - - ovl_limit_uevent(smi_profile, g_smi_bwc_mm_info.hw_ovl_limit); - - /* force 30 fps in VR slow motion, because disp driver set fps apis got mutex, call these APIs only when necessary */ - { - static unsigned int current_fps = 0; - - if( (eFinalScen == SMI_BWC_SCEN_VR_SLOW) && (current_fps != 30) ){ /* force 30 fps in VR slow motion profile */ - primary_display_force_set_vsync_fps(30); - current_fps = 30; - SMIMSG("[SMI_PROFILE] set 30 fps\n"); - }else if( (eFinalScen != SMI_BWC_SCEN_VR_SLOW) && (current_fps == 30) ){ /* back to normal fps */ - current_fps = primary_display_get_fps(); - primary_display_force_set_vsync_fps(current_fps); - SMIMSG("[SMI_PROFILE] back to %u fps\n", current_fps); - } - } - - SMIMSG("SMI_PROFILE to:%d %s,cur:%d,%d,%d,%d\n", p_conf->scenario, - (p_conf->b_on_off ? "on" : "off"), eFinalScen, - g_SMIInfo.pu4ConcurrencyTable[SMI_BWC_SCEN_NORMAL], - g_SMIInfo.pu4ConcurrencyTable[SMI_BWC_SCEN_VR], - g_SMIInfo.pu4ConcurrencyTable[SMI_BWC_SCEN_VP]); - - //Debug usage - S - //smi_dumpDebugMsg(); - //SMIMSG("Config:%d,%d,%d\n" , eFinalScen , g_SMIInfo.pu4ConcurrencyTable[SMI_BWC_SCEN_NORMAL] , (NULL == pu4LocalCnt ? (-1) : pu4LocalCnt[p_conf->scenario])); - //Debug usage - E - - return 0; -} - -struct larb_monitor larb_monitor_handler = -{ - .level = LARB_MONITOR_LEVEL_HIGH, - .backup = on_larb_power_off, - .restore = on_larb_power_on -}; - -int smi_common_init( void ){ - int i; - - SMIMSG("Enter smi_common_init\n") - for( i = 0; i < SMI_LARB_NR; i++ ){ - pLarbRegBackUp[i] = (unsigned int*) kmalloc(LARB_BACKUP_REG_SIZE, - GFP_KERNEL | __GFP_ZERO); - if( pLarbRegBackUp[i] == NULL ){ - SMIERR("pLarbRegBackUp kmalloc fail %d \n", i); - } - } - - /* - * make sure all larb power is on before we register callback func. - * then, when larb power is first off, default register value will be backed up. - */ - - for( i = 0; i < SMI_LARB_NR; i++ ){ - SMIMSG("Enalbe CLK of larb%d\n", i ); - larb_clock_on(i); - } - - /* apply init setting after kernel boot */ - SMIMSG("Enter smi_common_init\n") - initSetting(); - - register_larb_monitor(&larb_monitor_handler); - - for( i = 0; i < SMI_LARB_NR; i++ ){ - larb_clock_off(i); - } - - return 0; -} - -static int smi_open( struct inode *inode, struct file *file ){ - file->private_data = kmalloc(SMI_BWC_SCEN_CNT * sizeof(unsigned int), - GFP_ATOMIC); - - if( NULL == file->private_data ){ - SMIMSG("Not enough entry for DDP open operation\n"); - return -ENOMEM; - } - - memset(file->private_data, 0, SMI_BWC_SCEN_CNT * sizeof(unsigned int)); - - return 0; -} - -static int smi_release( struct inode *inode, struct file *file ){ - -#if 0 - unsigned long u4Index = 0; - unsigned long u4AssignCnt = 0; - unsigned long * pu4Cnt = (unsigned long *)file->private_data; - MTK_SMI_BWC_CONFIG config; - - for(; u4Index < SMI_BWC_SCEN_CNT; u4Index += 1) - { - if(pu4Cnt[u4Index]) - { - SMIMSG("Process:%s does not turn off BWC properly , force turn off %d\n" , current->comm , u4Index); - u4AssignCnt = pu4Cnt[u4Index]; - config.b_on_off = 0; - config.scenario = (MTK_SMI_BWC_SCEN)u4Index; - do - { - smi_bwc_config( &config , pu4Cnt); - } - while(0 < u4AssignCnt); - } - } -#endif - - if( NULL != file->private_data ){ - kfree(file->private_data); - file->private_data = NULL; - } - - return 0; -} -/* GMP start */ - -void smi_bwc_mm_info_set( int property_id, long val1, long val2 ){ - - switch( property_id ){ - case SMI_BWC_INFO_CON_PROFILE: - g_smi_bwc_mm_info.concurrent_profile = (int) val1; - break; - case SMI_BWC_INFO_SENSOR_SIZE: - g_smi_bwc_mm_info.sensor_size[0] = val1; - g_smi_bwc_mm_info.sensor_size[1] = val2; - break; - case SMI_BWC_INFO_VIDEO_RECORD_SIZE: - g_smi_bwc_mm_info.video_record_size[0] = val1; - g_smi_bwc_mm_info.video_record_size[1] = val2; - break; - case SMI_BWC_INFO_DISP_SIZE: - g_smi_bwc_mm_info.display_size[0] = val1; - g_smi_bwc_mm_info.display_size[1] = val2; - break; - case SMI_BWC_INFO_TV_OUT_SIZE: - g_smi_bwc_mm_info.tv_out_size[0] = val1; - g_smi_bwc_mm_info.tv_out_size[1] = val2; - break; - case SMI_BWC_INFO_FPS: - g_smi_bwc_mm_info.fps = (int) val1; - break; - case SMI_BWC_INFO_VIDEO_ENCODE_CODEC: - g_smi_bwc_mm_info.video_encode_codec = (int) val1; - break; - case SMI_BWC_INFO_VIDEO_DECODE_CODEC: - g_smi_bwc_mm_info.video_decode_codec = (int) val1; - break; - } -} - -/* GMP end */ - -static long smi_ioctl( - struct file * pFile, - unsigned int cmd, - unsigned long param ){ - int ret = 0; - - // unsigned long * pu4Cnt = (unsigned long *)pFile->private_data; - - switch( cmd ){ - - /* disable reg access ioctl by default for possible security holes */ - // TBD: check valid SMI register range - case MTK_IOC_SMI_BWC_CONFIG: { - MTK_SMI_BWC_CONFIG cfg; - ret = copy_from_user(&cfg, (void*) param, - sizeof(MTK_SMI_BWC_CONFIG)); - if( ret ){ - SMIMSG(" SMI_BWC_CONFIG, copy_from_user failed: %d\n", ret); - return -EFAULT; - } - - ret = smi_bwc_config(&cfg, NULL); - - break; - } - /* GMP start */ - case MTK_IOC_SMI_BWC_INFO_SET: { - MTK_SMI_BWC_INFO_SET cfg; - //SMIMSG("Handle MTK_IOC_SMI_BWC_INFO_SET request... start"); - ret = copy_from_user(&cfg, (void *) param, - sizeof(MTK_SMI_BWC_INFO_SET)); - if( ret ){ - SMIMSG(" MTK_IOC_SMI_BWC_INFO_SET, copy_to_user failed: %d\n", - ret); - return -EFAULT; - } - /* Set the address to the value assigned by user space program */ - smi_bwc_mm_info_set(cfg.property, cfg.value1, cfg.value2); - //SMIMSG("Handle MTK_IOC_SMI_BWC_INFO_SET request... finish"); - break; - } - case MTK_IOC_SMI_BWC_INFO_GET: { - ret = copy_to_user((void *) param, (void *) &g_smi_bwc_mm_info, - sizeof(MTK_SMI_BWC_MM_INFO)); - - if( ret ){ - SMIMSG(" MTK_IOC_SMI_BWC_INFO_GET, copy_to_user failed: %d\n", - ret); - return -EFAULT; - } - //SMIMSG("Handle MTK_IOC_SMI_BWC_INFO_GET request... finish"); - break; - } - /* GMP end */ - - case MTK_IOC_SMI_DUMP_LARB: { - unsigned int larb_index; - - ret = copy_from_user(&larb_index, (void*) param, - sizeof(unsigned int)); - if( ret ){ - return -EFAULT; - } - - smi_dumpLarb(larb_index); - } - break; - - case MTK_IOC_SMI_DUMP_COMMON: { - unsigned int arg; - - ret = copy_from_user(&arg, (void*) param, sizeof(unsigned int)); - if( ret ){ - return -EFAULT; - } - - smi_dumpCommon(); - } - break; - - default: - return -1; - } - - return ret; -} - -static const struct file_operations smiFops = -{ - .owner = THIS_MODULE, - .open = smi_open, - .release = smi_release, - .unlocked_ioctl = smi_ioctl, - .compat_ioctl = MTK_SMI_COMPAT_ioctl, -}; - -static dev_t smiDevNo = MKDEV(MTK_SMI_MAJOR_NUMBER, 0); -static inline int smi_register( void ){ - if( alloc_chrdev_region(&smiDevNo, 0, 1, "MTK_SMI") ){ - SMIERR("Allocate device No. failed"); - return -EAGAIN; - } - //Allocate driver - pSmiDev = cdev_alloc(); - - if( NULL == pSmiDev ){ - unregister_chrdev_region(smiDevNo, 1); - SMIERR("Allocate mem for kobject failed"); - return -ENOMEM; - } - - //Attatch file operation. - cdev_init(pSmiDev, &smiFops); - pSmiDev->owner = THIS_MODULE; - - //Add to system - if( cdev_add(pSmiDev, smiDevNo, 1) ){ - SMIERR("Attatch file operation failed"); - unregister_chrdev_region(smiDevNo, 1); - return -EAGAIN; - } - - return 0; -} - -static struct class *pSmiClass = NULL; - -static int smi_probe( struct platform_device *pdev ){ - - int i; - - static unsigned int smi_probe_cnt = 0; - struct device* smiDevice = NULL; - SMIMSG("Enter smi_probe\n"); - //Debug only - if( smi_probe_cnt != 0 ){ - SMIERR("Onlye support 1 SMI driver probed\n"); - return 0; - } - smi_probe_cnt++; - SMIMSG("Allocate smi_dev space\n"); - smi_dev = krealloc(smi_dev, sizeof(struct smi_device), GFP_KERNEL); - - if( smi_dev == NULL ){ - SMIERR("Unable to allocate memory for smi driver\n"); - return -ENOMEM; - } - if( NULL == pdev ){ - SMIERR("platform data missed\n"); - return -ENXIO; - } - // Keep the device structure - smi_dev->dev = &pdev->dev; - - // Map registers - for( i = 0; i < SMI_REG_REGION_MAX; i++ ){ - SMIMSG("Save region: %d\n", i); - smi_dev->regs[i] = (void *) of_iomap(pdev->dev.of_node, i); - - if( !smi_dev->regs[i] ){ - SMIERR("Unable to ioremap registers, of_iomap fail, i=%d \n", i); - return -ENOMEM; - } - - // Record the register base in global variable - gSMIBaseAddrs[i] = (unsigned long) (smi_dev->regs[i]); - SMIMSG("DT, i=%d, region=%s, map_addr=0x%p, reg_pa=0x%lx\n", i, - smi_get_region_name(i), smi_dev->regs[i], smi_reg_pa_base[i]); - } - -#if defined(SMI_INTERNAL_CCF_SUPPORT) - smi_dev->smi_common_clk = get_smi_clk("smi-common"); - smi_dev->smi_larb0_clk = get_smi_clk("smi-larb0"); - smi_dev->img_larb2_clk = get_smi_clk("img-larb2"); - smi_dev->vdec0_vdec_clk = get_smi_clk("vdec0-vdec"); - smi_dev->vdec1_larb_clk = get_smi_clk("vdec1-larb"); - smi_dev->venc_larb_clk = get_smi_clk("venc-larb"); -#endif - - SMIMSG("Execute smi_register\n"); - if( smi_register() ){ - dev_err(&pdev->dev, "register char failed\n"); - return -EAGAIN; - } - - pSmiClass = class_create(THIS_MODULE, "MTK_SMI"); - if(IS_ERR(pSmiClass)) { - int ret = PTR_ERR(pSmiClass); - SMIERR("Unable to create class, err = %d", ret); - return ret; - } - SMIMSG("Create davice\n"); - smiDevice = device_create(pSmiClass, NULL, smiDevNo, NULL, "MTK_SMI"); - smiDeviceUevent = smiDevice; - - SMIMSG("SMI probe done.\n"); - - // To adapt the legacy codes - smi_reg_base_common_ext = gSMIBaseAddrs[SMI_COMMON_REG_INDX]; - smi_reg_base_barb0 = gSMIBaseAddrs[SMI_LARB0_REG_INDX]; - smi_reg_base_barb1 = gSMIBaseAddrs[SMI_LARB1_REG_INDX]; - smi_reg_base_barb2 = gSMIBaseAddrs[SMI_LARB2_REG_INDX]; - smi_reg_base_barb3 = gSMIBaseAddrs[SMI_LARB3_REG_INDX]; - //smi_reg_base_barb4 = gSMIBaseAddrs[SMI_LARB4_REG_INDX]; - - gLarbBaseAddr[0] = LARB0_BASE; - gLarbBaseAddr[1] = LARB1_BASE; - gLarbBaseAddr[2] = LARB2_BASE; - gLarbBaseAddr[3] = LARB3_BASE; - //gLarbBaseAddr[4] = LARB4_BASE; - - SMIMSG("Execute smi_common_init\n"); - smi_common_init(); - - SMIMSG("Execute SMI_DBG_Init\n"); - SMI_DBG_Init(); - return 0; - -} - -char* smi_get_region_name( unsigned int region_indx ){ - switch( region_indx ){ - case SMI_COMMON_REG_INDX: - return "smi_common"; - case SMI_LARB0_REG_INDX: - return "larb0"; - case SMI_LARB1_REG_INDX: - return "larb1"; - case SMI_LARB2_REG_INDX: - return "larb2"; - case SMI_LARB3_REG_INDX: - return "larb3"; - //case SMI_LARB4_REG_INDX: - // return "larb4"; - default: - SMIMSG("invalid region id=%d", region_indx); - return "unknown"; - } -} - -void register_base_dump( void ){ - int i = 0; - unsigned long pa_value = 0; - unsigned long va_value = 0; - - for( i = 0; i < SMI_REG_REGION_MAX; i++ ){ - va_value = gSMIBaseAddrs[i]; - pa_value = virt_to_phys((void*) va_value); - SMIMSG("REG BASE:%s-->VA=0x%lx,PA=0x%lx,SPEC=0x%lx\n", - smi_get_region_name(i), va_value, pa_value, smi_reg_pa_base[i]); - } -} - -static int smi_remove( struct platform_device *pdev ){ - cdev_del(pSmiDev); - unregister_chrdev_region(smiDevNo, 1); - device_destroy(pSmiClass, smiDevNo); - class_destroy( pSmiClass); - return 0; -} - -static int smi_suspend( struct platform_device *pdev, pm_message_t mesg ){ - return 0; -} - -static int smi_resume( struct platform_device *pdev ){ - return 0; -} - -#ifdef SMI_DT_SUPPORT -static const struct of_device_id smi_of_ids[] ={ - { .compatible = "mediatek,SMI_COMMON",}, - {} -}; -#endif //SMI_DT_SUPPORT -static struct platform_driver smiDrv ={ - .probe = smi_probe, - .remove = smi_remove, - .suspend= smi_suspend, - .resume = smi_resume, - .driver ={ - .name = "MTK_SMI", - .owner = THIS_MODULE, -#ifdef SMI_DT_SUPPORT - .of_match_table = smi_of_ids, -#endif //SMI_DT_SUPPORT - } -}; - -static int __init smi_init(void) -{ - SMIMSG("smi_init enter\n"); - spin_lock_init(&g_SMIInfo.SMI_lock); - /* MMDVFS init */ - mmdvfs_init(&g_smi_bwc_mm_info); - - memset(g_SMIInfo.pu4ConcurrencyTable , 0 , SMI_BWC_SCEN_CNT * sizeof(unsigned int)); - - // Informs the kernel about the function to be called - // if hardware matching MTK_SMI has been found - SMIMSG("register platform driver\n"); - if (platform_driver_register(&smiDrv)){ - SMIERR("failed to register MAU driver"); - return -ENODEV; - } - SMIMSG("exit smi_init\n"); - return 0; -} - -static void __exit smi_exit(void) -{ - platform_driver_unregister(&smiDrv); - -} - -static void smi_dumpCommonDebugMsg( int output_gce_buffer ){ - unsigned long u4Base; - int smiCommonClkEnabled = 0; - - smiCommonClkEnabled = clock_is_on(MT_CG_DISP0_SMI_COMMON); - //SMI COMMON dump - if( smi_debug_level == 0 && (!smiCommonClkEnabled) ){ - SMIMSG3(output_gce_buffer, "===SMI common clock is disabled===\n"); - return; - } - - SMIMSG3(output_gce_buffer, "===SMI common reg dump, CLK: %d===\n", smiCommonClkEnabled); - - u4Base = SMI_COMMON_EXT_BASE; - SMIMSG3(output_gce_buffer, "[0x100,0x104,0x108]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x100), M4U_ReadReg32(u4Base, 0x104), - M4U_ReadReg32(u4Base, 0x108)); - SMIMSG3(output_gce_buffer, "[0x10C,0x110,0x114]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x10C), M4U_ReadReg32(u4Base, 0x110), - M4U_ReadReg32(u4Base, 0x114)); - SMIMSG3(output_gce_buffer, "[0x220,0x230,0x234,0x238]=[0x%x,0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x220), M4U_ReadReg32(u4Base, 0x230), - M4U_ReadReg32(u4Base, 0x234), M4U_ReadReg32(u4Base, 0x238)); - SMIMSG3(output_gce_buffer, "[0x400,0x404,0x408]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x400), M4U_ReadReg32(u4Base, 0x404), - M4U_ReadReg32(u4Base, 0x408)); - SMIMSG3(output_gce_buffer, "[0x40C,0x430,0x440]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x40C), M4U_ReadReg32(u4Base, 0x430), - M4U_ReadReg32(u4Base, 0x440)); - - // TBD: M4U should dump these - /* - // For VA and PA check: - // 0x1000C5C0 , 0x1000C5C4, 0x1000C5C8, 0x1000C5CC, 0x1000C5D0 - u4Base = SMI_COMMON_AO_BASE; - SMIMSG("===SMI always on reg dump===\n"); - SMIMSG("[0x5C0,0x5C4,0x5C8]=[0x%x,0x%x,0x%x]\n" ,M4U_ReadReg32(u4Base , 0x5C0),M4U_ReadReg32(u4Base , 0x5C4),M4U_ReadReg32(u4Base , 0x5C8)); - SMIMSG("[0x5CC,0x5D0]=[0x%x,0x%x]\n" ,M4U_ReadReg32(u4Base , 0x5CC),M4U_ReadReg32(u4Base , 0x5D0)); - */ -} -static int smi_larb_clock_is_on( unsigned int larb_index ){ - - int result = 0; -#if !defined (CONFIG_MTK_FPGA) && !defined (CONFIG_FPGA_EARLY_PORTING) - switch( larb_index ){ - case 0: - result = clock_is_on(MT_CG_DISP0_SMI_LARB0); - break; - case 1: - result = clock_is_on(MT_CG_VDEC1_LARB); - break; - case 2: - result = clock_is_on(MT_CG_IMAGE_LARB2_SMI); - break; - case 3: - result = clock_is_on(MT_CG_VENC_LARB); - break; -// case 4: -// result = clock_is_on(MT_CG_MJC_SMI_LARB); -// break; - default: - result = 0; - break; - } -#endif // !defined (CONFIG_MTK_FPGA) && !defined (CONFIG_FPGA_EARLY_PORTING) - return result; - -} -static void smi_dumpLarbDebugMsg( unsigned int u4Index ){ - unsigned long u4Base = 0; - - int larbClkEnabled = 0; - - u4Base = get_larb_base_addr(u4Index); - - larbClkEnabled = smi_larb_clock_is_on(u4Index); - - if( u4Base == SMI_ERROR_ADDR ){ - SMIMSG("Doesn't support reg dump for Larb%d\n", u4Index); - - return; - }else if( (larbClkEnabled != 0) || smi_debug_level > 0 ){ - SMIMSG("===SMI LARB%d reg dump, CLK: %d===\n", u4Index, larbClkEnabled); - - // Staus Registers - SMIMSG("[0x0,0x8,0x10]=[0x%x,0x%x,0x%x]\n", M4U_ReadReg32(u4Base, 0x0), - M4U_ReadReg32(u4Base, 0x8), M4U_ReadReg32(u4Base, 0x10)); - SMIMSG("[0x24,0x50,0x60]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x24), M4U_ReadReg32(u4Base, 0x50), - M4U_ReadReg32(u4Base, 0x60)); - SMIMSG("[0xa0,0xa4,0xa8]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0xa0), M4U_ReadReg32(u4Base, 0xa4), - M4U_ReadReg32(u4Base, 0xa8)); - SMIMSG("[0xac,0xb0,0xb4]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0xac), M4U_ReadReg32(u4Base, 0xb0), - M4U_ReadReg32(u4Base, 0xb4)); - SMIMSG("[0xb8,0xbc,0xc0]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0xb8), M4U_ReadReg32(u4Base, 0xbc), - M4U_ReadReg32(u4Base, 0xc0)); - SMIMSG("[0xc8,0xcc]=[0x%x,0x%x]\n", M4U_ReadReg32(u4Base, 0xc8), - M4U_ReadReg32(u4Base, 0xcc)); - // Settings - SMIMSG("[0x200, 0x204, 0x208]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x200), M4U_ReadReg32(u4Base, 0x204), - M4U_ReadReg32(u4Base, 0x208)); - - SMIMSG("[0x20c, 0x210, 0x214]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x20c), M4U_ReadReg32(u4Base, 0x210), - M4U_ReadReg32(u4Base, 0x214)); - - SMIMSG("[0x218, 0x21c, 0x220]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x218), M4U_ReadReg32(u4Base, 0x21c), - M4U_ReadReg32(u4Base, 0x220)); - - SMIMSG("[0x224, 0x228, 0x22c]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x224), M4U_ReadReg32(u4Base, 0x228), - M4U_ReadReg32(u4Base, 0x22c)); - - SMIMSG("[0x230, 0x234, 0x238]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x230), M4U_ReadReg32(u4Base, 0x234), - M4U_ReadReg32(u4Base, 0x238)); - - SMIMSG("[0x23c, 0x240, 0x244]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x23c), M4U_ReadReg32(u4Base, 0x240), - M4U_ReadReg32(u4Base, 0x244)); - - SMIMSG("[0x248, 0x24c]=[0x%x,0x%x]\n", M4U_ReadReg32(u4Base, 0x248), - M4U_ReadReg32(u4Base, 0x24c)); - }else{ - SMIMSG("===SMI LARB%d clock is disabled===\n", u4Index); - } - -} - -static void smi_dump_format( - unsigned long base, - unsigned int from, - unsigned int to ){ - int i, j, left; - unsigned int value[8]; - - for( i = from; i <= to; i += 32 ){ - for( j = 0; j < 8; j++ ){ - value[j] = M4U_ReadReg32(base, i + j * 4); - } - - SMIMSG2("%8x %x %x %x %x %x %x %x %x\n", i, value[0], value[1], - value[2], value[3], value[4], value[5], value[6], value[7]); - } - - left = ((from - to) / 4 + 1) % 8; - - if( left ){ - memset(value, 0, 8 * sizeof(unsigned int)); - - for( j = 0; j < left; j++ ){ - value[j] = M4U_ReadReg32(base, i - 32 + j * 4); - } - - SMIMSG2("%8x %x %x %x %x %x %x %x %x\n", i - 32 + j * 4, value[0], - value[1], value[2], value[3], value[4], value[5], value[6], - value[7]); - } -} - -static void smi_dumpLarb( unsigned int index ){ - unsigned long u4Base; - - u4Base = get_larb_base_addr(index); - - if( u4Base == SMI_ERROR_ADDR ){ - SMIMSG2("Doesn't support reg dump for Larb%d\n", index); - - return; - }else{ - SMIMSG2("===SMI LARB%d reg dump base 0x%lx===\n", index, u4Base); - - smi_dump_format(u4Base, 0, 0x434); - smi_dump_format(u4Base, 0xF00, 0xF0C); - } -} - -static void smi_dumpCommon( void ){ - SMIMSG2("===SMI COMMON reg dump base 0x%lx===\n", SMI_COMMON_EXT_BASE); - - smi_dump_format(SMI_COMMON_EXT_BASE, 0x1A0, 0x444); -} - -void smi_dumpDebugMsg( void ){ - unsigned int u4Index; - - // SMI COMMON dump, 0 stands for not pass log to CMDQ error dumping messages - smi_dumpCommonDebugMsg(0); - - // dump all SMI LARB - for( u4Index = 0; u4Index < SMI_LARB_NR; u4Index++ ){ - smi_dumpLarbDebugMsg(u4Index); - } -} - -int smi_debug_bus_hanging_detect( unsigned int larbs, int show_dump ){ - return smi_debug_bus_hanging_detect_ext(larbs, show_dump, 0); -} - -//output_gce_buffer = 1, write log into kernel log and CMDQ buffer. dual_buffer = 0, write log into kernel log only -int smi_debug_bus_hanging_detect_ext( unsigned int larbs, int show_dump, int output_gce_buffer){ - - int i = 0; - int dump_time = 0; - int is_smi_issue = 0; - int status_code = 0; - // Keep the dump result - unsigned char smi_common_busy_count = 0; - volatile unsigned int reg_temp = 0; - unsigned char smi_larb_busy_count[SMI_LARB_NR] = { 0 }; - unsigned char smi_larb_mmu_status[SMI_LARB_NR] = { 0 }; - - // dump resister and save resgister status - for( dump_time = 0; dump_time < 5; dump_time++ ){ - unsigned int u4Index = 0; - reg_temp = M4U_ReadReg32(SMI_COMMON_EXT_BASE, 0x440); - if( (reg_temp & (1 << 0)) == 0 ){ - // smi common is busy - smi_common_busy_count++; - } - // Dump smi common regs - if( show_dump != 0 ){ - smi_dumpCommonDebugMsg(output_gce_buffer); - } - for( u4Index = 0; u4Index < SMI_LARB_NR; u4Index++ ){ - unsigned long u4Base = get_larb_base_addr(u4Index); - if( u4Base != SMI_ERROR_ADDR ){ - reg_temp = M4U_ReadReg32(u4Base, 0x0); - if( reg_temp != 0 ){ - // Larb is busy - smi_larb_busy_count[u4Index]++; - } - smi_larb_mmu_status[u4Index] = M4U_ReadReg32(u4Base, 0xa0); - if( show_dump != 0 ){ - smi_dumpLarbDebugMsg(u4Index); - } - } - } - - } - - // Show the checked result - for( i = 0; i < SMI_LARB_NR; i++ ){ // Check each larb - if( SMI_DGB_LARB_SELECT(larbs, i) ){ - // larb i has been selected - // Get status code - - if( smi_larb_busy_count[i] == 5 ){ // The larb is always busy - if( smi_common_busy_count == 5 ){ // smi common is always busy - status_code = 1; - }else if( smi_common_busy_count == 0 ){ // smi common is always idle - status_code = 2; - }else{ - status_code = 5; // smi common is sometimes busy and idle - } - }else if( smi_larb_busy_count[i] == 0 ){ // The larb is always idle - if( smi_common_busy_count == 5 ){ // smi common is always busy - status_code = 3; - }else if( smi_common_busy_count == 0 ){ // smi common is always idle - status_code = 4; - }else{ - status_code = 6; // smi common is sometimes busy and idle - } - }else{ //sometime the larb is busy - if( smi_common_busy_count == 5 ){ // smi common is always busy - status_code = 7; - }else if( smi_common_busy_count == 0 ){ // smi common is always idle - status_code = 8; - }else{ - status_code = 9; // smi common is sometimes busy and idle - } - } - - // Send the debug message according to the final result - switch( status_code ){ - case 1: - case 3: - case 5: - case 7: - case 8: - SMIMSG3( - output_gce_buffer, - "Larb%d Busy=%d/5, SMI Common Busy=%d/5, status=%d ==> Check engine's state first\n", - i, smi_larb_busy_count[i], smi_common_busy_count, - status_code); - SMIMSG3( - output_gce_buffer, - "If the engine is waiting for Larb%ds' response, it needs SMI HW's check\n", - i); - break; - case 2: - if( smi_larb_mmu_status[i] == 0 ){ - SMIMSG3( - output_gce_buffer, - "Larb%d Busy=%d/5, SMI Common Busy=%d/5, status=%d ==> Check engine state first\n", - i, smi_larb_busy_count[i], smi_common_busy_count, - status_code); - SMIMSG3( - output_gce_buffer, - "If the engine is waiting for Larb%ds' response, it needs SMI HW's check\n", - i); - }else{ - SMIMSG3( - output_gce_buffer, - "Larb%d Busy=%d/5, SMI Common Busy=%d/5, status=%d ==> MMU port config error\n", - i, smi_larb_busy_count[i], smi_common_busy_count, - status_code); - is_smi_issue = 1; - } - break; - case 4: - case 6: - case 9: - SMIMSG3( - output_gce_buffer, - "Larb%d Busy=%d/5, SMI Common Busy=%d/5, status=%d ==> not SMI issue\n", - i, smi_larb_busy_count[i], smi_common_busy_count, - status_code); - break; - default: - SMIMSG3( - output_gce_buffer, - "Larb%d Busy=%d/5, SMI Common Busy=%d/5, status=%d ==> status unknown\n", - i, smi_larb_busy_count[i], smi_common_busy_count, - status_code); - break; - } - } - - } - - return is_smi_issue; -} - -void smi_client_status_change_notify( int module, int mode ){ - -} - -#if IS_ENABLED(CONFIG_COMPAT) -// 32 bits process ioctl support: -// This is prepared for the future extension since currently the sizes of 32 bits -// and 64 bits smi parameters are the same. - -typedef struct -{ - compat_int_t scenario; - compat_int_t b_on_off; //0 : exit this scenario , 1 : enter this scenario -}MTK_SMI_COMPAT_BWC_CONFIG; - -typedef struct -{ - compat_int_t property; - compat_int_t value1; - compat_int_t value2; -}MTK_SMI_COMPAT_BWC_INFO_SET; - -typedef struct -{ - compat_uint_t flag; // Reserved - compat_int_t concurrent_profile; - compat_int_t sensor_size[2]; - compat_int_t video_record_size[2]; - compat_int_t display_size[2]; - compat_int_t tv_out_size[2]; - compat_int_t fps; - compat_int_t video_encode_codec; - compat_int_t video_decode_codec; - compat_int_t hw_ovl_limit; -}MTK_SMI_COMPAT_BWC_MM_INFO; - -#define COMPAT_MTK_IOC_SMI_BWC_CONFIG MTK_IOW(24, MTK_SMI_COMPAT_BWC_CONFIG) -#define COMPAT_MTK_IOC_SMI_BWC_INFO_SET MTK_IOWR(28, MTK_SMI_COMPAT_BWC_INFO_SET) -#define COMPAT_MTK_IOC_SMI_BWC_INFO_GET MTK_IOWR(29, MTK_SMI_COMPAT_BWC_MM_INFO) - -static int compat_get_smi_bwc_config_struct( - MTK_SMI_COMPAT_BWC_CONFIG __user *data32, - MTK_SMI_BWC_CONFIG __user *data){ - - compat_int_t i; - int err; - - // since the int sizes of 32 A32 and A64 are equal so we don't convert them actually here - err = get_user(i, &(data32->scenario)); - err |= put_user(i, &(data->scenario)); - err |= get_user(i, &(data32->b_on_off)); - err |= put_user(i, &(data->b_on_off)); - - return err; -} - -static int compat_get_smi_bwc_mm_info_set_struct( - MTK_SMI_COMPAT_BWC_INFO_SET __user *data32, - MTK_SMI_BWC_INFO_SET __user *data){ - - compat_int_t i; - int err; - - // since the int sizes of 32 A32 and A64 are equal so we don't convert them actually here - err = get_user(i, &(data32->property)); - err |= put_user(i, &(data->property)); - err |= get_user(i, &(data32->value1)); - err |= put_user(i, &(data->value1)); - err |= get_user(i, &(data32->value2)); - err |= put_user(i, &(data->value2)); - - return err; -} - -static int compat_get_smi_bwc_mm_info_struct( - MTK_SMI_COMPAT_BWC_MM_INFO __user *data32, - MTK_SMI_BWC_MM_INFO __user *data) -{ - compat_uint_t u; - compat_int_t i; - compat_int_t p[2]; - int err; - - // since the int sizes of 32 A32 and A64 are equal so we don't convert them actually here - err = get_user(u, &(data32->flag)); - err |= put_user(u, &(data->flag)); - err |= get_user(i, &(data32->concurrent_profile)); - err |= put_user(i, &(data->concurrent_profile)); - err |= copy_from_user(p, &(data32->sensor_size),sizeof(p)); - err |= copy_to_user(&(data->sensor_size),p ,sizeof(p)); - err |= copy_from_user(p, &(data32->video_record_size),sizeof(p)); - err |= copy_to_user(&(data->video_record_size),p ,sizeof(p)); - err |= copy_from_user(p, &(data32->display_size),sizeof(p)); - err |= copy_to_user(&(data->display_size),p ,sizeof(p)); - err |= copy_from_user(p, &(data32->tv_out_size),sizeof(p)); - err |= copy_to_user(&(data->tv_out_size),p ,sizeof(p)); - err |= get_user(i, &(data32->fps)); - err |= put_user(i, &(data->fps)); - err |= get_user(i, &(data32->video_encode_codec)); - err |= put_user(i, &(data->video_encode_codec)); - err |= get_user(i, &(data32->video_decode_codec)); - err |= put_user(i, &(data->video_decode_codec)); - err |= get_user(i, &(data32->hw_ovl_limit)); - err |= put_user(i, &(data->hw_ovl_limit)); - - - return err; -} - -static int compat_put_smi_bwc_mm_info_struct( - MTK_SMI_COMPAT_BWC_MM_INFO __user *data32, - MTK_SMI_BWC_MM_INFO __user *data) -{ - - compat_uint_t u; - compat_int_t i; - compat_int_t p[2]; - int err; - - // since the int sizes of 32 A32 and A64 are equal so we don't convert them actually here - err = get_user(u, &(data->flag)); - err |= put_user(u, &(data32->flag)); - err |= get_user(i, &(data->concurrent_profile)); - err |= put_user(i, &(data32->concurrent_profile)); - err |= copy_from_user(p, &(data->sensor_size),sizeof(p)); - err |= copy_to_user(&(data32->sensor_size),p ,sizeof(p)); - err |= copy_from_user(p, &(data->video_record_size),sizeof(p)); - err |= copy_to_user(&(data32->video_record_size),p ,sizeof(p)); - err |= copy_from_user(p, &(data->display_size),sizeof(p)); - err |= copy_to_user(&(data32->display_size),p ,sizeof(p)); - err |= copy_from_user(p, &(data->tv_out_size),sizeof(p)); - err |= copy_to_user(&(data32->tv_out_size),p ,sizeof(p)); - err |= get_user(i, &(data->fps)); - err |= put_user(i, &(data32->fps)); - err |= get_user(i, &(data->video_encode_codec)); - err |= put_user(i, &(data32->video_encode_codec)); - err |= get_user(i, &(data->video_decode_codec)); - err |= put_user(i, &(data32->video_decode_codec)); - err |= get_user(i, &(data->hw_ovl_limit)); - err |= put_user(i, &(data32->hw_ovl_limit)); - return err; -} - -long MTK_SMI_COMPAT_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - long ret; - - if (!filp->f_op || !filp->f_op->unlocked_ioctl) - return -ENOTTY; - - switch (cmd){ - case COMPAT_MTK_IOC_SMI_BWC_CONFIG: - { - if(COMPAT_MTK_IOC_SMI_BWC_CONFIG == MTK_IOC_SMI_BWC_CONFIG) - { - SMIMSG("Optimized compct IOCTL: COMPAT_MTK_IOC_SMI_BWC_CONFIG"); - return filp->f_op->unlocked_ioctl(filp, cmd,(unsigned long)compat_ptr(arg)); - } else{ - - MTK_SMI_COMPAT_BWC_CONFIG __user *data32; - MTK_SMI_BWC_CONFIG __user *data; - int err; - - data32 = compat_ptr(arg); - data = compat_alloc_user_space(sizeof(MTK_SMI_BWC_CONFIG)); - - if (data == NULL) - return -EFAULT; - - err = compat_get_smi_bwc_config_struct(data32, data); - if (err) - return err; - - ret = filp->f_op->unlocked_ioctl(filp, MTK_IOC_SMI_BWC_CONFIG, - (unsigned long)data); - return ret; - } - } - - case COMPAT_MTK_IOC_SMI_BWC_INFO_SET: - { - - if(COMPAT_MTK_IOC_SMI_BWC_INFO_SET == MTK_IOC_SMI_BWC_INFO_SET) - { - SMIMSG("Optimized compct IOCTL: COMPAT_MTK_IOC_SMI_BWC_INFO_SET"); - return filp->f_op->unlocked_ioctl(filp, cmd,(unsigned long)compat_ptr(arg)); - } else{ - - MTK_SMI_COMPAT_BWC_INFO_SET __user *data32; - MTK_SMI_BWC_INFO_SET __user *data; - int err; - - data32 = compat_ptr(arg); - data = compat_alloc_user_space(sizeof(MTK_SMI_BWC_INFO_SET)); - if (data == NULL) - return -EFAULT; - - err = compat_get_smi_bwc_mm_info_set_struct(data32, data); - if (err) - return err; - - return filp->f_op->unlocked_ioctl(filp, MTK_IOC_SMI_BWC_INFO_SET, - (unsigned long)data); - } - } - - case COMPAT_MTK_IOC_SMI_BWC_INFO_GET: - { - - if(COMPAT_MTK_IOC_SMI_BWC_INFO_GET == MTK_IOC_SMI_BWC_INFO_GET){ - SMIMSG("Optimized compct IOCTL: COMPAT_MTK_IOC_SMI_BWC_INFO_GET"); - return filp->f_op->unlocked_ioctl(filp, cmd,(unsigned long)compat_ptr(arg)); - } else{ - MTK_SMI_COMPAT_BWC_MM_INFO __user *data32; - MTK_SMI_BWC_MM_INFO __user *data; - int err; - - data32 = compat_ptr(arg); - data = compat_alloc_user_space(sizeof(MTK_SMI_BWC_MM_INFO)); - - if (data == NULL) - return -EFAULT; - - err = compat_get_smi_bwc_mm_info_struct(data32, data); - if (err) - return err; - - ret = filp->f_op->unlocked_ioctl(filp, MTK_IOC_SMI_BWC_INFO_GET, - (unsigned long)data); - - err = compat_put_smi_bwc_mm_info_struct(data32, data); - - if (err) - return err; - - return ret; - } - } - - case MTK_IOC_SMI_DUMP_LARB: - case MTK_IOC_SMI_DUMP_COMMON: - - return filp->f_op->unlocked_ioctl(filp, cmd, - (unsigned long)compat_ptr(arg)); - default: - return -ENOIOCTLCMD; - } - -} - -#endif - -module_init( smi_init); -module_exit( smi_exit); - -module_param_named(debug_level, smi_debug_level, uint, S_IRUGO | S_IWUSR); -module_param_named(tuning_mode, smi_tuning_mode, uint, S_IRUGO | S_IWUSR); -module_param_named(wifi_disp_transaction, wifi_disp_transaction, uint, S_IRUGO | S_IWUSR); - -MODULE_DESCRIPTION("MTK SMI driver"); -MODULE_AUTHOR("Frederic Chen<frederic.chen@mediatek.com>"); -MODULE_LICENSE("GPL"); - diff --git a/drivers/misc/mediatek/smi/mt6735/smi_common_d2.c b/drivers/misc/mediatek/smi/mt6735/smi_common_d2.c deleted file mode 100644 index cbf1cca56..000000000 --- a/drivers/misc/mediatek/smi/mt6735/smi_common_d2.c +++ /dev/null @@ -1,1970 +0,0 @@ -#include <linux/of.h> -#include <linux/of_irq.h> -#include <linux/of_address.h> -#include <linux/kobject.h> - -#include <linux/uaccess.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/cdev.h> -#include <linux/mm.h> -#include <linux/vmalloc.h> -#include <linux/slab.h> -#include <linux/aee.h> -#include <linux/xlog.h> -#include <mach/mt_clkmgr.h> -#include <asm/io.h> - -#include <linux/ioctl.h> -#include <linux/fs.h> - -#if IS_ENABLED(CONFIG_COMPAT) -#include <linux/uaccess.h> -#include <linux/compat.h> -#endif - -#include <mach/mt_smi.h> - - -#include "smi_reg_d2.h" -#include "smi_common.h" -#include "smi_debug.h" - -#include "mmdvfs_mgr.h" - -#undef pr_fmt -#define pr_fmt(fmt) "[SMI]" fmt - -#define SMI_LOG_TAG "SMI" - -#define SMI_DT_SUPPORT - -#define LARB_BACKUP_REG_SIZE 128 -#define SMI_COMMON_BACKUP_REG_NUM 8 - -#define SF_HWC_PIXEL_MAX_NORMAL (1920 * 1080 * 7) -#define SF_HWC_PIXEL_MAX_VR (1920 * 1080 * 4 + 1036800) // 4.5 FHD size -#define SF_HWC_PIXEL_MAX_VP (1920 * 1080 * 7) -#define SF_HWC_PIXEL_MAX_ALWAYS_GPU (1920 * 1080 * 1) - -#define SMIDBG(level, x...) \ - do{ \ - if (smi_debug_level >= (level)) \ - SMIMSG(x); \ - } while (0) - -typedef struct { - spinlock_t SMI_lock; - unsigned int pu4ConcurrencyTable[SMI_BWC_SCEN_CNT]; //one bit represent one module -} SMI_struct; - -static SMI_struct g_SMIInfo; - -/* LARB BASE ADDRESS */ -static unsigned long gLarbBaseAddr[SMI_LARB_NR] = { 0, 0, 0}; - -// DT porting -unsigned long smi_reg_base_common_ext = 0; -unsigned long smi_reg_base_barb0 = 0; -unsigned long smi_reg_base_barb1 = 0; -unsigned long smi_reg_base_barb2 = 0; - -#define SMI_REG_REGION_MAX 4 -#define SMI_COMMON_REG_INDX 0 -#define SMI_LARB0_REG_INDX 1 -#define SMI_LARB1_REG_INDX 2 -#define SMI_LARB2_REG_INDX 3 - -static unsigned long gSMIBaseAddrs[SMI_REG_REGION_MAX]; -void register_base_dump( void ); - -//#ifdef SMI_DT_SUPPORT -char* smi_get_region_name( unsigned int region_indx ); -//#endif //SMI_DT_SUPPORT - -struct smi_device{ - struct device *dev;void __iomem *regs[SMI_REG_REGION_MAX]; -}; -static struct smi_device *smi_dev = NULL; - -static struct device* smiDeviceUevent = NULL; - -static struct cdev * pSmiDev = NULL; - -static const unsigned int larb_port_num[SMI_LARB_NR] = { SMI_LARB0_PORT_NUM, - SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM}; - -static unsigned short int larb0_port_backup[SMI_LARB0_PORT_NUM]; -static unsigned short int larb1_port_backup[SMI_LARB1_PORT_NUM]; -static unsigned short int larb2_port_backup[SMI_LARB2_PORT_NUM]; - -/* SMI COMMON register list to be backuped */ -static unsigned short -g_smi_common_backup_reg_offset[SMI_COMMON_BACKUP_REG_NUM] = { 0x100, 0x104, - 0x108, 0x10c, 0x110, 0x230, 0x234, 0x238 }; -static unsigned int g_smi_common_backup[SMI_COMMON_BACKUP_REG_NUM]; - -static unsigned char larb_vc_setting[SMI_LARB_NR] = { 0, 2, 1}; - -static unsigned short int * larb_port_backup[SMI_LARB_NR] = { - larb0_port_backup, larb1_port_backup, larb2_port_backup }; - -// To keep the HW's init value -static int is_default_value_saved = 0; -static unsigned int default_val_smi_l1arb[SMI_LARB_NR] = { 0 }; - -static unsigned int wifi_disp_transaction = 0; - -/* debug level */ -static unsigned int smi_debug_level = 0; - -/* tuning mode, 1 for register ioctl */ -static unsigned int smi_tuning_mode = 0; - -static unsigned int smi_profile = SMI_BWC_SCEN_NORMAL; - -static unsigned int* pLarbRegBackUp[SMI_LARB_NR]; -static int g_bInited = 0; - -static MTK_SMI_BWC_MM_INFO g_smi_bwc_mm_info = { 0, 0, { 0, 0 }, { 0, 0 }, { 0, - 0 }, { 0, 0 }, 0, 0, 0, SF_HWC_PIXEL_MAX_NORMAL }; - -char *smi_port_name[][21] = { { /* 0 MMSYS */ - "disp_ovl0", "disp_rdma0", "disp_rdma1", "disp_wdma0", "disp_ovl1", - "disp_rdma2", "disp_wdma1", "disp_od_r", "disp_od_w", "mdp_rdma0", - "mdp_rdma1", "mdp_wdma", "mdp_wrot0", "mdp_wrot1" }, { /* 1 VDEC */ - "hw_vdec_mc_ext", "hw_vdec_pp_ext", "hw_vdec_ufo_ext", "hw_vdec_vld_ext", - "hw_vdec_vld2_ext", "hw_vdec_avc_mv_ext", "hw_vdec_pred_rd_ext", - "hw_vdec_pred_wr_ext", "hw_vdec_ppwrap_ext" }, { /* 2 ISP */ - "imgo", "rrzo", "aao", "lcso", "esfko", "imgo_d", "lsci", "lsci_d", "bpci", - "bpci_d", "ufdi", "imgi", "img2o", "img3o", "vipi", "vip2i", "vip3i", - "lcei", "rb", "rp", "wr" }, { /* 3 VENC */ - "venc_rcpu", "venc_rec", "venc_bsdma", "venc_sv_comv", "venc_rd_comv", - "jpgenc_bsdma", "remdc_sdma", "remdc_bsdma", "jpgenc_rdma", "jpgenc_sdma", - "jpgdec_wdma", "jpgdec_bsdma", "venc_cur_luma", "venc_cur_chroma", - "venc_ref_luma", "venc_ref_chroma", "remdc_wdma", "venc_nbm_rdma", - "venc_nbm_wdma" }, { /* 4 MJC */ - "mjc_mv_rd", "mjc_mv_wr", "mjc_dma_rd", "mjc_dma_wr" } }; - -static unsigned long smi_reg_pa_base[SMI_REG_REGION_MAX] = { 0x14017000, - 0x14016000, 0x16010000, 0x15001000 }; - -static void initSetting( void ); -static void vpSetting( void ); -static void vrSetting( void ); -static void icfpSetting( void ); -static void vpWfdSetting( void ); - -static void smi_dumpLarb( unsigned int index ); -static void smi_dumpCommon( void ); -extern void smi_dumpDebugMsg( void ); -#if IS_ENABLED(CONFIG_COMPAT) - long MTK_SMI_COMPAT_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); -#else - #define MTK_SMI_COMPAT_ioctl NULL -#endif - -// for slow motion force 30 fps -extern int primary_display_force_set_vsync_fps( unsigned int fps ); -extern unsigned int primary_display_get_fps( void ); - -// Use this function to get base address of Larb resgister -// to support error checking -unsigned long get_larb_base_addr( int larb_id ){ - if( larb_id > SMI_LARB_NR || larb_id < 0 ){ - return SMI_ERROR_ADDR; - }else{ - return gLarbBaseAddr[larb_id]; - } -} - -static int larb_clock_on( int larb_id ){ - -#if !defined (CONFIG_MTK_FPGA) && !defined (CONFIG_FPGA_EARLY_PORTING) - char name[30]; - sprintf(name, "smi+%d", larb_id); - - switch( larb_id ){ - case 0: - enable_clock(MT_CG_DISP0_SMI_COMMON, name); - enable_clock(MT_CG_DISP0_SMI_LARB0, name); - break; - case 1: - enable_clock(MT_CG_DISP0_SMI_COMMON, name); - enable_clock(MT_CG_VDEC1_LARB, name); - break; - case 2: - enable_clock(MT_CG_DISP0_SMI_COMMON, name); - enable_clock(MT_CG_IMAGE_LARB2_SMI, name); - break; - default: - break; - } -#endif /* CONFIG_MTK_FPGA */ - - return 0; -} - -static int larb_clock_off( int larb_id ){ - -#ifndef CONFIG_MTK_FPGA - char name[30]; - sprintf(name, "smi+%d", larb_id); - - switch( larb_id ){ - case 0: - disable_clock(MT_CG_DISP0_SMI_LARB0, name); - disable_clock(MT_CG_DISP0_SMI_COMMON, name); - break; - case 1: - disable_clock(MT_CG_VDEC1_LARB, name); - disable_clock(MT_CG_DISP0_SMI_COMMON, name); - break; - case 2: - disable_clock(MT_CG_IMAGE_LARB2_SMI, name); - disable_clock(MT_CG_DISP0_SMI_COMMON, name); - break; - default: - break; - } -#endif /* CONFIG_MTK_FPGA */ - - return 0; -} - -static void backup_smi_common( void ){ - int i; - - for( i = 0; i < SMI_COMMON_BACKUP_REG_NUM; i++ ){ - g_smi_common_backup[i] = M4U_ReadReg32(SMI_COMMON_EXT_BASE, - (unsigned long) g_smi_common_backup_reg_offset[i]); - } -} - -static void restore_smi_common( void ){ - int i; - - for( i = 0; i < SMI_COMMON_BACKUP_REG_NUM; i++ ){ - M4U_WriteReg32(SMI_COMMON_EXT_BASE, - (unsigned long) g_smi_common_backup_reg_offset[i], - g_smi_common_backup[i]); - } -} - -static void backup_larb_smi( int index ){ - int port_index = 0; - unsigned short int *backup_ptr = NULL; - unsigned long larb_base = gLarbBaseAddr[index]; - unsigned long larb_offset = 0x200; - int total_port_num = 0; - - // boundary check for larb_port_num and larb_port_backup access - if( index < 0 || index >= SMI_LARB_NR ){ - return; - } - - total_port_num = larb_port_num[index]; - backup_ptr = larb_port_backup[index]; - - // boundary check for port value access - if( total_port_num <= 0 || backup_ptr == NULL ){ - return; - } - - for( port_index = 0; port_index < total_port_num; port_index++ ){ - *backup_ptr = (unsigned short int) (M4U_ReadReg32(larb_base, - larb_offset)); - backup_ptr++; - larb_offset += 4; - } - - /* backup smi common along with larb0, smi common clk is guaranteed to be on when processing larbs */ - if( index == 0 ){ - backup_smi_common(); - } - - return; -} - -static void restore_larb_smi( int index ){ - int port_index = 0; - unsigned short int *backup_ptr = NULL; - unsigned long larb_base = gLarbBaseAddr[index]; - unsigned long larb_offset = 0x200; - unsigned int backup_value = 0; - int total_port_num = 0; - - // boundary check for larb_port_num and larb_port_backup access - if( index < 0 || index >= SMI_LARB_NR ){ - return; - } - total_port_num = larb_port_num[index]; - backup_ptr = larb_port_backup[index]; - - // boundary check for port value access - if( total_port_num <= 0 || backup_ptr == NULL ){ - return; - } - - /* restore smi common along with larb0, smi common clk is guaranteed to be on when processing larbs */ - if( index == 0 ){ - restore_smi_common(); - } - - for( port_index = 0; port_index < total_port_num; port_index++ ){ - backup_value = *backup_ptr; - M4U_WriteReg32(larb_base, larb_offset, backup_value); - backup_ptr++; - larb_offset += 4; - } - - /* we do not backup 0x20 because it is a fixed setting */ - M4U_WriteReg32(larb_base, 0x20, larb_vc_setting[index]); - - /* turn off EMI empty OSTD dobule, fixed setting */ - M4U_WriteReg32(larb_base, 0x2c, 4); - - return; -} - -static int larb_reg_backup( int larb ){ - unsigned int* pReg = pLarbRegBackUp[larb]; - unsigned long larb_base = gLarbBaseAddr[larb]; - - *(pReg++) = M4U_ReadReg32(larb_base, SMI_LARB_CON); - - // *(pReg++) = M4U_ReadReg32(larb_base, SMI_SHARE_EN); - // *(pReg++) = M4U_ReadReg32(larb_base, SMI_ROUTE_SEL); - - backup_larb_smi(larb); - - if( 0 == larb ){ - g_bInited = 0; - } - - return 0; -} - -static int smi_larb_init( unsigned int larb ){ - unsigned int regval = 0; - unsigned int regval1 = 0; - unsigned int regval2 = 0; - unsigned long larb_base = get_larb_base_addr(larb); - - // Clock manager enable LARB clock before call back restore already, it will be disabled after restore call back returns - // Got to enable OSTD before engine starts - regval = M4U_ReadReg32(larb_base, SMI_LARB_STAT); - - // TODO: FIX ME - // regval1 = M4U_ReadReg32(larb_base , SMI_LARB_MON_BUS_REQ0); - // regval2 = M4U_ReadReg32(larb_base , SMI_LARB_MON_BUS_REQ1); - - if( 0 == regval ){ - SMIDBG(1, "Init OSTD for larb_base: 0x%lx\n", larb_base); - M4U_WriteReg32(larb_base, SMI_LARB_OSTDL_SOFT_EN, 0xffffffff); - }else{ - SMIMSG( - "Larb: 0x%lx is busy : 0x%x , port:0x%x,0x%x ,fail to set OSTD\n", - larb_base, regval, regval1, regval2); - smi_dumpDebugMsg(); - if( smi_debug_level >= 1 ){ - SMIERR( - "DISP_MDP LARB 0x%lx OSTD cannot be set:0x%x,port:0x%x,0x%x\n", - larb_base, regval, regval1, regval2); - }else{ - dump_stack(); - } - } - - restore_larb_smi(larb); - - return 0; -} - -int larb_reg_restore( int larb ){ - unsigned long larb_base = SMI_ERROR_ADDR; - unsigned int regval = 0; - unsigned int* pReg = NULL; - - larb_base = get_larb_base_addr(larb); - - // The larb assign doesn't exist - if( larb_base == SMI_ERROR_ADDR ){ - SMIMSG("Can't find the base address for Larb%d\n", larb); - return 0; - } - - pReg = pLarbRegBackUp[larb]; - - SMIDBG(1, "+larb_reg_restore(), larb_idx=%d \n", larb); - SMIDBG(1, "m4u part restore, larb_idx=%d \n", larb); - //warning: larb_con is controlled by set/clr - regval = *(pReg++); - M4U_WriteReg32(larb_base, SMI_LARB_CON_CLR, ~(regval)); - M4U_WriteReg32(larb_base, SMI_LARB_CON_SET, (regval)); - - //M4U_WriteReg32(larb_base, SMI_SHARE_EN, *(pReg++) ); - //M4U_WriteReg32(larb_base, SMI_ROUTE_SEL, *(pReg++) ); - - smi_larb_init(larb); - - return 0; -} - -// callback after larb clock is enabled -void on_larb_power_on( struct larb_monitor *h, int larb_idx ){ - //M4ULOG("on_larb_power_on(), larb_idx=%d \n", larb_idx); - larb_reg_restore(larb_idx); - - return; -} -// callback before larb clock is disabled -void on_larb_power_off( struct larb_monitor *h, int larb_idx ){ - //M4ULOG("on_larb_power_off(), larb_idx=%d \n", larb_idx); - larb_reg_backup(larb_idx); -} - -static void restSetting( void ){ - M4U_WriteReg32(LARB0_BASE, 0x200, 0x1); //disp_ovl0_port0 - M4U_WriteReg32(LARB0_BASE, 0x204, 0x1); //disp_ovl0_port1 - M4U_WriteReg32(LARB0_BASE, 0x208, 0x1); //disp_rdma0 - M4U_WriteReg32(LARB0_BASE, 0x20c, 0x1); //disp_wdma0 - M4U_WriteReg32(LARB0_BASE, 0x210, 0x1); //mdp_rdma - M4U_WriteReg32(LARB0_BASE, 0x214, 0x1); //mdp_wdma - M4U_WriteReg32(LARB0_BASE, 0x218, 0x1); //mdp_wrot - M4U_WriteReg32(LARB0_BASE, 0x21C, 0x1); //disp_fake - - M4U_WriteReg32(LARB1_BASE, 0x200, 0x1); //hw_vdec_mc_ext - M4U_WriteReg32(LARB1_BASE, 0x204, 0x1); //hw_vdec_pp_ext - M4U_WriteReg32(LARB1_BASE, 0x208, 0x1); //hw_vdec_avc_mv_ext - M4U_WriteReg32(LARB1_BASE, 0x20c, 0x1); //hw_vdec_pred_rd_ext - M4U_WriteReg32(LARB1_BASE, 0x210, 0x1); //hw_vdec_pred_wr_ext - M4U_WriteReg32(LARB1_BASE, 0x214, 0x1); //hw_vdec_vld_ext - M4U_WriteReg32(LARB1_BASE, 0x218, 0x1); //hw_vdec_ppwrap_ext - - M4U_WriteReg32(LARB2_BASE, 0x200, 0x1); //cam_imgo - M4U_WriteReg32(LARB2_BASE, 0x204, 0x1); //cam_img2o - M4U_WriteReg32(LARB2_BASE, 0x208, 0x1); //cam_lsci - M4U_WriteReg32(LARB2_BASE, 0x20c, 0x1); //venc_bsdma - M4U_WriteReg32(LARB2_BASE, 0x210, 0x1); //jpgenc_rdma - M4U_WriteReg32(LARB2_BASE, 0x214, 0x1); //cam_imgi - M4U_WriteReg32(LARB2_BASE, 0x218, 0x1); //cam_esfko - M4U_WriteReg32(LARB2_BASE, 0x21c, 0x1); //cam_aao - M4U_WriteReg32(LARB2_BASE, 0x220, 0x1); //jpgdec_bsdma - M4U_WriteReg32(LARB2_BASE, 0x224, 0x1); //venc_mvqp - M4U_WriteReg32(LARB2_BASE, 0x228, 0x1); //venc_mc - M4U_WriteReg32(LARB2_BASE, 0x22c, 0x1); //venc_cdma - M4U_WriteReg32(LARB2_BASE, 0x230, 0x1); //venc_rec -} -//Make sure clock is on -static void initSetting( void ){ - - /* save default larb regs */ - if( !is_default_value_saved ){ - SMIMSG("Save default config:\n"); - default_val_smi_l1arb[0] = M4U_ReadReg32(SMI_COMMON_EXT_BASE, - REG_OFFSET_SMI_L1ARB0); - default_val_smi_l1arb[1] = M4U_ReadReg32(SMI_COMMON_EXT_BASE, - REG_OFFSET_SMI_L1ARB1); - default_val_smi_l1arb[2] = M4U_ReadReg32(SMI_COMMON_EXT_BASE, - REG_OFFSET_SMI_L1ARB2); - - SMIMSG("l1arb[0-2]= 0x%x, 0x%x, 0x%x\n", default_val_smi_l1arb[0], - default_val_smi_l1arb[1], default_val_smi_l1arb[2]); - - is_default_value_saved = 1; - } - - // Keep the HW's init setting in REG_SMI_L1ARB0 ~ REG_SMI_L1ARB4 - M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB0, - default_val_smi_l1arb[0]); - M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB1, - default_val_smi_l1arb[1]); - M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB2, - default_val_smi_l1arb[2]); - - - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x100, 0xb); - - M4U_WriteReg32( - SMI_COMMON_EXT_BASE, - 0x234, - (0x1 << 31) + (0x1d << 26) + (0x1f << 21) + (0x0 << 20) + (0x3 << 15) - + (0x4 << 10) + (0x4 << 5) + 0x5); - - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x230, (0x7+(0x8<<3)+(0x7<<8))); - - // Set VC priority: MMSYS = ISP > VENC > VDEC = MJC - M4U_WriteReg32(LARB0_BASE, 0x20, 0x0); // MMSYS - M4U_WriteReg32(LARB1_BASE, 0x20, 0x2); // VDEC - M4U_WriteReg32(LARB2_BASE, 0x20, 0x1); // ISP - - - // for UI - restSetting(); - - //LARB 0 DISP+MDP - M4U_WriteReg32(LARB0_BASE, 0x200, 31); //disp_ovl0_port0 - M4U_WriteReg32(LARB0_BASE, 0x204, 31); //disp_ovl0_port1 - M4U_WriteReg32(LARB0_BASE, 0x208, 4); //disp_rdma0 - M4U_WriteReg32(LARB0_BASE, 0x20c, 6); //disp_wdma0 - M4U_WriteReg32(LARB0_BASE, 0x210, 4); //mdp_rdma - M4U_WriteReg32(LARB0_BASE, 0x214, 1); //mdp_wdma - M4U_WriteReg32(LARB0_BASE, 0x218, 1); //mdp_wrot - M4U_WriteReg32(LARB0_BASE, 0x21C, 1); //disp_fake - -} - -static void icfpSetting( void ){ - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x104, 0x11da); //LARB0, DISP+MDP - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x108, 0x1000); //LARB1, VDEC - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x10c, 0x1318); //LARB3, VENC+JPG - - M4U_WriteReg32(LARB0_BASE, 0x200, 0x6); //disp_ovl0_port0 - M4U_WriteReg32(LARB0_BASE, 0x204, 0x6); //disp_ovl0_port1 - M4U_WriteReg32(LARB0_BASE, 0x208, 0x1); //disp_rdma0 - M4U_WriteReg32(LARB0_BASE, 0x20c, 0x1); //disp_wdma0 - M4U_WriteReg32(LARB0_BASE, 0x210, 0x1); //mdp_rdma - M4U_WriteReg32(LARB0_BASE, 0x214, 0x1); //mdp_wdma - M4U_WriteReg32(LARB0_BASE, 0x218, 0x1); //mdp_wrot - M4U_WriteReg32(LARB0_BASE, 0x21C, 0x1); //disp_fake - - - M4U_WriteReg32(LARB2_BASE, 0x200, 0x8); //cam_imgo - M4U_WriteReg32(LARB2_BASE, 0x204, 0x6); //cam_img2o - M4U_WriteReg32(LARB2_BASE, 0x208, 0x1); //cam_lsci - M4U_WriteReg32(LARB2_BASE, 0x20c, 0x1); //venc_bsdma - M4U_WriteReg32(LARB2_BASE, 0x210, 0x2); //jpgenc_rdma - M4U_WriteReg32(LARB2_BASE, 0x214, 0x4); //cam_imgi - M4U_WriteReg32(LARB2_BASE, 0x218, 0x1); //cam_esfko - M4U_WriteReg32(LARB2_BASE, 0x21c, 0x1); //cam_aao - M4U_WriteReg32(LARB2_BASE, 0x220, 0x1); //jpgdec_bsdma - M4U_WriteReg32(LARB2_BASE, 0x224, 0x1); //venc_mvqp - M4U_WriteReg32(LARB2_BASE, 0x228, 0x1); //venc_mc - M4U_WriteReg32(LARB2_BASE, 0x22c, 0x1); //venc_cdma - M4U_WriteReg32(LARB2_BASE, 0x230, 0x1); //venc_rec -} - - - -static void vrSetting( void ){ - - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x104, 0x11ff); //LARB0, DISP+MDP - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x108, 0x1000); //LARB1, VDEC - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x10c, 0x1361); //LARB3, VENC+JPG - - M4U_WriteReg32(LARB0_BASE, 0x200, 0x6); //disp_ovl0_port0 - M4U_WriteReg32(LARB0_BASE, 0x204, 0x6); //disp_ovl0_port1 - M4U_WriteReg32(LARB0_BASE, 0x208, 0x1); //disp_rdma0 - M4U_WriteReg32(LARB0_BASE, 0x20c, 0x1); //disp_wdma0 - M4U_WriteReg32(LARB0_BASE, 0x210, 0x1); //mdp_rdma - M4U_WriteReg32(LARB0_BASE, 0x214, 0x1); //mdp_wdma - M4U_WriteReg32(LARB0_BASE, 0x218, 0x1); //mdp_wrot - M4U_WriteReg32(LARB0_BASE, 0x21C, 0x1); //disp_fake - - - M4U_WriteReg32(LARB2_BASE, 0x200, 0x8); //cam_imgo - M4U_WriteReg32(LARB2_BASE, 0x204, 0x6); //cam_img2o - M4U_WriteReg32(LARB2_BASE, 0x208, 0x1); //cam_lsci - M4U_WriteReg32(LARB2_BASE, 0x20c, 0x1); //venc_bsdma - M4U_WriteReg32(LARB2_BASE, 0x210, 0x1); //jpgenc_rdma - M4U_WriteReg32(LARB2_BASE, 0x214, 0x4); //cam_imgi - M4U_WriteReg32(LARB2_BASE, 0x218, 0x1); //cam_esfko - M4U_WriteReg32(LARB2_BASE, 0x21c, 0x1); //cam_aao - M4U_WriteReg32(LARB2_BASE, 0x220, 0x1); //jpgdec_bsdma - M4U_WriteReg32(LARB2_BASE, 0x224, 0x1); //venc_mvqp - M4U_WriteReg32(LARB2_BASE, 0x228, 0x2); //venc_mc - M4U_WriteReg32(LARB2_BASE, 0x22c, 0x1); //venc_cdma - M4U_WriteReg32(LARB2_BASE, 0x230, 0x1); //venc_rec -} - -static void vpSetting( void ){ - - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x104, 0x11ff); //LARB0, DISP+MDP - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x108, default_val_smi_l1arb[1]); //LARB1, VDEC - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x10c, 0x1361); //LARB3, VENC+JPG - - M4U_WriteReg32(LARB0_BASE, 0x200, 0x8); //disp_ovl0_port0 - M4U_WriteReg32(LARB0_BASE, 0x204, 0x8); //disp_ovl0_port1 - M4U_WriteReg32(LARB0_BASE, 0x208, 0x1); //disp_rdma0 - M4U_WriteReg32(LARB0_BASE, 0x20c, 0x1); //disp_wdma0 - M4U_WriteReg32(LARB0_BASE, 0x210, 0x3); //mdp_rdma - M4U_WriteReg32(LARB0_BASE, 0x214, 0x1); //mdp_wdma - M4U_WriteReg32(LARB0_BASE, 0x218, 0x4); //mdp_wrot - M4U_WriteReg32(LARB0_BASE, 0x21C, 0x1); //disp_fake - - - M4U_WriteReg32(LARB1_BASE, 0x200, 0xb); //hw_vdec_mc_ext - M4U_WriteReg32(LARB1_BASE, 0x204, 0xe); //hw_vdec_pp_ext - M4U_WriteReg32(LARB1_BASE, 0x208, 0x1); //hw_vdec_avc_mv_ext - M4U_WriteReg32(LARB1_BASE, 0x214, 0x1); //hw_vdec_vld_ext - - M4U_WriteReg32(LARB2_BASE, 0x200, 0x8); //cam_imgo - M4U_WriteReg32(LARB2_BASE, 0x204, 0x6); //cam_img2o - M4U_WriteReg32(LARB2_BASE, 0x208, 0x1); //cam_lsci - M4U_WriteReg32(LARB2_BASE, 0x20c, 0x1); //venc_bsdma - M4U_WriteReg32(LARB2_BASE, 0x210, 0x1); //jpgenc_rdma - M4U_WriteReg32(LARB2_BASE, 0x214, 0x4); //cam_imgi - M4U_WriteReg32(LARB2_BASE, 0x218, 0x1); //cam_esfko - M4U_WriteReg32(LARB2_BASE, 0x21c, 0x1); //cam_aao - M4U_WriteReg32(LARB2_BASE, 0x220, 0x1); //jpgdec_bsdma - M4U_WriteReg32(LARB2_BASE, 0x224, 0x1); //venc_mvqp - M4U_WriteReg32(LARB2_BASE, 0x228, 0x2); //venc_mc - M4U_WriteReg32(LARB2_BASE, 0x22c, 0x1); //venc_cdma - M4U_WriteReg32(LARB2_BASE, 0x230, 0x1); //venc_rec -} - - - - -static void vpWfdSetting( void ){ - - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x104, 0x11ff); //LARB0, DISP+MDP - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x108, default_val_smi_l1arb[1]); //LARB1, VDEC - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x10c, 0x1361); //LARB3, VENC+JPG - - M4U_WriteReg32(LARB0_BASE, 0x200, 0x8); //disp_ovl0_port0 - M4U_WriteReg32(LARB0_BASE, 0x204, 0x8); //disp_ovl0_port1 - M4U_WriteReg32(LARB0_BASE, 0x208, 0x1); //disp_rdma0 - M4U_WriteReg32(LARB0_BASE, 0x20c, 0x1); //disp_wdma0 - M4U_WriteReg32(LARB0_BASE, 0x210, 0x3); //mdp_rdma - M4U_WriteReg32(LARB0_BASE, 0x214, 0x1); //mdp_wdma - M4U_WriteReg32(LARB0_BASE, 0x218, 0x4); //mdp_wrot - M4U_WriteReg32(LARB0_BASE, 0x21C, 0x1); //disp_fake - - - M4U_WriteReg32(LARB1_BASE, 0x200, 0xb); //hw_vdec_mc_ext - M4U_WriteReg32(LARB1_BASE, 0x204, 0xe); //hw_vdec_pp_ext - M4U_WriteReg32(LARB1_BASE, 0x208, 0x1); //hw_vdec_avc_mv_ext - M4U_WriteReg32(LARB1_BASE, 0x214, 0x1); //hw_vdec_vld_ext - - M4U_WriteReg32(LARB2_BASE, 0x200, 0x8); //cam_imgo - M4U_WriteReg32(LARB2_BASE, 0x204, 0x6); //cam_img2o - M4U_WriteReg32(LARB2_BASE, 0x208, 0x1); //cam_lsci - M4U_WriteReg32(LARB2_BASE, 0x20c, 0x1); //venc_bsdma - M4U_WriteReg32(LARB2_BASE, 0x210, 0x1); //jpgenc_rdma - M4U_WriteReg32(LARB2_BASE, 0x214, 0x4); //cam_imgi - M4U_WriteReg32(LARB2_BASE, 0x218, 0x1); //cam_esfko - M4U_WriteReg32(LARB2_BASE, 0x21c, 0x1); //cam_aao - M4U_WriteReg32(LARB2_BASE, 0x220, 0x1); //jpgdec_bsdma - M4U_WriteReg32(LARB2_BASE, 0x224, 0x1); //venc_mvqp - M4U_WriteReg32(LARB2_BASE, 0x228, 0x2); //venc_mc - M4U_WriteReg32(LARB2_BASE, 0x22c, 0x1); //venc_cdma - M4U_WriteReg32(LARB2_BASE, 0x230, 0x1); //venc_rec -} - -// Fake mode check, e.g. WFD -static int fake_mode_handling( - MTK_SMI_BWC_CONFIG* p_conf, - unsigned int *pu4LocalCnt ){ - if( p_conf->scenario == SMI_BWC_SCEN_WFD ){ - if( p_conf->b_on_off ){ - wifi_disp_transaction = 1; - SMIMSG("Enable WFD in profile: %d\n", smi_profile); - }else{ - wifi_disp_transaction = 0; - SMIMSG("Disable WFD in profile: %d\n", smi_profile); - } - return 1; - }else{ - return 0; - } -} - -static int ovl_limit_uevent( int bwc_scenario, int ovl_pixel_limit ){ - int err = 0; - char *envp[3]; - char scenario_buf[32] = ""; - char ovl_limit_buf[32] = ""; - - // scenario_buf = kzalloc(sizeof(char)*128, GFP_KERNEL); - // ovl_limit_buf = kzalloc(sizeof(char)*128, GFP_KERNEL); - - snprintf(scenario_buf, 31, "SCEN=%d", bwc_scenario); - snprintf(ovl_limit_buf, 31, "HWOVL=%d", ovl_pixel_limit); - - envp[0] = scenario_buf; - envp[1] = ovl_limit_buf; - envp[2] = NULL; - - if( pSmiDev != NULL ){ - // err = kobject_uevent_env(&(pSmiDev->kobj), KOBJ_CHANGE, envp); - // use smi_dev->dev.lobj instead - // err = kobject_uevent_env(&(smi_dev->dev->kobj), KOBJ_CHANGE, envp); - // user smiDeviceUevent->kobj instead - err = kobject_uevent_env(&(smiDeviceUevent->kobj), KOBJ_CHANGE, envp); - SMIMSG("Notify OVL limitaion=%d, SCEN=%d", ovl_pixel_limit, - bwc_scenario); - } - //kfree(scenario_buf); - //kfree(ovl_limit_buf); - - if(err < 0) - SMIMSG(KERN_INFO "[%s] kobject_uevent_env error = %d\n", __func__, err); - - return err; -} - -static int smi_bwc_config( - MTK_SMI_BWC_CONFIG* p_conf, - unsigned int *pu4LocalCnt ){ - int i; - int result = 0; - unsigned int u4Concurrency = 0; - MTK_SMI_BWC_SCEN eFinalScen; - static MTK_SMI_BWC_SCEN ePreviousFinalScen = SMI_BWC_SCEN_CNT; - - if( smi_tuning_mode == 1 ){ - SMIMSG("Doesn't change profile in tunning mode"); - return 0; - } - //#ifdef SMI_DT_SUPPORT - //register_base_dump(); - //#endif - - spin_lock(&g_SMIInfo.SMI_lock); - result = fake_mode_handling(p_conf, pu4LocalCnt); - spin_unlock(&g_SMIInfo.SMI_lock); - - // Fake mode is not a real SMI profile, so we need to return here - if( result == 1 ){ - return 0; - } - - if( (SMI_BWC_SCEN_CNT <= p_conf->scenario) || (0 > p_conf->scenario) ){ - SMIERR("Incorrect SMI BWC config : 0x%x, how could this be...\n", - p_conf->scenario); - return -1; - } - - //Debug - S - //SMIMSG("SMI setTo%d,%s,%d\n" , p_conf->scenario , (p_conf->b_on_off ? "on" : "off") , ePreviousFinalScen); - //Debug - E - - if (p_conf->b_on_off) { - /* set mmdvfs step according to certain scenarios */ - mmdvfs_notify_scenario_enter(p_conf->scenario); - } else { - /* set mmdvfs step to default after the scenario exits */ - mmdvfs_notify_scenario_exit(p_conf->scenario); - } - - spin_lock(&g_SMIInfo.SMI_lock); - - if( p_conf->b_on_off ){ - //turn on certain scenario - g_SMIInfo.pu4ConcurrencyTable[p_conf->scenario] += 1; - - if( NULL != pu4LocalCnt ){ - pu4LocalCnt[p_conf->scenario] += 1; - } - }else{ - //turn off certain scenario - if( 0 == g_SMIInfo.pu4ConcurrencyTable[p_conf->scenario] ){ - SMIMSG("Too many turning off for global SMI profile:%d,%d\n", - p_conf->scenario, - g_SMIInfo.pu4ConcurrencyTable[p_conf->scenario]); - }else{ - g_SMIInfo.pu4ConcurrencyTable[p_conf->scenario] -= 1; - } - - if( NULL != pu4LocalCnt ){ - if( 0 == pu4LocalCnt[p_conf->scenario] ){ - SMIMSG( - "Process : %s did too many turning off for local SMI profile:%d,%d\n", - current->comm, p_conf->scenario, - pu4LocalCnt[p_conf->scenario]); - }else{ - pu4LocalCnt[p_conf->scenario] -= 1; - } - } - } - - for( i = 0; i < SMI_BWC_SCEN_CNT; i++ ){ - if( g_SMIInfo.pu4ConcurrencyTable[i] ){ - u4Concurrency |= (1 << i); - } - } - - /* notify mmdvfs concurrency */ - mmdvfs_notify_scenario_concurrency(u4Concurrency); - - if( (1 << SMI_BWC_SCEN_MM_GPU) & u4Concurrency ){ - eFinalScen = SMI_BWC_SCEN_MM_GPU; - }else if( (1 << SMI_BWC_SCEN_ICFP) & u4Concurrency ){ - eFinalScen = SMI_BWC_SCEN_ICFP; - }else if( (1 << SMI_BWC_SCEN_VR_SLOW) & u4Concurrency ){ - eFinalScen = SMI_BWC_SCEN_VR_SLOW; - }else if( (1 << SMI_BWC_SCEN_VR) & u4Concurrency ){ - eFinalScen = SMI_BWC_SCEN_VR; - }else if( (1 << SMI_BWC_SCEN_VP) & u4Concurrency ){ - eFinalScen = SMI_BWC_SCEN_VP; - }else if( (1 << SMI_BWC_SCEN_SWDEC_VP) & u4Concurrency ){ - eFinalScen = SMI_BWC_SCEN_SWDEC_VP; - }else if( (1 << SMI_BWC_SCEN_VENC) & u4Concurrency ){ - eFinalScen = SMI_BWC_SCEN_VENC; - }else{ - eFinalScen = SMI_BWC_SCEN_NORMAL; - } - - if( ePreviousFinalScen == eFinalScen ){ - SMIMSG("Scen equal%d,don't change\n", eFinalScen); - spin_unlock(&g_SMIInfo.SMI_lock); - return 0; - }else{ - ePreviousFinalScen = eFinalScen; - } - - /* turn on larb clock */ - for( i = 0; i < SMI_LARB_NR; i++ ){ - larb_clock_on(i); - } - - smi_profile = eFinalScen; - - /* Bandwidth Limiter */ - switch( eFinalScen ){ - case SMI_BWC_SCEN_VP: - SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_VP"); - if( wifi_disp_transaction ){ - vpSetting(); - }else{ - vpWfdSetting(); - } - g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_VP; - break; - - case SMI_BWC_SCEN_SWDEC_VP: - SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_SWDEC_VP"); - vpSetting(); - g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_VP; - break; - - case SMI_BWC_SCEN_ICFP: - SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_ICFP"); - icfpSetting(); - g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_VR; - break; - case SMI_BWC_SCEN_VR: - SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_VR"); - vrSetting(); - g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_VR; - break; - - case SMI_BWC_SCEN_VR_SLOW: - SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_VR"); - smi_profile = SMI_BWC_SCEN_VR_SLOW; - vrSetting(); - g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; - break; - - case SMI_BWC_SCEN_VENC: - SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_VENC"); - vrSetting(); - g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; - break; - - case SMI_BWC_SCEN_NORMAL: - SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_NORMAL"); - g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; - initSetting(); - break; - - case SMI_BWC_SCEN_MM_GPU: - SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_MM_GPU"); - g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; - initSetting(); - break; - - default: - SMIMSG("[SMI_PROFILE] : %s %d\n", "initSetting", eFinalScen); - initSetting(); - g_smi_bwc_mm_info .hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; - break; - } - - - /*turn off larb clock*/ - for( i = 0; i < SMI_LARB_NR; i++ ){ - larb_clock_off(i); - } - - spin_unlock(&g_SMIInfo.SMI_lock); - - ovl_limit_uevent(smi_profile, g_smi_bwc_mm_info.hw_ovl_limit); - - /* force 30 fps in VR slow motion, because disp driver set fps apis got mutex, call these APIs only when necessary */ - { - static unsigned int current_fps = 0; - - if( (eFinalScen == SMI_BWC_SCEN_VR_SLOW) && (current_fps != 30) ){ /* force 30 fps in VR slow motion profile */ - primary_display_force_set_vsync_fps(30); - current_fps = 30; - SMIMSG("[SMI_PROFILE] set 30 fps\n"); - }else if( (eFinalScen != SMI_BWC_SCEN_VR_SLOW) && (current_fps == 30) ){ /* back to normal fps */ - current_fps = primary_display_get_fps(); - primary_display_force_set_vsync_fps(current_fps); - SMIMSG("[SMI_PROFILE] back to %u fps\n", current_fps); - } - } - - SMIMSG("SMI_PROFILE to:%d %s,cur:%d,%d,%d,%d\n", p_conf->scenario, - (p_conf->b_on_off ? "on" : "off"), eFinalScen, - g_SMIInfo.pu4ConcurrencyTable[SMI_BWC_SCEN_NORMAL], - g_SMIInfo.pu4ConcurrencyTable[SMI_BWC_SCEN_VR], - g_SMIInfo.pu4ConcurrencyTable[SMI_BWC_SCEN_VP]); - - //Debug usage - S - //smi_dumpDebugMsg(); - //SMIMSG("Config:%d,%d,%d\n" , eFinalScen , g_SMIInfo.pu4ConcurrencyTable[SMI_BWC_SCEN_NORMAL] , (NULL == pu4LocalCnt ? (-1) : pu4LocalCnt[p_conf->scenario])); - //Debug usage - E - - return 0; -} - -struct larb_monitor larb_monitor_handler = -{ - .level = LARB_MONITOR_LEVEL_HIGH, - .backup = on_larb_power_off, - .restore = on_larb_power_on -}; - -int smi_common_init( void ){ - int i; - - SMIMSG("Enter smi_common_init\n") - for( i = 0; i < SMI_LARB_NR; i++ ){ - pLarbRegBackUp[i] = (unsigned int*) kmalloc(LARB_BACKUP_REG_SIZE, - GFP_KERNEL | __GFP_ZERO); - if( pLarbRegBackUp[i] == NULL ){ - SMIERR("pLarbRegBackUp kmalloc fail %d \n", i); - } - } - - /* - * make sure all larb power is on before we register callback func. - * then, when larb power is first off, default register value will be backed up. - */ - - for( i = 0; i < SMI_LARB_NR; i++ ){ - SMIMSG("Enalbe CLK of larb%d\n", i ); - larb_clock_on(i); - } - - /* apply init setting after kernel boot */ - SMIMSG("Enter smi_common_init\n") - initSetting(); - - register_larb_monitor(&larb_monitor_handler); - - for( i = 0; i < SMI_LARB_NR; i++ ){ - larb_clock_off(i); - } - - return 0; -} - -static int smi_open( struct inode *inode, struct file *file ){ - file->private_data = kmalloc(SMI_BWC_SCEN_CNT * sizeof(unsigned int), - GFP_ATOMIC); - - if( NULL == file->private_data ){ - SMIMSG("Not enough entry for DDP open operation\n"); - return -ENOMEM; - } - - memset(file->private_data, 0, SMI_BWC_SCEN_CNT * sizeof(unsigned int)); - - return 0; -} - -static int smi_release( struct inode *inode, struct file *file ){ - -#if 0 - unsigned long u4Index = 0; - unsigned long u4AssignCnt = 0; - unsigned long * pu4Cnt = (unsigned long *)file->private_data; - MTK_SMI_BWC_CONFIG config; - - for(; u4Index < SMI_BWC_SCEN_CNT; u4Index += 1) - { - if(pu4Cnt[u4Index]) - { - SMIMSG("Process:%s does not turn off BWC properly , force turn off %d\n" , current->comm , u4Index); - u4AssignCnt = pu4Cnt[u4Index]; - config.b_on_off = 0; - config.scenario = (MTK_SMI_BWC_SCEN)u4Index; - do - { - smi_bwc_config( &config , pu4Cnt); - } - while(0 < u4AssignCnt); - } - } -#endif - - if( NULL != file->private_data ){ - kfree(file->private_data); - file->private_data = NULL; - } - - return 0; -} -/* GMP start */ - -void smi_bwc_mm_info_set( int property_id, long val1, long val2 ){ - - switch( property_id ){ - case SMI_BWC_INFO_CON_PROFILE: - g_smi_bwc_mm_info.concurrent_profile = (int) val1; - break; - case SMI_BWC_INFO_SENSOR_SIZE: - g_smi_bwc_mm_info.sensor_size[0] = val1; - g_smi_bwc_mm_info.sensor_size[1] = val2; - break; - case SMI_BWC_INFO_VIDEO_RECORD_SIZE: - g_smi_bwc_mm_info.video_record_size[0] = val1; - g_smi_bwc_mm_info.video_record_size[1] = val2; - break; - case SMI_BWC_INFO_DISP_SIZE: - g_smi_bwc_mm_info.display_size[0] = val1; - g_smi_bwc_mm_info.display_size[1] = val2; - break; - case SMI_BWC_INFO_TV_OUT_SIZE: - g_smi_bwc_mm_info.tv_out_size[0] = val1; - g_smi_bwc_mm_info.tv_out_size[1] = val2; - break; - case SMI_BWC_INFO_FPS: - g_smi_bwc_mm_info.fps = (int) val1; - break; - case SMI_BWC_INFO_VIDEO_ENCODE_CODEC: - g_smi_bwc_mm_info.video_encode_codec = (int) val1; - break; - case SMI_BWC_INFO_VIDEO_DECODE_CODEC: - g_smi_bwc_mm_info.video_decode_codec = (int) val1; - break; - } -} - -/* GMP end */ - -static long smi_ioctl( - struct file * pFile, - unsigned int cmd, - unsigned long param ){ - int ret = 0; - - // unsigned long * pu4Cnt = (unsigned long *)pFile->private_data; - - switch( cmd ){ - - /* disable reg access ioctl by default for possible security holes */ - // TBD: check valid SMI register range - case MTK_IOC_SMI_BWC_CONFIG: { - MTK_SMI_BWC_CONFIG cfg; - ret = copy_from_user(&cfg, (void*) param, - sizeof(MTK_SMI_BWC_CONFIG)); - if( ret ){ - SMIMSG(" SMI_BWC_CONFIG, copy_from_user failed: %d\n", ret); - return -EFAULT; - } - - ret = smi_bwc_config(&cfg, NULL); - - break; - } - /* GMP start */ - case MTK_IOC_SMI_BWC_INFO_SET: { - MTK_SMI_BWC_INFO_SET cfg; - //SMIMSG("Handle MTK_IOC_SMI_BWC_INFO_SET request... start"); - ret = copy_from_user(&cfg, (void *) param, - sizeof(MTK_SMI_BWC_INFO_SET)); - if( ret ){ - SMIMSG(" MTK_IOC_SMI_BWC_INFO_SET, copy_to_user failed: %d\n", - ret); - return -EFAULT; - } - /* Set the address to the value assigned by user space program */ - smi_bwc_mm_info_set(cfg.property, cfg.value1, cfg.value2); - //SMIMSG("Handle MTK_IOC_SMI_BWC_INFO_SET request... finish"); - break; - } - case MTK_IOC_SMI_BWC_INFO_GET: { - ret = copy_to_user((void *) param, (void *) &g_smi_bwc_mm_info, - sizeof(MTK_SMI_BWC_MM_INFO)); - - if( ret ){ - SMIMSG(" MTK_IOC_SMI_BWC_INFO_GET, copy_to_user failed: %d\n", - ret); - return -EFAULT; - } - //SMIMSG("Handle MTK_IOC_SMI_BWC_INFO_GET request... finish"); - break; - } - /* GMP end */ - - case MTK_IOC_SMI_DUMP_LARB: { - unsigned int larb_index; - - ret = copy_from_user(&larb_index, (void*) param, - sizeof(unsigned int)); - if( ret ){ - return -EFAULT; - } - - smi_dumpLarb(larb_index); - } - break; - - case MTK_IOC_SMI_DUMP_COMMON: { - unsigned int arg; - - ret = copy_from_user(&arg, (void*) param, sizeof(unsigned int)); - if( ret ){ - return -EFAULT; - } - - smi_dumpCommon(); - } - break; - - case MTK_IOC_MMDVFS_CMD: - { - MTK_MMDVFS_CMD mmdvfs_cmd; - - if (copy_from_user(&mmdvfs_cmd, (void*)param, sizeof(MTK_MMDVFS_CMD))) { - return -EFAULT; - } - - mmdvfs_handle_cmd(&mmdvfs_cmd); - - if (copy_to_user((void*)param, (void*)&mmdvfs_cmd, sizeof(MTK_MMDVFS_CMD))) { - return -EFAULT; - } - } - break; - - default: - return -1; - } - - return ret; -} - -static const struct file_operations smiFops = -{ - .owner = THIS_MODULE, - .open = smi_open, - .release = smi_release, - .unlocked_ioctl = smi_ioctl, - .compat_ioctl = MTK_SMI_COMPAT_ioctl, -}; - -static dev_t smiDevNo = MKDEV(MTK_SMI_MAJOR_NUMBER, 0); -static inline int smi_register( void ){ - if( alloc_chrdev_region(&smiDevNo, 0, 1, "MTK_SMI") ){ - SMIERR("Allocate device No. failed"); - return -EAGAIN; - } - //Allocate driver - pSmiDev = cdev_alloc(); - - if( NULL == pSmiDev ){ - unregister_chrdev_region(smiDevNo, 1); - SMIERR("Allocate mem for kobject failed"); - return -ENOMEM; - } - - //Attatch file operation. - cdev_init(pSmiDev, &smiFops); - pSmiDev->owner = THIS_MODULE; - - //Add to system - if( cdev_add(pSmiDev, smiDevNo, 1) ){ - SMIERR("Attatch file operation failed"); - unregister_chrdev_region(smiDevNo, 1); - return -EAGAIN; - } - - return 0; -} - -static struct class *pSmiClass = NULL; - -static int smi_probe( struct platform_device *pdev ){ - - int i; - - static unsigned int smi_probe_cnt = 0; - struct device* smiDevice = NULL; - SMIMSG("Enter smi_probe\n"); - //Debug only - if( smi_probe_cnt != 0 ){ - SMIERR("Onlye support 1 SMI driver probed\n"); - return 0; - } - smi_probe_cnt++; - SMIMSG("Allocate smi_dev space\n"); - smi_dev = krealloc(smi_dev, sizeof(struct smi_device), GFP_KERNEL); - - if( smi_dev == NULL ){ - SMIERR("Unable to allocate memory for smi driver\n"); - return -ENOMEM; - } - if( NULL == pdev ){ - SMIERR("platform data missed\n"); - return -ENXIO; - } - // Keep the device structure - smi_dev->dev = &pdev->dev; - - // Map registers - for( i = 0; i < SMI_REG_REGION_MAX; i++ ){ - SMIMSG("Save region: %d\n", i); - smi_dev->regs[i] = (void *) of_iomap(pdev->dev.of_node, i); - - if( !smi_dev->regs[i] ){ - SMIERR("Unable to ioremap registers, of_iomap fail, i=%d \n", i); - return -ENOMEM; - } - - // Record the register base in global variable - gSMIBaseAddrs[i] = (unsigned long) (smi_dev->regs[i]); - SMIMSG("DT, i=%d, region=%s, map_addr=0x%p, reg_pa=0x%lx\n", i, - smi_get_region_name(i), smi_dev->regs[i], smi_reg_pa_base[i]); - } - - SMIMSG("Execute smi_register\n"); - if( smi_register() ){ - dev_err(&pdev->dev, "register char failed\n"); - return -EAGAIN; - } - - pSmiClass = class_create(THIS_MODULE, "MTK_SMI"); - if(IS_ERR(pSmiClass)) { - int ret = PTR_ERR(pSmiClass); - SMIERR("Unable to create class, err = %d", ret); - return ret; - } - SMIMSG("Create davice\n"); - smiDevice = device_create(pSmiClass, NULL, smiDevNo, NULL, "MTK_SMI"); - smiDeviceUevent = smiDevice; - - SMIMSG("SMI probe done.\n"); - - // To adapt the legacy codes - smi_reg_base_common_ext = gSMIBaseAddrs[SMI_COMMON_REG_INDX]; - smi_reg_base_barb0 = gSMIBaseAddrs[SMI_LARB0_REG_INDX]; - smi_reg_base_barb1 = gSMIBaseAddrs[SMI_LARB1_REG_INDX]; - smi_reg_base_barb2 = gSMIBaseAddrs[SMI_LARB2_REG_INDX]; - //smi_reg_base_barb4 = gSMIBaseAddrs[SMI_LARB4_REG_INDX]; - - gLarbBaseAddr[0] = LARB0_BASE; - gLarbBaseAddr[1] = LARB1_BASE; - gLarbBaseAddr[2] = LARB2_BASE; - - SMIMSG("Execute smi_common_init\n"); - smi_common_init(); - - SMIMSG("Execute SMI_DBG_Init\n"); - SMI_DBG_Init(); - return 0; - -} - -char* smi_get_region_name( unsigned int region_indx ){ - switch( region_indx ){ - case SMI_COMMON_REG_INDX: - return "smi_common"; - case SMI_LARB0_REG_INDX: - return "larb0"; - case SMI_LARB1_REG_INDX: - return "larb1"; - case SMI_LARB2_REG_INDX: - return "larb2"; - default: - SMIMSG("invalid region id=%d", region_indx); - return "unknown"; - } -} - -void register_base_dump( void ){ - int i = 0; - unsigned long pa_value = 0; - unsigned long va_value = 0; - - for( i = 0; i < SMI_REG_REGION_MAX; i++ ){ - va_value = gSMIBaseAddrs[i]; - pa_value = virt_to_phys((void*) va_value); - SMIMSG("REG BASE:%s-->VA=0x%lx,PA=0x%lx,SPEC=0x%lx\n", - smi_get_region_name(i), va_value, pa_value, smi_reg_pa_base[i]); - } -} - -static int smi_remove( struct platform_device *pdev ){ - cdev_del(pSmiDev); - unregister_chrdev_region(smiDevNo, 1); - device_destroy(pSmiClass, smiDevNo); - class_destroy( pSmiClass); - return 0; -} - -static int smi_suspend( struct platform_device *pdev, pm_message_t mesg ){ - return 0; -} - -static int smi_resume( struct platform_device *pdev ){ - return 0; -} - -#ifdef SMI_DT_SUPPORT -static const struct of_device_id smi_of_ids[] ={ - { .compatible = "mediatek,SMI_COMMON",}, - {} -}; -#endif //SMI_DT_SUPPORT -static struct platform_driver smiDrv ={ - .probe = smi_probe, - .remove = smi_remove, - .suspend= smi_suspend, - .resume = smi_resume, - .driver ={ - .name = "MTK_SMI", - .owner = THIS_MODULE, -#ifdef SMI_DT_SUPPORT - .of_match_table = smi_of_ids, -#endif //SMI_DT_SUPPORT - } -}; - -static int __init smi_init(void) -{ - SMIMSG("smi_init enter\n"); - spin_lock_init(&g_SMIInfo.SMI_lock); - /* MMDVFS init */ - mmdvfs_init(&g_smi_bwc_mm_info); - - memset(g_SMIInfo.pu4ConcurrencyTable , 0 , SMI_BWC_SCEN_CNT * sizeof(unsigned int)); - - // Informs the kernel about the function to be called - // if hardware matching MTK_SMI has been found - SMIMSG("register platform driver\n"); - if (platform_driver_register(&smiDrv)){ - SMIERR("failed to register MAU driver"); - return -ENODEV; - } - SMIMSG("exit smi_init\n"); - return 0; -} - -static void __exit smi_exit(void) -{ - platform_driver_unregister(&smiDrv); - -} - -static void smi_dumpCommonDebugMsg( int output_gce_buffer ){ - unsigned long u4Base; - int smiCommonClkEnabled = 0; - - smiCommonClkEnabled = clock_is_on(MT_CG_DISP0_SMI_COMMON); - //SMI COMMON dump - if( smi_debug_level == 0 && (!smiCommonClkEnabled) ){ - SMIMSG3(output_gce_buffer, "===SMI common clock is disabled===\n"); - return; - } - - SMIMSG3(output_gce_buffer, "===SMI common reg dump, CLK: %d===\n", smiCommonClkEnabled); - - u4Base = SMI_COMMON_EXT_BASE; - SMIMSG3(output_gce_buffer, "[0x100,0x104,0x108]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x100), M4U_ReadReg32(u4Base, 0x104), - M4U_ReadReg32(u4Base, 0x108)); - SMIMSG3(output_gce_buffer, "[0x10C,0x110,0x114]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x10C), M4U_ReadReg32(u4Base, 0x110), - M4U_ReadReg32(u4Base, 0x114)); - SMIMSG3(output_gce_buffer, "[0x220,0x230,0x234,0x238]=[0x%x,0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x220), M4U_ReadReg32(u4Base, 0x230), - M4U_ReadReg32(u4Base, 0x234), M4U_ReadReg32(u4Base, 0x238)); - SMIMSG3(output_gce_buffer, "[0x400,0x404,0x408]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x400), M4U_ReadReg32(u4Base, 0x404), - M4U_ReadReg32(u4Base, 0x408)); - SMIMSG3(output_gce_buffer, "[0x40C,0x430,0x440]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x40C), M4U_ReadReg32(u4Base, 0x430), - M4U_ReadReg32(u4Base, 0x440)); - - // TBD: M4U should dump these - /* - // For VA and PA check: - // 0x1000C5C0 , 0x1000C5C4, 0x1000C5C8, 0x1000C5CC, 0x1000C5D0 - u4Base = SMI_COMMON_AO_BASE; - SMIMSG("===SMI always on reg dump===\n"); - SMIMSG("[0x5C0,0x5C4,0x5C8]=[0x%x,0x%x,0x%x]\n" ,M4U_ReadReg32(u4Base , 0x5C0),M4U_ReadReg32(u4Base , 0x5C4),M4U_ReadReg32(u4Base , 0x5C8)); - SMIMSG("[0x5CC,0x5D0]=[0x%x,0x%x]\n" ,M4U_ReadReg32(u4Base , 0x5CC),M4U_ReadReg32(u4Base , 0x5D0)); - */ -} -static int smi_larb_clock_is_on( unsigned int larb_index ){ - - int result = 0; -#if !defined (CONFIG_MTK_FPGA) && !defined (CONFIG_FPGA_EARLY_PORTING) - switch( larb_index ){ - case 0: - result = clock_is_on(MT_CG_DISP0_SMI_LARB0); - break; - case 1: - result = clock_is_on(MT_CG_VDEC1_LARB); - break; - case 2: - result = clock_is_on(MT_CG_IMAGE_LARB2_SMI); - break; -// case 3: -// result = clock_is_on(MT_CG_VENC_LARB); -// break; -// case 4: -// result = clock_is_on(MT_CG_MJC_SMI_LARB); -// break; - default: - result = 0; - break; - } -#endif // !defined (CONFIG_MTK_FPGA) && !defined (CONFIG_FPGA_EARLY_PORTING) - return result; - -} -static void smi_dumpLarbDebugMsg( unsigned int u4Index ){ - unsigned long u4Base = 0; - - int larbClkEnabled = 0; - - u4Base = get_larb_base_addr(u4Index); - - larbClkEnabled = smi_larb_clock_is_on(u4Index); - - if( u4Base == SMI_ERROR_ADDR ){ - SMIMSG("Doesn't support reg dump for Larb%d\n", u4Index); - - return; - }else if( (larbClkEnabled != 0) || smi_debug_level > 0 ){ - SMIMSG("===SMI LARB%d reg dump, CLK: %d===\n", u4Index, larbClkEnabled); - - // Staus Registers - SMIMSG("[0x0,0x8,0x10]=[0x%x,0x%x,0x%x]\n", M4U_ReadReg32(u4Base, 0x0), - M4U_ReadReg32(u4Base, 0x8), M4U_ReadReg32(u4Base, 0x10)); - SMIMSG("[0x24,0x50,0x60]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x24), M4U_ReadReg32(u4Base, 0x50), - M4U_ReadReg32(u4Base, 0x60)); - SMIMSG("[0xa0,0xa4,0xa8]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0xa0), M4U_ReadReg32(u4Base, 0xa4), - M4U_ReadReg32(u4Base, 0xa8)); - SMIMSG("[0xac,0xb0,0xb4]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0xac), M4U_ReadReg32(u4Base, 0xb0), - M4U_ReadReg32(u4Base, 0xb4)); - SMIMSG("[0xb8,0xbc,0xc0]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0xb8), M4U_ReadReg32(u4Base, 0xbc), - M4U_ReadReg32(u4Base, 0xc0)); - SMIMSG("[0xc8,0xcc]=[0x%x,0x%x]\n", M4U_ReadReg32(u4Base, 0xc8), - M4U_ReadReg32(u4Base, 0xcc)); - // Settings - SMIMSG("[0x200, 0x204, 0x208]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x200), M4U_ReadReg32(u4Base, 0x204), - M4U_ReadReg32(u4Base, 0x208)); - - SMIMSG("[0x20c, 0x210, 0x214]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x20c), M4U_ReadReg32(u4Base, 0x210), - M4U_ReadReg32(u4Base, 0x214)); - - SMIMSG("[0x218, 0x21c, 0x220]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x218), M4U_ReadReg32(u4Base, 0x21c), - M4U_ReadReg32(u4Base, 0x220)); - - SMIMSG("[0x224, 0x228, 0x22c]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x224), M4U_ReadReg32(u4Base, 0x228), - M4U_ReadReg32(u4Base, 0x22c)); - - SMIMSG("[0x230, 0x234, 0x238]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x230), M4U_ReadReg32(u4Base, 0x234), - M4U_ReadReg32(u4Base, 0x238)); - - SMIMSG("[0x23c, 0x240, 0x244]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x23c), M4U_ReadReg32(u4Base, 0x240), - M4U_ReadReg32(u4Base, 0x244)); - - SMIMSG("[0x248, 0x24c]=[0x%x,0x%x]\n", M4U_ReadReg32(u4Base, 0x248), - M4U_ReadReg32(u4Base, 0x24c)); - }else{ - SMIMSG("===SMI LARB%d clock is disabled===\n", u4Index); - } - -} - -static void smi_dump_format( - unsigned long base, - unsigned int from, - unsigned int to ){ - int i, j, left; - unsigned int value[8]; - - for( i = from; i <= to; i += 32 ){ - for( j = 0; j < 8; j++ ){ - value[j] = M4U_ReadReg32(base, i + j * 4); - } - - SMIMSG2("%8x %x %x %x %x %x %x %x %x\n", i, value[0], value[1], - value[2], value[3], value[4], value[5], value[6], value[7]); - } - - left = ((from - to) / 4 + 1) % 8; - - if( left ){ - memset(value, 0, 8 * sizeof(unsigned int)); - - for( j = 0; j < left; j++ ){ - value[j] = M4U_ReadReg32(base, i - 32 + j * 4); - } - - SMIMSG2("%8x %x %x %x %x %x %x %x %x\n", i - 32 + j * 4, value[0], - value[1], value[2], value[3], value[4], value[5], value[6], - value[7]); - } -} - -static void smi_dumpLarb( unsigned int index ){ - unsigned long u4Base; - - u4Base = get_larb_base_addr(index); - - if( u4Base == SMI_ERROR_ADDR ){ - SMIMSG2("Doesn't support reg dump for Larb%d\n", index); - - return; - }else{ - SMIMSG2("===SMI LARB%d reg dump base 0x%lx===\n", index, u4Base); - - smi_dump_format(u4Base, 0, 0x434); - smi_dump_format(u4Base, 0xF00, 0xF0C); - } -} - -static void smi_dumpCommon( void ){ - SMIMSG2("===SMI COMMON reg dump base 0x%lx===\n", SMI_COMMON_EXT_BASE); - - smi_dump_format(SMI_COMMON_EXT_BASE, 0x1A0, 0x444); -} - -void smi_dumpDebugMsg( void ){ - unsigned int u4Index; - - // SMI COMMON dump, 0 stands for not pass log to CMDQ error dumping messages - smi_dumpCommonDebugMsg(0); - - // dump all SMI LARB - for( u4Index = 0; u4Index < SMI_LARB_NR; u4Index++ ){ - smi_dumpLarbDebugMsg(u4Index); - } -} - - -int smi_debug_bus_hanging_detect( unsigned int larbs, int show_dump){ - return smi_debug_bus_hanging_detect_ext(larbs, show_dump, 0); -} - -//dual_buffer = 1, write log into kernel log and CMDQ buffer. dual_buffer = 0, write log into kernel log only -int smi_debug_bus_hanging_detect_ext( unsigned int larbs, int show_dump, int output_gce_buffer){ - - int i = 0; - int dump_time = 0; - int is_smi_issue = 0; - int status_code = 0; - // Keep the dump result - unsigned char smi_common_busy_count = 0; - volatile unsigned int reg_temp = 0; - unsigned char smi_larb_busy_count[SMI_LARB_NR] = { 0 }; - unsigned char smi_larb_mmu_status[SMI_LARB_NR] = { 0 }; - - // dump resister and save resgister status - for( dump_time = 0; dump_time < 5; dump_time++ ){ - unsigned int u4Index = 0; - reg_temp = M4U_ReadReg32(SMI_COMMON_EXT_BASE, 0x440); - if( (reg_temp & (1 << 0)) == 0 ){ - // smi common is busy - smi_common_busy_count++; - } - // Dump smi common regs - if( show_dump != 0 ){ - smi_dumpCommonDebugMsg(output_gce_buffer); - } - for( u4Index = 0; u4Index < SMI_LARB_NR; u4Index++ ){ - unsigned long u4Base = get_larb_base_addr(u4Index); - if( u4Base != SMI_ERROR_ADDR ){ - reg_temp = M4U_ReadReg32(u4Base, 0x0); - if( reg_temp != 0 ){ - // Larb is busy - smi_larb_busy_count[u4Index]++; - } - smi_larb_mmu_status[u4Index] = M4U_ReadReg32(u4Base, 0xa0); - if( show_dump != 0 ){ - smi_dumpLarbDebugMsg(u4Index); - } - } - } - - } - - // Show the checked result - for( i = 0; i < SMI_LARB_NR; i++ ){ // Check each larb - if( SMI_DGB_LARB_SELECT(larbs, i) ){ - // larb i has been selected - // Get status code - - if( smi_larb_busy_count[i] == 5 ){ // The larb is always busy - if( smi_common_busy_count == 5 ){ // smi common is always busy - status_code = 1; - }else if( smi_common_busy_count == 0 ){ // smi common is always idle - status_code = 2; - }else{ - status_code = 5; // smi common is sometimes busy and idle - } - }else if( smi_larb_busy_count[i] == 0 ){ // The larb is always idle - if( smi_common_busy_count == 5 ){ // smi common is always busy - status_code = 3; - }else if( smi_common_busy_count == 0 ){ // smi common is always idle - status_code = 4; - }else{ - status_code = 6; // smi common is sometimes busy and idle - } - }else{ //sometime the larb is busy - if( smi_common_busy_count == 5 ){ // smi common is always busy - status_code = 7; - }else if( smi_common_busy_count == 0 ){ // smi common is always idle - status_code = 8; - }else{ - status_code = 9; // smi common is sometimes busy and idle - } - } - - // Send the debug message according to the final result - switch( status_code ){ - case 1: - case 3: - case 5: - case 7: - case 8: - SMIMSG3( - output_gce_buffer, - "Larb%d Busy=%d/5, SMI Common Busy=%d/5, status=%d ==> Check engine's state first\n", - i, smi_larb_busy_count[i], smi_common_busy_count, - status_code); - SMIMSG3( - output_gce_buffer, - "If the engine is waiting for Larb%ds' response, it needs SMI HW's check\n", - i); - break; - case 2: - if( smi_larb_mmu_status[i] == 0 ){ - SMIMSG3( - output_gce_buffer, - "Larb%d Busy=%d/5, SMI Common Busy=%d/5, status=%d ==> Check engine state first\n", - i, smi_larb_busy_count[i], smi_common_busy_count, - status_code); - SMIMSG3( - output_gce_buffer, - "If the engine is waiting for Larb%ds' response, it needs SMI HW's check\n", - i); - }else{ - SMIMSG3( - output_gce_buffer, - "Larb%d Busy=%d/5, SMI Common Busy=%d/5, status=%d ==> MMU port config error\n", - i, smi_larb_busy_count[i], smi_common_busy_count, - status_code); - is_smi_issue = 1; - } - break; - case 4: - case 6: - case 9: - SMIMSG3( - output_gce_buffer, - "Larb%d Busy=%d/5, SMI Common Busy=%d/5, status=%d ==> not SMI issue\n", - i, smi_larb_busy_count[i], smi_common_busy_count, - status_code); - break; - default: - SMIMSG3( - output_gce_buffer, - "Larb%d Busy=%d/5, SMI Common Busy=%d/5, status=%d ==> status unknown\n", - i, smi_larb_busy_count[i], smi_common_busy_count, - status_code); - break; - } - } - - } - - return is_smi_issue; -} - - -void smi_client_status_change_notify( int module, int mode ){ - -} - -#if IS_ENABLED(CONFIG_COMPAT) -// 32 bits process ioctl support: -// This is prepared for the future extension since currently the sizes of 32 bits -// and 64 bits smi parameters are the same. - -typedef struct -{ - compat_int_t scenario; - compat_int_t b_on_off; //0 : exit this scenario , 1 : enter this scenario -}MTK_SMI_COMPAT_BWC_CONFIG; - -typedef struct -{ - compat_int_t property; - compat_int_t value1; - compat_int_t value2; -}MTK_SMI_COMPAT_BWC_INFO_SET; - -typedef struct -{ - compat_uint_t flag; // Reserved - compat_int_t concurrent_profile; - compat_int_t sensor_size[2]; - compat_int_t video_record_size[2]; - compat_int_t display_size[2]; - compat_int_t tv_out_size[2]; - compat_int_t fps; - compat_int_t video_encode_codec; - compat_int_t video_decode_codec; - compat_int_t hw_ovl_limit; -}MTK_SMI_COMPAT_BWC_MM_INFO; - -#define COMPAT_MTK_IOC_SMI_BWC_CONFIG MTK_IOW(24, MTK_SMI_COMPAT_BWC_CONFIG) -#define COMPAT_MTK_IOC_SMI_BWC_INFO_SET MTK_IOWR(28, MTK_SMI_COMPAT_BWC_INFO_SET) -#define COMPAT_MTK_IOC_SMI_BWC_INFO_GET MTK_IOWR(29, MTK_SMI_COMPAT_BWC_MM_INFO) - -static int compat_get_smi_bwc_config_struct( - MTK_SMI_COMPAT_BWC_CONFIG __user *data32, - MTK_SMI_BWC_CONFIG __user *data){ - - compat_int_t i; - int err; - - // since the int sizes of 32 A32 and A64 are equal so we don't convert them actually here - err = get_user(i, &(data32->scenario)); - err |= put_user(i, &(data->scenario)); - err |= get_user(i, &(data32->b_on_off)); - err |= put_user(i, &(data->b_on_off)); - - return err; -} - -static int compat_get_smi_bwc_mm_info_set_struct( - MTK_SMI_COMPAT_BWC_INFO_SET __user *data32, - MTK_SMI_BWC_INFO_SET __user *data){ - - compat_int_t i; - int err; - - // since the int sizes of 32 A32 and A64 are equal so we don't convert them actually here - err = get_user(i, &(data32->property)); - err |= put_user(i, &(data->property)); - err |= get_user(i, &(data32->value1)); - err |= put_user(i, &(data->value1)); - err |= get_user(i, &(data32->value2)); - err |= put_user(i, &(data->value2)); - - return err; -} - -static int compat_get_smi_bwc_mm_info_struct( - MTK_SMI_COMPAT_BWC_MM_INFO __user *data32, - MTK_SMI_BWC_MM_INFO __user *data) -{ - compat_uint_t u; - compat_int_t i; - compat_int_t p[2]; - int err; - - // since the int sizes of 32 A32 and A64 are equal so we don't convert them actually here - err = get_user(u, &(data32->flag)); - err |= put_user(u, &(data->flag)); - err |= get_user(i, &(data32->concurrent_profile)); - err |= put_user(i, &(data->concurrent_profile)); - err |= copy_from_user(p, &(data32->sensor_size),sizeof(p)); - err |= copy_to_user(&(data->sensor_size),p ,sizeof(p)); - err |= copy_from_user(p, &(data32->video_record_size),sizeof(p)); - err |= copy_to_user(&(data->video_record_size),p ,sizeof(p)); - err |= copy_from_user(p, &(data32->display_size),sizeof(p)); - err |= copy_to_user(&(data->display_size),p ,sizeof(p)); - err |= copy_from_user(p, &(data32->tv_out_size),sizeof(p)); - err |= copy_to_user(&(data->tv_out_size),p ,sizeof(p)); - err |= get_user(i, &(data32->fps)); - err |= put_user(i, &(data->fps)); - err |= get_user(i, &(data32->video_encode_codec)); - err |= put_user(i, &(data->video_encode_codec)); - err |= get_user(i, &(data32->video_decode_codec)); - err |= put_user(i, &(data->video_decode_codec)); - err |= get_user(i, &(data32->hw_ovl_limit)); - err |= put_user(i, &(data->hw_ovl_limit)); - - - return err; -} - -static int compat_put_smi_bwc_mm_info_struct( - MTK_SMI_COMPAT_BWC_MM_INFO __user *data32, - MTK_SMI_BWC_MM_INFO __user *data) -{ - - compat_uint_t u; - compat_int_t i; - compat_int_t p[2]; - int err; - - // since the int sizes of 32 A32 and A64 are equal so we don't convert them actually here - err = get_user(u, &(data->flag)); - err |= put_user(u, &(data32->flag)); - err |= get_user(i, &(data->concurrent_profile)); - err |= put_user(i, &(data32->concurrent_profile)); - err |= copy_from_user(p, &(data->sensor_size),sizeof(p)); - err |= copy_to_user(&(data32->sensor_size),p ,sizeof(p)); - err |= copy_from_user(p, &(data->video_record_size),sizeof(p)); - err |= copy_to_user(&(data32->video_record_size),p ,sizeof(p)); - err |= copy_from_user(p, &(data->display_size),sizeof(p)); - err |= copy_to_user(&(data32->display_size),p ,sizeof(p)); - err |= copy_from_user(p, &(data->tv_out_size),sizeof(p)); - err |= copy_to_user(&(data32->tv_out_size),p ,sizeof(p)); - err |= get_user(i, &(data->fps)); - err |= put_user(i, &(data32->fps)); - err |= get_user(i, &(data->video_encode_codec)); - err |= put_user(i, &(data32->video_encode_codec)); - err |= get_user(i, &(data->video_decode_codec)); - err |= put_user(i, &(data32->video_decode_codec)); - err |= get_user(i, &(data->hw_ovl_limit)); - err |= put_user(i, &(data32->hw_ovl_limit)); - return err; -} - -long MTK_SMI_COMPAT_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - long ret; - - if (!filp->f_op || !filp->f_op->unlocked_ioctl) - return -ENOTTY; - - switch (cmd){ - case COMPAT_MTK_IOC_SMI_BWC_CONFIG: - { - if(COMPAT_MTK_IOC_SMI_BWC_CONFIG == MTK_IOC_SMI_BWC_CONFIG) - { - SMIMSG("Optimized compct IOCTL: COMPAT_MTK_IOC_SMI_BWC_CONFIG"); - return filp->f_op->unlocked_ioctl(filp, cmd,(unsigned long)compat_ptr(arg)); - } else{ - - MTK_SMI_COMPAT_BWC_CONFIG __user *data32; - MTK_SMI_BWC_CONFIG __user *data; - int err; - - data32 = compat_ptr(arg); - data = compat_alloc_user_space(sizeof(MTK_SMI_BWC_CONFIG)); - - if (data == NULL) - return -EFAULT; - - err = compat_get_smi_bwc_config_struct(data32, data); - if (err) - return err; - - ret = filp->f_op->unlocked_ioctl(filp, MTK_IOC_SMI_BWC_CONFIG, - (unsigned long)data); - return ret; - } - } - - case COMPAT_MTK_IOC_SMI_BWC_INFO_SET: - { - - if(COMPAT_MTK_IOC_SMI_BWC_INFO_SET == MTK_IOC_SMI_BWC_INFO_SET) - { - SMIMSG("Optimized compct IOCTL: COMPAT_MTK_IOC_SMI_BWC_INFO_SET"); - return filp->f_op->unlocked_ioctl(filp, cmd,(unsigned long)compat_ptr(arg)); - } else{ - - MTK_SMI_COMPAT_BWC_INFO_SET __user *data32; - MTK_SMI_BWC_INFO_SET __user *data; - int err; - - data32 = compat_ptr(arg); - data = compat_alloc_user_space(sizeof(MTK_SMI_BWC_INFO_SET)); - if (data == NULL) - return -EFAULT; - - err = compat_get_smi_bwc_mm_info_set_struct(data32, data); - if (err) - return err; - - return filp->f_op->unlocked_ioctl(filp, MTK_IOC_SMI_BWC_INFO_SET, - (unsigned long)data); - } - } - - case COMPAT_MTK_IOC_SMI_BWC_INFO_GET: - { - - if(COMPAT_MTK_IOC_SMI_BWC_INFO_GET == MTK_IOC_SMI_BWC_INFO_GET){ - SMIMSG("Optimized compct IOCTL: COMPAT_MTK_IOC_SMI_BWC_INFO_GET"); - return filp->f_op->unlocked_ioctl(filp, cmd,(unsigned long)compat_ptr(arg)); - } else{ - MTK_SMI_COMPAT_BWC_MM_INFO __user *data32; - MTK_SMI_BWC_MM_INFO __user *data; - int err; - - data32 = compat_ptr(arg); - data = compat_alloc_user_space(sizeof(MTK_SMI_BWC_MM_INFO)); - - if (data == NULL) - return -EFAULT; - - err = compat_get_smi_bwc_mm_info_struct(data32, data); - if (err) - return err; - - ret = filp->f_op->unlocked_ioctl(filp, MTK_IOC_SMI_BWC_INFO_GET, - (unsigned long)data); - - err = compat_put_smi_bwc_mm_info_struct(data32, data); - - if (err) - return err; - - return ret; - } - } - - case MTK_IOC_SMI_DUMP_LARB: - case MTK_IOC_SMI_DUMP_COMMON: - case MTK_IOC_MMDVFS_CMD: - - return filp->f_op->unlocked_ioctl(filp, cmd, - (unsigned long)compat_ptr(arg)); - default: - return -ENOIOCTLCMD; - } - -} - -#endif - -module_init( smi_init); -module_exit( smi_exit); - -module_param_named(debug_level, smi_debug_level, uint, S_IRUGO | S_IWUSR); -module_param_named(tuning_mode, smi_tuning_mode, uint, S_IRUGO | S_IWUSR); -module_param_named(wifi_disp_transaction, wifi_disp_transaction, uint, S_IRUGO | S_IWUSR); - -MODULE_DESCRIPTION("MTK SMI driver"); -MODULE_AUTHOR("Frederic Chen<frederic.chen@mediatek.com>"); -MODULE_LICENSE("GPL"); - diff --git a/drivers/misc/mediatek/smi/mt6735/smi_common_d3.c b/drivers/misc/mediatek/smi/mt6735/smi_common_d3.c deleted file mode 100644 index 66534dffc..000000000 --- a/drivers/misc/mediatek/smi/mt6735/smi_common_d3.c +++ /dev/null @@ -1,2077 +0,0 @@ -#include <linux/of.h> -#include <linux/of_irq.h> -#include <linux/of_address.h> -#include <linux/kobject.h> - -#include <linux/uaccess.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/cdev.h> -#include <linux/mm.h> -#include <linux/vmalloc.h> -#include <linux/slab.h> -#include <linux/aee.h> -#include <linux/xlog.h> - -// We can't remove mt_clkmgr.h now since SMI needs larb monitor APIs -#include <mach/mt_clkmgr.h> - -// Define SMI_INTERNAL_CCF_SUPPORT when CCF needs to be enabled -#if !defined(CONFIG_MTK_LEGACY) - #define SMI_INTERNAL_CCF_SUPPORT -#endif - -#if defined(SMI_INTERNAL_CCF_SUPPORT) -#include <linux/clk.h> -#endif /* defined(SMI_INTERNAL_CCF_SUPPORT) */ - -#include <asm/io.h> - -#include <linux/ioctl.h> -#include <linux/fs.h> - -#if IS_ENABLED(CONFIG_COMPAT) -#include <linux/uaccess.h> -#include <linux/compat.h> -#endif - -#include <mach/mt_smi.h> - -#include "smi_reg_d3.h" -#include "smi_common.h" -#include "smi_debug.h" - -#include "mmdvfs_mgr.h" - -#undef pr_fmt -#define pr_fmt(fmt) "[SMI]" fmt - -#define SMI_LOG_TAG "SMI" - -#define LARB_BACKUP_REG_SIZE 128 -#define SMI_COMMON_BACKUP_REG_NUM 7 - -#define SF_HWC_PIXEL_MAX_NORMAL (1920 * 1080 * 7) -#define SF_HWC_PIXEL_MAX_VR (1920 * 1080 * 4 + 1036800) // 4.5 FHD size -#define SF_HWC_PIXEL_MAX_VP (1920 * 1080 * 7) -#define SF_HWC_PIXEL_MAX_ALWAYS_GPU (1920 * 1080 * 1) - -#define SMIDBG(level, x...) \ - do{ \ - if (smi_debug_level >= (level)) \ - SMIMSG(x); \ - } while (0) - -typedef struct { - spinlock_t SMI_lock; - unsigned int pu4ConcurrencyTable[SMI_BWC_SCEN_CNT]; //one bit represent one module -} SMI_struct; - -static SMI_struct g_SMIInfo; - -/* LARB BASE ADDRESS */ -static unsigned long gLarbBaseAddr[SMI_LARB_NR] = { 0, 0, 0, 0}; - -// DT porting -unsigned long smi_reg_base_common_ext = 0; -unsigned long smi_reg_base_barb0 = 0; -unsigned long smi_reg_base_barb1 = 0; -unsigned long smi_reg_base_barb2 = 0; -unsigned long smi_reg_base_barb3 = 0; - -#define SMI_REG_REGION_MAX 5 -#define SMI_COMMON_REG_INDX 0 -#define SMI_LARB0_REG_INDX 1 -#define SMI_LARB1_REG_INDX 2 -#define SMI_LARB2_REG_INDX 3 -#define SMI_LARB3_REG_INDX 4 - -static unsigned long gSMIBaseAddrs[SMI_REG_REGION_MAX]; -void register_base_dump( void ); - -char* smi_get_region_name( unsigned int region_indx ); - -struct smi_device{ - struct device *dev; - void __iomem *regs[SMI_REG_REGION_MAX]; -#if defined(SMI_INTERNAL_CCF_SUPPORT) - struct clk *smi_common_clk; - struct clk *smi_larb0_clk; - struct clk *img_larb2_clk; - struct clk *vdec0_vdec_clk; - struct clk *vdec1_larb_clk; - struct clk *venc_larb_clk; -#endif -}; -static struct smi_device *smi_dev = NULL; - -static struct device* smiDeviceUevent = NULL; - -static struct cdev * pSmiDev = NULL; - -static const unsigned int larb_port_num[SMI_LARB_NR] = { SMI_LARB0_PORT_NUM, - SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}; - -static unsigned short int larb0_port_backup[SMI_LARB0_PORT_NUM]; -static unsigned short int larb1_port_backup[SMI_LARB1_PORT_NUM]; -static unsigned short int larb2_port_backup[SMI_LARB2_PORT_NUM]; -static unsigned short int larb3_port_backup[SMI_LARB3_PORT_NUM]; - -/* SMI COMMON register list to be backuped */ -static unsigned short -g_smi_common_backup_reg_offset[SMI_COMMON_BACKUP_REG_NUM] = { 0x100, 0x104, - 0x108, 0x10c, 0x110, 0x230, 0x234 }; -static unsigned int g_smi_common_backup[SMI_COMMON_BACKUP_REG_NUM]; - -static unsigned char larb_vc_setting[SMI_LARB_NR] = { 0, 2, 1, 1 }; - -static unsigned short int * larb_port_backup[SMI_LARB_NR] = { - larb0_port_backup, larb1_port_backup, larb2_port_backup, larb3_port_backup }; - -// To keep the HW's init value -static int is_default_value_saved = 0; -static unsigned int default_val_smi_l1arb[SMI_LARB_NR] = { 0 }; - -static unsigned int wifi_disp_transaction = 0; - -/* debug level */ -static unsigned int smi_debug_level = 0; - -/* tuning mode, 1 for register ioctl */ -static unsigned int smi_tuning_mode = 0; - -static unsigned int smi_profile = SMI_BWC_SCEN_NORMAL; - -static unsigned int* pLarbRegBackUp[SMI_LARB_NR]; -static int g_bInited = 0; - -static MTK_SMI_BWC_MM_INFO g_smi_bwc_mm_info = { 0, 0, { 0, 0 }, { 0, 0 }, { 0, - 0 }, { 0, 0 }, 0, 0, 0, SF_HWC_PIXEL_MAX_NORMAL }; - -char *smi_port_name[][21] = { { /* 0 MMSYS */ - "disp_ovl0", "disp_rdma0", "disp_rdma1", "disp_wdma0", "disp_ovl1", - "disp_rdma2", "disp_wdma1", "disp_od_r", "disp_od_w", "mdp_rdma0", - "mdp_rdma1", "mdp_wdma", "mdp_wrot0", "mdp_wrot1" }, { /* 1 VDEC */ - "hw_vdec_mc_ext", "hw_vdec_pp_ext", "hw_vdec_ufo_ext", "hw_vdec_vld_ext", - "hw_vdec_vld2_ext", "hw_vdec_avc_mv_ext", "hw_vdec_pred_rd_ext", - "hw_vdec_pred_wr_ext", "hw_vdec_ppwrap_ext" }, { /* 2 ISP */ - "imgo", "rrzo", "aao", "lcso", "esfko", "imgo_d", "lsci", "lsci_d", "bpci", - "bpci_d", "ufdi", "imgi", "img2o", "img3o", "vipi", "vip2i", "vip3i", - "lcei", "rb", "rp", "wr" }, { /* 3 VENC */ - "venc_rcpu", "venc_rec", "venc_bsdma", "venc_sv_comv", "venc_rd_comv", - "jpgenc_bsdma", "remdc_sdma", "remdc_bsdma", "jpgenc_rdma", "jpgenc_sdma", - "jpgdec_wdma", "jpgdec_bsdma", "venc_cur_luma", "venc_cur_chroma", - "venc_ref_luma", "venc_ref_chroma", "remdc_wdma", "venc_nbm_rdma", - "venc_nbm_wdma" }, { /* 4 MJC */ - "mjc_mv_rd", "mjc_mv_wr", "mjc_dma_rd", "mjc_dma_wr" } }; - -static unsigned long smi_reg_pa_base[SMI_REG_REGION_MAX] = { 0x14017000, - 0x14016000, 0x16010000, 0x15001000, 0x17001000 }; - -static void initSetting( void ); -static void vpSetting( void ); -static void vrSetting( void ); -static void icfpSetting( void ); -static void vpWfdSetting( void ); - -static void smi_dumpLarb( unsigned int index ); -static void smi_dumpCommon( void ); - -#if defined(SMI_INTERNAL_CCF_SUPPORT) -static struct clk *get_smi_clk(char *smi_clk_name); -#endif - -extern void smi_dumpDebugMsg( void ); -#if IS_ENABLED(CONFIG_COMPAT) - long MTK_SMI_COMPAT_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); -#else - #define MTK_SMI_COMPAT_ioctl NULL -#endif - -// for slow motion force 30 fps -extern int primary_display_force_set_vsync_fps( unsigned int fps ); -extern unsigned int primary_display_get_fps( void ); - -// Use this function to get base address of Larb resgister -// to support error checking -unsigned long get_larb_base_addr( int larb_id ){ - unsigned long ret; - if( larb_id > SMI_LARB_NR || larb_id < 0 ){ - ret = SMI_ERROR_ADDR; - }else{ - ret = gLarbBaseAddr[larb_id]; - } - return ret; -} - - -#if defined(SMI_INTERNAL_CCF_SUPPORT) -static struct clk *get_smi_clk(char *smi_clk_name){ - struct clk *smi_clk_ptr = NULL; - smi_clk_ptr = devm_clk_get(smi_dev->dev, smi_clk_name); - if (IS_ERR(smi_clk_ptr)) { - SMIMSG("cannot get %s\n", smi_clk_name); - smi_clk_ptr = NULL; - } - return smi_clk_ptr; -} - -static void smi_enable_clk(struct clk *smi_clk, char *name){ - if (smi_clk != NULL){ - int ret = 0; - ret = clk_prepare_enable(smi_clk); - if (ret){ - SMIMSG("clk_prepare_enable return error %d, %s\n", ret, name); - } - }else{ - SMIMSG("clk_prepare_enable error, smi_clk can't be NULL, %s\n", name); - } -} - -static void smi_disable_clk(struct clk *smi_clk, char *name){ - if (smi_clk != NULL){ - clk_disable_unprepare(smi_clk); - }else{ - SMIMSG("smi_disable_clk error, smi_clk can't be NULL, %s\n", name); - } -} -#endif - -static int larb_clock_on( int larb_id ){ - -#if !defined (CONFIG_MTK_FPGA) && !defined (CONFIG_FPGA_EARLY_PORTING) - char name[30]; - sprintf(name, "smi+%d", larb_id); - - switch( larb_id ){ -#if !defined(SMI_INTERNAL_CCF_SUPPORT) - case 0: - enable_clock(MT_CG_DISP0_SMI_COMMON, name); - enable_clock(MT_CG_DISP0_SMI_LARB0, name); - break; - case 1: - enable_clock(MT_CG_DISP0_SMI_COMMON, name); - enable_clock(MT_CG_VDEC1_LARB, name); - break; - case 2: - enable_clock(MT_CG_DISP0_SMI_COMMON, name); - enable_clock(MT_CG_IMAGE_LARB2_SMI, name); - break; - case 3: - enable_clock(MT_CG_DISP0_SMI_COMMON, name); - enable_clock(MT_CG_VENC_VENC, name); - break; -#else - case 0: - smi_enable_clk(smi_dev->smi_common_clk, name); - smi_enable_clk(smi_dev->smi_larb0_clk, name); - break; - case 1: - smi_enable_clk(smi_dev->smi_common_clk, name); - smi_enable_clk(smi_dev->vdec1_larb_clk, name); - break; - case 2: - smi_enable_clk(smi_dev->smi_common_clk, name); - smi_enable_clk(smi_dev->img_larb2_clk, name); - break; - case 3: - smi_enable_clk(smi_dev->smi_common_clk, name); - smi_enable_clk(smi_dev->venc_larb_clk, name); - break; -#endif - default: - break; - } -#endif /* CONFIG_MTK_FPGA */ - - return 0; -} - -static int larb_clock_off( int larb_id ){ - -#ifndef CONFIG_MTK_FPGA - char name[30]; - sprintf(name, "smi+%d", larb_id); - - switch( larb_id ){ -#if !defined(SMI_INTERNAL_CCF_SUPPORT) - case 0: - disable_clock(MT_CG_DISP0_SMI_LARB0, name); - disable_clock(MT_CG_DISP0_SMI_COMMON, name); - break; - case 1: - disable_clock(MT_CG_VDEC1_LARB, name); - disable_clock(MT_CG_DISP0_SMI_COMMON, name); - break; - case 2: - disable_clock(MT_CG_IMAGE_LARB2_SMI, name); - disable_clock(MT_CG_DISP0_SMI_COMMON, name); - break; - case 3: - disable_clock(MT_CG_VENC_VENC, name); - disable_clock(MT_CG_DISP0_SMI_COMMON, name); - break; -#else - case 0: - smi_disable_clk(smi_dev->smi_common_clk, name); - smi_disable_clk(smi_dev->smi_larb0_clk, name); - break; - case 1: - smi_disable_clk(smi_dev->smi_common_clk, name); - smi_disable_clk(smi_dev->vdec1_larb_clk, name); - break; - case 2: - smi_disable_clk(smi_dev->smi_common_clk, name); - smi_disable_clk(smi_dev->img_larb2_clk, name); - break; - case 3: - smi_disable_clk(smi_dev->smi_common_clk, name); - smi_disable_clk(smi_dev->venc_larb_clk, name); - break; -#endif - default: - break; - } -#endif /* CONFIG_MTK_FPGA */ - - return 0; -} - -static void backup_smi_common( void ){ - int i; - - for( i = 0; i < SMI_COMMON_BACKUP_REG_NUM; i++ ){ - g_smi_common_backup[i] = M4U_ReadReg32(SMI_COMMON_EXT_BASE, - (unsigned long) g_smi_common_backup_reg_offset[i]); - } -} - -static void restore_smi_common( void ){ - int i; - - for( i = 0; i < SMI_COMMON_BACKUP_REG_NUM; i++ ){ - M4U_WriteReg32(SMI_COMMON_EXT_BASE, - (unsigned long) g_smi_common_backup_reg_offset[i], - g_smi_common_backup[i]); - } -} - -static void backup_larb_smi( int index ){ - int port_index = 0; - unsigned short int *backup_ptr = NULL; - unsigned long larb_base = gLarbBaseAddr[index]; - unsigned long larb_offset = 0x200; - int total_port_num = 0; - - // boundary check for larb_port_num and larb_port_backup access - if( index < 0 || index >= SMI_LARB_NR ){ - return; - } - - total_port_num = larb_port_num[index]; - backup_ptr = larb_port_backup[index]; - - // boundary check for port value access - if( total_port_num <= 0 || backup_ptr == NULL ){ - return; - } - - for( port_index = 0; port_index < total_port_num; port_index++ ){ - *backup_ptr = (unsigned short int) (M4U_ReadReg32(larb_base, - larb_offset)); - backup_ptr++; - larb_offset += 4; - } - - /* backup smi common along with larb0, smi common clk is guaranteed to be on when processing larbs */ - if( index == 0 ){ - backup_smi_common(); - } - - return; -} - -static void restore_larb_smi( int index ){ - int port_index = 0; - unsigned short int *backup_ptr = NULL; - unsigned long larb_base = gLarbBaseAddr[index]; - unsigned long larb_offset = 0x200; - unsigned int backup_value = 0; - int total_port_num = 0; - - // boundary check for larb_port_num and larb_port_backup access - if( index < 0 || index >= SMI_LARB_NR ){ - return; - } - total_port_num = larb_port_num[index]; - backup_ptr = larb_port_backup[index]; - - // boundary check for port value access - if( total_port_num <= 0 || backup_ptr == NULL ){ - return; - } - - /* restore smi common along with larb0, smi common clk is guaranteed to be on when processing larbs */ - if( index == 0 ){ - restore_smi_common(); - } - - for( port_index = 0; port_index < total_port_num; port_index++ ){ - backup_value = *backup_ptr; - M4U_WriteReg32(larb_base, larb_offset, backup_value); - backup_ptr++; - larb_offset += 4; - } - - /* we do not backup 0x20 because it is a fixed setting */ - M4U_WriteReg32(larb_base, 0x20, larb_vc_setting[index]); - - /* turn off EMI empty OSTD dobule, fixed setting */ - M4U_WriteReg32(larb_base, 0x2c, 4); - - return; -} - -static int larb_reg_backup( int larb ){ - unsigned int* pReg = pLarbRegBackUp[larb]; - unsigned long larb_base = gLarbBaseAddr[larb]; - - *(pReg++) = M4U_ReadReg32(larb_base, SMI_LARB_CON); - - backup_larb_smi(larb); - - if( 0 == larb ){ - g_bInited = 0; - } - - return 0; -} - -static int smi_larb_init( unsigned int larb ){ - unsigned int regval = 0; - unsigned int regval1 = 0; - unsigned int regval2 = 0; - unsigned long larb_base = get_larb_base_addr(larb); - - // Clock manager enable LARB clock before call back restore already, it will be disabled after restore call back returns - // Got to enable OSTD before engine starts - regval = M4U_ReadReg32(larb_base, SMI_LARB_STAT); - - // TODO: FIX ME - // regval1 = M4U_ReadReg32(larb_base , SMI_LARB_MON_BUS_REQ0); - // regval2 = M4U_ReadReg32(larb_base , SMI_LARB_MON_BUS_REQ1); - - if( 0 == regval ){ - SMIDBG(1, "Init OSTD for larb_base: 0x%lx\n", larb_base); - M4U_WriteReg32(larb_base, SMI_LARB_OSTDL_SOFT_EN, 0xffffffff); - }else{ - SMIMSG( - "Larb: 0x%lx is busy : 0x%x , port:0x%x,0x%x ,fail to set OSTD\n", - larb_base, regval, regval1, regval2); - smi_dumpDebugMsg(); - if( smi_debug_level >= 1 ){ - SMIERR( - "DISP_MDP LARB 0x%lx OSTD cannot be set:0x%x,port:0x%x,0x%x\n", - larb_base, regval, regval1, regval2); - }else{ - dump_stack(); - } - } - - restore_larb_smi(larb); - - return 0; -} - -int larb_reg_restore( int larb ){ - unsigned long larb_base = SMI_ERROR_ADDR; - unsigned int regval = 0; - unsigned int* pReg = NULL; - - larb_base = get_larb_base_addr(larb); - - // The larb assign doesn't exist - if( larb_base == SMI_ERROR_ADDR ){ - SMIMSG("Can't find the base address for Larb%d\n", larb); - return 0; - } - - pReg = pLarbRegBackUp[larb]; - - SMIDBG(1, "+larb_reg_restore(), larb_idx=%d \n", larb); - SMIDBG(1, "m4u part restore, larb_idx=%d \n", larb); - //warning: larb_con is controlled by set/clr - regval = *(pReg++); - M4U_WriteReg32(larb_base, SMI_LARB_CON_CLR, ~(regval)); - M4U_WriteReg32(larb_base, SMI_LARB_CON_SET, (regval)); - - smi_larb_init(larb); - - return 0; -} - -// callback after larb clock is enabled -void on_larb_power_on( struct larb_monitor *h, int larb_idx ){ - larb_reg_restore(larb_idx); - - return; -} -// callback before larb clock is disabled -void on_larb_power_off( struct larb_monitor *h, int larb_idx ){ - larb_reg_backup(larb_idx); -} - -static void restSetting( void ){ - //initialize OSTD to 1 - M4U_WriteReg32(LARB0_BASE, 0x200, 0x1); //disp_ovl0 - M4U_WriteReg32(LARB0_BASE, 0x204, 0x1); //disp_rdma0 - M4U_WriteReg32(LARB0_BASE, 0x208, 0x1); //disp_wdma0 - M4U_WriteReg32(LARB0_BASE, 0x20c, 0x1); //disp_ovl1 - M4U_WriteReg32(LARB0_BASE, 0x210, 0x1); //disp_rdma1 - M4U_WriteReg32(LARB0_BASE, 0x214, 0x1); //disp_od_r - M4U_WriteReg32(LARB0_BASE, 0x218, 0x1); //disp_od_w - M4U_WriteReg32(LARB0_BASE, 0x21c, 0x1); //mdp_rdma - M4U_WriteReg32(LARB0_BASE, 0x220, 0x1); //mdp_wdma - M4U_WriteReg32(LARB0_BASE, 0x224, 0x1); //mdp_wrot - - M4U_WriteReg32(LARB1_BASE, 0x200, 0x1); //hw_vdec_mc_ext - M4U_WriteReg32(LARB1_BASE, 0x204, 0x1); //hw_vdec_pp_ext - M4U_WriteReg32(LARB1_BASE, 0x208, 0x1); //hw_vdec_avc_mv_ext - M4U_WriteReg32(LARB1_BASE, 0x20c, 0x1); //hw_vdec_pred_rd_ext - M4U_WriteReg32(LARB1_BASE, 0x210, 0x1); //hw_vdec_pred_wr_ext - M4U_WriteReg32(LARB1_BASE, 0x214, 0x1); //hw_vdec_vld_ext - M4U_WriteReg32(LARB1_BASE, 0x218, 0x1); //hw_vdec_ppwrap_ext - - M4U_WriteReg32(LARB2_BASE, 0x200, 0x1); //imgo - M4U_WriteReg32(LARB2_BASE, 0x204, 0x1); //rrzo - M4U_WriteReg32(LARB2_BASE, 0x208, 0x1); //aao - M4U_WriteReg32(LARB2_BASE, 0x20c, 0x1); //lcso - M4U_WriteReg32(LARB2_BASE, 0x210, 0x1); //esfko - M4U_WriteReg32(LARB2_BASE, 0x214, 0x1); //imgo_s - M4U_WriteReg32(LARB2_BASE, 0x218, 0x1); //lsci - M4U_WriteReg32(LARB2_BASE, 0x21c, 0x1); //lsci_d - M4U_WriteReg32(LARB2_BASE, 0x220, 0x1); //bpci - M4U_WriteReg32(LARB2_BASE, 0x224, 0x1); //bpci_d - M4U_WriteReg32(LARB2_BASE, 0x228, 0x1); //ufdi - M4U_WriteReg32(LARB2_BASE, 0x22c, 0x1); //imgi - M4U_WriteReg32(LARB2_BASE, 0x230, 0x1); //img2o - M4U_WriteReg32(LARB2_BASE, 0x234, 0x1); //img3o - M4U_WriteReg32(LARB2_BASE, 0x238, 0x1); //vipi - M4U_WriteReg32(LARB2_BASE, 0x23c, 0x1); //vip2i - M4U_WriteReg32(LARB2_BASE, 0x240, 0x1); //vip3i - M4U_WriteReg32(LARB2_BASE, 0x244, 0x1); //lcei - M4U_WriteReg32(LARB2_BASE, 0x248, 0x1); //rb - M4U_WriteReg32(LARB2_BASE, 0x24c, 0x1); //rp - M4U_WriteReg32(LARB2_BASE, 0x250, 0x1); //wr - - M4U_WriteReg32(LARB3_BASE, 0x200, 0x1); //venc_rcpu - M4U_WriteReg32(LARB3_BASE, 0x204, 0x2); //venc_rec - M4U_WriteReg32(LARB3_BASE, 0x208, 0x1); //venc_bsdma - M4U_WriteReg32(LARB3_BASE, 0x20c, 0x1); //venc_sv_comv - M4U_WriteReg32(LARB3_BASE, 0x210, 0x1); //venc_rd_comv - M4U_WriteReg32(LARB3_BASE, 0x214, 0x1); //jpgenc_rdma - M4U_WriteReg32(LARB3_BASE, 0x218, 0x1); //jpgenc_bsdma - M4U_WriteReg32(LARB3_BASE, 0x21c, 0x1); //jpgdec_wdma - M4U_WriteReg32(LARB3_BASE, 0x220, 0x1); //jpgdec_bsdma - M4U_WriteReg32(LARB3_BASE, 0x224, 0x1); //venc_cur_luma - M4U_WriteReg32(LARB3_BASE, 0x228, 0x1); //venc_cur_chroma - M4U_WriteReg32(LARB3_BASE, 0x22c, 0x1); //venc_ref_luma - M4U_WriteReg32(LARB3_BASE, 0x230, 0x1); //venc_ref_chroma -} -//Make sure clock is on -static void initSetting( void ){ - - /* save default larb regs */ - if( !is_default_value_saved ){ - SMIMSG("Save default config:\n"); - default_val_smi_l1arb[0] = M4U_ReadReg32(SMI_COMMON_EXT_BASE, - REG_OFFSET_SMI_L1ARB0); - default_val_smi_l1arb[1] = M4U_ReadReg32(SMI_COMMON_EXT_BASE, - REG_OFFSET_SMI_L1ARB1); - default_val_smi_l1arb[2] = M4U_ReadReg32(SMI_COMMON_EXT_BASE, - REG_OFFSET_SMI_L1ARB2); - default_val_smi_l1arb[3] = M4U_ReadReg32(SMI_COMMON_EXT_BASE, - REG_OFFSET_SMI_L1ARB3); - SMIMSG("l1arb[0-2]= 0x%x, 0x%x, 0x%x\n", default_val_smi_l1arb[0], - default_val_smi_l1arb[1], default_val_smi_l1arb[2]); - SMIMSG("l1arb[3]= 0x%x\n", default_val_smi_l1arb[3]); - - is_default_value_saved = 1; - } - - // Keep the HW's init setting in REG_SMI_L1ARB0 ~ REG_SMI_L1ARB4 - M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB0, - default_val_smi_l1arb[0]); - M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB1, - default_val_smi_l1arb[1]); - M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB2, - default_val_smi_l1arb[2]); - M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB3, - default_val_smi_l1arb[3]); - - - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x100, 0xb); - M4U_WriteReg32( - SMI_COMMON_EXT_BASE, - 0x234, - (0x1 << 31) + (0x1d << 26) + (0x1f << 21) + (0x0 << 20) + (0x3 << 15) - + (0x4 << 10) + (0x4 << 5) + 0x5); - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x230, 0xf + (0x8 << 4) + (0x7 << 9)); - - // Set VC priority: MMSYS = ISP > VENC > VDEC = MJC - M4U_WriteReg32(LARB0_BASE, 0x20, 0x0); // MMSYS - M4U_WriteReg32(LARB1_BASE, 0x20, 0x2); // VDEC - M4U_WriteReg32(LARB2_BASE, 0x20, 0x1); // ISP - M4U_WriteReg32(LARB3_BASE, 0x20, 0x1); // VENC - - // for ISP HRT - M4U_WriteReg32(LARB2_BASE, 0x24, - (M4U_ReadReg32(LARB2_BASE, 0x24) & 0xf7ffffff)); - - // for UI - restSetting(); - - //SMI common BW limiter - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x104, default_val_smi_l1arb[0]); - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x108, 0x1000); - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x10C, 0x1000); - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x110, 0x1000); - - //LARB 0 DISP+MDP - M4U_WriteReg32(LARB0_BASE, 0x200, 31); //disp_ovl0 - M4U_WriteReg32(LARB0_BASE, 0x204, 8); //disp_rdma0 - M4U_WriteReg32(LARB0_BASE, 0x208, 6); //disp_wdma0 - M4U_WriteReg32(LARB0_BASE, 0x20c, 31); //disp_ovl1 - M4U_WriteReg32(LARB0_BASE, 0x210, 4); //disp_rdma1 - M4U_WriteReg32(LARB0_BASE, 0x21c, 2); //mdp_rdma - M4U_WriteReg32(LARB0_BASE, 0x224, 3); //mdp_wrot - -} - -static void icfpSetting( void ){ - M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB0, 0x14E2); //LARB0, DISP+MDP - M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB1, 0x1000); //LARB1, VDEC - M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB2, 0x1310); //LARB2, ISP - M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB3, 0x106F); //LARB3, VENC+JPG - - restSetting(); - - //LARB 0 DISP+MDP - M4U_WriteReg32(LARB0_BASE, 0x200, 0x14); //disp_ovl0 - M4U_WriteReg32(LARB0_BASE, 0x21c, 0x2); //mdp_rdma - M4U_WriteReg32(LARB0_BASE, 0x220, 0x2); //mdp_wdma - M4U_WriteReg32(LARB0_BASE, 0x224, 0x3); //mdp_wrot - - M4U_WriteReg32(LARB2_BASE, 0x200, 0xc); //imgo - M4U_WriteReg32(LARB2_BASE, 0x204, 0x4); //aao - M4U_WriteReg32(LARB2_BASE, 0x208, 0x1); //esfko - M4U_WriteReg32(LARB2_BASE, 0x210, 0x1); //lsci - M4U_WriteReg32(LARB2_BASE, 0x218, 0x1); //bpci - M4U_WriteReg32(LARB2_BASE, 0x220, 0x1); //imgi - M4U_WriteReg32(LARB2_BASE, 0x22c, 0x3); //img2o - M4U_WriteReg32(LARB2_BASE, 0x230, 0x1); //img2o - - M4U_WriteReg32(LARB3_BASE, 0x214, 0x1); //jpgenc_rdma - M4U_WriteReg32(LARB3_BASE, 0x218, 0x1); //jpgenc_bsdma - -} - - - -static void vrSetting( void ){ - //SMI BW limit - // vss - M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB0, 0x1417); //LARB0, DISP+MDP - M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB1, 0x1000); //LARB1, VDEC - M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB2, 0x11D0); //LARB2, ISP - M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB3, 0x11F8); //LARB3, VENC+JPG - - restSetting(); - - //LARB 0 DISP+MDP - M4U_WriteReg32(LARB0_BASE, 0x200, 0x10); //disp_ovl0 - M4U_WriteReg32(LARB0_BASE, 0x21c, 0x4); //mdp_rdma - M4U_WriteReg32(LARB0_BASE, 0x220, 0x1); //mdp_wdma - M4U_WriteReg32(LARB0_BASE, 0x224, 0x6); //mdp_wrot - - M4U_WriteReg32(LARB2_BASE, 0x204, 0x2); //rrzo - M4U_WriteReg32(LARB2_BASE, 0x208, 0x1); //aao - M4U_WriteReg32(LARB2_BASE, 0x210, 0x1); //esfko - M4U_WriteReg32(LARB2_BASE, 0x218, 0x2); //lsci - M4U_WriteReg32(LARB2_BASE, 0x220, 0x2); //bpci - M4U_WriteReg32(LARB2_BASE, 0x22c, 0x8); //imgi - M4U_WriteReg32(LARB2_BASE, 0x230, 0x1); //img2o - M4U_WriteReg32(LARB2_BASE, 0x238, 0x2); //vipi - M4U_WriteReg32(LARB2_BASE, 0x23c, 0x2); //vip2i - M4U_WriteReg32(LARB2_BASE, 0x240, 0x2); //vip3i - - M4U_WriteReg32(LARB3_BASE, 0x200, 0x1); //venc_rcpu - M4U_WriteReg32(LARB3_BASE, 0x204, 0x2); //venc_rec - M4U_WriteReg32(LARB3_BASE, 0x208, 0x1); //venc_bsdma - M4U_WriteReg32(LARB3_BASE, 0x20c, 0x1); //venc_sv_comv - M4U_WriteReg32(LARB3_BASE, 0x210, 0x1); //venc_rd_comv - M4U_WriteReg32(LARB3_BASE, 0x214, 0x1); //jpgenc_rdma - M4U_WriteReg32(LARB3_BASE, 0x218, 0x1); //jpgenc_bsdma - M4U_WriteReg32(LARB3_BASE, 0x224, 0x2); //venc_cur_luma - M4U_WriteReg32(LARB3_BASE, 0x228, 0x1); //venc_cur_chroma - M4U_WriteReg32(LARB3_BASE, 0x22c, 0x3); //venc_ref_luma - M4U_WriteReg32(LARB3_BASE, 0x230, 0x2); //venc_ref_chroma -} - -static void vpSetting( void ){ - - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x104, 0x1262); //LARB0, DISP+MDP - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x108, 0x11E9); //LARB1, VDEC - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x10C, 0x1000); //LARB2, ISP - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x110, 0x123D); //LARB3, VENC+JPG - - restSetting(); - - M4U_WriteReg32(LARB0_BASE, 0x200, 0x8); //disp_ovl0 - M4U_WriteReg32(LARB0_BASE, 0x208, 0x2); //disp_wdma0 - M4U_WriteReg32(LARB0_BASE, 0x210, 0x3); //mdp_rdma - M4U_WriteReg32(LARB0_BASE, 0x214, 0x1); //mdp_wdma - M4U_WriteReg32(LARB0_BASE, 0x218, 0x4); //mdp_wrot - - M4U_WriteReg32(LARB1_BASE, 0x200, 0xb); //hw_vdec_mc_ext - M4U_WriteReg32(LARB1_BASE, 0x204, 0xe); //hw_vdec_pp_ext - M4U_WriteReg32(LARB1_BASE, 0x208, 0x1); //hw_vdec_avc_mv_ext - M4U_WriteReg32(LARB1_BASE, 0x214, 0x1); //hw_vdec_vld_ext - - M4U_WriteReg32(LARB3_BASE, 0x200, 0x1); //venc_rcpu - M4U_WriteReg32(LARB3_BASE, 0x204, 0x2); //venc_rec - M4U_WriteReg32(LARB3_BASE, 0x208, 0x1); //venc_bsdma - M4U_WriteReg32(LARB3_BASE, 0x20c, 0x1); //venc_sv_comv - M4U_WriteReg32(LARB3_BASE, 0x210, 0x1); //venc_rd_comv - M4U_WriteReg32(LARB3_BASE, 0x224, 0x1); //venc_cur_luma - M4U_WriteReg32(LARB3_BASE, 0x228, 0x1); //venc_cur_chroma - M4U_WriteReg32(LARB3_BASE, 0x22c, 0x3); //venc_ref_luma - M4U_WriteReg32(LARB3_BASE, 0x230, 0x2); //venc_ref_chroma -} - -static void vpWfdSetting( void ){ - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x104, 0x14B6); //LARB0, DISP+MDP - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x108, 0x11EE); //LARB1, VDEC - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x10C, 0x1000); //LARB2, ISP - M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x110, 0x11F2); //LARB3, VENC+JPG - - restSetting(); - - M4U_WriteReg32(LARB0_BASE, 0x200, 0x12); //disp_ovl0 - M4U_WriteReg32(LARB0_BASE, 0x204, 0x8); //disp_rdma0 - M4U_WriteReg32(LARB0_BASE, 0x208, 0x6); //disp_wdma0 - M4U_WriteReg32(LARB0_BASE, 0x20c, 0x12); //disp_ovl1 - M4U_WriteReg32(LARB0_BASE, 0x210, 0x4); //disp_rdma1 - M4U_WriteReg32(LARB0_BASE, 0x21c, 0x3); //mdp_rdma - M4U_WriteReg32(LARB0_BASE, 0x220, 0x2); //mdp_wdma - M4U_WriteReg32(LARB0_BASE, 0x224, 0x5); //mdp_wrot - - - M4U_WriteReg32(LARB1_BASE, 0x200, 0xb); //hw_vdec_mc_ext - M4U_WriteReg32(LARB1_BASE, 0x204, 0xe); //hw_vdec_pp_ext - M4U_WriteReg32(LARB1_BASE, 0x208, 0x1); //hw_vdec_avc_mv_ext - M4U_WriteReg32(LARB1_BASE, 0x214, 0x1); //hw_vdec_vld_ext - - - M4U_WriteReg32(LARB3_BASE, 0x200, 0x1); //venc_rcpu - M4U_WriteReg32(LARB3_BASE, 0x204, 0x2); //venc_rec - M4U_WriteReg32(LARB3_BASE, 0x208, 0x1); //venc_bsdma - M4U_WriteReg32(LARB3_BASE, 0x20c, 0x1); //venc_sv_comv - M4U_WriteReg32(LARB3_BASE, 0x210, 0x1); //venc_rd_comv - M4U_WriteReg32(LARB3_BASE, 0x224, 0x2); //venc_cur_luma - M4U_WriteReg32(LARB3_BASE, 0x228, 0x1); //venc_cur_chroma - M4U_WriteReg32(LARB3_BASE, 0x22c, 0x3); //venc_ref_luma - M4U_WriteReg32(LARB3_BASE, 0x230, 0x2); //venc_ref_chroma -} - -// Fake mode check, e.g. WFD -static int fake_mode_handling( - MTK_SMI_BWC_CONFIG* p_conf, - unsigned int *pu4LocalCnt ){ - if( p_conf->scenario == SMI_BWC_SCEN_WFD ){ - if( p_conf->b_on_off ){ - wifi_disp_transaction = 1; - SMIMSG("Enable WFD in profile: %d\n", smi_profile); - }else{ - wifi_disp_transaction = 0; - SMIMSG("Disable WFD in profile: %d\n", smi_profile); - } - return 1; - }else{ - return 0; - } -} - -static int ovl_limit_uevent( int bwc_scenario, int ovl_pixel_limit ){ - int err = 0; - char *envp[3]; - char scenario_buf[32] = ""; - char ovl_limit_buf[32] = ""; - - snprintf(scenario_buf, 31, "SCEN=%d", bwc_scenario); - snprintf(ovl_limit_buf, 31, "HWOVL=%d", ovl_pixel_limit); - - envp[0] = scenario_buf; - envp[1] = ovl_limit_buf; - envp[2] = NULL; - - if( pSmiDev != NULL ){ - err = kobject_uevent_env(&(smiDeviceUevent->kobj), KOBJ_CHANGE, envp); - SMIMSG("Notify OVL limitaion=%d, SCEN=%d", ovl_pixel_limit, - bwc_scenario); - } - - if(err < 0) - SMIMSG(KERN_INFO "[%s] kobject_uevent_env error = %d\n", __func__, err); - - return err; -} - -static int smi_bwc_config( - MTK_SMI_BWC_CONFIG* p_conf, - unsigned int *pu4LocalCnt ){ - int i; - int result = 0; - unsigned int u4Concurrency = 0; - MTK_SMI_BWC_SCEN eFinalScen; - static MTK_SMI_BWC_SCEN ePreviousFinalScen = SMI_BWC_SCEN_CNT; - - if( smi_tuning_mode == 1 ){ - SMIMSG("Doesn't change profile in tunning mode"); - return 0; - } - - if( (SMI_BWC_SCEN_CNT <= p_conf->scenario) || (0 > p_conf->scenario) ){ - SMIERR("Incorrect SMI BWC config : 0x%x, how could this be...\n", - p_conf->scenario); - return -1; - } - - if (p_conf->b_on_off) { - /* set mmdvfs step according to certain scenarios */ - mmdvfs_notify_scenario_enter(p_conf->scenario); - } else { - /* set mmdvfs step to default after the scenario exits */ - mmdvfs_notify_scenario_exit(p_conf->scenario); - } - - spin_lock(&g_SMIInfo.SMI_lock); - result = fake_mode_handling(p_conf, pu4LocalCnt); - spin_unlock(&g_SMIInfo.SMI_lock); - - // Fake mode is not a real SMI profile, so we need to return here - if( result == 1 ){ - return 0; - } - - spin_lock(&g_SMIInfo.SMI_lock); - - if( p_conf->b_on_off ){ - //turn on certain scenario - g_SMIInfo.pu4ConcurrencyTable[p_conf->scenario] += 1; - - if( NULL != pu4LocalCnt ){ - pu4LocalCnt[p_conf->scenario] += 1; - } - }else{ - //turn off certain scenario - if( 0 == g_SMIInfo.pu4ConcurrencyTable[p_conf->scenario] ){ - SMIMSG("Too many turning off for global SMI profile:%d,%d\n", - p_conf->scenario, - g_SMIInfo.pu4ConcurrencyTable[p_conf->scenario]); - }else{ - g_SMIInfo.pu4ConcurrencyTable[p_conf->scenario] -= 1; - } - - if( NULL != pu4LocalCnt ){ - if( 0 == pu4LocalCnt[p_conf->scenario] ){ - SMIMSG( - "Process : %s did too many turning off for local SMI profile:%d,%d\n", - current->comm, p_conf->scenario, - pu4LocalCnt[p_conf->scenario]); - }else{ - pu4LocalCnt[p_conf->scenario] -= 1; - } - } - } - - for( i = 0; i < SMI_BWC_SCEN_CNT; i++ ){ - if( g_SMIInfo.pu4ConcurrencyTable[i] ){ - u4Concurrency |= (1 << i); - } - } - - /* notify mmdvfs concurrency */ - mmdvfs_notify_scenario_concurrency(u4Concurrency); - - if( (1 << SMI_BWC_SCEN_MM_GPU) & u4Concurrency ){ - eFinalScen = SMI_BWC_SCEN_MM_GPU; - }else if( (1 << SMI_BWC_SCEN_ICFP) & u4Concurrency ){ - eFinalScen = SMI_BWC_SCEN_ICFP; - } else if ((1 << SMI_BWC_SCEN_VSS) & u4Concurrency) { - eFinalScen = SMI_BWC_SCEN_VR; - }else if( (1 << SMI_BWC_SCEN_VR_SLOW) & u4Concurrency ){ - eFinalScen = SMI_BWC_SCEN_VR_SLOW; - }else if( (1 << SMI_BWC_SCEN_VR) & u4Concurrency ){ - eFinalScen = SMI_BWC_SCEN_VR; - }else if( (1 << SMI_BWC_SCEN_VP) & u4Concurrency ){ - eFinalScen = SMI_BWC_SCEN_VP; - }else if( (1 << SMI_BWC_SCEN_SWDEC_VP) & u4Concurrency ){ - eFinalScen = SMI_BWC_SCEN_SWDEC_VP; - }else if( (1 << SMI_BWC_SCEN_VENC) & u4Concurrency ){ - eFinalScen = SMI_BWC_SCEN_VENC; - }else{ - eFinalScen = SMI_BWC_SCEN_NORMAL; - } - - if( ePreviousFinalScen == eFinalScen ){ - SMIMSG("Scen equal%d,don't change\n", eFinalScen); - spin_unlock(&g_SMIInfo.SMI_lock); - return 0; - }else{ - ePreviousFinalScen = eFinalScen; - } - - /* turn on larb clock */ - for( i = 0; i < SMI_LARB_NR; i++ ){ - larb_clock_on(i); - } - - smi_profile = eFinalScen; - - /* Bandwidth Limiter */ - switch( eFinalScen ){ - case SMI_BWC_SCEN_VP: - SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_VP"); - //fixed wrong judgement - if( !wifi_disp_transaction ){ - vpSetting(); - }else{ - vpWfdSetting(); - } - g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_VP; - break; - - case SMI_BWC_SCEN_SWDEC_VP: - SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_SWDEC_VP"); - vpSetting(); - g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_VP; - break; - - case SMI_BWC_SCEN_ICFP: - SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_ICFP"); - icfpSetting(); - g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_VR; - break; - case SMI_BWC_SCEN_VR: - SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_VR"); - vrSetting(); - g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_VR; - break; - - case SMI_BWC_SCEN_VR_SLOW: - SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_VR"); - smi_profile = SMI_BWC_SCEN_VR_SLOW; - vrSetting(); - g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; - break; - - case SMI_BWC_SCEN_VENC: - SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_VENC"); - vrSetting(); - g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; - break; - - case SMI_BWC_SCEN_NORMAL: - SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_NORMAL"); - g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; - initSetting(); - break; - - case SMI_BWC_SCEN_MM_GPU: - SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_MM_GPU"); - g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; - initSetting(); - break; - - default: - SMIMSG("[SMI_PROFILE] : %s %d\n", "initSetting", eFinalScen); - initSetting(); - g_smi_bwc_mm_info .hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; - break; - } - - /*turn off larb clock*/ - for( i = 0; i < SMI_LARB_NR; i++ ){ - larb_clock_off(i); - } - - spin_unlock(&g_SMIInfo.SMI_lock); - - ovl_limit_uevent(smi_profile, g_smi_bwc_mm_info.hw_ovl_limit); - - /* force 30 fps in VR slow motion, because disp driver set fps apis got mutex, call these APIs only when necessary */ - { - static unsigned int current_fps = 0; - - if( (eFinalScen == SMI_BWC_SCEN_VR_SLOW) && (current_fps != 30) ){ /* force 30 fps in VR slow motion profile */ - primary_display_force_set_vsync_fps(30); - current_fps = 30; - SMIMSG("[SMI_PROFILE] set 30 fps\n"); - }else if( (eFinalScen != SMI_BWC_SCEN_VR_SLOW) && (current_fps == 30) ){ /* back to normal fps */ - current_fps = primary_display_get_fps(); - primary_display_force_set_vsync_fps(current_fps); - SMIMSG("[SMI_PROFILE] back to %u fps\n", current_fps); - } - } - - SMIMSG("SMI_PROFILE to:%d %s,cur:%d,%d,%d,%d\n", p_conf->scenario, - (p_conf->b_on_off ? "on" : "off"), eFinalScen, - g_SMIInfo.pu4ConcurrencyTable[SMI_BWC_SCEN_NORMAL], - g_SMIInfo.pu4ConcurrencyTable[SMI_BWC_SCEN_VR], - g_SMIInfo.pu4ConcurrencyTable[SMI_BWC_SCEN_VP]); - - return 0; -} - -struct larb_monitor larb_monitor_handler = -{ - .level = LARB_MONITOR_LEVEL_HIGH, - .backup = on_larb_power_off, - .restore = on_larb_power_on -}; - -int smi_common_init( void ){ - int i; - - SMIMSG("Enter smi_common_init\n") - for( i = 0; i < SMI_LARB_NR; i++ ){ - pLarbRegBackUp[i] = (unsigned int*) kmalloc(LARB_BACKUP_REG_SIZE, - GFP_KERNEL | __GFP_ZERO); - if( pLarbRegBackUp[i] == NULL ){ - SMIERR("pLarbRegBackUp kmalloc fail %d \n", i); - } - } - - /* - * make sure all larb power is on before we register callback func. - * then, when larb power is first off, default register value will be backed up. - */ - - for( i = 0; i < SMI_LARB_NR; i++ ){ - SMIMSG("Enalbe CLK of larb%d\n", i ); - larb_clock_on(i); - } - - /* apply init setting after kernel boot */ - SMIMSG("Enter smi_common_init\n") - initSetting(); - - register_larb_monitor(&larb_monitor_handler); - - for( i = 0; i < SMI_LARB_NR; i++ ){ - larb_clock_off(i); - } - - return 0; -} - -static int smi_open( struct inode *inode, struct file *file ){ - file->private_data = kmalloc(SMI_BWC_SCEN_CNT * sizeof(unsigned int), - GFP_ATOMIC); - - if( NULL == file->private_data ){ - SMIMSG("Not enough entry for DDP open operation\n"); - return -ENOMEM; - } - - memset(file->private_data, 0, SMI_BWC_SCEN_CNT * sizeof(unsigned int)); - - return 0; -} - -static int smi_release( struct inode *inode, struct file *file ){ - -#if 0 - unsigned long u4Index = 0; - unsigned long u4AssignCnt = 0; - unsigned long * pu4Cnt = (unsigned long *)file->private_data; - MTK_SMI_BWC_CONFIG config; - - for(; u4Index < SMI_BWC_SCEN_CNT; u4Index += 1) - { - if(pu4Cnt[u4Index]) - { - SMIMSG("Process:%s does not turn off BWC properly , force turn off %d\n" , current->comm , u4Index); - u4AssignCnt = pu4Cnt[u4Index]; - config.b_on_off = 0; - config.scenario = (MTK_SMI_BWC_SCEN)u4Index; - do - { - smi_bwc_config( &config , pu4Cnt); - } - while(0 < u4AssignCnt); - } - } -#endif - - if( NULL != file->private_data ){ - kfree(file->private_data); - file->private_data = NULL; - } - - return 0; -} -/* GMP start */ - -void smi_bwc_mm_info_set( int property_id, long val1, long val2 ){ - - switch( property_id ){ - case SMI_BWC_INFO_CON_PROFILE: - g_smi_bwc_mm_info.concurrent_profile = (int) val1; - break; - case SMI_BWC_INFO_SENSOR_SIZE: - g_smi_bwc_mm_info.sensor_size[0] = val1; - g_smi_bwc_mm_info.sensor_size[1] = val2; - break; - case SMI_BWC_INFO_VIDEO_RECORD_SIZE: - g_smi_bwc_mm_info.video_record_size[0] = val1; - g_smi_bwc_mm_info.video_record_size[1] = val2; - break; - case SMI_BWC_INFO_DISP_SIZE: - g_smi_bwc_mm_info.display_size[0] = val1; - g_smi_bwc_mm_info.display_size[1] = val2; - break; - case SMI_BWC_INFO_TV_OUT_SIZE: - g_smi_bwc_mm_info.tv_out_size[0] = val1; - g_smi_bwc_mm_info.tv_out_size[1] = val2; - break; - case SMI_BWC_INFO_FPS: - g_smi_bwc_mm_info.fps = (int) val1; - break; - case SMI_BWC_INFO_VIDEO_ENCODE_CODEC: - g_smi_bwc_mm_info.video_encode_codec = (int) val1; - break; - case SMI_BWC_INFO_VIDEO_DECODE_CODEC: - g_smi_bwc_mm_info.video_decode_codec = (int) val1; - break; - } -} - -/* GMP end */ - -static long smi_ioctl( - struct file * pFile, - unsigned int cmd, - unsigned long param ){ - int ret = 0; - - // unsigned long * pu4Cnt = (unsigned long *)pFile->private_data; - - switch( cmd ){ - - /* disable reg access ioctl by default for possible security holes */ - // TBD: check valid SMI register range - case MTK_IOC_SMI_BWC_CONFIG: { - MTK_SMI_BWC_CONFIG cfg; - ret = copy_from_user(&cfg, (void*) param, - sizeof(MTK_SMI_BWC_CONFIG)); - if( ret ){ - SMIMSG(" SMI_BWC_CONFIG, copy_from_user failed: %d\n", ret); - return -EFAULT; - } - - ret = smi_bwc_config(&cfg, NULL); - - break; - } - /* GMP start */ - case MTK_IOC_SMI_BWC_INFO_SET: { - MTK_SMI_BWC_INFO_SET cfg; - //SMIMSG("Handle MTK_IOC_SMI_BWC_INFO_SET request... start"); - ret = copy_from_user(&cfg, (void *) param, - sizeof(MTK_SMI_BWC_INFO_SET)); - if( ret ){ - SMIMSG(" MTK_IOC_SMI_BWC_INFO_SET, copy_to_user failed: %d\n", - ret); - return -EFAULT; - } - /* Set the address to the value assigned by user space program */ - smi_bwc_mm_info_set(cfg.property, cfg.value1, cfg.value2); - //SMIMSG("Handle MTK_IOC_SMI_BWC_INFO_SET request... finish"); - break; - } - case MTK_IOC_SMI_BWC_INFO_GET: { - ret = copy_to_user((void *) param, (void *) &g_smi_bwc_mm_info, - sizeof(MTK_SMI_BWC_MM_INFO)); - - if( ret ){ - SMIMSG(" MTK_IOC_SMI_BWC_INFO_GET, copy_to_user failed: %d\n", - ret); - return -EFAULT; - } - //SMIMSG("Handle MTK_IOC_SMI_BWC_INFO_GET request... finish"); - break; - } - /* GMP end */ - - case MTK_IOC_SMI_DUMP_LARB: { - unsigned int larb_index; - - ret = copy_from_user(&larb_index, (void*) param, - sizeof(unsigned int)); - if( ret ){ - return -EFAULT; - } - - smi_dumpLarb(larb_index); - } - break; - - case MTK_IOC_SMI_DUMP_COMMON: { - unsigned int arg; - - ret = copy_from_user(&arg, (void*) param, sizeof(unsigned int)); - if( ret ){ - return -EFAULT; - } - - smi_dumpCommon(); - } - break; - - default: - return -1; - } - - return ret; -} - -static const struct file_operations smiFops = -{ - .owner = THIS_MODULE, - .open = smi_open, - .release = smi_release, - .unlocked_ioctl = smi_ioctl, - .compat_ioctl = MTK_SMI_COMPAT_ioctl, -}; - -static dev_t smiDevNo = MKDEV(MTK_SMI_MAJOR_NUMBER, 0); -static inline int smi_register( void ){ - if( alloc_chrdev_region(&smiDevNo, 0, 1, "MTK_SMI") ){ - SMIERR("Allocate device No. failed"); - return -EAGAIN; - } - //Allocate driver - pSmiDev = cdev_alloc(); - - if( NULL == pSmiDev ){ - unregister_chrdev_region(smiDevNo, 1); - SMIERR("Allocate mem for kobject failed"); - return -ENOMEM; - } - - //Attatch file operation. - cdev_init(pSmiDev, &smiFops); - pSmiDev->owner = THIS_MODULE; - - //Add to system - if( cdev_add(pSmiDev, smiDevNo, 1) ){ - SMIERR("Attatch file operation failed"); - unregister_chrdev_region(smiDevNo, 1); - return -EAGAIN; - } - - return 0; -} - -static struct class *pSmiClass = NULL; - -static int smi_probe( struct platform_device *pdev ){ - - int i; - - static unsigned int smi_probe_cnt = 0; - struct device* smiDevice = NULL; - SMIMSG("Enter smi_probe\n"); - //Debug only - if( smi_probe_cnt != 0 ){ - SMIERR("Onlye support 1 SMI driver probed\n"); - return 0; - } - smi_probe_cnt++; - SMIMSG("Allocate smi_dev space\n"); - smi_dev = krealloc(smi_dev, sizeof(struct smi_device), GFP_KERNEL); - - if( smi_dev == NULL ){ - SMIERR("Unable to allocate memory for smi driver\n"); - return -ENOMEM; - } - if( NULL == pdev ){ - SMIERR("platform data missed\n"); - return -ENXIO; - } - // Keep the device structure - smi_dev->dev = &pdev->dev; - - // Map registers - for( i = 0; i < SMI_REG_REGION_MAX; i++ ){ - SMIMSG("Save region: %d\n", i); - smi_dev->regs[i] = (void *) of_iomap(pdev->dev.of_node, i); - - if( !smi_dev->regs[i] ){ - SMIERR("Unable to ioremap registers, of_iomap fail, i=%d \n", i); - return -ENOMEM; - } - - // Record the register base in global variable - gSMIBaseAddrs[i] = (unsigned long) (smi_dev->regs[i]); - SMIMSG("DT, i=%d, region=%s, map_addr=0x%p, reg_pa=0x%lx\n", i, - smi_get_region_name(i), smi_dev->regs[i], smi_reg_pa_base[i]); - } - -#if defined(SMI_INTERNAL_CCF_SUPPORT) - smi_dev->smi_common_clk = get_smi_clk("smi-common"); - smi_dev->smi_larb0_clk = get_smi_clk("smi-larb0"); - smi_dev->img_larb2_clk = get_smi_clk("img-larb2"); - smi_dev->vdec0_vdec_clk = get_smi_clk("vdec0-vdec"); - smi_dev->vdec1_larb_clk = get_smi_clk("vdec1-larb"); - smi_dev->venc_larb_clk = get_smi_clk("venc-larb"); -#endif - - SMIMSG("Execute smi_register\n"); - if( smi_register() ){ - dev_err(&pdev->dev, "register char failed\n"); - return -EAGAIN; - } - - pSmiClass = class_create(THIS_MODULE, "MTK_SMI"); - if(IS_ERR(pSmiClass)) { - int ret = PTR_ERR(pSmiClass); - SMIERR("Unable to create class, err = %d", ret); - return ret; - } - SMIMSG("Create davice\n"); - smiDevice = device_create(pSmiClass, NULL, smiDevNo, NULL, "MTK_SMI"); - smiDeviceUevent = smiDevice; - - SMIMSG("SMI probe done.\n"); - - // To adapt the legacy codes - smi_reg_base_common_ext = gSMIBaseAddrs[SMI_COMMON_REG_INDX]; - smi_reg_base_barb0 = gSMIBaseAddrs[SMI_LARB0_REG_INDX]; - smi_reg_base_barb1 = gSMIBaseAddrs[SMI_LARB1_REG_INDX]; - smi_reg_base_barb2 = gSMIBaseAddrs[SMI_LARB2_REG_INDX]; - smi_reg_base_barb3 = gSMIBaseAddrs[SMI_LARB3_REG_INDX]; - - gLarbBaseAddr[0] = LARB0_BASE; - gLarbBaseAddr[1] = LARB1_BASE; - gLarbBaseAddr[2] = LARB2_BASE; - gLarbBaseAddr[3] = LARB3_BASE; - - SMIMSG("Execute smi_common_init\n"); - smi_common_init(); - - SMIMSG("Execute SMI_DBG_Init\n"); - SMI_DBG_Init(); - return 0; - -} - -char* smi_get_region_name( unsigned int region_indx ){ - switch( region_indx ){ - case SMI_COMMON_REG_INDX: - return "smi_common"; - case SMI_LARB0_REG_INDX: - return "larb0"; - case SMI_LARB1_REG_INDX: - return "larb1"; - case SMI_LARB2_REG_INDX: - return "larb2"; - case SMI_LARB3_REG_INDX: - return "larb3"; - default: - SMIMSG("invalid region id=%d", region_indx); - return "unknown"; - } -} - -void register_base_dump( void ){ - int i = 0; - unsigned long pa_value = 0; - unsigned long va_value = 0; - - for( i = 0; i < SMI_REG_REGION_MAX; i++ ){ - va_value = gSMIBaseAddrs[i]; - pa_value = virt_to_phys((void*) va_value); - SMIMSG("REG BASE:%s-->VA=0x%lx,PA=0x%lx,SPEC=0x%lx\n", - smi_get_region_name(i), va_value, pa_value, smi_reg_pa_base[i]); - } -} - -static int smi_remove( struct platform_device *pdev ){ - cdev_del(pSmiDev); - unregister_chrdev_region(smiDevNo, 1); - device_destroy(pSmiClass, smiDevNo); - class_destroy( pSmiClass); - return 0; -} - -static int smi_suspend( struct platform_device *pdev, pm_message_t mesg ){ - return 0; -} - -static int smi_resume( struct platform_device *pdev ){ - return 0; -} - - -static const struct of_device_id smi_of_ids[] ={ - { .compatible = "mediatek,SMI_COMMON",}, - {} -}; - -static struct platform_driver smiDrv ={ - .probe = smi_probe, - .remove = smi_remove, - .suspend= smi_suspend, - .resume = smi_resume, - .driver ={ - .name = "MTK_SMI", - .owner = THIS_MODULE, - .of_match_table = smi_of_ids, - - } -}; - -static int __init smi_init(void) -{ - SMIMSG("smi_init enter\n"); - spin_lock_init(&g_SMIInfo.SMI_lock); - /* MMDVFS init */ - mmdvfs_init(&g_smi_bwc_mm_info); - - memset(g_SMIInfo.pu4ConcurrencyTable , 0 , SMI_BWC_SCEN_CNT * sizeof(unsigned int)); - - // Informs the kernel about the function to be called - // if hardware matching MTK_SMI has been found - SMIMSG("register platform driver\n"); - if (platform_driver_register(&smiDrv)){ - SMIERR("failed to register MAU driver"); - return -ENODEV; - } - SMIMSG("exit smi_init\n"); - return 0; -} - -static void __exit smi_exit(void) -{ - platform_driver_unregister(&smiDrv); - -} - -static void smi_dumpCommonDebugMsg( int output_gce_buffer ){ - unsigned long u4Base; - int smiCommonClkEnabled = 0; - - smiCommonClkEnabled = clock_is_on(MT_CG_DISP0_SMI_COMMON); - //SMI COMMON dump - if( smi_debug_level == 0 && (!smiCommonClkEnabled) ){ - SMIMSG3(output_gce_buffer, "===SMI common clock is disabled===\n"); - return; - } - - SMIMSG3(output_gce_buffer, "===SMI common reg dump, CLK: %d===\n", smiCommonClkEnabled); - - u4Base = SMI_COMMON_EXT_BASE; - SMIMSG3(output_gce_buffer, "[0x100,0x104,0x108]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x100), M4U_ReadReg32(u4Base, 0x104), - M4U_ReadReg32(u4Base, 0x108)); - SMIMSG3(output_gce_buffer, "[0x10C,0x110,0x114]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x10C), M4U_ReadReg32(u4Base, 0x110), - M4U_ReadReg32(u4Base, 0x114)); - SMIMSG3(output_gce_buffer, "[0x220,0x230,0x234,0x238]=[0x%x,0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x220), M4U_ReadReg32(u4Base, 0x230), - M4U_ReadReg32(u4Base, 0x234), M4U_ReadReg32(u4Base, 0x238)); - SMIMSG3(output_gce_buffer, "[0x400,0x404,0x408]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x400), M4U_ReadReg32(u4Base, 0x404), - M4U_ReadReg32(u4Base, 0x408)); - SMIMSG3(output_gce_buffer, "[0x40C,0x430,0x440]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x40C), M4U_ReadReg32(u4Base, 0x430), - M4U_ReadReg32(u4Base, 0x440)); - -} -static int smi_larb_clock_is_on( unsigned int larb_index ){ - - int result = 0; -#if !defined (CONFIG_MTK_FPGA) && !defined (CONFIG_FPGA_EARLY_PORTING) - switch( larb_index ){ - case 0: - result = clock_is_on(MT_CG_DISP0_SMI_LARB0); - break; - case 1: - result = clock_is_on(MT_CG_VDEC1_LARB); - break; - case 2: - result = clock_is_on(MT_CG_IMAGE_LARB2_SMI); - break; - case 3: - result = clock_is_on(MT_CG_VENC_VENC); - break; - default: - result = 0; - break; - } -#endif // !defined (CONFIG_MTK_FPGA) && !defined (CONFIG_FPGA_EARLY_PORTING) - return result; - -} -static void smi_dumpLarbDebugMsg( unsigned int u4Index ){ - unsigned long u4Base = 0; - - int larbClkEnabled = 0; - - u4Base = get_larb_base_addr(u4Index); - - larbClkEnabled = smi_larb_clock_is_on(u4Index); - - if( u4Base == SMI_ERROR_ADDR ){ - SMIMSG("Doesn't support reg dump for Larb%d\n", u4Index); - - return; - }else if( (larbClkEnabled != 0) || smi_debug_level > 0 ){ - SMIMSG("===SMI LARB%d reg dump, CLK: %d===\n", u4Index, larbClkEnabled); - - // Staus Registers - SMIMSG("[0x0,0x8,0x10]=[0x%x,0x%x,0x%x]\n", M4U_ReadReg32(u4Base, 0x0), - M4U_ReadReg32(u4Base, 0x8), M4U_ReadReg32(u4Base, 0x10)); - SMIMSG("[0x24,0x50,0x60]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x24), M4U_ReadReg32(u4Base, 0x50), - M4U_ReadReg32(u4Base, 0x60)); - SMIMSG("[0xa0,0xa4,0xa8]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0xa0), M4U_ReadReg32(u4Base, 0xa4), - M4U_ReadReg32(u4Base, 0xa8)); - SMIMSG("[0xac,0xb0,0xb4]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0xac), M4U_ReadReg32(u4Base, 0xb0), - M4U_ReadReg32(u4Base, 0xb4)); - SMIMSG("[0xb8,0xbc,0xc0]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0xb8), M4U_ReadReg32(u4Base, 0xbc), - M4U_ReadReg32(u4Base, 0xc0)); - SMIMSG("[0xc8,0xcc]=[0x%x,0x%x]\n", M4U_ReadReg32(u4Base, 0xc8), - M4U_ReadReg32(u4Base, 0xcc)); - // Settings - SMIMSG("[0x200, 0x204, 0x208]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x200), M4U_ReadReg32(u4Base, 0x204), - M4U_ReadReg32(u4Base, 0x208)); - - SMIMSG("[0x20c, 0x210, 0x214]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x20c), M4U_ReadReg32(u4Base, 0x210), - M4U_ReadReg32(u4Base, 0x214)); - - SMIMSG("[0x218, 0x21c, 0x220]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x218), M4U_ReadReg32(u4Base, 0x21c), - M4U_ReadReg32(u4Base, 0x220)); - - SMIMSG("[0x224, 0x228, 0x22c]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x224), M4U_ReadReg32(u4Base, 0x228), - M4U_ReadReg32(u4Base, 0x22c)); - - SMIMSG("[0x230, 0x234, 0x238]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x230), M4U_ReadReg32(u4Base, 0x234), - M4U_ReadReg32(u4Base, 0x238)); - - SMIMSG("[0x23c, 0x240, 0x244]=[0x%x,0x%x,0x%x]\n", - M4U_ReadReg32(u4Base, 0x23c), M4U_ReadReg32(u4Base, 0x240), - M4U_ReadReg32(u4Base, 0x244)); - - SMIMSG("[0x248, 0x24c]=[0x%x,0x%x]\n", M4U_ReadReg32(u4Base, 0x248), - M4U_ReadReg32(u4Base, 0x24c)); - }else{ - SMIMSG("===SMI LARB%d clock is disabled===\n", u4Index); - } - -} - -static void smi_dump_format( - unsigned long base, - unsigned int from, - unsigned int to ){ - int i, j, left; - unsigned int value[8]; - - for( i = from; i <= to; i += 32 ){ - for( j = 0; j < 8; j++ ){ - value[j] = M4U_ReadReg32(base, i + j * 4); - } - - SMIMSG2("%8x %x %x %x %x %x %x %x %x\n", i, value[0], value[1], - value[2], value[3], value[4], value[5], value[6], value[7]); - } - - left = ((from - to) / 4 + 1) % 8; - - if( left ){ - memset(value, 0, 8 * sizeof(unsigned int)); - - for( j = 0; j < left; j++ ){ - value[j] = M4U_ReadReg32(base, i - 32 + j * 4); - } - - SMIMSG2("%8x %x %x %x %x %x %x %x %x\n", i - 32 + j * 4, value[0], - value[1], value[2], value[3], value[4], value[5], value[6], - value[7]); - } -} - -static void smi_dumpLarb( unsigned int index ){ - unsigned long u4Base; - - u4Base = get_larb_base_addr(index); - - if( u4Base == SMI_ERROR_ADDR ){ - SMIMSG2("Doesn't support reg dump for Larb%d\n", index); - - return; - }else{ - SMIMSG2("===SMI LARB%d reg dump base 0x%lx===\n", index, u4Base); - - smi_dump_format(u4Base, 0, 0x434); - smi_dump_format(u4Base, 0xF00, 0xF0C); - } -} - -static void smi_dumpCommon( void ){ - SMIMSG2("===SMI COMMON reg dump base 0x%lx===\n", SMI_COMMON_EXT_BASE); - - smi_dump_format(SMI_COMMON_EXT_BASE, 0x1A0, 0x444); -} - -void smi_dumpDebugMsg( void ){ - unsigned int u4Index; - - // SMI COMMON dump, 0 stands for not pass log to CMDQ error dumping messages - smi_dumpCommonDebugMsg(0); - - // dump all SMI LARB - for( u4Index = 0; u4Index < SMI_LARB_NR; u4Index++ ){ - smi_dumpLarbDebugMsg(u4Index); - } -} - -int smi_debug_bus_hanging_detect( unsigned int larbs, int show_dump ){ - return smi_debug_bus_hanging_detect_ext(larbs, show_dump, 0); -} - -//output_gce_buffer = 1, write log into kernel log and CMDQ buffer. output_gce_buffer = 0, write log into kernel log only -int smi_debug_bus_hanging_detect_ext( unsigned int larbs, int show_dump, int output_gce_buffer){ - - int i = 0; - int dump_time = 0; - int is_smi_issue = 0; - int status_code = 0; - // Keep the dump result - unsigned char smi_common_busy_count = 0; - volatile unsigned int reg_temp = 0; - unsigned char smi_larb_busy_count[SMI_LARB_NR] = { 0 }; - unsigned char smi_larb_mmu_status[SMI_LARB_NR] = { 0 }; - int smi_larb_clk_status[SMI_LARB_NR] = { 0 }; - // dump resister and save resgister status - for( dump_time = 0; dump_time < 5; dump_time++ ){ - unsigned int u4Index = 0; - reg_temp = M4U_ReadReg32(SMI_COMMON_EXT_BASE, 0x440); - if( (reg_temp & (1 << 0)) == 0 ){ - // smi common is busy - smi_common_busy_count++; - } - // Dump smi common regs - if( show_dump != 0 ){ - smi_dumpCommonDebugMsg(output_gce_buffer); - } - for( u4Index = 0; u4Index < SMI_LARB_NR; u4Index++ ){ - unsigned long u4Base = get_larb_base_addr(u4Index); - smi_larb_clk_status[u4Index] = smi_larb_clock_is_on(u4Index); - //check larb clk is enable - if( smi_larb_clk_status[u4Index] != 0){ - if( u4Base != SMI_ERROR_ADDR ){ - reg_temp = M4U_ReadReg32(u4Base, 0x0); - if( reg_temp != 0 ){ - // Larb is busy - smi_larb_busy_count[u4Index]++; - } - smi_larb_mmu_status[u4Index] = M4U_ReadReg32(u4Base, 0xa0); - if( show_dump != 0 ){ - smi_dumpLarbDebugMsg(u4Index); - } - } - } - } - - } - - // Show the checked result - for( i = 0; i < SMI_LARB_NR; i++ ){ // Check each larb - if( SMI_DGB_LARB_SELECT(larbs, i) ){ - // larb i has been selected - // Get status code - - //check busy count when larb clk is enable - if( smi_larb_clk_status[i] != 0){ - if( smi_larb_busy_count[i] == 5 ){ // The larb is always busy - if( smi_common_busy_count == 5 ){ // smi common is always busy - status_code = 1; - }else if( smi_common_busy_count == 0 ){ // smi common is always idle - status_code = 2; - }else{ - status_code = 5; // smi common is sometimes busy and idle - } - }else if( smi_larb_busy_count[i] == 0 ){ // The larb is always idle - if( smi_common_busy_count == 5 ){ // smi common is always busy - status_code = 3; - }else if( smi_common_busy_count == 0 ){ // smi common is always idle - status_code = 4; - }else{ - status_code = 6; // smi common is sometimes busy and idle - } - }else{ //sometime the larb is busy - if( smi_common_busy_count == 5 ){ // smi common is always busy - status_code = 7; - }else if( smi_common_busy_count == 0 ){ // smi common is always idle - status_code = 8; - }else{ - status_code = 9; // smi common is sometimes busy and idle - } - } - }else{ - status_code = 10; - } - - // Send the debug message according to the final result - switch( status_code ){ - case 1: - case 3: - case 5: - case 7: - case 8: - SMIMSG3( - output_gce_buffer, - "Larb%d Busy=%d/5, SMI Common Busy=%d/5, status=%d ==> Check engine's state first\n", - i, smi_larb_busy_count[i], smi_common_busy_count, - status_code); - SMIMSG3( - output_gce_buffer, - "If the engine is waiting for Larb%ds' response, it needs SMI HW's check\n", - i); - break; - case 2: - if( smi_larb_mmu_status[i] == 0 ){ - SMIMSG3( - output_gce_buffer, - "Larb%d Busy=%d/5, SMI Common Busy=%d/5, status=%d ==> Check engine state first\n", - i, smi_larb_busy_count[i], smi_common_busy_count, - status_code); - SMIMSG3( - output_gce_buffer, - "If the engine is waiting for Larb%ds' response, it needs SMI HW's check\n", - i); - }else{ - SMIMSG3( - output_gce_buffer, - "Larb%d Busy=%d/5, SMI Common Busy=%d/5, status=%d ==> MMU port config error\n", - i, smi_larb_busy_count[i], smi_common_busy_count, - status_code); - is_smi_issue = 1; - } - break; - case 4: - case 6: - case 9: - SMIMSG3( - output_gce_buffer, - "Larb%d Busy=%d/5, SMI Common Busy=%d/5, status=%d ==> not SMI issue\n", - i, smi_larb_busy_count[i], smi_common_busy_count, - status_code); - break; - case 10: - SMIMSG3( - output_gce_buffer, - "Larb%d clk is disbable, status=%d ==> no need to check\n", - i, status_code); - break; - default: - SMIMSG3( - output_gce_buffer, - "Larb%d Busy=%d/5, SMI Common Busy=%d/5, status=%d ==> status unknown\n", - i, smi_larb_busy_count[i], smi_common_busy_count, - status_code); - break; - } - } - - } - - return is_smi_issue; -} - -void smi_client_status_change_notify( int module, int mode ){ - -} - -#if IS_ENABLED(CONFIG_COMPAT) -// 32 bits process ioctl support: -// This is prepared for the future extension since currently the sizes of 32 bits -// and 64 bits smi parameters are the same. - -typedef struct -{ - compat_int_t scenario; - compat_int_t b_on_off; //0 : exit this scenario , 1 : enter this scenario -}MTK_SMI_COMPAT_BWC_CONFIG; - -typedef struct -{ - compat_int_t property; - compat_int_t value1; - compat_int_t value2; -}MTK_SMI_COMPAT_BWC_INFO_SET; - -typedef struct -{ - compat_uint_t flag; // Reserved - compat_int_t concurrent_profile; - compat_int_t sensor_size[2]; - compat_int_t video_record_size[2]; - compat_int_t display_size[2]; - compat_int_t tv_out_size[2]; - compat_int_t fps; - compat_int_t video_encode_codec; - compat_int_t video_decode_codec; - compat_int_t hw_ovl_limit; -}MTK_SMI_COMPAT_BWC_MM_INFO; - -#define COMPAT_MTK_IOC_SMI_BWC_CONFIG MTK_IOW(24, MTK_SMI_COMPAT_BWC_CONFIG) -#define COMPAT_MTK_IOC_SMI_BWC_INFO_SET MTK_IOWR(28, MTK_SMI_COMPAT_BWC_INFO_SET) -#define COMPAT_MTK_IOC_SMI_BWC_INFO_GET MTK_IOWR(29, MTK_SMI_COMPAT_BWC_MM_INFO) - -static int compat_get_smi_bwc_config_struct( - MTK_SMI_COMPAT_BWC_CONFIG __user *data32, - MTK_SMI_BWC_CONFIG __user *data){ - - compat_int_t i; - int err; - - // since the int sizes of 32 A32 and A64 are equal so we don't convert them actually here - err = get_user(i, &(data32->scenario)); - err |= put_user(i, &(data->scenario)); - err |= get_user(i, &(data32->b_on_off)); - err |= put_user(i, &(data->b_on_off)); - - return err; -} - -static int compat_get_smi_bwc_mm_info_set_struct( - MTK_SMI_COMPAT_BWC_INFO_SET __user *data32, - MTK_SMI_BWC_INFO_SET __user *data){ - - compat_int_t i; - int err; - - // since the int sizes of 32 A32 and A64 are equal so we don't convert them actually here - err = get_user(i, &(data32->property)); - err |= put_user(i, &(data->property)); - err |= get_user(i, &(data32->value1)); - err |= put_user(i, &(data->value1)); - err |= get_user(i, &(data32->value2)); - err |= put_user(i, &(data->value2)); - - return err; -} - -static int compat_get_smi_bwc_mm_info_struct( - MTK_SMI_COMPAT_BWC_MM_INFO __user *data32, - MTK_SMI_BWC_MM_INFO __user *data) -{ - compat_uint_t u; - compat_int_t i; - compat_int_t p[2]; - int err; - - // since the int sizes of 32 A32 and A64 are equal so we don't convert them actually here - err = get_user(u, &(data32->flag)); - err |= put_user(u, &(data->flag)); - err |= get_user(i, &(data32->concurrent_profile)); - err |= put_user(i, &(data->concurrent_profile)); - err |= copy_from_user(p, &(data32->sensor_size),sizeof(p)); - err |= copy_to_user(&(data->sensor_size),p ,sizeof(p)); - err |= copy_from_user(p, &(data32->video_record_size),sizeof(p)); - err |= copy_to_user(&(data->video_record_size),p ,sizeof(p)); - err |= copy_from_user(p, &(data32->display_size),sizeof(p)); - err |= copy_to_user(&(data->display_size),p ,sizeof(p)); - err |= copy_from_user(p, &(data32->tv_out_size),sizeof(p)); - err |= copy_to_user(&(data->tv_out_size),p ,sizeof(p)); - err |= get_user(i, &(data32->fps)); - err |= put_user(i, &(data->fps)); - err |= get_user(i, &(data32->video_encode_codec)); - err |= put_user(i, &(data->video_encode_codec)); - err |= get_user(i, &(data32->video_decode_codec)); - err |= put_user(i, &(data->video_decode_codec)); - err |= get_user(i, &(data32->hw_ovl_limit)); - err |= put_user(i, &(data->hw_ovl_limit)); - - - return err; -} - -static int compat_put_smi_bwc_mm_info_struct( - MTK_SMI_COMPAT_BWC_MM_INFO __user *data32, - MTK_SMI_BWC_MM_INFO __user *data) -{ - - compat_uint_t u; - compat_int_t i; - compat_int_t p[2]; - int err; - - // since the int sizes of 32 A32 and A64 are equal so we don't convert them actually here - err = get_user(u, &(data->flag)); - err |= put_user(u, &(data32->flag)); - err |= get_user(i, &(data->concurrent_profile)); - err |= put_user(i, &(data32->concurrent_profile)); - err |= copy_from_user(p, &(data->sensor_size),sizeof(p)); - err |= copy_to_user(&(data32->sensor_size),p ,sizeof(p)); - err |= copy_from_user(p, &(data->video_record_size),sizeof(p)); - err |= copy_to_user(&(data32->video_record_size),p ,sizeof(p)); - err |= copy_from_user(p, &(data->display_size),sizeof(p)); - err |= copy_to_user(&(data32->display_size),p ,sizeof(p)); - err |= copy_from_user(p, &(data->tv_out_size),sizeof(p)); - err |= copy_to_user(&(data32->tv_out_size),p ,sizeof(p)); - err |= get_user(i, &(data->fps)); - err |= put_user(i, &(data32->fps)); - err |= get_user(i, &(data->video_encode_codec)); - err |= put_user(i, &(data32->video_encode_codec)); - err |= get_user(i, &(data->video_decode_codec)); - err |= put_user(i, &(data32->video_decode_codec)); - err |= get_user(i, &(data->hw_ovl_limit)); - err |= put_user(i, &(data32->hw_ovl_limit)); - return err; -} - -long MTK_SMI_COMPAT_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - long ret; - - if (!filp->f_op || !filp->f_op->unlocked_ioctl) - return -ENOTTY; - - switch (cmd){ - case COMPAT_MTK_IOC_SMI_BWC_CONFIG: - { - if(COMPAT_MTK_IOC_SMI_BWC_CONFIG == MTK_IOC_SMI_BWC_CONFIG) - { - SMIMSG("Optimized compct IOCTL: COMPAT_MTK_IOC_SMI_BWC_CONFIG"); - return filp->f_op->unlocked_ioctl(filp, cmd,(unsigned long)compat_ptr(arg)); - } else{ - - MTK_SMI_COMPAT_BWC_CONFIG __user *data32; - MTK_SMI_BWC_CONFIG __user *data; - int err; - - data32 = compat_ptr(arg); - data = compat_alloc_user_space(sizeof(MTK_SMI_BWC_CONFIG)); - - if (data == NULL) - return -EFAULT; - - err = compat_get_smi_bwc_config_struct(data32, data); - if (err) - return err; - - ret = filp->f_op->unlocked_ioctl(filp, MTK_IOC_SMI_BWC_CONFIG, - (unsigned long)data); - return ret; - } - } - - case COMPAT_MTK_IOC_SMI_BWC_INFO_SET: - { - - if(COMPAT_MTK_IOC_SMI_BWC_INFO_SET == MTK_IOC_SMI_BWC_INFO_SET) - { - SMIMSG("Optimized compct IOCTL: COMPAT_MTK_IOC_SMI_BWC_INFO_SET"); - return filp->f_op->unlocked_ioctl(filp, cmd,(unsigned long)compat_ptr(arg)); - } else{ - - MTK_SMI_COMPAT_BWC_INFO_SET __user *data32; - MTK_SMI_BWC_INFO_SET __user *data; - int err; - - data32 = compat_ptr(arg); - data = compat_alloc_user_space(sizeof(MTK_SMI_BWC_INFO_SET)); - if (data == NULL) - return -EFAULT; - - err = compat_get_smi_bwc_mm_info_set_struct(data32, data); - if (err) - return err; - - return filp->f_op->unlocked_ioctl(filp, MTK_IOC_SMI_BWC_INFO_SET, - (unsigned long)data); - } - } - - case COMPAT_MTK_IOC_SMI_BWC_INFO_GET: - { - - if(COMPAT_MTK_IOC_SMI_BWC_INFO_GET == MTK_IOC_SMI_BWC_INFO_GET){ - SMIMSG("Optimized compct IOCTL: COMPAT_MTK_IOC_SMI_BWC_INFO_GET"); - return filp->f_op->unlocked_ioctl(filp, cmd,(unsigned long)compat_ptr(arg)); - } else{ - MTK_SMI_COMPAT_BWC_MM_INFO __user *data32; - MTK_SMI_BWC_MM_INFO __user *data; - int err; - - data32 = compat_ptr(arg); - data = compat_alloc_user_space(sizeof(MTK_SMI_BWC_MM_INFO)); - - if (data == NULL) - return -EFAULT; - - err = compat_get_smi_bwc_mm_info_struct(data32, data); - if (err) - return err; - - ret = filp->f_op->unlocked_ioctl(filp, MTK_IOC_SMI_BWC_INFO_GET, - (unsigned long)data); - - err = compat_put_smi_bwc_mm_info_struct(data32, data); - - if (err) - return err; - - return ret; - } - } - - case MTK_IOC_SMI_DUMP_LARB: - case MTK_IOC_SMI_DUMP_COMMON: - - return filp->f_op->unlocked_ioctl(filp, cmd, - (unsigned long)compat_ptr(arg)); - default: - return -ENOIOCTLCMD; - } - -} - -#endif - -module_init( smi_init); -module_exit( smi_exit); - -module_param_named(debug_level, smi_debug_level, uint, S_IRUGO | S_IWUSR); -module_param_named(tuning_mode, smi_tuning_mode, uint, S_IRUGO | S_IWUSR); -module_param_named(wifi_disp_transaction, wifi_disp_transaction, uint, S_IRUGO | S_IWUSR); - -MODULE_DESCRIPTION("MTK SMI driver"); -MODULE_AUTHOR("Kendrick Hsu<kendrick.hsu@mediatek.com>"); -MODULE_LICENSE("GPL"); - diff --git a/drivers/misc/mediatek/smi/mt6735/smi_debug.c b/drivers/misc/mediatek/smi/mt6735/smi_debug.c deleted file mode 100644 index bf06deae9..000000000 --- a/drivers/misc/mediatek/smi/mt6735/smi_debug.c +++ /dev/null @@ -1,153 +0,0 @@ -#include <linux/uaccess.h> -#include <linux/module.h> -#include <linux/fs.h> -#include <linux/platform_device.h> -#include <linux/cdev.h> -#include <linux/interrupt.h> -#include <asm/io.h> -#include <linux/sched.h> -#include <linux/wait.h> -#include <linux/spinlock.h> -#include <linux/delay.h> -#include <linux/earlysuspend.h> -#include <linux/mm.h> -#include <linux/vmalloc.h> -#include <linux/dma-mapping.h> -#include <linux/slab.h> -#include <linux/aee.h> -#include <linux/timer.h> -//#include <asm/system.h> -#include <asm-generic/irq_regs.h> -//#include <asm/mach/map.h> -#include <mach/sync_write.h> -#include <mach/irqs.h> -#include <asm/cacheflush.h> -#include <linux/string.h> -#include <linux/time.h> -#include <linux/fb.h> -#include <linux/debugfs.h> -#include <mach/mt_typedefs.h> -#include <mach/m4u.h> -#include <mach/mt_smi.h> - -#include "smi_common.h" - -#include <linux/xlog.h> - -#ifdef D1 - #include "smi_reg_d1.h" -#elif defined D2 - #include "smi_reg_d2.h" -#else - #include "smi_reg_d3.h" -#endif - -#define SMI_LOG_TAG "smi" - -static char debug_buffer[4096]; - -static void process_dbg_opt(const char *opt) -{ - if (0 == strncmp(opt, "set_reg:", 8 )) - { - unsigned long addr; - unsigned int val; - char *p = (char *)opt + 8; - - addr = (unsigned long) simple_strtoul(p, &p, 16); - p++; - val = (unsigned int) simple_strtoul(p, &p, 16); - - SMIMSG("set register: 0x%lx = 0x%x\n", addr, val); - - COM_WriteReg32(addr, val); - } - if (0 == strncmp(opt, "get_reg:", 8 )) - { - unsigned long addr; - char *p = (char *)opt + 8; - - addr = (unsigned long) simple_strtoul(p, &p, 16); - - SMIMSG("get register: 0x%lx = 0x%x \n", addr, COM_ReadReg32(addr)); - } - - - - return; -} - - -static void process_dbg_cmd(char *cmd) -{ - char *tok; - while ((tok = strsep(&cmd, " ")) != NULL) - { - process_dbg_opt(tok); - } -} - - -// --------------------------------------------------------------------------- -// Debug FileSystem Routines -// --------------------------------------------------------------------------- - -struct dentry *smi_dbgfs = NULL; - - -static int debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t debug_read(struct file *file, - char __user *ubuf, size_t count, loff_t *ppos) -{ - int n = 0; - return simple_read_from_buffer(ubuf, count, ppos, debug_buffer, n); -} - - -static ssize_t debug_write(struct file *file, - const char __user *ubuf, size_t count, loff_t *ppos) -{ - const int debug_bufmax = sizeof(debug_buffer) - 1; - size_t ret; - - ret = count; - - if (count > debug_bufmax) - count = debug_bufmax; - - if (copy_from_user(&debug_buffer, ubuf, count)) - return -EFAULT; - - debug_buffer[count] = 0; - - process_dbg_cmd(debug_buffer); - - return ret; -} - - -static struct file_operations debug_fops = { - .read = debug_read, - .write = debug_write, - .open = debug_open, -}; - - -void SMI_DBG_Init(void) -{ - smi_dbgfs = debugfs_create_file("smi", - S_IFREG|S_IRUGO, NULL, (void *)0, &debug_fops); -} - - -void SMI_DBG_Deinit(void) -{ - debugfs_remove(smi_dbgfs); -} - - diff --git a/drivers/misc/mediatek/smi/mt6735/smi_debug.h b/drivers/misc/mediatek/smi/mt6735/smi_debug.h deleted file mode 100644 index 94512dc12..000000000 --- a/drivers/misc/mediatek/smi/mt6735/smi_debug.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef __MT6735_SMI_DEBUG_H__ -#define __MT6735_SMI_DEBUG_H__ - -#define SMI_DBG_DISPSYS (1<<0) -#define SMI_DBG_VDEC (1<<1) -#define SMI_DBG_IMGSYS (1<<2) -#define SMI_DBG_VENC (1<<3) -#define SMI_DBG_MJC (1<<4) - -#define SMI_DGB_LARB_SELECT(smi_dbg_larb,n) ((smi_dbg_larb) & (1<<n)) - -#ifndef CONFIG_MTK_SMI - #define smi_debug_bus_hanging_detect(larbs, show_dump) {} - #define smi_debug_bus_hanging_detect_ext(larbs, show_dump, output_gce_buffer) {} -#else - int smi_debug_bus_hanging_detect(unsigned int larbs, int show_dump); - //output_gce_buffer = 1, pass log to CMDQ error dumping messages - int smi_debug_bus_hanging_detect_ext( unsigned int larbs, int show_dump, int output_gce_buffer); - -#endif - - -#endif //__MT6735_SMI_DEBUG_H__ - diff --git a/drivers/misc/mediatek/smi/mt6735/smi_reg_d1.h b/drivers/misc/mediatek/smi/mt6735/smi_reg_d1.h deleted file mode 100644 index cceadc9f7..000000000 --- a/drivers/misc/mediatek/smi/mt6735/smi_reg_d1.h +++ /dev/null @@ -1,467 +0,0 @@ -#ifndef _MT6735_SMI_REG_H__ -#define _MT6735_SMI_REG_H__ - -#define SMI_COMMON_EXT_BASE (smi_reg_base_common_ext) -#define LARB0_BASE (smi_reg_base_barb0) -#define LARB1_BASE (smi_reg_base_barb1) -#define LARB2_BASE (smi_reg_base_barb2) -#define LARB3_BASE (smi_reg_base_barb3) - - -//================================================= -//common macro definitions -#define F_VAL(val,msb,lsb) (((val)&((1<<(msb-lsb+1))-1))<<lsb) -#define F_MSK(msb, lsb) F_VAL(0xffffffff, msb, lsb) -#define F_BIT_SET(bit) (1<<(bit)) -#define F_BIT_VAL(val,bit) ((!!(val))<<(bit)) -#define F_MSK_SHIFT(regval,msb,lsb) (((regval)&F_MSK(msb,lsb))>>lsb) - - -//===================================================== -//M4U register definition -//===================================================== - -#define REG_MMUg_PT_BASE (0x0) - #define F_MMUg_PT_VA_MSK 0xffff0000 -#define REG_MMUg_PT_BASE_SEC (0x4) - #define F_MMUg_PT_VA_MSK_SEC 0xffff0000 - - -#define REG_MMU_PROG_EN 0x10 - #define F_MMU0_PROG_EN 1 - #define F_MMU1_PROG_EN 2 -#define REG_MMU_PROG_VA 0x14 - #define F_PROG_VA_LOCK_BIT (1<<11) - #define F_PROG_VA_LAYER_BIT F_BIT_SET(9) - #define F_PROG_VA_SIZE16X_BIT F_BIT_SET(8) - #define F_PROG_VA_SECURE_BIT (1<<7) - #define F_PROG_VA_MASK 0xfffff000 - -#define REG_MMU_PROG_DSC 0x18 - -#define REG_MMU_INVLD (0x20) - #define F_MMU_INV_ALL 0x2 - #define F_MMU_INV_RANGE 0x1 - -#define REG_MMU_INVLD_SA (0x24) -#define REG_MMU_INVLD_EA (0x28) - - -#define REG_MMU_INVLD_SEC (0x2c) - #define F_MMU_INV_SEC_ALL 0x2 - #define F_MMU_INV_SEC_RANGE 0x1 - -#define REG_MMU_INVLD_SA_SEC (0x30) -#define REG_MMU_INVLD_EA_SEC (0x34) - -#define REG_INVLID_SEL (0x38) - #define F_MMU_INV_EN_L1 (1<<0) - #define F_MMU_INV_EN_L2 (1<<1) - - -#define REG_INVLID_SEL_SEC (0x3c) - #define F_MMU_INV_SEC_EN_L1 (1<<0) - #define F_MMU_INV_SEC_EN_L2 (1<<1) - #define F_MMU_INV_SEC_INV_DONE (1<<2) - #define F_MMU_INV_SEC_INV_INT_SET (1<<3) - #define F_MMU_INV_SEC_INV_INT_CLR (1<<4) - #define F_MMU_INV_SEC_DBG (1<<5) - - -#define REG_MMU_SEC_ABORT_INFO (0x40) -#define REG_MMU_STANDARD_AXI_MODE (0x48) - -#define REG_MMU_PRIORITY (0x4c) -#define REG_MMU_DCM_DIS (0x50) -#define REG_MMU_WR_LEN (0x54) -#define REG_MMU_HW_DEBUG (0x58) - #define F_MMU_HW_DBG_L2_SCAN_ALL F_BIT_SET(1) - #define F_MMU_HW_DBG_PFQ_BRDCST F_BIT_SET(0) - -#define REG_MMU_NON_BLOCKING_DIS 0x5C - #define F_MMU_NON_BLOCK_DISABLE_BIT 1 - #define F_MMU_NON_BLOCK_HALF_ENTRY_BIT 2 - -#define REG_MMU_LEGACY_4KB_MODE (0x60) - -#define REG_MMU_PFH_DIST0 0x80 -#define REG_MMU_PFH_DIST1 0x84 -#define REG_MMU_PFH_DIST2 0x88 -#define REG_MMU_PFH_DIST3 0x8c -#define REG_MMU_PFH_DIST4 0x90 -#define REG_MMU_PFH_DIST5 0x94 -#define REG_MMU_PFH_DIST6 0x98 - -#define REG_MMU_PFH_DIST(port) (0x80+(((port)>>3)<<2)) - #define F_MMU_PFH_DIST_VAL(port,val) ((val&0xf)<<(((port)&0x7)<<2)) - #define F_MMU_PFH_DIST_MASK(port) F_MMU_PFH_DIST_VAL((port), 0xf) - -#define REG_MMU_PFH_DIR0 0xF0 -#define REG_MMU_PFH_DIR1 0xF4 -#define REG_MMU_PFH_DIR(port) (((port)<32) ? REG_MMU_PFH_DIR0: REG_MMU_PFH_DIR1) -#define F_MMU_PFH_DIR(port,val) ((!!(val))<<((port)&0x1f)) - - -#define REG_MMU_READ_ENTRY 0x100 - #define F_READ_ENTRY_EN F_BIT_SET(31) - #define F_READ_ENTRY_MM1_MAIN F_BIT_SET(26) - #define F_READ_ENTRY_MM0_MAIN F_BIT_SET(25) - #define F_READ_ENTRY_MMx_MAIN(id) F_BIT_SET(25+id) - #define F_READ_ENTRY_PFH F_BIT_SET(24) - #define F_READ_ENTRY_MAIN_IDX(idx) F_VAL(idx,21,16) - #define F_READ_ENTRY_PFH_IDX(idx) F_VAL(idx,11,5) - //#define F_READ_ENTRY_PFH_HI_LO(high) F_VAL(high, 4,4) - //#define F_READ_ENTRY_PFH_PAGE(page) F_VAL(page, 3,2) - #define F_READ_ENTRY_PFH_PAGE_IDX(idx) F_VAL(idx, 4, 2) - #define F_READ_ENTRY_PFH_WAY(way) F_VAL(way, 1,0) - -#define REG_MMU_DES_RDATA 0x104 - -#define REG_MMU_PFH_TAG_RDATA 0x108 - #define F_PFH_TAG_VA_GET(mmu,tag) (F_MSK_SHIFT(tag, 14, 4)<<(MMU_SET_MSB_OFFSET(mmu)+1)) - #define F_PFH_TAG_LAYER_BIT F_BIT_SET(3) - #define F_PFH_TAG_16X_BIT F_BIT_SET(2) //this bit is always 0 -- cost down. - #define F_PFH_TAG_SEC_BIT F_BIT_SET(1) - #define F_PFH_TAG_AUTO_PFH F_BIT_SET(0) - - -// tag releated macro - //#define MMU0_SET_ORDER 7 - //#define MMU1_SET_ORDER 6 - #define MMU_SET_ORDER(mmu) (7-(mmu)) - #define MMU_SET_NR(mmu) (1<<MMU_SET_ORDER(mmu)) - #define MMU_SET_LSB_OFFSET 15 - #define MMU_SET_MSB_OFFSET(mmu) (MMU_SET_LSB_OFFSET+MMU_SET_ORDER(mmu)-1) - #define MMU_PFH_VA_TO_SET(mmu,va) F_MSK_SHIFT(va, MMU_SET_MSB_OFFSET(mmu), MMU_SET_LSB_OFFSET) - - #define MMU_PAGE_PER_LINE 8 - #define MMU_WAY_NR 4 - #define MMU_PFH_TOTAL_LINE(mmu) (MMU_SET_NR(mmu)*MMU_WAY_NR) - - -#define REG_MMU_CTRL_REG 0x110 - #define F_MMU_CTRL_PFH_DIS(dis) F_BIT_VAL(dis, 0) - #define F_MMU_CTRL_TLB_WALK_DIS(dis) F_BIT_VAL(dis, 1) - #define F_MMU_CTRL_MONITOR_EN(en) F_BIT_VAL(en, 2) - #define F_MMU_CTRL_MONITOR_CLR(clr) F_BIT_VAL(clr, 3) - #define F_MMU_CTRL_PFH_RT_RPL_MODE(mod) F_BIT_VAL(mod, 4) - #define F_MMU_CTRL_TF_PROT_VAL(prot) F_VAL(prot, 6, 5) - #define F_MMU_CTRL_TF_PROT_MSK F_MSK(6,5) - #define F_MMU_CTRL_INT_HANG_en(en) F_BIT_VAL(en, 7) - #define F_MMU_CTRL_COHERE_EN(en) F_BIT_VAL(en, 8) - #define F_MMU_CTRL_IN_ORDER_WR(en) F_BIT_VAL(en, 9) - #define F_MMU_CTRL_MAIN_TLB_SHARE_ALL(en) F_BIT_VAL(en, 10) - - -#define REG_MMU_IVRP_PADDR 0x114 - #define F_MMU_IVRP_PA_SET(PA) (PA>>1) - #define F_MMU_IVRP_8G_PA_SET(PA) ((PA>>1)|(1<<31)) - -#define REG_MMU_INT_L2_CONTROL 0x120 - #define F_INT_L2_CLR_BIT (1<<12) - #define F_INT_L2_MULTI_HIT_FAULT F_BIT_SET(0) - #define F_INT_L2_TABLE_WALK_FAULT F_BIT_SET(1) - #define F_INT_L2_PFH_DMA_FIFO_OVERFLOW F_BIT_SET(2) - #define F_INT_L2_MISS_DMA_FIFO_OVERFLOW F_BIT_SET(3) - #define F_INT_L2_INVALD_DONE F_BIT_SET(4) - #define F_INT_L2_PFH_IN_OUT_FIFO_ERROR F_BIT_SET(5) - #define F_INT_L2_MISS_FIFO_ERR F_BIT_SET(6) - -#define REG_MMU_INT_MAIN_CONTROL 0x124 - #define F_INT_TRANSLATION_FAULT(MMU) F_BIT_SET(0+(((MMU)<<1)|((MMU)<<2))) - #define F_INT_MAIN_MULTI_HIT_FAULT(MMU) F_BIT_SET(1+(((MMU)<<1)|((MMU)<<2))) - #define F_INT_INVALID_PHYSICAL_ADDRESS_FAULT(MMU) F_BIT_SET(2+(((MMU)<<1)|((MMU)<<2))) - #define F_INT_ENTRY_REPLACEMENT_FAULT(MMU) F_BIT_SET(3+(((MMU)<<1)|((MMU)<<2))) - #define F_INT_TLB_MISS_FAULT(MMU) F_BIT_SET(5+(((MMU)<<1)|((MMU)<<2))) - #define F_INT_PFH_FIFO_ERR(MMU) F_BIT_SET(6+(((MMU)<<1)|((MMU)<<2))) - - #define F_INT_MAU(mmu, set) F_BIT_SET(14+(set)+(mmu<<2)) //(14+(set)+(mmu*4)) - - #define F_INT_MMU0_MAIN_MSK F_MSK(6, 0) - #define F_INT_MMU1_MAIN_MSK F_MSK(13, 7) - #define F_INT_MMU0_MAU_MSK F_MSK(17, 14) - #define F_INT_MMU1_MAU_MSK F_MSK(21, 18) - -#define REG_MMU_CPE_DONE_SEC 0x128 -#define REG_MMU_CPE_DONE 0x12C - -#define REG_MMU_L2_FAULT_ST 0x130 - #define F_INT_L2_MISS_OUT_FIFO_ERROR F_BIT_SET(7) - #define F_INT_L2_MISS_IN_FIFO_ERR F_BIT_SET(8) -#define REG_MMU_MAIN_FAULT_ST 0x134 - -#define REG_MMU_TBWALK_FAULT_VA 0x138 - #define F_MMU_TBWALK_FAULT_VA_MSK F_MSK(31, 12) - #define F_MMU_TBWALK_FAULT_LAYER(regval) F_MSK_SHIFT(regval, 0, 0) - -#define REG_MMU_FAULT_VA(mmu) (0x13c+((mmu)<<3)) - #define F_MMU_FAULT_VA_MSK F_MSK(31, 12) - #define F_MMU_FAULT_VA_WRITE_BIT F_BIT_SET(1) - #define F_MMU_FAULT_VA_LAYER_BIT F_BIT_SET(0) - -#define REG_MMU_INVLD_PA(mmu) (0x140+((mmu)<<3)) -#define REG_MMU_INT_ID(mmu) (0x150+((mmu)<<2)) - -#define REG_MMU_PF_MSCNT 0x160 -#define REG_MMU_PF_CNT 0x164 -#define REG_MMU_ACC_CNT(mmu) (0x168+(((mmu)<<3)|((mmu)<<2))) //(0x168+((mmu)*12) -#define REG_MMU_MAIN_MSCNT(mmu) (0x16c+(((mmu)<<3)|((mmu)<<2))) -#define REG_MMU_RS_PERF_CNT(mmu) (0x170+(((mmu)<<3)|((mmu)<<2))) - -#define MMU01_SQ_OFFSET (0x600-0x300) -#define REG_MMU_SQ_START(mmu,x) (0x300+((x)<<3)+((mmu)*MMU01_SQ_OFFSET)) - #define F_SQ_VA_MASK F_MSK(31, 18) - #define F_SQ_EN_BIT (1<<17) - //#define F_SQ_MULTI_ENTRY_VAL(x) (((x)&0xf)<<13) -#define REG_MMU_SQ_END(mmu, x) (0x304+((x)<<3)+((mmu)*MMU01_SQ_OFFSET)) - - -#define MMU_TOTAL_RS_NR 8 -#define REG_MMU_RSx_VA(mmu,x) (0x380+((x)<<4)+((mmu)*MMU01_SQ_OFFSET)) - #define F_MMU_RSx_VA_GET(regval) ((regval)&F_MSK(31, 12)) - #define F_MMU_RSx_VA_VALID(regval) F_MSK_SHIFT(regval, 11, 11) - #define F_MMU_RSx_VA_PID(regval) F_MSK_SHIFT(regval, 9, 0) - -#define REG_MMU_RSx_PA(mmu,x) (0x384+((x)<<4)+((mmu)*MMU01_SQ_OFFSET)) - #define F_MMU_RSx_PA_GET(regval) ((regval)&F_MSK(31, 12)) - #define F_MMU_RSx_PA_VALID(regval) F_MSK_SHIFT(regval, 1, 0) - -#define REG_MMU_RSx_2ND_BASE(mmu,x) (0x388+((x)<<4)+((mmu)*MMU01_SQ_OFFSET)) - -#define REG_MMU_RSx_ST(mmu,x) (0x38c+((x)<<4)+((mmu)*MMU01_SQ_OFFSET)) - #define F_MMU_RSx_ST_LID(regval) F_MSK_SHIFT(regval, 21, 20) - #define F_MMU_RSx_ST_WRT(regval) F_MSK_SHIFT(regval, 12, 12) - #define F_MMU_RSx_ST_OTHER(regval) F_MSK_SHIFT(regval, 8, 0) - -#define REG_MMU_MAIN_TAG(mmu,x) (0x500+((x)<<2)+((mmu)*MMU01_SQ_OFFSET)) - #define F_MAIN_TLB_VA_MSK F_MSK(31, 12) - #define F_MAIN_TLB_LOCK_BIT (1<<11) - #define F_MAIN_TLB_VALID_BIT (1<<10) - #define F_MAIN_TLB_LAYER_BIT F_BIT_SET(9) - #define F_MAIN_TLB_16X_BIT F_BIT_SET(8) - #define F_MAIN_TLB_SEC_BIT F_BIT_SET(7) - #define F_MAIN_TLB_INV_DES_BIT (1<<6) - #define F_MAIN_TLB_SQ_EN_BIT (1<<5) - #define F_MAIN_TLB_SQ_INDEX_MSK F_MSK(4,1) - #define F_MAIN_TLB_SQ_INDEX_GET(regval) F_MSK_SHIFT(regval, 4, 1) - - -#define REG_MMU_MAU_START(mmu,mau) (0x900+((mau)*0x20)+((mmu)*0xa0)) -#define REG_MMU_MAU_START_BIT32(mmu,mau) (0x904+((mau)*0x20)+((mmu)*0xa0)) -#define REG_MMU_MAU_END(mmu,mau) (0x908+((mau)*0x20)+((mmu)*0xa0)) -#define REG_MMU_MAU_END_BIT32(mmu,mau) (0x90C+((mau)*0x20)+((mmu)*0xa0)) -#define REG_MMU_MAU_PORT_EN(mmu,mau) (0x910+((mau)*0x20)+((mmu)*0xa0)) -#define REG_MMU_MAU_ASSERT_ID(mmu,mau) (0x914+((mau)*0x20)+((mmu)*0xa0)) -#define REG_MMU_MAU_ADDR(mmu,mau) (0x918+((mau)*0x20)+((mmu)*0xa0)) -#define REG_MMU_MAU_ADDR_BIT32(mmu,mau) (0x91C+((mau)*0x20)+((mmu)*0xa0)) - -#define REG_MMU_MAU_LARB_EN(mmu) (0x980+((mmu)*0xa0)) - #define F_MAU_LARB_VAL(mau,larb) ((larb)<<(mau*8)) - #define F_MAU_LARB_MSK(mau) (0xff<<(mau*8)) -#define REG_MMU_MAU_CLR(mmu) (0x984+((mmu)*0xa0)) -#define REG_MMU_MAU_IO(mmu) (0x988+((mmu)*0xa0)) - #define F_MAU_BIT_VAL(val, mau) F_BIT_VAL(val, mau) -#define REG_MMU_MAU_RW(mmu) (0x98c+((mmu)*0xa0)) -#define REG_MMU_MAU_VA(mmu) (0x990+((mmu)*0xa0)) -#define REG_MMU_MAU_ASSERT_ST(mmu) (0x994+((mmu)*0xa0)) - -#define REG_MMU_PFH_VLD_0 (0x180) -#define REG_MMU_PFH_VLD(set, way) (REG_MMU_PFH_VLD_0+(((set)>>5)<<2)+((way)<<4)) //+((set/32)*4)+(way*16) - #define F_MMU_PFH_VLD_BIT(set, way) F_BIT_SET((set)&0x1f) // set%32 - - - -//================================================================ -// SMI larb -//================================================================ - -#define SMI_ERROR_ADDR 0 -#define SMI_LARB_NR 4 - -#define SMI_LARB0_PORT_NUM 7 -#define SMI_LARB1_PORT_NUM 7 -#define SMI_LARB2_PORT_NUM 21 -#define SMI_LARB3_PORT_NUM 13 - -#define SMI_LARB_STAT (0x0 ) -#define SMI_LARB_IRQ_EN (0x4 ) -#define SMI_LARB_IRQ_STATUS (0x8 ) -#define SMI_LARB_SLP_CON (0xc ) -#define SMI_LARB_CON (0x10 ) -#define SMI_LARB_CON_SET (0x14 ) -#define SMI_LARB_CON_CLR (0x18 ) -#define SMI_LARB_VC_PRI_MODE (0x20 ) -#define SMI_LARB_CMD_THRT_CON (0x24 ) -#define SMI_LARB_STARV_CON (0x28 ) -#define SMI_LARB_EMI_CON (0x2C ) -#define SMI_LARB_SHARE_EN (0x30 ) -#define SMI_LARB_BWL_EN (0x50 ) -#define SMI_LARB_BWL_SOFT_EN (0x54 ) -#define SMI_LARB_BWL_CON (0x58 ) -#define SMI_LARB_OSTDL_EN (0x60 ) -#define SMI_LARB_OSTDL_SOFT_EN (0x64 ) -#define SMI_LARB_ULTRA_DIS (0x70 ) -#define SMI_LARB_PREULTRA_DIS (0x74 ) -#define SMI_LARB_FORCE_ULTRA (0x78 ) -#define SMI_LARB_FORCE_PREULTRA (0x7c ) -#define SMI_LARB_MST_GRP_SEL_L (0x80 ) -#define SMI_LARB_MST_GRP_SEL_H (0x84 ) -#define SMI_LARB_INT_PATH_SEL (0x90 ) -#define SMI_LARB_EXT_GREQ_VIO (0xa0 ) -#define SMI_LARB_INT_GREQ_VIO (0xa4 ) -#define SMI_LARB_OSTD_UDF_VIO (0xa8 ) -#define SMI_LARB_OSTD_CRS_VIO (0xac ) -#define SMI_LARB_FIFO_STAT (0xb0 ) -#define SMI_LARB_BUS_STAT (0xb4 ) -#define SMI_LARB_CMD_THRT_STAT (0xb8 ) -#define SMI_LARB_MON_REQ (0xbc ) -#define SMI_LARB_REQ_MASK (0xc0 ) -#define SMI_LARB_REQ_DET (0xc4 ) -#define SMI_LARB_EXT_ONGOING (0xc8 ) -#define SMI_LARB_INT_ONGOING (0xcc ) -#define SMI_LARB_MISC_MON0 (0xd0 ) -#define SMI_LARB_DBG_CON (0xf0 ) -#define SMI_LARB_TST_MODE (0xf4 ) -#define SMI_LARB_WRR_PORT (0x100 ) -#define SMI_LARB_BWL_PORT (0x180 ) -#define SMI_LARB_OSTDL_PORT (0x200 ) -#define SMI_LARB_OSTD_MON_PORT (0x280 ) -#define SMI_LARB_PINFO (0x300 ) -#define SMI_LARB_MON_EN (0x400 ) -#define SMI_LARB_MON_CLR (0x404 ) -#define SMI_LARB_MON_PORT (0x408 ) -#define SMI_LARB_MON_CON (0x40c ) -#define SMI_LARB_MON_ACT_CNT (0x410 ) -#define SMI_LARB_MON_REQ_CNT (0x414 ) -#define SMI_LARB_MON_BEAT_CNT (0x418 ) -#define SMI_LARB_MON_BYTE_CNT (0x41c ) -#define SMI_LARB_MON_CP_CNT (0x420 ) -#define SMI_LARB_MON_DP_CNT (0x424 ) -#define SMI_LARB_MON_OSTD_CNT (0x428 ) -#define SMI_LARB_MON_CP_MAX (0x430 ) -#define SMI_LARB_MON_COS_MAX (0x434 ) -#define SMI_LARB_MMU_EN (0xf00 ) - #define F_SMI_MMU_EN(port, en) ((en)<<((port))) - #define F_SMI_SEC_EN(port, en) ((en)<<((port))) -#define REG_SMI_LARB_DOMN_OF_PORT(port) (((port)>15) ? 0xf0c : 0xf08) - #define F_SMI_DOMN(port, domain) (((domain)&0x3)<<((((port)>15) ? (port-16) : port)<<1)) - - - - -/* -#define SMI_SHARE_EN (0x210) - #define F_SMI_SHARE_EN(port) F_BIT_SET(m4u_port_2_larb_port(port)) -#define SMI_ROUTE_SEL (0x220) - #define F_SMI_ROUTE_SEL_EMI(port) F_BIT_SET(m4u_port_2_larb_port(port)) -#define SMI_MMULOCK_EN (0x230) -*/ - - -/* =============================================================== - * SMI COMMON - * =============================================================== */ - -#define REG_OFFSET_SMI_L1LEN (0x100) -#define REG_OFFSET_SMI_L1ARB0 (0x104) -#define REG_OFFSET_SMI_L1ARB1 (0x108) -#define REG_OFFSET_SMI_L1ARB2 (0x10C) -#define REG_OFFSET_SMI_L1ARB3 (0x110) -#define REG_OFFSET_SMI_L1ARB4 (0x114) - -/* -#define REG_SMI_MON_AXI_ENA (0x1a0+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_CLR (0x1a4+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_TYPE (0x1ac+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_CON (0x1b0+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_ACT_CNT (0x1c0+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_REQ_CNT (0x1c4+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_OSTD_CNT (0x1c8+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_BEA_CNT (0x1cc+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_BYT_CNT (0x1d0+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_CP_CNT (0x1d4+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_DP_CNT (0x1d8+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_CP_MAX (0x1dc+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_COS_MAX (0x1e0+SMI_COMMON_EXT_BASE) -#define REG_SMI_L1LEN (0x200+SMI_COMMON_EXT_BASE) -#define REG_SMI_L1ARB0 (0x204+SMI_COMMON_EXT_BASE) -#define REG_SMI_L1ARB1 (0x208+SMI_COMMON_EXT_BASE) -#define REG_SMI_L1ARB2 (0x20C+SMI_COMMON_EXT_BASE) -#define REG_SMI_L1ARB3 (0x210+SMI_COMMON_EXT_BASE) -#define REG_SMI_L1ARB4 (0x214+SMI_COMMON_EXT_BASE) -#define REG_SMI_BUS_SEL (0x220+SMI_COMMON_EXT_BASE) - #define F_SMI_BUS_SEL_larb0(mmu_idx) F_VAL(mmu_idx, 1, 0) - #define F_SMI_BUS_SEL_larb1(mmu_idx) F_VAL(mmu_idx, 3, 2) - #define F_SMI_BUS_SEL_larb2(mmu_idx) F_VAL(mmu_idx, 5, 4) - #define F_SMI_BUS_SEL_larb3(mmu_idx) F_VAL(mmu_idx, 7, 6) - #define F_SMI_BUS_SEL_larb4(mmu_idx) F_VAL(mmu_idx, 9, 8) -#define REG_SMI_WRR_REG0 (0x228+SMI_COMMON_EXT_BASE) -#define REG_SMI_READ_FIFO_TH (0x230+SMI_COMMON_EXT_BASE) -#define REG_SMI_SMI_M4U_TH (0x234+SMI_COMMON_EXT_BASE) -#define REG_SMI_SMI_FIFO2_TH (0x238+SMI_COMMON_EXT_BASE) -#define REG_SMI_SMI_PREULTRA_MASK0 (0x23c+SMI_COMMON_EXT_BASE) -#define REG_SMI_SMI_PREULTRA_MASK1 (0x240+SMI_COMMON_EXT_BASE) -#define REG_SMI_DCM (0x300+SMI_COMMON_EXT_BASE) -#define REG_SMI_SMI_ELA (0x304+SMI_COMMON_EXT_BASE) -#define REG_SMI_DEBUG0 (0x400+SMI_COMMON_EXT_BASE) -#define REG_SMI_DEBUG1 (0x404+SMI_COMMON_EXT_BASE) -#define REG_SMI_DEBUG2 (0x408+SMI_COMMON_EXT_BASE) -#define REG_SMI_DUMMY (0x418+SMI_COMMON_EXT_BASE) - -*/ - -//========================================================================= -// peripheral system -//========================================================================= -#define REG_PERIAXI_BUS_CTL3 (0x208+0xf0003000) - #define F_PERI_MMU_EN(port, en) ((en)<<((port))) - - -static inline unsigned int M4U_ReadReg32(unsigned long M4uBase, unsigned long Offset) -{ - unsigned int val; - val = ioread32((void*)(M4uBase+Offset)); - - //printk("read base=0x%x, reg=0x%x, val=0x%x\n",M4uBase,Offset,val ); - return val; -} -static inline void M4U_WriteReg32(unsigned long M4uBase, unsigned long Offset, unsigned int Val) -{ - //unsigned int read; - iowrite32(Val, (void*)(M4uBase+Offset)); - mb(); - /* - read = M4U_ReadReg32(M4uBase, Offset); - if(read != Val) - { - printk("error to write base=0x%x, reg=0x%x, val=0x%x, read=0x%x\n",M4uBase,Offset, Val, read ); - } - else - { - printk("write base=0x%x, reg=0x%x, val=0x%x, read=0x%x\n",M4uBase,Offset, Val, read ); - } -*/ - -} - -static inline unsigned int COM_ReadReg32(unsigned long addr) -{ - return ioread32((void *)addr); -} - -static inline void COM_WriteReg32(unsigned long addr, unsigned int Val) -{ - iowrite32(Val, (void *)addr); - mb(); -} - - -extern unsigned long smi_reg_base_common_ext; -extern unsigned long smi_reg_base_barb0; -extern unsigned long smi_reg_base_barb1; -extern unsigned long smi_reg_base_barb2; -extern unsigned long smi_reg_base_barb3; - - -#endif //_MT6735_SMI_REG_H__ - diff --git a/drivers/misc/mediatek/smi/mt6735/smi_reg_d2.h b/drivers/misc/mediatek/smi/mt6735/smi_reg_d2.h deleted file mode 100644 index e6a7bbe99..000000000 --- a/drivers/misc/mediatek/smi/mt6735/smi_reg_d2.h +++ /dev/null @@ -1,464 +0,0 @@ -#ifndef _MT6735m_SMI_REG_H__ -#define _MT6735m_SMI_REG_H__ - -#define SMI_COMMON_EXT_BASE (smi_reg_base_common_ext) -#define LARB0_BASE (smi_reg_base_barb0) -#define LARB1_BASE (smi_reg_base_barb1) -#define LARB2_BASE (smi_reg_base_barb2) - - -//================================================= -//common macro definitions -#define F_VAL(val,msb,lsb) (((val)&((1<<(msb-lsb+1))-1))<<lsb) -#define F_MSK(msb, lsb) F_VAL(0xffffffff, msb, lsb) -#define F_BIT_SET(bit) (1<<(bit)) -#define F_BIT_VAL(val,bit) ((!!(val))<<(bit)) -#define F_MSK_SHIFT(regval,msb,lsb) (((regval)&F_MSK(msb,lsb))>>lsb) - - -//===================================================== -//M4U register definition -//===================================================== - -#define REG_MMUg_PT_BASE (0x0) - #define F_MMUg_PT_VA_MSK 0xffff0000 -#define REG_MMUg_PT_BASE_SEC (0x4) - #define F_MMUg_PT_VA_MSK_SEC 0xffff0000 - - -#define REG_MMU_PROG_EN 0x10 - #define F_MMU0_PROG_EN 1 - #define F_MMU1_PROG_EN 2 -#define REG_MMU_PROG_VA 0x14 - #define F_PROG_VA_LOCK_BIT (1<<11) - #define F_PROG_VA_LAYER_BIT F_BIT_SET(9) - #define F_PROG_VA_SIZE16X_BIT F_BIT_SET(8) - #define F_PROG_VA_SECURE_BIT (1<<7) - #define F_PROG_VA_MASK 0xfffff000 - -#define REG_MMU_PROG_DSC 0x18 - -#define REG_MMU_INVLD (0x20) - #define F_MMU_INV_ALL 0x2 - #define F_MMU_INV_RANGE 0x1 - -#define REG_MMU_INVLD_SA (0x24) -#define REG_MMU_INVLD_EA (0x28) - - -#define REG_MMU_INVLD_SEC (0x2c) - #define F_MMU_INV_SEC_ALL 0x2 - #define F_MMU_INV_SEC_RANGE 0x1 - -#define REG_MMU_INVLD_SA_SEC (0x30) -#define REG_MMU_INVLD_EA_SEC (0x34) - -#define REG_INVLID_SEL (0x38) - #define F_MMU_INV_EN_L1 (1<<0) - #define F_MMU_INV_EN_L2 (1<<1) - - -#define REG_INVLID_SEL_SEC (0x3c) - #define F_MMU_INV_SEC_EN_L1 (1<<0) - #define F_MMU_INV_SEC_EN_L2 (1<<1) - #define F_MMU_INV_SEC_INV_DONE (1<<2) - #define F_MMU_INV_SEC_INV_INT_SET (1<<3) - #define F_MMU_INV_SEC_INV_INT_CLR (1<<4) - #define F_MMU_INV_SEC_DBG (1<<5) - - -#define REG_MMU_SEC_ABORT_INFO (0x40) -#define REG_MMU_STANDARD_AXI_MODE (0x48) - -#define REG_MMU_PRIORITY (0x4c) -#define REG_MMU_DCM_DIS (0x50) -#define REG_MMU_WR_LEN (0x54) -#define REG_MMU_HW_DEBUG (0x58) - #define F_MMU_HW_DBG_L2_SCAN_ALL F_BIT_SET(1) - #define F_MMU_HW_DBG_PFQ_BRDCST F_BIT_SET(0) - -#define REG_MMU_NON_BLOCKING_DIS 0x5C - #define F_MMU_NON_BLOCK_DISABLE_BIT 1 - #define F_MMU_NON_BLOCK_HALF_ENTRY_BIT 2 - -#define REG_MMU_LEGACY_4KB_MODE (0x60) - -#define REG_MMU_PFH_DIST0 0x80 -#define REG_MMU_PFH_DIST1 0x84 -#define REG_MMU_PFH_DIST2 0x88 -#define REG_MMU_PFH_DIST3 0x8c -#define REG_MMU_PFH_DIST4 0x90 -#define REG_MMU_PFH_DIST5 0x94 -#define REG_MMU_PFH_DIST6 0x98 - -#define REG_MMU_PFH_DIST(port) (0x80+(((port)>>3)<<2)) - #define F_MMU_PFH_DIST_VAL(port,val) ((val&0xf)<<(((port)&0x7)<<2)) - #define F_MMU_PFH_DIST_MASK(port) F_MMU_PFH_DIST_VAL((port), 0xf) - -#define REG_MMU_PFH_DIR0 0xF0 -#define REG_MMU_PFH_DIR1 0xF4 -#define REG_MMU_PFH_DIR(port) (((port)<32) ? REG_MMU_PFH_DIR0: REG_MMU_PFH_DIR1) -#define F_MMU_PFH_DIR(port,val) ((!!(val))<<((port)&0x1f)) - - -#define REG_MMU_READ_ENTRY 0x100 - #define F_READ_ENTRY_EN F_BIT_SET(31) - #define F_READ_ENTRY_MM1_MAIN F_BIT_SET(26) - #define F_READ_ENTRY_MM0_MAIN F_BIT_SET(25) - #define F_READ_ENTRY_MMx_MAIN(id) F_BIT_SET(25+id) - #define F_READ_ENTRY_PFH F_BIT_SET(24) - #define F_READ_ENTRY_MAIN_IDX(idx) F_VAL(idx,21,16) - #define F_READ_ENTRY_PFH_IDX(idx) F_VAL(idx,11,5) - //#define F_READ_ENTRY_PFH_HI_LO(high) F_VAL(high, 4,4) - //#define F_READ_ENTRY_PFH_PAGE(page) F_VAL(page, 3,2) - #define F_READ_ENTRY_PFH_PAGE_IDX(idx) F_VAL(idx, 4, 2) - #define F_READ_ENTRY_PFH_WAY(way) F_VAL(way, 1,0) - -#define REG_MMU_DES_RDATA 0x104 - -#define REG_MMU_PFH_TAG_RDATA 0x108 - #define F_PFH_TAG_VA_GET(mmu,tag) (F_MSK_SHIFT(tag, 14, 4)<<(MMU_SET_MSB_OFFSET(mmu)+1)) - #define F_PFH_TAG_LAYER_BIT F_BIT_SET(3) - #define F_PFH_TAG_16X_BIT F_BIT_SET(2) //this bit is always 0 -- cost down. - #define F_PFH_TAG_SEC_BIT F_BIT_SET(1) - #define F_PFH_TAG_AUTO_PFH F_BIT_SET(0) - - -// tag releated macro - //#define MMU0_SET_ORDER 7 - //#define MMU1_SET_ORDER 6 - #define MMU_SET_ORDER(mmu) (7-(mmu)) - #define MMU_SET_NR(mmu) (1<<MMU_SET_ORDER(mmu)) - #define MMU_SET_LSB_OFFSET 15 - #define MMU_SET_MSB_OFFSET(mmu) (MMU_SET_LSB_OFFSET+MMU_SET_ORDER(mmu)-1) - #define MMU_PFH_VA_TO_SET(mmu,va) F_MSK_SHIFT(va, MMU_SET_MSB_OFFSET(mmu), MMU_SET_LSB_OFFSET) - - #define MMU_PAGE_PER_LINE 8 - #define MMU_WAY_NR 4 - #define MMU_PFH_TOTAL_LINE(mmu) (MMU_SET_NR(mmu)*MMU_WAY_NR) - - -#define REG_MMU_CTRL_REG 0x110 - #define F_MMU_CTRL_PFH_DIS(dis) F_BIT_VAL(dis, 0) - #define F_MMU_CTRL_TLB_WALK_DIS(dis) F_BIT_VAL(dis, 1) - #define F_MMU_CTRL_MONITOR_EN(en) F_BIT_VAL(en, 2) - #define F_MMU_CTRL_MONITOR_CLR(clr) F_BIT_VAL(clr, 3) - #define F_MMU_CTRL_PFH_RT_RPL_MODE(mod) F_BIT_VAL(mod, 4) - #define F_MMU_CTRL_TF_PROT_VAL(prot) F_VAL(prot, 6, 5) - #define F_MMU_CTRL_TF_PROT_MSK F_MSK(6,5) - #define F_MMU_CTRL_INT_HANG_en(en) F_BIT_VAL(en, 7) - #define F_MMU_CTRL_COHERE_EN(en) F_BIT_VAL(en, 8) - #define F_MMU_CTRL_IN_ORDER_WR(en) F_BIT_VAL(en, 9) - #define F_MMU_CTRL_MAIN_TLB_SHARE_ALL(en) F_BIT_VAL(en, 10) - - -#define REG_MMU_IVRP_PADDR 0x114 - #define F_MMU_IVRP_PA_SET(PA) (PA>>1) - #define F_MMU_IVRP_8G_PA_SET(PA) ((PA>>1)|(1<<31)) - -#define REG_MMU_INT_L2_CONTROL 0x120 - #define F_INT_L2_CLR_BIT (1<<12) - #define F_INT_L2_MULTI_HIT_FAULT F_BIT_SET(0) - #define F_INT_L2_TABLE_WALK_FAULT F_BIT_SET(1) - #define F_INT_L2_PFH_DMA_FIFO_OVERFLOW F_BIT_SET(2) - #define F_INT_L2_MISS_DMA_FIFO_OVERFLOW F_BIT_SET(3) - #define F_INT_L2_INVALD_DONE F_BIT_SET(4) - #define F_INT_L2_PFH_IN_OUT_FIFO_ERROR F_BIT_SET(5) - #define F_INT_L2_MISS_FIFO_ERR F_BIT_SET(6) - -#define REG_MMU_INT_MAIN_CONTROL 0x124 - #define F_INT_TRANSLATION_FAULT(MMU) F_BIT_SET(0+(((MMU)<<1)|((MMU)<<2))) - #define F_INT_MAIN_MULTI_HIT_FAULT(MMU) F_BIT_SET(1+(((MMU)<<1)|((MMU)<<2))) - #define F_INT_INVALID_PHYSICAL_ADDRESS_FAULT(MMU) F_BIT_SET(2+(((MMU)<<1)|((MMU)<<2))) - #define F_INT_ENTRY_REPLACEMENT_FAULT(MMU) F_BIT_SET(3+(((MMU)<<1)|((MMU)<<2))) - #define F_INT_TLB_MISS_FAULT(MMU) F_BIT_SET(5+(((MMU)<<1)|((MMU)<<2))) - #define F_INT_PFH_FIFO_ERR(MMU) F_BIT_SET(6+(((MMU)<<1)|((MMU)<<2))) - - #define F_INT_MAU(mmu, set) F_BIT_SET(14+(set)+(mmu<<2)) //(14+(set)+(mmu*4)) - - #define F_INT_MMU0_MAIN_MSK F_MSK(6, 0) - #define F_INT_MMU1_MAIN_MSK F_MSK(13, 7) - #define F_INT_MMU0_MAU_MSK F_MSK(17, 14) - #define F_INT_MMU1_MAU_MSK F_MSK(21, 18) - -#define REG_MMU_CPE_DONE_SEC 0x128 -#define REG_MMU_CPE_DONE 0x12C - -#define REG_MMU_L2_FAULT_ST 0x130 - #define F_INT_L2_MISS_OUT_FIFO_ERROR F_BIT_SET(7) - #define F_INT_L2_MISS_IN_FIFO_ERR F_BIT_SET(8) -#define REG_MMU_MAIN_FAULT_ST 0x134 - -#define REG_MMU_TBWALK_FAULT_VA 0x138 - #define F_MMU_TBWALK_FAULT_VA_MSK F_MSK(31, 12) - #define F_MMU_TBWALK_FAULT_LAYER(regval) F_MSK_SHIFT(regval, 0, 0) - -#define REG_MMU_FAULT_VA(mmu) (0x13c+((mmu)<<3)) - #define F_MMU_FAULT_VA_MSK F_MSK(31, 12) - #define F_MMU_FAULT_VA_WRITE_BIT F_BIT_SET(1) - #define F_MMU_FAULT_VA_LAYER_BIT F_BIT_SET(0) - -#define REG_MMU_INVLD_PA(mmu) (0x140+((mmu)<<3)) -#define REG_MMU_INT_ID(mmu) (0x150+((mmu)<<2)) - -#define REG_MMU_PF_MSCNT 0x160 -#define REG_MMU_PF_CNT 0x164 -#define REG_MMU_ACC_CNT(mmu) (0x168+(((mmu)<<3)|((mmu)<<2))) //(0x168+((mmu)*12) -#define REG_MMU_MAIN_MSCNT(mmu) (0x16c+(((mmu)<<3)|((mmu)<<2))) -#define REG_MMU_RS_PERF_CNT(mmu) (0x170+(((mmu)<<3)|((mmu)<<2))) - -#define MMU01_SQ_OFFSET (0x600-0x300) -#define REG_MMU_SQ_START(mmu,x) (0x300+((x)<<3)+((mmu)*MMU01_SQ_OFFSET)) - #define F_SQ_VA_MASK F_MSK(31, 18) - #define F_SQ_EN_BIT (1<<17) - //#define F_SQ_MULTI_ENTRY_VAL(x) (((x)&0xf)<<13) -#define REG_MMU_SQ_END(mmu, x) (0x304+((x)<<3)+((mmu)*MMU01_SQ_OFFSET)) - - -#define MMU_TOTAL_RS_NR 8 -#define REG_MMU_RSx_VA(mmu,x) (0x380+((x)<<4)+((mmu)*MMU01_SQ_OFFSET)) - #define F_MMU_RSx_VA_GET(regval) ((regval)&F_MSK(31, 12)) - #define F_MMU_RSx_VA_VALID(regval) F_MSK_SHIFT(regval, 11, 11) - #define F_MMU_RSx_VA_PID(regval) F_MSK_SHIFT(regval, 9, 0) - -#define REG_MMU_RSx_PA(mmu,x) (0x384+((x)<<4)+((mmu)*MMU01_SQ_OFFSET)) - #define F_MMU_RSx_PA_GET(regval) ((regval)&F_MSK(31, 12)) - #define F_MMU_RSx_PA_VALID(regval) F_MSK_SHIFT(regval, 1, 0) - -#define REG_MMU_RSx_2ND_BASE(mmu,x) (0x388+((x)<<4)+((mmu)*MMU01_SQ_OFFSET)) - -#define REG_MMU_RSx_ST(mmu,x) (0x38c+((x)<<4)+((mmu)*MMU01_SQ_OFFSET)) - #define F_MMU_RSx_ST_LID(regval) F_MSK_SHIFT(regval, 21, 20) - #define F_MMU_RSx_ST_WRT(regval) F_MSK_SHIFT(regval, 12, 12) - #define F_MMU_RSx_ST_OTHER(regval) F_MSK_SHIFT(regval, 8, 0) - -#define REG_MMU_MAIN_TAG(mmu,x) (0x500+((x)<<2)+((mmu)*MMU01_SQ_OFFSET)) - #define F_MAIN_TLB_VA_MSK F_MSK(31, 12) - #define F_MAIN_TLB_LOCK_BIT (1<<11) - #define F_MAIN_TLB_VALID_BIT (1<<10) - #define F_MAIN_TLB_LAYER_BIT F_BIT_SET(9) - #define F_MAIN_TLB_16X_BIT F_BIT_SET(8) - #define F_MAIN_TLB_SEC_BIT F_BIT_SET(7) - #define F_MAIN_TLB_INV_DES_BIT (1<<6) - #define F_MAIN_TLB_SQ_EN_BIT (1<<5) - #define F_MAIN_TLB_SQ_INDEX_MSK F_MSK(4,1) - #define F_MAIN_TLB_SQ_INDEX_GET(regval) F_MSK_SHIFT(regval, 4, 1) - - -#define REG_MMU_MAU_START(mmu,mau) (0x900+((mau)*0x20)+((mmu)*0xa0)) -#define REG_MMU_MAU_START_BIT32(mmu,mau) (0x904+((mau)*0x20)+((mmu)*0xa0)) -#define REG_MMU_MAU_END(mmu,mau) (0x908+((mau)*0x20)+((mmu)*0xa0)) -#define REG_MMU_MAU_END_BIT32(mmu,mau) (0x90C+((mau)*0x20)+((mmu)*0xa0)) -#define REG_MMU_MAU_PORT_EN(mmu,mau) (0x910+((mau)*0x20)+((mmu)*0xa0)) -#define REG_MMU_MAU_ASSERT_ID(mmu,mau) (0x914+((mau)*0x20)+((mmu)*0xa0)) -#define REG_MMU_MAU_ADDR(mmu,mau) (0x918+((mau)*0x20)+((mmu)*0xa0)) -#define REG_MMU_MAU_ADDR_BIT32(mmu,mau) (0x91C+((mau)*0x20)+((mmu)*0xa0)) - -#define REG_MMU_MAU_LARB_EN(mmu) (0x980+((mmu)*0xa0)) - #define F_MAU_LARB_VAL(mau,larb) ((larb)<<(mau*8)) - #define F_MAU_LARB_MSK(mau) (0xff<<(mau*8)) -#define REG_MMU_MAU_CLR(mmu) (0x984+((mmu)*0xa0)) -#define REG_MMU_MAU_IO(mmu) (0x988+((mmu)*0xa0)) - #define F_MAU_BIT_VAL(val, mau) F_BIT_VAL(val, mau) -#define REG_MMU_MAU_RW(mmu) (0x98c+((mmu)*0xa0)) -#define REG_MMU_MAU_VA(mmu) (0x990+((mmu)*0xa0)) -#define REG_MMU_MAU_ASSERT_ST(mmu) (0x994+((mmu)*0xa0)) - -#define REG_MMU_PFH_VLD_0 (0x180) -#define REG_MMU_PFH_VLD(set, way) (REG_MMU_PFH_VLD_0+(((set)>>5)<<2)+((way)<<4)) //+((set/32)*4)+(way*16) - #define F_MMU_PFH_VLD_BIT(set, way) F_BIT_SET((set)&0x1f) // set%32 - - - -//================================================================ -// SMI larb -//================================================================ - -#define SMI_ERROR_ADDR 0 -#define SMI_LARB_NR 3 - -#define SMI_LARB0_PORT_NUM 8 -#define SMI_LARB1_PORT_NUM 7 -#define SMI_LARB2_PORT_NUM 13 - -#define SMI_LARB_STAT (0x0 ) -#define SMI_LARB_IRQ_EN (0x4 ) -#define SMI_LARB_IRQ_STATUS (0x8 ) -#define SMI_LARB_SLP_CON (0xc ) -#define SMI_LARB_CON (0x10 ) -#define SMI_LARB_CON_SET (0x14 ) -#define SMI_LARB_CON_CLR (0x18 ) -#define SMI_LARB_VC_PRI_MODE (0x20 ) -#define SMI_LARB_CMD_THRT_CON (0x24 ) -#define SMI_LARB_STARV_CON (0x28 ) -#define SMI_LARB_EMI_CON (0x2C ) -#define SMI_LARB_SHARE_EN (0x30 ) -#define SMI_LARB_BWL_EN (0x50 ) -#define SMI_LARB_BWL_SOFT_EN (0x54 ) -#define SMI_LARB_BWL_CON (0x58 ) -#define SMI_LARB_OSTDL_EN (0x60 ) -#define SMI_LARB_OSTDL_SOFT_EN (0x64 ) -#define SMI_LARB_ULTRA_DIS (0x70 ) -#define SMI_LARB_PREULTRA_DIS (0x74 ) -#define SMI_LARB_FORCE_ULTRA (0x78 ) -#define SMI_LARB_FORCE_PREULTRA (0x7c ) -#define SMI_LARB_MST_GRP_SEL_L (0x80 ) -#define SMI_LARB_MST_GRP_SEL_H (0x84 ) -#define SMI_LARB_INT_PATH_SEL (0x90 ) -#define SMI_LARB_EXT_GREQ_VIO (0xa0 ) -#define SMI_LARB_INT_GREQ_VIO (0xa4 ) -#define SMI_LARB_OSTD_UDF_VIO (0xa8 ) -#define SMI_LARB_OSTD_CRS_VIO (0xac ) -#define SMI_LARB_FIFO_STAT (0xb0 ) -#define SMI_LARB_BUS_STAT (0xb4 ) -#define SMI_LARB_CMD_THRT_STAT (0xb8 ) -#define SMI_LARB_MON_REQ (0xbc ) -#define SMI_LARB_REQ_MASK (0xc0 ) -#define SMI_LARB_REQ_DET (0xc4 ) -#define SMI_LARB_EXT_ONGOING (0xc8 ) -#define SMI_LARB_INT_ONGOING (0xcc ) -#define SMI_LARB_MISC_MON0 (0xd0 ) -#define SMI_LARB_DBG_CON (0xf0 ) -#define SMI_LARB_TST_MODE (0xf4 ) -#define SMI_LARB_WRR_PORT (0x100 ) -#define SMI_LARB_BWL_PORT (0x180 ) -#define SMI_LARB_OSTDL_PORT (0x200 ) -#define SMI_LARB_OSTD_MON_PORT (0x280 ) -#define SMI_LARB_PINFO (0x300 ) -#define SMI_LARB_MON_EN (0x400 ) -#define SMI_LARB_MON_CLR (0x404 ) -#define SMI_LARB_MON_PORT (0x408 ) -#define SMI_LARB_MON_CON (0x40c ) -#define SMI_LARB_MON_ACT_CNT (0x410 ) -#define SMI_LARB_MON_REQ_CNT (0x414 ) -#define SMI_LARB_MON_BEAT_CNT (0x418 ) -#define SMI_LARB_MON_BYTE_CNT (0x41c ) -#define SMI_LARB_MON_CP_CNT (0x420 ) -#define SMI_LARB_MON_DP_CNT (0x424 ) -#define SMI_LARB_MON_OSTD_CNT (0x428 ) -#define SMI_LARB_MON_CP_MAX (0x430 ) -#define SMI_LARB_MON_COS_MAX (0x434 ) -#define SMI_LARB_MMU_EN (0xf00 ) - #define F_SMI_MMU_EN(port, en) ((en)<<((port))) - #define F_SMI_SEC_EN(port, en) ((en)<<((port))) -#define REG_SMI_LARB_DOMN_OF_PORT(port) (((port)>15) ? 0xf0c : 0xf08) - #define F_SMI_DOMN(port, domain) (((domain)&0x3)<<((((port)>15) ? (port-16) : port)<<1)) - - - - -/* -#define SMI_SHARE_EN (0x210) - #define F_SMI_SHARE_EN(port) F_BIT_SET(m4u_port_2_larb_port(port)) -#define SMI_ROUTE_SEL (0x220) - #define F_SMI_ROUTE_SEL_EMI(port) F_BIT_SET(m4u_port_2_larb_port(port)) -#define SMI_MMULOCK_EN (0x230) -*/ - - -/* =============================================================== - * SMI COMMON - * =============================================================== */ - -#define REG_OFFSET_SMI_L1LEN (0x100) -#define REG_OFFSET_SMI_L1ARB0 (0x104) -#define REG_OFFSET_SMI_L1ARB1 (0x108) -#define REG_OFFSET_SMI_L1ARB2 (0x10C) -#define REG_OFFSET_SMI_L1ARB3 (0x110) -#define REG_OFFSET_SMI_L1ARB4 (0x114) - -/* -#define REG_SMI_MON_AXI_ENA (0x1a0+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_CLR (0x1a4+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_TYPE (0x1ac+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_CON (0x1b0+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_ACT_CNT (0x1c0+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_REQ_CNT (0x1c4+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_OSTD_CNT (0x1c8+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_BEA_CNT (0x1cc+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_BYT_CNT (0x1d0+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_CP_CNT (0x1d4+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_DP_CNT (0x1d8+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_CP_MAX (0x1dc+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_COS_MAX (0x1e0+SMI_COMMON_EXT_BASE) -#define REG_SMI_L1LEN (0x200+SMI_COMMON_EXT_BASE) -#define REG_SMI_L1ARB0 (0x204+SMI_COMMON_EXT_BASE) -#define REG_SMI_L1ARB1 (0x208+SMI_COMMON_EXT_BASE) -#define REG_SMI_L1ARB2 (0x20C+SMI_COMMON_EXT_BASE) -#define REG_SMI_L1ARB3 (0x210+SMI_COMMON_EXT_BASE) -#define REG_SMI_L1ARB4 (0x214+SMI_COMMON_EXT_BASE) -#define REG_SMI_BUS_SEL (0x220+SMI_COMMON_EXT_BASE) - #define F_SMI_BUS_SEL_larb0(mmu_idx) F_VAL(mmu_idx, 1, 0) - #define F_SMI_BUS_SEL_larb1(mmu_idx) F_VAL(mmu_idx, 3, 2) - #define F_SMI_BUS_SEL_larb2(mmu_idx) F_VAL(mmu_idx, 5, 4) - #define F_SMI_BUS_SEL_larb3(mmu_idx) F_VAL(mmu_idx, 7, 6) - #define F_SMI_BUS_SEL_larb4(mmu_idx) F_VAL(mmu_idx, 9, 8) -#define REG_SMI_WRR_REG0 (0x228+SMI_COMMON_EXT_BASE) -#define REG_SMI_READ_FIFO_TH (0x230+SMI_COMMON_EXT_BASE) -#define REG_SMI_SMI_M4U_TH (0x234+SMI_COMMON_EXT_BASE) -#define REG_SMI_SMI_FIFO2_TH (0x238+SMI_COMMON_EXT_BASE) -#define REG_SMI_SMI_PREULTRA_MASK0 (0x23c+SMI_COMMON_EXT_BASE) -#define REG_SMI_SMI_PREULTRA_MASK1 (0x240+SMI_COMMON_EXT_BASE) -#define REG_SMI_DCM (0x300+SMI_COMMON_EXT_BASE) -#define REG_SMI_SMI_ELA (0x304+SMI_COMMON_EXT_BASE) -#define REG_SMI_DEBUG0 (0x400+SMI_COMMON_EXT_BASE) -#define REG_SMI_DEBUG1 (0x404+SMI_COMMON_EXT_BASE) -#define REG_SMI_DEBUG2 (0x408+SMI_COMMON_EXT_BASE) -#define REG_SMI_DUMMY (0x418+SMI_COMMON_EXT_BASE) - -*/ - -//========================================================================= -// peripheral system -//========================================================================= -#define REG_PERIAXI_BUS_CTL3 (0x208+0xf0003000) - #define F_PERI_MMU_EN(port, en) ((en)<<((port))) - - -static inline unsigned int M4U_ReadReg32(unsigned long M4uBase, unsigned long Offset) -{ - unsigned int val; - val = ioread32((void*)(M4uBase+Offset)); - - //printk("read base=0x%x, reg=0x%x, val=0x%x\n",M4uBase,Offset,val ); - return val; -} -static inline void M4U_WriteReg32(unsigned long M4uBase, unsigned long Offset, unsigned int Val) -{ - //unsigned int read; - iowrite32(Val, (void*)(M4uBase+Offset)); - mb(); - /* - read = M4U_ReadReg32(M4uBase, Offset); - if(read != Val) - { - printk("error to write base=0x%x, reg=0x%x, val=0x%x, read=0x%x\n",M4uBase,Offset, Val, read ); - } - else - { - printk("write base=0x%x, reg=0x%x, val=0x%x, read=0x%x\n",M4uBase,Offset, Val, read ); - } -*/ - -} - -static inline unsigned int COM_ReadReg32(unsigned long addr) -{ - return ioread32((void *)addr); -} - -static inline void COM_WriteReg32(unsigned long addr, unsigned int Val) -{ - iowrite32(Val, (void *)addr); - mb(); -} - - -extern unsigned long smi_reg_base_common_ext; -extern unsigned long smi_reg_base_barb0; -extern unsigned long smi_reg_base_barb1; -extern unsigned long smi_reg_base_barb2; - - -#endif //_MT6735m_SMI_REG_H__ - diff --git a/drivers/misc/mediatek/smi/mt6735/smi_reg_d3.h b/drivers/misc/mediatek/smi/mt6735/smi_reg_d3.h deleted file mode 100644 index 615b7c704..000000000 --- a/drivers/misc/mediatek/smi/mt6735/smi_reg_d3.h +++ /dev/null @@ -1,467 +0,0 @@ -#ifndef _MT6753_SMI_REG_H__ -#define _MT6753_SMI_REG_H__ - -#define SMI_COMMON_EXT_BASE (smi_reg_base_common_ext) -#define LARB0_BASE (smi_reg_base_barb0) -#define LARB1_BASE (smi_reg_base_barb1) -#define LARB2_BASE (smi_reg_base_barb2) -#define LARB3_BASE (smi_reg_base_barb3) - - -//================================================= -//common macro definitions -#define F_VAL(val,msb,lsb) (((val)&((1<<(msb-lsb+1))-1))<<lsb) -#define F_MSK(msb, lsb) F_VAL(0xffffffff, msb, lsb) -#define F_BIT_SET(bit) (1<<(bit)) -#define F_BIT_VAL(val,bit) ((!!(val))<<(bit)) -#define F_MSK_SHIFT(regval,msb,lsb) (((regval)&F_MSK(msb,lsb))>>lsb) - - -//===================================================== -//M4U register definition -//===================================================== - -#define REG_MMUg_PT_BASE (0x0) - #define F_MMUg_PT_VA_MSK 0xffff0000 -#define REG_MMUg_PT_BASE_SEC (0x4) - #define F_MMUg_PT_VA_MSK_SEC 0xffff0000 - - -#define REG_MMU_PROG_EN 0x10 - #define F_MMU0_PROG_EN 1 - #define F_MMU1_PROG_EN 2 -#define REG_MMU_PROG_VA 0x14 - #define F_PROG_VA_LOCK_BIT (1<<11) - #define F_PROG_VA_LAYER_BIT F_BIT_SET(9) - #define F_PROG_VA_SIZE16X_BIT F_BIT_SET(8) - #define F_PROG_VA_SECURE_BIT (1<<7) - #define F_PROG_VA_MASK 0xfffff000 - -#define REG_MMU_PROG_DSC 0x18 - -#define REG_MMU_INVLD (0x20) - #define F_MMU_INV_ALL 0x2 - #define F_MMU_INV_RANGE 0x1 - -#define REG_MMU_INVLD_SA (0x24) -#define REG_MMU_INVLD_EA (0x28) - - -#define REG_MMU_INVLD_SEC (0x2c) - #define F_MMU_INV_SEC_ALL 0x2 - #define F_MMU_INV_SEC_RANGE 0x1 - -#define REG_MMU_INVLD_SA_SEC (0x30) -#define REG_MMU_INVLD_EA_SEC (0x34) - -#define REG_INVLID_SEL (0x38) - #define F_MMU_INV_EN_L1 (1<<0) - #define F_MMU_INV_EN_L2 (1<<1) - - -#define REG_INVLID_SEL_SEC (0x3c) - #define F_MMU_INV_SEC_EN_L1 (1<<0) - #define F_MMU_INV_SEC_EN_L2 (1<<1) - #define F_MMU_INV_SEC_INV_DONE (1<<2) - #define F_MMU_INV_SEC_INV_INT_SET (1<<3) - #define F_MMU_INV_SEC_INV_INT_CLR (1<<4) - #define F_MMU_INV_SEC_DBG (1<<5) - - -#define REG_MMU_SEC_ABORT_INFO (0x40) -#define REG_MMU_STANDARD_AXI_MODE (0x48) - -#define REG_MMU_PRIORITY (0x4c) -#define REG_MMU_DCM_DIS (0x50) -#define REG_MMU_WR_LEN (0x54) -#define REG_MMU_HW_DEBUG (0x58) - #define F_MMU_HW_DBG_L2_SCAN_ALL F_BIT_SET(1) - #define F_MMU_HW_DBG_PFQ_BRDCST F_BIT_SET(0) - -#define REG_MMU_NON_BLOCKING_DIS 0x5C - #define F_MMU_NON_BLOCK_DISABLE_BIT 1 - #define F_MMU_NON_BLOCK_HALF_ENTRY_BIT 2 - -#define REG_MMU_LEGACY_4KB_MODE (0x60) - -#define REG_MMU_PFH_DIST0 0x80 -#define REG_MMU_PFH_DIST1 0x84 -#define REG_MMU_PFH_DIST2 0x88 -#define REG_MMU_PFH_DIST3 0x8c -#define REG_MMU_PFH_DIST4 0x90 -#define REG_MMU_PFH_DIST5 0x94 -#define REG_MMU_PFH_DIST6 0x98 - -#define REG_MMU_PFH_DIST(port) (0x80+(((port)>>3)<<2)) - #define F_MMU_PFH_DIST_VAL(port,val) ((val&0xf)<<(((port)&0x7)<<2)) - #define F_MMU_PFH_DIST_MASK(port) F_MMU_PFH_DIST_VAL((port), 0xf) - -#define REG_MMU_PFH_DIR0 0xF0 -#define REG_MMU_PFH_DIR1 0xF4 -#define REG_MMU_PFH_DIR(port) (((port)<32) ? REG_MMU_PFH_DIR0: REG_MMU_PFH_DIR1) -#define F_MMU_PFH_DIR(port,val) ((!!(val))<<((port)&0x1f)) - - -#define REG_MMU_READ_ENTRY 0x100 - #define F_READ_ENTRY_EN F_BIT_SET(31) - #define F_READ_ENTRY_MM1_MAIN F_BIT_SET(26) - #define F_READ_ENTRY_MM0_MAIN F_BIT_SET(25) - #define F_READ_ENTRY_MMx_MAIN(id) F_BIT_SET(25+id) - #define F_READ_ENTRY_PFH F_BIT_SET(24) - #define F_READ_ENTRY_MAIN_IDX(idx) F_VAL(idx,21,16) - #define F_READ_ENTRY_PFH_IDX(idx) F_VAL(idx,11,5) - //#define F_READ_ENTRY_PFH_HI_LO(high) F_VAL(high, 4,4) - //#define F_READ_ENTRY_PFH_PAGE(page) F_VAL(page, 3,2) - #define F_READ_ENTRY_PFH_PAGE_IDX(idx) F_VAL(idx, 4, 2) - #define F_READ_ENTRY_PFH_WAY(way) F_VAL(way, 1,0) - -#define REG_MMU_DES_RDATA 0x104 - -#define REG_MMU_PFH_TAG_RDATA 0x108 - #define F_PFH_TAG_VA_GET(mmu,tag) (F_MSK_SHIFT(tag, 14, 4)<<(MMU_SET_MSB_OFFSET(mmu)+1)) - #define F_PFH_TAG_LAYER_BIT F_BIT_SET(3) - #define F_PFH_TAG_16X_BIT F_BIT_SET(2) //this bit is always 0 -- cost down. - #define F_PFH_TAG_SEC_BIT F_BIT_SET(1) - #define F_PFH_TAG_AUTO_PFH F_BIT_SET(0) - - -// tag releated macro - //#define MMU0_SET_ORDER 7 - //#define MMU1_SET_ORDER 6 - #define MMU_SET_ORDER(mmu) (7-(mmu)) - #define MMU_SET_NR(mmu) (1<<MMU_SET_ORDER(mmu)) - #define MMU_SET_LSB_OFFSET 15 - #define MMU_SET_MSB_OFFSET(mmu) (MMU_SET_LSB_OFFSET+MMU_SET_ORDER(mmu)-1) - #define MMU_PFH_VA_TO_SET(mmu,va) F_MSK_SHIFT(va, MMU_SET_MSB_OFFSET(mmu), MMU_SET_LSB_OFFSET) - - #define MMU_PAGE_PER_LINE 8 - #define MMU_WAY_NR 4 - #define MMU_PFH_TOTAL_LINE(mmu) (MMU_SET_NR(mmu)*MMU_WAY_NR) - - -#define REG_MMU_CTRL_REG 0x110 - #define F_MMU_CTRL_PFH_DIS(dis) F_BIT_VAL(dis, 0) - #define F_MMU_CTRL_TLB_WALK_DIS(dis) F_BIT_VAL(dis, 1) - #define F_MMU_CTRL_MONITOR_EN(en) F_BIT_VAL(en, 2) - #define F_MMU_CTRL_MONITOR_CLR(clr) F_BIT_VAL(clr, 3) - #define F_MMU_CTRL_PFH_RT_RPL_MODE(mod) F_BIT_VAL(mod, 4) - #define F_MMU_CTRL_TF_PROT_VAL(prot) F_VAL(prot, 6, 5) - #define F_MMU_CTRL_TF_PROT_MSK F_MSK(6,5) - #define F_MMU_CTRL_INT_HANG_en(en) F_BIT_VAL(en, 7) - #define F_MMU_CTRL_COHERE_EN(en) F_BIT_VAL(en, 8) - #define F_MMU_CTRL_IN_ORDER_WR(en) F_BIT_VAL(en, 9) - #define F_MMU_CTRL_MAIN_TLB_SHARE_ALL(en) F_BIT_VAL(en, 10) - - -#define REG_MMU_IVRP_PADDR 0x114 - #define F_MMU_IVRP_PA_SET(PA) (PA>>1) - #define F_MMU_IVRP_8G_PA_SET(PA) ((PA>>1)|(1<<31)) - -#define REG_MMU_INT_L2_CONTROL 0x120 - #define F_INT_L2_CLR_BIT (1<<12) - #define F_INT_L2_MULTI_HIT_FAULT F_BIT_SET(0) - #define F_INT_L2_TABLE_WALK_FAULT F_BIT_SET(1) - #define F_INT_L2_PFH_DMA_FIFO_OVERFLOW F_BIT_SET(2) - #define F_INT_L2_MISS_DMA_FIFO_OVERFLOW F_BIT_SET(3) - #define F_INT_L2_INVALD_DONE F_BIT_SET(4) - #define F_INT_L2_PFH_IN_OUT_FIFO_ERROR F_BIT_SET(5) - #define F_INT_L2_MISS_FIFO_ERR F_BIT_SET(6) - -#define REG_MMU_INT_MAIN_CONTROL 0x124 - #define F_INT_TRANSLATION_FAULT(MMU) F_BIT_SET(0+(((MMU)<<1)|((MMU)<<2))) - #define F_INT_MAIN_MULTI_HIT_FAULT(MMU) F_BIT_SET(1+(((MMU)<<1)|((MMU)<<2))) - #define F_INT_INVALID_PHYSICAL_ADDRESS_FAULT(MMU) F_BIT_SET(2+(((MMU)<<1)|((MMU)<<2))) - #define F_INT_ENTRY_REPLACEMENT_FAULT(MMU) F_BIT_SET(3+(((MMU)<<1)|((MMU)<<2))) - #define F_INT_TLB_MISS_FAULT(MMU) F_BIT_SET(5+(((MMU)<<1)|((MMU)<<2))) - #define F_INT_PFH_FIFO_ERR(MMU) F_BIT_SET(6+(((MMU)<<1)|((MMU)<<2))) - - #define F_INT_MAU(mmu, set) F_BIT_SET(14+(set)+(mmu<<2)) //(14+(set)+(mmu*4)) - - #define F_INT_MMU0_MAIN_MSK F_MSK(6, 0) - #define F_INT_MMU1_MAIN_MSK F_MSK(13, 7) - #define F_INT_MMU0_MAU_MSK F_MSK(17, 14) - #define F_INT_MMU1_MAU_MSK F_MSK(21, 18) - -#define REG_MMU_CPE_DONE_SEC 0x128 -#define REG_MMU_CPE_DONE 0x12C - -#define REG_MMU_L2_FAULT_ST 0x130 - #define F_INT_L2_MISS_OUT_FIFO_ERROR F_BIT_SET(7) - #define F_INT_L2_MISS_IN_FIFO_ERR F_BIT_SET(8) -#define REG_MMU_MAIN_FAULT_ST 0x134 - -#define REG_MMU_TBWALK_FAULT_VA 0x138 - #define F_MMU_TBWALK_FAULT_VA_MSK F_MSK(31, 12) - #define F_MMU_TBWALK_FAULT_LAYER(regval) F_MSK_SHIFT(regval, 0, 0) - -#define REG_MMU_FAULT_VA(mmu) (0x13c+((mmu)<<3)) - #define F_MMU_FAULT_VA_MSK F_MSK(31, 12) - #define F_MMU_FAULT_VA_WRITE_BIT F_BIT_SET(1) - #define F_MMU_FAULT_VA_LAYER_BIT F_BIT_SET(0) - -#define REG_MMU_INVLD_PA(mmu) (0x140+((mmu)<<3)) -#define REG_MMU_INT_ID(mmu) (0x150+((mmu)<<2)) - -#define REG_MMU_PF_MSCNT 0x160 -#define REG_MMU_PF_CNT 0x164 -#define REG_MMU_ACC_CNT(mmu) (0x168+(((mmu)<<3)|((mmu)<<2))) //(0x168+((mmu)*12) -#define REG_MMU_MAIN_MSCNT(mmu) (0x16c+(((mmu)<<3)|((mmu)<<2))) -#define REG_MMU_RS_PERF_CNT(mmu) (0x170+(((mmu)<<3)|((mmu)<<2))) - -#define MMU01_SQ_OFFSET (0x600-0x300) -#define REG_MMU_SQ_START(mmu,x) (0x300+((x)<<3)+((mmu)*MMU01_SQ_OFFSET)) - #define F_SQ_VA_MASK F_MSK(31, 18) - #define F_SQ_EN_BIT (1<<17) - //#define F_SQ_MULTI_ENTRY_VAL(x) (((x)&0xf)<<13) -#define REG_MMU_SQ_END(mmu, x) (0x304+((x)<<3)+((mmu)*MMU01_SQ_OFFSET)) - - -#define MMU_TOTAL_RS_NR 8 -#define REG_MMU_RSx_VA(mmu,x) (0x380+((x)<<4)+((mmu)*MMU01_SQ_OFFSET)) - #define F_MMU_RSx_VA_GET(regval) ((regval)&F_MSK(31, 12)) - #define F_MMU_RSx_VA_VALID(regval) F_MSK_SHIFT(regval, 11, 11) - #define F_MMU_RSx_VA_PID(regval) F_MSK_SHIFT(regval, 9, 0) - -#define REG_MMU_RSx_PA(mmu,x) (0x384+((x)<<4)+((mmu)*MMU01_SQ_OFFSET)) - #define F_MMU_RSx_PA_GET(regval) ((regval)&F_MSK(31, 12)) - #define F_MMU_RSx_PA_VALID(regval) F_MSK_SHIFT(regval, 1, 0) - -#define REG_MMU_RSx_2ND_BASE(mmu,x) (0x388+((x)<<4)+((mmu)*MMU01_SQ_OFFSET)) - -#define REG_MMU_RSx_ST(mmu,x) (0x38c+((x)<<4)+((mmu)*MMU01_SQ_OFFSET)) - #define F_MMU_RSx_ST_LID(regval) F_MSK_SHIFT(regval, 21, 20) - #define F_MMU_RSx_ST_WRT(regval) F_MSK_SHIFT(regval, 12, 12) - #define F_MMU_RSx_ST_OTHER(regval) F_MSK_SHIFT(regval, 8, 0) - -#define REG_MMU_MAIN_TAG(mmu,x) (0x500+((x)<<2)+((mmu)*MMU01_SQ_OFFSET)) - #define F_MAIN_TLB_VA_MSK F_MSK(31, 12) - #define F_MAIN_TLB_LOCK_BIT (1<<11) - #define F_MAIN_TLB_VALID_BIT (1<<10) - #define F_MAIN_TLB_LAYER_BIT F_BIT_SET(9) - #define F_MAIN_TLB_16X_BIT F_BIT_SET(8) - #define F_MAIN_TLB_SEC_BIT F_BIT_SET(7) - #define F_MAIN_TLB_INV_DES_BIT (1<<6) - #define F_MAIN_TLB_SQ_EN_BIT (1<<5) - #define F_MAIN_TLB_SQ_INDEX_MSK F_MSK(4,1) - #define F_MAIN_TLB_SQ_INDEX_GET(regval) F_MSK_SHIFT(regval, 4, 1) - - -#define REG_MMU_MAU_START(mmu,mau) (0x900+((mau)*0x20)+((mmu)*0xa0)) -#define REG_MMU_MAU_START_BIT32(mmu,mau) (0x904+((mau)*0x20)+((mmu)*0xa0)) -#define REG_MMU_MAU_END(mmu,mau) (0x908+((mau)*0x20)+((mmu)*0xa0)) -#define REG_MMU_MAU_END_BIT32(mmu,mau) (0x90C+((mau)*0x20)+((mmu)*0xa0)) -#define REG_MMU_MAU_PORT_EN(mmu,mau) (0x910+((mau)*0x20)+((mmu)*0xa0)) -#define REG_MMU_MAU_ASSERT_ID(mmu,mau) (0x914+((mau)*0x20)+((mmu)*0xa0)) -#define REG_MMU_MAU_ADDR(mmu,mau) (0x918+((mau)*0x20)+((mmu)*0xa0)) -#define REG_MMU_MAU_ADDR_BIT32(mmu,mau) (0x91C+((mau)*0x20)+((mmu)*0xa0)) - -#define REG_MMU_MAU_LARB_EN(mmu) (0x980+((mmu)*0xa0)) - #define F_MAU_LARB_VAL(mau,larb) ((larb)<<(mau*8)) - #define F_MAU_LARB_MSK(mau) (0xff<<(mau*8)) -#define REG_MMU_MAU_CLR(mmu) (0x984+((mmu)*0xa0)) -#define REG_MMU_MAU_IO(mmu) (0x988+((mmu)*0xa0)) - #define F_MAU_BIT_VAL(val, mau) F_BIT_VAL(val, mau) -#define REG_MMU_MAU_RW(mmu) (0x98c+((mmu)*0xa0)) -#define REG_MMU_MAU_VA(mmu) (0x990+((mmu)*0xa0)) -#define REG_MMU_MAU_ASSERT_ST(mmu) (0x994+((mmu)*0xa0)) - -#define REG_MMU_PFH_VLD_0 (0x180) -#define REG_MMU_PFH_VLD(set, way) (REG_MMU_PFH_VLD_0+(((set)>>5)<<2)+((way)<<4)) //+((set/32)*4)+(way*16) - #define F_MMU_PFH_VLD_BIT(set, way) F_BIT_SET((set)&0x1f) // set%32 - - - -//================================================================ -// SMI larb -//================================================================ - -#define SMI_ERROR_ADDR 0 -#define SMI_LARB_NR 4 - -#define SMI_LARB0_PORT_NUM 10 -#define SMI_LARB1_PORT_NUM 7 -#define SMI_LARB2_PORT_NUM 21 -#define SMI_LARB3_PORT_NUM 13 - -#define SMI_LARB_STAT (0x0 ) -#define SMI_LARB_IRQ_EN (0x4 ) -#define SMI_LARB_IRQ_STATUS (0x8 ) -#define SMI_LARB_SLP_CON (0xc ) -#define SMI_LARB_CON (0x10 ) -#define SMI_LARB_CON_SET (0x14 ) -#define SMI_LARB_CON_CLR (0x18 ) -#define SMI_LARB_VC_PRI_MODE (0x20 ) -#define SMI_LARB_CMD_THRT_CON (0x24 ) -#define SMI_LARB_STARV_CON (0x28 ) -#define SMI_LARB_EMI_CON (0x2C ) -#define SMI_LARB_SHARE_EN (0x30 ) -#define SMI_LARB_BWL_EN (0x50 ) -#define SMI_LARB_BWL_SOFT_EN (0x54 ) -#define SMI_LARB_BWL_CON (0x58 ) -#define SMI_LARB_OSTDL_EN (0x60 ) -#define SMI_LARB_OSTDL_SOFT_EN (0x64 ) -#define SMI_LARB_ULTRA_DIS (0x70 ) -#define SMI_LARB_PREULTRA_DIS (0x74 ) -#define SMI_LARB_FORCE_ULTRA (0x78 ) -#define SMI_LARB_FORCE_PREULTRA (0x7c ) -#define SMI_LARB_MST_GRP_SEL_L (0x80 ) -#define SMI_LARB_MST_GRP_SEL_H (0x84 ) -#define SMI_LARB_INT_PATH_SEL (0x90 ) -#define SMI_LARB_EXT_GREQ_VIO (0xa0 ) -#define SMI_LARB_INT_GREQ_VIO (0xa4 ) -#define SMI_LARB_OSTD_UDF_VIO (0xa8 ) -#define SMI_LARB_OSTD_CRS_VIO (0xac ) -#define SMI_LARB_FIFO_STAT (0xb0 ) -#define SMI_LARB_BUS_STAT (0xb4 ) -#define SMI_LARB_CMD_THRT_STAT (0xb8 ) -#define SMI_LARB_MON_REQ (0xbc ) -#define SMI_LARB_REQ_MASK (0xc0 ) -#define SMI_LARB_REQ_DET (0xc4 ) -#define SMI_LARB_EXT_ONGOING (0xc8 ) -#define SMI_LARB_INT_ONGOING (0xcc ) -#define SMI_LARB_MISC_MON0 (0xd0 ) -#define SMI_LARB_DBG_CON (0xf0 ) -#define SMI_LARB_TST_MODE (0xf4 ) -#define SMI_LARB_WRR_PORT (0x100 ) -#define SMI_LARB_BWL_PORT (0x180 ) -#define SMI_LARB_OSTDL_PORT (0x200 ) -#define SMI_LARB_OSTD_MON_PORT (0x280 ) -#define SMI_LARB_PINFO (0x300 ) -#define SMI_LARB_MON_EN (0x400 ) -#define SMI_LARB_MON_CLR (0x404 ) -#define SMI_LARB_MON_PORT (0x408 ) -#define SMI_LARB_MON_CON (0x40c ) -#define SMI_LARB_MON_ACT_CNT (0x410 ) -#define SMI_LARB_MON_REQ_CNT (0x414 ) -#define SMI_LARB_MON_BEAT_CNT (0x418 ) -#define SMI_LARB_MON_BYTE_CNT (0x41c ) -#define SMI_LARB_MON_CP_CNT (0x420 ) -#define SMI_LARB_MON_DP_CNT (0x424 ) -#define SMI_LARB_MON_OSTD_CNT (0x428 ) -#define SMI_LARB_MON_CP_MAX (0x430 ) -#define SMI_LARB_MON_COS_MAX (0x434 ) -#define SMI_LARB_MMU_EN (0xf00 ) - #define F_SMI_MMU_EN(port, en) ((en)<<((port))) - #define F_SMI_SEC_EN(port, en) ((en)<<((port))) -#define REG_SMI_LARB_DOMN_OF_PORT(port) (((port)>15) ? 0xf0c : 0xf08) - #define F_SMI_DOMN(port, domain) (((domain)&0x3)<<((((port)>15) ? (port-16) : port)<<1)) - - - - -/* -#define SMI_SHARE_EN (0x210) - #define F_SMI_SHARE_EN(port) F_BIT_SET(m4u_port_2_larb_port(port)) -#define SMI_ROUTE_SEL (0x220) - #define F_SMI_ROUTE_SEL_EMI(port) F_BIT_SET(m4u_port_2_larb_port(port)) -#define SMI_MMULOCK_EN (0x230) -*/ - - -/* =============================================================== - * SMI COMMON - * =============================================================== */ - -#define REG_OFFSET_SMI_L1LEN (0x100) -#define REG_OFFSET_SMI_L1ARB0 (0x104) -#define REG_OFFSET_SMI_L1ARB1 (0x108) -#define REG_OFFSET_SMI_L1ARB2 (0x10C) -#define REG_OFFSET_SMI_L1ARB3 (0x110) -#define REG_OFFSET_SMI_L1ARB4 (0x114) - -/* -#define REG_SMI_MON_AXI_ENA (0x1a0+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_CLR (0x1a4+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_TYPE (0x1ac+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_CON (0x1b0+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_ACT_CNT (0x1c0+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_REQ_CNT (0x1c4+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_OSTD_CNT (0x1c8+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_BEA_CNT (0x1cc+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_BYT_CNT (0x1d0+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_CP_CNT (0x1d4+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_DP_CNT (0x1d8+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_CP_MAX (0x1dc+SMI_COMMON_EXT_BASE) -#define REG_SMI_MON_AXI_COS_MAX (0x1e0+SMI_COMMON_EXT_BASE) -#define REG_SMI_L1LEN (0x200+SMI_COMMON_EXT_BASE) -#define REG_SMI_L1ARB0 (0x204+SMI_COMMON_EXT_BASE) -#define REG_SMI_L1ARB1 (0x208+SMI_COMMON_EXT_BASE) -#define REG_SMI_L1ARB2 (0x20C+SMI_COMMON_EXT_BASE) -#define REG_SMI_L1ARB3 (0x210+SMI_COMMON_EXT_BASE) -#define REG_SMI_L1ARB4 (0x214+SMI_COMMON_EXT_BASE) -#define REG_SMI_BUS_SEL (0x220+SMI_COMMON_EXT_BASE) - #define F_SMI_BUS_SEL_larb0(mmu_idx) F_VAL(mmu_idx, 1, 0) - #define F_SMI_BUS_SEL_larb1(mmu_idx) F_VAL(mmu_idx, 3, 2) - #define F_SMI_BUS_SEL_larb2(mmu_idx) F_VAL(mmu_idx, 5, 4) - #define F_SMI_BUS_SEL_larb3(mmu_idx) F_VAL(mmu_idx, 7, 6) - #define F_SMI_BUS_SEL_larb4(mmu_idx) F_VAL(mmu_idx, 9, 8) -#define REG_SMI_WRR_REG0 (0x228+SMI_COMMON_EXT_BASE) -#define REG_SMI_READ_FIFO_TH (0x230+SMI_COMMON_EXT_BASE) -#define REG_SMI_SMI_M4U_TH (0x234+SMI_COMMON_EXT_BASE) -#define REG_SMI_SMI_FIFO2_TH (0x238+SMI_COMMON_EXT_BASE) -#define REG_SMI_SMI_PREULTRA_MASK0 (0x23c+SMI_COMMON_EXT_BASE) -#define REG_SMI_SMI_PREULTRA_MASK1 (0x240+SMI_COMMON_EXT_BASE) -#define REG_SMI_DCM (0x300+SMI_COMMON_EXT_BASE) -#define REG_SMI_SMI_ELA (0x304+SMI_COMMON_EXT_BASE) -#define REG_SMI_DEBUG0 (0x400+SMI_COMMON_EXT_BASE) -#define REG_SMI_DEBUG1 (0x404+SMI_COMMON_EXT_BASE) -#define REG_SMI_DEBUG2 (0x408+SMI_COMMON_EXT_BASE) -#define REG_SMI_DUMMY (0x418+SMI_COMMON_EXT_BASE) - -*/ - -//========================================================================= -// peripheral system -//========================================================================= -#define REG_PERIAXI_BUS_CTL3 (0x208+0xf0003000) - #define F_PERI_MMU_EN(port, en) ((en)<<((port))) - - -static inline unsigned int M4U_ReadReg32(unsigned long M4uBase, unsigned long Offset) -{ - unsigned int val; - val = ioread32((void*)(M4uBase+Offset)); - - //printk("read base=0x%x, reg=0x%x, val=0x%x\n",M4uBase,Offset,val ); - return val; -} -static inline void M4U_WriteReg32(unsigned long M4uBase, unsigned long Offset, unsigned int Val) -{ - //unsigned int read; - iowrite32(Val, (void*)(M4uBase+Offset)); - mb(); - /* - read = M4U_ReadReg32(M4uBase, Offset); - if(read != Val) - { - printk("error to write base=0x%x, reg=0x%x, val=0x%x, read=0x%x\n",M4uBase,Offset, Val, read ); - } - else - { - printk("write base=0x%x, reg=0x%x, val=0x%x, read=0x%x\n",M4uBase,Offset, Val, read ); - } -*/ - -} - -static inline unsigned int COM_ReadReg32(unsigned long addr) -{ - return ioread32((void *)addr); -} - -static inline void COM_WriteReg32(unsigned long addr, unsigned int Val) -{ - iowrite32(Val, (void *)addr); - mb(); -} - - -extern unsigned long smi_reg_base_common_ext; -extern unsigned long smi_reg_base_barb0; -extern unsigned long smi_reg_base_barb1; -extern unsigned long smi_reg_base_barb2; -extern unsigned long smi_reg_base_barb3; - - -#endif //_MT6753_SMI_REG_H__ - diff --git a/drivers/misc/mediatek/smi/smi_common.c b/drivers/misc/mediatek/smi/smi_common.c new file mode 100644 index 000000000..7237b2638 --- /dev/null +++ b/drivers/misc/mediatek/smi/smi_common.c @@ -0,0 +1,2003 @@ +#include <linux/of.h> +#include <linux/of_irq.h> +#include <linux/of_address.h> +#include <linux/kobject.h> + +#include <linux/uaccess.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/cdev.h> +#include <linux/mm.h> +#include <linux/vmalloc.h> +#include <linux/slab.h> +#include <linux/aee.h> + +/* Define SMI_INTERNAL_CCF_SUPPORT when CCF needs to be enabled */ +#if !defined(CONFIG_MTK_LEGACY) +#define SMI_INTERNAL_CCF_SUPPORT +#endif + +#if defined(SMI_INTERNAL_CCF_SUPPORT) +#include <linux/clk.h> +/* for ccf clk CB */ +#if defined(SMI_D1) +#include "clk-mt6735-pg.h" +#elif defined(SMI_J) +#include "clk-mt6755-pg.h" +#endif +/* notify clk is enabled/disabled for m4u*/ +#include "m4u.h" +#else +#include <mach/mt_clkmgr.h> +#endif /* defined(SMI_INTERNAL_CCF_SUPPORT) */ + +#include <asm/io.h> + +#include <linux/ioctl.h> +#include <linux/fs.h> + +#if IS_ENABLED(CONFIG_COMPAT) +#include <linux/uaccess.h> +#include <linux/compat.h> +#endif + +#include <mach/mt_smi.h> + + +#include "smi_reg.h" +#include "smi_common.h" +#include "smi_debug.h" +#include "smi_info_util.h" +#include "smi_configuration.h" +#if defined(SMI_D1) || defined(SMI_D2) || defined(SMI_D3) +#include "mmdvfs_mgr.h" +#endif +#undef pr_fmt +#define pr_fmt(fmt) "[SMI]" fmt + +#define SMI_LOG_TAG "SMI" + +#define LARB_BACKUP_REG_SIZE 128 +#define SMI_COMMON_BACKUP_REG_NUM 7 + +#define SF_HWC_PIXEL_MAX_NORMAL (1920 * 1080 * 7) +#define SF_HWC_PIXEL_MAX_VR (1920 * 1080 * 4 + 1036800) /* 4.5 FHD size */ +#define SF_HWC_PIXEL_MAX_VP (1920 * 1080 * 7) +#define SF_HWC_PIXEL_MAX_ALWAYS_GPU (1920 * 1080 * 1) + +/* debug level */ +static unsigned int smi_debug_level; + +#define SMIDBG(level, x...) \ + do { \ + if (smi_debug_level >= (level)) \ + SMIMSG(x); \ + } while (0) + +#define DEFINE_ATTR_RO(_name)\ + static struct kobj_attribute _name##_attr = {\ + .attr = {\ + .name = #_name,\ + .mode = 0444,\ + },\ + .show = _name##_show,\ + } + +#define DEFINE_ATTR_RW(_name)\ + static struct kobj_attribute _name##_attr = {\ + .attr = {\ + .name = #_name,\ + .mode = 0644,\ + },\ + .show = _name##_show,\ + .store = _name##_store,\ + } + +#define __ATTR_OF(_name) (&_name##_attr.attr) + +struct SMI_struct { + spinlock_t SMI_lock; + unsigned int pu4ConcurrencyTable[SMI_BWC_SCEN_CNT]; /* one bit represent one module */ +}; + +static struct SMI_struct g_SMIInfo; + +/* LARB BASE ADDRESS */ +unsigned long gLarbBaseAddr[SMI_LARB_NR] = { 0 }; + +/* DT porting */ +unsigned long smi_reg_base_common_ext = 0; +unsigned long smi_reg_base_barb0 = 0; +unsigned long smi_reg_base_barb1 = 0; +unsigned long smi_reg_base_barb2 = 0; +unsigned long smi_reg_base_barb3 = 0; + + + + +char *smi_get_region_name(unsigned int region_indx); + + +static struct smi_device *smi_dev; + +static struct device *smiDeviceUevent; + +static struct cdev *pSmiDev; + +#define SMI_COMMON_REG_INDX 0 +#define SMI_LARB0_REG_INDX 1 +#define SMI_LARB1_REG_INDX 2 +#define SMI_LARB2_REG_INDX 3 +#define SMI_LARB3_REG_INDX 4 + +#if defined(SMI_D2) +#define SMI_REG_REGION_MAX 4 + +static const unsigned int larb_port_num[SMI_LARB_NR] = { SMI_LARB0_PORT_NUM, + SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM +}; + +static unsigned char larb_vc_setting[SMI_LARB_NR] = { 0, 2, 1 }; + +static unsigned short int larb0_port_backup[SMI_LARB0_PORT_NUM]; +static unsigned short int larb1_port_backup[SMI_LARB1_PORT_NUM]; +static unsigned short int larb2_port_backup[SMI_LARB2_PORT_NUM]; + +static unsigned short int *larb_port_backup[SMI_LARB_NR] = { + larb0_port_backup, larb1_port_backup, larb2_port_backup +}; + + +#elif defined(SMI_D1) +#define SMI_REG_REGION_MAX 5 + +static const unsigned int larb_port_num[SMI_LARB_NR] = { SMI_LARB0_PORT_NUM, + SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM +}; + +static unsigned char larb_vc_setting[SMI_LARB_NR] = { 0, 2, 0, 1 }; + +static unsigned short int larb0_port_backup[SMI_LARB0_PORT_NUM]; +static unsigned short int larb1_port_backup[SMI_LARB1_PORT_NUM]; +static unsigned short int larb2_port_backup[SMI_LARB2_PORT_NUM]; +static unsigned short int larb3_port_backup[SMI_LARB3_PORT_NUM]; +static unsigned short int *larb_port_backup[SMI_LARB_NR] = { + larb0_port_backup, larb1_port_backup, larb2_port_backup, larb3_port_backup +}; + + +#elif defined(SMI_D3) +#define SMI_REG_REGION_MAX 5 + +static const unsigned int larb_port_num[SMI_LARB_NR] = { SMI_LARB0_PORT_NUM, + SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM +}; + +static unsigned short int larb0_port_backup[SMI_LARB0_PORT_NUM]; +static unsigned short int larb1_port_backup[SMI_LARB1_PORT_NUM]; +static unsigned short int larb2_port_backup[SMI_LARB2_PORT_NUM]; +static unsigned short int larb3_port_backup[SMI_LARB3_PORT_NUM]; + +static unsigned char larb_vc_setting[SMI_LARB_NR] = { 0, 2, 1, 1 }; + +static unsigned short int *larb_port_backup[SMI_LARB_NR] = { + larb0_port_backup, larb1_port_backup, larb2_port_backup, larb3_port_backup +}; +#elif defined(SMI_R) + +#define SMI_REG_REGION_MAX 3 + +static const unsigned int larb_port_num[SMI_LARB_NR] = { SMI_LARB0_PORT_NUM, + SMI_LARB1_PORT_NUM +}; + +static unsigned short int larb0_port_backup[SMI_LARB0_PORT_NUM]; +static unsigned short int larb1_port_backup[SMI_LARB1_PORT_NUM]; + +static unsigned char larb_vc_setting[SMI_LARB_NR] = { 0, 2 }; + +static unsigned short int *larb_port_backup[SMI_LARB_NR] = { + larb0_port_backup, larb1_port_backup +}; + +#elif defined(SMI_J) +#define SMI_REG_REGION_MAX 5 + + +static const unsigned int larb_port_num[SMI_LARB_NR] = { SMI_LARB0_PORT_NUM, + SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM +}; + +static unsigned short int larb0_port_backup[SMI_LARB0_PORT_NUM]; +static unsigned short int larb1_port_backup[SMI_LARB1_PORT_NUM]; +static unsigned short int larb2_port_backup[SMI_LARB2_PORT_NUM]; +static unsigned short int larb3_port_backup[SMI_LARB3_PORT_NUM]; + +static unsigned char larb_vc_setting[SMI_LARB_NR] = { 1, 2, 1, 1 }; + +static unsigned short int *larb_port_backup[SMI_LARB_NR] = { larb0_port_backup, + larb1_port_backup, larb2_port_backup, larb3_port_backup +}; +#endif + +static unsigned long gSMIBaseAddrs[SMI_REG_REGION_MAX]; + +/* SMI COMMON register list to be backuped */ +static unsigned short g_smi_common_backup_reg_offset[SMI_COMMON_BACKUP_REG_NUM] = { 0x100, 0x104, + 0x108, 0x10c, 0x110, 0x230, 0x234 +}; + +static unsigned int g_smi_common_backup[SMI_COMMON_BACKUP_REG_NUM]; +struct smi_device { + struct device *dev; + void __iomem *regs[SMI_REG_REGION_MAX]; +#if defined(SMI_INTERNAL_CCF_SUPPORT) + struct clk *smi_common_clk; + struct clk *smi_larb0_clk; + struct clk *img_larb2_clk; + struct clk *vdec0_vdec_clk; + struct clk *vdec1_larb_clk; + struct clk *venc_larb_clk; + struct clk *venc_venc_clk; + struct clk *larb0_mtcmos; + struct clk *larb1_mtcmos; + struct clk *larb2_mtcmos; + struct clk *larb3_mtcmos; +#endif +}; + + +/* To keep the HW's init value */ +static int is_default_value_saved; +static unsigned int default_val_smi_l1arb[SMI_LARB_NR] = { 0 }; + +static unsigned int wifi_disp_transaction; + + +/* larb backuprestore */ +#if defined(SMI_INTERNAL_CCF_SUPPORT) +static bool fglarbcallback; +#endif +/* tuning mode, 1 for register ioctl */ +static unsigned int smi_tuning_mode; +#if defined(SMI_J) +static unsigned int disable_freq_hopping; +static unsigned int disable_freq_mux = 1; +static unsigned int force_max_mmsys_clk; +static unsigned int force_camera_hpm; +#endif +static unsigned int smi_profile = SMI_BWC_SCEN_NORMAL; + +static unsigned int *pLarbRegBackUp[SMI_LARB_NR]; +static int g_bInited; + +MTK_SMI_BWC_MM_INFO g_smi_bwc_mm_info = { + 0, 0, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, 0, 0, + SF_HWC_PIXEL_MAX_NORMAL +}; + +char *smi_port_name[][21] = { + { /* 0 MMSYS */ + "disp_ovl0", "disp_rdma0", "disp_rdma1", "disp_wdma0", "disp_ovl1", + "disp_rdma2", "disp_wdma1", "disp_od_r", "disp_od_w", "mdp_rdma0", + "mdp_rdma1", "mdp_wdma", "mdp_wrot0", "mdp_wrot1"}, + { /* 1 VDEC */ "hw_vdec_mc_ext", "hw_vdec_pp_ext", "hw_vdec_ufo_ext", "hw_vdec_vld_ext", + "hw_vdec_vld2_ext", "hw_vdec_avc_mv_ext", "hw_vdec_pred_rd_ext", + "hw_vdec_pred_wr_ext", "hw_vdec_ppwrap_ext"}, + { /* 2 ISP */ "imgo", "rrzo", "aao", "lcso", "esfko", "imgo_d", "lsci", "lsci_d", "bpci", + "bpci_d", "ufdi", "imgi", "img2o", "img3o", "vipi", "vip2i", "vip3i", + "lcei", "rb", "rp", "wr"}, + { /* 3 VENC */ "venc_rcpu", "venc_rec", "venc_bsdma", "venc_sv_comv", "venc_rd_comv", + "jpgenc_bsdma", "remdc_sdma", "remdc_bsdma", "jpgenc_rdma", "jpgenc_sdma", + "jpgdec_wdma", "jpgdec_bsdma", "venc_cur_luma", "venc_cur_chroma", + "venc_ref_luma", "venc_ref_chroma", "remdc_wdma", "venc_nbm_rdma", + "venc_nbm_wdma"}, + { /* 4 MJC */ "mjc_mv_rd", "mjc_mv_wr", "mjc_dma_rd", "mjc_dma_wr"} +}; + + + +static unsigned long get_register_base(int i); + + +#if defined(SMI_INTERNAL_CCF_SUPPORT) +static struct clk *get_smi_clk(char *smi_clk_name); +#endif + +#if IS_ENABLED(CONFIG_COMPAT) +static long MTK_SMI_COMPAT_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +#else +#define MTK_SMI_COMPAT_ioctl NULL +#endif + + +/* Use this function to get base address of Larb resgister */ +/* to support error checking */ +unsigned long get_larb_base_addr(int larb_id) +{ + if (larb_id >= SMI_LARB_NR || larb_id < 0) + return SMI_ERROR_ADDR; + else + return gLarbBaseAddr[larb_id]; + +} + +/* 0 for common, 1 for larb0, 2 for larb1... */ +unsigned long get_smi_base_addr(int larb_id) +{ + if (larb_id >= SMI_LARB_NR || larb_id < 0) + return SMI_ERROR_ADDR; + else + return gSMIBaseAddrs[larb_id]; +} +EXPORT_SYMBOL(get_smi_base_addr); + + +#if defined(SMI_INTERNAL_CCF_SUPPORT) +struct clk *get_smi_clk(char *smi_clk_name) +{ + struct clk *smi_clk_ptr = NULL; + + smi_clk_ptr = devm_clk_get(smi_dev->dev, smi_clk_name); + if (IS_ERR(smi_clk_ptr)) { + SMIMSG("cannot get %s\n", smi_clk_name); + smi_clk_ptr = NULL; + } + return smi_clk_ptr; +} + +static void smi_prepare_clk(struct clk *smi_clk, char *name) +{ + if (smi_clk != NULL) { + int ret = 0; + + ret = clk_prepare(smi_clk); + if (ret) + SMIMSG("clk_prepare return error %d, %s\n", ret, name); + } else { + SMIMSG("clk_prepare error, smi_clk can't be NULL, %s\n", name); + } +} + +static void smi_enable_clk(struct clk *smi_clk, char *name) +{ + if (smi_clk != NULL) { + int ret = 0; + + ret = clk_enable(smi_clk); + if (ret) + SMIMSG("clk_enable return error %d, %s\n", ret, name); + } else { + SMIMSG("clk_enable error, smi_clk can't be NULL, %s\n", name); + } +} + +static void smi_unprepare_clk(struct clk *smi_clk, char *name) +{ + if (smi_clk != NULL) + clk_unprepare(smi_clk); + else + SMIMSG("smi_unprepare error, smi_clk can't be NULL, %s\n", name); +} + +static void smi_disable_clk(struct clk *smi_clk, char *name) +{ + if (smi_clk != NULL) + clk_disable(smi_clk); + else + SMIMSG("smi_disable error, smi_clk can't be NULL, %s\n", name); +} + +/* end MTCMOS*/ +#endif /* defined(SMI_INTERNAL_CCF_SUPPORT) */ + +static int larb_clock_enable(int larb_id, int enable_mtcmos) +{ +#if !defined(CONFIG_MTK_FPGA) && !defined(CONFIG_FPGA_EARLY_PORTING) + char name[30]; + + sprintf(name, "smi+%d", larb_id); + + + switch (larb_id) { +#if !defined(SMI_INTERNAL_CCF_SUPPORT) + case 0: + enable_clock(MT_CG_DISP0_SMI_COMMON, name); + enable_clock(MT_CG_DISP0_SMI_LARB0, name); + break; + case 1: + enable_clock(MT_CG_DISP0_SMI_COMMON, name); +#if defined(SMI_R) + enable_clock(MT_CG_LARB1_SMI_CKPDN, name); +#else + enable_clock(MT_CG_VDEC1_LARB, name); +#endif + break; + case 2: +#if !defined(SMI_R) + enable_clock(MT_CG_DISP0_SMI_COMMON, name); + enable_clock(MT_CG_IMAGE_LARB2_SMI, name); +#endif + break; + case 3: + enable_clock(MT_CG_DISP0_SMI_COMMON, name); +#if defined(SMI_D1) + enable_clock(MT_CG_VENC_LARB, name); +#elif defined(SMI_D3) + enable_clock(MT_CG_VENC_VENC, name); +#endif + break; +#else + case 0: + if (enable_mtcmos) + smi_enable_clk(smi_dev->larb0_mtcmos, name); + smi_enable_clk(smi_dev->smi_common_clk, name); + smi_enable_clk(smi_dev->smi_larb0_clk, name); + break; + case 1: + if (enable_mtcmos) { + smi_enable_clk(smi_dev->larb0_mtcmos, name); + smi_enable_clk(smi_dev->larb1_mtcmos, name); + } + smi_enable_clk(smi_dev->smi_common_clk, name); + smi_enable_clk(smi_dev->vdec1_larb_clk, name); + break; + case 2: + if (enable_mtcmos) { + smi_enable_clk(smi_dev->larb0_mtcmos, name); + smi_enable_clk(smi_dev->larb2_mtcmos, name); + } + smi_enable_clk(smi_dev->smi_common_clk, name); + smi_enable_clk(smi_dev->img_larb2_clk, name); + break; + case 3: + if (enable_mtcmos) { + smi_enable_clk(smi_dev->larb0_mtcmos, name); + smi_enable_clk(smi_dev->larb3_mtcmos, name); + } + smi_enable_clk(smi_dev->smi_common_clk, name); +#if defined(SMI_D1) + smi_enable_clk(smi_dev->venc_larb_clk, name); +#elif defined(SMI_J) + smi_enable_clk(smi_dev->venc_venc_clk, name); +#endif + break; +#endif + default: + break; + } +#endif + return 0; +} + +static int larb_clock_prepare(int larb_id, int enable_mtcmos) +{ +#if !defined(CONFIG_MTK_FPGA) && !defined(CONFIG_FPGA_EARLY_PORTING) && defined(SMI_INTERNAL_CCF_SUPPORT) + char name[30]; + + sprintf(name, "smi+%d", larb_id); + + switch (larb_id) { + case 0: + /* must enable MTCOMS before clk */ + /* common MTCMOS is called with larb0_MTCMOS */ + if (enable_mtcmos) + smi_prepare_clk(smi_dev->larb0_mtcmos, name); + smi_prepare_clk(smi_dev->smi_common_clk, name); + smi_prepare_clk(smi_dev->smi_larb0_clk, name); + break; + case 1: + if (enable_mtcmos) { + smi_prepare_clk(smi_dev->larb0_mtcmos, name); + smi_prepare_clk(smi_dev->larb1_mtcmos, name); + } + smi_prepare_clk(smi_dev->smi_common_clk, name); + smi_prepare_clk(smi_dev->vdec1_larb_clk, name); + break; + case 2: + if (enable_mtcmos) { + smi_prepare_clk(smi_dev->larb0_mtcmos, name); + smi_prepare_clk(smi_dev->larb2_mtcmos, name); + } + smi_prepare_clk(smi_dev->smi_common_clk, name); + smi_prepare_clk(smi_dev->img_larb2_clk, name); + break; + case 3: + if (enable_mtcmos) { + smi_prepare_clk(smi_dev->larb0_mtcmos, name); + smi_prepare_clk(smi_dev->larb3_mtcmos, name); + } + smi_prepare_clk(smi_dev->smi_common_clk, name); +#if defined(SMI_D1) + smi_prepare_clk(smi_dev->venc_larb_clk, name); +#elif defined(SMI_J) + smi_prepare_clk(smi_dev->venc_venc_clk, name); +#endif + break; + default: + break; + } +#endif + return 0; +} + +static int larb_clock_disable(int larb_id, int enable_mtcmos) +{ +#if !defined(CONFIG_MTK_FPGA) && !defined(CONFIG_FPGA_EARLY_PORTING) + char name[30]; + + sprintf(name, "smi+%d", larb_id); + + switch (larb_id) { +#if !defined(SMI_INTERNAL_CCF_SUPPORT) + case 0: + disable_clock(MT_CG_DISP0_SMI_LARB0, name); + disable_clock(MT_CG_DISP0_SMI_COMMON, name); + break; + case 1: +#if defined(SMI_R) + disable_clock(MT_CG_LARB1_SMI_CKPDN, name); +#else + disable_clock(MT_CG_VDEC1_LARB, name); +#endif + disable_clock(MT_CG_DISP0_SMI_COMMON, name); + break; + case 2: +#if !defined(SMI_R) + disable_clock(MT_CG_IMAGE_LARB2_SMI, name); + disable_clock(MT_CG_DISP0_SMI_COMMON, name); +#endif + break; + case 3: +#if defined(SMI_D1) + disable_clock(MT_CG_VENC_LARB, name); +#elif defined(SMI_D3) + disable_clock(MT_CG_VENC_VENC, name); +#endif + disable_clock(MT_CG_DISP0_SMI_COMMON, name); + break; +#else + case 0: + smi_disable_clk(smi_dev->smi_larb0_clk, name); + smi_disable_clk(smi_dev->smi_common_clk, name); + if (enable_mtcmos) + smi_disable_clk(smi_dev->larb0_mtcmos, name); + break; + case 1: + smi_disable_clk(smi_dev->vdec1_larb_clk, name); + smi_disable_clk(smi_dev->smi_common_clk, name); + if (enable_mtcmos) { + smi_disable_clk(smi_dev->larb1_mtcmos, name); + smi_disable_clk(smi_dev->larb0_mtcmos, name); + } + break; + case 2: + smi_disable_clk(smi_dev->img_larb2_clk, name); + smi_disable_clk(smi_dev->smi_common_clk, name); + if (enable_mtcmos) { + smi_disable_clk(smi_dev->larb2_mtcmos, name); + smi_disable_clk(smi_dev->larb0_mtcmos, name); + } + break; + case 3: +#if defined(SMI_D1) + smi_disable_clk(smi_dev->venc_larb_clk, name); +#elif defined(SMI_J) + smi_disable_clk(smi_dev->venc_venc_clk, name); +#endif + smi_disable_clk(smi_dev->smi_common_clk, name); + if (enable_mtcmos) { + smi_disable_clk(smi_dev->larb3_mtcmos, name); + smi_disable_clk(smi_dev->larb0_mtcmos, name); + } + break; +#endif + default: + break; + } +#endif + return 0; +} + +static int larb_clock_unprepare(int larb_id, int enable_mtcmos) +{ +#if !defined(CONFIG_MTK_FPGA) && !defined(CONFIG_FPGA_EARLY_PORTING) && defined(SMI_INTERNAL_CCF_SUPPORT) + char name[30]; + + sprintf(name, "smi+%d", larb_id); + + switch (larb_id) { + case 0: + /* must enable MTCOMS before clk */ + /* common MTCMOS is called with larb0_MTCMOS */ + smi_unprepare_clk(smi_dev->smi_larb0_clk, name); + smi_unprepare_clk(smi_dev->smi_common_clk, name); + if (enable_mtcmos) + smi_unprepare_clk(smi_dev->larb0_mtcmos, name); + break; + case 1: + smi_unprepare_clk(smi_dev->vdec1_larb_clk, name); + smi_unprepare_clk(smi_dev->smi_common_clk, name); + if (enable_mtcmos) { + smi_unprepare_clk(smi_dev->larb1_mtcmos, name); + smi_unprepare_clk(smi_dev->larb0_mtcmos, name); + } + break; + case 2: + smi_unprepare_clk(smi_dev->img_larb2_clk, name); + smi_unprepare_clk(smi_dev->smi_common_clk, name); + if (enable_mtcmos) { + smi_unprepare_clk(smi_dev->larb2_mtcmos, name); + smi_unprepare_clk(smi_dev->larb0_mtcmos, name); + } + break; + case 3: +#if defined(SMI_D1) + smi_unprepare_clk(smi_dev->venc_larb_clk, name); +#elif defined(SMI_J) + smi_unprepare_clk(smi_dev->venc_venc_clk, name); +#endif + smi_unprepare_clk(smi_dev->smi_common_clk, name); + if (enable_mtcmos) { + smi_unprepare_clk(smi_dev->larb3_mtcmos, name); + smi_unprepare_clk(smi_dev->larb0_mtcmos, name); + } + break; + + default: + break; + } +#endif + return 0; +} + +static void backup_smi_common(void) +{ + int i; + + for (i = 0; i < SMI_COMMON_BACKUP_REG_NUM; i++) { + g_smi_common_backup[i] = M4U_ReadReg32(SMI_COMMON_EXT_BASE, (unsigned long) + g_smi_common_backup_reg_offset[i]); + } +} + +static void restore_smi_common(void) +{ + int i; + + for (i = 0; i < SMI_COMMON_BACKUP_REG_NUM; i++) { + M4U_WriteReg32(SMI_COMMON_EXT_BASE, + (unsigned long)g_smi_common_backup_reg_offset[i], + g_smi_common_backup[i]); + } +} + +static void backup_larb_smi(int index) +{ + int port_index = 0; + unsigned short int *backup_ptr = NULL; + unsigned long larb_base = 0; + unsigned long larb_offset = 0x200; + int total_port_num = 0; + + /* boundary check for larb_port_num and larb_port_backup access */ + if (index < 0 || index >= SMI_LARB_NR) + return; + + larb_base = gLarbBaseAddr[index]; + total_port_num = larb_port_num[index]; + backup_ptr = larb_port_backup[index]; + + /* boundary check for port value access */ + if (total_port_num <= 0 || backup_ptr == NULL) + return; + + for (port_index = 0; port_index < total_port_num; port_index++) { + *backup_ptr = (unsigned short int)(M4U_ReadReg32(larb_base, larb_offset)); + backup_ptr++; + larb_offset += 4; + } + + /* backup smi common along with larb0, smi common clk is guaranteed to be on when processing larbs */ + if (index == 0) + backup_smi_common(); + +} + +static void restore_larb_smi(int index) +{ + int port_index = 0; + unsigned short int *backup_ptr = NULL; + unsigned long larb_base = 0; + unsigned long larb_offset = 0x200; + unsigned int backup_value = 0; + int total_port_num = 0; + + /* boundary check for larb_port_num and larb_port_backup access */ + if (index < 0 || index >= SMI_LARB_NR) + return; + + larb_base = gLarbBaseAddr[index]; + total_port_num = larb_port_num[index]; + backup_ptr = larb_port_backup[index]; + + /* boundary check for port value access */ + if (total_port_num <= 0 || backup_ptr == NULL) + return; + + /* restore smi common along with larb0, smi common clk is guaranteed to be on when processing larbs */ + if (index == 0) + restore_smi_common(); + + for (port_index = 0; port_index < total_port_num; port_index++) { + backup_value = *backup_ptr; + M4U_WriteReg32(larb_base, larb_offset, backup_value); + backup_ptr++; + larb_offset += 4; + } + + /* we do not backup 0x20 because it is a fixed setting */ + M4U_WriteReg32(larb_base, 0x20, larb_vc_setting[index]); + + /* turn off EMI empty OSTD dobule, fixed setting */ + M4U_WriteReg32(larb_base, 0x2c, 4); + +} + +static int larb_reg_backup(int larb) +{ + unsigned int *pReg = pLarbRegBackUp[larb]; + unsigned long larb_base = gLarbBaseAddr[larb]; + + *(pReg++) = M4U_ReadReg32(larb_base, SMI_LARB_CON); + + backup_larb_smi(larb); + + if (0 == larb) + g_bInited = 0; + + return 0; +} + +static int smi_larb_init(unsigned int larb) +{ + unsigned int regval = 0; + unsigned int regval1 = 0; + unsigned int regval2 = 0; + unsigned long larb_base = get_larb_base_addr(larb); + + /* Clock manager enable LARB clock before call back restore already, + * it will be disabled after restore call back returns + * Got to enable OSTD before engine starts */ + regval = M4U_ReadReg32(larb_base, SMI_LARB_STAT); + + /* TODO: FIX ME */ + /* regval1 = M4U_ReadReg32(larb_base , SMI_LARB_MON_BUS_REQ0); */ + /* regval2 = M4U_ReadReg32(larb_base , SMI_LARB_MON_BUS_REQ1); */ + + if (0 == regval) { + SMIDBG(1, "Init OSTD for larb_base: 0x%lx\n", larb_base); + M4U_WriteReg32(larb_base, SMI_LARB_OSTDL_SOFT_EN, 0xffffffff); + } else { + SMIMSG("Larb: 0x%lx is busy : 0x%x , port:0x%x,0x%x ,fail to set OSTD\n", + larb_base, regval, regval1, regval2); + if (smi_debug_level >= 1) { + SMIERR("DISP_MDP LARB 0x%lx OSTD cannot be set:0x%x,port:0x%x,0x%x\n", + larb_base, regval, regval1, regval2); + } else { + dump_stack(); + } + } + + restore_larb_smi(larb); + + return 0; +} + +int larb_reg_restore(int larb) +{ + unsigned long larb_base = SMI_ERROR_ADDR; + unsigned int regval = 0; + unsigned int *pReg = NULL; + + larb_base = get_larb_base_addr(larb); + + /* The larb assign doesn't exist */ + if (larb_base == SMI_ERROR_ADDR) { + SMIMSG("Can't find the base address for Larb%d\n", larb); + return 0; + } + + if (larb >= SMI_LARB_NR || larb < 0) { + SMIMSG("Can't find the backup register value for Larb%d\n", larb); + return 0; + } + + pReg = pLarbRegBackUp[larb]; + + SMIDBG(1, "+larb_reg_restore(), larb_idx=%d\n", larb); + SMIDBG(1, "m4u part restore, larb_idx=%d\n", larb); + /* warning: larb_con is controlled by set/clr */ + regval = *(pReg++); + M4U_WriteReg32(larb_base, SMI_LARB_CON_CLR, ~(regval)); + M4U_WriteReg32(larb_base, SMI_LARB_CON_SET, (regval)); + + smi_larb_init(larb); + + return 0; +} + +/* callback after larb clock is enabled */ +#if !defined(SMI_INTERNAL_CCF_SUPPORT) +void on_larb_power_on(struct larb_monitor *h, int larb_idx) +{ + larb_reg_restore(larb_idx); +} + +/* callback before larb clock is disabled */ +void on_larb_power_off(struct larb_monitor *h, int larb_idx) +{ + larb_reg_backup(larb_idx); +} +#endif /* !defined(SMI_INTERNAL_CCF_SUPPORT) */ + +#if defined(SMI_INTERNAL_CCF_SUPPORT) +void on_larb_power_on_with_ccf(int larb_idx) +{ + /* MTCMOS has already enable, only enable clk here to set register value */ + larb_clock_prepare(larb_idx, 0); + larb_clock_enable(larb_idx, 0); + larb_reg_restore(larb_idx); + larb_clock_disable(larb_idx, 0); + larb_clock_unprepare(larb_idx, 0); +} + +void on_larb_power_off_with_ccf(int larb_idx) +{ + /* enable clk here for get correct register value */ + larb_clock_prepare(larb_idx, 0); + larb_clock_enable(larb_idx, 0); + larb_reg_backup(larb_idx); + larb_clock_disable(larb_idx, 0); + larb_clock_unprepare(larb_idx, 0); +} +#endif /* defined(SMI_INTERNAL_CCF_SUPPORT) */ + +#if defined(SMI_J) +static void DCM_enable(void) +{ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x300, 0x1 + (0x78 << 1) + (0x4 << 8)); + M4U_WriteReg32(LARB0_BASE, 0x14, (0x7 << 8) + (0xf << 4)); + M4U_WriteReg32(LARB1_BASE, 0x14, (0x7 << 8) + (0xf << 4)); + M4U_WriteReg32(LARB2_BASE, 0x14, (0x7 << 8) + (0xf << 4)); + M4U_WriteReg32(LARB3_BASE, 0x14, (0x7 << 8) + (0xf << 4)); + +} +#endif + + +/* Fake mode check, e.g. WFD */ +static int fake_mode_handling(MTK_SMI_BWC_CONFIG *p_conf, unsigned int *pu4LocalCnt) +{ + if (p_conf->scenario == SMI_BWC_SCEN_WFD) { + if (p_conf->b_on_off) { + wifi_disp_transaction = 1; + SMIMSG("Enable WFD in profile: %d\n", smi_profile); + } else { + wifi_disp_transaction = 0; + SMIMSG("Disable WFD in profile: %d\n", smi_profile); + } + return 1; + } else { + return 0; + } +} + +static int ovl_limit_uevent(int bwc_scenario, int ovl_pixel_limit) +{ + int err = 0; + char *envp[3]; + char scenario_buf[32] = ""; + char ovl_limit_buf[32] = ""; + + snprintf(scenario_buf, 31, "SCEN=%d", bwc_scenario); + snprintf(ovl_limit_buf, 31, "HWOVL=%d", ovl_pixel_limit); + + envp[0] = scenario_buf; + envp[1] = ovl_limit_buf; + envp[2] = NULL; + + if (pSmiDev != NULL) { + err = kobject_uevent_env(&(smiDeviceUevent->kobj), KOBJ_CHANGE, envp); + SMIMSG("Notify OVL limitaion=%d, SCEN=%d", ovl_pixel_limit, bwc_scenario); + } + + if (err < 0) + SMIMSG(KERN_INFO "[%s] kobject_uevent_env error = %d\n", __func__, err); + + return err; +} + +#if defined(SMI_INTERNAL_CCF_SUPPORT) +static unsigned int smiclk_subsys_2_larb(enum subsys_id sys) +{ + unsigned int i4larbid = 0; + + switch (sys) { + case SYS_DIS: + i4larbid = 0; /*0&4 is disp */ + break; + case SYS_VDE: + i4larbid = 1; + break; + case SYS_ISP: + i4larbid = 2; + break; + case SYS_VEN: + i4larbid = 3; + break; + default: + i4larbid = SMI_LARB_NR; + break; + } + return i4larbid; +} + +static void smiclk_subsys_after_on(enum subsys_id sys) +{ + unsigned int i4larbid = smiclk_subsys_2_larb(sys); + + if (!fglarbcallback) { + SMIDBG(1, "don't need restore incb\n"); + return; + } + + if (i4larbid < SMI_LARB_NR) { + on_larb_power_on_with_ccf(i4larbid); +#if defined(SMI_D1) + /* inform m4u to restore register value */ + m4u_larb_backup((int)i4larbid); +#endif + } else { + SMIDBG(1, "subsys id don't backup sys %d larb %u\n", sys, i4larbid); + } +} + +static void smiclk_subsys_before_off(enum subsys_id sys) +{ + unsigned int i4larbid = smiclk_subsys_2_larb(sys); + + if (!fglarbcallback) { + SMIDBG(1, "don't need backup incb\n"); + return; + } + + if (i4larbid < SMI_LARB_NR) { + on_larb_power_off_with_ccf(i4larbid); +#if defined(SMI_D1) + /* inform m4u to backup register value */ + m4u_larb_restore((int)i4larbid); +#endif + } else { + SMIDBG(1, "subsys id don't restore sys %d larb %d\n", sys, i4larbid); + } + +} + +struct pg_callbacks smi_clk_subsys_handle = { + .before_off = smiclk_subsys_before_off, + .after_on = smiclk_subsys_after_on +}; +#endif + +static int smi_bwc_config(MTK_SMI_BWC_CONFIG *p_conf, unsigned int *pu4LocalCnt) +{ + int i; + int result = 0; + unsigned int u4Concurrency = 0; + MTK_SMI_BWC_SCEN eFinalScen; + static MTK_SMI_BWC_SCEN ePreviousFinalScen = SMI_BWC_SCEN_CNT; + + if (smi_tuning_mode == 1) { + SMIMSG("Doesn't change profile in tunning mode"); + return 0; + } + + + if ((SMI_BWC_SCEN_CNT <= p_conf->scenario) || (0 > p_conf->scenario)) { + SMIERR("Incorrect SMI BWC config : 0x%x, how could this be...\n", p_conf->scenario); + return -1; + } +#if defined(SMI_D1) || defined(SMI_D2) || defined(SMI_D3) + if (p_conf->b_on_off) { + /* set mmdvfs step according to certain scenarios */ + mmdvfs_notify_scenario_enter(p_conf->scenario); + } else { + /* set mmdvfs step to default after the scenario exits */ + mmdvfs_notify_scenario_exit(p_conf->scenario); + } +#endif + + spin_lock(&g_SMIInfo.SMI_lock); + result = fake_mode_handling(p_conf, pu4LocalCnt); + spin_unlock(&g_SMIInfo.SMI_lock); + + /* Fake mode is not a real SMI profile, so we need to return here */ + if (result == 1) + return 0; + +#if defined(SMI_INTERNAL_CCF_SUPPORT) + /* prepare larb clk because prepare cannot in spinlock */ + for (i = 0; i < SMI_LARB_NR; i++) + larb_clock_prepare(i, 1); +#endif + spin_lock(&g_SMIInfo.SMI_lock); + + if (p_conf->b_on_off) { + /* turn on certain scenario */ + g_SMIInfo.pu4ConcurrencyTable[p_conf->scenario] += 1; + + if (NULL != pu4LocalCnt) + pu4LocalCnt[p_conf->scenario] += 1; + + } else { + /* turn off certain scenario */ + if (0 == g_SMIInfo.pu4ConcurrencyTable[p_conf->scenario]) { + SMIMSG("Too many turning off for global SMI profile:%d,%d\n", + p_conf->scenario, g_SMIInfo.pu4ConcurrencyTable[p_conf->scenario]); + } else { + g_SMIInfo.pu4ConcurrencyTable[p_conf->scenario] -= 1; + } + + if (NULL != pu4LocalCnt) { + if (0 == pu4LocalCnt[p_conf->scenario]) { + SMIMSG + ("Process : %s did too many turning off for local SMI profile:%d,%d\n", + current->comm, p_conf->scenario, + pu4LocalCnt[p_conf->scenario]); + } else { + pu4LocalCnt[p_conf->scenario] -= 1; + } + } + } + + for (i = 0; i < SMI_BWC_SCEN_CNT; i++) { + if (g_SMIInfo.pu4ConcurrencyTable[i]) + u4Concurrency |= (1 << i); + } +#if defined(SMI_D1) || defined(SMI_D2) || defined(SMI_D3) + /* notify mmdvfs concurrency */ + mmdvfs_notify_scenario_concurrency(u4Concurrency); +#endif + + if ((1 << SMI_BWC_SCEN_MM_GPU) & u4Concurrency) + eFinalScen = SMI_BWC_SCEN_MM_GPU; + else if ((1 << SMI_BWC_SCEN_ICFP) & u4Concurrency) + eFinalScen = SMI_BWC_SCEN_ICFP; + else if ((1 << SMI_BWC_SCEN_VSS) & u4Concurrency) + eFinalScen = SMI_BWC_SCEN_VSS; + else if ((1 << SMI_BWC_SCEN_VR_SLOW) & u4Concurrency) + eFinalScen = SMI_BWC_SCEN_VR_SLOW; + else if ((1 << SMI_BWC_SCEN_VR) & u4Concurrency) + eFinalScen = SMI_BWC_SCEN_VR; + else if ((1 << SMI_BWC_SCEN_VP) & u4Concurrency) + eFinalScen = SMI_BWC_SCEN_VP; + else if ((1 << SMI_BWC_SCEN_SWDEC_VP) & u4Concurrency) + eFinalScen = SMI_BWC_SCEN_SWDEC_VP; + else if ((1 << SMI_BWC_SCEN_VENC) & u4Concurrency) + eFinalScen = SMI_BWC_SCEN_VENC; + else + eFinalScen = SMI_BWC_SCEN_NORMAL; + + if (ePreviousFinalScen != eFinalScen) { + ePreviousFinalScen = eFinalScen; + } else { + SMIMSG("Scen equal%d,don't change\n", eFinalScen); + spin_unlock(&g_SMIInfo.SMI_lock); +#if defined(SMI_INTERNAL_CCF_SUPPORT) + /* unprepare larb clock */ + for (i = 0; i < SMI_LARB_NR; i++) + larb_clock_unprepare(i, 1); +#endif + return 0; + } + + /* enable larb clock */ + for (i = 0; i < SMI_LARB_NR; i++) + larb_clock_enable(i, 1); + + smi_profile = eFinalScen; + + smi_bus_regs_setting(smi_profile, + smi_profile_config[smi_profile].setting); + + /* Bandwidth Limiter */ + switch (eFinalScen) { + case SMI_BWC_SCEN_VP: + SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_VP"); + g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_VP; + break; + + case SMI_BWC_SCEN_SWDEC_VP: + SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_SWDEC_VP"); + g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_VP; + break; + + case SMI_BWC_SCEN_ICFP: + SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_ICFP"); + g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_VR; + break; + case SMI_BWC_SCEN_VR: + SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_VR"); + g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_VR; + break; + + case SMI_BWC_SCEN_VR_SLOW: + SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_VR"); + g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; + break; + + case SMI_BWC_SCEN_VENC: + SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_VENC"); + g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; + break; + + case SMI_BWC_SCEN_NORMAL: + SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_NORMAL"); + g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; + break; + + case SMI_BWC_SCEN_MM_GPU: + SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_MM_GPU"); + g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; + break; + + default: + SMIMSG("[SMI_PROFILE] : %s %d\n", "initSetting", eFinalScen); + g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; + break; + } + + /* disable larb clock */ + for (i = 0; i < SMI_LARB_NR; i++) + larb_clock_disable(i, 1); + + spin_unlock(&g_SMIInfo.SMI_lock); +#if defined(SMI_INTERNAL_CCF_SUPPORT) + /* unprepare larb clock */ + for (i = 0; i < SMI_LARB_NR; i++) + larb_clock_unprepare(i, 1); +#endif + ovl_limit_uevent(smi_profile, g_smi_bwc_mm_info.hw_ovl_limit); + + /* force 30 fps in VR slow motion, because disp driver set fps apis got mutex, + * call these APIs only when necessary */ + { + static unsigned int current_fps; + + if ((eFinalScen == SMI_BWC_SCEN_VR_SLOW) && (current_fps != 30)) { + /* force 30 fps in VR slow motion profile */ + primary_display_force_set_vsync_fps(30); + current_fps = 30; + SMIMSG("[SMI_PROFILE] set 30 fps\n"); + } else if ((eFinalScen != SMI_BWC_SCEN_VR_SLOW) && (current_fps == 30)) { + /* back to normal fps */ + current_fps = primary_display_get_fps(); + primary_display_force_set_vsync_fps(current_fps); + SMIMSG("[SMI_PROFILE] back to %u fps\n", current_fps); + } + } + + SMIMSG("SMI_PROFILE to:%d %s,cur:%d,%d,%d,%d\n", p_conf->scenario, + (p_conf->b_on_off ? "on" : "off"), eFinalScen, + g_SMIInfo.pu4ConcurrencyTable[SMI_BWC_SCEN_NORMAL], + g_SMIInfo.pu4ConcurrencyTable[SMI_BWC_SCEN_VR], + g_SMIInfo.pu4ConcurrencyTable[SMI_BWC_SCEN_VP]); + + return 0; +} + +#if !defined(SMI_INTERNAL_CCF_SUPPORT) +struct larb_monitor larb_monitor_handler = { + .level = LARB_MONITOR_LEVEL_HIGH, + .backup = on_larb_power_off, + .restore = on_larb_power_on +}; +#endif /* !defined(SMI_INTERNAL_CCF_SUPPORT) */ + +int smi_common_init(void) +{ + int i; + +#if defined(SMI_INTERNAL_CCF_SUPPORT) + struct pg_callbacks *pold = 0; +#endif + +#if defined(SMI_J) + /* enable DCM */ + DCM_enable(); +#endif + SMIMSG("Enter smi_common_init\n"); + for (i = 0; i < SMI_LARB_NR; i++) { + pLarbRegBackUp[i] = kmalloc(LARB_BACKUP_REG_SIZE, GFP_KERNEL | __GFP_ZERO); + if (pLarbRegBackUp[i] == NULL) + SMIERR("pLarbRegBackUp kmalloc fail %d\n", i); + } + + /* + * make sure all larb power is on before we register callback func. + * then, when larb power is first off, default register value will be backed up. + */ + + for (i = 0; i < SMI_LARB_NR; i++) { + larb_clock_prepare(i, 1); + larb_clock_enable(i, 1); + } + /* keep default HW value */ + save_default_common_val(&is_default_value_saved, default_val_smi_l1arb); + /* set nonconstatnt variables */ + smi_set_nonconstant_variable(); + /* apply init setting after kernel boot */ + SMIMSG("Enter smi_common_init\n"); + smi_bus_regs_setting(SMI_BWC_SCEN_NORMAL, smi_profile_config[SMI_BWC_SCEN_NORMAL].setting); + +#if defined(SMI_INTERNAL_CCF_SUPPORT) + fglarbcallback = true; + + pold = register_pg_callback(&smi_clk_subsys_handle); + if (pold) + SMIERR("smi reg clk cb call fail\n"); + else + SMIMSG("smi reg clk cb call success\n"); + +#else /* !defined(SMI_INTERNAL_CCF_SUPPORT) */ + register_larb_monitor(&larb_monitor_handler); +#endif /* defined(SMI_INTERNAL_CCF_SUPPORT) */ + + for (i = 0; i < SMI_LARB_NR; i++) { + larb_clock_disable(i, 1); + larb_clock_unprepare(i, 1); + } + + return 0; +} + +static int smi_open(struct inode *inode, struct file *file) +{ + file->private_data = kmalloc_array(SMI_BWC_SCEN_CNT, sizeof(unsigned int), GFP_ATOMIC); + + if (NULL == file->private_data) { + SMIMSG("Not enough entry for DDP open operation\n"); + return -ENOMEM; + } + + memset(file->private_data, 0, SMI_BWC_SCEN_CNT * sizeof(unsigned int)); + + return 0; +} + +static int smi_release(struct inode *inode, struct file *file) +{ + +#if 0 + unsigned long u4Index = 0; + unsigned long u4AssignCnt = 0; + unsigned long *pu4Cnt = (unsigned long *)file->private_data; + MTK_SMI_BWC_CONFIG config; + + for (; u4Index < SMI_BWC_SCEN_CNT; u4Index += 1) { + if (pu4Cnt[u4Index]) { + SMIMSG("Process:%s does not turn off BWC properly , force turn off %d\n", + current->comm, u4Index); + u4AssignCnt = pu4Cnt[u4Index]; + config.b_on_off = 0; + config.scenario = (MTK_SMI_BWC_SCEN) u4Index; + do { + smi_bwc_config(&config, pu4Cnt); + } while (0 < u4AssignCnt); + } + } +#endif + + if (NULL != file->private_data) { + kfree(file->private_data); + file->private_data = NULL; + } + + return 0; +} + +static long smi_ioctl(struct file *pFile, unsigned int cmd, unsigned long param) +{ + int ret = 0; + + /* unsigned long * pu4Cnt = (unsigned long *)pFile->private_data; */ + + switch (cmd) { + + /* disable reg access ioctl by default for possible security holes */ + /* TBD: check valid SMI register range */ + case MTK_IOC_SMI_BWC_CONFIG:{ + MTK_SMI_BWC_CONFIG cfg; + + ret = copy_from_user(&cfg, (void *)param, sizeof(MTK_SMI_BWC_CONFIG)); + if (ret) { + SMIMSG(" SMI_BWC_CONFIG, copy_from_user failed: %d\n", ret); + return -EFAULT; + } + ret = smi_bwc_config(&cfg, NULL); + + break; + } + /* GMP start */ + case MTK_IOC_SMI_BWC_INFO_SET:{ + smi_set_mm_info_ioctl_wrapper(pFile, cmd, param); + break; + } + case MTK_IOC_SMI_BWC_INFO_GET:{ + smi_get_mm_info_ioctl_wrapper(pFile, cmd, param); + break; + } + /* GMP end */ + + case MTK_IOC_SMI_DUMP_LARB:{ + unsigned int larb_index; + + ret = copy_from_user(&larb_index, (void *)param, sizeof(unsigned int)); + if (ret) + return -EFAULT; + + smi_dumpLarb(larb_index); + } + break; + + case MTK_IOC_SMI_DUMP_COMMON:{ + unsigned int arg; + + ret = copy_from_user(&arg, (void *)param, sizeof(unsigned int)); + if (ret) + return -EFAULT; + + smi_dumpCommon(); + } + break; +#if defined(SMI_D1) || defined(SMI_D2) || defined(SMI_D3) + case MTK_IOC_MMDVFS_CMD: + { + MTK_MMDVFS_CMD mmdvfs_cmd; + + if (copy_from_user(&mmdvfs_cmd, (void *)param, sizeof(MTK_MMDVFS_CMD))) + return -EFAULT; + + + mmdvfs_handle_cmd(&mmdvfs_cmd); + + if (copy_to_user + ((void *)param, (void *)&mmdvfs_cmd, sizeof(MTK_MMDVFS_CMD))) { + return -EFAULT; + } + } + break; +#endif + default: + return -1; + } + + return ret; +} + +static const struct file_operations smiFops = { + .owner = THIS_MODULE, + .open = smi_open, + .release = smi_release, + .unlocked_ioctl = smi_ioctl, + .compat_ioctl = MTK_SMI_COMPAT_ioctl, +}; + +#if defined(SMI_J) +/* +static int smi_sel; + +static ssize_t smi_sel_show(struct kobject *kobj, struct kobj_attribute *attr, +char *buf) +{ + char *p = buf; + + p += sprintf(p, "%d\n", smi_sel); + + return p - buf; +} + +static ssize_t smi_sel_store(struct kobject *kobj, struct kobj_attribute *attr, +const char *buf, size_t count) +{ + int val; + + if (sscanf(buf, "%d", &val) != 1) + return -EPERM; + + smi_sel = val; + + return count; +} + +static ssize_t smi_dbg_show(struct kobject *kobj, struct kobj_attribute *attr, +char *buf) +{ + if (smi_sel >= 0 && smi_sel < SMI_LARB_NR) + smi_dumpLarb(smi_sel); + else if (smi_sel == 999) + smi_dumpCommon(); + + return 0; +} +DEFINE_ATTR_RW(smi_sel); +DEFINE_ATTR_RO(smi_dbg); + +static struct attribute *smi_attrs[] = {__ATTR_OF(smi_sel), __ATTR_OF(smi_dbg), +NULL, }; + +static struct attribute_group smi_attr_group = {.name = "smi", .attrs = +smi_attrs, }; +*/ +#endif +static dev_t smiDevNo = MKDEV(MTK_SMI_MAJOR_NUMBER, 0); +static inline int smi_register(void) +{ + if (alloc_chrdev_region(&smiDevNo, 0, 1, "MTK_SMI")) { + SMIERR("Allocate device No. failed"); + return -EAGAIN; + } + /* Allocate driver */ + pSmiDev = cdev_alloc(); + + if (NULL == pSmiDev) { + unregister_chrdev_region(smiDevNo, 1); + SMIERR("Allocate mem for kobject failed"); + return -ENOMEM; + } + /* Attatch file operation. */ + cdev_init(pSmiDev, &smiFops); + pSmiDev->owner = THIS_MODULE; + + /* Add to system */ + if (cdev_add(pSmiDev, smiDevNo, 1)) { + SMIERR("Attatch file operation failed"); + unregister_chrdev_region(smiDevNo, 1); + return -EAGAIN; + } + + return 0; +} + +static unsigned long get_register_base(int i) +{ + unsigned long pa_value = 0; + unsigned long va_value = 0; + + va_value = gSMIBaseAddrs[i]; + pa_value = virt_to_phys((void *)va_value); + + return pa_value; +} + +void register_base_dump(void) +{ + int i = 0; + + for (i = 0; i < SMI_REG_REGION_MAX; i++) { + SMIMSG("REG BASE:%s-->VA=0x%lx,PA=0x%lx\n", + smi_get_region_name(i), gSMIBaseAddrs[i], get_register_base(i)); + } +} + +static struct class *pSmiClass; + +static int smi_probe(struct platform_device *pdev) +{ + + int i; + + static unsigned int smi_probe_cnt; + struct device *smiDevice = NULL; + + SMIMSG("Enter smi_probe\n"); + /* Debug only */ + if (smi_probe_cnt != 0) { + SMIERR("Only support 1 SMI driver probed\n"); + return 0; + } + smi_probe_cnt++; + SMIMSG("Allocate smi_dev space\n"); + smi_dev = kmalloc(sizeof(struct smi_device), GFP_KERNEL); + + if (smi_dev == NULL) { + SMIERR("Unable to allocate memory for smi driver\n"); + return -ENOMEM; + } + if (NULL == pdev) { + SMIERR("platform data missed\n"); + return -ENXIO; + } + /* Keep the device structure */ + smi_dev->dev = &pdev->dev; + + /* Map registers */ + for (i = 0; i < SMI_REG_REGION_MAX; i++) { + SMIMSG("Save region: %d\n", i); + smi_dev->regs[i] = (void *)of_iomap(pdev->dev.of_node, i); + + if (!smi_dev->regs[i]) { + SMIERR("Unable to ioremap registers, of_iomap fail, i=%d\n", i); + return -ENOMEM; + } + /* Record the register base in global variable */ + gSMIBaseAddrs[i] = (unsigned long)(smi_dev->regs[i]); + SMIMSG("DT, i=%d, region=%s, map_addr=0x%p, reg_pa=0x%lx\n", i, + smi_get_region_name(i), smi_dev->regs[i], get_register_base(i)); + } + +#if defined(SMI_INTERNAL_CCF_SUPPORT) + smi_dev->smi_common_clk = get_smi_clk("smi-common"); + smi_dev->smi_larb0_clk = get_smi_clk("smi-larb0"); + smi_dev->img_larb2_clk = get_smi_clk("img-larb2"); +#if defined(SMI_D1) + smi_dev->vdec0_vdec_clk = get_smi_clk("vdec0-vdec"); +#endif + smi_dev->vdec1_larb_clk = get_smi_clk("vdec1-larb"); + smi_dev->venc_larb_clk = get_smi_clk("venc-larb"); +#if defined(SMI_J) + smi_dev->venc_venc_clk = get_smi_clk("venc-venc"); +#endif + /* MTCMOS */ + smi_dev->larb1_mtcmos = get_smi_clk("mtcmos-vde"); + smi_dev->larb3_mtcmos = get_smi_clk("mtcmos-ven"); + smi_dev->larb2_mtcmos = get_smi_clk("mtcmos-isp"); + smi_dev->larb0_mtcmos = get_smi_clk("mtcmos-dis"); +#endif + + SMIMSG("Execute smi_register\n"); + if (smi_register()) { + dev_err(&pdev->dev, "register char failed\n"); + return -EAGAIN; + } + + pSmiClass = class_create(THIS_MODULE, "MTK_SMI"); + if (IS_ERR(pSmiClass)) { + int ret = PTR_ERR(pSmiClass); + + SMIERR("Unable to create class, err = %d", ret); + return ret; + } + SMIMSG("Create davice\n"); + smiDevice = device_create(pSmiClass, NULL, smiDevNo, NULL, "MTK_SMI"); + smiDeviceUevent = smiDevice; + + SMIMSG("SMI probe done.\n"); +#if defined(SMI_D2) + /* To adapt the legacy codes */ + smi_reg_base_common_ext = gSMIBaseAddrs[SMI_COMMON_REG_INDX]; + smi_reg_base_barb0 = gSMIBaseAddrs[SMI_LARB0_REG_INDX]; + smi_reg_base_barb1 = gSMIBaseAddrs[SMI_LARB1_REG_INDX]; + smi_reg_base_barb2 = gSMIBaseAddrs[SMI_LARB2_REG_INDX]; + /* smi_reg_base_barb4 = gSMIBaseAddrs[SMI_LARB4_REG_INDX]; */ + + gLarbBaseAddr[0] = LARB0_BASE; + gLarbBaseAddr[1] = LARB1_BASE; + gLarbBaseAddr[2] = LARB2_BASE; +#elif defined(SMI_D1) || defined(SMI_D3) + /* To adapt the legacy codes */ + smi_reg_base_common_ext = gSMIBaseAddrs[SMI_COMMON_REG_INDX]; + smi_reg_base_barb0 = gSMIBaseAddrs[SMI_LARB0_REG_INDX]; + smi_reg_base_barb1 = gSMIBaseAddrs[SMI_LARB1_REG_INDX]; + smi_reg_base_barb2 = gSMIBaseAddrs[SMI_LARB2_REG_INDX]; + smi_reg_base_barb3 = gSMIBaseAddrs[SMI_LARB3_REG_INDX]; + + gLarbBaseAddr[0] = LARB0_BASE; + gLarbBaseAddr[1] = LARB1_BASE; + gLarbBaseAddr[2] = LARB2_BASE; + gLarbBaseAddr[3] = LARB3_BASE; + +#elif defined(SMI_J) +/* To adapt the legacy codes */ + smi_reg_base_common_ext = gSMIBaseAddrs[SMI_COMMON_REG_INDX]; + smi_reg_base_barb0 = gSMIBaseAddrs[SMI_LARB0_REG_INDX]; + smi_reg_base_barb1 = gSMIBaseAddrs[SMI_LARB1_REG_INDX]; + smi_reg_base_barb2 = gSMIBaseAddrs[SMI_LARB2_REG_INDX]; + smi_reg_base_barb3 = gSMIBaseAddrs[SMI_LARB3_REG_INDX]; + + gLarbBaseAddr[0] = LARB0_BASE; + gLarbBaseAddr[1] = LARB1_BASE; + gLarbBaseAddr[2] = LARB2_BASE; + gLarbBaseAddr[3] = LARB3_BASE; +#else + smi_reg_base_common_ext = gSMIBaseAddrs[SMI_COMMON_REG_INDX]; + smi_reg_base_barb0 = gSMIBaseAddrs[SMI_LARB0_REG_INDX]; + smi_reg_base_barb1 = gSMIBaseAddrs[SMI_LARB1_REG_INDX]; + + gLarbBaseAddr[0] = LARB0_BASE; + gLarbBaseAddr[1] = LARB1_BASE; +#endif + + SMIMSG("Execute smi_common_init\n"); + smi_common_init(); + + return 0; + +} + +char *smi_get_region_name(unsigned int region_indx) +{ + switch (region_indx) { + case SMI_COMMON_REG_INDX: + return "smi_common"; + case SMI_LARB0_REG_INDX: + return "larb0"; + case SMI_LARB1_REG_INDX: + return "larb1"; + case SMI_LARB2_REG_INDX: + return "larb2"; + case SMI_LARB3_REG_INDX: + return "larb3"; + default: + SMIMSG("invalid region id=%d", region_indx); + return "unknown"; + } +} + +static int smi_remove(struct platform_device *pdev) +{ + cdev_del(pSmiDev); + unregister_chrdev_region(smiDevNo, 1); + device_destroy(pSmiClass, smiDevNo); + class_destroy(pSmiClass); + return 0; +} + +static int smi_suspend(struct platform_device *pdev, pm_message_t mesg) +{ + return 0; +} + +static int smi_resume(struct platform_device *pdev) +{ + return 0; +} + +static const struct of_device_id smi_of_ids[] = { + {.compatible = "mediatek,smi_common",}, + {} +}; + +static struct platform_driver smiDrv = { + .probe = smi_probe, + .remove = smi_remove, + .suspend = smi_suspend, + .resume = smi_resume, + .driver = { + .name = "MTK_SMI", + .owner = THIS_MODULE, + .of_match_table = smi_of_ids, + } +}; + +static int __init smi_init(void) +{ + SMIMSG("smi_init enter\n"); + spin_lock_init(&g_SMIInfo.SMI_lock); +#if defined(SMI_D1) || defined(SMI_D2) || defined(SMI_D3) + /* MMDVFS init */ + mmdvfs_init(&g_smi_bwc_mm_info); +#endif + memset(g_SMIInfo.pu4ConcurrencyTable, 0, SMI_BWC_SCEN_CNT * sizeof(unsigned int)); + + /* Informs the kernel about the function to be called */ + /* if hardware matching MTK_SMI has been found */ + SMIMSG("register platform driver\n"); + if (platform_driver_register(&smiDrv)) { + SMIERR("failed to register MAU driver"); + return -ENODEV; + } + SMIMSG("exit smi_init\n"); + return 0; +} + +static void __exit smi_exit(void) +{ + platform_driver_unregister(&smiDrv); + +} + + + + + + + +void smi_client_status_change_notify(int module, int mode) +{ + +} + +#if defined(SMI_J) +MTK_SMI_BWC_SCEN smi_get_current_profile(void) +{ + return (MTK_SMI_BWC_SCEN) smi_profile; +} +#endif +#if IS_ENABLED(CONFIG_COMPAT) +/* 32 bits process ioctl support: */ +/* This is prepared for the future extension since currently the sizes of 32 bits */ +/* and 64 bits smi parameters are the same. */ + +struct MTK_SMI_COMPAT_BWC_CONFIG { + compat_int_t scenario; + compat_int_t b_on_off; /* 0 : exit this scenario , 1 : enter this scenario */ +}; + +struct MTK_SMI_COMPAT_BWC_INFO_SET { + compat_int_t property; + compat_int_t value1; + compat_int_t value2; +}; + +struct MTK_SMI_COMPAT_BWC_MM_INFO { + compat_uint_t flag; /* Reserved */ + compat_int_t concurrent_profile; + compat_int_t sensor_size[2]; + compat_int_t video_record_size[2]; + compat_int_t display_size[2]; + compat_int_t tv_out_size[2]; + compat_int_t fps; + compat_int_t video_encode_codec; + compat_int_t video_decode_codec; + compat_int_t hw_ovl_limit; +}; + +#define COMPAT_MTK_IOC_SMI_BWC_CONFIG MTK_IOW(24, struct MTK_SMI_COMPAT_BWC_CONFIG) +#define COMPAT_MTK_IOC_SMI_BWC_INFO_SET MTK_IOWR(28, struct MTK_SMI_COMPAT_BWC_INFO_SET) +#define COMPAT_MTK_IOC_SMI_BWC_INFO_GET MTK_IOWR(29, struct MTK_SMI_COMPAT_BWC_MM_INFO) + +static int compat_get_smi_bwc_config_struct(struct MTK_SMI_COMPAT_BWC_CONFIG __user *data32, + MTK_SMI_BWC_CONFIG __user *data) +{ + + compat_int_t i; + int err; + + /* since the int sizes of 32 A32 and A64 are equal so we don't convert them actually here */ + err = get_user(i, &(data32->scenario)); + err |= put_user(i, &(data->scenario)); + err |= get_user(i, &(data32->b_on_off)); + err |= put_user(i, &(data->b_on_off)); + + return err; +} + +static int compat_get_smi_bwc_mm_info_set_struct(struct MTK_SMI_COMPAT_BWC_INFO_SET __user *data32, + MTK_SMI_BWC_INFO_SET __user *data) +{ + + compat_int_t i; + int err; + + /* since the int sizes of 32 A32 and A64 are equal so we don't convert them actually here */ + err = get_user(i, &(data32->property)); + err |= put_user(i, &(data->property)); + err |= get_user(i, &(data32->value1)); + err |= put_user(i, &(data->value1)); + err |= get_user(i, &(data32->value2)); + err |= put_user(i, &(data->value2)); + + return err; +} + +static int compat_get_smi_bwc_mm_info_struct(struct MTK_SMI_COMPAT_BWC_MM_INFO __user *data32, + MTK_SMI_BWC_MM_INFO __user *data) +{ + compat_uint_t u; + compat_int_t i; + compat_int_t p[2]; + int err; + + /* since the int sizes of 32 A32 and A64 are equal so we don't convert them actually here */ + err = get_user(u, &(data32->flag)); + err |= put_user(u, &(data->flag)); + err |= get_user(i, &(data32->concurrent_profile)); + err |= put_user(i, &(data->concurrent_profile)); + err |= copy_from_user(p, &(data32->sensor_size), sizeof(p)); + err |= copy_to_user(&(data->sensor_size), p, sizeof(p)); + err |= copy_from_user(p, &(data32->video_record_size), sizeof(p)); + err |= copy_to_user(&(data->video_record_size), p, sizeof(p)); + err |= copy_from_user(p, &(data32->display_size), sizeof(p)); + err |= copy_to_user(&(data->display_size), p, sizeof(p)); + err |= copy_from_user(p, &(data32->tv_out_size), sizeof(p)); + err |= copy_to_user(&(data->tv_out_size), p, sizeof(p)); + err |= get_user(i, &(data32->fps)); + err |= put_user(i, &(data->fps)); + err |= get_user(i, &(data32->video_encode_codec)); + err |= put_user(i, &(data->video_encode_codec)); + err |= get_user(i, &(data32->video_decode_codec)); + err |= put_user(i, &(data->video_decode_codec)); + err |= get_user(i, &(data32->hw_ovl_limit)); + err |= put_user(i, &(data->hw_ovl_limit)); + + return err; +} + +static int compat_put_smi_bwc_mm_info_struct(struct MTK_SMI_COMPAT_BWC_MM_INFO __user *data32, + MTK_SMI_BWC_MM_INFO __user *data) +{ + + compat_uint_t u; + compat_int_t i; + compat_int_t p[2]; + int err; + + /* since the int sizes of 32 A32 and A64 are equal so we don't convert them actually here */ + err = get_user(u, &(data->flag)); + err |= put_user(u, &(data32->flag)); + err |= get_user(i, &(data->concurrent_profile)); + err |= put_user(i, &(data32->concurrent_profile)); + err |= copy_from_user(p, &(data->sensor_size), sizeof(p)); + err |= copy_to_user(&(data32->sensor_size), p, sizeof(p)); + err |= copy_from_user(p, &(data->video_record_size), sizeof(p)); + err |= copy_to_user(&(data32->video_record_size), p, sizeof(p)); + err |= copy_from_user(p, &(data->display_size), sizeof(p)); + err |= copy_to_user(&(data32->display_size), p, sizeof(p)); + err |= copy_from_user(p, &(data->tv_out_size), sizeof(p)); + err |= copy_to_user(&(data32->tv_out_size), p, sizeof(p)); + err |= get_user(i, &(data->fps)); + err |= put_user(i, &(data32->fps)); + err |= get_user(i, &(data->video_encode_codec)); + err |= put_user(i, &(data32->video_encode_codec)); + err |= get_user(i, &(data->video_decode_codec)); + err |= put_user(i, &(data32->video_decode_codec)); + err |= get_user(i, &(data->hw_ovl_limit)); + err |= put_user(i, &(data32->hw_ovl_limit)); + return err; +} + +static long MTK_SMI_COMPAT_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + long ret; + + if (!filp->f_op || !filp->f_op->unlocked_ioctl) + return -ENOTTY; + + switch (cmd) { + case COMPAT_MTK_IOC_SMI_BWC_CONFIG: + { + if (COMPAT_MTK_IOC_SMI_BWC_CONFIG == MTK_IOC_SMI_BWC_CONFIG) { + return filp->f_op->unlocked_ioctl(filp, cmd, + (unsigned long)compat_ptr(arg)); + } else { + + struct MTK_SMI_COMPAT_BWC_CONFIG __user *data32; + MTK_SMI_BWC_CONFIG __user *data; + int err; + + data32 = compat_ptr(arg); + data = compat_alloc_user_space(sizeof(MTK_SMI_BWC_CONFIG)); + + if (data == NULL) + return -EFAULT; + + err = compat_get_smi_bwc_config_struct(data32, data); + if (err) + return err; + + ret = filp->f_op->unlocked_ioctl(filp, MTK_IOC_SMI_BWC_CONFIG, + (unsigned long)data); + return ret; + } + } + + case COMPAT_MTK_IOC_SMI_BWC_INFO_SET: + { + + if (COMPAT_MTK_IOC_SMI_BWC_INFO_SET == MTK_IOC_SMI_BWC_INFO_SET) { + return filp->f_op->unlocked_ioctl(filp, cmd, + (unsigned long)compat_ptr(arg)); + } else { + + struct MTK_SMI_COMPAT_BWC_INFO_SET __user *data32; + MTK_SMI_BWC_INFO_SET __user *data; + int err; + + data32 = compat_ptr(arg); + data = compat_alloc_user_space(sizeof(MTK_SMI_BWC_INFO_SET)); + if (data == NULL) + return -EFAULT; + + err = compat_get_smi_bwc_mm_info_set_struct(data32, data); + if (err) + return err; + + return filp->f_op->unlocked_ioctl(filp, MTK_IOC_SMI_BWC_INFO_SET, + (unsigned long)data); + } + } + /* Fall through */ + case COMPAT_MTK_IOC_SMI_BWC_INFO_GET: + { + + if (COMPAT_MTK_IOC_SMI_BWC_INFO_GET == MTK_IOC_SMI_BWC_INFO_GET) { + return filp->f_op->unlocked_ioctl(filp, cmd, + (unsigned long)compat_ptr(arg)); + } else { + struct MTK_SMI_COMPAT_BWC_MM_INFO __user *data32; + MTK_SMI_BWC_MM_INFO __user *data; + int err; + + data32 = compat_ptr(arg); + data = compat_alloc_user_space(sizeof(MTK_SMI_BWC_MM_INFO)); + + if (data == NULL) + return -EFAULT; + + err = compat_get_smi_bwc_mm_info_struct(data32, data); + if (err) + return err; + + ret = filp->f_op->unlocked_ioctl(filp, MTK_IOC_SMI_BWC_INFO_GET, + (unsigned long)data); + + err = compat_put_smi_bwc_mm_info_struct(data32, data); + + if (err) + return err; + + return ret; + } + } + + case MTK_IOC_SMI_DUMP_LARB: + case MTK_IOC_SMI_DUMP_COMMON: + case MTK_IOC_MMDVFS_CMD: + + return filp->f_op->unlocked_ioctl(filp, cmd, (unsigned long)compat_ptr(arg)); + default: + return -ENOIOCTLCMD; + } + +} + +#endif + +#if defined(SMI_J) +int is_mmdvfs_freq_hopping_disabled(void) +{ + return disable_freq_hopping; +} + +int is_mmdvfs_freq_mux_disabled(void) +{ + return disable_freq_mux; +} + +int is_force_max_mmsys_clk(void) +{ + return force_max_mmsys_clk; +} + +int is_force_camera_hpm(void) +{ + return force_camera_hpm; +} +subsys_initcall(smi_init); +module_param_named(disable_freq_hopping, disable_freq_hopping, uint, S_IRUGO | S_IWUSR); +module_param_named(disable_freq_mux, disable_freq_mux, uint, S_IRUGO | S_IWUSR); +module_param_named(force_max_mmsys_clk, force_max_mmsys_clk, uint, S_IRUGO | S_IWUSR); +module_param_named(force_camera_hpm, force_camera_hpm, uint, S_IRUGO | S_IWUSR); +#endif +module_init(smi_init); +module_exit(smi_exit); + +module_param_named(debug_level, smi_debug_level, uint, S_IRUGO | S_IWUSR); +module_param_named(tuning_mode, smi_tuning_mode, uint, S_IRUGO | S_IWUSR); +module_param_named(wifi_disp_transaction, wifi_disp_transaction, uint, S_IRUGO | S_IWUSR); + +MODULE_DESCRIPTION("MTK SMI driver"); +MODULE_AUTHOR("Kendrick Hsu<kendrick.hsu@mediatek.com>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/misc/mediatek/smi/smi_common.h b/drivers/misc/mediatek/smi/smi_common.h new file mode 100644 index 000000000..0202bf3bd --- /dev/null +++ b/drivers/misc/mediatek/smi/smi_common.h @@ -0,0 +1,70 @@ +#ifndef __SMI_COMMON_H__ +#define __SMI_COMMON_H__ + +#include <linux/aee.h> +#include "smi_configuration.h" +#ifdef CONFIG_MTK_CMDQ +#include "cmdq_core.h" +#endif + +#define SMI_CLIENT_DISP 0 +#define SMI_CLIENT_WFD 1 +#define SMI_EVENT_DIRECT_LINK (0x1 << 0) +#define SMI_EVENT_DECOUPLE (0x1 << 1) +#define SMI_EVENT_OVL_CASCADE (0x1 << 2) +#define SMI_EVENT_OVL1_EXTERNAL (0x1 << 3) + +#define SMIMSG(string, args...) pr_debug("[pid=%d]" string, current->tgid, ##args) +#define SMIMSG2(string, args...) pr_debug(string, ##args) +#ifdef CONFIG_MTK_CMDQ +#define SMIMSG3(onoff, string, args...)\ + do {\ + if (onoff == 1)\ + cmdq_core_save_first_dump(string, ##args);\ + SMIMSG(string, ##args);\ + } while (0) +#else +#define SMIMSG3(string, args...) SMIMSG(string, ##args) +#endif +#define SMITMP(string, args...) pr_debug("[pid=%d]"string, current->tgid, ##args) + +#define SMIERR(string, args...) pr_debug("error: " string, ##args) +#define smi_aee_print(string, args...)\ + do {\ + char smi_name[100];\ + snprintf(smi_name, 100, "[" SMI_LOG_TAG "]" string, ##args); \ + } while (0) + +/* +#define SMIERR(string, args...)\ + do {\ + pr_debug("error: " string, ##args); \ + aee_kernel_warning(SMI_LOG_TAG, "error: "string, ##args); \ + } while (0) +#define smi_aee_print(string, args...)\ + do {\ + char smi_name[100];\ + snprintf(smi_name, 100, "[" SMI_LOG_TAG "]" string, ##args); \ + aee_kernel_warning(smi_name, "["SMI_LOG_TAG"]error:"string, ##args); \ + } while (0) +*/ +/* Please use the function to instead gLarbBaseAddr to prevent the NULL pointer access error */ +/* when the corrosponding larb is not exist */ +/* extern unsigned int gLarbBaseAddr[SMI_LARB_NR]; */ +extern unsigned long get_larb_base_addr(int larb_id); + +/* extern char *smi_port_name[][21]; */ +/* for slow motion force 30 fps */ +extern int primary_display_force_set_vsync_fps(unsigned int fps); +extern unsigned int primary_display_get_fps(void); +extern void smi_client_status_change_notify(int module, int mode); +extern void smi_dumpLarb(unsigned int index); +extern void smi_dumpCommon(void); +/* void register_base_dump(void); */ + +extern struct SMI_PROFILE_CONFIG smi_profile_config[SMI_PROFILE_CONFIG_NUM]; +extern void smi_set_nonconstant_variable(void); +extern void save_default_common_val(int *is_default_value_saved, unsigned int *default_val_smi_array); +extern int smi_bus_regs_setting(int profile, struct SMI_SETTING *settings); + +#endif diff --git a/drivers/misc/mediatek/smi/smi_config_util.c b/drivers/misc/mediatek/smi/smi_config_util.c new file mode 100644 index 000000000..2683adf45 --- /dev/null +++ b/drivers/misc/mediatek/smi/smi_config_util.c @@ -0,0 +1,49 @@ +#include <asm/io.h> +#include <linux/string.h> +#include "smi_reg.h" +#include <mach/mt_smi.h> +#include "smi_common.h" +#include "smi_configuration.h" +#include "smi_config_util.h" + +int smi_bus_regs_setting(int profile, struct SMI_SETTING *settings) +{ + int i = 0; + int j = 0; + + if (!settings || profile < 0 || profile >= SMI_BWC_SCEN_CNT) + return -1; + + if (settings->smi_common_reg_num == 0) + return -1; + + /* set regs of common */ + SMIMSG("Current Scen:%d", profile); + for (i = 0 ; i < settings->smi_common_reg_num ; ++i) { + M4U_WriteReg32(SMI_COMMON_EXT_BASE, + settings->smi_common_setting_vals[i].offset, + settings->smi_common_setting_vals[i].value); + } + + /* set regs of larbs */ + for (i = 0 ; i < SMI_LARB_NR ; ++i) + for (j = 0 ; j < settings->smi_larb_reg_num[i] ; ++j) { + M4U_WriteReg32(gLarbBaseAddr[i], + settings->smi_larb_setting_vals[i][j].offset, + settings->smi_larb_setting_vals[i][j].value); + } + return 0; +} + +void save_default_common_val(int *is_default_value_saved, unsigned int *default_val_smi_array) +{ + if (!*is_default_value_saved) { + int i = 0; + + SMIMSG("Save default config:\n"); + for (i = 0 ; i < SMI_LARB_NR ; ++i) + default_val_smi_array[i] = M4U_ReadReg32(SMI_COMMON_EXT_BASE, smi_common_l1arb_offset[i]); + + *is_default_value_saved = 1; + } +} diff --git a/drivers/misc/mediatek/smi/smi_config_util.h b/drivers/misc/mediatek/smi/smi_config_util.h new file mode 100644 index 000000000..8ef3934a9 --- /dev/null +++ b/drivers/misc/mediatek/smi/smi_config_util.h @@ -0,0 +1,8 @@ +#ifndef _SMI_CONFIG_UTIL_H_ +#define _SMI_CONFIG_UTIL_H_ + +extern unsigned long smi_common_l1arb_offset[SMI_LARB_NR]; +extern unsigned long gLarbBaseAddr[SMI_LARB_NR]; + + +#endif diff --git a/drivers/misc/mediatek/smi/smi_configuration.c b/drivers/misc/mediatek/smi/smi_configuration.c new file mode 100644 index 000000000..af1228ad7 --- /dev/null +++ b/drivers/misc/mediatek/smi/smi_configuration.c @@ -0,0 +1,1307 @@ +#include <asm/io.h> +#include <linux/string.h> +#include <mach/mt_smi.h> +#include "smi_configuration.h" +#include "smi_common.h" +#include "smi_reg.h" + +/* add static after all platform setting parameters moved to here */ +int is_default_value_saved; +unsigned int default_val_smi_l1arb[SMI_LARB_NR] = { 0 }; + +#define SMI_LARB_NUM_MAX 8 + +#if defined(SMI_D1) +unsigned int smi_dbg_disp_mask = 1; +unsigned int smi_dbg_vdec_mask = 2; +unsigned int smi_dbg_imgsys_mask = 4; +unsigned int smi_dbg_venc_mask = 8; +unsigned int smi_dbg_mjc_mask = 0; + +unsigned long smi_common_l1arb_offset[SMI_LARB_NR] = { + REG_OFFSET_SMI_L1ARB0, REG_OFFSET_SMI_L1ARB1, REG_OFFSET_SMI_L1ARB2 +}; + +unsigned long smi_larb0_debug_offset[SMI_LARB0_DEBUG_OFFSET_NUM] = { + 0x0, 0x8, 0x10, 0x24, 0x50, 0x60, 0xa0, 0xa4, 0xa8, 0xac, 0xb0, 0xb4, 0xb8, 0xbc, 0xc0, + 0xc8, + 0xcc, 0x200, 0x204, 0x208, 0x20c, 0x210, 0x214, 0x218, 0x21c, 0x220, 0x224, 0x228, 0x22c, + 0x230, + 0x234, 0x238, 0x23c, 0x240, 0x244, 0x248, 0x24c, 0x280, 0x284, 0x288, 0x28c, 0x290, 0x294, + 0x298, + 0x29c, 0x2a0, 0x2a4, 0x2a8, 0x2ac, 0x2b0, 0x2b4, 0x2b8, 0x2bc, 0x2c0, 0x2c4, 0x2c8, 0x2cc, + 0x2d0, + 0x2d4, 0x2d8, 0x2dc, 0x2e0, 0x2e4, 0x2e8, 0x2ec, 0x2f0, 0x2f4, 0x2f8, 0x2fc +}; + +unsigned long smi_larb1_debug_offset[SMI_LARB1_DEBUG_OFFSET_NUM] = { + 0x0, 0x8, 0x10, 0x24, 0x50, 0x60, 0xa0, 0xa4, 0xa8, 0xac, 0xb0, 0xb4, 0xb8, 0xbc, 0xc0, + 0xc8, + 0xcc, 0x200, 0x204, 0x208, 0x20c, 0x210, 0x214, 0x218, 0x21c, 0x220, 0x224, 0x228, 0x22c, + 0x230, + 0x234, 0x238, 0x23c, 0x240, 0x244, 0x248, 0x24c, 0x280, 0x284, 0x288, 0x28c, 0x290, 0x294, + 0x298, + 0x29c, 0x2a0, 0x2a4, 0x2a8, 0x2ac, 0x2b0, 0x2b4, 0x2b8, 0x2bc, 0x2c0, 0x2c4, 0x2c8, 0x2cc, + 0x2d0, + 0x2d4, 0x2d8, 0x2dc, 0x2e0, 0x2e4, 0x2e8, 0x2ec, 0x2f0, 0x2f4, 0x2f8, 0x2fc +}; + +unsigned long smi_larb2_debug_offset[SMI_LARB2_DEBUG_OFFSET_NUM] = { + 0x0, 0x8, 0x10, 0x24, 0x50, 0x60, 0xa0, 0xa4, 0xa8, 0xac, 0xb0, 0xb4, 0xb8, 0xbc, 0xc0, + 0xc8, + 0xcc, 0x200, 0x204, 0x208, 0x20c, 0x210, 0x214, 0x218, 0x21c, 0x220, 0x224, 0x228, 0x22c, + 0x230, + 0x234, 0x238, 0x23c, 0x240, 0x244, 0x248, 0x24c, 0x280, 0x284, 0x288, 0x28c, 0x290, 0x294, + 0x298, + 0x29c, 0x2a0, 0x2a4, 0x2a8, 0x2ac, 0x2b0, 0x2b4, 0x2b8, 0x2bc, 0x2c0, 0x2c4, 0x2c8, 0x2cc, + 0x2d0, + 0x2d4, 0x2d8, 0x2dc, 0x2e0, 0x2e4, 0x2e8, 0x2ec, 0x2f0, 0x2f4, 0x2f8, 0x2fc +}; + +unsigned long smi_larb3_debug_offset[SMI_LARB3_DEBUG_OFFSET_NUM] = { + 0x0, 0x8, 0x10, 0x24, 0x50, 0x60, 0xa0, 0xa4, 0xa8, 0xac, 0xb0, 0xb4, 0xb8, 0xbc, 0xc0, + 0xc8, + 0xcc, 0x200, 0x204, 0x208, 0x20c, 0x210, 0x214, 0x218, 0x21c, 0x220, 0x224, 0x228, 0x22c, + 0x230, + 0x234, 0x238, 0x23c, 0x240, 0x244, 0x248, 0x24c, 0x280, 0x284, 0x288, 0x28c, 0x290, 0x294, + 0x298, + 0x29c, 0x2a0, 0x2a4, 0x2a8, 0x2ac, 0x2b0, 0x2b4, 0x2b8, 0x2bc, 0x2c0, 0x2c4, 0x2c8, 0x2cc, + 0x2d0, + 0x2d4, 0x2d8, 0x2dc, 0x2e0, 0x2e4, 0x2e8, 0x2ec, 0x2f0, 0x2f4, 0x2f8, 0x2fc +}; + +unsigned long smi_common_debug_offset[SMI_COMMON_DEBUG_OFFSET_NUM] = { + 0x100, 0x104, 0x108, 0x10C, 0x110, 0x114, 0x220, 0x230, 0x234, 0x238, 0x400, 0x404, 0x408, + 0x40C, 0x430, 0x440 +}; + +int smi_larb_debug_offset_num[SMI_LARB_NR] = { + SMI_LARB0_DEBUG_OFFSET_NUM, SMI_LARB1_DEBUG_OFFSET_NUM, SMI_LARB2_DEBUG_OFFSET_NUM, + SMI_LARB3_DEBUG_OFFSET_NUM +}; + +unsigned long *smi_larb_debug_offset[SMI_LARB_NR] = { + smi_larb0_debug_offset, smi_larb1_debug_offset, smi_larb2_debug_offset, + smi_larb3_debug_offset +}; + +#define SMI_PROFILE_SETTING_COMMON_INIT_NUM 7 +#define SMI_VC_SETTING_NUM SMI_LARB_NR + + +/* vc setting */ +struct SMI_SETTING_VALUE smi_vc_setting[SMI_VC_SETTING_NUM] = { + {0x20, 0}, {0x20, 2}, {0x20, 1}, {0x20, 1} +}; + +/* init_setting */ +struct SMI_SETTING_VALUE smi_profile_setting_common_init[SMI_PROFILE_SETTING_COMMON_INIT_NUM] = { + {0, 0}, {0, 0x1000}, {0, 0x1000}, {0, 0x1000}, + {0x100, 0x1b}, + {0x234, (0x1 << 31) + (0x1d << 26) + (0x1f << 21) + (0x0 << 20) + (0x3 << 15) + + (0x4 << 10) + (0x4 << 5) + 0x5}, + {0x230, 0x1f + (0x8 << 4) + (0x7 << 9)} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb0_init[SMI_LARB0_PORT_NUM] = { + {0x200, 0x1f}, {0x204, 4}, {0x208, 6}, {0x20c, 0x1f}, {0x210, 4}, {0x214, 1}, {0x218, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb1_init[SMI_LARB1_PORT_NUM] = { + {0x200, 1}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb2_init[SMI_LARB2_PORT_NUM] = { + {0x200, 1}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1}, {0x21c, + 1}, + {0x220, 1}, {0x224, 1}, {0x228, 1}, {0x22c, 1}, {0x230, 1}, {0x234, 1}, {0x238, 1}, {0x23c, + 1}, + {0x240, 1}, {0x244, 1}, {0x248, 1}, {0x24c, 1}, {0x250, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb3_init[SMI_LARB3_PORT_NUM] = { + {0x200, 1}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1}, {0x21c, + 1}, + {0x220, 1}, {0x224, 1}, {0x228, 1}, {0x22c, 1}, {0x230, 1} +}; + +struct SMI_SETTING init_setting_config = { + SMI_PROFILE_SETTING_COMMON_INIT_NUM, smi_profile_setting_common_init, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_init, smi_profile_setting_larb1_init, + smi_profile_setting_larb2_init, smi_profile_setting_larb3_init} +}; + +#define SMI_PROFILE_SETTING_COMMON_VR_NUM SMI_LARB_NR +/* vr_setting */ +struct SMI_SETTING_VALUE smi_profile_setting_common_vr[SMI_PROFILE_SETTING_COMMON_VR_NUM] = { + {0, 0x11F1}, {0, 0x1000}, {0, 0x120A}, {0, 0x11F3} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb0_vr[SMI_LARB0_PORT_NUM] = { + {0x200, 8}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 2}, {0x218, 4} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb1_vr[SMI_LARB1_PORT_NUM] = { + {0x200, 1}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb2_vr[SMI_LARB2_PORT_NUM] = { + {0x200, 1}, {0x204, 4}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1}, {0x21c, + 1}, + {0x220, 1}, {0x224, 1}, {0x228, 4}, {0x22c, 1}, {0x230, 2}, {0x234, 2}, {0x238, 1}, {0x23c, + 1}, + {0x240, 1}, {0x244, 1}, {0x248, 1}, {0x24c, 1}, {0x250, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb3_vr[SMI_LARB3_PORT_NUM] = { + {0x200, 1}, {0x204, 2}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1}, {0x21c, + 1}, + {0x220, 1}, {0x224, 2}, {0x228, 1}, {0x22c, 3}, {0x230, 2} +}; + +struct SMI_SETTING vr_setting_config = { + SMI_PROFILE_SETTING_COMMON_VR_NUM, smi_profile_setting_common_vr, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_vr, smi_profile_setting_larb1_vr, smi_profile_setting_larb2_vr, + smi_profile_setting_larb3_vr} +}; + +#define SMI_PROFILE_SETTING_COMMON_VP_NUM SMI_LARB_NR +/* vp_setting */ +struct SMI_SETTING_VALUE smi_profile_setting_common_vp[SMI_PROFILE_SETTING_COMMON_VP_NUM] = { + {0, 0x1262}, {0, 0x11E9}, {0, 0x1000}, {0, 0x123D} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb0_vp[SMI_LARB0_PORT_NUM] = { + {0x200, 8}, {0x204, 1}, {0x208, 2}, {0x20c, 1}, {0x210, 3}, {0x214, 1}, {0x218, 4} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb1_vp[SMI_LARB1_PORT_NUM] = { + {0x200, 0xb}, {0x204, 0xe}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb2_vp[SMI_LARB2_PORT_NUM] = { + {0x200, 1}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1}, {0x21c, + 1}, + {0x220, 1}, {0x224, 1}, {0x228, 1}, {0x22c, 1}, {0x230, 1}, {0x234, 1}, {0x238, 1}, {0x23c, + 1}, + {0x240, 1}, {0x244, 1}, {0x248, 1}, {0x24c, 1}, {0x250, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb3_vp[SMI_LARB3_PORT_NUM] = { + {0x200, 1}, {0x204, 2}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1}, {0x21c, + 1}, + {0x220, 1}, {0x224, 1}, {0x228, 1}, {0x22c, 3}, {0x230, 2} +}; + +struct SMI_SETTING vp_setting_config = { + SMI_PROFILE_SETTING_COMMON_VP_NUM, smi_profile_setting_common_vp, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_vp, smi_profile_setting_larb1_vp, smi_profile_setting_larb2_vp, + smi_profile_setting_larb3_vp} +}; + +/* vr series */ +struct SMI_SETTING icfp_setting_config = { + SMI_PROFILE_SETTING_COMMON_VR_NUM, smi_profile_setting_common_vr, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_vr, smi_profile_setting_larb1_vr, smi_profile_setting_larb2_vr, + smi_profile_setting_larb3_vr} +}; + +struct SMI_SETTING vr_slow_setting_config = { + SMI_PROFILE_SETTING_COMMON_VR_NUM, smi_profile_setting_common_vr, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_vr, smi_profile_setting_larb1_vr, smi_profile_setting_larb2_vr, + smi_profile_setting_larb3_vr} +}; + +struct SMI_SETTING venc_setting_config = { + SMI_PROFILE_SETTING_COMMON_VR_NUM, smi_profile_setting_common_vr, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_vr, smi_profile_setting_larb1_vr, smi_profile_setting_larb2_vr, + smi_profile_setting_larb3_vr} +}; + +/* vp series */ +struct SMI_SETTING vpwfd_setting_config = { + SMI_PROFILE_SETTING_COMMON_VP_NUM, smi_profile_setting_common_vp, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_vp, smi_profile_setting_larb1_vp, smi_profile_setting_larb2_vp, + smi_profile_setting_larb3_vp} +}; + +struct SMI_SETTING swdec_vp_setting_config = { + SMI_PROFILE_SETTING_COMMON_VP_NUM, smi_profile_setting_common_vp, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_vp, smi_profile_setting_larb1_vp, smi_profile_setting_larb2_vp, + smi_profile_setting_larb3_vp} +}; + +/* init series */ +struct SMI_SETTING mm_gpu_setting_config = { + SMI_PROFILE_SETTING_COMMON_INIT_NUM, smi_profile_setting_common_init, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_init, smi_profile_setting_larb1_init, + smi_profile_setting_larb2_init, smi_profile_setting_larb3_init} +}; + +struct SMI_SETTING ui_idle_setting_config = { 0, NULL, {0}, {0} }; +struct SMI_SETTING hdmi_setting_config = { 0, NULL, {0}, {0} }; +struct SMI_SETTING hdmi4k_setting_config = { 0, NULL, {0}, {0} }; +struct SMI_SETTING vss_setting_config = { 0, NULL, {0}, {0} }; + +#elif defined(SMI_D3) +unsigned int smi_dbg_disp_mask = 1; +unsigned int smi_dbg_vdec_mask = 2; +unsigned int smi_dbg_imgsys_mask = 4; +unsigned int smi_dbg_venc_mask = 8; +unsigned int smi_dbg_mjc_mask = 0; + +unsigned long smi_common_l1arb_offset[SMI_LARB_NR] = { + REG_OFFSET_SMI_L1ARB0, REG_OFFSET_SMI_L1ARB1, REG_OFFSET_SMI_L1ARB2, REG_OFFSET_SMI_L1ARB3 +}; + +static unsigned long smi_larb0_debug_offset[SMI_LARB0_DEBUG_OFFSET_NUM] = { + 0x0, 0x8, 0x10, 0x24, 0x50, 0x60, 0xa0, 0xa4, 0xa8, 0xac, 0xb0, 0xb4, 0xb8, 0xbc, 0xc0, + 0xc8, + 0xcc, 0x200, 0x204, 0x208, 0x20c, 0x210, 0x214, 0x218, 0x21c, 0x220, 0x224, 0x228, 0x22c, + 0x230, + 0x234, 0x238, 0x23c, 0x240, 0x244, 0x248, 0x24c, 0x280, 0x284, 0x288, 0x28c, 0x290, 0x294, + 0x298, + 0x29c, 0x2a0, 0x2a4, 0x2a8, 0x2ac, 0x2b0, 0x2b4, 0x2b8, 0x2bc, 0x2c0, 0x2c4, 0x2c8, 0x2cc, + 0x2d0, + 0x2d4, 0x2d8, 0x2dc, 0x2e0, 0x2e4, 0x2e8, 0x2ec, 0x2f0, 0x2f4, 0x2f8, 0x2fc +}; + +static unsigned long smi_larb1_debug_offset[SMI_LARB1_DEBUG_OFFSET_NUM] = { + 0x0, 0x8, 0x10, 0x24, 0x50, 0x60, 0xa0, 0xa4, 0xa8, 0xac, 0xb0, 0xb4, 0xb8, 0xbc, 0xc0, + 0xc8, + 0xcc, 0x200, 0x204, 0x208, 0x20c, 0x210, 0x214, 0x218, 0x21c, 0x220, 0x224, 0x228, 0x22c, + 0x230, + 0x234, 0x238, 0x23c, 0x240, 0x244, 0x248, 0x24c, 0x280, 0x284, 0x288, 0x28c, 0x290, 0x294, + 0x298, + 0x29c, 0x2a0, 0x2a4, 0x2a8, 0x2ac, 0x2b0, 0x2b4, 0x2b8, 0x2bc, 0x2c0, 0x2c4, 0x2c8, 0x2cc, + 0x2d0, + 0x2d4, 0x2d8, 0x2dc, 0x2e0, 0x2e4, 0x2e8, 0x2ec, 0x2f0, 0x2f4, 0x2f8, 0x2fc +}; + +static unsigned long smi_larb2_debug_offset[SMI_LARB2_DEBUG_OFFSET_NUM] = { + 0x0, 0x8, 0x10, 0x24, 0x50, 0x60, 0xa0, 0xa4, 0xa8, 0xac, 0xb0, 0xb4, 0xb8, 0xbc, 0xc0, + 0xc8, + 0xcc, 0x200, 0x204, 0x208, 0x20c, 0x210, 0x214, 0x218, 0x21c, 0x220, 0x224, 0x228, 0x22c, + 0x230, + 0x234, 0x238, 0x23c, 0x240, 0x244, 0x248, 0x24c, 0x280, 0x284, 0x288, 0x28c, 0x290, 0x294, + 0x298, + 0x29c, 0x2a0, 0x2a4, 0x2a8, 0x2ac, 0x2b0, 0x2b4, 0x2b8, 0x2bc, 0x2c0, 0x2c4, 0x2c8, 0x2cc, + 0x2d0, + 0x2d4, 0x2d8, 0x2dc, 0x2e0, 0x2e4, 0x2e8, 0x2ec, 0x2f0, 0x2f4, 0x2f8, 0x2fc +}; + +static unsigned long smi_larb3_debug_offset[SMI_LARB3_DEBUG_OFFSET_NUM] = { + 0x0, 0x8, 0x10, 0x24, 0x50, 0x60, 0xa0, 0xa4, 0xa8, 0xac, 0xb0, 0xb4, 0xb8, 0xbc, 0xc0, + 0xc8, + 0xcc, 0x200, 0x204, 0x208, 0x20c, 0x210, 0x214, 0x218, 0x21c, 0x220, 0x224, 0x228, 0x22c, + 0x230, + 0x234, 0x238, 0x23c, 0x240, 0x244, 0x248, 0x24c, 0x280, 0x284, 0x288, 0x28c, 0x290, 0x294, + 0x298, + 0x29c, 0x2a0, 0x2a4, 0x2a8, 0x2ac, 0x2b0, 0x2b4, 0x2b8, 0x2bc, 0x2c0, 0x2c4, 0x2c8, 0x2cc, + 0x2d0, + 0x2d4, 0x2d8, 0x2dc, 0x2e0, 0x2e4, 0x2e8, 0x2ec, 0x2f0, 0x2f4, 0x2f8, 0x2fc +}; + +unsigned long smi_common_debug_offset[SMI_COMMON_DEBUG_OFFSET_NUM] = { + 0x100, 0x104, 0x108, 0x10C, 0x110, 0x114, 0x220, 0x230, 0x234, 0x238, 0x400, 0x404, 0x408, + 0x40C, 0x430, 0x440 +}; + +int smi_larb_debug_offset_num[SMI_LARB_NR] = { + SMI_LARB0_DEBUG_OFFSET_NUM, SMI_LARB1_DEBUG_OFFSET_NUM, SMI_LARB2_DEBUG_OFFSET_NUM, + SMI_LARB3_DEBUG_OFFSET_NUM +}; + +unsigned long *smi_larb_debug_offset[SMI_LARB_NR] = { + smi_larb0_debug_offset, smi_larb1_debug_offset, smi_larb2_debug_offset, + smi_larb3_debug_offset +}; + + +#define SMI_PROFILE_SETTING_COMMON_INIT_NUM 7 +#define SMI_VC_SETTING_NUM SMI_LARB_NR + + +/* vc setting */ +struct SMI_SETTING_VALUE smi_vc_setting[SMI_VC_SETTING_NUM] = { + {0x20, 0}, {0x20, 2}, {0x20, 1}, {0x20, 1} +}; + +/* init_setting */ +struct SMI_SETTING_VALUE smi_profile_setting_common_init[SMI_PROFILE_SETTING_COMMON_INIT_NUM] = { + {0, 0}, {0, 0x1000}, {0, 0x1000}, {0, 0x1000}, + {0x100, 0xb}, + {0x234, (0x1 << 31) + (0x1d << 26) + (0x1f << 21) + (0x0 << 20) + (0x3 << 15) + + (0x4 << 10) + (0x4 << 5) + 0x5}, + {0x230, 0xf + (0x8 << 4) + (0x7 << 9)} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb0_init[SMI_LARB0_PORT_NUM] = { + {0x200, 0x1f}, {0x204, 8}, {0x208, 6}, {0x20c, 0x1f}, {0x210, 4}, {0x214, 1}, {0x218, 0}, + {0x21c, 2}, + {0x220, 1}, {0x224, 3} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb1_init[SMI_LARB1_PORT_NUM] = { + {0x200, 1}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb2_init[SMI_LARB2_PORT_NUM] = { + {0x200, 1}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1}, {0x21c, + 1}, + {0x220, 1}, {0x224, 1}, {0x228, 1}, {0x22c, 1}, {0x230, 1}, {0x234, 1}, {0x238, 1}, {0x23c, + 1}, + {0x240, 1}, {0x244, 1}, {0x248, 1}, {0x24c, 1}, {0x250, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb3_init[SMI_LARB3_PORT_NUM] = { + {0x200, 1}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1}, {0x21c, + 1}, + {0x220, 1}, {0x224, 1}, {0x228, 1}, {0x22c, 1}, {0x230, 1} +}; + +struct SMI_SETTING init_setting_config = { + SMI_PROFILE_SETTING_COMMON_INIT_NUM, smi_profile_setting_common_init, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_init, smi_profile_setting_larb1_init, + smi_profile_setting_larb2_init, smi_profile_setting_larb3_init} +}; + +#define SMI_PROFILE_SETTING_COMMON_VR_NUM SMI_LARB_NR +/* vr_setting */ +struct SMI_SETTING_VALUE smi_profile_setting_common_vr[SMI_PROFILE_SETTING_COMMON_VR_NUM] = { + {0, 0x1417}, {0, 0x1000}, {0, 0x11D0}, {0, 0x11F8} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb0_vr[SMI_LARB0_PORT_NUM] = { + {0x200, 0xa}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1}, + {0x21c, 4}, + {0x220, 1}, {0x224, 6} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb1_vr[SMI_LARB1_PORT_NUM] = { + {0x200, 1}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb2_vr[SMI_LARB2_PORT_NUM] = { + {0x200, 1}, {0x204, 2}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 2}, {0x21c, + 1}, + {0x220, 2}, {0x224, 1}, {0x228, 1}, {0x22c, 8}, {0x230, 1}, {0x234, 1}, {0x238, 2}, {0x23c, + 2}, + {0x240, 2}, {0x244, 1}, {0x248, 1}, {0x24c, 1}, {0x250, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb3_vr[SMI_LARB3_PORT_NUM] = { + {0x200, 1}, {0x204, 2}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1}, {0x21c, + 1}, + {0x220, 1}, {0x224, 2}, {0x228, 1}, {0x22c, 3}, {0x230, 2} +}; + +struct SMI_SETTING vr_setting_config = { + SMI_PROFILE_SETTING_COMMON_VR_NUM, smi_profile_setting_common_vr, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_vr, smi_profile_setting_larb1_vr, smi_profile_setting_larb2_vr, + smi_profile_setting_larb3_vr} +}; + +#define SMI_PROFILE_SETTING_COMMON_VP_NUM SMI_LARB_NR +/* vp_setting */ +struct SMI_SETTING_VALUE smi_profile_setting_common_vp[SMI_PROFILE_SETTING_COMMON_VP_NUM] = { + {0, 0x1262}, {0, 0x11E9}, {0, 0x1000}, {0, 0x123D} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb0_vp[SMI_LARB0_PORT_NUM] = { + {0x200, 8}, {0x204, 1}, {0x208, 2}, {0x20c, 1}, {0x210, 3}, {0x214, 1}, {0x218, 4}, {0x21c, + 1}, + {0x220, 1}, {0x224, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb1_vp[SMI_LARB1_PORT_NUM] = { + {0x200, 0xb}, {0x204, 0xe}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb2_vp[SMI_LARB2_PORT_NUM] = { + {0x200, 1}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1}, {0x21c, + 1}, + {0x220, 1}, {0x224, 1}, {0x228, 1}, {0x22c, 1}, {0x230, 1}, {0x234, 1}, {0x238, 1}, {0x23c, + 1}, + {0x240, 1}, {0x244, 1}, {0x248, 1}, {0x24c, 1}, {0x250, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb3_vp[SMI_LARB3_PORT_NUM] = { + {0x200, 1}, {0x204, 2}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1}, {0x21c, + 1}, + {0x220, 1}, {0x224, 2}, {0x228, 1}, {0x22c, 3}, {0x230, 2} +}; + +struct SMI_SETTING vp_setting_config = { + SMI_PROFILE_SETTING_COMMON_VP_NUM, smi_profile_setting_common_vp, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_vp, smi_profile_setting_larb1_vp, smi_profile_setting_larb2_vp, + smi_profile_setting_larb3_vp} +}; + +#define SMI_PROFILE_SETTING_COMMON_VPWFD_NUM SMI_LARB_NR +/* vpwfd_setting */ +struct SMI_SETTING_VALUE smi_profile_setting_common_vpwfd[SMI_PROFILE_SETTING_COMMON_VPWFD_NUM] = { + {0, 0x14B6}, {0, 0x11EE}, {0, 0x1000}, {0, 0x11F2} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb0_vpwfd[SMI_LARB0_PORT_NUM] = { + {0x200, 0xc}, {0x204, 8}, {0x208, 6}, {0x20c, 0xc}, {0x210, 4}, {0x214, 1}, {0x218, 1}, + {0x21c, 3}, + {0x220, 2}, {0x224, 5} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb1_vpwfd[SMI_LARB1_PORT_NUM] = { + {0x200, 0xb}, {0x204, 0xe}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb2_vpwfd[SMI_LARB2_PORT_NUM] = { + {0x200, 1}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1}, {0x21c, + 1}, + {0x220, 1}, {0x224, 1}, {0x228, 1}, {0x22c, 1}, {0x230, 1}, {0x234, 1}, {0x238, 1}, {0x23c, + 1}, + {0x240, 1}, {0x244, 1}, {0x248, 1}, {0x24c, 1}, {0x250, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb3_vpwfd[SMI_LARB3_PORT_NUM] = { + {0x200, 1}, {0x204, 2}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1}, {0x21c, + 1}, + {0x220, 1}, {0x224, 2}, {0x228, 1}, {0x22c, 3}, {0x230, 2} +}; + +struct SMI_SETTING vpwfd_setting_config = { + SMI_PROFILE_SETTING_COMMON_VPWFD_NUM, smi_profile_setting_common_vpwfd, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_vpwfd, smi_profile_setting_larb1_vpwfd, + smi_profile_setting_larb2_vpwfd, smi_profile_setting_larb3_vpwfd} +}; + +#define SMI_PROFILE_SETTING_COMMON_ICFP_NUM SMI_LARB_NR +/* icfp_setting */ +struct SMI_SETTING_VALUE smi_profile_setting_common_icfp[SMI_PROFILE_SETTING_COMMON_ICFP_NUM] = { + {0, 0x14E2}, {0, 0x1000}, {0, 0x1310}, {0, 0x106F} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb0_icfp[SMI_LARB0_PORT_NUM] = { + {0x200, 0xe}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1}, + {0x21c, 2}, + {0x220, 2}, {0x224, 3} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb1_icfp[SMI_LARB1_PORT_NUM] = { + {0x200, 1}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb2_icfp[SMI_LARB2_PORT_NUM] = { + {0x200, 0xc}, {0x204, 4}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1}, + {0x21c, 1}, + {0x220, 1}, {0x224, 1}, {0x228, 1}, {0x22c, 3}, {0x230, 1}, {0x234, 1}, {0x238, 1}, {0x23c, + 1}, + {0x240, 1}, {0x244, 1}, {0x248, 1}, {0x24c, 1}, {0x250, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb3_icfp[SMI_LARB3_PORT_NUM] = { + {0x200, 1}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1}, {0x21c, + 1}, + {0x220, 1}, {0x224, 1}, {0x228, 1}, {0x22c, 1}, {0x230, 1} +}; + +struct SMI_SETTING icfp_setting_config = { + SMI_PROFILE_SETTING_COMMON_ICFP_NUM, smi_profile_setting_common_icfp, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_icfp, smi_profile_setting_larb1_icfp, + smi_profile_setting_larb2_icfp, smi_profile_setting_larb3_icfp} +}; + +/* vr series */ +struct SMI_SETTING vr_slow_setting_config = { + SMI_PROFILE_SETTING_COMMON_VR_NUM, smi_profile_setting_common_vr, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_vr, smi_profile_setting_larb1_vr, smi_profile_setting_larb2_vr, + smi_profile_setting_larb3_vr} +}; + +struct SMI_SETTING venc_setting_config = { + SMI_PROFILE_SETTING_COMMON_VR_NUM, smi_profile_setting_common_vr, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_vr, smi_profile_setting_larb1_vr, smi_profile_setting_larb2_vr, + smi_profile_setting_larb3_vr} +}; + +/* vp series */ +struct SMI_SETTING swdec_vp_setting_config = { + SMI_PROFILE_SETTING_COMMON_VP_NUM, smi_profile_setting_common_vp, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_vp, smi_profile_setting_larb1_vp, smi_profile_setting_larb2_vp, + smi_profile_setting_larb3_vp} +}; + +/* init seris */ +struct SMI_SETTING mm_gpu_setting_config = { + SMI_PROFILE_SETTING_COMMON_INIT_NUM, smi_profile_setting_common_init, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_init, smi_profile_setting_larb1_init, + smi_profile_setting_larb2_init, smi_profile_setting_larb3_init} +}; + +struct SMI_SETTING vss_setting_config = { 0, NULL, {0}, {0} }; +struct SMI_SETTING ui_idle_setting_config = { 0, NULL, {0}, {0} }; +struct SMI_SETTING hdmi_setting_config = { 0, NULL, {0}, {0} }; +struct SMI_SETTING hdmi4k_setting_config = { 0, NULL, {0}, {0} }; + +#elif defined(SMI_J) +unsigned int smi_dbg_disp_mask = 1; +unsigned int smi_dbg_vdec_mask = 2; +unsigned int smi_dbg_imgsys_mask = 4; +unsigned int smi_dbg_venc_mask = 8; +unsigned int smi_dbg_mjc_mask = 0; + +unsigned long smi_common_l1arb_offset[SMI_LARB_NR] = { + REG_OFFSET_SMI_L1ARB0, REG_OFFSET_SMI_L1ARB1, REG_OFFSET_SMI_L1ARB2, REG_OFFSET_SMI_L1ARB3 +}; + +unsigned long smi_larb0_debug_offset[SMI_LARB0_DEBUG_OFFSET_NUM] = { + 0x0, 0x8, 0x10, 0x24, 0x50, 0x60, 0xa0, 0xa4, 0xa8, 0xac, 0xb0, 0xb4, 0xb8, 0xbc, 0xc0, + 0xc8, + 0xcc, 0x200, 0x204, 0x208, 0x20c, 0x210, 0x214, 0x218, 0x21c, 0x220, 0x224, 0x228, 0x22c, + 0x230, + 0x234, 0x238, 0x23c, 0x240, 0x244, 0x248, 0x24c, 0x280, 0x284, 0x288, 0x28c, 0x290, 0x294, + 0x298, + 0x29c, 0x2a0, 0x2a4, 0x2a8, 0x2ac, 0x2b0, 0x2b4, 0x2b8, 0x2bc, 0x2c0, 0x2c4, 0x2c8, 0x2cc, + 0x2d0, + 0x2d4, 0x2d8, 0x2dc, 0x2e0, 0x2e4, 0x2e8, 0x2ec, 0x2f0, 0x2f4, 0x2f8, 0x2fc +}; + +unsigned long smi_larb1_debug_offset[SMI_LARB1_DEBUG_OFFSET_NUM] = { + 0x0, 0x8, 0x10, 0x24, 0x50, 0x60, 0xa0, 0xa4, 0xa8, 0xac, 0xb0, 0xb4, 0xb8, 0xbc, 0xc0, + 0xc8, + 0xcc, 0x200, 0x204, 0x208, 0x20c, 0x210, 0x214, 0x218, 0x21c, 0x220, 0x224, 0x228, 0x22c, + 0x230, + 0x234, 0x238, 0x23c, 0x240, 0x244, 0x248, 0x24c, 0x280, 0x284, 0x288, 0x28c, 0x290, 0x294, + 0x298, + 0x29c, 0x2a0, 0x2a4, 0x2a8, 0x2ac, 0x2b0, 0x2b4, 0x2b8, 0x2bc, 0x2c0, 0x2c4, 0x2c8, 0x2cc, + 0x2d0, + 0x2d4, 0x2d8, 0x2dc, 0x2e0, 0x2e4, 0x2e8, 0x2ec, 0x2f0, 0x2f4, 0x2f8, 0x2fc +}; + +unsigned long smi_larb2_debug_offset[SMI_LARB2_DEBUG_OFFSET_NUM] = { + 0x0, 0x8, 0x10, 0x24, 0x50, 0x60, 0xa0, 0xa4, 0xa8, 0xac, 0xb0, 0xb4, 0xb8, 0xbc, 0xc0, + 0xc8, + 0xcc, 0x200, 0x204, 0x208, 0x20c, 0x210, 0x214, 0x218, 0x21c, 0x220, 0x224, 0x228, 0x22c, + 0x230, + 0x234, 0x238, 0x23c, 0x240, 0x244, 0x248, 0x24c, 0x280, 0x284, 0x288, 0x28c, 0x290, 0x294, + 0x298, + 0x29c, 0x2a0, 0x2a4, 0x2a8, 0x2ac, 0x2b0, 0x2b4, 0x2b8, 0x2bc, 0x2c0, 0x2c4, 0x2c8, 0x2cc, + 0x2d0, + 0x2d4, 0x2d8, 0x2dc, 0x2e0, 0x2e4, 0x2e8, 0x2ec, 0x2f0, 0x2f4, 0x2f8, 0x2fc +}; + +unsigned long smi_larb3_debug_offset[SMI_LARB3_DEBUG_OFFSET_NUM] = { + 0x0, 0x8, 0x10, 0x24, 0x50, 0x60, 0xa0, 0xa4, 0xa8, 0xac, 0xb0, 0xb4, 0xb8, 0xbc, 0xc0, + 0xc8, + 0xcc, 0x200, 0x204, 0x208, 0x20c, 0x210, 0x214, 0x218, 0x21c, 0x220, 0x224, 0x228, 0x22c, + 0x230, + 0x234, 0x238, 0x23c, 0x240, 0x244, 0x248, 0x24c, 0x280, 0x284, 0x288, 0x28c, 0x290, 0x294, + 0x298, + 0x29c, 0x2a0, 0x2a4, 0x2a8, 0x2ac, 0x2b0, 0x2b4, 0x2b8, 0x2bc, 0x2c0, 0x2c4, 0x2c8, 0x2cc, + 0x2d0, + 0x2d4, 0x2d8, 0x2dc, 0x2e0, 0x2e4, 0x2e8, 0x2ec, 0x2f0, 0x2f4, 0x2f8, 0x2fc +}; + +unsigned long smi_common_debug_offset[SMI_COMMON_DEBUG_OFFSET_NUM] = { + 0x100, 0x104, 0x108, 0x10C, 0x110, 0x114, 0x220, 0x230, 0x234, 0x238, 0x400, 0x404, 0x408, + 0x40C, 0x430, 0x440 +}; + +int smi_larb_debug_offset_num[SMI_LARB_NR] = { + SMI_LARB0_DEBUG_OFFSET_NUM, SMI_LARB1_DEBUG_OFFSET_NUM, SMI_LARB2_DEBUG_OFFSET_NUM, + SMI_LARB3_DEBUG_OFFSET_NUM +}; + +unsigned long *smi_larb_debug_offset[SMI_LARB_NR] = { + smi_larb0_debug_offset, smi_larb1_debug_offset, smi_larb2_debug_offset, + smi_larb3_debug_offset +}; + +#define SMI_PROFILE_SETTING_COMMON_INIT_NUM 7 +#define SMI_VC_SETTING_NUM SMI_LARB_NR +#define SMI_INITSETTING_LARB0_NUM (SMI_LARB0_PORT_NUM + 4) + + +/* vc setting */ +struct SMI_SETTING_VALUE smi_vc_setting[SMI_VC_SETTING_NUM] = { + {0x20, 0}, {0x20, 2}, {0x20, 1}, {0x20, 1} +}; + +/* ISP HRT setting */ +struct SMI_SETTING_VALUE smi_isp_hrt_setting[SMI_LARB_NR] = { + {0x24, 0}, {0x24, 0}, {0x24, 0}, {0x24, 0} +}; + +/* init_setting */ +struct SMI_SETTING_VALUE smi_profile_setting_common_init[SMI_PROFILE_SETTING_COMMON_INIT_NUM] = { + {0, 0x15AE}, {0, 0x1000}, {0, 0x1000}, {0, 0x1000}, + {0x100, 0xb}, + {0x234, ((0x1 << 31) + (0x1d << 26) + (0x1f << 21) + (0x0 << 20) + (0x3 << 15) + + (0x4 << 10) + (0x4 << 5) + 0x5)}, + {0x230, 0xf + (0x8 << 4) + (0x7 << 9)} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb0_init[SMI_INITSETTING_LARB0_NUM] = { + {0x200, 31}, {0x204, 8}, {0x208, 6}, {0x20c, 31}, {0x210, 4}, {0x214, 1}, {0x218, 31}, + {0x21c, 31}, + {0x220, 2}, {0x224, 1}, {0x228, 3}, {0x100, 5}, {0x10c, 5}, {0x118, 5}, {0x11c, 5} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb1_init[SMI_LARB1_PORT_NUM] = { + {0x200, 1}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb2_init[SMI_LARB2_PORT_NUM] = { + {0x200, 1}, {0x204, 4}, {0x208, 2}, {0x20c, 2}, {0x210, 2}, {0x214, 1}, {0x218, 2}, {0x21c, + 2}, + {0x220, 2}, {0x224, 1}, {0x228, 1}, {0x22c, 1}, {0x230, 1}, {0x234, 2}, {0x238, 1}, {0x23c, + 1}, + {0x240, 1}, {0x244, 1}, {0x248, 1}, {0x24c, 1}, {0x250, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb3_init[SMI_LARB3_PORT_NUM] = { + {0x200, 1}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1}, {0x21c, + 1}, + {0x220, 1}, {0x224, 1}, {0x228, 1}, {0x22c, 1}, {0x230, 1} +}; + +struct SMI_SETTING init_setting_config = { + SMI_PROFILE_SETTING_COMMON_INIT_NUM, smi_profile_setting_common_init, + {SMI_INITSETTING_LARB0_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_init, smi_profile_setting_larb1_init, + smi_profile_setting_larb2_init, smi_profile_setting_larb3_init} +}; + +#define SMI_PROFILE_SETTING_COMMON_VR_NUM SMI_LARB_NR +/* vr_setting */ +struct SMI_SETTING_VALUE smi_profile_setting_common_vr[SMI_PROFILE_SETTING_COMMON_VR_NUM] = { + {0, 0x1393}, {0, 0x1000}, {0, 0x1205}, {0, 0x11D4} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb0_vr[SMI_LARB0_PORT_NUM] = { + {0x200, 0xe}, {0x204, 8}, {0x208, 4}, {0x20c, 0xe}, {0x210, 4}, {0x214, 1}, {0x218, 0xe}, + {0x21c, 0xe}, + {0x220, 2}, {0x224, 1}, {0x228, 2} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb1_vr[SMI_LARB1_PORT_NUM] = { + {0x200, 1}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb2_vr[SMI_LARB2_PORT_NUM] = { + {0x200, 1}, {0x204, 4}, {0x208, 2}, {0x20c, 2}, {0x210, 2}, {0x214, 1}, {0x218, 2}, {0x21c, + 2}, + {0x220, 2}, {0x224, 1}, {0x228, 1}, {0x22c, 2}, {0x230, 1}, {0x234, 2}, {0x238, 1}, {0x23c, + 1}, + {0x240, 1}, {0x244, 1}, {0x248, 1}, {0x24c, 1}, {0x250, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb3_vr[SMI_LARB3_PORT_NUM] = { + {0x200, 1}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1}, {0x21c, + 1}, + {0x220, 1}, {0x224, 2}, {0x228, 1}, {0x22c, 1}, {0x230, 4} +}; + +struct SMI_SETTING vr_setting_config = { + SMI_PROFILE_SETTING_COMMON_VR_NUM, smi_profile_setting_common_vr, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_vr, smi_profile_setting_larb1_vr, smi_profile_setting_larb2_vr, + smi_profile_setting_larb3_vr} +}; + +#define SMI_PROFILE_SETTING_COMMON_VP_NUM SMI_LARB_NR +/* vp_setting */ +struct SMI_SETTING_VALUE smi_profile_setting_common_vp[SMI_PROFILE_SETTING_COMMON_VP_NUM] = { + {0, 0x1510}, {0, 0x1169}, {0, 0x1000}, {0, 0x11CE} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb0_vp[SMI_LARB0_PORT_NUM] = { + {0x200, 0xc}, {0x204, 8}, {0x208, 4}, {0x20c, 0xc}, {0x210, 4}, {0x214, 2}, {0x218, 0xc}, + {0x21c, 0xc}, + {0x220, 2}, {0x224, 1}, {0x228, 3} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb1_vp[SMI_LARB1_PORT_NUM] = { + {0x200, 5}, {0x204, 2}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb2_vp[SMI_LARB2_PORT_NUM] = { + {0x200, 1}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1}, {0x21c, + 1}, + {0x220, 1}, {0x224, 1}, {0x228, 1}, {0x22c, 1}, {0x230, 1}, {0x234, 1}, {0x238, 1}, {0x23c, + 1}, + {0x240, 1}, {0x244, 1}, {0x248, 1}, {0x24c, 1}, {0x250, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb3_vp[SMI_LARB3_PORT_NUM] = { + {0x200, 1}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1}, {0x21c, + 1}, + {0x220, 1}, {0x224, 2}, {0x228, 1}, {0x22c, 1}, {0x230, 4} +}; + +struct SMI_SETTING vp_setting_config = { + SMI_PROFILE_SETTING_COMMON_VP_NUM, smi_profile_setting_common_vp, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_vp, smi_profile_setting_larb1_vp, smi_profile_setting_larb2_vp, + smi_profile_setting_larb3_vp} +}; + +/* vr series */ +struct SMI_SETTING icfp_setting_config = { + SMI_PROFILE_SETTING_COMMON_VR_NUM, smi_profile_setting_common_vr, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_vr, smi_profile_setting_larb1_vr, smi_profile_setting_larb2_vr, + smi_profile_setting_larb3_vr} +}; + +struct SMI_SETTING vr_slow_setting_config = { + SMI_PROFILE_SETTING_COMMON_VR_NUM, smi_profile_setting_common_vr, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_vr, smi_profile_setting_larb1_vr, smi_profile_setting_larb2_vr, + smi_profile_setting_larb3_vr} +}; + +struct SMI_SETTING vss_setting_config = { + SMI_PROFILE_SETTING_COMMON_VR_NUM, smi_profile_setting_common_vr, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_vr, smi_profile_setting_larb1_vr, smi_profile_setting_larb2_vr, + smi_profile_setting_larb3_vr} +}; + +struct SMI_SETTING venc_setting_config = { + SMI_PROFILE_SETTING_COMMON_VR_NUM, smi_profile_setting_common_vr, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_vr, smi_profile_setting_larb1_vr, smi_profile_setting_larb2_vr, + smi_profile_setting_larb3_vr} +}; + +/* vp series */ +struct SMI_SETTING vpwfd_setting_config = { + SMI_PROFILE_SETTING_COMMON_VP_NUM, smi_profile_setting_common_vp, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_vp, smi_profile_setting_larb1_vp, smi_profile_setting_larb2_vp, + smi_profile_setting_larb3_vp} +}; + +struct SMI_SETTING swdec_vp_setting_config = { + SMI_PROFILE_SETTING_COMMON_VP_NUM, smi_profile_setting_common_vp, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_vp, smi_profile_setting_larb1_vp, smi_profile_setting_larb2_vp, + smi_profile_setting_larb3_vp} +}; + +/* init seris */ +struct SMI_SETTING mm_gpu_setting_config = { + SMI_PROFILE_SETTING_COMMON_INIT_NUM, smi_profile_setting_common_init, + {SMI_INITSETTING_LARB0_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM, SMI_LARB3_PORT_NUM}, + {smi_profile_setting_larb0_init, smi_profile_setting_larb1_init, + smi_profile_setting_larb2_init, smi_profile_setting_larb3_init} +}; + +struct SMI_SETTING ui_idle_setting_config = { 0, NULL, {0}, {0} }; +struct SMI_SETTING hdmi_setting_config = { 0, NULL, {0}, {0} }; +struct SMI_SETTING hdmi4k_setting_config = { 0, NULL, {0}, {0} }; + +#elif defined(SMI_D2) + +unsigned long smi_common_l1arb_offset[SMI_LARB_NR] = { + REG_OFFSET_SMI_L1ARB0, REG_OFFSET_SMI_L1ARB1, REG_OFFSET_SMI_L1ARB2 +}; + +unsigned int smi_dbg_disp_mask = 1; +unsigned int smi_dbg_vdec_mask = 2; +unsigned int smi_dbg_imgsys_mask = 4; +unsigned int smi_dbg_venc_mask = 4; +unsigned int smi_dbg_mjc_mask = 0; + +unsigned long smi_larb0_debug_offset[SMI_LARB0_DEBUG_OFFSET_NUM] = { + 0x0, 0x8, 0x10, 0x24, 0x50, 0x60, 0xa0, 0xa4, 0xa8, 0xac, 0xb0, 0xb4, 0xb8, 0xbc, 0xc0, + 0xc8, + 0xcc, 0x200, 0x204, 0x208, 0x20c, 0x210, 0x214, 0x218, 0x21c, 0x220, 0x224, 0x228, 0x22c, + 0x230, + 0x234, 0x238, 0x23c, 0x240, 0x244, 0x248, 0x24c, 0x280, 0x284, 0x288, 0x28c, 0x290, 0x294, + 0x298, + 0x29c, 0x2a0, 0x2a4, 0x2a8, 0x2ac, 0x2b0, 0x2b4, 0x2b8, 0x2bc, 0x2c0, 0x2c4, 0x2c8, 0x2cc, + 0x2d0, + 0x2d4, 0x2d8, 0x2dc, 0x2e0, 0x2e4, 0x2e8, 0x2ec, 0x2f0, 0x2f4, 0x2f8, 0x2fc +}; + +unsigned long smi_larb1_debug_offset[SMI_LARB1_DEBUG_OFFSET_NUM] = { + 0x0, 0x8, 0x10, 0x24, 0x50, 0x60, 0xa0, 0xa4, 0xa8, 0xac, 0xb0, 0xb4, 0xb8, 0xbc, 0xc0, + 0xc8, + 0xcc, 0x200, 0x204, 0x208, 0x20c, 0x210, 0x214, 0x218, 0x21c, 0x220, 0x224, 0x228, 0x22c, + 0x230, + 0x234, 0x238, 0x23c, 0x240, 0x244, 0x248, 0x24c, 0x280, 0x284, 0x288, 0x28c, 0x290, 0x294, + 0x298, + 0x29c, 0x2a0, 0x2a4, 0x2a8, 0x2ac, 0x2b0, 0x2b4, 0x2b8, 0x2bc, 0x2c0, 0x2c4, 0x2c8, 0x2cc, + 0x2d0, + 0x2d4, 0x2d8, 0x2dc, 0x2e0, 0x2e4, 0x2e8, 0x2ec, 0x2f0, 0x2f4, 0x2f8, 0x2fc +}; + +unsigned long smi_larb2_debug_offset[SMI_LARB2_DEBUG_OFFSET_NUM] = { + 0x0, 0x8, 0x10, 0x24, 0x50, 0x60, 0xa0, 0xa4, 0xa8, 0xac, 0xb0, 0xb4, 0xb8, 0xbc, 0xc0, + 0xc8, + 0xcc, 0x200, 0x204, 0x208, 0x20c, 0x210, 0x214, 0x218, 0x21c, 0x220, 0x224, 0x228, 0x22c, + 0x230, + 0x234, 0x238, 0x23c, 0x240, 0x244, 0x248, 0x24c, 0x280, 0x284, 0x288, 0x28c, 0x290, 0x294, + 0x298, + 0x29c, 0x2a0, 0x2a4, 0x2a8, 0x2ac, 0x2b0, 0x2b4, 0x2b8, 0x2bc, 0x2c0, 0x2c4, 0x2c8, 0x2cc, + 0x2d0, + 0x2d4, 0x2d8, 0x2dc, 0x2e0, 0x2e4, 0x2e8, 0x2ec, 0x2f0, 0x2f4, 0x2f8, 0x2fc +}; + +unsigned long smi_common_debug_offset[SMI_COMMON_DEBUG_OFFSET_NUM] = { + 0x100, 0x104, 0x108, 0x10C, 0x110, 0x114, 0x220, 0x230, 0x234, 0x238, 0x400, 0x404, 0x408, + 0x40C, 0x430, 0x440 +}; + +int smi_larb_debug_offset_num[SMI_LARB_NR] = { + SMI_LARB0_DEBUG_OFFSET_NUM, SMI_LARB1_DEBUG_OFFSET_NUM, SMI_LARB2_DEBUG_OFFSET_NUM +}; + +unsigned long *smi_larb_debug_offset[SMI_LARB_NR] = { + smi_larb0_debug_offset, smi_larb1_debug_offset, smi_larb2_debug_offset +}; + +#define SMI_VC_SETTING_NUM SMI_LARB_NR +struct SMI_SETTING_VALUE smi_vc_setting[SMI_VC_SETTING_NUM] = { + {0x20, 0}, {0x20, 2}, {0x20, 1} +}; + +#define SMI_PROFILE_SETTING_COMMON_INIT_NUM 6 +/* init_setting */ +struct SMI_SETTING_VALUE smi_profile_setting_common_init[SMI_PROFILE_SETTING_COMMON_INIT_NUM] = { + {0, 0}, {0, 0}, {0, 0}, + {0x100, 0xb}, + {0x234, (0x1 << 31) + (0x1d << 26) + (0x1f << 21) + (0x0 << 20) + (0x3 << 15) + + (0x4 << 10) + (0x4 << 5) + 0x5}, + {0x230, (0x7 + (0x8 << 3) + (0x7 << 8))} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb0_init[SMI_LARB0_PORT_NUM] = { + {0x200, 0x1f}, {0x204, 0x1f}, {0x208, 4}, {0x20c, 6}, {0x210, 4}, {0x214, 1}, {0x218, 1}, + {0x21c, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb1_init[SMI_LARB1_PORT_NUM] = { + {0x200, 1}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb2_init[SMI_LARB2_PORT_NUM] = { + {0x200, 1}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1}, {0x21c, + 1}, + {0x220, 1}, {0x224, 1}, {0x228, 1}, {0x22c, 1}, {0x230, 1} +}; + +struct SMI_SETTING init_setting_config = { + SMI_PROFILE_SETTING_COMMON_INIT_NUM, smi_profile_setting_common_init, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM}, + {smi_profile_setting_larb0_init, smi_profile_setting_larb1_init, + smi_profile_setting_larb2_init} +}; + +#define SMI_PROFILE_SETTING_COMMON_ICFP_NUM SMI_LARB_NR +/* icfp_setting */ +struct SMI_SETTING_VALUE smi_profile_setting_common_icfp[SMI_PROFILE_SETTING_COMMON_ICFP_NUM] = { + {0, 0x11da}, {0, 0x1000}, {0, 0x1318} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb0_icfp[SMI_LARB0_PORT_NUM] = { + {0x200, 6}, {0x204, 6}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1}, {0x21c, + 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb1_icfp[SMI_LARB1_PORT_NUM] = { + {0x200, 1}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb2_icfp[SMI_LARB2_PORT_NUM] = { + {0x200, 8}, {0x204, 6}, {0x208, 1}, {0x20c, 1}, {0x210, 2}, {0x214, 4}, {0x218, 1}, {0x21c, + 1}, + {0x220, 1}, {0x224, 1}, {0x228, 1}, {0x22c, 1}, {0x230, 1} +}; + +struct SMI_SETTING icfp_setting_config = { + SMI_PROFILE_SETTING_COMMON_ICFP_NUM, smi_profile_setting_common_icfp, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM}, + {smi_profile_setting_larb0_icfp, smi_profile_setting_larb1_icfp, + smi_profile_setting_larb2_icfp} +}; + +#define SMI_PROFILE_SETTING_COMMON_VR_NUM SMI_LARB_NR +/* vr_setting */ +struct SMI_SETTING_VALUE smi_profile_setting_common_vr[SMI_PROFILE_SETTING_COMMON_VR_NUM] = { + {0, 0x11ff}, {0, 0x1000}, {0, 0x1361} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb0_vr[SMI_LARB0_PORT_NUM] = { + {0x200, 6}, {0x204, 6}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1}, {0x21c, + 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb1_vr[SMI_LARB1_PORT_NUM] = { + {0x200, 1}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb2_vr[SMI_LARB2_PORT_NUM] = { + {0x200, 8}, {0x204, 6}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 4}, {0x218, 1}, {0x21c, + 1}, + {0x220, 1}, {0x224, 1}, {0x228, 2}, {0x22c, 1}, {0x230, 1} +}; + +struct SMI_SETTING vr_setting_config = { + SMI_PROFILE_SETTING_COMMON_VR_NUM, smi_profile_setting_common_vr, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM}, + {smi_profile_setting_larb0_vr, smi_profile_setting_larb1_vr, smi_profile_setting_larb2_vr} +}; + +#define SMI_PROFILE_SETTING_COMMON_VP_NUM SMI_LARB_NR +/* vp_setting */ +struct SMI_SETTING_VALUE smi_profile_setting_common_vp[SMI_PROFILE_SETTING_COMMON_VP_NUM] = { + {0, 0x11ff}, {0, 0}, {0, 0x1361} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb0_vp[SMI_LARB0_PORT_NUM] = { + {0x200, 8}, {0x204, 8}, {0x208, 1}, {0x20c, 1}, {0x210, 3}, {0x214, 1}, {0x218, 4}, {0x21c, + 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb1_vp[SMI_LARB1_PORT_NUM] = { + {0x200, 0xb}, {0x204, 0xe}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb2_vp[SMI_LARB2_PORT_NUM] = { + {0x200, 8}, {0x204, 6}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 4}, {0x218, 1}, {0x21c, + 1}, + {0x220, 1}, {0x224, 1}, {0x228, 2}, {0x22c, 1}, {0x230, 1} +}; + +struct SMI_SETTING vp_setting_config = { + SMI_PROFILE_SETTING_COMMON_VP_NUM, smi_profile_setting_common_vp, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM}, + {smi_profile_setting_larb0_vp, smi_profile_setting_larb1_vp, smi_profile_setting_larb2_vp} +}; + +#define SMI_PROFILE_SETTING_COMMON_VPWFD_NUM SMI_LARB_NR +/* vfd_setting */ +struct SMI_SETTING_VALUE smi_profile_setting_common_vpwfd[SMI_PROFILE_SETTING_COMMON_VPWFD_NUM] = { + {0, 0x11ff}, {0, 0}, {0, 0x1361} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb0_vpwfd[SMI_LARB0_PORT_NUM] = { + {0x200, 8}, {0x204, 8}, {0x208, 1}, {0x20c, 1}, {0x210, 3}, {0x214, 1}, {0x218, 4}, {0x21c, + 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb1_vpwfd[SMI_LARB1_PORT_NUM] = { + {0x200, 0xb}, {0x204, 0xe}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb2_vpwfd[SMI_LARB2_PORT_NUM] = { + {0x200, 8}, {0x204, 6}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 4}, {0x218, 1}, {0x21c, + 1}, + {0x220, 1}, {0x224, 1}, {0x228, 2}, {0x22c, 1}, {0x230, 1} +}; + +struct SMI_SETTING vpwfd_setting_config = { + SMI_PROFILE_SETTING_COMMON_VPWFD_NUM, smi_profile_setting_common_vpwfd, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM}, + {smi_profile_setting_larb0_vpwfd, smi_profile_setting_larb1_vpwfd, + smi_profile_setting_larb2_vpwfd} +}; + +/* vp series */ +struct SMI_SETTING swdec_vp_setting_config = { + SMI_PROFILE_SETTING_COMMON_VP_NUM, smi_profile_setting_common_vp, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM}, + {smi_profile_setting_larb0_vp, smi_profile_setting_larb1_vp, smi_profile_setting_larb2_vp} +}; + +/* vr series */ +struct SMI_SETTING vr_slow_setting_config = { + SMI_PROFILE_SETTING_COMMON_VR_NUM, smi_profile_setting_common_vr, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM}, + {smi_profile_setting_larb0_vr, smi_profile_setting_larb1_vr, smi_profile_setting_larb2_vr} +}; + +struct SMI_SETTING venc_setting_config = { + SMI_PROFILE_SETTING_COMMON_VR_NUM, smi_profile_setting_common_vr, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM}, + {smi_profile_setting_larb0_vr, smi_profile_setting_larb1_vr, smi_profile_setting_larb2_vr} +}; + +/* init series */ +struct SMI_SETTING mm_gpu_setting_config = { + SMI_PROFILE_SETTING_COMMON_INIT_NUM, smi_profile_setting_common_init, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM}, + {smi_profile_setting_larb0_init, smi_profile_setting_larb1_init, + smi_profile_setting_larb2_init} +}; +struct SMI_SETTING vss_setting_config = { 0, NULL, {0}, {0} }; +struct SMI_SETTING ui_idle_setting_config = { 0, NULL, {0}, {0} }; +struct SMI_SETTING hdmi_setting_config = { 0, NULL, {0}, {0} }; +struct SMI_SETTING hdmi4k_setting_config = { 0, NULL, {0}, {0} }; + +#elif defined(SMI_R) +unsigned int smi_dbg_disp_mask = 1; +unsigned int smi_dbg_vdec_mask = 0; +unsigned int smi_dbg_imgsys_mask = 2; +unsigned int smi_dbg_venc_mask = 2; +unsigned int smi_dbg_mjc_mask = 0; + +unsigned long smi_common_l1arb_offset[SMI_LARB_NR] = { + REG_OFFSET_SMI_L1ARB0, REG_OFFSET_SMI_L1ARB1 +}; + +unsigned long smi_larb0_debug_offset[SMI_LARB0_DEBUG_OFFSET_NUM] = { + 0x0, 0x8, 0x10, 0x24, 0x50, 0x60, 0xa0, 0xa4, 0xa8, 0xac, 0xb0, 0xb4, 0xb8, 0xbc, 0xc0, + 0xc8, + 0xcc, 0x200, 0x204, 0x208, 0x20c, 0x210, 0x214, 0x218, 0x21c, 0x220, 0x224, 0x228, 0x22c, + 0x230, + 0x234, 0x238, 0x23c, 0x240, 0x244, 0x248, 0x24c, 0x280, 0x284, 0x288, 0x28c, 0x290, 0x294, + 0x298, + 0x29c, 0x2a0, 0x2a4, 0x2a8, 0x2ac, 0x2b0, 0x2b4, 0x2b8, 0x2bc, 0x2c0, 0x2c4, 0x2c8, 0x2cc, + 0x2d0, + 0x2d4, 0x2d8, 0x2dc, 0x2e0, 0x2e4, 0x2e8, 0x2ec, 0x2f0, 0x2f4, 0x2f8, 0x2fc +}; + +unsigned long smi_larb1_debug_offset[SMI_LARB1_DEBUG_OFFSET_NUM] = { + 0x0, 0x8, 0x10, 0x24, 0x50, 0x60, 0xa0, 0xa4, 0xa8, 0xac, 0xb0, 0xb4, 0xb8, 0xbc, 0xc0, + 0xc8, + 0xcc, 0x200, 0x204, 0x208, 0x20c, 0x210, 0x214, 0x218, 0x21c, 0x220, 0x224, 0x228, 0x22c, + 0x230, + 0x234, 0x238, 0x23c, 0x240, 0x244, 0x248, 0x24c, 0x280, 0x284, 0x288, 0x28c, 0x290, 0x294, + 0x298, + 0x29c, 0x2a0, 0x2a4, 0x2a8, 0x2ac, 0x2b0, 0x2b4, 0x2b8, 0x2bc, 0x2c0, 0x2c4, 0x2c8, 0x2cc, + 0x2d0, + 0x2d4, 0x2d8, 0x2dc, 0x2e0, 0x2e4, 0x2e8, 0x2ec, 0x2f0, 0x2f4, 0x2f8, 0x2fc +}; + +unsigned long smi_common_debug_offset[SMI_COMMON_DEBUG_OFFSET_NUM] = { + 0x100, 0x104, 0x108, 0x10C, 0x110, 0x114, 0x220, 0x230, 0x234, 0x238, 0x400, 0x404, 0x408, + 0x40C, 0x430, 0x440 +}; + +int smi_larb_debug_offset_num[SMI_LARB_NR] = { + SMI_LARB0_DEBUG_OFFSET_NUM, SMI_LARB1_DEBUG_OFFSET_NUM +}; + +unsigned long *smi_larb_debug_offset[SMI_LARB_NR] = { + smi_larb0_debug_offset, smi_larb1_debug_offset +}; + +#define SMI_VC_SETTING_NUM SMI_LARB_NR +struct SMI_SETTING_VALUE smi_vc_setting[SMI_VC_SETTING_NUM] = { + {0x20, 0}, {0x20, 2} +}; + +#define SMI_PROFILE_SETTING_COMMON_INIT_NUM 5 +/* init_setting */ +struct SMI_SETTING_VALUE smi_profile_setting_common_init[SMI_PROFILE_SETTING_COMMON_INIT_NUM] = { + {0, 0x14cb}, {0, 0x1001}, + {0x100, 0xb}, + {0x234, + (0x1 << 31) + (0x1d << 26) + (0x1f << 21) + (0x0 << 20) + (0x3 << 15) + + (0x4 << 10) + (0x4 << 5) + 0x5}, + {0x230, (0x3 + (0x8 << 2) + (0x7 << 7))} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb0_init[SMI_LARB0_PORT_NUM] = { + {0x200, 0x1c}, {0x204, 4}, {0x208, 6}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb1_init[SMI_LARB1_PORT_NUM] = { + {0x200, 1}, {0x204, 1}, {0x208, 1}, {0x20c, 1}, {0x210, 1}, {0x214, 1}, {0x218, 1}, {0x21c, + 1}, + {0x220, 1}, {0x224, 1}, {0x228, 1} +}; + +struct SMI_SETTING init_setting_config = { + SMI_PROFILE_SETTING_COMMON_INIT_NUM, smi_profile_setting_common_init, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM}, + {smi_profile_setting_larb0_init, smi_profile_setting_larb1_init} +}; + +#define SMI_PROFILE_SETTING_COMMON_VR_NUM SMI_LARB_NR +/* vr_setting */ +struct SMI_SETTING_VALUE smi_profile_setting_common_vr[SMI_PROFILE_SETTING_COMMON_VR_NUM] = { + {0, 0x122b}, {0, 0x142c} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb0_vr[SMI_LARB0_PORT_NUM] = { + {0x200, 0xa}, {0x204, 1}, {0x208, 1}, {0x20c, 4}, {0x210, 2}, {0x214, 2}, {0x218, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb1_vr[SMI_LARB1_PORT_NUM] = { + {0x200, 8}, {0x204, 6}, {0x208, 1}, {0x20c, 1}, {0x210, 4}, {0x214, 1}, {0x218, 1}, {0x21c, + 1}, + {0x220, 3}, {0x224, 2}, {0x228, 2} +}; + +struct SMI_SETTING vr_setting_config = { + SMI_PROFILE_SETTING_COMMON_VR_NUM, smi_profile_setting_common_vr, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM}, + {smi_profile_setting_larb0_vr, smi_profile_setting_larb1_vr} +}; + +#define SMI_PROFILE_SETTING_COMMON_VP_NUM SMI_LARB_NR +/* vp_setting */ +struct SMI_SETTING_VALUE smi_profile_setting_common_vp[SMI_PROFILE_SETTING_COMMON_VP_NUM] = { + {0, 0x11ff}, {0, 0} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb0_vp[SMI_LARB0_PORT_NUM] = { + {0x200, 8}, {0x204, 1}, {0x208, 1}, {0x20c, 3}, {0x210, 1}, {0x214, 4}, {0x218, 1} +}; + +struct SMI_SETTING_VALUE smi_profile_setting_larb1_vp[SMI_LARB1_PORT_NUM] = { + {0x200, 8}, {0x204, 6}, {0x208, 1}, {0x20c, 1}, {0x210, 4}, {0x214, 1}, {0x218, 1}, {0x21c, + 1}, + {0x220, 3}, {0x224, 2}, {0x228, 2} +}; + +struct SMI_SETTING vp_setting_config = { + SMI_PROFILE_SETTING_COMMON_VP_NUM, smi_profile_setting_common_vp, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM}, + {smi_profile_setting_larb0_vp, smi_profile_setting_larb1_vp} +}; + +/* vp series */ +struct SMI_SETTING swdec_vp_setting_config = { + SMI_PROFILE_SETTING_COMMON_VP_NUM, smi_profile_setting_common_vp, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM}, + {smi_profile_setting_larb0_vp, smi_profile_setting_larb1_vp} +}; + +/* vr series */ +struct SMI_SETTING vr_slow_setting_config = { + SMI_PROFILE_SETTING_COMMON_VR_NUM, smi_profile_setting_common_vr, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM}, + {smi_profile_setting_larb0_vr, smi_profile_setting_larb1_vr} +}; + +struct SMI_SETTING icfp_setting_config = { + SMI_PROFILE_SETTING_COMMON_VR_NUM, smi_profile_setting_common_vr, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM}, + {smi_profile_setting_larb0_vr, smi_profile_setting_larb1_vr} +}; + +struct SMI_SETTING venc_setting_config = { + SMI_PROFILE_SETTING_COMMON_VR_NUM, smi_profile_setting_common_vr, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM}, + {smi_profile_setting_larb0_vr, smi_profile_setting_larb1_vr} +}; + +/* init series */ +struct SMI_SETTING mm_gpu_setting_config = { + SMI_PROFILE_SETTING_COMMON_INIT_NUM, smi_profile_setting_common_init, + {SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM}, + {smi_profile_setting_larb0_init, smi_profile_setting_larb1_init} +}; + +struct SMI_SETTING vss_setting_config = { 0, NULL, {0}, {0} }; +struct SMI_SETTING vpwfd_setting_config = { 0, NULL, {0}, {0} }; +struct SMI_SETTING ui_idle_setting_config = { 0, NULL, {0}, {0} }; +struct SMI_SETTING hdmi_setting_config = { 0, NULL, {0}, {0} }; +struct SMI_SETTING hdmi4k_setting_config = { 0, NULL, {0}, {0} }; +#endif + +struct SMI_PROFILE_CONFIG smi_profile_config[SMI_PROFILE_CONFIG_NUM] = { + {SMI_BWC_SCEN_NORMAL, &init_setting_config}, + {SMI_BWC_SCEN_VR, &vr_setting_config}, + {SMI_BWC_SCEN_SWDEC_VP, &swdec_vp_setting_config}, + {SMI_BWC_SCEN_VP, &vp_setting_config}, + {SMI_BWC_SCEN_VR_SLOW, &vr_slow_setting_config}, + {SMI_BWC_SCEN_MM_GPU, &mm_gpu_setting_config}, + {SMI_BWC_SCEN_WFD, &vpwfd_setting_config}, + {SMI_BWC_SCEN_VENC, &venc_setting_config}, + {SMI_BWC_SCEN_ICFP, &icfp_setting_config}, + {SMI_BWC_SCEN_UI_IDLE, &ui_idle_setting_config}, + {SMI_BWC_SCEN_VSS, &vss_setting_config}, + {SMI_BWC_SCEN_FORCE_MMDVFS, &init_setting_config}, + {SMI_BWC_SCEN_HDMI, &hdmi_setting_config}, + {SMI_BWC_SCEN_HDMI4K, &hdmi4k_setting_config} +}; + +void smi_set_nonconstant_variable(void) +{ +#if defined(SMI_D2) + int i = 0; + + for (i = 0; i < SMI_LARB_NR; ++i) { + smi_profile_setting_common_init[i].offset = smi_common_l1arb_offset[i]; + smi_profile_setting_common_init[i].value = default_val_smi_l1arb[i]; + smi_profile_setting_common_icfp[i].offset = smi_common_l1arb_offset[i]; + smi_profile_setting_common_vp[i].offset = smi_common_l1arb_offset[i]; + smi_profile_setting_common_vr[i].offset = smi_common_l1arb_offset[i]; + smi_profile_setting_common_vpwfd[i].offset = smi_common_l1arb_offset[i]; + } + + smi_profile_setting_common_vp[1].value = default_val_smi_l1arb[1]; + smi_profile_setting_common_vpwfd[1].value = default_val_smi_l1arb[1]; + +#elif defined(SMI_D1) + int i = 0; + + M4U_WriteReg32(LARB2_BASE, 0x24, (M4U_ReadReg32(LARB2_BASE, 0x24) & 0xf7ffffff)); + for (i = 0; i < SMI_LARB_NR; ++i) { + smi_profile_setting_common_vr[i].offset = smi_common_l1arb_offset[i]; + smi_profile_setting_common_vp[i].offset = smi_common_l1arb_offset[i]; + smi_profile_setting_common_init[i].offset = smi_common_l1arb_offset[i]; + } + smi_profile_setting_common_init[0].value = default_val_smi_l1arb[0]; + +#elif defined(SMI_D3) + int i = 0; + + M4U_WriteReg32(LARB2_BASE, 0x24, (M4U_ReadReg32(LARB2_BASE, 0x24) & 0xf7ffffff)); + for (i = 0; i < SMI_LARB_NR; ++i) { + smi_profile_setting_common_vr[i].offset = smi_common_l1arb_offset[i]; + smi_profile_setting_common_vp[i].offset = smi_common_l1arb_offset[i]; + smi_profile_setting_common_icfp[i].offset = smi_common_l1arb_offset[i]; + smi_profile_setting_common_vpwfd[i].offset = smi_common_l1arb_offset[i]; + smi_profile_setting_common_init[i].offset = smi_common_l1arb_offset[i]; + } + smi_profile_setting_common_init[0].value = default_val_smi_l1arb[0]; + +#elif defined(SMI_J) + unsigned int smi_val = 0; + int i = 0; + + smi_val = (M4U_ReadReg32(LARB0_BASE, 0x24) & 0xf7ffffff); + for (i = 0; i < SMI_LARB_NR; ++i) + smi_isp_hrt_setting[i].value = smi_val; + + for (i = 0; i < SMI_LARB_NR; ++i) { + smi_profile_setting_common_vr[i].offset = smi_common_l1arb_offset[i]; + smi_profile_setting_common_vp[i].offset = smi_common_l1arb_offset[i]; + smi_profile_setting_common_init[i].offset = smi_common_l1arb_offset[i]; + } +#elif defined(SMI_R) + int i = 0; + + for (i = 0; i < SMI_LARB_NR; ++i) { + smi_profile_setting_common_vr[i].offset = smi_common_l1arb_offset[i]; + smi_profile_setting_common_vp[i].offset = smi_common_l1arb_offset[i]; + smi_profile_setting_common_init[i].offset = smi_common_l1arb_offset[i]; + } + smi_profile_setting_common_vp[1].offset = smi_common_l1arb_offset[1]; +#endif +} diff --git a/drivers/misc/mediatek/smi/smi_configuration.h b/drivers/misc/mediatek/smi/smi_configuration.h new file mode 100644 index 000000000..92579476b --- /dev/null +++ b/drivers/misc/mediatek/smi/smi_configuration.h @@ -0,0 +1,53 @@ +#ifndef _SMI_CONFIGURATION_H_ +#define _SMI_CONFIGURATION_H_ + +#include "smi_reg.h" +#include <mach/mt_smi.h> +/* ***********debug parameters*********** */ + +#define SMI_COMMON_DEBUG_OFFSET_NUM 16 +#define SMI_LARB_DEFAULT_DEBUG_OFFSET_NUM 69 + + +#if defined(SMI_D1) || defined(SMI_D3) || defined(SMI_J) +#define SMI_LARB0_DEBUG_OFFSET_NUM SMI_LARB_DEFAULT_DEBUG_OFFSET_NUM +#define SMI_LARB1_DEBUG_OFFSET_NUM SMI_LARB_DEFAULT_DEBUG_OFFSET_NUM +#define SMI_LARB2_DEBUG_OFFSET_NUM SMI_LARB_DEFAULT_DEBUG_OFFSET_NUM +#define SMI_LARB3_DEBUG_OFFSET_NUM SMI_LARB_DEFAULT_DEBUG_OFFSET_NUM + +#elif defined(SMI_D2) +#define SMI_LARB0_DEBUG_OFFSET_NUM SMI_LARB_DEFAULT_DEBUG_OFFSET_NUM +#define SMI_LARB1_DEBUG_OFFSET_NUM SMI_LARB_DEFAULT_DEBUG_OFFSET_NUM +#define SMI_LARB2_DEBUG_OFFSET_NUM SMI_LARB_DEFAULT_DEBUG_OFFSET_NUM + +#elif defined(SMI_R) +#define SMI_LARB0_DEBUG_OFFSET_NUM SMI_LARB_DEFAULT_DEBUG_OFFSET_NUM +#define SMI_LARB1_DEBUG_OFFSET_NUM SMI_LARB_DEFAULT_DEBUG_OFFSET_NUM + +#endif + + +struct SMI_SETTING_VALUE { + unsigned int offset; + int value; +}; + +struct SMI_SETTING { + unsigned int smi_common_reg_num; + struct SMI_SETTING_VALUE *smi_common_setting_vals; + unsigned int smi_larb_reg_num[SMI_LARB_NR]; + struct SMI_SETTING_VALUE *smi_larb_setting_vals[SMI_LARB_NR]; +}; + +struct SMI_PROFILE_CONFIG { + int smi_profile; + struct SMI_SETTING *setting; +}; + +#define SMI_PROFILE_CONFIG_NUM SMI_BWC_SCEN_CNT + +extern unsigned long smi_common_debug_offset[SMI_COMMON_DEBUG_OFFSET_NUM]; +extern int smi_larb_debug_offset_num[SMI_LARB_NR]; +extern unsigned long *smi_larb_debug_offset[SMI_LARB_NR]; + +#endif diff --git a/drivers/misc/mediatek/smi/smi_debug.c b/drivers/misc/mediatek/smi/smi_debug.c new file mode 100644 index 000000000..6931b758f --- /dev/null +++ b/drivers/misc/mediatek/smi/smi_debug.c @@ -0,0 +1,348 @@ +#include <linux/uaccess.h> +#include <linux/module.h> +#include <linux/fs.h> +#include <linux/platform_device.h> +#include <linux/cdev.h> +#include <linux/interrupt.h> +#include <asm/io.h> +#include <linux/sched.h> +#include <linux/wait.h> +#include <linux/spinlock.h> +#include <linux/delay.h> +#include <linux/mm.h> +#include <linux/vmalloc.h> +#include <linux/dma-mapping.h> +#include <linux/slab.h> +#include <linux/aee.h> +#include <linux/timer.h> +/* #include <asm/system.h> */ +#include <asm-generic/irq_regs.h> +/* #include <asm/mach/map.h> */ +#include <mach/sync_write.h> +/*#include <mach/irqs.h>*/ +#include <asm/cacheflush.h> +#include <linux/string.h> +#include <linux/time.h> +#include <linux/fb.h> +#include <linux/debugfs.h> +#include <m4u.h> +#include <mach/mt_smi.h> + +#include "smi_common.h" +#include "smi_reg.h" +#include "smi_debug.h" +#include "smi_configuration.h" + +#define SMI_LOG_TAG "smi" + +#if !defined(CONFIG_MTK_LEGACY) +#define SMI_INTERNAL_CCF_SUPPORT +#endif + +#if !defined(SMI_INTERNAL_CCF_SUPPORT) +#include <mach/mt_clkmgr.h> +#endif + + +/* Debug Function */ +static void smi_dump_format(unsigned long base, unsigned int from, unsigned int to); +static void smi_dumpper(int output_gce_buffer, unsigned long *offset, unsigned long base, int reg_number) +{ + int num_of_set = 3; + int remain_runtimes = 0; + int runtimes = 0; + int i = 0; + + remain_runtimes = reg_number % num_of_set; + runtimes = reg_number / num_of_set; + runtimes = runtimes * 3; + + do { + SMIMSG3(output_gce_buffer, "[0x%lx,0x%lx,0x%lx]=[0x%x,0x%x,0x%x]\n", + offset[i], offset[i + 1], offset[i + 2], + M4U_ReadReg32(base, offset[i]), M4U_ReadReg32(base, offset[i + 1]), + M4U_ReadReg32(base, offset[i + 2])); + i += 3; + } while (i < runtimes); + + switch (remain_runtimes) { + case 2: + SMIMSG3(output_gce_buffer, "[0x%lx,0x%lx]=[0x%x,0x%x]\n", + offset[i], offset[i + 1], + M4U_ReadReg32(base, offset[i]), M4U_ReadReg32(base, offset[i + 1])); + break; + case 1: + SMIMSG3(output_gce_buffer, "[0x%lx]=[0x%x]\n", + offset[i], M4U_ReadReg32(base, offset[i])); + break; + default: + break; + } +} + +void smi_dumpCommonDebugMsg(int output_gce_buffer) +{ + unsigned long u4Base; + + /* No verify API in CCF, assume clk is always on */ + int smiCommonClkEnabled = 1; + +#if !defined(SMI_INTERNAL_CCF_SUPPORT) + smiCommonClkEnabled = clock_is_on(MT_CG_DISP0_SMI_COMMON); +#endif /* !defined (SMI_INTERNAL_CCF_SUPPORT) */ + + /* SMI COMMON dump */ + if ((!smiCommonClkEnabled)) { + SMIMSG3(output_gce_buffer, "===SMI common clock is disabled===\n"); + return; + } + + SMIMSG3(output_gce_buffer, "===SMI common reg dump, CLK: %d===\n", smiCommonClkEnabled); + + u4Base = SMI_COMMON_EXT_BASE; + smi_dumpper(output_gce_buffer, smi_common_debug_offset, u4Base, + SMI_COMMON_DEBUG_OFFSET_NUM); +} + +void smi_dumpLarbDebugMsg(unsigned int u4Index, int output_gce_buffer) +{ + unsigned long u4Base = 0; + /* No verify API in CCF, assume clk is always on */ + int larbClkEnabled = 1; + + u4Base = get_larb_base_addr(u4Index); +#if !defined(SMI_INTERNAL_CCF_SUPPORT) + larbClkEnabled = smi_larb_clock_is_on(u4Index); +#endif + + if (u4Base == SMI_ERROR_ADDR) { + SMIMSG3(output_gce_buffer, "Doesn't support reg dump for Larb%d\n", u4Index); + return; + } else if ((larbClkEnabled != 0)) { + SMIMSG3(output_gce_buffer, "===SMI LARB%d reg dump, CLK: %d===\n", u4Index, + larbClkEnabled); + + smi_dumpper(output_gce_buffer, smi_larb_debug_offset[u4Index], u4Base, + smi_larb_debug_offset_num[u4Index]); + + } else { + SMIMSG3(output_gce_buffer, "===SMI LARB%d clock is disabled===\n", u4Index); + } + +} + +void smi_dumpLarb(unsigned int index) +{ + unsigned long u4Base; + + u4Base = get_larb_base_addr(index); + + if (u4Base == SMI_ERROR_ADDR) { + SMIMSG2("Doesn't support reg dump for Larb%d\n", index); + } else { + SMIMSG2("===SMI LARB%d reg dump base 0x%lx===\n", index, u4Base); + smi_dump_format(u4Base, 0, 0x434); + smi_dump_format(u4Base, 0xF00, 0xF0C); + } +} + +void smi_dumpCommon(void) +{ + SMIMSG2("===SMI COMMON reg dump base 0x%lx===\n", SMI_COMMON_EXT_BASE); + + smi_dump_format(SMI_COMMON_EXT_BASE, 0x1A0, 0x444); +} + +static void smi_dump_format(unsigned long base, unsigned int from, unsigned int to) +{ + int i, j, left; + unsigned int value[8]; + + for (i = from; i <= to; i += 32) { + for (j = 0; j < 8; j++) + value[j] = M4U_ReadReg32(base, i + j * 4); + + SMIMSG2("%8x %x %x %x %x %x %x %x %x\n", i, value[0], value[1], + value[2], value[3], value[4], value[5], value[6], value[7]); + } + + left = ((from - to) / 4 + 1) % 8; + + if (left) { + memset(value, 0, 8 * sizeof(unsigned int)); + + for (j = 0; j < left; j++) + value[j] = M4U_ReadReg32(base, i - 32 + j * 4); + + SMIMSG2("%8x %x %x %x %x %x %x %x %x\n", i - 32 + j * 4, value[0], + value[1], value[2], value[3], value[4], value[5], value[6], value[7]); + } +} + +void smi_dumpDebugMsg(void) +{ + unsigned int u4Index; + + /* SMI COMMON dump, 0 stands for not pass log to CMDQ error dumping messages */ + smi_dumpCommonDebugMsg(0); + + /* dump all SMI LARB */ + /* SMI Larb dump, 0 stands for not pass log to CMDQ error dumping messages */ + for (u4Index = 0; u4Index < SMI_LARB_NR; u4Index++) + smi_dumpLarbDebugMsg(u4Index, 0); +} + +int smi_debug_bus_hanging_detect(unsigned int larbs, int show_dump) +{ + return smi_debug_bus_hanging_detect_ext(larbs, show_dump, 0); +} + +static int get_status_code(int smi_larb_clk_status, int smi_larb_busy_count, + int smi_common_busy_count) +{ + int status_code = 0; + + if (smi_larb_clk_status != 0) { + if (smi_larb_busy_count == 5) { /* The larb is always busy */ + if (smi_common_busy_count == 5) /* smi common is always busy */ + status_code = 1; + else if (smi_common_busy_count == 0) /* smi common is always idle */ + status_code = 2; + else + status_code = 5; /* smi common is sometimes busy and idle */ + } else if (smi_larb_busy_count == 0) { /* The larb is always idle */ + if (smi_common_busy_count == 5) /* smi common is always busy */ + status_code = 3; + else if (smi_common_busy_count == 0) /* smi common is always idle */ + status_code = 4; + else + status_code = 6; /* smi common is sometimes busy and idle */ + } else { /* sometime the larb is busy */ + if (smi_common_busy_count == 5) /* smi common is always busy */ + status_code = 7; + else if (smi_common_busy_count == 0) /* smi common is always idle */ + status_code = 8; + else + status_code = 9; /* smi common is sometimes busy and idle */ + } + } else { + status_code = 10; + } + return status_code; +} + +int smi_debug_bus_hanging_detect_ext(unsigned int larbs, int show_dump, int output_gce_buffer) +{ +/* output_gce_buffer = 1, write log into kernel log and CMDQ buffer. */ +/* dual_buffer = 0, write log into kernel log only */ + int i = 0; + int dump_time = 0; + int is_smi_issue = 0; + int status_code = 0; + /* Keep the dump result */ + unsigned char smi_common_busy_count = 0; + unsigned int u4Index = 0; + unsigned long u4Base = 0; + + volatile unsigned int reg_temp = 0; + unsigned char smi_larb_busy_count[SMI_LARB_NR] = { 0 }; + unsigned char smi_larb_mmu_status[SMI_LARB_NR] = { 0 }; + int smi_larb_clk_status[SMI_LARB_NR] = { 0 }; + /* dump resister and save resgister status */ + for (dump_time = 0; dump_time < 5; dump_time++) { + reg_temp = M4U_ReadReg32(SMI_COMMON_EXT_BASE, 0x440); + if ((reg_temp & (1 << 0)) == 0) { + /* smi common is busy */ + smi_common_busy_count++; + } + /* Dump smi common regs */ + if (show_dump != 0) + smi_dumpCommonDebugMsg(output_gce_buffer); + + for (u4Index = 0; u4Index < SMI_LARB_NR; u4Index++) { + u4Base = get_larb_base_addr(u4Index); + + smi_larb_clk_status[u4Index] = smi_larb_clock_is_on(u4Index); + /* check larb clk is enable */ + if (smi_larb_clk_status[u4Index] != 0) { + if (u4Base != SMI_ERROR_ADDR) { + reg_temp = M4U_ReadReg32(u4Base, 0x0); + if (reg_temp != 0) { + /* Larb is busy */ + smi_larb_busy_count[u4Index]++; + } + smi_larb_mmu_status[u4Index] = M4U_ReadReg32(u4Base, 0xa0); + if (show_dump != 0) + smi_dumpLarbDebugMsg(u4Index, output_gce_buffer); + } + } + + } + + /* Show the checked result */ + for (i = 0; i < SMI_LARB_NR; i++) { /* Check each larb */ + if (SMI_DGB_LARB_SELECT(larbs, i)) { + /* larb i has been selected */ + /* Get status code */ + status_code = get_status_code(smi_larb_clk_status[i], smi_larb_busy_count[i], + smi_common_busy_count); + + /* Send the debug message according to the final result */ + switch (status_code) { + case 1: + case 3: + case 5: + case 7: + case 8: + SMIMSG3(output_gce_buffer, + "Larb%d Busy=%d/5, SMI Common Busy=%d/5, status=%d ==> Check engine's state first\n", + i, smi_larb_busy_count[i], smi_common_busy_count, + status_code); + SMIMSG3(output_gce_buffer, + "If the engine is waiting for Larb%ds' response, it needs SMI HW's check\n", + i); + break; + case 2: + if (smi_larb_mmu_status[i] == 0) { + SMIMSG3(output_gce_buffer, + "Larb%d Busy=%d/5, SMI Common Busy=%d/5, status=%d ==> Check engine state first\n", + i, smi_larb_busy_count[i], + smi_common_busy_count, status_code); + SMIMSG3(output_gce_buffer, + "If the engine is waiting for Larb%ds' response, it needs SMI HW's check\n", + i); + } else { + SMIMSG3(output_gce_buffer, + "Larb%d Busy=%d/5, SMI Common Busy=%d/5, status=%d ==> MMU port config error\n", + i, smi_larb_busy_count[i], + smi_common_busy_count, status_code); + is_smi_issue = 1; + } + break; + case 4: + case 6: + case 9: + SMIMSG3(output_gce_buffer, + "Larb%d Busy=%d/5, SMI Common Busy=%d/5, status=%d ==> not SMI issue\n", + i, smi_larb_busy_count[i], smi_common_busy_count, + status_code); + break; + case 10: + SMIMSG3(output_gce_buffer, + "Larb%d clk is disbable, status=%d ==> no need to check\n", + i, status_code); + break; + default: + SMIMSG3(output_gce_buffer, + "Larb%d Busy=%d/5, SMI Common Busy=%d/5, status=%d ==> status unknown\n", + i, smi_larb_busy_count[i], smi_common_busy_count, + status_code); + break; + } + } + + } + + } + return is_smi_issue; +} diff --git a/drivers/misc/mediatek/smi/smi_debug.h b/drivers/misc/mediatek/smi/smi_debug.h new file mode 100644 index 000000000..02fd0293b --- /dev/null +++ b/drivers/misc/mediatek/smi/smi_debug.h @@ -0,0 +1,34 @@ +#ifndef _SMI_DEBUG_H_ +#define _SMI_DEBUG_H_ + + +#define SMI_DBG_DISPSYS (smi_dbg_disp_mask) +#define SMI_DBG_VDEC (smi_dbg_vdec_mask) +#define SMI_DBG_IMGSYS (smi_dbg_imgsys_mask) +#define SMI_DBG_VENC (smi_dbg_venc_mask) +#define SMI_DBG_MJC (smi_dbg_mjc_mask) + +#define SMI_DGB_LARB_SELECT(smi_dbg_larb, n) ((smi_dbg_larb) & (1<<n)) + +#ifndef CONFIG_MTK_SMI_EXT +#define smi_debug_bus_hanging_detect(larbs, show_dump) {} +#define smi_debug_bus_hanging_detect_ext(larbs, show_dump, output_gce_buffer) {} +#else +int smi_debug_bus_hanging_detect(unsigned int larbs, int show_dump); + /* output_gce_buffer = 1, pass log to CMDQ error dumping messages */ +int smi_debug_bus_hanging_detect_ext(unsigned int larbs, int show_dump, int output_gce_buffer); + +#endif +void smi_dumpCommonDebugMsg(int output_gce_buffer); +void smi_dumpLarbDebugMsg(unsigned int u4Index, int output_gce_buffer); +void smi_dumpDebugMsg(void); + +extern int smi_larb_clock_is_on(unsigned int larb_index); + +extern unsigned int smi_dbg_disp_mask; +extern unsigned int smi_dbg_vdec_mask; +extern unsigned int smi_dbg_imgsys_mask; +extern unsigned int smi_dbg_venc_mask; +extern unsigned int smi_dbg_mjc_mask; + +#endif /* _SMI_DEBUG_H__ */ diff --git a/drivers/misc/mediatek/smi/smi_info_util.c b/drivers/misc/mediatek/smi/smi_info_util.c new file mode 100644 index 000000000..6612dd5cf --- /dev/null +++ b/drivers/misc/mediatek/smi/smi_info_util.c @@ -0,0 +1,86 @@ +#include <asm/io.h> +#include <linux/ioctl.h> +#include <linux/fs.h> +#include <linux/uaccess.h> +#include "smi_info_util.h" +#include "smi_common.h" + +int smi_set_mm_info_ioctl_wrapper(struct file *pFile, unsigned int cmd, unsigned long param) +{ + int ret = 0; + MTK_SMI_BWC_INFO_SET cfg; + + ret = copy_from_user(&cfg, (void *)param, sizeof(MTK_SMI_BWC_INFO_SET)); + if (ret) { + SMIMSG(" MTK_IOC_SMI_BWC_INFO_SET, copy_to_user failed: %d\n", ret); + return -EFAULT; + } + /* Set the address to the value assigned by user space program */ + smi_bwc_mm_info_set(cfg.property, cfg.value1, cfg.value2); + /* SMIMSG("Handle MTK_IOC_SMI_BWC_INFO_SET request... finish"); */ + return ret; +} + + +int smi_get_mm_info_ioctl_wrapper(struct file *pFile, unsigned int cmd, unsigned long param) +{ + int ret = 0; + + ret = copy_to_user((void *)param, (void *)&g_smi_bwc_mm_info, sizeof(MTK_SMI_BWC_MM_INFO)); + + if (ret) { + SMIMSG(" MTK_IOC_SMI_BWC_INFO_GET, copy_to_user failed: %d\n", ret); + return -EFAULT; + } + /* SMIMSG("Handle MTK_IOC_SMI_BWC_INFO_GET request... finish"); */ + return ret; +} + + +void smi_bwc_mm_info_set(int property_id, long val1, long val2) +{ + + switch (property_id) { + case SMI_BWC_INFO_CON_PROFILE: + g_smi_bwc_mm_info.concurrent_profile = (int)val1; + break; + case SMI_BWC_INFO_SENSOR_SIZE: + g_smi_bwc_mm_info.sensor_size[0] = val1; + g_smi_bwc_mm_info.sensor_size[1] = val2; + break; + case SMI_BWC_INFO_VIDEO_RECORD_SIZE: + g_smi_bwc_mm_info.video_record_size[0] = val1; + g_smi_bwc_mm_info.video_record_size[1] = val2; + break; + case SMI_BWC_INFO_DISP_SIZE: + g_smi_bwc_mm_info.display_size[0] = val1; + g_smi_bwc_mm_info.display_size[1] = val2; + break; + case SMI_BWC_INFO_TV_OUT_SIZE: + g_smi_bwc_mm_info.tv_out_size[0] = val1; + g_smi_bwc_mm_info.tv_out_size[1] = val2; + break; + case SMI_BWC_INFO_FPS: + g_smi_bwc_mm_info.fps = (int)val1; + break; + case SMI_BWC_INFO_VIDEO_ENCODE_CODEC: + g_smi_bwc_mm_info.video_encode_codec = (int)val1; +#if defined(SMI_J) + /* AVC @ 60 needs HPM */ + /* + if (g_smi_bwc_mm_info.video_encode_codec == 2) { + int is_smvr = 0; + spin_lock(&g_SMIInfo.SMI_lock); + is_smvr = g_SMIInfo.pu4ConcurrencyTable[SMI_BWC_SCEN_VR_SLOW] ? 1 : 0; + spin_unlock(&g_SMIInfo.SMI_lock); + if (is_smvr) + mmdvfs_notify_scenario_enter(SMI_BWC_SCEN_VR_SLOW); + } + */ +#endif + break; + case SMI_BWC_INFO_VIDEO_DECODE_CODEC: + g_smi_bwc_mm_info.video_decode_codec = (int)val1; + break; + } +} diff --git a/drivers/misc/mediatek/smi/smi_info_util.h b/drivers/misc/mediatek/smi/smi_info_util.h new file mode 100644 index 000000000..30eb18abd --- /dev/null +++ b/drivers/misc/mediatek/smi/smi_info_util.h @@ -0,0 +1,13 @@ +#ifndef __SMI_INFO_UTIL_H__ +#define __SMI_INFO_UTIL_H__ + +#include <asm/io.h> +#include <linux/ioctl.h> +#include <linux/fs.h> +#include <mach/mt_smi.h> +int smi_set_mm_info_ioctl_wrapper(struct file *pFile, unsigned int cmd, unsigned long param); +int smi_get_mm_info_ioctl_wrapper(struct file *pFile, unsigned int cmd, unsigned long param); +void smi_bwc_mm_info_set(int property_id, long val1, long val2); +extern MTK_SMI_BWC_MM_INFO g_smi_bwc_mm_info; + +#endif /* __SMI_INFO_UTIL_H__ */ diff --git a/drivers/misc/mediatek/smi/smi_internal.c b/drivers/misc/mediatek/smi/smi_internal.c new file mode 100644 index 000000000..1fb786968 --- /dev/null +++ b/drivers/misc/mediatek/smi/smi_internal.c @@ -0,0 +1,61 @@ +#include <asm/io.h> +/* Define SMI_INTERNAL_CCF_SUPPORT when CCF needs to be enabled */ +#if !defined(CONFIG_MTK_LEGACY) +#define SMI_INTERNAL_CCF_SUPPORT +#endif + +#if defined(SMI_INTERNAL_CCF_SUPPORT) +#include <linux/clk.h> +/* for ccf clk CB */ +#if defined(SMI_D1) +#include "clk-mt6735-pg.h" +#elif defined(SMI_J) +#include "clk-mt6755-pg.h" +#endif +/* notify clk is enabled/disabled for m4u*/ +#include "m4u.h" +#else +#include <mach/mt_clkmgr.h> +#endif /* defined(SMI_INTERNAL_CCF_SUPPORT) */ + +#include "smi_configuration.h" +#include "smi_common.h" + +int smi_larb_clock_is_on(unsigned int larb_index) +{ + int result = 0; + +#if defined(SMI_INTERNAL_CCF_SUPPORT) + result = 1; +#elif !defined(CONFIG_MTK_FPGA) && !defined(CONFIG_FPGA_EARLY_PORTING) + switch (larb_index) { + case 0: + result = clock_is_on(MT_CG_DISP0_SMI_LARB0); + break; + case 1: +#if defined(SMI_R) + result = clock_is_on(MT_CG_LARB1_SMI_CKPDN); +#else + result = clock_is_on(MT_CG_VDEC1_LARB); +#endif + break; + case 2: +#if !defined(SMI_R) + result = clock_is_on(MT_CG_IMAGE_LARB2_SMI); +#endif + break; + case 3: +#if defined(SMI_D1) + result = clock_is_on(MT_CG_VENC_LARB); +#elif defined(SMI_D3) + result = clock_is_on(MT_CG_VENC_VENC); +#endif + break; + default: + result = 0; + break; + } +#endif /* !defined (CONFIG_MTK_FPGA) && !defined (CONFIG_FPGA_EARLY_PORTING) */ + return result; +} + diff --git a/drivers/misc/mediatek/smi/smi_reg.h b/drivers/misc/mediatek/smi/smi_reg.h new file mode 100644 index 000000000..84d61d42c --- /dev/null +++ b/drivers/misc/mediatek/smi/smi_reg.h @@ -0,0 +1,449 @@ +#ifndef _SMI_REG_H_ +#define _SMI_REG_H_ + +#define SMI_COMMON_EXT_BASE (smi_reg_base_common_ext) +#define LARB0_BASE (smi_reg_base_barb0) +#define LARB1_BASE (smi_reg_base_barb1) + +#if defined(SMI_D2) +#define LARB2_BASE (smi_reg_base_barb2) +#elif defined(SMI_D1) || defined(SMI_D3) || defined(SMI_J) +#define LARB2_BASE (smi_reg_base_barb2) +#define LARB3_BASE (smi_reg_base_barb3) +#endif + + +/* ================================================= */ +/* common macro definitions */ +#define F_VAL(val, msb, lsb) (((val)&((1<<(msb-lsb+1))-1))<<lsb) +#define F_MSK(msb, lsb) F_VAL(0xffffffff, msb, lsb) +#define F_BIT_SET(bit) (1<<(bit)) +#define F_BIT_VAL(val, bit) ((!!(val))<<(bit)) +#define F_MSK_SHIFT(regval, msb, lsb) (((regval)&F_MSK(msb, lsb))>>lsb) + + +/* ===================================================== */ +/* M4U register definition */ +/* ===================================================== */ + +#define REG_MMUg_PT_BASE (0x0) +#define F_MMUg_PT_VA_MSK 0xffff0000 +#define REG_MMUg_PT_BASE_SEC (0x4) +#define F_MMUg_PT_VA_MSK_SEC 0xffff0000 + + +#define REG_MMU_PROG_EN 0x10 +#define F_MMU0_PROG_EN 1 +#define F_MMU1_PROG_EN 2 +#define REG_MMU_PROG_VA 0x14 +#define F_PROG_VA_LOCK_BIT (1<<11) +#define F_PROG_VA_LAYER_BIT F_BIT_SET(9) +#define F_PROG_VA_SIZE16X_BIT F_BIT_SET(8) +#define F_PROG_VA_SECURE_BIT (1<<7) +#define F_PROG_VA_MASK 0xfffff000 + +#define REG_MMU_PROG_DSC 0x18 + +#define REG_MMU_INVLD (0x20) +#define F_MMU_INV_ALL 0x2 +#define F_MMU_INV_RANGE 0x1 + +#define REG_MMU_INVLD_SA (0x24) +#define REG_MMU_INVLD_EA (0x28) + + +#define REG_MMU_INVLD_SEC (0x2c) +#define F_MMU_INV_SEC_ALL 0x2 +#define F_MMU_INV_SEC_RANGE 0x1 + +#define REG_MMU_INVLD_SA_SEC (0x30) +#define REG_MMU_INVLD_EA_SEC (0x34) + +#define REG_INVLID_SEL (0x38) +#define F_MMU_INV_EN_L1 (1<<0) +#define F_MMU_INV_EN_L2 (1<<1) + + +#define REG_INVLID_SEL_SEC (0x3c) +#define F_MMU_INV_SEC_EN_L1 (1<<0) +#define F_MMU_INV_SEC_EN_L2 (1<<1) +#define F_MMU_INV_SEC_INV_DONE (1<<2) +#define F_MMU_INV_SEC_INV_INT_SET (1<<3) +#define F_MMU_INV_SEC_INV_INT_CLR (1<<4) +#define F_MMU_INV_SEC_DBG (1<<5) + + +#define REG_MMU_SEC_ABORT_INFO (0x40) +#define REG_MMU_STANDARD_AXI_MODE (0x48) + +#define REG_MMU_PRIORITY (0x4c) +#define REG_MMU_DCM_DIS (0x50) +#define REG_MMU_WR_LEN (0x54) +#define REG_MMU_HW_DEBUG (0x58) +#define F_MMU_HW_DBG_L2_SCAN_ALL F_BIT_SET(1) +#define F_MMU_HW_DBG_PFQ_BRDCST F_BIT_SET(0) + +#define REG_MMU_NON_BLOCKING_DIS 0x5C +#define F_MMU_NON_BLOCK_DISABLE_BIT 1 +#define F_MMU_NON_BLOCK_HALF_ENTRY_BIT 2 + +#define REG_MMU_LEGACY_4KB_MODE (0x60) + +#define REG_MMU_PFH_DIST0 0x80 +#define REG_MMU_PFH_DIST1 0x84 +#define REG_MMU_PFH_DIST2 0x88 +#define REG_MMU_PFH_DIST3 0x8c +#define REG_MMU_PFH_DIST4 0x90 +#define REG_MMU_PFH_DIST5 0x94 +#define REG_MMU_PFH_DIST6 0x98 + +#define REG_MMU_PFH_DIST(port) (0x80+(((port)>>3)<<2)) +#define F_MMU_PFH_DIST_VAL(port, val) ((val&0xf)<<(((port)&0x7)<<2)) +#define F_MMU_PFH_DIST_MASK(port) F_MMU_PFH_DIST_VAL((port), 0xf) + +#define REG_MMU_PFH_DIR0 0xF0 +#define REG_MMU_PFH_DIR1 0xF4 +#define REG_MMU_PFH_DIR(port) (((port) < 32) ? REG_MMU_PFH_DIR0 : REG_MMU_PFH_DIR1) +#define F_MMU_PFH_DIR(port, val) ((!!(val))<<((port)&0x1f)) + + +#define REG_MMU_READ_ENTRY 0x100 +#define F_READ_ENTRY_EN F_BIT_SET(31) +#define F_READ_ENTRY_MM1_MAIN F_BIT_SET(26) +#define F_READ_ENTRY_MM0_MAIN F_BIT_SET(25) +#define F_READ_ENTRY_MMx_MAIN(id) F_BIT_SET(25+id) +#define F_READ_ENTRY_PFH F_BIT_SET(24) +#define F_READ_ENTRY_MAIN_IDX(idx) F_VAL(idx, 21, 16) +#define F_READ_ENTRY_PFH_IDX(idx) F_VAL(idx, 11, 5) + /* #define F_READ_ENTRY_PFH_HI_LO(high) F_VAL(high, 4,4) */ + /* #define F_READ_ENTRY_PFH_PAGE(page) F_VAL(page, 3,2) */ +#define F_READ_ENTRY_PFH_PAGE_IDX(idx) F_VAL(idx, 4, 2) +#define F_READ_ENTRY_PFH_WAY(way) F_VAL(way, 1, 0) + +#define REG_MMU_DES_RDATA 0x104 + +#define REG_MMU_PFH_TAG_RDATA 0x108 +#define F_PFH_TAG_VA_GET(mmu, tag) (F_MSK_SHIFT(tag, 14, 4)<<(MMU_SET_MSB_OFFSET(mmu)+1)) +#define F_PFH_TAG_LAYER_BIT F_BIT_SET(3) +#define F_PFH_TAG_16X_BIT F_BIT_SET(2) /* this bit is always 0 -- cost down. */ +#define F_PFH_TAG_SEC_BIT F_BIT_SET(1) +#define F_PFH_TAG_AUTO_PFH F_BIT_SET(0) + + +/* tag related macro */ + /* #define MMU0_SET_ORDER 7 */ + /* #define MMU1_SET_ORDER 6 */ +#define MMU_SET_ORDER(mmu) (7-(mmu)) +#define MMU_SET_NR(mmu) (1<<MMU_SET_ORDER(mmu)) +#define MMU_SET_LSB_OFFSET 15 +#define MMU_SET_MSB_OFFSET(mmu) (MMU_SET_LSB_OFFSET+MMU_SET_ORDER(mmu)-1) +#define MMU_PFH_VA_TO_SET(mmu, va) F_MSK_SHIFT(va, MMU_SET_MSB_OFFSET(mmu), MMU_SET_LSB_OFFSET) + +#define MMU_PAGE_PER_LINE 8 +#define MMU_WAY_NR 4 +#define MMU_PFH_TOTAL_LINE(mmu) (MMU_SET_NR(mmu)*MMU_WAY_NR) + + +#define REG_MMU_CTRL_REG 0x110 +#define F_MMU_CTRL_PFH_DIS(dis) F_BIT_VAL(dis, 0) +#define F_MMU_CTRL_TLB_WALK_DIS(dis) F_BIT_VAL(dis, 1) +#define F_MMU_CTRL_MONITOR_EN(en) F_BIT_VAL(en, 2) +#define F_MMU_CTRL_MONITOR_CLR(clr) F_BIT_VAL(clr, 3) +#define F_MMU_CTRL_PFH_RT_RPL_MODE(mod) F_BIT_VAL(mod, 4) +#define F_MMU_CTRL_TF_PROT_VAL(prot) F_VAL(prot, 6, 5) +#define F_MMU_CTRL_TF_PROT_MSK F_MSK(6, 5) +#define F_MMU_CTRL_INT_HANG_en(en) F_BIT_VAL(en, 7) +#define F_MMU_CTRL_COHERE_EN(en) F_BIT_VAL(en, 8) +#define F_MMU_CTRL_IN_ORDER_WR(en) F_BIT_VAL(en, 9) +#define F_MMU_CTRL_MAIN_TLB_SHARE_ALL(en) F_BIT_VAL(en, 10) + + +#define REG_MMU_IVRP_PADDR 0x114 +#define F_MMU_IVRP_PA_SET(PA) (PA>>1) +#define F_MMU_IVRP_8G_PA_SET(PA) ((PA>>1)|(1<<31)) + +#define REG_MMU_INT_L2_CONTROL 0x120 +#define F_INT_L2_CLR_BIT (1<<12) +#define F_INT_L2_MULTI_HIT_FAULT F_BIT_SET(0) +#define F_INT_L2_TABLE_WALK_FAULT F_BIT_SET(1) +#define F_INT_L2_PFH_DMA_FIFO_OVERFLOW F_BIT_SET(2) +#define F_INT_L2_MISS_DMA_FIFO_OVERFLOW F_BIT_SET(3) +#define F_INT_L2_INVALD_DONE F_BIT_SET(4) +#define F_INT_L2_PFH_IN_OUT_FIFO_ERROR F_BIT_SET(5) +#define F_INT_L2_MISS_FIFO_ERR F_BIT_SET(6) + +#define REG_MMU_INT_MAIN_CONTROL 0x124 +#define F_INT_TRANSLATION_FAULT(MMU) F_BIT_SET(0+(((MMU)<<1)|((MMU)<<2))) +#define F_INT_MAIN_MULTI_HIT_FAULT(MMU) F_BIT_SET(1+(((MMU)<<1)|((MMU)<<2))) +#define F_INT_INVALID_PHYSICAL_ADDRESS_FAULT(MMU) F_BIT_SET(2+(((MMU)<<1)|((MMU)<<2))) +#define F_INT_ENTRY_REPLACEMENT_FAULT(MMU) F_BIT_SET(3+(((MMU)<<1)|((MMU)<<2))) +#define F_INT_TLB_MISS_FAULT(MMU) F_BIT_SET(5+(((MMU)<<1)|((MMU)<<2))) +#define F_INT_PFH_FIFO_ERR(MMU) F_BIT_SET(6+(((MMU)<<1)|((MMU)<<2))) + +#define F_INT_MAU(mmu, set) F_BIT_SET(14+(set)+(mmu<<2)) /* (14+(set)+(mmu*4)) */ + +#define F_INT_MMU0_MAIN_MSK F_MSK(6, 0) +#define F_INT_MMU1_MAIN_MSK F_MSK(13, 7) +#define F_INT_MMU0_MAU_MSK F_MSK(17, 14) +#define F_INT_MMU1_MAU_MSK F_MSK(21, 18) + +#define REG_MMU_CPE_DONE_SEC 0x128 +#define REG_MMU_CPE_DONE 0x12C + +#define REG_MMU_L2_FAULT_ST 0x130 +#define F_INT_L2_MISS_OUT_FIFO_ERROR F_BIT_SET(7) +#define F_INT_L2_MISS_IN_FIFO_ERR F_BIT_SET(8) +#define REG_MMU_MAIN_FAULT_ST 0x134 + +#define REG_MMU_TBWALK_FAULT_VA 0x138 +#define F_MMU_TBWALK_FAULT_VA_MSK F_MSK(31, 12) +#define F_MMU_TBWALK_FAULT_LAYER(regval) F_MSK_SHIFT(regval, 0, 0) + +#define REG_MMU_FAULT_VA(mmu) (0x13c+((mmu)<<3)) +#define F_MMU_FAULT_VA_MSK F_MSK(31, 12) +#define F_MMU_FAULT_VA_WRITE_BIT F_BIT_SET(1) +#define F_MMU_FAULT_VA_LAYER_BIT F_BIT_SET(0) + +#define REG_MMU_INVLD_PA(mmu) (0x140+((mmu)<<3)) +#define REG_MMU_INT_ID(mmu) (0x150+((mmu)<<2)) + +#define REG_MMU_PF_MSCNT 0x160 +#define REG_MMU_PF_CNT 0x164 +#define REG_MMU_ACC_CNT(mmu) (0x168+(((mmu)<<3)|((mmu)<<2))) /* (0x168+((mmu)*12) */ +#define REG_MMU_MAIN_MSCNT(mmu) (0x16c+(((mmu)<<3)|((mmu)<<2))) +#define REG_MMU_RS_PERF_CNT(mmu) (0x170+(((mmu)<<3)|((mmu)<<2))) + +#define MMU01_SQ_OFFSET (0x600-0x300) +#define REG_MMU_SQ_START(mmu, x) (0x300+((x)<<3)+((mmu)*MMU01_SQ_OFFSET)) +#define F_SQ_VA_MASK F_MSK(31, 18) +#define F_SQ_EN_BIT (1<<17) + /* #define F_SQ_MULTI_ENTRY_VAL(x) (((x)&0xf)<<13) */ +#define REG_MMU_SQ_END(mmu, x) (0x304+((x)<<3)+((mmu)*MMU01_SQ_OFFSET)) + + +#define MMU_TOTAL_RS_NR 8 +#define REG_MMU_RSx_VA(mmu, x) (0x380+((x)<<4)+((mmu)*MMU01_SQ_OFFSET)) +#define F_MMU_RSx_VA_GET(regval) ((regval)&F_MSK(31, 12)) +#define F_MMU_RSx_VA_VALID(regval) F_MSK_SHIFT(regval, 11, 11) +#define F_MMU_RSx_VA_PID(regval) F_MSK_SHIFT(regval, 9, 0) + +#define REG_MMU_RSx_PA(mmu, x) (0x384+((x)<<4)+((mmu)*MMU01_SQ_OFFSET)) +#define F_MMU_RSx_PA_GET(regval) ((regval)&F_MSK(31, 12)) +#define F_MMU_RSx_PA_VALID(regval) F_MSK_SHIFT(regval, 1, 0) + +#define REG_MMU_RSx_2ND_BASE(mmu, x) (0x388+((x)<<4)+((mmu)*MMU01_SQ_OFFSET)) + +#define REG_MMU_RSx_ST(mmu, x) (0x38c+((x)<<4)+((mmu)*MMU01_SQ_OFFSET)) +#define F_MMU_RSx_ST_LID(regval) F_MSK_SHIFT(regval, 21, 20) +#define F_MMU_RSx_ST_WRT(regval) F_MSK_SHIFT(regval, 12, 12) +#define F_MMU_RSx_ST_OTHER(regval) F_MSK_SHIFT(regval, 8, 0) + +#define REG_MMU_MAIN_TAG(mmu, x) (0x500+((x)<<2)+((mmu)*MMU01_SQ_OFFSET)) +#define F_MAIN_TLB_VA_MSK F_MSK(31, 12) +#define F_MAIN_TLB_LOCK_BIT (1<<11) +#define F_MAIN_TLB_VALID_BIT (1<<10) +#define F_MAIN_TLB_LAYER_BIT F_BIT_SET(9) +#define F_MAIN_TLB_16X_BIT F_BIT_SET(8) +#define F_MAIN_TLB_SEC_BIT F_BIT_SET(7) +#define F_MAIN_TLB_INV_DES_BIT (1<<6) +#define F_MAIN_TLB_SQ_EN_BIT (1<<5) +#define F_MAIN_TLB_SQ_INDEX_MSK F_MSK(4, 1) +#define F_MAIN_TLB_SQ_INDEX_GET(regval) F_MSK_SHIFT(regval, 4, 1) + + +#define REG_MMU_MAU_START(mmu, mau) (0x900+((mau)*0x20)+((mmu)*0xa0)) +#define REG_MMU_MAU_START_BIT32(mmu, mau) (0x904+((mau)*0x20)+((mmu)*0xa0)) +#define REG_MMU_MAU_END(mmu, mau) (0x908+((mau)*0x20)+((mmu)*0xa0)) +#define REG_MMU_MAU_END_BIT32(mmu, mau) (0x90C+((mau)*0x20)+((mmu)*0xa0)) +#define REG_MMU_MAU_PORT_EN(mmu, mau) (0x910+((mau)*0x20)+((mmu)*0xa0)) +#define REG_MMU_MAU_ASSERT_ID(mmu, mau) (0x914+((mau)*0x20)+((mmu)*0xa0)) +#define REG_MMU_MAU_ADDR(mmu, mau) (0x918+((mau)*0x20)+((mmu)*0xa0)) +#define REG_MMU_MAU_ADDR_BIT32(mmu, mau) (0x91C+((mau)*0x20)+((mmu)*0xa0)) + +#define REG_MMU_MAU_LARB_EN(mmu) (0x980+((mmu)*0xa0)) +#define F_MAU_LARB_VAL(mau, larb) ((larb)<<(mau*8)) +#define F_MAU_LARB_MSK(mau) (0xff<<(mau*8)) +#define REG_MMU_MAU_CLR(mmu) (0x984+((mmu)*0xa0)) +#define REG_MMU_MAU_IO(mmu) (0x988+((mmu)*0xa0)) +#define F_MAU_BIT_VAL(val, mau) F_BIT_VAL(val, mau) +#define REG_MMU_MAU_RW(mmu) (0x98c+((mmu)*0xa0)) +#define REG_MMU_MAU_VA(mmu) (0x990+((mmu)*0xa0)) +#define REG_MMU_MAU_ASSERT_ST(mmu) (0x994+((mmu)*0xa0)) + +#define REG_MMU_PFH_VLD_0 (0x180) +#define REG_MMU_PFH_VLD(set, way) (REG_MMU_PFH_VLD_0+(((set)>>5)<<2)+((way)<<4)) /* +((set/32)*4)+(way*16) */ +#define F_MMU_PFH_VLD_BIT(set, way) F_BIT_SET((set)&0x1f) /* set%32 */ + + + +/* ================================================================ */ +/* SMI larb */ +/* ================================================================ */ + +#define SMI_ERROR_ADDR 0 +#if defined(SMI_D2) +#define SMI_LARB_NR 3 + +#define SMI_LARB0_PORT_NUM 8 +#define SMI_LARB1_PORT_NUM 7 +#define SMI_LARB2_PORT_NUM 13 +#elif defined(SMI_D1) +#define SMI_LARB_NR 4 + +#define SMI_LARB0_PORT_NUM 7 +#define SMI_LARB1_PORT_NUM 7 +#define SMI_LARB2_PORT_NUM 21 +#define SMI_LARB3_PORT_NUM 13 +#elif defined(SMI_D3) +#define SMI_LARB_NR 4 + +#define SMI_LARB0_PORT_NUM 10 +#define SMI_LARB1_PORT_NUM 7 +#define SMI_LARB2_PORT_NUM 21 +#define SMI_LARB3_PORT_NUM 13 +#elif defined(SMI_R) +#define SMI_LARB_NR 2 + +#define SMI_LARB0_PORT_NUM 7 +#define SMI_LARB1_PORT_NUM 11 +#elif defined(SMI_J) +#define SMI_LARB_NR 4 + +#define SMI_LARB0_PORT_NUM 11 +#define SMI_LARB1_PORT_NUM 7 +#define SMI_LARB2_PORT_NUM 21 +#define SMI_LARB3_PORT_NUM 13 +#endif + +#define SMI_LARB_STAT (0x0) +#define SMI_LARB_IRQ_EN (0x4) +#define SMI_LARB_IRQ_STATUS (0x8) +#define SMI_LARB_SLP_CON (0xc) +#define SMI_LARB_CON (0x10) +#define SMI_LARB_CON_SET (0x14) +#define SMI_LARB_CON_CLR (0x18) +#define SMI_LARB_VC_PRI_MODE (0x20) +#define SMI_LARB_CMD_THRT_CON (0x24) +#define SMI_LARB_STARV_CON (0x28) +#define SMI_LARB_EMI_CON (0x2C) +#define SMI_LARB_SHARE_EN (0x30) +#define SMI_LARB_BWL_EN (0x50) +#define SMI_LARB_BWL_SOFT_EN (0x54) +#define SMI_LARB_BWL_CON (0x58) +#define SMI_LARB_OSTDL_EN (0x60) +#define SMI_LARB_OSTDL_SOFT_EN (0x64) +#define SMI_LARB_ULTRA_DIS (0x70) +#define SMI_LARB_PREULTRA_DIS (0x74) +#define SMI_LARB_FORCE_ULTRA (0x78) +#define SMI_LARB_FORCE_PREULTRA (0x7c) +#define SMI_LARB_MST_GRP_SEL_L (0x80) +#define SMI_LARB_MST_GRP_SEL_H (0x84) +#define SMI_LARB_INT_PATH_SEL (0x90) +#define SMI_LARB_EXT_GREQ_VIO (0xa0) +#define SMI_LARB_INT_GREQ_VIO (0xa4) +#define SMI_LARB_OSTD_UDF_VIO (0xa8) +#define SMI_LARB_OSTD_CRS_VIO (0xac) +#define SMI_LARB_FIFO_STAT (0xb0) +#define SMI_LARB_BUS_STAT (0xb4) +#define SMI_LARB_CMD_THRT_STAT (0xb8) +#define SMI_LARB_MON_REQ (0xbc) +#define SMI_LARB_REQ_MASK (0xc0) +#define SMI_LARB_REQ_DET (0xc4) +#define SMI_LARB_EXT_ONGOING (0xc8) +#define SMI_LARB_INT_ONGOING (0xcc) +#define SMI_LARB_MISC_MON0 (0xd0) +#define SMI_LARB_DBG_CON (0xf0) +#define SMI_LARB_TST_MODE (0xf4) +#define SMI_LARB_WRR_PORT (0x100) +#define SMI_LARB_BWL_PORT (0x180) +#define SMI_LARB_OSTDL_PORT (0x200) +#define SMI_LARB_OSTD_MON_PORT (0x280) +#define SMI_LARB_PINFO (0x300) +#define SMI_LARB_MON_EN (0x400) +#define SMI_LARB_MON_CLR (0x404) +#define SMI_LARB_MON_PORT (0x408) +#define SMI_LARB_MON_CON (0x40c) +#define SMI_LARB_MON_ACT_CNT (0x410) +#define SMI_LARB_MON_REQ_CNT (0x414) +#define SMI_LARB_MON_BEAT_CNT (0x418) +#define SMI_LARB_MON_BYTE_CNT (0x41c) +#define SMI_LARB_MON_CP_CNT (0x420) +#define SMI_LARB_MON_DP_CNT (0x424) +#define SMI_LARB_MON_OSTD_CNT (0x428) +#define SMI_LARB_MON_CP_MAX (0x430) +#define SMI_LARB_MON_COS_MAX (0x434) +#define SMI_LARB_MMU_EN (0xf00) +#define F_SMI_MMU_EN(port, en) ((en)<<((port))) +#define F_SMI_SEC_EN(port, en) ((en)<<((port))) +#define REG_SMI_LARB_DOMN_OF_PORT(port) (((port) > 15) ? 0xf0c : 0xf08) +#define F_SMI_DOMN(port, domain) (((domain)&0x3)<<((((port) > 15) ? (port-16) : port)<<1)) + + +/* =============================================================== + * SMI COMMON + * =============================================================== */ +#if defined(SMI_R) +#define REG_OFFSET_SMI_L1LEN (0x200) +#define REG_OFFSET_SMI_L1ARB0 (0x204) +#define REG_OFFSET_SMI_L1ARB1 (0x208) +#define REG_OFFSET_SMI_L1ARB2 (0x20C) +#define REG_OFFSET_SMI_L1ARB3 (0x210) +#define REG_OFFSET_SMI_L1ARB4 (0x214) +#else +#define REG_OFFSET_SMI_L1LEN (0x100) +#define REG_OFFSET_SMI_L1ARB0 (0x104) +#define REG_OFFSET_SMI_L1ARB1 (0x108) +#define REG_OFFSET_SMI_L1ARB2 (0x10C) +#define REG_OFFSET_SMI_L1ARB3 (0x110) +#define REG_OFFSET_SMI_L1ARB4 (0x114) +#endif + +/* ========================================================================= */ +/* peripheral system */ +/* ========================================================================= */ +#define REG_PERIAXI_BUS_CTL3 (0x208+0xf0003000) +#define F_PERI_MMU_EN(port, en) ((en)<<((port))) + + +static inline unsigned int M4U_ReadReg32(unsigned long M4uBase, unsigned long Offset) +{ + unsigned int val; + + val = ioread32((void *)(M4uBase + Offset)); + + return val; +} + +static inline void M4U_WriteReg32(unsigned long M4uBase, unsigned long Offset, unsigned int Val) +{ + /* unsigned int read; */ + iowrite32(Val, (void *)(M4uBase + Offset)); + /* make sure memory manipulation sequence is OK */ + mb(); + +} + +static inline unsigned int COM_ReadReg32(unsigned long addr) +{ + return ioread32((void *)addr); +} + +static inline void COM_WriteReg32(unsigned long addr, unsigned int Val) +{ + iowrite32(Val, (void *)addr); + /* make sure memory manipulation sequence is OK */ + mb(); +} + + +extern unsigned long smi_reg_base_common_ext; +extern unsigned long smi_reg_base_barb0; +extern unsigned long smi_reg_base_barb1; +#if defined(SMI_D2) +extern unsigned long smi_reg_base_barb2; +#elif defined(SMI_D1) || defined(SMI_D3) || defined(SMI_J) +extern unsigned long smi_reg_base_barb2; +extern unsigned long smi_reg_base_barb3; +#endif + +#endif diff --git a/drivers/misc/mediatek/smi/variant/Makefile b/drivers/misc/mediatek/smi/variant/Makefile new file mode 100644 index 000000000..e98461dad --- /dev/null +++ b/drivers/misc/mediatek/smi/variant/Makefile @@ -0,0 +1,15 @@ +ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat +ccflags-y += -I$(srctree)/drivers/misc/mediatek/m4u/$(MTK_PLATFORM)/ + +obj-y += smi_variant.o +obj-y += smi_debug.o + +ifeq ($(CONFIG_ARCH_MT8173),y) +obj-y += smi_variant_config_8173.o +ccflags-y += -DMT73 +endif + +ifeq ($(CONFIG_ARCH_MT8127),y) +ccflags-y += -DMT27 +obj-y += smi_variant_config_8127.o +endif diff --git a/drivers/misc/mediatek/smi/variant/smi_common.h b/drivers/misc/mediatek/smi/variant/smi_common.h new file mode 100644 index 000000000..93d05cb6f --- /dev/null +++ b/drivers/misc/mediatek/smi/variant/smi_common.h @@ -0,0 +1,55 @@ +#ifndef __SMI_COMMON_H__ +#define __SMI_COMMON_H__ + +#include <aee.h> + +#define SMI_CLIENT_DISP 0 +#define SMI_CLIENT_WFD 1 +#define SMI_EVENT_DIRECT_LINK (0x1 << 0) +#define SMI_EVENT_DECOUPLE (0x1 << 1) +#define SMI_EVENT_OVL_CASCADE (0x1 << 2) +#define SMI_EVENT_OVL1_EXTERNAL (0x1 << 3) + +#define SMIMSG(string, args...) pr_warn("[pid=%d]" string, current->tgid, ##args) +#define SMIMSG2(string, args...) pr_debug(string, ##args) +#define SMIMSG3(string, args...) SMIMSG(string, ##args) + +#define SMITMP(string, args...) pr_debug("[pid=%d]"string, current->tgid, ##args) + +#define SMIERR(string, args...) pr_debug("error: " string, ##args) +#define smi_aee_print(string, args...)\ + do {\ + char smi_name[100];\ + snprintf(smi_name, 100, "[" SMI_LOG_TAG "]" string, ##args); \ + } while (0) + +/* +#define SMIERR(string, args...)\ + do {\ + pr_debug("error: " string, ##args); \ + aee_kernel_warning(SMI_LOG_TAG, "error: "string, ##args); \ + } while (0) +#define smi_aee_print(string, args...)\ + do {\ + char smi_name[100];\ + snprintf(smi_name, 100, "[" SMI_LOG_TAG "]" string, ##args); \ + aee_kernel_warning(smi_name, "["SMI_LOG_TAG"]error:"string, ##args); \ + } while (0) +*/ +/* Please use the function to instead gLarbBaseAddr to prevent the NULL pointer access error */ +/* when the corrosponding larb is not exist */ +/* extern unsigned int gLarbBaseAddr[SMI_LARB_NR]; */ +/*extern unsigned long get_larb_base_addr(int larb_id);*/ + +extern char *smi_port_name[][21]; +/* for slow motion force 30 fps */ +extern int primary_display_force_set_vsync_fps(unsigned int fps); +extern unsigned int primary_display_get_fps(void); +extern void smi_dumpDebugMsg(void); +extern void smi_client_status_change_notify(int module, int mode); +extern void SMI_DBG_Init(void); +void register_base_dump(void); + + + +#endif diff --git a/drivers/misc/mediatek/smi/variant/smi_debug.c b/drivers/misc/mediatek/smi/variant/smi_debug.c new file mode 100644 index 000000000..43e455382 --- /dev/null +++ b/drivers/misc/mediatek/smi/variant/smi_debug.c @@ -0,0 +1,136 @@ +#include <linux/uaccess.h> +#include <linux/module.h> +#include <linux/fs.h> +#include <linux/platform_device.h> +#include <linux/cdev.h> +#include <linux/interrupt.h> +#include <asm/io.h> +#include <linux/sched.h> +#include <linux/wait.h> +#include <linux/spinlock.h> +#include <linux/delay.h> +#include <linux/mm.h> +#include <linux/vmalloc.h> +#include <linux/dma-mapping.h> +#include <linux/slab.h> +#include <aee.h> +#include <linux/timer.h> +/* #include <asm/system.h> */ +#include <asm-generic/irq_regs.h> +/* #include <asm/mach/map.h> */ +#include <sync_write.h> +/*#include <mach/irqs.h>*/ +#include <asm/cacheflush.h> +#include <linux/string.h> +#include <linux/time.h> +#include <linux/fb.h> +#include <linux/debugfs.h> +#include <m4u.h> +#include <mt_smi.h> + +#include "smi_common.h" +#include "smi_reg.h" + +#define SMI_LOG_TAG "smi" + +static char debug_buffer[4096]; + +static void process_dbg_opt(const char *opt) +{ + unsigned long addr = 0; + int ret = 0; + + if (0 == strncmp(opt, "set_reg:", 8)) { + unsigned long val = 0; + + char *p = (char *)opt + 8; + + ret = kstrtoul(p, 16, &addr); + p++; + + ret = kstrtoul(p, 16, &val); + + SMIMSG("set register: 0x%lx = 0x%x\n", addr, (unsigned int)val); + + COM_WriteReg32(addr, val); + } + if (0 == strncmp(opt, "get_reg:", 8)) { + char *p = (char *)opt + 8; + + ret = kstrtoul(p, 16, &addr); + + SMIMSG("get register: 0x%lx = 0x%x\n", addr, COM_ReadReg32(addr)); + } + +} + + +static void process_dbg_cmd(char *cmd) +{ + char *tok; + + while ((tok = strsep(&cmd, " ")) != NULL) + process_dbg_opt(tok); + +} + + +/* --------------------------------------------------------------------------- */ +/* Debug FileSystem Routines */ +/* --------------------------------------------------------------------------- */ + +struct dentry *smi_dbgfs = NULL; + + +static int debug_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +static ssize_t debug_read(struct file *file, char __user *ubuf, size_t count, loff_t *ppos) +{ + int n = 0; + + return simple_read_from_buffer(ubuf, count, ppos, debug_buffer, n); +} + + +static ssize_t debug_write(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos) +{ + const int debug_bufmax = sizeof(debug_buffer) - 1; + size_t ret; + + ret = count; + + if (count > debug_bufmax) + count = debug_bufmax; + + if (copy_from_user(&debug_buffer, ubuf, count)) + return -EFAULT; + + debug_buffer[count] = 0; + + process_dbg_cmd(debug_buffer); + + return ret; +} + + +static const struct file_operations debug_fops = { + .read = debug_read, + .write = debug_write, + .open = debug_open, +}; + + +void SMI_DBG_Init(void) +{ + smi_dbgfs = debugfs_create_file("smi", S_IFREG | S_IRUGO, NULL, (void *)0, &debug_fops); +} + + +void SMI_DBG_Deinit(void) +{ + debugfs_remove(smi_dbgfs); +} diff --git a/drivers/misc/mediatek/smi/variant/smi_debug.h b/drivers/misc/mediatek/smi/variant/smi_debug.h new file mode 100644 index 000000000..3810d012e --- /dev/null +++ b/drivers/misc/mediatek/smi/variant/smi_debug.h @@ -0,0 +1,23 @@ +#ifndef __MT8173_SMI_DEBUG_H__ +#define __MT8173_SMI_DEBUG_H__ + +#define SMI_DBG_DISPSYS (1<<0) +#define SMI_DBG_VDEC (1<<1) +#define SMI_DBG_IMGSYS (1<<2) +#define SMI_DBG_VENC (1<<3) +#define SMI_DBG_MJC (1<<4) + +#define SMI_DGB_LARB_SELECT(smi_dbg_larb, n) ((smi_dbg_larb) & (1<<n)) + +#ifndef CONFIG_MTK_SMI_EXT +#define smi_debug_bus_hanging_detect(larbs, show_dump) {} +#define smi_debug_bus_hanging_detect_ext(larbs, show_dump, output_gce_buffer) {} +#else +int smi_debug_bus_hanging_detect(unsigned int larbs, int show_dump); + /* output_gce_buffer = 1, pass log to CMDQ error dumping messages */ +int smi_debug_bus_hanging_detect_ext(unsigned int larbs, int show_dump, int output_gce_buffer); + +#endif + + +#endif /* __MT6735_SMI_DEBUG_H__ */ diff --git a/drivers/misc/mediatek/smi/variant/smi_priv.h b/drivers/misc/mediatek/smi/variant/smi_priv.h new file mode 100644 index 000000000..769d7ff51 --- /dev/null +++ b/drivers/misc/mediatek/smi/variant/smi_priv.h @@ -0,0 +1,36 @@ +#ifndef __SMI_PRIV_H__ +#define __SMI_PRIV_H__ + +#include "smi_reg.h" + +#define SMI_LARB_PORT_NR_MAX 21/* Max port num in current platform.*/ +struct mtk_smi_priv; + +struct mtk_smi_data { + unsigned int larb_nr; + struct device *larb[SMI_LARB_NR]; + struct device *smicommon; + const struct mtk_smi_priv *smi_priv; + unsigned long smi_common_base; + unsigned long larb_base[SMI_LARB_NR]; + + /*record the larb port register, please use the max value*/ + unsigned short int larb_port_backup[SMI_LARB_PORT_NR_MAX*SMI_LARB_NR]; +}; + +struct mtk_smi_priv { + unsigned int larb_port_num[SMI_LARB_NR];/* the port number in each larb */ + unsigned char larb_vc_setting[SMI_LARB_NR]; + void (*init_setting)(struct mtk_smi_data *, bool *, + u32 *, unsigned int); + void (*vp_setting)(struct mtk_smi_data *); + void (*vr_setting)(struct mtk_smi_data *); + void (*hdmi_setting)(struct mtk_smi_data *); + void (*hdmi_4k_setting)(struct mtk_smi_data *); +}; + + +extern const struct mtk_smi_priv smi_mt8173_priv; +extern const struct mtk_smi_priv smi_mt8127_priv; + +#endif diff --git a/drivers/misc/mediatek/smi/variant/smi_reg.h b/drivers/misc/mediatek/smi/variant/smi_reg.h new file mode 100644 index 000000000..1bbd628c7 --- /dev/null +++ b/drivers/misc/mediatek/smi/variant/smi_reg.h @@ -0,0 +1,536 @@ +#ifndef _SMI_REG_H__ +#define _SMI_REG_H__ + +#ifndef CONFIG_MTK_SMI_VARIANT + +#define SMI_COMMON_EXT_BASE (smi_reg_base_common_ext) +#define LARB0_BASE (smi_reg_base_barb0) +#define LARB1_BASE (smi_reg_base_barb1) + +#if defined D2 +#define LARB2_BASE (smi_reg_base_barb2) +#elif defined D1 || defined D3 +#define LARB2_BASE (smi_reg_base_barb2) +#define LARB3_BASE (smi_reg_base_barb3) +#endif + +#else +extern struct mtk_smi_data *smi_data; + +#define LARB0_BASE smi_data->larb_base[0] +#define LARB1_BASE smi_data->larb_base[1] +#define LARB2_BASE smi_data->larb_base[2] +#define LARB3_BASE smi_data->larb_base[3] +#define LARB4_BASE smi_data->larb_base[4] +#define LARB5_BASE smi_data->larb_base[5] + +#define SMI_COMMON_EXT_BASE smi_data->smi_common_base + +#endif + +/* ================================================= */ +/* common macro definitions */ +#define F_VAL(val, msb, lsb) (((val)&((1<<(msb-lsb+1))-1))<<lsb) +#define F_MSK(msb, lsb) F_VAL(0xffffffff, msb, lsb) +#define F_BIT_SET(bit) (1<<(bit)) +#define F_BIT_VAL(val, bit) ((!!(val))<<(bit)) +#define F_MSK_SHIFT(regval, msb, lsb) (((regval)&F_MSK(msb, lsb))>>lsb) + + +/* ===================================================== */ +/* M4U register definition */ +/* ===================================================== */ + +#define REG_MMUg_PT_BASE (0x0) +#define F_MMUg_PT_VA_MSK 0xffff0000 +#define REG_MMUg_PT_BASE_SEC (0x4) +#define F_MMUg_PT_VA_MSK_SEC 0xffff0000 + + +#define REG_MMU_PROG_EN 0x10 +#define F_MMU0_PROG_EN 1 +#define F_MMU1_PROG_EN 2 +#define REG_MMU_PROG_VA 0x14 +#define F_PROG_VA_LOCK_BIT (1<<11) +#define F_PROG_VA_LAYER_BIT F_BIT_SET(9) +#define F_PROG_VA_SIZE16X_BIT F_BIT_SET(8) +#define F_PROG_VA_SECURE_BIT (1<<7) +#define F_PROG_VA_MASK 0xfffff000 + +#define REG_MMU_PROG_DSC 0x18 + +#define REG_MMU_INVLD (0x20) +#define F_MMU_INV_ALL 0x2 +#define F_MMU_INV_RANGE 0x1 + +#define REG_MMU_INVLD_SA (0x24) +#define REG_MMU_INVLD_EA (0x28) + + +#define REG_MMU_INVLD_SEC (0x2c) +#define F_MMU_INV_SEC_ALL 0x2 +#define F_MMU_INV_SEC_RANGE 0x1 + +#define REG_MMU_INVLD_SA_SEC (0x30) +#define REG_MMU_INVLD_EA_SEC (0x34) + +#define REG_INVLID_SEL (0x38) +#define F_MMU_INV_EN_L1 (1<<0) +#define F_MMU_INV_EN_L2 (1<<1) + + +#define REG_INVLID_SEL_SEC (0x3c) +#define F_MMU_INV_SEC_EN_L1 (1<<0) +#define F_MMU_INV_SEC_EN_L2 (1<<1) +#define F_MMU_INV_SEC_INV_DONE (1<<2) +#define F_MMU_INV_SEC_INV_INT_SET (1<<3) +#define F_MMU_INV_SEC_INV_INT_CLR (1<<4) +#define F_MMU_INV_SEC_DBG (1<<5) + + +#define REG_MMU_SEC_ABORT_INFO (0x40) +#define REG_MMU_STANDARD_AXI_MODE (0x48) + +#define REG_MMU_PRIORITY (0x4c) +#define REG_MMU_DCM_DIS (0x50) +#define REG_MMU_WR_LEN (0x54) +#define REG_MMU_HW_DEBUG (0x58) +#define F_MMU_HW_DBG_L2_SCAN_ALL F_BIT_SET(1) +#define F_MMU_HW_DBG_PFQ_BRDCST F_BIT_SET(0) + +#define REG_MMU_NON_BLOCKING_DIS 0x5C +#define F_MMU_NON_BLOCK_DISABLE_BIT 1 +#define F_MMU_NON_BLOCK_HALF_ENTRY_BIT 2 + +#define REG_MMU_LEGACY_4KB_MODE (0x60) + +#define REG_MMU_PFH_DIST0 0x80 +#define REG_MMU_PFH_DIST1 0x84 +#define REG_MMU_PFH_DIST2 0x88 +#define REG_MMU_PFH_DIST3 0x8c +#define REG_MMU_PFH_DIST4 0x90 +#define REG_MMU_PFH_DIST5 0x94 +#define REG_MMU_PFH_DIST6 0x98 + +#define REG_MMU_PFH_DIST(port) (0x80+(((port)>>3)<<2)) +#define F_MMU_PFH_DIST_VAL(port, val) ((val&0xf)<<(((port)&0x7)<<2)) +#define F_MMU_PFH_DIST_MASK(port) F_MMU_PFH_DIST_VAL((port), 0xf) + +#define REG_MMU_PFH_DIR0 0xF0 +#define REG_MMU_PFH_DIR1 0xF4 +#define REG_MMU_PFH_DIR(port) (((port) < 32) ? REG_MMU_PFH_DIR0 : REG_MMU_PFH_DIR1) +#define F_MMU_PFH_DIR(port, val) ((!!(val))<<((port)&0x1f)) + + +#define REG_MMU_READ_ENTRY 0x100 +#define F_READ_ENTRY_EN F_BIT_SET(31) +#define F_READ_ENTRY_MM1_MAIN F_BIT_SET(26) +#define F_READ_ENTRY_MM0_MAIN F_BIT_SET(25) +#define F_READ_ENTRY_MMx_MAIN(id) F_BIT_SET(25+id) +#define F_READ_ENTRY_PFH F_BIT_SET(24) +#define F_READ_ENTRY_MAIN_IDX(idx) F_VAL(idx, 21, 16) +#define F_READ_ENTRY_PFH_IDX(idx) F_VAL(idx, 11, 5) + /* #define F_READ_ENTRY_PFH_HI_LO(high) F_VAL(high, 4,4) */ + /* #define F_READ_ENTRY_PFH_PAGE(page) F_VAL(page, 3,2) */ +#define F_READ_ENTRY_PFH_PAGE_IDX(idx) F_VAL(idx, 4, 2) +#define F_READ_ENTRY_PFH_WAY(way) F_VAL(way, 1, 0) + +#define REG_MMU_DES_RDATA 0x104 + +#define REG_MMU_PFH_TAG_RDATA 0x108 +#define F_PFH_TAG_VA_GET(mmu, tag) (F_MSK_SHIFT(tag, 14, 4)<<(MMU_SET_MSB_OFFSET(mmu)+1)) +#define F_PFH_TAG_LAYER_BIT F_BIT_SET(3) +#define F_PFH_TAG_16X_BIT F_BIT_SET(2) /* this bit is always 0 -- cost down. */ +#define F_PFH_TAG_SEC_BIT F_BIT_SET(1) +#define F_PFH_TAG_AUTO_PFH F_BIT_SET(0) + + +/* tag related macro */ + /* #define MMU0_SET_ORDER 7 */ + /* #define MMU1_SET_ORDER 6 */ +#define MMU_SET_ORDER(mmu) (7-(mmu)) +#define MMU_SET_NR(mmu) (1<<MMU_SET_ORDER(mmu)) +#define MMU_SET_LSB_OFFSET 15 +#define MMU_SET_MSB_OFFSET(mmu) (MMU_SET_LSB_OFFSET+MMU_SET_ORDER(mmu)-1) +#define MMU_PFH_VA_TO_SET(mmu, va) F_MSK_SHIFT(va, MMU_SET_MSB_OFFSET(mmu), MMU_SET_LSB_OFFSET) + +#define MMU_PAGE_PER_LINE 8 +#define MMU_WAY_NR 4 +#define MMU_PFH_TOTAL_LINE(mmu) (MMU_SET_NR(mmu)*MMU_WAY_NR) + + +#define REG_MMU_CTRL_REG 0x110 +#define F_MMU_CTRL_PFH_DIS(dis) F_BIT_VAL(dis, 0) +#define F_MMU_CTRL_TLB_WALK_DIS(dis) F_BIT_VAL(dis, 1) +#define F_MMU_CTRL_MONITOR_EN(en) F_BIT_VAL(en, 2) +#define F_MMU_CTRL_MONITOR_CLR(clr) F_BIT_VAL(clr, 3) +#define F_MMU_CTRL_PFH_RT_RPL_MODE(mod) F_BIT_VAL(mod, 4) +#define F_MMU_CTRL_TF_PROT_VAL(prot) F_VAL(prot, 6, 5) +#define F_MMU_CTRL_TF_PROT_MSK F_MSK(6, 5) +#define F_MMU_CTRL_INT_HANG_en(en) F_BIT_VAL(en, 7) +#define F_MMU_CTRL_COHERE_EN(en) F_BIT_VAL(en, 8) +#define F_MMU_CTRL_IN_ORDER_WR(en) F_BIT_VAL(en, 9) +#define F_MMU_CTRL_MAIN_TLB_SHARE_ALL(en) F_BIT_VAL(en, 10) + + +#define REG_MMU_IVRP_PADDR 0x114 +#define F_MMU_IVRP_PA_SET(PA) (PA>>1) +#define F_MMU_IVRP_8G_PA_SET(PA) ((PA>>1)|(1<<31)) + +#define REG_MMU_INT_L2_CONTROL 0x120 +#define F_INT_L2_CLR_BIT (1<<12) +#define F_INT_L2_MULTI_HIT_FAULT F_BIT_SET(0) +#define F_INT_L2_TABLE_WALK_FAULT F_BIT_SET(1) +#define F_INT_L2_PFH_DMA_FIFO_OVERFLOW F_BIT_SET(2) +#define F_INT_L2_MISS_DMA_FIFO_OVERFLOW F_BIT_SET(3) +#define F_INT_L2_INVALD_DONE F_BIT_SET(4) +#define F_INT_L2_PFH_IN_OUT_FIFO_ERROR F_BIT_SET(5) +#define F_INT_L2_MISS_FIFO_ERR F_BIT_SET(6) + +#define REG_MMU_INT_MAIN_CONTROL 0x124 +#define F_INT_TRANSLATION_FAULT(MMU) F_BIT_SET(0+(((MMU)<<1)|((MMU)<<2))) +#define F_INT_MAIN_MULTI_HIT_FAULT(MMU) F_BIT_SET(1+(((MMU)<<1)|((MMU)<<2))) +#define F_INT_INVALID_PHYSICAL_ADDRESS_FAULT(MMU) F_BIT_SET(2+(((MMU)<<1)|((MMU)<<2))) +#define F_INT_ENTRY_REPLACEMENT_FAULT(MMU) F_BIT_SET(3+(((MMU)<<1)|((MMU)<<2))) +#define F_INT_TLB_MISS_FAULT(MMU) F_BIT_SET(5+(((MMU)<<1)|((MMU)<<2))) +#define F_INT_PFH_FIFO_ERR(MMU) F_BIT_SET(6+(((MMU)<<1)|((MMU)<<2))) + +#define F_INT_MAU(mmu, set) F_BIT_SET(14+(set)+(mmu<<2)) /* (14+(set)+(mmu*4)) */ + +#define F_INT_MMU0_MAIN_MSK F_MSK(6, 0) +#define F_INT_MMU1_MAIN_MSK F_MSK(13, 7) +#define F_INT_MMU0_MAU_MSK F_MSK(17, 14) +#define F_INT_MMU1_MAU_MSK F_MSK(21, 18) + +#define REG_MMU_CPE_DONE_SEC 0x128 +#define REG_MMU_CPE_DONE 0x12C + +#define REG_MMU_L2_FAULT_ST 0x130 +#define F_INT_L2_MISS_OUT_FIFO_ERROR F_BIT_SET(7) +#define F_INT_L2_MISS_IN_FIFO_ERR F_BIT_SET(8) +#define REG_MMU_MAIN_FAULT_ST 0x134 + +#define REG_MMU_TBWALK_FAULT_VA 0x138 +#define F_MMU_TBWALK_FAULT_VA_MSK F_MSK(31, 12) +#define F_MMU_TBWALK_FAULT_LAYER(regval) F_MSK_SHIFT(regval, 0, 0) + +#define REG_MMU_FAULT_VA(mmu) (0x13c+((mmu)<<3)) +#define F_MMU_FAULT_VA_MSK F_MSK(31, 12) +#define F_MMU_FAULT_VA_WRITE_BIT F_BIT_SET(1) +#define F_MMU_FAULT_VA_LAYER_BIT F_BIT_SET(0) + +#define REG_MMU_INVLD_PA(mmu) (0x140+((mmu)<<3)) +#define REG_MMU_INT_ID(mmu) (0x150+((mmu)<<2)) + +#define REG_MMU_PF_MSCNT 0x160 +#define REG_MMU_PF_CNT 0x164 +#define REG_MMU_ACC_CNT(mmu) (0x168+(((mmu)<<3)|((mmu)<<2))) /* (0x168+((mmu)*12) */ +#define REG_MMU_MAIN_MSCNT(mmu) (0x16c+(((mmu)<<3)|((mmu)<<2))) +#define REG_MMU_RS_PERF_CNT(mmu) (0x170+(((mmu)<<3)|((mmu)<<2))) + +#define MMU01_SQ_OFFSET (0x600-0x300) +#define REG_MMU_SQ_START(mmu, x) (0x300+((x)<<3)+((mmu)*MMU01_SQ_OFFSET)) +#define F_SQ_VA_MASK F_MSK(31, 18) +#define F_SQ_EN_BIT (1<<17) + /* #define F_SQ_MULTI_ENTRY_VAL(x) (((x)&0xf)<<13) */ +#define REG_MMU_SQ_END(mmu, x) (0x304+((x)<<3)+((mmu)*MMU01_SQ_OFFSET)) + + +#define MMU_TOTAL_RS_NR 8 +#define REG_MMU_RSx_VA(mmu, x) (0x380+((x)<<4)+((mmu)*MMU01_SQ_OFFSET)) +#define F_MMU_RSx_VA_GET(regval) ((regval)&F_MSK(31, 12)) +#define F_MMU_RSx_VA_VALID(regval) F_MSK_SHIFT(regval, 11, 11) +#define F_MMU_RSx_VA_PID(regval) F_MSK_SHIFT(regval, 9, 0) + +#define REG_MMU_RSx_PA(mmu, x) (0x384+((x)<<4)+((mmu)*MMU01_SQ_OFFSET)) +#define F_MMU_RSx_PA_GET(regval) ((regval)&F_MSK(31, 12)) +#define F_MMU_RSx_PA_VALID(regval) F_MSK_SHIFT(regval, 1, 0) + +#define REG_MMU_RSx_2ND_BASE(mmu, x) (0x388+((x)<<4)+((mmu)*MMU01_SQ_OFFSET)) + +#define REG_MMU_RSx_ST(mmu, x) (0x38c+((x)<<4)+((mmu)*MMU01_SQ_OFFSET)) +#define F_MMU_RSx_ST_LID(regval) F_MSK_SHIFT(regval, 21, 20) +#define F_MMU_RSx_ST_WRT(regval) F_MSK_SHIFT(regval, 12, 12) +#define F_MMU_RSx_ST_OTHER(regval) F_MSK_SHIFT(regval, 8, 0) + +#define REG_MMU_MAIN_TAG(mmu, x) (0x500+((x)<<2)+((mmu)*MMU01_SQ_OFFSET)) +#define F_MAIN_TLB_VA_MSK F_MSK(31, 12) +#define F_MAIN_TLB_LOCK_BIT (1<<11) +#define F_MAIN_TLB_VALID_BIT (1<<10) +#define F_MAIN_TLB_LAYER_BIT F_BIT_SET(9) +#define F_MAIN_TLB_16X_BIT F_BIT_SET(8) +#define F_MAIN_TLB_SEC_BIT F_BIT_SET(7) +#define F_MAIN_TLB_INV_DES_BIT (1<<6) +#define F_MAIN_TLB_SQ_EN_BIT (1<<5) +#define F_MAIN_TLB_SQ_INDEX_MSK F_MSK(4, 1) +#define F_MAIN_TLB_SQ_INDEX_GET(regval) F_MSK_SHIFT(regval, 4, 1) + + +#define REG_MMU_MAU_START(mmu, mau) (0x900+((mau)*0x20)+((mmu)*0xa0)) +#define REG_MMU_MAU_START_BIT32(mmu, mau) (0x904+((mau)*0x20)+((mmu)*0xa0)) +#define REG_MMU_MAU_END(mmu, mau) (0x908+((mau)*0x20)+((mmu)*0xa0)) +#define REG_MMU_MAU_END_BIT32(mmu, mau) (0x90C+((mau)*0x20)+((mmu)*0xa0)) +#define REG_MMU_MAU_PORT_EN(mmu, mau) (0x910+((mau)*0x20)+((mmu)*0xa0)) +#define REG_MMU_MAU_ASSERT_ID(mmu, mau) (0x914+((mau)*0x20)+((mmu)*0xa0)) +#define REG_MMU_MAU_ADDR(mmu, mau) (0x918+((mau)*0x20)+((mmu)*0xa0)) +#define REG_MMU_MAU_ADDR_BIT32(mmu, mau) (0x91C+((mau)*0x20)+((mmu)*0xa0)) + +#define REG_MMU_MAU_LARB_EN(mmu) (0x980+((mmu)*0xa0)) +#define F_MAU_LARB_VAL(mau, larb) ((larb)<<(mau*8)) +#define F_MAU_LARB_MSK(mau) (0xff<<(mau*8)) +#define REG_MMU_MAU_CLR(mmu) (0x984+((mmu)*0xa0)) +#define REG_MMU_MAU_IO(mmu) (0x988+((mmu)*0xa0)) +#define F_MAU_BIT_VAL(val, mau) F_BIT_VAL(val, mau) +#define REG_MMU_MAU_RW(mmu) (0x98c+((mmu)*0xa0)) +#define REG_MMU_MAU_VA(mmu) (0x990+((mmu)*0xa0)) +#define REG_MMU_MAU_ASSERT_ST(mmu) (0x994+((mmu)*0xa0)) + +#define REG_MMU_PFH_VLD_0 (0x180) +#define REG_MMU_PFH_VLD(set, way) (REG_MMU_PFH_VLD_0+(((set)>>5)<<2)+((way)<<4)) /* +((set/32)*4)+(way*16) */ +#define F_MMU_PFH_VLD_BIT(set, way) F_BIT_SET((set)&0x1f) /* set%32 */ + + + +/* ================================================================ */ +/* SMI larb */ +/* ================================================================ */ + +#define SMI_ERROR_ADDR 0 + +#if defined D2 +#define SMI_LARB_NR 3 + +#define SMI_LARB0_PORT_NUM 8 +#define SMI_LARB1_PORT_NUM 7 +#define SMI_LARB2_PORT_NUM 13 +#elif defined D1 +#define SMI_LARB_NR 4 + +#define SMI_LARB0_PORT_NUM 7 +#define SMI_LARB1_PORT_NUM 7 +#define SMI_LARB2_PORT_NUM 21 +#define SMI_LARB3_PORT_NUM 13 +#elif defined D3 +#define SMI_LARB_NR 4 + +#define SMI_LARB0_PORT_NUM 10 +#define SMI_LARB1_PORT_NUM 7 +#define SMI_LARB2_PORT_NUM 21 +#define SMI_LARB3_PORT_NUM 13 +#elif defined R +#define SMI_LARB_NR 2 + +#define SMI_LARB0_PORT_NUM 7 +#define SMI_LARB1_PORT_NUM 11 + +#elif defined MT73 + +#define SMI_LARB_NR 6 + +#elif defined MT27 + +#define SMI_LARB_NR 3 + +#endif + +#define SMI_LARB_STAT (0x0) +#define SMI_LARB_IRQ_EN (0x4) +#define SMI_LARB_IRQ_STATUS (0x8) +#define SMI_LARB_SLP_CON (0xc) +#define SMI_LARB_CON (0x10) +#define SMI_LARB_CON_SET (0x14) +#define SMI_LARB_CON_CLR (0x18) +#define SMI_LARB_VC_PRI_MODE (0x20) +#define SMI_LARB_CMD_THRT_CON (0x24) +#define SMI_LARB_STARV_CON (0x28) +#define SMI_LARB_EMI_CON (0x2C) +#define SMI_LARB_SHARE_EN (0x30) +#define SMI_LARB_BWL_EN (0x50) +#define SMI_LARB_BWL_SOFT_EN (0x54) +#define SMI_LARB_BWL_CON (0x58) +#define SMI_LARB_OSTDL_EN (0x60) +#define SMI_LARB_OSTDL_SOFT_EN (0x64) +#define SMI_LARB_ULTRA_DIS (0x70) +#define SMI_LARB_PREULTRA_DIS (0x74) +#define SMI_LARB_FORCE_ULTRA (0x78) +#define SMI_LARB_FORCE_PREULTRA (0x7c) +#define SMI_LARB_MST_GRP_SEL_L (0x80) +#define SMI_LARB_MST_GRP_SEL_H (0x84) +#define SMI_LARB_INT_PATH_SEL (0x90) +#define SMI_LARB_EXT_GREQ_VIO (0xa0) +#define SMI_LARB_INT_GREQ_VIO (0xa4) +#define SMI_LARB_OSTD_UDF_VIO (0xa8) +#define SMI_LARB_OSTD_CRS_VIO (0xac) +#define SMI_LARB_FIFO_STAT (0xb0) +#define SMI_LARB_BUS_STAT (0xb4) +#define SMI_LARB_CMD_THRT_STAT (0xb8) +#define SMI_LARB_MON_REQ (0xbc) +#define SMI_LARB_REQ_MASK (0xc0) +#define SMI_LARB_REQ_DET (0xc4) +#define SMI_LARB_EXT_ONGOING (0xc8) +#define SMI_LARB_INT_ONGOING (0xcc) +#define SMI_LARB_MISC_MON0 (0xd0) +#define SMI_LARB_DBG_CON (0xf0) +#define SMI_LARB_TST_MODE (0xf4) +#define SMI_LARB_WRR_PORT (0x100) +#define SMI_LARB_BWL_PORT (0x180) +#define SMI_LARB_OSTDL_PORT (0x200) +#define SMI_LARB_OSTD_MON_PORT (0x280) +#define SMI_LARB_PINFO (0x300) +#define SMI_LARB_MON_EN (0x400) +#define SMI_LARB_MON_CLR (0x404) +#define SMI_LARB_MON_PORT (0x408) +#define SMI_LARB_MON_CON (0x40c) +#define SMI_LARB_MON_ACT_CNT (0x410) +#define SMI_LARB_MON_REQ_CNT (0x414) +#define SMI_LARB_MON_BEAT_CNT (0x418) +#define SMI_LARB_MON_BYTE_CNT (0x41c) +#define SMI_LARB_MON_CP_CNT (0x420) +#define SMI_LARB_MON_DP_CNT (0x424) +#define SMI_LARB_MON_OSTD_CNT (0x428) +#define SMI_LARB_MON_CP_MAX (0x430) +#define SMI_LARB_MON_COS_MAX (0x434) +#define SMI_LARB_MMU_EN (0xf00) +#define F_SMI_MMU_EN(port, en) ((en)<<((port))) +#define F_SMI_SEC_EN(port, en) ((en)<<((port))) +#define REG_SMI_LARB_DOMN_OF_PORT(port) (((port) > 15) ? 0xf0c : 0xf08) +#define F_SMI_DOMN(port, domain) (((domain)&0x3)<<((((port) > 15) ? (port-16) : port)<<1)) + + + + +/* +#define SMI_SHARE_EN (0x210) + #define F_SMI_SHARE_EN(port) F_BIT_SET(m4u_port_2_larb_port(port)) +#define SMI_ROUTE_SEL (0x220) + #define F_SMI_ROUTE_SEL_EMI(port) F_BIT_SET(m4u_port_2_larb_port(port)) +#define SMI_MMULOCK_EN (0x230) +*/ + + +/* =============================================================== + * SMI COMMON + * =============================================================== */ +#if defined R +#define REG_OFFSET_SMI_L1LEN (0x200) +#define REG_OFFSET_SMI_L1ARB0 (0x204) +#define REG_OFFSET_SMI_L1ARB1 (0x208) +#define REG_OFFSET_SMI_L1ARB2 (0x20C) +#define REG_OFFSET_SMI_L1ARB3 (0x210) +#define REG_OFFSET_SMI_L1ARB4 (0x214) +#elif defined MT73 +#define REG_OFFSET_SMI_L1LEN (0x200) +#define REG_OFFSET_SMI_L1ARB0 (0x204) +#define REG_OFFSET_SMI_L1ARB1 (0x208) +#define REG_OFFSET_SMI_L1ARB2 (0x20C) +#define REG_OFFSET_SMI_L1ARB3 (0x210) +#define REG_OFFSET_SMI_L1ARB4 (0x214) +#define REG_OFFSET_SMI_L1ARB5 (0x218) +#else +#define REG_OFFSET_SMI_L1LEN (0x100) +#define REG_OFFSET_SMI_L1ARB0 (0x104) +#define REG_OFFSET_SMI_L1ARB1 (0x108) +#define REG_OFFSET_SMI_L1ARB2 (0x10C) +#define REG_OFFSET_SMI_L1ARB3 (0x110) +#define REG_OFFSET_SMI_L1ARB4 (0x114) +#endif + +/* +#define REG_SMI_MON_AXI_ENA (0x1a0+SMI_COMMON_EXT_BASE) +#define REG_SMI_MON_AXI_CLR (0x1a4+SMI_COMMON_EXT_BASE) +#define REG_SMI_MON_AXI_TYPE (0x1ac+SMI_COMMON_EXT_BASE) +#define REG_SMI_MON_AXI_CON (0x1b0+SMI_COMMON_EXT_BASE) +#define REG_SMI_MON_AXI_ACT_CNT (0x1c0+SMI_COMMON_EXT_BASE) +#define REG_SMI_MON_AXI_REQ_CNT (0x1c4+SMI_COMMON_EXT_BASE) +#define REG_SMI_MON_AXI_OSTD_CNT (0x1c8+SMI_COMMON_EXT_BASE) +#define REG_SMI_MON_AXI_BEA_CNT (0x1cc+SMI_COMMON_EXT_BASE) +#define REG_SMI_MON_AXI_BYT_CNT (0x1d0+SMI_COMMON_EXT_BASE) +#define REG_SMI_MON_AXI_CP_CNT (0x1d4+SMI_COMMON_EXT_BASE) +#define REG_SMI_MON_AXI_DP_CNT (0x1d8+SMI_COMMON_EXT_BASE) +#define REG_SMI_MON_AXI_CP_MAX (0x1dc+SMI_COMMON_EXT_BASE) +#define REG_SMI_MON_AXI_COS_MAX (0x1e0+SMI_COMMON_EXT_BASE) +#define REG_SMI_L1LEN (0x200+SMI_COMMON_EXT_BASE) +#define REG_SMI_L1ARB0 (0x204+SMI_COMMON_EXT_BASE) +#define REG_SMI_L1ARB1 (0x208+SMI_COMMON_EXT_BASE) +#define REG_SMI_L1ARB2 (0x20C+SMI_COMMON_EXT_BASE) +#define REG_SMI_L1ARB3 (0x210+SMI_COMMON_EXT_BASE) +#define REG_SMI_L1ARB4 (0x214+SMI_COMMON_EXT_BASE) +#define REG_SMI_BUS_SEL (0x220+SMI_COMMON_EXT_BASE) + #define F_SMI_BUS_SEL_larb0(mmu_idx) F_VAL(mmu_idx, 1, 0) + #define F_SMI_BUS_SEL_larb1(mmu_idx) F_VAL(mmu_idx, 3, 2) + #define F_SMI_BUS_SEL_larb2(mmu_idx) F_VAL(mmu_idx, 5, 4) + #define F_SMI_BUS_SEL_larb3(mmu_idx) F_VAL(mmu_idx, 7, 6) + #define F_SMI_BUS_SEL_larb4(mmu_idx) F_VAL(mmu_idx, 9, 8) +#define REG_SMI_WRR_REG0 (0x228+SMI_COMMON_EXT_BASE) +#define REG_SMI_READ_FIFO_TH (0x230+SMI_COMMON_EXT_BASE) +#define REG_SMI_SMI_M4U_TH (0x234+SMI_COMMON_EXT_BASE) +#define REG_SMI_SMI_FIFO2_TH (0x238+SMI_COMMON_EXT_BASE) +#define REG_SMI_SMI_PREULTRA_MASK0 (0x23c+SMI_COMMON_EXT_BASE) +#define REG_SMI_SMI_PREULTRA_MASK1 (0x240+SMI_COMMON_EXT_BASE) +#define REG_SMI_DCM (0x300+SMI_COMMON_EXT_BASE) +#define REG_SMI_SMI_ELA (0x304+SMI_COMMON_EXT_BASE) +#define REG_SMI_DEBUG0 (0x400+SMI_COMMON_EXT_BASE) +#define REG_SMI_DEBUG1 (0x404+SMI_COMMON_EXT_BASE) +#define REG_SMI_DEBUG2 (0x408+SMI_COMMON_EXT_BASE) +#define REG_SMI_DUMMY (0x418+SMI_COMMON_EXT_BASE) + +*/ + +#define REG_SMI_M4U_TH (0x234 + SMI_COMMON_EXT_BASE) +#define REG_SMI_L1LEN (0x200 + SMI_COMMON_EXT_BASE) +#define REG_SMI_L1ARB0 (0x204 + SMI_COMMON_EXT_BASE) +#define REG_SMI_L1ARB1 (0x208 + SMI_COMMON_EXT_BASE) +#define REG_SMI_L1ARB2 (0x20C + SMI_COMMON_EXT_BASE) +#define REG_SMI_WRR_REG0 (0x228 + SMI_COMMON_EXT_BASE) +#define REG_SMI_READ_FIFO_TH (0x230 + SMI_COMMON_EXT_BASE) + + +/* ========================================================================= */ +/* peripheral system */ +/* ========================================================================= */ +#define REG_PERIAXI_BUS_CTL3 (0x208+0xf0003000) +#define F_PERI_MMU_EN(port, en) ((en)<<((port))) + + +static inline unsigned int M4U_ReadReg32(unsigned long M4uBase, unsigned long Offset) +{ + unsigned int val; + + val = ioread32((void *)(M4uBase + Offset)); + + return val; +} + +static inline void M4U_WriteReg32(unsigned long M4uBase, unsigned long Offset, unsigned int Val) +{ + /* unsigned int read; */ + iowrite32(Val, (void *)(M4uBase + Offset)); + /* make sure memory manipulation sequence is OK */ + mb(); + +} + +static inline unsigned int COM_ReadReg32(unsigned long addr) +{ + return ioread32((void *)addr); +} + +static inline void COM_WriteReg32(unsigned long addr, unsigned int Val) +{ + iowrite32(Val, (void *)addr); + /* make sure memory manipulation sequence is OK */ + mb(); +} + + +extern unsigned long smi_reg_base_common_ext; +extern unsigned long smi_reg_base_barb0; +extern unsigned long smi_reg_base_barb1; +#if defined D2 +extern unsigned long smi_reg_base_barb2; +#elif defined D1 || defined D3 +extern unsigned long smi_reg_base_barb2; +extern unsigned long smi_reg_base_barb3; +#endif + +#endif diff --git a/drivers/misc/mediatek/smi/variant/smi_variant.c b/drivers/misc/mediatek/smi/variant/smi_variant.c new file mode 100644 index 000000000..f9adae4bd --- /dev/null +++ b/drivers/misc/mediatek/smi/variant/smi_variant.c @@ -0,0 +1,1760 @@ +#include <linux/of.h> +#include <linux/of_irq.h> +#include <linux/of_address.h> +#include <linux/kobject.h> + +#include <linux/uaccess.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/cdev.h> +#include <linux/mm.h> +#include <linux/vmalloc.h> +#include <linux/slab.h> +#include <linux/clk.h> +#include <linux/io.h> + +#include <linux/ioctl.h> +#include <linux/fs.h> +#include <linux/pm_runtime.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/of_platform.h> + +#if IS_ENABLED(CONFIG_COMPAT) +#include <linux/uaccess.h> +#include <linux/compat.h> +#endif + +#include "mt_smi.h" + +#include "smi_reg.h" +#include "smi_common.h" +#include "smi_debug.h" + +#include "smi_priv.h" +#include "m4u.h" + +/*#include "mmdvfs_mgr.h"*/ + +#define SMI_LOG_TAG "SMI" + +#define LARB_BACKUP_REG_SIZE 128 +#ifdef MT73 +#define SMI_COMMON_BACKUP_REG_NUM 10 + +/* SMI COMMON register list to be backuped */ +static unsigned short g_smi_common_backup_reg_offset[SMI_COMMON_BACKUP_REG_NUM] = { + 0x200, 0x204, 0x208, 0x20c, 0x210, 0x214, 0x220, 0x230, 0x234, 0x238 +}; + +#elif defined MT27 +/* + * MT8127 do not have the following register, offset(0x220, 0x238), + * which are SMI_BUS_SEL and SMI_FIFO2_TH, so do not backup them. + */ +#define SMI_COMMON_BACKUP_REG_NUM 8 + +static unsigned short g_smi_common_backup_reg_offset[SMI_COMMON_BACKUP_REG_NUM] = { + 0x200, 0x204, 0x208, 0x20c, 0x210, 0x214, 0x230, 0x234 +}; + +#endif + +#define SF_HWC_PIXEL_MAX_NORMAL (2560 * 1600 * 7) +#define SF_HWC_PIXEL_MAX_VR (2560 * 1600 * 7) +#define SF_HWC_PIXEL_MAX_VP (2560 * 1600 * 7) +#define SF_HWC_PIXEL_MAX_ALWAYS_GPU (2560 * 1600 * 1) + +#define SMIDBG(level, x...) \ + do { if (smi_debug_level >= (level))\ + SMIMSG(x);\ + } while (0) + +struct SMI_struct { + spinlock_t SMI_lock; + /*one bit represent one module */ + unsigned int pu4ConcurrencyTable[SMI_BWC_SCEN_CNT]; +}; + +static struct SMI_struct g_SMIInfo; + +static struct device *smiDeviceUevent; + +static bool fglarbcallback; /*larb backuprestore */ + +struct mtk_smi_data *smi_data; + +static struct cdev *pSmiDev; + +static unsigned int g_smi_common_backup[SMI_COMMON_BACKUP_REG_NUM]; + +/* To keep the HW's init value*/ +static bool is_default_value_saved; +static unsigned int default_val_smi_l1arb[SMI_LARB_NR] = { 0 }; + +static unsigned int wifi_disp_transaction; + +/* debug level */ +static unsigned int smi_debug_level; + +/* tuning mode, 1 for register ioctl */ +static unsigned int smi_tuning_mode; + +static unsigned int smi_profile = SMI_BWC_SCEN_NORMAL; + +static unsigned int *pLarbRegBackUp[SMI_LARB_NR]; +static int g_bInited; + +static MTK_SMI_BWC_MM_INFO g_smi_bwc_mm_info = { 0, 0, {0, 0}, {0, 0}, +{0, 0}, {0, 0}, 0, 0, 0, +SF_HWC_PIXEL_MAX_NORMAL +}; + +struct mtk_smi_common { + void __iomem *base; + struct clk *clk_apb; + struct clk *clk_smi; +}; +struct mtk_smi_larb { + void __iomem *base; + struct clk *clk_apb; + struct clk *clk_smi; + struct device *smi; +}; + +static void smi_dumpLarb(unsigned int index); +static void smi_dumpCommon(void); +static int _mtk_smi_larb_get(struct device *larbdev, bool pm); +static void _mtk_smi_larb_put(struct device *larbdev, bool pm); + +#if IS_ENABLED(CONFIG_COMPAT) +static long MTK_SMI_COMPAT_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +#else +#define MTK_SMI_COMPAT_ioctl NULL +#endif + +/* Use this function to get base address of Larb resgister +* to support error checking +*/ +static unsigned long get_larb_base_addr(int larb_id) +{ + if (larb_id >= SMI_LARB_NR || larb_id < 0 || !smi_data) + return SMI_ERROR_ADDR; + else + return smi_data->larb_base[larb_id]; +} + +unsigned long mtk_smi_larb_get_base(int larbid) +{ + return get_larb_base_addr(larbid); +} + +static unsigned int smi_get_larb_index(struct device *dev) +{ + unsigned int idx; + + for (idx = 0; idx < smi_data->larb_nr; idx++) { + if (smi_data->larb[idx] == dev) + break; + } + return idx; +} + +int mtk_smi_larb_clock_on(int larbid, bool pm) +{ + if (!smi_data || larbid < 0 || larbid >= smi_data->larb_nr) + return -EINVAL; + + return _mtk_smi_larb_get(smi_data->larb[larbid], pm); +} + +void mtk_smi_larb_clock_off(int larbid, bool pm) +{ + if (!smi_data || larbid < 0 || larbid >= smi_data->larb_nr) + return; + + _mtk_smi_larb_put(smi_data->larb[larbid], pm); +} + +static void backup_smi_common(void) +{ + int i; + + for (i = 0; i < SMI_COMMON_BACKUP_REG_NUM; i++) { + g_smi_common_backup[i] = + M4U_ReadReg32(SMI_COMMON_EXT_BASE, + (unsigned long)g_smi_common_backup_reg_offset[i]); + } +} + +static void restore_smi_common(void) +{ + int i; + + for (i = 0; i < SMI_COMMON_BACKUP_REG_NUM; i++) { + M4U_WriteReg32(SMI_COMMON_EXT_BASE, + (unsigned long)g_smi_common_backup_reg_offset[i], + g_smi_common_backup[i]); + } +} + +static void backup_larb_smi(int index) +{ + int port_index = 0; + unsigned short int *backup_ptr = NULL; + unsigned long larb_base = get_larb_base_addr(index); + unsigned long larb_offset = 0x200; + int total_port_num = 0; + + /* boundary check for larb_port_num and larb_port_backup access */ + if (index < 0 || index >= SMI_LARB_NR) + return; + + total_port_num = smi_data->smi_priv->larb_port_num[index]; + backup_ptr = smi_data->larb_port_backup + index*SMI_LARB_PORT_NR_MAX; + + /* boundary check for port value access */ + if (total_port_num <= 0 || backup_ptr == NULL) + return; + + for (port_index = 0; port_index < total_port_num; port_index++) { + *backup_ptr = (unsigned short int)(M4U_ReadReg32(larb_base, larb_offset)); + backup_ptr++; + larb_offset += 4; + } + + /* backup smi common along with larb0, + * smi common clk is guaranteed to be on when processing larbs */ + if (index == 0) + backup_smi_common(); + +} + + +static void restore_larb_smi(int index) +{ + int port_index = 0; + unsigned short int *backup_ptr = NULL; + unsigned long larb_base = get_larb_base_addr(index); + unsigned long larb_offset = 0x200; + unsigned int backup_value = 0; + int total_port_num = 0; + + /* boundary check for larb_port_num and larb_port_backup access */ + if (index < 0 || index >= SMI_LARB_NR) + return; + + total_port_num = smi_data->smi_priv->larb_port_num[index]; + backup_ptr = smi_data->larb_port_backup + index*SMI_LARB_PORT_NR_MAX; + + /* boundary check for port value access */ + if (total_port_num <= 0 || backup_ptr == NULL) + return; + + /* restore smi common along with larb0, + * smi common clk is guaranteed to be on when processing larbs */ + if (index == 0) + restore_smi_common(); + + for (port_index = 0; port_index < total_port_num; port_index++) { + backup_value = *backup_ptr; + M4U_WriteReg32(larb_base, larb_offset, backup_value); + backup_ptr++; + larb_offset += 4; + } + +#ifndef MT27 + /* we do not backup 0x20 because it is a fixed setting */ + M4U_WriteReg32(larb_base, 0x20, smi_data->smi_priv->larb_vc_setting[index]); +#endif + /* turn off EMI empty OSTD dobule, fixed setting */ + M4U_WriteReg32(larb_base, 0x2c, 4); + +} + +static int larb_reg_backup(int larb) +{ + unsigned int *pReg = pLarbRegBackUp[larb]; + unsigned long larb_base = get_larb_base_addr(larb); + + *(pReg++) = M4U_ReadReg32(larb_base, SMI_LARB_CON); + + /* *(pReg++) = M4U_ReadReg32(larb_base, SMI_SHARE_EN); */ + /* *(pReg++) = M4U_ReadReg32(larb_base, SMI_ROUTE_SEL); */ + + backup_larb_smi(larb); + + if (0 == larb) + g_bInited = 0; +#ifndef MT27 + m4u_larb_backup_sec(larb); +#endif + return 0; +} + +static int smi_larb_init(unsigned int larb) +{ + unsigned int regval = 0; + unsigned int regval1 = 0; + unsigned int regval2 = 0; + unsigned long larb_base = get_larb_base_addr(larb); + + /* Clock manager enable LARB clock before call back restore already, + *it will be disabled after restore call back returns + * Got to enable OSTD before engine starts */ + regval = M4U_ReadReg32(larb_base, SMI_LARB_STAT); + + /*todo */ + /* regval1 = M4U_ReadReg32(larb_base , SMI_LARB_MON_BUS_REQ0); */ + /* regval2 = M4U_ReadReg32(larb_base , SMI_LARB_MON_BUS_REQ1); */ + + if (0 == regval) { + SMIDBG(1, "Init OSTD for larb_base: 0x%lx\n", larb_base); + M4U_WriteReg32(larb_base, SMI_LARB_OSTDL_SOFT_EN, 0xffffffff); + } else { + SMIMSG("Larb: 0x%lx is busy : 0x%x , port:0x%x,0x%x ,fail to set OSTD\n", larb_base, + regval, regval1, regval2); + smi_dumpDebugMsg(); + if (smi_debug_level >= 1) { + SMIERR("DISP_MDP LARB 0x%lx OSTD cannot be set:0x%x,port:0x%x,0x%x\n", + larb_base, regval, regval1, regval2); + } else { + dump_stack(); + } + } + + restore_larb_smi(larb); + + return 0; +} + +int larb_reg_restore(int larb) +{ + unsigned long larb_base = SMI_ERROR_ADDR; + unsigned int regval = 0; + unsigned int *pReg = NULL; + + larb_base = get_larb_base_addr(larb); + + /* The larb assign doesn't exist */ + if (larb_base == SMI_ERROR_ADDR) { + SMIMSG("Can't find the base address for Larb%d\n", larb); + return 0; + } + + pReg = pLarbRegBackUp[larb]; + + SMIDBG(1, "+larb_reg_restore(), larb_idx=%d\n", larb); + SMIDBG(1, "m4u part restore, larb_idx=%d\n", larb); + /*warning: larb_con is controlled by set/clr */ + regval = *(pReg++); + M4U_WriteReg32(larb_base, SMI_LARB_CON_CLR, ~(regval)); + M4U_WriteReg32(larb_base, SMI_LARB_CON_SET, (regval)); + + /*M4U_WriteReg32(larb_base, SMI_SHARE_EN, *(pReg++) ); */ + /*M4U_WriteReg32(larb_base, SMI_ROUTE_SEL, *(pReg++) ); */ + + smi_larb_init(larb); +#ifndef MT27 + m4u_larb_restore_sec(larb); +#endif + return 0; +} + +/* Fake mode check, e.g. WFD */ +static int fake_mode_handling(MTK_SMI_BWC_CONFIG *p_conf, unsigned int *pu4LocalCnt) +{ + if (p_conf->scenario == SMI_BWC_SCEN_WFD) { + if (p_conf->b_on_off) { + wifi_disp_transaction = 1; + SMIMSG("Enable WFD in profile: %d\n", smi_profile); + } else { + wifi_disp_transaction = 0; + SMIMSG("Disable WFD in profile: %d\n", smi_profile); + } + return 1; + } else { + return 0; + } +} + +static int ovl_limit_uevent(int bwc_scenario, int ovl_pixel_limit) +{ + int err = 0; + char *envp[3]; + char scenario_buf[32] = ""; + char ovl_limit_buf[32] = ""; + + /* scenario_buf = kzalloc(sizeof(char)*128, GFP_KERNEL); */ + /* ovl_limit_buf = kzalloc(sizeof(char)*128, GFP_KERNEL); */ + + snprintf(scenario_buf, 31, "SCEN=%d", bwc_scenario); + snprintf(ovl_limit_buf, 31, "HWOVL=%d", ovl_pixel_limit); + + envp[0] = scenario_buf; + envp[1] = ovl_limit_buf; + envp[2] = NULL; + + if (pSmiDev != NULL) { + /* err = kobject_uevent_env(&(pSmiDev->kobj), KOBJ_CHANGE, envp); */ + /* use smi_data->dev.lobj instead */ + /* err = kobject_uevent_env(&(smi_data->dev->kobj), KOBJ_CHANGE, envp); */ + /* user smiDeviceUevent->kobj instead */ + err = kobject_uevent_env(&(smiDeviceUevent->kobj), KOBJ_CHANGE, envp); + SMIMSG("Notify OVL limitaion=%d, SCEN=%d", ovl_pixel_limit, bwc_scenario); + } + /* kfree(scenario_buf); */ + /* kfree(ovl_limit_buf); */ + + if (err < 0) + SMIMSG(KERN_INFO "[%s] kobject_uevent_env error = %d\n", __func__, err); + + return err; +} + +static int smi_bwc_config(MTK_SMI_BWC_CONFIG *p_conf, unsigned int *pu4LocalCnt) +{ + int i; + int result = 0; + unsigned int u4Concurrency = 0; + MTK_SMI_BWC_SCEN eFinalScen; + static MTK_SMI_BWC_SCEN ePreviousFinalScen = SMI_BWC_SCEN_CNT; + struct mtk_smi_priv *smicur = (struct mtk_smi_priv *)smi_data->smi_priv; + + if (smi_tuning_mode == 1) { + SMIMSG("Doesn't change profile in tunning mode"); + return 0; + } + + spin_lock(&g_SMIInfo.SMI_lock); + result = fake_mode_handling(p_conf, pu4LocalCnt); + spin_unlock(&g_SMIInfo.SMI_lock); + + /* Fake mode is not a real SMI profile, so we need to return here */ + if (result == 1) + return 0; + + if ((SMI_BWC_SCEN_CNT <= p_conf->scenario) || (0 > p_conf->scenario)) { + SMIERR("Incorrect SMI BWC config : 0x%x, how could this be...\n", p_conf->scenario); + return -1; + } +/* Debug - S */ +/* SMIMSG("SMI setTo%d,%s,%d\n" , p_conf->scenario , (p_conf->b_on_off ? "on" : "off") , ePreviousFinalScen); */ +/* Debug - E */ +#if 0 + if (p_conf->b_on_off) { + /* set mmdvfs step according to certain scenarios */ + mmdvfs_notify_scenario_enter(p_conf->scenario); + } else { + /* set mmdvfs step to default after the scenario exits */ + mmdvfs_notify_scenario_exit(p_conf->scenario); + } +#endif + /* turn on larb clock */ + for (i = 0; i < SMI_LARB_NR; i++) + mtk_smi_larb_clock_on(i, true); + + spin_lock(&g_SMIInfo.SMI_lock); + + if (p_conf->b_on_off) { + /* turn on certain scenario */ + g_SMIInfo.pu4ConcurrencyTable[p_conf->scenario] += 1; + + if (NULL != pu4LocalCnt) + pu4LocalCnt[p_conf->scenario] += 1; + } else { + /* turn off certain scenario */ + if (0 == g_SMIInfo.pu4ConcurrencyTable[p_conf->scenario]) { + SMIMSG("Too many turning off for global SMI profile:%d,%d\n", + p_conf->scenario, g_SMIInfo.pu4ConcurrencyTable[p_conf->scenario]); + } else { + g_SMIInfo.pu4ConcurrencyTable[p_conf->scenario] -= 1; + } + + if (NULL != pu4LocalCnt) { + if (0 == pu4LocalCnt[p_conf->scenario]) { + SMIMSG + ("Process : %s did too many turning off for local SMI profile:%d,%d\n", + current->comm, p_conf->scenario, + pu4LocalCnt[p_conf->scenario]); + } else { + pu4LocalCnt[p_conf->scenario] -= 1; + } + } + } + + for (i = 0; i < SMI_BWC_SCEN_CNT; i++) { + if (g_SMIInfo.pu4ConcurrencyTable[i]) + u4Concurrency |= (1 << i); + } + + if ((1 << SMI_BWC_SCEN_MM_GPU) & u4Concurrency) + eFinalScen = SMI_BWC_SCEN_MM_GPU; + else if ((1 << SMI_BWC_SCEN_VR_SLOW) & u4Concurrency) + eFinalScen = SMI_BWC_SCEN_VR_SLOW; + else if ((1 << SMI_BWC_SCEN_VR) & u4Concurrency) + eFinalScen = SMI_BWC_SCEN_VR; + else if ((1 << SMI_BWC_SCEN_ICFP) & u4Concurrency) + eFinalScen = SMI_BWC_SCEN_VR; + else if ((1 << SMI_BWC_SCEN_VP) & u4Concurrency) + eFinalScen = SMI_BWC_SCEN_VP; + else if ((1 << SMI_BWC_SCEN_SWDEC_VP) & u4Concurrency) + eFinalScen = SMI_BWC_SCEN_SWDEC_VP; + else if ((1 << SMI_BWC_SCEN_VENC) & u4Concurrency) + eFinalScen = SMI_BWC_SCEN_VENC; + else if ((1 << SMI_BWC_SCEN_HDMI) & u4Concurrency) + eFinalScen = SMI_BWC_SCEN_HDMI; + else if ((1 << SMI_BWC_SCEN_HDMI4K) & u4Concurrency) + eFinalScen = SMI_BWC_SCEN_HDMI4K; + else + eFinalScen = SMI_BWC_SCEN_NORMAL; + + if (ePreviousFinalScen == eFinalScen) { + SMIMSG("Scen equal%d,don't change\n", eFinalScen); + goto err_clkoff; + } else { + ePreviousFinalScen = eFinalScen; + } + + smi_profile = eFinalScen; + + /* Bandwidth Limiter */ + switch (eFinalScen) { + case SMI_BWC_SCEN_VP: + SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_VP"); + smicur->vp_setting(smi_data); + g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_VP; + break; + + case SMI_BWC_SCEN_SWDEC_VP: + SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_SWDEC_VP"); + smicur->vp_setting(smi_data); + g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_VP; + break; + + case SMI_BWC_SCEN_VR: + SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_VR"); + smicur->vr_setting(smi_data); + g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_VR; + break; + + case SMI_BWC_SCEN_VR_SLOW: + SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_VR"); + smi_profile = SMI_BWC_SCEN_VR_SLOW; + smicur->vr_setting(smi_data); + g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_VR; + break; + + case SMI_BWC_SCEN_VENC: + SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_VENC"); + smicur->vr_setting(smi_data); + g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; + break; + + case SMI_BWC_SCEN_NORMAL: + SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_NORMAL"); + g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; + smicur->init_setting(smi_data, &is_default_value_saved, + default_val_smi_l1arb, smi_data->larb_nr); + break; + + case SMI_BWC_SCEN_MM_GPU: + SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_MM_GPU"); + g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; + smicur->init_setting(smi_data, &is_default_value_saved, + default_val_smi_l1arb, smi_data->larb_nr); + break; + + case SMI_BWC_SCEN_HDMI: + SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_HDMI"); + g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; + smicur->hdmi_setting(smi_data); + break; + + case SMI_BWC_SCEN_HDMI4K: + SMIMSG("[SMI_PROFILE] : %s\n", "SMI_BWC_SCEN_HDMI4K"); + g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; + smicur->hdmi_4k_setting(smi_data); + break; + + default: + SMIMSG("[SMI_PROFILE] : %s %d\n", "initSetting", eFinalScen); + smicur->init_setting(smi_data, &is_default_value_saved, + default_val_smi_l1arb, smi_data->larb_nr); + g_smi_bwc_mm_info.hw_ovl_limit = SF_HWC_PIXEL_MAX_NORMAL; + break; + } + + spin_unlock(&g_SMIInfo.SMI_lock); + + /*turn off larb clock */ + for (i = 0; i < SMI_LARB_NR; i++) + mtk_smi_larb_clock_off(i, true); + + /* Since send uevent may trigger sleeping, we must send the event after releasing spin lock */ + ovl_limit_uevent(smi_profile, g_smi_bwc_mm_info.hw_ovl_limit); +#ifndef MT27 + /* force 30 fps in VR slow motion, because disp driver set fps apis got mutex, + * call these APIs only when necessary */ + { + static unsigned int current_fps; + + if ((eFinalScen == SMI_BWC_SCEN_VR_SLOW) && (current_fps != 30)) { + /* force 30 fps in VR slow motion profile */ + primary_display_force_set_vsync_fps(30); + current_fps = 30; + SMIMSG("[SMI_PROFILE] set 30 fps\n"); + } else if ((eFinalScen != SMI_BWC_SCEN_VR_SLOW) && (current_fps == 30)) { + /* back to normal fps */ + current_fps = primary_display_get_fps(); + primary_display_force_set_vsync_fps(current_fps); + SMIMSG("[SMI_PROFILE] back to %u fps\n", current_fps); + } + } +#endif + SMIMSG("SMI_PROFILE to:%d %s,cur:%d,%d,%d,%d\n", p_conf->scenario, + (p_conf->b_on_off ? "on" : "off"), eFinalScen, + g_SMIInfo.pu4ConcurrencyTable[SMI_BWC_SCEN_NORMAL], + g_SMIInfo.pu4ConcurrencyTable[SMI_BWC_SCEN_VR], + g_SMIInfo.pu4ConcurrencyTable[SMI_BWC_SCEN_VP]); + + return 0; + +/* Debug usage - S */ +/* smi_dumpDebugMsg(); */ +/* SMIMSG("Config:%d,%d,%d\n" , eFinalScen , +*g_SMIInfo.pu4ConcurrencyTable[SMI_BWC_SCEN_NORMAL] , +*(NULL == pu4LocalCnt ? (-1) : pu4LocalCnt[p_conf->scenario])); */ +/* Debug usage - E */ + +err_clkoff: + spin_unlock(&g_SMIInfo.SMI_lock); + + /*turn off larb clock */ + for (i = 0; i < SMI_LARB_NR; i++) + mtk_smi_larb_clock_off(i, true); + return 0; +} + +/* +const struct dev_pm_ops mtk_smi_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(smiclk_subsys_before_off, smiclk_subsys_after_on) +};*/ + +int smi_common_init(void) +{ + int i; + + for (i = 0; i < SMI_LARB_NR; i++) { + pLarbRegBackUp[i] = kmalloc(LARB_BACKUP_REG_SIZE, GFP_KERNEL | __GFP_ZERO); + if (pLarbRegBackUp[i] == NULL) + SMIERR("pLarbRegBackUp kmalloc fail %d\n", i); + } + + for (i = 0; i < smi_data->larb_nr; i++) + mtk_smi_larb_clock_on(i, true); + + /* apply init setting after kernel boot */ + smi_data->smi_priv->init_setting(smi_data, &is_default_value_saved, + default_val_smi_l1arb, smi_data->larb_nr); + + + fglarbcallback = true; + + for (i = smi_data->larb_nr; i >= 0; i--) + mtk_smi_larb_clock_off(i, true); + + return 0; +} + +static int smi_open(struct inode *inode, struct file *file) +{ + file->private_data = kmalloc_array(SMI_BWC_SCEN_CNT, sizeof(unsigned int), GFP_ATOMIC); + + if (NULL == file->private_data) { + SMIMSG("Not enough entry for DDP open operation\n"); + return -ENOMEM; + } + + memset(file->private_data, 0, SMI_BWC_SCEN_CNT * sizeof(unsigned int)); + + return 0; +} + +static int smi_release(struct inode *inode, struct file *file) +{ + if (NULL != file->private_data) { + kfree(file->private_data); + file->private_data = NULL; + } + + return 0; +} + +/* GMP start */ + +void smi_bwc_mm_info_set(int property_id, long val1, long val2) +{ + + switch (property_id) { + case SMI_BWC_INFO_CON_PROFILE: + g_smi_bwc_mm_info.concurrent_profile = (int)val1; + break; + case SMI_BWC_INFO_SENSOR_SIZE: + g_smi_bwc_mm_info.sensor_size[0] = val1; + g_smi_bwc_mm_info.sensor_size[1] = val2; + break; + case SMI_BWC_INFO_VIDEO_RECORD_SIZE: + g_smi_bwc_mm_info.video_record_size[0] = val1; + g_smi_bwc_mm_info.video_record_size[1] = val2; + break; + case SMI_BWC_INFO_DISP_SIZE: + g_smi_bwc_mm_info.display_size[0] = val1; + g_smi_bwc_mm_info.display_size[1] = val2; + break; + case SMI_BWC_INFO_TV_OUT_SIZE: + g_smi_bwc_mm_info.tv_out_size[0] = val1; + g_smi_bwc_mm_info.tv_out_size[1] = val2; + break; + case SMI_BWC_INFO_FPS: + g_smi_bwc_mm_info.fps = (int)val1; + break; + case SMI_BWC_INFO_VIDEO_ENCODE_CODEC: + g_smi_bwc_mm_info.video_encode_codec = (int)val1; + break; + case SMI_BWC_INFO_VIDEO_DECODE_CODEC: + g_smi_bwc_mm_info.video_decode_codec = (int)val1; + break; + } +} + +/* GMP end */ + + + +static long smi_ioctl(struct file *pFile, unsigned int cmd, unsigned long param) +{ + int ret = 0; +/* unsigned long * pu4Cnt = (unsigned long *)pFile->private_data; */ + + switch (cmd) { + + case MTK_IOC_SMI_BWC_CONFIG: + { + MTK_SMI_BWC_CONFIG cfg; + + ret = copy_from_user(&cfg, (void *)param, sizeof(MTK_SMI_BWC_CONFIG)); + if (ret) { + SMIMSG(" SMI_BWC_CONFIG, copy_from_user failed: %d\n", ret); + return -EFAULT; + } + + ret = smi_bwc_config(&cfg, NULL); + } + break; + /* GMP start */ + case MTK_IOC_SMI_BWC_INFO_SET: + { + MTK_SMI_BWC_INFO_SET cfg; + /* SMIMSG("Handle MTK_IOC_SMI_BWC_INFO_SET request... start"); */ + ret = copy_from_user(&cfg, (void *)param, sizeof(MTK_SMI_BWC_INFO_SET)); + if (ret) { + SMIMSG(" MTK_IOC_SMI_BWC_INFO_SET, copy_to_user failed: %d\n", ret); + return -EFAULT; + } + /* Set the address to the value assigned by user space program */ + smi_bwc_mm_info_set(cfg.property, cfg.value1, cfg.value2); + /* SMIMSG("Handle MTK_IOC_SMI_BWC_INFO_SET request... finish"); */ + break; + } + case MTK_IOC_SMI_BWC_INFO_GET: + { + ret = copy_to_user((void *)param, (void *)&g_smi_bwc_mm_info, + sizeof(MTK_SMI_BWC_MM_INFO)); + + if (ret) { + SMIMSG(" MTK_IOC_SMI_BWC_INFO_GET, copy_to_user failed: %d\n", ret); + return -EFAULT; + } + /* SMIMSG("Handle MTK_IOC_SMI_BWC_INFO_GET request... finish"); */ + break; + } + /* GMP end */ + + case MTK_IOC_SMI_DUMP_LARB: + { + unsigned int larb_index; + + ret = copy_from_user(&larb_index, (void *)param, sizeof(unsigned int)); + if (ret) + return -EFAULT; + + smi_dumpLarb(larb_index); + } + break; + + case MTK_IOC_SMI_DUMP_COMMON: + { + unsigned int arg; + + ret = copy_from_user(&arg, (void *)param, sizeof(unsigned int)); + if (ret) + return -EFAULT; + + smi_dumpCommon(); + } + break; + + /*case MTK_IOC_MMDVFS_CMD: + { + MTK_MMDVFS_CMD mmdvfs_cmd; + + if (copy_from_user(&mmdvfs_cmd, (void *)param, sizeof(MTK_MMDVFS_CMD))) + return -EFAULT; + + mmdvfs_handle_cmd(&mmdvfs_cmd); + + if (copy_to_user + ((void *)param, (void *)&mmdvfs_cmd, sizeof(MTK_MMDVFS_CMD))) + return -EFAULT; + + break; + }*/ + default: + return -1; + } + + return ret; +} + +static const struct file_operations smiFops = { + .owner = THIS_MODULE, + .open = smi_open, + .release = smi_release, + .unlocked_ioctl = smi_ioctl, + .compat_ioctl = MTK_SMI_COMPAT_ioctl +}; + +static dev_t smiDevNo = MKDEV(MTK_SMI_MAJOR_NUMBER, 0); +static inline int smi_register(void) +{ + if (alloc_chrdev_region(&smiDevNo, 0, 1, "MTK_SMI")) { + SMIERR("Allocate device No. failed"); + return -EAGAIN; + } + /* Allocate driver */ + pSmiDev = cdev_alloc(); + + if (NULL == pSmiDev) { + unregister_chrdev_region(smiDevNo, 1); + SMIERR("Allocate mem for kobject failed"); + return -ENOMEM; + } + /* Attatch file operation. */ + cdev_init(pSmiDev, &smiFops); + pSmiDev->owner = THIS_MODULE; + + /* Add to system */ + if (cdev_add(pSmiDev, smiDevNo, 1)) { + SMIERR("Attatch file operation failed"); + unregister_chrdev_region(smiDevNo, 1); + return -EAGAIN; + } + + return 0; +} + +static struct class *pSmiClass; +static int smi_dev_register(void) +{ + int ret; + struct device *smiDevice = NULL; + + if (smi_register()) { + pr_err("register SMI failed\n"); + return -EAGAIN; + } + + pSmiClass = class_create(THIS_MODULE, "MTK_SMI"); + if (IS_ERR(pSmiClass)) { + ret = PTR_ERR(pSmiClass); + SMIERR("Unable to create class, err = %d", ret); + return ret; + } + + smiDevice = device_create(pSmiClass, NULL, smiDevNo, NULL, "MTK_SMI"); + smiDeviceUevent = smiDevice; + + return 0; +} + +static int mtk_smi_common_get(struct device *smidev, bool pm) +{ + struct mtk_smi_common *smipriv = dev_get_drvdata(smidev); + int ret; + + if (pm) { + ret = pm_runtime_get_sync(smidev); + if (ret < 0) + return ret; + } + + ret = clk_prepare_enable(smipriv->clk_apb); + if (ret) { + dev_err(smidev, "Failed to enable the apb clock\n"); + goto err_put_pm; + } + ret = clk_prepare_enable(smipriv->clk_smi); + if (ret) { + dev_err(smidev, "Failed to enable the smi clock\n"); + goto err_disable_apb; + } + return ret; + +err_disable_apb: + clk_disable_unprepare(smipriv->clk_apb); +err_put_pm: + if (pm) + pm_runtime_put_sync(smidev); + return ret; +} + +static void mtk_smi_common_put(struct device *smidev, bool pm) +{ + struct mtk_smi_common *smipriv = dev_get_drvdata(smidev); + + if (pm) + pm_runtime_put_sync(smidev); + clk_disable_unprepare(smipriv->clk_smi); + clk_disable_unprepare(smipriv->clk_apb); +} + +static int _mtk_smi_larb_get(struct device *larbdev, bool pm) +{ + struct mtk_smi_larb *larbpriv = dev_get_drvdata(larbdev); + int ret; + + ret = mtk_smi_common_get(larbpriv->smi, pm); + if (ret) + return ret; + + if (pm) { + ret = pm_runtime_get_sync(larbdev); + if (ret < 0) + goto err_put_smicommon; + } + + ret = clk_prepare_enable(larbpriv->clk_apb); + if (ret) { + dev_err(larbdev, "Failed to enable the apb clock\n"); + goto err_put_pm; + } + + ret = clk_prepare_enable(larbpriv->clk_smi); + if (ret) { + dev_err(larbdev, "Failed to enable the smi clock\n"); + goto err_disable_apb; + } + + return ret; + +err_disable_apb: + clk_disable_unprepare(larbpriv->clk_apb); +err_put_pm: + if (pm) + pm_runtime_put_sync(larbdev); +err_put_smicommon: + mtk_smi_common_put(larbpriv->smi, pm); + return ret; +} + +static void _mtk_smi_larb_put(struct device *larbdev, bool pm) +{ + struct mtk_smi_larb *larbpriv = dev_get_drvdata(larbdev); + + clk_disable_unprepare(larbpriv->clk_smi); + clk_disable_unprepare(larbpriv->clk_apb); + if (pm) + pm_runtime_put_sync(larbdev); + mtk_smi_common_put(larbpriv->smi, pm); +} + +/* The power is alway on during power-domain callback.*/ +static int mtk_smi_larb_runtime_suspend(struct device *dev) +{ + unsigned int idx = smi_get_larb_index(dev); + int ret; + + if (!fglarbcallback) + return 0; + if (idx >= SMI_LARB_NR) + return 0; + + ret = _mtk_smi_larb_get(dev, false); + if (ret) { + dev_warn(dev, "runtime suspend clk-warn larb%d\n", idx); + return 0; + } + + larb_reg_backup(idx); + + _mtk_smi_larb_put(dev, false); + dev_dbg(dev, "runtime suspend larb%d\n", idx); + return 0; +} + +static int mtk_smi_larb_runtime_resume(struct device *dev) +{ + unsigned int idx = smi_get_larb_index(dev); + int ret; + + if (!fglarbcallback) + return 0; + if (idx >= SMI_LARB_NR) + return 0; + + ret = _mtk_smi_larb_get(dev, false); + if (ret) { + dev_warn(dev, "runtime resume clk-warn larb%d\n", idx); + return 0; + } + + larb_reg_restore(idx); + + _mtk_smi_larb_put(dev, false); + dev_dbg(dev, "runtime resume larb%d\n", idx); + return 0; +} + +/* modify this to avoid build error when runtime_pm not configured */ +static const struct dev_pm_ops mtk_smi_larb_ops = { + .runtime_suspend = mtk_smi_larb_runtime_suspend, + .runtime_resume = mtk_smi_larb_runtime_resume, +}; + +static int mtk_smi_larb_probe(struct platform_device *pdev) +{ + struct mtk_smi_larb *larbpriv; + struct resource *res; + struct device *dev = &pdev->dev; + struct device_node *smi_node; + struct platform_device *smi_pdev; + int ret, larbid; + + if (!dev->pm_domain) + return -EPROBE_DEFER; + + larbpriv = devm_kzalloc(dev, sizeof(*larbpriv), GFP_KERNEL); + if (!larbpriv) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + larbpriv->base = devm_ioremap_resource(dev, res); + if (IS_ERR(larbpriv->base)) + return PTR_ERR(larbpriv->base); + + larbpriv->clk_apb = devm_clk_get(dev, "apb"); + if (IS_ERR(larbpriv->clk_apb)) + return PTR_ERR(larbpriv->clk_apb); + + larbpriv->clk_smi = devm_clk_get(dev, "smi"); + if (IS_ERR(larbpriv->clk_smi)) + return PTR_ERR(larbpriv->clk_smi); + + smi_node = of_parse_phandle(dev->of_node, "mediatek,smi", 0); + if (!smi_node) + return -EINVAL; + + ret = of_property_read_u32(dev->of_node, "mediatek,larbid", &larbid); + if (ret) + return ret; + + smi_pdev = of_find_device_by_node(smi_node); + of_node_put(smi_node); + if (smi_pdev) { + larbpriv->smi = &smi_pdev->dev; + } else { + dev_err(dev, "Failed to get the smi_common device\n"); + return -EINVAL; + } + + smi_data->larb_base[larbid] = (unsigned long)larbpriv->base; + smi_data->larb[larbid] = dev; + smi_data->larb_nr++; + + SMIMSG("larb %d-cnt %d probe done\n", larbid, smi_data->larb_nr); + + pm_runtime_enable(dev); + dev_set_drvdata(dev, larbpriv); + return 0; +} + +static int mtk_smi_larb_remove(struct platform_device *pdev) +{ + pm_runtime_disable(&pdev->dev); + return 0; +} + +static const struct of_device_id mtk_smi_larb_of_ids[] = { + { .compatible = "mediatek,mt8173-smi-larb", }, + { .compatible = "mediatek,mt8127-smi-larb", }, + {} +}; + +static struct platform_driver mtk_smi_larb_driver = { + .probe = mtk_smi_larb_probe, + .remove = mtk_smi_larb_remove, + .driver = { + .name = "mtk-smi-larb", + .of_match_table = mtk_smi_larb_of_ids, +#ifdef CONFIG_PM + .pm = &mtk_smi_larb_ops, +#endif + } +}; + +static int mtk_smi_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct mtk_smi_common *smipriv; + struct resource *res; + + if (!dev->pm_domain) + return -EPROBE_DEFER; + + smipriv = devm_kzalloc(dev, sizeof(*smipriv), GFP_KERNEL); + if (!smipriv) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + smipriv->base = devm_ioremap_resource(dev, res); + if (IS_ERR(smipriv->base)) + return PTR_ERR(smipriv->base); + + smipriv->clk_apb = devm_clk_get(dev, "apb"); + if (IS_ERR(smipriv->clk_apb)) + return PTR_ERR(smipriv->clk_apb); + + smipriv->clk_smi = devm_clk_get(dev, "smi"); + if (IS_ERR(smipriv->clk_smi)) + return PTR_ERR(smipriv->clk_smi); + + smi_data->smicommon = dev; + smi_data->smi_common_base = (unsigned long)smipriv->base; + + pm_runtime_enable(dev); + dev_set_drvdata(dev, smipriv); + return 0; +} + +static int mtk_smi_remove(struct platform_device *pdev) +{ + pm_runtime_disable(&pdev->dev); + return 0; +} + +static const struct of_device_id mtk_smi_of_ids[] = { + { .compatible = "mediatek,mt8173-smi",}, + { .compatible = "mediatek,mt8127-smi",}, + {} +}; + +static struct platform_driver mtk_smi_driver = { + .probe = mtk_smi_probe, + .remove = mtk_smi_remove, + .driver = { + .name = "mtk-smi", + .of_match_table = mtk_smi_of_ids, + } +}; + +static int __init smi_init(void) +{ + int ret; + + smi_data = kzalloc(sizeof(*smi_data), GFP_KERNEL); + if (smi_data == NULL) { + SMIERR("Unable to allocate memory for smi driver"); + return -ENOMEM; + } + + ret = platform_driver_register(&mtk_smi_driver); + if (ret != 0) { + pr_err("Failed to register SMI driver\n"); + return ret; + } + + ret = platform_driver_register(&mtk_smi_larb_driver); + if (ret != 0) { + pr_err("Failed to register SMI-LARB driver\n"); + return ret; + } + + ret = smi_dev_register(); + if (ret) { + SMIMSG("register dev/smi failed\n"); + return ret; + } + + memset(g_SMIInfo.pu4ConcurrencyTable, 0, SMI_BWC_SCEN_CNT * sizeof(unsigned int)); + spin_lock_init(&g_SMIInfo.SMI_lock); + + SMI_DBG_Init(); + + #if defined MT73 + smi_data->smi_priv = &smi_mt8173_priv; + #elif defined MT27 + smi_data->smi_priv = &smi_mt8127_priv; + #endif + + SMIMSG("smi_init done\n"); + + return 0; +} + +static void __exit smi_exit(void) +{ + platform_driver_unregister(&mtk_smi_driver); + platform_driver_unregister(&mtk_smi_larb_driver); +} + +static int __init smi_init_late(void) +{ + /*init clk/mtcmos should be late while ccf */ + SMIMSG("smi_init_late-\n"); + + smi_common_init(); + + return 0; +} + +static void smi_dumpCommonDebugMsg(void) +{ + unsigned long u4Base; + + /* SMI COMMON dump */ + SMIMSG("===SMI common reg dump===\n"); + + u4Base = SMI_COMMON_EXT_BASE; + SMIMSG("[0x200,0x204,0x208]=[0x%x,0x%x,0x%x]\n", M4U_ReadReg32(u4Base, 0x200), + M4U_ReadReg32(u4Base, 0x204), M4U_ReadReg32(u4Base, 0x208)); + SMIMSG("[0x20C,0x210,0x214]=[0x%x,0x%x,0x%x]\n", M4U_ReadReg32(u4Base, 0x20C), + M4U_ReadReg32(u4Base, 0x210), M4U_ReadReg32(u4Base, 0x214)); + #ifdef MT73 + SMIMSG("[0x220,0x230,0x234,0x238]=[0x%x,0x%x,0x%x,0x%x]\n", M4U_ReadReg32(u4Base, 0x220), + M4U_ReadReg32(u4Base, 0x230), M4U_ReadReg32(u4Base, 0x234), M4U_ReadReg32(u4Base, + 0x238)); + SMIMSG("[0x400,0x404,0x408]=[0x%x,0x%x,0x%x]\n", M4U_ReadReg32(u4Base, 0x400), + M4U_ReadReg32(u4Base, 0x404), M4U_ReadReg32(u4Base, 0x408)); + + #elif defined MT27 + + SMIMSG("[0x218,0x230,0x234,0x238]=[0x%x,0x%x,0x%x,0x%x]\n", M4U_ReadReg32(u4Base, 0x218), + M4U_ReadReg32(u4Base, 0x230), M4U_ReadReg32(u4Base, 0x234), M4U_ReadReg32(u4Base, + 0x238)); + SMIMSG("[0x400,0x404,]=[0x%x,0x%x]\n", M4U_ReadReg32(u4Base, 0x400), + M4U_ReadReg32(u4Base, 0x404)); + + #endif + + /* TBD: M4U should dump these, the offset of MT27 have been checked and same with the followings. */ +/* + For VA and PA check: + 0x1000C5C0 , 0x1000C5C4, 0x1000C5C8, 0x1000C5CC, 0x1000C5D0 + u4Base = SMI_COMMON_AO_BASE; + SMIMSG("===SMI always on reg dump===\n"); + SMIMSG("[0x5C0,0x5C4,0x5C8]=[0x%x,0x%x,0x%x]\n" , + M4U_ReadReg32(u4Base , 0x5C0),M4U_ReadReg32(u4Base , 0x5C4), + M4U_ReadReg32(u4Base , 0x5C8)); + SMIMSG("[0x5CC,0x5D0]=[0x%x,0x%x]\n" ,M4U_ReadReg32(u4Base , 0x5CC), + M4U_ReadReg32(u4Base , 0x5D0)); +*/ +} + +static void smi_dumpLarbDebugMsg(unsigned int u4Index) +{ + unsigned long u4Base; + + u4Base = get_larb_base_addr(u4Index); + + if (u4Base == SMI_ERROR_ADDR) { + SMIMSG("Doesn't support reg dump for Larb%d\n", u4Index); + } else { + SMIMSG("===SMI LARB%d reg dump===\n", u4Index); + + #ifdef MT73 + SMIMSG("[0x0,0x8,0x10]=[0x%x,0x%x,0x%x]\n", M4U_ReadReg32(u4Base, 0x0), + M4U_ReadReg32(u4Base, 0x8), M4U_ReadReg32(u4Base, 0x10)); + SMIMSG("[0x24,0x50,0x60]=[0x%x,0x%x,0x%x]\n", M4U_ReadReg32(u4Base, 0x24), + M4U_ReadReg32(u4Base, 0x50), M4U_ReadReg32(u4Base, 0x60)); + SMIMSG("[0xa0,0xa4,0xa8]=[0x%x,0x%x,0x%x]\n", M4U_ReadReg32(u4Base, 0xa0), + M4U_ReadReg32(u4Base, 0xa4), M4U_ReadReg32(u4Base, 0xa8)); + SMIMSG("[0xac,0xb0,0xb4]=[0x%x,0x%x,0x%x]\n", M4U_ReadReg32(u4Base, 0xac), + M4U_ReadReg32(u4Base, 0xb0), M4U_ReadReg32(u4Base, 0xb4)); + SMIMSG("[0xb8,0xbc,0xc0]=[0x%x,0x%x,0x%x]\n", M4U_ReadReg32(u4Base, 0xb8), + M4U_ReadReg32(u4Base, 0xbc), M4U_ReadReg32(u4Base, 0xc0)); + SMIMSG("[0xc8,0xcc]=[0x%x,0x%x]\n", M4U_ReadReg32(u4Base, 0xc8), + M4U_ReadReg32(u4Base, 0xcc)); + #elif defined MT27 + { + unsigned int u4Offset = 0; + + SMIMSG("[0x0,0x10,0x60]=[0x%x,0x%x,0x%x]\n", M4U_ReadReg32(u4Base, 0x0), + M4U_ReadReg32(u4Base, 0x10), M4U_ReadReg32(u4Base, 0x60)); + SMIMSG("[0x64,0x8c,0x450]=[0x%x,0x%x,0x%x]\n", M4U_ReadReg32(u4Base, 0x64), + M4U_ReadReg32(u4Base, 0x8c), M4U_ReadReg32(u4Base, 0x450)); + SMIMSG("[0x454,0x600,0x604]=[0x%x,0x%x,0x%x]\n", M4U_ReadReg32(u4Base, 0x454), + M4U_ReadReg32(u4Base, 0x600), M4U_ReadReg32(u4Base, 0x604)); + SMIMSG("[0x610,0x614]=[0x%x,0x%x]\n", M4U_ReadReg32(u4Base, 0x610), + M4U_ReadReg32(u4Base, 0x614)); + + for (u4Offset = 0x200; u4Offset < 0x200 + SMI_LARB_NR * 4; u4Offset += 4) + SMIMSG("[0x%x = 0x%x ]\n", u4Offset, M4U_ReadReg32(u4Base , u4Offset)); + } + #endif + } +} + +static void smi_dump_format(unsigned long base, unsigned int from, unsigned int to) +{ + int i, j, left; + unsigned int value[8]; + + for (i = from; i <= to; i += 32) { + for (j = 0; j < 8; j++) + value[j] = M4U_ReadReg32(base, i + j * 4); + + SMIMSG2("%8x %x %x %x %x %x %x %x %x\n", i, value[0], value[1], value[2], value[3], + value[4], value[5], value[6], value[7]); + } + + left = ((from - to) / 4 + 1) % 8; + + if (left) { + memset(value, 0, 8 * sizeof(unsigned int)); + + for (j = 0; j < left; j++) + value[j] = M4U_ReadReg32(base, i - 32 + j * 4); + + SMIMSG2("%8x %x %x %x %x %x %x %x %x\n", i - 32 + j * 4, value[0], value[1], + value[2], value[3], value[4], value[5], value[6], value[7]); + } +} + +static void smi_dumpLarb(unsigned int index) +{ + unsigned long u4Base; + + u4Base = get_larb_base_addr(index); + + if (u4Base == SMI_ERROR_ADDR) { + SMIMSG2("Doesn't support reg dump for Larb%d\n", index); + + } else { + SMIMSG2("===SMI LARB%d reg dump base 0x%lx===\n", index, u4Base); + + smi_dump_format(u4Base, 0, 0x434); + smi_dump_format(u4Base, 0xF00, 0xF0C); + } +} + +static void smi_dumpCommon(void) +{ + SMIMSG2("===SMI COMMON reg dump base 0x%lx===\n", SMI_COMMON_EXT_BASE); + + smi_dump_format(SMI_COMMON_EXT_BASE, 0x1A0, 0x418); +} + +void smi_dumpDebugMsg(void) +{ + unsigned int u4Index; + + /* SMI COMMON dump */ + smi_dumpCommonDebugMsg(); + + /* dump all SMI LARB */ + for (u4Index = 0; u4Index < SMI_LARB_NR; u4Index++) + smi_dumpLarbDebugMsg(u4Index); +} + +int smi_debug_bus_hanging_detect(unsigned int larbs, int show_dump) +{ +#ifdef CONFIG_MTK_SMI_EXT + int i = 0; + int dump_time = 0; + int is_smi_issue = 0; + int status_code = 0; + /* Keep the dump result */ + unsigned char smi_common_busy_count = 0; + /*volatile */ unsigned int reg_temp = 0; + unsigned char smi_larb_busy_count[SMI_LARB_NR] = { 0 }; + unsigned char smi_larb_mmu_status[SMI_LARB_NR] = { 0 }; + + /* dump resister and save resgister status */ + for (dump_time = 0; dump_time < 5; dump_time++) { + unsigned int u4Index = 0; + + reg_temp = M4U_ReadReg32(SMI_COMMON_EXT_BASE, 0x400); + if ((reg_temp & (1 << 30)) == 0) { + /* smi common is busy */ + smi_common_busy_count++; + } + /* Dump smi common regs */ + if (show_dump != 0) + smi_dumpCommonDebugMsg(); + + for (u4Index = 0; u4Index < SMI_LARB_NR; u4Index++) { + unsigned long u4Base = get_larb_base_addr(u4Index); + + if (u4Base != SMI_ERROR_ADDR) { + reg_temp = M4U_ReadReg32(u4Base, 0x0); + if (reg_temp != 0) { + /* Larb is busy */ + smi_larb_busy_count[u4Index]++; + } + smi_larb_mmu_status[u4Index] = M4U_ReadReg32(u4Base, 0xa0); + if (show_dump != 0) + smi_dumpLarbDebugMsg(u4Index); + } + } + + } + + /* Show the checked result */ + for (i = 0; i < SMI_LARB_NR; i++) { /* Check each larb */ + if (SMI_DGB_LARB_SELECT(larbs, i)) { + /* larb i has been selected */ + /* Get status code */ + + if (smi_larb_busy_count[i] == 5) { /* The larb is always busy */ + if (smi_common_busy_count == 5) { /* smi common is always busy */ + status_code = 1; + } else if (smi_common_busy_count == 0) { /* smi common is always idle */ + status_code = 2; + } else { + status_code = 5; /* smi common is sometimes busy and idle */ + } + } else if (smi_larb_busy_count[i] == 0) { /* The larb is always idle */ + if (smi_common_busy_count == 5) { /* smi common is always busy */ + status_code = 3; + } else if (smi_common_busy_count == 0) { /* smi common is always idle */ + status_code = 4; + } else { + status_code = 6; /* smi common is sometimes busy and idle */ + } + } else { /* sometime the larb is busy */ + if (smi_common_busy_count == 5) { /* smi common is always busy */ + status_code = 7; + } else if (smi_common_busy_count == 0) { /* smi common is always idle */ + status_code = 8; + } else { + status_code = 9; /* smi common is sometimes busy and idle */ + } + } + + /* Send the debug message according to the final result */ + switch (status_code) { + case 1: + case 3: + case 5: + case 7: + case 8: + SMIMSG + ("Larb%d Busy=%d/5, SMI Common Busy=%d/5, status=%d ==> Check engine's state first", + i, smi_larb_busy_count[i], smi_common_busy_count, status_code); + SMIMSG + ("If the engine is waiting for Larb%ds' response, it needs SMI HW's check", + i); + break; + case 2: + if (smi_larb_mmu_status[i] == 0) { + SMIMSG("Larb%d Busy=%d/5, Common Busy=%d/5,status=%d=>Check engine state first", + i, smi_larb_busy_count[i], smi_common_busy_count, + status_code); + SMIMSG("If the engine is waiting for Larb%ds' response,it needs SMI HW's check", + i); + } else { + SMIMSG("Larb%d Busy=%d/5, Common Busy=%d/5, status=%d==>MMU port config error", + i, smi_larb_busy_count[i], smi_common_busy_count, + status_code); + is_smi_issue = 1; + } + break; + case 4: + case 6: + case 9: + SMIMSG + ("Larb%d Busy=%d/5, SMI Common Busy=%d/5, status=%d ==> not SMI issue", + i, smi_larb_busy_count[i], smi_common_busy_count, status_code); + break; + default: + SMIMSG + ("Larb%d Busy=%d/5, SMI Common Busy=%d/5, status=%d ==> status unknown", + i, smi_larb_busy_count[i], smi_common_busy_count, status_code); + break; + } + } + } + + return is_smi_issue; +#endif + return 0; +} + +#if IS_ENABLED(CONFIG_COMPAT) +/* 32 bits process ioctl support: */ +/* This is prepared for the future extension since currently the sizes of 32 bits */ +/* and 64 bits smi parameters are the same. */ + +typedef struct { + compat_int_t scenario; + compat_int_t b_on_off; /* 0 : exit this scenario , 1 : enter this scenario */ +} MTK_SMI_COMPAT_BWC_CONFIG; + +typedef struct { + compat_int_t property; + compat_int_t value1; + compat_int_t value2; +} MTK_SMI_COMPAT_BWC_INFO_SET; + +typedef struct { + compat_uint_t flag; /* Reserved */ + compat_int_t concurrent_profile; + compat_int_t sensor_size[2]; + compat_int_t video_record_size[2]; + compat_int_t display_size[2]; + compat_int_t tv_out_size[2]; + compat_int_t fps; + compat_int_t video_encode_codec; + compat_int_t video_decode_codec; + compat_int_t hw_ovl_limit; +} MTK_SMI_COMPAT_BWC_MM_INFO; + +#define COMPAT_MTK_IOC_SMI_BWC_CONFIG MTK_IOW(24, MTK_SMI_COMPAT_BWC_CONFIG) +#define COMPAT_MTK_IOC_SMI_BWC_INFO_SET MTK_IOWR(28, MTK_SMI_COMPAT_BWC_INFO_SET) +#define COMPAT_MTK_IOC_SMI_BWC_INFO_GET MTK_IOWR(29, MTK_SMI_COMPAT_BWC_MM_INFO) + +static int compat_get_smi_bwc_config_struct(MTK_SMI_COMPAT_BWC_CONFIG __user *data32, + MTK_SMI_BWC_CONFIG __user *data) +{ + + compat_int_t i; + int err; + + /* since the int sizes of 32 A32 and A64 are equal so we don't convert them actually here */ + err = get_user(i, &(data32->scenario)); + err |= put_user(i, &(data->scenario)); + err |= get_user(i, &(data32->b_on_off)); + err |= put_user(i, &(data->b_on_off)); + + return err; +} + +static int compat_get_smi_bwc_mm_info_set_struct(MTK_SMI_COMPAT_BWC_INFO_SET __user *data32, + MTK_SMI_BWC_INFO_SET __user *data) +{ + + compat_int_t i; + int err; + + /* since the int sizes of 32 A32 and A64 are equal so we don't convert them actually here */ + err = get_user(i, &(data32->property)); + err |= put_user(i, &(data->property)); + err |= get_user(i, &(data32->value1)); + err |= put_user(i, &(data->value1)); + err |= get_user(i, &(data32->value2)); + err |= put_user(i, &(data->value2)); + + return err; +} + +static int compat_get_smi_bwc_mm_info_struct(MTK_SMI_COMPAT_BWC_MM_INFO __user *data32, + MTK_SMI_BWC_MM_INFO __user *data) +{ + compat_uint_t u; + compat_int_t i; + compat_int_t p[2]; + int err; + + /* since the int sizes of 32 A32 and A64 are equal so we don't convert them actually here */ + err = get_user(u, &(data32->flag)); + err |= put_user(u, &(data->flag)); + err |= get_user(i, &(data32->concurrent_profile)); + err |= put_user(i, &(data->concurrent_profile)); + err |= copy_from_user(p, &(data32->sensor_size), sizeof(p)); + err |= copy_to_user(&(data->sensor_size), p, sizeof(p)); + err |= copy_from_user(p, &(data32->video_record_size), sizeof(p)); + err |= copy_to_user(&(data->video_record_size), p, sizeof(p)); + err |= copy_from_user(p, &(data32->display_size), sizeof(p)); + err |= copy_to_user(&(data->display_size), p, sizeof(p)); + err |= copy_from_user(p, &(data32->tv_out_size), sizeof(p)); + err |= copy_to_user(&(data->tv_out_size), p, sizeof(p)); + err |= get_user(i, &(data32->fps)); + err |= put_user(i, &(data->fps)); + err |= get_user(i, &(data32->video_encode_codec)); + err |= put_user(i, &(data->video_encode_codec)); + err |= get_user(i, &(data32->video_decode_codec)); + err |= put_user(i, &(data->video_decode_codec)); + err |= get_user(i, &(data32->hw_ovl_limit)); + err |= put_user(i, &(data->hw_ovl_limit)); + + + return err; +} + +static int compat_put_smi_bwc_mm_info_struct(MTK_SMI_COMPAT_BWC_MM_INFO __user *data32, + MTK_SMI_BWC_MM_INFO __user *data) +{ + + compat_uint_t u; + compat_int_t i; + compat_int_t p[2]; + int err; + + /* since the int sizes of 32 A32 and A64 are equal so we don't convert them actually here */ + err = get_user(u, &(data->flag)); + err |= put_user(u, &(data32->flag)); + err |= get_user(i, &(data->concurrent_profile)); + err |= put_user(i, &(data32->concurrent_profile)); + err |= copy_from_user(p, &(data->sensor_size), sizeof(p)); + err |= copy_to_user(&(data32->sensor_size), p, sizeof(p)); + err |= copy_from_user(p, &(data->video_record_size), sizeof(p)); + err |= copy_to_user(&(data32->video_record_size), p, sizeof(p)); + err |= copy_from_user(p, &(data->display_size), sizeof(p)); + err |= copy_to_user(&(data32->display_size), p, sizeof(p)); + err |= copy_from_user(p, &(data->tv_out_size), sizeof(p)); + err |= copy_to_user(&(data32->tv_out_size), p, sizeof(p)); + err |= get_user(i, &(data->fps)); + err |= put_user(i, &(data32->fps)); + err |= get_user(i, &(data->video_encode_codec)); + err |= put_user(i, &(data32->video_encode_codec)); + err |= get_user(i, &(data->video_decode_codec)); + err |= put_user(i, &(data32->video_decode_codec)); + err |= get_user(i, &(data->hw_ovl_limit)); + err |= put_user(i, &(data32->hw_ovl_limit)); + return err; +} + +long MTK_SMI_COMPAT_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + long ret; + + if (!filp->f_op || !filp->f_op->unlocked_ioctl) + return -ENOTTY; + + switch (cmd) { + case COMPAT_MTK_IOC_SMI_BWC_CONFIG: + { + if (COMPAT_MTK_IOC_SMI_BWC_CONFIG == MTK_IOC_SMI_BWC_CONFIG) { + SMIMSG("Optimized compct IOCTL: COMPAT_MTK_IOC_SMI_BWC_CONFIG"); + return filp->f_op->unlocked_ioctl(filp, cmd, + (unsigned long)compat_ptr(arg)); + } else { + + MTK_SMI_COMPAT_BWC_CONFIG __user *data32; + MTK_SMI_BWC_CONFIG __user *data; + int err; + + data32 = compat_ptr(arg); + data = compat_alloc_user_space(sizeof(MTK_SMI_BWC_CONFIG)); + + if (data == NULL) + return -EFAULT; + + err = compat_get_smi_bwc_config_struct(data32, data); + if (err) + return err; + + ret = filp->f_op->unlocked_ioctl(filp, MTK_IOC_SMI_BWC_CONFIG, + (unsigned long)data); + return ret; + } + } + + case COMPAT_MTK_IOC_SMI_BWC_INFO_SET: + { + + if (COMPAT_MTK_IOC_SMI_BWC_INFO_SET == MTK_IOC_SMI_BWC_INFO_SET) { + SMIMSG("Optimized compct IOCTL: COMPAT_MTK_IOC_SMI_BWC_INFO_SET"); + return filp->f_op->unlocked_ioctl(filp, cmd, + (unsigned long)compat_ptr(arg)); + } else { + + MTK_SMI_COMPAT_BWC_INFO_SET __user *data32; + MTK_SMI_BWC_INFO_SET __user *data; + int err; + + data32 = compat_ptr(arg); + data = compat_alloc_user_space(sizeof(MTK_SMI_BWC_INFO_SET)); + if (data == NULL) + return -EFAULT; + + err = compat_get_smi_bwc_mm_info_set_struct(data32, data); + if (err) + return err; + + return filp->f_op->unlocked_ioctl(filp, MTK_IOC_SMI_BWC_INFO_SET, + (unsigned long)data); + } + } + break; + + case COMPAT_MTK_IOC_SMI_BWC_INFO_GET: + { + if (COMPAT_MTK_IOC_SMI_BWC_INFO_GET == MTK_IOC_SMI_BWC_INFO_GET) { + SMIMSG("Optimized compct IOCTL: COMPAT_MTK_IOC_SMI_BWC_INFO_GET"); + return filp->f_op->unlocked_ioctl(filp, cmd, + (unsigned long)compat_ptr(arg)); + } else { + MTK_SMI_COMPAT_BWC_MM_INFO __user *data32; + MTK_SMI_BWC_MM_INFO __user *data; + int err; + + data32 = compat_ptr(arg); + data = compat_alloc_user_space(sizeof(MTK_SMI_BWC_MM_INFO)); + + if (data == NULL) + return -EFAULT; + + err = compat_get_smi_bwc_mm_info_struct(data32, data); + if (err) + return err; + + ret = filp->f_op->unlocked_ioctl(filp, MTK_IOC_SMI_BWC_INFO_GET, + (unsigned long)data); + + err = compat_put_smi_bwc_mm_info_struct(data32, data); + + if (err) + return err; + + return ret; + } + } + break; + + case MTK_IOC_SMI_DUMP_LARB: + case MTK_IOC_SMI_DUMP_COMMON: + case MTK_IOC_MMDVFS_CMD: + + return filp->f_op->unlocked_ioctl(filp, cmd, (unsigned long)compat_ptr(arg)); + default: + return -ENOIOCTLCMD; + } + +} + +#endif + +module_init(smi_init); +module_exit(smi_exit); +late_initcall(smi_init_late); + +module_param_named(debug_level, smi_debug_level, uint, S_IRUGO | S_IWUSR); +module_param_named(tuning_mode, smi_tuning_mode, uint, S_IRUGO | S_IWUSR); +module_param_named(wifi_disp_transaction, wifi_disp_transaction, uint, S_IRUGO | S_IWUSR); + +MODULE_DESCRIPTION("MTK SMI driver"); +MODULE_AUTHOR("Glory Hung<glory.hung@mediatek.com>"); +MODULE_AUTHOR("Yong Wu<yong.wu@mediatek.com>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/misc/mediatek/smi/variant/smi_variant_config_8127.c b/drivers/misc/mediatek/smi/variant/smi_variant_config_8127.c new file mode 100644 index 000000000..6c333e8b1 --- /dev/null +++ b/drivers/misc/mediatek/smi/variant/smi_variant_config_8127.c @@ -0,0 +1,220 @@ +#include <linux/of.h> +#include <linux/of_irq.h> +#include <linux/of_address.h> +#include <linux/kobject.h> + +#include <linux/uaccess.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/cdev.h> +#include <linux/mm.h> +#include <linux/vmalloc.h> +#include <linux/slab.h> +#include <linux/clk.h> +#include <linux/io.h> +#include "smi_reg.h" +#include "smi_common.h" +#include "smi_priv.h" + +#define SMI_LARB0_PORT_NUM 10 +#define SMI_LARB1_PORT_NUM 7 +#define SMI_LARB2_PORT_NUM 17 + +static void initSetting(struct mtk_smi_data *smidev, bool *default_saved, + u32 *default_smi_val, unsigned int larbid) +{ + + + SMIMSG("Current Setting: GPU - new"); + if (!SMI_COMMON_EXT_BASE || !LARB0_BASE) { + SMIMSG("smi and smi_larb should have been probe first\n"); + return; + } + /* 2 non-ultra write, 3 write command , 4 non-ultra read , 5 ultra read */ + M4U_WriteReg32(REG_SMI_M4U_TH, 0, ((0x3 << 15) + (0x4 << 10) + (0x4 << 5) + 0x5)); + /* + * Level 1 LARB, apply new outstanding control method, 1/4 bandwidth + * limiter overshoot control , enable warb channel + */ + M4U_WriteReg32(REG_SMI_L1LEN, 0, 0xB); + /* + * total 8 commnads between smi common to M4U, 12 non ultra commands + * between smi common to M4U, 1 commnads can in write AXI slice for all LARBs + */ + M4U_WriteReg32(REG_SMI_READ_FIFO_TH, 0, ((0x7 << 11) + (0x8 << 6) + 0x3F)); + + M4U_WriteReg32(LARB0_BASE, 0x200, 0xC); /* DISP_OVL_0 */ + M4U_WriteReg32(LARB0_BASE, 0x204, 0x1); /* DISP_RDMA_1 */ + M4U_WriteReg32(LARB0_BASE, 0x208, 0x1); /* DISP_RDMA */ + M4U_WriteReg32(LARB0_BASE, 0x20C, 0x2); /* DISP_WDMA */ + M4U_WriteReg32(LARB0_BASE, 0x210, 0x1); /* MM_CMDQ */ + M4U_WriteReg32(LARB0_BASE, 0x214, 0x5); /* MDP_RDMA */ + M4U_WriteReg32(LARB0_BASE, 0x218, 0x1); /* MDP_WDMA */ + M4U_WriteReg32(LARB0_BASE, 0x21C, 0x3); /* MDP_ROT */ + M4U_WriteReg32(LARB0_BASE, 0x220, 0x1); /* MDP_ROTCO */ + M4U_WriteReg32(LARB0_BASE, 0x224, 0x1); /* MDP ROTVO */ + + M4U_WriteReg32(LARB1_BASE, 0x200, 0x1); /* HW_VDEC_MC_EXT */ + M4U_WriteReg32(LARB1_BASE, 0x204, 0x1); /* HW_VDEC_PP_EXT */ + M4U_WriteReg32(LARB1_BASE, 0x208, 0x1); /* HW_VDEC_AVC_MV-EXT */ + M4U_WriteReg32(LARB1_BASE, 0x20C, 0x1); /* HW_VDEC_PRED_RD_EXT */ + M4U_WriteReg32(LARB1_BASE, 0x210, 0x1); /* HW_VDEC_PRED_WR_EXT */ + M4U_WriteReg32(LARB1_BASE, 0x214, 0x1); /* HW_VDEC_VLD_EXT */ + M4U_WriteReg32(LARB1_BASE, 0x218, 0x1); /* HW_VDEC_PP_INT */ + + M4U_WriteReg32(LARB2_BASE, 0x200, 0x1); /* CAM_IMGO */ + M4U_WriteReg32(LARB2_BASE, 0x204, 0x1); /* CAM_IMG2O */ + M4U_WriteReg32(LARB2_BASE, 0x208, 0x1); /* CAM_LSCI */ + M4U_WriteReg32(LARB2_BASE, 0x20C, 0x1); /* CAM_IMGI */ + M4U_WriteReg32(LARB2_BASE, 0x210, 0x1); /* CAM_ESFKO */ + M4U_WriteReg32(LARB2_BASE, 0x214, 0x1); /* CAM_AAO */ + M4U_WriteReg32(LARB2_BASE, 0x218, 0x1); /* CAM_LCEI */ + M4U_WriteReg32(LARB2_BASE, 0x21C, 0x1); /* CAM_LCSO */ + M4U_WriteReg32(LARB2_BASE, 0x220, 0x1); /* JPGENC_RDMA */ + M4U_WriteReg32(LARB2_BASE, 0x224, 0x1); /* JPGENC_BSDMA */ + M4U_WriteReg32(LARB2_BASE, 0x228, 0x1); /* VENC_SV_COMV */ + M4U_WriteReg32(LARB2_BASE, 0x22C, 0x1); /* VENC_RD_COMV */ + M4U_WriteReg32(LARB2_BASE, 0x230, 0x1); /* VENC_RCPU */ + M4U_WriteReg32(LARB2_BASE, 0x234, 0x1); /* VENC_REC_FRM */ + M4U_WriteReg32(LARB2_BASE, 0x238, 0x1); /* VENC_REF_LUMA */ + M4U_WriteReg32(LARB2_BASE, 0x23C, 0x1); /* VENC_REF_CHROMA */ + M4U_WriteReg32(LARB2_BASE, 0x244, 0x1); /* VENC_BSDMA */ + M4U_WriteReg32(LARB2_BASE, 0x248, 0x1); /* VENC_CUR_LUMA */ + M4U_WriteReg32(LARB2_BASE, 0x24C, 0x1); /* VENC_CUR_CHROMA */ +} + +static void vpSetting(struct mtk_smi_data *smidev) +{ + /* 2 non-ultra write, 3 write command , 4 non-ultra read , 5 ultra read */ + M4U_WriteReg32(REG_SMI_M4U_TH, 0, ((0x2 << 15) + (0x3 << 10) + (0x4 << 5) + 0x5)); + /* + * Level 1 LARB, apply new outstanding control method, 1/4 bandwidth limiter + * overshoot control , enable warb channel + */ + M4U_WriteReg32(REG_SMI_L1LEN, 0, 0x1B); + /* + * total 8 commnads between smi common to M4U, 12 non ultra commands + * between smi common to M4U, 1 commnads can in write AXI slice for all LARBs + */ + M4U_WriteReg32(REG_SMI_READ_FIFO_TH, 0, 0x323F); + + M4U_WriteReg32(REG_SMI_L1ARB0, 0, 0xC3A); /* 1111/4096 maximum grant counts, soft limiter */ + M4U_WriteReg32(REG_SMI_L1ARB1, 0, 0x9E8); /* 503/4096 maximum grant counts, soft limiter */ + M4U_WriteReg32(REG_SMI_L1ARB2, 0, 0x943); /* 353/4096 maximum grant counts, soft limiter */ + + M4U_WriteReg32(LARB0_BASE, 0x200, 0xC); /* DISP_OVL_0 */ + M4U_WriteReg32(LARB0_BASE, 0x204, 0x1); /* DISP_RDMA_1 */ + M4U_WriteReg32(LARB0_BASE, 0x208, 0x1); /* DISP_RDMA */ + M4U_WriteReg32(LARB0_BASE, 0x20C, 0x2); /* DISP_WDMA */ + M4U_WriteReg32(LARB0_BASE, 0x210, 0x1); /* MM_CMDQ */ + M4U_WriteReg32(LARB0_BASE, 0x214, 0x5); /* MDP_RDMA */ + M4U_WriteReg32(LARB0_BASE, 0x218, 0x1); /* MDP_WDMA */ + M4U_WriteReg32(LARB0_BASE, 0x21C, 0x3); /* MDP_ROT */ + M4U_WriteReg32(LARB0_BASE, 0x220, 0x1); /* MDP_ROTCO */ + M4U_WriteReg32(LARB0_BASE, 0x224, 0x1); /* MDP ROTVO */ + + M4U_WriteReg32(LARB1_BASE, 0x200, 0x6); /* HW_VDEC_MC_EXT */ + M4U_WriteReg32(LARB1_BASE, 0x204, 0x2); /* HW_VDEC_PP_EXT */ + M4U_WriteReg32(LARB1_BASE, 0x208, 0x1); /* HW_VDEC_AVC_MV-EXT */ + M4U_WriteReg32(LARB1_BASE, 0x20C, 0x3); /* HW_VDEC_PRED_RD_EXT */ + M4U_WriteReg32(LARB1_BASE, 0x210, 0x3); /* HW_VDEC_PRED_WR_EXT */ + M4U_WriteReg32(LARB1_BASE, 0x214, 0x1); /* HW_VDEC_VLD_EXT */ + M4U_WriteReg32(LARB1_BASE, 0x218, 0x1); /* HW_VDEC_PP_INT */ + + M4U_WriteReg32(LARB2_BASE, 0x200, 0x1); /* CAM_IMGO */ + M4U_WriteReg32(LARB2_BASE, 0x204, 0x1); /* CAM_IMG2O */ + M4U_WriteReg32(LARB2_BASE, 0x208, 0x1); /* CAM_LSCI */ + M4U_WriteReg32(LARB2_BASE, 0x20C, 0x1); /* CAM_IMGI */ + M4U_WriteReg32(LARB2_BASE, 0x210, 0x1); /* CAM_ESFKO */ + M4U_WriteReg32(LARB2_BASE, 0x214, 0x1); /* CAM_AAO */ + M4U_WriteReg32(LARB2_BASE, 0x218, 0x1); /* CAM_LCEI */ + M4U_WriteReg32(LARB2_BASE, 0x21C, 0x1); /* CAM_LCSO */ + M4U_WriteReg32(LARB2_BASE, 0x220, 0x1); /* JPGENC_RDMA */ + M4U_WriteReg32(LARB2_BASE, 0x224, 0x1); /* JPGENC_BSDMA */ + M4U_WriteReg32(LARB2_BASE, 0x228, 0x1); /* VENC_SV_COMV */ + M4U_WriteReg32(LARB2_BASE, 0x22C, 0x1); /* VENC_RD_COMV */ + M4U_WriteReg32(LARB2_BASE, 0x230, 0x1); /* VENC_RCPU */ + M4U_WriteReg32(LARB2_BASE, 0x234, 0x1); /* VENC_REC_FRM */ + M4U_WriteReg32(LARB2_BASE, 0x238, 0x1); /* VENC_REF_LUMA */ + M4U_WriteReg32(LARB2_BASE, 0x23C, 0x1); /* VENC_REF_CHROMA */ + M4U_WriteReg32(LARB2_BASE, 0x244, 0x1); /* VENC_BSDMA */ + M4U_WriteReg32(LARB2_BASE, 0x248, 0x1); /* VENC_CUR_LUMA */ + M4U_WriteReg32(LARB2_BASE, 0x24C, 0x1); /* VENC_CUR_CHROMA */ + +} + +static void vrSetting(struct mtk_smi_data *smidev) +{ + /* 2 non-ultra write, 3 write command , 4 non-ultra read , 5 ultra read */ + M4U_WriteReg32(REG_SMI_M4U_TH, 0, ((0x2 << 15) + (0x3 << 10) + (0x4 << 5) + 0x5)); + /* + * Level 1 LARB, apply new outstanding control method, 1/4 bandwidth limiter + * overshoot control , enable warb channel + */ + M4U_WriteReg32(REG_SMI_L1LEN, 0, 0xB); + /* + * total 8 commnads between smi common to M4U, 12 non ultra commands between smi common + * to M4U, 1 commnads can in write AXI slice for all LARBs + */ + M4U_WriteReg32(REG_SMI_READ_FIFO_TH, 0, ((0x6 << 11) + (0x8 << 6) + 0x3F)); + + M4U_WriteReg32(REG_SMI_L1ARB0, 0, 0xC26); /* 1111/4096 maximum grant counts, soft limiter */ + M4U_WriteReg32(REG_SMI_L1ARB1, 0, 0x943); /* 503/4096 maximum grant counts, soft limiter */ + M4U_WriteReg32(REG_SMI_L1ARB2, 0, 0xD4F); /* 1359/4096 maximum grant counts, soft limiter */ + + M4U_WriteReg32(LARB0_BASE, 0x200, 0xC); /* DISP_OVL_0 */ + M4U_WriteReg32(LARB0_BASE, 0x204, 0x1); /* DISP_RDMA_1 */ + M4U_WriteReg32(LARB0_BASE, 0x208, 0x1); /* DISP_RDMA */ + M4U_WriteReg32(LARB0_BASE, 0x20C, 0x1); /* DISP_WDMA */ + M4U_WriteReg32(LARB0_BASE, 0x210, 0x1); /* MM_CMDQ */ + M4U_WriteReg32(LARB0_BASE, 0x214, 0x2); /* MDP_RDMA */ + M4U_WriteReg32(LARB0_BASE, 0x218, 0x2); /* MDP_WDMA */ + M4U_WriteReg32(LARB0_BASE, 0x21C, 0x4); /* MDP_ROT */ + M4U_WriteReg32(LARB0_BASE, 0x220, 0x2); /* MDP_ROTCO */ + M4U_WriteReg32(LARB0_BASE, 0x224, 0x2); /* MDP ROTVO */ + + M4U_WriteReg32(LARB1_BASE, 0x200, 0x1); /* HW_VDEC_MC_EXT */ + M4U_WriteReg32(LARB1_BASE, 0x204, 0x1); /* HW_VDEC_PP_EXT */ + M4U_WriteReg32(LARB1_BASE, 0x208, 0x1); /* HW_VDEC_AVC_MV-EXT */ + M4U_WriteReg32(LARB1_BASE, 0x20C, 0x1); /* HW_VDEC_PRED_RD_EXT */ + M4U_WriteReg32(LARB1_BASE, 0x210, 0x1); /* HW_VDEC_PRED_WR_EXT */ + M4U_WriteReg32(LARB1_BASE, 0x214, 0x1); /* HW_VDEC_VLD_EXT */ + M4U_WriteReg32(LARB1_BASE, 0x218, 0x1); /* HW_VDEC_PP_INT */ + + M4U_WriteReg32(LARB2_BASE, 0x200, 0x6); /* CAM_IMGO */ + M4U_WriteReg32(LARB2_BASE, 0x204, 0x1); /* CAM_IMG2O */ + M4U_WriteReg32(LARB2_BASE, 0x208, 0x1); /* CAM_LSCI */ + M4U_WriteReg32(LARB2_BASE, 0x20C, 0x4); /* CAM_IMGI */ + M4U_WriteReg32(LARB2_BASE, 0x210, 0x1); /* CAM_ESFKO */ + M4U_WriteReg32(LARB2_BASE, 0x214, 0x1); /* CAM_AAO */ + M4U_WriteReg32(LARB2_BASE, 0x218, 0x1); /* CAM_LCEI */ + M4U_WriteReg32(LARB2_BASE, 0x21C, 0x1); /* CAM_LCSO */ + M4U_WriteReg32(LARB2_BASE, 0x220, 0x1); /* JPGENC_RDMA */ + M4U_WriteReg32(LARB2_BASE, 0x224, 0x1); /* JPGENC_BSDMA */ + M4U_WriteReg32(LARB2_BASE, 0x228, 0x1); /* VENC_SV_COMV */ + M4U_WriteReg32(LARB2_BASE, 0x22C, 0x1); /* VENC_RD_COMV */ + M4U_WriteReg32(LARB2_BASE, 0x230, 0x1); /* VENC_RCPU */ + M4U_WriteReg32(LARB2_BASE, 0x234, 0x2); /* VENC_REC_FRM */ + M4U_WriteReg32(LARB2_BASE, 0x238, 0x4); /* VENC_REF_LUMA */ + M4U_WriteReg32(LARB2_BASE, 0x23C, 0x2); /* VENC_REF_CHROMA */ + M4U_WriteReg32(LARB2_BASE, 0x244, 0x1); /* VENC_BSDMA */ + M4U_WriteReg32(LARB2_BASE, 0x248, 0x2); /* VENC_CUR_LUMA */ + M4U_WriteReg32(LARB2_BASE, 0x24C, 0x1); /* VENC_CUR_CHROMA */ +} + +static void hdmiSetting(struct mtk_smi_data *smidev) +{ +} + +static void hdmi4kSetting(struct mtk_smi_data *smidev) +{ +} + +const struct mtk_smi_priv smi_mt8127_priv = { + .larb_port_num = { SMI_LARB0_PORT_NUM, SMI_LARB1_PORT_NUM, SMI_LARB2_PORT_NUM }, + .init_setting = initSetting, + .vp_setting = vpSetting, + .vr_setting = vrSetting, + .hdmi_setting = hdmiSetting, + .hdmi_4k_setting = hdmi4kSetting, +}; diff --git a/drivers/misc/mediatek/smi/variant/smi_variant_config_8173.c b/drivers/misc/mediatek/smi/variant/smi_variant_config_8173.c new file mode 100644 index 000000000..143830bde --- /dev/null +++ b/drivers/misc/mediatek/smi/variant/smi_variant_config_8173.c @@ -0,0 +1,258 @@ +#include <linux/of.h> +#include <linux/of_irq.h> +#include <linux/of_address.h> +#include <linux/kobject.h> + +#include <linux/uaccess.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/cdev.h> +#include <linux/mm.h> +#include <linux/vmalloc.h> +#include <linux/slab.h> +#include <linux/clk.h> +#include <linux/io.h> +#include "smi_reg.h" +#include "smi_common.h" +#include "smi_priv.h" + +static void initSetting(struct mtk_smi_data *smidev, bool *default_saved, + u32 *default_smi_val, unsigned int larbid) +{ + + /* save default larb regs */ + if (!(*default_saved)) { + SMIMSG("Save default config:\n"); + default_smi_val[0] = M4U_ReadReg32(SMI_COMMON_EXT_BASE, + REG_OFFSET_SMI_L1ARB0); + default_smi_val[1] = M4U_ReadReg32(SMI_COMMON_EXT_BASE, + REG_OFFSET_SMI_L1ARB1); + default_smi_val[2] = M4U_ReadReg32(SMI_COMMON_EXT_BASE, + REG_OFFSET_SMI_L1ARB2); + default_smi_val[3] = M4U_ReadReg32(SMI_COMMON_EXT_BASE, + REG_OFFSET_SMI_L1ARB3); + default_smi_val[4] = M4U_ReadReg32(SMI_COMMON_EXT_BASE, + REG_OFFSET_SMI_L1ARB4); + default_smi_val[5] = M4U_ReadReg32(SMI_COMMON_EXT_BASE, + REG_OFFSET_SMI_L1ARB5); + SMIMSG("l1arb[0-2]= 0x%x, 0x%x, 0x%x\n", default_smi_val[0], + default_smi_val[1], default_smi_val[2]); + SMIMSG("l1arb[3-4]= 0x%x, 0x%x 0x%x\n", default_smi_val[3], + default_smi_val[4], default_smi_val[5]); + + *default_saved = true; + } + /* Keep the HW's init setting in REG_SMI_L1ARB0 ~ REG_SMI_L1ARB4 */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB0, default_smi_val[0]); + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB1, default_smi_val[1]); + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB2, default_smi_val[2]); + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB3, default_smi_val[3]); + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB4, default_smi_val[4]); + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB5, default_smi_val[5]); + + M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x200, 0x1b); + /* disp(larb0+larb4): emi0, other:emi1 */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x220, (0x1<<0) | (0x1<<8)); + M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x234, + (0x1 << 31) + (0x13 << 26) + (0x14 << 21) + (0x0 << 20) + (0x2 << 15) + + (0x3 << 10) + (0x4 << 5) + 0x5); + M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x238, + (0x2 << 25) + (0x3 << 20) + (0x4 << 15) + (0x5 << 10) + (0x6 << 5) + 0x8); + M4U_WriteReg32(SMI_COMMON_EXT_BASE, 0x230, 0x1f + (0x8 << 5) + (0x6 << 10)); + + /* Set VC priority: MMSYS = ISP > VENC > VDEC = MJC */ + M4U_WriteReg32(LARB0_BASE, 0x20, 0x0); /* MMSYS */ + M4U_WriteReg32(LARB1_BASE, 0x20, 0x2); /* VDEC */ + M4U_WriteReg32(LARB2_BASE, 0x20, 0x0); /* ISP */ + M4U_WriteReg32(LARB3_BASE, 0x20, 0x1); /* VENC */ + M4U_WriteReg32(LARB4_BASE, 0x20, 0x0); /* DISP1 */ + M4U_WriteReg32(LARB5_BASE, 0x20, 0x1); /* VENC2 */ + + /* turn off EMI empty double OSTD */ + M4U_WriteReg32(LARB0_BASE, 0x2c, M4U_ReadReg32(LARB0_BASE, 0x2c) | (1 << 2)); + M4U_WriteReg32(LARB1_BASE, 0x2c, M4U_ReadReg32(LARB1_BASE, 0x2c) | (1 << 2)); + M4U_WriteReg32(LARB2_BASE, 0x2c, M4U_ReadReg32(LARB2_BASE, 0x2c) | (1 << 2)); + M4U_WriteReg32(LARB3_BASE, 0x2c, M4U_ReadReg32(LARB3_BASE, 0x2c) | (1 << 2)); + M4U_WriteReg32(LARB4_BASE, 0x2c, M4U_ReadReg32(LARB4_BASE, 0x2c) | (1 << 2)); + M4U_WriteReg32(LARB5_BASE, 0x2c, M4U_ReadReg32(LARB5_BASE, 0x2c) | (1 << 2)); + + /* confirm. sometimes the reg can not be wrote while its clock is disable */ + if ((M4U_ReadReg32(LARB1_BASE, 0x20) != 0x2) || + (M4U_ReadReg32(LARB0_BASE, 0x20) != 0x0)) { + SMIMSG("warning setting failed. please check clk. 0x%x-0x%x\n", + M4U_ReadReg32(LARB1_BASE , 0x20), + M4U_ReadReg32(LARB0_BASE , 0x20)); + } +} + +static void vpSetting(struct mtk_smi_data *smidev) +{ + /* VP 4K */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB0, 0x17C0); /* LARB0, DISP+MDP */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB1, 0x161B); /* LARB1, VDEC */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB2, 0x1000); /* LARB2, ISP */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB3, 0x1000); /* LARB3, VENC+JPG */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB4, 0x17C0); /* LARB4, DISP2+MDP2 */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB5, 0x1000); /* LARB5, VENC2 */ + + M4U_WriteReg32(LARB0_BASE, 0x200, 0x18); /* ovl_ch0_0/1 */ + M4U_WriteReg32(LARB0_BASE, 0x214, 0x4); /* mdp_rdma0; min(4,5) */ + M4U_WriteReg32(LARB0_BASE, 0x21c, 0x5); /* mdp_wrot0 */ + + M4U_WriteReg32(LARB4_BASE, 0x200, 0x8); /* ovl_ch1_0/1 */ + M4U_WriteReg32(LARB4_BASE, 0x210, 0x4); /* mdp_rdma1; min(4,5) */ + M4U_WriteReg32(LARB4_BASE, 0x214, 0x3); /* mdp_wrot1 */ + + M4U_WriteReg32(LARB1_BASE, 0x200, 0x1f); /* port#0, mc */ + M4U_WriteReg32(LARB1_BASE, 0x204, 0x06); /* port#1, pp */ + M4U_WriteReg32(LARB1_BASE, 0x208, 0x1); /* port#2, ufo */ + M4U_WriteReg32(LARB1_BASE, 0x20c, 0x1); /* port#3, vld */ + M4U_WriteReg32(LARB1_BASE, 0x210, 0x1); /* port#4, vld2 */ + M4U_WriteReg32(LARB1_BASE, 0x214, 0x2); /* port#5, mv */ + M4U_WriteReg32(LARB1_BASE, 0x218, 0x1); /* port#6, pred rd */ + M4U_WriteReg32(LARB1_BASE, 0x21c, 0x1); /* port#7, pred wr */ + M4U_WriteReg32(LARB1_BASE, 0x220, 0x1); /* port#8, ppwrap */ + +} + +static void vrSetting(struct mtk_smi_data *smidev) +{ + /* VR 4K */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB0, 0x1614); /* LARB0, DISP+MDP */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB1, 0x1000); /* LARB1, VDEC */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB2, 0x11F7); /* LARB2, ISP */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB3, 0x1584); /* LARB3, VENC+JPG */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB4, 0x1614); /* LARB4, DISP2+MDP2 */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB5, 0x1584); /* LARB5, VENC2 */ + + M4U_WriteReg32(LARB0_BASE, 0x200, 0x1f); /* ovl_ch0_0+ovl_ch0_1 */ + M4U_WriteReg32(LARB0_BASE, 0x218, 0x2); /* mdp_wdma */ + M4U_WriteReg32(LARB0_BASE, 0x21C, 0x5); /* mdp_wrot0; min(9,5) */ + + M4U_WriteReg32(LARB2_BASE, 0x200, 0x8); /* imgo */ + M4U_WriteReg32(LARB2_BASE, 0x208, 0x1); /* aao */ + M4U_WriteReg32(LARB2_BASE, 0x20c, 0x1); /* lsco */ + M4U_WriteReg32(LARB2_BASE, 0x210, 0x1); /* esfko */ + M4U_WriteReg32(LARB2_BASE, 0x218, 0x1); /* lsci */ + M4U_WriteReg32(LARB2_BASE, 0x220, 0x1); /* bpci */ + M4U_WriteReg32(LARB2_BASE, 0x22c, 0x4); /* imgi */ + M4U_WriteReg32(LARB2_BASE, 0x230, 0x1); /* img2o */ + M4U_WriteReg32(LARB2_BASE, 0x244, 0x1); /* lcei */ + + M4U_WriteReg32(LARB3_BASE, 0x200, 0x1); /* venc_rcpu */ + M4U_WriteReg32(LARB3_BASE, 0x204, 0x4); /* venc_rec_frm */ + M4U_WriteReg32(LARB3_BASE, 0x208, 0x1); /* venc_bsdma */ + M4U_WriteReg32(LARB3_BASE, 0x20c, 0x1); /* venc_sv_comv */ + M4U_WriteReg32(LARB3_BASE, 0x210, 0x1); /* venc_rd_comv */ + M4U_WriteReg32(LARB3_BASE, 0x224, 0x8); /* venc_cur_luma */ + M4U_WriteReg32(LARB3_BASE, 0x228, 0x4); /* venc_cur_chroma */ + M4U_WriteReg32(LARB3_BASE, 0x230, 0x10); /* venc_ref_chroma */ + + M4U_WriteReg32(LARB4_BASE, 0x200, 0x1f); /* ovl_ch1_0+ovl_ch1_1 */ + M4U_WriteReg32(LARB4_BASE, 0x218, 0x2); /* mdp_wdma */ + M4U_WriteReg32(LARB4_BASE, 0x21C, 0x5); /* mdp_wrot0; min(9,5) */ + + + /* VP concurrent settings */ + /* LARB0 */ + /*M4U_WriteReg32(LARB0_BASE, 0x210, 0x8); *//* port 4:ovl_ch1_0/1 */ + /*M4U_WriteReg32(LARB0_BASE, 0x21C, 0x4); *//* port 7:mdp_rdma0; min(4,5) */ + /*M4U_WriteReg32(LARB0_BASE, 0x22C, 0x3); *//* port11:mdp_wrot1 */ + + /* VDEC */ + M4U_WriteReg32(LARB1_BASE, 0x200, 0x1f); /* port#0, mc */ + M4U_WriteReg32(LARB1_BASE, 0x204, 0x06); /* port#1, pp */ + M4U_WriteReg32(LARB1_BASE, 0x208, 0x1); /* port#2, ufo */ + M4U_WriteReg32(LARB1_BASE, 0x20c, 0x1); /* port#3, vld */ + M4U_WriteReg32(LARB1_BASE, 0x210, 0x1); /* port#4, vld2 */ + M4U_WriteReg32(LARB1_BASE, 0x214, 0x2); /* port#5, avc mv */ + M4U_WriteReg32(LARB1_BASE, 0x218, 0x1); /* port#6, pred rd */ + M4U_WriteReg32(LARB1_BASE, 0x21c, 0x1); /* port#7, pred wr */ + M4U_WriteReg32(LARB1_BASE, 0x220, 0x1); /* port#8, ppwrap */ + + /*venc2 */ + M4U_WriteReg32(LARB5_BASE, 0x200, 0x1); /* venc_rcpu2 */ + M4U_WriteReg32(LARB5_BASE, 0x204, 0x4); /* venc_rec_frm2 */ + /* venc_ref_luma2 */ + M4U_WriteReg32(LARB5_BASE, 0x20c, 0x10); /* venc_ref_chroma2 */ + M4U_WriteReg32(LARB5_BASE, 0x210, 0x1); /* venc_bsdma2 */ + M4U_WriteReg32(LARB5_BASE, 0x214, 0x8); /* venc_cur_luma2 */ + M4U_WriteReg32(LARB5_BASE, 0x218, 0x4); /* venc_cur_chroma2 */ + M4U_WriteReg32(LARB5_BASE, 0x21c, 0x1); /* venc_rd_comv2 */ + M4U_WriteReg32(LARB5_BASE, 0x220, 0x1); /* venc_sv_comv2 */ + +} + + +static void hdmiSetting(struct mtk_smi_data *smidev) +{ + /* VP 4K */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB0, 0x1117); /* LARB0, DISP+MDP */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB1, 0x1659); /* LARB1, VDEC */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB2, 0x1000); /* LARB2, ISP */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB3, 0x1000); /* LARB3, VENC+JPG */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB4, 0x1750); /* LARB4, DISP2+MDP2 */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB5, 0x1000); /* LARB5, VENC2 */ + + M4U_WriteReg32(LARB0_BASE, 0x200, 0x18); /* ovl_ch0_0/1 */ + M4U_WriteReg32(LARB0_BASE, 0x214, 0x4); /* mdp_rdma0; min(4,5) */ + M4U_WriteReg32(LARB0_BASE, 0x21c, 0x5); /* mdp_wrot0 */ + + M4U_WriteReg32(LARB4_BASE, 0x200, 0x8); /* ovl_ch1_0/1 */ + M4U_WriteReg32(LARB4_BASE, 0x210, 0x4); /* mdp_rdma1; min(4,5) */ + M4U_WriteReg32(LARB4_BASE, 0x214, 0x3); /* mdp_wrot1 */ + + M4U_WriteReg32(LARB1_BASE, 0x200, 0x1f); /* port#0, mc */ + M4U_WriteReg32(LARB1_BASE, 0x204, 0x06); /* port#1, pp */ + M4U_WriteReg32(LARB1_BASE, 0x208, 0x1); /* port#2, ufo */ + M4U_WriteReg32(LARB1_BASE, 0x20c, 0x1); /* port#3, vld */ + M4U_WriteReg32(LARB1_BASE, 0x210, 0x1); /* port#4, vld2 */ + M4U_WriteReg32(LARB1_BASE, 0x214, 0x2); /* port#5, mv */ + M4U_WriteReg32(LARB1_BASE, 0x218, 0x1); /* port#6, pred rd */ + M4U_WriteReg32(LARB1_BASE, 0x21c, 0x1); /* port#7, pred wr */ + M4U_WriteReg32(LARB1_BASE, 0x220, 0x1); /* port#8, ppwrap */ + +} + +static void hdmi4kSetting(struct mtk_smi_data *smidev) +{ + + /* VP 4K */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB0, 0x12A6); /* LARB0, DISP+MDP */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB1, 0x158B); /* LARB1, VDEC */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB2, 0x1000); /* LARB2, ISP */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB3, 0x1000); /* LARB3, VENC+JPG */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB4, 0x1A6D); /* LARB4, DISP2+MDP2 */ + M4U_WriteReg32(SMI_COMMON_EXT_BASE, REG_OFFSET_SMI_L1ARB5, 0x1000); /* LARB5, VENC2 */ + + M4U_WriteReg32(LARB0_BASE, 0x200, 0x18); /* ovl_ch0_0/1 */ + M4U_WriteReg32(LARB0_BASE, 0x214, 0x4); /* mdp_rdma0; min(4,5) */ + M4U_WriteReg32(LARB0_BASE, 0x21c, 0x5); /* mdp_wrot0 */ + + M4U_WriteReg32(LARB4_BASE, 0x200, 0x8); /* ovl_ch1_0/1 */ + M4U_WriteReg32(LARB4_BASE, 0x210, 0x4); /* mdp_rdma1; min(4,5) */ + M4U_WriteReg32(LARB4_BASE, 0x214, 0x3); /* mdp_wrot1 */ + + M4U_WriteReg32(LARB1_BASE, 0x200, 0x1f); /* port#0, mc */ + M4U_WriteReg32(LARB1_BASE, 0x204, 0x06); /* port#1, pp */ + M4U_WriteReg32(LARB1_BASE, 0x208, 0x1); /* port#2, ufo */ + M4U_WriteReg32(LARB1_BASE, 0x20c, 0x1); /* port#3, vld */ + M4U_WriteReg32(LARB1_BASE, 0x210, 0x1); /* port#4, vld2 */ + M4U_WriteReg32(LARB1_BASE, 0x214, 0x2); /* port#5, mv */ + M4U_WriteReg32(LARB1_BASE, 0x218, 0x1); /* port#6, pred rd */ + M4U_WriteReg32(LARB1_BASE, 0x21c, 0x1); /* port#7, pred wr */ + M4U_WriteReg32(LARB1_BASE, 0x220, 0x1); /* port#8, ppwrap */ + +} + +/* Make sure all the clock is enabled */ +const struct mtk_smi_priv smi_mt8173_priv = { + .larb_port_num = {8, 9, 21, 15, 6, 9}, + .larb_vc_setting = { 0, 2, 0, 1, 0, 1 }, + .init_setting = initSetting, + .vp_setting = vpSetting, + .vr_setting = vrSetting, + .hdmi_setting = hdmiSetting, + .hdmi_4k_setting = hdmi4kSetting, +}; + |
