From 49c33dab8b7a57780affea28db976ccab8dc345b Mon Sep 17 00:00:00 2001 From: XpLoDWilD Date: Fri, 26 Jul 2013 12:37:55 +0200 Subject: fimc/s3cfb: Remove inlines breaking build on 4.3 If anyone have any idea why it cannot find function body for these two functions... Others are fine. Change-Id: Ifebb2e995a4ef4e779bed2e8f12aa7990ac19b41 --- drivers/media/video/exynos/fimc-lite/fimc-lite-core.c | 2 +- drivers/media/video/exynos/fimc-lite/fimc-lite-core.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/exynos/fimc-lite/fimc-lite-core.c b/drivers/media/video/exynos/fimc-lite/fimc-lite-core.c index 011787c..0a10f2e 100644 --- a/drivers/media/video/exynos/fimc-lite/fimc-lite-core.c +++ b/drivers/media/video/exynos/fimc-lite/fimc-lite-core.c @@ -122,7 +122,7 @@ static struct flite_fmt *find_format(u32 *pixelformat, u32 *mbus_code, int index } #endif -inline struct flite_fmt const *find_flite_format(struct v4l2_mbus_framefmt *mf) +struct flite_fmt const *find_flite_format(struct v4l2_mbus_framefmt *mf) { int num_fmt = ARRAY_SIZE(flite_formats); diff --git a/drivers/media/video/exynos/fimc-lite/fimc-lite-core.h b/drivers/media/video/exynos/fimc-lite/fimc-lite-core.h index 2c46c8b..a8a0a2e 100644 --- a/drivers/media/video/exynos/fimc-lite/fimc-lite-core.h +++ b/drivers/media/video/exynos/fimc-lite/fimc-lite-core.h @@ -295,7 +295,7 @@ static inline void user_to_drv(struct v4l2_ctrl *ctrl, s32 value) ctrl->cur.val = ctrl->val = value; } -inline struct flite_fmt const *find_flite_format(struct v4l2_mbus_framefmt *mf); +struct flite_fmt const *find_flite_format(struct v4l2_mbus_framefmt *mf); /* * Add buf to the capture active buffers queue. -- cgit v1.1 From 008d6925cd8509bcf525950f66d9c9f913a207ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20G?= Date: Thu, 15 Aug 2013 23:59:31 +0200 Subject: Increase lowest GPU step for 1400MHz devices Devices using the 1400MHz Exynos 4210 are using 1280*800 screens. This is a much bigger resolution than the Galaxy S2. 100MHz as the lowest GPU step is too low for these devices, resulting in lag. Bump it up to 134MHz. Change-Id: Ifd08cdc2e263695232d034890e54585f122453ff --- .../video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c b/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c index 3bf6805..e0199b2 100644 --- a/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c +++ b/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c @@ -76,7 +76,11 @@ int mali_dvfs_control=0; /*dvfs table*/ mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={ +#ifdef CONFIG_EXYNOS4210_1400MHZ_SUPPORT + /*step 0*/{134 ,1000000 , 950000}, +#else /*step 0*/{100 ,1000000 , 950000}, +#endif /*step 1*/{160 ,1000000 , 950000}, /*step 2*/{267 ,1000000 ,1000000} }; @@ -87,7 +91,7 @@ mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={ #define ASV_LEVEL_SUPPORT 0 static unsigned int asv_3d_volt_5_table[ASV_5_LEVEL][MALI_DVFS_STEPS] = { - /* L3 (100MHz) L2(160MHz), L1(267MHz) */ + /* L3 (100/134MHz) L2(160MHz), L1(267MHz) */ {1000000, 1000000, 1100000}, /* S */ {1000000, 1000000, 1100000}, /* A */ { 950000, 950000, 1000000}, /* B */ @@ -96,7 +100,7 @@ static unsigned int asv_3d_volt_5_table[ASV_5_LEVEL][MALI_DVFS_STEPS] = { }; static unsigned int asv_3d_volt_8_table[ASV_8_LEVEL][MALI_DVFS_STEPS] = { - /* L3 (100MHz) L2(160MHz), L1(267MHz) */ + /* L3 (100/134MHz) L2(160MHz), L1(267MHz) */ {1000000, 1000000, 1100000}, /* SS */ {1000000, 1000000, 1100000}, /* A1 */ {1000000, 1000000, 1100000}, /* A2 */ -- cgit v1.1 From 81acf891b5786d5b392bc0af2a81f193cb90bfc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20G?= Date: Fri, 16 Aug 2013 18:30:12 +0200 Subject: mali: pick the right GPU voltage table for 1400MHz devices, restore thresholds 8-level table was always used, resulting in increased voltages for 1400MHz devices. Now, the right table (5-level) can be picked at runtime. Restore the thresholds to stock value for more stable frequencies. Change-Id: I29900535c15557e75c72793b7169771982fce7f9 --- .../samsung/mali/platform/orion-m400/mali_platform_dvfs.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c b/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c index 3bf6805..98a8852 100644 --- a/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c +++ b/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c @@ -67,8 +67,8 @@ mali_dvfs_staycount_table mali_dvfs_staycount[MALI_DVFS_STEPS]={ /*dvfs threshold*/ mali_dvfs_threshold_table mali_dvfs_threshold[MALI_DVFS_STEPS]={ /*step 0*/{((int)((255*0)/100)) ,((int)((255*85)/100))}, - /*step 1*/{((int)((255*80)/100)) ,((int)((255*90)/100))}, - /*step 2*/{((int)((255*80)/100)) ,((int)((255*100)/100))} }; + /*step 1*/{((int)((255*75)/100)) ,((int)((255*85)/100))}, + /*step 2*/{((int)((255*75)/100)) ,((int)((255*100)/100))} }; /*dvfs status*/ mali_dvfs_currentstatus maliDvfsStatus; @@ -84,7 +84,6 @@ mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={ #define ASV_8_LEVEL 8 #define ASV_5_LEVEL 5 -#define ASV_LEVEL_SUPPORT 0 static unsigned int asv_3d_volt_5_table[ASV_5_LEVEL][MALI_DVFS_STEPS] = { /* L3 (100MHz) L2(160MHz), L1(267MHz) */ @@ -269,16 +268,18 @@ static unsigned int decideNextStatus(unsigned int utilization) static mali_bool mali_dvfs_table_update(void) { unsigned int exynos_result_of_asv_group; + unsigned int target_asv; unsigned int i; exynos_result_of_asv_group = exynos_result_of_asv & 0xf; - MALI_PRINT(("exynos_result_of_asv_group = 0x%x\n", exynos_result_of_asv_group)); + target_asv = exynos_result_of_asv >> 28; + MALI_PRINT(("exynos_result_of_asv_group = 0x%x, target_asv = 0x%x\n", exynos_result_of_asv_group, target_asv)); - if (ASV_LEVEL_SUPPORT) { //asv level information will be added. + if (target_asv == 0x8) { //SUPPORT_1400MHZ for (i = 0; i < MALI_DVFS_STEPS; i++) { mali_dvfs[i].vol = asv_3d_volt_5_table[exynos_result_of_asv_group][i]; MALI_PRINT(("mali_dvfs[%d].vol = %d\n", i, mali_dvfs[i].vol)); } - } else { + } else if (target_asv == 0x4){ //SUPPORT_1200MHZ for (i = 0; i < MALI_DVFS_STEPS; i++) { mali_dvfs[i].vol = asv_3d_volt_8_table[exynos_result_of_asv_group][i]; MALI_PRINT(("mali_dvfs[%d].vol = %d\n", i, mali_dvfs[i].vol)); -- cgit v1.1 From 7fc3ce7312fec9320aeffb1a6c6c6d4bf2408669 Mon Sep 17 00:00:00 2001 From: sbrissen Date: Wed, 23 Oct 2013 13:19:08 -0400 Subject: Add support for Note 8 (N5100 and N5110) Change-Id: I6c9798682f9f6349b37cb452353bd0c0e6958401 --- drivers/media/video/Kconfig | 9 + drivers/media/video/Makefile | 1 + drivers/media/video/isx012.c | 352 +- drivers/media/video/isx012.h | 39 +- drivers/media/video/isx012_regs.h | 14 +- drivers/media/video/isx012_regs_kona.h | 11284 +++++++++++++++++++ drivers/media/video/samsung/fimc/fimc_capture.c | 17 +- .../video/samsung/mali/common/mali_kernel_mem_os.c | 10 +- drivers/media/video/sr130pc20.c | 1999 ++++ drivers/media/video/sr130pc20.h | 646 ++ drivers/media/video/sr130pc20_regs.h | 4229 +++++++ 11 files changed, 18449 insertions(+), 151 deletions(-) create mode 100644 drivers/media/video/isx012_regs_kona.h create mode 100644 drivers/media/video/sr130pc20.c create mode 100755 drivers/media/video/sr130pc20.h create mode 100644 drivers/media/video/sr130pc20_regs.h (limited to 'drivers/media/video') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index aeedd90..cc7c047 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -652,6 +652,15 @@ config VIDEO_SLP_S5C73M3 ---help--- This driver supports s5c73m3 ISP camera module with MIPI CSI-2 as well +config VIDEO_SR130PC20 + tristate "SR130PC20 camera driver" + depends on I2C && VIDEO_V4L2 + ---help--- + This driver supports SR130PC20 SoC camera module. + The SR130PC20 camera module uses siliconfile camera sensor + supporting 1.3M capture with MIPI interface. And also, It support + VGA recording with 25fps. + config VIDEO_IMPROVE_STREAMOFF bool "Improve shtter lag" depends on VIDEO_FIMC_MIPI diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 64f0f5b..7ce4839 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -92,6 +92,7 @@ obj-$(CONFIG_VIDEO_M5MOLS) += m5mols/ obj-$(CONFIG_VIDEO_S5C73M3) += s5c73m3.o obj-$(CONFIG_VIDEO_ISX012) += isx012.o obj-$(CONFIG_VIDEO_S5C73M3_SPI) += s5c73m3_spi.o +obj-$(CONFIG_VIDEO_SR130PC20) += sr130pc20.o obj-$(CONFIG_VIDEO_SLP_S5C73M3) += slp_s5c73m3.o obj-$(CONFIG_VIDEO_SLP_S5K4ECGX) += slp_s5k4ecgx.o obj-$(CONFIG_VIDEO_SLP_DB8131M) += slp_db8131m.o diff --git a/drivers/media/video/isx012.c b/drivers/media/video/isx012.c index 427d59b..e33a430 100644 --- a/drivers/media/video/isx012.c +++ b/drivers/media/video/isx012.c @@ -28,6 +28,7 @@ #define isx012_wait_ae_stable_cap(sd) isx012_wait_ae_stable(sd, false, false) static int dbg_level; +static u32 VendorID; static const struct isx012_fps isx012_framerates[] = { { I_FPS_0, FRAME_RATE_AUTO }, @@ -42,6 +43,11 @@ static const struct isx012_framesize isx012_preview_frmsizes[] = { { PREVIEW_SZ_320x240, 320, 240 }, { PREVIEW_SZ_CIF, 352, 288 }, { PREVIEW_SZ_528x432, 528, 432 }, +#if defined(CONFIG_MACH_P4NOTELTE_KOR_SKT) \ + || defined(CONFIG_MACH_P4NOTELTE_KOR_KT) \ + || defined(CONFIG_MACH_P4NOTELTE_KOR_LGT) /*For 4G VT call in Domestic*/ + { PREVIEW_SZ_VERTICAL_VGA, 480, 640 }, +#endif { PREVIEW_SZ_VGA, 640, 480 }, { PREVIEW_SZ_D1, 720, 480 }, { PREVIEW_SZ_880x720, 880, 720 }, @@ -83,154 +89,167 @@ static struct isx012_control isx012_ctrls[] = { static const struct isx012_regs reg_datas = { .ev = { ISX012_REGSET(GET_EV_INDEX(EV_MINUS_4), - ISX012_ExpSetting_M4Step), + ISX012_ExpSetting_M4Step, 0), ISX012_REGSET(GET_EV_INDEX(EV_MINUS_3), - ISX012_ExpSetting_M3Step), + ISX012_ExpSetting_M3Step, 0), ISX012_REGSET(GET_EV_INDEX(EV_MINUS_2), - ISX012_ExpSetting_M2Step), + ISX012_ExpSetting_M2Step, 0), ISX012_REGSET(GET_EV_INDEX(EV_MINUS_1), - ISX012_ExpSetting_M1Step), + ISX012_ExpSetting_M1Step, 0), ISX012_REGSET(GET_EV_INDEX(EV_DEFAULT), - ISX012_ExpSetting_Default), + ISX012_ExpSetting_Default, 0), ISX012_REGSET(GET_EV_INDEX(EV_PLUS_1), - ISX012_ExpSetting_P1Step), + ISX012_ExpSetting_P1Step, 0), ISX012_REGSET(GET_EV_INDEX(EV_PLUS_2), - ISX012_ExpSetting_P2Step), + ISX012_ExpSetting_P2Step, 0), ISX012_REGSET(GET_EV_INDEX(EV_PLUS_3), - ISX012_ExpSetting_P3Step), + ISX012_ExpSetting_P3Step, 0), ISX012_REGSET(GET_EV_INDEX(EV_PLUS_4), - ISX012_ExpSetting_P4Step), + ISX012_ExpSetting_P4Step, 0), }, .metering = { - ISX012_REGSET(METERING_MATRIX, isx012_Metering_Matrix), - ISX012_REGSET(METERING_CENTER, isx012_Metering_Center), - ISX012_REGSET(METERING_SPOT, isx012_Metering_Spot), + ISX012_REGSET(METERING_MATRIX, isx012_Metering_Matrix, 0), + ISX012_REGSET(METERING_CENTER, isx012_Metering_Center, 0), + ISX012_REGSET(METERING_SPOT, isx012_Metering_Spot, 0), }, .iso = { - ISX012_REGSET(ISO_AUTO, isx012_ISO_Auto), - ISX012_REGSET(ISO_50, isx012_ISO_50), - ISX012_REGSET(ISO_100, isx012_ISO_100), - ISX012_REGSET(ISO_200, isx012_ISO_200), - ISX012_REGSET(ISO_400, isx012_ISO_400), + ISX012_REGSET(ISO_AUTO, isx012_ISO_Auto, 0), + ISX012_REGSET(ISO_50, isx012_ISO_50, 0), + ISX012_REGSET(ISO_100, isx012_ISO_100, 0), + ISX012_REGSET(ISO_200, isx012_ISO_200, 0), + ISX012_REGSET(ISO_400, isx012_ISO_400, 0), }, .effect = { - ISX012_REGSET(IMAGE_EFFECT_NONE, isx012_Effect_Normal), - ISX012_REGSET(IMAGE_EFFECT_BNW, isx012_Effect_Black_White), - ISX012_REGSET(IMAGE_EFFECT_SEPIA, isx012_Effect_Sepia), + ISX012_REGSET(IMAGE_EFFECT_NONE, isx012_Effect_Normal, 0), + ISX012_REGSET(IMAGE_EFFECT_BNW, isx012_Effect_Black_White, 0), + ISX012_REGSET(IMAGE_EFFECT_SEPIA, isx012_Effect_Sepia, 0), ISX012_REGSET(IMAGE_EFFECT_NEGATIVE, - ISX012_Effect_Negative), - ISX012_REGSET(IMAGE_EFFECT_SOLARIZE, isx012_Effect_Solar), - ISX012_REGSET(IMAGE_EFFECT_SKETCH, isx012_Effect_Sketch), - ISX012_REGSET(IMAGE_EFFECT_POINT_COLOR_3, isx012_Effect_Pastel), + ISX012_Effect_Negative, 0), + ISX012_REGSET(IMAGE_EFFECT_SOLARIZE, isx012_Effect_Solar, 0), + ISX012_REGSET(IMAGE_EFFECT_SKETCH, isx012_Effect_Sketch, 0), + ISX012_REGSET(IMAGE_EFFECT_POINT_COLOR_3, + isx012_Effect_Pastel, 0), }, .white_balance = { - ISX012_REGSET(WHITE_BALANCE_AUTO, isx012_WB_Auto), - ISX012_REGSET(WHITE_BALANCE_SUNNY, isx012_WB_Sunny), - ISX012_REGSET(WHITE_BALANCE_CLOUDY, isx012_WB_Cloudy), + ISX012_REGSET(WHITE_BALANCE_AUTO, isx012_WB_Auto, 0), + ISX012_REGSET(WHITE_BALANCE_SUNNY, isx012_WB_Sunny, 0), + ISX012_REGSET(WHITE_BALANCE_CLOUDY, isx012_WB_Cloudy, 0), ISX012_REGSET(WHITE_BALANCE_TUNGSTEN, - isx012_WB_Tungsten), + isx012_WB_Tungsten, 0), ISX012_REGSET(WHITE_BALANCE_FLUORESCENT, - isx012_WB_Fluorescent), + isx012_WB_Fluorescent, 0), }, .scene_mode = { - ISX012_REGSET(SCENE_MODE_NONE, isx012_Scene_Default), - ISX012_REGSET(SCENE_MODE_PORTRAIT, isx012_Scene_Portrait), - ISX012_REGSET(SCENE_MODE_NIGHTSHOT, isx012_Scene_Nightshot), - ISX012_REGSET(SCENE_MODE_BACK_LIGHT, isx012_Scene_Backlight), - ISX012_REGSET(SCENE_MODE_LANDSCAPE, isx012_Scene_Landscape), - ISX012_REGSET(SCENE_MODE_SPORTS, isx012_Scene_Sports), + ISX012_REGSET(SCENE_MODE_NONE, isx012_Scene_Default, 0), + ISX012_REGSET(SCENE_MODE_PORTRAIT, isx012_Scene_Portrait, 0), + ISX012_REGSET(SCENE_MODE_NIGHTSHOT, isx012_Scene_Nightshot, 0), + ISX012_REGSET(SCENE_MODE_BACK_LIGHT, isx012_Scene_Backlight, 0), + ISX012_REGSET(SCENE_MODE_LANDSCAPE, isx012_Scene_Landscape, 0), + ISX012_REGSET(SCENE_MODE_SPORTS, isx012_Scene_Sports, 0), ISX012_REGSET(SCENE_MODE_PARTY_INDOOR, - isx012_Scene_Party_Indoor), - ISX012_REGSET(SCENE_MODE_BEACH_SNOW, isx012_Scene_Beach_Snow), - ISX012_REGSET(SCENE_MODE_SUNSET, isx012_Scene_Sunset), - ISX012_REGSET(SCENE_MODE_DUSK_DAWN, isx012_Scene_Duskdawn), - ISX012_REGSET(SCENE_MODE_FALL_COLOR, isx012_Scene_Fall_Color), - ISX012_REGSET(SCENE_MODE_FIREWORKS, isx012_Scene_Fireworks), - ISX012_REGSET(SCENE_MODE_TEXT, isx012_Scene_Text), + isx012_Scene_Party_Indoor, 0), + ISX012_REGSET(SCENE_MODE_BEACH_SNOW, + isx012_Scene_Beach_Snow, 0), + ISX012_REGSET(SCENE_MODE_SUNSET, isx012_Scene_Sunset, 0), + ISX012_REGSET(SCENE_MODE_DUSK_DAWN, isx012_Scene_Duskdawn, 0), + ISX012_REGSET(SCENE_MODE_FALL_COLOR, + isx012_Scene_Fall_Color, 0), + ISX012_REGSET(SCENE_MODE_FIREWORKS, isx012_Scene_Fireworks, 0), + ISX012_REGSET(SCENE_MODE_TEXT, isx012_Scene_Text, 0), ISX012_REGSET(SCENE_MODE_CANDLE_LIGHT, - isx012_Scene_Candle_Light), + isx012_Scene_Candle_Light, 0), }, .saturation = { - ISX012_REGSET(SATURATION_MINUS_2, isx012_Saturation_Minus_2), - ISX012_REGSET(SATURATION_MINUS_1, isx012_Saturation_Minus_1), - ISX012_REGSET(SATURATION_DEFAULT, isx012_Saturation_Default), - ISX012_REGSET(SATURATION_PLUS_1, isx012_Saturation_Plus_1), - ISX012_REGSET(SATURATION_PLUS_2, isx012_Saturation_Plus_2), + ISX012_REGSET(SATURATION_MINUS_2, isx012_Saturation_Minus_2, 0), + ISX012_REGSET(SATURATION_MINUS_1, isx012_Saturation_Minus_1, 0), + ISX012_REGSET(SATURATION_DEFAULT, isx012_Saturation_Default, 0), + ISX012_REGSET(SATURATION_PLUS_1, isx012_Saturation_Plus_1, 0), + ISX012_REGSET(SATURATION_PLUS_2, isx012_Saturation_Plus_2, 0), }, .contrast = { - ISX012_REGSET(CONTRAST_MINUS_2, isx012_Contrast_Minus_2), - ISX012_REGSET(CONTRAST_MINUS_1, isx012_Contrast_Minus_1), - ISX012_REGSET(CONTRAST_DEFAULT, isx012_Contrast_Default), - ISX012_REGSET(CONTRAST_PLUS_1, isx012_Contrast_Plus_1), - ISX012_REGSET(CONTRAST_PLUS_2, isx012_Contrast_Plus_2), + ISX012_REGSET(CONTRAST_MINUS_2, isx012_Contrast_Minus_2, 0), + ISX012_REGSET(CONTRAST_MINUS_1, isx012_Contrast_Minus_1, 0), + ISX012_REGSET(CONTRAST_DEFAULT, isx012_Contrast_Default, 0), + ISX012_REGSET(CONTRAST_PLUS_1, isx012_Contrast_Plus_1, 0), + ISX012_REGSET(CONTRAST_PLUS_2, isx012_Contrast_Plus_2, 0), }, .sharpness = { - ISX012_REGSET(SHARPNESS_MINUS_2, isx012_Sharpness_Minus_2), - ISX012_REGSET(SHARPNESS_MINUS_1, isx012_Sharpness_Minus_1), - ISX012_REGSET(SHARPNESS_DEFAULT, isx012_Sharpness_Default), - ISX012_REGSET(SHARPNESS_PLUS_1, isx012_Sharpness_Plus_1), - ISX012_REGSET(SHARPNESS_PLUS_2, isx012_Sharpness_Plus_2), + ISX012_REGSET(SHARPNESS_MINUS_2, isx012_Sharpness_Minus_2, 0), + ISX012_REGSET(SHARPNESS_MINUS_1, isx012_Sharpness_Minus_1, 0), + ISX012_REGSET(SHARPNESS_DEFAULT, isx012_Sharpness_Default, 0), + ISX012_REGSET(SHARPNESS_PLUS_1, isx012_Sharpness_Plus_1, 0), + ISX012_REGSET(SHARPNESS_PLUS_2, isx012_Sharpness_Plus_2, 0), }, .fps = { - ISX012_REGSET(I_FPS_0, isx012_fps_auto), - ISX012_REGSET(I_FPS_7, isx012_fps_7fix), - ISX012_REGSET(I_FPS_15, isx012_fps_15fix), - ISX012_REGSET(I_FPS_25, isx012_fps_25fix), - ISX012_REGSET(I_FPS_30, isx012_fps_30fix), + ISX012_REGSET(I_FPS_0, isx012_fps_auto, 0), + ISX012_REGSET(I_FPS_7, isx012_fps_7fix, 0), + ISX012_REGSET(I_FPS_15, isx012_fps_15fix, 0), + ISX012_REGSET(I_FPS_25, isx012_fps_25fix, 0), + ISX012_REGSET(I_FPS_30, isx012_fps_30fix, 0), }, .preview_size = { - ISX012_REGSET(PREVIEW_SZ_320x240, isx012_320_Preview), - ISX012_REGSET(PREVIEW_SZ_VGA, isx012_640_Preview), - ISX012_REGSET(PREVIEW_SZ_D1, isx012_720_Preview), - ISX012_REGSET(PREVIEW_SZ_XGA, isx012_1024_768_Preview), - ISX012_REGSET(PREVIEW_SZ_PVGA, isx012_1280_Preview_E), + ISX012_REGSET(PREVIEW_SZ_320x240, isx012_320_Preview, 0), +#if defined(CONFIG_MACH_P4NOTELTE_KOR_SKT) \ + || defined(CONFIG_MACH_P4NOTELTE_KOR_KT) \ + || defined(CONFIG_MACH_P4NOTELTE_KOR_LGT) /*For 4G VT call in Domestic*/ + ISX012_REGSET(PREVIEW_SZ_VERTICAL_VGA, isx012_480_Preview, 0), +#endif + ISX012_REGSET(PREVIEW_SZ_VGA, isx012_640_Preview, 0), + ISX012_REGSET(PREVIEW_SZ_D1, isx012_720_Preview, 0), + ISX012_REGSET(PREVIEW_SZ_XGA, isx012_1024_768_Preview, 0), + ISX012_REGSET(PREVIEW_SZ_PVGA, isx012_1280_Preview_E, 0), }, .capture_size = { - ISX012_REGSET(CAPTURE_SZ_VGA, isx012_VGA_Capture), - ISX012_REGSET(CAPTURE_SZ_960_720, isx012_960_720_Capture), - ISX012_REGSET(CAPTURE_SZ_3MP, isx012_3M_Capture), - ISX012_REGSET(CAPTURE_SZ_5MP, isx012_5M_Capture), + ISX012_REGSET(CAPTURE_SZ_VGA, isx012_VGA_Capture, 0), + ISX012_REGSET(CAPTURE_SZ_960_720, isx012_960_720_Capture, 0), + ISX012_REGSET(CAPTURE_SZ_3MP, isx012_3M_Capture, 0), + ISX012_REGSET(CAPTURE_SZ_5MP, isx012_5M_Capture, 0), }, /* AF */ - .af_window_reset = ISX012_REGSET_TABLE(ISX012_AF_Window_Reset), - .af_winddow_set = ISX012_REGSET_TABLE(ISX012_AF_Window_Set), - .af_restart = ISX012_REGSET_TABLE(ISX012_AF_ReStart), - .af_saf_off = ISX012_REGSET_TABLE(ISX012_AF_SAF_OFF), - .af_touch_saf_off = ISX012_REGSET_TABLE(ISX012_AF_TouchSAF_OFF), - .cancel_af_macro = ISX012_REGSET_TABLE(ISX012_AF_Cancel_Macro_ON), - .cancel_af_normal = ISX012_REGSET_TABLE(ISX012_AF_Cancel_Macro_OFF), - .af_macro_mode = ISX012_REGSET_TABLE(ISX012_AF_Macro_ON), - .af_normal_mode = ISX012_REGSET_TABLE(ISX012_AF_Macro_OFF), - .af_camcorder_start = ISX012_REGSET_TABLE(ISX012_Camcorder_SAF_Start), + .af_window_reset = ISX012_REGSET_TABLE(ISX012_AF_Window_Reset, 1), + .af_winddow_set = ISX012_REGSET_TABLE(ISX012_AF_Window_Set, 0), + .af_restart = ISX012_REGSET_TABLE(ISX012_AF_ReStart, 0), + .af_saf_off = ISX012_REGSET_TABLE(ISX012_AF_SAF_OFF, 0), + .af_touch_saf_off = ISX012_REGSET_TABLE(ISX012_AF_TouchSAF_OFF, 0), + .cancel_af_macro = ISX012_REGSET_TABLE(ISX012_AF_Cancel_Macro_ON, 0), + .cancel_af_normal = ISX012_REGSET_TABLE(ISX012_AF_Cancel_Macro_OFF, 0), + .af_macro_mode = ISX012_REGSET_TABLE(ISX012_AF_Macro_ON, 0), + .af_normal_mode = ISX012_REGSET_TABLE(ISX012_AF_Macro_OFF, 0), + .af_camcorder_start = ISX012_REGSET_TABLE( + ISX012_Camcorder_SAF_Start, 0), /* Flash */ - .flash_ae_line = ISX012_REGSET_TABLE(ISX012_Flash_AELINE), - .flash_on = ISX012_REGSET_TABLE(ISX012_Flash_ON), - .flash_off = ISX012_REGSET_TABLE(ISX012_Flash_OFF), - .ae_manual = ISX012_REGSET_TABLE(ISX012_ae_manual_mode), - .flash_fast_ae_awb = ISX012_REGSET_TABLE(ISX012_flash_fast_ae_awb), + .flash_ae_line = ISX012_REGSET_TABLE(ISX012_Flash_AELINE, 0), + .flash_on = ISX012_REGSET_TABLE(ISX012_Flash_ON, 1), + .flash_off = ISX012_REGSET_TABLE(ISX012_Flash_OFF, 1), + .ae_manual = ISX012_REGSET_TABLE(ISX012_ae_manual_mode, 0), + .flash_fast_ae_awb = ISX012_REGSET_TABLE(ISX012_flash_fast_ae_awb, 0), - .init_reg = ISX012_REGSET_TABLE(ISX012_Init_Reg), + .init_reg = ISX012_REGSET_TABLE(ISX012_Init_Reg, 1), /* Camera mode */ - .preview_mode = ISX012_REGSET_TABLE(ISX012_Preview_Mode), - .capture_mode = ISX012_REGSET_TABLE(ISX012_Capture_Mode), + .preview_mode = ISX012_REGSET_TABLE(ISX012_Preview_Mode, 0), + .capture_mode = ISX012_REGSET_TABLE(ISX012_Capture_Mode, 0), .capture_mode_night = - ISX012_REGSET_TABLE(ISX012_Lowlux_Night_Capture_Mode), - .halfrelease_mode = ISX012_REGSET_TABLE(ISX012_Halfrelease_Mode), + ISX012_REGSET_TABLE(ISX012_Lowlux_Night_Capture_Mode, 0), + .halfrelease_mode = ISX012_REGSET_TABLE(ISX012_Halfrelease_Mode, 0), .halfrelease_mode_night = - ISX012_REGSET_TABLE(ISX012_Lowlux_night_Halfrelease_Mode), - .camcorder_on = ISX012_REGSET_TABLE(ISX012_Camcorder_Mode_ON), - .camcorder_off = ISX012_REGSET_TABLE(ISX012_Camcorder_Mode_OFF), - - .lowlux_night_reset = ISX012_REGSET_TABLE(ISX012_Lowlux_Night_Reset), - - .set_pll_4 = ISX012_REGSET_TABLE(ISX012_Pll_Setting_4), - .softlanding = ISX012_REGSET_TABLE(ISX012_Sensor_Off_VCM), + ISX012_REGSET_TABLE(ISX012_Lowlux_night_Halfrelease_Mode, 0), + .camcorder_on = ISX012_REGSET_TABLE(ISX012_Camcorder_Mode_ON, 1), + .camcorder_off = ISX012_REGSET_TABLE(ISX012_Camcorder_Mode_OFF, 1), + + .lowlux_night_reset = ISX012_REGSET_TABLE(ISX012_Lowlux_Night_Reset, 0), + + .set_pll_4 = ISX012_REGSET_TABLE(ISX012_Pll_Setting_4, 1), + .shading_0 = ISX012_REGSET_TABLE(ISX012_Shading_0, 1), + .shading_1 = ISX012_REGSET_TABLE(ISX012_Shading_1, 1), + .shading_2 = ISX012_REGSET_TABLE(ISX012_Shading_2, 1), + .shading_nocal = ISX012_REGSET_TABLE(ISX012_Shading_Nocal, 1), + .softlanding = ISX012_REGSET_TABLE(ISX012_Sensor_Off_VCM, 0), #if 0 /* def CONFIG_VIDEO_ISX012_P8*/ - .antibanding = ISX012_REGSET_TABLE(ISX012_ANTIBANDING_REG), + .antibanding = ISX012_REGSET_TABLE(ISX012_ANTIBANDING_REG, 0), #endif }; @@ -854,6 +873,8 @@ static int isx012_i2c_burst_write_list(struct v4l2_subdev *sd, struct i2c_msg msg = {isx012_client->addr, 0, 4, buf}; + cam_trace("%s\n", name); + if (!isx012_client->adapter) { printk(KERN_ERR "%s: %d can't search i2c client adapter\n", __func__, __LINE__); return -EIO; @@ -965,7 +986,12 @@ static int isx012_set_from_table(struct v4l2_subdev *sd, table->name); # endif /* DEBUG_WRITE_REGS */ - err = isx012_write_regs(sd, table->reg, table->array_size); + if (table->burst) { + err = isx012_i2c_burst_write_list(sd, + table->reg, table->array_size, setting_name); + } else + err = isx012_write_regs(sd, table->reg, table->array_size); + CHECK_ERR_MSG(err, "write regs(%s), err=%d\n", setting_name, err); return 0; @@ -2098,11 +2124,11 @@ static int isx012_do_af(struct v4l2_subdev *sd, u32 touch) break; af_dbg("AF state= %d(0x%X)\n", read_value, read_value); - msleep_debug(30, false); + msleep_debug(10, false); } if (unlikely(count >= AF_SEARCH_COUNT)) { - cam_warn("warning, AF check failed. val=0x%X\n\n", read_value); + cam_warn("warning, AF check timeout. val=0x%X\n\n", read_value); isx012_writeb(sd, REG_INTCLR, 0x10); goto check_fail; } @@ -2195,6 +2221,13 @@ static int isx012_set_af(struct v4l2_subdev *sd, s32 val) state->focus.start = val; if (val == AUTO_FOCUS_ON) { + if ((state->runmode != RUNMODE_RUNNING) && + (state->runmode != RUNMODE_RECORDING)) { + cam_err("error, AF can't start, not in preview\n"); + state->focus.start = AUTO_FOCUS_OFF; + return -ESRCH; + } + err = queue_work(state->workqueue, &state->af_work); if (likely(err)) state->focus.status = AF_RESULT_DOING; @@ -2604,6 +2637,10 @@ static int isx012_control_stream(struct v4l2_subdev *sd, u32 cmd) #if !defined(CONFIG_VIDEO_IMPROVE_STREAMOFF) state->capture.pre_req = 0; #endif + + if (state->focus.status == AF_RESULT_DOING) + isx012_set_af(sd, AUTO_FOCUS_OFF); + if (!((state->runmode == RUNMODE_RUNNING) && state->capture.pre_req)) { isx012_writeb(sd, 0x00BF, 0x01); @@ -3126,8 +3163,10 @@ static int isx012_s_mbus_fmt(struct v4l2_subdev *sd, isx012_set_framesize(sd, isx012_preview_frmsizes, ARRAY_SIZE(isx012_preview_frmsizes), true); - if (previous_index != state->preview.frmsize->index) + if ((state->preview.frmsize != NULL) && + (previous_index != state->preview.frmsize->index)) state->preview.update_frmsize = 1; + } else { /* * In case of image capture mode, @@ -3136,6 +3175,15 @@ static int isx012_s_mbus_fmt(struct v4l2_subdev *sd, isx012_set_framesize(sd, isx012_capture_frmsizes, ARRAY_SIZE(isx012_capture_frmsizes), false); + /* for maket app. + * Samsung camera app does not use unmatched ratio.*/ + if (unlikely(NULL == state->preview.frmsize)) { + cam_warn("warning, capture without preview resolution\n"); + } else if (unlikely(FRM_RATIO(state->preview.frmsize) + != FRM_RATIO(state->capture.frmsize))) { + cam_warn("warning, capture ratio " \ + "is different with preview ratio\n"); + } } return 0; @@ -3540,22 +3588,9 @@ static int isx012_s_stream(struct v4l2_subdev *sd, int enable) return 0; } -#if 0 /* DSLIM */ -static int isx012_reset(struct v4l2_subdev *sd, u32 val) -{ - struct isx012_state *state = to_state(sd); - - cam_trace("EX\n"); - - isx012_return_focus(sd); - state->initialized = 0; - - return 0; -} -#endif - void isx012_Sensor_Calibration(struct v4l2_subdev *sd) { + struct isx012_state *state = to_state(sd); int status = 0; int temp = 0; @@ -3573,11 +3608,14 @@ void isx012_Sensor_Calibration(struct v4l2_subdev *sd) /* Write Shading Table */ if (temp == 0x0) - ISX012_BURST_WRITE_LIST(ISX012_Shading_0); + isx012_set_from_table(sd, "Shading_0", + &state->regs->shading_0, 1, 0); else if (temp == 0x1) - ISX012_BURST_WRITE_LIST(ISX012_Shading_1); + isx012_set_from_table(sd, "Shading_1", + &state->regs->shading_1, 1, 0); else if (temp == 0x2) - ISX012_BURST_WRITE_LIST(ISX012_Shading_2); + isx012_set_from_table(sd, "Shading_2", + &state->regs->shading_2, 1, 0); /* Write NorR */ isx012_readw(sd, 0x0054, &status); @@ -3615,11 +3653,14 @@ void isx012_Sensor_Calibration(struct v4l2_subdev *sd) /* Write Shading Table */ if (temp == 0x0) - ISX012_BURST_WRITE_LIST(ISX012_Shading_0); + isx012_set_from_table(sd, "Shading_0", + &state->regs->shading_0, 1, 0); else if (temp == 0x1) - ISX012_BURST_WRITE_LIST(ISX012_Shading_1); + isx012_set_from_table(sd, "Shading_1", + &state->regs->shading_1, 1, 0); else if (temp == 0x2) - ISX012_BURST_WRITE_LIST(ISX012_Shading_2); + isx012_set_from_table(sd, "Shading_2", + &state->regs->shading_2, 1, 0); /* Write NorR */ isx012_readw(sd, 0x0045, &status); @@ -3645,7 +3686,8 @@ void isx012_Sensor_Calibration(struct v4l2_subdev *sd) boot_dbg("Cal: PreB read : %x\n", temp); isx012_writew(sd, 0x680A, temp); } else - ISX012_BURST_WRITE_LIST(ISX012_Shading_Nocal); + isx012_set_from_table(sd, "Shading_nocal", + &state->regs->shading_nocal, 1, 0); } } @@ -3658,10 +3700,46 @@ static inline int isx012_check_i2c(struct v4l2_subdev *sd, u16 data) if (unlikely(err)) return err; - cam_info("version: 0x%04X is 0x6017?\n", val); + cam_dbg("version: 0x%04X is 0x6017?\n", val); + return 0; +} + +static int isx012_check_vendorid(struct v4l2_subdev *sd) +{ + struct isx012_state *state = to_state(sd); + int status = 0; + int temp = 0; + int temp_msb = 0; + int temp_lsb = 0; + + /* Read OTP version */ + isx012_readw(sd, 0x004F, &status); + cam_dbg("OTP : 0x004F read 0x%04X\n", status); + if ((status & 0x10) == 0x10) { + isx012_readw(sd, 0x0051, &status); + temp = (status&0xFFFC); + cam_dbg("OTP1 : 0x0051 read : 0x%04X\n", temp); + } else { + isx012_readw(sd, 0x0042, &status); + temp = status&0xFFFC; + cam_dbg("OTP0 : 0x0042 read : 0x%04X\n", temp); + } + + temp_msb = (temp&0x03FC) << 6; + temp_lsb = (temp&0xFC00) >> 10; + VendorID = temp_msb | temp_lsb; + cam_info("Vendor ID: 0x%04X\n", VendorID); + return 0; } +u32 isx012_get_vendorid(void) +{ + cam_dbg("VendorID: 0x%04X\n", VendorID); + + return VendorID; +} + static int isx012_post_poweron(struct v4l2_subdev *sd) { struct isx012_state *state = to_state(sd); @@ -3675,7 +3753,14 @@ static int isx012_post_poweron(struct v4l2_subdev *sd) cam_err("%s: error, I2C check fail\n", __func__); return err; } - cam_info("I2C check success!\n"); + cam_dbg("I2C check success!\n"); + + err = isx012_check_vendorid(sd); + if (err) { + cam_err("%s: error, VendorID check fail\n", __func__); + return err; + } + cam_dbg("VendorID check success!\n"); msleep_debug(10, false); err = isx012_is_om_changed(sd); @@ -3953,8 +4038,8 @@ static int is_sysdev(struct device *dev, void *str) return !strcmp(dev_name(dev), (char *)str) ? 1 : 0; } -ssize_t cam_loglevel_show(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t cam_loglevel_show(struct device *dev, + struct device_attribute *attr, char *buf) { char temp_buf[60] = {0,}; @@ -3980,8 +4065,9 @@ ssize_t cam_loglevel_show(struct device *dev, struct device_attribute *attr, return strlen(buf); } -ssize_t cam_loglevel_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t cam_loglevel_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { printk(KERN_DEBUG "CAM buf=%s, count=%d\n", buf, count); @@ -4056,6 +4142,6 @@ static void __exit v4l2_i2c_drv_cleanup(void) module_init(v4l2_i2c_drv_init); module_exit(v4l2_i2c_drv_cleanup); -MODULE_DESCRIPTION("LSI ISX012 3MP SOC camera driver"); +MODULE_DESCRIPTION("SONY ISX012 5MP SOC camera driver"); MODULE_AUTHOR("Dong-Seong Lim "); MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/isx012.h b/drivers/media/video/isx012.h index 5e65195..e427cc2 100644 --- a/drivers/media/video/isx012.h +++ b/drivers/media/video/isx012.h @@ -38,9 +38,9 @@ /* #define CONFIG_DEBUG_NO_FRAME */ /** Debuging Feature **/ -/* #define CONFIG_CAM_DEBUG */ -/* #define CONFIG_CAM_TRACE */ /* Enable it with CONFIG_CAM_DEBUG */ -/* #define CONFIG_CAM_AF_DEBUG *//* Enable it with CONFIG_CAM_DEBUG */ +#define CONFIG_CAM_DEBUG +#define CONFIG_CAM_TRACE /* Enable it with CONFIG_CAM_DEBUG */ +#define CONFIG_CAM_AF_DEBUG //* Enable it with CONFIG_CAM_DEBUG */ /* #define DEBUG_WRITE_REGS */ /***********************************/ @@ -193,6 +193,11 @@ enum isx012_preview_frame_size { PREVIEW_SZ_320x240, /* 320x240 */ PREVIEW_SZ_CIF, /* 352x288 */ PREVIEW_SZ_528x432, /* 528x432 */ +#if defined(CONFIG_MACH_P4NOTELTE_KOR_SKT) \ + || defined(CONFIG_MACH_P4NOTELTE_KOR_KT) \ + || defined(CONFIG_MACH_P4NOTELTE_KOR_LGT) /*For 4G VT call in Domestic*/ + PREVIEW_SZ_VERTICAL_VGA, /* 480x640 */ +#endif PREVIEW_SZ_VGA, /* 640x480 */ PREVIEW_SZ_D1, /* 720x480 */ PREVIEW_SZ_880x720, /* 880x720 */ @@ -458,12 +463,12 @@ struct regset_table { const char *const name; }; -#define ISX012_REGSET(x, y) \ +#define ISX012_REGSET(x, y, z) \ [(x)] = { \ .name = #y, \ } -#define ISX012_REGSET_TABLE(y) \ +#define ISX012_REGSET_TABLE(y, z) \ { \ .name = #y, \ } @@ -476,31 +481,36 @@ struct regset_table { #ifdef DEBUG_WRITE_REGS const char * const name; #endif + const u32 burst; /* on/off */ }; #ifdef DEBUG_WRITE_REGS -#define ISX012_REGSET(x, y) \ +#define ISX012_REGSET(x, y, z) \ [(x)] = { \ .reg = (y), \ .array_size = ARRAY_SIZE((y)), \ .name = #y, \ + .burst = z, \ } -#define ISX012_REGSET_TABLE(y) \ +#define ISX012_REGSET_TABLE(y, z) \ { \ .reg = (y), \ .array_size = ARRAY_SIZE((y)), \ .name = #y, \ + .burst = z, \ } #else /* !DEBUG_WRITE_REGS */ -#define ISX012_REGSET(x, y) \ +#define ISX012_REGSET(x, y, z) \ [(x)] = { \ .reg = (y), \ .array_size = ARRAY_SIZE((y)), \ + .burst = z, \ } -#define ISX012_REGSET_TABLE(y) \ +#define ISX012_REGSET_TABLE(y, z) \ { \ .reg = (y), \ .array_size = ARRAY_SIZE((y)), \ + .burst = z, \ } #endif /* DEBUG_WRITE_REGS */ @@ -558,6 +568,11 @@ struct isx012_regs { struct regset_table init_reg; struct regset_table set_pll_4; + struct regset_table shading_0; + struct regset_table shading_1; + struct regset_table shading_2; + struct regset_table shading_nocal; + #ifdef CONFIG_VIDEO_ISX012_P8 struct regset_table antibanding; #endif /* CONFIG_VIDEO_ISX012_P8 */ @@ -658,7 +673,7 @@ extern int isx012_create_file(struct class *cls); #define ISX012_CNT_CM_CHECK 280 /* 160 -> 180 */ #define ISX012_CNT_STREAMOFF 300 -#define AF_SEARCH_COUNT 200 +#define AF_SEARCH_COUNT 550 /* about 6s */ #define AE_STABLE_SEARCH_COUNT 7 /* Sensor AF first,second window size. @@ -736,6 +751,10 @@ extern int isx012_create_file(struct class *cls); #define TUNING_FILE_PATH "/mnt/sdcard/isx012_regs.h" #endif /* CONFIG_LOAD_FILE*/ +#ifdef CONFIG_MACH_KONA +#include "isx012_regs_kona.h" +#else /* P4NOTE */ #include "isx012_regs.h" +#endif #endif /* __ISX012_H__ */ diff --git a/drivers/media/video/isx012_regs.h b/drivers/media/video/isx012_regs.h index fa8de0c..0bb1a28 100644 --- a/drivers/media/video/isx012_regs.h +++ b/drivers/media/video/isx012_regs.h @@ -28,7 +28,7 @@ /* change 4129 to 4802 */ #define AE_SCL_SUBRACT_VALUE 4802 -const uint16_t aeoffset_table[] = { // normal 4.6times +static const uint16_t aeoffset_table[] = { /* normal 4.6times */ 0, 35, 70, 103, 136, 167, 198, 228, 257, 285, 313, 339, 366, 391, 416, 441, 465, 488, 511, 533, 555, 576, 597, 618, 638, 657, 677, 696, 714, 732, @@ -4760,7 +4760,6 @@ static const isx012_regset_t isx012_720_Preview[] = { {0x0090,0x02D0,0x02}, //HSIZE_MONI : 720 {0x0096,0x01E0,0x02}, //VSIZE_MONI : 480 - }; static const isx012_regset_t isx012_640_Preview[] = @@ -4769,6 +4768,15 @@ static const isx012_regset_t isx012_640_Preview[] = {0x0096,0x01E0,0x02}, //VSIZE_MONI : 480 }; +#if defined(CONFIG_MACH_P4NOTELTE_KOR_SKT) \ + || defined(CONFIG_MACH_P4NOTELTE_KOR_KT) \ + || defined(CONFIG_MACH_P4NOTELTE_KOR_LGT) /*For 4G VT call in Domestic*/ +static const isx012_regset_t isx012_480_Preview[] = { +{0x0090, 0x01E0, 0x02}, /* HSIZE_MONI : 480 */ +{0x0096, 0x0280, 0x02}, /* VSIZE_MONI : 640 */ +}; +#endif + static const isx012_regset_t isx012_320_Preview[] = { {0x0090,0x0140,0x02}, //HSIZE_MONI : 320 @@ -11223,7 +11231,7 @@ static const isx012_regset_t ISX012_ae_manual_mode[] = static const isx012_regset_t ISX012_flash_fast_ae_awb[] = { {0x5E32,0x0A,0x01}, -{0x5E3D,0x05,0x01}, +{0x5E3D,0x05,0x01}, /* Don't fix me. 0x05 */ {0x0181,0x01,0x01}, // CAP_HALF_AE_CTRL {0x00B2,0x03,0x01}, //AFMODE_MONI : AF OFF diff --git a/drivers/media/video/isx012_regs_kona.h b/drivers/media/video/isx012_regs_kona.h new file mode 100644 index 0000000..9d9496b --- /dev/null +++ b/drivers/media/video/isx012_regs_kona.h @@ -0,0 +1,11284 @@ +/* drivers/media/video/s5k5ccgx_regs-p4w.h + * + * Driver for s5k5ccgx (5MP Camera) from SEC(LSI), firmware EVT1.1 + * + * Copyright (C) 2010, SAMSUNG ELECTRONICS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Change Date: 2012.06.28 + */ + +#ifndef __ISX012_REGS_H__ +#define __ISX012_REGS_H__ + +#define AE_OFSETVAL 3450 //for tuning // max 5.1times +#define AE_MAXDIFF 4000 //for tuning // max =< 5000 +#define GLOWLIGHT_DEFAULT 0x002B //for tuning +#define GLOWLIGHT_ISO50 0xB52A //for tuning +#define GLOWLIGHT_ISO100 0x9DBA //for tuning +#define GLOWLIGHT_ISO200 0x864A //for tuning +#define GLOWLIGHT_ISO400 0x738A //for tuning + +#define ESD_VALUE 0xA6A6 + +/* change 4129 to 4802 */ +#define AE_SCL_SUBRACT_VALUE 4802 + +static const uint16_t aeoffset_table[] = { /* normal 4.6times */ + 0, 35, 70, 103, 136, 167, 198, 228, 257, 285, + 313, 339, 366, 391, 416, 441, 465, 488, 511, 533, + 555, 576, 597, 618, 638, 657, 677, 696, 714, 732, + 750, 768, 785, 802, 818, 835, 851, 866, 882, 897, + 912, 927, 941, 955, 969, 983, 997, 1010, 1023, 1036, + 1049, 1061, 1074, 1086, 1098, 1109, 1121, 1133, 1144, 1155, + 1166, 1177, 1187, 1198, 1208, 1219, 1229, 1239, 1248, 1258, + 1268, 1277, 1286, 1296, 1305, 1314, 1322, 1331, 1340, 1348, + 1357, 1365, 1373, 1381, 1389, 1397, 1405, 1413, 1420, 1428, + 1435, 1443, 1450, 1457, 1464, 1471, 1478, 1485, 1492, 1499, + 1505, 1512, 1518, 1525, 1531, 1538, 1544, 1550, 1556, 1562, + 1568, 1574, 1580, 1585, 1591, 1597, 1602, 1608, 1613, 1619, + 1624, 1629, 1635, 1640, 1645, 1650, 1655, 1660, 1665, 1670, + 1675, 1679, 1684, 1689, 1693, 1698, 1703, 1707, 1712, 1716, + 1720, 1725, 1729, 1733, 1737, 1742, 1746, 1750, 1754, 1758, + 1762, 1766, 1770, 1774, 1777, 1781, 1785, 1789, 1792, 1796, + 1800, 1803, 1807, 1810, 1814, 1817, 1821, 1824, 1828, 1831, + 1834, 1837, 1841, 1844, 1847, 1850, 1853, 1856, 1860, 1863, + 1866, 1869, 1872, 1875, 1877, 1880, 1883, 1886, 1889, 1892, + 1894, 1897, 1900, 1903, 1905, 1908, 1911, 1913, 1916, 1918, + 1921, 1923, 1926, 1928, 1931, 1933, 1936, 1938, 1941, 1943, + 1945, 1948, 1950, 1952, 1954, 1957, 1959, 1961, 1963, 1965, + 1968, 1970, 1972, 1974, 1976, 1978, 1980, 1982, 1984, 1986, + 1988, 1990, 1992, 1994, 1996, 1998, 2000, 2002, 2003, 2005, + 2007, 2009, 2011, 2013, 2014, 2016, 2018, 2020, 2021, 2023, + 2025, 2026, 2028, 2030, 2031, 2033, 2034, 2036, 2038, 2039, + 2041, 2042, 2044, 2045, 2047, 2048, 2050, 2051, 2053, 2054, + 2056, 2057, 2059, 2060, 2061, 2063, 2064, 2066, 2067, 2068, + 2070, 2071, 2072, 2074, 2075, 2076, 2077, 2079, 2080, 2081, + 2082, 2084, 2085, 2086, 2087, 2089, 2090, 2091, 2092, 2093, + 2094, 2096, 2097, 2098, 2099, 2100, 2101, 2102, 2103, 2104, + 2105, 2106, 2107, 2109, 2110, 2111, 2112, 2113, 2114, 2115, + 2116, 2117, 2118, 2119, 2120, 2120, 2121, 2122, 2123, 2124, + 2125, 2126, 2127, 2128, 2129, 2130, 2130, 2131, 2132, 2133, + 2134, 2135, 2136, 2136, 2137, 2138, 2139, 2140, 2141, 2141, + 2142, 2143, 2144, 2144, 2145, 2146, 2147, 2148, 2148, 2149, + 2150, 2150, 2151, 2152, 2153, 2153, 2154, 2155, 2155, 2156, + 2157, 2158, 2158, 2159, 2160, 2160, 2161, 2162, 2162, 2163, + 2163, 2164, 2165, 2165, 2166, 2167, 2167, 2168, 2168, 2169, + 2170, 2170, 2171, 2171, 2172, 2172, 2173, 2174, 2174, 2175, + 2175, 2176, 2176, 2177, 2177, 2178, 2179, 2179, 2180, 2180, + 2181, 2181, 2182, 2182, 2183, 2183, 2184, 2184, 2185, 2185, + 2186, 2186, 2186, 2187, 2187, 2188, 2188, 2189, 2189, 2190, + 2190, 2191, 2191, 2191, 2192, 2192, 2193, 2193, 2194, 2194, + 2194, 2195, 2195, 2196, 2196, 2196, 2197, 2197, 2198, 2198, + 2198, 2199, 2199, 2200, 2200, 2200, 2201, 2201, 2201, 2202, + 2202, 2203, 2203, 2203, 2204, 2204, 2204, 2205, 2205, 2205, + 2206, 2206, 2206, 2207, 2207, 2207, 2208, 2208, 2208, 2209, + 2209, 2209, 2210, 2210, 2210, 2210, 2211, 2211, 2211, 2212, + 2212, 2212, 2213, 2213, 2213, 2213, 2214, 2214, 2214, 2214, +}; + +static const isx012_regset_t ISX012_Init_Reg[] = +{ +///////////////////////////////////// +//AF driver setting//³»ºÎ AF driver// +///////////////////////////////////// +{0x66C2,0x0C,0x01},//AF_INTERNAL_LENSDRV_ADRS +{0x66C3,0x02,0x01},//AF_INTERNAL_LENSDRV_SIZE +{0x66C5,0x14,0x01},//AF_INTERNAL_LENSDRV_SHIFT +{0x66C8,0x0000,0x02},//AF_INTERNAL_LENSDRV_FIXEDPTN +{0x66CA,0x000F,0x02}, +{0x000B,0x01,0x01},//AF_EXT : AF driver start + +////////////////////////////////////////// +// ISX012_Initial_Setting.ini // +////////////////////////////////////////// +// AE window add V02 +{0x6000,0x06,0x01}, // CENTER_FIXWEIGHT_00_TYPE1 : +{0x6001,0x06,0x01}, // CENTER_FIXWEIGHT_01_TYPE1 : +{0x6002,0x06,0x01}, // CENTER_FIXWEIGHT_02_TYPE1 : +{0x6003,0x06,0x01}, // CENTER_FIXWEIGHT_03_TYPE1 : +{0x6004,0x06,0x01}, // CENTER_FIXWEIGHT_04_TYPE1 : +{0x6005,0x06,0x01}, // CENTER_FIXWEIGHT_05_TYPE1 : +{0x6006,0x06,0x01}, // CENTER_FIXWEIGHT_06_TYPE1 : +{0x6007,0x06,0x01}, // CENTER_FIXWEIGHT_07_TYPE1 : +{0x6008,0x06,0x01}, // CENTER_FIXWEIGHT_08_TYPE1 : +{0x6009,0x0C,0x01}, // CENTER_FIXWEIGHT_09_TYPE1 : +{0x600A,0x0C,0x01}, // CENTER_FIXWEIGHT_10_TYPE1 : +{0x600B,0x0C,0x01}, // CENTER_FIXWEIGHT_11_TYPE1 : +{0x600C,0x10,0x01}, // CENTER_FIXWEIGHT_12_TYPE1 : +{0x600D,0x10,0x01}, // CENTER_FIXWEIGHT_13_TYPE1 : +{0x600E,0x10,0x01}, // CENTER_FIXWEIGHT_14_TYPE1 : +{0x600F,0x0C,0x01}, // CENTER_FIXWEIGHT_15_TYPE1 : +{0x6010,0x0C,0x01}, // CENTER_FIXWEIGHT_16_TYPE1 : +{0x6011,0x0C,0x01}, // CENTER_FIXWEIGHT_17_TYPE1 : +{0x6012,0x0C,0x01}, // CENTER_FIXWEIGHT_18_TYPE1 : +{0x6013,0x0C,0x01}, // CENTER_FIXWEIGHT_19_TYPE1 : +{0x6014,0x18,0x01}, // CENTER_FIXWEIGHT_20_TYPE1 : +{0x6015,0x18,0x01}, // CENTER_FIXWEIGHT_21_TYPE1 : +{0x6016,0x18,0x01}, // CENTER_FIXWEIGHT_22_TYPE1 : +{0x6017,0x18,0x01}, // CENTER_FIXWEIGHT_23_TYPE1 : +{0x6018,0x18,0x01}, // CENTER_FIXWEIGHT_24_TYPE1 : +{0x6019,0x0C,0x01}, // CENTER_FIXWEIGHT_25_TYPE1 : +{0x601A,0x0C,0x01}, // CENTER_FIXWEIGHT_26_TYPE1 : +{0x601B,0x0C,0x01}, // CENTER_FIXWEIGHT_27_TYPE1 : +{0x601C,0x18,0x01}, // CENTER_FIXWEIGHT_28_TYPE1 : +{0x601D,0x18,0x01}, // CENTER_FIXWEIGHT_29_TYPE1 : +{0x601E,0x1E,0x01}, // CENTER_FIXWEIGHT_30_TYPE1 : +{0x601F,0x1E,0x01}, // CENTER_FIXWEIGHT_31_TYPE1 : +{0x6020,0x1E,0x01}, // CENTER_FIXWEIGHT_32_TYPE1 : +{0x6021,0x18,0x01}, // CENTER_FIXWEIGHT_33_TYPE1 : +{0x6022,0x18,0x01}, // CENTER_FIXWEIGHT_34_TYPE1 : +{0x6023,0x0C,0x01}, // CENTER_FIXWEIGHT_35_TYPE1 : +{0x6024,0x0C,0x01}, // CENTER_FIXWEIGHT_36_TYPE1 : +{0x6025,0x18,0x01}, // CENTER_FIXWEIGHT_37_TYPE1 : +{0x6026,0x18,0x01}, // CENTER_FIXWEIGHT_38_TYPE1 : +{0x6027,0x1E,0x01}, // CENTER_FIXWEIGHT_39_TYPE1 : +{0x6028,0x1E,0x01}, // CENTER_FIXWEIGHT_40_TYPE1 : +{0x6029,0x1E,0x01}, // CENTER_FIXWEIGHT_41_TYPE1 : +{0x602A,0x18,0x01}, // CENTER_FIXWEIGHT_42_TYPE1 : +{0x602B,0x18,0x01}, // CENTER_FIXWEIGHT_43_TYPE1 : +{0x602C,0x0C,0x01}, // CENTER_FIXWEIGHT_44_TYPE1 : +{0x602D,0x0C,0x01}, // CENTER_FIXWEIGHT_45_TYPE1 : +{0x602E,0x0C,0x01}, // CENTER_FIXWEIGHT_46_TYPE1 : +{0x602F,0x18,0x01}, // CENTER_FIXWEIGHT_47_TYPE1 : +{0x6030,0x18,0x01}, // CENTER_FIXWEIGHT_48_TYPE1 : +{0x6031,0x18,0x01}, // CENTER_FIXWEIGHT_49_TYPE1 : +{0x6032,0x18,0x01}, // CENTER_FIXWEIGHT_50_TYPE1 : +{0x6033,0x18,0x01}, // CENTER_FIXWEIGHT_51_TYPE1 : +{0x6034,0x0C,0x01}, // CENTER_FIXWEIGHT_52_TYPE1 : +{0x6035,0x0C,0x01}, // CENTER_FIXWEIGHT_53_TYPE1 : +{0x6036,0x0C,0x01}, // CENTER_FIXWEIGHT_54_TYPE1 : +{0x6037,0x0C,0x01}, // CENTER_FIXWEIGHT_55_TYPE1 : +{0x6038,0x0C,0x01}, // CENTER_FIXWEIGHT_56_TYPE1 : +{0x6039,0x0C,0x01}, // CENTER_FIXWEIGHT_57_TYPE1 : +{0x603A,0x0C,0x01}, // CENTER_FIXWEIGHT_58_TYPE1 : +{0x603B,0x0C,0x01}, // CENTER_FIXWEIGHT_59_TYPE1 : +{0x603C,0x0C,0x01}, // CENTER_FIXWEIGHT_60_TYPE1 : +{0x603D,0x0C,0x01}, // CENTER_FIXWEIGHT_61_TYPE1 : +{0x603E,0x0C,0x01}, // CENTER_FIXWEIGHT_62_TYPE1 : + + +//AF filter +{0x6D14,0x0001,0x02}, // HPF_HBPF_CORSL_Y1 : +{0x6D16,0x0001,0x02}, // HPF_HBPF_CORSL_Y2 : +{0x6D18,0x0002,0x02}, // HPF_HBPF_CORSL_Y3 : +{0x6D1A,0x0005,0x02}, // HPF_HBPF_CORSL_Y4 : + +{0x6D20,0x0004,0x02}, // HPF_HBPF_CORL_Y1 : +{0x6D22,0x0004,0x02}, // HPF_HBPF_CORL_Y2 : +{0x6D24,0x000F,0x02}, // HPF_HBPF_CORL_Y3 : +{0x6D26,0x001E,0x02}, // HPF_HBPF_CORL_Y4 : + +{0x6D2C,0x000E,0x02}, // HPF_HBPF_CORH_Y1 : +{0x6D2E,0x000F,0x02}, // HPF_HBPF_CORH_Y2 : +{0x6D30,0x0022,0x02}, // HPF_HBPF_CORH_Y3 : +{0x6D32,0x004D,0x02}, // HPF_HBPF_CORH_Y4 : + +{0x6D44,0x0001,0x02}, // HPF_LBPF_CORSL_Y1 : +{0x6D46,0x0001,0x02}, // HPF_LBPF_CORSL_Y2 : +{0x6D48,0x0002,0x02}, // HPF_LBPF_CORSL_Y3 : +{0x6D4A,0x0004,0x02}, // HPF_LBPF_CORSL_Y4 : + +{0x6D50,0x03FF,0x02}, // HPF_LBPF_CORL_Y1 : +{0x6D52,0x03FF,0x02}, // HPF_LBPF_CORL_Y2 : +{0x6D54,0x03FF,0x02}, // HPF_LBPF_CORL_Y3 : +{0x6D56,0x03FF,0x02}, // HPF_LBPF_CORL_Y4 : + +{0x6D5C,0x03FF,0x02}, // HPF_LBPF_CORH_Y1 : +{0x6D5E,0x03FF,0x02}, // HPF_LBPF_CORH_Y2 : +{0x6D60,0x03FF,0x02}, // HPF_LBPF_CORH_Y3 : +{0x6D62,0x03FF,0x02}, // HPF_LBPF_CORH_Y4 : + +{0x6D74,0x0001,0x02}, // HPF_VHBPF_CORSL_Y1 : +{0x6D76,0x0001,0x02}, // HPF_VHBPF_CORSL_Y2 : +{0x6D78,0x0002,0x02}, // HPF_VHBPF_CORSL_Y3 : +{0x6D7A,0x0005,0x02}, // HPF_VHBPF_CORSL_Y4 : + +{0x6D80,0x0004,0x02}, // HPF_VHBPF_CORL_Y1 : +{0x6D82,0x0005,0x02}, // HPF_VHBPF_CORL_Y2 : +{0x6D84,0x000C,0x02}, // HPF_VHBPF_CORL_Y3 : +{0x6D86,0x001C,0x02}, // HPF_VHBPF_CORL_Y4 : + +{0x6D8C,0x000D,0x02}, // HPF_VHBPF_CORH_Y1 : +{0x6D8E,0x0010,0x02}, // HPF_VHBPF_CORH_Y2 : +{0x6D90,0x0026,0x02}, // HPF_VHBPF_CORH_Y3 : +{0x6D92,0x004D,0x02}, // HPF_VHBPF_CORH_Y4 : + +// CAF Ãß°¡ºÎºÐ +{0x6622,0x0004,0x02}, // AF_CAF_PARAM_WOBBLE_STEP : +{0x6624,0x0008,0x02}, // AF_CAF_CLIMB_STEP : +{0x6687,0x01,0x01}, // AF_CAF_CLIMB_PEAK_BACK_STEP_ENABLE : +{0x6698,0x00,0x01}, // AF_CAF_WOBBLE_FILTER_ENABLE : +{0x66A4,0x06,0x01}, // AF_CAF_OPD_FLAT_MOVE_ENABLE : +{0x66B0,0x0002,0x02}, // AF_CAF_WAIT_FOR_AF_STABLE_TH : +{0x5003,0x04,0x01}, // Z1_HOLD = 1 +//110819 +{0x6696,0x16,0x01}, //AF_CAF_WOBBLE_START_INTERVAL_COUNTER +{0x6716,0x0000,0x02}, // CAF_LVD_WOB_HBPF_VAL1 : +{0x6718,0x0000,0x02}, // CAF_LVD_WOB_HBPF_VAL2 : +{0x671A,0x00C8,0x02}, // CAF_LVD_WOB_HBPF_RATE1 : +{0x671C,0x00C8,0x02}, // CAF_LVD_WOB_HBPF_RATE2 : +{0x671E,0x00,0x01}, // CAF_LVD_WOB_HBPF_SHIFT : +{0x6720,0x0000,0x02}, // CAF_LVD_WOB_LBPF_VAL1 : +{0x6722,0x0000,0x02}, // CAF_LVD_WOB_LBPF_VAL2 : +{0x6724,0x0014,0x02}, // CAF_LVD_WOB_LBPF_RATE1 : +{0x6726,0x0014,0x02}, // CAF_LVD_WOB_LBPF_RATE2 : +{0x6728,0x00,0x01}, // CAF_LVD_WOB_LBPF_SHIFT : +{0x672A,0x0000,0x02}, // CAF_LVD_CLMP_HBPF_VAL1 : +{0x672C,0x0000,0x02}, // CAF_LVD_CLMP_HBPF_VAL2 : +{0x672E,0x012C,0x02}, // CAF_LVD_CLMP_HBPF_RATE1 : +{0x6730,0x012C,0x02}, // CAF_LVD_CLMP_HBPF_RATE2 : +{0x6732,0x00,0x01}, // CAF_LVD_CLMP_HBPF_SHIFT : +{0x6734,0x0000,0x02}, // CAF_LVD_CLMP_LBPF_VAL1 : +{0x6736,0x0000,0x02}, // CAF_LVD_CLMP_LBPF_VAL2 : +{0x6738,0x0046,0x02}, // CAF_LVD_CLMP_LBPF_RATE1 : +{0x673A,0x0046,0x02}, // CAF_LVD_CLMP_LBPF_RATE2 : +{0x673C,0x00,0x01}, // CAF_LVD_CLMP_LBPF_SHIFT : +{0x661E,0x00C8,0x02}, //AF_CAF_FAR_POSITION +{0x6620,0x02BC,0x02}, //AF_CAF_NEAR_POSITION + +//Ãß°¡¼ÂÆúκРSAFºÎºÐ +{0x00B2,0x02,0x01}, // AFMODE_MONI : manual AF mode +{0x028E,0x00,0x01}, // AF_SN1_2 : +{0x028F,0x00,0x01}, // AF_SN3_4 : +{0x0290,0x00,0x01}, // AF_SN5_6 : +{0x0291,0x00,0x01}, // AF_SN7_8 : +{0x0292,0x00,0x01}, // AF_SN9_10 : +{0x0293,0x00,0x01}, // AF_SN11_12 : +{0x6604,0x00,0x01}, // AF_SEARCH_DIR : +{0x6616,0x01,0x01}, // AF_DIRECTBACK_F :On=1 +{0x661B,0x03,0x01}, // AF_OPDDATA_SAVE : +{0x661C,0x00,0x01}, // AF_MONOTONY_POS : +{0x663E,0x00,0x01}, // AF_SEARCH_SECOND_DIR : +{0x663F,0x01,0x01}, // AF_DIRECTBACK_SECOND_F : +{0x6674,0x00,0x01}, // AF_MONICHG_MOVE_F : AF off½Ã zero positionÀ¸·Î °¥Áö(01) ÇöÀ§Ä¡¿¡ ÀÖÀ»Áö(00) Á¤ÇÔ +{0x6675,0x01,0x01}, // CAP_AF_CANCEL_F : 1·Î ¼³Á¤½Ã capture¸ðµå¿¡¼­ AFÀÚµ¿ ĵ½½ +{0x6676,0x02,0x01}, // AF_SAxF_MODE : +{0x669E,0x02,0x01}, // AF_SECOND_WND_CHK : +{0x6600,0x00C8,0x02}, // AF_SEARCH_AREA_LOW : +{0x6602,0x02BC,0x02}, // AF_SEARCH_AREA_HIGH : +{0x6640,0x02,0x01}, // AF_DROPN_ON_PEAK_DETECT_SECOND : +{0x6641,0x02,0x01}, // AF_UPN_ON_PEAK_DETECT_SECOND : +{0x6642,0x02,0x01}, //AF_DROPRATE_ON_DETECT_SECOND_HBPF +{0x6643,0x02,0x01}, //AF_DROPRATE_ON_DETECT_SECOND_LBPF +{0x6644,0x14,0x01}, // AF_UPRATE_ON_PEAK_DETECT_HBPF_SECOND : +{0x6646,0x08,0x01}, // AF_OPD_WEIGHT_TH : +{0x664A,0x04,0x01}, // AF_DROPN_ON_PEAK_DETECT : +{0x664B,0x02,0x01}, // AF_UPN_ON_PEAK_DETECT : +{0x664C,0xFF,0x01}, // AF_UPRATE_ON_PEAK_DETECT_HBPF : +{0x665A,0x00C8,0x02}, // AF_LENSPOS_ON_AFNG : +{0x665C,0x0018,0x02}, // AF_DRV_AMOUNT_TONEAR_F : +{0x665E,0x0003,0x02}, // AF_DRV_AMOUNT_TONEAR_S : +{0x6660,0x0018,0x02}, // AF_DRV_AMOUNT_TOFAR_F : +{0x6662,0x0003,0x02}, // AF_DRV_AMOUNT_TOFAR_S : +{0x6666,0x00C8,0x02}, // AF_AREA_LOW_TYPE1 : +{0x6668,0x02BC,0x02}, // AF_AREA_HIGH_TYPE1 : +{0x669A,0x01F4,0x02}, // AF_OPD_MONOTONYUP_HBPF_TH : +{0x66E4,0x50,0x01}, // AF_TH_1STDEPEND_HBPF_RATE : +{0x66EE,0x03E8,0x02}, // AF_LVD_HBPF_VAL1_1ST : +{0x66F0,0x4E20,0x02}, // AF_LVD_HBPF_VAL2_1ST : +{0x66F2,0x004C,0x02}, // AF_LVD_HBPF_RATE1_1ST : +{0x66F4,0x0019,0x02}, // AF_LVD_HBPF_RATE2_1ST : +{0x66F6,0x00,0x01}, // AF_LVD_HBPF_SHIFT_1ST : +{0x6702,0x03E8,0x02}, // AF_LVD_HBPF_VAL1_2ND : +{0x6704,0x4E20,0x02}, // AF_LVD_HBPF_VAL2_2ND : +{0x6706,0x0003,0x02}, // AF_LVD_HBPF_RATE1_2ND : +{0x6708,0x0003,0x02}, // AF_LVD_HBPF_RATE2_2ND : +{0x670A,0x00,0x01}, // AF_LVD_HBPF_SHIFT_2ND : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : +//chooys add +{0x6677,0x00,0x01}, // AF_SEND_PARTITION : Use=1 +{0x6678,0x20,0x01}, // AF_SENDNUM_ALL +{0x6679,0x01,0x01}, // AF_SENDNUM_UP +{0x667A,0x01,0x01}, // AF_SENDNUM_DOWN +{0x667C,0x0002,0x02}, // AF_SENDAMOUNT_ADDLIMIT +{0x667E,0x0020,0x02}, //AF_SENDLINE + +// AF opd_TH +{0x660E,0x5A,0x01}, // AF_HBPF_PEAK_OPD_TH_MIN +{0x6610,0x5A,0x01}, // AF_HBPF_PEAK_OPD_TH_MAX + +{0x66E4,0xC8,0x01}, +{0x66E5,0xC8,0x01}, + +//AF opd window setting +{0x6A30,0x044E,0x02}, // AF_OPD0_HDELAY : +{0x6A32,0x02E5,0x02}, // AF_OPD0_VDELAY : +{0x6A34,0x01D8,0x02}, // AF_OPD0_HVALID : +{0x6A36,0x01D8,0x02}, // AF_OPD0_VVALID : +{0x6A38,0x0412,0x02}, // AF_OPD1_HDELAY : +{0x6A3A,0x02A9,0x02}, // AF_OPD1_VDELAY : +{0x6A3C,0x0251,0x02}, // AF_OPD1_HVALID : +{0x6A3E,0x0251,0x02}, // AF_OPD1_VVALID : +{0x6A40,0x04B4,0x02}, // AF_OPD2_HDELAY : +{0x6A42,0x0114,0x02}, // AF_OPD2_VDELAY : +{0x6A44,0x0118,0x02}, // AF_OPD2_HVALID : +{0x6A46,0x0118,0x02}, // AF_OPD2_VVALID : +{0x6A48,0x0469,0x02}, // AF_OPD3_HDELAY : +{0x6A4A,0x00C9,0x02}, // AF_OPD3_VDELAY : +{0x6A4C,0x01AE,0x02}, // AF_OPD3_HVALID : +{0x6A4E,0x01AE,0x02}, // AF_OPD3_VVALID : +{0x6A50,0x04C6,0x02}, // AF_OPD4_HDELAY : +{0x6A52,0x035D,0x02}, // AF_OPD4_VDELAY : +{0x6A54,0x00E6,0x02}, // AF_OPD4_HVALID : +{0x6A56,0x00E6,0x02}, // AF_OPD4_VVALID : +{0x6A58,0x048A,0x02}, // AF_OPD5_HDELAY : +{0x6A5A,0x0321,0x02}, // AF_OPD5_VDELAY : +{0x6A5C,0x015F,0x02}, // AF_OPD5_HVALID : +{0x6A5E,0x015F,0x02}, // AF_OPD5_VVALID : +{0x6A60,0x04B4,0x02}, // AF_OPD6_HDELAY : +{0x6A62,0x0579,0x02}, // AF_OPD6_VDELAY : +{0x6A64,0x0118,0x02}, // AF_OPD6_HVALID : +{0x6A66,0x0118,0x02}, // AF_OPD6_VVALID : +{0x6A68,0x0469,0x02}, // AF_OPD7_HDELAY : +{0x6A6A,0x052C,0x02}, // AF_OPD7_VDELAY : +{0x6A6C,0x01AE,0x02}, // AF_OPD7_HVALID : +{0x6A6E,0x01AE,0x02}, // AF_OPD7_VVALID : +{0x6A70,0x021D,0x02}, // AF_OPD8_HDELAY : +{0x6A72,0x02F5,0x02}, // AF_OPD8_VDELAY : +{0x6A74,0x01AE,0x02}, // AF_OPD8_HVALID : +{0x6A76,0x01AE,0x02}, // AF_OPD8_VVALID : +{0x6A78,0x06A4,0x02}, // AF_OPD9_HDELAY : +{0x6A7A,0x02F5,0x02}, // AF_OPD9_VDELAY : +{0x6A7C,0x01AE,0x02}, // AF_OPD9_HVALID : +{0x6A7E,0x01AE,0x02}, // AF_OPD9_VVALID : +{0x6A80,0x06,0x01}, // AF_OPD1A_WEIGHT : +{0x6A81,0x05,0x01}, // AF_OPD1B_WEIGHT : +{0x6A82,0x02,0x01}, // AF_OPD2A_WEIGHT : +{0x6A83,0x02,0x01}, // AF_OPD2B_WEIGHT : +{0x6A84,0x08,0x01}, // AF_OPD3A_WEIGHT : +{0x6A85,0x07,0x01}, // AF_OPD3B_WEIGHT : +{0x6A86,0x04,0x01}, // AF_OPD4A_WEIGHT : +{0x6A87,0x03,0x01}, // AF_OPD4B_WEIGHT : +{0x6A88,0x01,0x01}, // AF_OPD5A_WEIGHT : +{0x6A89,0x01,0x01}, // AF_OPD5B_WEIGHT : + + +//lee haknoh add +{0x661C,0x00,0x01}, +//S,66BE,0F,8, //AF_JUDGE_CONF +//S,669A,01F4,16, //AF_OPD_MONOTONYUP_HBPF_TH +//S,669C,03E8,16, //AF_OPD_MONOTONYUP_LBPF_TH +{0x673D,0x01,0x01}, //AF_MANUAL_MOVE_TYTPE : manual mode½Ã AF_MANUAL_POS·Î À̵¿ÇÒÁö ¼³Á¤ +{0x6648,0x00C8,0x02}, //AF_MANUAL_POS +{0x66E0,0x00C8,0x02}, //AF_POS_INF_SET +{0x66E2,0x02BC,0x02}, //AF_POS_MACRO_SET +{0x00B2,0x02,0x01}, //AFMODE_MONI : Manual AF mode + + +//Ãß°¡ ¼¼Æà ºÎºÐ +{0x00F7,0x52,0x01}, // INIT_QLTY0 : Standard 82 +{0x00F8,0x59,0x01}, // INIT_QLTY1 : Fine 89 +{0x00F9,0x5F,0x01}, // INIT_QLTY2 : SuperFine 95 + +//minimum shutter speed +{0x6800,0x03,0x01}, //SHTMINLINE + +/////// Normal AE Line ////// +// normal capture AE line +{0x0326,0x21,0x01}, // SHTCTRLTIME1_TYPE1 : +{0x0327,0x19,0x01}, // AGCGAIN1_TYPE1 : +{0x0328,0x52,0x01}, // SHTCTRLTIME2_TYPE1 : +{0x0329,0x23,0x01}, // AGCGAIN2_TYPE1 : +{0x032A,0x3E,0x01}, // SHTCTRLTIME3_TYPE1 : +{0x032B,0x3F,0x01}, // AGCGAIN3_TYPE1 : + +// normal preview AE line +{0x032C,0x7C,0x01}, // SHTCTRLTIME1_TYPE2 +{0x032D,0x3D,0x01}, // AGCGAIN1_TYPE2 +{0x032E,0x7C,0x01}, // SHTCTRLTIME2_TYPE2 +{0x032F,0x3D,0x01}, // AGCGAIN2_TYPE2 +{0x0330,0x3E,0x01}, // SHTCTRLTIME3_TYPE2 +{0x0331,0x3F,0x01}, // AGCGAIN3_TYPE2 + +// flash ae line +{0x0332,0x42,0x01}, // SHTCTRLTIME1_TYPE3 : +{0x0333,0x3C,0x01}, // AGCGAIN1_TYPE3 : +{0x0334,0x42,0x01}, // SHTCTRLTIME2_TYPE3 : +{0x0335,0x3C,0x01}, // AGCGAIN2_TYPE3 : +{0x0336,0x21,0x01}, // SHTCTRLTIME3_TYPE3 : +{0x0337,0x3C,0x01}, // AGCGAIN3_TYPE3 : + +//sports ae line +{0x0338,0x00,0x01}, // SHTCTRLTIME1_TYPE4 +{0x0339,0x14,0x01}, // AGCGAIN1_TYPE4 +{0x033A,0x21,0x01}, // SHTCTRLTIME2_TYPE4 +{0x033B,0x19,0x01}, // AGCGAIN2_TYPE4 +{0x033C,0x3E,0x01}, // SHTCTRLTIME3_TYPE4 +{0x033D,0x3D,0x01}, // AGCGAIN3_TYPE4 + +//night mode AF ae line +{0x033E,0xFF,0x01}, // SHTCTRLTIME1_TYPE5 : +{0x033F,0x00,0x01}, // AGCGAIN1_TYPE5 : +{0x0340,0xFF,0x01}, // SHTCTRLTIME2_TYPE5 : +{0x0341,0x00,0x01}, // AGCGAIN2_TYPE5 : +{0x0342,0xA6,0x01}, // SHTCTRLTIME3_TYPE5 : +{0x0343,0x49,0x01}, // AGCGAIN3_TYPE5 : + +//night mode capture ae line +{0x0344,0xFF,0x01}, // SHTCTRLTIME1_TYPE6 : +{0x0345,0x00,0x01}, // AGCGAIN1_TYPE6 : +{0x0346,0xFF,0x01}, // SHTCTRLTIME2_TYPE6 : +{0x0347,0x00,0x01}, // AGCGAIN2_TYPE6 : +{0x0348,0xFA,0x01}, // SHTCTRLTIME3_TYPE6 : +{0x0349,0x3B,0x01}, // AGCGAIN3_TYPE6 : + +// fire mode line +{0x0356,0x01,0x01}, // SHTCTRLTIME1_TYPE9 : +{0x0357,0x04,0x01}, // AGCGAIN1_TYPE9 : +{0x0358,0x01,0x01}, // SHTCTRLTIME2_TYPE9 : +{0x0359,0x04,0x01}, // AGCGAIN2_TYPE9 : +{0x035A,0xF8,0x01}, // SHTCTRLTIME3_TYPE9 : +{0x035B,0x04,0x01}, // AGCGAIN3_TYPE9 : + +// fire mode AF line +{0x035C,0x01,0x01}, // SHTCTRLTIME1_TYPE10 : +{0x035D,0x04,0x01}, // AGCGAIN1_TYPE10 : +{0x035E,0x01,0x01}, // SHTCTRLTIME2_TYPE10 : +{0x035F,0x04,0x01}, // AGCGAIN2_TYPE10 : +{0x0360,0x21,0x01}, // SHTCTRLTIME3_TYPE10 : +{0x0361,0x3E,0x01}, // AGCGAIN3_TYPE10 : + + +//AE ref tunning +{0x5E8A,0x02,0x01}, // EVREF_GAIN_A : +{0x5E8B,0x02,0x01}, // EVREF_GAIN_B : +{0x5E8C,0xFD,0x01}, // EVREF_GAIN_C : +{0x5E8D,0xFD,0x01}, // EVREF_GAIN_D : +{0x5E8E,0xFD,0x01}, // EVREF_GAIN_E : +{0x5E8F,0x90,0x01}, // EVREF_TH_A : +{0x5E90,0x94,0x01}, // EVREF_TH_B : +{0x5E91,0xA5,0x01}, // EVREF_TH_C : +{0x5E92,0xC0,0x01}, // EVREF_TH_D : +{0x5E93,0xD5,0x01}, // EVREF_TH_E : + + +//gamma Ilumi +{0x9211,0x58,0x01}, // GAIN_TH_A_TYPE3 : +{0x9212,0x63,0x01}, // GAIN_TH_B_TYPE3 : +{0x9213,0x9F,0x01}, // GAIN_TH_C_TYPE3 : + +{0x984E,0x0A,0x01}, // GAMMA0_0CLIP_A : +{0x984F,0x0A,0x01}, // GAMMA0_0CLIP_B : +{0x9850,0x05,0x01}, // GAMMA0_0CLIP_C : +{0x9851,0x1E,0x01}, // GAMMA0_SLOPE_A : +{0x9852,0x1E,0x01}, // GAMMA0_SLOPE_B : +{0x9853,0x1E,0x01}, // GAMMA0_SLOPE_C : +{0x9854,0x0A,0x01}, // GAMMA1_0CLIP_A : +{0x9855,0x0F,0x01}, // GAMMA1_0CLIP_B : +{0x9856,0x0F,0x01}, // GAMMA1_0CLIP_C : +{0x9857,0x32,0x01}, // GAMMA1_SLOPE_A : +{0x9858,0x1E,0x01}, // GAMMA1_SLOPE_B : +{0x9859,0x1E,0x01}, // GAMMA1_SLOPE_C : + + +//Gammma Table 0 +{0x7000,0x0000,0x02}, // G0_KNOT_G0 : +{0x7002,0x0015,0x02}, // G0_KNOT_G1 : +{0x7004,0x002C,0x02}, // G0_KNOT_G2 : +{0x7006,0x0041,0x02}, // G0_KNOT_G3 : +{0x7008,0x004D,0x02}, // G0_KNOT_G4 : +{0x700A,0x005B,0x02}, // G0_KNOT_G5 : +{0x700C,0x0060,0x02}, // G0_KNOT_G6 : +{0x700E,0x0068,0x02}, // G0_KNOT_G7 : +{0x7010,0x006F,0x02}, // G0_KNOT_G8 : +{0x7012,0x0078,0x02}, // G0_KNOT_G9 : +{0x7014,0x0057,0x02}, // G0_KNOT_G10 : +{0x7016,0x0090,0x02}, // G0_KNOT_G11 : +{0x7018,0x00BB,0x02}, // G0_KNOT_G12 : +{0x701A,0x00D6,0x02}, // G0_KNOT_G13 : +{0x701C,0x00E5,0x02}, // G0_KNOT_G14 : +{0x701E,0x00F0,0x02}, // G0_KNOT_G15 : +{0x7020,0x00F9,0x02}, // G0_KNOT_G16 : +{0x7022,0x0103,0x02}, // G0_KNOT_G17 : +{0x7024,0x010C,0x02}, // G0_KNOT_G18 : +{0x7026,0x00,0x01}, // G0_KNOT_R0_OFFSET : +{0x7027,0x00,0x01}, // G0_KNOT_R2_OFFSET : +{0x7028,0x00,0x01}, // G0_KNOT_R4_OFFSET : +{0x7029,0x00,0x01}, // G0_KNOT_R6_OFFSET : +{0x702A,0x00,0x01}, // G0_KNOT_R8_OFFSET : +{0x702B,0x00,0x01}, // G0_KNOT_R10_OFFSET : +{0x702C,0x00,0x01}, // G0_KNOT_R12_OFFSET : +{0x702D,0x00,0x01}, // G0_KNOT_R14_OFFSET : +{0x702E,0x00,0x01}, // G0_KNOT_R16_OFFSET : +{0x702F,0x00,0x01}, // G0_KNOT_R18_OFFSET : +{0x7030,0x00,0x01}, // G0_KNOT_B0_OFFSET : +{0x7031,0x00,0x01}, // G0_KNOT_B2_OFFSET : +{0x7032,0x00,0x01}, // G0_KNOT_B4_OFFSET : +{0x7033,0x00,0x01}, // G0_KNOT_B6_OFFSET : +{0x7034,0x00,0x01}, // G0_KNOT_B8_OFFSET : +{0x7035,0x00,0x01}, // G0_KNOT_B10_OFFSET : +{0x7036,0x00,0x01}, // G0_KNOT_B12_OFFSET : +{0x7037,0x00,0x01}, // G0_KNOT_B14_OFFSET : +{0x7038,0x00,0x01}, // G0_KNOT_B16_OFFSET : +{0x7039,0x00,0x01}, // G0_KNOT_B18_OFFSET : +{0x703A,0x0611,0x02}, // G0_LOWGM_ON_R : +{0x703C,0x1E0A,0x02}, // G0_0CLIP_R : +{0x703E,0x0611,0x02}, // G0_LOWGM_ON_G : +{0x7040,0x1E0A,0x02}, // G0_0CLIP_G : +{0x7042,0x0611,0x02}, // G0_LOWGM_ON_B : +{0x7044,0x1E0A,0x02}, // G0_0CLIP_B : +{0x7046,0x9C,0x01}, // G0_KNOT_GAINCTRL_TH_L : +{0x7047,0xA1,0x01}, // G0_KNOT_GAINCTRL_TH_H : +{0x7048,0x0000,0x02}, // G0_KNOT_L_G0 : +{0x704A,0x0007,0x02}, // G0_KNOT_L_G1 : +{0x704C,0x0016,0x02}, // G0_KNOT_L_G2 : +{0x704E,0x002A,0x02}, // G0_KNOT_L_G3 : +{0x7050,0x0039,0x02}, // G0_KNOT_L_G4 : +{0x7052,0x004A,0x02}, // G0_KNOT_L_G5 : +{0x7054,0x0051,0x02}, // G0_KNOT_L_G6 : +{0x7056,0x005D,0x02}, // G0_KNOT_L_G7 : +{0x7058,0x0065,0x02}, // G0_KNOT_L_G8 : +{0x705A,0x006C,0x02}, // G0_KNOT_L_G9 : +{0x705C,0x004E,0x02}, // G0_KNOT_L_G10 : +{0x705E,0x0083,0x02}, // G0_KNOT_L_G11 : +{0x7060,0x00AA,0x02}, // G0_KNOT_L_G12 : +{0x7062,0x00C8,0x02}, // G0_KNOT_L_G13 : +{0x7064,0x00E1,0x02}, // G0_KNOT_L_G14 : +{0x7066,0x00F5,0x02}, // G0_KNOT_L_G15 : +{0x7068,0x0100,0x02}, // G0_KNOT_L_G16 : +{0x706A,0x0106,0x02}, // G0_KNOT_L_G17 : +{0x706C,0x010C,0x02}, // G0_KNOT_L_G18 : + +//Gammma Table 1 +{0x7200,0x0000,0x02}, // G1_KNOT_G0 : +{0x7202,0x0008,0x02}, // G1_KNOT_G1 : +{0x7204,0x0020,0x02}, // G1_KNOT_G2 : +{0x7206,0x0037,0x02}, // G1_KNOT_G3 : +{0x7208,0x004D,0x02}, // G1_KNOT_G4 : +{0x720A,0x0064,0x02}, // G1_KNOT_G5 : +{0x720C,0x006E,0x02}, // G1_KNOT_G6 : +{0x720E,0x0072,0x02}, // G1_KNOT_G7 : +{0x7210,0x007A,0x02}, // G1_KNOT_G8 : +{0x7212,0x007E,0x02}, // G1_KNOT_G9 : +{0x7214,0x0064,0x02}, // G1_KNOT_G10 : +{0x7216,0x0093,0x02}, // G1_KNOT_G11 : +{0x7218,0x00B7,0x02}, // G1_KNOT_G12 : +{0x721A,0x00CD,0x02}, // G1_KNOT_G13 : +{0x721C,0x00DD,0x02}, // G1_KNOT_G14 : +{0x721E,0x00ED,0x02}, // G1_KNOT_G15 : +{0x7220,0x00F9,0x02}, // G1_KNOT_G16 : +{0x7222,0x0102,0x02}, // G1_KNOT_G17 : +{0x7224,0x0101,0x02}, // G1_KNOT_G18 : +{0x7226,0x00,0x01}, // G1_KNOT_R0_OFFSET : +{0x7227,0x00,0x01}, // G1_KNOT_R2_OFFSET : +{0x7228,0x00,0x01}, // G1_KNOT_R4_OFFSET : +{0x7229,0x00,0x01}, // G1_KNOT_R6_OFFSET : +{0x722A,0x00,0x01}, // G1_KNOT_R8_OFFSET : +{0x722B,0x00,0x01}, // G1_KNOT_R10_OFFSET : +{0x722C,0x00,0x01}, // G1_KNOT_R12_OFFSET : +{0x722D,0x00,0x01}, // G1_KNOT_R14_OFFSET : +{0x722E,0x00,0x01}, // G1_KNOT_R16_OFFSET : +{0x722F,0x00,0x01}, // G1_KNOT_R18_OFFSET : +{0x7230,0x00,0x01}, // G1_KNOT_B0_OFFSET : +{0x7231,0x00,0x01}, // G1_KNOT_B2_OFFSET : +{0x7232,0x00,0x01}, // G1_KNOT_B4_OFFSET : +{0x7233,0x00,0x01}, // G1_KNOT_B6_OFFSET : +{0x7234,0x00,0x01}, // G1_KNOT_B8_OFFSET : +{0x7235,0x00,0x01}, // G1_KNOT_B10_OFFSET : +{0x7236,0x00,0x01}, // G1_KNOT_B12_OFFSET : +{0x7237,0x00,0x01}, // G1_KNOT_B14_OFFSET : +{0x7238,0x00,0x01}, // G1_KNOT_B16_OFFSET : +{0x7239,0x00,0x01}, // G1_KNOT_B18_OFFSET : +{0x723A,0x0321,0x02}, // G1_LOWGM_ON_R : +{0x723C,0x0C00,0x02}, // G1_0CLIP_R : +{0x723E,0x0321,0x02}, // G1_LOWGM_ON_G : +{0x7240,0x0C00,0x02}, // G1_0CLIP_G : +{0x7242,0x0321,0x02}, // G1_LOWGM_ON_B : +{0x7244,0x0C00,0x02}, // G1_0CLIP_B : + + +//Gammma Table 2 +{0x7400,0x0000,0x02}, // G2_KNOT_G0 : +{0x7402,0x000A,0x02}, // G2_KNOT_G1 : +{0x7404,0x0023,0x02}, // G2_KNOT_G2 : +{0x7406,0x0038,0x02}, // G2_KNOT_G3 : +{0x7408,0x003F,0x02}, // G2_KNOT_G4 : +{0x740A,0x0047,0x02}, // G2_KNOT_G5 : +{0x740C,0x004F,0x02}, // G2_KNOT_G6 : +{0x740E,0x0058,0x02}, // G2_KNOT_G7 : +{0x7410,0x005F,0x02}, // G2_KNOT_G8 : +{0x7412,0x0068,0x02}, // G2_KNOT_G9 : +{0x7414,0x0044,0x02}, // G2_KNOT_G10 : +{0x7416,0x0083,0x02}, // G2_KNOT_G11 : +{0x7418,0x00B6,0x02}, // G2_KNOT_G12 : +{0x741A,0x00D1,0x02}, // G2_KNOT_G13 : +{0x741C,0x00E4,0x02}, // G2_KNOT_G14 : +{0x741E,0x00F0,0x02}, // G2_KNOT_G15 : +{0x7420,0x00F9,0x02}, // G2_KNOT_G16 : +{0x7422,0x0103,0x02}, // G2_KNOT_G17 : +{0x7424,0x010C,0x02}, // G2_KNOT_G18 : +{0x7426,0x00,0x01}, // G2_KNOT_R0_OFFSET : +{0x7427,0x00,0x01}, // G2_KNOT_R2_OFFSET : +{0x7428,0x00,0x01}, // G2_KNOT_R4_OFFSET : +{0x7429,0x00,0x01}, // G2_KNOT_R6_OFFSET : +{0x742A,0x00,0x01}, // G2_KNOT_R8_OFFSET : +{0x742B,0x00,0x01}, // G2_KNOT_R10_OFFSET : +{0x742C,0x00,0x01}, // G2_KNOT_R12_OFFSET : +{0x742D,0x00,0x01}, // G2_KNOT_R14_OFFSET : +{0x742E,0x00,0x01}, // G2_KNOT_R16_OFFSET : +{0x742F,0x00,0x01}, // G2_KNOT_R18_OFFSET : +{0x7430,0x00,0x01}, // G2_KNOT_B0_OFFSET : +{0x7431,0x00,0x01}, // G2_KNOT_B2_OFFSET : +{0x7432,0x00,0x01}, // G2_KNOT_B4_OFFSET : +{0x7433,0x00,0x01}, // G2_KNOT_B6_OFFSET : +{0x7434,0x00,0x01}, // G2_KNOT_B8_OFFSET : +{0x7435,0x00,0x01}, // G2_KNOT_B10_OFFSET : +{0x7436,0x00,0x01}, // G2_KNOT_B12_OFFSET : +{0x7437,0x00,0x01}, // G2_KNOT_B14_OFFSET : +{0x7438,0x00,0x01}, // G2_KNOT_B16_OFFSET : +{0x7439,0x00,0x01}, // G2_KNOT_B18_OFFSET : +{0x743A,0x0611,0x02}, // G2_LOWGM_ON_R : +{0x743C,0x1E0A,0x02}, // G2_0CLIP_R : +{0x743E,0x0611,0x02}, // G2_LOWGM_ON_G : +{0x7440,0x1E0A,0x02}, // G2_0CLIP_G : +{0x7442,0x0611,0x02}, // G2_LOWGM_ON_B : +{0x7444,0x1E0A,0x02}, // G2_0CLIP_B : + + +//AWB tuning +{0x64A4,0xFF,0x01}, // OUTFRM_LEFT00 : +{0x64A5,0xFF,0x01}, // OUTFRM_LEFT01 : +{0x64A6,0xFF,0x01}, // OUTFRM_LEFT02 : +{0x64A7,0xFF,0x01}, // OUTFRM_LEFT03 : +{0x64A8,0xFF,0x01}, // OUTFRM_LEFT04 : +{0x64A9,0xFF,0x01}, // OUTFRM_LEFT05 : +{0x64AA,0xFF,0x01}, // OUTFRM_LEFT06 : +{0x64AB,0xFF,0x01}, // OUTFRM_LEFT07 : +{0x64AC,0xFF,0x01}, // OUTFRM_LEFT08 : +{0x64AD,0xFD,0x01}, // OUTFRM_LEFT09 : +{0x64AE,0xCB,0x01}, // OUTFRM_LEFT10 : +{0x64AF,0xA9,0x01}, // OUTFRM_LEFT11 : +{0x64B0,0x90,0x01}, // OUTFRM_LEFT12 : +{0x64B1,0x7D,0x01}, // OUTFRM_LEFT13 : +{0x64B2,0x70,0x01}, // OUTFRM_LEFT14 : +{0x64B3,0x65,0x01}, // OUTFRM_LEFT15 : +{0x64B4,0x5C,0x01}, // OUTFRM_LEFT16 : +{0x64B5,0x55,0x01}, // OUTFRM_LEFT17 : +{0x64B6,0x4F,0x01}, // OUTFRM_LEFT18 : +{0x64B7,0x32,0x01}, // OUTFRM_LEFT19 : +{0x64B8,0x4D,0x01}, // OUTFRM_LEFT20 : +{0x64B9,0x40,0x01}, // OUTFRM_LEFT21 : +{0x64BA,0x2D,0x01}, // OUTFRM_LEFT22 : +{0x64BB,0x2B,0x01}, // OUTFRM_LEFT23 : +{0x64BC,0x29,0x01}, // OUTFRM_LEFT24 : +{0x64BD,0x27,0x01}, // OUTFRM_LEFT25 : +{0x64BE,0x25,0x01}, // OUTFRM_LEFT26 : +{0x64BF,0x23,0x01}, // OUTFRM_LEFT27 : +{0x64C0,0x21,0x01}, // OUTFRM_LEFT28 : +{0x64C1,0x1F,0x01}, // OUTFRM_LEFT29 : +{0x64C2,0x1D,0x01}, // OUTFRM_LEFT30 : +{0x64C3,0x1B,0x01}, // OUTFRM_LEFT31 : +{0x64C4,0x1A,0x01}, // OUTFRM_LEFT32 : +{0x64C5,0x1A,0x01}, // OUTFRM_LEFT33 : +{0x64C6,0x1A,0x01}, // OUTFRM_LEFT34 : +{0x64C7,0x28,0x01}, // OUTFRM_LEFT35 : +{0x64C8,0x27,0x01}, // OUTFRM_LEFT36 : +{0x64C9,0x26,0x01}, // OUTFRM_LEFT37 : +{0x64CA,0xFF,0x01}, // OUTFRM_RIGHT00 : +{0x64CB,0xFF,0x01}, // OUTFRM_RIGHT01 : +{0x64CC,0xFF,0x01}, // OUTFRM_RIGHT02 : +{0x64CD,0xFF,0x01}, // OUTFRM_RIGHT03 : +{0x64CE,0xFF,0x01}, // OUTFRM_RIGHT04 : +{0x64CF,0xFF,0x01}, // OUTFRM_RIGHT05 : +{0x64D0,0xFF,0x01}, // OUTFRM_RIGHT06 : +{0x64D1,0xFF,0x01}, // OUTFRM_RIGHT07 : +{0x64D2,0xFF,0x01}, // OUTFRM_RIGHT08 : +{0x64D3,0xFF,0x01}, // OUTFRM_RIGHT09 : +{0x64D4,0xD3,0x01}, // OUTFRM_RIGHT10 : +{0x64D5,0xB1,0x01}, // OUTFRM_RIGHT11 : +{0x64D6,0x98,0x01}, // OUTFRM_RIGHT12 : +{0x64D7,0x85,0x01}, // OUTFRM_RIGHT13 : +{0x64D8,0x78,0x01}, // OUTFRM_RIGHT14 : +{0x64D9,0x6D,0x01}, // OUTFRM_RIGHT15 : +{0x64DA,0x64,0x01}, // OUTFRM_RIGHT16 : +{0x64DB,0x5D,0x01}, // OUTFRM_RIGHT17 : +{0x64DC,0x57,0x01}, // OUTFRM_RIGHT18 : +{0x64DD,0x63,0x01}, // OUTFRM_RIGHT19 : +{0x64DE,0x5E,0x01}, // OUTFRM_RIGHT20 : +{0x64DF,0x5A,0x01}, // OUTFRM_RIGHT21 : +{0x64E0,0x56,0x01}, // OUTFRM_RIGHT22 : +{0x64E1,0x52,0x01}, // OUTFRM_RIGHT23 : +{0x64E2,0x50,0x01}, // OUTFRM_RIGHT24 : +{0x64E3,0x4E,0x01}, // OUTFRM_RIGHT25 : +{0x64E4,0x4C,0x01}, // OUTFRM_RIGHT26 : +{0x64E5,0x4A,0x01}, // OUTFRM_RIGHT27 : +{0x64E6,0x48,0x01}, // OUTFRM_RIGHT28 : +{0x64E7,0x46,0x01}, // OUTFRM_RIGHT29 : +{0x64E8,0x44,0x01}, // OUTFRM_RIGHT30 : +{0x64E9,0x43,0x01}, // OUTFRM_RIGHT31 : +{0x64EA,0x42,0x01}, // OUTFRM_RIGHT32 : +{0x64EB,0x42,0x01}, // OUTFRM_RIGHT33 : +{0x64EC,0x42,0x01}, // OUTFRM_RIGHT34 : +{0x64ED,0x30,0x01}, // OUTFRM_RIGHT35 : +{0x64EE,0x2F,0x01}, // OUTFRM_RIGHT36 : +{0x64EF,0x2E,0x01}, // OUTFRM_RIGHT37 : +{0x64F0,0x2163,0x02}, // OUTFRM_TOP : +{0x64F2,0x1400,0x02}, // OUTFRM_BOTM : +{0x64F4,0x19,0x01}, // OUTFRM_FLTOP : +{0x64F5,0x14,0x01}, // OUTFRM_FLBOTM : +{0x64F6,0xFF,0x01}, // OUTAIM_LEFT00 : +{0x64F7,0xFF,0x01}, // OUTAIM_LEFT01 : +{0x64F8,0xFF,0x01}, // OUTAIM_LEFT02 : +{0x64F9,0xFF,0x01}, // OUTAIM_LEFT03 : +{0x64FA,0xFF,0x01}, // OUTAIM_LEFT04 : +{0x64FB,0xFF,0x01}, // OUTAIM_LEFT05 : +{0x64FC,0xFF,0x01}, // OUTAIM_LEFT06 : +{0x64FD,0xFF,0x01}, // OUTAIM_LEFT07 : +{0x64FE,0xFF,0x01}, // OUTAIM_LEFT08 : +{0x64FF,0xFF,0x01}, // OUTAIM_LEFT09 : +{0x6500,0x91,0x01}, // OUTAIM_LEFT10 : +{0x6501,0x91,0x01}, // OUTAIM_LEFT11 : +{0x6502,0x91,0x01}, // OUTAIM_LEFT12 : +{0x6503,0x66,0x01}, // OUTAIM_LEFT13 : +{0x6504,0x5D,0x01}, // OUTAIM_LEFT14 : +{0x6505,0x3C,0x01}, // OUTAIM_LEFT15 : +{0x6506,0x3C,0x01}, // OUTAIM_LEFT16 : +{0x6507,0x3C,0x01}, // OUTAIM_LEFT17 : +{0x6508,0x3A,0x01}, // OUTAIM_LEFT18 : +{0x6509,0x39,0x01}, // OUTAIM_LEFT19 : +{0x650A,0x40,0x01}, // OUTAIM_LEFT20 : +{0x650B,0x46,0x01}, // OUTAIM_LEFT21 : +{0x650C,0x42,0x01}, // OUTAIM_LEFT22 : +{0x650D,0x3D,0x01}, // OUTAIM_LEFT23 : +{0x650E,0x3A,0x01}, // OUTAIM_LEFT24 : +{0x650F,0x3E,0x01}, // OUTAIM_LEFT25 : +{0x6510,0x38,0x01}, // OUTAIM_LEFT26 : +{0x6511,0x36,0x01}, // OUTAIM_LEFT27 : +{0x6512,0x34,0x01}, // OUTAIM_LEFT28 : +{0x6513,0x32,0x01}, // OUTAIM_LEFT29 : +{0x6514,0x30,0x01}, // OUTAIM_LEFT30 : +{0x6515,0x2F,0x01}, // OUTAIM_LEFT31 : +{0x6516,0x2D,0x01}, // OUTAIM_LEFT32 : +{0x6517,0x2C,0x01}, // OUTAIM_LEFT33 : +{0x6518,0x2B,0x01}, // OUTAIM_LEFT34 : +{0x6519,0x2A,0x01}, // OUTAIM_LEFT35 : +{0x651A,0x29,0x01}, // OUTAIM_LEFT36 : +{0x651B,0x28,0x01}, // OUTAIM_LEFT37 : +{0x651C,0xFF,0x01}, // OUTAIM_RIGHT00 : +{0x651D,0xFF,0x01}, // OUTAIM_RIGHT01 : +{0x651E,0xFF,0x01}, // OUTAIM_RIGHT02 : +{0x651F,0xFF,0x01}, // OUTAIM_RIGHT03 : +{0x6520,0xFF,0x01}, // OUTAIM_RIGHT04 : +{0x6521,0xFF,0x01}, // OUTAIM_RIGHT05 : +{0x6522,0xFF,0x01}, // OUTAIM_RIGHT06 : +{0x6523,0xFF,0x01}, // OUTAIM_RIGHT07 : +{0x6524,0xFF,0x01}, // OUTAIM_RIGHT08 : +{0x6525,0xFF,0x01}, // OUTAIM_RIGHT09 : +{0x6526,0xD9,0x01}, // OUTAIM_RIGHT10 : +{0x6527,0xB7,0x01}, // OUTAIM_RIGHT11 : +{0x6528,0x96,0x01}, // OUTAIM_RIGHT12 : +{0x6529,0x6C,0x01}, // OUTAIM_RIGHT13 : +{0x652A,0x64,0x01}, // OUTAIM_RIGHT14 : +{0x652B,0x62,0x01}, // OUTAIM_RIGHT15 : +{0x652C,0x62,0x01}, // OUTAIM_RIGHT16 : +{0x652D,0x61,0x01}, // OUTAIM_RIGHT17 : +{0x652E,0x60,0x01}, // OUTAIM_RIGHT18 : +{0x652F,0x5E,0x01}, // OUTAIM_RIGHT19 : +{0x6530,0x5B,0x01}, // OUTAIM_RIGHT20 : +{0x6531,0x4F,0x01}, // OUTAIM_RIGHT21 : +{0x6532,0x48,0x01}, // OUTAIM_RIGHT22 : +{0x6533,0x43,0x01}, // OUTAIM_RIGHT23 : +{0x6534,0x41,0x01}, // OUTAIM_RIGHT24 : +{0x6535,0x40,0x01}, // OUTAIM_RIGHT25 : +{0x6536,0x3D,0x01}, // OUTAIM_RIGHT26 : +{0x6537,0x3B,0x01}, // OUTAIM_RIGHT27 : +{0x6538,0x39,0x01}, // OUTAIM_RIGHT28 : +{0x6539,0x37,0x01}, // OUTAIM_RIGHT29 : +{0x653A,0x36,0x01}, // OUTAIM_RIGHT30 : +{0x653B,0x35,0x01}, // OUTAIM_RIGHT31 : +{0x653C,0x33,0x01}, // OUTAIM_RIGHT32 : +{0x653D,0x32,0x01}, // OUTAIM_RIGHT33 : +{0x653E,0x31,0x01}, // OUTAIM_RIGHT34 : +{0x653F,0x30,0x01}, // OUTAIM_RIGHT35 : +{0x6540,0x2F,0x01}, // OUTAIM_RIGHT36 : +{0x6541,0x2E,0x01}, // OUTAIM_RIGHT37 : +{0x6542,0x1F40,0x02}, // OUTAIM_TOP : +{0x6544,0x1752,0x02}, // OUTAIM_BOTM : +{0x6546,0x19,0x01}, // OUTAIM_FLTOP : +{0x6547,0x17,0x01}, // OUTAIM_FLBOTM : + +{0x657A,0x82,0x01}, // IN_CTMP_FRM_BG0 : +{0x657B,0x78,0x01}, // IN_CTMP_FRM_BG1 : +{0x657C,0x65,0x01}, // IN_CTMP_FRM_BG2 : +{0x657D,0x5B,0x01}, // IN_CTMP_FRM_BG3 : +{0x657E,0x55,0x01}, // IN_CTMP_FRM_BG4 : +{0x657F,0x4F,0x01}, // IN_CTMP_FRM_BG5 : +{0x6580,0x49,0x01}, // IN_CTMP_FRM_BG6 : +{0x6581,0x43,0x01}, // IN_CTMP_FRM_BG7 : +{0x6582,0x3E,0x01}, // IN_CTMP_FRM_BG8 : +{0x6583,0x35,0x01}, // IN_CTMP_FRM_BG9 : +{0x6584,0x30,0x01}, // IN_CTMP_FRM_BG10 : +{0x6585,0x23,0x01}, // IN_CTMP_FRM_RG0 : +{0x6586,0x33,0x01}, // IN_CTMP_FRM_RG1 : +{0x6587,0x3F,0x01}, // IN_CTMP_FRM_RG2 : +{0x6588,0x53,0x01}, // IN_CTMP_FRM_RG3 : +{0x6589,0x63,0x01}, // IN_CTMP_FRM_RG4 : +{0x658A,0x76,0x01}, // IN_CTMP_FRM_RG5 : +{0x658B,0x9A,0x01}, // IN_CTMP_FRM_RG6 : +{0x658C,0x00,0x01}, // IN_CTMP_WEIGHT00_01 : +{0x658D,0x00,0x01}, // IN_CTMP_WEIGHT02_03 : +{0x658E,0x00,0x01}, // IN_CTMP_WEIGHT04_05 : +{0x658F,0x00,0x01}, // IN_CTMP_WEIGHT06_07 : +{0x6590,0x00,0x01}, // IN_CTMP_WEIGHT08_09 : +{0x6591,0x00,0x01}, // IN_CTMP_WEIGHT10_11 : +{0x6592,0x00,0x01}, // IN_CTMP_WEIGHT12_13 : +{0x6593,0x00,0x01}, // IN_CTMP_WEIGHT14_15 : +{0x6594,0x00,0x01}, // IN_CTMP_WEIGHT16_17 : +{0x6595,0x00,0x01}, // IN_CTMP_WEIGHT18_19 : +{0x6596,0x00,0x01}, // IN_CTMP_WEIGHT20_21 : +{0x6597,0x00,0x01}, // IN_CTMP_WEIGHT22_23 : +{0x6598,0x00,0x01}, // IN_CTMP_WEIGHT24_25 : +{0x6599,0x00,0x01}, // IN_CTMP_WEIGHT26_27 : +{0x659A,0x00,0x01}, // IN_CTMP_WEIGHT28_29 : +{0x659B,0x00,0x01}, // IN_CTMP_WEIGHT30_31 : +{0x659C,0x00,0x01}, // IN_CTMP_WEIGHT32_33 : +{0x659D,0x00,0x01}, // IN_CTMP_WEIGHT34_35 : +{0x659E,0x00,0x01}, // IN_CTMP_WEIGHT36_37 : +{0x659F,0x00,0x01}, // IN_CTMP_WEIGHT38_39 : +{0x65A0,0x00,0x01}, // IN_CTMP_WEIGHT40_41 : +{0x65A1,0x00,0x01}, // IN_CTMP_WEIGHT42_43 : +{0x65A2,0x00,0x01}, // IN_CTMP_WEIGHT44_45 : +{0x65A3,0x00,0x01}, // IN_CTMP_WEIGHT46_47 : +{0x65A4,0x00,0x01}, // IN_CTMP_WEIGHT48_49 : +{0x65A5,0x00,0x01}, // IN_CTMP_WEIGHT50_51 : +{0x65A6,0x00,0x01}, // IN_CTMP_WEIGHT52_53 : +{0x65A7,0x00,0x01}, // IN_CTMP_WEIGHT54_55 : +{0x65A8,0x00,0x01}, // IN_CTMP_WEIGHT56_57 : +{0x65A9,0x10,0x01}, // IN_CTMP_WEIGHT58_59 : + +{0x65AA,0x78,0x01}, // OUT_CTMP_FRM_BG0 : +{0x65AB,0x74,0x01}, // OUT_CTMP_FRM_BG1 : +{0x65AC,0x70,0x01}, // OUT_CTMP_FRM_BG2 : +{0x65AD,0x6D,0x01}, // OUT_CTMP_FRM_BG3 : +{0x65AE,0x69,0x01}, // OUT_CTMP_FRM_BG4 : +{0x65AF,0x66,0x01}, // OUT_CTMP_FRM_BG5 : +{0x65B0,0x61,0x01}, // OUT_CTMP_FRM_BG6 : +{0x65B1,0x5D,0x01}, // OUT_CTMP_FRM_BG7 : +{0x65B2,0x52,0x01}, // OUT_CTMP_FRM_BG8 : +{0x65B3,0x4B,0x01}, // OUT_CTMP_FRM_BG9 : +{0x65B4,0x44,0x01}, // OUT_CTMP_FRM_BG10 : +{0x65B5,0x19,0x01}, // OUT_CTMP_FRM_RG0 : +{0x65B6,0x27,0x01}, // OUT_CTMP_FRM_RG1 : +{0x65B7,0x32,0x01}, // OUT_CTMP_FRM_RG2 : +{0x65B8,0x3A,0x01}, // OUT_CTMP_FRM_RG3 : +{0x65B9,0x43,0x01}, // OUT_CTMP_FRM_RG4 : +{0x65BA,0x4A,0x01}, // OUT_CTMP_FRM_RG5 : +{0x65BB,0x5E,0x01}, // OUT_CTMP_FRM_RG6 : +{0x65BC,0x00,0x01}, // OUT_CTMP_WEIGHT00_01 : +{0x65BD,0x00,0x01}, // OUT_CTMP_WEIGHT02_03 : +{0x65BE,0x00,0x01}, // OUT_CTMP_WEIGHT04_05 : +{0x65BF,0x00,0x01}, // OUT_CTMP_WEIGHT06_07 : +{0x65C0,0x33,0x01}, // OUT_CTMP_WEIGHT08_09 : +{0x65C1,0x00,0x01}, // OUT_CTMP_WEIGHT10_11 : +{0x65C2,0x30,0x01}, // OUT_CTMP_WEIGHT12_13 : +{0x65C3,0x33,0x01}, // OUT_CTMP_WEIGHT14_15 : +{0x65C4,0x00,0x01}, // OUT_CTMP_WEIGHT16_17 : +{0x65C5,0x30,0x01}, // OUT_CTMP_WEIGHT18_19 : +{0x65C6,0x33,0x01}, // OUT_CTMP_WEIGHT20_21 : +{0x65C7,0x00,0x01}, // OUT_CTMP_WEIGHT22_23 : +{0x65C8,0x30,0x01}, // OUT_CTMP_WEIGHT24_25 : +{0x65C9,0x33,0x01}, // OUT_CTMP_WEIGHT26_27 : +{0x65CA,0x00,0x01}, // OUT_CTMP_WEIGHT28_29 : +{0x65CB,0x30,0x01}, // OUT_CTMP_WEIGHT30_31 : +{0x65CC,0x44,0x01}, // OUT_CTMP_WEIGHT32_33 : +{0x65CD,0x00,0x01}, // OUT_CTMP_WEIGHT34_35 : +{0x65CE,0x40,0x01}, // OUT_CTMP_WEIGHT36_37 : +{0x65CF,0x55,0x01}, // OUT_CTMP_WEIGHT38_39 : +{0x65D0,0x05,0x01}, // OUT_CTMP_WEIGHT40_41 : +{0x65D1,0x20,0x01}, // OUT_CTMP_WEIGHT42_43 : +{0x65D2,0x72,0x01}, // OUT_CTMP_WEIGHT44_45 : +{0x65D3,0x07,0x01}, // OUT_CTMP_WEIGHT46_47 : +{0x65D4,0x00,0x01}, // OUT_CTMP_WEIGHT48_49 : +{0x65D5,0x00,0x01}, // OUT_CTMP_WEIGHT50_51 : +{0x65D6,0x00,0x01}, // OUT_CTMP_WEIGHT52_53 : +{0x65D7,0x00,0x01}, // OUT_CTMP_WEIGHT54_55 : +{0x65D8,0x00,0x01}, // OUT_CTMP_WEIGHT56_57 : +{0x65D9,0x00,0x01}, // OUT_CTMP_WEIGHT58_59 : + +{0x6400,0xAA,0x01}, // INFRM_LEFT00 : +{0x6401,0xAA,0x01}, // INFRM_LEFT01 : +{0x6402,0xAA,0x01}, // INFRM_LEFT02 : +{0x6403,0xAA,0x01}, // INFRM_LEFT03 : +{0x6404,0xAA,0x01}, // INFRM_LEFT04 : +{0x6405,0xAA,0x01}, // INFRM_LEFT05 : +{0x6406,0xAA,0x01}, // INFRM_LEFT06 : +{0x6407,0xAA,0x01}, // INFRM_LEFT07 : +{0x6408,0xAA,0x01}, // INFRM_LEFT08 : +{0x6409,0xAE,0x01}, // INFRM_LEFT09 : +{0x640A,0xA0,0x01}, // INFRM_LEFT10 : +{0x640B,0x8C,0x01}, // INFRM_LEFT11 : +{0x640C,0x72,0x01}, // INFRM_LEFT12 : +{0x640D,0x64,0x01}, // INFRM_LEFT13 : +{0x640E,0x5A,0x01}, // INFRM_LEFT14 : +{0x640F,0x52,0x01}, // INFRM_LEFT15 : +{0x6410,0x48,0x01}, // INFRM_LEFT16 : +{0x6411,0x43,0x01}, // INFRM_LEFT17 : +{0x6412,0x3D,0x01}, // INFRM_LEFT18 : +{0x6413,0x37,0x01}, // INFRM_LEFT19 : +{0x6414,0x33,0x01}, // INFRM_LEFT20 : +{0x6415,0x30,0x01}, // INFRM_LEFT21 : +{0x6416,0x2E,0x01}, // INFRM_LEFT22 : +{0x6417,0x2B,0x01}, // INFRM_LEFT23 : +{0x6418,0x28,0x01}, // INFRM_LEFT24 : +{0x6419,0x26,0x01}, // INFRM_LEFT25 : +{0x641A,0x24,0x01}, // INFRM_LEFT26 : +{0x641B,0x23,0x01}, // INFRM_LEFT27 : +{0x641C,0x22,0x01}, // INFRM_LEFT28 : +{0x641D,0x22,0x01}, // INFRM_LEFT29 : +{0x641E,0x21,0x01}, // INFRM_LEFT30 : +{0x641F,0x20,0x01}, // INFRM_LEFT31 : +{0x6420,0x1D,0x01}, // INFRM_LEFT32 : +{0x6421,0x1A,0x01}, // INFRM_LEFT33 : +{0x6422,0x18,0x01}, // INFRM_LEFT34 : +{0x6423,0x17,0x01}, // INFRM_LEFT35 : +{0x6424,0x16,0x01}, // INFRM_LEFT36 : +{0x6425,0x17,0x01}, // INFRM_LEFT37 : +{0x6426,0xAF,0x01}, // INFRM_RIGHT00 : +{0x6427,0xAF,0x01}, // INFRM_RIGHT01 : +{0x6428,0xAF,0x01}, // INFRM_RIGHT02 : +{0x6429,0xAF,0x01}, // INFRM_RIGHT03 : +{0x642A,0xAF,0x01}, // INFRM_RIGHT04 : +{0x642B,0xAF,0x01}, // INFRM_RIGHT05 : +{0x642C,0xAF,0x01}, // INFRM_RIGHT06 : +{0x642D,0xAF,0x01}, // INFRM_RIGHT07 : +{0x642E,0xAF,0x01}, // INFRM_RIGHT08 : +{0x642F,0xAA,0x01}, // INFRM_RIGHT09 : +{0x6430,0xB2,0x01}, // INFRM_RIGHT10 : +{0x6431,0xB4,0x01}, // INFRM_RIGHT11 : +{0x6432,0xB6,0x01}, // INFRM_RIGHT12 : +{0x6433,0xB4,0x01}, // INFRM_RIGHT13 : +{0x6434,0x9B,0x01}, // INFRM_RIGHT14 : +{0x6435,0x8E,0x01}, // INFRM_RIGHT15 : +{0x6436,0x84,0x01}, // INFRM_RIGHT16 : +{0x6437,0x7A,0x01}, // INFRM_RIGHT17 : +{0x6438,0x72,0x01}, // INFRM_RIGHT18 : +{0x6439,0x6A,0x01}, // INFRM_RIGHT19 : +{0x643A,0x63,0x01}, // INFRM_RIGHT20 : +{0x643B,0x5E,0x01}, // INFRM_RIGHT21 : +{0x643C,0x58,0x01}, // INFRM_RIGHT22 : +{0x643D,0x53,0x01}, // INFRM_RIGHT23 : +{0x643E,0x4E,0x01}, // INFRM_RIGHT24 : +{0x643F,0x4A,0x01}, // INFRM_RIGHT25 : +{0x6440,0x46,0x01}, // INFRM_RIGHT26 : +{0x6441,0x42,0x01}, // INFRM_RIGHT27 : +{0x6442,0x3F,0x01}, // INFRM_RIGHT28 : +{0x6443,0x3C,0x01}, // INFRM_RIGHT29 : +{0x6444,0x3A,0x01}, // INFRM_RIGHT30 : +{0x6445,0x38,0x01}, // INFRM_RIGHT31 : +{0x6446,0x37,0x01}, // INFRM_RIGHT32 : +{0x6447,0x35,0x01}, // INFRM_RIGHT33 : +{0x6448,0x33,0x01}, // INFRM_RIGHT34 : +{0x6449,0x32,0x01}, // INFRM_RIGHT35 : +{0x644A,0x32,0x01}, // INFRM_RIGHT36 : +{0x644B,0x32,0x01}, // INFRM_RIGHT37 : +{0x644C,0x24FA,0x02}, // INFRM_TOP : +{0x644E,0x0940,0x02}, // INFRM_BOTM : +{0x6450,0x19,0x01}, // INFRM_FLTOP : +{0x6451,0x10,0x01}, // INFRM_FLBOTM : +{0x6452,0x91,0x01}, // INAIM_LEFT00 : +{0x6453,0x91,0x01}, // INAIM_LEFT01 : +{0x6454,0x91,0x01}, // INAIM_LEFT02 : +{0x6455,0x91,0x01}, // INAIM_LEFT03 : +{0x6456,0x91,0x01}, // INAIM_LEFT04 : +{0x6457,0x91,0x01}, // INAIM_LEFT05 : +{0x6458,0x91,0x01}, // INAIM_LEFT06 : +{0x6459,0x91,0x01}, // INAIM_LEFT07 : +{0x645A,0x91,0x01}, // INAIM_LEFT08 : +{0x645B,0x91,0x01}, // INAIM_LEFT09 : +{0x645C,0x91,0x01}, // INAIM_LEFT10 : +{0x645D,0x91,0x01}, // INAIM_LEFT11 : +{0x645E,0x91,0x01}, // INAIM_LEFT12 : +{0x645F,0x66,0x01}, // INAIM_LEFT13 : +{0x6460,0x71,0x01}, // INAIM_LEFT14 : +{0x6461,0x5A,0x01}, // INAIM_LEFT15 : +{0x6462,0x4E,0x01}, // INAIM_LEFT16 : +{0x6463,0x47,0x01}, // INAIM_LEFT17 : +{0x6464,0x42,0x01}, // INAIM_LEFT18 : +{0x6465,0x3C,0x01}, // INAIM_LEFT19 : +{0x6466,0x38,0x01}, // INAIM_LEFT20 : +{0x6467,0x36,0x01}, // INAIM_LEFT21 : +{0x6468,0x33,0x01}, // INAIM_LEFT22 : +{0x6469,0x30,0x01}, // INAIM_LEFT23 : +{0x646A,0x2F,0x01}, // INAIM_LEFT24 : +{0x646B,0x2B,0x01}, // INAIM_LEFT25 : +{0x646C,0x29,0x01}, // INAIM_LEFT26 : +{0x646D,0x27,0x01}, // INAIM_LEFT27 : +{0x646E,0x26,0x01}, // INAIM_LEFT28 : +{0x646F,0x28,0x01}, // INAIM_LEFT29 : +{0x6470,0x2A,0x01}, // INAIM_LEFT30 : +{0x6471,0x28,0x01}, // INAIM_LEFT31 : +{0x6472,0x26,0x01}, // INAIM_LEFT32 : +{0x6473,0x24,0x01}, // INAIM_LEFT33 : +{0x6474,0x29,0x01}, // INAIM_LEFT34 : +{0x6475,0x28,0x01}, // INAIM_LEFT35 : +{0x6476,0x29,0x01}, // INAIM_LEFT36 : +{0x6477,0x26,0x01}, // INAIM_LEFT37 : +{0x6478,0xFF,0x01}, // INAIM_RIGHT00 : +{0x6479,0xFF,0x01}, // INAIM_RIGHT01 : +{0x647A,0xFF,0x01}, // INAIM_RIGHT02 : +{0x647B,0xFF,0x01}, // INAIM_RIGHT03 : +{0x647C,0xFF,0x01}, // INAIM_RIGHT04 : +{0x647D,0xFF,0x01}, // INAIM_RIGHT05 : +{0x647E,0xFF,0x01}, // INAIM_RIGHT06 : +{0x647F,0xFF,0x01}, // INAIM_RIGHT07 : +{0x6480,0xFF,0x01}, // INAIM_RIGHT08 : +{0x6481,0xFF,0x01}, // INAIM_RIGHT09 : +{0x6482,0xD9,0x01}, // INAIM_RIGHT10 : +{0x6483,0xB7,0x01}, // INAIM_RIGHT11 : +{0x6484,0x96,0x01}, // INAIM_RIGHT12 : +{0x6485,0x68,0x01}, // INAIM_RIGHT13 : +{0x6486,0x72,0x01}, // INAIM_RIGHT14 : +{0x6487,0x71,0x01}, // INAIM_RIGHT15 : +{0x6488,0x6E,0x01}, // INAIM_RIGHT16 : +{0x6489,0x6A,0x01}, // INAIM_RIGHT17 : +{0x648A,0x65,0x01}, // INAIM_RIGHT18 : +{0x648B,0x60,0x01}, // INAIM_RIGHT19 : +{0x648C,0x5B,0x01}, // INAIM_RIGHT20 : +{0x648D,0x56,0x01}, // INAIM_RIGHT21 : +{0x648E,0x51,0x01}, // INAIM_RIGHT22 : +{0x648F,0x4C,0x01}, // INAIM_RIGHT23 : +{0x6490,0x47,0x01}, // INAIM_RIGHT24 : +{0x6491,0x44,0x01}, // INAIM_RIGHT25 : +{0x6492,0x41,0x01}, // INAIM_RIGHT26 : +{0x6493,0x3E,0x01}, // INAIM_RIGHT27 : +{0x6494,0x3B,0x01}, // INAIM_RIGHT28 : +{0x6495,0x39,0x01}, // INAIM_RIGHT29 : +{0x6496,0x37,0x01}, // INAIM_RIGHT30 : +{0x6497,0x34,0x01}, // INAIM_RIGHT31 : +{0x6498,0x33,0x01}, // INAIM_RIGHT32 : +{0x6499,0x32,0x01}, // INAIM_RIGHT33 : +{0x649A,0x31,0x01}, // INAIM_RIGHT34 : +{0x649B,0x30,0x01}, // INAIM_RIGHT35 : +{0x649C,0x2F,0x01}, // INAIM_RIGHT36 : +{0x649D,0x2E,0x01}, // INAIM_RIGHT37 : +{0x649E,0x1E00,0x02}, // INAIM_TOP : +{0x64A0,0x0DFF,0x02}, // INAIM_BOTM : +{0x64A2,0x18,0x01}, // INAIM_FLTOP : +{0x64A3,0x09,0x01}, // INAIM_FLBOTM : + +//AWB setting +{0x629A,0x13,0x01}, // CAT_AWB_2 : OPDG ±â´É off +{0x629B,0x41,0x01}, // CAT_AWB_3 : outdoor_°¡ÁßÄ¡ on +{0x625F,0x15,0x01}, // CAT_AWB_1 : MWB½Ã userÁÂÇ¥·Î ÁÂÇ¥ °íÁ¤(AWB½Ã¿¡´Â ¿µÇâ ¹«) +{0x629C,0x80,0x01}, // FRMOUT_RATIO_BLEND1_OUT +{0x6224,0x04,0x01}, // ATW_DELAY +{0x6226,0x08,0x01}, // ATW_GAINS_IN_NR : +{0x6227,0x04,0x01}, // ATW_GAINS_IN : +{0x6228,0x08,0x01}, // ATW_GAINS_OUT_NR : +{0x6229,0x04,0x01}, // ATW_GAINS_OUT : + +//Bluesky threshold º¯°æ +{0x6548,0x18F7,0x02}, // OUTAIM_TOP_BLUESKY : + +//Hue, Gain setting +{0x6E86,0x0000,0x02}, // IBYHUE1_POS1 : +{0x6E88,0xFFF5,0x02}, // IRYHUE1_POS1 : +{0x6E8A,0xFFF8,0x02}, // IBYHUE2_POS1 : +{0x6E8C,0xFFF5,0x02}, // IRYHUE2_POS1 : +{0x6E8E,0xFFF8,0x02}, // IBYHUE3_POS1 : +{0x6E90,0xFFEE,0x02}, // IRYHUE3_POS1 : +{0x6E92,0x0000,0x02}, // IBYHUE4_POS1 : +{0x6E94,0xFFEC,0x02}, // IRYHUE4_POS1 : +{0x6E96,0x0000,0x02}, // IBYHUE1_POS2 : +{0x6E98,0xFFF5,0x02}, // IRYHUE1_POS2 : +{0x6E9A,0xFFFD,0x02}, // IBYHUE2_POS2 : +{0x6E9C,0xFFF5,0x02}, // IRYHUE2_POS2 : +{0x6E9E,0xFFFD,0x02}, // IBYHUE3_POS2 : +{0x6EA0,0xFFEE,0x02}, // IRYHUE3_POS2 : +{0x6EA2,0x0000,0x02}, // IBYHUE4_POS2 : +{0x6EA4,0xFFEC,0x02}, // IRYHUE4_POS2 : +{0x6EA6,0x0000,0x02}, // IBYHUE1_POS3 : +{0x6EA8,0xFFF5,0x02}, // IRYHUE1_POS3 : +{0x6EAA,0xFFF8,0x02}, // IBYHUE2_POS3 : +{0x6EAC,0xFFF5,0x02}, // IRYHUE2_POS3 : +{0x6EAE,0xFFF8,0x02}, // IBYHUE3_POS3 : +{0x6EB0,0xFFEE,0x02}, // IRYHUE3_POS3 : +{0x6EB2,0x0000,0x02}, // IBYHUE4_POS3 : +{0x6EB4,0xFFEC,0x02}, // IRYHUE4_POS3 : +{0x6EB6,0x0000,0x02}, // IBYHUE1_POS4 : +{0x6EB8,0xFFF5,0x02}, // IRYHUE1_POS4 : +{0x6EBA,0xFFF8,0x02}, // IBYHUE2_POS4 : +{0x6EBC,0xFFF5,0x02}, // IRYHUE2_POS4 : +{0x6EBE,0xFFF8,0x02}, // IBYHUE3_POS4 : +{0x6EC0,0xFFEE,0x02}, // IRYHUE3_POS4 : +{0x6EC2,0x0000,0x02}, // IBYHUE4_POS4 : +{0x6EC4,0xFFEC,0x02}, // IRYHUE4_POS4 : +{0x6EC6,0x0000,0x02}, // IBYHUE1_POS5 : +{0x6EC8,0xFFF5,0x02}, // IRYHUE1_POS5 : +{0x6ECA,0xFFF8,0x02}, // IBYHUE2_POS5 : +{0x6ECC,0xFFF5,0x02}, // IRYHUE2_POS5 : +{0x6ECE,0xFFF8,0x02}, // IBYHUE3_POS5 : +{0x6ED0,0xFFEE,0x02}, // IRYHUE3_POS5 : +{0x6ED2,0x0000,0x02}, // IBYHUE4_POS5 : +{0x6ED4,0xFFEC,0x02}, // IRYHUE4_POS5 : +{0x6ED6,0x0000,0x02}, // IBYHUE1_POS6 : +{0x6ED8,0xFFF5,0x02}, // IRYHUE1_POS6 : +{0x6EDA,0xFFF8,0x02}, // IBYHUE2_POS6 : +{0x6EDC,0xFFF5,0x02}, // IRYHUE2_POS6 : +{0x6EDE,0xFFF8,0x02}, // IBYHUE3_POS6 : +{0x6EE0,0xFFEE,0x02}, // IRYHUE3_POS6 : +{0x6EE2,0x0000,0x02}, // IBYHUE4_POS6 : +{0x6EE4,0xFFEC,0x02}, // IRYHUE4_POS6 : +{0x6EE6,0x0000,0x02}, // IBYHUE1_POS7 : +{0x6EE8,0xFFF5,0x02}, // IRYHUE1_POS7 : +{0x6EEA,0xFFEA,0x02}, // IBYHUE2_POS7 : +{0x6EEC,0xFFF5,0x02}, // IRYHUE2_POS7 : +{0x6EEE,0xFFEA,0x02}, // IBYHUE3_POS7 : +{0x6EF0,0xFFEE,0x02}, // IRYHUE3_POS7 : +{0x6EF2,0x0000,0x02}, // IBYHUE4_POS7 : +{0x6EF4,0xFFEC,0x02}, // IRYHUE4_POS7 : +{0x6EF6,0xFFF2,0x02}, // IBYHUE1_OUT : +{0x6EF8,0x0000,0x02}, // IRYHUE1_OUT : +{0x6EFA,0xFFFA,0x02}, // IBYHUE2_OUT : +{0x6EFC,0x0000,0x02}, // IRYHUE2_OUT : +{0x6EFE,0xFFFA,0x02}, // IBYHUE3_OUT : +{0x6F00,0xFFE7,0x02}, // IRYHUE3_OUT : +{0x6F02,0xFFF2,0x02}, // IBYHUE4_OUT : +{0x6F04,0xFFE7,0x02}, // IRYHUE4_OUT : +{0x6F06,0x0000,0x02}, // IBYHUE1_R2_POS4 : +{0x6F08,0xFFF5,0x02}, // IRYHUE1_R2_POS4 : +{0x6F0A,0xFFF8,0x02}, // IBYHUE2_R2_POS4 : +{0x6F0C,0xFFF5,0x02}, // IRYHUE2_R2_POS4 : +{0x6F0E,0xFFF8,0x02}, // IBYHUE3_R2_POS4 : +{0x6F10,0xFFEE,0x02}, // IRYHUE3_R2_POS4 : +{0x6F12,0x0000,0x02}, // IBYHUE4_R2_POS4 : +{0x6F14,0xFFEC,0x02}, // IRYHUE4_R2_POS4 : +{0x6F16,0x0000,0x02}, // IBYHUE1_R2_POS5 : +{0x6F18,0xFFF5,0x02}, // IRYHUE1_R2_POS5 : +{0x6F1A,0xFFF8,0x02}, // IBYHUE2_R2_POS5 : +{0x6F1C,0xFFF5,0x02}, // IRYHUE2_R2_POS5 : +{0x6F1E,0xFFF8,0x02}, // IBYHUE3_R2_POS5 : +{0x6F20,0xFFEE,0x02}, // IRYHUE3_R2_POS5 : +{0x6F22,0x0000,0x02}, // IBYHUE4_R2_POS5 : +{0x6F24,0xFFEC,0x02}, // IRYHUE4_R2_POS5 : +{0x6F26,0x4B,0x01}, // IRYGAIN1_POS1 : +{0x6F27,0x50,0x01}, // IBYGAIN1_POS1 : +{0x6F28,0x4B,0x01}, // IRYGAIN2_POS1 : +{0x6F29,0x57,0x01}, // IBYGAIN2_POS1 : +{0x6F2A,0x56,0x01}, // IRYGAIN3_POS1 : +{0x6F2B,0x57,0x01}, // IBYGAIN3_POS1 : +{0x6F2C,0x56,0x01}, // IRYGAIN4_POS1 : +{0x6F2D,0x50,0x01}, // IBYGAIN4_POS1 : +{0x6F2E,0x4B,0x01}, // IRYGAIN1_POS2 : +{0x6F2F,0x50,0x01}, // IBYGAIN1_POS2 : +{0x6F30,0x4B,0x01}, // IRYGAIN2_POS2 : +{0x6F31,0x57,0x01}, // IBYGAIN2_POS2 : +{0x6F32,0x54,0x01}, // IRYGAIN3_POS2 : +{0x6F33,0x57,0x01}, // IBYGAIN3_POS2 : +{0x6F34,0x54,0x01}, // IRYGAIN4_POS2 : +{0x6F35,0x50,0x01}, // IBYGAIN4_POS2 : +{0x6F36,0x4B,0x01}, // IRYGAIN1_POS3 : +{0x6F37,0x50,0x01}, // IBYGAIN1_POS3 : +{0x6F38,0x4B,0x01}, // IRYGAIN2_POS3 : +{0x6F39,0x57,0x01}, // IBYGAIN2_POS3 : +{0x6F3A,0x50,0x01}, // IRYGAIN3_POS3 : +{0x6F3B,0x57,0x01}, // IBYGAIN3_POS3 : +{0x6F3C,0x50,0x01}, // IRYGAIN4_POS3 : +{0x6F3D,0x50,0x01}, // IBYGAIN4_POS3 : +{0x6F3E,0x4B,0x01}, // IRYGAIN1_POS4 : +{0x6F3F,0x50,0x01}, // IBYGAIN1_POS4 : +{0x6F40,0x4B,0x01}, // IRYGAIN2_POS4 : +{0x6F41,0x57,0x01}, // IBYGAIN2_POS4 : +{0x6F42,0x50,0x01}, // IRYGAIN3_POS4 : +{0x6F43,0x57,0x01}, // IBYGAIN3_POS4 : +{0x6F44,0x50,0x01}, // IRYGAIN4_POS4 : +{0x6F45,0x50,0x01}, // IBYGAIN4_POS4 : +{0x6F46,0x4B,0x01}, // IRYGAIN1_POS5 : +{0x6F47,0x50,0x01}, // IBYGAIN1_POS5 : +{0x6F48,0x4B,0x01}, // IRYGAIN2_POS5 : +{0x6F49,0x57,0x01}, // IBYGAIN2_POS5 : +{0x6F4A,0x50,0x01}, // IRYGAIN3_POS5 : +{0x6F4B,0x57,0x01}, // IBYGAIN3_POS5 : +{0x6F4C,0x50,0x01}, // IRYGAIN4_POS5 : +{0x6F4D,0x50,0x01}, // IBYGAIN4_POS5 : +{0x6F4E,0x4B,0x01}, // IRYGAIN1_POS6 : +{0x6F4F,0x50,0x01}, // IBYGAIN1_POS6 : +{0x6F50,0x4B,0x01}, // IRYGAIN2_POS6 : +{0x6F51,0x57,0x01}, // IBYGAIN2_POS6 : +{0x6F52,0x50,0x01}, // IRYGAIN3_POS6 : +{0x6F53,0x57,0x01}, // IBYGAIN3_POS6 : +{0x6F54,0x50,0x01}, // IRYGAIN4_POS6 : +{0x6F55,0x50,0x01}, // IBYGAIN4_POS6 : +{0x6F56,0x4B,0x01}, // IRYGAIN1_POS7 : +{0x6F57,0x50,0x01}, // IBYGAIN1_POS7 : +{0x6F58,0x4B,0x01}, // IRYGAIN2_POS7 : +{0x6F59,0x57,0x01}, // IBYGAIN2_POS7 : +{0x6F5A,0x50,0x01}, // IRYGAIN3_POS7 : +{0x6F5B,0x57,0x01}, // IBYGAIN3_POS7 : +{0x6F5C,0x50,0x01}, // IRYGAIN4_POS7 : +{0x6F5D,0x50,0x01}, // IBYGAIN4_POS7 : +{0x6F5E,0x50,0x01}, // IRYGAIN1_OUT : +{0x6F5F,0x5A,0x01}, // IBYGAIN1_OUT : +{0x6F60,0x50,0x01}, // IRYGAIN2_OUT : +{0x6F61,0x51,0x01}, // IBYGAIN2_OUT : +{0x6F62,0x64,0x01}, // IRYGAIN3_OUT : +{0x6F63,0x51,0x01}, // IBYGAIN3_OUT : +{0x6F64,0x64,0x01}, // IRYGAIN4_OUT : +{0x6F65,0x5A,0x01}, // IBYGAIN4_OUT : +{0x6F66,0x4B,0x01}, // IRYGAIN1_R2_POS4 : +{0x6F67,0x50,0x01}, // IBYGAIN1_R2_POS4 : +{0x6F68,0x4B,0x01}, // IRYGAIN2_R2_POS4 : +{0x6F69,0x57,0x01}, // IBYGAIN2_R2_POS4 : +{0x6F6A,0x50,0x01}, // IRYGAIN3_R2_POS4 : +{0x6F6B,0x57,0x01}, // IBYGAIN3_R2_POS4 : +{0x6F6C,0x50,0x01}, // IRYGAIN4_R2_POS4 : +{0x6F6D,0x50,0x01}, // IBYGAIN4_R2_POS4 : +{0x6F6E,0x4B,0x01}, // IRYGAIN1_R2_POS5 : +{0x6F6F,0x50,0x01}, // IBYGAIN1_R2_POS5 : +{0x6F70,0x4B,0x01}, // IRYGAIN2_R2_POS5 : +{0x6F71,0x57,0x01}, // IBYGAIN2_R2_POS5 : +{0x6F72,0x50,0x01}, // IRYGAIN3_R2_POS5 : +{0x6F73,0x57,0x01}, // IBYGAIN3_R2_POS5 : +{0x6F74,0x50,0x01}, // IRYGAIN4_R2_POS5 : +{0x6F75,0x50,0x01}, // IBYGAIN4_R2_POS5 : + + +//LMT outdoor setting +{0x6E54,0xFFB1,0x02}, // LM_GRG_OUT : +{0x6E56,0x0015,0x02}, // LM_GRB_OUT : +{0x6E58,0xFFE5,0x02}, // LM_GGR_OUT : +{0x6E5A,0xFFFA,0x02}, // LM_GGB_OUT : +{0x6E5C,0xFFDA,0x02}, // LM_GBR_OUT : +{0x6E5E,0xFFE9,0x02}, // LM_GBG_OUT : + +//MC3 ON&OFF +{0x6C49,0xF5,0x01}, // MAIN_CONFIG4 : + + +//////////////////////////////////////////////////////////////// + +{0x941F,0x00,0x01}, // AP_N_GC_POS_CORE_A : < 0x6 +{0x5C05,0x05,0x01}, // RGTCLKPREPARE : //0x5C05 0x3 -> 0x5 +{0x5C06,0x14,0x01}, // RGTCLKZERO : +{0x5C07,0x02,0x01}, // RGTCLKPRE : +{0x5C08,0x0D,0x01}, // RGTCLKPOST : //0x5C08 0x11 -> 0xD +{0x5C09,0x07,0x01}, // RGTCLKTRAIL : //0x5C09 0x5 -> 0x7 +{0x5C0A,0x0A,0x01}, // RGTHSEXIT : //0x5C0A 0x7 -> 0xA +{0x5C0B,0x05,0x01}, // RGTHSPREPARE : //0x5C0B 0x3 -> 0x5 +{0x5C0C,0x08,0x01}, // RGTHSZERO : //0x5C0C 0x7 -> 0x8 +{0x5C0D,0x07,0x01}, // RGTHSTRAIL : //0x5C0D 0x5 -> 0x7 + +{0x0009,0x01,0x01}, // EXT_PLL_CKSEL : PLL 648MHz +{0x00D0,0x11,0x01}, // VIF_CLKCONFIG_EXT1 : VIFSEL and VIFDIV setting value with full frame pixel setting for JPG and interleave mode +{0x00D1,0x11,0x01}, // VIF_CLKCONFIG_EXT2 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for JPG and interleave mode +{0x00D4,0x11,0x01}, // VIF_CLKCONFIG_EXT5 : VIFSEL and VIFDIV setting value with full frame pixel setting for JPG mode +{0x00D5,0x11,0x01}, // VIF_CLKCONFIG_EXT6 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for JPG mode +{0x00D8,0x11,0x01}, // VIF_CLKCONFIG_EXT9 : VIFSEL and VIFDIV setting value with full frame pixel setting for other than JPG +{0x00D9,0x11,0x01}, // VIF_CLKCONFIG_EXT10 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for other than JPG + +//init Preview setting +{0x0089,0x00,0x01},//OUTFMT_MONI +{0x0090,0x0280,0x02},//HSIZE_MONI : 640 +{0x0096,0x01E0,0x02},//VSIZE_MONI : 480 +{0x0083,0x01,0x01},//SENSMODE_MONI +{0x0086,0x02,0x01},//FPSTYPE_MONI +{0x0081,0x00,0x01},//MODESEL +{0x0082,0x01,0x01},//MONI_REFRESH + +//jpeg setting +//Apex40 is not Jpeg Capture + +//Fast mode setting +{0x500A,0x00,0x01}, // FAST_MODECHG_EN +{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL +{0x500C,0x00FA,0x02}, // FAST_SHT_LIMIT_COUNT + +//Select sensor inversion link control +{0x501A,0x00,0x01}, //SENS_REVERSE_CTRL + +//shading +{0x6DBC,0x03,0x01}, // WHITE_EDGE_MAX : +{0x6DF6,0xFF,0x01}, // WHITE_SHD_JUDGE_BODY_COLOR_RATIO : +{0x6DF7,0xF0,0x01}, // WHITE_SHD_JUDGE_RED_RATIO : +{0x6DAD,0x0C,0x01}, // WHITE_OFSET1_UP : +{0x6DAE,0x0C,0x01}, // WHITE_OFSET1_DOWN : +{0x6DAF,0x11,0x01}, // WHITE_OFSET1_RIGHT : +{0x6DB0,0x1B,0x01}, // WHITE_OFSET1_LEFT : +{0x6DB1,0x0D,0x01}, // WHITE_OFSET2_UP : +{0x6DB2,0x13,0x01}, // WHITE_OFSET2_DOWN : +{0x6DB3,0x11,0x01}, // WHITE_OFSET2_RIGHT : +{0x6DB4,0x17,0x01}, // WHITE_OFSET2_LEFT : + +//addtional code +{0xF200,0xB9B9,0x02}, +{0xF202,0x4E12,0x02}, +{0xF204,0x6055,0x02}, +{0xF206,0x008B,0x02}, +{0xF208,0xF177,0x02}, +{0xF20A,0xFA70,0x02}, +{0xF20C,0x0000,0x02}, +{0xF20E,0x0000,0x02}, +{0xF210,0x0000,0x02}, +{0xF212,0x0000,0x02}, +{0xF214,0x0000,0x02}, +{0xF216,0x0000,0x02}, +{0xF218,0x0000,0x02}, +{0xF21A,0x0000,0x02}, +{0xF21C,0x0000,0x02}, +{0xF21E,0x0000,0x02}, +{0xF220,0x0000,0x02}, +{0xF222,0x0000,0x02}, +{0xF224,0x0000,0x02}, +{0xF226,0x0000,0x02}, +{0xF228,0x0000,0x02}, +{0xF22A,0x0000,0x02}, +{0xF22C,0x0000,0x02}, +{0xF22E,0x0000,0x02}, +{0xF230,0x0000,0x02}, +{0xF232,0x0000,0x02}, +{0xF234,0x0000,0x02}, +{0xF236,0x0000,0x02}, +{0xF238,0x0000,0x02}, +{0xF23A,0x0000,0x02}, +{0xF23C,0x0000,0x02}, +{0xF23E,0x0000,0x02}, +{0xF240,0x0000,0x02}, +{0xF242,0x0000,0x02}, +{0xF244,0xB47E,0x02}, +{0xF246,0x4808,0x02}, +{0xF248,0x7800,0x02}, +{0xF24A,0x07C0,0x02}, +{0xF24C,0x0FC0,0x02}, +{0xF24E,0xF687,0x02}, +{0xF250,0xF8ED,0x02}, +{0xF252,0xF68E,0x02}, +{0xF254,0xFE2B,0x02}, +{0xF256,0xF688,0x02}, +{0xF258,0xFF6B,0x02}, +{0xF25A,0xF693,0x02}, +{0xF25C,0xFB6B,0x02}, +{0xF25E,0xF687,0x02}, +{0xF260,0xF947,0x02}, +{0xF262,0xBC7E,0x02}, +{0xF264,0xF688,0x02}, +{0xF266,0xFD8F,0x02}, +{0xF268,0x239C,0x02}, +{0xF26A,0x0018,0x02}, + + +{0x0006,0x16,0x01}, //INCK_SET : 24MHz +}; + +// ISX012-0 +// MIPI 2LANE 432/LANE +// PLL 432MHz +// DCK 54 +// inifile +// size address data +// +static const isx012_regset_t ISX012_Pll_Setting_3[] = +{ +{0x0007,0x00,0x01}, // PLL_CKSEL : PLL 432MHz +{0x0008,0x00,0x01}, // SRCCK_DIV : 1/5 frequency + +{0x0004,0x03,0x01}, //I2C_ADR_SEL 2: 0x3C MIPI selected, 3: 0x3D MIPI selected +{0x5008,0x00,0x01}, //ENDIAN_SEL : 0:Little Endian +{0x6DA8,0x01,0x01}, //SHD_CoEF (OTP shading ON flag) +{0x6DA9,0x09,0x01}, // WHITE_CTRL +{0x6DCB,0x22,0x01}, // YGAM_CONFIG2 : + +{0x00C4,0x11,0x01}, // VIF_CLKCONFIG1 : VIFSEL and VIFDIV setting value with full frame pixel setting for other then JPG +{0x00C5,0x11,0x01}, // VIF_CLKCONFIG2 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for other then JPG +{0x00C6,0x11,0x01}, // VIF_CLKCONFIG3 : VIFSEL and VIFDIV setting value with 1/4 sub-sampling setting for other then JPG +{0x00C7,0x11,0x01}, // VIF_CLKCONFIG4 : VIFSEL and VIFDIV setting value with 1/8 sub-sampling setting for other then JPG +{0x00C8,0x11,0x01}, // VIF_CLKCONFIG5 : VIFSEL and VIFDIV setting value with full frame pixel setting for JPG mode +{0x00C9,0x11,0x01}, // VIF_CLKCONFIG6 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for JPG mode +{0x00CA,0x11,0x01}, // VIF_CLKCONFIG7 : VIFSEL and VIFDIV setting value with 1/4 sub-sampling setting for JPG mode +{0x00CC,0x11,0x01}, // VIF_CLKCONFIG9 : VIFSEL and VIFDIV setting value with full frame pixel setting for JPG and interleave mode +{0x00CD,0x11,0x01}, // VIF_CLKCONFIG10 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for JPG and interleave mode +{0x6A12,0x11,0x01}, // VIF_CLKCONFIG13 for RAW8 : VIFSEL and VIFDIV setting value with full frame pixel setting for RAW mode +{0x6A13,0x11,0x01}, // VIF_CLKCONFIG14 for RAW8 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for RAW mode +{0x6A14,0x11,0x01}, // VIF_CLKCONFIG15 for RAW8 : VIFSEL and VIFDIV setting value with 1/4 sub-sampling setting for RAW mode +{0x6A15,0x11,0x01}, // VIF_CLKCONFIG16 for RAW8 : VIFSEL and VIFDIV setting value with 1/8 sub-sampling setting for RAW mode +{0x018C,0x0000,0x02}, // VADJ_SENS_1_1 : VMAX adjustment value for full frame pixel +{0x018E,0x0012,0x02}, // VADJ_SENS_1_2 : VMAX adjustment value for 1/2 sub-sampling +{0x0190,0x0000,0x02}, // VADJ_SENS_1_4 : VMAX adjustment value for 1/4 sub-sampling +{0x0192,0x0000,0x02}, // VADJ_SENS_1_8 : VMAX adjustment value for 1/8 sub-sampling +{0x0194,0x0027,0x02}, // VADJ_SENS_HD_1_1 : VMAX adjustment value for HD full frame pixel +{0x0196,0x0015,0x02}, // VADJ_SENS_HD_1_2 : VMAX adjustment value for HD 1/2 sub-sampling +{0x6A16,0x0440,0x02}, // FLC_OPD_HEIGHT_NORMAL_1_1 : Detection window vertical size with all 32 windows for FLC full frame pixel +{0x6A18,0x03C0,0x02}, // FLC_OPD_HEIGHT_NORMAL_1_2 : Detection window vertical size with all 32 windows for FLC 1/2 sub-sampling +{0x6A1A,0x01E0,0x02}, // FLC_OPD_HEIGHT_NORMAL_1_4 : Detection window vertical size with all 32 windows for FLC 1/4 sub-sampling +{0x6A1C,0x00E0,0x02}, // FLC_OPD_HEIGHT_NORMAL_1_8 : Detection window vertical size with all 32 windows for FLC 1/8 sub-sampling +{0x6A1E,0x0420,0x02}, // FLC_OPD_HEIGHT_HD_1_1 : Detection window vertical size with all 32 windows for FLC HD full frame pixel +{0x6A20,0x02C0,0x02}, // FLC_OPD_HEIGHT_HD_1_2 : Detection window vertical size with all 32 windows for FLC HD 1/2 sub-sampling +{0x0016,0x0010,0x02}, // GPIO_FUNCSEL : GPIO setting +{0x5C01,0x00,0x01}, // RGLANESEL : +{0x5C04,0x04,0x01}, // RGTLPX : +{0x5C05,0x03,0x01}, // RGTCLKPREPARE : +{0x5C06,0x0E,0x01}, // RGTCLKZERO : +{0x5C07,0x02,0x01}, // RGTCLKPRE : +{0x5C08,0x0B,0x01}, // RGTCLKPOST : +{0x5C09,0x05,0x01}, // RGTCLKTRAIL : +{0x5C0A,0x07,0x01}, // RGTHSEXIT : +{0x5C0B,0x03,0x01}, // RGTHSPREPARE : +{0x5C0C,0x07,0x01}, // RGTHSZERO : +{0x5C0D,0x05,0x01}, // RGTHSTRAIL : + +{0x0009,0x01,0x01}, // +{0x000A,0x03,0x01}, // EXT_SRCCK_DIV : 1/8 frequency +{0x00D8,0x11,0x01}, // VIF_CLKCONFIG_EXT9 : VIFSEL and VIFDIV setting value with full frame pixel setting for other than JPG +{0x00D9,0x11,0x01}, // VIF_CLKCONFIG_EXT10 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for other than JPG +{0x00DA,0x11,0x01}, // VIF_CLKCONFIG_EXT11 : VIFSEL and VIFDIV setting value with 1/4 sub-sampling setting for other than JPG +{0x00DB,0x11,0x01}, // VIF_CLKCONFIG_EXT12 : VIFSEL and VIFDIV setting value with 1/8 sub-sampling setting for other than JPG +{0x00AC,0x02,0x01}, // + +//init Preview setting +{0x0089,0x00,0x01},//OUTFMT_MONI +{0x0090,0x0280,0x02},//HSIZE_MONI : 640 +{0x0096,0x01E0,0x02},//VSIZE_MONI : 480 +{0x0083,0x01,0x01},//SENSMODE_MONI +{0x0086,0x02,0x01},//FPSTYPE_MONI +{0x0081,0x00,0x01},//MODESEL +{0x0082,0x01,0x01},//MONI_REFRESH + +//jpeg setting +//Apex40 is not Jpeg Capture + +//Fast mode setting +{0x500A,0x00,0x01}, // FAST_MODECHG_EN +{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL +{0x500C,0x00FA,0x02}, // FAST_SHT_LIMIT_COUNT + +//Select sensor inversion link control +{0x501A,0x00,0x01}, //SENS_REVERSE_CTRL + +//shading +{0x6DBC,0x03,0x01}, // WHITE_EDGE_MAX : +{0x6DF6,0xFF,0x01}, // WHITE_SHD_JUDGE_BODY_COLOR_RATIO : +{0x6DF7,0xF0,0x01}, // WHITE_SHD_JUDGE_RED_RATIO : +{0x6DAD,0x0C,0x01}, // WHITE_OFSET1_UP : +{0x6DAE,0x0C,0x01}, // WHITE_OFSET1_DOWN : +{0x6DAF,0x11,0x01}, // WHITE_OFSET1_RIGHT : +{0x6DB0,0x1B,0x01}, // WHITE_OFSET1_LEFT : +{0x6DB1,0x0D,0x01}, // WHITE_OFSET2_UP : +{0x6DB2,0x13,0x01}, // WHITE_OFSET2_DOWN : +{0x6DB3,0x11,0x01}, // WHITE_OFSET2_RIGHT : +{0x6DB4,0x17,0x01}, // WHITE_OFSET2_LEFT : + +//additional code +{0xF200,0xB9B9,0x02}, +{0xF202,0x4E12,0x02}, +{0xF204,0x6055,0x02}, +{0xF206,0x008B,0x02}, +{0xF208,0xF177,0x02}, +{0xF20A,0xFA70,0x02}, +{0xF20C,0x0000,0x02}, +{0xF20E,0x0000,0x02}, +{0xF210,0x0000,0x02}, +{0xF212,0x0000,0x02}, +{0xF214,0x0000,0x02}, +{0xF216,0x0000,0x02}, +{0xF218,0x0000,0x02}, +{0xF21A,0x0000,0x02}, +{0xF21C,0x0000,0x02}, +{0xF21E,0x0000,0x02}, +{0xF220,0x0000,0x02}, +{0xF222,0x0000,0x02}, +{0xF224,0x0000,0x02}, +{0xF226,0x0000,0x02}, +{0xF228,0x0000,0x02}, +{0xF22A,0x0000,0x02}, +{0xF22C,0x0000,0x02}, +{0xF22E,0x0000,0x02}, +{0xF230,0x0000,0x02}, +{0xF232,0x0000,0x02}, +{0xF234,0x0000,0x02}, +{0xF236,0x0000,0x02}, +{0xF238,0x0000,0x02}, +{0xF23A,0x0000,0x02}, +{0xF23C,0x0000,0x02}, +{0xF23E,0x0000,0x02}, +{0xF240,0x0000,0x02}, +{0xF242,0x0000,0x02}, +{0xF244,0xB47E,0x02}, +{0xF246,0x4808,0x02}, +{0xF248,0x7800,0x02}, +{0xF24A,0x07C0,0x02}, +{0xF24C,0x0FC0,0x02}, +{0xF24E,0xF687,0x02}, +{0xF250,0xF8ED,0x02}, +{0xF252,0xF68E,0x02}, +{0xF254,0xFE2B,0x02}, +{0xF256,0xF688,0x02}, +{0xF258,0xFF6B,0x02}, +{0xF25A,0xF693,0x02}, +{0xF25C,0xFB6B,0x02}, +{0xF25E,0xF687,0x02}, +{0xF260,0xF947,0x02}, +{0xF262,0xBC7E,0x02}, +{0xF264,0xF688,0x02}, +{0xF266,0xFD8F,0x02}, +{0xF268,0x239C,0x02}, +{0xF26A,0x0018,0x02}, + +{0x0006,0x16,0x01}, //INCK_SET : 24MHz +}; + +// ISX012-0 +// MIPI 2LANE 432/LANE +// PLL 432MHz +// DCK 54 +// inifile +// size address data +// +static const isx012_regset_t ISX012_Pll_Setting_4[] = +{ +{0x0007,0x00,0x01}, // PLL_CKSEL : PLL 432MHz +{0x0008,0x00,0x01}, // SRCCK_DIV : 1/5 frequency + +{0x0004,0x03,0x01}, //I2C_ADR_SEL 2: 0x3C MIPI selected, 3: 0x3D MIPI selected +{0x5008,0x00,0x01}, //ENDIAN_SEL : 0:Little Endian +{0x6DA8,0x01,0x01}, //SHD_CoEF (OTP shading ON flag) +{0x6DA9,0x09,0x01}, // WHITE_CTRL +{0x6DCB,0x22,0x01}, // YGAM_CONFIG2 : + +{0x00C4,0x11,0x01}, // VIF_CLKCONFIG1 : VIFSEL and VIFDIV setting value with full frame pixel setting for other then JPG +{0x00C5,0x11,0x01}, // VIF_CLKCONFIG2 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for other then JPG +{0x00C6,0x11,0x01}, // VIF_CLKCONFIG3 : VIFSEL and VIFDIV setting value with 1/4 sub-sampling setting for other then JPG +{0x00C7,0x11,0x01}, // VIF_CLKCONFIG4 : VIFSEL and VIFDIV setting value with 1/8 sub-sampling setting for other then JPG +{0x00C8,0x11,0x01}, // VIF_CLKCONFIG5 : VIFSEL and VIFDIV setting value with full frame pixel setting for JPG mode +{0x00C9,0x11,0x01}, // VIF_CLKCONFIG6 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for JPG mode +{0x00CA,0x11,0x01}, // VIF_CLKCONFIG7 : VIFSEL and VIFDIV setting value with 1/4 sub-sampling setting for JPG mode +{0x00CC,0x11,0x01}, // VIF_CLKCONFIG9 : VIFSEL and VIFDIV setting value with full frame pixel setting for JPG and interleave mode +{0x00CD,0x11,0x01}, // VIF_CLKCONFIG10 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for JPG and interleave mode +{0x6A12,0x11,0x01}, // VIF_CLKCONFIG13 for RAW8 : VIFSEL and VIFDIV setting value with full frame pixel setting for RAW mode +{0x6A13,0x11,0x01}, // VIF_CLKCONFIG14 for RAW8 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for RAW mode +{0x6A14,0x11,0x01}, // VIF_CLKCONFIG15 for RAW8 : VIFSEL and VIFDIV setting value with 1/4 sub-sampling setting for RAW mode +{0x6A15,0x11,0x01}, // VIF_CLKCONFIG16 for RAW8 : VIFSEL and VIFDIV setting value with 1/8 sub-sampling setting for RAW mode +{0x018C,0x0026,0x02}, // VADJ_SENS_1_1 : VMAX adjustment value for full frame pixel +{0x018E,0x0012,0x02}, // VADJ_SENS_1_2 : VMAX adjustment value for 1/2 sub-sampling +{0x0190,0x0000,0x02}, // VADJ_SENS_1_4 : VMAX adjustment value for 1/4 sub-sampling +{0x0192,0x0000,0x02}, // VADJ_SENS_1_8 : VMAX adjustment value for 1/8 sub-sampling +{0x0194,0x0027,0x02}, // VADJ_SENS_HD_1_1 : VMAX adjustment value for HD full frame pixel +{0x0196,0x0015,0x02}, // VADJ_SENS_HD_1_2 : VMAX adjustment value for HD 1/2 sub-sampling +{0x6A16,0x0440,0x02}, // FLC_OPD_HEIGHT_NORMAL_1_1 : Detection window vertical size with all 32 windows for FLC full frame pixel +{0x6A18,0x03C0,0x02}, // FLC_OPD_HEIGHT_NORMAL_1_2 : Detection window vertical size with all 32 windows for FLC 1/2 sub-sampling +{0x6A1A,0x01E0,0x02}, // FLC_OPD_HEIGHT_NORMAL_1_4 : Detection window vertical size with all 32 windows for FLC 1/4 sub-sampling +{0x6A1C,0x00E0,0x02}, // FLC_OPD_HEIGHT_NORMAL_1_8 : Detection window vertical size with all 32 windows for FLC 1/8 sub-sampling +{0x6A1E,0x0420,0x02}, // FLC_OPD_HEIGHT_HD_1_1 : Detection window vertical size with all 32 windows for FLC HD full frame pixel +{0x6A20,0x02C0,0x02}, // FLC_OPD_HEIGHT_HD_1_2 : Detection window vertical size with all 32 windows for FLC HD 1/2 sub-sampling +{0x0016,0x0010,0x02}, // GPIO_FUNCSEL : GPIO setting +{0x5C01,0x00,0x01}, // RGLANESEL : +{0x5C04,0x04,0x01}, // RGTLPX : +{0x5C05,0x03,0x01}, // RGTCLKPREPARE : +{0x5C06,0x0E,0x01}, // RGTCLKZERO : +{0x5C07,0x02,0x01}, // RGTCLKPRE : +{0x5C08,0x0B,0x01}, // RGTCLKPOST : +{0x5C09,0x05,0x01}, // RGTCLKTRAIL : +{0x5C0A,0x07,0x01}, // RGTHSEXIT : +{0x5C0B,0x03,0x01}, // RGTHSPREPARE : +{0x5C0C,0x07,0x01}, // RGTHSZERO : +{0x5C0D,0x05,0x01}, // RGTHSTRAIL : + +{0x6A9E,0x15C0,0x02}, //HMAX_1_1(0x6A9E)=0x15C0 + +{0x0009,0x01,0x01}, // +{0x000A,0x03,0x01}, // EXT_SRCCK_DIV : 1/8 frequency +{0x00D8,0x11,0x01}, // VIF_CLKCONFIG_EXT9 : VIFSEL and VIFDIV setting value with full frame pixel setting for other than JPG +{0x00D9,0x11,0x01}, // VIF_CLKCONFIG_EXT10 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for other than JPG +{0x00DA,0x11,0x01}, // VIF_CLKCONFIG_EXT11 : VIFSEL and VIFDIV setting value with 1/4 sub-sampling setting for other than JPG +{0x00DB,0x11,0x01}, // VIF_CLKCONFIG_EXT12 : VIFSEL and VIFDIV setting value with 1/8 sub-sampling setting for other than JPG +{0x00AC,0x00,0x01}, // + +//init Preview setting +{0x0089,0x00,0x01},//OUTFMT_MONI +{0x0090,0x0280,0x02},//HSIZE_MONI : 640 +{0x0096,0x01E0,0x02},//VSIZE_MONI : 480 +{0x0083,0x01,0x01},//SENSMODE_MONI +{0x0086,0x02,0x01},//FPSTYPE_MONI +{0x0081,0x00,0x01},//MODESEL +{0x0082,0x01,0x01},//MONI_REFRESH + +//jpeg setting +//Apex40 is not Jpeg Capture + +//Fast mode setting +{0x500A,0x00,0x01}, // FAST_MODECHG_EN +{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL +{0x500C,0x00FA,0x02}, // FAST_SHT_LIMIT_COUNT + +//Select sensor inversion link control +{0x501A,0x00,0x01}, //SENS_REVERSE_CTRL + +//shading +{0x6DBC,0x03,0x01}, // WHITE_EDGE_MAX : +{0x6DF6,0xFF,0x01}, // WHITE_SHD_JUDGE_BODY_COLOR_RATIO : +{0x6DF7,0xF0,0x01}, // WHITE_SHD_JUDGE_RED_RATIO : +{0x6DAD,0x0C,0x01}, // WHITE_OFSET1_UP : +{0x6DAE,0x0C,0x01}, // WHITE_OFSET1_DOWN : +{0x6DAF,0x11,0x01}, // WHITE_OFSET1_RIGHT : +{0x6DB0,0x1B,0x01}, // WHITE_OFSET1_LEFT : +{0x6DB1,0x0D,0x01}, // WHITE_OFSET2_UP : +{0x6DB2,0x13,0x01}, // WHITE_OFSET2_DOWN : +{0x6DB3,0x11,0x01}, // WHITE_OFSET2_RIGHT : +{0x6DB4,0x17,0x01}, // WHITE_OFSET2_LEFT : + +//additional code +{0xF200,0xB9B9,0x02}, +{0xF202,0x4E12,0x02}, +{0xF204,0x6055,0x02}, +{0xF206,0x008B,0x02}, +{0xF208,0xF177,0x02}, +{0xF20A,0xFA70,0x02}, +{0xF20C,0x0000,0x02}, +{0xF20E,0x0000,0x02}, +{0xF210,0x0000,0x02}, +{0xF212,0x0000,0x02}, +{0xF214,0x0000,0x02}, +{0xF216,0x0000,0x02}, +{0xF218,0x0000,0x02}, +{0xF21A,0x0000,0x02}, +{0xF21C,0x0000,0x02}, +{0xF21E,0x0000,0x02}, +{0xF220,0x0000,0x02}, +{0xF222,0x0000,0x02}, +{0xF224,0x0000,0x02}, +{0xF226,0x0000,0x02}, +{0xF228,0x0000,0x02}, +{0xF22A,0x0000,0x02}, +{0xF22C,0x0000,0x02}, +{0xF22E,0x0000,0x02}, +{0xF230,0x0000,0x02}, +{0xF232,0x0000,0x02}, +{0xF234,0x0000,0x02}, +{0xF236,0x0000,0x02}, +{0xF238,0x0000,0x02}, +{0xF23A,0x0000,0x02}, +{0xF23C,0x0000,0x02}, +{0xF23E,0x0000,0x02}, +{0xF240,0x0000,0x02}, +{0xF242,0x0000,0x02}, +{0xF244,0xB47E,0x02}, +{0xF246,0x4808,0x02}, +{0xF248,0x7800,0x02}, +{0xF24A,0x07C0,0x02}, +{0xF24C,0x0FC0,0x02}, +{0xF24E,0xF687,0x02}, +{0xF250,0xF8ED,0x02}, +{0xF252,0xF68E,0x02}, +{0xF254,0xFE2B,0x02}, +{0xF256,0xF688,0x02}, +{0xF258,0xFF6B,0x02}, +{0xF25A,0xF693,0x02}, +{0xF25C,0xFB6B,0x02}, +{0xF25E,0xF687,0x02}, +{0xF260,0xF947,0x02}, +{0xF262,0xBC7E,0x02}, +{0xF264,0xF688,0x02}, +{0xF266,0xFD8F,0x02}, +{0xF268,0x239C,0x02}, +{0xF26A,0x0018,0x02}, + +{0x0006,0x16,0x01}, //INCK_SET : 24MHz +}; + +static const isx012_regset_t ISX012_Preview_SizeSetting[] = +{ +{0x0090,0x0280,0x02}, //HSIZE_MONI : 640 +{0x0096,0x01E0,0x02}, //VSIZE_MONI : 480 +}; + +static const isx012_regset_t ISX012_Preview_Mode[] = +{ +{0x5000,0x00,0x01}, /* CPUEXT, added by SAMSUNG TN */ +{0x5E32,0x0F,0x01}, /* for Fast-AE reset */ +{0x5E3D,0x0A,0x01}, /* for Fast-AE reset */ +{0x0181,0x00,0x01}, // CAP_HALF_AE_CTRL + +{0x0089,0x00,0x01}, //OUTFMT_MONI +{0x0083,0x01,0x01}, //SENSMODE_MONI +{0x0086,0x02,0x01}, //FPSTYPE_MONI +{0x0012,0xFF,0x01}, //INTCLR0 +{0x00F7,0x52,0x01}, // INIT_QLTY0 : Standard 82 +{0x00F8,0x59,0x01}, // INIT_QLTY1 : Fine 89 +{0x00F9,0x5F,0x01}, // INIT_QLTY2 : SuperFine 95 +{0x0081,0x00,0x01}, //MODESEL +{0x0082,0x01,0x01}, //MONI_REFRESH +{0xFFFF,0x1E,0x01}, //$wait,30 +}; + +static const isx012_regset_t ISX012_Camcorder_Mode_ON[] = +{ +//SN setting +{0x0308,0x02,0x01}, // AELINE_MONI_SN1_2 : +{0x0320,0x02,0x01}, // AELINE_MONI_SN1_2 : +{0x00B2,0x02,0x01}, /* AFMODE_MONI : manual mode */ + +//BRIGHTNESS setting +{0x01C6,0x10,0x01}, //UIBRIGHTNESS + +//AE speed +{0x02AC,0x00,0x01}, // AE_SUB_SN1 : +{0x5E2D,0x0C,0x01}, // AEMOVECNT : +{0x5E2E,0x20,0x01}, // AEINDEADBAND : +{0x5E2F,0x08,0x01}, // AEOUTDEADBAND : +{0x5E30,0xA0,0x01}, // AESPEED : + +{0x5E31,0x0F,0x01}, // AESPEED_INIT : +{0x5E32,0x0F,0x01}, // AESPEED_FAST : + +{0x621E,0x18,0x01}, // AIM_NR_TH_UP : +{0x621F,0x18,0x01}, // AIM_NR_TH_DOWN : +{0x6220,0x18,0x01}, // AIM_NR_TH_RIGHT : +{0x6221,0x18,0x01}, // AIM_NR_TH_LEFT : + +//AWB speed +{0x6222,0x00,0x01}, // INIT_AIMW : +{0x6223,0x04,0x01}, // INIT_GAINS : +{0x6224,0x10,0x01}, // ATW_DELAY : +{0x6225,0x00,0x01}, // ATW_AIMW : + +{0x6226,0x20,0x01}, // ATW_GAINS_IN_NR : +{0x6227,0x30,0x01}, // ATW_GAINS_IN : +{0x6228,0x20,0x01}, // ATW_GAINS_OUT_NR : +{0x6229,0x30,0x01}, // ATW_GAINS_OUT : +{0x622A,0x0D,0x01}, // ALLWB_GAINS : + +//Gammma Table 0 +{0x7000,0x0000,0x02}, // G0_KNOT_G0 : +{0x7002,0x0000,0x02}, // G0_KNOT_G1 : +{0x7004,0x001E,0x02}, // G0_KNOT_G2 : +{0x7006,0x0038,0x02}, // G0_KNOT_G3 : +{0x7008,0x0046,0x02}, // G0_KNOT_G4 : +{0x700A,0x0053,0x02}, // G0_KNOT_G5 : +{0x700C,0x005A,0x02}, // G0_KNOT_G6 : +{0x700E,0x0063,0x02}, // G0_KNOT_G7 : +{0x7010,0x006D,0x02}, // G0_KNOT_G8 : +{0x7012,0x0076,0x02}, // G0_KNOT_G9 : +{0x7014,0x0055,0x02}, // G0_KNOT_G10 : +{0x7016,0x008E,0x02}, // G0_KNOT_G11 : +{0x7018,0x00B9,0x02}, // G0_KNOT_G12 : +{0x701A,0x00D5,0x02}, // G0_KNOT_G13 : +{0x701C,0x00E4,0x02}, // G0_KNOT_G14 : +{0x701E,0x00F0,0x02}, // G0_KNOT_G15 : +{0x7020,0x00F9,0x02}, // G0_KNOT_G16 : +{0x7022,0x0103,0x02}, // G0_KNOT_G17 : +{0x7024,0x010C,0x02}, // G0_KNOT_G18 : +{0x7026,0x00,0x01}, // G0_KNOT_R0_OFFSET : +{0x7027,0x00,0x01}, // G0_KNOT_R2_OFFSET : +{0x7028,0x00,0x01}, // G0_KNOT_R4_OFFSET : +{0x7029,0x00,0x01}, // G0_KNOT_R6_OFFSET : +{0x702A,0x00,0x01}, // G0_KNOT_R8_OFFSET : +{0x702B,0x00,0x01}, // G0_KNOT_R10_OFFSET : +{0x702C,0x00,0x01}, // G0_KNOT_R12_OFFSET : +{0x702D,0x00,0x01}, // G0_KNOT_R14_OFFSET : +{0x702E,0x00,0x01}, // G0_KNOT_R16_OFFSET : +{0x702F,0x00,0x01}, // G0_KNOT_R18_OFFSET : +{0x7030,0x00,0x01}, // G0_KNOT_B0_OFFSET : +{0x7031,0x00,0x01}, // G0_KNOT_B2_OFFSET : +{0x7032,0x00,0x01}, // G0_KNOT_B4_OFFSET : +{0x7033,0x00,0x01}, // G0_KNOT_B6_OFFSET : +{0x7034,0x00,0x01}, // G0_KNOT_B8_OFFSET : +{0x7035,0x00,0x01}, // G0_KNOT_B10_OFFSET : +{0x7036,0x00,0x01}, // G0_KNOT_B12_OFFSET : +{0x7037,0x00,0x01}, // G0_KNOT_B14_OFFSET : +{0x7038,0x00,0x01}, // G0_KNOT_B16_OFFSET : +{0x7039,0x00,0x01}, // G0_KNOT_B18_OFFSET : +{0x703A,0x0611,0x02}, // G0_LOWGM_ON_R : +{0x703C,0x1E0A,0x02}, // G0_0CLIP_R : +{0x703E,0x0611,0x02}, // G0_LOWGM_ON_G : +{0x7040,0x1E0A,0x02}, // G0_0CLIP_G : +{0x7042,0x0611,0x02}, // G0_LOWGM_ON_B : +{0x7044,0x1E0A,0x02}, // G0_0CLIP_B : +{0x7046,0x91,0x01}, // G0_KNOT_GAINCTRL_TH_L : +{0x7047,0x96,0x01}, // G0_KNOT_GAINCTRL_TH_H : +{0x7048,0x0000,0x02}, // G0_KNOT_L_G0 : +{0x704A,0x0000,0x02}, // G0_KNOT_L_G1 : +{0x704C,0x000E,0x02}, // G0_KNOT_L_G2 : +{0x704E,0x002F,0x02}, // G0_KNOT_L_G3 : +{0x7050,0x003D,0x02}, // G0_KNOT_L_G4 : +{0x7052,0x004A,0x02}, // G0_KNOT_L_G5 : +{0x7054,0x0051,0x02}, // G0_KNOT_L_G6 : +{0x7056,0x005A,0x02}, // G0_KNOT_L_G7 : +{0x7058,0x0061,0x02}, // G0_KNOT_L_G8 : +{0x705A,0x006A,0x02}, // G0_KNOT_L_G9 : +{0x705C,0x0049,0x02}, // G0_KNOT_L_G10 : +{0x705E,0x0082,0x02}, // G0_KNOT_L_G11 : +{0x7060,0x00AD,0x02}, // G0_KNOT_L_G12 : +{0x7062,0x00CC,0x02}, // G0_KNOT_L_G13 : +{0x7064,0x00E1,0x02}, // G0_KNOT_L_G14 : +{0x7066,0x00ED,0x02}, // G0_KNOT_L_G15 : +{0x7068,0x00F6,0x02}, // G0_KNOT_L_G16 : +{0x706A,0x0106,0x02}, // G0_KNOT_L_G17 : +{0x706C,0x010C,0x02}, // G0_KNOT_L_G18 : + + +{0x6400,0x00,0x01}, // INFRM_LEFT00 : +{0x6401,0x00,0x01}, // INFRM_LEFT01 : +{0x6402,0x00,0x01}, // INFRM_LEFT02 : +{0x6403,0x00,0x01}, // INFRM_LEFT03 : +{0x6404,0x00,0x01}, // INFRM_LEFT04 : +{0x6405,0x00,0x01}, // INFRM_LEFT05 : +{0x6406,0x00,0x01}, // INFRM_LEFT06 : +{0x6407,0x00,0x01}, // INFRM_LEFT07 : +{0x6408,0x00,0x01}, // INFRM_LEFT08 : +{0x6409,0x00,0x01}, // INFRM_LEFT09 : +{0x640A,0x00,0x01}, // INFRM_LEFT10 : +{0x640B,0x00,0x01}, // INFRM_LEFT11 : +{0x640C,0x00,0x01}, // INFRM_LEFT12 : +{0x640D,0x00,0x01}, // INFRM_LEFT13 : +{0x640E,0x00,0x01}, // INFRM_LEFT14 : +{0x640F,0x00,0x01}, // INFRM_LEFT15 : +{0x6410,0x00,0x01}, // INFRM_LEFT16 : +{0x6411,0x00,0x01}, // INFRM_LEFT17 : +{0x6412,0x00,0x01}, // INFRM_LEFT18 : +{0x6413,0x00,0x01}, // INFRM_LEFT19 : +{0x6414,0x00,0x01}, // INFRM_LEFT20 : +{0x6415,0x00,0x01}, // INFRM_LEFT21 : +{0x6416,0x00,0x01}, // INFRM_LEFT22 : +{0x6417,0x00,0x01}, // INFRM_LEFT23 : +{0x6418,0x00,0x01}, // INFRM_LEFT24 : +{0x6419,0x00,0x01}, // INFRM_LEFT25 : +{0x641A,0x00,0x01}, // INFRM_LEFT26 : +{0x641B,0x00,0x01}, // INFRM_LEFT27 : +{0x641C,0x00,0x01}, // INFRM_LEFT28 : +{0x641D,0x00,0x01}, // INFRM_LEFT29 : +{0x641E,0x00,0x01}, // INFRM_LEFT30 : +{0x641F,0x00,0x01}, // INFRM_LEFT31 : +{0x6420,0x00,0x01}, // INFRM_LEFT32 : +{0x6421,0x00,0x01}, // INFRM_LEFT33 : +{0x6422,0x00,0x01}, // INFRM_LEFT34 : +{0x6423,0x00,0x01}, // INFRM_LEFT35 : +{0x6424,0x00,0x01}, // INFRM_LEFT36 : +{0x6425,0x00,0x01}, // INFRM_LEFT37 : +{0x6426,0xFF,0x01}, // INFRM_RIGHT00 : +{0x6427,0xFF,0x01}, // INFRM_RIGHT01 : +{0x6428,0xFF,0x01}, // INFRM_RIGHT02 : +{0x6429,0xFF,0x01}, // INFRM_RIGHT03 : +{0x642A,0xFF,0x01}, // INFRM_RIGHT04 : +{0x642B,0xFF,0x01}, // INFRM_RIGHT05 : +{0x642C,0xFF,0x01}, // INFRM_RIGHT06 : +{0x642D,0xFF,0x01}, // INFRM_RIGHT07 : +{0x642E,0xFF,0x01}, // INFRM_RIGHT08 : +{0x642F,0xFF,0x01}, // INFRM_RIGHT09 : +{0x6430,0xFF,0x01}, // INFRM_RIGHT10 : +{0x6431,0xFF,0x01}, // INFRM_RIGHT11 : +{0x6432,0xFF,0x01}, // INFRM_RIGHT12 : +{0x6433,0xFF,0x01}, // INFRM_RIGHT13 : +{0x6434,0xFF,0x01}, // INFRM_RIGHT14 : +{0x6435,0xFF,0x01}, // INFRM_RIGHT15 : +{0x6436,0xFF,0x01}, // INFRM_RIGHT16 : +{0x6437,0xFF,0x01}, // INFRM_RIGHT17 : +{0x6438,0xFF,0x01}, // INFRM_RIGHT18 : +{0x6439,0xFF,0x01}, // INFRM_RIGHT19 : +{0x643A,0xFF,0x01}, // INFRM_RIGHT20 : +{0x643B,0xFF,0x01}, // INFRM_RIGHT21 : +{0x643C,0xFF,0x01}, // INFRM_RIGHT22 : +{0x643D,0xFF,0x01}, // INFRM_RIGHT23 : +{0x643E,0xFF,0x01}, // INFRM_RIGHT24 : +{0x643F,0xFF,0x01}, // INFRM_RIGHT25 : +{0x6440,0xFF,0x01}, // INFRM_RIGHT26 : +{0x6441,0xFF,0x01}, // INFRM_RIGHT27 : +{0x6442,0xFF,0x01}, // INFRM_RIGHT28 : +{0x6443,0xFF,0x01}, // INFRM_RIGHT29 : +{0x6444,0xFF,0x01}, // INFRM_RIGHT30 : +{0x6445,0xFF,0x01}, // INFRM_RIGHT31 : +{0x6446,0xFF,0x01}, // INFRM_RIGHT32 : +{0x6447,0xFF,0x01}, // INFRM_RIGHT33 : +{0x6448,0xFF,0x01}, // INFRM_RIGHT34 : +{0x6449,0xFF,0x01}, // INFRM_RIGHT35 : +{0x644A,0xFF,0x01}, // INFRM_RIGHT36 : +{0x644B,0xFF,0x01}, // INFRM_RIGHT37 : +{0x644C,0xFFFF,0x02}, // INFRM_TOP : +{0x644E,0x0000,0x02}, // INFRM_BOTM : +{0x6450,0x25,0x01}, // INFRM_FLTOP : +{0x6451,0x00,0x01}, // INFRM_FLBOTM : +{0x6452,0x91,0x01}, // INAIM_LEFT00 : +{0x6453,0x91,0x01}, // INAIM_LEFT01 : +{0x6454,0x91,0x01}, // INAIM_LEFT02 : +{0x6455,0x91,0x01}, // INAIM_LEFT03 : +{0x6456,0x91,0x01}, // INAIM_LEFT04 : +{0x6457,0x91,0x01}, // INAIM_LEFT05 : +{0x6458,0x91,0x01}, // INAIM_LEFT06 : +{0x6459,0x91,0x01}, // INAIM_LEFT07 : +{0x645A,0x91,0x01}, // INAIM_LEFT08 : +{0x645B,0x91,0x01}, // INAIM_LEFT09 : +{0x645C,0x91,0x01}, // INAIM_LEFT10 : +{0x645D,0x91,0x01}, // INAIM_LEFT11 : +{0x645E,0x91,0x01}, // INAIM_LEFT12 : +{0x645F,0x66,0x01}, // INAIM_LEFT13 : +{0x6460,0x5D,0x01}, // INAIM_LEFT14 : +{0x6461,0x69,0x01}, // INAIM_LEFT15 : +{0x6462,0x54,0x01}, // INAIM_LEFT16 : +{0x6463,0x4B,0x01}, // INAIM_LEFT17 : +{0x6464,0x42,0x01}, // INAIM_LEFT18 : +{0x6465,0x3C,0x01}, // INAIM_LEFT19 : +{0x6466,0x38,0x01}, // INAIM_LEFT20 : +{0x6467,0x36,0x01}, // INAIM_LEFT21 : +{0x6468,0x35,0x01}, // INAIM_LEFT22 : +{0x6469,0x33,0x01}, // INAIM_LEFT23 : +{0x646A,0x32,0x01}, // INAIM_LEFT24 : +{0x646B,0x30,0x01}, // INAIM_LEFT25 : +{0x646C,0x2F,0x01}, // INAIM_LEFT26 : +{0x646D,0x2D,0x01}, // INAIM_LEFT27 : +{0x646E,0x2C,0x01}, // INAIM_LEFT28 : +{0x646F,0x2B,0x01}, // INAIM_LEFT29 : +{0x6470,0x2A,0x01}, // INAIM_LEFT30 : +{0x6471,0x28,0x01}, // INAIM_LEFT31 : +{0x6472,0x26,0x01}, // INAIM_LEFT32 : +{0x6473,0x24,0x01}, // INAIM_LEFT33 : +{0x6474,0x29,0x01}, // INAIM_LEFT34 : +{0x6475,0x28,0x01}, // INAIM_LEFT35 : +{0x6476,0x29,0x01}, // INAIM_LEFT36 : +{0x6477,0x26,0x01}, // INAIM_LEFT37 : +{0x6478,0xFF,0x01}, // INAIM_RIGHT00 : +{0x6479,0xFF,0x01}, // INAIM_RIGHT01 : +{0x647A,0xFF,0x01}, // INAIM_RIGHT02 : +{0x647B,0xFF,0x01}, // INAIM_RIGHT03 : +{0x647C,0xFF,0x01}, // INAIM_RIGHT04 : +{0x647D,0xFF,0x01}, // INAIM_RIGHT05 : +{0x647E,0xFF,0x01}, // INAIM_RIGHT06 : +{0x647F,0xFF,0x01}, // INAIM_RIGHT07 : +{0x6480,0xFF,0x01}, // INAIM_RIGHT08 : +{0x6481,0xFF,0x01}, // INAIM_RIGHT09 : +{0x6482,0xD9,0x01}, // INAIM_RIGHT10 : +{0x6483,0xB7,0x01}, // INAIM_RIGHT11 : +{0x6484,0x96,0x01}, // INAIM_RIGHT12 : +{0x6485,0x68,0x01}, // INAIM_RIGHT13 : +{0x6486,0x70,0x01}, // INAIM_RIGHT14 : +{0x6487,0x72,0x01}, // INAIM_RIGHT15 : +{0x6488,0x71,0x01}, // INAIM_RIGHT16 : +{0x6489,0x6B,0x01}, // INAIM_RIGHT17 : +{0x648A,0x65,0x01}, // INAIM_RIGHT18 : +{0x648B,0x60,0x01}, // INAIM_RIGHT19 : +{0x648C,0x5B,0x01}, // INAIM_RIGHT20 : +{0x648D,0x56,0x01}, // INAIM_RIGHT21 : +{0x648E,0x51,0x01}, // INAIM_RIGHT22 : +{0x648F,0x4C,0x01}, // INAIM_RIGHT23 : +{0x6490,0x47,0x01}, // INAIM_RIGHT24 : +{0x6491,0x44,0x01}, // INAIM_RIGHT25 : +{0x6492,0x41,0x01}, // INAIM_RIGHT26 : +{0x6493,0x3E,0x01}, // INAIM_RIGHT27 : +{0x6494,0x3B,0x01}, // INAIM_RIGHT28 : +{0x6495,0x39,0x01}, // INAIM_RIGHT29 : +{0x6496,0x37,0x01}, // INAIM_RIGHT30 : +{0x6497,0x34,0x01}, // INAIM_RIGHT31 : +{0x6498,0x33,0x01}, // INAIM_RIGHT32 : +{0x6499,0x32,0x01}, // INAIM_RIGHT33 : +{0x649A,0x31,0x01}, // INAIM_RIGHT34 : +{0x649B,0x30,0x01}, // INAIM_RIGHT35 : +{0x649C,0x2F,0x01}, // INAIM_RIGHT36 : +{0x649D,0x2E,0x01}, // INAIM_RIGHT37 : +{0x649E,0x1E00,0x02}, // INAIM_TOP : +{0x64A0,0x0F48,0x02}, // INAIM_BOTM : +{0x64A2,0x18,0x01}, // INAIM_FLTOP : +{0x64A3,0x11,0x01}, // INAIM_FLBOTM : +{0x64A4,0x00,0x01}, // OUTFRM_LEFT00 : +{0x64A5,0x00,0x01}, // OUTFRM_LEFT01 : +{0x64A6,0x00,0x01}, // OUTFRM_LEFT02 : +{0x64A7,0x00,0x01}, // OUTFRM_LEFT03 : +{0x64A8,0x00,0x01}, // OUTFRM_LEFT04 : +{0x64A9,0x00,0x01}, // OUTFRM_LEFT05 : +{0x64AA,0x00,0x01}, // OUTFRM_LEFT06 : +{0x64AB,0x00,0x01}, // OUTFRM_LEFT07 : +{0x64AC,0x00,0x01}, // OUTFRM_LEFT08 : +{0x64AD,0x00,0x01}, // OUTFRM_LEFT09 : +{0x64AE,0x00,0x01}, // OUTFRM_LEFT10 : +{0x64AF,0x00,0x01}, // OUTFRM_LEFT11 : +{0x64B0,0x00,0x01}, // OUTFRM_LEFT12 : +{0x64B1,0x00,0x01}, // OUTFRM_LEFT13 : +{0x64B2,0x00,0x01}, // OUTFRM_LEFT14 : +{0x64B3,0x00,0x01}, // OUTFRM_LEFT15 : +{0x64B4,0x00,0x01}, // OUTFRM_LEFT16 : +{0x64B5,0x00,0x01}, // OUTFRM_LEFT17 : +{0x64B6,0x00,0x01}, // OUTFRM_LEFT18 : +{0x64B7,0x00,0x01}, // OUTFRM_LEFT19 : +{0x64B8,0x00,0x01}, // OUTFRM_LEFT20 : +{0x64B9,0x00,0x01}, // OUTFRM_LEFT21 : +{0x64BA,0x00,0x01}, // OUTFRM_LEFT22 : +{0x64BB,0x00,0x01}, // OUTFRM_LEFT23 : +{0x64BC,0x00,0x01}, // OUTFRM_LEFT24 : +{0x64BD,0x00,0x01}, // OUTFRM_LEFT25 : +{0x64BE,0x00,0x01}, // OUTFRM_LEFT26 : +{0x64BF,0x00,0x01}, // OUTFRM_LEFT27 : +{0x64C0,0x00,0x01}, // OUTFRM_LEFT28 : +{0x64C1,0x00,0x01}, // OUTFRM_LEFT29 : +{0x64C2,0x00,0x01}, // OUTFRM_LEFT30 : +{0x64C3,0x00,0x01}, // OUTFRM_LEFT31 : +{0x64C4,0x00,0x01}, // OUTFRM_LEFT32 : +{0x64C5,0x00,0x01}, // OUTFRM_LEFT33 : +{0x64C6,0x00,0x01}, // OUTFRM_LEFT34 : +{0x64C7,0x00,0x01}, // OUTFRM_LEFT35 : +{0x64C8,0x00,0x01}, // OUTFRM_LEFT36 : +{0x64C9,0x00,0x01}, // OUTFRM_LEFT37 : +{0x64CA,0xFF,0x01}, // OUTFRM_RIGHT00 : +{0x64CB,0xFF,0x01}, // OUTFRM_RIGHT01 : +{0x64CC,0xFF,0x01}, // OUTFRM_RIGHT02 : +{0x64CD,0xFF,0x01}, // OUTFRM_RIGHT03 : +{0x64CE,0xFF,0x01}, // OUTFRM_RIGHT04 : +{0x64CF,0xFF,0x01}, // OUTFRM_RIGHT05 : +{0x64D0,0xFF,0x01}, // OUTFRM_RIGHT06 : +{0x64D1,0xFF,0x01}, // OUTFRM_RIGHT07 : +{0x64D2,0xFF,0x01}, // OUTFRM_RIGHT08 : +{0x64D3,0xFF,0x01}, // OUTFRM_RIGHT09 : +{0x64D4,0xFF,0x01}, // OUTFRM_RIGHT10 : +{0x64D5,0xFF,0x01}, // OUTFRM_RIGHT11 : +{0x64D6,0xFF,0x01}, // OUTFRM_RIGHT12 : +{0x64D7,0xFF,0x01}, // OUTFRM_RIGHT13 : +{0x64D8,0xFF,0x01}, // OUTFRM_RIGHT14 : +{0x64D9,0xFF,0x01}, // OUTFRM_RIGHT15 : +{0x64DA,0xFF,0x01}, // OUTFRM_RIGHT16 : +{0x64DB,0xFF,0x01}, // OUTFRM_RIGHT17 : +{0x64DC,0xFF,0x01}, // OUTFRM_RIGHT18 : +{0x64DD,0xFF,0x01}, // OUTFRM_RIGHT19 : +{0x64DE,0xFF,0x01}, // OUTFRM_RIGHT20 : +{0x64DF,0xFF,0x01}, // OUTFRM_RIGHT21 : +{0x64E0,0xFF,0x01}, // OUTFRM_RIGHT22 : +{0x64E1,0xFF,0x01}, // OUTFRM_RIGHT23 : +{0x64E2,0xFF,0x01}, // OUTFRM_RIGHT24 : +{0x64E3,0xFF,0x01}, // OUTFRM_RIGHT25 : +{0x64E4,0xFF,0x01}, // OUTFRM_RIGHT26 : +{0x64E5,0xFF,0x01}, // OUTFRM_RIGHT27 : +{0x64E6,0xFF,0x01}, // OUTFRM_RIGHT28 : +{0x64E7,0xFF,0x01}, // OUTFRM_RIGHT29 : +{0x64E8,0xFF,0x01}, // OUTFRM_RIGHT30 : +{0x64E9,0xFF,0x01}, // OUTFRM_RIGHT31 : +{0x64EA,0xFF,0x01}, // OUTFRM_RIGHT32 : +{0x64EB,0xFF,0x01}, // OUTFRM_RIGHT33 : +{0x64EC,0xFF,0x01}, // OUTFRM_RIGHT34 : +{0x64ED,0xFF,0x01}, // OUTFRM_RIGHT35 : +{0x64EE,0xFF,0x01}, // OUTFRM_RIGHT36 : +{0x64EF,0xFF,0x01}, // OUTFRM_RIGHT37 : +{0x64F0,0x24F0,0x02}, // OUTFRM_TOP : +{0x64F2,0x1400,0x02}, // OUTFRM_BOTM : +{0x64F4,0x37,0x01}, // OUTFRM_FLTOP : +{0x64F5,0x00,0x01}, // OUTFRM_FLBOTM : + +//AWB +{0x6232,0x07,0x01},//ATW_SFTLMT_OUT_NR +{0x6234,0x05,0x01},//ATW_SFTLMT_OUT + +/////MC3 Setting///// +{0x7600,0x07,0x01}, // MC3_PXDEF0_SEL : +{0x7601,0x07,0x01}, // MC3_PYDEF0_SEL : +{0x7602,0x07,0x01}, // MC3_PXDEF1_SEL : +{0x7603,0x07,0x01}, // MC3_PYDEF1_SEL : +{0x7604,0x07,0x01}, // MC3_PXDEF2_SEL : +{0x7605,0x07,0x01}, // MC3_PYDEF2_SEL : +{0x7606,0x07,0x01}, // MC3_PXDEF3_SEL : +{0x7607,0x07,0x01}, // MC3_PYDEF3_SEL : +{0x7608,0x40,0x01}, // MC3_PXDEF0_A : +{0x7609,0x40,0x01}, // MC3_PXDEF0_B : +{0x760A,0x40,0x01}, // MC3_PXDEF0_C : +{0x760B,0x40,0x01}, // MC3_PYDEF0_A : +{0x760C,0x40,0x01}, // MC3_PYDEF0_B : +{0x760D,0x40,0x01}, // MC3_PYDEF0_C : +{0x760E,0x40,0x01}, // MC3_PXDEF1_A : +{0x760F,0x40,0x01}, // MC3_PXDEF1_B : +{0x7610,0x40,0x01}, // MC3_PXDEF1_C : +{0x7611,0x40,0x01}, // MC3_PYDEF1_A : +{0x7612,0x40,0x01}, // MC3_PYDEF1_B : +{0x7613,0x40,0x01}, // MC3_PYDEF1_C : +{0x7614,0x40,0x01}, // MC3_PXDEF2_A : +{0x7615,0x40,0x01}, // MC3_PXDEF2_B : +{0x7616,0x40,0x01}, // MC3_PXDEF2_C : +{0x7617,0x40,0x01}, // MC3_PYDEF2_A : +{0x7618,0x40,0x01}, // MC3_PYDEF2_B : +{0x7619,0x40,0x01}, // MC3_PYDEF2_C : +{0x761A,0x40,0x01}, // MC3_PXDEF3_A : +{0x761B,0x40,0x01}, // MC3_PXDEF3_B : +{0x761C,0x40,0x01}, // MC3_PXDEF3_C : +{0x761D,0x40,0x01}, // MC3_PYDEF3_A : +{0x761E,0x40,0x01}, // MC3_PYDEF3_B : +{0x761F,0x40,0x01}, // MC3_PYDEF3_C : +{0x7620,0x00,0x01}, // MC3_LUMSL0_IN : +{0x7621,0x06,0x01}, // MC3_LUMSL1_IN : +{0x7622,0x03,0x01}, // MC3_LUMSL2_IN : +{0x7623,0x06,0x01}, // MC3_LUMSL3_IN : +{0x7624,0x00,0x01}, // MC3_LUMSL0_OUT : +{0x7625,0x03,0x01}, // MC3_LUMSL1_OUT : +{0x7626,0x00,0x01}, // MC3_LUMSL2_OUT : +{0x7627,0x00,0x01}, // MC3_LUMSL3_OUT : +{0x7628,0x0000,0x02}, // MC3_L0DEF0_IN : +{0x762A,0x008C,0x02}, // MC3_L0DEF1_IN : +{0x762C,0x0078,0x02}, // MC3_L0DEF2_IN : +{0x762E,0x00E6,0x02}, // MC3_L0DEF3_IN : +{0x7630,0x0000,0x02}, // MC3_L0DEF0_OUT : +{0x7632,0x0082,0x02}, // MC3_L0DEF1_OUT : +{0x7634,0x0000,0x02}, // MC3_L0DEF2_OUT : +{0x7636,0x0000,0x02}, // MC3_L0DEF3_OUT : +{0x7638,0x41,0x01}, // MC3_RDEF0_POS1 : +{0x7639,0x10,0x01}, // MC3_RDEF1_POS1 : +{0x763A,0x15,0x01}, // MC3_RDEF2_POS1 : +{0x763B,0x71,0x01}, // MC3_RDEF3_POS1 : +{0x763C,0x41,0x01}, // MC3_RDEF0_POS2 : +{0x763D,0x10,0x01}, // MC3_RDEF1_POS2 : +{0x763E,0x15,0x01}, // MC3_RDEF2_POS2 : +{0x763F,0x71,0x01}, // MC3_RDEF3_POS2 : +{0x7640,0x3C,0x01}, // MC3_RDEF0_POS3 : +{0x7641,0x10,0x01}, // MC3_RDEF1_POS3 : +{0x7642,0x15,0x01}, // MC3_RDEF2_POS3 : +{0x7643,0x71,0x01}, // MC3_RDEF3_POS3 : +{0x7644,0x46,0x01}, // MC3_RDEF0_POS4 : +{0x7645,0x32,0x01}, // MC3_RDEF1_POS4 : +{0x7646,0x15,0x01}, // MC3_RDEF2_POS4 : +{0x7647,0x71,0x01}, // MC3_RDEF3_POS4 : +{0x7648,0x46,0x01}, // MC3_RDEF0_POS5 : +{0x7649,0x32,0x01}, // MC3_RDEF1_POS5 : +{0x764A,0x15,0x01}, // MC3_RDEF2_POS5 : +{0x764B,0x71,0x01}, // MC3_RDEF3_POS5 : +{0x764C,0x46,0x01}, // MC3_RDEF0_POS6 : +{0x764D,0x10,0x01}, // MC3_RDEF1_POS6 : +{0x764E,0x15,0x01}, // MC3_RDEF2_POS6 : +{0x764F,0x71,0x01}, // MC3_RDEF3_POS6 : +{0x7650,0x46,0x01}, // MC3_RDEF0_POS7 : +{0x7651,0x10,0x01}, // MC3_RDEF1_POS7 : +{0x7652,0x15,0x01}, // MC3_RDEF2_POS7 : +{0x7653,0x71,0x01}, // MC3_RDEF3_POS7 : +{0x7654,0x2D,0x01}, // MC3_RDEF0_OUT : +{0x7655,0x10,0x01}, // MC3_RDEF1_OUT : +{0x7656,0x15,0x01}, // MC3_RDEF2_OUT : +{0x7657,0x54,0x01}, // MC3_RDEF3_OUT : +{0x7658,0x46,0x01}, // MC3_RDEF0_R2_POS4 : +{0x7659,0x32,0x01}, // MC3_RDEF1_R2_POS4 : +{0x765A,0x15,0x01}, // MC3_RDEF2_R2_POS4 : +{0x765B,0x71,0x01}, // MC3_RDEF3_R2_POS4 : +{0x765C,0x46,0x01}, // MC3_RDEF0_R2_POS5 : +{0x765D,0x32,0x01}, // MC3_RDEF1_R2_POS5 : +{0x765E,0x15,0x01}, // MC3_RDEF2_R2_POS5 : +{0x765F,0x71,0x01}, // MC3_RDEF3_R2_POS5 : +{0x7660,0xFFBA,0x02}, // MC3_X0DEF0_POS1 : +{0x7662,0xFFBA,0x02}, // MC3_Y0DEF0_POS1 : +{0x7664,0xFFFE,0x02}, // MC3_X0DEF1_POS1 : +{0x7666,0x000D,0x02}, // MC3_Y0DEF1_POS1 : +{0x7668,0x0002,0x02}, // MC3_X0DEF2_POS1 : +{0x766A,0xFFF6,0x02}, // MC3_Y0DEF2_POS1 : +{0x766C,0x003B,0x02}, // MC3_X0DEF3_POS1 : +{0x766E,0xFFBB,0x02}, // MC3_Y0DEF3_POS1 : +{0x7670,0xFFBA,0x02}, // MC3_X0DEF0_POS2 : +{0x7672,0xFFBA,0x02}, // MC3_Y0DEF0_POS2 : +{0x7674,0xFFFE,0x02}, // MC3_X0DEF1_POS2 : +{0x7676,0x000D,0x02}, // MC3_Y0DEF1_POS2 : +{0x7678,0x0002,0x02}, // MC3_X0DEF2_POS2 : +{0x767A,0xFFF6,0x02}, // MC3_Y0DEF2_POS2 : +{0x767C,0x003B,0x02}, // MC3_X0DEF3_POS2 : +{0x767E,0xFFBB,0x02}, // MC3_Y0DEF3_POS2 : +{0x7680,0xFFCE,0x02}, // MC3_X0DEF0_POS3 : +{0x7682,0xFFBA,0x02}, // MC3_Y0DEF0_POS3 : +{0x7684,0xFFFE,0x02}, // MC3_X0DEF1_POS3 : +{0x7686,0x000D,0x02}, // MC3_Y0DEF1_POS3 : +{0x7688,0x0002,0x02}, // MC3_X0DEF2_POS3 : +{0x768A,0xFFF6,0x02}, // MC3_Y0DEF2_POS3 : +{0x768C,0x003B,0x02}, // MC3_X0DEF3_POS3 : +{0x768E,0xFFBB,0x02}, // MC3_Y0DEF3_POS3 : +{0x7690,0xFFCE,0x02}, // MC3_X0DEF0_POS4 : +{0x7692,0xFFC9,0x02}, // MC3_Y0DEF0_POS4 : +{0x7694,0xFFD0,0x02}, // MC3_X0DEF1_POS4 : +{0x7696,0x0037,0x02}, // MC3_Y0DEF1_POS4 : +{0x7698,0x0002,0x02}, // MC3_X0DEF2_POS4 : +{0x769A,0xFFF6,0x02}, // MC3_Y0DEF2_POS4 : +{0x769C,0x003B,0x02}, // MC3_X0DEF3_POS4 : +{0x769E,0xFFBB,0x02}, // MC3_Y0DEF3_POS4 : +{0x76A0,0xFFCE,0x02}, // MC3_X0DEF0_POS5 : +{0x76A2,0xFFC9,0x02}, // MC3_Y0DEF0_POS5 : +{0x76A4,0xFFD0,0x02}, // MC3_X0DEF1_POS5 : +{0x76A6,0x0037,0x02}, // MC3_Y0DEF1_POS5 : +{0x76A8,0x0002,0x02}, // MC3_X0DEF2_POS5 : +{0x76AA,0xFFF6,0x02}, // MC3_Y0DEF2_POS5 : +{0x76AC,0x003B,0x02}, // MC3_X0DEF3_POS5 : +{0x76AE,0xFFBB,0x02}, // MC3_Y0DEF3_POS5 : +{0x76B0,0xFFCE,0x02}, // MC3_X0DEF0_POS6 : +{0x76B2,0xFFC9,0x02}, // MC3_Y0DEF0_POS6 : +{0x76B4,0xFFFE,0x02}, // MC3_X0DEF1_POS6 : +{0x76B6,0x000D,0x02}, // MC3_Y0DEF1_POS6 : +{0x76B8,0x0002,0x02}, // MC3_X0DEF2_POS6 : +{0x76BA,0xFFF6,0x02}, // MC3_Y0DEF2_POS6 : +{0x76BC,0x003B,0x02}, // MC3_X0DEF3_POS6 : +{0x76BE,0xFFBB,0x02}, // MC3_Y0DEF3_POS6 : +{0x76C0,0xFFCE,0x02}, // MC3_X0DEF0_POS7 : +{0x76C2,0xFFC9,0x02}, // MC3_Y0DEF0_POS7 : +{0x76C4,0xFFFE,0x02}, // MC3_X0DEF1_POS7 : +{0x76C6,0x000D,0x02}, // MC3_Y0DEF1_POS7 : +{0x76C8,0x0002,0x02}, // MC3_X0DEF2_POS7 : +{0x76CA,0xFFF6,0x02}, // MC3_Y0DEF2_POS7 : +{0x76CC,0x003B,0x02}, // MC3_X0DEF3_POS7 : +{0x76CE,0xFFBB,0x02}, // MC3_Y0DEF3_POS7 : +{0x76D0,0xFF7E,0x02}, // MC3_X0DEF0_OUT : +{0x76D2,0xFFE2,0x02}, // MC3_Y0DEF0_OUT : +{0x76D4,0xFFFE,0x02}, // MC3_X0DEF1_OUT : +{0x76D6,0x000D,0x02}, // MC3_Y0DEF1_OUT : +{0x76D8,0x0002,0x02}, // MC3_X0DEF2_OUT : +{0x76DA,0xFFF6,0x02}, // MC3_Y0DEF2_OUT : +{0x76DC,0xFFC4,0x02}, // MC3_X0DEF3_OUT : +{0x76DE,0xFFEC,0x02}, // MC3_Y0DEF3_OUT : +{0x76E0,0xFFCE,0x02}, // MC3_X0DEF0_R2_POS4 : +{0x76E2,0xFFC9,0x02}, // MC3_Y0DEF0_R2_POS4 : +{0x76E4,0xFFD0,0x02}, // MC3_X0DEF1_R2_POS4 : +{0x76E6,0x0037,0x02}, // MC3_Y0DEF1_R2_POS4 : +{0x76E8,0x0002,0x02}, // MC3_X0DEF2_R2_POS4 : +{0x76EA,0xFFF6,0x02}, // MC3_Y0DEF2_R2_POS4 : +{0x76EC,0x003B,0x02}, // MC3_X0DEF3_R2_POS4 : +{0x76EE,0xFFBB,0x02}, // MC3_Y0DEF3_R2_POS4 : +{0x76F0,0xFFCE,0x02}, // MC3_X0DEF0_R2_POS5 : +{0x76F2,0xFFC9,0x02}, // MC3_Y0DEF0_R2_POS5 : +{0x76F4,0xFFD0,0x02}, // MC3_X0DEF1_R2_POS5 : +{0x76F6,0x0037,0x02}, // MC3_Y0DEF1_R2_POS5 : +{0x76F8,0x0002,0x02}, // MC3_X0DEF2_R2_POS5 : +{0x76FA,0xFFF6,0x02}, // MC3_Y0DEF2_R2_POS5 : +{0x76FC,0x003B,0x02}, // MC3_X0DEF3_R2_POS5 : +{0x76FE,0xFFBB,0x02}, // MC3_Y0DEF3_R2_POS5 : +{0x7700,0x0019,0x02}, // MC3_PXDEF0_POS1 : +{0x7702,0xFF66,0x02}, // MC3_PYDEF0_POS1 : +{0x7704,0x0000,0x02}, // MC3_PXDEF1_POS1 : +{0x7706,0x0000,0x02}, // MC3_PYDEF1_POS1 : +{0x7708,0x0000,0x02}, // MC3_PXDEF2_POS1 : +{0x770A,0x0000,0x02}, // MC3_PYDEF2_POS1 : +{0x770C,0xFFD7,0x02}, // MC3_PXDEF3_POS1 : +{0x770E,0x0068,0x02}, // MC3_PYDEF3_POS1 : +{0x7710,0x0000,0x02}, // MC3_PXDEF0_POS2 : +{0x7712,0xFF66,0x02}, // MC3_PYDEF0_POS2 : +{0x7714,0x0033,0x02}, // MC3_PXDEF1_POS2 : +{0x7716,0xFF4C,0x02}, // MC3_PYDEF1_POS2 : +{0x7718,0x0000,0x02}, // MC3_PXDEF2_POS2 : +{0x771A,0x00B3,0x02}, // MC3_PYDEF2_POS2 : +{0x771C,0xFFD7,0x02}, // MC3_PXDEF3_POS2 : +{0x771E,0x0068,0x02}, // MC3_PYDEF3_POS2 : +{0x7720,0x0000,0x02}, // MC3_PXDEF0_POS3 : +{0x7722,0xFF80,0x02}, // MC3_PYDEF0_POS3 : +{0x7724,0x0000,0x02}, // MC3_PXDEF1_POS3 : +{0x7726,0x0000,0x02}, // MC3_PYDEF1_POS3 : +{0x7728,0x0000,0x02}, // MC3_PXDEF2_POS3 : +{0x772A,0x0000,0x02}, // MC3_PYDEF2_POS3 : +{0x772C,0xFFD7,0x02}, // MC3_PXDEF3_POS3 : +{0x772E,0x0068,0x02}, // MC3_PYDEF3_POS3 : +{0x7730,0x0000,0x02}, // MC3_PXDEF0_POS4 : +{0x7732,0xFFCC,0x02}, // MC3_PYDEF0_POS4 : +{0x7734,0x0000,0x02}, // MC3_PXDEF1_POS4 : +{0x7736,0x0000,0x02}, // MC3_PYDEF1_POS4 : +{0x7738,0x0000,0x02}, // MC3_PXDEF2_POS4 : +{0x773A,0x0000,0x02}, // MC3_PYDEF2_POS4 : +{0x773C,0xFFD7,0x02}, // MC3_PXDEF3_POS4 : +{0x773E,0x0068,0x02}, // MC3_PYDEF3_POS4 : +{0x7740,0x0000,0x02}, // MC3_PXDEF0_POS5 : +{0x7742,0xFFCC,0x02}, // MC3_PYDEF0_POS5 : +{0x7744,0x0000,0x02}, // MC3_PXDEF1_POS5 : +{0x7746,0x0000,0x02}, // MC3_PYDEF1_POS5 : +{0x7748,0x0000,0x02}, // MC3_PXDEF2_POS5 : +{0x774A,0x0000,0x02}, // MC3_PYDEF2_POS5 : +{0x774C,0xFFD7,0x02}, // MC3_PXDEF3_POS5 : +{0x774E,0x0068,0x02}, // MC3_PYDEF3_POS5 : +{0x7750,0xFFB3,0x02}, // MC3_PXDEF0_POS6 : +{0x7752,0x0000,0x02}, // MC3_PYDEF0_POS6 : +{0x7754,0x0033,0x02}, // MC3_PXDEF1_POS6 : +{0x7756,0xFF4C,0x02}, // MC3_PYDEF1_POS6 : +{0x7758,0x0000,0x02}, // MC3_PXDEF2_POS6 : +{0x775A,0x00B3,0x02}, // MC3_PYDEF2_POS6 : +{0x775C,0xFFD7,0x02}, // MC3_PXDEF3_POS6 : +{0x775E,0x0068,0x02}, // MC3_PYDEF3_POS6 : +{0x7760,0xFFB3,0x02}, // MC3_PXDEF0_POS7 : +{0x7762,0x0000,0x02}, // MC3_PYDEF0_POS7 : +{0x7764,0x0000,0x02}, // MC3_PXDEF1_POS7 : +{0x7766,0x0000,0x02}, // MC3_PYDEF1_POS7 : +{0x7768,0x0000,0x02}, // MC3_PXDEF2_POS7 : +{0x776A,0x0000,0x02}, // MC3_PYDEF2_POS7 : +{0x776C,0xFFD7,0x02}, // MC3_PXDEF3_POS7 : +{0x776E,0x0068,0x02}, // MC3_PYDEF3_POS7 : +{0x7770,0x0019,0x02}, // MC3_PXDEF0_OUT : +{0x7772,0xFFE6,0x02}, // MC3_PYDEF0_OUT : +{0x7774,0x0000,0x02}, // MC3_PXDEF1_OUT : +{0x7776,0x0000,0x02}, // MC3_PYDEF1_OUT : +{0x7778,0x0000,0x02}, // MC3_PXDEF2_OUT : +{0x777A,0x0000,0x02}, // MC3_PYDEF2_OUT : +{0x777C,0xFFE1,0x02}, // MC3_PXDEF3_OUT : +{0x777E,0xFFEB,0x02}, // MC3_PYDEF3_OUT : +{0x7780,0x0000,0x02}, // MC3_PXDEF0_R2_POS4 : +{0x7782,0xFFCC,0x02}, // MC3_PYDEF0_R2_POS4 : +{0x7784,0x0000,0x02}, // MC3_PXDEF1_R2_POS4 : +{0x7786,0x0000,0x02}, // MC3_PYDEF1_R2_POS4 : +{0x7788,0x0000,0x02}, // MC3_PXDEF2_R2_POS4 : +{0x778A,0x0000,0x02}, // MC3_PYDEF2_R2_POS4 : +{0x778C,0xFFD7,0x02}, // MC3_PXDEF3_R2_POS4 : +{0x778E,0x0068,0x02}, // MC3_PYDEF3_R2_POS4 : +{0x7790,0x0000,0x02}, // MC3_PXDEF0_R2_POS5 : +{0x7792,0xFFCC,0x02}, // MC3_PYDEF0_R2_POS5 : +{0x7794,0x0000,0x02}, // MC3_PXDEF1_R2_POS5 : +{0x7796,0x0000,0x02}, // MC3_PYDEF1_R2_POS5 : +{0x7798,0x0000,0x02}, // MC3_PXDEF2_R2_POS5 : +{0x779A,0x0000,0x02}, // MC3_PYDEF2_R2_POS5 : +{0x779C,0xFFD7,0x02}, // MC3_PXDEF3_R2_POS5 : +{0x779E,0x0068,0x02}, // MC3_PYDEF3_R2_POS5 : + +}; + +static const isx012_regset_t ISX012_Camcorder_Mode_OFF[] = { +//SN setting +{0x0308,0x11,0x01}, // AELINE_MONI_SN1_2 : +{0x0320,0x22,0x01}, // AELINE_MONI_SN1_2 : +{0x00B2,0x02,0x01}, // AFMODE_MONI : +//BRIGHTNESS setting +{0x01C6,0x00,0x01}, // UIBRIGHTNESS +//AE speed +{0x02AC,0x01,0x01}, // AE_SUB_SN1 : +{0x5E2D,0x08,0x01}, // AEMOVECNT : +{0x5E2E,0x1A,0x01}, // AEINDEADBAND : +{0x5E2F,0x04,0x01}, // AEOUTDEADBAND : +{0x5E30,0x20,0x01}, // AESPEED : +{0x5E31,0x0F,0x01}, // AESPEED_INIT : +{0x5E32,0x0F,0x01}, // AESPEED_FAST : +{0x621E,0x20,0x01}, // AIM_NR_TH_UP : +{0x621F,0x20,0x01}, // AIM_NR_TH_DOWN : +{0x6220,0x20,0x01}, // AIM_NR_TH_RIGHT : +{0x6221,0x20,0x01}, // AIM_NR_TH_LEFT : +//AWB speed +{0x6222,0x00,0x01}, // INIT_AIMW : +{0x6223,0x04,0x01}, // INIT_GAINS : +{0x6224,0x04,0x01}, // ATW_DELAY : +{0x6225,0x00,0x01}, // ATW_AIMW : +{0x6226,0x08,0x01}, // ATW_GAINS_IN_NR : +{0x6227,0x04,0x01}, // ATW_GAINS_IN : +{0x6228,0x08,0x01}, // ATW_GAINS_OUT_NR : +{0x6229,0x04,0x01}, // ATW_GAINS_OUT : +{0x622A,0x02,0x01}, // ALLWB_GAINS : +//Gammma Table 0 +{0x7000,0x0000,0x02}, // G0_KNOT_G0 : +{0x7002,0x0015,0x02}, // G0_KNOT_G1 : +{0x7004,0x002C,0x02}, // G0_KNOT_G2 : +{0x7006,0x0041,0x02}, // G0_KNOT_G3 : +{0x7008,0x004D,0x02}, // G0_KNOT_G4 : +{0x700A,0x005B,0x02}, // G0_KNOT_G5 : +{0x700C,0x0060,0x02}, // G0_KNOT_G6 : +{0x700E,0x0068,0x02}, // G0_KNOT_G7 : +{0x7010,0x006F,0x02}, // G0_KNOT_G8 : +{0x7012,0x0078,0x02}, // G0_KNOT_G9 : +{0x7014,0x0057,0x02}, // G0_KNOT_G10 : +{0x7016,0x0090,0x02}, // G0_KNOT_G11 : +{0x7018,0x00BB,0x02}, // G0_KNOT_G12 : +{0x701A,0x00D6,0x02}, // G0_KNOT_G13 : +{0x701C,0x00E5,0x02}, // G0_KNOT_G14 : +{0x701E,0x00F0,0x02}, // G0_KNOT_G15 : +{0x7020,0x00F9,0x02}, // G0_KNOT_G16 : +{0x7022,0x0103,0x02}, // G0_KNOT_G17 : +{0x7024,0x010C,0x02}, // G0_KNOT_G18 : +{0x7026,0x00,0x01}, // G0_KNOT_R0_OFFSET : +{0x7027,0x00,0x01}, // G0_KNOT_R2_OFFSET : +{0x7028,0x00,0x01}, // G0_KNOT_R4_OFFSET : +{0x7029,0x00,0x01}, // G0_KNOT_R6_OFFSET : +{0x702A,0x00,0x01}, // G0_KNOT_R8_OFFSET : +{0x702B,0x00,0x01}, // G0_KNOT_R10_OFFSET : +{0x702C,0x00,0x01}, // G0_KNOT_R12_OFFSET : +{0x702D,0x00,0x01}, // G0_KNOT_R14_OFFSET : +{0x702E,0x00,0x01}, // G0_KNOT_R16_OFFSET : +{0x702F,0x00,0x01}, // G0_KNOT_R18_OFFSET : +{0x7030,0x00,0x01}, // G0_KNOT_B0_OFFSET : +{0x7031,0x00,0x01}, // G0_KNOT_B2_OFFSET : +{0x7032,0x00,0x01}, // G0_KNOT_B4_OFFSET : +{0x7033,0x00,0x01}, // G0_KNOT_B6_OFFSET : +{0x7034,0x00,0x01}, // G0_KNOT_B8_OFFSET : +{0x7035,0x00,0x01}, // G0_KNOT_B10_OFFSET : +{0x7036,0x00,0x01}, // G0_KNOT_B12_OFFSET : +{0x7037,0x00,0x01}, // G0_KNOT_B14_OFFSET : +{0x7038,0x00,0x01}, // G0_KNOT_B16_OFFSET : +{0x7039,0x00,0x01}, // G0_KNOT_B18_OFFSET : +{0x703A,0x0611,0x02}, // G0_LOWGM_ON_R : +{0x703C,0x1E0A,0x02}, // G0_0CLIP_R : +{0x703E,0x0611,0x02}, // G0_LOWGM_ON_G : +{0x7040,0x1E0A,0x02}, // G0_0CLIP_G : +{0x7042,0x0611,0x02}, // G0_LOWGM_ON_B : +{0x7044,0x1E0A,0x02}, // G0_0CLIP_B : +{0x7046,0x9C,0x01}, // G0_KNOT_GAINCTRL_TH_L : +{0x7047,0xA1,0x01}, // G0_KNOT_GAINCTRL_TH_H : +{0x7048,0x0000,0x02}, // G0_KNOT_L_G0 : +{0x704A,0x0007,0x02}, // G0_KNOT_L_G1 : +{0x704C,0x0016,0x02}, // G0_KNOT_L_G2 : +{0x704E,0x002A,0x02}, // G0_KNOT_L_G3 : +{0x7050,0x0039,0x02}, // G0_KNOT_L_G4 : +{0x7052,0x004A,0x02}, // G0_KNOT_L_G5 : +{0x7054,0x0051,0x02}, // G0_KNOT_L_G6 : +{0x7056,0x005D,0x02}, // G0_KNOT_L_G7 : +{0x7058,0x0065,0x02}, // G0_KNOT_L_G8 : +{0x705A,0x006C,0x02}, // G0_KNOT_L_G9 : +{0x705C,0x004E,0x02}, // G0_KNOT_L_G10 : +{0x705E,0x0083,0x02}, // G0_KNOT_L_G11 : +{0x7060,0x00AA,0x02}, // G0_KNOT_L_G12 : +{0x7062,0x00C8,0x02}, // G0_KNOT_L_G13 : +{0x7064,0x00E1,0x02}, // G0_KNOT_L_G14 : +{0x7066,0x00F5,0x02}, // G0_KNOT_L_G15 : +{0x7068,0x0100,0x02}, // G0_KNOT_L_G16 : +{0x706A,0x0106,0x02}, // G0_KNOT_L_G17 : +{0x706C,0x010C,0x02}, // G0_KNOT_L_G18 : +{0x6400,0xAA,0x01}, // INFRM_LEFT00 : +{0x6401,0xAA,0x01}, // INFRM_LEFT01 : +{0x6402,0xAA,0x01}, // INFRM_LEFT02 : +{0x6403,0xAA,0x01}, // INFRM_LEFT03 : +{0x6404,0xAA,0x01}, // INFRM_LEFT04 : +{0x6405,0xAA,0x01}, // INFRM_LEFT05 : +{0x6406,0xAA,0x01}, // INFRM_LEFT06 : +{0x6407,0xAA,0x01}, // INFRM_LEFT07 : +{0x6408,0xAA,0x01}, // INFRM_LEFT08 : +{0x6409,0xAE,0x01}, // INFRM_LEFT09 : +{0x640A,0xA0,0x01}, // INFRM_LEFT10 : +{0x640B,0x8C,0x01}, // INFRM_LEFT11 : +{0x640C,0x72,0x01}, // INFRM_LEFT12 : +{0x640D,0x64,0x01}, // INFRM_LEFT13 : +{0x640E,0x5A,0x01}, // INFRM_LEFT14 : +{0x640F,0x52,0x01}, // INFRM_LEFT15 : +{0x6410,0x48,0x01}, // INFRM_LEFT16 : +{0x6411,0x43,0x01}, // INFRM_LEFT17 : +{0x6412,0x3D,0x01}, // INFRM_LEFT18 : +{0x6413,0x37,0x01}, // INFRM_LEFT19 : +{0x6414,0x33,0x01}, // INFRM_LEFT20 : +{0x6415,0x30,0x01}, // INFRM_LEFT21 : +{0x6416,0x2E,0x01}, // INFRM_LEFT22 : +{0x6417,0x2B,0x01}, // INFRM_LEFT23 : +{0x6418,0x28,0x01}, // INFRM_LEFT24 : +{0x6419,0x26,0x01}, // INFRM_LEFT25 : +{0x641A,0x24,0x01}, // INFRM_LEFT26 : +{0x641B,0x23,0x01}, // INFRM_LEFT27 : +{0x641C,0x22,0x01}, // INFRM_LEFT28 : +{0x641D,0x22,0x01}, // INFRM_LEFT29 : +{0x641E,0x21,0x01}, // INFRM_LEFT30 : +{0x641F,0x20,0x01}, // INFRM_LEFT31 : +{0x6420,0x1D,0x01}, // INFRM_LEFT32 : +{0x6421,0x1A,0x01}, // INFRM_LEFT33 : +{0x6422,0x18,0x01}, // INFRM_LEFT34 : +{0x6423,0x17,0x01}, // INFRM_LEFT35 : +{0x6424,0x16,0x01}, // INFRM_LEFT36 : +{0x6425,0x17,0x01}, // INFRM_LEFT37 : +{0x6426,0xAF,0x01}, // INFRM_RIGHT00 : +{0x6427,0xAF,0x01}, // INFRM_RIGHT01 : +{0x6428,0xAF,0x01}, // INFRM_RIGHT02 : +{0x6429,0xAF,0x01}, // INFRM_RIGHT03 : +{0x642A,0xAF,0x01}, // INFRM_RIGHT04 : +{0x642B,0xAF,0x01}, // INFRM_RIGHT05 : +{0x642C,0xAF,0x01}, // INFRM_RIGHT06 : +{0x642D,0xAF,0x01}, // INFRM_RIGHT07 : +{0x642E,0xAF,0x01}, // INFRM_RIGHT08 : +{0x642F,0xAA,0x01}, // INFRM_RIGHT09 : +{0x6430,0xB2,0x01}, // INFRM_RIGHT10 : +{0x6431,0xB4,0x01}, // INFRM_RIGHT11 : +{0x6432,0xB6,0x01}, // INFRM_RIGHT12 : +{0x6433,0xB4,0x01}, // INFRM_RIGHT13 : +{0x6434,0x9B,0x01}, // INFRM_RIGHT14 : +{0x6435,0x8E,0x01}, // INFRM_RIGHT15 : +{0x6436,0x84,0x01}, // INFRM_RIGHT16 : +{0x6437,0x7A,0x01}, // INFRM_RIGHT17 : +{0x6438,0x72,0x01}, // INFRM_RIGHT18 : +{0x6439,0x6A,0x01}, // INFRM_RIGHT19 : +{0x643A,0x63,0x01}, // INFRM_RIGHT20 : +{0x643B,0x5E,0x01}, // INFRM_RIGHT21 : +{0x643C,0x58,0x01}, // INFRM_RIGHT22 : +{0x643D,0x53,0x01}, // INFRM_RIGHT23 : +{0x643E,0x4E,0x01}, // INFRM_RIGHT24 : +{0x643F,0x4A,0x01}, // INFRM_RIGHT25 : +{0x6440,0x46,0x01}, // INFRM_RIGHT26 : +{0x6441,0x42,0x01}, // INFRM_RIGHT27 : +{0x6442,0x3F,0x01}, // INFRM_RIGHT28 : +{0x6443,0x3C,0x01}, // INFRM_RIGHT29 : +{0x6444,0x3A,0x01}, // INFRM_RIGHT30 : +{0x6445,0x38,0x01}, // INFRM_RIGHT31 : +{0x6446,0x37,0x01}, // INFRM_RIGHT32 : +{0x6447,0x35,0x01}, // INFRM_RIGHT33 : +{0x6448,0x33,0x01}, // INFRM_RIGHT34 : +{0x6449,0x32,0x01}, // INFRM_RIGHT35 : +{0x644A,0x32,0x01}, // INFRM_RIGHT36 : +{0x644B,0x32,0x01}, // INFRM_RIGHT37 : +{0x644C,0x24FA,0x02}, // INFRM_TOP : +{0x644E,0x0940,0x02}, // INFRM_BOTM : +{0x6450,0x19,0x01}, // INFRM_FLTOP : +{0x6451,0x10,0x01}, // INFRM_FLBOTM : +{0x6452,0x91,0x01}, // INAIM_LEFT00 : +{0x6453,0x91,0x01}, // INAIM_LEFT01 : +{0x6454,0x91,0x01}, // INAIM_LEFT02 : +{0x6455,0x91,0x01}, // INAIM_LEFT03 : +{0x6456,0x91,0x01}, // INAIM_LEFT04 : +{0x6457,0x91,0x01}, // INAIM_LEFT05 : +{0x6458,0x91,0x01}, // INAIM_LEFT06 : +{0x6459,0x91,0x01}, // INAIM_LEFT07 : +{0x645A,0x91,0x01}, // INAIM_LEFT08 : +{0x645B,0x91,0x01}, // INAIM_LEFT09 : +{0x645C,0x91,0x01}, // INAIM_LEFT10 : +{0x645D,0x91,0x01}, // INAIM_LEFT11 : +{0x645E,0x91,0x01}, // INAIM_LEFT12 : +{0x645F,0x66,0x01}, // INAIM_LEFT13 : +{0x6460,0x71,0x01}, // INAIM_LEFT14 : +{0x6461,0x5A,0x01}, // INAIM_LEFT15 : +{0x6462,0x4E,0x01}, // INAIM_LEFT16 : +{0x6463,0x47,0x01}, // INAIM_LEFT17 : +{0x6464,0x42,0x01}, // INAIM_LEFT18 : +{0x6465,0x3C,0x01}, // INAIM_LEFT19 : +{0x6466,0x38,0x01}, // INAIM_LEFT20 : +{0x6467,0x36,0x01}, // INAIM_LEFT21 : +{0x6468,0x33,0x01}, // INAIM_LEFT22 : +{0x6469,0x30,0x01}, // INAIM_LEFT23 : +{0x646A,0x2F,0x01}, // INAIM_LEFT24 : +{0x646B,0x2B,0x01}, // INAIM_LEFT25 : +{0x646C,0x29,0x01}, // INAIM_LEFT26 : +{0x646D,0x27,0x01}, // INAIM_LEFT27 : +{0x646E,0x26,0x01}, // INAIM_LEFT28 : +{0x646F,0x28,0x01}, // INAIM_LEFT29 : +{0x6470,0x2A,0x01}, // INAIM_LEFT30 : +{0x6471,0x28,0x01}, // INAIM_LEFT31 : +{0x6472,0x26,0x01}, // INAIM_LEFT32 : +{0x6473,0x24,0x01}, // INAIM_LEFT33 : +{0x6474,0x29,0x01}, // INAIM_LEFT34 : +{0x6475,0x28,0x01}, // INAIM_LEFT35 : +{0x6476,0x29,0x01}, // INAIM_LEFT36 : +{0x6477,0x26,0x01}, // INAIM_LEFT37 : +{0x6478,0xFF,0x01}, // INAIM_RIGHT00 : +{0x6479,0xFF,0x01}, // INAIM_RIGHT01 : +{0x647A,0xFF,0x01}, // INAIM_RIGHT02 : +{0x647B,0xFF,0x01}, // INAIM_RIGHT03 : +{0x647C,0xFF,0x01}, // INAIM_RIGHT04 : +{0x647D,0xFF,0x01}, // INAIM_RIGHT05 : +{0x647E,0xFF,0x01}, // INAIM_RIGHT06 : +{0x647F,0xFF,0x01}, // INAIM_RIGHT07 : +{0x6480,0xFF,0x01}, // INAIM_RIGHT08 : +{0x6481,0xFF,0x01}, // INAIM_RIGHT09 : +{0x6482,0xD9,0x01}, // INAIM_RIGHT10 : +{0x6483,0xB7,0x01}, // INAIM_RIGHT11 : +{0x6484,0x96,0x01}, // INAIM_RIGHT12 : +{0x6485,0x68,0x01}, // INAIM_RIGHT13 : +{0x6486,0x72,0x01}, // INAIM_RIGHT14 : +{0x6487,0x71,0x01}, // INAIM_RIGHT15 : +{0x6488,0x6E,0x01}, // INAIM_RIGHT16 : +{0x6489,0x6A,0x01}, // INAIM_RIGHT17 : +{0x648A,0x65,0x01}, // INAIM_RIGHT18 : +{0x648B,0x60,0x01}, // INAIM_RIGHT19 : +{0x648C,0x5B,0x01}, // INAIM_RIGHT20 : +{0x648D,0x56,0x01}, // INAIM_RIGHT21 : +{0x648E,0x51,0x01}, // INAIM_RIGHT22 : +{0x648F,0x4C,0x01}, // INAIM_RIGHT23 : +{0x6490,0x47,0x01}, // INAIM_RIGHT24 : +{0x6491,0x44,0x01}, // INAIM_RIGHT25 : +{0x6492,0x41,0x01}, // INAIM_RIGHT26 : +{0x6493,0x3E,0x01}, // INAIM_RIGHT27 : +{0x6494,0x3B,0x01}, // INAIM_RIGHT28 : +{0x6495,0x39,0x01}, // INAIM_RIGHT29 : +{0x6496,0x37,0x01}, // INAIM_RIGHT30 : +{0x6497,0x34,0x01}, // INAIM_RIGHT31 : +{0x6498,0x33,0x01}, // INAIM_RIGHT32 : +{0x6499,0x32,0x01}, // INAIM_RIGHT33 : +{0x649A,0x31,0x01}, // INAIM_RIGHT34 : +{0x649B,0x30,0x01}, // INAIM_RIGHT35 : +{0x649C,0x2F,0x01}, // INAIM_RIGHT36 : +{0x649D,0x2E,0x01}, // INAIM_RIGHT37 : +{0x649E,0x1E00,0x02}, // INAIM_TOP : +{0x64A0,0x0DFF,0x02}, // INAIM_BOTM : +{0x64A2,0x18,0x01}, // INAIM_FLTOP : +{0x64A3,0x09,0x01}, // INAIM_FLBOTM : +{0x64A4,0xFF,0x01}, // OUTFRM_LEFT00 : +{0x64A5,0xFF,0x01}, // OUTFRM_LEFT01 : +{0x64A6,0xFF,0x01}, // OUTFRM_LEFT02 : +{0x64A7,0xFF,0x01}, // OUTFRM_LEFT03 : +{0x64A8,0xFF,0x01}, // OUTFRM_LEFT04 : +{0x64A9,0xFF,0x01}, // OUTFRM_LEFT05 : +{0x64AA,0xFF,0x01}, // OUTFRM_LEFT06 : +{0x64AB,0xFF,0x01}, // OUTFRM_LEFT07 : +{0x64AC,0xFF,0x01}, // OUTFRM_LEFT08 : +{0x64AD,0xFD,0x01}, // OUTFRM_LEFT09 : +{0x64AE,0xCB,0x01}, // OUTFRM_LEFT10 : +{0x64AF,0xA9,0x01}, // OUTFRM_LEFT11 : +{0x64B0,0x90,0x01}, // OUTFRM_LEFT12 : +{0x64B1,0x7D,0x01}, // OUTFRM_LEFT13 : +{0x64B2,0x70,0x01}, // OUTFRM_LEFT14 : +{0x64B3,0x65,0x01}, // OUTFRM_LEFT15 : +{0x64B4,0x5C,0x01}, // OUTFRM_LEFT16 : +{0x64B5,0x55,0x01}, // OUTFRM_LEFT17 : +{0x64B6,0x4F,0x01}, // OUTFRM_LEFT18 : +{0x64B7,0x32,0x01}, // OUTFRM_LEFT19 : +{0x64B8,0x4D,0x01}, // OUTFRM_LEFT20 : +{0x64B9,0x40,0x01}, // OUTFRM_LEFT21 : +{0x64BA,0x2D,0x01}, // OUTFRM_LEFT22 : +{0x64BB,0x2B,0x01}, // OUTFRM_LEFT23 : +{0x64BC,0x29,0x01}, // OUTFRM_LEFT24 : +{0x64BD,0x27,0x01}, // OUTFRM_LEFT25 : +{0x64BE,0x25,0x01}, // OUTFRM_LEFT26 : +{0x64BF,0x23,0x01}, // OUTFRM_LEFT27 : +{0x64C0,0x21,0x01}, // OUTFRM_LEFT28 : +{0x64C1,0x1F,0x01}, // OUTFRM_LEFT29 : +{0x64C2,0x1D,0x01}, // OUTFRM_LEFT30 : +{0x64C3,0x1B,0x01}, // OUTFRM_LEFT31 : +{0x64C4,0x1A,0x01}, // OUTFRM_LEFT32 : +{0x64C5,0x1A,0x01}, // OUTFRM_LEFT33 : +{0x64C6,0x1A,0x01}, // OUTFRM_LEFT34 : +{0x64C7,0x28,0x01}, // OUTFRM_LEFT35 : +{0x64C8,0x27,0x01}, // OUTFRM_LEFT36 : +{0x64C9,0x26,0x01}, // OUTFRM_LEFT37 : +{0x64CA,0xFF,0x01}, // OUTFRM_RIGHT00 : +{0x64CB,0xFF,0x01}, // OUTFRM_RIGHT01 : +{0x64CC,0xFF,0x01}, // OUTFRM_RIGHT02 : +{0x64CD,0xFF,0x01}, // OUTFRM_RIGHT03 : +{0x64CE,0xFF,0x01}, // OUTFRM_RIGHT04 : +{0x64CF,0xFF,0x01}, // OUTFRM_RIGHT05 : +{0x64D0,0xFF,0x01}, // OUTFRM_RIGHT06 : +{0x64D1,0xFF,0x01}, // OUTFRM_RIGHT07 : +{0x64D2,0xFF,0x01}, // OUTFRM_RIGHT08 : +{0x64D3,0xFF,0x01}, // OUTFRM_RIGHT09 : +{0x64D4,0xD3,0x01}, // OUTFRM_RIGHT10 : +{0x64D5,0xB1,0x01}, // OUTFRM_RIGHT11 : +{0x64D6,0x98,0x01}, // OUTFRM_RIGHT12 : +{0x64D7,0x85,0x01}, // OUTFRM_RIGHT13 : +{0x64D8,0x78,0x01}, // OUTFRM_RIGHT14 : +{0x64D9,0x6D,0x01}, // OUTFRM_RIGHT15 : +{0x64DA,0x64,0x01}, // OUTFRM_RIGHT16 : +{0x64DB,0x5D,0x01}, // OUTFRM_RIGHT17 : +{0x64DC,0x57,0x01}, // OUTFRM_RIGHT18 : +{0x64DD,0x63,0x01}, // OUTFRM_RIGHT19 : +{0x64DE,0x5E,0x01}, // OUTFRM_RIGHT20 : +{0x64DF,0x5A,0x01}, // OUTFRM_RIGHT21 : +{0x64E0,0x56,0x01}, // OUTFRM_RIGHT22 : +{0x64E1,0x52,0x01}, // OUTFRM_RIGHT23 : +{0x64E2,0x50,0x01}, // OUTFRM_RIGHT24 : +{0x64E3,0x4E,0x01}, // OUTFRM_RIGHT25 : +{0x64E4,0x4C,0x01}, // OUTFRM_RIGHT26 : +{0x64E5,0x4A,0x01}, // OUTFRM_RIGHT27 : +{0x64E6,0x48,0x01}, // OUTFRM_RIGHT28 : +{0x64E7,0x46,0x01}, // OUTFRM_RIGHT29 : +{0x64E8,0x44,0x01}, // OUTFRM_RIGHT30 : +{0x64E9,0x43,0x01}, // OUTFRM_RIGHT31 : +{0x64EA,0x42,0x01}, // OUTFRM_RIGHT32 : +{0x64EB,0x42,0x01}, // OUTFRM_RIGHT33 : +{0x64EC,0x42,0x01}, // OUTFRM_RIGHT34 : +{0x64ED,0x30,0x01}, // OUTFRM_RIGHT35 : +{0x64EE,0x2F,0x01}, // OUTFRM_RIGHT36 : +{0x64EF,0x2E,0x01}, // OUTFRM_RIGHT37 : +{0x64F0,0x2163,0x02}, // OUTFRM_TOP : +{0x64F2,0x1400,0x02}, // OUTFRM_BOTM : +{0x64F4,0x19,0x01}, // OUTFRM_FLTOP : +{0x64F5,0x14,0x01}, // OUTFRM_FLBOTM : +//AWB +{0x6232,0xFF,0x01}, // ATW_SFTLMT_OUT_NR +{0x6234,0xFF,0x01}, // ATW_SFTLMT_OUT +/////MC3 Setting///// +{0x7600,0x07,0x01}, // MC3_PXDEF0_SEL : +{0x7601,0x07,0x01}, // MC3_PYDEF0_SEL : +{0x7602,0x07,0x01}, // MC3_PXDEF1_SEL : +{0x7603,0x07,0x01}, // MC3_PYDEF1_SEL : +{0x7604,0x07,0x01}, // MC3_PXDEF2_SEL : +{0x7605,0x07,0x01}, // MC3_PYDEF2_SEL : +{0x7606,0x07,0x01}, // MC3_PXDEF3_SEL : +{0x7607,0x07,0x01}, // MC3_PYDEF3_SEL : +{0x7608,0x40,0x01}, // MC3_PXDEF0_A : +{0x7609,0x40,0x01}, // MC3_PXDEF0_B : +{0x760A,0x40,0x01}, // MC3_PXDEF0_C : +{0x760B,0x40,0x01}, // MC3_PYDEF0_A : +{0x760C,0x40,0x01}, // MC3_PYDEF0_B : +{0x760D,0x40,0x01}, // MC3_PYDEF0_C : +{0x760E,0x40,0x01}, // MC3_PXDEF1_A : +{0x760F,0x40,0x01}, // MC3_PXDEF1_B : +{0x7610,0x40,0x01}, // MC3_PXDEF1_C : +{0x7611,0x40,0x01}, // MC3_PYDEF1_A : +{0x7612,0x40,0x01}, // MC3_PYDEF1_B : +{0x7613,0x40,0x01}, // MC3_PYDEF1_C : +{0x7614,0x40,0x01}, // MC3_PXDEF2_A : +{0x7615,0x40,0x01}, // MC3_PXDEF2_B : +{0x7616,0x40,0x01}, // MC3_PXDEF2_C : +{0x7617,0x40,0x01}, // MC3_PYDEF2_A : +{0x7618,0x40,0x01}, // MC3_PYDEF2_B : +{0x7619,0x40,0x01}, // MC3_PYDEF2_C : +{0x761A,0x40,0x01}, // MC3_PXDEF3_A : +{0x761B,0x40,0x01}, // MC3_PXDEF3_B : +{0x761C,0x40,0x01}, // MC3_PXDEF3_C : +{0x761D,0x40,0x01}, // MC3_PYDEF3_A : +{0x761E,0x40,0x01}, // MC3_PYDEF3_B : +{0x761F,0x40,0x01}, // MC3_PYDEF3_C : +{0x7620,0x00,0x01}, // MC3_LUMSL0_IN : +{0x7621,0x06,0x01}, // MC3_LUMSL1_IN : +{0x7622,0x03,0x01}, // MC3_LUMSL2_IN : +{0x7623,0x06,0x01}, // MC3_LUMSL3_IN : +{0x7624,0x00,0x01}, // MC3_LUMSL0_OUT : +{0x7625,0x03,0x01}, // MC3_LUMSL1_OUT : +{0x7626,0x00,0x01}, // MC3_LUMSL2_OUT : +{0x7627,0x00,0x01}, // MC3_LUMSL3_OUT : +{0x7628,0x0000,0x02}, // MC3_L0DEF0_IN : +{0x762A,0x008C,0x02}, // MC3_L0DEF1_IN : +{0x762C,0x0078,0x02}, // MC3_L0DEF2_IN : +{0x762E,0x00E6,0x02}, // MC3_L0DEF3_IN : +{0x7630,0x0000,0x02}, // MC3_L0DEF0_OUT : +{0x7632,0x0082,0x02}, // MC3_L0DEF1_OUT : +{0x7634,0x0000,0x02}, // MC3_L0DEF2_OUT : +{0x7636,0x0000,0x02}, // MC3_L0DEF3_OUT : +{0x7638,0x41,0x01}, // MC3_RDEF0_POS1 : +{0x7639,0x10,0x01}, // MC3_RDEF1_POS1 : +{0x763A,0x15,0x01}, // MC3_RDEF2_POS1 : +{0x763B,0x71,0x01}, // MC3_RDEF3_POS1 : +{0x763C,0x41,0x01}, // MC3_RDEF0_POS2 : +{0x763D,0x10,0x01}, // MC3_RDEF1_POS2 : +{0x763E,0x15,0x01}, // MC3_RDEF2_POS2 : +{0x763F,0x71,0x01}, // MC3_RDEF3_POS2 : +{0x7640,0x3C,0x01}, // MC3_RDEF0_POS3 : +{0x7641,0x10,0x01}, // MC3_RDEF1_POS3 : +{0x7642,0x15,0x01}, // MC3_RDEF2_POS3 : +{0x7643,0x71,0x01}, // MC3_RDEF3_POS3 : +{0x7644,0x46,0x01}, // MC3_RDEF0_POS4 : +{0x7645,0x32,0x01}, // MC3_RDEF1_POS4 : +{0x7646,0x15,0x01}, // MC3_RDEF2_POS4 : +{0x7647,0x71,0x01}, // MC3_RDEF3_POS4 : +{0x7648,0x46,0x01}, // MC3_RDEF0_POS5 : +{0x7649,0x32,0x01}, // MC3_RDEF1_POS5 : +{0x764A,0x15,0x01}, // MC3_RDEF2_POS5 : +{0x764B,0x71,0x01}, // MC3_RDEF3_POS5 : +{0x764C,0x46,0x01}, // MC3_RDEF0_POS6 : +{0x764D,0x10,0x01}, // MC3_RDEF1_POS6 : +{0x764E,0x15,0x01}, // MC3_RDEF2_POS6 : +{0x764F,0x71,0x01}, // MC3_RDEF3_POS6 : +{0x7650,0x46,0x01}, // MC3_RDEF0_POS7 : +{0x7651,0x10,0x01}, // MC3_RDEF1_POS7 : +{0x7652,0x15,0x01}, // MC3_RDEF2_POS7 : +{0x7653,0x71,0x01}, // MC3_RDEF3_POS7 : +{0x7654,0x2D,0x01}, // MC3_RDEF0_OUT : +{0x7655,0x10,0x01}, // MC3_RDEF1_OUT : +{0x7656,0x15,0x01}, // MC3_RDEF2_OUT : +{0x7657,0x54,0x01}, // MC3_RDEF3_OUT : +{0x7658,0x46,0x01}, // MC3_RDEF0_R2_POS4 : +{0x7659,0x32,0x01}, // MC3_RDEF1_R2_POS4 : +{0x765A,0x15,0x01}, // MC3_RDEF2_R2_POS4 : +{0x765B,0x71,0x01}, // MC3_RDEF3_R2_POS4 : +{0x765C,0x46,0x01}, // MC3_RDEF0_R2_POS5 : +{0x765D,0x32,0x01}, // MC3_RDEF1_R2_POS5 : +{0x765E,0x15,0x01}, // MC3_RDEF2_R2_POS5 : +{0x765F,0x71,0x01}, // MC3_RDEF3_R2_POS5 : +{0x7660,0xFFBA,0x02}, // MC3_X0DEF0_POS1 : +{0x7662,0xFFBA,0x02}, // MC3_Y0DEF0_POS1 : +{0x7664,0xFFFE,0x02}, // MC3_X0DEF1_POS1 : +{0x7666,0x000D,0x02}, // MC3_Y0DEF1_POS1 : +{0x7668,0x0002,0x02}, // MC3_X0DEF2_POS1 : +{0x766A,0xFFF6,0x02}, // MC3_Y0DEF2_POS1 : +{0x766C,0x003B,0x02}, // MC3_X0DEF3_POS1 : +{0x766E,0xFFBB,0x02}, // MC3_Y0DEF3_POS1 : +{0x7670,0xFFBA,0x02}, // MC3_X0DEF0_POS2 : +{0x7672,0xFFBA,0x02}, // MC3_Y0DEF0_POS2 : +{0x7674,0xFFFE,0x02}, // MC3_X0DEF1_POS2 : +{0x7676,0x000D,0x02}, // MC3_Y0DEF1_POS2 : +{0x7678,0x0002,0x02}, // MC3_X0DEF2_POS2 : +{0x767A,0xFFF6,0x02}, // MC3_Y0DEF2_POS2 : +{0x767C,0x003B,0x02}, // MC3_X0DEF3_POS2 : +{0x767E,0xFFBB,0x02}, // MC3_Y0DEF3_POS2 : +{0x7680,0xFFCE,0x02}, // MC3_X0DEF0_POS3 : +{0x7682,0xFFBA,0x02}, // MC3_Y0DEF0_POS3 : +{0x7684,0xFFFE,0x02}, // MC3_X0DEF1_POS3 : +{0x7686,0x000D,0x02}, // MC3_Y0DEF1_POS3 : +{0x7688,0x0002,0x02}, // MC3_X0DEF2_POS3 : +{0x768A,0xFFF6,0x02}, // MC3_Y0DEF2_POS3 : +{0x768C,0x003B,0x02}, // MC3_X0DEF3_POS3 : +{0x768E,0xFFBB,0x02}, // MC3_Y0DEF3_POS3 : +{0x7690,0xFFCE,0x02}, // MC3_X0DEF0_POS4 : +{0x7692,0xFFC9,0x02}, // MC3_Y0DEF0_POS4 : +{0x7694,0xFFD0,0x02}, // MC3_X0DEF1_POS4 : +{0x7696,0x0037,0x02}, // MC3_Y0DEF1_POS4 : +{0x7698,0x0002,0x02}, // MC3_X0DEF2_POS4 : +{0x769A,0xFFF6,0x02}, // MC3_Y0DEF2_POS4 : +{0x769C,0x003B,0x02}, // MC3_X0DEF3_POS4 : +{0x769E,0xFFBB,0x02}, // MC3_Y0DEF3_POS4 : +{0x76A0,0xFFCE,0x02}, // MC3_X0DEF0_POS5 : +{0x76A2,0xFFC9,0x02}, // MC3_Y0DEF0_POS5 : +{0x76A4,0xFFD0,0x02}, // MC3_X0DEF1_POS5 : +{0x76A6,0x0037,0x02}, // MC3_Y0DEF1_POS5 : +{0x76A8,0x0002,0x02}, // MC3_X0DEF2_POS5 : +{0x76AA,0xFFF6,0x02}, // MC3_Y0DEF2_POS5 : +{0x76AC,0x003B,0x02}, // MC3_X0DEF3_POS5 : +{0x76AE,0xFFBB,0x02}, // MC3_Y0DEF3_POS5 : +{0x76B0,0xFFCE,0x02}, // MC3_X0DEF0_POS6 : +{0x76B2,0xFFC9,0x02}, // MC3_Y0DEF0_POS6 : +{0x76B4,0xFFFE,0x02}, // MC3_X0DEF1_POS6 : +{0x76B6,0x000D,0x02}, // MC3_Y0DEF1_POS6 : +{0x76B8,0x0002,0x02}, // MC3_X0DEF2_POS6 : +{0x76BA,0xFFF6,0x02}, // MC3_Y0DEF2_POS6 : +{0x76BC,0x003B,0x02}, // MC3_X0DEF3_POS6 : +{0x76BE,0xFFBB,0x02}, // MC3_Y0DEF3_POS6 : +{0x76C0,0xFFCE,0x02}, // MC3_X0DEF0_POS7 : +{0x76C2,0xFFC9,0x02}, // MC3_Y0DEF0_POS7 : +{0x76C4,0xFFFE,0x02}, // MC3_X0DEF1_POS7 : +{0x76C6,0x000D,0x02}, // MC3_Y0DEF1_POS7 : +{0x76C8,0x0002,0x02}, // MC3_X0DEF2_POS7 : +{0x76CA,0xFFF6,0x02}, // MC3_Y0DEF2_POS7 : +{0x76CC,0x003B,0x02}, // MC3_X0DEF3_POS7 : +{0x76CE,0xFFBB,0x02}, // MC3_Y0DEF3_POS7 : +{0x76D0,0xFF7E,0x02}, // MC3_X0DEF0_OUT : +{0x76D2,0xFFE2,0x02}, // MC3_Y0DEF0_OUT : +{0x76D4,0xFFFE,0x02}, // MC3_X0DEF1_OUT : +{0x76D6,0x000D,0x02}, // MC3_Y0DEF1_OUT : +{0x76D8,0x0002,0x02}, // MC3_X0DEF2_OUT : +{0x76DA,0xFFF6,0x02}, // MC3_Y0DEF2_OUT : +{0x76DC,0xFFC4,0x02}, // MC3_X0DEF3_OUT : +{0x76DE,0xFFEC,0x02}, // MC3_Y0DEF3_OUT : +{0x76E0,0xFFCE,0x02}, // MC3_X0DEF0_R2_POS4 : +{0x76E2,0xFFC9,0x02}, // MC3_Y0DEF0_R2_POS4 : +{0x76E4,0xFFD0,0x02}, // MC3_X0DEF1_R2_POS4 : +{0x76E6,0x0037,0x02}, // MC3_Y0DEF1_R2_POS4 : +{0x76E8,0x0002,0x02}, // MC3_X0DEF2_R2_POS4 : +{0x76EA,0xFFF6,0x02}, // MC3_Y0DEF2_R2_POS4 : +{0x76EC,0x003B,0x02}, // MC3_X0DEF3_R2_POS4 : +{0x76EE,0xFFBB,0x02}, // MC3_Y0DEF3_R2_POS4 : +{0x76F0,0xFFCE,0x02}, // MC3_X0DEF0_R2_POS5 : +{0x76F2,0xFFC9,0x02}, // MC3_Y0DEF0_R2_POS5 : +{0x76F4,0xFFD0,0x02}, // MC3_X0DEF1_R2_POS5 : +{0x76F6,0x0037,0x02}, // MC3_Y0DEF1_R2_POS5 : +{0x76F8,0x0002,0x02}, // MC3_X0DEF2_R2_POS5 : +{0x76FA,0xFFF6,0x02}, // MC3_Y0DEF2_R2_POS5 : +{0x76FC,0x003B,0x02}, // MC3_X0DEF3_R2_POS5 : +{0x76FE,0xFFBB,0x02}, // MC3_Y0DEF3_R2_POS5 : +{0x7700,0x0019,0x02}, // MC3_PXDEF0_POS1 : +{0x7702,0xFF66,0x02}, // MC3_PYDEF0_POS1 : +{0x7704,0x0000,0x02}, // MC3_PXDEF1_POS1 : +{0x7706,0x0000,0x02}, // MC3_PYDEF1_POS1 : +{0x7708,0x0000,0x02}, // MC3_PXDEF2_POS1 : +{0x770A,0x0000,0x02}, // MC3_PYDEF2_POS1 : +{0x770C,0xFFD7,0x02}, // MC3_PXDEF3_POS1 : +{0x770E,0x0068,0x02}, // MC3_PYDEF3_POS1 : +{0x7710,0x0000,0x02}, // MC3_PXDEF0_POS2 : +{0x7712,0xFF66,0x02}, // MC3_PYDEF0_POS2 : +{0x7714,0x0033,0x02}, // MC3_PXDEF1_POS2 : +{0x7716,0xFF4C,0x02}, // MC3_PYDEF1_POS2 : +{0x7718,0x0000,0x02}, // MC3_PXDEF2_POS2 : +{0x771A,0x00B3,0x02}, // MC3_PYDEF2_POS2 : +{0x771C,0xFFD7,0x02}, // MC3_PXDEF3_POS2 : +{0x771E,0x0068,0x02}, // MC3_PYDEF3_POS2 : +{0x7720,0x0000,0x02}, // MC3_PXDEF0_POS3 : +{0x7722,0xFF80,0x02}, // MC3_PYDEF0_POS3 : +{0x7724,0x0000,0x02}, // MC3_PXDEF1_POS3 : +{0x7726,0x0000,0x02}, // MC3_PYDEF1_POS3 : +{0x7728,0x0000,0x02}, // MC3_PXDEF2_POS3 : +{0x772A,0x0000,0x02}, // MC3_PYDEF2_POS3 : +{0x772C,0xFFD7,0x02}, // MC3_PXDEF3_POS3 : +{0x772E,0x0068,0x02}, // MC3_PYDEF3_POS3 : +{0x7730,0x0000,0x02}, // MC3_PXDEF0_POS4 : +{0x7732,0xFFCC,0x02}, // MC3_PYDEF0_POS4 : +{0x7734,0x0000,0x02}, // MC3_PXDEF1_POS4 : +{0x7736,0x0000,0x02}, // MC3_PYDEF1_POS4 : +{0x7738,0x0000,0x02}, // MC3_PXDEF2_POS4 : +{0x773A,0x0000,0x02}, // MC3_PYDEF2_POS4 : +{0x773C,0xFFD7,0x02}, // MC3_PXDEF3_POS4 : +{0x773E,0x0068,0x02}, // MC3_PYDEF3_POS4 : +{0x7740,0x0000,0x02}, // MC3_PXDEF0_POS5 : +{0x7742,0xFFCC,0x02}, // MC3_PYDEF0_POS5 : +{0x7744,0x0000,0x02}, // MC3_PXDEF1_POS5 : +{0x7746,0x0000,0x02}, // MC3_PYDEF1_POS5 : +{0x7748,0x0000,0x02}, // MC3_PXDEF2_POS5 : +{0x774A,0x0000,0x02}, // MC3_PYDEF2_POS5 : +{0x774C,0xFFD7,0x02}, // MC3_PXDEF3_POS5 : +{0x774E,0x0068,0x02}, // MC3_PYDEF3_POS5 : +{0x7750,0xFFB3,0x02}, // MC3_PXDEF0_POS6 : +{0x7752,0x0000,0x02}, // MC3_PYDEF0_POS6 : +{0x7754,0x0033,0x02}, // MC3_PXDEF1_POS6 : +{0x7756,0xFF4C,0x02}, // MC3_PYDEF1_POS6 : +{0x7758,0x0000,0x02}, // MC3_PXDEF2_POS6 : +{0x775A,0x00B3,0x02}, // MC3_PYDEF2_POS6 : +{0x775C,0xFFD7,0x02}, // MC3_PXDEF3_POS6 : +{0x775E,0x0068,0x02}, // MC3_PYDEF3_POS6 : +{0x7760,0xFFB3,0x02}, // MC3_PXDEF0_POS7 : +{0x7762,0x0000,0x02}, // MC3_PYDEF0_POS7 : +{0x7764,0x0000,0x02}, // MC3_PXDEF1_POS7 : +{0x7766,0x0000,0x02}, // MC3_PYDEF1_POS7 : +{0x7768,0x0000,0x02}, // MC3_PXDEF2_POS7 : +{0x776A,0x0000,0x02}, // MC3_PYDEF2_POS7 : +{0x776C,0xFFD7,0x02}, // MC3_PXDEF3_POS7 : +{0x776E,0x0068,0x02}, // MC3_PYDEF3_POS7 : +{0x7770,0x0019,0x02}, // MC3_PXDEF0_OUT : +{0x7772,0xFFE6,0x02}, // MC3_PYDEF0_OUT : +{0x7774,0x0000,0x02}, // MC3_PXDEF1_OUT : +{0x7776,0x0000,0x02}, // MC3_PYDEF1_OUT : +{0x7778,0x0000,0x02}, // MC3_PXDEF2_OUT : +{0x777A,0x0000,0x02}, // MC3_PYDEF2_OUT : +{0x777C,0xFFE1,0x02}, // MC3_PXDEF3_OUT : +{0x777E,0xFFEB,0x02}, // MC3_PYDEF3_OUT : +{0x7780,0x0000,0x02}, // MC3_PXDEF0_R2_POS4 : +{0x7782,0xFFCC,0x02}, // MC3_PYDEF0_R2_POS4 : +{0x7784,0x0000,0x02}, // MC3_PXDEF1_R2_POS4 : +{0x7786,0x0000,0x02}, // MC3_PYDEF1_R2_POS4 : +{0x7788,0x0000,0x02}, // MC3_PXDEF2_R2_POS4 : +{0x778A,0x0000,0x02}, // MC3_PYDEF2_R2_POS4 : +{0x778C,0xFFD7,0x02}, // MC3_PXDEF3_R2_POS4 : +{0x778E,0x0068,0x02}, // MC3_PYDEF3_R2_POS4 : +{0x7790,0x0000,0x02}, // MC3_PXDEF0_R2_POS5 : +{0x7792,0xFFCC,0x02}, // MC3_PYDEF0_R2_POS5 : +{0x7794,0x0000,0x02}, // MC3_PXDEF1_R2_POS5 : +{0x7796,0x0000,0x02}, // MC3_PYDEF1_R2_POS5 : +{0x7798,0x0000,0x02}, // MC3_PXDEF2_R2_POS5 : +{0x779A,0x0000,0x02}, // MC3_PYDEF2_R2_POS5 : +{0x779C,0xFFD7,0x02}, // MC3_PXDEF3_R2_POS5 : +{0x779E,0x0068,0x02}, // MC3_PYDEF3_R2_POS5 : +}; + +static const isx012_regset_t ISX012_Halfrelease_Mode[] = +{ +{0x0082,0x01,0x01}, // MONI_REFRESH +{0x00B1,0x01,0x01}, //AF_RESTART_F : +{0x00B2,0x03,0x01}, //AFMODE_MONI : AF OFF +{0x00B3,0x00,0x01}, //AFMODE_HREL : +//{0xFFFF,0x42,0x01}, //$wait, 66 +{0x0081,0x01,0x01}, //MODESEL +}; + +static const isx012_regset_t ISX012_Barcode_SAF[] = +{ +{0x0082,0x01,0x01}, // MONI_REFRESH +{0x00B1,0x01,0x01}, //AF_RESTART_F : +//{0xFFFF,0x21,0x01}, //$wait, 33 +{0x00B2,0x00,0x01}, //AFMODE_MONI : +}; + +static const isx012_regset_t ISX012_Lowlux_night_Halfrelease_Mode[] = +{ +{0x660E,0x04,0x01}, // AF_HBPF_PEAK_OPD_TH_MIN +{0x6610,0x04,0x01}, // AF_HBPF_PEAK_OPD_TH_MAX +{0x664A,0x01,0x01}, // AF_DROPN_ON_PEAK_DETECT : +{0x6640,0x01,0x01}, // AF_DROPN_ON_PEAK_DETECT_SECOND : +{0x0289,0x21,0x01}, //AWB_SN8 +{0x6674,0x01,0x01}, // AF_MONICHG_MOVE_F +{0x0082,0x01,0x01}, // MONI_REFRESH +{0x00B1,0x01,0x01}, //AF_RESTART_F +{0x00B3,0x00,0x01}, //AFMODE_HREL : +//{0xFFFF,0x42,0x01}, //$wait, 66 +{0x0081,0x01,0x01}, //MODESEL +}; + +static const isx012_regset_t ISX012_AF_Cancel_Macro_ON[] = +{ +{0x6674,0x00,0x01}, // AF_MONICHG_MOVE_F +{0x0082,0x01,0x01}, // MONI_REFRESH +{0x00B2,0x02,0x01}, //AFMODE_MONI : Manual AF mode +{0x0081,0x00,0x01}, //MODESEL : Monitoring mode +{0x6648,0x02BC,0x02}, //AF_MANUAL_POS : MANUA AF search start position +{0x00B1,0x01,0x01}, //AF_RESTART_F +}; + +static const isx012_regset_t ISX012_AF_Cancel_Macro_OFF[] = +{ +{0x6674,0x00,0x01}, // AF_MONICHG_MOVE_F +{0x0082,0x01,0x01}, // MONI_REFRESH +{0x00B2,0x02,0x01}, //AFMODE_MONI : Manual AF mode +{0x0081,0x00,0x01}, //MODESEL : Monitoring mode +{0x6648,0x00C8,0x02}, //AF_MANUAL_POS : MANUA AF search start position +{0x00B1,0x01,0x01}, //AF_RESTART_F +}; + +static const isx012_regset_t ISX012_AF_ReStart[] = +{ +{0x00B1,0x01,0x01}, //AF_RESTART_F +{0x0082,0x01,0x01}, // MONI_REFRESH +}; + +static const isx012_regset_t ISX012_AF_Macro_OFF[] = +{ +{0x0081,0x00,0x01}, //MODESEL : Monitoring mode +{0x6648,0x00C8,0x02}, //AF_MANUAL_POS : MANUA AF search start position +{0x66DC,0x02BC,0x02}, //AF_JUDGE_MONO_POS_S +{0x665A,0x00C8,0x02}, // AF_LENSPOS_ON_AFNG : +{0x028E,0x00,0x01}, //AF_SEARCH_DIR : NEAR->FAR +{0x00B3,0x00,0x01}, //AFMODE_HREL : Manual AF mode +{0x00B2,0x02,0x01}, //AFMODE_MONI : Manual AF mode +//{0xFFFF,0x21,0x01}, //$wait, 33 +}; + +static const isx012_regset_t ISX012_AF_Macro_ON[] = +{ +{0x0081,0x00,0x01}, //MODESEL : Monitoring mode +{0x6648,0x02BC,0x02}, //AF_MANUAL_POS : MANUA AF search start position +{0x66DC,0x00C8,0x02}, //AF_JUDGE_MONO_POS_S +{0x665A,0x02BC,0x02}, // AF_LENSPOS_ON_AFNG : +{0x028E,0x01,0x01}, //AF_SEARCH_DIR : NEAR->FAR +{0x00B3,0x00,0x01}, //AFMODE_HREL : Manual AF mode +{0x00B2,0x02,0x01}, //AFMODE_MONI : Manual AF mode +//{0xFFFF,0x21,0x01}, //$wait, 33 +}; + +static const isx012_regset_t ISX012_AF_SAF[] = +{ +{0x0082,0x01,0x01}, // MONI_REFRESH +{0x00B1,0x01,0x01}, //AF_RESTART_F : +{0x00B2,0x03,0x01}, //AFMODE_MONI : AF OFF +{0x00B3,0x00,0x01}, //AFMODE_HREL : +//{0xFFFF,0x42,0x01}, //$wait, 66 +{0x0081,0x01,0x01}, //MODESEL +}; + +static const isx012_regset_t ISX012_AF_SAF_OFF[] = +{ +{0x6674,0x00,0x01}, // AF_MONICHG_MOVE_F +{0x0082,0x01,0x01}, // MONI_REFRESH +//{0xFFFF,0x42,0x01}, //$wait, 66 +{0x00B2,0x03,0x01}, //AFMODE_MONI : AF OFF +{0x00B3,0x03,0x01}, //AFMODE_HREL : AF OFF +}; + +static const isx012_regset_t ISX012_AF_TouchSAF_OFF[] = +{ +{0x6674,0x00,0x01}, // AF_MONICHG_MOVE_F +{0x0082,0x01,0x01}, // MONI_REFRESH +//{0xFFFF,0x42,0x01}, //$wait, 66 +{0x00B2,0x03,0x01}, //AFMODE_MONI : AF OFF +{0x00B3,0x03,0x01}, //AFMODE_HREL : AF OFF +{0x0081,0x00,0x01}, //MODESEL +}; + +static const isx012_regset_t ISX012_Camcorder_SAF_Start[] = +{ +{0x0082,0x01,0x01}, // MONI_REFRESH +{0x00B1,0x01,0x01}, /* AF_RESTART_F */ +//{0xFFFF,0x21,0x01}, /* $wait, 33 */ +{0x00B2,0x00,0x01}, /* AFMODE_MONI */ +}; + +static const isx012_regset_t ISX012_Camcorder_CAF_Start[] = +{ +{0x00B2,0x01,0x01}, /* AFMODE_MONI */ +}; + +static const isx012_regset_t ISX012_AF_Window_Reset[] = +{ +//AF opd window setting +{0x6A30,0x044E,0x02}, // AF_OPD0_HDELAY : +{0x6A32,0x02E5,0x02}, // AF_OPD0_VDELAY : +{0x6A34,0x01D8,0x02}, // AF_OPD0_HVALID : +{0x6A36,0x01D8,0x02}, // AF_OPD0_VVALID : +{0x6A38,0x0412,0x02}, // AF_OPD1_HDELAY : +{0x6A3A,0x02A9,0x02}, // AF_OPD1_VDELAY : +{0x6A3C,0x0251,0x02}, // AF_OPD1_HVALID : +{0x6A3E,0x0251,0x02}, // AF_OPD1_VVALID : +{0x6A40,0x04B4,0x02}, // AF_OPD2_HDELAY : +{0x6A42,0x0114,0x02}, // AF_OPD2_VDELAY : +{0x6A44,0x0118,0x02}, // AF_OPD2_HVALID : +{0x6A46,0x0118,0x02}, // AF_OPD2_VVALID : +{0x6A48,0x0469,0x02}, // AF_OPD3_HDELAY : +{0x6A4A,0x00C9,0x02}, // AF_OPD3_VDELAY : +{0x6A4C,0x01AE,0x02}, // AF_OPD3_HVALID : +{0x6A4E,0x01AE,0x02}, // AF_OPD3_VVALID : +{0x6A50,0x04C6,0x02}, // AF_OPD4_HDELAY : +{0x6A52,0x035D,0x02}, // AF_OPD4_VDELAY : +{0x6A54,0x00E6,0x02}, // AF_OPD4_HVALID : +{0x6A56,0x00E6,0x02}, // AF_OPD4_VVALID : +{0x6A58,0x048A,0x02}, // AF_OPD5_HDELAY : +{0x6A5A,0x0321,0x02}, // AF_OPD5_VDELAY : +{0x6A5C,0x015F,0x02}, // AF_OPD5_HVALID : +{0x6A5E,0x015F,0x02}, // AF_OPD5_VVALID : +{0x6A60,0x04B4,0x02}, // AF_OPD6_HDELAY : +{0x6A62,0x0579,0x02}, // AF_OPD6_VDELAY : +{0x6A64,0x0118,0x02}, // AF_OPD6_HVALID : +{0x6A66,0x0118,0x02}, // AF_OPD6_VVALID : +{0x6A68,0x0469,0x02}, // AF_OPD7_HDELAY : +{0x6A6A,0x052C,0x02}, // AF_OPD7_VDELAY : +{0x6A6C,0x01AE,0x02}, // AF_OPD7_HVALID : +{0x6A6E,0x01AE,0x02}, // AF_OPD7_VVALID : +{0x6A70,0x021D,0x02}, // AF_OPD8_HDELAY : +{0x6A72,0x02F5,0x02}, // AF_OPD8_VDELAY : +{0x6A74,0x01AE,0x02}, // AF_OPD8_HVALID : +{0x6A76,0x01AE,0x02}, // AF_OPD8_VVALID : +{0x6A78,0x06A4,0x02}, // AF_OPD9_HDELAY : +{0x6A7A,0x02F5,0x02}, // AF_OPD9_VDELAY : +{0x6A7C,0x01AE,0x02}, // AF_OPD9_HVALID : +{0x6A7E,0x01AE,0x02}, // AF_OPD9_VVALID : +{0x6A80,0x06,0x01}, // AF_OPD1A_WEIGHT : +{0x6A81,0x05,0x01}, // AF_OPD1B_WEIGHT : +{0x6A82,0x02,0x01}, // AF_OPD2A_WEIGHT : +{0x6A83,0x02,0x01}, // AF_OPD2B_WEIGHT : +{0x6A84,0x08,0x01}, // AF_OPD3A_WEIGHT : +{0x6A85,0x07,0x01}, // AF_OPD3B_WEIGHT : +{0x6A86,0x04,0x01}, // AF_OPD4A_WEIGHT : +{0x6A87,0x03,0x01}, // AF_OPD4B_WEIGHT : +{0x6A88,0x01,0x01}, // AF_OPD5A_WEIGHT : +{0x6A89,0x01,0x01}, // AF_OPD5B_WEIGHT : +{0x6646,0x08,0x01}, // AF_OPD_WEIGHT_TH : +}; + +/* Added by Samsung TN */ +static const isx012_regset_t ISX012_AF_Window_Set[] = +{ +{0x6A80,0x00,0x01}, +{0x6A81,0x00,0x01}, +{0x6A82,0x00,0x01}, +{0x6A83,0x00,0x01}, +{0x6A84,0x08,0x01}, +{0x6A85,0x00,0x01}, +{0x6A86,0x00,0x01}, +{0x6A87,0x00,0x01}, +{0x6A88,0x00,0x01}, +{0x6A89,0x00,0x01}, +{0x6646,0x08,0x01}, +}; + +static const isx012_regset_t isx012_Contrast_Minus_2[] = +{ +{0x01C7,0x58,0x01}, //UICONTRAST +}; + +static const isx012_regset_t isx012_Contrast_Minus_1[] = +{ +{0x01C7,0x6C,0x01}, //UICONTRAST +}; + +static const isx012_regset_t isx012_Contrast_Default[] = +{ +{0x01C7,0x80,0x01}, //UICONTRAST +}; + +static const isx012_regset_t isx012_Contrast_Plus_1[] = +{ +{0x01C7,0x94,0x01}, //UICONTRAST +}; + +static const isx012_regset_t isx012_Contrast_Plus_2[] = +{ +{0x01C7,0xA8,0x01}, //UICONTRAST +}; + +static const isx012_regset_t isx012_Effect_Sketch[] = +{ +{0x01C5,0x06,0x01}, /* FMODE */ +{0x6C5F,0x04,0x01}, /* SKETCH_APGAIN */ +}; + +static const isx012_regset_t isx012_Effect_Pastel[] = +{ +{0x01C5,0x05,0x01}, /* FMODE */ +}; + +static const isx012_regset_t isx012_Effect_Black_White[] = +{ +{0x01C5,0x04,0x01}, //FMODE +}; + +static const isx012_regset_t ISX012_Effect_Negative[] = +{ +{0x01C5,0x02,0x01}, //FMODE +}; + +static const isx012_regset_t isx012_Effect_Solar[] = +{ +{0x01C5,0x01,0x01}, /* FMODE */ +}; + +static const isx012_regset_t isx012_Effect_Normal[] = +{ +{0x01C5,0x00,0x01}, //FMODE +}; + +static const isx012_regset_t isx012_Effect_Sepia[] = +{ +{0x01C5,0x03,0x01}, //FMODE +}; + +static const isx012_regset_t isx012_Metering_Center[] = +{ +{0x02AC,0x01,0x01}, //AE_SUB_SN1 +{0x02B6,0x01,0x01}, //AE_SUB_SN11 +}; + +static const isx012_regset_t isx012_Metering_Matrix[] = +{ +{0x02AC,0x00,0x01}, //AE_SUB_SN1 +}; + +static const isx012_regset_t isx012_Metering_Spot[] = +{ +{0x02AC,0x02,0x01}, //AE_SUB_SN1 +{0x02B6,0x02,0x01}, //AE_SUB_SN11 +}; + +static const isx012_regset_t ISX012_ExpSetting_Default[] = +{ +{0x0180,0x00,0x01}, //EVSEL +}; + +static const isx012_regset_t ISX012_ExpSetting_M1Step[] = +{ +{0x0180,0xFF,0x01}, //EVSEL +}; + +static const isx012_regset_t ISX012_ExpSetting_M2Step[] = +{ +{0x0180,0xFE,0x01}, //EVSEL +}; + +static const isx012_regset_t ISX012_ExpSetting_M3Step[] = +{ +{0x0180,0xFD,0x01}, //EVSEL +}; + +static const isx012_regset_t ISX012_ExpSetting_M4Step[] = +{ +{0x0180,0xFC,0x01}, //EVSEL +}; + +static const isx012_regset_t ISX012_ExpSetting_P1Step[] = +{ +{0x0180,0x01,0x01}, //EVSEL +}; + +static const isx012_regset_t ISX012_ExpSetting_P2Step[] = +{ +{0x0180,0x02,0x01}, //EVSEL +}; + +static const isx012_regset_t ISX012_ExpSetting_P3Step[] = +{ +{0x0180,0x03,0x01}, //EVSEL +}; + +static const isx012_regset_t ISX012_ExpSetting_P4Step[] = +{ +{0x0180,0x04,0x01}, //EVSEL +}; + +static const isx012_regset_t isx012_ISO_50[] = +{ +{0x02A8,0x04,0x01}, //ISO_TYPE1 +{0x5E8A,0x00,0x01}, // EVREF_GAIN_A : +{0x5E8B,0x00,0x01}, // EVREF_GAIN_B : +{0x0362,0x57,0x01}, // PICT3_GAMMA_MONI0 : +{0x0365,0x57,0x01}, // PICT3_GAMMA_CAP0 : +}; + +static const isx012_regset_t isx012_ISO_100[] = +{ +{0x02A8,0x07,0x01}, //ISO_TYPE1 +{0x5E8A,0x00,0x01}, // EVREF_GAIN_A : +{0x5E8B,0x00,0x01}, // EVREF_GAIN_B : +{0x0362,0x57,0x01}, // PICT3_GAMMA_MONI0 : +{0x0365,0x57,0x01}, // PICT3_GAMMA_CAP0 : +}; + +static const isx012_regset_t isx012_ISO_200[] = +{ +{0x02A8,0x0A,0x01}, //ISO_TYPE1 +{0x5E8A,0x00,0x01}, // EVREF_GAIN_A : +{0x5E8B,0x00,0x01}, // EVREF_GAIN_B : +{0x0362,0x57,0x01}, // PICT3_GAMMA_MONI0 : +{0x0365,0x57,0x01}, // PICT3_GAMMA_CAP0 : +}; + +static const isx012_regset_t isx012_ISO_400[] = +{ +{0x02A8,0x0D,0x01}, //ISO_TYPE1 +{0x5E8A,0x00,0x01}, // EVREF_GAIN_A : +{0x5E8B,0x00,0x01}, // EVREF_GAIN_B : +{0x0362,0x57,0x01}, // PICT3_GAMMA_MONI0 : +{0x0365,0x57,0x01}, // PICT3_GAMMA_CAP0 : +}; + +#if 0 +static const isx012_regset_t ISX012_ISO_800[] = +{ +{0x02A8,0x10,0x01}, //ISO_TYPE1 +{0x5E8A,0x00,0x01}, // EVREF_GAIN_A : +{0x5E8B,0x00,0x01}, // EVREF_GAIN_B : +{0x0362,0x57,0x01}, // PICT3_GAMMA_MONI0 : +{0x0365,0x57,0x01}, // PICT3_GAMMA_CAP0 : +}; +#endif + +static const isx012_regset_t isx012_ISO_Auto[] = +{ +{0x02A8,0x00,0x01}, //ISO_TYPE1 +{0x5E8A,0x02,0x01}, // EVREF_GAIN_A : +{0x5E8B,0x02,0x01}, // EVREF_GAIN_B : +{0x0362,0x55,0x01}, // PICT3_GAMMA_MONI0 : +{0x0365,0x55,0x01}, // PICT3_GAMMA_CAP0 : +}; + +static const isx012_regset_t ISX012_Capture_SizeSetting[] = +{ +{0x0092,0x0A20,0x02}, //HSIZE_CAP : 2592 +{0x0098,0x0798,0x02}, //VSIZE_CAP : 1944 +}; + +static const isx012_regset_t ISX012_Capture_Mode[] = +{ +{0x008A,0x00,0x01}, //OUTFMT_CAP +{0x0084,0x00,0x01}, //SENSMODE_CAP +{0x0087,0x03,0x01}, //FPSTYPE_CAP +{0x0012,0xFF,0x01}, //INTCLR0 +{0x0081,0x02,0x01}, //MODESEL +{0x0082,0x01,0x01}, //MONI_REFRESH +}; + +static const isx012_regset_t ISX012_Lowlux_Night_Capture_Mode[] = +{ +{0x03A0,0xA0,0x01}, //UISATURATION_TYPE3 : +{0x039D,0xF4,0x01}, //UIHUE_TYPE3 : +{0x982A,0xFFD8,0x02}, // CS_CBLLEV_A : +{0x9830,0xFFD8,0x02}, // CS_CRLLEV_A : +{0x9805,0x06,0x01}, // CS_SLP_C_A : +{0x008A,0x00,0x01}, //OUTFMT_CAP +{0x0084,0x00,0x01}, //SENSMODE_CAP +{0x0087,0x03,0x01}, //FPSTYPE_CAP +{0x0012,0xFF,0x01}, //INTCLR0 +{0x0081,0x02,0x01}, //MODESEL +{0x0082,0x01,0x01}, //MONI_REFRESH +}; + +static const isx012_regset_t isx012_Saturation_Default[] = +{ +{0x039E,0x80,0x01}, //UISATURATION_TYPE1 +}; + +static const isx012_regset_t isx012_Saturation_Minus_1[] = +{ +{0x039E,0x62,0x01}, //UISATURATION_TYPE1 +}; + +static const isx012_regset_t isx012_Saturation_Minus_2[] = +{ +{0x039E,0x44,0x01}, //UISATURATION_TYPE1 +}; + +static const isx012_regset_t isx012_Saturation_Plus_1[] = +{ +{0x039E,0x9E,0x01}, //UISATURATION_TYPE1 +}; + +static const isx012_regset_t isx012_Saturation_Plus_2[] = +{ +{0x039E,0xBC,0x01}, //UISATURATION_TYPE1 +}; + +static const isx012_regset_t isx012_Scene_Default[] = +{ +{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto +{0x5E06,0x02,0x01}, //SHTCTRLMAG3 +{0x038F,0x00,0x01}, //PICT1_SN1 : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL +{0x0280,0x00,0x01}, //SCENE_SELECT +}; + +static const isx012_regset_t isx012_Scene_Landscape[] = +{ +{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto +{0x039F,0x9E,0x01}, //UISATURATION_TYPE2 : +{0x03A3,0x2C,0x01}, //UISHARPNESS_POS_TYPE3 : +1 +{0x03A6,0x2C,0x01}, //UISHARPNESS_NEG_TYPE3 : +1 +{0x5E06,0x02,0x01}, //SHTCTRLMAG3 +{0x038F,0x00,0x01}, //PICT1_SN1 : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL +{0x0280,0x01,0x01}, //SCENE_SELECT +}; + +static const isx012_regset_t isx012_Scene_Sports[] = +{ +{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto +{0x5E06,0x02,0x01}, //SHTCTRLMAG3 +{0x038F,0x00,0x01}, //PICT1_SN1 : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL +{0x0280,0x02,0x01}, //SCENE_SELECT +}; + +static const isx012_regset_t isx012_Scene_Party_Indoor[] = +{ +{0x02A8,0x0A,0x01}, //ISO_TYPE1 : ISO200 +{0x039F,0x9E,0x01}, //UISATURATION_TYPE2 : +{0x5E06,0x02,0x01}, //SHTCTRLMAG3 +{0x038F,0x04,0x01}, //PICT1_SN1 : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL +{0x0280,0x00,0x01}, //SCENE_SELECT +}; + +static const isx012_regset_t isx012_Scene_Beach_Snow[] = +{ +{0x02A8,0x04,0x01}, //ISO_TYPE1 : ISO50 +{0x039F,0x9E,0x01}, //UISATURATION_TYPE2 : +{0x5E06,0x02,0x01}, //SHTCTRLMAG3 +{0x038F,0x00,0x01}, //PICT1_SN1 : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL +{0x0280,0x04,0x01}, //SCENE_SELECT +}; + +static const isx012_regset_t isx012_Scene_Sunset[] = +{ +{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto +{0x0287,0x25,0x01}, //AWB_SN6 : daylight +{0x0394,0x00,0x01}, //PICT1_SN6 : +{0x5E06,0x02,0x01}, //SHTCTRLMAG3 +{0x038F,0x00,0x01}, //PICT1_SN1 : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL +{0x0280,0x05,0x01}, //SCENE_SELECT +}; + +static const isx012_regset_t isx012_Scene_Duskdawn[] = +{ +{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto +{0x0287,0x27,0x01}, //AWB_SN6 : CWF +{0x0394,0x00,0x01}, //PICT1_SN6 : +{0x5E06,0x02,0x01}, //SHTCTRLMAG3 +{0x038F,0x00,0x01}, //PICT1_SN1 : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL +{0x0280,0x05,0x01}, //SCENE_SELECT +}; + +static const isx012_regset_t isx012_Scene_Candle_Light[] = +{ +{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto +{0x0287,0x25,0x01}, //AWB_SN6 : daylight +{0x0394,0x00,0x01}, //PICT1_SN6 : +{0x5E06,0x02,0x01}, //SHTCTRLMAG3 +{0x038F,0x00,0x01}, //PICT1_SN1 : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL +{0x0280,0x05,0x01}, //SCENE_SELECT +}; + +static const isx012_regset_t isx012_Scene_Fall_Color[] = +{ +{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto +{0x039F,0xBC,0x01}, //UISATURATION_TYPE2 : +{0x0287,0x20,0x01}, //AWB_SN6 : AWB +{0x0394,0x04,0x01}, //PICT1_SN6 : +{0x5E06,0x02,0x01}, //SHTCTRLMAG3 +{0x038F,0x00,0x01}, //PICT1_SN1 : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL +{0x0280,0x05,0x01}, //SCENE_SELECT +}; + +static const isx012_regset_t isx012_Scene_Portrait[] = +{ +{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto +{0x5E06,0x02,0x01}, //SHTCTRLMAG3 +{0x038F,0x50,0x01}, //PICT1_SN1 : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL +{0x0280,0x00,0x01}, //SCENE_SELECT +}; + +static const isx012_regset_t isx012_Scene_Nightshot[] = +{ +{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto +{0x5E06,0x02,0x01}, //SHTCTRLMAG3 +{0x038F,0x00,0x01}, //PICT1_SN1 : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x500B,0x00,0x01}, // FAST_SHT_MODE_SEL +{0x0280,0x07,0x01}, //SCENE_SELECT +}; + +static const isx012_regset_t isx012_Scene_Fireworks[] = +{ +{0x02A8,0x00,0x01}, //ISO_TYPE1 : AUTO +{0x5E06,0x04,0x01}, //SHTCTRLMAG3 +{0x038F,0x00,0x01}, //PICT1_SN1 : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x500B,0x00,0x01}, // FAST_SHT_MODE_SEL +{0x0280,0x08,0x01}, //SCENE_SELECT +}; + +static const isx012_regset_t isx012_Scene_Text[] = +{ +{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto +{0x03A3,0x38,0x01}, //UISHARPNESS_POS_TYPE3 : +2 +{0x03A6,0x38,0x01}, //UISHARPNESS_NEG_TYPE3 : +2 +{0x5E06,0x02,0x01}, //SHTCTRLMAG3 +{0x038F,0xA0,0x01}, //PICT1_SN1 : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL +{0x0280,0x00,0x01}, //SCENE_SELECT +}; + +static const isx012_regset_t isx012_Scene_Backlight[] = +{ +{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto +{0x5E06,0x02,0x01}, //SHTCTRLMAG3 +{0x038F,0x00,0x01}, //PICT1_SN1 : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL +{0x0280,0x00,0x01}, //SCENE_SELECT +}; + +static const isx012_regset_t isx012_Sharpness_Default[] = +{ +{0x00A1,0x20,0x01}, //UISHARPNESS_POS_TYPE1 +{0x00A4,0x20,0x01}, //UISHARPNESS_NEG_TYPE1 +}; + +static const isx012_regset_t isx012_Sharpness_Minus_1[] = +{ +{0x00A1,0x14,0x01}, //UISHARPNESS_POS_TYPE1 +{0x00A4,0x14,0x01}, //UISHARPNESS_NEG_TYPE1 +}; + +static const isx012_regset_t isx012_Sharpness_Minus_2[] = +{ +{0x00A1,0x08,0x01}, //UISHARPNESS_POS_TYPE1 +{0x00A4,0x08,0x01}, //UISHARPNESS_NEG_TYPE1 +}; + +static const isx012_regset_t isx012_Sharpness_Plus_1[] = +{ +{0x00A1,0x2C,0x01}, //UISHARPNESS_POS_TYPE1 +{0x00A4,0x2C,0x01}, //UISHARPNESS_NEG_TYPE1 +}; + +static const isx012_regset_t isx012_Sharpness_Plus_2[] = +{ +{0x00A1,0x38,0x01}, //UISHARPNESS_POS_TYPE1 +{0x00A4,0x38,0x01}, //UISHARPNESS_NEG_TYPE1 +}; + +static const isx012_regset_t isx012_WB_Auto[] = +{ +{0x0282,0x20,0x01}, //AWB_SN1 +}; + +static const isx012_regset_t isx012_WB_Cloudy[] = +{ +{0x0282,0x26,0x01}, //AWB_SN1 +}; + +static const isx012_regset_t isx012_WB_Sunny[] = +{ +{0x0282,0x25,0x01}, //AWB_SN1 +}; + +static const isx012_regset_t isx012_WB_Fluorescent[] = +{ +{0x0282,0x27,0x01}, //AWB_SN1 +}; + +static const isx012_regset_t isx012_WB_Tungsten[] = +{ +{0x0282,0x28,0x01}, //AWB_SN1 +}; + +static const isx012_regset_t ISX012_Image_Quality_Standard[] = +{ +{0x00F6,0x00,0x01}, //JPG_QLTY +{0x0082,0x01,0x01}, //MONI_REFRESH +}; + +static const isx012_regset_t ISX012_Image_Quality_Fine[] = +{ +{0x00F6,0x01,0x01}, //JPG_QLTY +{0x0082,0x01,0x01}, //MONI_REFRESH +}; + +static const isx012_regset_t ISX012_Image_Quality_Super_Fine[] = +{ +{0x00F6,0x02,0x01}, //JPG_QLTY +{0x0082,0x01,0x01}, //MONI_REFRESH +}; + +static const isx012_regset_t ISX012_Image_Quality_Table[] = +{ +{0x00F7,0x52,0x01}, // INIT_QLTY0 : Standard 82 +{0x00F8,0x59,0x01}, // INIT_QLTY1 : Fine 89 +{0x00F9,0x5F,0x01}, // INIT_QLTY2 : SuperFine 95 +}; + +static const isx012_regset_t ISX012_Sensor_Off_VCM[] = +{ +{0x6674,0x00,0x01}, // AF_MONICHG_MOVE_F +{0x00B2,0x02,0x01}, //AFMODE_MONI : Manual AF mode +{0x0081,0x00,0x01}, //MODESEL : Monitoring mode +{0x6600,0x0000,0x02}, // AF_SEARCH_AREA_LOW +{0x6666,0x0000,0x02}, // AF_AREA_LOW_TYPE1 +{0x6648,0x00C8,0x02}, // AF_MANUAL_POS : +{0x00B1,0x01,0x01}, //AF_RESTART_F +{0xFFFF,0x64,0x01}, // $wait, 100 +{0x6648,0x0019,0x02}, // AF_MANUAL_POS : +{0x00B1,0x01,0x01}, // AF_RESTART_F +{0xFFFF,0x64,0x01}, // $wait, 100 +}; + +static const isx012_regset_t isx012_1280_Preview_E[] = +{ +{0x0090,0x0500,0x02}, //HSIZE_MONI : 1280 +{0x0096,0x02D0,0x02}, //VSIZE_MONI : 720 +}; + +static const isx012_regset_t isx012_1024_768_Preview[] = { +{0x0090,0x0400,0x02}, /* HSIZE_MONI : 1024 */ +{0x0096,0x0300,0x02}, /* VSIZE_MONI : 768 */ +}; + +static const isx012_regset_t isx012_800_Preview[] = +{ +{0x0090,0x0320,0x02}, //HSIZE_MONI : 800 +{0x0096,0x01E0,0x02}, //VSIZE_MONI : 480 +}; + +static const isx012_regset_t isx012_720_Preview[] = +{ +{0x0090,0x02D0,0x02}, //HSIZE_MONI : 720 +{0x0096,0x01E0,0x02}, //VSIZE_MONI : 480 +}; + +static const isx012_regset_t isx012_640_Preview[] = +{ +{0x0090,0x0280,0x02}, //HSIZE_MONI : 640 +{0x0096,0x01E0,0x02}, //VSIZE_MONI : 480 +}; + +#if defined(CONFIG_MACH_P4NOTELTE_KOR_SKT) \ + || defined(CONFIG_MACH_P4NOTELTE_KOR_KT) \ + || defined(CONFIG_MACH_P4NOTELTE_KOR_LGT) /*For 4G VT call in Domestic*/ +static const isx012_regset_t isx012_480_Preview[] = { +{0x0090, 0x01E0, 0x02}, /* HSIZE_MONI : 480 */ +{0x0096, 0x0280, 0x02}, /* VSIZE_MONI : 640 */ +}; +#endif + +static const isx012_regset_t isx012_320_Preview[] = +{ +{0x0090,0x0140,0x02}, //HSIZE_MONI : 320 +{0x0096,0x00F0,0x02}, //VSIZE_MONI :240 + +}; +static const isx012_regset_t isx012_176_Preview[] = +{ +{0x0090,0x00B0,0x02}, //HSIZE_MONI : 176 +{0x0096,0x0090,0x02}, //VSIZE_MONI : 144 +}; + + +static const isx012_regset_t isx012_5M_Capture[] = { +{0x0092,0x0A00,0x02}, /* HSIZE_CAP: 2560 */ +{0x0098,0x0780,0x02}, /* VSIZE_CAP: 1920 */ +}; + +static const isx012_regset_t isx012_4M_WIDE_Capture[] = +{ +{0x0282,0x20,0x01}, //AWB_SN1 +}; + +static const isx012_regset_t isx012_3M_Capture[] = { +{0x0092,0x0800,0x02}, /* HSIZE_CAP : 2048 */ +{0x0098,0x0600,0x02}, /* VSIZE_CAP : 1536 */ +}; + +static const isx012_regset_t isx012_2_4M_WIDE_Capture[] = +{ +{0x0282,0x20,0x01}, //AWB_SN1 +}; + +static const isx012_regset_t isx012_1_5M_WIDE_Capture[] = +{ +{0x0282,0x20,0x01}, //AWB_SN1 +}; + +static const isx012_regset_t isx012_960_720_Capture[] = { +{0x0092,0x03C0,0x02}, /* HSIZE_CAP : 960 */ +{0x0098,0x02D0,0x02}, /* VSIZE_CAP : 720 */ +}; + +static const isx012_regset_t isx012_1M_Capture[] = +{ +{0x0282,0x20,0x01}, //AWB_SN1 +}; + +static const isx012_regset_t isx012_4K_WIDE_Capture[] = +{ +{0x0282,0x20,0x01}, //AWB_SN1 +}; + +static const isx012_regset_t isx012_VGA_Capture[] = { +{0x0092,0x0280,0x02}, /* HSIZE_CAP : 640 */ +{0x0098,0x01E0,0x02}, /* VSIZE_CAP : 480 */ +}; + +static const isx012_regset_t isx012_QVGA_Capture[] = +{ +{0x0282,0x20,0x01}, //AWB_SN1 +}; + +static const isx012_regset_t isx012_DTP_init[] = +{ +{0x01BC,0x50,0x01},//Shading Gain off +{0x5E00,0x07,0x01},//Flicker off + +// Pre-WB +{0x6804,0x1000,0x02}, // NORMR +{0x6806,0x1000,0x02}, // NORMB +{0x6808,0x0100,0x02}, // AWBPRER +{0x680A,0x0100,0x02}, // AWBPREB +{0x6818,0x00,0x01}, //REFERENCE SENSITIVITY RATIO OF SENSOR (R/G) +{0x6819,0x00,0x01}, //REFERENCE SENSITIVITY RATIO OF SENSOR (B/G) + +{0x036B,0x11,0x01}, +{0x0377,0x11,0x01}, +{0x0383,0x11,0x01}, + +// +{0x6C44,0x00,0x01}, // G_CTRL_SEL : + +//CNR +{0x6C4A,0x07,0x01}, // MAIN_CONFIG5 : + +//ITP NR +{0x5005,0xBB,0x01}, // DM_SW1 : +{0x5006,0x03,0x01}, // DM_SW2 : +{0x0362,0x00,0x01}, + +{0x6C0B,0x04,0x01}, // PICT_FLAG : +{0x9800,0x80,0x01}, // LMT_WEIGHT_A : +{0x9801,0x80,0x01}, // LMT_WEIGHT_B : + +{0x6C46,0x00,0x01}, // MAIN_CONFIG1 : +{0x6C47,0x00,0x01}, // MAIN_CONFIG2 : +{0x6C48,0x00,0x01}, // MAIN_CONFIG3 : +{0x6C49,0x00,0x01}, // MAIN_CONFIG4 : +{0x6C4A,0x00,0x01}, // MAIN_CONFIG5 : + + +{0x5001,0x04,0x01}, // MUTECNT : +{0x5002,0x00,0x01}, // WDT_EN : +{0x5003,0x07,0x01}, // Z1_SEL1 : +{0x5004,0x00,0x01}, // Z1_SEL2 : +{0x5005,0x00,0x01}, // DM_SW1 : +{0x5006,0x00,0x01}, // DM_SW2 : +{0x5007,0x00,0x01}, // CLMP_CTRL : +{0x5009,0x00,0x01}, // CPUSLEEP_EN : +{0x500A,0x00,0x01}, // FAST_MODECHG_EN : +{0x500B,0x00,0x01}, // FAST_SHT_MODE_SEL : +{0x500C,0x00FA,0x02}, // FAST_SHT_LIMIT_COUNT : +{0x500E,0x06D0,0x02}, // SYSINT3_VDLY_1_1 : +{0x5010,0x02F8,0x02}, // SYSINT3_VDLY_1_2 : +{0x5012,0x0118,0x02}, // SYSINT3_VDLY_1_4 : +{0x5014,0x0028,0x02}, // SYSINT3_VDLY_1_8 : +{0x5016,0x0370,0x02}, // SYSINT3_VDLY_1_1_HD : +{0x5018,0x0208,0x02}, // SYSINT3_VDLY_1_2_HD : +{0x501A,0x00,0x01}, // SENS_REVERSE_CTRL : +{0x501B,0x19,0x01}, // EEP_ADDRESS : +{0x501C,0x5180,0x02}, // SRCCK : +{0x501E,0x0001,0x02}, + +{0x6E86,0x0000,0x02}, // IBYHUE1_POS1 : +{0x6E88,0xFFF5,0x02}, // IRYHUE1_POS1 : +{0x6E8A,0xFFF8,0x02}, // IBYHUE2_POS1 : +{0x6E8C,0xFFF5,0x02}, // IRYHUE2_POS1 : +{0x6E8E,0xFFF8,0x02}, // IBYHUE3_POS1 : +{0x6E90,0xFFEE,0x02}, // IRYHUE3_POS1 : +{0x6E92,0x0000,0x02}, // IBYHUE4_POS1 : +{0x6E94,0xFFEC,0x02}, // IRYHUE4_POS1 : +{0x6F26,0x4E,0x01}, // IRYGAIN1_POS1 : +{0x6F27,0x50,0x01}, // IBYGAIN1_POS1 : +{0x6F28,0x4E,0x01}, // IRYGAIN2_POS1 : +{0x6F29,0x5A,0x01}, // IBYGAIN2_POS1 : +{0x6F2A,0x50,0x01}, // IRYGAIN3_POS1 : +{0x6F2B,0x5A,0x01}, // IBYGAIN3_POS1 : +{0x6F2C,0x50,0x01}, // IRYGAIN4_POS1 : +{0x6F2D,0x50,0x01}, // IBYGAIN4_POS1 : + +//ae +{0x5E12,0x0000,0x02}, +{0x5E14,0x0000,0x02}, +{0x0294,0x03,0x01}, + +//AWB +{0x625F,0x35,0x01},//CAT_AWB_1 +{0x0282,0x05,0x01},//AWB_SN1 +//S, 5000, 3F, 8, // CPUEXT : + + +{0x5021,0x00,0x01}, // PG_GAIN_SEL : +{0x5022,0x01,0x01}, // PG_WIDTH_SEL : +{0x5023,0x04,0x01}, // PG_MODE_SEL : +{0x5024,0x0000,0x02}, // PG_LEVEL_SEL : +{0x5026,0x00,0x01}, // PG_DATEN_OFF_SEL : +{0x5020,0x01,0x01}, // PGSEL : + +}; + +static const isx012_regset_t isx012_DTP_stop[] = +{ +{0x01BC,0x57,0x01}, // Shading Gain off +{0x5E00,0x00,0x01}, // Flicker off +{0x6804,0x11F0,0x02}, // NORMR +{0x6806,0x106F,0x02}, // NORMB +{0x6808,0x014C,0x02}, // AWBPRER +{0x680A,0x021E,0x02}, // AWBPREB +{0x6818,0x00,0x01}, // REFERENCE SENSITIVITY RATIO OF SENSOR (R/G) +{0x6819,0x00,0x01}, // REFERENCE SENSITIVITY RATIO OF SENSOR (B/G) +{0x036B,0x80,0x01}, // +{0x0377,0x80,0x01}, // +{0x0383,0x80,0x01}, // +{0x6C44,0x13,0x01}, // G_CTRL_SEL : +{0x6C4A,0x07,0x01}, // MAIN_CONFIG5 : +{0x5005,0xBB,0x01}, // DM_SW1 : +{0x5006,0x03,0x01}, // DM_SW2 : +{0x0362,0x55,0x01}, // +{0x6C0B,0x00,0x01}, // PICT_FLAG : +{0x9800,0x40,0x01}, // LMT_WEIGHT_A : +{0x9801,0x80,0x01}, // LMT_WEIGHT_B : +{0x6C46,0x1C,0x01}, // MAIN_CONFIG1 : +{0x6C47,0x0F,0x01}, // MAIN_CONFIG2 : +{0x6C48,0x03,0x01}, // MAIN_CONFIG3 : +{0x6C49,0xF5,0x01}, // MAIN_CONFIG4 : +{0x6C4A,0x07,0x01}, // MAIN_CONFIG5 : +{0x5001,0x04,0x01}, // MUTECNT : +{0x5002,0x01,0x01}, // WDT_EN : +{0x5003,0x04,0x01}, // Z1_SEL1 : +{0x5004,0x00,0x01}, // Z1_SEL2 : +{0x5005,0xBB,0x01}, // DM_SW1 : +{0x5006,0x03,0x01}, // DM_SW2 : +{0x5007,0x01,0x01}, // CLMP_CTRL : +{0x5009,0x00,0x01}, // CPUSLEEP_EN : +{0x500A,0x00,0x01}, // FAST_MODECHG_EN : +{0x500B,0x00,0x01}, // FAST_SHT_MODE_SEL : +{0x500C,0x00FA,0x02}, // FAST_SHT_LIMIT_COUNT : +{0x500E,0x06D0,0x02}, // SYSINT3_VDLY_1_1 : +{0x5010,0x02F8,0x02}, // SYSINT3_VDLY_1_2 : +{0x5012,0x0118,0x02}, // SYSINT3_VDLY_1_4 : +{0x5014,0x0028,0x02}, // SYSINT3_VDLY_1_8 : +{0x5016,0x0370,0x02}, // SYSINT3_VDLY_1_1_HD : +{0x5018,0x0208,0x02}, // SYSINT3_VDLY_1_2_HD : +{0x501A,0x00,0x01}, // SENS_REVERSE_CTRL : +{0x501B,0x50,0x01}, // EEP_ADDRESS : +{0x501C,0x5180,0x02}, // SRCCK : +{0x501E,0x0001,0x02}, +{0x6E86,0x0000,0x02}, // IBYHUE1_POS1 : +{0x6E88,0xFFF5,0x02}, // IRYHUE1_POS1 : +{0x6E8A,0xFFF8,0x02}, // IBYHUE2_POS1 : +{0x6E8C,0xFFF5,0x02}, // IRYHUE2_POS1 : +{0x6E8E,0xFFF8,0x02}, // IBYHUE3_POS1 : +{0x6E90,0xFFEE,0x02}, // IRYHUE3_POS1 : +{0x6E92,0x0000,0x02}, // IBYHUE4_POS1 : +{0x6E94,0xFFEC,0x02}, // IRYHUE4_POS1 : +{0x6F26,0x4E,0x01}, // IRYGAIN1_POS1 : +{0x6F27,0x50,0x01}, // IBYGAIN1_POS1 : +{0x6F28,0x4E,0x01}, // IRYGAIN2_POS1 : +{0x6F29,0x5A,0x01}, // IBYGAIN2_POS1 : +{0x6F2A,0x50,0x01}, // IRYGAIN3_POS1 : +{0x6F2B,0x5A,0x01}, // IBYGAIN3_POS1 : +{0x6F2C,0x50,0x01}, // IRYGAIN4_POS1 : +{0x6F2D,0x50,0x01}, // IBYGAIN4_POS1 : +{0x5E12,0x014A,0x02}, // +{0x5E14,0x000D,0x02}, // +{0x0294,0x00,0x01}, // +{0x625F,0x35,0x01}, // CAT_AWB_1 +{0x0282,0x20,0x01}, // AWB_SN1 +{0x5021,0x00,0x01}, // PG_GAIN_SEL : +{0x5022,0x00,0x01}, // PG_WIDTH_SEL : +{0x5023,0x00,0x01}, // PG_MODE_SEL : +{0x5024,0x0000,0x02}, // PG_LEVEL_SEL : +{0x5026,0x00,0x01}, // PG_DATEN_OFF_SEL : +{0x5020,0x00,0x01}, // PGSEL : + +}; + +static const isx012_regset_t isx012_Preview_Return[] = +{ +{0x0282,0x20,0x01}, //AWB_SN1 + +}; + +static const isx012_regset_t isx012_Capture_Start[] = +{ + {0x008A,0x00,0x01}, //OUTFMT_CAP + {0x0084,0x00,0x01}, //SENSMODE_CAP + {0x0087,0x03,0x01}, //FPSTYPE_CAP + {0x0012,0x06,0x01}, //INTCLR0 + {0x0081,0x02,0x01}, //MODESEL + {0x0082,0x01,0x01}, //MONI_REFRESH +}; +#if 0 +static const isx012_regset_t isx012_Preview_Return[] = +{ +{0x0282,0x20,0x01}, //AWB_SN1 +}; +#endif + +static const isx012_regset_t isx012_fps_auto[] = +{ +{0x0308,0x11,0x01}, /* AELINE_MONI_SN1_2 */ +{0x018E,0x0012,0x02}, /* VADJ_SENS_1_2 */ +}; + +static const isx012_regset_t isx012_fps_7fix[] = +{ +{0x0308,0x02,0x01}, /* AELINE_MONI_SN1_2 */ +{0x018E,0x0D59,0x02}, /* VADJ_SENS_1_2 */ +}; + +static const isx012_regset_t isx012_fps_15fix[] = +{ +{0x0308,0x02,0x01}, /* AELINE_MONI_SN1_2 */ +{0x018E,0x041C,0x02}, /* VADJ_SENS_1_2 */ +}; + +static const isx012_regset_t isx012_fps_25fix[] = +{ +{0x0308,0x02,0x01}, /* AELINE_MONI_SN1_2 */ +{0x018E,0x00E1,0x02}, /* VADJ_SENS_1_2 */ +}; + +static const isx012_regset_t isx012_fps_30fix[] = +{ +{0x0308,0x02,0x01}, /* AELINE_MONI_SN1_2 */ +{0x018E,0x0012,0x02}, /* VADJ_SENS_1_2 */ +}; + +static const isx012_regset_t isx012_ae_lock[] = +{ +{0x0282,0x20,0x01}, //AWB_SN1 +}; + +static const isx012_regset_t isx012_ae_unlock[] = +{ +{0x0282,0x20,0x01}, //AWB_SN1 +}; + +static const isx012_regset_t isx012_awb_lock[] = +{ +{0x0282,0x20,0x01}, //AWB_SN1 +}; + +static const isx012_regset_t isx012_awb_unlock[] = +{ +{0x0282,0x20,0x01}, //AWB_SN1 +}; + + +static const isx012_regset_t ISX012_Shading_Nocal[] = +{ +{0x01BC,0x50,0x01}, // CXC OFF SHD OFF +{0xEB00,0x8282,0x02}, //valid_code +{0xEB02,0xFE,0x01}, +{0xEB03,0x84,0x01}, +{0xEB04,0x3F,0x01}, +{0xEB05,0x01,0x01}, +{0xEB06,0x50,0x01}, +{0xEB07,0x08,0x01}, +{0xEB08,0x14,0x01}, +{0xEB09,0xFF,0x01}, +{0xEB0A,0x45,0x01}, +{0xEB0B,0x80,0x01}, +{0xEB0C,0x01,0x01}, +{0xEB0D,0x68,0x01}, +{0xEB0E,0x04,0x01}, +{0xEB0F,0x1A,0x01}, +{0xEB10,0x81,0x01}, +{0xEB11,0x86,0x01}, +{0xEB12,0x3F,0x01}, +{0xEB13,0xE1,0x01}, +{0xEB14,0x4F,0x01}, +{0xEB15,0x00,0x01}, +{0xEB16,0x14,0x01}, +{0xEB17,0x02,0x01}, +{0xEB18,0xC5,0x01}, +{0xEB19,0x7F,0x01}, +{0xEB1A,0x11,0x01}, +{0xEB1B,0x60,0x01}, +{0xEB1C,0x00,0x01}, +{0xEB1D,0x1A,0x01}, +{0xEB1E,0x81,0x01}, +{0xEB1F,0x46,0x01}, +{0xEB20,0xA0,0x01}, +{0xEB21,0x01,0x01}, +{0xEB22,0x48,0x01}, +{0xEB23,0x00,0x01}, +{0xEB24,0x12,0x01}, +{0xEB25,0x81,0x01}, +{0xEB26,0x05,0x01}, +{0xEB27,0x20,0x01}, +{0xEB28,0xF1,0x01}, +{0xEB29,0x4F,0x01}, +{0xEB2A,0x00,0x01}, +{0xEB2B,0x14,0x01}, +{0xEB2C,0x82,0x01}, +{0xEB2D,0x85,0x01}, +{0xEB2E,0x80,0x01}, +{0xEB2F,0x21,0x01}, +{0xEB30,0x60,0x01}, +{0xEB31,0x04,0x01}, +{0xEB32,0x12,0x01}, +{0xEB33,0x81,0x01}, +{0xEB34,0x84,0x01}, +{0xEB35,0xE0,0x01}, +{0xEB36,0x00,0x01}, +{0xEB37,0x28,0x01}, +{0xEB38,0x04,0x01}, +{0xEB39,0x0C,0x01}, +{0xEB3A,0x82,0x01}, +{0xEB3B,0x43,0x01}, +{0xEB3C,0x20,0x01}, +{0xEB3D,0x11,0x01}, +{0xEB3E,0x68,0x01}, +{0xEB3F,0x04,0x01}, +{0xEB40,0x1A,0x01}, +{0xEB41,0x82,0x01}, +{0xEB42,0x83,0x01}, +{0xEB43,0xE0,0x01}, +{0xEB44,0x00,0x01}, +{0xEB45,0x20,0x01}, +{0xEB46,0x00,0x01}, +{0xEB47,0x06,0x01}, +{0xEB48,0xFF,0x01}, +{0xEB49,0x41,0x01}, +{0xEB4A,0x80,0x01}, +{0xEB4B,0x10,0x01}, +{0xEB4C,0x30,0x01}, +{0xEB4D,0x08,0x01}, +{0xEB4E,0x14,0x01}, +{0xEB4F,0x02,0x01}, +{0xEB50,0x45,0x01}, +{0xEB51,0xC0,0x01}, +{0xEB52,0x10,0x01}, +{0xEB53,0x30,0x01}, +{0xEB54,0x04,0x01}, +{0xEB55,0x04,0x01}, +{0xEB56,0x01,0x01}, +{0xEB57,0xC0,0x01}, +{0xEB58,0x3F,0x01}, +{0xEB59,0x10,0x01}, +{0xEB5A,0x10,0x01}, +{0xEB5B,0x04,0x01}, +{0xEB5C,0x0A,0x01}, +{0xEB5D,0x80,0x01}, +{0xEB5E,0x03,0x01}, +{0xEB5F,0xE0,0x01}, +{0xEB60,0x10,0x01}, +{0xEB61,0x28,0x01}, +{0xEB62,0x04,0x01}, +{0xEB63,0x0A,0x01}, +{0xEB64,0x81,0x01}, +{0xEB65,0x01,0x01}, +{0xEB66,0x00,0x01}, +{0xEB67,0x10,0x01}, +{0xEB68,0x00,0x01}, +{0xEB69,0x04,0x01}, +{0xEB6A,0x04,0x01}, +{0xEB6B,0x01,0x01}, +{0xEB6C,0x42,0x01}, +{0xEB6D,0xE0,0x01}, +{0xEB6E,0x10,0x01}, +{0xEB6F,0x38,0x01}, +{0xEB70,0xFC,0x01}, +{0xEB71,0x0D,0x01}, +{0xEB72,0x7F,0x01}, +{0xEB73,0x43,0x01}, +{0xEB74,0x60,0x01}, +{0xEB75,0x00,0x01}, +{0xEB76,0x08,0x01}, +{0xEB77,0x08,0x01}, +{0xEB78,0x02,0x01}, +{0xEB79,0x81,0x01}, +{0xEB7A,0x41,0x01}, +{0xEB7B,0x80,0x01}, +{0xEB7C,0x10,0x01}, +{0xEB7D,0x30,0x01}, +{0xEB7E,0x04,0x01}, +{0xEB7F,0x0C,0x01}, +{0xEB80,0x01,0x01}, +{0xEB81,0x43,0x01}, +{0xEB82,0xC0,0x01}, +{0xEB83,0x20,0x01}, +{0xEB84,0x28,0x01}, +{0xEB85,0x08,0x01}, +{0xEB86,0x06,0x01}, +{0xEB87,0x02,0x01}, +{0xEB88,0xC2,0x01}, +{0xEB89,0xA0,0x01}, +{0xEB8A,0x30,0x01}, +{0xEB8B,0x30,0x01}, +{0xEB8C,0x0C,0x01}, +{0xEB8D,0x12,0x01}, +{0xEB8E,0x83,0x01}, +{0xEB8F,0x84,0x01}, +{0xEB90,0x00,0x01}, +{0xEB91,0x21,0x01}, +{0xEB92,0x40,0x01}, +{0xEB93,0x0C,0x01}, +{0xEB94,0x0C,0x01}, +{0xEB95,0x82,0x01}, +{0xEB96,0x03,0x01}, +{0xEB97,0xC1,0x01}, +{0xEB98,0x40,0x01}, +{0xEB99,0x40,0x01}, +{0xEB9A,0x08,0x01}, +{0xEB9B,0x10,0x01}, +{0xEB9C,0x03,0x01}, +{0xEB9D,0xC4,0x01}, +{0xEB9E,0x00,0x01}, +{0xEB9F,0x21,0x01}, +{0xEBA0,0x38,0x01}, +{0xEBA1,0x08,0x01}, +{0xEBA2,0x0E,0x01}, +{0xEBA3,0x82,0x01}, +{0xEBA4,0xC3,0x01}, +{0xEBA5,0x20,0x01}, +{0xEBA6,0x41,0x01}, +{0xEBA7,0x48,0x01}, +{0xEBA8,0x00,0x01}, +{0xEBA9,0x14,0x01}, +{0xEBAA,0x83,0x01}, +{0xEBAB,0x44,0x01}, +{0xEBAC,0x20,0x01}, +{0xEBAD,0x11,0x01}, +{0xEBAE,0x48,0x01}, +{0xEBAF,0x08,0x01}, +{0xEBB0,0x0E,0x01}, +{0xEBB1,0x82,0x01}, +{0xEBB2,0x83,0x01}, +{0xEBB3,0xE0,0x01}, +{0xEBB4,0x30,0x01}, +{0xEBB5,0x48,0x01}, +{0xEBB6,0x10,0x01}, +{0xEBB7,0x12,0x01}, +{0xEBB8,0x00,0x01}, +{0xEBB9,0xC5,0x01}, +{0xEBBA,0x20,0x01}, +{0xEBBB,0x11,0x01}, +{0xEBBC,0x48,0x01}, +{0xEBBD,0x04,0x01}, +{0xEBBE,0x12,0x01}, +{0xEBBF,0x04,0x01}, +{0xEBC0,0x3B,0x01}, +{0xEBC1,0xC1,0x01}, +{0xEBC2,0x1E,0x01}, +{0xEBC3,0xC8,0x01}, +{0xEBC4,0x0F,0x01}, +{0xEBC5,0xF8,0x01}, +{0xEBC6,0x02,0x01}, +{0xEBC7,0xBB,0x01}, +{0xEBC8,0x60,0x01}, +{0xEBC9,0x0F,0x01}, +{0xEBCA,0xB8,0x01}, +{0xEBCB,0x0F,0x01}, +{0xEBCC,0xEA,0x01}, +{0xEBCD,0x83,0x01}, +{0xEBCE,0x3A,0x01}, +{0xEBCF,0xC1,0x01}, +{0xEBD0,0x4E,0x01}, +{0xEBD1,0xB0,0x01}, +{0xEBD2,0x07,0x01}, +{0xEBD3,0xF2,0x01}, +{0xEBD4,0x03,0x01}, +{0xEBD5,0xBE,0x01}, +{0xEBD6,0xC0,0x01}, +{0xEBD7,0x2E,0x01}, +{0xEBD8,0xD8,0x01}, +{0xEBD9,0x03,0x01}, +{0xEBDA,0xEE,0x01}, +{0xEBDB,0x83,0x01}, +{0xEBDC,0xFA,0x01}, +{0xEBDD,0xA0,0x01}, +{0xEBDE,0x2E,0x01}, +{0xEBDF,0xB0,0x01}, +{0xEBE0,0x0B,0x01}, +{0xEBE1,0xEC,0x01}, +{0xEBE2,0x05,0x01}, +{0xEBE3,0xBD,0x01}, +{0xEBE4,0x60,0x01}, +{0xEBE5,0x2F,0x01}, +{0xEBE6,0xD0,0x01}, +{0xEBE7,0x07,0x01}, +{0xEBE8,0xEC,0x01}, +{0xEBE9,0x02,0x01}, +{0xEBEA,0xBC,0x01}, +{0xEBEB,0x40,0x01}, +{0xEBEC,0x2F,0x01}, +{0xEBED,0xD0,0x01}, +{0xEBEE,0x13,0x01}, +{0xEBEF,0xEE,0x01}, +{0xEBF0,0x84,0x01}, +{0xEBF1,0xBB,0x01}, +{0xEBF2,0x00,0x01}, +{0xEBF3,0x1F,0x01}, +{0xEBF4,0xC8,0x01}, +{0xEBF5,0xFF,0x01}, +{0xEBF6,0xEF,0x01}, +{0xEBF7,0x00,0x01}, +{0xEBF8,0x7D,0x01}, +{0xEBF9,0x60,0x01}, +{0xEBFA,0x2F,0x01}, +{0xEBFB,0xD0,0x01}, +{0xEBFC,0x0B,0x01}, +{0xEBFD,0xF4,0x01}, +{0xEBFE,0x85,0x01}, +{0xEBFF,0x7D,0x01}, +{0xEC00,0x61,0x01}, +{0xEC01,0x0F,0x01}, +{0xEC02,0xC0,0x01}, +{0xEC03,0xFF,0x01}, +{0xEC04,0xF7,0x01}, +{0xEC05,0x7F,0x01}, +{0xEC06,0x3D,0x01}, +{0xEC07,0x40,0x01}, +{0xEC08,0xFF,0x01}, +{0xEC09,0xDF,0x01}, +{0xEC0A,0x07,0x01}, +{0xEC0B,0xFA,0x01}, +{0xEC0C,0x81,0x01}, +{0xEC0D,0x3E,0x01}, +{0xEC0E,0x61,0x01}, +{0xEC0F,0x4F,0x01}, +{0xEC10,0xD8,0x01}, +{0xEC11,0x0B,0x01}, +{0xEC12,0xFC,0x01}, +{0xEC13,0xFE,0x01}, +{0xEC14,0x3D,0x01}, +{0xEC15,0xC0,0x01}, +{0xEC16,0xFF,0x01}, +{0xEC17,0xFF,0x01}, +{0xEC18,0x03,0x01}, +{0xEC19,0xFC,0x01}, +{0xEC1A,0x82,0x01}, +{0xEC1B,0xBE,0x01}, +{0xEC1C,0xA0,0x01}, +{0xEC1D,0x6F,0x01}, +{0xEC1E,0xF8,0x01}, +{0xEC1F,0x1B,0x01}, +{0xEC20,0xFE,0x01}, +{0xEC21,0x83,0x01}, +{0xEC22,0xBF,0x01}, +{0xEC23,0xE0,0x01}, +{0xEC24,0x0F,0x01}, +{0xEC25,0x10,0x01}, +{0xEC26,0x00,0x01}, +{0xEC27,0x00,0x01}, +{0xEC28,0x82,0x01}, +{0xEC29,0xC0,0x01}, +{0xEC2A,0x60,0x01}, +{0xEC2B,0x30,0x01}, +{0xEC2C,0x18,0x01}, +{0xEC2D,0x20,0x01}, +{0xEC2E,0x04,0x01}, +{0xEC2F,0x08,0x01}, +{0xEC30,0x81,0x01}, +{0xEC31,0x21,0x01}, +{0xEC32,0x30,0x01}, +{0xEC33,0x08,0x01}, +{0xEC34,0x08,0x01}, +{0xEC35,0x08,0x01}, +{0xEC36,0x82,0x01}, +{0xEC37,0x01,0x01}, +{0xEC38,0x81,0x01}, +{0xEC39,0x50,0x01}, +{0xEC3A,0x08,0x01}, +{0xEC3B,0x14,0x01}, +{0xEC3C,0x02,0x01}, +{0xEC3D,0x09,0x01}, +{0xEC3E,0x41,0x01}, +{0xEC3F,0x42,0x01}, +{0xEC40,0x70,0x01}, +{0xEC41,0x20,0x01}, +{0xEC42,0x0C,0x01}, +{0xEC43,0x06,0x01}, +{0xEC44,0x84,0x01}, +{0xEC45,0x42,0x01}, +{0xEC46,0xE1,0x01}, +{0xEC47,0x40,0x01}, +{0xEC48,0x38,0x01}, +{0xEC49,0x1C,0x01}, +{0xEC4A,0x0C,0x01}, +{0xEC4B,0x07,0x01}, +{0xEC4C,0x03,0x01}, +{0xEC4D,0xA2,0x01}, +{0xEC4E,0x80,0x01}, +{0xEC4F,0x28,0x01}, +{0xEC50,0x18,0x01}, +{0xEC51,0x10,0x01}, +{0xEC52,0x87,0x01}, +{0xEC53,0x43,0x01}, +{0xEC54,0x61,0x01}, +{0xEC55,0x41,0x01}, +{0xEC56,0x48,0x01}, +{0xEC57,0x14,0x01}, +{0xEC58,0x10,0x01}, +{0xEC59,0x07,0x01}, +{0xEC5A,0xC2,0x01}, +{0xEC5B,0x81,0x01}, +{0xEC5C,0x80,0x01}, +{0xEC5D,0x30,0x01}, +{0xEC5E,0x20,0x01}, +{0xEC5F,0x0C,0x01}, +{0xEC60,0x87,0x01}, +{0xEC61,0x83,0x01}, +{0xEC62,0xC1,0x01}, +{0xEC63,0x40,0x01}, +{0xEC64,0x38,0x01}, +{0xEC65,0x14,0x01}, +{0xEC66,0x0A,0x01}, +{0xEC67,0x07,0x01}, +{0xEC68,0xC3,0x01}, +{0xEC69,0xC1,0x01}, +{0xEC6A,0x70,0x01}, +{0xEC6B,0x30,0x01}, +{0xEC6C,0x20,0x01}, +{0xEC6D,0x0C,0x01}, +{0xEC6E,0x08,0x01}, +{0xEC6F,0xC3,0x01}, +{0xEC70,0xE1,0x01}, +{0xEC71,0x60,0x01}, +{0xEC72,0x30,0x01}, +{0xEC73,0x10,0x01}, +{0xEC74,0x0E,0x01}, +{0xEC75,0x85,0x01}, +{0xEC76,0xC2,0x01}, +{0xEC77,0xC1,0x01}, +{0xEC78,0x70,0x01}, +{0xEC79,0x30,0x01}, +{0xEC7A,0x1C,0x01}, +{0xEC7B,0x0C,0x01}, + +//SHD1(from CO1) +{0xED02,0xE6,0x01}, +{0xED03,0x61,0x01}, +{0xED04,0x92,0x01}, +{0xED05,0x7C,0x01}, +{0xED06,0xBE,0x01}, +{0xED07,0xB4,0x01}, +{0xED08,0x9E,0x01}, +{0xED09,0x2C,0x01}, +{0xED0A,0x75,0x01}, +{0xED0B,0x47,0x01}, +{0xED0C,0x49,0x01}, +{0xED0D,0xD7,0x01}, +{0xED0E,0x61,0x01}, +{0xED0F,0x12,0x01}, +{0xED10,0x76,0x01}, +{0xED11,0xA8,0x01}, +{0xED12,0x34,0x01}, +{0xED13,0x1E,0x01}, +{0xED14,0x31,0x01}, +{0xED15,0xA1,0x01}, +{0xED16,0xC7,0x01}, +{0xED17,0x4C,0x01}, +{0xED18,0xDE,0x01}, +{0xED19,0xC1,0x01}, +{0xED1A,0xD2,0x01}, +{0xED1B,0x77,0x01}, +{0xED1C,0x76,0x01}, +{0xED1D,0x94,0x01}, +{0xED1E,0x9C,0x01}, +{0xED1F,0x10,0x01}, +{0xED20,0xC9,0x01}, +{0xED21,0xC6,0x01}, +{0xED22,0x40,0x01}, +{0xED23,0xA2,0x01}, +{0xED24,0x99,0x01}, +{0xED25,0x8F,0x01}, +{0xED26,0x66,0x01}, +{0xED27,0xDC,0x01}, +{0xED28,0xF3,0x01}, +{0xED29,0x19,0x01}, +{0xED2A,0xFC,0x01}, +{0xED2B,0xB0,0x01}, +{0xED2C,0xA6,0x01}, +{0xED2D,0x41,0x01}, +{0xED2E,0xC1,0x01}, +{0xED2F,0x49,0x01}, +{0xED30,0x91,0x01}, +{0xED31,0x75,0x01}, +{0xED32,0x8C,0x01}, +{0xED33,0x74,0x01}, +{0xED34,0x1C,0x01}, +{0xED35,0x0B,0x01}, +{0xED36,0x91,0x01}, +{0xED37,0x86,0x01}, +{0xED38,0x3D,0x01}, +{0xED39,0x87,0x01}, +{0xED3A,0x39,0x01}, +{0xED3B,0x4E,0x01}, +{0xED3C,0x5C,0x01}, +{0xED3D,0x50,0x01}, +{0xED3E,0x83,0x01}, +{0xED3F,0x16,0x01}, +{0xED40,0xCF,0x01}, +{0xED41,0xBC,0x01}, +{0xED42,0x45,0x01}, +{0xED43,0x35,0x01}, +{0xED44,0x83,0x01}, +{0xED45,0x41,0x01}, +{0xED46,0xCE,0x01}, +{0xED47,0x67,0x01}, +{0xED48,0xE8,0x01}, +{0xED49,0x33,0x01}, +{0xED4A,0x1C,0x01}, +{0xED4B,0x16,0x01}, +{0xED4C,0xC1,0x01}, +{0xED4D,0x86,0x01}, +{0xED4E,0x3E,0x01}, +{0xED4F,0x83,0x01}, +{0xED50,0xC1,0x01}, +{0xED51,0x0D,0x01}, +{0xED52,0x57,0x01}, +{0xED53,0x02,0x01}, +{0xED54,0x23,0x01}, +{0xED55,0x14,0x01}, +{0xED56,0xAE,0x01}, +{0xED57,0xE4,0x01}, +{0xED58,0x44,0x01}, +{0xED59,0x2A,0x01}, +{0xED5A,0x43,0x01}, +{0xED5B,0xF9,0x01}, +{0xED5C,0xCA,0x01}, +{0xED5D,0x56,0x01}, +{0xED5E,0x0C,0x01}, +{0xED5F,0x03,0x01}, +{0xED60,0x98,0x01}, +{0xED61,0xE2,0x01}, +{0xED62,0xA8,0x01}, +{0xED63,0x26,0x01}, +{0xED64,0x41,0x01}, +{0xED65,0x9E,0x01}, +{0xED66,0xC1,0x01}, +{0xED67,0xCE,0x01}, +{0xED68,0x59,0x01}, +{0xED69,0x1C,0x01}, +{0xED6A,0xB3,0x01}, +{0xED6B,0x93,0x01}, +{0xED6C,0xA7,0x01}, +{0xED6D,0x74,0x01}, +{0xED6E,0x04,0x01}, +{0xED6F,0x25,0x01}, +{0xED70,0x13,0x01}, +{0xED71,0xD9,0x01}, +{0xED72,0xC8,0x01}, +{0xED73,0x47,0x01}, +{0xED74,0x54,0x01}, +{0xED75,0xD2,0x01}, +{0xED76,0x93,0x01}, +{0xED77,0xAA,0x01}, +{0xED78,0x98,0x01}, +{0xED79,0xE5,0x01}, +{0xED7A,0x32,0x01}, +{0xED7B,0x9A,0x01}, +{0xED7C,0x29,0x01}, +{0xED7D,0xCF,0x01}, +{0xED7E,0x64,0x01}, +{0xED7F,0x8E,0x01}, +{0xED80,0x73,0x01}, +{0xED81,0x95,0x01}, +{0xED82,0xBB,0x01}, +{0xED83,0xA4,0x01}, +{0xED84,0xA4,0x01}, +{0xED85,0x26,0x01}, +{0xED86,0x0A,0x01}, +{0xED87,0x59,0x01}, +{0xED88,0x08,0x01}, +{0xED89,0x40,0x01}, +{0xED8A,0x00,0x01}, +{0xED8B,0xC2,0x01}, +{0xED8C,0x10,0x01}, +{0xED8D,0x88,0x01}, +{0xED8E,0xB0,0x01}, +{0xED8F,0x84,0x01}, +{0xED90,0x27,0x01}, +{0xED91,0x59,0x01}, +{0xED92,0xF1,0x01}, +{0xED93,0x0B,0x01}, +{0xED94,0x64,0x01}, +{0xED95,0xA2,0x01}, +{0xED96,0x43,0x01}, +{0xED97,0x99,0x01}, +{0xED98,0xE4,0x01}, +{0xED99,0x68,0x01}, +{0xED9A,0x25,0x01}, +{0xED9B,0x2F,0x01}, +{0xED9C,0x2B,0x01}, +{0xED9D,0xB1,0x01}, +{0xED9E,0xC9,0x01}, +{0xED9F,0x42,0x01}, +{0xEDA0,0x18,0x01}, +{0xEDA1,0x32,0x01}, +{0xEDA2,0x90,0x01}, +{0xEDA3,0x80,0x01}, +{0xEDA4,0x3C,0x01}, +{0xEDA5,0x24,0x01}, +{0xEDA6,0x22,0x01}, +{0xEDA7,0x2F,0x01}, +{0xEDA8,0xF1,0x01}, +{0xEDA9,0x09,0x01}, +{0xEDAA,0x57,0x01}, +{0xEDAB,0x00,0x01}, +{0xEDAC,0x53,0x01}, +{0xEDAD,0x99,0x01}, +{0xEDAE,0xEA,0x01}, +{0xEDAF,0x90,0x01}, +{0xEDB0,0xC6,0x01}, +{0xEDB1,0x3B,0x01}, +{0xEDB2,0x6D,0x01}, +{0xEDB3,0x99,0x01}, +{0xEDB4,0x4C,0x01}, +{0xEDB5,0x50,0x01}, +{0xEDB6,0xA4,0x01}, +{0xEDB7,0x32,0x01}, +{0xEDB8,0x12,0x01}, +{0xEDB9,0x94,0x01}, +{0xEDBA,0x64,0x01}, +{0xEDBB,0xA4,0x01}, +{0xEDBC,0x23,0x01}, +{0xEDBD,0x25,0x01}, +{0xEDBE,0x71,0x01}, +{0xEDBF,0x49,0x01}, +{0xEDC0,0x51,0x01}, +{0xEDC1,0xB2,0x01}, +{0xEDC2,0x02,0x01}, +{0xEDC3,0x17,0x01}, +{0xEDC4,0xCD,0x01}, +{0xEDC5,0x98,0x01}, +{0xEDC6,0x86,0x01}, +{0xEDC7,0x3D,0x01}, +{0xEDC8,0xBC,0x01}, +{0xEDC9,0x01,0x01}, +{0xEDCA,0x50,0x01}, +{0xEDCB,0x63,0x01}, +{0xEDCC,0x80,0x01}, +{0xEDCD,0x63,0x01}, +{0xEDCE,0x16,0x01}, +{0xEDCF,0xC3,0x01}, +{0xEDD0,0x2C,0x01}, +{0xEDD1,0x25,0x01}, +{0xEDD2,0x2C,0x01}, +{0xEDD3,0x43,0x01}, +{0xEDD4,0xB1,0x01}, +{0xEDD5,0x4A,0x01}, +{0xEDD6,0x53,0x01}, +{0xEDD7,0xCC,0x01}, +{0xEDD8,0x82,0x01}, +{0xEDD9,0x96,0x01}, +{0xEDDA,0xC7,0x01}, +{0xEDDB,0x40,0x01}, +{0xEDDC,0xA6,0x01}, +{0xEDDD,0x39,0x01}, +{0xEDDE,0xBE,0x01}, +{0xEDDF,0x91,0x01}, +{0xEDE0,0xD0,0x01}, +{0xEDE1,0x75,0x01}, +{0xEDE2,0x54,0x01}, +{0xEDE3,0x34,0x01}, +{0xEDE4,0x1B,0x01}, +{0xEDE5,0xFC,0x01}, +{0xEDE6,0x4C,0x01}, +{0xEDE7,0x46,0x01}, +{0xEDE8,0x39,0x01}, +{0xEDE9,0x7D,0x01}, +{0xEDEA,0x71,0x01}, +{0xEDEB,0x8D,0x01}, +{0xEDEC,0x5D,0x01}, +{0xEDED,0x46,0x01}, +{0xEDEE,0xE3,0x01}, +{0xEDEF,0x17,0x01}, +{0xEDF0,0xD9,0x01}, +{0xEDF1,0x50,0x01}, +{0xEDF2,0x86,0x01}, +{0xEDF3,0x3A,0x01}, +{0xEDF4,0xB3,0x01}, +{0xEDF5,0x09,0x01}, +{0xEDF6,0x50,0x01}, +{0xEDF7,0x76,0x01}, +{0xEDF8,0x6A,0x01}, +{0xEDF9,0xF4,0x01}, +{0xEDFA,0x1E,0x01}, +{0xEDFB,0x25,0x01}, +{0xEDFC,0x61,0x01}, +{0xEDFD,0x67,0x01}, +{0xEDFE,0x45,0x01}, +{0xEDFF,0xC0,0x01}, +{0xEE00,0x69,0x01}, +{0xEE01,0xD0,0x01}, +{0xEE02,0x6B,0x01}, +{0xEE03,0xF6,0x01}, +{0xEE04,0x93,0x01}, +{0xEE05,0x9A,0x01}, +{0xEE06,0xFA,0x01}, +{0xEE07,0xB8,0x01}, +{0xEE08,0x26,0x01}, +{0xEE09,0x40,0x01}, +{0xEE0A,0xC0,0x01}, +{0xEE0B,0xB9,0x01}, +{0xEE0C,0xD0,0x01}, +{0xEE0D,0x75,0x01}, +{0xEE0E,0x6E,0x01}, +{0xEE0F,0xE4,0x01}, +{0xEE10,0x9E,0x01}, +{0xEE11,0x2D,0x01}, +{0xEE12,0xE1,0x01}, +{0xEE13,0xA7,0x01}, +{0xEE14,0x49,0x01}, +{0xEE15,0xFD,0x01}, +{0xEE16,0xB9,0x01}, +{0xEE17,0x52,0x01}, +{0xEE18,0x7C,0x01}, +{0xEE19,0x98,0x01}, +{0xEE1A,0x64,0x01}, +{0xEE1B,0x1E,0x01}, +{0xEE1C,0x22,0x01}, +{0xEE1D,0x89,0x01}, +{0xEE1E,0xA7,0x01}, +{0xEE1F,0x48,0x01}, +{0xEE20,0xE4,0x01}, +{0xEE21,0x49,0x01}, +{0xEE22,0x12,0x01}, +{0xEE23,0x7D,0x01}, +{0xEE24,0xB4,0x01}, +{0xEE25,0xB4,0x01}, +{0xEE26,0x1F,0x01}, +{0xEE27,0x31,0x01}, +{0xEE28,0xC5,0x01}, +{0xEE29,0x47,0x01}, +{0xEE2A,0x4B,0x01}, +{0xEE2B,0xC2,0x01}, +{0xEE2C,0x19,0x01}, +{0xEE2D,0x0F,0x01}, +{0xEE2E,0x73,0x01}, +{0xEE2F,0xE2,0x01}, +{0xEE30,0x13,0x01}, +{0xEE31,0x1C,0x01}, +{0xEE32,0xF5,0x01}, +{0xEE33,0xE0,0x01}, +{0xEE34,0xC6,0x01}, +{0xEE35,0x3B,0x01}, +{0xEE36,0xB6,0x01}, +{0xEE37,0xB1,0x01}, +{0xEE38,0xCE,0x01}, +{0xEE39,0x6D,0x01}, +{0xEE3A,0xB8,0x01}, +{0xEE3B,0xF3,0x01}, +{0xEE3C,0x9B,0x01}, +{0xEE3D,0xF2,0x01}, +{0xEE3E,0x18,0x01}, +{0xEE3F,0x27,0x01}, +{0xEE40,0x3D,0x01}, +{0xEE41,0xBF,0x01}, +{0xEE42,0xE9,0x01}, +{0xEE43,0xCE,0x01}, +{0xEE44,0x6E,0x01}, +{0xEE45,0xBA,0x01}, +{0xEE46,0x83,0x01}, +{0xEE47,0x9A,0x01}, +{0xEE48,0xE4,0x01}, +{0xEE49,0x50,0x01}, +{0xEE4A,0x66,0x01}, +{0xEE4B,0x36,0x01}, +{0xEE4C,0x8A,0x01}, +{0xEE4D,0x29,0x01}, +{0xEE4E,0x4D,0x01}, +{0xEE4F,0x61,0x01}, +{0xEE50,0x3A,0x01}, +{0xEE51,0xA3,0x01}, +{0xEE52,0x18,0x01}, +{0xEE53,0xD2,0x01}, +{0xEE54,0x50,0x01}, +{0xEE55,0x26,0x01}, +{0xEE56,0x36,0x01}, +{0xEE57,0xA8,0x01}, +{0xEE58,0x21,0x01}, +{0xEE59,0xCE,0x01}, +{0xEE5A,0x6E,0x01}, +{0xEE5B,0xB2,0x01}, +{0xEE5C,0x03,0x01}, +{0xEE5D,0x9A,0x01}, +{0xEE5E,0xE0,0x01}, +{0xEE5F,0x1C,0x01}, +{0xEE60,0x46,0x01}, +{0xEE61,0x34,0x01}, +{0xEE62,0x72,0x01}, +{0xEE63,0x41,0x01}, +{0xEE64,0x8C,0x01}, +{0xEE65,0x58,0x01}, +{0xEE66,0xE8,0x01}, +{0xEE67,0xC2,0x01}, +{0xEE68,0x95,0x01}, +{0xEE69,0xB5,0x01}, +{0xEE6A,0x88,0x01}, +{0xEE6B,0x65,0x01}, +{0xEE6C,0x2E,0x01}, +{0xEE6D,0x72,0x01}, +{0xEE6E,0x39,0x01}, +{0xEE6F,0x8C,0x01}, +{0xEE70,0x62,0x01}, +{0xEE71,0x48,0x01}, +{0xEE72,0x83,0x01}, +{0xEE73,0x1A,0x01}, +{0xEE74,0xE4,0x01}, +{0xEE75,0x28,0x01}, +{0xEE76,0x06,0x01}, +{0xEE77,0x35,0x01}, +{0xEE78,0x6A,0x01}, +{0xEE79,0xF9,0x01}, +{0xEE7A,0x4B,0x01}, +{0xEE7B,0x53,0x01}, +{0xEE7C,0xB8,0x01}, +{0xEE7D,0x92,0x01}, +{0xEE7E,0x13,0x01}, +{0xEE7F,0xA2,0x01}, +{0xEE80,0xCC,0x01}, +{0xEE81,0x64,0x01}, +{0xEE82,0x27,0x01}, +{0xEE83,0x3B,0x01}, +{0xEE84,0x29,0x01}, +{0xEE85,0x0A,0x01}, +{0xEE86,0x54,0x01}, +{0xEE87,0xBC,0x01}, +{0xEE88,0xF2,0x01}, +{0xEE89,0x96,0x01}, +{0xEE8A,0xC1,0x01}, +{0xEE8B,0x40,0x01}, +{0xEE8C,0xA6,0x01}, +{0xEE8D,0x35,0x01}, +{0xEE8E,0x7A,0x01}, +{0xEE8F,0xB1,0x01}, +{0xEE90,0x8C,0x01}, +{0xEE91,0x54,0x01}, +{0xEE92,0xC8,0x01}, +{0xEE93,0xF2,0x01}, +{0xEE94,0x92,0x01}, +{0xEE95,0x9D,0x01}, +{0xEE96,0x64,0x01}, +{0xEE97,0xE4,0x01}, +{0xEE98,0x23,0x01}, +{0xEE99,0x13,0x01}, +{0xEE9A,0xA9,0x01}, +{0xEE9B,0x48,0x01}, +{0xEE9C,0x47,0x01}, +{0xEE9D,0x40,0x01}, +{0xEE9E,0x42,0x01}, +{0xEE9F,0x13,0x01}, +{0xEEA0,0x9F,0x01}, +{0xEEA1,0x58,0x01}, +{0xEEA2,0xE5,0x01}, +{0xEEA3,0x2C,0x01}, +{0xEEA4,0x7F,0x01}, +{0xEEA5,0xD9,0x01}, +{0xEEA6,0x8C,0x01}, +{0xEEA7,0x5B,0x01}, +{0xEEA8,0x12,0x01}, +{0xEEA9,0x43,0x01}, +{0xEEAA,0x14,0x01}, +{0xEEAB,0xAA,0x01}, +{0xEEAC,0x80,0x01}, +{0xEEAD,0x04,0x01}, +{0xEEAE,0x25,0x01}, +{0xEEAF,0x06,0x01}, +{0xEEB0,0x51,0x01}, +{0xEEB1,0x08,0x01}, +{0xEEB2,0x40,0x01}, +{0xEEB3,0x00,0x01}, +{0xEEB4,0xB2,0x01}, +{0xEEB5,0x10,0x01}, +{0xEEB6,0x86,0x01}, +{0xEEB7,0x98,0x01}, +{0xEEB8,0x64,0x01}, +{0xEEB9,0x25,0x01}, +{0xEEBA,0x4A,0x01}, +{0xEEBB,0xB9,0x01}, +{0xEEBC,0x0A,0x01}, +{0xEEBD,0x5D,0x01}, +{0xEEBE,0x1C,0x01}, +{0xEEBF,0x13,0x01}, +{0xEEC0,0x97,0x01}, +{0xEEC1,0xC4,0x01}, +{0xEEC2,0x18,0x01}, +{0xEEC3,0x85,0x01}, +{0xEEC4,0x2A,0x01}, +{0xEEC5,0x21,0x01}, +{0xEEC6,0x41,0x01}, +{0xEEC7,0xC9,0x01}, +{0xEEC8,0x41,0x01}, +{0xEEC9,0x12,0x01}, +{0xEECA,0x02,0x01}, +{0xEECB,0x10,0x01}, +{0xEECC,0x80,0x01}, +{0xEECD,0x2C,0x01}, +{0xEECE,0x64,0x01}, +{0xEECF,0x21,0x01}, +{0xEED0,0x27,0x01}, +{0xEED1,0x61,0x01}, +{0xEED2,0xC9,0x01}, +{0xEED3,0x52,0x01}, +{0xEED4,0xB0,0x01}, +{0xEED5,0x42,0x01}, +{0xEED6,0x17,0x01}, +{0xEED7,0xC8,0x01}, +{0xEED8,0x04,0x01}, +{0xEED9,0xE6,0x01}, +{0xEEDA,0x32,0x01}, +{0xEEDB,0x58,0x01}, +{0xEEDC,0x29,0x01}, +{0xEEDD,0xCB,0x01}, +{0xEEDE,0x4C,0x01}, +{0xEEDF,0x74,0x01}, +{0xEEE0,0x92,0x01}, +{0xEEE1,0x91,0x01}, +{0xEEE2,0x8E,0x01}, +{0xEEE3,0x48,0x01}, +{0xEEE4,0x84,0x01}, +{0xEEE5,0x22,0x01}, +{0xEEE6,0x1D,0x01}, +{0xEEE7,0x01,0x01}, +{0xEEE8,0xC9,0x01}, +{0xEEE9,0x4D,0x01}, +{0xEEEA,0x7E,0x01}, +{0xEEEB,0x82,0x01}, +{0xEEEC,0x15,0x01}, +{0xEEED,0xB5,0x01}, +{0xEEEE,0x04,0x01}, +{0xEEEF,0xE6,0x01}, +{0xEEF0,0x33,0x01}, +{0xEEF1,0x99,0x01}, +{0xEEF2,0x69,0x01}, +{0xEEF3,0x0D,0x01}, +{0xEEF4,0x5D,0x01}, +{0xEEF5,0x06,0x01}, +{0xEEF6,0x33,0x01}, +{0xEEF7,0x15,0x01}, +{0xEEF8,0xAF,0x01}, +{0xEEF9,0xEC,0x01}, +{0xEEFA,0xA4,0x01}, +{0xEEFB,0x28,0x01}, +{0xEEFC,0x35,0x01}, +{0xEEFD,0xE9,0x01}, +{0xEEFE,0x09,0x01}, +{0xEEFF,0x4F,0x01}, +{0xEF00,0x8E,0x01}, +{0xEF01,0x02,0x01}, +{0xEF02,0x95,0x01}, +{0xEF03,0xB1,0x01}, +{0xEF04,0xC4,0x01}, +{0xEF05,0x25,0x01}, +{0xEF06,0x31,0x01}, +{0xEF07,0x94,0x01}, +{0xEF08,0xB1,0x01}, +{0xEF09,0x4D,0x01}, +{0xEF0A,0x6C,0x01}, +{0xEF0B,0x94,0x01}, +{0xEF0C,0x43,0x01}, +{0xEF0D,0x99,0x01}, +{0xEF0E,0xD4,0x01}, +{0xEF0F,0xEC,0x01}, +{0xEF10,0xC5,0x01}, +{0xEF11,0x31,0x01}, +{0xEF12,0x69,0x01}, +{0xEF13,0xC9,0x01}, +{0xEF14,0x0B,0x01}, +{0xEF15,0x58,0x01}, +{0xEF16,0xE6,0x01}, +{0xEF17,0x52,0x01}, +{0xEF18,0x16,0x01}, +{0xEF19,0xBE,0x01}, +{0xEF1A,0xD4,0x01}, +{0xEF1B,0x45,0x01}, +{0xEF1C,0x32,0x01}, +{0xEF1D,0x8E,0x01}, +{0xEF1E,0x79,0x01}, +{0xEF1F,0x4D,0x01}, +{0xEF20,0x6A,0x01}, +{0xEF21,0xA4,0x01}, +{0xEF22,0x83,0x01}, +{0xEF23,0x1C,0x01}, +{0xEF24,0xF2,0x01}, +{0xEF25,0xDC,0x01}, +{0xEF26,0x26,0x01}, +{0xEF27,0x3A,0x01}, +{0xEF28,0xA3,0x01}, +{0xEF29,0xE1,0x01}, +{0xEF2A,0x4D,0x01}, +{0xEF2B,0x65,0x01}, +{0xEF2C,0x5C,0x01}, +{0xEF2D,0xC3,0x01}, +{0xEF2E,0x98,0x01}, +{0xEF2F,0xD4,0x01}, +{0xEF30,0x3C,0x01}, +{0xEF31,0xE6,0x01}, +{0xEF32,0x35,0x01}, +{0xEF33,0x9D,0x01}, +{0xEF34,0x09,0x01}, +{0xEF35,0x8E,0x01}, +{0xEF36,0x6B,0x01}, +{0xEF37,0xAC,0x01}, +{0xEF38,0xE3,0x01}, +{0xEF39,0x9B,0x01}, +{0xEF3A,0xF4,0x01}, +{0xEF3B,0x34,0x01}, +{0xEF3C,0x07,0x01}, +{0xEF3D,0x3E,0x01}, +{0xEF3E,0xDA,0x01}, +{0xEF3F,0xC1,0x01}, +{0xEF40,0x8F,0x01}, +{0xEF41,0x74,0x01}, +{0xEF42,0xEA,0x01}, +{0xEF43,0x13,0x01}, +{0xEF44,0x9C,0x01}, +{0xEF45,0xF4,0x01}, +{0xEF46,0xF0,0x01}, +{0xEF47,0xA6,0x01}, +{0xEF48,0x3C,0x01}, +{0xEF49,0xC0,0x01}, +{0xEF4A,0x49,0x01}, +{0xEF4B,0x0F,0x01}, +{0xEF4C,0x72,0x01}, +{0xEF4D,0xEA,0x01}, +{0xEF4E,0xD3,0x01}, +{0xEF4F,0x9C,0x01}, +{0xEF50,0xFE,0x01}, +{0xEF51,0x04,0x01}, +{0xEF52,0xA7,0x01}, +{0xEF53,0x3D,0x01}, + +//SHD2 CW+TL84 33:66 + +{0xED00,0x9191,0x02},// +{0xEF54,0x28,0x01}, +{0xEF55,0xC2,0x01}, +{0xEF56,0x11,0x01}, +{0xEF57,0x8C,0x01}, +{0xEF58,0x46,0x01}, +{0xEF59,0x34,0x01}, +{0xEF5A,0xA2,0x01}, +{0xEF5B,0x12,0x01}, +{0xEF5C,0xCD,0x01}, +{0xEF5D,0x08,0x01}, +{0xEF5E,0x47,0x01}, +{0xEF5F,0x27,0x01}, +{0xEF60,0xAA,0x01}, +{0xEF61,0x10,0x01}, +{0xEF62,0x7F,0x01}, +{0xEF63,0xC2,0x01}, +{0xEF64,0xF3,0x01}, +{0xEF65,0x1C,0x01}, +{0xEF66,0xE4,0x01}, +{0xEF67,0x40,0x01}, +{0xEF68,0x27,0x01}, +{0xEF69,0x3C,0x01}, +{0xEF6A,0xFB,0x01}, +{0xEF6B,0xA1,0x01}, +{0xEF6C,0x90,0x01}, +{0xEF6D,0x7C,0x01}, +{0xEF6E,0x92,0x01}, +{0xEF6F,0x63,0x01}, +{0xEF70,0x9A,0x01}, +{0xEF71,0xC5,0x01}, +{0xEF72,0x0C,0x01}, +{0xEF73,0x66,0x01}, +{0xEF74,0x31,0x01}, +{0xEF75,0xA4,0x01}, +{0xEF76,0x49,0x01}, +{0xEF77,0x0E,0x01}, +{0xEF78,0x7F,0x01}, +{0xEF79,0xA0,0x01}, +{0xEF7A,0xB3,0x01}, +{0xEF7B,0x19,0x01}, +{0xEF7C,0xB6,0x01}, +{0xEF7D,0x34,0x01}, +{0xEF7E,0x85,0x01}, +{0xEF7F,0x28,0x01}, +{0xEF80,0x4D,0x01}, +{0xEF81,0x61,0x01}, +{0xEF82,0x0B,0x01}, +{0xEF83,0x68,0x01}, +{0xEF84,0xB6,0x01}, +{0xEF85,0x73,0x01}, +{0xEF86,0x9B,0x01}, +{0xEF87,0xBB,0x01}, +{0xEF88,0x0C,0x01}, +{0xEF89,0x45,0x01}, +{0xEF8A,0x24,0x01}, +{0xEF8B,0x17,0x01}, +{0xEF8C,0x11,0x01}, +{0xEF8D,0x49,0x01}, +{0xEF8E,0x51,0x01}, +{0xEF8F,0xF4,0x01}, +{0xEF90,0xC2,0x01}, +{0xEF91,0x1B,0x01}, +{0xEF92,0xD4,0x01}, +{0xEF93,0x94,0x01}, +{0xEF94,0xC5,0x01}, +{0xEF95,0x25,0x01}, +{0xEF96,0x0B,0x01}, +{0xEF97,0x01,0x01}, +{0xEF98,0x48,0x01}, +{0xEF99,0x43,0x01}, +{0xEF9A,0x62,0x01}, +{0xEF9B,0x62,0x01}, +{0xEF9C,0x96,0x01}, +{0xEF9D,0xD5,0x01}, +{0xEF9E,0xA4,0x01}, +{0xEF9F,0xC6,0x01}, +{0xEFA0,0x2C,0x01}, +{0xEFA1,0x2F,0x01}, +{0xEFA2,0x51,0x01}, +{0xEFA3,0x48,0x01}, +{0xEFA4,0x40,0x01}, +{0xEFA5,0x1C,0x01}, +{0xEFA6,0x22,0x01}, +{0xEFA7,0x13,0x01}, +{0xEFA8,0xB4,0x01}, +{0xEFA9,0xC0,0x01}, +{0xEFAA,0x86,0x01}, +{0xEFAB,0x37,0x01}, +{0xEFAC,0x7B,0x01}, +{0xEFAD,0x29,0x01}, +{0xEFAE,0x8A,0x01}, +{0xEFAF,0x48,0x01}, +{0xEFB0,0x30,0x01}, +{0xEFB1,0x52,0x01}, +{0xEFB2,0x12,0x01}, +{0xEFB3,0xA4,0x01}, +{0xEFB4,0xF4,0x01}, +{0xEFB5,0x25,0x01}, +{0xEFB6,0x38,0x01}, +{0xEFB7,0xD9,0x01}, +{0xEFB8,0x01,0x01}, +{0xEFB9,0xCD,0x01}, +{0xEFBA,0x5B,0x01}, +{0xEFBB,0xA0,0x01}, +{0xEFBC,0x72,0x01}, +{0xEFBD,0x14,0x01}, +{0xEFBE,0xA9,0x01}, +{0xEFBF,0xCC,0x01}, +{0xEFC0,0xC5,0x01}, +{0xEFC1,0x34,0x01}, +{0xEFC2,0xE3,0x01}, +{0xEFC3,0xF1,0x01}, +{0xEFC4,0x0F,0x01}, +{0xEFC5,0x74,0x01}, +{0xEFC6,0x50,0x01}, +{0xEFC7,0xF3,0x01}, +{0xEFC8,0x98,0x01}, +{0xEFC9,0xC2,0x01}, +{0xEFCA,0x40,0x01}, +{0xEFCB,0x86,0x01}, +{0xEFCC,0x35,0x01}, +{0xEFCD,0xD4,0x01}, +{0xEFCE,0x29,0x01}, +{0xEFCF,0xD0,0x01}, +{0xEFD0,0x86,0x01}, +{0xEFD1,0xFE,0x01}, +{0xEFD2,0x23,0x01}, +{0xEFD3,0x9E,0x01}, +{0xEFD4,0xE8,0x01}, +{0xEFD5,0x28,0x01}, +{0xEFD6,0x87,0x01}, +{0xEFD7,0x3A,0x01}, +{0xEFD8,0xE7,0x01}, +{0xEFD9,0x21,0x01}, +{0xEFDA,0x10,0x01}, +{0xEFDB,0x89,0x01}, +{0xEFDC,0x3E,0x01}, +{0xEFDD,0x64,0x01}, +{0xEFDE,0xA2,0x01}, +{0xEFDF,0x0D,0x01}, +{0xEFE0,0x41,0x01}, +{0xEFE1,0xC8,0x01}, +{0xEFE2,0x41,0x01}, +{0xEFE3,0x14,0x01}, +{0xEFE4,0x02,0x01}, +{0xEFE5,0x11,0x01}, +{0xEFE6,0x8A,0x01}, +{0xEFE7,0x4C,0x01}, +{0xEFE8,0x04,0x01}, +{0xEFE9,0x00,0x01}, +{0xEFEA,0x00,0x01}, +{0xEFEB,0x00,0x01}, +{0xEFEC,0x00,0x01}, +{0xEFED,0x00,0x01}, + + +//SHD3 D65+TL84 C01// +{0xED00,0x9191,0x02},// +{0xEFEE,0x12,0x01}, +{0xEFEF,0x42,0x01}, +{0xEFF0,0x51,0x01}, +{0xEFF1,0x89,0x01}, +{0xEFF2,0x38,0x01}, +{0xEFF3,0xD4,0x01}, +{0xEFF4,0x21,0x01}, +{0xEFF5,0x10,0x01}, +{0xEFF6,0xAD,0x01}, +{0xEFF7,0xA8,0x01}, +{0xEFF8,0x45,0x01}, +{0xEFF9,0x18,0x01}, +{0xEFFA,0x4A,0x01}, +{0xEFFB,0x50,0x01}, +{0xEFFC,0x7D,0x01}, +{0xEFFD,0xBA,0x01}, +{0xEFFE,0xD3,0x01}, +{0xEFFF,0x1C,0x01}, +{0xF000,0xE4,0x01}, +{0xF001,0x40,0x01}, +{0xF002,0x27,0x01}, +{0xF003,0x3C,0x01}, +{0xF004,0xF8,0x01}, +{0xF005,0x69,0x01}, +{0xF006,0x10,0x01}, +{0xF007,0x7B,0x01}, +{0xF008,0x8E,0x01}, +{0xF009,0x63,0x01}, +{0xF00A,0x1A,0x01}, +{0xF00B,0xC6,0x01}, +{0xF00C,0x10,0x01}, +{0xF00D,0xA6,0x01}, +{0xF00E,0x31,0x01}, +{0xF00F,0xA6,0x01}, +{0xF010,0x59,0x01}, +{0xF011,0x8E,0x01}, +{0xF012,0x7E,0x01}, +{0xF013,0x9A,0x01}, +{0xF014,0xB3,0x01}, +{0xF015,0x19,0x01}, +{0xF016,0xB6,0x01}, +{0xF017,0x38,0x01}, +{0xF018,0xA5,0x01}, +{0xF019,0x28,0x01}, +{0xF01A,0x4F,0x01}, +{0xF01B,0x79,0x01}, +{0xF01C,0xCB,0x01}, +{0xF01D,0x68,0x01}, +{0xF01E,0xBA,0x01}, +{0xF01F,0x53,0x01}, +{0xF020,0x9B,0x01}, +{0xF021,0xBB,0x01}, +{0xF022,0x0C,0x01}, +{0xF023,0x65,0x01}, +{0xF024,0x24,0x01}, +{0xF025,0x17,0x01}, +{0xF026,0x21,0x01}, +{0xF027,0xC9,0x01}, +{0xF028,0x51,0x01}, +{0xF029,0xFC,0x01}, +{0xF02A,0xF2,0x01}, +{0xF02B,0x9B,0x01}, +{0xF02C,0xD3,0x01}, +{0xF02D,0x94,0x01}, +{0xF02E,0xC5,0x01}, +{0xF02F,0x25,0x01}, +{0xF030,0x0A,0x01}, +{0xF031,0x01,0x01}, +{0xF032,0x48,0x01}, +{0xF033,0x43,0x01}, +{0xF034,0x66,0x01}, +{0xF035,0x92,0x01}, +{0xF036,0x96,0x01}, +{0xF037,0xD7,0x01}, +{0xF038,0xA0,0x01}, +{0xF039,0xE6,0x01}, +{0xF03A,0x2C,0x01}, +{0xF03B,0x2F,0x01}, +{0xF03C,0x51,0x01}, +{0xF03D,0x48,0x01}, +{0xF03E,0x40,0x01}, +{0xF03F,0x1E,0x01}, +{0xF040,0x42,0x01}, +{0xF041,0x93,0x01}, +{0xF042,0xB5,0x01}, +{0xF043,0xCC,0x01}, +{0xF044,0x46,0x01}, +{0xF045,0x37,0x01}, +{0xF046,0x7C,0x01}, +{0xF047,0x29,0x01}, +{0xF048,0x8A,0x01}, +{0xF049,0x48,0x01}, +{0xF04A,0x32,0x01}, +{0xF04B,0x72,0x01}, +{0xF04C,0x12,0x01}, +{0xF04D,0xA5,0x01}, +{0xF04E,0x00,0x01}, +{0xF04F,0xA6,0x01}, +{0xF050,0x38,0x01}, +{0xF051,0xD7,0x01}, +{0xF052,0x01,0x01}, +{0xF053,0x0D,0x01}, +{0xF054,0x5C,0x01}, +{0xF055,0xA2,0x01}, +{0xF056,0x82,0x01}, +{0xF057,0x94,0x01}, +{0xF058,0xAA,0x01}, +{0xF059,0xD8,0x01}, +{0xF05A,0x45,0x01}, +{0xF05B,0x35,0x01}, +{0xF05C,0xE5,0x01}, +{0xF05D,0xC9,0x01}, +{0xF05E,0xCF,0x01}, +{0xF05F,0x73,0x01}, +{0xF060,0x50,0x01}, +{0xF061,0x03,0x01}, +{0xF062,0x99,0x01}, +{0xF063,0xC3,0x01}, +{0xF064,0x4C,0x01}, +{0xF065,0xE6,0x01}, +{0xF066,0x35,0x01}, +{0xF067,0xD7,0x01}, +{0xF068,0x21,0x01}, +{0xF069,0x10,0x01}, +{0xF06A,0x84,0x01}, +{0xF06B,0xF2,0x01}, +{0xF06C,0x03,0x01}, +{0xF06D,0x9E,0x01}, +{0xF06E,0xE8,0x01}, +{0xF06F,0x2C,0x01}, +{0xF070,0xA7,0x01}, +{0xF071,0x3A,0x01}, +{0xF072,0xE8,0x01}, +{0xF073,0x11,0x01}, +{0xF074,0x90,0x01}, +{0xF075,0x87,0x01}, +{0xF076,0x18,0x01}, +{0xF077,0x94,0x01}, +{0xF078,0x21,0x01}, +{0xF079,0x09,0x01}, +{0xF07A,0x2D,0x01}, +{0xF07B,0x68,0x01}, +{0xF07C,0x41,0x01}, +{0xF07D,0x11,0x01}, +{0xF07E,0xDA,0x01}, +{0xF07F,0x10,0x01}, +{0xF080,0x88,0x01}, +{0xF081,0x2A,0x01}, +{0xF082,0x04,0x01}, +{0xF083,0x00,0x01}, +{0xF084,0x00,0x01}, +{0xF085,0x00,0x01}, +{0xF086,0x00,0x01}, +{0xF087,0x00,0x01}, +{0xF088,0xBE,0x01}, +{0xF089,0x51,0x01}, +{0xF08A,0x4E,0x01}, +{0xF08B,0x6F,0x01}, +{0xF08C,0x6C,0x01}, +{0xF08D,0x43,0x01}, +{0xF08E,0x1B,0x01}, +{0xF08F,0xDA,0x01}, +{0xF090,0xEC,0x01}, +{0xF091,0x46,0x01}, +{0xF092,0x38,0x01}, +{0xF093,0xBB,0x01}, +{0xF094,0xC1,0x01}, +{0xF095,0xCD,0x01}, +{0xF096,0x69,0x01}, +{0xF097,0x26,0x01}, +{0xF098,0x93,0x01}, +{0xF099,0x98,0x01}, +{0xF09A,0xC1,0x01}, +{0xF09B,0x20,0x01}, +{0xF09C,0x26,0x01}, +{0xF09D,0x32,0x01}, +{0xF09E,0xA5,0x01}, +{0xF09F,0xB1,0x01}, +{0xF0A0,0x8D,0x01}, +{0xF0A1,0x67,0x01}, +{0xF0A2,0x0E,0x01}, +{0xF0A3,0x23,0x01}, +{0xF0A4,0x97,0x01}, +{0xF0A5,0xB0,0x01}, +{0xF0A6,0x6C,0x01}, +{0xF0A7,0x25,0x01}, +{0xF0A8,0x2C,0x01}, +{0xF0A9,0x71,0x01}, +{0xF0AA,0x41,0x01}, +{0xF0AB,0x0C,0x01}, +{0xF0AC,0x69,0x01}, +{0xF0AD,0x14,0x01}, +{0xF0AE,0xB3,0x01}, +{0xF0AF,0x96,0x01}, +{0xF0B0,0xA6,0x01}, +{0xF0B1,0xE8,0x01}, +{0xF0B2,0x64,0x01}, +{0xF0B3,0x26,0x01}, +{0xF0B4,0x3A,0x01}, +{0xF0B5,0x79,0x01}, +{0xF0B6,0x4A,0x01}, +{0xF0B7,0x5B,0x01}, +{0xF0B8,0x18,0x01}, +{0xF0B9,0xA3,0x01}, +{0xF0BA,0x97,0x01}, +{0xF0BB,0xA9,0x01}, +{0xF0BC,0xBC,0x01}, +{0xF0BD,0x24,0x01}, +{0xF0BE,0x23,0x01}, +{0xF0BF,0x13,0x01}, +{0xF0C0,0xE1,0x01}, +{0xF0C1,0xC8,0x01}, +{0xF0C2,0x4C,0x01}, +{0xF0C3,0xAA,0x01}, +{0xF0C4,0xA2,0x01}, +{0xF0C5,0x97,0x01}, +{0xF0C6,0xB6,0x01}, +{0xF0C7,0x14,0x01}, +{0xF0C8,0x05,0x01}, +{0xF0C9,0x24,0x01}, +{0xF0CA,0x06,0x01}, +{0xF0CB,0x09,0x01}, +{0xF0CC,0xC8,0x01}, +{0xF0CD,0x42,0x01}, +{0xF0CE,0x48,0x01}, +{0xF0CF,0x82,0x01}, +{0xF0D0,0x14,0x01}, +{0xF0D1,0xB8,0x01}, +{0xF0D2,0xC0,0x01}, +{0xF0D3,0xE5,0x01}, +{0xF0D4,0x28,0x01}, +{0xF0D5,0x21,0x01}, +{0xF0D6,0x39,0x01}, +{0xF0D7,0x08,0x01}, +{0xF0D8,0x40,0x01}, +{0xF0D9,0x14,0x01}, +{0xF0DA,0x62,0x01}, +{0xF0DB,0x92,0x01}, +{0xF0DC,0xA4,0x01}, +{0xF0DD,0xC4,0x01}, +{0xF0DE,0x05,0x01}, +{0xF0DF,0x30,0x01}, +{0xF0E0,0x58,0x01}, +{0xF0E1,0xA1,0x01}, +{0xF0E2,0x49,0x01}, +{0xF0E3,0x46,0x01}, +{0xF0E4,0x22,0x01}, +{0xF0E5,0xB2,0x01}, +{0xF0E6,0x91,0x01}, +{0xF0E7,0x9A,0x01}, +{0xF0E8,0x58,0x01}, +{0xF0E9,0xA5,0x01}, +{0xF0EA,0x2F,0x01}, +{0xF0EB,0x96,0x01}, +{0xF0EC,0x99,0x01}, +{0xF0ED,0x8B,0x01}, +{0xF0EE,0x54,0x01}, +{0xF0EF,0x74,0x01}, +{0xF0F0,0x32,0x01}, +{0xF0F1,0x13,0x01}, +{0xF0F2,0x9D,0x01}, +{0xF0F3,0x38,0x01}, +{0xF0F4,0xC5,0x01}, +{0xF0F5,0x2D,0x01}, +{0xF0F6,0x90,0x01}, +{0xF0F7,0x59,0x01}, +{0xF0F8,0x4D,0x01}, +{0xF0F9,0x64,0x01}, +{0xF0FA,0xEE,0x01}, +{0xF0FB,0x62,0x01}, +{0xF0FC,0x16,0x01}, +{0xF0FD,0xAE,0x01}, +{0xF0FE,0x84,0x01}, +{0xF0FF,0x25,0x01}, +{0xF100,0x2E,0x01}, +{0xF101,0x8B,0x01}, +{0xF102,0x31,0x01}, +{0xF103,0xCD,0x01}, +{0xF104,0x6F,0x01}, +{0xF105,0x60,0x01}, +{0xF106,0xC3,0x01}, +{0xF107,0x19,0x01}, +{0xF108,0xC7,0x01}, +{0xF109,0x14,0x01}, +{0xF10A,0x26,0x01}, +{0xF10B,0x31,0x01}, +{0xF10C,0x97,0x01}, +{0xF10D,0x41,0x01}, +{0xF10E,0x8D,0x01}, +{0xF10F,0x6D,0x01}, +{0xF110,0x86,0x01}, +{0xF111,0xE3,0x01}, +{0xF112,0x9C,0x01}, +{0xF113,0xE2,0x01}, +{0xF114,0xD8,0x01}, +{0xF115,0x06,0x01}, +{0xF116,0x36,0x01}, +{0xF117,0xB5,0x01}, +{0xF118,0xE9,0x01}, +{0xF119,0x4D,0x01}, +{0xF11A,0x70,0x01}, +{0xF11B,0x68,0x01}, +{0xF11C,0x03,0x01}, +{0xF11D,0x00,0x01}, +{0xF11E,0x00,0x01}, +{0xF11F,0x00,0x01}, +{0xF120,0x00,0x01}, +{0xF121,0x00,0x01}, + + +//SHD TH +{0x6C32,0x1964,0x02}, // SHD_INP_TH_HB_H_R2 +{0x6C34,0x18CE,0x02}, // SHD_INP_TH_HB_L_R2 +{0x6C36,0x10CC,0x02}, // SHD_INP_TH_LB_H_R2 +{0x6C38,0x1004,0x02}, // SHD_INP_TH_LB_L_R2 +{0x6C3C,0x10CC,0x02}, // SHD_INP_TH_HB_H_RB +{0x6C3E,0x1004,0x02}, // SHD_INP_TH_HB_L_RB +{0x6C40,0x0000,0x02}, // SHD_INP_TH_LB_H_RB +{0x6C42,0x0000,0x02}, // SHD_INP_TH_LB_L_RB + +//PreWB_offset (for SHD2) +{0x6828,0x0013,0x02}, // SHD_PRER_OFFSET_R2 : +//PreWB_offset (for SHD3) +{0x682C,0x000C,0x02}, // SHD_PRER_OFFSET_RB : +{0x6830,0xFFFF,0x02}, // SHD_PREB_OFFSET_RB : + +// CXC/SHD EN +{0x01BC,0x57,0x01}, // CXC ON SHD ON INP ON GAIN OFF +}; + +static const isx012_regset_t ISX012_Shading_0[] = +{ +{0x01BC,0x50,0x01}, // CXC OFF SHD OFF +{0xEB00,0x8282,0x02}, //valid_code +{0xEB02,0xFE,0x01}, +{0xEB03,0x84,0x01}, +{0xEB04,0x3F,0x01}, +{0xEB05,0x01,0x01}, +{0xEB06,0x50,0x01}, +{0xEB07,0x08,0x01}, +{0xEB08,0x14,0x01}, +{0xEB09,0xFF,0x01}, +{0xEB0A,0x45,0x01}, +{0xEB0B,0x80,0x01}, +{0xEB0C,0x01,0x01}, +{0xEB0D,0x68,0x01}, +{0xEB0E,0x04,0x01}, +{0xEB0F,0x1A,0x01}, +{0xEB10,0x81,0x01}, +{0xEB11,0x86,0x01}, +{0xEB12,0x3F,0x01}, +{0xEB13,0xE1,0x01}, +{0xEB14,0x4F,0x01}, +{0xEB15,0x00,0x01}, +{0xEB16,0x14,0x01}, +{0xEB17,0x02,0x01}, +{0xEB18,0xC5,0x01}, +{0xEB19,0x7F,0x01}, +{0xEB1A,0x11,0x01}, +{0xEB1B,0x60,0x01}, +{0xEB1C,0x00,0x01}, +{0xEB1D,0x1A,0x01}, +{0xEB1E,0x81,0x01}, +{0xEB1F,0x46,0x01}, +{0xEB20,0xA0,0x01}, +{0xEB21,0x01,0x01}, +{0xEB22,0x48,0x01}, +{0xEB23,0x00,0x01}, +{0xEB24,0x12,0x01}, +{0xEB25,0x81,0x01}, +{0xEB26,0x05,0x01}, +{0xEB27,0x20,0x01}, +{0xEB28,0xF1,0x01}, +{0xEB29,0x4F,0x01}, +{0xEB2A,0x00,0x01}, +{0xEB2B,0x14,0x01}, +{0xEB2C,0x82,0x01}, +{0xEB2D,0x85,0x01}, +{0xEB2E,0x80,0x01}, +{0xEB2F,0x21,0x01}, +{0xEB30,0x60,0x01}, +{0xEB31,0x04,0x01}, +{0xEB32,0x12,0x01}, +{0xEB33,0x81,0x01}, +{0xEB34,0x84,0x01}, +{0xEB35,0xE0,0x01}, +{0xEB36,0x00,0x01}, +{0xEB37,0x28,0x01}, +{0xEB38,0x04,0x01}, +{0xEB39,0x0C,0x01}, +{0xEB3A,0x82,0x01}, +{0xEB3B,0x43,0x01}, +{0xEB3C,0x20,0x01}, +{0xEB3D,0x11,0x01}, +{0xEB3E,0x68,0x01}, +{0xEB3F,0x04,0x01}, +{0xEB40,0x1A,0x01}, +{0xEB41,0x82,0x01}, +{0xEB42,0x83,0x01}, +{0xEB43,0xE0,0x01}, +{0xEB44,0x00,0x01}, +{0xEB45,0x20,0x01}, +{0xEB46,0x00,0x01}, +{0xEB47,0x06,0x01}, +{0xEB48,0xFF,0x01}, +{0xEB49,0x41,0x01}, +{0xEB4A,0x80,0x01}, +{0xEB4B,0x10,0x01}, +{0xEB4C,0x30,0x01}, +{0xEB4D,0x08,0x01}, +{0xEB4E,0x14,0x01}, +{0xEB4F,0x02,0x01}, +{0xEB50,0x45,0x01}, +{0xEB51,0xC0,0x01}, +{0xEB52,0x10,0x01}, +{0xEB53,0x30,0x01}, +{0xEB54,0x04,0x01}, +{0xEB55,0x04,0x01}, +{0xEB56,0x01,0x01}, +{0xEB57,0xC0,0x01}, +{0xEB58,0x3F,0x01}, +{0xEB59,0x10,0x01}, +{0xEB5A,0x10,0x01}, +{0xEB5B,0x04,0x01}, +{0xEB5C,0x0A,0x01}, +{0xEB5D,0x80,0x01}, +{0xEB5E,0x03,0x01}, +{0xEB5F,0xE0,0x01}, +{0xEB60,0x10,0x01}, +{0xEB61,0x28,0x01}, +{0xEB62,0x04,0x01}, +{0xEB63,0x0A,0x01}, +{0xEB64,0x81,0x01}, +{0xEB65,0x01,0x01}, +{0xEB66,0x00,0x01}, +{0xEB67,0x10,0x01}, +{0xEB68,0x00,0x01}, +{0xEB69,0x04,0x01}, +{0xEB6A,0x04,0x01}, +{0xEB6B,0x01,0x01}, +{0xEB6C,0x42,0x01}, +{0xEB6D,0xE0,0x01}, +{0xEB6E,0x10,0x01}, +{0xEB6F,0x38,0x01}, +{0xEB70,0xFC,0x01}, +{0xEB71,0x0D,0x01}, +{0xEB72,0x7F,0x01}, +{0xEB73,0x43,0x01}, +{0xEB74,0x60,0x01}, +{0xEB75,0x00,0x01}, +{0xEB76,0x08,0x01}, +{0xEB77,0x08,0x01}, +{0xEB78,0x02,0x01}, +{0xEB79,0x81,0x01}, +{0xEB7A,0x41,0x01}, +{0xEB7B,0x80,0x01}, +{0xEB7C,0x10,0x01}, +{0xEB7D,0x30,0x01}, +{0xEB7E,0x04,0x01}, +{0xEB7F,0x0C,0x01}, +{0xEB80,0x01,0x01}, +{0xEB81,0x43,0x01}, +{0xEB82,0xC0,0x01}, +{0xEB83,0x20,0x01}, +{0xEB84,0x28,0x01}, +{0xEB85,0x08,0x01}, +{0xEB86,0x06,0x01}, +{0xEB87,0x02,0x01}, +{0xEB88,0xC2,0x01}, +{0xEB89,0xA0,0x01}, +{0xEB8A,0x30,0x01}, +{0xEB8B,0x30,0x01}, +{0xEB8C,0x0C,0x01}, +{0xEB8D,0x12,0x01}, +{0xEB8E,0x83,0x01}, +{0xEB8F,0x84,0x01}, +{0xEB90,0x00,0x01}, +{0xEB91,0x21,0x01}, +{0xEB92,0x40,0x01}, +{0xEB93,0x0C,0x01}, +{0xEB94,0x0C,0x01}, +{0xEB95,0x82,0x01}, +{0xEB96,0x03,0x01}, +{0xEB97,0xC1,0x01}, +{0xEB98,0x40,0x01}, +{0xEB99,0x40,0x01}, +{0xEB9A,0x08,0x01}, +{0xEB9B,0x10,0x01}, +{0xEB9C,0x03,0x01}, +{0xEB9D,0xC4,0x01}, +{0xEB9E,0x00,0x01}, +{0xEB9F,0x21,0x01}, +{0xEBA0,0x38,0x01}, +{0xEBA1,0x08,0x01}, +{0xEBA2,0x0E,0x01}, +{0xEBA3,0x82,0x01}, +{0xEBA4,0xC3,0x01}, +{0xEBA5,0x20,0x01}, +{0xEBA6,0x41,0x01}, +{0xEBA7,0x48,0x01}, +{0xEBA8,0x00,0x01}, +{0xEBA9,0x14,0x01}, +{0xEBAA,0x83,0x01}, +{0xEBAB,0x44,0x01}, +{0xEBAC,0x20,0x01}, +{0xEBAD,0x11,0x01}, +{0xEBAE,0x48,0x01}, +{0xEBAF,0x08,0x01}, +{0xEBB0,0x0E,0x01}, +{0xEBB1,0x82,0x01}, +{0xEBB2,0x83,0x01}, +{0xEBB3,0xE0,0x01}, +{0xEBB4,0x30,0x01}, +{0xEBB5,0x48,0x01}, +{0xEBB6,0x10,0x01}, +{0xEBB7,0x12,0x01}, +{0xEBB8,0x00,0x01}, +{0xEBB9,0xC5,0x01}, +{0xEBBA,0x20,0x01}, +{0xEBBB,0x11,0x01}, +{0xEBBC,0x48,0x01}, +{0xEBBD,0x04,0x01}, +{0xEBBE,0x12,0x01}, +{0xEBBF,0x04,0x01}, +{0xEBC0,0x3B,0x01}, +{0xEBC1,0xC1,0x01}, +{0xEBC2,0x1E,0x01}, +{0xEBC3,0xC8,0x01}, +{0xEBC4,0x0F,0x01}, +{0xEBC5,0xF8,0x01}, +{0xEBC6,0x02,0x01}, +{0xEBC7,0xBB,0x01}, +{0xEBC8,0x60,0x01}, +{0xEBC9,0x0F,0x01}, +{0xEBCA,0xB8,0x01}, +{0xEBCB,0x0F,0x01}, +{0xEBCC,0xEA,0x01}, +{0xEBCD,0x83,0x01}, +{0xEBCE,0x3A,0x01}, +{0xEBCF,0xC1,0x01}, +{0xEBD0,0x4E,0x01}, +{0xEBD1,0xB0,0x01}, +{0xEBD2,0x07,0x01}, +{0xEBD3,0xF2,0x01}, +{0xEBD4,0x03,0x01}, +{0xEBD5,0xBE,0x01}, +{0xEBD6,0xC0,0x01}, +{0xEBD7,0x2E,0x01}, +{0xEBD8,0xD8,0x01}, +{0xEBD9,0x03,0x01}, +{0xEBDA,0xEE,0x01}, +{0xEBDB,0x83,0x01}, +{0xEBDC,0xFA,0x01}, +{0xEBDD,0xA0,0x01}, +{0xEBDE,0x2E,0x01}, +{0xEBDF,0xB0,0x01}, +{0xEBE0,0x0B,0x01}, +{0xEBE1,0xEC,0x01}, +{0xEBE2,0x05,0x01}, +{0xEBE3,0xBD,0x01}, +{0xEBE4,0x60,0x01}, +{0xEBE5,0x2F,0x01}, +{0xEBE6,0xD0,0x01}, +{0xEBE7,0x07,0x01}, +{0xEBE8,0xEC,0x01}, +{0xEBE9,0x02,0x01}, +{0xEBEA,0xBC,0x01}, +{0xEBEB,0x40,0x01}, +{0xEBEC,0x2F,0x01}, +{0xEBED,0xD0,0x01}, +{0xEBEE,0x13,0x01}, +{0xEBEF,0xEE,0x01}, +{0xEBF0,0x84,0x01}, +{0xEBF1,0xBB,0x01}, +{0xEBF2,0x00,0x01}, +{0xEBF3,0x1F,0x01}, +{0xEBF4,0xC8,0x01}, +{0xEBF5,0xFF,0x01}, +{0xEBF6,0xEF,0x01}, +{0xEBF7,0x00,0x01}, +{0xEBF8,0x7D,0x01}, +{0xEBF9,0x60,0x01}, +{0xEBFA,0x2F,0x01}, +{0xEBFB,0xD0,0x01}, +{0xEBFC,0x0B,0x01}, +{0xEBFD,0xF4,0x01}, +{0xEBFE,0x85,0x01}, +{0xEBFF,0x7D,0x01}, +{0xEC00,0x61,0x01}, +{0xEC01,0x0F,0x01}, +{0xEC02,0xC0,0x01}, +{0xEC03,0xFF,0x01}, +{0xEC04,0xF7,0x01}, +{0xEC05,0x7F,0x01}, +{0xEC06,0x3D,0x01}, +{0xEC07,0x40,0x01}, +{0xEC08,0xFF,0x01}, +{0xEC09,0xDF,0x01}, +{0xEC0A,0x07,0x01}, +{0xEC0B,0xFA,0x01}, +{0xEC0C,0x81,0x01}, +{0xEC0D,0x3E,0x01}, +{0xEC0E,0x61,0x01}, +{0xEC0F,0x4F,0x01}, +{0xEC10,0xD8,0x01}, +{0xEC11,0x0B,0x01}, +{0xEC12,0xFC,0x01}, +{0xEC13,0xFE,0x01}, +{0xEC14,0x3D,0x01}, +{0xEC15,0xC0,0x01}, +{0xEC16,0xFF,0x01}, +{0xEC17,0xFF,0x01}, +{0xEC18,0x03,0x01}, +{0xEC19,0xFC,0x01}, +{0xEC1A,0x82,0x01}, +{0xEC1B,0xBE,0x01}, +{0xEC1C,0xA0,0x01}, +{0xEC1D,0x6F,0x01}, +{0xEC1E,0xF8,0x01}, +{0xEC1F,0x1B,0x01}, +{0xEC20,0xFE,0x01}, +{0xEC21,0x83,0x01}, +{0xEC22,0xBF,0x01}, +{0xEC23,0xE0,0x01}, +{0xEC24,0x0F,0x01}, +{0xEC25,0x10,0x01}, +{0xEC26,0x00,0x01}, +{0xEC27,0x00,0x01}, +{0xEC28,0x82,0x01}, +{0xEC29,0xC0,0x01}, +{0xEC2A,0x60,0x01}, +{0xEC2B,0x30,0x01}, +{0xEC2C,0x18,0x01}, +{0xEC2D,0x20,0x01}, +{0xEC2E,0x04,0x01}, +{0xEC2F,0x08,0x01}, +{0xEC30,0x81,0x01}, +{0xEC31,0x21,0x01}, +{0xEC32,0x30,0x01}, +{0xEC33,0x08,0x01}, +{0xEC34,0x08,0x01}, +{0xEC35,0x08,0x01}, +{0xEC36,0x82,0x01}, +{0xEC37,0x01,0x01}, +{0xEC38,0x81,0x01}, +{0xEC39,0x50,0x01}, +{0xEC3A,0x08,0x01}, +{0xEC3B,0x14,0x01}, +{0xEC3C,0x02,0x01}, +{0xEC3D,0x09,0x01}, +{0xEC3E,0x41,0x01}, +{0xEC3F,0x42,0x01}, +{0xEC40,0x70,0x01}, +{0xEC41,0x20,0x01}, +{0xEC42,0x0C,0x01}, +{0xEC43,0x06,0x01}, +{0xEC44,0x84,0x01}, +{0xEC45,0x42,0x01}, +{0xEC46,0xE1,0x01}, +{0xEC47,0x40,0x01}, +{0xEC48,0x38,0x01}, +{0xEC49,0x1C,0x01}, +{0xEC4A,0x0C,0x01}, +{0xEC4B,0x07,0x01}, +{0xEC4C,0x03,0x01}, +{0xEC4D,0xA2,0x01}, +{0xEC4E,0x80,0x01}, +{0xEC4F,0x28,0x01}, +{0xEC50,0x18,0x01}, +{0xEC51,0x10,0x01}, +{0xEC52,0x87,0x01}, +{0xEC53,0x43,0x01}, +{0xEC54,0x61,0x01}, +{0xEC55,0x41,0x01}, +{0xEC56,0x48,0x01}, +{0xEC57,0x14,0x01}, +{0xEC58,0x10,0x01}, +{0xEC59,0x07,0x01}, +{0xEC5A,0xC2,0x01}, +{0xEC5B,0x81,0x01}, +{0xEC5C,0x80,0x01}, +{0xEC5D,0x30,0x01}, +{0xEC5E,0x20,0x01}, +{0xEC5F,0x0C,0x01}, +{0xEC60,0x87,0x01}, +{0xEC61,0x83,0x01}, +{0xEC62,0xC1,0x01}, +{0xEC63,0x40,0x01}, +{0xEC64,0x38,0x01}, +{0xEC65,0x14,0x01}, +{0xEC66,0x0A,0x01}, +{0xEC67,0x07,0x01}, +{0xEC68,0xC3,0x01}, +{0xEC69,0xC1,0x01}, +{0xEC6A,0x70,0x01}, +{0xEC6B,0x30,0x01}, +{0xEC6C,0x20,0x01}, +{0xEC6D,0x0C,0x01}, +{0xEC6E,0x08,0x01}, +{0xEC6F,0xC3,0x01}, +{0xEC70,0xE1,0x01}, +{0xEC71,0x60,0x01}, +{0xEC72,0x30,0x01}, +{0xEC73,0x10,0x01}, +{0xEC74,0x0E,0x01}, +{0xEC75,0x85,0x01}, +{0xEC76,0xC2,0x01}, +{0xEC77,0xC1,0x01}, +{0xEC78,0x70,0x01}, +{0xEC79,0x30,0x01}, +{0xEC7A,0x1C,0x01}, +{0xEC7B,0x0C,0x01}, + +//SHD1(from CO1) +{0xED02,0xE6,0x01}, +{0xED03,0x61,0x01}, +{0xED04,0x92,0x01}, +{0xED05,0x7C,0x01}, +{0xED06,0xBE,0x01}, +{0xED07,0xB4,0x01}, +{0xED08,0x9E,0x01}, +{0xED09,0x2C,0x01}, +{0xED0A,0x75,0x01}, +{0xED0B,0x47,0x01}, +{0xED0C,0x49,0x01}, +{0xED0D,0xD7,0x01}, +{0xED0E,0x61,0x01}, +{0xED0F,0x12,0x01}, +{0xED10,0x76,0x01}, +{0xED11,0xA8,0x01}, +{0xED12,0x34,0x01}, +{0xED13,0x1E,0x01}, +{0xED14,0x31,0x01}, +{0xED15,0xA1,0x01}, +{0xED16,0xC7,0x01}, +{0xED17,0x4C,0x01}, +{0xED18,0xDE,0x01}, +{0xED19,0xC1,0x01}, +{0xED1A,0xD2,0x01}, +{0xED1B,0x77,0x01}, +{0xED1C,0x76,0x01}, +{0xED1D,0x94,0x01}, +{0xED1E,0x9C,0x01}, +{0xED1F,0x10,0x01}, +{0xED20,0xC9,0x01}, +{0xED21,0xC6,0x01}, +{0xED22,0x40,0x01}, +{0xED23,0xA2,0x01}, +{0xED24,0x99,0x01}, +{0xED25,0x8F,0x01}, +{0xED26,0x66,0x01}, +{0xED27,0xDC,0x01}, +{0xED28,0xF3,0x01}, +{0xED29,0x19,0x01}, +{0xED2A,0xFC,0x01}, +{0xED2B,0xB0,0x01}, +{0xED2C,0xA6,0x01}, +{0xED2D,0x41,0x01}, +{0xED2E,0xC1,0x01}, +{0xED2F,0x49,0x01}, +{0xED30,0x91,0x01}, +{0xED31,0x75,0x01}, +{0xED32,0x8C,0x01}, +{0xED33,0x74,0x01}, +{0xED34,0x1C,0x01}, +{0xED35,0x0B,0x01}, +{0xED36,0x91,0x01}, +{0xED37,0x86,0x01}, +{0xED38,0x3D,0x01}, +{0xED39,0x87,0x01}, +{0xED3A,0x39,0x01}, +{0xED3B,0x4E,0x01}, +{0xED3C,0x5C,0x01}, +{0xED3D,0x50,0x01}, +{0xED3E,0x83,0x01}, +{0xED3F,0x16,0x01}, +{0xED40,0xCF,0x01}, +{0xED41,0xBC,0x01}, +{0xED42,0x45,0x01}, +{0xED43,0x35,0x01}, +{0xED44,0x83,0x01}, +{0xED45,0x41,0x01}, +{0xED46,0xCE,0x01}, +{0xED47,0x67,0x01}, +{0xED48,0xE8,0x01}, +{0xED49,0x33,0x01}, +{0xED4A,0x1C,0x01}, +{0xED4B,0x16,0x01}, +{0xED4C,0xC1,0x01}, +{0xED4D,0x86,0x01}, +{0xED4E,0x3E,0x01}, +{0xED4F,0x83,0x01}, +{0xED50,0xC1,0x01}, +{0xED51,0x0D,0x01}, +{0xED52,0x57,0x01}, +{0xED53,0x02,0x01}, +{0xED54,0x23,0x01}, +{0xED55,0x14,0x01}, +{0xED56,0xAE,0x01}, +{0xED57,0xE4,0x01}, +{0xED58,0x44,0x01}, +{0xED59,0x2A,0x01}, +{0xED5A,0x43,0x01}, +{0xED5B,0xF9,0x01}, +{0xED5C,0xCA,0x01}, +{0xED5D,0x56,0x01}, +{0xED5E,0x0C,0x01}, +{0xED5F,0x03,0x01}, +{0xED60,0x98,0x01}, +{0xED61,0xE2,0x01}, +{0xED62,0xA8,0x01}, +{0xED63,0x26,0x01}, +{0xED64,0x41,0x01}, +{0xED65,0x9E,0x01}, +{0xED66,0xC1,0x01}, +{0xED67,0xCE,0x01}, +{0xED68,0x59,0x01}, +{0xED69,0x1C,0x01}, +{0xED6A,0xB3,0x01}, +{0xED6B,0x93,0x01}, +{0xED6C,0xA7,0x01}, +{0xED6D,0x74,0x01}, +{0xED6E,0x04,0x01}, +{0xED6F,0x25,0x01}, +{0xED70,0x13,0x01}, +{0xED71,0xD9,0x01}, +{0xED72,0xC8,0x01}, +{0xED73,0x47,0x01}, +{0xED74,0x54,0x01}, +{0xED75,0xD2,0x01}, +{0xED76,0x93,0x01}, +{0xED77,0xAA,0x01}, +{0xED78,0x98,0x01}, +{0xED79,0xE5,0x01}, +{0xED7A,0x32,0x01}, +{0xED7B,0x9A,0x01}, +{0xED7C,0x29,0x01}, +{0xED7D,0xCF,0x01}, +{0xED7E,0x64,0x01}, +{0xED7F,0x8E,0x01}, +{0xED80,0x73,0x01}, +{0xED81,0x95,0x01}, +{0xED82,0xBB,0x01}, +{0xED83,0xA4,0x01}, +{0xED84,0xA4,0x01}, +{0xED85,0x26,0x01}, +{0xED86,0x0A,0x01}, +{0xED87,0x59,0x01}, +{0xED88,0x08,0x01}, +{0xED89,0x40,0x01}, +{0xED8A,0x00,0x01}, +{0xED8B,0xC2,0x01}, +{0xED8C,0x10,0x01}, +{0xED8D,0x88,0x01}, +{0xED8E,0xB0,0x01}, +{0xED8F,0x84,0x01}, +{0xED90,0x27,0x01}, +{0xED91,0x59,0x01}, +{0xED92,0xF1,0x01}, +{0xED93,0x0B,0x01}, +{0xED94,0x64,0x01}, +{0xED95,0xA2,0x01}, +{0xED96,0x43,0x01}, +{0xED97,0x99,0x01}, +{0xED98,0xE4,0x01}, +{0xED99,0x68,0x01}, +{0xED9A,0x25,0x01}, +{0xED9B,0x2F,0x01}, +{0xED9C,0x2B,0x01}, +{0xED9D,0xB1,0x01}, +{0xED9E,0xC9,0x01}, +{0xED9F,0x42,0x01}, +{0xEDA0,0x18,0x01}, +{0xEDA1,0x32,0x01}, +{0xEDA2,0x90,0x01}, +{0xEDA3,0x80,0x01}, +{0xEDA4,0x3C,0x01}, +{0xEDA5,0x24,0x01}, +{0xEDA6,0x22,0x01}, +{0xEDA7,0x2F,0x01}, +{0xEDA8,0xF1,0x01}, +{0xEDA9,0x09,0x01}, +{0xEDAA,0x57,0x01}, +{0xEDAB,0x00,0x01}, +{0xEDAC,0x53,0x01}, +{0xEDAD,0x99,0x01}, +{0xEDAE,0xEA,0x01}, +{0xEDAF,0x90,0x01}, +{0xEDB0,0xC6,0x01}, +{0xEDB1,0x3B,0x01}, +{0xEDB2,0x6D,0x01}, +{0xEDB3,0x99,0x01}, +{0xEDB4,0x4C,0x01}, +{0xEDB5,0x50,0x01}, +{0xEDB6,0xA4,0x01}, +{0xEDB7,0x32,0x01}, +{0xEDB8,0x12,0x01}, +{0xEDB9,0x94,0x01}, +{0xEDBA,0x64,0x01}, +{0xEDBB,0xA4,0x01}, +{0xEDBC,0x23,0x01}, +{0xEDBD,0x25,0x01}, +{0xEDBE,0x71,0x01}, +{0xEDBF,0x49,0x01}, +{0xEDC0,0x51,0x01}, +{0xEDC1,0xB2,0x01}, +{0xEDC2,0x02,0x01}, +{0xEDC3,0x17,0x01}, +{0xEDC4,0xCD,0x01}, +{0xEDC5,0x98,0x01}, +{0xEDC6,0x86,0x01}, +{0xEDC7,0x3D,0x01}, +{0xEDC8,0xBC,0x01}, +{0xEDC9,0x01,0x01}, +{0xEDCA,0x50,0x01}, +{0xEDCB,0x63,0x01}, +{0xEDCC,0x80,0x01}, +{0xEDCD,0x63,0x01}, +{0xEDCE,0x16,0x01}, +{0xEDCF,0xC3,0x01}, +{0xEDD0,0x2C,0x01}, +{0xEDD1,0x25,0x01}, +{0xEDD2,0x2C,0x01}, +{0xEDD3,0x43,0x01}, +{0xEDD4,0xB1,0x01}, +{0xEDD5,0x4A,0x01}, +{0xEDD6,0x53,0x01}, +{0xEDD7,0xCC,0x01}, +{0xEDD8,0x82,0x01}, +{0xEDD9,0x96,0x01}, +{0xEDDA,0xC7,0x01}, +{0xEDDB,0x40,0x01}, +{0xEDDC,0xA6,0x01}, +{0xEDDD,0x39,0x01}, +{0xEDDE,0xBE,0x01}, +{0xEDDF,0x91,0x01}, +{0xEDE0,0xD0,0x01}, +{0xEDE1,0x75,0x01}, +{0xEDE2,0x54,0x01}, +{0xEDE3,0x34,0x01}, +{0xEDE4,0x1B,0x01}, +{0xEDE5,0xFC,0x01}, +{0xEDE6,0x4C,0x01}, +{0xEDE7,0x46,0x01}, +{0xEDE8,0x39,0x01}, +{0xEDE9,0x7D,0x01}, +{0xEDEA,0x71,0x01}, +{0xEDEB,0x8D,0x01}, +{0xEDEC,0x5D,0x01}, +{0xEDED,0x46,0x01}, +{0xEDEE,0xE3,0x01}, +{0xEDEF,0x17,0x01}, +{0xEDF0,0xD9,0x01}, +{0xEDF1,0x50,0x01}, +{0xEDF2,0x86,0x01}, +{0xEDF3,0x3A,0x01}, +{0xEDF4,0xB3,0x01}, +{0xEDF5,0x09,0x01}, +{0xEDF6,0x50,0x01}, +{0xEDF7,0x76,0x01}, +{0xEDF8,0x6A,0x01}, +{0xEDF9,0xF4,0x01}, +{0xEDFA,0x1E,0x01}, +{0xEDFB,0x25,0x01}, +{0xEDFC,0x61,0x01}, +{0xEDFD,0x67,0x01}, +{0xEDFE,0x45,0x01}, +{0xEDFF,0xC0,0x01}, +{0xEE00,0x69,0x01}, +{0xEE01,0xD0,0x01}, +{0xEE02,0x6B,0x01}, +{0xEE03,0xF6,0x01}, +{0xEE04,0x93,0x01}, +{0xEE05,0x9A,0x01}, +{0xEE06,0xFA,0x01}, +{0xEE07,0xB8,0x01}, +{0xEE08,0x26,0x01}, +{0xEE09,0x40,0x01}, +{0xEE0A,0xC0,0x01}, +{0xEE0B,0xB9,0x01}, +{0xEE0C,0xD0,0x01}, +{0xEE0D,0x75,0x01}, +{0xEE0E,0x6E,0x01}, +{0xEE0F,0xE4,0x01}, +{0xEE10,0x9E,0x01}, +{0xEE11,0x2D,0x01}, +{0xEE12,0xE1,0x01}, +{0xEE13,0xA7,0x01}, +{0xEE14,0x49,0x01}, +{0xEE15,0xFD,0x01}, +{0xEE16,0xB9,0x01}, +{0xEE17,0x52,0x01}, +{0xEE18,0x7C,0x01}, +{0xEE19,0x98,0x01}, +{0xEE1A,0x64,0x01}, +{0xEE1B,0x1E,0x01}, +{0xEE1C,0x22,0x01}, +{0xEE1D,0x89,0x01}, +{0xEE1E,0xA7,0x01}, +{0xEE1F,0x48,0x01}, +{0xEE20,0xE4,0x01}, +{0xEE21,0x49,0x01}, +{0xEE22,0x12,0x01}, +{0xEE23,0x7D,0x01}, +{0xEE24,0xB4,0x01}, +{0xEE25,0xB4,0x01}, +{0xEE26,0x1F,0x01}, +{0xEE27,0x31,0x01}, +{0xEE28,0xC5,0x01}, +{0xEE29,0x47,0x01}, +{0xEE2A,0x4B,0x01}, +{0xEE2B,0xC2,0x01}, +{0xEE2C,0x19,0x01}, +{0xEE2D,0x0F,0x01}, +{0xEE2E,0x73,0x01}, +{0xEE2F,0xE2,0x01}, +{0xEE30,0x13,0x01}, +{0xEE31,0x1C,0x01}, +{0xEE32,0xF5,0x01}, +{0xEE33,0xE0,0x01}, +{0xEE34,0xC6,0x01}, +{0xEE35,0x3B,0x01}, +{0xEE36,0xB6,0x01}, +{0xEE37,0xB1,0x01}, +{0xEE38,0xCE,0x01}, +{0xEE39,0x6D,0x01}, +{0xEE3A,0xB8,0x01}, +{0xEE3B,0xF3,0x01}, +{0xEE3C,0x9B,0x01}, +{0xEE3D,0xF2,0x01}, +{0xEE3E,0x18,0x01}, +{0xEE3F,0x27,0x01}, +{0xEE40,0x3D,0x01}, +{0xEE41,0xBF,0x01}, +{0xEE42,0xE9,0x01}, +{0xEE43,0xCE,0x01}, +{0xEE44,0x6E,0x01}, +{0xEE45,0xBA,0x01}, +{0xEE46,0x83,0x01}, +{0xEE47,0x9A,0x01}, +{0xEE48,0xE4,0x01}, +{0xEE49,0x50,0x01}, +{0xEE4A,0x66,0x01}, +{0xEE4B,0x36,0x01}, +{0xEE4C,0x8A,0x01}, +{0xEE4D,0x29,0x01}, +{0xEE4E,0x4D,0x01}, +{0xEE4F,0x61,0x01}, +{0xEE50,0x3A,0x01}, +{0xEE51,0xA3,0x01}, +{0xEE52,0x18,0x01}, +{0xEE53,0xD2,0x01}, +{0xEE54,0x50,0x01}, +{0xEE55,0x26,0x01}, +{0xEE56,0x36,0x01}, +{0xEE57,0xA8,0x01}, +{0xEE58,0x21,0x01}, +{0xEE59,0xCE,0x01}, +{0xEE5A,0x6E,0x01}, +{0xEE5B,0xB2,0x01}, +{0xEE5C,0x03,0x01}, +{0xEE5D,0x9A,0x01}, +{0xEE5E,0xE0,0x01}, +{0xEE5F,0x1C,0x01}, +{0xEE60,0x46,0x01}, +{0xEE61,0x34,0x01}, +{0xEE62,0x72,0x01}, +{0xEE63,0x41,0x01}, +{0xEE64,0x8C,0x01}, +{0xEE65,0x58,0x01}, +{0xEE66,0xE8,0x01}, +{0xEE67,0xC2,0x01}, +{0xEE68,0x95,0x01}, +{0xEE69,0xB5,0x01}, +{0xEE6A,0x88,0x01}, +{0xEE6B,0x65,0x01}, +{0xEE6C,0x2E,0x01}, +{0xEE6D,0x72,0x01}, +{0xEE6E,0x39,0x01}, +{0xEE6F,0x8C,0x01}, +{0xEE70,0x62,0x01}, +{0xEE71,0x48,0x01}, +{0xEE72,0x83,0x01}, +{0xEE73,0x1A,0x01}, +{0xEE74,0xE4,0x01}, +{0xEE75,0x28,0x01}, +{0xEE76,0x06,0x01}, +{0xEE77,0x35,0x01}, +{0xEE78,0x6A,0x01}, +{0xEE79,0xF9,0x01}, +{0xEE7A,0x4B,0x01}, +{0xEE7B,0x53,0x01}, +{0xEE7C,0xB8,0x01}, +{0xEE7D,0x92,0x01}, +{0xEE7E,0x13,0x01}, +{0xEE7F,0xA2,0x01}, +{0xEE80,0xCC,0x01}, +{0xEE81,0x64,0x01}, +{0xEE82,0x27,0x01}, +{0xEE83,0x3B,0x01}, +{0xEE84,0x29,0x01}, +{0xEE85,0x0A,0x01}, +{0xEE86,0x54,0x01}, +{0xEE87,0xBC,0x01}, +{0xEE88,0xF2,0x01}, +{0xEE89,0x96,0x01}, +{0xEE8A,0xC1,0x01}, +{0xEE8B,0x40,0x01}, +{0xEE8C,0xA6,0x01}, +{0xEE8D,0x35,0x01}, +{0xEE8E,0x7A,0x01}, +{0xEE8F,0xB1,0x01}, +{0xEE90,0x8C,0x01}, +{0xEE91,0x54,0x01}, +{0xEE92,0xC8,0x01}, +{0xEE93,0xF2,0x01}, +{0xEE94,0x92,0x01}, +{0xEE95,0x9D,0x01}, +{0xEE96,0x64,0x01}, +{0xEE97,0xE4,0x01}, +{0xEE98,0x23,0x01}, +{0xEE99,0x13,0x01}, +{0xEE9A,0xA9,0x01}, +{0xEE9B,0x48,0x01}, +{0xEE9C,0x47,0x01}, +{0xEE9D,0x40,0x01}, +{0xEE9E,0x42,0x01}, +{0xEE9F,0x13,0x01}, +{0xEEA0,0x9F,0x01}, +{0xEEA1,0x58,0x01}, +{0xEEA2,0xE5,0x01}, +{0xEEA3,0x2C,0x01}, +{0xEEA4,0x7F,0x01}, +{0xEEA5,0xD9,0x01}, +{0xEEA6,0x8C,0x01}, +{0xEEA7,0x5B,0x01}, +{0xEEA8,0x12,0x01}, +{0xEEA9,0x43,0x01}, +{0xEEAA,0x14,0x01}, +{0xEEAB,0xAA,0x01}, +{0xEEAC,0x80,0x01}, +{0xEEAD,0x04,0x01}, +{0xEEAE,0x25,0x01}, +{0xEEAF,0x06,0x01}, +{0xEEB0,0x51,0x01}, +{0xEEB1,0x08,0x01}, +{0xEEB2,0x40,0x01}, +{0xEEB3,0x00,0x01}, +{0xEEB4,0xB2,0x01}, +{0xEEB5,0x10,0x01}, +{0xEEB6,0x86,0x01}, +{0xEEB7,0x98,0x01}, +{0xEEB8,0x64,0x01}, +{0xEEB9,0x25,0x01}, +{0xEEBA,0x4A,0x01}, +{0xEEBB,0xB9,0x01}, +{0xEEBC,0x0A,0x01}, +{0xEEBD,0x5D,0x01}, +{0xEEBE,0x1C,0x01}, +{0xEEBF,0x13,0x01}, +{0xEEC0,0x97,0x01}, +{0xEEC1,0xC4,0x01}, +{0xEEC2,0x18,0x01}, +{0xEEC3,0x85,0x01}, +{0xEEC4,0x2A,0x01}, +{0xEEC5,0x21,0x01}, +{0xEEC6,0x41,0x01}, +{0xEEC7,0xC9,0x01}, +{0xEEC8,0x41,0x01}, +{0xEEC9,0x12,0x01}, +{0xEECA,0x02,0x01}, +{0xEECB,0x10,0x01}, +{0xEECC,0x80,0x01}, +{0xEECD,0x2C,0x01}, +{0xEECE,0x64,0x01}, +{0xEECF,0x21,0x01}, +{0xEED0,0x27,0x01}, +{0xEED1,0x61,0x01}, +{0xEED2,0xC9,0x01}, +{0xEED3,0x52,0x01}, +{0xEED4,0xB0,0x01}, +{0xEED5,0x42,0x01}, +{0xEED6,0x17,0x01}, +{0xEED7,0xC8,0x01}, +{0xEED8,0x04,0x01}, +{0xEED9,0xE6,0x01}, +{0xEEDA,0x32,0x01}, +{0xEEDB,0x58,0x01}, +{0xEEDC,0x29,0x01}, +{0xEEDD,0xCB,0x01}, +{0xEEDE,0x4C,0x01}, +{0xEEDF,0x74,0x01}, +{0xEEE0,0x92,0x01}, +{0xEEE1,0x91,0x01}, +{0xEEE2,0x8E,0x01}, +{0xEEE3,0x48,0x01}, +{0xEEE4,0x84,0x01}, +{0xEEE5,0x22,0x01}, +{0xEEE6,0x1D,0x01}, +{0xEEE7,0x01,0x01}, +{0xEEE8,0xC9,0x01}, +{0xEEE9,0x4D,0x01}, +{0xEEEA,0x7E,0x01}, +{0xEEEB,0x82,0x01}, +{0xEEEC,0x15,0x01}, +{0xEEED,0xB5,0x01}, +{0xEEEE,0x04,0x01}, +{0xEEEF,0xE6,0x01}, +{0xEEF0,0x33,0x01}, +{0xEEF1,0x99,0x01}, +{0xEEF2,0x69,0x01}, +{0xEEF3,0x0D,0x01}, +{0xEEF4,0x5D,0x01}, +{0xEEF5,0x06,0x01}, +{0xEEF6,0x33,0x01}, +{0xEEF7,0x15,0x01}, +{0xEEF8,0xAF,0x01}, +{0xEEF9,0xEC,0x01}, +{0xEEFA,0xA4,0x01}, +{0xEEFB,0x28,0x01}, +{0xEEFC,0x35,0x01}, +{0xEEFD,0xE9,0x01}, +{0xEEFE,0x09,0x01}, +{0xEEFF,0x4F,0x01}, +{0xEF00,0x8E,0x01}, +{0xEF01,0x02,0x01}, +{0xEF02,0x95,0x01}, +{0xEF03,0xB1,0x01}, +{0xEF04,0xC4,0x01}, +{0xEF05,0x25,0x01}, +{0xEF06,0x31,0x01}, +{0xEF07,0x94,0x01}, +{0xEF08,0xB1,0x01}, +{0xEF09,0x4D,0x01}, +{0xEF0A,0x6C,0x01}, +{0xEF0B,0x94,0x01}, +{0xEF0C,0x43,0x01}, +{0xEF0D,0x99,0x01}, +{0xEF0E,0xD4,0x01}, +{0xEF0F,0xEC,0x01}, +{0xEF10,0xC5,0x01}, +{0xEF11,0x31,0x01}, +{0xEF12,0x69,0x01}, +{0xEF13,0xC9,0x01}, +{0xEF14,0x0B,0x01}, +{0xEF15,0x58,0x01}, +{0xEF16,0xE6,0x01}, +{0xEF17,0x52,0x01}, +{0xEF18,0x16,0x01}, +{0xEF19,0xBE,0x01}, +{0xEF1A,0xD4,0x01}, +{0xEF1B,0x45,0x01}, +{0xEF1C,0x32,0x01}, +{0xEF1D,0x8E,0x01}, +{0xEF1E,0x79,0x01}, +{0xEF1F,0x4D,0x01}, +{0xEF20,0x6A,0x01}, +{0xEF21,0xA4,0x01}, +{0xEF22,0x83,0x01}, +{0xEF23,0x1C,0x01}, +{0xEF24,0xF2,0x01}, +{0xEF25,0xDC,0x01}, +{0xEF26,0x26,0x01}, +{0xEF27,0x3A,0x01}, +{0xEF28,0xA3,0x01}, +{0xEF29,0xE1,0x01}, +{0xEF2A,0x4D,0x01}, +{0xEF2B,0x65,0x01}, +{0xEF2C,0x5C,0x01}, +{0xEF2D,0xC3,0x01}, +{0xEF2E,0x98,0x01}, +{0xEF2F,0xD4,0x01}, +{0xEF30,0x3C,0x01}, +{0xEF31,0xE6,0x01}, +{0xEF32,0x35,0x01}, +{0xEF33,0x9D,0x01}, +{0xEF34,0x09,0x01}, +{0xEF35,0x8E,0x01}, +{0xEF36,0x6B,0x01}, +{0xEF37,0xAC,0x01}, +{0xEF38,0xE3,0x01}, +{0xEF39,0x9B,0x01}, +{0xEF3A,0xF4,0x01}, +{0xEF3B,0x34,0x01}, +{0xEF3C,0x07,0x01}, +{0xEF3D,0x3E,0x01}, +{0xEF3E,0xDA,0x01}, +{0xEF3F,0xC1,0x01}, +{0xEF40,0x8F,0x01}, +{0xEF41,0x74,0x01}, +{0xEF42,0xEA,0x01}, +{0xEF43,0x13,0x01}, +{0xEF44,0x9C,0x01}, +{0xEF45,0xF4,0x01}, +{0xEF46,0xF0,0x01}, +{0xEF47,0xA6,0x01}, +{0xEF48,0x3C,0x01}, +{0xEF49,0xC0,0x01}, +{0xEF4A,0x49,0x01}, +{0xEF4B,0x0F,0x01}, +{0xEF4C,0x72,0x01}, +{0xEF4D,0xEA,0x01}, +{0xEF4E,0xD3,0x01}, +{0xEF4F,0x9C,0x01}, +{0xEF50,0xFE,0x01}, +{0xEF51,0x04,0x01}, +{0xEF52,0xA7,0x01}, +{0xEF53,0x3D,0x01}, + +//SHD2 CW+TL84 33:66 + +{0xED00,0x9191,0x02},// +{0xEF54,0x28,0x01}, +{0xEF55,0xC2,0x01}, +{0xEF56,0x11,0x01}, +{0xEF57,0x8C,0x01}, +{0xEF58,0x46,0x01}, +{0xEF59,0x34,0x01}, +{0xEF5A,0xA2,0x01}, +{0xEF5B,0x12,0x01}, +{0xEF5C,0xCD,0x01}, +{0xEF5D,0x08,0x01}, +{0xEF5E,0x47,0x01}, +{0xEF5F,0x27,0x01}, +{0xEF60,0xAA,0x01}, +{0xEF61,0x10,0x01}, +{0xEF62,0x7F,0x01}, +{0xEF63,0xC2,0x01}, +{0xEF64,0xF3,0x01}, +{0xEF65,0x1C,0x01}, +{0xEF66,0xE4,0x01}, +{0xEF67,0x40,0x01}, +{0xEF68,0x27,0x01}, +{0xEF69,0x3C,0x01}, +{0xEF6A,0xFB,0x01}, +{0xEF6B,0xA1,0x01}, +{0xEF6C,0x90,0x01}, +{0xEF6D,0x7C,0x01}, +{0xEF6E,0x92,0x01}, +{0xEF6F,0x63,0x01}, +{0xEF70,0x9A,0x01}, +{0xEF71,0xC5,0x01}, +{0xEF72,0x0C,0x01}, +{0xEF73,0x66,0x01}, +{0xEF74,0x31,0x01}, +{0xEF75,0xA4,0x01}, +{0xEF76,0x49,0x01}, +{0xEF77,0x0E,0x01}, +{0xEF78,0x7F,0x01}, +{0xEF79,0xA0,0x01}, +{0xEF7A,0xB3,0x01}, +{0xEF7B,0x19,0x01}, +{0xEF7C,0xB6,0x01}, +{0xEF7D,0x34,0x01}, +{0xEF7E,0x85,0x01}, +{0xEF7F,0x28,0x01}, +{0xEF80,0x4D,0x01}, +{0xEF81,0x61,0x01}, +{0xEF82,0x0B,0x01}, +{0xEF83,0x68,0x01}, +{0xEF84,0xB6,0x01}, +{0xEF85,0x73,0x01}, +{0xEF86,0x9B,0x01}, +{0xEF87,0xBB,0x01}, +{0xEF88,0x0C,0x01}, +{0xEF89,0x45,0x01}, +{0xEF8A,0x24,0x01}, +{0xEF8B,0x17,0x01}, +{0xEF8C,0x11,0x01}, +{0xEF8D,0x49,0x01}, +{0xEF8E,0x51,0x01}, +{0xEF8F,0xF4,0x01}, +{0xEF90,0xC2,0x01}, +{0xEF91,0x1B,0x01}, +{0xEF92,0xD4,0x01}, +{0xEF93,0x94,0x01}, +{0xEF94,0xC5,0x01}, +{0xEF95,0x25,0x01}, +{0xEF96,0x0B,0x01}, +{0xEF97,0x01,0x01}, +{0xEF98,0x48,0x01}, +{0xEF99,0x43,0x01}, +{0xEF9A,0x62,0x01}, +{0xEF9B,0x62,0x01}, +{0xEF9C,0x96,0x01}, +{0xEF9D,0xD5,0x01}, +{0xEF9E,0xA4,0x01}, +{0xEF9F,0xC6,0x01}, +{0xEFA0,0x2C,0x01}, +{0xEFA1,0x2F,0x01}, +{0xEFA2,0x51,0x01}, +{0xEFA3,0x48,0x01}, +{0xEFA4,0x40,0x01}, +{0xEFA5,0x1C,0x01}, +{0xEFA6,0x22,0x01}, +{0xEFA7,0x13,0x01}, +{0xEFA8,0xB4,0x01}, +{0xEFA9,0xC0,0x01}, +{0xEFAA,0x86,0x01}, +{0xEFAB,0x37,0x01}, +{0xEFAC,0x7B,0x01}, +{0xEFAD,0x29,0x01}, +{0xEFAE,0x8A,0x01}, +{0xEFAF,0x48,0x01}, +{0xEFB0,0x30,0x01}, +{0xEFB1,0x52,0x01}, +{0xEFB2,0x12,0x01}, +{0xEFB3,0xA4,0x01}, +{0xEFB4,0xF4,0x01}, +{0xEFB5,0x25,0x01}, +{0xEFB6,0x38,0x01}, +{0xEFB7,0xD9,0x01}, +{0xEFB8,0x01,0x01}, +{0xEFB9,0xCD,0x01}, +{0xEFBA,0x5B,0x01}, +{0xEFBB,0xA0,0x01}, +{0xEFBC,0x72,0x01}, +{0xEFBD,0x14,0x01}, +{0xEFBE,0xA9,0x01}, +{0xEFBF,0xCC,0x01}, +{0xEFC0,0xC5,0x01}, +{0xEFC1,0x34,0x01}, +{0xEFC2,0xE3,0x01}, +{0xEFC3,0xF1,0x01}, +{0xEFC4,0x0F,0x01}, +{0xEFC5,0x74,0x01}, +{0xEFC6,0x50,0x01}, +{0xEFC7,0xF3,0x01}, +{0xEFC8,0x98,0x01}, +{0xEFC9,0xC2,0x01}, +{0xEFCA,0x40,0x01}, +{0xEFCB,0x86,0x01}, +{0xEFCC,0x35,0x01}, +{0xEFCD,0xD4,0x01}, +{0xEFCE,0x29,0x01}, +{0xEFCF,0xD0,0x01}, +{0xEFD0,0x86,0x01}, +{0xEFD1,0xFE,0x01}, +{0xEFD2,0x23,0x01}, +{0xEFD3,0x9E,0x01}, +{0xEFD4,0xE8,0x01}, +{0xEFD5,0x28,0x01}, +{0xEFD6,0x87,0x01}, +{0xEFD7,0x3A,0x01}, +{0xEFD8,0xE7,0x01}, +{0xEFD9,0x21,0x01}, +{0xEFDA,0x10,0x01}, +{0xEFDB,0x89,0x01}, +{0xEFDC,0x3E,0x01}, +{0xEFDD,0x64,0x01}, +{0xEFDE,0xA2,0x01}, +{0xEFDF,0x0D,0x01}, +{0xEFE0,0x41,0x01}, +{0xEFE1,0xC8,0x01}, +{0xEFE2,0x41,0x01}, +{0xEFE3,0x14,0x01}, +{0xEFE4,0x02,0x01}, +{0xEFE5,0x11,0x01}, +{0xEFE6,0x8A,0x01}, +{0xEFE7,0x4C,0x01}, +{0xEFE8,0x04,0x01}, +{0xEFE9,0x00,0x01}, +{0xEFEA,0x00,0x01}, +{0xEFEB,0x00,0x01}, +{0xEFEC,0x00,0x01}, +{0xEFED,0x00,0x01}, + + +//SHD3 D65+TL84 C01// +{0xED00,0x9191,0x02},// +{0xEFEE,0x12,0x01}, +{0xEFEF,0x42,0x01}, +{0xEFF0,0x51,0x01}, +{0xEFF1,0x89,0x01}, +{0xEFF2,0x38,0x01}, +{0xEFF3,0xD4,0x01}, +{0xEFF4,0x21,0x01}, +{0xEFF5,0x10,0x01}, +{0xEFF6,0xAD,0x01}, +{0xEFF7,0xA8,0x01}, +{0xEFF8,0x45,0x01}, +{0xEFF9,0x18,0x01}, +{0xEFFA,0x4A,0x01}, +{0xEFFB,0x50,0x01}, +{0xEFFC,0x7D,0x01}, +{0xEFFD,0xBA,0x01}, +{0xEFFE,0xD3,0x01}, +{0xEFFF,0x1C,0x01}, +{0xF000,0xE4,0x01}, +{0xF001,0x40,0x01}, +{0xF002,0x27,0x01}, +{0xF003,0x3C,0x01}, +{0xF004,0xF8,0x01}, +{0xF005,0x69,0x01}, +{0xF006,0x10,0x01}, +{0xF007,0x7B,0x01}, +{0xF008,0x8E,0x01}, +{0xF009,0x63,0x01}, +{0xF00A,0x1A,0x01}, +{0xF00B,0xC6,0x01}, +{0xF00C,0x10,0x01}, +{0xF00D,0xA6,0x01}, +{0xF00E,0x31,0x01}, +{0xF00F,0xA6,0x01}, +{0xF010,0x59,0x01}, +{0xF011,0x8E,0x01}, +{0xF012,0x7E,0x01}, +{0xF013,0x9A,0x01}, +{0xF014,0xB3,0x01}, +{0xF015,0x19,0x01}, +{0xF016,0xB6,0x01}, +{0xF017,0x38,0x01}, +{0xF018,0xA5,0x01}, +{0xF019,0x28,0x01}, +{0xF01A,0x4F,0x01}, +{0xF01B,0x79,0x01}, +{0xF01C,0xCB,0x01}, +{0xF01D,0x68,0x01}, +{0xF01E,0xBA,0x01}, +{0xF01F,0x53,0x01}, +{0xF020,0x9B,0x01}, +{0xF021,0xBB,0x01}, +{0xF022,0x0C,0x01}, +{0xF023,0x65,0x01}, +{0xF024,0x24,0x01}, +{0xF025,0x17,0x01}, +{0xF026,0x21,0x01}, +{0xF027,0xC9,0x01}, +{0xF028,0x51,0x01}, +{0xF029,0xFC,0x01}, +{0xF02A,0xF2,0x01}, +{0xF02B,0x9B,0x01}, +{0xF02C,0xD3,0x01}, +{0xF02D,0x94,0x01}, +{0xF02E,0xC5,0x01}, +{0xF02F,0x25,0x01}, +{0xF030,0x0A,0x01}, +{0xF031,0x01,0x01}, +{0xF032,0x48,0x01}, +{0xF033,0x43,0x01}, +{0xF034,0x66,0x01}, +{0xF035,0x92,0x01}, +{0xF036,0x96,0x01}, +{0xF037,0xD7,0x01}, +{0xF038,0xA0,0x01}, +{0xF039,0xE6,0x01}, +{0xF03A,0x2C,0x01}, +{0xF03B,0x2F,0x01}, +{0xF03C,0x51,0x01}, +{0xF03D,0x48,0x01}, +{0xF03E,0x40,0x01}, +{0xF03F,0x1E,0x01}, +{0xF040,0x42,0x01}, +{0xF041,0x93,0x01}, +{0xF042,0xB5,0x01}, +{0xF043,0xCC,0x01}, +{0xF044,0x46,0x01}, +{0xF045,0x37,0x01}, +{0xF046,0x7C,0x01}, +{0xF047,0x29,0x01}, +{0xF048,0x8A,0x01}, +{0xF049,0x48,0x01}, +{0xF04A,0x32,0x01}, +{0xF04B,0x72,0x01}, +{0xF04C,0x12,0x01}, +{0xF04D,0xA5,0x01}, +{0xF04E,0x00,0x01}, +{0xF04F,0xA6,0x01}, +{0xF050,0x38,0x01}, +{0xF051,0xD7,0x01}, +{0xF052,0x01,0x01}, +{0xF053,0x0D,0x01}, +{0xF054,0x5C,0x01}, +{0xF055,0xA2,0x01}, +{0xF056,0x82,0x01}, +{0xF057,0x94,0x01}, +{0xF058,0xAA,0x01}, +{0xF059,0xD8,0x01}, +{0xF05A,0x45,0x01}, +{0xF05B,0x35,0x01}, +{0xF05C,0xE5,0x01}, +{0xF05D,0xC9,0x01}, +{0xF05E,0xCF,0x01}, +{0xF05F,0x73,0x01}, +{0xF060,0x50,0x01}, +{0xF061,0x03,0x01}, +{0xF062,0x99,0x01}, +{0xF063,0xC3,0x01}, +{0xF064,0x4C,0x01}, +{0xF065,0xE6,0x01}, +{0xF066,0x35,0x01}, +{0xF067,0xD7,0x01}, +{0xF068,0x21,0x01}, +{0xF069,0x10,0x01}, +{0xF06A,0x84,0x01}, +{0xF06B,0xF2,0x01}, +{0xF06C,0x03,0x01}, +{0xF06D,0x9E,0x01}, +{0xF06E,0xE8,0x01}, +{0xF06F,0x2C,0x01}, +{0xF070,0xA7,0x01}, +{0xF071,0x3A,0x01}, +{0xF072,0xE8,0x01}, +{0xF073,0x11,0x01}, +{0xF074,0x90,0x01}, +{0xF075,0x87,0x01}, +{0xF076,0x18,0x01}, +{0xF077,0x94,0x01}, +{0xF078,0x21,0x01}, +{0xF079,0x09,0x01}, +{0xF07A,0x2D,0x01}, +{0xF07B,0x68,0x01}, +{0xF07C,0x41,0x01}, +{0xF07D,0x11,0x01}, +{0xF07E,0xDA,0x01}, +{0xF07F,0x10,0x01}, +{0xF080,0x88,0x01}, +{0xF081,0x2A,0x01}, +{0xF082,0x04,0x01}, +{0xF083,0x00,0x01}, +{0xF084,0x00,0x01}, +{0xF085,0x00,0x01}, +{0xF086,0x00,0x01}, +{0xF087,0x00,0x01}, +{0xF088,0xBE,0x01}, +{0xF089,0x51,0x01}, +{0xF08A,0x4E,0x01}, +{0xF08B,0x6F,0x01}, +{0xF08C,0x6C,0x01}, +{0xF08D,0x43,0x01}, +{0xF08E,0x1B,0x01}, +{0xF08F,0xDA,0x01}, +{0xF090,0xEC,0x01}, +{0xF091,0x46,0x01}, +{0xF092,0x38,0x01}, +{0xF093,0xBB,0x01}, +{0xF094,0xC1,0x01}, +{0xF095,0xCD,0x01}, +{0xF096,0x69,0x01}, +{0xF097,0x26,0x01}, +{0xF098,0x93,0x01}, +{0xF099,0x98,0x01}, +{0xF09A,0xC1,0x01}, +{0xF09B,0x20,0x01}, +{0xF09C,0x26,0x01}, +{0xF09D,0x32,0x01}, +{0xF09E,0xA5,0x01}, +{0xF09F,0xB1,0x01}, +{0xF0A0,0x8D,0x01}, +{0xF0A1,0x67,0x01}, +{0xF0A2,0x0E,0x01}, +{0xF0A3,0x23,0x01}, +{0xF0A4,0x97,0x01}, +{0xF0A5,0xB0,0x01}, +{0xF0A6,0x6C,0x01}, +{0xF0A7,0x25,0x01}, +{0xF0A8,0x2C,0x01}, +{0xF0A9,0x71,0x01}, +{0xF0AA,0x41,0x01}, +{0xF0AB,0x0C,0x01}, +{0xF0AC,0x69,0x01}, +{0xF0AD,0x14,0x01}, +{0xF0AE,0xB3,0x01}, +{0xF0AF,0x96,0x01}, +{0xF0B0,0xA6,0x01}, +{0xF0B1,0xE8,0x01}, +{0xF0B2,0x64,0x01}, +{0xF0B3,0x26,0x01}, +{0xF0B4,0x3A,0x01}, +{0xF0B5,0x79,0x01}, +{0xF0B6,0x4A,0x01}, +{0xF0B7,0x5B,0x01}, +{0xF0B8,0x18,0x01}, +{0xF0B9,0xA3,0x01}, +{0xF0BA,0x97,0x01}, +{0xF0BB,0xA9,0x01}, +{0xF0BC,0xBC,0x01}, +{0xF0BD,0x24,0x01}, +{0xF0BE,0x23,0x01}, +{0xF0BF,0x13,0x01}, +{0xF0C0,0xE1,0x01}, +{0xF0C1,0xC8,0x01}, +{0xF0C2,0x4C,0x01}, +{0xF0C3,0xAA,0x01}, +{0xF0C4,0xA2,0x01}, +{0xF0C5,0x97,0x01}, +{0xF0C6,0xB6,0x01}, +{0xF0C7,0x14,0x01}, +{0xF0C8,0x05,0x01}, +{0xF0C9,0x24,0x01}, +{0xF0CA,0x06,0x01}, +{0xF0CB,0x09,0x01}, +{0xF0CC,0xC8,0x01}, +{0xF0CD,0x42,0x01}, +{0xF0CE,0x48,0x01}, +{0xF0CF,0x82,0x01}, +{0xF0D0,0x14,0x01}, +{0xF0D1,0xB8,0x01}, +{0xF0D2,0xC0,0x01}, +{0xF0D3,0xE5,0x01}, +{0xF0D4,0x28,0x01}, +{0xF0D5,0x21,0x01}, +{0xF0D6,0x39,0x01}, +{0xF0D7,0x08,0x01}, +{0xF0D8,0x40,0x01}, +{0xF0D9,0x14,0x01}, +{0xF0DA,0x62,0x01}, +{0xF0DB,0x92,0x01}, +{0xF0DC,0xA4,0x01}, +{0xF0DD,0xC4,0x01}, +{0xF0DE,0x05,0x01}, +{0xF0DF,0x30,0x01}, +{0xF0E0,0x58,0x01}, +{0xF0E1,0xA1,0x01}, +{0xF0E2,0x49,0x01}, +{0xF0E3,0x46,0x01}, +{0xF0E4,0x22,0x01}, +{0xF0E5,0xB2,0x01}, +{0xF0E6,0x91,0x01}, +{0xF0E7,0x9A,0x01}, +{0xF0E8,0x58,0x01}, +{0xF0E9,0xA5,0x01}, +{0xF0EA,0x2F,0x01}, +{0xF0EB,0x96,0x01}, +{0xF0EC,0x99,0x01}, +{0xF0ED,0x8B,0x01}, +{0xF0EE,0x54,0x01}, +{0xF0EF,0x74,0x01}, +{0xF0F0,0x32,0x01}, +{0xF0F1,0x13,0x01}, +{0xF0F2,0x9D,0x01}, +{0xF0F3,0x38,0x01}, +{0xF0F4,0xC5,0x01}, +{0xF0F5,0x2D,0x01}, +{0xF0F6,0x90,0x01}, +{0xF0F7,0x59,0x01}, +{0xF0F8,0x4D,0x01}, +{0xF0F9,0x64,0x01}, +{0xF0FA,0xEE,0x01}, +{0xF0FB,0x62,0x01}, +{0xF0FC,0x16,0x01}, +{0xF0FD,0xAE,0x01}, +{0xF0FE,0x84,0x01}, +{0xF0FF,0x25,0x01}, +{0xF100,0x2E,0x01}, +{0xF101,0x8B,0x01}, +{0xF102,0x31,0x01}, +{0xF103,0xCD,0x01}, +{0xF104,0x6F,0x01}, +{0xF105,0x60,0x01}, +{0xF106,0xC3,0x01}, +{0xF107,0x19,0x01}, +{0xF108,0xC7,0x01}, +{0xF109,0x14,0x01}, +{0xF10A,0x26,0x01}, +{0xF10B,0x31,0x01}, +{0xF10C,0x97,0x01}, +{0xF10D,0x41,0x01}, +{0xF10E,0x8D,0x01}, +{0xF10F,0x6D,0x01}, +{0xF110,0x86,0x01}, +{0xF111,0xE3,0x01}, +{0xF112,0x9C,0x01}, +{0xF113,0xE2,0x01}, +{0xF114,0xD8,0x01}, +{0xF115,0x06,0x01}, +{0xF116,0x36,0x01}, +{0xF117,0xB5,0x01}, +{0xF118,0xE9,0x01}, +{0xF119,0x4D,0x01}, +{0xF11A,0x70,0x01}, +{0xF11B,0x68,0x01}, +{0xF11C,0x03,0x01}, +{0xF11D,0x00,0x01}, +{0xF11E,0x00,0x01}, +{0xF11F,0x00,0x01}, +{0xF120,0x00,0x01}, +{0xF121,0x00,0x01}, + + +//SHD TH +{0x6C32,0x1964,0x02}, // SHD_INP_TH_HB_H_R2 +{0x6C34,0x18CE,0x02}, // SHD_INP_TH_HB_L_R2 +{0x6C36,0x10CC,0x02}, // SHD_INP_TH_LB_H_R2 +{0x6C38,0x1004,0x02}, // SHD_INP_TH_LB_L_R2 +{0x6C3C,0x10CC,0x02}, // SHD_INP_TH_HB_H_RB +{0x6C3E,0x1004,0x02}, // SHD_INP_TH_HB_L_RB +{0x6C40,0x0000,0x02}, // SHD_INP_TH_LB_H_RB +{0x6C42,0x0000,0x02}, // SHD_INP_TH_LB_L_RB + +//PreWB_offset (for SHD2) +{0x6828,0x0013,0x02}, // SHD_PRER_OFFSET_R2 : +//PreWB_offset (for SHD3) +{0x682C,0x000C,0x02}, // SHD_PRER_OFFSET_RB : +{0x6830,0xFFFF,0x02}, // SHD_PREB_OFFSET_RB : + +// CXC/SHD EN +{0x01BC,0x57,0x01}, // CXC ON SHD ON INP ON GAIN OFF +}; + +static const isx012_regset_t ISX012_Shading_1[] = +{ +{0x01BC,0x50,0x01}, // CXC OFF SHD OFF +{0xEB00,0x8282,0x02}, //valid_code +{0xEB02,0xFE,0x01}, +{0xEB03,0x84,0x01}, +{0xEB04,0x3F,0x01}, +{0xEB05,0x01,0x01}, +{0xEB06,0x50,0x01}, +{0xEB07,0x08,0x01}, +{0xEB08,0x14,0x01}, +{0xEB09,0xFF,0x01}, +{0xEB0A,0x45,0x01}, +{0xEB0B,0x80,0x01}, +{0xEB0C,0x01,0x01}, +{0xEB0D,0x68,0x01}, +{0xEB0E,0x04,0x01}, +{0xEB0F,0x1A,0x01}, +{0xEB10,0x81,0x01}, +{0xEB11,0x86,0x01}, +{0xEB12,0x3F,0x01}, +{0xEB13,0xE1,0x01}, +{0xEB14,0x4F,0x01}, +{0xEB15,0x00,0x01}, +{0xEB16,0x14,0x01}, +{0xEB17,0x02,0x01}, +{0xEB18,0xC5,0x01}, +{0xEB19,0x7F,0x01}, +{0xEB1A,0x11,0x01}, +{0xEB1B,0x60,0x01}, +{0xEB1C,0x00,0x01}, +{0xEB1D,0x1A,0x01}, +{0xEB1E,0x81,0x01}, +{0xEB1F,0x46,0x01}, +{0xEB20,0xA0,0x01}, +{0xEB21,0x01,0x01}, +{0xEB22,0x48,0x01}, +{0xEB23,0x00,0x01}, +{0xEB24,0x12,0x01}, +{0xEB25,0x81,0x01}, +{0xEB26,0x05,0x01}, +{0xEB27,0x20,0x01}, +{0xEB28,0xF1,0x01}, +{0xEB29,0x4F,0x01}, +{0xEB2A,0x00,0x01}, +{0xEB2B,0x14,0x01}, +{0xEB2C,0x82,0x01}, +{0xEB2D,0x85,0x01}, +{0xEB2E,0x80,0x01}, +{0xEB2F,0x21,0x01}, +{0xEB30,0x60,0x01}, +{0xEB31,0x04,0x01}, +{0xEB32,0x12,0x01}, +{0xEB33,0x81,0x01}, +{0xEB34,0x84,0x01}, +{0xEB35,0xE0,0x01}, +{0xEB36,0x00,0x01}, +{0xEB37,0x28,0x01}, +{0xEB38,0x04,0x01}, +{0xEB39,0x0C,0x01}, +{0xEB3A,0x82,0x01}, +{0xEB3B,0x43,0x01}, +{0xEB3C,0x20,0x01}, +{0xEB3D,0x11,0x01}, +{0xEB3E,0x68,0x01}, +{0xEB3F,0x04,0x01}, +{0xEB40,0x1A,0x01}, +{0xEB41,0x82,0x01}, +{0xEB42,0x83,0x01}, +{0xEB43,0xE0,0x01}, +{0xEB44,0x00,0x01}, +{0xEB45,0x20,0x01}, +{0xEB46,0x00,0x01}, +{0xEB47,0x06,0x01}, +{0xEB48,0xFF,0x01}, +{0xEB49,0x41,0x01}, +{0xEB4A,0x80,0x01}, +{0xEB4B,0x10,0x01}, +{0xEB4C,0x30,0x01}, +{0xEB4D,0x08,0x01}, +{0xEB4E,0x14,0x01}, +{0xEB4F,0x02,0x01}, +{0xEB50,0x45,0x01}, +{0xEB51,0xC0,0x01}, +{0xEB52,0x10,0x01}, +{0xEB53,0x30,0x01}, +{0xEB54,0x04,0x01}, +{0xEB55,0x04,0x01}, +{0xEB56,0x01,0x01}, +{0xEB57,0xC0,0x01}, +{0xEB58,0x3F,0x01}, +{0xEB59,0x10,0x01}, +{0xEB5A,0x10,0x01}, +{0xEB5B,0x04,0x01}, +{0xEB5C,0x0A,0x01}, +{0xEB5D,0x80,0x01}, +{0xEB5E,0x03,0x01}, +{0xEB5F,0xE0,0x01}, +{0xEB60,0x10,0x01}, +{0xEB61,0x28,0x01}, +{0xEB62,0x04,0x01}, +{0xEB63,0x0A,0x01}, +{0xEB64,0x81,0x01}, +{0xEB65,0x01,0x01}, +{0xEB66,0x00,0x01}, +{0xEB67,0x10,0x01}, +{0xEB68,0x00,0x01}, +{0xEB69,0x04,0x01}, +{0xEB6A,0x04,0x01}, +{0xEB6B,0x01,0x01}, +{0xEB6C,0x42,0x01}, +{0xEB6D,0xE0,0x01}, +{0xEB6E,0x10,0x01}, +{0xEB6F,0x38,0x01}, +{0xEB70,0xFC,0x01}, +{0xEB71,0x0D,0x01}, +{0xEB72,0x7F,0x01}, +{0xEB73,0x43,0x01}, +{0xEB74,0x60,0x01}, +{0xEB75,0x00,0x01}, +{0xEB76,0x08,0x01}, +{0xEB77,0x08,0x01}, +{0xEB78,0x02,0x01}, +{0xEB79,0x81,0x01}, +{0xEB7A,0x41,0x01}, +{0xEB7B,0x80,0x01}, +{0xEB7C,0x10,0x01}, +{0xEB7D,0x30,0x01}, +{0xEB7E,0x04,0x01}, +{0xEB7F,0x0C,0x01}, +{0xEB80,0x01,0x01}, +{0xEB81,0x43,0x01}, +{0xEB82,0xC0,0x01}, +{0xEB83,0x20,0x01}, +{0xEB84,0x28,0x01}, +{0xEB85,0x08,0x01}, +{0xEB86,0x06,0x01}, +{0xEB87,0x02,0x01}, +{0xEB88,0xC2,0x01}, +{0xEB89,0xA0,0x01}, +{0xEB8A,0x30,0x01}, +{0xEB8B,0x30,0x01}, +{0xEB8C,0x0C,0x01}, +{0xEB8D,0x12,0x01}, +{0xEB8E,0x83,0x01}, +{0xEB8F,0x84,0x01}, +{0xEB90,0x00,0x01}, +{0xEB91,0x21,0x01}, +{0xEB92,0x40,0x01}, +{0xEB93,0x0C,0x01}, +{0xEB94,0x0C,0x01}, +{0xEB95,0x82,0x01}, +{0xEB96,0x03,0x01}, +{0xEB97,0xC1,0x01}, +{0xEB98,0x40,0x01}, +{0xEB99,0x40,0x01}, +{0xEB9A,0x08,0x01}, +{0xEB9B,0x10,0x01}, +{0xEB9C,0x03,0x01}, +{0xEB9D,0xC4,0x01}, +{0xEB9E,0x00,0x01}, +{0xEB9F,0x21,0x01}, +{0xEBA0,0x38,0x01}, +{0xEBA1,0x08,0x01}, +{0xEBA2,0x0E,0x01}, +{0xEBA3,0x82,0x01}, +{0xEBA4,0xC3,0x01}, +{0xEBA5,0x20,0x01}, +{0xEBA6,0x41,0x01}, +{0xEBA7,0x48,0x01}, +{0xEBA8,0x00,0x01}, +{0xEBA9,0x14,0x01}, +{0xEBAA,0x83,0x01}, +{0xEBAB,0x44,0x01}, +{0xEBAC,0x20,0x01}, +{0xEBAD,0x11,0x01}, +{0xEBAE,0x48,0x01}, +{0xEBAF,0x08,0x01}, +{0xEBB0,0x0E,0x01}, +{0xEBB1,0x82,0x01}, +{0xEBB2,0x83,0x01}, +{0xEBB3,0xE0,0x01}, +{0xEBB4,0x30,0x01}, +{0xEBB5,0x48,0x01}, +{0xEBB6,0x10,0x01}, +{0xEBB7,0x12,0x01}, +{0xEBB8,0x00,0x01}, +{0xEBB9,0xC5,0x01}, +{0xEBBA,0x20,0x01}, +{0xEBBB,0x11,0x01}, +{0xEBBC,0x48,0x01}, +{0xEBBD,0x04,0x01}, +{0xEBBE,0x12,0x01}, +{0xEBBF,0x04,0x01}, +{0xEBC0,0x3B,0x01}, +{0xEBC1,0xC1,0x01}, +{0xEBC2,0x1E,0x01}, +{0xEBC3,0xC8,0x01}, +{0xEBC4,0x0F,0x01}, +{0xEBC5,0xF8,0x01}, +{0xEBC6,0x02,0x01}, +{0xEBC7,0xBB,0x01}, +{0xEBC8,0x60,0x01}, +{0xEBC9,0x0F,0x01}, +{0xEBCA,0xB8,0x01}, +{0xEBCB,0x0F,0x01}, +{0xEBCC,0xEA,0x01}, +{0xEBCD,0x83,0x01}, +{0xEBCE,0x3A,0x01}, +{0xEBCF,0xC1,0x01}, +{0xEBD0,0x4E,0x01}, +{0xEBD1,0xB0,0x01}, +{0xEBD2,0x07,0x01}, +{0xEBD3,0xF2,0x01}, +{0xEBD4,0x03,0x01}, +{0xEBD5,0xBE,0x01}, +{0xEBD6,0xC0,0x01}, +{0xEBD7,0x2E,0x01}, +{0xEBD8,0xD8,0x01}, +{0xEBD9,0x03,0x01}, +{0xEBDA,0xEE,0x01}, +{0xEBDB,0x83,0x01}, +{0xEBDC,0xFA,0x01}, +{0xEBDD,0xA0,0x01}, +{0xEBDE,0x2E,0x01}, +{0xEBDF,0xB0,0x01}, +{0xEBE0,0x0B,0x01}, +{0xEBE1,0xEC,0x01}, +{0xEBE2,0x05,0x01}, +{0xEBE3,0xBD,0x01}, +{0xEBE4,0x60,0x01}, +{0xEBE5,0x2F,0x01}, +{0xEBE6,0xD0,0x01}, +{0xEBE7,0x07,0x01}, +{0xEBE8,0xEC,0x01}, +{0xEBE9,0x02,0x01}, +{0xEBEA,0xBC,0x01}, +{0xEBEB,0x40,0x01}, +{0xEBEC,0x2F,0x01}, +{0xEBED,0xD0,0x01}, +{0xEBEE,0x13,0x01}, +{0xEBEF,0xEE,0x01}, +{0xEBF0,0x84,0x01}, +{0xEBF1,0xBB,0x01}, +{0xEBF2,0x00,0x01}, +{0xEBF3,0x1F,0x01}, +{0xEBF4,0xC8,0x01}, +{0xEBF5,0xFF,0x01}, +{0xEBF6,0xEF,0x01}, +{0xEBF7,0x00,0x01}, +{0xEBF8,0x7D,0x01}, +{0xEBF9,0x60,0x01}, +{0xEBFA,0x2F,0x01}, +{0xEBFB,0xD0,0x01}, +{0xEBFC,0x0B,0x01}, +{0xEBFD,0xF4,0x01}, +{0xEBFE,0x85,0x01}, +{0xEBFF,0x7D,0x01}, +{0xEC00,0x61,0x01}, +{0xEC01,0x0F,0x01}, +{0xEC02,0xC0,0x01}, +{0xEC03,0xFF,0x01}, +{0xEC04,0xF7,0x01}, +{0xEC05,0x7F,0x01}, +{0xEC06,0x3D,0x01}, +{0xEC07,0x40,0x01}, +{0xEC08,0xFF,0x01}, +{0xEC09,0xDF,0x01}, +{0xEC0A,0x07,0x01}, +{0xEC0B,0xFA,0x01}, +{0xEC0C,0x81,0x01}, +{0xEC0D,0x3E,0x01}, +{0xEC0E,0x61,0x01}, +{0xEC0F,0x4F,0x01}, +{0xEC10,0xD8,0x01}, +{0xEC11,0x0B,0x01}, +{0xEC12,0xFC,0x01}, +{0xEC13,0xFE,0x01}, +{0xEC14,0x3D,0x01}, +{0xEC15,0xC0,0x01}, +{0xEC16,0xFF,0x01}, +{0xEC17,0xFF,0x01}, +{0xEC18,0x03,0x01}, +{0xEC19,0xFC,0x01}, +{0xEC1A,0x82,0x01}, +{0xEC1B,0xBE,0x01}, +{0xEC1C,0xA0,0x01}, +{0xEC1D,0x6F,0x01}, +{0xEC1E,0xF8,0x01}, +{0xEC1F,0x1B,0x01}, +{0xEC20,0xFE,0x01}, +{0xEC21,0x83,0x01}, +{0xEC22,0xBF,0x01}, +{0xEC23,0xE0,0x01}, +{0xEC24,0x0F,0x01}, +{0xEC25,0x10,0x01}, +{0xEC26,0x00,0x01}, +{0xEC27,0x00,0x01}, +{0xEC28,0x82,0x01}, +{0xEC29,0xC0,0x01}, +{0xEC2A,0x60,0x01}, +{0xEC2B,0x30,0x01}, +{0xEC2C,0x18,0x01}, +{0xEC2D,0x20,0x01}, +{0xEC2E,0x04,0x01}, +{0xEC2F,0x08,0x01}, +{0xEC30,0x81,0x01}, +{0xEC31,0x21,0x01}, +{0xEC32,0x30,0x01}, +{0xEC33,0x08,0x01}, +{0xEC34,0x08,0x01}, +{0xEC35,0x08,0x01}, +{0xEC36,0x82,0x01}, +{0xEC37,0x01,0x01}, +{0xEC38,0x81,0x01}, +{0xEC39,0x50,0x01}, +{0xEC3A,0x08,0x01}, +{0xEC3B,0x14,0x01}, +{0xEC3C,0x02,0x01}, +{0xEC3D,0x09,0x01}, +{0xEC3E,0x41,0x01}, +{0xEC3F,0x42,0x01}, +{0xEC40,0x70,0x01}, +{0xEC41,0x20,0x01}, +{0xEC42,0x0C,0x01}, +{0xEC43,0x06,0x01}, +{0xEC44,0x84,0x01}, +{0xEC45,0x42,0x01}, +{0xEC46,0xE1,0x01}, +{0xEC47,0x40,0x01}, +{0xEC48,0x38,0x01}, +{0xEC49,0x1C,0x01}, +{0xEC4A,0x0C,0x01}, +{0xEC4B,0x07,0x01}, +{0xEC4C,0x03,0x01}, +{0xEC4D,0xA2,0x01}, +{0xEC4E,0x80,0x01}, +{0xEC4F,0x28,0x01}, +{0xEC50,0x18,0x01}, +{0xEC51,0x10,0x01}, +{0xEC52,0x87,0x01}, +{0xEC53,0x43,0x01}, +{0xEC54,0x61,0x01}, +{0xEC55,0x41,0x01}, +{0xEC56,0x48,0x01}, +{0xEC57,0x14,0x01}, +{0xEC58,0x10,0x01}, +{0xEC59,0x07,0x01}, +{0xEC5A,0xC2,0x01}, +{0xEC5B,0x81,0x01}, +{0xEC5C,0x80,0x01}, +{0xEC5D,0x30,0x01}, +{0xEC5E,0x20,0x01}, +{0xEC5F,0x0C,0x01}, +{0xEC60,0x87,0x01}, +{0xEC61,0x83,0x01}, +{0xEC62,0xC1,0x01}, +{0xEC63,0x40,0x01}, +{0xEC64,0x38,0x01}, +{0xEC65,0x14,0x01}, +{0xEC66,0x0A,0x01}, +{0xEC67,0x07,0x01}, +{0xEC68,0xC3,0x01}, +{0xEC69,0xC1,0x01}, +{0xEC6A,0x70,0x01}, +{0xEC6B,0x30,0x01}, +{0xEC6C,0x20,0x01}, +{0xEC6D,0x0C,0x01}, +{0xEC6E,0x08,0x01}, +{0xEC6F,0xC3,0x01}, +{0xEC70,0xE1,0x01}, +{0xEC71,0x60,0x01}, +{0xEC72,0x30,0x01}, +{0xEC73,0x10,0x01}, +{0xEC74,0x0E,0x01}, +{0xEC75,0x85,0x01}, +{0xEC76,0xC2,0x01}, +{0xEC77,0xC1,0x01}, +{0xEC78,0x70,0x01}, +{0xEC79,0x30,0x01}, +{0xEC7A,0x1C,0x01}, +{0xEC7B,0x0C,0x01}, + +//SHD1(from CO1) +{0xED02,0xE6,0x01}, +{0xED03,0x61,0x01}, +{0xED04,0x92,0x01}, +{0xED05,0x7C,0x01}, +{0xED06,0xBE,0x01}, +{0xED07,0xB4,0x01}, +{0xED08,0x9E,0x01}, +{0xED09,0x2C,0x01}, +{0xED0A,0x75,0x01}, +{0xED0B,0x47,0x01}, +{0xED0C,0x49,0x01}, +{0xED0D,0xD7,0x01}, +{0xED0E,0x61,0x01}, +{0xED0F,0x12,0x01}, +{0xED10,0x76,0x01}, +{0xED11,0xA8,0x01}, +{0xED12,0x34,0x01}, +{0xED13,0x1E,0x01}, +{0xED14,0x31,0x01}, +{0xED15,0xA1,0x01}, +{0xED16,0xC7,0x01}, +{0xED17,0x4C,0x01}, +{0xED18,0xDE,0x01}, +{0xED19,0xC1,0x01}, +{0xED1A,0xD2,0x01}, +{0xED1B,0x77,0x01}, +{0xED1C,0x76,0x01}, +{0xED1D,0x94,0x01}, +{0xED1E,0x9C,0x01}, +{0xED1F,0x10,0x01}, +{0xED20,0xC9,0x01}, +{0xED21,0xC6,0x01}, +{0xED22,0x40,0x01}, +{0xED23,0xA2,0x01}, +{0xED24,0x99,0x01}, +{0xED25,0x8F,0x01}, +{0xED26,0x66,0x01}, +{0xED27,0xDC,0x01}, +{0xED28,0xF3,0x01}, +{0xED29,0x19,0x01}, +{0xED2A,0xFC,0x01}, +{0xED2B,0xB0,0x01}, +{0xED2C,0xA6,0x01}, +{0xED2D,0x41,0x01}, +{0xED2E,0xC1,0x01}, +{0xED2F,0x49,0x01}, +{0xED30,0x91,0x01}, +{0xED31,0x75,0x01}, +{0xED32,0x8C,0x01}, +{0xED33,0x74,0x01}, +{0xED34,0x1C,0x01}, +{0xED35,0x0B,0x01}, +{0xED36,0x91,0x01}, +{0xED37,0x86,0x01}, +{0xED38,0x3D,0x01}, +{0xED39,0x87,0x01}, +{0xED3A,0x39,0x01}, +{0xED3B,0x4E,0x01}, +{0xED3C,0x5C,0x01}, +{0xED3D,0x50,0x01}, +{0xED3E,0x83,0x01}, +{0xED3F,0x16,0x01}, +{0xED40,0xCF,0x01}, +{0xED41,0xBC,0x01}, +{0xED42,0x45,0x01}, +{0xED43,0x35,0x01}, +{0xED44,0x83,0x01}, +{0xED45,0x41,0x01}, +{0xED46,0xCE,0x01}, +{0xED47,0x67,0x01}, +{0xED48,0xE8,0x01}, +{0xED49,0x33,0x01}, +{0xED4A,0x1C,0x01}, +{0xED4B,0x16,0x01}, +{0xED4C,0xC1,0x01}, +{0xED4D,0x86,0x01}, +{0xED4E,0x3E,0x01}, +{0xED4F,0x83,0x01}, +{0xED50,0xC1,0x01}, +{0xED51,0x0D,0x01}, +{0xED52,0x57,0x01}, +{0xED53,0x02,0x01}, +{0xED54,0x23,0x01}, +{0xED55,0x14,0x01}, +{0xED56,0xAE,0x01}, +{0xED57,0xE4,0x01}, +{0xED58,0x44,0x01}, +{0xED59,0x2A,0x01}, +{0xED5A,0x43,0x01}, +{0xED5B,0xF9,0x01}, +{0xED5C,0xCA,0x01}, +{0xED5D,0x56,0x01}, +{0xED5E,0x0C,0x01}, +{0xED5F,0x03,0x01}, +{0xED60,0x98,0x01}, +{0xED61,0xE2,0x01}, +{0xED62,0xA8,0x01}, +{0xED63,0x26,0x01}, +{0xED64,0x41,0x01}, +{0xED65,0x9E,0x01}, +{0xED66,0xC1,0x01}, +{0xED67,0xCE,0x01}, +{0xED68,0x59,0x01}, +{0xED69,0x1C,0x01}, +{0xED6A,0xB3,0x01}, +{0xED6B,0x93,0x01}, +{0xED6C,0xA7,0x01}, +{0xED6D,0x74,0x01}, +{0xED6E,0x04,0x01}, +{0xED6F,0x25,0x01}, +{0xED70,0x13,0x01}, +{0xED71,0xD9,0x01}, +{0xED72,0xC8,0x01}, +{0xED73,0x47,0x01}, +{0xED74,0x54,0x01}, +{0xED75,0xD2,0x01}, +{0xED76,0x93,0x01}, +{0xED77,0xAA,0x01}, +{0xED78,0x98,0x01}, +{0xED79,0xE5,0x01}, +{0xED7A,0x32,0x01}, +{0xED7B,0x9A,0x01}, +{0xED7C,0x29,0x01}, +{0xED7D,0xCF,0x01}, +{0xED7E,0x64,0x01}, +{0xED7F,0x8E,0x01}, +{0xED80,0x73,0x01}, +{0xED81,0x95,0x01}, +{0xED82,0xBB,0x01}, +{0xED83,0xA4,0x01}, +{0xED84,0xA4,0x01}, +{0xED85,0x26,0x01}, +{0xED86,0x0A,0x01}, +{0xED87,0x59,0x01}, +{0xED88,0x08,0x01}, +{0xED89,0x40,0x01}, +{0xED8A,0x00,0x01}, +{0xED8B,0xC2,0x01}, +{0xED8C,0x10,0x01}, +{0xED8D,0x88,0x01}, +{0xED8E,0xB0,0x01}, +{0xED8F,0x84,0x01}, +{0xED90,0x27,0x01}, +{0xED91,0x59,0x01}, +{0xED92,0xF1,0x01}, +{0xED93,0x0B,0x01}, +{0xED94,0x64,0x01}, +{0xED95,0xA2,0x01}, +{0xED96,0x43,0x01}, +{0xED97,0x99,0x01}, +{0xED98,0xE4,0x01}, +{0xED99,0x68,0x01}, +{0xED9A,0x25,0x01}, +{0xED9B,0x2F,0x01}, +{0xED9C,0x2B,0x01}, +{0xED9D,0xB1,0x01}, +{0xED9E,0xC9,0x01}, +{0xED9F,0x42,0x01}, +{0xEDA0,0x18,0x01}, +{0xEDA1,0x32,0x01}, +{0xEDA2,0x90,0x01}, +{0xEDA3,0x80,0x01}, +{0xEDA4,0x3C,0x01}, +{0xEDA5,0x24,0x01}, +{0xEDA6,0x22,0x01}, +{0xEDA7,0x2F,0x01}, +{0xEDA8,0xF1,0x01}, +{0xEDA9,0x09,0x01}, +{0xEDAA,0x57,0x01}, +{0xEDAB,0x00,0x01}, +{0xEDAC,0x53,0x01}, +{0xEDAD,0x99,0x01}, +{0xEDAE,0xEA,0x01}, +{0xEDAF,0x90,0x01}, +{0xEDB0,0xC6,0x01}, +{0xEDB1,0x3B,0x01}, +{0xEDB2,0x6D,0x01}, +{0xEDB3,0x99,0x01}, +{0xEDB4,0x4C,0x01}, +{0xEDB5,0x50,0x01}, +{0xEDB6,0xA4,0x01}, +{0xEDB7,0x32,0x01}, +{0xEDB8,0x12,0x01}, +{0xEDB9,0x94,0x01}, +{0xEDBA,0x64,0x01}, +{0xEDBB,0xA4,0x01}, +{0xEDBC,0x23,0x01}, +{0xEDBD,0x25,0x01}, +{0xEDBE,0x71,0x01}, +{0xEDBF,0x49,0x01}, +{0xEDC0,0x51,0x01}, +{0xEDC1,0xB2,0x01}, +{0xEDC2,0x02,0x01}, +{0xEDC3,0x17,0x01}, +{0xEDC4,0xCD,0x01}, +{0xEDC5,0x98,0x01}, +{0xEDC6,0x86,0x01}, +{0xEDC7,0x3D,0x01}, +{0xEDC8,0xBC,0x01}, +{0xEDC9,0x01,0x01}, +{0xEDCA,0x50,0x01}, +{0xEDCB,0x63,0x01}, +{0xEDCC,0x80,0x01}, +{0xEDCD,0x63,0x01}, +{0xEDCE,0x16,0x01}, +{0xEDCF,0xC3,0x01}, +{0xEDD0,0x2C,0x01}, +{0xEDD1,0x25,0x01}, +{0xEDD2,0x2C,0x01}, +{0xEDD3,0x43,0x01}, +{0xEDD4,0xB1,0x01}, +{0xEDD5,0x4A,0x01}, +{0xEDD6,0x53,0x01}, +{0xEDD7,0xCC,0x01}, +{0xEDD8,0x82,0x01}, +{0xEDD9,0x96,0x01}, +{0xEDDA,0xC7,0x01}, +{0xEDDB,0x40,0x01}, +{0xEDDC,0xA6,0x01}, +{0xEDDD,0x39,0x01}, +{0xEDDE,0xBE,0x01}, +{0xEDDF,0x91,0x01}, +{0xEDE0,0xD0,0x01}, +{0xEDE1,0x75,0x01}, +{0xEDE2,0x54,0x01}, +{0xEDE3,0x34,0x01}, +{0xEDE4,0x1B,0x01}, +{0xEDE5,0xFC,0x01}, +{0xEDE6,0x4C,0x01}, +{0xEDE7,0x46,0x01}, +{0xEDE8,0x39,0x01}, +{0xEDE9,0x7D,0x01}, +{0xEDEA,0x71,0x01}, +{0xEDEB,0x8D,0x01}, +{0xEDEC,0x5D,0x01}, +{0xEDED,0x46,0x01}, +{0xEDEE,0xE3,0x01}, +{0xEDEF,0x17,0x01}, +{0xEDF0,0xD9,0x01}, +{0xEDF1,0x50,0x01}, +{0xEDF2,0x86,0x01}, +{0xEDF3,0x3A,0x01}, +{0xEDF4,0xB3,0x01}, +{0xEDF5,0x09,0x01}, +{0xEDF6,0x50,0x01}, +{0xEDF7,0x76,0x01}, +{0xEDF8,0x6A,0x01}, +{0xEDF9,0xF4,0x01}, +{0xEDFA,0x1E,0x01}, +{0xEDFB,0x25,0x01}, +{0xEDFC,0x61,0x01}, +{0xEDFD,0x67,0x01}, +{0xEDFE,0x45,0x01}, +{0xEDFF,0xC0,0x01}, +{0xEE00,0x69,0x01}, +{0xEE01,0xD0,0x01}, +{0xEE02,0x6B,0x01}, +{0xEE03,0xF6,0x01}, +{0xEE04,0x93,0x01}, +{0xEE05,0x9A,0x01}, +{0xEE06,0xFA,0x01}, +{0xEE07,0xB8,0x01}, +{0xEE08,0x26,0x01}, +{0xEE09,0x40,0x01}, +{0xEE0A,0xC0,0x01}, +{0xEE0B,0xB9,0x01}, +{0xEE0C,0xD0,0x01}, +{0xEE0D,0x75,0x01}, +{0xEE0E,0x6E,0x01}, +{0xEE0F,0xE4,0x01}, +{0xEE10,0x9E,0x01}, +{0xEE11,0x2D,0x01}, +{0xEE12,0xE1,0x01}, +{0xEE13,0xA7,0x01}, +{0xEE14,0x49,0x01}, +{0xEE15,0xFD,0x01}, +{0xEE16,0xB9,0x01}, +{0xEE17,0x52,0x01}, +{0xEE18,0x7C,0x01}, +{0xEE19,0x98,0x01}, +{0xEE1A,0x64,0x01}, +{0xEE1B,0x1E,0x01}, +{0xEE1C,0x22,0x01}, +{0xEE1D,0x89,0x01}, +{0xEE1E,0xA7,0x01}, +{0xEE1F,0x48,0x01}, +{0xEE20,0xE4,0x01}, +{0xEE21,0x49,0x01}, +{0xEE22,0x12,0x01}, +{0xEE23,0x7D,0x01}, +{0xEE24,0xB4,0x01}, +{0xEE25,0xB4,0x01}, +{0xEE26,0x1F,0x01}, +{0xEE27,0x31,0x01}, +{0xEE28,0xC5,0x01}, +{0xEE29,0x47,0x01}, +{0xEE2A,0x4B,0x01}, +{0xEE2B,0xC2,0x01}, +{0xEE2C,0x19,0x01}, +{0xEE2D,0x0F,0x01}, +{0xEE2E,0x73,0x01}, +{0xEE2F,0xE2,0x01}, +{0xEE30,0x13,0x01}, +{0xEE31,0x1C,0x01}, +{0xEE32,0xF5,0x01}, +{0xEE33,0xE0,0x01}, +{0xEE34,0xC6,0x01}, +{0xEE35,0x3B,0x01}, +{0xEE36,0xB6,0x01}, +{0xEE37,0xB1,0x01}, +{0xEE38,0xCE,0x01}, +{0xEE39,0x6D,0x01}, +{0xEE3A,0xB8,0x01}, +{0xEE3B,0xF3,0x01}, +{0xEE3C,0x9B,0x01}, +{0xEE3D,0xF2,0x01}, +{0xEE3E,0x18,0x01}, +{0xEE3F,0x27,0x01}, +{0xEE40,0x3D,0x01}, +{0xEE41,0xBF,0x01}, +{0xEE42,0xE9,0x01}, +{0xEE43,0xCE,0x01}, +{0xEE44,0x6E,0x01}, +{0xEE45,0xBA,0x01}, +{0xEE46,0x83,0x01}, +{0xEE47,0x9A,0x01}, +{0xEE48,0xE4,0x01}, +{0xEE49,0x50,0x01}, +{0xEE4A,0x66,0x01}, +{0xEE4B,0x36,0x01}, +{0xEE4C,0x8A,0x01}, +{0xEE4D,0x29,0x01}, +{0xEE4E,0x4D,0x01}, +{0xEE4F,0x61,0x01}, +{0xEE50,0x3A,0x01}, +{0xEE51,0xA3,0x01}, +{0xEE52,0x18,0x01}, +{0xEE53,0xD2,0x01}, +{0xEE54,0x50,0x01}, +{0xEE55,0x26,0x01}, +{0xEE56,0x36,0x01}, +{0xEE57,0xA8,0x01}, +{0xEE58,0x21,0x01}, +{0xEE59,0xCE,0x01}, +{0xEE5A,0x6E,0x01}, +{0xEE5B,0xB2,0x01}, +{0xEE5C,0x03,0x01}, +{0xEE5D,0x9A,0x01}, +{0xEE5E,0xE0,0x01}, +{0xEE5F,0x1C,0x01}, +{0xEE60,0x46,0x01}, +{0xEE61,0x34,0x01}, +{0xEE62,0x72,0x01}, +{0xEE63,0x41,0x01}, +{0xEE64,0x8C,0x01}, +{0xEE65,0x58,0x01}, +{0xEE66,0xE8,0x01}, +{0xEE67,0xC2,0x01}, +{0xEE68,0x95,0x01}, +{0xEE69,0xB5,0x01}, +{0xEE6A,0x88,0x01}, +{0xEE6B,0x65,0x01}, +{0xEE6C,0x2E,0x01}, +{0xEE6D,0x72,0x01}, +{0xEE6E,0x39,0x01}, +{0xEE6F,0x8C,0x01}, +{0xEE70,0x62,0x01}, +{0xEE71,0x48,0x01}, +{0xEE72,0x83,0x01}, +{0xEE73,0x1A,0x01}, +{0xEE74,0xE4,0x01}, +{0xEE75,0x28,0x01}, +{0xEE76,0x06,0x01}, +{0xEE77,0x35,0x01}, +{0xEE78,0x6A,0x01}, +{0xEE79,0xF9,0x01}, +{0xEE7A,0x4B,0x01}, +{0xEE7B,0x53,0x01}, +{0xEE7C,0xB8,0x01}, +{0xEE7D,0x92,0x01}, +{0xEE7E,0x13,0x01}, +{0xEE7F,0xA2,0x01}, +{0xEE80,0xCC,0x01}, +{0xEE81,0x64,0x01}, +{0xEE82,0x27,0x01}, +{0xEE83,0x3B,0x01}, +{0xEE84,0x29,0x01}, +{0xEE85,0x0A,0x01}, +{0xEE86,0x54,0x01}, +{0xEE87,0xBC,0x01}, +{0xEE88,0xF2,0x01}, +{0xEE89,0x96,0x01}, +{0xEE8A,0xC1,0x01}, +{0xEE8B,0x40,0x01}, +{0xEE8C,0xA6,0x01}, +{0xEE8D,0x35,0x01}, +{0xEE8E,0x7A,0x01}, +{0xEE8F,0xB1,0x01}, +{0xEE90,0x8C,0x01}, +{0xEE91,0x54,0x01}, +{0xEE92,0xC8,0x01}, +{0xEE93,0xF2,0x01}, +{0xEE94,0x92,0x01}, +{0xEE95,0x9D,0x01}, +{0xEE96,0x64,0x01}, +{0xEE97,0xE4,0x01}, +{0xEE98,0x23,0x01}, +{0xEE99,0x13,0x01}, +{0xEE9A,0xA9,0x01}, +{0xEE9B,0x48,0x01}, +{0xEE9C,0x47,0x01}, +{0xEE9D,0x40,0x01}, +{0xEE9E,0x42,0x01}, +{0xEE9F,0x13,0x01}, +{0xEEA0,0x9F,0x01}, +{0xEEA1,0x58,0x01}, +{0xEEA2,0xE5,0x01}, +{0xEEA3,0x2C,0x01}, +{0xEEA4,0x7F,0x01}, +{0xEEA5,0xD9,0x01}, +{0xEEA6,0x8C,0x01}, +{0xEEA7,0x5B,0x01}, +{0xEEA8,0x12,0x01}, +{0xEEA9,0x43,0x01}, +{0xEEAA,0x14,0x01}, +{0xEEAB,0xAA,0x01}, +{0xEEAC,0x80,0x01}, +{0xEEAD,0x04,0x01}, +{0xEEAE,0x25,0x01}, +{0xEEAF,0x06,0x01}, +{0xEEB0,0x51,0x01}, +{0xEEB1,0x08,0x01}, +{0xEEB2,0x40,0x01}, +{0xEEB3,0x00,0x01}, +{0xEEB4,0xB2,0x01}, +{0xEEB5,0x10,0x01}, +{0xEEB6,0x86,0x01}, +{0xEEB7,0x98,0x01}, +{0xEEB8,0x64,0x01}, +{0xEEB9,0x25,0x01}, +{0xEEBA,0x4A,0x01}, +{0xEEBB,0xB9,0x01}, +{0xEEBC,0x0A,0x01}, +{0xEEBD,0x5D,0x01}, +{0xEEBE,0x1C,0x01}, +{0xEEBF,0x13,0x01}, +{0xEEC0,0x97,0x01}, +{0xEEC1,0xC4,0x01}, +{0xEEC2,0x18,0x01}, +{0xEEC3,0x85,0x01}, +{0xEEC4,0x2A,0x01}, +{0xEEC5,0x21,0x01}, +{0xEEC6,0x41,0x01}, +{0xEEC7,0xC9,0x01}, +{0xEEC8,0x41,0x01}, +{0xEEC9,0x12,0x01}, +{0xEECA,0x02,0x01}, +{0xEECB,0x10,0x01}, +{0xEECC,0x80,0x01}, +{0xEECD,0x2C,0x01}, +{0xEECE,0x64,0x01}, +{0xEECF,0x21,0x01}, +{0xEED0,0x27,0x01}, +{0xEED1,0x61,0x01}, +{0xEED2,0xC9,0x01}, +{0xEED3,0x52,0x01}, +{0xEED4,0xB0,0x01}, +{0xEED5,0x42,0x01}, +{0xEED6,0x17,0x01}, +{0xEED7,0xC8,0x01}, +{0xEED8,0x04,0x01}, +{0xEED9,0xE6,0x01}, +{0xEEDA,0x32,0x01}, +{0xEEDB,0x58,0x01}, +{0xEEDC,0x29,0x01}, +{0xEEDD,0xCB,0x01}, +{0xEEDE,0x4C,0x01}, +{0xEEDF,0x74,0x01}, +{0xEEE0,0x92,0x01}, +{0xEEE1,0x91,0x01}, +{0xEEE2,0x8E,0x01}, +{0xEEE3,0x48,0x01}, +{0xEEE4,0x84,0x01}, +{0xEEE5,0x22,0x01}, +{0xEEE6,0x1D,0x01}, +{0xEEE7,0x01,0x01}, +{0xEEE8,0xC9,0x01}, +{0xEEE9,0x4D,0x01}, +{0xEEEA,0x7E,0x01}, +{0xEEEB,0x82,0x01}, +{0xEEEC,0x15,0x01}, +{0xEEED,0xB5,0x01}, +{0xEEEE,0x04,0x01}, +{0xEEEF,0xE6,0x01}, +{0xEEF0,0x33,0x01}, +{0xEEF1,0x99,0x01}, +{0xEEF2,0x69,0x01}, +{0xEEF3,0x0D,0x01}, +{0xEEF4,0x5D,0x01}, +{0xEEF5,0x06,0x01}, +{0xEEF6,0x33,0x01}, +{0xEEF7,0x15,0x01}, +{0xEEF8,0xAF,0x01}, +{0xEEF9,0xEC,0x01}, +{0xEEFA,0xA4,0x01}, +{0xEEFB,0x28,0x01}, +{0xEEFC,0x35,0x01}, +{0xEEFD,0xE9,0x01}, +{0xEEFE,0x09,0x01}, +{0xEEFF,0x4F,0x01}, +{0xEF00,0x8E,0x01}, +{0xEF01,0x02,0x01}, +{0xEF02,0x95,0x01}, +{0xEF03,0xB1,0x01}, +{0xEF04,0xC4,0x01}, +{0xEF05,0x25,0x01}, +{0xEF06,0x31,0x01}, +{0xEF07,0x94,0x01}, +{0xEF08,0xB1,0x01}, +{0xEF09,0x4D,0x01}, +{0xEF0A,0x6C,0x01}, +{0xEF0B,0x94,0x01}, +{0xEF0C,0x43,0x01}, +{0xEF0D,0x99,0x01}, +{0xEF0E,0xD4,0x01}, +{0xEF0F,0xEC,0x01}, +{0xEF10,0xC5,0x01}, +{0xEF11,0x31,0x01}, +{0xEF12,0x69,0x01}, +{0xEF13,0xC9,0x01}, +{0xEF14,0x0B,0x01}, +{0xEF15,0x58,0x01}, +{0xEF16,0xE6,0x01}, +{0xEF17,0x52,0x01}, +{0xEF18,0x16,0x01}, +{0xEF19,0xBE,0x01}, +{0xEF1A,0xD4,0x01}, +{0xEF1B,0x45,0x01}, +{0xEF1C,0x32,0x01}, +{0xEF1D,0x8E,0x01}, +{0xEF1E,0x79,0x01}, +{0xEF1F,0x4D,0x01}, +{0xEF20,0x6A,0x01}, +{0xEF21,0xA4,0x01}, +{0xEF22,0x83,0x01}, +{0xEF23,0x1C,0x01}, +{0xEF24,0xF2,0x01}, +{0xEF25,0xDC,0x01}, +{0xEF26,0x26,0x01}, +{0xEF27,0x3A,0x01}, +{0xEF28,0xA3,0x01}, +{0xEF29,0xE1,0x01}, +{0xEF2A,0x4D,0x01}, +{0xEF2B,0x65,0x01}, +{0xEF2C,0x5C,0x01}, +{0xEF2D,0xC3,0x01}, +{0xEF2E,0x98,0x01}, +{0xEF2F,0xD4,0x01}, +{0xEF30,0x3C,0x01}, +{0xEF31,0xE6,0x01}, +{0xEF32,0x35,0x01}, +{0xEF33,0x9D,0x01}, +{0xEF34,0x09,0x01}, +{0xEF35,0x8E,0x01}, +{0xEF36,0x6B,0x01}, +{0xEF37,0xAC,0x01}, +{0xEF38,0xE3,0x01}, +{0xEF39,0x9B,0x01}, +{0xEF3A,0xF4,0x01}, +{0xEF3B,0x34,0x01}, +{0xEF3C,0x07,0x01}, +{0xEF3D,0x3E,0x01}, +{0xEF3E,0xDA,0x01}, +{0xEF3F,0xC1,0x01}, +{0xEF40,0x8F,0x01}, +{0xEF41,0x74,0x01}, +{0xEF42,0xEA,0x01}, +{0xEF43,0x13,0x01}, +{0xEF44,0x9C,0x01}, +{0xEF45,0xF4,0x01}, +{0xEF46,0xF0,0x01}, +{0xEF47,0xA6,0x01}, +{0xEF48,0x3C,0x01}, +{0xEF49,0xC0,0x01}, +{0xEF4A,0x49,0x01}, +{0xEF4B,0x0F,0x01}, +{0xEF4C,0x72,0x01}, +{0xEF4D,0xEA,0x01}, +{0xEF4E,0xD3,0x01}, +{0xEF4F,0x9C,0x01}, +{0xEF50,0xFE,0x01}, +{0xEF51,0x04,0x01}, +{0xEF52,0xA7,0x01}, +{0xEF53,0x3D,0x01}, + +//SHD2 CW+TL84 33:66 + +{0xED00,0x9191,0x02},// +{0xEF54,0x0B,0x01}, +{0xEF55,0xFA,0x01}, +{0xEF56,0x10,0x01}, +{0xEF57,0x87,0x01}, +{0xEF58,0x24,0x01}, +{0xEF59,0x24,0x01}, +{0xEF5A,0xA1,0x01}, +{0xEF5B,0x09,0x01}, +{0xEF5C,0x7D,0x01}, +{0xEF5D,0x08,0x01}, +{0xEF5E,0x44,0x01}, +{0xEF5F,0x0A,0x01}, +{0xEF60,0x0A,0x01}, +{0xEF61,0x50,0x01}, +{0xEF62,0x7B,0x01}, +{0xEF63,0xAA,0x01}, +{0xEF64,0x53,0x01}, +{0xEF65,0x9C,0x01}, +{0xEF66,0xDF,0x01}, +{0xEF67,0x18,0x01}, +{0xEF68,0xC7,0x01}, +{0xEF69,0x3A,0x01}, +{0xEF6A,0xEC,0x01}, +{0xEF6B,0xF9,0x01}, +{0xEF6C,0x0F,0x01}, +{0xEF6D,0x79,0x01}, +{0xEF6E,0x80,0x01}, +{0xEF6F,0x03,0x01}, +{0xEF70,0x9A,0x01}, +{0xEF71,0xC3,0x01}, +{0xEF72,0xF8,0x01}, +{0xEF73,0xE5,0x01}, +{0xEF74,0x30,0x01}, +{0xEF75,0x9D,0x01}, +{0xEF76,0x01,0x01}, +{0xEF77,0x4E,0x01}, +{0xEF78,0x7B,0x01}, +{0xEF79,0x8C,0x01}, +{0xEF7A,0x53,0x01}, +{0xEF7B,0x19,0x01}, +{0xEF7C,0xB4,0x01}, +{0xEF7D,0x2C,0x01}, +{0xEF7E,0x45,0x01}, +{0xEF7F,0x28,0x01}, +{0xEF80,0x4B,0x01}, +{0xEF81,0x49,0x01}, +{0xEF82,0x8B,0x01}, +{0xEF83,0x66,0x01}, +{0xEF84,0xA0,0x01}, +{0xEF85,0xF3,0x01}, +{0xEF86,0x9A,0x01}, +{0xEF87,0xB9,0x01}, +{0xEF88,0x04,0x01}, +{0xEF89,0x45,0x01}, +{0xEF8A,0x24,0x01}, +{0xEF8B,0x16,0x01}, +{0xEF8C,0x09,0x01}, +{0xEF8D,0xC9,0x01}, +{0xEF8E,0x50,0x01}, +{0xEF8F,0xEC,0x01}, +{0xEF90,0x42,0x01}, +{0xEF91,0x1B,0x01}, +{0xEF92,0xD1,0x01}, +{0xEF93,0x88,0x01}, +{0xEF94,0xA5,0x01}, +{0xEF95,0x25,0x01}, +{0xEF96,0x0A,0x01}, +{0xEF97,0x01,0x01}, +{0xEF98,0x48,0x01}, +{0xEF99,0x43,0x01}, +{0xEF9A,0x60,0x01}, +{0xEF9B,0x32,0x01}, +{0xEF9C,0x96,0x01}, +{0xEF9D,0xD2,0x01}, +{0xEF9E,0x88,0x01}, +{0xEF9F,0x66,0x01}, +{0xEFA0,0x2C,0x01}, +{0xEFA1,0x2E,0x01}, +{0xEFA2,0x51,0x01}, +{0xEFA3,0x48,0x01}, +{0xEFA4,0x40,0x01}, +{0xEFA5,0x1C,0x01}, +{0xEFA6,0x12,0x01}, +{0xEFA7,0x93,0x01}, +{0xEFA8,0xB2,0x01}, +{0xEFA9,0xA4,0x01}, +{0xEFAA,0x86,0x01}, +{0xEFAB,0x36,0x01}, +{0xEFAC,0x77,0x01}, +{0xEFAD,0x19,0x01}, +{0xEFAE,0x4A,0x01}, +{0xEFAF,0x48,0x01}, +{0xEFB0,0x30,0x01}, +{0xEFB1,0x52,0x01}, +{0xEFB2,0x12,0x01}, +{0xEFB3,0xA3,0x01}, +{0xEFB4,0xE4,0x01}, +{0xEFB5,0x25,0x01}, +{0xEFB6,0x37,0x01}, +{0xEFB7,0xCF,0x01}, +{0xEFB8,0xD1,0x01}, +{0xEFB9,0xCC,0x01}, +{0xEFBA,0x5A,0x01}, +{0xEFBB,0x9A,0x01}, +{0xEFBC,0x52,0x01}, +{0xEFBD,0x14,0x01}, +{0xEFBE,0xA8,0x01}, +{0xEFBF,0xC0,0x01}, +{0xEFC0,0x05,0x01}, +{0xEFC1,0x34,0x01}, +{0xEFC2,0xD8,0x01}, +{0xEFC3,0x79,0x01}, +{0xEFC4,0xCF,0x01}, +{0xEFC5,0x71,0x01}, +{0xEFC6,0x42,0x01}, +{0xEFC7,0xA3,0x01}, +{0xEFC8,0x98,0x01}, +{0xEFC9,0xC0,0x01}, +{0xEFCA,0x30,0x01}, +{0xEFCB,0xA6,0x01}, +{0xEFCC,0x34,0x01}, +{0xEFCD,0xCA,0x01}, +{0xEFCE,0xB1,0x01}, +{0xEFCF,0x8F,0x01}, +{0xEFD0,0x81,0x01}, +{0xEFD1,0xE0,0x01}, +{0xEFD2,0x73,0x01}, +{0xEFD3,0x9D,0x01}, +{0xEFD4,0xE3,0x01}, +{0xEFD5,0x04,0x01}, +{0xEFD6,0x47,0x01}, +{0xEFD7,0x39,0x01}, +{0xEFD8,0xDB,0x01}, +{0xEFD9,0xA9,0x01}, +{0xEFDA,0x8F,0x01}, +{0xEFDB,0x83,0x01}, +{0xEFDC,0x06,0x01}, +{0xEFDD,0xE4,0x01}, +{0xEFDE,0xA0,0x01}, +{0xEFDF,0x03,0x01}, +{0xEFE0,0xFD,0x01}, +{0xEFE1,0xA7,0x01}, +{0xEFE2,0x3F,0x01}, +{0xEFE3,0x03,0x01}, +{0xEFE4,0x62,0x01}, +{0xEFE5,0x10,0x01}, +{0xEFE6,0x84,0x01}, +{0xEFE7,0x12,0x01}, +{0xEFE8,0x04,0x01}, +{0xEFE9,0x00,0x01}, +{0xEFEA,0x00,0x01}, +{0xEFEB,0x00,0x01}, +{0xEFEC,0x00,0x01}, +{0xEFED,0x00,0x01}, + + + +//SHD3 D65+TL84 C01// +{0xED00,0x9191,0x02},// +{0xEFEE,0x0B,0x01}, +{0xEFEF,0x12,0x01}, +{0xEFF0,0x11,0x01}, +{0xEFF1,0x88,0x01}, +{0xEFF2,0x2E,0x01}, +{0xEFF3,0x94,0x01}, +{0xEFF4,0x21,0x01}, +{0xEFF5,0x0E,0x01}, +{0xEFF6,0x99,0x01}, +{0xEFF7,0xE8,0x01}, +{0xEFF8,0x44,0x01}, +{0xEFF9,0x10,0x01}, +{0xEFFA,0x22,0x01}, +{0xEFFB,0x50,0x01}, +{0xEFFC,0x7C,0x01}, +{0xEFFD,0xB6,0x01}, +{0xEFFE,0xB3,0x01}, +{0xEFFF,0x1C,0x01}, +{0xF000,0xE3,0x01}, +{0xF001,0x38,0x01}, +{0xF002,0xC7,0x01}, +{0xF003,0x3B,0x01}, +{0xF004,0xF4,0x01}, +{0xF005,0x39,0x01}, +{0xF006,0x10,0x01}, +{0xF007,0x7A,0x01}, +{0xF008,0x8A,0x01}, +{0xF009,0x53,0x01}, +{0xF00A,0x9A,0x01}, +{0xF00B,0xC5,0x01}, +{0xF00C,0x0C,0x01}, +{0xF00D,0x86,0x01}, +{0xF00E,0x31,0x01}, +{0xF00F,0xA5,0x01}, +{0xF010,0x49,0x01}, +{0xF011,0xCE,0x01}, +{0xF012,0x7D,0x01}, +{0xF013,0x94,0x01}, +{0xF014,0xA3,0x01}, +{0xF015,0x19,0x01}, +{0xF016,0xB6,0x01}, +{0xF017,0x38,0x01}, +{0xF018,0xA5,0x01}, +{0xF019,0x28,0x01}, +{0xF01A,0x4F,0x01}, +{0xF01B,0x79,0x01}, +{0xF01C,0x8B,0x01}, +{0xF01D,0x68,0x01}, +{0xF01E,0xB4,0x01}, +{0xF01F,0x43,0x01}, +{0xF020,0x1B,0x01}, +{0xF021,0xBB,0x01}, +{0xF022,0x0C,0x01}, +{0xF023,0x45,0x01}, +{0xF024,0x24,0x01}, +{0xF025,0x17,0x01}, +{0xF026,0x19,0x01}, +{0xF027,0xC9,0x01}, +{0xF028,0x51,0x01}, +{0xF029,0xFA,0x01}, +{0xF02A,0xD2,0x01}, +{0xF02B,0x1B,0x01}, +{0xF02C,0xD3,0x01}, +{0xF02D,0x94,0x01}, +{0xF02E,0xC5,0x01}, +{0xF02F,0x25,0x01}, +{0xF030,0x0A,0x01}, +{0xF031,0x01,0x01}, +{0xF032,0x48,0x01}, +{0xF033,0x43,0x01}, +{0xF034,0x66,0x01}, +{0xF035,0x82,0x01}, +{0xF036,0x96,0x01}, +{0xF037,0xD6,0x01}, +{0xF038,0x98,0x01}, +{0xF039,0xC6,0x01}, +{0xF03A,0x2C,0x01}, +{0xF03B,0x2F,0x01}, +{0xF03C,0x51,0x01}, +{0xF03D,0x48,0x01}, +{0xF03E,0x40,0x01}, +{0xF03F,0x1E,0x01}, +{0xF040,0x42,0x01}, +{0xF041,0x13,0x01}, +{0xF042,0xB5,0x01}, +{0xF043,0xC8,0x01}, +{0xF044,0x06,0x01}, +{0xF045,0x37,0x01}, +{0xF046,0x7B,0x01}, +{0xF047,0x29,0x01}, +{0xF048,0x8A,0x01}, +{0xF049,0x48,0x01}, +{0xF04A,0x32,0x01}, +{0xF04B,0x72,0x01}, +{0xF04C,0x12,0x01}, +{0xF04D,0xA5,0x01}, +{0xF04E,0xFC,0x01}, +{0xF04F,0x65,0x01}, +{0xF050,0x38,0x01}, +{0xF051,0xD4,0x01}, +{0xF052,0xF9,0x01}, +{0xF053,0xCC,0x01}, +{0xF054,0x5B,0x01}, +{0xF055,0xA0,0x01}, +{0xF056,0x82,0x01}, +{0xF057,0x14,0x01}, +{0xF058,0xAA,0x01}, +{0xF059,0xD4,0x01}, +{0xF05A,0x05,0x01}, +{0xF05B,0x35,0x01}, +{0xF05C,0xE2,0x01}, +{0xF05D,0xA9,0x01}, +{0xF05E,0x4F,0x01}, +{0xF05F,0x73,0x01}, +{0xF060,0x4E,0x01}, +{0xF061,0xF3,0x01}, +{0xF062,0x18,0x01}, +{0xF063,0xC3,0x01}, +{0xF064,0x48,0x01}, +{0xF065,0xC6,0x01}, +{0xF066,0x35,0x01}, +{0xF067,0xD4,0x01}, +{0xF068,0x01,0x01}, +{0xF069,0xD0,0x01}, +{0xF06A,0x82,0x01}, +{0xF06B,0xEA,0x01}, +{0xF06C,0xD3,0x01}, +{0xF06D,0x1D,0x01}, +{0xF06E,0xE7,0x01}, +{0xF06F,0x24,0x01}, +{0xF070,0x47,0x01}, +{0xF071,0x3A,0x01}, +{0xF072,0xE5,0x01}, +{0xF073,0xF1,0x01}, +{0xF074,0x0F,0x01}, +{0xF075,0x86,0x01}, +{0xF076,0x0A,0x01}, +{0xF077,0x34,0x01}, +{0xF078,0xA1,0x01}, +{0xF079,0x06,0x01}, +{0xF07A,0x19,0x01}, +{0xF07B,0xE8,0x01}, +{0xF07C,0x40,0x01}, +{0xF07D,0x0D,0x01}, +{0xF07E,0xB2,0x01}, +{0xF07F,0x90,0x01}, +{0xF080,0x86,0x01}, +{0xF081,0x1C,0x01}, +{0xF082,0x04,0x01}, +{0xF083,0x00,0x01}, +{0xF084,0x00,0x01}, +{0xF085,0x00,0x01}, +{0xF086,0x00,0x01}, +{0xF087,0x00,0x01}, +{0xF088,0xBE,0x01}, +{0xF089,0x51,0x01}, +{0xF08A,0x4E,0x01}, +{0xF08B,0x6F,0x01}, +{0xF08C,0x6C,0x01}, +{0xF08D,0x43,0x01}, +{0xF08E,0x1B,0x01}, +{0xF08F,0xDA,0x01}, +{0xF090,0xEC,0x01}, +{0xF091,0x46,0x01}, +{0xF092,0x38,0x01}, +{0xF093,0xBB,0x01}, +{0xF094,0xC1,0x01}, +{0xF095,0xCD,0x01}, +{0xF096,0x69,0x01}, +{0xF097,0x26,0x01}, +{0xF098,0x93,0x01}, +{0xF099,0x98,0x01}, +{0xF09A,0xC1,0x01}, +{0xF09B,0x20,0x01}, +{0xF09C,0x26,0x01}, +{0xF09D,0x32,0x01}, +{0xF09E,0xA5,0x01}, +{0xF09F,0xB1,0x01}, +{0xF0A0,0x8D,0x01}, +{0xF0A1,0x67,0x01}, +{0xF0A2,0x0E,0x01}, +{0xF0A3,0x23,0x01}, +{0xF0A4,0x97,0x01}, +{0xF0A5,0xB0,0x01}, +{0xF0A6,0x6C,0x01}, +{0xF0A7,0x25,0x01}, +{0xF0A8,0x2C,0x01}, +{0xF0A9,0x71,0x01}, +{0xF0AA,0x41,0x01}, +{0xF0AB,0x0C,0x01}, +{0xF0AC,0x69,0x01}, +{0xF0AD,0x14,0x01}, +{0xF0AE,0xB3,0x01}, +{0xF0AF,0x96,0x01}, +{0xF0B0,0xA6,0x01}, +{0xF0B1,0xE8,0x01}, +{0xF0B2,0x64,0x01}, +{0xF0B3,0x26,0x01}, +{0xF0B4,0x3A,0x01}, +{0xF0B5,0x79,0x01}, +{0xF0B6,0x4A,0x01}, +{0xF0B7,0x5B,0x01}, +{0xF0B8,0x18,0x01}, +{0xF0B9,0xA3,0x01}, +{0xF0BA,0x97,0x01}, +{0xF0BB,0xA9,0x01}, +{0xF0BC,0xBC,0x01}, +{0xF0BD,0x24,0x01}, +{0xF0BE,0x23,0x01}, +{0xF0BF,0x13,0x01}, +{0xF0C0,0xE1,0x01}, +{0xF0C1,0xC8,0x01}, +{0xF0C2,0x4C,0x01}, +{0xF0C3,0xAA,0x01}, +{0xF0C4,0xA2,0x01}, +{0xF0C5,0x97,0x01}, +{0xF0C6,0xB6,0x01}, +{0xF0C7,0x14,0x01}, +{0xF0C8,0x05,0x01}, +{0xF0C9,0x24,0x01}, +{0xF0CA,0x06,0x01}, +{0xF0CB,0x09,0x01}, +{0xF0CC,0xC8,0x01}, +{0xF0CD,0x42,0x01}, +{0xF0CE,0x48,0x01}, +{0xF0CF,0x82,0x01}, +{0xF0D0,0x14,0x01}, +{0xF0D1,0xB8,0x01}, +{0xF0D2,0xC0,0x01}, +{0xF0D3,0xE5,0x01}, +{0xF0D4,0x28,0x01}, +{0xF0D5,0x21,0x01}, +{0xF0D6,0x39,0x01}, +{0xF0D7,0x08,0x01}, +{0xF0D8,0x40,0x01}, +{0xF0D9,0x14,0x01}, +{0xF0DA,0x62,0x01}, +{0xF0DB,0x92,0x01}, +{0xF0DC,0xA4,0x01}, +{0xF0DD,0xC4,0x01}, +{0xF0DE,0x05,0x01}, +{0xF0DF,0x30,0x01}, +{0xF0E0,0x58,0x01}, +{0xF0E1,0xA1,0x01}, +{0xF0E2,0x49,0x01}, +{0xF0E3,0x46,0x01}, +{0xF0E4,0x22,0x01}, +{0xF0E5,0xB2,0x01}, +{0xF0E6,0x91,0x01}, +{0xF0E7,0x9A,0x01}, +{0xF0E8,0x58,0x01}, +{0xF0E9,0xA5,0x01}, +{0xF0EA,0x2F,0x01}, +{0xF0EB,0x96,0x01}, +{0xF0EC,0x99,0x01}, +{0xF0ED,0x8B,0x01}, +{0xF0EE,0x54,0x01}, +{0xF0EF,0x74,0x01}, +{0xF0F0,0x32,0x01}, +{0xF0F1,0x13,0x01}, +{0xF0F2,0x9D,0x01}, +{0xF0F3,0x38,0x01}, +{0xF0F4,0xC5,0x01}, +{0xF0F5,0x2D,0x01}, +{0xF0F6,0x90,0x01}, +{0xF0F7,0x59,0x01}, +{0xF0F8,0x4D,0x01}, +{0xF0F9,0x64,0x01}, +{0xF0FA,0xEE,0x01}, +{0xF0FB,0x62,0x01}, +{0xF0FC,0x16,0x01}, +{0xF0FD,0xAE,0x01}, +{0xF0FE,0x84,0x01}, +{0xF0FF,0x25,0x01}, +{0xF100,0x2E,0x01}, +{0xF101,0x8B,0x01}, +{0xF102,0x31,0x01}, +{0xF103,0xCD,0x01}, +{0xF104,0x6F,0x01}, +{0xF105,0x60,0x01}, +{0xF106,0xC3,0x01}, +{0xF107,0x19,0x01}, +{0xF108,0xC7,0x01}, +{0xF109,0x14,0x01}, +{0xF10A,0x26,0x01}, +{0xF10B,0x31,0x01}, +{0xF10C,0x97,0x01}, +{0xF10D,0x41,0x01}, +{0xF10E,0x8D,0x01}, +{0xF10F,0x6D,0x01}, +{0xF110,0x86,0x01}, +{0xF111,0xE3,0x01}, +{0xF112,0x9C,0x01}, +{0xF113,0xE2,0x01}, +{0xF114,0xD8,0x01}, +{0xF115,0x06,0x01}, +{0xF116,0x36,0x01}, +{0xF117,0xB5,0x01}, +{0xF118,0xE9,0x01}, +{0xF119,0x4D,0x01}, +{0xF11A,0x70,0x01}, +{0xF11B,0x68,0x01}, +{0xF11C,0x03,0x01}, +{0xF11D,0x00,0x01}, +{0xF11E,0x00,0x01}, +{0xF11F,0x00,0x01}, +{0xF120,0x00,0x01}, +{0xF121,0x00,0x01}, + + +//SHD TH +{0x6C32,0x1964,0x02}, // SHD_INP_TH_HB_H_R2 +{0x6C34,0x18CE,0x02}, // SHD_INP_TH_HB_L_R2 +{0x6C36,0x10CC,0x02}, // SHD_INP_TH_LB_H_R2 +{0x6C38,0x1004,0x02}, // SHD_INP_TH_LB_L_R2 +{0x6C3C,0x10CC,0x02}, // SHD_INP_TH_HB_H_RB +{0x6C3E,0x1004,0x02}, // SHD_INP_TH_HB_L_RB +{0x6C40,0x0000,0x02}, // SHD_INP_TH_LB_H_RB +{0x6C42,0x0000,0x02}, // SHD_INP_TH_LB_L_RB + +//PreWB_offset (for SHD2) +{0x6828,0x0013,0x02}, // SHD_PRER_OFFSET_R2 : +//PreWB_offset (for SHD3) +{0x682C,0x000D,0x02}, // SHD_PRER_OFFSET_RB : +{0x6830,0xFFFE,0x02}, // SHD_PREB_OFFSET_RB : + +// CXC/SHD EN +{0x01BC,0x57,0x01}, // CXC ON SHD ON INP ON GAIN OFF +}; + +static const isx012_regset_t ISX012_Shading_2[] = +{ +{0x01BC,0x50,0x01}, // CXC OFF SHD OFF +{0xEB00,0x8282,0x02}, //valid_code +{0xEB02,0xFE,0x01}, +{0xEB03,0x84,0x01}, +{0xEB04,0x3F,0x01}, +{0xEB05,0x01,0x01}, +{0xEB06,0x50,0x01}, +{0xEB07,0x08,0x01}, +{0xEB08,0x14,0x01}, +{0xEB09,0xFF,0x01}, +{0xEB0A,0x45,0x01}, +{0xEB0B,0x80,0x01}, +{0xEB0C,0x01,0x01}, +{0xEB0D,0x68,0x01}, +{0xEB0E,0x04,0x01}, +{0xEB0F,0x1A,0x01}, +{0xEB10,0x81,0x01}, +{0xEB11,0x86,0x01}, +{0xEB12,0x3F,0x01}, +{0xEB13,0xE1,0x01}, +{0xEB14,0x4F,0x01}, +{0xEB15,0x00,0x01}, +{0xEB16,0x14,0x01}, +{0xEB17,0x02,0x01}, +{0xEB18,0xC5,0x01}, +{0xEB19,0x7F,0x01}, +{0xEB1A,0x11,0x01}, +{0xEB1B,0x60,0x01}, +{0xEB1C,0x00,0x01}, +{0xEB1D,0x1A,0x01}, +{0xEB1E,0x81,0x01}, +{0xEB1F,0x46,0x01}, +{0xEB20,0xA0,0x01}, +{0xEB21,0x01,0x01}, +{0xEB22,0x48,0x01}, +{0xEB23,0x00,0x01}, +{0xEB24,0x12,0x01}, +{0xEB25,0x81,0x01}, +{0xEB26,0x05,0x01}, +{0xEB27,0x20,0x01}, +{0xEB28,0xF1,0x01}, +{0xEB29,0x4F,0x01}, +{0xEB2A,0x00,0x01}, +{0xEB2B,0x14,0x01}, +{0xEB2C,0x82,0x01}, +{0xEB2D,0x85,0x01}, +{0xEB2E,0x80,0x01}, +{0xEB2F,0x21,0x01}, +{0xEB30,0x60,0x01}, +{0xEB31,0x04,0x01}, +{0xEB32,0x12,0x01}, +{0xEB33,0x81,0x01}, +{0xEB34,0x84,0x01}, +{0xEB35,0xE0,0x01}, +{0xEB36,0x00,0x01}, +{0xEB37,0x28,0x01}, +{0xEB38,0x04,0x01}, +{0xEB39,0x0C,0x01}, +{0xEB3A,0x82,0x01}, +{0xEB3B,0x43,0x01}, +{0xEB3C,0x20,0x01}, +{0xEB3D,0x11,0x01}, +{0xEB3E,0x68,0x01}, +{0xEB3F,0x04,0x01}, +{0xEB40,0x1A,0x01}, +{0xEB41,0x82,0x01}, +{0xEB42,0x83,0x01}, +{0xEB43,0xE0,0x01}, +{0xEB44,0x00,0x01}, +{0xEB45,0x20,0x01}, +{0xEB46,0x00,0x01}, +{0xEB47,0x06,0x01}, +{0xEB48,0xFF,0x01}, +{0xEB49,0x41,0x01}, +{0xEB4A,0x80,0x01}, +{0xEB4B,0x10,0x01}, +{0xEB4C,0x30,0x01}, +{0xEB4D,0x08,0x01}, +{0xEB4E,0x14,0x01}, +{0xEB4F,0x02,0x01}, +{0xEB50,0x45,0x01}, +{0xEB51,0xC0,0x01}, +{0xEB52,0x10,0x01}, +{0xEB53,0x30,0x01}, +{0xEB54,0x04,0x01}, +{0xEB55,0x04,0x01}, +{0xEB56,0x01,0x01}, +{0xEB57,0xC0,0x01}, +{0xEB58,0x3F,0x01}, +{0xEB59,0x10,0x01}, +{0xEB5A,0x10,0x01}, +{0xEB5B,0x04,0x01}, +{0xEB5C,0x0A,0x01}, +{0xEB5D,0x80,0x01}, +{0xEB5E,0x03,0x01}, +{0xEB5F,0xE0,0x01}, +{0xEB60,0x10,0x01}, +{0xEB61,0x28,0x01}, +{0xEB62,0x04,0x01}, +{0xEB63,0x0A,0x01}, +{0xEB64,0x81,0x01}, +{0xEB65,0x01,0x01}, +{0xEB66,0x00,0x01}, +{0xEB67,0x10,0x01}, +{0xEB68,0x00,0x01}, +{0xEB69,0x04,0x01}, +{0xEB6A,0x04,0x01}, +{0xEB6B,0x01,0x01}, +{0xEB6C,0x42,0x01}, +{0xEB6D,0xE0,0x01}, +{0xEB6E,0x10,0x01}, +{0xEB6F,0x38,0x01}, +{0xEB70,0xFC,0x01}, +{0xEB71,0x0D,0x01}, +{0xEB72,0x7F,0x01}, +{0xEB73,0x43,0x01}, +{0xEB74,0x60,0x01}, +{0xEB75,0x00,0x01}, +{0xEB76,0x08,0x01}, +{0xEB77,0x08,0x01}, +{0xEB78,0x02,0x01}, +{0xEB79,0x81,0x01}, +{0xEB7A,0x41,0x01}, +{0xEB7B,0x80,0x01}, +{0xEB7C,0x10,0x01}, +{0xEB7D,0x30,0x01}, +{0xEB7E,0x04,0x01}, +{0xEB7F,0x0C,0x01}, +{0xEB80,0x01,0x01}, +{0xEB81,0x43,0x01}, +{0xEB82,0xC0,0x01}, +{0xEB83,0x20,0x01}, +{0xEB84,0x28,0x01}, +{0xEB85,0x08,0x01}, +{0xEB86,0x06,0x01}, +{0xEB87,0x02,0x01}, +{0xEB88,0xC2,0x01}, +{0xEB89,0xA0,0x01}, +{0xEB8A,0x30,0x01}, +{0xEB8B,0x30,0x01}, +{0xEB8C,0x0C,0x01}, +{0xEB8D,0x12,0x01}, +{0xEB8E,0x83,0x01}, +{0xEB8F,0x84,0x01}, +{0xEB90,0x00,0x01}, +{0xEB91,0x21,0x01}, +{0xEB92,0x40,0x01}, +{0xEB93,0x0C,0x01}, +{0xEB94,0x0C,0x01}, +{0xEB95,0x82,0x01}, +{0xEB96,0x03,0x01}, +{0xEB97,0xC1,0x01}, +{0xEB98,0x40,0x01}, +{0xEB99,0x40,0x01}, +{0xEB9A,0x08,0x01}, +{0xEB9B,0x10,0x01}, +{0xEB9C,0x03,0x01}, +{0xEB9D,0xC4,0x01}, +{0xEB9E,0x00,0x01}, +{0xEB9F,0x21,0x01}, +{0xEBA0,0x38,0x01}, +{0xEBA1,0x08,0x01}, +{0xEBA2,0x0E,0x01}, +{0xEBA3,0x82,0x01}, +{0xEBA4,0xC3,0x01}, +{0xEBA5,0x20,0x01}, +{0xEBA6,0x41,0x01}, +{0xEBA7,0x48,0x01}, +{0xEBA8,0x00,0x01}, +{0xEBA9,0x14,0x01}, +{0xEBAA,0x83,0x01}, +{0xEBAB,0x44,0x01}, +{0xEBAC,0x20,0x01}, +{0xEBAD,0x11,0x01}, +{0xEBAE,0x48,0x01}, +{0xEBAF,0x08,0x01}, +{0xEBB0,0x0E,0x01}, +{0xEBB1,0x82,0x01}, +{0xEBB2,0x83,0x01}, +{0xEBB3,0xE0,0x01}, +{0xEBB4,0x30,0x01}, +{0xEBB5,0x48,0x01}, +{0xEBB6,0x10,0x01}, +{0xEBB7,0x12,0x01}, +{0xEBB8,0x00,0x01}, +{0xEBB9,0xC5,0x01}, +{0xEBBA,0x20,0x01}, +{0xEBBB,0x11,0x01}, +{0xEBBC,0x48,0x01}, +{0xEBBD,0x04,0x01}, +{0xEBBE,0x12,0x01}, +{0xEBBF,0x04,0x01}, +{0xEBC0,0x3B,0x01}, +{0xEBC1,0xC1,0x01}, +{0xEBC2,0x1E,0x01}, +{0xEBC3,0xC8,0x01}, +{0xEBC4,0x0F,0x01}, +{0xEBC5,0xF8,0x01}, +{0xEBC6,0x02,0x01}, +{0xEBC7,0xBB,0x01}, +{0xEBC8,0x60,0x01}, +{0xEBC9,0x0F,0x01}, +{0xEBCA,0xB8,0x01}, +{0xEBCB,0x0F,0x01}, +{0xEBCC,0xEA,0x01}, +{0xEBCD,0x83,0x01}, +{0xEBCE,0x3A,0x01}, +{0xEBCF,0xC1,0x01}, +{0xEBD0,0x4E,0x01}, +{0xEBD1,0xB0,0x01}, +{0xEBD2,0x07,0x01}, +{0xEBD3,0xF2,0x01}, +{0xEBD4,0x03,0x01}, +{0xEBD5,0xBE,0x01}, +{0xEBD6,0xC0,0x01}, +{0xEBD7,0x2E,0x01}, +{0xEBD8,0xD8,0x01}, +{0xEBD9,0x03,0x01}, +{0xEBDA,0xEE,0x01}, +{0xEBDB,0x83,0x01}, +{0xEBDC,0xFA,0x01}, +{0xEBDD,0xA0,0x01}, +{0xEBDE,0x2E,0x01}, +{0xEBDF,0xB0,0x01}, +{0xEBE0,0x0B,0x01}, +{0xEBE1,0xEC,0x01}, +{0xEBE2,0x05,0x01}, +{0xEBE3,0xBD,0x01}, +{0xEBE4,0x60,0x01}, +{0xEBE5,0x2F,0x01}, +{0xEBE6,0xD0,0x01}, +{0xEBE7,0x07,0x01}, +{0xEBE8,0xEC,0x01}, +{0xEBE9,0x02,0x01}, +{0xEBEA,0xBC,0x01}, +{0xEBEB,0x40,0x01}, +{0xEBEC,0x2F,0x01}, +{0xEBED,0xD0,0x01}, +{0xEBEE,0x13,0x01}, +{0xEBEF,0xEE,0x01}, +{0xEBF0,0x84,0x01}, +{0xEBF1,0xBB,0x01}, +{0xEBF2,0x00,0x01}, +{0xEBF3,0x1F,0x01}, +{0xEBF4,0xC8,0x01}, +{0xEBF5,0xFF,0x01}, +{0xEBF6,0xEF,0x01}, +{0xEBF7,0x00,0x01}, +{0xEBF8,0x7D,0x01}, +{0xEBF9,0x60,0x01}, +{0xEBFA,0x2F,0x01}, +{0xEBFB,0xD0,0x01}, +{0xEBFC,0x0B,0x01}, +{0xEBFD,0xF4,0x01}, +{0xEBFE,0x85,0x01}, +{0xEBFF,0x7D,0x01}, +{0xEC00,0x61,0x01}, +{0xEC01,0x0F,0x01}, +{0xEC02,0xC0,0x01}, +{0xEC03,0xFF,0x01}, +{0xEC04,0xF7,0x01}, +{0xEC05,0x7F,0x01}, +{0xEC06,0x3D,0x01}, +{0xEC07,0x40,0x01}, +{0xEC08,0xFF,0x01}, +{0xEC09,0xDF,0x01}, +{0xEC0A,0x07,0x01}, +{0xEC0B,0xFA,0x01}, +{0xEC0C,0x81,0x01}, +{0xEC0D,0x3E,0x01}, +{0xEC0E,0x61,0x01}, +{0xEC0F,0x4F,0x01}, +{0xEC10,0xD8,0x01}, +{0xEC11,0x0B,0x01}, +{0xEC12,0xFC,0x01}, +{0xEC13,0xFE,0x01}, +{0xEC14,0x3D,0x01}, +{0xEC15,0xC0,0x01}, +{0xEC16,0xFF,0x01}, +{0xEC17,0xFF,0x01}, +{0xEC18,0x03,0x01}, +{0xEC19,0xFC,0x01}, +{0xEC1A,0x82,0x01}, +{0xEC1B,0xBE,0x01}, +{0xEC1C,0xA0,0x01}, +{0xEC1D,0x6F,0x01}, +{0xEC1E,0xF8,0x01}, +{0xEC1F,0x1B,0x01}, +{0xEC20,0xFE,0x01}, +{0xEC21,0x83,0x01}, +{0xEC22,0xBF,0x01}, +{0xEC23,0xE0,0x01}, +{0xEC24,0x0F,0x01}, +{0xEC25,0x10,0x01}, +{0xEC26,0x00,0x01}, +{0xEC27,0x00,0x01}, +{0xEC28,0x82,0x01}, +{0xEC29,0xC0,0x01}, +{0xEC2A,0x60,0x01}, +{0xEC2B,0x30,0x01}, +{0xEC2C,0x18,0x01}, +{0xEC2D,0x20,0x01}, +{0xEC2E,0x04,0x01}, +{0xEC2F,0x08,0x01}, +{0xEC30,0x81,0x01}, +{0xEC31,0x21,0x01}, +{0xEC32,0x30,0x01}, +{0xEC33,0x08,0x01}, +{0xEC34,0x08,0x01}, +{0xEC35,0x08,0x01}, +{0xEC36,0x82,0x01}, +{0xEC37,0x01,0x01}, +{0xEC38,0x81,0x01}, +{0xEC39,0x50,0x01}, +{0xEC3A,0x08,0x01}, +{0xEC3B,0x14,0x01}, +{0xEC3C,0x02,0x01}, +{0xEC3D,0x09,0x01}, +{0xEC3E,0x41,0x01}, +{0xEC3F,0x42,0x01}, +{0xEC40,0x70,0x01}, +{0xEC41,0x20,0x01}, +{0xEC42,0x0C,0x01}, +{0xEC43,0x06,0x01}, +{0xEC44,0x84,0x01}, +{0xEC45,0x42,0x01}, +{0xEC46,0xE1,0x01}, +{0xEC47,0x40,0x01}, +{0xEC48,0x38,0x01}, +{0xEC49,0x1C,0x01}, +{0xEC4A,0x0C,0x01}, +{0xEC4B,0x07,0x01}, +{0xEC4C,0x03,0x01}, +{0xEC4D,0xA2,0x01}, +{0xEC4E,0x80,0x01}, +{0xEC4F,0x28,0x01}, +{0xEC50,0x18,0x01}, +{0xEC51,0x10,0x01}, +{0xEC52,0x87,0x01}, +{0xEC53,0x43,0x01}, +{0xEC54,0x61,0x01}, +{0xEC55,0x41,0x01}, +{0xEC56,0x48,0x01}, +{0xEC57,0x14,0x01}, +{0xEC58,0x10,0x01}, +{0xEC59,0x07,0x01}, +{0xEC5A,0xC2,0x01}, +{0xEC5B,0x81,0x01}, +{0xEC5C,0x80,0x01}, +{0xEC5D,0x30,0x01}, +{0xEC5E,0x20,0x01}, +{0xEC5F,0x0C,0x01}, +{0xEC60,0x87,0x01}, +{0xEC61,0x83,0x01}, +{0xEC62,0xC1,0x01}, +{0xEC63,0x40,0x01}, +{0xEC64,0x38,0x01}, +{0xEC65,0x14,0x01}, +{0xEC66,0x0A,0x01}, +{0xEC67,0x07,0x01}, +{0xEC68,0xC3,0x01}, +{0xEC69,0xC1,0x01}, +{0xEC6A,0x70,0x01}, +{0xEC6B,0x30,0x01}, +{0xEC6C,0x20,0x01}, +{0xEC6D,0x0C,0x01}, +{0xEC6E,0x08,0x01}, +{0xEC6F,0xC3,0x01}, +{0xEC70,0xE1,0x01}, +{0xEC71,0x60,0x01}, +{0xEC72,0x30,0x01}, +{0xEC73,0x10,0x01}, +{0xEC74,0x0E,0x01}, +{0xEC75,0x85,0x01}, +{0xEC76,0xC2,0x01}, +{0xEC77,0xC1,0x01}, +{0xEC78,0x70,0x01}, +{0xEC79,0x30,0x01}, +{0xEC7A,0x1C,0x01}, +{0xEC7B,0x0C,0x01}, + +//SHD1(from CO1) +{0xED02,0xE6,0x01}, +{0xED03,0xD9,0x01}, +{0xED04,0x92,0x01}, +{0xED05,0x7C,0x01}, +{0xED06,0xD8,0x01}, +{0xED07,0xB4,0x01}, +{0xED08,0x1E,0x01}, +{0xED09,0x32,0x01}, +{0xED0A,0x75,0x01}, +{0xED0B,0x67,0x01}, +{0xED0C,0x4A,0x01}, +{0xED0D,0xD7,0x01}, +{0xED0E,0xA9,0x01}, +{0xED0F,0x12,0x01}, +{0xED10,0x76,0x01}, +{0xED11,0xBC,0x01}, +{0xED12,0x34,0x01}, +{0xED13,0x1E,0x01}, +{0xED14,0x37,0x01}, +{0xED15,0xA1,0x01}, +{0xED16,0x87,0x01}, +{0xED17,0x4E,0x01}, +{0xED18,0xDE,0x01}, +{0xED19,0x41,0x01}, +{0xED1A,0xD3,0x01}, +{0xED1B,0x77,0x01}, +{0xED1C,0x8C,0x01}, +{0xED1D,0x94,0x01}, +{0xED1E,0x9C,0x01}, +{0xED1F,0x14,0x01}, +{0xED20,0xC9,0x01}, +{0xED21,0xA6,0x01}, +{0xED22,0x41,0x01}, +{0xED23,0xA2,0x01}, +{0xED24,0xC1,0x01}, +{0xED25,0x8F,0x01}, +{0xED26,0x66,0x01}, +{0xED27,0xE6,0x01}, +{0xED28,0xF3,0x01}, +{0xED29,0x19,0x01}, +{0xED2A,0xFF,0x01}, +{0xED2B,0xB0,0x01}, +{0xED2C,0x66,0x01}, +{0xED2D,0x42,0x01}, +{0xED2E,0xC1,0x01}, +{0xED2F,0x91,0x01}, +{0xED30,0x91,0x01}, +{0xED31,0x75,0x01}, +{0xED32,0xA2,0x01}, +{0xED33,0x74,0x01}, +{0xED34,0x1C,0x01}, +{0xED35,0x0F,0x01}, +{0xED36,0x91,0x01}, +{0xED37,0x26,0x01}, +{0xED38,0x3E,0x01}, +{0xED39,0x87,0x01}, +{0xED3A,0x51,0x01}, +{0xED3B,0x4E,0x01}, +{0xED3C,0x5C,0x01}, +{0xED3D,0x54,0x01}, +{0xED3E,0x83,0x01}, +{0xED3F,0x96,0x01}, +{0xED40,0xD0,0x01}, +{0xED41,0xBC,0x01}, +{0xED42,0xA5,0x01}, +{0xED43,0x35,0x01}, +{0xED44,0x83,0x01}, +{0xED45,0x61,0x01}, +{0xED46,0xCE,0x01}, +{0xED47,0x67,0x01}, +{0xED48,0xF2,0x01}, +{0xED49,0x33,0x01}, +{0xED4A,0x1C,0x01}, +{0xED4B,0x1A,0x01}, +{0xED4C,0xC1,0x01}, +{0xED4D,0x46,0x01}, +{0xED4E,0x3F,0x01}, +{0xED4F,0x83,0x01}, +{0xED50,0xD9,0x01}, +{0xED51,0x0D,0x01}, +{0xED52,0x57,0x01}, +{0xED53,0x06,0x01}, +{0xED54,0x23,0x01}, +{0xED55,0x14,0x01}, +{0xED56,0xAF,0x01}, +{0xED57,0xE4,0x01}, +{0xED58,0x64,0x01}, +{0xED59,0x2A,0x01}, +{0xED5A,0x43,0x01}, +{0xED5B,0x01,0x01}, +{0xED5C,0xCB,0x01}, +{0xED5D,0x56,0x01}, +{0xED5E,0x10,0x01}, +{0xED5F,0x03,0x01}, +{0xED60,0x18,0x01}, +{0xED61,0xE4,0x01}, +{0xED62,0xA8,0x01}, +{0xED63,0xE6,0x01}, +{0xED64,0x41,0x01}, +{0xED65,0x9E,0x01}, +{0xED66,0xE1,0x01}, +{0xED67,0xCE,0x01}, +{0xED68,0x59,0x01}, +{0xED69,0x20,0x01}, +{0xED6A,0xB3,0x01}, +{0xED6B,0x13,0x01}, +{0xED6C,0xA8,0x01}, +{0xED6D,0x74,0x01}, +{0xED6E,0x04,0x01}, +{0xED6F,0x25,0x01}, +{0xED70,0x13,0x01}, +{0xED71,0xE1,0x01}, +{0xED72,0xC8,0x01}, +{0xED73,0x47,0x01}, +{0xED74,0x56,0x01}, +{0xED75,0xD2,0x01}, +{0xED76,0x13,0x01}, +{0xED77,0xAB,0x01}, +{0xED78,0x98,0x01}, +{0xED79,0x25,0x01}, +{0xED7A,0x33,0x01}, +{0xED7B,0x9A,0x01}, +{0xED7C,0x49,0x01}, +{0xED7D,0xCF,0x01}, +{0xED7E,0x64,0x01}, +{0xED7F,0x96,0x01}, +{0xED80,0x73,0x01}, +{0xED81,0x95,0x01}, +{0xED82,0xBC,0x01}, +{0xED83,0xA4,0x01}, +{0xED84,0xC4,0x01}, +{0xED85,0x26,0x01}, +{0xED86,0x0A,0x01}, +{0xED87,0x59,0x01}, +{0xED88,0x08,0x01}, +{0xED89,0x40,0x01}, +{0xED8A,0x00,0x01}, +{0xED8B,0xC2,0x01}, +{0xED8C,0x10,0x01}, +{0xED8D,0x88,0x01}, +{0xED8E,0xB0,0x01}, +{0xED8F,0xA4,0x01}, +{0xED90,0x27,0x01}, +{0xED91,0x59,0x01}, +{0xED92,0xF9,0x01}, +{0xED93,0x0B,0x01}, +{0xED94,0x64,0x01}, +{0xED95,0xA8,0x01}, +{0xED96,0x43,0x01}, +{0xED97,0x19,0x01}, +{0xED98,0xE6,0x01}, +{0xED99,0x68,0x01}, +{0xED9A,0x45,0x01}, +{0xED9B,0x2F,0x01}, +{0xED9C,0x2B,0x01}, +{0xED9D,0xB9,0x01}, +{0xED9E,0xC9,0x01}, +{0xED9F,0x42,0x01}, +{0xEDA0,0x18,0x01}, +{0xEDA1,0x32,0x01}, +{0xEDA2,0x90,0x01}, +{0xEDA3,0x80,0x01}, +{0xEDA4,0x3C,0x01}, +{0xEDA5,0x44,0x01}, +{0xEDA6,0x22,0x01}, +{0xEDA7,0x2F,0x01}, +{0xEDA8,0xF1,0x01}, +{0xEDA9,0x09,0x01}, +{0xEDAA,0x57,0x01}, +{0xEDAB,0x04,0x01}, +{0xEDAC,0x53,0x01}, +{0xEDAD,0x99,0x01}, +{0xEDAE,0xEC,0x01}, +{0xEDAF,0x90,0x01}, +{0xEDB0,0x66,0x01}, +{0xEDB1,0x3C,0x01}, +{0xEDB2,0x6D,0x01}, +{0xEDB3,0xA9,0x01}, +{0xEDB4,0x4C,0x01}, +{0xEDB5,0x50,0x01}, +{0xEDB6,0xA6,0x01}, +{0xEDB7,0x32,0x01}, +{0xEDB8,0x12,0x01}, +{0xEDB9,0x94,0x01}, +{0xEDBA,0x64,0x01}, +{0xEDBB,0xA4,0x01}, +{0xEDBC,0x23,0x01}, +{0xEDBD,0x25,0x01}, +{0xEDBE,0x71,0x01}, +{0xEDBF,0x49,0x01}, +{0xEDC0,0x51,0x01}, +{0xEDC1,0xB4,0x01}, +{0xEDC2,0x02,0x01}, +{0xEDC3,0x17,0x01}, +{0xEDC4,0xCE,0x01}, +{0xEDC5,0x98,0x01}, +{0xEDC6,0x06,0x01}, +{0xEDC7,0x3E,0x01}, +{0xEDC8,0xBC,0x01}, +{0xEDC9,0x31,0x01}, +{0xEDCA,0x50,0x01}, +{0xEDCB,0x63,0x01}, +{0xEDCC,0x86,0x01}, +{0xEDCD,0x63,0x01}, +{0xEDCE,0x16,0x01}, +{0xEDCF,0xC4,0x01}, +{0xEDD0,0x2C,0x01}, +{0xEDD1,0x45,0x01}, +{0xEDD2,0x2C,0x01}, +{0xEDD3,0x43,0x01}, +{0xEDD4,0xB9,0x01}, +{0xEDD5,0x4A,0x01}, +{0xEDD6,0x53,0x01}, +{0xEDD7,0xCE,0x01}, +{0xEDD8,0x82,0x01}, +{0xEDD9,0x96,0x01}, +{0xEDDA,0xC8,0x01}, +{0xEDDB,0x40,0x01}, +{0xEDDC,0x06,0x01}, +{0xEDDD,0x3A,0x01}, +{0xEDDE,0xBE,0x01}, +{0xEDDF,0xC1,0x01}, +{0xEDE0,0xD0,0x01}, +{0xEDE1,0x75,0x01}, +{0xEDE2,0x64,0x01}, +{0xEDE3,0x34,0x01}, +{0xEDE4,0x9B,0x01}, +{0xEDE5,0xFE,0x01}, +{0xEDE6,0x4C,0x01}, +{0xEDE7,0xA6,0x01}, +{0xEDE8,0x39,0x01}, +{0xEDE9,0x7D,0x01}, +{0xEDEA,0x89,0x01}, +{0xEDEB,0x8D,0x01}, +{0xEDEC,0x5D,0x01}, +{0xEDED,0x4A,0x01}, +{0xEDEE,0xE3,0x01}, +{0xEDEF,0x97,0x01}, +{0xEDF0,0xDA,0x01}, +{0xEDF1,0x50,0x01}, +{0xEDF2,0xE6,0x01}, +{0xEDF3,0x3A,0x01}, +{0xEDF4,0xB3,0x01}, +{0xEDF5,0x39,0x01}, +{0xEDF6,0x50,0x01}, +{0xEDF7,0x76,0x01}, +{0xEDF8,0x7A,0x01}, +{0xEDF9,0xF4,0x01}, +{0xEDFA,0x9E,0x01}, +{0xEDFB,0x2A,0x01}, +{0xEDFC,0x61,0x01}, +{0xEDFD,0x87,0x01}, +{0xEDFE,0x46,0x01}, +{0xEDFF,0xC0,0x01}, +{0xEE00,0x99,0x01}, +{0xEE01,0xD0,0x01}, +{0xEE02,0x6B,0x01}, +{0xEE03,0x02,0x01}, +{0xEE04,0x94,0x01}, +{0xEE05,0x1A,0x01}, +{0xEE06,0xFD,0x01}, +{0xEE07,0xB8,0x01}, +{0xEE08,0xE6,0x01}, +{0xEE09,0x40,0x01}, +{0xEE0A,0xC0,0x01}, +{0xEE0B,0xF1,0x01}, +{0xEE0C,0xD0,0x01}, +{0xEE0D,0x75,0x01}, +{0xEE0E,0x80,0x01}, +{0xEE0F,0xE4,0x01}, +{0xEE10,0x9E,0x01}, +{0xEE11,0x33,0x01}, +{0xEE12,0xE1,0x01}, +{0xEE13,0xA7,0x01}, +{0xEE14,0x4B,0x01}, +{0xEE15,0xFD,0x01}, +{0xEE16,0x21,0x01}, +{0xEE17,0x53,0x01}, +{0xEE18,0x7C,0x01}, +{0xEE19,0xAE,0x01}, +{0xEE1A,0x64,0x01}, +{0xEE1B,0x9E,0x01}, +{0xEE1C,0x26,0x01}, +{0xEE1D,0x89,0x01}, +{0xEE1E,0xC7,0x01}, +{0xEE1F,0x49,0x01}, +{0xEE20,0xE4,0x01}, +{0xEE21,0x99,0x01}, +{0xEE22,0x12,0x01}, +{0xEE23,0x7D,0x01}, +{0xEE24,0xCA,0x01}, +{0xEE25,0xB4,0x01}, +{0xEE26,0x9F,0x01}, +{0xEE27,0x37,0x01}, +{0xEE28,0xC5,0x01}, +{0xEE29,0x47,0x01}, +{0xEE2A,0x4D,0x01}, +{0xEE2B,0xC2,0x01}, +{0xEE2C,0x19,0x01}, +{0xEE2D,0x0F,0x01}, +{0xEE2E,0x73,0x01}, +{0xEE2F,0xE2,0x01}, +{0xEE30,0x13,0x01}, +{0xEE31,0x1C,0x01}, +{0xEE32,0xF5,0x01}, +{0xEE33,0xE0,0x01}, +{0xEE34,0xC6,0x01}, +{0xEE35,0x3B,0x01}, +{0xEE36,0xB6,0x01}, +{0xEE37,0xB1,0x01}, +{0xEE38,0xCE,0x01}, +{0xEE39,0x6D,0x01}, +{0xEE3A,0xB8,0x01}, +{0xEE3B,0xF3,0x01}, +{0xEE3C,0x9B,0x01}, +{0xEE3D,0xF2,0x01}, +{0xEE3E,0x18,0x01}, +{0xEE3F,0x27,0x01}, +{0xEE40,0x3D,0x01}, +{0xEE41,0xBF,0x01}, +{0xEE42,0xE9,0x01}, +{0xEE43,0xCE,0x01}, +{0xEE44,0x6E,0x01}, +{0xEE45,0xBA,0x01}, +{0xEE46,0x83,0x01}, +{0xEE47,0x9A,0x01}, +{0xEE48,0xE4,0x01}, +{0xEE49,0x50,0x01}, +{0xEE4A,0x66,0x01}, +{0xEE4B,0x36,0x01}, +{0xEE4C,0x8A,0x01}, +{0xEE4D,0x29,0x01}, +{0xEE4E,0x4D,0x01}, +{0xEE4F,0x61,0x01}, +{0xEE50,0x3A,0x01}, +{0xEE51,0xA3,0x01}, +{0xEE52,0x18,0x01}, +{0xEE53,0xD2,0x01}, +{0xEE54,0x50,0x01}, +{0xEE55,0x26,0x01}, +{0xEE56,0x36,0x01}, +{0xEE57,0xA8,0x01}, +{0xEE58,0x21,0x01}, +{0xEE59,0xCE,0x01}, +{0xEE5A,0x6E,0x01}, +{0xEE5B,0xB2,0x01}, +{0xEE5C,0x03,0x01}, +{0xEE5D,0x9A,0x01}, +{0xEE5E,0xE0,0x01}, +{0xEE5F,0x1C,0x01}, +{0xEE60,0x46,0x01}, +{0xEE61,0x34,0x01}, +{0xEE62,0x72,0x01}, +{0xEE63,0x41,0x01}, +{0xEE64,0x8C,0x01}, +{0xEE65,0x58,0x01}, +{0xEE66,0xE8,0x01}, +{0xEE67,0xC2,0x01}, +{0xEE68,0x95,0x01}, +{0xEE69,0xB5,0x01}, +{0xEE6A,0x88,0x01}, +{0xEE6B,0x65,0x01}, +{0xEE6C,0x2E,0x01}, +{0xEE6D,0x72,0x01}, +{0xEE6E,0x39,0x01}, +{0xEE6F,0x8C,0x01}, +{0xEE70,0x62,0x01}, +{0xEE71,0x48,0x01}, +{0xEE72,0x83,0x01}, +{0xEE73,0x1A,0x01}, +{0xEE74,0xE4,0x01}, +{0xEE75,0x28,0x01}, +{0xEE76,0x06,0x01}, +{0xEE77,0x35,0x01}, +{0xEE78,0x6A,0x01}, +{0xEE79,0xF9,0x01}, +{0xEE7A,0x4B,0x01}, +{0xEE7B,0x53,0x01}, +{0xEE7C,0xB8,0x01}, +{0xEE7D,0x92,0x01}, +{0xEE7E,0x13,0x01}, +{0xEE7F,0xA2,0x01}, +{0xEE80,0xCC,0x01}, +{0xEE81,0x64,0x01}, +{0xEE82,0x27,0x01}, +{0xEE83,0x3B,0x01}, +{0xEE84,0x29,0x01}, +{0xEE85,0x0A,0x01}, +{0xEE86,0x54,0x01}, +{0xEE87,0xBC,0x01}, +{0xEE88,0xF2,0x01}, +{0xEE89,0x96,0x01}, +{0xEE8A,0xC1,0x01}, +{0xEE8B,0x40,0x01}, +{0xEE8C,0xA6,0x01}, +{0xEE8D,0x35,0x01}, +{0xEE8E,0x7A,0x01}, +{0xEE8F,0xB1,0x01}, +{0xEE90,0x8C,0x01}, +{0xEE91,0x54,0x01}, +{0xEE92,0xC8,0x01}, +{0xEE93,0xF2,0x01}, +{0xEE94,0x92,0x01}, +{0xEE95,0x9D,0x01}, +{0xEE96,0x64,0x01}, +{0xEE97,0xE4,0x01}, +{0xEE98,0x23,0x01}, +{0xEE99,0x13,0x01}, +{0xEE9A,0xA9,0x01}, +{0xEE9B,0x48,0x01}, +{0xEE9C,0x47,0x01}, +{0xEE9D,0x40,0x01}, +{0xEE9E,0x42,0x01}, +{0xEE9F,0x13,0x01}, +{0xEEA0,0x9F,0x01}, +{0xEEA1,0x58,0x01}, +{0xEEA2,0xE5,0x01}, +{0xEEA3,0x2C,0x01}, +{0xEEA4,0x7F,0x01}, +{0xEEA5,0xD9,0x01}, +{0xEEA6,0x8C,0x01}, +{0xEEA7,0x5B,0x01}, +{0xEEA8,0x12,0x01}, +{0xEEA9,0x43,0x01}, +{0xEEAA,0x14,0x01}, +{0xEEAB,0xAA,0x01}, +{0xEEAC,0x80,0x01}, +{0xEEAD,0x04,0x01}, +{0xEEAE,0x25,0x01}, +{0xEEAF,0x06,0x01}, +{0xEEB0,0x51,0x01}, +{0xEEB1,0x08,0x01}, +{0xEEB2,0x40,0x01}, +{0xEEB3,0x00,0x01}, +{0xEEB4,0xB2,0x01}, +{0xEEB5,0x10,0x01}, +{0xEEB6,0x86,0x01}, +{0xEEB7,0x98,0x01}, +{0xEEB8,0x64,0x01}, +{0xEEB9,0x25,0x01}, +{0xEEBA,0x4A,0x01}, +{0xEEBB,0xB9,0x01}, +{0xEEBC,0x0A,0x01}, +{0xEEBD,0x5D,0x01}, +{0xEEBE,0x1C,0x01}, +{0xEEBF,0x13,0x01}, +{0xEEC0,0x97,0x01}, +{0xEEC1,0xC4,0x01}, +{0xEEC2,0x18,0x01}, +{0xEEC3,0x85,0x01}, +{0xEEC4,0x2A,0x01}, +{0xEEC5,0x21,0x01}, +{0xEEC6,0x41,0x01}, +{0xEEC7,0xC9,0x01}, +{0xEEC8,0x41,0x01}, +{0xEEC9,0x12,0x01}, +{0xEECA,0x02,0x01}, +{0xEECB,0x10,0x01}, +{0xEECC,0x80,0x01}, +{0xEECD,0x2C,0x01}, +{0xEECE,0x64,0x01}, +{0xEECF,0x21,0x01}, +{0xEED0,0x27,0x01}, +{0xEED1,0x61,0x01}, +{0xEED2,0xC9,0x01}, +{0xEED3,0x52,0x01}, +{0xEED4,0xB0,0x01}, +{0xEED5,0x42,0x01}, +{0xEED6,0x17,0x01}, +{0xEED7,0xC8,0x01}, +{0xEED8,0x04,0x01}, +{0xEED9,0xE6,0x01}, +{0xEEDA,0x32,0x01}, +{0xEEDB,0x58,0x01}, +{0xEEDC,0x29,0x01}, +{0xEEDD,0xCB,0x01}, +{0xEEDE,0x4C,0x01}, +{0xEEDF,0x74,0x01}, +{0xEEE0,0x92,0x01}, +{0xEEE1,0x91,0x01}, +{0xEEE2,0x8E,0x01}, +{0xEEE3,0x48,0x01}, +{0xEEE4,0x84,0x01}, +{0xEEE5,0x22,0x01}, +{0xEEE6,0x1D,0x01}, +{0xEEE7,0x01,0x01}, +{0xEEE8,0xC9,0x01}, +{0xEEE9,0x4D,0x01}, +{0xEEEA,0x7E,0x01}, +{0xEEEB,0x82,0x01}, +{0xEEEC,0x15,0x01}, +{0xEEED,0xB5,0x01}, +{0xEEEE,0x04,0x01}, +{0xEEEF,0xE6,0x01}, +{0xEEF0,0x33,0x01}, +{0xEEF1,0x99,0x01}, +{0xEEF2,0x69,0x01}, +{0xEEF3,0x0D,0x01}, +{0xEEF4,0x5D,0x01}, +{0xEEF5,0x06,0x01}, +{0xEEF6,0x33,0x01}, +{0xEEF7,0x15,0x01}, +{0xEEF8,0xAF,0x01}, +{0xEEF9,0xEC,0x01}, +{0xEEFA,0xA4,0x01}, +{0xEEFB,0x28,0x01}, +{0xEEFC,0x35,0x01}, +{0xEEFD,0xE9,0x01}, +{0xEEFE,0x09,0x01}, +{0xEEFF,0x4F,0x01}, +{0xEF00,0x8E,0x01}, +{0xEF01,0x02,0x01}, +{0xEF02,0x95,0x01}, +{0xEF03,0xB1,0x01}, +{0xEF04,0xC4,0x01}, +{0xEF05,0x25,0x01}, +{0xEF06,0x31,0x01}, +{0xEF07,0x94,0x01}, +{0xEF08,0xB1,0x01}, +{0xEF09,0x4D,0x01}, +{0xEF0A,0x6C,0x01}, +{0xEF0B,0x94,0x01}, +{0xEF0C,0x43,0x01}, +{0xEF0D,0x99,0x01}, +{0xEF0E,0xD4,0x01}, +{0xEF0F,0xEC,0x01}, +{0xEF10,0xC5,0x01}, +{0xEF11,0x31,0x01}, +{0xEF12,0x69,0x01}, +{0xEF13,0xC9,0x01}, +{0xEF14,0x0B,0x01}, +{0xEF15,0x58,0x01}, +{0xEF16,0xE6,0x01}, +{0xEF17,0x52,0x01}, +{0xEF18,0x16,0x01}, +{0xEF19,0xBE,0x01}, +{0xEF1A,0xD4,0x01}, +{0xEF1B,0x45,0x01}, +{0xEF1C,0x32,0x01}, +{0xEF1D,0x8E,0x01}, +{0xEF1E,0x79,0x01}, +{0xEF1F,0x4D,0x01}, +{0xEF20,0x6A,0x01}, +{0xEF21,0xA4,0x01}, +{0xEF22,0x83,0x01}, +{0xEF23,0x1C,0x01}, +{0xEF24,0xF2,0x01}, +{0xEF25,0xDC,0x01}, +{0xEF26,0x26,0x01}, +{0xEF27,0x3A,0x01}, +{0xEF28,0xA3,0x01}, +{0xEF29,0xE1,0x01}, +{0xEF2A,0x4D,0x01}, +{0xEF2B,0x65,0x01}, +{0xEF2C,0x5C,0x01}, +{0xEF2D,0xC3,0x01}, +{0xEF2E,0x98,0x01}, +{0xEF2F,0xD4,0x01}, +{0xEF30,0x3C,0x01}, +{0xEF31,0xE6,0x01}, +{0xEF32,0x35,0x01}, +{0xEF33,0x9D,0x01}, +{0xEF34,0x09,0x01}, +{0xEF35,0x8E,0x01}, +{0xEF36,0x6B,0x01}, +{0xEF37,0xAC,0x01}, +{0xEF38,0xE3,0x01}, +{0xEF39,0x9B,0x01}, +{0xEF3A,0xF4,0x01}, +{0xEF3B,0x34,0x01}, +{0xEF3C,0x07,0x01}, +{0xEF3D,0x3E,0x01}, +{0xEF3E,0xDA,0x01}, +{0xEF3F,0xC1,0x01}, +{0xEF40,0x8F,0x01}, +{0xEF41,0x74,0x01}, +{0xEF42,0xEA,0x01}, +{0xEF43,0x13,0x01}, +{0xEF44,0x9C,0x01}, +{0xEF45,0xF4,0x01}, +{0xEF46,0xF0,0x01}, +{0xEF47,0xA6,0x01}, +{0xEF48,0x3C,0x01}, +{0xEF49,0xC0,0x01}, +{0xEF4A,0x49,0x01}, +{0xEF4B,0x0F,0x01}, +{0xEF4C,0x72,0x01}, +{0xEF4D,0xEA,0x01}, +{0xEF4E,0xD3,0x01}, +{0xEF4F,0x9C,0x01}, +{0xEF50,0xFE,0x01}, +{0xEF51,0x04,0x01}, +{0xEF52,0xA7,0x01}, +{0xEF53,0x3D,0x01}, + +//SHD2 CW+TL84 33:66 + +{0xED00,0x9191,0x02},// +{0xEF54,0x2F,0x01}, +{0xEF55,0xF2,0x01}, +{0xEF56,0x51,0x01}, +{0xEF57,0x8D,0x01}, +{0xEF58,0x50,0x01}, +{0xEF59,0x74,0x01}, +{0xEF5A,0xA2,0x01}, +{0xEF5B,0x14,0x01}, +{0xEF5C,0xE1,0x01}, +{0xEF5D,0xC8,0x01}, +{0xEF5E,0x47,0x01}, +{0xEF5F,0x2E,0x01}, +{0xEF60,0xD2,0x01}, +{0xEF61,0x10,0x01}, +{0xEF62,0x80,0x01}, +{0xEF63,0xC8,0x01}, +{0xEF64,0x13,0x01}, +{0xEF65,0x9D,0x01}, +{0xEF66,0xE5,0x01}, +{0xEF67,0x48,0x01}, +{0xEF68,0x87,0x01}, +{0xEF69,0x3C,0x01}, +{0xEF6A,0xFE,0x01}, +{0xEF6B,0xC9,0x01}, +{0xEF6C,0x50,0x01}, +{0xEF6D,0x7D,0x01}, +{0xEF6E,0x96,0x01}, +{0xEF6F,0x83,0x01}, +{0xEF70,0x9A,0x01}, +{0xEF71,0xC6,0x01}, +{0xEF72,0x10,0x01}, +{0xEF73,0xA6,0x01}, +{0xEF74,0x31,0x01}, +{0xEF75,0xA5,0x01}, +{0xEF76,0x61,0x01}, +{0xEF77,0xCE,0x01}, +{0xEF78,0x7F,0x01}, +{0xEF79,0xA4,0x01}, +{0xEF7A,0xD3,0x01}, +{0xEF7B,0x19,0x01}, +{0xEF7C,0xB6,0x01}, +{0xEF7D,0x38,0x01}, +{0xEF7E,0xA5,0x01}, +{0xEF7F,0x28,0x01}, +{0xEF80,0x4E,0x01}, +{0xEF81,0x69,0x01}, +{0xEF82,0x4B,0x01}, +{0xEF83,0x68,0x01}, +{0xEF84,0xBA,0x01}, +{0xEF85,0x93,0x01}, +{0xEF86,0x1B,0x01}, +{0xEF87,0xBC,0x01}, +{0xEF88,0x0C,0x01}, +{0xEF89,0x65,0x01}, +{0xEF8A,0x24,0x01}, +{0xEF8B,0x17,0x01}, +{0xEF8C,0x19,0x01}, +{0xEF8D,0x49,0x01}, +{0xEF8E,0x51,0x01}, +{0xEF8F,0xF6,0x01}, +{0xEF90,0xE2,0x01}, +{0xEF91,0x1B,0x01}, +{0xEF92,0xD5,0x01}, +{0xEF93,0x98,0x01}, +{0xEF94,0xC5,0x01}, +{0xEF95,0x25,0x01}, +{0xEF96,0x0B,0x01}, +{0xEF97,0x01,0x01}, +{0xEF98,0x48,0x01}, +{0xEF99,0x43,0x01}, +{0xEF9A,0x64,0x01}, +{0xEF9B,0x72,0x01}, +{0xEF9C,0x96,0x01}, +{0xEF9D,0xD6,0x01}, +{0xEF9E,0xA8,0x01}, +{0xEF9F,0xE6,0x01}, +{0xEFA0,0x2C,0x01}, +{0xEFA1,0x30,0x01}, +{0xEFA2,0x51,0x01}, +{0xEFA3,0x48,0x01}, +{0xEFA4,0x40,0x01}, +{0xEFA5,0x1C,0x01}, +{0xEFA6,0x22,0x01}, +{0xEFA7,0x93,0x01}, +{0xEFA8,0xB4,0x01}, +{0xEFA9,0xC8,0x01}, +{0xEFAA,0xA6,0x01}, +{0xEFAB,0x37,0x01}, +{0xEFAC,0x7C,0x01}, +{0xEFAD,0x29,0x01}, +{0xEFAE,0x8A,0x01}, +{0xEFAF,0x48,0x01}, +{0xEFB0,0x30,0x01}, +{0xEFB1,0x62,0x01}, +{0xEFB2,0x12,0x01}, +{0xEFB3,0xA4,0x01}, +{0xEFB4,0xF8,0x01}, +{0xEFB5,0x65,0x01}, +{0xEFB6,0x38,0x01}, +{0xEFB7,0xDB,0x01}, +{0xEFB8,0x11,0x01}, +{0xEFB9,0x0D,0x01}, +{0xEFBA,0x5C,0x01}, +{0xEFBB,0xA0,0x01}, +{0xEFBC,0x72,0x01}, +{0xEFBD,0x94,0x01}, +{0xEFBE,0xA9,0x01}, +{0xEFBF,0xD0,0x01}, +{0xEFC0,0x05,0x01}, +{0xEFC1,0x35,0x01}, +{0xEFC2,0xE5,0x01}, +{0xEFC3,0x11,0x01}, +{0xEFC4,0xD0,0x01}, +{0xEFC5,0x74,0x01}, +{0xEFC6,0x52,0x01}, +{0xEFC7,0x03,0x01}, +{0xEFC8,0x19,0x01}, +{0xEFC9,0xC3,0x01}, +{0xEFCA,0x48,0x01}, +{0xEFCB,0xC6,0x01}, +{0xEFCC,0x35,0x01}, +{0xEFCD,0xD7,0x01}, +{0xEFCE,0x41,0x01}, +{0xEFCF,0x10,0x01}, +{0xEFD0,0x88,0x01}, +{0xEFD1,0x06,0x01}, +{0xEFD2,0x54,0x01}, +{0xEFD3,0x9E,0x01}, +{0xEFD4,0xE9,0x01}, +{0xEFD5,0x30,0x01}, +{0xEFD6,0xC7,0x01}, +{0xEFD7,0x3A,0x01}, +{0xEFD8,0xEA,0x01}, +{0xEFD9,0x41,0x01}, +{0xEFDA,0x50,0x01}, +{0xEFDB,0x8A,0x01}, +{0xEFDC,0x4E,0x01}, +{0xEFDD,0xB4,0x01}, +{0xEFDE,0x22,0x01}, +{0xEFDF,0x10,0x01}, +{0xEFE0,0x51,0x01}, +{0xEFE1,0x48,0x01}, +{0xEFE2,0x42,0x01}, +{0xEFE3,0x19,0x01}, +{0xEFE4,0x2A,0x01}, +{0xEFE5,0x91,0x01}, +{0xEFE6,0x8B,0x01}, +{0xEFE7,0x5A,0x01}, +{0xEFE8,0x04,0x01}, +{0xEFE9,0x00,0x01}, +{0xEFEA,0x00,0x01}, +{0xEFEB,0x00,0x01}, +{0xEFEC,0x00,0x01}, +{0xEFED,0x00,0x01}, + + + +//SHD3 D65+TL84 C01// +{0xED00,0x9191,0x02},// +{0xEFEE,0x21,0x01}, +{0xEFEF,0xAA,0x01}, +{0xEFF0,0xD1,0x01}, +{0xEFF1,0x8B,0x01}, +{0xEFF2,0x4A,0x01}, +{0xEFF3,0x64,0x01}, +{0xEFF4,0x22,0x01}, +{0xEFF5,0x15,0x01}, +{0xEFF6,0xD9,0x01}, +{0xEFF7,0x28,0x01}, +{0xEFF8,0x47,0x01}, +{0xEFF9,0x26,0x01}, +{0xEFFA,0xA2,0x01}, +{0xEFFB,0x50,0x01}, +{0xEFFC,0x7F,0x01}, +{0xEFFD,0xC6,0x01}, +{0xEFFE,0x23,0x01}, +{0xEFFF,0x9D,0x01}, +{0xF000,0xE6,0x01}, +{0xF001,0x54,0x01}, +{0xF002,0xE7,0x01}, +{0xF003,0x3C,0x01}, +{0xF004,0x00,0x01}, +{0xF005,0xBA,0x01}, +{0xF006,0xD0,0x01}, +{0xF007,0x7C,0x01}, +{0xF008,0x98,0x01}, +{0xF009,0xA3,0x01}, +{0xF00A,0x9A,0x01}, +{0xF00B,0xC7,0x01}, +{0xF00C,0x18,0x01}, +{0xF00D,0x06,0x01}, +{0xF00E,0x32,0x01}, +{0xF00F,0xAA,0x01}, +{0xF010,0x81,0x01}, +{0xF011,0x8E,0x01}, +{0xF012,0x80,0x01}, +{0xF013,0xA4,0x01}, +{0xF014,0xE3,0x01}, +{0xF015,0x19,0x01}, +{0xF016,0xB7,0x01}, +{0xF017,0x3C,0x01}, +{0xF018,0xC5,0x01}, +{0xF019,0x28,0x01}, +{0xF01A,0x51,0x01}, +{0xF01B,0x89,0x01}, +{0xF01C,0x8B,0x01}, +{0xF01D,0x69,0x01}, +{0xF01E,0xC4,0x01}, +{0xF01F,0x93,0x01}, +{0xF020,0x9B,0x01}, +{0xF021,0xBC,0x01}, +{0xF022,0x10,0x01}, +{0xF023,0x65,0x01}, +{0xF024,0x24,0x01}, +{0xF025,0x18,0x01}, +{0xF026,0x21,0x01}, +{0xF027,0x09,0x01}, +{0xF028,0x52,0x01}, +{0xF029,0x00,0x01}, +{0xF02A,0x33,0x01}, +{0xF02B,0x9C,0x01}, +{0xF02C,0xD5,0x01}, +{0xF02D,0x9C,0x01}, +{0xF02E,0xE5,0x01}, +{0xF02F,0x25,0x01}, +{0xF030,0x0A,0x01}, +{0xF031,0x01,0x01}, +{0xF032,0x88,0x01}, +{0xF033,0x43,0x01}, +{0xF034,0x68,0x01}, +{0xF035,0xA2,0x01}, +{0xF036,0x16,0x01}, +{0xF037,0xD9,0x01}, +{0xF038,0xAC,0x01}, +{0xF039,0x06,0x01}, +{0xF03A,0x2D,0x01}, +{0xF03B,0x30,0x01}, +{0xF03C,0x51,0x01}, +{0xF03D,0x48,0x01}, +{0xF03E,0x40,0x01}, +{0xF03F,0x1E,0x01}, +{0xF040,0x42,0x01}, +{0xF041,0x93,0x01}, +{0xF042,0xB6,0x01}, +{0xF043,0xDC,0x01}, +{0xF044,0xC6,0x01}, +{0xF045,0x37,0x01}, +{0xF046,0x7E,0x01}, +{0xF047,0x31,0x01}, +{0xF048,0xCA,0x01}, +{0xF049,0x48,0x01}, +{0xF04A,0x32,0x01}, +{0xF04B,0x72,0x01}, +{0xF04C,0x92,0x01}, +{0xF04D,0xA5,0x01}, +{0xF04E,0x08,0x01}, +{0xF04F,0x26,0x01}, +{0xF050,0x39,0x01}, +{0xF051,0xDC,0x01}, +{0xF052,0x19,0x01}, +{0xF053,0x8D,0x01}, +{0xF054,0x5C,0x01}, +{0xF055,0xA4,0x01}, +{0xF056,0x92,0x01}, +{0xF057,0x14,0x01}, +{0xF058,0xAB,0x01}, +{0xF059,0xE0,0x01}, +{0xF05A,0xA5,0x01}, +{0xF05B,0x35,0x01}, +{0xF05C,0xEA,0x01}, +{0xF05D,0x09,0x01}, +{0xF05E,0x10,0x01}, +{0xF05F,0x75,0x01}, +{0xF060,0x58,0x01}, +{0xF061,0x33,0x01}, +{0xF062,0x99,0x01}, +{0xF063,0xC4,0x01}, +{0xF064,0x58,0x01}, +{0xF065,0x66,0x01}, +{0xF066,0x36,0x01}, +{0xF067,0xDB,0x01}, +{0xF068,0x61,0x01}, +{0xF069,0xD0,0x01}, +{0xF06A,0x86,0x01}, +{0xF06B,0x02,0x01}, +{0xF06C,0x64,0x01}, +{0xF06D,0x1E,0x01}, +{0xF06E,0xEB,0x01}, +{0xF06F,0x40,0x01}, +{0xF070,0x47,0x01}, +{0xF071,0x3B,0x01}, +{0xF072,0xEE,0x01}, +{0xF073,0x51,0x01}, +{0xF074,0x10,0x01}, +{0xF075,0x8A,0x01}, +{0xF076,0x36,0x01}, +{0xF077,0x54,0x01}, +{0xF078,0x22,0x01}, +{0xF079,0x0E,0x01}, +{0xF07A,0x51,0x01}, +{0xF07B,0x88,0x01}, +{0xF07C,0x42,0x01}, +{0xF07D,0x1A,0x01}, +{0xF07E,0x2A,0x01}, +{0xF07F,0x11,0x01}, +{0xF080,0x8B,0x01}, +{0xF081,0x48,0x01}, +{0xF082,0x04,0x01}, +{0xF083,0x00,0x01}, +{0xF084,0x00,0x01}, +{0xF085,0x00,0x01}, +{0xF086,0x00,0x01}, +{0xF087,0x00,0x01}, +{0xF088,0xBE,0x01}, +{0xF089,0x51,0x01}, +{0xF08A,0x4E,0x01}, +{0xF08B,0x6F,0x01}, +{0xF08C,0x6C,0x01}, +{0xF08D,0x43,0x01}, +{0xF08E,0x1B,0x01}, +{0xF08F,0xDA,0x01}, +{0xF090,0xEC,0x01}, +{0xF091,0x46,0x01}, +{0xF092,0x38,0x01}, +{0xF093,0xBB,0x01}, +{0xF094,0xC1,0x01}, +{0xF095,0xCD,0x01}, +{0xF096,0x69,0x01}, +{0xF097,0x26,0x01}, +{0xF098,0x93,0x01}, +{0xF099,0x98,0x01}, +{0xF09A,0xC1,0x01}, +{0xF09B,0x20,0x01}, +{0xF09C,0x26,0x01}, +{0xF09D,0x32,0x01}, +{0xF09E,0xA5,0x01}, +{0xF09F,0xB1,0x01}, +{0xF0A0,0x8D,0x01}, +{0xF0A1,0x67,0x01}, +{0xF0A2,0x0E,0x01}, +{0xF0A3,0x23,0x01}, +{0xF0A4,0x97,0x01}, +{0xF0A5,0xB0,0x01}, +{0xF0A6,0x6C,0x01}, +{0xF0A7,0x25,0x01}, +{0xF0A8,0x2C,0x01}, +{0xF0A9,0x71,0x01}, +{0xF0AA,0x41,0x01}, +{0xF0AB,0x0C,0x01}, +{0xF0AC,0x69,0x01}, +{0xF0AD,0x14,0x01}, +{0xF0AE,0xB3,0x01}, +{0xF0AF,0x96,0x01}, +{0xF0B0,0xA6,0x01}, +{0xF0B1,0xE8,0x01}, +{0xF0B2,0x64,0x01}, +{0xF0B3,0x26,0x01}, +{0xF0B4,0x3A,0x01}, +{0xF0B5,0x79,0x01}, +{0xF0B6,0x4A,0x01}, +{0xF0B7,0x5B,0x01}, +{0xF0B8,0x18,0x01}, +{0xF0B9,0xA3,0x01}, +{0xF0BA,0x97,0x01}, +{0xF0BB,0xA9,0x01}, +{0xF0BC,0xBC,0x01}, +{0xF0BD,0x24,0x01}, +{0xF0BE,0x23,0x01}, +{0xF0BF,0x13,0x01}, +{0xF0C0,0xE1,0x01}, +{0xF0C1,0xC8,0x01}, +{0xF0C2,0x4C,0x01}, +{0xF0C3,0xAA,0x01}, +{0xF0C4,0xA2,0x01}, +{0xF0C5,0x97,0x01}, +{0xF0C6,0xB6,0x01}, +{0xF0C7,0x14,0x01}, +{0xF0C8,0x05,0x01}, +{0xF0C9,0x24,0x01}, +{0xF0CA,0x06,0x01}, +{0xF0CB,0x09,0x01}, +{0xF0CC,0xC8,0x01}, +{0xF0CD,0x42,0x01}, +{0xF0CE,0x48,0x01}, +{0xF0CF,0x82,0x01}, +{0xF0D0,0x14,0x01}, +{0xF0D1,0xB8,0x01}, +{0xF0D2,0xC0,0x01}, +{0xF0D3,0xE5,0x01}, +{0xF0D4,0x28,0x01}, +{0xF0D5,0x21,0x01}, +{0xF0D6,0x39,0x01}, +{0xF0D7,0x08,0x01}, +{0xF0D8,0x40,0x01}, +{0xF0D9,0x14,0x01}, +{0xF0DA,0x62,0x01}, +{0xF0DB,0x92,0x01}, +{0xF0DC,0xA4,0x01}, +{0xF0DD,0xC4,0x01}, +{0xF0DE,0x05,0x01}, +{0xF0DF,0x30,0x01}, +{0xF0E0,0x58,0x01}, +{0xF0E1,0xA1,0x01}, +{0xF0E2,0x49,0x01}, +{0xF0E3,0x46,0x01}, +{0xF0E4,0x22,0x01}, +{0xF0E5,0xB2,0x01}, +{0xF0E6,0x91,0x01}, +{0xF0E7,0x9A,0x01}, +{0xF0E8,0x58,0x01}, +{0xF0E9,0xA5,0x01}, +{0xF0EA,0x2F,0x01}, +{0xF0EB,0x96,0x01}, +{0xF0EC,0x99,0x01}, +{0xF0ED,0x8B,0x01}, +{0xF0EE,0x54,0x01}, +{0xF0EF,0x74,0x01}, +{0xF0F0,0x32,0x01}, +{0xF0F1,0x13,0x01}, +{0xF0F2,0x9D,0x01}, +{0xF0F3,0x38,0x01}, +{0xF0F4,0xC5,0x01}, +{0xF0F5,0x2D,0x01}, +{0xF0F6,0x90,0x01}, +{0xF0F7,0x59,0x01}, +{0xF0F8,0x4D,0x01}, +{0xF0F9,0x64,0x01}, +{0xF0FA,0xEE,0x01}, +{0xF0FB,0x62,0x01}, +{0xF0FC,0x16,0x01}, +{0xF0FD,0xAE,0x01}, +{0xF0FE,0x84,0x01}, +{0xF0FF,0x25,0x01}, +{0xF100,0x2E,0x01}, +{0xF101,0x8B,0x01}, +{0xF102,0x31,0x01}, +{0xF103,0xCD,0x01}, +{0xF104,0x6F,0x01}, +{0xF105,0x60,0x01}, +{0xF106,0xC3,0x01}, +{0xF107,0x19,0x01}, +{0xF108,0xC7,0x01}, +{0xF109,0x14,0x01}, +{0xF10A,0x26,0x01}, +{0xF10B,0x31,0x01}, +{0xF10C,0x97,0x01}, +{0xF10D,0x41,0x01}, +{0xF10E,0x8D,0x01}, +{0xF10F,0x6D,0x01}, +{0xF110,0x86,0x01}, +{0xF111,0xE3,0x01}, +{0xF112,0x9C,0x01}, +{0xF113,0xE2,0x01}, +{0xF114,0xD8,0x01}, +{0xF115,0x06,0x01}, +{0xF116,0x36,0x01}, +{0xF117,0xB5,0x01}, +{0xF118,0xE9,0x01}, +{0xF119,0x4D,0x01}, +{0xF11A,0x70,0x01}, +{0xF11B,0x68,0x01}, +{0xF11C,0x03,0x01}, +{0xF11D,0x00,0x01}, +{0xF11E,0x00,0x01}, +{0xF11F,0x00,0x01}, +{0xF120,0x00,0x01}, +{0xF121,0x00,0x01}, + + +//SHD TH +{0x6C32,0x1964,0x02}, // SHD_INP_TH_HB_H_R2 +{0x6C34,0x18CE,0x02}, // SHD_INP_TH_HB_L_R2 +{0x6C36,0x10CC,0x02}, // SHD_INP_TH_LB_H_R2 +{0x6C38,0x1004,0x02}, // SHD_INP_TH_LB_L_R2 +{0x6C3C,0x10CC,0x02}, // SHD_INP_TH_HB_H_RB +{0x6C3E,0x1004,0x02}, // SHD_INP_TH_HB_L_RB +{0x6C40,0x0000,0x02}, // SHD_INP_TH_LB_H_RB +{0x6C42,0x0000,0x02}, // SHD_INP_TH_LB_L_RB + +//PreWB_offset (for SHD2) +{0x6828,0x0013,0x02}, // SHD_PRER_OFFSET_R2 : +//PreWB_offset (for SHD3) +{0x682C,0x000B,0x02}, // SHD_PRER_OFFSET_RB : +{0x6830,0xFFFD,0x02}, // SHD_PREB_OFFSET_RB : + +// CXC/SHD EN +{0x01BC,0x57,0x01}, // CXC ON SHD ON INP ON GAIN OFF +}; + +static const isx012_regset_t ISX012_Flash_ON[] = +{ +//Flash_ON_SET +{0x00B7,0x15,0x01}, // LED_ON +{0x0016,0x10,0x01}, // GPIO_FUNCSEL +{0x0181,0x05,0x01}, // CAP_HALF_AE_CTRL +{0x01AE,0x01,0x01}, // HALF_AWB_CTRL +{0x6223,0x01,0x01}, // INIT_GAINS +{0x6226,0x01,0x01}, // ATW_GAINS_IN_NR +{0x6227,0x01,0x01}, // ATW_GAINS_IN +{0x6228,0x01,0x01}, // ATW_GAINS_OUT_NR +{0x6229,0x01,0x01}, // ATW_GAINS_OUT +{0x5E3D,0x0F,0x01}, // FASTMOVE_TIMEOUT +{0x5E32,0x0F,0x01}, // AESPEED_FAST +{0x5E2E,0x1A,0x01}, // AEIINDEADBAND +{0x500A,0x00,0x01}, // FAST_MODECHG_EN +{0x01AF,0x01,0x01}, // CAP_AWB_CTRL +{0x6224,0x01,0x01}, // ATW_DELAY +//AWB boundary set +{0x6400,0x00,0x01}, // INFRM_LEFT00 : +{0x6401,0x00,0x01}, // INFRM_LEFT01 : +{0x6402,0x00,0x01}, // INFRM_LEFT02 : +{0x6403,0x00,0x01}, // INFRM_LEFT03 : +{0x6404,0x00,0x01}, // INFRM_LEFT04 : +{0x6405,0x00,0x01}, // INFRM_LEFT05 : +{0x6406,0x00,0x01}, // INFRM_LEFT06 : +{0x6407,0x00,0x01}, // INFRM_LEFT07 : +{0x6408,0x00,0x01}, // INFRM_LEFT08 : +{0x6409,0x00,0x01}, // INFRM_LEFT09 : +{0x640A,0x00,0x01}, // INFRM_LEFT10 : +{0x640B,0x00,0x01}, // INFRM_LEFT11 : +{0x640C,0x00,0x01}, // INFRM_LEFT12 : +{0x640D,0x00,0x01}, // INFRM_LEFT13 : +{0x640E,0x00,0x01}, // INFRM_LEFT14 : +{0x640F,0x00,0x01}, // INFRM_LEFT15 : +{0x6410,0x00,0x01}, // INFRM_LEFT16 : +{0x6411,0x00,0x01}, // INFRM_LEFT17 : +{0x6412,0x00,0x01}, // INFRM_LEFT18 : +{0x6413,0x00,0x01}, // INFRM_LEFT19 : +{0x6414,0x00,0x01}, // INFRM_LEFT20 : +{0x6415,0x00,0x01}, // INFRM_LEFT21 : +{0x6416,0x00,0x01}, // INFRM_LEFT22 : +{0x6417,0x00,0x01}, // INFRM_LEFT23 : +{0x6418,0x00,0x01}, // INFRM_LEFT24 : +{0x6419,0x00,0x01}, // INFRM_LEFT25 : +{0x641A,0x00,0x01}, // INFRM_LEFT26 : +{0x641B,0x00,0x01}, // INFRM_LEFT27 : +{0x641C,0x00,0x01}, // INFRM_LEFT28 : +{0x641D,0x00,0x01}, // INFRM_LEFT29 : +{0x641E,0x00,0x01}, // INFRM_LEFT30 : +{0x641F,0x00,0x01}, // INFRM_LEFT31 : +{0x6420,0x00,0x01}, // INFRM_LEFT32 : +{0x6421,0x00,0x01}, // INFRM_LEFT33 : +{0x6422,0x00,0x01}, // INFRM_LEFT34 : +{0x6423,0x00,0x01}, // INFRM_LEFT35 : +{0x6424,0x00,0x01}, // INFRM_LEFT36 : +{0x6425,0x00,0x01}, // INFRM_LEFT37 : +{0x6426,0xFF,0x01}, // INFRM_RIGHT00 : +{0x6427,0xFF,0x01}, // INFRM_RIGHT01 : +{0x6428,0xFF,0x01}, // INFRM_RIGHT02 : +{0x6429,0xFF,0x01}, // INFRM_RIGHT03 : +{0x642A,0xFF,0x01}, // INFRM_RIGHT04 : +{0x642B,0xFF,0x01}, // INFRM_RIGHT05 : +{0x642C,0xFF,0x01}, // INFRM_RIGHT06 : +{0x642D,0xFF,0x01}, // INFRM_RIGHT07 : +{0x642E,0xFF,0x01}, // INFRM_RIGHT08 : +{0x642F,0xFF,0x01}, // INFRM_RIGHT09 : +{0x6430,0xFF,0x01}, // INFRM_RIGHT10 : +{0x6431,0xFF,0x01}, // INFRM_RIGHT11 : +{0x6432,0xFF,0x01}, // INFRM_RIGHT12 : +{0x6433,0xFF,0x01}, // INFRM_RIGHT13 : +{0x6434,0xFF,0x01}, // INFRM_RIGHT14 : +{0x6435,0xFF,0x01}, // INFRM_RIGHT15 : +{0x6436,0xFF,0x01}, // INFRM_RIGHT16 : +{0x6437,0xFF,0x01}, // INFRM_RIGHT17 : +{0x6438,0xFF,0x01}, // INFRM_RIGHT18 : +{0x6439,0xFF,0x01}, // INFRM_RIGHT19 : +{0x643A,0xFF,0x01}, // INFRM_RIGHT20 : +{0x643B,0xFF,0x01}, // INFRM_RIGHT21 : +{0x643C,0xFF,0x01}, // INFRM_RIGHT22 : +{0x643D,0xFF,0x01}, // INFRM_RIGHT23 : +{0x643E,0xFF,0x01}, // INFRM_RIGHT24 : +{0x643F,0xFF,0x01}, // INFRM_RIGHT25 : +{0x6440,0xFF,0x01}, // INFRM_RIGHT26 : +{0x6441,0xFF,0x01}, // INFRM_RIGHT27 : +{0x6442,0xFF,0x01}, // INFRM_RIGHT28 : +{0x6443,0xFF,0x01}, // INFRM_RIGHT29 : +{0x6444,0xFF,0x01}, // INFRM_RIGHT30 : +{0x6445,0xFF,0x01}, // INFRM_RIGHT31 : +{0x6446,0xFF,0x01}, // INFRM_RIGHT32 : +{0x6447,0xFF,0x01}, // INFRM_RIGHT33 : +{0x6448,0xFF,0x01}, // INFRM_RIGHT34 : +{0x6449,0xFF,0x01}, // INFRM_RIGHT35 : +{0x644A,0xFF,0x01}, // INFRM_RIGHT36 : +{0x644B,0xFF,0x01}, // INFRM_RIGHT37 : +{0x644C,0x25C2,0x02}, // INFRM_TOP : +{0x644E,0x0348,0x02}, // INFRM_BOTM : +{0x6450,0x1D,0x01}, // INFRM_FLTOP : +{0x6451,0x00,0x01}, // INFRM_FLBOTM : +//halfrelease_mode value +{0x0082,0x01,0x01}, // MONI_REFRESH +{0x00B1,0x01,0x01}, //AF_RESTART_F : +{0x00B2,0x03,0x01}, //AFMODE_MONI : AF OFF +{0x00B3,0x00,0x01}, //AFMODE_HREL : +{0xFFFF,0x42,0x01},//$wait, 66 +{0x0081,0x01,0x01}, //MODESEL +}; + +static const isx012_regset_t ISX012_Flash_OFF[] = +{ +//Flash_OFF_RESET +{0x00B7,0x00,0x01}, // LED_ON +{0x0016,0x10,0x01}, // GPIO_FUNCSEL +{0x0181,0x00,0x01}, // CAP_HALF_AE_CTRL +{0x01AE,0x00,0x01}, // HALF_AWB_CTRL +{0x6223,0x04,0x01}, // INIT_GAINS +{0x6226,0x08,0x01}, // ATW_GAINS_IN_NR +{0x6227,0x04,0x01}, // ATW_GAINS_IN +{0x6228,0x08,0x01}, // ATW_GAINS_OUT_NR +{0x6229,0x04,0x01}, // ATW_GAINS_OUT +{0x5E3D,0x0A,0x01}, // FASTMOVE_TIMEOUT +{0x5E32,0x0F,0x01}, // AESPEED_FAST +{0x5E2E,0x1A,0x01}, // AEIINDEADBAND +{0x500A,0x00,0x01}, // FAST_MODECHG_EN +{0x01AF,0x00,0x01}, // CAP_AWB_CTRL +{0x6224,0x04,0x01}, // ATW_DELAY +//AWB boundary reset +{0x6400,0xAA,0x01}, // INFRM_LEFT00 : +{0x6401,0xAA,0x01}, // INFRM_LEFT01 : +{0x6402,0xAA,0x01}, // INFRM_LEFT02 : +{0x6403,0xAA,0x01}, // INFRM_LEFT03 : +{0x6404,0xAA,0x01}, // INFRM_LEFT04 : +{0x6405,0xAA,0x01}, // INFRM_LEFT05 : +{0x6406,0xAA,0x01}, // INFRM_LEFT06 : +{0x6407,0xAA,0x01}, // INFRM_LEFT07 : +{0x6408,0xAA,0x01}, // INFRM_LEFT08 : +{0x6409,0xAE,0x01}, // INFRM_LEFT09 : +{0x640A,0xA0,0x01}, // INFRM_LEFT10 : +{0x640B,0x8C,0x01}, // INFRM_LEFT11 : +{0x640C,0x72,0x01}, // INFRM_LEFT12 : +{0x640D,0x64,0x01}, // INFRM_LEFT13 : +{0x640E,0x5A,0x01}, // INFRM_LEFT14 : +{0x640F,0x52,0x01}, // INFRM_LEFT15 : +{0x6410,0x48,0x01}, // INFRM_LEFT16 : +{0x6411,0x43,0x01}, // INFRM_LEFT17 : +{0x6412,0x3D,0x01}, // INFRM_LEFT18 : +{0x6413,0x37,0x01}, // INFRM_LEFT19 : +{0x6414,0x33,0x01}, // INFRM_LEFT20 : +{0x6415,0x30,0x01}, // INFRM_LEFT21 : +{0x6416,0x2E,0x01}, // INFRM_LEFT22 : +{0x6417,0x2B,0x01}, // INFRM_LEFT23 : +{0x6418,0x28,0x01}, // INFRM_LEFT24 : +{0x6419,0x26,0x01}, // INFRM_LEFT25 : +{0x641A,0x24,0x01}, // INFRM_LEFT26 : +{0x641B,0x23,0x01}, // INFRM_LEFT27 : +{0x641C,0x22,0x01}, // INFRM_LEFT28 : +{0x641D,0x22,0x01}, // INFRM_LEFT29 : +{0x641E,0x21,0x01}, // INFRM_LEFT30 : +{0x641F,0x20,0x01}, // INFRM_LEFT31 : +{0x6420,0x1D,0x01}, // INFRM_LEFT32 : +{0x6421,0x1A,0x01}, // INFRM_LEFT33 : +{0x6422,0x18,0x01}, // INFRM_LEFT34 : +{0x6423,0x17,0x01}, // INFRM_LEFT35 : +{0x6424,0x16,0x01}, // INFRM_LEFT36 : +{0x6425,0x17,0x01}, // INFRM_LEFT37 : +{0x6426,0xAF,0x01}, // INFRM_RIGHT00 : +{0x6427,0xAF,0x01}, // INFRM_RIGHT01 : +{0x6428,0xAF,0x01}, // INFRM_RIGHT02 : +{0x6429,0xAF,0x01}, // INFRM_RIGHT03 : +{0x642A,0xAF,0x01}, // INFRM_RIGHT04 : +{0x642B,0xAF,0x01}, // INFRM_RIGHT05 : +{0x642C,0xAF,0x01}, // INFRM_RIGHT06 : +{0x642D,0xAF,0x01}, // INFRM_RIGHT07 : +{0x642E,0xAF,0x01}, // INFRM_RIGHT08 : +{0x642F,0xAA,0x01}, // INFRM_RIGHT09 : +{0x6430,0xB2,0x01}, // INFRM_RIGHT10 : +{0x6431,0xB4,0x01}, // INFRM_RIGHT11 : +{0x6432,0xB6,0x01}, // INFRM_RIGHT12 : +{0x6433,0xB4,0x01}, // INFRM_RIGHT13 : +{0x6434,0x9B,0x01}, // INFRM_RIGHT14 : +{0x6435,0x8E,0x01}, // INFRM_RIGHT15 : +{0x6436,0x84,0x01}, // INFRM_RIGHT16 : +{0x6437,0x7A,0x01}, // INFRM_RIGHT17 : +{0x6438,0x72,0x01}, // INFRM_RIGHT18 : +{0x6439,0x6A,0x01}, // INFRM_RIGHT19 : +{0x643A,0x63,0x01}, // INFRM_RIGHT20 : +{0x643B,0x5E,0x01}, // INFRM_RIGHT21 : +{0x643C,0x58,0x01}, // INFRM_RIGHT22 : +{0x643D,0x53,0x01}, // INFRM_RIGHT23 : +{0x643E,0x4E,0x01}, // INFRM_RIGHT24 : +{0x643F,0x4A,0x01}, // INFRM_RIGHT25 : +{0x6440,0x46,0x01}, // INFRM_RIGHT26 : +{0x6441,0x42,0x01}, // INFRM_RIGHT27 : +{0x6442,0x3F,0x01}, // INFRM_RIGHT28 : +{0x6443,0x3C,0x01}, // INFRM_RIGHT29 : +{0x6444,0x3A,0x01}, // INFRM_RIGHT30 : +{0x6445,0x38,0x01}, // INFRM_RIGHT31 : +{0x6446,0x37,0x01}, // INFRM_RIGHT32 : +{0x6447,0x35,0x01}, // INFRM_RIGHT33 : +{0x6448,0x33,0x01}, // INFRM_RIGHT34 : +{0x6449,0x32,0x01}, // INFRM_RIGHT35 : +{0x644A,0x32,0x01}, // INFRM_RIGHT36 : +{0x644B,0x32,0x01}, // INFRM_RIGHT37 : +{0x644C,0x24FA,0x02}, // INFRM_TOP : +{0x644E,0x0940,0x02}, // INFRM_BOTM : +{0x6450,0x19,0x01}, // INFRM_FLTOP : +{0x6451,0x10,0x01}, // INFRM_FLBOTM : +////Flash_ON_RESET +{0x0308,0x11,0x01}, // AELINE_MONI_SN1_2 : +{0x0309,0x13,0x01}, // AELINE_MONI_SN3_4 : +{0x030B,0x41,0x01}, // AELINE_MONI_SN7_8 : +{0x030D,0x11,0x01}, // AELINE_MONI_SN11_12 : +{0x030E,0x11,0x01}, // AELINE_HALF_SN1_2 : +{0x030F,0x13,0x01}, // AELINE_HALF_SN3_4 : +{0x0311,0x41,0x01}, // AELINE_HALF_SN7_8 : +{0x0313,0x11,0x01}, // AELINE_HALF_SN11_12 : +{0x0314,0x11,0x01}, // AELINE_HALF_AFEND_SN1_2 : +{0x0315,0x13,0x01}, // AELINE_HALF_AFEND_SN3_4 : +{0x0317,0x41,0x01}, // AELINE_HALF_AFEND_SN7_8 : +{0x0319,0x11,0x01}, // AELINE_HALF_AFEND_SN11_12 : +{0x031A,0x00,0x01}, // AELINE_CAP_SN1_2 : +{0x031B,0x03,0x01}, // AELINE_CAP_SN3_4 : +{0x031D,0x50,0x01}, // AELINE_CAP_SN7_8 : +{0x031F,0x00,0x01}, // AELINE_CAP_SN11_12 : +{0x0294,0x00,0x01}, // AE_SN1 +{0x0297,0x00,0x01}, // AE_SN4 +{0x029A,0x00,0x01}, // AE_SN7 +{0x029E,0x00,0x01}, // AE_SN11 +}; + +static const isx012_regset_t ISX012_Flash_AELINE[] = +{ +//Flash_ON_SET +{0x0308,0x12,0x01}, // AELINE_MONI_SN1_2 : +{0x0309,0x23,0x01}, // AELINE_MONI_SN3_4 : +{0x030B,0x42,0x01}, // AELINE_MONI_SN7_8 : +{0x030D,0x12,0x01}, // AELINE_MONI_SN11_12 : +{0x030E,0x12,0x01}, // AELINE_HALF_SN1_2 : +{0x030F,0x23,0x01}, // AELINE_HALF_SN3_4 : +{0x0311,0x42,0x01}, // AELINE_HALF_SN7_8 : +{0x0313,0x12,0x01}, // AELINE_HALF_SN11_12 : +{0x0314,0x12,0x01}, // AELINE_HALF_AFEND_SN1_2 : +{0x0315,0x23,0x01}, // AELINE_HALF_AFEND_SN3_4 : +{0x0317,0x42,0x01}, // AELINE_HALF_AFEND_SN7_8 : +{0x0319,0x12,0x01}, // AELINE_HALF_AFEND_SN11_12 : +{0x031A,0x02,0x01}, // AELINE_CAP_SN1_2 : +{0x031B,0x23,0x01}, // AELINE_CAP_SN3_4 : +{0x031D,0x52,0x01}, // AELINE_CAP_SN7_8 : +{0x031F,0x02,0x01}, // AELINE_CAP_SN11_12 : +}; + +static const isx012_regset_t ISX012_ae_manual_mode[] = +{ +{0x0294,0x02,0x01}, /* AE_SN1 */ +{0x0297,0x02,0x01}, /* AE_SN4 */ +{0x029A,0x02,0x01}, /* AE_SN7 */ +{0x029E,0x02,0x01}, /* AE_SN11 */ +{0xFFFF,0x42,0x01}, /* $wait, 66 */ +}; + +static const isx012_regset_t ISX012_flash_fast_ae_awb[] = +{ +{0x5E32,0x0A,0x01}, +{0x5E3D,0x05,0x01}, /* Don't fix me. 0x05 */ + +{0x0181,0x01,0x01}, // CAP_HALF_AE_CTRL +{0x00B2,0x03,0x01}, //AFMODE_MONI : AF OFF +{0x00B3,0x03,0x01}, //AFMODE_HREL : AF OFF +{0x0081,0x01,0x01}, //MODESEL +}; + +static const isx012_regset_t ISX012_Lowlux_Night_Reset[] = +{ +{0x039D,0x00,0x01}, //UIHUE_TYPE3 : +{0x03A0,0x80,0x01}, //UISATURATION_TYPE3 : +{0x982A,0xFFEC,0x02}, // CS_CBLLEV_A : +{0x9830,0xFFEC,0x02}, // CS_CRLLEV_A : +{0x9805,0x0A,0x01}, // CS_SLP_C_A : +{0x6A9E,0x15C0,0x02}, //HMAX_1_1(0x6A9E)=0x15C0 +{0x00AC,0x00,0x01}, // +{0x660E,0x5A,0x01}, // AF_HBPF_PEAK_OPD_TH_MIN +{0x6610,0x5A,0x01}, // AF_HBPF_PEAK_OPD_TH_MAX +{0x664A,0x04,0x01}, // AF_DROPN_ON_PEAK_DETECT : +{0x6640,0x02,0x01}, // AF_DROPN_ON_PEAK_DETECT_SECOND : +{0x0289,0x20,0x01}, //AWB_SN8 +}; + +#endif /* __ISX012_REGS_H__ */ diff --git a/drivers/media/video/samsung/fimc/fimc_capture.c b/drivers/media/video/samsung/fimc/fimc_capture.c index 7d00c8b..75928ed 100644 --- a/drivers/media/video/samsung/fimc/fimc_capture.c +++ b/drivers/media/video/samsung/fimc/fimc_capture.c @@ -1435,7 +1435,7 @@ int fimc_s_fmt_vid_private(struct file *file, void *fh, struct v4l2_format *f) mbus_fmt = &ctrl->cap->mbus_fmt; mbus_fmt->width = pix->width; mbus_fmt->height = pix->height; -#ifdef CONFIG_MACH_P4NOTE +#if defined(CONFIG_MACH_P4NOTE) || defined(CONFIG_MACH_KONA) /* Unfortuntely, we have to use pix->field (not pix->priv) since * pix.field is already used in the below else condtion statement * (in case that sub-devices are not registered) @@ -1927,12 +1927,16 @@ int fimc_reqbufs_capture_mmap(void *fh, struct v4l2_requestbuffers *b) case V4L2_PIX_FMT_YVYU: /* fall through */ case V4L2_PIX_FMT_NV16: /* fall through */ case V4L2_PIX_FMT_NV61: /* fall through */ + fimc_err("%s : V4L2_PIX_FMT_YUYV - SBRISSEN\n", __func__); + fimc_err("%s : w %d h %d \n",__func__, + cap->fmt.width, cap->fmt.height); fimc_info1("%s : 1plane\n", __func__); ret = fimc_alloc_buffers(ctrl, 1, cap->fmt.width * cap->fmt.height, SZ_4K, bpp, cap->pktdata_enable, cap->pktdata_size); break; case V4L2_PIX_FMT_NV21: + fimc_err("%s : V4L2_PIX_FMT_NV12 - SBRISSEN\n", __func__); fimc_info1("%s : 2plane for NV21 w %d h %d\n", __func__, cap->fmt.width, cap->fmt.height); ret = fimc_alloc_buffers(ctrl, 2, @@ -1940,6 +1944,7 @@ int fimc_reqbufs_capture_mmap(void *fh, struct v4l2_requestbuffers *b) break; case V4L2_PIX_FMT_NV12: + fimc_info1("%s : 2plane for NV12\n", __func__); ret = fimc_alloc_buffers(ctrl, 2, cap->fmt.width * cap->fmt.height, SZ_64K, bpp, cap->pktdata_enable, cap->pktdata_size); @@ -1961,18 +1966,21 @@ int fimc_reqbufs_capture_mmap(void *fh, struct v4l2_requestbuffers *b) break; case V4L2_PIX_FMT_JPEG: + fimc_err("%s : V4L2_PIX_FMT_JPEG - SBRISSEN\n", __func__); fimc_info1("%s : JPEG 1plane\n", __func__); size = fimc_camera_get_jpeg_memsize(ctrl); fimc_info2("%s : JPEG 1plane size = %x\n", __func__, size); ret = fimc_alloc_buffers(ctrl, 1, size, 0, 8, cap->pktdata_enable, cap->pktdata_size); break; case V4L2_PIX_FMT_INTERLEAVED: + fimc_err("%s : V4L2_PIX_FMT_INTERLEAVED - SBRISSEN\n", __func__); fimc_info1("%s : Interleaved Format\n", __func__); size = fimc_camera_get_jpeg_memsize(ctrl); /*0xA00000*/ fimc_info2("%s : Interleaved size = %x\n", __func__, size); ret = fimc_alloc_buffers(ctrl, 1, size, 0, 8, cap->pktdata_enable, cap->pktdata_size); break; default: + fimc_err("%s : default - SBRISSEN\n", __func__); break; } @@ -1982,6 +1990,7 @@ int fimc_reqbufs_capture_mmap(void *fh, struct v4l2_requestbuffers *b) return -ENOMEM; } + fimc_err("%s : SBRISSEN - done\n", __func__); mutex_unlock(&ctrl->v4l2_lock); return 0; @@ -2248,7 +2257,7 @@ int fimc_s_ctrl_capture(void *fh, struct v4l2_control *c) clk_disable(ctrl->cam->clk); fimc->mclk_status = CAM_MCLK_OFF; ctrl->cam->initialized = 0; -#ifdef CONFIG_MACH_P4NOTE +#if defined(CONFIG_MACH_P4NOTE) || defined(CONFIG_MACH_KONA) /* 100ms: increase delay. * There are cases that sensor doesn't get revived * inspite of doing power reset.*/ @@ -2723,7 +2732,7 @@ int fimc_streamon_capture(void *fh) } } -#ifdef CONFIG_MACH_P4NOTE +#if defined(CONFIG_MACH_P4NOTE) || defined(CONFIG_MACH_KONA) #ifdef CONFIG_VIDEO_IMPROVE_STREAMOFF v4l2_subdev_call(cam->sd, video, s_stream, STREAM_MODE_WAIT_OFF); @@ -2753,7 +2762,7 @@ int fimc_streamon_capture(void *fh) cap->fmt.pixelformat); } } -#ifdef CONFIG_MACH_P4NOTE +#if defined(CONFIG_MACH_P4NOTE) || defined(CONFIG_MACH_KONA) if (1) { #else if (cap->fmt.priv != V4L2_PIX_FMT_MODE_CAPTURE) { diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c b/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c index 7fbea2a..8ff3d37 100644 --- a/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c +++ b/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c @@ -243,7 +243,15 @@ static void os_allocator_release(void * ctx, void * handle) static mali_physical_memory_allocation_result os_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block) { - int allocation_order = 11; /* _MALI_OSK_CPU_PAGE_SIZE << 11 */ +#if defined(CONFIG_MACH_KONA) +#ifndef CONFIG_FORCE_MAX_ZONEORDER + int allocation_order = 10; +#else + int allocation_order = CONFIG_FORCE_MAX_ZONEORDER - 1; +#endif +#else + int allocation_order = 11; /* _MALI_OSK_CPU_PAGE_SIZE << 6 */ +#endif void *virt = NULL; u32 size = _MALI_OSK_CPU_PAGE_SIZE << allocation_order; os_allocator * info; diff --git a/drivers/media/video/sr130pc20.c b/drivers/media/video/sr130pc20.c new file mode 100644 index 0000000..ab2b8d5 --- /dev/null +++ b/drivers/media/video/sr130pc20.c @@ -0,0 +1,1999 @@ +/* drivers/media/video/sr130pc20.c + * + * Copyright (c) 2010, Samsung Electronics. All rights reserved + * Author: dongseong.lim + * + * 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. + * + * - change date: 2012.06.28 + */ +#include "sr130pc20.h" +#include + +#define i2c_read_nop() \ + (cam_err("error, not used read function, line %d\n", __LINE__)) +#define i2c_write_nop() \ + (cam_err("error, not used write function, line %d\n", __LINE__)) + +#define isx012_readb(sd, addr, data) i2c_read_nop() +#define isx012_writeb(sd, addr, data) i2c_write_nop() + +#define sr130pc20_readb(sd, addr, data) sr130pc20_i2c_read(sd, addr, data) +#define sr130pc20_readw(sd, addr, data) i2c_read_nop() +#define sr130pc20_readl(sd, addr, data) i2c_read_nop() +#define sr130pc20_writeb(sd, addr, data) sr130pc20_i2c_write(sd, addr, data) +#define sr130pc20_writew(sd, addr, data) i2c_write_nop() +#define sr130pc20_writel(sd, addr, data) i2c_write_nop() + +static int dbg_level; + +static const struct sr130pc20_fps sr130pc20_framerates[] = { + { I_FPS_0, FRAME_RATE_AUTO }, + { I_FPS_7, FRAME_RATE_7}, + { I_FPS_15, FRAME_RATE_15 }, + { I_FPS_25, FRAME_RATE_25 }, + { I_FPS_30, FRAME_RATE_30 }, +}; + +static const struct sr130pc20_framesize sr130pc20_preview_frmsizes[] = { + { PREVIEW_SZ_320x240, 320, 240 }, + { PREVIEW_SZ_CIF, 352, 288 }, + { PREVIEW_SZ_VGA, 640, 480 }, +}; + +static const struct sr130pc20_framesize sr130pc20_capture_frmsizes[] = { +/* { CAPTURE_SZ_VGA, 640, 480 },*/ + { CAPTURE_SZ_1MP, 1280, 960 }, +}; + +static struct sr130pc20_control sr130pc20_ctrls[] = { + SR130PC20_INIT_CONTROL(V4L2_CID_CAMERA_FLASH_MODE, \ + FLASH_MODE_OFF), + + SR130PC20_INIT_CONTROL(V4L2_CID_CAMERA_BRIGHTNESS, \ + EV_DEFAULT), + + SR130PC20_INIT_CONTROL(V4L2_CID_CAMERA_METERING, \ + METERING_MATRIX), + + SR130PC20_INIT_CONTROL(V4L2_CID_CAMERA_WHITE_BALANCE, \ + WHITE_BALANCE_AUTO), + + SR130PC20_INIT_CONTROL(V4L2_CID_CAMERA_EFFECT, \ + IMAGE_EFFECT_NONE), +}; + +static const struct sr130pc20_regs reg_datas = { + .ev = { + SR130PC20_REGSET(GET_EV_INDEX(EV_MINUS_4), + SR130PC20_ExpSetting_M4Step, 0), + SR130PC20_REGSET(GET_EV_INDEX(EV_MINUS_3), + SR130PC20_ExpSetting_M3Step, 0), + SR130PC20_REGSET(GET_EV_INDEX(EV_MINUS_2), + SR130PC20_ExpSetting_M2Step, 0), + SR130PC20_REGSET(GET_EV_INDEX(EV_MINUS_1), + SR130PC20_ExpSetting_M1Step, 0), + SR130PC20_REGSET(GET_EV_INDEX(EV_DEFAULT), + SR130PC20_ExpSetting_Default, 0), + SR130PC20_REGSET(GET_EV_INDEX(EV_PLUS_1), + SR130PC20_ExpSetting_P1Step, 0), + SR130PC20_REGSET(GET_EV_INDEX(EV_PLUS_2), + SR130PC20_ExpSetting_P2Step, 0), + SR130PC20_REGSET(GET_EV_INDEX(EV_PLUS_3), + SR130PC20_ExpSetting_P3Step, 0), + SR130PC20_REGSET(GET_EV_INDEX(EV_PLUS_4), + SR130PC20_ExpSetting_P4Step, 0), + }, + .metering = { + SR130PC20_REGSET(METERING_MATRIX, sr130pc20_Metering_Matrix, 0), + SR130PC20_REGSET(METERING_CENTER, sr130pc20_Metering_Center, 0), + SR130PC20_REGSET(METERING_SPOT, sr130pc20_Metering_Spot, 0), + }, + .iso = { + SR130PC20_REGSET(ISO_AUTO, sr130pc20_ISO_Auto, 0), + SR130PC20_REGSET(ISO_50, sr130pc20_ISO_50, 0), + SR130PC20_REGSET(ISO_100, sr130pc20_ISO_100, 0), + SR130PC20_REGSET(ISO_200, sr130pc20_ISO_200, 0), + SR130PC20_REGSET(ISO_400, sr130pc20_ISO_400, 0), + }, + .effect = { + SR130PC20_REGSET(IMAGE_EFFECT_NONE, sr130pc20_Effect_Normal, 0), + SR130PC20_REGSET(IMAGE_EFFECT_BNW, sr130pc20_Effect_Black_White, 0), + SR130PC20_REGSET(IMAGE_EFFECT_SEPIA, sr130pc20_Effect_Sepia, 0), + SR130PC20_REGSET(IMAGE_EFFECT_NEGATIVE, + SR130PC20_Effect_Negative, 0), + SR130PC20_REGSET(IMAGE_EFFECT_SOLARIZE, sr130pc20_Effect_Solar, 0), + SR130PC20_REGSET(IMAGE_EFFECT_SKETCH, sr130pc20_Effect_Sketch, 0), + SR130PC20_REGSET(IMAGE_EFFECT_POINT_COLOR_3, + sr130pc20_Effect_Pastel, 0), + }, + .white_balance = { + SR130PC20_REGSET(WHITE_BALANCE_AUTO, sr130pc20_WB_Auto, 0), + SR130PC20_REGSET(WHITE_BALANCE_SUNNY, sr130pc20_WB_Sunny, 0), + SR130PC20_REGSET(WHITE_BALANCE_CLOUDY, sr130pc20_WB_Cloudy, 0), + SR130PC20_REGSET(WHITE_BALANCE_TUNGSTEN, + sr130pc20_WB_Tungsten, 0), + SR130PC20_REGSET(WHITE_BALANCE_FLUORESCENT, + sr130pc20_WB_Fluorescent, 0), + }, + .scene_mode = { + SR130PC20_REGSET(SCENE_MODE_NONE, sr130pc20_Scene_Default, 0), + SR130PC20_REGSET(SCENE_MODE_PORTRAIT, sr130pc20_Scene_Portrait, 0), + SR130PC20_REGSET(SCENE_MODE_NIGHTSHOT, sr130pc20_Scene_Nightshot, 0), + SR130PC20_REGSET(SCENE_MODE_BACK_LIGHT, sr130pc20_Scene_Backlight, 0), + SR130PC20_REGSET(SCENE_MODE_LANDSCAPE, sr130pc20_Scene_Landscape, 0), + SR130PC20_REGSET(SCENE_MODE_SPORTS, sr130pc20_Scene_Sports, 0), + SR130PC20_REGSET(SCENE_MODE_PARTY_INDOOR, + sr130pc20_Scene_Party_Indoor, 0), + SR130PC20_REGSET(SCENE_MODE_BEACH_SNOW, + sr130pc20_Scene_Beach_Snow, 0), + SR130PC20_REGSET(SCENE_MODE_SUNSET, sr130pc20_Scene_Sunset, 0), + SR130PC20_REGSET(SCENE_MODE_DUSK_DAWN, sr130pc20_Scene_Duskdawn, 0), + SR130PC20_REGSET(SCENE_MODE_FALL_COLOR, + sr130pc20_Scene_Fall_Color, 0), + SR130PC20_REGSET(SCENE_MODE_FIREWORKS, sr130pc20_Scene_Fireworks, 0), + SR130PC20_REGSET(SCENE_MODE_TEXT, sr130pc20_Scene_Text, 0), + SR130PC20_REGSET(SCENE_MODE_CANDLE_LIGHT, + sr130pc20_Scene_Candle_Light, 0), + }, + .fps = { + SR130PC20_REGSET(I_FPS_0, sr130pc20_fps_auto, 0), + SR130PC20_REGSET(I_FPS_7, sr130pc20_fps_7fix, 0), + SR130PC20_REGSET(I_FPS_15, sr130pc20_fps_15fix, 0), + SR130PC20_REGSET(I_FPS_25, sr130pc20_fps_25fix, 0), + SR130PC20_REGSET(I_FPS_30, sr130pc20_fps_30fix, 0), + }, + .preview_size = { + SR130PC20_REGSET(PREVIEW_SZ_320x240, + sr130pc20_320_240_Preview, 0), + SR130PC20_REGSET(PREVIEW_SZ_CIF, sr130pc20_352_288_Preview, 0), + SR130PC20_REGSET(PREVIEW_SZ_VGA, sr130pc20_640_480_Preview, 0), + }, + .capture_size = { + /*SR130PC20_REGSET(CAPTURE_SZ_VGA, sr130pc20_VGA_Capture, 0),*/ + SR130PC20_REGSET(CAPTURE_SZ_1MP, sr130pc20_1280_960_Capture, 0), + }, + + .init_reg = SR130PC20_REGSET_TABLE(SR130PC20_Init_Reg, 0), + .VT_init_reg = SR130PC20_REGSET_TABLE(sr130pc20_VT_Init_Reg, 0), + .SS_init_reg = SR130PC20_REGSET_TABLE(sr130pc20_SmartStay_Init_Reg, 0), + /* Camera mode */ + .preview_mode = SR130PC20_REGSET_TABLE(SR130PC20_Preview_Mode, 0), + .capture_mode = SR130PC20_REGSET_TABLE(SR130PC20_Capture_Mode, 0), + .capture_mode_night = + SR130PC20_REGSET_TABLE(SR130PC20_Lowlux_Night_Capture_Mode, 0), + .stream_stop = SR130PC20_REGSET_TABLE(sr130pc20_stop_stream, 0), +}; + +static const struct v4l2_mbus_framefmt capture_fmts[] = { + { + .code = V4L2_MBUS_FMT_FIXED, + .colorspace = V4L2_COLORSPACE_JPEG, + }, +}; + +/** + * msleep_debug: wrapper function calling proper sleep() + * @msecs: time to be sleep (in milli-seconds unit) + * @dbg_on: whether enable log or not. + */ +static void msleep_debug(u32 msecs, bool dbg_on) +{ + u32 delta_halfrange; /* in us unit */ + + if (unlikely(!msecs)) + return; + + if (dbg_on) + cam_dbg("delay for %dms\n", msecs); + + if (msecs <= 7) + delta_halfrange = 100; + else + delta_halfrange = 300; + + if (msecs <= 20) + usleep_range((msecs * 1000 - delta_halfrange), + (msecs * 1000 + delta_halfrange)); + else + msleep(msecs); +} + +#ifdef CONFIG_LOAD_FILE +#define TABLE_MAX_NUM 500 +static char *sr130pc20_regs_table; +static int sr130pc20_regs_table_size; +static int gtable_buf[TABLE_MAX_NUM]; +static int sr130pc20_i2c_write(struct v4l2_subdev *sd, + u8 subaddr, u8 data); + +int sr130pc20_regs_table_init(void) +{ + struct file *filp; + char *dp; + long l; + loff_t pos; + int ret; + mm_segment_t fs = get_fs(); + + cam_info("%s %d\n", __func__, __LINE__); + + set_fs(get_ds()); + + filp = filp_open("/mnt/sdcard/sr130pc20_regs.h", O_RDONLY, 0); + + if (IS_ERR_OR_NULL(filp)) { + cam_err("file open error\n"); + return PTR_ERR(filp); + } + + l = filp->f_path.dentry->d_inode->i_size; + cam_trace("l = %ld\n", l); + //dp = kmalloc(l, GFP_KERNEL); + dp = vmalloc(l); + if (dp == NULL) { + cam_err("Out of Memory\n"); + filp_close(filp, current->files); + return -EINVAL; + } + + pos = 0; + memset(dp, 0, l); + ret = vfs_read(filp, (char __user *)dp, l, &pos); + + if (ret != l) { + cam_err("Failed to read file ret = %d\n", ret); + /*kfree(dp);*/ + vfree(dp); + filp_close(filp, current->files); + return -EINVAL; + } + + filp_close(filp, current->files); + + set_fs(fs); + + sr130pc20_regs_table = dp; + + sr130pc20_regs_table_size = l; + + *((sr130pc20_regs_table + sr130pc20_regs_table_size) - 1) = '\0'; + + printk("sr130pc20_reg_table_init end\n"); + return 0; +} + +void sr130pc20_regs_table_exit(void) +{ + printk(KERN_DEBUG "%s %d\n", __func__, __LINE__); + + if (sr130pc20_regs_table) { + vfree(sr130pc20_regs_table); + sr130pc20_regs_table = NULL; + } +} + +static int sr130pc20_is_hexnum(char *num) +{ + int i = 0; + for (i = 2; num[i] != '\0'; i++) { + if (!((num[i] >= '0' && num[5] <= '9') + || (num[5] >= 'a' && num[5] <= 'f') || (num[5] >= 'A' + && num[5] <= + 'F'))) { + return 0; + } + } + return 1; +} + +static int sr130pc20_write_regs_from_sd(struct v4l2_subdev *sd, + const char *name) +{ + char *start = NULL, *end = NULL, *reg = NULL, *temp = NULL; + unsigned char addr = 0, value = 0; + unsigned short data = 0; + char data_buf[7] = { 0 }; + int err = 0; + + cam_info("Enter!!\n"); + + addr = value = 0; + + *(data_buf + 6) = '\0'; + + start = strnstr(sr130pc20_regs_table, name, sr130pc20_regs_table_size); + if (start == NULL) { + cam_err("[%s : %d] start is NULL\n", __func__, __LINE__); + err = -EIO; + return err; + } + + end = strnstr(start, "};", sr130pc20_regs_table_size); + if (end == NULL) { + cam_err("[%s : %d] end is NULL\n", __func__, __LINE__); + err = -EIO; + return err; + } + + while (1) { + /* Find Address */ + reg = strnstr(start, "0x", sr130pc20_regs_table_size); + if (reg) + start = (reg + 6); + + if ((reg == NULL) || (reg > end)) { + cam_err("[%s : %d] write end of %s\n", + __func__, __LINE__, name); + break; + } + /* Write Value to Address */ + memcpy(data_buf, reg, 6); + + if (sr130pc20_is_hexnum(data_buf) == 0) { + cam_err("[%s : %d] it's not hex number %s\n", + __func__, __LINE__, data_buf); + continue; + } + + err = kstrtou16(data_buf, 16, &data); + if (err < 0) { + cam_err("[%s : %d] kstrtou16 failed\n", + __func__, __LINE__); + } + addr = (data >> 8); + value = (data & 0xff); + + if (addr == 0xff) { + msleep(value * 10); /*one step is 10ms */ + cam_trace("delay %d msec\n", value * 10); + } else { + if (sr130pc20_i2c_write(sd, addr, value) < 0) { + cam_err + ("[%s : %d] fail on sensor_write :" + "addr[0x%04x], value[0x%04x]\n", + __func__, __LINE__, addr, value); + err = -EIO; + return err; + } + cam_trace + ("success on sensor_write :" + "addr[0x%04x], value[0x%04x]\n", addr, value); + } + } + + cam_info("Exit!!\n"); + + return err; +} +#endif + +/** + * sr130pc20_read: read data from sensor with I2C + * Note the data-store way(Big or Little) + */ +static int sr130pc20_i2c_read(struct v4l2_subdev *sd, + u8 subaddr, u8 *data) +{ + int err = -EIO; + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct i2c_msg msg[2]; + u8 buf[16] = {0,}; + int retry = 5; + + + CHECK_ERR_COND_MSG(!client->adapter, -ENODEV, + "can't search i2c client adapter\n"); + + msg[0].addr = client->addr; + msg[0].flags = 0; + msg[0].len = sizeof(subaddr); + msg[0].buf = &subaddr; + + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].len = 1; + msg[1].buf = buf; + + while (retry-- > 0) { + err = i2c_transfer(client->adapter, msg, 2); + if (likely(err == 2)) + break; + cam_err("i2c read: error, read register(0x%X). cnt %d\n", + subaddr, retry); + msleep_debug(POLL_TIME_MS, false); + } + + CHECK_ERR_COND_MSG(err != 2, -EIO, "I2C does not work\n"); + + *data = buf[0]; + + return 0; +} + +/** + * sr130pc20_write: write data with I2C + * Note the data-store way(Big or Little) + */ +static inline int sr130pc20_i2c_write(struct v4l2_subdev *sd, + u8 subaddr, u8 data) +{ + u8 buf[2]; + int err = 0, retry = 5; + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct i2c_msg msg = { + .addr = client->addr, + .flags = 0, + .buf = buf, + .len = 2, + }; + + CHECK_ERR_COND_MSG(!client->adapter, -ENODEV, + "can't search i2c client adapter\n"); + + buf[0] = subaddr; + buf[1] = data; + + while (retry-- > 0) { + err = i2c_transfer(client->adapter, &msg, 1); + if (likely(err == 1)) + break; + cam_err("i2c write: error %d, write 0x%04X, retry %d\n", + err, ((subaddr << 8) | data), retry); + msleep_debug(POLL_TIME_MS, false); + } + + CHECK_ERR_COND_MSG(err != 1, -EIO, "I2C does not work\n"); + return 0; +} + +static int sr130pc20_i2c_burst_write_list(struct v4l2_subdev *sd, + const sr130pc20_regset_t regs[], int size, const char *name) +{ + + cam_err("burst write: not implemented\n"); + + return 0; +} + +static inline int sr130pc20_write_regs(struct v4l2_subdev *sd, + const sr130pc20_regset_t regs[], int size) +{ + int err = 0, i; + u8 subaddr, value; + + cam_trace("size %d\n", size); + + for (i = 0; i < size; i++) { + subaddr = (u8)(regs[i] >> 8); + value = (u8)(regs[i]); + if (unlikely(DELAY_SEQ == subaddr)) + msleep_debug(value * 10, true); + else { + err = sr130pc20_writeb(sd, subaddr, value); + CHECK_ERR_MSG(err, "register set failed\n") + } + } + + return 0; +} + +/* PX: */ +static int sr130pc20_set_from_table(struct v4l2_subdev *sd, + const char *setting_name, + const struct regset_table *table, + u32 table_size, s32 index) +{ + int err = 0; + + cam_trace("set %s index %d\n", setting_name, index); + + CHECK_ERR_COND_MSG(((index < 0) || (index >= table_size)), + -EINVAL, "index(%d) out of range[0:%d] for table for %s\n", + index, table_size, setting_name); + + table += index; + +#ifdef CONFIG_LOAD_FILE + cam_dbg("%s: \"%s\", reg_name=%s\n", __func__, + setting_name, table->name); + return sr130pc20_write_regs_from_sd(sd, table->name); + +#else /* !CONFIG_LOAD_FILE */ + CHECK_ERR_COND_MSG(!table->reg, -EFAULT, \ + "table=%s, index=%d, reg = NULL\n", setting_name, index); +# ifdef DEBUG_WRITE_REGS + cam_dbg("write_regtable: \"%s\", reg_name=%s\n", setting_name, + table->name); +# endif /* DEBUG_WRITE_REGS */ + + if (table->burst) { + err = sr130pc20_i2c_burst_write_list(sd, + table->reg, table->array_size, setting_name); + } else + err = sr130pc20_write_regs(sd, table->reg, table->array_size); + + CHECK_ERR_MSG(err, "write regs(%s), err=%d\n", setting_name, err); + + return 0; +#endif /* CONFIG_LOAD_FILE */ +} + +static inline int sr130pc20_transit_preview_mode(struct v4l2_subdev *sd) +{ + struct sr130pc20_state *state = to_state(sd); + int err = 0; + + if (state->exposure.ae_lock || state->wb.awb_lock) + cam_info("Restore user ae(awb)-lock...\n"); + + err = sr130pc20_set_from_table(sd, "preview_mode", + &state->regs->preview_mode, 1, 0); + + return err; +} + +static inline int sr130pc20_transit_capture_mode(struct v4l2_subdev *sd) +{ + struct sr130pc20_state *state = to_state(sd); + int err = -EIO; + + if (state->capture.lowlux_night) { + cam_info("capture_mode: night lowlux\n"); + err = sr130pc20_set_from_table(sd, "capture_mode_night", + &state->regs->capture_mode_night, 1, 0); + } else + err = sr130pc20_set_from_table(sd, "capture_mode", + &state->regs->capture_mode, 1, 0); + + return err; +} + +/** + * sr130pc20_transit_movie_mode: switch camera mode if needed. + * Note that this fuction should be called from start_preview(). + */ +static inline int sr130pc20_transit_movie_mode(struct v4l2_subdev *sd) +{ + struct sr130pc20_state *state = to_state(sd); + + /* we'll go from the below modes to RUNNING or RECORDING */ + switch (state->runmode) { + case RUNMODE_INIT: + /* case of entering camcorder firstly */ + break; + case RUNMODE_RUNNING_STOP: + /* case of switching from camera to camcorder */ + break; + case RUNMODE_RECORDING_STOP: + /* case of switching from camcorder to camera */ + break; + + default: + break; + } + + return 0; +} + +/** + * sr130pc20_is_hwflash_on - check whether flash device is on + * + * Refer to state->flash.on to check whether flash is in use in driver. + */ +static inline int sr130pc20_is_hwflash_on(struct v4l2_subdev *sd) +{ + struct sr130pc20_state *state = to_state(sd); + +#ifdef SR130PC20_SUPPORT_FLASH + return state->pdata->is_flash_on(); +#else + return 0; +#endif +} + +/** + * sr130pc20_flash_en - contro Flash LED + * @mode: SR130PC20_FLASH_MODE_NORMAL or SR130PC20_FLASH_MODE_MOVIE + * @onoff: SR130PC20_FLASH_ON or SR130PC20_FLASH_OFF + */ +static int sr130pc20_flash_en(struct v4l2_subdev *sd, s32 mode, s32 onoff) +{ + struct sr130pc20_state *state = to_state(sd); + + if (unlikely(state->flash.ignore_flash)) { + cam_warn("WARNING, we ignore flash command.\n"); + return 0; + } + +#ifdef SR130PC20_SUPPORT_FLASH + return state->pdata->flash_en(mode, onoff); +#else + return 0; +#endif +} + +/** + * sr130pc20_flash_torch - turn flash on/off as torch for preflash, recording + * @onoff: SR130PC20_FLASH_ON or SR130PC20_FLASH_OFF + * + * This func set state->flash.on properly. + */ +static inline int sr130pc20_flash_torch(struct v4l2_subdev *sd, s32 onoff) +{ + struct sr130pc20_state *state = to_state(sd); + int err = 0; + + err = sr130pc20_flash_en(sd, SR130PC20_FLASH_MODE_MOVIE, onoff); + state->flash.on = (onoff == SR130PC20_FLASH_ON) ? 1 : 0; + + return err; +} + +/** + * sr130pc20_flash_oneshot - turn main flash on for capture + * @onoff: SR130PC20_FLASH_ON or SR130PC20_FLASH_OFF + * + * Main flash is turn off automatically in some milliseconds. + */ +static inline int sr130pc20_flash_oneshot(struct v4l2_subdev *sd, s32 onoff) +{ + struct sr130pc20_state *state = to_state(sd); + int err = 0; + + err = sr130pc20_flash_en(sd, SR130PC20_FLASH_MODE_NORMAL, onoff); + state->flash.on = (onoff == SR130PC20_FLASH_ON) ? 1 : 0; + + return err; +} + +static const struct sr130pc20_framesize *sr130pc20_get_framesize + (const struct sr130pc20_framesize *frmsizes, + u32 frmsize_count, u32 index) +{ + int i = 0; + + for (i = 0; i < frmsize_count; i++) { + if (frmsizes[i].index == index) + return &frmsizes[i]; + } + + return NULL; +} + +/* This function is called from the g_ctrl api + * + * This function should be called only after the s_fmt call, + * which sets the required width/height value. + * + * It checks a list of available frame sizes and sets the + * most appropriate frame size. + * + * The list is stored in an increasing order (as far as possible). + * Hence the first entry (searching from the beginning) where both the + * width and height is more than the required value is returned. + * In case of no perfect match, we set the last entry (which is supposed + * to be the largest resolution supported.) + */ +static void sr130pc20_set_framesize(struct v4l2_subdev *sd, + const struct sr130pc20_framesize *frmsizes, + u32 num_frmsize, bool preview) +{ + struct sr130pc20_state *state = to_state(sd); + const struct sr130pc20_framesize **found_frmsize = NULL; + u32 width = state->req_fmt.width; + u32 height = state->req_fmt.height; + int i = 0; + + cam_dbg("%s: Requested Res %dx%d\n", __func__, + width, height); + + found_frmsize = preview ? + &state->preview.frmsize : &state->capture.frmsize; + + for (i = 0; i < num_frmsize; i++) { + if ((frmsizes[i].width == width) && + (frmsizes[i].height == height)) { + *found_frmsize = &frmsizes[i]; + break; + } + } + + if (*found_frmsize == NULL) { + cam_err("%s: error, invalid frame size %dx%d\n", + __func__, width, height); + *found_frmsize = preview ? + sr130pc20_get_framesize(frmsizes, num_frmsize, + PREVIEW_SZ_VGA) : + sr130pc20_get_framesize(frmsizes, num_frmsize, + CAPTURE_SZ_1MP); + BUG_ON(!(*found_frmsize)); + } + + if (preview) + cam_info("Preview Res Set: %dx%d, index %d\n", + (*found_frmsize)->width, (*found_frmsize)->height, + (*found_frmsize)->index); + else + cam_info("Capture Res Set: %dx%d, index %d\n", + (*found_frmsize)->width, (*found_frmsize)->height, + (*found_frmsize)->index); +} + +/* PX: Set scene mode */ +static int sr130pc20_set_scene_mode(struct v4l2_subdev *sd, s32 val) +{ + struct sr130pc20_state *state = to_state(sd); + + cam_trace("E, value %d\n", val); + +retry: + switch (val) { + case SCENE_MODE_NONE: + case SCENE_MODE_PORTRAIT: + case SCENE_MODE_NIGHTSHOT: + case SCENE_MODE_BACK_LIGHT: + case SCENE_MODE_LANDSCAPE: + case SCENE_MODE_SPORTS: + case SCENE_MODE_PARTY_INDOOR: + case SCENE_MODE_BEACH_SNOW: + case SCENE_MODE_SUNSET: + case SCENE_MODE_DUSK_DAWN: + case SCENE_MODE_FALL_COLOR: + case SCENE_MODE_FIREWORKS: + case SCENE_MODE_TEXT: + case SCENE_MODE_CANDLE_LIGHT: + sr130pc20_set_from_table(sd, "scene_mode", + state->regs->scene_mode, + ARRAY_SIZE(state->regs->scene_mode), val); + break; + + default: + cam_err("set_scene: error, not supported (%d)\n", val); + val = SCENE_MODE_NONE; + goto retry; + } + + state->scene_mode = val; + + cam_trace("X\n"); + return 0; +} + +/* PX: Set brightness */ +static int sr130pc20_set_exposure(struct v4l2_subdev *sd, s32 val) +{ + struct sr130pc20_state *state = to_state(sd); + int err = 0; + + if ((val < EV_MINUS_4) || (val > EV_PLUS_4)) { + cam_err("%s: error, invalid value(%d)\n", __func__, val); + return -EINVAL; + } + + sr130pc20_set_from_table(sd, "brightness", state->regs->ev, + ARRAY_SIZE(state->regs->ev), GET_EV_INDEX(val)); + + state->exposure.val = val; + + return err; +} + +static int sr130pc20_set_vt_mode(struct v4l2_subdev *sd, s32 val) +{ + struct sr130pc20_state *state = to_state(sd); + int err = 0; + + if (val == PREVIEW_VIDEOCALL) { + err = sr130pc20_set_from_table(sd, "VT_init_reg", + &state->regs->VT_init_reg, 1, 0); + cam_info("VT Mode\n"); + } else if (val == PREVIEW_SMARTSTAY) { + err = sr130pc20_set_from_table(sd, "SS_init_reg", + &state->regs->SS_init_reg, 1, 0); + cam_info("SMART STAY Mode\n"); + } + + state->vt_mode = val; + + return err; +} + +/* PX(NEW) */ +static int sr130pc20_set_capture_size(struct v4l2_subdev *sd) +{ + struct sr130pc20_state *state = to_state(sd); + u32 width, height; + + if (unlikely(!state->capture.frmsize)) { + cam_warn("warning, capture resolution not set\n"); + state->capture.frmsize = sr130pc20_get_framesize( + sr130pc20_capture_frmsizes, + ARRAY_SIZE(sr130pc20_capture_frmsizes), + CAPTURE_SZ_1MP); + } + + width = state->capture.frmsize->width; + height = state->capture.frmsize->height; + + state->preview.update_frmsize = 1; + + cam_dbg("set capture size(%dx%d)\n", width, height); + + return 0; +} + +/* PX: Set sensor mode */ +static int sr130pc20_set_sensor_mode(struct v4l2_subdev *sd, s32 val) +{ + struct sr130pc20_state *state = to_state(sd); + + cam_trace("mode=%d\n", val); + + switch (val) { + case SENSOR_MOVIE: + /* We does not support movie mode when in VT. */ + if (state->vt_mode) { + state->sensor_mode = SENSOR_CAMERA; + cam_err("%s: error, Not support movie\n", __func__); + break; + } + /* We do not break. */ + + case SENSOR_CAMERA: + state->sensor_mode = val; + break; + + default: + cam_err("%s: error, Not support.(%d)\n", __func__, val); + state->sensor_mode = SENSOR_CAMERA; + WARN_ON(1); + break; + } + + return 0; +} + +/* PX: Set framerate */ +static int sr130pc20_set_frame_rate(struct v4l2_subdev *sd, s32 fps) +{ + struct sr130pc20_state *state = to_state(sd); + int err = -EIO; + int i = 0, fps_index = -1; + + if (!state->initialized || (state->req_fps < 0)) + return 0; + + cam_info("set frame rate %d\n", fps); + + if (fps > 25) + fps = 25; /* sensor limitation */ + + for (i = 0; i < ARRAY_SIZE(sr130pc20_framerates); i++) { + if (fps == sr130pc20_framerates[i].fps) { + fps_index = sr130pc20_framerates[i].index; + state->fps = fps; + state->req_fps = -1; + break; + } + } + + if (unlikely(fps_index < 0)) { + cam_err("set_fps: warning, not supported fps %d\n", fps); + return 0; + } + + err = sr130pc20_set_from_table(sd, "fps", state->regs->fps, + ARRAY_SIZE(state->regs->fps), fps_index); + CHECK_ERR_MSG(err, "fail to set framerate\n"); + + /*sr130pc20_control_stream(sd, STREAM_STOP);*/ + + return 0; +} + +static int sr130pc20_control_stream(struct v4l2_subdev *sd, u32 cmd) +{ + struct sr130pc20_state *state = to_state(sd); + int err = -EINVAL; + + if (cmd == STREAM_STOP) { + if (!((state->runmode == RUNMODE_RUNNING) + && state->capture.pre_req)) { + cam_info("STREAM STOP!!\n"); + // [ W/A : Skip stream off sr130pc20 to prevent I2C behavior (P130301-0098) + // - DPM timeout (kernel Panic) happen by I2C behavior during system suspending + // ] + if (state->vt_mode != PREVIEW_SMARTSTAY) { + err = sr130pc20_set_from_table(sd, "stream_stop", + &state->regs->stream_stop, 1, 0); + CHECK_ERR_MSG(err, "failed to stop stream\n"); + } + state->preview.update_frmsize = 1; + } + } else { + cam_info("STREAM START\n"); + return 0; + } + + switch (state->runmode) { + case RUNMODE_CAPTURING: + cam_dbg("Capture Stop!\n"); + state->runmode = RUNMODE_CAPTURING_STOP; + state->capture.ready = 0; + state->capture.lowlux_night = 0; + break; + + case RUNMODE_RUNNING: + cam_dbg("Preview Stop!\n"); + state->runmode = RUNMODE_RUNNING_STOP; + if (state->capture.pre_req) { + sr130pc20_prepare_fast_capture(sd); + state->capture.pre_req = 0; + } + break; + + case RUNMODE_RECORDING: + state->runmode = RUNMODE_RECORDING_STOP; + break; + + default: + break; + } + + /*msleep_debug(state->pdata->streamoff_delay, true);*/ + + return 0; +} + +/* PX: Set flash mode */ +static int sr130pc20_set_flash_mode(struct v4l2_subdev *sd, s32 val) +{ + struct sr130pc20_state *state = to_state(sd); + + /* movie flash mode should be set when recording is started */ +/* if (state->sensor_mode == SENSOR_MOVIE && !state->recording) + return 0;*/ + + if (state->flash.mode == val) { + cam_dbg("the same flash mode=%d\n", val); + return 0; + } + + if (val == FLASH_MODE_TORCH) + sr130pc20_flash_torch(sd, SR130PC20_FLASH_ON); + + if ((state->flash.mode == FLASH_MODE_TORCH) + && (val == FLASH_MODE_OFF)) + sr130pc20_flash_torch(sd, SR130PC20_FLASH_OFF); + + state->flash.mode = val; + cam_dbg("Flash mode = %d\n", val); + return 0; +} + +static int sr130pc20_check_esd(struct v4l2_subdev *sd, s32 val) +{ + u32 data = 0, size_h = 0, size_v = 0; + +/* To do */ + return 0; + +esd_out: + cam_err("Check ESD(%d): ESD Shock detected! val=0x%X\n\n", data, val); + return -ERESTART; +} + +/* returns the real iso currently used by sensor due to lighting + * conditions, not the requested iso we sent using s_ctrl. + */ +static inline int sr130pc20_get_exif_iso(struct v4l2_subdev *sd, u16 *iso) +{ + struct sr130pc20_state *state = to_state(sd); + int err = 0; + u8 read_value = 0; + unsigned short gain_value = 0; + + err = sr130pc20_writeb(sd, 0x03, 0x20); + CHECK_ERR_COND(err < 0, -ENODEV); + sr130pc20_readb(sd, 0xb0, &read_value); + + gain_value = ((read_value * 100) / 32) + 50; + cam_dbg("gain_value=%d, read_value=%d\n", gain_value, read_value); + + if (gain_value < 114) + *iso = 50; + else if (gain_value < 214) + *iso = 100; + else if (gain_value < 264) + *iso = 200; + else if (gain_value < 825) + *iso = 400; + else + *iso = 800; + + cam_dbg("gain_value=%d, ISO=%d\n", gain_value, *iso); + return 0; +} + +/* PX: Set ISO */ +static int __used sr130pc20_set_iso(struct v4l2_subdev *sd, s32 val) +{ + struct sr130pc20_state *state = to_state(sd); + + sr130pc20_set_from_table(sd, "iso", state->regs->iso, + ARRAY_SIZE(state->regs->iso), val); + + state->iso = val; + + cam_trace("X\n"); + return 0; +} + +/* PX: Return exposure time (ms) */ +static inline int sr130pc20_get_exif_exptime(struct v4l2_subdev *sd, + u32 *exp_time) +{ + struct sr130pc20_state *state = to_state(sd); + int err = 0; + u8 read_value1 = 0; + u8 read_value2 = 0; + u8 read_value3 = 0; + + err = sr130pc20_writeb(sd, 0x03, 0x20); + CHECK_ERR_COND(err < 0, -ENODEV); + + sr130pc20_readb(sd, 0x80, &read_value1); + sr130pc20_readb(sd, 0x81, &read_value2); + sr130pc20_readb(sd, 0x82, &read_value3); + + cam_dbg("exposure time read_value %d, %d, %d\n", + read_value1, read_value2, read_value3); + *exp_time = (read_value1 << 19) + + (read_value2 << 11) + (read_value3 << 3); + + cam_dbg("exposure time %dus\n", *exp_time); + return 0; +} + +static inline void sr130pc20_get_exif_flash(struct v4l2_subdev *sd, + u16 *flash) +{ + struct sr130pc20_state *state = to_state(sd); + + *flash = 0; + + switch (state->flash.mode) { + case FLASH_MODE_OFF: + *flash |= EXIF_FLASH_MODE_SUPPRESSION; + break; + + case FLASH_MODE_AUTO: + *flash |= EXIF_FLASH_MODE_AUTO; + break; + + case FLASH_MODE_ON: + case FLASH_MODE_TORCH: + *flash |= EXIF_FLASH_MODE_FIRING; + break; + + default: + break; + } + + if (state->flash.on) + *flash |= EXIF_FLASH_FIRED; +} + +/* PX: */ +static int sr130pc20_get_exif(struct v4l2_subdev *sd) +{ + struct sr130pc20_state *state = to_state(sd); + u32 exposure_time = 0; + u32 int_dec, integer; + int OPCLK = 24000000; + + /* exposure time */ + state->exif.exp_time_den = 0; + sr130pc20_get_exif_exptime(sd, &exposure_time); + if (exposure_time) { + state->exif.exp_time_den = OPCLK / exposure_time; + } else { + state->exif.exp_time_den = 0; + } + + /* iso */ + state->exif.iso = 0; + sr130pc20_get_exif_iso(sd, &state->exif.iso); + + /* flash */ + sr130pc20_get_exif_flash(sd, &state->exif.flash); + + cam_dbg("EXIF: ex_time_den=%d, iso=%d, flash=0x%02X\n", + state->exif.exp_time_den, state->exif.iso, state->exif.flash); + + return 0; +} + +static int sr130pc20_set_preview_size(struct v4l2_subdev *sd) +{ + struct sr130pc20_state *state = to_state(sd); + u32 width, height; + int err = -EINVAL; + + if (!state->preview.update_frmsize) + return 0; + + if (unlikely(!state->preview.frmsize)) { + cam_warn("warning, preview resolution not set\n"); + state->preview.frmsize = sr130pc20_get_framesize( + sr130pc20_preview_frmsizes, + ARRAY_SIZE(sr130pc20_preview_frmsizes), + PREVIEW_SZ_VGA); + } + + width = state->preview.frmsize->width; + height = state->preview.frmsize->height; + + cam_dbg("set preview size(%dx%d)\n", width, height); + + err = sr130pc20_set_from_table(sd, "preview_size", + state->regs->preview_size, ARRAY_SIZE(state->regs->preview_size), + state->preview.frmsize->index); + CHECK_ERR_MSG(err, "fail to set preview size\n"); + + state->preview.update_frmsize = 0; + + return 0; +} + +static int sr130pc20_start_preview(struct v4l2_subdev *sd) +{ + struct sr130pc20_state *state = to_state(sd); + int err = -EINVAL; + + cam_info("Camera Preview start, runmode = %d\n", state->runmode); + + if ((state->runmode == RUNMODE_NOTREADY) || + (state->runmode == RUNMODE_CAPTURING)) { + cam_err("%s: error - Invalid runmode\n", __func__); + return -EPERM; + } + + state->focus.status = AF_RESULT_SUCCESS; + + /* Transit preview mode */ + err = sr130pc20_transit_preview_mode(sd); + CHECK_ERR_MSG(err, "preview_mode(%d)\n", err); + + /* Set preview size */ + sr130pc20_set_preview_size(sd); + + sr130pc20_control_stream(sd, STREAM_START); + + state->runmode = (state->sensor_mode == SENSOR_CAMERA) ? + RUNMODE_RUNNING : RUNMODE_RECORDING; + return 0; +} + +static int sr130pc20_set_capture(struct v4l2_subdev *sd) +{ + struct sr130pc20_state *state = to_state(sd); + int err = 0; + + cam_info("set_capture\n"); + + /* Set capture size */ + sr130pc20_set_capture_size(sd); + + /* Transit to capture mode */ + err = sr130pc20_transit_capture_mode(sd); + CHECK_ERR_MSG(err, "fail to capture_mode (%d)\n", err); + return 0; +} + +static int sr130pc20_prepare_fast_capture(struct v4l2_subdev *sd) +{ + struct sr130pc20_state *state = to_state(sd); + int err = 0; + + cam_info("prepare_fast_capture\n"); + + state->req_fmt.width = (state->capture.pre_req >> 16); + state->req_fmt.height = (state->capture.pre_req & 0xFFFF); + sr130pc20_set_framesize(sd, sr130pc20_capture_frmsizes, + ARRAY_SIZE(sr130pc20_capture_frmsizes), false); + + err = sr130pc20_set_capture(sd); + CHECK_ERR(err); + + state->capture.ready = 1; + + return 0; +} + +static int sr130pc20_start_capture(struct v4l2_subdev *sd) +{ + struct sr130pc20_state *state = to_state(sd); + int err = -ENODEV, count; + u32 val = 0; + u32 night_delay; + + cam_info("start_capture\n"); + + if (!state->capture.ready) { + err = sr130pc20_set_capture(sd); + CHECK_ERR(err); + + sr130pc20_control_stream(sd, STREAM_START); + night_delay = 500; + } else + night_delay = 700; /* for completely skipping 1 frame. */ + + state->runmode = RUNMODE_CAPTURING; + + if (state->capture.lowlux_night) + msleep_debug(night_delay, true); + + /* Get EXIF */ + sr130pc20_get_exif(sd); + + return 0; +} + +/** + * sr200pc20_init_regs: Indentify chip and get pointer to reg table + * @ + */ +static int sr130pc20_init_regs(struct v4l2_subdev *sd) +{ + struct sr130pc20_state *state = to_state(sd); + int err = -ENODEV; + u8 read_value = 0; + + err = sr130pc20_writeb(sd, 0x03, 0x00); + CHECK_ERR_COND(err < 0, -ENODEV); + + sr130pc20_readb(sd, 0x04, &read_value); + if (SR130PC20_CHIP_ID == read_value) + cam_info("Sensor ChipID: 0x%02X\n", SR130PC20_CHIP_ID); + else + cam_info("Sensor ChipID: 0x%02X, unknown chipID\n", read_value); + + state->regs = ®_datas; + + return 0; +} + + +/* PX(NEW) */ +static int sr130pc20_s_mbus_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt) +{ + struct sr130pc20_state *state = to_state(sd); + s32 previous_index = 0; + + cam_dbg("%s: pixelformat = 0x%x, colorspace = 0x%x, width = %d, height = %d\n", + __func__, fmt->code, fmt->colorspace, fmt->width, fmt->height); + + v4l2_fill_pix_format(&state->req_fmt, fmt); + if (fmt->field < IS_MODE_CAPTURE_STILL) + state->format_mode = V4L2_PIX_FMT_MODE_PREVIEW; + else + state->format_mode = V4L2_PIX_FMT_MODE_CAPTURE; + + if (state->format_mode != V4L2_PIX_FMT_MODE_CAPTURE) { + previous_index = state->preview.frmsize ? + state->preview.frmsize->index : -1; + sr130pc20_set_framesize(sd, sr130pc20_preview_frmsizes, + ARRAY_SIZE(sr130pc20_preview_frmsizes), true); + + if (previous_index != state->preview.frmsize->index) + state->preview.update_frmsize = 1; + } else { + /* + * In case of image capture mode, + * if the given image resolution is not supported, + * use the next higher image resolution. */ + sr130pc20_set_framesize(sd, sr130pc20_capture_frmsizes, + ARRAY_SIZE(sr130pc20_capture_frmsizes), false); + + /* for maket app. + * Samsung camera app does not use unmatched ratio.*/ + if (unlikely(NULL == state->preview.frmsize)) { + cam_warn("warning, capture without preview resolution\n"); + } else if (unlikely(FRM_RATIO(state->preview.frmsize) + != FRM_RATIO(state->capture.frmsize))) { + cam_warn("warning, capture ratio " \ + "is different with preview ratio\n"); + } + } + + return 0; +} + +static int sr130pc20_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + cam_dbg("%s: index = %d\n", __func__, index); + + if (index >= ARRAY_SIZE(capture_fmts)) + return -EINVAL; + + *code = capture_fmts[index].code; + + return 0; +} + +static int sr130pc20_try_mbus_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt) +{ + int num_entries; + int i; + + num_entries = ARRAY_SIZE(capture_fmts); + + cam_dbg("%s: code = 0x%x , colorspace = 0x%x, num_entries = %d\n", + __func__, fmt->code, fmt->colorspace, num_entries); + + for (i = 0; i < num_entries; i++) { + if (capture_fmts[i].code == fmt->code && + capture_fmts[i].colorspace == fmt->colorspace) { + cam_info("%s: match found, returning 0\n", __func__); + return 0; + } + } + + cam_err("%s: no match found, returning -EINVAL\n", __func__); + return -EINVAL; +} + + +static int sr130pc20_enum_framesizes(struct v4l2_subdev *sd, + struct v4l2_frmsizeenum *fsize) +{ + struct sr130pc20_state *state = to_state(sd); + + /* + * The camera interface should read this value, this is the resolution + * at which the sensor would provide framedata to the camera i/f + * In case of image capture, + * this returns the default camera resolution (VGA) + */ + if (state->format_mode != V4L2_PIX_FMT_MODE_CAPTURE) { + if (unlikely(state->preview.frmsize == NULL)) { + cam_err("%s: error\n", __func__); + return -EFAULT; + } + + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; + fsize->discrete.width = state->preview.frmsize->width; + fsize->discrete.height = state->preview.frmsize->height; + } else { + if (unlikely(state->capture.frmsize == NULL)) { + cam_err("%s: error\n", __func__); + return -EFAULT; + } + + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; + fsize->discrete.width = state->capture.frmsize->width; + fsize->discrete.height = state->capture.frmsize->height; + } + + return 0; +} + +static int sr130pc20_g_parm(struct v4l2_subdev *sd, + struct v4l2_streamparm *param) +{ + return 0; +} + +static int sr130pc20_s_parm(struct v4l2_subdev *sd, + struct v4l2_streamparm *param) +{ + struct sr130pc20_state *state = to_state(sd); + + state->req_fps = param->parm.capture.timeperframe.denominator / + param->parm.capture.timeperframe.numerator; + + cam_dbg("s_parm state->fps=%d, state->req_fps=%d\n", + state->fps, state->req_fps); + + if ((state->req_fps < 0) || (state->req_fps > 30)) { + cam_err("%s: error, invalid frame rate %d. we'll set to 30\n", + __func__, state->req_fps); + state->req_fps = 0; + } + + return sr130pc20_set_frame_rate(sd, state->req_fps); +} + +static int sr130pc20_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct sr130pc20_state *state = to_state(sd); + int err = 0; + + if (!state->initialized) { + cam_err("%s: WARNING, camera not initialized\n", __func__); + return 0; + } + + mutex_lock(&state->ctrl_lock); + + switch (ctrl->id) { + case V4L2_CID_CAMERA_EXIF_EXPTIME: + if (state->sensor_mode == SENSOR_CAMERA) + ctrl->value = state->exif.exp_time_den; + else + ctrl->value = 24; + break; + + case V4L2_CID_CAMERA_EXIF_ISO: + if (state->sensor_mode == SENSOR_CAMERA) + ctrl->value = state->exif.iso; + else + ctrl->value = 100; + break; + + case V4L2_CID_CAMERA_EXIF_FLASH: + if (state->sensor_mode == SENSOR_CAMERA) + ctrl->value = state->exif.flash; + else + sr130pc20_get_exif_flash(sd, (u16 *)ctrl->value); + break; + +#if !defined(CONFIG_CAM_YUV_CAPTURE) + case V4L2_CID_CAM_JPEG_MAIN_SIZE: + ctrl->value = state->jpeg.main_size; + break; + + case V4L2_CID_CAM_JPEG_MAIN_OFFSET: + ctrl->value = state->jpeg.main_offset; + break; + + case V4L2_CID_CAM_JPEG_THUMB_SIZE: + ctrl->value = state->jpeg.thumb_size; + break; + + case V4L2_CID_CAM_JPEG_THUMB_OFFSET: + ctrl->value = state->jpeg.thumb_offset; + break; + + case V4L2_CID_CAM_JPEG_QUALITY: + ctrl->value = state->jpeg.quality; + break; + + case V4L2_CID_CAM_JPEG_MEMSIZE: + ctrl->value = SENSOR_JPEG_SNAPSHOT_MEMSIZE; + break; +#endif + + case V4L2_CID_CAMERA_AUTO_FOCUS_RESULT: + ctrl->value = state->focus.status; + break; + + case V4L2_CID_CAMERA_WHITE_BALANCE: + case V4L2_CID_CAMERA_EFFECT: + case V4L2_CID_CAMERA_CONTRAST: + case V4L2_CID_CAMERA_SATURATION: + case V4L2_CID_CAMERA_SHARPNESS: + case V4L2_CID_CAMERA_OBJ_TRACKING_STATUS: + case V4L2_CID_CAMERA_SMART_AUTO_STATUS: + default: + cam_err("%s: WARNING, unknown Ctrl-ID 0x%x\n", + __func__, ctrl->id); + err = 0; /* we return no error. */ + break; + } + + mutex_unlock(&state->ctrl_lock); + + return err; +} + +static int sr130pc20_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct sr130pc20_state *state = to_state(sd); + int err = 0; + + if (!state->initialized && ctrl->id != V4L2_CID_CAMERA_SENSOR_MODE + && ctrl->id != V4L2_CID_CAMERA_VT_MODE) { + cam_warn("%s: WARNING, camera not initialized. ID = %d(0x%X)\n", + __func__, ctrl->id - V4L2_CID_PRIVATE_BASE, + ctrl->id - V4L2_CID_PRIVATE_BASE); + return 0; + } + + cam_dbg("%s: ID =%d, val = %d\n", + __func__, ctrl->id - V4L2_CID_PRIVATE_BASE, ctrl->value); + + mutex_lock(&state->ctrl_lock); + + switch (ctrl->id) { + case V4L2_CID_CAMERA_SENSOR_MODE: + err = sr130pc20_set_sensor_mode(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_BRIGHTNESS: + err = sr130pc20_set_exposure(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_WHITE_BALANCE: + err = sr130pc20_set_from_table(sd, "white balance", + state->regs->white_balance, + ARRAY_SIZE(state->regs->white_balance), ctrl->value); + state->wb.mode = ctrl->value; + break; + + case V4L2_CID_CAMERA_EFFECT: + err = sr130pc20_set_from_table(sd, "effects", + state->regs->effect, + ARRAY_SIZE(state->regs->effect), ctrl->value); + break; + + case V4L2_CID_CAMERA_METERING: + err = sr130pc20_set_from_table(sd, "metering", + state->regs->metering, + ARRAY_SIZE(state->regs->metering), ctrl->value); + break; + + case V4L2_CID_CAMERA_SCENE_MODE: + err = sr130pc20_set_scene_mode(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_CHECK_ESD: + err = sr130pc20_check_esd(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_ISO: + err = sr130pc20_set_iso(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_CAPTURE_MODE: + if (RUNMODE_RUNNING == state->runmode) + state->capture.pre_req = ctrl->value; + break; + + case V4L2_CID_CAMERA_VT_MODE: + err = sr130pc20_set_vt_mode(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_ANTI_BANDING: + break; + + case V4L2_CID_CAMERA_OBJECT_POSITION_X: + case V4L2_CID_CAMERA_OBJECT_POSITION_Y: + case V4L2_CID_CAMERA_TOUCH_AF_START_STOP: + case V4L2_CID_CAMERA_FOCUS_MODE: + case V4L2_CID_CAMERA_SET_AUTO_FOCUS: + case V4L2_CID_CAMERA_FLASH_MODE: + case V4L2_CID_CAMERA_CONTRAST: + case V4L2_CID_CAMERA_SATURATION: + case V4L2_CID_CAMERA_SHARPNESS: + case V4L2_CID_CAMERA_FRAME_RATE: + case V4L2_CID_CAMERA_AE_LOCK_UNLOCK: + case V4L2_CID_CAMERA_AWB_LOCK_UNLOCK: + default: + cam_err("%s: WARNING, unknown Ctrl-ID 0x%x\n", + __func__, ctrl->id); + /* we return no error. */ + break; + } + + mutex_unlock(&state->ctrl_lock); + CHECK_ERR_MSG(err, "s_ctrl failed %d\n", err) + + return 0; +} + +static int sr130pc20_s_ext_ctrl(struct v4l2_subdev *sd, + struct v4l2_ext_control *ctrl) +{ + return 0; +} + +static int sr130pc20_s_ext_ctrls(struct v4l2_subdev *sd, + struct v4l2_ext_controls *ctrls) +{ + struct v4l2_ext_control *ctrl = ctrls->controls; + int ret; + int i; + + for (i = 0; i < ctrls->count; i++, ctrl++) { + ret = sr130pc20_s_ext_ctrl(sd, ctrl); + + if (ret) { + ctrls->error_idx = i; + break; + } + } + + return ret; +} + +static int sr130pc20_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct sr130pc20_state *state = to_state(sd); + int err = 0; + + cam_info("stream mode = %d\n", enable); + + BUG_ON(!state->initialized); + + switch (enable) { + case STREAM_MODE_CAM_OFF: + if (state->pdata->is_mipi) + err = sr130pc20_control_stream(sd, STREAM_STOP); + break; + + case STREAM_MODE_CAM_ON: + switch (state->sensor_mode) { + case SENSOR_CAMERA: + if (state->format_mode == V4L2_PIX_FMT_MODE_CAPTURE) + err = sr130pc20_start_capture(sd); + else + err = sr130pc20_start_preview(sd); + break; + + case SENSOR_MOVIE: + err = sr130pc20_start_preview(sd); + break; + + default: + break; + } + break; + + case STREAM_MODE_MOVIE_OFF: + cam_info("movie off"); + state->recording = 0; + break; + + case STREAM_MODE_MOVIE_ON: + cam_info("movie on"); + state->recording = 1; + break; + + default: + cam_err("%s: error - Invalid stream mode\n", __func__); + break; + } + + CHECK_ERR_MSG(err, "failed\n"); + + return 0; +} + +static inline int sr130pc20_check_i2c(struct v4l2_subdev *sd, u16 data) +{ + int err; + u32 val = 0; + + err = sr130pc20_readw(sd, 0x0000, &val); + if (unlikely(err)) + return err; + + cam_dbg("version: 0x%04X is 0x6017?\n", val); + return 0; +} + +static void sr130pc20_init_parameter(struct v4l2_subdev *sd) +{ + struct sr130pc20_state *state = to_state(sd); + + state->runmode = RUNMODE_INIT; + + /* Default state values */ + state->scene_mode = SCENE_MODE_NONE; + state->wb.mode = WHITE_BALANCE_AUTO; + state->light_level = LUX_LEVEL_MAX; + + /* Set update_frmsize to 1 for case of power reset */ + state->preview.update_frmsize = 1; + + /* Initialize focus field for case of init after power reset. */ + memset(&state->focus, 0, sizeof(state->focus)); + + state->lux_level_flash = LUX_LEVEL_FLASH_ON; + state->shutter_level_flash = 0x0; + +} + +static int sr130pc20_init(struct v4l2_subdev *sd, u32 val) +{ + struct sr130pc20_state *state = to_state(sd); + int err = -EINVAL; + + cam_info("init: start (%s)\n", __DATE__); + +#ifdef CONFIG_LOAD_FILE + err = sr130pc20_regs_table_init(); + CHECK_ERR_MSG(err, "loading setfile fail!\n"); +#endif + err = sr130pc20_init_regs(sd); + CHECK_ERR_MSG(err, "failed to indentify sensor chip\n"); + + err = sr130pc20_set_from_table(sd, "init_reg", + &state->regs->init_reg, 1, 0); + + CHECK_ERR_MSG(err, "failed to initialize camera device\n"); + sr130pc20_init_parameter(sd); + state->initialized = 1; + + return 0; +} + +/* + * s_config subdev ops + * With camera device, we need to re-initialize + * every single opening time therefor, + * it is not necessary to be initialized on probe time. + * except for version checking + * NOTE: version checking is optional + */ +static int sr130pc20_s_config(struct v4l2_subdev *sd, + int irq, void *platform_data) +{ + struct sr130pc20_state *state = to_state(sd); + int i; + + if (!platform_data) { + cam_err("%s: error, no platform data\n", __func__); + return -ENODEV; + } + state->pdata = platform_data; + state->dbg_level = &state->pdata->dbg_level; + + /* + * Assign default format and resolution + * Use configured default information in platform data + * or without them, use default information in driver + */ + state->req_fmt.width = state->pdata->default_width; + state->req_fmt.height = state->pdata->default_height; + + if (!state->pdata->pixelformat) + state->req_fmt.pixelformat = DEFAULT_PIX_FMT; + else + state->req_fmt.pixelformat = state->pdata->pixelformat; + + if (!state->pdata->freq) + state->freq = DEFAULT_MCLK; /* 24MHz default */ + else + state->freq = state->pdata->freq; + + state->preview.frmsize = state->capture.frmsize = NULL; + state->sensor_mode = SENSOR_CAMERA; + state->format_mode = V4L2_PIX_FMT_MODE_PREVIEW; + state->fps = 0; + state->req_fps = -1; + + /* Initialize the independant HW module like flash here */ + state->flash.mode = FLASH_MODE_OFF; + state->flash.on = 0; + + for (i = 0; i < ARRAY_SIZE(sr130pc20_ctrls); i++) + sr130pc20_ctrls[i].value = sr130pc20_ctrls[i].default_value; + +#ifdef SR130PC20_SUPPORT_FLASH + if (sr130pc20_is_hwflash_on(sd)) + state->flash.ignore_flash = 1; +#endif + + state->regs = ®_datas; + + return 0; +} + +static const struct v4l2_subdev_core_ops sr130pc20_core_ops = { + .init = sr130pc20_init, /* initializing API */ + .g_ctrl = sr130pc20_g_ctrl, + .s_ctrl = sr130pc20_s_ctrl, + .s_ext_ctrls = sr130pc20_s_ext_ctrls, + /*eset = sr130pc20_reset, */ +}; + +static const struct v4l2_subdev_video_ops sr130pc20_video_ops = { + .s_mbus_fmt = sr130pc20_s_mbus_fmt, + .enum_framesizes = sr130pc20_enum_framesizes, + .enum_mbus_fmt = sr130pc20_enum_mbus_fmt, + .try_mbus_fmt = sr130pc20_try_mbus_fmt, + .g_parm = sr130pc20_g_parm, + .s_parm = sr130pc20_s_parm, + .s_stream = sr130pc20_s_stream, +}; + +static const struct v4l2_subdev_ops sr130pc20_ops = { + .core = &sr130pc20_core_ops, + .video = &sr130pc20_video_ops, +}; + + +/* + * sr130pc20_probe + * Fetching platform data is being done with s_config subdev call. + * In probe routine, we just register subdev device + */ +static int sr130pc20_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct v4l2_subdev *sd; + struct sr130pc20_state *state; + int err = -EINVAL; + + state = kzalloc(sizeof(struct sr130pc20_state), GFP_KERNEL); + if (unlikely(!state)) { + dev_err(&client->dev, "probe, fail to get memory\n"); + return -ENOMEM; + } + + mutex_init(&state->ctrl_lock); + + state->runmode = RUNMODE_NOTREADY; + sd = &state->sd; + strcpy(sd->name, SR130PC20_DRIVER_NAME); + + /* Registering subdev */ + v4l2_i2c_subdev_init(sd, client, &sr130pc20_ops); + + state->workqueue = create_workqueue("cam_workqueue"); + if (unlikely(!state->workqueue)) { + dev_err(&client->dev, "probe, fail to create workqueue\n"); + goto err_out; + } + + err = sr130pc20_s_config(sd, 0, client->dev.platform_data); + CHECK_ERR_MSG(err, "fail to s_config\n"); + + printk(KERN_DEBUG "%s %s: driver probed!!\n", + dev_driver_string(&client->dev), dev_name(&client->dev)); + + return 0; + +err_out: + kfree(state); + return -ENOMEM; +} + +static int sr130pc20_remove(struct i2c_client *client) +{ + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct sr130pc20_state *state = to_state(sd); + + destroy_workqueue(state->workqueue); + + /* Check whether flash is on when unlolading driver, + * to preventing Market App from controlling improperly flash. + * It isn't necessary in case that you power flash down + * in power routine to turn camera off.*/ + if (unlikely(state->flash.on && !state->flash.ignore_flash)) + sr130pc20_flash_torch(sd, SR130PC20_FLASH_OFF); + + v4l2_device_unregister_subdev(sd); + mutex_destroy(&state->ctrl_lock); + kfree(state); + + printk(KERN_DEBUG "%s %s: driver removed!!\n", + dev_driver_string(&client->dev), dev_name(&client->dev)); + return 0; +} + +static int is_sysdev(struct device *dev, void *str) +{ + return !strcmp(dev_name(dev), (char *)str) ? 1 : 0; +} + +static ssize_t cam_loglevel_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + char temp_buf[60] = {0,}; + + sprintf(buf, "Log Level: "); + if (dbg_level & CAMDBG_LEVEL_TRACE) { + sprintf(temp_buf, "trace "); + strcat(buf, temp_buf); + } + + if (dbg_level & CAMDBG_LEVEL_DEBUG) { + sprintf(temp_buf, "debug "); + strcat(buf, temp_buf); + } + + if (dbg_level & CAMDBG_LEVEL_INFO) { + sprintf(temp_buf, "info "); + strcat(buf, temp_buf); + } + + sprintf(temp_buf, "\n - warn and error level is always on\n\n"); + strcat(buf, temp_buf); + + return strlen(buf); +} + +static ssize_t cam_loglevel_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + printk(KERN_DEBUG "CAM buf=%s, count=%d\n", buf, count); + + if (strstr(buf, "trace")) + dbg_level |= CAMDBG_LEVEL_TRACE; + else + dbg_level &= ~CAMDBG_LEVEL_TRACE; + + if (strstr(buf, "debug")) + dbg_level |= CAMDBG_LEVEL_DEBUG; + else + dbg_level &= ~CAMDBG_LEVEL_DEBUG; + + if (strstr(buf, "info")) + dbg_level |= CAMDBG_LEVEL_INFO; + + return count; +} + +static DEVICE_ATTR(loglevel, 0664, cam_loglevel_show, cam_loglevel_store); + +static int sr130pc20_create_dbglogfile(struct class *cls) +{ + struct device *dev; + int err; + + dbg_level |= CAMDBG_LEVEL_DEFAULT; + + dev = class_find_device(cls, NULL, "front", is_sysdev); + if (unlikely(!dev)) { + pr_info("[SR130PC20] can not find front device\n"); + return 0; + } + + err = device_create_file(dev, &dev_attr_loglevel); + if (unlikely(err < 0)) { + pr_err("cam_init: failed to create device file, %s\n", + dev_attr_loglevel.attr.name); + } + + return 0; +} + +static const struct i2c_device_id sr130pc20_id[] = { + { SR130PC20_DRIVER_NAME, 0 }, + {} +}; + +MODULE_DEVICE_TABLE(i2c, sr130pc20_id); + +static struct i2c_driver v4l2_i2c_driver = { + .driver.name = SR130PC20_DRIVER_NAME, + .probe = sr130pc20_probe, + .remove = sr130pc20_remove, + .id_table = sr130pc20_id, +}; + +static int __init v4l2_i2c_drv_init(void) +{ + pr_info("%s: %s called\n", __func__, SR130PC20_DRIVER_NAME); /* dslim*/ + sr130pc20_create_file(camera_class); + sr130pc20_create_dbglogfile(camera_class); + return i2c_add_driver(&v4l2_i2c_driver); +} + +static void __exit v4l2_i2c_drv_cleanup(void) +{ + pr_info("%s: %s called\n", __func__, SR130PC20_DRIVER_NAME); /* dslim*/ + i2c_del_driver(&v4l2_i2c_driver); +} + +module_init(v4l2_i2c_drv_init); +module_exit(v4l2_i2c_drv_cleanup); + +MODULE_DESCRIPTION("SILICONFILE SR130PC20 1.3MP SOC camera driver"); +MODULE_AUTHOR("Dong-Seong Lim "); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/sr130pc20.h b/drivers/media/video/sr130pc20.h new file mode 100755 index 0000000..a831007 --- /dev/null +++ b/drivers/media/video/sr130pc20.h @@ -0,0 +1,646 @@ +/* drivers/media/video/sr130pc20.h + * + * Driver for sr130pc20 (1.5MP Camera) from siliconfile + * + * Copyright (C) 2010, SAMSUNG ELECTRONICS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * - change date: 2012.06.28 + */ + +#ifndef __SR130PC20_H__ +#define __SR130PC20_H__ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SR130PC20_DRIVER_NAME "SR130PC20" + +#define SR130PC20_DELAY 0xFFFF0000 + +/************************************ + * FEATURE DEFINITIONS + ************************************/ +#define CONFIG_CAM_YUV_CAPTURE +#define CONFIG_CAM_I2C_LITTLE_ENDIAN +/* #define CONFIG_LOAD_FILE *//* for tuning */ +/* #define CONFIG_DEBUG_NO_FRAME */ + +/** Debuging Feature **/ +// #define CONFIG_CAM_DEBUG */ +// #define CONFIG_CAM_TRACE *//* Enable it with CONFIG_CAM_DEBUG */ +// #define CONFIG_CAM_AF_DEBUG *//* Enable it with CONFIG_CAM_DEBUG */ +#define DEBUG_WRITE_REGS +/***********************************/ + +#ifdef CONFIG_VIDEO_SR130PC20_DEBUG +enum { + SR130PC20_DEBUG_I2C = 1U << 0, + SR130PC20_DEBUG_I2C_BURSTS = 1U << 1, +}; +static uint32_t sr130pc20_debug_mask = SR130PC20_DEBUG_I2C_BURSTS; +module_param_named(debug_mask, sr130pc20_debug_mask, uint, S_IWUSR | S_IRUGO); + +#define sr130pc20_debug(mask, x...) \ + do { \ + if (sr130pc20_debug_mask & mask) \ + pr_info(x); \ + } while (0) +#else +#define sr130pc20_debug(mask, x...) +#endif + +#define TAG_NAME "["SR130PC20_DRIVER_NAME"]"" " + +/* Define debug level */ +#define CAMDBG_LEVEL_ERR (1 << 0) +#define CAMDBG_LEVEL_WARN (1 << 1) +#define CAMDBG_LEVEL_INFO (1 << 2) +#define CAMDBG_LEVEL_DEBUG (1 << 3) +#define CAMDBG_LEVEL_TRACE (1 << 4) +#define CAMDBG_LEVEL_DEFAULT \ + (CAMDBG_LEVEL_ERR | CAMDBG_LEVEL_WARN | CAMDBG_LEVEL_INFO) + +#define cam_err(fmt, ...) \ + printk(KERN_ERR TAG_NAME fmt, ##__VA_ARGS__) +#define cam_warn(fmt, ...) \ + printk(KERN_WARNING TAG_NAME fmt, ##__VA_ARGS__) +#define cam_info(fmt, ...) \ + printk(KERN_INFO TAG_NAME fmt, ##__VA_ARGS__) + +#if defined(CONFIG_CAM_DEBUG) +#define cam_dbg(fmt, ...) \ + printk(KERN_DEBUG TAG_NAME fmt, ##__VA_ARGS__) +#else +#define cam_dbg(fmt, ...) \ + do { \ + if (dbg_level & CAMDBG_LEVEL_DEBUG) \ + printk(KERN_DEBUG TAG_NAME fmt, ##__VA_ARGS__); \ + } while (0) +#endif + +#if defined(CONFIG_CAM_DEBUG) && defined(CONFIG_CAM_TRACE) +#define cam_trace(fmt, ...) cam_dbg("%s: " fmt, __func__, ##__VA_ARGS__); +#else +#define cam_trace(fmt, ...) \ + do { \ + if (dbg_level & CAMDBG_LEVEL_TRACE) \ + printk(KERN_DEBUG TAG_NAME "%s: " fmt, \ + __func__, ##__VA_ARGS__); \ + } while (0) +#endif + +#if defined(CONFIG_CAM_DEBUG) && defined(CONFIG_CAM_AF_DEBUG) +#define af_dbg(fmt, ...) cam_dbg(fmt, ##__VA_ARGS__); +#else +#define af_dbg(fmt, ...) +#endif +#if defined(CONFIG_CAM_DEBUG) && defined(CONFIG_CAM_BOOT_DEBUG) +#define boot_dbg(fmt, ...) cam_dbg(fmt, ##__VA_ARGS__); +#else +#define boot_dbg(fmt, ...) +#endif + +#if 0 +#define cam_bug_on(arg...) \ + do { cam_err(arg); BUG_ON(1); } while (0) +#else +#define cam_bug_on(arg...) +#endif + +#define CHECK_ERR_COND(condition, ret) \ + do { if (unlikely(condition)) return ret; } while (0) +#define CHECK_ERR_COND_MSG(condition, ret, fmt, ...) \ + if (unlikely(condition)) { \ + cam_err("%s: error, " fmt, __func__, ##__VA_ARGS__); \ + return ret; \ + } + +#define CHECK_ERR(x) CHECK_ERR_COND(((x) < 0), (x)) +#define CHECK_ERR_MSG(x, fmt, ...) \ + CHECK_ERR_COND_MSG(((x) < 0), (x), fmt, ##__VA_ARGS__) + +/* result values returned to HAL */ +enum af_result_status { + AF_RESULT_NONE = 0x00, + AF_RESULT_FAILED = 0x01, + AF_RESULT_SUCCESS = 0x02, + AF_RESULT_CANCELLED = 0x04, + AF_RESULT_DOING = 0x08 +}; + +enum af_operation_status { + AF_NONE = 0, + AF_START, + AF_CANCEL, +}; + +enum preflash_status { + PREFLASH_NONE = 0, + PREFLASH_OFF, + PREFLASH_ON, +}; + +enum sr130pc20_oprmode { + SR130PC20_OPRMODE_VIDEO = 0, + SR130PC20_OPRMODE_IMAGE = 1, +}; + +enum stream_cmd { + STREAM_STOP, + STREAM_START, +}; + +enum wide_req_cmd { + WIDE_REQ_NONE, + WIDE_REQ_CHANGE, + WIDE_REQ_RESTORE, +}; + +/* Preview Size List: refer to the belows. */ +enum sr130pc20_preview_frame_size { + PREVIEW_SZ_QCIF = 0, /* 176x144 */ + PREVIEW_SZ_320x240, /* 320x240 */ + PREVIEW_SZ_CIF, /* 352x288 */ + PREVIEW_SZ_528x432, /* 528x432 */ + PREVIEW_SZ_VGA, /* 640x480 */ + PREVIEW_SZ_D1, /* 720x480 */ + PREVIEW_SZ_880x720, /* 880x720 */ + PREVIEW_SZ_SVGA, /* 800x600 */ + PREVIEW_SZ_1024x576, /* 1024x576, 16:9 */ + PREVIEW_SZ_1024x616, /* 1024x616, ? */ + PREVIEW_SZ_XGA, /* 1024x768 */ + PREVIEW_SZ_PVGA, /* 1280x720 */ + PREVIEW_SZ_SXGA, /* 1280x1024 */ + PREVIEW_SZ_MAX, +}; + +/* Capture Size List: Capture size is defined as below. + * + * CAPTURE_SZ_VGA: 640x480 + * CAPTURE_SZ_WVGA: 800x480 + * CAPTURE_SZ_SVGA: 800x600 + * CAPTURE_SZ_WSVGA: 1024x600 + * CAPTURE_SZ_1MP: 1280x960 + * CAPTURE_SZ_W1MP: 1600x960 + * CAPTURE_SZ_2MP: UXGA - 1600x1200 + * CAPTURE_SZ_W2MP: 35mm Academy Offset Standard 1.66 + * 2048x1232, 2.4MP + * CAPTURE_SZ_3MP: QXGA - 2048x1536 + * CAPTURE_SZ_W4MP: WQXGA - 2560x1536 + * CAPTURE_SZ_5MP: 2560x1920 + */ + +enum sr130pc20_capture_frame_size { + /*CAPTURE_SZ_VGA = 0,*/ /* 640x480 */ + /*CAPTURE_SZ_960_720,*/ + CAPTURE_SZ_1MP,/* 1280x960 */ + CAPTURE_SZ_MAX, +}; + +#define PREVIEW_WIDE_SIZE PREVIEW_SZ_1024x576 +#define CAPTURE_WIDE_SIZE CAPTURE_SZ_W2MP + +enum frame_ratio { + FRMRATIO_QCIF = 12, /* 11 : 9 */ + FRMRATIO_VGA = 13, /* 4 : 3 */ + FRMRATIO_D1 = 15, /* 3 : 2 */ + FRMRATIO_WVGA = 16, /* 5 : 3 */ + FRMRATIO_HD = 17, /* 16 : 9 */ +}; + +enum sr130pc20_fps_index { + I_FPS_0, + I_FPS_7, + I_FPS_10, + I_FPS_12, + I_FPS_15, + I_FPS_25, + I_FPS_30, + I_FPS_MAX, +}; + +enum ae_awb_lock { + AEAWB_UNLOCK = 0, + AEAWB_LOCK, + AEAWB_LOCK_MAX, +}; + +enum runmode { + RUNMODE_NOTREADY, + RUNMODE_INIT, + /*RUNMODE_IDLE,*/ + RUNMODE_RUNNING, /* previewing */ + RUNMODE_RUNNING_STOP, + RUNMODE_CAPTURING, + RUNMODE_CAPTURING_STOP, + RUNMODE_RECORDING, /* camcorder mode */ + RUNMODE_RECORDING_STOP, +}; + +enum sr130pc20_stby_type { + SR130PC20_STBY_HW, + SR130PC20_STBY_SW, +}; + +enum sr130_pc20_preview_mode { + PREVIEW_CAMERA = 1, + PREVIEW_VIDEOCALL, + PREVIEW_SMARTSTAY, +}; + +struct sr130pc20_control { + u32 id; + s32 value; + s32 default_value; +}; + +#define SR130PC20_INIT_CONTROL(ctrl_id, default_val) \ + { \ + .id = ctrl_id, \ + .value = default_val, \ + .default_value = default_val, \ + } + +struct sr130pc20_framesize { + s32 index; + u32 width; + u32 height; +}; + +#define FRM_RATIO(framesize) \ + (((framesize)->width) * 10 / ((framesize)->height)) + +struct sr130pc20_fps { + u32 index; + u32 fps; +}; + +struct sr130pc20_version { + u32 major; + u32 minor; +}; + +struct sr130pc20_date_info { + u32 year; + u32 month; + u32 date; +}; + +struct sr130pc20_firmware { + u32 addr; + u32 size; +}; + +struct sr130pc20_jpeg_param { + u32 enable; + u32 quality; + u32 main_size; /* Main JPEG file size */ + u32 thumb_size; /* Thumbnail file size */ + u32 main_offset; + u32 thumb_offset; + /* u32 postview_offset; */ +}; + +struct sr130pc20_position { + s32 x; + s32 y; +}; + +struct sr130pc20_rect { + s32 x; + s32 y; + u32 width; + u32 height; +}; + +struct gps_info_common { + u32 direction; + u32 dgree; + u32 minute; + u32 second; +}; + +struct sr130pc20_gps_info { + u8 gps_buf[8]; + u8 altitude_buf[4]; + s32 gps_timeStamp; +}; + +struct sr130pc20_preview { + const struct sr130pc20_framesize *frmsize; + u32 update_frmsize:1; + u32 fast_ae:1; +}; + +struct sr130pc20_capture { + const struct sr130pc20_framesize *frmsize; + u32 pre_req; /* for fast capture */ + u32 ae_manual_mode:1; + u32 lowlux_night:1; + u32 ready:1; /* for fast capture */ +}; + +/* Focus struct */ +struct sr130pc20_focus { + enum v4l2_focusmode mode; + enum af_result_status status; + + u32 pos_x; + u32 pos_y; + + u32 start:1; /* enum v4l2_auto_focus*/ + u32 touch:1; + u32 lock:1; /* set if single AF is done */ +}; + +/* struct for sensor specific data */ +struct sr130pc20_ae_gain_offset { + u32 ae_auto; + u32 ae_now; + u32 ersc_auto; + u32 ersc_now; + + u32 ae_ofsetval; + u32 ae_maxdiff; +}; + +/* Flash struct */ +struct sr130pc20_flash { + struct sr130pc20_ae_gain_offset ae_offset; + enum v4l2_flash_mode mode; + enum preflash_status preflash; + u32 awb_delay; + u32 ae_scl; /* for back-up */ + u32 on:1; /* flash on/off */ + u32 ignore_flash:1; + u32 ae_flash_lock:1; +}; + +/* Exposure struct */ +struct sr130pc20_exposure { + s32 val; /* exposure value */ + u32 ae_lock:1; +}; + +/* White Balance struct */ +struct sr130pc20_whitebalance { + enum v4l2_wb_mode mode; /* wb mode */ + u32 awb_lock:1; +}; + +struct sr130pc20_exif { + u16 exp_time_den; + u16 iso; + u16 flash; + + /*int bv;*/ /* brightness */ + /*int ebv;*/ /* exposure bias */ +}; + +/* EXIF - flash filed */ +#define EXIF_FLASH_FIRED (0x01) +#define EXIF_FLASH_MODE_FIRING (0x01 << 3) +#define EXIF_FLASH_MODE_SUPPRESSION (0x02 << 3) +#define EXIF_FLASH_MODE_AUTO (0x03 << 3) + +struct sr130pc20_stream_time { + struct timeval curr_time; + struct timeval before_time; +}; + +#define GET_ELAPSED_TIME(cur, before) \ + (((cur).tv_sec - (before).tv_sec) * USEC_PER_SEC \ + + ((cur).tv_usec - (before).tv_usec)) + +typedef u16 sr130pc20_regset_t; + +typedef struct isx012_regset { + u16 subaddr; + u32 value; + u32 len; +} isx012_regset_t; + +#ifdef CONFIG_LOAD_FILE +#define DEBUG_WRITE_REGS +struct regset_table { + const char *const name; +}; + +#define SR130PC20_REGSET(x, y, z) \ + [(x)] = { \ + .name = #y, \ + } + +#define SR130PC20_REGSET_TABLE(y, z) \ + { \ + .name = #y, \ + } + +#else /* !CONFIG_LOAD_FILE */ + +struct regset_table { + const sr130pc20_regset_t * const reg; + const u32 array_size; +#ifdef DEBUG_WRITE_REGS + const char * const name; +#endif + const u32 burst; /* on/off */ +}; + +#ifdef DEBUG_WRITE_REGS +#define SR130PC20_REGSET(x, y, z) \ + [(x)] = { \ + .reg = (y), \ + .array_size = ARRAY_SIZE((y)), \ + .name = #y, \ + .burst = z, \ + } +#define SR130PC20_REGSET_TABLE(y, z) \ + { \ + .reg = (y), \ + .array_size = ARRAY_SIZE((y)), \ + .name = #y, \ + .burst = z, \ + } +#else /* !DEBUG_WRITE_REGS */ +#define SR130PC20_REGSET(x, y, z) \ + [(x)] = { \ + .reg = (y), \ + .array_size = ARRAY_SIZE((y)), \ + .burst = z, \ + } +#define SR130PC20_REGSET_TABLE(y, z) \ + { \ + .reg = (y), \ + .array_size = ARRAY_SIZE((y)), \ + .burst = z, \ + } +#endif /* DEBUG_WRITE_REGS */ + +#endif /* CONFIG_LOAD_FILE */ + +#define EV_MIN_VLAUE EV_MINUS_4 +#define GET_EV_INDEX(EV) ((EV) - (EV_MIN_VLAUE)) + +struct sr130pc20_regs { + struct regset_table ev[GET_EV_INDEX(EV_MAX_V4L2)]; + struct regset_table metering[METERING_MAX]; + struct regset_table iso[ISO_MAX]; + struct regset_table effect[IMAGE_EFFECT_MAX]; + struct regset_table white_balance[WHITE_BALANCE_MAX]; + struct regset_table preview_size[PREVIEW_SZ_MAX]; + struct regset_table capture_size[CAPTURE_SZ_MAX]; + struct regset_table scene_mode[SCENE_MODE_MAX]; + struct regset_table fps[I_FPS_MAX]; + /* camera mode */ + struct regset_table preview_mode; + struct regset_table capture_mode; + struct regset_table capture_mode_night; + struct regset_table stream_stop; + struct regset_table init_reg; + struct regset_table VT_init_reg; + struct regset_table SS_init_reg; +}; + +struct sr130pc20_state { + struct sr130pc20_platform_data *pdata; + struct v4l2_subdev sd; + struct v4l2_pix_format req_fmt; + struct sr130pc20_preview preview; + struct sr130pc20_capture capture; + struct sr130pc20_focus focus; + struct sr130pc20_flash flash; + struct sr130pc20_exposure exposure; + struct sr130pc20_whitebalance wb; + struct sr130pc20_exif exif; +#if !defined(CONFIG_CAM_YUV_CAPTURE) + struct sr130pc20_jpeg_param jpeg; +#endif + struct sr130pc20_stream_time stream_time; + const struct sr130pc20_regs *regs; + struct mutex ctrl_lock; + struct mutex af_lock; + struct workqueue_struct *workqueue; + struct work_struct af_work; + struct work_struct af_win_work; +#ifdef CONFIG_DEBUG_NO_FRAME + struct work_struct frame_work; +#endif + enum runmode runmode; + enum v4l2_sensor_mode sensor_mode; + enum v4l2_pix_format_mode format_mode; + enum v4l2_scene_mode scene_mode; + enum v4l2_iso_mode iso; + + s32 vt_mode; + s32 req_fps; + s32 fps; + s32 freq; /* MCLK in Hz */ + u32 one_frame_delay_ms; + u32 light_level; /* light level */ + u32 lux_level_flash; + u32 shutter_level_flash; + u8 *dbg_level; +#ifdef CONFIG_DEBUG_NO_FRAME + bool frame_check; +#endif + u32 recording:1; + u32 hd_videomode:1; + u32 need_wait_streamoff:1; + u32 initialized:1; +}; + +static inline struct sr130pc20_state *to_state(struct v4l2_subdev *sd) +{ + return container_of(sd, struct sr130pc20_state, sd); +} + +static inline int sr130pc20_restore_sensor_flash(struct v4l2_subdev *sd); +static int sr130pc20_set_capture(struct v4l2_subdev *sd); +static int sr130pc20_prepare_fast_capture(struct v4l2_subdev *sd); +static int sr130pc20_control_stream(struct v4l2_subdev *sd, u32 cmd); + +extern struct class *camera_class; +extern int sr130pc20_create_file(struct class *cls); + +#if !defined(CONFIG_CAM_YUV_CAPTURE) +/* JPEG MEMORY SIZE */ +#define SENSOR_JPEG_OUTPUT_MAXSIZE 0x29999A /*2726298bytes, 2.6M */ +#define EXTRA_MEMSIZE (0 * SZ_1K) +#define SENSOR_JPEG_SNAPSHOT_MEMSIZE \ + (((SENSOR_JPEG_OUTPUT_MAXSIZE + EXTRA_MEMSIZE + SZ_16K-1) / SZ_16K) * SZ_16K) +#endif + +/*********** Sensor specific ************/ +#define DELAY_SEQ 0xFF +#define SR130PC20_CHIP_ID 0xC1 + +#define SR130PC20_INTSRC_VINT (0x01 << 5) + +#define POLL_TIME_MS 10 +#define CAPTURE_POLL_TIME_MS 1000 + +/* maximum time for one frame in norma light */ +#define ONE_FRAME_DELAY_MS_NORMAL 66 +/* maximum time for one frame in low light: minimum 10fps. */ +#define ONE_FRAME_DELAY_MS_LOW 100 +/* maximum time for one frame in night mode: 6fps */ +#define ONE_FRAME_DELAY_MS_NIGHTMODE 166 + +/* level at or below which we need to enable flash when in auto mode */ +#define LUX_LEVEL_MAX 0x00 /* the brightest */ +#define LUX_LEVEL_LOW 0x3D /* low light */ +#define LUX_LEVEL_FLASH_ON 0x2B + +/* Count for loop */ +#define SR130PC20_CNT_CAPTURE_FRM 330 +#define SR130PC20_CNT_CLEAR_VINT 20 +#define SR130PC20_CNT_AE_STABLE 100 /* for checking MODESEL_FIX */ +#define SR130PC20_CNT_CAPTURE_AWB 3 /* 8 -> 3 */ +#define SR130PC20_CNT_OM_CHECK 30 +#define SR130PC20_CNT_CM_CHECK 280 /* 160 -> 180 */ +#define SR130PC20_CNT_STREAMOFF 300 + +#define AF_SEARCH_COUNT 550 /* about 6s */ +#define AE_STABLE_SEARCH_COUNT 7 + +/* Sensor AF first,second window size. + * we use constant values intead of reading sensor register */ +#define DEFAULT_WINDOW_WIDTH 80 +#define DEFAULT_WINDOW_HEIGHT 80 +#define AF_PRECISION 100 + +/* diff value fior fast AE in preview */ +#define AESCL_DIFF_FASTAE 1000 + + +/* + * Register Address Definition + */ + +/* The Path of Setfile */ +#ifdef CONFIG_LOAD_FILE +#include +#include +#include +#include +#include + +#define TUNING_FILE_PATH "/mnt/sdcard/sr130pc20_regs.h" +#endif /* CONFIG_LOAD_FILE*/ + +#include "sr130pc20_regs.h" + +#endif /* __SR130PC20_H__ */ diff --git a/drivers/media/video/sr130pc20_regs.h b/drivers/media/video/sr130pc20_regs.h new file mode 100644 index 0000000..ebc578b --- /dev/null +++ b/drivers/media/video/sr130pc20_regs.h @@ -0,0 +1,4229 @@ +/* sr130pc20_regs.h + * + * Driver for s5k5ccgx (5MP Camera) from siliconfile + * + * Copyright (C) 2010, SAMSUNG ELECTRONICS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Change Date: 2012.06.28 + */ + +#ifndef __SR130PC20_REGS_H__ +#define __SR130PC20_REGS_H__ + +/* PV 1st */ + +static const sr130pc20_regset_t SR130PC20_Init_Reg[] = { + +/*0 Page*/ +0x0300, +0x0101, /*sleep*/ +0x0103, /*s/w reset*/ +0x0101, /*sleep*/ + +0x0800,/*Don't touch*/ +0x0937,/*Don't touch*/ +0x0a33,/*Don't touch*/ + +/*PLL Setting*/ +0xd005, +0xd130, +0xd201, +0xd320, +0xd085, +0xd085, +0xd085, +0xd095, + +0x1011, +0x1190, /*xy flip*/ +0x1200, +0x1488, + +0x0300, +0x2000, +0x2104, +0x2200, +0x2304, +0x2403, +0x25C0, +0x2605, +0x2700, + +0x4001, /*Hblank_280*/ +0x4118, +0x4200, /*Vblank 100*/ +0x4364, + +/*--------------- BLC*/ +0x8008, /*Don't touch */ +0x8197, /*Don't touch */ +0x8290, /*Don't touch */ +0x8330, /*Don't touch */ +0x84cc, /*Don't touch*/ +0x8500, /*Don't touch*/ +0x86d4, /*Don' t touch*/ +0x870f, /*Don't touch*/ +0x8834, /*Don't touch*/ + +0x900c, /*BLC_TIME_TH_ON*/ +0x910c, /*BLC_TIME_TH_OFF */ +0x92f0, /*BLC_AG_TH_ON*/ +0x93e8, /*BLC_AG_TH_OFF*/ + +0x9495, /*091202*/ +0x9590, /*091202 */ +0x9838, /*Don't touch*/ + +/*Dark BLC*/ +0xa001, /* 20100309*/ +0xa201, /* 20100309*/ +0xa401, /* 20100309*/ +0xa601, /* 20100309*/ + +/*Normal BLC*/ +0xa800, +0xaa00, +0xac00, +0xae00, + +/*Out BLC*/ +0x9900, +0x9a00, +0x9b00, +0x9c00, + +/*2 Page*/ +0x0302, +0x1200, /*Don't touch*/ +0x1400, /*Don't touch*/ +0x1500, /*Don't touch*/ +0x184C, /*Don't touch*/ +0x1900, /*Don't touch*/ +0x1A39, /*Don't touch*/ +0x1B00,/*Don't touch*/ +0x1C1a, /*Don't touch*/ +0x1D14, /*Don't touch*/ +0x1E30,/*Don't touch*/ +0x1F10,/*Don't touch*/ + +0x2077, +0x21de, +0x22a7, +0x2330, +0x2477, +0x2510, +0x2610, +0x273c, +0x2b80, +0x2c02, +0x2da0, +0x2e00, +0x2fa7, + +0x3000, +0x3199, +0x3200, +0x3300, +0x3422, +0x3601, +0x3701, +0x3888, +0x3988, +0x3d03, +0x3e0d, +0x3f02, + +0x49d1, +0x4a14, + +0x5021, +0x5201, +0x5381, +0x5410, +0x551c, +0x5611, +0x5818, +0x5916, +0x5da2, +0x5e5a, + +0x6093, /* 20120517 modify*/ +0x61a4, /* 20120517 modify*/ +0x6294, /* 20120517 modify*/ +0x63a3, /* 20120517 modify*/ +0x6494, /* 20120517 modify*/ +0x65a3, /* 20120517 modify*/ +0x670c, +0x680c, +0x690c, +0x6ab4, +0x6bc4, +0x6cb5, +0x6dc2, +0x6eb5, +0x6fc0, + +0x70b6, +0x71b8, +0x7295, /* 20120517 modify*/ +0x73a2, /* 20120517 modify*/ +0x7495, /* 20120517 modify*/ +0x75a2, /* 20120517 modify*/ +0x7695, /* 20120517 modify*/ +0x77a2, /* 20120517 modify*/ +0x7C92, /* 20120517 modify*/ +0x7Dff, /* 20120517 modify*/ + +0x8001, /* 20120517 modify*/ +0x818a, /* 20120517 modify*/ +0x821e, /* 20120517 modify*/ +0x8336, /* 20120517 modify*/ +0x8489, /* 20120517 modify*/ +0x858b, /* 20120517 modify*/ +0x8689, /* 20120517 modify*/ +0x878b, /* 20120517 modify*/ +0x88ab, +0x89bc, +0x8aac, +0x8bba, +0x8cad, +0x8db8, +0x8eae, +0x8fb2, + +0x90b3, +0x91b7, +0x9252, /* 20120517 modify*/ +0x936a, /* 20120517 modify*/ +0x9489, /* 20120517 modify*/ +0x958b, /* 20120517 modify*/ +0x9689, /* 20120517 modify*/ +0x978b, /* 20120517 modify*/ + +0xA002, +0xA186, /* 20120517 modify*/ +0xA202, +0xA386, /* 20120517 modify*/ +0xA486, /* 20120517 modify*/ +0xA502, +0xA686, /* 20120517 modify*/ +0xA702, +0xA892, /* 20120517 modify*/ +0xA994, /* 20120517 modify*/ +0xAA92, /* 20120517 modify*/ +0xAB94, /* 20120517 modify*/ +0xAC1c, +0xAD22, +0xAE1c, +0xAF22, + +0xB0a4, /* 20120517 modify*/ +0xB1ae, /* 20120517 modify*/ +0xB2a4, /* 20120517 modify*/ +0xB3ae, /* 20120517 modify*/ +0xB4a6, /* 20120517 modify*/ +0xB5ac, /* 20120517 modify*/ +0xB6a6, /* 20120517 modify*/ +0xB7ac, /* 20120517 modify*/ +0xB8a6, /* 20120517 modify*/ +0xB9ab, /* 20120517 modify*/ +0xBAa6, /* 20120517 modify*/ +0xBBab, /* 20120517 modify*/ +0xBCa6, /* 20120517 modify*/ +0xBDab, /* 20120517 modify*/ +0xBEa6, /* 20120517 modify*/ +0xBFab, /* 20120517 modify*/ + +0xc437, +0xc552, +0xc66b, +0xc786, +0xc838, /* 20120517 modify*/ +0xc950, /* 20120517 modify*/ +0xca38, /* 20120517 modify*/ +0xcb50, /* 20120517 modify*/ +0xcc6c, /* 20120517 modify*/ +0xcd84, /* 20120517 modify*/ +0xce6c, /* 20120517 modify*/ +0xcf84, /* 20120517 modify*/ + +/*0xd4a6,*/ +/*0xd5ac,*/ +/*0xd6a6,*/ +/*0xd7ac,*/ +/*add 20120517*/ +0xdc00, /* Added*/ +0xddaf, /* Added*/ +0xde00, /* Added*/ +0xdf90, /* Added*/ + +0xd010, +0xd114, +0xd220, +0xd300, +/*DCDC */ +0xd40c, /*DCDC_TIME_TH_ON*/ +0xd50c, /*DCDC_TIME_TH_OFF */ +0xd6f0, /*DCDC_AG_TH_ON*/ +0xd7e8, /*DCDC_AG_TH_OFF*/ + +0xea8a, + +0xF001, /* clock inversion*/ +0xF101, +0xF201, +0xF301, +0xF401, +0xF500, + +/*----------------------------------------------*/ +0x0310, /*page 10*/ +0x1001, /*Ycbcr422_bit Order: YUYV*/ +0x1103, +0x1230, /*y offset[4], dif_offset[5]*/ +0x1302, /*contrast effet enable : 0x02*/ +0x3400, /*hidden 10->00 100209*/ +0x3701, /*yc2d power save */ +0x3f04, /*100825*/ +0x4080, /*Y offset */ +0x4880, +0x5300, /*dif_offset option */ +0x5530, /*dif_offset option diff_offset max */ + +0x604f, /*out color sat en[7] | auto color decrement en[1] / + | manual color sat en[0]*/ + +0x6183, /*blue saturation_C0*/ +0x6280, /*red saturation_B0*/ + +0x63ff, /*auto decresment on AG th*/ +0x64c0, /*auto decresment on DG th*/ +0x66e4, /*Outdoor saturation step 137fps apply out th */ +0x6703, /*Outdoor saturation B/R*/ +0x7601, /* ADD 20121031 */ +0x7904, /* ADD 20121031 */ + +/* Hi 163 */ +/* PAGE 10 START*/ +0x0310, +0x8000, /* dsshin --> color enhance*/ +0xf500, /* dsshin --> h blank option*/ + +0x0311, /*page 11 D_LPF */ +0x103f, /*B[6]:Blue En Dlpf on[4:0] Sky over off : 0x7f->3f*/ +0x1120, /* Uniform Full GbGr/OV-Nr*/ + +0x1280, /*Blue MaxOpt blue sky max filter optoin rate : 0 0xc0->80*/ +0x13b8, /*dark2[7] | ratio[6:4] | dark3[3] | dark3 maxfilter ratio[2:0] */ + +0x30ba, /*Outdoor2 H th*/ +0x3110, /*Outdoor2 L th*/ +0x3250, /*Outdoor2 gain ratio*/ +0x331d, /*Outdoor2 H lum*/ +0x3420, /*Outdoor2 M lum*/ +0x351f, /*Outdoor2 L lum*/ + +0x36b0, /*Outdoor1 H th*/ +0x3718, /*Outdoor1 L th*/ +0x3850, /*Outdoor1 gain ratio 0x80->40*/ +0x391d, /*Outdoor1 H lum 0x28->1e*/ +0x3a20, /*Outdoor1 M lum 0x10->15*/ +0x3b1f, /*Outdoor1 L lum 0x08->20*/ + +0x3c3f, /*indoor H th*/ +0x3d16, /*indoor L th*/ +0x3e30, /*indoor gain ratio 0x44 6a */ +0x3f1a, /*indoor H lum 0x12 18 */ +0x4060, /*indoor M lum 0x18 1c*/ +0x411a, /*indoor L lum 0x18 3e*/ + +0x4298, /*dark1 H th*/ +0x4328, /*dark1 L th*/ +0x4465, /*dark1 gain ratio*/ +0x4516, /*dark1 H lum 0x38->0x28 */ +0x4630, /*dark1 M lum 0x27->0x17*/ +0x4734, /*dark1 L lum 0x20->0x1a */ + +0x4890, /*dark2 H th*/ +0x492a, /*dark2 L th*/ +0x4a65, /*dark2 gain ratio*/ +0x4b18, /*dark2 H lum */ +0x4c31, /*dark2 M lum*/ +0x4d36, /*dark2 L lum */ + +0x4e80, /*dark3 H th*/ +0x4f30, /*dark3 L th*/ +0x5065, /*dark3 gain ratio*/ +0x5119, /*dark3 H lum */ +0x5231, /*dark3 M lum */ +0x5336, /*dark3 L lum */ + +0x5a3f, /*blue sky mode out1/2 enable 0x27->3f */ +0x5b00, /*Impulse pixel enable dark123,in,out123 :: must be 0x07*/ +0x5c9f, /*Indoor maxfilter rate[7:5] | Uncertain onoff[4:0] 0x1f ->0x9f*/ + +0x603f, /*GbGr all enable*/ +0x620f, /*GbGr offset*/ + +0x650c, /*Outdoor GbGr rate H 100% M 25% L 100%*/ +0x660c, /*Indoor GbGr rate H 100% M 25% L 100%*/ +0x6700, /*dark GbGr rate H/M/L 100%*/ + +0x700c, /* Abberation On/Off B[1]: Outdoor B[0]: Indoor 07>>c*/ +0x75a0, /* Outdoor2 Abberation Luminance lvl */ +0x7db4, /* Indoor Abberation Luminance lvl*/ + +0x9608, /*indoor/Dark1 edgeoffset1*/ +0x9714, /*indoor/Dark1 center G value*/ +0x98f5, /*slope indoor :: left/right graph polarity, slope*/ +0x992a, /*indoor uncertain ratio control*/ +0x9a20, /*Edgeoffset_dark*/ + +/*DPC_CTRL*/ +0x0312, /*Preview DPC off[0x5c] on[0x5d]*/ +0x200f, +0x210f, + +0x2500, /* 0x30*/ + +0x2a01, +0x2e00, /*2010.8.25*/ + +0x3035, /*Texture region(most detail)*/ +0x31a0, /*STD uniform1 most blur region*/ +0x32b0, /*STD uniform2 2nd blur*/ +0x33c0, /*STD uniform3 3rd blur*/ +0x34d0, /*STD normal noise1 4th blur */ +0x35e0, /*STD normal noise2 5th blur*/ +0x36ff, /*STD normal noise3 6th blur*/ + +0x4083, /*Outdoor2 H th*/ +0x4120, /*Outdoor2 L th */ +0x4208, /*Outdoor2 H luminance */ +0x4310, /*Outdoor2 M luminance */ +0x4410, /*Outdoor2 l luminance */ +0x4550, /*Outdoor2 ratio*/ + +0x4683, /*Outdoor1 H th*/ +0x4720, /*Outdoor1 L th */ +0x4808, /*Outdoor1 H luminance*/ +0x4910, /*Outdoor1 M luminance*/ +0x4a10, /*Outdoor1 L luminance*/ +0x4b50, /*Outdoor1 ratio*/ + +0x4c80, /*Indoor H th*/ +0x4d48, /*Indoor L th*/ +0x4e30, /*indoor H lum*/ +0x4f30, /*indoor M lum*/ +0x5012, /*indoor L lum */ +0x5170, /*indoor ratio 0x10 -> 0x45*/ + +0x52a8, /*dark1 H th*/ +0x5330, /*dark1 L th */ +0x5428, /*dark1 H lum */ +0x553e, /*dark1 M lum*/ +0x5667, /*dark1 L lum*/ +0x576a, /*dark1 ratio*/ + +0x58a0, /*dark2 H th*/ +0x5940, /*dark2 L th*/ +0x5a28, /*dark2 H lum*/ +0x5b3f, /*dark2 M lum*/ +0x5c68, /*dark2 L lum*/ +0x5d70, /*dark2 ratio*/ + +0x5ea0, /*dark3 H th*/ +0x5f40, /*dark3 L th*/ +0x6029, /*dark3 H lum*/ +0x613f, /*dark3 M lum*/ +0x6269, /*dark3 L lum*/ +0x636a, /*dark3 ratio*/ + +/*C-filter(Out2&Out1)*/ +0x7010, +0x710a, + +/*C-filter(Indoor&Dark3)*/ +0x7210, +0x730a, + +/*C-filter(Dark2&Dark1)*/ +0x7418, +0x7512, + +0x8020, +0x8140, +0x8265, +0x851a, +0x8800, +0x8900, +0x905d, /*Preview DPC off[0x5c] on[0x5d]*/ + +/*DPC-Dark1,2,3*/ +0xad07, /*10825*/ +0xae07, /*10825*/ +0xaf07, /*10825*/ + +/*Blue Det..*/ +0xc558, /*BlueRange 2010.8.25 0x40->23 */ +0xc620, /*GreenRange 2010.8.25 0x3b->20 */ + +0xd088, /*2010.8.25*/ +0xd180, +0xd217,/*preview 17, full 67*/ +0xd300, +0xd400, +0xd50f,/*preview 0f, full 02*/ +0xd6ff, +0xd7ff,/*preview ff, full 18*/ +0xd800, +0xd904, + +/*interpolated with average*/ +0xdb38, /*resolution issue 0x00->0x18->0x38 */ +0xd904, /*strong_edge detect ratio*/ +0xe001, /*strong_edge detect ratio*/ + +0x0313, /*page 13 sharpness 1D*/ +0x10c5, +0x117b, +0x120e, +0x1400, + +0x1511, /*added option 1.3M*/ +0x1830, /*added option 1.3M*/ + +0x2015, +0x2113, +0x2233, +0x2308, /*hi_clip th1*/ +0x241a, /*hi_clip th2*/ +0x2506, /*low clip th*/ + +0x2618, +0x2730, +0x2910, /*time th*/ +0x2a30, /*pga th*/ + +0x2b03, /*lpf out2*/ +0x2c03, /*lpf out1*/ +0x2d0c, +0x2e12, +0x2f12, + +/*1D Edge*/ +0x500a, /*out2 hi nega*/ +0x5307, /* hi pos*/ +0x510c, /* mi nega*/ +0x5407, /* mi pos*/ +0x520b, /* lo nega*/ +0x5508, /* lo pos*/ + +0x560a, /*out1 hi nega*/ +0x5907, /* hi pos */ +0x570c, /* mi nega*/ +0x5a07, /* mi pos */ +0x580b, /* lo nega*/ +0x5b08, /* lo pos */ + +/*Indoor Edge*/ +0x5c08, /*indoor hi nega*/ +0x5f07, /* hi pos*/ +0x5d14, +0x6012, +0x5e0a, +0x6108, /* low pos*/ + +0x6208, /*dark1 hi nega*/ +0x6506, /* hi pos */ +0x6308, /* mid nega */ +0x6606, /* mid pos */ +0x6408, /* low nega */ +0x6706, /* low pos */ + +0x6807, /*dark2 hi nega*/ +0x6b05, /* hi pos */ +0x6907, /* mid nega */ +0x6c05, /* mid pos */ +0x6a07, /* low nega */ +0x6d05, /* low pos */ + +0x6e0a, /*dark3 hi nega*/ +0x7109, /* hi pos */ +0x6f0a, /* mid nega */ +0x7209, /* mid pos */ +0x700a, /* low nega */ +0x7309, /* low pos */ + + /* 2DY*/ +0x80c1, +0x811f, +0x82e1, +0x8333, + +0x9005, +0x9105, +0x9233, +0x9330, +0x9403, +0x9514, +0x9730, +0x9930, + +0xa002, /*2d lclp out2 nega*/ +0xa103, /*2d lclp out2 pos*/ +0xa202, /*2d lclp out1 nega*/ +0xa303, /*2d lclp out1 pos*/ +0xa403, /*2d lclp in nega*/ +0xa504, /*2d lclp in pos*/ +0xa607, /*2d lclp dark1 nega*/ +0xa708, /*2d lclp dark1 pos*/ +0xa807, /*2d lclp dark2 nega*/ +0xa908, /*2d lclp dark2 pos*/ +0xaa07, /*2d lclp dark3 nega*/ +0xab08, /*2d lclp dark3 pos*/ + +0xb010, /*out2 H Ne*/ +0xb310, /* H Po*/ +0xb11e, /* M Ne*/ +0xb41e, /* M Po*/ +0xb21f, /* L Ne*/ +0xb51e, /* L Po*/ + +0xb610, /*out1 H Ne */ +0xb910, /* H Po */ +0xb71e, /* M Ne */ +0xba1e, /* M Po */ +0xb81f, /* L Ne */ +0xbb1e, /* L Po */ + +0xbc20, /*indoor H Ne*/ +0xbf1e, /* H Po*/ +0xbd25, /* M Ne*/ +0xc023, /* M Po*/ +0xbe24, /* L Ne*/ +0xc122, /* L Po*/ + +0xc223, /*dark1 H Ne*/ +0xc523, /* H Po*/ +0xc329, /* M Ne*/ +0xc629, /* M Po*/ +0xc425, /* L Ne*/ +0xc725, /* L Po*/ + +0xc81c, /*dark2 H Ne*/ +0xcb1c, /* H Po*/ +0xc925, /* M Ne*/ +0xcc25, /* M Po*/ +0xca23, /* L Ne*/ +0xcd23, /* L Po*/ + +0xce1c, /*dark3 H Ne*/ +0xd11c, /* H Po*/ +0xcf25, /* M Ne*/ +0xd225, /* M Po*/ +0xd023, /* L Ne*/ +0xd323, /* L Po*/ + +/* PAGE 14 START*/ +0x0314, +0x1031, + +0x1480, /* GX*/ +0x1580, /* GY*/ +0x1680, /* RX*/ +0x1780, /* RY*/ +0x1880, /* BX*/ +0x1980, /* BY*/ + +0x2060, /* X Center*/ +0x2180, /* Y Center*/ + +0x2280, +0x2380, +0x2480, + +0x30c8, +0x312b, +0x3200, +0x3300, +0x3490, + +0x4056, /*R min's set 4e*/ +0x413a, /*Gr*/ +0x4237, /*B*/ +0x433a, /*Gb*/ + +0x0315, +0x1021, +0x1444, /*49*/ +0x1534, /*38*/ +0x1626, /*2b*/ +0x172f, + +0x30dd, +0x3162, +0x3205, +0x3326, +0x34bd, +0x3517, +0x3618, +0x3738, +0x38d0, + +0x40b0, +0x4130, +0x4200, +0x4300, +0x4400, +0x4500, +0x4699, +0x4719, +0x4800, + +0x5016, +0x51b2, +0x521c, +0x5306, +0x5420, +0x55a6, +0x560e, +0x57b2, +0x5824, + +0x0316, +0x1031, /*GMA_CTL*/ +0x187e, /*AG_ON*/ +0x197d, /*AG_OFF*/ +0x1a0e, /*TIME_ON*/ +0x1b01, /*TIME_OFF*/ +0x1Cdc, /*OUT_ON*/ +0x1Dfe, /*OUT_OFF*/ + +/*GMA Indoor*/ +0x3000, +0x3107, +0x321a, +0x3335, +0x345a, +0x357c, +0x3696, +0x37a9, +0x38b7, +0x39c6, +0x3ad2, +0x3bdc, +0x3ce4, +0x3deb, +0x3ef1, +0x3ff5, +0x40f9, +0x41fd, +0x42ff, + +/*RGMA Outdoor*/ +0x5000, +0x5103, +0x5213, +0x532e, +0x5459, +0x5579, +0x5690, +0x57a3, +0x58b4, +0x59c2, +0x5acd, +0x5bd7, +0x5ce0, +0x5de5, +0x5ee9, +0x5fee, +0x60f1, +0x61f3, +0x62f6, + +/*BGMA Dark*/ +0x7003, +0x7111, +0x721f, +0x7337, +0x7452, +0x756c, +0x7685, +0x779a, +0x78ad, +0x79bd, +0x7acb, +0x7bd6, +0x7ce0, +0x7de8, +0x7eef, +0x7ff4, +0x80f8, +0x81fb, +0x82fe, + +0x0324, /*Resol control */ +0x60c5, /*edge even frame | 16bit resol | white edge cnt | scene resol enable*/ +0x6104, /*even frame update */ +0x6408, +0x6500, +0x6626, /*edge th2 H */ +0x6700, /*edge th2 L */ + +0x0313, +0x1831, /*flat center Gb/Gr*/ +0x7402, /*det slope en | gausian filter*/ +0x750d, /*1D negative gain det 09 */ +0x760d, /*1D postive gain det 08*/ +0x7710, /*1D hclp2 det*/ +0x7808, /*outdoor flat threshold*/ +0x7910, /*indoor flat threshold*/ + +0x81df, /*det gain controler*/ +0x8690, /*2D negative gain det */ +0x8790, /*2D postive gain det */ +0x962a, /*2D hclp2 det*/ + +0x0312, /*0x12 page*/ +0xd088, +0xd9e4, + +/* PAGE 18 START*/ +0x0318, +0x1400, + +/* PAGE 20 START*/ +0x0320, +0x111c, +0x1830, +0x1a08, +0x2045,/*weight*/ +0x2130, +0x2210, +0x2300, +0x2400, + +0x28e7, /* add 20120223*/ +0x290d, /* 20100305 ad -> 0d*/ +0x2afd, +0x2bf8, + +0x2cc3, +0x2d5f, /* add 20120223*/ +0x2e33, +0x30f8, +0x3203, +0x332e, +0x3430, +0x35d4, +0x36ff, /*fe*/ +0x3732, +0x3804, +0x3922, +0x3ade, +0x3b22, +0x3cde, +0x3de1, + +0x5045, +0x5188, + +0x561a, +0x5780, +0x580e, +0x596a, +0x5a04, + +0x5e9d, /*AE_AWB_start*/ +0x5f76, /*AE_AWB_start*/ + +0x7033, /* 6c*/ +0x7182, /* 82(+8)*/ + +0x7621, +0x7771, +0x7822, /* 24*/ +0x7923, /* Y Target 70 => 25, 72 => 26*/ +0x7a23, /* 23*/ +0x7b22, /* 22*/ +0x7d23, + +0x8301, /*EXP Normal 33.33 fps */ +0x845f, +0x8590, +0x8601, /*EXPMin 7500.00 fps*/ +0x8790, +0x8805, /*EXP Max(120Hz) 8.00 fps */ +0x89b8, +0x8ad8, +0xa505, /*EXP Max(100Hz) 8.33 fps */ +0xa67e, +0xa740, +0x8B75, /*EXP100 */ +0x8C30, +0x8D61, /*EXP120 */ +0x8Ea8, +0x9c09, /*EXP Limit 1250.00 fps */ +0x9d60, +0x9e01, /*EXP Unit */ +0x9f90, +0x989d, + +0xb016, +0xb114, +0xb2f8, +0xb314, +0xb41b, +0xb546, +0xb631, +0xb729, +0xb826, +0xb924, +0xba22, +0xbb42, +0xbc41, +0xbd40, + +0xc010, +0xc138, +0xc238, +0xc338, +0xc407, + +0xc880, +0xc980, +0x109c, /* ae enable*/ +/* PAGE 20 END*/ + +/*AE_Weight*/ +0x0321, +0x2011, +0x2111, +0x2211, +0x2311, +0x2412, +0x2522, +0x2622, +0x2721, +0x2812, +0x2922, +0x2a22, +0x2b21, +0x2c12, +0x2d23, +0x2e32, +0x2f21, +0x3012, +0x3123, +0x3232, +0x3321, +0x3412, +0x3522, +0x3622, +0x3721, +0x3812, +0x3922, +0x3a22, +0x3b21, +0x3c11, +0x3d11, +0x3e11, +0x3f11, + +/* PAGE 22 START*/ +0x0322, +0x10fd, +0x112e, +0x1901, /* Low On*/ +0x2030, /* for wb speed*/ +0x2140, +0x2401, +0x257e, /* for tracking 20120314 */ + +0x3080, /* 20120224 test*/ +0x3180, +0x3811, +0x3934, + +0x40e8, +0x4143, /* 33*/ +0x4222, /* 22*/ + +0x43f3, /* f6*/ +0x4454, /* 44*/ +0x4522, /* 33*/ + +0x4600, +0x480a, +0x50b2, +0x5181, +0x5298, + +0x8038, +0x8120, +0x8238, /* 3a*/ + +0x8356, /* R Max*/ +0x8420, /* R Min*/ +0x8552, /* B Max*/ +0x8620, /* B Min*/ + +0x8745, +0x883a, +0x8933, +0x8a2c, + +0x8b42, +0x8c3d, +0x8d30, +0x8e2c, + +0x8f5a, +0x9059, +0x9155, +0x924e, +0x9344, +0x943a, +0x9534, +0x962c, +0x9723, +0x9820, +0x991f, +0x9a1f, + +0x9b77, +0x9c77, +0x9d48, +0x9e38, +0x9f30, + +0xa040, +0xa121, +0xa26f, +0xa3ff, + +0xa414, /* 1500fps*/ +0xa544, /* 700fps*/ +0xa6cf, + +0xad40, +0xae4a, + +0xaf2a, /* low temp Rgain*/ +0xb028, /* low temp Rgain*/ + +0xb100, /* 0x20 -> 0x00 0405 modify*/ +0xb4bf, /* for tracking 20120314*/ +0xb8a1, /* a2: b-2, R+2 b4 B-3, R+4 lowtemp b0 a1 Spec AWB A modify*/ +0xb900, +/* PAGE 22 END*/ + +/* PAGE 48 (MiPi 1600x1200)*/ +0x0300, + +/* PLL Setting */ +0xd005, +0xd130, +0xd205, +0xd320, +0xd085, +0xd085, +0xd085, +0xd095, + +0x0348, +/* MIPI TX Setting */ +0x101c, +0x1100, +0x1200, +0x1400, +0x1604, +0x1700, +0x1880, +0x1900, +0x1aa0, +/*0x1b0d,*/ +0x1c02, +0x1d0e, +0x1e07, +0x1f08, + +0x2200, +0x2301, +0x241e, +0x2500, +0x2600, +0x2708, +0x2800, +/*0x2b40,*/ + +0x3005, +0x3100, + +0x3207, +0x3309, +0x3401, +0x3501, + +0x0300, +0x0101, +}; + +static const sr130pc20_regset_t sr130pc20_VT_Init_Reg[] = { +/*0 Page*/ +0x0300, +0x0101, /*sleep*/ +0x0103, /*s/w reset*/ +0x0101, /*sleep*/ + +0x0800,/*Don't touch*/ +0x0937,/*Don't touch*/ +0x0a33,/*Don't touch*/ + +/*PLL Setting*/ +0xd005, +0xd130, +0xd201, +0xd320, +0xd085, +0xd085, +0xd085, +0xd095, + +0x1011, +0x1194, /*xy flip*/ +0x1200, /*Sync type default:0x00 PCLK[2] 0 falling, 1 rising*/ +0x1488, + +/*--------------- windowing */ +0x0300, +0x2000, +0x2104, +0x2200, +0x2304, +0x2403, +0x25C0, +0x2605, +0x2700, + +0x4001, /*Hblank 280*/ +0x4118, +0x4200, /*Vblank 20*/ +0x4314, + +/*--------------- BLC*/ +0x8008, /*Don't touch */ +0x8197, /*Don't touch */ +0x8290, /*Don't touch */ +0x8330, /*Don't touch */ +0x84cc, /*Don't touch*/ +0x8500, /*Don't touch*/ +0x86d4, /*Don' t touch*/ +0x870f, /*Don't touch*/ +0x8834, /*Don't touch*/ + +0x9009, /*BLC_TIME_TH_ON*/ +0x9109, /*BLC_TIME_TH_OFF */ +0x92f0, /*BLC_AG_TH_ON*/ +0x93e8, /*BLC_AG_TH_OFF*/ + +0x9495, /*091202*/ +0x9590, /*091202 */ +0x9838, /*Don't touch*/ + +/*Dark BLC*/ +0xa001, /* 20100309*/ +0xa201, /* 20100309*/ +0xa401, /* 20100309*/ +0xa601, /* 20100309*/ + +/*Normal BLC*/ +0xa800, +0xaa00, +0xac00, +0xae00, + +/*Out BLC*/ +0x9900, +0x9a00, +0x9b00, +0x9c00, + +/*2 Page*/ +0x0302, +0x1200, /*Don't touch*/ +0x1400, /*Don't touch*/ +0x1500, /*Don't touch*/ +0x184C, /*Don't touch*/ +0x1900, /*Don't touch*/ +0x1A39, /*Don't touch*/ +0x1B00,/*Don't touch*/ +0x1C1a, /*Don't touch*/ +0x1D14, /*Don't touch*/ +0x1E30,/*Don't touch*/ +0x1F10,/*Don't touch*/ + +0x2077, +0x21de, +0x22a7, +0x2330, +0x2477, +0x2510, +0x2610, +0x273c, +0x2b80, +0x2c02, +0x2da0, +0x2e00, +0x2fa7, + +0x3000, +0x3199, +0x3200, +0x3300, +0x3422, +0x3601, +0x3701, +0x3888, +0x3988, +0x3d03, +0x3e0d, +0x3f02, + +0x49d1, +0x4a14, + +0x5021, +0x5201, +0x5381, +0x5410, +0x551c, +0x5611, +0x5818, +0x5916, +0x5da2, +0x5e5a, + +0x6093, /* 20120517 modify*/ +0x61a4, /* 20120517 modify*/ +0x6294, /* 20120517 modify*/ +0x63a3, /* 20120517 modify*/ +0x6494, /* 20120517 modify*/ +0x65a3, /* 20120517 modify*/ +0x670c, +0x680c, +0x690c, +0x6ab4, +0x6bc4, +0x6cb5, +0x6dc2, +0x6eb5, +0x6fc0, + +0x70b6, +0x71b8, +0x7295, /* 20120517 modify*/ +0x73a2, /* 20120517 modify*/ +0x7495, /* 20120517 modify*/ +0x75a2, /* 20120517 modify*/ +0x7695, /* 20120517 modify*/ +0x77a2, /* 20120517 modify*/ +0x7C92, /* 20120517 modify*/ +0x7Dff, /* 20120517 modify*/ + +0x8001, /* 20120517 modify*/ +0x818a, /* 20120517 modify*/ +0x821e, /* 20120517 modify*/ +0x8336, /* 20120517 modify*/ +0x8489, /* 20120517 modify*/ +0x858b, /* 20120517 modify*/ +0x8689, /* 20120517 modify*/ +0x878b, /* 20120517 modify*/ +0x88ab, +0x89bc, +0x8aac, +0x8bba, +0x8cad, +0x8db8, +0x8eae, +0x8fb2, + +0x90b3, +0x91b7, +0x9252, /* 20120517 modify*/ +0x936a, /* 20120517 modify*/ +0x9489, /* 20120517 modify*/ +0x958b, /* 20120517 modify*/ +0x9689, /* 20120517 modify*/ +0x978b, /* 20120517 modify*/ + +0xA002, +0xA186, /* 20120517 modify*/ +0xA202, +0xA386, /* 20120517 modify*/ +0xA486, /* 20120517 modify*/ +0xA502, +0xA686, /* 20120517 modify*/ +0xA702, +0xA892, /* 20120517 modify*/ +0xA994, /* 20120517 modify*/ +0xAA92, /* 20120517 modify*/ +0xAB94, /* 20120517 modify*/ +0xAC1c, +0xAD22, +0xAE1c, +0xAF22, + +0xB0a4, /* 20120517 modify*/ +0xB1ae, /* 20120517 modify*/ +0xB2a4, /* 20120517 modify*/ +0xB3ae, /* 20120517 modify*/ +0xB4a6, /* 20120517 modify*/ +0xB5ac, /* 20120517 modify*/ +0xB6a6, /* 20120517 modify*/ +0xB7ac, /* 20120517 modify*/ +0xB8a6, /* 20120517 modify*/ +0xB9ab, /* 20120517 modify*/ +0xBAa6, /* 20120517 modify*/ +0xBBab, /* 20120517 modify*/ +0xBCa6, /* 20120517 modify*/ +0xBDab, /* 20120517 modify*/ +0xBEa6, /* 20120517 modify*/ +0xBFab, /* 20120517 modify*/ + +0xc437, +0xc552, +0xc66b, +0xc786, +0xc838, /* 20120517 modify*/ +0xc950, /* 20120517 modify*/ +0xca38, /* 20120517 modify*/ +0xcb50, /* 20120517 modify*/ +0xcc6c, /* 20120517 modify*/ +0xcd84, /* 20120517 modify*/ +0xce6c, /* 20120517 modify*/ +0xcf84, /* 20120517 modify*/ + +/*0xd4a6,*/ +/*0xd5ac,*/ +/*0xd6a6,*/ +/*0xd7ac,*/ +/*add 20120517*/ +0xdc00, /* Added*/ +0xddaf, /* Added*/ +0xde00, /* Added*/ +0xdf90, /* Added*/ + +0xd010, +0xd114, +0xd220, +0xd300, +/*DCDC */ +0xd409, /*DCDC_TIME_TH_ON*/ +0xd509, /*DCDC_TIME_TH_OFF */ +0xd6f0, /*DCDC_AG_TH_ON*/ +0xd7e8, /*DCDC_AG_TH_OFF*/ + +0xea8a, + +0xF001, /* clock inversion*/ +0xF101, +0xF201, +0xF301, +0xF401, +0xF500, + +/*----------------------------------------------*/ +0x0310, /*page 10*/ +0x1001, /*Ycbcr422_bit Order: YUYV*/ +0x1230, /*y offset[4], dif_offset[5]*/ +0x1302, /*contrast effet enable : 0x02*/ +0x3400, /*hidden 10->00 100209*/ +0x3701, /*yc2d power save */ +0x3f04, /*100825*/ +0x4080, /*Y offset */ +0x4138, +0x4880, /*Contrast (Y = constrast * (Y - 128) + 128)*//*86 */ +0x50f0, +0x5300, /*dif_offset option */ +0x5530, /*dif_offset option diff_offset max */ + +0x6003, /*out color sat en[7] | auto color decrement en[1] / + | manual color sat en[0]*/ + + +0x6183, /*blue saturation_C0*/ +0x6280, /*red saturation_B0*/ + +0x63ff, /*auto decresment on AG th*/ +0x64ff, /*auto decresment on DG th*/ +0x66e4, /*Outdoor saturation step 137fps apply out th */ +0x6700, /*Outdoor saturation B/R*/ +0x7601, /* ADD 20121031 */ +0x7904, /* ADD 20121031 */ + +/* Hi 163 */ +/* PAGE 10 START*/ +0x0310, +0x8000, /* dsshin --> color enhance*/ +0xf500, /* dsshin --> h blank option*/ + +0x0311, /*page 11 D_LPF */ +0x103f, /*B[6]:Blue En Dlpf on[4:0] Sky over off : 0x7f->3f*/ +0x1120, /* Uniform Full GbGr/OV-Nr*/ + +0x1280, /*Blue MaxOpt blue sky max filter optoin rate : 0 0xc0->80*/ +0x13b8, /*dark2[7] | dark2 maxfilter ratio[6:4] + | dark3[3] | dark3 maxfilter ratio[2:0] */ + +0x30ba, /*Outdoor2 H th*/ +0x3110, /*Outdoor2 L th*/ +0x3250, /*Outdoor2 gain ratio*/ +0x331d, /*Outdoor2 H lum*/ +0x3420, /*Outdoor2 M lum*/ +0x351f, /*Outdoor2 L lum*/ + +0x36b0, /*Outdoor1 H th*/ +0x3718, /*Outdoor1 L th*/ +0x3850, /*Outdoor1 gain ratio 0x80->40*/ +0x391d, /*Outdoor1 H lum 0x28->1e*/ +0x3a20, /*Outdoor1 M lum 0x10->15*/ +0x3b1f, /*Outdoor1 L lum 0x08->20*/ + +0x3c3f, /*indoor H th*/ +0x3d16, /*indoor L th*/ +0x3e30, /*indoor gain ratio 0x44 6a */ +0x3f1a, /*indoor H lum 0x12 18 */ +0x4060, /*indoor M lum 0x18 1c*/ +0x411a, /*indoor L lum 0x18 3e*/ + +0x4298, /*dark1 H th*/ +0x4328, /*dark1 L th*/ +0x4465, /*dark1 gain ratio*/ +0x4516, /*dark1 H lum 0x38->0x28 */ +0x4630, /*dark1 M lum 0x27->0x17*/ +0x4734, /*dark1 L lum 0x20->0x1a */ + +0x4890, /*dark2 H th*/ +0x492a, /*dark2 L th*/ +0x4a65, /*dark2 gain ratio*/ +0x4b18, /*dark2 H lum */ +0x4c31, /*dark2 M lum*/ +0x4d36, /*dark2 L lum */ + +0x4e80, /*dark3 H th*/ +0x4f30, /*dark3 L th*/ +0x5065, /*dark3 gain ratio*/ +0x5119, /*dark3 H lum */ +0x5231, /*dark3 M lum */ +0x5336, /*dark3 L lum */ + +0x5a3f, /*blue sky mode out1/2 enable 0x27->3f */ +0x5b00, /*Impulse pixel enable dark123,in,out123 + :: must be 0x07 fix setting use!*/ +0x5c9f, /*Indoor maxfilter rate[7:5] | Uncertain onoff[4:0] 0x1f ->0x9f*/ + +0x603f, /*GbGr all enable*/ +0x620f, /*GbGr offset*/ +/*0x6325,*/ /*GbGr max_20120605_off*/ +/*0x6410,*/ /*GbGr min_20120605_off*/ + +0x650c, /*Outdoor GbGr rate H 100% M 25% L 100%*/ +0x660c, /*Indoor GbGr rate H 100% M 25% L 100%*/ +0x6700, /*dark GbGr rate H/M/L 100%*/ + +0x700c, /* Abberation On/Off B[1]: Outdoor B[0]: Indoor 07>>c*/ +0x75a0, /* Outdoor2 Abberation Luminance lvl */ +0x7db4, /* Indoor Abberation Luminance lvl*/ + +0x9608, /*indoor/Dark1 edgeoffset1*/ +0x9714, /*indoor/Dark1 center G value*/ +0x98f5, /*slope indoor :: left/right graph polarity, slope*/ +0x992a, /*indoor uncertain ratio control*/ +0x9a20, /*Edgeoffset_dark*/ + +/*DPC_CTRL*/ +0x0312, /*Preview DPC off[0x5c] on[0x5d]*/ +0x200e, +0x210e, + +0x2500, /* 0x30*/ + +0x2a01, +0x2e00, /*2010.8.25*/ + +0x3035, /*Texture region(most detail)*/ +0x31a0, /*STD uniform1 most blur region*/ +0x32b0, /*STD uniform2 2nd blur*/ +0x33c0, /*STD uniform3 3rd blur*/ +0x34d0, /*STD normal noise1 4th blur */ +0x35e0, /*STD normal noise2 5th blur*/ +0x36ff, /*STD normal noise3 6th blur*/ + +0x4083, /*Outdoor2 H th*/ +0x4120, /*Outdoor2 L th */ +0x4208, /*Outdoor2 H luminance */ +0x4310, /*Outdoor2 M luminance */ +0x4410, /*Outdoor2 l luminance */ +0x4550, /*Outdoor2 ratio*/ + +0x4683, /*Outdoor1 H th*/ +0x4720, /*Outdoor1 L th */ +0x4808, /*Outdoor1 H luminance*/ +0x4910, /*Outdoor1 M luminance*/ +0x4a10, /*Outdoor1 L luminance*/ +0x4b50, /*Outdoor1 ratio*/ + +0x4c80, /*Indoor H th*/ +0x4d48, /*Indoor L th*/ +0x4e30, /*indoor H lum*/ +0x4f30, /*indoor M lum*/ +0x5012, /*indoor L lum */ +0x5170, /*indoor ratio 0x10 -> 0x45*/ + +0x52a8, /*dark1 H th*/ +0x5330, /*dark1 L th */ +0x5428, /*dark1 H lum */ +0x553e, /*dark1 M lum*/ +0x5667, /*dark1 L lum*/ +0x576a, /*dark1 ratio*/ + +0x58a0, /*dark2 H th*/ +0x5940, /*dark2 L th*/ +0x5a28, /*dark2 H lum*/ +0x5b3f, /*dark2 M lum*/ +0x5c68, /*dark2 L lum*/ +0x5d70, /*dark2 ratio*/ + +0x5ea0, /*dark3 H th*/ +0x5f40, /*dark3 L th*/ +0x6029, /*dark3 H lum*/ +0x613f, /*dark3 M lum*/ +0x6269, /*dark3 L lum*/ +0x636a, /*dark3 ratio*/ + +/*C-filter(Out2&Out1)*/ +0x7010, +0x710a, + +/*C-filter(Indoor&Dark3)*/ +0x7210, +0x730a, + +/*C-filter(Dark2&Dark1)*/ +0x7418, +0x7512, + +0x8020, +0x8140, +0x8265, +0x851a, +0x8800, +0x8900, +0x905d, /*Preview DPC off[0x5c] on[0x5d]*/ + +/*DPC-Dark1,2,3*/ +0xad07, /*10825*/ +0xae07, /*10825*/ +0xaf07, /*10825*/ + +/*Blue Det..*/ +0xc558, /*BlueRange 2010.8.25 0x40->23 */ +0xc620, /*GreenRange 2010.8.25 0x3b->20 */ + +0xd088, /*2010.8.25*/ +0xd180, +0xd217,/*preview 17, full 67*/ +0xd300, +0xd400, +0xd50f,/*preview 0f, full 02*/ +0xd6ff, +0xd7ff,/*preview ff, full 18*/ +0xd800, +0xd904, + +/*interpolated with average*/ +0xdb38, /*resolution issue 0x00->0x18->0x38 */ +0xd904, /*strong_edge detect ratio*/ +0xe001, /*strong_edge detect ratio*/ + +0x0313, /*page 13 sharpness 1D*/ +0x10c5, +0x117b, +0x120e, +0x1400, + +0x1511, /*added option 1.3M*/ +0x1830, /*added option 1.3M*/ + +0x2015, +0x2113, +0x2233, +0x2308, /*hi_clip th1*/ +0x241a, /*hi_clip th2*/ +0x2506, /*low clip th*/ + +0x2618, +0x2730, +0x2910, /*time th*/ +0x2a30, /*pga th*/ + +0x2b03, /*lpf out2*/ +0x2c03, /*lpf out1*/ +0x2d0c, +0x2e12, +0x2f12, + +/*1D Edge*/ +0x500a, /*out2 hi nega*/ +0x5307, /* hi pos*/ +0x510c, /* mi nega*/ +0x5407, /* mi pos*/ +0x520b, /* lo nega*/ +0x5508, /* lo pos*/ + +0x560a, /*out1 hi nega*/ +0x5907, /* hi pos */ +0x570c, /* mi nega*/ +0x5a07, /* mi pos */ +0x580b, /* lo nega*/ +0x5b08, /* lo pos */ + +/*Indoor Edge*/ +0x5c08, /*indoor hi nega*/ +0x5f07, /* hi pos*/ +0x5d14, /* mid nega ,11*/ +0x6012, /* mid pos ,0*/ +0x5e0a, /* low nega */ +0x6108, /* low pos*/ + +0x6208, /*dark1 hi nega*/ +0x6506, /* hi pos */ +0x6308, /* mid nega */ +0x6606, /* mid pos */ +0x6408, /* low nega */ +0x6706, /* low pos */ + +0x6807, /*dark2 hi nega*/ +0x6b05, /* hi pos */ +0x6907, /* mid nega */ +0x6c05, /* mid pos */ +0x6a07, /* low nega */ +0x6d05, /* low pos */ + +0x6e0a, /*dark3 hi nega*/ +0x7109, /* hi pos */ +0x6f0a, /* mid nega */ +0x7209, /* mid pos */ +0x700a, /* low nega */ +0x7309, /* low pos */ + + /* 2DY*/ +0x80c1, +0x811f, +0x82e1, +0x8333, + +0x9005, +0x9105, +0x9233, +0x9330, +0x9403, +0x9514, +0x9730, +0x9930, + +0xa002, /*2d lclp out2 nega*/ +0xa103, /*2d lclp out2 pos*/ +0xa202, /*2d lclp out1 nega*/ +0xa303, /*2d lclp out1 pos*/ +0xa403, /*2d lclp in nega*/ +0xa504, /*2d lclp in pos*/ +0xa607, /*2d lclp dark1 nega*/ +0xa708, /*2d lclp dark1 pos*/ +0xa807, /*2d lclp dark2 nega*/ +0xa908, /*2d lclp dark2 pos*/ +0xaa07, /*2d lclp dark3 nega*/ +0xab08, /*2d lclp dark3 pos*/ + +0xb010, /*out2 H Ne*/ +0xb310, /* H Po*/ +0xb11e, /* M Ne*/ +0xb41e, /* M Po*/ +0xb21f, /* L Ne*/ +0xb51e, /* L Po*/ + +0xb610, /*out1 H Ne */ +0xb910, /* H Po */ +0xb71e, /* M Ne */ +0xba1e, /* M Po */ +0xb81f, /* L Ne */ +0xbb1e, /* L Po */ + +0xbc20, /*indoor H Ne*/ +0xbf1e, /* H Po*/ +0xbd25, /* M Ne*/ +0xc023, /* M Po*/ +0xbe24, /* L Ne*/ +0xc122, /* L Po*/ + +0xc223, /*dark1 H Ne*/ +0xc523, /* H Po*/ +0xc329, /* M Ne*/ +0xc629, /* M Po*/ +0xc425, /* L Ne*/ +0xc725, /* L Po*/ + +0xc81c, /*dark2 H Ne*/ +0xcb1c, /* H Po*/ +0xc925, /* M Ne*/ +0xcc25, /* M Po*/ +0xca23, /* L Ne*/ +0xcd23, /* L Po*/ + +0xce1c, /*dark3 H Ne*/ +0xd11c, /* H Po*/ +0xcf25, /* M Ne*/ +0xd225, /* M Po*/ +0xd023, /* L Ne*/ +0xd323, /* L Po*/ + +/* PAGE 14 START*/ +0x0314, +0x1031, + +0x1480, /* GX*/ +0x1580, /* GY*/ +0x1680, /* RX*/ +0x1780, /* RY*/ +0x1880, /* BX*/ +0x1980, /* BY*/ + +0x2060, /* X Center*/ +0x2180, /* Y Center*/ + +0x2280, +0x2380, +0x2480, + +0x30c8, +0x312b, +0x3200, +0x3300, +0x3490, + +0x4056, /*R min's set 4e*/ +0x413a, /*Gr*/ +0x4237, /*B*/ +0x433a, /*Gb*/ + +0x0315, +0x1021, +0x1444, /*49*/ +0x1534, /*38*/ +0x1626, /*2b*/ +0x172f, + +0x30dd, +0x3162, +0x3205, +0x3326, +0x34bd, +0x3517, +0x3618, +0x3738, +0x38d0, + +0x40b0, +0x4130, +0x4200, +0x4300, +0x4400, +0x4500, +0x4699, +0x4719, +0x4800, + +0x5016, +0x51b2, +0x521c, +0x5306, +0x5420, +0x55a6, +0x560e, +0x57b2, +0x5824, + +0x0316, +0x1031, /*GMA_CTL*/ +0x187e, /*AG_ON*/ +0x197d, /*AG_OFF*/ +0x1a0e, /*TIME_ON*/ +0x1b01, /*TIME_OFF*/ +0x1Cdc, /*OUT_ON*/ +0x1Dfe, /*OUT_OFF*/ + +/*GMA, Indoor*/ +0x3000, +0x3107, +0x321a, +0x3335, +0x345a, +0x357c, +0x3696, +0x37a9, +0x38b7, +0x39c6, +0x3ad2, +0x3bdc, +0x3ce4, +0x3deb, +0x3ef1, +0x3ff5, +0x40f9, +0x41fd, +0x42ff, + +/*RGMA, Outdoor*/ +0x5000, +0x5103, +0x5213, +0x532e, +0x5459, +0x5579, +0x5690, +0x57a3, +0x58b4, +0x59c2, +0x5acd, +0x5bd7, +0x5ce0, +0x5de5, +0x5ee9, +0x5fee, +0x60f1, +0x61f3, +0x62f6, + +/*BGMA Dark*/ +0x7000, +0x7107, +0x721a, +0x7335, +0x745a, +0x757c, +0x7696, +0x77a9, +0x78b7, +0x79c6, +0x7ad2, +0x7bdc, +0x7ce4, +0x7deb, +0x7ef1, +0x7ff5, +0x80f9, +0x81fd, +0x82ff, + +0x0324, /*Resol control */ +0x60c5, /*edge even frame | 16bit resol | white edge cnt | scene resol enable*/ +0x6104, /*even frame update */ +0x6408, /* 0x6435, edge th1 H*/ +0x6500, /*edge th1 L*/ +0x6626, /*edge th2 H */ +0x6700, /*edge th2 L */ + +0x0313, +0x1831, /*flat center Gb/Gr*/ +0x7402, /*det slope en | gausian filter*/ +0x750d, /*1D negative gain det 09 */ +0x760d, /*1D postive gain det 08*/ +0x7710, /*1D hclp2 det*/ +0x7808, /*outdoor flat threshold*/ +0x7910, /*indoor flat threshold*/ + +0x81df, /*det gain controler*/ +0x8690, /*2D negative gain det */ +0x8790, /*2D postive gain det */ +0x962a, /*2D hclp2 det*/ + +0x0312, /*0x12 page*/ +0xd088, +0xd9e4, + +/* PAGE 20 START*/ +0x0320, +0x111c, +0x1830, +0x1a08, +0x2045,/*weight*/ +0x2130, +0x2210, +0x2300, +0x2400, + +0x28e7, /* add 20120223*/ +0x290d, /* 20100305 ad -> 0d*/ +0x2afd, +0x2bf8, + +0x2cc3, +0x2d5f, /* add 20120223*/ +0x2e33, +0x30f8, +0x3203, +0x332e, +0x3430, +0x35d4, +0x36fe, +0x3732, +0x3804, +0x3922, +0x3ade, +0x3b22, +0x3cde, +0x3de1, + +0x5045, +0x5188, + +0x561a, +0x5780, +0x580e, +0x596a, +0x5a04, + +0x5e9d, /*AE_AWB_start*/ +0x5f76, /*AE_AWB_start*/ + +0x7040, /* 6c*/ +0x7182, /* 82(+8)*/ + +0x7621, +0x7791, +0x7822, /* 24*/ +0x792b, /* Y Target 70 => 25, 72 => 26*/ +0x7a23, /* 23*/ +0x7b22, /* 22*/ +0x7d23, + +0x8301, /*EXP Normal 33.33 fps */ +0x845f, +0x8590, + +0x8601, /*EXPMin 7500.00 fps*/ +0x8790, + +0x8803, /*EXP Max(120Hz) 12.00 fps*/ +0x89d0, +0x8a90, + +0xa504, /*EXP Max(100Hz) 11.11 fps*/ +0xa61e, +0xa7b0, + +0x8B75, /*EXP100 */ +0x8C30, +0x8D61, /*EXP120 */ +0x8Ea8, + +0x9104, /*EXP Fix 10.00 fps*/ +0x9293, +0x93e0, + +0x9c0a, /*EXP Limit 1071.43 fps*/ +0x9df0, +0x9e01, /*EXP Unit */ +0x9f90, +0x989d, + +0xb016, +0xb114, +0xb2f8, +0xb314, +0xb41b, +0xb546, +0xb631, +0xb729, +0xb826, +0xb924, +0xba22, +0xbb42, +0xbc41, +0xbd40, + +0xc010, +0xc138, +0xc238, +0xc338, +0xc407, + +0xc880, +0xc980, +0x109c, /* ae enable*/ +/* PAGE 20 END*/ + +/*AE_Weight*/ +0x0321, +0x2011, +0x2111, +0x2211, +0x2311, +0x2412, +0x2522, +0x2622, +0x2721, +0x2812, +0x2922, +0x2a22, +0x2b21, +0x2c12, +0x2d23, +0x2e32, +0x2f21, +0x3012, +0x3123, +0x3232, +0x3321, +0x3412, +0x3522, +0x3622, +0x3721, +0x3812, +0x3922, +0x3a22, +0x3b21, +0x3c11, +0x3d11, +0x3e11, +0x3f11, + +/* PAGE 22 START*/ +0x0322, +0x10fd, +0x112e, +0x1901, /* Low On*/ +0x2030, /* for wb speed*/ +0x2140, +0x2401, +0x257e, /* for tracking 20120314 */ + +0x3080, /* 20120224 test*/ +0x3180, +0x3811, +0x3934, + +0x40e8, +0x4143, /* 33*/ +0x4222, /* 22*/ + +0x43f3, /* f6*/ +0x4454, /* 44*/ +0x4522, /* 33*/ + +0x4600, +0x480a, +0x50b2, +0x5181, +0x5298, + +0x8038, +0x8120, +0x8238, /* 3a*/ + +0x8356, /* R Max*/ +0x8420, /* R Min*/ +0x8554, /* B Max*/ +0x8620, /* B Min*/ + +0x8746, +0x8836, +0x893a, +0x8a2f, + +0x8b3d, +0x8c37, +0x8d35, +0x8e32, + +0x8f5a, +0x9059, +0x9155, +0x924e, +0x9344, +0x943a, +0x9534, +0x962c, +0x9723, +0x9820, +0x991f, +0x9a1f, + +0x9b77, +0x9c77, +0x9d48, +0x9e38, +0x9f30, + +0xa040, +0xa121, +0xa26f, +0xa3ff, + +0xa414, /* 1500fps*/ +0xa544, /* 700fps*/ +0xa6cf, + +0xad40, +0xae4a, + +0xaf2a, /* low temp Rgain*/ +0xb028, /* low temp Rgain*/ + +0xb100, /* 0x20 -> 0x00 0405 modify*/ +0xb4bf, /* for tracking 20120314*/ +0xb8a1, /* a2: b-2, R+2 b4 B-3, R+4 lowtemp b0 a1 Spec AWB A modify*/ +0xb900, +/* PAGE 22 END*/ + +/* PAGE 48 (MiPi 1600x1200)*/ +0x0300, + +/* PLL Setting */ +0xd005, +0xd130, +0xd205, +0xd320, +0xd085, +0xd085, +0xd085, +0xd095, + +/* MIPI TX Setting */ +0x0348, +0x101c, +0x1100, +0x1200, +0x1400, +0x1604, +0x1700, +0x1880, +0x1900, +0x1aa0, +/*0x1b0d,*/ +0x1c02, +0x1d0e, +0x1e07, +0x1f08, +/*0x2000,*/ + +0x2200, +0x2301, +0x241e, +0x2500, +0x2600, +0x2708, +0x2800, +/*0x2a06,*/ +/*0x2b40,*/ +/*0x2c04,*/ +/*0x2db0,*/ + +0x3005, +0x3100, + +0x3207, +0x3309, +0x3401, +0x3501, +/*0x3601,*/ +/*0x3707,*/ +/*0x3802,*/ +/*0x3902,*/ + +0x0300, +0x0101, +}; + +static const sr130pc20_regset_t sr130pc20_SmartStay_Init_Reg[] = { +/*0 Page*/ +0x0300, +0x0101, /*sleep*/ +0x0103, /*s/w reset*/ +0x0101, /*sleep*/ + +0x0800,/*Don't touch*/ +0x0937,/*Don't touch*/ +0x0a33,/*Don't touch*/ + +/*PLL Setting*/ +0xd005, +0xd130, +0xd201, +0xd320, +0xd085, +0xd085, +0xd085, +0xd095, + +0x1011, +0x1190, /*xy flip*/ +0x1200, +0x1488, + +0x0300, +0x2000, +0x2104, +0x2200, +0x2304, +0x2403, +0x25C0, +0x2605, +0x2700, + +0x4001, /*Hblank_280*/ +0x4118, +0x4201, /*Vblank 400*/ +0x4390, + +/*--------------- BLC*/ +0x8008, /*Don't touch */ +0x8197, /*Don't touch */ +0x8290, /*Don't touch */ +0x8330, /*Don't touch */ +0x84cc, /*Don't touch*/ +0x8500, /*Don't touch*/ +0x86d4, /*Don' t touch*/ +0x870f, /*Don't touch*/ +0x8834, /*Don't touch*/ + +0x900c, /*BLC_TIME_TH_ON*/ +0x910c, /*BLC_TIME_TH_OFF */ +0x92f7, /*BLC_AG_TH_ON*/ +0x93ef, /*BLC_AG_TH_OFF*/ + +0x9495, /*091202*/ +0x9590, /*091202 */ +0x9838, /*Don't touch*/ + +/*Dark BLC*/ +0xa000, /* 20100309*/ +0xa200, /* 20100309*/ +0xa400, /* 20100309*/ +0xa600, /* 20100309*/ + +/*Normal BLC*/ +0xa800, +0xaa00, +0xac00, +0xae00, + +/*Out BLC*/ +0x9900, +0x9a00, +0x9b00, +0x9c00, + +/*2 Page*/ +0x0302, +0x1200, /*Don't touch*/ +0x1400, /*Don't touch*/ +0x1500, /*Don't touch*/ +0x184C, /*Don't touch*/ +0x1900, /*Don't touch*/ +0x1A39, /*Don't touch*/ +0x1B00,/*Don't touch*/ +0x1C1a, /*Don't touch*/ +0x1D14, /*Don't touch*/ +0x1E30,/*Don't touch*/ +0x1F10,/*Don't touch*/ + +0x2077, +0x21de, +0x22a7, +0x2330, +0x2477, +0x2510, +0x2610, +0x273c, +0x2b80, +0x2c02, +0x2da0, +0x2e00, +0x2fa7, + +0x3000, +0x3199, +0x3200, +0x3300, +0x3422, +0x3601, +0x3701, +0x3888, +0x3988, +0x3d03, +0x3e0d, +0x3f02, + +0x49d1, +0x4a14, + +0x5021, +0x5201, +0x5381, +0x5410, +0x551c, +0x5611, +0x5818, +0x5916, +0x5da2, +0x5e5a, + +0x6093, /* 20120517 modify*/ +0x61a4, /* 20120517 modify*/ +0x6294, /* 20120517 modify*/ +0x63a3, /* 20120517 modify*/ +0x6494, /* 20120517 modify*/ +0x65a3, /* 20120517 modify*/ +0x670c, +0x680c, +0x690c, +0x6ab4, +0x6bc4, +0x6cb5, +0x6dc2, +0x6eb5, +0x6fc0, + +0x70b6, +0x71b8, +0x7295, /* 20120517 modify*/ +0x73a2, /* 20120517 modify*/ +0x7495, /* 20120517 modify*/ +0x75a2, /* 20120517 modify*/ +0x7695, /* 20120517 modify*/ +0x77a2, /* 20120517 modify*/ +0x7C92, /* 20120517 modify*/ +0x7Dff, /* 20120517 modify*/ + +0x8001, /* 20120517 modify*/ +0x818a, /* 20120517 modify*/ +0x821e, /* 20120517 modify*/ +0x8336, /* 20120517 modify*/ +0x8489, /* 20120517 modify*/ +0x858b, /* 20120517 modify*/ +0x8689, /* 20120517 modify*/ +0x878b, /* 20120517 modify*/ +0x88ab, +0x89bc, +0x8aac, +0x8bba, +0x8cad, +0x8db8, +0x8eae, +0x8fb2, + +0x90b3, +0x91b7, +0x9252, /* 20120517 modify*/ +0x936a, /* 20120517 modify*/ +0x9489, /* 20120517 modify*/ +0x958b, /* 20120517 modify*/ +0x9689, /* 20120517 modify*/ +0x978b, /* 20120517 modify*/ + +0xA002, +0xA186, /* 20120517 modify*/ +0xA202, +0xA386, /* 20120517 modify*/ +0xA486, /* 20120517 modify*/ +0xA502, +0xA686, /* 20120517 modify*/ +0xA702, +0xA892, /* 20120517 modify*/ +0xA994, /* 20120517 modify*/ +0xAA92, /* 20120517 modify*/ +0xAB94, /* 20120517 modify*/ +0xAC1c, +0xAD22, +0xAE1c, +0xAF22, + +0xB0a4, /* 20120517 modify*/ +0xB1ae, /* 20120517 modify*/ +0xB2a4, /* 20120517 modify*/ +0xB3ae, /* 20120517 modify*/ +0xB4a6, /* 20120517 modify*/ +0xB5ac, /* 20120517 modify*/ +0xB6a6, /* 20120517 modify*/ +0xB7ac, /* 20120517 modify*/ +0xB8a6, /* 20120517 modify*/ +0xB9ab, /* 20120517 modify*/ +0xBAa6, /* 20120517 modify*/ +0xBBab, /* 20120517 modify*/ +0xBCa6, /* 20120517 modify*/ +0xBDab, /* 20120517 modify*/ +0xBEa6, /* 20120517 modify*/ +0xBFab, /* 20120517 modify*/ + +0xc437, +0xc552, +0xc66b, +0xc786, +0xc838, /* 20120517 modify*/ +0xc950, /* 20120517 modify*/ +0xca38, /* 20120517 modify*/ +0xcb50, /* 20120517 modify*/ +0xcc6c, /* 20120517 modify*/ +0xcd84, /* 20120517 modify*/ +0xce6c, /* 20120517 modify*/ +0xcf84, /* 20120517 modify*/ + +/*0xd4a6,*/ +/*0xd5ac,*/ +/*0xd6a6,*/ +/*0xd7ac,*/ +/*add 20120517*/ +0xdc00, /* Added*/ +0xddaf, /* Added*/ +0xde00, /* Added*/ +0xdf90, /* Added*/ + +0xd010, +0xd114, +0xd220, +0xd300, +/*DCDC */ +0xd40c, /*DCDC_TIME_TH_ON*/ +0xd50c, /*DCDC_TIME_TH_OFF */ +0xd6f7, /*DCDC_AG_TH_ON*/ +0xd7ef, /*DCDC_AG_TH_OFF*/ + +0xea8a, + +0xF001, /* clock inversion*/ +0xF101, +0xF201, +0xF301, +0xF401, +0xF500, + +/*----------------------------------------------*/ +0x0310, /*page 10*/ +0x1001, /*Ycbcr422_bit Order: YUYV*/ +0x1103, +0x1230, /*y offset[4], dif_offset[5]*/ +0x1302, /*contrast effet enable : 0x02*/ +0x3400, /*hidden 10->00 100209*/ +0x3701, /*yc2d power save */ +0x3f04, /*100825*/ +0x4080, /*Y offset */ +0x4128, +0x4880, +0x5300, /*dif_offset option */ +0x5530, /*dif_offset option diff_offset max */ + +0x606b, /*out color sat en[7] | auto color decrement en[1] / + | manual color sat en[0]*/ + +0x6183, /*blue saturation_C0*/ +0x6280, /*red saturation_B0*/ + +0x63b0, /*auto decresment on AG th*/ +0x64ff, /*auto decresment on DG th*/ +0x66e4, /*Outdoor saturation step 137fps apply out th */ +0x6700, /*Outdoor saturation B/R*/ +0x7601, /* ADD 20121031 */ +0x7904, /* ADD 20121031 */ + +/* Hi 163 */ +/* PAGE 10 START*/ +0x0310, +0x8000, /* dsshin --> color enhance*/ +0xf500, /* dsshin --> h blank option*/ + +0x0311, /*page 11 D_LPF */ +0x103f, /*B[6]:Blue En Dlpf on[4:0] Sky over off : 0x7f->3f*/ +0x1120, /* Uniform Full GbGr/OV-Nr*/ + +0x1280, /*Blue MaxOpt blue sky max filter optoin rate : 0 0xc0->80*/ +0x13b8, /*dark2[7] | ratio[6:4] | dark3[3] | dark3 maxfilter ratio[2:0] */ + +0x30ba, /*Outdoor2 H th*/ +0x3110, /*Outdoor2 L th*/ +0x3250, /*Outdoor2 gain ratio*/ +0x331d, /*Outdoor2 H lum*/ +0x3420, /*Outdoor2 M lum*/ +0x351f, /*Outdoor2 L lum*/ + +0x36b0, /*Outdoor1 H th*/ +0x3718, /*Outdoor1 L th*/ +0x3850, /*Outdoor1 gain ratio 0x80->40*/ +0x391d, /*Outdoor1 H lum 0x28->1e*/ +0x3a20, /*Outdoor1 M lum 0x10->15*/ +0x3b1f, /*Outdoor1 L lum 0x08->20*/ + +0x3c3f, /*indoor H th*/ +0x3d16, /*indoor L th*/ +0x3e30, /*indoor gain ratio 0x44 6a */ +0x3f1a, /*indoor H lum 0x12 18 */ +0x4060, /*indoor M lum 0x18 1c*/ +0x411a, /*indoor L lum 0x18 3e*/ + +0x4280, /*dark1 H th*/ +0x4318, /*dark1 L th*/ +0x4480, /*dark1 gain ratio*/ +0x450f, /*dark1 H lum 0x38->0x28 */ +0x460c, /*dark1 M lum 0x27->0x17*/ +0x470b, /*dark1 L lum 0x20->0x1a */ + +0x4880, /*dark2 H th*/ +0x4918, /*dark2 L th*/ +0x4a80, /*dark2 gain ratio*/ +0x4b0f, /*dark2 H lum */ +0x4c0c, /*dark2 M lum*/ +0x4d0b, /*dark2 L lum */ + +0x4e80, /*dark3 H th*/ +0x4f23, /*dark3 L th*/ +0x5080, /*dark3 gain ratio*/ +0x511d, /*dark3 H lum */ +0x521f, /*dark3 M lum */ +0x531f, /*dark3 L lum */ + +0x5a3f, /*blue sky mode out1/2 enable 0x27->3f */ +0x5b00, /*Impulse pixel enable dark123,in,out123 :: must be 0x07*/ +0x5c9f, /*Indoor maxfilter rate[7:5] | Uncertain onoff[4:0] 0x1f ->0x9f*/ + +0x603f, /*GbGr all enable*/ +0x620f, /*GbGr offset*/ + +0x650c, /*Outdoor GbGr rate H 100% M 25% L 100%*/ +0x660c, /*Indoor GbGr rate H 100% M 25% L 100%*/ +0x6700, /*dark GbGr rate H/M/L 100%*/ + +0x700c, /* Abberation On/Off B[1]: Outdoor B[0]: Indoor 07>>c*/ +0x75a0, /* Outdoor2 Abberation Luminance lvl */ +0x7db4, /* Indoor Abberation Luminance lvl*/ + +0x9608, /*indoor/Dark1 edgeoffset1*/ +0x9714, /*indoor/Dark1 center G value*/ +0x98f5, /*slope indoor :: left/right graph polarity, slope*/ +0x992a, /*indoor uncertain ratio control*/ +0x9a20, /*Edgeoffset_dark*/ + +/*DPC_CTRL*/ +0x0312, /*Preview DPC off[0x5c] on[0x5d]*/ +0x200f, +0x210f, + +0x2500, /* 0x30*/ + +0x2a01, +0x2e00, /*2010.8.25*/ + +0x3035, /*Texture region(most detail)*/ +0x31a0, /*STD uniform1 most blur region*/ +0x32b0, /*STD uniform2 2nd blur*/ +0x33c0, /*STD uniform3 3rd blur*/ +0x34d0, /*STD normal noise1 4th blur */ +0x35e0, /*STD normal noise2 5th blur*/ +0x36ff, /*STD normal noise3 6th blur*/ + +0x4083, /*Outdoor2 H th*/ +0x4120, /*Outdoor2 L th */ +0x4208, /*Outdoor2 H luminance */ +0x4310, /*Outdoor2 M luminance */ +0x4410, /*Outdoor2 l luminance */ +0x4550, /*Outdoor2 ratio*/ + +0x4683, /*Outdoor1 H th*/ +0x4720, /*Outdoor1 L th */ +0x4808, /*Outdoor1 H luminance*/ +0x4910, /*Outdoor1 M luminance*/ +0x4a10, /*Outdoor1 L luminance*/ +0x4b50, /*Outdoor1 ratio*/ + +0x4c80, /*Indoor H th*/ +0x4d48, /*Indoor L th*/ +0x4e30, /*indoor H lum*/ +0x4f30, /*indoor M lum*/ +0x5012, /*indoor L lum */ +0x5170, /*indoor ratio 0x10 -> 0x45*/ + +0x52a8, /*dark1 H th*/ +0x5330, /*dark1 L th */ +0x5428, /*dark1 H lum */ +0x553e, /*dark1 M lum*/ +0x5667, /*dark1 L lum*/ +0x576a, /*dark1 ratio*/ + +0x58a0, /*dark2 H th*/ +0x5940, /*dark2 L th*/ +0x5a28, /*dark2 H lum*/ +0x5b3f, /*dark2 M lum*/ +0x5c68, /*dark2 L lum*/ +0x5d70, /*dark2 ratio*/ + +0x5ea0, /*dark3 H th*/ +0x5f1c, /*dark3 L th*/ +0x6029, /*dark3 H lum*/ +0x614a, /*dark3 M lum*/ +0x62ff, /*dark3 L lum*/ +0x63ff, /*dark3 ratio*/ + +/*C-filter(Out2&Out1)*/ +0x7010, +0x710a, + +/*C-filter(Indoor&Dark3)*/ +0x7210, +0x730a, + +/*C-filter(Dark2&Dark1)*/ +0x7418, +0x7512, + +0x8020, +0x8140, +0x8265, +0x851a, +0x8800, +0x8900, +0x905d, /*Preview DPC off[0x5c] on[0x5d]*/ + +/*DPC-Dark1,2,3*/ +0xad07, /*10825*/ +0xae07, /*10825*/ +0xaf07, /*10825*/ + +/*Blue Det..*/ +0xc558, /*BlueRange 2010.8.25 0x40->23 */ +0xc620, /*GreenRange 2010.8.25 0x3b->20 */ + +0xd088, /*2010.8.25*/ +0xd180, +0xd217,/*preview 17, full 67*/ +0xd300, +0xd400, +0xd50f,/*preview 0f, full 02*/ +0xd6ff, +0xd7ff,/*preview ff, full 18*/ +0xd800, +0xd904, + +/*interpolated with average*/ +0xdb38, /*resolution issue 0x00->0x18->0x38 */ +0xd904, /*strong_edge detect ratio*/ +0xe001, /*strong_edge detect ratio*/ + +0x0313, /*page 13 sharpness 1D*/ +0x10c5, +0x117b, +0x120e, +0x1400, + +0x1511, /*added option 1.3M*/ +0x1830, /*added option 1.3M*/ + +0x2015, +0x2113, +0x2233, +0x2308, /*hi_clip th1*/ +0x241a, /*hi_clip th2*/ +0x2506, /*low clip th*/ + +0x2618, +0x2730, +0x2910, /*time th*/ +0x2a30, /*pga th*/ + +0x2b03, /*lpf out2*/ +0x2c03, /*lpf out1*/ +0x2d0c, +0x2e12, +0x2f12, + +/*1D Edge*/ +0x500a, /*out2 hi nega*/ +0x5307, /* hi pos*/ +0x510c, /* mi nega*/ +0x5407, /* mi pos*/ +0x520b, /* lo nega*/ +0x5508, /* lo pos*/ + +0x560a, /*out1 hi nega*/ +0x5907, /* hi pos */ +0x570c, /* mi nega*/ +0x5a07, /* mi pos */ +0x580b, /* lo nega*/ +0x5b08, /* lo pos */ + +/*Indoor Edge*/ +0x5c08, /*indoor hi nega*/ +0x5f07, /* hi pos*/ +0x5d14, +0x6012, +0x5e0a, +0x6108, /* low pos*/ + +0x6208, /*dark1 hi nega*/ +0x6506, /* hi pos */ +0x6308, /* mid nega */ +0x6606, /* mid pos */ +0x6408, /* low nega */ +0x6706, /* low pos */ + +0x6807, /*dark2 hi nega*/ +0x6b05, /* hi pos */ +0x6907, /* mid nega */ +0x6c05, /* mid pos */ +0x6a07, /* low nega */ +0x6d05, /* low pos */ + +0x6e0a, /*dark3 hi nega*/ +0x7109, /* hi pos */ +0x6f0d, /* mid nega */ +0x720c, /* mid pos */ +0x700d, /* low nega */ +0x730c, /* low pos */ + + /* 2DY*/ +0x80c1, +0x811f, +0x82e1, +0x8333, + +0x9005, +0x9105, +0x9233, +0x9330, +0x9403, +0x9514, +0x9730, +0x9930, + +0xa002, /*2d lclp out2 nega*/ +0xa103, /*2d lclp out2 pos*/ +0xa202, /*2d lclp out1 nega*/ +0xa303, /*2d lclp out1 pos*/ +0xa403, /*2d lclp in nega*/ +0xa504, /*2d lclp in pos*/ +0xa607, /*2d lclp dark1 nega*/ +0xa708, /*2d lclp dark1 pos*/ +0xa807, /*2d lclp dark2 nega*/ +0xa908, /*2d lclp dark2 pos*/ +0xaa07, /*2d lclp dark3 nega*/ +0xab08, /*2d lclp dark3 pos*/ + +0xb010, /*out2 H Ne*/ +0xb310, /* H Po*/ +0xb11e, /* M Ne*/ +0xb41e, /* M Po*/ +0xb21f, /* L Ne*/ +0xb51e, /* L Po*/ + +0xb610, /*out1 H Ne */ +0xb910, /* H Po */ +0xb71e, /* M Ne */ +0xba1e, /* M Po */ +0xb81f, /* L Ne */ +0xbb1e, /* L Po */ + +0xbc20, /*indoor H Ne*/ +0xbf1e, /* H Po*/ +0xbd25, /* M Ne*/ +0xc023, /* M Po*/ +0xbe24, /* L Ne*/ +0xc122, /* L Po*/ + +0xc223, /*dark1 H Ne*/ +0xc523, /* H Po*/ +0xc329, /* M Ne*/ +0xc629, /* M Po*/ +0xc425, /* L Ne*/ +0xc725, /* L Po*/ + +0xc81c, /*dark2 H Ne*/ +0xcb1c, /* H Po*/ +0xc925, /* M Ne*/ +0xcc25, /* M Po*/ +0xca23, /* L Ne*/ +0xcd23, /* L Po*/ + +0xce1c, /*dark3 H Ne*/ +0xd11c, /* H Po*/ +0xcf29, /* M Ne*/ +0xd229, /* M Po*/ +0xd027, /* L Ne*/ +0xd327, /* L Po*/ + +/* PAGE 14 START*/ +0x0314, +0x1031, + +0x1480, /* GX*/ +0x1580, /* GY*/ +0x1680, /* RX*/ +0x1780, /* RY*/ +0x1880, /* BX*/ +0x1980, /* BY*/ + +0x2060, /* X Center*/ +0x2180, /* Y Center*/ + +0x2280, +0x2380, +0x2480, + +0x30c8, +0x312b, +0x3200, +0x3300, +0x3490, + +0x4056, /*R min's set 4e*/ +0x413a, /*Gr*/ +0x4237, /*B*/ +0x433a, /*Gb*/ + +0x0315, +0x1021, +0x1444, /*49*/ +0x1534, /*38*/ +0x1626, /*2b*/ +0x172f, + +0x30dd, +0x3162, +0x3205, +0x3326, +0x34bd, +0x3517, +0x3618, +0x3738, +0x38d0, + +0x40b0, +0x4130, +0x4200, +0x4300, +0x4400, +0x4500, +0x4699, +0x4719, +0x4800, + +0x5016, +0x51b2, +0x521c, +0x5306, +0x5420, +0x55a6, +0x560e, +0x57b2, +0x5824, + +0x0316, +0x1031, /*GMA_CTL*/ +0x187e, /*AG_ON*/ +0x197d, /*AG_OFF*/ +0x1a0e, /*TIME_ON*/ +0x1b01, /*TIME_OFF*/ +0x1Cdc, /*OUT_ON*/ +0x1Dfe, /*OUT_OFF*/ + +/*GMA Indoor*/ +0x3000, +0x3126, +0x3238, +0x3355, +0x347e, +0x3597, +0x36a9, +0x37ba, +0x38c7, +0x39d2, +0x3adb, +0x3be3, +0x3cea, +0x3dee, +0x3ef5, +0x3ff9, +0x40fc, +0x41fe, +0x42ff, + +/*RGMA Outdoor*/ +0x5000, +0x5126, +0x5238, +0x5355, +0x547e, +0x5597, +0x56a9, +0x57ba, +0x58c7, +0x59d2, +0x5adb, +0x5be3, +0x5cea, +0x5dee, +0x5ef5, +0x5ff9, +0x60fc, +0x61fe, +0x62ff, + +/*BGMA Dark*/ +0x7002, +0x712a, +0x723b, +0x7359, +0x7481, +0x759b, +0x76ac, +0x77be, +0x78ca, +0x79d4, +0x7adb, +0x7be4, +0x7ceb, +0x7def, +0x7ef6, +0x7ffa, +0x80fc, +0x81fe, +0x82ff, + +0x0324, /*Resol control */ +0x60c5, /*edge even frame | 16bit resol | white edge cnt | scene resol enable*/ +0x6104, /*even frame update */ +0x6408, +0x6500, +0x6626, /*edge th2 H */ +0x6700, /*edge th2 L */ + +0x0313, +0x1831, /*flat center Gb/Gr*/ +0x7402, /*det slope en | gausian filter*/ +0x750d, /*1D negative gain det 09 */ +0x760d, /*1D postive gain det 08*/ +0x7710, /*1D hclp2 det*/ +0x7808, /*outdoor flat threshold*/ +0x7910, /*indoor flat threshold*/ + +0x81df, /*det gain controler*/ +0x8690, /*2D negative gain det */ +0x8790, /*2D postive gain det */ +0x962a, /*2D hclp2 det*/ + +0x0312, /*0x12 page*/ +0xd088, +0xd9e4, + +/* PAGE 18 START*/ +0x0318, +0x1400, + +/* PAGE 20 START*/ +0x0320, +0x111c, +0x1830, +0x1a08, +0x2045,/*weight*/ +0x2130, +0x2210, +0x2300, +0x2400, + +0x28e7, /* add 20120223*/ +0x290d, /* 20100305 ad -> 0d*/ +0x2afd, +0x2bf8, + +0x2cc3, +0x2d5f, /* add 20120223*/ +0x2e33, +0x30f8, +0x3203, +0x332e, +0x3430, +0x35d4, +0x36ff, /*fe*/ +0x3732, +0x3804, +0x3922, +0x3ade, +0x3b22, +0x3cde, +0x3de1, + +0x5045, +0x5188, + +0x561a, +0x5780, +0x580e, +0x596a, +0x5a04, + +0x5e9d, /*AE_AWB_start*/ +0x5f76, /*AE_AWB_start*/ + +0x703f, /* 6c*/ +0x7180, /* 82(+8)*/ + +0x7621, +0x7781, +0x7822, /* 24*/ +0x7925, /* Y Target 70 => 25, 72 => 26*/ +0x7a23, /* 23*/ +0x7b22, /* 22*/ +0x7d23, + +0x8301, /*EXP Normal 30.00 fps */ +0x845f, +0x8590, +0x8601, /*EXPMin 7500.00 fps*/ +0x8790, +0x8805, /*EXP Max(120Hz) 8.00 fps */ +0x89b8, +0x8ad8, +0xa505, /*EXP Max(100Hz) 8.33 fps */ +0xa67e, +0xa740, +0x8B75, /*EXP100 */ +0x8C30, +0x8D61, /*EXP120 */ +0x8Ea8, +0x9c09, /*EXP Limit 1250.00 fps */ +0x9d60, +0x9e01, /*EXP Unit */ +0x9f90, +0x989d, + +0xb016, +0xb114, +0xb2f0, +0xb314, +0xb41b, +0xb546, +0xb631, +0xb729, +0xb826, +0xb924, +0xba22, +0xbb42, +0xbc41, +0xbd40, + +0xc010, +0xc138, +0xc238, +0xc338, +0xc407, + +0xc880, +0xc980, +0x109c, /* ae enable*/ +/* PAGE 20 END*/ + +/*AE_Weight*/ +0x0321, +0x2011, +0x2111, +0x2211, +0x2311, +0x2422, +0x2522, +0x2622, +0x2721, +0x2823, +0x2933, +0x2a32, +0x2b21, +0x2c23, +0x2d44, +0x2e32, +0x2f21, +0x3023, +0x3144, +0x3232, +0x3311, +0x3423, +0x3533, +0x3632, +0x3721, +0x3822, +0x3922, +0x3a22, +0x3b21, +0x3c11, +0x3d11, +0x3e11, +0x3f11, + +/* PAGE 22 START*/ +0x0322, +0x10fd, +0x112e, +0x1901, /* Low On*/ +0x2030, /* for wb speed*/ +0x2140, +0x2401, +0x257e, /* for tracking 20120314 */ + +0x3080, /* 20120224 test*/ +0x3180, +0x3811, +0x3934, + +0x40e8, +0x4143, /* 33*/ +0x4222, /* 22*/ + +0x43f3, /* f6*/ +0x4454, /* 44*/ +0x4522, /* 33*/ + +0x4600, +0x480a, +0x50b2, +0x5181, +0x5298, + +0x8038, +0x8120, +0x8238, /* 3a*/ + +0x8356, /* R Max*/ +0x8420, /* R Min*/ +0x8552, /* B Max*/ +0x8620, /* B Min*/ + +0x8746, +0x8836, +0x8939, +0x8a2d, + +0x8b3c, +0x8c36, +0x8d34, +0x8e31, + +0x8f5a, +0x9059, +0x9154, +0x924d, +0x9342, +0x943a, +0x9534, +0x962c, +0x9723, +0x9820, +0x991f, +0x9a1f, + +0x9b77, +0x9c77, +0x9d48, +0x9e38, +0x9f30, + +0xa040, +0xa122, +0xa26f, +0xa3ff, + +0xa414, /* 1500fps*/ +0xa544, /* 700fps*/ +0xa6cf, + +0xad40, +0xae4a, + +0xaf2a, /* low temp Rgain*/ +0xb028, /* low temp Rgain*/ + +0xb100, /* 0x20 -> 0x00 0405 modify*/ +0xb4bf, /* for tracking 20120314*/ +0xb8a1, /* a2: b-2, R+2 b4 B-3, R+4 lowtemp b0 a1 Spec AWB A modify*/ +0xb900, +/* PAGE 22 END*/ + +/* PAGE 48 (MiPi 1600x1200)*/ +0x0300, + +/* PLL Setting */ +0xd005, +0xd130, +0xd205, +0xd320, +0xd085, +0xd085, +0xd085, +0xd095, + +0x0348, +/* MIPI TX Setting */ +0x101c, +0x1100, +0x1200, +0x1400, +0x1604, +0x1700, +0x1880, +0x1900, +0x1aa0, +/*0x1b0d,*/ +0x1c02, +0x1d0e, +0x1e07, +0x1f08, + +0x2200, +0x2301, +0x241e, +0x2500, +0x2600, +0x2708, +0x2800, +/*0x2b40,*/ + +0x3005, +0x3100, + +0x3207, +0x3309, +0x3401, +0x3501, + +0x0300, +0x0101, +}; + +static const sr130pc20_regset_t sr130pc20_stop_stream[] = { +0x0300, +0x0101, +}; + +static const sr130pc20_regset_t SR130PC20_Preview_Mode[] = +{ +0x0300, +0x0101,/*sleep*/ + +0xd005,/*Pll Off*/ + +0x0320, +0x101c,/*AE off (0x0c:60Hz 0x1c:50Hz)*/ +0x0322, +0x107d,/*AWB off*/ + +0x0300, +0x1011, +/* 0x1190, *//*0x91 : mirror mode*/ + +/* page 11 yc_lpf */ +0x0311, +0x5b00,/*don't touch*/ + +/* PAGE 12 YC_LPF */ +0x0312, +0x200f, +0x210f, + +/*preview DPC*/ +0xd217, +0xd50f, +0xd7ff, + + +/* PAGE13 Sharpness 1D/2D */ +0x0313, +0x10c4, +0x80c0, + +/* PAGE 18 START*/ +0x0318, +0x1443, /*83*/ + +0x0320, +0x109c, /*AE ON (0x8c:60Hz 0x9c:50Hz)*/ +0x0322, +0x10fd, /*AWB ON*/ + +0x0300, /*Page 0 PLL on*/ +0xd005, +0xd130, +0xd205, +0xd320, +0xd085, +0xd085, +0xd085, +0xd095, + +/* MIPI TX Setting */ +0x0348, +0x101c, +0x1100, +0x1200, +0x1400, +0x1604, +0x1700, +0x1880, +0x1900, +0x1aa0, +/*0x1b0d,*/ +0x1c02, +/*0x1d09,*/ +0x1d0e, +0x1e07, +0x1f08, +/*0x2000,*/ + +0x2200, +0x2301, +0x241e, +0x2500, +0x2600, +0x2708, +0x2800, +/*0x2a06,*/ +/*0x2b40,*/ +/*0x2c04,*/ +/*0x2db0,*/ + +0x3005, +0x3100, + +0x3207, +0x3309, +0x3401, +0x3501, +/*0x3601,*/ +/*0x3707,*/ +/*0x3802,*/ +/*0x3902,*/ + +0x0300, +0x0100, + +}; + +static const sr130pc20_regset_t SR130PC20_Capture_Mode[] = +{ +0x0300, +0x0101,/*sleep*/ + +0xd005,/*Pll off*/ + +0x0322, +0x107d,/*AWB off*/ + +0x0300, +0x1000, +/* 0x1190, */ + +0x0302, +0x2faa, + +0x0311, +0x5b00,/*don't touch*/ + +0x0312, +0x200f, +0x210f, + +/*preview DPC*/ +0xd267, +0xd502, +0xd718, + +0x0313, +0x10c5, +0x80c1,/*Sharpness 2D On[0xc1] Off[0xc0]*/ + +/* PAGE 18 START*/ +0x0318, +0x1400, + +0x0300, +0xd005,/*pll on*/ +0xd130, +0xd201, +0xd320, +0xd085, +0xd085, +0xd085, +0xd095, + +0x0348, +/* MIPI TX Setting */ +0x101c, +0x1100, +0x1200, +0x1400, +0x1604, +0x1700, +0x1880, +0x1900, +0x1aa0, +/*0x1b0d,*/ +0x1c02, +0x1d0d, /* 0c:90ns , 0b:110ns */ +0x1e0f, +0x1f0a, +/*0x2000,*/ + +0x2200, +0x2301, +0x241e, +0x2500, +0x2600, +0x2708, +0x2800, +/*0x2a06,*/ +/*0x2b40,*/ +/*0x2c04,*/ +/*0x2db0,*/ + +0x300a, +0x3100, + +0x320d, +0x330b, +0x3402, +0x3504, +0x3601, +0x3709, +/*0x3802,*/ +/*0x3902,*/ + +0x0300, +0x0100,/*sleep off*/ + +}; + +static const sr130pc20_regset_t SR130PC20_Lowlux_Night_Capture_Mode[] = +{ +0x0300, +0x0101,/*sleep*/ + +0xd005,/*Pll off*/ + +0x0322, +0x107d,/*AWB off*/ + +0x0300, +0x1000, +/* 0x1190, */ + +0x0302, +0x2faa, + +0x0311, +0x5b00,/*don't touch*/ + +0x0312, +0x200f, +0x210f, + +/*preview DPC*/ +0xd267, +0xd502, +0xd718, + +0x0313, +0x10c5, +0x80c1,/*Sharpness 2D On[0xc1] Off[0xc0]*/ + +/* PAGE 18 START*/ +0x0318, +0x1400, + +0x0300, +0xd005,/*pll on*/ +0xd130, +0xd201, +0xd320, +0xd085, +0xd085, +0xd085, +0xd095, + +0x0348, +/* MIPI TX Setting */ +0x101c, +0x1100, +0x1200, +0x1400, +0x1604, +0x1700, +0x1880, +0x1900, +0x1aa0, +/*0x1b0d,*/ +0x1c02, +0x1d0d, /* 0c:90ns , 0b:110ns */ +0x1e0f, +0x1f0a, +/*0x2000,*/ + +0x2200, +0x2301, +0x241e, +0x2500, +0x2600, +0x2708, +0x2800, +/*0x2a06,*/ +/*0x2b40,*/ +/*0x2c04,*/ +/*0x2db0,*/ + +0x300a, +0x3100, + +0x320d, +0x330b, +0x3402, +0x3504, +0x3601, +0x3709, +/*0x3802,*/ +/*0x3902,*/ + +0x0300, +0x0100,/*sleep off*/ + +0xff03, +}; + +static const sr130pc20_regset_t sr130pc20_Effect_Sketch[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Effect_Pastel[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Effect_Black_White[] = +{ +0x0310, +0x1103, +0x1233, +0x1302, +0x4080, +0x4480, +0x4580, +}; + +static const sr130pc20_regset_t SR130PC20_Effect_Negative[] = +{ +0x0310, +0x1103, +0x1238, +0x1302, +0x4080, +0x4480, +0x4580, +}; + +static const sr130pc20_regset_t sr130pc20_Effect_Solar[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Effect_Normal[] = +{ +0x0310, +0x1103, +0x1230, +0x1302, +0x4080, +0x4480, +0x4580, +}; + +static const sr130pc20_regset_t sr130pc20_Effect_Sepia[] = +{ +0x0310, +0x1103, +0x1233, +0x1302, +0x4080, +0x4470, +0x4598, +}; + +static const sr130pc20_regset_t sr130pc20_Metering_Center[] = +{ +0x0321, +0x2011, +0x2111, +0x2211, +0x2311, +0x2412, +0x2522, +0x2622, +0x2721, +0x2812, +0x2922, +0x2a22, +0x2b21, +0x2c12, +0x2d23, +0x2e32, +0x2f21, +0x3012, +0x3123, +0x3232, +0x3321, +0x3412, +0x3522, +0x3622, +0x3721, +0x3812, +0x3922, +0x3a22, +0x3b21, +0x3c11, +0x3d11, +0x3e11, +0x3f11, +}; + +static const sr130pc20_regset_t sr130pc20_Metering_Matrix[] = +{ +0x0321, +0x2011, +0x2111, +0x2211, +0x2311, +0x2411, +0x2511, +0x2611, +0x2711, +0x2811, +0x2911, +0x2a11, +0x2b11, +0x2c11, +0x2d11, +0x2e11, +0x2f11, +0x3011, +0x3111, +0x3211, +0x3311, +0x3411, +0x3511, +0x3611, +0x3711, +0x3811, +0x3911, +0x3a11, +0x3b11, +0x3c11, +0x3d11, +0x3e11, +0x3f11, +}; + +static const sr130pc20_regset_t sr130pc20_Metering_Spot[] = +{ +0x0321, +0x2011, +0x2111, +0x2211, +0x2311, +0x2411, +0x2511, +0x2611, +0x2711, +0x2811, +0x2911, +0x2a11, +0x2b11, +0x2c11, +0x2d13, +0x2e31, +0x2f11, +0x3011, +0x3113, +0x3231, +0x3311, +0x3411, +0x3511, +0x3611, +0x3711, +0x3811, +0x3911, +0x3a11, +0x3b11, +0x3c11, +0x3d11, +0x3e11, +0x3f11, +}; + +static const sr130pc20_regset_t SR130PC20_ExpSetting_Default[] = +{ +0x0310, +0x4080, +}; + +static const sr130pc20_regset_t SR130PC20_ExpSetting_M1Step[] = +{ +0x0310, +0x4090, +}; + +static const sr130pc20_regset_t SR130PC20_ExpSetting_M2Step[] = +{ +0x0310, +0x40A0, +}; + +static const sr130pc20_regset_t SR130PC20_ExpSetting_M3Step[] = +{ +0x0310, +0x40B0, +}; + +static const sr130pc20_regset_t SR130PC20_ExpSetting_M4Step[] = +{ +0x0310, +0x40d0, +}; + +static const sr130pc20_regset_t SR130PC20_ExpSetting_P1Step[] = +{ +0x0310, +0x4010, +}; + +static const sr130pc20_regset_t SR130PC20_ExpSetting_P2Step[] = +{ +0x0310, +0x4020, +}; + +static const sr130pc20_regset_t SR130PC20_ExpSetting_P3Step[] = +{ +0x0310, +0x4030, +}; + +static const sr130pc20_regset_t SR130PC20_ExpSetting_P4Step[] = +{ +0x0310, +0x4050, +}; + +static const sr130pc20_regset_t sr130pc20_ISO_50[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_ISO_100[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_ISO_200[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_ISO_400[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_ISO_Auto[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Default[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Landscape[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Sports[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Party_Indoor[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Beach_Snow[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Sunset[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Duskdawn[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Candle_Light[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Fall_Color[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Portrait[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Nightshot[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Fireworks[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Text[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Backlight[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Sharpness_Default[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_WB_Auto[] = +{ +0x0322, +0x106b, +0x112e, +0x8038, +0x8120, +0x8238, +0x8356, +0x8420, +0x8552, +0x8620, +0x10eb, +}; + +static const sr130pc20_regset_t sr130pc20_WB_Cloudy[] = +{ +0x0322, +0x106b, +0x112c, +0x8050, +0x8120, +0x8228, +0x8352, +0x844c, +0x852c, +0x8622, +0x10eb, +}; + +static const sr130pc20_regset_t sr130pc20_WB_Sunny[] = +{ +0x0322, +0x106b, +0x112c, +0x8038, +0x8120, +0x8235, +0x833b, +0x8434, +0x8538, +0x8631, +0x10eb, +}; + +static const sr130pc20_regset_t sr130pc20_WB_Fluorescent[] = +{ +0x0322, +0x106b, +0x112c, +0x8037, +0x8120, +0x8248, +0x8339, +0x8434, +0x854a, +0x8645, +0x10eb, +}; + +static const sr130pc20_regset_t sr130pc20_WB_Tungsten[] = +{ +0x0322, +0x106b, +0x112c, +0x8021, +0x8120, +0x824f, +0x8327, +0x841b, +0x8559, +0x8650, +0x10eb, +}; + +static const sr130pc20_regset_t sr130pc20_640_480_Preview[] = { +0x0300, +0x0101, + +0x0300, +0x1011, + +0x0318, +0x1000, + +0x0348, +0x3005, +0x3100, + +0x0300, +0x0100, + +0xff0a, +}; + +static const sr130pc20_regset_t sr130pc20_352_288_Preview[] = { +0x0300, +0x0101, +0x0300, +0x1011, + +0x0318, +0x1007, +0x1200, +0x2003, +0x2100, +0x2201, +0x2320, +0x2400, +0x2520, +0x2600, +0x2700, +0x2802, +0x29e0, +0x2a01, +0x2b20, +0x2c0d, +0x2d55, +0x2e0d, +0x2f55, +0x3051, + +0x0348, +0x3002, +0x31c0, + +0x0300, +0x0100, + +0xff28, +}; + +static const sr130pc20_regset_t sr130pc20_320_240_Preview[] = { +0x0300, +0x0101, + +0x0300, +0x1023, + +0x0318, +0x1000, + +0x0348, +0x3002, +0x3180, + +0x0300, +0x0100, + +0xff28, +}; + +static const sr130pc20_regset_t sr130pc20_176_144_Preview[] = { +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_1280_960_Capture[] = { +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_960_720_Capture[] = { +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_VGA_Capture[] = { +0xff00 +}; + +static const sr130pc20_regset_t sr130pc20_fps_auto[] = { +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_fps_7fix[] = { +0x0300, +0x0101, + +0x1190, + +0x4200, +0x4314, + +0x0320, +0x101C, + +0x0322, +0x107d, + +0x0320, +0x2af3, +0x2bf5, + +0x8301, /*EXP Normal 33.33 fps */ +0x845f, +0x8590, + +0x8806, /*EXP Max(120Hz) 7.50 fps */ +0x8968, +0x8aa0, + +0xa506, /*EXP Max(100Hz) 7.14 fps */ +0xa668, +0xa7a0, + +0x9106, /*EXP Fix 7.00 fps*/ +0x9289, +0x9370, + +0x0320, +0x109C, + +0x0322, +0x10fd, + +0x0300, +0x1194, + +0x0300, +0x0101, +}; + +static const sr130pc20_regset_t sr130pc20_fps_15fix[] = { +0x0300, +0x0101, + +0x1190, + +0x4200, +0x4314, + +0x0320, +0x101C, + +0x0322, +0x107d, + +0x0310, /*page 10*/ +0x6007, +0x6380, /*auto decresment on AG th*/ + +0x0316, +0x7007, +0x711a, +0x722d, +0x7346, +0x746a, +0x7586, +0x769c, +0x77ad, +0x78bc, +0x79c9, +0x7ad4, +0x7bde, +0x7ce4, +0x7deb, +0x7ef1, +0x7ff5, +0x80f9, +0x81fd, +0x82ff, + +0x0322, +0x8f5d, +0x905a, +0x9156, +0x9250, +0x9348, +0x943f, + +0x0320, +0x2afd, +0x2bf8, + +0x8301, /*EXP Normal 33.33 fps */ +0x845f, +0x8590, + +0x8802, /*EXP Max(120Hz) 17.14 fps */ +0x89bf, +0x8a20, + +0xa502, /*EXP Max(100Hz) 16.67 fps */ +0xa6bf, +0xa720, + +0x9103, /*EXP Fix 15.00 fps*/ +0x920d, +0x9340, + +0x0320, +0x109C, + +0x0322, +0x10fd, + +0x0300, +0x1194, + +0x0300, +0x0101, +}; + +static const sr130pc20_regset_t sr130pc20_fps_25fix[] = { +0x0300, +0x0101, + +0x1190, + +0x4200, +0x4362, + +0x0320, +0x101C, + +0x0322, +0x107d, + +0x0310, /*page 10*/ + +0x410a, +0x6007, +0x6380, /*auto decresment on AG th*/ + +0x0316, +0x7007, +0x711a, +0x722d, +0x7346, +0x746a, +0x7586, +0x769c, +0x77ad, +0x78bc, +0x79c9, +0x7ad4, +0x7bde, +0x7ce4, +0x7deb, +0x7ef1, +0x7ff5, +0x80f9, +0x81fd, +0x82ff, + +0x0322, +0x8f5d, +0x905a, +0x9156, +0x9250, +0x9348, +0x943f, + +0x0320, +0x2afd, +0x2bf8, + +0x8301, /*EXP Normal 33.33 fps */ +0x845d, +0x8538, + +0x8801, /*EXP Max(120Hz) 40.00 fps */ +0x895f, +0x8a90, + +0xa501, /*EXP Max(100Hz) 25.xx fps */ +0xa6d1, +0xa7a0, + +0x8b74, /*EXP100 */ +0x8c68, +0x8d60, /*EXP120 */ +0x8ee0, + +0x9101, /*EXP Fix 25.00 fps*/ +0x92d4, +0x93c0, + +0x0320, +0x109C, + +0x0322, +0x10fd, + +0x0300, +0x1194, + +0x0300, +0x0101, +}; + +static const sr130pc20_regset_t sr130pc20_fps_30fix[] = +{ +/* sensor limitation, use 25fps */ +0xff00, +}; + +#endif /* __SR130PC20_REGS_H__ */ -- cgit v1.1 From 2a6649bf6aa50c44a05fc02e1efb8b788c58e82b Mon Sep 17 00:00:00 2001 From: sakindia123 Date: Sun, 11 Aug 2013 14:20:37 +0200 Subject: Samsung i9300 Update 11 Change-Id: I7f6dbdd97e3ed66634bf123d43224a79524c04e9 --- drivers/media/video/samsung/fimc/fimc_dev.c | 54 ++++++++++++++++++++ drivers/media/video/samsung/fimc/fimc_dev_u1.c | 54 ++++++++++++++++++++ drivers/media/video/samsung/jpeg/jpeg_dev.c | 7 +++ .../video/samsung/mali/arch-orion-m400/config.h | 2 +- drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c | 59 ++++++++++++++-------- 5 files changed, 155 insertions(+), 21 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/samsung/fimc/fimc_dev.c b/drivers/media/video/samsung/fimc/fimc_dev.c index 1ed79dd..4822587 100644 --- a/drivers/media/video/samsung/fimc/fimc_dev.c +++ b/drivers/media/video/samsung/fimc/fimc_dev.c @@ -898,6 +898,50 @@ static struct vm_operations_struct fimc_mmap_ops = { }; static inline +int fimc_mmap_own_mem(struct file *filp, struct vm_area_struct *vma) +{ + struct fimc_prv_data *prv_data = + (struct fimc_prv_data *)filp->private_data; + struct fimc_control *ctrl = prv_data->ctrl; + u32 start_phy_addr = 0; + u32 size = vma->vm_end - vma->vm_start; + u32 pfn, idx = vma->vm_pgoff; + u32 buf_length = 0; + + buf_length = ctrl->mem.size; + if (size > PAGE_ALIGN(buf_length)) { + fimc_err("Requested mmap size is too big\n"); + return -EINVAL; + } + + start_phy_addr = ctrl->mem.base + (vma->vm_pgoff << PAGE_SHIFT); + + if (!cma_is_registered_region(start_phy_addr, size)) { + pr_err("[%s] handling non-cma region (%#x@%#x)is prohibited\n", + __func__, buf_length, start_phy_addr); + return -EINVAL; + } + + /* only supports non-cached mmap */ + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + vma->vm_flags |= VM_RESERVED; + + if ((vma->vm_flags & VM_WRITE) && !(vma->vm_flags & VM_SHARED)) { + fimc_err("writable mapping must be shared\n"); + return -EINVAL; + } + + pfn = __phys_to_pfn(start_phy_addr); + + if (remap_pfn_range(vma, vma->vm_start, pfn, size, vma->vm_page_prot)) { + fimc_err("mmap fail\n"); + return -EINVAL; + } + + return 0; +} + +static inline int fimc_mmap_out_src(struct file *filp, struct vm_area_struct *vma) { struct fimc_prv_data *prv_data = @@ -981,10 +1025,14 @@ static inline int fimc_mmap_out(struct file *filp, struct vm_area_struct *vma) int idx = ctrl->out->ctx[ctx_id].overlay.req_idx; int ret = -1; +#if 0 if (idx >= 0) ret = fimc_mmap_out_dst(filp, vma, idx); else if (idx == FIMC_MMAP_IDX) ret = fimc_mmap_out_src(filp, vma); +#else + ret = fimc_mmap_own_mem(filp, vma); +#endif return ret; } @@ -1002,6 +1050,12 @@ static inline int fimc_mmap_cap(struct file *filp, struct vm_area_struct *vma) vma->vm_flags |= VM_RESERVED; + if (!cma_is_registered_region(ctrl->cap->bufs[idx].base[0], size)) { + pr_err("[%s] handling non-cma region (%#x@%#x)is prohibited\n", + __func__, size, ctrl->cap->bufs[idx].base[0]); + return -EINVAL; + } + /* * page frame number of the address for a source frame * to be stored at. diff --git a/drivers/media/video/samsung/fimc/fimc_dev_u1.c b/drivers/media/video/samsung/fimc/fimc_dev_u1.c index 811ac96..52246a1 100644 --- a/drivers/media/video/samsung/fimc/fimc_dev_u1.c +++ b/drivers/media/video/samsung/fimc/fimc_dev_u1.c @@ -745,6 +745,50 @@ static struct vm_operations_struct fimc_mmap_ops = { }; static inline +int fimc_mmap_own_mem(struct file *filp, struct vm_area_struct *vma) +{ + struct fimc_prv_data *prv_data = + (struct fimc_prv_data *)filp->private_data; + struct fimc_control *ctrl = prv_data->ctrl; + u32 start_phy_addr = 0; + u32 size = vma->vm_end - vma->vm_start; + u32 pfn, idx = vma->vm_pgoff; + u32 buf_length = 0; + + buf_length = ctrl->mem.size; + if (size > PAGE_ALIGN(buf_length)) { + fimc_err("Requested mmap size is too big\n"); + return -EINVAL; + } + + start_phy_addr = ctrl->mem.base + (vma->vm_pgoff << PAGE_SHIFT); + + if (!cma_is_registered_region(start_phy_addr, size)) { + pr_err("[%s] handling non-cma region (%#x@%#x)is prohibited\n", + __func__, buf_length, start_phy_addr); + return -EINVAL; + } + + /* only supports non-cached mmap */ + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + vma->vm_flags |= VM_RESERVED; + + if ((vma->vm_flags & VM_WRITE) && !(vma->vm_flags & VM_SHARED)) { + fimc_err("writable mapping must be shared\n"); + return -EINVAL; + } + + pfn = __phys_to_pfn(start_phy_addr); + + if (remap_pfn_range(vma, vma->vm_start, pfn, size, vma->vm_page_prot)) { + fimc_err("mmap fail\n"); + return -EINVAL; + } + + return 0; +} + +static inline int fimc_mmap_out_src(struct file *filp, struct vm_area_struct *vma) { struct fimc_prv_data *prv_data = @@ -829,10 +873,14 @@ static inline int fimc_mmap_out(struct file *filp, struct vm_area_struct *vma) int idx = ctrl->out->ctx[ctx_id].overlay.req_idx; int ret = -1; +#if 0 if (idx >= 0) ret = fimc_mmap_out_dst(filp, vma, idx); else if (idx == FIMC_MMAP_IDX) ret = fimc_mmap_out_src(filp, vma); +#else + ret = fimc_mmap_own_mem(filp, vma); +#endif return ret; } @@ -849,6 +897,12 @@ static inline int fimc_mmap_cap(struct file *filp, struct vm_area_struct *vma) vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); vma->vm_flags |= VM_RESERVED; + if (!cma_is_registered_region(ctrl->cap->bufs[idx].base[0], size)) { + pr_err("[%s] handling non-cma region (%#x@%#x)is prohibited\n", + __func__, size, ctrl->cap->bufs[idx].base[0]); + return -EINVAL; + } + /* * page frame number of the address for a source frame * to be stored at. diff --git a/drivers/media/video/samsung/jpeg/jpeg_dev.c b/drivers/media/video/samsung/jpeg/jpeg_dev.c index 4038fd2..6ebcfb6 100644 --- a/drivers/media/video/samsung/jpeg/jpeg_dev.c +++ b/drivers/media/video/samsung/jpeg/jpeg_dev.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -247,6 +248,12 @@ int jpeg_mmap(struct file *filp, struct vm_area_struct *vma) size = vma->vm_end - vma->vm_start; + if (!cma_is_registered_region(jpeg_ctrl->mem.base, size)) { + pr_err("[%s] handling non-cma region (%#x@%#x)is prohibited\n", + __func__, (unsigned int)size, jpeg_ctrl->mem.base); + return -EINVAL; + } + vma->vm_flags |= VM_RESERVED | VM_IO; vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); diff --git a/drivers/media/video/samsung/mali/arch-orion-m400/config.h b/drivers/media/video/samsung/mali/arch-orion-m400/config.h index 5c4d79d..73502a2 100644 --- a/drivers/media/video/samsung/mali/arch-orion-m400/config.h +++ b/drivers/media/video/samsung/mali/arch-orion-m400/config.h @@ -130,7 +130,7 @@ static _mali_osk_resource_t arch_configuration [] = #endif/* if USING_OS_MEMORY*/ { .type = MEM_VALIDATION, - .description = "memory validation", + .description = "Framebuffer Memory", .base = MEM_BASE_ADDR, .size = MEM_TOTAL_SIZE, .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE diff --git a/drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c b/drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c index 3fa6e55..228be02 100644 --- a/drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c +++ b/drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c @@ -27,6 +27,8 @@ #include #endif +#include + #ifdef CONFIG_UMP_VCM_ALLOC #include "ump_kernel_interface.h" #endif @@ -881,13 +883,24 @@ long s5p_tvout_tvif_ioctl( goto end_tvif_ioctl; } for (i = 0; i < S5PTV_VP_BUFF_CNT; i++) { - s5ptv_vp_buff.vp_buffs[i].phy_base = buffs[i].phy_base; - s5ptv_vp_buff.vp_buffs[i].vir_base = - (unsigned int)phys_to_virt(buffs[i].phy_base); - s5ptv_vp_buff.vp_buffs[i].size = buffs[i].size; - tvout_dbg("s5ptv_vp_buff phy_base = 0x%x, vir_base = 0x%8x\n", - s5ptv_vp_buff.vp_buffs[i].phy_base, - s5ptv_vp_buff.vp_buffs[i].vir_base); + if (cma_is_registered_region(buffs[i].phy_base, + buffs[i].size)) { + s5ptv_vp_buff.vp_buffs[i].phy_base = + buffs[i].phy_base; + s5ptv_vp_buff.vp_buffs[i].vir_base = + (unsigned int)phys_to_virt(buffs[i].phy_base); + s5ptv_vp_buff.vp_buffs[i].size = buffs[i].size; + tvout_dbg("s5ptv_vp_buff phy_base = 0x%x, " + "vir_base = 0x%8x\n", + s5ptv_vp_buff.vp_buffs[i].phy_base, + s5ptv_vp_buff.vp_buffs[i].vir_base); + } else { + s5ptv_vp_buff.vp_buffs[i].phy_base = 0; + s5ptv_vp_buff.vp_buffs[i].vir_base = 0; + printk(KERN_ERR "Buffer for VP is not CMA region\n"); + ret = -EINVAL; + goto end_tvif_ioctl; + } } goto end_tvif_ioctl; } @@ -1134,6 +1147,25 @@ static int s5p_tvout_vo_s_fmt_type_private( pix_fmt->height, color, field); #else if (pix_fmt->priv) { + if (pix_fmt->pixelformat == V4L2_PIX_FMT_NV12T + || pix_fmt->pixelformat == V4L2_PIX_FMT_NV21T) { + y_size = ALIGN(ALIGN(pix_fmt->width, 128) * + ALIGN(pix_fmt->height, 32), SZ_8K); + cbcr_size = ALIGN(ALIGN(pix_fmt->width, 128) * + ALIGN(pix_fmt->height >> 1, 32), SZ_8K); + } else { + y_size = pix_fmt->width * pix_fmt->height; + cbcr_size = pix_fmt->width * (pix_fmt->height >> 1); + } + if (!cma_is_registered_region((unsigned int)vparam.base_y, + y_size) || + !cma_is_registered_region((unsigned int)vparam.base_c, + cbcr_size)) { + printk(KERN_ERR "Source image for VP is not" + "CMA region\n"); + goto error_on_s_fmt_type_private; + } + copy_buff_idx = s5ptv_vp_buff. copy_buff_idxs[s5ptv_vp_buff.curr_copy_idx]; @@ -1144,19 +1176,6 @@ static int s5p_tvout_vo_s_fmt_type_private( (u32) vparam.base_y, (u32) vparam.base_c, pix_fmt->width, pix_fmt->height, color, field); } else { - if (pix_fmt->pixelformat == - V4L2_PIX_FMT_NV12T - || pix_fmt->pixelformat == V4L2_PIX_FMT_NV21T) { - y_size = ALIGN(ALIGN(pix_fmt->width, 128) * - ALIGN(pix_fmt->height, 32), SZ_8K); - cbcr_size = ALIGN(ALIGN(pix_fmt->width, 128) * - ALIGN(pix_fmt->height >> 1, 32), SZ_8K); - } else { - y_size = pix_fmt->width * pix_fmt->height; - cbcr_size = - pix_fmt->width * (pix_fmt->height >> 1); - } - src_vir_y_addr = (unsigned int)phys_to_virt( (unsigned long)vparam.base_y); src_vir_cb_addr = (unsigned int)phys_to_virt( -- cgit v1.1 From 74bcc029c6ab942f252477a74102877f7d093388 Mon Sep 17 00:00:00 2001 From: mcampbellsmith Date: Wed, 20 Nov 2013 22:34:44 +1100 Subject: mali: bulk import of r3p2-01rel3 drivers from i9300-update12 Courtesy of a similar commit from OMNI ROM. Requires updated mali blobs Change-Id: I9ee55b653b57b7c390f8e0e8cd4fc068f1c751c3 --- drivers/media/video/samsung/Kconfig | 2 - drivers/media/video/samsung/Makefile | 2 - drivers/media/video/samsung/mali/Kbuild_module | 295 ---- drivers/media/video/samsung/mali/Kconfig | 63 - drivers/media/video/samsung/mali/Kconfig_module | 30 - drivers/media/video/samsung/mali/Makefile | 337 ---- drivers/media/video/samsung/mali/Makefile_module | 97 -- drivers/media/video/samsung/mali/arch | 1 - drivers/media/video/samsung/mali/arch-debug | 1 - .../video/samsung/mali/arch-orion-m400/config.h | 154 -- .../samsung/mali/arch-pb-virtex5-m300/config.h | 85 - .../mali/arch-pb-virtex5-m400-1-direct/config.h | 92 - .../mali/arch-pb-virtex5-m400-1-pmu/config.h | 85 - .../samsung/mali/arch-pb-virtex5-m400-1/config.h | 77 - .../samsung/mali/arch-pb-virtex5-m400-2/config.h | 91 - .../samsung/mali/arch-pb-virtex5-m400-3/config.h | 105 -- .../samsung/mali/arch-pb-virtex5-m400-4/config.h | 119 -- .../video/samsung/mali/arch-pegasus-m400/config.h | 154 -- drivers/media/video/samsung/mali/arch-release | 1 - .../samsung/mali/arch-ve-virtex6-m450-8/config.h | 174 -- .../samsung/mali/common/mali_block_allocator.c | 391 ----- .../samsung/mali/common/mali_block_allocator.h | 18 - .../media/video/samsung/mali/common/mali_cluster.c | 218 --- .../media/video/samsung/mali/common/mali_cluster.h | 44 - .../samsung/mali/common/mali_device_pause_resume.c | 46 - .../samsung/mali/common/mali_device_pause_resume.h | 31 - .../media/video/samsung/mali/common/mali_dlbu.c | 285 ---- .../media/video/samsung/mali/common/mali_dlbu.h | 45 - drivers/media/video/samsung/mali/common/mali_gp.c | 746 -------- drivers/media/video/samsung/mali/common/mali_gp.h | 46 - .../media/video/samsung/mali/common/mali_gp_job.c | 49 - .../media/video/samsung/mali/common/mali_gp_job.h | 131 -- .../video/samsung/mali/common/mali_gp_scheduler.c | 443 ----- .../video/samsung/mali/common/mali_gp_scheduler.h | 30 - .../media/video/samsung/mali/common/mali_group.c | 841 --------- .../media/video/samsung/mali/common/mali_group.h | 146 -- .../media/video/samsung/mali/common/mali_hw_core.c | 46 - .../media/video/samsung/mali/common/mali_hw_core.h | 71 - .../video/samsung/mali/common/mali_kernel_common.h | 183 -- .../video/samsung/mali/common/mali_kernel_core.c | 980 ----------- .../video/samsung/mali/common/mali_kernel_core.h | 39 - .../mali/common/mali_kernel_descriptor_mapping.c | 184 -- .../mali/common/mali_kernel_descriptor_mapping.h | 101 -- .../video/samsung/mali/common/mali_kernel_mem_os.c | 354 ---- .../video/samsung/mali/common/mali_kernel_mem_os.h | 37 - .../mali/common/mali_kernel_memory_engine.c | 376 ---- .../mali/common/mali_kernel_memory_engine.h | 152 -- .../samsung/mali/common/mali_kernel_utilization.c | 218 --- .../samsung/mali/common/mali_kernel_utilization.h | 44 - .../video/samsung/mali/common/mali_kernel_vsync.c | 51 - .../video/samsung/mali/common/mali_l2_cache.c | 414 ----- .../video/samsung/mali/common/mali_l2_cache.h | 43 - .../samsung/mali/common/mali_mem_validation.c | 71 - .../samsung/mali/common/mali_mem_validation.h | 19 - .../media/video/samsung/mali/common/mali_memory.c | 1319 -------------- .../media/video/samsung/mali/common/mali_memory.h | 82 - drivers/media/video/samsung/mali/common/mali_mmu.c | 619 ------- drivers/media/video/samsung/mali/common/mali_mmu.h | 55 - .../samsung/mali/common/mali_mmu_page_directory.c | 475 ------ .../samsung/mali/common/mali_mmu_page_directory.h | 100 -- drivers/media/video/samsung/mali/common/mali_osk.h | 1798 -------------------- .../video/samsung/mali/common/mali_osk_bitops.h | 166 -- .../video/samsung/mali/common/mali_osk_list.h | 184 -- .../video/samsung/mali/common/mali_osk_mali.h | 222 --- .../video/samsung/mali/common/mali_osk_profiling.h | 147 -- drivers/media/video/samsung/mali/common/mali_pm.c | 552 ------ drivers/media/video/samsung/mali/common/mali_pm.h | 56 - drivers/media/video/samsung/mali/common/mali_pmu.c | 199 --- drivers/media/video/samsung/mali/common/mali_pmu.h | 70 - drivers/media/video/samsung/mali/common/mali_pp.c | 710 -------- drivers/media/video/samsung/mali/common/mali_pp.h | 47 - .../media/video/samsung/mali/common/mali_pp_job.c | 95 -- .../media/video/samsung/mali/common/mali_pp_job.h | 273 --- .../video/samsung/mali/common/mali_pp_scheduler.c | 594 ------- .../video/samsung/mali/common/mali_pp_scheduler.h | 38 - .../video/samsung/mali/common/mali_scheduler.c | 37 - .../video/samsung/mali/common/mali_scheduler.h | 21 - .../media/video/samsung/mali/common/mali_session.c | 47 - .../media/video/samsung/mali/common/mali_session.h | 65 - drivers/media/video/samsung/mali/common/mali_ukk.h | 612 ------- .../samsung/mali/common/mali_user_settings_db.c | 88 - .../samsung/mali/common/mali_user_settings_db.h | 40 - .../samsung/mali/include/linux/mali/mali_utgard.h | 28 - .../mali/include/linux/mali/mali_utgard_counters.h | 264 --- .../mali/include/linux/mali/mali_utgard_ioctl.h | 86 - .../linux/mali/mali_utgard_profiling_events.h | 127 -- .../mali/include/linux/mali/mali_utgard_uk_types.h | 1095 ------------ .../mali/linux/license/gpl/mali_kernel_license.h | 31 - .../media/video/samsung/mali/linux/mali_dma_buf.c | 392 ----- .../media/video/samsung/mali/linux/mali_dma_buf.h | 29 - .../video/samsung/mali/linux/mali_kernel_linux.c | 634 ------- .../video/samsung/mali/linux/mali_kernel_linux.h | 43 - .../video/samsung/mali/linux/mali_kernel_pm.c | 268 --- .../video/samsung/mali/linux/mali_kernel_pm.h | 17 - .../video/samsung/mali/linux/mali_kernel_sysfs.c | 1280 -------------- .../video/samsung/mali/linux/mali_kernel_sysfs.h | 35 - .../media/video/samsung/mali/linux/mali_linux_pm.h | 50 - .../samsung/mali/linux/mali_linux_pm_testsuite.h | 32 - .../video/samsung/mali/linux/mali_linux_trace.h | 126 -- .../video/samsung/mali/linux/mali_osk_atomics.c | 55 - .../media/video/samsung/mali/linux/mali_osk_irq.c | 266 --- .../video/samsung/mali/linux/mali_osk_locks.c | 340 ---- .../samsung/mali/linux/mali_osk_low_level_mem.c | 660 ------- .../media/video/samsung/mali/linux/mali_osk_mali.c | 34 - .../media/video/samsung/mali/linux/mali_osk_math.c | 22 - .../video/samsung/mali/linux/mali_osk_memory.c | 61 - .../media/video/samsung/mali/linux/mali_osk_misc.c | 64 - .../samsung/mali/linux/mali_osk_notification.c | 189 -- .../media/video/samsung/mali/linux/mali_osk_pm.c | 83 - .../samsung/mali/linux/mali_osk_profiling_gator.c | 261 --- .../mali/linux/mali_osk_profiling_internal.c | 324 ---- .../video/samsung/mali/linux/mali_osk_specific.h | 130 -- .../media/video/samsung/mali/linux/mali_osk_time.c | 51 - .../video/samsung/mali/linux/mali_osk_timers.c | 65 - .../video/samsung/mali/linux/mali_osk_wait_queue.c | 73 - .../samsung/mali/linux/mali_pmu_power_up_down.c | 65 - .../samsung/mali/linux/mali_profiling_events.h | 17 - .../media/video/samsung/mali/linux/mali_uk_types.h | 18 - .../media/video/samsung/mali/linux/mali_ukk_core.c | 104 -- .../media/video/samsung/mali/linux/mali_ukk_gp.c | 113 -- .../media/video/samsung/mali/linux/mali_ukk_mem.c | 259 --- .../media/video/samsung/mali/linux/mali_ukk_pp.c | 88 - .../video/samsung/mali/linux/mali_ukk_profiling.c | 183 -- .../video/samsung/mali/linux/mali_ukk_vsync.c | 41 - .../video/samsung/mali/linux/mali_ukk_wrappers.h | 68 - .../samsung/mali/platform/default/mali_platform.c | 43 - .../video/samsung/mali/platform/mali_platform.h | 153 -- .../mali_platform_pmu_testing/mali_platform.c | 66 - .../mali/platform/orion-m400/mali_platform.c | 656 ------- .../mali/platform/orion-m400/mali_platform_dvfs.c | 448 ----- .../mali/platform/pegasus-m400/mali_platform.c | 801 --------- .../platform/pegasus-m400/mali_platform_dvfs.c | 847 --------- .../media/video/samsung/mali/regs/mali_200_regs.h | 172 -- .../media/video/samsung/mali/regs/mali_gp_regs.h | 214 --- .../mali/timestamp-arm11-cc/mali_timestamp.c | 13 - .../mali/timestamp-arm11-cc/mali_timestamp.h | 48 - .../mali/timestamp-default/mali_timestamp.c | 13 - .../mali/timestamp-default/mali_timestamp.h | 26 - drivers/media/video/samsung/ump/Kconfig | 58 - drivers/media/video/samsung/ump/Kconfig_module | 16 - drivers/media/video/samsung/ump/Makefile | 93 - drivers/media/video/samsung/ump/Makefile.common | 20 - drivers/media/video/samsung/ump/arch | 1 - drivers/media/video/samsung/ump/arch-debug | 1 - .../video/samsung/ump/arch-orion-m400/config.h | 22 - .../video/samsung/ump/arch-pb-virtex5/config.h | 18 - .../video/samsung/ump/arch-pegasus-m400/config.h | 22 - drivers/media/video/samsung/ump/arch-release | 1 - .../video/samsung/ump/common/ump_kernel_api.c | 551 ------ .../video/samsung/ump/common/ump_kernel_common.c | 414 ----- .../video/samsung/ump/common/ump_kernel_common.h | 128 -- .../ump/common/ump_kernel_descriptor_mapping.c | 165 -- .../ump/common/ump_kernel_descriptor_mapping.h | 91 - .../samsung/ump/common/ump_kernel_memory_backend.h | 51 - .../video/samsung/ump/common/ump_kernel_ref_drv.c | 260 --- .../video/samsung/ump/common/ump_kernel_types.h | 53 - drivers/media/video/samsung/ump/common/ump_osk.h | 51 - .../media/video/samsung/ump/common/ump_uk_types.h | 208 --- drivers/media/video/samsung/ump/common/ump_ukk.h | 61 - .../samsung/ump/include/ump_kernel_interface.h | 236 --- .../ump/include/ump_kernel_interface_ref_drv.h | 35 - .../samsung/ump/include/ump_kernel_platform.h | 48 - .../ump/linux/license/gpl/ump_kernel_license.h | 31 - drivers/media/video/samsung/ump/linux/ump_ioctl.h | 61 - .../video/samsung/ump/linux/ump_kernel_linux.c | 492 ------ .../video/samsung/ump/linux/ump_kernel_linux.h | 18 - .../linux/ump_kernel_memory_backend_dedicated.c | 287 ---- .../linux/ump_kernel_memory_backend_dedicated.h | 23 - .../ump/linux/ump_kernel_memory_backend_os.c | 260 --- .../ump/linux/ump_kernel_memory_backend_os.h | 23 - .../ump/linux/ump_kernel_memory_backend_vcm.c | 290 ---- .../ump/linux/ump_kernel_memory_backend_vcm.h | 22 - .../video/samsung/ump/linux/ump_memory_backend.c | 77 - .../video/samsung/ump/linux/ump_osk_atomics.c | 27 - .../samsung/ump/linux/ump_osk_low_level_mem.c | 485 ------ .../media/video/samsung/ump/linux/ump_osk_misc.c | 37 - .../video/samsung/ump/linux/ump_ukk_ref_wrappers.c | 320 ---- .../video/samsung/ump/linux/ump_ukk_ref_wrappers.h | 43 - .../video/samsung/ump/linux/ump_ukk_wrappers.c | 306 ---- .../video/samsung/ump/linux/ump_ukk_wrappers.h | 47 - 180 files changed, 34693 deletions(-) delete mode 100644 drivers/media/video/samsung/mali/Kbuild_module delete mode 100644 drivers/media/video/samsung/mali/Kconfig delete mode 100644 drivers/media/video/samsung/mali/Kconfig_module delete mode 100644 drivers/media/video/samsung/mali/Makefile delete mode 100644 drivers/media/video/samsung/mali/Makefile_module delete mode 120000 drivers/media/video/samsung/mali/arch delete mode 120000 drivers/media/video/samsung/mali/arch-debug delete mode 100644 drivers/media/video/samsung/mali/arch-orion-m400/config.h delete mode 100644 drivers/media/video/samsung/mali/arch-pb-virtex5-m300/config.h delete mode 100644 drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-direct/config.h delete mode 100644 drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-pmu/config.h delete mode 100644 drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1/config.h delete mode 100644 drivers/media/video/samsung/mali/arch-pb-virtex5-m400-2/config.h delete mode 100644 drivers/media/video/samsung/mali/arch-pb-virtex5-m400-3/config.h delete mode 100644 drivers/media/video/samsung/mali/arch-pb-virtex5-m400-4/config.h delete mode 100644 drivers/media/video/samsung/mali/arch-pegasus-m400/config.h delete mode 120000 drivers/media/video/samsung/mali/arch-release delete mode 100644 drivers/media/video/samsung/mali/arch-ve-virtex6-m450-8/config.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_block_allocator.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_block_allocator.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_cluster.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_cluster.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_device_pause_resume.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_device_pause_resume.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_dlbu.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_dlbu.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_gp.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_gp.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_gp_job.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_gp_job.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_gp_scheduler.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_gp_scheduler.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_group.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_group.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_hw_core.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_hw_core.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_common.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_core.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_core.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_mem_os.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_utilization.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_utilization.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_vsync.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_l2_cache.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_l2_cache.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_mem_validation.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_mem_validation.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_memory.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_memory.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_mmu.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_mmu.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_mmu_page_directory.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_mmu_page_directory.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_osk.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_osk_bitops.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_osk_list.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_osk_mali.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_osk_profiling.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_pm.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_pm.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_pmu.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_pmu.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_pp.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_pp.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_pp_job.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_pp_job.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_pp_scheduler.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_pp_scheduler.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_scheduler.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_scheduler.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_session.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_session.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_ukk.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_user_settings_db.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_user_settings_db.h delete mode 100644 drivers/media/video/samsung/mali/include/linux/mali/mali_utgard.h delete mode 100644 drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_counters.h delete mode 100644 drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_ioctl.h delete mode 100644 drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_profiling_events.h delete mode 100644 drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_uk_types.h delete mode 100644 drivers/media/video/samsung/mali/linux/license/gpl/mali_kernel_license.h delete mode 100644 drivers/media/video/samsung/mali/linux/mali_dma_buf.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_dma_buf.h delete mode 100644 drivers/media/video/samsung/mali/linux/mali_kernel_linux.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_kernel_linux.h delete mode 100644 drivers/media/video/samsung/mali/linux/mali_kernel_pm.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_kernel_pm.h delete mode 100644 drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.h delete mode 100644 drivers/media/video/samsung/mali/linux/mali_linux_pm.h delete mode 100644 drivers/media/video/samsung/mali/linux/mali_linux_pm_testsuite.h delete mode 100644 drivers/media/video/samsung/mali/linux/mali_linux_trace.h delete mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_atomics.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_irq.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_locks.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_low_level_mem.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_mali.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_math.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_memory.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_misc.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_notification.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_pm.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_profiling_gator.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_profiling_internal.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_specific.h delete mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_time.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_timers.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_wait_queue.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_pmu_power_up_down.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_profiling_events.h delete mode 100644 drivers/media/video/samsung/mali/linux/mali_uk_types.h delete mode 100644 drivers/media/video/samsung/mali/linux/mali_ukk_core.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_ukk_gp.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_ukk_mem.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_ukk_pp.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_ukk_profiling.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_ukk_vsync.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_ukk_wrappers.h delete mode 100644 drivers/media/video/samsung/mali/platform/default/mali_platform.c delete mode 100644 drivers/media/video/samsung/mali/platform/mali_platform.h delete mode 100644 drivers/media/video/samsung/mali/platform/mali_platform_pmu_testing/mali_platform.c delete mode 100644 drivers/media/video/samsung/mali/platform/orion-m400/mali_platform.c delete mode 100644 drivers/media/video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c delete mode 100644 drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c delete mode 100644 drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c delete mode 100644 drivers/media/video/samsung/mali/regs/mali_200_regs.h delete mode 100644 drivers/media/video/samsung/mali/regs/mali_gp_regs.h delete mode 100644 drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.c delete mode 100644 drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.h delete mode 100644 drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.c delete mode 100644 drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.h delete mode 100644 drivers/media/video/samsung/ump/Kconfig delete mode 100644 drivers/media/video/samsung/ump/Kconfig_module delete mode 100644 drivers/media/video/samsung/ump/Makefile delete mode 100644 drivers/media/video/samsung/ump/Makefile.common delete mode 120000 drivers/media/video/samsung/ump/arch delete mode 120000 drivers/media/video/samsung/ump/arch-debug delete mode 100644 drivers/media/video/samsung/ump/arch-orion-m400/config.h delete mode 100644 drivers/media/video/samsung/ump/arch-pb-virtex5/config.h delete mode 100644 drivers/media/video/samsung/ump/arch-pegasus-m400/config.h delete mode 120000 drivers/media/video/samsung/ump/arch-release delete mode 100644 drivers/media/video/samsung/ump/common/ump_kernel_api.c delete mode 100644 drivers/media/video/samsung/ump/common/ump_kernel_common.c delete mode 100644 drivers/media/video/samsung/ump/common/ump_kernel_common.h delete mode 100644 drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.c delete mode 100644 drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.h delete mode 100644 drivers/media/video/samsung/ump/common/ump_kernel_memory_backend.h delete mode 100644 drivers/media/video/samsung/ump/common/ump_kernel_ref_drv.c delete mode 100644 drivers/media/video/samsung/ump/common/ump_kernel_types.h delete mode 100644 drivers/media/video/samsung/ump/common/ump_osk.h delete mode 100644 drivers/media/video/samsung/ump/common/ump_uk_types.h delete mode 100644 drivers/media/video/samsung/ump/common/ump_ukk.h delete mode 100644 drivers/media/video/samsung/ump/include/ump_kernel_interface.h delete mode 100644 drivers/media/video/samsung/ump/include/ump_kernel_interface_ref_drv.h delete mode 100644 drivers/media/video/samsung/ump/include/ump_kernel_platform.h delete mode 100644 drivers/media/video/samsung/ump/linux/license/gpl/ump_kernel_license.h delete mode 100644 drivers/media/video/samsung/ump/linux/ump_ioctl.h delete mode 100644 drivers/media/video/samsung/ump/linux/ump_kernel_linux.c delete mode 100644 drivers/media/video/samsung/ump/linux/ump_kernel_linux.h delete mode 100644 drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c delete mode 100644 drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.h delete mode 100644 drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c delete mode 100644 drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.h delete mode 100644 drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.c delete mode 100644 drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.h delete mode 100644 drivers/media/video/samsung/ump/linux/ump_memory_backend.c delete mode 100644 drivers/media/video/samsung/ump/linux/ump_osk_atomics.c delete mode 100644 drivers/media/video/samsung/ump/linux/ump_osk_low_level_mem.c delete mode 100644 drivers/media/video/samsung/ump/linux/ump_osk_misc.c delete mode 100644 drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.c delete mode 100644 drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.h delete mode 100644 drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.c delete mode 100644 drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.h (limited to 'drivers/media/video') diff --git a/drivers/media/video/samsung/Kconfig b/drivers/media/video/samsung/Kconfig index 7ae9e6a..4824144 100644 --- a/drivers/media/video/samsung/Kconfig +++ b/drivers/media/video/samsung/Kconfig @@ -17,8 +17,6 @@ if CPU_EXYNOS4210 || CPU_EXYNOS4212 || CPU_EXYNOS4412 source "drivers/media/video/samsung/fimc/Kconfig" source "drivers/media/video/samsung/tvout/Kconfig" source "drivers/media/video/samsung/mfc5x/Kconfig" - source "drivers/media/video/samsung/mali/Kconfig" - source "drivers/media/video/samsung/ump/Kconfig" endif config VIDEO_FIMG2D diff --git a/drivers/media/video/samsung/Makefile b/drivers/media/video/samsung/Makefile index e9905d2..5a46253 100644 --- a/drivers/media/video/samsung/Makefile +++ b/drivers/media/video/samsung/Makefile @@ -12,8 +12,6 @@ obj-$(CONFIG_VIDEO_FIMG2D3X) += fimg2d3x/ obj-$(CONFIG_VIDEO_FIMG2D4X) += fimg2d4x/ endif -obj-$(CONFIG_VIDEO_UMP) += ump/ obj-$(CONFIG_VIDEO_TSI) += tsi/ -obj-$(CONFIG_VIDEO_MALI400MP) += mali/ EXTRA_CFLAGS += -Idrivers/media/video diff --git a/drivers/media/video/samsung/mali/Kbuild_module b/drivers/media/video/samsung/mali/Kbuild_module deleted file mode 100644 index e865954..0000000 --- a/drivers/media/video/samsung/mali/Kbuild_module +++ /dev/null @@ -1,295 +0,0 @@ -# -# Copyright (C) 2010-2011 ARM Limited. All rights reserved. -# -# This program is free software and is provided to you under the terms of the GNU General Public License version 2 -# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. -# -# A copy of the licence is included with the program, and can also be obtained from Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# - -# This file is called by the Linux build system. - -OSKOS=linux - -# set up defaults if not defined by the user -USING_UMP ?= 0 -USING_OS_MEMORY ?= 0 -USING_MALI_PMM_TESTSUITE ?= 0 -OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB ?= 16 -USING_PROFILING ?= 1 -USING_INTERNAL_PROFILING ?= 0 -DISABLE_PP0 ?= 0 -DISABLE_PP1 ?= 0 -DISABLE_PP2 ?= 0 -DISABLE_PP3 ?= 0 -PROFILING_SKIP_PP_JOBS ?= 0 -PROFILING_SKIP_PP_AND_GP_JOBS ?= 0 -PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH ?= 0 -TIMESTAMP ?= default -BUILD ?= debug -TARGET_PLATFORM ?= default -KERNEL_RUNTIME_PM_ENABLED ?= 0 -CONFIG ?= pb-virtex5-m200 -MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP ?= 0 -MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED ?= 0 -MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS ?= 0 - -DEFINES := $(EXTRA_DEFINES) - -# Get path to driver source from Linux build system -DRIVER_DIR=$(src) - -# For customer releases the Linux Device Drivers will be provided as ARM proprietary and GPL releases: -# The ARM proprietary product will only include the license/proprietary directory -# The GPL product will only include the license/gpl directory - -ifeq ($(wildcard $(DRIVER_DIR)/linux/license/gpl/*),) -ccflags-y += -I$(DRIVER_DIR)/linux/license/proprietary -# Disable profiling for proprietary -override USING_PROFILING := 0 -$(warning "USING_PROFILING not supported, disabling.") -else -ccflags-y += -I$(DRIVER_DIR)/linux/license/gpl -endif - - -ifeq ($(USING_PROFILING),1) -ifeq ($(USING_INTERNAL_PROFILING),0) -ifndef CONFIG_TRACEPOINTS -# Should default to gator profiling, but we dont have the kernel feature required, so disable profiling -override USING_PROFILING = 0 -$(warning "CONFIG_TRACEPOINTS required for USING_PROFILING") -endif -endif -endif - -ifeq ($(USING_PROFILING),0) -# make sure user hasnt selected incompatible flags -override USING_INTERNAL_PROFILING = 0 -endif - -MALI_RELEASE_NAME=$(shell cat $(DRIVER_DIR)/.version 2> /dev/null) - -# Check if a Mali Core sub module should be enabled, true or false returned -submodule_enabled = $(shell gcc $(DEFINES) -E $1/arch/config.h | grep type | grep -c $(2)) - -OSKFILES = \ - $(OSKOS)/mali_osk_atomics.c \ - $(OSKOS)/mali_osk_irq.c \ - $(OSKOS)/mali_osk_locks.c \ - $(OSKOS)/mali_osk_wait_queue.c \ - $(OSKOS)/mali_osk_low_level_mem.c \ - $(OSKOS)/mali_osk_math.c \ - $(OSKOS)/mali_osk_memory.c \ - $(OSKOS)/mali_osk_misc.c \ - $(OSKOS)/mali_osk_mali.c \ - $(OSKOS)/mali_osk_notification.c \ - $(OSKOS)/mali_osk_time.c \ - $(OSKOS)/mali_osk_timers.c - -UKKFILES = \ - $(OSKOS)/mali_ukk_mem.c \ - $(OSKOS)/mali_ukk_gp.c \ - $(OSKOS)/mali_ukk_pp.c \ - $(OSKOS)/mali_ukk_core.c - -ifeq ($(USING_PROFILING),1) -UKKFILES += \ - $(OSKOS)/mali_ukk_profiling.c -endif - -ifeq ($(MALI_PLATFORM_FILE),) -MALI_PLATFORM_FILE = platform/default/mali_platform.c -endif - -# Get subversion revision number, fall back to only ${MALI_RELEASE_NAME} if no svn info is available -SVN_REV := $(shell (cd $(DRIVER_DIR); (svnversion | grep -E "^[0-9]+" && svnversion) || git svn info | grep '^Revision: '| sed -e 's/^Revision: //' ) 2>/dev/null ) -ifeq ($(SVN_REV),) -SVN_REV := $(MALI_RELEASE_NAME) -else -SVN_REV := $(MALI_RELEASE_NAME)-r$(SVN_REV) -endif - -# Validate selected config -ifneq ($(shell [ -d $(DRIVER_DIR)/arch-$(CONFIG) ] && [ -f $(DRIVER_DIR)/arch-$(CONFIG)/config.h ] && echo "OK"), OK) -$(warning Current directory is $(shell pwd)) -$(error No configuration found for config $(CONFIG). Check that arch-$(CONFIG)/config.h exists) -else -# Link arch to the selected arch-config directory -$(shell [ -L $(DRIVER_DIR)/arch ] && rm $(DRIVER_DIR)/arch) -$(shell ln -sf arch-$(CONFIG) $(DRIVER_DIR)/arch) -$(shell touch $(DRIVER_DIR)/arch/config.h) -endif - -# Set up our defines, which will be passed to gcc -DEFINES += -DUSING_OS_MEMORY=$(USING_OS_MEMORY) -DEFINES += -DUSING_MMU=1 -DEFINES += -DUSING_UMP=$(USING_UMP) -DEFINES += -D_MALI_OSK_SPECIFIC_INDIRECT_MMAP -DEFINES += -DMALI_INTERNAL_TIMELINE_PROFILING_ENABLED=$(USING_INTERNAL_PROFILING) -DEFINES += -DDISABLE_PP0=$(DISABLE_PP0) -DEFINES += -DDISABLE_PP1=$(DISABLE_PP1) -DEFINES += -DDISABLE_PP2=$(DISABLE_PP2) -DEFINES += -DDISABLE_PP3=$(DISABLE_PP3) -DEFINES += -DPROFILING_SKIP_PP_JOBS=$(PROFILING_SKIP_PP_JOBS) -DEFINES += -DPROFILING_SKIP_PP_AND_GP_JOBS=$(PROFILING_SKIP_PP_AND_GP_JOBS) -DEFINES += -DPROFILING_PRINT_L2_HITRATE_ON_GP_FINISH=$(PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH) - -DEFINES += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP) -DEFINES += -DMALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED=$(MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED) -DEFINES += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS) -DEFINES += -DMALI_TIMELINE_PROFILING_ENABLED=$(USING_PROFILING) -DEFINES += -DMALI_POWER_MGMT_TEST_SUITE=$(USING_MALI_PMM_TESTSUITE) -ifeq ($(shell test $(SUBLEVEL) -gt 32 -a $(PATCHLEVEL) = 6 -a $(VERSION) = 2 -o $(VERSION) -gt 2 && echo "OK"),OK) -# MALI_STATE_TRACKING is only supported on Linux kernels from version 2.6.32. -DEFINES += -DMALI_STATE_TRACKING=1 -else -DEFINES += -DMALI_STATE_TRACKING=0 -endif -DEFINES += -DMALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=$(OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB) - -MALI_PLATFORM_FILE = platform/$(TARGET_PLATFORM)/mali_platform.c - - -ifdef CONFIG_PM -ifdef CONFIG_PM_RUNTIME - KERNEL_RUNTIME_PM_ENABLED = 1 -endif -endif - -DEFINES += -DMALI_PMM_RUNTIME_JOB_CONTROL_ON=$(KERNEL_RUNTIME_PM_ENABLED) - -ifeq ($(BUILD), debug) -DEFINES += -DDEBUG -endif -DEFINES += -DSVN_REV=$(SVN_REV) -DEFINES += -DSVN_REV_STRING=\"$(SVN_REV)\" - -# Linux has its own mmap cleanup handlers (see mali_kernel_memory.c) -DEFINES += -DMALI_UKK_HAS_IMPLICIT_MMAP_CLEANUP - -ifeq ($(USING_UMP),1) - DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER=1 - ccflags-y += -I$(DRIVER_DIR)/../../ump/include/ump -else - DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER=0 -endif - -# Use our defines when compiling -ccflags-y += $(DEFINES) -I$(DRIVER_DIR) -I$(DRIVER_DIR)/include -I$(DRIVER_DIR)/common -I$(DRIVER_DIR)/linux -I$(DRIVER_DIR)/platform - -# Source files which always are included in a build -SRC = \ - common/mali_kernel_core.c \ - linux/mali_kernel_linux.c \ - common/mali_kernel_descriptor_mapping.c \ - common/mali_session.c \ - common/mali_device_pause_resume.c \ - common/mali_kernel_vsync.c \ - linux/mali_ukk_vsync.c \ - linux/mali_kernel_sysfs.c \ - common/mali_mmu.c \ - common/mali_mmu_page_directory.c \ - common/mali_memory.c \ - common/mali_kernel_memory_engine.c \ - common/mali_block_allocator.c \ - common/mali_kernel_mem_os.c \ - common/mali_mem_validation.c \ - common/mali_hw_core.c \ - common/mali_gp.c \ - common/mali_pp.c \ - common/mali_pp_job.c \ - common/mali_gp_job.c \ - common/mali_scheduler.c \ - common/mali_gp_scheduler.c \ - common/mali_pp_scheduler.c \ - common/mali_cluster.c \ - common/mali_group.c \ - common/mali_dlbu.c \ - common/mali_pm.c \ - common/mali_pmu.c \ - common/mali_user_settings_db.c \ - $(OSKOS)/mali_osk_pm.c \ - linux/mali_kernel_pm.c \ - linux/mali_pmu_power_up_down.c \ - $(MALI_PLATFORM_FILE) \ - $(OSKFILES) \ - $(UKKFILES) \ - __malidrv_build_info.c - -# Selecting files to compile by parsing the config file - -ifeq ($(USING_INTERNAL_PROFILING),1) -PROFILING_BACKEND_SOURCES = \ - linux/mali_osk_profiling_internal.c \ - timestamp-$(TIMESTAMP)/mali_timestamp.c -ccflags-y += -I$(DRIVER_DIR)/timestamp-$(TIMESTAMP) -else -ifeq ($(USING_PROFILING),1) -PROFILING_BACKEND_SOURCES = \ - linux/mali_osk_profiling_gator.c -endif -endif - -# Add the profiling sources -SRC += $(PROFILING_BACKEND_SOURCES) - -ifeq ($(USING_MALI_PMM_TESTSUITE),1) -ccflags-y += -I$(DRIVER_DIR)/platform/mali_pmu_testing -endif - -mali-$(CONFIG_MALI400_GPU_UTILIZATION) += common/mali_kernel_utilization.o -mali-$(CONFIG_DMA_SHARED_BUFFER) += linux/mali_dma_buf.o - -ifneq ($(call submodule_enabled, $(DRIVER_DIR), MALI400PP),0) - # Mali-400 PP in use - ccflags-y += -DUSING_MALI400 -endif - -ifneq ($(call submodule_enabled, $(DRIVER_DIR), MALI300PP),0) - # Mali-400 PP in use - ccflags-y += -DUSING_MALI400 -endif - -ifneq ($(call submodule_enabled, $(DRIVER_DIR), MALI200),0) - # Mali200 in use - ccflags-y += -DUSING_MALI200 -endif - -# Always build in support for Mali L2 cache -SRC += common/mali_l2_cache.c - -# Tell the Linux build system to enable building of our .c files -mali-y += $(SRC:.c=.o) -# Tell the Linux build system from which .o file to create the kernel module -obj-$(CONFIG_MALI400) := mali.o - - -VERSION_STRINGS := -VERSION_STRINGS += CONFIG=$(CONFIG) -VERSION_STRINGS += USING_OS_MEMORY=$(USING_OS_MEMORY) -VERSION_STRINGS += API_VERSION=$(shell cd $(DRIVER_DIR); grep "\#define _MALI_API_VERSION" $(FILES_PREFIX)include/linux/mali/mali_utgard_uk_types.h | cut -d' ' -f 3 ) -VERSION_STRINGS += REPO_URL=$(shell cd $(DRIVER_DIR); (svn info || git svn info || echo 'URL: $(MALI_RELEASE_NAME)') 2>/dev/null | grep '^URL: ' | cut -d: -f2- | cut -b2-) -VERSION_STRINGS += REVISION=$(SVN_REV) -VERSION_STRINGS += CHANGED_REVISION=$(shell cd $(DRIVER_DIR); (svn info || git svn info || echo 'Last Changed Rev: $(MALI_RELEASE_NAME)') 2>/dev/null | grep '^Last Changed Rev: ' | cut -d: -f2- | cut -b2-) -VERSION_STRINGS += CHANGE_DATE=$(shell cd $(DRIVER_DIR); (svn info || git svn info || echo 'Last Changed Date: $(MALI_RELEASE_NAME)') 2>/dev/null | grep '^Last Changed Date: ' | cut -d: -f2- | cut -b2-) -VERSION_STRINGS += BUILD_DATE=$(shell date) - -VERSION_STRINGS += BUILD=$(shell echo $(BUILD) | tr a-z A-Z) -VERSION_STRINGS += CPU=$(CPU) -VERSION_STRINGS += USING_UMP=$(USING_UMP) -VERSION_STRINGS += USING_MALI200=$(call submodule_enabled, $(DRIVER_DIR), MALI200) -VERSION_STRINGS += USING_MALI400=$(call submodule_enabled, $(DRIVER_DIR), MALI400) -VERSION_STRINGS += USING_MALI400_L2_CACHE=$(call submodule_enabled, $(DRIVER_DIR), MALI400L2) -VERSION_STRINGS += USING_GP2=$(call submodule_enabled, $(DRIVER_DIR), MALIGP2) -VERSION_STRINGS += KDIR=$(KDIR) -VERSION_STRINGS += MALI_PLATFORM_FILE=$(MALI_PLATFORM_FILE) -VERSION_STRINGS += OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=$(OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB) -VERSION_STRINGS += USING_PROFILING=$(USING_PROFILING) -VERSION_STRINGS += USING_INTERNAL_PROFILING=$(USING_INTERNAL_PROFILING) -VERSION_STRINGS += USING_GPU_UTILIZATION=$(CONFIG_MALI400_GPU_UTILIZATION) - -# Create file with Mali driver configuration -$(DRIVER_DIR)/__malidrv_build_info.c: - @echo 'const char *__malidrv_build_info(void) { return "malidrv: $(VERSION_STRINGS)";}' > $(DRIVER_DIR)/__malidrv_build_info.c diff --git a/drivers/media/video/samsung/mali/Kconfig b/drivers/media/video/samsung/mali/Kconfig deleted file mode 100644 index 1736eed..0000000 --- a/drivers/media/video/samsung/mali/Kconfig +++ /dev/null @@ -1,63 +0,0 @@ -# -## S3C Multimedia Mali configuration -## -# -# For Mali -config VIDEO_MALI400MP - bool "Enable MALI integration" - depends on VIDEO_SAMSUNG - default y - ---help--- - This enables MALI integration in the multimedia device driver - -choice -depends on VIDEO_MALI400MP -prompt "MALI MEMORY OPTION" -default MALI_OSMEM_ONLY -config MALI_DED_ONLY - bool "mali dedicated memory only" - ---help--- - This enables MALI dedicated memory only option -config MALI_DED_MMU - bool "mali dedicated memory with mmu enable" - ---help--- - This enables MALI dedicated memory with mmu enable option -config MALI_OSMEM_ONLY - bool "mali OS memory only" - ---help--- - This enables MALI OS memory only option -config MALI_DED_OSMEM - bool "mali dedicated memory and OS memory" - ---help--- - This enables MALI dedicated memory and OS memory option - -endchoice -config MALI_MEM_SIZE -int "Dedicated Memory Size" - depends on VIDEO_MALI400MP && (MALI_DED_ONLY || MALI_DED_MMU || MALI_DED_OSMEM) - default "128" - ---help--- - This value is dedicated memory size of Mali GPU(unit is MByte). - -config MALI_R3P1_LSI - bool "Uses the R3P1 as a kernel module" - depends on VIDEO_MALI400MP - default n - ---help--- - This uses the r3p1 as a MALI kernel module - - -# For DEBUG -config VIDEO_MALI400MP_DEBUG - bool "Enables debug messages" - depends on VIDEO_MALI400MP - default n - help - This enables Mali driver debug messages. - -config VIDEO_MALI400MP_DVFS - bool "Enables DVFS" - depends on VIDEO_MALI400MP && PM - default y - help - This enables Mali driver DVFS. diff --git a/drivers/media/video/samsung/mali/Kconfig_module b/drivers/media/video/samsung/mali/Kconfig_module deleted file mode 100644 index dabb36e..0000000 --- a/drivers/media/video/samsung/mali/Kconfig_module +++ /dev/null @@ -1,30 +0,0 @@ -config MALI400 - tristate "Mali-300/400/450 support" - depends on ARM - select FB - ---help--- - This enables support for the Mali-300, Mali-400, and Mali-450 GPUs. - - To compile this driver as a module, choose M here: the module will be - called mali. - -config MALI400_DEBUG - bool "Enable debug in Mali driver" - depends on MALI400 - ---help--- - This enabled extra debug checks and messages in the Mali-300/400/450 - driver. - -config MALI400_PROFILING - bool "Enable Mali profiling" - depends on MALI400 && TRACEPOINTS - ---help--- - This enables gator profiling of Mali GPU events. - -config MALI400_GPU_UTILIZATION - bool "Enable Mali GPU utilization tracking" - depends on MALI400 - ---help--- - This enables gathering and processing of the utilization of Mali GPU. - This data can be used as a basis to change GPU operating frequency. - diff --git a/drivers/media/video/samsung/mali/Makefile b/drivers/media/video/samsung/mali/Makefile deleted file mode 100644 index 3e25b61..0000000 --- a/drivers/media/video/samsung/mali/Makefile +++ /dev/null @@ -1,337 +0,0 @@ -# -# Copyright (C) 2010-2012 ARM Limited. All rights reserved. -# -# This program is free software and is provided to you under the terms of the GNU General Public License version 2 -# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. -# -# A copy of the licence is included with the program, and can also be obtained from Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# - -OSKOS :=linux -FILES_PREFIX= -MALI_INCLUDE_PREFIX := drivers/media/video/samsung/mali/ -KBUILDROOT = - -ifeq ($(CONFIG_MALI_DED_ONLY),y) -USING_OS_MEMORY=0 -USING_MMU=0 -USING_DED=1 -endif - -ifeq ($(CONFIG_MALI_DED_MMU),y) -USING_OS_MEMORY=0 -USING_MMU=1 -USING_DED=1 -endif - -ifeq ($(CONFIG_MALI_OSMEM_ONLY),y) -USING_MMU=1 -USING_DED=0 -USING_OS_MEMORY=1 -endif - -ifeq ($(CONFIG_MALI_DED_OSMEM),y) -USING_MMU=1 -USING_DED=1 -USING_OS_MEMORY=1 -endif - -ifeq ($(CONFIG_PM),y) - USING_PMM = 1 -ifeq ($(CONFIG_PM_RUNTIME),y) - KERNEL_RUNTIME_PM_ENABLED = 1 -endif -endif - -ifeq ($(CONFIG_VIDEO_MALI400MP_DVFS),y) -USING_GPU_UTILIZATION=1 -USING_MALI_DVFS_ENABLED=1 -endif - -ifeq ($(CONFIG_VIDEO_UMP_DEBUG),y) -BUILD=debug -endif - -ifeq ($(CONFIG_VIDEO_MALI400MP_STREAMLINE_PROFILING),y) -USING_PROFILING=1 -USING_TRACEPOINTS=1 -endif - -# set up defaults if not defined by the user -USE_UMPV2 ?= 0 -PANIC_ON_WATCHDOG_TIMEOUT ?= 1 -USING_MALI400 ?= 1 -USING_MMU ?= 1 -USING_DED ?= 0 -USING_UMP ?= 0 -ONLY_ZBT ?= 0 -USING_ZBT ?= 0 -USING_OS_MEMORY ?= 1 -USING_PMM ?= 0 -USING_MALI_RUN_TIME_PM ?= 0 -USING_MALI_PMM_TESTSUITE ?= 0 -USING_MALI_PMU ?= 0 -USING_GPU_UTILIZATION ?= 0 -OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB ?= 16 -USING_PROFILING ?= 0 -USING_INTERNAL_PROFILING ?= 0 -USING_TRACEPOINTS ?= 0 -USING_MALI_MAJOR_PREDEFINE = 1 -USING_MALI_DVFS_ENABLED ?= 1 -USING_MALI_PMM_EARLYSUSPEND ?= 0 -#USING_KERNEL_WITH_DMA_ALLOC_PHYS_PAGE ?= 0 -#CONFIG_MALI_MEM_SIZE ?= 512 -DISABLE_PP0 ?= 0 -DISABLE_PP1 ?= 0 -DISABLE_PP2 ?= 0 -DISABLE_PP3 ?= 0 -PROFILING_SKIP_PP_JOBS ?= 0 -PROFILING_SKIP_PP_AND_GP_JOBS ?= 0 -PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH ?= 0 -TIMESTAMP ?= default -BUILD ?= release -TARGET_PLATFORM ?= default -KERNEL_RUNTIME_PM_ENABLED ?= 0 -MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP ?= 0 -MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED ?= 0 -MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS ?= 0 - -# Get path to driver source from Linux build system -ifeq ($(USING_PROFILING),1) -ifeq ($(USING_INTERNAL_PROFILING),0) -ifndef CONFIG_TRACEPOINTS -# Should default to gator profiling, but we dont have the kernel feature required, so disable profiling -override USING_PROFILING = 0 -$(warning "CONFIG_TRACEPOINTS required for USING_PROFILING") -endif -endif -endif - -ifeq ($(USING_PROFILING),0) -# make sure user hasnt selected incompatible flags -override USING_INTERNAL_PROFILING = 0 -endif - -USING_MALI_SLP_GLOBAL_LOCK ?= 0 - -#config validtion check -ifeq ($(USING_OS_MEMORY),1) - USING_MMU = 1 -endif - -# Check if a Mali Core sub module should be enabled, true or false returned -#submodule_enabled = $(shell gcc $(DEFINES) -E $(FILES_PREFIX)/arch/config.h | grep type | grep -c $(2)) - -# Inside the kernel build system - -# This conditional makefile exports the global definition ARM_INTERNAL_BUILD. Customer releases will not include arm_internal.mak --include ../../../arm_internal.mak - -# Set up our defines, which will be passed to gcc -DEFINES += -DONLY_ZBT=$(ONLY_ZBT) -DEFINES += -DUSING_ZBT=$(USING_ZBT) -DEFINES += -DUSING_MMU=$(USING_MMU) -DEFINES += -DUSING_OS_MEMORY=$(USING_OS_MEMORY) -DEFINES += -DUSING_DED=$(USING_DED) -DEFINES += -DUSING_UMP=$(USING_UMP) -DEFINES += -D_MALI_OSK_SPECIFIC_INDIRECT_MMAP -DEFINES += -DUSING_MALI_PMU=$(USING_MALI_PMU) -DEFINES += -DMALI_PMM_RUNTIME_JOB_CONTROL_ON=$(KERNEL_RUNTIME_PM_ENABLED) -DEFINES += -DUSING_MALI_PMM=$(USING_PMM) -DEFINES += -DMALI_GPU_UTILIZATION=$(USING_GPU_UTILIZATION) -DEFINES += -DCONFIG_MALI_MEM_SIZE=$(CONFIG_MALI_MEM_SIZE) -DEFINES += -D_MALI_OSK_SPECIFIC_INDIRECT_MMAP -DEFINES += -DMALI_INTERNAL_TIMELINE_PROFILING_ENABLED=$(USING_INTERNAL_PROFILING) -DEFINES += -DMALI_MAJOR_PREDEFINE=$(USING_MALI_MAJOR_PREDEFINE) -DEFINES += -DMALI_DVFS_ENABLED=$(USING_MALI_DVFS_ENABLED) -DEFINES += -DUSING_MALI_PMM_EARLYSUSPEND=$(USING_MALI_PMM_EARLYSUSPEND) -DEFINES += -DMALI_STATE_TRACKING=0 -DEFINES += -DMALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=$(OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB) -DEFINES += -DMALI_TRACEPOINTS_ENABLED=$(USING_TRACEPOINTS) -DEFINES += -DDISABLE_PP0=$(DISABLE_PP0) -DEFINES += -DDISABLE_PP1=$(DISABLE_PP1) -DEFINES += -DDISABLE_PP2=$(DISABLE_PP2) -DEFINES += -DDISABLE_PP3=$(DISABLE_PP3) -DEFINES += -DPROFILING_SKIP_PP_JOBS=$(PROFILING_SKIP_PP_JOBS) -DEFINES += -DPROFILING_SKIP_PP_AND_GP_JOBS=$(PROFILING_SKIP_PP_AND_GP_JOBS) -DEFINES += -DPROFILING_PRINT_L2_HITRATE_ON_GP_FINISH=$(PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH) -DEFINES += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP) -DEFINES += -DMALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED=$(MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED) -DEFINES += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS) -DEFINES += -DMALI_TIMELINE_PROFILING_ENABLED=$(USING_PROFILING) -DEFINES += -DMALI_POWER_MGMT_TEST_SUITE=$(USING_MALI_PMM_TESTSUITE) -DEFINES += -DMALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=$(OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB) - -ifeq ($(BUILD),debug) -DEFINES += -DDEBUG -endif - -# Linux has its own mmap cleanup handlers (see mali_kernel_mem_mmu.o) -DEFINES += -DMALI_UKK_HAS_IMPLICIT_MMAP_CLEANUP - -# UMP -ifeq ($(CONFIG_VIDEO_UMP),y) - DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER=1 - EXTRA_CFLAGS += -I$(MALI_INCLUDE_PREFIX)../ump/include -else - DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER=0 -endif - -# Target build file -obj-$(CONFIG_VIDEO_UMP) += mali.o - -# Use our defines when compiling -# MALI -INCLUDES = \ - -I$(MALI_INCLUDE_PREFIX)\ - -I$(MALI_INCLUDE_PREFIX)include \ - -I$(MALI_INCLUDE_PREFIX)common \ - -I$(MALI_INCLUDE_PREFIX)linux \ - -I$(MALI_INCLUDE_PREFIX)platform\ - -I$(MALI_INCLUDE_PREFIX)regs - -EXTRA_CFLAGS += $(INCLUDES)\ - $(DEFINES) - -EXTRA_CFLAGS += -I$(MALI_INCLUDE_PREFIX)linux/license/gpl -EXTRA_CFLAGS += -I$(MALI_INCLUDE_PREFIX)common/pmm - -# Source files which always are included in a build -ifeq ($(CONFIG_VIDEO_UMP),y) -OSKFILES=\ - $(FILES_PREFIX)$(OSKOS)/mali_osk_irq.o \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_wait_queue.o \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_low_level_mem.o \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_mali.o \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_notification.o \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_time.o \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_timers.o -else -OSKFILES=\ - $(FILES_PREFIX)$(OSKOS)/mali_osk_atomics.o \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_irq.o \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_locks.o \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_wait_queue.o \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_low_level_mem.o \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_math.o \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_memory.o \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_misc.o \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_mali.o \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_notification.o \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_time.o \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_timers.o -endif #($(CONFIG_VIDEO_UMP),y) - -ifeq ($(CONFIG_CPU_EXYNOS4210),y) - MALI_PLATFORM_DIR = platform/orion-m400 -else - MALI_PLATFORM_DIR = platform/pegasus-m400 -endif #($(CONFIG_CPU_EXYNOS4210),y) - -MALI_PLATFORM_FILE=$(MALI_PLATFORM_DIR)/mali_platform.o -UKKFILES=\ - $(FILES_PREFIX)$(OSKOS)/mali_ukk_mem.o \ - $(FILES_PREFIX)$(OSKOS)/mali_ukk_gp.o \ - $(FILES_PREFIX)$(OSKOS)/mali_ukk_pp.o \ - $(FILES_PREFIX)$(OSKOS)/mali_ukk_core.o - -ifeq ($(USING_PROFILING),1) -UKKFILES += \ - $(FILES_PREFIX)$(OSKOS)/mali_ukk_profiling.o -endif - -mali-y := \ - common/mali_kernel_core.o \ - linux/mali_kernel_linux.o \ - common/mali_kernel_descriptor_mapping.o \ - common/mali_session.o \ - common/mali_device_pause_resume.o \ - common/mali_kernel_vsync.o \ - linux/mali_ukk_vsync.o \ - linux/mali_kernel_sysfs.o \ - common/mali_mmu.o \ - common/mali_mmu_page_directory.o \ - common/mali_memory.o \ - common/mali_kernel_memory_engine.o \ - common/mali_block_allocator.o \ - common/mali_kernel_mem_os.o \ - common/mali_mem_validation.o \ - common/mali_hw_core.o \ - common/mali_gp.o \ - common/mali_pp.o \ - common/mali_pp_job.o \ - common/mali_gp_job.o \ - common/mali_scheduler.o \ - common/mali_gp_scheduler.o \ - common/mali_pp_scheduler.o \ - common/mali_cluster.o \ - common/mali_group.o \ - common/mali_dlbu.o \ - common/mali_pm.o \ - common/mali_pmu.o \ - common/mali_user_settings_db.o \ - $(OSKOS)/mali_osk_pm.o \ - linux/mali_kernel_pm.o \ - linux/mali_pmu_power_up_down.o \ - $(MALI_PLATFORM_FILE) \ - $(OSKFILES) \ - $(UKKFILES) -# __malidrv_build_info.c - -# Selecting files to compile by parsing the config file - -ifeq ($(USING_INTERNAL_PROFILING),1) -PROFILING_BACKEND_SOURCES = \ - linux/mali_osk_profiling_internal.o \ - timestamp-$(TIMESTAMP)/mali_timestamp.o -EXTRA_CFLAGS += -I$(MALI_INCLUDE_PREFIX)timestamp-$(TIMESTAMP) -else -ifeq ($(USING_PROFILING),1) -PROFILING_BACKEND_SOURCES = \ - linux/mali_osk_profiling_gator.o -endif -endif - -# Add the profiling sources -mali-y += $(PROFILING_BACKEND_SOURCES) - -# Mali-400 PP in use -ifeq ($(USING_MALI_PMM_TESTSUITE),1) -EXTRA_CFLAGS += -I$(MALI_INCLUDE_PREFIX)platform/mali_pmu_testing -endif - -ifeq ($(USING_GPU_UTILIZATION),1) -EXTRA_CFLAGS += -DCONFIG_MALI400_GPU_UTILIZATION=1 - -mali-y += \ - common/mali_kernel_utilization.o -endif - -ifeq ($(USING_MALI_DVFS_ENABLED),1) -mali-y += $(MALI_PLATFORM_DIR)/mali_platform_dvfs.o -endif #($(USING_MALI_DVFS_ENABLED),1) - -EXTRA_CFLAGS += -DUSING_MALI400 - -# Mali Level2 cache in use -EXTRA_CFLAGS += -DUSING_MALI400_L2_CACHE -mali-y += common/mali_l2_cache.o - -# Mali SLP Global lock feature -ifeq ($(USING_MALI_SLP_GLOBAL_LOCK),1) -mali-y += \ - linux/mali_slp_global_lock.o -endif - - -ifeq ($(PANIC_ON_WATCHDOG_TIMEOUT),1) - EXTRA_CFLAGS += -DUSING_KERNEL_PANIC -endif - -# Get subversion revision number, fall back to 0000 if no svn info is available -SVN_REV:=$(shell ((svnversion | grep -E "^[0-9]+" && echo -n 'Revision: ' && svnversion) || git svn info | sed -e 's/$$$$/M/' | grep '^Revision: ' || echo ${MALI_RELEASE_NAME}) 2>/dev/null | sed -e 's/^Revision: //') - -EXTRA_CFLAGS += -DSVN_REV=$(SVN_REV) -EXTRA_CFLAGS += -DSVN_REV_STRING=\"$(SVN_REV)\" - diff --git a/drivers/media/video/samsung/mali/Makefile_module b/drivers/media/video/samsung/mali/Makefile_module deleted file mode 100644 index 361ce08..0000000 --- a/drivers/media/video/samsung/mali/Makefile_module +++ /dev/null @@ -1,97 +0,0 @@ -# -# Copyright (C) 2010-2012 ARM Limited. All rights reserved. -# -# This program is free software and is provided to you under the terms of the GNU General Public License version 2 -# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. -# -# A copy of the licence is included with the program, and can also be obtained from Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# - -USE_UMPV2=0 - -# The Makefile sets up "arch" based on the CONFIG, creates the version info -# string and the __malidrv_build_info.c file, and then call the Linux build -# system to actually build the driver. After that point the Kbuild file takes -# over. - -# set up defaults if not defined by the user -ARCH ?= arm - -OSKOS=linux -FILES_PREFIX= - -check_cc2 = \ - $(shell if $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; \ - then \ - echo "$(2)"; \ - else \ - echo "$(3)"; \ - fi ;) - -# This conditional makefile exports the global definition ARM_INTERNAL_BUILD. Customer releases will not include arm_internal.mak --include ../../../arm_internal.mak - -# Check that required parameters are supplied. -ifeq ($(CONFIG),) -$(error "CONFIG must be specified.") -endif -ifeq ($(CPU)$(KDIR),) -$(error "KDIR or CPU must be specified.") -endif - -ifeq ($(USING_UMP),1) -ifeq ($(USE_UMPV2),1) -UMP_SYMVERS_FILE ?= ../umpv2/Module.symvers -else -UMP_SYMVERS_FILE ?= ../ump/Module.symvers -endif -KBUILD_EXTRA_SYMBOLS = $(realpath $(UMP_SYMVERS_FILE)) -$(warning $(KBUILD_EXTRA_SYMBOLS)) -endif - -# Get any user defined KDIR- or maybe even a hardcoded KDIR --include KDIR_CONFIGURATION - -# Define host system directory -KDIR-$(shell uname -m):=/lib/modules/$(shell uname -r)/build - -ifeq ($(ARCH), arm) -# when compiling for ARM we're cross compiling -export CROSS_COMPILE ?= $(call check_cc2, arm-linux-gnueabi-gcc, arm-linux-gnueabi-, arm-none-linux-gnueabi-) -endif - -# look up KDIR based om CPU selection -KDIR ?= $(KDIR-$(CPU)) - -# validate lookup result -ifeq ($(KDIR),) -$(error No KDIR found for platform $(CPU)) -endif - -# report detected/selected settings -ifdef ARM_INTERNAL_BUILD -$(warning Config $(CONFIG)) -$(warning Host CPU $(CPU)) -$(warning OS_MEMORY $(USING_OS_MEMORY)) -endif - -# Set up build config -export CONFIG_MALI400=m - -ifeq ($(USING_GPU_UTILIZATION),1) -export EXTRA_DEFINES += -DCONFIG_MALI400_GPU_UTILIZATION=1 -export CONFIG_MALI400_GPU_UTILIZATION := y -endif - -all: $(UMP_SYMVERS_FILE) - $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) modules - @rm $(FILES_PREFIX)__malidrv_build_info.c $(FILES_PREFIX)__malidrv_build_info.o - -clean: - $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) clean - -kernelrelease: - $(MAKE) ARCH=$(ARCH) -C $(KDIR) kernelrelease - -export CONFIG KBUILD_EXTRA_SYMBOLS diff --git a/drivers/media/video/samsung/mali/arch b/drivers/media/video/samsung/mali/arch deleted file mode 120000 index 58ffbe7..0000000 --- a/drivers/media/video/samsung/mali/arch +++ /dev/null @@ -1 +0,0 @@ -arch-release \ No newline at end of file diff --git a/drivers/media/video/samsung/mali/arch-debug b/drivers/media/video/samsung/mali/arch-debug deleted file mode 120000 index 0ed0909..0000000 --- a/drivers/media/video/samsung/mali/arch-debug +++ /dev/null @@ -1 +0,0 @@ -arch-pegasus-m400/ \ No newline at end of file diff --git a/drivers/media/video/samsung/mali/arch-orion-m400/config.h b/drivers/media/video/samsung/mali/arch-orion-m400/config.h deleted file mode 100644 index 73502a2..0000000 --- a/drivers/media/video/samsung/mali/arch-orion-m400/config.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __ARCH_CONFIG_H__ -#define __ARCH_CONFIG_H__ - -/* Configuration for the EB platform with ZBT memory enabled */ -/*zepplin added 2010.08.17 for orion configuration*/ -#define MALI_BASE_ADDR 0x13000000 -#define GP_ADDR MALI_BASE_ADDR -#define L2_ADDR MALI_BASE_ADDR+0x1000 -#define PMU_ADDR MALI_BASE_ADDR+0x2000 -#define GP_MMU_ADDR MALI_BASE_ADDR+0x3000 -#define PP0_MMU_ADDR MALI_BASE_ADDR+0x4000 -#define PP1_MMU_ADDR MALI_BASE_ADDR+0x5000 -#define PP2_MMU_ADDR MALI_BASE_ADDR+0x6000 -#define PP3_MMU_ADDR MALI_BASE_ADDR+0x7000 -#define PP0_ADDR MALI_BASE_ADDR+0x8000 -#define PP1_ADDR MALI_BASE_ADDR+0xA000 -#define PP2_ADDR MALI_BASE_ADDR+0xC000 -#define PP3_ADDR MALI_BASE_ADDR+0xE000 - -/*for mmu and os memory*/ -#define MEM_BASE_ADDR 0x40000000 -#define MEM_TOTAL_SIZE 0x40000000 -#define MEM_MALI_OS_SIZE 0x40000000 - -/*for dedicated memory*/ -//#define MEM_MALI_BASE 0x58000000 -//#define MEM_MALI_SIZE 0x08000000 -#define MEM_MALI_SIZE CONFIG_MALI_MEM_SIZE*1024*1024 -#define MEM_MALI_BASE 0x80000000 - MEM_MALI_SIZE - -static _mali_osk_resource_t arch_configuration [] = -{ - { - .type = MALI400GP, - .description = "Mali-400 GP", - .base = GP_ADDR, - .irq = IRQ_GP_3D, - .mmu_id = 1 - }, - { - .type = MALI400PP, - .base = PP0_ADDR, - .irq = IRQ_PP0_3D, - .description = "Mali-400 PP 0", - .mmu_id = 2 - }, - { - .type = MALI400PP, - .base = PP1_ADDR, - .irq = IRQ_PP1_3D, - .description = "Mali-400 PP 1", - .mmu_id = 3 - }, - { - .type = MALI400PP, - .base = PP2_ADDR, - .irq = IRQ_PP2_3D, - .description = "Mali-400 PP 2", - .mmu_id = 4 - }, - { - .type = MALI400PP, - .base = PP3_ADDR, - .irq = IRQ_PP3_3D, - .description = "Mali-400 PP 3", - .mmu_id = 5 - }, -#if USING_MMU - { - .type = MMU, - .base = GP_MMU_ADDR, - .irq = IRQ_GPMMU_3D, - .description = "Mali-400 MMU for GP", - .mmu_id = 1 - }, - { - .type = MMU, - .base = PP0_MMU_ADDR, - .irq = IRQ_PPMMU0_3D, - .description = "Mali-400 MMU for PP 0", - .mmu_id = 2 - }, - { - .type = MMU, - .base = PP1_MMU_ADDR, - .irq = IRQ_PPMMU1_3D, - .description = "Mali-400 MMU for PP 1", - .mmu_id = 3 - }, - { - .type = MMU, - .base = PP2_MMU_ADDR, - .irq = IRQ_PPMMU2_3D, - .description = "Mali-400 MMU for PP 2", - .mmu_id = 4 - }, - { - .type = MMU, - .base = PP3_MMU_ADDR, - .irq = IRQ_PPMMU3_3D, - .description = "Mali-400 MMU for PP 3", - .mmu_id = 5 - }, -#if USING_OS_MEMORY - { - .type = OS_MEMORY, - .description = "System Memory", - .size = MEM_MALI_OS_SIZE, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE - }, -#endif -#if USING_DED /* Dedicated Memory */ - { - .type = MEMORY, - .description = "Dedicated Memory", - .base = MEM_MALI_BASE, - .size = MEM_MALI_SIZE, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE - }, -#endif/* if USING_OS_MEMORY*/ - { - .type = MEM_VALIDATION, - .description = "Framebuffer Memory", - .base = MEM_BASE_ADDR, - .size = MEM_TOTAL_SIZE, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE - }, -#else /* Not using MMU */ - { - .type = MEMORY, - .description = "Dedicated Memory", - .base = MEM_MALI_BASE, - .size = MEM_MALI_SIZE, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE - }, -#endif - { - .type = MALI400L2, - .base = L2_ADDR, - .description = "Mali-400 L2 cache" - }, -}; - -#endif /* __ARCH_CONFIG_H__ */ diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m300/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m300/config.h deleted file mode 100644 index e579526..0000000 --- a/drivers/media/video/samsung/mali/arch-pb-virtex5-m300/config.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __ARCH_CONFIG_H__ -#define __ARCH_CONFIG_H__ - -/* Configuration for the PB platform with ZBT memory enabled */ - -static _mali_osk_resource_t arch_configuration [] = -{ - { - .type = PMU, - .description = "Mali-300 PMU", - .base = 0xC0002000, - .irq = -1, - .mmu_id = 0 - - }, - { - .type = MALI300GP, - .description = "Mali-300 GP", - .base = 0xC0000000, - .irq = -1, - .mmu_id = 1 - }, - { - .type = MALI300PP, - .base = 0xc0008000, - .irq = -1, - .description = "Mali-300 PP", - .mmu_id = 2 - }, - { - .type = MMU, - .base = 0xC0003000, - .irq = -1, - .description = "Mali-300 MMU for GP", - .mmu_id = 1 - }, - { - .type = MMU, - .base = 0xC0004000, - .irq = -1, - .description = "Mali-300 MMU for PP", - .mmu_id = 2 - }, - { - .type = MEMORY, - .description = "Mali SDRAM remapped to baseboard", - .cpu_usage_adjust = -0x50000000, - .alloc_order = 0, /* Highest preference for this memory */ - .base = 0xD0000000, - .size = 0x10000000, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE - }, - { - .type = MEMORY, - .description = "Mali ZBT", - .alloc_order = 5, /* Medium preference for this memory */ - .base = 0xe1000000, - .size = 0x01000000, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE - }, - { - .type = MEM_VALIDATION, - .description = "Framebuffer", - .base = 0xe0000000, - .size = 0x01000000, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE - }, - { - .type = MALI300L2, - .base = 0xC0001000, - .description = "Mali-300 L2 cache" - }, -}; - -#endif /* __ARCH_CONFIG_H__ */ diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-direct/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-direct/config.h deleted file mode 100644 index 3893d72..0000000 --- a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-direct/config.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __ARCH_CONFIG_H__ -#define __ARCH_CONFIG_H__ - -/* Configuration for the PB platform with ZBT memory enabled */ - -static _mali_osk_resource_t arch_configuration [] = -{ - - { - .type = PMU, - .description = "Mali-400 PMU", - .base = 0xC0002000, - .irq = -1, - .mmu_id = 0 - }, - { - .type = MALI400GP, - .description = "Mali-400 GP", - .base = 0xC0000000, - .irq = -1, - .mmu_id = 1 - }, - { - .type = MALI400PP, - .base = 0xc0008000, - .irq = -1, - .description = "Mali-400 PP", - .mmu_id = 2 - }, - { - .type = MMU, - .base = 0xC0003000, - .irq = -1, - .description = "Mali-400 MMU for GP", - .mmu_id = 1 - }, - { - .type = MMU, - .base = 0xC0004000, - .irq = -1, - .description = "Mali-400 MMU for PP", - .mmu_id = 2 - }, - { - .type = OS_MEMORY, - .description = "OS Memory", - .alloc_order = 10, /* Lowest preference for this memory */ - .size = 96 * 1024 * 1024, /* 96 MB */ - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE - }, - { - .type = MEMORY, - .description = "Mali SDRAM remapped to baseboard", - .cpu_usage_adjust = 0, - .alloc_order = 5, /* Medium preference for this memory */ - .base = 0x80000000, - .size = 0x10000000, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE - }, - { - .type = MEMORY, - .description = "Mali ZBT", - .alloc_order = 0, /* Highest preference for this memory */ - .base = 0xe1000000, - .size = 0x01000000, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE - }, - { - .type = MEM_VALIDATION, - .description = "Framebuffer", - .base = 0xe0000000, - .size = 0x01000000, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE - }, - { - .type = MALI400L2, - .base = 0xC0001000, - .description = "Mali-400 L2 cache" - }, -}; - -#endif /* __ARCH_CONFIG_H__ */ diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-pmu/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-pmu/config.h deleted file mode 100644 index 6d84ab1..0000000 --- a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-pmu/config.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __ARCH_CONFIG_H__ -#define __ARCH_CONFIG_H__ - -/* Configuration for the PB platform with ZBT memory enabled */ - -static _mali_osk_resource_t arch_configuration [] = -{ - { - .type = PMU, - .description = "Mali-400 PMU", - .base = 0xC0002000, - .irq = -1, - .mmu_id = 0 - - }, - { - .type = MALI400GP, - .description = "Mali-400 GP", - .base = 0xC0000000, - .irq = -1, - .mmu_id = 1 - }, - { - .type = MALI400PP, - .base = 0xc0008000, - .irq = -1, - .description = "Mali-400 PP", - .mmu_id = 2 - }, - { - .type = MMU, - .base = 0xC0003000, - .irq = -1, - .description = "Mali-400 MMU for GP", - .mmu_id = 1 - }, - { - .type = MMU, - .base = 0xC0004000, - .irq = -1, - .description = "Mali-400 MMU for PP", - .mmu_id = 2 - }, - { - .type = MEMORY, - .description = "Mali SDRAM remapped to baseboard", - .cpu_usage_adjust = -0x50000000, - .alloc_order = 0, /* Highest preference for this memory */ - .base = 0xD0000000, - .size = 0x10000000, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE - }, - { - .type = MEMORY, - .description = "Mali ZBT", - .alloc_order = 5, /* Medium preference for this memory */ - .base = 0xe1000000, - .size = 0x01000000, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE - }, - { - .type = MEM_VALIDATION, - .description = "Framebuffer", - .base = 0xe0000000, - .size = 0x01000000, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE - }, - { - .type = MALI400L2, - .base = 0xC0001000, - .description = "Mali-400 L2 cache" - }, -}; - -#endif /* __ARCH_CONFIG_H__ */ diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1/config.h deleted file mode 100644 index 568ac0a..0000000 --- a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1/config.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __ARCH_CONFIG_H__ -#define __ARCH_CONFIG_H__ - -/* Configuration for the PB platform with ZBT memory enabled */ - -static _mali_osk_resource_t arch_configuration [] = -{ - { - .type = MALI400GP, - .description = "Mali-400 GP", - .base = 0xC0000000, - .irq = -1, - .mmu_id = 1 - }, - { - .type = MALI400PP, - .base = 0xc0008000, - .irq = -1, - .description = "Mali-400 PP", - .mmu_id = 2 - }, - { - .type = MMU, - .base = 0xC0003000, - .irq = -1, - .description = "Mali-400 MMU for GP", - .mmu_id = 1 - }, - { - .type = MMU, - .base = 0xC0004000, - .irq = -1, - .description = "Mali-400 MMU for PP", - .mmu_id = 2 - }, - { - .type = MEMORY, - .description = "Mali SDRAM remapped to baseboard", - .cpu_usage_adjust = -0x50000000, - .alloc_order = 0, /* Highest preference for this memory */ - .base = 0xD0000000, - .size = 0x10000000, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE - }, - { - .type = MEMORY, - .description = "Mali ZBT", - .alloc_order = 5, /* Medium preference for this memory */ - .base = 0xe1000000, - .size = 0x01000000, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE - }, - { - .type = MEM_VALIDATION, - .description = "Framebuffer", - .base = 0xe0000000, - .size = 0x01000000, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE - }, - { - .type = MALI400L2, - .base = 0xC0001000, - .description = "Mali-400 L2 cache" - }, -}; - -#endif /* __ARCH_CONFIG_H__ */ diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-2/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-2/config.h deleted file mode 100644 index 98b8059..0000000 --- a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-2/config.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __ARCH_CONFIG_H__ -#define __ARCH_CONFIG_H__ - -/* Configuration for the PB platform with ZBT memory enabled */ - -static _mali_osk_resource_t arch_configuration [] = -{ - { - .type = MALI400GP, - .description = "Mali-400 GP", - .base = 0xC0000000, - .irq = -1, - .mmu_id = 1 - }, - { - .type = MALI400PP, - .base = 0xc0008000, - .irq = -1, - .description = "Mali-400 PP 0", - .mmu_id = 2 - }, - { - .type = MALI400PP, - .base = 0xc000A000, - .irq = -1, - .description = "Mali-400 PP 1", - .mmu_id = 3 - }, - { - .type = MMU, - .base = 0xC0003000, - .irq = -1, - .description = "Mali-400 MMU for GP", - .mmu_id = 1 - }, - { - .type = MMU, - .base = 0xC0004000, - .irq = -1, - .description = "Mali-400 MMU for PP 0", - .mmu_id = 2 - }, - { - .type = MMU, - .base = 0xC0005000, - .irq = -1, - .description = "Mali-400 MMU for PP 1", - .mmu_id = 3 - }, - { - .type = MEMORY, - .description = "Mali SDRAM remapped to baseboard", - .cpu_usage_adjust = -0x50000000, - .alloc_order = 0, /* Highest preference for this memory */ - .base = 0xD0000000, - .size = 0x10000000, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE - }, - { - .type = MEMORY, - .description = "Mali ZBT", - .alloc_order = 5, /* Medium preference for this memory */ - .base = 0xe1000000, - .size = 0x01000000, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE - }, - { - .type = MEM_VALIDATION, - .description = "Framebuffer", - .base = 0xe0000000, - .size = 0x01000000, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE - }, - { - .type = MALI400L2, - .base = 0xC0001000, - .description = "Mali-400 L2 cache" - }, -}; - -#endif /* __ARCH_CONFIG_H__ */ diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-3/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-3/config.h deleted file mode 100644 index 7b10925..0000000 --- a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-3/config.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __ARCH_CONFIG_H__ -#define __ARCH_CONFIG_H__ - -/* Configuration for the PB platform with ZBT memory enabled */ - -static _mali_osk_resource_t arch_configuration [] = -{ - { - .type = MALI400GP, - .description = "Mali-400 GP", - .base = 0xC0000000, - .irq = -1, - .mmu_id = 1 - }, - { - .type = MALI400PP, - .base = 0xc0008000, - .irq = -1, - .description = "Mali-400 PP 0", - .mmu_id = 2 - }, - { - .type = MALI400PP, - .base = 0xc000A000, - .irq = -1, - .description = "Mali-400 PP 1", - .mmu_id = 3 - }, - { - .type = MALI400PP, - .base = 0xc000C000, - .irq = -1, - .description = "Mali-400 PP 2", - .mmu_id = 4 - }, - { - .type = MMU, - .base = 0xC0003000, - .irq = 102, - .description = "Mali-400 MMU for GP", - .mmu_id = 1 - }, - { - .type = MMU, - .base = 0xC0004000, - .irq = 102, - .description = "Mali-400 MMU for PP 0", - .mmu_id = 2 - }, - { - .type = MMU, - .base = 0xC0005000, - .irq = 102, - .description = "Mali-400 MMU for PP 1", - .mmu_id = 3 - }, - { - .type = MMU, - .base = 0xC0006000, - .irq = 102, - .description = "Mali-400 MMU for PP 2", - .mmu_id = 4 - }, - { - .type = MEMORY, - .description = "Mali SDRAM remapped to baseboard", - .cpu_usage_adjust = -0x50000000, - .alloc_order = 0, /* Highest preference for this memory */ - .base = 0xD0000000, - .size = 0x10000000, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE - }, - { - .type = MEMORY, - .description = "Mali ZBT", - .alloc_order = 5, /* Medium preference for this memory */ - .base = 0xe1000000, - .size = 0x01000000, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE - }, - { - .type = MEM_VALIDATION, - .description = "Framebuffer", - .base = 0xe0000000, - .size = 0x01000000, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE - }, - { - .type = MALI400L2, - .base = 0xC0001000, - .description = "Mali-400 L2 cache" - }, -}; - -#endif /* __ARCH_CONFIG_H__ */ diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-4/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-4/config.h deleted file mode 100644 index a15a6bd..0000000 --- a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-4/config.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __ARCH_CONFIG_H__ -#define __ARCH_CONFIG_H__ - -/* Configuration for the EB platform with ZBT memory enabled */ - -static _mali_osk_resource_t arch_configuration [] = -{ - { - .type = MALI400GP, - .description = "Mali-400 GP", - .base = 0xC0000000, - .irq = -1, - .mmu_id = 1 - }, - { - .type = MALI400PP, - .base = 0xc0008000, - .irq = -1, - .description = "Mali-400 PP 0", - .mmu_id = 2 - }, - { - .type = MALI400PP, - .base = 0xc000A000, - .irq = -1, - .description = "Mali-400 PP 1", - .mmu_id = 3 - }, - { - .type = MALI400PP, - .base = 0xc000C000, - .irq = -1, - .description = "Mali-400 PP 2", - .mmu_id = 4 - }, - { - .type = MALI400PP, - .base = 0xc000E000, - .irq = -1, - .description = "Mali-400 PP 3", - .mmu_id = 5 - }, - { - .type = MMU, - .base = 0xC0003000, - .irq = 102, - .description = "Mali-400 MMU for GP", - .mmu_id = 1 - }, - { - .type = MMU, - .base = 0xC0004000, - .irq = 102, - .description = "Mali-400 MMU for PP 0", - .mmu_id = 2 - }, - { - .type = MMU, - .base = 0xC0005000, - .irq = 102, - .description = "Mali-400 MMU for PP 1", - .mmu_id = 3 - }, - { - .type = MMU, - .base = 0xC0006000, - .irq = 102, - .description = "Mali-400 MMU for PP 2", - .mmu_id = 4 - }, - { - .type = MMU, - .base = 0xC0007000, - .irq = 102, - .description = "Mali-400 MMU for PP 3", - .mmu_id = 5 - }, - { - .type = MEMORY, - .description = "Mali SDRAM remapped to baseboard", - .cpu_usage_adjust = -0x50000000, - .alloc_order = 0, /* Highest preference for this memory */ - .base = 0xD0000000, - .size = 0x10000000, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE - }, - { - .type = MEMORY, - .description = "Mali ZBT", - .alloc_order = 5, /* Medium preference for this memory */ - .base = 0xe1000000, - .size = 0x01000000, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE - }, - { - .type = MEM_VALIDATION, - .description = "Framebuffer", - .base = 0xe0000000, - .size = 0x01000000, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE - }, - { - .type = MALI400L2, - .base = 0xC0001000, - .description = "Mali-400 L2 cache" - }, -}; - -#endif /* __ARCH_CONFIG_H__ */ diff --git a/drivers/media/video/samsung/mali/arch-pegasus-m400/config.h b/drivers/media/video/samsung/mali/arch-pegasus-m400/config.h deleted file mode 100644 index d5196c3..0000000 --- a/drivers/media/video/samsung/mali/arch-pegasus-m400/config.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __ARCH_CONFIG_H__ -#define __ARCH_CONFIG_H__ - -/* Configuration for the EB platform with ZBT memory enabled */ -/*zepplin added 2010.08.17 for orion configuration*/ -#define MALI_BASE_ADDR 0x13000000 -#define GP_ADDR MALI_BASE_ADDR -#define L2_ADDR MALI_BASE_ADDR+0x1000 -#define PMU_ADDR MALI_BASE_ADDR+0x2000 -#define GP_MMU_ADDR MALI_BASE_ADDR+0x3000 -#define PP0_MMU_ADDR MALI_BASE_ADDR+0x4000 -#define PP1_MMU_ADDR MALI_BASE_ADDR+0x5000 -#define PP2_MMU_ADDR MALI_BASE_ADDR+0x6000 -#define PP3_MMU_ADDR MALI_BASE_ADDR+0x7000 -#define PP0_ADDR MALI_BASE_ADDR+0x8000 -#define PP1_ADDR MALI_BASE_ADDR+0xA000 -#define PP2_ADDR MALI_BASE_ADDR+0xC000 -#define PP3_ADDR MALI_BASE_ADDR+0xE000 - -/*for mmu and os memory*/ -#define MEM_BASE_ADDR 0x40000000 -#define MEM_TOTAL_SIZE 0x40000000 -#define MEM_MALI_OS_SIZE 0x40000000 - -/*for dedicated memory*/ -//#define MEM_MALI_BASE 0x58000000 -//#define MEM_MALI_SIZE 0x08000000 -#define MEM_MALI_SIZE CONFIG_MALI_MEM_SIZE*1024*1024 -#define MEM_MALI_BASE 0x80000000 - MEM_MALI_SIZE - -static _mali_osk_resource_t arch_configuration [] = -{ - { - .type = MALI400GP, - .description = "Mali-400 GP", - .base = GP_ADDR, - .irq = IRQ_GP_3D, - .mmu_id = 1 - }, - { - .type = MALI400PP, - .base = PP0_ADDR, - .irq = IRQ_PP0_3D, - .description = "Mali-400 PP 0", - .mmu_id = 2 - }, - { - .type = MALI400PP, - .base = PP1_ADDR, - .irq = IRQ_PP1_3D, - .description = "Mali-400 PP 1", - .mmu_id = 3 - }, - { - .type = MALI400PP, - .base = PP2_ADDR, - .irq = IRQ_PP2_3D, - .description = "Mali-400 PP 2", - .mmu_id = 4 - }, - { - .type = MALI400PP, - .base = PP3_ADDR, - .irq = IRQ_PP3_3D, - .description = "Mali-400 PP 3", - .mmu_id = 5 - }, -#if USING_MMU - { - .type = MMU, - .base = GP_MMU_ADDR, - .irq = IRQ_GPMMU_3D, - .description = "Mali-400 MMU for GP", - .mmu_id = 1 - }, - { - .type = MMU, - .base = PP0_MMU_ADDR, - .irq = IRQ_PPMMU0_3D, - .description = "Mali-400 MMU for PP 0", - .mmu_id = 2 - }, - { - .type = MMU, - .base = PP1_MMU_ADDR, - .irq = IRQ_PPMMU1_3D, - .description = "Mali-400 MMU for PP 1", - .mmu_id = 3 - }, - { - .type = MMU, - .base = PP2_MMU_ADDR, - .irq = IRQ_PPMMU2_3D, - .description = "Mali-400 MMU for PP 2", - .mmu_id = 4 - }, - { - .type = MMU, - .base = PP3_MMU_ADDR, - .irq = IRQ_PPMMU3_3D, - .description = "Mali-400 MMU for PP 3", - .mmu_id = 5 - }, -#if USING_OS_MEMORY - { - .type = OS_MEMORY, - .description = "System Memory", - .size = MEM_MALI_OS_SIZE, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE - }, -#endif -#if USING_DED /* Dedicated Memory */ - { - .type = MEMORY, - .description = "Dedicated Memory", - .base = MEM_MALI_BASE, - .size = MEM_MALI_SIZE, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE - }, -#endif/* if USING_OS_MEMORY*/ - { - .type = MEM_VALIDATION, - .description = "memory validation", - .base = MEM_BASE_ADDR, - .size = MEM_TOTAL_SIZE, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE - }, -#else /* Not using MMU */ - { - .type = MEMORY, - .description = "Dedicated Memory", - .base = MEM_MALI_BASE, - .size = MEM_MALI_SIZE, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE - }, -#endif - { - .type = MALI400L2, - .base = L2_ADDR, - .description = "Mali-400 L2 cache" - }, -}; - -#endif /* __ARCH_CONFIG_H__ */ diff --git a/drivers/media/video/samsung/mali/arch-release b/drivers/media/video/samsung/mali/arch-release deleted file mode 120000 index 0ed0909..0000000 --- a/drivers/media/video/samsung/mali/arch-release +++ /dev/null @@ -1 +0,0 @@ -arch-pegasus-m400/ \ No newline at end of file diff --git a/drivers/media/video/samsung/mali/arch-ve-virtex6-m450-8/config.h b/drivers/media/video/samsung/mali/arch-ve-virtex6-m450-8/config.h deleted file mode 100644 index eb5da50..0000000 --- a/drivers/media/video/samsung/mali/arch-ve-virtex6-m450-8/config.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __ARCH_CONFIG_H__ -#define __ARCH_CONFIG_H__ - -/* Configuration for the Versatile Express platform */ - -#define MALI_BASE_ADDRESS 0xFC040000 - -static _mali_osk_resource_t arch_configuration [] = -{ - /* PMU */ - { - .type = PMU, - .base = MALI_BASE_ADDRESS + 0x02000, - .description = "MALI PMU" - }, - /* GP cluster */ - { - .type = MALI400L2, - .base = MALI_BASE_ADDRESS + 0x10000, - .description = "Mali-450 L2 cache for GP" - }, - { - .type = MALI400GP, - .description = "Mali-450 GP", - .base = MALI_BASE_ADDRESS, - .irq = -1, - }, - { - .type = MMU, - .base = MALI_BASE_ADDRESS + 0x3000, - .irq = 70, - .description = "Mali-450 MMU for GP", - }, - - /* PP0-3 cluster */ - { - .type = MALI400L2, - .base = MALI_BASE_ADDRESS + 0x1000, - .description = "Mali-450 L2 cache for PP0-3" - }, - { - .type = MALI400PP, - .base = MALI_BASE_ADDRESS + 0x8000, - .irq = 70, - .description = "Mali-450 PP0", - }, - { - .type = MMU, - .base = MALI_BASE_ADDRESS + 0x4000, - .irq = 70, - .description = "Mali-450 MMU for PP0", - }, - { - .type = MALI400PP, - .base = MALI_BASE_ADDRESS + 0xA000, - .irq = 70, - .description = "Mali-450 PP1", - }, - { - .type = MMU, - .base = MALI_BASE_ADDRESS + 0x5000, - .irq = 70, - .description = "Mali-450 MMU for PP1", - }, - { - .type = MALI400PP, - .base = MALI_BASE_ADDRESS + 0xC000, - .irq = 70, - .description = "Mali-450 PP2", - }, - { - .type = MMU, - .base = MALI_BASE_ADDRESS + 0x6000, - .irq = 70, - .description = "Mali-450 MMU for PP2", - }, - { - .type = MALI400PP, - .base = MALI_BASE_ADDRESS + 0xE000, - .irq = 70, - .description = "Mali-450 PP3", - }, - { - .type = MMU, - .base = MALI_BASE_ADDRESS + 0x7000, - .irq = 70, - .description = "Mali-450 MMU for PP3", - }, - - /* PP4-7 cluster */ - { - .type = MALI400L2, - .base = MALI_BASE_ADDRESS + 0x11000, - .description = "Mali-450 L2 cache for PP4-7" - }, - { - .type = MALI400PP, - .base = MALI_BASE_ADDRESS + 0x28000, - .irq = 70, - .description = "Mali-450 PP4", - }, - { - .type = MMU, - .base = MALI_BASE_ADDRESS + 0x1C000, - .irq = 70, - .description = "Mali-450 MMU for PP4", - }, - { - .type = MALI400PP, - .base = MALI_BASE_ADDRESS + 0x2A000, - .irq = 70, - .description = "Mali-450 PP5", - }, - { - .type = MMU, - .base = MALI_BASE_ADDRESS + 0x1D000, - .irq = 70, - .description = "Mali-450 MMU for PP5", - }, - { - .type = MALI400PP, - .base = MALI_BASE_ADDRESS + 0x2C000, - .irq = 70, - .description = "Mali-450 PP6", - }, - { - .type = MMU, - .base = MALI_BASE_ADDRESS + 0x1E000, - .irq = 70, - .description = "Mali-450 MMU for PP6", - }, - { - .type = MALI400PP, - .base = MALI_BASE_ADDRESS + 0x2E000, - .irq = 70, - .description = "Mali-450 PP7", - }, - { - .type = MMU, - .base = MALI_BASE_ADDRESS + 0x1F000, - .irq = 70, - .description = "Mali-450 MMU for PP7", - }, - - /* Memory */ - { - .type = OS_MEMORY, - .description = "Mali OS memory", - .cpu_usage_adjust = 0, - .alloc_order = 0, /* Highest preference for this memory */ - .base = 0x0, - .size = 256 * 1024 * 1024, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE - }, - { - .type = MEM_VALIDATION, - .description = "Framebuffer", - .base = 0xe0000000, - .size = 0x01000000, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE - }, -}; - -#endif /* __ARCH_CONFIG_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_block_allocator.c b/drivers/media/video/samsung/mali/common/mali_block_allocator.c deleted file mode 100644 index 269e662..0000000 --- a/drivers/media/video/samsung/mali/common/mali_block_allocator.c +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include "mali_kernel_common.h" -#include "mali_kernel_core.h" -#include "mali_kernel_memory_engine.h" -#include "mali_block_allocator.h" -#include "mali_osk.h" - -#define MALI_BLOCK_SIZE (256UL * 1024UL) /* 256 kB, remember to keep the ()s */ - -typedef struct block_info -{ - struct block_info * next; -} block_info; - -/* The structure used as the handle produced by block_allocator_allocate, - * and removed by block_allocator_release */ -typedef struct block_allocator_allocation -{ - /* The list will be released in reverse order */ - block_info *last_allocated; - mali_allocation_engine * engine; - mali_memory_allocation * descriptor; - u32 start_offset; - u32 mapping_length; -} block_allocator_allocation; - - -typedef struct block_allocator -{ - _mali_osk_lock_t *mutex; - block_info * all_blocks; - block_info * first_free; - u32 base; - u32 cpu_usage_adjust; - u32 num_blocks; -} block_allocator; - -MALI_STATIC_INLINE u32 get_phys(block_allocator * info, block_info * block); -static mali_physical_memory_allocation_result block_allocator_allocate(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info); -static void block_allocator_release(void * ctx, void * handle); -static mali_physical_memory_allocation_result block_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block); -static void block_allocator_release_page_table_block( mali_page_table_block *page_table_block ); -static void block_allocator_destroy(mali_physical_memory_allocator * allocator); -static u32 block_allocator_stat(mali_physical_memory_allocator * allocator); - -mali_physical_memory_allocator * mali_block_allocator_create(u32 base_address, u32 cpu_usage_adjust, u32 size, const char *name) -{ - mali_physical_memory_allocator * allocator; - block_allocator * info; - u32 usable_size; - u32 num_blocks; - - usable_size = size & ~(MALI_BLOCK_SIZE - 1); - MALI_DEBUG_PRINT(3, ("Mali block allocator create for region starting at 0x%08X length 0x%08X\n", base_address, size)); - MALI_DEBUG_PRINT(4, ("%d usable bytes\n", usable_size)); - num_blocks = usable_size / MALI_BLOCK_SIZE; - MALI_DEBUG_PRINT(4, ("which becomes %d blocks\n", num_blocks)); - - if (usable_size == 0) - { - MALI_DEBUG_PRINT(1, ("Memory block of size %d is unusable\n", size)); - return NULL; - } - - allocator = _mali_osk_malloc(sizeof(mali_physical_memory_allocator)); - if (NULL != allocator) - { - info = _mali_osk_malloc(sizeof(block_allocator)); - if (NULL != info) - { - info->mutex = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED, 0, _MALI_OSK_LOCK_ORDER_MEM_INFO); - if (NULL != info->mutex) - { - info->all_blocks = _mali_osk_malloc(sizeof(block_info) * num_blocks); - if (NULL != info->all_blocks) - { - u32 i; - info->first_free = NULL; - info->num_blocks = num_blocks; - - info->base = base_address; - info->cpu_usage_adjust = cpu_usage_adjust; - - for ( i = 0; i < num_blocks; i++) - { - info->all_blocks[i].next = info->first_free; - info->first_free = &info->all_blocks[i]; - } - - allocator->allocate = block_allocator_allocate; - allocator->allocate_page_table_block = block_allocator_allocate_page_table_block; - allocator->destroy = block_allocator_destroy; - allocator->stat = block_allocator_stat; - allocator->ctx = info; - allocator->name = name; - - return allocator; - } - _mali_osk_lock_term(info->mutex); - } - _mali_osk_free(info); - } - _mali_osk_free(allocator); - } - - return NULL; -} - -static void block_allocator_destroy(mali_physical_memory_allocator * allocator) -{ - block_allocator * info; - MALI_DEBUG_ASSERT_POINTER(allocator); - MALI_DEBUG_ASSERT_POINTER(allocator->ctx); - info = (block_allocator*)allocator->ctx; - - _mali_osk_free(info->all_blocks); - _mali_osk_lock_term(info->mutex); - _mali_osk_free(info); - _mali_osk_free(allocator); -} - -MALI_STATIC_INLINE u32 get_phys(block_allocator * info, block_info * block) -{ - return info->base + ((block - info->all_blocks) * MALI_BLOCK_SIZE); -} - -static mali_physical_memory_allocation_result block_allocator_allocate(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info) -{ - block_allocator * info; - u32 left; - block_info * last_allocated = NULL; - mali_physical_memory_allocation_result result = MALI_MEM_ALLOC_NONE; - block_allocator_allocation *ret_allocation; - - MALI_DEBUG_ASSERT_POINTER(ctx); - MALI_DEBUG_ASSERT_POINTER(descriptor); - MALI_DEBUG_ASSERT_POINTER(offset); - MALI_DEBUG_ASSERT_POINTER(alloc_info); - - info = (block_allocator*)ctx; - left = descriptor->size - *offset; - MALI_DEBUG_ASSERT(0 != left); - - if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) return MALI_MEM_ALLOC_INTERNAL_FAILURE; - - ret_allocation = _mali_osk_malloc( sizeof(block_allocator_allocation) ); - - if ( NULL == ret_allocation ) - { - /* Failure; try another allocator by returning MALI_MEM_ALLOC_NONE */ - _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); - return result; - } - - ret_allocation->start_offset = *offset; - ret_allocation->mapping_length = 0; - - while ((left > 0) && (info->first_free)) - { - block_info * block; - u32 phys_addr; - u32 padding; - u32 current_mapping_size; - - block = info->first_free; - info->first_free = info->first_free->next; - block->next = last_allocated; - last_allocated = block; - - phys_addr = get_phys(info, block); - - padding = *offset & (MALI_BLOCK_SIZE-1); - - if (MALI_BLOCK_SIZE - padding < left) - { - current_mapping_size = MALI_BLOCK_SIZE - padding; - } - else - { - current_mapping_size = left; - } - - if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, phys_addr + padding, info->cpu_usage_adjust, current_mapping_size)) - { - MALI_DEBUG_PRINT(1, ("Mapping of physical memory failed\n")); - result = MALI_MEM_ALLOC_INTERNAL_FAILURE; - mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->start_offset, ret_allocation->mapping_length, (_mali_osk_mem_mapregion_flags_t)0); - - /* release all memory back to the pool */ - while (last_allocated) - { - /* This relinks every block we've just allocated back into the free-list */ - block = last_allocated->next; - last_allocated->next = info->first_free; - info->first_free = last_allocated; - last_allocated = block; - } - - break; - } - - *offset += current_mapping_size; - left -= current_mapping_size; - ret_allocation->mapping_length += current_mapping_size; - } - - _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); - - if (last_allocated) - { - if (left) result = MALI_MEM_ALLOC_PARTIAL; - else result = MALI_MEM_ALLOC_FINISHED; - - /* Record all the information about this allocation */ - ret_allocation->last_allocated = last_allocated; - ret_allocation->engine = engine; - ret_allocation->descriptor = descriptor; - - alloc_info->ctx = info; - alloc_info->handle = ret_allocation; - alloc_info->release = block_allocator_release; - } - else - { - /* Free the allocation information - nothing to be passed back */ - _mali_osk_free( ret_allocation ); - } - - return result; -} - -static void block_allocator_release(void * ctx, void * handle) -{ - block_allocator * info; - block_info * block, * next; - block_allocator_allocation *allocation; - - MALI_DEBUG_ASSERT_POINTER(ctx); - MALI_DEBUG_ASSERT_POINTER(handle); - - info = (block_allocator*)ctx; - allocation = (block_allocator_allocation*)handle; - block = allocation->last_allocated; - - MALI_DEBUG_ASSERT_POINTER(block); - - if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) - { - MALI_DEBUG_PRINT(1, ("allocator release: Failed to get mutex\n")); - return; - } - - /* unmap */ - mali_allocation_engine_unmap_physical(allocation->engine, allocation->descriptor, allocation->start_offset, allocation->mapping_length, (_mali_osk_mem_mapregion_flags_t)0); - - while (block) - { - MALI_DEBUG_ASSERT(!((block < info->all_blocks) || (block > (info->all_blocks + info->num_blocks)))); - - next = block->next; - - /* relink into free-list */ - block->next = info->first_free; - info->first_free = block; - - /* advance the loop */ - block = next; - } - - _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); - - _mali_osk_free( allocation ); -} - - -static mali_physical_memory_allocation_result block_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block) -{ - block_allocator * info; - mali_physical_memory_allocation_result result = MALI_MEM_ALLOC_INTERNAL_FAILURE; - - MALI_DEBUG_ASSERT_POINTER(ctx); - MALI_DEBUG_ASSERT_POINTER(block); - info = (block_allocator*)ctx; - - if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) return MALI_MEM_ALLOC_INTERNAL_FAILURE; - - if (NULL != info->first_free) - { - void * virt; - u32 phys; - u32 size; - block_info * alloc; - alloc = info->first_free; - - phys = get_phys(info, alloc); /* Does not modify info or alloc */ - size = MALI_BLOCK_SIZE; /* Must be multiple of MALI_MMU_PAGE_SIZE */ - virt = _mali_osk_mem_mapioregion( phys, size, "Mali block allocator page tables" ); - - /* Failure of _mali_osk_mem_mapioregion will result in MALI_MEM_ALLOC_INTERNAL_FAILURE, - * because it's unlikely another allocator will be able to map in. */ - - if ( NULL != virt ) - { - block->ctx = info; /* same as incoming ctx */ - block->handle = alloc; - block->phys_base = phys; - block->size = size; - block->release = block_allocator_release_page_table_block; - block->mapping = virt; - - info->first_free = alloc->next; - - alloc->next = NULL; /* Could potentially link many blocks together instead */ - - result = MALI_MEM_ALLOC_FINISHED; - } - } - else result = MALI_MEM_ALLOC_NONE; - - _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); - - return result; -} - - -static void block_allocator_release_page_table_block( mali_page_table_block *page_table_block ) -{ - block_allocator * info; - block_info * block, * next; - - MALI_DEBUG_ASSERT_POINTER( page_table_block ); - - info = (block_allocator*)page_table_block->ctx; - block = (block_info*)page_table_block->handle; - - MALI_DEBUG_ASSERT_POINTER(info); - MALI_DEBUG_ASSERT_POINTER(block); - - - if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) - { - MALI_DEBUG_PRINT(1, ("allocator release: Failed to get mutex\n")); - return; - } - - /* Unmap all the physical memory at once */ - _mali_osk_mem_unmapioregion( page_table_block->phys_base, page_table_block->size, page_table_block->mapping ); - - /** @note This loop handles the case where more than one block_info was linked. - * Probably unnecessary for page table block releasing. */ - while (block) - { - next = block->next; - - MALI_DEBUG_ASSERT(!((block < info->all_blocks) || (block > (info->all_blocks + info->num_blocks)))); - - block->next = info->first_free; - info->first_free = block; - - block = next; - } - - _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); -} - -static u32 block_allocator_stat(mali_physical_memory_allocator * allocator) -{ - block_allocator * info; - block_info *block; - u32 free_blocks = 0; - - MALI_DEBUG_ASSERT_POINTER(allocator); - - info = (block_allocator*)allocator->ctx; - block = info->first_free; - - while(block) - { - free_blocks++; - block = block->next; - } - return (info->num_blocks - free_blocks) * MALI_BLOCK_SIZE; -} diff --git a/drivers/media/video/samsung/mali/common/mali_block_allocator.h b/drivers/media/video/samsung/mali/common/mali_block_allocator.h deleted file mode 100644 index 6c6f13e..0000000 --- a/drivers/media/video/samsung/mali/common/mali_block_allocator.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_BLOCK_ALLOCATOR_H__ -#define __MALI_BLOCK_ALLOCATOR_H__ - -#include "mali_kernel_memory_engine.h" - -mali_physical_memory_allocator * mali_block_allocator_create(u32 base_address, u32 cpu_usage_adjust, u32 size, const char *name); - -#endif /* __MALI_BLOCK_ALLOCATOR_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_cluster.c b/drivers/media/video/samsung/mali/common/mali_cluster.c deleted file mode 100644 index f0fb2b6..0000000 --- a/drivers/media/video/samsung/mali/common/mali_cluster.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (C) 2011-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_kernel_common.h" -#include "mali_cluster.h" -#include "mali_osk.h" -#include "mali_group.h" -#include "mali_l2_cache.h" -#include "mali_scheduler.h" - -static struct mali_cluster *mali_global_clusters[MALI_MAX_NUMBER_OF_CLUSTERS] = { NULL, NULL, NULL }; -static u32 mali_global_num_clusters = 0; - -/** - * The structure represents a render cluster - * A render cluster is defined by all the cores that share the same Mali L2 cache - */ -struct mali_cluster -{ - struct mali_l2_cache_core *l2; - u32 number_of_groups; - struct mali_group* groups[MALI_MAX_NUMBER_OF_GROUPS_PER_CLUSTER]; - u32 last_invalidated_id; - mali_bool power_is_enabled; -}; - -struct mali_cluster *mali_cluster_create(struct mali_l2_cache_core *l2_cache) -{ - struct mali_cluster *cluster = NULL; - - if (mali_global_num_clusters >= MALI_MAX_NUMBER_OF_CLUSTERS) - { - MALI_PRINT_ERROR(("Mali cluster: Too many cluster objects created\n")); - return NULL; - } - - cluster = _mali_osk_malloc(sizeof(struct mali_cluster)); - if (NULL != cluster) - { - _mali_osk_memset(cluster, 0, sizeof(struct mali_cluster)); - cluster->l2 = l2_cache; /* This cluster now owns this L2 cache object */ - cluster->last_invalidated_id = 0; - cluster->power_is_enabled = MALI_TRUE; - - mali_global_clusters[mali_global_num_clusters] = cluster; - mali_global_num_clusters++; - - return cluster; - } - - return NULL; -} - -void mali_cluster_power_is_enabled_set(struct mali_cluster * cluster, mali_bool power_is_enabled) -{ - cluster->power_is_enabled = power_is_enabled; -} - -mali_bool mali_cluster_power_is_enabled_get(struct mali_cluster * cluster) -{ - return cluster->power_is_enabled; -} - - -void mali_cluster_add_group(struct mali_cluster *cluster, struct mali_group *group) -{ - MALI_DEBUG_ASSERT_POINTER(cluster); - - if (cluster->number_of_groups < MALI_MAX_NUMBER_OF_GROUPS_PER_CLUSTER) - { - /* This cluster now owns the group object */ - cluster->groups[cluster->number_of_groups] = group; - cluster->number_of_groups++; - } -} - -void mali_cluster_delete(struct mali_cluster *cluster) -{ - u32 i; - - MALI_DEBUG_ASSERT_POINTER(cluster); - - /* Free all the resources we own */ - for (i = 0; i < cluster->number_of_groups; i++) - { - mali_group_delete(cluster->groups[i]); - } - - if (NULL != cluster->l2) - { - mali_l2_cache_delete(cluster->l2); - } - - for (i = 0; i < mali_global_num_clusters; i++) - { - if (mali_global_clusters[i] == cluster) - { - mali_global_clusters[i] = NULL; - mali_global_num_clusters--; - break; - } - } - - _mali_osk_free(cluster); -} - -void mali_cluster_reset(struct mali_cluster *cluster) -{ - u32 i; - - MALI_DEBUG_ASSERT_POINTER(cluster); - - /* Free all the resources we own */ - for (i = 0; i < cluster->number_of_groups; i++) - { - struct mali_group *group = cluster->groups[i]; - - mali_group_reset(group); - } - - if (NULL != cluster->l2) - { - mali_l2_cache_reset(cluster->l2); - } -} - -struct mali_l2_cache_core* mali_cluster_get_l2_cache_core(struct mali_cluster *cluster) -{ - MALI_DEBUG_ASSERT_POINTER(cluster); - return cluster->l2; -} - -struct mali_group *mali_cluster_get_group(struct mali_cluster *cluster, u32 index) -{ - MALI_DEBUG_ASSERT_POINTER(cluster); - - if (index < cluster->number_of_groups) - { - return cluster->groups[index]; - } - - return NULL; -} - -struct mali_cluster *mali_cluster_get_global_cluster(u32 index) -{ - if (MALI_MAX_NUMBER_OF_CLUSTERS > index) - { - return mali_global_clusters[index]; - } - - return NULL; -} - -u32 mali_cluster_get_glob_num_clusters(void) -{ - return mali_global_num_clusters; -} - -mali_bool mali_cluster_l2_cache_invalidate_all(struct mali_cluster *cluster, u32 id) -{ - MALI_DEBUG_ASSERT_POINTER(cluster); - - if (NULL != cluster->l2) - { - /* If the last cache invalidation was done by a job with a higher id we - * don't have to flush. Since user space will store jobs w/ their - * corresponding memory in sequence (first job #0, then job #1, ...), - * we don't have to flush for job n-1 if job n has already invalidated - * the cache since we know for sure that job n-1's memory was already - * written when job n was started. */ - if (((s32)id) <= ((s32)cluster->last_invalidated_id)) - { - return MALI_FALSE; - } - else - { - cluster->last_invalidated_id = mali_scheduler_get_new_id(); - } - - mali_l2_cache_invalidate_all(cluster->l2); - } - return MALI_TRUE; -} - -void mali_cluster_l2_cache_invalidate_all_force(struct mali_cluster *cluster) -{ - MALI_DEBUG_ASSERT_POINTER(cluster); - - if (NULL != cluster->l2) - { - cluster->last_invalidated_id = mali_scheduler_get_new_id(); - mali_l2_cache_invalidate_all(cluster->l2); - } -} - -void mali_cluster_invalidate_pages(u32 *pages, u32 num_pages) -{ - u32 i; - - for (i = 0; i < mali_global_num_clusters; i++) - { - /*additional check for cluster*/ - if (MALI_TRUE == mali_l2_cache_lock_power_state(mali_global_clusters[i]->l2)) - { - mali_l2_cache_invalidate_pages(mali_global_clusters[i]->l2, pages, num_pages); - } - mali_l2_cache_unlock_power_state(mali_global_clusters[i]->l2); - /*check for failed power locking???*/ - } -} diff --git a/drivers/media/video/samsung/mali/common/mali_cluster.h b/drivers/media/video/samsung/mali/common/mali_cluster.h deleted file mode 100644 index 33debdb..0000000 --- a/drivers/media/video/samsung/mali/common/mali_cluster.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2011-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_CLUSTER_H__ -#define __MALI_CLUSTER_H__ - -#include "mali_osk.h" -#include "mali_l2_cache.h" - -/* Maximum 1 GP and 4 PP for a cluster (Mali-400 Quad-core) */ -#define MALI_MAX_NUMBER_OF_GROUPS_PER_CLUSTER 5 -#define MALI_MAX_NUMBER_OF_CLUSTERS 3 - -struct mali_cluster; -struct mali_group; - -struct mali_cluster *mali_cluster_create(struct mali_l2_cache_core *l2_cache); -void mali_cluster_add_group(struct mali_cluster *cluster, struct mali_group *group); -void mali_cluster_delete(struct mali_cluster *cluster); - -void mali_cluster_power_is_enabled_set(struct mali_cluster * cluster, mali_bool power_is_enabled); -mali_bool mali_cluster_power_is_enabled_get(struct mali_cluster * cluster); - -void mali_cluster_reset(struct mali_cluster *cluster); - -struct mali_l2_cache_core* mali_cluster_get_l2_cache_core(struct mali_cluster *cluster); -struct mali_group *mali_cluster_get_group(struct mali_cluster *cluster, u32 index); - -struct mali_cluster *mali_cluster_get_global_cluster(u32 index); -u32 mali_cluster_get_glob_num_clusters(void); - -/* Returns MALI_TRUE if it did the flush */ -mali_bool mali_cluster_l2_cache_invalidate_all(struct mali_cluster *cluster, u32 id); -void mali_cluster_l2_cache_invalidate_all_force(struct mali_cluster *cluster); -void mali_cluster_invalidate_pages(u32 *pages, u32 num_pages); - -#endif /* __MALI_CLUSTER_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_device_pause_resume.c b/drivers/media/video/samsung/mali/common/mali_device_pause_resume.c deleted file mode 100644 index 6af1279..0000000 --- a/drivers/media/video/samsung/mali/common/mali_device_pause_resume.c +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_device_pause_resume.c - * Implementation of the Mali pause/resume functionality - */ - -#include "mali_gp_scheduler.h" -#include "mali_pp_scheduler.h" -#include "mali_pm.h" - -void mali_dev_pause(mali_bool *power_is_on) -{ - mali_gp_scheduler_suspend(); - mali_pp_scheduler_suspend(); - - /* - * Take and hold the PM lock to be sure we don't change power state as well. - * (it might be unsafe to for instance change frequency if Mali GPU is powered off) - */ - mali_pm_execute_state_change_lock(); - if (NULL != power_is_on) - { - *power_is_on = mali_pm_is_powered_on(); - } -} - -void mali_dev_resume(void) -{ - mali_pm_execute_state_change_unlock(); - mali_gp_scheduler_resume(); - mali_pp_scheduler_resume(); -} - -/* -EXPORT_SYMBOL(mali_dev_pause); -EXPORT_SYMBOL(mali_dev_resume); -*/ diff --git a/drivers/media/video/samsung/mali/common/mali_device_pause_resume.h b/drivers/media/video/samsung/mali/common/mali_device_pause_resume.h deleted file mode 100644 index 6be75b0..0000000 --- a/drivers/media/video/samsung/mali/common/mali_device_pause_resume.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_DEVICE_PAUSE_RESUME_H__ -#define __MALI_DEVICE_PAUSE_RESUME_H__ - -#include "mali_osk.h" - -/** - * Pause the scheduling and power state changes of Mali device driver. - * mali_dev_resume() must always be called as soon as possible after this function - * in order to resume normal operation of the Mali driver. - * - * @param power_is_on Receives the power current status of Mali GPU. MALI_TRUE if GPU is powered on - */ -void mali_dev_pause(mali_bool *power_is_on); - -/** - * Resume scheduling and allow power changes in Mali device driver. - * This must always be called after mali_dev_pause(). - */ -void mali_dev_resume(void); - -#endif /* __MALI_DEVICE_PAUSE_RESUME_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_dlbu.c b/drivers/media/video/samsung/mali/common/mali_dlbu.c deleted file mode 100644 index fcc51fa..0000000 --- a/drivers/media/video/samsung/mali/common/mali_dlbu.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright (C) 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_dlbu.h" -#include "mali_memory.h" -#include "mali_pp.h" -#include "mali_group.h" -#include "mali_osk.h" -#include "mali_hw_core.h" - -/** - * Size of DLBU registers in bytes - */ -#define MALI_DLBU_SIZE 0x400 - -u32 mali_dlbu_phys_addr = 0; -static mali_io_address mali_dlbu_cpu_addr = 0; - -static u32 mali_dlbu_tile_position; - -/** - * DLBU register numbers - * Used in the register read/write routines. - * See the hardware documentation for more information about each register - */ -typedef enum mali_dlbu_register { - MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR = 0x0000, /**< Master tile list physical base address; - 31:12 Physical address to the page used for the DLBU - 0 DLBU enable - set this bit to 1 enables the AXI bus - between PPs and L2s, setting to 0 disables the router and - no further transactions are sent to DLBU */ - MALI_DLBU_REGISTER_MASTER_TLLIST_VADDR = 0x0004, /**< Master tile list virtual base address; - 31:12 Virtual address to the page used for the DLBU */ - MALI_DLBU_REGISTER_TLLIST_VBASEADDR = 0x0008, /**< Tile list virtual base address; - 31:12 Virtual address to the tile list. This address is used when - calculating the call address sent to PP.*/ - MALI_DLBU_REGISTER_FB_DIM = 0x000C, /**< Framebuffer dimension; - 23:16 Number of tiles in Y direction-1 - 7:0 Number of tiles in X direction-1 */ - MALI_DLBU_REGISTER_TLLIST_CONF = 0x0010, /**< Tile list configuration; - 29:28 select the size of each allocated block: 0=128 bytes, 1=256, 2=512, 3=1024 - 21:16 2^n number of tiles to be binned to one tile list in Y direction - 5:0 2^n number of tiles to be binned to one tile list in X direction */ - MALI_DLBU_REGISTER_START_TILE_POS = 0x0014, /**< Start tile positions; - 31:24 start position in Y direction for group 1 - 23:16 start position in X direction for group 1 - 15:8 start position in Y direction for group 0 - 7:0 start position in X direction for group 0 */ - MALI_DLBU_REGISTER_PP_ENABLE_MASK = 0x0018, /**< PP enable mask; - 7 enable PP7 for load balancing - 6 enable PP6 for load balancing - 5 enable PP5 for load balancing - 4 enable PP4 for load balancing - 3 enable PP3 for load balancing - 2 enable PP2 for load balancing - 1 enable PP1 for load balancing - 0 enable PP0 for load balancing */ -} mali_dlbu_register; - -typedef enum -{ - PP0ENABLE = 0, - PP1ENABLE, - PP2ENABLE, - PP3ENABLE, - PP4ENABLE, - PP5ENABLE, - PP6ENABLE, - PP7ENABLE -} mali_dlbu_pp_enable; - -struct mali_dlbu_core -{ - struct mali_hw_core hw_core; /**< Common for all HW cores */ - u32 pp_cores_mask; /**< This is a mask for the PP cores whose operation will be controlled by LBU - see MALI_DLBU_REGISTER_PP_ENABLE_MASK register */ -}; - -_mali_osk_errcode_t mali_dlbu_initialize(void) -{ - - MALI_DEBUG_PRINT(2, ("Dynamic Load Balancing Unit initializing\n")); - - if (_MALI_OSK_ERR_OK == mali_mmu_get_table_page(&mali_dlbu_phys_addr, &mali_dlbu_cpu_addr)) - { - MALI_SUCCESS; - } - - return _MALI_OSK_ERR_FAULT; -} - -void mali_dlbu_terminate(void) -{ - MALI_DEBUG_PRINT(3, ("Mali DLBU: terminating\n")); - - mali_mmu_release_table_page(mali_dlbu_phys_addr); -} - -struct mali_dlbu_core *mali_dlbu_create(const _mali_osk_resource_t * resource) -{ - struct mali_dlbu_core *core = NULL; - - MALI_DEBUG_PRINT(2, ("Mali DLBU: Creating Mali dynamic load balancing unit: %s\n", resource->description)); - - core = _mali_osk_malloc(sizeof(struct mali_dlbu_core)); - if (NULL != core) - { - if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALI_DLBU_SIZE)) - { - if (_MALI_OSK_ERR_OK == mali_dlbu_reset(core)) - { - mali_hw_core_register_write(&core->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_VADDR, MALI_DLB_VIRT_ADDR); - - return core; - } - MALI_PRINT_ERROR(("Failed to reset DLBU %s\n", core->hw_core.description)); - mali_hw_core_delete(&core->hw_core); - } - - _mali_osk_free(core); - } - else - { - MALI_PRINT_ERROR(("Mali DLBU: Failed to allocate memory for DLBU core\n")); - } - - return NULL; -} - -void mali_dlbu_delete(struct mali_dlbu_core *dlbu) -{ - mali_dlbu_reset(dlbu); - mali_hw_core_delete(&dlbu->hw_core); - _mali_osk_free(dlbu); -} - -void mali_dlbu_enable(struct mali_dlbu_core *dlbu) -{ - u32 wval = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR); - - wval |= 0x1; - mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR, wval); -} - -void mali_dlbu_disable(struct mali_dlbu_core *dlbu) -{ - u32 wval = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR); - - wval |= (wval & 0xFFFFFFFE); - mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR, wval); -} - -_mali_osk_errcode_t mali_dlbu_enable_pp_core(struct mali_dlbu_core *dlbu, u32 pp_core_enable, u32 val) -{ - u32 wval = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK); - - if((pp_core_enable < mali_pp_get_glob_num_pp_cores()) && ((0 == val) || (1 == val))) /* check for valid input parameters */ - { - if (val == 1) - { - val = (wval | (pp_core_enable <<= 0x1)); - } - if (val == 0) - { - val = (wval & ~(pp_core_enable << 0x1)); - } - wval |= val; - mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, wval); - dlbu->pp_cores_mask = wval; - - return _MALI_OSK_ERR_OK; - } - - return _MALI_OSK_ERR_FAULT; -} - -void mali_dlbu_enable_all_pp_cores(struct mali_dlbu_core *dlbu) -{ - mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, dlbu->pp_cores_mask); -} - -void mali_dlbu_disable_all_pp_cores(struct mali_dlbu_core *dlbu) -{ - mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, 0x0); -} - -void mali_dlbu_setup(struct mali_dlbu_core *dlbu, u8 fb_xdim, u8 fb_ydim, u8 xtilesize, u8 ytilesize, u8 blocksize, u8 xgr0, u8 ygr0, u8 xgr1, u8 ygr1) -{ - u32 wval = 0x0; - - /* write the framebuffer dimensions */ - wval = (16 << (u32)fb_ydim) | (u32)fb_xdim; - mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_FB_DIM, wval); - - /* write the tile list configuration */ - wval = 0x0; - wval = (28 << (u32)blocksize) | (16 << (u32)ytilesize) | ((u32)xtilesize); - mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_TLLIST_CONF, wval); - - /* write the start tile position */ - wval = 0x0; - wval = (24 << (u32)ygr1 | (16 << (u32)xgr1) | 8 << (u32)ygr0) | (u32)xgr0; - mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_START_TILE_POS, wval); -} - -_mali_osk_errcode_t mali_dlbu_reset(struct mali_dlbu_core *dlbu) -{ - _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT; - MALI_DEBUG_ASSERT_POINTER(dlbu); - - MALI_DEBUG_PRINT(4, ("Mali DLBU: mali_dlbu_reset: %s\n", dlbu->hw_core.description)); - - mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR, mali_dlbu_phys_addr); - mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_TLLIST_VBASEADDR, 0x00); - mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_FB_DIM, 0x00); - mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_TLLIST_CONF, 0x00); - mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_START_TILE_POS, 0x00); - - mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, dlbu->pp_cores_mask); - - err = _MALI_OSK_ERR_OK; - - return err; -} - -_mali_osk_errcode_t mali_dlbu_add_group(struct mali_dlbu_core *dlbu, struct mali_group *group) -{ - _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT; - u32 wval, rval; - struct mali_pp_core *pp_core = mali_group_get_pp_core(group); - - /* find the core id and set the mask */ - - if (NULL != pp_core) - { - wval = mali_pp_core_get_id(pp_core); - rval = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK); - mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, (wval << 0x1) | rval); - err = _MALI_OSK_ERR_OK; - } - - return err; -} - -void mali_dlbu_set_tllist_base_address(struct mali_dlbu_core *dlbu, u32 val) -{ - mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_TLLIST_VBASEADDR, val); -} - -void mali_dlbu_pp_jobs_stop(struct mali_dlbu_core *dlbu) -{ - /* this function to implement (see documentation): - * 1) clear all bits in the enable register - * 2) wait until all PPs have finished - mali_pp_scheduler.c code - this done in interrupts call? - * 3) read the current tile position registers to get current tile positions - - * note that current tile position register is the same as start tile position - perhaps the name should be changed!!! */ - - /* 1) */ - mali_dlbu_disable_all_pp_cores(dlbu); - - /* 3) */ - mali_dlbu_tile_position = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_START_TILE_POS); -} - -void mali_dlbu_pp_jobs_restart(struct mali_dlbu_core *dlbu) -{ - /* this function to implement (see the document): - * 1) configure the dynamic load balancing unit as normal - * 2) set the current tile position registers as read when stopping the job - * 3) configure the PPs to start the job as normal - done by another part of the system - scheduler */ - - /* 1) */ - mali_dlbu_reset(dlbu); - /* ++ setup the needed values - see this */ - - /* 2) */ - mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_START_TILE_POS, mali_dlbu_tile_position); -} diff --git a/drivers/media/video/samsung/mali/common/mali_dlbu.h b/drivers/media/video/samsung/mali/common/mali_dlbu.h deleted file mode 100644 index e3c3b9d..0000000 --- a/drivers/media/video/samsung/mali/common/mali_dlbu.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_DLBU_H__ -#define __MALI_DLBU_H__ - -#include "mali_osk.h" -#include "mali_group.h" - -#define MALI_DLB_VIRT_ADDR 0xFFF00000 /* master tile virtual address fixed at this value and mapped into every session */ - -extern u32 mali_dlbu_phys_addr; - -struct mali_dlbu_core; - -_mali_osk_errcode_t mali_dlbu_initialize(void); -void mali_dlbu_terminate(void); - -struct mali_dlbu_core *mali_dlbu_create(const _mali_osk_resource_t * resource); -void mali_dlbu_delete(struct mali_dlbu_core *dlbu); - -void mali_dlbu_enable(struct mali_dlbu_core *dlbu); -void mali_dlbu_disable(struct mali_dlbu_core *dlbu); - -_mali_osk_errcode_t mali_dlbu_enable_pp_core(struct mali_dlbu_core *dlbu, u32 pp_core_enable, u32 val); -void mali_dlbu_enable_all_pp_cores(struct mali_dlbu_core *dlbu); -void mali_dlbu_disable_all_pp_cores(struct mali_dlbu_core *dlbu); - -_mali_osk_errcode_t mali_dlbu_reset(struct mali_dlbu_core *dlbu); -void mali_dlbu_setup(struct mali_dlbu_core *dlbu, u8 fb_xdim, u8 fb_ydim, u8 xtilesize, u8 ytilesize, u8 blocksize, u8 xgr0, u8 ygr0, u8 xgr1, u8 ygr1); - -_mali_osk_errcode_t mali_dlbu_add_group(struct mali_dlbu_core *dlbu, struct mali_group *group); -void mali_dlbu_set_tllist_base_address(struct mali_dlbu_core *dlbu, u32 val); - -void mali_dlbu_pp_jobs_stop(struct mali_dlbu_core *dlbu); -void mali_dlbu_pp_jobs_restart(struct mali_dlbu_core *dlbu); - -#endif /* __MALI_DLBU_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_gp.c b/drivers/media/video/samsung/mali/common/mali_gp.c deleted file mode 100644 index 1624e46..0000000 --- a/drivers/media/video/samsung/mali/common/mali_gp.c +++ /dev/null @@ -1,746 +0,0 @@ -/* - * Copyright (C) 2011-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_gp.h" -#include "mali_hw_core.h" -#include "mali_group.h" -#include "mali_osk.h" -#include "regs/mali_gp_regs.h" -#include "mali_kernel_common.h" -#include "mali_kernel_core.h" -#if MALI_TIMELINE_PROFILING_ENABLED -#include "mali_osk_profiling.h" -#endif - -/** - * Definition of the GP core struct - * Used to track a GP core in the system. - */ -struct mali_gp_core -{ - struct mali_hw_core hw_core; /**< Common for all HW cores */ - struct mali_group *group; /**< Parent group for this core */ - _mali_osk_irq_t *irq; /**< IRQ handler */ - struct mali_gp_job *running_job; /**< Current running job */ - _mali_osk_timer_t *timeout_timer; /**< timeout timer for this core */ - u32 timeout_job_id; /**< job id for the timed out job - relevant only if gp_core_timed_out == MALI_TRUE */ - mali_bool core_timed_out; /**< if MALI_TRUE, this gp core has timed out; if MALI_FALSE, no timeout on this gp core */ - u32 counter_src0; /**< Performance counter 0, MALI_HW_CORE_NO_COUNTER for disabled */ - u32 counter_src1; /**< Performance counter 1, MALI_HW_CORE_NO_COUNTER for disabled */ - u32 counter_src0_used; /**< The selected performance counter 0 when a job is running */ - u32 counter_src1_used; /**< The selected performance counter 1 when a job is running */ -}; - -static struct mali_gp_core *mali_global_gp_core = NULL; - -/* Interrupt handlers */ -static _mali_osk_errcode_t mali_gp_upper_half(void *data); -static void mali_gp_bottom_half(void *data); -static void mali_gp_irq_probe_trigger(void *data); -static _mali_osk_errcode_t mali_gp_irq_probe_ack(void *data); -static void mali_gp_post_process_job(struct mali_gp_core *core, mali_bool suspend); -static void mali_gp_timeout(void *data); - -struct mali_gp_core *mali_gp_create(const _mali_osk_resource_t * resource, struct mali_group *group) -{ - struct mali_gp_core* core = NULL; - - MALI_DEBUG_ASSERT(NULL == mali_global_gp_core); - MALI_DEBUG_PRINT(2, ("Mali GP: Creating Mali GP core: %s\n", resource->description)); - - core = _mali_osk_malloc(sizeof(struct mali_gp_core)); - if (NULL != core) - { - core->group = group; - core->running_job = NULL; - core->counter_src0 = MALI_HW_CORE_NO_COUNTER; - core->counter_src1 = MALI_HW_CORE_NO_COUNTER; - core->counter_src0_used = MALI_HW_CORE_NO_COUNTER; - core->counter_src1_used = MALI_HW_CORE_NO_COUNTER; - if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALIGP2_REGISTER_ADDRESS_SPACE_SIZE)) - { - _mali_osk_errcode_t ret; - - mali_group_lock(group); - ret = mali_gp_reset(core); - mali_group_unlock(group); - - if (_MALI_OSK_ERR_OK == ret) - { - /* Setup IRQ handlers (which will do IRQ probing if needed) */ - core->irq = _mali_osk_irq_init(resource->irq, - mali_gp_upper_half, - mali_gp_bottom_half, - mali_gp_irq_probe_trigger, - mali_gp_irq_probe_ack, - core, - "mali_gp_irq_handlers"); - if (NULL != core->irq) - { - /* Initialise the timeout timer */ - core->timeout_timer = _mali_osk_timer_init(); - if(NULL != core->timeout_timer) - { - _mali_osk_timer_setcallback(core->timeout_timer, mali_gp_timeout, (void *)core); - MALI_DEBUG_PRINT(4, ("Mali GP: set global gp core from 0x%08X to 0x%08X\n", mali_global_gp_core, core)); - mali_global_gp_core = core; - - return core; - } - else - { - MALI_PRINT_ERROR(("Failed to setup timeout timer for GP core %s\n", core->hw_core.description)); - /* Release IRQ handlers */ - _mali_osk_irq_term(core->irq); - } - } - else - { - MALI_PRINT_ERROR(("Failed to setup interrupt handlers for GP core %s\n", core->hw_core.description)); - } - } - mali_hw_core_delete(&core->hw_core); - } - - _mali_osk_free(core); - } - else - { - MALI_PRINT_ERROR(("Failed to allocate memory for GP core\n")); - } - - return NULL; -} - -void mali_gp_delete(struct mali_gp_core *core) -{ - MALI_DEBUG_ASSERT_POINTER(core); - - _mali_osk_timer_term(core->timeout_timer); - _mali_osk_irq_term(core->irq); - mali_hw_core_delete(&core->hw_core); - mali_global_gp_core = NULL; - _mali_osk_free(core); -} - -void mali_gp_stop_bus(struct mali_gp_core *core) -{ - MALI_DEBUG_ASSERT_POINTER(core); - - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_STOP_BUS); -} - -_mali_osk_errcode_t mali_gp_stop_bus_wait(struct mali_gp_core *core) -{ - int i; - const int request_loop_count = 20; - - MALI_DEBUG_ASSERT_POINTER(core); - - /* Send the stop bus command. */ - mali_gp_stop_bus(core); - - /* Wait for bus to be stopped */ - for (i = 0; i < request_loop_count; i++) - { - if (mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS) & MALIGP2_REG_VAL_STATUS_BUS_STOPPED) - { - break; - } - _mali_osk_time_ubusydelay(10); - } - - if (request_loop_count == i) - { - MALI_PRINT_ERROR(("Mali GP: Failed to stop bus on %s\n", core->hw_core.description)); - return _MALI_OSK_ERR_FAULT; - } - return _MALI_OSK_ERR_OK; -} - -void mali_gp_hard_reset(struct mali_gp_core *core) -{ - const int reset_finished_loop_count = 15; - const u32 reset_wait_target_register = MALIGP2_REG_ADDR_MGMT_WRITE_BOUND_LOW; - const u32 reset_invalid_value = 0xC0FFE000; - const u32 reset_check_value = 0xC01A0000; - const u32 reset_default_value = 0; - int i; - - MALI_DEBUG_ASSERT_POINTER(core); - MALI_DEBUG_PRINT(4, ("Mali GP: Hard reset of core %s\n", core->hw_core.description)); - MALI_ASSERT_GROUP_LOCKED(core->group); - - mali_gp_post_process_job(core, MALI_FALSE); - - mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, reset_invalid_value); - - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_RESET); - - for (i = 0; i < reset_finished_loop_count; i++) - { - mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, reset_check_value); - if (reset_check_value == mali_hw_core_register_read(&core->hw_core, reset_wait_target_register)) - { - break; - } - } - - if (i == reset_finished_loop_count) - { - MALI_PRINT_ERROR(("Mali GP: The hard reset loop didn't work, unable to recover\n")); - } - - mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, reset_default_value); /* set it back to the default */ - /* Re-enable interrupts */ - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL); - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED); - -} - -_mali_osk_errcode_t mali_gp_reset(struct mali_gp_core *core) -{ - int i; - const int request_loop_count = 20; - - MALI_DEBUG_ASSERT_POINTER(core); - MALI_DEBUG_PRINT(4, ("Mali GP: Reset of core %s\n", core->hw_core.description)); - MALI_ASSERT_GROUP_LOCKED(core->group); - - mali_gp_post_process_job(core, MALI_FALSE); - - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, 0); /* disable the IRQs */ - -#if defined(USING_MALI200) - - /* On Mali-200, stop the bus, then do a hard reset of the core */ - - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_STOP_BUS); - - for (i = 0; i < request_loop_count; i++) - { - if (mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS) & MALIGP2_REG_VAL_STATUS_BUS_STOPPED) - { - break; - } - _mali_osk_time_ubusydelay(10); - } - - if (request_loop_count == i) - { - MALI_PRINT_ERROR(("Mali GP: Failed to stop bus for core %s, unable to recover\n", core->hw_core.description)); - return _MALI_OSK_ERR_FAULT; - } - - /* the bus was stopped OK, do the hard reset */ - mali_gp_hard_reset(core); - -#elif defined(USING_MALI400) - - /* Mali-300 and Mali-400 have a safe reset command which we use */ - - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALI400GP_REG_VAL_IRQ_RESET_COMPLETED); - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALI400GP_REG_VAL_CMD_SOFT_RESET); - - for (i = 0; i < request_loop_count; i++) - { - if (mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT) & MALI400GP_REG_VAL_IRQ_RESET_COMPLETED) - { - break; - } - _mali_osk_time_ubusydelay(10); - } - - if (request_loop_count == i) - { - MALI_PRINT_ERROR(("Mali GP: Failed to reset core %s, unable to recover\n", core->hw_core.description)); - return _MALI_OSK_ERR_FAULT; - } -#else -#error "no supported mali core defined" -#endif - - /* Re-enable interrupts */ - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL); - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED); - - return _MALI_OSK_ERR_OK; -} - -void mali_gp_job_start(struct mali_gp_core *core, struct mali_gp_job *job) -{ - u32 startcmd = 0; - u32 *frame_registers = mali_gp_job_get_frame_registers(job); - core->counter_src0_used = core->counter_src0; - core->counter_src1_used = core->counter_src1; - - MALI_DEBUG_ASSERT_POINTER(core); - MALI_ASSERT_GROUP_LOCKED(core->group); - - if (mali_gp_job_has_vs_job(job)) - { - startcmd |= (u32) MALIGP2_REG_VAL_CMD_START_VS; - } - - if (mali_gp_job_has_plbu_job(job)) - { - startcmd |= (u32) MALIGP2_REG_VAL_CMD_START_PLBU; - } - - MALI_DEBUG_ASSERT(0 != startcmd); - - mali_hw_core_register_write_array_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR, frame_registers, MALIGP2_NUM_REGS_FRAME); - -#if PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH - { - /* Read hits and Read misses*/ - mali_l2_cache_core_set_counter_src0(mali_l2_cache_core_get_glob_l2_core(0), 20); - mali_l2_cache_core_set_counter_src1(mali_l2_cache_core_get_glob_l2_core(0), 21); - } -#endif - - /* This selects which performance counters we are reading */ - if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used || MALI_HW_CORE_NO_COUNTER != core->counter_src0_used) - { - /* global_config has enabled HW counters, this will override anything specified by user space */ - if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used) - { - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used); - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE); - } - if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used) - { - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used); - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE); - } - } - else - { - /* Use HW counters from job object, if any */ - u32 perf_counter_flag = mali_gp_job_get_perf_counter_flag(job); - if (0 != perf_counter_flag) - { - if (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE) - { - core->counter_src0_used = mali_gp_job_get_perf_counter_src0(job); - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used); - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE); - } - - if (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE) - { - core->counter_src1_used = mali_gp_job_get_perf_counter_src1(job); - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used); - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE); - } - } - } - - MALI_DEBUG_PRINT(3, ("Mali GP: Starting job (0x%08x) on core %s with command 0x%08X\n", job, core->hw_core.description, startcmd)); - - /* Barrier to make sure the previous register write is finished */ - _mali_osk_write_mem_barrier(); - - /* This is the command that starts the core. */ - mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, startcmd); - - /* Barrier to make sure the previous register write is finished */ - _mali_osk_write_mem_barrier(); - - /* Setup the timeout timer value and save the job id for the job running on the gp core */ - - _mali_osk_timer_add(core->timeout_timer, _mali_osk_time_mstoticks(mali_max_job_runtime)); - core->timeout_job_id = mali_gp_job_get_id(job); - -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0) | MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH, - job->frame_builder_id, job->flush_id, 0, 0, 0); - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0), job->pid, job->tid, 0, 0, 0); -#endif - - core->running_job = job; -} - -void mali_gp_resume_with_new_heap(struct mali_gp_core *core, u32 start_addr, u32 end_addr) -{ - u32 irq_readout; - - MALI_DEBUG_ASSERT_POINTER(core); - MALI_ASSERT_GROUP_LOCKED(core->group); - - irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT); - - if (irq_readout & MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM) - { - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, (MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | MALIGP2_REG_VAL_IRQ_HANG)); - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED); /* re-enable interrupts */ - mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR, start_addr); - mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR, end_addr); - - MALI_DEBUG_PRINT(3, ("Mali GP: Resuming job\n")); - - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_UPDATE_PLBU_ALLOC); - _mali_osk_write_mem_barrier(); - -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_RESUME|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0), 0, 0, 0, 0, 0); -#endif - } - /* - * else: core has been reset between PLBU_OUT_OF_MEM interrupt and this new heap response. - * A timeout or a page fault on Mali-200 PP core can cause this behaviour. - */ -} - -void mali_gp_abort_job(struct mali_gp_core *core) -{ - MALI_DEBUG_ASSERT_POINTER(core); - MALI_ASSERT_GROUP_LOCKED(core->group); - - if (_MALI_OSK_ERR_FAULT != mali_gp_reset(core)) - { - _mali_osk_timer_del(core->timeout_timer); - } -} - -u32 mali_gp_core_get_version(struct mali_gp_core *core) -{ - MALI_DEBUG_ASSERT_POINTER(core); - return mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_VERSION); -} - -mali_bool mali_gp_core_set_counter_src0(struct mali_gp_core *core, u32 counter) -{ - MALI_DEBUG_ASSERT_POINTER(core); - - core->counter_src0 = counter; - return MALI_TRUE; -} - -mali_bool mali_gp_core_set_counter_src1(struct mali_gp_core *core, u32 counter) -{ - MALI_DEBUG_ASSERT_POINTER(core); - - core->counter_src1 = counter; - return MALI_TRUE; -} - -u32 mali_gp_core_get_counter_src0(struct mali_gp_core *core) -{ - MALI_DEBUG_ASSERT_POINTER(core); - return core->counter_src0; -} - -u32 mali_gp_core_get_counter_src1(struct mali_gp_core *core) -{ - MALI_DEBUG_ASSERT_POINTER(core); - return core->counter_src1; -} - -struct mali_gp_core *mali_gp_get_global_gp_core(void) -{ - return mali_global_gp_core; -} - -/* ------------- interrupt handling below ------------------ */ -static _mali_osk_errcode_t mali_gp_upper_half(void *data) -{ - struct mali_gp_core *core = (struct mali_gp_core *)data; - u32 irq_readout; - - irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_STAT); - if (MALIGP2_REG_VAL_IRQ_MASK_NONE != irq_readout) - { - /* Mask out all IRQs from this core until IRQ is handled */ - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_NONE); - -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0)|MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT, irq_readout, 0, 0, 0, 0); -#endif - - /* We do need to handle this in a bottom half */ - _mali_osk_irq_schedulework(core->irq); - return _MALI_OSK_ERR_OK; - } - - return _MALI_OSK_ERR_FAULT; -} - -static void mali_gp_bottom_half(void *data) -{ - struct mali_gp_core *core = (struct mali_gp_core *)data; - u32 irq_readout; - u32 irq_errors; - -#if MALI_TIMELINE_PROFILING_ENABLED -#if 0 /* Bottom half TLP logging is currently not supported */ - _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_START| MALI_PROFILING_EVENT_CHANNEL_SOFTWARE , _mali_osk_get_pid(), _mali_osk_get_tid()+11000, 0, 0, 0); -#endif -#endif - - mali_group_lock(core->group); /* Group lock grabbed in core handlers, but released in common group handler */ - - if ( MALI_FALSE == mali_group_power_is_on(core->group) ) - { - MALI_PRINT_ERROR(("Interrupt bottom half of %s when core is OFF.", core->hw_core.description)); - mali_group_unlock(core->group); - return; - } - - irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT) & MALIGP2_REG_VAL_IRQ_MASK_USED; - MALI_DEBUG_PRINT(4, ("Mali GP: Bottom half IRQ 0x%08X from core %s\n", irq_readout, core->hw_core.description)); - - if (irq_readout & (MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST|MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST)) - { - u32 core_status = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS); - if (0 == (core_status & MALIGP2_REG_VAL_STATUS_MASK_ACTIVE)) - { - mali_gp_post_process_job(core, MALI_FALSE); - MALI_DEBUG_PRINT(4, ("Mali GP: Job completed, calling group handler\n")); - mali_group_bottom_half(core->group, GROUP_EVENT_GP_JOB_COMPLETED); /* Will release group lock */ - return; - } - } - - /* - * Now lets look at the possible error cases (IRQ indicating error or timeout) - * END_CMD_LST, HANG and PLBU_OOM interrupts are not considered error. - */ - irq_errors = irq_readout & ~(MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST|MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST|MALIGP2_REG_VAL_IRQ_HANG|MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM); - if (0 != irq_errors) - { - mali_gp_post_process_job(core, MALI_FALSE); - MALI_PRINT_ERROR(("Mali GP: Unknown interrupt 0x%08X from core %s, aborting job\n", irq_readout, core->hw_core.description)); - mali_group_bottom_half(core->group, GROUP_EVENT_GP_JOB_FAILED); /* Will release group lock */ - return; - } - else if (MALI_TRUE == core->core_timed_out) /* SW timeout */ - { - if (core->timeout_job_id == mali_gp_job_get_id(core->running_job)) - { - mali_gp_post_process_job(core, MALI_FALSE); - MALI_DEBUG_PRINT(2, ("Mali GP: Job %d timed out\n", mali_gp_job_get_id(core->running_job))); - mali_group_bottom_half(core->group, GROUP_EVENT_GP_JOB_TIMED_OUT); - } - core->core_timed_out = MALI_FALSE; - return; - } - else if (irq_readout & MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM) - { - /* GP wants more memory in order to continue. - * - * This must be handled prior to HANG because this actually can - * generate a HANG while waiting for more memory. - * And it must be handled before the completion interrupts, - * since the PLBU can run out of memory after VS is complete; - * in which case the OOM must be handled before to complete the - * PLBU work. - */ - mali_gp_post_process_job(core, MALI_TRUE); - MALI_DEBUG_PRINT(3, ("Mali GP: PLBU needs more heap memory\n")); - mali_group_bottom_half(core->group, GROUP_EVENT_GP_OOM); /* Will release group lock */ - return; - } - else if (irq_readout & MALIGP2_REG_VAL_IRQ_HANG) - { - /* Just ignore hang interrupts, the job timer will detect hanging jobs anyways */ - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_HANG); - } - - /* - * The only way to get here is if we got a HANG interrupt, which we ignore, or only one of two needed END_CMD_LST interrupts. - * Re-enable interrupts and let core continue to run. - */ - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED); - mali_group_unlock(core->group); - -#if MALI_TIMELINE_PROFILING_ENABLED -#if 0 /* Bottom half TLP logging is currently not supported */ - _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_STOP| MALI_PROFILING_EVENT_CHANNEL_SOFTWARE , _mali_osk_get_pid(), _mali_osk_get_tid()+11000, 0, 0, 0); -#endif -#endif -} - -static void mali_gp_irq_probe_trigger(void *data) -{ - struct mali_gp_core *core = (struct mali_gp_core *)data; - - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED); /* @@@@ This should not be needed */ - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT, MALIGP2_REG_VAL_CMD_FORCE_HANG); - _mali_osk_mem_barrier(); -} - -static _mali_osk_errcode_t mali_gp_irq_probe_ack(void *data) -{ - struct mali_gp_core *core = (struct mali_gp_core *)data; - u32 irq_readout; - - irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_STAT); - if (MALIGP2_REG_VAL_IRQ_FORCE_HANG & irq_readout) - { - mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_FORCE_HANG); - _mali_osk_mem_barrier(); - return _MALI_OSK_ERR_OK; - } - - return _MALI_OSK_ERR_FAULT; -} - -/* ------ local helper functions below --------- */ - -static void mali_gp_post_process_job(struct mali_gp_core *core, mali_bool suspend) -{ - MALI_ASSERT_GROUP_LOCKED(core->group); - - if (NULL != core->running_job) - { - u32 val0 = 0; - u32 val1 = 0; -#if MALI_TIMELINE_PROFILING_ENABLED - u32 event_id; -#endif - -#if PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH - { - u32 src0, value0, src1, value1, sum, per_thousand, per_thousand_now, diff0, diff1; - static u32 print_nr=0; - static u32 prev0=0; - static u32 prev1=0; - if ( !(++print_nr&511) ) - { - mali_l2_cache_core_get_counter_values(mali_l2_cache_core_get_glob_l2_core(0), &src0, &value0, &src1, &value1); - MALI_DEBUG_ASSERT( src0==20 ); /* Read hits */ - MALI_DEBUG_ASSERT( src1==21 ); /* Read misses */ - - sum = value0+value1; - if ( sum > 1000000 ) - { - per_thousand = value0 / (sum/1000); - } - else - { - per_thousand = (value0*1000) / (sum); - } - diff0 = value0-prev0; - diff1 = value1-prev1; - - sum = diff0 + diff1 ; - if ( sum > 1000000 ) - { - per_thousand_now = diff0 / (sum/1000); - } - else - { - per_thousand_now = (diff0*1000) / (sum); - } - - prev0=value0; - prev1=value1; - if (per_thousand_now<=1000) - { - MALI_DEBUG_PRINT(2, ("Mali L2: Read hits/misses: %d/%d = %d thousand_parts total, since previous: %d\n", value0, value1, per_thousand, per_thousand_now)); - } - - } - } -#endif - - if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used) - { - val0 = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE); - if (mali_gp_job_get_perf_counter_flag(core->running_job) && - _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE && mali_gp_job_get_perf_counter_src0(core->running_job) == core->counter_src0_used) - { - /* We retrieved the counter that user space asked for, so return the value through the job object */ - mali_gp_job_set_perf_counter_value0(core->running_job, val0); - } - else - { - /* User space asked for a counter, but this is not what we retrived (overridden by counter src set on core) */ - mali_gp_job_set_perf_counter_value0(core->running_job, MALI_HW_CORE_INVALID_VALUE); - } - -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_osk_profiling_report_hw_counter(COUNTER_VP_C0, val0); -#endif - - } - - if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used) - { - val1 = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE); - if (mali_gp_job_get_perf_counter_flag(core->running_job) && - _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE && mali_gp_job_get_perf_counter_src1(core->running_job) == core->counter_src1_used) - { - /* We retrieved the counter that user space asked for, so return the value through the job object */ - mali_gp_job_set_perf_counter_value1(core->running_job, val1); - } - else - { - /* User space asked for a counter, but this is not what we retrieved (overridden by counter src set on core) */ - mali_gp_job_set_perf_counter_value1(core->running_job, MALI_HW_CORE_INVALID_VALUE); - } - -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_osk_profiling_report_hw_counter(COUNTER_VP_C1, val1); -#endif - } - -#if MALI_TIMELINE_PROFILING_ENABLED - if (MALI_TRUE == suspend) - { - event_id = MALI_PROFILING_EVENT_TYPE_SUSPEND|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0); - } - else - { - event_id = MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0); - } - _mali_osk_profiling_add_event(event_id, val0, val1, core->counter_src0_used | (core->counter_src1_used << 8), 0, 0); -#endif - - mali_gp_job_set_current_heap_addr(core->running_job, - mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR)); - - if (MALI_TRUE != suspend) - { - /* We are no longer running a job... */ - core->running_job = NULL; - _mali_osk_timer_del(core->timeout_timer); - } - } -} - -/* callback function for gp core timeout */ -static void mali_gp_timeout(void *data) -{ - struct mali_gp_core * core = ((struct mali_gp_core *)data); - - MALI_DEBUG_PRINT(3, ("Mali GP: TIMEOUT callback \n")); - core->core_timed_out = MALI_TRUE; - _mali_osk_irq_schedulework(core->irq); -} - -#if 0 -void mali_gp_print_state(struct mali_gp_core *core) -{ - MALI_DEBUG_PRINT(2, ("Mali GP: State: 0x%08x\n", mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS) )); -} -#endif - -#if MALI_STATE_TRACKING -u32 mali_gp_dump_state(struct mali_gp_core *core, char *buf, u32 size) -{ - int n = 0; - - n += _mali_osk_snprintf(buf + n, size - n, "\tGP: %s\n", core->hw_core.description); - - return n; -} -#endif diff --git a/drivers/media/video/samsung/mali/common/mali_gp.h b/drivers/media/video/samsung/mali/common/mali_gp.h deleted file mode 100644 index 3175b75..0000000 --- a/drivers/media/video/samsung/mali/common/mali_gp.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2011-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_GP_H__ -#define __MALI_GP_H__ - -#include "mali_osk.h" -#include "mali_gp_job.h" - -struct mali_gp_core; -struct mali_group; - -_mali_osk_errcode_t mali_gp_initialize(void); -void mali_gp_terminate(void); - -struct mali_gp_core *mali_gp_create(const _mali_osk_resource_t * resource, struct mali_group *group); -void mali_gp_delete(struct mali_gp_core *core); - -void mali_gp_stop_bus(struct mali_gp_core *core); -_mali_osk_errcode_t mali_gp_stop_bus_wait(struct mali_gp_core *core); -void mali_gp_hard_reset(struct mali_gp_core *core); -_mali_osk_errcode_t mali_gp_reset(struct mali_gp_core *core); - -void mali_gp_job_start(struct mali_gp_core *core, struct mali_gp_job *job); -void mali_gp_resume_with_new_heap(struct mali_gp_core *core, u32 start_addr, u32 end_addr); - -void mali_gp_abort_job(struct mali_gp_core *core); - -u32 mali_gp_core_get_version(struct mali_gp_core *core); - -mali_bool mali_gp_core_set_counter_src0(struct mali_gp_core *core, u32 counter); -mali_bool mali_gp_core_set_counter_src1(struct mali_gp_core *core, u32 counter); -u32 mali_gp_core_get_counter_src0(struct mali_gp_core *core); -u32 mali_gp_core_get_counter_src1(struct mali_gp_core *core); -struct mali_gp_core *mali_gp_get_global_gp_core(void); - -u32 mali_gp_dump_state(struct mali_gp_core *core, char *buf, u32 size); - -#endif /* __MALI_GP_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_gp_job.c b/drivers/media/video/samsung/mali/common/mali_gp_job.c deleted file mode 100644 index abe1d93..0000000 --- a/drivers/media/video/samsung/mali/common/mali_gp_job.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2011-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_gp_job.h" -#include "mali_osk.h" -#include "mali_osk_list.h" -#include "mali_uk_types.h" - -struct mali_gp_job *mali_gp_job_create(struct mali_session_data *session, _mali_uk_gp_start_job_s *args, u32 id) -{ - struct mali_gp_job *job; - - job = _mali_osk_malloc(sizeof(struct mali_gp_job)); - if (NULL != job) - { - _mali_osk_list_init(&job->list); - job->session = session; - job->id = id; - job->user_id = args->user_job_ptr; - _mali_osk_memcpy(job->frame_registers, args->frame_registers, sizeof(job->frame_registers)); - job->heap_current_addr = args->frame_registers[4]; - job->perf_counter_flag = args->perf_counter_flag; - job->perf_counter_src0 = args->perf_counter_src0; - job->perf_counter_src1 = args->perf_counter_src1; - job->perf_counter_value0 = 0; - job->perf_counter_value1 = 0; - - job->pid = _mali_osk_get_pid(); - job->tid = _mali_osk_get_tid(); - job->frame_builder_id = args->frame_builder_id; - job->flush_id = args->flush_id; - - return job; - } - - return NULL; -} - -void mali_gp_job_delete(struct mali_gp_job *job) -{ - _mali_osk_free(job); -} diff --git a/drivers/media/video/samsung/mali/common/mali_gp_job.h b/drivers/media/video/samsung/mali/common/mali_gp_job.h deleted file mode 100644 index 9c29f1c..0000000 --- a/drivers/media/video/samsung/mali/common/mali_gp_job.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2011-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_GP_JOB_H__ -#define __MALI_GP_JOB_H__ - -#include "mali_osk.h" -#include "mali_osk_list.h" -#include "mali_uk_types.h" -#include "mali_session.h" - -/** - * The structure represends a GP job, including all sub-jobs - * (This struct unfortunatly needs to be public because of how the _mali_osk_list_* - * mechanism works) - */ -struct mali_gp_job -{ - _mali_osk_list_t list; /**< Used to link jobs together in the scheduler queue */ - struct mali_session_data *session; /**< Session which submitted this job */ - u32 id; /**< identifier for this job in kernel space (sequential numbering) */ - u32 user_id; /**< identifier for the job in user space */ - u32 frame_registers[MALIGP2_NUM_REGS_FRAME]; /**< core specific registers associated with this job, see ARM DDI0415A */ - u32 heap_current_addr; /**< Holds the current HEAP address when the job has completed */ - u32 perf_counter_flag; /**< bitmask indicating which performance counters to enable, see \ref _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE and related macro definitions */ - u32 perf_counter_src0; /**< source id for performance counter 0 (see ARM DDI0415A, Table 3-60) */ - u32 perf_counter_src1; /**< source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */ - u32 perf_counter_value0; /**< Value of performance counter 0 (to be returned to user space) */ - u32 perf_counter_value1; /**< Value of performance counter 1 (to be returned to user space) */ - u32 pid; /**< Process ID of submitting process */ - u32 tid; /**< Thread ID of submitting thread */ - u32 frame_builder_id; /**< id of the originating frame builder */ - u32 flush_id; /**< flush id within the originating frame builder */ -}; - -struct mali_gp_job *mali_gp_job_create(struct mali_session_data *session, _mali_uk_gp_start_job_s *args, u32 id); -void mali_gp_job_delete(struct mali_gp_job *job); - -MALI_STATIC_INLINE u32 mali_gp_job_get_id(struct mali_gp_job *job) -{ - return (NULL == job) ? 0 : job->id; -} - -MALI_STATIC_INLINE u32 mali_gp_job_get_user_id(struct mali_gp_job *job) -{ - return job->user_id; -} - -MALI_STATIC_INLINE u32 mali_gp_job_get_frame_builder_id(struct mali_gp_job *job) -{ - return job->frame_builder_id; -} - -MALI_STATIC_INLINE u32 mali_gp_job_get_flush_id(struct mali_gp_job *job) -{ - return job->flush_id; -} - -MALI_STATIC_INLINE u32* mali_gp_job_get_frame_registers(struct mali_gp_job *job) -{ - return job->frame_registers; -} - -MALI_STATIC_INLINE struct mali_session_data *mali_gp_job_get_session(struct mali_gp_job *job) -{ - return job->session; -} - -MALI_STATIC_INLINE mali_bool mali_gp_job_has_vs_job(struct mali_gp_job *job) -{ - return (job->frame_registers[0] != job->frame_registers[1]) ? MALI_TRUE : MALI_FALSE; -} - -MALI_STATIC_INLINE mali_bool mali_gp_job_has_plbu_job(struct mali_gp_job *job) -{ - return (job->frame_registers[2] != job->frame_registers[3]) ? MALI_TRUE : MALI_FALSE; -} - -MALI_STATIC_INLINE u32 mali_gp_job_get_current_heap_addr(struct mali_gp_job *job) -{ - return job->heap_current_addr; -} - -MALI_STATIC_INLINE void mali_gp_job_set_current_heap_addr(struct mali_gp_job *job, u32 heap_addr) -{ - job->heap_current_addr = heap_addr; -} - -MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_flag(struct mali_gp_job *job) -{ - return job->perf_counter_flag; -} - -MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_src0(struct mali_gp_job *job) -{ - return job->perf_counter_src0; -} - -MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_src1(struct mali_gp_job *job) -{ - return job->perf_counter_src1; -} - -MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_value0(struct mali_gp_job *job) -{ - return job->perf_counter_value0; -} - -MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_value1(struct mali_gp_job *job) -{ - return job->perf_counter_value1; -} - -MALI_STATIC_INLINE void mali_gp_job_set_perf_counter_value0(struct mali_gp_job *job, u32 value) -{ - job->perf_counter_value0 = value; -} - -MALI_STATIC_INLINE void mali_gp_job_set_perf_counter_value1(struct mali_gp_job *job, u32 value) -{ - job->perf_counter_value1 = value; -} - -#endif /* __MALI_GP_JOB_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_gp_scheduler.c b/drivers/media/video/samsung/mali/common/mali_gp_scheduler.c deleted file mode 100644 index f06d899..0000000 --- a/drivers/media/video/samsung/mali/common/mali_gp_scheduler.c +++ /dev/null @@ -1,443 +0,0 @@ -/* - * Copyright (C) 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_gp_scheduler.h" -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "mali_osk_list.h" -#include "mali_scheduler.h" -#include "mali_gp.h" -#include "mali_gp_job.h" -#include "mali_group.h" -#include "mali_cluster.h" - -enum mali_gp_slot_state -{ - MALI_GP_SLOT_STATE_IDLE, - MALI_GP_SLOT_STATE_WORKING, -}; - -/* A render slot is an entity which jobs can be scheduled onto */ -struct mali_gp_slot -{ - struct mali_group *group; - /* - * We keep track of the state here as well as in the group object - * so we don't need to take the group lock so often (and also avoid clutter with the working lock) - */ - enum mali_gp_slot_state state; - u32 returned_cookie; -}; - -static u32 gp_version = 0; -static _MALI_OSK_LIST_HEAD(job_queue); /* List of jobs with some unscheduled work */ -static struct mali_gp_slot slot; - -/* Variables to allow safe pausing of the scheduler */ -static _mali_osk_wait_queue_t *gp_scheduler_working_wait_queue = NULL; -static u32 pause_count = 0; - -static mali_bool mali_gp_scheduler_is_suspended(void); - -static _mali_osk_lock_t *gp_scheduler_lock = NULL; -/* Contains tid of thread that locked the scheduler or 0, if not locked */ - -_mali_osk_errcode_t mali_gp_scheduler_initialize(void) -{ - u32 i; - - _MALI_OSK_INIT_LIST_HEAD(&job_queue); - - gp_scheduler_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_SCHEDULER); - if (NULL == gp_scheduler_lock) - { - return _MALI_OSK_ERR_NOMEM; - } - - gp_scheduler_working_wait_queue = _mali_osk_wait_queue_init(); - if (NULL == gp_scheduler_working_wait_queue) - { - _mali_osk_lock_term(gp_scheduler_lock); - return _MALI_OSK_ERR_NOMEM; - } - - /* Find all the available GP cores */ - for (i = 0; i < mali_cluster_get_glob_num_clusters(); i++) - { - u32 group_id = 0; - struct mali_cluster *curr_cluster = mali_cluster_get_global_cluster(i); - struct mali_group *group = mali_cluster_get_group(curr_cluster, group_id); - while (NULL != group) - { - struct mali_gp_core *gp_core = mali_group_get_gp_core(group); - if (NULL != gp_core) - { - if (0 == gp_version) - { - /* Retrieve GP version */ - gp_version = mali_gp_core_get_version(gp_core); - } - slot.group = group; - slot.state = MALI_GP_SLOT_STATE_IDLE; - break; /* There are only one GP, no point in looking for more */ - } - group_id++; - group = mali_cluster_get_group(curr_cluster, group_id); - } - } - - return _MALI_OSK_ERR_OK; -} - -void mali_gp_scheduler_terminate(void) -{ - _mali_osk_wait_queue_term(gp_scheduler_working_wait_queue); - _mali_osk_lock_term(gp_scheduler_lock); -} - -MALI_STATIC_INLINE void mali_gp_scheduler_lock(void) -{ - if(_MALI_OSK_ERR_OK != _mali_osk_lock_wait(gp_scheduler_lock, _MALI_OSK_LOCKMODE_RW)) - { - /* Non-interruptable lock failed: this should never happen. */ - MALI_DEBUG_ASSERT(0); - } - MALI_DEBUG_PRINT(5, ("Mali GP scheduler: GP scheduler lock taken\n")); -} - -MALI_STATIC_INLINE void mali_gp_scheduler_unlock(void) -{ - MALI_DEBUG_PRINT(5, ("Mali GP scheduler: Releasing GP scheduler lock\n")); - _mali_osk_lock_signal(gp_scheduler_lock, _MALI_OSK_LOCKMODE_RW); -} - -#ifdef DEBUG -MALI_STATIC_INLINE void mali_gp_scheduler_assert_locked(void) -{ - MALI_DEBUG_ASSERT_LOCK_HELD(gp_scheduler_lock); -} -#define MALI_ASSERT_GP_SCHEDULER_LOCKED() mali_gp_scheduler_assert_locked() -#else -#define MALI_ASSERT_GP_SCHEDULER_LOCKED() -#endif - -static void mali_gp_scheduler_schedule(void) -{ - struct mali_gp_job *job; - - MALI_ASSERT_GP_SCHEDULER_LOCKED(); - - if (0 < pause_count || MALI_GP_SLOT_STATE_IDLE != slot.state || _mali_osk_list_empty(&job_queue)) - { - MALI_DEBUG_PRINT(4, ("Mali GP scheduler: Nothing to schedule (paused=%u, idle slots=%u)\n", - pause_count, MALI_GP_SLOT_STATE_IDLE == slot.state ? 1 : 0)); - return; /* Nothing to do, so early out */ - } - - job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_gp_job, list); - - MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Starting job %u (0x%08X)\n", mali_gp_job_get_id(job), job)); - if (_MALI_OSK_ERR_OK == mali_group_start_gp_job(slot.group, job)) - { - /* Mark slot as busy */ - slot.state = MALI_GP_SLOT_STATE_WORKING; - - /* Remove from queue of unscheduled jobs */ - _mali_osk_list_del(&job->list); - } - else - { - MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Failed to start GP job\n")); - } -} - -static void mali_gp_scheduler_return_job_to_user(struct mali_gp_job *job, mali_bool success) -{ - _mali_osk_notification_t *notobj = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_FINISHED, sizeof(_mali_uk_gp_job_finished_s)); - if (NULL != notobj) - { - _mali_uk_gp_job_finished_s *jobres = notobj->result_buffer; - _mali_osk_memset(jobres, 0, sizeof(_mali_uk_gp_job_finished_s)); /* @@@@ can be removed once we initialize all members in this struct */ - jobres->user_job_ptr = mali_gp_job_get_user_id(job); - if (MALI_TRUE == success) - { - jobres->status = _MALI_UK_JOB_STATUS_END_SUCCESS; - } - else - { - jobres->status = _MALI_UK_JOB_STATUS_END_UNKNOWN_ERR; - } - - jobres->heap_current_addr = mali_gp_job_get_current_heap_addr(job); - jobres->perf_counter0 = mali_gp_job_get_perf_counter_value0(job); - jobres->perf_counter1 = mali_gp_job_get_perf_counter_value1(job); - - mali_session_send_notification(mali_gp_job_get_session(job), notobj); - } - else - { - MALI_PRINT_ERROR(("Mali GP scheduler: Unable to allocate notification object\n")); - } - - mali_gp_job_delete(job); -} - - -void mali_gp_scheduler_do_schedule(void) -{ - mali_gp_scheduler_lock(); - - mali_gp_scheduler_schedule(); - - mali_gp_scheduler_unlock(); -} - -void mali_gp_scheduler_job_done(struct mali_group *group, struct mali_gp_job *job, mali_bool success) -{ - MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Job %u (0x%08X) completed (%s)\n", mali_gp_job_get_id(job), job, success ? "success" : "failure")); - - mali_gp_scheduler_lock(); - - /* Mark slot as idle again */ - slot.state = MALI_GP_SLOT_STATE_IDLE; - - /* If paused, then this was the last job, so wake up sleeping workers */ - if (pause_count > 0) - { - _mali_osk_wait_queue_wake_up(gp_scheduler_working_wait_queue); - } - else - { - mali_gp_scheduler_schedule(); - } - - mali_gp_scheduler_unlock(); - - mali_gp_scheduler_return_job_to_user(job, success); -} - -void mali_gp_scheduler_oom(struct mali_group *group, struct mali_gp_job *job) -{ - _mali_osk_notification_t *notobj; - - notobj = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_STALLED, sizeof(_mali_uk_gp_job_suspended_s)); - - if (NULL != notobj) - { - _mali_uk_gp_job_suspended_s * jobres; - - mali_gp_scheduler_lock(); - - jobres = (_mali_uk_gp_job_suspended_s *)notobj->result_buffer; - - jobres->user_job_ptr = mali_gp_job_get_user_id(job); - jobres->reason = _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY; - jobres->cookie = mali_gp_job_get_id(job); - slot.returned_cookie = jobres->cookie; - - mali_session_send_notification(mali_gp_job_get_session(job), notobj); - - mali_gp_scheduler_unlock(); - } - - /* - * If this function failed, then we could return the job to user space right away, - * but there is a job timer anyway that will do that eventually. - * This is not exactly a common case anyway. - */ -} - -void mali_gp_scheduler_suspend(void) -{ - mali_gp_scheduler_lock(); - pause_count++; /* Increment the pause_count so that no more jobs will be scheduled */ - mali_gp_scheduler_unlock(); - - _mali_osk_wait_queue_wait_event(gp_scheduler_working_wait_queue, mali_gp_scheduler_is_suspended); -} - -void mali_gp_scheduler_resume(void) -{ - mali_gp_scheduler_lock(); - pause_count--; /* Decrement pause_count to allow scheduling again (if it reaches 0) */ - if (0 == pause_count) - { - mali_gp_scheduler_schedule(); - } - mali_gp_scheduler_unlock(); -} - -_mali_osk_errcode_t _mali_ukk_gp_start_job(_mali_uk_gp_start_job_s *args) -{ - struct mali_session_data *session; - struct mali_gp_job *job; - - MALI_DEBUG_ASSERT_POINTER(args); - - if (NULL == args->ctx) - { - return _MALI_OSK_ERR_INVALID_ARGS; - } - - session = (struct mali_session_data*)args->ctx; - if (NULL == session) - { - return _MALI_OSK_ERR_FAULT; - } - - job = mali_gp_job_create(session, args, mali_scheduler_get_new_id()); - if (NULL == job) - { - return _MALI_OSK_ERR_NOMEM; - } - -#if PROFILING_SKIP_PP_AND_GP_JOBS -#warning GP jobs will not be executed - mali_gp_scheduler_return_job_to_user(job, MALI_TRUE); - return _MALI_OSK_ERR_OK; -#endif - - mali_gp_scheduler_lock(); - - _mali_osk_list_addtail(&job->list, &job_queue); - - MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Job %u (0x%08X) queued\n", mali_gp_job_get_id(job), job)); - - mali_gp_scheduler_schedule(); - - mali_gp_scheduler_unlock(); - - return _MALI_OSK_ERR_OK; -} - -_mali_osk_errcode_t _mali_ukk_get_gp_number_of_cores(_mali_uk_get_gp_number_of_cores_s *args) -{ - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - args->number_of_cores = 1; - return _MALI_OSK_ERR_OK; -} - -_mali_osk_errcode_t _mali_ukk_get_gp_core_version(_mali_uk_get_gp_core_version_s *args) -{ - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - args->version = gp_version; - return _MALI_OSK_ERR_OK; -} - -_mali_osk_errcode_t _mali_ukk_gp_suspend_response(_mali_uk_gp_suspend_response_s *args) -{ - struct mali_session_data *session; - _mali_osk_errcode_t ret = _MALI_OSK_ERR_FAULT; - - MALI_DEBUG_ASSERT_POINTER(args); - - if (NULL == args->ctx) - { - return _MALI_OSK_ERR_INVALID_ARGS; - } - - session = (struct mali_session_data*)args->ctx; - if (NULL == session) - { - return _MALI_OSK_ERR_FAULT; - } - - mali_gp_scheduler_lock(); - - /* Make sure that the cookie returned by user space is the same as we provided in the first place */ - if (args->cookie != slot.returned_cookie) - { - MALI_DEBUG_PRINT(2, ("Mali GP scheduler: Got an illegal cookie from user space, expected %u but got %u (job id)\n", slot.returned_cookie, args->cookie)) ; - mali_gp_scheduler_unlock(); - return _MALI_OSK_ERR_FAULT; - } - - mali_gp_scheduler_unlock(); - - switch (args->code) - { - case _MALIGP_JOB_RESUME_WITH_NEW_HEAP: - MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Resuming job %u with new heap; 0x%08X - 0x%08X\n", args->cookie, args->arguments[0], args->arguments[1])); - mali_group_resume_gp_with_new_heap(slot.group, args->cookie, args->arguments[0], args->arguments[1]); - ret = _MALI_OSK_ERR_OK; - break; - - case _MALIGP_JOB_ABORT: - MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Aborting job %u, no new heap provided\n", args->cookie)); - mali_group_abort_gp_job(slot.group, args->cookie); - ret = _MALI_OSK_ERR_OK; - break; - - default: - MALI_PRINT_ERROR(("Mali GP scheduler: Wrong suspend response from user space\n")); - ret = _MALI_OSK_ERR_FAULT; - break; - } - - return ret; - -} - -void mali_gp_scheduler_abort_session(struct mali_session_data *session) -{ - struct mali_gp_job *job, *tmp; - - mali_gp_scheduler_lock(); - MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Aborting all jobs from session 0x%08x\n", session)); - - /* Check queue for jobs and remove */ - _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &job_queue, struct mali_gp_job, list) - { - if (mali_gp_job_get_session(job) == session) - { - MALI_DEBUG_PRINT(4, ("Mali GP scheduler: Removing GP job 0x%08x from queue\n", job)); - _mali_osk_list_del(&(job->list)); - mali_gp_job_delete(job); - } - } - - mali_gp_scheduler_unlock(); - - /* Abort running jobs from this session. It is safe to do this outside - * the scheduler lock as there is only one GP core, and the queue has - * already been emptied, as long as there are no new jobs coming in - * from user space. */ - mali_group_abort_session(slot.group, session); -} - -static mali_bool mali_gp_scheduler_is_suspended(void) -{ - mali_bool ret; - - mali_gp_scheduler_lock(); - ret = pause_count > 0 && slot.state == MALI_GP_SLOT_STATE_IDLE; - mali_gp_scheduler_unlock(); - - return ret; -} - - -#if MALI_STATE_TRACKING -u32 mali_gp_scheduler_dump_state(char *buf, u32 size) -{ - int n = 0; - - n += _mali_osk_snprintf(buf + n, size - n, "GP\n"); - n += _mali_osk_snprintf(buf + n, size - n, "\tQueue is %s\n", _mali_osk_list_empty(&job_queue) ? "empty" : "not empty"); - - n += mali_group_dump_state(slot.group, buf + n, size - n); - n += _mali_osk_snprintf(buf + n, size - n, "\t\tState: %d\n", mali_group_gp_state(slot.group)); - n += _mali_osk_snprintf(buf + n, size - n, "\n"); - - return n; -} -#endif diff --git a/drivers/media/video/samsung/mali/common/mali_gp_scheduler.h b/drivers/media/video/samsung/mali/common/mali_gp_scheduler.h deleted file mode 100644 index ef58509..0000000 --- a/drivers/media/video/samsung/mali/common/mali_gp_scheduler.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_GP_SCHEDULER_H__ -#define __MALI_GP_SCHEDULER_H__ - -#include "mali_osk.h" -#include "mali_cluster.h" -#include "mali_gp_job.h" - -_mali_osk_errcode_t mali_gp_scheduler_initialize(void); -void mali_gp_scheduler_terminate(void); - -void mali_gp_scheduler_do_schedule(void); -void mali_gp_scheduler_job_done(struct mali_group *group, struct mali_gp_job *job, mali_bool success); -void mali_gp_scheduler_oom(struct mali_group *group, struct mali_gp_job *job); -void mali_gp_scheduler_abort_session(struct mali_session_data *session); -u32 mali_gp_scheduler_dump_state(char *buf, u32 size); - -void mali_gp_scheduler_suspend(void); -void mali_gp_scheduler_resume(void); - -#endif /* __MALI_GP_SCHEDULER_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_group.c b/drivers/media/video/samsung/mali/common/mali_group.c deleted file mode 100644 index 94bf774..0000000 --- a/drivers/media/video/samsung/mali/common/mali_group.c +++ /dev/null @@ -1,841 +0,0 @@ -/* - * Copyright (C) 2011-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_kernel_common.h" -#include "mali_group.h" -#include "mali_osk.h" -#include "mali_cluster.h" -#include "mali_gp.h" -#include "mali_pp.h" -#include "mali_mmu.h" -#include "mali_gp_scheduler.h" -#include "mali_pp_scheduler.h" -#include "mali_pm.h" - -/* - * The group object is the most important object in the device driver, - * and acts as the center of many HW operations. - * The reason for this is that operations on the MMU will affect all - * cores connected to this MMU (a group is defined by the MMU and the - * cores which are connected to this). - * The group lock is thus the most important lock, followed by the - * GP and PP scheduler locks. They must be taken in the following - * order: - * GP/PP lock first, then group lock(s). - */ - -/** - * The structure represents a render group - * A render group is defined by all the cores that share the same Mali MMU - */ - -struct mali_group -{ - struct mali_cluster *cluster; - - struct mali_mmu_core *mmu; - struct mali_session_data *session; - int page_dir_ref_count; - mali_bool power_is_on; -#if defined(USING_MALI200) - mali_bool pagedir_activation_failed; -#endif - - struct mali_gp_core *gp_core; - enum mali_group_core_state gp_state; - struct mali_gp_job *gp_running_job; - - struct mali_pp_core *pp_core; - enum mali_group_core_state pp_state; - struct mali_pp_job *pp_running_job; - u32 pp_running_sub_job; - - _mali_osk_lock_t *lock; -}; - -static struct mali_group *mali_global_groups[MALI_MAX_NUMBER_OF_GROUPS]; -static u32 mali_global_num_groups = 0; - -enum mali_group_activate_pd_status -{ - MALI_GROUP_ACTIVATE_PD_STATUS_FAILED, - MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD, - MALI_GROUP_ACTIVATE_PD_STATUS_OK_SWITCHED_PD, -}; - -/* local helper functions */ -static enum mali_group_activate_pd_status mali_group_activate_page_directory(struct mali_group *group, struct mali_session_data *session); -static void mali_group_deactivate_page_directory(struct mali_group *group, struct mali_session_data *session); -static void mali_group_recovery_reset(struct mali_group *group); -static void mali_group_complete_jobs(struct mali_group *group, mali_bool complete_gp, mali_bool complete_pp, bool success); - -void mali_group_lock(struct mali_group *group) -{ - if(_MALI_OSK_ERR_OK != _mali_osk_lock_wait(group->lock, _MALI_OSK_LOCKMODE_RW)) - { - /* Non-interruptable lock failed: this should never happen. */ - MALI_DEBUG_ASSERT(0); - } - MALI_DEBUG_PRINT(5, ("Mali group: Group lock taken 0x%08X\n", group)); -} - -void mali_group_unlock(struct mali_group *group) -{ - MALI_DEBUG_PRINT(5, ("Mali group: Releasing group lock 0x%08X\n", group)); - _mali_osk_lock_signal(group->lock, _MALI_OSK_LOCKMODE_RW); -} - -#ifdef DEBUG -void mali_group_assert_locked(struct mali_group *group) -{ - MALI_DEBUG_ASSERT_LOCK_HELD(group->lock); -} -#endif - - -struct mali_group *mali_group_create(struct mali_cluster *cluster, struct mali_mmu_core *mmu) -{ - struct mali_group *group = NULL; - - if (mali_global_num_groups >= MALI_MAX_NUMBER_OF_GROUPS) - { - MALI_PRINT_ERROR(("Mali group: Too many group objects created\n")); - return NULL; - } - - group = _mali_osk_malloc(sizeof(struct mali_group)); - if (NULL != group) - { - _mali_osk_memset(group, 0, sizeof(struct mali_group)); - group->lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_GROUP); - if (NULL != group->lock) - { - group->cluster = cluster; - group->mmu = mmu; /* This group object now owns the MMU object */ - group->session = NULL; - group->page_dir_ref_count = 0; - group->power_is_on = MALI_TRUE; - - group->gp_state = MALI_GROUP_CORE_STATE_IDLE; - group->pp_state = MALI_GROUP_CORE_STATE_IDLE; -#if defined(USING_MALI200) - group->pagedir_activation_failed = MALI_FALSE; -#endif - mali_global_groups[mali_global_num_groups] = group; - mali_global_num_groups++; - - return group; - } - _mali_osk_free(group); - } - - return NULL; -} - -void mali_group_add_gp_core(struct mali_group *group, struct mali_gp_core* gp_core) -{ - /* This group object now owns the GP core object */ - group->gp_core = gp_core; -} - -void mali_group_add_pp_core(struct mali_group *group, struct mali_pp_core* pp_core) -{ - /* This group object now owns the PP core object */ - group->pp_core = pp_core; -} - -void mali_group_delete(struct mali_group *group) -{ - u32 i; - - /* Delete the resources that this group owns */ - if (NULL != group->gp_core) - { - mali_gp_delete(group->gp_core); - } - - if (NULL != group->pp_core) - { - mali_pp_delete(group->pp_core); - } - - if (NULL != group->mmu) - { - mali_mmu_delete(group->mmu); - } - - for (i = 0; i < mali_global_num_groups; i++) - { - if (mali_global_groups[i] == group) - { - mali_global_groups[i] = NULL; - mali_global_num_groups--; - break; - } - } - - _mali_osk_lock_term(group->lock); - - _mali_osk_free(group); -} - -/* Called from mali_cluster_reset() when the system is re-turned on */ -void mali_group_reset(struct mali_group *group) -{ - mali_group_lock(group); - - group->session = NULL; - - if (NULL != group->mmu) - { - mali_mmu_reset(group->mmu); - } - - if (NULL != group->gp_core) - { - mali_gp_reset(group->gp_core); - } - - if (NULL != group->pp_core) - { - mali_pp_reset(group->pp_core); - } - - mali_group_unlock(group); -} - -struct mali_gp_core* mali_group_get_gp_core(struct mali_group *group) -{ - return group->gp_core; -} - -struct mali_pp_core* mali_group_get_pp_core(struct mali_group *group) -{ - return group->pp_core; -} - -_mali_osk_errcode_t mali_group_start_gp_job(struct mali_group *group, struct mali_gp_job *job) -{ - struct mali_session_data *session; - enum mali_group_activate_pd_status activate_status; - - MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->gp_state); - - mali_pm_core_event(MALI_CORE_EVENT_GP_START); - - session = mali_gp_job_get_session(job); - - mali_group_lock(group); - - mali_cluster_l2_cache_invalidate_all(group->cluster, mali_gp_job_get_id(job)); - - activate_status = mali_group_activate_page_directory(group, session); - if (MALI_GROUP_ACTIVATE_PD_STATUS_FAILED != activate_status) - { - /* if session is NOT kept Zapping is done as part of session switch */ - if (MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD == activate_status) - { - mali_mmu_zap_tlb_without_stall(group->mmu); - } - mali_gp_job_start(group->gp_core, job); - group->gp_running_job = job; - group->gp_state = MALI_GROUP_CORE_STATE_WORKING; - - mali_group_unlock(group); - - return _MALI_OSK_ERR_OK; - } - -#if defined(USING_MALI200) - group->pagedir_activation_failed = MALI_TRUE; -#endif - - mali_group_unlock(group); - - mali_pm_core_event(MALI_CORE_EVENT_GP_STOP); /* Failed to start, so "cancel" the MALI_CORE_EVENT_GP_START */ - return _MALI_OSK_ERR_FAULT; -} - -_mali_osk_errcode_t mali_group_start_pp_job(struct mali_group *group, struct mali_pp_job *job, u32 sub_job) -{ - struct mali_session_data *session; - enum mali_group_activate_pd_status activate_status; - - MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->pp_state); - - mali_pm_core_event(MALI_CORE_EVENT_PP_START); - - session = mali_pp_job_get_session(job); - - mali_group_lock(group); - - mali_cluster_l2_cache_invalidate_all(group->cluster, mali_pp_job_get_id(job)); - - activate_status = mali_group_activate_page_directory(group, session); - if (MALI_GROUP_ACTIVATE_PD_STATUS_FAILED != activate_status) - { - /* if session is NOT kept Zapping is done as part of session switch */ - if (MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD == activate_status) - { - MALI_DEBUG_PRINT(3, ("PP starting job PD_Switch 0 Flush 1 Zap 1\n")); - mali_mmu_zap_tlb_without_stall(group->mmu); - } - mali_pp_job_start(group->pp_core, job, sub_job); - group->pp_running_job = job; - group->pp_running_sub_job = sub_job; - group->pp_state = MALI_GROUP_CORE_STATE_WORKING; - - mali_group_unlock(group); - - return _MALI_OSK_ERR_OK; - } - -#if defined(USING_MALI200) - group->pagedir_activation_failed = MALI_TRUE; -#endif - - mali_group_unlock(group); - - mali_pm_core_event(MALI_CORE_EVENT_PP_STOP); /* Failed to start, so "cancel" the MALI_CORE_EVENT_PP_START */ - return _MALI_OSK_ERR_FAULT; -} - -void mali_group_resume_gp_with_new_heap(struct mali_group *group, u32 job_id, u32 start_addr, u32 end_addr) -{ - mali_group_lock(group); - - if (group->gp_state != MALI_GROUP_CORE_STATE_OOM || - mali_gp_job_get_id(group->gp_running_job) != job_id) - { - mali_group_unlock(group); - return; /* Illegal request or job has already been aborted */ - } - - mali_cluster_l2_cache_invalidate_all_force(group->cluster); - mali_mmu_zap_tlb_without_stall(group->mmu); - - mali_gp_resume_with_new_heap(group->gp_core, start_addr, end_addr); - group->gp_state = MALI_GROUP_CORE_STATE_WORKING; - - mali_group_unlock(group); -} - -void mali_group_abort_gp_job(struct mali_group *group, u32 job_id) -{ - mali_group_lock(group); - - if (group->gp_state == MALI_GROUP_CORE_STATE_IDLE || - mali_gp_job_get_id(group->gp_running_job) != job_id) - { - mali_group_unlock(group); - return; /* No need to cancel or job has already been aborted or completed */ - } - - mali_group_complete_jobs(group, MALI_TRUE, MALI_FALSE, MALI_FALSE); /* Will release group lock */ -} - -void mali_group_abort_pp_job(struct mali_group *group, u32 job_id) -{ - mali_group_lock(group); - - if (group->pp_state == MALI_GROUP_CORE_STATE_IDLE || - mali_pp_job_get_id(group->pp_running_job) != job_id) - { - mali_group_unlock(group); - return; /* No need to cancel or job has already been aborted or completed */ - } - - mali_group_complete_jobs(group, MALI_FALSE, MALI_TRUE, MALI_FALSE); /* Will release group lock */ -} - -void mali_group_abort_session(struct mali_group *group, struct mali_session_data *session) -{ - struct mali_gp_job *gp_job; - struct mali_pp_job *pp_job; - u32 gp_job_id = 0; - u32 pp_job_id = 0; - mali_bool abort_pp = MALI_FALSE; - mali_bool abort_gp = MALI_FALSE; - - mali_group_lock(group); - - gp_job = group->gp_running_job; - pp_job = group->pp_running_job; - - if (gp_job && mali_gp_job_get_session(gp_job) == session) - { - MALI_DEBUG_PRINT(4, ("Aborting GP job 0x%08x from session 0x%08x\n", gp_job, session)); - - gp_job_id = mali_gp_job_get_id(gp_job); - abort_gp = MALI_TRUE; - } - - if (pp_job && mali_pp_job_get_session(pp_job) == session) - { - MALI_DEBUG_PRINT(4, ("Mali group: Aborting PP job 0x%08x from session 0x%08x\n", pp_job, session)); - - pp_job_id = mali_pp_job_get_id(pp_job); - abort_pp = MALI_TRUE; - } - - mali_group_unlock(group); - - /* These functions takes and releases the group lock */ - if (0 != abort_gp) - { - mali_group_abort_gp_job(group, gp_job_id); - } - if (0 != abort_pp) - { - mali_group_abort_pp_job(group, pp_job_id); - } - - mali_group_lock(group); - mali_group_remove_session_if_unused(group, session); - mali_group_unlock(group); -} - -enum mali_group_core_state mali_group_gp_state(struct mali_group *group) -{ - return group->gp_state; -} - -enum mali_group_core_state mali_group_pp_state(struct mali_group *group) -{ - return group->pp_state; -} - -/* group lock need to be taken before calling mali_group_bottom_half */ -void mali_group_bottom_half(struct mali_group *group, enum mali_group_event_t event) -{ - MALI_ASSERT_GROUP_LOCKED(group); - - switch (event) - { - case GROUP_EVENT_PP_JOB_COMPLETED: - mali_group_complete_jobs(group, MALI_FALSE, MALI_TRUE, MALI_TRUE); /* PP job SUCCESS */ - /* group lock is released by mali_group_complete_jobs() call above */ - break; - case GROUP_EVENT_PP_JOB_FAILED: - mali_group_complete_jobs(group, MALI_FALSE, MALI_TRUE, MALI_FALSE); /* PP job FAIL */ - /* group lock is released by mali_group_complete_jobs() call above */ - break; - case GROUP_EVENT_PP_JOB_TIMED_OUT: - mali_group_complete_jobs(group, MALI_FALSE, MALI_TRUE, MALI_FALSE); /* PP job TIMEOUT */ - /* group lock is released by mali_group_complete_jobs() call above */ - break; - case GROUP_EVENT_GP_JOB_COMPLETED: - mali_group_complete_jobs(group, MALI_TRUE, MALI_FALSE, MALI_TRUE); /* GP job SUCCESS */ - /* group lock is released by mali_group_complete_jobs() call above */ - break; - case GROUP_EVENT_GP_JOB_FAILED: - mali_group_complete_jobs(group, MALI_TRUE, MALI_FALSE, MALI_FALSE); /* GP job FAIL */ - /* group lock is released by mali_group_complete_jobs() call above */ - break; - case GROUP_EVENT_GP_JOB_TIMED_OUT: - mali_group_complete_jobs(group, MALI_TRUE, MALI_FALSE, MALI_FALSE); /* GP job TIMEOUT */ - /* group lock is released by mali_group_complete_jobs() call above */ - break; - case GROUP_EVENT_GP_OOM: - group->gp_state = MALI_GROUP_CORE_STATE_OOM; - mali_group_unlock(group); /* Nothing to do on the HW side, so just release group lock right away */ - mali_gp_scheduler_oom(group, group->gp_running_job); - break; - case GROUP_EVENT_MMU_PAGE_FAULT: - mali_group_complete_jobs(group, MALI_TRUE, MALI_TRUE, MALI_FALSE); /* GP and PP job FAIL */ - /* group lock is released by mali_group_complete_jobs() call above */ - break; - default: - break; - } -} - -struct mali_mmu_core *mali_group_get_mmu(struct mali_group *group) -{ - return group->mmu; -} - -struct mali_session_data *mali_group_get_session(struct mali_group *group) -{ - return group->session; -} - -struct mali_group *mali_group_get_glob_group(u32 index) -{ - if(mali_global_num_groups > index) - { - return mali_global_groups[index]; - } - - return NULL; -} - -u32 mali_group_get_glob_num_groups(void) -{ - return mali_global_num_groups; -} - -/* Used to check if scheduler for the other core type needs to be called on job completion. - * - * Used only for Mali-200, where job start may fail if the only MMU is busy - * with another session's address space. - */ -static inline mali_bool mali_group_other_reschedule_needed(struct mali_group *group) -{ - MALI_ASSERT_GROUP_LOCKED(group); - -#if defined(USING_MALI200) - if (group->pagedir_activation_failed) - { - group->pagedir_activation_failed = MALI_FALSE; - return MALI_TRUE; - } - else -#endif - { - return MALI_FALSE; - } -} - -static enum mali_group_activate_pd_status mali_group_activate_page_directory(struct mali_group *group, struct mali_session_data *session) -{ - enum mali_group_activate_pd_status retval; - MALI_ASSERT_GROUP_LOCKED(group); - - MALI_DEBUG_PRINT(5, ("Mali group: Activating page directory 0x%08X from session 0x%08X on group 0x%08X\n", mali_session_get_page_directory(session), session, group)); - MALI_DEBUG_ASSERT(0 <= group->page_dir_ref_count); - - if (0 != group->page_dir_ref_count) - { - if (group->session != session) - { - MALI_DEBUG_PRINT(4, ("Mali group: Activating session FAILED: 0x%08x on group 0x%08X. Existing session: 0x%08x\n", session, group, group->session)); - return MALI_GROUP_ACTIVATE_PD_STATUS_FAILED; - } - else - { - MALI_DEBUG_PRINT(4, ("Mali group: Activating session already activated: 0x%08x on group 0x%08X. New Ref: %d\n", session, group, 1+group->page_dir_ref_count)); - retval = MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD; - - } - } - else - { - /* There might be another session here, but it is ok to overwrite it since group->page_dir_ref_count==0 */ - if (group->session != session) - { - mali_bool activate_success; - MALI_DEBUG_PRINT(5, ("Mali group: Activate session: %08x previous: %08x on group 0x%08X. Ref: %d\n", session, group->session, group, 1+group->page_dir_ref_count)); - - activate_success = mali_mmu_activate_page_directory(group->mmu, mali_session_get_page_directory(session)); - MALI_DEBUG_ASSERT(activate_success); - if ( MALI_FALSE== activate_success ) return MALI_GROUP_ACTIVATE_PD_STATUS_FAILED; - group->session = session; - retval = MALI_GROUP_ACTIVATE_PD_STATUS_OK_SWITCHED_PD; - } - else - { - MALI_DEBUG_PRINT(4, ("Mali group: Activate existing session 0x%08X on group 0x%08X. Ref: %d\n", session->page_directory, group, 1+group->page_dir_ref_count)); - retval = MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD; - } - } - - group->page_dir_ref_count++; - return retval; -} - -static void mali_group_deactivate_page_directory(struct mali_group *group, struct mali_session_data *session) -{ - MALI_ASSERT_GROUP_LOCKED(group); - - MALI_DEBUG_ASSERT(0 < group->page_dir_ref_count); - MALI_DEBUG_ASSERT(session == group->session); - - group->page_dir_ref_count--; - - /* As an optimization, the MMU still points to the group->session even if (0 == group->page_dir_ref_count), - and we do not call mali_mmu_activate_empty_page_directory(group->mmu); */ - MALI_DEBUG_ASSERT(0 <= group->page_dir_ref_count); -} - -void mali_group_remove_session_if_unused(struct mali_group *group, struct mali_session_data *session) -{ - MALI_ASSERT_GROUP_LOCKED(group); - - if (0 == group->page_dir_ref_count) - { - MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->gp_state); - MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->pp_state); - - if (group->session == session) - { - MALI_DEBUG_ASSERT(MALI_TRUE == group->power_is_on); - MALI_DEBUG_PRINT(3, ("Mali group: Deactivating unused session 0x%08X on group %08X\n", session, group)); - mali_mmu_activate_empty_page_directory(group->mmu); - group->session = NULL; - } - } -} - -void mali_group_power_on(void) -{ - int i; - for (i = 0; i < mali_global_num_groups; i++) - { - struct mali_group *group = mali_global_groups[i]; - mali_group_lock(group); - MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->gp_state); - MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->pp_state); - MALI_DEBUG_ASSERT_POINTER(group->cluster); - group->power_is_on = MALI_TRUE; - mali_cluster_power_is_enabled_set(group->cluster, MALI_TRUE); - mali_group_unlock(group); - } - MALI_DEBUG_PRINT(3,("group: POWER ON\n")); -} - -mali_bool mali_group_power_is_on(struct mali_group *group) -{ - MALI_ASSERT_GROUP_LOCKED(group); - return group->power_is_on; -} - -void mali_group_power_off(void) -{ - int i; - /* It is necessary to set group->session = NULL; so that the powered off MMU is not written to on map /unmap */ - /* It is necessary to set group->power_is_on=MALI_FALSE so that pending bottom_halves does not access powered off cores. */ - for (i = 0; i < mali_global_num_groups; i++) - { - struct mali_group *group = mali_global_groups[i]; - mali_group_lock(group); - MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->gp_state); - MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->pp_state); - MALI_DEBUG_ASSERT_POINTER(group->cluster); - group->session = NULL; - MALI_DEBUG_ASSERT(MALI_TRUE == group->power_is_on); - group->power_is_on = MALI_FALSE; - mali_cluster_power_is_enabled_set(group->cluster, MALI_FALSE); - mali_group_unlock(group); - } - MALI_DEBUG_PRINT(3,("group: POWER OFF\n")); -} - - -static void mali_group_recovery_reset(struct mali_group *group) -{ - MALI_ASSERT_GROUP_LOCKED(group); - - /* Stop cores, bus stop */ - if (NULL != group->pp_core) - { - mali_pp_stop_bus(group->pp_core); - } - if (NULL != group->gp_core) - { - mali_gp_stop_bus(group->gp_core); - } - - /* Flush MMU */ - mali_mmu_activate_fault_flush_page_directory(group->mmu); - mali_mmu_page_fault_done(group->mmu); - - /* Wait for cores to stop bus */ - if (NULL != group->pp_core) - { - mali_pp_stop_bus_wait(group->pp_core); - } - if (NULL != group->gp_core) - { - mali_gp_stop_bus_wait(group->gp_core); - } - - /* Reset cores */ - if (NULL != group->pp_core) - { - mali_pp_hard_reset(group->pp_core); - } - if (NULL != group->gp_core) - { - mali_gp_hard_reset(group->gp_core); - } - - /* Reset MMU */ - mali_mmu_reset(group->mmu); - group->session = NULL; -} - -/* Group lock need to be taken before calling mali_group_complete_jobs. Will release the lock here. */ -static void mali_group_complete_jobs(struct mali_group *group, mali_bool complete_gp, mali_bool complete_pp, bool success) -{ - mali_bool need_group_reset = MALI_FALSE; - mali_bool gp_success = success; - mali_bool pp_success = success; - - MALI_ASSERT_GROUP_LOCKED(group); - - if (complete_gp && !complete_pp) - { - MALI_DEBUG_ASSERT_POINTER(group->gp_core); - if (_MALI_OSK_ERR_OK == mali_gp_reset(group->gp_core)) - { - struct mali_gp_job *gp_job_to_return = group->gp_running_job; - group->gp_state = MALI_GROUP_CORE_STATE_IDLE; - group->gp_running_job = NULL; - - MALI_DEBUG_ASSERT_POINTER(gp_job_to_return); - - mali_group_deactivate_page_directory(group, mali_gp_job_get_session(gp_job_to_return)); - - if(mali_group_other_reschedule_needed(group)) - { - mali_group_unlock(group); - mali_pp_scheduler_do_schedule(); - } - else - { - mali_group_unlock(group); - } - - mali_gp_scheduler_job_done(group, gp_job_to_return, gp_success); - mali_pm_core_event(MALI_CORE_EVENT_GP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */ - - return; - } - else - { - need_group_reset = MALI_TRUE; - MALI_DEBUG_PRINT(3, ("Mali group: Failed to reset GP, need to reset entire group\n")); - pp_success = MALI_FALSE; /* This might kill PP as well, so this should fail */ - } - } - if (complete_pp && !complete_gp) - { - MALI_DEBUG_ASSERT_POINTER(group->pp_core); - if (_MALI_OSK_ERR_OK == mali_pp_reset(group->pp_core)) - { - struct mali_pp_job *pp_job_to_return = group->pp_running_job; - u32 pp_sub_job_to_return = group->pp_running_sub_job; - group->pp_state = MALI_GROUP_CORE_STATE_IDLE; - group->pp_running_job = NULL; - - MALI_DEBUG_ASSERT_POINTER(pp_job_to_return); - - mali_group_deactivate_page_directory(group, mali_pp_job_get_session(pp_job_to_return)); - - if(mali_group_other_reschedule_needed(group)) - { - mali_group_unlock(group); - mali_gp_scheduler_do_schedule(); - } - else - { - mali_group_unlock(group); - } - - mali_pp_scheduler_job_done(group, pp_job_to_return, pp_sub_job_to_return, pp_success); - mali_pm_core_event(MALI_CORE_EVENT_PP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */ - - return; - } - else - { - need_group_reset = MALI_TRUE; - MALI_DEBUG_PRINT(3, ("Mali group: Failed to reset PP, need to reset entire group\n")); - gp_success = MALI_FALSE; /* This might kill GP as well, so this should fail */ - } - } - else if (complete_gp && complete_pp) - { - need_group_reset = MALI_TRUE; - } - - if (MALI_TRUE == need_group_reset) - { - struct mali_gp_job *gp_job_to_return = group->gp_running_job; - struct mali_pp_job *pp_job_to_return = group->pp_running_job; - u32 pp_sub_job_to_return = group->pp_running_sub_job; - mali_bool schedule_other = MALI_FALSE; - - MALI_DEBUG_PRINT(3, ("Mali group: Resetting entire group\n")); - - group->gp_state = MALI_GROUP_CORE_STATE_IDLE; - group->gp_running_job = NULL; - if (NULL != gp_job_to_return) - { - mali_group_deactivate_page_directory(group, mali_gp_job_get_session(gp_job_to_return)); - } - - group->pp_state = MALI_GROUP_CORE_STATE_IDLE; - group->pp_running_job = NULL; - if (NULL != pp_job_to_return) - { - mali_group_deactivate_page_directory(group, mali_pp_job_get_session(pp_job_to_return)); - } - - /* The reset has to be done after mali_group_deactivate_page_directory() */ - mali_group_recovery_reset(group); - - if (mali_group_other_reschedule_needed(group) && (NULL == gp_job_to_return || NULL == pp_job_to_return)) - { - schedule_other = MALI_TRUE; - } - - mali_group_unlock(group); - - if (NULL != gp_job_to_return) - { - mali_gp_scheduler_job_done(group, gp_job_to_return, gp_success); - mali_pm_core_event(MALI_CORE_EVENT_GP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */ - } - else if (schedule_other) - { - mali_pp_scheduler_do_schedule(); - } - - if (NULL != pp_job_to_return) - { - mali_pp_scheduler_job_done(group, pp_job_to_return, pp_sub_job_to_return, pp_success); - mali_pm_core_event(MALI_CORE_EVENT_PP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */ - } - else if (schedule_other) - { - mali_gp_scheduler_do_schedule(); - } - - return; - } - - mali_group_unlock(group); -} - -#if MALI_STATE_TRACKING -u32 mali_group_dump_state(struct mali_group *group, char *buf, u32 size) -{ - int n = 0; - - n += _mali_osk_snprintf(buf + n, size - n, "Group: %p\n", group); - if (group->gp_core) - { - n += mali_gp_dump_state(group->gp_core, buf + n, size - n); - n += _mali_osk_snprintf(buf + n, size - n, "\tGP state: %d\n", group->gp_state); - n += _mali_osk_snprintf(buf + n, size - n, "\tGP job: %p\n", group->gp_running_job); - } - if (group->pp_core) - { - n += mali_pp_dump_state(group->pp_core, buf + n, size - n); - n += _mali_osk_snprintf(buf + n, size - n, "\tPP state: %d\n", group->pp_state); - n += _mali_osk_snprintf(buf + n, size - n, "\tPP job: %p, subjob %d \n", - group->pp_running_job, group->pp_running_sub_job); - } - - return n; -} -#endif diff --git a/drivers/media/video/samsung/mali/common/mali_group.h b/drivers/media/video/samsung/mali/common/mali_group.h deleted file mode 100644 index 3533d13..0000000 --- a/drivers/media/video/samsung/mali/common/mali_group.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2011-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_GROUP_H__ -#define __MALI_GROUP_H__ - -#include "linux/jiffies.h" -#include "mali_osk.h" -#include "mali_cluster.h" -#include "mali_mmu.h" -#include "mali_gp.h" -#include "mali_pp.h" -#include "mali_session.h" - -/* max runtime [ms] for a core job - used by timeout timers */ -#define MAX_RUNTIME 5000 -/** @brief A mali group object represents a MMU and a PP and/or a GP core. - * - */ -#define MALI_MAX_NUMBER_OF_GROUPS 9 - -struct mali_group; - -enum mali_group_event_t -{ - GROUP_EVENT_PP_JOB_COMPLETED, /**< PP job completed successfully */ - GROUP_EVENT_PP_JOB_FAILED, /**< PP job completed with failure */ - GROUP_EVENT_PP_JOB_TIMED_OUT, /**< PP job reached max runtime */ - GROUP_EVENT_GP_JOB_COMPLETED, /**< GP job completed successfully */ - GROUP_EVENT_GP_JOB_FAILED, /**< GP job completed with failure */ - GROUP_EVENT_GP_JOB_TIMED_OUT, /**< GP job reached max runtime */ - GROUP_EVENT_GP_OOM, /**< GP job ran out of heap memory */ - GROUP_EVENT_MMU_PAGE_FAULT, /**< MMU page fault */ -}; - -enum mali_group_core_state -{ - MALI_GROUP_CORE_STATE_IDLE, - MALI_GROUP_CORE_STATE_WORKING, - MALI_GROUP_CORE_STATE_OOM -}; - -/** @brief Create a new Mali group object - * - * @param cluster Pointer to the cluster to which the group is connected. - * @param mmu Pointer to the MMU that defines this group - * @return A pointer to a new group object - */ -struct mali_group *mali_group_create(struct mali_cluster *cluster, struct mali_mmu_core *mmu); -void mali_group_add_gp_core(struct mali_group *group, struct mali_gp_core* gp_core); -void mali_group_add_pp_core(struct mali_group *group, struct mali_pp_core* pp_core); -void mali_group_delete(struct mali_group *group); - -/** @brief Reset group - * - * This function will reset the entire group, including all the cores present in the group. - * - * @param group Pointer to the group to reset - */ -void mali_group_reset(struct mali_group *group); - -/** @brief Get pointer to GP core object - */ -struct mali_gp_core* mali_group_get_gp_core(struct mali_group *group); - -/** @brief Get pointer to PP core object - */ -struct mali_pp_core* mali_group_get_pp_core(struct mali_group *group); - -/** @brief Lock group object - * - * Most group functions will lock the group object themselves. The expection is - * the group_bottom_half which requires the group to be locked on entry. - * - * @param group Pointer to group to lock - */ -void mali_group_lock(struct mali_group *group); - -/** @brief Unlock group object - * - * @param group Pointer to group to unlock - */ -void mali_group_unlock(struct mali_group *group); -#ifdef DEBUG -void mali_group_assert_locked(struct mali_group *group); -#define MALI_ASSERT_GROUP_LOCKED(group) mali_group_assert_locked(group) -#else -#define MALI_ASSERT_GROUP_LOCKED(group) -#endif - -/** @brief Start GP job - */ -_mali_osk_errcode_t mali_group_start_gp_job(struct mali_group *group, struct mali_gp_job *job); -/** @brief Start fragment of PP job - */ -_mali_osk_errcode_t mali_group_start_pp_job(struct mali_group *group, struct mali_pp_job *job, u32 sub_job); - -/** @brief Resume GP job that suspended waiting for more heap memory - */ -void mali_group_resume_gp_with_new_heap(struct mali_group *group, u32 job_id, u32 start_addr, u32 end_addr); -/** @brief Abort GP job - * - * Used to abort suspended OOM jobs when user space failed to allocte more memory. - */ -void mali_group_abort_gp_job(struct mali_group *group, u32 job_id); -/** @brief Abort all GP jobs from \a session - * - * Used on session close when terminating all running and queued jobs from \a session. - */ -void mali_group_abort_session(struct mali_group *group, struct mali_session_data *session); - -enum mali_group_core_state mali_group_gp_state(struct mali_group *group); -enum mali_group_core_state mali_group_pp_state(struct mali_group *group); - -/** @brief The common group bottom half interrupt handler - * - * This is only called from the GP and PP bottom halves. - * - * The action taken is dictated by the \a event. - * - * @param event The event code - */ -void mali_group_bottom_half(struct mali_group *group, enum mali_group_event_t event); - -struct mali_mmu_core *mali_group_get_mmu(struct mali_group *group); -struct mali_session_data *mali_group_get_session(struct mali_group *group); - -void mali_group_remove_session_if_unused(struct mali_group *group, struct mali_session_data *session_data); - -void mali_group_power_on(void); -void mali_group_power_off(void); -mali_bool mali_group_power_is_on(struct mali_group *group); - -struct mali_group *mali_group_get_glob_group(u32 index); -u32 mali_group_get_glob_num_groups(void); - -u32 mali_group_dump_state(struct mali_group *group, char *buf, u32 size); - -#endif /* __MALI_GROUP_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_hw_core.c b/drivers/media/video/samsung/mali/common/mali_hw_core.c deleted file mode 100644 index 0b08622..0000000 --- a/drivers/media/video/samsung/mali/common/mali_hw_core.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2011-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_hw_core.h" -#include "mali_osk.h" -#include "mali_kernel_common.h" - -_mali_osk_errcode_t mali_hw_core_create(struct mali_hw_core *core, const _mali_osk_resource_t *resource, u32 reg_size) -{ - core->phys_addr = resource->base; - core->description = resource->description; - core->size = reg_size; - if (_MALI_OSK_ERR_OK == _mali_osk_mem_reqregion(core->phys_addr, core->size, core->description)) - { - core->mapped_registers = _mali_osk_mem_mapioregion(core->phys_addr, core->size, core->description); - if (NULL != core->mapped_registers) - { - return _MALI_OSK_ERR_OK; - } - else - { - MALI_PRINT_ERROR(("Failed to map memory region for core %s at phys_addr 0x%08X\n", core->description, core->phys_addr)); - } - _mali_osk_mem_unreqregion(core->phys_addr, core->size); - } - else - { - MALI_PRINT_ERROR(("Failed to request memory region for core %s at phys_addr 0x%08X\n", core->description, core->phys_addr)); - } - - return _MALI_OSK_ERR_FAULT; -} - -void mali_hw_core_delete(struct mali_hw_core *core) -{ - _mali_osk_mem_unmapioregion(core->phys_addr, core->size, core->mapped_registers); - core->mapped_registers = NULL; - _mali_osk_mem_unreqregion(core->phys_addr, core->size); -} diff --git a/drivers/media/video/samsung/mali/common/mali_hw_core.h b/drivers/media/video/samsung/mali/common/mali_hw_core.h deleted file mode 100644 index c797804..0000000 --- a/drivers/media/video/samsung/mali/common/mali_hw_core.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2011-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_HW_CORE_H__ -#define __MALI_HW_CORE_H__ - -#include "mali_osk.h" -#include "mali_kernel_common.h" - -/** - * The common parts for all Mali HW cores (GP, PP, MMU, L2 and PMU) - * This struct is embedded inside all core specific structs. - */ -struct mali_hw_core -{ - u32 phys_addr; /**< Physical address of the registers */ - u32 size; /**< Size of registers */ - mali_io_address mapped_registers; /**< Virtual mapping of the registers */ - const char* description; /**< Name of unit (as specified in device configuration) */ -}; - -#define MALI_HW_CORE_NO_COUNTER ((u32)-1) -#define MALI_HW_CORE_INVALID_VALUE ((u32)-1) - -_mali_osk_errcode_t mali_hw_core_create(struct mali_hw_core *core, const _mali_osk_resource_t *resource, u32 reg_size); -void mali_hw_core_delete(struct mali_hw_core *core); - -MALI_STATIC_INLINE u32 mali_hw_core_register_read(struct mali_hw_core *core, u32 relative_address) -{ - u32 read_val; - read_val = _mali_osk_mem_ioread32(core->mapped_registers, relative_address); - MALI_DEBUG_PRINT(6, ("register_read for core %s, relative addr=0x%04X, val=0x%08X\n", - core->description, relative_address, read_val)); - return read_val; -} - -MALI_STATIC_INLINE void mali_hw_core_register_write_relaxed(struct mali_hw_core *core, u32 relative_address, u32 new_val) -{ - MALI_DEBUG_PRINT(6, ("register_write_relaxed for core %s, relative addr=0x%04X, val=0x%08X\n", - core->description, relative_address, new_val)); - _mali_osk_mem_iowrite32_relaxed(core->mapped_registers, relative_address, new_val); -} - -MALI_STATIC_INLINE void mali_hw_core_register_write(struct mali_hw_core *core, u32 relative_address, u32 new_val) -{ - MALI_DEBUG_PRINT(6, ("register_write for core %s, relative addr=0x%04X, val=0x%08X\n", - core->description, relative_address, new_val)); - _mali_osk_mem_iowrite32(core->mapped_registers, relative_address, new_val); -} - -MALI_STATIC_INLINE void mali_hw_core_register_write_array_relaxed(struct mali_hw_core *core, u32 relative_address, u32 *write_array, u32 nr_of_regs) -{ - u32 i; - MALI_DEBUG_PRINT(6, ("register_write_array: for core %s, relative addr=0x%04X, nr of regs=%u\n", - core->description,relative_address, nr_of_regs)); - - /* Do not use burst writes against the registers */ - for (i = 0; i< nr_of_regs; i++) - { - mali_hw_core_register_write_relaxed(core, relative_address + i*4, write_array[i]); - } -} - -#endif /* __MALI_HW_CORE_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_common.h b/drivers/media/video/samsung/mali/common/mali_kernel_common.h deleted file mode 100644 index b354f92..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_common.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_KERNEL_COMMON_H__ -#define __MALI_KERNEL_COMMON_H__ - -/* Make sure debug is defined when it should be */ -#ifndef DEBUG - #if defined(_DEBUG) - #define DEBUG - #endif -#endif - -/* Macro for generating a kernel panic. - * Turned on off by compile-time Makefile settings - */ -#if defined(USING_KERNEL_PANIC) -#include - #define MALI_PANIC(fmt, args...) panic( fmt, ## args ); -#else - #define MALI_PANIC(fmt, args...) -#endif - -/* The file include several useful macros for error checking, debugging and printing. - * - MALI_PRINTF(...) Do not use this function: Will be included in Release builds. - * - MALI_DEBUG_PRINT(nr, (X) ) Prints the second argument if nr<=MALI_DEBUG_LEVEL. - * - MALI_DEBUG_ERROR( (X) ) Prints an errortext, a source trace, and the given error message. - * - MALI_DEBUG_ASSERT(exp,(X)) If the asserted expr is false, the program will exit. - * - MALI_DEBUG_ASSERT_POINTER(pointer) Triggers if the pointer is a zero pointer. - * - MALI_DEBUG_CODE( X ) The code inside the macro is only compiled in Debug builds. - * - * The (X) means that you must add an extra parenthesis around the argumentlist. - * - * The printf function: MALI_PRINTF(...) is routed to _mali_osk_debugmsg - * - * Suggested range for the DEBUG-LEVEL is [1:6] where - * [1:2] Is messages with highest priority, indicate possible errors. - * [3:4] Is messages with medium priority, output important variables. - * [5:6] Is messages with low priority, used during extensive debugging. - */ - - /** - * Fundamental error macro. Reports an error code. This is abstracted to allow us to - * easily switch to a different error reporting method if we want, and also to allow - * us to search for error returns easily. - * - * Note no closing semicolon - this is supplied in typical usage: - * - * MALI_ERROR(MALI_ERROR_OUT_OF_MEMORY); - */ -#define MALI_ERROR(error_code) return (error_code) - -/** - * Basic error macro, to indicate success. - * Note no closing semicolon - this is supplied in typical usage: - * - * MALI_SUCCESS; - */ -#define MALI_SUCCESS MALI_ERROR(_MALI_OSK_ERR_OK) - -/** - * Basic error macro. This checks whether the given condition is true, and if not returns - * from this function with the supplied error code. This is a macro so that we can override it - * for stress testing. - * - * Note that this uses the do-while-0 wrapping to ensure that we don't get problems with dangling - * else clauses. Note also no closing semicolon - this is supplied in typical usage: - * - * MALI_CHECK((p!=NULL), ERROR_NO_OBJECT); - */ -#define MALI_CHECK(condition, error_code) do { if(!(condition)) MALI_ERROR(error_code); } while(0) - -/** - * Error propagation macro. If the expression given is anything other than _MALI_OSK_NO_ERROR, - * then the value is returned from the enclosing function as an error code. This effectively - * acts as a guard clause, and propagates error values up the call stack. This uses a - * temporary value to ensure that the error expression is not evaluated twice. - * If the counter for forcing a failure has been set using _mali_force_error, this error will be - * returned without evaluating the expression in MALI_CHECK_NO_ERROR - */ -#define MALI_CHECK_NO_ERROR(expression) \ - do { _mali_osk_errcode_t _check_no_error_result=(expression); \ - if(_check_no_error_result != _MALI_OSK_ERR_OK) \ - MALI_ERROR(_check_no_error_result); \ - } while(0) - -/** - * Pointer check macro. Checks non-null pointer. - */ -#define MALI_CHECK_NON_NULL(pointer, error_code) MALI_CHECK( ((pointer)!=NULL), (error_code) ) - -/** - * Error macro with goto. This checks whether the given condition is true, and if not jumps - * to the specified label using a goto. The label must therefore be local to the function in - * which this macro appears. This is most usually used to execute some clean-up code before - * exiting with a call to ERROR. - * - * Like the other macros, this is a macro to allow us to override the condition if we wish, - * e.g. to force an error during stress testing. - */ -#define MALI_CHECK_GOTO(condition, label) do { if(!(condition)) goto label; } while(0) - -/** - * Explicitly ignore a parameter passed into a function, to suppress compiler warnings. - * Should only be used with parameter names. - */ -#define MALI_IGNORE(x) x=x - -#define MALI_PRINTF(args) _mali_osk_dbgmsg args; - -#define MALI_PRINT_ERROR(args) do{ \ - MALI_PRINTF(("Mali: ERR: %s\n" ,__FILE__)); \ - MALI_PRINTF((" %s()%4d\n ", __FUNCTION__, __LINE__)) ; \ - MALI_PRINTF(args); \ - MALI_PRINTF(("\n")); \ - } while(0) - -#define MALI_PRINT(args) do{ \ - MALI_PRINTF(("Mali: ")); \ - MALI_PRINTF(args); \ - } while (0) - -#ifdef DEBUG -#ifndef mali_debug_level -extern int mali_debug_level; -#endif - -#define MALI_DEBUG_CODE(code) code -#define MALI_DEBUG_PRINT(level, args) do { \ - if((level) <= mali_debug_level)\ - {MALI_PRINTF(("Mali<" #level ">: ")); MALI_PRINTF(args); } \ - } while (0) - -#define MALI_DEBUG_PRINT_ERROR(args) MALI_PRINT_ERROR(args) - -#define MALI_DEBUG_PRINT_IF(level,condition,args) \ - if((condition)&&((level) <= mali_debug_level))\ - {MALI_PRINTF(("Mali<" #level ">: ")); MALI_PRINTF(args); } - -#define MALI_DEBUG_PRINT_ELSE(level, args)\ - else if((level) <= mali_debug_level)\ - { MALI_PRINTF(("Mali<" #level ">: ")); MALI_PRINTF(args); } - -/** - * @note these variants of DEBUG ASSERTS will cause a debugger breakpoint - * to be entered (see _mali_osk_break() ). An alternative would be to call - * _mali_osk_abort(), on OSs that support it. - */ -#define MALI_DEBUG_PRINT_ASSERT(condition, args) do {if( !(condition)) { MALI_PRINT_ERROR(args); _mali_osk_break(); } } while(0) -#define MALI_DEBUG_ASSERT_POINTER(pointer) do {if( (pointer)== NULL) {MALI_PRINT_ERROR(("NULL pointer " #pointer)); _mali_osk_break();} } while(0) -#define MALI_DEBUG_ASSERT(condition) do {if( !(condition)) {MALI_PRINT_ERROR(("ASSERT failed: " #condition )); _mali_osk_break();} } while(0) - -#else /* DEBUG */ - -#define MALI_DEBUG_CODE(code) -#define MALI_DEBUG_PRINT(string,args) do {} while(0) -#define MALI_DEBUG_PRINT_ERROR(args) do {} while(0) -#define MALI_DEBUG_PRINT_IF(level,condition,args) do {} while(0) -#define MALI_DEBUG_PRINT_ELSE(level,condition,args) do {} while(0) -#define MALI_DEBUG_PRINT_ASSERT(condition,args) do {} while(0) -#define MALI_DEBUG_ASSERT_POINTER(pointer) do {} while(0) -#define MALI_DEBUG_ASSERT(condition) do {} while(0) - -#endif /* DEBUG */ - -/** - * variables from user space cannot be dereferenced from kernel space; tagging them - * with __user allows the GCC compiler to generate a warning. Other compilers may - * not support this so we define it here as an empty macro if the compiler doesn't - * define it. - */ -#ifndef __user -#define __user -#endif - -#endif /* __MALI_KERNEL_COMMON_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_core.c b/drivers/media/video/samsung/mali/common/mali_kernel_core.c deleted file mode 100644 index 45e86d2..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_core.c +++ /dev/null @@ -1,980 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_kernel_common.h" -#include "mali_session.h" -#include "mali_osk.h" -#include "mali_osk_mali.h" -#include "mali_ukk.h" -#include "mali_kernel_core.h" -#include "mali_memory.h" -#include "mali_mem_validation.h" -#include "mali_mmu.h" -#include "mali_mmu_page_directory.h" -#include "mali_dlbu.h" -#include "mali_gp.h" -#include "mali_pp.h" -#include "mali_gp_scheduler.h" -#include "mali_pp_scheduler.h" -#include "mali_cluster.h" -#include "mali_group.h" -#include "mali_pm.h" -#include "mali_pmu.h" -#include "mali_scheduler.h" -#ifdef CONFIG_MALI400_GPU_UTILIZATION -#include "mali_kernel_utilization.h" -#endif -#include "mali_l2_cache.h" -#if MALI_TIMELINE_PROFILING_ENABLED -#include "mali_osk_profiling.h" -#endif - -/** Pointer to table of resource definitions available to the Mali driver. - * _mali_osk_resources_init() sets up the pointer to this table. - */ -static _mali_osk_resource_t *arch_configuration = NULL; - -/** Start profiling from module load? */ -int mali_boot_profiling = 0; - -/** Number of resources initialized by _mali_osk_resources_init() */ -static u32 num_resources; - -static _mali_product_id_t global_product_id = _MALI_PRODUCT_ID_UNKNOWN; -static u32 global_gpu_base_address = 0; -static u32 global_gpu_major_version = 0; -static u32 global_gpu_minor_version = 0; - -static u32 first_pp_offset = 0; - -#define HANG_CHECK_MSECS_DEFAULT 500 /* 500 ms */ -#define WATCHDOG_MSECS_DEFAULT 4000 /* 4 s */ - -/* timer related */ -int mali_max_job_runtime = WATCHDOG_MSECS_DEFAULT; -int mali_hang_check_interval = HANG_CHECK_MSECS_DEFAULT; - -static _mali_osk_resource_t *mali_find_resource(_mali_osk_resource_type_t type, u32 offset) -{ - int i; - u32 addr = global_gpu_base_address + offset; - - for (i = 0; i < num_resources; i++) - { - if (type == arch_configuration[i].type && arch_configuration[i].base == addr) - { - return &(arch_configuration[i]); - } - } - - return NULL; -} - -static u32 mali_count_resources(_mali_osk_resource_type_t type) -{ - int i; - u32 retval = 0; - - for (i = 0; i < num_resources; i++) - { - if (type == arch_configuration[i].type) - { - retval++; - } - } - - return retval; -} - - -static _mali_osk_errcode_t mali_parse_gpu_base_and_first_pp_offset_address(void) -{ - int i; - _mali_osk_resource_t *first_gp_resource = NULL; - _mali_osk_resource_t *first_pp_resource = NULL; - - for (i = 0; i < num_resources; i++) - { - if (MALI_GP == arch_configuration[i].type) - { - if (NULL == first_gp_resource || first_gp_resource->base > arch_configuration[i].base) - { - first_gp_resource = &(arch_configuration[i]); - } - } - if (MALI_PP == arch_configuration[i].type) - { - if (NULL == first_pp_resource || first_pp_resource->base > arch_configuration[i].base) - { - first_pp_resource = &(arch_configuration[i]); - } - } - } - - if (NULL == first_gp_resource || NULL == first_pp_resource) - { - MALI_PRINT_ERROR(("No GP+PP core specified in config file\n")); - return _MALI_OSK_ERR_FAULT; - } - - if (first_gp_resource->base < first_pp_resource->base) - { - /* GP is first, so we are dealing with Mali-300, Mali-400 or Mali-450 */ - global_gpu_base_address = first_gp_resource->base; - first_pp_offset = 0x8000; - } - else - { - /* PP is first, so we are dealing with Mali-200 */ - global_gpu_base_address = first_pp_resource->base; - first_pp_offset = 0x0; - } - MALI_SUCCESS; -} - -static _mali_osk_errcode_t mali_parse_product_info(void) -{ - _mali_osk_resource_t *first_pp_resource = NULL; - - /* Find the first PP core */ - first_pp_resource = mali_find_resource(MALI_PP, first_pp_offset); - if (NULL != first_pp_resource) - { - /* Create a dummy PP object for this core so that we can read the version register */ - struct mali_group *group = mali_group_create(NULL, NULL); - if (NULL != group) - { - /*struct mali_pp_core *pp_core = mali_pp_create(first_pp_resource, group, 0);*/ - struct mali_pp_core *pp_core = mali_pp_create(first_pp_resource, group); - if (NULL != pp_core) - { - u32 pp_version = mali_pp_core_get_version(pp_core); - mali_pp_delete(pp_core); - mali_group_delete(group); - - global_gpu_major_version = (pp_version >> 8) & 0xFF; - global_gpu_minor_version = pp_version & 0xFF; - - switch (pp_version >> 16) - { - case MALI200_PP_PRODUCT_ID: - global_product_id = _MALI_PRODUCT_ID_MALI200; - MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-200 r%up%u\n", global_gpu_major_version, global_gpu_minor_version)); - break; - case MALI300_PP_PRODUCT_ID: - global_product_id = _MALI_PRODUCT_ID_MALI300; - MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-300 r%up%u\n", global_gpu_major_version, global_gpu_minor_version)); - break; - case MALI400_PP_PRODUCT_ID: - global_product_id = _MALI_PRODUCT_ID_MALI400; - MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-400 MP r%up%u\n", global_gpu_major_version, global_gpu_minor_version)); - break; - case MALI450_PP_PRODUCT_ID: - global_product_id = _MALI_PRODUCT_ID_MALI450; - MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-450 MP r%up%u\n", global_gpu_major_version, global_gpu_minor_version)); - break; - default: - MALI_DEBUG_PRINT(2, ("Found unknown Mali GPU GPU (r%up%u)\n", global_gpu_major_version, global_gpu_minor_version)); - return _MALI_OSK_ERR_FAULT; - } - - return _MALI_OSK_ERR_OK; - } - else - { - MALI_PRINT_ERROR(("Failed to create initial PP object\n")); - } - } - else - { - MALI_PRINT_ERROR(("Failed to create initial group object\n")); - } - } - else - { - MALI_PRINT_ERROR(("First PP core not specified in config file\n")); - } - - return _MALI_OSK_ERR_FAULT; -} - -static void mali_delete_clusters(void) -{ - u32 i; - u32 number_of_clusters = mali_cluster_get_glob_num_clusters(); - - for (i = 0; i < number_of_clusters; i++) - { - mali_cluster_delete(mali_cluster_get_global_cluster(i)); - } -} - -static _mali_osk_errcode_t mali_create_cluster(_mali_osk_resource_t *resource) -{ - if (NULL != resource) - { - struct mali_l2_cache_core *l2_cache; - - if (mali_l2_cache_core_get_glob_num_l2_cores() >= mali_l2_cache_core_get_max_num_l2_cores()) - { - MALI_PRINT_ERROR(("Found too many L2 cache core objects, max %u is supported\n", mali_l2_cache_core_get_max_num_l2_cores())); - return _MALI_OSK_ERR_FAULT; - } - - MALI_DEBUG_PRINT(3, ("Found L2 cache %s, starting new cluster\n", resource->description)); - - /*l2_cache = mali_l2_cache_create(resource, global_num_l2_cache_cores);*/ - l2_cache = mali_l2_cache_create(resource); - if (NULL == l2_cache) - { - MALI_PRINT_ERROR(("Failed to create L2 cache object\n")); - return _MALI_OSK_ERR_FAULT; - } - - if (NULL == mali_cluster_create(l2_cache)) - { - MALI_PRINT_ERROR(("Failed to create cluster object\n")); - mali_l2_cache_delete(l2_cache); - return _MALI_OSK_ERR_FAULT; - } - } - else - { - mali_cluster_create(NULL); - if (NULL == mali_cluster_get_global_cluster(0)) - { - MALI_PRINT_ERROR(("Failed to create cluster object\n")); - return _MALI_OSK_ERR_FAULT; - } - } - - MALI_DEBUG_PRINT(3, ("Created cluster object\n")); - return _MALI_OSK_ERR_OK; -} - -static _mali_osk_errcode_t mali_parse_config_cluster(void) -{ - if (_MALI_PRODUCT_ID_MALI200 == global_product_id) - { - /* Create dummy cluster without L2 cache */ - return mali_create_cluster(NULL); - } - else if (_MALI_PRODUCT_ID_MALI300 == global_product_id || _MALI_PRODUCT_ID_MALI400 == global_product_id) - { - _mali_osk_resource_t *l2_resource = mali_find_resource(MALI_L2, 0x1000); - if (NULL == l2_resource) - { - MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache in config file\n")); - return _MALI_OSK_ERR_FAULT; - } - - return mali_create_cluster(l2_resource); - } - else if (_MALI_PRODUCT_ID_MALI450 == global_product_id) - { - /* - * L2 for GP at 0x10000 - * L2 for PP0-3 at 0x01000 - * L2 for PP4-7 at 0x11000 (optional) - */ - - _mali_osk_resource_t *l2_gp_resource; - _mali_osk_resource_t *l2_pp_grp0_resource; - _mali_osk_resource_t *l2_pp_grp1_resource; - - /* Make cluster for GP's L2 */ - l2_gp_resource = mali_find_resource(MALI_L2, 0x10000); - if (NULL != l2_gp_resource) - { - _mali_osk_errcode_t ret; - MALI_DEBUG_PRINT(3, ("Creating Mali-450 cluster for GP\n")); - ret = mali_create_cluster(l2_gp_resource); - if (_MALI_OSK_ERR_OK != ret) - { - return ret; - } - } - else - { - MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache for GP in config file\n")); - return _MALI_OSK_ERR_FAULT; - } - - /* Make cluster for first PP core group */ - l2_pp_grp0_resource = mali_find_resource(MALI_L2, 0x1000); - if (NULL != l2_pp_grp0_resource) - { - _mali_osk_errcode_t ret; - MALI_DEBUG_PRINT(3, ("Creating Mali-450 cluster for PP group 0\n")); - ret = mali_create_cluster(l2_pp_grp0_resource); - if (_MALI_OSK_ERR_OK != ret) - { - return ret; - } - } - else - { - MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache for PP group 0 in config file\n")); - return _MALI_OSK_ERR_FAULT; - } - - /* Second PP core group is optional, don't fail if we don't find it */ - l2_pp_grp1_resource = mali_find_resource(MALI_L2, 0x11000); - if (NULL != l2_pp_grp1_resource) - { - _mali_osk_errcode_t ret; - MALI_DEBUG_PRINT(3, ("Creating Mali-450 cluster for PP group 0\n")); - ret = mali_create_cluster(l2_pp_grp1_resource); - if (_MALI_OSK_ERR_OK != ret) - { - return ret; - } - } - } - - return _MALI_OSK_ERR_OK; -} - -static _mali_osk_errcode_t mali_create_group(struct mali_cluster *cluster, - _mali_osk_resource_t *resource_mmu, - _mali_osk_resource_t *resource_gp, - _mali_osk_resource_t *resource_pp) -{ - struct mali_mmu_core *mmu; - struct mali_group *group; - struct mali_pp_core *pp; - - MALI_DEBUG_PRINT(3, ("Starting new group for MMU %s\n", resource_mmu->description)); - - /* Create the MMU object */ - mmu = mali_mmu_create(resource_mmu); - if (NULL == mmu) - { - MALI_PRINT_ERROR(("Failed to create MMU object\n")); - return _MALI_OSK_ERR_FAULT; - } - - /* Create the group object */ - group = mali_group_create(cluster, mmu); - if (NULL == group) - { - MALI_PRINT_ERROR(("Failed to create group object for MMU %s\n", resource_mmu->description)); - mali_mmu_delete(mmu); - return _MALI_OSK_ERR_FAULT; - } - - /* Set pointer back to group in mmu.*/ - mali_mmu_set_group(mmu, group); - - /* Add this group to current cluster */ - mali_cluster_add_group(cluster, group); - - if (NULL != resource_gp) - { - /* Create the GP core object inside this group */ - /* global_gp_core = mali_gp_create(resource_gp, group); */ - if (NULL == mali_gp_create(resource_gp, group)) - { - /* No need to clean up now, as we will clean up everything linked in from the cluster when we fail this function */ - MALI_PRINT_ERROR(("Failed to create GP object\n")); - return _MALI_OSK_ERR_FAULT; - } - - /* Add GP object to this group */ - MALI_DEBUG_PRINT(3, ("Adding GP %s to group\n", resource_gp->description)); - mali_group_add_gp_core(group, mali_gp_get_global_gp_core()); - } - - if (NULL != resource_pp) - { - /* Create the PP core object inside this group */ - pp = mali_pp_create(resource_pp, group); - - if (NULL == pp) - { - /* No need to clean up now, as we will clean up everything linked in from the cluster when we fail this function */ - MALI_PRINT_ERROR(("Failed to create PP object\n")); - return _MALI_OSK_ERR_FAULT; - } - - /* Add PP object to this group */ - MALI_DEBUG_PRINT(3, ("Adding PP %s to group\n", resource_pp->description)); - mali_group_add_pp_core(group, pp); - } - - return _MALI_OSK_ERR_OK; -} - -static _mali_osk_errcode_t mali_parse_config_groups(void) -{ - if (_MALI_PRODUCT_ID_MALI200 == global_product_id) - { - _mali_osk_resource_t *resource_gp; - _mali_osk_resource_t *resource_pp; - _mali_osk_resource_t *resource_mmu; - - MALI_DEBUG_ASSERT(1 == mali_cluster_get_glob_num_clusters()); - - resource_gp = mali_find_resource(MALI_GP, 0x02000); - resource_pp = mali_find_resource(MALI_PP, 0x00000); - resource_mmu = mali_find_resource(MMU, 0x03000); - - if (NULL == resource_mmu || NULL == resource_gp || NULL == resource_pp) - { - /* Missing mandatory core(s) */ - return _MALI_OSK_ERR_FAULT; - } - - /*return mali_create_group(global_clusters[0], resource_mmu, resource_gp, resource_pp);*/ - return mali_create_group(mali_cluster_get_global_cluster(0), resource_mmu, resource_gp, resource_pp); - } - else if (_MALI_PRODUCT_ID_MALI300 == global_product_id || - _MALI_PRODUCT_ID_MALI400 == global_product_id || - _MALI_PRODUCT_ID_MALI450 == global_product_id) - { - _mali_osk_errcode_t err; - int cluster_id_gp = 0; - int cluster_id_pp_grp0 = 0; - int cluster_id_pp_grp1 = 0; - int i; - _mali_osk_resource_t *resource_gp; - _mali_osk_resource_t *resource_gp_mmu; - _mali_osk_resource_t *resource_pp[mali_pp_get_max_num_pp_cores()]; - _mali_osk_resource_t *resource_pp_mmu[mali_pp_get_max_num_pp_cores()]; - u32 max_num_pp_cores = mali_pp_get_max_num_pp_cores(); - - if (_MALI_PRODUCT_ID_MALI450 == global_product_id) - { - /* Mali-450 has separate L2s for GP, and PP core group(s) */ - cluster_id_pp_grp0 = 1; - cluster_id_pp_grp1 = 2; - } - - resource_gp = mali_find_resource(MALI_GP, 0x00000); - resource_gp_mmu = mali_find_resource(MMU, 0x03000); - resource_pp[0] = mali_find_resource(MALI_PP, 0x08000); - resource_pp[1] = mali_find_resource(MALI_PP, 0x0A000); - resource_pp[2] = mali_find_resource(MALI_PP, 0x0C000); - resource_pp[3] = mali_find_resource(MALI_PP, 0x0E000); - resource_pp[4] = mali_find_resource(MALI_PP, 0x28000); - resource_pp[5] = mali_find_resource(MALI_PP, 0x2A000); - resource_pp[6] = mali_find_resource(MALI_PP, 0x2C000); - resource_pp[7] = mali_find_resource(MALI_PP, 0x2E000); - resource_pp_mmu[0] = mali_find_resource(MMU, 0x04000); - resource_pp_mmu[1] = mali_find_resource(MMU, 0x05000); - resource_pp_mmu[2] = mali_find_resource(MMU, 0x06000); - resource_pp_mmu[3] = mali_find_resource(MMU, 0x07000); - resource_pp_mmu[4] = mali_find_resource(MMU, 0x1C000); - resource_pp_mmu[5] = mali_find_resource(MMU, 0x1D000); - resource_pp_mmu[6] = mali_find_resource(MMU, 0x1E000); - resource_pp_mmu[7] = mali_find_resource(MMU, 0x1F000); - - if (NULL == resource_gp || NULL == resource_gp_mmu || NULL == resource_pp[0] || NULL == resource_pp_mmu[0]) - { - /* Missing mandatory core(s) */ - MALI_DEBUG_PRINT(2, ("Missing mandatory resource, need at least one GP and one PP, both with a separate MMU (0x%08X, 0x%08X, 0x%08X, 0x%08X)\n", - resource_gp, resource_gp_mmu, resource_pp[0], resource_pp_mmu[0])); - return _MALI_OSK_ERR_FAULT; - } - - MALI_DEBUG_ASSERT(1 <= mali_cluster_get_glob_num_clusters()); - err = mali_create_group(mali_cluster_get_global_cluster(cluster_id_gp), resource_gp_mmu, resource_gp, NULL); - if (err != _MALI_OSK_ERR_OK) - { - return err; - } - - /* Create group for first (and mandatory) PP core */ - MALI_DEBUG_ASSERT(mali_cluster_get_glob_num_clusters() >= (cluster_id_pp_grp0 + 1)); /* >= 1 on Mali-300 and Mali-400, >= 2 on Mali-450 */ - err = mali_create_group(mali_cluster_get_global_cluster(cluster_id_pp_grp0), resource_pp_mmu[0], NULL, resource_pp[0]); - if (err != _MALI_OSK_ERR_OK) - { - return err; - } - - /* Create groups for rest of the cores in the first PP core group */ - for (i = 1; i < 4; i++) /* First half of the PP cores belong to first core group */ - { - if (NULL != resource_pp[i]) - { - err = mali_create_group(mali_cluster_get_global_cluster(cluster_id_pp_grp0), resource_pp_mmu[i], NULL, resource_pp[i]); - if (err != _MALI_OSK_ERR_OK) - { - return err; - } - } - } - - /* Create groups for cores in the second PP core group */ - for (i = 4; i < max_num_pp_cores; i++) /* Second half of the PP cores belong to second core group */ - { - if (NULL != resource_pp[i]) - { - MALI_DEBUG_ASSERT(mali_cluster_get_glob_num_clusters() >= 2); /* Only Mali-450 have more than 4 PPs, and these cores belong to second core group */ - err = mali_create_group(mali_cluster_get_global_cluster(cluster_id_pp_grp1), resource_pp_mmu[i], NULL, resource_pp[i]); - if (err != _MALI_OSK_ERR_OK) - { - return err; - } - } - } - } - - return _MALI_OSK_ERR_OK; -} - -static _mali_osk_errcode_t mali_parse_config_pmu(void) -{ - _mali_osk_errcode_t err = _MALI_OSK_ERR_OK; - _mali_osk_resource_t *resource_pmu; - u32 number_of_pp_cores; - u32 number_of_l2_caches; - - resource_pmu = mali_find_resource(PMU, 0x02000); - number_of_pp_cores = mali_count_resources(MALI_PP); - number_of_l2_caches = mali_count_resources(MALI_L2); - - if (NULL != resource_pmu) - { - if (NULL == mali_pmu_create(resource_pmu, number_of_pp_cores, number_of_l2_caches)) - { - err = _MALI_OSK_ERR_FAULT; - } - } - return err; -} - -static _mali_osk_errcode_t mali_parse_config_memory(void) -{ - int i; - _mali_osk_errcode_t ret; - - for(i = 0; i < num_resources; i++) - { - switch(arch_configuration[i].type) - { - case OS_MEMORY: - ret = mali_memory_core_resource_os_memory(&arch_configuration[i]); - if (_MALI_OSK_ERR_OK != ret) - { - MALI_PRINT_ERROR(("Failed to register OS_MEMORY\n")); - mali_memory_terminate(); - return ret; - } - break; - case MEMORY: - ret = mali_memory_core_resource_dedicated_memory(&arch_configuration[i]); - if (_MALI_OSK_ERR_OK != ret) - { - MALI_PRINT_ERROR(("Failed to register MEMORY\n")); - mali_memory_terminate(); - return ret; - } - break; - case MEM_VALIDATION: - ret = mali_mem_validation_add_range(&arch_configuration[i]); - if (_MALI_OSK_ERR_OK != ret) - { - MALI_PRINT_ERROR(("Failed to register MEM_VALIDATION\n")); - mali_memory_terminate(); - return ret; - } - break; - default: - break; - } - } - return _MALI_OSK_ERR_OK; -} - -_mali_osk_errcode_t mali_initialize_subsystems(void) -{ - _mali_osk_errcode_t err; - mali_bool is_pmu_enabled; - - err = mali_session_initialize(); - if (_MALI_OSK_ERR_OK != err) goto session_init_failed; - -#if MALI_TIMELINE_PROFILING_ENABLED - err = _mali_osk_profiling_init(mali_boot_profiling ? MALI_TRUE : MALI_FALSE); - if (_MALI_OSK_ERR_OK != err) - { - /* No biggie if we wheren't able to initialize the profiling */ - MALI_PRINT_ERROR(("Failed to initialize profiling, feature will be unavailable\n")); - } -#endif - - /* Get data from config.h */ - err = _mali_osk_resources_init(&arch_configuration, &num_resources); - if (_MALI_OSK_ERR_OK != err) goto osk_resources_init_failed; - - /* Initialize driver subsystems */ - err = mali_memory_initialize(); - if (_MALI_OSK_ERR_OK != err) goto memory_init_failed; - - /* Configure memory early. Memory allocation needed for mali_mmu_initialize. */ - err = mali_parse_config_memory(); - if (_MALI_OSK_ERR_OK != err) goto parse_memory_config_failed; - - /* Parsing the GPU base address and first pp offset */ - err = mali_parse_gpu_base_and_first_pp_offset_address(); - if (_MALI_OSK_ERR_OK != err) goto parse_gpu_base_address_failed; - - /* Initialize the MALI PMU */ - err = mali_parse_config_pmu(); - if (_MALI_OSK_ERR_OK != err) goto parse_pmu_config_failed; - - is_pmu_enabled = mali_pmu_get_global_pmu_core() != NULL ? MALI_TRUE : MALI_FALSE; - - /* Initialize the power management module */ - err = mali_pm_initialize(); - if (_MALI_OSK_ERR_OK != err) goto pm_init_failed; - - /* Make sure the power stays on for the rest of this function */ - mali_pm_always_on(MALI_TRUE); - - /* Detect which Mali GPU we are dealing with */ - err = mali_parse_product_info(); - if (_MALI_OSK_ERR_OK != err) goto product_info_parsing_failed; - - /* The global_product_id is now populated with the correct Mali GPU */ - - /* Initialize MMU module */ - err = mali_mmu_initialize(); - if (_MALI_OSK_ERR_OK != err) goto mmu_init_failed; - - /* Initialize the DLBU module for Mali-450 */ - if (_MALI_PRODUCT_ID_MALI450 == global_product_id) - { - err = mali_dlbu_initialize(); - if (_MALI_OSK_ERR_OK != err) goto dlbu_init_failed; - } - - /* Start configuring the actual Mali hardware. */ - err = mali_parse_config_cluster(); - if (_MALI_OSK_ERR_OK != err) goto config_parsing_failed; - err = mali_parse_config_groups(); - if (_MALI_OSK_ERR_OK != err) goto config_parsing_failed; - - /* Initialize the schedulers */ - err = mali_scheduler_initialize(); - if (_MALI_OSK_ERR_OK != err) goto scheduler_init_failed; - err = mali_gp_scheduler_initialize(); - if (_MALI_OSK_ERR_OK != err) goto gp_scheduler_init_failed; - err = mali_pp_scheduler_initialize(); - if (_MALI_OSK_ERR_OK != err) goto pp_scheduler_init_failed; - -#ifdef CONFIG_MALI400_GPU_UTILIZATION - /* Initialize the GPU utilization tracking */ - err = mali_utilization_init(); - if (_MALI_OSK_ERR_OK != err) goto utilization_init_failed; -#endif - - /* We no longer need to stay */ - mali_pm_always_on(MALI_FALSE); - MALI_SUCCESS; /* all ok */ - - /* Error handling */ -#ifdef CONFIG_MALI400_GPU_UTILIZATION -utilization_init_failed: - mali_pp_scheduler_terminate(); -#endif -pp_scheduler_init_failed: - mali_gp_scheduler_terminate(); -gp_scheduler_init_failed: - mali_scheduler_terminate(); -scheduler_init_failed: -config_parsing_failed: - mali_delete_clusters(); /* Delete clusters even if config parsing failed. */ - if (_MALI_PRODUCT_ID_MALI450 == global_product_id) - { - mali_dlbu_terminate(); - } -dlbu_init_failed: - mali_mmu_terminate(); -mmu_init_failed: - /* Nothing to roll back */ -product_info_parsing_failed: - mali_pm_terminate(); -pm_init_failed: - if (is_pmu_enabled) - { - mali_pmu_delete(mali_pmu_get_global_pmu_core()); - } -parse_pmu_config_failed: -parse_gpu_base_address_failed: -parse_memory_config_failed: - mali_memory_terminate(); -memory_init_failed: - _mali_osk_resources_term(&arch_configuration, num_resources); -osk_resources_init_failed: -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_osk_profiling_term(); -#endif - mali_session_terminate(); -session_init_failed: - return err; -} - -void mali_terminate_subsystems(void) -{ - struct mali_pmu_core *pmu; - - MALI_DEBUG_PRINT(2, ("terminate_subsystems() called\n")); - - /* shut down subsystems in reverse order from startup */ - - mali_pm_always_on(MALI_TRUE); /* Mali will be powered off once PM subsystem terminates */ - -#ifdef CONFIG_MALI400_GPU_UTILIZATION - mali_utilization_term(); -#endif - - mali_pp_scheduler_terminate(); - mali_gp_scheduler_terminate(); - mali_scheduler_terminate(); - - mali_delete_clusters(); /* Delete clusters even if config parsing failed. */ - - if (_MALI_PRODUCT_ID_MALI450 == global_product_id) - { - mali_dlbu_terminate(); - } - - mali_mmu_terminate(); - - pmu = mali_pmu_get_global_pmu_core(); - if (NULL != pmu) - { - mali_pmu_delete(pmu); - } - - mali_pm_terminate(); - - mali_memory_terminate(); - - _mali_osk_resources_term(&arch_configuration, num_resources); - -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_osk_profiling_term(); -#endif - - mali_session_terminate(); -} - -_mali_product_id_t mali_kernel_core_get_product_id(void) -{ - return global_product_id; -} - -void mali_kernel_core_wakeup(void) -{ - u32 i; - u32 glob_num_clusters = mali_cluster_get_glob_num_clusters(); - struct mali_cluster *cluster; - - for (i = 0; i < glob_num_clusters; i++) - { - cluster = mali_cluster_get_global_cluster(i); - mali_cluster_reset(cluster); - } -} - -_mali_osk_errcode_t _mali_ukk_get_api_version( _mali_uk_get_api_version_s *args ) -{ - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - - /* check compatability */ - if ( args->version == _MALI_UK_API_VERSION ) - { - args->compatible = 1; - } - else - { - args->compatible = 0; - } - - args->version = _MALI_UK_API_VERSION; /* report our version */ - - /* success regardless of being compatible or not */ - MALI_SUCCESS; -} - -_mali_osk_errcode_t _mali_ukk_wait_for_notification( _mali_uk_wait_for_notification_s *args ) -{ - _mali_osk_errcode_t err; - _mali_osk_notification_t *notification; - _mali_osk_notification_queue_t *queue; - - /* check input */ - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - - queue = ((struct mali_session_data *)args->ctx)->ioctl_queue; - - /* if the queue does not exist we're currently shutting down */ - if (NULL == queue) - { - MALI_DEBUG_PRINT(1, ("No notification queue registered with the session. Asking userspace to stop querying\n")); - args->type = _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS; - MALI_SUCCESS; - } - - /* receive a notification, might sleep */ - err = _mali_osk_notification_queue_receive(queue, ¬ification); - if (_MALI_OSK_ERR_OK != err) - { - MALI_ERROR(err); /* errcode returned, pass on to caller */ - } - - /* copy the buffer to the user */ - args->type = (_mali_uk_notification_type)notification->notification_type; - _mali_osk_memcpy(&args->data, notification->result_buffer, notification->result_buffer_size); - - /* finished with the notification */ - _mali_osk_notification_delete( notification ); - - MALI_SUCCESS; /* all ok */ -} - -_mali_osk_errcode_t _mali_ukk_post_notification( _mali_uk_post_notification_s *args ) -{ - _mali_osk_notification_t * notification; - _mali_osk_notification_queue_t *queue; - - /* check input */ - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - - queue = ((struct mali_session_data *)args->ctx)->ioctl_queue; - - /* if the queue does not exist we're currently shutting down */ - if (NULL == queue) - { - MALI_DEBUG_PRINT(1, ("No notification queue registered with the session. Asking userspace to stop querying\n")); - MALI_SUCCESS; - } - - notification = _mali_osk_notification_create(args->type, 0); - if ( NULL == notification) - { - MALI_PRINT_ERROR( ("Failed to create notification object\n")); - return _MALI_OSK_ERR_NOMEM; - } - - _mali_osk_notification_queue_send(queue, notification); - - MALI_SUCCESS; /* all ok */ -} - -_mali_osk_errcode_t _mali_ukk_open(void **context) -{ - struct mali_session_data *session_data; - - /* allocated struct to track this session */ - session_data = (struct mali_session_data *)_mali_osk_calloc(1, sizeof(struct mali_session_data)); - MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_NOMEM); - - MALI_DEBUG_PRINT(2, ("Session starting\n")); - - /* create a response queue for this session */ - session_data->ioctl_queue = _mali_osk_notification_queue_init(); - if (NULL == session_data->ioctl_queue) - { - _mali_osk_free(session_data); - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - - session_data->page_directory = mali_mmu_pagedir_alloc(); - if (NULL == session_data->page_directory) - { - _mali_osk_notification_queue_term(session_data->ioctl_queue); - _mali_osk_free(session_data); - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - - if (_MALI_OSK_ERR_OK != mali_mmu_pagedir_map(session_data->page_directory, MALI_DLB_VIRT_ADDR, _MALI_OSK_MALI_PAGE_SIZE)) - { - MALI_PRINT_ERROR(("Failed to map DLB page into session\n")); - _mali_osk_notification_queue_term(session_data->ioctl_queue); - _mali_osk_free(session_data); - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - - if (0 != mali_dlbu_phys_addr) - { - mali_mmu_pagedir_update(session_data->page_directory, MALI_DLB_VIRT_ADDR, mali_dlbu_phys_addr, _MALI_OSK_MALI_PAGE_SIZE, MALI_CACHE_STANDARD); - } - - if (_MALI_OSK_ERR_OK != mali_memory_session_begin(session_data)) - { - mali_mmu_pagedir_free(session_data->page_directory); - _mali_osk_notification_queue_term(session_data->ioctl_queue); - _mali_osk_free(session_data); - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - - *context = (void*)session_data; - - /* Add session to the list of all sessions. */ - mali_session_add(session_data); - - MALI_DEBUG_PRINT(3, ("Session started\n")); - MALI_SUCCESS; -} - -_mali_osk_errcode_t _mali_ukk_close(void **context) -{ - struct mali_session_data *session; - MALI_CHECK_NON_NULL(context, _MALI_OSK_ERR_INVALID_ARGS); - session = (struct mali_session_data *)*context; - - MALI_DEBUG_PRINT(3, ("Session ending\n")); - - /* Remove session from list of all sessions. */ - mali_session_remove(session); - - /* Abort queued and running jobs */ - mali_gp_scheduler_abort_session(session); - mali_pp_scheduler_abort_session(session); - - /* Flush pending work. - * Needed to make sure all bottom half processing related to this - * session has been completed, before we free internal data structures. - */ - _mali_osk_flush_workqueue(NULL); - - /* Free remaining memory allocated to this session */ - mali_memory_session_end(session); - - /* Free session data structures */ - mali_mmu_pagedir_free(session->page_directory); - _mali_osk_notification_queue_term(session->ioctl_queue); - _mali_osk_free(session); - - *context = NULL; - - MALI_DEBUG_PRINT(2, ("Session has ended\n")); - - MALI_SUCCESS; -} - -#if MALI_STATE_TRACKING -u32 _mali_kernel_core_dump_state(char* buf, u32 size) -{ - int n = 0; /* Number of bytes written to buf */ - - n += mali_gp_scheduler_dump_state(buf + n, size - n); - n += mali_pp_scheduler_dump_state(buf + n, size - n); - - return n; -} -#endif diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_core.h b/drivers/media/video/samsung/mali/common/mali_kernel_core.h deleted file mode 100644 index d424c48..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_core.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_KERNEL_CORE_H__ -#define __MALI_KERNEL_CORE_H__ - -#include "mali_osk.h" - -extern int mali_hang_check_interval; -extern int mali_max_job_runtime; - -typedef enum -{ - _MALI_PRODUCT_ID_UNKNOWN, - _MALI_PRODUCT_ID_MALI200, - _MALI_PRODUCT_ID_MALI300, - _MALI_PRODUCT_ID_MALI400, - _MALI_PRODUCT_ID_MALI450, -} _mali_product_id_t; - -_mali_osk_errcode_t mali_initialize_subsystems(void); - -void mali_terminate_subsystems(void); - -void mali_kernel_core_wakeup(void); - -_mali_product_id_t mali_kernel_core_get_product_id(void); - -u32 _mali_kernel_core_dump_state(char* buf, u32 size); - -#endif /* __MALI_KERNEL_CORE_H__ */ - diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.c b/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.c deleted file mode 100644 index b9f05ca..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_kernel_common.h" -#include "mali_kernel_descriptor_mapping.h" -#include "mali_osk.h" -#include "mali_osk_bitops.h" - -#define MALI_PAD_INT(x) (((x) + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1)) - -/** - * Allocate a descriptor table capable of holding 'count' mappings - * @param count Number of mappings in the table - * @return Pointer to a new table, NULL on error - */ -static mali_descriptor_table * descriptor_table_alloc(int count); - -/** - * Free a descriptor table - * @param table The table to free - */ -static void descriptor_table_free(mali_descriptor_table * table); - -mali_descriptor_mapping * mali_descriptor_mapping_create(int init_entries, int max_entries) -{ - mali_descriptor_mapping * map = _mali_osk_calloc(1, sizeof(mali_descriptor_mapping)); - - init_entries = MALI_PAD_INT(init_entries); - max_entries = MALI_PAD_INT(max_entries); - - if (NULL != map) - { - map->table = descriptor_table_alloc(init_entries); - if (NULL != map->table) - { - map->lock = _mali_osk_lock_init( (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, _MALI_OSK_LOCK_ORDER_DESCRIPTOR_MAP); - if (NULL != map->lock) - { - _mali_osk_set_nonatomic_bit(0, map->table->usage); /* reserve bit 0 to prevent NULL/zero logic to kick in */ - map->max_nr_mappings_allowed = max_entries; - map->current_nr_mappings = init_entries; - return map; - } - descriptor_table_free(map->table); - } - _mali_osk_free(map); - } - return NULL; -} - -void mali_descriptor_mapping_destroy(mali_descriptor_mapping * map) -{ - descriptor_table_free(map->table); - _mali_osk_lock_term(map->lock); - _mali_osk_free(map); -} - -_mali_osk_errcode_t mali_descriptor_mapping_allocate_mapping(mali_descriptor_mapping * map, void * target, int *odescriptor) -{ - _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT; - int new_descriptor; - - MALI_DEBUG_ASSERT_POINTER(map); - MALI_DEBUG_ASSERT_POINTER(odescriptor); - - _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW); - new_descriptor = _mali_osk_find_first_zero_bit(map->table->usage, map->current_nr_mappings); - if (new_descriptor == map->current_nr_mappings) - { - /* no free descriptor, try to expand the table */ - mali_descriptor_table * new_table, * old_table; - if (map->current_nr_mappings >= map->max_nr_mappings_allowed) goto unlock_and_exit; - - map->current_nr_mappings += BITS_PER_LONG; - new_table = descriptor_table_alloc(map->current_nr_mappings); - if (NULL == new_table) goto unlock_and_exit; - - old_table = map->table; - _mali_osk_memcpy(new_table->usage, old_table->usage, (sizeof(unsigned long)*map->current_nr_mappings) / BITS_PER_LONG); - _mali_osk_memcpy(new_table->mappings, old_table->mappings, map->current_nr_mappings * sizeof(void*)); - map->table = new_table; - descriptor_table_free(old_table); - } - - /* we have found a valid descriptor, set the value and usage bit */ - _mali_osk_set_nonatomic_bit(new_descriptor, map->table->usage); - map->table->mappings[new_descriptor] = target; - *odescriptor = new_descriptor; - err = _MALI_OSK_ERR_OK; - -unlock_and_exit: - _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RW); - MALI_ERROR(err); -} - -void mali_descriptor_mapping_call_for_each(mali_descriptor_mapping * map, void (*callback)(int, void*)) -{ - int i; - - MALI_DEBUG_ASSERT_POINTER(map); - MALI_DEBUG_ASSERT_POINTER(callback); - - _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO); - /* id 0 is skipped as it's an reserved ID not mapping to anything */ - for (i = 1; i < map->current_nr_mappings; ++i) - { - if (_mali_osk_test_bit(i, map->table->usage)) - { - callback(i, map->table->mappings[i]); - } - } - _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO); -} - -_mali_osk_errcode_t mali_descriptor_mapping_get(mali_descriptor_mapping * map, int descriptor, void** target) -{ - _mali_osk_errcode_t result = _MALI_OSK_ERR_FAULT; - MALI_DEBUG_ASSERT_POINTER(map); - _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO); - if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) ) - { - *target = map->table->mappings[descriptor]; - result = _MALI_OSK_ERR_OK; - } - else *target = NULL; - _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO); - MALI_ERROR(result); -} - -_mali_osk_errcode_t mali_descriptor_mapping_set(mali_descriptor_mapping * map, int descriptor, void * target) -{ - _mali_osk_errcode_t result = _MALI_OSK_ERR_FAULT; - _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO); - if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) ) - { - map->table->mappings[descriptor] = target; - result = _MALI_OSK_ERR_OK; - } - _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO); - MALI_ERROR(result); -} - -void *mali_descriptor_mapping_free(mali_descriptor_mapping * map, int descriptor) -{ - void *old_value = NULL; - - _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW); - if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) ) - { - old_value = map->table->mappings[descriptor]; - map->table->mappings[descriptor] = NULL; - _mali_osk_clear_nonatomic_bit(descriptor, map->table->usage); - } - _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RW); - - return old_value; -} - -static mali_descriptor_table * descriptor_table_alloc(int count) -{ - mali_descriptor_table * table; - - table = _mali_osk_calloc(1, sizeof(mali_descriptor_table) + ((sizeof(unsigned long) * count)/BITS_PER_LONG) + (sizeof(void*) * count)); - - if (NULL != table) - { - table->usage = (u32*)((u8*)table + sizeof(mali_descriptor_table)); - table->mappings = (void**)((u8*)table + sizeof(mali_descriptor_table) + ((sizeof(unsigned long) * count)/BITS_PER_LONG)); - } - - return table; -} - -static void descriptor_table_free(mali_descriptor_table * table) -{ - _mali_osk_free(table); -} diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.h b/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.h deleted file mode 100644 index 82ed94d..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_kernel_descriptor_mapping.h - */ - -#ifndef __MALI_KERNEL_DESCRIPTOR_MAPPING_H__ -#define __MALI_KERNEL_DESCRIPTOR_MAPPING_H__ - -#include "mali_osk.h" - -/** - * The actual descriptor mapping table, never directly accessed by clients - */ -typedef struct mali_descriptor_table -{ - u32 * usage; /**< Pointer to bitpattern indicating if a descriptor is valid/used or not */ - void** mappings; /**< Array of the pointers the descriptors map to */ -} mali_descriptor_table; - -/** - * The descriptor mapping object - * Provides a separate namespace where we can map an integer to a pointer - */ -typedef struct mali_descriptor_mapping -{ - _mali_osk_lock_t *lock; /**< Lock protecting access to the mapping object */ - int max_nr_mappings_allowed; /**< Max number of mappings to support in this namespace */ - int current_nr_mappings; /**< Current number of possible mappings */ - mali_descriptor_table * table; /**< Pointer to the current mapping table */ -} mali_descriptor_mapping; - -/** - * Create a descriptor mapping object - * Create a descriptor mapping capable of holding init_entries growable to max_entries - * @param init_entries Number of entries to preallocate memory for - * @param max_entries Number of entries to max support - * @return Pointer to a descriptor mapping object, NULL on failure - */ -mali_descriptor_mapping * mali_descriptor_mapping_create(int init_entries, int max_entries); - -/** - * Destroy a descriptor mapping object - * @param map The map to free - */ -void mali_descriptor_mapping_destroy(mali_descriptor_mapping * map); - -/** - * Allocate a new mapping entry (descriptor ID) - * Allocates a new entry in the map. - * @param map The map to allocate a new entry in - * @param target The value to map to - * @return The descriptor allocated, a negative value on error - */ -_mali_osk_errcode_t mali_descriptor_mapping_allocate_mapping(mali_descriptor_mapping * map, void * target, int *descriptor); - -/** - * Get the value mapped to by a descriptor ID - * @param map The map to lookup the descriptor id in - * @param descriptor The descriptor ID to lookup - * @param target Pointer to a pointer which will receive the stored value - * @return 0 on successful lookup, negative on error - */ -_mali_osk_errcode_t mali_descriptor_mapping_get(mali_descriptor_mapping * map, int descriptor, void** target); - -/** - * Set the value mapped to by a descriptor ID - * @param map The map to lookup the descriptor id in - * @param descriptor The descriptor ID to lookup - * @param target Pointer to replace the current value with - * @return 0 on successful lookup, negative on error - */ -_mali_osk_errcode_t mali_descriptor_mapping_set(mali_descriptor_mapping * map, int descriptor, void * target); - -/** - * Call the specified callback function for each descriptor in map. - * Entire function is mutex protected. - * @param map The map to do callbacks for - * @param callback A callback function which will be calle for each entry in map - */ -void mali_descriptor_mapping_call_for_each(mali_descriptor_mapping * map, void (*callback)(int, void*)); - -/** - * Free the descriptor ID - * For the descriptor to be reused it has to be freed - * @param map The map to free the descriptor from - * @param descriptor The descriptor ID to free - * - * @return old value of descriptor mapping - */ -void *mali_descriptor_mapping_free(mali_descriptor_mapping * map, int descriptor); - -#endif /* __MALI_KERNEL_DESCRIPTOR_MAPPING_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c b/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c deleted file mode 100644 index 8ff3d37..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c +++ /dev/null @@ -1,354 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_kernel_common.h" -#include "mali_kernel_core.h" -#include "mali_kernel_memory_engine.h" -#include "mali_osk.h" - -typedef struct os_allocation -{ - u32 num_pages; - u32 offset_start; - mali_allocation_engine * engine; - mali_memory_allocation * descriptor; -} os_allocation; - -typedef struct os_allocator -{ - _mali_osk_lock_t *mutex; - - /** - * Maximum number of pages to allocate from the OS - */ - u32 num_pages_max; - - /** - * Number of pages allocated from the OS - */ - u32 num_pages_allocated; - - /** CPU Usage adjustment (add to mali physical address to get cpu physical address) */ - u32 cpu_usage_adjust; -} os_allocator; - -static mali_physical_memory_allocation_result os_allocator_allocate(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info); -static mali_physical_memory_allocation_result os_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block); -static void os_allocator_release(void * ctx, void * handle); -static void os_allocator_page_table_block_release( mali_page_table_block *page_table_block ); -static void os_allocator_destroy(mali_physical_memory_allocator * allocator); -static u32 os_allocator_stat(mali_physical_memory_allocator * allocator); - -mali_physical_memory_allocator * mali_os_allocator_create(u32 max_allocation, u32 cpu_usage_adjust, const char *name) -{ - mali_physical_memory_allocator * allocator; - os_allocator * info; - - max_allocation = (max_allocation + _MALI_OSK_CPU_PAGE_SIZE-1) & ~(_MALI_OSK_CPU_PAGE_SIZE-1); - - MALI_DEBUG_PRINT(2, ("Mali OS memory allocator created with max allocation size of 0x%X bytes, cpu_usage_adjust 0x%08X\n", max_allocation, cpu_usage_adjust)); - - allocator = _mali_osk_malloc(sizeof(mali_physical_memory_allocator)); - if (NULL != allocator) - { - info = _mali_osk_malloc(sizeof(os_allocator)); - if (NULL != info) - { - info->num_pages_max = max_allocation / _MALI_OSK_CPU_PAGE_SIZE; - info->num_pages_allocated = 0; - info->cpu_usage_adjust = cpu_usage_adjust; - - info->mutex = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_ORDERED, 0, _MALI_OSK_LOCK_ORDER_MEM_INFO); - if (NULL != info->mutex) - { - allocator->allocate = os_allocator_allocate; - allocator->allocate_page_table_block = os_allocator_allocate_page_table_block; - allocator->destroy = os_allocator_destroy; - allocator->stat = os_allocator_stat; - allocator->ctx = info; - allocator->name = name; - - return allocator; - } - _mali_osk_free(info); - } - _mali_osk_free(allocator); - } - - return NULL; -} - -static u32 os_allocator_stat(mali_physical_memory_allocator * allocator) -{ - os_allocator * info; - info = (os_allocator*)allocator->ctx; - return info->num_pages_allocated * _MALI_OSK_MALI_PAGE_SIZE; -} - -static void os_allocator_destroy(mali_physical_memory_allocator * allocator) -{ - os_allocator * info; - MALI_DEBUG_ASSERT_POINTER(allocator); - MALI_DEBUG_ASSERT_POINTER(allocator->ctx); - info = (os_allocator*)allocator->ctx; - _mali_osk_lock_term(info->mutex); - _mali_osk_free(info); - _mali_osk_free(allocator); -} - -static mali_physical_memory_allocation_result os_allocator_allocate(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info) -{ - mali_physical_memory_allocation_result result = MALI_MEM_ALLOC_NONE; - u32 left; - os_allocator * info; - os_allocation * allocation; - int pages_allocated = 0; - _mali_osk_errcode_t err = _MALI_OSK_ERR_OK; - - MALI_DEBUG_ASSERT_POINTER(ctx); - MALI_DEBUG_ASSERT_POINTER(engine); - MALI_DEBUG_ASSERT_POINTER(descriptor); - MALI_DEBUG_ASSERT_POINTER(offset); - MALI_DEBUG_ASSERT_POINTER(alloc_info); - - info = (os_allocator*)ctx; - left = descriptor->size - *offset; - - if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) return MALI_MEM_ALLOC_INTERNAL_FAILURE; - - /** @note this code may not work on Linux, or may require a more complex Linux implementation */ - allocation = _mali_osk_malloc(sizeof(os_allocation)); - if (NULL != allocation) - { - u32 os_mem_max_usage = info->num_pages_max * _MALI_OSK_CPU_PAGE_SIZE; - allocation->offset_start = *offset; - allocation->num_pages = ((left + _MALI_OSK_CPU_PAGE_SIZE - 1) & ~(_MALI_OSK_CPU_PAGE_SIZE - 1)) >> _MALI_OSK_CPU_PAGE_ORDER; - MALI_DEBUG_PRINT(6, ("Allocating page array of size %d bytes\n", allocation->num_pages * sizeof(struct page*))); - - while (left > 0) - { - err = mali_allocation_engine_map_physical(engine, descriptor, *offset, MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC, info->cpu_usage_adjust, _MALI_OSK_CPU_PAGE_SIZE); - if ( _MALI_OSK_ERR_OK != err) - { - if ( _MALI_OSK_ERR_NOMEM == err) - { - /* 'Partial' allocation (or, out-of-memory on first page) */ - break; - } - - MALI_DEBUG_PRINT(1, ("Mapping of physical memory failed\n")); - - /* Fatal error, cleanup any previous pages allocated. */ - if ( pages_allocated > 0 ) - { - mali_allocation_engine_unmap_physical( engine, descriptor, allocation->offset_start, _MALI_OSK_CPU_PAGE_SIZE*pages_allocated, _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR ); - /* (*offset) doesn't need to be restored; it will not be used by the caller on failure */ - } - - pages_allocated = 0; - - result = MALI_MEM_ALLOC_INTERNAL_FAILURE; - break; - } - - /* Loop iteration */ - if (left < _MALI_OSK_CPU_PAGE_SIZE) left = 0; - else left -= _MALI_OSK_CPU_PAGE_SIZE; - - pages_allocated++; - - *offset += _MALI_OSK_CPU_PAGE_SIZE; - } - - if (left) MALI_PRINT(("Out of memory. Mali memory allocated: %d kB Configured maximum OS memory usage: %d kB\n", - (info->num_pages_allocated * _MALI_OSK_CPU_PAGE_SIZE)/1024, (info->num_pages_max* _MALI_OSK_CPU_PAGE_SIZE)/1024)); - - /* Loop termination; decide on result */ - if (pages_allocated) - { - MALI_DEBUG_PRINT(6, ("Allocated %d pages\n", pages_allocated)); - if (left) result = MALI_MEM_ALLOC_PARTIAL; - else result = MALI_MEM_ALLOC_FINISHED; - - /* Some OS do not perform a full cache flush (including all outer caches) for uncached mapped memory. - * They zero the memory through a cached mapping, then flush the inner caches but not the outer caches. - * This is required for MALI to have the correct view of the memory. - */ - _mali_osk_cache_ensure_uncached_range_flushed( (void *)descriptor, allocation->offset_start, pages_allocated *_MALI_OSK_CPU_PAGE_SIZE ); - allocation->num_pages = pages_allocated; - allocation->engine = engine; /* Necessary to make the engine's unmap call */ - allocation->descriptor = descriptor; /* Necessary to make the engine's unmap call */ - info->num_pages_allocated += pages_allocated; - - MALI_DEBUG_PRINT(6, ("%d out of %d pages now allocated\n", info->num_pages_allocated, info->num_pages_max)); - - alloc_info->ctx = info; - alloc_info->handle = allocation; - alloc_info->release = os_allocator_release; - } - else - { - MALI_DEBUG_PRINT(6, ("Releasing pages array due to no pages allocated\n")); - _mali_osk_free( allocation ); - } - } - - _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); - - return result; -} - -static void os_allocator_release(void * ctx, void * handle) -{ - os_allocator * info; - os_allocation * allocation; - mali_allocation_engine * engine; - mali_memory_allocation * descriptor; - - MALI_DEBUG_ASSERT_POINTER(ctx); - MALI_DEBUG_ASSERT_POINTER(handle); - - info = (os_allocator*)ctx; - allocation = (os_allocation*)handle; - engine = allocation->engine; - descriptor = allocation->descriptor; - - MALI_DEBUG_ASSERT_POINTER( engine ); - MALI_DEBUG_ASSERT_POINTER( descriptor ); - - if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) - { - MALI_DEBUG_PRINT(1, ("allocator release: Failed to get mutex\n")); - return; - } - - MALI_DEBUG_PRINT(6, ("Releasing %d os pages\n", allocation->num_pages)); - - MALI_DEBUG_ASSERT( allocation->num_pages <= info->num_pages_allocated); - info->num_pages_allocated -= allocation->num_pages; - - mali_allocation_engine_unmap_physical( engine, descriptor, allocation->offset_start, _MALI_OSK_CPU_PAGE_SIZE*allocation->num_pages, _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR ); - - _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); - - _mali_osk_free(allocation); -} - -static mali_physical_memory_allocation_result os_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block) -{ -#if defined(CONFIG_MACH_KONA) -#ifndef CONFIG_FORCE_MAX_ZONEORDER - int allocation_order = 10; -#else - int allocation_order = CONFIG_FORCE_MAX_ZONEORDER - 1; -#endif -#else - int allocation_order = 11; /* _MALI_OSK_CPU_PAGE_SIZE << 6 */ -#endif - void *virt = NULL; - u32 size = _MALI_OSK_CPU_PAGE_SIZE << allocation_order; - os_allocator * info; - - u32 cpu_phys_base; - - MALI_DEBUG_ASSERT_POINTER(ctx); - info = (os_allocator*)ctx; - - /* Ensure we don't allocate more than we're supposed to from the ctx */ - if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) return MALI_MEM_ALLOC_INTERNAL_FAILURE; - - /* if the number of pages to be requested lead to exceeding the memory - * limit in info->num_pages_max, reduce the size that is to be requested. */ - while ( (info->num_pages_allocated + (1 << allocation_order) > info->num_pages_max) - && _mali_osk_mem_check_allocated(info->num_pages_max * _MALI_OSK_CPU_PAGE_SIZE) ) - { - if ( allocation_order > 0 ) { - --allocation_order; - } else { - /* return OOM */ - _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); - return MALI_MEM_ALLOC_NONE; - } - } - - /* try to allocate 2^(allocation_order) pages, if that fails, try - * allocation_order-1 to allocation_order 0 (inclusive) */ - while ( allocation_order >= 0 ) - { - size = _MALI_OSK_CPU_PAGE_SIZE << allocation_order; - virt = _mali_osk_mem_allocioregion( &cpu_phys_base, size ); - - if (NULL != virt) break; - - --allocation_order; - } - - if ( NULL == virt ) - { - MALI_DEBUG_PRINT(1, ("Failed to allocate consistent memory. Is CONSISTENT_DMA_SIZE set too low?\n")); - /* return OOM */ - _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); - return MALI_MEM_ALLOC_NONE; - } - - MALI_DEBUG_PRINT(5, ("os_allocator_allocate_page_table_block: Allocation of order %i succeeded\n", - allocation_order)); - - /* we now know the size of the allocation since we know for what - * allocation_order the allocation succeeded */ - size = _MALI_OSK_CPU_PAGE_SIZE << allocation_order; - - - block->release = os_allocator_page_table_block_release; - block->ctx = ctx; - block->handle = (void*)allocation_order; - block->size = size; - block->phys_base = cpu_phys_base - info->cpu_usage_adjust; - block->mapping = virt; - - info->num_pages_allocated += (1 << allocation_order); - - _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); - - return MALI_MEM_ALLOC_FINISHED; -} - -static void os_allocator_page_table_block_release( mali_page_table_block *page_table_block ) -{ - os_allocator * info; - u32 allocation_order; - u32 pages_allocated; - - MALI_DEBUG_ASSERT_POINTER( page_table_block ); - - info = (os_allocator*)page_table_block->ctx; - - MALI_DEBUG_ASSERT_POINTER( info ); - - allocation_order = (u32)page_table_block->handle; - - pages_allocated = 1 << allocation_order; - - MALI_DEBUG_ASSERT( pages_allocated * _MALI_OSK_CPU_PAGE_SIZE == page_table_block->size ); - - if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) - { - MALI_DEBUG_PRINT(1, ("allocator release: Failed to get mutex\n")); - return; - } - - MALI_DEBUG_ASSERT( pages_allocated <= info->num_pages_allocated); - info->num_pages_allocated -= pages_allocated; - - /* Adjust phys_base from mali physical address to CPU physical address */ - _mali_osk_mem_freeioregion( page_table_block->phys_base + info->cpu_usage_adjust, page_table_block->size, page_table_block->mapping ); - - _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); -} diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.h b/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.h deleted file mode 100644 index 59e6494..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_KERNEL_MEM_OS_H__ -#define __MALI_KERNEL_MEM_OS_H__ - -/** - * @brief Creates an object that manages allocating OS memory - * - * Creates an object that provides an interface to allocate OS memory and - * have it mapped into the Mali virtual memory space. - * - * The object exposes pointers to - * - allocate OS memory - * - allocate Mali page tables in OS memory - * - destroy the object - * - * Allocations from OS memory are of type mali_physical_memory_allocation - * which provides a function to release the allocation. - * - * @param max_allocation max. number of bytes that can be allocated from OS memory - * @param cpu_usage_adjust value to add to mali physical addresses to obtain CPU physical addresses - * @param name description of the allocator - * @return pointer to mali_physical_memory_allocator object. NULL on failure. - **/ -mali_physical_memory_allocator * mali_os_allocator_create(u32 max_allocation, u32 cpu_usage_adjust, const char *name); - -#endif /* __MALI_KERNEL_MEM_OS_H__ */ - - diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.c b/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.c deleted file mode 100644 index d770e3e..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.c +++ /dev/null @@ -1,376 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_kernel_common.h" -#include "mali_kernel_core.h" -#include "mali_kernel_memory_engine.h" -#include "mali_osk.h" -#include "mali_osk_list.h" - -typedef struct memory_engine -{ - mali_kernel_mem_address_manager * mali_address; - mali_kernel_mem_address_manager * process_address; -} memory_engine; - -mali_allocation_engine mali_allocation_engine_create(mali_kernel_mem_address_manager * mali_address_manager, mali_kernel_mem_address_manager * process_address_manager) -{ - memory_engine * engine; - - /* Mali Address Manager need not support unmap_physical */ - MALI_DEBUG_ASSERT_POINTER(mali_address_manager); - MALI_DEBUG_ASSERT_POINTER(mali_address_manager->allocate); - MALI_DEBUG_ASSERT_POINTER(mali_address_manager->release); - MALI_DEBUG_ASSERT_POINTER(mali_address_manager->map_physical); - - /* Process Address Manager must support unmap_physical for OS allocation - * error path handling */ - MALI_DEBUG_ASSERT_POINTER(process_address_manager); - MALI_DEBUG_ASSERT_POINTER(process_address_manager->allocate); - MALI_DEBUG_ASSERT_POINTER(process_address_manager->release); - MALI_DEBUG_ASSERT_POINTER(process_address_manager->map_physical); - MALI_DEBUG_ASSERT_POINTER(process_address_manager->unmap_physical); - - - engine = (memory_engine*)_mali_osk_malloc(sizeof(memory_engine)); - if (NULL == engine) return NULL; - - engine->mali_address = mali_address_manager; - engine->process_address = process_address_manager; - - return (mali_allocation_engine)engine; -} - -void mali_allocation_engine_destroy(mali_allocation_engine engine) -{ - MALI_DEBUG_ASSERT_POINTER(engine); - _mali_osk_free(engine); -} - -_mali_osk_errcode_t mali_allocation_engine_allocate_memory(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor, mali_physical_memory_allocator * physical_allocators, _mali_osk_list_t *tracking_list ) -{ - memory_engine * engine = (memory_engine*)mem_engine; - - MALI_DEBUG_ASSERT_POINTER(engine); - MALI_DEBUG_ASSERT_POINTER(descriptor); - MALI_DEBUG_ASSERT_POINTER(physical_allocators); - /* ASSERT that the list member has been initialized, even if it won't be - * used for tracking. We need it to be initialized to see if we need to - * delete it from a list in the release function. */ - MALI_DEBUG_ASSERT( NULL != descriptor->list.next && NULL != descriptor->list.prev ); - - if (_MALI_OSK_ERR_OK == engine->mali_address->allocate(descriptor)) - { - _mali_osk_errcode_t res = _MALI_OSK_ERR_OK; - if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE ) - { - res = engine->process_address->allocate(descriptor); - } - if ( _MALI_OSK_ERR_OK == res ) - { - /* address space setup OK, commit physical memory to the allocation */ - mali_physical_memory_allocator * active_allocator = physical_allocators; - struct mali_physical_memory_allocation * active_allocation_tracker = &descriptor->physical_allocation; - u32 offset = 0; - - while ( NULL != active_allocator ) - { - switch (active_allocator->allocate(active_allocator->ctx, mem_engine, descriptor, &offset, active_allocation_tracker)) - { - case MALI_MEM_ALLOC_FINISHED: - if ( NULL != tracking_list ) - { - /* Insert into the memory session list */ - /* ASSERT that it is not already part of a list */ - MALI_DEBUG_ASSERT( _mali_osk_list_empty( &descriptor->list ) ); - _mali_osk_list_add( &descriptor->list, tracking_list ); - } - - MALI_SUCCESS; /* all done */ - case MALI_MEM_ALLOC_NONE: - /* reuse current active_allocation_tracker */ - MALI_DEBUG_PRINT( 4, ("Memory Engine Allocate: No allocation on %s, resorting to %s\n", - ( active_allocator->name ) ? active_allocator->name : "UNNAMED", - ( active_allocator->next ) ? (( active_allocator->next->name )? active_allocator->next->name : "UNNAMED") : "NONE") ); - active_allocator = active_allocator->next; - break; - case MALI_MEM_ALLOC_PARTIAL: - if (NULL != active_allocator->next) - { - /* need a new allocation tracker */ - active_allocation_tracker->next = _mali_osk_calloc(1, sizeof(mali_physical_memory_allocation)); - if (NULL != active_allocation_tracker->next) - { - active_allocation_tracker = active_allocation_tracker->next; - MALI_DEBUG_PRINT( 2, ("Memory Engine Allocate: Partial allocation on %s, resorting to %s\n", - ( active_allocator->name ) ? active_allocator->name : "UNNAMED", - ( active_allocator->next ) ? (( active_allocator->next->name )? active_allocator->next->name : "UNNAMED") : "NONE") ); - active_allocator = active_allocator->next; - break; - } - } - /* FALL THROUGH */ - case MALI_MEM_ALLOC_INTERNAL_FAILURE: - active_allocator = NULL; /* end the while loop */ - break; - } - } - - MALI_PRINT(("Memory allocate failed, could not allocate size %d kB.\n", descriptor->size/1024)); - - /* allocation failure, start cleanup */ - /* loop over any potential partial allocations */ - active_allocation_tracker = &descriptor->physical_allocation; - while (NULL != active_allocation_tracker) - { - /* handle blank trackers which will show up during failure */ - if (NULL != active_allocation_tracker->release) - { - active_allocation_tracker->release(active_allocation_tracker->ctx, active_allocation_tracker->handle); - } - active_allocation_tracker = active_allocation_tracker->next; - } - - /* free the allocation tracker objects themselves, skipping the tracker stored inside the descriptor itself */ - for ( active_allocation_tracker = descriptor->physical_allocation.next; active_allocation_tracker != NULL; ) - { - void * buf = active_allocation_tracker; - active_allocation_tracker = active_allocation_tracker->next; - _mali_osk_free(buf); - } - - /* release the address spaces */ - - if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE ) - { - engine->process_address->release(descriptor); - } - } - engine->mali_address->release(descriptor); - } - - MALI_ERROR(_MALI_OSK_ERR_FAULT); -} - -void mali_allocation_engine_release_memory(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor) -{ - mali_allocation_engine_release_pt1_mali_pagetables_unmap(mem_engine, descriptor); - mali_allocation_engine_release_pt2_physical_memory_free(mem_engine, descriptor); -} - -void mali_allocation_engine_release_pt1_mali_pagetables_unmap(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor) -{ - memory_engine * engine = (memory_engine*)mem_engine; - - MALI_DEBUG_ASSERT_POINTER(engine); - MALI_DEBUG_ASSERT_POINTER(descriptor); - - /* Calling: mali_address_manager_release() */ - /* This function is allowed to be called several times, and it only does the release on the first call. */ - engine->mali_address->release(descriptor); -} - -void mali_allocation_engine_release_pt2_physical_memory_free(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor) -{ - memory_engine * engine = (memory_engine*)mem_engine; - mali_physical_memory_allocation * active_allocation_tracker; - - /* Remove this from a tracking list in session_data->memory_head */ - if ( ! _mali_osk_list_empty( &descriptor->list ) ) - { - _mali_osk_list_del( &descriptor->list ); - /* Clear the list for debug mode, catch use-after-free */ - MALI_DEBUG_CODE( descriptor->list.next = descriptor->list.prev = NULL; ) - } - - active_allocation_tracker = &descriptor->physical_allocation; - while (NULL != active_allocation_tracker) - { - MALI_DEBUG_ASSERT_POINTER(active_allocation_tracker->release); - active_allocation_tracker->release(active_allocation_tracker->ctx, active_allocation_tracker->handle); - active_allocation_tracker = active_allocation_tracker->next; - } - - /* free the allocation tracker objects themselves, skipping the tracker stored inside the descriptor itself */ - for ( active_allocation_tracker = descriptor->physical_allocation.next; active_allocation_tracker != NULL; ) - { - void * buf = active_allocation_tracker; - active_allocation_tracker = active_allocation_tracker->next; - _mali_osk_free(buf); - } - - if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE ) - { - engine->process_address->release(descriptor); - } -} - -_mali_osk_errcode_t mali_allocation_engine_map_physical(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor, u32 offset, u32 phys, u32 cpu_usage_adjust, u32 size) -{ - _mali_osk_errcode_t err; - memory_engine * engine = (memory_engine*)mem_engine; - _mali_osk_mem_mapregion_flags_t unmap_flags = (_mali_osk_mem_mapregion_flags_t)0; - - MALI_DEBUG_ASSERT_POINTER(engine); - MALI_DEBUG_ASSERT_POINTER(descriptor); - - MALI_DEBUG_PRINT(7, ("Mapping phys 0x%08X length 0x%08X at offset 0x%08X\n", phys, size, offset)); - - MALI_DEBUG_ASSERT_POINTER(engine->mali_address); - MALI_DEBUG_ASSERT_POINTER(engine->mali_address->map_physical); - - /* Handle process address manager first, because we may need them to - * allocate the physical page */ - if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE ) - { - /* Handle OS-allocated specially, since an adjustment may be required */ - if ( MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC == phys ) - { - MALI_DEBUG_ASSERT( _MALI_OSK_CPU_PAGE_SIZE == size ); - - /* Set flags to use on error path */ - unmap_flags |= _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR; - - err = engine->process_address->map_physical(descriptor, offset, &phys, size); - /* Adjust for cpu physical address to mali physical address */ - phys -= cpu_usage_adjust; - } - else - { - u32 cpu_phys; - /* Adjust mali physical address to cpu physical address */ - cpu_phys = phys + cpu_usage_adjust; - err = engine->process_address->map_physical(descriptor, offset, &cpu_phys, size); - } - - if ( _MALI_OSK_ERR_OK != err ) - { - MALI_DEBUG_PRINT(2, ("Map failed: %s %d\n", __FUNCTION__, __LINE__)); - MALI_ERROR( err ); - } - } - - MALI_DEBUG_PRINT(7, ("Mapping phys 0x%08X length 0x%08X at offset 0x%08X to CPUVA 0x%08X\n", phys, size, offset, (u32)(descriptor->mapping) + offset)); - - /* Mali address manager must use the physical address - no point in asking - * it to allocate another one for us */ - MALI_DEBUG_ASSERT( MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC != phys ); - - err = engine->mali_address->map_physical(descriptor, offset, &phys, size); - - if ( _MALI_OSK_ERR_OK != err ) - { - if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE ) - { - MALI_DEBUG_PRINT( 2, ("Process address manager succeeded, but Mali Address manager failed for phys=0x%08X size=0x%08X, offset=0x%08X. Will unmap.\n", phys, size, offset)); - engine->process_address->unmap_physical(descriptor, offset, size, unmap_flags); - } - MALI_DEBUG_PRINT(2, ("Map mali failed: %s %d\n", __FUNCTION__, __LINE__)); - MALI_ERROR( err ); - } - - MALI_SUCCESS; -} - -void mali_allocation_engine_unmap_physical(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t unmap_flags ) -{ - memory_engine * engine = (memory_engine*)mem_engine; - - MALI_DEBUG_ASSERT_POINTER(engine); - MALI_DEBUG_ASSERT_POINTER(descriptor); - - MALI_DEBUG_PRINT(7, ("UnMapping length 0x%08X at offset 0x%08X\n", size, offset)); - - MALI_DEBUG_ASSERT_POINTER(engine->mali_address); - MALI_DEBUG_ASSERT_POINTER(engine->process_address); - - if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE ) - { - /* Mandetory for process_address manager to have an unmap function*/ - engine->process_address->unmap_physical( descriptor, offset, size, unmap_flags ); - } - - /* Optional for mali_address manager to have an unmap function*/ - if ( NULL != engine->mali_address->unmap_physical ) - { - engine->mali_address->unmap_physical( descriptor, offset, size, unmap_flags ); - } -} - - -_mali_osk_errcode_t mali_allocation_engine_allocate_page_tables(mali_allocation_engine engine, mali_page_table_block * descriptor, mali_physical_memory_allocator * physical_provider) -{ - mali_physical_memory_allocator * active_allocator = physical_provider; - - MALI_DEBUG_ASSERT_POINTER(descriptor); - MALI_DEBUG_ASSERT_POINTER(physical_provider); - - while ( NULL != active_allocator ) - { - switch (active_allocator->allocate_page_table_block(active_allocator->ctx, descriptor)) - { - case MALI_MEM_ALLOC_FINISHED: - MALI_SUCCESS; /* all done */ - case MALI_MEM_ALLOC_NONE: - /* try next */ - MALI_DEBUG_PRINT( 2, ("Memory Engine Allocate PageTables: No allocation on %s, resorting to %s\n", - ( active_allocator->name ) ? active_allocator->name : "UNNAMED", - ( active_allocator->next ) ? (( active_allocator->next->name )? active_allocator->next->name : "UNNAMED") : "NONE") ); - active_allocator = active_allocator->next; - break; - case MALI_MEM_ALLOC_PARTIAL: - MALI_DEBUG_PRINT(1, ("Invalid return value from allocate_page_table_block call: MALI_MEM_ALLOC_PARTIAL\n")); - /* FALL THROUGH */ - case MALI_MEM_ALLOC_INTERNAL_FAILURE: - MALI_DEBUG_PRINT(1, ("Aborting due to allocation failure\n")); - active_allocator = NULL; /* end the while loop */ - break; - } - } - - MALI_ERROR(_MALI_OSK_ERR_FAULT); -} - - -void mali_allocation_engine_report_allocators( mali_physical_memory_allocator * physical_provider ) -{ - mali_physical_memory_allocator * active_allocator = physical_provider; - MALI_DEBUG_ASSERT_POINTER(physical_provider); - - MALI_DEBUG_PRINT( 1, ("Mali memory allocators will be used in this order of preference (lowest numbered first) :\n")); - while ( NULL != active_allocator ) - { - if ( NULL != active_allocator->name ) - { - MALI_DEBUG_PRINT( 1, ("\t%d: %s\n", active_allocator->alloc_order, active_allocator->name) ); - } - else - { - MALI_DEBUG_PRINT( 1, ("\t%d: (UNNAMED ALLOCATOR)\n", active_allocator->alloc_order) ); - } - active_allocator = active_allocator->next; - } - -} - -u32 mali_allocation_engine_memory_usage(mali_physical_memory_allocator *allocator) -{ - u32 sum = 0; - while(NULL != allocator) - { - /* Only count allocators that have set up a stat function. */ - if(allocator->stat) - sum += allocator->stat(allocator); - - allocator = allocator->next; - } - - return sum; -} diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.h b/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.h deleted file mode 100644 index 3b41cee..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.h +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_KERNEL_MEMORY_ENGINE_H__ -#define __MALI_KERNEL_MEMORY_ENGINE_H__ - -typedef void * mali_allocation_engine; - -typedef enum { MALI_MEM_ALLOC_FINISHED, MALI_MEM_ALLOC_PARTIAL, MALI_MEM_ALLOC_NONE, MALI_MEM_ALLOC_INTERNAL_FAILURE } mali_physical_memory_allocation_result; - -typedef struct mali_physical_memory_allocation -{ - void (*release)(void * ctx, void * handle); /**< Function to call on to release the physical memory */ - void * ctx; - void * handle; - struct mali_physical_memory_allocation * next; -} mali_physical_memory_allocation; - -struct mali_page_table_block; - -typedef struct mali_page_table_block -{ - void (*release)(struct mali_page_table_block *page_table_block); - void * ctx; - void * handle; - u32 size; /**< In bytes, should be a multiple of MALI_MMU_PAGE_SIZE to avoid internal fragementation */ - u32 phys_base; /**< Mali physical address */ - mali_io_address mapping; -} mali_page_table_block; - - -/** @addtogroup _mali_osk_low_level_memory - * @{ */ - -typedef enum -{ - MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE = 0x1, - MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE = 0x2, -} mali_memory_allocation_flag; - -/** - * Supplying this 'magic' physical address requests that the OS allocate the - * physical address at page commit time, rather than committing a specific page - */ -#define MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC ((u32)(-1)) - -typedef struct mali_memory_allocation -{ - /* Information about the allocation */ - void * mapping; /**< CPU virtual address where the memory is mapped at */ - u32 mali_address; /**< The Mali seen address of the memory allocation */ - u32 size; /**< Size of the allocation */ - u32 permission; /**< Permission settings */ - mali_memory_allocation_flag flags; - u32 cache_settings; /* type: mali_memory_cache_settings, found in Ump DD breaks if we include it...*/ - - _mali_osk_lock_t * lock; - - /* Manager specific information pointers */ - void * mali_addr_mapping_info; /**< Mali address allocation specific info */ - void * process_addr_mapping_info; /**< Mapping manager specific info */ - - mali_physical_memory_allocation physical_allocation; - - _mali_osk_list_t list; /**< List for linking together memory allocations into the session's memory head */ -} mali_memory_allocation; -/** @} */ /* end group _mali_osk_low_level_memory */ - - -typedef struct mali_physical_memory_allocator -{ - mali_physical_memory_allocation_result (*allocate)(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info); - mali_physical_memory_allocation_result (*allocate_page_table_block)(void * ctx, mali_page_table_block * block); /* MALI_MEM_ALLOC_PARTIAL not allowed */ - void (*destroy)(struct mali_physical_memory_allocator * allocator); - u32 (*stat)(struct mali_physical_memory_allocator * allocator); - void * ctx; - const char * name; /**< Descriptive name for use in mali_allocation_engine_report_allocators, or NULL */ - u32 alloc_order; /**< Order in which the allocations should happen */ - struct mali_physical_memory_allocator * next; -} mali_physical_memory_allocator; - -typedef struct mali_kernel_mem_address_manager -{ - _mali_osk_errcode_t (*allocate)(mali_memory_allocation *); /**< Function to call to reserve an address */ - void (*release)(mali_memory_allocation *); /**< Function to call to free the address allocated */ - - /** - * Function called for each physical sub allocation. - * Called for each physical block allocated by the physical memory manager. - * @param[in] descriptor The memory descriptor in question - * @param[in] off Offset from the start of range - * @param[in,out] phys_addr A pointer to the physical address of the start of the - * physical block. When *phys_addr == MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC - * is used, this requests the function to allocate the physical page - * itself, and return it through the pointer provided. - * @param[in] size Length in bytes of the physical block - * @return _MALI_OSK_ERR_OK on success. - * A value of type _mali_osk_errcode_t other than _MALI_OSK_ERR_OK indicates failure. - * Specifically, _MALI_OSK_ERR_UNSUPPORTED indicates that the function - * does not support allocating physical pages itself. - */ - _mali_osk_errcode_t (*map_physical)(mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size); - - /** - * Function called to remove a physical sub allocation. - * Called on error paths where one of the address managers fails. - * - * @note this is optional. For address managers where this is not - * implemented, the value of this member is NULL. The memory engine - * currently does not require the mali address manager to be able to - * unmap individual pages, but the process address manager must have this - * capability. - * - * @param[in] descriptor The memory descriptor in question - * @param[in] off Offset from the start of range - * @param[in] size Length in bytes of the physical block - * @param[in] flags flags to use on a per-page basis. For OS-allocated - * physical pages, this must include _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR. - * @return _MALI_OSK_ERR_OK on success. - * A value of type _mali_osk_errcode_t other than _MALI_OSK_ERR_OK indicates failure. - */ - void (*unmap_physical)(mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t flags); - -} mali_kernel_mem_address_manager; - -mali_allocation_engine mali_allocation_engine_create(mali_kernel_mem_address_manager * mali_address_manager, mali_kernel_mem_address_manager * process_address_manager); - -void mali_allocation_engine_destroy(mali_allocation_engine engine); - -int mali_allocation_engine_allocate_memory(mali_allocation_engine engine, mali_memory_allocation * descriptor, mali_physical_memory_allocator * physical_provider, _mali_osk_list_t *tracking_list ); -void mali_allocation_engine_release_memory(mali_allocation_engine engine, mali_memory_allocation * descriptor); - -void mali_allocation_engine_release_pt1_mali_pagetables_unmap(mali_allocation_engine engine, mali_memory_allocation * descriptor); -void mali_allocation_engine_release_pt2_physical_memory_free(mali_allocation_engine engine, mali_memory_allocation * descriptor); - -int mali_allocation_engine_map_physical(mali_allocation_engine engine, mali_memory_allocation * descriptor, u32 offset, u32 phys, u32 cpu_usage_adjust, u32 size); -void mali_allocation_engine_unmap_physical(mali_allocation_engine engine, mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t unmap_flags); - -int mali_allocation_engine_allocate_page_tables(mali_allocation_engine, mali_page_table_block * descriptor, mali_physical_memory_allocator * physical_provider); - -void mali_allocation_engine_report_allocators(mali_physical_memory_allocator * physical_provider); - -u32 mali_allocation_engine_memory_usage(mali_physical_memory_allocator *allocator); - -#endif /* __MALI_KERNEL_MEMORY_ENGINE_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_utilization.c b/drivers/media/video/samsung/mali/common/mali_kernel_utilization.c deleted file mode 100644 index a374dbf..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_utilization.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_kernel_utilization.h" -#include "mali_osk.h" -#include "mali_platform.h" - -/* Define how often to calculate and report GPU utilization, in milliseconds */ -#define MALI_GPU_UTILIZATION_TIMEOUT 1000 - -static _mali_osk_lock_t *time_data_lock; - -static _mali_osk_atomic_t num_running_cores; - -static u64 period_start_time = 0; -static u64 work_start_time = 0; -static u64 accumulated_work_time = 0; - -static _mali_osk_timer_t *utilization_timer = NULL; -static mali_bool timer_running = MALI_FALSE; - - -static void calculate_gpu_utilization(void* arg) -{ - u64 time_now; - u64 time_period; - u32 leading_zeroes; - u32 shift_val; - u32 work_normalized; - u32 period_normalized; - u32 utilization; - - _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW); - - if (accumulated_work_time == 0 && work_start_time == 0) - { - /* Don't reschedule timer, this will be started if new work arrives */ - timer_running = MALI_FALSE; - - _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW); - - /* No work done for this period, report zero usage */ - mali_gpu_utilization_handler(0); - - return; - } - - time_now = _mali_osk_time_get_ns(); - time_period = time_now - period_start_time; - - /* If we are currently busy, update working period up to now */ - if (work_start_time != 0) - { - accumulated_work_time += (time_now - work_start_time); - work_start_time = time_now; - } - - /* - * We have two 64-bit values, a dividend and a divisor. - * To avoid dependencies to a 64-bit divider, we shift down the two values - * equally first. - * We shift the dividend up and possibly the divisor down, making the result X in 256. - */ - - /* Shift the 64-bit values down so they fit inside a 32-bit integer */ - leading_zeroes = _mali_osk_clz((u32)(time_period >> 32)); - shift_val = 32 - leading_zeroes; - work_normalized = (u32)(accumulated_work_time >> shift_val); - period_normalized = (u32)(time_period >> shift_val); - - /* - * Now, we should report the usage in parts of 256 - * this means we must shift up the dividend or down the divisor by 8 - * (we could do a combination, but we just use one for simplicity, - * but the end result should be good enough anyway) - */ - if (period_normalized > 0x00FFFFFF) - { - /* The divisor is so big that it is safe to shift it down */ - period_normalized >>= 8; - } - else - { - /* - * The divisor is so small that we can shift up the dividend, without loosing any data. - * (dividend is always smaller than the divisor) - */ - work_normalized <<= 8; - } - - utilization = work_normalized / period_normalized; - - accumulated_work_time = 0; - period_start_time = time_now; /* starting a new period */ - - _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW); - - _mali_osk_timer_add(utilization_timer, _mali_osk_time_mstoticks(MALI_GPU_UTILIZATION_TIMEOUT)); - - - mali_gpu_utilization_handler(utilization); -} - -_mali_osk_errcode_t mali_utilization_init(void) -{ - time_data_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ | - _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_UTILIZATION); - - if (NULL == time_data_lock) - { - return _MALI_OSK_ERR_FAULT; - } - - _mali_osk_atomic_init(&num_running_cores, 0); - - utilization_timer = _mali_osk_timer_init(); - if (NULL == utilization_timer) - { - _mali_osk_lock_term(time_data_lock); - return _MALI_OSK_ERR_FAULT; - } - _mali_osk_timer_setcallback(utilization_timer, calculate_gpu_utilization, NULL); - - return _MALI_OSK_ERR_OK; -} - -void mali_utilization_suspend(void) -{ - if (NULL != utilization_timer) - { - _mali_osk_timer_del(utilization_timer); - timer_running = MALI_FALSE; - } -} - -void mali_utilization_term(void) -{ - if (NULL != utilization_timer) - { - _mali_osk_timer_del(utilization_timer); - timer_running = MALI_FALSE; - _mali_osk_timer_term(utilization_timer); - utilization_timer = NULL; - } - - _mali_osk_atomic_term(&num_running_cores); - - _mali_osk_lock_term(time_data_lock); -} - -void mali_utilization_core_start(u64 time_now) -{ - if (_mali_osk_atomic_inc_return(&num_running_cores) == 1) - { - /* - * We went from zero cores working, to one core working, - * we now consider the entire GPU for being busy - */ - - _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW); - - if (time_now < period_start_time) - { - /* - * This might happen if the calculate_gpu_utilization() was able - * to run between the sampling of time_now and us grabbing the lock above - */ - time_now = period_start_time; - } - - work_start_time = time_now; - if (timer_running != MALI_TRUE) - { - timer_running = MALI_TRUE; - period_start_time = work_start_time; /* starting a new period */ - - _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW); - - _mali_osk_timer_add(utilization_timer, _mali_osk_time_mstoticks(MALI_GPU_UTILIZATION_TIMEOUT)); - } - else - { - _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW); - } - } -} - -void mali_utilization_core_end(u64 time_now) -{ - if (_mali_osk_atomic_dec_return(&num_running_cores) == 0) - { - /* - * No more cores are working, so accumulate the time we was busy. - */ - _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW); - - if (time_now < work_start_time) - { - /* - * This might happen if the calculate_gpu_utilization() was able - * to run between the sampling of time_now and us grabbing the lock above - */ - time_now = work_start_time; - } - - accumulated_work_time += (time_now - work_start_time); - work_start_time = 0; - - _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW); - } -} diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_utilization.h b/drivers/media/video/samsung/mali/common/mali_kernel_utilization.h deleted file mode 100644 index 1f60517..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_utilization.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_KERNEL_UTILIZATION_H__ -#define __MALI_KERNEL_UTILIZATION_H__ - -#include "mali_osk.h" - -/** - * Initialize/start the Mali GPU utilization metrics reporting. - * - * @return _MALI_OSK_ERR_OK on success, otherwise failure. - */ -_mali_osk_errcode_t mali_utilization_init(void); - -/** - * Terminate the Mali GPU utilization metrics reporting - */ -void mali_utilization_term(void); - -/** - * Should be called when a job is about to execute a job - */ -void mali_utilization_core_start(u64 time_now); - -/** - * Should be called to stop the utilization timer during system suspend - */ -void mali_utilization_suspend(void); - -/** - * Should be called when a job has completed executing a job - */ -void mali_utilization_core_end(u64 time_now); - - -#endif /* __MALI_KERNEL_UTILIZATION_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_vsync.c b/drivers/media/video/samsung/mali/common/mali_kernel_vsync.c deleted file mode 100644 index 63c9f5b..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_vsync.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2011-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "mali_ukk.h" - -#if MALI_TIMELINE_PROFILING_ENABLED -#include "mali_osk_profiling.h" -#endif - -_mali_osk_errcode_t _mali_ukk_vsync_event_report(_mali_uk_vsync_event_report_s *args) -{ - _mali_uk_vsync_event event = (_mali_uk_vsync_event)args->event; - MALI_IGNORE(event); /* event is not used for release code, and that is OK */ - -#if MALI_TIMELINE_PROFILING_ENABLED - /* - * Manually generate user space events in kernel space. - * This saves user space from calling kernel space twice in this case. - * We just need to remember to add pid and tid manually. - */ - if ( event==_MALI_UK_VSYNC_EVENT_BEGIN_WAIT) - { - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SUSPEND | - MALI_PROFILING_EVENT_CHANNEL_SOFTWARE | - MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VSYNC, - _mali_osk_get_pid(), _mali_osk_get_tid(), 0, 0, 0); - } - - if (event==_MALI_UK_VSYNC_EVENT_END_WAIT) - { - - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_RESUME | - MALI_PROFILING_EVENT_CHANNEL_SOFTWARE | - MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VSYNC, - _mali_osk_get_pid(), _mali_osk_get_tid(), 0, 0, 0); - } -#endif - - MALI_DEBUG_PRINT(4, ("Received VSYNC event: %d\n", event)); - MALI_SUCCESS; -} - diff --git a/drivers/media/video/samsung/mali/common/mali_l2_cache.c b/drivers/media/video/samsung/mali/common/mali_l2_cache.c deleted file mode 100644 index b7267f1..0000000 --- a/drivers/media/video/samsung/mali/common/mali_l2_cache.c +++ /dev/null @@ -1,414 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include "mali_kernel_common.h" -#include "mali_osk.h" - -#include "mali_l2_cache.h" -#include "mali_hw_core.h" -#include "mali_pm.h" - -/** - * Size of the Mali L2 cache registers in bytes - */ -#define MALI400_L2_CACHE_REGISTERS_SIZE 0x30 - -#define MALI_MAX_NUMBER_OF_L2_CACHE_CORES 3 - -/** - * Mali L2 cache register numbers - * Used in the register read/write routines. - * See the hardware documentation for more information about each register - */ -typedef enum mali_l2_cache_register { - MALI400_L2_CACHE_REGISTER_STATUS = 0x0008, - /*unused = 0x000C */ - MALI400_L2_CACHE_REGISTER_COMMAND = 0x0010, /**< Misc cache commands, e.g. clear */ - MALI400_L2_CACHE_REGISTER_CLEAR_PAGE = 0x0014, - MALI400_L2_CACHE_REGISTER_MAX_READS = 0x0018, /**< Limit of outstanding read requests */ - MALI400_L2_CACHE_REGISTER_ENABLE = 0x001C, /**< Enable misc cache features */ - MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0 = 0x0020, - MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0 = 0x0024, - MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1 = 0x0028, - MALI400_L2_CACHE_REGISTER_PERFCNT_VAL1 = 0x002C, -} mali_l2_cache_register; - -/** - * Mali L2 cache commands - * These are the commands that can be sent to the Mali L2 cache unit - */ -typedef enum mali_l2_cache_command -{ - MALI400_L2_CACHE_COMMAND_CLEAR_ALL = 0x01, /**< Clear the entire cache */ - /* Read HW TRM carefully before adding/using other commands than the clear above */ -} mali_l2_cache_command; - -/** - * Mali L2 cache commands - * These are the commands that can be sent to the Mali L2 cache unit - */ -typedef enum mali_l2_cache_enable -{ - MALI400_L2_CACHE_ENABLE_DEFAULT = 0x0, /**< Default state of enable register */ - MALI400_L2_CACHE_ENABLE_ACCESS = 0x01, /**< Permit cacheable accesses */ - MALI400_L2_CACHE_ENABLE_READ_ALLOCATE = 0x02, /**< Permit cache read allocate */ -} mali_l2_cache_enable; - -/** - * Mali L2 cache status bits - */ -typedef enum mali_l2_cache_status -{ - MALI400_L2_CACHE_STATUS_COMMAND_BUSY = 0x01, /**< Command handler of L2 cache is busy */ - MALI400_L2_CACHE_STATUS_DATA_BUSY = 0x02, /**< L2 cache is busy handling data requests */ -} mali_l2_cache_status; - -/** - * Definition of the L2 cache core struct - * Used to track a L2 cache unit in the system. - * Contains information about the mapping of the registers - */ -struct mali_l2_cache_core -{ - struct mali_hw_core hw_core; /**< Common for all HW cores */ - u32 core_id; /**< Unique core ID */ - _mali_osk_lock_t *command_lock; /**< Serialize all L2 cache commands */ - _mali_osk_lock_t *counter_lock; /**< Synchronize L2 cache counter access */ - u32 counter_src0; /**< Performance counter 0, MALI_HW_CORE_NO_COUNTER for disabled */ - u32 counter_src1; /**< Performance counter 1, MALI_HW_CORE_NO_COUNTER for disabled */ -}; - -#define MALI400_L2_MAX_READS_DEFAULT 0x1C - -static struct mali_l2_cache_core *mali_global_l2_cache_cores[MALI_MAX_NUMBER_OF_L2_CACHE_CORES]; -static u32 mali_global_num_l2_cache_cores = 0; - -int mali_l2_max_reads = MALI400_L2_MAX_READS_DEFAULT; - -/* Local helper functions */ -static _mali_osk_errcode_t mali_l2_cache_send_command(struct mali_l2_cache_core *cache, u32 reg, u32 val); - - -struct mali_l2_cache_core *mali_l2_cache_create(_mali_osk_resource_t *resource) -{ - struct mali_l2_cache_core *cache = NULL; - - MALI_DEBUG_PRINT(2, ("Mali L2 cache: Creating Mali L2 cache: %s\n", resource->description)); - - if (mali_global_num_l2_cache_cores >= MALI_MAX_NUMBER_OF_L2_CACHE_CORES) - { - MALI_PRINT_ERROR(("Mali L2 cache: Too many L2 cache core objects created\n")); - return NULL; - } - - cache = _mali_osk_malloc(sizeof(struct mali_l2_cache_core)); - if (NULL != cache) - { - cache->core_id = mali_global_num_l2_cache_cores; - cache->counter_src0 = MALI_HW_CORE_NO_COUNTER; - cache->counter_src1 = MALI_HW_CORE_NO_COUNTER; - if (_MALI_OSK_ERR_OK == mali_hw_core_create(&cache->hw_core, resource, MALI400_L2_CACHE_REGISTERS_SIZE)) - { - cache->command_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, - 0, _MALI_OSK_LOCK_ORDER_L2_COMMAND); - if (NULL != cache->command_lock) - { - cache->counter_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, - 0, _MALI_OSK_LOCK_ORDER_L2_COUNTER); - if (NULL != cache->counter_lock) - { - if (_MALI_OSK_ERR_OK == mali_l2_cache_reset(cache)) - { - mali_global_l2_cache_cores[mali_global_num_l2_cache_cores] = cache; - mali_global_num_l2_cache_cores++; - - return cache; - } - else - { - MALI_PRINT_ERROR(("Mali L2 cache: Failed to reset L2 cache core %s\n", cache->hw_core.description)); - } - - _mali_osk_lock_term(cache->counter_lock); - } - else - { - MALI_PRINT_ERROR(("Mali L2 cache: Failed to create counter lock for L2 cache core %s\n", cache->hw_core.description)); - } - - _mali_osk_lock_term(cache->command_lock); - } - else - { - MALI_PRINT_ERROR(("Mali L2 cache: Failed to create command lock for L2 cache core %s\n", cache->hw_core.description)); - } - - mali_hw_core_delete(&cache->hw_core); - } - - _mali_osk_free(cache); - } - else - { - MALI_PRINT_ERROR(("Mali L2 cache: Failed to allocate memory for L2 cache core\n")); - } - - return NULL; -} - -void mali_l2_cache_delete(struct mali_l2_cache_core *cache) -{ - u32 i; - - /* reset to defaults */ - mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_MAX_READS, (u32)MALI400_L2_MAX_READS_DEFAULT); - mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_ENABLE, (u32)MALI400_L2_CACHE_ENABLE_DEFAULT); - - _mali_osk_lock_term(cache->counter_lock); - _mali_osk_lock_term(cache->command_lock); - mali_hw_core_delete(&cache->hw_core); - - for (i = 0; i < mali_global_num_l2_cache_cores; i++) - { - if (mali_global_l2_cache_cores[i] == cache) - { - mali_global_l2_cache_cores[i] = NULL; - mali_global_num_l2_cache_cores--; - } - } - - _mali_osk_free(cache); -} - -u32 mali_l2_cache_get_id(struct mali_l2_cache_core *cache) -{ - return cache->core_id; -} - -mali_bool mali_l2_cache_core_set_counter_src0(struct mali_l2_cache_core *cache, u32 counter) -{ - u32 value = 0; /* disabled src */ - mali_bool core_is_on; - - MALI_DEBUG_ASSERT_POINTER(cache); - - core_is_on = mali_l2_cache_lock_power_state(cache); - - _mali_osk_lock_wait(cache->counter_lock, _MALI_OSK_LOCKMODE_RW); - - cache->counter_src0 = counter; - - if (MALI_HW_CORE_NO_COUNTER != counter) - { - value = counter; - } - - if (MALI_TRUE == core_is_on) - { - mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0, value); - } - - _mali_osk_lock_signal(cache->counter_lock, _MALI_OSK_LOCKMODE_RW); - - mali_l2_cache_unlock_power_state(cache); - - return MALI_TRUE; -} - -mali_bool mali_l2_cache_core_set_counter_src1(struct mali_l2_cache_core *cache, u32 counter) -{ - u32 value = 0; /* disabled src */ - mali_bool core_is_on; - - MALI_DEBUG_ASSERT_POINTER(cache); - - core_is_on = mali_l2_cache_lock_power_state(cache); - - _mali_osk_lock_wait(cache->counter_lock, _MALI_OSK_LOCKMODE_RW); - - cache->counter_src1 = counter; - - if (MALI_HW_CORE_NO_COUNTER != counter) - { - value = counter; - } - - if (MALI_TRUE == core_is_on) - { - mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1, value); - } - - _mali_osk_lock_signal(cache->counter_lock, _MALI_OSK_LOCKMODE_RW); - - mali_l2_cache_unlock_power_state(cache); - - return MALI_TRUE; -} - -u32 mali_l2_cache_core_get_counter_src0(struct mali_l2_cache_core *cache) -{ - return cache->counter_src0; -} - -u32 mali_l2_cache_core_get_counter_src1(struct mali_l2_cache_core *cache) -{ - return cache->counter_src1; -} - -void mali_l2_cache_core_get_counter_values(struct mali_l2_cache_core *cache, u32 *src0, u32 *value0, u32 *src1, u32 *value1) -{ - MALI_DEBUG_ASSERT(NULL != src0); - MALI_DEBUG_ASSERT(NULL != value0); - MALI_DEBUG_ASSERT(NULL != src1); - MALI_DEBUG_ASSERT(NULL != value1); - - /* Caller must hold the PM lock and know that we are powered on */ - - _mali_osk_lock_wait(cache->counter_lock, _MALI_OSK_LOCKMODE_RW); - - *src0 = cache->counter_src0; - *src1 = cache->counter_src1; - - if (cache->counter_src0 != MALI_HW_CORE_NO_COUNTER) - { - *value0 = mali_hw_core_register_read(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0); - } - - if (cache->counter_src0 != MALI_HW_CORE_NO_COUNTER) - { - *value1 = mali_hw_core_register_read(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_VAL1); - } - - _mali_osk_lock_signal(cache->counter_lock, _MALI_OSK_LOCKMODE_RW); -} - -struct mali_l2_cache_core *mali_l2_cache_core_get_glob_l2_core(u32 index) -{ - if (MALI_MAX_NUMBER_OF_L2_CACHE_CORES > index) - { - return mali_global_l2_cache_cores[index]; - } - - return NULL; -} - -u32 mali_l2_cache_core_get_glob_num_l2_cores(void) -{ - return mali_global_num_l2_cache_cores; -} - -u32 mali_l2_cache_core_get_max_num_l2_cores(void) -{ - return MALI_MAX_NUMBER_OF_L2_CACHE_CORES; -} - -_mali_osk_errcode_t mali_l2_cache_reset(struct mali_l2_cache_core *cache) -{ - /* Invalidate cache (just to keep it in a known state at startup) */ - mali_l2_cache_invalidate_all(cache); - - /* Enable cache */ - mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_ENABLE, (u32)MALI400_L2_CACHE_ENABLE_ACCESS | (u32)MALI400_L2_CACHE_ENABLE_READ_ALLOCATE); - mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_MAX_READS, (u32)mali_l2_max_reads); - - /* Restart any performance counters (if enabled) */ - _mali_osk_lock_wait(cache->counter_lock, _MALI_OSK_LOCKMODE_RW); - - if (cache->counter_src0 != MALI_HW_CORE_NO_COUNTER) - { - mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0, cache->counter_src0); - } - - if (cache->counter_src1 != MALI_HW_CORE_NO_COUNTER) - { - mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1, cache->counter_src1); - } - - _mali_osk_lock_signal(cache->counter_lock, _MALI_OSK_LOCKMODE_RW); - - return _MALI_OSK_ERR_OK; -} - -_mali_osk_errcode_t mali_l2_cache_invalidate_all(struct mali_l2_cache_core *cache) -{ - return mali_l2_cache_send_command(cache, MALI400_L2_CACHE_REGISTER_COMMAND, MALI400_L2_CACHE_COMMAND_CLEAR_ALL); -} - -_mali_osk_errcode_t mali_l2_cache_invalidate_pages(struct mali_l2_cache_core *cache, u32 *pages, u32 num_pages) -{ - u32 i; - _mali_osk_errcode_t ret1, ret = _MALI_OSK_ERR_OK; - - for (i = 0; i < num_pages; i++) - { - ret1 = mali_l2_cache_send_command(cache, MALI400_L2_CACHE_REGISTER_CLEAR_PAGE, pages[i]); - if (_MALI_OSK_ERR_OK != ret1) - { - ret = ret1; - } - } - - return ret; -} - -mali_bool mali_l2_cache_lock_power_state(struct mali_l2_cache_core *cache) -{ - /* - * Take PM lock and check power state. - * Returns MALI_TRUE if module is powered on. - * Power state will not change until mali_l2_cache_unlock_power_state() is called. - */ - mali_pm_lock(); - return mali_pm_is_powered_on(); -} - -void mali_l2_cache_unlock_power_state(struct mali_l2_cache_core *cache) -{ - /* Release PM lock */ - mali_pm_unlock(); -} - -/* -------- local helper functions below -------- */ - - -static _mali_osk_errcode_t mali_l2_cache_send_command(struct mali_l2_cache_core *cache, u32 reg, u32 val) -{ - int i = 0; - const int loop_count = 100000; - - /* - * Grab lock in order to send commands to the L2 cache in a serialized fashion. - * The L2 cache will ignore commands if it is busy. - */ - _mali_osk_lock_wait(cache->command_lock, _MALI_OSK_LOCKMODE_RW); - - /* First, wait for L2 cache command handler to go idle */ - - for (i = 0; i < loop_count; i++) - { - if (!(mali_hw_core_register_read(&cache->hw_core, MALI400_L2_CACHE_REGISTER_STATUS) & (u32)MALI400_L2_CACHE_STATUS_COMMAND_BUSY)) - { - break; - } - } - - if (i == loop_count) - { - _mali_osk_lock_signal(cache->command_lock, _MALI_OSK_LOCKMODE_RW); - MALI_DEBUG_PRINT(1, ( "Mali L2 cache: aborting wait for command interface to go idle\n")); - MALI_ERROR( _MALI_OSK_ERR_FAULT ); - } - - /* then issue the command */ - mali_hw_core_register_write(&cache->hw_core, reg, val); - - _mali_osk_lock_signal(cache->command_lock, _MALI_OSK_LOCKMODE_RW); - - MALI_SUCCESS; -} diff --git a/drivers/media/video/samsung/mali/common/mali_l2_cache.h b/drivers/media/video/samsung/mali/common/mali_l2_cache.h deleted file mode 100644 index 5a8e4da..0000000 --- a/drivers/media/video/samsung/mali/common/mali_l2_cache.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_KERNEL_L2_CACHE_H__ -#define __MALI_KERNEL_L2_CACHE_H__ - -#include "mali_osk.h" - -struct mali_l2_cache_core; - -_mali_osk_errcode_t mali_l2_cache_initialize(void); -void mali_l2_cache_terminate(void); - -struct mali_l2_cache_core *mali_l2_cache_create(_mali_osk_resource_t * resource); -void mali_l2_cache_delete(struct mali_l2_cache_core *cache); - -u32 mali_l2_cache_get_id(struct mali_l2_cache_core *cache); - -mali_bool mali_l2_cache_core_set_counter_src0(struct mali_l2_cache_core *cache, u32 counter); -mali_bool mali_l2_cache_core_set_counter_src1(struct mali_l2_cache_core *cache, u32 counter); -u32 mali_l2_cache_core_get_counter_src0(struct mali_l2_cache_core *cache); -u32 mali_l2_cache_core_get_counter_src1(struct mali_l2_cache_core *cache); -void mali_l2_cache_core_get_counter_values(struct mali_l2_cache_core *cache, u32 *src0, u32 *value0, u32 *src1, u32 *value1); -struct mali_l2_cache_core *mali_l2_cache_core_get_glob_l2_core(u32 index); -u32 mali_l2_cache_core_get_glob_num_l2_cores(void); -u32 mali_l2_cache_core_get_max_num_l2_cores(void); - -_mali_osk_errcode_t mali_l2_cache_reset(struct mali_l2_cache_core *cache); - -_mali_osk_errcode_t mali_l2_cache_invalidate_all(struct mali_l2_cache_core *cache); -_mali_osk_errcode_t mali_l2_cache_invalidate_pages(struct mali_l2_cache_core *cache, u32 *pages, u32 num_pages); - -mali_bool mali_l2_cache_lock_power_state(struct mali_l2_cache_core *cache); -void mali_l2_cache_unlock_power_state(struct mali_l2_cache_core *cache); - -#endif /* __MALI_KERNEL_L2_CACHE_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_mem_validation.c b/drivers/media/video/samsung/mali/common/mali_mem_validation.c deleted file mode 100644 index ea9c428..0000000 --- a/drivers/media/video/samsung/mali/common/mali_mem_validation.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2011-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_mem_validation.h" -#include "mali_osk.h" -#include "mali_kernel_common.h" - -#define MALI_INVALID_MEM_ADDR 0xFFFFFFFF - -typedef struct -{ - u32 phys_base; /**< Mali physical base of the memory, page aligned */ - u32 size; /**< size in bytes of the memory, multiple of page size */ -} _mali_mem_validation_t; - -static _mali_mem_validation_t mali_mem_validator = { MALI_INVALID_MEM_ADDR, MALI_INVALID_MEM_ADDR }; - -_mali_osk_errcode_t mali_mem_validation_add_range(const _mali_osk_resource_t *resource) -{ - /* Check that no other MEM_VALIDATION resources exist */ - if (MALI_INVALID_MEM_ADDR != mali_mem_validator.phys_base) - { - MALI_PRINT_ERROR(("Failed to add MEM_VALIDATION resource %s; another range is already specified\n", resource->description)); - return _MALI_OSK_ERR_FAULT; - } - - /* Check restrictions on page alignment */ - if ((0 != (resource->base & (~_MALI_OSK_CPU_PAGE_MASK))) || - (0 != (resource->size & (~_MALI_OSK_CPU_PAGE_MASK)))) - { - MALI_PRINT_ERROR(("Failed to add MEM_VALIDATION resource %s; incorrect alignment\n", resource->description)); - return _MALI_OSK_ERR_FAULT; - } - - mali_mem_validator.phys_base = resource->base; - mali_mem_validator.size = resource->size; - MALI_DEBUG_PRINT(2, ("Memory Validator '%s' installed for Mali physical address base=0x%08X, size=0x%08X\n", - resource->description, mali_mem_validator.phys_base, mali_mem_validator.size)); - - return _MALI_OSK_ERR_OK; -} - -_mali_osk_errcode_t mali_mem_validation_check(u32 phys_addr, u32 size) -{ - if (phys_addr < (phys_addr + size)) /* Don't allow overflow (or zero size) */ - { - if ((0 == ( phys_addr & (~_MALI_OSK_CPU_PAGE_MASK))) && - (0 == ( size & (~_MALI_OSK_CPU_PAGE_MASK)))) - { - if ((phys_addr >= mali_mem_validator.phys_base) && - ((phys_addr + (size - 1)) >= mali_mem_validator.phys_base) && - (phys_addr <= (mali_mem_validator.phys_base + (mali_mem_validator.size - 1))) && - ((phys_addr + (size - 1)) <= (mali_mem_validator.phys_base + (mali_mem_validator.size - 1))) ) - { - MALI_DEBUG_PRINT(3, ("Accepted range 0x%08X + size 0x%08X (= 0x%08X)\n", phys_addr, size, (phys_addr + size - 1))); - return _MALI_OSK_ERR_OK; - } - } - } - - MALI_PRINT_ERROR(("MALI PHYSICAL RANGE VALIDATION ERROR: The range supplied was: phys_base=0x%08X, size=0x%08X\n", phys_addr, size)); - - return _MALI_OSK_ERR_FAULT; -} diff --git a/drivers/media/video/samsung/mali/common/mali_mem_validation.h b/drivers/media/video/samsung/mali/common/mali_mem_validation.h deleted file mode 100644 index 2043b44..0000000 --- a/drivers/media/video/samsung/mali/common/mali_mem_validation.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2011-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_MEM_VALIDATION_H__ -#define __MALI_MEM_VALIDATION_H__ - -#include "mali_osk.h" - -_mali_osk_errcode_t mali_mem_validation_add_range(const _mali_osk_resource_t * resource); -_mali_osk_errcode_t mali_mem_validation_check(u32 phys_addr, u32 size); - -#endif /* __MALI_MEM_VALIDATION_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_memory.c b/drivers/media/video/samsung/mali/common/mali_memory.c deleted file mode 100644 index 75506ed..0000000 --- a/drivers/media/video/samsung/mali/common/mali_memory.c +++ /dev/null @@ -1,1319 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_kernel_common.h" -#include "mali_kernel_descriptor_mapping.h" -#include "mali_mem_validation.h" -#include "mali_memory.h" -#include "mali_mmu_page_directory.h" -#include "mali_kernel_memory_engine.h" -#include "mali_block_allocator.h" -#include "mali_kernel_mem_os.h" -#include "mali_session.h" -#include "mali_l2_cache.h" -#include "mali_cluster.h" -#include "mali_group.h" -#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 -#include "ump_kernel_interface.h" -#endif - -/* kernel side OS functions and user-kernel interface */ -#include "mali_osk.h" -#include "mali_osk_mali.h" -#include "mali_ukk.h" -#include "mali_osk_list.h" -#include "mali_osk_bitops.h" - -/** - * Per-session memory descriptor mapping table sizes - */ -#define MALI_MEM_DESCRIPTORS_INIT 64 -#define MALI_MEM_DESCRIPTORS_MAX 65536 - -typedef struct dedicated_memory_info -{ - u32 base; - u32 size; - struct dedicated_memory_info * next; -} dedicated_memory_info; - -/* types used for external_memory and ump_memory physical memory allocators, which are using the mali_allocation_engine */ -#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 -typedef struct ump_mem_allocation -{ - mali_allocation_engine * engine; - mali_memory_allocation * descriptor; - u32 initial_offset; - u32 size_allocated; - ump_dd_handle ump_mem; -} ump_mem_allocation ; -#endif - -typedef struct external_mem_allocation -{ - mali_allocation_engine * engine; - mali_memory_allocation * descriptor; - u32 initial_offset; - u32 size; -} external_mem_allocation; - -/** - * @brief Internal function for unmapping memory - * - * Worker function for unmapping memory from a user-process. We assume that the - * session/descriptor's lock was obtained before entry. For example, the - * wrapper _mali_ukk_mem_munmap() will lock the descriptor, then call this - * function to do the actual unmapping. mali_memory_core_session_end() could - * also call this directly (depending on compilation options), having locked - * the descriptor. - * - * This function will fail if it is unable to put the MMU in stall mode (which - * might be the case if a page fault is also being processed). - * - * @param args see _mali_uk_mem_munmap_s in "mali_utgard_uk_types.h" - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. - */ -static _mali_osk_errcode_t _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args ); - -#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 -static void ump_memory_release(void * ctx, void * handle); -static mali_physical_memory_allocation_result ump_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info); -#endif /* MALI_USE_UNIFIED_MEMORY_PROVIDER != 0*/ - - -static void external_memory_release(void * ctx, void * handle); -static mali_physical_memory_allocation_result external_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info); - - -/* nop functions */ - -/* mali address manager needs to allocate page tables on allocate, write to page table(s) on map, write to page table(s) and release page tables on release */ -static _mali_osk_errcode_t mali_address_manager_allocate(mali_memory_allocation * descriptor); /* validates the range, allocates memory for the page tables if needed */ -static _mali_osk_errcode_t mali_address_manager_map(mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size); -static void mali_address_manager_release(mali_memory_allocation * descriptor); - -/* MMU variables */ - -typedef struct mali_mmu_page_table_allocation -{ - _mali_osk_list_t list; - u32 * usage_map; - u32 usage_count; - u32 num_pages; - mali_page_table_block pages; -} mali_mmu_page_table_allocation; - -typedef struct mali_mmu_page_table_allocations -{ - _mali_osk_lock_t *lock; - _mali_osk_list_t partial; - _mali_osk_list_t full; - /* we never hold on to a empty allocation */ -} mali_mmu_page_table_allocations; - -static mali_kernel_mem_address_manager mali_address_manager = -{ - mali_address_manager_allocate, /* allocate */ - mali_address_manager_release, /* release */ - mali_address_manager_map, /* map_physical */ - NULL /* unmap_physical not present*/ -}; - -/* the mmu page table cache */ -static struct mali_mmu_page_table_allocations page_table_cache; - - -static mali_kernel_mem_address_manager process_address_manager = -{ - _mali_osk_mem_mapregion_init, /* allocate */ - _mali_osk_mem_mapregion_term, /* release */ - _mali_osk_mem_mapregion_map, /* map_physical */ - _mali_osk_mem_mapregion_unmap /* unmap_physical */ -}; - -static _mali_osk_errcode_t mali_mmu_page_table_cache_create(void); -static void mali_mmu_page_table_cache_destroy(void); - -static mali_allocation_engine memory_engine = NULL; -static mali_physical_memory_allocator * physical_memory_allocators = NULL; - -static dedicated_memory_info * mem_region_registrations = NULL; - -mali_allocation_engine mali_mem_get_memory_engine(void) -{ - return memory_engine; -} - -/* called during module init */ -_mali_osk_errcode_t mali_memory_initialize(void) -{ - _mali_osk_errcode_t err; - - MALI_DEBUG_PRINT(2, ("Memory system initializing\n")); - - err = mali_mmu_page_table_cache_create(); - if(_MALI_OSK_ERR_OK != err) - { - MALI_ERROR(err); - } - - memory_engine = mali_allocation_engine_create(&mali_address_manager, &process_address_manager); - MALI_CHECK_NON_NULL( memory_engine, _MALI_OSK_ERR_FAULT); - - MALI_SUCCESS; -} - -/* called if/when our module is unloaded */ -void mali_memory_terminate(void) -{ - MALI_DEBUG_PRINT(2, ("Memory system terminating\n")); - - mali_mmu_page_table_cache_destroy(); - - while ( NULL != mem_region_registrations) - { - dedicated_memory_info * m; - m = mem_region_registrations; - mem_region_registrations = m->next; - _mali_osk_mem_unreqregion(m->base, m->size); - _mali_osk_free(m); - } - - while ( NULL != physical_memory_allocators) - { - mali_physical_memory_allocator * m; - m = physical_memory_allocators; - physical_memory_allocators = m->next; - m->destroy(m); - } - - if (NULL != memory_engine) - { - mali_allocation_engine_destroy(memory_engine); - memory_engine = NULL; - } -} - -_mali_osk_errcode_t mali_memory_session_begin(struct mali_session_data * session_data) -{ - MALI_DEBUG_PRINT(5, ("Memory session begin\n")); - - /* create descriptor mapping table */ - session_data->descriptor_mapping = mali_descriptor_mapping_create(MALI_MEM_DESCRIPTORS_INIT, MALI_MEM_DESCRIPTORS_MAX); - - if (NULL == session_data->descriptor_mapping) - { - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - - session_data->memory_lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_ONELOCK - | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_MEM_SESSION); - if (NULL == session_data->memory_lock) - { - mali_descriptor_mapping_destroy(session_data->descriptor_mapping); - _mali_osk_free(session_data); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - /* Init the session's memory allocation list */ - _MALI_OSK_INIT_LIST_HEAD( &session_data->memory_head ); - - MALI_DEBUG_PRINT(5, ("MMU session begin: success\n")); - MALI_SUCCESS; -} - -static void descriptor_table_cleanup_callback(int descriptor_id, void* map_target) -{ - mali_memory_allocation * descriptor; - - descriptor = (mali_memory_allocation*)map_target; - - MALI_DEBUG_PRINT(3, ("Cleanup of descriptor %d mapping to 0x%x in descriptor table\n", descriptor_id, map_target)); - MALI_DEBUG_ASSERT(descriptor); - - mali_allocation_engine_release_memory(memory_engine, descriptor); - _mali_osk_free(descriptor); -} - -void mali_memory_session_end(struct mali_session_data *session_data) -{ - _mali_osk_errcode_t err = _MALI_OSK_ERR_BUSY; - - MALI_DEBUG_PRINT(3, ("MMU session end\n")); - - if (NULL == session_data) - { - MALI_DEBUG_PRINT(1, ("No session data found during session end\n")); - return; - } - - while (err == _MALI_OSK_ERR_BUSY) - { - /* Lock the session so we can modify the memory list */ - _mali_osk_lock_wait( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW ); - err = _MALI_OSK_ERR_OK; - - /* Free all memory engine allocations */ - if (0 == _mali_osk_list_empty(&session_data->memory_head)) - { - mali_memory_allocation *descriptor; - mali_memory_allocation *temp; - _mali_uk_mem_munmap_s unmap_args; - - MALI_DEBUG_PRINT(1, ("Memory found on session usage list during session termination\n")); - - unmap_args.ctx = session_data; - - /* use the 'safe' list iterator, since freeing removes the active block from the list we're iterating */ - _MALI_OSK_LIST_FOREACHENTRY(descriptor, temp, &session_data->memory_head, mali_memory_allocation, list) - { - MALI_DEBUG_PRINT(4, ("Freeing block with mali address 0x%x size %d mapped in user space at 0x%x\n", - descriptor->mali_address, descriptor->size, descriptor->size, descriptor->mapping) - ); - /* ASSERT that the descriptor's lock references the correct thing */ - MALI_DEBUG_ASSERT( descriptor->lock == session_data->memory_lock ); - /* Therefore, we have already locked the descriptor */ - - unmap_args.size = descriptor->size; - unmap_args.mapping = descriptor->mapping; - unmap_args.cookie = (u32)descriptor; - - /* - * This removes the descriptor from the list, and frees the descriptor - * - * Does not handle the _MALI_OSK_SPECIFIC_INDIRECT_MMAP case, since - * the only OS we are aware of that requires indirect MMAP also has - * implicit mmap cleanup. - */ - err = _mali_ukk_mem_munmap_internal( &unmap_args ); - - if (err == _MALI_OSK_ERR_BUSY) - { - _mali_osk_lock_signal( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW ); - /* - * Reason for this; - * We where unable to stall the MMU, probably because we are in page fault handling. - * Sleep for a while with the session lock released, then try again. - * Abnormal termination of programs with running Mali jobs is a normal reason for this. - */ - _mali_osk_time_ubusydelay(10); - break; /* Will jump back into: "while (err == _MALI_OSK_ERR_BUSY)" */ - } - } - } - } - /* Assert that we really did free everything */ - MALI_DEBUG_ASSERT( _mali_osk_list_empty(&session_data->memory_head) ); - - if (NULL != session_data->descriptor_mapping) - { - mali_descriptor_mapping_call_for_each(session_data->descriptor_mapping, descriptor_table_cleanup_callback); - mali_descriptor_mapping_destroy(session_data->descriptor_mapping); - session_data->descriptor_mapping = NULL; - } - - _mali_osk_lock_signal( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW ); - - /** - * @note Could the VMA close handler mean that we use the session data after it was freed? - * In which case, would need to refcount the session data, and free on VMA close - */ - - /* Free the lock */ - _mali_osk_lock_term( session_data->memory_lock ); - - return; -} - -_mali_osk_errcode_t mali_memory_core_resource_os_memory(_mali_osk_resource_t * resource) -{ - mali_physical_memory_allocator * allocator; - mali_physical_memory_allocator ** next_allocator_list; - - u32 alloc_order = resource->alloc_order; - - allocator = mali_os_allocator_create(resource->size, resource->cpu_usage_adjust, resource->description); - if (NULL == allocator) - { - MALI_DEBUG_PRINT(1, ("Failed to create OS memory allocator\n")); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - allocator->alloc_order = alloc_order; - - /* link in the allocator: insertion into ordered list - * resources of the same alloc_order will be Last-in-first */ - next_allocator_list = &physical_memory_allocators; - - while (NULL != *next_allocator_list && - (*next_allocator_list)->alloc_order < alloc_order ) - { - next_allocator_list = &((*next_allocator_list)->next); - } - - allocator->next = (*next_allocator_list); - (*next_allocator_list) = allocator; - - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(_mali_osk_resource_t * resource) -{ - mali_physical_memory_allocator * allocator; - mali_physical_memory_allocator ** next_allocator_list; - dedicated_memory_info * cleanup_data; - - u32 alloc_order = resource->alloc_order; - - /* do the low level linux operation first */ - - /* Request ownership of the memory */ - if (_MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(resource->base, resource->size, resource->description)) - { - MALI_DEBUG_PRINT(1, ("Failed to request memory region %s (0x%08X - 0x%08X)\n", resource->description, resource->base, resource->base + resource->size - 1)); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - /* create generic block allocator object to handle it */ - allocator = mali_block_allocator_create(resource->base, resource->cpu_usage_adjust, resource->size, resource->description ); - - if (NULL == allocator) - { - MALI_DEBUG_PRINT(1, ("Memory bank registration failed\n")); - _mali_osk_mem_unreqregion(resource->base, resource->size); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - /* save low level cleanup info */ - allocator->alloc_order = alloc_order; - - cleanup_data = _mali_osk_malloc(sizeof(dedicated_memory_info)); - - if (NULL == cleanup_data) - { - _mali_osk_mem_unreqregion(resource->base, resource->size); - allocator->destroy(allocator); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - cleanup_data->base = resource->base; - cleanup_data->size = resource->size; - - cleanup_data->next = mem_region_registrations; - mem_region_registrations = cleanup_data; - - /* link in the allocator: insertion into ordered list - * resources of the same alloc_order will be Last-in-first */ - next_allocator_list = &physical_memory_allocators; - - while ( NULL != *next_allocator_list && - (*next_allocator_list)->alloc_order < alloc_order ) - { - next_allocator_list = &((*next_allocator_list)->next); - } - - allocator->next = (*next_allocator_list); - (*next_allocator_list) = allocator; - - MALI_SUCCESS; -} - -#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 -static mali_physical_memory_allocation_result ump_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info) -{ - ump_dd_handle ump_mem; - u32 nr_blocks; - u32 i; - ump_dd_physical_block * ump_blocks; - ump_mem_allocation *ret_allocation; - - MALI_DEBUG_ASSERT_POINTER(ctx); - MALI_DEBUG_ASSERT_POINTER(engine); - MALI_DEBUG_ASSERT_POINTER(descriptor); - MALI_DEBUG_ASSERT_POINTER(alloc_info); - - ret_allocation = _mali_osk_malloc( sizeof( ump_mem_allocation ) ); - if ( NULL==ret_allocation ) return MALI_MEM_ALLOC_INTERNAL_FAILURE; - - ump_mem = (ump_dd_handle)ctx; - - MALI_DEBUG_PRINT(4, ("In ump_memory_commit\n")); - - nr_blocks = ump_dd_phys_block_count_get(ump_mem); - - MALI_DEBUG_PRINT(4, ("Have %d blocks\n", nr_blocks)); - - if (nr_blocks == 0) - { - MALI_DEBUG_PRINT(1, ("No block count\n")); - _mali_osk_free( ret_allocation ); - return MALI_MEM_ALLOC_INTERNAL_FAILURE; - } - - ump_blocks = _mali_osk_malloc(sizeof(*ump_blocks)*nr_blocks ); - if ( NULL==ump_blocks ) - { - _mali_osk_free( ret_allocation ); - return MALI_MEM_ALLOC_INTERNAL_FAILURE; - } - - if (UMP_DD_INVALID == ump_dd_phys_blocks_get(ump_mem, ump_blocks, nr_blocks)) - { - _mali_osk_free(ump_blocks); - _mali_osk_free( ret_allocation ); - return MALI_MEM_ALLOC_INTERNAL_FAILURE; - } - - /* Store away the initial offset for unmapping purposes */ - ret_allocation->initial_offset = *offset; - - for(i=0; iinitial_offset; - MALI_DEBUG_PRINT(1, ("Mapping of external memory failed\n")); - - /* unmap all previous blocks (if any) */ - mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->initial_offset, size_allocated, (_mali_osk_mem_mapregion_flags_t)0 ); - - _mali_osk_free(ump_blocks); - _mali_osk_free(ret_allocation); - return MALI_MEM_ALLOC_INTERNAL_FAILURE; - } - *offset += ump_blocks[i].size; - } - - if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE) - { - /* Map in an extra virtual guard page at the end of the VMA */ - MALI_DEBUG_PRINT(4, ("Mapping in extra guard page\n")); - if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, ump_blocks[0].addr , 0, _MALI_OSK_MALI_PAGE_SIZE )) - { - u32 size_allocated = *offset - ret_allocation->initial_offset; - MALI_DEBUG_PRINT(1, ("Mapping of external memory (guard page) failed\n")); - - /* unmap all previous blocks (if any) */ - mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->initial_offset, size_allocated, (_mali_osk_mem_mapregion_flags_t)0 ); - - _mali_osk_free(ump_blocks); - _mali_osk_free(ret_allocation); - return MALI_MEM_ALLOC_INTERNAL_FAILURE; - } - *offset += _MALI_OSK_MALI_PAGE_SIZE; - } - - _mali_osk_free( ump_blocks ); - - ret_allocation->engine = engine; - ret_allocation->descriptor = descriptor; - ret_allocation->ump_mem = ump_mem; - ret_allocation->size_allocated = *offset - ret_allocation->initial_offset; - - alloc_info->ctx = NULL; - alloc_info->handle = ret_allocation; - alloc_info->next = NULL; - alloc_info->release = ump_memory_release; - - return MALI_MEM_ALLOC_FINISHED; -} - -static void ump_memory_release(void * ctx, void * handle) -{ - ump_dd_handle ump_mem; - ump_mem_allocation *allocation; - - allocation = (ump_mem_allocation *)handle; - - MALI_DEBUG_ASSERT_POINTER( allocation ); - - ump_mem = allocation->ump_mem; - - MALI_DEBUG_ASSERT(UMP_DD_HANDLE_INVALID!=ump_mem); - - /* At present, this is a no-op. But, it allows the mali_address_manager to - * do unmapping of a subrange in future. */ - mali_allocation_engine_unmap_physical( allocation->engine, - allocation->descriptor, - allocation->initial_offset, - allocation->size_allocated, - (_mali_osk_mem_mapregion_flags_t)0 - ); - _mali_osk_free( allocation ); - - - ump_dd_reference_release(ump_mem) ; - return; -} - -_mali_osk_errcode_t _mali_ukk_attach_ump_mem( _mali_uk_attach_ump_mem_s *args ) -{ - ump_dd_handle ump_mem; - mali_physical_memory_allocator external_memory_allocator; - struct mali_session_data *session_data; - mali_memory_allocation * descriptor; - int md; - - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - - session_data = (struct mali_session_data *)args->ctx; - MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS); - - /* check arguments */ - /* NULL might be a valid Mali address */ - if ( ! args->size) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); - - /* size must be a multiple of the system page size */ - if ( args->size % _MALI_OSK_MALI_PAGE_SIZE ) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); - - MALI_DEBUG_PRINT(3, - ("Requested to map ump memory with secure id %d into virtual memory 0x%08X, size 0x%08X\n", - args->secure_id, args->mali_address, args->size)); - - ump_mem = ump_dd_handle_create_from_secure_id( (int)args->secure_id ) ; - - if ( UMP_DD_HANDLE_INVALID==ump_mem ) MALI_ERROR(_MALI_OSK_ERR_FAULT); - - descriptor = _mali_osk_calloc(1, sizeof(mali_memory_allocation)); - if (NULL == descriptor) - { - ump_dd_reference_release(ump_mem); - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - - descriptor->size = args->size; - descriptor->mapping = NULL; - descriptor->mali_address = args->mali_address; - descriptor->mali_addr_mapping_info = (void*)session_data; - descriptor->process_addr_mapping_info = NULL; /* do not map to process address space */ - descriptor->cache_settings = (u32) MALI_CACHE_STANDARD; - descriptor->lock = session_data->memory_lock; - - if (args->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) - { - descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE; - } - _mali_osk_list_init( &descriptor->list ); - - if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session_data->descriptor_mapping, descriptor, &md)) - { - ump_dd_reference_release(ump_mem); - _mali_osk_free(descriptor); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - external_memory_allocator.allocate = ump_memory_commit; - external_memory_allocator.allocate_page_table_block = NULL; - external_memory_allocator.ctx = ump_mem; - external_memory_allocator.name = "UMP Memory"; - external_memory_allocator.next = NULL; - - _mali_osk_lock_wait(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); - - if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_memory(memory_engine, descriptor, &external_memory_allocator, NULL)) - { - _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); - mali_descriptor_mapping_free(session_data->descriptor_mapping, md); - ump_dd_reference_release(ump_mem); - _mali_osk_free(descriptor); - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - - _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); - - args->cookie = md; - - MALI_DEBUG_PRINT(5,("Returning from UMP attach\n")); - - /* All OK */ - MALI_SUCCESS; -} - - -_mali_osk_errcode_t _mali_ukk_release_ump_mem( _mali_uk_release_ump_mem_s *args ) -{ - mali_memory_allocation * descriptor; - struct mali_session_data *session_data; - - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - - session_data = (struct mali_session_data *)args->ctx; - MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS); - - if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_get(session_data->descriptor_mapping, args->cookie, (void**)&descriptor)) - { - MALI_DEBUG_PRINT(1, ("Invalid memory descriptor %d used to release ump memory\n", args->cookie)); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - descriptor = mali_descriptor_mapping_free(session_data->descriptor_mapping, args->cookie); - - if (NULL != descriptor) - { - _mali_osk_lock_wait( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW ); - - mali_allocation_engine_release_memory(memory_engine, descriptor); - - _mali_osk_lock_signal( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW ); - - _mali_osk_free(descriptor); - } - - MALI_SUCCESS; - -} -#endif /* MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 */ - - -static mali_physical_memory_allocation_result external_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info) -{ - u32 * data; - external_mem_allocation * ret_allocation; - - MALI_DEBUG_ASSERT_POINTER(ctx); - MALI_DEBUG_ASSERT_POINTER(engine); - MALI_DEBUG_ASSERT_POINTER(descriptor); - MALI_DEBUG_ASSERT_POINTER(alloc_info); - - ret_allocation = _mali_osk_malloc( sizeof(external_mem_allocation) ); - - if ( NULL == ret_allocation ) - { - return MALI_MEM_ALLOC_INTERNAL_FAILURE; - } - - data = (u32*)ctx; - - ret_allocation->engine = engine; - ret_allocation->descriptor = descriptor; - ret_allocation->initial_offset = *offset; - - alloc_info->ctx = NULL; - alloc_info->handle = ret_allocation; - alloc_info->next = NULL; - alloc_info->release = external_memory_release; - - MALI_DEBUG_PRINT(5, ("External map: mapping phys 0x%08X at mali virtual address 0x%08X staring at offset 0x%08X length 0x%08X\n", data[0], descriptor->mali_address, *offset, data[1])); - - if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, data[0], 0, data[1])) - { - MALI_DEBUG_PRINT(1, ("Mapping of external memory failed\n")); - _mali_osk_free(ret_allocation); - return MALI_MEM_ALLOC_INTERNAL_FAILURE; - } - *offset += data[1]; - - if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE) - { - /* Map in an extra virtual guard page at the end of the VMA */ - MALI_DEBUG_PRINT(4, ("Mapping in extra guard page\n")); - if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, data[0], 0, _MALI_OSK_MALI_PAGE_SIZE)) - { - u32 size_allocated = *offset - ret_allocation->initial_offset; - MALI_DEBUG_PRINT(1, ("Mapping of external memory (guard page) failed\n")); - - /* unmap what we previously mapped */ - mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->initial_offset, size_allocated, (_mali_osk_mem_mapregion_flags_t)0 ); - _mali_osk_free(ret_allocation); - return MALI_MEM_ALLOC_INTERNAL_FAILURE; - } - *offset += _MALI_OSK_MALI_PAGE_SIZE; - } - - ret_allocation->size = *offset - ret_allocation->initial_offset; - - return MALI_MEM_ALLOC_FINISHED; -} - -static void external_memory_release(void * ctx, void * handle) -{ - external_mem_allocation * allocation; - - allocation = (external_mem_allocation *) handle; - MALI_DEBUG_ASSERT_POINTER( allocation ); - - /* At present, this is a no-op. But, it allows the mali_address_manager to - * do unmapping of a subrange in future. */ - - mali_allocation_engine_unmap_physical( allocation->engine, - allocation->descriptor, - allocation->initial_offset, - allocation->size, - (_mali_osk_mem_mapregion_flags_t)0 - ); - - _mali_osk_free( allocation ); - - return; -} - -_mali_osk_errcode_t _mali_ukk_map_external_mem( _mali_uk_map_external_mem_s *args ) -{ - mali_physical_memory_allocator external_memory_allocator; - struct mali_session_data *session_data; - u32 info[2]; - mali_memory_allocation * descriptor; - int md; - - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - - session_data = (struct mali_session_data *)args->ctx; - MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS); - - external_memory_allocator.allocate = external_memory_commit; - external_memory_allocator.allocate_page_table_block = NULL; - external_memory_allocator.ctx = &info[0]; - external_memory_allocator.name = "External Memory"; - external_memory_allocator.next = NULL; - - /* check arguments */ - /* NULL might be a valid Mali address */ - if ( ! args->size) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); - - /* size must be a multiple of the system page size */ - if ( args->size % _MALI_OSK_MALI_PAGE_SIZE ) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); - - MALI_DEBUG_PRINT(3, - ("Requested to map physical memory 0x%x-0x%x into virtual memory 0x%x\n", - (void*)args->phys_addr, - (void*)(args->phys_addr + args->size -1), - (void*)args->mali_address) - ); - - /* Validate the mali physical range */ - if (_MALI_OSK_ERR_OK != mali_mem_validation_check(args->phys_addr, args->size)) - { - return _MALI_OSK_ERR_FAULT; - } - - info[0] = args->phys_addr; - info[1] = args->size; - - descriptor = _mali_osk_calloc(1, sizeof(mali_memory_allocation)); - if (NULL == descriptor) MALI_ERROR(_MALI_OSK_ERR_NOMEM); - - descriptor->size = args->size; - descriptor->mapping = NULL; - descriptor->mali_address = args->mali_address; - descriptor->mali_addr_mapping_info = (void*)session_data; - descriptor->process_addr_mapping_info = NULL; /* do not map to process address space */ - descriptor->cache_settings = (u32)MALI_CACHE_STANDARD; - descriptor->lock = session_data->memory_lock; - if (args->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) - { - descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE; - } - _mali_osk_list_init( &descriptor->list ); - - _mali_osk_lock_wait(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); - - if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_memory(memory_engine, descriptor, &external_memory_allocator, NULL)) - { - _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); - _mali_osk_free(descriptor); - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - - _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); - - if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session_data->descriptor_mapping, descriptor, &md)) - { - mali_allocation_engine_release_memory(memory_engine, descriptor); - _mali_osk_free(descriptor); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - args->cookie = md; - - MALI_DEBUG_PRINT(5,("Returning from range_map_external_memory\n")); - - /* All OK */ - MALI_SUCCESS; -} - - -_mali_osk_errcode_t _mali_ukk_unmap_external_mem( _mali_uk_unmap_external_mem_s *args ) -{ - mali_memory_allocation * descriptor; - void* old_value; - struct mali_session_data *session_data; - - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - - session_data = (struct mali_session_data *)args->ctx; - MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS); - - if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_get(session_data->descriptor_mapping, args->cookie, (void**)&descriptor)) - { - MALI_DEBUG_PRINT(1, ("Invalid memory descriptor %d used to unmap external memory\n", args->cookie)); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - old_value = mali_descriptor_mapping_free(session_data->descriptor_mapping, args->cookie); - - if (NULL != old_value) - { - _mali_osk_lock_wait( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW ); - - mali_allocation_engine_release_memory(memory_engine, descriptor); - - _mali_osk_lock_signal( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW ); - - _mali_osk_free(descriptor); - } - - MALI_SUCCESS; -} - -_mali_osk_errcode_t _mali_ukk_init_mem( _mali_uk_init_mem_s *args ) -{ - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - - args->memory_size = 2 * 1024 * 1024 * 1024UL; /* 2GB address space */ - args->mali_address_base = 1 * 1024 * 1024 * 1024UL; /* staring at 1GB, causing this layout: (0-1GB unused)(1GB-3G usage by Mali)(3G-4G unused) */ - MALI_SUCCESS; -} - -_mali_osk_errcode_t _mali_ukk_term_mem( _mali_uk_term_mem_s *args ) -{ - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - MALI_SUCCESS; -} - -static _mali_osk_errcode_t mali_address_manager_allocate(mali_memory_allocation * descriptor) -{ - struct mali_session_data *session_data; - u32 actual_size; - - MALI_DEBUG_ASSERT_POINTER(descriptor); - - session_data = (struct mali_session_data *)descriptor->mali_addr_mapping_info; - - actual_size = descriptor->size; - - if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE) - { - actual_size += _MALI_OSK_MALI_PAGE_SIZE; - } - - return mali_mmu_pagedir_map(session_data->page_directory, descriptor->mali_address, actual_size); -} - -static void mali_address_manager_release(mali_memory_allocation * descriptor) -{ - const u32 illegal_mali_address = 0xffffffff; - struct mali_session_data *session_data; - MALI_DEBUG_ASSERT_POINTER(descriptor); - - /* It is allowed to call this function several times on the same descriptor. - When memory is released we set the illegal_mali_address so we can early out here. */ - if ( illegal_mali_address == descriptor->mali_address) return; - - session_data = (struct mali_session_data *)descriptor->mali_addr_mapping_info; - mali_mmu_pagedir_unmap(session_data->page_directory, descriptor->mali_address, descriptor->size); - - descriptor->mali_address = illegal_mali_address ; -} - -static _mali_osk_errcode_t mali_address_manager_map(mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size) -{ - struct mali_session_data *session_data; - u32 mali_address; - - MALI_DEBUG_ASSERT_POINTER(descriptor); - MALI_DEBUG_ASSERT_POINTER(phys_addr); - - session_data = (struct mali_session_data *)descriptor->mali_addr_mapping_info; - MALI_DEBUG_ASSERT_POINTER(session_data); - - mali_address = descriptor->mali_address + offset; - - MALI_DEBUG_PRINT(7, ("Mali map: mapping 0x%08X to Mali address 0x%08X length 0x%08X\n", *phys_addr, mali_address, size)); - - mali_mmu_pagedir_update(session_data->page_directory, mali_address, *phys_addr, size, descriptor->cache_settings); - - MALI_SUCCESS; -} - -/* This handler registered to mali_mmap for MMU builds */ -_mali_osk_errcode_t _mali_ukk_mem_mmap( _mali_uk_mem_mmap_s *args ) -{ - struct mali_session_data *session_data; - mali_memory_allocation * descriptor; - - /* validate input */ - if (NULL == args) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: args was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); } - - /* Unpack arguments */ - session_data = (struct mali_session_data *)args->ctx; - - /* validate input */ - if (NULL == session_data) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: session data was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_FAULT); } - - descriptor = (mali_memory_allocation*) _mali_osk_calloc( 1, sizeof(mali_memory_allocation) ); - if (NULL == descriptor) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: descriptor was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_NOMEM); } - - descriptor->size = args->size; - descriptor->mali_address = args->phys_addr; - descriptor->mali_addr_mapping_info = (void*)session_data; - - descriptor->process_addr_mapping_info = args->ukk_private; /* save to be used during physical manager callback */ - descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE; - descriptor->cache_settings = (u32) args->cache_settings ; - descriptor->lock = session_data->memory_lock; - _mali_osk_list_init( &descriptor->list ); - - _mali_osk_lock_wait(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); - - if (0 == mali_allocation_engine_allocate_memory(memory_engine, descriptor, physical_memory_allocators, &session_data->memory_head)) - { - /* We do not FLUSH nor TLB_ZAP on MMAP, since we do both of those on job start*/ - _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); - - args->mapping = descriptor->mapping; - args->cookie = (u32)descriptor; - - MALI_DEBUG_PRINT(7, ("MMAP OK\n")); - MALI_SUCCESS; - } - else - { - _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); - /* OOM, but not a fatal error */ - MALI_DEBUG_PRINT(4, ("Memory allocation failure, OOM\n")); - _mali_osk_free(descriptor); - /* Linux will free the CPU address allocation, userspace client the Mali address allocation */ - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } -} - -static _mali_osk_errcode_t _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args ) -{ - struct mali_session_data *session_data; - mali_memory_allocation * descriptor; - - u32 num_groups = mali_group_get_glob_num_groups(); - struct mali_group *group; - u32 i; - - descriptor = (mali_memory_allocation *)args->cookie; - MALI_DEBUG_ASSERT_POINTER(descriptor); - - /** @note args->context unused; we use the memory_session from the cookie */ - /* args->mapping and args->size are also discarded. They are only necessary - for certain do_munmap implementations. However, they could be used to check the - descriptor at this point. */ - - session_data = (struct mali_session_data *)descriptor->mali_addr_mapping_info; - MALI_DEBUG_ASSERT_POINTER(session_data); - - /* Unmapping the memory from the mali virtual address space. - It is allowed to call this function severeal times, which might happen if zapping below fails. */ - mali_allocation_engine_release_pt1_mali_pagetables_unmap(memory_engine, descriptor); - -#ifdef MALI_UNMAP_FLUSH_ALL_MALI_L2 - { - u32 number_of_clusters = mali_cluster_get_glob_num_clusters(); - for (i = 0; i < number_of_clusters; i++) - { - struct mali_cluster *cluster; - cluster = mali_cluster_get_global_cluster(i); - if( mali_cluster_power_is_enabled_get(cluster) ) - { - mali_cluster_l2_cache_invalidate_all_force(cluster); - } - } - } -#endif - - for (i = 0; i < num_groups; i++) - { - group = mali_group_get_glob_group(i); - mali_group_lock(group); - mali_group_remove_session_if_unused(group, session_data); - if (mali_group_get_session(group) == session_data) - { - /* The Zap also does the stall and disable_stall */ - mali_bool zap_success = mali_mmu_zap_tlb(mali_group_get_mmu(group)); - if (MALI_TRUE != zap_success) - { - MALI_DEBUG_PRINT(2, ("Mali memory unmap failed. Doing pagefault handling.\n")); - mali_group_bottom_half(group, GROUP_EVENT_MMU_PAGE_FAULT); - /* The bottom half will also do the unlock */ - continue; - } - } - mali_group_unlock(group); - } - - /* Removes the descriptor from the session's memory list, releases physical memory, releases descriptor */ - mali_allocation_engine_release_pt2_physical_memory_free(memory_engine, descriptor); - - _mali_osk_free(descriptor); - - return _MALI_OSK_ERR_OK; -} - -/* Handler for unmapping memory for MMU builds */ -_mali_osk_errcode_t _mali_ukk_mem_munmap( _mali_uk_mem_munmap_s *args ) -{ - mali_memory_allocation * descriptor; - _mali_osk_lock_t *descriptor_lock; - _mali_osk_errcode_t err; - - descriptor = (mali_memory_allocation *)args->cookie; - MALI_DEBUG_ASSERT_POINTER(descriptor); - - /** @note args->context unused; we use the memory_session from the cookie */ - /* args->mapping and args->size are also discarded. They are only necessary - for certain do_munmap implementations. However, they could be used to check the - descriptor at this point. */ - - MALI_DEBUG_ASSERT_POINTER((struct mali_session_data *)descriptor->mali_addr_mapping_info); - - descriptor_lock = descriptor->lock; /* should point to the session data lock... */ - - err = _MALI_OSK_ERR_BUSY; - while (err == _MALI_OSK_ERR_BUSY) - { - if (descriptor_lock) - { - _mali_osk_lock_wait( descriptor_lock, _MALI_OSK_LOCKMODE_RW ); - } - - err = _mali_ukk_mem_munmap_internal( args ); - - if (descriptor_lock) - { - _mali_osk_lock_signal( descriptor_lock, _MALI_OSK_LOCKMODE_RW ); - } - - if (err == _MALI_OSK_ERR_BUSY) - { - /* - * Reason for this; - * We where unable to stall the MMU, probably because we are in page fault handling. - * Sleep for a while with the session lock released, then try again. - * Abnormal termination of programs with running Mali jobs is a normal reason for this. - */ - _mali_osk_time_ubusydelay(10); - } - } - - return err; -} - -u32 _mali_ukk_report_memory_usage(void) -{ - return mali_allocation_engine_memory_usage(physical_memory_allocators); -} - -_mali_osk_errcode_t mali_mmu_get_table_page(u32 *table_page, mali_io_address *mapping) -{ - _mali_osk_lock_wait(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); - - if (0 == _mali_osk_list_empty(&page_table_cache.partial)) - { - mali_mmu_page_table_allocation * alloc = _MALI_OSK_LIST_ENTRY(page_table_cache.partial.next, mali_mmu_page_table_allocation, list); - int page_number = _mali_osk_find_first_zero_bit(alloc->usage_map, alloc->num_pages); - MALI_DEBUG_PRINT(6, ("Partial page table allocation found, using page offset %d\n", page_number)); - _mali_osk_set_nonatomic_bit(page_number, alloc->usage_map); - alloc->usage_count++; - if (alloc->num_pages == alloc->usage_count) - { - /* full, move alloc to full list*/ - _mali_osk_list_move(&alloc->list, &page_table_cache.full); - } - _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); - - *table_page = (MALI_MMU_PAGE_SIZE * page_number) + alloc->pages.phys_base; - *mapping = (mali_io_address)((MALI_MMU_PAGE_SIZE * page_number) + (u32)alloc->pages.mapping); - MALI_DEBUG_PRINT(4, ("Page table allocated for VA=0x%08X, MaliPA=0x%08X\n", *mapping, *table_page )); - MALI_SUCCESS; - } - else - { - mali_mmu_page_table_allocation * alloc; - /* no free pages, allocate a new one */ - - alloc = (mali_mmu_page_table_allocation *)_mali_osk_calloc(1, sizeof(mali_mmu_page_table_allocation)); - if (NULL == alloc) - { - _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); - *table_page = MALI_INVALID_PAGE; - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - - _MALI_OSK_INIT_LIST_HEAD(&alloc->list); - - if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_page_tables(memory_engine, &alloc->pages, physical_memory_allocators)) - { - MALI_DEBUG_PRINT(1, ("No more memory for page tables\n")); - _mali_osk_free(alloc); - _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); - *table_page = MALI_INVALID_PAGE; - *mapping = NULL; - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - - /* create the usage map */ - alloc->num_pages = alloc->pages.size / MALI_MMU_PAGE_SIZE; - alloc->usage_count = 1; - MALI_DEBUG_PRINT(3, ("New page table cache expansion, %d pages in new cache allocation\n", alloc->num_pages)); - alloc->usage_map = _mali_osk_calloc(1, ((alloc->num_pages + BITS_PER_LONG - 1) & ~(BITS_PER_LONG-1) / BITS_PER_LONG) * sizeof(unsigned long)); - if (NULL == alloc->usage_map) - { - MALI_DEBUG_PRINT(1, ("Failed to allocate memory to describe MMU page table cache usage\n")); - alloc->pages.release(&alloc->pages); - _mali_osk_free(alloc); - _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); - *table_page = MALI_INVALID_PAGE; - *mapping = NULL; - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - - _mali_osk_set_nonatomic_bit(0, alloc->usage_map); - - if (alloc->num_pages > 1) - { - _mali_osk_list_add(&alloc->list, &page_table_cache.partial); - } - else - { - _mali_osk_list_add(&alloc->list, &page_table_cache.full); - } - - _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); - *table_page = alloc->pages.phys_base; /* return the first page */ - *mapping = alloc->pages.mapping; /* Mapping for first page */ - MALI_DEBUG_PRINT(4, ("Page table allocated: VA=0x%08X, MaliPA=0x%08X\n", *mapping, *table_page )); - MALI_SUCCESS; - } -} - -void mali_mmu_release_table_page(u32 pa) -{ - mali_mmu_page_table_allocation * alloc, * temp_alloc; - - MALI_DEBUG_PRINT_IF(1, pa & 4095, ("Bad page address 0x%x given to mali_mmu_release_table_page\n", (void*)pa)); - - MALI_DEBUG_PRINT(4, ("Releasing table page 0x%08X to the cache\n", pa)); - - _mali_osk_lock_wait(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); - - /* find the entry this address belongs to */ - /* first check the partial list */ - _MALI_OSK_LIST_FOREACHENTRY(alloc, temp_alloc, &page_table_cache.partial, mali_mmu_page_table_allocation, list) - { - u32 start = alloc->pages.phys_base; - u32 last = start + (alloc->num_pages - 1) * MALI_MMU_PAGE_SIZE; - if (pa >= start && pa <= last) - { - MALI_DEBUG_ASSERT(0 != _mali_osk_test_bit((pa - start)/MALI_MMU_PAGE_SIZE, alloc->usage_map)); - _mali_osk_clear_nonatomic_bit((pa - start)/MALI_MMU_PAGE_SIZE, alloc->usage_map); - alloc->usage_count--; - - _mali_osk_memset((void*)( ((u32)alloc->pages.mapping) + (pa - start) ), 0, MALI_MMU_PAGE_SIZE); - - if (0 == alloc->usage_count) - { - /* empty, release whole page alloc */ - _mali_osk_list_del(&alloc->list); - alloc->pages.release(&alloc->pages); - _mali_osk_free(alloc->usage_map); - _mali_osk_free(alloc); - } - _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); - MALI_DEBUG_PRINT(4, ("(partial list)Released table page 0x%08X to the cache\n", pa)); - return; - } - } - - /* the check the full list */ - _MALI_OSK_LIST_FOREACHENTRY(alloc, temp_alloc, &page_table_cache.full, mali_mmu_page_table_allocation, list) - { - u32 start = alloc->pages.phys_base; - u32 last = start + (alloc->num_pages - 1) * MALI_MMU_PAGE_SIZE; - if (pa >= start && pa <= last) - { - _mali_osk_clear_nonatomic_bit((pa - start)/MALI_MMU_PAGE_SIZE, alloc->usage_map); - alloc->usage_count--; - - _mali_osk_memset((void*)( ((u32)alloc->pages.mapping) + (pa - start) ), 0, MALI_MMU_PAGE_SIZE); - - - if (0 == alloc->usage_count) - { - /* empty, release whole page alloc */ - _mali_osk_list_del(&alloc->list); - alloc->pages.release(&alloc->pages); - _mali_osk_free(alloc->usage_map); - _mali_osk_free(alloc); - } - else - { - /* transfer to partial list */ - _mali_osk_list_move(&alloc->list, &page_table_cache.partial); - } - - _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); - MALI_DEBUG_PRINT(4, ("(full list)Released table page 0x%08X to the cache\n", pa)); - return; - } - } - - MALI_DEBUG_PRINT(1, ("pa 0x%x not found in the page table cache\n", (void*)pa)); - - _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); -} - -static _mali_osk_errcode_t mali_mmu_page_table_cache_create(void) -{ - page_table_cache.lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_ONELOCK - | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_MEM_PT_CACHE); - MALI_CHECK_NON_NULL( page_table_cache.lock, _MALI_OSK_ERR_FAULT ); - _MALI_OSK_INIT_LIST_HEAD(&page_table_cache.partial); - _MALI_OSK_INIT_LIST_HEAD(&page_table_cache.full); - MALI_SUCCESS; -} - -static void mali_mmu_page_table_cache_destroy(void) -{ - mali_mmu_page_table_allocation * alloc, *temp; - - _MALI_OSK_LIST_FOREACHENTRY(alloc, temp, &page_table_cache.partial, mali_mmu_page_table_allocation, list) - { - MALI_DEBUG_PRINT_IF(1, 0 != alloc->usage_count, ("Destroying page table cache while pages are tagged as in use. %d allocations still marked as in use.\n", alloc->usage_count)); - _mali_osk_list_del(&alloc->list); - alloc->pages.release(&alloc->pages); - _mali_osk_free(alloc->usage_map); - _mali_osk_free(alloc); - } - - MALI_DEBUG_PRINT_IF(1, 0 == _mali_osk_list_empty(&page_table_cache.full), ("Page table cache full list contains one or more elements \n")); - - _MALI_OSK_LIST_FOREACHENTRY(alloc, temp, &page_table_cache.full, mali_mmu_page_table_allocation, list) - { - MALI_DEBUG_PRINT(1, ("Destroy alloc 0x%08X with usage count %d\n", (u32)alloc, alloc->usage_count)); - _mali_osk_list_del(&alloc->list); - alloc->pages.release(&alloc->pages); - _mali_osk_free(alloc->usage_map); - _mali_osk_free(alloc); - } - - _mali_osk_lock_term(page_table_cache.lock); -} diff --git a/drivers/media/video/samsung/mali/common/mali_memory.h b/drivers/media/video/samsung/mali/common/mali_memory.h deleted file mode 100644 index 78e2945..0000000 --- a/drivers/media/video/samsung/mali/common/mali_memory.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_MEMORY_H__ -#define __MALI_MEMORY_H__ - -#include "mali_osk.h" -#include "mali_session.h" - -struct mali_cluster; -struct mali_group; - -/** @brief Initialize Mali memory subsystem - * - * Allocate and initialize internal data structures. Must be called before - * allocating Mali memory. - * - * @return On success _MALI_OSK_ERR_OK, othervise some error code describing the error. - */ -_mali_osk_errcode_t mali_memory_initialize(void); - -/** @brief Terminate Mali memory system - * - * Clean up and release internal data structures. - */ -void mali_memory_terminate(void); - -/** @brief Start new Mali memory session - * - * Allocate and prepare session specific memory allocation data data. The - * session page directory, lock, and descriptor map is set up. - * - * @param mali_session_data pointer to the session data structure - */ -_mali_osk_errcode_t mali_memory_session_begin(struct mali_session_data *mali_session_data); - -/** @brief Close a Mali memory session - * - * Release session specific memory allocation related data. - * - * @param mali_session_data pointer to the session data structure - */ -void mali_memory_session_end(struct mali_session_data *mali_session_data); - -/** @brief Allocate a page table page - * - * Allocate a page for use as a page directory or page table. The page is - * mapped into kernel space. - * - * @return _MALI_OSK_ERR_OK on success, othervise an error code - * @param table_page GPU pointer to the allocated page - * @param mapping CPU pointer to the mapping of the allocated page - */ -_mali_osk_errcode_t mali_mmu_get_table_page(u32 *table_page, mali_io_address *mapping); - -/** @brief Release a page table page - * - * Release a page table page allocated through \a mali_mmu_get_table_page - * - * @param pa the GPU address of the page to release - */ -void mali_mmu_release_table_page(u32 pa); - - -/** @brief Parse resource and prepare the OS memory allocator - */ -_mali_osk_errcode_t mali_memory_core_resource_os_memory(_mali_osk_resource_t * resource); - -/** @brief Parse resource and prepare the dedicated memory allocator - */ -_mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(_mali_osk_resource_t * resource); - -mali_allocation_engine mali_mem_get_memory_engine(void); - -#endif /* __MALI_MEMORY_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_mmu.c b/drivers/media/video/samsung/mali/common/mali_mmu.c deleted file mode 100644 index 2f2fa4d..0000000 --- a/drivers/media/video/samsung/mali/common/mali_mmu.c +++ /dev/null @@ -1,619 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "mali_osk_bitops.h" -#include "mali_osk_list.h" -#include "mali_ukk.h" - -#include "mali_mmu.h" -#include "mali_hw_core.h" -#include "mali_group.h" -#include "mali_mmu_page_directory.h" - -/** - * Size of the MMU registers in bytes - */ -#define MALI_MMU_REGISTERS_SIZE 0x24 - -/** - * MMU register numbers - * Used in the register read/write routines. - * See the hardware documentation for more information about each register - */ -typedef enum mali_mmu_register { - MALI_MMU_REGISTER_DTE_ADDR = 0x0000, /**< Current Page Directory Pointer */ - MALI_MMU_REGISTER_STATUS = 0x0004, /**< Status of the MMU */ - MALI_MMU_REGISTER_COMMAND = 0x0008, /**< Command register, used to control the MMU */ - MALI_MMU_REGISTER_PAGE_FAULT_ADDR = 0x000C, /**< Logical address of the last page fault */ - MALI_MMU_REGISTER_ZAP_ONE_LINE = 0x010, /**< Used to invalidate the mapping of a single page from the MMU */ - MALI_MMU_REGISTER_INT_RAWSTAT = 0x0014, /**< Raw interrupt status, all interrupts visible */ - MALI_MMU_REGISTER_INT_CLEAR = 0x0018, /**< Indicate to the MMU that the interrupt has been received */ - MALI_MMU_REGISTER_INT_MASK = 0x001C, /**< Enable/disable types of interrupts */ - MALI_MMU_REGISTER_INT_STATUS = 0x0020 /**< Interrupt status based on the mask */ -} mali_mmu_register; - -/** - * MMU interrupt register bits - * Each cause of the interrupt is reported - * through the (raw) interrupt status registers. - * Multiple interrupts can be pending, so multiple bits - * can be set at once. - */ -typedef enum mali_mmu_interrupt -{ - MALI_MMU_INTERRUPT_PAGE_FAULT = 0x01, /**< A page fault occured */ - MALI_MMU_INTERRUPT_READ_BUS_ERROR = 0x02 /**< A bus read error occured */ -} mali_mmu_interrupt; - -/** - * MMU commands - * These are the commands that can be sent - * to the MMU unit. - */ -typedef enum mali_mmu_command -{ - MALI_MMU_COMMAND_ENABLE_PAGING = 0x00, /**< Enable paging (memory translation) */ - MALI_MMU_COMMAND_DISABLE_PAGING = 0x01, /**< Disable paging (memory translation) */ - MALI_MMU_COMMAND_ENABLE_STALL = 0x02, /**< Enable stall on page fault */ - MALI_MMU_COMMAND_DISABLE_STALL = 0x03, /**< Disable stall on page fault */ - MALI_MMU_COMMAND_ZAP_CACHE = 0x04, /**< Zap the entire page table cache */ - MALI_MMU_COMMAND_PAGE_FAULT_DONE = 0x05, /**< Page fault processed */ - MALI_MMU_COMMAND_HARD_RESET = 0x06 /**< Reset the MMU back to power-on settings */ -} mali_mmu_command; - -typedef enum mali_mmu_status_bits -{ - MALI_MMU_STATUS_BIT_PAGING_ENABLED = 1 << 0, - MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE = 1 << 1, - MALI_MMU_STATUS_BIT_STALL_ACTIVE = 1 << 2, - MALI_MMU_STATUS_BIT_IDLE = 1 << 3, - MALI_MMU_STATUS_BIT_REPLAY_BUFFER_EMPTY = 1 << 4, - MALI_MMU_STATUS_BIT_PAGE_FAULT_IS_WRITE = 1 << 5, -} mali_mmu_status_bits; - -/** - * Definition of the MMU struct - * Used to track a MMU unit in the system. - * Contains information about the mapping of the registers - */ -struct mali_mmu_core -{ - struct mali_hw_core hw_core; /**< Common for all HW cores */ - struct mali_group *group; /**< Parent core group */ - _mali_osk_irq_t *irq; /**< IRQ handler */ -}; - -/** - * The MMU interrupt handler - * Upper half of the MMU interrupt processing. - * Called by the kernel when the MMU has triggered an interrupt. - * The interrupt function supports IRQ sharing. So it'll probe the MMU in question - * @param irq The irq number (not used) - * @param dev_id Points to the MMU object being handled - * @param regs Registers of interrupted process (not used) - * @return Standard Linux interrupt result. - * Subset used by the driver is IRQ_HANDLED processed - * IRQ_NONE Not processed - */ -static _mali_osk_errcode_t mali_mmu_upper_half(void * data); - -/** - * The MMU reset hander - * Bottom half of the MMU interrupt processing for page faults and bus errors - * @param work The item to operate on, NULL in our case - */ -static void mali_mmu_bottom_half(void *data); - -static void mali_mmu_probe_trigger(void *data); -static _mali_osk_errcode_t mali_mmu_probe_ack(void *data); - -MALI_STATIC_INLINE _mali_osk_errcode_t mali_mmu_raw_reset(struct mali_mmu_core *mmu); - -/* page fault queue flush helper pages - * note that the mapping pointers are currently unused outside of the initialization functions */ -static u32 mali_page_fault_flush_page_directory = MALI_INVALID_PAGE; -static u32 mali_page_fault_flush_page_table = MALI_INVALID_PAGE; -static u32 mali_page_fault_flush_data_page = MALI_INVALID_PAGE; - -/* an empty page directory (no address valid) which is active on any MMU not currently marked as in use */ -static u32 mali_empty_page_directory = MALI_INVALID_PAGE; - -_mali_osk_errcode_t mali_mmu_initialize(void) -{ - /* allocate the helper pages */ - mali_empty_page_directory = mali_allocate_empty_page(); - if(0 == mali_empty_page_directory) - { - mali_empty_page_directory = MALI_INVALID_PAGE; - return _MALI_OSK_ERR_NOMEM; - } - - if (_MALI_OSK_ERR_OK != mali_create_fault_flush_pages(&mali_page_fault_flush_page_directory, - &mali_page_fault_flush_page_table, &mali_page_fault_flush_data_page)) - { - mali_free_empty_page(mali_empty_page_directory); - return _MALI_OSK_ERR_FAULT; - } - - return _MALI_OSK_ERR_OK; -} - -void mali_mmu_terminate(void) -{ - MALI_DEBUG_PRINT(3, ("Mali MMU: terminating\n")); - - /* Free global helper pages */ - mali_free_empty_page(mali_empty_page_directory); - - /* Free the page fault flush pages */ - mali_destroy_fault_flush_pages(&mali_page_fault_flush_page_directory, - &mali_page_fault_flush_page_table, &mali_page_fault_flush_data_page); -} - -struct mali_mmu_core *mali_mmu_create(_mali_osk_resource_t *resource) -{ - struct mali_mmu_core* mmu = NULL; - - MALI_DEBUG_ASSERT_POINTER(resource); - - MALI_DEBUG_PRINT(2, ("Mali MMU: Creating Mali MMU: %s\n", resource->description)); - - mmu = _mali_osk_calloc(1,sizeof(struct mali_mmu_core)); - if (NULL != mmu) - { - if (_MALI_OSK_ERR_OK == mali_hw_core_create(&mmu->hw_core, resource, MALI_MMU_REGISTERS_SIZE)) - { - if (_MALI_OSK_ERR_OK == mali_mmu_reset(mmu)) - { - /* Setup IRQ handlers (which will do IRQ probing if needed) */ - mmu->irq = _mali_osk_irq_init(resource->irq, - mali_mmu_upper_half, - mali_mmu_bottom_half, - mali_mmu_probe_trigger, - mali_mmu_probe_ack, - mmu, - "mali_mmu_irq_handlers"); - if (NULL != mmu->irq) - { - return mmu; - } - else - { - MALI_PRINT_ERROR(("Failed to setup interrupt handlers for MMU %s\n", mmu->hw_core.description)); - } - } - mali_hw_core_delete(&mmu->hw_core); - } - - _mali_osk_free(mmu); - } - else - { - MALI_PRINT_ERROR(("Failed to allocate memory for MMU\n")); - } - - return NULL; -} - -void mali_mmu_delete(struct mali_mmu_core *mmu) -{ - _mali_osk_irq_term(mmu->irq); - mali_hw_core_delete(&mmu->hw_core); - _mali_osk_free(mmu); -} - -void mali_mmu_set_group(struct mali_mmu_core *mmu, struct mali_group *group) -{ - mmu->group = group; -} - -static void mali_mmu_enable_paging(struct mali_mmu_core *mmu) -{ - const int max_loop_count = 100; - const int delay_in_usecs = 1; - int i; - - mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_PAGING); - - for (i = 0; i < max_loop_count; ++i) - { - if (mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_PAGING_ENABLED) - { - break; - } - _mali_osk_time_ubusydelay(delay_in_usecs); - } - if (max_loop_count == i) - { - MALI_PRINT_ERROR(("Enable paging request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS))); - } -} - -mali_bool mali_mmu_enable_stall(struct mali_mmu_core *mmu) -{ - const int max_loop_count = 100; - const int delay_in_usecs = 999; - int i; - u32 mmu_status; - - /* There are no group when it is called from mali_mmu_create */ - if ( mmu->group ) MALI_ASSERT_GROUP_LOCKED(mmu->group); - - mmu_status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS); - - if ( 0 == (mmu_status & MALI_MMU_STATUS_BIT_PAGING_ENABLED) ) - { - MALI_DEBUG_PRINT(4, ("MMU stall is implicit when Paging is not enebled.\n")); - return MALI_TRUE; - } - - if ( mmu_status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE ) - { - MALI_DEBUG_PRINT(3, ("Aborting MMU stall request since it is in pagefault state.\n")); - return MALI_FALSE; - } - - mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_STALL); - - for (i = 0; i < max_loop_count; ++i) - { - mmu_status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS); - if ( mmu_status & (MALI_MMU_STATUS_BIT_STALL_ACTIVE|MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE)) - { - break; - } - if ( 0 == (mmu_status & ( MALI_MMU_STATUS_BIT_PAGING_ENABLED ))) - { - break; - } - _mali_osk_time_ubusydelay(delay_in_usecs); - } - if (max_loop_count == i) - { - MALI_PRINT_ERROR(("Enable stall request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS))); - return MALI_FALSE; - } - - if ( mmu_status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE ) - { - MALI_DEBUG_PRINT(3, ("Aborting MMU stall request since it has a pagefault.\n")); - return MALI_FALSE; - } - - return MALI_TRUE; -} - -void mali_mmu_disable_stall(struct mali_mmu_core *mmu) -{ - const int max_loop_count = 100; - const int delay_in_usecs = 1; - int i; - u32 mmu_status; - /* There are no group when it is called from mali_mmu_create */ - if ( mmu->group ) MALI_ASSERT_GROUP_LOCKED(mmu->group); - - mmu_status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS); - - if ( 0 == (mmu_status & MALI_MMU_STATUS_BIT_PAGING_ENABLED )) - { - MALI_DEBUG_PRINT(3, ("MMU disable skipped since it was not enabled.\n")); - return; - } - if (mmu_status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE) - { - MALI_DEBUG_PRINT(2, ("Aborting MMU disable stall request since it is in pagefault state.\n")); - return; - } - - mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_DISABLE_STALL); - - for (i = 0; i < max_loop_count; ++i) - { - u32 status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS); - if ( 0 == (status & MALI_MMU_STATUS_BIT_STALL_ACTIVE) ) - { - break; - } - if ( status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE ) - { - break; - } - if ( 0 == (mmu_status & MALI_MMU_STATUS_BIT_PAGING_ENABLED )) - { - break; - } - _mali_osk_time_ubusydelay(delay_in_usecs); - } - if (max_loop_count == i) MALI_DEBUG_PRINT(1,("Disable stall request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS))); -} - -void mali_mmu_page_fault_done(struct mali_mmu_core *mmu) -{ - MALI_ASSERT_GROUP_LOCKED(mmu->group); - MALI_DEBUG_PRINT(4, ("Mali MMU: %s: Leaving page fault mode\n", mmu->hw_core.description)); - mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_PAGE_FAULT_DONE); -} - -MALI_STATIC_INLINE _mali_osk_errcode_t mali_mmu_raw_reset(struct mali_mmu_core *mmu) -{ - const int max_loop_count = 100; - const int delay_in_usecs = 1; - int i; - /* The _if_ is neccessary when called from mali_mmu_create and NULL==group */ - if (mmu->group)MALI_ASSERT_GROUP_LOCKED(mmu->group); - - mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR, 0xCAFEBABE); - mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_HARD_RESET); - - for (i = 0; i < max_loop_count; ++i) - { - if (mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR) == 0) - { - break; - } - _mali_osk_time_ubusydelay(delay_in_usecs); - } - if (max_loop_count == i) - { - MALI_PRINT_ERROR(("Reset request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS))); - return _MALI_OSK_ERR_FAULT; - } - - return _MALI_OSK_ERR_OK; -} - -_mali_osk_errcode_t mali_mmu_reset(struct mali_mmu_core *mmu) -{ - _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT; - mali_bool stall_success; - MALI_DEBUG_ASSERT_POINTER(mmu); - /* The _if_ is neccessary when called from mali_mmu_create and NULL==group */ - if (mmu->group) - { - MALI_ASSERT_GROUP_LOCKED(mmu->group); - } - - stall_success = mali_mmu_enable_stall(mmu); - - /* The stall can not fail in current hw-state */ - MALI_DEBUG_ASSERT(stall_success); - - MALI_DEBUG_PRINT(3, ("Mali MMU: mali_kernel_mmu_reset: %s\n", mmu->hw_core.description)); - - if (_MALI_OSK_ERR_OK == mali_mmu_raw_reset(mmu)) - { - mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK, MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR); - /* no session is active, so just activate the empty page directory */ - mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR, mali_empty_page_directory); - mali_mmu_enable_paging(mmu); - err = _MALI_OSK_ERR_OK; - } - mali_mmu_disable_stall(mmu); - - return err; -} - - -/* ------------- interrupt handling below ------------------ */ - -static _mali_osk_errcode_t mali_mmu_upper_half(void * data) -{ - struct mali_mmu_core *mmu = (struct mali_mmu_core *)data; - u32 int_stat; - - MALI_DEBUG_ASSERT_POINTER(mmu); - - /* Check if it was our device which caused the interrupt (we could be sharing the IRQ line) */ - int_stat = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_STATUS); - if (0 != int_stat) - { - mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK, 0); - mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS); - - if (int_stat & MALI_MMU_INTERRUPT_PAGE_FAULT) - { - _mali_osk_irq_schedulework(mmu->irq); - } - - if (int_stat & MALI_MMU_INTERRUPT_READ_BUS_ERROR) - { - /* clear interrupt flag */ - mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_READ_BUS_ERROR); - /* reenable it */ - mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK, - mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK) | MALI_MMU_INTERRUPT_READ_BUS_ERROR); - MALI_PRINT_ERROR(("Mali MMU: Read bus error\n")); - } - return _MALI_OSK_ERR_OK; - } - - return _MALI_OSK_ERR_FAULT; -} - -static void mali_mmu_bottom_half(void * data) -{ - struct mali_mmu_core *mmu = (struct mali_mmu_core*)data; - u32 raw, status, fault_address; - - MALI_DEBUG_ASSERT_POINTER(mmu); - - MALI_DEBUG_PRINT(3, ("Mali MMU: Page fault bottom half: Locking subsystems\n")); - - mali_group_lock(mmu->group); /* Unlocked in mali_group_bottom_half */ - - if ( MALI_FALSE == mali_group_power_is_on(mmu->group) ) - { - MALI_PRINT_ERROR(("Interrupt bottom half of %s when core is OFF.",mmu->hw_core.description)); - mali_group_unlock(mmu->group); - return; - } - - raw = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_RAWSTAT); - status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS); - - if ( (0==(raw & MALI_MMU_INTERRUPT_PAGE_FAULT)) && (0==(status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE)) ) - { - MALI_DEBUG_PRINT(2, ("Mali MMU: Page fault bottom half: No Irq found.\n")); - mali_group_unlock(mmu->group); - /* MALI_DEBUG_ASSERT(0); */ - return; - } - - /* An actual page fault has occurred. */ - - fault_address = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_PAGE_FAULT_ADDR); - - MALI_DEBUG_PRINT(2,("Mali MMU: Page fault detected at 0x%x from bus id %d of type %s on %s\n", - (void*)fault_address, - (status >> 6) & 0x1F, - (status & 32) ? "write" : "read", - mmu->hw_core.description)); - - mali_group_bottom_half(mmu->group, GROUP_EVENT_MMU_PAGE_FAULT); /* Unlocks the group lock */ -} - -mali_bool mali_mmu_zap_tlb(struct mali_mmu_core *mmu) -{ - mali_bool stall_success; - MALI_ASSERT_GROUP_LOCKED(mmu->group); - - stall_success = mali_mmu_enable_stall(mmu); - - mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE); - - if (MALI_FALSE == stall_success) - { - /* False means that it is in Pagefault state. Not possible to disable_stall then */ - return MALI_FALSE; - } - - mali_mmu_disable_stall(mmu); - return MALI_TRUE; -} - -void mali_mmu_zap_tlb_without_stall(struct mali_mmu_core *mmu) -{ - MALI_ASSERT_GROUP_LOCKED(mmu->group); - mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE); -} - - -void mali_mmu_invalidate_page(struct mali_mmu_core *mmu, u32 mali_address) -{ - MALI_ASSERT_GROUP_LOCKED(mmu->group); - mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_ZAP_ONE_LINE, MALI_MMU_PDE_ENTRY(mali_address)); -} - -static void mali_mmu_activate_address_space(struct mali_mmu_core *mmu, u32 page_directory) -{ - MALI_ASSERT_GROUP_LOCKED(mmu->group); - /* The MMU must be in stalled or page fault mode, for this writing to work */ - MALI_DEBUG_ASSERT( 0 != ( mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS) - & (MALI_MMU_STATUS_BIT_STALL_ACTIVE|MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE) ) ); - mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR, page_directory); - mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE); - -} - -mali_bool mali_mmu_activate_page_directory(struct mali_mmu_core *mmu, struct mali_page_directory *pagedir) -{ - mali_bool stall_success; - MALI_DEBUG_ASSERT_POINTER(mmu); - MALI_ASSERT_GROUP_LOCKED(mmu->group); - - MALI_DEBUG_PRINT(5, ("Asked to activate page directory 0x%x on MMU %s\n", pagedir, mmu->hw_core.description)); - stall_success = mali_mmu_enable_stall(mmu); - - if ( MALI_FALSE==stall_success ) return MALI_FALSE; - mali_mmu_activate_address_space(mmu, pagedir->page_directory); - mali_mmu_disable_stall(mmu); - return MALI_TRUE; -} - -void mali_mmu_activate_empty_page_directory(struct mali_mmu_core* mmu) -{ - mali_bool stall_success; - MALI_DEBUG_ASSERT_POINTER(mmu); - MALI_ASSERT_GROUP_LOCKED(mmu->group); - MALI_DEBUG_PRINT(3, ("Activating the empty page directory on MMU %s\n", mmu->hw_core.description)); - - stall_success = mali_mmu_enable_stall(mmu); - /* This function can only be called when the core is idle, so it could not fail. */ - MALI_DEBUG_ASSERT( stall_success ); - mali_mmu_activate_address_space(mmu, mali_empty_page_directory); - mali_mmu_disable_stall(mmu); -} - -void mali_mmu_activate_fault_flush_page_directory(struct mali_mmu_core* mmu) -{ - mali_bool stall_success; - MALI_DEBUG_ASSERT_POINTER(mmu); - MALI_ASSERT_GROUP_LOCKED(mmu->group); - - MALI_DEBUG_PRINT(3, ("Activating the page fault flush page directory on MMU %s\n", mmu->hw_core.description)); - stall_success = mali_mmu_enable_stall(mmu); - /* This function is expect to fail the stalling, since it might be in PageFault mode when it is called */ - mali_mmu_activate_address_space(mmu, mali_page_fault_flush_page_directory); - if ( MALI_TRUE==stall_success ) mali_mmu_disable_stall(mmu); -} - -/* Is called when we want the mmu to give an interrupt */ -static void mali_mmu_probe_trigger(void *data) -{ - struct mali_mmu_core *mmu = (struct mali_mmu_core *)data; - mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_RAWSTAT, MALI_MMU_INTERRUPT_PAGE_FAULT|MALI_MMU_INTERRUPT_READ_BUS_ERROR); -} - -/* Is called when the irq probe wants the mmu to acknowledge an interrupt from the hw */ -static _mali_osk_errcode_t mali_mmu_probe_ack(void *data) -{ - struct mali_mmu_core *mmu = (struct mali_mmu_core *)data; - u32 int_stat; - - int_stat = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_STATUS); - - MALI_DEBUG_PRINT(2, ("mali_mmu_probe_irq_acknowledge: intstat 0x%x\n", int_stat)); - if (int_stat & MALI_MMU_INTERRUPT_PAGE_FAULT) - { - MALI_DEBUG_PRINT(2, ("Probe: Page fault detect: PASSED\n")); - mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_PAGE_FAULT); - } - else - { - MALI_DEBUG_PRINT(1, ("Probe: Page fault detect: FAILED\n")); - } - - if (int_stat & MALI_MMU_INTERRUPT_READ_BUS_ERROR) - { - MALI_DEBUG_PRINT(2, ("Probe: Bus read error detect: PASSED\n")); - mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_READ_BUS_ERROR); - } - else - { - MALI_DEBUG_PRINT(1, ("Probe: Bus read error detect: FAILED\n")); - } - - if ( (int_stat & (MALI_MMU_INTERRUPT_PAGE_FAULT|MALI_MMU_INTERRUPT_READ_BUS_ERROR)) == - (MALI_MMU_INTERRUPT_PAGE_FAULT|MALI_MMU_INTERRUPT_READ_BUS_ERROR)) - { - return _MALI_OSK_ERR_OK; - } - - return _MALI_OSK_ERR_FAULT; -} - -#if 0 -void mali_mmu_print_state(struct mali_mmu_core *mmu) -{ - MALI_DEBUG_PRINT(2, ("MMU: State of %s is 0x%08x\n", mmu->hw_core.description, mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS))); -} -#endif diff --git a/drivers/media/video/samsung/mali/common/mali_mmu.h b/drivers/media/video/samsung/mali/common/mali_mmu.h deleted file mode 100644 index c7274b8..0000000 --- a/drivers/media/video/samsung/mali/common/mali_mmu.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_MMU_H__ -#define __MALI_MMU_H__ - -#include "mali_osk.h" -#include "mali_mmu_page_directory.h" - -/* Forward declaration from mali_group.h */ -struct mali_group; - -struct mali_mmu_core; - -_mali_osk_errcode_t mali_mmu_initialize(void); - -void mali_mmu_terminate(void); - -struct mali_mmu_core *mali_mmu_create(_mali_osk_resource_t *resource); -void mali_mmu_set_group(struct mali_mmu_core *mmu, struct mali_group *group); -void mali_mmu_delete(struct mali_mmu_core *mmu); - -_mali_osk_errcode_t mali_mmu_reset(struct mali_mmu_core *mmu); -mali_bool mali_mmu_zap_tlb(struct mali_mmu_core *mmu); -void mali_mmu_zap_tlb_without_stall(struct mali_mmu_core *mmu); -void mali_mmu_invalidate_page(struct mali_mmu_core *mmu, u32 mali_address); - -mali_bool mali_mmu_activate_page_directory(struct mali_mmu_core* mmu, struct mali_page_directory *pagedir); -void mali_mmu_activate_empty_page_directory(struct mali_mmu_core* mmu); -void mali_mmu_activate_fault_flush_page_directory(struct mali_mmu_core* mmu); - -/** - * Issues the enable stall command to the MMU and waits for HW to complete the request - * @param mmu The MMU to enable paging for - * @return MALI_TRUE if HW stall was successfully engaged, otherwise MALI_FALSE (req timed out) - */ -mali_bool mali_mmu_enable_stall(struct mali_mmu_core *mmu); - -/** - * Issues the disable stall command to the MMU and waits for HW to complete the request - * @param mmu The MMU to enable paging for - */ -void mali_mmu_disable_stall(struct mali_mmu_core *mmu); - -void mali_mmu_page_fault_done(struct mali_mmu_core *mmu); - - -#endif /* __MALI_MMU_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.c b/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.c deleted file mode 100644 index cc91ae9..0000000 --- a/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.c +++ /dev/null @@ -1,475 +0,0 @@ -/* - * Copyright (C) 2011-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_kernel_common.h" -#include "mali_kernel_core.h" -#include "mali_osk.h" -#include "mali_uk_types.h" -#include "mali_mmu_page_directory.h" -#include "mali_memory.h" - -#include "mali_cluster.h" -#include "mali_group.h" - -static _mali_osk_errcode_t fill_page(mali_io_address mapping, u32 data); - -u32 mali_allocate_empty_page(void) -{ - _mali_osk_errcode_t err; - mali_io_address mapping; - u32 address; - - if(_MALI_OSK_ERR_OK != mali_mmu_get_table_page(&address, &mapping)) - { - /* Allocation failed */ - return 0; - } - - MALI_DEBUG_ASSERT_POINTER( mapping ); - - err = fill_page(mapping, 0); - if (_MALI_OSK_ERR_OK != err) - { - mali_mmu_release_table_page(address); - } - return address; -} - -void mali_free_empty_page(u32 address) -{ - if (MALI_INVALID_PAGE != address) - { - mali_mmu_release_table_page(address); - } -} - -_mali_osk_errcode_t mali_create_fault_flush_pages(u32 *page_directory, u32 *page_table, u32 *data_page) -{ - _mali_osk_errcode_t err; - mali_io_address page_directory_mapping; - mali_io_address page_table_mapping; - mali_io_address data_page_mapping; - - err = mali_mmu_get_table_page(data_page, &data_page_mapping); - if (_MALI_OSK_ERR_OK == err) - { - err = mali_mmu_get_table_page(page_table, &page_table_mapping); - if (_MALI_OSK_ERR_OK == err) - { - err = mali_mmu_get_table_page(page_directory, &page_directory_mapping); - if (_MALI_OSK_ERR_OK == err) - { - fill_page(data_page_mapping, 0); - fill_page(page_table_mapping, *data_page | MALI_MMU_FLAGS_WRITE_PERMISSION | MALI_MMU_FLAGS_READ_PERMISSION | MALI_MMU_FLAGS_PRESENT); - fill_page(page_directory_mapping, *page_table | MALI_MMU_FLAGS_PRESENT); - MALI_SUCCESS; - } - mali_mmu_release_table_page(*page_table); - *page_table = MALI_INVALID_PAGE; - } - mali_mmu_release_table_page(*data_page); - *data_page = MALI_INVALID_PAGE; - } - return err; -} - -void mali_destroy_fault_flush_pages(u32 *page_directory, u32 *page_table, u32 *data_page) -{ - if (MALI_INVALID_PAGE != *page_directory) - { - mali_mmu_release_table_page(*page_directory); - *page_directory = MALI_INVALID_PAGE; - } - - if (MALI_INVALID_PAGE != *page_table) - { - mali_mmu_release_table_page(*page_table); - *page_table = MALI_INVALID_PAGE; - } - - if (MALI_INVALID_PAGE != *data_page) - { - mali_mmu_release_table_page(*data_page); - *data_page = MALI_INVALID_PAGE; - } -} - -static _mali_osk_errcode_t fill_page(mali_io_address mapping, u32 data) -{ - int i; - MALI_DEBUG_ASSERT_POINTER( mapping ); - - for(i = 0; i < MALI_MMU_PAGE_SIZE/4; i++) - { - _mali_osk_mem_iowrite32_relaxed( mapping, i * sizeof(u32), data); - } - _mali_osk_mem_barrier(); - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_mmu_pagedir_map(struct mali_page_directory *pagedir, u32 mali_address, u32 size) -{ - const int first_pde = MALI_MMU_PDE_ENTRY(mali_address); - const int last_pde = MALI_MMU_PDE_ENTRY(mali_address + size - 1); - _mali_osk_errcode_t err; - mali_io_address pde_mapping; - u32 pde_phys; - int i; - - for(i = first_pde; i <= last_pde; i++) - { - if(0 == (_mali_osk_mem_ioread32(pagedir->page_directory_mapped, i*sizeof(u32)) & MALI_MMU_FLAGS_PRESENT)) - { - /* Page table not present */ - MALI_DEBUG_ASSERT(0 == pagedir->page_entries_usage_count[i]); - MALI_DEBUG_ASSERT(NULL == pagedir->page_entries_mapped[i]); - - err = mali_mmu_get_table_page(&pde_phys, &pde_mapping); - if(_MALI_OSK_ERR_OK != err) - { - MALI_PRINT_ERROR(("Failed to allocate page table page.\n")); - return err; - } - pagedir->page_entries_mapped[i] = pde_mapping; - - /* Update PDE, mark as present */ - _mali_osk_mem_iowrite32_relaxed(pagedir->page_directory_mapped, i*sizeof(u32), - pde_phys | MALI_MMU_FLAGS_PRESENT); - - MALI_DEBUG_ASSERT(0 == pagedir->page_entries_usage_count[i]); - pagedir->page_entries_usage_count[i] = 1; - } - else - { - pagedir->page_entries_usage_count[i]++; - } - } - _mali_osk_write_mem_barrier(); - - MALI_SUCCESS; -} - -MALI_STATIC_INLINE void mali_mmu_zero_pte(mali_io_address page_table, u32 mali_address, u32 size) -{ - int i; - const int first_pte = MALI_MMU_PTE_ENTRY(mali_address); - const int last_pte = MALI_MMU_PTE_ENTRY(mali_address + size - 1); - - for (i = first_pte; i <= last_pte; i++) - { - _mali_osk_mem_iowrite32_relaxed(page_table, i * sizeof(u32), 0); - } -} - -_mali_osk_errcode_t mali_mmu_pagedir_unmap(struct mali_page_directory *pagedir, u32 mali_address, u32 size) -{ - const int first_pde = MALI_MMU_PDE_ENTRY(mali_address); - const int last_pde = MALI_MMU_PDE_ENTRY(mali_address + size - 1); - u32 left = size; - int i; -#ifndef MALI_UNMAP_FLUSH_ALL_MALI_L2 - mali_bool pd_changed = MALI_FALSE; - u32 pages_to_invalidate[3]; /* hard-coded to 3: max two pages from the PT level plus max one page from PD level */ - u32 num_pages_inv = 0; -#endif - - /* For all page directory entries in range. */ - for (i = first_pde; i <= last_pde; i++) - { - u32 size_in_pde, offset; - - MALI_DEBUG_ASSERT_POINTER(pagedir->page_entries_mapped[i]); - MALI_DEBUG_ASSERT(0 != pagedir->page_entries_usage_count[i]); - - /* Offset into page table, 0 if mali_address is 4MiB aligned */ - offset = (mali_address & (MALI_MMU_VIRTUAL_PAGE_SIZE - 1)); - if (left < MALI_MMU_VIRTUAL_PAGE_SIZE - offset) - { - size_in_pde = left; - } - else - { - size_in_pde = MALI_MMU_VIRTUAL_PAGE_SIZE - offset; - } - - pagedir->page_entries_usage_count[i]--; - - /* If entire page table is unused, free it */ - if (0 == pagedir->page_entries_usage_count[i]) - { - u32 page_address; - MALI_DEBUG_PRINT(4, ("Releasing page table as this is the last reference\n")); - /* last reference removed, no need to zero out each PTE */ - - page_address = MALI_MMU_ENTRY_ADDRESS(_mali_osk_mem_ioread32(pagedir->page_directory_mapped, i*sizeof(u32))); - pagedir->page_entries_mapped[i] = NULL; - _mali_osk_mem_iowrite32_relaxed(pagedir->page_directory_mapped, i*sizeof(u32), 0); - - mali_mmu_release_table_page(page_address); -#ifndef MALI_UNMAP_FLUSH_ALL_MALI_L2 - pd_changed = MALI_TRUE; -#endif - } - else - { -#ifndef MALI_UNMAP_FLUSH_ALL_MALI_L2 - pages_to_invalidate[num_pages_inv] = mali_page_directory_get_phys_address(pagedir, i); - num_pages_inv++; - MALI_DEBUG_ASSERT(num_pages_inv<3); -#endif - - /* If part of the page table is still in use, zero the relevant PTEs */ - mali_mmu_zero_pte(pagedir->page_entries_mapped[i], mali_address, size_in_pde); - } - - left -= size_in_pde; - mali_address += size_in_pde; - } - _mali_osk_write_mem_barrier(); - -#ifndef MALI_UNMAP_FLUSH_ALL_MALI_L2 - /* L2 pages invalidation */ - if (MALI_TRUE == pd_changed) - { - pages_to_invalidate[num_pages_inv] = pagedir->page_directory; - num_pages_inv++; - MALI_DEBUG_ASSERT(num_pages_inv<3); - } - - if (_MALI_PRODUCT_ID_MALI200 != mali_kernel_core_get_product_id()) - { - mali_cluster_invalidate_pages(pages_to_invalidate, num_pages_inv); - } -#endif - - MALI_SUCCESS; -} - -struct mali_page_directory *mali_mmu_pagedir_alloc(void) -{ - struct mali_page_directory *pagedir; - - pagedir = _mali_osk_calloc(1, sizeof(struct mali_page_directory)); - if(NULL == pagedir) - { - return NULL; - } - - if(_MALI_OSK_ERR_OK != mali_mmu_get_table_page(&pagedir->page_directory, &pagedir->page_directory_mapped)) - { - _mali_osk_free(pagedir); - return NULL; - } - - /* Zero page directory */ - fill_page(pagedir->page_directory_mapped, 0); - - return pagedir; -} - -void mali_mmu_pagedir_free(struct mali_page_directory *pagedir) -{ - const int num_page_table_entries = sizeof(pagedir->page_entries_mapped) / sizeof(pagedir->page_entries_mapped[0]); - int i; - - /* Free referenced page tables and zero PDEs. */ - for (i = 0; i < num_page_table_entries; i++) - { - if (pagedir->page_directory_mapped && (_mali_osk_mem_ioread32(pagedir->page_directory_mapped, sizeof(u32)*i) & MALI_MMU_FLAGS_PRESENT)) - { - mali_mmu_release_table_page( _mali_osk_mem_ioread32(pagedir->page_directory_mapped, i*sizeof(u32)) & ~MALI_MMU_FLAGS_MASK); - _mali_osk_mem_iowrite32_relaxed(pagedir->page_directory_mapped, i * sizeof(u32), 0); - } - } - _mali_osk_write_mem_barrier(); - - /* Free the page directory page. */ - mali_mmu_release_table_page(pagedir->page_directory); - - _mali_osk_free(pagedir); -} - - -void mali_mmu_pagedir_update(struct mali_page_directory *pagedir, u32 mali_address, u32 phys_address, u32 size, mali_memory_cache_settings cache_settings) -{ - u32 end_address = mali_address + size; - u32 permission_bits; - - switch ( cache_settings ) - { - case MALI_CACHE_GP_READ_ALLOCATE: - MALI_DEBUG_PRINT(3, ("Map L2 GP_Read_allocate\n")); - permission_bits = MALI_MMU_FLAGS_FORCE_GP_READ_ALLOCATE; - break; - - case MALI_CACHE_STANDARD: - MALI_DEBUG_PRINT(3, ("Map L2 Standard\n")); - /*falltrough */ - default: - if ( MALI_CACHE_STANDARD != cache_settings) MALI_PRINT_ERROR(("Wrong cache settings\n")); - permission_bits = MALI_MMU_FLAGS_WRITE_PERMISSION | MALI_MMU_FLAGS_READ_PERMISSION | MALI_MMU_FLAGS_PRESENT; - } - - /* Map physical pages into MMU page tables */ - for ( ; mali_address < end_address; mali_address += MALI_MMU_PAGE_SIZE, phys_address += MALI_MMU_PAGE_SIZE) - { - MALI_DEBUG_ASSERT_POINTER(pagedir->page_entries_mapped[MALI_MMU_PDE_ENTRY(mali_address)]); - _mali_osk_mem_iowrite32_relaxed(pagedir->page_entries_mapped[MALI_MMU_PDE_ENTRY(mali_address)], - MALI_MMU_PTE_ENTRY(mali_address) * sizeof(u32), - phys_address | permission_bits); - } - _mali_osk_write_mem_barrier(); -} - -u32 mali_page_directory_get_phys_address(struct mali_page_directory *pagedir, u32 index) -{ - return (_mali_osk_mem_ioread32(pagedir->page_directory_mapped, index*sizeof(u32)) & ~MALI_MMU_FLAGS_MASK); -} - -/* For instrumented */ -struct dump_info -{ - u32 buffer_left; - u32 register_writes_size; - u32 page_table_dump_size; - u32 *buffer; -}; - -static _mali_osk_errcode_t writereg(u32 where, u32 what, const char *comment, struct dump_info *info) -{ - if (NULL != info) - { - info->register_writes_size += sizeof(u32)*2; /* two 32-bit words */ - - if (NULL != info->buffer) - { - /* check that we have enough space */ - if (info->buffer_left < sizeof(u32)*2) MALI_ERROR(_MALI_OSK_ERR_NOMEM); - - *info->buffer = where; - info->buffer++; - - *info->buffer = what; - info->buffer++; - - info->buffer_left -= sizeof(u32)*2; - } - } - - MALI_SUCCESS; -} - -static _mali_osk_errcode_t dump_page(mali_io_address page, u32 phys_addr, struct dump_info * info) -{ - if (NULL != info) - { - /* 4096 for the page and 4 bytes for the address */ - const u32 page_size_in_elements = MALI_MMU_PAGE_SIZE / 4; - const u32 page_size_in_bytes = MALI_MMU_PAGE_SIZE; - const u32 dump_size_in_bytes = MALI_MMU_PAGE_SIZE + 4; - - info->page_table_dump_size += dump_size_in_bytes; - - if (NULL != info->buffer) - { - if (info->buffer_left < dump_size_in_bytes) MALI_ERROR(_MALI_OSK_ERR_NOMEM); - - *info->buffer = phys_addr; - info->buffer++; - - _mali_osk_memcpy(info->buffer, page, page_size_in_bytes); - info->buffer += page_size_in_elements; - - info->buffer_left -= dump_size_in_bytes; - } - } - - MALI_SUCCESS; -} - -static _mali_osk_errcode_t dump_mmu_page_table(struct mali_page_directory *pagedir, struct dump_info * info) -{ - MALI_DEBUG_ASSERT_POINTER(pagedir); - MALI_DEBUG_ASSERT_POINTER(info); - - if (NULL != pagedir->page_directory_mapped) - { - int i; - - MALI_CHECK_NO_ERROR( - dump_page(pagedir->page_directory_mapped, pagedir->page_directory, info) - ); - - for (i = 0; i < 1024; i++) - { - if (NULL != pagedir->page_entries_mapped[i]) - { - MALI_CHECK_NO_ERROR( - dump_page(pagedir->page_entries_mapped[i], - _mali_osk_mem_ioread32(pagedir->page_directory_mapped, - i * sizeof(u32)) & ~MALI_MMU_FLAGS_MASK, info) - ); - } - } - } - - MALI_SUCCESS; -} - -static _mali_osk_errcode_t dump_mmu_registers(struct mali_page_directory *pagedir, struct dump_info * info) -{ - MALI_CHECK_NO_ERROR(writereg(0x00000000, pagedir->page_directory, - "set the page directory address", info)); - MALI_CHECK_NO_ERROR(writereg(0x00000008, 4, "zap???", info)); - MALI_CHECK_NO_ERROR(writereg(0x00000008, 0, "enable paging", info)); - MALI_SUCCESS; -} - -_mali_osk_errcode_t _mali_ukk_query_mmu_page_table_dump_size( _mali_uk_query_mmu_page_table_dump_size_s *args ) -{ - struct dump_info info = { 0, 0, 0, NULL }; - struct mali_session_data * session_data; - - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - - session_data = (struct mali_session_data *)(args->ctx); - - MALI_CHECK_NO_ERROR(dump_mmu_registers(session_data->page_directory, &info)); - MALI_CHECK_NO_ERROR(dump_mmu_page_table(session_data->page_directory, &info)); - args->size = info.register_writes_size + info.page_table_dump_size; - MALI_SUCCESS; -} - -_mali_osk_errcode_t _mali_ukk_dump_mmu_page_table( _mali_uk_dump_mmu_page_table_s * args ) -{ - struct dump_info info = { 0, 0, 0, NULL }; - struct mali_session_data * session_data; - - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - MALI_CHECK_NON_NULL(args->buffer, _MALI_OSK_ERR_INVALID_ARGS); - - session_data = (struct mali_session_data *)(args->ctx); - - info.buffer_left = args->size; - info.buffer = args->buffer; - - args->register_writes = info.buffer; - MALI_CHECK_NO_ERROR(dump_mmu_registers(session_data->page_directory, &info)); - - args->page_table_dump = info.buffer; - MALI_CHECK_NO_ERROR(dump_mmu_page_table(session_data->page_directory, &info)); - - args->register_writes_size = info.register_writes_size; - args->page_table_dump_size = info.page_table_dump_size; - - MALI_SUCCESS; -} diff --git a/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.h b/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.h deleted file mode 100644 index 628833a..0000000 --- a/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2011-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_MMU_PAGE_DIRECTORY_H__ -#define __MALI_MMU_PAGE_DIRECTORY_H__ - -#include "mali_osk.h" - -/** - * Size of an MMU page in bytes - */ -#define MALI_MMU_PAGE_SIZE 0x1000 - -/* - * Size of the address space referenced by a page table page - */ -#define MALI_MMU_VIRTUAL_PAGE_SIZE 0x400000 /* 4 MiB */ - -/** - * Page directory index from address - * Calculates the page directory index from the given address - */ -#define MALI_MMU_PDE_ENTRY(address) (((address)>>22) & 0x03FF) - -/** - * Page table index from address - * Calculates the page table index from the given address - */ -#define MALI_MMU_PTE_ENTRY(address) (((address)>>12) & 0x03FF) - -/** - * Extract the memory address from an PDE/PTE entry - */ -#define MALI_MMU_ENTRY_ADDRESS(value) ((value) & 0xFFFFFC00) - -#define MALI_INVALID_PAGE ((u32)(~0)) - -/** - * - */ -typedef enum mali_mmu_entry_flags -{ - MALI_MMU_FLAGS_PRESENT = 0x01, - MALI_MMU_FLAGS_READ_PERMISSION = 0x02, - MALI_MMU_FLAGS_WRITE_PERMISSION = 0x04, - MALI_MMU_FLAGS_OVERRIDE_CACHE = 0x8, - MALI_MMU_FLAGS_WRITE_CACHEABLE = 0x10, - MALI_MMU_FLAGS_WRITE_ALLOCATE = 0x20, - MALI_MMU_FLAGS_WRITE_BUFFERABLE = 0x40, - MALI_MMU_FLAGS_READ_CACHEABLE = 0x80, - MALI_MMU_FLAGS_READ_ALLOCATE = 0x100, - MALI_MMU_FLAGS_MASK = 0x1FF, -} mali_mmu_entry_flags; - - -#define MALI_MMU_FLAGS_FORCE_GP_READ_ALLOCATE ( \ -MALI_MMU_FLAGS_PRESENT | \ - MALI_MMU_FLAGS_READ_PERMISSION | \ - MALI_MMU_FLAGS_WRITE_PERMISSION | \ - MALI_MMU_FLAGS_OVERRIDE_CACHE | \ - MALI_MMU_FLAGS_WRITE_CACHEABLE | \ - MALI_MMU_FLAGS_WRITE_BUFFERABLE | \ - MALI_MMU_FLAGS_READ_CACHEABLE | \ - MALI_MMU_FLAGS_READ_ALLOCATE ) - - -struct mali_page_directory -{ - u32 page_directory; /**< Physical address of the memory session's page directory */ - mali_io_address page_directory_mapped; /**< Pointer to the mapped version of the page directory into the kernel's address space */ - - mali_io_address page_entries_mapped[1024]; /**< Pointers to the page tables which exists in the page directory mapped into the kernel's address space */ - u32 page_entries_usage_count[1024]; /**< Tracks usage count of the page table pages, so they can be releases on the last reference */ -}; - -/* Map Mali virtual address space (i.e. ensure page tables exist for the virtual range) */ -_mali_osk_errcode_t mali_mmu_pagedir_map(struct mali_page_directory *pagedir, u32 mali_address, u32 size); -_mali_osk_errcode_t mali_mmu_pagedir_unmap(struct mali_page_directory *pagedir, u32 mali_address, u32 size); - -/* Back virtual address space with actual pages. Assumes input is contiguous and 4k aligned. */ -void mali_mmu_pagedir_update(struct mali_page_directory *pagedir, u32 mali_address, u32 phys_address, u32 size, u32 cache_settings); - -u32 mali_page_directory_get_phys_address(struct mali_page_directory *pagedir, u32 index); - -u32 mali_allocate_empty_page(void); -void mali_free_empty_page(u32 address); -_mali_osk_errcode_t mali_create_fault_flush_pages(u32 *page_directory, u32 *page_table, u32 *data_page); -void mali_destroy_fault_flush_pages(u32 *page_directory, u32 *page_table, u32 *data_page); - -struct mali_page_directory *mali_mmu_pagedir_alloc(void); -void mali_mmu_pagedir_free(struct mali_page_directory *pagedir); - -#endif /* __MALI_MMU_PAGE_DIRECTORY_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_osk.h b/drivers/media/video/samsung/mali/common/mali_osk.h deleted file mode 100644 index e32d15d..0000000 --- a/drivers/media/video/samsung/mali/common/mali_osk.h +++ /dev/null @@ -1,1798 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_osk.h - * Defines the OS abstraction layer for the kernel device driver (OSK) - */ - -#ifndef __MALI_OSK_H__ -#define __MALI_OSK_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -/** - * @addtogroup uddapi Unified Device Driver (UDD) APIs - * - * @{ - */ - -/** - * @addtogroup oskapi UDD OS Abstraction for Kernel-side (OSK) APIs - * - * @{ - */ - -/** @defgroup _mali_osk_miscellaneous OSK Miscellaneous functions, constants and types - * @{ */ - -/* Define integer types used by OSK. Note: these currently clash with Linux so we only define them if not defined already */ -#ifndef __KERNEL__ - typedef unsigned char u8; - typedef signed char s8; - typedef unsigned short u16; - typedef signed short s16; - typedef unsigned int u32; - typedef signed int s32; - typedef unsigned long long u64; - #define BITS_PER_LONG (sizeof(long)*8) -#else - /* Ensure Linux types u32, etc. are defined */ - #include -#endif - -/** @brief Mali Boolean type which uses MALI_TRUE and MALI_FALSE - */ - typedef unsigned long mali_bool; - -#ifndef MALI_TRUE - #define MALI_TRUE ((mali_bool)1) -#endif - -#ifndef MALI_FALSE - #define MALI_FALSE ((mali_bool)0) -#endif - -/** - * @brief OSK Error codes - * - * Each OS may use its own set of error codes, and may require that the - * User/Kernel interface take certain error code. This means that the common - * error codes need to be sufficiently rich to pass the correct error code - * thorugh from the OSK to U/K layer, across all OSs. - * - * The result is that some error codes will appear redundant on some OSs. - * Under all OSs, the OSK layer must translate native OS error codes to - * _mali_osk_errcode_t codes. Similarly, the U/K layer must translate from - * _mali_osk_errcode_t codes to native OS error codes. - */ -typedef enum -{ - _MALI_OSK_ERR_OK = 0, /**< Success. */ - _MALI_OSK_ERR_FAULT = -1, /**< General non-success */ - _MALI_OSK_ERR_INVALID_FUNC = -2, /**< Invalid function requested through User/Kernel interface (e.g. bad IOCTL number) */ - _MALI_OSK_ERR_INVALID_ARGS = -3, /**< Invalid arguments passed through User/Kernel interface */ - _MALI_OSK_ERR_NOMEM = -4, /**< Insufficient memory */ - _MALI_OSK_ERR_TIMEOUT = -5, /**< Timeout occurred */ - _MALI_OSK_ERR_RESTARTSYSCALL = -6, /**< Special: On certain OSs, must report when an interruptable mutex is interrupted. Ignore otherwise. */ - _MALI_OSK_ERR_ITEM_NOT_FOUND = -7, /**< Table Lookup failed */ - _MALI_OSK_ERR_BUSY = -8, /**< Device/operation is busy. Try again later */ - _MALI_OSK_ERR_UNSUPPORTED = -9, /**< Optional part of the interface used, and is unsupported */ -} _mali_osk_errcode_t; - -/** @} */ /* end group _mali_osk_miscellaneous */ - - -/** @defgroup _mali_osk_irq OSK IRQ handling - * @{ */ - -/** @brief Private type for IRQ handling objects */ -typedef struct _mali_osk_irq_t_struct _mali_osk_irq_t; - -/** @brief Optional function to trigger an irq from a resource - * - * This function is implemented by the common layer to allow probing of a resource's IRQ. - * @param arg resource-specific data */ -typedef void (*_mali_osk_irq_trigger_t)( void * arg ); - -/** @brief Optional function to acknowledge an irq from a resource - * - * This function is implemented by the common layer to allow probing of a resource's IRQ. - * @param arg resource-specific data - * @return _MALI_OSK_ERR_OK if the IRQ was successful, or a suitable _mali_osk_errcode_t on failure. */ -typedef _mali_osk_errcode_t (*_mali_osk_irq_ack_t)( void * arg ); - -/** @brief IRQ 'upper-half' handler callback. - * - * This function is implemented by the common layer to do the initial handling of a - * resource's IRQ. This maps on to the concept of an ISR that does the minimum - * work necessary before handing off to an IST. - * - * The communication of the resource-specific data from the ISR to the IST is - * handled by the OSK implementation. - * - * On most systems, the IRQ upper-half handler executes in IRQ context. - * Therefore, the system may have restrictions about what can be done in this - * context - * - * If an IRQ upper-half handler requires more work to be done than can be - * acheived in an IRQ context, then it may defer the work with - * _mali_osk_irq_schedulework(). Refer to \ref _mali_osk_irq_schedulework() for - * more information. - * - * @param arg resource-specific data - * @return _MALI_OSK_ERR_OK if the IRQ was correctly handled, or a suitable - * _mali_osk_errcode_t otherwise. - */ -typedef _mali_osk_errcode_t (*_mali_osk_irq_uhandler_t)( void * arg ); - -/** @brief IRQ 'bottom-half' handler callback. - * - * This function is implemented by the common layer to do the deferred handling - * of a resource's IRQ. Usually, this work cannot be carried out in IRQ context - * by the IRQ upper-half handler. - * - * The IRQ bottom-half handler maps on to the concept of an IST that may - * execute some time after the actual IRQ has fired. - * - * All OSK-registered IRQ bottom-half handlers will be serialized, across all - * CPU-cores in the system. - * - * Refer to \ref _mali_osk_irq_schedulework() for more information on the - * IRQ work-queue, and the calling of the IRQ bottom-half handler. - * - * @param arg resource-specific data - */ -typedef void (*_mali_osk_irq_bhandler_t)( void * arg ); -/** @} */ /* end group _mali_osk_irq */ - - -/** @defgroup _mali_osk_atomic OSK Atomic counters - * @{ */ - -/** @brief Public type of atomic counters - * - * This is public for allocation on stack. On systems that support it, this is just a single 32-bit value. - * On others, it could be encapsulating an object stored elsewhere. - * - * Regardless of implementation, the \ref _mali_osk_atomic functions \b must be used - * for all accesses to the variable's value, even if atomicity is not required. - * Do not access u.val or u.obj directly. - */ -typedef struct -{ - union - { - u32 val; - void *obj; - } u; -} _mali_osk_atomic_t; -/** @} */ /* end group _mali_osk_atomic */ - - -/** @defgroup _mali_osk_lock OSK Mutual Exclusion Locks - * @{ */ - - -/** @brief OSK Mutual Exclusion Lock ordered list - * - * This lists the various types of locks in the system and is used to check - * that locks are taken in the correct order. - * - * Holding more than one lock of the same order at the same time is not - * allowed. - * - */ -typedef enum -{ - _MALI_OSK_LOCK_ORDER_LAST = 0, - - _MALI_OSK_LOCK_ORDER_PM_EXECUTE, - _MALI_OSK_LOCK_ORDER_UTILIZATION, - _MALI_OSK_LOCK_ORDER_L2_COUNTER, - _MALI_OSK_LOCK_ORDER_PROFILING, - _MALI_OSK_LOCK_ORDER_L2_COMMAND, - _MALI_OSK_LOCK_ORDER_PM_CORE_STATE, - _MALI_OSK_LOCK_ORDER_GROUP, - _MALI_OSK_LOCK_ORDER_SCHEDULER, - - _MALI_OSK_LOCK_ORDER_DESCRIPTOR_MAP, - _MALI_OSK_LOCK_ORDER_MEM_PT_CACHE, - _MALI_OSK_LOCK_ORDER_MEM_INFO, - _MALI_OSK_LOCK_ORDER_MEM_SESSION, - - _MALI_OSK_LOCK_ORDER_SESSIONS, - - _MALI_OSK_LOCK_ORDER_FIRST -} _mali_osk_lock_order_t; - - -/** @brief OSK Mutual Exclusion Lock flags type - * - * Flags are supplied at the point where the Lock is initialized. Each flag can - * be combined with others using bitwise OR, '|'. - * - * The flags must be sufficiently rich to cope with all our OSs. This means - * that on some OSs, certain flags can be completely ignored. We define a - * number of terms that are significant across all OSs: - * - * - Sleeping/non-sleeping mutexs. Sleeping mutexs can block on waiting, and so - * schedule out the current thread. This is significant on OSs where there are - * situations in which the current thread must not be put to sleep. On OSs - * without this restriction, sleeping and non-sleeping mutexes can be treated - * as the same (if that is required). - * - Interruptable/non-interruptable mutexes. For sleeping mutexes, it may be - * possible for the sleep to be interrupted for a reason other than the thread - * being able to obtain the lock. OSs behaving in this way may provide a - * mechanism to control whether sleeping mutexes can be interrupted. On OSs - * that do not support the concept of interruption, \b or they do not support - * control of mutex interruption, then interruptable mutexes may be treated - * as non-interruptable. - * - * Some constrains apply to the lock type flags: - * - * - Spinlocks are by nature, non-interruptable. Hence, they must always be - * combined with the NONINTERRUPTABLE flag, because it is meaningless to ask - * for a spinlock that is interruptable (and this highlights its - * non-interruptable-ness). For example, on certain OSs they should be used when - * you must not sleep. - * - Reader/writer is an optimization hint, and any type of lock can be - * reader/writer. Since this is an optimization hint, the implementation need - * not respect this for any/all types of lock. For example, on certain OSs, - * there's no interruptable reader/writer mutex. If such a thing were requested - * on that OS, the fact that interruptable was requested takes priority over the - * reader/writer-ness, because reader/writer-ness is not necessary for correct - * operation. - * - Any lock can use the order parameter. - * - A onelock is an optimization hint specific to certain OSs. It can be - * specified when it is known that only one lock will be held by the thread, - * and so can provide faster mutual exclusion. This can be safely ignored if - * such optimization is not required/present. - * - * The absence of any flags (the value 0) results in a sleeping-mutex, which is interruptable. - */ -typedef enum -{ - _MALI_OSK_LOCKFLAG_SPINLOCK = 0x1, /**< Specifically, don't sleep on those architectures that require it */ - _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE = 0x2, /**< The mutex cannot be interrupted, e.g. delivery of signals on those architectures where this is required */ - _MALI_OSK_LOCKFLAG_READERWRITER = 0x4, /**< Optimise for readers/writers */ - _MALI_OSK_LOCKFLAG_ORDERED = 0x8, /**< Use the order parameter; otherwise use automatic ordering */ - _MALI_OSK_LOCKFLAG_ONELOCK = 0x10, /**< Each thread can only hold one lock at a time */ - _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ = 0x20, /**< IRQ version of spinlock */ - /** @enum _mali_osk_lock_flags_t - * - * Flags from 0x10000--0x80000000 are RESERVED for User-mode */ - -} _mali_osk_lock_flags_t; - -/** @brief Mutual Exclusion Lock Mode Optimization hint - * - * The lock mode is used to implement the read/write locking of locks specified - * as _MALI_OSK_LOCKFLAG_READERWRITER. In this case, the RO mode can be used - * to allow multiple concurrent readers, but no writers. The RW mode is used for - * writers, and so will wait for all readers to release the lock (if any present). - * Further readers and writers will wait until the writer releases the lock. - * - * The mode is purely an optimization hint: for example, it is permissible for - * all locks to behave in RW mode, regardless of that supplied. - * - * It is an error to attempt to use locks in anything other that RW mode when - * _MALI_OSK_LOCKFLAG_READERWRITER is not supplied. - * - */ -typedef enum -{ - _MALI_OSK_LOCKMODE_UNDEF = -1, /**< Undefined lock mode. For internal use only */ - _MALI_OSK_LOCKMODE_RW = 0x0, /**< Read-write mode, default. All readers and writers are mutually-exclusive */ - _MALI_OSK_LOCKMODE_RO, /**< Read-only mode, to support multiple concurrent readers, but mutual exclusion in the presence of writers. */ - /** @enum _mali_osk_lock_mode_t - * - * Lock modes 0x40--0x7F are RESERVED for User-mode */ -} _mali_osk_lock_mode_t; - -/** @brief Private type for Mutual Exclusion lock objects */ -typedef struct _mali_osk_lock_t_struct _mali_osk_lock_t; - -#ifdef DEBUG -/** @brief Macro for asserting that the current thread holds a given lock - */ -#define MALI_DEBUG_ASSERT_LOCK_HELD(l) MALI_DEBUG_ASSERT(_mali_osk_lock_get_owner(l) == _mali_osk_get_tid()); - -/** @brief returns a lock's owner (thread id) if debugging is enabled - */ -u32 _mali_osk_lock_get_owner( _mali_osk_lock_t *lock ); -#endif - -/** @} */ /* end group _mali_osk_lock */ - -/** @defgroup _mali_osk_low_level_memory OSK Low-level Memory Operations - * @{ */ - -/** - * @brief Private data type for use in IO accesses to/from devices. - * - * This represents some range that is accessible from the device. Examples - * include: - * - Device Registers, which could be readable and/or writeable. - * - Memory that the device has access to, for storing configuration structures. - * - * Access to this range must be made through the _mali_osk_mem_ioread32() and - * _mali_osk_mem_iowrite32() functions. - */ -typedef struct _mali_io_address * mali_io_address; - -/** @defgroup _MALI_OSK_CPU_PAGE CPU Physical page size macros. - * - * The order of the page size is supplied for - * ease of use by algorithms that might require it, since it is easier to know - * it ahead of time rather than calculating it. - * - * The Mali Page Mask macro masks off the lower bits of a physical address to - * give the start address of the page for that physical address. - * - * @note The Mali device driver code is designed for systems with 4KB page size. - * Changing these macros will not make the entire Mali device driver work with - * page sizes other than 4KB. - * - * @note The CPU Physical Page Size has been assumed to be the same as the Mali - * Physical Page Size. - * - * @{ - */ - -/** CPU Page Order, as log to base 2 of the Page size. @see _MALI_OSK_CPU_PAGE_SIZE */ -#define _MALI_OSK_CPU_PAGE_ORDER ((u32)12) -/** CPU Page Size, in bytes. */ -#define _MALI_OSK_CPU_PAGE_SIZE (((u32)1) << (_MALI_OSK_CPU_PAGE_ORDER)) -/** CPU Page Mask, which masks off the offset within a page */ -#define _MALI_OSK_CPU_PAGE_MASK (~((((u32)1) << (_MALI_OSK_CPU_PAGE_ORDER)) - ((u32)1))) -/** @} */ /* end of group _MALI_OSK_CPU_PAGE */ - -/** @defgroup _MALI_OSK_MALI_PAGE Mali Physical Page size macros - * - * Mali Physical page size macros. The order of the page size is supplied for - * ease of use by algorithms that might require it, since it is easier to know - * it ahead of time rather than calculating it. - * - * The Mali Page Mask macro masks off the lower bits of a physical address to - * give the start address of the page for that physical address. - * - * @note The Mali device driver code is designed for systems with 4KB page size. - * Changing these macros will not make the entire Mali device driver work with - * page sizes other than 4KB. - * - * @note The Mali Physical Page Size has been assumed to be the same as the CPU - * Physical Page Size. - * - * @{ - */ - -/** Mali Page Order, as log to base 2 of the Page size. @see _MALI_OSK_MALI_PAGE_SIZE */ -#define _MALI_OSK_MALI_PAGE_ORDER ((u32)12) -/** Mali Page Size, in bytes. */ -#define _MALI_OSK_MALI_PAGE_SIZE (((u32)1) << (_MALI_OSK_MALI_PAGE_ORDER)) -/** Mali Page Mask, which masks off the offset within a page */ -#define _MALI_OSK_MALI_PAGE_MASK (~((((u32)1) << (_MALI_OSK_MALI_PAGE_ORDER)) - ((u32)1))) -/** @} */ /* end of group _MALI_OSK_MALI_PAGE*/ - -/** @brief flags for mapping a user-accessible memory range - * - * Where a function with prefix '_mali_osk_mem_mapregion' accepts flags as one - * of the function parameters, it will use one of these. These allow per-page - * control over mappings. Compare with the mali_memory_allocation_flag type, - * which acts over an entire range - * - * These may be OR'd together with bitwise OR (|), but must be cast back into - * the type after OR'ing. - */ -typedef enum -{ - _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR = 0x1, /**< Physical address is OS Allocated */ -} _mali_osk_mem_mapregion_flags_t; -/** @} */ /* end group _mali_osk_low_level_memory */ - -/** @defgroup _mali_osk_notification OSK Notification Queues - * @{ */ - -/** @brief Private type for notification queue objects */ -typedef struct _mali_osk_notification_queue_t_struct _mali_osk_notification_queue_t; - -/** @brief Public notification data object type */ -typedef struct _mali_osk_notification_t_struct -{ - u32 notification_type; /**< The notification type */ - u32 result_buffer_size; /**< Size of the result buffer to copy to user space */ - void * result_buffer; /**< Buffer containing any type specific data */ -} _mali_osk_notification_t; - -/** @} */ /* end group _mali_osk_notification */ - - -/** @defgroup _mali_osk_timer OSK Timer Callbacks - * @{ */ - -/** @brief Function to call when a timer expires - * - * When a timer expires, this function is called. Note that on many systems, - * a timer callback will be executed in IRQ context. Therefore, restrictions - * may apply on what can be done inside the timer callback. - * - * If a timer requires more work to be done than can be acheived in an IRQ - * context, then it may defer the work with a work-queue. For example, it may - * use \ref _mali_osk_irq_schedulework() to make use of the IRQ bottom-half handler - * to carry out the remaining work. - * - * Stopping the timer with \ref _mali_osk_timer_del() blocks on compeletion of - * the callback. Therefore, the callback may not obtain any mutexes also held - * by any callers of _mali_osk_timer_del(). Otherwise, a deadlock may occur. - * - * @param arg Function-specific data */ -typedef void (*_mali_osk_timer_callback_t)(void * arg ); - -/** @brief Private type for Timer Callback Objects */ -typedef struct _mali_osk_timer_t_struct _mali_osk_timer_t; -/** @} */ /* end group _mali_osk_timer */ - - -/** @addtogroup _mali_osk_list OSK Doubly-Linked Circular Lists - * @{ */ - -/** @brief Public List objects. - * - * To use, add a _mali_osk_list_t member to the structure that may become part - * of a list. When traversing the _mali_osk_list_t objects, use the - * _MALI_OSK_CONTAINER_OF() macro to recover the structure from its - *_mali_osk_list_t member - * - * Each structure may have multiple _mali_osk_list_t members, so that the - * structure is part of multiple lists. When traversing lists, ensure that the - * correct _mali_osk_list_t member is used, because type-checking will be - * lost by the compiler. - */ -typedef struct _mali_osk_list_s -{ - struct _mali_osk_list_s *next; - struct _mali_osk_list_s *prev; -} _mali_osk_list_t; - -/** @brief Initialize a list to be a head of an empty list - * @param exp the list to initialize. */ -#define _MALI_OSK_INIT_LIST_HEAD(exp) _mali_osk_list_init(exp) - -/** @brief Define a list variable, which is uninitialized. - * @param exp the name of the variable that the list will be defined as. */ -#define _MALI_OSK_LIST_HEAD(exp) _mali_osk_list_t exp - -/** @brief Find the containing structure of another structure - * - * This is the reverse of the operation 'offsetof'. This means that the - * following condition is satisfied: - * - * ptr == _MALI_OSK_CONTAINER_OF( &ptr->member, type, member ) - * - * When ptr is of type 'type'. - * - * Its purpose it to recover a larger structure that has wrapped a smaller one. - * - * @note no type or memory checking occurs to ensure that a wrapper structure - * does in fact exist, and that it is being recovered with respect to the - * correct member. - * - * @param ptr the pointer to the member that is contained within the larger - * structure - * @param type the type of the structure that contains the member - * @param member the name of the member in the structure that ptr points to. - * @return a pointer to a \a type object which contains \a member, as pointed - * to by \a ptr. - */ -#define _MALI_OSK_CONTAINER_OF(ptr, type, member) \ - ((type *)( ((char *)ptr) - offsetof(type,member) )) - -/** @brief Find the containing structure of a list - * - * When traversing a list, this is used to recover the containing structure, - * given that is contains a _mali_osk_list_t member. - * - * Each list must be of structures of one type, and must link the same members - * together, otherwise it will not be possible to correctly recover the - * sturctures that the lists link. - * - * @note no type or memory checking occurs to ensure that a structure does in - * fact exist for the list entry, and that it is being recovered with respect - * to the correct list member. - * - * @param ptr the pointer to the _mali_osk_list_t member in this structure - * @param type the type of the structure that contains the member - * @param member the member of the structure that ptr points to. - * @return a pointer to a \a type object which contains the _mali_osk_list_t - * \a member, as pointed to by the _mali_osk_list_t \a *ptr. - */ -#define _MALI_OSK_LIST_ENTRY(ptr, type, member) \ - _MALI_OSK_CONTAINER_OF(ptr, type, member) - -/** @brief Enumerate a list safely - * - * With this macro, lists can be enumerated in a 'safe' manner. That is, - * entries can be deleted from the list without causing an error during - * enumeration. To achieve this, a 'temporary' pointer is required, which must - * be provided to the macro. - * - * Use it like a 'for()', 'while()' or 'do()' construct, and so it must be - * followed by a statement or compound-statement which will be executed for - * each list entry. - * - * Upon loop completion, providing that an early out was not taken in the - * loop body, then it is guaranteed that ptr->member == list, even if the loop - * body never executed. - * - * @param ptr a pointer to an object of type 'type', which points to the - * structure that contains the currently enumerated list entry. - * @param tmp a pointer to an object of type 'type', which must not be used - * inside the list-execution statement. - * @param list a pointer to a _mali_osk_list_t, from which enumeration will - * begin - * @param type the type of the structure that contains the _mali_osk_list_t - * member that is part of the list to be enumerated. - * @param member the _mali_osk_list_t member of the structure that is part of - * the list to be enumerated. - */ -#define _MALI_OSK_LIST_FOREACHENTRY(ptr, tmp, list, type, member) \ - for (ptr = _MALI_OSK_LIST_ENTRY((list)->next, type, member), \ - tmp = _MALI_OSK_LIST_ENTRY(ptr->member.next, type, member); \ - &ptr->member != (list); \ - ptr = tmp, tmp = _MALI_OSK_LIST_ENTRY(tmp->member.next, type, member)) -/** @} */ /* end group _mali_osk_list */ - - -/** @addtogroup _mali_osk_miscellaneous - * @{ */ - -/** @brief The known resource types - * - * @note \b IMPORTANT: these must remain fixed, and only be extended. This is - * because not all systems use a header file for reading in their resources. - * The resources may instead come from a data file where these resources are - * 'hard-coded' in, because there's no easy way of transferring the enum values - * into such data files. E.g. the C-Pre-processor does \em not process enums. - */ -typedef enum _mali_osk_resource_type -{ - RESOURCE_TYPE_FIRST =0, /**< Duplicate resource marker for the first resource*/ - - MEMORY =0, /**< Physically contiguous memory block, not managed by the OS */ - OS_MEMORY =1, /**< Memory managed by and shared with the OS */ - - MALI_PP =2, /**< Mali Pixel Processor core */ - MALI450PP =2, /**< Compatibility option */ - MALI400PP =2, /**< Compatibility option */ - MALI300PP =2, /**< Compatibility option */ - MALI200 =2, /**< Compatibility option */ - - MALI_GP =3, /**< Mali Geometry Processor core */ - MALI450GP =3, /**< Compatibility option */ - MALI400GP =3, /**< Compatibility option */ - MALI300GP =3, /**< Compatibility option */ - MALIGP2 =3, /**< Compatibility option */ - - MMU =4, /**< Mali MMU (Memory Management Unit) */ - - FPGA_FRAMEWORK =5, /**< Mali registers specific to FPGA implementations */ - - MALI_L2 =6, /**< Mali Level 2 cache core */ - MALI450L2 =6, /**< Compatibility option */ - MALI400L2 =6, /**< Compatibility option */ - MALI300L2 =6, /**< Compatibility option */ - - MEM_VALIDATION =7, /**< External Memory Validator */ - - PMU =8, /**< Power Manangement Unit */ - - RESOURCE_TYPE_COUNT /**< The total number of known resources */ -} _mali_osk_resource_type_t; - -/** @brief resource description struct - * - * _mali_osk_resources_init() will enumerate objects of this type. Not all - * members have a valid meaning across all types. - * - * The mmu_id is used to group resources to a certain MMU, since there may be - * more than one MMU in the system, and each resource may be using a different - * MMU: - * - For MMU resources, the setting of mmu_id is a uniquely identifying number. - * - For Other resources, the setting of mmu_id determines which MMU the - * resource uses. - */ -typedef struct _mali_osk_resource -{ - _mali_osk_resource_type_t type; /**< type of the resource */ - const char * description; /**< short description of the resource */ - u32 base; /**< Physical base address of the resource, as seen by Mali resources. */ - s32 cpu_usage_adjust; /**< Offset added to the base address of the resource to arrive at the CPU physical address of the resource (if different from the Mali physical address) */ - u32 size; /**< Size in bytes of the resource - either the size of its register range, or the size of the memory block. */ - u32 irq; /**< IRQ number delivered to the CPU, or -1 to tell the driver to probe for it (if possible) */ - u32 flags; /**< Resources-specific flags. */ - u32 mmu_id; /**< Identifier for Mali MMU resources. */ - u32 alloc_order; /**< Order in which MEMORY/OS_MEMORY resources are used */ -} _mali_osk_resource_t; -/** @} */ /* end group _mali_osk_miscellaneous */ - - -#include "mali_kernel_memory_engine.h" /* include for mali_memory_allocation and mali_physical_memory_allocation type */ - -/** @addtogroup _mali_osk_irq - * @{ */ - -/** @brief Fake IRQ number for testing purposes - */ -#define _MALI_OSK_IRQ_NUMBER_FAKE ((u32)0xFFFFFFF1) - -/** @addtogroup _mali_osk_irq - * @{ */ - -/** @brief PMM Virtual IRQ number - */ -#define _MALI_OSK_IRQ_NUMBER_PMM ((u32)0xFFFFFFF2) - - -/** @brief Initialize IRQ handling for a resource - * - * The _mali_osk_irq_t returned must be written into the resource-specific data - * pointed to by data. This is so that the upper and lower handlers can call - * _mali_osk_irq_schedulework(). - * - * @note The caller must ensure that the resource does not generate an - * interrupt after _mali_osk_irq_init() finishes, and before the - * _mali_osk_irq_t is written into the resource-specific data. Otherwise, - * the upper-half handler will fail to call _mali_osk_irq_schedulework(). - * - * @param irqnum The IRQ number that the resource uses, as seen by the CPU. - * The value -1 has a special meaning which indicates the use of probing, and trigger_func and ack_func must be - * non-NULL. - * @param uhandler The upper-half handler, corresponding to a ISR handler for - * the resource - * @param bhandler The lower-half handler, corresponding to an IST handler for - * the resource - * @param trigger_func Optional: a function to trigger the resource's irq, to - * probe for the interrupt. Use NULL if irqnum != -1. - * @param ack_func Optional: a function to acknowledge the resource's irq, to - * probe for the interrupt. Use NULL if irqnum != -1. - * @param data resource-specific data, which will be passed to uhandler, - * bhandler and (if present) trigger_func and ack_funnc - * @param description textual description of the IRQ resource. - * @return on success, a pointer to a _mali_osk_irq_t object, which represents - * the IRQ handling on this resource. NULL on failure. - */ -_mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandler, _mali_osk_irq_bhandler_t bhandler, _mali_osk_irq_trigger_t trigger_func, _mali_osk_irq_ack_t ack_func, void *data, const char *description ); - -/** @brief Cause a queued, deferred call of the IRQ bottom-half. - * - * _mali_osk_irq_schedulework provides a mechanism for enqueuing deferred calls - * to the IRQ bottom-half handler. The queue is known as the IRQ work-queue. - * After calling _mali_osk_irq_schedulework(), the IRQ bottom-half handler will - * be scheduled to run at some point in the future. - * - * This is called by the IRQ upper-half to defer further processing of - * IRQ-related work to the IRQ bottom-half handler. This is necessary for work - * that cannot be done in an IRQ context by the IRQ upper-half handler. Timer - * callbacks also use this mechanism, because they are treated as though they - * operate in an IRQ context. Refer to \ref _mali_osk_timer_t for more - * information. - * - * Code that operates in a kernel-process context (with no IRQ context - * restrictions) may also enqueue deferred calls to the IRQ bottom-half. The - * advantage over direct calling is that deferred calling allows the caller and - * IRQ bottom half to hold the same mutex, with a guarantee that they will not - * deadlock just by using this mechanism. - * - * _mali_osk_irq_schedulework() places deferred call requests on a queue, to - * allow for more than one thread to make a deferred call. Therfore, if it is - * called 'K' times, then the IRQ bottom-half will be scheduled 'K' times too. - * 'K' is a number that is implementation-specific. - * - * _mali_osk_irq_schedulework() is guaranteed to not block on: - * - enqueuing a deferred call request. - * - the completion of the IRQ bottom-half handler. - * - * This is to prevent deadlock. For example, if _mali_osk_irq_schedulework() - * blocked, then it would cause a deadlock when the following two conditions - * hold: - * - The IRQ bottom-half callback (of type _mali_osk_irq_bhandler_t) locks - * a mutex - * - And, at the same time, the caller of _mali_osk_irq_schedulework() also - * holds the same mutex - * - * @note care must be taken to not overflow the queue that - * _mali_osk_irq_schedulework() operates on. Code must be structured to - * ensure that the number of requests made to the queue is bounded. Otherwise, - * IRQs will be lost. - * - * The queue that _mali_osk_irq_schedulework implements is a FIFO of N-writer, - * 1-reader type. The writers are the callers of _mali_osk_irq_schedulework - * (all OSK-registered IRQ upper-half handlers in the system, watchdog timers, - * callers from a Kernel-process context). The reader is a single thread that - * handles all OSK-registered IRQs. - * - * The consequence of the queue being a 1-reader type is that calling - * _mali_osk_irq_schedulework() on different _mali_osk_irq_t objects causes - * their IRQ bottom-halves to be serialized, across all CPU-cores in the - * system. - * - * @param irq a pointer to the _mali_osk_irq_t object corresponding to the - * resource whose IRQ bottom-half must begin processing. - */ -void _mali_osk_irq_schedulework( _mali_osk_irq_t *irq ); - -/** @brief Terminate IRQ handling on a resource. - * - * This will disable the interrupt from the device, and then waits for the - * IRQ work-queue to finish the work that is currently in the queue. That is, - * for every deferred call currently in the IRQ work-queue, it waits for each - * of those to be processed by their respective IRQ bottom-half handler. - * - * This function is used to ensure that the bottom-half handler of the supplied - * IRQ object will not be running at the completion of this function call. - * However, the caller must ensure that no other sources could call the - * _mali_osk_irq_schedulework() on the same IRQ object. For example, the - * relevant timers must be stopped. - * - * @note While this function is being called, other OSK-registered IRQs in the - * system may enqueue work for their respective bottom-half handlers. This - * function will not wait for those entries in the work-queue to be flushed. - * - * Since this blocks on the completion of work in the IRQ work-queue, the - * caller of this function \b must \b not hold any mutexes that are taken by - * any OSK-registered IRQ bottom-half handler. To do so may cause a deadlock. - * - * @param irq a pointer to the _mali_osk_irq_t object corresponding to the - * resource whose IRQ handling is to be terminated. - */ -void _mali_osk_irq_term( _mali_osk_irq_t *irq ); - -/** @brief flushing workqueue. - * - * This will flush the workqueue. - * - * @param irq a pointer to the _mali_osk_irq_t object corresponding to the - * resource whose IRQ handling is to be terminated. - */ -void _mali_osk_flush_workqueue( _mali_osk_irq_t *irq ); - -/** @} */ /* end group _mali_osk_irq */ - - -/** @addtogroup _mali_osk_atomic - * @{ */ - -/** @brief Decrement an atomic counter - * - * @note It is an error to decrement the counter beyond -(1<<23) - * - * @param atom pointer to an atomic counter */ -void _mali_osk_atomic_dec( _mali_osk_atomic_t *atom ); - -/** @brief Decrement an atomic counter, return new value - * - * @param atom pointer to an atomic counter - * @return The new value, after decrement */ -u32 _mali_osk_atomic_dec_return( _mali_osk_atomic_t *atom ); - -/** @brief Increment an atomic counter - * - * @note It is an error to increment the counter beyond (1<<23)-1 - * - * @param atom pointer to an atomic counter */ -void _mali_osk_atomic_inc( _mali_osk_atomic_t *atom ); - -/** @brief Increment an atomic counter, return new value - * - * @param atom pointer to an atomic counter */ -u32 _mali_osk_atomic_inc_return( _mali_osk_atomic_t *atom ); - -/** @brief Initialize an atomic counter - * - * @note the parameter required is a u32, and so signed integers should be - * cast to u32. - * - * @param atom pointer to an atomic counter - * @param val the value to initialize the atomic counter. - * @return _MALI_OSK_ERR_OK on success, otherwise, a suitable - * _mali_osk_errcode_t on failure. - */ -_mali_osk_errcode_t _mali_osk_atomic_init( _mali_osk_atomic_t *atom, u32 val ); - -/** @brief Read a value from an atomic counter - * - * This can only be safely used to determine the value of the counter when it - * is guaranteed that other threads will not be modifying the counter. This - * makes its usefulness limited. - * - * @param atom pointer to an atomic counter - */ -u32 _mali_osk_atomic_read( _mali_osk_atomic_t *atom ); - -/** @brief Terminate an atomic counter - * - * @param atom pointer to an atomic counter - */ -void _mali_osk_atomic_term( _mali_osk_atomic_t *atom ); -/** @} */ /* end group _mali_osk_atomic */ - - -/** @defgroup _mali_osk_memory OSK Memory Allocation - * @{ */ - -/** @brief Allocate zero-initialized memory. - * - * Returns a buffer capable of containing at least \a n elements of \a size - * bytes each. The buffer is initialized to zero. - * - * If there is a need for a bigger block of memory (16KB or bigger), then - * consider to use _mali_osk_vmalloc() instead, as this function might - * map down to a OS function with size limitations. - * - * The buffer is suitably aligned for storage and subsequent access of every - * type that the compiler supports. Therefore, the pointer to the start of the - * buffer may be cast into any pointer type, and be subsequently accessed from - * such a pointer, without loss of information. - * - * When the buffer is no longer in use, it must be freed with _mali_osk_free(). - * Failure to do so will cause a memory leak. - * - * @note Most toolchains supply memory allocation functions that meet the - * compiler's alignment requirements. - * - * @param n Number of elements to allocate - * @param size Size of each element - * @return On success, the zero-initialized buffer allocated. NULL on failure - */ -void *_mali_osk_calloc( u32 n, u32 size ); - -/** @brief Allocate memory. - * - * Returns a buffer capable of containing at least \a size bytes. The - * contents of the buffer are undefined. - * - * If there is a need for a bigger block of memory (16KB or bigger), then - * consider to use _mali_osk_vmalloc() instead, as this function might - * map down to a OS function with size limitations. - * - * The buffer is suitably aligned for storage and subsequent access of every - * type that the compiler supports. Therefore, the pointer to the start of the - * buffer may be cast into any pointer type, and be subsequently accessed from - * such a pointer, without loss of information. - * - * When the buffer is no longer in use, it must be freed with _mali_osk_free(). - * Failure to do so will cause a memory leak. - * - * @note Most toolchains supply memory allocation functions that meet the - * compiler's alignment requirements. - * - * Remember to free memory using _mali_osk_free(). - * @param size Number of bytes to allocate - * @return On success, the buffer allocated. NULL on failure. - */ -void *_mali_osk_malloc( u32 size ); - -/** @brief Free memory. - * - * Reclaims the buffer pointed to by the parameter \a ptr for the system. - * All memory returned from _mali_osk_malloc() and _mali_osk_calloc() - * must be freed before the application exits. Otherwise, - * a memory leak will occur. - * - * Memory must be freed once. It is an error to free the same non-NULL pointer - * more than once. - * - * It is legal to free the NULL pointer. - * - * @param ptr Pointer to buffer to free - */ -void _mali_osk_free( void *ptr ); - -/** @brief Allocate memory. - * - * Returns a buffer capable of containing at least \a size bytes. The - * contents of the buffer are undefined. - * - * This function is potentially slower than _mali_osk_malloc() and _mali_osk_calloc(), - * but do support bigger sizes. - * - * The buffer is suitably aligned for storage and subsequent access of every - * type that the compiler supports. Therefore, the pointer to the start of the - * buffer may be cast into any pointer type, and be subsequently accessed from - * such a pointer, without loss of information. - * - * When the buffer is no longer in use, it must be freed with _mali_osk_free(). - * Failure to do so will cause a memory leak. - * - * @note Most toolchains supply memory allocation functions that meet the - * compiler's alignment requirements. - * - * Remember to free memory using _mali_osk_free(). - * @param size Number of bytes to allocate - * @return On success, the buffer allocated. NULL on failure. - */ -void *_mali_osk_valloc( u32 size ); - -/** @brief Free memory. - * - * Reclaims the buffer pointed to by the parameter \a ptr for the system. - * All memory returned from _mali_osk_valloc() must be freed before the - * application exits. Otherwise a memory leak will occur. - * - * Memory must be freed once. It is an error to free the same non-NULL pointer - * more than once. - * - * It is legal to free the NULL pointer. - * - * @param ptr Pointer to buffer to free - */ -void _mali_osk_vfree( void *ptr ); - -/** @brief Copies memory. - * - * Copies the \a len bytes from the buffer pointed by the parameter \a src - * directly to the buffer pointed by \a dst. - * - * It is an error for \a src to overlap \a dst anywhere in \a len bytes. - * - * @param dst Pointer to the destination array where the content is to be - * copied. - * @param src Pointer to the source of data to be copied. - * @param len Number of bytes to copy. - * @return \a dst is always passed through unmodified. - */ -void *_mali_osk_memcpy( void *dst, const void *src, u32 len ); - -/** @brief Fills memory. - * - * Sets the first \a n bytes of the block of memory pointed to by \a s to - * the specified value - * @param s Pointer to the block of memory to fill. - * @param c Value to be set, passed as u32. Only the 8 Least Significant Bits (LSB) - * are used. - * @param n Number of bytes to be set to the value. - * @return \a s is always passed through unmodified - */ -void *_mali_osk_memset( void *s, u32 c, u32 n ); -/** @} */ /* end group _mali_osk_memory */ - - -/** @brief Checks the amount of memory allocated - * - * Checks that not more than \a max_allocated bytes are allocated. - * - * Some OS bring up an interactive out of memory dialogue when the - * system runs out of memory. This can stall non-interactive - * apps (e.g. automated test runs). This function can be used to - * not trigger the OOM dialogue by keeping allocations - * within a certain limit. - * - * @return MALI_TRUE when \a max_allocated bytes are not in use yet. MALI_FALSE - * when at least \a max_allocated bytes are in use. - */ -mali_bool _mali_osk_mem_check_allocated( u32 max_allocated ); - -/** @addtogroup _mali_osk_lock - * @{ */ - -/** @brief Initialize a Mutual Exclusion Lock - * - * Locks are created in the signalled (unlocked) state. - * - * initial must be zero, since there is currently no means of expressing - * whether a reader/writer lock should be initially locked as a reader or - * writer. This would require some encoding to be used. - * - * 'Automatic' ordering means that locks must be obtained in the order that - * they were created. For all locks that can be held at the same time, they must - * either all provide the order parameter, or they all must use 'automatic' - * ordering - because there is no way of mixing 'automatic' and 'manual' - * ordering. - * - * @param flags flags combined with bitwise OR ('|'), or zero. There are - * restrictions on which flags can be combined, @see _mali_osk_lock_flags_t. - * @param initial For future expansion into semaphores. SBZ. - * @param order The locking order of the mutex. That is, locks obtained by the - * same thread must have been created with an increasing order parameter, for - * deadlock prevention. Setting to zero causes 'automatic' ordering to be used. - * @return On success, a pointer to a _mali_osk_lock_t object. NULL on failure. - */ -_mali_osk_lock_t *_mali_osk_lock_init( _mali_osk_lock_flags_t flags, u32 initial, u32 order ); - -/** @brief Wait for a lock to be signalled (obtained) - - * After a thread has successfully waited on the lock, the lock is obtained by - * the thread, and is marked as unsignalled. The thread releases the lock by - * signalling it. - * - * In the case of Reader/Writer locks, multiple readers can obtain a lock in - * the absence of writers, which is a performance optimization (providing that - * the readers never write to the protected resource). - * - * To prevent deadlock, locks must always be obtained in the same order. - * - * For locks marked as _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, it is a - * programming error for the function to exit without obtaining the lock. This - * means that the error code must only be checked for interruptible locks. - * - * @param lock the lock to wait upon (obtain). - * @param mode the mode in which the lock should be obtained. Unless the lock - * was created with _MALI_OSK_LOCKFLAG_READERWRITER, this must be - * _MALI_OSK_LOCKMODE_RW. - * @return On success, _MALI_OSK_ERR_OK. For interruptible locks, a suitable - * _mali_osk_errcode_t will be returned on failure, and the lock will not be - * obtained. In this case, the error code must be propagated up to the U/K - * interface. - */ -_mali_osk_errcode_t _mali_osk_lock_wait( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode); - - -/** @brief Signal (release) a lock - * - * Locks may only be signalled by the thread that originally waited upon the - * lock. - * - * @note In the OSU, a flag exists to allow any thread to signal a - * lock. Such functionality is not present in the OSK. - * - * @param lock the lock to signal (release). - * @param mode the mode in which the lock should be obtained. This must match - * the mode in which the lock was waited upon. - */ -void _mali_osk_lock_signal( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode ); - -/** @brief Terminate a lock - * - * This terminates a lock and frees all associated resources. - * - * It is a programming error to terminate the lock when it is held (unsignalled) - * by a thread. - * - * @param lock the lock to terminate. - */ -void _mali_osk_lock_term( _mali_osk_lock_t *lock ); -/** @} */ /* end group _mali_osk_lock */ - - -/** @addtogroup _mali_osk_low_level_memory - * @{ */ - -/** @brief Issue a memory barrier - * - * This defines an arbitrary memory barrier operation, which forces an ordering constraint - * on memory read and write operations. - */ -void _mali_osk_mem_barrier( void ); - -/** @brief Issue a write memory barrier - * - * This defines an write memory barrier operation which forces an ordering constraint - * on memory write operations. - */ -void _mali_osk_write_mem_barrier( void ); - -/** @brief Map a physically contiguous region into kernel space - * - * This is primarily used for mapping in registers from resources, and Mali-MMU - * page tables. The mapping is only visable from kernel-space. - * - * Access has to go through _mali_osk_mem_ioread32 and _mali_osk_mem_iowrite32 - * - * @param phys CPU-physical base address of the memory to map in. This must - * be aligned to the system's page size, which is assumed to be 4K. - * @param size the number of bytes of physically contiguous address space to - * map in - * @param description A textual description of the memory being mapped in. - * @return On success, a Mali IO address through which the mapped-in - * memory/registers can be accessed. NULL on failure. - */ -mali_io_address _mali_osk_mem_mapioregion( u32 phys, u32 size, const char *description ); - -/** @brief Unmap a physically contiguous address range from kernel space. - * - * The address range should be one previously mapped in through - * _mali_osk_mem_mapioregion. - * - * It is a programming error to do (but not limited to) the following: - * - attempt an unmap twice - * - unmap only part of a range obtained through _mali_osk_mem_mapioregion - * - unmap more than the range obtained through _mali_osk_mem_mapioregion - * - unmap an address range that was not successfully mapped using - * _mali_osk_mem_mapioregion - * - provide a mapping that does not map to phys. - * - * @param phys CPU-physical base address of the memory that was originally - * mapped in. This must be aligned to the system's page size, which is assumed - * to be 4K - * @param size The number of bytes that were originally mapped in. - * @param mapping The Mali IO address through which the mapping is - * accessed. - */ -void _mali_osk_mem_unmapioregion( u32 phys, u32 size, mali_io_address mapping ); - -/** @brief Allocate and Map a physically contiguous region into kernel space - * - * This is used for allocating physically contiguous regions (such as Mali-MMU - * page tables) and mapping them into kernel space. The mapping is only - * visible from kernel-space. - * - * The alignment of the returned memory is guaranteed to be at least - * _MALI_OSK_CPU_PAGE_SIZE. - * - * Access must go through _mali_osk_mem_ioread32 and _mali_osk_mem_iowrite32 - * - * @note This function is primarily to provide support for OSs that are - * incapable of separating the tasks 'allocate physically contiguous memory' - * and 'map it into kernel space' - * - * @param[out] phys CPU-physical base address of memory that was allocated. - * (*phys) will be guaranteed to be aligned to at least - * _MALI_OSK_CPU_PAGE_SIZE on success. - * - * @param[in] size the number of bytes of physically contiguous memory to - * allocate. This must be a multiple of _MALI_OSK_CPU_PAGE_SIZE. - * - * @return On success, a Mali IO address through which the mapped-in - * memory/registers can be accessed. NULL on failure, and (*phys) is unmodified. - */ -mali_io_address _mali_osk_mem_allocioregion( u32 *phys, u32 size ); - -/** @brief Free a physically contiguous address range from kernel space. - * - * The address range should be one previously mapped in through - * _mali_osk_mem_allocioregion. - * - * It is a programming error to do (but not limited to) the following: - * - attempt a free twice on the same ioregion - * - free only part of a range obtained through _mali_osk_mem_allocioregion - * - free more than the range obtained through _mali_osk_mem_allocioregion - * - free an address range that was not successfully mapped using - * _mali_osk_mem_allocioregion - * - provide a mapping that does not map to phys. - * - * @param phys CPU-physical base address of the memory that was originally - * mapped in, which was aligned to _MALI_OSK_CPU_PAGE_SIZE. - * @param size The number of bytes that were originally mapped in, which was - * a multiple of _MALI_OSK_CPU_PAGE_SIZE. - * @param mapping The Mali IO address through which the mapping is - * accessed. - */ -void _mali_osk_mem_freeioregion( u32 phys, u32 size, mali_io_address mapping ); - -/** @brief Request a region of physically contiguous memory - * - * This is used to ensure exclusive access to a region of physically contigous - * memory. - * - * It is acceptable to implement this as a stub. However, it is then the job - * of the System Integrator to ensure that no other device driver will be using - * the physical address ranges used by Mali, while the Mali device driver is - * loaded. - * - * @param phys CPU-physical base address of the memory to request. This must - * be aligned to the system's page size, which is assumed to be 4K. - * @param size the number of bytes of physically contiguous address space to - * request. - * @param description A textual description of the memory being requested. - * @return _MALI_OSK_ERR_OK on success. Otherwise, a suitable - * _mali_osk_errcode_t on failure. - */ -_mali_osk_errcode_t _mali_osk_mem_reqregion( u32 phys, u32 size, const char *description ); - -/** @brief Un-request a region of physically contiguous memory - * - * This is used to release a regious of physically contiguous memory previously - * requested through _mali_osk_mem_reqregion, so that other device drivers may - * use it. This will be called at time of Mali device driver termination. - * - * It is a programming error to attempt to: - * - unrequest a region twice - * - unrequest only part of a range obtained through _mali_osk_mem_reqregion - * - unrequest more than the range obtained through _mali_osk_mem_reqregion - * - unrequest an address range that was not successfully requested using - * _mali_osk_mem_reqregion - * - * @param phys CPU-physical base address of the memory to un-request. This must - * be aligned to the system's page size, which is assumed to be 4K - * @param size the number of bytes of physically contiguous address space to - * un-request. - */ -void _mali_osk_mem_unreqregion( u32 phys, u32 size ); - -/** @brief Read from a location currently mapped in through - * _mali_osk_mem_mapioregion - * - * This reads a 32-bit word from a 32-bit aligned location. It is a programming - * error to provide unaligned locations, or to read from memory that is not - * mapped in, or not mapped through either _mali_osk_mem_mapioregion() or - * _mali_osk_mem_allocioregion(). - * - * @param mapping Mali IO address to read from - * @param offset Byte offset from the given IO address to operate on, must be a multiple of 4 - * @return the 32-bit word from the specified location. - */ -u32 _mali_osk_mem_ioread32( volatile mali_io_address mapping, u32 offset ); - -/** @brief Write to a location currently mapped in through - * _mali_osk_mem_mapioregion without memory barriers - * - * This write a 32-bit word to a 32-bit aligned location without using memory barrier. - * It is a programming error to provide unaligned locations, or to write to memory that is not - * mapped in, or not mapped through either _mali_osk_mem_mapioregion() or - * _mali_osk_mem_allocioregion(). - * - * @param mapping Mali IO address to write to - * @param offset Byte offset from the given IO address to operate on, must be a multiple of 4 - * @param val the 32-bit word to write. - */ -void _mali_osk_mem_iowrite32_relaxed( volatile mali_io_address addr, u32 offset, u32 val ); - -/** @brief Write to a location currently mapped in through - * _mali_osk_mem_mapioregion with write memory barrier - * - * This write a 32-bit word to a 32-bit aligned location. It is a programming - * error to provide unaligned locations, or to write to memory that is not - * mapped in, or not mapped through either _mali_osk_mem_mapioregion() or - * _mali_osk_mem_allocioregion(). - * - * @param mapping Mali IO address to write to - * @param offset Byte offset from the given IO address to operate on, must be a multiple of 4 - * @param val the 32-bit word to write. - */ -void _mali_osk_mem_iowrite32( volatile mali_io_address mapping, u32 offset, u32 val ); - -/** @brief Flush all CPU caches - * - * This should only be implemented if flushing of the cache is required for - * memory mapped in through _mali_osk_mem_mapregion. - */ -void _mali_osk_cache_flushall( void ); - -/** @brief Flush any caches necessary for the CPU and MALI to have the same view of a range of uncached mapped memory - * - * This should only be implemented if your OS doesn't do a full cache flush (inner & outer) - * after allocating uncached mapped memory. - * - * Some OS do not perform a full cache flush (including all outer caches) for uncached mapped memory. - * They zero the memory through a cached mapping, then flush the inner caches but not the outer caches. - * This is required for MALI to have the correct view of the memory. - */ -void _mali_osk_cache_ensure_uncached_range_flushed( void *uncached_mapping, u32 offset, u32 size ); - -/** @} */ /* end group _mali_osk_low_level_memory */ - - -/** @addtogroup _mali_osk_notification - * - * User space notification framework - * - * Communication with user space of asynchronous events is performed through a - * synchronous call to the \ref u_k_api. - * - * Since the events are asynchronous, the events have to be queued until a - * synchronous U/K API call can be made by user-space. A U/K API call might also - * be received before any event has happened. Therefore the notifications the - * different subsystems wants to send to user space has to be queued for later - * reception, or a U/K API call has to be blocked until an event has occured. - * - * Typical uses of notifications are after running of jobs on the hardware or - * when changes to the system is detected that needs to be relayed to user - * space. - * - * After an event has occured user space has to be notified using some kind of - * message. The notification framework supports sending messages to waiting - * threads or queueing of messages until a U/K API call is made. - * - * The notification queue is a FIFO. There are no restrictions on the numbers - * of readers or writers in the queue. - * - * A message contains what user space needs to identifiy how to handle an - * event. This includes a type field and a possible type specific payload. - * - * A notification to user space is represented by a - * \ref _mali_osk_notification_t object. A sender gets hold of such an object - * using _mali_osk_notification_create(). The buffer given by the - * _mali_osk_notification_t::result_buffer field in the object is used to store - * any type specific data. The other fields are internal to the queue system - * and should not be touched. - * - * @{ */ - -/** @brief Create a notification object - * - * Returns a notification object which can be added to the queue of - * notifications pending for user space transfer. - * - * The implementation will initialize all members of the - * \ref _mali_osk_notification_t object. In particular, the - * _mali_osk_notification_t::result_buffer member will be initialized to point - * to \a size bytes of storage, and that storage will be suitably aligned for - * storage of any structure. That is, the created buffer meets the same - * requirements as _mali_osk_malloc(). - * - * The notification object must be deleted when not in use. Use - * _mali_osk_notification_delete() for deleting it. - * - * @note You \b must \b not call _mali_osk_free() on a \ref _mali_osk_notification_t, - * object, or on a _mali_osk_notification_t::result_buffer. You must only use - * _mali_osk_notification_delete() to free the resources assocaited with a - * \ref _mali_osk_notification_t object. - * - * @param type The notification type - * @param size The size of the type specific buffer to send - * @return Pointer to a notification object with a suitable buffer, or NULL on error. - */ -_mali_osk_notification_t *_mali_osk_notification_create( u32 type, u32 size ); - -/** @brief Delete a notification object - * - * This must be called to reclaim the resources of a notification object. This - * includes: - * - The _mali_osk_notification_t::result_buffer - * - The \ref _mali_osk_notification_t itself. - * - * A notification object \b must \b not be used after it has been deleted by - * _mali_osk_notification_delete(). - * - * In addition, the notification object may not be deleted while it is in a - * queue. That is, if it has been placed on a queue with - * _mali_osk_notification_queue_send(), then it must not be deleted until - * it has been received by a call to _mali_osk_notification_queue_receive(). - * Otherwise, the queue may be corrupted. - * - * @param object the notification object to delete. - */ -void _mali_osk_notification_delete( _mali_osk_notification_t *object ); - -/** @brief Create a notification queue - * - * Creates a notification queue which can be used to queue messages for user - * delivery and get queued messages from - * - * The queue is a FIFO, and has no restrictions on the numbers of readers or - * writers. - * - * When the queue is no longer in use, it must be terminated with - * \ref _mali_osk_notification_queue_term(). Failure to do so will result in a - * memory leak. - * - * @return Pointer to a new notification queue or NULL on error. - */ -_mali_osk_notification_queue_t *_mali_osk_notification_queue_init( void ); - -/** @brief Destroy a notification queue - * - * Destroys a notification queue and frees associated resources from the queue. - * - * A notification queue \b must \b not be destroyed in the following cases: - * - while there are \ref _mali_osk_notification_t objects in the queue. - * - while there are writers currently acting upon the queue. That is, while - * a thread is currently calling \ref _mali_osk_notification_queue_send() on - * the queue, or while a thread may call - * \ref _mali_osk_notification_queue_send() on the queue in the future. - * - while there are readers currently waiting upon the queue. That is, while - * a thread is currently calling \ref _mali_osk_notification_queue_receive() on - * the queue, or while a thread may call - * \ref _mali_osk_notification_queue_receive() on the queue in the future. - * - * Therefore, all \ref _mali_osk_notification_t objects must be flushed and - * deleted by the code that makes use of the notification queues, since only - * they know the structure of the _mali_osk_notification_t::result_buffer - * (even if it may only be a flat sturcture). - * - * @note Since the queue is a FIFO, the code using notification queues may - * create its own 'flush' type of notification, to assist in flushing the - * queue. - * - * Once the queue has been destroyed, it must not be used again. - * - * @param queue The queue to destroy - */ -void _mali_osk_notification_queue_term( _mali_osk_notification_queue_t *queue ); - -/** @brief Schedule notification for delivery - * - * When a \ref _mali_osk_notification_t object has been created successfully - * and set up, it may be added to the queue of objects waiting for user space - * transfer. - * - * The sending will not block if the queue is full. - * - * A \ref _mali_osk_notification_t object \b must \b not be put on two different - * queues at the same time, or enqueued twice onto a single queue before - * reception. However, it is acceptable for it to be requeued \em after reception - * from a call to _mali_osk_notification_queue_receive(), even onto the same queue. - * - * Again, requeuing must also not enqueue onto two different queues at the same - * time, or enqueue onto the same queue twice before reception. - * - * @param queue The notification queue to add this notification to - * @param object The entry to add - */ -void _mali_osk_notification_queue_send( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t *object ); - -#if MALI_STATE_TRACKING -/** @brief Receive a notification from a queue - * - * Check if a notification queue is empty. - * - * @param queue The queue to check. - * @return MALI_TRUE if queue is empty, otherwise MALI_FALSE. - */ -mali_bool _mali_osk_notification_queue_is_empty( _mali_osk_notification_queue_t *queue ); -#endif - -/** @brief Receive a notification from a queue - * - * Receives a single notification from the given queue. - * - * If no notifciations are ready the thread will sleep until one becomes ready. - * Therefore, notifications may not be received into an - * IRQ or 'atomic' context (that is, a context where sleeping is disallowed). - * - * @param queue The queue to receive from - * @param result Pointer to storage of a pointer of type - * \ref _mali_osk_notification_t*. \a result will be written to such that the - * expression \a (*result) will evaluate to a pointer to a valid - * \ref _mali_osk_notification_t object, or NULL if none were received. - * @return _MALI_OSK_ERR_OK on success. _MALI_OSK_ERR_RESTARTSYSCALL if the sleep was interrupted. - */ -_mali_osk_errcode_t _mali_osk_notification_queue_receive( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t **result ); - -/** @brief Dequeues a notification from a queue - * - * Receives a single notification from the given queue. - * - * If no notifciations are ready the function call will return an error code. - * - * @param queue The queue to receive from - * @param result Pointer to storage of a pointer of type - * \ref _mali_osk_notification_t*. \a result will be written to such that the - * expression \a (*result) will evaluate to a pointer to a valid - * \ref _mali_osk_notification_t object, or NULL if none were received. - * @return _MALI_OSK_ERR_OK on success, _MALI_OSK_ERR_ITEM_NOT_FOUND if queue was empty. - */ -_mali_osk_errcode_t _mali_osk_notification_queue_dequeue( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t **result ); - -/** @} */ /* end group _mali_osk_notification */ - - -/** @addtogroup _mali_osk_timer - * - * Timers use the OS's representation of time, which are 'ticks'. This is to - * prevent aliasing problems between the internal timer time, and the time - * asked for. - * - * @{ */ - -/** @brief Initialize a timer - * - * Allocates resources for a new timer, and initializes them. This does not - * start the timer. - * - * @return a pointer to the allocated timer object, or NULL on failure. - */ -_mali_osk_timer_t *_mali_osk_timer_init(void); - -/** @brief Start a timer - * - * It is an error to start a timer without setting the callback via - * _mali_osk_timer_setcallback(). - * - * It is an error to use this to start an already started timer. - * - * The timer will expire in \a ticks_to_expire ticks, at which point, the - * callback function will be invoked with the callback-specific data, - * as registered by _mali_osk_timer_setcallback(). - * - * @param tim the timer to start - * @param ticks_to_expire the amount of time in ticks for the timer to run - * before triggering. - */ -void _mali_osk_timer_add( _mali_osk_timer_t *tim, u32 ticks_to_expire ); - -/** @brief Modify a timer - * - * Set the absolute time at which a timer will expire, and start it if it is - * stopped. If \a expiry_tick is in the past (determined by - * _mali_osk_time_after() ), the timer fires immediately. - * - * It is an error to modify a timer without setting the callback via - * _mali_osk_timer_setcallback(). - * - * The timer will expire at absolute time \a expiry_tick, at which point, the - * callback function will be invoked with the callback-specific data, as set - * by _mali_osk_timer_setcallback(). - * - * @param tim the timer to modify, and start if necessary - * @param expiry_tick the \em absolute time in ticks at which this timer should - * trigger. - * - */ -void _mali_osk_timer_mod( _mali_osk_timer_t *tim, u32 expiry_tick); - -/** @brief Stop a timer, and block on its completion. - * - * Stop the timer. When the function returns, it is guaranteed that the timer's - * callback will not be running on any CPU core. - * - * Since stoping the timer blocks on compeletion of the callback, the callback - * may not obtain any mutexes that the caller holds. Otherwise, a deadlock will - * occur. - * - * @note While the callback itself is guaranteed to not be running, work - * enqueued on the IRQ work-queue by the timer (with - * \ref _mali_osk_irq_schedulework()) may still run. The timer callback and IRQ - * bottom-half handler must take this into account. - * - * It is legal to stop an already stopped timer. - * - * @param tim the timer to stop. - * - */ -void _mali_osk_timer_del( _mali_osk_timer_t *tim ); - -/** @brief Set a timer's callback parameters. - * - * This must be called at least once before a timer is started/modified. - * - * After a timer has been stopped or expires, the callback remains set. This - * means that restarting the timer will call the same function with the same - * parameters on expiry. - * - * @param tim the timer to set callback on. - * @param callback Function to call when timer expires - * @param data Function-specific data to supply to the function on expiry. - */ -void _mali_osk_timer_setcallback( _mali_osk_timer_t *tim, _mali_osk_timer_callback_t callback, void *data ); - -/** @brief Terminate a timer, and deallocate resources. - * - * The timer must first be stopped by calling _mali_osk_timer_del(). - * - * It is a programming error for _mali_osk_timer_term() to be called on: - * - timer that is currently running - * - a timer that is currently executing its callback. - * - * @param tim the timer to deallocate. - */ -void _mali_osk_timer_term( _mali_osk_timer_t *tim ); -/** @} */ /* end group _mali_osk_timer */ - - -/** @defgroup _mali_osk_time OSK Time functions - * - * \ref _mali_osk_time use the OS's representation of time, which are - * 'ticks'. This is to prevent aliasing problems between the internal timer - * time, and the time asked for. - * - * OS tick time is measured as a u32. The time stored in a u32 may either be - * an absolute time, or a time delta between two events. Whilst it is valid to - * use math opeartors to \em change the tick value represented as a u32, it - * is often only meaningful to do such operations on time deltas, rather than - * on absolute time. However, it is meaningful to add/subtract time deltas to - * absolute times. - * - * Conversion between tick time and milliseconds (ms) may not be loss-less, - * and are \em implementation \em depenedant. - * - * Code use OS time must take this into account, since: - * - a small OS time may (or may not) be rounded - * - a large time may (or may not) overflow - * - * @{ */ - -/** @brief Return whether ticka occurs after tickb - * - * Some OSs handle tick 'rollover' specially, and so can be more robust against - * tick counters rolling-over. This function must therefore be called to - * determine if a time (in ticks) really occurs after another time (in ticks). - * - * @param ticka ticka - * @param tickb tickb - * @return non-zero if ticka represents a time that occurs after tickb. - * Zero otherwise. - */ -int _mali_osk_time_after( u32 ticka, u32 tickb ); - -/** @brief Convert milliseconds to OS 'ticks' - * - * @param ms time interval in milliseconds - * @return the corresponding time interval in OS ticks. - */ -u32 _mali_osk_time_mstoticks( u32 ms ); - -/** @brief Convert OS 'ticks' to milliseconds - * - * @param ticks time interval in OS ticks. - * @return the corresponding time interval in milliseconds - */ -u32 _mali_osk_time_tickstoms( u32 ticks ); - - -/** @brief Get the current time in OS 'ticks'. - * @return the current time in OS 'ticks'. - */ -u32 _mali_osk_time_tickcount( void ); - -/** @brief Cause a microsecond delay - * - * The delay will have microsecond resolution, and is necessary for correct - * operation of the driver. At worst, the delay will be \b at least \a usecs - * microseconds, and so may be (significantly) more. - * - * This function may be implemented as a busy-wait, which is the most sensible - * implementation. On OSs where there are situations in which a thread must not - * sleep, this is definitely implemented as a busy-wait. - * - * @param usecs the number of microseconds to wait for. - */ -void _mali_osk_time_ubusydelay( u32 usecs ); - -/** @brief Return time in nano seconds, since any given reference. - * - * @return Time in nano seconds - */ -u64 _mali_osk_time_get_ns( void ); - - -/** @} */ /* end group _mali_osk_time */ - -/** @defgroup _mali_osk_math OSK Math - * @{ */ - -/** @brief Count Leading Zeros (Little-endian) - * - * @note This function must be implemented to support the reference - * implementation of _mali_osk_find_first_zero_bit, as defined in - * mali_osk_bitops.h. - * - * @param val 32-bit words to count leading zeros on - * @return the number of leading zeros. - */ -u32 _mali_osk_clz( u32 val ); -/** @} */ /* end group _mali_osk_math */ - -/** @defgroup _mali_osk_wait_queue OSK Wait Queue functionality - * @{ */ -/** @brief Private type for wait queue objects */ -typedef struct _mali_osk_wait_queue_t_struct _mali_osk_wait_queue_t; - -/** @brief Initialize an empty Wait Queue */ -_mali_osk_wait_queue_t* _mali_osk_wait_queue_init( void ); - -/** @brief Sleep if condition is false - * - * @param queue the queue to use - * @param condition function pointer to a boolean function - * - * Put thread to sleep if the given \a codition function returns false. When - * being asked to wake up again, the condition will be re-checked and the - * thread only woken up if the condition is now true. - */ -void _mali_osk_wait_queue_wait_event( _mali_osk_wait_queue_t *queue, mali_bool (*condition)(void) ); - -/** @brief Wake up all threads in wait queue if their respective conditions are - * true - * - * @param queue the queue whose threads should be woken up - * - * Wake up all threads in wait queue \a queue whose condition is now true. - */ -void _mali_osk_wait_queue_wake_up( _mali_osk_wait_queue_t *queue ); - -/** @brief terminate a wait queue - * - * @param queue the queue to terminate. - */ -void _mali_osk_wait_queue_term( _mali_osk_wait_queue_t *queue ); -/** @} */ /* end group _mali_osk_wait_queue */ - - -/** @addtogroup _mali_osk_miscellaneous - * @{ */ - -/** @brief Output a device driver debug message. - * - * The interpretation of \a fmt is the same as the \c format parameter in - * _mali_osu_vsnprintf(). - * - * @param fmt a _mali_osu_vsnprintf() style format string - * @param ... a variable-number of parameters suitable for \a fmt - */ -void _mali_osk_dbgmsg( const char *fmt, ... ); - -/** @brief Print fmt into buf. - * - * The interpretation of \a fmt is the same as the \c format parameter in - * _mali_osu_vsnprintf(). - * - * @param buf a pointer to the result buffer - * @param size the total number of bytes allowed to write to \a buf - * @param fmt a _mali_osu_vsnprintf() style format string - * @param ... a variable-number of parameters suitable for \a fmt - * @return The number of bytes written to \a buf - */ -u32 _mali_osk_snprintf( char *buf, u32 size, const char *fmt, ... ); - -/** @brief Abnormal process abort. - * - * Terminates the caller-process if this function is called. - * - * This function will be called from Debug assert-macros in mali_kernel_common.h. - * - * This function will never return - because to continue from a Debug assert - * could cause even more problems, and hinder debugging of the initial problem. - * - * This function is only used in Debug builds, and is not used in Release builds. - */ -void _mali_osk_abort(void); - -/** @brief Sets breakpoint at point where function is called. - * - * This function will be called from Debug assert-macros in mali_kernel_common.h, - * to assist in debugging. If debugging at this level is not required, then this - * function may be implemented as a stub. - * - * This function is only used in Debug builds, and is not used in Release builds. - */ -void _mali_osk_break(void); - -/** @brief Return an identificator for calling process. - * - * @return Identificator for calling process. - */ -u32 _mali_osk_get_pid(void); - -/** @brief Return an identificator for calling thread. - * - * @return Identificator for calling thread. - */ -u32 _mali_osk_get_tid(void); - -/** @brief Enable OS controlled runtime power management - */ -void _mali_osk_pm_dev_enable(void); - -/** @brief Tells the OS that device is now idle - */ -_mali_osk_errcode_t _mali_osk_pm_dev_idle(void); - -/** @brief Tells the OS that the device is about to become active - */ -_mali_osk_errcode_t _mali_osk_pm_dev_activate(void); - -/** @} */ /* end group _mali_osk_miscellaneous */ - -/** @} */ /* end group osuapi */ - -/** @} */ /* end group uddapi */ - - -#ifdef __cplusplus -} -#endif - -#include "mali_osk_specific.h" /* include any per-os specifics */ - -/* Check standard inlines */ -#ifndef MALI_STATIC_INLINE - #error MALI_STATIC_INLINE not defined on your OS -#endif - -#ifndef MALI_NON_STATIC_INLINE - #error MALI_NON_STATIC_INLINE not defined on your OS -#endif - -#endif /* __MALI_OSK_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_osk_bitops.h b/drivers/media/video/samsung/mali/common/mali_osk_bitops.h deleted file mode 100644 index ada1488..0000000 --- a/drivers/media/video/samsung/mali/common/mali_osk_bitops.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_osk_bitops.h - * Implementation of the OS abstraction layer for the kernel device driver - */ - -#ifndef __MALI_OSK_BITOPS_H__ -#define __MALI_OSK_BITOPS_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -MALI_STATIC_INLINE void _mali_internal_clear_bit( u32 bit, u32 *addr ) -{ - MALI_DEBUG_ASSERT( bit < 32 ); - MALI_DEBUG_ASSERT( NULL != addr ); - - (*addr) &= ~(1 << bit); -} - -MALI_STATIC_INLINE void _mali_internal_set_bit( u32 bit, u32 *addr ) -{ - MALI_DEBUG_ASSERT( bit < 32 ); - MALI_DEBUG_ASSERT( NULL != addr ); - - (*addr) |= (1 << bit); -} - -MALI_STATIC_INLINE u32 _mali_internal_test_bit( u32 bit, u32 value ) -{ - MALI_DEBUG_ASSERT( bit < 32 ); - return value & (1 << bit); -} - -MALI_STATIC_INLINE int _mali_internal_find_first_zero_bit( u32 value ) -{ - u32 inverted; - u32 negated; - u32 isolated; - u32 leading_zeros; - - /* Begin with xxx...x0yyy...y, where ys are 1, number of ys is in range 0..31 */ - inverted = ~value; /* zzz...z1000...0 */ - /* Using count_trailing_zeros on inverted value - - * See ARM System Developers Guide for details of count_trailing_zeros */ - - /* Isolate the zero: it is preceeded by a run of 1s, so add 1 to it */ - negated = (u32)-inverted ; /* -a == ~a + 1 (mod 2^n) for n-bit numbers */ - /* negated = xxx...x1000...0 */ - - isolated = negated & inverted ; /* xxx...x1000...0 & zzz...z1000...0, zs are ~xs */ - /* And so the first zero bit is in the same position as the 1 == number of 1s that preceeded it - * Note that the output is zero if value was all 1s */ - - leading_zeros = _mali_osk_clz( isolated ); - - return 31 - leading_zeros; -} - - -/** @defgroup _mali_osk_bitops OSK Non-atomic Bit-operations - * @{ */ - -/** - * These bit-operations do not work atomically, and so locks must be used if - * atomicity is required. - * - * Reference implementations for Little Endian are provided, and so it should - * not normally be necessary to re-implement these. Efficient bit-twiddling - * techniques are used where possible, implemented in portable C. - * - * Note that these reference implementations rely on _mali_osk_clz() being - * implemented. - */ - -/** @brief Clear a bit in a sequence of 32-bit words - * @param nr bit number to clear, starting from the (Little-endian) least - * significant bit - * @param addr starting point for counting. - */ -MALI_STATIC_INLINE void _mali_osk_clear_nonatomic_bit( u32 nr, u32 *addr ) -{ - addr += nr >> 5; /* find the correct word */ - nr = nr & ((1 << 5)-1); /* The bit number within the word */ - - _mali_internal_clear_bit( nr, addr ); -} - -/** @brief Set a bit in a sequence of 32-bit words - * @param nr bit number to set, starting from the (Little-endian) least - * significant bit - * @param addr starting point for counting. - */ -MALI_STATIC_INLINE void _mali_osk_set_nonatomic_bit( u32 nr, u32 *addr ) -{ - addr += nr >> 5; /* find the correct word */ - nr = nr & ((1 << 5)-1); /* The bit number within the word */ - - _mali_internal_set_bit( nr, addr ); -} - -/** @brief Test a bit in a sequence of 32-bit words - * @param nr bit number to test, starting from the (Little-endian) least - * significant bit - * @param addr starting point for counting. - * @return zero if bit was clear, non-zero if set. Do not rely on the return - * value being related to the actual word under test. - */ -MALI_STATIC_INLINE u32 _mali_osk_test_bit( u32 nr, u32 *addr ) -{ - addr += nr >> 5; /* find the correct word */ - nr = nr & ((1 << 5)-1); /* The bit number within the word */ - - return _mali_internal_test_bit( nr, *addr ); -} - -/* Return maxbit if not found */ -/** @brief Find the first zero bit in a sequence of 32-bit words - * @param addr starting point for search. - * @param maxbit the maximum number of bits to search - * @return the number of the first zero bit found, or maxbit if none were found - * in the specified range. - */ -MALI_STATIC_INLINE u32 _mali_osk_find_first_zero_bit( const u32 *addr, u32 maxbit ) -{ - u32 total; - - for ( total = 0; total < maxbit; total += 32, ++addr ) - { - int result; - result = _mali_internal_find_first_zero_bit( *addr ); - - /* non-negative signifies the bit was found */ - if ( result >= 0 ) - { - total += (u32)result; - break; - } - } - - /* Now check if we reached maxbit or above */ - if ( total >= maxbit ) - { - total = maxbit; - } - - return total; /* either the found bit nr, or maxbit if not found */ -} -/** @} */ /* end group _mali_osk_bitops */ - -#ifdef __cplusplus -} -#endif - -#endif /* __MALI_OSK_BITOPS_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_osk_list.h b/drivers/media/video/samsung/mali/common/mali_osk_list.h deleted file mode 100644 index 5987b0a..0000000 --- a/drivers/media/video/samsung/mali/common/mali_osk_list.h +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_osk_list.h - * Implementation of the OS abstraction layer for the kernel device driver - */ - -#ifndef __MALI_OSK_LIST_H__ -#define __MALI_OSK_LIST_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -MALI_STATIC_INLINE void __mali_osk_list_add(_mali_osk_list_t *new_entry, _mali_osk_list_t *prev, _mali_osk_list_t *next) -{ - next->prev = new_entry; - new_entry->next = next; - new_entry->prev = prev; - prev->next = new_entry; -} - -MALI_STATIC_INLINE void __mali_osk_list_del(_mali_osk_list_t *prev, _mali_osk_list_t *next) -{ - next->prev = prev; - prev->next = next; -} - -/** @addtogroup _mali_osk_list - * @{ */ - -/** Reference implementations of Doubly-linked Circular Lists are provided. - * There is often no need to re-implement these. - * - * @note The implementation may differ subtly from any lists the OS provides. - * For this reason, these lists should not be mixed with OS-specific lists - * inside the OSK/UKK implementation. */ - -/** @brief Initialize a list element. - * - * All list elements must be initialized before use. - * - * Do not use on any list element that is present in a list without using - * _mali_osk_list_del first, otherwise this will break the list. - * - * @param list the list element to initialize - */ -MALI_STATIC_INLINE void _mali_osk_list_init( _mali_osk_list_t *list ) -{ - list->next = list; - list->prev = list; -} - -/** @brief Insert a single list element after an entry in a list - * - * As an example, if this is inserted to the head of a list, then this becomes - * the first element of the list. - * - * Do not use to move list elements from one list to another, as it will break - * the originating list. - * - * - * @param newlist the list element to insert - * @param list the list in which to insert. The new element will be the next - * entry in this list - */ -MALI_STATIC_INLINE void _mali_osk_list_add( _mali_osk_list_t *new_entry, _mali_osk_list_t *list ) -{ - __mali_osk_list_add(new_entry, list, list->next); -} - -/** @brief Insert a single list element before an entry in a list - * - * As an example, if this is inserted to the head of a list, then this becomes - * the last element of the list. - * - * Do not use to move list elements from one list to another, as it will break - * the originating list. - * - * @param newlist the list element to insert - * @param list the list in which to insert. The new element will be the previous - * entry in this list - */ -MALI_STATIC_INLINE void _mali_osk_list_addtail( _mali_osk_list_t *new_entry, _mali_osk_list_t *list ) -{ - __mali_osk_list_add(new_entry, list->prev, list); -} - -/** @brief Remove a single element from a list - * - * The element will no longer be present in the list. The removed list element - * will be uninitialized, and so should not be traversed. It must be - * initialized before further use. - * - * @param list the list element to remove. - */ -MALI_STATIC_INLINE void _mali_osk_list_del( _mali_osk_list_t *list ) -{ - __mali_osk_list_del(list->prev, list->next); -} - -/** @brief Remove a single element from a list, and re-initialize it - * - * The element will no longer be present in the list. The removed list element - * will initialized, and so can be used as normal. - * - * @param list the list element to remove and initialize. - */ -MALI_STATIC_INLINE void _mali_osk_list_delinit( _mali_osk_list_t *list ) -{ - __mali_osk_list_del(list->prev, list->next); - _mali_osk_list_init(list); -} - -/** @brief Determine whether a list is empty. - * - * An empty list is one that contains a single element that points to itself. - * - * @param list the list to check. - * @return non-zero if the list is empty, and zero otherwise. - */ -MALI_STATIC_INLINE int _mali_osk_list_empty( _mali_osk_list_t *list ) -{ - return list->next == list; -} - -/** @brief Move a list element from one list to another. - * - * The list element must be initialized. - * - * As an example, moving a list item to the head of a new list causes this item - * to be the first element in the new list. - * - * @param move the list element to move - * @param list the new list into which the element will be inserted, as the next - * element in the list. - */ -MALI_STATIC_INLINE void _mali_osk_list_move( _mali_osk_list_t *move_entry, _mali_osk_list_t *list ) -{ - __mali_osk_list_del(move_entry->prev, move_entry->next); - _mali_osk_list_add(move_entry, list); -} - -/** @brief Join two lists - * - * The list element must be initialized. - * - * Allows you to join a list into another list at a specific location - * - * @param list the new list to add - * @param at the location in a list to add the new list into - */ -MALI_STATIC_INLINE void _mali_osk_list_splice( _mali_osk_list_t *list, _mali_osk_list_t *at ) -{ - if (!_mali_osk_list_empty(list)) - { - /* insert all items from 'list' after 'at' */ - _mali_osk_list_t *first = list->next; - _mali_osk_list_t *last = list->prev; - _mali_osk_list_t *split = at->next; - - first->prev = at; - at->next = first; - - last->next = split; - split->prev = last; - } -} -/** @} */ /* end group _mali_osk_list */ - -#ifdef __cplusplus -} -#endif - -#endif /* __MALI_OSK_LIST_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_osk_mali.h b/drivers/media/video/samsung/mali/common/mali_osk_mali.h deleted file mode 100644 index 427fcc8..0000000 --- a/drivers/media/video/samsung/mali/common/mali_osk_mali.h +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_osk_mali.h - * Defines the OS abstraction layer which is specific for the Mali kernel device driver (OSK) - */ - -#ifndef __MALI_OSK_MALI_H__ -#define __MALI_OSK_MALI_H__ - -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - -/** @addtogroup _mali_osk_miscellaneous - * @{ */ - -/** @brief Read the Mali Resource configuration - * - * Populates a _mali_arch_resource_t array from configuration settings, which - * are stored in an OS-specific way. - * - * For example, these may be compiled in to a static structure, or read from - * the filesystem at startup. - * - * On failure, do not call _mali_osk_resources_term. - * - * @param arch_config a pointer to the store the pointer to the resources - * @param num_resources the number of resources read - * @return _MALI_OSK_ERR_OK on success. _MALI_OSK_ERR_NOMEM on allocation - * error. For other failures, a suitable _mali_osk_errcode_t is returned. - */ -_mali_osk_errcode_t _mali_osk_resources_init( _mali_osk_resource_t **arch_config, u32 *num_resources ); - -/** @brief Free resources allocated by _mali_osk_resources_init. - * - * Frees the _mali_arch_resource_t array allocated by _mali_osk_resources_init - * - * @param arch_config a pointer to the stored the pointer to the resources - * @param num_resources the number of resources in the array - */ -void _mali_osk_resources_term( _mali_osk_resource_t **arch_config, u32 num_resources); -/** @} */ /* end group _mali_osk_miscellaneous */ - -/** @addtogroup _mali_osk_low_level_memory - * @{ */ - -/** @brief Initialize a user-space accessible memory range - * - * This initializes a virtual address range such that it is reserved for the - * current process, but does not map any physical pages into this range. - * - * This function may initialize or adjust any members of the - * mali_memory_allocation \a descriptor supplied, before the physical pages are - * mapped in with _mali_osk_mem_mapregion_map(). - * - * The function will always be called with MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE - * set in \a descriptor->flags. It is an error to call this function without - * setting this flag. Otherwise, \a descriptor->flags bits are reserved for - * future expansion - * - * The \a descriptor's process_addr_mapping_info member can be modified to - * allocate OS-specific information. Note that on input, this will be a - * ukk_private word from the U/K inteface, as inserted by _mali_ukk_mem_mmap(). - * This is used to pass information from the U/K interface to the OSK interface, - * if necessary. The precise usage of the process_addr_mapping_info member - * depends on the U/K implementation of _mali_ukk_mem_mmap(). - * - * Therefore, the U/K implementation of _mali_ukk_mem_mmap() and the OSK - * implementation of _mali_osk_mem_mapregion_init() must agree on the meaning and - * usage of the ukk_private word and process_addr_mapping_info member. - * - * Refer to \ref u_k_api for more information on the U/K interface. - * - * On successful return, \a descriptor's mapping member will be correct for - * use with _mali_osk_mem_mapregion_term() and _mali_osk_mem_mapregion_map(). - * - * @param descriptor the mali_memory_allocation to initialize. - */ -_mali_osk_errcode_t _mali_osk_mem_mapregion_init( mali_memory_allocation * descriptor ); - -/** @brief Terminate a user-space accessible memory range - * - * This terminates a virtual address range reserved in the current user process, - * where none, some or all of the virtual address ranges have mappings to - * physical pages. - * - * It will unmap any physical pages that had been mapped into a reserved - * virtual address range for the current process, and then releases the virtual - * address range. Any extra book-keeping information or resources allocated - * during _mali_osk_mem_mapregion_init() will also be released. - * - * The \a descriptor itself is not freed - this must be handled by the caller of - * _mali_osk_mem_mapregion_term(). - * - * The function will always be called with MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE - * set in descriptor->flags. It is an error to call this function without - * setting this flag. Otherwise, descriptor->flags bits are reserved for - * future expansion - * - * @param descriptor the mali_memory_allocation to terminate. - */ -void _mali_osk_mem_mapregion_term( mali_memory_allocation * descriptor ); - -/** @brief Map physical pages into a user process's virtual address range - * - * This is used to map a number of physically contigous pages into a - * user-process's virtual address range, which was previously reserved by a - * call to _mali_osk_mem_mapregion_init(). - * - * This need not provide a mapping for the entire virtual address range - * reserved for \a descriptor - it may be used to map single pages per call. - * - * The function will always be called with MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE - * set in \a descriptor->flags. It is an error to call this function without - * setting this flag. Otherwise, \a descriptor->flags bits are reserved for - * future expansion - * - * The function may supply \a *phys_addr == \ref MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC. - * In this case, \a size must be set to \ref _MALI_OSK_CPU_PAGE_SIZE, and the function - * will allocate the physical page itself. The physical address of the - * allocated page will be returned through \a phys_addr. - * - * It is an error to set \a size != \ref _MALI_OSK_CPU_PAGE_SIZE while - * \a *phys_addr == \ref MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC, - * since it is not always possible for OSs to support such a setting through this - * interface. - * - * @note \b IMPORTANT: This code must validate the input parameters. If the - * range defined by \a offset and \a size is outside the range allocated in - * \a descriptor, then this function \b MUST not attempt any mapping, and must - * instead return a suitable \ref _mali_osk_errcode_t \b failure code. - * - * @param[in,out] descriptor the mali_memory_allocation representing the - * user-process's virtual address range to map into. - * - * @param[in] offset the offset into the virtual address range. This is only added - * to the mapping member of the \a descriptor, and not the \a phys_addr parameter. - * It must be a multiple of \ref _MALI_OSK_CPU_PAGE_SIZE. - * - * @param[in,out] phys_addr a pointer to the physical base address to begin the - * mapping from. If \a size == \ref _MALI_OSK_CPU_PAGE_SIZE and - * \a *phys_addr == \ref MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC, then this - * function will allocate the physical page itself, and return the - * physical address of the page through \a phys_addr, which will be aligned to - * \ref _MALI_OSK_CPU_PAGE_SIZE. Otherwise, \a *phys_addr must be aligned to - * \ref _MALI_OSK_CPU_PAGE_SIZE, and is unmodified after the call. - * \a phys_addr is unaffected by the \a offset parameter. - * - * @param[in] size the number of bytes to map in. This must be a multiple of - * \ref _MALI_OSK_CPU_PAGE_SIZE. - * - * @return _MALI_OSK_ERR_OK on sucess, otherwise a _mali_osk_errcode_t value - * on failure - * - * @note could expand to use _mali_osk_mem_mapregion_flags_t instead of - * \ref MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC, but note that we must - * also modify the mali process address manager in the mmu/memory engine code. - */ -_mali_osk_errcode_t _mali_osk_mem_mapregion_map( mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size ); - - -/** @brief Unmap physical pages from a user process's virtual address range - * - * This is used to unmap a number of physically contigous pages from a - * user-process's virtual address range, which were previously mapped by a - * call to _mali_osk_mem_mapregion_map(). If the range specified was allocated - * from OS memory, then that memory will be returned to the OS. Whilst pages - * will be mapped out, the Virtual address range remains reserved, and at the - * same base address. - * - * When this function is used to unmap pages from OS memory - * (_mali_osk_mem_mapregion_map() was called with *phys_addr == - * \ref MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC), then the \a flags must - * include \ref _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR. This is because - * it is not always easy for an OS implementation to discover whether the - * memory was OS allocated or not (and so, how it should release the memory). - * - * For this reason, only a range of pages of the same allocation type (all OS - * allocated, or none OS allocacted) may be unmapped in one call. Multiple - * calls must be made if allocations of these different types exist across the - * entire region described by the \a descriptor. - * - * The function will always be called with MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE - * set in \a descriptor->flags. It is an error to call this function without - * setting this flag. Otherwise, \a descriptor->flags bits are reserved for - * future expansion - * - * @param[in,out] descriptor the mali_memory_allocation representing the - * user-process's virtual address range to map into. - * - * @param[in] offset the offset into the virtual address range. This is only added - * to the mapping member of the \a descriptor. \a offset must be a multiple of - * \ref _MALI_OSK_CPU_PAGE_SIZE. - * - * @param[in] size the number of bytes to unmap. This must be a multiple of - * \ref _MALI_OSK_CPU_PAGE_SIZE. - * - * @param[in] flags specifies how the memory should be unmapped. For a range - * of pages that were originally OS allocated, this must have - * \ref _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR set. - */ -void _mali_osk_mem_mapregion_unmap( mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t flags ); -/** @} */ /* end group _mali_osk_low_level_memory */ - - -#ifdef __cplusplus -} -#endif - -#endif /* __MALI_OSK_MALI_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_osk_profiling.h b/drivers/media/video/samsung/mali/common/mali_osk_profiling.h deleted file mode 100644 index fd9a8fb..0000000 --- a/drivers/media/video/samsung/mali/common/mali_osk_profiling.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_OSK_PROFILING_H__ -#define __MALI_OSK_PROFILING_H__ - -#if MALI_TIMELINE_PROFILING_ENABLED - -#if defined (CONFIG_TRACEPOINTS) && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED -#include "mali_linux_trace.h" -#endif /* CONFIG_TRACEPOINTS && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED */ - -#include "mali_profiling_events.h" - -#define MALI_PROFILING_MAX_BUFFER_ENTRIES 1048576 - -#define MALI_PROFILING_NO_HW_COUNTER = ((u32)-1) - -/** @defgroup _mali_osk_profiling External profiling connectivity - * @{ */ - -/** - * Initialize the profiling module. - * @return _MALI_OSK_ERR_OK on success, otherwise failure. - */ -_mali_osk_errcode_t _mali_osk_profiling_init(mali_bool auto_start); - -/* - * Terminate the profiling module. - */ -void _mali_osk_profiling_term(void); - -/** - * Start recording profiling data - * - * The specified limit will determine how large the capture buffer is. - * MALI_PROFILING_MAX_BUFFER_ENTRIES determines the maximum size allowed by the device driver. - * - * @param limit The desired maximum number of events to record on input, the actual maximum on output. - * @return _MALI_OSK_ERR_OK on success, otherwise failure. - */ -_mali_osk_errcode_t _mali_osk_profiling_start(u32 * limit); - -/** - * Add an profiling event - * - * @param event_id The event identificator. - * @param data0 First data parameter, depending on event_id specified. - * @param data1 Second data parameter, depending on event_id specified. - * @param data2 Third data parameter, depending on event_id specified. - * @param data3 Fourth data parameter, depending on event_id specified. - * @param data4 Fifth data parameter, depending on event_id specified. - * @return _MALI_OSK_ERR_OK on success, otherwise failure. - */ -#if defined (CONFIG_TRACEPOINTS) && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED -/* Call Linux tracepoint directly */ -#define _mali_osk_profiling_add_event(event_id, data0, data1, data2, data3, data4) trace_mali_timeline_event((event_id), (data0), (data1), (data2), (data3), (data4)) -#else -/* Internal profiling is handled like a plain function call */ -void _mali_osk_profiling_add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4); -#endif - -/** - * Report a hardware counter event. - * - * @param counter_id The ID of the counter. - * @param value The value of the counter. - */ - -#if defined (CONFIG_TRACEPOINTS) && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED -/* Call Linux tracepoint directly */ -#define _mali_osk_profiling_report_hw_counter(counter_id, value) trace_mali_hw_counter(counter_id, value) -#else -/* Internal profiling is handled like a plain function call */ -void _mali_osk_profiling_report_hw_counter(u32 counter_id, u32 value); -#endif - -/** - * Report SW counters - * - * @param counters array of counter values - */ -void _mali_osk_profiling_report_sw_counters(u32 *counters); - -/** - * Stop recording profiling data - * - * @param count Returns the number of recorded events. - * @return _MALI_OSK_ERR_OK on success, otherwise failure. - */ -_mali_osk_errcode_t _mali_osk_profiling_stop(u32 * count); - -/** - * Retrieves the number of events that can be retrieved - * - * @return The number of recorded events that can be retrieved. - */ -u32 _mali_osk_profiling_get_count(void); - -/** - * Retrieve an event - * - * @param index Event index (start with 0 and continue until this function fails to retrieve all events) - * @param timestamp The timestamp for the retrieved event will be stored here. - * @param event_id The event ID for the retrieved event will be stored here. - * @param data The 5 data values for the retrieved event will be stored here. - * @return _MALI_OSK_ERR_OK on success, otherwise failure. - */ -_mali_osk_errcode_t _mali_osk_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5]); - -/** - * Clear the recorded buffer. - * - * This is needed in order to start another recording. - * - * @return _MALI_OSK_ERR_OK on success, otherwise failure. - */ -_mali_osk_errcode_t _mali_osk_profiling_clear(void); - -/** - * Checks if a recording of profiling data is in progress - * - * @return MALI_TRUE if recording of profiling data is in progress, MALI_FALSE if not - */ -mali_bool _mali_osk_profiling_is_recording(void); - -/** - * Checks if profiling data is available for retrival - * - * @return MALI_TRUE if profiling data is avaiable, MALI_FALSE if not - */ -mali_bool _mali_osk_profiling_have_recording(void); - -/** @} */ /* end group _mali_osk_profiling */ - -#endif /* MALI_TIMELINE_PROFILING_ENABLED */ - -#endif /* __MALI_OSK_PROFILING_H__ */ - - diff --git a/drivers/media/video/samsung/mali/common/mali_pm.c b/drivers/media/video/samsung/mali/common/mali_pm.c deleted file mode 100644 index 933e54e..0000000 --- a/drivers/media/video/samsung/mali/common/mali_pm.c +++ /dev/null @@ -1,552 +0,0 @@ -/* - * Copyright (C) 2011-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_pm.h" -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "mali_gp_scheduler.h" -#include "mali_pp_scheduler.h" -#include "mali_platform.h" -#include "mali_kernel_utilization.h" -#include "mali_kernel_core.h" -#include "mali_group.h" - -#define MALI_PM_LIGHT_SLEEP_TIMEOUT 1000 - -enum mali_pm_scheme -{ - MALI_PM_SCHEME_DYNAMIC, - MALI_PM_SCHEME_OS_SUSPENDED, - MALI_PM_SCHEME_ALWAYS_ON -}; - -enum mali_pm_level -{ - MALI_PM_LEVEL_1_ON, - MALI_PM_LEVEL_2_STANDBY, - MALI_PM_LEVEL_3_LIGHT_SLEEP, - MALI_PM_LEVEL_4_DEEP_SLEEP -}; -static _mali_osk_lock_t *mali_pm_lock_set_next_state; -static _mali_osk_lock_t *mali_pm_lock_set_core_states; -static _mali_osk_lock_t *mali_pm_lock_execute_state_change; -static _mali_osk_irq_t *wq_irq; - -static _mali_osk_timer_t *idle_timer = NULL; -static mali_bool idle_timer_running = MALI_FALSE; -static u32 mali_pm_event_number = 0; - -static u32 num_active_gps = 0; -static u32 num_active_pps = 0; - -static enum mali_pm_scheme current_scheme = MALI_PM_SCHEME_DYNAMIC; -static enum mali_pm_level current_level = MALI_PM_LEVEL_1_ON; -static enum mali_pm_level next_level_dynamic = MALI_PM_LEVEL_2_STANDBY; /* Should be the state we go to when we go out of MALI_PM_SCHEME_ALWAYS_ON during init */ - - - -static _mali_osk_errcode_t mali_pm_upper_half(void *data); -static void mali_pm_bottom_half(void *data); -static void mali_pm_powerup(void); -static void mali_pm_powerdown(mali_power_mode power_mode); - -static void timeout_light_sleep(void* arg); -#if 0 -/* Deep sleep timout not supported */ -static void timeout_deep_sleep(void* arg); -#endif -static u32 mali_pm_event_number_get(void); -static void mali_pm_event(enum mali_pm_event pm_event, mali_bool schedule_work, u32 timer_time ); - -_mali_osk_errcode_t mali_pm_initialize(void) -{ - mali_pm_lock_execute_state_change = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_ORDERED |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_PM_EXECUTE); - - if (NULL != mali_pm_lock_execute_state_change ) - { - mali_pm_lock_set_next_state = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ONELOCK| _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_LAST); - - if (NULL != mali_pm_lock_set_next_state) - { - mali_pm_lock_set_core_states = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_PM_CORE_STATE); - - if (NULL != mali_pm_lock_set_core_states) - { - idle_timer = _mali_osk_timer_init(); - if (NULL != idle_timer) - { - wq_irq = _mali_osk_irq_init(_MALI_OSK_IRQ_NUMBER_PMM, - mali_pm_upper_half, - mali_pm_bottom_half, - NULL, - NULL, - (void *)NULL, - "Mali PM deferred work"); - if (NULL != wq_irq) - { - if (_MALI_OSK_ERR_OK == mali_platform_init()) - { -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON - _mali_osk_pm_dev_enable(); - mali_pm_powerup(); -#endif - return _MALI_OSK_ERR_OK; - } - - _mali_osk_irq_term(wq_irq); - } - - _mali_osk_timer_del(idle_timer); - _mali_osk_timer_term(idle_timer); - } - _mali_osk_lock_term(mali_pm_lock_set_core_states); - } - _mali_osk_lock_term(mali_pm_lock_set_next_state); - } - _mali_osk_lock_term(mali_pm_lock_execute_state_change); - } - - return _MALI_OSK_ERR_FAULT; -} - -void mali_pm_terminate(void) -{ - mali_platform_deinit(); - _mali_osk_irq_term(wq_irq); - _mali_osk_timer_del(idle_timer); - _mali_osk_timer_term(idle_timer); - _mali_osk_lock_term(mali_pm_lock_execute_state_change); - _mali_osk_lock_term(mali_pm_lock_set_next_state); - _mali_osk_lock_term(mali_pm_lock_set_core_states); -} - - -inline void mali_pm_lock(void) -{ - _mali_osk_lock_wait(mali_pm_lock_set_next_state, _MALI_OSK_LOCKMODE_RW); -} - -inline void mali_pm_unlock(void) -{ - _mali_osk_lock_signal(mali_pm_lock_set_next_state, _MALI_OSK_LOCKMODE_RW); -} - -inline void mali_pm_execute_state_change_lock(void) -{ - _mali_osk_lock_wait(mali_pm_lock_execute_state_change,_MALI_OSK_LOCKMODE_RW); -} - -inline void mali_pm_execute_state_change_unlock(void) -{ - _mali_osk_lock_signal(mali_pm_lock_execute_state_change, _MALI_OSK_LOCKMODE_RW); -} - -static void mali_pm_powerup(void) -{ -#if !MALI_PMM_RUNTIME_JOB_CONTROL_ON - MALI_DEBUG_PRINT(3, ("Mali PM: Setting GPU power mode to MALI_POWER_MODE_ON\n")); - mali_platform_power_mode_change(MALI_POWER_MODE_ON); -#else - /* Aquire our reference */ - _mali_osk_pm_dev_activate(); -#endif - mali_group_power_on(); -} - -static void mali_pm_powerdown(mali_power_mode power_mode) -{ - if ( (MALI_PM_LEVEL_1_ON == current_level) || (MALI_PM_LEVEL_2_STANDBY == current_level) ) - { - mali_group_power_off(); - } - -#if !MALI_PMM_RUNTIME_JOB_CONTROL_ON - mali_platform_power_mode_change(power_mode); -#else - _mali_osk_pm_dev_idle(); - - if (MALI_POWER_MODE_DEEP_SLEEP == power_mode) - { - mali_platform_power_mode_change(power_mode); - } -#endif -} - -mali_bool mali_pm_is_powered_on(void) -{ - mali_bool is_on = MALI_TRUE; - - if( ! (MALI_PM_SCHEME_ALWAYS_ON == current_scheme || MALI_PM_SCHEME_DYNAMIC == current_scheme) ) - { - is_on = MALI_FALSE; - } - else if ( ! (MALI_PM_LEVEL_1_ON == current_level || MALI_PM_LEVEL_2_STANDBY == current_level)) - { - is_on = MALI_FALSE; - } - else if ( ! (MALI_PM_LEVEL_1_ON == next_level_dynamic || MALI_PM_LEVEL_2_STANDBY == next_level_dynamic)) - { - is_on = MALI_FALSE; - } - - return is_on; -} - -MALI_DEBUG_CODE( -static const char *state_as_string(enum mali_pm_level level) -{ - switch(level) - { - case MALI_PM_LEVEL_1_ON: - return "MALI_PM_LEVEL_1_ON"; - case MALI_PM_LEVEL_2_STANDBY: - return "MALI_PM_LEVEL_2_STANDBY"; - case MALI_PM_LEVEL_3_LIGHT_SLEEP: - return "MALI_PM_LEVEL_3_LIGHT_SLEEP"; - case MALI_PM_LEVEL_4_DEEP_SLEEP: - return "MALI_PM_LEVEL_4_DEEP_SLEEP"; - default: - return "UNKNOWN LEVEL"; - } -}); - -/* This could be used from another thread (work queue), if we need that */ -static void mali_pm_process_next(void) -{ - enum mali_pm_level pm_level_to_set; - - _mali_osk_lock_wait(mali_pm_lock_execute_state_change, _MALI_OSK_LOCKMODE_RW); - - pm_level_to_set = current_level; - - if (MALI_PM_SCHEME_DYNAMIC == current_scheme) - { - pm_level_to_set = next_level_dynamic; - - MALI_DEBUG_PRINT(4, ("Mali PM: Dynamic scheme; Changing Mali GPU power state from %s to: %s\n", state_as_string(current_level), state_as_string(pm_level_to_set))); - - if (current_level == pm_level_to_set) - { - goto end_function; /* early out, no change in power level */ - } - - /* Start timers according to new state, so we get STANDBY -> LIGHT_SLEEP -> DEEP_SLEEP */ - - if (MALI_TRUE == idle_timer_running) - { - /* There is an existing timeout, so delete it */ - _mali_osk_timer_del(idle_timer); - idle_timer_running = MALI_FALSE; - } - - /* Making sure that we turn on through the platform file - Since it was turned OFF directly through the platform file. - This might lead to double turn-on, but the plaform file supports that.*/ - if ( current_level == MALI_PM_LEVEL_4_DEEP_SLEEP) - { - mali_pm_powerup(); - mali_kernel_core_wakeup(); - - } - if (MALI_PM_LEVEL_1_ON == pm_level_to_set) - { - if (MALI_PM_LEVEL_2_STANDBY != current_level) - { - /* We only need to do anything if we came from one of the sleeping states */ - mali_pm_powerup(); - - /* Wake up Mali cores since we came from a sleep state */ - mali_kernel_core_wakeup(); - } - } - else if (MALI_PM_LEVEL_2_STANDBY == pm_level_to_set) - { - /* This is just an internal state, so we don't bother to report it to the platform file */ - idle_timer_running = MALI_TRUE; - _mali_osk_timer_setcallback(idle_timer, timeout_light_sleep, (void*) mali_pm_event_number_get()); - _mali_osk_timer_add(idle_timer, _mali_osk_time_mstoticks(MALI_PM_LIGHT_SLEEP_TIMEOUT)); - } - else if (MALI_PM_LEVEL_3_LIGHT_SLEEP == pm_level_to_set) - { - mali_pm_powerdown(MALI_POWER_MODE_LIGHT_SLEEP); - } - else if (MALI_PM_LEVEL_4_DEEP_SLEEP == pm_level_to_set) - { - MALI_DEBUG_PRINT(2, ("Mali PM: Setting GPU power mode to MALI_POWER_MODE_DEEP_SLEEP\n")); - mali_pm_powerdown(MALI_POWER_MODE_DEEP_SLEEP); - } - } - else if (MALI_PM_SCHEME_OS_SUSPENDED == current_scheme) - { - MALI_DEBUG_PRINT(4, ("Mali PM: OS scheme; Changing Mali GPU power state from %s to: %s\n", state_as_string(current_level), state_as_string(MALI_PM_LEVEL_4_DEEP_SLEEP))); - - pm_level_to_set = MALI_PM_LEVEL_4_DEEP_SLEEP; - - if (current_level == pm_level_to_set) - { - goto end_function; /* early out, no change in power level */ - } - - /* Cancel any timers */ - if (MALI_TRUE == idle_timer_running) - { - /* There is an existing timeout, so delete it */ - _mali_osk_timer_del(idle_timer); - idle_timer_running = MALI_FALSE; - } - - MALI_DEBUG_PRINT(2, ("Mali PM: Setting GPU power mode to MALI_POWER_MODE_DEEP_SLEEP\n")); - mali_pm_powerdown(MALI_POWER_MODE_DEEP_SLEEP); - next_level_dynamic = current_level; - } - else if (MALI_PM_SCHEME_ALWAYS_ON == current_scheme) - { - MALI_DEBUG_PRINT(4, ("Mali PM: Always on scheme; Changing Mali GPU power state from %s to: %s\n", state_as_string(current_level), state_as_string(MALI_PM_LEVEL_1_ON))); - - pm_level_to_set = MALI_PM_LEVEL_1_ON; - if (current_level == pm_level_to_set) - { - goto end_function; /* early out, no change in power level */ - } - - MALI_DEBUG_PRINT(2, ("Mali PM: Setting GPU power mode to MALI_POWER_MODE_ON\n")); - mali_pm_powerup(); - if (MALI_PM_LEVEL_2_STANDBY != current_level) - { - /* Wake up Mali cores since we came from a sleep state */ - mali_kernel_core_wakeup(); - } - } - else - { - MALI_PRINT_ERROR(("MALI PM: Illegal scheme")); - } - - current_level = pm_level_to_set; - -end_function: - _mali_osk_lock_signal(mali_pm_lock_execute_state_change, _MALI_OSK_LOCKMODE_RW); - -} - -void mali_pm_always_on(mali_bool enable) -{ - if (MALI_TRUE == enable) - { - /* The event is processed in current thread synchronously */ - mali_pm_event(MALI_PM_EVENT_SCHEME_ALWAYS_ON, MALI_FALSE, 0 ); - } - else - { - /* The event is processed in current thread synchronously */ - mali_pm_event(MALI_PM_EVENT_SCHEME_DYNAMIC_CONTROLL, MALI_FALSE, 0 ); - } -} - -static _mali_osk_errcode_t mali_pm_upper_half(void *data) -{ - /* not used */ - return _MALI_OSK_ERR_OK; -} - -static void mali_pm_bottom_half(void *data) -{ - mali_pm_process_next(); -} - -static u32 mali_pm_event_number_get(void) -{ - u32 retval; - - mali_pm_lock(); /* spinlock: mali_pm_lock_set_next_state */ - retval = ++mali_pm_event_number; - if (0==retval ) retval = ++mali_pm_event_number; - mali_pm_unlock(); - - return retval; -} - -static void mali_pm_event(enum mali_pm_event pm_event, mali_bool schedule_work, u32 timer_time ) -{ - mali_pm_lock(); /* spinlock: mali_pm_lock_set_next_state */ - /* Only timer events should set this variable, all other events must set it to zero. */ - if ( 0 != timer_time ) - { - MALI_DEBUG_ASSERT( (pm_event==MALI_PM_EVENT_TIMER_LIGHT_SLEEP) || (pm_event==MALI_PM_EVENT_TIMER_DEEP_SLEEP) ); - if ( mali_pm_event_number != timer_time ) - { - /* In this case there have been processed newer events since the timer event was set up. - If so we always ignore the timing event */ - mali_pm_unlock(); - return; - } - } - else - { - /* Delete possible ongoing timers - if ( (MALI_PM_LEVEL_2_STANDBY==current_level) || (MALI_PM_LEVEL_3_LIGHT_SLEEP==current_level) ) - { - _mali_osk_timer_del(idle_timer); - } - */ - } - mali_pm_event_number++; - switch (pm_event) - { - case MALI_PM_EVENT_CORES_WORKING: - next_level_dynamic = MALI_PM_LEVEL_1_ON; - MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme ); - break; - case MALI_PM_EVENT_CORES_IDLE: - next_level_dynamic = MALI_PM_LEVEL_2_STANDBY; - /*MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme );*/ - break; - case MALI_PM_EVENT_TIMER_LIGHT_SLEEP: - MALI_DEBUG_ASSERT( MALI_PM_SCHEME_ALWAYS_ON != current_scheme ); - MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme ); - next_level_dynamic = MALI_PM_LEVEL_3_LIGHT_SLEEP; - break; - case MALI_PM_EVENT_TIMER_DEEP_SLEEP: - MALI_DEBUG_ASSERT( MALI_PM_SCHEME_ALWAYS_ON != current_scheme ); - MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme ); - next_level_dynamic = MALI_PM_LEVEL_4_DEEP_SLEEP; - break; - case MALI_PM_EVENT_OS_SUSPEND: - MALI_DEBUG_ASSERT( MALI_PM_SCHEME_ALWAYS_ON != current_scheme ); - MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme ); - current_scheme = MALI_PM_SCHEME_OS_SUSPENDED; - next_level_dynamic = MALI_PM_LEVEL_4_DEEP_SLEEP; /* Dynamic scheme will go into level when we are resumed */ - break; - case MALI_PM_EVENT_OS_RESUME: - MALI_DEBUG_ASSERT(MALI_PM_SCHEME_OS_SUSPENDED == current_scheme ); - current_scheme = MALI_PM_SCHEME_DYNAMIC; - break; - case MALI_PM_EVENT_SCHEME_ALWAYS_ON: - MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme ); - current_scheme = MALI_PM_SCHEME_ALWAYS_ON; - break; - case MALI_PM_EVENT_SCHEME_DYNAMIC_CONTROLL: - MALI_DEBUG_ASSERT( MALI_PM_SCHEME_ALWAYS_ON == current_scheme || MALI_PM_SCHEME_DYNAMIC == current_scheme ); - current_scheme = MALI_PM_SCHEME_DYNAMIC; - break; - default: - MALI_DEBUG_PRINT_ERROR(("Unknown next state.")); - mali_pm_unlock(); - return; - } - mali_pm_unlock(); - - if (MALI_TRUE == schedule_work) - { - _mali_osk_irq_schedulework(wq_irq); - } - else - { - mali_pm_process_next(); - } -} - -static void timeout_light_sleep(void* arg) -{ - /* State change only if no newer power events have happend from the time in arg. - Actual work will be scheduled on worker thread. */ - mali_pm_event(MALI_PM_EVENT_TIMER_LIGHT_SLEEP, MALI_TRUE, (u32) arg); -} - -void mali_pm_core_event(enum mali_core_event core_event) -{ - mali_bool transition_working = MALI_FALSE; - mali_bool transition_idle = MALI_FALSE; - - _mali_osk_lock_wait(mali_pm_lock_set_core_states, _MALI_OSK_LOCKMODE_RW); - - switch (core_event) - { - case MALI_CORE_EVENT_GP_START: - if (num_active_pps + num_active_gps == 0) - { - transition_working = MALI_TRUE; - } - num_active_gps++; - break; - case MALI_CORE_EVENT_GP_STOP: - if (num_active_pps + num_active_gps == 1) - { - transition_idle = MALI_TRUE; - } - num_active_gps--; - break; - case MALI_CORE_EVENT_PP_START: - if (num_active_pps + num_active_gps == 0) - { - transition_working = MALI_TRUE; - } - num_active_pps++; - break; - case MALI_CORE_EVENT_PP_STOP: - if (num_active_pps + num_active_gps == 1) - { - transition_idle = MALI_TRUE; - } - num_active_pps--; - break; - } - - if (transition_working == MALI_TRUE) - { -#ifdef CONFIG_MALI400_GPU_UTILIZATION - mali_utilization_core_start(_mali_osk_time_get_ns()); -#endif - mali_pm_event(MALI_PM_EVENT_CORES_WORKING, MALI_FALSE, 0); /* process event in same thread */ - } - else if (transition_idle == MALI_TRUE) - { -#ifdef CONFIG_MALI400_GPU_UTILIZATION - mali_utilization_core_end(_mali_osk_time_get_ns()); -#endif - mali_pm_event(MALI_PM_EVENT_CORES_IDLE, MALI_FALSE, 0); /* process event in same thread */ - } - - _mali_osk_lock_signal(mali_pm_lock_set_core_states, _MALI_OSK_LOCKMODE_RW); -} - -void mali_pm_os_suspend(void) -{ - MALI_DEBUG_PRINT(2, ("Mali PM: OS suspending...\n")); - - mali_gp_scheduler_suspend(); - mali_pp_scheduler_suspend(); - mali_pm_event(MALI_PM_EVENT_OS_SUSPEND, MALI_FALSE, 0); /* process event in same thread */ - - MALI_DEBUG_PRINT(2, ("Mali PM: OS suspend completed\n")); -} - -void mali_pm_os_resume(void) -{ - MALI_DEBUG_PRINT(2, ("Mali PM: OS resuming...\n")); - - mali_pm_event(MALI_PM_EVENT_OS_RESUME, MALI_FALSE, 0); /* process event in same thread */ - mali_gp_scheduler_resume(); - mali_pp_scheduler_resume(); - - MALI_DEBUG_PRINT(2, ("Mali PM: OS resume completed\n")); -} - -void mali_pm_runtime_suspend(void) -{ - MALI_DEBUG_PRINT(2, ("Mali PM: OS runtime suspended\n")); - mali_platform_power_mode_change(MALI_POWER_MODE_LIGHT_SLEEP); -} - -void mali_pm_runtime_resume(void) -{ - MALI_DEBUG_PRINT(2, ("Mali PM: OS runtime resumed\n")); - mali_platform_power_mode_change(MALI_POWER_MODE_ON); -} diff --git a/drivers/media/video/samsung/mali/common/mali_pm.h b/drivers/media/video/samsung/mali/common/mali_pm.h deleted file mode 100644 index d4ccfde..0000000 --- a/drivers/media/video/samsung/mali/common/mali_pm.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2011-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_PM_H__ -#define __MALI_PM_H__ - -#include "mali_osk.h" - -enum mali_core_event -{ - MALI_CORE_EVENT_GP_START, - MALI_CORE_EVENT_GP_STOP, - MALI_CORE_EVENT_PP_START, - MALI_CORE_EVENT_PP_STOP -}; - -enum mali_pm_event -{ - MALI_PM_EVENT_CORES_WORKING, - MALI_PM_EVENT_CORES_IDLE, - MALI_PM_EVENT_TIMER_LIGHT_SLEEP, - MALI_PM_EVENT_TIMER_DEEP_SLEEP, - MALI_PM_EVENT_OS_SUSPEND, - MALI_PM_EVENT_OS_RESUME, - MALI_PM_EVENT_SCHEME_ALWAYS_ON, - MALI_PM_EVENT_SCHEME_DYNAMIC_CONTROLL, -}; - -_mali_osk_errcode_t mali_pm_initialize(void); -void mali_pm_terminate(void); -void mali_pm_always_on(mali_bool enable); - -void mali_pm_lock(void); -void mali_pm_unlock(void); -void mali_pm_execute_state_change_lock(void); - -void mali_pm_execute_state_change_unlock(void); - -mali_bool mali_pm_is_powered_on(void); - -void mali_pm_core_event(enum mali_core_event core_event); - -void mali_pm_os_suspend(void); -void mali_pm_os_resume(void); -void mali_pm_runtime_suspend(void); -void mali_pm_runtime_resume(void); - - -#endif /* __MALI_PM_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_pmu.c b/drivers/media/video/samsung/mali/common/mali_pmu.c deleted file mode 100644 index 348b5dc..0000000 --- a/drivers/media/video/samsung/mali/common/mali_pmu.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_pmu.c - * Mali driver functions for Mali 400 PMU hardware - */ -#include "mali_hw_core.h" -#include "mali_pmu.h" -#include "mali_pp.h" -#include "mali_kernel_common.h" -#include "mali_osk.h" - -static u32 mali_pmu_detect_mask(u32 number_of_pp_cores, u32 number_of_l2_caches); - -/** @brief MALI inbuilt PMU hardware info and PMU hardware has knowledge of cores power mask - */ -struct mali_pmu_core -{ - struct mali_hw_core hw_core; - u32 mali_registered_cores_power_mask; -}; - -static struct mali_pmu_core *mali_global_pmu_core = NULL; - -/** @brief Register layout for hardware PMU - */ -typedef enum { - PMU_REG_ADDR_MGMT_POWER_UP = 0x00, /*< Power up register */ - PMU_REG_ADDR_MGMT_POWER_DOWN = 0x04, /*< Power down register */ - PMU_REG_ADDR_MGMT_STATUS = 0x08, /*< Core sleep status register */ - PMU_REG_ADDR_MGMT_INT_MASK = 0x0C, /*< Interrupt mask register */ - PMU_REGISTER_ADDRESS_SPACE_SIZE = 0x10, /*< Size of register space */ -} pmu_reg_addr_mgmt_addr; - -struct mali_pmu_core *mali_pmu_create(_mali_osk_resource_t *resource, u32 number_of_pp_cores, u32 number_of_l2_caches) -{ - struct mali_pmu_core* pmu; - - MALI_DEBUG_ASSERT(NULL == mali_global_pmu_core); - MALI_DEBUG_PRINT(2, ("Mali PMU: Creating Mali PMU core\n")); - - pmu = (struct mali_pmu_core *)_mali_osk_malloc(sizeof(struct mali_pmu_core)); - if (NULL != pmu) - { - pmu->mali_registered_cores_power_mask = mali_pmu_detect_mask(number_of_pp_cores, number_of_l2_caches); - if (_MALI_OSK_ERR_OK == mali_hw_core_create(&pmu->hw_core, resource, PMU_REGISTER_ADDRESS_SPACE_SIZE)) - { - if (_MALI_OSK_ERR_OK == mali_pmu_reset(pmu)) - { - mali_global_pmu_core = pmu; - return pmu; - } - mali_hw_core_delete(&pmu->hw_core); - } - _mali_osk_free(pmu); - } - - return NULL; -} - -void mali_pmu_delete(struct mali_pmu_core *pmu) -{ - MALI_DEBUG_ASSERT_POINTER(pmu); - - mali_hw_core_delete(&pmu->hw_core); - _mali_osk_free(pmu); - pmu = NULL; -} - -_mali_osk_errcode_t mali_pmu_reset(struct mali_pmu_core *pmu) -{ - /* Don't use interrupts - just poll status */ - mali_hw_core_register_write(&pmu->hw_core, PMU_REG_ADDR_MGMT_INT_MASK, 0); - return _MALI_OSK_ERR_OK; -} - -_mali_osk_errcode_t mali_pmu_powerdown_all(struct mali_pmu_core *pmu) -{ - u32 stat; - u32 timeout; - - MALI_DEBUG_ASSERT_POINTER(pmu); - MALI_DEBUG_ASSERT( pmu->mali_registered_cores_power_mask != 0 ); - MALI_DEBUG_PRINT( 4, ("Mali PMU: power down (0x%08X)\n", pmu->mali_registered_cores_power_mask) ); - - mali_hw_core_register_write(&pmu->hw_core, PMU_REG_ADDR_MGMT_POWER_DOWN, pmu->mali_registered_cores_power_mask); - - /* Wait for cores to be powered down (100 x 100us = 100ms) */ - timeout = 100; - do - { - /* Get status of sleeping cores */ - stat = mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_STATUS); - stat &= pmu->mali_registered_cores_power_mask; - if( stat == pmu->mali_registered_cores_power_mask ) break; /* All cores we wanted are now asleep */ - _mali_osk_time_ubusydelay(100); - timeout--; - } while( timeout > 0 ); - - if( timeout == 0 ) - { - return _MALI_OSK_ERR_TIMEOUT; - } - - return _MALI_OSK_ERR_OK; -} - -_mali_osk_errcode_t mali_pmu_powerup_all(struct mali_pmu_core *pmu) -{ - u32 stat; - u32 timeout; - - MALI_DEBUG_ASSERT_POINTER(pmu); - MALI_DEBUG_ASSERT( pmu->mali_registered_cores_power_mask != 0 ); /* Shouldn't be zero */ - MALI_DEBUG_PRINT( 4, ("Mali PMU: power up (0x%08X)\n", pmu->mali_registered_cores_power_mask) ); - - mali_hw_core_register_write(&pmu->hw_core, PMU_REG_ADDR_MGMT_POWER_UP, pmu->mali_registered_cores_power_mask); - - /* Wait for cores to be powered up (100 x 100us = 100ms) */ - timeout = 100; - do - { - /* Get status of sleeping cores */ - stat = mali_hw_core_register_read(&pmu->hw_core,PMU_REG_ADDR_MGMT_STATUS); - stat &= pmu->mali_registered_cores_power_mask; - if( stat == 0 ) break; /* All cores we wanted are now awake */ - _mali_osk_time_ubusydelay(100); - timeout--; - } while( timeout > 0 ); - - if( timeout == 0 ) - { - return _MALI_OSK_ERR_TIMEOUT; - } - - return _MALI_OSK_ERR_OK; -} - -struct mali_pmu_core *mali_pmu_get_global_pmu_core(void) -{ - return mali_global_pmu_core; -} - -static u32 mali_pmu_detect_mask(u32 number_of_pp_cores, u32 number_of_l2_caches) -{ - u32 mask = 0; - - if (number_of_l2_caches == 1) - { - /* Mali-300 or Mali-400 */ - u32 i; - - /* GP */ - mask = 0x01; - - /* L2 cache */ - mask |= 0x01<<1; - - /* Set bit for each PP core */ - for (i = 0; i < number_of_pp_cores; i++) - { - mask |= 0x01<<(i+2); - } - } - else if (number_of_l2_caches > 1) - { - /* Mali-450 */ - - /* GP (including its L2 cache) */ - mask = 0x01; - - /* There is always at least one PP (including its L2 cache) */ - mask |= 0x01<<1; - - /* Additional PP cores in same L2 cache */ - if (number_of_pp_cores >= 2) - { - mask |= 0x01<<2; - } - - /* Additional PP cores in a third L2 cache */ - if (number_of_pp_cores >= 5) - { - mask |= 0x01<<3; - } - } - - MALI_DEBUG_PRINT(4, ("Mali PMU: Power mask is 0x%08X (%u + %u)\n", mask, number_of_pp_cores, number_of_l2_caches)); - - return mask; -} diff --git a/drivers/media/video/samsung/mali/common/mali_pmu.h b/drivers/media/video/samsung/mali/common/mali_pmu.h deleted file mode 100644 index fd10c08..0000000 --- a/drivers/media/video/samsung/mali/common/mali_pmu.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_platform.h - * Platform specific Mali driver functions - */ - -#include "mali_osk.h" - -struct mali_pmu_core; - -/** @brief Initialisation of MALI PMU - * - * This is called from entry point of the driver in order to create and intialize the PMU resource - * - * @param resource it will be a pointer to a PMU resource - * @param number_of_pp_cores Number of found PP resources in configuration - * @param number_of_l2_caches Number of found L2 cache resources in configuration - * @return The created PMU object, or NULL in case of failure. - */ -struct mali_pmu_core *mali_pmu_create(_mali_osk_resource_t *resource, u32 number_of_pp_cores, u32 number_of_l2_caches); - -/** @brief It deallocates the PMU resource - * - * This is called on the exit of the driver to terminate the PMU resource - * - * @param pmu Pointer to PMU core object to delete - */ -void mali_pmu_delete(struct mali_pmu_core *pmu); - -/** @brief Reset PMU core - * - * @param pmu Pointer to PMU core object to reset - * @return _MALI_OSK_ERR_OK on success, otherwise failure. - */ -_mali_osk_errcode_t mali_pmu_reset(struct mali_pmu_core *pmu); - -/** @brief MALI GPU power down using MALI in-built PMU - * - * called to power down all cores - * - * @param pmu Pointer to PMU core object to power down - * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. - */ -_mali_osk_errcode_t mali_pmu_powerdown_all(struct mali_pmu_core *pmu); - - -/** @brief MALI GPU power up using MALI in-built PMU - * - * called to power up all cores - * - * @param pmu Pointer to PMU core object to power up - * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. - */ -_mali_osk_errcode_t mali_pmu_powerup_all(struct mali_pmu_core *pmu); - - -/** @brief Retrieves the Mali PMU core object (if any) - * - * @return The Mali PMU object, or NULL if no PMU exists. - */ -struct mali_pmu_core *mali_pmu_get_global_pmu_core(void); diff --git a/drivers/media/video/samsung/mali/common/mali_pp.c b/drivers/media/video/samsung/mali/common/mali_pp.c deleted file mode 100644 index 5549f82..0000000 --- a/drivers/media/video/samsung/mali/common/mali_pp.c +++ /dev/null @@ -1,710 +0,0 @@ -/* - * Copyright (C) 2011-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_pp.h" -#include "mali_hw_core.h" -#include "mali_group.h" -#include "mali_osk.h" -#include "regs/mali_200_regs.h" -#include "mali_kernel_common.h" -#include "mali_kernel_core.h" -#if MALI_TIMELINE_PROFILING_ENABLED -#include "mali_osk_profiling.h" -#endif - -/* See mali_gp.c file for description on how to handle the interrupt mask. - * This is how to do it on PP: mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED); - */ - -#define MALI_MAX_NUMBER_OF_PP_CORES 8 - -/** - * Definition of the PP core struct - * Used to track a PP core in the system. - */ -struct mali_pp_core -{ - struct mali_hw_core hw_core; /**< Common for all HW cores */ - struct mali_group *group; /**< Parent group for this core */ - _mali_osk_irq_t *irq; /**< IRQ handler */ - u32 core_id; /**< Unique core ID */ - struct mali_pp_job *running_job; /**< Current running (super) job */ - u32 running_sub_job; /**< Current running sub job */ - _mali_osk_timer_t *timeout_timer; /**< timeout timer for this core */ - u32 timeout_job_id; /**< job id for the timed out job - relevant only if pp_core_timed_out == MALI_TRUE */ - mali_bool core_timed_out; /**< if MALI_TRUE, this pp core has timed out; if MALI_FALSE, no timeout on this pp core */ - u32 counter_src0; /**< Performance counter 0, MALI_HW_CORE_NO_COUNTER for disabled */ - u32 counter_src1; /**< Performance counter 1, MALI_HW_CORE_NO_COUNTER for disabled */ - u32 counter_src0_used; /**< The selected performance counter 0 when a job is running */ - u32 counter_src1_used; /**< The selected performance counter 1 when a job is running */ -}; - -static struct mali_pp_core* mali_global_pp_cores[MALI_MAX_NUMBER_OF_PP_CORES]; -static u32 mali_global_num_pp_cores = 0; - -/* Interrupt handlers */ -static _mali_osk_errcode_t mali_pp_upper_half(void *data); -static void mali_pp_bottom_half(void *data); -static void mali_pp_irq_probe_trigger(void *data); -static _mali_osk_errcode_t mali_pp_irq_probe_ack(void *data); -static void mali_pp_post_process_job(struct mali_pp_core *core); -static void mali_pp_timeout(void *data); - -struct mali_pp_core *mali_pp_create(const _mali_osk_resource_t *resource, struct mali_group *group) -{ - struct mali_pp_core* core = NULL; - - MALI_DEBUG_PRINT(2, ("Mali PP: Creating Mali PP core: %s\n", resource->description)); - MALI_DEBUG_PRINT(2, ("Mali PP: Base address of PP core: 0x%x\n", resource->base)); - - if (mali_global_num_pp_cores >= MALI_MAX_NUMBER_OF_PP_CORES) - { - MALI_PRINT_ERROR(("Mali PP: Too many PP core objects created\n")); - return NULL; - } - - core = _mali_osk_malloc(sizeof(struct mali_pp_core)); - if (NULL != core) - { - core->group = group; - core->core_id = mali_global_num_pp_cores; - core->running_job = NULL; - core->counter_src0 = MALI_HW_CORE_NO_COUNTER; - core->counter_src1 = MALI_HW_CORE_NO_COUNTER; - core->counter_src0_used = MALI_HW_CORE_NO_COUNTER; - core->counter_src1_used = MALI_HW_CORE_NO_COUNTER; - if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALI200_REG_SIZEOF_REGISTER_BANK)) - { - _mali_osk_errcode_t ret; - - mali_group_lock(group); - ret = mali_pp_reset(core); - mali_group_unlock(group); - - if (_MALI_OSK_ERR_OK == ret) - { - /* Setup IRQ handlers (which will do IRQ probing if needed) */ - core->irq = _mali_osk_irq_init(resource->irq, - mali_pp_upper_half, - mali_pp_bottom_half, - mali_pp_irq_probe_trigger, - mali_pp_irq_probe_ack, - core, - "mali_pp_irq_handlers"); - if (NULL != core->irq) - { - /* Initialise the timeout timer */ - core->timeout_timer = _mali_osk_timer_init(); - if(NULL != core->timeout_timer) - { - _mali_osk_timer_setcallback(core->timeout_timer, mali_pp_timeout, (void *)core); - - mali_global_pp_cores[mali_global_num_pp_cores] = core; - mali_global_num_pp_cores++; - - return core; - } - else - { - MALI_PRINT_ERROR(("Failed to setup timeout timer for PP core %s\n", core->hw_core.description)); - /* Release IRQ handlers */ - _mali_osk_irq_term(core->irq); - } - } - else - { - MALI_PRINT_ERROR(("Mali PP: Failed to setup interrupt handlers for PP core %s\n", core->hw_core.description)); - } - } - mali_hw_core_delete(&core->hw_core); - } - - _mali_osk_free(core); - } - else - { - MALI_PRINT_ERROR(("Mali PP: Failed to allocate memory for PP core\n")); - } - - return NULL; -} - -void mali_pp_delete(struct mali_pp_core *core) -{ - u32 i; - - MALI_DEBUG_ASSERT_POINTER(core); - - _mali_osk_timer_term(core->timeout_timer); - _mali_osk_irq_term(core->irq); - mali_hw_core_delete(&core->hw_core); - - /* Remove core from global list */ - for (i = 0; i < mali_global_num_pp_cores; i++) - { - if (mali_global_pp_cores[i] == core) - { - mali_global_pp_cores[i] = NULL; - mali_global_num_pp_cores--; - break; - } - } - - _mali_osk_free(core); -} - -void mali_pp_stop_bus(struct mali_pp_core *core) -{ - MALI_DEBUG_ASSERT_POINTER(core); - /* Will only send the stop bus command, and not wait for it to complete */ - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_STOP_BUS); -} - -_mali_osk_errcode_t mali_pp_stop_bus_wait(struct mali_pp_core *core) -{ - int i; - const int request_loop_count = 20; - - MALI_DEBUG_ASSERT_POINTER(core); - MALI_ASSERT_GROUP_LOCKED(core->group); - - /* Send the stop bus command. */ - mali_pp_stop_bus(core); - - /* Wait for bus to be stopped */ - for (i = 0; i < request_loop_count; i++) - { - if (mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS) & MALI200_REG_VAL_STATUS_BUS_STOPPED) - break; - _mali_osk_time_ubusydelay(10); - } - - if (request_loop_count == i) - { - MALI_PRINT_ERROR(("Mali PP: Failed to stop bus on %s. Status: 0x%08x\n", core->hw_core.description, mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS))); - return _MALI_OSK_ERR_FAULT; - } - return _MALI_OSK_ERR_OK; -} - -_mali_osk_errcode_t mali_pp_hard_reset(struct mali_pp_core *core) -{ - /* Bus must be stopped before calling this function */ - const int reset_finished_loop_count = 15; - const u32 reset_invalid_value = 0xC0FFE000; - const u32 reset_check_value = 0xC01A0000; - int i; - - MALI_DEBUG_ASSERT_POINTER(core); - MALI_DEBUG_PRINT(2, ("Mali PP: Hard reset of core %s\n", core->hw_core.description)); - MALI_ASSERT_GROUP_LOCKED(core->group); - - mali_pp_post_process_job(core); /* @@@@ is there some cases where it is unsafe to post process the job here? */ - - /* Set register to a bogus value. The register will be used to detect when reset is complete */ - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, reset_invalid_value); - - /* Force core to reset */ - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_FORCE_RESET); - - /* Wait for reset to be complete */ - for (i = 0; i < reset_finished_loop_count; i++) - { - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, reset_check_value); - if (reset_check_value == mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW)) - { - break; - } - _mali_osk_time_ubusydelay(10); - } - - if (i == reset_finished_loop_count) - { - MALI_PRINT_ERROR(("Mali PP: The hard reset loop didn't work, unable to recover\n")); - } - - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, 0x00000000); /* set it back to the default */ - /* Re-enable interrupts */ - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL); - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED); - - return _MALI_OSK_ERR_OK; -} - -_mali_osk_errcode_t mali_pp_reset(struct mali_pp_core *core) -{ - int i; - const int request_loop_count = 20; - - MALI_DEBUG_ASSERT_POINTER(core); - MALI_DEBUG_PRINT(4, ("Mali PP: Reset of core %s\n", core->hw_core.description)); - MALI_ASSERT_GROUP_LOCKED(core->group); - - mali_pp_post_process_job(core); /* @@@@ is there some cases where it is unsafe to post process the job here? */ - - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, 0); /* disable the IRQs */ - -#if defined(USING_MALI200) - - /* On Mali-200, stop the bus, then do a hard reset of the core */ - - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_STOP_BUS); - - for (i = 0; i < request_loop_count; i++) - { - if (mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS) & MALI200_REG_VAL_STATUS_BUS_STOPPED) - { - break; - } - _mali_osk_time_ubusydelay(10); - } - - if (request_loop_count == i) - { - MALI_PRINT_ERROR(("Mali PP: Failed to stop bus for core %s, unable to recover\n", core->hw_core.description)); - return _MALI_OSK_ERR_FAULT ; - } - - /* the bus was stopped OK, do the hard reset */ - mali_pp_hard_reset(core); - -#elif defined(USING_MALI400) - - /* Mali-300 and Mali-400 have a safe reset command which we use */ - - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI400PP_REG_VAL_IRQ_RESET_COMPLETED); - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI400PP_REG_VAL_CTRL_MGMT_SOFT_RESET); - - for (i = 0; i < request_loop_count; i++) - { - if (mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT) & MALI400PP_REG_VAL_IRQ_RESET_COMPLETED) - { - break; - } - _mali_osk_time_ubusydelay(10); - } - - if (request_loop_count == i) - { - MALI_DEBUG_PRINT(2, ("Mali PP: Failed to reset core %s, Status: 0x%08x\n", core->hw_core.description, mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS))); - return _MALI_OSK_ERR_FAULT; - } -#else -#error "no supported mali core defined" -#endif - - /* Re-enable interrupts */ - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL); - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED); - - return _MALI_OSK_ERR_OK; -} - -void mali_pp_job_start(struct mali_pp_core *core, struct mali_pp_job *job, u32 sub_job) -{ - u32 *frame_registers = mali_pp_job_get_frame_registers(job); - u32 *wb0_registers = mali_pp_job_get_wb0_registers(job); - u32 *wb1_registers = mali_pp_job_get_wb1_registers(job); - u32 *wb2_registers = mali_pp_job_get_wb2_registers(job); - core->counter_src0_used = core->counter_src0; - core->counter_src1_used = core->counter_src1; - - MALI_DEBUG_ASSERT_POINTER(core); - MALI_ASSERT_GROUP_LOCKED(core->group); - - mali_hw_core_register_write_array_relaxed(&core->hw_core, MALI200_REG_ADDR_FRAME, frame_registers, MALI200_NUM_REGS_FRAME); - if (0 != sub_job) - { - /* - * There are two frame registers which are different for each sub job. - * For the first sub job, these are correctly represented in the frame register array, - * but we need to patch these for all other sub jobs - */ - mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_FRAME, mali_pp_job_get_addr_frame(job, sub_job)); - mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_STACK, mali_pp_job_get_addr_stack(job, sub_job)); - } - - if (wb0_registers[0]) /* M200_WB0_REG_SOURCE_SELECT register */ - { - mali_hw_core_register_write_array_relaxed(&core->hw_core, MALI200_REG_ADDR_WB0, wb0_registers, MALI200_NUM_REGS_WBx); - } - - if (wb1_registers[0]) /* M200_WB1_REG_SOURCE_SELECT register */ - { - mali_hw_core_register_write_array_relaxed(&core->hw_core, MALI200_REG_ADDR_WB1, wb1_registers, MALI200_NUM_REGS_WBx); - } - - if (wb2_registers[0]) /* M200_WB2_REG_SOURCE_SELECT register */ - { - mali_hw_core_register_write_array_relaxed(&core->hw_core, MALI200_REG_ADDR_WB2, wb2_registers, MALI200_NUM_REGS_WBx); - } - - /* This selects which performance counters we are reading */ - if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used || MALI_HW_CORE_NO_COUNTER != core->counter_src1_used) - { - /* global_config has enabled HW counters, this will override anything specified by user space */ - if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used) - { - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used); - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE); - } - if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used) - { - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used); - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE); - } - } - else - { - /* Use HW counters from job object, if any */ - u32 perf_counter_flag = mali_pp_job_get_perf_counter_flag(job); - if (0 != perf_counter_flag) - { - if (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE) - { - core->counter_src0_used = mali_pp_job_get_perf_counter_src0(job); - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used); - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE); - } - - if (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE) - { - core->counter_src1_used = mali_pp_job_get_perf_counter_src1(job); - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used); - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE); - } - } - } - - MALI_DEBUG_PRINT(3, ("Mali PP: Starting job 0x%08X part %u/%u on PP core %s\n", job, sub_job + 1, mali_pp_job_get_sub_job_count(job), core->hw_core.description)); - - /* Adding barrier to make sure all rester writes are finished */ - _mali_osk_write_mem_barrier(); - - /* This is the command that starts the core. */ - mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_START_RENDERING); - - /* Adding barrier to make sure previous rester writes is finished */ - _mali_osk_write_mem_barrier(); - - /* Setup the timeout timer value and save the job id for the job running on the pp core */ - _mali_osk_timer_add(core->timeout_timer, _mali_osk_time_mstoticks(mali_max_job_runtime)); - core->timeout_job_id = mali_pp_job_get_id(job); - -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_id) | MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH, job->frame_builder_id, job->flush_id, 0, 0, 0); - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_id), job->pid, job->tid, 0, 0, 0); -#endif - - core->running_job = job; - core->running_sub_job = sub_job; -} - -u32 mali_pp_core_get_version(struct mali_pp_core *core) -{ - MALI_DEBUG_ASSERT_POINTER(core); - return mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_VERSION); -} - -u32 mali_pp_core_get_id(struct mali_pp_core *core) -{ - MALI_DEBUG_ASSERT_POINTER(core); - return core->core_id; -} - -mali_bool mali_pp_core_set_counter_src0(struct mali_pp_core *core, u32 counter) -{ - MALI_DEBUG_ASSERT_POINTER(core); - - core->counter_src0 = counter; - return MALI_TRUE; -} - -mali_bool mali_pp_core_set_counter_src1(struct mali_pp_core *core, u32 counter) -{ - MALI_DEBUG_ASSERT_POINTER(core); - - core->counter_src1 = counter; - return MALI_TRUE; -} - -u32 mali_pp_core_get_counter_src0(struct mali_pp_core *core) -{ - MALI_DEBUG_ASSERT_POINTER(core); - return core->counter_src0; -} - -u32 mali_pp_core_get_counter_src1(struct mali_pp_core *core) -{ - MALI_DEBUG_ASSERT_POINTER(core); - return core->counter_src1; -} - -struct mali_pp_core* mali_pp_get_global_pp_core(u32 index) -{ - if (MALI_MAX_NUMBER_OF_PP_CORES > index) - { - return mali_global_pp_cores[index]; - } - - return NULL; -} - -u32 mali_pp_get_glob_num_pp_cores(void) -{ - return mali_global_num_pp_cores; -} - -u32 mali_pp_get_max_num_pp_cores(void) -{ - return MALI_MAX_NUMBER_OF_PP_CORES; -} - -/* ------------- interrupt handling below ------------------ */ -static _mali_osk_errcode_t mali_pp_upper_half(void *data) -{ - struct mali_pp_core *core = (struct mali_pp_core *)data; - u32 irq_readout; - - irq_readout = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_STATUS); - if (MALI200_REG_VAL_IRQ_MASK_NONE != irq_readout) - { - /* Mask out all IRQs from this core until IRQ is handled */ - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_NONE); - -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_id)|MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT, irq_readout, 0, 0, 0, 0); -#endif - - /* We do need to handle this in a bottom half */ - _mali_osk_irq_schedulework(core->irq); - return _MALI_OSK_ERR_OK; - } - - return _MALI_OSK_ERR_FAULT; -} - -static void mali_pp_bottom_half(void *data) -{ - struct mali_pp_core *core = (struct mali_pp_core *)data; - u32 irq_readout; - u32 irq_errors; - -#if MALI_TIMELINE_PROFILING_ENABLED -#if 0 /* Bottom half TLP logging is currently not supported */ - _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_START| MALI_PROFILING_EVENT_CHANNEL_SOFTWARE , _mali_osk_get_pid(), _mali_osk_get_tid(), 0, 0, 0); -#endif -#endif - - mali_group_lock(core->group); /* Group lock grabbed in core handlers, but released in common group handler */ - - if ( MALI_FALSE == mali_group_power_is_on(core->group) ) - { - MALI_PRINT_ERROR(("Interrupt bottom half of %s when core is OFF.", core->hw_core.description)); - mali_group_unlock(core->group); - return; - } - - irq_readout = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT) & MALI200_REG_VAL_IRQ_MASK_USED; - - MALI_DEBUG_PRINT(4, ("Mali PP: Bottom half IRQ 0x%08X from core %s\n", irq_readout, core->hw_core.description)); - - if (irq_readout & MALI200_REG_VAL_IRQ_END_OF_FRAME) - { - mali_pp_post_process_job(core); - MALI_DEBUG_PRINT(3, ("Mali PP: Job completed, calling group handler\n")); - mali_group_bottom_half(core->group, GROUP_EVENT_PP_JOB_COMPLETED); /* Will release group lock */ - return; - } - - /* - * Now lets look at the possible error cases (IRQ indicating error or timeout) - * END_OF_FRAME and HANG interrupts are not considered error. - */ - irq_errors = irq_readout & ~(MALI200_REG_VAL_IRQ_END_OF_FRAME|MALI200_REG_VAL_IRQ_HANG); - if (0 != irq_errors) - { - mali_pp_post_process_job(core); - MALI_PRINT_ERROR(("Mali PP: Unknown interrupt 0x%08X from core %s, aborting job\n", - irq_readout, core->hw_core.description)); - mali_group_bottom_half(core->group, GROUP_EVENT_PP_JOB_FAILED); /* Will release group lock */ - return; - } - else if (MALI_TRUE == core->core_timed_out) /* SW timeout */ - { - if (core->timeout_job_id == mali_pp_job_get_id(core->running_job)) - { - mali_pp_post_process_job(core); - MALI_DEBUG_PRINT(2, ("Mali PP: Job %d timed out on core %s\n", - mali_pp_job_get_id(core->running_job), core->hw_core.description)); - mali_group_bottom_half(core->group, GROUP_EVENT_PP_JOB_TIMED_OUT); /* Will release group lock */ - } - else - { - mali_group_unlock(core->group); - } - core->core_timed_out = MALI_FALSE; - return; - } - else if (irq_readout & MALI200_REG_VAL_IRQ_HANG) - { - /* Just ignore hang interrupts, the job timer will detect hanging jobs anyways */ - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_HANG); - } - - /* - * The only way to get here is if we got a HANG interrupt, which we ignore. - * Re-enable interrupts and let core continue to run - */ - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED); - mali_group_unlock(core->group); - -#if MALI_TIMELINE_PROFILING_ENABLED -#if 0 /* Bottom half TLP logging is currently not supported */ - _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_STOP| MALI_PROFILING_EVENT_CHANNEL_SOFTWARE , _mali_osk_get_pid(), _mali_osk_get_tid(), 0, 0, 0); -#endif -#endif -} - -static void mali_pp_irq_probe_trigger(void *data) -{ - struct mali_pp_core *core = (struct mali_pp_core *)data; - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED); /* @@@@ This should not be needed */ - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT, MALI200_REG_VAL_IRQ_FORCE_HANG); - _mali_osk_mem_barrier(); -} - -static _mali_osk_errcode_t mali_pp_irq_probe_ack(void *data) -{ - struct mali_pp_core *core = (struct mali_pp_core *)data; - u32 irq_readout; - - irq_readout = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_STATUS); - if (MALI200_REG_VAL_IRQ_FORCE_HANG & irq_readout) - { - mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_FORCE_HANG); - _mali_osk_mem_barrier(); - return _MALI_OSK_ERR_OK; - } - - return _MALI_OSK_ERR_FAULT; -} - - -/* ------ local helper functions below --------- */ -static void mali_pp_post_process_job(struct mali_pp_core *core) -{ - MALI_ASSERT_GROUP_LOCKED(core->group); - - if (NULL != core->running_job) - { - u32 val0 = 0; - u32 val1 = 0; -#if MALI_TIMELINE_PROFILING_ENABLED - int counter_index = COUNTER_FP0_C0 + (2 * core->core_id); -#endif - - if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used) - { - val0 = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE); - if (mali_pp_job_get_perf_counter_flag(core->running_job) && - _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE && mali_pp_job_get_perf_counter_src0(core->running_job) == core->counter_src0_used) - { - /* We retrieved the counter that user space asked for, so return the value through the job object */ - mali_pp_job_set_perf_counter_value0(core->running_job, core->running_sub_job, val0); - } - else - { - /* User space asked for a counter, but this is not what we retrived (overridden by counter src set on core) */ - mali_pp_job_set_perf_counter_value0(core->running_job, core->running_sub_job, MALI_HW_CORE_INVALID_VALUE); - } - -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_osk_profiling_report_hw_counter(counter_index, val0); -#endif - } - - if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used) - { - val1 = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE); - if (mali_pp_job_get_perf_counter_flag(core->running_job) && - _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE && mali_pp_job_get_perf_counter_src1(core->running_job) == core->counter_src1_used) - { - /* We retrieved the counter that user space asked for, so return the value through the job object */ - mali_pp_job_set_perf_counter_value1(core->running_job, core->running_sub_job, val1); - } - else - { - /* User space asked for a counter, but this is not what we retrived (overridden by counter src set on core) */ - mali_pp_job_set_perf_counter_value1(core->running_job, core->running_sub_job, MALI_HW_CORE_INVALID_VALUE); - } - -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_osk_profiling_report_hw_counter(counter_index + 1, val1); -#endif - } - -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_id), - val0, val1, core->counter_src0_used | (core->counter_src1_used << 8), 0, 0); -#endif - - /* We are no longer running a job... */ - core->running_job = NULL; - _mali_osk_timer_del(core->timeout_timer); - } -} - -/* callback function for pp core timeout */ -static void mali_pp_timeout(void *data) -{ - struct mali_pp_core * core = ((struct mali_pp_core *)data); - - MALI_DEBUG_PRINT(3, ("Mali PP: TIMEOUT callback \n")); - core->core_timed_out = MALI_TRUE; - _mali_osk_irq_schedulework(core->irq); -} - -#if 0 -static void mali_pp_print_registers(struct mali_pp_core *core) -{ - MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_VERSION = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_VERSION))); - MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_CURRENT_REND_LIST_ADDR = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_CURRENT_REND_LIST_ADDR))); - MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS))); - MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_RAWSTAT = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT))); - MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_MASK = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK))); - MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_STATUS))); - MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_BUS_ERROR_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_BUS_ERROR_STATUS))); - MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE))); - MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC))); - MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE))); - MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE))); - MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC))); - MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE))); -} -#endif - -#if 0 -void mali_pp_print_state(struct mali_pp_core *core) -{ - MALI_DEBUG_PRINT(2, ("Mali PP: State: 0x%08x\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS) )); -} -#endif - -#if MALI_STATE_TRACKING -u32 mali_pp_dump_state(struct mali_pp_core *core, char *buf, u32 size) -{ - int n = 0; - - n += _mali_osk_snprintf(buf + n, size - n, "\tPP #%d: %s\n", core->core_id, core->hw_core.description); - - return n; -} -#endif diff --git a/drivers/media/video/samsung/mali/common/mali_pp.h b/drivers/media/video/samsung/mali/common/mali_pp.h deleted file mode 100644 index 9b425a0..0000000 --- a/drivers/media/video/samsung/mali/common/mali_pp.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2011-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_PP_H__ -#define __MALI_PP_H__ - -#include "mali_osk.h" -#include "mali_pp_job.h" - -struct mali_pp_core; -struct mali_group; - -_mali_osk_errcode_t mali_pp_initialize(void); -void mali_pp_terminate(void); - -struct mali_pp_core *mali_pp_create(const _mali_osk_resource_t * resource, struct mali_group *group); -void mali_pp_delete(struct mali_pp_core *core); - -void mali_pp_stop_bus(struct mali_pp_core *core); -_mali_osk_errcode_t mali_pp_stop_bus_wait(struct mali_pp_core *core); -_mali_osk_errcode_t mali_pp_reset(struct mali_pp_core *core); -_mali_osk_errcode_t mali_pp_hard_reset(struct mali_pp_core *core); - -void mali_pp_job_start(struct mali_pp_core *core, struct mali_pp_job *job, u32 sub_job); - -u32 mali_pp_core_get_version(struct mali_pp_core *core); - -u32 mali_pp_core_get_id(struct mali_pp_core *core); - -mali_bool mali_pp_core_set_counter_src0(struct mali_pp_core *core, u32 counter); -mali_bool mali_pp_core_set_counter_src1(struct mali_pp_core *core, u32 counter); -u32 mali_pp_core_get_counter_src0(struct mali_pp_core *core); -u32 mali_pp_core_get_counter_src1(struct mali_pp_core *core); -struct mali_pp_core* mali_pp_get_global_pp_core(u32 index); -u32 mali_pp_get_glob_num_pp_cores(void); -u32 mali_pp_get_max_num_pp_cores(void); -/* Debug */ -u32 mali_pp_dump_state(struct mali_pp_core *core, char *buf, u32 size); - -#endif /* __MALI_PP_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_pp_job.c b/drivers/media/video/samsung/mali/common/mali_pp_job.c deleted file mode 100644 index 47b8a0a..0000000 --- a/drivers/media/video/samsung/mali/common/mali_pp_job.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2011-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_pp_job.h" -#include "mali_osk.h" -#include "mali_osk_list.h" -#include "mali_kernel_common.h" -#include "mali_uk_types.h" - -struct mali_pp_job *mali_pp_job_create(struct mali_session_data *session, _mali_uk_pp_start_job_s *args, u32 id) -{ - struct mali_pp_job *job; - - if (args->num_cores > _MALI_PP_MAX_SUB_JOBS) - { - MALI_PRINT_ERROR(("Mali PP job: Too many sub jobs specified in job object\n")); - return NULL; - } - - job = _mali_osk_malloc(sizeof(struct mali_pp_job)); - if (NULL != job) - { - u32 i; - _mali_osk_list_init(&job->list); - job->session = session; - job->id = id; - job->user_id = args->user_job_ptr; - job->barrier = args->flags & _MALI_PP_JOB_FLAG_BARRIER ? MALI_TRUE : MALI_FALSE; - job->active_barrier = job->barrier; - job->no_notification = args->flags & _MALI_PP_JOB_FLAG_NO_NOTIFICATION ? MALI_TRUE : MALI_FALSE; - _mali_osk_memcpy(job->frame_registers, args->frame_registers, sizeof(job->frame_registers)); - _mali_osk_memcpy(job->frame_registers_addr_frame, args->frame_registers_addr_frame, sizeof(job->frame_registers_addr_frame)); - _mali_osk_memcpy(job->frame_registers_addr_stack, args->frame_registers_addr_stack, sizeof(job->frame_registers_addr_stack)); - - /* Only copy write back registers for the units that are enabled */ - job->wb0_registers[0] = 0; - job->wb1_registers[0] = 0; - job->wb2_registers[0] = 0; - if (args->wb0_registers[0]) /* M200_WB0_REG_SOURCE_SELECT register */ - { - _mali_osk_memcpy(job->wb0_registers, args->wb0_registers, sizeof(job->wb0_registers)); - } - if (args->wb1_registers[0]) /* M200_WB1_REG_SOURCE_SELECT register */ - { - _mali_osk_memcpy(job->wb1_registers, args->wb1_registers, sizeof(job->wb1_registers)); - } - if (args->wb2_registers[0]) /* M200_WB2_REG_SOURCE_SELECT register */ - { - _mali_osk_memcpy(job->wb2_registers, args->wb2_registers, sizeof(job->wb2_registers)); - } - - job->perf_counter_flag = args->perf_counter_flag; - job->perf_counter_src0 = args->perf_counter_src0; - job->perf_counter_src1 = args->perf_counter_src1; - for (i = 0; i < args->num_cores; i++) - { - job->perf_counter_value0[i] = 0; - job->perf_counter_value1[i] = 0; - } - job->sub_job_count = args->num_cores; - job->sub_jobs_started = 0; - job->sub_jobs_completed = 0; - job->sub_job_errors = 0; - - job->pid = _mali_osk_get_pid(); - job->tid = _mali_osk_get_tid(); - job->frame_builder_id = args->frame_builder_id; - job->flush_id = args->flush_id; - - return job; - } - - return NULL; -} - -void mali_pp_job_delete(struct mali_pp_job *job) -{ - _mali_osk_free(job); -} - -_mali_osk_errcode_t mali_pp_job_check(struct mali_pp_job *job) -{ - if ((0 == job->frame_registers[0]) || (0 == job->frame_registers[1])) - { - return _MALI_OSK_ERR_FAULT; - } - return _MALI_OSK_ERR_OK; -} diff --git a/drivers/media/video/samsung/mali/common/mali_pp_job.h b/drivers/media/video/samsung/mali/common/mali_pp_job.h deleted file mode 100644 index 4399c1d..0000000 --- a/drivers/media/video/samsung/mali/common/mali_pp_job.h +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (C) 2011-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_PP_JOB_H__ -#define __MALI_PP_JOB_H__ - -#include "mali_osk.h" -#include "mali_osk_list.h" -#include "mali_uk_types.h" -#include "mali_session.h" -#include "mali_kernel_common.h" -#include "regs/mali_200_regs.h" - -/** - * The structure represends a PP job, including all sub-jobs - * (This struct unfortunatly needs to be public because of how the _mali_osk_list_* - * mechanism works) - */ -struct mali_pp_job -{ - _mali_osk_list_t list; /**< Used to link jobs together in the scheduler queue */ - struct mali_session_data *session; /**< Session which submitted this job */ - u32 id; /**< identifier for this job in kernel space (sequencial numbering) */ - u32 user_id; /**< identifier for the job in user space */ - u32 frame_registers[_MALI_PP_MAX_FRAME_REGISTERS]; /**< core specific registers associated with this job, see ARM DDI0415A */ - u32 frame_registers_addr_frame[_MALI_PP_MAX_SUB_JOBS - 1]; /**< ADDR_FRAME registers for sub job 1-7 */ - u32 frame_registers_addr_stack[_MALI_PP_MAX_SUB_JOBS - 1]; /**< ADDR_STACK registers for sub job 1-7 */ - u32 wb0_registers[_MALI_PP_MAX_WB_REGISTERS]; /**< Write back unit 0 registers */ - u32 wb1_registers[_MALI_PP_MAX_WB_REGISTERS]; /**< Write back unit 1 registers */ - u32 wb2_registers[_MALI_PP_MAX_WB_REGISTERS]; /**< Write back unit 2 registers */ - u32 perf_counter_flag; /**< bitmask indicating which performance counters to enable, see \ref _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE and related macro definitions */ - u32 perf_counter_src0; /**< Source id for performance counter 0 (see ARM DDI0415A, Table 3-60) */ - u32 perf_counter_src1; /**< Source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */ - u32 perf_counter_value0[_MALI_PP_MAX_SUB_JOBS]; /**< Value of performance counter 0 (to be returned to user space), one for each sub job */ - u32 perf_counter_value1[_MALI_PP_MAX_SUB_JOBS]; /**< Value of performance counter 1 (to be returned to user space), one for each sub job */ - u32 sub_job_count; /**< Total number of sub-jobs in this superjob */ - u32 sub_jobs_started; /**< Total number of sub-jobs started (always started in ascending order) */ - u32 sub_jobs_completed; /**< Number of completed sub-jobs in this superjob */ - u32 sub_job_errors; /**< Bitfield with errors (errors for each single sub-job is or'ed together) */ - u32 pid; /**< Process ID of submitting process */ - u32 tid; /**< Thread ID of submitting thread */ - u32 frame_builder_id; /**< id of the originating frame builder */ - u32 flush_id; /**< flush id within the originating frame builder */ - mali_bool barrier; /**< [in] MALI_TRUE means wait for all my previous jobs to complete before scheduling this one */ - mali_bool active_barrier; /**< [in] Changes from MALI_TRUE to MALI_FALSE when barrier has been resolved */ - mali_bool no_notification; /**< [in] MALI_TRUE means do not notify user space when this job has completed */ -}; - -struct mali_pp_job *mali_pp_job_create(struct mali_session_data *session, _mali_uk_pp_start_job_s *args, u32 id); -void mali_pp_job_delete(struct mali_pp_job *job); - -_mali_osk_errcode_t mali_pp_job_check(struct mali_pp_job *job); - -/****************************************************** - * simple utility functions for dealing with pp jobs: - *****************************************************/ - -MALI_STATIC_INLINE u32 mali_pp_job_get_id(struct mali_pp_job *job) -{ - return (NULL == job) ? 0 : job->id; -} - -MALI_STATIC_INLINE u32 mali_pp_job_get_user_id(struct mali_pp_job *job) -{ - return job->user_id; -} - -MALI_STATIC_INLINE u32 mali_pp_job_get_frame_builder_id(struct mali_pp_job *job) -{ - return job->frame_builder_id; -} - -MALI_STATIC_INLINE u32 mali_pp_job_get_flush_id(struct mali_pp_job *job) -{ - return job->flush_id; -} - -MALI_STATIC_INLINE u32* mali_pp_job_get_frame_registers(struct mali_pp_job *job) -{ - return job->frame_registers; -} - -MALI_STATIC_INLINE u32 mali_pp_job_get_addr_frame(struct mali_pp_job *job, u32 sub_job) -{ - if (sub_job == 0) - { - return job->frame_registers[MALI200_REG_ADDR_FRAME / sizeof(u32)]; - } - else if (sub_job < _MALI_PP_MAX_SUB_JOBS) - { - return job->frame_registers_addr_frame[sub_job - 1]; - } - - return 0; -} - -MALI_STATIC_INLINE u32 mali_pp_job_get_addr_stack(struct mali_pp_job *job, u32 sub_job) -{ - if (sub_job == 0) - { - return job->frame_registers[MALI200_REG_ADDR_STACK / sizeof(u32)]; - } - else if (sub_job < _MALI_PP_MAX_SUB_JOBS) - { - return job->frame_registers_addr_stack[sub_job - 1]; - } - - return 0; -} - -MALI_STATIC_INLINE u32* mali_pp_job_get_wb0_registers(struct mali_pp_job *job) -{ - return job->wb0_registers; -} - -MALI_STATIC_INLINE u32* mali_pp_job_get_wb1_registers(struct mali_pp_job *job) -{ - return job->wb1_registers; -} - -MALI_STATIC_INLINE u32* mali_pp_job_get_wb2_registers(struct mali_pp_job *job) -{ - return job->wb2_registers; -} - -MALI_STATIC_INLINE void mali_pp_job_disable_wb0(struct mali_pp_job *job) -{ - job->wb0_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0; -} - -MALI_STATIC_INLINE void mali_pp_job_disable_wb1(struct mali_pp_job *job) -{ - job->wb1_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0; -} - -MALI_STATIC_INLINE void mali_pp_job_disable_wb2(struct mali_pp_job *job) -{ - job->wb2_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0; -} - -MALI_STATIC_INLINE struct mali_session_data *mali_pp_job_get_session(struct mali_pp_job *job) -{ - return job->session; -} - -MALI_STATIC_INLINE mali_bool mali_pp_job_has_unstarted_sub_jobs(struct mali_pp_job *job) -{ - return (job->sub_jobs_started < job->sub_job_count) ? MALI_TRUE : MALI_FALSE; -} - -/* Function used when we are terminating a session with jobs. Return TRUE if it has a rendering job. - Makes sure that no new subjobs is started. */ -MALI_STATIC_INLINE mali_bool mali_pp_job_is_currently_rendering_and_if_so_abort_new_starts(struct mali_pp_job *job) -{ - /* All can not be started, since then it would not be in the job queue */ - MALI_DEBUG_ASSERT( job->sub_jobs_started != job->sub_job_count ); - - /* If at least one job is started */ - if ( (job->sub_jobs_started > 0) ) - { - /* If at least one job is currently being rendered, and thus assigned to a group and core */ - if (job->sub_jobs_started > job->sub_jobs_completed ) - { - u32 jobs_remaining = job->sub_job_count - job->sub_jobs_started; - job->sub_jobs_started += jobs_remaining; - job->sub_jobs_completed += jobs_remaining; - job->sub_job_errors += jobs_remaining; - /* Returning TRUE indicating that we can not delete this job which is being redered */ - return MALI_TRUE; - } - } - /* The job is not being rendered to at the moment and can then safely be deleted */ - return MALI_FALSE; -} - -MALI_STATIC_INLINE mali_bool mali_pp_job_is_complete(struct mali_pp_job *job) -{ - return (job->sub_job_count == job->sub_jobs_completed) ? MALI_TRUE : MALI_FALSE; -} - -MALI_STATIC_INLINE u32 mali_pp_job_get_first_unstarted_sub_job(struct mali_pp_job *job) -{ - return job->sub_jobs_started; -} - -MALI_STATIC_INLINE u32 mali_pp_job_get_sub_job_count(struct mali_pp_job *job) -{ - return job->sub_job_count; -} - -MALI_STATIC_INLINE void mali_pp_job_mark_sub_job_started(struct mali_pp_job *job, u32 sub_job) -{ - /* Assert that we are marking the "first unstarted sub job" as started */ - MALI_DEBUG_ASSERT(job->sub_jobs_started == sub_job); - job->sub_jobs_started++; -} - -MALI_STATIC_INLINE void mali_pp_job_mark_sub_job_completed(struct mali_pp_job *job, mali_bool success) -{ - job->sub_jobs_completed++; - if ( MALI_FALSE == success ) - { - job->sub_job_errors++; - } -} - -MALI_STATIC_INLINE mali_bool mali_pp_job_was_success(struct mali_pp_job *job) -{ - if ( 0 == job->sub_job_errors ) - { - return MALI_TRUE; - } - return MALI_FALSE; -} - -MALI_STATIC_INLINE mali_bool mali_pp_job_has_active_barrier(struct mali_pp_job *job) -{ - return job->active_barrier; -} - -MALI_STATIC_INLINE void mali_pp_job_barrier_enforced(struct mali_pp_job *job) -{ - job->active_barrier = MALI_FALSE; -} - -MALI_STATIC_INLINE mali_bool mali_pp_job_use_no_notification(struct mali_pp_job *job) -{ - return job->no_notification; -} - -MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_flag(struct mali_pp_job *job) -{ - return job->perf_counter_flag; -} - -MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_src0(struct mali_pp_job *job) -{ - return job->perf_counter_src0; -} - -MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_src1(struct mali_pp_job *job) -{ - return job->perf_counter_src1; -} - -MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_value0(struct mali_pp_job *job, u32 sub_job) -{ - return job->perf_counter_value0[sub_job]; -} - -MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_value1(struct mali_pp_job *job, u32 sub_job) -{ - return job->perf_counter_value1[sub_job]; -} - -MALI_STATIC_INLINE void mali_pp_job_set_perf_counter_value0(struct mali_pp_job *job, u32 sub_job, u32 value) -{ - job->perf_counter_value0[sub_job] = value; -} - -MALI_STATIC_INLINE void mali_pp_job_set_perf_counter_value1(struct mali_pp_job *job, u32 sub_job, u32 value) -{ - job->perf_counter_value1[sub_job] = value; -} - -#endif /* __MALI_PP_JOB_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_pp_scheduler.c b/drivers/media/video/samsung/mali/common/mali_pp_scheduler.c deleted file mode 100644 index a944055..0000000 --- a/drivers/media/video/samsung/mali/common/mali_pp_scheduler.c +++ /dev/null @@ -1,594 +0,0 @@ -/* - * Copyright (C) 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_pp_scheduler.h" -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "mali_osk_list.h" -#include "mali_scheduler.h" -#include "mali_pp.h" -#include "mali_pp_job.h" -#include "mali_group.h" -#include "mali_cluster.h" - -/* Maximum of 8 PP cores (a group can only have maximum of 1 PP core) */ -#define MALI_MAX_NUMBER_OF_PP_GROUPS 8 - -static mali_bool mali_pp_scheduler_is_suspended(void); - -enum mali_pp_slot_state -{ - MALI_PP_SLOT_STATE_IDLE, - MALI_PP_SLOT_STATE_WORKING, -}; - -/* A render slot is an entity which jobs can be scheduled onto */ -struct mali_pp_slot -{ - struct mali_group *group; - /* - * We keep track of the state here as well as in the group object - * so we don't need to take the group lock so often (and also avoid clutter with the working lock) - */ - enum mali_pp_slot_state state; - struct mali_session_data *session; -}; - -static u32 pp_version = 0; -static _MALI_OSK_LIST_HEAD(job_queue); /* List of jobs with some unscheduled work */ -static struct mali_pp_slot slots[MALI_MAX_NUMBER_OF_PP_GROUPS]; -static u32 num_slots = 0; -static u32 num_slots_idle = 0; - -/* Variables to allow safe pausing of the scheduler */ -static _mali_osk_wait_queue_t *pp_scheduler_working_wait_queue = NULL; -static u32 pause_count = 0; - -static _mali_osk_lock_t *pp_scheduler_lock = NULL; -/* Contains tid of thread that locked the scheduler or 0, if not locked */ -MALI_DEBUG_CODE(static u32 pp_scheduler_lock_owner = 0); - -_mali_osk_errcode_t mali_pp_scheduler_initialize(void) -{ - u32 i; - - _MALI_OSK_INIT_LIST_HEAD(&job_queue); - - pp_scheduler_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_SCHEDULER); - if (NULL == pp_scheduler_lock) - { - return _MALI_OSK_ERR_NOMEM; - } - - pp_scheduler_working_wait_queue = _mali_osk_wait_queue_init(); - if (NULL == pp_scheduler_working_wait_queue) - { - _mali_osk_lock_term(pp_scheduler_lock); - return _MALI_OSK_ERR_NOMEM; - } - - /* Find all the available PP cores */ - for (i = 0; i < mali_cluster_get_glob_num_clusters(); i++) - { - u32 group_id = 0; - struct mali_cluster *curr_cluster = mali_cluster_get_global_cluster(i); - struct mali_group *group = mali_cluster_get_group(curr_cluster, group_id); - while (NULL != group) - { - struct mali_pp_core *pp_core = mali_group_get_pp_core(group); - if (NULL != pp_core) - { - if (0 == pp_version) - { - /* Retrieve PP version from first avaiable PP core */ - pp_version = mali_pp_core_get_version(pp_core); - } - slots[num_slots].group = group; - slots[num_slots].state = MALI_PP_SLOT_STATE_IDLE; - slots[num_slots].session = NULL; - num_slots++; - num_slots_idle++; - } - group_id++; - group = mali_cluster_get_group(curr_cluster, group_id); - } - } - - return _MALI_OSK_ERR_OK; -} - -void mali_pp_scheduler_terminate(void) -{ - _mali_osk_wait_queue_term(pp_scheduler_working_wait_queue); - _mali_osk_lock_term(pp_scheduler_lock); -} - -MALI_STATIC_INLINE void mali_pp_scheduler_lock(void) -{ - if(_MALI_OSK_ERR_OK != _mali_osk_lock_wait(pp_scheduler_lock, _MALI_OSK_LOCKMODE_RW)) - { - /* Non-interruptable lock failed: this should never happen. */ - MALI_DEBUG_ASSERT(0); - } - MALI_DEBUG_PRINT(5, ("Mali PP scheduler: PP scheduler lock taken\n")); - MALI_DEBUG_ASSERT(0 == pp_scheduler_lock_owner); - MALI_DEBUG_CODE(pp_scheduler_lock_owner = _mali_osk_get_tid()); -} - -MALI_STATIC_INLINE void mali_pp_scheduler_unlock(void) -{ - MALI_DEBUG_PRINT(5, ("Mali PP scheduler: Releasing PP scheduler lock\n")); - MALI_DEBUG_ASSERT(_mali_osk_get_tid() == pp_scheduler_lock_owner); - MALI_DEBUG_CODE(pp_scheduler_lock_owner = 0); - _mali_osk_lock_signal(pp_scheduler_lock, _MALI_OSK_LOCKMODE_RW); -} - -#ifdef DEBUG -MALI_STATIC_INLINE void mali_pp_scheduler_assert_locked(void) -{ - MALI_DEBUG_ASSERT(_mali_osk_get_tid() == pp_scheduler_lock_owner); -} -#define MALI_ASSERT_PP_SCHEDULER_LOCKED() mali_pp_scheduler_assert_locked() -#else -#define MALI_ASSERT_PP_SCHEDULER_LOCKED() -#endif - -static mali_bool mali_pp_scheduler_session_has_running_jobs(struct mali_session_data *session) -{ - u32 i; - - MALI_ASSERT_PP_SCHEDULER_LOCKED(); - - if (num_slots_idle == num_slots) - { - return MALI_FALSE; - } - - for (i = 0; i < num_slots; i++) - { - if (MALI_PP_SLOT_STATE_WORKING == slots[i].state) - { - if (slots[i].session == session) - { - return MALI_TRUE; - } - } - } - - return MALI_FALSE; -} - -static void mali_pp_scheduler_schedule(void) -{ - u32 i; - struct mali_pp_job *job; -#if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS - struct mali_session_data * session; -#endif - - MALI_ASSERT_PP_SCHEDULER_LOCKED(); - - if (0 < pause_count || 0 == num_slots_idle || _mali_osk_list_empty(&job_queue)) - { - MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Nothing to schedule (paused=%u, idle slots=%u)\n", - pause_count, num_slots_idle)); - return; /* Nothing to do, so early out */ - } - - -#if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP - if ( num_slots_idle < num_slots ) - { - MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job not started, since only %d/%d cores are available\n", num_slots_idle,num_slots)); - return; - } -#endif - -#if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS - /* Finding initial session for the PP cores */ - job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_pp_job, list); - session = job->session; - if ( num_slots != num_slots_idle ) - { - for (i = 0; (i < num_slots) ; i++) - { - if ( slots[i].state == MALI_PP_SLOT_STATE_IDLE ) - { - continue; - } - session = mali_group_get_session(slots[i].group); - break; - } - } -#endif - - for (i = 0; (i < num_slots) && (0 < num_slots_idle); i++) - { - u32 sub_job; - - if (_mali_osk_list_empty(&job_queue)) /* move this check down to where we know we have started all sub jobs for this job??? */ - { - break; /* No more jobs to schedule, so early out */ - } - - if (MALI_PP_SLOT_STATE_IDLE != slots[i].state) - { - continue; - } - - job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_pp_job, list); - MALI_DEBUG_ASSERT(mali_pp_job_has_unstarted_sub_jobs(job)); /* All jobs on the job_queue should have unstarted sub jobs */ - - if (MALI_TRUE == mali_pp_job_has_active_barrier(job)) - { - if (MALI_TRUE == mali_pp_scheduler_session_has_running_jobs(mali_pp_job_get_session(job))) - { - /* There is already a running job from this session, so we need to enforce the barrier */ - return; - } - else - { - /* Barrier is now enforced, update job object so we don't delay execution of sub-jobs */ - mali_pp_job_barrier_enforced(job); - } - } - - #if MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED - if ( (0==job->sub_jobs_started) && (num_slots_idle < num_slots) && (job->sub_job_count > num_slots_idle)) - { - MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job with %d subjobs not started, since only %d/%d cores are available\n", job->sub_job_count, num_slots_idle,num_slots)); - return; - } - #endif - - #if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS - if ( job->session != session ) - { - MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job not started since existing job is from another application\n")); - return; - } - #endif - - sub_job = mali_pp_job_get_first_unstarted_sub_job(job); - - MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Starting job %u (0x%08X) part %u/%u\n", mali_pp_job_get_id(job), job, sub_job + 1, mali_pp_job_get_sub_job_count(job))); - if (_MALI_OSK_ERR_OK == mali_group_start_pp_job(slots[i].group, job, sub_job)) - { - MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job %u (0x%08X) part %u/%u started\n", mali_pp_job_get_id(job), job, sub_job + 1, mali_pp_job_get_sub_job_count(job))); - - /* Mark this sub job as started */ - mali_pp_job_mark_sub_job_started(job, sub_job); - - /* Mark slot as busy */ - slots[i].state = MALI_PP_SLOT_STATE_WORKING; - slots[i].session = mali_pp_job_get_session(job); - num_slots_idle--; - - if (!mali_pp_job_has_unstarted_sub_jobs(job)) - { - /* - * All sub jobs have now started for this job, remove this job from the job queue. - * The job will now only be referred to by the slots which are running it. - * The last slot to complete will make sure it is returned to user space. - */ - _mali_osk_list_del(&job->list); -#if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP - MALI_DEBUG_PRINT(6, ("Mali PP scheduler: Skip scheduling more jobs when MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP is set.\n")); - return; -#endif - } - } - else - { - MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Failed to start PP job\n")); - return; - } - } -} - -static void mali_pp_scheduler_return_job_to_user(struct mali_pp_job *job) -{ - if (MALI_FALSE == mali_pp_job_use_no_notification(job)) - { - _mali_osk_notification_t *notobj = _mali_osk_notification_create(_MALI_NOTIFICATION_PP_FINISHED, sizeof(_mali_uk_pp_job_finished_s)); - if (NULL != notobj) - { - u32 i; - u32 sub_jobs = mali_pp_job_get_sub_job_count(job); - mali_bool success = mali_pp_job_was_success(job); - - _mali_uk_pp_job_finished_s *jobres = notobj->result_buffer; - _mali_osk_memset(jobres, 0, sizeof(_mali_uk_pp_job_finished_s)); /* @@@@ can be removed once we initialize all members in this struct */ - jobres->user_job_ptr = mali_pp_job_get_user_id(job); - if (MALI_TRUE == success) - { - jobres->status = _MALI_UK_JOB_STATUS_END_SUCCESS; - } - else - { - jobres->status = _MALI_UK_JOB_STATUS_END_UNKNOWN_ERR; - } - - for (i = 0; i < sub_jobs; i++) - { - jobres->perf_counter0[i] = mali_pp_job_get_perf_counter_value0(job, i); - jobres->perf_counter1[i] = mali_pp_job_get_perf_counter_value1(job, i); - } - - mali_session_send_notification(mali_pp_job_get_session(job), notobj); - } - else - { - MALI_PRINT_ERROR(("Mali PP scheduler: Unable to allocate notification object\n")); - } - } - - mali_pp_job_delete(job); -} - -void mali_pp_scheduler_do_schedule(void) -{ - mali_pp_scheduler_lock(); - - mali_pp_scheduler_schedule(); - - mali_pp_scheduler_unlock(); -} - -void mali_pp_scheduler_job_done(struct mali_group *group, struct mali_pp_job *job, u32 sub_job, mali_bool success) -{ - u32 i; - mali_bool job_is_done; - - MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Job %u (0x%08X) part %u/%u completed (%s)\n", mali_pp_job_get_id(job), job, sub_job + 1, mali_pp_job_get_sub_job_count(job), success ? "success" : "failure")); - - mali_pp_scheduler_lock(); - - /* Find slot which was running this job */ - for (i = 0; i < num_slots; i++) - { - if (slots[i].group == group) - { - MALI_DEBUG_ASSERT(MALI_PP_SLOT_STATE_WORKING == slots[i].state); - slots[i].state = MALI_PP_SLOT_STATE_IDLE; - slots[i].session = NULL; - num_slots_idle++; - mali_pp_job_mark_sub_job_completed(job, success); - } - } - - /* If paused, then this was the last job, so wake up sleeping workers */ - if (pause_count > 0) - { - /* Wake up sleeping workers. Their wake-up condition is that - * num_slots == num_slots_idle, so unless we are done working, no - * threads will actually be woken up. - */ - _mali_osk_wait_queue_wake_up(pp_scheduler_working_wait_queue); - } - else - { - mali_pp_scheduler_schedule(); - } - - job_is_done = mali_pp_job_is_complete(job); - - mali_pp_scheduler_unlock(); - - if (job_is_done) - { - /* Send notification back to user space */ - MALI_DEBUG_PRINT(4, ("Mali PP scheduler: All parts completed for job %u (0x%08X)\n", mali_pp_job_get_id(job), job)); - mali_pp_scheduler_return_job_to_user(job); - } -} - -void mali_pp_scheduler_suspend(void) -{ - mali_pp_scheduler_lock(); - pause_count++; /* Increment the pause_count so that no more jobs will be scheduled */ - mali_pp_scheduler_unlock(); - - /*mali_pp_scheduler_working_lock();*/ - /* We have now aquired the working lock, which means that we have successfully paused the scheduler */ - /*mali_pp_scheduler_working_unlock();*/ - - /* go to sleep. When woken up again (in mali_pp_scheduler_job_done), the - * mali_pp_scheduler_suspended() function will be called. This will return true - * iff state is idle and pause_count > 0, so if the core is active this - * will not do anything. - */ - _mali_osk_wait_queue_wait_event(pp_scheduler_working_wait_queue, mali_pp_scheduler_is_suspended); -} - -void mali_pp_scheduler_resume(void) -{ - mali_pp_scheduler_lock(); - pause_count--; /* Decrement pause_count to allow scheduling again (if it reaches 0) */ - if (0 == pause_count) - { - mali_pp_scheduler_schedule(); - } - mali_pp_scheduler_unlock(); -} - -_mali_osk_errcode_t _mali_ukk_pp_start_job(_mali_uk_pp_start_job_s *args) -{ - struct mali_session_data *session; - struct mali_pp_job *job; - - MALI_DEBUG_ASSERT_POINTER(args); - MALI_DEBUG_ASSERT_POINTER(args->ctx); - - session = (struct mali_session_data*)args->ctx; - - job = mali_pp_job_create(session, args, mali_scheduler_get_new_id()); - if (NULL == job) - { - return _MALI_OSK_ERR_NOMEM; - } - - if (_MALI_OSK_ERR_OK != mali_pp_job_check(job)) - { - /* Not a valid job, return to user immediately */ - mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */ - mali_pp_scheduler_return_job_to_user(job); /* This will also delete the job object */ - return _MALI_OSK_ERR_OK; /* User is notified via a notification, so this call is ok */ - } - -#if PROFILING_SKIP_PP_JOBS || PROFILING_SKIP_PP_AND_GP_JOBS -#warning PP jobs will not be executed - mali_pp_scheduler_return_job_to_user(job); - return _MALI_OSK_ERR_OK; -#endif - - mali_pp_scheduler_lock(); - - _mali_osk_list_addtail(&job->list, &job_queue); - - MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Job %u (0x%08X) with %u parts queued\n", mali_pp_job_get_id(job), job, mali_pp_job_get_sub_job_count(job))); - - mali_pp_scheduler_schedule(); - - mali_pp_scheduler_unlock(); - - return _MALI_OSK_ERR_OK; -} - -_mali_osk_errcode_t _mali_ukk_get_pp_number_of_cores(_mali_uk_get_pp_number_of_cores_s *args) -{ - MALI_DEBUG_ASSERT_POINTER(args); - MALI_DEBUG_ASSERT_POINTER(args->ctx); - args->number_of_cores = num_slots; - return _MALI_OSK_ERR_OK; -} - -_mali_osk_errcode_t _mali_ukk_get_pp_core_version(_mali_uk_get_pp_core_version_s *args) -{ - MALI_DEBUG_ASSERT_POINTER(args); - MALI_DEBUG_ASSERT_POINTER(args->ctx); - args->version = pp_version; - return _MALI_OSK_ERR_OK; -} - -void _mali_ukk_pp_job_disable_wb(_mali_uk_pp_disable_wb_s *args) -{ - struct mali_session_data *session; - struct mali_pp_job *job; - struct mali_pp_job *tmp; - - MALI_DEBUG_ASSERT_POINTER(args); - MALI_DEBUG_ASSERT_POINTER(args->ctx); - - session = (struct mali_session_data*)args->ctx; - - mali_pp_scheduler_lock(); - - /* Check queue for jobs that match */ - _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &job_queue, struct mali_pp_job, list) - { - if (mali_pp_job_get_session(job) == session && - mali_pp_job_get_frame_builder_id(job) == (u32)args->fb_id && - mali_pp_job_get_flush_id(job) == (u32)args->flush_id) - { - if (args->wbx & _MALI_UK_PP_JOB_WB0) - { - mali_pp_job_disable_wb0(job); - } - if (args->wbx & _MALI_UK_PP_JOB_WB1) - { - mali_pp_job_disable_wb1(job); - } - if (args->wbx & _MALI_UK_PP_JOB_WB2) - { - mali_pp_job_disable_wb2(job); - } - break; - } - } - - mali_pp_scheduler_unlock(); -} - -void mali_pp_scheduler_abort_session(struct mali_session_data *session) -{ - struct mali_pp_job *job, *tmp; - int i; - - mali_pp_scheduler_lock(); - MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Aborting all jobs from session 0x%08x\n", session)); - - /* Check queue for jobs and remove */ - _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &job_queue, struct mali_pp_job, list) - { - if (mali_pp_job_get_session(job) == session) - { - _mali_osk_list_del(&(job->list)); - - if ( mali_pp_job_is_currently_rendering_and_if_so_abort_new_starts(job) ) - { - /* The job is in the render pipeline, we can not delete it yet. */ - /* It will be deleted in the mali_group_abort_session() call below */ - MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Keeping partially started PP job 0x%08x in queue\n", job)); - continue; - } - MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Removing PP job 0x%08x from queue\n", job)); - mali_pp_job_delete(job); - } - } - - mali_pp_scheduler_unlock(); - - /* Abort running jobs from this session */ - for (i = 0; i < num_slots; i++) - { - struct mali_group *group = slots[i].group; - - MALI_DEBUG_PRINT(5, ("PP sched abort: Looking at group 0x%08x\n", group)); - - if (MALI_PP_SLOT_STATE_WORKING == slots[i].state) - { - MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Aborting session 0x%08x from group 0x%08x\n", session, group)); - - mali_group_abort_session(group, session); - } - } -} - -static mali_bool mali_pp_scheduler_is_suspended(void) -{ - mali_bool ret; - - mali_pp_scheduler_lock(); - ret = pause_count > 0 && num_slots == num_slots_idle; - mali_pp_scheduler_unlock(); - - return ret; -} - -#if MALI_STATE_TRACKING -u32 mali_pp_scheduler_dump_state(char *buf, u32 size) -{ - int n = 0; - int i; - - n += _mali_osk_snprintf(buf + n, size - n, "PP:\n"); - n += _mali_osk_snprintf(buf + n, size - n, "\tQueue is %s\n", _mali_osk_list_empty(&job_queue) ? "empty" : "not empty"); - n += _mali_osk_snprintf(buf + n, size - n, "\n"); - - for (i = 0; i < num_slots; i++) - { - n += mali_group_dump_state(slots[i].group, buf + n, size - n); - n += _mali_osk_snprintf(buf + n, size - n, "\t\tState: %d\n", slots[i].state); - } - - return n; -} -#endif diff --git a/drivers/media/video/samsung/mali/common/mali_pp_scheduler.h b/drivers/media/video/samsung/mali/common/mali_pp_scheduler.h deleted file mode 100644 index 48eb3bd..0000000 --- a/drivers/media/video/samsung/mali/common/mali_pp_scheduler.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_PP_SCHEDULER_H__ -#define __MALI_PP_SCHEDULER_H__ - -#include "mali_osk.h" -#include "mali_cluster.h" -#include "mali_pp_job.h" - -_mali_osk_errcode_t mali_pp_scheduler_initialize(void); -void mali_pp_scheduler_terminate(void); - -void mali_pp_scheduler_do_schedule(void); -void mali_pp_scheduler_job_done(struct mali_group *group, struct mali_pp_job *job, u32 sub_job, mali_bool success); - -void mali_pp_scheduler_suspend(void); -void mali_pp_scheduler_resume(void); - -/** @brief Abort all PP jobs from session running or queued - * - * This functions aborts all PP jobs from the specified session. Queued jobs are removed from the queue and jobs - * currently running on a core will be aborted. - * - * @param session Pointer to session whose jobs should be aborted - */ -void mali_pp_scheduler_abort_session(struct mali_session_data *session); - -u32 mali_pp_scheduler_dump_state(char *buf, u32 size); - -#endif /* __MALI_PP_SCHEDULER_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_scheduler.c b/drivers/media/video/samsung/mali/common/mali_scheduler.c deleted file mode 100644 index f360209..0000000 --- a/drivers/media/video/samsung/mali/common/mali_scheduler.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_kernel_common.h" -#include "mali_osk.h" - -static _mali_osk_atomic_t mali_job_autonumber; - -_mali_osk_errcode_t mali_scheduler_initialize(void) -{ - if ( _MALI_OSK_ERR_OK != _mali_osk_atomic_init(&mali_job_autonumber, 0)) - { - MALI_DEBUG_PRINT(1, ("Initialization of atomic job id counter failed.\n")); - return _MALI_OSK_ERR_FAULT; - } - - return _MALI_OSK_ERR_OK; -} - -void mali_scheduler_terminate(void) -{ - _mali_osk_atomic_term(&mali_job_autonumber); -} - -u32 mali_scheduler_get_new_id(void) -{ - u32 job_id = _mali_osk_atomic_inc_return(&mali_job_autonumber); - return job_id; -} - diff --git a/drivers/media/video/samsung/mali/common/mali_scheduler.h b/drivers/media/video/samsung/mali/common/mali_scheduler.h deleted file mode 100644 index 74f0947..0000000 --- a/drivers/media/video/samsung/mali/common/mali_scheduler.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_SCHEDULER_H__ -#define __MALI_SCHEDULER_H__ - -#include "mali_osk.h" - -_mali_osk_errcode_t mali_scheduler_initialize(void); -void mali_scheduler_terminate(void); - -u32 mali_scheduler_get_new_id(void); - -#endif /* __MALI_SCHEDULER_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_session.c b/drivers/media/video/samsung/mali/common/mali_session.c deleted file mode 100644 index 2394bb9..0000000 --- a/drivers/media/video/samsung/mali/common/mali_session.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_osk.h" -#include "mali_osk_list.h" -#include "mali_session.h" - -_MALI_OSK_LIST_HEAD(mali_sessions); - -_mali_osk_lock_t *mali_sessions_lock; - -_mali_osk_errcode_t mali_session_initialize(void) -{ - _MALI_OSK_INIT_LIST_HEAD(&mali_sessions); - - mali_sessions_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_ORDERED, 0, _MALI_OSK_LOCK_ORDER_SESSIONS); - - if (NULL == mali_sessions_lock) return _MALI_OSK_ERR_NOMEM; - - return _MALI_OSK_ERR_OK; -} - -void mali_session_terminate(void) -{ - _mali_osk_lock_term(mali_sessions_lock); -} - -void mali_session_add(struct mali_session_data *session) -{ - mali_session_lock(); - _mali_osk_list_add(&session->link, &mali_sessions); - mali_session_unlock(); -} - -void mali_session_remove(struct mali_session_data *session) -{ - mali_session_lock(); - _mali_osk_list_delinit(&session->link); - mali_session_unlock(); -} diff --git a/drivers/media/video/samsung/mali/common/mali_session.h b/drivers/media/video/samsung/mali/common/mali_session.h deleted file mode 100644 index c8640b5..0000000 --- a/drivers/media/video/samsung/mali/common/mali_session.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_SESSION_H__ -#define __MALI_SESSION_H__ - -#include "mali_mmu_page_directory.h" -#include "mali_kernel_descriptor_mapping.h" -#include "mali_osk.h" -#include "mali_osk_list.h" - -struct mali_session_data -{ - _mali_osk_notification_queue_t * ioctl_queue; - - _mali_osk_lock_t *memory_lock; /**< Lock protecting the vm manipulation */ - mali_descriptor_mapping * descriptor_mapping; /**< Mapping between userspace descriptors and our pointers */ - _mali_osk_list_t memory_head; /**< Track all the memory allocated in this session, for freeing on abnormal termination */ - - struct mali_page_directory *page_directory; /**< MMU page directory for this session */ - - _MALI_OSK_LIST_HEAD(link); /**< Link for list of all sessions */ -}; - -_mali_osk_errcode_t mali_session_initialize(void); -void mali_session_terminate(void); - -/* List of all sessions. Actual list head in mali_kernel_core.c */ -extern _mali_osk_list_t mali_sessions; -/* Lock to protect modification and access to the mali_sessions list */ -extern _mali_osk_lock_t *mali_sessions_lock; - -MALI_STATIC_INLINE void mali_session_lock(void) -{ - _mali_osk_lock_wait(mali_sessions_lock, _MALI_OSK_LOCKMODE_RW); -} - -MALI_STATIC_INLINE void mali_session_unlock(void) -{ - _mali_osk_lock_signal(mali_sessions_lock, _MALI_OSK_LOCKMODE_RW); -} - -void mali_session_add(struct mali_session_data *session); -void mali_session_remove(struct mali_session_data *session); -#define MALI_SESSION_FOREACH(session, tmp, link) \ - _MALI_OSK_LIST_FOREACHENTRY(session, tmp, &mali_sessions, struct mali_session_data, link) - -MALI_STATIC_INLINE struct mali_page_directory *mali_session_get_page_directory(struct mali_session_data *session) -{ - return session->page_directory; -} - -MALI_STATIC_INLINE void mali_session_send_notification(struct mali_session_data *session, _mali_osk_notification_t *object) -{ - _mali_osk_notification_queue_send(session->ioctl_queue, object); -} - -#endif /* __MALI_SESSION_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_ukk.h b/drivers/media/video/samsung/mali/common/mali_ukk.h deleted file mode 100644 index 6b018d0..0000000 --- a/drivers/media/video/samsung/mali/common/mali_ukk.h +++ /dev/null @@ -1,612 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_ukk.h - * Defines the kernel-side interface of the user-kernel interface - */ - -#ifndef __MALI_UKK_H__ -#define __MALI_UKK_H__ - -#include "mali_osk.h" -#include "mali_uk_types.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -/** - * @addtogroup uddapi Unified Device Driver (UDD) APIs - * - * @{ - */ - -/** - * @addtogroup u_k_api UDD User/Kernel Interface (U/K) APIs - * - * - The _mali_uk functions are an abstraction of the interface to the device - * driver. On certain OSs, this would be implemented via the IOCTL interface. - * On other OSs, it could be via extension of some Device Driver Class, or - * direct function call for Bare metal/RTOSs. - * - It is important to note that: - * - The Device Driver has implemented the _mali_ukk set of functions - * - The Base Driver calls the corresponding set of _mali_uku functions. - * - What requires porting is solely the calling mechanism from User-side to - * Kernel-side, and propagating back the results. - * - Each U/K function is associated with a (group, number) pair from - * \ref _mali_uk_functions to make it possible for a common function in the - * Base Driver and Device Driver to route User/Kernel calls from/to the - * correct _mali_uk function. For example, in an IOCTL system, the IOCTL number - * would be formed based on the group and number assigned to the _mali_uk - * function, as listed in \ref _mali_uk_functions. On the user-side, each - * _mali_uku function would just make an IOCTL with the IOCTL-code being an - * encoded form of the (group, number) pair. On the kernel-side, the Device - * Driver's IOCTL handler decodes the IOCTL-code back into a (group, number) - * pair, and uses this to determine which corresponding _mali_ukk should be - * called. - * - Refer to \ref _mali_uk_functions for more information about this - * (group, number) pairing. - * - In a system where there is no distinction between user and kernel-side, - * the U/K interface may be implemented as:@code - * MALI_STATIC_INLINE _mali_osk_errcode_t _mali_uku_examplefunction( _mali_uk_examplefunction_s *args ) - * { - * return mali_ukk_examplefunction( args ); - * } - * @endcode - * - Therefore, all U/K calls behave \em as \em though they were direct - * function calls (but the \b implementation \em need \em not be a direct - * function calls) - * - * @note Naming the _mali_uk functions the same on both User and Kernel sides - * on non-RTOS systems causes debugging issues when setting breakpoints. In - * this case, it is not clear which function the breakpoint is put on. - * Therefore the _mali_uk functions in user space are prefixed with \c _mali_uku - * and in kernel space with \c _mali_ukk. The naming for the argument - * structures is unaffected. - * - * - The _mali_uk functions are synchronous. - * - Arguments to the _mali_uk functions are passed in a structure. The only - * parameter passed to the _mali_uk functions is a pointer to this structure. - * This first member of this structure, ctx, is a pointer to a context returned - * by _mali_uku_open(). For example:@code - * typedef struct - * { - * void *ctx; - * u32 number_of_cores; - * } _mali_uk_get_gp_number_of_cores_s; - * @endcode - * - * - Each _mali_uk function has its own argument structure named after the - * function. The argument is distinguished by the _s suffix. - * - The argument types are defined by the base driver and user-kernel - * interface. - * - All _mali_uk functions return a standard \ref _mali_osk_errcode_t. - * - Only arguments of type input or input/output need be initialized before - * calling a _mali_uk function. - * - Arguments of type output and input/output are only valid when the - * _mali_uk function returns \ref _MALI_OSK_ERR_OK. - * - The \c ctx member is always invalid after it has been used by a - * _mali_uk function, except for the context management functions - * - * - * \b Interface \b restrictions - * - * The requirements of the interface mean that an implementation of the - * User-kernel interface may do no 'real' work. For example, the following are - * illegal in the User-kernel implementation: - * - Calling functions necessary for operation on all systems, which would - * not otherwise get called on RTOS systems. - * - For example, a U/K interface that calls multiple _mali_ukk functions - * during one particular U/K call. This could not be achieved by the same code - * which uses direct function calls for the U/K interface. - * - Writing in values to the args members, when otherwise these members would - * not hold a useful value for a direct function call U/K interface. - * - For example, U/K interface implementation that take NULL members in - * their arguments structure from the user side, but those members are - * replaced with non-NULL values in the kernel-side of the U/K interface - * implementation. A scratch area for writing data is one such example. In this - * case, a direct function call U/K interface would segfault, because no code - * would be present to replace the NULL pointer with a meaningful pointer. - * - Note that we discourage the case where the U/K implementation changes - * a NULL argument member to non-NULL, and then the Device Driver code (outside - * of the U/K layer) re-checks this member for NULL, and corrects it when - * necessary. Whilst such code works even on direct function call U/K - * intefaces, it reduces the testing coverage of the Device Driver code. This - * is because we have no way of testing the NULL == value path on an OS - * implementation. - * - * A number of allowable examples exist where U/K interfaces do 'real' work: - * - The 'pointer switching' technique for \ref _mali_ukk_get_system_info - * - In this case, without the pointer switching on direct function call - * U/K interface, the Device Driver code still sees the same thing: a pointer - * to which it can write memory. This is because such a system has no - * distinction between a user and kernel pointer. - * - Writing an OS-specific value into the ukk_private member for - * _mali_ukk_mem_mmap(). - * - In this case, this value is passed around by Device Driver code, but - * its actual value is never checked. Device Driver code simply passes it from - * the U/K layer to the OSK layer, where it can be acted upon. In this case, - * \em some OS implementations of the U/K (_mali_ukk_mem_mmap()) and OSK - * (_mali_osk_mem_mapregion_init()) functions will collaborate on the - * meaning of ukk_private member. On other OSs, it may be unused by both - * U/K and OSK layers - * - Therefore, on error inside the U/K interface implementation itself, - * it will be as though the _mali_ukk function itself had failed, and cleaned - * up after itself. - * - Compare this to a direct function call U/K implementation, where all - * error cleanup is handled by the _mali_ukk function itself. The direct - * function call U/K interface implementation is automatically atomic. - * - * The last example highlights a consequence of all U/K interface - * implementations: they must be atomic with respect to the Device Driver code. - * And therefore, should Device Driver code succeed but the U/K implementation - * fail afterwards (but before return to user-space), then the U/K - * implementation must cause appropriate cleanup actions to preserve the - * atomicity of the interface. - * - * @{ - */ - - -/** @defgroup _mali_uk_context U/K Context management - * - * These functions allow for initialisation of the user-kernel interface once per process. - * - * Generally the context will store the OS specific object to communicate with the kernel device driver and further - * state information required by the specific implementation. The context is shareable among all threads in the caller process. - * - * On IOCTL systems, this is likely to be a file descriptor as a result of opening the kernel device driver. - * - * On a bare-metal/RTOS system with no distinction between kernel and - * user-space, the U/K interface simply calls the _mali_ukk variant of the - * function by direct function call. In this case, the context returned is the - * mali_session_data from _mali_ukk_open(). - * - * The kernel side implementations of the U/K interface expect the first member of the argument structure to - * be the context created by _mali_uku_open(). On some OS implementations, the meaning of this context - * will be different between user-side and kernel-side. In which case, the kernel-side will need to replace this context - * with the kernel-side equivalent, because user-side will not have access to kernel-side data. The context parameter - * in the argument structure therefore has to be of type input/output. - * - * It should be noted that the caller cannot reuse the \c ctx member of U/K - * argument structure after a U/K call, because it may be overwritten. Instead, - * the context handle must always be stored elsewhere, and copied into - * the appropriate U/K argument structure for each user-side call to - * the U/K interface. This is not usually a problem, since U/K argument - * structures are usually placed on the stack. - * - * @{ */ - -/** @brief Begin a new Mali Device Driver session - * - * This is used to obtain a per-process context handle for all future U/K calls. - * - * @param context pointer to storage to return a (void*)context handle. - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. - */ -_mali_osk_errcode_t _mali_ukk_open( void **context ); - -/** @brief End a Mali Device Driver session - * - * This should be called when the process no longer requires use of the Mali Device Driver. - * - * The context handle must not be used after it has been closed. - * - * @param context pointer to a stored (void*)context handle. - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. - */ -_mali_osk_errcode_t _mali_ukk_close( void **context ); - -/** @} */ /* end group _mali_uk_context */ - - -/** @addtogroup _mali_uk_core U/K Core - * - * The core functions provide the following functionality: - * - verify that the user and kernel API are compatible - * - retrieve information about the cores and memory banks in the system - * - wait for the result of jobs started on a core - * - * @{ */ - -/** @brief Waits for a job notification. - * - * Sleeps until notified or a timeout occurs. Returns information about the notification. - * - * @param args see _mali_uk_wait_for_notification_s in "mali_utgard_uk_types.h" - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. - */ -_mali_osk_errcode_t _mali_ukk_wait_for_notification( _mali_uk_wait_for_notification_s *args ); - -/** @brief Post a notification to the notification queue of this application. - * - * @param args see _mali_uk_post_notification_s in "mali_utgard_uk_types.h" - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. - */ -_mali_osk_errcode_t _mali_ukk_post_notification( _mali_uk_post_notification_s *args ); - -/** @brief Verifies if the user and kernel side of this API are compatible. - * - * @param args see _mali_uk_get_api_version_s in "mali_utgard_uk_types.h" - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. - */ -_mali_osk_errcode_t _mali_ukk_get_api_version( _mali_uk_get_api_version_s *args ); - -/** @brief Get the user space settings applicable for calling process. - * - * @param args see _mali_uk_get_user_settings_s in "mali_utgard_uk_types.h" - */ -_mali_osk_errcode_t _mali_ukk_get_user_settings(_mali_uk_get_user_settings_s *args); - -/** @brief Get a user space setting applicable for calling process. - * - * @param args see _mali_uk_get_user_setting_s in "mali_utgard_uk_types.h" - */ -_mali_osk_errcode_t _mali_ukk_get_user_setting(_mali_uk_get_user_setting_s *args); - -/** @} */ /* end group _mali_uk_core */ - - -/** @addtogroup _mali_uk_memory U/K Memory - * - * The memory functions provide functionality with and without a Mali-MMU present. - * - * For Mali-MMU based systems, the following functionality is provided: - * - Initialize and terminate MALI virtual address space - * - Allocate/deallocate physical memory to a MALI virtual address range and map into/unmap from the - * current process address space - * - Map/unmap external physical memory into the MALI virtual address range - * - * For Mali-nonMMU based systems: - * - Allocate/deallocate MALI memory - * - * @{ */ - -/** - * @brief Initialize the Mali-MMU Memory system - * - * For Mali-MMU builds of the drivers, this function must be called before any - * other functions in the \ref _mali_uk_memory group are called. - * - * @note This function is for Mali-MMU builds \b only. It should not be called - * when the drivers are built without Mali-MMU support. - * - * @param args see \ref _mali_uk_init_mem_s in mali_utgard_uk_types.h - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable - * _mali_osk_errcode_t on failure. - */ -_mali_osk_errcode_t _mali_ukk_init_mem( _mali_uk_init_mem_s *args ); - -/** - * @brief Terminate the MMU Memory system - * - * For Mali-MMU builds of the drivers, this function must be called when - * functions in the \ref _mali_uk_memory group will no longer be called. This - * function must be called before the application terminates. - * - * @note This function is for Mali-MMU builds \b only. It should not be called - * when the drivers are built without Mali-MMU support. - * - * @param args see \ref _mali_uk_term_mem_s in mali_utgard_uk_types.h - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable - * _mali_osk_errcode_t on failure. - */ -_mali_osk_errcode_t _mali_ukk_term_mem( _mali_uk_term_mem_s *args ); - -/** @brief Map Mali Memory into the current user process - * - * Maps Mali memory into the current user process in a generic way. - * - * This function is to be used for Mali-MMU mode. The function is available in both Mali-MMU and Mali-nonMMU modes, - * but should not be called by a user process in Mali-nonMMU mode. - * - * The implementation and operation of _mali_ukk_mem_mmap() is dependant on whether the driver is built for Mali-MMU - * or Mali-nonMMU: - * - In the nonMMU case, _mali_ukk_mem_mmap() requires a physical address to be specified. For this reason, an OS U/K - * implementation should not allow this to be called from user-space. In any case, nonMMU implementations are - * inherently insecure, and so the overall impact is minimal. Mali-MMU mode should be used if security is desired. - * - In the MMU case, _mali_ukk_mem_mmap() the _mali_uk_mem_mmap_s::phys_addr - * member is used for the \em Mali-virtual address desired for the mapping. The - * implementation of _mali_ukk_mem_mmap() will allocate both the CPU-virtual - * and CPU-physical addresses, and can cope with mapping a contiguous virtual - * address range to a sequence of non-contiguous physical pages. In this case, - * the CPU-physical addresses are not communicated back to the user-side, as - * they are unnecsessary; the \em Mali-virtual address range must be used for - * programming Mali structures. - * - * In the second (MMU) case, _mali_ukk_mem_mmap() handles management of - * CPU-virtual and CPU-physical ranges, but the \em caller must manage the - * \em Mali-virtual address range from the user-side. - * - * @note Mali-virtual address ranges are entirely separate between processes. - * It is not possible for a process to accidentally corrupt another process' - * \em Mali-virtual address space. - * - * @param args see _mali_uk_mem_mmap_s in "mali_utgard_uk_types.h" - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. - */ -_mali_osk_errcode_t _mali_ukk_mem_mmap( _mali_uk_mem_mmap_s *args ); - -/** @brief Unmap Mali Memory from the current user process - * - * Unmaps Mali memory from the current user process in a generic way. This only operates on Mali memory supplied - * from _mali_ukk_mem_mmap(). - * - * @param args see _mali_uk_mem_munmap_s in "mali_utgard_uk_types.h" - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. - */ -_mali_osk_errcode_t _mali_ukk_mem_munmap( _mali_uk_mem_munmap_s *args ); - -/** @brief Determine the buffer size necessary for an MMU page table dump. - * @param args see _mali_uk_query_mmu_page_table_dump_size_s in mali_utgard_uk_types.h - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. - */ -_mali_osk_errcode_t _mali_ukk_query_mmu_page_table_dump_size( _mali_uk_query_mmu_page_table_dump_size_s *args ); -/** @brief Dump MMU Page tables. - * @param args see _mali_uk_dump_mmu_page_table_s in mali_utgard_uk_types.h - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. - */ -_mali_osk_errcode_t _mali_ukk_dump_mmu_page_table( _mali_uk_dump_mmu_page_table_s * args ); - -/** @brief Map a physically contiguous range of memory into Mali - * @param args see _mali_uk_map_external_mem_s in mali_utgard_uk_types.h - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. - */ -_mali_osk_errcode_t _mali_ukk_map_external_mem( _mali_uk_map_external_mem_s *args ); - -/** @brief Unmap a physically contiguous range of memory from Mali - * @param args see _mali_uk_unmap_external_mem_s in mali_utgard_uk_types.h - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. - */ -_mali_osk_errcode_t _mali_ukk_unmap_external_mem( _mali_uk_unmap_external_mem_s *args ); - -#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 -/** @brief Map UMP memory into Mali - * @param args see _mali_uk_attach_ump_mem_s in mali_utgard_uk_types.h - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. - */ -_mali_osk_errcode_t _mali_ukk_attach_ump_mem( _mali_uk_attach_ump_mem_s *args ); -/** @brief Unmap UMP memory from Mali - * @param args see _mali_uk_release_ump_mem_s in mali_utgard_uk_types.h - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. - */ -_mali_osk_errcode_t _mali_ukk_release_ump_mem( _mali_uk_release_ump_mem_s *args ); -#endif /* MALI_USE_UNIFIED_MEMORY_PROVIDER */ - -/** @brief Determine virtual-to-physical mapping of a contiguous memory range - * (optional) - * - * This allows the user-side to do a virtual-to-physical address translation. - * In conjunction with _mali_uku_map_external_mem, this can be used to do - * direct rendering. - * - * This function will only succeed on a virtual range that is mapped into the - * current process, and that is contigious. - * - * If va is not page-aligned, then it is rounded down to the next page - * boundary. The remainer is added to size, such that ((u32)va)+size before - * rounding is equal to ((u32)va)+size after rounding. The rounded modified - * va and size will be written out into args on success. - * - * If the supplied size is zero, or not a multiple of the system's PAGE_SIZE, - * then size will be rounded up to the next multiple of PAGE_SIZE before - * translation occurs. The rounded up size will be written out into args on - * success. - * - * On most OSs, virtual-to-physical address translation is a priveledged - * function. Therefore, the implementer must validate the range supplied, to - * ensure they are not providing arbitrary virtual-to-physical address - * translations. While it is unlikely such a mechanism could be used to - * compromise the security of a system on its own, it is possible it could be - * combined with another small security risk to cause a much larger security - * risk. - * - * @note This is an optional part of the interface, and is only used by certain - * implementations of libEGL. If the platform layer in your libEGL - * implementation does not require Virtual-to-Physical address translation, - * then this function need not be implemented. A stub implementation should not - * be required either, as it would only be removed by the compiler's dead code - * elimination. - * - * @note if implemented, this function is entirely platform-dependant, and does - * not exist in common code. - * - * @param args see _mali_uk_va_to_mali_pa_s in "mali_utgard_uk_types.h" - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. - */ -_mali_osk_errcode_t _mali_ukk_va_to_mali_pa( _mali_uk_va_to_mali_pa_s * args ); - -/** @} */ /* end group _mali_uk_memory */ - - -/** @addtogroup _mali_uk_pp U/K Fragment Processor - * - * The Fragment Processor (aka PP (Pixel Processor)) functions provide the following functionality: - * - retrieving version of the fragment processors - * - determine number of fragment processors - * - starting a job on a fragment processor - * - * @{ */ - -/** @brief Issue a request to start a new job on a Fragment Processor. - * - * If the request fails args->status is set to _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE and you can - * try to start the job again. - * - * An existing job could be returned for requeueing if the new job has a higher priority than a previously started job - * which the hardware hasn't actually started processing yet. In this case the new job will be started instead and the - * existing one returned, otherwise the new job is started and the status field args->status is set to - * _MALI_UK_START_JOB_STARTED. - * - * Job completion can be awaited with _mali_ukk_wait_for_notification(). - * - * @param args see _mali_uk_pp_start_job_s in "mali_utgard_uk_types.h" - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. - */ -_mali_osk_errcode_t _mali_ukk_pp_start_job( _mali_uk_pp_start_job_s *args ); - -/** @brief Returns the number of Fragment Processors in the system - * - * @param args see _mali_uk_get_pp_number_of_cores_s in "mali_utgard_uk_types.h" - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. - */ -_mali_osk_errcode_t _mali_ukk_get_pp_number_of_cores( _mali_uk_get_pp_number_of_cores_s *args ); - -/** @brief Returns the version that all Fragment Processor cores are compatible with. - * - * This function may only be called when _mali_ukk_get_pp_number_of_cores() indicated at least one Fragment - * Processor core is available. - * - * @param args see _mali_uk_get_pp_core_version_s in "mali_utgard_uk_types.h" - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. - */ -_mali_osk_errcode_t _mali_ukk_get_pp_core_version( _mali_uk_get_pp_core_version_s *args ); - -/** @brief Disable Write-back unit(s) on specified job - * - * @param args see _mali_uk_get_pp_core_version_s in "mali_utgard_uk_types.h" - */ -void _mali_ukk_pp_job_disable_wb(_mali_uk_pp_disable_wb_s *args); - - -/** @} */ /* end group _mali_uk_pp */ - - -/** @addtogroup _mali_uk_gp U/K Vertex Processor - * - * The Vertex Processor (aka GP (Geometry Processor)) functions provide the following functionality: - * - retrieving version of the Vertex Processors - * - determine number of Vertex Processors available - * - starting a job on a Vertex Processor - * - * @{ */ - -/** @brief Issue a request to start a new job on a Vertex Processor. - * - * If the request fails args->status is set to _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE and you can - * try to start the job again. - * - * An existing job could be returned for requeueing if the new job has a higher priority than a previously started job - * which the hardware hasn't actually started processing yet. In this case the new job will be started and the - * existing one returned, otherwise the new job is started and the status field args->status is set to - * _MALI_UK_START_JOB_STARTED. - * - * Job completion can be awaited with _mali_ukk_wait_for_notification(). - * - * @param args see _mali_uk_gp_start_job_s in "mali_utgard_uk_types.h" - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. - */ -_mali_osk_errcode_t _mali_ukk_gp_start_job( _mali_uk_gp_start_job_s *args ); - -/** @brief Returns the number of Vertex Processors in the system. - * - * @param args see _mali_uk_get_gp_number_of_cores_s in "mali_utgard_uk_types.h" - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. - */ -_mali_osk_errcode_t _mali_ukk_get_gp_number_of_cores( _mali_uk_get_gp_number_of_cores_s *args ); - -/** @brief Returns the version that all Vertex Processor cores are compatible with. - * - * This function may only be called when _mali_uk_get_gp_number_of_cores() indicated at least one Vertex - * Processor core is available. - * - * @param args see _mali_uk_get_gp_core_version_s in "mali_utgard_uk_types.h" - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. - */ -_mali_osk_errcode_t _mali_ukk_get_gp_core_version( _mali_uk_get_gp_core_version_s *args ); - -/** @brief Resume or abort suspended Vertex Processor jobs. - * - * After receiving notification that a Vertex Processor job was suspended from - * _mali_ukk_wait_for_notification() you can use this function to resume or abort the job. - * - * @param args see _mali_uk_gp_suspend_response_s in "mali_utgard_uk_types.h" - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. - */ -_mali_osk_errcode_t _mali_ukk_gp_suspend_response( _mali_uk_gp_suspend_response_s *args ); - -/** @} */ /* end group _mali_uk_gp */ - -#if MALI_TIMELINE_PROFILING_ENABLED -/** @addtogroup _mali_uk_profiling U/K Timeline profiling module - * @{ */ - -/** @brief Start recording profiling events. - * - * @param args see _mali_uk_profiling_start_s in "mali_utgard_uk_types.h" - */ -_mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args); - -/** @brief Add event to profiling buffer. - * - * @param args see _mali_uk_profiling_add_event_s in "mali_utgard_uk_types.h" - */ -_mali_osk_errcode_t _mali_ukk_profiling_add_event(_mali_uk_profiling_add_event_s *args); - -/** @brief Stop recording profiling events. - * - * @param args see _mali_uk_profiling_stop_s in "mali_utgard_uk_types.h" - */ -_mali_osk_errcode_t _mali_ukk_profiling_stop(_mali_uk_profiling_stop_s *args); - -/** @brief Retrieve a recorded profiling event. - * - * @param args see _mali_uk_profiling_get_event_s in "mali_utgard_uk_types.h" - */ -_mali_osk_errcode_t _mali_ukk_profiling_get_event(_mali_uk_profiling_get_event_s *args); - -/** @brief Clear recorded profiling events. - * - * @param args see _mali_uk_profiling_clear_s in "mali_utgard_uk_types.h" - */ -_mali_osk_errcode_t _mali_ukk_profiling_clear(_mali_uk_profiling_clear_s *args); - -/** @} */ /* end group _mali_uk_profiling */ -#endif - -/** @addtogroup _mali_uk_vsync U/K VSYNC reporting module - * @{ */ - -/** @brief Report events related to vsync. - * - * @note Events should be reported when starting to wait for vsync and when the - * waiting is finished. This information can then be used in kernel space to - * complement the GPU utilization metric. - * - * @param args see _mali_uk_vsync_event_report_s in "mali_utgard_uk_types.h" - */ -_mali_osk_errcode_t _mali_ukk_vsync_event_report(_mali_uk_vsync_event_report_s *args); - -/** @} */ /* end group _mali_uk_vsync */ - -/** @addtogroup _mali_sw_counters_report U/K Software counter reporting - * @{ */ - -/** @brief Report software counters. - * - * @param args see _mali_uk_sw_counters_report_s in "mali_uk_types.h" - */ -_mali_osk_errcode_t _mali_ukk_sw_counters_report(_mali_uk_sw_counters_report_s *args); - -/** @} */ /* end group _mali_sw_counters_report */ - -/** @} */ /* end group u_k_api */ - -/** @} */ /* end group uddapi */ - -u32 _mali_ukk_report_memory_usage(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __MALI_UKK_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_user_settings_db.c b/drivers/media/video/samsung/mali/common/mali_user_settings_db.c deleted file mode 100644 index d3f1e50..0000000 --- a/drivers/media/video/samsung/mali/common/mali_user_settings_db.c +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Copyright (C) 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_osk.h" -#include "mali_kernel_common.h" -#include "mali_uk_types.h" -#include "mali_user_settings_db.h" -#include "mali_session.h" - -static u32 mali_user_settings[_MALI_UK_USER_SETTING_MAX]; -const char *_mali_uk_user_setting_descriptions[] = _MALI_UK_USER_SETTING_DESCRIPTIONS; - -static void mali_user_settings_notify(_mali_uk_user_setting_t setting, u32 value) -{ - struct mali_session_data *session, *tmp; - - mali_session_lock(); - MALI_SESSION_FOREACH(session, tmp, link) - { - _mali_osk_notification_t *notobj = _mali_osk_notification_create(_MALI_NOTIFICATION_SETTINGS_CHANGED, sizeof(_mali_uk_settings_changed_s)); - _mali_uk_settings_changed_s *data = notobj->result_buffer; - data->setting = setting; - data->value = value; - - mali_session_send_notification(session, notobj); - } - mali_session_unlock(); -} - -void mali_set_user_setting(_mali_uk_user_setting_t setting, u32 value) -{ - mali_bool notify = MALI_FALSE; - - MALI_DEBUG_ASSERT(setting < _MALI_UK_USER_SETTING_MAX && setting >= 0); - - if (mali_user_settings[setting] != value) - { - notify = MALI_TRUE; - } - - mali_user_settings[setting] = value; - - if (notify) - { - mali_user_settings_notify(setting, value); - } -} - -u32 mali_get_user_setting(_mali_uk_user_setting_t setting) -{ - MALI_DEBUG_ASSERT(setting < _MALI_UK_USER_SETTING_MAX && setting >= 0); - - return mali_user_settings[setting]; -} - -_mali_osk_errcode_t _mali_ukk_get_user_setting(_mali_uk_get_user_setting_s *args) -{ - _mali_uk_user_setting_t setting; - MALI_DEBUG_ASSERT_POINTER(args); - - setting = args->setting; - - if (0 <= setting && _MALI_UK_USER_SETTING_MAX > setting) - { - args->value = mali_user_settings[setting]; - return _MALI_OSK_ERR_OK; - } - else - { - return _MALI_OSK_ERR_INVALID_ARGS; - } -} - -_mali_osk_errcode_t _mali_ukk_get_user_settings(_mali_uk_get_user_settings_s *args) -{ - MALI_DEBUG_ASSERT_POINTER(args); - - _mali_osk_memcpy(args->settings, mali_user_settings, sizeof(mali_user_settings)); - - return _MALI_OSK_ERR_OK; -} diff --git a/drivers/media/video/samsung/mali/common/mali_user_settings_db.h b/drivers/media/video/samsung/mali/common/mali_user_settings_db.h deleted file mode 100644 index fbb9415..0000000 --- a/drivers/media/video/samsung/mali/common/mali_user_settings_db.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Copyright (C) 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_USER_SETTINGS_DB_H__ -#define __MALI_USER_SETTINGS_DB_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "mali_uk_types.h" - -/** @brief Set Mali user setting in DB - * - * Update the DB with a new value for \a setting. If the value is different from theprevious set value running sessions will be notified of the change. - * - * @param setting the setting to be changed - * @param value the new value to set - */ -void mali_set_user_setting(_mali_uk_user_setting_t setting, u32 value); - -/** @brief Get current Mali user setting value from DB - * - * @param setting the setting to extract - * @return the value of the selected setting - */ -u32 mali_get_user_setting(_mali_uk_user_setting_t setting); - -#ifdef __cplusplus -} -#endif -#endif /* __MALI_KERNEL_USER_SETTING__ */ diff --git a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard.h b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard.h deleted file mode 100644 index 7c78947..0000000 --- a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_UTGARD_H__ -#define __MALI_UTGARD_H__ - -/** @brief MALI GPU power down using MALI in-built PMU - * - * called to power down all cores - */ -int mali_pmu_powerdown(void); - - -/** @brief MALI GPU power up using MALI in-built PMU - * - * called to power up all cores - */ -int mali_pmu_powerup(void); - -#endif /* __MALI_UTGARD_H__ */ - diff --git a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_counters.h b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_counters.h deleted file mode 100644 index 40822f7..0000000 --- a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_counters.h +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef _MALI_UTGARD_COUNTERS_H_ -#define _MALI_UTGARD_COUNTERS_H_ - -typedef struct -{ - void *unused; -} mali_cinstr_counter_info; - -typedef enum -{ - MALI_CINSTR_COUNTER_SOURCE_EGL = 0, - MALI_CINSTR_COUNTER_SOURCE_OPENGLES = 1000, - MALI_CINSTR_COUNTER_SOURCE_OPENVG = 2000, - MALI_CINSTR_COUNTER_SOURCE_GP = 3000, - MALI_CINSTR_COUNTER_SOURCE_PP = 4000, -} cinstr_counter_source; - -#define MALI_CINSTR_EGL_FIRST_COUNTER MALI_CINSTR_COUNTER_SOURCE_EGL -#define MALI_CINSTR_EGL_LAST_COUNTER (MALI_CINSTR_COUNTER_SOURCE_EGL + 999) - -#define MALI_CINSTR_GLES_FIRST_COUNTER MALI_CINSTR_COUNTER_SOURCE_OPENGLES -#define MALI_CINSTR_GLES_LAST_COUNTER (MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 999) - -#define MALI_CINSTR_VG_FIRST_COUNTER MALI_CINSTR_COUNTER_SOURCE_OPENVG -#define MALI_CINSTR_VG_LAST_COUNTER (MALI_CINSTR_COUNTER_SOURCE_OPENVG + 999) - -#define MALI_CINSTR_GP_FIRST_COUNTER MALI_CINSTR_COUNTER_SOURCE_GP -#define MALI_CINSTR_GP_LAST_COUNTER (MALI_CINSTR_COUNTER_SOURCE_GP + 999) - -#define MALI_CINSTR_PP_FIRST_COUNTER MALI_CINSTR_COUNTER_SOURCE_PP -#define MALI_CINSTR_PP_LAST_COUNTER (MALI_CINSTR_COUNTER_SOURCE_PP + 999) - - -typedef enum -{ - /* EGL counters */ - - MALI_CINSTR_EGL_BLIT_TIME = MALI_CINSTR_COUNTER_SOURCE_EGL + 0, - - /* Last counter in the EGL set */ - MALI_CINSTR_EGL_MAX_COUNTER = MALI_CINSTR_COUNTER_SOURCE_EGL + 1, - - /* GLES counters */ - - MALI_CINSTR_GLES_DRAW_ELEMENTS_CALLS = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 0, - MALI_CINSTR_GLES_DRAW_ELEMENTS_NUM_INDICES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 1, - MALI_CINSTR_GLES_DRAW_ELEMENTS_NUM_TRANSFORMED = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 2, - MALI_CINSTR_GLES_DRAW_ARRAYS_CALLS = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 3, - MALI_CINSTR_GLES_DRAW_ARRAYS_NUM_TRANSFORMED = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 4, - MALI_CINSTR_GLES_DRAW_POINTS = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 5, - MALI_CINSTR_GLES_DRAW_LINES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 6, - MALI_CINSTR_GLES_DRAW_LINE_LOOP = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 7, - MALI_CINSTR_GLES_DRAW_LINE_STRIP = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 8, - MALI_CINSTR_GLES_DRAW_TRIANGLES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 9, - MALI_CINSTR_GLES_DRAW_TRIANGLE_STRIP = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 10, - MALI_CINSTR_GLES_DRAW_TRIANGLE_FAN = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 11, - MALI_CINSTR_GLES_NON_VBO_DATA_COPY_TIME = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 12, - MALI_CINSTR_GLES_UNIFORM_BYTES_COPIED_TO_MALI = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 13, - MALI_CINSTR_GLES_UPLOAD_TEXTURE_TIME = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 14, - MALI_CINSTR_GLES_UPLOAD_VBO_TIME = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 15, - MALI_CINSTR_GLES_NUM_FLUSHES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 16, - MALI_CINSTR_GLES_NUM_VSHADERS_GENERATED = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 17, - MALI_CINSTR_GLES_NUM_FSHADERS_GENERATED = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 18, - MALI_CINSTR_GLES_VSHADER_GEN_TIME = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 19, - MALI_CINSTR_GLES_FSHADER_GEN_TIME = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 20, - MALI_CINSTR_GLES_INPUT_TRIANGLES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 21, - MALI_CINSTR_GLES_VXCACHE_HIT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 22, - MALI_CINSTR_GLES_VXCACHE_MISS = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 23, - MALI_CINSTR_GLES_VXCACHE_COLLISION = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 24, - MALI_CINSTR_GLES_CULLED_TRIANGLES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 25, - MALI_CINSTR_GLES_CULLED_LINES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 26, - MALI_CINSTR_GLES_BACKFACE_TRIANGLES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 27, - MALI_CINSTR_GLES_GBCLIP_TRIANGLES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 28, - MALI_CINSTR_GLES_GBCLIP_LINES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 29, - MALI_CINSTR_GLES_TRIANGLES_DRAWN = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 30, - MALI_CINSTR_GLES_DRAWCALL_TIME = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 31, - MALI_CINSTR_GLES_TRIANGLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 32, - MALI_CINSTR_GLES_INDEPENDENT_TRIANGLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 33, - MALI_CINSTR_GLES_STRIP_TRIANGLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 34, - MALI_CINSTR_GLES_FAN_TRIANGLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 35, - MALI_CINSTR_GLES_LINES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 36, - MALI_CINSTR_GLES_INDEPENDENT_LINES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 37, - MALI_CINSTR_GLES_STRIP_LINES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 38, - MALI_CINSTR_GLES_LOOP_LINES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 39, - MALI_CINSTR_GLES_POINTS_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 40, - - /* Last counter in the GLES set */ - MALI_CINSTR_GLES_MAX_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 41, - - /* OpenVG counters */ - - MALI_CINSTR_VG_MASK_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 0, - MALI_CINSTR_VG_CLEAR_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 1, - MALI_CINSTR_VG_APPEND_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 2, - MALI_CINSTR_VG_APPEND_PATH_DATA_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 3, - MALI_CINSTR_VG_MODIFY_PATH_COORDS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 4, - MALI_CINSTR_VG_TRANSFORM_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 5, - MALI_CINSTR_VG_INTERPOLATE_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 6, - MALI_CINSTR_VG_PATH_LENGTH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 7, - MALI_CINSTR_VG_POINT_ALONG_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 8, - MALI_CINSTR_VG_PATH_BOUNDS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 9, - MALI_CINSTR_VG_PATH_TRANSFORMED_BOUNDS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 10, - MALI_CINSTR_VG_DRAW_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 11, - MALI_CINSTR_VG_CLEAR_IMAGE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 12, - MALI_CINSTR_VG_IMAGE_SUB_DATA_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 13, - MALI_CINSTR_VG_GET_IMAGE_SUB_DATA_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 14, - MALI_CINSTR_VG_COPY_IMAGE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 15, - MALI_CINSTR_VG_DRAW_IMAGE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 16, - MALI_CINSTR_VG_SET_PIXELS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 17, - MALI_CINSTR_VG_WRITE_PIXELS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 18, - MALI_CINSTR_VG_GET_PIXELS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 19, - MALI_CINSTR_VG_READ_PIXELS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 20, - MALI_CINSTR_VG_COPY_PIXELS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 21, - MALI_CINSTR_VG_COLOR_MATRIX_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 22, - MALI_CINSTR_VG_CONVOLVE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 23, - MALI_CINSTR_VG_SEPARABLE_CONVOLVE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 24, - MALI_CINSTR_VG_GAUSSIAN_BLUR_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 25, - MALI_CINSTR_VG_LOOKUP_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 26, - MALI_CINSTR_VG_LOOKUP_SINGLE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 27, - MALI_CINSTR_VG_CONTEXT_CREATE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 28, - MALI_CINSTR_VG_STROKED_CUBICS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 29, - MALI_CINSTR_VG_STROKED_QUADS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 30, - MALI_CINSTR_VG_STROKED_ARCS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 31, - MALI_CINSTR_VG_STROKED_LINES_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 32, - MALI_CINSTR_VG_FILLED_CUBICS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 33, - MALI_CINSTR_VG_FILLED_QUADS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 34, - MALI_CINSTR_VG_FILLED_ARCS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 35, - MALI_CINSTR_VG_FILLED_LINES_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 36, - MALI_CINSTR_VG_DRAW_PATH_CALLS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 37, - MALI_CINSTR_VG_TRIANGLES_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 38, - MALI_CINSTR_VG_VERTICES_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 39, - MALI_CINSTR_VG_INDICES_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 40, - MALI_CINSTR_VG_FILLED_PATHS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 41, - MALI_CINSTR_VG_STROKED_PATHS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 42, - MALI_CINSTR_VG_FILL_EXTRACT_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 43, - MALI_CINSTR_VG_DRAW_FILLED_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 44, - MALI_CINSTR_VG_STROKE_EXTRACT_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 45, - MALI_CINSTR_VG_DRAW_STROKED_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 46, - MALI_CINSTR_VG_DRAW_PAINT_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 47, - MALI_CINSTR_VG_DATA_STRUCTURES_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 48, - MALI_CINSTR_VG_MEM_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 49, - MALI_CINSTR_VG_RSW_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 50, - - /* Last counter in the VG set */ - MALI_CINSTR_VG_MAX_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 51, - - /* Mali GP counters */ - - MALI_CINSTR_GP_DEPRECATED_0 = MALI_CINSTR_COUNTER_SOURCE_GP + 0, - MALI_CINSTR_GP_ACTIVE_CYCLES_GP = MALI_CINSTR_COUNTER_SOURCE_GP + 1, - MALI_CINSTR_GP_ACTIVE_CYCLES_VERTEX_SHADER = MALI_CINSTR_COUNTER_SOURCE_GP + 2, - MALI_CINSTR_GP_ACTIVE_CYCLES_VERTEX_STORER = MALI_CINSTR_COUNTER_SOURCE_GP + 3, - MALI_CINSTR_GP_ACTIVE_CYCLES_VERTEX_LOADER = MALI_CINSTR_COUNTER_SOURCE_GP + 4, - MALI_CINSTR_GP_CYCLES_VERTEX_LOADER_WAITING_FOR_VERTEX_SHADER = MALI_CINSTR_COUNTER_SOURCE_GP + 5, - MALI_CINSTR_GP_NUMBER_OF_WORDS_READ = MALI_CINSTR_COUNTER_SOURCE_GP + 6, - MALI_CINSTR_GP_NUMBER_OF_WORDS_WRITTEN = MALI_CINSTR_COUNTER_SOURCE_GP + 7, - MALI_CINSTR_GP_NUMBER_OF_READ_BURSTS = MALI_CINSTR_COUNTER_SOURCE_GP + 8, - MALI_CINSTR_GP_NUMBER_OF_WRITE_BURSTS = MALI_CINSTR_COUNTER_SOURCE_GP + 9, - MALI_CINSTR_GP_NUMBER_OF_VERTICES_PROCESSED = MALI_CINSTR_COUNTER_SOURCE_GP + 10, - MALI_CINSTR_GP_NUMBER_OF_VERTICES_FETCHED = MALI_CINSTR_COUNTER_SOURCE_GP + 11, - MALI_CINSTR_GP_NUMBER_OF_PRIMITIVES_FETCHED = MALI_CINSTR_COUNTER_SOURCE_GP + 12, - MALI_CINSTR_GP_RESERVED_13 = MALI_CINSTR_COUNTER_SOURCE_GP + 13, - MALI_CINSTR_GP_NUMBER_OF_BACKFACE_CULLINGS_DONE = MALI_CINSTR_COUNTER_SOURCE_GP + 14, - MALI_CINSTR_GP_NUMBER_OF_COMMANDS_WRITTEN_TO_TILES = MALI_CINSTR_COUNTER_SOURCE_GP + 15, - MALI_CINSTR_GP_NUMBER_OF_MEMORY_BLOCKS_ALLOCATED = MALI_CINSTR_COUNTER_SOURCE_GP + 16, - MALI_CINSTR_GP_RESERVED_17 = MALI_CINSTR_COUNTER_SOURCE_GP + 17, - MALI_CINSTR_GP_RESERVED_18 = MALI_CINSTR_COUNTER_SOURCE_GP + 18, - MALI_CINSTR_GP_NUMBER_OF_VERTEX_LOADER_CACHE_MISSES = MALI_CINSTR_COUNTER_SOURCE_GP + 19, - MALI_CINSTR_GP_RESERVED_20 = MALI_CINSTR_COUNTER_SOURCE_GP + 20, - MALI_CINSTR_GP_RESERVED_21 = MALI_CINSTR_COUNTER_SOURCE_GP + 21, - MALI_CINSTR_GP_ACTIVE_CYCLES_VERTEX_SHADER_COMMAND_PROCESSOR = MALI_CINSTR_COUNTER_SOURCE_GP + 22, - MALI_CINSTR_GP_ACTIVE_CYCLES_PLBU_COMMAND_PROCESSOR = MALI_CINSTR_COUNTER_SOURCE_GP + 23, - MALI_CINSTR_GP_ACTIVE_CYCLES_PLBU_LIST_WRITER = MALI_CINSTR_COUNTER_SOURCE_GP + 24, - MALI_CINSTR_GP_ACTIVE_CYCLES_THROUGH_THE_PREPARE_LIST_COMMANDS = MALI_CINSTR_COUNTER_SOURCE_GP + 25, - MALI_CINSTR_GP_RESERVED_26 = MALI_CINSTR_COUNTER_SOURCE_GP + 26, - MALI_CINSTR_GP_ACTIVE_CYCLES_PRIMITIVE_ASSEMBLY = MALI_CINSTR_COUNTER_SOURCE_GP + 27, - MALI_CINSTR_GP_ACTIVE_CYCLES_PLBU_VERTEX_FETCHER = MALI_CINSTR_COUNTER_SOURCE_GP + 28, - MALI_CINSTR_GP_RESERVED_29 = MALI_CINSTR_COUNTER_SOURCE_GP + 29, - MALI_CINSTR_GP_ACTIVE_CYCLES_BOUNDINGBOX_AND_COMMAND_GENERATOR = MALI_CINSTR_COUNTER_SOURCE_GP + 30, - MALI_CINSTR_GP_RESERVED_31 = MALI_CINSTR_COUNTER_SOURCE_GP + 31, - MALI_CINSTR_GP_ACTIVE_CYCLES_SCISSOR_TILE_ITERATOR = MALI_CINSTR_COUNTER_SOURCE_GP + 32, - MALI_CINSTR_GP_ACTIVE_CYCLES_PLBU_TILE_ITERATOR = MALI_CINSTR_COUNTER_SOURCE_GP + 33, - MALI_CINSTR_GP_JOB_COUNT = MALI_CINSTR_COUNTER_SOURCE_GP + 900, - - /* Mali PP counters */ - - MALI_CINSTR_PP_ACTIVE_CLOCK_CYCLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 0, - MALI_CINSTR_PP_TOTAL_CLOCK_CYCLES_COUNT_REMOVED = MALI_CINSTR_COUNTER_SOURCE_PP + 1, - MALI_CINSTR_PP_TOTAL_BUS_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 2, - MALI_CINSTR_PP_TOTAL_BUS_WRITES = MALI_CINSTR_COUNTER_SOURCE_PP + 3, - MALI_CINSTR_PP_BUS_READ_REQUEST_CYCLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 4, - MALI_CINSTR_PP_BUS_WRITE_REQUEST_CYCLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 5, - MALI_CINSTR_PP_BUS_READ_TRANSACTIONS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 6, - MALI_CINSTR_PP_BUS_WRITE_TRANSACTIONS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 7, - MALI_CINSTR_PP_RESERVED_08 = MALI_CINSTR_COUNTER_SOURCE_PP + 8, - MALI_CINSTR_PP_TILE_WRITEBACK_WRITES = MALI_CINSTR_COUNTER_SOURCE_PP + 9, - MALI_CINSTR_PP_STORE_UNIT_WRITES = MALI_CINSTR_COUNTER_SOURCE_PP + 10, - MALI_CINSTR_PP_RESERVED_11 = MALI_CINSTR_COUNTER_SOURCE_PP + 11, - MALI_CINSTR_PP_PALETTE_CACHE_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 12, - MALI_CINSTR_PP_TEXTURE_CACHE_UNCOMPRESSED_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 13, - MALI_CINSTR_PP_POLYGON_LIST_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 14, - MALI_CINSTR_PP_RSW_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 15, - MALI_CINSTR_PP_VERTEX_CACHE_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 16, - MALI_CINSTR_PP_UNIFORM_REMAPPING_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 17, - MALI_CINSTR_PP_PROGRAM_CACHE_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 19, - MALI_CINSTR_PP_VARYING_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 19, - MALI_CINSTR_PP_TEXTURE_DESCRIPTORS_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 20, - MALI_CINSTR_PP_TEXTURE_DESCRIPTORS_REMAPPING_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 21, - MALI_CINSTR_PP_TEXTURE_CACHE_COMPRESSED_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 22, - MALI_CINSTR_PP_LOAD_UNIT_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 23, - MALI_CINSTR_PP_POLYGON_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 24, - MALI_CINSTR_PP_PIXEL_RECTANGLE_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 25, - MALI_CINSTR_PP_LINES_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 26, - MALI_CINSTR_PP_POINTS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 27, - MALI_CINSTR_PP_STALL_CYCLES_POLYGON_LIST_READER = MALI_CINSTR_COUNTER_SOURCE_PP + 28, - MALI_CINSTR_PP_STALL_CYCLES_TRIANGLE_SETUP = MALI_CINSTR_COUNTER_SOURCE_PP + 29, - MALI_CINSTR_PP_QUAD_RASTERIZED_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 30, - MALI_CINSTR_PP_FRAGMENT_RASTERIZED_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 31, - MALI_CINSTR_PP_FRAGMENT_REJECTED_FRAGMENT_KILL_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 32, - MALI_CINSTR_PP_FRAGMENT_REJECTED_FWD_FRAGMENT_KILL_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 33, - MALI_CINSTR_PP_FRAGMENT_PASSED_ZSTENCIL_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 34, - MALI_CINSTR_PP_PATCHES_REJECTED_EARLY_Z_STENCIL_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 35, - MALI_CINSTR_PP_PATCHES_EVALUATED = MALI_CINSTR_COUNTER_SOURCE_PP + 36, - MALI_CINSTR_PP_INSTRUCTION_COMPLETED_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 37, - MALI_CINSTR_PP_INSTRUCTION_FAILED_RENDEZVOUS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 38, - MALI_CINSTR_PP_INSTRUCTION_FAILED_VARYING_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 39, - MALI_CINSTR_PP_INSTRUCTION_FAILED_TEXTURE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 40, - MALI_CINSTR_PP_INSTRUCTION_FAILED_LOAD_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 41, - MALI_CINSTR_PP_INSTRUCTION_FAILED_TILE_READ_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 42, - MALI_CINSTR_PP_INSTRUCTION_FAILED_STORE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 43, - MALI_CINSTR_PP_RENDEZVOUS_BREAKAGE_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 44, - MALI_CINSTR_PP_PIPELINE_BUBBLES_CYCLE_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 45, - MALI_CINSTR_PP_TEXTURE_MAPPER_MULTIPASS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 46, - MALI_CINSTR_PP_TEXTURE_MAPPER_CYCLE_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 47, - MALI_CINSTR_PP_VERTEX_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 48, - MALI_CINSTR_PP_VERTEX_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 49, - MALI_CINSTR_PP_VARYING_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 50, - MALI_CINSTR_PP_VARYING_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 51, - MALI_CINSTR_PP_VARYING_CACHE_CONFLICT_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 52, - MALI_CINSTR_PP_TEXTURE_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 53, - MALI_CINSTR_PP_TEXTURE_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 54, - MALI_CINSTR_PP_TEXTURE_CACHE_CONFLICT_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 55, - MALI_CINSTR_PP_PALETTE_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 56, /* Mali 200 only */ - MALI_CINSTR_PP_PALETTE_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 57, /* Mali 200 only */ - MALI_CINSTR_PP_COMPRESSED_TEXTURE_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 56, /* Mali 400 class only */ - MALI_CINSTR_PP_COMPRESSED_TEXTURE_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 57, /* Mali 400 class only */ - MALI_CINSTR_PP_LOAD_STORE_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 58, - MALI_CINSTR_PP_LOAD_STORE_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 59, - MALI_CINSTR_PP_PROGRAM_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 60, - MALI_CINSTR_PP_PROGRAM_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 61, - MALI_CINSTR_PP_JOB_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 900, -} cinstr_counters_m200_t; - -#endif /*_MALI_UTGARD_COUNTERS_H_*/ diff --git a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_ioctl.h b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_ioctl.h deleted file mode 100644 index 7935448..0000000 --- a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_ioctl.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_UTGARD_IOCTL_H__ -#define __MALI_UTGARD_IOCTL_H__ - -#include -#include -#include /* file system operations */ - -#ifdef __cplusplus -extern "C" -{ -#endif - -/** - * @file mali_kernel_ioctl.h - * Interface to the Linux device driver. - * This file describes the interface needed to use the Linux device driver. - * Its interface is designed to used by the HAL implementation through a thin arch layer. - */ - -/** - * ioctl commands - */ - -#define MALI_IOC_BASE 0x82 -#define MALI_IOC_CORE_BASE (_MALI_UK_CORE_SUBSYSTEM + MALI_IOC_BASE) -#define MALI_IOC_MEMORY_BASE (_MALI_UK_MEMORY_SUBSYSTEM + MALI_IOC_BASE) -#define MALI_IOC_PP_BASE (_MALI_UK_PP_SUBSYSTEM + MALI_IOC_BASE) -#define MALI_IOC_GP_BASE (_MALI_UK_GP_SUBSYSTEM + MALI_IOC_BASE) -#define MALI_IOC_PROFILING_BASE (_MALI_UK_PROFILING_SUBSYSTEM + MALI_IOC_BASE) -#define MALI_IOC_VSYNC_BASE (_MALI_UK_VSYNC_SUBSYSTEM + MALI_IOC_BASE) - -#define MALI_IOC_WAIT_FOR_NOTIFICATION _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_WAIT_FOR_NOTIFICATION, _mali_uk_wait_for_notification_s *) -#define MALI_IOC_GET_API_VERSION _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_GET_API_VERSION, _mali_uk_get_api_version_s *) -#define MALI_IOC_POST_NOTIFICATION _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_POST_NOTIFICATION, _mali_uk_post_notification_s *) -#define MALI_IOC_GET_USER_SETTING _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_GET_USER_SETTING, _mali_uk_get_user_setting_s *) -#define MALI_IOC_GET_USER_SETTINGS _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_GET_USER_SETTINGS, _mali_uk_get_user_settings_s *) - -#define MALI_IOC_MEM_GET_BIG_BLOCK _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_GET_BIG_BLOCK, void *) -#define MALI_IOC_MEM_FREE_BIG_BLOCK _IOW (MALI_IOC_MEMORY_BASE, _MALI_UK_FREE_BIG_BLOCK, void *) -#define MALI_IOC_MEM_INIT _IOR (MALI_IOC_MEMORY_BASE, _MALI_UK_INIT_MEM, _mali_uk_init_mem_s *) -#define MALI_IOC_MEM_TERM _IOW (MALI_IOC_MEMORY_BASE, _MALI_UK_TERM_MEM, _mali_uk_term_mem_s *) -#define MALI_IOC_MEM_MAP_EXT _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_MAP_EXT_MEM, _mali_uk_map_external_mem_s *) -#define MALI_IOC_MEM_UNMAP_EXT _IOW (MALI_IOC_MEMORY_BASE, _MALI_UK_UNMAP_EXT_MEM, _mali_uk_unmap_external_mem_s *) -#define MALI_IOC_MEM_ATTACH_DMA_BUF _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_ATTACH_DMA_BUF, _mali_uk_attach_dma_buf_s *) -#define MALI_IOC_MEM_RELEASE_DMA_BUF _IOW(MALI_IOC_MEMORY_BASE, _MALI_UK_RELEASE_DMA_BUF, _mali_uk_release_dma_buf_s *) -#define MALI_IOC_MEM_DMA_BUF_GET_SIZE _IOR(MALI_IOC_MEMORY_BASE, _MALI_UK_DMA_BUF_GET_SIZE, _mali_uk_dma_buf_get_size_s *) -#define MALI_IOC_MEM_ATTACH_UMP _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_ATTACH_UMP_MEM, _mali_uk_attach_ump_mem_s *) -#define MALI_IOC_MEM_RELEASE_UMP _IOW(MALI_IOC_MEMORY_BASE, _MALI_UK_RELEASE_UMP_MEM, _mali_uk_release_ump_mem_s *) -#define MALI_IOC_MEM_QUERY_MMU_PAGE_TABLE_DUMP_SIZE _IOR (MALI_IOC_MEMORY_BASE, _MALI_UK_QUERY_MMU_PAGE_TABLE_DUMP_SIZE, _mali_uk_query_mmu_page_table_dump_size_s *) -#define MALI_IOC_MEM_DUMP_MMU_PAGE_TABLE _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_DUMP_MMU_PAGE_TABLE, _mali_uk_dump_mmu_page_table_s *) - -#define MALI_IOC_PP_START_JOB _IOWR(MALI_IOC_PP_BASE, _MALI_UK_PP_START_JOB, _mali_uk_pp_start_job_s *) -#define MALI_IOC_PP_NUMBER_OF_CORES_GET _IOR (MALI_IOC_PP_BASE, _MALI_UK_GET_PP_NUMBER_OF_CORES, _mali_uk_get_pp_number_of_cores_s *) -#define MALI_IOC_PP_CORE_VERSION_GET _IOR (MALI_IOC_PP_BASE, _MALI_UK_GET_PP_CORE_VERSION, _mali_uk_get_pp_core_version_s * ) -#define MALI_IOC_PP_DISABLE_WB _IOW (MALI_IOC_PP_BASE, _MALI_UK_PP_DISABLE_WB, _mali_uk_pp_disable_wb_s * ) - -#define MALI_IOC_GP2_START_JOB _IOWR(MALI_IOC_GP_BASE, _MALI_UK_GP_START_JOB, _mali_uk_gp_start_job_s *) -#define MALI_IOC_GP2_NUMBER_OF_CORES_GET _IOR (MALI_IOC_GP_BASE, _MALI_UK_GET_GP_NUMBER_OF_CORES, _mali_uk_get_gp_number_of_cores_s *) -#define MALI_IOC_GP2_CORE_VERSION_GET _IOR (MALI_IOC_GP_BASE, _MALI_UK_GET_GP_CORE_VERSION, _mali_uk_get_gp_core_version_s *) -#define MALI_IOC_GP2_SUSPEND_RESPONSE _IOW (MALI_IOC_GP_BASE, _MALI_UK_GP_SUSPEND_RESPONSE,_mali_uk_gp_suspend_response_s *) - -#define MALI_IOC_PROFILING_START _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_START, _mali_uk_profiling_start_s *) -#define MALI_IOC_PROFILING_ADD_EVENT _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_ADD_EVENT, _mali_uk_profiling_add_event_s*) -#define MALI_IOC_PROFILING_STOP _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_STOP, _mali_uk_profiling_stop_s *) -#define MALI_IOC_PROFILING_GET_EVENT _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_GET_EVENT, _mali_uk_profiling_get_event_s *) -#define MALI_IOC_PROFILING_CLEAR _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_CLEAR, _mali_uk_profiling_clear_s *) -#define MALI_IOC_PROFILING_GET_CONFIG _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_GET_CONFIG, _mali_uk_get_user_settings_s *) -#define MALI_IOC_PROFILING_REPORT_SW_COUNTERS _IOW (MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_REPORT_SW_COUNTERS, _mali_uk_sw_counters_report_s *) - -#define MALI_IOC_VSYNC_EVENT_REPORT _IOW (MALI_IOC_VSYNC_BASE, _MALI_UK_VSYNC_EVENT_REPORT, _mali_uk_vsync_event_report_s *) - -#ifdef __cplusplus -} -#endif - -#endif /* __MALI_UTGARD_IOCTL_H__ */ diff --git a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_profiling_events.h b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_profiling_events.h deleted file mode 100644 index b96596e..0000000 --- a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_profiling_events.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef _MALI_UTGARD_PROFILING_EVENTS_H_ -#define _MALI_UTGARD_PROFILING_EVENTS_H_ - -/* - * The event ID is a 32 bit value consisting of different fields - * reserved, 4 bits, for future use - * event type, 4 bits, cinstr_profiling_event_type_t - * event channel, 8 bits, the source of the event. - * event data, 16 bit field, data depending on event type - */ - -/** - * Specifies what kind of event this is - */ -typedef enum -{ - MALI_PROFILING_EVENT_TYPE_SINGLE = 0 << 24, - MALI_PROFILING_EVENT_TYPE_START = 1 << 24, - MALI_PROFILING_EVENT_TYPE_STOP = 2 << 24, - MALI_PROFILING_EVENT_TYPE_SUSPEND = 3 << 24, - MALI_PROFILING_EVENT_TYPE_RESUME = 4 << 24, -} cinstr_profiling_event_type_t; - - -/** - * Secifies the channel/source of the event - */ -typedef enum -{ - MALI_PROFILING_EVENT_CHANNEL_SOFTWARE = 0 << 16, - MALI_PROFILING_EVENT_CHANNEL_GP0 = 1 << 16, - MALI_PROFILING_EVENT_CHANNEL_PP0 = 5 << 16, - MALI_PROFILING_EVENT_CHANNEL_PP1 = 6 << 16, - MALI_PROFILING_EVENT_CHANNEL_PP2 = 7 << 16, - MALI_PROFILING_EVENT_CHANNEL_PP3 = 8 << 16, - MALI_PROFILING_EVENT_CHANNEL_PP4 = 9 << 16, - MALI_PROFILING_EVENT_CHANNEL_PP5 = 10 << 16, - MALI_PROFILING_EVENT_CHANNEL_PP6 = 11 << 16, - MALI_PROFILING_EVENT_CHANNEL_PP7 = 12 << 16, - MALI_PROFILING_EVENT_CHANNEL_GPU = 21 << 16, -} cinstr_profiling_event_channel_t; - - -#define MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(num) (((MALI_PROFILING_EVENT_CHANNEL_GP0 >> 16) + (num)) << 16) -#define MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(num) (((MALI_PROFILING_EVENT_CHANNEL_PP0 >> 16) + (num)) << 16) - -/** - * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SINGLE is used from software channel - */ -typedef enum -{ - MALI_PROFILING_EVENT_REASON_SINGLE_SW_NONE = 0, - MALI_PROFILING_EVENT_REASON_SINGLE_SW_EGL_NEW_FRAME = 1, - MALI_PROFILING_EVENT_REASON_SINGLE_SW_FLUSH = 2, - MALI_PROFILING_EVENT_REASON_SINGLE_SW_EGL_SWAP_BUFFERS = 3, - MALI_PROFILING_EVENT_REASON_SINGLE_SW_FB_EVENT = 4, - MALI_PROFILING_EVENT_REASON_SINGLE_SW_GP_ENQUEUE = 5, - MALI_PROFILING_EVENT_REASON_SINGLE_SW_PP_ENQUEUE = 6, - MALI_PROFILING_EVENT_REASON_SINGLE_SW_ENTER_API_FUNC = 10, - MALI_PROFILING_EVENT_REASON_SINGLE_SW_LEAVE_API_FUNC = 11, - MALI_PROFILING_EVENT_REASON_SINGLE_SW_UMP_TRY_LOCK = 53, - MALI_PROFILING_EVENT_REASON_SINGLE_SW_UMP_LOCK = 54, - MALI_PROFILING_EVENT_REASON_SINGLE_SW_UMP_UNLOCK = 55, -} cinstr_profiling_event_reason_single_sw_t; - -/** - * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_START/STOP is used from software channel - */ -typedef enum -{ - MALI_PROFILING_EVENT_REASON_START_STOP_SW_NONE = 0, - MALI_PROFILING_EVENT_REASON_START_STOP_MALI = 1, -} cinstr_profiling_event_reason_start_stop_sw_t; - -/** - * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SUSPEND/RESUME is used from software channel - */ -typedef enum -{ - MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_NONE = 0, /* NOT used */ - MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_PIPELINE_FULL = 1, /* NOT used */ - MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VSYNC = 26, /* used in some build configurations */ - MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_FB_IFRAME_WAIT = 27, /* USED */ - MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_FB_IFRAME_SYNC = 28, /* USED */ - MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VG_WAIT_FILTER_CLEANUP = 29, /* used */ - MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VG_WAIT_TEXTURE = 30, /* used */ - MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_GLES_WAIT_MIPLEVEL = 31, /* used */ - MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_GLES_WAIT_READPIXELS = 32, /* used */ - MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_EGL_WAIT_SWAP_IMMEDIATE= 33, /* NOT used */ - MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_ICS_QUEUE_BUFFER = 34, /* USED */ - MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_ICS_DEQUEUE_BUFFER = 35, /* USED */ - MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_UMP_LOCK = 36, /* Not currently used */ - MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_X11_GLOBAL_LOCK = 37, /* Not currently used */ - MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_X11_SWAP = 38, /* Not currently used */ - MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_MALI_EGL_IMAGE_SYNC_WAIT = 39, /* USED */ -} cinstr_profiling_event_reason_suspend_resume_sw_t; - -/** - * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SINGLE is used from a HW channel (GPx+PPx) - */ -typedef enum -{ - MALI_PROFILING_EVENT_REASON_SINGLE_HW_NONE = 0, - MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT = 1, - MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH = 2, -} cinstr_profiling_event_reason_single_hw_t; - -/** - * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SINGLE is used from the GPU channel - */ -typedef enum -{ - MALI_PROFILING_EVENT_REASON_SINGLE_GPU_NONE = 0, - MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE = 1, -} cinstr_profiling_event_reason_single_gpu_t; - -#endif /*_MALI_UTGARD_PROFILING_EVENTS_H_*/ diff --git a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_uk_types.h b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_uk_types.h deleted file mode 100644 index b35a715..0000000 --- a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_uk_types.h +++ /dev/null @@ -1,1095 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_uk_types.h - * Defines the types and constants used in the user-kernel interface - */ - -#ifndef __MALI_UTGARD_UK_TYPES_H__ -#define __MALI_UTGARD_UK_TYPES_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -/** - * @addtogroup uddapi Unified Device Driver (UDD) APIs - * - * @{ - */ - -/** - * @addtogroup u_k_api UDD User/Kernel Interface (U/K) APIs - * - * @{ - */ - -/** @defgroup _mali_uk_core U/K Core - * @{ */ - -/** Definition of subsystem numbers, to assist in creating a unique identifier - * for each U/K call. - * - * @see _mali_uk_functions */ -typedef enum -{ - _MALI_UK_CORE_SUBSYSTEM, /**< Core Group of U/K calls */ - _MALI_UK_MEMORY_SUBSYSTEM, /**< Memory Group of U/K calls */ - _MALI_UK_PP_SUBSYSTEM, /**< Fragment Processor Group of U/K calls */ - _MALI_UK_GP_SUBSYSTEM, /**< Vertex Processor Group of U/K calls */ - _MALI_UK_PROFILING_SUBSYSTEM, /**< Profiling Group of U/K calls */ - _MALI_UK_PMM_SUBSYSTEM, /**< Power Management Module Group of U/K calls */ - _MALI_UK_VSYNC_SUBSYSTEM, /**< VSYNC Group of U/K calls */ -} _mali_uk_subsystem_t; - -/** Within a function group each function has its unique sequence number - * to assist in creating a unique identifier for each U/K call. - * - * An ordered pair of numbers selected from - * ( \ref _mali_uk_subsystem_t,\ref _mali_uk_functions) will uniquely identify the - * U/K call across all groups of functions, and all functions. */ -typedef enum -{ - /** Core functions */ - - _MALI_UK_OPEN = 0, /**< _mali_ukk_open() */ - _MALI_UK_CLOSE, /**< _mali_ukk_close() */ - _MALI_UK_WAIT_FOR_NOTIFICATION, /**< _mali_ukk_wait_for_notification() */ - _MALI_UK_GET_API_VERSION, /**< _mali_ukk_get_api_version() */ - _MALI_UK_POST_NOTIFICATION, /**< _mali_ukk_post_notification() */ - _MALI_UK_GET_USER_SETTING, /**< _mali_ukk_get_user_setting() *//**< [out] */ - _MALI_UK_GET_USER_SETTINGS, /**< _mali_ukk_get_user_settings() *//**< [out] */ - - /** Memory functions */ - - _MALI_UK_INIT_MEM = 0, /**< _mali_ukk_init_mem() */ - _MALI_UK_TERM_MEM, /**< _mali_ukk_term_mem() */ - _MALI_UK_GET_BIG_BLOCK, /**< _mali_ukk_get_big_block() */ - _MALI_UK_FREE_BIG_BLOCK, /**< _mali_ukk_free_big_block() */ - _MALI_UK_MAP_MEM, /**< _mali_ukk_mem_mmap() */ - _MALI_UK_UNMAP_MEM, /**< _mali_ukk_mem_munmap() */ - _MALI_UK_QUERY_MMU_PAGE_TABLE_DUMP_SIZE, /**< _mali_ukk_mem_get_mmu_page_table_dump_size() */ - _MALI_UK_DUMP_MMU_PAGE_TABLE, /**< _mali_ukk_mem_dump_mmu_page_table() */ - _MALI_UK_ATTACH_DMA_BUF, /**< _mali_ukk_attach_dma_buf() */ - _MALI_UK_RELEASE_DMA_BUF, /**< _mali_ukk_release_dma_buf() */ - _MALI_UK_DMA_BUF_GET_SIZE, /**< _mali_ukk_dma_buf_get_size() */ - _MALI_UK_ATTACH_UMP_MEM, /**< _mali_ukk_attach_ump_mem() */ - _MALI_UK_RELEASE_UMP_MEM, /**< _mali_ukk_release_ump_mem() */ - _MALI_UK_MAP_EXT_MEM, /**< _mali_uku_map_external_mem() */ - _MALI_UK_UNMAP_EXT_MEM, /**< _mali_uku_unmap_external_mem() */ - _MALI_UK_VA_TO_MALI_PA, /**< _mali_uku_va_to_mali_pa() */ - - /** Common functions for each core */ - - _MALI_UK_START_JOB = 0, /**< Start a Fragment/Vertex Processor Job on a core */ - _MALI_UK_GET_NUMBER_OF_CORES, /**< Get the number of Fragment/Vertex Processor cores */ - _MALI_UK_GET_CORE_VERSION, /**< Get the Fragment/Vertex Processor version compatible with all cores */ - - /** Fragment Processor Functions */ - - _MALI_UK_PP_START_JOB = _MALI_UK_START_JOB, /**< _mali_ukk_pp_start_job() */ - _MALI_UK_GET_PP_NUMBER_OF_CORES = _MALI_UK_GET_NUMBER_OF_CORES, /**< _mali_ukk_get_pp_number_of_cores() */ - _MALI_UK_GET_PP_CORE_VERSION = _MALI_UK_GET_CORE_VERSION, /**< _mali_ukk_get_pp_core_version() */ - _MALI_UK_PP_DISABLE_WB, /**< _mali_ukk_pp_job_disable_wb() */ - - /** Vertex Processor Functions */ - - _MALI_UK_GP_START_JOB = _MALI_UK_START_JOB, /**< _mali_ukk_gp_start_job() */ - _MALI_UK_GET_GP_NUMBER_OF_CORES = _MALI_UK_GET_NUMBER_OF_CORES, /**< _mali_ukk_get_gp_number_of_cores() */ - _MALI_UK_GET_GP_CORE_VERSION = _MALI_UK_GET_CORE_VERSION, /**< _mali_ukk_get_gp_core_version() */ - _MALI_UK_GP_SUSPEND_RESPONSE, /**< _mali_ukk_gp_suspend_response() */ - - /** Profiling functions */ - - _MALI_UK_PROFILING_START = 0, /**< __mali_uku_profiling_start() */ - _MALI_UK_PROFILING_ADD_EVENT, /**< __mali_uku_profiling_add_event() */ - _MALI_UK_PROFILING_STOP, /**< __mali_uku_profiling_stop() */ - _MALI_UK_PROFILING_GET_EVENT, /**< __mali_uku_profiling_get_event() */ - _MALI_UK_PROFILING_CLEAR, /**< __mali_uku_profiling_clear() */ - _MALI_UK_PROFILING_GET_CONFIG, /**< __mali_uku_profiling_get_config() */ - _MALI_UK_PROFILING_REPORT_SW_COUNTERS,/**< __mali_uku_profiling_report_sw_counters() */ - - /** VSYNC reporting fuctions */ - _MALI_UK_VSYNC_EVENT_REPORT = 0, /**< _mali_ukk_vsync_event_report() */ - -} _mali_uk_functions; - -/** @brief Get the size necessary for system info - * - * @see _mali_ukk_get_system_info_size() - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 size; /**< [out] size of buffer necessary to hold system information data, in bytes */ -} _mali_uk_get_system_info_size_s; - - -/** @defgroup _mali_uk_getsysteminfo U/K Get System Info - * @{ */ - -/** - * Type definition for the core version number. - * Used when returning the version number read from a core - * - * Its format is that of the 32-bit Version register for a particular core. - * Refer to the "Mali200 and MaliGP2 3D Graphics Processor Technical Reference - * Manual", ARM DDI 0415C, for more information. - */ -typedef u32 _mali_core_version; - -/** - * Enum values for the different modes the driver can be put in. - * Normal is the default mode. The driver then uses a job queue and takes job objects from the clients. - * Job completion is reported using the _mali_ukk_wait_for_notification call. - * The driver blocks this io command until a job has completed or failed or a timeout occurs. - * - * The 'raw' mode is reserved for future expansion. - */ -typedef enum _mali_driver_mode -{ - _MALI_DRIVER_MODE_RAW = 1, /**< Reserved for future expansion */ - _MALI_DRIVER_MODE_NORMAL = 2 /**< Normal mode of operation */ -} _mali_driver_mode; - -/** @brief List of possible cores - * - * add new entries to the end of this enum */ -typedef enum _mali_core_type -{ - _MALI_GP2 = 2, /**< MaliGP2 Programmable Vertex Processor */ - _MALI_200 = 5, /**< Mali200 Programmable Fragment Processor */ - _MALI_400_GP = 6, /**< Mali400 Programmable Vertex Processor */ - _MALI_400_PP = 7, /**< Mali400 Programmable Fragment Processor */ - /* insert new core here, do NOT alter the existing values */ -} _mali_core_type; - - -/** @brief Capabilities of Memory Banks - * - * These may be used to restrict memory banks for certain uses. They may be - * used when access is not possible (e.g. Bus does not support access to it) - * or when access is possible but not desired (e.g. Access is slow). - * - * In the case of 'possible but not desired', there is no way of specifying - * the flags as an optimization hint, so that the memory could be used as a - * last resort. - * - * @see _mali_mem_info - */ -typedef enum _mali_bus_usage -{ - - _MALI_PP_READABLE = (1<<0), /** Readable by the Fragment Processor */ - _MALI_PP_WRITEABLE = (1<<1), /** Writeable by the Fragment Processor */ - _MALI_GP_READABLE = (1<<2), /** Readable by the Vertex Processor */ - _MALI_GP_WRITEABLE = (1<<3), /** Writeable by the Vertex Processor */ - _MALI_CPU_READABLE = (1<<4), /** Readable by the CPU */ - _MALI_CPU_WRITEABLE = (1<<5), /** Writeable by the CPU */ - _MALI_GP_L2_ALLOC = (1<<6), /** GP allocate mali L2 cache lines*/ - _MALI_MMU_READABLE = _MALI_PP_READABLE | _MALI_GP_READABLE, /** Readable by the MMU (including all cores behind it) */ - _MALI_MMU_WRITEABLE = _MALI_PP_WRITEABLE | _MALI_GP_WRITEABLE, /** Writeable by the MMU (including all cores behind it) */ -} _mali_bus_usage; - -typedef enum mali_memory_cache_settings -{ - MALI_CACHE_STANDARD = 0, - MALI_CACHE_GP_READ_ALLOCATE = 1, -} mali_memory_cache_settings ; - - -/** @brief Information about the Mali Memory system - * - * Information is stored in a linked list, which is stored entirely in the - * buffer pointed to by the system_info member of the - * _mali_uk_get_system_info_s arguments provided to _mali_ukk_get_system_info() - * - * Each element of the linked list describes a single Mali Memory bank. - * Each allocation can only come from one bank, and will not cross multiple - * banks. - * - * On Mali-MMU systems, there is only one bank, which describes the maximum - * possible address range that could be allocated (which may be much less than - * the available physical memory) - * - * The flags member describes the capabilities of the memory. It is an error - * to attempt to build a job for a particular core (PP or GP) when the memory - * regions used do not have the capabilities for supporting that core. This - * would result in a job abort from the Device Driver. - * - * For example, it is correct to build a PP job where read-only data structures - * are taken from a memory with _MALI_PP_READABLE set and - * _MALI_PP_WRITEABLE clear, and a framebuffer with _MALI_PP_WRITEABLE set and - * _MALI_PP_READABLE clear. However, it would be incorrect to use a framebuffer - * where _MALI_PP_WRITEABLE is clear. - */ -typedef struct _mali_mem_info -{ - u32 size; /**< Size of the memory bank in bytes */ - _mali_bus_usage flags; /**< Capabilitiy flags of the memory */ - u32 maximum_order_supported; /**< log2 supported size */ - u32 identifier; /* mali_memory_cache_settings cache_settings; */ - struct _mali_mem_info * next; /**< Next List Link */ -} _mali_mem_info; - - - -/** @} */ /* end group _mali_uk_core */ - - -/** @defgroup _mali_uk_gp U/K Vertex Processor - * @{ */ - -/** @defgroup _mali_uk_gp_suspend_response_s Vertex Processor Suspend Response - * @{ */ - -/** @brief Arguments for _mali_ukk_gp_suspend_response() - * - * When _mali_wait_for_notification() receives notification that a - * Vertex Processor job was suspended, you need to send a response to indicate - * what needs to happen with this job. You can either abort or resume the job. - * - * - set @c code to indicate response code. This is either @c _MALIGP_JOB_ABORT or - * @c _MALIGP_JOB_RESUME_WITH_NEW_HEAP to indicate you will provide a new heap - * for the job that will resolve the out of memory condition for the job. - * - copy the @c cookie value from the @c _mali_uk_gp_job_suspended_s notification; - * this is an identifier for the suspended job - * - set @c arguments[0] and @c arguments[1] to zero if you abort the job. If - * you resume it, @c argument[0] should specify the Mali start address for the new - * heap and @c argument[1] the Mali end address of the heap. - * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open() - * - */ -typedef enum _maligp_job_suspended_response_code -{ - _MALIGP_JOB_ABORT, /**< Abort the Vertex Processor job */ - _MALIGP_JOB_RESUME_WITH_NEW_HEAP /**< Resume the Vertex Processor job with a new heap */ -} _maligp_job_suspended_response_code; - -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 cookie; /**< [in] cookie from the _mali_uk_gp_job_suspended_s notification */ - _maligp_job_suspended_response_code code; /**< [in] abort or resume response code, see \ref _maligp_job_suspended_response_code */ - u32 arguments[2]; /**< [in] 0 when aborting a job. When resuming a job, the Mali start and end address for a new heap to resume the job with */ -} _mali_uk_gp_suspend_response_s; - -/** @} */ /* end group _mali_uk_gp_suspend_response_s */ - -/** @defgroup _mali_uk_gpstartjob_s Vertex Processor Start Job - * @{ */ - -/** @brief Status indicating the result of starting a Vertex or Fragment processor job */ -typedef enum -{ - _MALI_UK_START_JOB_STARTED, /**< Job started */ - _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE /**< Job could not be started at this time. Try starting the job again */ -} _mali_uk_start_job_status; - -/** @brief Status indicating the result of the execution of a Vertex or Fragment processor job */ - -typedef enum -{ - _MALI_UK_JOB_STATUS_END_SUCCESS = 1<<(16+0), - _MALI_UK_JOB_STATUS_END_OOM = 1<<(16+1), - _MALI_UK_JOB_STATUS_END_ABORT = 1<<(16+2), - _MALI_UK_JOB_STATUS_END_TIMEOUT_SW = 1<<(16+3), - _MALI_UK_JOB_STATUS_END_HANG = 1<<(16+4), - _MALI_UK_JOB_STATUS_END_SEG_FAULT = 1<<(16+5), - _MALI_UK_JOB_STATUS_END_ILLEGAL_JOB = 1<<(16+6), - _MALI_UK_JOB_STATUS_END_UNKNOWN_ERR = 1<<(16+7), - _MALI_UK_JOB_STATUS_END_SHUTDOWN = 1<<(16+8), - _MALI_UK_JOB_STATUS_END_SYSTEM_UNUSABLE = 1<<(16+9) -} _mali_uk_job_status; - -#define MALIGP2_NUM_REGS_FRAME (6) - -/** @brief Arguments for _mali_ukk_gp_start_job() - * - * To start a Vertex Processor job - * - associate the request with a reference to a @c mali_gp_job_info by setting - * user_job_ptr to the address of the @c mali_gp_job_info of the job. - * - set @c priority to the priority of the @c mali_gp_job_info - * - specify a timeout for the job by setting @c watchdog_msecs to the number of - * milliseconds the job is allowed to run. Specifying a value of 0 selects the - * default timeout in use by the device driver. - * - copy the frame registers from the @c mali_gp_job_info into @c frame_registers. - * - set the @c perf_counter_flag, @c perf_counter_src0 and @c perf_counter_src1 to zero - * for a non-instrumented build. For an instrumented build you can use up - * to two performance counters. Set the corresponding bit in @c perf_counter_flag - * to enable them. @c perf_counter_src0 and @c perf_counter_src1 specify - * the source of what needs to get counted (e.g. number of vertex loader - * cache hits). For source id values, see ARM DDI0415A, Table 3-60. - * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open() - * - * When @c _mali_ukk_gp_start_job() returns @c _MALI_OSK_ERR_OK, status contains the - * result of the request (see \ref _mali_uk_start_job_status). If the job could - * not get started (@c _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE) it should be - * tried again. - * - * After the job has started, @c _mali_wait_for_notification() will be notified - * that the job finished or got suspended. It may get suspended due to - * resource shortage. If it finished (see _mali_ukk_wait_for_notification()) - * the notification will contain a @c _mali_uk_gp_job_finished_s result. If - * it got suspended the notification will contain a @c _mali_uk_gp_job_suspended_s - * result. - * - * The @c _mali_uk_gp_job_finished_s contains the job status (see \ref _mali_uk_job_status), - * the number of milliseconds the job took to render, and values of core registers - * when the job finished (irq status, performance counters, renderer list - * address). A job has finished succesfully when its status is - * @c _MALI_UK_JOB_STATUS_FINISHED. If the hardware detected a timeout while rendering - * the job, or software detected the job is taking more than watchdog_msecs to - * complete, the status will indicate @c _MALI_UK_JOB_STATUS_HANG. - * If the hardware detected a bus error while accessing memory associated with the - * job, status will indicate @c _MALI_UK_JOB_STATUS_SEG_FAULT. - * status will indicate @c _MALI_UK_JOB_STATUS_NOT_STARTED if the driver had to - * stop the job but the job didn't start on the hardware yet, e.g. when the - * driver shutdown. - * - * In case the job got suspended, @c _mali_uk_gp_job_suspended_s contains - * the @c user_job_ptr identifier used to start the job with, the @c reason - * why the job stalled (see \ref _maligp_job_suspended_reason) and a @c cookie - * to identify the core on which the job stalled. This @c cookie will be needed - * when responding to this nofication by means of _mali_ukk_gp_suspend_response(). - * (see _mali_ukk_gp_suspend_response()). The response is either to abort or - * resume the job. If the job got suspended due to an out of memory condition - * you may be able to resolve this by providing more memory and resuming the job. - * - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 user_job_ptr; /**< [in] identifier for the job in user space, a @c mali_gp_job_info* */ - u32 priority; /**< [in] job priority. A lower number means higher priority */ - u32 frame_registers[MALIGP2_NUM_REGS_FRAME]; /**< [in] core specific registers associated with this job */ - u32 perf_counter_flag; /**< [in] bitmask indicating which performance counters to enable, see \ref _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE and related macro definitions */ - u32 perf_counter_src0; /**< [in] source id for performance counter 0 (see ARM DDI0415A, Table 3-60) */ - u32 perf_counter_src1; /**< [in] source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */ - u32 frame_builder_id; /**< [in] id of the originating frame builder */ - u32 flush_id; /**< [in] flush id within the originating frame builder */ -} _mali_uk_gp_start_job_s; - -#define _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE (1<<0) /**< Enable performance counter SRC0 for a job */ -#define _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE (1<<1) /**< Enable performance counter SRC1 for a job */ - -/** @} */ /* end group _mali_uk_gpstartjob_s */ - -typedef struct -{ - u32 user_job_ptr; /**< [out] identifier for the job in user space */ - _mali_uk_job_status status; /**< [out] status of finished job */ - u32 heap_current_addr; /**< [out] value of the GP PLB PL heap start address register */ - u32 perf_counter0; /**< [out] value of perfomance counter 0 (see ARM DDI0415A) */ - u32 perf_counter1; /**< [out] value of perfomance counter 1 (see ARM DDI0415A) */ -} _mali_uk_gp_job_finished_s; - -typedef enum _maligp_job_suspended_reason -{ - _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY /**< Polygon list builder unit (PLBU) has run out of memory */ -} _maligp_job_suspended_reason; - -typedef struct -{ - u32 user_job_ptr; /**< [out] identifier for the job in user space */ - _maligp_job_suspended_reason reason; /**< [out] reason why the job stalled */ - u32 cookie; /**< [out] identifier for the core in kernel space on which the job stalled */ -} _mali_uk_gp_job_suspended_s; - -/** @} */ /* end group _mali_uk_gp */ - - -/** @defgroup _mali_uk_pp U/K Fragment Processor - * @{ */ - -#define _MALI_PP_MAX_SUB_JOBS 8 - -#define _MALI_PP_MAX_FRAME_REGISTERS ((0x058/4)+1) - -#define _MALI_PP_MAX_WB_REGISTERS ((0x02C/4)+1) - -/** Flag for _mali_uk_pp_start_job_s */ -#define _MALI_PP_JOB_FLAG_NO_NOTIFICATION (1<<0) -#define _MALI_PP_JOB_FLAG_BARRIER (1<<1) - -/** @defgroup _mali_uk_ppstartjob_s Fragment Processor Start Job - * @{ */ - -/** @brief Arguments for _mali_ukk_pp_start_job() - * - * To start a Fragment Processor job - * - associate the request with a reference to a mali_pp_job by setting - * @c user_job_ptr to the address of the @c mali_pp_job of the job. - * - set @c priority to the priority of the mali_pp_job - * - specify a timeout for the job by setting @c watchdog_msecs to the number of - * milliseconds the job is allowed to run. Specifying a value of 0 selects the - * default timeout in use by the device driver. - * - copy the frame registers from the @c mali_pp_job into @c frame_registers. - * For MALI200 you also need to copy the write back 0,1 and 2 registers. - * - set the @c perf_counter_flag, @c perf_counter_src0 and @c perf_counter_src1 to zero - * for a non-instrumented build. For an instrumented build you can use up - * to two performance counters. Set the corresponding bit in @c perf_counter_flag - * to enable them. @c perf_counter_src0 and @c perf_counter_src1 specify - * the source of what needs to get counted (e.g. number of vertex loader - * cache hits). For source id values, see ARM DDI0415A, Table 3-60. - * - pass in the user-kernel context in @c ctx that was returned from _mali_ukk_open() - * - * When _mali_ukk_pp_start_job() returns @c _MALI_OSK_ERR_OK, @c status contains the - * result of the request (see \ref _mali_uk_start_job_status). If the job could - * not get started (@c _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE) it should be - * tried again. - * - * After the job has started, _mali_wait_for_notification() will be notified - * when the job finished. The notification will contain a - * @c _mali_uk_pp_job_finished_s result. It contains the @c user_job_ptr - * identifier used to start the job with, the job @c status (see \ref _mali_uk_job_status), - * the number of milliseconds the job took to render, and values of core registers - * when the job finished (irq status, performance counters, renderer list - * address). A job has finished succesfully when its status is - * @c _MALI_UK_JOB_STATUS_FINISHED. If the hardware detected a timeout while rendering - * the job, or software detected the job is taking more than @c watchdog_msecs to - * complete, the status will indicate @c _MALI_UK_JOB_STATUS_HANG. - * If the hardware detected a bus error while accessing memory associated with the - * job, status will indicate @c _MALI_UK_JOB_STATUS_SEG_FAULT. - * status will indicate @c _MALI_UK_JOB_STATUS_NOT_STARTED if the driver had to - * stop the job but the job didn't start on the hardware yet, e.g. when the - * driver shutdown. - * - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 user_job_ptr; /**< [in] identifier for the job in user space */ - u32 priority; /**< [in] job priority. A lower number means higher priority */ - u32 frame_registers[_MALI_PP_MAX_FRAME_REGISTERS]; /**< [in] core specific registers associated with first sub job, see ARM DDI0415A */ - u32 frame_registers_addr_frame[_MALI_PP_MAX_SUB_JOBS - 1]; /**< [in] ADDR_FRAME registers for sub job 1-7 */ - u32 frame_registers_addr_stack[_MALI_PP_MAX_SUB_JOBS - 1]; /**< [in] ADDR_STACK registers for sub job 1-7 */ - u32 wb0_registers[_MALI_PP_MAX_WB_REGISTERS]; - u32 wb1_registers[_MALI_PP_MAX_WB_REGISTERS]; - u32 wb2_registers[_MALI_PP_MAX_WB_REGISTERS]; - u32 num_cores; /**< [in] Number of cores to set up (valid range: 1-4) */ - u32 perf_counter_flag; /**< [in] bitmask indicating which performance counters to enable, see \ref _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE and related macro definitions */ - u32 perf_counter_src0; /**< [in] source id for performance counter 0 (see ARM DDI0415A, Table 3-60) */ - u32 perf_counter_src1; /**< [in] source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */ - u32 frame_builder_id; /**< [in] id of the originating frame builder */ - u32 flush_id; /**< [in] flush id within the originating frame builder */ - u32 flags; /**< [in] See _MALI_PP_JOB_FLAG_* for a list of avaiable flags */ -} _mali_uk_pp_start_job_s; -/** @} */ /* end group _mali_uk_ppstartjob_s */ - -typedef struct -{ - u32 user_job_ptr; /**< [out] identifier for the job in user space */ - _mali_uk_job_status status; /**< [out] status of finished job */ - u32 perf_counter0[_MALI_PP_MAX_SUB_JOBS]; /**< [out] value of perfomance counter 0 (see ARM DDI0415A), one for each sub job */ - u32 perf_counter1[_MALI_PP_MAX_SUB_JOBS]; /**< [out] value of perfomance counter 1 (see ARM DDI0415A), one for each sub job */ -} _mali_uk_pp_job_finished_s; - -/** - * Flags to indicate write-back units - */ -typedef enum -{ - _MALI_UK_PP_JOB_WB0 = 1, - _MALI_UK_PP_JOB_WB1 = 2, - _MALI_UK_PP_JOB_WB2 = 4, -} _mali_uk_pp_job_wbx_flag; - -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 fb_id; /**< [in] Frame builder ID of job to disable WB units for */ - u32 flush_id; /**< [in] Flush ID of job to disable WB units for */ - _mali_uk_pp_job_wbx_flag wbx; /**< [in] write-back units to disable */ -} _mali_uk_pp_disable_wb_s; - - -/** @} */ /* end group _mali_uk_pp */ - - -/** @addtogroup _mali_uk_core U/K Core - * @{ */ - -/** @defgroup _mali_uk_waitfornotification_s Wait For Notification - * @{ */ - -/** @brief Notification type encodings - * - * Each Notification type is an ordered pair of (subsystem,id), and is unique. - * - * The encoding of subsystem,id into a 32-bit word is: - * encoding = (( subsystem << _MALI_NOTIFICATION_SUBSYSTEM_SHIFT ) & _MALI_NOTIFICATION_SUBSYSTEM_MASK) - * | (( id << _MALI_NOTIFICATION_ID_SHIFT ) & _MALI_NOTIFICATION_ID_MASK) - * - * @see _mali_uk_wait_for_notification_s - */ -typedef enum -{ - /** core notifications */ - - _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS = (_MALI_UK_CORE_SUBSYSTEM << 16) | 0x20, - _MALI_NOTIFICATION_APPLICATION_QUIT = (_MALI_UK_CORE_SUBSYSTEM << 16) | 0x40, - _MALI_NOTIFICATION_SETTINGS_CHANGED = (_MALI_UK_CORE_SUBSYSTEM << 16) | 0x80, - - /** Fragment Processor notifications */ - - _MALI_NOTIFICATION_PP_FINISHED = (_MALI_UK_PP_SUBSYSTEM << 16) | 0x10, - - /** Vertex Processor notifications */ - - _MALI_NOTIFICATION_GP_FINISHED = (_MALI_UK_GP_SUBSYSTEM << 16) | 0x10, - _MALI_NOTIFICATION_GP_STALLED = (_MALI_UK_GP_SUBSYSTEM << 16) | 0x20, - -} _mali_uk_notification_type; - -/** to assist in splitting up 32-bit notification value in subsystem and id value */ -#define _MALI_NOTIFICATION_SUBSYSTEM_MASK 0xFFFF0000 -#define _MALI_NOTIFICATION_SUBSYSTEM_SHIFT 16 -#define _MALI_NOTIFICATION_ID_MASK 0x0000FFFF -#define _MALI_NOTIFICATION_ID_SHIFT 0 - - -/** @brief Enumeration of possible settings which match mali_setting_t in user space - * - * - */ -typedef enum -{ - _MALI_UK_USER_SETTING_SW_EVENTS_ENABLE = 0, - _MALI_UK_USER_SETTING_COLORBUFFER_CAPTURE_ENABLED, - _MALI_UK_USER_SETTING_DEPTHBUFFER_CAPTURE_ENABLED, - _MALI_UK_USER_SETTING_STENCILBUFFER_CAPTURE_ENABLED, - _MALI_UK_USER_SETTING_PER_TILE_COUNTERS_CAPTURE_ENABLED, - _MALI_UK_USER_SETTING_BUFFER_CAPTURE_COMPOSITOR, - _MALI_UK_USER_SETTING_BUFFER_CAPTURE_WINDOW, - _MALI_UK_USER_SETTING_BUFFER_CAPTURE_OTHER, - _MALI_UK_USER_SETTING_BUFFER_CAPTURE_N_FRAMES, - _MALI_UK_USER_SETTING_BUFFER_CAPTURE_RESIZE_FACTOR, - _MALI_UK_USER_SETTING_SW_COUNTER_ENABLED, - _MALI_UK_USER_SETTING_MAX, -} _mali_uk_user_setting_t; - -/* See mali_user_settings_db.c */ -extern const char *_mali_uk_user_setting_descriptions[]; -#define _MALI_UK_USER_SETTING_DESCRIPTIONS \ -{ \ - "sw_events_enable", \ - "colorbuffer_capture_enable", \ - "depthbuffer_capture_enable", \ - "stencilbuffer_capture_enable", \ - "per_tile_counters_enable", \ - "buffer_capture_compositor", \ - "buffer_capture_window", \ - "buffer_capture_other", \ - "buffer_capture_n_frames", \ - "buffer_capture_resize_factor", \ - "sw_counters_enable", \ -}; - -/** @brief struct to hold the value to a particular setting as seen in the kernel space - */ -typedef struct -{ - _mali_uk_user_setting_t setting; - u32 value; -} _mali_uk_settings_changed_s; - -/** @brief Arguments for _mali_ukk_wait_for_notification() - * - * On successful return from _mali_ukk_wait_for_notification(), the members of - * this structure will indicate the reason for notification. - * - * Specifically, the source of the notification can be identified by the - * subsystem and id fields of the mali_uk_notification_type in the code.type - * member. The type member is encoded in a way to divide up the types into a - * subsystem field, and a per-subsystem ID field. See - * _mali_uk_notification_type for more information. - * - * Interpreting the data union member depends on the notification type: - * - * - type == _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS - * - The kernel side is shutting down. No further - * _mali_uk_wait_for_notification() calls should be made. - * - In this case, the value of the data union member is undefined. - * - This is used to indicate to the user space client that it should close - * the connection to the Mali Device Driver. - * - type == _MALI_NOTIFICATION_PP_FINISHED - * - The notification data is of type _mali_uk_pp_job_finished_s. It contains the user_job_ptr - * identifier used to start the job with, the job status, the number of milliseconds the job took to render, - * and values of core registers when the job finished (irq status, performance counters, renderer list - * address). - * - A job has finished succesfully when its status member is _MALI_UK_JOB_STATUS_FINISHED. - * - If the hardware detected a timeout while rendering the job, or software detected the job is - * taking more than watchdog_msecs (see _mali_ukk_pp_start_job()) to complete, the status member will - * indicate _MALI_UK_JOB_STATUS_HANG. - * - If the hardware detected a bus error while accessing memory associated with the job, status will - * indicate _MALI_UK_JOB_STATUS_SEG_FAULT. - * - Status will indicate MALI_UK_JOB_STATUS_NOT_STARTED if the driver had to stop the job but the job - * didn't start the hardware yet, e.g. when the driver closes. - * - type == _MALI_NOTIFICATION_GP_FINISHED - * - The notification data is of type _mali_uk_gp_job_finished_s. The notification is similar to that of - * type == _MALI_NOTIFICATION_PP_FINISHED, except that several other GP core register values are returned. - * The status values have the same meaning for type == _MALI_NOTIFICATION_PP_FINISHED. - * - type == _MALI_NOTIFICATION_GP_STALLED - * - The nofication data is of type _mali_uk_gp_job_suspended_s. It contains the user_job_ptr - * identifier used to start the job with, the reason why the job stalled and a cookie to identify the core on - * which the job stalled. - * - The reason member of gp_job_suspended is set to _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY - * when the polygon list builder unit has run out of memory. - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - _mali_uk_notification_type type; /**< [out] Type of notification available */ - union - { - _mali_uk_gp_job_suspended_s gp_job_suspended;/**< [out] Notification data for _MALI_NOTIFICATION_GP_STALLED notification type */ - _mali_uk_gp_job_finished_s gp_job_finished; /**< [out] Notification data for _MALI_NOTIFICATION_GP_FINISHED notification type */ - _mali_uk_pp_job_finished_s pp_job_finished; /**< [out] Notification data for _MALI_NOTIFICATION_PP_FINISHED notification type */ - _mali_uk_settings_changed_s setting_changed;/**< [out] Notification data for _MALI_NOTIFICAATION_SETTINGS_CHANGED notification type */ - } data; -} _mali_uk_wait_for_notification_s; - -/** @brief Arguments for _mali_ukk_post_notification() - * - * Posts the specified notification to the notification queue for this application. - * This is used to send a quit message to the callback thread. - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - _mali_uk_notification_type type; /**< [in] Type of notification to post */ -} _mali_uk_post_notification_s; - -/** @} */ /* end group _mali_uk_waitfornotification_s */ - -/** @defgroup _mali_uk_getapiversion_s Get API Version - * @{ */ - -/** helpers for Device Driver API version handling */ - -/** @brief Encode a version ID from a 16-bit input - * - * @note the input is assumed to be 16 bits. It must not exceed 16 bits. */ -#define _MAKE_VERSION_ID(x) (((x) << 16UL) | (x)) - -/** @brief Check whether a 32-bit value is likely to be Device Driver API - * version ID. */ -#define _IS_VERSION_ID(x) (((x) & 0xFFFF) == (((x) >> 16UL) & 0xFFFF)) - -/** @brief Decode a 16-bit version number from a 32-bit Device Driver API version - * ID */ -#define _GET_VERSION(x) (((x) >> 16UL) & 0xFFFF) - -/** @brief Determine whether two 32-bit encoded version IDs match */ -#define _IS_API_MATCH(x, y) (IS_VERSION_ID((x)) && IS_VERSION_ID((y)) && (GET_VERSION((x)) == GET_VERSION((y)))) - -/** - * API version define. - * Indicates the version of the kernel API - * The version is a 16bit integer incremented on each API change. - * The 16bit integer is stored twice in a 32bit integer - * For example, for version 1 the value would be 0x00010001 - */ -#define _MALI_API_VERSION 17 -#define _MALI_UK_API_VERSION _MAKE_VERSION_ID(_MALI_API_VERSION) - -/** - * The API version is a 16-bit integer stored in both the lower and upper 16-bits - * of a 32-bit value. The 16-bit API version value is incremented on each API - * change. Version 1 would be 0x00010001. Used in _mali_uk_get_api_version_s. - */ -typedef u32 _mali_uk_api_version; - -/** @brief Arguments for _mali_uk_get_api_version() - * - * The user-side interface version must be written into the version member, - * encoded using _MAKE_VERSION_ID(). It will be compared to the API version of - * the kernel-side interface. - * - * On successful return, the version member will be the API version of the - * kernel-side interface. _MALI_UK_API_VERSION macro defines the current version - * of the API. - * - * The compatible member must be checked to see if the version of the user-side - * interface is compatible with the kernel-side interface, since future versions - * of the interface may be backwards compatible. - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - _mali_uk_api_version version; /**< [in,out] API version of user-side interface. */ - int compatible; /**< [out] @c 1 when @version is compatible, @c 0 otherwise */ -} _mali_uk_get_api_version_s; -/** @} */ /* end group _mali_uk_getapiversion_s */ - -/** @defgroup _mali_uk_get_user_settings_s Get user space settings */ - -/** @brief struct to keep the matching values of the user space settings within certain context - * - * Each member of the settings array corresponds to a matching setting in the user space and its value is the value - * of that particular setting. - * - * All settings are given reference to the context pointed to by the ctx pointer. - * - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 settings[_MALI_UK_USER_SETTING_MAX]; /**< [out] The values for all settings */ -} _mali_uk_get_user_settings_s; - -/** @brief struct to hold the value of a particular setting from the user space within a given context - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - _mali_uk_user_setting_t setting; /**< [in] setting to get */ - u32 value; /**< [out] value of setting */ -} _mali_uk_get_user_setting_s; - -/** @} */ /* end group _mali_uk_core */ - - -/** @defgroup _mali_uk_memory U/K Memory - * @{ */ - -/** @brief Arguments for _mali_ukk_init_mem(). */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 mali_address_base; /**< [out] start of MALI address space */ - u32 memory_size; /**< [out] total MALI address space available */ -} _mali_uk_init_mem_s; - -/** @brief Arguments for _mali_ukk_term_mem(). */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ -} _mali_uk_term_mem_s; - -/** Flag for _mali_uk_map_external_mem_s, _mali_uk_attach_ump_mem_s and _mali_uk_attach_dma_buf_s */ -#define _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE (1<<0) - -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 phys_addr; /**< [in] physical address */ - u32 size; /**< [in] size */ - u32 mali_address; /**< [in] mali address to map the physical memory to */ - u32 rights; /**< [in] rights necessary for accessing memory */ - u32 flags; /**< [in] flags, see \ref _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE */ - u32 cookie; /**< [out] identifier for mapped memory object in kernel space */ -} _mali_uk_map_external_mem_s; - -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 cookie; /**< [out] identifier for mapped memory object in kernel space */ -} _mali_uk_unmap_external_mem_s; - -/** @note This is identical to _mali_uk_map_external_mem_s above, however phys_addr is replaced by memory descriptor */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 mem_fd; /**< [in] Memory descriptor */ - u32 size; /**< [in] size */ - u32 mali_address; /**< [in] mali address to map the physical memory to */ - u32 rights; /**< [in] rights necessary for accessing memory */ - u32 flags; /**< [in] flags, see \ref _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE */ - u32 cookie; /**< [out] identifier for mapped memory object in kernel space */ -} _mali_uk_attach_dma_buf_s; - -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 mem_fd; /**< [in] Memory descriptor */ - u32 size; /**< [out] size */ -} _mali_uk_dma_buf_get_size_s; - -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 cookie; /**< [in] identifier for mapped memory object in kernel space */ -} _mali_uk_release_dma_buf_s; - -/** @note This is identical to _mali_uk_map_external_mem_s above, however phys_addr is replaced by secure_id */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 secure_id; /**< [in] secure id */ - u32 size; /**< [in] size */ - u32 mali_address; /**< [in] mali address to map the physical memory to */ - u32 rights; /**< [in] rights necessary for accessing memory */ - u32 flags; /**< [in] flags, see \ref _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE */ - u32 cookie; /**< [out] identifier for mapped memory object in kernel space */ -} _mali_uk_attach_ump_mem_s; - -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 cookie; /**< [in] identifier for mapped memory object in kernel space */ -} _mali_uk_release_ump_mem_s; - -/** @brief Arguments for _mali_ukk_va_to_mali_pa() - * - * if size is zero or not a multiple of the system's page size, it will be - * rounded up to the next multiple of the page size. This will occur before - * any other use of the size parameter. - * - * if va is not PAGE_SIZE aligned, it will be rounded down to the next page - * boundary. - * - * The range (va) to ((u32)va)+(size-1) inclusive will be checked for physical - * contiguity. - * - * The implementor will check that the entire physical range is allowed to be mapped - * into user-space. - * - * Failure will occur if either of the above are not satisfied. - * - * Otherwise, the physical base address of the range is returned through pa, - * va is updated to be page aligned, and size is updated to be a non-zero - * multiple of the system's pagesize. - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - void *va; /**< [in,out] Virtual address of the start of the range */ - u32 pa; /**< [out] Physical base address of the range */ - u32 size; /**< [in,out] Size of the range, in bytes. */ -} _mali_uk_va_to_mali_pa_s; - - -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 size; /**< [out] size of MMU page table information (registers + page tables) */ -} _mali_uk_query_mmu_page_table_dump_size_s; - -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 size; /**< [in] size of buffer to receive mmu page table information */ - void *buffer; /**< [in,out] buffer to receive mmu page table information */ - u32 register_writes_size; /**< [out] size of MMU register dump */ - u32 *register_writes; /**< [out] pointer within buffer where MMU register dump is stored */ - u32 page_table_dump_size; /**< [out] size of MMU page table dump */ - u32 *page_table_dump; /**< [out] pointer within buffer where MMU page table dump is stored */ -} _mali_uk_dump_mmu_page_table_s; - -/** @} */ /* end group _mali_uk_memory */ - - -/** @addtogroup _mali_uk_pp U/K Fragment Processor - * @{ */ - -/** @brief Arguments for _mali_ukk_get_pp_number_of_cores() - * - * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open() - * - Upon successful return from _mali_ukk_get_pp_number_of_cores(), @c number_of_cores - * will contain the number of Fragment Processor cores in the system. - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 number_of_cores; /**< [out] number of Fragment Processor cores in the system */ -} _mali_uk_get_pp_number_of_cores_s; - -/** @brief Arguments for _mali_ukk_get_pp_core_version() - * - * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open() - * - Upon successful return from _mali_ukk_get_pp_core_version(), @c version contains - * the version that all Fragment Processor cores are compatible with. - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - _mali_core_version version; /**< [out] version returned from core, see \ref _mali_core_version */ -} _mali_uk_get_pp_core_version_s; - -/** @} */ /* end group _mali_uk_pp */ - - -/** @addtogroup _mali_uk_gp U/K Vertex Processor - * @{ */ - -/** @brief Arguments for _mali_ukk_get_gp_number_of_cores() - * - * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open() - * - Upon successful return from _mali_ukk_get_gp_number_of_cores(), @c number_of_cores - * will contain the number of Vertex Processor cores in the system. - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 number_of_cores; /**< [out] number of Vertex Processor cores in the system */ -} _mali_uk_get_gp_number_of_cores_s; - -/** @brief Arguments for _mali_ukk_get_gp_core_version() - * - * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open() - * - Upon successful return from _mali_ukk_get_gp_core_version(), @c version contains - * the version that all Vertex Processor cores are compatible with. - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - _mali_core_version version; /**< [out] version returned from core, see \ref _mali_core_version */ -} _mali_uk_get_gp_core_version_s; - -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 limit; /**< [in,out] The desired limit for number of events to record on input, actual limit on output */ -} _mali_uk_profiling_start_s; - -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 event_id; /**< [in] event id to register (see enum mali_profiling_events for values) */ - u32 data[5]; /**< [in] event specific data */ -} _mali_uk_profiling_add_event_s; - -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 count; /**< [out] The number of events sampled */ -} _mali_uk_profiling_stop_s; - -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 index; /**< [in] which index to get (starting at zero) */ - u64 timestamp; /**< [out] timestamp of event */ - u32 event_id; /**< [out] event id of event (see enum mali_profiling_events for values) */ - u32 data[5]; /**< [out] event specific data */ -} _mali_uk_profiling_get_event_s; - -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ -} _mali_uk_profiling_clear_s; - -/** @} */ /* end group _mali_uk_gp */ - - -/** @addtogroup _mali_uk_memory U/K Memory - * @{ */ - -/** @brief Arguments to _mali_ukk_mem_mmap() - * - * Use of the phys_addr member depends on whether the driver is compiled for - * Mali-MMU or nonMMU: - * - in the nonMMU case, this is the physical address of the memory as seen by - * the CPU (which may be a constant offset from that used by Mali) - * - in the MMU case, this is the Mali Virtual base address of the memory to - * allocate, and the particular physical pages used to back the memory are - * entirely determined by _mali_ukk_mem_mmap(). The details of the physical pages - * are not reported to user-space for security reasons. - * - * The cookie member must be stored for use later when freeing the memory by - * calling _mali_ukk_mem_munmap(). In the Mali-MMU case, the cookie is secure. - * - * The ukk_private word must be set to zero when calling from user-space. On - * Kernel-side, the OS implementation of the U/K interface can use it to - * communicate data to the OS implementation of the OSK layer. In particular, - * _mali_ukk_get_big_block() directly calls _mali_ukk_mem_mmap directly, and - * will communicate its own ukk_private word through the ukk_private member - * here. The common code itself will not inspect or modify the ukk_private - * word, and so it may be safely used for whatever purposes necessary to - * integrate Mali Memory handling into the OS. - * - * The uku_private member is currently reserved for use by the user-side - * implementation of the U/K interface. Its value must be zero. - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - void *mapping; /**< [out] Returns user-space virtual address for the mapping */ - u32 size; /**< [in] Size of the requested mapping */ - u32 phys_addr; /**< [in] Physical address - could be offset, depending on caller+callee convention */ - u32 cookie; /**< [out] Returns a cookie for use in munmap calls */ - void *uku_private; /**< [in] User-side Private word used by U/K interface */ - void *ukk_private; /**< [in] Kernel-side Private word used by U/K interface */ - mali_memory_cache_settings cache_settings; /**< [in] Option to set special cache flags, tuning L2 efficency */ -} _mali_uk_mem_mmap_s; - -/** @brief Arguments to _mali_ukk_mem_munmap() - * - * The cookie and mapping members must be that returned from the same previous - * call to _mali_ukk_mem_mmap(). The size member must correspond to cookie - * and mapping - that is, it must be the value originally supplied to a call to - * _mali_ukk_mem_mmap that returned the values of mapping and cookie. - * - * An error will be returned if an attempt is made to unmap only part of the - * originally obtained range, or to unmap more than was originally obtained. - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - void *mapping; /**< [in] The mapping returned from mmap call */ - u32 size; /**< [in] The size passed to mmap call */ - u32 cookie; /**< [in] Cookie from mmap call */ -} _mali_uk_mem_munmap_s; -/** @} */ /* end group _mali_uk_memory */ - -/** @defgroup _mali_uk_vsync U/K VSYNC Wait Reporting Module - * @{ */ - -/** @brief VSYNC events - * - * These events are reported when DDK starts to wait for vsync and when the - * vsync has occured and the DDK can continue on the next frame. - */ -typedef enum _mali_uk_vsync_event -{ - _MALI_UK_VSYNC_EVENT_BEGIN_WAIT = 0, - _MALI_UK_VSYNC_EVENT_END_WAIT -} _mali_uk_vsync_event; - -/** @brief Arguments to _mali_ukk_vsync_event() - * - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - _mali_uk_vsync_event event; /**< [in] VSYNCH event type */ -} _mali_uk_vsync_event_report_s; - -/** @} */ /* end group _mali_uk_vsync */ - -/** @defgroup _mali_uk_sw_counters_report U/K Software Counter Reporting - * @{ */ - -/** @brief Software counter values - * - * Values recorded for each of the software counters during a single renderpass. - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32* counters; /**< [in] The array of counter values */ - u32 num_counters; /**< [in] The number of elements in counters array */ -} _mali_uk_sw_counters_report_s; - -/** @} */ /* end group _mali_uk_sw_counters_report */ - -/** @} */ /* end group u_k_api */ - -/** @} */ /* end group uddapi */ - -#ifdef __cplusplus -} -#endif - -#endif /* __MALI_UTGARD_UK_TYPES_H__ */ diff --git a/drivers/media/video/samsung/mali/linux/license/gpl/mali_kernel_license.h b/drivers/media/video/samsung/mali/linux/license/gpl/mali_kernel_license.h deleted file mode 100644 index 52bb5e0..0000000 --- a/drivers/media/video/samsung/mali/linux/license/gpl/mali_kernel_license.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_kernel_license.h - * Defines for the macro MODULE_LICENSE. - */ - -#ifndef __MALI_KERNEL_LICENSE_H__ -#define __MALI_KERNEL_LICENSE_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#define MALI_KERNEL_LINUX_LICENSE "GPL" -#define MALI_LICENSE_IS_GPL 1 - -#ifdef __cplusplus -} -#endif - -#endif /* __MALI_KERNEL_LICENSE_H__ */ diff --git a/drivers/media/video/samsung/mali/linux/mali_dma_buf.c b/drivers/media/video/samsung/mali/linux/mali_dma_buf.c deleted file mode 100644 index 4dd711f..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_dma_buf.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Copyright (C) 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include /* file system operations */ -#include /* user space access */ -#include -#include -#include - -#include "mali_ukk.h" -#include "mali_osk.h" -#include "mali_kernel_common.h" -#include "mali_session.h" -#include "mali_kernel_linux.h" - -#include "mali_kernel_memory_engine.h" -#include "mali_memory.h" - -#include "mali_kernel_sysfs.h" - - -struct mali_dma_buf_attachment { - struct dma_buf *buf; - struct dma_buf_attachment *attachment; - struct sg_table *sgt; - _mali_osk_atomic_t ref; - struct rb_node rb_node; -}; - -static struct rb_root mali_dma_bufs = RB_ROOT; -static DEFINE_SPINLOCK(mali_dma_bufs_lock); - -static inline struct mali_dma_buf_attachment *mali_dma_buf_lookup(struct rb_root *root, struct dma_buf *target) -{ - struct rb_node *node = root->rb_node; - struct mali_dma_buf_attachment *res; - - spin_lock(&mali_dma_bufs_lock); - while (node) - { - res = rb_entry(node, struct mali_dma_buf_attachment, rb_node); - - if (target < res->buf) node = node->rb_left; - else if (target > res->buf) node = node->rb_right; - else - { - _mali_osk_atomic_inc(&res->ref); - spin_unlock(&mali_dma_bufs_lock); - return res; - } - } - spin_unlock(&mali_dma_bufs_lock); - - return NULL; -} - -static void mali_dma_buf_add(struct rb_root *root, struct mali_dma_buf_attachment *new) -{ - struct rb_node **node = &root->rb_node; - struct rb_node *parent = NULL; - struct mali_dma_buf_attachment *res; - - spin_lock(&mali_dma_bufs_lock); - while (*node) - { - parent = *node; - res = rb_entry(*node, struct mali_dma_buf_attachment, rb_node); - - if (new->buf < res->buf) node = &(*node)->rb_left; - else node = &(*node)->rb_right; - } - - rb_link_node(&new->rb_node, parent, node); - rb_insert_color(&new->rb_node, &mali_dma_bufs); - - spin_unlock(&mali_dma_bufs_lock); - - return; -} - - -static void mali_dma_buf_release(void *ctx, void *handle) -{ - struct mali_dma_buf_attachment *mem; - u32 ref; - - mem = (struct mali_dma_buf_attachment *)handle; - - MALI_DEBUG_ASSERT_POINTER(mem); - MALI_DEBUG_ASSERT_POINTER(mem->attachment); - MALI_DEBUG_ASSERT_POINTER(mem->buf); - - spin_lock(&mali_dma_bufs_lock); - ref = _mali_osk_atomic_dec_return(&mem->ref); - - MALI_DEBUG_ASSERT(ref >= 0); - - if (0 == ref) - { - rb_erase(&mem->rb_node, &mali_dma_bufs); - spin_unlock(&mali_dma_bufs_lock); - - MALI_DEBUG_ASSERT(0 == _mali_osk_atomic_read(&mem->ref)); - - dma_buf_unmap_attachment(mem->attachment, mem->sgt, DMA_BIDIRECTIONAL); - - dma_buf_detach(mem->buf, mem->attachment); - dma_buf_put(mem->buf); - - _mali_osk_free(mem); - } - else - { - spin_unlock(&mali_dma_bufs_lock); - } -} - -/* Callback from memory engine which will map into Mali virtual address space */ -static mali_physical_memory_allocation_result mali_dma_buf_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info) -{ - struct mali_session_data *session; - struct mali_page_directory *pagedir; - struct mali_dma_buf_attachment *mem; - struct scatterlist *sg; - int i; - u32 virt; - - MALI_DEBUG_ASSERT_POINTER(ctx); - MALI_DEBUG_ASSERT_POINTER(engine); - MALI_DEBUG_ASSERT_POINTER(descriptor); - MALI_DEBUG_ASSERT_POINTER(offset); - MALI_DEBUG_ASSERT_POINTER(alloc_info); - - /* Mapping dma-buf with an offset is not supported. */ - MALI_DEBUG_ASSERT(0 == *offset); - - virt = descriptor->mali_address; - session = (struct mali_session_data *)descriptor->mali_addr_mapping_info; - pagedir = mali_session_get_page_directory(session); - - MALI_DEBUG_ASSERT_POINTER(session); - - mem = (struct mali_dma_buf_attachment *)ctx; - - MALI_DEBUG_ASSERT_POINTER(mem); - - mem->sgt = dma_buf_map_attachment(mem->attachment, DMA_BIDIRECTIONAL); - if (IS_ERR_OR_NULL(mem->sgt)) - { - MALI_PRINT_ERROR(("Failed to map dma-buf attachment\n")); - return MALI_MEM_ALLOC_INTERNAL_FAILURE; - } - - for_each_sg(mem->sgt->sgl, sg, mem->sgt->nents, i) - { - u32 size = sg_dma_len(sg); - dma_addr_t phys = sg_dma_address(sg); - - /* sg must be page aligned. */ - MALI_DEBUG_ASSERT(0 == size % MALI_MMU_PAGE_SIZE); - - mali_mmu_pagedir_update(pagedir, virt, phys, size, MALI_CACHE_STANDARD); - - virt += size; - *offset += size; - } - - if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE) - { - u32 guard_phys; - MALI_DEBUG_PRINT(7, ("Mapping in extra guard page\n")); - - guard_phys = sg_dma_address(mem->sgt->sgl); - mali_mmu_pagedir_update(mali_session_get_page_directory(session), virt, guard_phys, MALI_MMU_PAGE_SIZE, MALI_CACHE_STANDARD); - } - - MALI_DEBUG_ASSERT(*offset == descriptor->size); - - alloc_info->ctx = NULL; - alloc_info->handle = mem; - alloc_info->next = NULL; - alloc_info->release = mali_dma_buf_release; - - return MALI_MEM_ALLOC_FINISHED; -} - -int mali_attach_dma_buf(struct mali_session_data *session, _mali_uk_attach_dma_buf_s __user *user_arg) -{ - mali_physical_memory_allocator external_memory_allocator; - struct dma_buf *buf; - struct mali_dma_buf_attachment *mem; - _mali_uk_attach_dma_buf_s args; - mali_memory_allocation *descriptor; - int md; - int fd; - - /* Get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */ - if (0 != copy_from_user(&args, (void __user *)user_arg, sizeof(_mali_uk_attach_dma_buf_s))) - { - return -EFAULT; - } - - - fd = args.mem_fd; - - buf = dma_buf_get(fd); - if (IS_ERR_OR_NULL(buf)) - { - MALI_DEBUG_PRINT(2, ("Failed to get dma-buf from fd: %d\n", fd)); - return PTR_RET(buf); - } - - /* Currently, mapping of the full buffer are supported. */ - if (args.size != buf->size) - { - MALI_DEBUG_PRINT(2, ("dma-buf size doesn't match mapping size.\n")); - dma_buf_put(buf); - return -EINVAL; - } - - - mem = mali_dma_buf_lookup(&mali_dma_bufs, buf); - if (NULL == mem) - { - /* dma-buf is not already attached to Mali */ - mem = _mali_osk_calloc(1, sizeof(struct mali_dma_buf_attachment)); - if (NULL == mem) - { - MALI_PRINT_ERROR(("Failed to allocate dma-buf tracing struct\n")); - dma_buf_put(mem->buf); - return -ENOMEM; - } - _mali_osk_atomic_init(&mem->ref, 1); - mem->buf = buf; - - mem->attachment = dma_buf_attach(mem->buf, mali_device); - if (NULL == mem->attachment) - { - MALI_DEBUG_PRINT(2, ("Failed to attach to dma-buf %d\n", fd)); - dma_buf_put(mem->buf); - _mali_osk_free(mem); - return -EFAULT; - } - - mali_dma_buf_add(&mali_dma_bufs, mem); - } - else - { - /* dma-buf is already attached to Mali */ - /* Give back the reference we just took, mali_dma_buf_lookup grabbed a new reference for us. */ - dma_buf_put(buf); - } - - /* Map dma-buf into this session's page tables */ - - /* Set up Mali memory descriptor */ - descriptor = _mali_osk_calloc(1, sizeof(mali_memory_allocation)); - if (NULL == descriptor) - { - MALI_PRINT_ERROR(("Failed to allocate descriptor dma-buf %d\n", fd)); - mali_dma_buf_release(NULL, mem); - return -ENOMEM; - } - - descriptor->size = args.size; - descriptor->mapping = NULL; - descriptor->mali_address = args.mali_address; - descriptor->mali_addr_mapping_info = (void*)session; - descriptor->process_addr_mapping_info = NULL; /* do not map to process address space */ - descriptor->lock = session->memory_lock; - - if (args.flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) - { - descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE; - } - _mali_osk_list_init( &descriptor->list ); - - /* Get descriptor mapping for memory. */ - if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session->descriptor_mapping, descriptor, &md)) - { - MALI_PRINT_ERROR(("Failed to create descriptor mapping for dma-buf %d\n", fd)); - _mali_osk_free(descriptor); - mali_dma_buf_release(NULL, mem); - return -EFAULT; - } - - external_memory_allocator.allocate = mali_dma_buf_commit; - external_memory_allocator.allocate_page_table_block = NULL; - external_memory_allocator.ctx = mem; - external_memory_allocator.name = "DMA-BUF Memory"; - external_memory_allocator.next = NULL; - - /* Map memory into session's Mali virtual address space. */ - _mali_osk_lock_wait(session->memory_lock, _MALI_OSK_LOCKMODE_RW); - if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_memory(mali_mem_get_memory_engine(), descriptor, &external_memory_allocator, NULL)) - { - _mali_osk_lock_signal(session->memory_lock, _MALI_OSK_LOCKMODE_RW); - - MALI_PRINT_ERROR(("Failed to map dma-buf %d into Mali address space\n", fd)); - mali_descriptor_mapping_free(session->descriptor_mapping, md); - mali_dma_buf_release(NULL, mem); - return -ENOMEM; - } - _mali_osk_lock_signal(session->memory_lock, _MALI_OSK_LOCKMODE_RW); - - /* Return stuff to user space */ - if (0 != put_user(md, &user_arg->cookie)) - { - /* Roll back */ - MALI_PRINT_ERROR(("Failed to return descriptor to user space for dma-buf %d\n", fd)); - mali_descriptor_mapping_free(session->descriptor_mapping, md); - mali_dma_buf_release(NULL, mem); - return -EFAULT; - } - - return 0; -} - -int mali_release_dma_buf(struct mali_session_data *session, _mali_uk_release_dma_buf_s __user *user_arg) -{ - _mali_uk_release_dma_buf_s args; - mali_memory_allocation *descriptor; - - /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */ - if ( 0 != copy_from_user(&args, (void __user *)user_arg, sizeof(_mali_uk_release_dma_buf_s)) ) - { - return -EFAULT; - } - - if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_get(session->descriptor_mapping, args.cookie, (void**)&descriptor)) - { - MALI_DEBUG_PRINT(1, ("Invalid memory descriptor %d used to release dma-buf\n", args.cookie)); - return -EINVAL; - } - - descriptor = mali_descriptor_mapping_free(session->descriptor_mapping, args.cookie); - - if (NULL != descriptor) - { - _mali_osk_lock_wait( session->memory_lock, _MALI_OSK_LOCKMODE_RW ); - - /* Will call back to mali_dma_buf_release() which will release the dma-buf attachment. */ - mali_allocation_engine_release_memory(mali_mem_get_memory_engine(), descriptor); - - _mali_osk_lock_signal( session->memory_lock, _MALI_OSK_LOCKMODE_RW ); - - _mali_osk_free(descriptor); - } - - /* Return the error that _mali_ukk_map_external_ump_mem produced */ - return 0; -} - -int mali_dma_buf_get_size(struct mali_session_data *session, _mali_uk_dma_buf_get_size_s __user *user_arg) -{ - _mali_uk_dma_buf_get_size_s args; - int fd; - struct dma_buf *buf; - - /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */ - if ( 0 != copy_from_user(&args, (void __user *)user_arg, sizeof(_mali_uk_dma_buf_get_size_s)) ) - { - return -EFAULT; - } - - /* Do DMA-BUF stuff */ - fd = args.mem_fd; - - buf = dma_buf_get(fd); - if (IS_ERR_OR_NULL(buf)) - { - MALI_DEBUG_PRINT(2, ("Failed to get dma-buf from fd: %d\n", fd)); - return PTR_RET(buf); - } - - if (0 != put_user(buf->size, &user_arg->size)) - { - dma_buf_put(buf); - return -EFAULT; - } - - dma_buf_put(buf); - - return 0; -} diff --git a/drivers/media/video/samsung/mali/linux/mali_dma_buf.h b/drivers/media/video/samsung/mali/linux/mali_dma_buf.h deleted file mode 100644 index ee9a0ed..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_dma_buf.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2011-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_DMA_BUF_H__ -#define __MALI_DMA_BUF_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "mali_osk.h" - -int mali_attach_dma_buf(struct mali_session_data *session, _mali_uk_attach_dma_buf_s __user *arg); -int mali_release_dma_buf(struct mali_session_data *session, _mali_uk_release_dma_buf_s __user *arg); -int mali_dma_buf_get_size(struct mali_session_data *session, _mali_uk_dma_buf_get_size_s __user *arg); - -#ifdef __cplusplus -} -#endif - -#endif /* __MALI_KERNEL_LINUX_H__ */ diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_linux.c b/drivers/media/video/samsung/mali/linux/mali_kernel_linux.c deleted file mode 100644 index 233c0ca..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_kernel_linux.c +++ /dev/null @@ -1,634 +0,0 @@ -/** - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_kernel_linux.c - * Implementation of the Linux device driver entrypoints - */ -#include /* kernel module definitions */ -#include /* file system operations */ -#include /* character device definitions */ -#include /* memory manager definitions */ -#include -#include "mali_kernel_common.h" -#include "mali_session.h" -#include "mali_kernel_core.h" -#include "mali_osk.h" -#include "mali_kernel_linux.h" -#include "mali_ukk.h" -#include "mali_ukk_wrappers.h" -#include "mali_kernel_pm.h" -#include "mali_kernel_sysfs.h" -#include "mali_platform.h" -#include "mali_kernel_license.h" -#include "mali_dma_buf.h" - -/* Streamline support for the Mali driver */ -#if defined(CONFIG_TRACEPOINTS) && MALI_TIMELINE_PROFILING_ENABLED -/* Ask Linux to create the tracepoints */ -#define CREATE_TRACE_POINTS -#include "mali_linux_trace.h" -#endif /* CONFIG_TRACEPOINTS */ - -static _mali_osk_errcode_t initialize_kernel_device(void); -static int initialize_sysfs(void); -static void terminate_kernel_device(void); - - -/* from the __malidrv_build_info.c file that is generated during build */ -extern const char *__malidrv_build_info(void); - -/* Module parameter to control log level */ -int mali_debug_level = 2; -module_param(mali_debug_level, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); /* rw-rw-r-- */ -MODULE_PARM_DESC(mali_debug_level, "Higher number, more dmesg output"); - -/* By default the module uses any available major, but it's possible to set it at load time to a specific number */ -#if MALI_MAJOR_PREDEFINE -int mali_major = 244; -#else -int mali_major = 0; -#endif -module_param(mali_major, int, S_IRUGO); /* r--r--r-- */ -MODULE_PARM_DESC(mali_major, "Device major number"); - -module_param(mali_hang_check_interval, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); -MODULE_PARM_DESC(mali_hang_check_interval, "Interval at which to check for progress after the hw watchdog has been triggered"); - -module_param(mali_max_job_runtime, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); -MODULE_PARM_DESC(mali_max_job_runtime, "Maximum allowed job runtime in msecs.\nJobs will be killed after this no matter what"); - -extern int mali_l2_max_reads; -module_param(mali_l2_max_reads, int, S_IRUSR | S_IRGRP | S_IROTH); -MODULE_PARM_DESC(mali_l2_max_reads, "Maximum reads for Mali L2 cache"); - -#if MALI_TIMELINE_PROFILING_ENABLED -extern int mali_boot_profiling; -module_param(mali_boot_profiling, int, S_IRUSR | S_IRGRP | S_IROTH); -MODULE_PARM_DESC(mali_boot_profiling, "Start profiling as a part of Mali driver initialization"); -#endif - -/* Export symbols from common code: mali_user_settings.c */ -#include "mali_user_settings_db.h" -EXPORT_SYMBOL(mali_set_user_setting); -EXPORT_SYMBOL(mali_get_user_setting); -#if MALI_DVFS_ENABLED -extern int mali_dvfs_control; -module_param(mali_dvfs_control, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ -MODULE_PARM_DESC(mali_dvfs_control, "Mali Current DVFS"); -#if defined(CONFIG_CPU_EXYNOS4210) -#else -extern int step0_clk; -module_param(step0_clk, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ -MODULE_PARM_DESC(step0_clk, "Mali Current step0_clk"); -#ifdef DEBUG -extern int step0_vol; -module_param(step0_vol, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ -MODULE_PARM_DESC(step0_vol, "Mali Current step0_vol"); -#endif - -#if (MALI_DVFS_STEPS > 1) -extern int step1_clk; -module_param(step1_clk, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ -MODULE_PARM_DESC(step1_clk, "Mali Current step1_clk"); - -extern int step0_up; -module_param(step0_up, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ -MODULE_PARM_DESC(step0_up, "Mali Current step0_up"); - -extern int step1_down; -module_param(step1_down, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ -MODULE_PARM_DESC(step1_down, "Mali Current step1_down"); -#ifdef DEBUG -extern int step1_vol; -module_param(step1_vol, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ -MODULE_PARM_DESC(step1_vol, "Mali Current step1_vol"); -#endif - -#if (MALI_DVFS_STEPS > 2) -extern int step2_clk; -module_param(step2_clk, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ -MODULE_PARM_DESC(step2_clk, "Mali Current step2_clk"); - -extern int step1_up; -module_param(step1_up, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ -MODULE_PARM_DESC(step1_up, "Mali Current step1_up"); - -extern int step2_down; -module_param(step2_down, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ -MODULE_PARM_DESC(step2_down, "Mali Current step2_down"); -#ifdef DEBUG -extern int step2_vol; -module_param(step2_vol, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ -MODULE_PARM_DESC(step2_vol, "Mali Current step2_vol"); -#endif - -#if (MALI_DVFS_STEPS > 3) -extern int step3_clk; -module_param(step3_clk, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ -MODULE_PARM_DESC(step3_clk, "Mali Current step3_clk"); - -extern int step2_up; -module_param(step2_up, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ -MODULE_PARM_DESC(step2_up, "Mali Current step2_up"); - -extern int step3_down; -module_param(step3_down, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ -MODULE_PARM_DESC(step3_down, "Mali Current step3_down"); -#ifdef DEBUG -extern int step3_vol; -module_param(step3_vol, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ -MODULE_PARM_DESC(step3_vol, "Mali Current step3_vol"); -#endif -#endif -#endif -#endif -#endif - -extern int mali_gpu_clk; -module_param(mali_gpu_clk, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */ -MODULE_PARM_DESC(mali_gpu_clk, "Mali Current Clock"); - -extern int mali_gpu_vol; -module_param(mali_gpu_vol, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */ -MODULE_PARM_DESC(mali_gpu_vol, "Mali Current Voltage"); - -extern int gpu_power_state; -module_param(gpu_power_state, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */ -MODULE_PARM_DESC(gpu_power_state, "Mali Power State"); -#endif - - -static char mali_dev_name[] = "mali"; /* should be const, but the functions we call requires non-cost */ - -/* the mali device */ -static struct mali_dev device; - - -static int mali_open(struct inode *inode, struct file *filp); -static int mali_release(struct inode *inode, struct file *filp); -#ifdef HAVE_UNLOCKED_IOCTL -static long mali_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); -#else -static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -#endif - -static int mali_mmap(struct file * filp, struct vm_area_struct * vma); - -/* Linux char file operations provided by the Mali module */ -struct file_operations mali_fops = -{ - .owner = THIS_MODULE, - .open = mali_open, - .release = mali_release, -#ifdef HAVE_UNLOCKED_IOCTL - .unlocked_ioctl = mali_ioctl, -#else - .ioctl = mali_ioctl, -#endif - .mmap = mali_mmap -}; - - -int mali_driver_init(void) -{ - int ret = 0; - - MALI_DEBUG_PRINT(2, ("\n")); - MALI_DEBUG_PRINT(2, ("Inserting Mali v%d device driver. \n",_MALI_API_VERSION)); - MALI_DEBUG_PRINT(2, ("Compiled: %s, time: %s.\n", __DATE__, __TIME__)); - MALI_DEBUG_PRINT(2, ("Driver revision: %s\n", SVN_REV_STRING)); - - ret = _mali_dev_platform_register(); - if (0 != ret) goto platform_register_failed; - ret = map_errcode(initialize_kernel_device()); - if (0 != ret) goto initialize_kernel_device_failed; - - ret = map_errcode(mali_platform_init()); - if (0 != ret) goto platform_init_failed; - - mali_osk_low_level_mem_init(); - - ret = map_errcode(mali_initialize_subsystems()); - if (0 != ret) goto initialize_subsystems_failed; - - ret = initialize_sysfs(); - if (0 != ret) goto initialize_sysfs_failed; - - MALI_PRINT(("Mali device driver loaded\n")); - - return 0; /* Success */ - - /* Error handling */ -initialize_sysfs_failed: - mali_terminate_subsystems(); -initialize_subsystems_failed: - mali_osk_low_level_mem_term(); - mali_platform_deinit(); -platform_init_failed: - terminate_kernel_device(); -initialize_kernel_device_failed: - _mali_dev_platform_unregister(); -platform_register_failed: - return ret; -} - -void mali_driver_exit(void) -{ - MALI_DEBUG_PRINT(2, ("\n")); - MALI_DEBUG_PRINT(2, ("Unloading Mali v%d device driver.\n",_MALI_API_VERSION)); - - /* No need to terminate sysfs, this will be done automatically along with device termination */ - - mali_terminate_subsystems(); - - mali_osk_low_level_mem_term(); - - mali_platform_deinit(); - - terminate_kernel_device(); - _mali_dev_platform_unregister(); - -#if MALI_LICENSE_IS_GPL - /* @@@@ clean up the work queues! This should not be terminated here, since it isn't inited in the function above! */ - flush_workqueue(mali_wq); - destroy_workqueue(mali_wq); - mali_wq = NULL; -#endif - - MALI_PRINT(("Mali device driver unloaded\n")); -} - -static int initialize_kernel_device(void) -{ - int err; - dev_t dev = 0; - if (0 == mali_major) - { - /* auto select a major */ - err = alloc_chrdev_region(&dev, 0/*first minor*/, 1/*count*/, mali_dev_name); - mali_major = MAJOR(dev); - } - else - { - /* use load time defined major number */ - dev = MKDEV(mali_major, 0); - err = register_chrdev_region(dev, 1/*count*/, mali_dev_name); - } - - if (err) - { - goto init_chrdev_err; - } - - memset(&device, 0, sizeof(device)); - - /* initialize our char dev data */ - cdev_init(&device.cdev, &mali_fops); - device.cdev.owner = THIS_MODULE; - device.cdev.ops = &mali_fops; - - /* register char dev with the kernel */ - err = cdev_add(&device.cdev, dev, 1/*count*/); - if (err) - { - goto init_cdev_err; - } - - /* Success! */ - return 0; - -init_cdev_err: - unregister_chrdev_region(dev, 1/*count*/); -init_chrdev_err: - return err; -} - -static int initialize_sysfs(void) -{ - dev_t dev = MKDEV(mali_major, 0); - return mali_sysfs_register(&device, dev, mali_dev_name); -} - -static void terminate_kernel_device(void) -{ - dev_t dev = MKDEV(mali_major, 0); - - mali_sysfs_unregister(&device, dev, mali_dev_name); - - /* unregister char device */ - cdev_del(&device.cdev); - /* free major */ - unregister_chrdev_region(dev, 1/*count*/); - return; -} - -/** @note munmap handler is done by vma close handler */ -static int mali_mmap(struct file * filp, struct vm_area_struct * vma) -{ - struct mali_session_data * session_data; - _mali_uk_mem_mmap_s args = {0, }; - - session_data = (struct mali_session_data *)filp->private_data; - if (NULL == session_data) - { - MALI_PRINT_ERROR(("mmap called without any session data available\n")); - return -EFAULT; - } - - MALI_DEBUG_PRINT(4, ("MMap() handler: start=0x%08X, phys=0x%08X, size=0x%08X vma->flags 0x%08x\n", (unsigned int)vma->vm_start, (unsigned int)(vma->vm_pgoff << PAGE_SHIFT), (unsigned int)(vma->vm_end - vma->vm_start), vma->vm_flags)); - - /* Re-pack the arguments that mmap() packed for us */ - args.ctx = session_data; - args.phys_addr = vma->vm_pgoff << PAGE_SHIFT; - args.size = vma->vm_end - vma->vm_start; - args.ukk_private = vma; - - if ( VM_SHARED== (VM_SHARED & vma->vm_flags)) - { - args.cache_settings = MALI_CACHE_STANDARD ; - MALI_DEBUG_PRINT(3,("Allocate - Standard - Size: %d kb\n", args.size/1024)); - } - else - { - args.cache_settings = MALI_CACHE_GP_READ_ALLOCATE; - MALI_DEBUG_PRINT(3,("Allocate - GP Cached - Size: %d kb\n", args.size/1024)); - } - /* Setting it equal to VM_SHARED and not Private, which would have made the later io_remap fail for MALI_CACHE_GP_READ_ALLOCATE */ - vma->vm_flags = 0x000000fb; - - /* Call the common mmap handler */ - MALI_CHECK(_MALI_OSK_ERR_OK ==_mali_ukk_mem_mmap( &args ), -EFAULT); - - return 0; -} - -static int mali_open(struct inode *inode, struct file *filp) -{ - struct mali_session_data * session_data; - _mali_osk_errcode_t err; - - /* input validation */ - if (0 != MINOR(inode->i_rdev)) return -ENODEV; - - /* allocated struct to track this session */ - err = _mali_ukk_open((void **)&session_data); - if (_MALI_OSK_ERR_OK != err) return map_errcode(err); - - /* initialize file pointer */ - filp->f_pos = 0; - - /* link in our session data */ - filp->private_data = (void*)session_data; - - return 0; -} - -static int mali_release(struct inode *inode, struct file *filp) -{ - _mali_osk_errcode_t err; - - /* input validation */ - if (0 != MINOR(inode->i_rdev)) return -ENODEV; - - err = _mali_ukk_close((void **)&filp->private_data); - if (_MALI_OSK_ERR_OK != err) return map_errcode(err); - - return 0; -} - -int map_errcode( _mali_osk_errcode_t err ) -{ - switch(err) - { - case _MALI_OSK_ERR_OK : return 0; - case _MALI_OSK_ERR_FAULT: return -EFAULT; - case _MALI_OSK_ERR_INVALID_FUNC: return -ENOTTY; - case _MALI_OSK_ERR_INVALID_ARGS: return -EINVAL; - case _MALI_OSK_ERR_NOMEM: return -ENOMEM; - case _MALI_OSK_ERR_TIMEOUT: return -ETIMEDOUT; - case _MALI_OSK_ERR_RESTARTSYSCALL: return -ERESTARTSYS; - case _MALI_OSK_ERR_ITEM_NOT_FOUND: return -ENOENT; - default: return -EFAULT; - } -} - -#ifdef HAVE_UNLOCKED_IOCTL -static long mali_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -#else -static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) -#endif -{ - int err; - struct mali_session_data *session_data; - -#ifndef HAVE_UNLOCKED_IOCTL - /* inode not used */ - (void)inode; -#endif - - MALI_DEBUG_PRINT(7, ("Ioctl received 0x%08X 0x%08lX\n", cmd, arg)); - - session_data = (struct mali_session_data *)filp->private_data; - if (NULL == session_data) - { - MALI_DEBUG_PRINT(7, ("filp->private_data was NULL\n")); - return -ENOTTY; - } - - if (NULL == (void *)arg) - { - MALI_DEBUG_PRINT(7, ("arg was NULL\n")); - return -ENOTTY; - } - - switch(cmd) - { - case MALI_IOC_WAIT_FOR_NOTIFICATION: - err = wait_for_notification_wrapper(session_data, (_mali_uk_wait_for_notification_s __user *)arg); - break; - - case MALI_IOC_GET_API_VERSION: - err = get_api_version_wrapper(session_data, (_mali_uk_get_api_version_s __user *)arg); - break; - - case MALI_IOC_POST_NOTIFICATION: - err = post_notification_wrapper(session_data, (_mali_uk_post_notification_s __user *)arg); - break; - - case MALI_IOC_GET_USER_SETTINGS: - err = get_user_settings_wrapper(session_data, (_mali_uk_get_user_settings_s __user *)arg); - break; - -#if MALI_TIMELINE_PROFILING_ENABLED - case MALI_IOC_PROFILING_START: - err = profiling_start_wrapper(session_data, (_mali_uk_profiling_start_s __user *)arg); - break; - - case MALI_IOC_PROFILING_ADD_EVENT: - err = profiling_add_event_wrapper(session_data, (_mali_uk_profiling_add_event_s __user *)arg); - break; - - case MALI_IOC_PROFILING_STOP: - err = profiling_stop_wrapper(session_data, (_mali_uk_profiling_stop_s __user *)arg); - break; - - case MALI_IOC_PROFILING_GET_EVENT: - err = profiling_get_event_wrapper(session_data, (_mali_uk_profiling_get_event_s __user *)arg); - break; - - case MALI_IOC_PROFILING_CLEAR: - err = profiling_clear_wrapper(session_data, (_mali_uk_profiling_clear_s __user *)arg); - break; - - case MALI_IOC_PROFILING_GET_CONFIG: - /* Deprecated: still compatible with get_user_settings */ - err = get_user_settings_wrapper(session_data, (_mali_uk_get_user_settings_s __user *)arg); - break; - - case MALI_IOC_PROFILING_REPORT_SW_COUNTERS: - err = profiling_report_sw_counters_wrapper(session_data, (_mali_uk_sw_counters_report_s __user *)arg); - break; - -#else - - case MALI_IOC_PROFILING_START: /* FALL-THROUGH */ - case MALI_IOC_PROFILING_ADD_EVENT: /* FALL-THROUGH */ - case MALI_IOC_PROFILING_STOP: /* FALL-THROUGH */ - case MALI_IOC_PROFILING_GET_EVENT: /* FALL-THROUGH */ - case MALI_IOC_PROFILING_CLEAR: /* FALL-THROUGH */ - case MALI_IOC_PROFILING_GET_CONFIG: /* FALL-THROUGH */ - case MALI_IOC_PROFILING_REPORT_SW_COUNTERS: /* FALL-THROUGH */ - MALI_DEBUG_PRINT(2, ("Profiling not supported\n")); - err = -ENOTTY; - break; - -#endif - - case MALI_IOC_MEM_INIT: - err = mem_init_wrapper(session_data, (_mali_uk_init_mem_s __user *)arg); - break; - - case MALI_IOC_MEM_TERM: - err = mem_term_wrapper(session_data, (_mali_uk_term_mem_s __user *)arg); - break; - - case MALI_IOC_MEM_MAP_EXT: - err = mem_map_ext_wrapper(session_data, (_mali_uk_map_external_mem_s __user *)arg); - break; - - case MALI_IOC_MEM_UNMAP_EXT: - err = mem_unmap_ext_wrapper(session_data, (_mali_uk_unmap_external_mem_s __user *)arg); - break; - - case MALI_IOC_MEM_QUERY_MMU_PAGE_TABLE_DUMP_SIZE: - err = mem_query_mmu_page_table_dump_size_wrapper(session_data, (_mali_uk_query_mmu_page_table_dump_size_s __user *)arg); - break; - - case MALI_IOC_MEM_DUMP_MMU_PAGE_TABLE: - err = mem_dump_mmu_page_table_wrapper(session_data, (_mali_uk_dump_mmu_page_table_s __user *)arg); - break; - -#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 - - case MALI_IOC_MEM_ATTACH_UMP: - err = mem_attach_ump_wrapper(session_data, (_mali_uk_attach_ump_mem_s __user *)arg); - break; - - case MALI_IOC_MEM_RELEASE_UMP: - err = mem_release_ump_wrapper(session_data, (_mali_uk_release_ump_mem_s __user *)arg); - break; - -#else - - case MALI_IOC_MEM_ATTACH_UMP: - case MALI_IOC_MEM_RELEASE_UMP: /* FALL-THROUGH */ - MALI_DEBUG_PRINT(2, ("UMP not supported\n")); - err = -ENOTTY; - break; -#endif - -#ifdef CONFIG_DMA_SHARED_BUFFER - case MALI_IOC_MEM_ATTACH_DMA_BUF: - err = mali_attach_dma_buf(session_data, (_mali_uk_attach_dma_buf_s __user *)arg); - break; - - case MALI_IOC_MEM_RELEASE_DMA_BUF: - err = mali_release_dma_buf(session_data, (_mali_uk_release_dma_buf_s __user *)arg); - break; - - case MALI_IOC_MEM_DMA_BUF_GET_SIZE: - err = mali_dma_buf_get_size(session_data, (_mali_uk_dma_buf_get_size_s __user *)arg); - break; -#else - - case MALI_IOC_MEM_DMA_BUF_GET_SIZE: /* FALL-THROUGH */ - MALI_DEBUG_PRINT(2, ("DMA-BUF not supported\n")); - err = -ENOTTY; - break; -#endif - - case MALI_IOC_PP_START_JOB: - err = pp_start_job_wrapper(session_data, (_mali_uk_pp_start_job_s __user *)arg); - break; - - case MALI_IOC_PP_NUMBER_OF_CORES_GET: - err = pp_get_number_of_cores_wrapper(session_data, (_mali_uk_get_pp_number_of_cores_s __user *)arg); - break; - - case MALI_IOC_PP_CORE_VERSION_GET: - err = pp_get_core_version_wrapper(session_data, (_mali_uk_get_pp_core_version_s __user *)arg); - break; - - case MALI_IOC_PP_DISABLE_WB: - err = pp_disable_wb_wrapper(session_data, (_mali_uk_pp_disable_wb_s __user *)arg); - break; - - case MALI_IOC_GP2_START_JOB: - err = gp_start_job_wrapper(session_data, (_mali_uk_gp_start_job_s __user *)arg); - break; - - case MALI_IOC_GP2_NUMBER_OF_CORES_GET: - err = gp_get_number_of_cores_wrapper(session_data, (_mali_uk_get_gp_number_of_cores_s __user *)arg); - break; - - case MALI_IOC_GP2_CORE_VERSION_GET: - err = gp_get_core_version_wrapper(session_data, (_mali_uk_get_gp_core_version_s __user *)arg); - break; - - case MALI_IOC_GP2_SUSPEND_RESPONSE: - err = gp_suspend_response_wrapper(session_data, (_mali_uk_gp_suspend_response_s __user *)arg); - break; - - case MALI_IOC_VSYNC_EVENT_REPORT: - err = vsync_event_report_wrapper(session_data, (_mali_uk_vsync_event_report_s __user *)arg); - break; - - case MALI_IOC_MEM_GET_BIG_BLOCK: /* Fallthrough */ - case MALI_IOC_MEM_FREE_BIG_BLOCK: - MALI_PRINT_ERROR(("Non-MMU mode is no longer supported.\n")); - err = -ENOTTY; - break; - - default: - MALI_DEBUG_PRINT(2, ("No handler for ioctl 0x%08X 0x%08lX\n", cmd, arg)); - err = -ENOTTY; - }; - - return err; -} - - -module_init(mali_driver_init); -module_exit(mali_driver_exit); - -MODULE_LICENSE(MALI_KERNEL_LINUX_LICENSE); -MODULE_AUTHOR("ARM Ltd."); -MODULE_VERSION(SVN_REV_STRING); diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_linux.h b/drivers/media/video/samsung/mali/linux/mali_kernel_linux.h deleted file mode 100644 index 22dc9a4..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_kernel_linux.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_KERNEL_LINUX_H__ -#define __MALI_KERNEL_LINUX_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include /* character device definitions */ -#include "mali_kernel_license.h" -#include "mali_osk.h" - -struct mali_dev -{ - struct cdev cdev; -#if MALI_LICENSE_IS_GPL - struct class * mali_class; -#endif -}; - -#if MALI_LICENSE_IS_GPL -/* Defined in mali_osk_irq.h */ -extern struct workqueue_struct * mali_wq; -#endif - -void mali_osk_low_level_mem_init(void); -void mali_osk_low_level_mem_term(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __MALI_KERNEL_LINUX_H__ */ diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_pm.c b/drivers/media/video/samsung/mali/linux/mali_kernel_pm.c deleted file mode 100644 index 4639d55..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_kernel_pm.c +++ /dev/null @@ -1,268 +0,0 @@ -/** - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_kernel_pm.c - * Linux Power Management integration - */ - -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_PM_RUNTIME -#include -#endif -#include "mali_osk.h" -#include "mali_uk_types.h" -#include "mali_kernel_common.h" -#include "mali_kernel_license.h" -#include "mali_linux_pm.h" -#include "mali_pm.h" -#include "mali_platform.h" - -#if ! MALI_LICENSE_IS_GPL -#undef CONFIG_PM_RUNTIME -#endif - -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON -extern void set_mali_parent_power_domain(struct platform_device* dev); -#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ -static int mali_probe(struct platform_device *pdev); -static int mali_remove(struct platform_device *pdev); - -#ifdef CONFIG_PM_RUNTIME -static int mali_runtime_suspend(struct device *dev); -static int mali_runtime_resume(struct device *dev); -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) -static int mali_os_suspend(struct platform_device *pdev, pm_message_t state); -static int mali_os_resume(struct platform_device *pdev); -#else -static int mali_os_suspend(struct device *dev); -static int mali_os_resume(struct device *dev); -#endif - - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) -static const struct dev_pm_ops mali_dev_pm_ops = -{ -#ifdef CONFIG_PM_RUNTIME - .runtime_suspend = mali_runtime_suspend, - .runtime_resume = mali_runtime_resume, - .runtime_idle = NULL, -#else - .suspend = mali_os_suspend, - .resume = mali_os_resume, -#endif - .freeze = mali_os_suspend, - .poweroff = mali_os_suspend, - .thaw = mali_os_resume, - .restore = mali_os_resume, -}; -#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) -struct pm_ext_ops mali_ext_pm_operations = -{ - .base = - { - .freeze = mali_os_suspend, - .thaw = mali_os_resume, - .poweroff = mali_os_suspend, - .restore = mali_os_resume, - }, -}; -#endif - - -static struct platform_driver mali_plat_driver = -{ - .probe = mali_probe, - .remove = mali_remove, -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) - .suspend = mali_os_suspend, - .resume = mali_os_resume, - .pm = &mali_ext_pm_operations, -#endif - - .driver = - { - .name = "mali_dev", - .owner = THIS_MODULE, -#if MALI_LICENSE_IS_GPL - .bus = &platform_bus_type, -#endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) - .pm = &mali_dev_pm_ops, -#endif - }, -}; - -#ifdef CONFIG_PM_RUNTIME -static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long event,void* dummy); - -static struct notifier_block mali_pwr_notif_block = -{ - .notifier_call = mali_pwr_suspend_notifier -}; -#endif - -/** This function is called when platform device is unregistered. This function - * is necessary when the platform device is unregistered. - */ -static void _mali_release_pm(struct device *device) -{ -} -struct platform_device mali_gpu_device = -{ - .name = "mali_dev", - .id = 0, - .dev.release = _mali_release_pm -}; - -/** This function is called when the device is probed */ -static int mali_probe(struct platform_device *pdev) -{ - return 0; -} - -static int mali_remove(struct platform_device *pdev) -{ -#ifdef CONFIG_PM_RUNTIME - pm_runtime_disable(&pdev->dev); -#endif - return 0; -} - -#ifdef CONFIG_PM_RUNTIME -static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long event,void* dummy) -{ - switch (event) - { - case PM_SUSPEND_PREPARE: - MALI_DEBUG_PRINT(2, ("mali_pwr_suspend_notifier(PM_SUSPEND_PREPARE) called\n")); - mali_pm_os_suspend(); - break; - case PM_POST_SUSPEND: - MALI_DEBUG_PRINT(2, ("mali_pwr_suspend_notifier(PM_SUSPEND_PREPARE) called\n")); - mali_pm_os_resume(); - break; - default: - break; - } - return 0; -} -#endif - - -#ifdef CONFIG_PM_RUNTIME - -static int mali_runtime_suspend(struct device *dev) -{ - MALI_DEBUG_PRINT(3, ("mali_runtime_suspend() called\n")); - mali_pm_runtime_suspend(); - return 0; /* all ok */ -} - -static int mali_runtime_resume(struct device *dev) -{ - MALI_DEBUG_PRINT(3, ("mali_runtime_resume() called\n")); - mali_pm_runtime_resume(); - return 0; /* all ok */ -} - -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) - -static int mali_os_suspend(struct platform_device *pdev, pm_message_t state) -{ - MALI_DEBUG_PRINT(3, ("mali_os_suspend(old) called\n")); - mali_pm_os_suspend(); - return 0; /* all ok */ -} - -static int mali_os_resume(struct platform_device *pdev) -{ - MALI_DEBUG_PRINT(3, ("mali_os_resume(old) called\n")); - mali_pm_os_resume(); - return 0; /* all ok */ -} - -#else - -static int mali_os_suspend(struct device *dev) -{ - MALI_DEBUG_PRINT(3, ("mali_os_suspend(new) called\n")); - mali_pm_os_suspend(); - return 0; /* all ok */ -} - -static int mali_os_resume(struct device *dev) -{ - MALI_DEBUG_PRINT(3, ("mali_os_resume(new) called\n")); - mali_pm_os_resume(); - return 0; /* all ok */ -} - -#endif - -/** This function is called when Mali GPU device is initialized - */ -int _mali_dev_platform_register(void) -{ - int err; - -#ifdef CONFIG_PM_RUNTIME - set_mali_parent_power_domain((void *)&mali_gpu_device); -#endif - -#ifdef CONFIG_PM_RUNTIME - err = register_pm_notifier(&mali_pwr_notif_block); - if (err) - { - return err; - } -#endif - -#if MALI_LICENSE_IS_GPL - err = platform_device_register(&mali_gpu_device); - if (!err) - { - err = platform_driver_register(&mali_plat_driver); - if (err) - { -#ifdef CONFIG_PM_RUNTIME - unregister_pm_notifier(&mali_pwr_notif_block); -#endif - platform_device_unregister(&mali_gpu_device); - } - } -#endif - - return err; -} - -/** This function is called when Mali GPU device is unloaded - */ -void _mali_dev_platform_unregister(void) -{ -#ifdef CONFIG_PM_RUNTIME - unregister_pm_notifier(&mali_pwr_notif_block); -#endif - -#if MALI_LICENSE_IS_GPL - platform_driver_unregister(&mali_plat_driver); - platform_device_unregister(&mali_gpu_device); -#endif -} - diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_pm.h b/drivers/media/video/samsung/mali/linux/mali_kernel_pm.h deleted file mode 100644 index 6ef7270..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_kernel_pm.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_KERNEL_PM_H__ -#define __MALI_KERNEL_PM_H__ - -int _mali_dev_platform_register(void); -void _mali_dev_platform_unregister(void); - -#endif /* __MALI_KERNEL_PM_H__ */ diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.c b/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.c deleted file mode 100644 index e2dc17b..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.c +++ /dev/null @@ -1,1280 +0,0 @@ -/** - * Copyright (C) 2011-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -/** - * @file mali_kernel_sysfs.c - * Implementation of some sysfs data exports - */ - -#include -#include -#include -#include -#include "mali_kernel_license.h" -#include "mali_kernel_common.h" -#include "mali_kernel_linux.h" -#include "mali_ukk.h" - -#if MALI_LICENSE_IS_GPL - -#include -#include -#include -#include -#include "mali_kernel_sysfs.h" -#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED -#include -#include "mali_osk_profiling.h" -#endif -#include "mali_pm.h" -#include "mali_cluster.h" -#include "mali_group.h" -#include "mali_gp.h" -#include "mali_pp.h" -#include "mali_l2_cache.h" -#include "mali_hw_core.h" -#include "mali_kernel_core.h" -#include "mali_user_settings_db.h" -#include "mali_device_pause_resume.h" - -#define POWER_BUFFER_SIZE 3 - -struct device *mali_device; -static struct dentry *mali_debugfs_dir = NULL; - -typedef enum -{ - _MALI_DEVICE_SUSPEND, - _MALI_DEVICE_RESUME, - _MALI_DEVICE_DVFS_PAUSE, - _MALI_DEVICE_DVFS_RESUME, - _MALI_MAX_EVENTS -} _mali_device_debug_power_events; - -static const char* const mali_power_events[_MALI_MAX_EVENTS] = { - [_MALI_DEVICE_SUSPEND] = "suspend", - [_MALI_DEVICE_RESUME] = "resume", - [_MALI_DEVICE_DVFS_PAUSE] = "dvfs_pause", - [_MALI_DEVICE_DVFS_RESUME] = "dvfs_resume", -}; - -static u32 virtual_power_status_register=0; -static char pwr_buf[POWER_BUFFER_SIZE]; - -static int open_copy_private_data(struct inode *inode, struct file *filp) -{ - filp->private_data = inode->i_private; - return 0; -} - -static ssize_t gp_gpx_counter_srcx_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *gpos, u32 src_id) -{ - char buf[64]; - int r; - u32 val; - struct mali_gp_core *gp_core = (struct mali_gp_core *)filp->private_data; - - if (0 == src_id) - { - val = mali_gp_core_get_counter_src0(gp_core); - } - else - { - val = mali_gp_core_get_counter_src1(gp_core); - } - - if (MALI_HW_CORE_NO_COUNTER == val) - { - r = sprintf(buf, "-1\n"); - } - else - { - r = sprintf(buf, "%u\n", val); - } - return simple_read_from_buffer(ubuf, cnt, gpos, buf, r); -} - -static ssize_t gp_gpx_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos, u32 src_id) -{ - struct mali_gp_core *gp_core = (struct mali_gp_core *)filp->private_data; - char buf[64]; - long val; - int ret; - - if (cnt >= sizeof(buf)) - { - return -EINVAL; - } - - if (copy_from_user(&buf, ubuf, cnt)) - { - return -EFAULT; - } - - buf[cnt] = 0; - - ret = strict_strtol(buf, 10, &val); - if (ret < 0) - { - return ret; - } - - if (val < 0) - { - /* any negative input will disable counter */ - val = MALI_HW_CORE_NO_COUNTER; - } - - if (0 == src_id) - { - if (MALI_TRUE != mali_gp_core_set_counter_src0(gp_core, (u32)val)) - { - return 0; - } - } - else - { - if (MALI_TRUE != mali_gp_core_set_counter_src1(gp_core, (u32)val)) - { - return 0; - } - } - - *gpos += cnt; - return cnt; -} - -static ssize_t gp_all_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos, u32 src_id) -{ - char buf[64]; - long val; - int ret; - u32 ci; - struct mali_cluster *cluster; - - if (cnt >= sizeof(buf)) - { - return -EINVAL; - } - - if (copy_from_user(&buf, ubuf, cnt)) - { - return -EFAULT; - } - - buf[cnt] = 0; - - ret = strict_strtol(buf, 10, &val); - if (ret < 0) - { - return ret; - } - - if (val < 0) - { - /* any negative input will disable counter */ - val = MALI_HW_CORE_NO_COUNTER; - } - - ci = 0; - cluster = mali_cluster_get_global_cluster(ci); - while (NULL != cluster) - { - u32 gi = 0; - struct mali_group *group = mali_cluster_get_group(cluster, gi); - while (NULL != group) - { - struct mali_gp_core *gp_core = mali_group_get_gp_core(group); - if (NULL != gp_core) - { - if (0 == src_id) - { - if (MALI_TRUE != mali_gp_core_set_counter_src0(gp_core, (u32)val)) - { - return 0; - } - } - else - { - if (MALI_TRUE != mali_gp_core_set_counter_src1(gp_core, (u32)val)) - { - return 0; - } - } - } - - /* try next group */ - gi++; - group = mali_cluster_get_group(cluster, gi); - } - - /* try next cluster */ - ci++; - cluster = mali_cluster_get_global_cluster(ci); - } - - *gpos += cnt; - return cnt; -} - -static ssize_t gp_gpx_counter_src0_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *gpos) -{ - return gp_gpx_counter_srcx_read(filp, ubuf, cnt, gpos, 0); -} - -static ssize_t gp_gpx_counter_src1_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *gpos) -{ - return gp_gpx_counter_srcx_read(filp, ubuf, cnt, gpos, 1); -} - -static ssize_t gp_gpx_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos) -{ - return gp_gpx_counter_srcx_write(filp, ubuf, cnt, gpos, 0); -} - -static ssize_t gp_gpx_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos) -{ - return gp_gpx_counter_srcx_write(filp, ubuf, cnt, gpos, 1); -} - -static ssize_t gp_all_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos) -{ - return gp_all_counter_srcx_write(filp, ubuf, cnt, gpos, 0); -} - -static ssize_t gp_all_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos) -{ - return gp_all_counter_srcx_write(filp, ubuf, cnt, gpos, 1); -} - -static const struct file_operations gp_gpx_counter_src0_fops = { - .owner = THIS_MODULE, - .open = open_copy_private_data, - .read = gp_gpx_counter_src0_read, - .write = gp_gpx_counter_src0_write, -}; - -static const struct file_operations gp_gpx_counter_src1_fops = { - .owner = THIS_MODULE, - .open = open_copy_private_data, - .read = gp_gpx_counter_src1_read, - .write = gp_gpx_counter_src1_write, -}; - -static const struct file_operations gp_all_counter_src0_fops = { - .owner = THIS_MODULE, - .write = gp_all_counter_src0_write, -}; - -static const struct file_operations gp_all_counter_src1_fops = { - .owner = THIS_MODULE, - .write = gp_all_counter_src1_write, -}; - -static ssize_t pp_ppx_counter_srcx_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id) -{ - char buf[64]; - int r; - u32 val; - struct mali_pp_core *pp_core = (struct mali_pp_core *)filp->private_data; - - if (0 == src_id) - { - val = mali_pp_core_get_counter_src0(pp_core); - } - else - { - val = mali_pp_core_get_counter_src1(pp_core); - } - - if (MALI_HW_CORE_NO_COUNTER == val) - { - r = sprintf(buf, "-1\n"); - } - else - { - r = sprintf(buf, "%u\n", val); - } - return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); -} - -static ssize_t pp_ppx_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id) -{ - struct mali_pp_core *pp_core = (struct mali_pp_core *)filp->private_data; - char buf[64]; - long val; - int ret; - - if (cnt >= sizeof(buf)) - { - return -EINVAL; - } - - if (copy_from_user(&buf, ubuf, cnt)) - { - return -EFAULT; - } - - buf[cnt] = 0; - - ret = strict_strtol(buf, 10, &val); - if (ret < 0) - { - return ret; - } - - if (val < 0) - { - /* any negative input will disable counter */ - val = MALI_HW_CORE_NO_COUNTER; - } - - if (0 == src_id) - { - if (MALI_TRUE != mali_pp_core_set_counter_src0(pp_core, (u32)val)) - { - return 0; - } - } - else - { - if (MALI_TRUE != mali_pp_core_set_counter_src1(pp_core, (u32)val)) - { - return 0; - } - } - - *ppos += cnt; - return cnt; -} - -static ssize_t pp_all_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id) -{ - char buf[64]; - long val; - int ret; - u32 ci; - struct mali_cluster *cluster; - - if (cnt >= sizeof(buf)) - { - return -EINVAL; - } - - if (copy_from_user(&buf, ubuf, cnt)) - { - return -EFAULT; - } - - buf[cnt] = 0; - - ret = strict_strtol(buf, 10, &val); - if (ret < 0) - { - return ret; - } - - if (val < 0) - { - /* any negative input will disable counter */ - val = MALI_HW_CORE_NO_COUNTER; - } - - ci = 0; - cluster = mali_cluster_get_global_cluster(ci); - while (NULL != cluster) - { - u32 gi = 0; - struct mali_group *group = mali_cluster_get_group(cluster, gi); - while (NULL != group) - { - struct mali_pp_core *pp_core = mali_group_get_pp_core(group); - if (NULL != pp_core) - { - if (0 == src_id) - { - if (MALI_TRUE != mali_pp_core_set_counter_src0(pp_core, (u32)val)) - { - return 0; - } - } - else - { - if (MALI_TRUE != mali_pp_core_set_counter_src1(pp_core, (u32)val)) - { - return 0; - } - } - } - - /* try next group */ - gi++; - group = mali_cluster_get_group(cluster, gi); - } - - /* try next cluster */ - ci++; - cluster = mali_cluster_get_global_cluster(ci); - } - - *ppos += cnt; - return cnt; -} - -static ssize_t pp_ppx_counter_src0_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) -{ - return pp_ppx_counter_srcx_read(filp, ubuf, cnt, ppos, 0); -} - -static ssize_t pp_ppx_counter_src1_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) -{ - return pp_ppx_counter_srcx_read(filp, ubuf, cnt, ppos, 1); -} - -static ssize_t pp_ppx_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) -{ - return pp_ppx_counter_srcx_write(filp, ubuf, cnt, ppos, 0); -} - -static ssize_t pp_ppx_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) -{ - return pp_ppx_counter_srcx_write(filp, ubuf, cnt, ppos, 1); -} - -static ssize_t pp_all_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) -{ - return pp_all_counter_srcx_write(filp, ubuf, cnt, ppos, 0); -} - -static ssize_t pp_all_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) -{ - return pp_all_counter_srcx_write(filp, ubuf, cnt, ppos, 1); -} - -static const struct file_operations pp_ppx_counter_src0_fops = { - .owner = THIS_MODULE, - .open = open_copy_private_data, - .read = pp_ppx_counter_src0_read, - .write = pp_ppx_counter_src0_write, -}; - -static const struct file_operations pp_ppx_counter_src1_fops = { - .owner = THIS_MODULE, - .open = open_copy_private_data, - .read = pp_ppx_counter_src1_read, - .write = pp_ppx_counter_src1_write, -}; - -static const struct file_operations pp_all_counter_src0_fops = { - .owner = THIS_MODULE, - .write = pp_all_counter_src0_write, -}; - -static const struct file_operations pp_all_counter_src1_fops = { - .owner = THIS_MODULE, - .write = pp_all_counter_src1_write, -}; - - - - - - -static ssize_t l2_l2x_counter_srcx_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id) -{ - char buf[64]; - int r; - u32 val; - struct mali_l2_cache_core *l2_core = (struct mali_l2_cache_core *)filp->private_data; - - if (0 == src_id) - { - val = mali_l2_cache_core_get_counter_src0(l2_core); - } - else - { - val = mali_l2_cache_core_get_counter_src1(l2_core); - } - - if (MALI_HW_CORE_NO_COUNTER == val) - { - r = sprintf(buf, "-1\n"); - } - else - { - r = sprintf(buf, "%u\n", val); - } - return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); -} - -static ssize_t l2_l2x_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id) -{ - struct mali_l2_cache_core *l2_core = (struct mali_l2_cache_core *)filp->private_data; - char buf[64]; - long val; - int ret; - - if (cnt >= sizeof(buf)) - { - return -EINVAL; - } - - if (copy_from_user(&buf, ubuf, cnt)) - { - return -EFAULT; - } - - buf[cnt] = 0; - - ret = strict_strtol(buf, 10, &val); - if (ret < 0) - { - return ret; - } - - if (val < 0) - { - /* any negative input will disable counter */ - val = MALI_HW_CORE_NO_COUNTER; - } - - if (0 == src_id) - { - if (MALI_TRUE != mali_l2_cache_core_set_counter_src0(l2_core, (u32)val)) - { - return 0; - } - } - else - { - if (MALI_TRUE != mali_l2_cache_core_set_counter_src1(l2_core, (u32)val)) - { - return 0; - } - } - - *ppos += cnt; - return cnt; -} - -static ssize_t l2_all_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id) -{ - char buf[64]; - long val; - int ret; - u32 l2_id; - struct mali_l2_cache_core *l2_cache; - - if (cnt >= sizeof(buf)) - { - return -EINVAL; - } - - if (copy_from_user(&buf, ubuf, cnt)) - { - return -EFAULT; - } - - buf[cnt] = 0; - - ret = strict_strtol(buf, 10, &val); - if (ret < 0) - { - return ret; - } - - if (val < 0) - { - /* any negative input will disable counter */ - val = MALI_HW_CORE_NO_COUNTER; - } - - l2_id = 0; - l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id); - while (NULL != l2_cache) - { - if (0 == src_id) - { - if (MALI_TRUE != mali_l2_cache_core_set_counter_src0(l2_cache, (u32)val)) - { - return 0; - } - } - else - { - if (MALI_TRUE != mali_l2_cache_core_set_counter_src1(l2_cache, (u32)val)) - { - return 0; - } - } - - /* try next L2 */ - l2_id++; - l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id); - } - - *ppos += cnt; - return cnt; -} - -static ssize_t l2_l2x_counter_src0_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) -{ - return l2_l2x_counter_srcx_read(filp, ubuf, cnt, ppos, 0); -} - -static ssize_t l2_l2x_counter_src1_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) -{ - return l2_l2x_counter_srcx_read(filp, ubuf, cnt, ppos, 1); -} - -static ssize_t l2_l2x_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) -{ - return l2_l2x_counter_srcx_write(filp, ubuf, cnt, ppos, 0); -} - -static ssize_t l2_l2x_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) -{ - return l2_l2x_counter_srcx_write(filp, ubuf, cnt, ppos, 1); -} - -static ssize_t l2_all_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) -{ - return l2_all_counter_srcx_write(filp, ubuf, cnt, ppos, 0); -} - -static ssize_t l2_all_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) -{ - return l2_all_counter_srcx_write(filp, ubuf, cnt, ppos, 1); -} - -static const struct file_operations l2_l2x_counter_src0_fops = { - .owner = THIS_MODULE, - .open = open_copy_private_data, - .read = l2_l2x_counter_src0_read, - .write = l2_l2x_counter_src0_write, -}; - -static const struct file_operations l2_l2x_counter_src1_fops = { - .owner = THIS_MODULE, - .open = open_copy_private_data, - .read = l2_l2x_counter_src1_read, - .write = l2_l2x_counter_src1_write, -}; - -static const struct file_operations l2_all_counter_src0_fops = { - .owner = THIS_MODULE, - .write = l2_all_counter_src0_write, -}; - -static const struct file_operations l2_all_counter_src1_fops = { - .owner = THIS_MODULE, - .write = l2_all_counter_src1_write, -}; - -static ssize_t power_events_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) -{ - - memset(pwr_buf,0,POWER_BUFFER_SIZE); - virtual_power_status_register = 0; - if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_SUSPEND],strlen(mali_power_events[_MALI_DEVICE_SUSPEND]))) - { - mali_pm_os_suspend(); - /* @@@@ assuming currently suspend is successful later on to tune as per previous*/ - virtual_power_status_register =1; - - } - else if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_RESUME],strlen(mali_power_events[_MALI_DEVICE_RESUME]))) - { - mali_pm_os_resume(); - - /* @@@@ assuming currently resume is successful later on to tune as per previous */ - virtual_power_status_register = 1; - } - else if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_DVFS_PAUSE],strlen(mali_power_events[_MALI_DEVICE_DVFS_PAUSE]))) - { - mali_bool power_on; - mali_dev_pause(&power_on); - if (!power_on) - { - virtual_power_status_register = 2; - mali_dev_resume(); - } - else - { - /* @@@@ assuming currently resume is successful later on to tune as per previous */ - virtual_power_status_register =1; - } - } - else if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_DVFS_RESUME],strlen(mali_power_events[_MALI_DEVICE_DVFS_RESUME]))) - { - mali_dev_resume(); - /* @@@@ assuming currently resume is successful later on to tune as per previous */ - virtual_power_status_register = 1; - - } - *ppos += cnt; - sprintf(pwr_buf, "%d",virtual_power_status_register); - return cnt; -} - -static ssize_t power_events_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) -{ - return simple_read_from_buffer(ubuf, cnt, ppos, pwr_buf, POWER_BUFFER_SIZE); -} - -static loff_t power_events_seek(struct file *file, loff_t offset, int orig) -{ - file->f_pos = offset; - return 0; -} - -static const struct file_operations power_events_fops = { - .owner = THIS_MODULE, - .read = power_events_read, - .write = power_events_write, - .llseek = power_events_seek, -}; - - -#if MALI_STATE_TRACKING -static int mali_seq_internal_state_show(struct seq_file *seq_file, void *v) -{ - u32 len = 0; - u32 size; - char *buf; - - size = seq_get_buf(seq_file, &buf); - - if(!size) - { - return -ENOMEM; - } - - /* Create the internal state dump. */ - len = snprintf(buf+len, size-len, "Mali device driver %s\n", SVN_REV_STRING); - len += snprintf(buf+len, size-len, "License: %s\n\n", MALI_KERNEL_LINUX_LICENSE); - - len += _mali_kernel_core_dump_state(buf + len, size - len); - - seq_commit(seq_file, len); - - return 0; -} - -static int mali_seq_internal_state_open(struct inode *inode, struct file *file) -{ - return single_open(file, mali_seq_internal_state_show, NULL); -} - -static const struct file_operations mali_seq_internal_state_fops = { - .owner = THIS_MODULE, - .open = mali_seq_internal_state_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; -#endif /* MALI_STATE_TRACKING */ - - -#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED -static ssize_t profiling_record_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) -{ - char buf[64]; - int r; - - r = sprintf(buf, "%u\n", _mali_osk_profiling_is_recording() ? 1 : 0); - return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); -} - -static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) -{ - char buf[64]; - unsigned long val; - int ret; - - if (cnt >= sizeof(buf)) - { - return -EINVAL; - } - - if (copy_from_user(&buf, ubuf, cnt)) - { - return -EFAULT; - } - - buf[cnt] = 0; - - ret = strict_strtoul(buf, 10, &val); - if (ret < 0) - { - return ret; - } - - if (val != 0) - { - u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* This can be made configurable at a later stage if we need to */ - - /* check if we are already recording */ - if (MALI_TRUE == _mali_osk_profiling_is_recording()) - { - MALI_DEBUG_PRINT(3, ("Recording of profiling events already in progress\n")); - return -EFAULT; - } - - /* check if we need to clear out an old recording first */ - if (MALI_TRUE == _mali_osk_profiling_have_recording()) - { - if (_MALI_OSK_ERR_OK != _mali_osk_profiling_clear()) - { - MALI_DEBUG_PRINT(3, ("Failed to clear existing recording of profiling events\n")); - return -EFAULT; - } - } - - /* start recording profiling data */ - if (_MALI_OSK_ERR_OK != _mali_osk_profiling_start(&limit)) - { - MALI_DEBUG_PRINT(3, ("Failed to start recording of profiling events\n")); - return -EFAULT; - } - - MALI_DEBUG_PRINT(3, ("Profiling recording started (max %u events)\n", limit)); - } - else - { - /* stop recording profiling data */ - u32 count = 0; - if (_MALI_OSK_ERR_OK != _mali_osk_profiling_stop(&count)) - { - MALI_DEBUG_PRINT(2, ("Failed to stop recording of profiling events\n")); - return -EFAULT; - } - - MALI_DEBUG_PRINT(2, ("Profiling recording stopped (recorded %u events)\n", count)); - } - - *ppos += cnt; - return cnt; -} - -static const struct file_operations profiling_record_fops = { - .owner = THIS_MODULE, - .read = profiling_record_read, - .write = profiling_record_write, -}; - -static void *profiling_events_start(struct seq_file *s, loff_t *pos) -{ - loff_t *spos; - - /* check if we have data avaiable */ - if (MALI_TRUE != _mali_osk_profiling_have_recording()) - { - return NULL; - } - - spos = kmalloc(sizeof(loff_t), GFP_KERNEL); - if (NULL == spos) - { - return NULL; - } - - *spos = *pos; - return spos; -} - -static void *profiling_events_next(struct seq_file *s, void *v, loff_t *pos) -{ - loff_t *spos = v; - - /* check if we have data avaiable */ - if (MALI_TRUE != _mali_osk_profiling_have_recording()) - { - return NULL; - } - - /* check if the next entry actually is avaiable */ - if (_mali_osk_profiling_get_count() <= (u32)(*spos + 1)) - { - return NULL; - } - - *pos = ++*spos; - return spos; -} - -static void profiling_events_stop(struct seq_file *s, void *v) -{ - kfree(v); -} - -static int profiling_events_show(struct seq_file *seq_file, void *v) -{ - loff_t *spos = v; - u32 index; - u64 timestamp; - u32 event_id; - u32 data[5]; - - index = (u32)*spos; - - /* Retrieve all events */ - if (_MALI_OSK_ERR_OK == _mali_osk_profiling_get_event(index, ×tamp, &event_id, data)) - { - seq_printf(seq_file, "%llu %u %u %u %u %u %u\n", timestamp, event_id, data[0], data[1], data[2], data[3], data[4]); - return 0; - } - - return 0; -} - -static const struct seq_operations profiling_events_seq_ops = { - .start = profiling_events_start, - .next = profiling_events_next, - .stop = profiling_events_stop, - .show = profiling_events_show -}; - -static int profiling_events_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &profiling_events_seq_ops); -} - -static const struct file_operations profiling_events_fops = { - .owner = THIS_MODULE, - .open = profiling_events_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; -#endif - -static ssize_t memory_used_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) -{ - char buf[64]; - size_t r; - u32 mem = _mali_ukk_report_memory_usage(); - - r = snprintf(buf, 64, "%u\n", mem); - return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); -} - -static const struct file_operations memory_usage_fops = { - .owner = THIS_MODULE, - .read = memory_used_read, -}; - - -static ssize_t user_settings_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) -{ - unsigned long val; - int ret; - _mali_uk_user_setting_t setting; - char buf[32]; - - cnt = min(cnt, sizeof(buf) - 1); - if (copy_from_user(buf, ubuf, cnt)) - { - return -EFAULT; - } - buf[cnt] = '\0'; - - ret = strict_strtoul(buf, 10, &val); - if (0 != ret) - { - return ret; - } - - /* Update setting */ - setting = (_mali_uk_user_setting_t)(filp->private_data); - mali_set_user_setting(setting, val); - - *ppos += cnt; - return cnt; -} - -static ssize_t user_settings_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) -{ - char buf[64]; - size_t r; - u32 value; - _mali_uk_user_setting_t setting; - - setting = (_mali_uk_user_setting_t)(filp->private_data); - value = mali_get_user_setting(setting); - - r = snprintf(buf, 64, "%u\n", value); - return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); -} - -static const struct file_operations user_settings_fops = { - .owner = THIS_MODULE, - .open = open_copy_private_data, - .read = user_settings_read, - .write = user_settings_write, -}; - -static int mali_sysfs_user_settings_register(void) -{ - struct dentry *mali_user_settings_dir = debugfs_create_dir("userspace_settings", mali_debugfs_dir); - - if (mali_user_settings_dir != NULL) - { - int i; - for (i = 0; i < _MALI_UK_USER_SETTING_MAX; i++) - { - debugfs_create_file(_mali_uk_user_setting_descriptions[i], 0600, mali_user_settings_dir, (void*)i, &user_settings_fops); - } - } - - return 0; -} - -int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev_name) -{ - int err = 0; - - device->mali_class = class_create(THIS_MODULE, mali_dev_name); - if (IS_ERR(device->mali_class)) - { - err = PTR_ERR(device->mali_class); - goto init_class_err; - } - mali_device = device_create(device->mali_class, NULL, dev, NULL, mali_dev_name); - if (IS_ERR(mali_device)) - { - err = PTR_ERR(mali_device); - goto init_mdev_err; - } - - mali_debugfs_dir = debugfs_create_dir(mali_dev_name, NULL); - if(ERR_PTR(-ENODEV) == mali_debugfs_dir) - { - /* Debugfs not supported. */ - mali_debugfs_dir = NULL; - } - else - { - if(NULL != mali_debugfs_dir) - { - /* Debugfs directory created successfully; create files now */ - struct dentry *mali_power_dir; - struct dentry *mali_gp_dir; - struct dentry *mali_pp_dir; - struct dentry *mali_l2_dir; -#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED - struct dentry *mali_profiling_dir; -#endif - - mali_power_dir = debugfs_create_dir("power", mali_debugfs_dir); - if (mali_power_dir != NULL) - { - debugfs_create_file("power_events", 0400, mali_power_dir, NULL, &power_events_fops); - } - - mali_gp_dir = debugfs_create_dir("gp", mali_debugfs_dir); - if (mali_gp_dir != NULL) - { - struct dentry *mali_gp_all_dir; - u32 ci; - struct mali_cluster *cluster; - - mali_gp_all_dir = debugfs_create_dir("all", mali_gp_dir); - if (mali_gp_all_dir != NULL) - { - debugfs_create_file("counter_src0", 0400, mali_gp_all_dir, NULL, &gp_all_counter_src0_fops); - debugfs_create_file("counter_src1", 0400, mali_gp_all_dir, NULL, &gp_all_counter_src1_fops); - } - - ci = 0; - cluster = mali_cluster_get_global_cluster(ci); - while (NULL != cluster) - { - u32 gi = 0; - struct mali_group *group = mali_cluster_get_group(cluster, gi); - while (NULL != group) - { - struct mali_gp_core *gp_core = mali_group_get_gp_core(group); - if (NULL != gp_core) - { - struct dentry *mali_gp_gpx_dir; - mali_gp_gpx_dir = debugfs_create_dir("gp0", mali_gp_dir); - if (NULL != mali_gp_gpx_dir) - { - debugfs_create_file("counter_src0", 0600, mali_gp_gpx_dir, gp_core, &gp_gpx_counter_src0_fops); - debugfs_create_file("counter_src1", 0600, mali_gp_gpx_dir, gp_core, &gp_gpx_counter_src1_fops); - } - break; /* no need to look for any other GP cores */ - } - - /* try next group */ - gi++; - group = mali_cluster_get_group(cluster, gi); - } - - /* try next cluster */ - ci++; - cluster = mali_cluster_get_global_cluster(ci); - } - } - - mali_pp_dir = debugfs_create_dir("pp", mali_debugfs_dir); - if (mali_pp_dir != NULL) - { - struct dentry *mali_pp_all_dir; - u32 ci; - struct mali_cluster *cluster; - - mali_pp_all_dir = debugfs_create_dir("all", mali_pp_dir); - if (mali_pp_all_dir != NULL) - { - debugfs_create_file("counter_src0", 0400, mali_pp_all_dir, NULL, &pp_all_counter_src0_fops); - debugfs_create_file("counter_src1", 0400, mali_pp_all_dir, NULL, &pp_all_counter_src1_fops); - } - - ci = 0; - cluster = mali_cluster_get_global_cluster(ci); - while (NULL != cluster) - { - u32 gi = 0; - struct mali_group *group = mali_cluster_get_group(cluster, gi); - while (NULL != group) - { - struct mali_pp_core *pp_core = mali_group_get_pp_core(group); - if (NULL != pp_core) - { - char buf[16]; - struct dentry *mali_pp_ppx_dir; - _mali_osk_snprintf(buf, sizeof(buf), "pp%u", mali_pp_core_get_id(pp_core)); - mali_pp_ppx_dir = debugfs_create_dir(buf, mali_pp_dir); - if (NULL != mali_pp_ppx_dir) - { - debugfs_create_file("counter_src0", 0600, mali_pp_ppx_dir, pp_core, &pp_ppx_counter_src0_fops); - debugfs_create_file("counter_src1", 0600, mali_pp_ppx_dir, pp_core, &pp_ppx_counter_src1_fops); - } - } - - /* try next group */ - gi++; - group = mali_cluster_get_group(cluster, gi); - } - - /* try next cluster */ - ci++; - cluster = mali_cluster_get_global_cluster(ci); - } - } - - mali_l2_dir = debugfs_create_dir("l2", mali_debugfs_dir); - if (mali_l2_dir != NULL) - { - struct dentry *mali_l2_all_dir; - u32 l2_id; - struct mali_l2_cache_core *l2_cache; - - mali_l2_all_dir = debugfs_create_dir("all", mali_l2_dir); - if (mali_l2_all_dir != NULL) - { - debugfs_create_file("counter_src0", 0400, mali_l2_all_dir, NULL, &l2_all_counter_src0_fops); - debugfs_create_file("counter_src1", 0400, mali_l2_all_dir, NULL, &l2_all_counter_src1_fops); - } - - l2_id = 0; - l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id); - while (NULL != l2_cache) - { - char buf[16]; - struct dentry *mali_l2_l2x_dir; - _mali_osk_snprintf(buf, sizeof(buf), "l2%u", l2_id); - mali_l2_l2x_dir = debugfs_create_dir(buf, mali_l2_dir); - if (NULL != mali_l2_l2x_dir) - { - debugfs_create_file("counter_src0", 0600, mali_l2_l2x_dir, l2_cache, &l2_l2x_counter_src0_fops); - debugfs_create_file("counter_src1", 0600, mali_l2_l2x_dir, l2_cache, &l2_l2x_counter_src1_fops); - } - - /* try next L2 */ - l2_id++; - l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id); - } - } - - debugfs_create_file("memory_usage", 0400, mali_debugfs_dir, NULL, &memory_usage_fops); - -#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED - mali_profiling_dir = debugfs_create_dir("profiling", mali_debugfs_dir); - if (mali_profiling_dir != NULL) - { - struct dentry *mali_profiling_proc_dir = debugfs_create_dir("proc", mali_profiling_dir); - if (mali_profiling_proc_dir != NULL) - { - struct dentry *mali_profiling_proc_default_dir = debugfs_create_dir("default", mali_profiling_proc_dir); - if (mali_profiling_proc_default_dir != NULL) - { - debugfs_create_file("enable", 0600, mali_profiling_proc_default_dir, (void*)_MALI_UK_USER_SETTING_SW_EVENTS_ENABLE, &user_settings_fops); - } - } - debugfs_create_file("record", 0600, mali_profiling_dir, NULL, &profiling_record_fops); - debugfs_create_file("events", 0400, mali_profiling_dir, NULL, &profiling_events_fops); - } -#endif - -#if MALI_STATE_TRACKING - debugfs_create_file("state_dump", 0400, mali_debugfs_dir, NULL, &mali_seq_internal_state_fops); -#endif - - if (mali_sysfs_user_settings_register()) - { - /* Failed to create the debugfs entries for the user settings DB. */ - MALI_DEBUG_PRINT(2, ("Failed to create user setting debugfs files. Ignoring...\n")); - } - } - } - - /* Success! */ - return 0; - - /* Error handling */ -init_mdev_err: - class_destroy(device->mali_class); -init_class_err: - - return err; -} - -int mali_sysfs_unregister(struct mali_dev *device, dev_t dev, const char *mali_dev_name) -{ - if(NULL != mali_debugfs_dir) - { - debugfs_remove_recursive(mali_debugfs_dir); - } - device_destroy(device->mali_class, dev); - class_destroy(device->mali_class); - - return 0; -} - -#else - -/* Dummy implementations for non-GPL */ - -int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev_name) -{ - return 0; -} - -int mali_sysfs_unregister(struct mali_dev *device, dev_t dev, const char *mali_dev_name) -{ - return 0; -} - - -#endif diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.h b/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.h deleted file mode 100644 index 24acca9..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2011-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_KERNEL_SYSFS_H__ -#define __MALI_KERNEL_SYSFS_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include - -#define MALI_PROC_DIR "driver/mali" - -extern struct device *mali_device; -struct mali_dev; - -int mali_sysfs_register(struct mali_dev *mali_class, dev_t dev, const char *mali_dev_name); - -int mali_sysfs_unregister(struct mali_dev *mali_class, dev_t dev, const char *mali_dev_name); - - -#ifdef __cplusplus -} -#endif - -#endif /* __MALI_KERNEL_LINUX_H__ */ diff --git a/drivers/media/video/samsung/mali/linux/mali_linux_pm.h b/drivers/media/video/samsung/mali/linux/mali_linux_pm.h deleted file mode 100644 index 10f633e..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_linux_pm.h +++ /dev/null @@ -1,50 +0,0 @@ - -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_LINUX_PM_H__ -#define __MALI_LINUX_PM_H__ - -#ifdef CONFIG_PM -/* Number of power states supported for making power up and down */ -typedef enum -{ - _MALI_DEVICE_SUSPEND, /* Suspend */ - _MALI_DEVICE_RESUME, /* Resume */ - _MALI_DEVICE_MAX_POWER_STATES, /* Maximum power states */ -} _mali_device_power_states; - -/* Number of DVFS events */ -typedef enum -{ - _MALI_DVFS_PAUSE_EVENT = _MALI_DEVICE_MAX_POWER_STATES, /* DVFS Pause event */ - _MALI_DVFS_RESUME_EVENT, /* DVFS Resume event */ - _MALI_MAX_DEBUG_OPERATIONS, -} _mali_device_dvfs_events; - -extern _mali_device_power_states mali_device_state; -extern _mali_device_power_states mali_dvfs_device_state; -extern _mali_osk_lock_t *lock; -extern short is_wake_up_needed; -extern int timeout_fired; -extern struct platform_device mali_gpu_device; - -/* dvfs pm thread */ -extern struct task_struct *dvfs_pm_thread; - -/* Power management thread */ -extern struct task_struct *pm_thread; - -int mali_device_suspend(u32 event_id, struct task_struct **pwr_mgmt_thread); -int mali_device_resume(u32 event_id, struct task_struct **pwr_mgmt_thread); -int mali_get_ospmm_thread_state(void); - -#endif /* CONFIG_PM */ -#endif /* __MALI_LINUX_PM_H___ */ diff --git a/drivers/media/video/samsung/mali/linux/mali_linux_pm_testsuite.h b/drivers/media/video/samsung/mali/linux/mali_linux_pm_testsuite.h deleted file mode 100644 index 7d811bd..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_linux_pm_testsuite.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#ifndef __MALI_LINUX_PM_TESTSUITE_H__ -#define __MALI_LINUX_PM_TESTSUITE_H__ - -#if MALI_POWER_MGMT_TEST_SUITE && defined(CONFIG_PM) - -typedef enum -{ - _MALI_DEVICE_PMM_TIMEOUT_EVENT, - _MALI_DEVICE_PMM_JOB_SCHEDULING_EVENTS, - _MALI_DEVICE_PMM_REGISTERED_CORES, - _MALI_DEVICE_MAX_PMM_EVENTS - -} _mali_device_pmm_recording_events; - -extern unsigned int mali_timeout_event_recording_on; -extern unsigned int mali_job_scheduling_events_recording_on; -extern unsigned int pwr_mgmt_status_reg; -extern unsigned int is_mali_pmm_testsuite_enabled; -extern unsigned int is_mali_pmu_present; - -#endif /* MALI_POWER_MGMT_TEST_SUITE && defined(CONFIG_PM) */ - -#endif /* __MALI_LINUX_PM_TESTSUITE_H__ */ diff --git a/drivers/media/video/samsung/mali/linux/mali_linux_trace.h b/drivers/media/video/samsung/mali/linux/mali_linux_trace.h deleted file mode 100644 index 5329ba3..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_linux_trace.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#if !defined (MALI_LINUX_TRACE_H) || defined (TRACE_HEADER_MULTI_READ) -#define MALI_LINUX_TRACE_H - -#include - -#include -#include - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM mali -#define TRACE_SYSTEM_STRING __stringfy(TRACE_SYSTEM) - -#define TRACE_INCLUDE_PATH . -#define TRACE_INCLUDE_FILE mali_linux_trace - -/** - * Define the tracepoint used to communicate the status of a GPU. Called - * when a GPU turns on or turns off. - * - * @param event_id The type of the event. This parameter is a bitfield - * encoding the type of the event. - * - * @param d0 First data parameter. - * @param d1 Second data parameter. - * @param d2 Third data parameter. - * @param d3 Fourth data parameter. - * @param d4 Fifth data parameter. - */ -TRACE_EVENT(mali_timeline_event, - - TP_PROTO(unsigned int event_id, unsigned int d0, unsigned int d1, - unsigned int d2, unsigned int d3, unsigned int d4), - - TP_ARGS(event_id, d0, d1, d2, d3, d4), - - TP_STRUCT__entry( - __field(unsigned int, event_id) - __field(unsigned int, d0) - __field(unsigned int, d1) - __field(unsigned int, d2) - __field(unsigned int, d3) - __field(unsigned int, d4) - ), - - TP_fast_assign( - __entry->event_id = event_id; - __entry->d0 = d0; - __entry->d1 = d1; - __entry->d2 = d2; - __entry->d3 = d3; - __entry->d4 = d4; - ), - - TP_printk("event=%d", __entry->event_id) -); - -/** - * Define a tracepoint used to regsiter the value of a hardware counter. - * Hardware counters belonging to the vertex or fragment processor are - * reported via this tracepoint each frame, whilst L2 cache hardware - * counters are reported continuously. - * - * @param counter_id The counter ID. - * @param value The value of the counter. - */ -TRACE_EVENT(mali_hw_counter, - - TP_PROTO(unsigned int counter_id, unsigned int value), - - TP_ARGS(counter_id, value), - - TP_STRUCT__entry( - __field(unsigned int, counter_id) - __field(unsigned int, value) - ), - - TP_fast_assign( - __entry->counter_id = counter_id; - ), - - TP_printk("event %d = %d", __entry->counter_id, __entry->value) -); - -/** - * Define a tracepoint used to send a bundle of software counters. - * - * @param counters The bundle of counters. - */ -TRACE_EVENT(mali_sw_counters, - - TP_PROTO(pid_t pid, pid_t tid, void * surface_id, unsigned int * counters), - - TP_ARGS(pid, tid, surface_id, counters), - - TP_STRUCT__entry( - __field(pid_t, pid) - __field(pid_t, tid) - __field(void *, surface_id) - __field(unsigned int *, counters) - ), - - TP_fast_assign( - __entry->pid = pid; - __entry->tid = tid; - __entry->surface_id = surface_id; - __entry->counters = counters; - ), - - TP_printk("counters were %s", __entry->counters == NULL? "NULL" : "not NULL") -); - -#endif /* MALI_LINUX_TRACE_H */ - -/* This part must exist outside the header guard. */ -#include - diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_atomics.c b/drivers/media/video/samsung/mali/linux/mali_osk_atomics.c deleted file mode 100644 index 32f8e6b..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_osk_atomics.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_osk_atomics.c - * Implementation of the OS abstraction layer for the kernel device driver - */ - -#include "mali_osk.h" -#include -#include "mali_kernel_common.h" - -void _mali_osk_atomic_dec( _mali_osk_atomic_t *atom ) -{ - atomic_dec((atomic_t *)&atom->u.val); -} - -u32 _mali_osk_atomic_dec_return( _mali_osk_atomic_t *atom ) -{ - return atomic_dec_return((atomic_t *)&atom->u.val); -} - -void _mali_osk_atomic_inc( _mali_osk_atomic_t *atom ) -{ - atomic_inc((atomic_t *)&atom->u.val); -} - -u32 _mali_osk_atomic_inc_return( _mali_osk_atomic_t *atom ) -{ - return atomic_inc_return((atomic_t *)&atom->u.val); -} - -_mali_osk_errcode_t _mali_osk_atomic_init( _mali_osk_atomic_t *atom, u32 val ) -{ - MALI_CHECK_NON_NULL(atom, _MALI_OSK_ERR_INVALID_ARGS); - atomic_set((atomic_t *)&atom->u.val, val); - return _MALI_OSK_ERR_OK; -} - -u32 _mali_osk_atomic_read( _mali_osk_atomic_t *atom ) -{ - return atomic_read((atomic_t *)&atom->u.val); -} - -void _mali_osk_atomic_term( _mali_osk_atomic_t *atom ) -{ - MALI_IGNORE(atom); -} diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_irq.c b/drivers/media/video/samsung/mali/linux/mali_osk_irq.c deleted file mode 100644 index ddfe564..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_osk_irq.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_osk_irq.c - * Implementation of the OS abstraction layer for the kernel device driver - */ - -#include /* For memory allocation */ -#include -#include - -#include "mali_osk.h" -#include "mali_kernel_common.h" -#include "mali_kernel_license.h" -#include "mali_kernel_linux.h" -#include "linux/interrupt.h" - -typedef struct _mali_osk_irq_t_struct -{ - u32 irqnum; - void *data; - _mali_osk_irq_uhandler_t uhandler; - _mali_osk_irq_bhandler_t bhandler; - struct work_struct work_queue_irq_handle; /* Workqueue for the bottom half of the IRQ-handling. This job is activated when this core gets an IRQ.*/ -} mali_osk_irq_object_t; - -#if MALI_LICENSE_IS_GPL -static struct workqueue_struct *pmm_wq = NULL; -struct workqueue_struct *mali_wq = NULL; -#endif - -typedef void (*workqueue_func_t)(void *); -typedef irqreturn_t (*irq_handler_func_t)(int, void *, struct pt_regs *); -static irqreturn_t irq_handler_upper_half (int port_name, void* dev_id ); /* , struct pt_regs *regs*/ - -#if defined(INIT_DELAYED_WORK) -static void irq_handler_bottom_half ( struct work_struct *work ); -#else -static void irq_handler_bottom_half ( void * input ); -#endif - -/** - * Linux kernel version has marked SA_SHIRQ as deprecated, IRQF_SHARED should be used. - * This is to handle older kernels which haven't done this swap. - */ -#ifndef IRQF_SHARED -#define IRQF_SHARED SA_SHIRQ -#endif /* IRQF_SHARED */ - -_mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandler, _mali_osk_irq_bhandler_t bhandler, _mali_osk_irq_trigger_t trigger_func, _mali_osk_irq_ack_t ack_func, void *data, const char *description ) -{ - mali_osk_irq_object_t *irq_object; - - irq_object = kmalloc(sizeof(mali_osk_irq_object_t), GFP_KERNEL); - if (NULL == irq_object) return NULL; - -#if MALI_LICENSE_IS_GPL - if (NULL == mali_wq) - { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) - mali_wq = alloc_workqueue("mali", WQ_UNBOUND, 0); -#else - mali_wq = create_workqueue("mali"); -#endif - if(NULL == mali_wq) - { - MALI_PRINT_ERROR(("Unable to create Mali workqueue\n")); - kfree(irq_object); - return NULL; - } - } -#endif - - /* workqueue API changed in 2.6.20, support both versions: */ -#if defined(INIT_DELAYED_WORK) - /* New syntax: INIT_WORK( struct work_struct *work, void (*function)(struct work_struct *)) */ - INIT_WORK( &irq_object->work_queue_irq_handle, irq_handler_bottom_half); -#else - /* Old syntax: INIT_WORK( struct work_struct *work, void (*function)(void *), void *data) */ - INIT_WORK( &irq_object->work_queue_irq_handle, irq_handler_bottom_half, irq_object); -#endif /* defined(INIT_DELAYED_WORK) */ - - if (-1 == irqnum) - { - /* Probe for IRQ */ - if ( (NULL != trigger_func) && (NULL != ack_func) ) - { - unsigned long probe_count = 3; - _mali_osk_errcode_t err; - int irq; - - MALI_DEBUG_PRINT(2, ("Probing for irq\n")); - - do - { - unsigned long mask; - - mask = probe_irq_on(); - trigger_func(data); - - _mali_osk_time_ubusydelay(5); - - irq = probe_irq_off(mask); - err = ack_func(data); - } - while (irq < 0 && (err == _MALI_OSK_ERR_OK) && probe_count--); - - if (irq < 0 || (_MALI_OSK_ERR_OK != err)) irqnum = -1; - else irqnum = irq; - } - else irqnum = -1; /* no probe functions, fault */ - - if (-1 != irqnum) - { - /* found an irq */ - MALI_DEBUG_PRINT(2, ("Found irq %d\n", irqnum)); - } - else - { - MALI_DEBUG_PRINT(2, ("Probe for irq failed\n")); - } - } - - irq_object->irqnum = irqnum; - irq_object->uhandler = uhandler; - irq_object->bhandler = bhandler; - irq_object->data = data; - - /* Is this a real IRQ handler we need? */ - if (irqnum != _MALI_OSK_IRQ_NUMBER_FAKE && irqnum != _MALI_OSK_IRQ_NUMBER_PMM) - { - if (-1 == irqnum) - { - MALI_DEBUG_PRINT(2, ("No IRQ for core '%s' found during probe\n", description)); - kfree(irq_object); - return NULL; - } - - if (0 != request_irq(irqnum, irq_handler_upper_half, IRQF_SHARED, description, irq_object)) - { - MALI_DEBUG_PRINT(2, ("Unable to install IRQ handler for core '%s'\n", description)); - kfree(irq_object); - return NULL; - } - } - -#if MALI_LICENSE_IS_GPL - if ( _MALI_OSK_IRQ_NUMBER_PMM == irqnum ) - { - pmm_wq = create_singlethread_workqueue("mali-pmm-wq"); - } -#endif - - return irq_object; -} - -void _mali_osk_irq_schedulework( _mali_osk_irq_t *irq ) -{ - mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq; -#if MALI_LICENSE_IS_GPL - if ( irq_object->irqnum == _MALI_OSK_IRQ_NUMBER_PMM ) - { - queue_work( pmm_wq,&irq_object->work_queue_irq_handle ); - } - else - { - queue_work(mali_wq, &irq_object->work_queue_irq_handle); - } -#else - schedule_work(&irq_object->work_queue_irq_handle); -#endif -} - -void _mali_osk_flush_workqueue( _mali_osk_irq_t *irq ) -{ -#if MALI_LICENSE_IS_GPL - if (NULL != irq) - { - mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq; - if(irq_object->irqnum == _MALI_OSK_IRQ_NUMBER_PMM ) - { - flush_workqueue(pmm_wq); - } - else - { - flush_workqueue(mali_wq); - } - } - else - { - flush_workqueue(mali_wq); - } -#endif -} - -void _mali_osk_irq_term( _mali_osk_irq_t *irq ) -{ - mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq; - -#if MALI_LICENSE_IS_GPL - if(irq_object->irqnum == _MALI_OSK_IRQ_NUMBER_PMM ) - { - flush_workqueue(pmm_wq); - destroy_workqueue(pmm_wq); - } -#endif - free_irq(irq_object->irqnum, irq_object); - kfree(irq_object); - flush_scheduled_work(); -} - - -/** This function is called directly in interrupt context from the OS just after - * the CPU get the hw-irq from mali, or other devices on the same IRQ-channel. - * It is registered one of these function for each mali core. When an interrupt - * arrives this function will be called equal times as registered mali cores. - * That means that we only check one mali core in one function call, and the - * core we check for each turn is given by the \a dev_id variable. - * If we detect an pending interrupt on the given core, we mask the interrupt - * out by settging the core's IRQ_MASK register to zero. - * Then we schedule the mali_core_irq_handler_bottom_half to run as high priority - * work queue job. - */ -static irqreturn_t irq_handler_upper_half (int port_name, void* dev_id ) /* , struct pt_regs *regs*/ -{ - mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)dev_id; - - if (irq_object->uhandler(irq_object->data) == _MALI_OSK_ERR_OK) - { - return IRQ_HANDLED; - } - return IRQ_NONE; -} - -/* Is executed when an interrupt occur on one core */ -/* workqueue API changed in 2.6.20, support both versions: */ -#if defined(INIT_DELAYED_WORK) -static void irq_handler_bottom_half ( struct work_struct *work ) -#else -static void irq_handler_bottom_half ( void * input ) -#endif -{ - mali_osk_irq_object_t *irq_object; - -#if defined(INIT_DELAYED_WORK) - irq_object = _MALI_OSK_CONTAINER_OF(work, mali_osk_irq_object_t, work_queue_irq_handle); -#else - if ( NULL == input ) - { - MALI_PRINT_ERROR(("IRQ: Null pointer! Illegal!")); - return; /* Error */ - } - irq_object = (mali_osk_irq_object_t *) input; -#endif - - irq_object->bhandler(irq_object->data); -} - diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_locks.c b/drivers/media/video/samsung/mali/linux/mali_osk_locks.c deleted file mode 100644 index ee857d5..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_osk_locks.c +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_osk_locks.c - * Implemenation of the OS abstraction layer for the kernel device driver - */ - -/* needed to detect kernel version specific code */ -#include - -#include -#include - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) -#include -#else /* pre 2.6.26 the file was in the arch specific location */ -#include -#endif - -#include -#include "mali_osk.h" -#include "mali_kernel_common.h" - -/* These are all the locks we implement: */ -typedef enum -{ - _MALI_OSK_INTERNAL_LOCKTYPE_SPIN, /* Mutex, implicitly non-interruptable, use spin_lock/spin_unlock */ - _MALI_OSK_INTERNAL_LOCKTYPE_SPIN_IRQ, /* Mutex, IRQ version of spinlock, use spin_lock_irqsave/spin_unlock_irqrestore */ - _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX, /* Interruptable, use up()/down_interruptable() */ - _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT, /* Non-Interruptable, use up()/down() */ - _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW, /* Non-interruptable, Reader/Writer, use {up,down}{read,write}() */ - - /* Linux supports, but we do not support: - * Non-Interruptable Reader/Writer spinlock mutexes - RW optimization will be switched off - */ - - /* Linux does not support: - * One-locks, of any sort - no optimization for this fact will be made. - */ - -} _mali_osk_internal_locktype; - -struct _mali_osk_lock_t_struct -{ - _mali_osk_internal_locktype type; - unsigned long flags; - union - { - spinlock_t spinlock; - struct semaphore sema; - struct rw_semaphore rw_sema; - } obj; - MALI_DEBUG_CODE( - /** original flags for debug checking */ - _mali_osk_lock_flags_t orig_flags; - - /* id of the thread currently holding this lock, 0 if no - * threads hold it. */ - u32 owner; - /* number of owners this lock currently has (can be > 1 if - * taken in R/O mode. */ - u32 nOwners; - /* what mode the lock was taken in */ - _mali_osk_lock_mode_t mode; - ); /* MALI_DEBUG_CODE */ -}; - -_mali_osk_lock_t *_mali_osk_lock_init( _mali_osk_lock_flags_t flags, u32 initial, u32 order ) -{ - _mali_osk_lock_t *lock = NULL; - - /* Validate parameters: */ - /* Flags acceptable */ - MALI_DEBUG_ASSERT( 0 == ( flags & ~(_MALI_OSK_LOCKFLAG_SPINLOCK - | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ - | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE - | _MALI_OSK_LOCKFLAG_READERWRITER - | _MALI_OSK_LOCKFLAG_ORDERED - | _MALI_OSK_LOCKFLAG_ONELOCK )) ); - /* Spinlocks are always non-interruptable */ - MALI_DEBUG_ASSERT( (((flags & _MALI_OSK_LOCKFLAG_SPINLOCK) || (flags & _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ)) && (flags & _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE)) - || !(flags & _MALI_OSK_LOCKFLAG_SPINLOCK)); - /* Parameter initial SBZ - for future expansion */ - MALI_DEBUG_ASSERT( 0 == initial ); - - lock = kmalloc(sizeof(_mali_osk_lock_t), GFP_KERNEL); - - if ( NULL == lock ) - { - return lock; - } - - /* Determine type of mutex: */ - /* defaults to interruptable mutex if no flags are specified */ - - if ( (flags & _MALI_OSK_LOCKFLAG_SPINLOCK) ) - { - /* Non-interruptable Spinlocks override all others */ - lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_SPIN; - spin_lock_init( &lock->obj.spinlock ); - } - else if ( (flags & _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ ) ) - { - lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_SPIN_IRQ; - lock->flags = 0; - spin_lock_init( &lock->obj.spinlock ); - } - else if ( (flags & _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE) - && (flags & _MALI_OSK_LOCKFLAG_READERWRITER) ) - { - lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW; - init_rwsem( &lock->obj.rw_sema ); - } - else - { - /* Usual mutex types */ - if ( (flags & _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE) ) - { - lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT; - } - else - { - lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX; - } - - /* Initially unlocked */ - sema_init( &lock->obj.sema, 1 ); - } - -#ifdef DEBUG - /* Debug tracking of flags */ - lock->orig_flags = flags; - - /* Debug tracking of lock owner */ - lock->owner = 0; - lock->nOwners = 0; -#endif /* DEBUG */ - - return lock; -} - -#ifdef DEBUG -u32 _mali_osk_lock_get_owner( _mali_osk_lock_t *lock ) -{ - return lock->owner; -} - -u32 _mali_osk_lock_get_number_owners( _mali_osk_lock_t *lock ) -{ - return lock->nOwners; -} - -u32 _mali_osk_lock_get_mode( _mali_osk_lock_t *lock ) -{ - return lock->mode; -} -#endif /* DEBUG */ - -_mali_osk_errcode_t _mali_osk_lock_wait( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode) -{ - _mali_osk_errcode_t err = _MALI_OSK_ERR_OK; - - /* Parameter validation */ - MALI_DEBUG_ASSERT_POINTER( lock ); - - MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_RW == mode - || _MALI_OSK_LOCKMODE_RO == mode ); - - /* Only allow RO locks when the initial object was a Reader/Writer lock - * Since information is lost on the internal locktype, we use the original - * information, which is only stored when built for DEBUG */ - MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_RW == mode - || (_MALI_OSK_LOCKMODE_RO == mode && (_MALI_OSK_LOCKFLAG_READERWRITER & lock->orig_flags)) ); - - switch ( lock->type ) - { - case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN: - spin_lock(&lock->obj.spinlock); - break; - case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN_IRQ: - { - unsigned long tmp_flags; - spin_lock_irqsave(&lock->obj.spinlock, tmp_flags); - lock->flags = tmp_flags; - } - break; - - case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX: - if ( down_interruptible(&lock->obj.sema) ) - { - MALI_PRINT_ERROR(("Can not lock mutex\n")); - err = _MALI_OSK_ERR_RESTARTSYSCALL; - } - break; - - case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT: - down(&lock->obj.sema); - break; - - case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW: - if (mode == _MALI_OSK_LOCKMODE_RO) - { - down_read(&lock->obj.rw_sema); - } - else - { - down_write(&lock->obj.rw_sema); - } - break; - - default: - /* Reaching here indicates a programming error, so you will not get here - * on non-DEBUG builds */ - MALI_DEBUG_PRINT_ERROR( ("Invalid internal lock type: %.8X", lock->type ) ); - break; - } - -#ifdef DEBUG - /* This thread is now the owner of this lock */ - if (_MALI_OSK_ERR_OK == err) - { - if (mode == _MALI_OSK_LOCKMODE_RW) - { - /*MALI_DEBUG_ASSERT(0 == lock->owner);*/ - if (0 != lock->owner) - { - printk(KERN_ERR "%d: ERROR: Lock %p already has owner %d\n", _mali_osk_get_tid(), lock, lock->owner); - dump_stack(); - } - lock->owner = _mali_osk_get_tid(); - lock->mode = mode; - ++lock->nOwners; - } - else /* mode == _MALI_OSK_LOCKMODE_RO */ - { - lock->owner |= _mali_osk_get_tid(); - lock->mode = mode; - ++lock->nOwners; - } - } -#endif - - return err; -} - -void _mali_osk_lock_signal( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode ) -{ - /* Parameter validation */ - MALI_DEBUG_ASSERT_POINTER( lock ); - - MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_RW == mode - || _MALI_OSK_LOCKMODE_RO == mode ); - - /* Only allow RO locks when the initial object was a Reader/Writer lock - * Since information is lost on the internal locktype, we use the original - * information, which is only stored when built for DEBUG */ - MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_RW == mode - || (_MALI_OSK_LOCKMODE_RO == mode && (_MALI_OSK_LOCKFLAG_READERWRITER & lock->orig_flags)) ); - -#ifdef DEBUG - /* make sure the thread releasing the lock actually was the owner */ - if (mode == _MALI_OSK_LOCKMODE_RW) - { - /*MALI_DEBUG_ASSERT(_mali_osk_get_tid() == lock->owner);*/ - if (_mali_osk_get_tid() != lock->owner) - { - printk(KERN_ERR "%d: ERROR: Lock %p owner was %d\n", _mali_osk_get_tid(), lock, lock->owner); - dump_stack(); - } - /* This lock now has no owner */ - lock->owner = 0; - --lock->nOwners; - } - else /* mode == _MALI_OSK_LOCKMODE_RO */ - { - if ((_mali_osk_get_tid() & lock->owner) != _mali_osk_get_tid()) - { - printk(KERN_ERR "%d: ERROR: Not an owner of %p lock.\n", _mali_osk_get_tid(), lock); - dump_stack(); - } - - /* if this is the last thread holding this lock in R/O mode, set owner - * back to 0 */ - if (0 == --lock->nOwners) - { - lock->owner = 0; - } - } -#endif /* DEBUG */ - - switch ( lock->type ) - { - case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN: - spin_unlock(&lock->obj.spinlock); - break; - case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN_IRQ: - spin_unlock_irqrestore(&lock->obj.spinlock, lock->flags); - break; - - case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX: - /* FALLTHROUGH */ - case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT: - up(&lock->obj.sema); - break; - - case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW: - if (mode == _MALI_OSK_LOCKMODE_RO) - { - up_read(&lock->obj.rw_sema); - } - else - { - up_write(&lock->obj.rw_sema); - } - break; - - default: - /* Reaching here indicates a programming error, so you will not get here - * on non-DEBUG builds */ - MALI_DEBUG_PRINT_ERROR( ("Invalid internal lock type: %.8X", lock->type ) ); - break; - } -} - -void _mali_osk_lock_term( _mali_osk_lock_t *lock ) -{ - /* Parameter validation */ - MALI_DEBUG_ASSERT_POINTER( lock ); - - /* Linux requires no explicit termination of spinlocks, semaphores, or rw_semaphores */ - kfree(lock); -} diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_low_level_mem.c b/drivers/media/video/samsung/mali/linux/mali_osk_low_level_mem.c deleted file mode 100644 index 02558a0..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_osk_low_level_mem.c +++ /dev/null @@ -1,660 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_osk_low_level_mem.c - * Implementation of the OS abstraction layer for the kernel device driver - */ - -/* needed to detect kernel version specific code */ -#include - -#include -#include -#include -#include -#include -#include -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0) -#include -#endif - -#include "mali_osk.h" -#include "mali_ukk.h" /* required to hook in _mali_ukk_mem_mmap handling */ -#include "mali_kernel_common.h" -#include "mali_kernel_linux.h" - -static void mali_kernel_memory_vma_open(struct vm_area_struct * vma); -static void mali_kernel_memory_vma_close(struct vm_area_struct * vma); - - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) -static int mali_kernel_memory_cpu_page_fault_handler(struct vm_area_struct *vma, struct vm_fault *vmf); -#else -static unsigned long mali_kernel_memory_cpu_page_fault_handler(struct vm_area_struct * vma, unsigned long address); -#endif - - -typedef struct mali_vma_usage_tracker -{ - int references; - u32 cookie; -} mali_vma_usage_tracker; - - -/* Linked list structure to hold details of all OS allocations in a particular - * mapping - */ -struct AllocationList -{ - struct AllocationList *next; - u32 offset; - u32 physaddr; -}; - -typedef struct AllocationList AllocationList; - -/* Private structure to store details of a mapping region returned - * from _mali_osk_mem_mapregion_init - */ -struct MappingInfo -{ - struct vm_area_struct *vma; - struct AllocationList *list; - struct AllocationList *tail; -}; - -typedef struct MappingInfo MappingInfo; - - -static u32 _kernel_page_allocate(void); -static void _kernel_page_release(u32 physical_address); -static AllocationList * _allocation_list_item_get(void); -static void _allocation_list_item_release(AllocationList * item); - - -/* Variable declarations */ -static DEFINE_SPINLOCK(allocation_list_spinlock); -static AllocationList * pre_allocated_memory = (AllocationList*) NULL ; -static int pre_allocated_memory_size_current = 0; -#ifdef MALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB - static int pre_allocated_memory_size_max = MALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB * 1024 * 1024; -#else - static int pre_allocated_memory_size_max = 16 * 1024 * 1024; /* 6 MiB */ -#endif - -static struct vm_operations_struct mali_kernel_vm_ops = -{ - .open = mali_kernel_memory_vma_open, - .close = mali_kernel_memory_vma_close, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) - .fault = mali_kernel_memory_cpu_page_fault_handler -#else - .nopfn = mali_kernel_memory_cpu_page_fault_handler -#endif -}; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) - #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) -static int mali_mem_shrink(int nr_to_scan, gfp_t gfp_mask) - #else -static int mali_mem_shrink(struct shrinker *shrinker, int nr_to_scan, gfp_t gfp_mask) - #endif -#else -static int mali_mem_shrink(struct shrinker *shrinker, struct shrink_control *sc) -#endif -{ - unsigned long flags; - AllocationList *item; -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) - int nr = nr_to_scan; -#else - int nr = sc->nr_to_scan; -#endif - - if (0 == nr) - { - return pre_allocated_memory_size_current / PAGE_SIZE; - } - - if (0 == pre_allocated_memory_size_current) - { - /* No pages availble */ - return 0; - } - - if (0 == spin_trylock_irqsave(&allocation_list_spinlock, flags)) - { - /* Not able to lock. */ - return -1; - } - - while (pre_allocated_memory && nr > 0) - { - item = pre_allocated_memory; - pre_allocated_memory = item->next; - - _kernel_page_release(item->physaddr); - _mali_osk_free(item); - - pre_allocated_memory_size_current -= PAGE_SIZE; - --nr; - } - spin_unlock_irqrestore(&allocation_list_spinlock,flags); - - return pre_allocated_memory_size_current / PAGE_SIZE; -} - -struct shrinker mali_mem_shrinker = { - .shrink = mali_mem_shrink, - .seeks = DEFAULT_SEEKS, -}; - -void mali_osk_low_level_mem_init(void) -{ - pre_allocated_memory = (AllocationList*) NULL ; - - register_shrinker(&mali_mem_shrinker); -} - -void mali_osk_low_level_mem_term(void) -{ - unregister_shrinker(&mali_mem_shrinker); - - while ( NULL != pre_allocated_memory ) - { - AllocationList *item; - item = pre_allocated_memory; - pre_allocated_memory = item->next; - _kernel_page_release(item->physaddr); - _mali_osk_free( item ); - } - pre_allocated_memory_size_current = 0; -} - -static u32 _kernel_page_allocate(void) -{ - struct page *new_page; - u32 linux_phys_addr; - - new_page = alloc_page(GFP_HIGHUSER | __GFP_ZERO | __GFP_REPEAT | __GFP_NOWARN | __GFP_COLD); - - if ( NULL == new_page ) - { - return 0; - } - - /* Ensure page is flushed from CPU caches. */ - linux_phys_addr = dma_map_page(NULL, new_page, 0, PAGE_SIZE, DMA_BIDIRECTIONAL); - - return linux_phys_addr; -} - -static void _kernel_page_release(u32 physical_address) -{ - struct page *unmap_page; - - #if 1 - dma_unmap_page(NULL, physical_address, PAGE_SIZE, DMA_BIDIRECTIONAL); - #endif - - unmap_page = pfn_to_page( physical_address >> PAGE_SHIFT ); - MALI_DEBUG_ASSERT_POINTER( unmap_page ); - __free_page( unmap_page ); -} - -static AllocationList * _allocation_list_item_get(void) -{ - AllocationList *item = NULL; - unsigned long flags; - - spin_lock_irqsave(&allocation_list_spinlock,flags); - if ( pre_allocated_memory ) - { - item = pre_allocated_memory; - pre_allocated_memory = pre_allocated_memory->next; - pre_allocated_memory_size_current -= PAGE_SIZE; - - spin_unlock_irqrestore(&allocation_list_spinlock,flags); - return item; - } - spin_unlock_irqrestore(&allocation_list_spinlock,flags); - - item = _mali_osk_malloc( sizeof(AllocationList) ); - if ( NULL == item) - { - return NULL; - } - - item->physaddr = _kernel_page_allocate(); - if ( 0 == item->physaddr ) - { - /* Non-fatal error condition, out of memory. Upper levels will handle this. */ - _mali_osk_free( item ); - return NULL; - } - return item; -} - -static void _allocation_list_item_release(AllocationList * item) -{ - unsigned long flags; - spin_lock_irqsave(&allocation_list_spinlock,flags); - if ( pre_allocated_memory_size_current < pre_allocated_memory_size_max) - { - item->next = pre_allocated_memory; - pre_allocated_memory = item; - pre_allocated_memory_size_current += PAGE_SIZE; - spin_unlock_irqrestore(&allocation_list_spinlock,flags); - return; - } - spin_unlock_irqrestore(&allocation_list_spinlock,flags); - - _kernel_page_release(item->physaddr); - _mali_osk_free( item ); -} - - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) -static int mali_kernel_memory_cpu_page_fault_handler(struct vm_area_struct *vma, struct vm_fault *vmf) -#else -static unsigned long mali_kernel_memory_cpu_page_fault_handler(struct vm_area_struct * vma, unsigned long address) -#endif -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) - void __user * address; - address = vmf->virtual_address; -#endif - /* - * We always fail the call since all memory is pre-faulted when assigned to the process. - * Only the Mali cores can use page faults to extend buffers. - */ - - MALI_DEBUG_PRINT(1, ("Page-fault in Mali memory region caused by the CPU.\n")); - MALI_DEBUG_PRINT(1, ("Tried to access %p (process local virtual address) which is not currently mapped to any Mali memory.\n", (void*)address)); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) - return VM_FAULT_SIGBUS; -#else - return NOPFN_SIGBUS; -#endif -} - -static void mali_kernel_memory_vma_open(struct vm_area_struct * vma) -{ - mali_vma_usage_tracker * vma_usage_tracker; - MALI_DEBUG_PRINT(4, ("Open called on vma %p\n", vma)); - - vma_usage_tracker = (mali_vma_usage_tracker*)vma->vm_private_data; - vma_usage_tracker->references++; - - return; -} - -static void mali_kernel_memory_vma_close(struct vm_area_struct * vma) -{ - _mali_uk_mem_munmap_s args = {0, }; - mali_memory_allocation * descriptor; - mali_vma_usage_tracker * vma_usage_tracker; - MALI_DEBUG_PRINT(3, ("Close called on vma %p\n", vma)); - - vma_usage_tracker = (mali_vma_usage_tracker*)vma->vm_private_data; - - BUG_ON(!vma_usage_tracker); - BUG_ON(0 == vma_usage_tracker->references); - - vma_usage_tracker->references--; - - if (0 != vma_usage_tracker->references) - { - MALI_DEBUG_PRINT(3, ("Ignoring this close, %d references still exists\n", vma_usage_tracker->references)); - return; - } - - /** @note args->context unused, initialized to 0. - * Instead, we use the memory_session from the cookie */ - - descriptor = (mali_memory_allocation *)vma_usage_tracker->cookie; - - args.cookie = (u32)descriptor; - args.mapping = descriptor->mapping; - args.size = descriptor->size; - - _mali_ukk_mem_munmap( &args ); - - /* vma_usage_tracker is free()d by _mali_osk_mem_mapregion_term(). - * In the case of the memory engine, it is called as the release function that has been registered with the engine*/ -} - - -void _mali_osk_mem_barrier( void ) -{ - mb(); -} - -void _mali_osk_write_mem_barrier( void ) -{ - wmb(); -} - -mali_io_address _mali_osk_mem_mapioregion( u32 phys, u32 size, const char *description ) -{ - return (mali_io_address)ioremap_nocache(phys, size); -} - -void _mali_osk_mem_unmapioregion( u32 phys, u32 size, mali_io_address virt ) -{ - iounmap((void*)virt); -} - -mali_io_address _mali_osk_mem_allocioregion( u32 *phys, u32 size ) -{ - void * virt; - MALI_DEBUG_ASSERT_POINTER( phys ); - MALI_DEBUG_ASSERT( 0 == (size & ~_MALI_OSK_CPU_PAGE_MASK) ); - MALI_DEBUG_ASSERT( 0 != size ); - - /* dma_alloc_* uses a limited region of address space. On most arch/marchs - * 2 to 14 MiB is available. This should be enough for the page tables, which - * currently is the only user of this function. */ - virt = dma_alloc_coherent(NULL, size, phys, GFP_KERNEL | GFP_DMA ); - - MALI_DEBUG_PRINT(3, ("Page table virt: 0x%x = dma_alloc_coherent(size:%d, phys:0x%x, )\n", virt, size, phys)); - - if ( NULL == virt ) - { - MALI_DEBUG_PRINT(5, ("allocioregion: Failed to allocate Pagetable memory, size=0x%.8X\n", size )); - return 0; - } - - MALI_DEBUG_ASSERT( 0 == (*phys & ~_MALI_OSK_CPU_PAGE_MASK) ); - - return (mali_io_address)virt; -} - -void _mali_osk_mem_freeioregion( u32 phys, u32 size, mali_io_address virt ) -{ - MALI_DEBUG_ASSERT_POINTER( (void*)virt ); - MALI_DEBUG_ASSERT( 0 != size ); - MALI_DEBUG_ASSERT( 0 == (phys & ( (1 << PAGE_SHIFT) - 1 )) ); - - dma_free_coherent(NULL, size, virt, phys); -} - -_mali_osk_errcode_t inline _mali_osk_mem_reqregion( u32 phys, u32 size, const char *description ) -{ - return ((NULL == request_mem_region(phys, size, description)) ? _MALI_OSK_ERR_NOMEM : _MALI_OSK_ERR_OK); -} - -void inline _mali_osk_mem_unreqregion( u32 phys, u32 size ) -{ - release_mem_region(phys, size); -} - -void inline _mali_osk_mem_iowrite32_relaxed( volatile mali_io_address addr, u32 offset, u32 val ) -{ - __raw_writel(cpu_to_le32(val),((u8*)addr) + offset); -} - -u32 inline _mali_osk_mem_ioread32( volatile mali_io_address addr, u32 offset ) -{ - return ioread32(((u8*)addr) + offset); -} - -void inline _mali_osk_mem_iowrite32( volatile mali_io_address addr, u32 offset, u32 val ) -{ - iowrite32(val, ((u8*)addr) + offset); -} - -void _mali_osk_cache_flushall( void ) -{ - /** @note Cached memory is not currently supported in this implementation */ -} - -void _mali_osk_cache_ensure_uncached_range_flushed( void *uncached_mapping, u32 offset, u32 size ) -{ - _mali_osk_write_mem_barrier(); -} - -_mali_osk_errcode_t _mali_osk_mem_mapregion_init( mali_memory_allocation * descriptor ) -{ - struct vm_area_struct *vma; - mali_vma_usage_tracker * vma_usage_tracker; - MappingInfo *mappingInfo; - - if (NULL == descriptor) return _MALI_OSK_ERR_FAULT; - - MALI_DEBUG_ASSERT( 0 != (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE) ); - - vma = (struct vm_area_struct*)descriptor->process_addr_mapping_info; - - if (NULL == vma ) return _MALI_OSK_ERR_FAULT; - - /* Re-write the process_addr_mapping_info */ - mappingInfo = _mali_osk_calloc( 1, sizeof(MappingInfo) ); - - if ( NULL == mappingInfo ) return _MALI_OSK_ERR_FAULT; - - vma_usage_tracker = _mali_osk_calloc( 1, sizeof(mali_vma_usage_tracker) ); - - if (NULL == vma_usage_tracker) - { - MALI_DEBUG_PRINT(2, ("Failed to allocate memory to track memory usage\n")); - _mali_osk_free( mappingInfo ); - return _MALI_OSK_ERR_FAULT; - } - - mappingInfo->vma = vma; - descriptor->process_addr_mapping_info = mappingInfo; - - /* Do the va range allocation - in this case, it was done earlier, so we copy in that information */ - descriptor->mapping = (void __user*)vma->vm_start; - /* list member is already NULL */ - - /* - set some bits which indicate that: - The memory is IO memory, meaning that no paging is to be performed and the memory should not be included in crash dumps - The memory is reserved, meaning that it's present and can never be paged out (see also previous entry) - */ - vma->vm_flags |= VM_IO; - vma->vm_flags |= VM_RESERVED; - vma->vm_flags |= VM_DONTCOPY; - - vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); - vma->vm_ops = &mali_kernel_vm_ops; /* Operations used on any memory system */ - - vma_usage_tracker->references = 1; /* set initial reference count to be 1 as vma_open won't be called for the first mmap call */ - vma_usage_tracker->cookie = (u32)descriptor; /* cookie for munmap */ - - vma->vm_private_data = vma_usage_tracker; - - return _MALI_OSK_ERR_OK; -} - -void _mali_osk_mem_mapregion_term( mali_memory_allocation * descriptor ) -{ - struct vm_area_struct* vma; - mali_vma_usage_tracker * vma_usage_tracker; - MappingInfo *mappingInfo; - - if (NULL == descriptor) return; - - MALI_DEBUG_ASSERT( 0 != (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE) ); - - mappingInfo = (MappingInfo *)descriptor->process_addr_mapping_info; - - MALI_DEBUG_ASSERT_POINTER( mappingInfo ); - - /* Linux does the right thing as part of munmap to remove the mapping - * All that remains is that we remove the vma_usage_tracker setup in init() */ - vma = mappingInfo->vma; - - MALI_DEBUG_ASSERT_POINTER( vma ); - - /* ASSERT that there are no allocations on the list. Unmap should've been - * called on all OS allocations. */ - MALI_DEBUG_ASSERT( NULL == mappingInfo->list ); - - vma_usage_tracker = vma->vm_private_data; - - /* We only get called if mem_mapregion_init succeeded */ - _mali_osk_free(vma_usage_tracker); - - _mali_osk_free( mappingInfo ); - return; -} - -_mali_osk_errcode_t _mali_osk_mem_mapregion_map( mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size ) -{ - struct vm_area_struct *vma; - MappingInfo *mappingInfo; - - if (NULL == descriptor) return _MALI_OSK_ERR_FAULT; - - MALI_DEBUG_ASSERT_POINTER( phys_addr ); - - MALI_DEBUG_ASSERT( 0 != (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE) ); - - MALI_DEBUG_ASSERT( 0 == (size & ~_MALI_OSK_CPU_PAGE_MASK) ); - - MALI_DEBUG_ASSERT( 0 == (offset & ~_MALI_OSK_CPU_PAGE_MASK)); - - if (NULL == descriptor->mapping) return _MALI_OSK_ERR_INVALID_ARGS; - - if (size > (descriptor->size - offset)) - { - MALI_DEBUG_PRINT(1,("_mali_osk_mem_mapregion_map: virtual memory area not large enough to map physical 0x%x size %x into area 0x%x at offset 0x%xr\n", - *phys_addr, size, descriptor->mapping, offset)); - return _MALI_OSK_ERR_FAULT; - } - - mappingInfo = (MappingInfo *)descriptor->process_addr_mapping_info; - - MALI_DEBUG_ASSERT_POINTER( mappingInfo ); - - vma = mappingInfo->vma; - - if (NULL == vma ) return _MALI_OSK_ERR_FAULT; - - MALI_DEBUG_PRINT(7, ("Process map: mapping 0x%08X to process address 0x%08lX length 0x%08X\n", *phys_addr, (long unsigned int)(descriptor->mapping + offset), size)); - - if ( MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC == *phys_addr ) - { - _mali_osk_errcode_t ret; - AllocationList *alloc_item; - u32 linux_phys_frame_num; - - alloc_item = _allocation_list_item_get(); - if (NULL == alloc_item) - { - MALI_DEBUG_PRINT(1, ("Failed to allocate list item\n")); - return _MALI_OSK_ERR_NOMEM; - } - - linux_phys_frame_num = alloc_item->physaddr >> PAGE_SHIFT; - - ret = ( remap_pfn_range( vma, ((u32)descriptor->mapping) + offset, linux_phys_frame_num, size, vma->vm_page_prot) ) ? _MALI_OSK_ERR_FAULT : _MALI_OSK_ERR_OK; - - if ( ret != _MALI_OSK_ERR_OK) - { - MALI_PRINT_ERROR(("%s %d could not remap_pfn_range()\n", __FUNCTION__, __LINE__)); - _allocation_list_item_release(alloc_item); - return ret; - } - - /* Put our alloc_item into the list of allocations on success */ - if (NULL == mappingInfo->list) - { - mappingInfo->list = alloc_item; - } - else - { - mappingInfo->tail->next = alloc_item; - } - - mappingInfo->tail = alloc_item; - alloc_item->next = NULL; - alloc_item->offset = offset; - - /* Write out new physical address on success */ - *phys_addr = alloc_item->physaddr; - - return ret; - } - - /* Otherwise, Use the supplied physical address */ - - /* ASSERT that supplied phys_addr is page aligned */ - MALI_DEBUG_ASSERT( 0 == ((*phys_addr) & ~_MALI_OSK_CPU_PAGE_MASK) ); - - return ( remap_pfn_range( vma, ((u32)descriptor->mapping) + offset, *phys_addr >> PAGE_SHIFT, size, vma->vm_page_prot) ) ? _MALI_OSK_ERR_FAULT : _MALI_OSK_ERR_OK; - -} - -void _mali_osk_mem_mapregion_unmap( mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t flags ) -{ - MappingInfo *mappingInfo; - - if (NULL == descriptor) return; - - MALI_DEBUG_ASSERT( 0 != (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE) ); - - MALI_DEBUG_ASSERT( 0 == (size & ~_MALI_OSK_CPU_PAGE_MASK) ); - - MALI_DEBUG_ASSERT( 0 == (offset & ~_MALI_OSK_CPU_PAGE_MASK) ); - - if (NULL == descriptor->mapping) return; - - if (size > (descriptor->size - offset)) - { - MALI_DEBUG_PRINT(1,("_mali_osk_mem_mapregion_unmap: virtual memory area not large enough to unmap size %x from area 0x%x at offset 0x%x\n", - size, descriptor->mapping, offset)); - return; - } - mappingInfo = (MappingInfo *)descriptor->process_addr_mapping_info; - - MALI_DEBUG_ASSERT_POINTER( mappingInfo ); - - if ( 0 != (flags & _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR) ) - { - /* This physical RAM was allocated in _mali_osk_mem_mapregion_map and - * so needs to be unmapped - */ - while (size) - { - /* First find the allocation in the list of allocations */ - AllocationList *alloc = mappingInfo->list; - AllocationList **prev = &(mappingInfo->list); - - while (NULL != alloc && alloc->offset != offset) - { - prev = &(alloc->next); - alloc = alloc->next; - } - if (alloc == NULL) { - MALI_DEBUG_PRINT(1, ("Unmapping memory that isn't mapped\n")); - size -= _MALI_OSK_CPU_PAGE_SIZE; - offset += _MALI_OSK_CPU_PAGE_SIZE; - continue; - } - - *prev = alloc->next; - _allocation_list_item_release(alloc); - - /* Move onto the next allocation */ - size -= _MALI_OSK_CPU_PAGE_SIZE; - offset += _MALI_OSK_CPU_PAGE_SIZE; - } - } - - /* Linux does the right thing as part of munmap to remove the mapping */ - - return; -} diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_mali.c b/drivers/media/video/samsung/mali/linux/mali_osk_mali.c deleted file mode 100644 index 06cb215..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_osk_mali.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_osk_mali.c - * Implementation of the OS abstraction layer which is specific for the Mali kernel device driver - */ -#include -#include -#include - -#include "mali_kernel_common.h" /* MALI_xxx macros */ -#include "mali_osk.h" /* kernel side OS functions */ -#include "mali_uk_types.h" -#include "arch/config.h" /* contains the configuration of the arch we are compiling for */ - -_mali_osk_errcode_t _mali_osk_resources_init( _mali_osk_resource_t **arch_config, u32 *num_resources ) -{ - *num_resources = sizeof(arch_configuration) / sizeof(arch_configuration[0]); - *arch_config = arch_configuration; - return _MALI_OSK_ERR_OK; -} - -void _mali_osk_resources_term( _mali_osk_resource_t **arch_config, u32 num_resources ) -{ - /* Nothing to do */ -} diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_math.c b/drivers/media/video/samsung/mali/linux/mali_osk_math.c deleted file mode 100644 index bb25e7d..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_osk_math.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_osk_math.c - * Implementation of the OS abstraction layer for the kernel device driver - */ - -#include "mali_osk.h" -#include - -u32 inline _mali_osk_clz( u32 input ) -{ - return 32-fls(input); -} diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_memory.c b/drivers/media/video/samsung/mali/linux/mali_osk_memory.c deleted file mode 100644 index 5354e85..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_osk_memory.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_osk_memory.c - * Implementation of the OS abstraction layer for the kernel device driver - */ - -#include "mali_osk.h" -#include -#include - -void inline *_mali_osk_calloc( u32 n, u32 size ) -{ - return kcalloc(n, size, GFP_KERNEL); -} - -void inline *_mali_osk_malloc( u32 size ) -{ - return kmalloc(size, GFP_KERNEL); -} - -void inline _mali_osk_free( void *ptr ) -{ - kfree(ptr); -} - -void inline *_mali_osk_valloc( u32 size ) -{ - return vmalloc(size); -} - -void inline _mali_osk_vfree( void *ptr ) -{ - vfree(ptr); -} - -void inline *_mali_osk_memcpy( void *dst, const void *src, u32 len ) -{ - return memcpy(dst, src, len); -} - -void inline *_mali_osk_memset( void *s, u32 c, u32 n ) -{ - return memset(s, c, n); -} - -mali_bool _mali_osk_mem_check_allocated( u32 max_allocated ) -{ - /* No need to prevent an out-of-memory dialogue appearing on Linux, - * so we always return MALI_TRUE. - */ - return MALI_TRUE; -} diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_misc.c b/drivers/media/video/samsung/mali/linux/mali_osk_misc.c deleted file mode 100644 index ad486db..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_osk_misc.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_osk_misc.c - * Implementation of the OS abstraction layer for the kernel device driver - */ -#include -#include -#include -#include -#include -#include "mali_osk.h" - -void _mali_osk_dbgmsg( const char *fmt, ... ) -{ - va_list args; - va_start(args, fmt); - vprintk(fmt, args); - va_end(args); -} - -u32 _mali_osk_snprintf( char *buf, u32 size, const char *fmt, ... ) -{ - int res; - va_list args; - va_start(args, fmt); - - res = vscnprintf(buf, (size_t)size, fmt, args); - - va_end(args); - return res; -} - -void _mali_osk_abort(void) -{ - /* make a simple fault by dereferencing a NULL pointer */ - dump_stack(); - *(int *)0 = 0; -} - -void _mali_osk_break(void) -{ - _mali_osk_abort(); -} - -u32 _mali_osk_get_pid(void) -{ - /* Thread group ID is the process ID on Linux */ - return (u32)current->tgid; -} - -u32 _mali_osk_get_tid(void) -{ - /* pid is actually identifying the thread on Linux */ - return (u32)current->pid; -} diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_notification.c b/drivers/media/video/samsung/mali/linux/mali_osk_notification.c deleted file mode 100644 index c14c0d5..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_osk_notification.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_osk_notification.c - * Implementation of the OS abstraction layer for the kernel device driver - */ - -#include "mali_osk.h" -#include "mali_kernel_common.h" - -/* needed to detect kernel version specific code */ -#include - -#include -#include -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) -#include -#else /* pre 2.6.26 the file was in the arch specific location */ -#include -#endif - -/** - * Declaration of the notification queue object type - * Contains a linked list of notification pending delivery to user space. - * It also contains a wait queue of exclusive waiters blocked in the ioctl - * When a new notification is posted a single thread is resumed. - */ -struct _mali_osk_notification_queue_t_struct -{ - struct semaphore mutex; /**< Mutex protecting the list */ - wait_queue_head_t receive_queue; /**< Threads waiting for new entries to the queue */ - struct list_head head; /**< List of notifications waiting to be picked up */ -}; - -typedef struct _mali_osk_notification_wrapper_t_struct -{ - struct list_head list; /**< Internal linked list variable */ - _mali_osk_notification_t data; /**< Notification data */ -} _mali_osk_notification_wrapper_t; - -_mali_osk_notification_queue_t *_mali_osk_notification_queue_init( void ) -{ - _mali_osk_notification_queue_t * result; - - result = (_mali_osk_notification_queue_t *)kmalloc(sizeof(_mali_osk_notification_queue_t), GFP_KERNEL); - if (NULL == result) return NULL; - - sema_init(&result->mutex, 1); - init_waitqueue_head(&result->receive_queue); - INIT_LIST_HEAD(&result->head); - - return result; -} - -_mali_osk_notification_t *_mali_osk_notification_create( u32 type, u32 size ) -{ - /* OPT Recycling of notification objects */ - _mali_osk_notification_wrapper_t *notification; - - notification = (_mali_osk_notification_wrapper_t *)kmalloc( sizeof(_mali_osk_notification_wrapper_t) + size, - GFP_KERNEL | __GFP_HIGH | __GFP_REPEAT); - if (NULL == notification) - { - MALI_DEBUG_PRINT(1, ("Failed to create a notification object\n")); - return NULL; - } - - /* Init the list */ - INIT_LIST_HEAD(¬ification->list); - - if (0 != size) - { - notification->data.result_buffer = ((u8*)notification) + sizeof(_mali_osk_notification_wrapper_t); - } - else - { - notification->data.result_buffer = NULL; - } - - /* set up the non-allocating fields */ - notification->data.notification_type = type; - notification->data.result_buffer_size = size; - - /* all ok */ - return &(notification->data); -} - -void _mali_osk_notification_delete( _mali_osk_notification_t *object ) -{ - _mali_osk_notification_wrapper_t *notification; - MALI_DEBUG_ASSERT_POINTER( object ); - - notification = container_of( object, _mali_osk_notification_wrapper_t, data ); - - /* Free the container */ - kfree(notification); -} - -void _mali_osk_notification_queue_term( _mali_osk_notification_queue_t *queue ) -{ - MALI_DEBUG_ASSERT_POINTER( queue ); - - /* not much to do, just free the memory */ - kfree(queue); -} - -void _mali_osk_notification_queue_send( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t *object ) -{ - _mali_osk_notification_wrapper_t *notification; - MALI_DEBUG_ASSERT_POINTER( queue ); - MALI_DEBUG_ASSERT_POINTER( object ); - - notification = container_of( object, _mali_osk_notification_wrapper_t, data ); - - /* lock queue access */ - down(&queue->mutex); - /* add to list */ - list_add_tail(¬ification->list, &queue->head); - /* unlock the queue */ - up(&queue->mutex); - - /* and wake up one possible exclusive waiter */ - wake_up(&queue->receive_queue); -} - -static int _mali_notification_queue_is_empty( _mali_osk_notification_queue_t *queue ) -{ - int ret; - - down(&queue->mutex); - ret = list_empty(&queue->head); - up(&queue->mutex); - return ret; -} - -#if MALI_STATE_TRACKING -mali_bool _mali_osk_notification_queue_is_empty( _mali_osk_notification_queue_t *queue ) -{ - return _mali_notification_queue_is_empty(queue) ? MALI_TRUE : MALI_FALSE; -} -#endif - -_mali_osk_errcode_t _mali_osk_notification_queue_dequeue( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t **result ) -{ - _mali_osk_errcode_t ret = _MALI_OSK_ERR_ITEM_NOT_FOUND; - _mali_osk_notification_wrapper_t *wrapper_object; - - down(&queue->mutex); - - if (!list_empty(&queue->head)) - { - wrapper_object = list_entry(queue->head.next, _mali_osk_notification_wrapper_t, list); - *result = &(wrapper_object->data); - list_del_init(&wrapper_object->list); - ret = _MALI_OSK_ERR_OK; - } - - up(&queue->mutex); - - return ret; -} - -_mali_osk_errcode_t _mali_osk_notification_queue_receive( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t **result ) -{ - /* check input */ - MALI_DEBUG_ASSERT_POINTER( queue ); - MALI_DEBUG_ASSERT_POINTER( result ); - - /* default result */ - *result = NULL; - - while (_MALI_OSK_ERR_OK != _mali_osk_notification_queue_dequeue(queue, result)) - { - if (wait_event_interruptible(queue->receive_queue, !_mali_notification_queue_is_empty(queue))) - { - return _MALI_OSK_ERR_RESTARTSYSCALL; - } - } - - return _MALI_OSK_ERR_OK; /* all ok */ -} diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_pm.c b/drivers/media/video/samsung/mali/linux/mali_osk_pm.c deleted file mode 100644 index 491a603..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_osk_pm.c +++ /dev/null @@ -1,83 +0,0 @@ -/** - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_osk_pm.c - * Implementation of the callback functions from common power management - */ - -#include - -#ifdef CONFIG_PM_RUNTIME -#include -#endif /* CONFIG_PM_RUNTIME */ -#include -#include "mali_platform.h" -#include "mali_osk.h" -#include "mali_uk_types.h" -#include "mali_kernel_common.h" -#include "mali_kernel_license.h" -#include "mali_linux_pm.h" -#include "mali_kernel_license.h" - -#if ! MALI_LICENSE_IS_GPL -#undef CONFIG_PM_RUNTIME -#endif - -extern struct platform_device mali_gpu_device; - -#ifdef CONFIG_PM_RUNTIME -static mali_bool have_runtime_reference = MALI_FALSE; -#endif - -void _mali_osk_pm_dev_enable(void) -{ -#ifdef CONFIG_PM_RUNTIME - pm_runtime_enable(&(mali_gpu_device.dev)); -#endif -} - -/* NB: Function is not thread safe */ -_mali_osk_errcode_t _mali_osk_pm_dev_idle(void) -{ -#ifdef CONFIG_PM_RUNTIME - if (MALI_TRUE == have_runtime_reference) - { - int err; - err = pm_runtime_put_sync(&(mali_gpu_device.dev)); - if (0 > err) - { - MALI_PRINT_ERROR(("OSK PM: pm_runtime_put_sync() returned error code %d\n", err)); - return _MALI_OSK_ERR_FAULT; - } - have_runtime_reference = MALI_FALSE; - } -#endif - return _MALI_OSK_ERR_OK; -} - -/* NB: Function is not thread safe */ -_mali_osk_errcode_t _mali_osk_pm_dev_activate(void) -{ -#ifdef CONFIG_PM_RUNTIME - if (MALI_TRUE != have_runtime_reference) - { - int err; - err = pm_runtime_get_sync(&(mali_gpu_device.dev)); - if (0 > err) - { - MALI_PRINT_ERROR(("OSK PM: pm_runtime_get_sync() returned error code %d\n", err)); - return _MALI_OSK_ERR_FAULT; - } - have_runtime_reference = MALI_TRUE; - } -#endif - return _MALI_OSK_ERR_OK; -} diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_profiling_gator.c b/drivers/media/video/samsung/mali/linux/mali_osk_profiling_gator.c deleted file mode 100644 index 95bee53..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_osk_profiling_gator.c +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (C) 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "mali_ukk.h" -#include "mali_uk_types.h" -#include "mali_osk_profiling.h" -#include "mali_linux_trace.h" -#include "mali_gp.h" -#include "mali_pp.h" -#include "mali_l2_cache.h" -#include "mali_user_settings_db.h" - -_mali_osk_errcode_t _mali_osk_profiling_init(mali_bool auto_start) -{ - if (MALI_TRUE == auto_start) - { - mali_set_user_setting(_MALI_UK_USER_SETTING_SW_EVENTS_ENABLE, MALI_TRUE); - } - - return _MALI_OSK_ERR_OK; -} - -void _mali_osk_profiling_term(void) -{ - /* Nothing to do */ -} - -_mali_osk_errcode_t _mali_osk_profiling_start(u32 * limit) -{ - /* Nothing to do */ - return _MALI_OSK_ERR_OK; -} - -_mali_osk_errcode_t _mali_osk_profiling_stop(u32 *count) -{ - /* Nothing to do */ - return _MALI_OSK_ERR_OK; -} - -u32 _mali_osk_profiling_get_count(void) -{ - return 0; -} - -_mali_osk_errcode_t _mali_osk_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5]) -{ - /* Nothing to do */ - return _MALI_OSK_ERR_OK; -} - -_mali_osk_errcode_t _mali_osk_profiling_clear(void) -{ - /* Nothing to do */ - return _MALI_OSK_ERR_OK; -} - -mali_bool _mali_osk_profiling_is_recording(void) -{ - return MALI_FALSE; -} - -mali_bool _mali_osk_profiling_have_recording(void) -{ - return MALI_FALSE; -} - -void _mali_osk_profiling_report_sw_counters(u32 *counters) -{ - trace_mali_sw_counters(_mali_osk_get_pid(), _mali_osk_get_tid(), NULL, counters); -} - - -_mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args) -{ - return _mali_osk_profiling_start(&args->limit); -} - -_mali_osk_errcode_t _mali_ukk_profiling_add_event(_mali_uk_profiling_add_event_s *args) -{ - /* Always add process and thread identificator in the first two data elements for events from user space */ - _mali_osk_profiling_add_event(args->event_id, _mali_osk_get_pid(), _mali_osk_get_tid(), args->data[2], args->data[3], args->data[4]); - - return _MALI_OSK_ERR_OK; -} - -_mali_osk_errcode_t _mali_ukk_profiling_stop(_mali_uk_profiling_stop_s *args) -{ - return _mali_osk_profiling_stop(&args->count); -} - -_mali_osk_errcode_t _mali_ukk_profiling_get_event(_mali_uk_profiling_get_event_s *args) -{ - return _mali_osk_profiling_get_event(args->index, &args->timestamp, &args->event_id, args->data); -} - -_mali_osk_errcode_t _mali_ukk_profiling_clear(_mali_uk_profiling_clear_s *args) -{ - return _mali_osk_profiling_clear(); -} - -_mali_osk_errcode_t _mali_ukk_sw_counters_report(_mali_uk_sw_counters_report_s *args) -{ - _mali_osk_profiling_report_sw_counters(args->counters); - return _MALI_OSK_ERR_OK; -} - -/** - * Called by gator.ko to set HW counters - * - * @param counter_id The counter ID. - * @param event_id Event ID that the counter should count (HW counter value from TRM). - * - * @return 1 on success, 0 on failure. - */ -int _mali_profiling_set_event(u32 counter_id, s32 event_id) -{ - - if (COUNTER_VP_C0 == counter_id) - { - struct mali_gp_core* gp_core = mali_gp_get_global_gp_core(); - if (NULL != gp_core) - { - if (MALI_TRUE == mali_gp_core_set_counter_src0(gp_core, event_id)) - { - return 1; - } - } - } - if (COUNTER_VP_C1 == counter_id) - { - struct mali_gp_core* gp_core = mali_gp_get_global_gp_core(); - if (NULL != gp_core) - { - if (MALI_TRUE == mali_gp_core_set_counter_src1(gp_core, event_id)) - { - return 1; - } - } - } - if (COUNTER_FP0_C0 <= counter_id && COUNTER_FP3_C1 >= counter_id) - { - u32 core_id = (counter_id - COUNTER_FP0_C0) >> 1; - struct mali_pp_core* pp_core = mali_pp_get_global_pp_core(core_id); - if (NULL != pp_core) - { - u32 counter_src = (counter_id - COUNTER_FP0_C0) & 1; - if (0 == counter_src) - { - if (MALI_TRUE == mali_pp_core_set_counter_src0(pp_core, event_id)) - { - return 1; - } - } - else - { - if (MALI_TRUE == mali_pp_core_set_counter_src1(pp_core, event_id)) - { - return 1; - } - } - } - } - if (COUNTER_L2_C0 <= counter_id && COUNTER_L2_C1 >= counter_id) - { - u32 core_id = (counter_id - COUNTER_L2_C0) >> 1; - struct mali_l2_cache_core* l2_cache_core = mali_l2_cache_core_get_glob_l2_core(core_id); - if (NULL != l2_cache_core) - { - u32 counter_src = (counter_id - COUNTER_L2_C0) & 1; - if (0 == counter_src) - { - if (MALI_TRUE == mali_l2_cache_core_set_counter_src0(l2_cache_core, event_id)) - { - return 1; - } - } - else - { - if (MALI_TRUE == mali_l2_cache_core_set_counter_src1(l2_cache_core, event_id)) - { - return 1; - } - } - } - } - - return 0; -} - -/** - * Called by gator.ko to retrieve the L2 cache counter values for the first L2 cache. - * The L2 cache counters are unique in that they are polled by gator, rather than being - * transmitted via the tracepoint mechanism. - * - * @param src0 First L2 cache counter ID. - * @param val0 First L2 cache counter value. - * @param src1 Second L2 cache counter ID. - * @param val1 Second L2 cache counter value. - */ -void _mali_profiling_get_counters(u32 *src0, u32 *val0, u32 *src1, u32 *val1) -{ - struct mali_l2_cache_core *l2_cache = mali_l2_cache_core_get_glob_l2_core(0); - if (NULL != l2_cache) - { - if (MALI_TRUE == mali_l2_cache_lock_power_state(l2_cache)) - { - /* It is now safe to access the L2 cache core in order to retrieve the counters */ - mali_l2_cache_core_get_counter_values(l2_cache, src0, val0, src1, val1); - } - mali_l2_cache_unlock_power_state(l2_cache); - } -} - -/* - * List of possible actions to be controlled by Streamline. - * The following numbers are used by gator to control the frame buffer dumping and s/w counter reporting. - * We cannot use the enums in mali_uk_types.h because they are unknown inside gator. - */ -#define FBDUMP_CONTROL_ENABLE (1) -#define FBDUMP_CONTROL_RATE (2) -#define SW_COUNTER_ENABLE (3) -#define FBDUMP_CONTROL_RESIZE_FACTOR (4) - -/** - * Called by gator to control the production of profiling information at runtime. - */ -void _mali_profiling_control(u32 action, u32 value) -{ - switch(action) - { - case FBDUMP_CONTROL_ENABLE: - mali_set_user_setting(_MALI_UK_USER_SETTING_COLORBUFFER_CAPTURE_ENABLED, (value == 0 ? MALI_FALSE : MALI_TRUE)); - break; - case FBDUMP_CONTROL_RATE: - mali_set_user_setting(_MALI_UK_USER_SETTING_BUFFER_CAPTURE_N_FRAMES, value); - break; - case SW_COUNTER_ENABLE: - mali_set_user_setting(_MALI_UK_USER_SETTING_SW_COUNTER_ENABLED, value); - break; - case FBDUMP_CONTROL_RESIZE_FACTOR: - mali_set_user_setting(_MALI_UK_USER_SETTING_BUFFER_CAPTURE_RESIZE_FACTOR, value); - break; - default: - break; /* Ignore unimplemented actions */ - } -} - -EXPORT_SYMBOL(_mali_profiling_set_event); -EXPORT_SYMBOL(_mali_profiling_get_counters); -EXPORT_SYMBOL(_mali_profiling_control); diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_profiling_internal.c b/drivers/media/video/samsung/mali/linux/mali_osk_profiling_internal.c deleted file mode 100644 index 2df935d..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_osk_profiling_internal.c +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "mali_osk_mali.h" -#include "mali_ukk.h" -#include "mali_timestamp.h" -#include "mali_osk_profiling.h" -#include "mali_user_settings_db.h" - -typedef struct mali_profiling_entry -{ - u64 timestamp; - u32 event_id; - u32 data[5]; -} mali_profiling_entry; - - -typedef enum mali_profiling_state -{ - MALI_PROFILING_STATE_UNINITIALIZED, - MALI_PROFILING_STATE_IDLE, - MALI_PROFILING_STATE_RUNNING, - MALI_PROFILING_STATE_RETURN, -} mali_profiling_state; - -static _mali_osk_lock_t *lock = NULL; -static mali_profiling_state prof_state = MALI_PROFILING_STATE_UNINITIALIZED; -static mali_profiling_entry* profile_entries = NULL; -static u32 profile_entry_count = 0; -static _mali_osk_atomic_t profile_insert_index; -static _mali_osk_atomic_t profile_entries_written; - -_mali_osk_errcode_t _mali_osk_profiling_init(mali_bool auto_start) -{ - profile_entries = NULL; - profile_entry_count = 0; - _mali_osk_atomic_init(&profile_insert_index, 0); - _mali_osk_atomic_init(&profile_entries_written, 0); - - lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_PROFILING); - if (NULL == lock) - { - return _MALI_OSK_ERR_FAULT; - } - - prof_state = MALI_PROFILING_STATE_IDLE; - - if (MALI_TRUE == auto_start) - { - u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* Use maximum buffer size */ - - mali_set_user_setting(_MALI_UK_USER_SETTING_SW_EVENTS_ENABLE, MALI_TRUE); - if (_MALI_OSK_ERR_OK != _mali_osk_profiling_start(&limit)) - { - return _MALI_OSK_ERR_FAULT; - } - } - - return _MALI_OSK_ERR_OK; -} - -void _mali_osk_profiling_term(void) -{ - prof_state = MALI_PROFILING_STATE_UNINITIALIZED; - - /* wait for all elements to be completely inserted into array */ - while (_mali_osk_atomic_read(&profile_insert_index) != _mali_osk_atomic_read(&profile_entries_written)) - { - /* do nothing */; - } - - if (NULL != profile_entries) - { - _mali_osk_vfree(profile_entries); - profile_entries = NULL; - } - - if (NULL != lock) - { - _mali_osk_lock_term(lock); - lock = NULL; - } -} - -inline _mali_osk_errcode_t _mali_osk_profiling_start(u32 * limit) -{ - _mali_osk_errcode_t ret; - - mali_profiling_entry *new_profile_entries = _mali_osk_valloc(*limit * sizeof(mali_profiling_entry)); - - if(NULL == new_profile_entries) - { - return _MALI_OSK_ERR_NOMEM; - } - - _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); - - if (prof_state != MALI_PROFILING_STATE_IDLE) - { - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - _mali_osk_vfree(new_profile_entries); - return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */ - } - - if (*limit > MALI_PROFILING_MAX_BUFFER_ENTRIES) - { - *limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; - } - - profile_entries = new_profile_entries; - profile_entry_count = *limit; - - ret = _mali_timestamp_reset(); - - if (ret == _MALI_OSK_ERR_OK) - { - prof_state = MALI_PROFILING_STATE_RUNNING; - } - else - { - _mali_osk_vfree(profile_entries); - profile_entries = NULL; - } - - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return ret; -} - -inline void _mali_osk_profiling_add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4) -{ - if (prof_state == MALI_PROFILING_STATE_RUNNING) - { - u32 cur_index = (_mali_osk_atomic_inc_return(&profile_insert_index) - 1) % profile_entry_count; - - profile_entries[cur_index].timestamp = _mali_timestamp_get(); - profile_entries[cur_index].event_id = event_id; - profile_entries[cur_index].data[0] = data0; - profile_entries[cur_index].data[1] = data1; - profile_entries[cur_index].data[2] = data2; - profile_entries[cur_index].data[3] = data3; - profile_entries[cur_index].data[4] = data4; - - /* If event is "leave API function", add current memory usage to the event - * as data point 4. This is used in timeline profiling to indicate how - * much memory was used when leaving a function. */ - if (event_id == (MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_SINGLE_SW_LEAVE_API_FUNC)) - { - profile_entries[cur_index].data[4] = _mali_ukk_report_memory_usage(); - } - - _mali_osk_atomic_inc(&profile_entries_written); - } -} - -inline void _mali_osk_profiling_report_hw_counter(u32 counter_id, u32 value) -{ - /* Not implemented */ -} - -void _mali_osk_profiling_report_sw_counters(u32 *counters) -{ - /* Not implemented */ -} - -inline _mali_osk_errcode_t _mali_osk_profiling_stop(u32 * count) -{ - _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); - - if (prof_state != MALI_PROFILING_STATE_RUNNING) - { - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */ - } - - /* go into return state (user to retreive events), no more events will be added after this */ - prof_state = MALI_PROFILING_STATE_RETURN; - - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - - /* wait for all elements to be completely inserted into array */ - while (_mali_osk_atomic_read(&profile_insert_index) != _mali_osk_atomic_read(&profile_entries_written)) - { - /* do nothing */; - } - - *count = _mali_osk_atomic_read(&profile_insert_index); - if(*count>profile_entry_count) *count=profile_entry_count; - - return _MALI_OSK_ERR_OK; -} - -inline u32 _mali_osk_profiling_get_count(void) -{ - u32 retval = 0; - - _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); - if (prof_state == MALI_PROFILING_STATE_RETURN) - { - retval = _mali_osk_atomic_read(&profile_entries_written); - if(retval>profile_entry_count) retval = profile_entry_count; - } - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - - return retval; -} - -inline _mali_osk_errcode_t _mali_osk_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5]) -{ - _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); - - if(index=profile_entry_count) - { - idx = (index + _mali_osk_atomic_read(&profile_insert_index)) % profile_entry_count; - } - - if (prof_state != MALI_PROFILING_STATE_RETURN) - { - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */ - } - - if (idx >= _mali_osk_atomic_read(&profile_entries_written)) - { - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return _MALI_OSK_ERR_FAULT; - } - - *timestamp = profile_entries[idx].timestamp; - *event_id = profile_entries[idx].event_id; - data[0] = profile_entries[idx].data[0]; - data[1] = profile_entries[idx].data[1]; - data[2] = profile_entries[idx].data[2]; - data[3] = profile_entries[idx].data[3]; - data[4] = profile_entries[idx].data[4]; - } - else - { - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return _MALI_OSK_ERR_FAULT; - } - - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return _MALI_OSK_ERR_OK; -} - -inline _mali_osk_errcode_t _mali_osk_profiling_clear(void) -{ - _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); - - if (prof_state != MALI_PROFILING_STATE_RETURN) - { - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */ - } - - prof_state = MALI_PROFILING_STATE_IDLE; - profile_entry_count = 0; - _mali_osk_atomic_init(&profile_insert_index, 0); - _mali_osk_atomic_init(&profile_entries_written, 0); - if (NULL != profile_entries) - { - _mali_osk_vfree(profile_entries); - profile_entries = NULL; - } - - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return _MALI_OSK_ERR_OK; -} - -mali_bool _mali_osk_profiling_is_recording(void) -{ - return prof_state == MALI_PROFILING_STATE_RUNNING ? MALI_TRUE : MALI_FALSE; -} - -mali_bool _mali_osk_profiling_have_recording(void) -{ - return prof_state == MALI_PROFILING_STATE_RETURN ? MALI_TRUE : MALI_FALSE; -} - -_mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args) -{ - return _mali_osk_profiling_start(&args->limit); -} - -_mali_osk_errcode_t _mali_ukk_profiling_add_event(_mali_uk_profiling_add_event_s *args) -{ - /* Always add process and thread identificator in the first two data elements for events from user space */ - _mali_osk_profiling_add_event(args->event_id, _mali_osk_get_pid(), _mali_osk_get_tid(), args->data[2], args->data[3], args->data[4]); - return _MALI_OSK_ERR_OK; -} - -_mali_osk_errcode_t _mali_ukk_profiling_stop(_mali_uk_profiling_stop_s *args) -{ - return _mali_osk_profiling_stop(&args->count); -} - -_mali_osk_errcode_t _mali_ukk_profiling_get_event(_mali_uk_profiling_get_event_s *args) -{ - return _mali_osk_profiling_get_event(args->index, &args->timestamp, &args->event_id, args->data); -} - -_mali_osk_errcode_t _mali_ukk_profiling_clear(_mali_uk_profiling_clear_s *args) -{ - return _mali_osk_profiling_clear(); -} - -_mali_osk_errcode_t _mali_ukk_sw_counters_report(_mali_uk_sw_counters_report_s *args) -{ - _mali_osk_profiling_report_sw_counters(args->counters); - return _MALI_OSK_ERR_OK; -} - diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_specific.h b/drivers/media/video/samsung/mali/linux/mali_osk_specific.h deleted file mode 100644 index 83ee906..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_osk_specific.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_osk_specific.h - * Defines per-OS Kernel level specifics, such as unusual workarounds for - * certain OSs. - */ - -#ifndef __MALI_OSK_SPECIFIC_H__ -#define __MALI_OSK_SPECIFIC_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#define MALI_STATIC_INLINE static inline -#define MALI_NON_STATIC_INLINE inline - -#ifdef __cplusplus -} -#endif - -/** The list of events supported by the Mali DDK. */ -typedef enum -{ - /* Vertex processor activity */ - ACTIVITY_VP = 0, - - /* Fragment processor activity */ - ACTIVITY_FP0, - ACTIVITY_FP1, - ACTIVITY_FP2, - ACTIVITY_FP3, - - /* L2 cache counters */ - COUNTER_L2_C0, - COUNTER_L2_C1, - - /* Vertex processor counters */ - COUNTER_VP_C0, - COUNTER_VP_C1, - - /* Fragment processor counters */ - COUNTER_FP0_C0, - COUNTER_FP0_C1, - COUNTER_FP1_C0, - COUNTER_FP1_C1, - COUNTER_FP2_C0, - COUNTER_FP2_C1, - COUNTER_FP3_C0, - COUNTER_FP3_C1, - - /* - * If more hardware counters are added, the _mali_osk_hw_counter_table - * below should also be updated. - */ - - /* EGL software counters */ - COUNTER_EGL_BLIT_TIME, - - /* GLES software counters */ - COUNTER_GLES_DRAW_ELEMENTS_CALLS, - COUNTER_GLES_DRAW_ELEMENTS_NUM_INDICES, - COUNTER_GLES_DRAW_ELEMENTS_NUM_TRANSFORMED, - COUNTER_GLES_DRAW_ARRAYS_CALLS, - COUNTER_GLES_DRAW_ARRAYS_NUM_TRANSFORMED, - COUNTER_GLES_DRAW_POINTS, - COUNTER_GLES_DRAW_LINES, - COUNTER_GLES_DRAW_LINE_LOOP, - COUNTER_GLES_DRAW_LINE_STRIP, - COUNTER_GLES_DRAW_TRIANGLES, - COUNTER_GLES_DRAW_TRIANGLE_STRIP, - COUNTER_GLES_DRAW_TRIANGLE_FAN, - COUNTER_GLES_NON_VBO_DATA_COPY_TIME, - COUNTER_GLES_UNIFORM_BYTES_COPIED_TO_MALI, - COUNTER_GLES_UPLOAD_TEXTURE_TIME, - COUNTER_GLES_UPLOAD_VBO_TIME, - COUNTER_GLES_NUM_FLUSHES, - COUNTER_GLES_NUM_VSHADERS_GENERATED, - COUNTER_GLES_NUM_FSHADERS_GENERATED, - COUNTER_GLES_VSHADER_GEN_TIME, - COUNTER_GLES_FSHADER_GEN_TIME, - COUNTER_GLES_INPUT_TRIANGLES, - COUNTER_GLES_VXCACHE_HIT, - COUNTER_GLES_VXCACHE_MISS, - COUNTER_GLES_VXCACHE_COLLISION, - COUNTER_GLES_CULLED_TRIANGLES, - COUNTER_GLES_CULLED_LINES, - COUNTER_GLES_BACKFACE_TRIANGLES, - COUNTER_GLES_GBCLIP_TRIANGLES, - COUNTER_GLES_GBCLIP_LINES, - COUNTER_GLES_TRIANGLES_DRAWN, - COUNTER_GLES_DRAWCALL_TIME, - COUNTER_GLES_TRIANGLES_COUNT, - COUNTER_GLES_INDEPENDENT_TRIANGLES_COUNT, - COUNTER_GLES_STRIP_TRIANGLES_COUNT, - COUNTER_GLES_FAN_TRIANGLES_COUNT, - COUNTER_GLES_LINES_COUNT, - COUNTER_GLES_INDEPENDENT_LINES_COUNT, - COUNTER_GLES_STRIP_LINES_COUNT, - COUNTER_GLES_LOOP_LINES_COUNT, - - /* Framebuffer capture pseudo-counter */ - COUNTER_FILMSTRIP, - - NUMBER_OF_EVENTS -} _mali_osk_counter_id; - -#define FIRST_ACTIVITY_EVENT ACTIVITY_VP -#define LAST_ACTIVITY_EVENT ACTIVITY_FP3 - -#define FIRST_HW_COUNTER COUNTER_L2_C0 -#define LAST_HW_COUNTER COUNTER_FP3_C1 - -#define FIRST_SW_COUNTER COUNTER_EGL_BLIT_TIME -#define LAST_SW_COUNTER COUNTER_GLES_LOOP_LINES_COUNT - -#define FIRST_SPECIAL_COUNTER COUNTER_FILMSTRIP -#define LAST_SPECIAL_COUNTER COUNTER_FILMSTRIP - -#endif /* __MALI_OSK_SPECIFIC_H__ */ diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_time.c b/drivers/media/video/samsung/mali/linux/mali_osk_time.c deleted file mode 100644 index b399b87..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_osk_time.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_osk_time.c - * Implementation of the OS abstraction layer for the kernel device driver - */ - -#include "mali_osk.h" -#include -#include -#include - -int _mali_osk_time_after( u32 ticka, u32 tickb ) -{ - return time_after((unsigned long)ticka, (unsigned long)tickb); -} - -u32 _mali_osk_time_mstoticks( u32 ms ) -{ - return msecs_to_jiffies(ms); -} - -u32 _mali_osk_time_tickstoms( u32 ticks ) -{ - return jiffies_to_msecs(ticks); -} - -u32 _mali_osk_time_tickcount( void ) -{ - return jiffies; -} - -void _mali_osk_time_ubusydelay( u32 usecs ) -{ - udelay(usecs); -} - -u64 _mali_osk_time_get_ns( void ) -{ - struct timespec tsval; - getnstimeofday(&tsval); - return (u64)timespec_to_ns(&tsval); -} diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_timers.c b/drivers/media/video/samsung/mali/linux/mali_osk_timers.c deleted file mode 100644 index e5829a3..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_osk_timers.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_osk_timers.c - * Implementation of the OS abstraction layer for the kernel device driver - */ - -#include -#include -#include "mali_osk.h" -#include "mali_kernel_common.h" - -struct _mali_osk_timer_t_struct -{ - struct timer_list timer; -}; - -typedef void (*timer_timeout_function_t)(unsigned long); - -_mali_osk_timer_t *_mali_osk_timer_init(void) -{ - _mali_osk_timer_t *t = (_mali_osk_timer_t*)kmalloc(sizeof(_mali_osk_timer_t), GFP_KERNEL); - if (NULL != t) init_timer(&t->timer); - return t; -} - -void _mali_osk_timer_add( _mali_osk_timer_t *tim, u32 ticks_to_expire ) -{ - MALI_DEBUG_ASSERT_POINTER(tim); - tim->timer.expires = _mali_osk_time_tickcount() + ticks_to_expire; - add_timer(&(tim->timer)); -} - -void _mali_osk_timer_mod( _mali_osk_timer_t *tim, u32 expiry_tick) -{ - MALI_DEBUG_ASSERT_POINTER(tim); - mod_timer(&(tim->timer), expiry_tick); -} - -void _mali_osk_timer_del( _mali_osk_timer_t *tim ) -{ - MALI_DEBUG_ASSERT_POINTER(tim); - del_timer_sync(&(tim->timer)); -} - -void _mali_osk_timer_setcallback( _mali_osk_timer_t *tim, _mali_osk_timer_callback_t callback, void *data ) -{ - MALI_DEBUG_ASSERT_POINTER(tim); - tim->timer.data = (unsigned long)data; - tim->timer.function = (timer_timeout_function_t)callback; -} - -void _mali_osk_timer_term( _mali_osk_timer_t *tim ) -{ - MALI_DEBUG_ASSERT_POINTER(tim); - kfree(tim); -} diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_wait_queue.c b/drivers/media/video/samsung/mali/linux/mali_osk_wait_queue.c deleted file mode 100644 index ce0561d..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_osk_wait_queue.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_osk_wait_queue.c - * Implemenation of the OS abstraction layer for the kernel device driver - */ - -#include -#include -#include - -#include "mali_osk.h" -#include "mali_kernel_common.h" - -struct _mali_osk_wait_queue_t_struct -{ - wait_queue_head_t wait_queue; -}; - -_mali_osk_wait_queue_t* _mali_osk_wait_queue_init( void ) -{ - _mali_osk_wait_queue_t* ret = NULL; - - ret = kmalloc(sizeof(_mali_osk_wait_queue_t), GFP_KERNEL); - - if (NULL == ret) - { - return ret; - } - - init_waitqueue_head(&ret->wait_queue); - MALI_DEBUG_ASSERT(!waitqueue_active(&ret->wait_queue)); - - return ret; -} - -void _mali_osk_wait_queue_wait_event( _mali_osk_wait_queue_t *queue, mali_bool (*condition)(void) ) -{ - MALI_DEBUG_ASSERT_POINTER( queue ); - MALI_DEBUG_PRINT(6, ("Adding to wait queue %p\n", queue)); - wait_event(queue->wait_queue, condition()); -} - -void _mali_osk_wait_queue_wake_up( _mali_osk_wait_queue_t *queue ) -{ - MALI_DEBUG_ASSERT_POINTER( queue ); - - /* if queue is empty, don't attempt to wake up its elements */ - if (!waitqueue_active(&queue->wait_queue)) return; - - MALI_DEBUG_PRINT(6, ("Waking up elements in wait queue %p ....\n", queue)); - - wake_up_all(&queue->wait_queue); - - MALI_DEBUG_PRINT(6, ("... elements in wait queue %p woken up\n", queue)); -} - -void _mali_osk_wait_queue_term( _mali_osk_wait_queue_t *queue ) -{ - /* Parameter validation */ - MALI_DEBUG_ASSERT_POINTER( queue ); - - /* Linux requires no explicit termination of wait queues */ - kfree(queue); -} diff --git a/drivers/media/video/samsung/mali/linux/mali_pmu_power_up_down.c b/drivers/media/video/samsung/mali/linux/mali_pmu_power_up_down.c deleted file mode 100644 index f3b0a2c..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_pmu_power_up_down.c +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_pmu_power_up_down.c - */ - -#include -#include -#include -#include "mali_osk.h" -#include "mali_kernel_common.h" -#include "mali_pmu.h" -#include "linux/mali/mali_utgard.h" - -/* Mali PMU power up/down APIs */ - -int mali_pmu_powerup(void) -{ - struct mali_pmu_core *pmu = mali_pmu_get_global_pmu_core(); - - MALI_DEBUG_PRINT(5, ("Mali PMU: Power up\n")); - - if (NULL == pmu) - { - return -ENXIO; - } - - if (_MALI_OSK_ERR_OK != mali_pmu_powerup_all(pmu)) - { - return -EFAULT; - } - - return 0; -} - -EXPORT_SYMBOL(mali_pmu_powerup); - -int mali_pmu_powerdown(void) -{ - struct mali_pmu_core *pmu = mali_pmu_get_global_pmu_core(); - - MALI_DEBUG_PRINT(5, ("Mali PMU: Power down\n")); - - if (NULL == pmu) - { - return -ENXIO; - } - - if (_MALI_OSK_ERR_OK != mali_pmu_powerdown_all(pmu)) - { - return -EFAULT; - } - - return 0; -} - -EXPORT_SYMBOL(mali_pmu_powerdown); diff --git a/drivers/media/video/samsung/mali/linux/mali_profiling_events.h b/drivers/media/video/samsung/mali/linux/mali_profiling_events.h deleted file mode 100644 index 2639a40..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_profiling_events.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_PROFILING_EVENTS_H__ -#define __MALI_PROFILING_EVENTS_H__ - -/* Simple wrapper in order to find the OS specific location of this file */ -#include - -#endif /* __MALI_PROFILING_EVENTS_H__ */ diff --git a/drivers/media/video/samsung/mali/linux/mali_uk_types.h b/drivers/media/video/samsung/mali/linux/mali_uk_types.h deleted file mode 100644 index 1a81246..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_uk_types.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (C) 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_UK_TYPES_H__ -#define __MALI_UK_TYPES_H__ - -/* Simple wrapper in order to find the OS specific location of this file */ -//#include -#include "../include/linux/mali/mali_utgard_uk_types.h" - -#endif /* __MALI_UK_TYPES_H__ */ diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_core.c b/drivers/media/video/samsung/mali/linux/mali_ukk_core.c deleted file mode 100644 index 22262fe..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_ukk_core.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include /* file system operations */ -#include /* memort allocation functions */ -#include /* user space access */ - -#include "mali_ukk.h" -#include "mali_osk.h" -#include "mali_kernel_common.h" -#include "mali_session.h" -#include "mali_ukk_wrappers.h" - -int get_api_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_api_version_s __user *uargs) -{ - _mali_uk_get_api_version_s kargs; - _mali_osk_errcode_t err; - - MALI_CHECK_NON_NULL(uargs, -EINVAL); - - if (0 != get_user(kargs.version, &uargs->version)) return -EFAULT; - - kargs.ctx = session_data; - err = _mali_ukk_get_api_version(&kargs); - if (_MALI_OSK_ERR_OK != err) return map_errcode(err); - - if (0 != put_user(kargs.version, &uargs->version)) return -EFAULT; - if (0 != put_user(kargs.compatible, &uargs->compatible)) return -EFAULT; - - return 0; -} - -int wait_for_notification_wrapper(struct mali_session_data *session_data, _mali_uk_wait_for_notification_s __user *uargs) -{ - _mali_uk_wait_for_notification_s kargs; - _mali_osk_errcode_t err; - - MALI_CHECK_NON_NULL(uargs, -EINVAL); - - kargs.ctx = session_data; - err = _mali_ukk_wait_for_notification(&kargs); - if (_MALI_OSK_ERR_OK != err) return map_errcode(err); - - if(_MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS != kargs.type) - { - kargs.ctx = NULL; /* prevent kernel address to be returned to user space */ - if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_wait_for_notification_s))) return -EFAULT; - } - else - { - if (0 != put_user(kargs.type, &uargs->type)) return -EFAULT; - } - - return 0; -} - -int post_notification_wrapper(struct mali_session_data *session_data, _mali_uk_post_notification_s __user *uargs) -{ - _mali_uk_post_notification_s kargs; - _mali_osk_errcode_t err; - - MALI_CHECK_NON_NULL(uargs, -EINVAL); - - kargs.ctx = session_data; - - if (0 != get_user(kargs.type, &uargs->type)) - { - return -EFAULT; - } - - err = _mali_ukk_post_notification(&kargs); - if (_MALI_OSK_ERR_OK != err) - { - return map_errcode(err); - } - - return 0; -} - -int get_user_settings_wrapper(struct mali_session_data *session_data, _mali_uk_get_user_settings_s __user *uargs) -{ - _mali_uk_get_user_settings_s kargs; - _mali_osk_errcode_t err; - - MALI_CHECK_NON_NULL(uargs, -EINVAL); - - kargs.ctx = session_data; - err = _mali_ukk_get_user_settings(&kargs); - if (_MALI_OSK_ERR_OK != err) - { - return map_errcode(err); - } - - kargs.ctx = NULL; /* prevent kernel address to be returned to user space */ - if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_get_user_settings_s))) return -EFAULT; - - return 0; -} diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_gp.c b/drivers/media/video/samsung/mali/linux/mali_ukk_gp.c deleted file mode 100644 index 7070016..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_ukk_gp.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include /* file system operations */ -#include /* user space access */ - -#include "mali_ukk.h" -#include "mali_osk.h" -#include "mali_kernel_common.h" -#include "mali_session.h" -#include "mali_ukk_wrappers.h" - -int gp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_gp_start_job_s __user *uargs) -{ - _mali_uk_gp_start_job_s kargs; - _mali_osk_errcode_t err; - - MALI_CHECK_NON_NULL(uargs, -EINVAL); - MALI_CHECK_NON_NULL(session_data, -EINVAL); - - if (!access_ok(VERIFY_WRITE, uargs, sizeof(_mali_uk_gp_start_job_s))) - { - return -EFAULT; - } - - if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_gp_start_job_s))) return -EFAULT; - - kargs.ctx = session_data; - err = _mali_ukk_gp_start_job(&kargs); - if (_MALI_OSK_ERR_OK != err) return map_errcode(err); - - kargs.ctx = NULL; /* prevent kernel address to be returned to user space */ - - if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_gp_start_job_s))) - { - /* - * If this happens, then user space will not know that the job was actually started, - * and if we return a queued job, then user space will still think that one is still queued. - * This will typically lead to a deadlock in user space. - * This could however only happen if user space deliberately passes a user buffer which - * passes the access_ok(VERIFY_WRITE) check, but isn't fully writable at the time of copy_to_user(). - * The official Mali driver will never attempt to do that, and kernel space should not be affected. - * That is why we do not bother to do a complex rollback in this very very very rare case. - */ - return -EFAULT; - } - - return 0; -} - -int gp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_gp_core_version_s __user *uargs) -{ - _mali_uk_get_gp_core_version_s kargs; - _mali_osk_errcode_t err; - - MALI_CHECK_NON_NULL(uargs, -EINVAL); - MALI_CHECK_NON_NULL(session_data, -EINVAL); - - kargs.ctx = session_data; - err = _mali_ukk_get_gp_core_version(&kargs); - if (_MALI_OSK_ERR_OK != err) return map_errcode(err); - - /* no known transactions to roll-back */ - - if (0 != put_user(kargs.version, &uargs->version)) return -EFAULT; - - return 0; -} - -int gp_suspend_response_wrapper(struct mali_session_data *session_data, _mali_uk_gp_suspend_response_s __user *uargs) -{ - _mali_uk_gp_suspend_response_s kargs; - _mali_osk_errcode_t err; - - MALI_CHECK_NON_NULL(uargs, -EINVAL); - MALI_CHECK_NON_NULL(session_data, -EINVAL); - - if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_gp_suspend_response_s))) return -EFAULT; - - kargs.ctx = session_data; - err = _mali_ukk_gp_suspend_response(&kargs); - if (_MALI_OSK_ERR_OK != err) return map_errcode(err); - - if (0 != put_user(kargs.cookie, &uargs->cookie)) return -EFAULT; - - /* no known transactions to roll-back */ - return 0; -} - -int gp_get_number_of_cores_wrapper(struct mali_session_data *session_data, _mali_uk_get_gp_number_of_cores_s __user *uargs) -{ - _mali_uk_get_gp_number_of_cores_s kargs; - _mali_osk_errcode_t err; - - MALI_CHECK_NON_NULL(uargs, -EINVAL); - MALI_CHECK_NON_NULL(session_data, -EINVAL); - - kargs.ctx = session_data; - err = _mali_ukk_get_gp_number_of_cores(&kargs); - if (_MALI_OSK_ERR_OK != err) return map_errcode(err); - - /* no known transactions to roll-back */ - - if (0 != put_user(kargs.number_of_cores, &uargs->number_of_cores)) return -EFAULT; - - return 0; -} diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_mem.c b/drivers/media/video/samsung/mali/linux/mali_ukk_mem.c deleted file mode 100644 index 260f257..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_ukk_mem.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include /* file system operations */ -#include /* user space access */ - -#include "mali_ukk.h" -#include "mali_osk.h" -#include "mali_kernel_common.h" -#include "mali_session.h" -#include "mali_ukk_wrappers.h" - -int mem_init_wrapper(struct mali_session_data *session_data, _mali_uk_init_mem_s __user *uargs) -{ - _mali_uk_init_mem_s kargs; - _mali_osk_errcode_t err; - - MALI_CHECK_NON_NULL(uargs, -EINVAL); - - kargs.ctx = session_data; - err = _mali_ukk_init_mem(&kargs); - if (_MALI_OSK_ERR_OK != err) - { - return map_errcode(err); - } - - if (0 != put_user(kargs.mali_address_base, &uargs->mali_address_base)) goto mem_init_rollback; - if (0 != put_user(kargs.memory_size, &uargs->memory_size)) goto mem_init_rollback; - - return 0; - -mem_init_rollback: - { - _mali_uk_term_mem_s kargs; - kargs.ctx = session_data; - err = _mali_ukk_term_mem(&kargs); - if (_MALI_OSK_ERR_OK != err) - { - MALI_DEBUG_PRINT(4, ("reverting _mali_ukk_init_mem, as a result of failing put_user(), failed\n")); - } - } - return -EFAULT; -} - -int mem_term_wrapper(struct mali_session_data *session_data, _mali_uk_term_mem_s __user *uargs) -{ - _mali_uk_term_mem_s kargs; - _mali_osk_errcode_t err; - - MALI_CHECK_NON_NULL(uargs, -EINVAL); - - kargs.ctx = session_data; - err = _mali_ukk_term_mem(&kargs); - if (_MALI_OSK_ERR_OK != err) - { - return map_errcode(err); - } - - return 0; -} - -int mem_map_ext_wrapper(struct mali_session_data *session_data, _mali_uk_map_external_mem_s __user * argument) -{ - _mali_uk_map_external_mem_s uk_args; - _mali_osk_errcode_t err_code; - - /* validate input */ - /* the session_data pointer was validated by caller */ - MALI_CHECK_NON_NULL( argument, -EINVAL); - - /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */ - if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_map_external_mem_s)) ) - { - return -EFAULT; - } - - uk_args.ctx = session_data; - err_code = _mali_ukk_map_external_mem( &uk_args ); - - if (0 != put_user(uk_args.cookie, &argument->cookie)) - { - if (_MALI_OSK_ERR_OK == err_code) - { - /* Rollback */ - _mali_uk_unmap_external_mem_s uk_args_unmap; - - uk_args_unmap.ctx = session_data; - uk_args_unmap.cookie = uk_args.cookie; - err_code = _mali_ukk_unmap_external_mem( &uk_args_unmap ); - if (_MALI_OSK_ERR_OK != err_code) - { - MALI_DEBUG_PRINT(4, ("reverting _mali_ukk_unmap_external_mem, as a result of failing put_user(), failed\n")); - } - } - return -EFAULT; - } - - /* Return the error that _mali_ukk_free_big_block produced */ - return map_errcode(err_code); -} - -int mem_unmap_ext_wrapper(struct mali_session_data *session_data, _mali_uk_unmap_external_mem_s __user * argument) -{ - _mali_uk_unmap_external_mem_s uk_args; - _mali_osk_errcode_t err_code; - - /* validate input */ - /* the session_data pointer was validated by caller */ - MALI_CHECK_NON_NULL( argument, -EINVAL); - - /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */ - if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_unmap_external_mem_s)) ) - { - return -EFAULT; - } - - uk_args.ctx = session_data; - err_code = _mali_ukk_unmap_external_mem( &uk_args ); - - /* Return the error that _mali_ukk_free_big_block produced */ - return map_errcode(err_code); -} - -#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 -int mem_release_ump_wrapper(struct mali_session_data *session_data, _mali_uk_release_ump_mem_s __user * argument) -{ - _mali_uk_release_ump_mem_s uk_args; - _mali_osk_errcode_t err_code; - - /* validate input */ - /* the session_data pointer was validated by caller */ - MALI_CHECK_NON_NULL( argument, -EINVAL); - - /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */ - if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_release_ump_mem_s)) ) - { - return -EFAULT; - } - - uk_args.ctx = session_data; - err_code = _mali_ukk_release_ump_mem( &uk_args ); - - /* Return the error that _mali_ukk_free_big_block produced */ - return map_errcode(err_code); -} - -int mem_attach_ump_wrapper(struct mali_session_data *session_data, _mali_uk_attach_ump_mem_s __user * argument) -{ - _mali_uk_attach_ump_mem_s uk_args; - _mali_osk_errcode_t err_code; - - /* validate input */ - /* the session_data pointer was validated by caller */ - MALI_CHECK_NON_NULL( argument, -EINVAL); - - /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */ - if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_attach_ump_mem_s)) ) - { - return -EFAULT; - } - - uk_args.ctx = session_data; - err_code = _mali_ukk_attach_ump_mem( &uk_args ); - - if (0 != put_user(uk_args.cookie, &argument->cookie)) - { - if (_MALI_OSK_ERR_OK == err_code) - { - /* Rollback */ - _mali_uk_release_ump_mem_s uk_args_unmap; - - uk_args_unmap.ctx = session_data; - uk_args_unmap.cookie = uk_args.cookie; - err_code = _mali_ukk_release_ump_mem( &uk_args_unmap ); - if (_MALI_OSK_ERR_OK != err_code) - { - MALI_DEBUG_PRINT(4, ("reverting _mali_ukk_attach_mem, as a result of failing put_user(), failed\n")); - } - } - return -EFAULT; - } - - /* Return the error that _mali_ukk_map_external_ump_mem produced */ - return map_errcode(err_code); -} -#endif /* MALI_USE_UNIFIED_MEMORY_PROVIDER */ - -int mem_query_mmu_page_table_dump_size_wrapper(struct mali_session_data *session_data, _mali_uk_query_mmu_page_table_dump_size_s __user * uargs) -{ - _mali_uk_query_mmu_page_table_dump_size_s kargs; - _mali_osk_errcode_t err; - - MALI_CHECK_NON_NULL(uargs, -EINVAL); - MALI_CHECK_NON_NULL(session_data, -EINVAL); - - kargs.ctx = session_data; - - err = _mali_ukk_query_mmu_page_table_dump_size(&kargs); - if (_MALI_OSK_ERR_OK != err) return map_errcode(err); - - if (0 != put_user(kargs.size, &uargs->size)) return -EFAULT; - - return 0; -} - -int mem_dump_mmu_page_table_wrapper(struct mali_session_data *session_data, _mali_uk_dump_mmu_page_table_s __user * uargs) -{ - _mali_uk_dump_mmu_page_table_s kargs; - _mali_osk_errcode_t err; - void *buffer; - int rc = -EFAULT; - - /* validate input */ - MALI_CHECK_NON_NULL(uargs, -EINVAL); - /* the session_data pointer was validated by caller */ - - kargs.buffer = NULL; - - /* get location of user buffer */ - if (0 != get_user(buffer, &uargs->buffer)) goto err_exit; - /* get size of mmu page table info buffer from user space */ - if ( 0 != get_user(kargs.size, &uargs->size) ) goto err_exit; - /* verify we can access the whole of the user buffer */ - if (!access_ok(VERIFY_WRITE, buffer, kargs.size)) goto err_exit; - - /* allocate temporary buffer (kernel side) to store mmu page table info */ - kargs.buffer = _mali_osk_valloc(kargs.size); - if (NULL == kargs.buffer) - { - rc = -ENOMEM; - goto err_exit; - } - - kargs.ctx = session_data; - err = _mali_ukk_dump_mmu_page_table(&kargs); - if (_MALI_OSK_ERR_OK != err) - { - rc = map_errcode(err); - goto err_exit; - } - - /* copy mmu page table info back to user space and update pointers */ - if (0 != copy_to_user(uargs->buffer, kargs.buffer, kargs.size) ) goto err_exit; - if (0 != put_user((kargs.register_writes - (u32 *)kargs.buffer) + (u32 *)uargs->buffer, &uargs->register_writes)) goto err_exit; - if (0 != put_user((kargs.page_table_dump - (u32 *)kargs.buffer) + (u32 *)uargs->buffer, &uargs->page_table_dump)) goto err_exit; - if (0 != put_user(kargs.register_writes_size, &uargs->register_writes_size)) goto err_exit; - if (0 != put_user(kargs.page_table_dump_size, &uargs->page_table_dump_size)) goto err_exit; - rc = 0; - -err_exit: - if (kargs.buffer) _mali_osk_vfree(kargs.buffer); - return rc; -} diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_pp.c b/drivers/media/video/samsung/mali/linux/mali_ukk_pp.c deleted file mode 100644 index c11c61b..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_ukk_pp.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include /* file system operations */ -#include /* user space access */ - -#include "mali_ukk.h" -#include "mali_osk.h" -#include "mali_kernel_common.h" -#include "mali_session.h" -#include "mali_ukk_wrappers.h" - -int pp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_start_job_s __user *uargs) -{ - _mali_uk_pp_start_job_s kargs; - _mali_osk_errcode_t err; - - MALI_CHECK_NON_NULL(uargs, -EINVAL); - MALI_CHECK_NON_NULL(session_data, -EINVAL); - - if (!access_ok(VERIFY_WRITE, uargs, sizeof(_mali_uk_pp_start_job_s))) - { - return -EFAULT; - } - - if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_pp_start_job_s))) return -EFAULT; - - kargs.ctx = session_data; - err = _mali_ukk_pp_start_job(&kargs); - if (_MALI_OSK_ERR_OK != err) return map_errcode(err); - - return 0; -} - -int pp_get_number_of_cores_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_number_of_cores_s __user *uargs) -{ - _mali_uk_get_pp_number_of_cores_s kargs; - _mali_osk_errcode_t err; - - MALI_CHECK_NON_NULL(uargs, -EINVAL); - MALI_CHECK_NON_NULL(session_data, -EINVAL); - - kargs.ctx = session_data; - err = _mali_ukk_get_pp_number_of_cores(&kargs); - if (_MALI_OSK_ERR_OK != err) return map_errcode(err); - - if (0 != put_user(kargs.number_of_cores, &uargs->number_of_cores)) return -EFAULT; - - return 0; -} - -int pp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_core_version_s __user *uargs) -{ - _mali_uk_get_pp_core_version_s kargs; - _mali_osk_errcode_t err; - - MALI_CHECK_NON_NULL(uargs, -EINVAL); - MALI_CHECK_NON_NULL(session_data, -EINVAL); - - kargs.ctx = session_data; - err = _mali_ukk_get_pp_core_version(&kargs); - if (_MALI_OSK_ERR_OK != err) return map_errcode(err); - - if (0 != put_user(kargs.version, &uargs->version)) return -EFAULT; - - return 0; -} - -int pp_disable_wb_wrapper(struct mali_session_data *session_data, _mali_uk_pp_disable_wb_s __user *uargs) -{ - _mali_uk_pp_disable_wb_s kargs; - - MALI_CHECK_NON_NULL(uargs, -EINVAL); - MALI_CHECK_NON_NULL(session_data, -EINVAL); - - if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_pp_disable_wb_s))) return -EFAULT; - - kargs.ctx = session_data; - _mali_ukk_pp_job_disable_wb(&kargs); - - return 0; -} diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_profiling.c b/drivers/media/video/samsung/mali/linux/mali_ukk_profiling.c deleted file mode 100644 index f4e31c9..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_ukk_profiling.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include /* file system operations */ -#include /* user space access */ -#include - -#include "mali_ukk.h" -#include "mali_osk.h" -#include "mali_kernel_common.h" -#include "mali_session.h" -#include "mali_ukk_wrappers.h" - -int profiling_start_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_start_s __user *uargs) -{ - _mali_uk_profiling_start_s kargs; - _mali_osk_errcode_t err; - - MALI_CHECK_NON_NULL(uargs, -EINVAL); - - if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_profiling_start_s))) - { - return -EFAULT; - } - - kargs.ctx = session_data; - err = _mali_ukk_profiling_start(&kargs); - if (_MALI_OSK_ERR_OK != err) - { - return map_errcode(err); - } - - if (0 != put_user(kargs.limit, &uargs->limit)) - { - return -EFAULT; - } - - return 0; -} - -int profiling_add_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_add_event_s __user *uargs) -{ - _mali_uk_profiling_add_event_s kargs; - _mali_osk_errcode_t err; - - MALI_CHECK_NON_NULL(uargs, -EINVAL); - - if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_profiling_add_event_s))) - { - return -EFAULT; - } - - kargs.ctx = session_data; - err = _mali_ukk_profiling_add_event(&kargs); - if (_MALI_OSK_ERR_OK != err) - { - return map_errcode(err); - } - - return 0; -} - -int profiling_stop_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_stop_s __user *uargs) -{ - _mali_uk_profiling_stop_s kargs; - _mali_osk_errcode_t err; - - MALI_CHECK_NON_NULL(uargs, -EINVAL); - - kargs.ctx = session_data; - err = _mali_ukk_profiling_stop(&kargs); - if (_MALI_OSK_ERR_OK != err) - { - return map_errcode(err); - } - - if (0 != put_user(kargs.count, &uargs->count)) - { - return -EFAULT; - } - - return 0; -} - -int profiling_get_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_get_event_s __user *uargs) -{ - _mali_uk_profiling_get_event_s kargs; - _mali_osk_errcode_t err; - - MALI_CHECK_NON_NULL(uargs, -EINVAL); - - if (0 != get_user(kargs.index, &uargs->index)) - { - return -EFAULT; - } - - kargs.ctx = session_data; - - err = _mali_ukk_profiling_get_event(&kargs); - if (_MALI_OSK_ERR_OK != err) - { - return map_errcode(err); - } - - kargs.ctx = NULL; /* prevent kernel address to be returned to user space */ - if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_profiling_get_event_s))) - { - return -EFAULT; - } - - return 0; -} - -int profiling_clear_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_clear_s __user *uargs) -{ - _mali_uk_profiling_clear_s kargs; - _mali_osk_errcode_t err; - - MALI_CHECK_NON_NULL(uargs, -EINVAL); - - kargs.ctx = session_data; - err = _mali_ukk_profiling_clear(&kargs); - if (_MALI_OSK_ERR_OK != err) - { - return map_errcode(err); - } - - return 0; -} - -int profiling_report_sw_counters_wrapper(struct mali_session_data *session_data, _mali_uk_sw_counters_report_s __user *uargs) -{ - _mali_uk_sw_counters_report_s kargs; - _mali_osk_errcode_t err; - u32 *counter_buffer; - - MALI_CHECK_NON_NULL(uargs, -EINVAL); - - if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_sw_counters_report_s))) - { - return -EFAULT; - } - - /* make sure that kargs.num_counters is [at least somewhat] sane */ - if (kargs.num_counters > 10000) { - MALI_DEBUG_PRINT(1, ("User space attempted to allocate too many counters.\n")); - return -EINVAL; - } - - counter_buffer = (u32*)kmalloc(sizeof(u32) * kargs.num_counters, GFP_KERNEL); - if (NULL == counter_buffer) - { - return -ENOMEM; - } - - if (0 != copy_from_user(counter_buffer, kargs.counters, sizeof(u32) * kargs.num_counters)) - { - kfree(counter_buffer); - return -EFAULT; - } - - kargs.ctx = session_data; - kargs.counters = counter_buffer; - - err = _mali_ukk_sw_counters_report(&kargs); - - kfree(counter_buffer); - - if (_MALI_OSK_ERR_OK != err) - { - return map_errcode(err); - } - - return 0; -} - - diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_vsync.c b/drivers/media/video/samsung/mali/linux/mali_ukk_vsync.c deleted file mode 100644 index f9b5a3e..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_ukk_vsync.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2011-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include /* file system operations */ -#include /* user space access */ - -#include "mali_ukk.h" -#include "mali_osk.h" -#include "mali_kernel_common.h" -#include "mali_session.h" -#include "mali_ukk_wrappers.h" - - -int vsync_event_report_wrapper(struct mali_session_data *session_data, _mali_uk_vsync_event_report_s __user *uargs) -{ - _mali_uk_vsync_event_report_s kargs; - _mali_osk_errcode_t err; - - MALI_CHECK_NON_NULL(uargs, -EINVAL); - - if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_vsync_event_report_s))) - { - return -EFAULT; - } - - kargs.ctx = session_data; - err = _mali_ukk_vsync_event_report(&kargs); - if (_MALI_OSK_ERR_OK != err) - { - return map_errcode(err); - } - - return 0; -} - diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_wrappers.h b/drivers/media/video/samsung/mali/linux/mali_ukk_wrappers.h deleted file mode 100644 index 65857fd..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_ukk_wrappers.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_ukk_wrappers.h - * Defines the wrapper functions for each user-kernel function - */ - -#ifndef __MALI_UKK_WRAPPERS_H__ -#define __MALI_UKK_WRAPPERS_H__ - -#include "mali_uk_types.h" -#include "mali_osk.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -int wait_for_notification_wrapper(struct mali_session_data *session_data, _mali_uk_wait_for_notification_s __user *uargs); -int get_api_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_api_version_s __user *uargs); -int get_user_settings_wrapper(struct mali_session_data *session_data, _mali_uk_get_user_settings_s __user *uargs); -int post_notification_wrapper(struct mali_session_data *session_data, _mali_uk_post_notification_s __user *uargs); -int mem_init_wrapper(struct mali_session_data *session_data, _mali_uk_init_mem_s __user *uargs); -int mem_term_wrapper(struct mali_session_data *session_data, _mali_uk_term_mem_s __user *uargs); -int mem_map_ext_wrapper(struct mali_session_data *session_data, _mali_uk_map_external_mem_s __user * argument); -int mem_unmap_ext_wrapper(struct mali_session_data *session_data, _mali_uk_unmap_external_mem_s __user * argument); -int mem_query_mmu_page_table_dump_size_wrapper(struct mali_session_data *session_data, _mali_uk_query_mmu_page_table_dump_size_s __user * uargs); -int mem_dump_mmu_page_table_wrapper(struct mali_session_data *session_data, _mali_uk_dump_mmu_page_table_s __user * uargs); - -#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 -int mem_attach_ump_wrapper(struct mali_session_data *session_data, _mali_uk_attach_ump_mem_s __user * argument); -int mem_release_ump_wrapper(struct mali_session_data *session_data, _mali_uk_release_ump_mem_s __user * argument); -#endif /* MALI_USE_UNIFIED_MEMORY_PROVIDER */ - -int pp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_start_job_s __user *uargs); -int pp_get_number_of_cores_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_number_of_cores_s __user *uargs); -int pp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_core_version_s __user *uargs); -int pp_disable_wb_wrapper(struct mali_session_data *session_data, _mali_uk_pp_disable_wb_s __user *uargs); -int gp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_gp_start_job_s __user *uargs); -int gp_get_number_of_cores_wrapper(struct mali_session_data *session_data, _mali_uk_get_gp_number_of_cores_s __user *uargs); -int gp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_gp_core_version_s __user *uargs); -int gp_suspend_response_wrapper(struct mali_session_data *session_data, _mali_uk_gp_suspend_response_s __user *uargs); - -int profiling_start_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_start_s __user *uargs); -int profiling_add_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_add_event_s __user *uargs); -int profiling_stop_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_stop_s __user *uargs); -int profiling_get_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_get_event_s __user *uargs); -int profiling_clear_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_clear_s __user *uargs); -int profiling_report_sw_counters_wrapper(struct mali_session_data *session_data, _mali_uk_sw_counters_report_s __user *uargs); - -int vsync_event_report_wrapper(struct mali_session_data *session_data, _mali_uk_vsync_event_report_s __user *uargs); - - -int map_errcode( _mali_osk_errcode_t err ); - -#ifdef __cplusplus -} -#endif - -#endif /* __MALI_UKK_WRAPPERS_H__ */ diff --git a/drivers/media/video/samsung/mali/platform/default/mali_platform.c b/drivers/media/video/samsung/mali/platform/default/mali_platform.c deleted file mode 100644 index d966f25..0000000 --- a/drivers/media/video/samsung/mali/platform/default/mali_platform.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_platform.c - * Platform specific Mali driver functions for a default platform - */ -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "mali_platform.h" - - -_mali_osk_errcode_t mali_platform_init(void) -{ - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_deinit(void) -{ - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode) -{ - MALI_SUCCESS; -} - -void mali_gpu_utilization_handler(u32 utilization) -{ -} - -void set_mali_parent_power_domain(void* dev) -{ -} - - diff --git a/drivers/media/video/samsung/mali/platform/mali_platform.h b/drivers/media/video/samsung/mali/platform/mali_platform.h deleted file mode 100644 index 888f57a..0000000 --- a/drivers/media/video/samsung/mali/platform/mali_platform.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_platform.h - * Platform specific Mali driver functions - */ - -#ifndef __MALI_PLATFORM_H__ -#define __MALI_PLATFORM_H__ - -#include "mali_osk.h" - -#ifdef CONFIG_CPU_EXYNOS4210 -#define MALI_DVFS_STEPS 3 -#else -#define MALI_DVFS_STEPS 5 -#endif - -/* @Enable or Disable Mali GPU Bottom Lock feature */ -#define MALI_GPU_BOTTOM_LOCK 1 - -#define MALI_VOLTAGE_LOCK 1 - -/* @Enable or Disable the CPU frequency lock when the GPU clock is 440 Mhz */ -#define CPUFREQ_LOCK_DURING_440 0 - -#ifdef __cplusplus -extern "C" { -#endif - -/** @brief description of power change reasons - */ -typedef enum mali_power_mode_tag -{ - MALI_POWER_MODE_ON, /**< Power Mali on */ - MALI_POWER_MODE_LIGHT_SLEEP, /**< Mali has been idle for a short time, or runtime PM suspend */ - MALI_POWER_MODE_DEEP_SLEEP, /**< Mali has been idle for a long time, or OS suspend */ -} mali_power_mode; - -/** @brief Platform specific setup and initialisation of MALI - * - * This is called from the entrypoint of the driver to initialize the platform - * - * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. - */ -_mali_osk_errcode_t mali_platform_init(void); - -/** @brief Platform specific deinitialisation of MALI - * - * This is called on the exit of the driver to terminate the platform - * - * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. - */ -_mali_osk_errcode_t mali_platform_deinit(void); - -/** @brief Platform specific powerdown sequence of MALI - * - * Notification from the Mali device driver stating the new desired power mode. - * MALI_POWER_MODE_ON must be obeyed, while the other modes are optional. - * @param power_mode defines the power modes - * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. - */ -_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode); - - -/** @brief Platform specific handling of GPU utilization data - * - * When GPU utilization data is enabled, this function will be - * periodically called. - * - * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization. - */ -void mali_gpu_utilization_handler(u32 utilization); - -/** @brief Setting the power domain of MALI - * - * This function sets the power domain of MALI if Linux run time power management is enabled - * - * @param dev Reference to struct platform_device (defined in linux) used by MALI GPU - */ -//void set_mali_parent_power_domain(void* dev); -void mali_utilization_suspend(void); - -#ifdef CONFIG_REGULATOR -int mali_regulator_get_usecount(void); -void mali_regulator_disable(void); -void mali_regulator_enable(void); -void mali_regulator_set_voltage(int min_uV, int max_uV); -#endif -mali_bool mali_clk_set_rate(unsigned int clk, unsigned int mhz); -unsigned long mali_clk_get_rate(void); -void mali_clk_put(mali_bool binc_mali_clk); - -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON -_mali_osk_errcode_t mali_platform_powerdown(u32 cores); -_mali_osk_errcode_t mali_platform_powerup(u32 cores); -#endif - - -#if USING_MALI_PMM -#if MALI_POWER_MGMT_TEST_SUITE -/** @brief function to get status of individual cores - * - * This function is used by power management test suite to get the status of powered up/down the number - * of cores - * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization. - */ -u32 pmu_get_power_up_down_info(void); -#endif -#endif - -#if MALI_DVFS_ENABLED -mali_bool init_mali_dvfs_status(int step); -void deinit_mali_dvfs_status(void); -mali_bool mali_dvfs_handler(u32 utilization); -int mali_dvfs_is_running(void); -void mali_dvfs_late_resume(void); -int get_mali_dvfs_control_status(void); -mali_bool set_mali_dvfs_current_step(unsigned int step); -void mali_default_step_set(int step, mali_bool boostup); -int change_dvfs_tableset(int change_clk, int change_step); -#ifdef CONFIG_CPU_EXYNOS4210 -#if MALI_GPU_BOTTOM_LOCK -int mali_dvfs_bottom_lock_push(void); -int mali_dvfs_bottom_lock_pop(void); -#endif -#else -int mali_dvfs_bottom_lock_push(int lock_step); -int mali_dvfs_bottom_lock_pop(void); -#endif -#endif - -int mali_dvfs_get_vol(int step); - -#if MALI_VOLTAGE_LOCK -int mali_voltage_lock_push(int lock_vol); -int mali_voltage_lock_pop(void); -int mali_voltage_lock_init(void); -int mali_vol_get_from_table(int vol); -#endif - -#ifdef __cplusplus -} -#endif -#endif diff --git a/drivers/media/video/samsung/mali/platform/mali_platform_pmu_testing/mali_platform.c b/drivers/media/video/samsung/mali/platform/mali_platform_pmu_testing/mali_platform.c deleted file mode 100644 index cb95dc6..0000000 --- a/drivers/media/video/samsung/mali/platform/mali_platform_pmu_testing/mali_platform.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_platform.c - * Platform specific Mali driver functions for a default platform - */ -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "mali_platform.h" -#include "mali_pmu.h" -#include "linux/mali/mali_utgard.h" - -static u32 bPowerOff = 1; - -_mali_osk_errcode_t mali_platform_init(void) -{ - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_deinit(void) -{ - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode) -{ - switch (power_mode) - { - case MALI_POWER_MODE_ON: - if (bPowerOff == 1) - { - mali_pmu_powerup(); - bPowerOff = 0; - } - break; - case MALI_POWER_MODE_LIGHT_SLEEP: - case MALI_POWER_MODE_DEEP_SLEEP: - - if (bPowerOff == 0) - { - mali_pmu_powerdown(); - bPowerOff = 1; - } - - break; - } - MALI_SUCCESS; -} - -void mali_gpu_utilization_handler(u32 utilization) -{ -} - -void set_mali_parent_power_domain(void* dev) -{ -} - - diff --git a/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform.c b/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform.c deleted file mode 100644 index 119831d..0000000 --- a/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform.c +++ /dev/null @@ -1,656 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_platform.c - * Platform specific Mali driver functions for a default platform - */ -#include -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "mali_platform.h" -#include "mali_linux_pm.h" - -#if USING_MALI_PMM -#include "mali_pm.h" -#endif - -#include -#include -#include -#include -#include - -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON -#include -#endif - -#if MALI_TIMELINE_PROFILING_ENABLED -#include "mali_kernel_profiling.h" -#endif - -#include -#include - -#define EXTXTALCLK_NAME "ext_xtal" -#define VPLLSRCCLK_NAME "vpll_src" -#define FOUTVPLLCLK_NAME "fout_vpll" -#define SCLVPLLCLK_NAME "sclk_vpll" -#define GPUMOUT1CLK_NAME "mout_g3d1" - -#define MPLLCLK_NAME "mout_mpll" -#define GPUMOUT0CLK_NAME "mout_g3d0" -#define GPUCLK_NAME "sclk_g3d" -#define CLK_DIV_STAT_G3D 0x1003C62C -#define CLK_DESC "clk-divider-status" - -static struct clk *ext_xtal_clock = 0; -static struct clk *vpll_src_clock = 0; -static struct clk *fout_vpll_clock = 0; -static struct clk *sclk_vpll_clock = 0; - -static struct clk *mpll_clock = 0; -static struct clk *mali_parent_clock = 0; -static struct clk *mali_clock = 0; - -int mali_gpu_clk = 160; -static unsigned int GPU_MHZ = 1000000; -#ifdef CONFIG_S5PV310_ASV -int mali_gpu_vol = 1100000; /* 1.10V for ASV */ -#else -int mali_gpu_vol = 1100000; /* 1.10V */ -#endif - -#if MALI_DVFS_ENABLED -#define MALI_DVFS_DEFAULT_STEP 0 // 134Mhz default -#endif - -int gpu_power_state; -static int bPoweroff; - -#ifdef CONFIG_REGULATOR -struct regulator { - struct device *dev; - struct list_head list; - int uA_load; - int min_uV; - int max_uV; - char *supply_name; - struct device_attribute dev_attr; - struct regulator_dev *rdev; -}; - -struct regulator *g3d_regulator=NULL; -#endif - -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36) -extern struct platform_device s5pv310_device_pd[]; -#else -extern struct platform_device exynos4_device_pd[]; -#endif -#endif - -mali_io_address clk_register_map=0; - -#if MALI_GPU_BOTTOM_LOCK -_mali_osk_lock_t *mali_dvfs_lock; -#else -static _mali_osk_lock_t *mali_dvfs_lock; -#endif - -#ifdef CONFIG_REGULATOR -int mali_regulator_get_usecount(void) -{ - struct regulator_dev *rdev; - - if( IS_ERR_OR_NULL(g3d_regulator) ) - { - MALI_DEBUG_PRINT(1, ("error on mali_regulator_get_usecount : g3d_regulator is null\n")); - return 0; - } - rdev = g3d_regulator->rdev; - return rdev->use_count; -} - -void mali_regulator_disable(void) -{ - bPoweroff = 1; - if( IS_ERR_OR_NULL(g3d_regulator) ) - { - MALI_DEBUG_PRINT(1, ("error on mali_regulator_disable : g3d_regulator is null\n")); - return; - } - regulator_disable(g3d_regulator); - MALI_DEBUG_PRINT(1, ("regulator_disable -> use cnt: %d \n",mali_regulator_get_usecount())); -} - -void mali_regulator_enable(void) -{ - bPoweroff = 0; - if( IS_ERR_OR_NULL(g3d_regulator) ) - { - MALI_DEBUG_PRINT(1, ("error on mali_regulator_enable : g3d_regulator is null\n")); - return; - } - regulator_enable(g3d_regulator); - MALI_DEBUG_PRINT(1, ("regulator_enable -> use cnt: %d \n",mali_regulator_get_usecount())); -} - -void mali_regulator_set_voltage(int min_uV, int max_uV) -{ - int voltage; - - _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); - - if( IS_ERR_OR_NULL(g3d_regulator) ) - { - MALI_DEBUG_PRINT(1, ("error on mali_regulator_set_voltage : g3d_regulator is null\n")); - return; - } - MALI_DEBUG_PRINT(2, ("= regulator_set_voltage: %d, %d \n",min_uV, max_uV)); - -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE | - MALI_PROFILING_EVENT_CHANNEL_SOFTWARE | - MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_VOLTS, - min_uV, max_uV, 0, 0, 0); -#endif - - regulator_set_voltage(g3d_regulator,min_uV,max_uV); - voltage = regulator_get_voltage(g3d_regulator); - -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE | - MALI_PROFILING_EVENT_CHANNEL_SOFTWARE | - MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_VOLTS, - voltage, 0, 1, 0, 0); -#endif - mali_gpu_vol = voltage; - MALI_DEBUG_PRINT(1, ("= regulator_get_voltage: %d \n",mali_gpu_vol)); - - _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); -} -#endif - -unsigned long mali_clk_get_rate(void) -{ - return clk_get_rate(mali_clock); -} - -mali_bool mali_clk_get(mali_bool bis_vpll) -{ - if (bis_vpll == MALI_TRUE) - { - if (ext_xtal_clock == NULL) - { - ext_xtal_clock = clk_get(NULL,EXTXTALCLK_NAME); - if (IS_ERR(ext_xtal_clock)) { - MALI_PRINT( ("MALI Error : failed to get source ext_xtal_clock\n")); - return MALI_FALSE; - } - } - - if (vpll_src_clock == NULL) - { - vpll_src_clock = clk_get(NULL,VPLLSRCCLK_NAME); - if (IS_ERR(vpll_src_clock)) { - MALI_PRINT( ("MALI Error : failed to get source vpll_src_clock\n")); - return MALI_FALSE; - } - } - - if (fout_vpll_clock == NULL) - { - fout_vpll_clock = clk_get(NULL,FOUTVPLLCLK_NAME); - if (IS_ERR(fout_vpll_clock)) { - MALI_PRINT( ("MALI Error : failed to get source fout_vpll_clock\n")); - return MALI_FALSE; - } - } - - if (sclk_vpll_clock == NULL) - { - sclk_vpll_clock = clk_get(NULL,SCLVPLLCLK_NAME); - if (IS_ERR(sclk_vpll_clock)) { - MALI_PRINT( ("MALI Error : failed to get source sclk_vpll_clock\n")); - return MALI_FALSE; - } - } - - if (mali_parent_clock == NULL) - { - mali_parent_clock = clk_get(NULL, GPUMOUT1CLK_NAME); - - if (IS_ERR(mali_parent_clock)) { - MALI_PRINT( ( "MALI Error : failed to get source mali parent clock\n")); - return MALI_FALSE; - } - } - } - else // mpll - { - if (mpll_clock == NULL) - { - mpll_clock = clk_get(NULL,MPLLCLK_NAME); - - if (IS_ERR(mpll_clock)) { - MALI_PRINT( ("MALI Error : failed to get source mpll clock\n")); - return MALI_FALSE; - } - } - - if (mali_parent_clock == NULL) - { - mali_parent_clock = clk_get(NULL, GPUMOUT0CLK_NAME); - - if (IS_ERR(mali_parent_clock)) { - MALI_PRINT( ( "MALI Error : failed to get source mali parent clock\n")); - return MALI_FALSE; - } - } - } - - // mali clock get always. - if (mali_clock == NULL) - { - mali_clock = clk_get(NULL, GPUCLK_NAME); - - if (IS_ERR(mali_clock)) { - MALI_PRINT( ("MALI Error : failed to get source mali clock\n")); - return MALI_FALSE; - } - } - - return MALI_TRUE; -} - -void mali_clk_put(mali_bool binc_mali_clock) -{ - if (mali_parent_clock) - { - clk_put(mali_parent_clock); - mali_parent_clock = 0; - } - - if (mpll_clock) - { - clk_put(mpll_clock); - mpll_clock = 0; - } - - if (sclk_vpll_clock) - { - clk_put(sclk_vpll_clock); - sclk_vpll_clock = 0; - } - - if (fout_vpll_clock) - { - clk_put(fout_vpll_clock); - fout_vpll_clock = 0; - } - - if (vpll_src_clock) - { - clk_put(vpll_src_clock); - vpll_src_clock = 0; - } - - if (ext_xtal_clock) - { - clk_put(ext_xtal_clock); - ext_xtal_clock = 0; - } - - if (binc_mali_clock == MALI_TRUE && mali_clock) - { - clk_put(mali_clock); - mali_clock = 0; - } - -} - - -mali_bool mali_clk_set_rate(unsigned int clk, unsigned int mhz) -{ - unsigned long rate = 0; - mali_bool bis_vpll = MALI_FALSE; - -#ifdef CONFIG_VPLL_USE_FOR_TVENC - bis_vpll = MALI_TRUE; -#endif - - _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); - - if (mali_clk_get(bis_vpll) == MALI_FALSE) - return MALI_FALSE; - - rate = (unsigned long)clk * (unsigned long)mhz; - MALI_DEBUG_PRINT(3,("= clk_set_rate : %d , %d \n",clk, mhz )); - - if (bis_vpll) - { - clk_set_rate(fout_vpll_clock, (unsigned int)clk * GPU_MHZ); - clk_set_parent(vpll_src_clock, ext_xtal_clock); - clk_set_parent(sclk_vpll_clock, fout_vpll_clock); - - clk_set_parent(mali_parent_clock, sclk_vpll_clock); - clk_set_parent(mali_clock, mali_parent_clock); - } - else - { - clk_set_parent(mali_parent_clock, mpll_clock); - clk_set_parent(mali_clock, mali_parent_clock); - } - - if (clk_enable(mali_clock) < 0) - return MALI_FALSE; - -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE | - MALI_PROFILING_EVENT_CHANNEL_SOFTWARE | - MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_FREQ, - rate, 0, 0, 0, 0); -#endif - - clk_set_rate(mali_clock, rate); - rate = clk_get_rate(mali_clock); - -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE | - MALI_PROFILING_EVENT_CHANNEL_SOFTWARE | - MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_FREQ, - rate, 0, 0, 0, 0); -#endif - - if (bis_vpll) - mali_gpu_clk = (int)(rate / mhz); - else - mali_gpu_clk = (int)((rate + 500000) / mhz); - - GPU_MHZ = mhz; - MALI_DEBUG_PRINT(3,("= clk_get_rate: %d \n",mali_gpu_clk)); - - mali_clk_put(MALI_FALSE); - - _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); - - return MALI_TRUE; -} - -static mali_bool init_mali_clock(void) -{ - mali_bool ret = MALI_TRUE; - - gpu_power_state = 0; - - if (mali_clock != 0) - return ret; // already initialized - - mali_dvfs_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE - | _MALI_OSK_LOCKFLAG_ONELOCK, 0, 0); - if (mali_dvfs_lock == NULL) - return _MALI_OSK_ERR_FAULT; - - if (mali_clk_set_rate(mali_gpu_clk, GPU_MHZ) == MALI_FALSE) - { - ret = MALI_FALSE; - goto err_clock_get; - } - - MALI_PRINT(("init_mali_clock mali_clock %p \n", mali_clock)); - - -#ifdef CONFIG_REGULATOR -#if USING_MALI_PMM - g3d_regulator = regulator_get(&mali_gpu_device.dev, "vdd_g3d"); -#else - g3d_regulator = regulator_get(NULL, "vdd_g3d"); -#endif - - if (IS_ERR(g3d_regulator)) - { - MALI_PRINT( ("MALI Error : failed to get vdd_g3d\n")); - ret = MALI_FALSE; - goto err_regulator; - } - - regulator_enable(g3d_regulator); - MALI_DEBUG_PRINT(1, ("= regulator_enable -> use cnt: %d \n",mali_regulator_get_usecount())); - mali_regulator_set_voltage(mali_gpu_vol, mali_gpu_vol); -#endif - - MALI_DEBUG_PRINT(2, ("MALI Clock is set at mali driver\n")); - MALI_DEBUG_PRINT(3,("::clk_put:: %s mali_parent_clock - normal\n", __FUNCTION__)); - MALI_DEBUG_PRINT(3,("::clk_put:: %s mpll_clock - normal\n", __FUNCTION__)); - - mali_clk_put(MALI_FALSE); - - return MALI_TRUE; - - -#ifdef CONFIG_REGULATOR -err_regulator: - regulator_put(g3d_regulator); -#endif - -err_clock_get: - mali_clk_put(MALI_TRUE); - - return ret; -} - -static mali_bool deinit_mali_clock(void) -{ - if (mali_clock == 0) - return MALI_TRUE; - -#ifdef CONFIG_REGULATOR - if (g3d_regulator) - { - regulator_put(g3d_regulator); - g3d_regulator=NULL; - } -#endif - - mali_clk_put(MALI_TRUE); - - return MALI_TRUE; -} - - -static _mali_osk_errcode_t enable_mali_clocks(void) -{ - int err; - err = clk_enable(mali_clock); - MALI_DEBUG_PRINT(3,("enable_mali_clocks mali_clock %p error %d \n", mali_clock, err)); - - // set clock rate - mali_clk_set_rate(mali_gpu_clk, GPU_MHZ); - - MALI_SUCCESS; -} - -static _mali_osk_errcode_t disable_mali_clocks(void) -{ - clk_disable(mali_clock); - MALI_DEBUG_PRINT(3,("disable_mali_clocks mali_clock %p \n", mali_clock)); - - MALI_SUCCESS; -} - -void set_mali_parent_power_domain(struct platform_device* dev) -{ -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36) - dev->dev.parent = &s5pv310_device_pd[PD_G3D].dev; -#else - dev->dev.parent = &exynos4_device_pd[PD_G3D].dev; -#endif - -#endif -} - -_mali_osk_errcode_t g3d_power_domain_control(int bpower_on) -{ - if (bpower_on) - { -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON - MALI_DEBUG_PRINT(3,("_mali_osk_pm_dev_activate \n")); - _mali_osk_pm_dev_activate(); -#else //MALI_PMM_RUNTIME_JOB_CONTROL_ON - void __iomem *status; - u32 timeout; - __raw_writel(S5P_INT_LOCAL_PWR_EN, S5P_PMU_G3D_CONF); - status = S5P_PMU_G3D_CONF + 0x4; - - timeout = 10; - while ((__raw_readl(status) & S5P_INT_LOCAL_PWR_EN) - != S5P_INT_LOCAL_PWR_EN) { - if (timeout == 0) { - MALI_PRINTF(("Power domain enable failed.\n")); - return -ETIMEDOUT; - } - timeout--; - _mali_osk_time_ubusydelay(100); - } -#endif //MALI_PMM_RUNTIME_JOB_CONTROL_ON - } - else - { -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON - MALI_DEBUG_PRINT( 4,("_mali_osk_pm_dev_idle\n")); - _mali_osk_pm_dev_idle(); - -#else //MALI_PMM_RUNTIME_JOB_CONTROL_ON - void __iomem *status; - u32 timeout; - __raw_writel(0, S5P_PMU_G3D_CONF); - - status = S5P_PMU_G3D_CONF + 0x4; - /* Wait max 1ms */ - timeout = 10; - while (__raw_readl(status) & S5P_INT_LOCAL_PWR_EN) - { - if (timeout == 0) { - MALI_PRINTF(("Power domain disable failed.\n" )); - return -ETIMEDOUT; - } - timeout--; - _mali_osk_time_ubusydelay( 100); - } -#endif //MALI_PMM_RUNTIME_JOB_CONTROL_ON - } - - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_init() -{ - MALI_CHECK(init_mali_clock(), _MALI_OSK_ERR_FAULT); -#if MALI_DVFS_ENABLED - if (!clk_register_map) clk_register_map = _mali_osk_mem_mapioregion( CLK_DIV_STAT_G3D, 0x20, CLK_DESC ); - if(!init_mali_dvfs_status(MALI_DVFS_DEFAULT_STEP)) - MALI_DEBUG_PRINT(1, ("mali_platform_init failed\n")); -#endif - - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_deinit() -{ - deinit_mali_clock(); - -#if MALI_DVFS_ENABLED - deinit_mali_dvfs_status(); - if (clk_register_map ) - { - _mali_osk_mem_unmapioregion(CLK_DIV_STAT_G3D, 0x20, clk_register_map); - clk_register_map=0; - } -#endif - - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_powerdown(u32 cores) -{ - MALI_DEBUG_PRINT(3,("power down is called in mali_platform_powerdown state %x core %x \n", gpu_power_state, cores)); - - if (gpu_power_state != 0) // power down after state is 0 - { - gpu_power_state = gpu_power_state & (~cores); - if (gpu_power_state == 0) - { - MALI_DEBUG_PRINT( 3,("disable clock\n")); - disable_mali_clocks(); - } - } - else - { - MALI_PRINT(("mali_platform_powerdown gpu_power_state == 0 and cores %x \n", cores)); - } - - bPoweroff=1; - - - - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_powerup(u32 cores) -{ - MALI_DEBUG_PRINT(3,("power up is called in mali_platform_powerup state %x core %x \n", gpu_power_state, cores)); - - if (gpu_power_state == 0) // power up only before state is 0 - { - gpu_power_state = gpu_power_state | cores; - - if (gpu_power_state != 0) - { - MALI_DEBUG_PRINT(4,("enable clock \n")); - enable_mali_clocks(); - } - } - else - { - gpu_power_state = gpu_power_state | cores; - } - - bPoweroff=0; - - - MALI_SUCCESS; -} - -void mali_gpu_utilization_handler(u32 utilization) -{ - if (bPoweroff==0) - { -#if MALI_DVFS_ENABLED - if(!mali_dvfs_handler(utilization)) - MALI_DEBUG_PRINT(1,( "error on mali dvfs status in utilization\n")); -#endif - } -} - -#if MALI_POWER_MGMT_TEST_SUITE -u32 pmu_get_power_up_down_info(void) -{ - return 4095; -} - -#endif -_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode) -{ - MALI_SUCCESS; -} - diff --git a/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c b/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c deleted file mode 100644 index 4efa759..0000000 --- a/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c +++ /dev/null @@ -1,448 +0,0 @@ -/* * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_platform_dvfs.c - * Platform specific Mali driver dvfs functions - */ - -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "mali_platform.h" - -#include -#include -#include -#include - -#include - -#ifdef CONFIG_CPU_FREQ -#include -#include -#define EXYNOS4_ASV_ENABLED -#endif - -#include "mali_device_pause_resume.h" -#include - -#define MALI_DVFS_WATING 10 // msec - -static int bMaliDvfsRun=0; - -#if MALI_GPU_BOTTOM_LOCK -static _mali_osk_atomic_t bottomlock_status; -#endif - -typedef struct mali_dvfs_tableTag{ - unsigned int clock; - unsigned int freq; - unsigned int vol; -}mali_dvfs_table; - -typedef struct mali_dvfs_statusTag{ - unsigned int currentStep; - mali_dvfs_table * pCurrentDvfs; - -}mali_dvfs_currentstatus; - -typedef struct mali_dvfs_thresholdTag{ - unsigned int downthreshold; - unsigned int upthreshold; -}mali_dvfs_threshold_table; - -typedef struct mali_dvfs_staycount{ - unsigned int staycount; -}mali_dvfs_staycount_table; - -mali_dvfs_staycount_table mali_dvfs_staycount[MALI_DVFS_STEPS]={ - /*step 0*/{1}, - /*step 1*/{1}, - /*step 2*/{1} }; - -/*dvfs threshold*/ -mali_dvfs_threshold_table mali_dvfs_threshold[MALI_DVFS_STEPS]={ - /*step 0*/{((int)((255*0)/100)) ,((int)((255*85)/100))}, - /*step 1*/{((int)((255*75)/100)) ,((int)((255*85)/100))}, - /*step 2*/{((int)((255*75)/100)) ,((int)((255*100)/100))} }; - -/*dvfs status*/ -mali_dvfs_currentstatus maliDvfsStatus; -int mali_dvfs_control=0; - -/*dvfs table*/ -mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={ -#ifdef CONFIG_EXYNOS4210_1400MHZ_SUPPORT - /*step 0*/{134 ,1000000 , 950000}, -#else - /*step 0*/{100 ,1000000 , 950000}, -#endif - /*step 1*/{160 ,1000000 , 950000}, - /*step 2*/{267 ,1000000 ,1000000} }; - -#ifdef EXYNOS4_ASV_ENABLED - -#define ASV_8_LEVEL 8 -#define ASV_5_LEVEL 5 - -static unsigned int asv_3d_volt_5_table[ASV_5_LEVEL][MALI_DVFS_STEPS] = { - /* L3 (100/134MHz) L2(160MHz), L1(267MHz) */ - {1000000, 1000000, 1100000}, /* S */ - {1000000, 1000000, 1100000}, /* A */ - { 950000, 950000, 1000000}, /* B */ - { 950000, 950000, 1000000}, /* C */ - { 950000, 950000, 950000}, /* D */ -}; - -static unsigned int asv_3d_volt_8_table[ASV_8_LEVEL][MALI_DVFS_STEPS] = { - /* L3 (100/134MHz) L2(160MHz), L1(267MHz) */ - {1000000, 1000000, 1100000}, /* SS */ - {1000000, 1000000, 1100000}, /* A1 */ - {1000000, 1000000, 1100000}, /* A2 */ - { 950000, 950000, 1000000}, /* B1 */ - { 950000, 950000, 1000000}, /* B2 */ - { 950000, 950000, 1000000}, /* C1 */ - { 950000, 950000, 1000000}, /* C2 */ - { 950000, 950000, 950000}, /* D1 */ -}; -#endif - -static u32 mali_dvfs_utilization = 255; - -static void mali_dvfs_work_handler(struct work_struct *w); - -static struct workqueue_struct *mali_dvfs_wq = 0; -extern mali_io_address clk_register_map; - -#if MALI_GPU_BOTTOM_LOCK -extern _mali_osk_lock_t *mali_dvfs_lock; -#endif - -static DECLARE_WORK(mali_dvfs_work, mali_dvfs_work_handler); - -static unsigned int get_mali_dvfs_status(void) -{ - return maliDvfsStatus.currentStep; -} - -#if MALI_GPU_BOTTOM_LOCK -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON -int get_mali_dvfs_control_status(void) -{ - return mali_dvfs_control; -} - -mali_bool set_mali_dvfs_current_step(unsigned int step) -{ - _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); - maliDvfsStatus.currentStep = step; - _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); - return MALI_TRUE; -} -#endif -#endif - -static mali_bool set_mali_dvfs_status(u32 step,mali_bool boostup) -{ - u32 validatedStep=step; - -#ifdef CONFIG_REGULATOR - if (mali_regulator_get_usecount()==0) { - MALI_DEBUG_PRINT(1, ("regulator use_count is 0 \n")); - return MALI_FALSE; - } -#endif - - if (boostup) { -#ifdef CONFIG_REGULATOR - /*change the voltage*/ - mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol); -#endif - /*change the clock*/ - mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq); - } else { - /*change the clock*/ - mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq); -#ifdef CONFIG_REGULATOR - /*change the voltage*/ - mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol); -#endif - } - - maliDvfsStatus.currentStep = validatedStep; - /*for future use*/ - maliDvfsStatus.pCurrentDvfs = &mali_dvfs[validatedStep]; - - return MALI_TRUE; -} - -static void mali_platform_wating(u32 msec) -{ - /*sample wating - change this in the future with proper check routine. - */ - unsigned int read_val; - while(1) { - read_val = _mali_osk_mem_ioread32(clk_register_map, 0x00); - if ((read_val & 0x8000)==0x0000) break; - - _mali_osk_time_ubusydelay(100); // 1000 -> 100 : 20101218 - } - /* _mali_osk_time_ubusydelay(msec*1000);*/ -} - -static mali_bool change_mali_dvfs_status(u32 step, mali_bool boostup ) -{ - - MALI_DEBUG_PRINT(1, ("> change_mali_dvfs_status: %d, %d \n",step, boostup)); - - if (!set_mali_dvfs_status(step, boostup)) { - MALI_DEBUG_PRINT(1, ("error on set_mali_dvfs_status: %d, %d \n",step, boostup)); - return MALI_FALSE; - } - - /*wait until clock and voltage is stablized*/ - mali_platform_wating(MALI_DVFS_WATING); /*msec*/ - - return MALI_TRUE; -} - -static unsigned int decideNextStatus(unsigned int utilization) -{ - unsigned int level=0; // 0:stay, 1:up - - if (!mali_dvfs_control) { -#if MALI_GPU_BOTTOM_LOCK - if (_mali_osk_atomic_read(&bottomlock_status) > 0) - level = 1; /* or bigger */ - else -#endif - switch(maliDvfsStatus.currentStep) - { - case 0: - if( utilization > mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold) - level=1; - else - level = maliDvfsStatus.currentStep; - break; - case 1: - if( utilization > mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold) - level=2; - else if( utilization < - (mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold*mali_dvfs[maliDvfsStatus.currentStep-1].clock)/ - mali_dvfs[maliDvfsStatus.currentStep].clock) - level=0; - else - level = maliDvfsStatus.currentStep; - break; - case 2: - if( utilization < - (mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold*mali_dvfs[maliDvfsStatus.currentStep-1].clock)/ - mali_dvfs[maliDvfsStatus.currentStep].clock) - level=1; - else - level = maliDvfsStatus.currentStep; - break; - } - } - else - { - if((mali_dvfs_control == 1)||(( mali_dvfs_control > 3) && (mali_dvfs_control < mali_dvfs[0].clock+1))) - { - level=0; - } - else if((mali_dvfs_control == 2)||(( mali_dvfs_control > mali_dvfs[0].clock) && (mali_dvfs_control < mali_dvfs[1].clock+1))) - { - level=1; - } - else - { - level=2; - } - } - - return level; -} - -#ifdef EXYNOS4_ASV_ENABLED -static mali_bool mali_dvfs_table_update(void) -{ - unsigned int exynos_result_of_asv_group; - unsigned int target_asv; - unsigned int i; - exynos_result_of_asv_group = exynos_result_of_asv & 0xf; - target_asv = exynos_result_of_asv >> 28; - MALI_PRINT(("exynos_result_of_asv_group = 0x%x, target_asv = 0x%x\n", exynos_result_of_asv_group, target_asv)); - - if (target_asv == 0x8) { //SUPPORT_1400MHZ - for (i = 0; i < MALI_DVFS_STEPS; i++) { - mali_dvfs[i].vol = asv_3d_volt_5_table[exynos_result_of_asv_group][i]; - MALI_PRINT(("mali_dvfs[%d].vol = %d\n", i, mali_dvfs[i].vol)); - } - } else if (target_asv == 0x4){ //SUPPORT_1200MHZ - for (i = 0; i < MALI_DVFS_STEPS; i++) { - mali_dvfs[i].vol = asv_3d_volt_8_table[exynos_result_of_asv_group][i]; - MALI_PRINT(("mali_dvfs[%d].vol = %d\n", i, mali_dvfs[i].vol)); - } - } - - return MALI_TRUE; - -} -#endif - -static mali_bool mali_dvfs_status(u32 utilization) -{ - unsigned int nextStatus = 0; - unsigned int curStatus = 0; - mali_bool boostup = MALI_FALSE; -#ifdef EXYNOS4_ASV_ENABLED - static mali_bool asv_applied = MALI_FALSE; -#endif - static int stay_count = 0; // to prevent frequent switch - - MALI_DEBUG_PRINT(1, ("> mali_dvfs_status: %d \n",utilization)); -#ifdef EXYNOS4_ASV_ENABLED - if (asv_applied == MALI_FALSE) { - mali_dvfs_table_update(); - change_mali_dvfs_status(0,0); - asv_applied = MALI_TRUE; - - return MALI_TRUE; - } -#endif - - /*decide next step*/ - curStatus = get_mali_dvfs_status(); - nextStatus = decideNextStatus(utilization); - - MALI_DEBUG_PRINT(1, ("= curStatus %d, nextStatus %d, maliDvfsStatus.currentStep %d \n", curStatus, nextStatus, maliDvfsStatus.currentStep)); - - /*if next status is same with current status, don't change anything*/ - if ((curStatus!=nextStatus && stay_count==0)) { - /*check if boost up or not*/ - if (nextStatus > maliDvfsStatus.currentStep) - boostup = 1; - - /*change mali dvfs status*/ - if (!change_mali_dvfs_status(nextStatus,boostup)) { - MALI_DEBUG_PRINT(1, ("error on change_mali_dvfs_status \n")); - return MALI_FALSE; - } - stay_count = mali_dvfs_staycount[maliDvfsStatus.currentStep].staycount; - } else { - if (stay_count>0) - stay_count--; - } - - return MALI_TRUE; -} - - - -int mali_dvfs_is_running(void) -{ - return bMaliDvfsRun; -} - - - -void mali_dvfs_late_resume(void) -{ - // set the init clock as low when resume - set_mali_dvfs_status(0,0); -} - - -static void mali_dvfs_work_handler(struct work_struct *w) -{ - bMaliDvfsRun=1; - - MALI_DEBUG_PRINT(3, ("=== mali_dvfs_work_handler\n")); - - if (!mali_dvfs_status(mali_dvfs_utilization)) - MALI_DEBUG_PRINT(1,( "error on mali dvfs status in mali_dvfs_work_handler")); - - bMaliDvfsRun=0; -} - - -mali_bool init_mali_dvfs_status(int step) -{ - /*default status - add here with the right function to get initilization value. - */ - if (!mali_dvfs_wq) - mali_dvfs_wq = create_singlethread_workqueue("mali_dvfs"); - -#if MALI_GPU_BOTTOM_LOCK - _mali_osk_atomic_init(&bottomlock_status, 0); -#endif - - /*add a error handling here*/ - maliDvfsStatus.currentStep = step; - - return MALI_TRUE; -} - -void deinit_mali_dvfs_status(void) -{ -#if MALI_GPU_BOTTOM_LOCK - _mali_osk_atomic_term(&bottomlock_status); -#endif - - if (mali_dvfs_wq) - destroy_workqueue(mali_dvfs_wq); - mali_dvfs_wq = NULL; -} - -mali_bool mali_dvfs_handler(u32 utilization) -{ - mali_dvfs_utilization = utilization; - queue_work_on(0, mali_dvfs_wq,&mali_dvfs_work); - - /*add error handle here*/ - return MALI_TRUE; -} - -void mali_default_step_set(int step, mali_bool boostup) -{ - mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq); - - if (maliDvfsStatus.currentStep == 1) - set_mali_dvfs_status(step, boostup); -} - -#if MALI_GPU_BOTTOM_LOCK -int mali_dvfs_bottom_lock_push(void) -{ - int prev_status = _mali_osk_atomic_read(&bottomlock_status); - - if (prev_status < 0) { - MALI_PRINT(("gpu bottom lock status is not valid for push")); - return -1; - } - - if (prev_status == 0) { - mali_regulator_set_voltage(mali_dvfs[1].vol, mali_dvfs[1].vol); - mali_clk_set_rate(mali_dvfs[1].clock, mali_dvfs[1].freq); - set_mali_dvfs_current_step(1); - } - - return _mali_osk_atomic_inc_return(&bottomlock_status); -} - -int mali_dvfs_bottom_lock_pop(void) -{ - if (_mali_osk_atomic_read(&bottomlock_status) <= 0) { - MALI_PRINT(("gpu bottom lock status is not valid for pop")); - return -1; - } - - return _mali_osk_atomic_dec_return(&bottomlock_status); -} -#endif diff --git a/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c b/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c deleted file mode 100644 index a08bc97..0000000 --- a/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c +++ /dev/null @@ -1,801 +0,0 @@ -/* Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_platform.c - * Platform specific Mali driver functions for a default platform - */ -#include -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "mali_platform.h" -#include "mali_linux_pm.h" - -#if USING_MALI_PMM -#include "mali_pm.h" -#endif - -#include -#include -#include -#include -#include - -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON -#include -#endif - -#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED -#include "mali_osk_profiling.h" -unsigned long gFreq = 366; -int gVolt = 5000; -#endif - -#include -#include - -#define EXTXTALCLK_NAME "ext_xtal" -#define VPLLSRCCLK_NAME "vpll_src" -#define FOUTVPLLCLK_NAME "fout_vpll" -#define SCLVPLLCLK_NAME "sclk_vpll" -#define GPUMOUT1CLK_NAME "mout_g3d1" - -#define MPLLCLK_NAME "mout_mpll" -#define GPUMOUT0CLK_NAME "mout_g3d0" -#define GPUCLK_NAME "sclk_g3d" -#define CLK_DIV_STAT_G3D 0x1003C62C -#define CLK_DESC "clk-divider-status" - -#define MALI_BOTTOMLOCK_VOL 900000 - -typedef struct mali_runtime_resumeTag{ - int clk; - int vol; -}mali_runtime_resume_table; - -mali_runtime_resume_table mali_runtime_resume = {266, 900000}; - -/* lock/unlock CPU freq by Mali */ -extern int cpufreq_lock_by_mali(unsigned int freq); -extern void cpufreq_unlock_by_mali(void); - -/* start of modification by skkim */ -extern mali_bool init_mali_dvfs_status(int step); -extern void deinit_mali_dvfs_status(void); -extern mali_bool mali_dvfs_handler(u32 utilization); -extern int get_mali_dvfs_control_status(void); -extern mali_bool set_mali_dvfs_current_step(unsigned int step); -/* end of modification by skkim */ - -static struct clk *ext_xtal_clock = 0; -static struct clk *vpll_src_clock = 0; -static struct clk *fout_vpll_clock = 0; -static struct clk *sclk_vpll_clock = 0; - -static struct clk *mpll_clock = 0; -static struct clk *mali_parent_clock = 0; -static struct clk *mali_clock = 0; - - -static unsigned int GPU_MHZ = 1000000; - -int mali_gpu_clk = 266; -int mali_gpu_vol = 900000; - -#if MALI_DVFS_ENABLED -#define MALI_DVFS_DEFAULT_STEP 1 -#endif -#if MALI_VOLTAGE_LOCK -int mali_lock_vol = 0; -static _mali_osk_atomic_t voltage_lock_status; -static mali_bool mali_vol_lock_flag = 0; -#endif - -int gpu_power_state; -static int bPoweroff; - -#ifdef CONFIG_REGULATOR -struct regulator { - struct device *dev; - struct list_head list; - int uA_load; - int min_uV; - int max_uV; - char *supply_name; - struct device_attribute dev_attr; - struct regulator_dev *rdev; -}; - -struct regulator *g3d_regulator=NULL; -#endif - -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36) -extern struct platform_device s5pv310_device_pd[]; -#else -extern struct platform_device exynos4_device_pd[]; -#endif -#endif - -mali_io_address clk_register_map=0; - -_mali_osk_lock_t *mali_dvfs_lock = 0; - -#ifdef CONFIG_REGULATOR -int mali_regulator_get_usecount(void) -{ - struct regulator_dev *rdev; - - if( IS_ERR_OR_NULL(g3d_regulator) ) - { - MALI_DEBUG_PRINT(1, ("error on mali_regulator_get_usecount : g3d_regulator is null\n")); - return 0; - } - rdev = g3d_regulator->rdev; - return rdev->use_count; -} - -void mali_regulator_disable(void) -{ - if( IS_ERR_OR_NULL(g3d_regulator) ) - { - MALI_DEBUG_PRINT(1, ("error on mali_regulator_disable : g3d_regulator is null\n")); - return; - } - regulator_disable(g3d_regulator); - MALI_DEBUG_PRINT(1, ("regulator_disable -> use cnt: %d \n",mali_regulator_get_usecount())); - bPoweroff = 1; -} - -void mali_regulator_enable(void) -{ - if( IS_ERR_OR_NULL(g3d_regulator) ) - { - MALI_DEBUG_PRINT(1, ("error on mali_regulator_enable : g3d_regulator is null\n")); - return; - } - regulator_enable(g3d_regulator); - MALI_DEBUG_PRINT(1, ("regulator_enable -> use cnt: %d \n",mali_regulator_get_usecount())); - bPoweroff = 0; -} - -void mali_regulator_set_voltage(int min_uV, int max_uV) -{ - int voltage; -#if !MALI_DVFS_ENABLED - min_uV = mali_gpu_vol; - max_uV = mali_gpu_vol; -#endif -#if MALI_VOLTAGE_LOCK - if (mali_vol_lock_flag == MALI_FALSE) { - if (min_uV < MALI_BOTTOMLOCK_VOL || max_uV < MALI_BOTTOMLOCK_VOL) { - min_uV = MALI_BOTTOMLOCK_VOL; - max_uV = MALI_BOTTOMLOCK_VOL; - } - } else if (_mali_osk_atomic_read(&voltage_lock_status) > 0 ) { - if (min_uV < mali_lock_vol || max_uV < mali_lock_vol) { -#if MALI_DVFS_ENABLED - int mali_vol_get; - mali_vol_get = mali_vol_get_from_table(mali_lock_vol); - if (mali_vol_get) { - min_uV = mali_vol_get; - max_uV = mali_vol_get; - } -#else - min_uV = mali_lock_vol; - max_uV = mali_lock_vol; -#endif - } - } -#endif - - _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); - - if( IS_ERR_OR_NULL(g3d_regulator) ) - { - MALI_DEBUG_PRINT(1, ("error on mali_regulator_set_voltage : g3d_regulator is null\n")); - return; - } - - MALI_DEBUG_PRINT(2, ("= regulator_set_voltage: %d, %d \n",min_uV, max_uV)); - - regulator_set_voltage(g3d_regulator,min_uV,max_uV); - voltage = regulator_get_voltage(g3d_regulator); - -#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED - gVolt = voltage/1000; - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | - MALI_PROFILING_EVENT_CHANNEL_GPU | - MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, gFreq, gVolt, - 0, 0, 0); -#endif - - mali_gpu_vol = voltage; - MALI_DEBUG_PRINT(1, ("= regulator_get_voltage: %d \n",mali_gpu_vol)); - - _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); -} -#endif - -unsigned long mali_clk_get_rate(void) -{ - return clk_get_rate(mali_clock); -} - -mali_bool mali_clk_get(mali_bool bis_vpll) -{ - if (bis_vpll == MALI_TRUE) - { - if (ext_xtal_clock == NULL) - { - ext_xtal_clock = clk_get(NULL,EXTXTALCLK_NAME); - if (IS_ERR(ext_xtal_clock)) { - MALI_PRINT( ("MALI Error : failed to get source ext_xtal_clock\n")); - return MALI_FALSE; - } - } - - if (vpll_src_clock == NULL) - { - vpll_src_clock = clk_get(NULL,VPLLSRCCLK_NAME); - if (IS_ERR(vpll_src_clock)) { - MALI_PRINT( ("MALI Error : failed to get source vpll_src_clock\n")); - return MALI_FALSE; - } - } - - if (fout_vpll_clock == NULL) - { - fout_vpll_clock = clk_get(NULL,FOUTVPLLCLK_NAME); - if (IS_ERR(fout_vpll_clock)) { - MALI_PRINT( ("MALI Error : failed to get source fout_vpll_clock\n")); - return MALI_FALSE; - } - } - - if (sclk_vpll_clock == NULL) - { - sclk_vpll_clock = clk_get(NULL,SCLVPLLCLK_NAME); - if (IS_ERR(sclk_vpll_clock)) { - MALI_PRINT( ("MALI Error : failed to get source sclk_vpll_clock\n")); - return MALI_FALSE; - } - } - - if (mali_parent_clock == NULL) - { - mali_parent_clock = clk_get(NULL, GPUMOUT1CLK_NAME); - - if (IS_ERR(mali_parent_clock)) { - MALI_PRINT( ( "MALI Error : failed to get source mali parent clock\n")); - return MALI_FALSE; - } - } - } - else // mpll - { - if (mpll_clock == NULL) - { - mpll_clock = clk_get(NULL,MPLLCLK_NAME); - - if (IS_ERR(mpll_clock)) { - MALI_PRINT( ("MALI Error : failed to get source mpll clock\n")); - return MALI_FALSE; - } - } - - if (mali_parent_clock == NULL) - { - mali_parent_clock = clk_get(NULL, GPUMOUT0CLK_NAME); - - if (IS_ERR(mali_parent_clock)) { - MALI_PRINT( ( "MALI Error : failed to get source mali parent clock\n")); - return MALI_FALSE; - } - } - } - - // mali clock get always. - if (mali_clock == NULL) - { - mali_clock = clk_get(NULL, GPUCLK_NAME); - - if (IS_ERR(mali_clock)) { - MALI_PRINT( ("MALI Error : failed to get source mali clock\n")); - return MALI_FALSE; - } - } - - return MALI_TRUE; -} - -void mali_clk_put(mali_bool binc_mali_clock) -{ - if (mali_parent_clock) - { - clk_put(mali_parent_clock); - mali_parent_clock = 0; - } - - if (mpll_clock) - { - clk_put(mpll_clock); - mpll_clock = 0; - } - - if (sclk_vpll_clock) - { - clk_put(sclk_vpll_clock); - sclk_vpll_clock = 0; - } - - if (fout_vpll_clock) - { - clk_put(fout_vpll_clock); - fout_vpll_clock = 0; - } - - if (vpll_src_clock) - { - clk_put(vpll_src_clock); - vpll_src_clock = 0; - } - - if (ext_xtal_clock) - { - clk_put(ext_xtal_clock); - ext_xtal_clock = 0; - } - - if (binc_mali_clock == MALI_TRUE && mali_clock) - { - clk_put(mali_clock); - mali_clock = 0; - } - -} - - -mali_bool mali_clk_set_rate(unsigned int clk, unsigned int mhz) -{ - unsigned long rate = 0; - mali_bool bis_vpll = MALI_TRUE; - -#ifndef CONFIG_VPLL_USE_FOR_TVENC - bis_vpll = MALI_TRUE; -#endif - -#if !MALI_DVFS_ENABLED - clk = mali_gpu_clk; -#endif - trace_printk("SPI_GPUFREQ_%uMHz\n", mali_gpu_clk); - _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); - - if (mali_clk_get(bis_vpll) == MALI_FALSE) - return MALI_FALSE; - - rate = (unsigned long)clk * (unsigned long)mhz; - MALI_DEBUG_PRINT(3,("= clk_set_rate : %d , %d \n",clk, mhz )); - - if (bis_vpll) - { - clk_set_rate(fout_vpll_clock, (unsigned int)clk * GPU_MHZ); - clk_set_parent(vpll_src_clock, ext_xtal_clock); - clk_set_parent(sclk_vpll_clock, fout_vpll_clock); - - clk_set_parent(mali_parent_clock, sclk_vpll_clock); - clk_set_parent(mali_clock, mali_parent_clock); - } - else - { - clk_set_parent(mali_parent_clock, mpll_clock); - clk_set_parent(mali_clock, mali_parent_clock); - } - - if (clk_enable(mali_clock) < 0) - return MALI_FALSE; - - - clk_set_rate(mali_clock, rate); - rate = clk_get_rate(mali_clock); - -#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED - gFreq = rate/1000000; - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | - MALI_PROFILING_EVENT_CHANNEL_GPU | - MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, - gFreq, gVolt, 0, 0, 0); -#endif - - if (bis_vpll) - mali_gpu_clk = (int)(rate / mhz); - else - mali_gpu_clk = (int)((rate + 500000) / mhz); - - GPU_MHZ = mhz; - MALI_DEBUG_PRINT(3,("= clk_get_rate: %d \n",mali_gpu_clk)); - - mali_clk_put(MALI_FALSE); - - _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); - - return MALI_TRUE; -} - -static mali_bool init_mali_clock(void) -{ - mali_bool ret = MALI_TRUE; - - if (mali_clock != 0) - return ret; // already initialized - - mali_dvfs_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE - | _MALI_OSK_LOCKFLAG_ONELOCK, 0, 0); - if (mali_dvfs_lock == NULL) - return _MALI_OSK_ERR_FAULT; - - if (mali_clk_set_rate(mali_gpu_clk, GPU_MHZ) == MALI_FALSE) - { - ret = MALI_FALSE; - goto err_clock_get; - } - - MALI_PRINT(("init_mali_clock mali_clock %p \n", mali_clock)); - - -#ifdef CONFIG_REGULATOR -#if USING_MALI_PMM - g3d_regulator = regulator_get(&mali_gpu_device.dev, "vdd_g3d"); -#else - g3d_regulator = regulator_get(NULL, "vdd_g3d"); -#endif - - if (IS_ERR(g3d_regulator)) - { - MALI_PRINT( ("MALI Error : failed to get vdd_g3d\n")); - ret = MALI_FALSE; - goto err_regulator; - } - - regulator_enable(g3d_regulator); - - MALI_DEBUG_PRINT(1, ("= regulator_enable -> use cnt: %d \n",mali_regulator_get_usecount())); - mali_regulator_set_voltage(mali_gpu_vol, mali_gpu_vol); -#endif - - MALI_DEBUG_PRINT(2, ("MALI Clock is set at mali driver\n")); - - MALI_DEBUG_PRINT(3,("::clk_put:: %s mali_parent_clock - normal\n", __FUNCTION__)); - MALI_DEBUG_PRINT(3,("::clk_put:: %s mpll_clock - normal\n", __FUNCTION__)); - - mali_clk_put(MALI_FALSE); - - gpu_power_state=0; - bPoweroff=1; - - return MALI_TRUE; -#ifdef CONFIG_REGULATOR -err_regulator: - regulator_put(g3d_regulator); -#endif - -err_clock_get: - mali_clk_put(MALI_TRUE); - - return ret; -} - -static mali_bool deinit_mali_clock(void) -{ - if (mali_clock == 0) - return MALI_TRUE; - -#ifdef CONFIG_REGULATOR - if (g3d_regulator) - { - regulator_put(g3d_regulator); - g3d_regulator=NULL; - } -#endif - - mali_clk_put(MALI_TRUE); - - return MALI_TRUE; -} -static _mali_osk_errcode_t enable_mali_clocks(void) -{ - int err; - err = clk_enable(mali_clock); - MALI_DEBUG_PRINT(3,("enable_mali_clocks mali_clock %p error %d \n", mali_clock, err)); - - mali_runtime_resume.vol = mali_dvfs_get_vol(MALI_DVFS_DEFAULT_STEP); -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON -#if MALI_DVFS_ENABLED - // set clock rate - if (get_mali_dvfs_control_status() != 0 || mali_gpu_clk >= mali_runtime_resume.clk) - mali_clk_set_rate(mali_gpu_clk, GPU_MHZ); - else { - mali_regulator_set_voltage(mali_runtime_resume.vol, mali_runtime_resume.vol); - mali_clk_set_rate(mali_runtime_resume.clk, GPU_MHZ); - set_mali_dvfs_current_step(MALI_DVFS_DEFAULT_STEP); - } -#if CPUFREQ_LOCK_DURING_440 - /* lock/unlock CPU freq by Mali */ - if (mali_gpu_clk >= 440) - err = cpufreq_lock_by_mali(1200); -#endif -#else - mali_regulator_set_voltage(mali_runtime_resume.vol, mali_runtime_resume.vol); - mali_clk_set_rate(mali_runtime_resume.clk, GPU_MHZ); -#endif -#else - mali_clk_set_rate(mali_gpu_clk, GPU_MHZ); -#endif - MALI_SUCCESS; -} - -static _mali_osk_errcode_t disable_mali_clocks(void) -{ - clk_disable(mali_clock); - MALI_DEBUG_PRINT(3,("disable_mali_clocks mali_clock %p \n", mali_clock)); - -#if MALI_DVFS_ENABLED && CPUFREQ_LOCK_DURING_440 - /* lock/unlock CPU freq by Mali */ - cpufreq_unlock_by_mali(); -#endif - MALI_SUCCESS; -} - -void set_mali_parent_power_domain(struct platform_device* dev) -{ -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36) - dev->dev.parent = &s5pv310_device_pd[PD_G3D].dev; -#else - dev->dev.parent = &exynos4_device_pd[PD_G3D].dev; -#endif -#endif -} - -_mali_osk_errcode_t g3d_power_domain_control(int bpower_on) -{ - if (bpower_on) - { -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON - MALI_DEBUG_PRINT(3,("_mali_osk_pmm_dev_activate \n")); - _mali_osk_pm_dev_activate(); -#else //MALI_PMM_RUNTIME_JOB_CONTROL_ON - void __iomem *status; - u32 timeout; - __raw_writel(S5P_INT_LOCAL_PWR_EN, S5P_PMU_G3D_CONF); - status = S5P_PMU_G3D_CONF + 0x4; - - timeout = 10; - while ((__raw_readl(status) & S5P_INT_LOCAL_PWR_EN) - != S5P_INT_LOCAL_PWR_EN) { - if (timeout == 0) { - MALI_PRINTF(("Power domain enable failed.\n")); - return -ETIMEDOUT; - } - timeout--; - _mali_osk_time_ubusydelay(100); - } -#endif //MALI_PMM_RUNTIME_JOB_CONTROL_ON - } - else - { -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON - MALI_DEBUG_PRINT( 4,("_mali_osk_pmm_dev_idle\n")); - _mali_osk_pm_dev_idle(); -#else //MALI_PMM_RUNTIME_JOB_CONTROL_ON - void __iomem *status; - u32 timeout; - __raw_writel(0, S5P_PMU_G3D_CONF); - - status = S5P_PMU_G3D_CONF + 0x4; - /* Wait max 1ms */ - timeout = 10; - while (__raw_readl(status) & S5P_INT_LOCAL_PWR_EN) - { - if (timeout == 0) { - MALI_PRINTF(("Power domain disable failed.\n" )); - return -ETIMEDOUT; - } - timeout--; - _mali_osk_time_ubusydelay( 100); - } -#endif //MALI_PMM_RUNTIME_JOB_CONTROL_ON - } - - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_init() -{ - MALI_CHECK(init_mali_clock(), _MALI_OSK_ERR_FAULT); -#if MALI_VOLTAGE_LOCK - _mali_osk_atomic_init(&voltage_lock_status, 0); -#endif -#if MALI_DVFS_ENABLED - if (!clk_register_map) clk_register_map = _mali_osk_mem_mapioregion( CLK_DIV_STAT_G3D, 0x20, CLK_DESC ); - if(!init_mali_dvfs_status(MALI_DVFS_DEFAULT_STEP)) - MALI_DEBUG_PRINT(1, ("mali_platform_init failed\n")); -#endif - - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_deinit() -{ - deinit_mali_clock(); -#if MALI_VOLTAGE_LOCK - _mali_osk_atomic_term(&voltage_lock_status); -#endif -#if MALI_DVFS_ENABLED - deinit_mali_dvfs_status(); - if (clk_register_map ) - { - _mali_osk_mem_unmapioregion(CLK_DIV_STAT_G3D, 0x20, clk_register_map); - clk_register_map=0; - } -#endif - - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_powerdown(u32 cores) -{ - trace_printk("SPI_GPU_PWR Idle\n"); - MALI_DEBUG_PRINT(3,("power down is called in mali_platform_powerdown state %x core %x \n", gpu_power_state, cores)); - - if (gpu_power_state != 0) // power down after state is 0 - { - gpu_power_state = gpu_power_state & (~cores); - if (gpu_power_state == 0) - { - MALI_DEBUG_PRINT( 3,("disable clock\n")); - disable_mali_clocks(); - } - } - else - { - MALI_PRINT(("mali_platform_powerdown gpu_power_state == 0 and cores %x \n", cores)); - } - - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_powerup(u32 cores) -{ - trace_printk("SPI_GPU_PWR Start\n"); - MALI_DEBUG_PRINT(3,("power up is called in mali_platform_powerup state %x core %x \n", gpu_power_state, cores)); - - if (gpu_power_state == 0) // power up only before state is 0 - { - gpu_power_state = gpu_power_state | cores; - - if (gpu_power_state != 0) - { - MALI_DEBUG_PRINT(4,("enable clock \n")); - enable_mali_clocks(); - } - } - else - { - gpu_power_state = gpu_power_state | cores; - } - - MALI_SUCCESS; -} - -void mali_gpu_utilization_handler(u32 utilization) -{ - if (bPoweroff==0) - { -#if MALI_DVFS_ENABLED - if(!mali_dvfs_handler(utilization)) - MALI_DEBUG_PRINT(1,( "error on mali dvfs status in utilization\n")); -#endif - } -} - -#if MALI_POWER_MGMT_TEST_SUITE -u32 pmu_get_power_up_down_info(void) -{ - return 4095; -} - -#endif - -_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode) -{ - switch (power_mode) - { - case MALI_POWER_MODE_ON: - MALI_DEBUG_PRINT(1, ("Mali platform: Got MALI_POWER_MODE_ON event, %s\n", bPoweroff ? "powering on" : "already on")); - if (bPoweroff == 1) - { - /** If run time power management is used, donot call this function */ -#ifndef CONFIG_PM_RUNTIME - g3d_power_domain_control(1); -#endif - - MALI_DEBUG_PRINT(4,("enable clock \n")); - enable_mali_clocks(); -#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE| MALI_PROFILING_EVENT_CHANNEL_GPU|MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0); -#endif - //MALI_PRINTF(("Mali Platform powered up")); - gpu_power_state=1; - bPoweroff=0; - } - break; - case MALI_POWER_MODE_LIGHT_SLEEP: - case MALI_POWER_MODE_DEEP_SLEEP: - MALI_DEBUG_PRINT(1, ("Mali platform: Got %s event, %s\n", - power_mode == MALI_POWER_MODE_LIGHT_SLEEP ? "MALI_POWER_MODE_LIGHT_SLEEP" : "MALI_POWER_MODE_DEEP_SLEEP", - bPoweroff ? "already off" : "powering off")); - if (bPoweroff == 0) - { - disable_mali_clocks(); -#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED - _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE| MALI_PROFILING_EVENT_CHANNEL_GPU|MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, 0, 0, 0, 0, 0); -#endif - -#ifndef CONFIG_PM_RUNTIME - g3d_power_domain_control(0); -#endif - - //MALI_PRINTF(("Mali Platform powered down")); - gpu_power_state=0; - bPoweroff=1; - } - - break; - } - MALI_SUCCESS; -} - -#if MALI_VOLTAGE_LOCK -int mali_voltage_lock_push(int lock_vol) -{ - int prev_status = _mali_osk_atomic_read(&voltage_lock_status); - - if (prev_status < 0) { - MALI_PRINT(("gpu voltage lock status is not valid for push\n")); - return -1; - } - if (prev_status == 0) { - mali_lock_vol = lock_vol; - if (mali_gpu_vol < mali_lock_vol) - mali_regulator_set_voltage(mali_lock_vol, mali_lock_vol); - } else { - MALI_PRINT(("gpu voltage lock status is already pushed, current lock voltage : %d\n", mali_lock_vol)); - return -1; - } - - return _mali_osk_atomic_inc_return(&voltage_lock_status); -} - -int mali_voltage_lock_pop(void) -{ - if (_mali_osk_atomic_read(&voltage_lock_status) <= 0) { - MALI_PRINT(("gpu voltage lock status is not valid for pop\n")); - return -1; - } - return _mali_osk_atomic_dec_return(&voltage_lock_status); -} - -int mali_voltage_lock_init(void) -{ - mali_vol_lock_flag = MALI_TRUE; - - MALI_SUCCESS; -} -#endif diff --git a/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c b/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c deleted file mode 100644 index cc1164e..0000000 --- a/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c +++ /dev/null @@ -1,847 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_platform_dvfs.c - * Platform specific Mali driver dvfs functions - */ - -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "mali_platform.h" - -#include -#include -#include -#include - -#include - -#include "mali_device_pause_resume.h" -#include - -#define MAX_MALI_DVFS_STEPS 5 -#define MALI_DVFS_WATING 10 // msec - -#ifdef CONFIG_CPU_FREQ -#include -#define EXYNOS4_ASV_ENABLED -#endif - -#include - -static int bMaliDvfsRun=0; - -static _mali_osk_atomic_t bottomlock_status; -int bottom_lock_step = 0; - -typedef struct mali_dvfs_tableTag{ - unsigned int clock; - unsigned int freq; - unsigned int vol; -}mali_dvfs_table; - -typedef struct mali_dvfs_statusTag{ - unsigned int currentStep; - mali_dvfs_table * pCurrentDvfs; - -}mali_dvfs_currentstatus; - -typedef struct mali_dvfs_thresholdTag{ - unsigned int downthreshold; - unsigned int upthreshold; -}mali_dvfs_threshold_table; - -typedef struct mali_dvfs_staycount{ - unsigned int staycount; -}mali_dvfs_staycount_table; - -typedef struct mali_dvfs_stepTag{ - int clk; - int vol; -}mali_dvfs_step; - -mali_dvfs_step step[MALI_DVFS_STEPS]={ - /*step 0 clk*/ {160, 875000}, -#if (MALI_DVFS_STEPS > 1) - /*step 1 clk*/ {266, 900000}, -#if (MALI_DVFS_STEPS > 2) - /*step 2 clk*/ {350, 950000}, -#if (MALI_DVFS_STEPS > 3) - /*step 3 clk*/ {440, 1025000}, -#if (MALI_DVFS_STEPS > 4) - /*step 4 clk*/ {533, 1075000} -#endif -#endif -#endif -#endif -}; - -mali_dvfs_staycount_table mali_dvfs_staycount[MALI_DVFS_STEPS]={ - /*step 0*/{0}, -#if (MALI_DVFS_STEPS > 1) - /*step 1*/{0}, -#if (MALI_DVFS_STEPS > 2) - /*step 2*/{0}, -#if (MALI_DVFS_STEPS > 3) - /*step 3*/{0}, -#if (MALI_DVFS_STEPS > 4) - /*step 4*/{0} -#endif -#endif -#endif -#endif -}; - -/* dvfs information */ -// L0 = 533Mhz, 1.075V -// L1 = 440Mhz, 1.025V -// L2 = 350Mhz, 0.95V -// L3 = 266Mhz, 0.90V -// L4 = 160Mhz, 0.875V - -int step0_clk = 160; -int step0_vol = 875000; -#if (MALI_DVFS_STEPS > 1) -int step1_clk = 266; -int step1_vol = 900000; -int step0_up = 70; -int step1_down = 62; -#if (MALI_DVFS_STEPS > 2) -int step2_clk = 350; -int step2_vol = 950000; -int step1_up = 90; -int step2_down = 85; -#if (MALI_DVFS_STEPS > 3) -int step3_clk = 440; -int step3_vol = 1025000; -int step2_up = 90; -int step3_down = 85; -#if (MALI_DVFS_STEPS > 4) -int step4_clk = 533; -int step4_vol = 1075000; -int step3_up = 90; -int step4_down = 95; -#endif -#endif -#endif -#endif - -mali_dvfs_table mali_dvfs_all[MAX_MALI_DVFS_STEPS]={ - {160 ,1000000 , 875000}, - {266 ,1000000 , 900000}, - {350 ,1000000 , 950000}, - {440 ,1000000 , 1025000}, - {533 ,1000000 , 1075000} }; - -mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={ - {160 ,1000000 , 875000}, -#if (MALI_DVFS_STEPS > 1) - {266 ,1000000 , 900000}, -#if (MALI_DVFS_STEPS > 2) - {350 ,1000000 , 950000}, -#if (MALI_DVFS_STEPS > 3) - {440 ,1000000 ,1025000}, -#if (MALI_DVFS_STEPS > 4) - {533 ,1000000 ,1075000} -#endif -#endif -#endif -#endif -}; - -mali_dvfs_threshold_table mali_dvfs_threshold[MALI_DVFS_STEPS]={ - {0 , 70}, -#if (MALI_DVFS_STEPS > 1) - {62 , 90}, -#if (MALI_DVFS_STEPS > 2) - {85 , 90}, -#if (MALI_DVFS_STEPS > 3) - {85 ,90}, -#if (MALI_DVFS_STEPS > 4) - {95 ,100} -#endif -#endif -#endif -#endif -}; - -#ifdef EXYNOS4_ASV_ENABLED -#define ASV_LEVEL 12 /* ASV0, 1, 11 is reserved */ -#define ASV_LEVEL_PRIME 13 /* ASV0, 1, 12 is reserved */ - -static unsigned int asv_3d_volt_9_table_1ghz_type[MALI_DVFS_STEPS-1][ASV_LEVEL] = { - { 975000, 950000, 950000, 950000, 925000, 925000, 925000, 900000, 900000, 900000, 900000, 875000}, /* L3(160Mhz) */ -#if (MALI_DVFS_STEPS > 1) - { 1000000, 975000, 975000, 975000, 950000, 950000, 950000, 900000, 900000, 900000, 900000, 875000}, /* L2(266Mhz) */ -#if (MALI_DVFS_STEPS > 2) - { 1075000, 1050000, 1050000, 1050000, 1000000, 1000000, 1000000, 975000, 975000, 975000, 975000, 925000}, /* L1(350Mhz) */ -#if (MALI_DVFS_STEPS > 3) - { 1125000, 1100000, 1100000, 1100000, 1075000, 1075000, 1075000, 1025000, 1025000, 1025000, 1025000, 975000}, /* L0(440Mhz) */ -#endif -#endif -#endif -}; - -static unsigned int asv_3d_volt_9_table[MALI_DVFS_STEPS-1][ASV_LEVEL] = { - { 950000, 925000, 900000, 900000, 875000, 875000, 875000, 875000, 850000, 850000, 850000, 850000}, /* L3(160Mhz) */ -#if (MALI_DVFS_STEPS > 1) - { 975000, 950000, 925000, 925000, 925000, 900000, 900000, 875000, 875000, 875000, 875000, 850000}, /* L2(266Mhz) */ -#if (MALI_DVFS_STEPS > 2) - { 1050000, 1025000, 1000000, 1000000, 975000, 950000, 950000, 950000, 925000, 925000, 925000, 900000}, /* L1(350Mhz) */ -#if (MALI_DVFS_STEPS > 3) - { 1100000, 1075000, 1050000, 1050000, 1050000, 1025000, 1025000, 1000000, 1000000, 1000000, 975000, 950000}, /* L0(440Mhz) */ -#endif -#endif -#endif -}; - -static unsigned int asv_3d_volt_9_table_for_prime[MALI_DVFS_STEPS][ASV_LEVEL_PRIME] = { - { 950000, 937500, 925000, 912500, 900000, 887500, 875000, 862500, 875000, 862500, 850000, 850000}, /* L4(160Mhz) */ -#if (MALI_DVFS_STEPS > 1) - { 975000, 962500, 950000, 937500, 925000, 912500, 900000, 887500, 900000, 887500, 875000, 862500}, /* L3(266Mhz) */ -#if (MALI_DVFS_STEPS > 2) - { 1025000, 1012500, 1000000, 987500, 975000, 962500, 950000, 937500, 950000, 937500, 925000, 912500}, /* L2(350Mhz) */ -#if (MALI_DVFS_STEPS > 3) - { 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 1012500, 1000000, 987500, 975000}, /* L1(440Mhz) */ -#if (MALI_DVFS_STEPS > 4) - { 1150000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1087500, 1075000, 1062500, 1050000}, /* L0(600Mhz) */ -#endif -#endif -#endif -#endif -}; -#endif /* ASV_LEVEL */ - -/*dvfs status*/ -mali_dvfs_currentstatus maliDvfsStatus; -int mali_dvfs_control=0; - -static u32 mali_dvfs_utilization = 255; - -static void mali_dvfs_work_handler(struct work_struct *w); - -static struct workqueue_struct *mali_dvfs_wq = 0; -extern mali_io_address clk_register_map; -extern _mali_osk_lock_t *mali_dvfs_lock; - -int mali_runtime_resumed = -1; - -static DECLARE_WORK(mali_dvfs_work, mali_dvfs_work_handler); - -/* lock/unlock CPU freq by Mali */ -#include -#include - -atomic_t mali_cpufreq_lock; - -int cpufreq_lock_by_mali(unsigned int freq) -{ -#ifdef CONFIG_EXYNOS4_CPUFREQ -/* #if defined(CONFIG_CPU_FREQ) && defined(CONFIG_ARCH_EXYNOS4) */ - unsigned int level; - - if (atomic_read(&mali_cpufreq_lock) == 0) { - if (exynos_cpufreq_get_level(freq * 1000, &level)) { - printk(KERN_ERR - "Mali: failed to get cpufreq level for %dMHz", - freq); - return -EINVAL; - } - - if (exynos_cpufreq_lock(DVFS_LOCK_ID_G3D, level)) { - printk(KERN_ERR - "Mali: failed to cpufreq lock for L%d", level); - return -EINVAL; - } - - atomic_set(&mali_cpufreq_lock, 1); - printk(KERN_DEBUG "Mali: cpufreq locked on <%d>%dMHz\n", level, - freq); - } -#endif - return 0; -} - -void cpufreq_unlock_by_mali(void) -{ -#ifdef CONFIG_EXYNOS4_CPUFREQ -/* #if defined(CONFIG_CPU_FREQ) && defined(CONFIG_ARCH_EXYNOS4) */ - if (atomic_read(&mali_cpufreq_lock) == 1) { - exynos_cpufreq_lock_free(DVFS_LOCK_ID_G3D); - atomic_set(&mali_cpufreq_lock, 0); - printk(KERN_DEBUG "Mali: cpufreq locked off\n"); - } -#endif -} - -static unsigned int get_mali_dvfs_status(void) -{ - return maliDvfsStatus.currentStep; -} -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON -int get_mali_dvfs_control_status(void) -{ - return mali_dvfs_control; -} - -mali_bool set_mali_dvfs_current_step(unsigned int step) -{ - _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); - maliDvfsStatus.currentStep = step % MAX_MALI_DVFS_STEPS; - if (step >= MAX_MALI_DVFS_STEPS) - mali_runtime_resumed = maliDvfsStatus.currentStep; - _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); - return MALI_TRUE; -} -#endif -static mali_bool set_mali_dvfs_status(u32 step,mali_bool boostup) -{ - u32 validatedStep=step; - int err; - -#ifdef CONFIG_REGULATOR - if (mali_regulator_get_usecount() == 0) { - MALI_DEBUG_PRINT(1, ("regulator use_count is 0 \n")); - return MALI_FALSE; - } -#endif - - if (boostup) { -#ifdef CONFIG_REGULATOR - /*change the voltage*/ - mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol); -#endif - /*change the clock*/ - mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq); - } else { - /*change the clock*/ - mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq); -#ifdef CONFIG_REGULATOR - /*change the voltage*/ - mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol); -#endif - } - -#ifdef EXYNOS4_ASV_ENABLED - if (samsung_rev() < EXYNOS4412_REV_2_0) { - if (mali_dvfs[step].clock == 160) - exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_100V); - else - exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_130V); - } -#endif - - - set_mali_dvfs_current_step(validatedStep); - /*for future use*/ - maliDvfsStatus.pCurrentDvfs = &mali_dvfs[validatedStep]; - -#if CPUFREQ_LOCK_DURING_440 - /* lock/unlock CPU freq by Mali */ - if (mali_dvfs[step].clock == 440) - err = cpufreq_lock_by_mali(1200); - else - cpufreq_unlock_by_mali(); -#endif - - return MALI_TRUE; -} - -static void mali_platform_wating(u32 msec) -{ - /*sample wating - change this in the future with proper check routine. - */ - unsigned int read_val; - while(1) { - read_val = _mali_osk_mem_ioread32(clk_register_map, 0x00); - if ((read_val & 0x8000)==0x0000) break; - _mali_osk_time_ubusydelay(100); // 1000 -> 100 : 20101218 - } - /* _mali_osk_time_ubusydelay(msec*1000);*/ -} - -static mali_bool change_mali_dvfs_status(u32 step, mali_bool boostup ) -{ - - MALI_DEBUG_PRINT(1, ("> change_mali_dvfs_status: %d, %d \n",step, boostup)); - - if (!set_mali_dvfs_status(step, boostup)) { - MALI_DEBUG_PRINT(1, ("error on set_mali_dvfs_status: %d, %d \n",step, boostup)); - return MALI_FALSE; - } - - /*wait until clock and voltage is stablized*/ - mali_platform_wating(MALI_DVFS_WATING); /*msec*/ - - return MALI_TRUE; -} - -#ifdef EXYNOS4_ASV_ENABLED -extern unsigned int exynos_result_of_asv; - -static mali_bool mali_dvfs_table_update(void) -{ - unsigned int i; - unsigned int step_num = MALI_DVFS_STEPS; - - if(samsung_rev() < EXYNOS4412_REV_2_0) - step_num = MALI_DVFS_STEPS - 1; - - if(soc_is_exynos4412()) { - if (exynos_armclk_max == 1000000) { - MALI_PRINT(("::C::exynos_result_of_asv : %d\n", exynos_result_of_asv)); - for (i = 0; i < step_num; i++) { - mali_dvfs[i].vol = asv_3d_volt_9_table_1ghz_type[i][exynos_result_of_asv]; - MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol)); - } - } else if(((is_special_flag() >> G3D_LOCK_FLAG) & 0x1) && (samsung_rev() >= EXYNOS4412_REV_2_0)) { - MALI_PRINT(("::L::exynos_result_of_asv : %d\n", exynos_result_of_asv)); - for (i = 0; i < step_num; i++) { - mali_dvfs[i].vol = asv_3d_volt_9_table_for_prime[i][exynos_result_of_asv] + 25000; - MALI_PRINT(("mali_dvfs[%d].vol = %d \n ", i, mali_dvfs[i].vol)); - } - } else if (samsung_rev() >= EXYNOS4412_REV_2_0) { - MALI_PRINT(("::P::exynos_result_of_asv : %d\n", exynos_result_of_asv)); - for (i = 0; i < step_num; i++) { - mali_dvfs[i].vol = asv_3d_volt_9_table_for_prime[i][exynos_result_of_asv]; - MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol)); - } - } else { - MALI_PRINT(("::Q::exynos_result_of_asv : %d\n", exynos_result_of_asv)); - for (i = 0; i < step_num; i++) { - mali_dvfs[i].vol = asv_3d_volt_9_table[i][exynos_result_of_asv]; - MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol)); - } - } - } - - return MALI_TRUE; -} -#endif - -static unsigned int decideNextStatus(unsigned int utilization) -{ - static unsigned int level = 0; // 0:stay, 1:up - static int mali_dvfs_clk = 0; - - if (mali_runtime_resumed >= 0) { - level = mali_runtime_resumed; - mali_runtime_resumed = -1; - } - - if (mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold - <= mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold) { - MALI_PRINT(("upthreadshold is smaller than downthreshold: %d < %d\n", - mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold, - mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold)); - return level; - } - - if (!mali_dvfs_control && level == maliDvfsStatus.currentStep) { - if (utilization > (int)(255 * mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold / 100) && - level < MALI_DVFS_STEPS - 1) { - level++; - if ((samsung_rev() < EXYNOS4412_REV_2_0) && (maliDvfsStatus.currentStep == 3)) { - level=get_mali_dvfs_status(); - } - } - if (utilization < (int)(255 * mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold / 100) && - level > 0) { - level--; - } - } else if (mali_dvfs_control == 999) { - int i = 0; - for (i = 0; i < MALI_DVFS_STEPS; i++) { - step[i].clk = mali_dvfs_all[i].clock; - } -#ifdef EXYNOS4_ASV_ENABLED - mali_dvfs_table_update(); -#endif - i = 0; - for (i = 0; i < MALI_DVFS_STEPS; i++) { - mali_dvfs[i].clock = step[i].clk; - } - mali_dvfs_control = 0; - level = 0; - - step0_clk = step[0].clk; - change_dvfs_tableset(step0_clk, 0); -#if (MALI_DVFS_STEPS > 1) - step1_clk = step[1].clk; - change_dvfs_tableset(step1_clk, 1); -#if (MALI_DVFS_STEPS > 2) - step2_clk = step[2].clk; - change_dvfs_tableset(step2_clk, 2); -#if (MALI_DVFS_STEPS > 3) - step3_clk = step[3].clk; - change_dvfs_tableset(step3_clk, 3); -#if (MALI_DVFS_STEPS > 4) - step4_clk = step[4].clk; - change_dvfs_tableset(step4_clk, 4); -#endif -#endif -#endif -#endif - } else if (mali_dvfs_control != mali_dvfs_clk && mali_dvfs_control != 999) { - if (mali_dvfs_control < mali_dvfs_all[1].clock && mali_dvfs_control > 0) { - int i = 0; - for (i = 0; i < MALI_DVFS_STEPS; i++) { - step[i].clk = mali_dvfs_all[0].clock; - } - maliDvfsStatus.currentStep = 0; - } else if (mali_dvfs_control < mali_dvfs_all[2].clock && mali_dvfs_control >= mali_dvfs_all[1].clock) { - int i = 0; - for (i = 0; i < MALI_DVFS_STEPS; i++) { - step[i].clk = mali_dvfs_all[1].clock; - } - maliDvfsStatus.currentStep = 1; - } else if (mali_dvfs_control < mali_dvfs_all[3].clock && mali_dvfs_control >= mali_dvfs_all[2].clock) { - int i = 0; - for (i = 0; i < MALI_DVFS_STEPS; i++) { - step[i].clk = mali_dvfs_all[2].clock; - } - maliDvfsStatus.currentStep = 2; - } else if (mali_dvfs_control < mali_dvfs_all[4].clock && mali_dvfs_control >= mali_dvfs_all[3].clock) { - int i = 0; - for (i = 0; i < MALI_DVFS_STEPS; i++) { - step[i].clk = mali_dvfs_all[3].clock; - } - maliDvfsStatus.currentStep = 3; - } else { - int i = 0; - for (i = 0; i < MALI_DVFS_STEPS; i++) { - step[i].clk = mali_dvfs_all[4].clock; - } - maliDvfsStatus.currentStep = 4; - } - step0_clk = step[0].clk; - change_dvfs_tableset(step0_clk, 0); -#if (MALI_DVFS_STEPS > 1) - step1_clk = step[1].clk; - change_dvfs_tableset(step1_clk, 1); -#if (MALI_DVFS_STEPS > 2) - step2_clk = step[2].clk; - change_dvfs_tableset(step2_clk, 2); -#if (MALI_DVFS_STEPS > 3) - step3_clk = step[3].clk; - change_dvfs_tableset(step3_clk, 3); -#if (MALI_DVFS_STEPS > 4) - step4_clk = step[4].clk; - change_dvfs_tableset(step4_clk, 4); -#endif -#endif -#endif -#endif - level = maliDvfsStatus.currentStep; - } - - mali_dvfs_clk = mali_dvfs_control; - - if (_mali_osk_atomic_read(&bottomlock_status) > 0) { - if (level < bottom_lock_step) - level = bottom_lock_step; - } - - return level; -} - -static mali_bool mali_dvfs_status(u32 utilization) -{ - unsigned int nextStatus = 0; - unsigned int curStatus = 0; - mali_bool boostup = MALI_FALSE; - static int stay_count = 0; -#ifdef EXYNOS4_ASV_ENABLED - static mali_bool asv_applied = MALI_FALSE; -#endif - - MALI_DEBUG_PRINT(1, ("> mali_dvfs_status: %d \n",utilization)); -#ifdef EXYNOS4_ASV_ENABLED - if (asv_applied == MALI_FALSE) { - mali_dvfs_table_update(); - change_mali_dvfs_status(1, 0); - asv_applied = MALI_TRUE; - - return MALI_TRUE; - } -#endif - - /*decide next step*/ - curStatus = get_mali_dvfs_status(); - nextStatus = decideNextStatus(utilization); - - MALI_DEBUG_PRINT(1, ("= curStatus %d, nextStatus %d, maliDvfsStatus.currentStep %d \n", curStatus, nextStatus, maliDvfsStatus.currentStep)); - - /*if next status is same with current status, don't change anything*/ - if ((curStatus != nextStatus && stay_count == 0)) { - /*check if boost up or not*/ - if (nextStatus > maliDvfsStatus.currentStep) boostup = 1; - - /*change mali dvfs status*/ - if (!change_mali_dvfs_status(nextStatus,boostup)) { - MALI_DEBUG_PRINT(1, ("error on change_mali_dvfs_status \n")); - return MALI_FALSE; - } - stay_count = mali_dvfs_staycount[maliDvfsStatus.currentStep].staycount; - } else { - if (stay_count > 0) - stay_count--; - } - - return MALI_TRUE; -} - - - -int mali_dvfs_is_running(void) -{ - return bMaliDvfsRun; - -} - - - -void mali_dvfs_late_resume(void) -{ - // set the init clock as low when resume - set_mali_dvfs_status(0,0); -} - - -static void mali_dvfs_work_handler(struct work_struct *w) -{ - int change_clk = 0; - int change_step = 0; - bMaliDvfsRun=1; - - /* dvfs table change when clock was changed */ - if (step0_clk != mali_dvfs[0].clock) { - MALI_PRINT(("::: step0_clk change to %d Mhz\n", step0_clk)); - change_clk = step0_clk; - change_step = 0; - step0_clk = change_dvfs_tableset(change_clk, change_step); - } -#if (MALI_DVFS_STEPS > 1) - if (step1_clk != mali_dvfs[1].clock) { - MALI_PRINT(("::: step1_clk change to %d Mhz\n", step1_clk)); - change_clk = step1_clk; - change_step = 1; - step1_clk = change_dvfs_tableset(change_clk, change_step); - } - if (step0_up != mali_dvfs_threshold[0].upthreshold) { - MALI_PRINT(("::: step0_up change to %d %\n", step0_up)); - mali_dvfs_threshold[0].upthreshold = step0_up; - } - if (step1_down != mali_dvfs_threshold[1].downthreshold) { - MALI_PRINT((":::step1_down change to %d %\n", step1_down)); - mali_dvfs_threshold[1].downthreshold = step1_down; - } -#if (MALI_DVFS_STEPS > 2) - if (step2_clk != mali_dvfs[2].clock) { - MALI_PRINT(("::: step2_clk change to %d Mhz\n", step2_clk)); - change_clk = step2_clk; - change_step = 2; - step2_clk = change_dvfs_tableset(change_clk, change_step); - } - if (step1_up != mali_dvfs_threshold[1].upthreshold) { - MALI_PRINT((":::step1_up change to %d %\n", step1_up)); - mali_dvfs_threshold[1].upthreshold = step1_up; - } - if (step2_down != mali_dvfs_threshold[2].downthreshold) { - MALI_PRINT((":::step2_down change to %d %\n", step2_down)); - mali_dvfs_threshold[2].downthreshold = step2_down; - } -#if (MALI_DVFS_STEPS > 3) - if (step3_clk != mali_dvfs[3].clock) { - MALI_PRINT(("::: step3_clk change to %d Mhz\n", step3_clk)); - change_clk = step3_clk; - change_step = 3; - step3_clk = change_dvfs_tableset(change_clk, change_step); - } - if (step2_up != mali_dvfs_threshold[2].upthreshold) { - MALI_PRINT((":::step2_up change to %d %\n", step2_up)); - mali_dvfs_threshold[2].upthreshold = step2_up; - } - if (step3_down != mali_dvfs_threshold[3].downthreshold) { - MALI_PRINT((":::step3_down change to %d %\n", step3_down)); - mali_dvfs_threshold[3].downthreshold = step3_down; - } -#if (MALI_DVFS_STEPS > 4) - if (step4_clk != mali_dvfs[4].clock) { - MALI_PRINT(("::: step4_clk change to %d Mhz\n", step4_clk)); - change_clk = step4_clk; - change_step = 4; - step4_clk = change_dvfs_tableset(change_clk, change_step); - } - if (step3_up != mali_dvfs_threshold[3].upthreshold) { - MALI_PRINT((":::step3_up change to %d %\n", step3_up)); - mali_dvfs_threshold[3].upthreshold = step3_up; - } - if (step4_down != mali_dvfs_threshold[4].downthreshold) { - MALI_PRINT((":::step4_down change to %d %\n", step4_down)); - mali_dvfs_threshold[4].downthreshold = step4_down; - } -#endif -#endif -#endif -#endif - - -#ifdef DEBUG - mali_dvfs[0].vol = step0_vol; - mali_dvfs[1].vol = step1_vol; - mali_dvfs[2].vol = step2_vol; - mali_dvfs[3].vol = step3_vol; - mali_dvfs[4].vol = step4_vol; -#endif - MALI_DEBUG_PRINT(3, ("=== mali_dvfs_work_handler\n")); - - if (!mali_dvfs_status(mali_dvfs_utilization)) - MALI_DEBUG_PRINT(1,( "error on mali dvfs status in mali_dvfs_work_handler")); - - bMaliDvfsRun=0; -} - -mali_bool init_mali_dvfs_status(int step) -{ - /*default status - add here with the right function to get initilization value. - */ - if (!mali_dvfs_wq) - mali_dvfs_wq = create_singlethread_workqueue("mali_dvfs"); - - _mali_osk_atomic_init(&bottomlock_status, 0); - - /*add a error handling here*/ - set_mali_dvfs_current_step(step); - - return MALI_TRUE; -} - -void deinit_mali_dvfs_status(void) -{ - if (mali_dvfs_wq) - destroy_workqueue(mali_dvfs_wq); - - _mali_osk_atomic_term(&bottomlock_status); - - mali_dvfs_wq = NULL; -} - -mali_bool mali_dvfs_handler(u32 utilization) -{ - mali_dvfs_utilization = utilization; - queue_work_on(0, mali_dvfs_wq,&mali_dvfs_work); - - /*add error handle here*/ - return MALI_TRUE; -} - -int change_dvfs_tableset(int change_clk, int change_step) -{ - int err; - - if (change_clk < mali_dvfs_all[1].clock) { - mali_dvfs[change_step].clock = mali_dvfs_all[0].clock; - } else if (change_clk < mali_dvfs_all[2].clock && change_clk >= mali_dvfs_all[1].clock) { - mali_dvfs[change_step].clock = mali_dvfs_all[1].clock; - } else if (change_clk < mali_dvfs_all[3].clock && change_clk >= mali_dvfs_all[2].clock) { - mali_dvfs[change_step].clock = mali_dvfs_all[2].clock; - } else if (change_clk < mali_dvfs_all[4].clock && change_clk >= mali_dvfs_all[3].clock) { - mali_dvfs[change_step].clock = mali_dvfs_all[3].clock; - } else { - mali_dvfs[change_step].clock = mali_dvfs_all[4].clock; - } - - MALI_PRINT((":::mali dvfs step %d clock and voltage = %d Mhz, %d V\n",change_step, mali_dvfs[change_step].clock, mali_dvfs[change_step].vol)); - - if (maliDvfsStatus.currentStep == change_step) { -#ifdef CONFIG_REGULATOR - /*change the voltage*/ - mali_regulator_set_voltage(mali_dvfs[change_step].vol, mali_dvfs[change_step].vol); -#endif - /*change the clock*/ - mali_clk_set_rate(mali_dvfs[change_step].clock, mali_dvfs[change_step].freq); - -#if CPUFREQ_LOCK_DURING_440 - /* lock/unlock CPU freq by Mali */ - if (mali_dvfs[change_step].clock == 440) - err = cpufreq_lock_by_mali(1200); - else - cpufreq_unlock_by_mali(); -#endif - } - - return mali_dvfs[change_step].clock; -} - -void mali_default_step_set(int step, mali_bool boostup) -{ - mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq); - - if (maliDvfsStatus.currentStep == 1) - set_mali_dvfs_status(step, boostup); -} - -int mali_dvfs_bottom_lock_push(int lock_step) -{ - int prev_status = _mali_osk_atomic_read(&bottomlock_status); - - if (prev_status < 0) { - MALI_PRINT(("gpu bottom lock status is not valid for push\n")); - return -1; - } - if (bottom_lock_step < lock_step) { - bottom_lock_step = lock_step; - if (get_mali_dvfs_status() < lock_step) { - mali_regulator_set_voltage(mali_dvfs[lock_step].vol, mali_dvfs[lock_step].vol); - mali_clk_set_rate(mali_dvfs[lock_step].clock, mali_dvfs[lock_step].freq); - set_mali_dvfs_current_step(lock_step); - } - } - return _mali_osk_atomic_inc_return(&bottomlock_status); -} - -int mali_dvfs_bottom_lock_pop(void) -{ - int prev_status = _mali_osk_atomic_read(&bottomlock_status); - if (prev_status <= 0) { - MALI_PRINT(("gpu bottom lock status is not valid for pop\n")); - return -1; - } else if (prev_status == 1) { - bottom_lock_step = 0; - MALI_PRINT(("gpu bottom lock release\n")); - } - - return _mali_osk_atomic_dec_return(&bottomlock_status); -} - -int mali_dvfs_get_vol(int step) -{ - step = step % MAX_MALI_DVFS_STEPS; - MALI_DEBUG_ASSERT(step= vol) - return mali_dvfs[i].vol; - } - MALI_PRINT(("Failed to get voltage from mali_dvfs table, maximum voltage is %d uV\n", mali_dvfs[MALI_DVFS_STEPS-1].vol)); - return 0; -} -#endif diff --git a/drivers/media/video/samsung/mali/regs/mali_200_regs.h b/drivers/media/video/samsung/mali/regs/mali_200_regs.h deleted file mode 100644 index 59e92c8..0000000 --- a/drivers/media/video/samsung/mali/regs/mali_200_regs.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef _MALI200_REGS_H_ -#define _MALI200_REGS_H_ - -/** - * Enum for management register addresses. - */ -enum mali200_mgmt_reg -{ - MALI200_REG_ADDR_MGMT_VERSION = 0x1000, - MALI200_REG_ADDR_MGMT_CURRENT_REND_LIST_ADDR = 0x1004, - MALI200_REG_ADDR_MGMT_STATUS = 0x1008, - MALI200_REG_ADDR_MGMT_CTRL_MGMT = 0x100c, - - MALI200_REG_ADDR_MGMT_INT_RAWSTAT = 0x1020, - MALI200_REG_ADDR_MGMT_INT_CLEAR = 0x1024, - MALI200_REG_ADDR_MGMT_INT_MASK = 0x1028, - MALI200_REG_ADDR_MGMT_INT_STATUS = 0x102c, - - MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW = 0x1044, - - MALI200_REG_ADDR_MGMT_BUS_ERROR_STATUS = 0x1050, - - MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE = 0x1080, - MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC = 0x1084, - MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE = 0x108c, - - MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE = 0x10a0, - MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC = 0x10a4, - MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE = 0x10ac, - - MALI200_REG_SIZEOF_REGISTER_BANK = 0x10f0 - -}; - -#define MALI200_REG_VAL_PERF_CNT_ENABLE 1 - -enum mali200_mgmt_ctrl_mgmt { - MALI200_REG_VAL_CTRL_MGMT_STOP_BUS = (1<<0), -#if defined(USING_MALI200) - MALI200_REG_VAL_CTRL_MGMT_FLUSH_CACHES = (1<<3), -#endif - MALI200_REG_VAL_CTRL_MGMT_FORCE_RESET = (1<<5), - MALI200_REG_VAL_CTRL_MGMT_START_RENDERING = (1<<6), -#if defined(USING_MALI400) || defined(USING_MALI450) - MALI400PP_REG_VAL_CTRL_MGMT_SOFT_RESET = (1<<7), -#endif -}; - -enum mali200_mgmt_irq { - MALI200_REG_VAL_IRQ_END_OF_FRAME = (1<<0), - MALI200_REG_VAL_IRQ_END_OF_TILE = (1<<1), - MALI200_REG_VAL_IRQ_HANG = (1<<2), - MALI200_REG_VAL_IRQ_FORCE_HANG = (1<<3), - MALI200_REG_VAL_IRQ_BUS_ERROR = (1<<4), - MALI200_REG_VAL_IRQ_BUS_STOP = (1<<5), - MALI200_REG_VAL_IRQ_CNT_0_LIMIT = (1<<6), - MALI200_REG_VAL_IRQ_CNT_1_LIMIT = (1<<7), - MALI200_REG_VAL_IRQ_WRITE_BOUNDARY_ERROR = (1<<8), - MALI400PP_REG_VAL_IRQ_INVALID_PLIST_COMMAND = (1<<9), - MALI400PP_REG_VAL_IRQ_CALL_STACK_UNDERFLOW = (1<<10), - MALI400PP_REG_VAL_IRQ_CALL_STACK_OVERFLOW = (1<<11), - MALI400PP_REG_VAL_IRQ_RESET_COMPLETED = (1<<12), -}; - -#if defined(USING_MALI200) -#define MALI200_REG_VAL_IRQ_MASK_ALL ((enum mali200_mgmt_irq) (\ - MALI200_REG_VAL_IRQ_END_OF_FRAME |\ - MALI200_REG_VAL_IRQ_END_OF_TILE |\ - MALI200_REG_VAL_IRQ_HANG |\ - MALI200_REG_VAL_IRQ_FORCE_HANG |\ - MALI200_REG_VAL_IRQ_BUS_ERROR |\ - MALI200_REG_VAL_IRQ_BUS_STOP |\ - MALI200_REG_VAL_IRQ_CNT_0_LIMIT |\ - MALI200_REG_VAL_IRQ_CNT_1_LIMIT |\ - MALI200_REG_VAL_IRQ_WRITE_BOUNDARY_ERROR)) -#elif defined(USING_MALI400) || defined(USING_MALI450) -#define MALI200_REG_VAL_IRQ_MASK_ALL ((enum mali200_mgmt_irq) (\ - MALI200_REG_VAL_IRQ_END_OF_FRAME |\ - MALI200_REG_VAL_IRQ_END_OF_TILE |\ - MALI200_REG_VAL_IRQ_HANG |\ - MALI200_REG_VAL_IRQ_FORCE_HANG |\ - MALI200_REG_VAL_IRQ_BUS_ERROR |\ - MALI200_REG_VAL_IRQ_BUS_STOP |\ - MALI200_REG_VAL_IRQ_CNT_0_LIMIT |\ - MALI200_REG_VAL_IRQ_CNT_1_LIMIT |\ - MALI200_REG_VAL_IRQ_WRITE_BOUNDARY_ERROR |\ - MALI400PP_REG_VAL_IRQ_INVALID_PLIST_COMMAND |\ - MALI400PP_REG_VAL_IRQ_CALL_STACK_UNDERFLOW |\ - MALI400PP_REG_VAL_IRQ_CALL_STACK_OVERFLOW |\ - MALI400PP_REG_VAL_IRQ_RESET_COMPLETED)) -#else -#error "No supported mali core defined" -#endif - -#if defined(USING_MALI200) -#define MALI200_REG_VAL_IRQ_MASK_USED ((enum mali200_mgmt_irq) (\ - MALI200_REG_VAL_IRQ_END_OF_FRAME |\ - MALI200_REG_VAL_IRQ_HANG |\ - MALI200_REG_VAL_IRQ_FORCE_HANG |\ - MALI200_REG_VAL_IRQ_BUS_ERROR |\ - MALI200_REG_VAL_IRQ_WRITE_BOUNDARY_ERROR)) -#elif defined(USING_MALI400) || defined(USING_MALI450) -#define MALI200_REG_VAL_IRQ_MASK_USED ((enum mali200_mgmt_irq) (\ - MALI200_REG_VAL_IRQ_END_OF_FRAME |\ - MALI200_REG_VAL_IRQ_HANG |\ - MALI200_REG_VAL_IRQ_FORCE_HANG |\ - MALI200_REG_VAL_IRQ_BUS_ERROR |\ - MALI200_REG_VAL_IRQ_BUS_STOP |\ - MALI200_REG_VAL_IRQ_WRITE_BOUNDARY_ERROR |\ - MALI400PP_REG_VAL_IRQ_INVALID_PLIST_COMMAND |\ - MALI400PP_REG_VAL_IRQ_CALL_STACK_UNDERFLOW |\ - MALI400PP_REG_VAL_IRQ_CALL_STACK_OVERFLOW)) -#else -#error "No supported mali core defined" -#endif - -#define MALI200_REG_VAL_IRQ_MASK_NONE ((enum mali200_mgmt_irq)(0)) - -enum mali200_mgmt_status { - MALI200_REG_VAL_STATUS_RENDERING_ACTIVE = (1<<0), - MALI200_REG_VAL_STATUS_BUS_STOPPED = (1<<4), -}; - -enum mali200_render_unit -{ - MALI200_REG_ADDR_FRAME = 0x0000, - MALI200_REG_ADDR_STACK = 0x0030 -}; - -#if defined(USING_MALI200) -#define MALI200_NUM_REGS_FRAME ((0x04C/4)+1) -#elif defined(USING_MALI400) -#define MALI200_NUM_REGS_FRAME ((0x058/4)+1) -#elif defined(USING_MALI450) -#define MALI200_NUM_REGS_FRAME ((0x058/4)+1) -#else -#error "No supported mali core defined" -#endif - -enum mali200_wb_unit { - MALI200_REG_ADDR_WB0 = 0x0100, - MALI200_REG_ADDR_WB1 = 0x0200, - MALI200_REG_ADDR_WB2 = 0x0300 -}; - -enum mali200_wb_unit_regs { - MALI200_REG_ADDR_WB_SOURCE_SELECT = 0x0000, -}; - -/** The number of registers in one single writeback unit */ -#ifndef MALI200_NUM_REGS_WBx -#define MALI200_NUM_REGS_WBx ((0x02C/4)+1) -#endif - -/* This should be in the top 16 bit of the version register of Mali PP */ -#define MALI200_PP_PRODUCT_ID 0xC807 -#define MALI300_PP_PRODUCT_ID 0xCE07 -#define MALI400_PP_PRODUCT_ID 0xCD07 -#define MALI450_PP_PRODUCT_ID 0xCF07 - - -#endif /* _MALI200_REGS_H_ */ diff --git a/drivers/media/video/samsung/mali/regs/mali_gp_regs.h b/drivers/media/video/samsung/mali/regs/mali_gp_regs.h deleted file mode 100644 index 21c83c0..0000000 --- a/drivers/media/video/samsung/mali/regs/mali_gp_regs.h +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef _MALIGP2_CONROL_REGS_H_ -#define _MALIGP2_CONROL_REGS_H_ - -/** - * These are the different geometry processor control registers. - * Their usage is to control and monitor the operation of the - * Vertex Shader and the Polygon List Builder in the geometry processor. - * Addresses are in 32-bit word relative sizes. - * @see [P0081] "Geometry Processor Data Structures" for details - */ - -typedef enum { - MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR = 0x00, - MALIGP2_REG_ADDR_MGMT_VSCL_END_ADDR = 0x04, - MALIGP2_REG_ADDR_MGMT_PLBUCL_START_ADDR = 0x08, - MALIGP2_REG_ADDR_MGMT_PLBUCL_END_ADDR = 0x0c, - MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR = 0x10, - MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR = 0x14, - MALIGP2_REG_ADDR_MGMT_CMD = 0x20, - MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT = 0x24, - MALIGP2_REG_ADDR_MGMT_INT_CLEAR = 0x28, - MALIGP2_REG_ADDR_MGMT_INT_MASK = 0x2C, - MALIGP2_REG_ADDR_MGMT_INT_STAT = 0x30, - MALIGP2_REG_ADDR_MGMT_WRITE_BOUND_LOW = 0x34, - MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE = 0x3C, - MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE = 0x40, - MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC = 0x44, - MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC = 0x48, - MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE = 0x4C, - MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE = 0x50, - MALIGP2_REG_ADDR_MGMT_STATUS = 0x68, - MALIGP2_REG_ADDR_MGMT_VERSION = 0x6C, - MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR_READ = 0x80, - MALIGP2_REG_ADDR_MGMT_PLBCL_START_ADDR_READ = 0x84, - MALIGP2_CONTR_AXI_BUS_ERROR_STAT = 0x94, - MALIGP2_REGISTER_ADDRESS_SPACE_SIZE = 0x98, -} maligp_reg_addr_mgmt_addr; - -#define MALIGP2_REG_VAL_PERF_CNT_ENABLE 1 - -/** - * Commands to geometry processor. - * @see MALIGP2_CTRL_REG_CMD - */ -typedef enum -{ - MALIGP2_REG_VAL_CMD_START_VS = (1<< 0), - MALIGP2_REG_VAL_CMD_START_PLBU = (1<< 1), - MALIGP2_REG_VAL_CMD_UPDATE_PLBU_ALLOC = (1<< 4), - MALIGP2_REG_VAL_CMD_RESET = (1<< 5), - MALIGP2_REG_VAL_CMD_FORCE_HANG = (1<< 6), - MALIGP2_REG_VAL_CMD_STOP_BUS = (1<< 9), -#if defined(USING_MALI400) || defined(USING_MALI450) - MALI400GP_REG_VAL_CMD_SOFT_RESET = (1<<10), -#endif -} mgp_contr_reg_val_cmd; - - -/** @defgroup MALIGP2_IRQ - * Interrupt status of geometry processor. - * @see MALIGP2_CTRL_REG_INT_RAWSTAT, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, - * MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_ADDR_MGMT_INT_STAT - * @{ - */ -#define MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST (1 << 0) -#define MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST (1 << 1) -#define MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM (1 << 2) -#define MALIGP2_REG_VAL_IRQ_VS_SEM_IRQ (1 << 3) -#define MALIGP2_REG_VAL_IRQ_PLBU_SEM_IRQ (1 << 4) -#define MALIGP2_REG_VAL_IRQ_HANG (1 << 5) -#define MALIGP2_REG_VAL_IRQ_FORCE_HANG (1 << 6) -#define MALIGP2_REG_VAL_IRQ_PERF_CNT_0_LIMIT (1 << 7) -#define MALIGP2_REG_VAL_IRQ_PERF_CNT_1_LIMIT (1 << 8) -#define MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR (1 << 9) -#define MALIGP2_REG_VAL_IRQ_SYNC_ERROR (1 << 10) -#define MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR (1 << 11) -#if defined(USING_MALI400) || defined(USING_MALI450) -#define MALI400GP_REG_VAL_IRQ_AXI_BUS_STOPPED (1 << 12) -#define MALI400GP_REG_VAL_IRQ_VS_INVALID_CMD (1 << 13) -#define MALI400GP_REG_VAL_IRQ_PLB_INVALID_CMD (1 << 14) -#define MALI400GP_REG_VAL_IRQ_RESET_COMPLETED (1 << 19) -#define MALI400GP_REG_VAL_IRQ_SEMAPHORE_UNDERFLOW (1 << 20) -#define MALI400GP_REG_VAL_IRQ_SEMAPHORE_OVERFLOW (1 << 21) -#define MALI400GP_REG_VAL_IRQ_PTR_ARRAY_OUT_OF_BOUNDS (1 << 22) -#elif !defined USING_MALI200 -#error "No supported mali core defined" -#endif - -/* Mask defining all IRQs in MaliGP2 */ -#if defined(USING_MALI200) -#define MALIGP2_REG_VAL_IRQ_MASK_ALL \ - (\ - MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | \ - MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST | \ - MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | \ - MALIGP2_REG_VAL_IRQ_VS_SEM_IRQ | \ - MALIGP2_REG_VAL_IRQ_PLBU_SEM_IRQ | \ - MALIGP2_REG_VAL_IRQ_HANG | \ - MALIGP2_REG_VAL_IRQ_FORCE_HANG | \ - MALIGP2_REG_VAL_IRQ_PERF_CNT_0_LIMIT | \ - MALIGP2_REG_VAL_IRQ_PERF_CNT_1_LIMIT | \ - MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR | \ - MALIGP2_REG_VAL_IRQ_SYNC_ERROR | \ - MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR) -#elif defined(USING_MALI400) || defined(USING_MALI450) -#define MALIGP2_REG_VAL_IRQ_MASK_ALL \ - (\ - MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | \ - MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST | \ - MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | \ - MALIGP2_REG_VAL_IRQ_VS_SEM_IRQ | \ - MALIGP2_REG_VAL_IRQ_PLBU_SEM_IRQ | \ - MALIGP2_REG_VAL_IRQ_HANG | \ - MALIGP2_REG_VAL_IRQ_FORCE_HANG | \ - MALIGP2_REG_VAL_IRQ_PERF_CNT_0_LIMIT | \ - MALIGP2_REG_VAL_IRQ_PERF_CNT_1_LIMIT | \ - MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR | \ - MALIGP2_REG_VAL_IRQ_SYNC_ERROR | \ - MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR | \ - MALI400GP_REG_VAL_IRQ_AXI_BUS_STOPPED | \ - MALI400GP_REG_VAL_IRQ_VS_INVALID_CMD | \ - MALI400GP_REG_VAL_IRQ_PLB_INVALID_CMD | \ - MALI400GP_REG_VAL_IRQ_RESET_COMPLETED | \ - MALI400GP_REG_VAL_IRQ_SEMAPHORE_UNDERFLOW | \ - MALI400GP_REG_VAL_IRQ_SEMAPHORE_OVERFLOW | \ - MALI400GP_REG_VAL_IRQ_PTR_ARRAY_OUT_OF_BOUNDS) -#else -#error "No supported mali core defined" -#endif - -/* Mask defining the IRQs in MaliGP2 which we use*/ -#if defined(USING_MALI200) -#define MALIGP2_REG_VAL_IRQ_MASK_USED \ - (\ - MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | \ - MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST | \ - MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | \ - MALIGP2_REG_VAL_IRQ_HANG | \ - MALIGP2_REG_VAL_IRQ_FORCE_HANG | \ - MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR | \ - MALIGP2_REG_VAL_IRQ_SYNC_ERROR | \ - MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR) -#elif defined(USING_MALI400) || defined(USING_MALI450) -#define MALIGP2_REG_VAL_IRQ_MASK_USED \ - (\ - MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | \ - MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST | \ - MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | \ - MALIGP2_REG_VAL_IRQ_HANG | \ - MALIGP2_REG_VAL_IRQ_FORCE_HANG | \ - MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR | \ - MALIGP2_REG_VAL_IRQ_SYNC_ERROR | \ - MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR | \ - MALI400GP_REG_VAL_IRQ_VS_INVALID_CMD | \ - MALI400GP_REG_VAL_IRQ_PLB_INVALID_CMD | \ - MALI400GP_REG_VAL_IRQ_SEMAPHORE_UNDERFLOW | \ - MALI400GP_REG_VAL_IRQ_SEMAPHORE_OVERFLOW | \ - MALI400GP_REG_VAL_IRQ_PTR_ARRAY_OUT_OF_BOUNDS) -#else -#error "No supported mali core defined" -#endif - -/* Mask defining non IRQs on MaliGP2*/ -#define MALIGP2_REG_VAL_IRQ_MASK_NONE 0 - -/** }@ defgroup MALIGP2_IRQ*/ - -/** @defgroup MALIGP2_STATUS - * The different Status values to the geometry processor. - * @see MALIGP2_CTRL_REG_STATUS - * @{ - */ -#define MALIGP2_REG_VAL_STATUS_VS_ACTIVE 0x0002 -#define MALIGP2_REG_VAL_STATUS_BUS_STOPPED 0x0004 -#define MALIGP2_REG_VAL_STATUS_PLBU_ACTIVE 0x0008 -#define MALIGP2_REG_VAL_STATUS_BUS_ERROR 0x0040 -#define MALIGP2_REG_VAL_STATUS_WRITE_BOUND_ERR 0x0100 -/** }@ defgroup MALIGP2_STATUS*/ - -#define MALIGP2_REG_VAL_STATUS_MASK_ACTIVE (\ - MALIGP2_REG_VAL_STATUS_VS_ACTIVE|\ - MALIGP2_REG_VAL_STATUS_PLBU_ACTIVE) - - -#define MALIGP2_REG_VAL_STATUS_MASK_ERROR (\ - MALIGP2_REG_VAL_STATUS_BUS_ERROR |\ - MALIGP2_REG_VAL_STATUS_WRITE_BOUND_ERR ) - -/* This should be in the top 16 bit of the version register of gp.*/ -#define MALI200_GP_PRODUCT_ID 0xA07 -#define MALI300_GP_PRODUCT_ID 0xC07 -#define MALI400_GP_PRODUCT_ID 0xB07 -#define MALI450_GP_PRODUCT_ID 0xD07 - -/** - * The different sources for instrumented on the geometry processor. - * @see MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC - */ - -enum MALIGP2_cont_reg_perf_cnt_src { - MALIGP2_REG_VAL_PERF_CNT1_SRC_NUMBER_OF_VERTICES_PROCESSED = 0x0a, -}; - -#endif diff --git a/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.c b/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.c deleted file mode 100644 index 2426853..0000000 --- a/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_timestamp.h" - -/* This file is intentionally left empty, as all functions are inlined in mali_profiling_sampler.h */ diff --git a/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.h b/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.h deleted file mode 100644 index 0551726..0000000 --- a/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_TIMESTAMP_H__ -#define __MALI_TIMESTAMP_H__ - -#include "mali_osk.h" - -MALI_STATIC_INLINE _mali_osk_errcode_t _mali_timestamp_reset(void) -{ - /* - * reset counters and overflow flags - */ - - u32 mask = (1 << 0) | /* enable all three counters */ - (0 << 1) | /* reset both Count Registers to 0x0 */ - (1 << 2) | /* reset the Cycle Counter Register to 0x0 */ - (0 << 3) | /* 1 = Cycle Counter Register counts every 64th processor clock cycle */ - (0 << 4) | /* Count Register 0 interrupt enable */ - (0 << 5) | /* Count Register 1 interrupt enable */ - (0 << 6) | /* Cycle Counter interrupt enable */ - (0 << 8) | /* Count Register 0 overflow flag (clear or write, flag on read) */ - (0 << 9) | /* Count Register 1 overflow flag (clear or write, flag on read) */ - (1 << 10); /* Cycle Counter Register overflow flag (clear or write, flag on read) */ - - __asm__ __volatile__ ("MCR p15, 0, %0, c15, c12, 0" : : "r" (mask) ); - - return _MALI_OSK_ERR_OK; -} - -MALI_STATIC_INLINE u64 _mali_timestamp_get(void) -{ - u32 result; - - /* this is for the clock cycles */ - __asm__ __volatile__ ("MRC p15, 0, %0, c15, c12, 1" : "=r" (result)); - - return (u64)result; -} - -#endif /* __MALI_TIMESTAMP_H__ */ diff --git a/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.c b/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.c deleted file mode 100644 index 2426853..0000000 --- a/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_timestamp.h" - -/* This file is intentionally left empty, as all functions are inlined in mali_profiling_sampler.h */ diff --git a/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.h b/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.h deleted file mode 100644 index e6d3f2a..0000000 --- a/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_TIMESTAMP_H__ -#define __MALI_TIMESTAMP_H__ - -#include "mali_osk.h" - -MALI_STATIC_INLINE _mali_osk_errcode_t _mali_timestamp_reset(void) -{ - return _MALI_OSK_ERR_OK; -} - -MALI_STATIC_INLINE u64 _mali_timestamp_get(void) -{ - return _mali_osk_time_get_ns(); -} - -#endif /* __MALI_TIMESTAMP_H__ */ diff --git a/drivers/media/video/samsung/ump/Kconfig b/drivers/media/video/samsung/ump/Kconfig deleted file mode 100644 index 9d8e5e6..0000000 --- a/drivers/media/video/samsung/ump/Kconfig +++ /dev/null @@ -1,58 +0,0 @@ - -# -## S3C Multimedia Mali configuration -## -# -# For UMP -config VIDEO_UMP - bool "Enable UMP(Unified Memory Provider)" - default y - ---help--- - This enables UMP memory provider - -config UMP_VCM_ALLOC - depends on VIDEO_UMP && VCM - default y - bool "Enable ump-vcm(virtual contiguous memory) memory" - help - Use VCM(virtual-contiguous-memory) to allocate physical memory. - - -config UMP_R3P1_LSI - bool "Uses the R3P1 as a ump module" - depends on VIDEO_UMP - default n - ---help--- - This uses the r3p1 as a UMP kernel module - -choice -depends on VIDEO_UMP -prompt "UMP MEMEMORY OPTION" -default UMP_OSMEM_ONLY -config UMP_DED_ONLY - bool "ump dedicated memory only" - ---help--- - This enables UMP dedicated memory only option -config UMP_OSMEM_ONLY - bool "ump OS memory only" - ---help--- - This enables UMP OS memory only option -config UMP_VCM_ONLY - bool "ump VCM memory" - ---help--- - This enables UMP VCM memory only option - -endchoice -config UMP_MEM_SIZE -int "UMP Memory Size" - depends on VIDEO_UMP - default "512" - ---help--- - This value is dedicated memory size of UMP (unit is MByte). -# For UMP_DEBUG -config VIDEO_UMP_DEBUG - bool "Enables debug messages" - depends on VIDEO_UMP - default n - help - This enables UMP driver debug messages. diff --git a/drivers/media/video/samsung/ump/Kconfig_module b/drivers/media/video/samsung/ump/Kconfig_module deleted file mode 100644 index 3ae316c..0000000 --- a/drivers/media/video/samsung/ump/Kconfig_module +++ /dev/null @@ -1,16 +0,0 @@ -config UMP - tristate "UMP support" - depends on ARM - ---help--- - This enables support for the UMP memory allocation and sharing API. - - To compile this driver as a module, choose M here: the module will be - called ump. - -config UMP_DEBUG - bool "Enable extra debug in UMP" - depends on UMP - default y - ---help--- - This enabled extra debug checks and messages in UMP. - diff --git a/drivers/media/video/samsung/ump/Makefile b/drivers/media/video/samsung/ump/Makefile deleted file mode 100644 index 3a1aac0..0000000 --- a/drivers/media/video/samsung/ump/Makefile +++ /dev/null @@ -1,93 +0,0 @@ -# -# Copyright (C) 2010-2012 ARM Limited. All rights reserved. -# -# This program is free software and is provided to you under the terms of the GNU General Public License version 2 -# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. -# -# A copy of the licence is included with the program, and can also be obtained from Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# - -ifeq ($(CONFIG_UMP_DED_ONLY),y) -UMP_MEM_SIZE= $(CONFIG_UMP_MEM_SIZE) -USING_MEMORY=0 -endif - -ifeq ($(CONFIG_UMP_OSMEM_ONLY),y) -UMP_MEM_SIZE= $(CONFIG_UMP_MEM_SIZE) -USING_MEMORY=1 -endif - -ifeq ($(CONFIG_UMP_VCM_ONLY),y) -UMP_MEM_SIZE= $(CONFIG_UMP_MEM_SIZE) -USING_MEMORY=2 -endif - - -# For UMP Debug -ifeq ($(CONFIG_VIDEO_UMP_DEBUG),y) -DEFINES += -DDEBUG -endif - -# Set up our defines, which will be passed to gcc -DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER -DEFINES += -DUSING_MEMORY=$(USING_MEMORY) -DEFINES += -DUMP_MEM_SIZE=$(UMP_MEM_SIZE) -DEFINES += -DMALI_STATE_TRACKING=1 - -UDD_FILE_PREFIX := drivers/media/video/samsung/ump/ -KBUILDROOT = - -# linux build system integration - -obj-$(CONFIG_VIDEO_UMP) += ump.o - -# For customer releases the Linux Device Drivers will be provided as ARM proprietary and GPL releases: -# The ARM proprietary product will only include the license/proprietary directory -# The GPL product will only include the license/gpl directory - -INCLUDES += \ - -I$(UDD_FILE_PREFIX)\ - -I$(UDD_FILE_PREFIX)common\ - -I$(UDD_FILE_PREFIX)linux\ - -I$(UDD_FILE_PREFIX)include\ - -I$(UDD_FILE_PREFIX)linux/license/gpl/\ - -I$(UDD_FILE_PREFIX)../mali/common\ - -I$(UDD_FILE_PREFIX)../mali/linux - -OSKFILES+=\ - $(KBUILDROOT)../mali/linux/mali_osk_atomics.o \ - $(KBUILDROOT)../mali/linux/mali_osk_locks.o \ - $(KBUILDROOT)../mali/linux/mali_osk_math.o \ - $(KBUILDROOT)../mali/linux/mali_osk_memory.o \ - $(KBUILDROOT)../mali/linux/mali_osk_misc.o - -ump-y := \ - $(KBUILDROOT)linux/ump_kernel_linux.o \ - $(KBUILDROOT)linux/ump_kernel_memory_backend_os.o \ - $(KBUILDROOT)linux/ump_kernel_memory_backend_dedicated.o \ - $(KBUILDROOT)linux/ump_memory_backend.o \ - $(KBUILDROOT)linux/ump_ukk_wrappers.o \ - $(KBUILDROOT)linux/ump_ukk_ref_wrappers.o \ - $(KBUILDROOT)linux/ump_osk_atomics.o \ - $(KBUILDROOT)linux/ump_osk_low_level_mem.o \ - $(KBUILDROOT)linux/ump_osk_misc.o \ - $(KBUILDROOT)common/ump_kernel_common.o \ - $(KBUILDROOT)common/ump_kernel_descriptor_mapping.o \ - $(KBUILDROOT)common/ump_kernel_api.o \ - $(KBUILDROOT)common/ump_kernel_ref_drv.o\ - $(OSKFILES) - -ump-$(CONFIG_UMP_VCM_ALLOC) += \ - $(KBUILDROOT)linux/ump_kernel_memory_backend_vcm.o \ - -EXTRA_CFLAGS += $(INCLUDES) \ - $(DEFINES) - - -# Get subversion revision number, fall back to 0000 if no svn info is available -SVN_REV:=$(shell ((svnversion | grep -E "^[0-9]+" && echo -n 'Revision: ' && svnversion) || git svn info | sed -e 's/$$$$/M/' | grep '^Revision: ' || echo ${MALI_RELEASE_NAME}) 2>/dev/null | sed -e 's/^Revision: //') - -EXTRA_CFLAGS += -DSVN_REV=$(SVN_REV) -EXTRA_CFLAGS += -DSVN_REV_STRING=\"$(SVN_REV)\" - diff --git a/drivers/media/video/samsung/ump/Makefile.common b/drivers/media/video/samsung/ump/Makefile.common deleted file mode 100644 index 26a3d6c..0000000 --- a/drivers/media/video/samsung/ump/Makefile.common +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright (C) 2010-2012 ARM Limited. All rights reserved. -# -# This program is free software and is provided to you under the terms of the GNU General Public License version 2 -# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. -# -# A copy of the licence is included with the program, and can also be obtained from Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# - -SRC = $(UMP_FILE_PREFIX)common/ump_kernel_common.c \ - $(UMP_FILE_PREFIX)common/ump_kernel_descriptor_mapping.c \ - $(UMP_FILE_PREFIX)common/ump_kernel_api.c \ - $(UMP_FILE_PREFIX)common/ump_kernel_ref_drv.c - -# Get subversion revision number, fall back to 0000 if no svn info is available -SVN_REV:=$(shell ((svnversion | grep -E "^[0-9]+" && echo -n 'Revision: ' && svnversion) || git svn info | sed -e 's/$$$$/M/' | grep '^Revision: ' || echo ${MALI_RELEASE_NAME}) 2>/dev/null | sed -e 's/^Revision: //') - -EXTRA_CFLAGS += -DSVN_REV=$(SVN_REV) -EXTRA_CFLAGS += -DSVN_REV_STRING=\"$(SVN_REV)\" diff --git a/drivers/media/video/samsung/ump/arch b/drivers/media/video/samsung/ump/arch deleted file mode 120000 index 58ffbe7..0000000 --- a/drivers/media/video/samsung/ump/arch +++ /dev/null @@ -1 +0,0 @@ -arch-release \ No newline at end of file diff --git a/drivers/media/video/samsung/ump/arch-debug b/drivers/media/video/samsung/ump/arch-debug deleted file mode 120000 index 0ed0909..0000000 --- a/drivers/media/video/samsung/ump/arch-debug +++ /dev/null @@ -1 +0,0 @@ -arch-pegasus-m400/ \ No newline at end of file diff --git a/drivers/media/video/samsung/ump/arch-orion-m400/config.h b/drivers/media/video/samsung/ump/arch-orion-m400/config.h deleted file mode 100644 index 7afbca6..0000000 --- a/drivers/media/video/samsung/ump/arch-orion-m400/config.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __ARCH_CONFIG_UMP_H__ -#define __ARCH_CONFIG_UMP_H__ - -#define ARCH_UMP_BACKEND_DEFAULT USING_MEMORY -#if (USING_MEMORY == 0) /* Dedicated Memory */ -#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0x2C000000 -#else -#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0 -#endif - -#define ARCH_UMP_MEMORY_SIZE_DEFAULT UMP_MEM_SIZE*1024*1024 -#endif /* __ARCH_CONFIG_UMP_H__ */ diff --git a/drivers/media/video/samsung/ump/arch-pb-virtex5/config.h b/drivers/media/video/samsung/ump/arch-pb-virtex5/config.h deleted file mode 100644 index 532fc94..0000000 --- a/drivers/media/video/samsung/ump/arch-pb-virtex5/config.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __ARCH_CONFIG_H__ -#define __ARCH_CONFIG_H__ - -#define ARCH_UMP_BACKEND_DEFAULT 0 -#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0xCE000000 -#define ARCH_UMP_MEMORY_SIZE_DEFAULT 32UL * 1024UL * 1024UL - -#endif /* __ARCH_CONFIG_H__ */ diff --git a/drivers/media/video/samsung/ump/arch-pegasus-m400/config.h b/drivers/media/video/samsung/ump/arch-pegasus-m400/config.h deleted file mode 100644 index 7afbca6..0000000 --- a/drivers/media/video/samsung/ump/arch-pegasus-m400/config.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __ARCH_CONFIG_UMP_H__ -#define __ARCH_CONFIG_UMP_H__ - -#define ARCH_UMP_BACKEND_DEFAULT USING_MEMORY -#if (USING_MEMORY == 0) /* Dedicated Memory */ -#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0x2C000000 -#else -#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0 -#endif - -#define ARCH_UMP_MEMORY_SIZE_DEFAULT UMP_MEM_SIZE*1024*1024 -#endif /* __ARCH_CONFIG_UMP_H__ */ diff --git a/drivers/media/video/samsung/ump/arch-release b/drivers/media/video/samsung/ump/arch-release deleted file mode 120000 index 0ed0909..0000000 --- a/drivers/media/video/samsung/ump/arch-release +++ /dev/null @@ -1 +0,0 @@ -arch-pegasus-m400/ \ No newline at end of file diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_api.c b/drivers/media/video/samsung/ump/common/ump_kernel_api.c deleted file mode 100644 index 83f0d30..0000000 --- a/drivers/media/video/samsung/ump/common/ump_kernel_api.c +++ /dev/null @@ -1,551 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_osk.h" -#include "mali_osk_list.h" -#include "ump_osk.h" -#include "ump_uk_types.h" -#include "ump_kernel_interface.h" -#include "ump_kernel_common.h" - - - -/* ---------------- UMP kernel space API functions follows ---------------- */ - - - -UMP_KERNEL_API_EXPORT ump_secure_id ump_dd_secure_id_get(ump_dd_handle memh) -{ - ump_dd_mem * mem = (ump_dd_mem *)memh; - - DEBUG_ASSERT_POINTER(mem); - - DBG_MSG(5, ("Returning secure ID. ID: %u\n", mem->secure_id)); - - return mem->secure_id; -} - - - -UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_secure_id(ump_secure_id secure_id) -{ - ump_dd_mem * mem; - - _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - - DBG_MSG(5, ("Getting handle from secure ID. ID: %u\n", secure_id)); - if (0 != ump_descriptor_mapping_get(device.secure_id_map, (int)secure_id, (void**)&mem)) - { - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - DBG_MSG(1, ("Secure ID not found. ID: %u\n", secure_id)); - return UMP_DD_HANDLE_INVALID; - } - - ump_dd_reference_add(mem); - - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - - return (ump_dd_handle)mem; -} - -UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_get(ump_secure_id secure_id) -{ - ump_dd_mem * mem; - - _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - - DBG_MSG(5, ("Getting handle from secure ID. ID: %u\n", secure_id)); - if (0 != ump_descriptor_mapping_get(device.secure_id_map, (int)secure_id, (void**)&mem)) - { - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - DBG_MSG(1, ("Secure ID not found. ID: %u\n", secure_id)); - return UMP_DD_HANDLE_INVALID; - } - - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - - return (ump_dd_handle)mem; -} - -UMP_KERNEL_API_EXPORT unsigned long ump_dd_phys_block_count_get(ump_dd_handle memh) -{ - ump_dd_mem * mem = (ump_dd_mem*) memh; - - DEBUG_ASSERT_POINTER(mem); - - return mem->nr_blocks; -} - - - -UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_phys_blocks_get(ump_dd_handle memh, ump_dd_physical_block * blocks, unsigned long num_blocks) -{ - ump_dd_mem * mem = (ump_dd_mem *)memh; - - DEBUG_ASSERT_POINTER(mem); - - if (blocks == NULL) - { - DBG_MSG(1, ("NULL parameter in ump_dd_phys_blocks_get()\n")); - return UMP_DD_INVALID; - } - - if (mem->nr_blocks != num_blocks) - { - DBG_MSG(1, ("Specified number of blocks do not match actual number of blocks\n")); - return UMP_DD_INVALID; - } - - DBG_MSG(5, ("Returning physical block information. ID: %u\n", mem->secure_id)); - - _mali_osk_memcpy(blocks, mem->block_array, sizeof(ump_dd_physical_block) * mem->nr_blocks); - - return UMP_DD_SUCCESS; -} - - - -UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_phys_block_get(ump_dd_handle memh, unsigned long index, ump_dd_physical_block * block) -{ - ump_dd_mem * mem = (ump_dd_mem *)memh; - - DEBUG_ASSERT_POINTER(mem); - - if (block == NULL) - { - DBG_MSG(1, ("NULL parameter in ump_dd_phys_block_get()\n")); - return UMP_DD_INVALID; - } - - if (index >= mem->nr_blocks) - { - DBG_MSG(5, ("Invalid index specified in ump_dd_phys_block_get()\n")); - return UMP_DD_INVALID; - } - - DBG_MSG(5, ("Returning physical block information. ID: %u, index: %lu\n", mem->secure_id, index)); - - *block = mem->block_array[index]; - - return UMP_DD_SUCCESS; -} - - - -UMP_KERNEL_API_EXPORT unsigned long ump_dd_size_get(ump_dd_handle memh) -{ - ump_dd_mem * mem = (ump_dd_mem*)memh; - - DEBUG_ASSERT_POINTER(mem); - - DBG_MSG(5, ("Returning size. ID: %u, size: %lu\n", mem->secure_id, mem->size_bytes)); - - return mem->size_bytes; -} - - - -UMP_KERNEL_API_EXPORT void ump_dd_reference_add(ump_dd_handle memh) -{ - ump_dd_mem * mem = (ump_dd_mem*)memh; - int new_ref; - - DEBUG_ASSERT_POINTER(mem); - - new_ref = _ump_osk_atomic_inc_and_read(&mem->ref_count); - - DBG_MSG(5, ("Memory reference incremented. ID: %u, new value: %d\n", mem->secure_id, new_ref)); -} - - - -UMP_KERNEL_API_EXPORT void ump_dd_reference_release(ump_dd_handle memh) -{ - int new_ref; - ump_dd_mem * mem = (ump_dd_mem*)memh; - - DEBUG_ASSERT_POINTER(mem); - - /* We must hold this mutex while doing the atomic_dec_and_read, to protect - that elements in the ump_descriptor_mapping table is always valid. If they - are not, userspace may accidently map in this secure_ids right before its freed - giving a mapped backdoor into unallocated memory.*/ - _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - - new_ref = _ump_osk_atomic_dec_and_read(&mem->ref_count); - - DBG_MSG(5, ("Memory reference decremented. ID: %u, new value: %d\n", mem->secure_id, new_ref)); - - if (0 == new_ref) - { - DBG_MSG(3, ("Final release of memory. ID: %u\n", mem->secure_id)); - - ump_descriptor_mapping_free(device.secure_id_map, (int)mem->secure_id); - - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - mem->release_func(mem->ctx, mem); - _mali_osk_free(mem); - } - else - { - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - } -} - - - -/* --------------- Handling of user space requests follows --------------- */ - - -_mali_osk_errcode_t _ump_uku_get_api_version( _ump_uk_api_version_s *args ) -{ - ump_session_data * session_data; - - DEBUG_ASSERT_POINTER( args ); - DEBUG_ASSERT_POINTER( args->ctx ); - - session_data = (ump_session_data *)args->ctx; - - /* check compatability */ - if (args->version == UMP_IOCTL_API_VERSION) - { - DBG_MSG(3, ("API version set to newest %d (compatible)\n", GET_VERSION(args->version))); - args->compatible = 1; - session_data->api_version = args->version; - } - else if (args->version == MAKE_VERSION_ID(1)) - { - DBG_MSG(2, ("API version set to depricated: %d (compatible)\n", GET_VERSION(args->version))); - args->compatible = 1; - session_data->api_version = args->version; - } - else - { - DBG_MSG(2, ("API version set to %d (incompatible with client version %d)\n", GET_VERSION(UMP_IOCTL_API_VERSION), GET_VERSION(args->version))); - args->compatible = 0; - args->version = UMP_IOCTL_API_VERSION; /* report our version */ - } - - return _MALI_OSK_ERR_OK; -} - - -_mali_osk_errcode_t _ump_ukk_release( _ump_uk_release_s *release_info ) -{ - ump_session_memory_list_element * session_memory_element; - ump_session_memory_list_element * tmp; - ump_session_data * session_data; - _mali_osk_errcode_t ret = _MALI_OSK_ERR_INVALID_FUNC; - int secure_id; - - DEBUG_ASSERT_POINTER( release_info ); - DEBUG_ASSERT_POINTER( release_info->ctx ); - - /* Retreive the session data */ - session_data = (ump_session_data*)release_info->ctx; - - /* If there are many items in the memory session list we - * could be de-referencing this pointer a lot so keep a local copy - */ - secure_id = release_info->secure_id; - - DBG_MSG(4, ("Releasing memory with IOCTL, ID: %u\n", secure_id)); - - /* Iterate through the memory list looking for the requested secure ID */ - _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); - _MALI_OSK_LIST_FOREACHENTRY(session_memory_element, tmp, &session_data->list_head_session_memory_list, ump_session_memory_list_element, list) - { - if ( session_memory_element->mem->secure_id == secure_id) - { - ump_dd_mem *release_mem; - - release_mem = session_memory_element->mem; - _mali_osk_list_del(&session_memory_element->list); - ump_dd_reference_release(release_mem); - _mali_osk_free(session_memory_element); - - ret = _MALI_OSK_ERR_OK; - break; - } - } - - _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); - DBG_MSG_IF(1, _MALI_OSK_ERR_OK != ret, ("UMP memory with ID %u does not belong to this session.\n", secure_id)); - - DBG_MSG(4, ("_ump_ukk_release() returning 0x%x\n", ret)); - return ret; -} - -_mali_osk_errcode_t _ump_ukk_size_get( _ump_uk_size_get_s *user_interaction ) -{ - ump_dd_mem * mem; - _mali_osk_errcode_t ret = _MALI_OSK_ERR_FAULT; - - DEBUG_ASSERT_POINTER( user_interaction ); - - /* We lock the mappings so things don't get removed while we are looking for the memory */ - _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - if (0 == ump_descriptor_mapping_get(device.secure_id_map, (int)user_interaction->secure_id, (void**)&mem)) - { - user_interaction->size = mem->size_bytes; - DBG_MSG(4, ("Returning size. ID: %u, size: %lu ", (ump_secure_id)user_interaction->secure_id, (unsigned long)user_interaction->size)); - ret = _MALI_OSK_ERR_OK; - } - else - { - user_interaction->size = 0; - DBG_MSG(1, ("Failed to look up mapping in ump_ioctl_size_get(). ID: %u\n", (ump_secure_id)user_interaction->secure_id)); - } - - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - return ret; -} - - - -void _ump_ukk_msync( _ump_uk_msync_s *args ) -{ - ump_dd_mem * mem = NULL; - void *virtual = NULL; - u32 size = 0; - u32 offset = 0; - - _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - ump_descriptor_mapping_get(device.secure_id_map, (int)args->secure_id, (void**)&mem); - - if (NULL == mem) - { - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - DBG_MSG(1, ("Failed to look up mapping in _ump_ukk_msync(). ID: %u\n", (ump_secure_id)args->secure_id)); - return; - } - /* Ensure the memory doesn't dissapear when we are flushing it. */ - ump_dd_reference_add(mem); - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - - /* Returns the cache settings back to Userspace */ - args->is_cached=mem->is_cached; - - /* If this flag is the only one set, we should not do the actual flush, only the readout */ - if ( _UMP_UK_MSYNC_READOUT_CACHE_ENABLED==args->op ) - { - DBG_MSG(3, ("_ump_ukk_msync READOUT ID: %u Enabled: %d\n", (ump_secure_id)args->secure_id, mem->is_cached)); - goto msync_release_and_return; - } - - /* Nothing to do if the memory is not caches */ - if ( 0==mem->is_cached ) - { - DBG_MSG(3, ("_ump_ukk_msync IGNORING ID: %u Enabled: %d OP: %d\n", (ump_secure_id)args->secure_id, mem->is_cached, args->op)); - goto msync_release_and_return; - } - DBG_MSG(3, ("UMP[%02u] _ump_ukk_msync Flush OP: %d Address: 0x%08x Mapping: 0x%08x\n", - (ump_secure_id)args->secure_id, args->op, args->address, args->mapping)); - - if ( args->address ) - { - virtual = (void *)((u32)args->address); - offset = (u32)((args->address) - (args->mapping)); - } else { - /* Flush entire mapping when no address is specified. */ - virtual = args->mapping; - } - if ( args->size ) - { - size = args->size; - } else { - /* Flush entire mapping when no size is specified. */ - size = mem->size_bytes - offset; - } - - if ( (offset + size) > mem->size_bytes ) - { - DBG_MSG(1, ("Trying to flush more than the entire UMP allocation: offset: %u + size: %u > %u\n", offset, size, mem->size_bytes)); - goto msync_release_and_return; - } - - /* The actual cache flush - Implemented for each OS*/ - _ump_osk_msync( mem, virtual, offset, size, args->op, NULL); - -msync_release_and_return: - ump_dd_reference_release(mem); - return; -} - -void _ump_ukk_cache_operations_control(_ump_uk_cache_operations_control_s* args) -{ - ump_session_data * session_data; - ump_uk_cache_op_control op; - - DEBUG_ASSERT_POINTER( args ); - DEBUG_ASSERT_POINTER( args->ctx ); - - op = args->op; - session_data = (ump_session_data *)args->ctx; - - _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); - if ( op== _UMP_UK_CACHE_OP_START ) - { - session_data->cache_operations_ongoing++; - DBG_MSG(4, ("Cache ops start\n" )); - if ( session_data->cache_operations_ongoing != 1 ) - { - DBG_MSG(2, ("UMP: Number of simultanious cache control ops: %d\n", session_data->cache_operations_ongoing) ); - } - } - else if ( op== _UMP_UK_CACHE_OP_FINISH ) - { - DBG_MSG(4, ("Cache ops finish\n")); - session_data->cache_operations_ongoing--; - #if 0 - if ( session_data->has_pending_level1_cache_flush) - { - /* This function will set has_pending_level1_cache_flush=0 */ - _ump_osk_msync( NULL, NULL, 0, 0, _UMP_UK_MSYNC_FLUSH_L1, session_data); - } - #endif - - /* to be on the safe side: always flush l1 cache when cache operations are done */ - _ump_osk_msync( NULL, NULL, 0, 0, _UMP_UK_MSYNC_FLUSH_L1, session_data); - DBG_MSG(4, ("Cache ops finish end\n" )); - } - else - { - DBG_MSG(1, ("Illegal call to %s at line %d\n", __FUNCTION__, __LINE__)); - } - _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); - -} - -void _ump_ukk_switch_hw_usage(_ump_uk_switch_hw_usage_s *args ) -{ - ump_dd_mem * mem = NULL; - ump_uk_user old_user; - ump_uk_msync_op cache_op = _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE; - ump_session_data *session_data; - - DEBUG_ASSERT_POINTER( args ); - DEBUG_ASSERT_POINTER( args->ctx ); - - session_data = (ump_session_data *)args->ctx; - - _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - ump_descriptor_mapping_get(device.secure_id_map, (int)args->secure_id, (void**)&mem); - - if (NULL == mem) - { - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - DBG_MSG(1, ("Failed to look up mapping in _ump_ukk_switch_hw_usage(). ID: %u\n", (ump_secure_id)args->secure_id)); - return; - } - - old_user = mem->hw_device; - mem->hw_device = args->new_user; - - DBG_MSG(3, ("UMP[%02u] Switch usage Start New: %s Prev: %s.\n", (ump_secure_id)args->secure_id, args->new_user?"MALI":"CPU",old_user?"MALI":"CPU")); - - if ( ! mem->is_cached ) - { - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - DBG_MSG(3, ("UMP[%02u] Changing owner of uncached memory. Cache flushing not needed.\n", (ump_secure_id)args->secure_id)); - return; - } - - if ( old_user == args->new_user) - { - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - DBG_MSG(4, ("UMP[%02u] Setting the new_user equal to previous for. Cache flushing not needed.\n", (ump_secure_id)args->secure_id)); - return; - } - if ( - /* Previous AND new is both different from CPU */ - (old_user != _UMP_UK_USED_BY_CPU) && (args->new_user != _UMP_UK_USED_BY_CPU ) - ) - { - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - DBG_MSG(4, ("UMP[%02u] Previous and new user is not CPU. Cache flushing not needed.\n", (ump_secure_id)args->secure_id)); - return; - } - - if ( (old_user != _UMP_UK_USED_BY_CPU ) && (args->new_user==_UMP_UK_USED_BY_CPU) ) - { - cache_op =_UMP_UK_MSYNC_INVALIDATE; - DBG_MSG(4, ("UMP[%02u] Cache invalidation needed\n", (ump_secure_id)args->secure_id)); -#ifdef UMP_SKIP_INVALIDATION -#error - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - DBG_MSG(4, ("UMP[%02u] Performing Cache invalidation SKIPPED\n", (ump_secure_id)args->secure_id)); - return; -#endif - } - /* Ensure the memory doesn't dissapear when we are flushing it. */ - ump_dd_reference_add(mem); - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - - /* Take lock to protect: session->cache_operations_ongoing and session->has_pending_level1_cache_flush */ - _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); - /* Actual cache flush */ - _ump_osk_msync( mem, NULL, 0, mem->size_bytes, cache_op, session_data); - _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); - - ump_dd_reference_release(mem); - DBG_MSG(4, ("UMP[%02u] Switch usage Finish\n", (ump_secure_id)args->secure_id)); - return; -} - -void _ump_ukk_lock(_ump_uk_lock_s *args ) -{ - ump_dd_mem * mem = NULL; - - _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - ump_descriptor_mapping_get(device.secure_id_map, (int)args->secure_id, (void**)&mem); - - if (NULL == mem) - { - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - DBG_MSG(1, ("UMP[%02u] Failed to look up mapping in _ump_ukk_lock(). ID: %u\n", (ump_secure_id)args->secure_id)); - return; - } - ump_dd_reference_add(mem); - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - - DBG_MSG(1, ("UMP[%02u] Lock. New lock flag: %d. Old Lock flag:\n", (u32)args->secure_id, (u32)args->lock_usage, (u32) mem->lock_usage )); - - mem->lock_usage = (ump_lock_usage) args->lock_usage; - - /** TODO: TAKE LOCK HERE */ - - ump_dd_reference_release(mem); -} - -void _ump_ukk_unlock(_ump_uk_unlock_s *args ) -{ - ump_dd_mem * mem = NULL; - - _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - ump_descriptor_mapping_get(device.secure_id_map, (int)args->secure_id, (void**)&mem); - - if (NULL == mem) - { - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - DBG_MSG(1, ("Failed to look up mapping in _ump_ukk_unlock(). ID: %u\n", (ump_secure_id)args->secure_id)); - return; - } - ump_dd_reference_add(mem); - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - - DBG_MSG(1, ("UMP[%02u] Unlocking. Old Lock flag:\n", (u32)args->secure_id, (u32) mem->lock_usage )); - - mem->lock_usage = (ump_lock_usage) UMP_NOT_LOCKED; - - /** TODO: RELEASE LOCK HERE */ - - ump_dd_reference_release(mem); -} diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_common.c b/drivers/media/video/samsung/ump/common/ump_kernel_common.c deleted file mode 100644 index a27bc77..0000000 --- a/drivers/media/video/samsung/ump/common/ump_kernel_common.c +++ /dev/null @@ -1,414 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "mali_osk_bitops.h" -#include "mali_osk_list.h" -#include "ump_osk.h" -#include "ump_uk_types.h" -#include "ump_ukk.h" -#include "ump_kernel_common.h" -#include "ump_kernel_descriptor_mapping.h" -#include "ump_kernel_memory_backend.h" - - - -/** - * Define the initial and maximum size of number of secure_ids on the system - */ -#define UMP_SECURE_ID_TABLE_ENTRIES_INITIAL (128 ) -#define UMP_SECURE_ID_TABLE_ENTRIES_MAXIMUM (4096 ) - - -/** - * Define the initial and maximum size of the ump_session_data::cookies_map, - * which is a \ref ump_descriptor_mapping. This limits how many secure_ids - * may be mapped into a particular process using _ump_ukk_map_mem(). - */ - -#define UMP_COOKIES_PER_SESSION_INITIAL (UMP_SECURE_ID_TABLE_ENTRIES_INITIAL ) -#define UMP_COOKIES_PER_SESSION_MAXIMUM (UMP_SECURE_ID_TABLE_ENTRIES_MAXIMUM) - -struct ump_dev device; - -_mali_osk_errcode_t ump_kernel_constructor(void) -{ - _mali_osk_errcode_t err; - - /* Perform OS Specific initialization */ - err = _ump_osk_init(); - if( _MALI_OSK_ERR_OK != err ) - { - MSG_ERR(("Failed to initiaze the UMP Device Driver")); - return err; - } - - /* Init the global device */ - _mali_osk_memset(&device, 0, sizeof(device) ); - - /* Create the descriptor map, which will be used for mapping secure ID to ump_dd_mem structs */ - device.secure_id_map_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0 , 0); - if (NULL == device.secure_id_map_lock) - { - MSG_ERR(("Failed to create OSK lock for secure id lookup table\n")); - return _MALI_OSK_ERR_NOMEM; - } - - device.secure_id_map = ump_descriptor_mapping_create(UMP_SECURE_ID_TABLE_ENTRIES_INITIAL, UMP_SECURE_ID_TABLE_ENTRIES_MAXIMUM); - if (NULL == device.secure_id_map) - { - _mali_osk_lock_term(device.secure_id_map_lock); - MSG_ERR(("Failed to create secure id lookup table\n")); - return _MALI_OSK_ERR_NOMEM; - } - - /* Init memory backend */ - device.backend = ump_memory_backend_create(); - if (NULL == device.backend) - { - MSG_ERR(("Failed to create memory backend\n")); - _mali_osk_lock_term(device.secure_id_map_lock); - ump_descriptor_mapping_destroy(device.secure_id_map); - return _MALI_OSK_ERR_NOMEM; - } - - return _MALI_OSK_ERR_OK; -} - -void ump_kernel_destructor(void) -{ - DEBUG_ASSERT_POINTER(device.secure_id_map); - DEBUG_ASSERT_POINTER(device.secure_id_map_lock); - - _mali_osk_lock_term(device.secure_id_map_lock); - device.secure_id_map_lock = NULL; - - ump_descriptor_mapping_destroy(device.secure_id_map); - device.secure_id_map = NULL; - - device.backend->shutdown(device.backend); - device.backend = NULL; - - ump_memory_backend_destroy(); - - _ump_osk_term(); -} - -/** Creates a new UMP session - */ -_mali_osk_errcode_t _ump_ukk_open( void** context ) -{ - struct ump_session_data * session_data; - - /* allocated struct to track this session */ - session_data = (struct ump_session_data *)_mali_osk_malloc(sizeof(struct ump_session_data)); - if (NULL == session_data) - { - MSG_ERR(("Failed to allocate ump_session_data in ump_file_open()\n")); - return _MALI_OSK_ERR_NOMEM; - } - - session_data->lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, 0); - if( NULL == session_data->lock ) - { - MSG_ERR(("Failed to initialize lock for ump_session_data in ump_file_open()\n")); - _mali_osk_free(session_data); - return _MALI_OSK_ERR_NOMEM; - } - - session_data->cookies_map = ump_descriptor_mapping_create( UMP_COOKIES_PER_SESSION_INITIAL, UMP_COOKIES_PER_SESSION_MAXIMUM ); - - if ( NULL == session_data->cookies_map ) - { - MSG_ERR(("Failed to create descriptor mapping for _ump_ukk_map_mem cookies\n")); - - _mali_osk_lock_term( session_data->lock ); - _mali_osk_free( session_data ); - return _MALI_OSK_ERR_NOMEM; - } - - _MALI_OSK_INIT_LIST_HEAD(&session_data->list_head_session_memory_list); - - _MALI_OSK_INIT_LIST_HEAD(&session_data->list_head_session_memory_mappings_list); - - /* Since initial version of the UMP interface did not use the API_VERSION ioctl we have to assume - that it is this version, and not the "latest" one: UMP_IOCTL_API_VERSION - Current and later API versions would do an additional call to this IOCTL and update this variable - to the correct one.*/ - session_data->api_version = MAKE_VERSION_ID(1); - - *context = (void*)session_data; - - session_data->cache_operations_ongoing = 0 ; - session_data->has_pending_level1_cache_flush = 0; - - DBG_MSG(2, ("New session opened\n")); - - return _MALI_OSK_ERR_OK; -} - -_mali_osk_errcode_t _ump_ukk_close( void** context ) -{ - struct ump_session_data * session_data; - ump_session_memory_list_element * item; - ump_session_memory_list_element * tmp; - - session_data = (struct ump_session_data *)*context; - if (NULL == session_data) - { - MSG_ERR(("Session data is NULL in _ump_ukk_close()\n")); - return _MALI_OSK_ERR_INVALID_ARGS; - } - - /* Unmap any descriptors mapped in. */ - if (0 == _mali_osk_list_empty(&session_data->list_head_session_memory_mappings_list)) - { - ump_memory_allocation *descriptor; - ump_memory_allocation *temp; - - DBG_MSG(1, ("Memory mappings found on session usage list during session termination\n")); - - /* use the 'safe' list iterator, since freeing removes the active block from the list we're iterating */ - _MALI_OSK_LIST_FOREACHENTRY(descriptor, temp, &session_data->list_head_session_memory_mappings_list, ump_memory_allocation, list) - { - _ump_uk_unmap_mem_s unmap_args; - DBG_MSG(4, ("Freeing block with phys address 0x%x size 0x%x mapped in user space at 0x%x\n", - descriptor->phys_addr, descriptor->size, descriptor->mapping)); - unmap_args.ctx = (void*)session_data; - unmap_args.mapping = descriptor->mapping; - unmap_args.size = descriptor->size; - unmap_args._ukk_private = NULL; /* NOTE: unused */ - unmap_args.cookie = descriptor->cookie; - - /* NOTE: This modifies the list_head_session_memory_mappings_list */ - _ump_ukk_unmap_mem( &unmap_args ); - } - } - - /* ASSERT that we really did free everything, because _ump_ukk_unmap_mem() - * can fail silently. */ - DEBUG_ASSERT( _mali_osk_list_empty(&session_data->list_head_session_memory_mappings_list) ); - - _MALI_OSK_LIST_FOREACHENTRY(item, tmp, &session_data->list_head_session_memory_list, ump_session_memory_list_element, list) - { - _mali_osk_list_del(&item->list); - DBG_MSG(2, ("Releasing UMP memory %u as part of file close\n", item->mem->secure_id)); - ump_dd_reference_release(item->mem); - _mali_osk_free(item); - } - - ump_descriptor_mapping_destroy( session_data->cookies_map ); - - _mali_osk_lock_term(session_data->lock); - _mali_osk_free(session_data); - - DBG_MSG(2, ("Session closed\n")); - - return _MALI_OSK_ERR_OK; -} - -_mali_osk_errcode_t _ump_ukk_map_mem( _ump_uk_map_mem_s *args ) -{ - struct ump_session_data * session_data; - ump_memory_allocation * descriptor; /* Describes current mapping of memory */ - _mali_osk_errcode_t err; - unsigned long offset = 0; - unsigned long left; - ump_dd_handle handle; /* The real UMP handle for this memory. Its real datatype is ump_dd_mem* */ - ump_dd_mem * mem; /* The real UMP memory. It is equal to the handle, but with exposed struct */ - u32 block; - int map_id; - - session_data = (ump_session_data *)args->ctx; - if( NULL == session_data ) - { - MSG_ERR(("Session data is NULL in _ump_ukk_map_mem()\n")); - return _MALI_OSK_ERR_INVALID_ARGS; - } - /* SEC kernel stability 2012-02-17 */ - if (NULL == session_data->cookies_map) - { - MSG_ERR(("session_data->cookies_map is NULL in _ump_ukk_map_mem()\n")); - return _MALI_OSK_ERR_INVALID_ARGS; - } - descriptor = (ump_memory_allocation*) _mali_osk_calloc( 1, sizeof(ump_memory_allocation)); - if (NULL == descriptor) - { - MSG_ERR(("ump_ukk_map_mem: descriptor allocation failed\n")); - return _MALI_OSK_ERR_NOMEM; - } - - handle = ump_dd_handle_create_from_secure_id(args->secure_id); - if ( UMP_DD_HANDLE_INVALID == handle) - { - _mali_osk_free(descriptor); - DBG_MSG(1, ("Trying to map unknown secure ID %u\n", args->secure_id)); - return _MALI_OSK_ERR_FAULT; - } - - mem = (ump_dd_mem*)handle; - DEBUG_ASSERT(mem); - if (mem->size_bytes != args->size) - { - _mali_osk_free(descriptor); - ump_dd_reference_release(handle); - DBG_MSG(1, ("Trying to map too much or little. ID: %u, virtual size=%lu, UMP size: %lu\n", args->secure_id, args->size, mem->size_bytes)); - return _MALI_OSK_ERR_FAULT; - } - - map_id = ump_descriptor_mapping_allocate_mapping( session_data->cookies_map, (void*) descriptor ); - - if (map_id < 0) - { - _mali_osk_free(descriptor); - ump_dd_reference_release(handle); - DBG_MSG(1, ("ump_ukk_map_mem: unable to allocate a descriptor_mapping for return cookie\n")); - - return _MALI_OSK_ERR_NOMEM; - } - - descriptor->size = args->size; - descriptor->handle = handle; - descriptor->phys_addr = args->phys_addr; - descriptor->process_mapping_info = args->_ukk_private; - descriptor->ump_session = session_data; - descriptor->cookie = (u32)map_id; - - if ( mem->is_cached ) - { - descriptor->is_cached = 1; - args->is_cached = 1; - DBG_MSG(3, ("Mapping UMP secure_id: %d as cached.\n", args->secure_id)); - } - else if ( args->is_cached) - { - mem->is_cached = 1; - descriptor->is_cached = 1; - DBG_MSG(3, ("Warning mapping UMP secure_id: %d. As cached, while it was allocated uncached.\n", args->secure_id)); - } - else - { - descriptor->is_cached = 0; - args->is_cached = 0; - DBG_MSG(3, ("Mapping UMP secure_id: %d as Uncached.\n", args->secure_id)); - } - - _mali_osk_list_init( &descriptor->list ); - - err = _ump_osk_mem_mapregion_init( descriptor ); - if( _MALI_OSK_ERR_OK != err ) - { - DBG_MSG(1, ("Failed to initialize memory mapping in _ump_ukk_map_mem(). ID: %u\n", args->secure_id)); - ump_descriptor_mapping_free( session_data->cookies_map, map_id ); - _mali_osk_free(descriptor); - ump_dd_reference_release(mem); - return err; - } - - DBG_MSG(4, ("Mapping virtual to physical memory: ID: %u, size:%lu, first physical addr: 0x%08lx, number of regions: %lu\n", - mem->secure_id, - mem->size_bytes, - ((NULL != mem->block_array) ? mem->block_array->addr : 0), - mem->nr_blocks)); - - left = descriptor->size; - /* loop over all blocks and map them in */ - for (block = 0; block < mem->nr_blocks; block++) - { - unsigned long size_to_map; - - if (left > mem->block_array[block].size) - { - size_to_map = mem->block_array[block].size; - } - else - { - size_to_map = left; - } - - if (_MALI_OSK_ERR_OK != _ump_osk_mem_mapregion_map(descriptor, offset, (u32 *)&(mem->block_array[block].addr), size_to_map ) ) - { - DBG_MSG(1, ("WARNING: _ump_ukk_map_mem failed to map memory into userspace\n")); - ump_descriptor_mapping_free( session_data->cookies_map, map_id ); - ump_dd_reference_release(mem); - _ump_osk_mem_mapregion_term( descriptor ); - _mali_osk_free(descriptor); - return _MALI_OSK_ERR_FAULT; - } - left -= size_to_map; - offset += size_to_map; - } - - /* Add to the ump_memory_allocation tracking list */ - _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); - _mali_osk_list_add( &descriptor->list, &session_data->list_head_session_memory_mappings_list ); - _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); - - args->mapping = descriptor->mapping; - args->cookie = descriptor->cookie; - - return _MALI_OSK_ERR_OK; -} - -void _ump_ukk_unmap_mem( _ump_uk_unmap_mem_s *args ) -{ - struct ump_session_data * session_data; - ump_memory_allocation * descriptor; - ump_dd_handle handle; - - session_data = (ump_session_data *)args->ctx; - - if( NULL == session_data ) - { - MSG_ERR(("Session data is NULL in _ump_ukk_map_mem()\n")); - return; - } - /* SEC kernel stability 2012-02-17 */ - if (NULL == session_data->cookies_map) - { - MSG_ERR(("session_data->cookies_map is NULL in _ump_ukk_map_mem()\n")); - return; - } - if (0 != ump_descriptor_mapping_get( session_data->cookies_map, (int)args->cookie, (void**)&descriptor) ) - { - MSG_ERR(("_ump_ukk_map_mem: cookie 0x%X not found for this session\n", args->cookie )); - return; - } - - DEBUG_ASSERT_POINTER(descriptor); - - handle = descriptor->handle; - if ( UMP_DD_HANDLE_INVALID == handle) - { - DBG_MSG(1, ("WARNING: Trying to unmap unknown handle: UNKNOWN\n")); - return; - } - - /* Remove the ump_memory_allocation from the list of tracked mappings */ - _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); - _mali_osk_list_del( &descriptor->list ); - _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); - - ump_descriptor_mapping_free( session_data->cookies_map, (int)args->cookie ); - - ump_dd_reference_release(handle); - - _ump_osk_mem_mapregion_term( descriptor ); - _mali_osk_free(descriptor); -} - -u32 _ump_ukk_report_memory_usage( void ) -{ - if(device.backend->stat) - return device.backend->stat(device.backend); - else - return 0; -} diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_common.h b/drivers/media/video/samsung/ump/common/ump_kernel_common.h deleted file mode 100644 index 6e3a2e9..0000000 --- a/drivers/media/video/samsung/ump/common/ump_kernel_common.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __UMP_KERNEL_COMMON_H__ -#define __UMP_KERNEL_COMMON_H__ - -#include "ump_kernel_types.h" -#include "ump_kernel_interface.h" -#include "ump_kernel_descriptor_mapping.h" -#include "ump_kernel_memory_backend.h" - - -#ifdef DEBUG - extern int ump_debug_level; - #define UMP_DEBUG_PRINT(args) _mali_osk_dbgmsg args - #define UMP_DEBUG_CODE(args) args - #define DBG_MSG(level,args) do { /* args should be in brackets */ \ - ((level) <= ump_debug_level)?\ - UMP_DEBUG_PRINT(("UMP<" #level ">: ")), \ - UMP_DEBUG_PRINT(args):0; \ - } while (0) - - #define DBG_MSG_IF(level,condition,args) /* args should be in brackets */ \ - if((condition)&&((level) <= ump_debug_level)) {\ - UMP_DEBUG_PRINT(("UMP<" #level ">: ")); \ - UMP_DEBUG_PRINT(args); \ - } - - #define DBG_MSG_ELSE(level,args) /* args should be in brackets */ \ - else if((level) <= ump_debug_level) { \ - UMP_DEBUG_PRINT(("UMP<" #level ">: ")); \ - UMP_DEBUG_PRINT(args); \ - } - - #define DEBUG_ASSERT_POINTER(pointer) do {if( (pointer)== NULL) MSG_ERR(("NULL pointer " #pointer)); } while(0) - #define DEBUG_ASSERT(condition) do {if(!(condition)) MSG_ERR(("ASSERT failed: " #condition)); } while(0) -#else /* DEBUG */ - #define UMP_DEBUG_PRINT(args) do {} while(0) - #define UMP_DEBUG_CODE(args) - #define DBG_MSG(level,args) do {} while(0) - #define DBG_MSG_IF(level,condition,args) do {} while(0) - #define DBG_MSG_ELSE(level,args) do {} while(0) - #define DEBUG_ASSERT(condition) do {} while(0) - #define DEBUG_ASSERT_POINTER(pointer) do {} while(0) -#endif /* DEBUG */ - -#define MSG_ERR(args) do{ /* args should be in brackets */ \ - _mali_osk_dbgmsg("UMP: ERR: %s\n" ,__FILE__); \ - _mali_osk_dbgmsg( " %s()%4d\n", __FUNCTION__, __LINE__) ; \ - _mali_osk_dbgmsg args ; \ - _mali_osk_dbgmsg("\n"); \ - } while(0) - -#define MSG(args) do{ /* args should be in brackets */ \ - _mali_osk_dbgmsg("UMP: "); \ - _mali_osk_dbgmsg args; \ - } while (0) - - - -/* - * This struct is used to store per session data. - * A session is created when someone open() the device, and - * closed when someone close() it or the user space application terminates. - */ -typedef struct ump_session_data -{ - _mali_osk_list_t list_head_session_memory_list; /**< List of ump allocations made by the process (elements are ump_session_memory_list_element) */ - _mali_osk_list_t list_head_session_memory_mappings_list; /**< List of ump_memory_allocations mapped in */ - int api_version; - _mali_osk_lock_t * lock; - ump_descriptor_mapping * cookies_map; /**< Secure mapping of cookies from _ump_ukk_map_mem() */ - int cache_operations_ongoing; - int has_pending_level1_cache_flush; -} ump_session_data; - - - -/* - * This struct is used to track the UMP memory references a session has. - * We need to track this in order to be able to clean up after user space processes - * which don't do it themself (e.g. due to a crash or premature termination). - */ -typedef struct ump_session_memory_list_element -{ - struct ump_dd_mem * mem; - _mali_osk_list_t list; -} ump_session_memory_list_element; - - - -/* - * Device specific data, created when device driver is loaded, and then kept as the global variable device. - */ -typedef struct ump_dev -{ - _mali_osk_lock_t * secure_id_map_lock; - ump_descriptor_mapping * secure_id_map; - ump_memory_backend * backend; -} ump_dev; - - - -extern int ump_debug_level; -extern struct ump_dev device; - -_mali_osk_errcode_t ump_kernel_constructor(void); -void ump_kernel_destructor(void); -int map_errcode( _mali_osk_errcode_t err ); - -/** - * variables from user space cannot be dereferenced from kernel space; tagging them - * with __user allows the GCC compiler to generate a warning. Other compilers may - * not support this so we define it here as an empty macro if the compiler doesn't - * define it. - */ -#ifndef __user -#define __user -#endif - -#endif /* __UMP_KERNEL_COMMON_H__ */ diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.c b/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.c deleted file mode 100644 index cc7b8be..0000000 --- a/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "mali_osk_bitops.h" -#include "ump_kernel_common.h" -#include "ump_kernel_descriptor_mapping.h" - -#define MALI_PAD_INT(x) (((x) + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1)) - -/** - * Allocate a descriptor table capable of holding 'count' mappings - * @param count Number of mappings in the table - * @return Pointer to a new table, NULL on error - */ -static ump_descriptor_table * descriptor_table_alloc(int count); - -/** - * Free a descriptor table - * @param table The table to free - */ -static void descriptor_table_free(ump_descriptor_table * table); - -ump_descriptor_mapping * ump_descriptor_mapping_create(int init_entries, int max_entries) -{ - ump_descriptor_mapping * map = _mali_osk_calloc(1, sizeof(ump_descriptor_mapping) ); - - init_entries = MALI_PAD_INT(init_entries); - max_entries = MALI_PAD_INT(max_entries); - - if (NULL != map) - { - map->table = descriptor_table_alloc(init_entries); - if (NULL != map->table) - { - map->lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_READERWRITER, 0 , 0); - if ( NULL != map->lock ) - { - _mali_osk_set_nonatomic_bit(0, map->table->usage); /* reserve bit 0 to prevent NULL/zero logic to kick in */ - map->max_nr_mappings_allowed = max_entries; - map->current_nr_mappings = init_entries; - return map; - } - descriptor_table_free(map->table); - } - _mali_osk_free(map); - } - return NULL; -} - -void ump_descriptor_mapping_destroy(ump_descriptor_mapping * map) -{ - descriptor_table_free(map->table); - _mali_osk_lock_term( map->lock ); - _mali_osk_free(map); -} - -int ump_descriptor_mapping_allocate_mapping(ump_descriptor_mapping * map, void * target) -{ - int descriptor = -1;/*-EFAULT;*/ - _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW); - descriptor = _mali_osk_find_first_zero_bit(map->table->usage, map->current_nr_mappings); - if (descriptor == map->current_nr_mappings) - { - int nr_mappings_new; - /* no free descriptor, try to expand the table */ - ump_descriptor_table * new_table; - ump_descriptor_table * old_table = map->table; - nr_mappings_new= map->current_nr_mappings *2; - - if (map->current_nr_mappings >= map->max_nr_mappings_allowed) - { - descriptor = -1; - goto unlock_and_exit; - } - - new_table = descriptor_table_alloc(nr_mappings_new); - if (NULL == new_table) - { - descriptor = -1; - goto unlock_and_exit; - } - - _mali_osk_memcpy(new_table->usage, old_table->usage, (sizeof(unsigned long)*map->current_nr_mappings) / BITS_PER_LONG); - _mali_osk_memcpy(new_table->mappings, old_table->mappings, map->current_nr_mappings * sizeof(void*)); - map->table = new_table; - map->current_nr_mappings = nr_mappings_new; - descriptor_table_free(old_table); - } - - /* we have found a valid descriptor, set the value and usage bit */ - _mali_osk_set_nonatomic_bit(descriptor, map->table->usage); - map->table->mappings[descriptor] = target; - -unlock_and_exit: - _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RW); - return descriptor; -} - -int ump_descriptor_mapping_get(ump_descriptor_mapping * map, int descriptor, void** target) -{ - int result = -1;/*-EFAULT;*/ - DEBUG_ASSERT(map); - _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO); - if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) ) - { - *target = map->table->mappings[descriptor]; - result = 0; - } - else *target = NULL; - _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO); - return result; -} - -int ump_descriptor_mapping_set(ump_descriptor_mapping * map, int descriptor, void * target) -{ - int result = -1;/*-EFAULT;*/ - _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO); - if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) ) - { - map->table->mappings[descriptor] = target; - result = 0; - } - _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO); - return result; -} - -void ump_descriptor_mapping_free(ump_descriptor_mapping * map, int descriptor) -{ - _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW); - if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) ) - { - map->table->mappings[descriptor] = NULL; - _mali_osk_clear_nonatomic_bit(descriptor, map->table->usage); - } - _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RW); -} - -static ump_descriptor_table * descriptor_table_alloc(int count) -{ - ump_descriptor_table * table; - - table = _mali_osk_calloc(1, sizeof(ump_descriptor_table) + ((sizeof(unsigned long) * count)/BITS_PER_LONG) + (sizeof(void*) * count) ); - - if (NULL != table) - { - table->usage = (u32*)((u8*)table + sizeof(ump_descriptor_table)); - table->mappings = (void**)((u8*)table + sizeof(ump_descriptor_table) + ((sizeof(unsigned long) * count)/BITS_PER_LONG)); - } - - return table; -} - -static void descriptor_table_free(ump_descriptor_table * table) -{ - _mali_osk_free(table); -} diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.h b/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.h deleted file mode 100644 index 05b3982..0000000 --- a/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file ump_kernel_descriptor_mapping.h - */ - -#ifndef __UMP_KERNEL_DESCRIPTOR_MAPPING_H__ -#define __UMP_KERNEL_DESCRIPTOR_MAPPING_H__ - -#include "mali_osk.h" - -/** - * The actual descriptor mapping table, never directly accessed by clients - */ -typedef struct ump_descriptor_table -{ - u32 * usage; /**< Pointer to bitpattern indicating if a descriptor is valid/used or not */ - void** mappings; /**< Array of the pointers the descriptors map to */ -} ump_descriptor_table; - -/** - * The descriptor mapping object - * Provides a separate namespace where we can map an integer to a pointer - */ -typedef struct ump_descriptor_mapping -{ - _mali_osk_lock_t *lock; /**< Lock protecting access to the mapping object */ - int max_nr_mappings_allowed; /**< Max number of mappings to support in this namespace */ - int current_nr_mappings; /**< Current number of possible mappings */ - ump_descriptor_table * table; /**< Pointer to the current mapping table */ -} ump_descriptor_mapping; - -/** - * Create a descriptor mapping object - * Create a descriptor mapping capable of holding init_entries growable to max_entries - * @param init_entries Number of entries to preallocate memory for - * @param max_entries Number of entries to max support - * @return Pointer to a descriptor mapping object, NULL on failure - */ -ump_descriptor_mapping * ump_descriptor_mapping_create(int init_entries, int max_entries); - -/** - * Destroy a descriptor mapping object - * @param map The map to free - */ -void ump_descriptor_mapping_destroy(ump_descriptor_mapping * map); - -/** - * Allocate a new mapping entry (descriptor ID) - * Allocates a new entry in the map. - * @param map The map to allocate a new entry in - * @param target The value to map to - * @return The descriptor allocated, a negative value on error - */ -int ump_descriptor_mapping_allocate_mapping(ump_descriptor_mapping * map, void * target); - -/** - * Get the value mapped to by a descriptor ID - * @param map The map to lookup the descriptor id in - * @param descriptor The descriptor ID to lookup - * @param target Pointer to a pointer which will receive the stored value - * @return 0 on successful lookup, negative on error - */ -int ump_descriptor_mapping_get(ump_descriptor_mapping * map, int descriptor, void** target); - -/** - * Set the value mapped to by a descriptor ID - * @param map The map to lookup the descriptor id in - * @param descriptor The descriptor ID to lookup - * @param target Pointer to replace the current value with - * @return 0 on successful lookup, negative on error - */ -int ump_descriptor_mapping_set(ump_descriptor_mapping * map, int descriptor, void * target); - -/** - * Free the descriptor ID - * For the descriptor to be reused it has to be freed - * @param map The map to free the descriptor from - * @param descriptor The descriptor ID to free - */ -void ump_descriptor_mapping_free(ump_descriptor_mapping * map, int descriptor); - -#endif /* __UMP_KERNEL_DESCRIPTOR_MAPPING_H__ */ diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_memory_backend.h b/drivers/media/video/samsung/ump/common/ump_kernel_memory_backend.h deleted file mode 100644 index 73915ee..0000000 --- a/drivers/media/video/samsung/ump/common/ump_kernel_memory_backend.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file ump_kernel_memory_mapping.h - */ - -#ifndef __UMP_KERNEL_MEMORY_BACKEND_H__ -#define __UMP_KERNEL_MEMORY_BACKEND_H__ - -#include "ump_kernel_interface.h" -#include "ump_kernel_types.h" - - -typedef struct ump_memory_allocation -{ - void * phys_addr; - void * mapping; - unsigned long size; - ump_dd_handle handle; - void * process_mapping_info; - u32 cookie; /**< necessary on some U/K interface implementations */ - struct ump_session_data * ump_session; /**< Session that this allocation belongs to */ - _mali_osk_list_t list; /**< List for linking together memory allocations into the session's memory head */ - u32 is_cached; -} ump_memory_allocation; - -typedef struct ump_memory_backend -{ - int (*allocate)(void* ctx, ump_dd_mem * descriptor); - void (*release)(void* ctx, ump_dd_mem * descriptor); - void (*shutdown)(struct ump_memory_backend * backend); - u32 (*stat)(struct ump_memory_backend *backend); - int (*pre_allocate_physical_check)(void *ctx, u32 size); - u32 (*adjust_to_mali_phys)(void *ctx, u32 cpu_phys); - void *(*get)(ump_dd_mem *mem, void *args); - void (*set)(ump_dd_mem *mem, void *args); - void * ctx; -} ump_memory_backend; - -ump_memory_backend * ump_memory_backend_create ( void ); -void ump_memory_backend_destroy( void ); - -#endif /*__UMP_KERNEL_MEMORY_BACKEND_H__ */ diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_ref_drv.c b/drivers/media/video/samsung/ump/common/ump_kernel_ref_drv.c deleted file mode 100644 index cb13232..0000000 --- a/drivers/media/video/samsung/ump/common/ump_kernel_ref_drv.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mali_osk.h" -#include "mali_osk_list.h" -#include "ump_osk.h" -#include "ump_uk_types.h" - -#include "ump_kernel_interface_ref_drv.h" -#include "ump_kernel_common.h" -#include "ump_kernel_descriptor_mapping.h" - -#define UMP_MINIMUM_SIZE 4096 -#define UMP_MINIMUM_SIZE_MASK (~(UMP_MINIMUM_SIZE-1)) -#define UMP_SIZE_ALIGN(x) (((x)+UMP_MINIMUM_SIZE-1)&UMP_MINIMUM_SIZE_MASK) -#define UMP_ADDR_ALIGN_OFFSET(x) ((x)&(UMP_MINIMUM_SIZE-1)) -static void phys_blocks_release(void * ctx, struct ump_dd_mem * descriptor); - -UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_phys_blocks(ump_dd_physical_block * blocks, unsigned long num_blocks) -{ - ump_dd_mem * mem; - unsigned long size_total = 0; - int map_id; - u32 i; - - /* Go through the input blocks and verify that they are sane */ - for (i=0; i < num_blocks; i++) - { - unsigned long addr = blocks[i].addr; - unsigned long size = blocks[i].size; - - DBG_MSG(5, ("Adding physical memory to new handle. Address: 0x%08lx, size: %lu\n", addr, size)); - size_total += blocks[i].size; - - if (0 != UMP_ADDR_ALIGN_OFFSET(addr)) - { - MSG_ERR(("Trying to create UMP memory from unaligned physical address. Address: 0x%08lx\n", addr)); - return UMP_DD_HANDLE_INVALID; - } - - if (0 != UMP_ADDR_ALIGN_OFFSET(size)) - { - MSG_ERR(("Trying to create UMP memory with unaligned size. Size: %lu\n", size)); - return UMP_DD_HANDLE_INVALID; - } - } - - /* Allocate the ump_dd_mem struct for this allocation */ - mem = _mali_osk_malloc(sizeof(*mem)); - if (NULL == mem) - { - DBG_MSG(1, ("Could not allocate ump_dd_mem in ump_dd_handle_create_from_phys_blocks()\n")); - return UMP_DD_HANDLE_INVALID; - } - - /* Find a secure ID for this allocation */ - _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - map_id = ump_descriptor_mapping_allocate_mapping(device.secure_id_map, (void*) mem); - - if (map_id < 0) - { - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - _mali_osk_free(mem); - DBG_MSG(1, ("Failed to allocate secure ID in ump_dd_handle_create_from_phys_blocks()\n")); - return UMP_DD_HANDLE_INVALID; - } - - /* Now, make a copy of the block information supplied by the user */ - mem->block_array = _mali_osk_malloc(sizeof(ump_dd_physical_block)* num_blocks); - if (NULL == mem->block_array) - { - ump_descriptor_mapping_free(device.secure_id_map, map_id); - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - _mali_osk_free(mem); - DBG_MSG(1, ("Could not allocate a mem handle for function ump_dd_handle_create_from_phys_blocks().\n")); - return UMP_DD_HANDLE_INVALID; - } - - _mali_osk_memcpy(mem->block_array, blocks, sizeof(ump_dd_physical_block) * num_blocks); - - /* And setup the rest of the ump_dd_mem struct */ - _mali_osk_atomic_init(&mem->ref_count, 1); - mem->secure_id = (ump_secure_id)map_id; - mem->size_bytes = size_total; - mem->nr_blocks = num_blocks; - mem->backend_info = NULL; - mem->ctx = NULL; - mem->release_func = phys_blocks_release; - /* For now UMP handles created by ump_dd_handle_create_from_phys_blocks() is forced to be Uncached */ - mem->is_cached = 0; - mem->hw_device = _UMP_UK_USED_BY_CPU; - mem->lock_usage = UMP_NOT_LOCKED; - - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - DBG_MSG(3, ("UMP memory created. ID: %u, size: %lu\n", mem->secure_id, mem->size_bytes)); - - return (ump_dd_handle)mem; -} - -static void phys_blocks_release(void * ctx, struct ump_dd_mem * descriptor) -{ - _mali_osk_free(descriptor->block_array); - descriptor->block_array = NULL; -} - -_mali_osk_errcode_t _ump_ukk_allocate( _ump_uk_allocate_s *user_interaction ) -{ - ump_session_data * session_data = NULL; - ump_dd_mem *new_allocation = NULL; - ump_session_memory_list_element * session_memory_element = NULL; - int map_id; - - DEBUG_ASSERT_POINTER( user_interaction ); - DEBUG_ASSERT_POINTER( user_interaction->ctx ); - - session_data = (ump_session_data *) user_interaction->ctx; - - session_memory_element = _mali_osk_calloc( 1, sizeof(ump_session_memory_list_element)); - if (NULL == session_memory_element) - { - DBG_MSG(1, ("Failed to allocate ump_session_memory_list_element in ump_ioctl_allocate()\n")); - return _MALI_OSK_ERR_NOMEM; - } - - - new_allocation = _mali_osk_calloc( 1, sizeof(ump_dd_mem)); - if (NULL==new_allocation) - { - _mali_osk_free(session_memory_element); - DBG_MSG(1, ("Failed to allocate ump_dd_mem in _ump_ukk_allocate()\n")); - return _MALI_OSK_ERR_NOMEM; - } - - /* Create a secure ID for this allocation */ - _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - map_id = ump_descriptor_mapping_allocate_mapping(device.secure_id_map, (void*)new_allocation); - - if (map_id < 0) - { - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - _mali_osk_free(session_memory_element); - _mali_osk_free(new_allocation); - DBG_MSG(1, ("Failed to allocate secure ID in ump_ioctl_allocate()\n")); - return - _MALI_OSK_ERR_INVALID_FUNC; - } - - /* Initialize the part of the new_allocation that we know so for */ - new_allocation->secure_id = (ump_secure_id)map_id; - _mali_osk_atomic_init(&new_allocation->ref_count,1); - if ( 0==(UMP_REF_DRV_UK_CONSTRAINT_USE_CACHE & user_interaction->constraints) ) - new_allocation->is_cached = 0; - else new_allocation->is_cached = 1; - - /* special case a size of 0, we should try to emulate what malloc does in this case, which is to return a valid pointer that must be freed, but can't be dereferences */ - if (0 == user_interaction->size) - { - user_interaction->size = 1; /* emulate by actually allocating the minimum block size */ - } - - new_allocation->size_bytes = UMP_SIZE_ALIGN(user_interaction->size); /* Page align the size */ - new_allocation->lock_usage = UMP_NOT_LOCKED; - - /* Now, ask the active memory backend to do the actual memory allocation */ - if (!device.backend->allocate( device.backend->ctx, new_allocation ) ) - { - DBG_MSG(3, ("OOM: No more UMP memory left. Failed to allocate memory in ump_ioctl_allocate(). Size: %lu, requested size: %lu\n", new_allocation->size_bytes, (unsigned long)user_interaction->size)); - ump_descriptor_mapping_free(device.secure_id_map, map_id); - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - _mali_osk_free(new_allocation); - _mali_osk_free(session_memory_element); - return _MALI_OSK_ERR_INVALID_FUNC; - } - new_allocation->hw_device = _UMP_UK_USED_BY_CPU; - new_allocation->ctx = device.backend->ctx; - new_allocation->release_func = device.backend->release; - - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - - /* Initialize the session_memory_element, and add it to the session object */ - session_memory_element->mem = new_allocation; - _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); - _mali_osk_list_add(&(session_memory_element->list), &(session_data->list_head_session_memory_list)); - _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); - - user_interaction->secure_id = new_allocation->secure_id; - user_interaction->size = new_allocation->size_bytes; - DBG_MSG(3, ("UMP memory allocated. ID: %u, size: %lu\n", new_allocation->secure_id, new_allocation->size_bytes)); - - return _MALI_OSK_ERR_OK; -} - - -UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_meminfo_set(ump_dd_handle memh, void* args) -{ - ump_dd_mem * mem; - ump_secure_id secure_id; - - DEBUG_ASSERT_POINTER(memh); - - secure_id = ump_dd_secure_id_get(memh); - - _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - if (0 == ump_descriptor_mapping_get(device.secure_id_map, (int)secure_id, (void**)&mem)) - { - device.backend->set(mem, args); - } - else - { - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - DBG_MSG(1, ("Failed to look up mapping in ump_meminfo_set(). ID: %u\n", (ump_secure_id)secure_id)); - return UMP_DD_INVALID; - } - - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - - return UMP_DD_SUCCESS; -} - -UMP_KERNEL_API_EXPORT void *ump_dd_meminfo_get(ump_secure_id secure_id, void* args) -{ - ump_dd_mem * mem; - void *result; - - _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - if (0 == ump_descriptor_mapping_get(device.secure_id_map, (int)secure_id, (void**)&mem)) - { - result = device.backend->get(mem, args); - } - else - { - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - DBG_MSG(1, ("Failed to look up mapping in ump_meminfo_get(). ID: %u\n", (ump_secure_id)secure_id)); - return UMP_DD_HANDLE_INVALID; - } - - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - - return result; -} - -UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_get_from_vaddr(unsigned long vaddr) -{ - ump_dd_mem * mem; - - DBG_MSG(5, ("Getting handle from Virtual address. vaddr: %u\n", vaddr)); - - _ump_osk_mem_mapregion_get(&mem, vaddr); - - DBG_MSG(1, ("Getting handle's Handle : 0x%8lx\n", mem)); - - return (ump_dd_handle)mem; -} - diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_types.h b/drivers/media/video/samsung/ump/common/ump_kernel_types.h deleted file mode 100644 index 19a9755..0000000 --- a/drivers/media/video/samsung/ump/common/ump_kernel_types.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __UMP_KERNEL_TYPES_H__ -#define __UMP_KERNEL_TYPES_H__ - -#include "ump_kernel_interface.h" -#include "mali_osk.h" - - -typedef enum -{ - UMP_USED_BY_CPU = 0, - UMP_USED_BY_MALI = 1, - UMP_USED_BY_UNKNOWN_DEVICE= 100, -} ump_hw_usage; - -typedef enum -{ - UMP_NOT_LOCKED = 0, - UMP_READ = 1, - UMP_READ_WRITE = 3, -} ump_lock_usage; - - -/* - * This struct is what is "behind" a ump_dd_handle - */ -typedef struct ump_dd_mem -{ - ump_secure_id secure_id; - _mali_osk_atomic_t ref_count; - unsigned long size_bytes; - unsigned long nr_blocks; - ump_dd_physical_block * block_array; - void (*release_func)(void * ctx, struct ump_dd_mem * descriptor); - void * ctx; - void * backend_info; - int is_cached; - ump_hw_usage hw_device; - ump_lock_usage lock_usage; -} ump_dd_mem; - - - -#endif /* __UMP_KERNEL_TYPES_H__ */ diff --git a/drivers/media/video/samsung/ump/common/ump_osk.h b/drivers/media/video/samsung/ump/common/ump_osk.h deleted file mode 100644 index dabdc7f..0000000 --- a/drivers/media/video/samsung/ump/common/ump_osk.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file ump_osk.h - * Defines the OS abstraction layer for the UMP kernel device driver (OSK) - */ - -#ifndef __UMP_OSK_H__ -#define __UMP_OSK_H__ - -#include -#include -#include "ump_uk_types.h" -#include "ump_kernel_common.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -_mali_osk_errcode_t _ump_osk_init( void ); - -_mali_osk_errcode_t _ump_osk_term( void ); - -int _ump_osk_atomic_inc_and_read( _mali_osk_atomic_t *atom ); - -int _ump_osk_atomic_dec_and_read( _mali_osk_atomic_t *atom ); - -_mali_osk_errcode_t _ump_osk_mem_mapregion_init( ump_memory_allocation *descriptor ); - -_mali_osk_errcode_t _ump_osk_mem_mapregion_map( ump_memory_allocation * descriptor, u32 offset, u32 * phys_addr, unsigned long size ); - -void _ump_osk_mem_mapregion_term( ump_memory_allocation * descriptor ); - -void _ump_osk_msync( ump_dd_mem * mem, void * virt, u32 offset, u32 size, ump_uk_msync_op op, ump_session_data * session_data ); - -void _ump_osk_mem_mapregion_get( ump_dd_mem ** mem, unsigned long vaddr); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/drivers/media/video/samsung/ump/common/ump_uk_types.h b/drivers/media/video/samsung/ump/common/ump_uk_types.h deleted file mode 100644 index 143588d..0000000 --- a/drivers/media/video/samsung/ump/common/ump_uk_types.h +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file ump_uk_types.h - * Defines the types and constants used in the user-kernel interface - */ - -#ifndef __UMP_UK_TYPES_H__ -#define __UMP_UK_TYPES_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* Helpers for API version handling */ -#define MAKE_VERSION_ID(x) (((x) << 16UL) | (x)) -#define IS_VERSION_ID(x) (((x) & 0xFFFF) == (((x) >> 16UL) & 0xFFFF)) -#define GET_VERSION(x) (((x) >> 16UL) & 0xFFFF) -#define IS_API_MATCH(x, y) (IS_VERSION_ID((x)) && IS_VERSION_ID((y)) && (GET_VERSION((x)) == GET_VERSION((y)))) - -/** - * API version define. - * Indicates the version of the kernel API - * The version is a 16bit integer incremented on each API change. - * The 16bit integer is stored twice in a 32bit integer - * So for version 1 the value would be 0x00010001 - */ -#define UMP_IOCTL_API_VERSION MAKE_VERSION_ID(2) - -typedef enum -{ - _UMP_IOC_QUERY_API_VERSION = 1, - _UMP_IOC_ALLOCATE, - _UMP_IOC_RELEASE, - _UMP_IOC_SIZE_GET, - _UMP_IOC_MAP_MEM, /* not used in Linux */ - _UMP_IOC_UNMAP_MEM, /* not used in Linux */ - _UMP_IOC_MSYNC, - _UMP_IOC_CACHE_OPERATIONS_CONTROL, - _UMP_IOC_SWITCH_HW_USAGE, - _UMP_IOC_LOCK, - _UMP_IOC_UNLOCK, -#ifdef CONFIG_ION_EXYNOS - _UMP_IOC_ION_IMPORT, -#endif -}_ump_uk_functions; - -typedef enum -{ - UMP_REF_DRV_UK_CONSTRAINT_NONE = 0, - UMP_REF_DRV_UK_CONSTRAINT_PHYSICALLY_LINEAR = 1, - UMP_REF_DRV_UK_CONSTRAINT_USE_CACHE = 128, -} ump_uk_alloc_constraints; - -typedef enum -{ - _UMP_UK_MSYNC_CLEAN = 0, - _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE = 1, - _UMP_UK_MSYNC_INVALIDATE = 2, - _UMP_UK_MSYNC_FLUSH_L1 = 3, - _UMP_UK_MSYNC_READOUT_CACHE_ENABLED = 128, -} ump_uk_msync_op; - -typedef enum -{ - _UMP_UK_CACHE_OP_START = 0, - _UMP_UK_CACHE_OP_FINISH = 1, -} ump_uk_cache_op_control; - -typedef enum -{ - _UMP_UK_READ = 1, - _UMP_UK_READ_WRITE = 3, -} ump_uk_lock_usage; - -typedef enum -{ - _UMP_UK_USED_BY_CPU = 0, - _UMP_UK_USED_BY_MALI = 1, - _UMP_UK_USED_BY_UNKNOWN_DEVICE= 100, -} ump_uk_user; - -/** - * Get API version ([in,out] u32 api_version, [out] u32 compatible) - */ -typedef struct _ump_uk_api_version_s -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 version; /**< Set to the user space version on entry, stores the device driver version on exit */ - u32 compatible; /**< Non-null if the device is compatible with the client */ -} _ump_uk_api_version_s; - -/** - * ALLOCATE ([out] u32 secure_id, [in,out] u32 size, [in] contraints) - */ -typedef struct _ump_uk_allocate_s -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 secure_id; /**< Return value from DD to Userdriver */ - u32 size; /**< Input and output. Requested size; input. Returned size; output */ - ump_uk_alloc_constraints constraints; /**< Only input to Devicedriver */ -} _ump_uk_allocate_s; - -#ifdef CONFIG_ION_EXYNOS -typedef struct _ump_uk_ion_import_s -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - int ion_fd; /**< ion_fd */ - u32 secure_id; /**< Return value from DD to Userdriver */ - u32 size; /**< Input and output. Requested size; input. Returned size; output */ - ump_uk_alloc_constraints constraints; /**< Only input to Devicedriver */ -} _ump_uk_ion_import_s; -#endif - -/** - * SIZE_GET ([in] u32 secure_id, [out]size ) - */ -typedef struct _ump_uk_size_get_s -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 secure_id; /**< Input to DD */ - u32 size; /**< Returned size; output */ -} _ump_uk_size_get_s; - -/** - * Release ([in] u32 secure_id) - */ -typedef struct _ump_uk_release_s -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 secure_id; /**< Input to DD */ -} _ump_uk_release_s; - -typedef struct _ump_uk_map_mem_s -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - void *mapping; /**< [out] Returns user-space virtual address for the mapping */ - void *phys_addr; /**< [in] physical address */ - unsigned long size; /**< [in] size */ - u32 secure_id; /**< [in] secure_id to assign to mapping */ - void * _ukk_private; /**< Only used inside linux port between kernel frontend and common part to store vma */ - u32 cookie; - u32 is_cached; /**< [in,out] caching of CPU mappings */ -} _ump_uk_map_mem_s; - -typedef struct _ump_uk_unmap_mem_s -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - void *mapping; - u32 size; - void * _ukk_private; - u32 cookie; -} _ump_uk_unmap_mem_s; - -typedef struct _ump_uk_msync_s -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - void *mapping; /**< [in] mapping addr */ - void *address; /**< [in] flush start addr */ - u32 size; /**< [in] size to flush */ - ump_uk_msync_op op; /**< [in] flush operation */ - u32 cookie; /**< [in] cookie stored with reference to the kernel mapping internals */ - u32 secure_id; /**< [in] secure_id that identifies the ump buffer */ - u32 is_cached; /**< [out] caching of CPU mappings */ -} _ump_uk_msync_s; - -typedef struct _ump_uk_cache_operations_control_s -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - ump_uk_cache_op_control op; /**< [in] cache operations start/stop */ -} _ump_uk_cache_operations_control_s; - - -typedef struct _ump_uk_switch_hw_usage_s -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 secure_id; /**< [in] secure_id that identifies the ump buffer */ - ump_uk_user new_user; /**< [in] cookie stored with reference to the kernel mapping internals */ - -} _ump_uk_switch_hw_usage_s; - -typedef struct _ump_uk_lock_s -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 secure_id; /**< [in] secure_id that identifies the ump buffer */ - ump_uk_lock_usage lock_usage; -} _ump_uk_lock_s; - -typedef struct _ump_uk_unlock_s -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 secure_id; /**< [in] secure_id that identifies the ump buffer */ -} _ump_uk_unlock_s; - -#ifdef __cplusplus -} -#endif - -#endif /* __UMP_UK_TYPES_H__ */ diff --git a/drivers/media/video/samsung/ump/common/ump_ukk.h b/drivers/media/video/samsung/ump/common/ump_ukk.h deleted file mode 100644 index 56e4be3..0000000 --- a/drivers/media/video/samsung/ump/common/ump_ukk.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file ump_ukk.h - * Defines the kernel-side interface of the user-kernel interface - */ - -#ifndef __UMP_UKK_H__ -#define __UMP_UKK_H__ - -#include "mali_osk.h" -#include "ump_uk_types.h" - - -#ifdef __cplusplus -extern "C" -{ -#endif - - -_mali_osk_errcode_t _ump_ukk_open( void** context ); - -_mali_osk_errcode_t _ump_ukk_close( void** context ); - -_mali_osk_errcode_t _ump_ukk_allocate( _ump_uk_allocate_s *user_interaction ); - -_mali_osk_errcode_t _ump_ukk_release( _ump_uk_release_s *release_info ); - -_mali_osk_errcode_t _ump_ukk_size_get( _ump_uk_size_get_s *user_interaction ); - -_mali_osk_errcode_t _ump_ukk_map_mem( _ump_uk_map_mem_s *args ); - -_mali_osk_errcode_t _ump_uku_get_api_version( _ump_uk_api_version_s *args ); - -void _ump_ukk_unmap_mem( _ump_uk_unmap_mem_s *args ); - -void _ump_ukk_msync( _ump_uk_msync_s *args ); - -void _ump_ukk_cache_operations_control(_ump_uk_cache_operations_control_s* args); - -void _ump_ukk_switch_hw_usage(_ump_uk_switch_hw_usage_s *args ); - -void _ump_ukk_lock(_ump_uk_lock_s *args ); - -void _ump_ukk_unlock(_ump_uk_unlock_s *args ); - -u32 _ump_ukk_report_memory_usage( void ); - -#ifdef __cplusplus -} -#endif - -#endif /* __UMP_UKK_H__ */ diff --git a/drivers/media/video/samsung/ump/include/ump_kernel_interface.h b/drivers/media/video/samsung/ump/include/ump_kernel_interface.h deleted file mode 100644 index 042c8b1..0000000 --- a/drivers/media/video/samsung/ump/include/ump_kernel_interface.h +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file ump_kernel_interface.h - * - * This file contains the kernel space part of the UMP API. - */ - -#ifndef __UMP_KERNEL_INTERFACE_H__ -#define __UMP_KERNEL_INTERFACE_H__ - - -/** @defgroup ump_kernel_space_api UMP Kernel Space API - * @{ */ - - -#include "ump_kernel_platform.h" - - -#ifdef __cplusplus -extern "C" -{ -#endif - - -/** - * External representation of a UMP handle in kernel space. - */ -typedef void * ump_dd_handle; - -/** - * Typedef for a secure ID, a system wide identificator for UMP memory buffers. - */ -typedef unsigned int ump_secure_id; - - -/** - * Value to indicate an invalid UMP memory handle. - */ -#define UMP_DD_HANDLE_INVALID ((ump_dd_handle)0) - - -/** - * Value to indicate an invalid secure Id. - */ -#define UMP_INVALID_SECURE_ID ((ump_secure_id)-1) - - -/** - * UMP error codes for kernel space. - */ -typedef enum -{ - UMP_DD_SUCCESS, /**< indicates success */ - UMP_DD_INVALID, /**< indicates failure */ -} ump_dd_status_code; - - -/** - * Struct used to describe a physical block used by UMP memory - */ -typedef struct ump_dd_physical_block -{ - unsigned long addr; /**< The physical address of the block */ - unsigned long size; /**< The length of the block, typically page aligned */ -} ump_dd_physical_block; - - -/** - * Retrieves the secure ID for the specified UMP memory. - * - * This identificator is unique across the entire system, and uniquely identifies - * the specified UMP memory. This identificator can later be used through the - * @ref ump_dd_handle_create_from_secure_id "ump_dd_handle_create_from_secure_id" or - * @ref ump_handle_create_from_secure_id "ump_handle_create_from_secure_id" - * functions in order to access this UMP memory, for instance from another process. - * - * @note There is a user space equivalent function called @ref ump_secure_id_get "ump_secure_id_get" - * - * @see ump_dd_handle_create_from_secure_id - * @see ump_handle_create_from_secure_id - * @see ump_secure_id_get - * - * @param mem Handle to UMP memory. - * - * @return Returns the secure ID for the specified UMP memory. - */ -UMP_KERNEL_API_EXPORT ump_secure_id ump_dd_secure_id_get(ump_dd_handle mem); - - -/** - * Retrieves a handle to allocated UMP memory. - * - * The usage of UMP memory is reference counted, so this will increment the reference - * count by one for the specified UMP memory. - * Use @ref ump_dd_reference_release "ump_dd_reference_release" when there is no longer any - * use for the retrieved handle. - * - * @note There is a user space equivalent function called @ref ump_handle_create_from_secure_id "ump_handle_create_from_secure_id" - * - * @see ump_dd_reference_release - * @see ump_handle_create_from_secure_id - * - * @param secure_id The secure ID of the UMP memory to open, that can be retrieved using the @ref ump_secure_id_get "ump_secure_id_get " function. - * - * @return UMP_INVALID_MEMORY_HANDLE indicates failure, otherwise a valid handle is returned. - */ -UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_secure_id(ump_secure_id secure_id); - - -/** - * Retrieves the number of physical blocks used by the specified UMP memory. - * - * This function retrieves the number of @ref ump_dd_physical_block "ump_dd_physical_block" structs needed - * to describe the physical memory layout of the given UMP memory. This can later be used when calling - * the functions @ref ump_dd_phys_blocks_get "ump_dd_phys_blocks_get" and - * @ref ump_dd_phys_block_get "ump_dd_phys_block_get". - * - * @see ump_dd_phys_blocks_get - * @see ump_dd_phys_block_get - * - * @param mem Handle to UMP memory. - * - * @return The number of ump_dd_physical_block structs required to describe the physical memory layout of the specified UMP memory. - */ -UMP_KERNEL_API_EXPORT unsigned long ump_dd_phys_block_count_get(ump_dd_handle mem); - - -/** - * Retrieves all physical memory block information for specified UMP memory. - * - * This function can be used by other device drivers in order to create MMU tables. - * - * @note This function will fail if the num_blocks parameter is either to large or to small. - * - * @see ump_dd_phys_block_get - * - * @param mem Handle to UMP memory. - * @param blocks An array of @ref ump_dd_physical_block "ump_dd_physical_block" structs that will receive the physical description. - * @param num_blocks The number of blocks to return in the blocks array. Use the function - * @ref ump_dd_phys_block_count_get "ump_dd_phys_block_count_get" first to determine the number of blocks required. - * - * @return UMP_DD_SUCCESS indicates success, UMP_DD_INVALID indicates failure. - */ -UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_phys_blocks_get(ump_dd_handle mem, ump_dd_physical_block * blocks, unsigned long num_blocks); - - -/** - * Retrieves the physical memory block information for specified block for the specified UMP memory. - * - * This function can be used by other device drivers in order to create MMU tables. - * - * @note This function will return UMP_DD_INVALID if the specified index is out of range. - * - * @see ump_dd_phys_blocks_get - * - * @param mem Handle to UMP memory. - * @param index Which physical info block to retrieve. - * @param block Pointer to a @ref ump_dd_physical_block "ump_dd_physical_block" struct which will receive the requested information. - * - * @return UMP_DD_SUCCESS indicates success, UMP_DD_INVALID indicates failure. - */ -UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_phys_block_get(ump_dd_handle mem, unsigned long index, ump_dd_physical_block * block); - - -/** - * Retrieves the actual size of the specified UMP memory. - * - * The size is reported in bytes, and is typically page aligned. - * - * @note There is a user space equivalent function called @ref ump_size_get "ump_size_get" - * - * @see ump_size_get - * - * @param mem Handle to UMP memory. - * - * @return Returns the allocated size of the specified UMP memory, in bytes. - */ -UMP_KERNEL_API_EXPORT unsigned long ump_dd_size_get(ump_dd_handle mem); - - -/** - * Adds an extra reference to the specified UMP memory. - * - * This function adds an extra reference to the specified UMP memory. This function should - * be used every time a UMP memory handle is duplicated, that is, assigned to another ump_dd_handle - * variable. The function @ref ump_dd_reference_release "ump_dd_reference_release" must then be used - * to release each copy of the UMP memory handle. - * - * @note You are not required to call @ref ump_dd_reference_add "ump_dd_reference_add" - * for UMP handles returned from - * @ref ump_dd_handle_create_from_secure_id "ump_dd_handle_create_from_secure_id", - * because these handles are already reference counted by this function. - * - * @note There is a user space equivalent function called @ref ump_reference_add "ump_reference_add" - * - * @see ump_reference_add - * - * @param mem Handle to UMP memory. - */ -UMP_KERNEL_API_EXPORT void ump_dd_reference_add(ump_dd_handle mem); - - -/** - * Releases a reference from the specified UMP memory. - * - * This function should be called once for every reference to the UMP memory handle. - * When the last reference is released, all resources associated with this UMP memory - * handle are freed. - * - * @note There is a user space equivalent function called @ref ump_reference_release "ump_reference_release" - * - * @see ump_reference_release - * - * @param mem Handle to UMP memory. - */ -UMP_KERNEL_API_EXPORT void ump_dd_reference_release(ump_dd_handle mem); - - -#ifdef __cplusplus -} -#endif - - -/** @} */ /* end group ump_kernel_space_api */ - - -#endif /* __UMP_KERNEL_INTERFACE_H__ */ diff --git a/drivers/media/video/samsung/ump/include/ump_kernel_interface_ref_drv.h b/drivers/media/video/samsung/ump/include/ump_kernel_interface_ref_drv.h deleted file mode 100644 index 36c5c9d..0000000 --- a/drivers/media/video/samsung/ump/include/ump_kernel_interface_ref_drv.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file ump_kernel_interface.h - */ - -#ifndef __UMP_KERNEL_INTERFACE_REF_DRV_H__ -#define __UMP_KERNEL_INTERFACE_REF_DRV_H__ - -#include "ump_kernel_interface.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** Turn specified physical memory into UMP memory. */ -UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_phys_blocks(ump_dd_physical_block * blocks, unsigned long num_blocks); -UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_get(ump_secure_id secure_id); -UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_meminfo_set(ump_dd_handle memh, void* args); -UMP_KERNEL_API_EXPORT void *ump_dd_meminfo_get(ump_secure_id secure_id, void* args); -UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_get_from_vaddr(unsigned long vaddr); - -#ifdef __cplusplus -} -#endif - -#endif /* __UMP_KERNEL_INTERFACE_REF_DRV_H__ */ diff --git a/drivers/media/video/samsung/ump/include/ump_kernel_platform.h b/drivers/media/video/samsung/ump/include/ump_kernel_platform.h deleted file mode 100644 index 4349605..0000000 --- a/drivers/media/video/samsung/ump/include/ump_kernel_platform.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file ump_kernel_platform.h - * - * This file should define UMP_KERNEL_API_EXPORT, - * which dictates how the UMP kernel API should be exported/imported. - * Modify this file, if needed, to match your platform setup. - */ - -#ifndef __UMP_KERNEL_PLATFORM_H__ -#define __UMP_KERNEL_PLATFORM_H__ - -/** @addtogroup ump_kernel_space_api - * @{ */ - -/** - * A define which controls how UMP kernel space API functions are imported and exported. - * This define should be set by the implementor of the UMP API. - */ - -#if defined(_WIN32) - -#if defined(UMP_BUILDING_UMP_LIBRARY) -#define UMP_KERNEL_API_EXPORT __declspec(dllexport) -#else -#define UMP_KERNEL_API_EXPORT __declspec(dllimport) -#endif - -#else - -#define UMP_KERNEL_API_EXPORT - -#endif - - -/** @} */ /* end group ump_kernel_space_api */ - - -#endif /* __UMP_KERNEL_PLATFORM_H__ */ diff --git a/drivers/media/video/samsung/ump/linux/license/gpl/ump_kernel_license.h b/drivers/media/video/samsung/ump/linux/license/gpl/ump_kernel_license.h deleted file mode 100644 index 187e33b..0000000 --- a/drivers/media/video/samsung/ump/linux/license/gpl/ump_kernel_license.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file ump_kernel_license.h - * Defines for the macro MODULE_LICENSE. - */ - -#ifndef __UMP_KERNEL_LICENSE_H__ -#define __UMP_KERNEL_LICENSE_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#define UMP_KERNEL_LINUX_LICENSE "GPL" -#define UMP_LICENSE_IS_GPL 1 - -#ifdef __cplusplus -} -#endif - -#endif /* __UMP_KERNEL_LICENSE_H__ */ diff --git a/drivers/media/video/samsung/ump/linux/ump_ioctl.h b/drivers/media/video/samsung/ump/linux/ump_ioctl.h deleted file mode 100644 index 83bb2a4..0000000 --- a/drivers/media/video/samsung/ump/linux/ump_ioctl.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __UMP_IOCTL_H__ -#define __UMP_IOCTL_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include -#include - -#include - -#ifndef __user -#define __user -#endif - - -/** - * @file UMP_ioctl.h - * This file describes the interface needed to use the Linux device driver. - * The interface is used by the userpace UMP driver. - */ - -#define UMP_IOCTL_NR 0x90 - - -#define UMP_IOC_QUERY_API_VERSION _IOR(UMP_IOCTL_NR, _UMP_IOC_QUERY_API_VERSION, _ump_uk_api_version_s) -#define UMP_IOC_ALLOCATE _IOWR(UMP_IOCTL_NR, _UMP_IOC_ALLOCATE, _ump_uk_allocate_s) -#define UMP_IOC_RELEASE _IOR(UMP_IOCTL_NR, _UMP_IOC_RELEASE, _ump_uk_release_s) -#define UMP_IOC_SIZE_GET _IOWR(UMP_IOCTL_NR, _UMP_IOC_SIZE_GET, _ump_uk_size_get_s) -#define UMP_IOC_MSYNC _IOW(UMP_IOCTL_NR, _UMP_IOC_MSYNC, _ump_uk_msync_s) -#ifdef CONFIG_ION_EXYNOS -#define UMP_IOC_ION_IMPORT _IOW(UMP_IOCTL_NR, _UMP_IOC_ION_IMPORT, _ump_uk_ion_import_s) -#endif -#ifdef CONFIG_DMA_SHARED_BUFFER -#define UMP_IOC_DMABUF_IMPORT _IOW(UMP_IOCTL_NR, _UMP_IOC_DMABUF_IMPORT,\ - struct ump_uk_dmabuf) -#endif - -#define UMP_IOC_CACHE_OPERATIONS_CONTROL _IOW(UMP_IOCTL_NR, _UMP_IOC_CACHE_OPERATIONS_CONTROL, _ump_uk_cache_operations_control_s) -#define UMP_IOC_SWITCH_HW_USAGE _IOW(UMP_IOCTL_NR, _UMP_IOC_SWITCH_HW_USAGE, _ump_uk_switch_hw_usage_s) -#define UMP_IOC_LOCK _IOW(UMP_IOCTL_NR, _UMP_IOC_LOCK, _ump_uk_lock_s) -#define UMP_IOC_UNLOCK _IOW(UMP_IOCTL_NR, _UMP_IOC_UNLOCK, _ump_uk_unlock_s) - - -#ifdef __cplusplus -} -#endif - -#endif /* __UMP_IOCTL_H__ */ diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_linux.c b/drivers/media/video/samsung/ump/linux/ump_kernel_linux.c deleted file mode 100644 index a358a3c..0000000 --- a/drivers/media/video/samsung/ump/linux/ump_kernel_linux.c +++ /dev/null @@ -1,492 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include /* kernel module definitions */ -#include /* file system operations */ -#include /* character device definitions */ -#include /* request_mem_region */ -#include /* memory management functions and types */ -#include /* user space access */ -#include -#include -#include - -#include "arch/config.h" /* Configuration for current platform. The symlinc for arch is set by Makefile */ -#include "ump_ioctl.h" -#include "ump_kernel_common.h" -#include "ump_kernel_interface.h" -#include "ump_kernel_interface_ref_drv.h" -#include "ump_kernel_descriptor_mapping.h" -#include "ump_kernel_memory_backend.h" -#include "ump_kernel_memory_backend_os.h" -#include "ump_kernel_memory_backend_dedicated.h" -#include "ump_kernel_license.h" - -#include "ump_osk.h" -#include "ump_ukk.h" -#include "ump_uk_types.h" -#include "ump_ukk_wrappers.h" -#include "ump_ukk_ref_wrappers.h" - -#ifdef CONFIG_ION_EXYNOS -#include -extern struct ion_device *ion_exynos; -struct ion_client *ion_client_ump = NULL; -#endif - -/* Module parameter to control log level */ -int ump_debug_level = 2; -module_param(ump_debug_level, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); /* rw-rw-r-- */ -MODULE_PARM_DESC(ump_debug_level, "Higher number, more dmesg output"); - -/* By default the module uses any available major, but it's possible to set it at load time to a specific number */ -int ump_major = 243; -module_param(ump_major, int, S_IRUGO); /* r--r--r-- */ -MODULE_PARM_DESC(ump_major, "Device major number"); - -/* Name of the UMP device driver */ -static char ump_dev_name[] = "ump"; /* should be const, but the functions we call requires non-cost */ - - -#if UMP_LICENSE_IS_GPL -static struct dentry *ump_debugfs_dir = NULL; -#endif - -/* - * The data which we attached to each virtual memory mapping request we get. - * Each memory mapping has a reference to the UMP memory it maps. - * We release this reference when the last memory mapping is unmapped. - */ -typedef struct ump_vma_usage_tracker -{ - int references; - ump_dd_handle handle; -} ump_vma_usage_tracker; - -struct ump_device -{ - struct cdev cdev; -#if UMP_LICENSE_IS_GPL - struct class * ump_class; -#endif -}; - -/* The global variable containing the global device data */ -static struct ump_device ump_device; - - -/* Forward declare static functions */ -static int ump_file_open(struct inode *inode, struct file *filp); -static int ump_file_release(struct inode *inode, struct file *filp); -#ifdef HAVE_UNLOCKED_IOCTL -static long ump_file_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); -#else -static int ump_file_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -#endif -static int ump_file_mmap(struct file * filp, struct vm_area_struct * vma); - -#if defined(CONFIG_VIDEO_UMP) -extern int map_errcode( _mali_osk_errcode_t err ); -#endif - -/* This variable defines the file operations this UMP device driver offer */ -static struct file_operations ump_fops = -{ - .owner = THIS_MODULE, - .open = ump_file_open, - .release = ump_file_release, -#ifdef HAVE_UNLOCKED_IOCTL - .unlocked_ioctl = ump_file_ioctl, -#else - .ioctl = ump_file_ioctl, -#endif - .mmap = ump_file_mmap -}; - - -/* This function is called by Linux to initialize this module. - * All we do is initialize the UMP device driver. - */ -static int ump_initialize_module(void) -{ - _mali_osk_errcode_t err; - - DBG_MSG(2, ("Inserting UMP device driver. Compiled: %s, time: %s\n", __DATE__, __TIME__)); - - err = ump_kernel_constructor(); - if (_MALI_OSK_ERR_OK != err) - { - MSG_ERR(("UMP device driver init failed\n")); - return map_errcode(err); - } - - MSG(("UMP device driver %s loaded\n", SVN_REV_STRING)); - return 0; -} - - - -/* - * This function is called by Linux to unload/terminate/exit/cleanup this module. - * All we do is terminate the UMP device driver. - */ -static void ump_cleanup_module(void) -{ -#ifdef CONFIG_ION_EXYNOS - if (ion_client_ump) - ion_client_destroy(ion_client_ump); -#endif - - DBG_MSG(2, ("Unloading UMP device driver\n")); - ump_kernel_destructor(); - DBG_MSG(2, ("Module unloaded\n")); -} - - - -static ssize_t ump_memory_used_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) -{ - char buf[64]; - size_t r; - u32 mem = _ump_ukk_report_memory_usage(); - - r = snprintf(buf, 64, "%u\n", mem); - return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); -} - -static const struct file_operations ump_memory_usage_fops = { - .owner = THIS_MODULE, - .read = ump_memory_used_read, -}; - -/* - * Initialize the UMP device driver. - */ -int ump_kernel_device_initialize(void) -{ - int err; - dev_t dev = 0; -#if UMP_LICENSE_IS_GPL - ump_debugfs_dir = debugfs_create_dir(ump_dev_name, NULL); - if (ERR_PTR(-ENODEV) == ump_debugfs_dir) - { - ump_debugfs_dir = NULL; - } - else - { - debugfs_create_file("memory_usage", 0400, ump_debugfs_dir, NULL, &ump_memory_usage_fops); - } -#endif - - if (0 == ump_major) - { - /* auto select a major */ - err = alloc_chrdev_region(&dev, 0, 1, ump_dev_name); - ump_major = MAJOR(dev); - } - else - { - /* use load time defined major number */ - dev = MKDEV(ump_major, 0); - err = register_chrdev_region(dev, 1, ump_dev_name); - } - - if (0 == err) - { - memset(&ump_device, 0, sizeof(ump_device)); - - /* initialize our char dev data */ - cdev_init(&ump_device.cdev, &ump_fops); - ump_device.cdev.owner = THIS_MODULE; - ump_device.cdev.ops = &ump_fops; - - /* register char dev with the kernel */ - err = cdev_add(&ump_device.cdev, dev, 1/*count*/); - if (0 == err) - { - -#if UMP_LICENSE_IS_GPL - ump_device.ump_class = class_create(THIS_MODULE, ump_dev_name); - if (IS_ERR(ump_device.ump_class)) - { - err = PTR_ERR(ump_device.ump_class); - } - else - { - struct device * mdev; - mdev = device_create(ump_device.ump_class, NULL, dev, NULL, ump_dev_name); - if (!IS_ERR(mdev)) - { - return 0; - } - - err = PTR_ERR(mdev); - } - cdev_del(&ump_device.cdev); -#else - return 0; -#endif - } - - unregister_chrdev_region(dev, 1); - } - - return err; -} - - - -/* - * Terminate the UMP device driver - */ -void ump_kernel_device_terminate(void) -{ - dev_t dev = MKDEV(ump_major, 0); - -#if UMP_LICENSE_IS_GPL - device_destroy(ump_device.ump_class, dev); - class_destroy(ump_device.ump_class); -#endif - - /* unregister char device */ - cdev_del(&ump_device.cdev); - - /* free major */ - unregister_chrdev_region(dev, 1); - -#if UMP_LICENSE_IS_GPL - if(ump_debugfs_dir) - debugfs_remove_recursive(ump_debugfs_dir); -#endif -} - -/* - * Open a new session. User space has called open() on us. - */ -static int ump_file_open(struct inode *inode, struct file *filp) -{ - struct ump_session_data * session_data; - _mali_osk_errcode_t err; - - /* input validation */ - if (0 != MINOR(inode->i_rdev)) - { - MSG_ERR(("Minor not zero in ump_file_open()\n")); - return -ENODEV; - } - - /* Call the OS-Independent UMP Open function */ - err = _ump_ukk_open((void**) &session_data ); - if( _MALI_OSK_ERR_OK != err ) - { - MSG_ERR(("Ump failed to open a new session\n")); - return map_errcode( err ); - } - - filp->private_data = (void*)session_data; - filp->f_pos = 0; - - return 0; /* success */ -} - - - -/* - * Close a session. User space has called close() or crashed/terminated. - */ -static int ump_file_release(struct inode *inode, struct file *filp) -{ - _mali_osk_errcode_t err; - - err = _ump_ukk_close((void**) &filp->private_data ); - if( _MALI_OSK_ERR_OK != err ) - { - return map_errcode( err ); - } - - return 0; /* success */ -} - - - -/* - * Handle IOCTL requests. - */ -#ifdef HAVE_UNLOCKED_IOCTL -static long ump_file_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -#else -static int ump_file_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) -#endif -{ - int err = -ENOTTY; - void __user * argument; - struct ump_session_data * session_data; - -#ifndef HAVE_UNLOCKED_IOCTL - (void)inode; /* inode not used */ -#endif - - session_data = (struct ump_session_data *)filp->private_data; - if (NULL == session_data) - { - MSG_ERR(("No session data attached to file object\n")); - return -ENOTTY; - } - - /* interpret the argument as a user pointer to something */ - argument = (void __user *)arg; - - switch (cmd) - { - case UMP_IOC_QUERY_API_VERSION: - err = ump_get_api_version_wrapper((u32 __user *)argument, session_data); - break; - - case UMP_IOC_ALLOCATE : - err = ump_allocate_wrapper((u32 __user *)argument, session_data); - break; -#ifdef CONFIG_ION_EXYNOS - case UMP_IOC_ION_IMPORT: - err = ump_ion_import_wrapper((u32 __user *)argument, session_data); - break; -#endif -#ifdef CONFIG_DMA_SHARED_BUFFER - case UMP_IOC_DMABUF_IMPORT: - err = ump_dmabuf_import_wrapper((u32 __user *)argument, - session_data); - break; -#endif - case UMP_IOC_RELEASE: - err = ump_release_wrapper((u32 __user *)argument, session_data); - break; - - case UMP_IOC_SIZE_GET: - err = ump_size_get_wrapper((u32 __user *)argument, session_data); - break; - - case UMP_IOC_MSYNC: - err = ump_msync_wrapper((u32 __user *)argument, session_data); - break; - - case UMP_IOC_CACHE_OPERATIONS_CONTROL: - err = ump_cache_operations_control_wrapper((u32 __user *)argument, session_data); - break; - - case UMP_IOC_SWITCH_HW_USAGE: - err = ump_switch_hw_usage_wrapper((u32 __user *)argument, session_data); - break; - - case UMP_IOC_LOCK: - err = ump_lock_wrapper((u32 __user *)argument, session_data); - break; - - case UMP_IOC_UNLOCK: - err = ump_unlock_wrapper((u32 __user *)argument, session_data); - break; - - default: - DBG_MSG(1, ("No handler for IOCTL. cmd: 0x%08x, arg: 0x%08lx\n", cmd, arg)); - err = -EFAULT; - break; - } - - return err; -} - -#ifndef CONFIG_VIDEO_UMP -int map_errcode( _mali_osk_errcode_t err ) -{ - switch(err) - { - case _MALI_OSK_ERR_OK : return 0; - case _MALI_OSK_ERR_FAULT: return -EFAULT; - case _MALI_OSK_ERR_INVALID_FUNC: return -ENOTTY; - case _MALI_OSK_ERR_INVALID_ARGS: return -EINVAL; - case _MALI_OSK_ERR_NOMEM: return -ENOMEM; - case _MALI_OSK_ERR_TIMEOUT: return -ETIMEDOUT; - case _MALI_OSK_ERR_RESTARTSYSCALL: return -ERESTARTSYS; - case _MALI_OSK_ERR_ITEM_NOT_FOUND: return -ENOENT; - default: return -EFAULT; - } -} -#endif - -/* - * Handle from OS to map specified virtual memory to specified UMP memory. - */ -static int ump_file_mmap(struct file * filp, struct vm_area_struct * vma) -{ - _ump_uk_map_mem_s args; - _mali_osk_errcode_t err; - struct ump_session_data * session_data; - - /* Validate the session data */ - session_data = (struct ump_session_data *)filp->private_data; - if (NULL == session_data || NULL == session_data->cookies_map->table->mappings) - { - MSG_ERR(("mmap() called without any session data available\n")); - return -EFAULT; - } - - /* Re-pack the arguments that mmap() packed for us */ - args.ctx = session_data; - args.phys_addr = 0; - args.size = vma->vm_end - vma->vm_start; - args._ukk_private = vma; - args.secure_id = vma->vm_pgoff; - args.is_cached = 0; - - if (!(vma->vm_flags & VM_SHARED)) - { - args.is_cached = 1; - vma->vm_flags = vma->vm_flags | VM_SHARED | VM_MAYSHARE ; - DBG_MSG(3, ("UMP Map function: Forcing the CPU to use cache\n")); - } - /* By setting this flag, during a process fork; the child process will not have the parent UMP mappings */ - vma->vm_flags |= VM_DONTCOPY; - - DBG_MSG(4, ("UMP vma->flags: %x\n", vma->vm_flags )); - - /* Call the common mmap handler */ - err = _ump_ukk_map_mem( &args ); - if ( _MALI_OSK_ERR_OK != err) - { - MSG_ERR(("_ump_ukk_map_mem() failed in function ump_file_mmap()")); - return map_errcode( err ); - } - - return 0; /* success */ -} - -/* Export UMP kernel space API functions */ -EXPORT_SYMBOL(ump_dd_secure_id_get); -EXPORT_SYMBOL(ump_dd_handle_create_from_secure_id); -EXPORT_SYMBOL(ump_dd_phys_block_count_get); -EXPORT_SYMBOL(ump_dd_phys_block_get); -EXPORT_SYMBOL(ump_dd_phys_blocks_get); -EXPORT_SYMBOL(ump_dd_size_get); -EXPORT_SYMBOL(ump_dd_reference_add); -EXPORT_SYMBOL(ump_dd_reference_release); -EXPORT_SYMBOL(ump_dd_meminfo_get); -EXPORT_SYMBOL(ump_dd_meminfo_set); -EXPORT_SYMBOL(ump_dd_handle_get_from_vaddr); - -/* Export our own extended kernel space allocator */ -EXPORT_SYMBOL(ump_dd_handle_create_from_phys_blocks); - -/* Setup init and exit functions for this module */ -//module_init(ump_initialize_module); -arch_initcall(ump_initialize_module); -module_exit(ump_cleanup_module); - -/* And some module informatio */ -MODULE_LICENSE(UMP_KERNEL_LINUX_LICENSE); -MODULE_AUTHOR("ARM Ltd."); -MODULE_VERSION(SVN_REV_STRING); diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_linux.h b/drivers/media/video/samsung/ump/linux/ump_kernel_linux.h deleted file mode 100644 index 4985bb7..0000000 --- a/drivers/media/video/samsung/ump/linux/ump_kernel_linux.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __UMP_KERNEL_LINUX_H__ -#define __UMP_KERNEL_LINUX_H__ - -int ump_kernel_device_initialize(void); -void ump_kernel_device_terminate(void); - - -#endif /* __UMP_KERNEL_H__ */ diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c deleted file mode 100644 index 82c16cc..0000000 --- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/* needed to detect kernel version specific code */ -#include - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) -#include -#else /* pre 2.6.26 the file was in the arch specific location */ -#include -#endif - -#include -#include -#include -#include -#include "ump_kernel_common.h" -#include "ump_kernel_memory_backend.h" - - - -#define UMP_BLOCK_SIZE (256UL * 1024UL) /* 256kB, remember to keep the ()s */ - - - -typedef struct block_info -{ - struct block_info * next; -} block_info; - - - -typedef struct block_allocator -{ - struct semaphore mutex; - block_info * all_blocks; - block_info * first_free; - u32 base; - u32 num_blocks; - u32 num_free; -} block_allocator; - - -static void block_allocator_shutdown(ump_memory_backend * backend); -static int block_allocator_allocate(void* ctx, ump_dd_mem * mem); -static void block_allocator_release(void * ctx, ump_dd_mem * handle); -static inline u32 get_phys(block_allocator * allocator, block_info * block); -static u32 block_allocator_stat(struct ump_memory_backend *backend); - - - -/* - * Create dedicated memory backend - */ -ump_memory_backend * ump_block_allocator_create(u32 base_address, u32 size) -{ - ump_memory_backend * backend; - block_allocator * allocator; - u32 usable_size; - u32 num_blocks; - - usable_size = (size + UMP_BLOCK_SIZE - 1) & ~(UMP_BLOCK_SIZE - 1); - num_blocks = usable_size / UMP_BLOCK_SIZE; - - if (0 == usable_size) - { - DBG_MSG(1, ("Memory block of size %u is unusable\n", size)); - return NULL; - } - - DBG_MSG(5, ("Creating dedicated UMP memory backend. Base address: 0x%08x, size: 0x%08x\n", base_address, size)); - DBG_MSG(6, ("%u usable bytes which becomes %u blocks\n", usable_size, num_blocks)); - - backend = kzalloc(sizeof(ump_memory_backend), GFP_KERNEL); - if (NULL != backend) - { - allocator = kmalloc(sizeof(block_allocator), GFP_KERNEL); - if (NULL != allocator) - { - allocator->all_blocks = kmalloc(sizeof(block_allocator) * num_blocks, GFP_KERNEL); - if (NULL != allocator->all_blocks) - { - int i; - - allocator->first_free = NULL; - allocator->num_blocks = num_blocks; - allocator->num_free = num_blocks; - allocator->base = base_address; - sema_init(&allocator->mutex, 1); - - for (i = 0; i < num_blocks; i++) - { - allocator->all_blocks[i].next = allocator->first_free; - allocator->first_free = &allocator->all_blocks[i]; - } - - backend->ctx = allocator; - backend->allocate = block_allocator_allocate; - backend->release = block_allocator_release; - backend->shutdown = block_allocator_shutdown; - backend->stat = block_allocator_stat; - backend->pre_allocate_physical_check = NULL; - backend->adjust_to_mali_phys = NULL; - backend->get = NULL; - backend->set = NULL; - - return backend; - } - kfree(allocator); - } - kfree(backend); - } - - return NULL; -} - - - -/* - * Destroy specified dedicated memory backend - */ -static void block_allocator_shutdown(ump_memory_backend * backend) -{ - block_allocator * allocator; - - BUG_ON(!backend); - BUG_ON(!backend->ctx); - - allocator = (block_allocator*)backend->ctx; - - DBG_MSG_IF(1, allocator->num_free != allocator->num_blocks, ("%u blocks still in use during shutdown\n", allocator->num_blocks - allocator->num_free)); - - kfree(allocator->all_blocks); - kfree(allocator); - kfree(backend); -} - - - -static int block_allocator_allocate(void* ctx, ump_dd_mem * mem) -{ - block_allocator * allocator; - u32 left; - block_info * last_allocated = NULL; - int i = 0; - - BUG_ON(!ctx); - BUG_ON(!mem); - - allocator = (block_allocator*)ctx; - left = mem->size_bytes; - - BUG_ON(!left); - BUG_ON(!&allocator->mutex); - - mem->nr_blocks = ((left + UMP_BLOCK_SIZE - 1) & ~(UMP_BLOCK_SIZE - 1)) / UMP_BLOCK_SIZE; - mem->block_array = (ump_dd_physical_block*)vmalloc(sizeof(ump_dd_physical_block) * mem->nr_blocks); - if (NULL == mem->block_array) - { - MSG_ERR(("Failed to allocate block array\n")); - return 0; - } - - if (down_interruptible(&allocator->mutex)) - { - MSG_ERR(("Could not get mutex to do block_allocate\n")); - return 0; - } - - mem->size_bytes = 0; - - while ((left > 0) && (allocator->first_free)) - { - block_info * block; - - block = allocator->first_free; - allocator->first_free = allocator->first_free->next; - block->next = last_allocated; - last_allocated = block; - allocator->num_free--; - - mem->block_array[i].addr = get_phys(allocator, block); - mem->block_array[i].size = UMP_BLOCK_SIZE; - mem->size_bytes += UMP_BLOCK_SIZE; - - i++; - - if (left < UMP_BLOCK_SIZE) left = 0; - else left -= UMP_BLOCK_SIZE; - } - - if (left) - { - block_info * block; - /* release all memory back to the pool */ - while (last_allocated) - { - block = last_allocated->next; - last_allocated->next = allocator->first_free; - allocator->first_free = last_allocated; - last_allocated = block; - allocator->num_free++; - } - - vfree(mem->block_array); - mem->backend_info = NULL; - mem->block_array = NULL; - - DBG_MSG(4, ("Could not find a mem-block for the allocation.\n")); - up(&allocator->mutex); - - return 0; - } - - mem->backend_info = last_allocated; - - up(&allocator->mutex); - mem->is_cached=0; - - return 1; -} - - - -static void block_allocator_release(void * ctx, ump_dd_mem * handle) -{ - block_allocator * allocator; - block_info * block, * next; - - BUG_ON(!ctx); - BUG_ON(!handle); - - allocator = (block_allocator*)ctx; - block = (block_info*)handle->backend_info; - BUG_ON(!block); - - if (down_interruptible(&allocator->mutex)) - { - MSG_ERR(("Allocator release: Failed to get mutex - memory leak\n")); - return; - } - - while (block) - { - next = block->next; - - BUG_ON( (block < allocator->all_blocks) || (block > (allocator->all_blocks + allocator->num_blocks))); - - block->next = allocator->first_free; - allocator->first_free = block; - allocator->num_free++; - - block = next; - } - DBG_MSG(3, ("%d blocks free after release call\n", allocator->num_free)); - up(&allocator->mutex); - - vfree(handle->block_array); - handle->block_array = NULL; -} - - - -/* - * Helper function for calculating the physical base adderss of a memory block - */ -static inline u32 get_phys(block_allocator * allocator, block_info * block) -{ - return allocator->base + ((block - allocator->all_blocks) * UMP_BLOCK_SIZE); -} - -static u32 block_allocator_stat(struct ump_memory_backend *backend) -{ - block_allocator *allocator; - BUG_ON(!backend); - allocator = (block_allocator*)backend->ctx; - BUG_ON(!allocator); - - return (allocator->num_blocks - allocator->num_free)* UMP_BLOCK_SIZE; -} diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.h b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.h deleted file mode 100644 index ca8faae..0000000 --- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file ump_kernel_memory_backend_dedicated.h - */ - -#ifndef __UMP_KERNEL_MEMORY_BACKEND_DEDICATED_H__ -#define __UMP_KERNEL_MEMORY_BACKEND_DEDICATED_H__ - -#include "ump_kernel_memory_backend.h" - -ump_memory_backend * ump_block_allocator_create(u32 base_address, u32 size); - -#endif /* __UMP_KERNEL_MEMORY_BACKEND_DEDICATED_H__ */ - diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c deleted file mode 100644 index 8f6a9b3..0000000 --- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/* needed to detect kernel version specific code */ -#include - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) -#include -#else /* pre 2.6.26 the file was in the arch specific location */ -#include -#endif - -#include -#include -#include -#include -#include -#include -#include "ump_kernel_common.h" -#include "ump_kernel_memory_backend.h" - - - -typedef struct os_allocator -{ - struct semaphore mutex; - u32 num_pages_max; /**< Maximum number of pages to allocate from the OS */ - u32 num_pages_allocated; /**< Number of pages allocated from the OS */ -} os_allocator; - - - -static void os_free(void* ctx, ump_dd_mem * descriptor); -static int os_allocate(void* ctx, ump_dd_mem * descriptor); -static void os_memory_backend_destroy(ump_memory_backend * backend); -static u32 os_stat(struct ump_memory_backend *backend); - - - -/* - * Create OS memory backend - */ -ump_memory_backend * ump_os_memory_backend_create(const int max_allocation) -{ - ump_memory_backend * backend; - os_allocator * info; - - info = kmalloc(sizeof(os_allocator), GFP_KERNEL); - if (NULL == info) - { - return NULL; - } - - info->num_pages_max = max_allocation >> PAGE_SHIFT; - info->num_pages_allocated = 0; - - sema_init(&info->mutex, 1); - - backend = kmalloc(sizeof(ump_memory_backend), GFP_KERNEL); - if (NULL == backend) - { - kfree(info); - return NULL; - } - - backend->ctx = info; - backend->allocate = os_allocate; - backend->release = os_free; - backend->shutdown = os_memory_backend_destroy; - backend->stat = os_stat; - backend->pre_allocate_physical_check = NULL; - backend->adjust_to_mali_phys = NULL; - backend->get = NULL; - backend->set = NULL; - - return backend; -} - - - -/* - * Destroy specified OS memory backend - */ -static void os_memory_backend_destroy(ump_memory_backend * backend) -{ - os_allocator * info = (os_allocator*)backend->ctx; - - DBG_MSG_IF(1, 0 != info->num_pages_allocated, ("%d pages still in use during shutdown\n", info->num_pages_allocated)); - - kfree(info); - kfree(backend); -} - - - -/* - * Allocate UMP memory - */ -static int os_allocate(void* ctx, ump_dd_mem * descriptor) -{ - u32 left; - os_allocator * info; - int pages_allocated = 0; - int is_cached; - - BUG_ON(!descriptor); - BUG_ON(!ctx); - - info = (os_allocator*)ctx; - left = descriptor->size_bytes; - is_cached = descriptor->is_cached; - - if (down_interruptible(&info->mutex)) - { - DBG_MSG(1, ("Failed to get mutex in os_free\n")); - return 0; /* failure */ - } - - descriptor->backend_info = NULL; - descriptor->nr_blocks = ((left + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) >> PAGE_SHIFT; - - DBG_MSG(5, ("Allocating page array. Size: %lu\n", descriptor->nr_blocks * sizeof(ump_dd_physical_block))); - - descriptor->block_array = (ump_dd_physical_block *)vmalloc(sizeof(ump_dd_physical_block) * descriptor->nr_blocks); - if (NULL == descriptor->block_array) - { - up(&info->mutex); - DBG_MSG(1, ("Block array could not be allocated\n")); - return 0; /* failure */ - } - - while (left > 0) - { - struct page * new_page; - - if (is_cached) - { - new_page = alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_NORETRY | __GFP_NOWARN ); - } else - { - new_page = alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_NORETRY | __GFP_NOWARN | __GFP_COLD); - } - if (NULL == new_page) - { - MSG_ERR(("UMP memory allocated: Out of Memory !!\n")); - break; - } - - /* Ensure page caches are flushed. */ - if ( is_cached ) - { - descriptor->block_array[pages_allocated].addr = page_to_phys(new_page); - descriptor->block_array[pages_allocated].size = PAGE_SIZE; - } else - { - descriptor->block_array[pages_allocated].addr = dma_map_page(NULL, new_page, 0, PAGE_SIZE, DMA_BIDIRECTIONAL ); - descriptor->block_array[pages_allocated].size = PAGE_SIZE; - } - - DBG_MSG(5, ("Allocated page 0x%08lx cached: %d\n", descriptor->block_array[pages_allocated].addr, is_cached)); - - if (left < PAGE_SIZE) - { - left = 0; - } - else - { - left -= PAGE_SIZE; - } - - pages_allocated++; - } - - DBG_MSG(5, ("Alloce for ID:%2d got %d pages, cached: %d\n", descriptor->secure_id, pages_allocated)); - - if (left) - { - DBG_MSG(1, ("Failed to allocate needed pages\n")); - DBG_MSG(1, ("UMP memory allocated: %d kB Configured maximum OS memory usage: %d kB\n", - (pages_allocated * _MALI_OSK_CPU_PAGE_SIZE)/1024, (info->num_pages_max* _MALI_OSK_CPU_PAGE_SIZE)/1024)); - - while(pages_allocated) - { - pages_allocated--; - if ( !is_cached ) - { - dma_unmap_page(NULL, descriptor->block_array[pages_allocated].addr, PAGE_SIZE, DMA_BIDIRECTIONAL); - } - __free_page(pfn_to_page(descriptor->block_array[pages_allocated].addr >> PAGE_SHIFT) ); - } - - up(&info->mutex); - - return 0; /* failure */ - } - - info->num_pages_allocated += pages_allocated; - - DBG_MSG(6, ("%d out of %d pages now allocated\n", info->num_pages_allocated, info->num_pages_max)); - - up(&info->mutex); - - return 1; /* success*/ -} - - -/* - * Free specified UMP memory - */ -static void os_free(void* ctx, ump_dd_mem * descriptor) -{ - os_allocator * info; - int i; - - BUG_ON(!ctx); - BUG_ON(!descriptor); - - info = (os_allocator*)ctx; - - BUG_ON(descriptor->nr_blocks > info->num_pages_allocated); - - if (down_interruptible(&info->mutex)) - { - DBG_MSG(1, ("Failed to get mutex in os_free\n")); - return; - } - - DBG_MSG(5, ("Releasing %lu OS pages\n", descriptor->nr_blocks)); - - info->num_pages_allocated -= descriptor->nr_blocks; - - up(&info->mutex); - - for ( i = 0; i < descriptor->nr_blocks; i++) - { - DBG_MSG(6, ("Freeing physical page. Address: 0x%08lx\n", descriptor->block_array[i].addr)); - if ( ! descriptor->is_cached) - { - dma_unmap_page(NULL, descriptor->block_array[i].addr, PAGE_SIZE, DMA_BIDIRECTIONAL); - } - __free_page(pfn_to_page(descriptor->block_array[i].addr>>PAGE_SHIFT) ); - } - - vfree(descriptor->block_array); -} - - -static u32 os_stat(struct ump_memory_backend *backend) -{ - os_allocator *info; - info = (os_allocator*)backend->ctx; - return info->num_pages_allocated * _MALI_OSK_MALI_PAGE_SIZE; -} diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.h b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.h deleted file mode 100644 index 6f7e610..0000000 --- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file ump_kernel_memory_backend_os.h - */ - -#ifndef __UMP_KERNEL_MEMORY_BACKEND_OS_H__ -#define __UMP_KERNEL_MEMORY_BACKEND_OS_H__ - -#include "ump_kernel_memory_backend.h" - -ump_memory_backend * ump_os_memory_backend_create(const int max_allocation); - -#endif /* __UMP_KERNEL_MEMORY_BACKEND_OS_H__ */ - diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.c b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.c deleted file mode 100644 index 46797ea..0000000 --- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/* create by boojin.kim@samsung.com */ -/* needed to detect kernel version specific code */ -#include - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) -#include -#else /* pre 2.6.26 the file was in the arch specific location */ -#include -#endif - -#include -#include -#include -#include -#include -#include "ump_kernel_common.h" -#include "ump_kernel_memory_backend.h" -#include "ump_kernel_interface_ref_drv.h" -#include "ump_kernel_memory_backend_vcm.h" -#include "../common/ump_uk_types.h" -#include -#include -#include - -#define UMP_REF_DRV_UK_VCM_DEV_G2D 12 - -typedef struct ump_vcm { - struct vcm *vcm; - struct vcm_res *vcm_res; - unsigned int dev_id; -} ump_vcm; - -typedef struct vcm_allocator { - struct semaphore mutex; - u32 num_vcm_blocks; -} vcm_allocator; - -static void ump_vcm_free(void* ctx, ump_dd_mem * descriptor); -static int ump_vcm_allocate(void* ctx, ump_dd_mem * descriptor); -static void *vcm_res_get(ump_dd_mem *mem, void* args); -static void vcm_attr_set(ump_dd_mem *mem, void* args); -static int vcm_mem_allocator(vcm_allocator *info, ump_dd_mem *descriptor); -static void vcm_memory_backend_destroy(ump_memory_backend * backend); - - -/* - * Create VCM memory backend - */ -ump_memory_backend * ump_vcm_memory_backend_create(const int max_allocation) -{ - ump_memory_backend * backend; - vcm_allocator * info; - - info = kmalloc(sizeof(vcm_allocator), GFP_KERNEL); - if (NULL == info) - { - return NULL; - } - - info->num_vcm_blocks = 0; - - - sema_init(&info->mutex, 1); - - backend = kmalloc(sizeof(ump_memory_backend), GFP_KERNEL); - if (NULL == backend) - { - kfree(info); - return NULL; - } - - backend->ctx = info; - backend->allocate = ump_vcm_allocate; - backend->release = ump_vcm_free; - backend->shutdown = vcm_memory_backend_destroy; - backend->pre_allocate_physical_check = NULL; - backend->adjust_to_mali_phys = NULL; - - backend->get = vcm_res_get; - backend->set = vcm_attr_set; - - - return backend; -} - -/* - * Destroy specified VCM memory backend - */ -static void vcm_memory_backend_destroy(ump_memory_backend * backend) -{ - vcm_allocator * info = (vcm_allocator*)backend->ctx; -#if 0 - DBG_MSG_IF(1, 0 != info->num_pages_allocated, ("%d pages still in use during shutdown\n", info->num_pages_allocated)); -#endif - kfree(info); - kfree(backend); -} - -/* - * Allocate UMP memory - */ -static int ump_vcm_allocate(void *ctx, ump_dd_mem * descriptor) -{ - int ret; /* success */ - vcm_allocator *info; - struct ump_vcm *ump_vcm; - - BUG_ON(!descriptor); - BUG_ON(!ctx); - - info = (vcm_allocator*)ctx; - - ump_vcm = kmalloc(sizeof(struct ump_vcm), GFP_KERNEL); - if (NULL == ump_vcm) - { - return 0; - } - - ump_vcm->dev_id = (int)descriptor->backend_info & ~UMP_REF_DRV_UK_CONSTRAINT_USE_CACHE; - - if(ump_vcm->dev_id == UMP_REF_DRV_UK_CONSTRAINT_NONE) { /* None */ - ump_vcm->dev_id = UMP_REF_DRV_UK_VCM_DEV_G2D; /* this ID is G2D */ - } - else if(ump_vcm->dev_id == UMP_REF_DRV_UK_CONSTRAINT_PHYSICALLY_LINEAR) { /* Physical Linear */ - return 0; - } - else { /* Other VCM */ - ump_vcm->dev_id -= 2; - } - - DBG_MSG(5, ("Device ID for VCM : %d\n", ump_vcm->dev_id)); - ump_vcm->vcm = vcm_find_vcm(ump_vcm->dev_id); - - if (!ump_vcm->vcm) - { - return 0; - } - descriptor->backend_info = (void*)ump_vcm; - - if (down_interruptible(&info->mutex)) { - DBG_MSG(1, ("Failed to get mutex in ump_vcm_allocate\n")); - return 0; /* failure */ - } - - ret = vcm_mem_allocator(info, descriptor); - up(&info->mutex); - - return ret; /* success */ -} - -static int vcm_mem_allocator(vcm_allocator *info, ump_dd_mem *descriptor) -{ - unsigned long num_blocks; - int i; - struct vcm_phys *phys; - struct vcm_phys_part *part; - int size_total = 0; - struct ump_vcm *ump_vcm; - - ump_vcm = (struct ump_vcm*)descriptor->backend_info; - - ump_vcm->vcm_res = - vcm_make_binding(ump_vcm->vcm, descriptor->size_bytes, - ump_vcm->dev_id, 0); - - phys = ump_vcm->vcm_res->phys; - part = phys->parts; - num_blocks = phys->count; - - DBG_MSG(5, - ("Allocating page array. Size: %lu, VCM Reservation : 0x%x\n", - phys->count * sizeof(ump_dd_physical_block), - ump_vcm->vcm_res->start)); - - /* Now, make a copy of the block information supplied by the user */ - descriptor->block_array = - (ump_dd_physical_block *) vmalloc(sizeof(ump_dd_physical_block) * - num_blocks); - - if (NULL == descriptor->block_array) { - vfree(descriptor->block_array); - DBG_MSG(1, ("Could not allocate a mem handle for function.\n")); - return 0; /* failure */ - } - - for (i = 0; i < num_blocks; i++) { - descriptor->block_array[i].addr = part->start; - descriptor->block_array[i].size = part->size; - - dmac_unmap_area(phys_to_virt(part->start), part->size, DMA_FROM_DEVICE); - outer_inv_range(part->start, part->start + part->size); - - ++part; - size_total += descriptor->block_array[i].size; - DBG_MSG(6, - ("UMP memory created with VCM. addr 0x%x, size: 0x%x\n", - descriptor->block_array[i].addr, - descriptor->block_array[i].size)); - } - - descriptor->size_bytes = size_total; - descriptor->nr_blocks = num_blocks; - descriptor->ctx = NULL; - - info->num_vcm_blocks += num_blocks; - return 1; -} - -/* - * Free specified UMP memory - */ -static void ump_vcm_free(void *ctx, ump_dd_mem * descriptor) -{ - struct ump_vcm *ump_vcm; - vcm_allocator *info; - - BUG_ON(!descriptor); - BUG_ON(!ctx); - - ump_vcm = (struct ump_vcm*)descriptor->backend_info; - info = (vcm_allocator*)ctx; - - BUG_ON(descriptor->nr_blocks > info->num_vcm_blocks); - - if (down_interruptible(&info->mutex)) { - DBG_MSG(1, ("Failed to get mutex in ump_vcm_free\n")); - return; - } - - DBG_MSG(5, ("Releasing %lu VCM pages\n", descriptor->nr_blocks)); - - info->num_vcm_blocks -= descriptor->nr_blocks; - - up(&info->mutex); - - DBG_MSG(6, ("Freeing physical page by VCM\n")); - vcm_destroy_binding(ump_vcm->vcm_res); - ump_vcm->vcm = NULL; - ump_vcm->vcm_res = NULL; - - kfree(ump_vcm); - vfree(descriptor->block_array); -} - -static void *vcm_res_get(ump_dd_mem *mem, void *args) -{ - struct ump_vcm *ump_vcm; - enum vcm_dev_id vcm_id; - - ump_vcm = (struct ump_vcm*)mem->backend_info; - vcm_id = (enum vcm_dev_id)args; - - if (vcm_reservation_in_vcm - (vcm_find_vcm(vcm_id), ump_vcm->vcm_res) - == S5PVCM_RES_NOT_IN_VCM) - return NULL; - else - return ump_vcm->vcm_res; -} - -static void vcm_attr_set(ump_dd_mem *mem, void *args) -{ - struct ump_vcm *ump_vcm, *ump_vcmh; - - ump_vcm = (struct ump_vcm*)args; - - ump_vcmh = kmalloc(sizeof(struct ump_vcm), GFP_KERNEL); - if (NULL == ump_vcmh) - { - return; - } - - ump_vcmh->dev_id = ump_vcm->dev_id; - ump_vcmh->vcm = ump_vcm->vcm; - ump_vcmh->vcm_res = ump_vcm->vcm_res; - - mem->backend_info= (void*)ump_vcmh; - - return; -} diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.h b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.h deleted file mode 100644 index c1ead0d..0000000 --- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file ump_kernel_memory_backend_vcm.h - */ - -#ifndef __UMP_KERNEL_MEMORY_BACKEND_VCM_H__ -#define __UMP_KERNEL_MEMORY_BACKEND_VCM_H__ - -#include "ump_kernel_memory_backend.h" - -ump_memory_backend * ump_vcm_memory_backend_create(const int max_allocation); - -#endif /* __UMP_KERNEL_MEMORY_BACKEND_VCM_H__ */ diff --git a/drivers/media/video/samsung/ump/linux/ump_memory_backend.c b/drivers/media/video/samsung/ump/linux/ump_memory_backend.c deleted file mode 100644 index d067cfe..0000000 --- a/drivers/media/video/samsung/ump/linux/ump_memory_backend.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include /* kernel module definitions */ -#include /* request_mem_region */ - -#include "arch/config.h" /* Configuration for current platform. The symlink for arch is set by Makefile */ - -#include "ump_osk.h" -#include "ump_kernel_common.h" -#include "ump_kernel_memory_backend_os.h" -#include "ump_kernel_memory_backend_dedicated.h" - -/* Configure which dynamic memory allocator to use */ -int ump_backend = ARCH_UMP_BACKEND_DEFAULT; -module_param(ump_backend, int, S_IRUGO); /* r--r--r-- */ -MODULE_PARM_DESC(ump_backend, "0 = dedicated memory backend (default), 1 = OS memory backend"); - -/* The base address of the memory block for the dedicated memory backend */ -unsigned int ump_memory_address = ARCH_UMP_MEMORY_ADDRESS_DEFAULT; -module_param(ump_memory_address, uint, S_IRUGO); /* r--r--r-- */ -MODULE_PARM_DESC(ump_memory_address, "The physical address to map for the dedicated memory backend"); - -/* The size of the memory block for the dedicated memory backend */ -unsigned int ump_memory_size = ARCH_UMP_MEMORY_SIZE_DEFAULT; -module_param(ump_memory_size, uint, S_IRUGO); /* r--r--r-- */ -MODULE_PARM_DESC(ump_memory_size, "The size of fixed memory to map in the dedicated memory backend"); - -ump_memory_backend* ump_memory_backend_create ( void ) -{ - ump_memory_backend * backend = NULL; - - /* Create the dynamic memory allocator backend */ - if (0 == ump_backend) - { - DBG_MSG(2, ("Using dedicated memory backend\n")); - - DBG_MSG(2, ("Requesting dedicated memory: 0x%08x, size: %u\n", ump_memory_address, ump_memory_size)); - /* Ask the OS if we can use the specified physical memory */ - if (NULL == request_mem_region(ump_memory_address, ump_memory_size, "UMP Memory")) - { - MSG_ERR(("Failed to request memory region (0x%08X - 0x%08X). Is Mali DD already loaded?\n", ump_memory_address, ump_memory_address + ump_memory_size - 1)); - return NULL; - } - backend = ump_block_allocator_create(ump_memory_address, ump_memory_size); - } - else if (1 == ump_backend) - { - DBG_MSG(2, ("Using OS memory backend, allocation limit: %d\n", ump_memory_size)); - backend = ump_os_memory_backend_create(ump_memory_size); - } -#ifdef CONFIG_UMP_VCM_ALLOC - else if (2 == ump_backend) - { - DBG_MSG(2, ("Using VCM memory backend, allocation limit: %d\n", ump_memory_size)); - backend = ump_vcm_memory_backend_create(ump_memory_size); - } -#endif - - return backend; -} - -void ump_memory_backend_destroy( void ) -{ - if (0 == ump_backend) - { - DBG_MSG(2, ("Releasing dedicated memory: 0x%08x\n", ump_memory_address)); - release_mem_region(ump_memory_address, ump_memory_size); - } -} diff --git a/drivers/media/video/samsung/ump/linux/ump_osk_atomics.c b/drivers/media/video/samsung/ump/linux/ump_osk_atomics.c deleted file mode 100644 index b117d99..0000000 --- a/drivers/media/video/samsung/ump/linux/ump_osk_atomics.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file ump_osk_atomics.c - * Implementation of the OS abstraction layer for the UMP kernel device driver - */ - -#include "ump_osk.h" -#include - -int _ump_osk_atomic_dec_and_read( _mali_osk_atomic_t *atom ) -{ - return atomic_dec_return((atomic_t *)&atom->u.val); -} - -int _ump_osk_atomic_inc_and_read( _mali_osk_atomic_t *atom ) -{ - return atomic_inc_return((atomic_t *)&atom->u.val); -} diff --git a/drivers/media/video/samsung/ump/linux/ump_osk_low_level_mem.c b/drivers/media/video/samsung/ump/linux/ump_osk_low_level_mem.c deleted file mode 100644 index 8ae169a..0000000 --- a/drivers/media/video/samsung/ump/linux/ump_osk_low_level_mem.c +++ /dev/null @@ -1,485 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file ump_osk_memory.c - * Implementation of the OS abstraction layer for the kernel device driver - */ - -/* needed to detect kernel version specific code */ -#include - -#include "ump_osk.h" -#include "ump_uk_types.h" -#include "ump_ukk.h" -#include "ump_kernel_common.h" -#include /* kernel module definitions */ -#include -#include -#include -#include - -#include -#include /* to verify pointers from user space */ -#include -#include - -typedef struct ump_vma_usage_tracker -{ - atomic_t references; - ump_memory_allocation *descriptor; -} ump_vma_usage_tracker; - -static void ump_vma_open(struct vm_area_struct * vma); -static void ump_vma_close(struct vm_area_struct * vma); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) -static int ump_cpu_page_fault_handler(struct vm_area_struct *vma, struct vm_fault *vmf); -#else -static unsigned long ump_cpu_page_fault_handler(struct vm_area_struct * vma, unsigned long address); -#endif - -static struct vm_operations_struct ump_vm_ops = -{ - .open = ump_vma_open, - .close = ump_vma_close, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) - .fault = ump_cpu_page_fault_handler -#else - .nopfn = ump_cpu_page_fault_handler -#endif -}; - -/* - * Page fault for VMA region - * This should never happen since we always map in the entire virtual memory range. - */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) -static int ump_cpu_page_fault_handler(struct vm_area_struct *vma, struct vm_fault *vmf) -#else -static unsigned long ump_cpu_page_fault_handler(struct vm_area_struct * vma, unsigned long address) -#endif -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) - void __user * address; - address = vmf->virtual_address; -#endif - MSG_ERR(("Page-fault in UMP memory region caused by the CPU\n")); - MSG_ERR(("VMA: 0x%08lx, virtual address: 0x%08lx\n", (unsigned long)vma, address)); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) - return VM_FAULT_SIGBUS; -#else - return NOPFN_SIGBUS; -#endif -} - -static void ump_vma_open(struct vm_area_struct * vma) -{ - ump_vma_usage_tracker * vma_usage_tracker; - int new_val; - - vma_usage_tracker = (ump_vma_usage_tracker*)vma->vm_private_data; - BUG_ON(NULL == vma_usage_tracker); - - new_val = atomic_inc_return(&vma_usage_tracker->references); - - DBG_MSG(4, ("VMA open, VMA reference count incremented. VMA: 0x%08lx, reference count: %d\n", (unsigned long)vma, new_val)); -} - -static void ump_vma_close(struct vm_area_struct * vma) -{ - ump_vma_usage_tracker * vma_usage_tracker; - _ump_uk_unmap_mem_s args; - int new_val; - - vma_usage_tracker = (ump_vma_usage_tracker*)vma->vm_private_data; - BUG_ON(NULL == vma_usage_tracker); - - new_val = atomic_dec_return(&vma_usage_tracker->references); - - DBG_MSG(4, ("VMA close, VMA reference count decremented. VMA: 0x%08lx, reference count: %d\n", (unsigned long)vma, new_val)); - - if (0 == new_val) - { - ump_memory_allocation * descriptor; - - descriptor = vma_usage_tracker->descriptor; - - args.ctx = descriptor->ump_session; - args.cookie = descriptor->cookie; - args.mapping = descriptor->mapping; - args.size = descriptor->size; - - args._ukk_private = NULL; /** @note unused */ - - DBG_MSG(4, ("No more VMA references left, releasing UMP memory\n")); - _ump_ukk_unmap_mem( & args ); - - /* vma_usage_tracker is free()d by _ump_osk_mem_mapregion_term() */ - } -} - -_mali_osk_errcode_t _ump_osk_mem_mapregion_init( ump_memory_allocation * descriptor ) -{ - ump_vma_usage_tracker * vma_usage_tracker; - struct vm_area_struct *vma; - - if (NULL == descriptor) return _MALI_OSK_ERR_FAULT; - - vma_usage_tracker = kmalloc(sizeof(ump_vma_usage_tracker), GFP_KERNEL); - if (NULL == vma_usage_tracker) - { - DBG_MSG(1, ("Failed to allocate memory for ump_vma_usage_tracker in _mali_osk_mem_mapregion_init\n")); - return -_MALI_OSK_ERR_FAULT; - } - - vma = (struct vm_area_struct*)descriptor->process_mapping_info; - if (NULL == vma ) - { - kfree(vma_usage_tracker); - return _MALI_OSK_ERR_FAULT; - } - - vma->vm_private_data = vma_usage_tracker; - vma->vm_flags |= VM_IO; - vma->vm_flags |= VM_RESERVED; - - if (0==descriptor->is_cached) - { - vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); - } - DBG_MSG(3, ("Mapping with page_prot: 0x%x\n", vma->vm_page_prot )); - - /* Setup the functions which handle further VMA handling */ - vma->vm_ops = &ump_vm_ops; - - /* Do the va range allocation - in this case, it was done earlier, so we copy in that information */ - descriptor->mapping = (void __user*)vma->vm_start; - - atomic_set(&vma_usage_tracker->references, 1); /*this can later be increased if process is forked, see ump_vma_open() */ - vma_usage_tracker->descriptor = descriptor; - - return _MALI_OSK_ERR_OK; -} - -void _ump_osk_mem_mapregion_term( ump_memory_allocation * descriptor ) -{ - struct vm_area_struct* vma; - ump_vma_usage_tracker * vma_usage_tracker; - - if (NULL == descriptor) return; - - /* Linux does the right thing as part of munmap to remove the mapping - * All that remains is that we remove the vma_usage_tracker setup in init() */ - vma = (struct vm_area_struct*)descriptor->process_mapping_info; - - vma_usage_tracker = vma->vm_private_data; - - /* We only get called if mem_mapregion_init succeeded */ - kfree(vma_usage_tracker); - return; -} - -_mali_osk_errcode_t _ump_osk_mem_mapregion_map( ump_memory_allocation * descriptor, u32 offset, u32 * phys_addr, unsigned long size ) -{ - struct vm_area_struct *vma; - _mali_osk_errcode_t retval; - - if (NULL == descriptor) return _MALI_OSK_ERR_FAULT; - - vma = (struct vm_area_struct*)descriptor->process_mapping_info; - - if (NULL == vma ) return _MALI_OSK_ERR_FAULT; - - retval = remap_pfn_range( vma, ((u32)descriptor->mapping) + offset, (*phys_addr) >> PAGE_SHIFT, size, vma->vm_page_prot) ? _MALI_OSK_ERR_FAULT : _MALI_OSK_ERR_OK;; - - DBG_MSG(4, ("Mapping virtual to physical memory. ID: %u, vma: 0x%08lx, virtual addr:0x%08lx, physical addr: 0x%08lx, size:%lu, prot:0x%x, vm_flags:0x%x RETVAL: 0x%x\n", - ump_dd_secure_id_get(descriptor->handle), - (unsigned long)vma, - (unsigned long)(vma->vm_start + offset), - (unsigned long)*phys_addr, - size, - (unsigned int)vma->vm_page_prot, vma->vm_flags, retval)); - - return retval; -} - -static u32 _ump_osk_virt_to_phys_start(ump_dd_mem * mem, u32 start, u32 address, int *index) -{ - int i; - u32 offset = address - start; - ump_dd_physical_block *block; - u32 sum = 0; - - for (i=0; inr_blocks; i++) { - block = &mem->block_array[i]; - sum += block->size; - if (sum > offset) { - *index = i; - DBG_MSG(3, ("_ump_osk_virt_to_phys : index : %d, virtual 0x%x, phys 0x%x\n", i, address, (u32)block->addr + offset - (sum -block->size))); - return (u32)block->addr + offset - (sum -block->size); - } - } - - return _MALI_OSK_ERR_FAULT; -} - -static u32 _ump_osk_virt_to_phys_end(ump_dd_mem * mem, u32 start, u32 address, int *index) -{ - int i; - u32 offset = address - start; - ump_dd_physical_block *block; - u32 sum = 0; - - for (i=0; inr_blocks; i++) { - block = &mem->block_array[i]; - sum += block->size; - if (sum >= offset) { - *index = i; - DBG_MSG(3, ("_ump_osk_virt_to_phys : index : %d, virtual 0x%x, phys 0x%x\n", i, address, (u32)block->addr + offset - (sum -block->size))); - return (u32)block->addr + offset - (sum -block->size); - } - } - - return _MALI_OSK_ERR_FAULT; -} - -static void _ump_osk_msync_with_virt(ump_dd_mem * mem, ump_uk_msync_op op, u32 start, u32 address, u32 size) -{ - int start_index, end_index; - u32 start_p, end_p; - - DBG_MSG(3, ("Cache flush with user virtual address. start : 0x%x, end : 0x%x, address 0x%x, size 0x%x\n", start, start+mem->size_bytes, address, size)); - - start_p = _ump_osk_virt_to_phys_start(mem, start, address, &start_index); - end_p = _ump_osk_virt_to_phys_end(mem, start, address+size, &end_index); - - if (start_index==end_index) { - if (op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE) - outer_flush_range(start_p, end_p); - else - outer_clean_range(start_p, end_p); - } else { - ump_dd_physical_block *block; - int i; - - for (i=start_index; i<=end_index; i++) { - block = &mem->block_array[i]; - - if (i == start_index) { - if (op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE) { - outer_flush_range(start_p, block->addr+block->size); - } else { - outer_clean_range(start_p, block->addr+block->size); - } - } - else if (i == end_index) { - if (op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE) { - outer_flush_range(block->addr, end_p); - } else { - outer_clean_range(block->addr, end_p); - } - break; - } - else { - if (op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE) { - outer_flush_range(block->addr, block->addr+block->size); - } else { - outer_clean_range(block->addr, block->addr+block->size); - } - } - } - } - return; -} - -static void level1_cache_flush_all(void) -{ - DBG_MSG(4, ("UMP[xx] Flushing complete L1 cache\n")); - __cpuc_flush_kern_all(); -} - -void _ump_osk_msync( ump_dd_mem * mem, void * virt, u32 offset, u32 size, ump_uk_msync_op op, ump_session_data * session_data ) -{ - int i; - const void *start_v, *end_v; - - /* Flush L1 using virtual address, the entire range in one go. - * Only flush if user space process has a valid write mapping on given address. */ - if( (mem) && (virt!=NULL) && (access_ok(VERIFY_WRITE, virt, size)) ) - { - start_v = (void *)virt; - end_v = (void *)(start_v + size - 1); - /* There is no dmac_clean_range, so the L1 is always flushed, - * also for UMP_MSYNC_CLEAN. */ - if (size >= SZ_64K) - flush_all_cpu_caches(); - else - dmac_flush_range(start_v, end_v); - - DBG_MSG(3, ("UMP[%02u] Flushing CPU L1 Cache. Cpu address: %x-%x\n", mem->secure_id, start_v,end_v)); - } - else - { - if (session_data) - { - if (op == _UMP_UK_MSYNC_FLUSH_L1 ) - { - DBG_MSG(4, ("UMP Pending L1 cache flushes: %d\n", session_data->has_pending_level1_cache_flush)); - session_data->has_pending_level1_cache_flush = 0; - level1_cache_flush_all(); - return; - } - else - { - if (session_data->cache_operations_ongoing) - { - session_data->has_pending_level1_cache_flush++; - DBG_MSG(4, ("UMP[%02u] Defering the L1 flush. Nr pending:%d\n", mem->secure_id, session_data->has_pending_level1_cache_flush) ); - } - else - { - /* Flushing the L1 cache for each switch_user() if ump_cache_operations_control(START) is not called */ - level1_cache_flush_all(); - } - } - } - else - { - DBG_MSG(4, ("Unkown state %s %d\n", __FUNCTION__, __LINE__)); - level1_cache_flush_all(); - } - } - - if ( NULL == mem ) return; - - if ( mem->size_bytes==size) - { - DBG_MSG(3, ("UMP[%02u] Flushing CPU L2 Cache\n",mem->secure_id)); - } - else - { - DBG_MSG(3, ("UMP[%02u] Flushing CPU L2 Cache. Blocks:%u, TotalSize:%u. FlushSize:%u Offset:0x%x FirstPaddr:0x%08x\n", - mem->secure_id, mem->nr_blocks, mem->size_bytes, size, offset, mem->block_array[0].addr)); - } - - - /* Flush L2 using physical addresses, block for block. */ - if ((virt!=NULL) && (mem->size_bytes >= SZ_1M)) { - if (op == _UMP_UK_MSYNC_CLEAN) - outer_clean_all(); - else if ((op == _UMP_UK_MSYNC_INVALIDATE) || (op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE)) - outer_flush_all(); - return; - } - - for (i=0 ; i < mem->nr_blocks; i++) - { - u32 start_p, end_p; - ump_dd_physical_block *block; - block = &mem->block_array[i]; - - if(offset >= block->size) - { - offset -= block->size; - continue; - } - - if(offset) - { - start_p = (u32)block->addr + offset; - /* We'll zero the offset later, after using it to calculate end_p. */ - } - else - { - start_p = (u32)block->addr; - } - - if(size < block->size - offset) - { - end_p = start_p + size - 1; - size = 0; - } - else - { - if(offset) - { - end_p = start_p + (block->size - offset - 1); - size -= block->size - offset; - offset = 0; - } - else - { - end_p = start_p + block->size - 1; - size -= block->size; - } - } - - switch(op) - { - case _UMP_UK_MSYNC_CLEAN: - outer_clean_range(start_p, end_p); - break; - case _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE: - outer_flush_range(start_p, end_p); - break; - case _UMP_UK_MSYNC_INVALIDATE: - outer_inv_range(start_p, end_p); - break; - default: - break; - } - - if(0 == size) - { - /* Nothing left to flush. */ - break; - } - } - - return; -} - -void _ump_osk_mem_mapregion_get( ump_dd_mem ** mem, unsigned long vaddr) -{ - struct mm_struct *mm = current->mm; - struct vm_area_struct *vma; - ump_vma_usage_tracker * vma_usage_tracker; - ump_memory_allocation *descriptor; - ump_dd_handle handle; - - DBG_MSG(3, ("_ump_osk_mem_mapregion_get: vaddr 0x%08lx\n", vaddr)); - - down_read(&mm->mmap_sem); - vma = find_vma(mm, vaddr); - up_read(&mm->mmap_sem); - if(!vma) - { - DBG_MSG(3, ("Not found VMA\n")); - *mem = NULL; - return; - } - DBG_MSG(4, ("Get vma: 0x%08lx vma->vm_start: 0x%08lx\n", (unsigned long)vma, vma->vm_start)); - - vma_usage_tracker = (struct ump_vma_usage_tracker*)vma->vm_private_data; - if(vma_usage_tracker == NULL) - { - DBG_MSG(3, ("Not found vma_usage_tracker\n")); - *mem = NULL; - return; - } - - descriptor = (struct ump_memory_allocation*)vma_usage_tracker->descriptor; - handle = (ump_dd_handle)descriptor->handle; - - DBG_MSG(3, ("Get handle: 0x%08lx\n", handle)); - *mem = (ump_dd_mem*)handle; -} - diff --git a/drivers/media/video/samsung/ump/linux/ump_osk_misc.c b/drivers/media/video/samsung/ump/linux/ump_osk_misc.c deleted file mode 100644 index 3be6fed..0000000 --- a/drivers/media/video/samsung/ump/linux/ump_osk_misc.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file ump_osk_misc.c - * Implementation of the OS abstraction layer for the UMP kernel device driver - */ - - -#include "ump_osk.h" - -#include -#include "ump_kernel_linux.h" - -/* is called from ump_kernel_constructor in common code */ -_mali_osk_errcode_t _ump_osk_init( void ) -{ - if (0 != ump_kernel_device_initialize()) - { - return _MALI_OSK_ERR_FAULT; - } - - return _MALI_OSK_ERR_OK; -} - -_mali_osk_errcode_t _ump_osk_term( void ) -{ - ump_kernel_device_terminate(); - return _MALI_OSK_ERR_OK; -} diff --git a/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.c b/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.c deleted file mode 100644 index a6691ed..0000000 --- a/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file ump_ukk_wrappers.c - * Defines the wrapper functions which turn Linux IOCTL calls into _ukk_ calls for the reference implementation - */ - - -#include /* user space access */ - -#include "ump_osk.h" -#include "ump_uk_types.h" -#include "ump_ukk.h" -#include "ump_kernel_common.h" - -#if defined(CONFIG_ION_EXYNOS) || defined(CONFIG_DMA_SHARED_BUFFER) -#include -#include "ump_kernel_interface_ref_drv.h" -#include "mali_osk_list.h" -#ifdef CONFIG_ION_EXYNOS -#include -#include "../../../../../gpu/ion/ion_priv.h" -extern struct ion_device *ion_exynos; -extern struct ion_client *ion_client_ump; -#endif -#ifdef CONFIG_DMA_SHARED_BUFFER -#include -#endif -#endif - -/* - * IOCTL operation; Allocate UMP memory - */ -int ump_allocate_wrapper(u32 __user * argument, struct ump_session_data * session_data) -{ - _ump_uk_allocate_s user_interaction; - _mali_osk_errcode_t err; - - /* Sanity check input parameters */ - if (NULL == argument || NULL == session_data) - { - MSG_ERR(("NULL parameter in ump_ioctl_allocate()\n")); - return -ENOTTY; - } - - /* Copy the user space memory to kernel space (so we safely can read it) */ - if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction))) - { - MSG_ERR(("copy_from_user() in ump_ioctl_allocate()\n")); - return -EFAULT; - } - - user_interaction.ctx = (void *) session_data; - - err = _ump_ukk_allocate( &user_interaction ); - if( _MALI_OSK_ERR_OK != err ) - { - DBG_MSG(1, ("_ump_ukk_allocate() failed in ump_ioctl_allocate()\n")); - return map_errcode(err); - } - user_interaction.ctx = NULL; - - if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction))) - { - /* If the copy fails then we should release the memory. We can use the IOCTL release to accomplish this */ - _ump_uk_release_s release_args; - - MSG_ERR(("copy_to_user() failed in ump_ioctl_allocate()\n")); - - release_args.ctx = (void *) session_data; - release_args.secure_id = user_interaction.secure_id; - - err = _ump_ukk_release( &release_args ); - if(_MALI_OSK_ERR_OK != err) - { - MSG_ERR(("_ump_ukk_release() also failed when trying to release newly allocated memory in ump_ioctl_allocate()\n")); - } - - return -EFAULT; - } - - return 0; /* success */ -} -#ifdef CONFIG_ION_EXYNOS -/* - * IOCTL operation; Import fd to UMP memory - */ -int ump_ion_import_wrapper(u32 __user * argument, struct ump_session_data * session_data) -{ - _ump_uk_ion_import_s user_interaction; - ump_dd_handle *ump_handle; - ump_dd_physical_block * blocks; - unsigned long num_blocks; - struct ion_handle *ion_hnd; - struct scatterlist *sg; - struct scatterlist *sg_ion; - unsigned long i = 0; - - ump_session_memory_list_element * session_memory_element = NULL; - if (ion_client_ump==NULL) - ion_client_ump = ion_client_create(ion_exynos, -1, "ump"); - - /* Sanity check input parameters */ - if (NULL == argument || NULL == session_data) - { - MSG_ERR(("NULL parameter in ump_ioctl_allocate()\n")); - return -ENOTTY; - } - - /* Copy the user space memory to kernel space (so we safely can read it) */ - if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction))) - { - MSG_ERR(("copy_from_user() in ump_ioctl_allocate()\n")); - return -EFAULT; - } - - user_interaction.ctx = (void *) session_data; - - /* translate fd to secure ID*/ - ion_hnd = ion_import_fd(ion_client_ump, user_interaction.ion_fd); - sg_ion = ion_map_dma(ion_client_ump,ion_hnd); - - blocks = (ump_dd_physical_block*)_mali_osk_malloc(sizeof(ump_dd_physical_block)*1024); - - if (NULL == blocks) { - MSG_ERR(("Failed to allocate blocks in ump_ioctl_allocate()\n")); - return -ENOMEM; - } - - sg = sg_ion; - do { - blocks[i].addr = sg_phys(sg); - blocks[i].size = sg_dma_len(sg); - i++; - if (i>=1024) { - _mali_osk_free(blocks); - MSG_ERR(("ion_import fail() in ump_ioctl_allocate()\n")); - return -EFAULT; - } - sg = sg_next(sg); - } while(sg); - - num_blocks = i; - - /* Initialize the session_memory_element, and add it to the session object */ - session_memory_element = _mali_osk_calloc( 1, sizeof(ump_session_memory_list_element)); - - if (NULL == session_memory_element) - { - _mali_osk_free(blocks); - DBG_MSG(1, ("Failed to allocate ump_session_memory_list_element in ump_ioctl_allocate()\n")); - return -EFAULT; - } - - ump_handle = ump_dd_handle_create_from_phys_blocks(blocks, num_blocks); - if (UMP_DD_HANDLE_INVALID == ump_handle) - { - _mali_osk_free(session_memory_element); - _mali_osk_free(blocks); - DBG_MSG(1, ("Failed to allocate ump_session_memory_list_element in ump_ioctl_allocate()\n")); - return -EFAULT; - } - - session_memory_element->mem = (ump_dd_mem*)ump_handle; - _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); - _mali_osk_list_add(&(session_memory_element->list), &(session_data->list_head_session_memory_list)); - _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); - ion_unmap_dma(ion_client_ump,ion_hnd); - ion_free(ion_client_ump, ion_hnd); - - _mali_osk_free(blocks); - - user_interaction.secure_id = ump_dd_secure_id_get(ump_handle); - user_interaction.size = ump_dd_size_get(ump_handle); - user_interaction.ctx = NULL; - - if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction))) - { - /* If the copy fails then we should release the memory. We can use the IOCTL release to accomplish this */ - - MSG_ERR(("copy_to_user() failed in ump_ioctl_allocate()\n")); - - return -EFAULT; - } - return 0; /* success */ -} -#endif - -#ifdef CONFIG_DMA_SHARED_BUFFER -int ump_dmabuf_import_wrapper(u32 __user *argument, - struct ump_session_data *session_data) -{ - ump_session_memory_list_element *session = NULL; - struct ump_uk_dmabuf ump_dmabuf; - ump_dd_handle *ump_handle; - ump_dd_physical_block *blocks; - struct dma_buf_attachment *attach; - struct dma_buf *dma_buf; - struct sg_table *sgt; - struct scatterlist *sgl; - unsigned long block_size; - /* FIXME */ - struct device dev; - unsigned int i = 0, npages; - int ret; - - /* Sanity check input parameters */ - if (!argument || !session_data) { - MSG_ERR(("NULL parameter.\n")); - return -EINVAL; - } - - if (copy_from_user(&ump_dmabuf, argument, - sizeof(struct ump_uk_dmabuf))) { - MSG_ERR(("copy_from_user() failed.\n")); - return -EFAULT; - } - - dma_buf = dma_buf_get(ump_dmabuf.fd); - if (IS_ERR(dma_buf)) - return PTR_ERR(dma_buf); - - /* - * check whether dma_buf imported already exists or not. - * - * TODO - * if already imported then dma_buf_put() should be called - * and then just return dma_buf imported. - */ - - attach = dma_buf_attach(dma_buf, &dev); - if (IS_ERR(attach)) { - ret = PTR_ERR(attach); - goto err_dma_buf_put; - } - - sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); - if (IS_ERR(sgt)) { - ret = PTR_ERR(sgt); - goto err_dma_buf_detach; - } - - npages = sgt->nents; - - /* really need? */ - ump_dmabuf.ctx = (void *)session_data; - - block_size = sizeof(ump_dd_physical_block) * npages; - - blocks = (ump_dd_physical_block *)_mali_osk_malloc(block_size); - sgl = sgt->sgl; - - while (i < npages) { - blocks[i].addr = sg_phys(sgl); - blocks[i].size = sg_dma_len(sgl); - sgl = sg_next(sgl); - i++; - } - - /* - * Initialize the session memory list element, and add it - * to the session object - */ - session = _mali_osk_calloc(1, sizeof(*session)); - if (!session) { - DBG_MSG(1, ("Failed to allocate session.\n")); - ret = -EFAULT; - goto err_free_block; - } - - ump_handle = ump_dd_handle_create_from_phys_blocks(blocks, i); - if (UMP_DD_HANDLE_INVALID == ump_handle) { - DBG_MSG(1, ("Failed to create ump handle.\n")); - ret = -EFAULT; - goto err_free_session; - } - - session->mem = (ump_dd_mem *)ump_handle; - - _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); - _mali_osk_list_add(&(session->list), - &(session_data->list_head_session_memory_list)); - _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); - - _mali_osk_free(blocks); - - ump_dmabuf.ump_handle = (uint32_t)ump_handle; - ump_dmabuf.size = ump_dd_size_get(ump_handle); - - if (copy_to_user(argument, &ump_dmabuf, - sizeof(struct ump_uk_dmabuf))) { - MSG_ERR(("copy_to_user() failed.\n")); - ret = -EFAULT; - goto err_release_ump_handle; - } - - return 0; - -err_release_ump_handle: - ump_dd_reference_release(ump_handle); -err_free_session: - _mali_osk_free(session); -err_free_block: - _mali_osk_free(blocks); - dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); -err_dma_buf_detach: - dma_buf_detach(dma_buf, attach); -err_dma_buf_put: - dma_buf_put(dma_buf); - return ret; -} -#endif diff --git a/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.h b/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.h deleted file mode 100644 index 416a584..0000000 --- a/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file ump_ukk_wrappers.h - * Defines the wrapper functions which turn Linux IOCTL calls into _ukk_ calls for the reference implementation - */ - -#ifndef __UMP_UKK_REF_WRAPPERS_H__ -#define __UMP_UKK_REF_WRAPPERS_H__ - -#include -#include "ump_kernel_common.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - - -int ump_allocate_wrapper(u32 __user * argument, struct ump_session_data * session_data); - -#ifdef CONFIG_ION_EXYNOS -int ump_ion_import_wrapper(u32 __user * argument, struct ump_session_data * session_data); -#endif - -#ifdef CONFIG_DMA_SHARED_BUFFER -int ump_dmabuf_import_wrapper(u32 __user *argument, - struct ump_session_data *session_data); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* __UMP_UKK_REF_WRAPPERS_H__ */ diff --git a/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.c b/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.c deleted file mode 100644 index 780f311..0000000 --- a/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file ump_ukk_wrappers.c - * Defines the wrapper functions which turn Linux IOCTL calls into _ukk_ calls - */ - -#include /* user space access */ - -#include "ump_osk.h" -#include "ump_uk_types.h" -#include "ump_ukk.h" -#include "ump_kernel_common.h" - -/* - * IOCTL operation; Negotiate version of IOCTL API - */ -int ump_get_api_version_wrapper(u32 __user * argument, struct ump_session_data * session_data) -{ - _ump_uk_api_version_s version_info; - _mali_osk_errcode_t err; - - /* Sanity check input parameters */ - if (NULL == argument || NULL == session_data) - { - MSG_ERR(("NULL parameter in ump_ioctl_get_api_version()\n")); - return -ENOTTY; - } - - /* Copy the user space memory to kernel space (so we safely can read it) */ - if (0 != copy_from_user(&version_info, argument, sizeof(version_info))) - { - MSG_ERR(("copy_from_user() in ump_ioctl_get_api_version()\n")); - return -EFAULT; - } - - version_info.ctx = (void*) session_data; - err = _ump_uku_get_api_version( &version_info ); - if( _MALI_OSK_ERR_OK != err ) - { - MSG_ERR(("_ump_uku_get_api_version() failed in ump_ioctl_get_api_version()\n")); - return map_errcode(err); - } - - version_info.ctx = NULL; - - /* Copy ouput data back to user space */ - if (0 != copy_to_user(argument, &version_info, sizeof(version_info))) - { - MSG_ERR(("copy_to_user() failed in ump_ioctl_get_api_version()\n")); - return -EFAULT; - } - - return 0; /* success */ -} - - -/* - * IOCTL operation; Release reference to specified UMP memory. - */ -int ump_release_wrapper(u32 __user * argument, struct ump_session_data * session_data) -{ - _ump_uk_release_s release_args; - _mali_osk_errcode_t err; - - /* Sanity check input parameters */ - if (NULL == session_data) - { - MSG_ERR(("NULL parameter in ump_ioctl_release()\n")); - return -ENOTTY; - } - - /* Copy the user space memory to kernel space (so we safely can read it) */ - if (0 != copy_from_user(&release_args, argument, sizeof(release_args))) - { - MSG_ERR(("copy_from_user() in ump_ioctl_get_api_version()\n")); - return -EFAULT; - } - - release_args.ctx = (void*) session_data; - err = _ump_ukk_release( &release_args ); - if( _MALI_OSK_ERR_OK != err ) - { - MSG_ERR(("_ump_ukk_release() failed in ump_ioctl_release()\n")); - return map_errcode(err); - } - - - return 0; /* success */ -} - -/* - * IOCTL operation; Return size for specified UMP memory. - */ -int ump_size_get_wrapper(u32 __user * argument, struct ump_session_data * session_data) -{ - _ump_uk_size_get_s user_interaction; - _mali_osk_errcode_t err; - - /* Sanity check input parameters */ - if (NULL == argument || NULL == session_data) - { - MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n")); - return -ENOTTY; - } - - if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction))) - { - MSG_ERR(("copy_from_user() in ump_ioctl_size_get()\n")); - return -EFAULT; - } - - user_interaction.ctx = (void *) session_data; - err = _ump_ukk_size_get( &user_interaction ); - if( _MALI_OSK_ERR_OK != err ) - { - MSG_ERR(("_ump_ukk_size_get() failed in ump_ioctl_size_get()\n")); - return map_errcode(err); - } - - user_interaction.ctx = NULL; - - if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction))) - { - MSG_ERR(("copy_to_user() failed in ump_ioctl_size_get()\n")); - return -EFAULT; - } - - return 0; /* success */ -} - -/* - * IOCTL operation; Do cache maintenance on specified UMP memory. - */ -int ump_msync_wrapper(u32 __user * argument, struct ump_session_data * session_data) -{ - _ump_uk_msync_s user_interaction; - - /* Sanity check input parameters */ - if (NULL == argument || NULL == session_data) - { - MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n")); - return -ENOTTY; - } - - if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction))) - { - MSG_ERR(("copy_from_user() in ump_ioctl_msync()\n")); - return -EFAULT; - } - - user_interaction.ctx = (void *) session_data; - - _ump_ukk_msync( &user_interaction ); - - user_interaction.ctx = NULL; - - if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction))) - { - MSG_ERR(("copy_to_user() failed in ump_ioctl_msync()\n")); - return -EFAULT; - } - - return 0; /* success */ -} -int ump_cache_operations_control_wrapper(u32 __user * argument, struct ump_session_data * session_data) -{ - _ump_uk_cache_operations_control_s user_interaction; - - /* Sanity check input parameters */ - if (NULL == argument || NULL == session_data) - { - MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n")); - return -ENOTTY; - } - - if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction))) - { - MSG_ERR(("copy_from_user() in ump_ioctl_cache_operations_control()\n")); - return -EFAULT; - } - - user_interaction.ctx = (void *) session_data; - - _ump_ukk_cache_operations_control((_ump_uk_cache_operations_control_s*) &user_interaction ); - - user_interaction.ctx = NULL; - -#if 0 /* No data to copy back */ - if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction))) - { - MSG_ERR(("copy_to_user() failed in ump_ioctl_cache_operations_control()\n")); - return -EFAULT; - } -#endif - return 0; /* success */ -} - -int ump_switch_hw_usage_wrapper(u32 __user * argument, struct ump_session_data * session_data) -{ - _ump_uk_switch_hw_usage_s user_interaction; - - /* Sanity check input parameters */ - if (NULL == argument || NULL == session_data) - { - MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n")); - return -ENOTTY; - } - - if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction))) - { - MSG_ERR(("copy_from_user() in ump_ioctl_switch_hw_usage()\n")); - return -EFAULT; - } - - user_interaction.ctx = (void *) session_data; - - _ump_ukk_switch_hw_usage( &user_interaction ); - - user_interaction.ctx = NULL; - -#if 0 /* No data to copy back */ - if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction))) - { - MSG_ERR(("copy_to_user() failed in ump_ioctl_switch_hw_usage()\n")); - return -EFAULT; - } -#endif - return 0; /* success */ -} - -int ump_lock_wrapper(u32 __user * argument, struct ump_session_data * session_data) -{ - _ump_uk_lock_s user_interaction; - - /* Sanity check input parameters */ - if (NULL == argument || NULL == session_data) - { - MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n")); - return -ENOTTY; - } - - if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction))) - { - MSG_ERR(("copy_from_user() in ump_ioctl_switch_hw_usage()\n")); - return -EFAULT; - } - - user_interaction.ctx = (void *) session_data; - - _ump_ukk_lock( &user_interaction ); - - user_interaction.ctx = NULL; - -#if 0 /* No data to copy back */ - if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction))) - { - MSG_ERR(("copy_to_user() failed in ump_ioctl_switch_hw_usage()\n")); - return -EFAULT; - } -#endif - - return 0; /* success */ -} - -int ump_unlock_wrapper(u32 __user * argument, struct ump_session_data * session_data) -{ - _ump_uk_unlock_s user_interaction; - - /* Sanity check input parameters */ - if (NULL == argument || NULL == session_data) - { - MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n")); - return -ENOTTY; - } - - if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction))) - { - MSG_ERR(("copy_from_user() in ump_ioctl_switch_hw_usage()\n")); - return -EFAULT; - } - - user_interaction.ctx = (void *) session_data; - - _ump_ukk_unlock( &user_interaction ); - - user_interaction.ctx = NULL; - -#if 0 /* No data to copy back */ - if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction))) - { - MSG_ERR(("copy_to_user() failed in ump_ioctl_switch_hw_usage()\n")); - return -EFAULT; - } -#endif - - return 0; /* success */ -} diff --git a/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.h b/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.h deleted file mode 100644 index e87a903..0000000 --- a/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file ump_ukk_wrappers.h - * Defines the wrapper functions which turn Linux IOCTL calls into _ukk_ calls - */ - -#ifndef __UMP_UKK_WRAPPERS_H__ -#define __UMP_UKK_WRAPPERS_H__ - -#include -#include "ump_kernel_common.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - - - -int ump_get_api_version_wrapper(u32 __user * argument, struct ump_session_data * session_data); -int ump_release_wrapper(u32 __user * argument, struct ump_session_data * session_data); -int ump_size_get_wrapper(u32 __user * argument, struct ump_session_data * session_data); -int ump_msync_wrapper(u32 __user * argument, struct ump_session_data * session_data); -int ump_cache_operations_control_wrapper(u32 __user * argument, struct ump_session_data * session_data); -int ump_switch_hw_usage_wrapper(u32 __user * argument, struct ump_session_data * session_data); -int ump_lock_wrapper(u32 __user * argument, struct ump_session_data * session_data); -int ump_unlock_wrapper(u32 __user * argument, struct ump_session_data * session_data); - - - - -#ifdef __cplusplus -} -#endif - - - -#endif /* __UMP_UKK_WRAPPERS_H__ */ -- cgit v1.1 From cb45b00f2febffb7711f898f2e98e7f53a0c84ba Mon Sep 17 00:00:00 2001 From: sbrissen Date: Fri, 13 Dec 2013 14:35:25 -0500 Subject: smdk4412: revert jpeg_dev from update 11 fixes front cam for some that broke from update 11 merge http://forum.xda-developers.com/showpost.php?p=48429637&postcount=576 Change-Id: I4a654f10e9ccd50a744a710ecd01d2d26f67401d --- drivers/media/video/samsung/jpeg/jpeg_dev.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/samsung/jpeg/jpeg_dev.c b/drivers/media/video/samsung/jpeg/jpeg_dev.c index 6ebcfb6..4038fd2 100644 --- a/drivers/media/video/samsung/jpeg/jpeg_dev.c +++ b/drivers/media/video/samsung/jpeg/jpeg_dev.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include @@ -248,12 +247,6 @@ int jpeg_mmap(struct file *filp, struct vm_area_struct *vma) size = vma->vm_end - vma->vm_start; - if (!cma_is_registered_region(jpeg_ctrl->mem.base, size)) { - pr_err("[%s] handling non-cma region (%#x@%#x)is prohibited\n", - __func__, (unsigned int)size, jpeg_ctrl->mem.base); - return -EINVAL; - } - vma->vm_flags |= VM_RESERVED | VM_IO; vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); -- cgit v1.1 From fab9e4c915e35338d589b04b3b9c2a9ce283e960 Mon Sep 17 00:00:00 2001 From: sbrissen Date: Mon, 16 Dec 2013 13:18:35 -0500 Subject: smdk4412: remove some logging I added Change-Id: I264ee04c7c6726e68cdd186f22ab45dc8bf5be0f --- drivers/media/video/samsung/fimc/fimc_capture.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/samsung/fimc/fimc_capture.c b/drivers/media/video/samsung/fimc/fimc_capture.c index 75928ed..e438205 100644 --- a/drivers/media/video/samsung/fimc/fimc_capture.c +++ b/drivers/media/video/samsung/fimc/fimc_capture.c @@ -1927,7 +1927,6 @@ int fimc_reqbufs_capture_mmap(void *fh, struct v4l2_requestbuffers *b) case V4L2_PIX_FMT_YVYU: /* fall through */ case V4L2_PIX_FMT_NV16: /* fall through */ case V4L2_PIX_FMT_NV61: /* fall through */ - fimc_err("%s : V4L2_PIX_FMT_YUYV - SBRISSEN\n", __func__); fimc_err("%s : w %d h %d \n",__func__, cap->fmt.width, cap->fmt.height); fimc_info1("%s : 1plane\n", __func__); @@ -1936,7 +1935,6 @@ int fimc_reqbufs_capture_mmap(void *fh, struct v4l2_requestbuffers *b) break; case V4L2_PIX_FMT_NV21: - fimc_err("%s : V4L2_PIX_FMT_NV12 - SBRISSEN\n", __func__); fimc_info1("%s : 2plane for NV21 w %d h %d\n", __func__, cap->fmt.width, cap->fmt.height); ret = fimc_alloc_buffers(ctrl, 2, @@ -1966,21 +1964,18 @@ int fimc_reqbufs_capture_mmap(void *fh, struct v4l2_requestbuffers *b) break; case V4L2_PIX_FMT_JPEG: - fimc_err("%s : V4L2_PIX_FMT_JPEG - SBRISSEN\n", __func__); fimc_info1("%s : JPEG 1plane\n", __func__); size = fimc_camera_get_jpeg_memsize(ctrl); fimc_info2("%s : JPEG 1plane size = %x\n", __func__, size); ret = fimc_alloc_buffers(ctrl, 1, size, 0, 8, cap->pktdata_enable, cap->pktdata_size); break; case V4L2_PIX_FMT_INTERLEAVED: - fimc_err("%s : V4L2_PIX_FMT_INTERLEAVED - SBRISSEN\n", __func__); fimc_info1("%s : Interleaved Format\n", __func__); size = fimc_camera_get_jpeg_memsize(ctrl); /*0xA00000*/ fimc_info2("%s : Interleaved size = %x\n", __func__, size); ret = fimc_alloc_buffers(ctrl, 1, size, 0, 8, cap->pktdata_enable, cap->pktdata_size); break; default: - fimc_err("%s : default - SBRISSEN\n", __func__); break; } @@ -1990,7 +1985,6 @@ int fimc_reqbufs_capture_mmap(void *fh, struct v4l2_requestbuffers *b) return -ENOMEM; } - fimc_err("%s : SBRISSEN - done\n", __func__); mutex_unlock(&ctrl->v4l2_lock); return 0; -- cgit v1.1 From b1c5069196635586f0cc98cf3eca277c08b282f6 Mon Sep 17 00:00:00 2001 From: sbrissen Date: Fri, 7 Feb 2014 22:32:21 -0500 Subject: smdk4412: update fimc_capture and sr130pc20 cam driver -updates are from i605 4.3 kernel source -updates + small hack fixes front cam on kona Change-Id: If8348be6dbef50bb322a60d554d177e046eec429 --- drivers/media/video/samsung/fimc/fimc.h | 1 + drivers/media/video/samsung/fimc/fimc_capture.c | 55 +- drivers/media/video/sr130pc20.c | 45 +- drivers/media/video/sr130pc20.h | 9 + drivers/media/video/sr130pc20_regs_kona.h | 4229 +++++++++++++++++++++++ 5 files changed, 4305 insertions(+), 34 deletions(-) create mode 100644 drivers/media/video/sr130pc20_regs_kona.h (limited to 'drivers/media/video') diff --git a/drivers/media/video/samsung/fimc/fimc.h b/drivers/media/video/samsung/fimc/fimc.h index b648965..228a1c4 100644 --- a/drivers/media/video/samsung/fimc/fimc.h +++ b/drivers/media/video/samsung/fimc/fimc.h @@ -469,6 +469,7 @@ struct fimc_control { struct mutex lock; /* controller lock */ struct mutex v4l2_lock; spinlock_t outq_lock; + spinlock_t inq_lock; wait_queue_head_t wq; struct device *dev; #if defined(CONFIG_BUSFREQ_OPP) || defined(CONFIG_BUSFREQ_LOCK_WRAPPER) diff --git a/drivers/media/video/samsung/fimc/fimc_capture.c b/drivers/media/video/samsung/fimc/fimc_capture.c index e438205..f76345c 100644 --- a/drivers/media/video/samsung/fimc/fimc_capture.c +++ b/drivers/media/video/samsung/fimc/fimc_capture.c @@ -32,6 +32,10 @@ #include "fimc.h" +#ifdef CONFIG_MACH_KONA +extern fimc_is; +#endif + static struct pm_qos_request_list bus_qos_pm_qos_req; static const struct v4l2_fmtdesc capture_fmts[] = { @@ -816,6 +820,7 @@ static int fimc_configure_subdev(struct fimc_control *ctrl) if (!sd) { fimc_err("%s: v4l2 subdev board registering failed\n", __func__); + return -ENODEV; } /* Assign subdev to proper camera device pointer */ ctrl->cam->sd = sd; @@ -1435,7 +1440,7 @@ int fimc_s_fmt_vid_private(struct file *file, void *fh, struct v4l2_format *f) mbus_fmt = &ctrl->cap->mbus_fmt; mbus_fmt->width = pix->width; mbus_fmt->height = pix->height; -#if defined(CONFIG_MACH_P4NOTE) || defined(CONFIG_MACH_KONA) +#if defined(CONFIG_MACH_P4NOTE) /* Unfortuntely, we have to use pix->field (not pix->priv) since * pix.field is already used in the below else condtion statement * (in case that sub-devices are not registered) @@ -1445,6 +1450,11 @@ int fimc_s_fmt_vid_private(struct file *file, void *fh, struct v4l2_format *f) #if defined(CONFIG_MACH_GC1) mbus_fmt->field = pix->priv; #endif + +#if defined(CONFIG_MACH_KONA) + if(!fimc_is) + mbus_fmt->field = pix->field; +#endif printk(KERN_INFO "%s mbus_fmt->width = %d, height = %d,\n", __func__,mbus_fmt->width ,mbus_fmt->height); @@ -2146,6 +2156,7 @@ int fimc_querybuf_capture(void *fh, struct v4l2_buffer *b) int fimc_g_ctrl_capture(void *fh, struct v4l2_control *c) { struct fimc_control *ctrl = fh; + struct v4l2_frmsizeenum cam_frmsize; int ret = 0; fimc_dbg("%s\n", __func__); @@ -2167,6 +2178,24 @@ int fimc_g_ctrl_capture(void *fh, struct v4l2_control *c) c->value = ctrl->cap->cacheable; break; + case V4L2_CID_CAMERA_SENSOR_OUTPUT_SIZE: + cam_frmsize.index = -1; + cam_frmsize.discrete.width = 0; + cam_frmsize.discrete.height = 0; + + ret = v4l2_subdev_call(ctrl->cam->sd, video, enum_framesizes, + &cam_frmsize); + if (ret < 0) { + dev_err(ctrl->dev, "%s: enum_framesizes failed\n", + __func__); + if (ret != -ENOIOCTLCMD) + return ret; + } else { + c->value = (cam_frmsize.discrete.width << 16)|(cam_frmsize.discrete.height&0xFFFF); + dev_err(ctrl->dev,"sensor_output (%d, %d)\n", cam_frmsize.discrete.width, cam_frmsize.discrete.height); + } + break; + default: /* get ctrl supported by subdev */ /* WriteBack doesn't have subdev_call */ @@ -2933,9 +2962,20 @@ int fimc_streamon_capture(void *fh) fimc_start_capture(ctrl); ctrl->status = FIMC_STREAMON; - if (ctrl->is.sd && fimc_cam_use) + if (ctrl->is.sd && fimc_cam_use) { ret = v4l2_subdev_call(ctrl->is.sd, video, s_stream, 1); - printk(KERN_INFO "%s-- fimc%d\n", __func__, ctrl->id); + if (ret < 0) { + dev_err(ctrl->dev, "%s: s_stream failed\n", + __func__); + if (cam->type == CAM_TYPE_MIPI) { + if (cam->id == CAMERA_CSI_C) + s3c_csis_stop(CSI_CH_0); + else + s3c_csis_stop(CSI_CH_1); + } + return ret; + } + } /* if available buffer did not remained */ return 0; @@ -3138,17 +3178,16 @@ int fimc_qbuf_capture(void *fh, struct v4l2_buffer *b) int available_bufnum; size_t length = 0; int i; + unsigned long spin_flags; if (!cap || !ctrl->cam) { fimc_err("%s: No capture device.\n", __func__); return -ENODEV; } - mutex_lock(&ctrl->v4l2_lock); if (pdata->hw_ver >= 0x51) { if (cap->bufs[idx].state != VIDEOBUF_IDLE) { fimc_err("%s: invalid state idx : %d\n", __func__, idx); - mutex_unlock(&ctrl->v4l2_lock); return -EINVAL; } else { if (b->memory == V4L2_MEMORY_USERPTR) { @@ -3170,7 +3209,6 @@ int fimc_qbuf_capture(void *fh, struct v4l2_buffer *b) if (ret < 0) { fimc_err("%s: _qbuf_dmabuf error.\n", __func__); - mutex_unlock(&ctrl->v4l2_lock); return -ENODEV; } for (i = 0; i < vb->num_planes; i++) { @@ -3184,7 +3222,6 @@ int fimc_qbuf_capture(void *fh, struct v4l2_buffer *b) } else { fimc_err("%s: Wrong sg value.\n", __func__); - mutex_unlock(&ctrl->v4l2_lock); return -ENODEV; } } @@ -3206,6 +3243,7 @@ int fimc_qbuf_capture(void *fh, struct v4l2_buffer *b) #endif } + spin_lock_irqsave(&ctrl->inq_lock, spin_flags); fimc_hwset_output_buf_sequence(ctrl, idx, FIMC_FRAMECNT_SEQ_ENABLE); cap->bufs[idx].state = VIDEOBUF_QUEUED; if (ctrl->status == FIMC_BUFFER_STOP) { @@ -3220,13 +3258,12 @@ int fimc_qbuf_capture(void *fh, struct v4l2_buffer *b) ctrl->restart = true; } } + spin_unlock_irqrestore(&ctrl->inq_lock, spin_flags); } } else { fimc_add_inqueue(ctrl, b->index); } - mutex_unlock(&ctrl->v4l2_lock); - if (!cap->cacheable) return 0; diff --git a/drivers/media/video/sr130pc20.c b/drivers/media/video/sr130pc20.c index ab2b8d5..8dbc83f 100644 --- a/drivers/media/video/sr130pc20.c +++ b/drivers/media/video/sr130pc20.c @@ -32,6 +32,9 @@ #define sr130pc20_writew(sd, addr, data) i2c_write_nop() #define sr130pc20_writel(sd, addr, data) i2c_write_nop() +int fimc_is; +EXPORT(fimc_is); + static int dbg_level; static const struct sr130pc20_fps sr130pc20_framerates[] = { @@ -1284,10 +1287,11 @@ static int sr130pc20_s_mbus_fmt(struct v4l2_subdev *sd, __func__, fmt->code, fmt->colorspace, fmt->width, fmt->height); v4l2_fill_pix_format(&state->req_fmt, fmt); - if (fmt->field < IS_MODE_CAPTURE_STILL) - state->format_mode = V4L2_PIX_FMT_MODE_PREVIEW; - else + if ((IS_MODE_CAPTURE_STILL == fmt->field) + && (SENSOR_CAMERA == state->sensor_mode)) state->format_mode = V4L2_PIX_FMT_MODE_CAPTURE; + else + state->format_mode = V4L2_PIX_FMT_MODE_PREVIEW; if (state->format_mode != V4L2_PIX_FMT_MODE_CAPTURE) { previous_index = state->preview.frmsize ? @@ -1407,10 +1411,14 @@ static int sr130pc20_s_parm(struct v4l2_subdev *sd, cam_dbg("s_parm state->fps=%d, state->req_fps=%d\n", state->fps, state->req_fps); - if ((state->req_fps < 0) || (state->req_fps > 30)) { - cam_err("%s: error, invalid frame rate %d. we'll set to 30\n", + if (state->req_fps < 0) { + cam_err("%s: error, invalid frame rate %d. we'll set to 0\n", __func__, state->req_fps); state->req_fps = 0; + } else if (state->req_fps > 25) { + cam_err("%s: error, invalid frame rate %d. we'll set to 25\n", + __func__, state->req_fps); + state->req_fps = 25; } return sr130pc20_set_frame_rate(sd, state->req_fps); @@ -1626,7 +1634,10 @@ static int sr130pc20_s_stream(struct v4l2_subdev *sd, int enable) cam_info("stream mode = %d\n", enable); - BUG_ON(!state->initialized); + if (unlikely(!state->initialized)) { + WARN(1, "s_stream, not initialized\n"); + return -EPERM; + } switch (enable) { case STREAM_MODE_CAM_OFF: @@ -1635,23 +1646,12 @@ static int sr130pc20_s_stream(struct v4l2_subdev *sd, int enable) break; case STREAM_MODE_CAM_ON: - switch (state->sensor_mode) { - case SENSOR_CAMERA: if (state->format_mode == V4L2_PIX_FMT_MODE_CAPTURE) err = sr130pc20_start_capture(sd); else err = sr130pc20_start_preview(sd); break; - case SENSOR_MOVIE: - err = sr130pc20_start_preview(sd); - break; - - default: - break; - } - break; - case STREAM_MODE_MOVIE_OFF: cam_info("movie off"); state->recording = 0; @@ -1674,14 +1674,6 @@ static int sr130pc20_s_stream(struct v4l2_subdev *sd, int enable) static inline int sr130pc20_check_i2c(struct v4l2_subdev *sd, u16 data) { - int err; - u32 val = 0; - - err = sr130pc20_readw(sd, 0x0000, &val); - if (unlikely(err)) - return err; - - cam_dbg("version: 0x%04X is 0x6017?\n", val); return 0; } @@ -1727,6 +1719,7 @@ static int sr130pc20_init(struct v4l2_subdev *sd, u32 val) CHECK_ERR_MSG(err, "failed to initialize camera device\n"); sr130pc20_init_parameter(sd); state->initialized = 1; + fimc_is = 1; return 0; } @@ -1775,6 +1768,7 @@ static int sr130pc20_s_config(struct v4l2_subdev *sd, state->format_mode = V4L2_PIX_FMT_MODE_PREVIEW; state->fps = 0; state->req_fps = -1; + state->write_fps = 0; /* Initialize the independant HW module like flash here */ state->flash.mode = FLASH_MODE_OFF; @@ -1880,6 +1874,7 @@ static int sr130pc20_remove(struct i2c_client *client) v4l2_device_unregister_subdev(sd); mutex_destroy(&state->ctrl_lock); kfree(state); + fimc_is = 0; printk(KERN_DEBUG "%s %s: driver removed!!\n", dev_driver_string(&client->dev), dev_name(&client->dev)); diff --git a/drivers/media/video/sr130pc20.h b/drivers/media/video/sr130pc20.h index a831007..25a5949 100755 --- a/drivers/media/video/sr130pc20.h +++ b/drivers/media/video/sr130pc20.h @@ -547,6 +547,7 @@ struct sr130pc20_state { s32 vt_mode; s32 req_fps; s32 fps; + s32 write_fps; s32 freq; /* MCLK in Hz */ u32 one_frame_delay_ms; u32 light_level; /* light level */ @@ -638,9 +639,17 @@ extern int sr130pc20_create_file(struct class *cls); #include #include +#ifdef CONFIG_MACH_KONA +#define TUNING_FILE_PATH "/mnt/sdcard/sr130pc20_regs_kona.h" +#else #define TUNING_FILE_PATH "/mnt/sdcard/sr130pc20_regs.h" +#endif /* CONFIG_MACH_KONA */ #endif /* CONFIG_LOAD_FILE*/ +#ifdef CONFIG_MACH_KONA +#include "sr130pc20_regs_kona.h" +#else #include "sr130pc20_regs.h" +#endif #endif /* __SR130PC20_H__ */ diff --git a/drivers/media/video/sr130pc20_regs_kona.h b/drivers/media/video/sr130pc20_regs_kona.h new file mode 100644 index 0000000..ebc578b --- /dev/null +++ b/drivers/media/video/sr130pc20_regs_kona.h @@ -0,0 +1,4229 @@ +/* sr130pc20_regs.h + * + * Driver for s5k5ccgx (5MP Camera) from siliconfile + * + * Copyright (C) 2010, SAMSUNG ELECTRONICS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Change Date: 2012.06.28 + */ + +#ifndef __SR130PC20_REGS_H__ +#define __SR130PC20_REGS_H__ + +/* PV 1st */ + +static const sr130pc20_regset_t SR130PC20_Init_Reg[] = { + +/*0 Page*/ +0x0300, +0x0101, /*sleep*/ +0x0103, /*s/w reset*/ +0x0101, /*sleep*/ + +0x0800,/*Don't touch*/ +0x0937,/*Don't touch*/ +0x0a33,/*Don't touch*/ + +/*PLL Setting*/ +0xd005, +0xd130, +0xd201, +0xd320, +0xd085, +0xd085, +0xd085, +0xd095, + +0x1011, +0x1190, /*xy flip*/ +0x1200, +0x1488, + +0x0300, +0x2000, +0x2104, +0x2200, +0x2304, +0x2403, +0x25C0, +0x2605, +0x2700, + +0x4001, /*Hblank_280*/ +0x4118, +0x4200, /*Vblank 100*/ +0x4364, + +/*--------------- BLC*/ +0x8008, /*Don't touch */ +0x8197, /*Don't touch */ +0x8290, /*Don't touch */ +0x8330, /*Don't touch */ +0x84cc, /*Don't touch*/ +0x8500, /*Don't touch*/ +0x86d4, /*Don' t touch*/ +0x870f, /*Don't touch*/ +0x8834, /*Don't touch*/ + +0x900c, /*BLC_TIME_TH_ON*/ +0x910c, /*BLC_TIME_TH_OFF */ +0x92f0, /*BLC_AG_TH_ON*/ +0x93e8, /*BLC_AG_TH_OFF*/ + +0x9495, /*091202*/ +0x9590, /*091202 */ +0x9838, /*Don't touch*/ + +/*Dark BLC*/ +0xa001, /* 20100309*/ +0xa201, /* 20100309*/ +0xa401, /* 20100309*/ +0xa601, /* 20100309*/ + +/*Normal BLC*/ +0xa800, +0xaa00, +0xac00, +0xae00, + +/*Out BLC*/ +0x9900, +0x9a00, +0x9b00, +0x9c00, + +/*2 Page*/ +0x0302, +0x1200, /*Don't touch*/ +0x1400, /*Don't touch*/ +0x1500, /*Don't touch*/ +0x184C, /*Don't touch*/ +0x1900, /*Don't touch*/ +0x1A39, /*Don't touch*/ +0x1B00,/*Don't touch*/ +0x1C1a, /*Don't touch*/ +0x1D14, /*Don't touch*/ +0x1E30,/*Don't touch*/ +0x1F10,/*Don't touch*/ + +0x2077, +0x21de, +0x22a7, +0x2330, +0x2477, +0x2510, +0x2610, +0x273c, +0x2b80, +0x2c02, +0x2da0, +0x2e00, +0x2fa7, + +0x3000, +0x3199, +0x3200, +0x3300, +0x3422, +0x3601, +0x3701, +0x3888, +0x3988, +0x3d03, +0x3e0d, +0x3f02, + +0x49d1, +0x4a14, + +0x5021, +0x5201, +0x5381, +0x5410, +0x551c, +0x5611, +0x5818, +0x5916, +0x5da2, +0x5e5a, + +0x6093, /* 20120517 modify*/ +0x61a4, /* 20120517 modify*/ +0x6294, /* 20120517 modify*/ +0x63a3, /* 20120517 modify*/ +0x6494, /* 20120517 modify*/ +0x65a3, /* 20120517 modify*/ +0x670c, +0x680c, +0x690c, +0x6ab4, +0x6bc4, +0x6cb5, +0x6dc2, +0x6eb5, +0x6fc0, + +0x70b6, +0x71b8, +0x7295, /* 20120517 modify*/ +0x73a2, /* 20120517 modify*/ +0x7495, /* 20120517 modify*/ +0x75a2, /* 20120517 modify*/ +0x7695, /* 20120517 modify*/ +0x77a2, /* 20120517 modify*/ +0x7C92, /* 20120517 modify*/ +0x7Dff, /* 20120517 modify*/ + +0x8001, /* 20120517 modify*/ +0x818a, /* 20120517 modify*/ +0x821e, /* 20120517 modify*/ +0x8336, /* 20120517 modify*/ +0x8489, /* 20120517 modify*/ +0x858b, /* 20120517 modify*/ +0x8689, /* 20120517 modify*/ +0x878b, /* 20120517 modify*/ +0x88ab, +0x89bc, +0x8aac, +0x8bba, +0x8cad, +0x8db8, +0x8eae, +0x8fb2, + +0x90b3, +0x91b7, +0x9252, /* 20120517 modify*/ +0x936a, /* 20120517 modify*/ +0x9489, /* 20120517 modify*/ +0x958b, /* 20120517 modify*/ +0x9689, /* 20120517 modify*/ +0x978b, /* 20120517 modify*/ + +0xA002, +0xA186, /* 20120517 modify*/ +0xA202, +0xA386, /* 20120517 modify*/ +0xA486, /* 20120517 modify*/ +0xA502, +0xA686, /* 20120517 modify*/ +0xA702, +0xA892, /* 20120517 modify*/ +0xA994, /* 20120517 modify*/ +0xAA92, /* 20120517 modify*/ +0xAB94, /* 20120517 modify*/ +0xAC1c, +0xAD22, +0xAE1c, +0xAF22, + +0xB0a4, /* 20120517 modify*/ +0xB1ae, /* 20120517 modify*/ +0xB2a4, /* 20120517 modify*/ +0xB3ae, /* 20120517 modify*/ +0xB4a6, /* 20120517 modify*/ +0xB5ac, /* 20120517 modify*/ +0xB6a6, /* 20120517 modify*/ +0xB7ac, /* 20120517 modify*/ +0xB8a6, /* 20120517 modify*/ +0xB9ab, /* 20120517 modify*/ +0xBAa6, /* 20120517 modify*/ +0xBBab, /* 20120517 modify*/ +0xBCa6, /* 20120517 modify*/ +0xBDab, /* 20120517 modify*/ +0xBEa6, /* 20120517 modify*/ +0xBFab, /* 20120517 modify*/ + +0xc437, +0xc552, +0xc66b, +0xc786, +0xc838, /* 20120517 modify*/ +0xc950, /* 20120517 modify*/ +0xca38, /* 20120517 modify*/ +0xcb50, /* 20120517 modify*/ +0xcc6c, /* 20120517 modify*/ +0xcd84, /* 20120517 modify*/ +0xce6c, /* 20120517 modify*/ +0xcf84, /* 20120517 modify*/ + +/*0xd4a6,*/ +/*0xd5ac,*/ +/*0xd6a6,*/ +/*0xd7ac,*/ +/*add 20120517*/ +0xdc00, /* Added*/ +0xddaf, /* Added*/ +0xde00, /* Added*/ +0xdf90, /* Added*/ + +0xd010, +0xd114, +0xd220, +0xd300, +/*DCDC */ +0xd40c, /*DCDC_TIME_TH_ON*/ +0xd50c, /*DCDC_TIME_TH_OFF */ +0xd6f0, /*DCDC_AG_TH_ON*/ +0xd7e8, /*DCDC_AG_TH_OFF*/ + +0xea8a, + +0xF001, /* clock inversion*/ +0xF101, +0xF201, +0xF301, +0xF401, +0xF500, + +/*----------------------------------------------*/ +0x0310, /*page 10*/ +0x1001, /*Ycbcr422_bit Order: YUYV*/ +0x1103, +0x1230, /*y offset[4], dif_offset[5]*/ +0x1302, /*contrast effet enable : 0x02*/ +0x3400, /*hidden 10->00 100209*/ +0x3701, /*yc2d power save */ +0x3f04, /*100825*/ +0x4080, /*Y offset */ +0x4880, +0x5300, /*dif_offset option */ +0x5530, /*dif_offset option diff_offset max */ + +0x604f, /*out color sat en[7] | auto color decrement en[1] / + | manual color sat en[0]*/ + +0x6183, /*blue saturation_C0*/ +0x6280, /*red saturation_B0*/ + +0x63ff, /*auto decresment on AG th*/ +0x64c0, /*auto decresment on DG th*/ +0x66e4, /*Outdoor saturation step 137fps apply out th */ +0x6703, /*Outdoor saturation B/R*/ +0x7601, /* ADD 20121031 */ +0x7904, /* ADD 20121031 */ + +/* Hi 163 */ +/* PAGE 10 START*/ +0x0310, +0x8000, /* dsshin --> color enhance*/ +0xf500, /* dsshin --> h blank option*/ + +0x0311, /*page 11 D_LPF */ +0x103f, /*B[6]:Blue En Dlpf on[4:0] Sky over off : 0x7f->3f*/ +0x1120, /* Uniform Full GbGr/OV-Nr*/ + +0x1280, /*Blue MaxOpt blue sky max filter optoin rate : 0 0xc0->80*/ +0x13b8, /*dark2[7] | ratio[6:4] | dark3[3] | dark3 maxfilter ratio[2:0] */ + +0x30ba, /*Outdoor2 H th*/ +0x3110, /*Outdoor2 L th*/ +0x3250, /*Outdoor2 gain ratio*/ +0x331d, /*Outdoor2 H lum*/ +0x3420, /*Outdoor2 M lum*/ +0x351f, /*Outdoor2 L lum*/ + +0x36b0, /*Outdoor1 H th*/ +0x3718, /*Outdoor1 L th*/ +0x3850, /*Outdoor1 gain ratio 0x80->40*/ +0x391d, /*Outdoor1 H lum 0x28->1e*/ +0x3a20, /*Outdoor1 M lum 0x10->15*/ +0x3b1f, /*Outdoor1 L lum 0x08->20*/ + +0x3c3f, /*indoor H th*/ +0x3d16, /*indoor L th*/ +0x3e30, /*indoor gain ratio 0x44 6a */ +0x3f1a, /*indoor H lum 0x12 18 */ +0x4060, /*indoor M lum 0x18 1c*/ +0x411a, /*indoor L lum 0x18 3e*/ + +0x4298, /*dark1 H th*/ +0x4328, /*dark1 L th*/ +0x4465, /*dark1 gain ratio*/ +0x4516, /*dark1 H lum 0x38->0x28 */ +0x4630, /*dark1 M lum 0x27->0x17*/ +0x4734, /*dark1 L lum 0x20->0x1a */ + +0x4890, /*dark2 H th*/ +0x492a, /*dark2 L th*/ +0x4a65, /*dark2 gain ratio*/ +0x4b18, /*dark2 H lum */ +0x4c31, /*dark2 M lum*/ +0x4d36, /*dark2 L lum */ + +0x4e80, /*dark3 H th*/ +0x4f30, /*dark3 L th*/ +0x5065, /*dark3 gain ratio*/ +0x5119, /*dark3 H lum */ +0x5231, /*dark3 M lum */ +0x5336, /*dark3 L lum */ + +0x5a3f, /*blue sky mode out1/2 enable 0x27->3f */ +0x5b00, /*Impulse pixel enable dark123,in,out123 :: must be 0x07*/ +0x5c9f, /*Indoor maxfilter rate[7:5] | Uncertain onoff[4:0] 0x1f ->0x9f*/ + +0x603f, /*GbGr all enable*/ +0x620f, /*GbGr offset*/ + +0x650c, /*Outdoor GbGr rate H 100% M 25% L 100%*/ +0x660c, /*Indoor GbGr rate H 100% M 25% L 100%*/ +0x6700, /*dark GbGr rate H/M/L 100%*/ + +0x700c, /* Abberation On/Off B[1]: Outdoor B[0]: Indoor 07>>c*/ +0x75a0, /* Outdoor2 Abberation Luminance lvl */ +0x7db4, /* Indoor Abberation Luminance lvl*/ + +0x9608, /*indoor/Dark1 edgeoffset1*/ +0x9714, /*indoor/Dark1 center G value*/ +0x98f5, /*slope indoor :: left/right graph polarity, slope*/ +0x992a, /*indoor uncertain ratio control*/ +0x9a20, /*Edgeoffset_dark*/ + +/*DPC_CTRL*/ +0x0312, /*Preview DPC off[0x5c] on[0x5d]*/ +0x200f, +0x210f, + +0x2500, /* 0x30*/ + +0x2a01, +0x2e00, /*2010.8.25*/ + +0x3035, /*Texture region(most detail)*/ +0x31a0, /*STD uniform1 most blur region*/ +0x32b0, /*STD uniform2 2nd blur*/ +0x33c0, /*STD uniform3 3rd blur*/ +0x34d0, /*STD normal noise1 4th blur */ +0x35e0, /*STD normal noise2 5th blur*/ +0x36ff, /*STD normal noise3 6th blur*/ + +0x4083, /*Outdoor2 H th*/ +0x4120, /*Outdoor2 L th */ +0x4208, /*Outdoor2 H luminance */ +0x4310, /*Outdoor2 M luminance */ +0x4410, /*Outdoor2 l luminance */ +0x4550, /*Outdoor2 ratio*/ + +0x4683, /*Outdoor1 H th*/ +0x4720, /*Outdoor1 L th */ +0x4808, /*Outdoor1 H luminance*/ +0x4910, /*Outdoor1 M luminance*/ +0x4a10, /*Outdoor1 L luminance*/ +0x4b50, /*Outdoor1 ratio*/ + +0x4c80, /*Indoor H th*/ +0x4d48, /*Indoor L th*/ +0x4e30, /*indoor H lum*/ +0x4f30, /*indoor M lum*/ +0x5012, /*indoor L lum */ +0x5170, /*indoor ratio 0x10 -> 0x45*/ + +0x52a8, /*dark1 H th*/ +0x5330, /*dark1 L th */ +0x5428, /*dark1 H lum */ +0x553e, /*dark1 M lum*/ +0x5667, /*dark1 L lum*/ +0x576a, /*dark1 ratio*/ + +0x58a0, /*dark2 H th*/ +0x5940, /*dark2 L th*/ +0x5a28, /*dark2 H lum*/ +0x5b3f, /*dark2 M lum*/ +0x5c68, /*dark2 L lum*/ +0x5d70, /*dark2 ratio*/ + +0x5ea0, /*dark3 H th*/ +0x5f40, /*dark3 L th*/ +0x6029, /*dark3 H lum*/ +0x613f, /*dark3 M lum*/ +0x6269, /*dark3 L lum*/ +0x636a, /*dark3 ratio*/ + +/*C-filter(Out2&Out1)*/ +0x7010, +0x710a, + +/*C-filter(Indoor&Dark3)*/ +0x7210, +0x730a, + +/*C-filter(Dark2&Dark1)*/ +0x7418, +0x7512, + +0x8020, +0x8140, +0x8265, +0x851a, +0x8800, +0x8900, +0x905d, /*Preview DPC off[0x5c] on[0x5d]*/ + +/*DPC-Dark1,2,3*/ +0xad07, /*10825*/ +0xae07, /*10825*/ +0xaf07, /*10825*/ + +/*Blue Det..*/ +0xc558, /*BlueRange 2010.8.25 0x40->23 */ +0xc620, /*GreenRange 2010.8.25 0x3b->20 */ + +0xd088, /*2010.8.25*/ +0xd180, +0xd217,/*preview 17, full 67*/ +0xd300, +0xd400, +0xd50f,/*preview 0f, full 02*/ +0xd6ff, +0xd7ff,/*preview ff, full 18*/ +0xd800, +0xd904, + +/*interpolated with average*/ +0xdb38, /*resolution issue 0x00->0x18->0x38 */ +0xd904, /*strong_edge detect ratio*/ +0xe001, /*strong_edge detect ratio*/ + +0x0313, /*page 13 sharpness 1D*/ +0x10c5, +0x117b, +0x120e, +0x1400, + +0x1511, /*added option 1.3M*/ +0x1830, /*added option 1.3M*/ + +0x2015, +0x2113, +0x2233, +0x2308, /*hi_clip th1*/ +0x241a, /*hi_clip th2*/ +0x2506, /*low clip th*/ + +0x2618, +0x2730, +0x2910, /*time th*/ +0x2a30, /*pga th*/ + +0x2b03, /*lpf out2*/ +0x2c03, /*lpf out1*/ +0x2d0c, +0x2e12, +0x2f12, + +/*1D Edge*/ +0x500a, /*out2 hi nega*/ +0x5307, /* hi pos*/ +0x510c, /* mi nega*/ +0x5407, /* mi pos*/ +0x520b, /* lo nega*/ +0x5508, /* lo pos*/ + +0x560a, /*out1 hi nega*/ +0x5907, /* hi pos */ +0x570c, /* mi nega*/ +0x5a07, /* mi pos */ +0x580b, /* lo nega*/ +0x5b08, /* lo pos */ + +/*Indoor Edge*/ +0x5c08, /*indoor hi nega*/ +0x5f07, /* hi pos*/ +0x5d14, +0x6012, +0x5e0a, +0x6108, /* low pos*/ + +0x6208, /*dark1 hi nega*/ +0x6506, /* hi pos */ +0x6308, /* mid nega */ +0x6606, /* mid pos */ +0x6408, /* low nega */ +0x6706, /* low pos */ + +0x6807, /*dark2 hi nega*/ +0x6b05, /* hi pos */ +0x6907, /* mid nega */ +0x6c05, /* mid pos */ +0x6a07, /* low nega */ +0x6d05, /* low pos */ + +0x6e0a, /*dark3 hi nega*/ +0x7109, /* hi pos */ +0x6f0a, /* mid nega */ +0x7209, /* mid pos */ +0x700a, /* low nega */ +0x7309, /* low pos */ + + /* 2DY*/ +0x80c1, +0x811f, +0x82e1, +0x8333, + +0x9005, +0x9105, +0x9233, +0x9330, +0x9403, +0x9514, +0x9730, +0x9930, + +0xa002, /*2d lclp out2 nega*/ +0xa103, /*2d lclp out2 pos*/ +0xa202, /*2d lclp out1 nega*/ +0xa303, /*2d lclp out1 pos*/ +0xa403, /*2d lclp in nega*/ +0xa504, /*2d lclp in pos*/ +0xa607, /*2d lclp dark1 nega*/ +0xa708, /*2d lclp dark1 pos*/ +0xa807, /*2d lclp dark2 nega*/ +0xa908, /*2d lclp dark2 pos*/ +0xaa07, /*2d lclp dark3 nega*/ +0xab08, /*2d lclp dark3 pos*/ + +0xb010, /*out2 H Ne*/ +0xb310, /* H Po*/ +0xb11e, /* M Ne*/ +0xb41e, /* M Po*/ +0xb21f, /* L Ne*/ +0xb51e, /* L Po*/ + +0xb610, /*out1 H Ne */ +0xb910, /* H Po */ +0xb71e, /* M Ne */ +0xba1e, /* M Po */ +0xb81f, /* L Ne */ +0xbb1e, /* L Po */ + +0xbc20, /*indoor H Ne*/ +0xbf1e, /* H Po*/ +0xbd25, /* M Ne*/ +0xc023, /* M Po*/ +0xbe24, /* L Ne*/ +0xc122, /* L Po*/ + +0xc223, /*dark1 H Ne*/ +0xc523, /* H Po*/ +0xc329, /* M Ne*/ +0xc629, /* M Po*/ +0xc425, /* L Ne*/ +0xc725, /* L Po*/ + +0xc81c, /*dark2 H Ne*/ +0xcb1c, /* H Po*/ +0xc925, /* M Ne*/ +0xcc25, /* M Po*/ +0xca23, /* L Ne*/ +0xcd23, /* L Po*/ + +0xce1c, /*dark3 H Ne*/ +0xd11c, /* H Po*/ +0xcf25, /* M Ne*/ +0xd225, /* M Po*/ +0xd023, /* L Ne*/ +0xd323, /* L Po*/ + +/* PAGE 14 START*/ +0x0314, +0x1031, + +0x1480, /* GX*/ +0x1580, /* GY*/ +0x1680, /* RX*/ +0x1780, /* RY*/ +0x1880, /* BX*/ +0x1980, /* BY*/ + +0x2060, /* X Center*/ +0x2180, /* Y Center*/ + +0x2280, +0x2380, +0x2480, + +0x30c8, +0x312b, +0x3200, +0x3300, +0x3490, + +0x4056, /*R min's set 4e*/ +0x413a, /*Gr*/ +0x4237, /*B*/ +0x433a, /*Gb*/ + +0x0315, +0x1021, +0x1444, /*49*/ +0x1534, /*38*/ +0x1626, /*2b*/ +0x172f, + +0x30dd, +0x3162, +0x3205, +0x3326, +0x34bd, +0x3517, +0x3618, +0x3738, +0x38d0, + +0x40b0, +0x4130, +0x4200, +0x4300, +0x4400, +0x4500, +0x4699, +0x4719, +0x4800, + +0x5016, +0x51b2, +0x521c, +0x5306, +0x5420, +0x55a6, +0x560e, +0x57b2, +0x5824, + +0x0316, +0x1031, /*GMA_CTL*/ +0x187e, /*AG_ON*/ +0x197d, /*AG_OFF*/ +0x1a0e, /*TIME_ON*/ +0x1b01, /*TIME_OFF*/ +0x1Cdc, /*OUT_ON*/ +0x1Dfe, /*OUT_OFF*/ + +/*GMA Indoor*/ +0x3000, +0x3107, +0x321a, +0x3335, +0x345a, +0x357c, +0x3696, +0x37a9, +0x38b7, +0x39c6, +0x3ad2, +0x3bdc, +0x3ce4, +0x3deb, +0x3ef1, +0x3ff5, +0x40f9, +0x41fd, +0x42ff, + +/*RGMA Outdoor*/ +0x5000, +0x5103, +0x5213, +0x532e, +0x5459, +0x5579, +0x5690, +0x57a3, +0x58b4, +0x59c2, +0x5acd, +0x5bd7, +0x5ce0, +0x5de5, +0x5ee9, +0x5fee, +0x60f1, +0x61f3, +0x62f6, + +/*BGMA Dark*/ +0x7003, +0x7111, +0x721f, +0x7337, +0x7452, +0x756c, +0x7685, +0x779a, +0x78ad, +0x79bd, +0x7acb, +0x7bd6, +0x7ce0, +0x7de8, +0x7eef, +0x7ff4, +0x80f8, +0x81fb, +0x82fe, + +0x0324, /*Resol control */ +0x60c5, /*edge even frame | 16bit resol | white edge cnt | scene resol enable*/ +0x6104, /*even frame update */ +0x6408, +0x6500, +0x6626, /*edge th2 H */ +0x6700, /*edge th2 L */ + +0x0313, +0x1831, /*flat center Gb/Gr*/ +0x7402, /*det slope en | gausian filter*/ +0x750d, /*1D negative gain det 09 */ +0x760d, /*1D postive gain det 08*/ +0x7710, /*1D hclp2 det*/ +0x7808, /*outdoor flat threshold*/ +0x7910, /*indoor flat threshold*/ + +0x81df, /*det gain controler*/ +0x8690, /*2D negative gain det */ +0x8790, /*2D postive gain det */ +0x962a, /*2D hclp2 det*/ + +0x0312, /*0x12 page*/ +0xd088, +0xd9e4, + +/* PAGE 18 START*/ +0x0318, +0x1400, + +/* PAGE 20 START*/ +0x0320, +0x111c, +0x1830, +0x1a08, +0x2045,/*weight*/ +0x2130, +0x2210, +0x2300, +0x2400, + +0x28e7, /* add 20120223*/ +0x290d, /* 20100305 ad -> 0d*/ +0x2afd, +0x2bf8, + +0x2cc3, +0x2d5f, /* add 20120223*/ +0x2e33, +0x30f8, +0x3203, +0x332e, +0x3430, +0x35d4, +0x36ff, /*fe*/ +0x3732, +0x3804, +0x3922, +0x3ade, +0x3b22, +0x3cde, +0x3de1, + +0x5045, +0x5188, + +0x561a, +0x5780, +0x580e, +0x596a, +0x5a04, + +0x5e9d, /*AE_AWB_start*/ +0x5f76, /*AE_AWB_start*/ + +0x7033, /* 6c*/ +0x7182, /* 82(+8)*/ + +0x7621, +0x7771, +0x7822, /* 24*/ +0x7923, /* Y Target 70 => 25, 72 => 26*/ +0x7a23, /* 23*/ +0x7b22, /* 22*/ +0x7d23, + +0x8301, /*EXP Normal 33.33 fps */ +0x845f, +0x8590, +0x8601, /*EXPMin 7500.00 fps*/ +0x8790, +0x8805, /*EXP Max(120Hz) 8.00 fps */ +0x89b8, +0x8ad8, +0xa505, /*EXP Max(100Hz) 8.33 fps */ +0xa67e, +0xa740, +0x8B75, /*EXP100 */ +0x8C30, +0x8D61, /*EXP120 */ +0x8Ea8, +0x9c09, /*EXP Limit 1250.00 fps */ +0x9d60, +0x9e01, /*EXP Unit */ +0x9f90, +0x989d, + +0xb016, +0xb114, +0xb2f8, +0xb314, +0xb41b, +0xb546, +0xb631, +0xb729, +0xb826, +0xb924, +0xba22, +0xbb42, +0xbc41, +0xbd40, + +0xc010, +0xc138, +0xc238, +0xc338, +0xc407, + +0xc880, +0xc980, +0x109c, /* ae enable*/ +/* PAGE 20 END*/ + +/*AE_Weight*/ +0x0321, +0x2011, +0x2111, +0x2211, +0x2311, +0x2412, +0x2522, +0x2622, +0x2721, +0x2812, +0x2922, +0x2a22, +0x2b21, +0x2c12, +0x2d23, +0x2e32, +0x2f21, +0x3012, +0x3123, +0x3232, +0x3321, +0x3412, +0x3522, +0x3622, +0x3721, +0x3812, +0x3922, +0x3a22, +0x3b21, +0x3c11, +0x3d11, +0x3e11, +0x3f11, + +/* PAGE 22 START*/ +0x0322, +0x10fd, +0x112e, +0x1901, /* Low On*/ +0x2030, /* for wb speed*/ +0x2140, +0x2401, +0x257e, /* for tracking 20120314 */ + +0x3080, /* 20120224 test*/ +0x3180, +0x3811, +0x3934, + +0x40e8, +0x4143, /* 33*/ +0x4222, /* 22*/ + +0x43f3, /* f6*/ +0x4454, /* 44*/ +0x4522, /* 33*/ + +0x4600, +0x480a, +0x50b2, +0x5181, +0x5298, + +0x8038, +0x8120, +0x8238, /* 3a*/ + +0x8356, /* R Max*/ +0x8420, /* R Min*/ +0x8552, /* B Max*/ +0x8620, /* B Min*/ + +0x8745, +0x883a, +0x8933, +0x8a2c, + +0x8b42, +0x8c3d, +0x8d30, +0x8e2c, + +0x8f5a, +0x9059, +0x9155, +0x924e, +0x9344, +0x943a, +0x9534, +0x962c, +0x9723, +0x9820, +0x991f, +0x9a1f, + +0x9b77, +0x9c77, +0x9d48, +0x9e38, +0x9f30, + +0xa040, +0xa121, +0xa26f, +0xa3ff, + +0xa414, /* 1500fps*/ +0xa544, /* 700fps*/ +0xa6cf, + +0xad40, +0xae4a, + +0xaf2a, /* low temp Rgain*/ +0xb028, /* low temp Rgain*/ + +0xb100, /* 0x20 -> 0x00 0405 modify*/ +0xb4bf, /* for tracking 20120314*/ +0xb8a1, /* a2: b-2, R+2 b4 B-3, R+4 lowtemp b0 a1 Spec AWB A modify*/ +0xb900, +/* PAGE 22 END*/ + +/* PAGE 48 (MiPi 1600x1200)*/ +0x0300, + +/* PLL Setting */ +0xd005, +0xd130, +0xd205, +0xd320, +0xd085, +0xd085, +0xd085, +0xd095, + +0x0348, +/* MIPI TX Setting */ +0x101c, +0x1100, +0x1200, +0x1400, +0x1604, +0x1700, +0x1880, +0x1900, +0x1aa0, +/*0x1b0d,*/ +0x1c02, +0x1d0e, +0x1e07, +0x1f08, + +0x2200, +0x2301, +0x241e, +0x2500, +0x2600, +0x2708, +0x2800, +/*0x2b40,*/ + +0x3005, +0x3100, + +0x3207, +0x3309, +0x3401, +0x3501, + +0x0300, +0x0101, +}; + +static const sr130pc20_regset_t sr130pc20_VT_Init_Reg[] = { +/*0 Page*/ +0x0300, +0x0101, /*sleep*/ +0x0103, /*s/w reset*/ +0x0101, /*sleep*/ + +0x0800,/*Don't touch*/ +0x0937,/*Don't touch*/ +0x0a33,/*Don't touch*/ + +/*PLL Setting*/ +0xd005, +0xd130, +0xd201, +0xd320, +0xd085, +0xd085, +0xd085, +0xd095, + +0x1011, +0x1194, /*xy flip*/ +0x1200, /*Sync type default:0x00 PCLK[2] 0 falling, 1 rising*/ +0x1488, + +/*--------------- windowing */ +0x0300, +0x2000, +0x2104, +0x2200, +0x2304, +0x2403, +0x25C0, +0x2605, +0x2700, + +0x4001, /*Hblank 280*/ +0x4118, +0x4200, /*Vblank 20*/ +0x4314, + +/*--------------- BLC*/ +0x8008, /*Don't touch */ +0x8197, /*Don't touch */ +0x8290, /*Don't touch */ +0x8330, /*Don't touch */ +0x84cc, /*Don't touch*/ +0x8500, /*Don't touch*/ +0x86d4, /*Don' t touch*/ +0x870f, /*Don't touch*/ +0x8834, /*Don't touch*/ + +0x9009, /*BLC_TIME_TH_ON*/ +0x9109, /*BLC_TIME_TH_OFF */ +0x92f0, /*BLC_AG_TH_ON*/ +0x93e8, /*BLC_AG_TH_OFF*/ + +0x9495, /*091202*/ +0x9590, /*091202 */ +0x9838, /*Don't touch*/ + +/*Dark BLC*/ +0xa001, /* 20100309*/ +0xa201, /* 20100309*/ +0xa401, /* 20100309*/ +0xa601, /* 20100309*/ + +/*Normal BLC*/ +0xa800, +0xaa00, +0xac00, +0xae00, + +/*Out BLC*/ +0x9900, +0x9a00, +0x9b00, +0x9c00, + +/*2 Page*/ +0x0302, +0x1200, /*Don't touch*/ +0x1400, /*Don't touch*/ +0x1500, /*Don't touch*/ +0x184C, /*Don't touch*/ +0x1900, /*Don't touch*/ +0x1A39, /*Don't touch*/ +0x1B00,/*Don't touch*/ +0x1C1a, /*Don't touch*/ +0x1D14, /*Don't touch*/ +0x1E30,/*Don't touch*/ +0x1F10,/*Don't touch*/ + +0x2077, +0x21de, +0x22a7, +0x2330, +0x2477, +0x2510, +0x2610, +0x273c, +0x2b80, +0x2c02, +0x2da0, +0x2e00, +0x2fa7, + +0x3000, +0x3199, +0x3200, +0x3300, +0x3422, +0x3601, +0x3701, +0x3888, +0x3988, +0x3d03, +0x3e0d, +0x3f02, + +0x49d1, +0x4a14, + +0x5021, +0x5201, +0x5381, +0x5410, +0x551c, +0x5611, +0x5818, +0x5916, +0x5da2, +0x5e5a, + +0x6093, /* 20120517 modify*/ +0x61a4, /* 20120517 modify*/ +0x6294, /* 20120517 modify*/ +0x63a3, /* 20120517 modify*/ +0x6494, /* 20120517 modify*/ +0x65a3, /* 20120517 modify*/ +0x670c, +0x680c, +0x690c, +0x6ab4, +0x6bc4, +0x6cb5, +0x6dc2, +0x6eb5, +0x6fc0, + +0x70b6, +0x71b8, +0x7295, /* 20120517 modify*/ +0x73a2, /* 20120517 modify*/ +0x7495, /* 20120517 modify*/ +0x75a2, /* 20120517 modify*/ +0x7695, /* 20120517 modify*/ +0x77a2, /* 20120517 modify*/ +0x7C92, /* 20120517 modify*/ +0x7Dff, /* 20120517 modify*/ + +0x8001, /* 20120517 modify*/ +0x818a, /* 20120517 modify*/ +0x821e, /* 20120517 modify*/ +0x8336, /* 20120517 modify*/ +0x8489, /* 20120517 modify*/ +0x858b, /* 20120517 modify*/ +0x8689, /* 20120517 modify*/ +0x878b, /* 20120517 modify*/ +0x88ab, +0x89bc, +0x8aac, +0x8bba, +0x8cad, +0x8db8, +0x8eae, +0x8fb2, + +0x90b3, +0x91b7, +0x9252, /* 20120517 modify*/ +0x936a, /* 20120517 modify*/ +0x9489, /* 20120517 modify*/ +0x958b, /* 20120517 modify*/ +0x9689, /* 20120517 modify*/ +0x978b, /* 20120517 modify*/ + +0xA002, +0xA186, /* 20120517 modify*/ +0xA202, +0xA386, /* 20120517 modify*/ +0xA486, /* 20120517 modify*/ +0xA502, +0xA686, /* 20120517 modify*/ +0xA702, +0xA892, /* 20120517 modify*/ +0xA994, /* 20120517 modify*/ +0xAA92, /* 20120517 modify*/ +0xAB94, /* 20120517 modify*/ +0xAC1c, +0xAD22, +0xAE1c, +0xAF22, + +0xB0a4, /* 20120517 modify*/ +0xB1ae, /* 20120517 modify*/ +0xB2a4, /* 20120517 modify*/ +0xB3ae, /* 20120517 modify*/ +0xB4a6, /* 20120517 modify*/ +0xB5ac, /* 20120517 modify*/ +0xB6a6, /* 20120517 modify*/ +0xB7ac, /* 20120517 modify*/ +0xB8a6, /* 20120517 modify*/ +0xB9ab, /* 20120517 modify*/ +0xBAa6, /* 20120517 modify*/ +0xBBab, /* 20120517 modify*/ +0xBCa6, /* 20120517 modify*/ +0xBDab, /* 20120517 modify*/ +0xBEa6, /* 20120517 modify*/ +0xBFab, /* 20120517 modify*/ + +0xc437, +0xc552, +0xc66b, +0xc786, +0xc838, /* 20120517 modify*/ +0xc950, /* 20120517 modify*/ +0xca38, /* 20120517 modify*/ +0xcb50, /* 20120517 modify*/ +0xcc6c, /* 20120517 modify*/ +0xcd84, /* 20120517 modify*/ +0xce6c, /* 20120517 modify*/ +0xcf84, /* 20120517 modify*/ + +/*0xd4a6,*/ +/*0xd5ac,*/ +/*0xd6a6,*/ +/*0xd7ac,*/ +/*add 20120517*/ +0xdc00, /* Added*/ +0xddaf, /* Added*/ +0xde00, /* Added*/ +0xdf90, /* Added*/ + +0xd010, +0xd114, +0xd220, +0xd300, +/*DCDC */ +0xd409, /*DCDC_TIME_TH_ON*/ +0xd509, /*DCDC_TIME_TH_OFF */ +0xd6f0, /*DCDC_AG_TH_ON*/ +0xd7e8, /*DCDC_AG_TH_OFF*/ + +0xea8a, + +0xF001, /* clock inversion*/ +0xF101, +0xF201, +0xF301, +0xF401, +0xF500, + +/*----------------------------------------------*/ +0x0310, /*page 10*/ +0x1001, /*Ycbcr422_bit Order: YUYV*/ +0x1230, /*y offset[4], dif_offset[5]*/ +0x1302, /*contrast effet enable : 0x02*/ +0x3400, /*hidden 10->00 100209*/ +0x3701, /*yc2d power save */ +0x3f04, /*100825*/ +0x4080, /*Y offset */ +0x4138, +0x4880, /*Contrast (Y = constrast * (Y - 128) + 128)*//*86 */ +0x50f0, +0x5300, /*dif_offset option */ +0x5530, /*dif_offset option diff_offset max */ + +0x6003, /*out color sat en[7] | auto color decrement en[1] / + | manual color sat en[0]*/ + + +0x6183, /*blue saturation_C0*/ +0x6280, /*red saturation_B0*/ + +0x63ff, /*auto decresment on AG th*/ +0x64ff, /*auto decresment on DG th*/ +0x66e4, /*Outdoor saturation step 137fps apply out th */ +0x6700, /*Outdoor saturation B/R*/ +0x7601, /* ADD 20121031 */ +0x7904, /* ADD 20121031 */ + +/* Hi 163 */ +/* PAGE 10 START*/ +0x0310, +0x8000, /* dsshin --> color enhance*/ +0xf500, /* dsshin --> h blank option*/ + +0x0311, /*page 11 D_LPF */ +0x103f, /*B[6]:Blue En Dlpf on[4:0] Sky over off : 0x7f->3f*/ +0x1120, /* Uniform Full GbGr/OV-Nr*/ + +0x1280, /*Blue MaxOpt blue sky max filter optoin rate : 0 0xc0->80*/ +0x13b8, /*dark2[7] | dark2 maxfilter ratio[6:4] + | dark3[3] | dark3 maxfilter ratio[2:0] */ + +0x30ba, /*Outdoor2 H th*/ +0x3110, /*Outdoor2 L th*/ +0x3250, /*Outdoor2 gain ratio*/ +0x331d, /*Outdoor2 H lum*/ +0x3420, /*Outdoor2 M lum*/ +0x351f, /*Outdoor2 L lum*/ + +0x36b0, /*Outdoor1 H th*/ +0x3718, /*Outdoor1 L th*/ +0x3850, /*Outdoor1 gain ratio 0x80->40*/ +0x391d, /*Outdoor1 H lum 0x28->1e*/ +0x3a20, /*Outdoor1 M lum 0x10->15*/ +0x3b1f, /*Outdoor1 L lum 0x08->20*/ + +0x3c3f, /*indoor H th*/ +0x3d16, /*indoor L th*/ +0x3e30, /*indoor gain ratio 0x44 6a */ +0x3f1a, /*indoor H lum 0x12 18 */ +0x4060, /*indoor M lum 0x18 1c*/ +0x411a, /*indoor L lum 0x18 3e*/ + +0x4298, /*dark1 H th*/ +0x4328, /*dark1 L th*/ +0x4465, /*dark1 gain ratio*/ +0x4516, /*dark1 H lum 0x38->0x28 */ +0x4630, /*dark1 M lum 0x27->0x17*/ +0x4734, /*dark1 L lum 0x20->0x1a */ + +0x4890, /*dark2 H th*/ +0x492a, /*dark2 L th*/ +0x4a65, /*dark2 gain ratio*/ +0x4b18, /*dark2 H lum */ +0x4c31, /*dark2 M lum*/ +0x4d36, /*dark2 L lum */ + +0x4e80, /*dark3 H th*/ +0x4f30, /*dark3 L th*/ +0x5065, /*dark3 gain ratio*/ +0x5119, /*dark3 H lum */ +0x5231, /*dark3 M lum */ +0x5336, /*dark3 L lum */ + +0x5a3f, /*blue sky mode out1/2 enable 0x27->3f */ +0x5b00, /*Impulse pixel enable dark123,in,out123 + :: must be 0x07 fix setting use!*/ +0x5c9f, /*Indoor maxfilter rate[7:5] | Uncertain onoff[4:0] 0x1f ->0x9f*/ + +0x603f, /*GbGr all enable*/ +0x620f, /*GbGr offset*/ +/*0x6325,*/ /*GbGr max_20120605_off*/ +/*0x6410,*/ /*GbGr min_20120605_off*/ + +0x650c, /*Outdoor GbGr rate H 100% M 25% L 100%*/ +0x660c, /*Indoor GbGr rate H 100% M 25% L 100%*/ +0x6700, /*dark GbGr rate H/M/L 100%*/ + +0x700c, /* Abberation On/Off B[1]: Outdoor B[0]: Indoor 07>>c*/ +0x75a0, /* Outdoor2 Abberation Luminance lvl */ +0x7db4, /* Indoor Abberation Luminance lvl*/ + +0x9608, /*indoor/Dark1 edgeoffset1*/ +0x9714, /*indoor/Dark1 center G value*/ +0x98f5, /*slope indoor :: left/right graph polarity, slope*/ +0x992a, /*indoor uncertain ratio control*/ +0x9a20, /*Edgeoffset_dark*/ + +/*DPC_CTRL*/ +0x0312, /*Preview DPC off[0x5c] on[0x5d]*/ +0x200e, +0x210e, + +0x2500, /* 0x30*/ + +0x2a01, +0x2e00, /*2010.8.25*/ + +0x3035, /*Texture region(most detail)*/ +0x31a0, /*STD uniform1 most blur region*/ +0x32b0, /*STD uniform2 2nd blur*/ +0x33c0, /*STD uniform3 3rd blur*/ +0x34d0, /*STD normal noise1 4th blur */ +0x35e0, /*STD normal noise2 5th blur*/ +0x36ff, /*STD normal noise3 6th blur*/ + +0x4083, /*Outdoor2 H th*/ +0x4120, /*Outdoor2 L th */ +0x4208, /*Outdoor2 H luminance */ +0x4310, /*Outdoor2 M luminance */ +0x4410, /*Outdoor2 l luminance */ +0x4550, /*Outdoor2 ratio*/ + +0x4683, /*Outdoor1 H th*/ +0x4720, /*Outdoor1 L th */ +0x4808, /*Outdoor1 H luminance*/ +0x4910, /*Outdoor1 M luminance*/ +0x4a10, /*Outdoor1 L luminance*/ +0x4b50, /*Outdoor1 ratio*/ + +0x4c80, /*Indoor H th*/ +0x4d48, /*Indoor L th*/ +0x4e30, /*indoor H lum*/ +0x4f30, /*indoor M lum*/ +0x5012, /*indoor L lum */ +0x5170, /*indoor ratio 0x10 -> 0x45*/ + +0x52a8, /*dark1 H th*/ +0x5330, /*dark1 L th */ +0x5428, /*dark1 H lum */ +0x553e, /*dark1 M lum*/ +0x5667, /*dark1 L lum*/ +0x576a, /*dark1 ratio*/ + +0x58a0, /*dark2 H th*/ +0x5940, /*dark2 L th*/ +0x5a28, /*dark2 H lum*/ +0x5b3f, /*dark2 M lum*/ +0x5c68, /*dark2 L lum*/ +0x5d70, /*dark2 ratio*/ + +0x5ea0, /*dark3 H th*/ +0x5f40, /*dark3 L th*/ +0x6029, /*dark3 H lum*/ +0x613f, /*dark3 M lum*/ +0x6269, /*dark3 L lum*/ +0x636a, /*dark3 ratio*/ + +/*C-filter(Out2&Out1)*/ +0x7010, +0x710a, + +/*C-filter(Indoor&Dark3)*/ +0x7210, +0x730a, + +/*C-filter(Dark2&Dark1)*/ +0x7418, +0x7512, + +0x8020, +0x8140, +0x8265, +0x851a, +0x8800, +0x8900, +0x905d, /*Preview DPC off[0x5c] on[0x5d]*/ + +/*DPC-Dark1,2,3*/ +0xad07, /*10825*/ +0xae07, /*10825*/ +0xaf07, /*10825*/ + +/*Blue Det..*/ +0xc558, /*BlueRange 2010.8.25 0x40->23 */ +0xc620, /*GreenRange 2010.8.25 0x3b->20 */ + +0xd088, /*2010.8.25*/ +0xd180, +0xd217,/*preview 17, full 67*/ +0xd300, +0xd400, +0xd50f,/*preview 0f, full 02*/ +0xd6ff, +0xd7ff,/*preview ff, full 18*/ +0xd800, +0xd904, + +/*interpolated with average*/ +0xdb38, /*resolution issue 0x00->0x18->0x38 */ +0xd904, /*strong_edge detect ratio*/ +0xe001, /*strong_edge detect ratio*/ + +0x0313, /*page 13 sharpness 1D*/ +0x10c5, +0x117b, +0x120e, +0x1400, + +0x1511, /*added option 1.3M*/ +0x1830, /*added option 1.3M*/ + +0x2015, +0x2113, +0x2233, +0x2308, /*hi_clip th1*/ +0x241a, /*hi_clip th2*/ +0x2506, /*low clip th*/ + +0x2618, +0x2730, +0x2910, /*time th*/ +0x2a30, /*pga th*/ + +0x2b03, /*lpf out2*/ +0x2c03, /*lpf out1*/ +0x2d0c, +0x2e12, +0x2f12, + +/*1D Edge*/ +0x500a, /*out2 hi nega*/ +0x5307, /* hi pos*/ +0x510c, /* mi nega*/ +0x5407, /* mi pos*/ +0x520b, /* lo nega*/ +0x5508, /* lo pos*/ + +0x560a, /*out1 hi nega*/ +0x5907, /* hi pos */ +0x570c, /* mi nega*/ +0x5a07, /* mi pos */ +0x580b, /* lo nega*/ +0x5b08, /* lo pos */ + +/*Indoor Edge*/ +0x5c08, /*indoor hi nega*/ +0x5f07, /* hi pos*/ +0x5d14, /* mid nega ,11*/ +0x6012, /* mid pos ,0*/ +0x5e0a, /* low nega */ +0x6108, /* low pos*/ + +0x6208, /*dark1 hi nega*/ +0x6506, /* hi pos */ +0x6308, /* mid nega */ +0x6606, /* mid pos */ +0x6408, /* low nega */ +0x6706, /* low pos */ + +0x6807, /*dark2 hi nega*/ +0x6b05, /* hi pos */ +0x6907, /* mid nega */ +0x6c05, /* mid pos */ +0x6a07, /* low nega */ +0x6d05, /* low pos */ + +0x6e0a, /*dark3 hi nega*/ +0x7109, /* hi pos */ +0x6f0a, /* mid nega */ +0x7209, /* mid pos */ +0x700a, /* low nega */ +0x7309, /* low pos */ + + /* 2DY*/ +0x80c1, +0x811f, +0x82e1, +0x8333, + +0x9005, +0x9105, +0x9233, +0x9330, +0x9403, +0x9514, +0x9730, +0x9930, + +0xa002, /*2d lclp out2 nega*/ +0xa103, /*2d lclp out2 pos*/ +0xa202, /*2d lclp out1 nega*/ +0xa303, /*2d lclp out1 pos*/ +0xa403, /*2d lclp in nega*/ +0xa504, /*2d lclp in pos*/ +0xa607, /*2d lclp dark1 nega*/ +0xa708, /*2d lclp dark1 pos*/ +0xa807, /*2d lclp dark2 nega*/ +0xa908, /*2d lclp dark2 pos*/ +0xaa07, /*2d lclp dark3 nega*/ +0xab08, /*2d lclp dark3 pos*/ + +0xb010, /*out2 H Ne*/ +0xb310, /* H Po*/ +0xb11e, /* M Ne*/ +0xb41e, /* M Po*/ +0xb21f, /* L Ne*/ +0xb51e, /* L Po*/ + +0xb610, /*out1 H Ne */ +0xb910, /* H Po */ +0xb71e, /* M Ne */ +0xba1e, /* M Po */ +0xb81f, /* L Ne */ +0xbb1e, /* L Po */ + +0xbc20, /*indoor H Ne*/ +0xbf1e, /* H Po*/ +0xbd25, /* M Ne*/ +0xc023, /* M Po*/ +0xbe24, /* L Ne*/ +0xc122, /* L Po*/ + +0xc223, /*dark1 H Ne*/ +0xc523, /* H Po*/ +0xc329, /* M Ne*/ +0xc629, /* M Po*/ +0xc425, /* L Ne*/ +0xc725, /* L Po*/ + +0xc81c, /*dark2 H Ne*/ +0xcb1c, /* H Po*/ +0xc925, /* M Ne*/ +0xcc25, /* M Po*/ +0xca23, /* L Ne*/ +0xcd23, /* L Po*/ + +0xce1c, /*dark3 H Ne*/ +0xd11c, /* H Po*/ +0xcf25, /* M Ne*/ +0xd225, /* M Po*/ +0xd023, /* L Ne*/ +0xd323, /* L Po*/ + +/* PAGE 14 START*/ +0x0314, +0x1031, + +0x1480, /* GX*/ +0x1580, /* GY*/ +0x1680, /* RX*/ +0x1780, /* RY*/ +0x1880, /* BX*/ +0x1980, /* BY*/ + +0x2060, /* X Center*/ +0x2180, /* Y Center*/ + +0x2280, +0x2380, +0x2480, + +0x30c8, +0x312b, +0x3200, +0x3300, +0x3490, + +0x4056, /*R min's set 4e*/ +0x413a, /*Gr*/ +0x4237, /*B*/ +0x433a, /*Gb*/ + +0x0315, +0x1021, +0x1444, /*49*/ +0x1534, /*38*/ +0x1626, /*2b*/ +0x172f, + +0x30dd, +0x3162, +0x3205, +0x3326, +0x34bd, +0x3517, +0x3618, +0x3738, +0x38d0, + +0x40b0, +0x4130, +0x4200, +0x4300, +0x4400, +0x4500, +0x4699, +0x4719, +0x4800, + +0x5016, +0x51b2, +0x521c, +0x5306, +0x5420, +0x55a6, +0x560e, +0x57b2, +0x5824, + +0x0316, +0x1031, /*GMA_CTL*/ +0x187e, /*AG_ON*/ +0x197d, /*AG_OFF*/ +0x1a0e, /*TIME_ON*/ +0x1b01, /*TIME_OFF*/ +0x1Cdc, /*OUT_ON*/ +0x1Dfe, /*OUT_OFF*/ + +/*GMA, Indoor*/ +0x3000, +0x3107, +0x321a, +0x3335, +0x345a, +0x357c, +0x3696, +0x37a9, +0x38b7, +0x39c6, +0x3ad2, +0x3bdc, +0x3ce4, +0x3deb, +0x3ef1, +0x3ff5, +0x40f9, +0x41fd, +0x42ff, + +/*RGMA, Outdoor*/ +0x5000, +0x5103, +0x5213, +0x532e, +0x5459, +0x5579, +0x5690, +0x57a3, +0x58b4, +0x59c2, +0x5acd, +0x5bd7, +0x5ce0, +0x5de5, +0x5ee9, +0x5fee, +0x60f1, +0x61f3, +0x62f6, + +/*BGMA Dark*/ +0x7000, +0x7107, +0x721a, +0x7335, +0x745a, +0x757c, +0x7696, +0x77a9, +0x78b7, +0x79c6, +0x7ad2, +0x7bdc, +0x7ce4, +0x7deb, +0x7ef1, +0x7ff5, +0x80f9, +0x81fd, +0x82ff, + +0x0324, /*Resol control */ +0x60c5, /*edge even frame | 16bit resol | white edge cnt | scene resol enable*/ +0x6104, /*even frame update */ +0x6408, /* 0x6435, edge th1 H*/ +0x6500, /*edge th1 L*/ +0x6626, /*edge th2 H */ +0x6700, /*edge th2 L */ + +0x0313, +0x1831, /*flat center Gb/Gr*/ +0x7402, /*det slope en | gausian filter*/ +0x750d, /*1D negative gain det 09 */ +0x760d, /*1D postive gain det 08*/ +0x7710, /*1D hclp2 det*/ +0x7808, /*outdoor flat threshold*/ +0x7910, /*indoor flat threshold*/ + +0x81df, /*det gain controler*/ +0x8690, /*2D negative gain det */ +0x8790, /*2D postive gain det */ +0x962a, /*2D hclp2 det*/ + +0x0312, /*0x12 page*/ +0xd088, +0xd9e4, + +/* PAGE 20 START*/ +0x0320, +0x111c, +0x1830, +0x1a08, +0x2045,/*weight*/ +0x2130, +0x2210, +0x2300, +0x2400, + +0x28e7, /* add 20120223*/ +0x290d, /* 20100305 ad -> 0d*/ +0x2afd, +0x2bf8, + +0x2cc3, +0x2d5f, /* add 20120223*/ +0x2e33, +0x30f8, +0x3203, +0x332e, +0x3430, +0x35d4, +0x36fe, +0x3732, +0x3804, +0x3922, +0x3ade, +0x3b22, +0x3cde, +0x3de1, + +0x5045, +0x5188, + +0x561a, +0x5780, +0x580e, +0x596a, +0x5a04, + +0x5e9d, /*AE_AWB_start*/ +0x5f76, /*AE_AWB_start*/ + +0x7040, /* 6c*/ +0x7182, /* 82(+8)*/ + +0x7621, +0x7791, +0x7822, /* 24*/ +0x792b, /* Y Target 70 => 25, 72 => 26*/ +0x7a23, /* 23*/ +0x7b22, /* 22*/ +0x7d23, + +0x8301, /*EXP Normal 33.33 fps */ +0x845f, +0x8590, + +0x8601, /*EXPMin 7500.00 fps*/ +0x8790, + +0x8803, /*EXP Max(120Hz) 12.00 fps*/ +0x89d0, +0x8a90, + +0xa504, /*EXP Max(100Hz) 11.11 fps*/ +0xa61e, +0xa7b0, + +0x8B75, /*EXP100 */ +0x8C30, +0x8D61, /*EXP120 */ +0x8Ea8, + +0x9104, /*EXP Fix 10.00 fps*/ +0x9293, +0x93e0, + +0x9c0a, /*EXP Limit 1071.43 fps*/ +0x9df0, +0x9e01, /*EXP Unit */ +0x9f90, +0x989d, + +0xb016, +0xb114, +0xb2f8, +0xb314, +0xb41b, +0xb546, +0xb631, +0xb729, +0xb826, +0xb924, +0xba22, +0xbb42, +0xbc41, +0xbd40, + +0xc010, +0xc138, +0xc238, +0xc338, +0xc407, + +0xc880, +0xc980, +0x109c, /* ae enable*/ +/* PAGE 20 END*/ + +/*AE_Weight*/ +0x0321, +0x2011, +0x2111, +0x2211, +0x2311, +0x2412, +0x2522, +0x2622, +0x2721, +0x2812, +0x2922, +0x2a22, +0x2b21, +0x2c12, +0x2d23, +0x2e32, +0x2f21, +0x3012, +0x3123, +0x3232, +0x3321, +0x3412, +0x3522, +0x3622, +0x3721, +0x3812, +0x3922, +0x3a22, +0x3b21, +0x3c11, +0x3d11, +0x3e11, +0x3f11, + +/* PAGE 22 START*/ +0x0322, +0x10fd, +0x112e, +0x1901, /* Low On*/ +0x2030, /* for wb speed*/ +0x2140, +0x2401, +0x257e, /* for tracking 20120314 */ + +0x3080, /* 20120224 test*/ +0x3180, +0x3811, +0x3934, + +0x40e8, +0x4143, /* 33*/ +0x4222, /* 22*/ + +0x43f3, /* f6*/ +0x4454, /* 44*/ +0x4522, /* 33*/ + +0x4600, +0x480a, +0x50b2, +0x5181, +0x5298, + +0x8038, +0x8120, +0x8238, /* 3a*/ + +0x8356, /* R Max*/ +0x8420, /* R Min*/ +0x8554, /* B Max*/ +0x8620, /* B Min*/ + +0x8746, +0x8836, +0x893a, +0x8a2f, + +0x8b3d, +0x8c37, +0x8d35, +0x8e32, + +0x8f5a, +0x9059, +0x9155, +0x924e, +0x9344, +0x943a, +0x9534, +0x962c, +0x9723, +0x9820, +0x991f, +0x9a1f, + +0x9b77, +0x9c77, +0x9d48, +0x9e38, +0x9f30, + +0xa040, +0xa121, +0xa26f, +0xa3ff, + +0xa414, /* 1500fps*/ +0xa544, /* 700fps*/ +0xa6cf, + +0xad40, +0xae4a, + +0xaf2a, /* low temp Rgain*/ +0xb028, /* low temp Rgain*/ + +0xb100, /* 0x20 -> 0x00 0405 modify*/ +0xb4bf, /* for tracking 20120314*/ +0xb8a1, /* a2: b-2, R+2 b4 B-3, R+4 lowtemp b0 a1 Spec AWB A modify*/ +0xb900, +/* PAGE 22 END*/ + +/* PAGE 48 (MiPi 1600x1200)*/ +0x0300, + +/* PLL Setting */ +0xd005, +0xd130, +0xd205, +0xd320, +0xd085, +0xd085, +0xd085, +0xd095, + +/* MIPI TX Setting */ +0x0348, +0x101c, +0x1100, +0x1200, +0x1400, +0x1604, +0x1700, +0x1880, +0x1900, +0x1aa0, +/*0x1b0d,*/ +0x1c02, +0x1d0e, +0x1e07, +0x1f08, +/*0x2000,*/ + +0x2200, +0x2301, +0x241e, +0x2500, +0x2600, +0x2708, +0x2800, +/*0x2a06,*/ +/*0x2b40,*/ +/*0x2c04,*/ +/*0x2db0,*/ + +0x3005, +0x3100, + +0x3207, +0x3309, +0x3401, +0x3501, +/*0x3601,*/ +/*0x3707,*/ +/*0x3802,*/ +/*0x3902,*/ + +0x0300, +0x0101, +}; + +static const sr130pc20_regset_t sr130pc20_SmartStay_Init_Reg[] = { +/*0 Page*/ +0x0300, +0x0101, /*sleep*/ +0x0103, /*s/w reset*/ +0x0101, /*sleep*/ + +0x0800,/*Don't touch*/ +0x0937,/*Don't touch*/ +0x0a33,/*Don't touch*/ + +/*PLL Setting*/ +0xd005, +0xd130, +0xd201, +0xd320, +0xd085, +0xd085, +0xd085, +0xd095, + +0x1011, +0x1190, /*xy flip*/ +0x1200, +0x1488, + +0x0300, +0x2000, +0x2104, +0x2200, +0x2304, +0x2403, +0x25C0, +0x2605, +0x2700, + +0x4001, /*Hblank_280*/ +0x4118, +0x4201, /*Vblank 400*/ +0x4390, + +/*--------------- BLC*/ +0x8008, /*Don't touch */ +0x8197, /*Don't touch */ +0x8290, /*Don't touch */ +0x8330, /*Don't touch */ +0x84cc, /*Don't touch*/ +0x8500, /*Don't touch*/ +0x86d4, /*Don' t touch*/ +0x870f, /*Don't touch*/ +0x8834, /*Don't touch*/ + +0x900c, /*BLC_TIME_TH_ON*/ +0x910c, /*BLC_TIME_TH_OFF */ +0x92f7, /*BLC_AG_TH_ON*/ +0x93ef, /*BLC_AG_TH_OFF*/ + +0x9495, /*091202*/ +0x9590, /*091202 */ +0x9838, /*Don't touch*/ + +/*Dark BLC*/ +0xa000, /* 20100309*/ +0xa200, /* 20100309*/ +0xa400, /* 20100309*/ +0xa600, /* 20100309*/ + +/*Normal BLC*/ +0xa800, +0xaa00, +0xac00, +0xae00, + +/*Out BLC*/ +0x9900, +0x9a00, +0x9b00, +0x9c00, + +/*2 Page*/ +0x0302, +0x1200, /*Don't touch*/ +0x1400, /*Don't touch*/ +0x1500, /*Don't touch*/ +0x184C, /*Don't touch*/ +0x1900, /*Don't touch*/ +0x1A39, /*Don't touch*/ +0x1B00,/*Don't touch*/ +0x1C1a, /*Don't touch*/ +0x1D14, /*Don't touch*/ +0x1E30,/*Don't touch*/ +0x1F10,/*Don't touch*/ + +0x2077, +0x21de, +0x22a7, +0x2330, +0x2477, +0x2510, +0x2610, +0x273c, +0x2b80, +0x2c02, +0x2da0, +0x2e00, +0x2fa7, + +0x3000, +0x3199, +0x3200, +0x3300, +0x3422, +0x3601, +0x3701, +0x3888, +0x3988, +0x3d03, +0x3e0d, +0x3f02, + +0x49d1, +0x4a14, + +0x5021, +0x5201, +0x5381, +0x5410, +0x551c, +0x5611, +0x5818, +0x5916, +0x5da2, +0x5e5a, + +0x6093, /* 20120517 modify*/ +0x61a4, /* 20120517 modify*/ +0x6294, /* 20120517 modify*/ +0x63a3, /* 20120517 modify*/ +0x6494, /* 20120517 modify*/ +0x65a3, /* 20120517 modify*/ +0x670c, +0x680c, +0x690c, +0x6ab4, +0x6bc4, +0x6cb5, +0x6dc2, +0x6eb5, +0x6fc0, + +0x70b6, +0x71b8, +0x7295, /* 20120517 modify*/ +0x73a2, /* 20120517 modify*/ +0x7495, /* 20120517 modify*/ +0x75a2, /* 20120517 modify*/ +0x7695, /* 20120517 modify*/ +0x77a2, /* 20120517 modify*/ +0x7C92, /* 20120517 modify*/ +0x7Dff, /* 20120517 modify*/ + +0x8001, /* 20120517 modify*/ +0x818a, /* 20120517 modify*/ +0x821e, /* 20120517 modify*/ +0x8336, /* 20120517 modify*/ +0x8489, /* 20120517 modify*/ +0x858b, /* 20120517 modify*/ +0x8689, /* 20120517 modify*/ +0x878b, /* 20120517 modify*/ +0x88ab, +0x89bc, +0x8aac, +0x8bba, +0x8cad, +0x8db8, +0x8eae, +0x8fb2, + +0x90b3, +0x91b7, +0x9252, /* 20120517 modify*/ +0x936a, /* 20120517 modify*/ +0x9489, /* 20120517 modify*/ +0x958b, /* 20120517 modify*/ +0x9689, /* 20120517 modify*/ +0x978b, /* 20120517 modify*/ + +0xA002, +0xA186, /* 20120517 modify*/ +0xA202, +0xA386, /* 20120517 modify*/ +0xA486, /* 20120517 modify*/ +0xA502, +0xA686, /* 20120517 modify*/ +0xA702, +0xA892, /* 20120517 modify*/ +0xA994, /* 20120517 modify*/ +0xAA92, /* 20120517 modify*/ +0xAB94, /* 20120517 modify*/ +0xAC1c, +0xAD22, +0xAE1c, +0xAF22, + +0xB0a4, /* 20120517 modify*/ +0xB1ae, /* 20120517 modify*/ +0xB2a4, /* 20120517 modify*/ +0xB3ae, /* 20120517 modify*/ +0xB4a6, /* 20120517 modify*/ +0xB5ac, /* 20120517 modify*/ +0xB6a6, /* 20120517 modify*/ +0xB7ac, /* 20120517 modify*/ +0xB8a6, /* 20120517 modify*/ +0xB9ab, /* 20120517 modify*/ +0xBAa6, /* 20120517 modify*/ +0xBBab, /* 20120517 modify*/ +0xBCa6, /* 20120517 modify*/ +0xBDab, /* 20120517 modify*/ +0xBEa6, /* 20120517 modify*/ +0xBFab, /* 20120517 modify*/ + +0xc437, +0xc552, +0xc66b, +0xc786, +0xc838, /* 20120517 modify*/ +0xc950, /* 20120517 modify*/ +0xca38, /* 20120517 modify*/ +0xcb50, /* 20120517 modify*/ +0xcc6c, /* 20120517 modify*/ +0xcd84, /* 20120517 modify*/ +0xce6c, /* 20120517 modify*/ +0xcf84, /* 20120517 modify*/ + +/*0xd4a6,*/ +/*0xd5ac,*/ +/*0xd6a6,*/ +/*0xd7ac,*/ +/*add 20120517*/ +0xdc00, /* Added*/ +0xddaf, /* Added*/ +0xde00, /* Added*/ +0xdf90, /* Added*/ + +0xd010, +0xd114, +0xd220, +0xd300, +/*DCDC */ +0xd40c, /*DCDC_TIME_TH_ON*/ +0xd50c, /*DCDC_TIME_TH_OFF */ +0xd6f7, /*DCDC_AG_TH_ON*/ +0xd7ef, /*DCDC_AG_TH_OFF*/ + +0xea8a, + +0xF001, /* clock inversion*/ +0xF101, +0xF201, +0xF301, +0xF401, +0xF500, + +/*----------------------------------------------*/ +0x0310, /*page 10*/ +0x1001, /*Ycbcr422_bit Order: YUYV*/ +0x1103, +0x1230, /*y offset[4], dif_offset[5]*/ +0x1302, /*contrast effet enable : 0x02*/ +0x3400, /*hidden 10->00 100209*/ +0x3701, /*yc2d power save */ +0x3f04, /*100825*/ +0x4080, /*Y offset */ +0x4128, +0x4880, +0x5300, /*dif_offset option */ +0x5530, /*dif_offset option diff_offset max */ + +0x606b, /*out color sat en[7] | auto color decrement en[1] / + | manual color sat en[0]*/ + +0x6183, /*blue saturation_C0*/ +0x6280, /*red saturation_B0*/ + +0x63b0, /*auto decresment on AG th*/ +0x64ff, /*auto decresment on DG th*/ +0x66e4, /*Outdoor saturation step 137fps apply out th */ +0x6700, /*Outdoor saturation B/R*/ +0x7601, /* ADD 20121031 */ +0x7904, /* ADD 20121031 */ + +/* Hi 163 */ +/* PAGE 10 START*/ +0x0310, +0x8000, /* dsshin --> color enhance*/ +0xf500, /* dsshin --> h blank option*/ + +0x0311, /*page 11 D_LPF */ +0x103f, /*B[6]:Blue En Dlpf on[4:0] Sky over off : 0x7f->3f*/ +0x1120, /* Uniform Full GbGr/OV-Nr*/ + +0x1280, /*Blue MaxOpt blue sky max filter optoin rate : 0 0xc0->80*/ +0x13b8, /*dark2[7] | ratio[6:4] | dark3[3] | dark3 maxfilter ratio[2:0] */ + +0x30ba, /*Outdoor2 H th*/ +0x3110, /*Outdoor2 L th*/ +0x3250, /*Outdoor2 gain ratio*/ +0x331d, /*Outdoor2 H lum*/ +0x3420, /*Outdoor2 M lum*/ +0x351f, /*Outdoor2 L lum*/ + +0x36b0, /*Outdoor1 H th*/ +0x3718, /*Outdoor1 L th*/ +0x3850, /*Outdoor1 gain ratio 0x80->40*/ +0x391d, /*Outdoor1 H lum 0x28->1e*/ +0x3a20, /*Outdoor1 M lum 0x10->15*/ +0x3b1f, /*Outdoor1 L lum 0x08->20*/ + +0x3c3f, /*indoor H th*/ +0x3d16, /*indoor L th*/ +0x3e30, /*indoor gain ratio 0x44 6a */ +0x3f1a, /*indoor H lum 0x12 18 */ +0x4060, /*indoor M lum 0x18 1c*/ +0x411a, /*indoor L lum 0x18 3e*/ + +0x4280, /*dark1 H th*/ +0x4318, /*dark1 L th*/ +0x4480, /*dark1 gain ratio*/ +0x450f, /*dark1 H lum 0x38->0x28 */ +0x460c, /*dark1 M lum 0x27->0x17*/ +0x470b, /*dark1 L lum 0x20->0x1a */ + +0x4880, /*dark2 H th*/ +0x4918, /*dark2 L th*/ +0x4a80, /*dark2 gain ratio*/ +0x4b0f, /*dark2 H lum */ +0x4c0c, /*dark2 M lum*/ +0x4d0b, /*dark2 L lum */ + +0x4e80, /*dark3 H th*/ +0x4f23, /*dark3 L th*/ +0x5080, /*dark3 gain ratio*/ +0x511d, /*dark3 H lum */ +0x521f, /*dark3 M lum */ +0x531f, /*dark3 L lum */ + +0x5a3f, /*blue sky mode out1/2 enable 0x27->3f */ +0x5b00, /*Impulse pixel enable dark123,in,out123 :: must be 0x07*/ +0x5c9f, /*Indoor maxfilter rate[7:5] | Uncertain onoff[4:0] 0x1f ->0x9f*/ + +0x603f, /*GbGr all enable*/ +0x620f, /*GbGr offset*/ + +0x650c, /*Outdoor GbGr rate H 100% M 25% L 100%*/ +0x660c, /*Indoor GbGr rate H 100% M 25% L 100%*/ +0x6700, /*dark GbGr rate H/M/L 100%*/ + +0x700c, /* Abberation On/Off B[1]: Outdoor B[0]: Indoor 07>>c*/ +0x75a0, /* Outdoor2 Abberation Luminance lvl */ +0x7db4, /* Indoor Abberation Luminance lvl*/ + +0x9608, /*indoor/Dark1 edgeoffset1*/ +0x9714, /*indoor/Dark1 center G value*/ +0x98f5, /*slope indoor :: left/right graph polarity, slope*/ +0x992a, /*indoor uncertain ratio control*/ +0x9a20, /*Edgeoffset_dark*/ + +/*DPC_CTRL*/ +0x0312, /*Preview DPC off[0x5c] on[0x5d]*/ +0x200f, +0x210f, + +0x2500, /* 0x30*/ + +0x2a01, +0x2e00, /*2010.8.25*/ + +0x3035, /*Texture region(most detail)*/ +0x31a0, /*STD uniform1 most blur region*/ +0x32b0, /*STD uniform2 2nd blur*/ +0x33c0, /*STD uniform3 3rd blur*/ +0x34d0, /*STD normal noise1 4th blur */ +0x35e0, /*STD normal noise2 5th blur*/ +0x36ff, /*STD normal noise3 6th blur*/ + +0x4083, /*Outdoor2 H th*/ +0x4120, /*Outdoor2 L th */ +0x4208, /*Outdoor2 H luminance */ +0x4310, /*Outdoor2 M luminance */ +0x4410, /*Outdoor2 l luminance */ +0x4550, /*Outdoor2 ratio*/ + +0x4683, /*Outdoor1 H th*/ +0x4720, /*Outdoor1 L th */ +0x4808, /*Outdoor1 H luminance*/ +0x4910, /*Outdoor1 M luminance*/ +0x4a10, /*Outdoor1 L luminance*/ +0x4b50, /*Outdoor1 ratio*/ + +0x4c80, /*Indoor H th*/ +0x4d48, /*Indoor L th*/ +0x4e30, /*indoor H lum*/ +0x4f30, /*indoor M lum*/ +0x5012, /*indoor L lum */ +0x5170, /*indoor ratio 0x10 -> 0x45*/ + +0x52a8, /*dark1 H th*/ +0x5330, /*dark1 L th */ +0x5428, /*dark1 H lum */ +0x553e, /*dark1 M lum*/ +0x5667, /*dark1 L lum*/ +0x576a, /*dark1 ratio*/ + +0x58a0, /*dark2 H th*/ +0x5940, /*dark2 L th*/ +0x5a28, /*dark2 H lum*/ +0x5b3f, /*dark2 M lum*/ +0x5c68, /*dark2 L lum*/ +0x5d70, /*dark2 ratio*/ + +0x5ea0, /*dark3 H th*/ +0x5f1c, /*dark3 L th*/ +0x6029, /*dark3 H lum*/ +0x614a, /*dark3 M lum*/ +0x62ff, /*dark3 L lum*/ +0x63ff, /*dark3 ratio*/ + +/*C-filter(Out2&Out1)*/ +0x7010, +0x710a, + +/*C-filter(Indoor&Dark3)*/ +0x7210, +0x730a, + +/*C-filter(Dark2&Dark1)*/ +0x7418, +0x7512, + +0x8020, +0x8140, +0x8265, +0x851a, +0x8800, +0x8900, +0x905d, /*Preview DPC off[0x5c] on[0x5d]*/ + +/*DPC-Dark1,2,3*/ +0xad07, /*10825*/ +0xae07, /*10825*/ +0xaf07, /*10825*/ + +/*Blue Det..*/ +0xc558, /*BlueRange 2010.8.25 0x40->23 */ +0xc620, /*GreenRange 2010.8.25 0x3b->20 */ + +0xd088, /*2010.8.25*/ +0xd180, +0xd217,/*preview 17, full 67*/ +0xd300, +0xd400, +0xd50f,/*preview 0f, full 02*/ +0xd6ff, +0xd7ff,/*preview ff, full 18*/ +0xd800, +0xd904, + +/*interpolated with average*/ +0xdb38, /*resolution issue 0x00->0x18->0x38 */ +0xd904, /*strong_edge detect ratio*/ +0xe001, /*strong_edge detect ratio*/ + +0x0313, /*page 13 sharpness 1D*/ +0x10c5, +0x117b, +0x120e, +0x1400, + +0x1511, /*added option 1.3M*/ +0x1830, /*added option 1.3M*/ + +0x2015, +0x2113, +0x2233, +0x2308, /*hi_clip th1*/ +0x241a, /*hi_clip th2*/ +0x2506, /*low clip th*/ + +0x2618, +0x2730, +0x2910, /*time th*/ +0x2a30, /*pga th*/ + +0x2b03, /*lpf out2*/ +0x2c03, /*lpf out1*/ +0x2d0c, +0x2e12, +0x2f12, + +/*1D Edge*/ +0x500a, /*out2 hi nega*/ +0x5307, /* hi pos*/ +0x510c, /* mi nega*/ +0x5407, /* mi pos*/ +0x520b, /* lo nega*/ +0x5508, /* lo pos*/ + +0x560a, /*out1 hi nega*/ +0x5907, /* hi pos */ +0x570c, /* mi nega*/ +0x5a07, /* mi pos */ +0x580b, /* lo nega*/ +0x5b08, /* lo pos */ + +/*Indoor Edge*/ +0x5c08, /*indoor hi nega*/ +0x5f07, /* hi pos*/ +0x5d14, +0x6012, +0x5e0a, +0x6108, /* low pos*/ + +0x6208, /*dark1 hi nega*/ +0x6506, /* hi pos */ +0x6308, /* mid nega */ +0x6606, /* mid pos */ +0x6408, /* low nega */ +0x6706, /* low pos */ + +0x6807, /*dark2 hi nega*/ +0x6b05, /* hi pos */ +0x6907, /* mid nega */ +0x6c05, /* mid pos */ +0x6a07, /* low nega */ +0x6d05, /* low pos */ + +0x6e0a, /*dark3 hi nega*/ +0x7109, /* hi pos */ +0x6f0d, /* mid nega */ +0x720c, /* mid pos */ +0x700d, /* low nega */ +0x730c, /* low pos */ + + /* 2DY*/ +0x80c1, +0x811f, +0x82e1, +0x8333, + +0x9005, +0x9105, +0x9233, +0x9330, +0x9403, +0x9514, +0x9730, +0x9930, + +0xa002, /*2d lclp out2 nega*/ +0xa103, /*2d lclp out2 pos*/ +0xa202, /*2d lclp out1 nega*/ +0xa303, /*2d lclp out1 pos*/ +0xa403, /*2d lclp in nega*/ +0xa504, /*2d lclp in pos*/ +0xa607, /*2d lclp dark1 nega*/ +0xa708, /*2d lclp dark1 pos*/ +0xa807, /*2d lclp dark2 nega*/ +0xa908, /*2d lclp dark2 pos*/ +0xaa07, /*2d lclp dark3 nega*/ +0xab08, /*2d lclp dark3 pos*/ + +0xb010, /*out2 H Ne*/ +0xb310, /* H Po*/ +0xb11e, /* M Ne*/ +0xb41e, /* M Po*/ +0xb21f, /* L Ne*/ +0xb51e, /* L Po*/ + +0xb610, /*out1 H Ne */ +0xb910, /* H Po */ +0xb71e, /* M Ne */ +0xba1e, /* M Po */ +0xb81f, /* L Ne */ +0xbb1e, /* L Po */ + +0xbc20, /*indoor H Ne*/ +0xbf1e, /* H Po*/ +0xbd25, /* M Ne*/ +0xc023, /* M Po*/ +0xbe24, /* L Ne*/ +0xc122, /* L Po*/ + +0xc223, /*dark1 H Ne*/ +0xc523, /* H Po*/ +0xc329, /* M Ne*/ +0xc629, /* M Po*/ +0xc425, /* L Ne*/ +0xc725, /* L Po*/ + +0xc81c, /*dark2 H Ne*/ +0xcb1c, /* H Po*/ +0xc925, /* M Ne*/ +0xcc25, /* M Po*/ +0xca23, /* L Ne*/ +0xcd23, /* L Po*/ + +0xce1c, /*dark3 H Ne*/ +0xd11c, /* H Po*/ +0xcf29, /* M Ne*/ +0xd229, /* M Po*/ +0xd027, /* L Ne*/ +0xd327, /* L Po*/ + +/* PAGE 14 START*/ +0x0314, +0x1031, + +0x1480, /* GX*/ +0x1580, /* GY*/ +0x1680, /* RX*/ +0x1780, /* RY*/ +0x1880, /* BX*/ +0x1980, /* BY*/ + +0x2060, /* X Center*/ +0x2180, /* Y Center*/ + +0x2280, +0x2380, +0x2480, + +0x30c8, +0x312b, +0x3200, +0x3300, +0x3490, + +0x4056, /*R min's set 4e*/ +0x413a, /*Gr*/ +0x4237, /*B*/ +0x433a, /*Gb*/ + +0x0315, +0x1021, +0x1444, /*49*/ +0x1534, /*38*/ +0x1626, /*2b*/ +0x172f, + +0x30dd, +0x3162, +0x3205, +0x3326, +0x34bd, +0x3517, +0x3618, +0x3738, +0x38d0, + +0x40b0, +0x4130, +0x4200, +0x4300, +0x4400, +0x4500, +0x4699, +0x4719, +0x4800, + +0x5016, +0x51b2, +0x521c, +0x5306, +0x5420, +0x55a6, +0x560e, +0x57b2, +0x5824, + +0x0316, +0x1031, /*GMA_CTL*/ +0x187e, /*AG_ON*/ +0x197d, /*AG_OFF*/ +0x1a0e, /*TIME_ON*/ +0x1b01, /*TIME_OFF*/ +0x1Cdc, /*OUT_ON*/ +0x1Dfe, /*OUT_OFF*/ + +/*GMA Indoor*/ +0x3000, +0x3126, +0x3238, +0x3355, +0x347e, +0x3597, +0x36a9, +0x37ba, +0x38c7, +0x39d2, +0x3adb, +0x3be3, +0x3cea, +0x3dee, +0x3ef5, +0x3ff9, +0x40fc, +0x41fe, +0x42ff, + +/*RGMA Outdoor*/ +0x5000, +0x5126, +0x5238, +0x5355, +0x547e, +0x5597, +0x56a9, +0x57ba, +0x58c7, +0x59d2, +0x5adb, +0x5be3, +0x5cea, +0x5dee, +0x5ef5, +0x5ff9, +0x60fc, +0x61fe, +0x62ff, + +/*BGMA Dark*/ +0x7002, +0x712a, +0x723b, +0x7359, +0x7481, +0x759b, +0x76ac, +0x77be, +0x78ca, +0x79d4, +0x7adb, +0x7be4, +0x7ceb, +0x7def, +0x7ef6, +0x7ffa, +0x80fc, +0x81fe, +0x82ff, + +0x0324, /*Resol control */ +0x60c5, /*edge even frame | 16bit resol | white edge cnt | scene resol enable*/ +0x6104, /*even frame update */ +0x6408, +0x6500, +0x6626, /*edge th2 H */ +0x6700, /*edge th2 L */ + +0x0313, +0x1831, /*flat center Gb/Gr*/ +0x7402, /*det slope en | gausian filter*/ +0x750d, /*1D negative gain det 09 */ +0x760d, /*1D postive gain det 08*/ +0x7710, /*1D hclp2 det*/ +0x7808, /*outdoor flat threshold*/ +0x7910, /*indoor flat threshold*/ + +0x81df, /*det gain controler*/ +0x8690, /*2D negative gain det */ +0x8790, /*2D postive gain det */ +0x962a, /*2D hclp2 det*/ + +0x0312, /*0x12 page*/ +0xd088, +0xd9e4, + +/* PAGE 18 START*/ +0x0318, +0x1400, + +/* PAGE 20 START*/ +0x0320, +0x111c, +0x1830, +0x1a08, +0x2045,/*weight*/ +0x2130, +0x2210, +0x2300, +0x2400, + +0x28e7, /* add 20120223*/ +0x290d, /* 20100305 ad -> 0d*/ +0x2afd, +0x2bf8, + +0x2cc3, +0x2d5f, /* add 20120223*/ +0x2e33, +0x30f8, +0x3203, +0x332e, +0x3430, +0x35d4, +0x36ff, /*fe*/ +0x3732, +0x3804, +0x3922, +0x3ade, +0x3b22, +0x3cde, +0x3de1, + +0x5045, +0x5188, + +0x561a, +0x5780, +0x580e, +0x596a, +0x5a04, + +0x5e9d, /*AE_AWB_start*/ +0x5f76, /*AE_AWB_start*/ + +0x703f, /* 6c*/ +0x7180, /* 82(+8)*/ + +0x7621, +0x7781, +0x7822, /* 24*/ +0x7925, /* Y Target 70 => 25, 72 => 26*/ +0x7a23, /* 23*/ +0x7b22, /* 22*/ +0x7d23, + +0x8301, /*EXP Normal 30.00 fps */ +0x845f, +0x8590, +0x8601, /*EXPMin 7500.00 fps*/ +0x8790, +0x8805, /*EXP Max(120Hz) 8.00 fps */ +0x89b8, +0x8ad8, +0xa505, /*EXP Max(100Hz) 8.33 fps */ +0xa67e, +0xa740, +0x8B75, /*EXP100 */ +0x8C30, +0x8D61, /*EXP120 */ +0x8Ea8, +0x9c09, /*EXP Limit 1250.00 fps */ +0x9d60, +0x9e01, /*EXP Unit */ +0x9f90, +0x989d, + +0xb016, +0xb114, +0xb2f0, +0xb314, +0xb41b, +0xb546, +0xb631, +0xb729, +0xb826, +0xb924, +0xba22, +0xbb42, +0xbc41, +0xbd40, + +0xc010, +0xc138, +0xc238, +0xc338, +0xc407, + +0xc880, +0xc980, +0x109c, /* ae enable*/ +/* PAGE 20 END*/ + +/*AE_Weight*/ +0x0321, +0x2011, +0x2111, +0x2211, +0x2311, +0x2422, +0x2522, +0x2622, +0x2721, +0x2823, +0x2933, +0x2a32, +0x2b21, +0x2c23, +0x2d44, +0x2e32, +0x2f21, +0x3023, +0x3144, +0x3232, +0x3311, +0x3423, +0x3533, +0x3632, +0x3721, +0x3822, +0x3922, +0x3a22, +0x3b21, +0x3c11, +0x3d11, +0x3e11, +0x3f11, + +/* PAGE 22 START*/ +0x0322, +0x10fd, +0x112e, +0x1901, /* Low On*/ +0x2030, /* for wb speed*/ +0x2140, +0x2401, +0x257e, /* for tracking 20120314 */ + +0x3080, /* 20120224 test*/ +0x3180, +0x3811, +0x3934, + +0x40e8, +0x4143, /* 33*/ +0x4222, /* 22*/ + +0x43f3, /* f6*/ +0x4454, /* 44*/ +0x4522, /* 33*/ + +0x4600, +0x480a, +0x50b2, +0x5181, +0x5298, + +0x8038, +0x8120, +0x8238, /* 3a*/ + +0x8356, /* R Max*/ +0x8420, /* R Min*/ +0x8552, /* B Max*/ +0x8620, /* B Min*/ + +0x8746, +0x8836, +0x8939, +0x8a2d, + +0x8b3c, +0x8c36, +0x8d34, +0x8e31, + +0x8f5a, +0x9059, +0x9154, +0x924d, +0x9342, +0x943a, +0x9534, +0x962c, +0x9723, +0x9820, +0x991f, +0x9a1f, + +0x9b77, +0x9c77, +0x9d48, +0x9e38, +0x9f30, + +0xa040, +0xa122, +0xa26f, +0xa3ff, + +0xa414, /* 1500fps*/ +0xa544, /* 700fps*/ +0xa6cf, + +0xad40, +0xae4a, + +0xaf2a, /* low temp Rgain*/ +0xb028, /* low temp Rgain*/ + +0xb100, /* 0x20 -> 0x00 0405 modify*/ +0xb4bf, /* for tracking 20120314*/ +0xb8a1, /* a2: b-2, R+2 b4 B-3, R+4 lowtemp b0 a1 Spec AWB A modify*/ +0xb900, +/* PAGE 22 END*/ + +/* PAGE 48 (MiPi 1600x1200)*/ +0x0300, + +/* PLL Setting */ +0xd005, +0xd130, +0xd205, +0xd320, +0xd085, +0xd085, +0xd085, +0xd095, + +0x0348, +/* MIPI TX Setting */ +0x101c, +0x1100, +0x1200, +0x1400, +0x1604, +0x1700, +0x1880, +0x1900, +0x1aa0, +/*0x1b0d,*/ +0x1c02, +0x1d0e, +0x1e07, +0x1f08, + +0x2200, +0x2301, +0x241e, +0x2500, +0x2600, +0x2708, +0x2800, +/*0x2b40,*/ + +0x3005, +0x3100, + +0x3207, +0x3309, +0x3401, +0x3501, + +0x0300, +0x0101, +}; + +static const sr130pc20_regset_t sr130pc20_stop_stream[] = { +0x0300, +0x0101, +}; + +static const sr130pc20_regset_t SR130PC20_Preview_Mode[] = +{ +0x0300, +0x0101,/*sleep*/ + +0xd005,/*Pll Off*/ + +0x0320, +0x101c,/*AE off (0x0c:60Hz 0x1c:50Hz)*/ +0x0322, +0x107d,/*AWB off*/ + +0x0300, +0x1011, +/* 0x1190, *//*0x91 : mirror mode*/ + +/* page 11 yc_lpf */ +0x0311, +0x5b00,/*don't touch*/ + +/* PAGE 12 YC_LPF */ +0x0312, +0x200f, +0x210f, + +/*preview DPC*/ +0xd217, +0xd50f, +0xd7ff, + + +/* PAGE13 Sharpness 1D/2D */ +0x0313, +0x10c4, +0x80c0, + +/* PAGE 18 START*/ +0x0318, +0x1443, /*83*/ + +0x0320, +0x109c, /*AE ON (0x8c:60Hz 0x9c:50Hz)*/ +0x0322, +0x10fd, /*AWB ON*/ + +0x0300, /*Page 0 PLL on*/ +0xd005, +0xd130, +0xd205, +0xd320, +0xd085, +0xd085, +0xd085, +0xd095, + +/* MIPI TX Setting */ +0x0348, +0x101c, +0x1100, +0x1200, +0x1400, +0x1604, +0x1700, +0x1880, +0x1900, +0x1aa0, +/*0x1b0d,*/ +0x1c02, +/*0x1d09,*/ +0x1d0e, +0x1e07, +0x1f08, +/*0x2000,*/ + +0x2200, +0x2301, +0x241e, +0x2500, +0x2600, +0x2708, +0x2800, +/*0x2a06,*/ +/*0x2b40,*/ +/*0x2c04,*/ +/*0x2db0,*/ + +0x3005, +0x3100, + +0x3207, +0x3309, +0x3401, +0x3501, +/*0x3601,*/ +/*0x3707,*/ +/*0x3802,*/ +/*0x3902,*/ + +0x0300, +0x0100, + +}; + +static const sr130pc20_regset_t SR130PC20_Capture_Mode[] = +{ +0x0300, +0x0101,/*sleep*/ + +0xd005,/*Pll off*/ + +0x0322, +0x107d,/*AWB off*/ + +0x0300, +0x1000, +/* 0x1190, */ + +0x0302, +0x2faa, + +0x0311, +0x5b00,/*don't touch*/ + +0x0312, +0x200f, +0x210f, + +/*preview DPC*/ +0xd267, +0xd502, +0xd718, + +0x0313, +0x10c5, +0x80c1,/*Sharpness 2D On[0xc1] Off[0xc0]*/ + +/* PAGE 18 START*/ +0x0318, +0x1400, + +0x0300, +0xd005,/*pll on*/ +0xd130, +0xd201, +0xd320, +0xd085, +0xd085, +0xd085, +0xd095, + +0x0348, +/* MIPI TX Setting */ +0x101c, +0x1100, +0x1200, +0x1400, +0x1604, +0x1700, +0x1880, +0x1900, +0x1aa0, +/*0x1b0d,*/ +0x1c02, +0x1d0d, /* 0c:90ns , 0b:110ns */ +0x1e0f, +0x1f0a, +/*0x2000,*/ + +0x2200, +0x2301, +0x241e, +0x2500, +0x2600, +0x2708, +0x2800, +/*0x2a06,*/ +/*0x2b40,*/ +/*0x2c04,*/ +/*0x2db0,*/ + +0x300a, +0x3100, + +0x320d, +0x330b, +0x3402, +0x3504, +0x3601, +0x3709, +/*0x3802,*/ +/*0x3902,*/ + +0x0300, +0x0100,/*sleep off*/ + +}; + +static const sr130pc20_regset_t SR130PC20_Lowlux_Night_Capture_Mode[] = +{ +0x0300, +0x0101,/*sleep*/ + +0xd005,/*Pll off*/ + +0x0322, +0x107d,/*AWB off*/ + +0x0300, +0x1000, +/* 0x1190, */ + +0x0302, +0x2faa, + +0x0311, +0x5b00,/*don't touch*/ + +0x0312, +0x200f, +0x210f, + +/*preview DPC*/ +0xd267, +0xd502, +0xd718, + +0x0313, +0x10c5, +0x80c1,/*Sharpness 2D On[0xc1] Off[0xc0]*/ + +/* PAGE 18 START*/ +0x0318, +0x1400, + +0x0300, +0xd005,/*pll on*/ +0xd130, +0xd201, +0xd320, +0xd085, +0xd085, +0xd085, +0xd095, + +0x0348, +/* MIPI TX Setting */ +0x101c, +0x1100, +0x1200, +0x1400, +0x1604, +0x1700, +0x1880, +0x1900, +0x1aa0, +/*0x1b0d,*/ +0x1c02, +0x1d0d, /* 0c:90ns , 0b:110ns */ +0x1e0f, +0x1f0a, +/*0x2000,*/ + +0x2200, +0x2301, +0x241e, +0x2500, +0x2600, +0x2708, +0x2800, +/*0x2a06,*/ +/*0x2b40,*/ +/*0x2c04,*/ +/*0x2db0,*/ + +0x300a, +0x3100, + +0x320d, +0x330b, +0x3402, +0x3504, +0x3601, +0x3709, +/*0x3802,*/ +/*0x3902,*/ + +0x0300, +0x0100,/*sleep off*/ + +0xff03, +}; + +static const sr130pc20_regset_t sr130pc20_Effect_Sketch[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Effect_Pastel[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Effect_Black_White[] = +{ +0x0310, +0x1103, +0x1233, +0x1302, +0x4080, +0x4480, +0x4580, +}; + +static const sr130pc20_regset_t SR130PC20_Effect_Negative[] = +{ +0x0310, +0x1103, +0x1238, +0x1302, +0x4080, +0x4480, +0x4580, +}; + +static const sr130pc20_regset_t sr130pc20_Effect_Solar[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Effect_Normal[] = +{ +0x0310, +0x1103, +0x1230, +0x1302, +0x4080, +0x4480, +0x4580, +}; + +static const sr130pc20_regset_t sr130pc20_Effect_Sepia[] = +{ +0x0310, +0x1103, +0x1233, +0x1302, +0x4080, +0x4470, +0x4598, +}; + +static const sr130pc20_regset_t sr130pc20_Metering_Center[] = +{ +0x0321, +0x2011, +0x2111, +0x2211, +0x2311, +0x2412, +0x2522, +0x2622, +0x2721, +0x2812, +0x2922, +0x2a22, +0x2b21, +0x2c12, +0x2d23, +0x2e32, +0x2f21, +0x3012, +0x3123, +0x3232, +0x3321, +0x3412, +0x3522, +0x3622, +0x3721, +0x3812, +0x3922, +0x3a22, +0x3b21, +0x3c11, +0x3d11, +0x3e11, +0x3f11, +}; + +static const sr130pc20_regset_t sr130pc20_Metering_Matrix[] = +{ +0x0321, +0x2011, +0x2111, +0x2211, +0x2311, +0x2411, +0x2511, +0x2611, +0x2711, +0x2811, +0x2911, +0x2a11, +0x2b11, +0x2c11, +0x2d11, +0x2e11, +0x2f11, +0x3011, +0x3111, +0x3211, +0x3311, +0x3411, +0x3511, +0x3611, +0x3711, +0x3811, +0x3911, +0x3a11, +0x3b11, +0x3c11, +0x3d11, +0x3e11, +0x3f11, +}; + +static const sr130pc20_regset_t sr130pc20_Metering_Spot[] = +{ +0x0321, +0x2011, +0x2111, +0x2211, +0x2311, +0x2411, +0x2511, +0x2611, +0x2711, +0x2811, +0x2911, +0x2a11, +0x2b11, +0x2c11, +0x2d13, +0x2e31, +0x2f11, +0x3011, +0x3113, +0x3231, +0x3311, +0x3411, +0x3511, +0x3611, +0x3711, +0x3811, +0x3911, +0x3a11, +0x3b11, +0x3c11, +0x3d11, +0x3e11, +0x3f11, +}; + +static const sr130pc20_regset_t SR130PC20_ExpSetting_Default[] = +{ +0x0310, +0x4080, +}; + +static const sr130pc20_regset_t SR130PC20_ExpSetting_M1Step[] = +{ +0x0310, +0x4090, +}; + +static const sr130pc20_regset_t SR130PC20_ExpSetting_M2Step[] = +{ +0x0310, +0x40A0, +}; + +static const sr130pc20_regset_t SR130PC20_ExpSetting_M3Step[] = +{ +0x0310, +0x40B0, +}; + +static const sr130pc20_regset_t SR130PC20_ExpSetting_M4Step[] = +{ +0x0310, +0x40d0, +}; + +static const sr130pc20_regset_t SR130PC20_ExpSetting_P1Step[] = +{ +0x0310, +0x4010, +}; + +static const sr130pc20_regset_t SR130PC20_ExpSetting_P2Step[] = +{ +0x0310, +0x4020, +}; + +static const sr130pc20_regset_t SR130PC20_ExpSetting_P3Step[] = +{ +0x0310, +0x4030, +}; + +static const sr130pc20_regset_t SR130PC20_ExpSetting_P4Step[] = +{ +0x0310, +0x4050, +}; + +static const sr130pc20_regset_t sr130pc20_ISO_50[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_ISO_100[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_ISO_200[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_ISO_400[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_ISO_Auto[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Default[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Landscape[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Sports[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Party_Indoor[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Beach_Snow[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Sunset[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Duskdawn[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Candle_Light[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Fall_Color[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Portrait[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Nightshot[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Fireworks[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Text[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Scene_Backlight[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_Sharpness_Default[] = +{ +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_WB_Auto[] = +{ +0x0322, +0x106b, +0x112e, +0x8038, +0x8120, +0x8238, +0x8356, +0x8420, +0x8552, +0x8620, +0x10eb, +}; + +static const sr130pc20_regset_t sr130pc20_WB_Cloudy[] = +{ +0x0322, +0x106b, +0x112c, +0x8050, +0x8120, +0x8228, +0x8352, +0x844c, +0x852c, +0x8622, +0x10eb, +}; + +static const sr130pc20_regset_t sr130pc20_WB_Sunny[] = +{ +0x0322, +0x106b, +0x112c, +0x8038, +0x8120, +0x8235, +0x833b, +0x8434, +0x8538, +0x8631, +0x10eb, +}; + +static const sr130pc20_regset_t sr130pc20_WB_Fluorescent[] = +{ +0x0322, +0x106b, +0x112c, +0x8037, +0x8120, +0x8248, +0x8339, +0x8434, +0x854a, +0x8645, +0x10eb, +}; + +static const sr130pc20_regset_t sr130pc20_WB_Tungsten[] = +{ +0x0322, +0x106b, +0x112c, +0x8021, +0x8120, +0x824f, +0x8327, +0x841b, +0x8559, +0x8650, +0x10eb, +}; + +static const sr130pc20_regset_t sr130pc20_640_480_Preview[] = { +0x0300, +0x0101, + +0x0300, +0x1011, + +0x0318, +0x1000, + +0x0348, +0x3005, +0x3100, + +0x0300, +0x0100, + +0xff0a, +}; + +static const sr130pc20_regset_t sr130pc20_352_288_Preview[] = { +0x0300, +0x0101, +0x0300, +0x1011, + +0x0318, +0x1007, +0x1200, +0x2003, +0x2100, +0x2201, +0x2320, +0x2400, +0x2520, +0x2600, +0x2700, +0x2802, +0x29e0, +0x2a01, +0x2b20, +0x2c0d, +0x2d55, +0x2e0d, +0x2f55, +0x3051, + +0x0348, +0x3002, +0x31c0, + +0x0300, +0x0100, + +0xff28, +}; + +static const sr130pc20_regset_t sr130pc20_320_240_Preview[] = { +0x0300, +0x0101, + +0x0300, +0x1023, + +0x0318, +0x1000, + +0x0348, +0x3002, +0x3180, + +0x0300, +0x0100, + +0xff28, +}; + +static const sr130pc20_regset_t sr130pc20_176_144_Preview[] = { +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_1280_960_Capture[] = { +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_960_720_Capture[] = { +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_VGA_Capture[] = { +0xff00 +}; + +static const sr130pc20_regset_t sr130pc20_fps_auto[] = { +0xff00, +}; + +static const sr130pc20_regset_t sr130pc20_fps_7fix[] = { +0x0300, +0x0101, + +0x1190, + +0x4200, +0x4314, + +0x0320, +0x101C, + +0x0322, +0x107d, + +0x0320, +0x2af3, +0x2bf5, + +0x8301, /*EXP Normal 33.33 fps */ +0x845f, +0x8590, + +0x8806, /*EXP Max(120Hz) 7.50 fps */ +0x8968, +0x8aa0, + +0xa506, /*EXP Max(100Hz) 7.14 fps */ +0xa668, +0xa7a0, + +0x9106, /*EXP Fix 7.00 fps*/ +0x9289, +0x9370, + +0x0320, +0x109C, + +0x0322, +0x10fd, + +0x0300, +0x1194, + +0x0300, +0x0101, +}; + +static const sr130pc20_regset_t sr130pc20_fps_15fix[] = { +0x0300, +0x0101, + +0x1190, + +0x4200, +0x4314, + +0x0320, +0x101C, + +0x0322, +0x107d, + +0x0310, /*page 10*/ +0x6007, +0x6380, /*auto decresment on AG th*/ + +0x0316, +0x7007, +0x711a, +0x722d, +0x7346, +0x746a, +0x7586, +0x769c, +0x77ad, +0x78bc, +0x79c9, +0x7ad4, +0x7bde, +0x7ce4, +0x7deb, +0x7ef1, +0x7ff5, +0x80f9, +0x81fd, +0x82ff, + +0x0322, +0x8f5d, +0x905a, +0x9156, +0x9250, +0x9348, +0x943f, + +0x0320, +0x2afd, +0x2bf8, + +0x8301, /*EXP Normal 33.33 fps */ +0x845f, +0x8590, + +0x8802, /*EXP Max(120Hz) 17.14 fps */ +0x89bf, +0x8a20, + +0xa502, /*EXP Max(100Hz) 16.67 fps */ +0xa6bf, +0xa720, + +0x9103, /*EXP Fix 15.00 fps*/ +0x920d, +0x9340, + +0x0320, +0x109C, + +0x0322, +0x10fd, + +0x0300, +0x1194, + +0x0300, +0x0101, +}; + +static const sr130pc20_regset_t sr130pc20_fps_25fix[] = { +0x0300, +0x0101, + +0x1190, + +0x4200, +0x4362, + +0x0320, +0x101C, + +0x0322, +0x107d, + +0x0310, /*page 10*/ + +0x410a, +0x6007, +0x6380, /*auto decresment on AG th*/ + +0x0316, +0x7007, +0x711a, +0x722d, +0x7346, +0x746a, +0x7586, +0x769c, +0x77ad, +0x78bc, +0x79c9, +0x7ad4, +0x7bde, +0x7ce4, +0x7deb, +0x7ef1, +0x7ff5, +0x80f9, +0x81fd, +0x82ff, + +0x0322, +0x8f5d, +0x905a, +0x9156, +0x9250, +0x9348, +0x943f, + +0x0320, +0x2afd, +0x2bf8, + +0x8301, /*EXP Normal 33.33 fps */ +0x845d, +0x8538, + +0x8801, /*EXP Max(120Hz) 40.00 fps */ +0x895f, +0x8a90, + +0xa501, /*EXP Max(100Hz) 25.xx fps */ +0xa6d1, +0xa7a0, + +0x8b74, /*EXP100 */ +0x8c68, +0x8d60, /*EXP120 */ +0x8ee0, + +0x9101, /*EXP Fix 25.00 fps*/ +0x92d4, +0x93c0, + +0x0320, +0x109C, + +0x0322, +0x10fd, + +0x0300, +0x1194, + +0x0300, +0x0101, +}; + +static const sr130pc20_regset_t sr130pc20_fps_30fix[] = +{ +/* sensor limitation, use 25fps */ +0xff00, +}; + +#endif /* __SR130PC20_REGS_H__ */ -- cgit v1.1 From d90b43b963027b4d1559cec14e97117827a6458d Mon Sep 17 00:00:00 2001 From: Dorian Snyder Date: Sun, 15 Jun 2014 01:24:33 -0700 Subject: mali: add r3p1 for devices that need it d710 needs to use old mali drivers due to new ones causing signal to be completely killed Change-Id: I450c356b50e3f3521a63717a1c241e3b818b936f --- drivers/media/video/samsung/Kconfig | 2 + drivers/media/video/samsung/Makefile | 2 + drivers/media/video/samsung/mali/Kbuild_module | 295 ++++ drivers/media/video/samsung/mali/Kconfig | 63 + drivers/media/video/samsung/mali/Kconfig_module | 20 + drivers/media/video/samsung/mali/Makefile | 337 ++++ drivers/media/video/samsung/mali/Makefile_module | 97 ++ drivers/media/video/samsung/mali/arch | 1 + drivers/media/video/samsung/mali/arch-debug | 1 + .../video/samsung/mali/arch-orion-m400/config.h | 154 ++ .../samsung/mali/arch-pb-virtex5-m300/config.h | 85 + .../mali/arch-pb-virtex5-m400-1-direct/config.h | 92 + .../mali/arch-pb-virtex5-m400-1-pmu/config.h | 85 + .../samsung/mali/arch-pb-virtex5-m400-1/config.h | 77 + .../samsung/mali/arch-pb-virtex5-m400-2/config.h | 91 + .../samsung/mali/arch-pb-virtex5-m400-3/config.h | 105 ++ .../samsung/mali/arch-pb-virtex5-m400-4/config.h | 119 ++ .../video/samsung/mali/arch-pegasus-m400/config.h | 154 ++ drivers/media/video/samsung/mali/arch-release | 1 + .../samsung/mali/arch-ve-virtex6-m450-8/config.h | 174 ++ .../samsung/mali/common/mali_block_allocator.c | 391 +++++ .../samsung/mali/common/mali_block_allocator.h | 18 + .../media/video/samsung/mali/common/mali_cluster.c | 218 +++ .../media/video/samsung/mali/common/mali_cluster.h | 44 + .../samsung/mali/common/mali_device_pause_resume.c | 46 + .../samsung/mali/common/mali_device_pause_resume.h | 31 + .../media/video/samsung/mali/common/mali_dlbu.c | 285 ++++ .../media/video/samsung/mali/common/mali_dlbu.h | 45 + drivers/media/video/samsung/mali/common/mali_gp.c | 746 ++++++++ drivers/media/video/samsung/mali/common/mali_gp.h | 46 + .../media/video/samsung/mali/common/mali_gp_job.c | 49 + .../media/video/samsung/mali/common/mali_gp_job.h | 131 ++ .../video/samsung/mali/common/mali_gp_scheduler.c | 443 +++++ .../video/samsung/mali/common/mali_gp_scheduler.h | 30 + .../media/video/samsung/mali/common/mali_group.c | 841 +++++++++ .../media/video/samsung/mali/common/mali_group.h | 146 ++ .../media/video/samsung/mali/common/mali_hw_core.c | 46 + .../media/video/samsung/mali/common/mali_hw_core.h | 71 + .../video/samsung/mali/common/mali_kernel_common.h | 183 ++ .../video/samsung/mali/common/mali_kernel_core.c | 980 +++++++++++ .../video/samsung/mali/common/mali_kernel_core.h | 39 + .../mali/common/mali_kernel_descriptor_mapping.c | 184 ++ .../mali/common/mali_kernel_descriptor_mapping.h | 101 ++ .../video/samsung/mali/common/mali_kernel_mem_os.c | 354 ++++ .../video/samsung/mali/common/mali_kernel_mem_os.h | 37 + .../mali/common/mali_kernel_memory_engine.c | 376 ++++ .../mali/common/mali_kernel_memory_engine.h | 152 ++ .../samsung/mali/common/mali_kernel_utilization.c | 218 +++ .../samsung/mali/common/mali_kernel_utilization.h | 44 + .../video/samsung/mali/common/mali_kernel_vsync.c | 51 + .../video/samsung/mali/common/mali_l2_cache.c | 414 +++++ .../video/samsung/mali/common/mali_l2_cache.h | 43 + .../samsung/mali/common/mali_mem_validation.c | 71 + .../samsung/mali/common/mali_mem_validation.h | 19 + .../media/video/samsung/mali/common/mali_memory.c | 1319 ++++++++++++++ .../media/video/samsung/mali/common/mali_memory.h | 82 + drivers/media/video/samsung/mali/common/mali_mmu.c | 619 +++++++ drivers/media/video/samsung/mali/common/mali_mmu.h | 55 + .../samsung/mali/common/mali_mmu_page_directory.c | 475 ++++++ .../samsung/mali/common/mali_mmu_page_directory.h | 100 ++ drivers/media/video/samsung/mali/common/mali_osk.h | 1798 ++++++++++++++++++++ .../video/samsung/mali/common/mali_osk_bitops.h | 166 ++ .../video/samsung/mali/common/mali_osk_list.h | 184 ++ .../video/samsung/mali/common/mali_osk_mali.h | 222 +++ .../video/samsung/mali/common/mali_osk_profiling.h | 147 ++ drivers/media/video/samsung/mali/common/mali_pm.c | 552 ++++++ drivers/media/video/samsung/mali/common/mali_pm.h | 56 + drivers/media/video/samsung/mali/common/mali_pmu.c | 199 +++ drivers/media/video/samsung/mali/common/mali_pmu.h | 70 + drivers/media/video/samsung/mali/common/mali_pp.c | 710 ++++++++ drivers/media/video/samsung/mali/common/mali_pp.h | 47 + .../media/video/samsung/mali/common/mali_pp_job.c | 95 ++ .../media/video/samsung/mali/common/mali_pp_job.h | 273 +++ .../video/samsung/mali/common/mali_pp_scheduler.c | 594 +++++++ .../video/samsung/mali/common/mali_pp_scheduler.h | 38 + .../video/samsung/mali/common/mali_scheduler.c | 37 + .../video/samsung/mali/common/mali_scheduler.h | 21 + .../media/video/samsung/mali/common/mali_session.c | 47 + .../media/video/samsung/mali/common/mali_session.h | 65 + drivers/media/video/samsung/mali/common/mali_ukk.h | 612 +++++++ .../samsung/mali/common/mali_user_settings_db.c | 88 + .../samsung/mali/common/mali_user_settings_db.h | 40 + .../samsung/mali/include/linux/mali/mali_utgard.h | 28 + .../mali/include/linux/mali/mali_utgard_counters.h | 264 +++ .../mali/include/linux/mali/mali_utgard_ioctl.h | 86 + .../linux/mali/mali_utgard_profiling_events.h | 127 ++ .../mali/include/linux/mali/mali_utgard_uk_types.h | 1095 ++++++++++++ .../mali/linux/license/gpl/mali_kernel_license.h | 31 + .../media/video/samsung/mali/linux/mali_dma_buf.c | 392 +++++ .../media/video/samsung/mali/linux/mali_dma_buf.h | 29 + .../video/samsung/mali/linux/mali_kernel_linux.c | 634 +++++++ .../video/samsung/mali/linux/mali_kernel_linux.h | 43 + .../video/samsung/mali/linux/mali_kernel_pm.c | 268 +++ .../video/samsung/mali/linux/mali_kernel_pm.h | 17 + .../video/samsung/mali/linux/mali_kernel_sysfs.c | 1280 ++++++++++++++ .../video/samsung/mali/linux/mali_kernel_sysfs.h | 35 + .../media/video/samsung/mali/linux/mali_linux_pm.h | 50 + .../samsung/mali/linux/mali_linux_pm_testsuite.h | 32 + .../video/samsung/mali/linux/mali_linux_trace.h | 126 ++ .../video/samsung/mali/linux/mali_osk_atomics.c | 55 + .../media/video/samsung/mali/linux/mali_osk_irq.c | 266 +++ .../video/samsung/mali/linux/mali_osk_locks.c | 340 ++++ .../samsung/mali/linux/mali_osk_low_level_mem.c | 660 +++++++ .../media/video/samsung/mali/linux/mali_osk_mali.c | 34 + .../media/video/samsung/mali/linux/mali_osk_math.c | 22 + .../video/samsung/mali/linux/mali_osk_memory.c | 61 + .../media/video/samsung/mali/linux/mali_osk_misc.c | 64 + .../samsung/mali/linux/mali_osk_notification.c | 189 ++ .../media/video/samsung/mali/linux/mali_osk_pm.c | 83 + .../samsung/mali/linux/mali_osk_profiling_gator.c | 261 +++ .../mali/linux/mali_osk_profiling_internal.c | 324 ++++ .../video/samsung/mali/linux/mali_osk_specific.h | 130 ++ .../media/video/samsung/mali/linux/mali_osk_time.c | 51 + .../video/samsung/mali/linux/mali_osk_timers.c | 65 + .../video/samsung/mali/linux/mali_osk_wait_queue.c | 73 + .../samsung/mali/linux/mali_pmu_power_up_down.c | 65 + .../samsung/mali/linux/mali_profiling_events.h | 17 + .../media/video/samsung/mali/linux/mali_uk_types.h | 18 + .../media/video/samsung/mali/linux/mali_ukk_core.c | 104 ++ .../media/video/samsung/mali/linux/mali_ukk_gp.c | 113 ++ .../media/video/samsung/mali/linux/mali_ukk_mem.c | 259 +++ .../media/video/samsung/mali/linux/mali_ukk_pp.c | 88 + .../video/samsung/mali/linux/mali_ukk_profiling.c | 183 ++ .../video/samsung/mali/linux/mali_ukk_vsync.c | 41 + .../video/samsung/mali/linux/mali_ukk_wrappers.h | 68 + .../samsung/mali/platform/default/mali_platform.c | 43 + .../video/samsung/mali/platform/mali_platform.h | 153 ++ .../mali_platform_pmu_testing/mali_platform.c | 66 + .../mali/platform/orion-m400/mali_platform.c | 656 +++++++ .../mali/platform/orion-m400/mali_platform_dvfs.c | 448 +++++ .../mali/platform/pegasus-m400/mali_platform.c | 801 +++++++++ .../platform/pegasus-m400/mali_platform_dvfs.c | 847 +++++++++ .../media/video/samsung/mali/regs/mali_200_regs.h | 172 ++ .../media/video/samsung/mali/regs/mali_gp_regs.h | 214 +++ .../mali/timestamp-arm11-cc/mali_timestamp.c | 13 + .../mali/timestamp-arm11-cc/mali_timestamp.h | 48 + .../mali/timestamp-default/mali_timestamp.c | 13 + .../mali/timestamp-default/mali_timestamp.h | 26 + drivers/media/video/samsung/ump/Kconfig | 58 + drivers/media/video/samsung/ump/Kconfig_module | 16 + drivers/media/video/samsung/ump/Makefile | 93 + drivers/media/video/samsung/ump/Makefile.common | 20 + drivers/media/video/samsung/ump/arch | 1 + drivers/media/video/samsung/ump/arch-debug | 1 + .../video/samsung/ump/arch-orion-m400/config.h | 22 + .../video/samsung/ump/arch-pb-virtex5/config.h | 18 + .../video/samsung/ump/arch-pegasus-m400/config.h | 22 + drivers/media/video/samsung/ump/arch-release | 1 + .../video/samsung/ump/common/ump_kernel_api.c | 551 ++++++ .../video/samsung/ump/common/ump_kernel_common.c | 414 +++++ .../video/samsung/ump/common/ump_kernel_common.h | 128 ++ .../ump/common/ump_kernel_descriptor_mapping.c | 165 ++ .../ump/common/ump_kernel_descriptor_mapping.h | 91 + .../samsung/ump/common/ump_kernel_memory_backend.h | 51 + .../video/samsung/ump/common/ump_kernel_ref_drv.c | 260 +++ .../video/samsung/ump/common/ump_kernel_types.h | 53 + drivers/media/video/samsung/ump/common/ump_osk.h | 51 + .../media/video/samsung/ump/common/ump_uk_types.h | 208 +++ drivers/media/video/samsung/ump/common/ump_ukk.h | 61 + .../samsung/ump/include/ump_kernel_interface.h | 236 +++ .../ump/include/ump_kernel_interface_ref_drv.h | 35 + .../samsung/ump/include/ump_kernel_platform.h | 48 + .../ump/linux/license/gpl/ump_kernel_license.h | 31 + drivers/media/video/samsung/ump/linux/ump_ioctl.h | 61 + .../video/samsung/ump/linux/ump_kernel_linux.c | 492 ++++++ .../video/samsung/ump/linux/ump_kernel_linux.h | 18 + .../linux/ump_kernel_memory_backend_dedicated.c | 287 ++++ .../linux/ump_kernel_memory_backend_dedicated.h | 23 + .../ump/linux/ump_kernel_memory_backend_os.c | 260 +++ .../ump/linux/ump_kernel_memory_backend_os.h | 23 + .../ump/linux/ump_kernel_memory_backend_vcm.c | 290 ++++ .../ump/linux/ump_kernel_memory_backend_vcm.h | 22 + .../video/samsung/ump/linux/ump_memory_backend.c | 77 + .../video/samsung/ump/linux/ump_osk_atomics.c | 27 + .../samsung/ump/linux/ump_osk_low_level_mem.c | 485 ++++++ .../media/video/samsung/ump/linux/ump_osk_misc.c | 37 + .../video/samsung/ump/linux/ump_ukk_ref_wrappers.c | 320 ++++ .../video/samsung/ump/linux/ump_ukk_ref_wrappers.h | 43 + .../video/samsung/ump/linux/ump_ukk_wrappers.c | 306 ++++ .../video/samsung/ump/linux/ump_ukk_wrappers.h | 47 + 180 files changed, 34683 insertions(+) create mode 100644 drivers/media/video/samsung/mali/Kbuild_module create mode 100644 drivers/media/video/samsung/mali/Kconfig create mode 100644 drivers/media/video/samsung/mali/Kconfig_module create mode 100644 drivers/media/video/samsung/mali/Makefile create mode 100644 drivers/media/video/samsung/mali/Makefile_module create mode 120000 drivers/media/video/samsung/mali/arch create mode 120000 drivers/media/video/samsung/mali/arch-debug create mode 100644 drivers/media/video/samsung/mali/arch-orion-m400/config.h create mode 100644 drivers/media/video/samsung/mali/arch-pb-virtex5-m300/config.h create mode 100644 drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-direct/config.h create mode 100644 drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-pmu/config.h create mode 100644 drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1/config.h create mode 100644 drivers/media/video/samsung/mali/arch-pb-virtex5-m400-2/config.h create mode 100644 drivers/media/video/samsung/mali/arch-pb-virtex5-m400-3/config.h create mode 100644 drivers/media/video/samsung/mali/arch-pb-virtex5-m400-4/config.h create mode 100644 drivers/media/video/samsung/mali/arch-pegasus-m400/config.h create mode 120000 drivers/media/video/samsung/mali/arch-release create mode 100644 drivers/media/video/samsung/mali/arch-ve-virtex6-m450-8/config.h create mode 100644 drivers/media/video/samsung/mali/common/mali_block_allocator.c create mode 100644 drivers/media/video/samsung/mali/common/mali_block_allocator.h create mode 100644 drivers/media/video/samsung/mali/common/mali_cluster.c create mode 100644 drivers/media/video/samsung/mali/common/mali_cluster.h create mode 100644 drivers/media/video/samsung/mali/common/mali_device_pause_resume.c create mode 100644 drivers/media/video/samsung/mali/common/mali_device_pause_resume.h create mode 100644 drivers/media/video/samsung/mali/common/mali_dlbu.c create mode 100644 drivers/media/video/samsung/mali/common/mali_dlbu.h create mode 100644 drivers/media/video/samsung/mali/common/mali_gp.c create mode 100644 drivers/media/video/samsung/mali/common/mali_gp.h create mode 100644 drivers/media/video/samsung/mali/common/mali_gp_job.c create mode 100644 drivers/media/video/samsung/mali/common/mali_gp_job.h create mode 100644 drivers/media/video/samsung/mali/common/mali_gp_scheduler.c create mode 100644 drivers/media/video/samsung/mali/common/mali_gp_scheduler.h create mode 100644 drivers/media/video/samsung/mali/common/mali_group.c create mode 100644 drivers/media/video/samsung/mali/common/mali_group.h create mode 100644 drivers/media/video/samsung/mali/common/mali_hw_core.c create mode 100644 drivers/media/video/samsung/mali/common/mali_hw_core.h create mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_common.h create mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_core.c create mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_core.h create mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.c create mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.h create mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c create mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_mem_os.h create mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.c create mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.h create mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_utilization.c create mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_utilization.h create mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_vsync.c create mode 100644 drivers/media/video/samsung/mali/common/mali_l2_cache.c create mode 100644 drivers/media/video/samsung/mali/common/mali_l2_cache.h create mode 100644 drivers/media/video/samsung/mali/common/mali_mem_validation.c create mode 100644 drivers/media/video/samsung/mali/common/mali_mem_validation.h create mode 100644 drivers/media/video/samsung/mali/common/mali_memory.c create mode 100644 drivers/media/video/samsung/mali/common/mali_memory.h create mode 100644 drivers/media/video/samsung/mali/common/mali_mmu.c create mode 100644 drivers/media/video/samsung/mali/common/mali_mmu.h create mode 100644 drivers/media/video/samsung/mali/common/mali_mmu_page_directory.c create mode 100644 drivers/media/video/samsung/mali/common/mali_mmu_page_directory.h create mode 100644 drivers/media/video/samsung/mali/common/mali_osk.h create mode 100644 drivers/media/video/samsung/mali/common/mali_osk_bitops.h create mode 100644 drivers/media/video/samsung/mali/common/mali_osk_list.h create mode 100644 drivers/media/video/samsung/mali/common/mali_osk_mali.h create mode 100644 drivers/media/video/samsung/mali/common/mali_osk_profiling.h create mode 100644 drivers/media/video/samsung/mali/common/mali_pm.c create mode 100644 drivers/media/video/samsung/mali/common/mali_pm.h create mode 100644 drivers/media/video/samsung/mali/common/mali_pmu.c create mode 100644 drivers/media/video/samsung/mali/common/mali_pmu.h create mode 100644 drivers/media/video/samsung/mali/common/mali_pp.c create mode 100644 drivers/media/video/samsung/mali/common/mali_pp.h create mode 100644 drivers/media/video/samsung/mali/common/mali_pp_job.c create mode 100644 drivers/media/video/samsung/mali/common/mali_pp_job.h create mode 100644 drivers/media/video/samsung/mali/common/mali_pp_scheduler.c create mode 100644 drivers/media/video/samsung/mali/common/mali_pp_scheduler.h create mode 100644 drivers/media/video/samsung/mali/common/mali_scheduler.c create mode 100644 drivers/media/video/samsung/mali/common/mali_scheduler.h create mode 100644 drivers/media/video/samsung/mali/common/mali_session.c create mode 100644 drivers/media/video/samsung/mali/common/mali_session.h create mode 100644 drivers/media/video/samsung/mali/common/mali_ukk.h create mode 100644 drivers/media/video/samsung/mali/common/mali_user_settings_db.c create mode 100644 drivers/media/video/samsung/mali/common/mali_user_settings_db.h create mode 100644 drivers/media/video/samsung/mali/include/linux/mali/mali_utgard.h create mode 100644 drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_counters.h create mode 100644 drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_ioctl.h create mode 100644 drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_profiling_events.h create mode 100644 drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_uk_types.h create mode 100644 drivers/media/video/samsung/mali/linux/license/gpl/mali_kernel_license.h create mode 100644 drivers/media/video/samsung/mali/linux/mali_dma_buf.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_dma_buf.h create mode 100644 drivers/media/video/samsung/mali/linux/mali_kernel_linux.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_kernel_linux.h create mode 100644 drivers/media/video/samsung/mali/linux/mali_kernel_pm.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_kernel_pm.h create mode 100644 drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.h create mode 100644 drivers/media/video/samsung/mali/linux/mali_linux_pm.h create mode 100644 drivers/media/video/samsung/mali/linux/mali_linux_pm_testsuite.h create mode 100644 drivers/media/video/samsung/mali/linux/mali_linux_trace.h create mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_atomics.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_irq.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_locks.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_low_level_mem.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_mali.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_math.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_memory.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_misc.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_notification.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_pm.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_profiling_gator.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_profiling_internal.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_specific.h create mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_time.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_timers.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_wait_queue.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_pmu_power_up_down.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_profiling_events.h create mode 100644 drivers/media/video/samsung/mali/linux/mali_uk_types.h create mode 100644 drivers/media/video/samsung/mali/linux/mali_ukk_core.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_ukk_gp.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_ukk_mem.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_ukk_pp.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_ukk_profiling.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_ukk_vsync.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_ukk_wrappers.h create mode 100644 drivers/media/video/samsung/mali/platform/default/mali_platform.c create mode 100644 drivers/media/video/samsung/mali/platform/mali_platform.h create mode 100644 drivers/media/video/samsung/mali/platform/mali_platform_pmu_testing/mali_platform.c create mode 100644 drivers/media/video/samsung/mali/platform/orion-m400/mali_platform.c create mode 100644 drivers/media/video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c create mode 100644 drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c create mode 100644 drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c create mode 100644 drivers/media/video/samsung/mali/regs/mali_200_regs.h create mode 100644 drivers/media/video/samsung/mali/regs/mali_gp_regs.h create mode 100644 drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.c create mode 100644 drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.h create mode 100644 drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.c create mode 100644 drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.h create mode 100644 drivers/media/video/samsung/ump/Kconfig create mode 100644 drivers/media/video/samsung/ump/Kconfig_module create mode 100644 drivers/media/video/samsung/ump/Makefile create mode 100644 drivers/media/video/samsung/ump/Makefile.common create mode 120000 drivers/media/video/samsung/ump/arch create mode 120000 drivers/media/video/samsung/ump/arch-debug create mode 100644 drivers/media/video/samsung/ump/arch-orion-m400/config.h create mode 100644 drivers/media/video/samsung/ump/arch-pb-virtex5/config.h create mode 100644 drivers/media/video/samsung/ump/arch-pegasus-m400/config.h create mode 120000 drivers/media/video/samsung/ump/arch-release create mode 100644 drivers/media/video/samsung/ump/common/ump_kernel_api.c create mode 100644 drivers/media/video/samsung/ump/common/ump_kernel_common.c create mode 100644 drivers/media/video/samsung/ump/common/ump_kernel_common.h create mode 100644 drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.c create mode 100644 drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.h create mode 100644 drivers/media/video/samsung/ump/common/ump_kernel_memory_backend.h create mode 100644 drivers/media/video/samsung/ump/common/ump_kernel_ref_drv.c create mode 100644 drivers/media/video/samsung/ump/common/ump_kernel_types.h create mode 100644 drivers/media/video/samsung/ump/common/ump_osk.h create mode 100644 drivers/media/video/samsung/ump/common/ump_uk_types.h create mode 100644 drivers/media/video/samsung/ump/common/ump_ukk.h create mode 100644 drivers/media/video/samsung/ump/include/ump_kernel_interface.h create mode 100644 drivers/media/video/samsung/ump/include/ump_kernel_interface_ref_drv.h create mode 100644 drivers/media/video/samsung/ump/include/ump_kernel_platform.h create mode 100644 drivers/media/video/samsung/ump/linux/license/gpl/ump_kernel_license.h create mode 100644 drivers/media/video/samsung/ump/linux/ump_ioctl.h create mode 100644 drivers/media/video/samsung/ump/linux/ump_kernel_linux.c create mode 100644 drivers/media/video/samsung/ump/linux/ump_kernel_linux.h create mode 100644 drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c create mode 100644 drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.h create mode 100644 drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c create mode 100644 drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.h create mode 100644 drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.c create mode 100644 drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.h create mode 100644 drivers/media/video/samsung/ump/linux/ump_memory_backend.c create mode 100644 drivers/media/video/samsung/ump/linux/ump_osk_atomics.c create mode 100644 drivers/media/video/samsung/ump/linux/ump_osk_low_level_mem.c create mode 100644 drivers/media/video/samsung/ump/linux/ump_osk_misc.c create mode 100644 drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.c create mode 100644 drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.h create mode 100644 drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.c create mode 100644 drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.h (limited to 'drivers/media/video') diff --git a/drivers/media/video/samsung/Kconfig b/drivers/media/video/samsung/Kconfig index 4824144..01232a0 100644 --- a/drivers/media/video/samsung/Kconfig +++ b/drivers/media/video/samsung/Kconfig @@ -17,6 +17,8 @@ if CPU_EXYNOS4210 || CPU_EXYNOS4212 || CPU_EXYNOS4412 source "drivers/media/video/samsung/fimc/Kconfig" source "drivers/media/video/samsung/tvout/Kconfig" source "drivers/media/video/samsung/mfc5x/Kconfig" + source "drivers/media/video/samsung/mali/Kconfig" + source "drivers/media/video/samsung/ump/Kconfig" endif config VIDEO_FIMG2D diff --git a/drivers/media/video/samsung/Makefile b/drivers/media/video/samsung/Makefile index 5a46253..e9905d2 100644 --- a/drivers/media/video/samsung/Makefile +++ b/drivers/media/video/samsung/Makefile @@ -12,6 +12,8 @@ obj-$(CONFIG_VIDEO_FIMG2D3X) += fimg2d3x/ obj-$(CONFIG_VIDEO_FIMG2D4X) += fimg2d4x/ endif +obj-$(CONFIG_VIDEO_UMP) += ump/ obj-$(CONFIG_VIDEO_TSI) += tsi/ +obj-$(CONFIG_VIDEO_MALI400MP) += mali/ EXTRA_CFLAGS += -Idrivers/media/video diff --git a/drivers/media/video/samsung/mali/Kbuild_module b/drivers/media/video/samsung/mali/Kbuild_module new file mode 100644 index 0000000..e865954 --- /dev/null +++ b/drivers/media/video/samsung/mali/Kbuild_module @@ -0,0 +1,295 @@ +# +# Copyright (C) 2010-2011 ARM Limited. All rights reserved. +# +# This program is free software and is provided to you under the terms of the GNU General Public License version 2 +# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. +# +# A copy of the licence is included with the program, and can also be obtained from Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# + +# This file is called by the Linux build system. + +OSKOS=linux + +# set up defaults if not defined by the user +USING_UMP ?= 0 +USING_OS_MEMORY ?= 0 +USING_MALI_PMM_TESTSUITE ?= 0 +OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB ?= 16 +USING_PROFILING ?= 1 +USING_INTERNAL_PROFILING ?= 0 +DISABLE_PP0 ?= 0 +DISABLE_PP1 ?= 0 +DISABLE_PP2 ?= 0 +DISABLE_PP3 ?= 0 +PROFILING_SKIP_PP_JOBS ?= 0 +PROFILING_SKIP_PP_AND_GP_JOBS ?= 0 +PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH ?= 0 +TIMESTAMP ?= default +BUILD ?= debug +TARGET_PLATFORM ?= default +KERNEL_RUNTIME_PM_ENABLED ?= 0 +CONFIG ?= pb-virtex5-m200 +MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP ?= 0 +MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED ?= 0 +MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS ?= 0 + +DEFINES := $(EXTRA_DEFINES) + +# Get path to driver source from Linux build system +DRIVER_DIR=$(src) + +# For customer releases the Linux Device Drivers will be provided as ARM proprietary and GPL releases: +# The ARM proprietary product will only include the license/proprietary directory +# The GPL product will only include the license/gpl directory + +ifeq ($(wildcard $(DRIVER_DIR)/linux/license/gpl/*),) +ccflags-y += -I$(DRIVER_DIR)/linux/license/proprietary +# Disable profiling for proprietary +override USING_PROFILING := 0 +$(warning "USING_PROFILING not supported, disabling.") +else +ccflags-y += -I$(DRIVER_DIR)/linux/license/gpl +endif + + +ifeq ($(USING_PROFILING),1) +ifeq ($(USING_INTERNAL_PROFILING),0) +ifndef CONFIG_TRACEPOINTS +# Should default to gator profiling, but we dont have the kernel feature required, so disable profiling +override USING_PROFILING = 0 +$(warning "CONFIG_TRACEPOINTS required for USING_PROFILING") +endif +endif +endif + +ifeq ($(USING_PROFILING),0) +# make sure user hasnt selected incompatible flags +override USING_INTERNAL_PROFILING = 0 +endif + +MALI_RELEASE_NAME=$(shell cat $(DRIVER_DIR)/.version 2> /dev/null) + +# Check if a Mali Core sub module should be enabled, true or false returned +submodule_enabled = $(shell gcc $(DEFINES) -E $1/arch/config.h | grep type | grep -c $(2)) + +OSKFILES = \ + $(OSKOS)/mali_osk_atomics.c \ + $(OSKOS)/mali_osk_irq.c \ + $(OSKOS)/mali_osk_locks.c \ + $(OSKOS)/mali_osk_wait_queue.c \ + $(OSKOS)/mali_osk_low_level_mem.c \ + $(OSKOS)/mali_osk_math.c \ + $(OSKOS)/mali_osk_memory.c \ + $(OSKOS)/mali_osk_misc.c \ + $(OSKOS)/mali_osk_mali.c \ + $(OSKOS)/mali_osk_notification.c \ + $(OSKOS)/mali_osk_time.c \ + $(OSKOS)/mali_osk_timers.c + +UKKFILES = \ + $(OSKOS)/mali_ukk_mem.c \ + $(OSKOS)/mali_ukk_gp.c \ + $(OSKOS)/mali_ukk_pp.c \ + $(OSKOS)/mali_ukk_core.c + +ifeq ($(USING_PROFILING),1) +UKKFILES += \ + $(OSKOS)/mali_ukk_profiling.c +endif + +ifeq ($(MALI_PLATFORM_FILE),) +MALI_PLATFORM_FILE = platform/default/mali_platform.c +endif + +# Get subversion revision number, fall back to only ${MALI_RELEASE_NAME} if no svn info is available +SVN_REV := $(shell (cd $(DRIVER_DIR); (svnversion | grep -E "^[0-9]+" && svnversion) || git svn info | grep '^Revision: '| sed -e 's/^Revision: //' ) 2>/dev/null ) +ifeq ($(SVN_REV),) +SVN_REV := $(MALI_RELEASE_NAME) +else +SVN_REV := $(MALI_RELEASE_NAME)-r$(SVN_REV) +endif + +# Validate selected config +ifneq ($(shell [ -d $(DRIVER_DIR)/arch-$(CONFIG) ] && [ -f $(DRIVER_DIR)/arch-$(CONFIG)/config.h ] && echo "OK"), OK) +$(warning Current directory is $(shell pwd)) +$(error No configuration found for config $(CONFIG). Check that arch-$(CONFIG)/config.h exists) +else +# Link arch to the selected arch-config directory +$(shell [ -L $(DRIVER_DIR)/arch ] && rm $(DRIVER_DIR)/arch) +$(shell ln -sf arch-$(CONFIG) $(DRIVER_DIR)/arch) +$(shell touch $(DRIVER_DIR)/arch/config.h) +endif + +# Set up our defines, which will be passed to gcc +DEFINES += -DUSING_OS_MEMORY=$(USING_OS_MEMORY) +DEFINES += -DUSING_MMU=1 +DEFINES += -DUSING_UMP=$(USING_UMP) +DEFINES += -D_MALI_OSK_SPECIFIC_INDIRECT_MMAP +DEFINES += -DMALI_INTERNAL_TIMELINE_PROFILING_ENABLED=$(USING_INTERNAL_PROFILING) +DEFINES += -DDISABLE_PP0=$(DISABLE_PP0) +DEFINES += -DDISABLE_PP1=$(DISABLE_PP1) +DEFINES += -DDISABLE_PP2=$(DISABLE_PP2) +DEFINES += -DDISABLE_PP3=$(DISABLE_PP3) +DEFINES += -DPROFILING_SKIP_PP_JOBS=$(PROFILING_SKIP_PP_JOBS) +DEFINES += -DPROFILING_SKIP_PP_AND_GP_JOBS=$(PROFILING_SKIP_PP_AND_GP_JOBS) +DEFINES += -DPROFILING_PRINT_L2_HITRATE_ON_GP_FINISH=$(PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH) + +DEFINES += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP) +DEFINES += -DMALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED=$(MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED) +DEFINES += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS) +DEFINES += -DMALI_TIMELINE_PROFILING_ENABLED=$(USING_PROFILING) +DEFINES += -DMALI_POWER_MGMT_TEST_SUITE=$(USING_MALI_PMM_TESTSUITE) +ifeq ($(shell test $(SUBLEVEL) -gt 32 -a $(PATCHLEVEL) = 6 -a $(VERSION) = 2 -o $(VERSION) -gt 2 && echo "OK"),OK) +# MALI_STATE_TRACKING is only supported on Linux kernels from version 2.6.32. +DEFINES += -DMALI_STATE_TRACKING=1 +else +DEFINES += -DMALI_STATE_TRACKING=0 +endif +DEFINES += -DMALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=$(OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB) + +MALI_PLATFORM_FILE = platform/$(TARGET_PLATFORM)/mali_platform.c + + +ifdef CONFIG_PM +ifdef CONFIG_PM_RUNTIME + KERNEL_RUNTIME_PM_ENABLED = 1 +endif +endif + +DEFINES += -DMALI_PMM_RUNTIME_JOB_CONTROL_ON=$(KERNEL_RUNTIME_PM_ENABLED) + +ifeq ($(BUILD), debug) +DEFINES += -DDEBUG +endif +DEFINES += -DSVN_REV=$(SVN_REV) +DEFINES += -DSVN_REV_STRING=\"$(SVN_REV)\" + +# Linux has its own mmap cleanup handlers (see mali_kernel_memory.c) +DEFINES += -DMALI_UKK_HAS_IMPLICIT_MMAP_CLEANUP + +ifeq ($(USING_UMP),1) + DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER=1 + ccflags-y += -I$(DRIVER_DIR)/../../ump/include/ump +else + DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER=0 +endif + +# Use our defines when compiling +ccflags-y += $(DEFINES) -I$(DRIVER_DIR) -I$(DRIVER_DIR)/include -I$(DRIVER_DIR)/common -I$(DRIVER_DIR)/linux -I$(DRIVER_DIR)/platform + +# Source files which always are included in a build +SRC = \ + common/mali_kernel_core.c \ + linux/mali_kernel_linux.c \ + common/mali_kernel_descriptor_mapping.c \ + common/mali_session.c \ + common/mali_device_pause_resume.c \ + common/mali_kernel_vsync.c \ + linux/mali_ukk_vsync.c \ + linux/mali_kernel_sysfs.c \ + common/mali_mmu.c \ + common/mali_mmu_page_directory.c \ + common/mali_memory.c \ + common/mali_kernel_memory_engine.c \ + common/mali_block_allocator.c \ + common/mali_kernel_mem_os.c \ + common/mali_mem_validation.c \ + common/mali_hw_core.c \ + common/mali_gp.c \ + common/mali_pp.c \ + common/mali_pp_job.c \ + common/mali_gp_job.c \ + common/mali_scheduler.c \ + common/mali_gp_scheduler.c \ + common/mali_pp_scheduler.c \ + common/mali_cluster.c \ + common/mali_group.c \ + common/mali_dlbu.c \ + common/mali_pm.c \ + common/mali_pmu.c \ + common/mali_user_settings_db.c \ + $(OSKOS)/mali_osk_pm.c \ + linux/mali_kernel_pm.c \ + linux/mali_pmu_power_up_down.c \ + $(MALI_PLATFORM_FILE) \ + $(OSKFILES) \ + $(UKKFILES) \ + __malidrv_build_info.c + +# Selecting files to compile by parsing the config file + +ifeq ($(USING_INTERNAL_PROFILING),1) +PROFILING_BACKEND_SOURCES = \ + linux/mali_osk_profiling_internal.c \ + timestamp-$(TIMESTAMP)/mali_timestamp.c +ccflags-y += -I$(DRIVER_DIR)/timestamp-$(TIMESTAMP) +else +ifeq ($(USING_PROFILING),1) +PROFILING_BACKEND_SOURCES = \ + linux/mali_osk_profiling_gator.c +endif +endif + +# Add the profiling sources +SRC += $(PROFILING_BACKEND_SOURCES) + +ifeq ($(USING_MALI_PMM_TESTSUITE),1) +ccflags-y += -I$(DRIVER_DIR)/platform/mali_pmu_testing +endif + +mali-$(CONFIG_MALI400_GPU_UTILIZATION) += common/mali_kernel_utilization.o +mali-$(CONFIG_DMA_SHARED_BUFFER) += linux/mali_dma_buf.o + +ifneq ($(call submodule_enabled, $(DRIVER_DIR), MALI400PP),0) + # Mali-400 PP in use + ccflags-y += -DUSING_MALI400 +endif + +ifneq ($(call submodule_enabled, $(DRIVER_DIR), MALI300PP),0) + # Mali-400 PP in use + ccflags-y += -DUSING_MALI400 +endif + +ifneq ($(call submodule_enabled, $(DRIVER_DIR), MALI200),0) + # Mali200 in use + ccflags-y += -DUSING_MALI200 +endif + +# Always build in support for Mali L2 cache +SRC += common/mali_l2_cache.c + +# Tell the Linux build system to enable building of our .c files +mali-y += $(SRC:.c=.o) +# Tell the Linux build system from which .o file to create the kernel module +obj-$(CONFIG_MALI400) := mali.o + + +VERSION_STRINGS := +VERSION_STRINGS += CONFIG=$(CONFIG) +VERSION_STRINGS += USING_OS_MEMORY=$(USING_OS_MEMORY) +VERSION_STRINGS += API_VERSION=$(shell cd $(DRIVER_DIR); grep "\#define _MALI_API_VERSION" $(FILES_PREFIX)include/linux/mali/mali_utgard_uk_types.h | cut -d' ' -f 3 ) +VERSION_STRINGS += REPO_URL=$(shell cd $(DRIVER_DIR); (svn info || git svn info || echo 'URL: $(MALI_RELEASE_NAME)') 2>/dev/null | grep '^URL: ' | cut -d: -f2- | cut -b2-) +VERSION_STRINGS += REVISION=$(SVN_REV) +VERSION_STRINGS += CHANGED_REVISION=$(shell cd $(DRIVER_DIR); (svn info || git svn info || echo 'Last Changed Rev: $(MALI_RELEASE_NAME)') 2>/dev/null | grep '^Last Changed Rev: ' | cut -d: -f2- | cut -b2-) +VERSION_STRINGS += CHANGE_DATE=$(shell cd $(DRIVER_DIR); (svn info || git svn info || echo 'Last Changed Date: $(MALI_RELEASE_NAME)') 2>/dev/null | grep '^Last Changed Date: ' | cut -d: -f2- | cut -b2-) +VERSION_STRINGS += BUILD_DATE=$(shell date) + +VERSION_STRINGS += BUILD=$(shell echo $(BUILD) | tr a-z A-Z) +VERSION_STRINGS += CPU=$(CPU) +VERSION_STRINGS += USING_UMP=$(USING_UMP) +VERSION_STRINGS += USING_MALI200=$(call submodule_enabled, $(DRIVER_DIR), MALI200) +VERSION_STRINGS += USING_MALI400=$(call submodule_enabled, $(DRIVER_DIR), MALI400) +VERSION_STRINGS += USING_MALI400_L2_CACHE=$(call submodule_enabled, $(DRIVER_DIR), MALI400L2) +VERSION_STRINGS += USING_GP2=$(call submodule_enabled, $(DRIVER_DIR), MALIGP2) +VERSION_STRINGS += KDIR=$(KDIR) +VERSION_STRINGS += MALI_PLATFORM_FILE=$(MALI_PLATFORM_FILE) +VERSION_STRINGS += OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=$(OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB) +VERSION_STRINGS += USING_PROFILING=$(USING_PROFILING) +VERSION_STRINGS += USING_INTERNAL_PROFILING=$(USING_INTERNAL_PROFILING) +VERSION_STRINGS += USING_GPU_UTILIZATION=$(CONFIG_MALI400_GPU_UTILIZATION) + +# Create file with Mali driver configuration +$(DRIVER_DIR)/__malidrv_build_info.c: + @echo 'const char *__malidrv_build_info(void) { return "malidrv: $(VERSION_STRINGS)";}' > $(DRIVER_DIR)/__malidrv_build_info.c diff --git a/drivers/media/video/samsung/mali/Kconfig b/drivers/media/video/samsung/mali/Kconfig new file mode 100644 index 0000000..e53d2b3 --- /dev/null +++ b/drivers/media/video/samsung/mali/Kconfig @@ -0,0 +1,63 @@ +# +## S3C Multimedia Mali configuration +## +# +# For Mali +config VIDEO_MALI400MP + bool "Enable MALI integration" + depends on VIDEO_SAMSUNG + default n + ---help--- + This enables MALI integration in the multimedia device driver + +choice +depends on VIDEO_MALI400MP +prompt "MALI MEMORY OPTION" +default MALI_OSMEM_ONLY +config MALI_DED_ONLY + bool "mali dedicated memory only" + ---help--- + This enables MALI dedicated memory only option +config MALI_DED_MMU + bool "mali dedicated memory with mmu enable" + ---help--- + This enables MALI dedicated memory with mmu enable option +config MALI_OSMEM_ONLY + bool "mali OS memory only" + ---help--- + This enables MALI OS memory only option +config MALI_DED_OSMEM + bool "mali dedicated memory and OS memory" + ---help--- + This enables MALI dedicated memory and OS memory option + +endchoice +config MALI_MEM_SIZE +int "Dedicated Memory Size" + depends on VIDEO_MALI400MP && (MALI_DED_ONLY || MALI_DED_MMU || MALI_DED_OSMEM) + default "128" + ---help--- + This value is dedicated memory size of Mali GPU(unit is MByte). + +config MALI_R3P1_LSI + bool "Uses the R3P1 as a kernel module" + depends on VIDEO_MALI400MP + default n + ---help--- + This uses the r3p1 as a MALI kernel module + + +# For DEBUG +config VIDEO_MALI400MP_DEBUG + bool "Enables debug messages" + depends on VIDEO_MALI400MP + default n + help + This enables Mali driver debug messages. + +config VIDEO_MALI400MP_DVFS + bool "Enables DVFS" + depends on VIDEO_MALI400MP && PM + default y + help + This enables Mali driver DVFS. diff --git a/drivers/media/video/samsung/mali/Kconfig_module b/drivers/media/video/samsung/mali/Kconfig_module new file mode 100644 index 0000000..1fdc638 --- /dev/null +++ b/drivers/media/video/samsung/mali/Kconfig_module @@ -0,0 +1,20 @@ +config MALI400_DEBUG + bool "Enable debug in Mali driver" + depends on MALI400 + ---help--- + This enabled extra debug checks and messages in the Mali-300/400/450 + driver. + +config MALI400_PROFILING + bool "Enable Mali profiling" + depends on MALI400 && TRACEPOINTS + ---help--- + This enables gator profiling of Mali GPU events. + +config MALI400_GPU_UTILIZATION + bool "Enable Mali GPU utilization tracking" + depends on MALI400 + ---help--- + This enables gathering and processing of the utilization of Mali GPU. + This data can be used as a basis to change GPU operating frequency. + diff --git a/drivers/media/video/samsung/mali/Makefile b/drivers/media/video/samsung/mali/Makefile new file mode 100644 index 0000000..3e25b61 --- /dev/null +++ b/drivers/media/video/samsung/mali/Makefile @@ -0,0 +1,337 @@ +# +# Copyright (C) 2010-2012 ARM Limited. All rights reserved. +# +# This program is free software and is provided to you under the terms of the GNU General Public License version 2 +# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. +# +# A copy of the licence is included with the program, and can also be obtained from Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# + +OSKOS :=linux +FILES_PREFIX= +MALI_INCLUDE_PREFIX := drivers/media/video/samsung/mali/ +KBUILDROOT = + +ifeq ($(CONFIG_MALI_DED_ONLY),y) +USING_OS_MEMORY=0 +USING_MMU=0 +USING_DED=1 +endif + +ifeq ($(CONFIG_MALI_DED_MMU),y) +USING_OS_MEMORY=0 +USING_MMU=1 +USING_DED=1 +endif + +ifeq ($(CONFIG_MALI_OSMEM_ONLY),y) +USING_MMU=1 +USING_DED=0 +USING_OS_MEMORY=1 +endif + +ifeq ($(CONFIG_MALI_DED_OSMEM),y) +USING_MMU=1 +USING_DED=1 +USING_OS_MEMORY=1 +endif + +ifeq ($(CONFIG_PM),y) + USING_PMM = 1 +ifeq ($(CONFIG_PM_RUNTIME),y) + KERNEL_RUNTIME_PM_ENABLED = 1 +endif +endif + +ifeq ($(CONFIG_VIDEO_MALI400MP_DVFS),y) +USING_GPU_UTILIZATION=1 +USING_MALI_DVFS_ENABLED=1 +endif + +ifeq ($(CONFIG_VIDEO_UMP_DEBUG),y) +BUILD=debug +endif + +ifeq ($(CONFIG_VIDEO_MALI400MP_STREAMLINE_PROFILING),y) +USING_PROFILING=1 +USING_TRACEPOINTS=1 +endif + +# set up defaults if not defined by the user +USE_UMPV2 ?= 0 +PANIC_ON_WATCHDOG_TIMEOUT ?= 1 +USING_MALI400 ?= 1 +USING_MMU ?= 1 +USING_DED ?= 0 +USING_UMP ?= 0 +ONLY_ZBT ?= 0 +USING_ZBT ?= 0 +USING_OS_MEMORY ?= 1 +USING_PMM ?= 0 +USING_MALI_RUN_TIME_PM ?= 0 +USING_MALI_PMM_TESTSUITE ?= 0 +USING_MALI_PMU ?= 0 +USING_GPU_UTILIZATION ?= 0 +OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB ?= 16 +USING_PROFILING ?= 0 +USING_INTERNAL_PROFILING ?= 0 +USING_TRACEPOINTS ?= 0 +USING_MALI_MAJOR_PREDEFINE = 1 +USING_MALI_DVFS_ENABLED ?= 1 +USING_MALI_PMM_EARLYSUSPEND ?= 0 +#USING_KERNEL_WITH_DMA_ALLOC_PHYS_PAGE ?= 0 +#CONFIG_MALI_MEM_SIZE ?= 512 +DISABLE_PP0 ?= 0 +DISABLE_PP1 ?= 0 +DISABLE_PP2 ?= 0 +DISABLE_PP3 ?= 0 +PROFILING_SKIP_PP_JOBS ?= 0 +PROFILING_SKIP_PP_AND_GP_JOBS ?= 0 +PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH ?= 0 +TIMESTAMP ?= default +BUILD ?= release +TARGET_PLATFORM ?= default +KERNEL_RUNTIME_PM_ENABLED ?= 0 +MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP ?= 0 +MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED ?= 0 +MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS ?= 0 + +# Get path to driver source from Linux build system +ifeq ($(USING_PROFILING),1) +ifeq ($(USING_INTERNAL_PROFILING),0) +ifndef CONFIG_TRACEPOINTS +# Should default to gator profiling, but we dont have the kernel feature required, so disable profiling +override USING_PROFILING = 0 +$(warning "CONFIG_TRACEPOINTS required for USING_PROFILING") +endif +endif +endif + +ifeq ($(USING_PROFILING),0) +# make sure user hasnt selected incompatible flags +override USING_INTERNAL_PROFILING = 0 +endif + +USING_MALI_SLP_GLOBAL_LOCK ?= 0 + +#config validtion check +ifeq ($(USING_OS_MEMORY),1) + USING_MMU = 1 +endif + +# Check if a Mali Core sub module should be enabled, true or false returned +#submodule_enabled = $(shell gcc $(DEFINES) -E $(FILES_PREFIX)/arch/config.h | grep type | grep -c $(2)) + +# Inside the kernel build system + +# This conditional makefile exports the global definition ARM_INTERNAL_BUILD. Customer releases will not include arm_internal.mak +-include ../../../arm_internal.mak + +# Set up our defines, which will be passed to gcc +DEFINES += -DONLY_ZBT=$(ONLY_ZBT) +DEFINES += -DUSING_ZBT=$(USING_ZBT) +DEFINES += -DUSING_MMU=$(USING_MMU) +DEFINES += -DUSING_OS_MEMORY=$(USING_OS_MEMORY) +DEFINES += -DUSING_DED=$(USING_DED) +DEFINES += -DUSING_UMP=$(USING_UMP) +DEFINES += -D_MALI_OSK_SPECIFIC_INDIRECT_MMAP +DEFINES += -DUSING_MALI_PMU=$(USING_MALI_PMU) +DEFINES += -DMALI_PMM_RUNTIME_JOB_CONTROL_ON=$(KERNEL_RUNTIME_PM_ENABLED) +DEFINES += -DUSING_MALI_PMM=$(USING_PMM) +DEFINES += -DMALI_GPU_UTILIZATION=$(USING_GPU_UTILIZATION) +DEFINES += -DCONFIG_MALI_MEM_SIZE=$(CONFIG_MALI_MEM_SIZE) +DEFINES += -D_MALI_OSK_SPECIFIC_INDIRECT_MMAP +DEFINES += -DMALI_INTERNAL_TIMELINE_PROFILING_ENABLED=$(USING_INTERNAL_PROFILING) +DEFINES += -DMALI_MAJOR_PREDEFINE=$(USING_MALI_MAJOR_PREDEFINE) +DEFINES += -DMALI_DVFS_ENABLED=$(USING_MALI_DVFS_ENABLED) +DEFINES += -DUSING_MALI_PMM_EARLYSUSPEND=$(USING_MALI_PMM_EARLYSUSPEND) +DEFINES += -DMALI_STATE_TRACKING=0 +DEFINES += -DMALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=$(OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB) +DEFINES += -DMALI_TRACEPOINTS_ENABLED=$(USING_TRACEPOINTS) +DEFINES += -DDISABLE_PP0=$(DISABLE_PP0) +DEFINES += -DDISABLE_PP1=$(DISABLE_PP1) +DEFINES += -DDISABLE_PP2=$(DISABLE_PP2) +DEFINES += -DDISABLE_PP3=$(DISABLE_PP3) +DEFINES += -DPROFILING_SKIP_PP_JOBS=$(PROFILING_SKIP_PP_JOBS) +DEFINES += -DPROFILING_SKIP_PP_AND_GP_JOBS=$(PROFILING_SKIP_PP_AND_GP_JOBS) +DEFINES += -DPROFILING_PRINT_L2_HITRATE_ON_GP_FINISH=$(PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH) +DEFINES += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP) +DEFINES += -DMALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED=$(MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED) +DEFINES += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS) +DEFINES += -DMALI_TIMELINE_PROFILING_ENABLED=$(USING_PROFILING) +DEFINES += -DMALI_POWER_MGMT_TEST_SUITE=$(USING_MALI_PMM_TESTSUITE) +DEFINES += -DMALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=$(OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB) + +ifeq ($(BUILD),debug) +DEFINES += -DDEBUG +endif + +# Linux has its own mmap cleanup handlers (see mali_kernel_mem_mmu.o) +DEFINES += -DMALI_UKK_HAS_IMPLICIT_MMAP_CLEANUP + +# UMP +ifeq ($(CONFIG_VIDEO_UMP),y) + DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER=1 + EXTRA_CFLAGS += -I$(MALI_INCLUDE_PREFIX)../ump/include +else + DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER=0 +endif + +# Target build file +obj-$(CONFIG_VIDEO_UMP) += mali.o + +# Use our defines when compiling +# MALI +INCLUDES = \ + -I$(MALI_INCLUDE_PREFIX)\ + -I$(MALI_INCLUDE_PREFIX)include \ + -I$(MALI_INCLUDE_PREFIX)common \ + -I$(MALI_INCLUDE_PREFIX)linux \ + -I$(MALI_INCLUDE_PREFIX)platform\ + -I$(MALI_INCLUDE_PREFIX)regs + +EXTRA_CFLAGS += $(INCLUDES)\ + $(DEFINES) + +EXTRA_CFLAGS += -I$(MALI_INCLUDE_PREFIX)linux/license/gpl +EXTRA_CFLAGS += -I$(MALI_INCLUDE_PREFIX)common/pmm + +# Source files which always are included in a build +ifeq ($(CONFIG_VIDEO_UMP),y) +OSKFILES=\ + $(FILES_PREFIX)$(OSKOS)/mali_osk_irq.o \ + $(FILES_PREFIX)$(OSKOS)/mali_osk_wait_queue.o \ + $(FILES_PREFIX)$(OSKOS)/mali_osk_low_level_mem.o \ + $(FILES_PREFIX)$(OSKOS)/mali_osk_mali.o \ + $(FILES_PREFIX)$(OSKOS)/mali_osk_notification.o \ + $(FILES_PREFIX)$(OSKOS)/mali_osk_time.o \ + $(FILES_PREFIX)$(OSKOS)/mali_osk_timers.o +else +OSKFILES=\ + $(FILES_PREFIX)$(OSKOS)/mali_osk_atomics.o \ + $(FILES_PREFIX)$(OSKOS)/mali_osk_irq.o \ + $(FILES_PREFIX)$(OSKOS)/mali_osk_locks.o \ + $(FILES_PREFIX)$(OSKOS)/mali_osk_wait_queue.o \ + $(FILES_PREFIX)$(OSKOS)/mali_osk_low_level_mem.o \ + $(FILES_PREFIX)$(OSKOS)/mali_osk_math.o \ + $(FILES_PREFIX)$(OSKOS)/mali_osk_memory.o \ + $(FILES_PREFIX)$(OSKOS)/mali_osk_misc.o \ + $(FILES_PREFIX)$(OSKOS)/mali_osk_mali.o \ + $(FILES_PREFIX)$(OSKOS)/mali_osk_notification.o \ + $(FILES_PREFIX)$(OSKOS)/mali_osk_time.o \ + $(FILES_PREFIX)$(OSKOS)/mali_osk_timers.o +endif #($(CONFIG_VIDEO_UMP),y) + +ifeq ($(CONFIG_CPU_EXYNOS4210),y) + MALI_PLATFORM_DIR = platform/orion-m400 +else + MALI_PLATFORM_DIR = platform/pegasus-m400 +endif #($(CONFIG_CPU_EXYNOS4210),y) + +MALI_PLATFORM_FILE=$(MALI_PLATFORM_DIR)/mali_platform.o +UKKFILES=\ + $(FILES_PREFIX)$(OSKOS)/mali_ukk_mem.o \ + $(FILES_PREFIX)$(OSKOS)/mali_ukk_gp.o \ + $(FILES_PREFIX)$(OSKOS)/mali_ukk_pp.o \ + $(FILES_PREFIX)$(OSKOS)/mali_ukk_core.o + +ifeq ($(USING_PROFILING),1) +UKKFILES += \ + $(FILES_PREFIX)$(OSKOS)/mali_ukk_profiling.o +endif + +mali-y := \ + common/mali_kernel_core.o \ + linux/mali_kernel_linux.o \ + common/mali_kernel_descriptor_mapping.o \ + common/mali_session.o \ + common/mali_device_pause_resume.o \ + common/mali_kernel_vsync.o \ + linux/mali_ukk_vsync.o \ + linux/mali_kernel_sysfs.o \ + common/mali_mmu.o \ + common/mali_mmu_page_directory.o \ + common/mali_memory.o \ + common/mali_kernel_memory_engine.o \ + common/mali_block_allocator.o \ + common/mali_kernel_mem_os.o \ + common/mali_mem_validation.o \ + common/mali_hw_core.o \ + common/mali_gp.o \ + common/mali_pp.o \ + common/mali_pp_job.o \ + common/mali_gp_job.o \ + common/mali_scheduler.o \ + common/mali_gp_scheduler.o \ + common/mali_pp_scheduler.o \ + common/mali_cluster.o \ + common/mali_group.o \ + common/mali_dlbu.o \ + common/mali_pm.o \ + common/mali_pmu.o \ + common/mali_user_settings_db.o \ + $(OSKOS)/mali_osk_pm.o \ + linux/mali_kernel_pm.o \ + linux/mali_pmu_power_up_down.o \ + $(MALI_PLATFORM_FILE) \ + $(OSKFILES) \ + $(UKKFILES) +# __malidrv_build_info.c + +# Selecting files to compile by parsing the config file + +ifeq ($(USING_INTERNAL_PROFILING),1) +PROFILING_BACKEND_SOURCES = \ + linux/mali_osk_profiling_internal.o \ + timestamp-$(TIMESTAMP)/mali_timestamp.o +EXTRA_CFLAGS += -I$(MALI_INCLUDE_PREFIX)timestamp-$(TIMESTAMP) +else +ifeq ($(USING_PROFILING),1) +PROFILING_BACKEND_SOURCES = \ + linux/mali_osk_profiling_gator.o +endif +endif + +# Add the profiling sources +mali-y += $(PROFILING_BACKEND_SOURCES) + +# Mali-400 PP in use +ifeq ($(USING_MALI_PMM_TESTSUITE),1) +EXTRA_CFLAGS += -I$(MALI_INCLUDE_PREFIX)platform/mali_pmu_testing +endif + +ifeq ($(USING_GPU_UTILIZATION),1) +EXTRA_CFLAGS += -DCONFIG_MALI400_GPU_UTILIZATION=1 + +mali-y += \ + common/mali_kernel_utilization.o +endif + +ifeq ($(USING_MALI_DVFS_ENABLED),1) +mali-y += $(MALI_PLATFORM_DIR)/mali_platform_dvfs.o +endif #($(USING_MALI_DVFS_ENABLED),1) + +EXTRA_CFLAGS += -DUSING_MALI400 + +# Mali Level2 cache in use +EXTRA_CFLAGS += -DUSING_MALI400_L2_CACHE +mali-y += common/mali_l2_cache.o + +# Mali SLP Global lock feature +ifeq ($(USING_MALI_SLP_GLOBAL_LOCK),1) +mali-y += \ + linux/mali_slp_global_lock.o +endif + + +ifeq ($(PANIC_ON_WATCHDOG_TIMEOUT),1) + EXTRA_CFLAGS += -DUSING_KERNEL_PANIC +endif + +# Get subversion revision number, fall back to 0000 if no svn info is available +SVN_REV:=$(shell ((svnversion | grep -E "^[0-9]+" && echo -n 'Revision: ' && svnversion) || git svn info | sed -e 's/$$$$/M/' | grep '^Revision: ' || echo ${MALI_RELEASE_NAME}) 2>/dev/null | sed -e 's/^Revision: //') + +EXTRA_CFLAGS += -DSVN_REV=$(SVN_REV) +EXTRA_CFLAGS += -DSVN_REV_STRING=\"$(SVN_REV)\" + diff --git a/drivers/media/video/samsung/mali/Makefile_module b/drivers/media/video/samsung/mali/Makefile_module new file mode 100644 index 0000000..361ce08 --- /dev/null +++ b/drivers/media/video/samsung/mali/Makefile_module @@ -0,0 +1,97 @@ +# +# Copyright (C) 2010-2012 ARM Limited. All rights reserved. +# +# This program is free software and is provided to you under the terms of the GNU General Public License version 2 +# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. +# +# A copy of the licence is included with the program, and can also be obtained from Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# + +USE_UMPV2=0 + +# The Makefile sets up "arch" based on the CONFIG, creates the version info +# string and the __malidrv_build_info.c file, and then call the Linux build +# system to actually build the driver. After that point the Kbuild file takes +# over. + +# set up defaults if not defined by the user +ARCH ?= arm + +OSKOS=linux +FILES_PREFIX= + +check_cc2 = \ + $(shell if $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; \ + then \ + echo "$(2)"; \ + else \ + echo "$(3)"; \ + fi ;) + +# This conditional makefile exports the global definition ARM_INTERNAL_BUILD. Customer releases will not include arm_internal.mak +-include ../../../arm_internal.mak + +# Check that required parameters are supplied. +ifeq ($(CONFIG),) +$(error "CONFIG must be specified.") +endif +ifeq ($(CPU)$(KDIR),) +$(error "KDIR or CPU must be specified.") +endif + +ifeq ($(USING_UMP),1) +ifeq ($(USE_UMPV2),1) +UMP_SYMVERS_FILE ?= ../umpv2/Module.symvers +else +UMP_SYMVERS_FILE ?= ../ump/Module.symvers +endif +KBUILD_EXTRA_SYMBOLS = $(realpath $(UMP_SYMVERS_FILE)) +$(warning $(KBUILD_EXTRA_SYMBOLS)) +endif + +# Get any user defined KDIR- or maybe even a hardcoded KDIR +-include KDIR_CONFIGURATION + +# Define host system directory +KDIR-$(shell uname -m):=/lib/modules/$(shell uname -r)/build + +ifeq ($(ARCH), arm) +# when compiling for ARM we're cross compiling +export CROSS_COMPILE ?= $(call check_cc2, arm-linux-gnueabi-gcc, arm-linux-gnueabi-, arm-none-linux-gnueabi-) +endif + +# look up KDIR based om CPU selection +KDIR ?= $(KDIR-$(CPU)) + +# validate lookup result +ifeq ($(KDIR),) +$(error No KDIR found for platform $(CPU)) +endif + +# report detected/selected settings +ifdef ARM_INTERNAL_BUILD +$(warning Config $(CONFIG)) +$(warning Host CPU $(CPU)) +$(warning OS_MEMORY $(USING_OS_MEMORY)) +endif + +# Set up build config +export CONFIG_MALI400=m + +ifeq ($(USING_GPU_UTILIZATION),1) +export EXTRA_DEFINES += -DCONFIG_MALI400_GPU_UTILIZATION=1 +export CONFIG_MALI400_GPU_UTILIZATION := y +endif + +all: $(UMP_SYMVERS_FILE) + $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) modules + @rm $(FILES_PREFIX)__malidrv_build_info.c $(FILES_PREFIX)__malidrv_build_info.o + +clean: + $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) clean + +kernelrelease: + $(MAKE) ARCH=$(ARCH) -C $(KDIR) kernelrelease + +export CONFIG KBUILD_EXTRA_SYMBOLS diff --git a/drivers/media/video/samsung/mali/arch b/drivers/media/video/samsung/mali/arch new file mode 120000 index 0000000..58ffbe7 --- /dev/null +++ b/drivers/media/video/samsung/mali/arch @@ -0,0 +1 @@ +arch-release \ No newline at end of file diff --git a/drivers/media/video/samsung/mali/arch-debug b/drivers/media/video/samsung/mali/arch-debug new file mode 120000 index 0000000..0ed0909 --- /dev/null +++ b/drivers/media/video/samsung/mali/arch-debug @@ -0,0 +1 @@ +arch-pegasus-m400/ \ No newline at end of file diff --git a/drivers/media/video/samsung/mali/arch-orion-m400/config.h b/drivers/media/video/samsung/mali/arch-orion-m400/config.h new file mode 100644 index 0000000..73502a2 --- /dev/null +++ b/drivers/media/video/samsung/mali/arch-orion-m400/config.h @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __ARCH_CONFIG_H__ +#define __ARCH_CONFIG_H__ + +/* Configuration for the EB platform with ZBT memory enabled */ +/*zepplin added 2010.08.17 for orion configuration*/ +#define MALI_BASE_ADDR 0x13000000 +#define GP_ADDR MALI_BASE_ADDR +#define L2_ADDR MALI_BASE_ADDR+0x1000 +#define PMU_ADDR MALI_BASE_ADDR+0x2000 +#define GP_MMU_ADDR MALI_BASE_ADDR+0x3000 +#define PP0_MMU_ADDR MALI_BASE_ADDR+0x4000 +#define PP1_MMU_ADDR MALI_BASE_ADDR+0x5000 +#define PP2_MMU_ADDR MALI_BASE_ADDR+0x6000 +#define PP3_MMU_ADDR MALI_BASE_ADDR+0x7000 +#define PP0_ADDR MALI_BASE_ADDR+0x8000 +#define PP1_ADDR MALI_BASE_ADDR+0xA000 +#define PP2_ADDR MALI_BASE_ADDR+0xC000 +#define PP3_ADDR MALI_BASE_ADDR+0xE000 + +/*for mmu and os memory*/ +#define MEM_BASE_ADDR 0x40000000 +#define MEM_TOTAL_SIZE 0x40000000 +#define MEM_MALI_OS_SIZE 0x40000000 + +/*for dedicated memory*/ +//#define MEM_MALI_BASE 0x58000000 +//#define MEM_MALI_SIZE 0x08000000 +#define MEM_MALI_SIZE CONFIG_MALI_MEM_SIZE*1024*1024 +#define MEM_MALI_BASE 0x80000000 - MEM_MALI_SIZE + +static _mali_osk_resource_t arch_configuration [] = +{ + { + .type = MALI400GP, + .description = "Mali-400 GP", + .base = GP_ADDR, + .irq = IRQ_GP_3D, + .mmu_id = 1 + }, + { + .type = MALI400PP, + .base = PP0_ADDR, + .irq = IRQ_PP0_3D, + .description = "Mali-400 PP 0", + .mmu_id = 2 + }, + { + .type = MALI400PP, + .base = PP1_ADDR, + .irq = IRQ_PP1_3D, + .description = "Mali-400 PP 1", + .mmu_id = 3 + }, + { + .type = MALI400PP, + .base = PP2_ADDR, + .irq = IRQ_PP2_3D, + .description = "Mali-400 PP 2", + .mmu_id = 4 + }, + { + .type = MALI400PP, + .base = PP3_ADDR, + .irq = IRQ_PP3_3D, + .description = "Mali-400 PP 3", + .mmu_id = 5 + }, +#if USING_MMU + { + .type = MMU, + .base = GP_MMU_ADDR, + .irq = IRQ_GPMMU_3D, + .description = "Mali-400 MMU for GP", + .mmu_id = 1 + }, + { + .type = MMU, + .base = PP0_MMU_ADDR, + .irq = IRQ_PPMMU0_3D, + .description = "Mali-400 MMU for PP 0", + .mmu_id = 2 + }, + { + .type = MMU, + .base = PP1_MMU_ADDR, + .irq = IRQ_PPMMU1_3D, + .description = "Mali-400 MMU for PP 1", + .mmu_id = 3 + }, + { + .type = MMU, + .base = PP2_MMU_ADDR, + .irq = IRQ_PPMMU2_3D, + .description = "Mali-400 MMU for PP 2", + .mmu_id = 4 + }, + { + .type = MMU, + .base = PP3_MMU_ADDR, + .irq = IRQ_PPMMU3_3D, + .description = "Mali-400 MMU for PP 3", + .mmu_id = 5 + }, +#if USING_OS_MEMORY + { + .type = OS_MEMORY, + .description = "System Memory", + .size = MEM_MALI_OS_SIZE, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE + }, +#endif +#if USING_DED /* Dedicated Memory */ + { + .type = MEMORY, + .description = "Dedicated Memory", + .base = MEM_MALI_BASE, + .size = MEM_MALI_SIZE, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE + }, +#endif/* if USING_OS_MEMORY*/ + { + .type = MEM_VALIDATION, + .description = "Framebuffer Memory", + .base = MEM_BASE_ADDR, + .size = MEM_TOTAL_SIZE, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE + }, +#else /* Not using MMU */ + { + .type = MEMORY, + .description = "Dedicated Memory", + .base = MEM_MALI_BASE, + .size = MEM_MALI_SIZE, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE + }, +#endif + { + .type = MALI400L2, + .base = L2_ADDR, + .description = "Mali-400 L2 cache" + }, +}; + +#endif /* __ARCH_CONFIG_H__ */ diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m300/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m300/config.h new file mode 100644 index 0000000..e579526 --- /dev/null +++ b/drivers/media/video/samsung/mali/arch-pb-virtex5-m300/config.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __ARCH_CONFIG_H__ +#define __ARCH_CONFIG_H__ + +/* Configuration for the PB platform with ZBT memory enabled */ + +static _mali_osk_resource_t arch_configuration [] = +{ + { + .type = PMU, + .description = "Mali-300 PMU", + .base = 0xC0002000, + .irq = -1, + .mmu_id = 0 + + }, + { + .type = MALI300GP, + .description = "Mali-300 GP", + .base = 0xC0000000, + .irq = -1, + .mmu_id = 1 + }, + { + .type = MALI300PP, + .base = 0xc0008000, + .irq = -1, + .description = "Mali-300 PP", + .mmu_id = 2 + }, + { + .type = MMU, + .base = 0xC0003000, + .irq = -1, + .description = "Mali-300 MMU for GP", + .mmu_id = 1 + }, + { + .type = MMU, + .base = 0xC0004000, + .irq = -1, + .description = "Mali-300 MMU for PP", + .mmu_id = 2 + }, + { + .type = MEMORY, + .description = "Mali SDRAM remapped to baseboard", + .cpu_usage_adjust = -0x50000000, + .alloc_order = 0, /* Highest preference for this memory */ + .base = 0xD0000000, + .size = 0x10000000, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE + }, + { + .type = MEMORY, + .description = "Mali ZBT", + .alloc_order = 5, /* Medium preference for this memory */ + .base = 0xe1000000, + .size = 0x01000000, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE + }, + { + .type = MEM_VALIDATION, + .description = "Framebuffer", + .base = 0xe0000000, + .size = 0x01000000, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE + }, + { + .type = MALI300L2, + .base = 0xC0001000, + .description = "Mali-300 L2 cache" + }, +}; + +#endif /* __ARCH_CONFIG_H__ */ diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-direct/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-direct/config.h new file mode 100644 index 0000000..3893d72 --- /dev/null +++ b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-direct/config.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __ARCH_CONFIG_H__ +#define __ARCH_CONFIG_H__ + +/* Configuration for the PB platform with ZBT memory enabled */ + +static _mali_osk_resource_t arch_configuration [] = +{ + + { + .type = PMU, + .description = "Mali-400 PMU", + .base = 0xC0002000, + .irq = -1, + .mmu_id = 0 + }, + { + .type = MALI400GP, + .description = "Mali-400 GP", + .base = 0xC0000000, + .irq = -1, + .mmu_id = 1 + }, + { + .type = MALI400PP, + .base = 0xc0008000, + .irq = -1, + .description = "Mali-400 PP", + .mmu_id = 2 + }, + { + .type = MMU, + .base = 0xC0003000, + .irq = -1, + .description = "Mali-400 MMU for GP", + .mmu_id = 1 + }, + { + .type = MMU, + .base = 0xC0004000, + .irq = -1, + .description = "Mali-400 MMU for PP", + .mmu_id = 2 + }, + { + .type = OS_MEMORY, + .description = "OS Memory", + .alloc_order = 10, /* Lowest preference for this memory */ + .size = 96 * 1024 * 1024, /* 96 MB */ + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE + }, + { + .type = MEMORY, + .description = "Mali SDRAM remapped to baseboard", + .cpu_usage_adjust = 0, + .alloc_order = 5, /* Medium preference for this memory */ + .base = 0x80000000, + .size = 0x10000000, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE + }, + { + .type = MEMORY, + .description = "Mali ZBT", + .alloc_order = 0, /* Highest preference for this memory */ + .base = 0xe1000000, + .size = 0x01000000, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE + }, + { + .type = MEM_VALIDATION, + .description = "Framebuffer", + .base = 0xe0000000, + .size = 0x01000000, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE + }, + { + .type = MALI400L2, + .base = 0xC0001000, + .description = "Mali-400 L2 cache" + }, +}; + +#endif /* __ARCH_CONFIG_H__ */ diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-pmu/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-pmu/config.h new file mode 100644 index 0000000..6d84ab1 --- /dev/null +++ b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-pmu/config.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __ARCH_CONFIG_H__ +#define __ARCH_CONFIG_H__ + +/* Configuration for the PB platform with ZBT memory enabled */ + +static _mali_osk_resource_t arch_configuration [] = +{ + { + .type = PMU, + .description = "Mali-400 PMU", + .base = 0xC0002000, + .irq = -1, + .mmu_id = 0 + + }, + { + .type = MALI400GP, + .description = "Mali-400 GP", + .base = 0xC0000000, + .irq = -1, + .mmu_id = 1 + }, + { + .type = MALI400PP, + .base = 0xc0008000, + .irq = -1, + .description = "Mali-400 PP", + .mmu_id = 2 + }, + { + .type = MMU, + .base = 0xC0003000, + .irq = -1, + .description = "Mali-400 MMU for GP", + .mmu_id = 1 + }, + { + .type = MMU, + .base = 0xC0004000, + .irq = -1, + .description = "Mali-400 MMU for PP", + .mmu_id = 2 + }, + { + .type = MEMORY, + .description = "Mali SDRAM remapped to baseboard", + .cpu_usage_adjust = -0x50000000, + .alloc_order = 0, /* Highest preference for this memory */ + .base = 0xD0000000, + .size = 0x10000000, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE + }, + { + .type = MEMORY, + .description = "Mali ZBT", + .alloc_order = 5, /* Medium preference for this memory */ + .base = 0xe1000000, + .size = 0x01000000, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE + }, + { + .type = MEM_VALIDATION, + .description = "Framebuffer", + .base = 0xe0000000, + .size = 0x01000000, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE + }, + { + .type = MALI400L2, + .base = 0xC0001000, + .description = "Mali-400 L2 cache" + }, +}; + +#endif /* __ARCH_CONFIG_H__ */ diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1/config.h new file mode 100644 index 0000000..568ac0a --- /dev/null +++ b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1/config.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __ARCH_CONFIG_H__ +#define __ARCH_CONFIG_H__ + +/* Configuration for the PB platform with ZBT memory enabled */ + +static _mali_osk_resource_t arch_configuration [] = +{ + { + .type = MALI400GP, + .description = "Mali-400 GP", + .base = 0xC0000000, + .irq = -1, + .mmu_id = 1 + }, + { + .type = MALI400PP, + .base = 0xc0008000, + .irq = -1, + .description = "Mali-400 PP", + .mmu_id = 2 + }, + { + .type = MMU, + .base = 0xC0003000, + .irq = -1, + .description = "Mali-400 MMU for GP", + .mmu_id = 1 + }, + { + .type = MMU, + .base = 0xC0004000, + .irq = -1, + .description = "Mali-400 MMU for PP", + .mmu_id = 2 + }, + { + .type = MEMORY, + .description = "Mali SDRAM remapped to baseboard", + .cpu_usage_adjust = -0x50000000, + .alloc_order = 0, /* Highest preference for this memory */ + .base = 0xD0000000, + .size = 0x10000000, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE + }, + { + .type = MEMORY, + .description = "Mali ZBT", + .alloc_order = 5, /* Medium preference for this memory */ + .base = 0xe1000000, + .size = 0x01000000, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE + }, + { + .type = MEM_VALIDATION, + .description = "Framebuffer", + .base = 0xe0000000, + .size = 0x01000000, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE + }, + { + .type = MALI400L2, + .base = 0xC0001000, + .description = "Mali-400 L2 cache" + }, +}; + +#endif /* __ARCH_CONFIG_H__ */ diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-2/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-2/config.h new file mode 100644 index 0000000..98b8059 --- /dev/null +++ b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-2/config.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __ARCH_CONFIG_H__ +#define __ARCH_CONFIG_H__ + +/* Configuration for the PB platform with ZBT memory enabled */ + +static _mali_osk_resource_t arch_configuration [] = +{ + { + .type = MALI400GP, + .description = "Mali-400 GP", + .base = 0xC0000000, + .irq = -1, + .mmu_id = 1 + }, + { + .type = MALI400PP, + .base = 0xc0008000, + .irq = -1, + .description = "Mali-400 PP 0", + .mmu_id = 2 + }, + { + .type = MALI400PP, + .base = 0xc000A000, + .irq = -1, + .description = "Mali-400 PP 1", + .mmu_id = 3 + }, + { + .type = MMU, + .base = 0xC0003000, + .irq = -1, + .description = "Mali-400 MMU for GP", + .mmu_id = 1 + }, + { + .type = MMU, + .base = 0xC0004000, + .irq = -1, + .description = "Mali-400 MMU for PP 0", + .mmu_id = 2 + }, + { + .type = MMU, + .base = 0xC0005000, + .irq = -1, + .description = "Mali-400 MMU for PP 1", + .mmu_id = 3 + }, + { + .type = MEMORY, + .description = "Mali SDRAM remapped to baseboard", + .cpu_usage_adjust = -0x50000000, + .alloc_order = 0, /* Highest preference for this memory */ + .base = 0xD0000000, + .size = 0x10000000, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE + }, + { + .type = MEMORY, + .description = "Mali ZBT", + .alloc_order = 5, /* Medium preference for this memory */ + .base = 0xe1000000, + .size = 0x01000000, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE + }, + { + .type = MEM_VALIDATION, + .description = "Framebuffer", + .base = 0xe0000000, + .size = 0x01000000, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE + }, + { + .type = MALI400L2, + .base = 0xC0001000, + .description = "Mali-400 L2 cache" + }, +}; + +#endif /* __ARCH_CONFIG_H__ */ diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-3/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-3/config.h new file mode 100644 index 0000000..7b10925 --- /dev/null +++ b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-3/config.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __ARCH_CONFIG_H__ +#define __ARCH_CONFIG_H__ + +/* Configuration for the PB platform with ZBT memory enabled */ + +static _mali_osk_resource_t arch_configuration [] = +{ + { + .type = MALI400GP, + .description = "Mali-400 GP", + .base = 0xC0000000, + .irq = -1, + .mmu_id = 1 + }, + { + .type = MALI400PP, + .base = 0xc0008000, + .irq = -1, + .description = "Mali-400 PP 0", + .mmu_id = 2 + }, + { + .type = MALI400PP, + .base = 0xc000A000, + .irq = -1, + .description = "Mali-400 PP 1", + .mmu_id = 3 + }, + { + .type = MALI400PP, + .base = 0xc000C000, + .irq = -1, + .description = "Mali-400 PP 2", + .mmu_id = 4 + }, + { + .type = MMU, + .base = 0xC0003000, + .irq = 102, + .description = "Mali-400 MMU for GP", + .mmu_id = 1 + }, + { + .type = MMU, + .base = 0xC0004000, + .irq = 102, + .description = "Mali-400 MMU for PP 0", + .mmu_id = 2 + }, + { + .type = MMU, + .base = 0xC0005000, + .irq = 102, + .description = "Mali-400 MMU for PP 1", + .mmu_id = 3 + }, + { + .type = MMU, + .base = 0xC0006000, + .irq = 102, + .description = "Mali-400 MMU for PP 2", + .mmu_id = 4 + }, + { + .type = MEMORY, + .description = "Mali SDRAM remapped to baseboard", + .cpu_usage_adjust = -0x50000000, + .alloc_order = 0, /* Highest preference for this memory */ + .base = 0xD0000000, + .size = 0x10000000, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE + }, + { + .type = MEMORY, + .description = "Mali ZBT", + .alloc_order = 5, /* Medium preference for this memory */ + .base = 0xe1000000, + .size = 0x01000000, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE + }, + { + .type = MEM_VALIDATION, + .description = "Framebuffer", + .base = 0xe0000000, + .size = 0x01000000, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE + }, + { + .type = MALI400L2, + .base = 0xC0001000, + .description = "Mali-400 L2 cache" + }, +}; + +#endif /* __ARCH_CONFIG_H__ */ diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-4/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-4/config.h new file mode 100644 index 0000000..a15a6bd --- /dev/null +++ b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-4/config.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __ARCH_CONFIG_H__ +#define __ARCH_CONFIG_H__ + +/* Configuration for the EB platform with ZBT memory enabled */ + +static _mali_osk_resource_t arch_configuration [] = +{ + { + .type = MALI400GP, + .description = "Mali-400 GP", + .base = 0xC0000000, + .irq = -1, + .mmu_id = 1 + }, + { + .type = MALI400PP, + .base = 0xc0008000, + .irq = -1, + .description = "Mali-400 PP 0", + .mmu_id = 2 + }, + { + .type = MALI400PP, + .base = 0xc000A000, + .irq = -1, + .description = "Mali-400 PP 1", + .mmu_id = 3 + }, + { + .type = MALI400PP, + .base = 0xc000C000, + .irq = -1, + .description = "Mali-400 PP 2", + .mmu_id = 4 + }, + { + .type = MALI400PP, + .base = 0xc000E000, + .irq = -1, + .description = "Mali-400 PP 3", + .mmu_id = 5 + }, + { + .type = MMU, + .base = 0xC0003000, + .irq = 102, + .description = "Mali-400 MMU for GP", + .mmu_id = 1 + }, + { + .type = MMU, + .base = 0xC0004000, + .irq = 102, + .description = "Mali-400 MMU for PP 0", + .mmu_id = 2 + }, + { + .type = MMU, + .base = 0xC0005000, + .irq = 102, + .description = "Mali-400 MMU for PP 1", + .mmu_id = 3 + }, + { + .type = MMU, + .base = 0xC0006000, + .irq = 102, + .description = "Mali-400 MMU for PP 2", + .mmu_id = 4 + }, + { + .type = MMU, + .base = 0xC0007000, + .irq = 102, + .description = "Mali-400 MMU for PP 3", + .mmu_id = 5 + }, + { + .type = MEMORY, + .description = "Mali SDRAM remapped to baseboard", + .cpu_usage_adjust = -0x50000000, + .alloc_order = 0, /* Highest preference for this memory */ + .base = 0xD0000000, + .size = 0x10000000, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE + }, + { + .type = MEMORY, + .description = "Mali ZBT", + .alloc_order = 5, /* Medium preference for this memory */ + .base = 0xe1000000, + .size = 0x01000000, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE + }, + { + .type = MEM_VALIDATION, + .description = "Framebuffer", + .base = 0xe0000000, + .size = 0x01000000, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE + }, + { + .type = MALI400L2, + .base = 0xC0001000, + .description = "Mali-400 L2 cache" + }, +}; + +#endif /* __ARCH_CONFIG_H__ */ diff --git a/drivers/media/video/samsung/mali/arch-pegasus-m400/config.h b/drivers/media/video/samsung/mali/arch-pegasus-m400/config.h new file mode 100644 index 0000000..d5196c3 --- /dev/null +++ b/drivers/media/video/samsung/mali/arch-pegasus-m400/config.h @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __ARCH_CONFIG_H__ +#define __ARCH_CONFIG_H__ + +/* Configuration for the EB platform with ZBT memory enabled */ +/*zepplin added 2010.08.17 for orion configuration*/ +#define MALI_BASE_ADDR 0x13000000 +#define GP_ADDR MALI_BASE_ADDR +#define L2_ADDR MALI_BASE_ADDR+0x1000 +#define PMU_ADDR MALI_BASE_ADDR+0x2000 +#define GP_MMU_ADDR MALI_BASE_ADDR+0x3000 +#define PP0_MMU_ADDR MALI_BASE_ADDR+0x4000 +#define PP1_MMU_ADDR MALI_BASE_ADDR+0x5000 +#define PP2_MMU_ADDR MALI_BASE_ADDR+0x6000 +#define PP3_MMU_ADDR MALI_BASE_ADDR+0x7000 +#define PP0_ADDR MALI_BASE_ADDR+0x8000 +#define PP1_ADDR MALI_BASE_ADDR+0xA000 +#define PP2_ADDR MALI_BASE_ADDR+0xC000 +#define PP3_ADDR MALI_BASE_ADDR+0xE000 + +/*for mmu and os memory*/ +#define MEM_BASE_ADDR 0x40000000 +#define MEM_TOTAL_SIZE 0x40000000 +#define MEM_MALI_OS_SIZE 0x40000000 + +/*for dedicated memory*/ +//#define MEM_MALI_BASE 0x58000000 +//#define MEM_MALI_SIZE 0x08000000 +#define MEM_MALI_SIZE CONFIG_MALI_MEM_SIZE*1024*1024 +#define MEM_MALI_BASE 0x80000000 - MEM_MALI_SIZE + +static _mali_osk_resource_t arch_configuration [] = +{ + { + .type = MALI400GP, + .description = "Mali-400 GP", + .base = GP_ADDR, + .irq = IRQ_GP_3D, + .mmu_id = 1 + }, + { + .type = MALI400PP, + .base = PP0_ADDR, + .irq = IRQ_PP0_3D, + .description = "Mali-400 PP 0", + .mmu_id = 2 + }, + { + .type = MALI400PP, + .base = PP1_ADDR, + .irq = IRQ_PP1_3D, + .description = "Mali-400 PP 1", + .mmu_id = 3 + }, + { + .type = MALI400PP, + .base = PP2_ADDR, + .irq = IRQ_PP2_3D, + .description = "Mali-400 PP 2", + .mmu_id = 4 + }, + { + .type = MALI400PP, + .base = PP3_ADDR, + .irq = IRQ_PP3_3D, + .description = "Mali-400 PP 3", + .mmu_id = 5 + }, +#if USING_MMU + { + .type = MMU, + .base = GP_MMU_ADDR, + .irq = IRQ_GPMMU_3D, + .description = "Mali-400 MMU for GP", + .mmu_id = 1 + }, + { + .type = MMU, + .base = PP0_MMU_ADDR, + .irq = IRQ_PPMMU0_3D, + .description = "Mali-400 MMU for PP 0", + .mmu_id = 2 + }, + { + .type = MMU, + .base = PP1_MMU_ADDR, + .irq = IRQ_PPMMU1_3D, + .description = "Mali-400 MMU for PP 1", + .mmu_id = 3 + }, + { + .type = MMU, + .base = PP2_MMU_ADDR, + .irq = IRQ_PPMMU2_3D, + .description = "Mali-400 MMU for PP 2", + .mmu_id = 4 + }, + { + .type = MMU, + .base = PP3_MMU_ADDR, + .irq = IRQ_PPMMU3_3D, + .description = "Mali-400 MMU for PP 3", + .mmu_id = 5 + }, +#if USING_OS_MEMORY + { + .type = OS_MEMORY, + .description = "System Memory", + .size = MEM_MALI_OS_SIZE, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE + }, +#endif +#if USING_DED /* Dedicated Memory */ + { + .type = MEMORY, + .description = "Dedicated Memory", + .base = MEM_MALI_BASE, + .size = MEM_MALI_SIZE, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE + }, +#endif/* if USING_OS_MEMORY*/ + { + .type = MEM_VALIDATION, + .description = "memory validation", + .base = MEM_BASE_ADDR, + .size = MEM_TOTAL_SIZE, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE + }, +#else /* Not using MMU */ + { + .type = MEMORY, + .description = "Dedicated Memory", + .base = MEM_MALI_BASE, + .size = MEM_MALI_SIZE, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE + }, +#endif + { + .type = MALI400L2, + .base = L2_ADDR, + .description = "Mali-400 L2 cache" + }, +}; + +#endif /* __ARCH_CONFIG_H__ */ diff --git a/drivers/media/video/samsung/mali/arch-release b/drivers/media/video/samsung/mali/arch-release new file mode 120000 index 0000000..0ed0909 --- /dev/null +++ b/drivers/media/video/samsung/mali/arch-release @@ -0,0 +1 @@ +arch-pegasus-m400/ \ No newline at end of file diff --git a/drivers/media/video/samsung/mali/arch-ve-virtex6-m450-8/config.h b/drivers/media/video/samsung/mali/arch-ve-virtex6-m450-8/config.h new file mode 100644 index 0000000..eb5da50 --- /dev/null +++ b/drivers/media/video/samsung/mali/arch-ve-virtex6-m450-8/config.h @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __ARCH_CONFIG_H__ +#define __ARCH_CONFIG_H__ + +/* Configuration for the Versatile Express platform */ + +#define MALI_BASE_ADDRESS 0xFC040000 + +static _mali_osk_resource_t arch_configuration [] = +{ + /* PMU */ + { + .type = PMU, + .base = MALI_BASE_ADDRESS + 0x02000, + .description = "MALI PMU" + }, + /* GP cluster */ + { + .type = MALI400L2, + .base = MALI_BASE_ADDRESS + 0x10000, + .description = "Mali-450 L2 cache for GP" + }, + { + .type = MALI400GP, + .description = "Mali-450 GP", + .base = MALI_BASE_ADDRESS, + .irq = -1, + }, + { + .type = MMU, + .base = MALI_BASE_ADDRESS + 0x3000, + .irq = 70, + .description = "Mali-450 MMU for GP", + }, + + /* PP0-3 cluster */ + { + .type = MALI400L2, + .base = MALI_BASE_ADDRESS + 0x1000, + .description = "Mali-450 L2 cache for PP0-3" + }, + { + .type = MALI400PP, + .base = MALI_BASE_ADDRESS + 0x8000, + .irq = 70, + .description = "Mali-450 PP0", + }, + { + .type = MMU, + .base = MALI_BASE_ADDRESS + 0x4000, + .irq = 70, + .description = "Mali-450 MMU for PP0", + }, + { + .type = MALI400PP, + .base = MALI_BASE_ADDRESS + 0xA000, + .irq = 70, + .description = "Mali-450 PP1", + }, + { + .type = MMU, + .base = MALI_BASE_ADDRESS + 0x5000, + .irq = 70, + .description = "Mali-450 MMU for PP1", + }, + { + .type = MALI400PP, + .base = MALI_BASE_ADDRESS + 0xC000, + .irq = 70, + .description = "Mali-450 PP2", + }, + { + .type = MMU, + .base = MALI_BASE_ADDRESS + 0x6000, + .irq = 70, + .description = "Mali-450 MMU for PP2", + }, + { + .type = MALI400PP, + .base = MALI_BASE_ADDRESS + 0xE000, + .irq = 70, + .description = "Mali-450 PP3", + }, + { + .type = MMU, + .base = MALI_BASE_ADDRESS + 0x7000, + .irq = 70, + .description = "Mali-450 MMU for PP3", + }, + + /* PP4-7 cluster */ + { + .type = MALI400L2, + .base = MALI_BASE_ADDRESS + 0x11000, + .description = "Mali-450 L2 cache for PP4-7" + }, + { + .type = MALI400PP, + .base = MALI_BASE_ADDRESS + 0x28000, + .irq = 70, + .description = "Mali-450 PP4", + }, + { + .type = MMU, + .base = MALI_BASE_ADDRESS + 0x1C000, + .irq = 70, + .description = "Mali-450 MMU for PP4", + }, + { + .type = MALI400PP, + .base = MALI_BASE_ADDRESS + 0x2A000, + .irq = 70, + .description = "Mali-450 PP5", + }, + { + .type = MMU, + .base = MALI_BASE_ADDRESS + 0x1D000, + .irq = 70, + .description = "Mali-450 MMU for PP5", + }, + { + .type = MALI400PP, + .base = MALI_BASE_ADDRESS + 0x2C000, + .irq = 70, + .description = "Mali-450 PP6", + }, + { + .type = MMU, + .base = MALI_BASE_ADDRESS + 0x1E000, + .irq = 70, + .description = "Mali-450 MMU for PP6", + }, + { + .type = MALI400PP, + .base = MALI_BASE_ADDRESS + 0x2E000, + .irq = 70, + .description = "Mali-450 PP7", + }, + { + .type = MMU, + .base = MALI_BASE_ADDRESS + 0x1F000, + .irq = 70, + .description = "Mali-450 MMU for PP7", + }, + + /* Memory */ + { + .type = OS_MEMORY, + .description = "Mali OS memory", + .cpu_usage_adjust = 0, + .alloc_order = 0, /* Highest preference for this memory */ + .base = 0x0, + .size = 256 * 1024 * 1024, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE + }, + { + .type = MEM_VALIDATION, + .description = "Framebuffer", + .base = 0xe0000000, + .size = 0x01000000, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE + }, +}; + +#endif /* __ARCH_CONFIG_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_block_allocator.c b/drivers/media/video/samsung/mali/common/mali_block_allocator.c new file mode 100644 index 0000000..269e662 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_block_allocator.c @@ -0,0 +1,391 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "mali_kernel_common.h" +#include "mali_kernel_core.h" +#include "mali_kernel_memory_engine.h" +#include "mali_block_allocator.h" +#include "mali_osk.h" + +#define MALI_BLOCK_SIZE (256UL * 1024UL) /* 256 kB, remember to keep the ()s */ + +typedef struct block_info +{ + struct block_info * next; +} block_info; + +/* The structure used as the handle produced by block_allocator_allocate, + * and removed by block_allocator_release */ +typedef struct block_allocator_allocation +{ + /* The list will be released in reverse order */ + block_info *last_allocated; + mali_allocation_engine * engine; + mali_memory_allocation * descriptor; + u32 start_offset; + u32 mapping_length; +} block_allocator_allocation; + + +typedef struct block_allocator +{ + _mali_osk_lock_t *mutex; + block_info * all_blocks; + block_info * first_free; + u32 base; + u32 cpu_usage_adjust; + u32 num_blocks; +} block_allocator; + +MALI_STATIC_INLINE u32 get_phys(block_allocator * info, block_info * block); +static mali_physical_memory_allocation_result block_allocator_allocate(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info); +static void block_allocator_release(void * ctx, void * handle); +static mali_physical_memory_allocation_result block_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block); +static void block_allocator_release_page_table_block( mali_page_table_block *page_table_block ); +static void block_allocator_destroy(mali_physical_memory_allocator * allocator); +static u32 block_allocator_stat(mali_physical_memory_allocator * allocator); + +mali_physical_memory_allocator * mali_block_allocator_create(u32 base_address, u32 cpu_usage_adjust, u32 size, const char *name) +{ + mali_physical_memory_allocator * allocator; + block_allocator * info; + u32 usable_size; + u32 num_blocks; + + usable_size = size & ~(MALI_BLOCK_SIZE - 1); + MALI_DEBUG_PRINT(3, ("Mali block allocator create for region starting at 0x%08X length 0x%08X\n", base_address, size)); + MALI_DEBUG_PRINT(4, ("%d usable bytes\n", usable_size)); + num_blocks = usable_size / MALI_BLOCK_SIZE; + MALI_DEBUG_PRINT(4, ("which becomes %d blocks\n", num_blocks)); + + if (usable_size == 0) + { + MALI_DEBUG_PRINT(1, ("Memory block of size %d is unusable\n", size)); + return NULL; + } + + allocator = _mali_osk_malloc(sizeof(mali_physical_memory_allocator)); + if (NULL != allocator) + { + info = _mali_osk_malloc(sizeof(block_allocator)); + if (NULL != info) + { + info->mutex = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED, 0, _MALI_OSK_LOCK_ORDER_MEM_INFO); + if (NULL != info->mutex) + { + info->all_blocks = _mali_osk_malloc(sizeof(block_info) * num_blocks); + if (NULL != info->all_blocks) + { + u32 i; + info->first_free = NULL; + info->num_blocks = num_blocks; + + info->base = base_address; + info->cpu_usage_adjust = cpu_usage_adjust; + + for ( i = 0; i < num_blocks; i++) + { + info->all_blocks[i].next = info->first_free; + info->first_free = &info->all_blocks[i]; + } + + allocator->allocate = block_allocator_allocate; + allocator->allocate_page_table_block = block_allocator_allocate_page_table_block; + allocator->destroy = block_allocator_destroy; + allocator->stat = block_allocator_stat; + allocator->ctx = info; + allocator->name = name; + + return allocator; + } + _mali_osk_lock_term(info->mutex); + } + _mali_osk_free(info); + } + _mali_osk_free(allocator); + } + + return NULL; +} + +static void block_allocator_destroy(mali_physical_memory_allocator * allocator) +{ + block_allocator * info; + MALI_DEBUG_ASSERT_POINTER(allocator); + MALI_DEBUG_ASSERT_POINTER(allocator->ctx); + info = (block_allocator*)allocator->ctx; + + _mali_osk_free(info->all_blocks); + _mali_osk_lock_term(info->mutex); + _mali_osk_free(info); + _mali_osk_free(allocator); +} + +MALI_STATIC_INLINE u32 get_phys(block_allocator * info, block_info * block) +{ + return info->base + ((block - info->all_blocks) * MALI_BLOCK_SIZE); +} + +static mali_physical_memory_allocation_result block_allocator_allocate(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info) +{ + block_allocator * info; + u32 left; + block_info * last_allocated = NULL; + mali_physical_memory_allocation_result result = MALI_MEM_ALLOC_NONE; + block_allocator_allocation *ret_allocation; + + MALI_DEBUG_ASSERT_POINTER(ctx); + MALI_DEBUG_ASSERT_POINTER(descriptor); + MALI_DEBUG_ASSERT_POINTER(offset); + MALI_DEBUG_ASSERT_POINTER(alloc_info); + + info = (block_allocator*)ctx; + left = descriptor->size - *offset; + MALI_DEBUG_ASSERT(0 != left); + + if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) return MALI_MEM_ALLOC_INTERNAL_FAILURE; + + ret_allocation = _mali_osk_malloc( sizeof(block_allocator_allocation) ); + + if ( NULL == ret_allocation ) + { + /* Failure; try another allocator by returning MALI_MEM_ALLOC_NONE */ + _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); + return result; + } + + ret_allocation->start_offset = *offset; + ret_allocation->mapping_length = 0; + + while ((left > 0) && (info->first_free)) + { + block_info * block; + u32 phys_addr; + u32 padding; + u32 current_mapping_size; + + block = info->first_free; + info->first_free = info->first_free->next; + block->next = last_allocated; + last_allocated = block; + + phys_addr = get_phys(info, block); + + padding = *offset & (MALI_BLOCK_SIZE-1); + + if (MALI_BLOCK_SIZE - padding < left) + { + current_mapping_size = MALI_BLOCK_SIZE - padding; + } + else + { + current_mapping_size = left; + } + + if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, phys_addr + padding, info->cpu_usage_adjust, current_mapping_size)) + { + MALI_DEBUG_PRINT(1, ("Mapping of physical memory failed\n")); + result = MALI_MEM_ALLOC_INTERNAL_FAILURE; + mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->start_offset, ret_allocation->mapping_length, (_mali_osk_mem_mapregion_flags_t)0); + + /* release all memory back to the pool */ + while (last_allocated) + { + /* This relinks every block we've just allocated back into the free-list */ + block = last_allocated->next; + last_allocated->next = info->first_free; + info->first_free = last_allocated; + last_allocated = block; + } + + break; + } + + *offset += current_mapping_size; + left -= current_mapping_size; + ret_allocation->mapping_length += current_mapping_size; + } + + _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); + + if (last_allocated) + { + if (left) result = MALI_MEM_ALLOC_PARTIAL; + else result = MALI_MEM_ALLOC_FINISHED; + + /* Record all the information about this allocation */ + ret_allocation->last_allocated = last_allocated; + ret_allocation->engine = engine; + ret_allocation->descriptor = descriptor; + + alloc_info->ctx = info; + alloc_info->handle = ret_allocation; + alloc_info->release = block_allocator_release; + } + else + { + /* Free the allocation information - nothing to be passed back */ + _mali_osk_free( ret_allocation ); + } + + return result; +} + +static void block_allocator_release(void * ctx, void * handle) +{ + block_allocator * info; + block_info * block, * next; + block_allocator_allocation *allocation; + + MALI_DEBUG_ASSERT_POINTER(ctx); + MALI_DEBUG_ASSERT_POINTER(handle); + + info = (block_allocator*)ctx; + allocation = (block_allocator_allocation*)handle; + block = allocation->last_allocated; + + MALI_DEBUG_ASSERT_POINTER(block); + + if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) + { + MALI_DEBUG_PRINT(1, ("allocator release: Failed to get mutex\n")); + return; + } + + /* unmap */ + mali_allocation_engine_unmap_physical(allocation->engine, allocation->descriptor, allocation->start_offset, allocation->mapping_length, (_mali_osk_mem_mapregion_flags_t)0); + + while (block) + { + MALI_DEBUG_ASSERT(!((block < info->all_blocks) || (block > (info->all_blocks + info->num_blocks)))); + + next = block->next; + + /* relink into free-list */ + block->next = info->first_free; + info->first_free = block; + + /* advance the loop */ + block = next; + } + + _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); + + _mali_osk_free( allocation ); +} + + +static mali_physical_memory_allocation_result block_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block) +{ + block_allocator * info; + mali_physical_memory_allocation_result result = MALI_MEM_ALLOC_INTERNAL_FAILURE; + + MALI_DEBUG_ASSERT_POINTER(ctx); + MALI_DEBUG_ASSERT_POINTER(block); + info = (block_allocator*)ctx; + + if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) return MALI_MEM_ALLOC_INTERNAL_FAILURE; + + if (NULL != info->first_free) + { + void * virt; + u32 phys; + u32 size; + block_info * alloc; + alloc = info->first_free; + + phys = get_phys(info, alloc); /* Does not modify info or alloc */ + size = MALI_BLOCK_SIZE; /* Must be multiple of MALI_MMU_PAGE_SIZE */ + virt = _mali_osk_mem_mapioregion( phys, size, "Mali block allocator page tables" ); + + /* Failure of _mali_osk_mem_mapioregion will result in MALI_MEM_ALLOC_INTERNAL_FAILURE, + * because it's unlikely another allocator will be able to map in. */ + + if ( NULL != virt ) + { + block->ctx = info; /* same as incoming ctx */ + block->handle = alloc; + block->phys_base = phys; + block->size = size; + block->release = block_allocator_release_page_table_block; + block->mapping = virt; + + info->first_free = alloc->next; + + alloc->next = NULL; /* Could potentially link many blocks together instead */ + + result = MALI_MEM_ALLOC_FINISHED; + } + } + else result = MALI_MEM_ALLOC_NONE; + + _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); + + return result; +} + + +static void block_allocator_release_page_table_block( mali_page_table_block *page_table_block ) +{ + block_allocator * info; + block_info * block, * next; + + MALI_DEBUG_ASSERT_POINTER( page_table_block ); + + info = (block_allocator*)page_table_block->ctx; + block = (block_info*)page_table_block->handle; + + MALI_DEBUG_ASSERT_POINTER(info); + MALI_DEBUG_ASSERT_POINTER(block); + + + if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) + { + MALI_DEBUG_PRINT(1, ("allocator release: Failed to get mutex\n")); + return; + } + + /* Unmap all the physical memory at once */ + _mali_osk_mem_unmapioregion( page_table_block->phys_base, page_table_block->size, page_table_block->mapping ); + + /** @note This loop handles the case where more than one block_info was linked. + * Probably unnecessary for page table block releasing. */ + while (block) + { + next = block->next; + + MALI_DEBUG_ASSERT(!((block < info->all_blocks) || (block > (info->all_blocks + info->num_blocks)))); + + block->next = info->first_free; + info->first_free = block; + + block = next; + } + + _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); +} + +static u32 block_allocator_stat(mali_physical_memory_allocator * allocator) +{ + block_allocator * info; + block_info *block; + u32 free_blocks = 0; + + MALI_DEBUG_ASSERT_POINTER(allocator); + + info = (block_allocator*)allocator->ctx; + block = info->first_free; + + while(block) + { + free_blocks++; + block = block->next; + } + return (info->num_blocks - free_blocks) * MALI_BLOCK_SIZE; +} diff --git a/drivers/media/video/samsung/mali/common/mali_block_allocator.h b/drivers/media/video/samsung/mali/common/mali_block_allocator.h new file mode 100644 index 0000000..6c6f13e --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_block_allocator.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_BLOCK_ALLOCATOR_H__ +#define __MALI_BLOCK_ALLOCATOR_H__ + +#include "mali_kernel_memory_engine.h" + +mali_physical_memory_allocator * mali_block_allocator_create(u32 base_address, u32 cpu_usage_adjust, u32 size, const char *name); + +#endif /* __MALI_BLOCK_ALLOCATOR_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_cluster.c b/drivers/media/video/samsung/mali/common/mali_cluster.c new file mode 100644 index 0000000..f0fb2b6 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_cluster.c @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_kernel_common.h" +#include "mali_cluster.h" +#include "mali_osk.h" +#include "mali_group.h" +#include "mali_l2_cache.h" +#include "mali_scheduler.h" + +static struct mali_cluster *mali_global_clusters[MALI_MAX_NUMBER_OF_CLUSTERS] = { NULL, NULL, NULL }; +static u32 mali_global_num_clusters = 0; + +/** + * The structure represents a render cluster + * A render cluster is defined by all the cores that share the same Mali L2 cache + */ +struct mali_cluster +{ + struct mali_l2_cache_core *l2; + u32 number_of_groups; + struct mali_group* groups[MALI_MAX_NUMBER_OF_GROUPS_PER_CLUSTER]; + u32 last_invalidated_id; + mali_bool power_is_enabled; +}; + +struct mali_cluster *mali_cluster_create(struct mali_l2_cache_core *l2_cache) +{ + struct mali_cluster *cluster = NULL; + + if (mali_global_num_clusters >= MALI_MAX_NUMBER_OF_CLUSTERS) + { + MALI_PRINT_ERROR(("Mali cluster: Too many cluster objects created\n")); + return NULL; + } + + cluster = _mali_osk_malloc(sizeof(struct mali_cluster)); + if (NULL != cluster) + { + _mali_osk_memset(cluster, 0, sizeof(struct mali_cluster)); + cluster->l2 = l2_cache; /* This cluster now owns this L2 cache object */ + cluster->last_invalidated_id = 0; + cluster->power_is_enabled = MALI_TRUE; + + mali_global_clusters[mali_global_num_clusters] = cluster; + mali_global_num_clusters++; + + return cluster; + } + + return NULL; +} + +void mali_cluster_power_is_enabled_set(struct mali_cluster * cluster, mali_bool power_is_enabled) +{ + cluster->power_is_enabled = power_is_enabled; +} + +mali_bool mali_cluster_power_is_enabled_get(struct mali_cluster * cluster) +{ + return cluster->power_is_enabled; +} + + +void mali_cluster_add_group(struct mali_cluster *cluster, struct mali_group *group) +{ + MALI_DEBUG_ASSERT_POINTER(cluster); + + if (cluster->number_of_groups < MALI_MAX_NUMBER_OF_GROUPS_PER_CLUSTER) + { + /* This cluster now owns the group object */ + cluster->groups[cluster->number_of_groups] = group; + cluster->number_of_groups++; + } +} + +void mali_cluster_delete(struct mali_cluster *cluster) +{ + u32 i; + + MALI_DEBUG_ASSERT_POINTER(cluster); + + /* Free all the resources we own */ + for (i = 0; i < cluster->number_of_groups; i++) + { + mali_group_delete(cluster->groups[i]); + } + + if (NULL != cluster->l2) + { + mali_l2_cache_delete(cluster->l2); + } + + for (i = 0; i < mali_global_num_clusters; i++) + { + if (mali_global_clusters[i] == cluster) + { + mali_global_clusters[i] = NULL; + mali_global_num_clusters--; + break; + } + } + + _mali_osk_free(cluster); +} + +void mali_cluster_reset(struct mali_cluster *cluster) +{ + u32 i; + + MALI_DEBUG_ASSERT_POINTER(cluster); + + /* Free all the resources we own */ + for (i = 0; i < cluster->number_of_groups; i++) + { + struct mali_group *group = cluster->groups[i]; + + mali_group_reset(group); + } + + if (NULL != cluster->l2) + { + mali_l2_cache_reset(cluster->l2); + } +} + +struct mali_l2_cache_core* mali_cluster_get_l2_cache_core(struct mali_cluster *cluster) +{ + MALI_DEBUG_ASSERT_POINTER(cluster); + return cluster->l2; +} + +struct mali_group *mali_cluster_get_group(struct mali_cluster *cluster, u32 index) +{ + MALI_DEBUG_ASSERT_POINTER(cluster); + + if (index < cluster->number_of_groups) + { + return cluster->groups[index]; + } + + return NULL; +} + +struct mali_cluster *mali_cluster_get_global_cluster(u32 index) +{ + if (MALI_MAX_NUMBER_OF_CLUSTERS > index) + { + return mali_global_clusters[index]; + } + + return NULL; +} + +u32 mali_cluster_get_glob_num_clusters(void) +{ + return mali_global_num_clusters; +} + +mali_bool mali_cluster_l2_cache_invalidate_all(struct mali_cluster *cluster, u32 id) +{ + MALI_DEBUG_ASSERT_POINTER(cluster); + + if (NULL != cluster->l2) + { + /* If the last cache invalidation was done by a job with a higher id we + * don't have to flush. Since user space will store jobs w/ their + * corresponding memory in sequence (first job #0, then job #1, ...), + * we don't have to flush for job n-1 if job n has already invalidated + * the cache since we know for sure that job n-1's memory was already + * written when job n was started. */ + if (((s32)id) <= ((s32)cluster->last_invalidated_id)) + { + return MALI_FALSE; + } + else + { + cluster->last_invalidated_id = mali_scheduler_get_new_id(); + } + + mali_l2_cache_invalidate_all(cluster->l2); + } + return MALI_TRUE; +} + +void mali_cluster_l2_cache_invalidate_all_force(struct mali_cluster *cluster) +{ + MALI_DEBUG_ASSERT_POINTER(cluster); + + if (NULL != cluster->l2) + { + cluster->last_invalidated_id = mali_scheduler_get_new_id(); + mali_l2_cache_invalidate_all(cluster->l2); + } +} + +void mali_cluster_invalidate_pages(u32 *pages, u32 num_pages) +{ + u32 i; + + for (i = 0; i < mali_global_num_clusters; i++) + { + /*additional check for cluster*/ + if (MALI_TRUE == mali_l2_cache_lock_power_state(mali_global_clusters[i]->l2)) + { + mali_l2_cache_invalidate_pages(mali_global_clusters[i]->l2, pages, num_pages); + } + mali_l2_cache_unlock_power_state(mali_global_clusters[i]->l2); + /*check for failed power locking???*/ + } +} diff --git a/drivers/media/video/samsung/mali/common/mali_cluster.h b/drivers/media/video/samsung/mali/common/mali_cluster.h new file mode 100644 index 0000000..33debdb --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_cluster.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_CLUSTER_H__ +#define __MALI_CLUSTER_H__ + +#include "mali_osk.h" +#include "mali_l2_cache.h" + +/* Maximum 1 GP and 4 PP for a cluster (Mali-400 Quad-core) */ +#define MALI_MAX_NUMBER_OF_GROUPS_PER_CLUSTER 5 +#define MALI_MAX_NUMBER_OF_CLUSTERS 3 + +struct mali_cluster; +struct mali_group; + +struct mali_cluster *mali_cluster_create(struct mali_l2_cache_core *l2_cache); +void mali_cluster_add_group(struct mali_cluster *cluster, struct mali_group *group); +void mali_cluster_delete(struct mali_cluster *cluster); + +void mali_cluster_power_is_enabled_set(struct mali_cluster * cluster, mali_bool power_is_enabled); +mali_bool mali_cluster_power_is_enabled_get(struct mali_cluster * cluster); + +void mali_cluster_reset(struct mali_cluster *cluster); + +struct mali_l2_cache_core* mali_cluster_get_l2_cache_core(struct mali_cluster *cluster); +struct mali_group *mali_cluster_get_group(struct mali_cluster *cluster, u32 index); + +struct mali_cluster *mali_cluster_get_global_cluster(u32 index); +u32 mali_cluster_get_glob_num_clusters(void); + +/* Returns MALI_TRUE if it did the flush */ +mali_bool mali_cluster_l2_cache_invalidate_all(struct mali_cluster *cluster, u32 id); +void mali_cluster_l2_cache_invalidate_all_force(struct mali_cluster *cluster); +void mali_cluster_invalidate_pages(u32 *pages, u32 num_pages); + +#endif /* __MALI_CLUSTER_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_device_pause_resume.c b/drivers/media/video/samsung/mali/common/mali_device_pause_resume.c new file mode 100644 index 0000000..6af1279 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_device_pause_resume.c @@ -0,0 +1,46 @@ +/** + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_device_pause_resume.c + * Implementation of the Mali pause/resume functionality + */ + +#include "mali_gp_scheduler.h" +#include "mali_pp_scheduler.h" +#include "mali_pm.h" + +void mali_dev_pause(mali_bool *power_is_on) +{ + mali_gp_scheduler_suspend(); + mali_pp_scheduler_suspend(); + + /* + * Take and hold the PM lock to be sure we don't change power state as well. + * (it might be unsafe to for instance change frequency if Mali GPU is powered off) + */ + mali_pm_execute_state_change_lock(); + if (NULL != power_is_on) + { + *power_is_on = mali_pm_is_powered_on(); + } +} + +void mali_dev_resume(void) +{ + mali_pm_execute_state_change_unlock(); + mali_gp_scheduler_resume(); + mali_pp_scheduler_resume(); +} + +/* +EXPORT_SYMBOL(mali_dev_pause); +EXPORT_SYMBOL(mali_dev_resume); +*/ diff --git a/drivers/media/video/samsung/mali/common/mali_device_pause_resume.h b/drivers/media/video/samsung/mali/common/mali_device_pause_resume.h new file mode 100644 index 0000000..6be75b0 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_device_pause_resume.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_DEVICE_PAUSE_RESUME_H__ +#define __MALI_DEVICE_PAUSE_RESUME_H__ + +#include "mali_osk.h" + +/** + * Pause the scheduling and power state changes of Mali device driver. + * mali_dev_resume() must always be called as soon as possible after this function + * in order to resume normal operation of the Mali driver. + * + * @param power_is_on Receives the power current status of Mali GPU. MALI_TRUE if GPU is powered on + */ +void mali_dev_pause(mali_bool *power_is_on); + +/** + * Resume scheduling and allow power changes in Mali device driver. + * This must always be called after mali_dev_pause(). + */ +void mali_dev_resume(void); + +#endif /* __MALI_DEVICE_PAUSE_RESUME_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_dlbu.c b/drivers/media/video/samsung/mali/common/mali_dlbu.c new file mode 100644 index 0000000..fcc51fa --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_dlbu.c @@ -0,0 +1,285 @@ +/* + * Copyright (C) 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_dlbu.h" +#include "mali_memory.h" +#include "mali_pp.h" +#include "mali_group.h" +#include "mali_osk.h" +#include "mali_hw_core.h" + +/** + * Size of DLBU registers in bytes + */ +#define MALI_DLBU_SIZE 0x400 + +u32 mali_dlbu_phys_addr = 0; +static mali_io_address mali_dlbu_cpu_addr = 0; + +static u32 mali_dlbu_tile_position; + +/** + * DLBU register numbers + * Used in the register read/write routines. + * See the hardware documentation for more information about each register + */ +typedef enum mali_dlbu_register { + MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR = 0x0000, /**< Master tile list physical base address; + 31:12 Physical address to the page used for the DLBU + 0 DLBU enable - set this bit to 1 enables the AXI bus + between PPs and L2s, setting to 0 disables the router and + no further transactions are sent to DLBU */ + MALI_DLBU_REGISTER_MASTER_TLLIST_VADDR = 0x0004, /**< Master tile list virtual base address; + 31:12 Virtual address to the page used for the DLBU */ + MALI_DLBU_REGISTER_TLLIST_VBASEADDR = 0x0008, /**< Tile list virtual base address; + 31:12 Virtual address to the tile list. This address is used when + calculating the call address sent to PP.*/ + MALI_DLBU_REGISTER_FB_DIM = 0x000C, /**< Framebuffer dimension; + 23:16 Number of tiles in Y direction-1 + 7:0 Number of tiles in X direction-1 */ + MALI_DLBU_REGISTER_TLLIST_CONF = 0x0010, /**< Tile list configuration; + 29:28 select the size of each allocated block: 0=128 bytes, 1=256, 2=512, 3=1024 + 21:16 2^n number of tiles to be binned to one tile list in Y direction + 5:0 2^n number of tiles to be binned to one tile list in X direction */ + MALI_DLBU_REGISTER_START_TILE_POS = 0x0014, /**< Start tile positions; + 31:24 start position in Y direction for group 1 + 23:16 start position in X direction for group 1 + 15:8 start position in Y direction for group 0 + 7:0 start position in X direction for group 0 */ + MALI_DLBU_REGISTER_PP_ENABLE_MASK = 0x0018, /**< PP enable mask; + 7 enable PP7 for load balancing + 6 enable PP6 for load balancing + 5 enable PP5 for load balancing + 4 enable PP4 for load balancing + 3 enable PP3 for load balancing + 2 enable PP2 for load balancing + 1 enable PP1 for load balancing + 0 enable PP0 for load balancing */ +} mali_dlbu_register; + +typedef enum +{ + PP0ENABLE = 0, + PP1ENABLE, + PP2ENABLE, + PP3ENABLE, + PP4ENABLE, + PP5ENABLE, + PP6ENABLE, + PP7ENABLE +} mali_dlbu_pp_enable; + +struct mali_dlbu_core +{ + struct mali_hw_core hw_core; /**< Common for all HW cores */ + u32 pp_cores_mask; /**< This is a mask for the PP cores whose operation will be controlled by LBU + see MALI_DLBU_REGISTER_PP_ENABLE_MASK register */ +}; + +_mali_osk_errcode_t mali_dlbu_initialize(void) +{ + + MALI_DEBUG_PRINT(2, ("Dynamic Load Balancing Unit initializing\n")); + + if (_MALI_OSK_ERR_OK == mali_mmu_get_table_page(&mali_dlbu_phys_addr, &mali_dlbu_cpu_addr)) + { + MALI_SUCCESS; + } + + return _MALI_OSK_ERR_FAULT; +} + +void mali_dlbu_terminate(void) +{ + MALI_DEBUG_PRINT(3, ("Mali DLBU: terminating\n")); + + mali_mmu_release_table_page(mali_dlbu_phys_addr); +} + +struct mali_dlbu_core *mali_dlbu_create(const _mali_osk_resource_t * resource) +{ + struct mali_dlbu_core *core = NULL; + + MALI_DEBUG_PRINT(2, ("Mali DLBU: Creating Mali dynamic load balancing unit: %s\n", resource->description)); + + core = _mali_osk_malloc(sizeof(struct mali_dlbu_core)); + if (NULL != core) + { + if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALI_DLBU_SIZE)) + { + if (_MALI_OSK_ERR_OK == mali_dlbu_reset(core)) + { + mali_hw_core_register_write(&core->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_VADDR, MALI_DLB_VIRT_ADDR); + + return core; + } + MALI_PRINT_ERROR(("Failed to reset DLBU %s\n", core->hw_core.description)); + mali_hw_core_delete(&core->hw_core); + } + + _mali_osk_free(core); + } + else + { + MALI_PRINT_ERROR(("Mali DLBU: Failed to allocate memory for DLBU core\n")); + } + + return NULL; +} + +void mali_dlbu_delete(struct mali_dlbu_core *dlbu) +{ + mali_dlbu_reset(dlbu); + mali_hw_core_delete(&dlbu->hw_core); + _mali_osk_free(dlbu); +} + +void mali_dlbu_enable(struct mali_dlbu_core *dlbu) +{ + u32 wval = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR); + + wval |= 0x1; + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR, wval); +} + +void mali_dlbu_disable(struct mali_dlbu_core *dlbu) +{ + u32 wval = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR); + + wval |= (wval & 0xFFFFFFFE); + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR, wval); +} + +_mali_osk_errcode_t mali_dlbu_enable_pp_core(struct mali_dlbu_core *dlbu, u32 pp_core_enable, u32 val) +{ + u32 wval = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK); + + if((pp_core_enable < mali_pp_get_glob_num_pp_cores()) && ((0 == val) || (1 == val))) /* check for valid input parameters */ + { + if (val == 1) + { + val = (wval | (pp_core_enable <<= 0x1)); + } + if (val == 0) + { + val = (wval & ~(pp_core_enable << 0x1)); + } + wval |= val; + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, wval); + dlbu->pp_cores_mask = wval; + + return _MALI_OSK_ERR_OK; + } + + return _MALI_OSK_ERR_FAULT; +} + +void mali_dlbu_enable_all_pp_cores(struct mali_dlbu_core *dlbu) +{ + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, dlbu->pp_cores_mask); +} + +void mali_dlbu_disable_all_pp_cores(struct mali_dlbu_core *dlbu) +{ + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, 0x0); +} + +void mali_dlbu_setup(struct mali_dlbu_core *dlbu, u8 fb_xdim, u8 fb_ydim, u8 xtilesize, u8 ytilesize, u8 blocksize, u8 xgr0, u8 ygr0, u8 xgr1, u8 ygr1) +{ + u32 wval = 0x0; + + /* write the framebuffer dimensions */ + wval = (16 << (u32)fb_ydim) | (u32)fb_xdim; + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_FB_DIM, wval); + + /* write the tile list configuration */ + wval = 0x0; + wval = (28 << (u32)blocksize) | (16 << (u32)ytilesize) | ((u32)xtilesize); + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_TLLIST_CONF, wval); + + /* write the start tile position */ + wval = 0x0; + wval = (24 << (u32)ygr1 | (16 << (u32)xgr1) | 8 << (u32)ygr0) | (u32)xgr0; + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_START_TILE_POS, wval); +} + +_mali_osk_errcode_t mali_dlbu_reset(struct mali_dlbu_core *dlbu) +{ + _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT; + MALI_DEBUG_ASSERT_POINTER(dlbu); + + MALI_DEBUG_PRINT(4, ("Mali DLBU: mali_dlbu_reset: %s\n", dlbu->hw_core.description)); + + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR, mali_dlbu_phys_addr); + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_TLLIST_VBASEADDR, 0x00); + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_FB_DIM, 0x00); + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_TLLIST_CONF, 0x00); + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_START_TILE_POS, 0x00); + + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, dlbu->pp_cores_mask); + + err = _MALI_OSK_ERR_OK; + + return err; +} + +_mali_osk_errcode_t mali_dlbu_add_group(struct mali_dlbu_core *dlbu, struct mali_group *group) +{ + _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT; + u32 wval, rval; + struct mali_pp_core *pp_core = mali_group_get_pp_core(group); + + /* find the core id and set the mask */ + + if (NULL != pp_core) + { + wval = mali_pp_core_get_id(pp_core); + rval = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK); + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, (wval << 0x1) | rval); + err = _MALI_OSK_ERR_OK; + } + + return err; +} + +void mali_dlbu_set_tllist_base_address(struct mali_dlbu_core *dlbu, u32 val) +{ + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_TLLIST_VBASEADDR, val); +} + +void mali_dlbu_pp_jobs_stop(struct mali_dlbu_core *dlbu) +{ + /* this function to implement (see documentation): + * 1) clear all bits in the enable register + * 2) wait until all PPs have finished - mali_pp_scheduler.c code - this done in interrupts call? + * 3) read the current tile position registers to get current tile positions - + * note that current tile position register is the same as start tile position - perhaps the name should be changed!!! */ + + /* 1) */ + mali_dlbu_disable_all_pp_cores(dlbu); + + /* 3) */ + mali_dlbu_tile_position = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_START_TILE_POS); +} + +void mali_dlbu_pp_jobs_restart(struct mali_dlbu_core *dlbu) +{ + /* this function to implement (see the document): + * 1) configure the dynamic load balancing unit as normal + * 2) set the current tile position registers as read when stopping the job + * 3) configure the PPs to start the job as normal - done by another part of the system - scheduler */ + + /* 1) */ + mali_dlbu_reset(dlbu); + /* ++ setup the needed values - see this */ + + /* 2) */ + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_START_TILE_POS, mali_dlbu_tile_position); +} diff --git a/drivers/media/video/samsung/mali/common/mali_dlbu.h b/drivers/media/video/samsung/mali/common/mali_dlbu.h new file mode 100644 index 0000000..e3c3b9d --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_dlbu.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_DLBU_H__ +#define __MALI_DLBU_H__ + +#include "mali_osk.h" +#include "mali_group.h" + +#define MALI_DLB_VIRT_ADDR 0xFFF00000 /* master tile virtual address fixed at this value and mapped into every session */ + +extern u32 mali_dlbu_phys_addr; + +struct mali_dlbu_core; + +_mali_osk_errcode_t mali_dlbu_initialize(void); +void mali_dlbu_terminate(void); + +struct mali_dlbu_core *mali_dlbu_create(const _mali_osk_resource_t * resource); +void mali_dlbu_delete(struct mali_dlbu_core *dlbu); + +void mali_dlbu_enable(struct mali_dlbu_core *dlbu); +void mali_dlbu_disable(struct mali_dlbu_core *dlbu); + +_mali_osk_errcode_t mali_dlbu_enable_pp_core(struct mali_dlbu_core *dlbu, u32 pp_core_enable, u32 val); +void mali_dlbu_enable_all_pp_cores(struct mali_dlbu_core *dlbu); +void mali_dlbu_disable_all_pp_cores(struct mali_dlbu_core *dlbu); + +_mali_osk_errcode_t mali_dlbu_reset(struct mali_dlbu_core *dlbu); +void mali_dlbu_setup(struct mali_dlbu_core *dlbu, u8 fb_xdim, u8 fb_ydim, u8 xtilesize, u8 ytilesize, u8 blocksize, u8 xgr0, u8 ygr0, u8 xgr1, u8 ygr1); + +_mali_osk_errcode_t mali_dlbu_add_group(struct mali_dlbu_core *dlbu, struct mali_group *group); +void mali_dlbu_set_tllist_base_address(struct mali_dlbu_core *dlbu, u32 val); + +void mali_dlbu_pp_jobs_stop(struct mali_dlbu_core *dlbu); +void mali_dlbu_pp_jobs_restart(struct mali_dlbu_core *dlbu); + +#endif /* __MALI_DLBU_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_gp.c b/drivers/media/video/samsung/mali/common/mali_gp.c new file mode 100644 index 0000000..1624e46 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_gp.c @@ -0,0 +1,746 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_gp.h" +#include "mali_hw_core.h" +#include "mali_group.h" +#include "mali_osk.h" +#include "regs/mali_gp_regs.h" +#include "mali_kernel_common.h" +#include "mali_kernel_core.h" +#if MALI_TIMELINE_PROFILING_ENABLED +#include "mali_osk_profiling.h" +#endif + +/** + * Definition of the GP core struct + * Used to track a GP core in the system. + */ +struct mali_gp_core +{ + struct mali_hw_core hw_core; /**< Common for all HW cores */ + struct mali_group *group; /**< Parent group for this core */ + _mali_osk_irq_t *irq; /**< IRQ handler */ + struct mali_gp_job *running_job; /**< Current running job */ + _mali_osk_timer_t *timeout_timer; /**< timeout timer for this core */ + u32 timeout_job_id; /**< job id for the timed out job - relevant only if gp_core_timed_out == MALI_TRUE */ + mali_bool core_timed_out; /**< if MALI_TRUE, this gp core has timed out; if MALI_FALSE, no timeout on this gp core */ + u32 counter_src0; /**< Performance counter 0, MALI_HW_CORE_NO_COUNTER for disabled */ + u32 counter_src1; /**< Performance counter 1, MALI_HW_CORE_NO_COUNTER for disabled */ + u32 counter_src0_used; /**< The selected performance counter 0 when a job is running */ + u32 counter_src1_used; /**< The selected performance counter 1 when a job is running */ +}; + +static struct mali_gp_core *mali_global_gp_core = NULL; + +/* Interrupt handlers */ +static _mali_osk_errcode_t mali_gp_upper_half(void *data); +static void mali_gp_bottom_half(void *data); +static void mali_gp_irq_probe_trigger(void *data); +static _mali_osk_errcode_t mali_gp_irq_probe_ack(void *data); +static void mali_gp_post_process_job(struct mali_gp_core *core, mali_bool suspend); +static void mali_gp_timeout(void *data); + +struct mali_gp_core *mali_gp_create(const _mali_osk_resource_t * resource, struct mali_group *group) +{ + struct mali_gp_core* core = NULL; + + MALI_DEBUG_ASSERT(NULL == mali_global_gp_core); + MALI_DEBUG_PRINT(2, ("Mali GP: Creating Mali GP core: %s\n", resource->description)); + + core = _mali_osk_malloc(sizeof(struct mali_gp_core)); + if (NULL != core) + { + core->group = group; + core->running_job = NULL; + core->counter_src0 = MALI_HW_CORE_NO_COUNTER; + core->counter_src1 = MALI_HW_CORE_NO_COUNTER; + core->counter_src0_used = MALI_HW_CORE_NO_COUNTER; + core->counter_src1_used = MALI_HW_CORE_NO_COUNTER; + if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALIGP2_REGISTER_ADDRESS_SPACE_SIZE)) + { + _mali_osk_errcode_t ret; + + mali_group_lock(group); + ret = mali_gp_reset(core); + mali_group_unlock(group); + + if (_MALI_OSK_ERR_OK == ret) + { + /* Setup IRQ handlers (which will do IRQ probing if needed) */ + core->irq = _mali_osk_irq_init(resource->irq, + mali_gp_upper_half, + mali_gp_bottom_half, + mali_gp_irq_probe_trigger, + mali_gp_irq_probe_ack, + core, + "mali_gp_irq_handlers"); + if (NULL != core->irq) + { + /* Initialise the timeout timer */ + core->timeout_timer = _mali_osk_timer_init(); + if(NULL != core->timeout_timer) + { + _mali_osk_timer_setcallback(core->timeout_timer, mali_gp_timeout, (void *)core); + MALI_DEBUG_PRINT(4, ("Mali GP: set global gp core from 0x%08X to 0x%08X\n", mali_global_gp_core, core)); + mali_global_gp_core = core; + + return core; + } + else + { + MALI_PRINT_ERROR(("Failed to setup timeout timer for GP core %s\n", core->hw_core.description)); + /* Release IRQ handlers */ + _mali_osk_irq_term(core->irq); + } + } + else + { + MALI_PRINT_ERROR(("Failed to setup interrupt handlers for GP core %s\n", core->hw_core.description)); + } + } + mali_hw_core_delete(&core->hw_core); + } + + _mali_osk_free(core); + } + else + { + MALI_PRINT_ERROR(("Failed to allocate memory for GP core\n")); + } + + return NULL; +} + +void mali_gp_delete(struct mali_gp_core *core) +{ + MALI_DEBUG_ASSERT_POINTER(core); + + _mali_osk_timer_term(core->timeout_timer); + _mali_osk_irq_term(core->irq); + mali_hw_core_delete(&core->hw_core); + mali_global_gp_core = NULL; + _mali_osk_free(core); +} + +void mali_gp_stop_bus(struct mali_gp_core *core) +{ + MALI_DEBUG_ASSERT_POINTER(core); + + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_STOP_BUS); +} + +_mali_osk_errcode_t mali_gp_stop_bus_wait(struct mali_gp_core *core) +{ + int i; + const int request_loop_count = 20; + + MALI_DEBUG_ASSERT_POINTER(core); + + /* Send the stop bus command. */ + mali_gp_stop_bus(core); + + /* Wait for bus to be stopped */ + for (i = 0; i < request_loop_count; i++) + { + if (mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS) & MALIGP2_REG_VAL_STATUS_BUS_STOPPED) + { + break; + } + _mali_osk_time_ubusydelay(10); + } + + if (request_loop_count == i) + { + MALI_PRINT_ERROR(("Mali GP: Failed to stop bus on %s\n", core->hw_core.description)); + return _MALI_OSK_ERR_FAULT; + } + return _MALI_OSK_ERR_OK; +} + +void mali_gp_hard_reset(struct mali_gp_core *core) +{ + const int reset_finished_loop_count = 15; + const u32 reset_wait_target_register = MALIGP2_REG_ADDR_MGMT_WRITE_BOUND_LOW; + const u32 reset_invalid_value = 0xC0FFE000; + const u32 reset_check_value = 0xC01A0000; + const u32 reset_default_value = 0; + int i; + + MALI_DEBUG_ASSERT_POINTER(core); + MALI_DEBUG_PRINT(4, ("Mali GP: Hard reset of core %s\n", core->hw_core.description)); + MALI_ASSERT_GROUP_LOCKED(core->group); + + mali_gp_post_process_job(core, MALI_FALSE); + + mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, reset_invalid_value); + + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_RESET); + + for (i = 0; i < reset_finished_loop_count; i++) + { + mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, reset_check_value); + if (reset_check_value == mali_hw_core_register_read(&core->hw_core, reset_wait_target_register)) + { + break; + } + } + + if (i == reset_finished_loop_count) + { + MALI_PRINT_ERROR(("Mali GP: The hard reset loop didn't work, unable to recover\n")); + } + + mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, reset_default_value); /* set it back to the default */ + /* Re-enable interrupts */ + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL); + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED); + +} + +_mali_osk_errcode_t mali_gp_reset(struct mali_gp_core *core) +{ + int i; + const int request_loop_count = 20; + + MALI_DEBUG_ASSERT_POINTER(core); + MALI_DEBUG_PRINT(4, ("Mali GP: Reset of core %s\n", core->hw_core.description)); + MALI_ASSERT_GROUP_LOCKED(core->group); + + mali_gp_post_process_job(core, MALI_FALSE); + + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, 0); /* disable the IRQs */ + +#if defined(USING_MALI200) + + /* On Mali-200, stop the bus, then do a hard reset of the core */ + + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_STOP_BUS); + + for (i = 0; i < request_loop_count; i++) + { + if (mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS) & MALIGP2_REG_VAL_STATUS_BUS_STOPPED) + { + break; + } + _mali_osk_time_ubusydelay(10); + } + + if (request_loop_count == i) + { + MALI_PRINT_ERROR(("Mali GP: Failed to stop bus for core %s, unable to recover\n", core->hw_core.description)); + return _MALI_OSK_ERR_FAULT; + } + + /* the bus was stopped OK, do the hard reset */ + mali_gp_hard_reset(core); + +#elif defined(USING_MALI400) + + /* Mali-300 and Mali-400 have a safe reset command which we use */ + + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALI400GP_REG_VAL_IRQ_RESET_COMPLETED); + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALI400GP_REG_VAL_CMD_SOFT_RESET); + + for (i = 0; i < request_loop_count; i++) + { + if (mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT) & MALI400GP_REG_VAL_IRQ_RESET_COMPLETED) + { + break; + } + _mali_osk_time_ubusydelay(10); + } + + if (request_loop_count == i) + { + MALI_PRINT_ERROR(("Mali GP: Failed to reset core %s, unable to recover\n", core->hw_core.description)); + return _MALI_OSK_ERR_FAULT; + } +#else +#error "no supported mali core defined" +#endif + + /* Re-enable interrupts */ + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL); + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED); + + return _MALI_OSK_ERR_OK; +} + +void mali_gp_job_start(struct mali_gp_core *core, struct mali_gp_job *job) +{ + u32 startcmd = 0; + u32 *frame_registers = mali_gp_job_get_frame_registers(job); + core->counter_src0_used = core->counter_src0; + core->counter_src1_used = core->counter_src1; + + MALI_DEBUG_ASSERT_POINTER(core); + MALI_ASSERT_GROUP_LOCKED(core->group); + + if (mali_gp_job_has_vs_job(job)) + { + startcmd |= (u32) MALIGP2_REG_VAL_CMD_START_VS; + } + + if (mali_gp_job_has_plbu_job(job)) + { + startcmd |= (u32) MALIGP2_REG_VAL_CMD_START_PLBU; + } + + MALI_DEBUG_ASSERT(0 != startcmd); + + mali_hw_core_register_write_array_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR, frame_registers, MALIGP2_NUM_REGS_FRAME); + +#if PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH + { + /* Read hits and Read misses*/ + mali_l2_cache_core_set_counter_src0(mali_l2_cache_core_get_glob_l2_core(0), 20); + mali_l2_cache_core_set_counter_src1(mali_l2_cache_core_get_glob_l2_core(0), 21); + } +#endif + + /* This selects which performance counters we are reading */ + if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used || MALI_HW_CORE_NO_COUNTER != core->counter_src0_used) + { + /* global_config has enabled HW counters, this will override anything specified by user space */ + if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used) + { + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used); + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE); + } + if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used) + { + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used); + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE); + } + } + else + { + /* Use HW counters from job object, if any */ + u32 perf_counter_flag = mali_gp_job_get_perf_counter_flag(job); + if (0 != perf_counter_flag) + { + if (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE) + { + core->counter_src0_used = mali_gp_job_get_perf_counter_src0(job); + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used); + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE); + } + + if (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE) + { + core->counter_src1_used = mali_gp_job_get_perf_counter_src1(job); + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used); + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE); + } + } + } + + MALI_DEBUG_PRINT(3, ("Mali GP: Starting job (0x%08x) on core %s with command 0x%08X\n", job, core->hw_core.description, startcmd)); + + /* Barrier to make sure the previous register write is finished */ + _mali_osk_write_mem_barrier(); + + /* This is the command that starts the core. */ + mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, startcmd); + + /* Barrier to make sure the previous register write is finished */ + _mali_osk_write_mem_barrier(); + + /* Setup the timeout timer value and save the job id for the job running on the gp core */ + + _mali_osk_timer_add(core->timeout_timer, _mali_osk_time_mstoticks(mali_max_job_runtime)); + core->timeout_job_id = mali_gp_job_get_id(job); + +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0) | MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH, + job->frame_builder_id, job->flush_id, 0, 0, 0); + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0), job->pid, job->tid, 0, 0, 0); +#endif + + core->running_job = job; +} + +void mali_gp_resume_with_new_heap(struct mali_gp_core *core, u32 start_addr, u32 end_addr) +{ + u32 irq_readout; + + MALI_DEBUG_ASSERT_POINTER(core); + MALI_ASSERT_GROUP_LOCKED(core->group); + + irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT); + + if (irq_readout & MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM) + { + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, (MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | MALIGP2_REG_VAL_IRQ_HANG)); + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED); /* re-enable interrupts */ + mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR, start_addr); + mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR, end_addr); + + MALI_DEBUG_PRINT(3, ("Mali GP: Resuming job\n")); + + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_UPDATE_PLBU_ALLOC); + _mali_osk_write_mem_barrier(); + +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_RESUME|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0), 0, 0, 0, 0, 0); +#endif + } + /* + * else: core has been reset between PLBU_OUT_OF_MEM interrupt and this new heap response. + * A timeout or a page fault on Mali-200 PP core can cause this behaviour. + */ +} + +void mali_gp_abort_job(struct mali_gp_core *core) +{ + MALI_DEBUG_ASSERT_POINTER(core); + MALI_ASSERT_GROUP_LOCKED(core->group); + + if (_MALI_OSK_ERR_FAULT != mali_gp_reset(core)) + { + _mali_osk_timer_del(core->timeout_timer); + } +} + +u32 mali_gp_core_get_version(struct mali_gp_core *core) +{ + MALI_DEBUG_ASSERT_POINTER(core); + return mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_VERSION); +} + +mali_bool mali_gp_core_set_counter_src0(struct mali_gp_core *core, u32 counter) +{ + MALI_DEBUG_ASSERT_POINTER(core); + + core->counter_src0 = counter; + return MALI_TRUE; +} + +mali_bool mali_gp_core_set_counter_src1(struct mali_gp_core *core, u32 counter) +{ + MALI_DEBUG_ASSERT_POINTER(core); + + core->counter_src1 = counter; + return MALI_TRUE; +} + +u32 mali_gp_core_get_counter_src0(struct mali_gp_core *core) +{ + MALI_DEBUG_ASSERT_POINTER(core); + return core->counter_src0; +} + +u32 mali_gp_core_get_counter_src1(struct mali_gp_core *core) +{ + MALI_DEBUG_ASSERT_POINTER(core); + return core->counter_src1; +} + +struct mali_gp_core *mali_gp_get_global_gp_core(void) +{ + return mali_global_gp_core; +} + +/* ------------- interrupt handling below ------------------ */ +static _mali_osk_errcode_t mali_gp_upper_half(void *data) +{ + struct mali_gp_core *core = (struct mali_gp_core *)data; + u32 irq_readout; + + irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_STAT); + if (MALIGP2_REG_VAL_IRQ_MASK_NONE != irq_readout) + { + /* Mask out all IRQs from this core until IRQ is handled */ + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_NONE); + +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0)|MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT, irq_readout, 0, 0, 0, 0); +#endif + + /* We do need to handle this in a bottom half */ + _mali_osk_irq_schedulework(core->irq); + return _MALI_OSK_ERR_OK; + } + + return _MALI_OSK_ERR_FAULT; +} + +static void mali_gp_bottom_half(void *data) +{ + struct mali_gp_core *core = (struct mali_gp_core *)data; + u32 irq_readout; + u32 irq_errors; + +#if MALI_TIMELINE_PROFILING_ENABLED +#if 0 /* Bottom half TLP logging is currently not supported */ + _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_START| MALI_PROFILING_EVENT_CHANNEL_SOFTWARE , _mali_osk_get_pid(), _mali_osk_get_tid()+11000, 0, 0, 0); +#endif +#endif + + mali_group_lock(core->group); /* Group lock grabbed in core handlers, but released in common group handler */ + + if ( MALI_FALSE == mali_group_power_is_on(core->group) ) + { + MALI_PRINT_ERROR(("Interrupt bottom half of %s when core is OFF.", core->hw_core.description)); + mali_group_unlock(core->group); + return; + } + + irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT) & MALIGP2_REG_VAL_IRQ_MASK_USED; + MALI_DEBUG_PRINT(4, ("Mali GP: Bottom half IRQ 0x%08X from core %s\n", irq_readout, core->hw_core.description)); + + if (irq_readout & (MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST|MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST)) + { + u32 core_status = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS); + if (0 == (core_status & MALIGP2_REG_VAL_STATUS_MASK_ACTIVE)) + { + mali_gp_post_process_job(core, MALI_FALSE); + MALI_DEBUG_PRINT(4, ("Mali GP: Job completed, calling group handler\n")); + mali_group_bottom_half(core->group, GROUP_EVENT_GP_JOB_COMPLETED); /* Will release group lock */ + return; + } + } + + /* + * Now lets look at the possible error cases (IRQ indicating error or timeout) + * END_CMD_LST, HANG and PLBU_OOM interrupts are not considered error. + */ + irq_errors = irq_readout & ~(MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST|MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST|MALIGP2_REG_VAL_IRQ_HANG|MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM); + if (0 != irq_errors) + { + mali_gp_post_process_job(core, MALI_FALSE); + MALI_PRINT_ERROR(("Mali GP: Unknown interrupt 0x%08X from core %s, aborting job\n", irq_readout, core->hw_core.description)); + mali_group_bottom_half(core->group, GROUP_EVENT_GP_JOB_FAILED); /* Will release group lock */ + return; + } + else if (MALI_TRUE == core->core_timed_out) /* SW timeout */ + { + if (core->timeout_job_id == mali_gp_job_get_id(core->running_job)) + { + mali_gp_post_process_job(core, MALI_FALSE); + MALI_DEBUG_PRINT(2, ("Mali GP: Job %d timed out\n", mali_gp_job_get_id(core->running_job))); + mali_group_bottom_half(core->group, GROUP_EVENT_GP_JOB_TIMED_OUT); + } + core->core_timed_out = MALI_FALSE; + return; + } + else if (irq_readout & MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM) + { + /* GP wants more memory in order to continue. + * + * This must be handled prior to HANG because this actually can + * generate a HANG while waiting for more memory. + * And it must be handled before the completion interrupts, + * since the PLBU can run out of memory after VS is complete; + * in which case the OOM must be handled before to complete the + * PLBU work. + */ + mali_gp_post_process_job(core, MALI_TRUE); + MALI_DEBUG_PRINT(3, ("Mali GP: PLBU needs more heap memory\n")); + mali_group_bottom_half(core->group, GROUP_EVENT_GP_OOM); /* Will release group lock */ + return; + } + else if (irq_readout & MALIGP2_REG_VAL_IRQ_HANG) + { + /* Just ignore hang interrupts, the job timer will detect hanging jobs anyways */ + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_HANG); + } + + /* + * The only way to get here is if we got a HANG interrupt, which we ignore, or only one of two needed END_CMD_LST interrupts. + * Re-enable interrupts and let core continue to run. + */ + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED); + mali_group_unlock(core->group); + +#if MALI_TIMELINE_PROFILING_ENABLED +#if 0 /* Bottom half TLP logging is currently not supported */ + _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_STOP| MALI_PROFILING_EVENT_CHANNEL_SOFTWARE , _mali_osk_get_pid(), _mali_osk_get_tid()+11000, 0, 0, 0); +#endif +#endif +} + +static void mali_gp_irq_probe_trigger(void *data) +{ + struct mali_gp_core *core = (struct mali_gp_core *)data; + + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED); /* @@@@ This should not be needed */ + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT, MALIGP2_REG_VAL_CMD_FORCE_HANG); + _mali_osk_mem_barrier(); +} + +static _mali_osk_errcode_t mali_gp_irq_probe_ack(void *data) +{ + struct mali_gp_core *core = (struct mali_gp_core *)data; + u32 irq_readout; + + irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_STAT); + if (MALIGP2_REG_VAL_IRQ_FORCE_HANG & irq_readout) + { + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_FORCE_HANG); + _mali_osk_mem_barrier(); + return _MALI_OSK_ERR_OK; + } + + return _MALI_OSK_ERR_FAULT; +} + +/* ------ local helper functions below --------- */ + +static void mali_gp_post_process_job(struct mali_gp_core *core, mali_bool suspend) +{ + MALI_ASSERT_GROUP_LOCKED(core->group); + + if (NULL != core->running_job) + { + u32 val0 = 0; + u32 val1 = 0; +#if MALI_TIMELINE_PROFILING_ENABLED + u32 event_id; +#endif + +#if PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH + { + u32 src0, value0, src1, value1, sum, per_thousand, per_thousand_now, diff0, diff1; + static u32 print_nr=0; + static u32 prev0=0; + static u32 prev1=0; + if ( !(++print_nr&511) ) + { + mali_l2_cache_core_get_counter_values(mali_l2_cache_core_get_glob_l2_core(0), &src0, &value0, &src1, &value1); + MALI_DEBUG_ASSERT( src0==20 ); /* Read hits */ + MALI_DEBUG_ASSERT( src1==21 ); /* Read misses */ + + sum = value0+value1; + if ( sum > 1000000 ) + { + per_thousand = value0 / (sum/1000); + } + else + { + per_thousand = (value0*1000) / (sum); + } + diff0 = value0-prev0; + diff1 = value1-prev1; + + sum = diff0 + diff1 ; + if ( sum > 1000000 ) + { + per_thousand_now = diff0 / (sum/1000); + } + else + { + per_thousand_now = (diff0*1000) / (sum); + } + + prev0=value0; + prev1=value1; + if (per_thousand_now<=1000) + { + MALI_DEBUG_PRINT(2, ("Mali L2: Read hits/misses: %d/%d = %d thousand_parts total, since previous: %d\n", value0, value1, per_thousand, per_thousand_now)); + } + + } + } +#endif + + if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used) + { + val0 = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE); + if (mali_gp_job_get_perf_counter_flag(core->running_job) && + _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE && mali_gp_job_get_perf_counter_src0(core->running_job) == core->counter_src0_used) + { + /* We retrieved the counter that user space asked for, so return the value through the job object */ + mali_gp_job_set_perf_counter_value0(core->running_job, val0); + } + else + { + /* User space asked for a counter, but this is not what we retrived (overridden by counter src set on core) */ + mali_gp_job_set_perf_counter_value0(core->running_job, MALI_HW_CORE_INVALID_VALUE); + } + +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_report_hw_counter(COUNTER_VP_C0, val0); +#endif + + } + + if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used) + { + val1 = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE); + if (mali_gp_job_get_perf_counter_flag(core->running_job) && + _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE && mali_gp_job_get_perf_counter_src1(core->running_job) == core->counter_src1_used) + { + /* We retrieved the counter that user space asked for, so return the value through the job object */ + mali_gp_job_set_perf_counter_value1(core->running_job, val1); + } + else + { + /* User space asked for a counter, but this is not what we retrieved (overridden by counter src set on core) */ + mali_gp_job_set_perf_counter_value1(core->running_job, MALI_HW_CORE_INVALID_VALUE); + } + +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_report_hw_counter(COUNTER_VP_C1, val1); +#endif + } + +#if MALI_TIMELINE_PROFILING_ENABLED + if (MALI_TRUE == suspend) + { + event_id = MALI_PROFILING_EVENT_TYPE_SUSPEND|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0); + } + else + { + event_id = MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0); + } + _mali_osk_profiling_add_event(event_id, val0, val1, core->counter_src0_used | (core->counter_src1_used << 8), 0, 0); +#endif + + mali_gp_job_set_current_heap_addr(core->running_job, + mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR)); + + if (MALI_TRUE != suspend) + { + /* We are no longer running a job... */ + core->running_job = NULL; + _mali_osk_timer_del(core->timeout_timer); + } + } +} + +/* callback function for gp core timeout */ +static void mali_gp_timeout(void *data) +{ + struct mali_gp_core * core = ((struct mali_gp_core *)data); + + MALI_DEBUG_PRINT(3, ("Mali GP: TIMEOUT callback \n")); + core->core_timed_out = MALI_TRUE; + _mali_osk_irq_schedulework(core->irq); +} + +#if 0 +void mali_gp_print_state(struct mali_gp_core *core) +{ + MALI_DEBUG_PRINT(2, ("Mali GP: State: 0x%08x\n", mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS) )); +} +#endif + +#if MALI_STATE_TRACKING +u32 mali_gp_dump_state(struct mali_gp_core *core, char *buf, u32 size) +{ + int n = 0; + + n += _mali_osk_snprintf(buf + n, size - n, "\tGP: %s\n", core->hw_core.description); + + return n; +} +#endif diff --git a/drivers/media/video/samsung/mali/common/mali_gp.h b/drivers/media/video/samsung/mali/common/mali_gp.h new file mode 100644 index 0000000..3175b75 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_gp.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_GP_H__ +#define __MALI_GP_H__ + +#include "mali_osk.h" +#include "mali_gp_job.h" + +struct mali_gp_core; +struct mali_group; + +_mali_osk_errcode_t mali_gp_initialize(void); +void mali_gp_terminate(void); + +struct mali_gp_core *mali_gp_create(const _mali_osk_resource_t * resource, struct mali_group *group); +void mali_gp_delete(struct mali_gp_core *core); + +void mali_gp_stop_bus(struct mali_gp_core *core); +_mali_osk_errcode_t mali_gp_stop_bus_wait(struct mali_gp_core *core); +void mali_gp_hard_reset(struct mali_gp_core *core); +_mali_osk_errcode_t mali_gp_reset(struct mali_gp_core *core); + +void mali_gp_job_start(struct mali_gp_core *core, struct mali_gp_job *job); +void mali_gp_resume_with_new_heap(struct mali_gp_core *core, u32 start_addr, u32 end_addr); + +void mali_gp_abort_job(struct mali_gp_core *core); + +u32 mali_gp_core_get_version(struct mali_gp_core *core); + +mali_bool mali_gp_core_set_counter_src0(struct mali_gp_core *core, u32 counter); +mali_bool mali_gp_core_set_counter_src1(struct mali_gp_core *core, u32 counter); +u32 mali_gp_core_get_counter_src0(struct mali_gp_core *core); +u32 mali_gp_core_get_counter_src1(struct mali_gp_core *core); +struct mali_gp_core *mali_gp_get_global_gp_core(void); + +u32 mali_gp_dump_state(struct mali_gp_core *core, char *buf, u32 size); + +#endif /* __MALI_GP_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_gp_job.c b/drivers/media/video/samsung/mali/common/mali_gp_job.c new file mode 100644 index 0000000..abe1d93 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_gp_job.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_gp_job.h" +#include "mali_osk.h" +#include "mali_osk_list.h" +#include "mali_uk_types.h" + +struct mali_gp_job *mali_gp_job_create(struct mali_session_data *session, _mali_uk_gp_start_job_s *args, u32 id) +{ + struct mali_gp_job *job; + + job = _mali_osk_malloc(sizeof(struct mali_gp_job)); + if (NULL != job) + { + _mali_osk_list_init(&job->list); + job->session = session; + job->id = id; + job->user_id = args->user_job_ptr; + _mali_osk_memcpy(job->frame_registers, args->frame_registers, sizeof(job->frame_registers)); + job->heap_current_addr = args->frame_registers[4]; + job->perf_counter_flag = args->perf_counter_flag; + job->perf_counter_src0 = args->perf_counter_src0; + job->perf_counter_src1 = args->perf_counter_src1; + job->perf_counter_value0 = 0; + job->perf_counter_value1 = 0; + + job->pid = _mali_osk_get_pid(); + job->tid = _mali_osk_get_tid(); + job->frame_builder_id = args->frame_builder_id; + job->flush_id = args->flush_id; + + return job; + } + + return NULL; +} + +void mali_gp_job_delete(struct mali_gp_job *job) +{ + _mali_osk_free(job); +} diff --git a/drivers/media/video/samsung/mali/common/mali_gp_job.h b/drivers/media/video/samsung/mali/common/mali_gp_job.h new file mode 100644 index 0000000..9c29f1c --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_gp_job.h @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_GP_JOB_H__ +#define __MALI_GP_JOB_H__ + +#include "mali_osk.h" +#include "mali_osk_list.h" +#include "mali_uk_types.h" +#include "mali_session.h" + +/** + * The structure represends a GP job, including all sub-jobs + * (This struct unfortunatly needs to be public because of how the _mali_osk_list_* + * mechanism works) + */ +struct mali_gp_job +{ + _mali_osk_list_t list; /**< Used to link jobs together in the scheduler queue */ + struct mali_session_data *session; /**< Session which submitted this job */ + u32 id; /**< identifier for this job in kernel space (sequential numbering) */ + u32 user_id; /**< identifier for the job in user space */ + u32 frame_registers[MALIGP2_NUM_REGS_FRAME]; /**< core specific registers associated with this job, see ARM DDI0415A */ + u32 heap_current_addr; /**< Holds the current HEAP address when the job has completed */ + u32 perf_counter_flag; /**< bitmask indicating which performance counters to enable, see \ref _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE and related macro definitions */ + u32 perf_counter_src0; /**< source id for performance counter 0 (see ARM DDI0415A, Table 3-60) */ + u32 perf_counter_src1; /**< source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */ + u32 perf_counter_value0; /**< Value of performance counter 0 (to be returned to user space) */ + u32 perf_counter_value1; /**< Value of performance counter 1 (to be returned to user space) */ + u32 pid; /**< Process ID of submitting process */ + u32 tid; /**< Thread ID of submitting thread */ + u32 frame_builder_id; /**< id of the originating frame builder */ + u32 flush_id; /**< flush id within the originating frame builder */ +}; + +struct mali_gp_job *mali_gp_job_create(struct mali_session_data *session, _mali_uk_gp_start_job_s *args, u32 id); +void mali_gp_job_delete(struct mali_gp_job *job); + +MALI_STATIC_INLINE u32 mali_gp_job_get_id(struct mali_gp_job *job) +{ + return (NULL == job) ? 0 : job->id; +} + +MALI_STATIC_INLINE u32 mali_gp_job_get_user_id(struct mali_gp_job *job) +{ + return job->user_id; +} + +MALI_STATIC_INLINE u32 mali_gp_job_get_frame_builder_id(struct mali_gp_job *job) +{ + return job->frame_builder_id; +} + +MALI_STATIC_INLINE u32 mali_gp_job_get_flush_id(struct mali_gp_job *job) +{ + return job->flush_id; +} + +MALI_STATIC_INLINE u32* mali_gp_job_get_frame_registers(struct mali_gp_job *job) +{ + return job->frame_registers; +} + +MALI_STATIC_INLINE struct mali_session_data *mali_gp_job_get_session(struct mali_gp_job *job) +{ + return job->session; +} + +MALI_STATIC_INLINE mali_bool mali_gp_job_has_vs_job(struct mali_gp_job *job) +{ + return (job->frame_registers[0] != job->frame_registers[1]) ? MALI_TRUE : MALI_FALSE; +} + +MALI_STATIC_INLINE mali_bool mali_gp_job_has_plbu_job(struct mali_gp_job *job) +{ + return (job->frame_registers[2] != job->frame_registers[3]) ? MALI_TRUE : MALI_FALSE; +} + +MALI_STATIC_INLINE u32 mali_gp_job_get_current_heap_addr(struct mali_gp_job *job) +{ + return job->heap_current_addr; +} + +MALI_STATIC_INLINE void mali_gp_job_set_current_heap_addr(struct mali_gp_job *job, u32 heap_addr) +{ + job->heap_current_addr = heap_addr; +} + +MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_flag(struct mali_gp_job *job) +{ + return job->perf_counter_flag; +} + +MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_src0(struct mali_gp_job *job) +{ + return job->perf_counter_src0; +} + +MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_src1(struct mali_gp_job *job) +{ + return job->perf_counter_src1; +} + +MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_value0(struct mali_gp_job *job) +{ + return job->perf_counter_value0; +} + +MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_value1(struct mali_gp_job *job) +{ + return job->perf_counter_value1; +} + +MALI_STATIC_INLINE void mali_gp_job_set_perf_counter_value0(struct mali_gp_job *job, u32 value) +{ + job->perf_counter_value0 = value; +} + +MALI_STATIC_INLINE void mali_gp_job_set_perf_counter_value1(struct mali_gp_job *job, u32 value) +{ + job->perf_counter_value1 = value; +} + +#endif /* __MALI_GP_JOB_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_gp_scheduler.c b/drivers/media/video/samsung/mali/common/mali_gp_scheduler.c new file mode 100644 index 0000000..f06d899 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_gp_scheduler.c @@ -0,0 +1,443 @@ +/* + * Copyright (C) 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_gp_scheduler.h" +#include "mali_kernel_common.h" +#include "mali_osk.h" +#include "mali_osk_list.h" +#include "mali_scheduler.h" +#include "mali_gp.h" +#include "mali_gp_job.h" +#include "mali_group.h" +#include "mali_cluster.h" + +enum mali_gp_slot_state +{ + MALI_GP_SLOT_STATE_IDLE, + MALI_GP_SLOT_STATE_WORKING, +}; + +/* A render slot is an entity which jobs can be scheduled onto */ +struct mali_gp_slot +{ + struct mali_group *group; + /* + * We keep track of the state here as well as in the group object + * so we don't need to take the group lock so often (and also avoid clutter with the working lock) + */ + enum mali_gp_slot_state state; + u32 returned_cookie; +}; + +static u32 gp_version = 0; +static _MALI_OSK_LIST_HEAD(job_queue); /* List of jobs with some unscheduled work */ +static struct mali_gp_slot slot; + +/* Variables to allow safe pausing of the scheduler */ +static _mali_osk_wait_queue_t *gp_scheduler_working_wait_queue = NULL; +static u32 pause_count = 0; + +static mali_bool mali_gp_scheduler_is_suspended(void); + +static _mali_osk_lock_t *gp_scheduler_lock = NULL; +/* Contains tid of thread that locked the scheduler or 0, if not locked */ + +_mali_osk_errcode_t mali_gp_scheduler_initialize(void) +{ + u32 i; + + _MALI_OSK_INIT_LIST_HEAD(&job_queue); + + gp_scheduler_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_SCHEDULER); + if (NULL == gp_scheduler_lock) + { + return _MALI_OSK_ERR_NOMEM; + } + + gp_scheduler_working_wait_queue = _mali_osk_wait_queue_init(); + if (NULL == gp_scheduler_working_wait_queue) + { + _mali_osk_lock_term(gp_scheduler_lock); + return _MALI_OSK_ERR_NOMEM; + } + + /* Find all the available GP cores */ + for (i = 0; i < mali_cluster_get_glob_num_clusters(); i++) + { + u32 group_id = 0; + struct mali_cluster *curr_cluster = mali_cluster_get_global_cluster(i); + struct mali_group *group = mali_cluster_get_group(curr_cluster, group_id); + while (NULL != group) + { + struct mali_gp_core *gp_core = mali_group_get_gp_core(group); + if (NULL != gp_core) + { + if (0 == gp_version) + { + /* Retrieve GP version */ + gp_version = mali_gp_core_get_version(gp_core); + } + slot.group = group; + slot.state = MALI_GP_SLOT_STATE_IDLE; + break; /* There are only one GP, no point in looking for more */ + } + group_id++; + group = mali_cluster_get_group(curr_cluster, group_id); + } + } + + return _MALI_OSK_ERR_OK; +} + +void mali_gp_scheduler_terminate(void) +{ + _mali_osk_wait_queue_term(gp_scheduler_working_wait_queue); + _mali_osk_lock_term(gp_scheduler_lock); +} + +MALI_STATIC_INLINE void mali_gp_scheduler_lock(void) +{ + if(_MALI_OSK_ERR_OK != _mali_osk_lock_wait(gp_scheduler_lock, _MALI_OSK_LOCKMODE_RW)) + { + /* Non-interruptable lock failed: this should never happen. */ + MALI_DEBUG_ASSERT(0); + } + MALI_DEBUG_PRINT(5, ("Mali GP scheduler: GP scheduler lock taken\n")); +} + +MALI_STATIC_INLINE void mali_gp_scheduler_unlock(void) +{ + MALI_DEBUG_PRINT(5, ("Mali GP scheduler: Releasing GP scheduler lock\n")); + _mali_osk_lock_signal(gp_scheduler_lock, _MALI_OSK_LOCKMODE_RW); +} + +#ifdef DEBUG +MALI_STATIC_INLINE void mali_gp_scheduler_assert_locked(void) +{ + MALI_DEBUG_ASSERT_LOCK_HELD(gp_scheduler_lock); +} +#define MALI_ASSERT_GP_SCHEDULER_LOCKED() mali_gp_scheduler_assert_locked() +#else +#define MALI_ASSERT_GP_SCHEDULER_LOCKED() +#endif + +static void mali_gp_scheduler_schedule(void) +{ + struct mali_gp_job *job; + + MALI_ASSERT_GP_SCHEDULER_LOCKED(); + + if (0 < pause_count || MALI_GP_SLOT_STATE_IDLE != slot.state || _mali_osk_list_empty(&job_queue)) + { + MALI_DEBUG_PRINT(4, ("Mali GP scheduler: Nothing to schedule (paused=%u, idle slots=%u)\n", + pause_count, MALI_GP_SLOT_STATE_IDLE == slot.state ? 1 : 0)); + return; /* Nothing to do, so early out */ + } + + job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_gp_job, list); + + MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Starting job %u (0x%08X)\n", mali_gp_job_get_id(job), job)); + if (_MALI_OSK_ERR_OK == mali_group_start_gp_job(slot.group, job)) + { + /* Mark slot as busy */ + slot.state = MALI_GP_SLOT_STATE_WORKING; + + /* Remove from queue of unscheduled jobs */ + _mali_osk_list_del(&job->list); + } + else + { + MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Failed to start GP job\n")); + } +} + +static void mali_gp_scheduler_return_job_to_user(struct mali_gp_job *job, mali_bool success) +{ + _mali_osk_notification_t *notobj = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_FINISHED, sizeof(_mali_uk_gp_job_finished_s)); + if (NULL != notobj) + { + _mali_uk_gp_job_finished_s *jobres = notobj->result_buffer; + _mali_osk_memset(jobres, 0, sizeof(_mali_uk_gp_job_finished_s)); /* @@@@ can be removed once we initialize all members in this struct */ + jobres->user_job_ptr = mali_gp_job_get_user_id(job); + if (MALI_TRUE == success) + { + jobres->status = _MALI_UK_JOB_STATUS_END_SUCCESS; + } + else + { + jobres->status = _MALI_UK_JOB_STATUS_END_UNKNOWN_ERR; + } + + jobres->heap_current_addr = mali_gp_job_get_current_heap_addr(job); + jobres->perf_counter0 = mali_gp_job_get_perf_counter_value0(job); + jobres->perf_counter1 = mali_gp_job_get_perf_counter_value1(job); + + mali_session_send_notification(mali_gp_job_get_session(job), notobj); + } + else + { + MALI_PRINT_ERROR(("Mali GP scheduler: Unable to allocate notification object\n")); + } + + mali_gp_job_delete(job); +} + + +void mali_gp_scheduler_do_schedule(void) +{ + mali_gp_scheduler_lock(); + + mali_gp_scheduler_schedule(); + + mali_gp_scheduler_unlock(); +} + +void mali_gp_scheduler_job_done(struct mali_group *group, struct mali_gp_job *job, mali_bool success) +{ + MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Job %u (0x%08X) completed (%s)\n", mali_gp_job_get_id(job), job, success ? "success" : "failure")); + + mali_gp_scheduler_lock(); + + /* Mark slot as idle again */ + slot.state = MALI_GP_SLOT_STATE_IDLE; + + /* If paused, then this was the last job, so wake up sleeping workers */ + if (pause_count > 0) + { + _mali_osk_wait_queue_wake_up(gp_scheduler_working_wait_queue); + } + else + { + mali_gp_scheduler_schedule(); + } + + mali_gp_scheduler_unlock(); + + mali_gp_scheduler_return_job_to_user(job, success); +} + +void mali_gp_scheduler_oom(struct mali_group *group, struct mali_gp_job *job) +{ + _mali_osk_notification_t *notobj; + + notobj = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_STALLED, sizeof(_mali_uk_gp_job_suspended_s)); + + if (NULL != notobj) + { + _mali_uk_gp_job_suspended_s * jobres; + + mali_gp_scheduler_lock(); + + jobres = (_mali_uk_gp_job_suspended_s *)notobj->result_buffer; + + jobres->user_job_ptr = mali_gp_job_get_user_id(job); + jobres->reason = _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY; + jobres->cookie = mali_gp_job_get_id(job); + slot.returned_cookie = jobres->cookie; + + mali_session_send_notification(mali_gp_job_get_session(job), notobj); + + mali_gp_scheduler_unlock(); + } + + /* + * If this function failed, then we could return the job to user space right away, + * but there is a job timer anyway that will do that eventually. + * This is not exactly a common case anyway. + */ +} + +void mali_gp_scheduler_suspend(void) +{ + mali_gp_scheduler_lock(); + pause_count++; /* Increment the pause_count so that no more jobs will be scheduled */ + mali_gp_scheduler_unlock(); + + _mali_osk_wait_queue_wait_event(gp_scheduler_working_wait_queue, mali_gp_scheduler_is_suspended); +} + +void mali_gp_scheduler_resume(void) +{ + mali_gp_scheduler_lock(); + pause_count--; /* Decrement pause_count to allow scheduling again (if it reaches 0) */ + if (0 == pause_count) + { + mali_gp_scheduler_schedule(); + } + mali_gp_scheduler_unlock(); +} + +_mali_osk_errcode_t _mali_ukk_gp_start_job(_mali_uk_gp_start_job_s *args) +{ + struct mali_session_data *session; + struct mali_gp_job *job; + + MALI_DEBUG_ASSERT_POINTER(args); + + if (NULL == args->ctx) + { + return _MALI_OSK_ERR_INVALID_ARGS; + } + + session = (struct mali_session_data*)args->ctx; + if (NULL == session) + { + return _MALI_OSK_ERR_FAULT; + } + + job = mali_gp_job_create(session, args, mali_scheduler_get_new_id()); + if (NULL == job) + { + return _MALI_OSK_ERR_NOMEM; + } + +#if PROFILING_SKIP_PP_AND_GP_JOBS +#warning GP jobs will not be executed + mali_gp_scheduler_return_job_to_user(job, MALI_TRUE); + return _MALI_OSK_ERR_OK; +#endif + + mali_gp_scheduler_lock(); + + _mali_osk_list_addtail(&job->list, &job_queue); + + MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Job %u (0x%08X) queued\n", mali_gp_job_get_id(job), job)); + + mali_gp_scheduler_schedule(); + + mali_gp_scheduler_unlock(); + + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t _mali_ukk_get_gp_number_of_cores(_mali_uk_get_gp_number_of_cores_s *args) +{ + MALI_DEBUG_ASSERT_POINTER(args); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + args->number_of_cores = 1; + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t _mali_ukk_get_gp_core_version(_mali_uk_get_gp_core_version_s *args) +{ + MALI_DEBUG_ASSERT_POINTER(args); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + args->version = gp_version; + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t _mali_ukk_gp_suspend_response(_mali_uk_gp_suspend_response_s *args) +{ + struct mali_session_data *session; + _mali_osk_errcode_t ret = _MALI_OSK_ERR_FAULT; + + MALI_DEBUG_ASSERT_POINTER(args); + + if (NULL == args->ctx) + { + return _MALI_OSK_ERR_INVALID_ARGS; + } + + session = (struct mali_session_data*)args->ctx; + if (NULL == session) + { + return _MALI_OSK_ERR_FAULT; + } + + mali_gp_scheduler_lock(); + + /* Make sure that the cookie returned by user space is the same as we provided in the first place */ + if (args->cookie != slot.returned_cookie) + { + MALI_DEBUG_PRINT(2, ("Mali GP scheduler: Got an illegal cookie from user space, expected %u but got %u (job id)\n", slot.returned_cookie, args->cookie)) ; + mali_gp_scheduler_unlock(); + return _MALI_OSK_ERR_FAULT; + } + + mali_gp_scheduler_unlock(); + + switch (args->code) + { + case _MALIGP_JOB_RESUME_WITH_NEW_HEAP: + MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Resuming job %u with new heap; 0x%08X - 0x%08X\n", args->cookie, args->arguments[0], args->arguments[1])); + mali_group_resume_gp_with_new_heap(slot.group, args->cookie, args->arguments[0], args->arguments[1]); + ret = _MALI_OSK_ERR_OK; + break; + + case _MALIGP_JOB_ABORT: + MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Aborting job %u, no new heap provided\n", args->cookie)); + mali_group_abort_gp_job(slot.group, args->cookie); + ret = _MALI_OSK_ERR_OK; + break; + + default: + MALI_PRINT_ERROR(("Mali GP scheduler: Wrong suspend response from user space\n")); + ret = _MALI_OSK_ERR_FAULT; + break; + } + + return ret; + +} + +void mali_gp_scheduler_abort_session(struct mali_session_data *session) +{ + struct mali_gp_job *job, *tmp; + + mali_gp_scheduler_lock(); + MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Aborting all jobs from session 0x%08x\n", session)); + + /* Check queue for jobs and remove */ + _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &job_queue, struct mali_gp_job, list) + { + if (mali_gp_job_get_session(job) == session) + { + MALI_DEBUG_PRINT(4, ("Mali GP scheduler: Removing GP job 0x%08x from queue\n", job)); + _mali_osk_list_del(&(job->list)); + mali_gp_job_delete(job); + } + } + + mali_gp_scheduler_unlock(); + + /* Abort running jobs from this session. It is safe to do this outside + * the scheduler lock as there is only one GP core, and the queue has + * already been emptied, as long as there are no new jobs coming in + * from user space. */ + mali_group_abort_session(slot.group, session); +} + +static mali_bool mali_gp_scheduler_is_suspended(void) +{ + mali_bool ret; + + mali_gp_scheduler_lock(); + ret = pause_count > 0 && slot.state == MALI_GP_SLOT_STATE_IDLE; + mali_gp_scheduler_unlock(); + + return ret; +} + + +#if MALI_STATE_TRACKING +u32 mali_gp_scheduler_dump_state(char *buf, u32 size) +{ + int n = 0; + + n += _mali_osk_snprintf(buf + n, size - n, "GP\n"); + n += _mali_osk_snprintf(buf + n, size - n, "\tQueue is %s\n", _mali_osk_list_empty(&job_queue) ? "empty" : "not empty"); + + n += mali_group_dump_state(slot.group, buf + n, size - n); + n += _mali_osk_snprintf(buf + n, size - n, "\t\tState: %d\n", mali_group_gp_state(slot.group)); + n += _mali_osk_snprintf(buf + n, size - n, "\n"); + + return n; +} +#endif diff --git a/drivers/media/video/samsung/mali/common/mali_gp_scheduler.h b/drivers/media/video/samsung/mali/common/mali_gp_scheduler.h new file mode 100644 index 0000000..ef58509 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_gp_scheduler.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_GP_SCHEDULER_H__ +#define __MALI_GP_SCHEDULER_H__ + +#include "mali_osk.h" +#include "mali_cluster.h" +#include "mali_gp_job.h" + +_mali_osk_errcode_t mali_gp_scheduler_initialize(void); +void mali_gp_scheduler_terminate(void); + +void mali_gp_scheduler_do_schedule(void); +void mali_gp_scheduler_job_done(struct mali_group *group, struct mali_gp_job *job, mali_bool success); +void mali_gp_scheduler_oom(struct mali_group *group, struct mali_gp_job *job); +void mali_gp_scheduler_abort_session(struct mali_session_data *session); +u32 mali_gp_scheduler_dump_state(char *buf, u32 size); + +void mali_gp_scheduler_suspend(void); +void mali_gp_scheduler_resume(void); + +#endif /* __MALI_GP_SCHEDULER_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_group.c b/drivers/media/video/samsung/mali/common/mali_group.c new file mode 100644 index 0000000..94bf774 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_group.c @@ -0,0 +1,841 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_kernel_common.h" +#include "mali_group.h" +#include "mali_osk.h" +#include "mali_cluster.h" +#include "mali_gp.h" +#include "mali_pp.h" +#include "mali_mmu.h" +#include "mali_gp_scheduler.h" +#include "mali_pp_scheduler.h" +#include "mali_pm.h" + +/* + * The group object is the most important object in the device driver, + * and acts as the center of many HW operations. + * The reason for this is that operations on the MMU will affect all + * cores connected to this MMU (a group is defined by the MMU and the + * cores which are connected to this). + * The group lock is thus the most important lock, followed by the + * GP and PP scheduler locks. They must be taken in the following + * order: + * GP/PP lock first, then group lock(s). + */ + +/** + * The structure represents a render group + * A render group is defined by all the cores that share the same Mali MMU + */ + +struct mali_group +{ + struct mali_cluster *cluster; + + struct mali_mmu_core *mmu; + struct mali_session_data *session; + int page_dir_ref_count; + mali_bool power_is_on; +#if defined(USING_MALI200) + mali_bool pagedir_activation_failed; +#endif + + struct mali_gp_core *gp_core; + enum mali_group_core_state gp_state; + struct mali_gp_job *gp_running_job; + + struct mali_pp_core *pp_core; + enum mali_group_core_state pp_state; + struct mali_pp_job *pp_running_job; + u32 pp_running_sub_job; + + _mali_osk_lock_t *lock; +}; + +static struct mali_group *mali_global_groups[MALI_MAX_NUMBER_OF_GROUPS]; +static u32 mali_global_num_groups = 0; + +enum mali_group_activate_pd_status +{ + MALI_GROUP_ACTIVATE_PD_STATUS_FAILED, + MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD, + MALI_GROUP_ACTIVATE_PD_STATUS_OK_SWITCHED_PD, +}; + +/* local helper functions */ +static enum mali_group_activate_pd_status mali_group_activate_page_directory(struct mali_group *group, struct mali_session_data *session); +static void mali_group_deactivate_page_directory(struct mali_group *group, struct mali_session_data *session); +static void mali_group_recovery_reset(struct mali_group *group); +static void mali_group_complete_jobs(struct mali_group *group, mali_bool complete_gp, mali_bool complete_pp, bool success); + +void mali_group_lock(struct mali_group *group) +{ + if(_MALI_OSK_ERR_OK != _mali_osk_lock_wait(group->lock, _MALI_OSK_LOCKMODE_RW)) + { + /* Non-interruptable lock failed: this should never happen. */ + MALI_DEBUG_ASSERT(0); + } + MALI_DEBUG_PRINT(5, ("Mali group: Group lock taken 0x%08X\n", group)); +} + +void mali_group_unlock(struct mali_group *group) +{ + MALI_DEBUG_PRINT(5, ("Mali group: Releasing group lock 0x%08X\n", group)); + _mali_osk_lock_signal(group->lock, _MALI_OSK_LOCKMODE_RW); +} + +#ifdef DEBUG +void mali_group_assert_locked(struct mali_group *group) +{ + MALI_DEBUG_ASSERT_LOCK_HELD(group->lock); +} +#endif + + +struct mali_group *mali_group_create(struct mali_cluster *cluster, struct mali_mmu_core *mmu) +{ + struct mali_group *group = NULL; + + if (mali_global_num_groups >= MALI_MAX_NUMBER_OF_GROUPS) + { + MALI_PRINT_ERROR(("Mali group: Too many group objects created\n")); + return NULL; + } + + group = _mali_osk_malloc(sizeof(struct mali_group)); + if (NULL != group) + { + _mali_osk_memset(group, 0, sizeof(struct mali_group)); + group->lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_GROUP); + if (NULL != group->lock) + { + group->cluster = cluster; + group->mmu = mmu; /* This group object now owns the MMU object */ + group->session = NULL; + group->page_dir_ref_count = 0; + group->power_is_on = MALI_TRUE; + + group->gp_state = MALI_GROUP_CORE_STATE_IDLE; + group->pp_state = MALI_GROUP_CORE_STATE_IDLE; +#if defined(USING_MALI200) + group->pagedir_activation_failed = MALI_FALSE; +#endif + mali_global_groups[mali_global_num_groups] = group; + mali_global_num_groups++; + + return group; + } + _mali_osk_free(group); + } + + return NULL; +} + +void mali_group_add_gp_core(struct mali_group *group, struct mali_gp_core* gp_core) +{ + /* This group object now owns the GP core object */ + group->gp_core = gp_core; +} + +void mali_group_add_pp_core(struct mali_group *group, struct mali_pp_core* pp_core) +{ + /* This group object now owns the PP core object */ + group->pp_core = pp_core; +} + +void mali_group_delete(struct mali_group *group) +{ + u32 i; + + /* Delete the resources that this group owns */ + if (NULL != group->gp_core) + { + mali_gp_delete(group->gp_core); + } + + if (NULL != group->pp_core) + { + mali_pp_delete(group->pp_core); + } + + if (NULL != group->mmu) + { + mali_mmu_delete(group->mmu); + } + + for (i = 0; i < mali_global_num_groups; i++) + { + if (mali_global_groups[i] == group) + { + mali_global_groups[i] = NULL; + mali_global_num_groups--; + break; + } + } + + _mali_osk_lock_term(group->lock); + + _mali_osk_free(group); +} + +/* Called from mali_cluster_reset() when the system is re-turned on */ +void mali_group_reset(struct mali_group *group) +{ + mali_group_lock(group); + + group->session = NULL; + + if (NULL != group->mmu) + { + mali_mmu_reset(group->mmu); + } + + if (NULL != group->gp_core) + { + mali_gp_reset(group->gp_core); + } + + if (NULL != group->pp_core) + { + mali_pp_reset(group->pp_core); + } + + mali_group_unlock(group); +} + +struct mali_gp_core* mali_group_get_gp_core(struct mali_group *group) +{ + return group->gp_core; +} + +struct mali_pp_core* mali_group_get_pp_core(struct mali_group *group) +{ + return group->pp_core; +} + +_mali_osk_errcode_t mali_group_start_gp_job(struct mali_group *group, struct mali_gp_job *job) +{ + struct mali_session_data *session; + enum mali_group_activate_pd_status activate_status; + + MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->gp_state); + + mali_pm_core_event(MALI_CORE_EVENT_GP_START); + + session = mali_gp_job_get_session(job); + + mali_group_lock(group); + + mali_cluster_l2_cache_invalidate_all(group->cluster, mali_gp_job_get_id(job)); + + activate_status = mali_group_activate_page_directory(group, session); + if (MALI_GROUP_ACTIVATE_PD_STATUS_FAILED != activate_status) + { + /* if session is NOT kept Zapping is done as part of session switch */ + if (MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD == activate_status) + { + mali_mmu_zap_tlb_without_stall(group->mmu); + } + mali_gp_job_start(group->gp_core, job); + group->gp_running_job = job; + group->gp_state = MALI_GROUP_CORE_STATE_WORKING; + + mali_group_unlock(group); + + return _MALI_OSK_ERR_OK; + } + +#if defined(USING_MALI200) + group->pagedir_activation_failed = MALI_TRUE; +#endif + + mali_group_unlock(group); + + mali_pm_core_event(MALI_CORE_EVENT_GP_STOP); /* Failed to start, so "cancel" the MALI_CORE_EVENT_GP_START */ + return _MALI_OSK_ERR_FAULT; +} + +_mali_osk_errcode_t mali_group_start_pp_job(struct mali_group *group, struct mali_pp_job *job, u32 sub_job) +{ + struct mali_session_data *session; + enum mali_group_activate_pd_status activate_status; + + MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->pp_state); + + mali_pm_core_event(MALI_CORE_EVENT_PP_START); + + session = mali_pp_job_get_session(job); + + mali_group_lock(group); + + mali_cluster_l2_cache_invalidate_all(group->cluster, mali_pp_job_get_id(job)); + + activate_status = mali_group_activate_page_directory(group, session); + if (MALI_GROUP_ACTIVATE_PD_STATUS_FAILED != activate_status) + { + /* if session is NOT kept Zapping is done as part of session switch */ + if (MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD == activate_status) + { + MALI_DEBUG_PRINT(3, ("PP starting job PD_Switch 0 Flush 1 Zap 1\n")); + mali_mmu_zap_tlb_without_stall(group->mmu); + } + mali_pp_job_start(group->pp_core, job, sub_job); + group->pp_running_job = job; + group->pp_running_sub_job = sub_job; + group->pp_state = MALI_GROUP_CORE_STATE_WORKING; + + mali_group_unlock(group); + + return _MALI_OSK_ERR_OK; + } + +#if defined(USING_MALI200) + group->pagedir_activation_failed = MALI_TRUE; +#endif + + mali_group_unlock(group); + + mali_pm_core_event(MALI_CORE_EVENT_PP_STOP); /* Failed to start, so "cancel" the MALI_CORE_EVENT_PP_START */ + return _MALI_OSK_ERR_FAULT; +} + +void mali_group_resume_gp_with_new_heap(struct mali_group *group, u32 job_id, u32 start_addr, u32 end_addr) +{ + mali_group_lock(group); + + if (group->gp_state != MALI_GROUP_CORE_STATE_OOM || + mali_gp_job_get_id(group->gp_running_job) != job_id) + { + mali_group_unlock(group); + return; /* Illegal request or job has already been aborted */ + } + + mali_cluster_l2_cache_invalidate_all_force(group->cluster); + mali_mmu_zap_tlb_without_stall(group->mmu); + + mali_gp_resume_with_new_heap(group->gp_core, start_addr, end_addr); + group->gp_state = MALI_GROUP_CORE_STATE_WORKING; + + mali_group_unlock(group); +} + +void mali_group_abort_gp_job(struct mali_group *group, u32 job_id) +{ + mali_group_lock(group); + + if (group->gp_state == MALI_GROUP_CORE_STATE_IDLE || + mali_gp_job_get_id(group->gp_running_job) != job_id) + { + mali_group_unlock(group); + return; /* No need to cancel or job has already been aborted or completed */ + } + + mali_group_complete_jobs(group, MALI_TRUE, MALI_FALSE, MALI_FALSE); /* Will release group lock */ +} + +void mali_group_abort_pp_job(struct mali_group *group, u32 job_id) +{ + mali_group_lock(group); + + if (group->pp_state == MALI_GROUP_CORE_STATE_IDLE || + mali_pp_job_get_id(group->pp_running_job) != job_id) + { + mali_group_unlock(group); + return; /* No need to cancel or job has already been aborted or completed */ + } + + mali_group_complete_jobs(group, MALI_FALSE, MALI_TRUE, MALI_FALSE); /* Will release group lock */ +} + +void mali_group_abort_session(struct mali_group *group, struct mali_session_data *session) +{ + struct mali_gp_job *gp_job; + struct mali_pp_job *pp_job; + u32 gp_job_id = 0; + u32 pp_job_id = 0; + mali_bool abort_pp = MALI_FALSE; + mali_bool abort_gp = MALI_FALSE; + + mali_group_lock(group); + + gp_job = group->gp_running_job; + pp_job = group->pp_running_job; + + if (gp_job && mali_gp_job_get_session(gp_job) == session) + { + MALI_DEBUG_PRINT(4, ("Aborting GP job 0x%08x from session 0x%08x\n", gp_job, session)); + + gp_job_id = mali_gp_job_get_id(gp_job); + abort_gp = MALI_TRUE; + } + + if (pp_job && mali_pp_job_get_session(pp_job) == session) + { + MALI_DEBUG_PRINT(4, ("Mali group: Aborting PP job 0x%08x from session 0x%08x\n", pp_job, session)); + + pp_job_id = mali_pp_job_get_id(pp_job); + abort_pp = MALI_TRUE; + } + + mali_group_unlock(group); + + /* These functions takes and releases the group lock */ + if (0 != abort_gp) + { + mali_group_abort_gp_job(group, gp_job_id); + } + if (0 != abort_pp) + { + mali_group_abort_pp_job(group, pp_job_id); + } + + mali_group_lock(group); + mali_group_remove_session_if_unused(group, session); + mali_group_unlock(group); +} + +enum mali_group_core_state mali_group_gp_state(struct mali_group *group) +{ + return group->gp_state; +} + +enum mali_group_core_state mali_group_pp_state(struct mali_group *group) +{ + return group->pp_state; +} + +/* group lock need to be taken before calling mali_group_bottom_half */ +void mali_group_bottom_half(struct mali_group *group, enum mali_group_event_t event) +{ + MALI_ASSERT_GROUP_LOCKED(group); + + switch (event) + { + case GROUP_EVENT_PP_JOB_COMPLETED: + mali_group_complete_jobs(group, MALI_FALSE, MALI_TRUE, MALI_TRUE); /* PP job SUCCESS */ + /* group lock is released by mali_group_complete_jobs() call above */ + break; + case GROUP_EVENT_PP_JOB_FAILED: + mali_group_complete_jobs(group, MALI_FALSE, MALI_TRUE, MALI_FALSE); /* PP job FAIL */ + /* group lock is released by mali_group_complete_jobs() call above */ + break; + case GROUP_EVENT_PP_JOB_TIMED_OUT: + mali_group_complete_jobs(group, MALI_FALSE, MALI_TRUE, MALI_FALSE); /* PP job TIMEOUT */ + /* group lock is released by mali_group_complete_jobs() call above */ + break; + case GROUP_EVENT_GP_JOB_COMPLETED: + mali_group_complete_jobs(group, MALI_TRUE, MALI_FALSE, MALI_TRUE); /* GP job SUCCESS */ + /* group lock is released by mali_group_complete_jobs() call above */ + break; + case GROUP_EVENT_GP_JOB_FAILED: + mali_group_complete_jobs(group, MALI_TRUE, MALI_FALSE, MALI_FALSE); /* GP job FAIL */ + /* group lock is released by mali_group_complete_jobs() call above */ + break; + case GROUP_EVENT_GP_JOB_TIMED_OUT: + mali_group_complete_jobs(group, MALI_TRUE, MALI_FALSE, MALI_FALSE); /* GP job TIMEOUT */ + /* group lock is released by mali_group_complete_jobs() call above */ + break; + case GROUP_EVENT_GP_OOM: + group->gp_state = MALI_GROUP_CORE_STATE_OOM; + mali_group_unlock(group); /* Nothing to do on the HW side, so just release group lock right away */ + mali_gp_scheduler_oom(group, group->gp_running_job); + break; + case GROUP_EVENT_MMU_PAGE_FAULT: + mali_group_complete_jobs(group, MALI_TRUE, MALI_TRUE, MALI_FALSE); /* GP and PP job FAIL */ + /* group lock is released by mali_group_complete_jobs() call above */ + break; + default: + break; + } +} + +struct mali_mmu_core *mali_group_get_mmu(struct mali_group *group) +{ + return group->mmu; +} + +struct mali_session_data *mali_group_get_session(struct mali_group *group) +{ + return group->session; +} + +struct mali_group *mali_group_get_glob_group(u32 index) +{ + if(mali_global_num_groups > index) + { + return mali_global_groups[index]; + } + + return NULL; +} + +u32 mali_group_get_glob_num_groups(void) +{ + return mali_global_num_groups; +} + +/* Used to check if scheduler for the other core type needs to be called on job completion. + * + * Used only for Mali-200, where job start may fail if the only MMU is busy + * with another session's address space. + */ +static inline mali_bool mali_group_other_reschedule_needed(struct mali_group *group) +{ + MALI_ASSERT_GROUP_LOCKED(group); + +#if defined(USING_MALI200) + if (group->pagedir_activation_failed) + { + group->pagedir_activation_failed = MALI_FALSE; + return MALI_TRUE; + } + else +#endif + { + return MALI_FALSE; + } +} + +static enum mali_group_activate_pd_status mali_group_activate_page_directory(struct mali_group *group, struct mali_session_data *session) +{ + enum mali_group_activate_pd_status retval; + MALI_ASSERT_GROUP_LOCKED(group); + + MALI_DEBUG_PRINT(5, ("Mali group: Activating page directory 0x%08X from session 0x%08X on group 0x%08X\n", mali_session_get_page_directory(session), session, group)); + MALI_DEBUG_ASSERT(0 <= group->page_dir_ref_count); + + if (0 != group->page_dir_ref_count) + { + if (group->session != session) + { + MALI_DEBUG_PRINT(4, ("Mali group: Activating session FAILED: 0x%08x on group 0x%08X. Existing session: 0x%08x\n", session, group, group->session)); + return MALI_GROUP_ACTIVATE_PD_STATUS_FAILED; + } + else + { + MALI_DEBUG_PRINT(4, ("Mali group: Activating session already activated: 0x%08x on group 0x%08X. New Ref: %d\n", session, group, 1+group->page_dir_ref_count)); + retval = MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD; + + } + } + else + { + /* There might be another session here, but it is ok to overwrite it since group->page_dir_ref_count==0 */ + if (group->session != session) + { + mali_bool activate_success; + MALI_DEBUG_PRINT(5, ("Mali group: Activate session: %08x previous: %08x on group 0x%08X. Ref: %d\n", session, group->session, group, 1+group->page_dir_ref_count)); + + activate_success = mali_mmu_activate_page_directory(group->mmu, mali_session_get_page_directory(session)); + MALI_DEBUG_ASSERT(activate_success); + if ( MALI_FALSE== activate_success ) return MALI_GROUP_ACTIVATE_PD_STATUS_FAILED; + group->session = session; + retval = MALI_GROUP_ACTIVATE_PD_STATUS_OK_SWITCHED_PD; + } + else + { + MALI_DEBUG_PRINT(4, ("Mali group: Activate existing session 0x%08X on group 0x%08X. Ref: %d\n", session->page_directory, group, 1+group->page_dir_ref_count)); + retval = MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD; + } + } + + group->page_dir_ref_count++; + return retval; +} + +static void mali_group_deactivate_page_directory(struct mali_group *group, struct mali_session_data *session) +{ + MALI_ASSERT_GROUP_LOCKED(group); + + MALI_DEBUG_ASSERT(0 < group->page_dir_ref_count); + MALI_DEBUG_ASSERT(session == group->session); + + group->page_dir_ref_count--; + + /* As an optimization, the MMU still points to the group->session even if (0 == group->page_dir_ref_count), + and we do not call mali_mmu_activate_empty_page_directory(group->mmu); */ + MALI_DEBUG_ASSERT(0 <= group->page_dir_ref_count); +} + +void mali_group_remove_session_if_unused(struct mali_group *group, struct mali_session_data *session) +{ + MALI_ASSERT_GROUP_LOCKED(group); + + if (0 == group->page_dir_ref_count) + { + MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->gp_state); + MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->pp_state); + + if (group->session == session) + { + MALI_DEBUG_ASSERT(MALI_TRUE == group->power_is_on); + MALI_DEBUG_PRINT(3, ("Mali group: Deactivating unused session 0x%08X on group %08X\n", session, group)); + mali_mmu_activate_empty_page_directory(group->mmu); + group->session = NULL; + } + } +} + +void mali_group_power_on(void) +{ + int i; + for (i = 0; i < mali_global_num_groups; i++) + { + struct mali_group *group = mali_global_groups[i]; + mali_group_lock(group); + MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->gp_state); + MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->pp_state); + MALI_DEBUG_ASSERT_POINTER(group->cluster); + group->power_is_on = MALI_TRUE; + mali_cluster_power_is_enabled_set(group->cluster, MALI_TRUE); + mali_group_unlock(group); + } + MALI_DEBUG_PRINT(3,("group: POWER ON\n")); +} + +mali_bool mali_group_power_is_on(struct mali_group *group) +{ + MALI_ASSERT_GROUP_LOCKED(group); + return group->power_is_on; +} + +void mali_group_power_off(void) +{ + int i; + /* It is necessary to set group->session = NULL; so that the powered off MMU is not written to on map /unmap */ + /* It is necessary to set group->power_is_on=MALI_FALSE so that pending bottom_halves does not access powered off cores. */ + for (i = 0; i < mali_global_num_groups; i++) + { + struct mali_group *group = mali_global_groups[i]; + mali_group_lock(group); + MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->gp_state); + MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->pp_state); + MALI_DEBUG_ASSERT_POINTER(group->cluster); + group->session = NULL; + MALI_DEBUG_ASSERT(MALI_TRUE == group->power_is_on); + group->power_is_on = MALI_FALSE; + mali_cluster_power_is_enabled_set(group->cluster, MALI_FALSE); + mali_group_unlock(group); + } + MALI_DEBUG_PRINT(3,("group: POWER OFF\n")); +} + + +static void mali_group_recovery_reset(struct mali_group *group) +{ + MALI_ASSERT_GROUP_LOCKED(group); + + /* Stop cores, bus stop */ + if (NULL != group->pp_core) + { + mali_pp_stop_bus(group->pp_core); + } + if (NULL != group->gp_core) + { + mali_gp_stop_bus(group->gp_core); + } + + /* Flush MMU */ + mali_mmu_activate_fault_flush_page_directory(group->mmu); + mali_mmu_page_fault_done(group->mmu); + + /* Wait for cores to stop bus */ + if (NULL != group->pp_core) + { + mali_pp_stop_bus_wait(group->pp_core); + } + if (NULL != group->gp_core) + { + mali_gp_stop_bus_wait(group->gp_core); + } + + /* Reset cores */ + if (NULL != group->pp_core) + { + mali_pp_hard_reset(group->pp_core); + } + if (NULL != group->gp_core) + { + mali_gp_hard_reset(group->gp_core); + } + + /* Reset MMU */ + mali_mmu_reset(group->mmu); + group->session = NULL; +} + +/* Group lock need to be taken before calling mali_group_complete_jobs. Will release the lock here. */ +static void mali_group_complete_jobs(struct mali_group *group, mali_bool complete_gp, mali_bool complete_pp, bool success) +{ + mali_bool need_group_reset = MALI_FALSE; + mali_bool gp_success = success; + mali_bool pp_success = success; + + MALI_ASSERT_GROUP_LOCKED(group); + + if (complete_gp && !complete_pp) + { + MALI_DEBUG_ASSERT_POINTER(group->gp_core); + if (_MALI_OSK_ERR_OK == mali_gp_reset(group->gp_core)) + { + struct mali_gp_job *gp_job_to_return = group->gp_running_job; + group->gp_state = MALI_GROUP_CORE_STATE_IDLE; + group->gp_running_job = NULL; + + MALI_DEBUG_ASSERT_POINTER(gp_job_to_return); + + mali_group_deactivate_page_directory(group, mali_gp_job_get_session(gp_job_to_return)); + + if(mali_group_other_reschedule_needed(group)) + { + mali_group_unlock(group); + mali_pp_scheduler_do_schedule(); + } + else + { + mali_group_unlock(group); + } + + mali_gp_scheduler_job_done(group, gp_job_to_return, gp_success); + mali_pm_core_event(MALI_CORE_EVENT_GP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */ + + return; + } + else + { + need_group_reset = MALI_TRUE; + MALI_DEBUG_PRINT(3, ("Mali group: Failed to reset GP, need to reset entire group\n")); + pp_success = MALI_FALSE; /* This might kill PP as well, so this should fail */ + } + } + if (complete_pp && !complete_gp) + { + MALI_DEBUG_ASSERT_POINTER(group->pp_core); + if (_MALI_OSK_ERR_OK == mali_pp_reset(group->pp_core)) + { + struct mali_pp_job *pp_job_to_return = group->pp_running_job; + u32 pp_sub_job_to_return = group->pp_running_sub_job; + group->pp_state = MALI_GROUP_CORE_STATE_IDLE; + group->pp_running_job = NULL; + + MALI_DEBUG_ASSERT_POINTER(pp_job_to_return); + + mali_group_deactivate_page_directory(group, mali_pp_job_get_session(pp_job_to_return)); + + if(mali_group_other_reschedule_needed(group)) + { + mali_group_unlock(group); + mali_gp_scheduler_do_schedule(); + } + else + { + mali_group_unlock(group); + } + + mali_pp_scheduler_job_done(group, pp_job_to_return, pp_sub_job_to_return, pp_success); + mali_pm_core_event(MALI_CORE_EVENT_PP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */ + + return; + } + else + { + need_group_reset = MALI_TRUE; + MALI_DEBUG_PRINT(3, ("Mali group: Failed to reset PP, need to reset entire group\n")); + gp_success = MALI_FALSE; /* This might kill GP as well, so this should fail */ + } + } + else if (complete_gp && complete_pp) + { + need_group_reset = MALI_TRUE; + } + + if (MALI_TRUE == need_group_reset) + { + struct mali_gp_job *gp_job_to_return = group->gp_running_job; + struct mali_pp_job *pp_job_to_return = group->pp_running_job; + u32 pp_sub_job_to_return = group->pp_running_sub_job; + mali_bool schedule_other = MALI_FALSE; + + MALI_DEBUG_PRINT(3, ("Mali group: Resetting entire group\n")); + + group->gp_state = MALI_GROUP_CORE_STATE_IDLE; + group->gp_running_job = NULL; + if (NULL != gp_job_to_return) + { + mali_group_deactivate_page_directory(group, mali_gp_job_get_session(gp_job_to_return)); + } + + group->pp_state = MALI_GROUP_CORE_STATE_IDLE; + group->pp_running_job = NULL; + if (NULL != pp_job_to_return) + { + mali_group_deactivate_page_directory(group, mali_pp_job_get_session(pp_job_to_return)); + } + + /* The reset has to be done after mali_group_deactivate_page_directory() */ + mali_group_recovery_reset(group); + + if (mali_group_other_reschedule_needed(group) && (NULL == gp_job_to_return || NULL == pp_job_to_return)) + { + schedule_other = MALI_TRUE; + } + + mali_group_unlock(group); + + if (NULL != gp_job_to_return) + { + mali_gp_scheduler_job_done(group, gp_job_to_return, gp_success); + mali_pm_core_event(MALI_CORE_EVENT_GP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */ + } + else if (schedule_other) + { + mali_pp_scheduler_do_schedule(); + } + + if (NULL != pp_job_to_return) + { + mali_pp_scheduler_job_done(group, pp_job_to_return, pp_sub_job_to_return, pp_success); + mali_pm_core_event(MALI_CORE_EVENT_PP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */ + } + else if (schedule_other) + { + mali_gp_scheduler_do_schedule(); + } + + return; + } + + mali_group_unlock(group); +} + +#if MALI_STATE_TRACKING +u32 mali_group_dump_state(struct mali_group *group, char *buf, u32 size) +{ + int n = 0; + + n += _mali_osk_snprintf(buf + n, size - n, "Group: %p\n", group); + if (group->gp_core) + { + n += mali_gp_dump_state(group->gp_core, buf + n, size - n); + n += _mali_osk_snprintf(buf + n, size - n, "\tGP state: %d\n", group->gp_state); + n += _mali_osk_snprintf(buf + n, size - n, "\tGP job: %p\n", group->gp_running_job); + } + if (group->pp_core) + { + n += mali_pp_dump_state(group->pp_core, buf + n, size - n); + n += _mali_osk_snprintf(buf + n, size - n, "\tPP state: %d\n", group->pp_state); + n += _mali_osk_snprintf(buf + n, size - n, "\tPP job: %p, subjob %d \n", + group->pp_running_job, group->pp_running_sub_job); + } + + return n; +} +#endif diff --git a/drivers/media/video/samsung/mali/common/mali_group.h b/drivers/media/video/samsung/mali/common/mali_group.h new file mode 100644 index 0000000..3533d13 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_group.h @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_GROUP_H__ +#define __MALI_GROUP_H__ + +#include "linux/jiffies.h" +#include "mali_osk.h" +#include "mali_cluster.h" +#include "mali_mmu.h" +#include "mali_gp.h" +#include "mali_pp.h" +#include "mali_session.h" + +/* max runtime [ms] for a core job - used by timeout timers */ +#define MAX_RUNTIME 5000 +/** @brief A mali group object represents a MMU and a PP and/or a GP core. + * + */ +#define MALI_MAX_NUMBER_OF_GROUPS 9 + +struct mali_group; + +enum mali_group_event_t +{ + GROUP_EVENT_PP_JOB_COMPLETED, /**< PP job completed successfully */ + GROUP_EVENT_PP_JOB_FAILED, /**< PP job completed with failure */ + GROUP_EVENT_PP_JOB_TIMED_OUT, /**< PP job reached max runtime */ + GROUP_EVENT_GP_JOB_COMPLETED, /**< GP job completed successfully */ + GROUP_EVENT_GP_JOB_FAILED, /**< GP job completed with failure */ + GROUP_EVENT_GP_JOB_TIMED_OUT, /**< GP job reached max runtime */ + GROUP_EVENT_GP_OOM, /**< GP job ran out of heap memory */ + GROUP_EVENT_MMU_PAGE_FAULT, /**< MMU page fault */ +}; + +enum mali_group_core_state +{ + MALI_GROUP_CORE_STATE_IDLE, + MALI_GROUP_CORE_STATE_WORKING, + MALI_GROUP_CORE_STATE_OOM +}; + +/** @brief Create a new Mali group object + * + * @param cluster Pointer to the cluster to which the group is connected. + * @param mmu Pointer to the MMU that defines this group + * @return A pointer to a new group object + */ +struct mali_group *mali_group_create(struct mali_cluster *cluster, struct mali_mmu_core *mmu); +void mali_group_add_gp_core(struct mali_group *group, struct mali_gp_core* gp_core); +void mali_group_add_pp_core(struct mali_group *group, struct mali_pp_core* pp_core); +void mali_group_delete(struct mali_group *group); + +/** @brief Reset group + * + * This function will reset the entire group, including all the cores present in the group. + * + * @param group Pointer to the group to reset + */ +void mali_group_reset(struct mali_group *group); + +/** @brief Get pointer to GP core object + */ +struct mali_gp_core* mali_group_get_gp_core(struct mali_group *group); + +/** @brief Get pointer to PP core object + */ +struct mali_pp_core* mali_group_get_pp_core(struct mali_group *group); + +/** @brief Lock group object + * + * Most group functions will lock the group object themselves. The expection is + * the group_bottom_half which requires the group to be locked on entry. + * + * @param group Pointer to group to lock + */ +void mali_group_lock(struct mali_group *group); + +/** @brief Unlock group object + * + * @param group Pointer to group to unlock + */ +void mali_group_unlock(struct mali_group *group); +#ifdef DEBUG +void mali_group_assert_locked(struct mali_group *group); +#define MALI_ASSERT_GROUP_LOCKED(group) mali_group_assert_locked(group) +#else +#define MALI_ASSERT_GROUP_LOCKED(group) +#endif + +/** @brief Start GP job + */ +_mali_osk_errcode_t mali_group_start_gp_job(struct mali_group *group, struct mali_gp_job *job); +/** @brief Start fragment of PP job + */ +_mali_osk_errcode_t mali_group_start_pp_job(struct mali_group *group, struct mali_pp_job *job, u32 sub_job); + +/** @brief Resume GP job that suspended waiting for more heap memory + */ +void mali_group_resume_gp_with_new_heap(struct mali_group *group, u32 job_id, u32 start_addr, u32 end_addr); +/** @brief Abort GP job + * + * Used to abort suspended OOM jobs when user space failed to allocte more memory. + */ +void mali_group_abort_gp_job(struct mali_group *group, u32 job_id); +/** @brief Abort all GP jobs from \a session + * + * Used on session close when terminating all running and queued jobs from \a session. + */ +void mali_group_abort_session(struct mali_group *group, struct mali_session_data *session); + +enum mali_group_core_state mali_group_gp_state(struct mali_group *group); +enum mali_group_core_state mali_group_pp_state(struct mali_group *group); + +/** @brief The common group bottom half interrupt handler + * + * This is only called from the GP and PP bottom halves. + * + * The action taken is dictated by the \a event. + * + * @param event The event code + */ +void mali_group_bottom_half(struct mali_group *group, enum mali_group_event_t event); + +struct mali_mmu_core *mali_group_get_mmu(struct mali_group *group); +struct mali_session_data *mali_group_get_session(struct mali_group *group); + +void mali_group_remove_session_if_unused(struct mali_group *group, struct mali_session_data *session_data); + +void mali_group_power_on(void); +void mali_group_power_off(void); +mali_bool mali_group_power_is_on(struct mali_group *group); + +struct mali_group *mali_group_get_glob_group(u32 index); +u32 mali_group_get_glob_num_groups(void); + +u32 mali_group_dump_state(struct mali_group *group, char *buf, u32 size); + +#endif /* __MALI_GROUP_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_hw_core.c b/drivers/media/video/samsung/mali/common/mali_hw_core.c new file mode 100644 index 0000000..0b08622 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_hw_core.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_hw_core.h" +#include "mali_osk.h" +#include "mali_kernel_common.h" + +_mali_osk_errcode_t mali_hw_core_create(struct mali_hw_core *core, const _mali_osk_resource_t *resource, u32 reg_size) +{ + core->phys_addr = resource->base; + core->description = resource->description; + core->size = reg_size; + if (_MALI_OSK_ERR_OK == _mali_osk_mem_reqregion(core->phys_addr, core->size, core->description)) + { + core->mapped_registers = _mali_osk_mem_mapioregion(core->phys_addr, core->size, core->description); + if (NULL != core->mapped_registers) + { + return _MALI_OSK_ERR_OK; + } + else + { + MALI_PRINT_ERROR(("Failed to map memory region for core %s at phys_addr 0x%08X\n", core->description, core->phys_addr)); + } + _mali_osk_mem_unreqregion(core->phys_addr, core->size); + } + else + { + MALI_PRINT_ERROR(("Failed to request memory region for core %s at phys_addr 0x%08X\n", core->description, core->phys_addr)); + } + + return _MALI_OSK_ERR_FAULT; +} + +void mali_hw_core_delete(struct mali_hw_core *core) +{ + _mali_osk_mem_unmapioregion(core->phys_addr, core->size, core->mapped_registers); + core->mapped_registers = NULL; + _mali_osk_mem_unreqregion(core->phys_addr, core->size); +} diff --git a/drivers/media/video/samsung/mali/common/mali_hw_core.h b/drivers/media/video/samsung/mali/common/mali_hw_core.h new file mode 100644 index 0000000..c797804 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_hw_core.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_HW_CORE_H__ +#define __MALI_HW_CORE_H__ + +#include "mali_osk.h" +#include "mali_kernel_common.h" + +/** + * The common parts for all Mali HW cores (GP, PP, MMU, L2 and PMU) + * This struct is embedded inside all core specific structs. + */ +struct mali_hw_core +{ + u32 phys_addr; /**< Physical address of the registers */ + u32 size; /**< Size of registers */ + mali_io_address mapped_registers; /**< Virtual mapping of the registers */ + const char* description; /**< Name of unit (as specified in device configuration) */ +}; + +#define MALI_HW_CORE_NO_COUNTER ((u32)-1) +#define MALI_HW_CORE_INVALID_VALUE ((u32)-1) + +_mali_osk_errcode_t mali_hw_core_create(struct mali_hw_core *core, const _mali_osk_resource_t *resource, u32 reg_size); +void mali_hw_core_delete(struct mali_hw_core *core); + +MALI_STATIC_INLINE u32 mali_hw_core_register_read(struct mali_hw_core *core, u32 relative_address) +{ + u32 read_val; + read_val = _mali_osk_mem_ioread32(core->mapped_registers, relative_address); + MALI_DEBUG_PRINT(6, ("register_read for core %s, relative addr=0x%04X, val=0x%08X\n", + core->description, relative_address, read_val)); + return read_val; +} + +MALI_STATIC_INLINE void mali_hw_core_register_write_relaxed(struct mali_hw_core *core, u32 relative_address, u32 new_val) +{ + MALI_DEBUG_PRINT(6, ("register_write_relaxed for core %s, relative addr=0x%04X, val=0x%08X\n", + core->description, relative_address, new_val)); + _mali_osk_mem_iowrite32_relaxed(core->mapped_registers, relative_address, new_val); +} + +MALI_STATIC_INLINE void mali_hw_core_register_write(struct mali_hw_core *core, u32 relative_address, u32 new_val) +{ + MALI_DEBUG_PRINT(6, ("register_write for core %s, relative addr=0x%04X, val=0x%08X\n", + core->description, relative_address, new_val)); + _mali_osk_mem_iowrite32(core->mapped_registers, relative_address, new_val); +} + +MALI_STATIC_INLINE void mali_hw_core_register_write_array_relaxed(struct mali_hw_core *core, u32 relative_address, u32 *write_array, u32 nr_of_regs) +{ + u32 i; + MALI_DEBUG_PRINT(6, ("register_write_array: for core %s, relative addr=0x%04X, nr of regs=%u\n", + core->description,relative_address, nr_of_regs)); + + /* Do not use burst writes against the registers */ + for (i = 0; i< nr_of_regs; i++) + { + mali_hw_core_register_write_relaxed(core, relative_address + i*4, write_array[i]); + } +} + +#endif /* __MALI_HW_CORE_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_common.h b/drivers/media/video/samsung/mali/common/mali_kernel_common.h new file mode 100644 index 0000000..b354f92 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_kernel_common.h @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_KERNEL_COMMON_H__ +#define __MALI_KERNEL_COMMON_H__ + +/* Make sure debug is defined when it should be */ +#ifndef DEBUG + #if defined(_DEBUG) + #define DEBUG + #endif +#endif + +/* Macro for generating a kernel panic. + * Turned on off by compile-time Makefile settings + */ +#if defined(USING_KERNEL_PANIC) +#include + #define MALI_PANIC(fmt, args...) panic( fmt, ## args ); +#else + #define MALI_PANIC(fmt, args...) +#endif + +/* The file include several useful macros for error checking, debugging and printing. + * - MALI_PRINTF(...) Do not use this function: Will be included in Release builds. + * - MALI_DEBUG_PRINT(nr, (X) ) Prints the second argument if nr<=MALI_DEBUG_LEVEL. + * - MALI_DEBUG_ERROR( (X) ) Prints an errortext, a source trace, and the given error message. + * - MALI_DEBUG_ASSERT(exp,(X)) If the asserted expr is false, the program will exit. + * - MALI_DEBUG_ASSERT_POINTER(pointer) Triggers if the pointer is a zero pointer. + * - MALI_DEBUG_CODE( X ) The code inside the macro is only compiled in Debug builds. + * + * The (X) means that you must add an extra parenthesis around the argumentlist. + * + * The printf function: MALI_PRINTF(...) is routed to _mali_osk_debugmsg + * + * Suggested range for the DEBUG-LEVEL is [1:6] where + * [1:2] Is messages with highest priority, indicate possible errors. + * [3:4] Is messages with medium priority, output important variables. + * [5:6] Is messages with low priority, used during extensive debugging. + */ + + /** + * Fundamental error macro. Reports an error code. This is abstracted to allow us to + * easily switch to a different error reporting method if we want, and also to allow + * us to search for error returns easily. + * + * Note no closing semicolon - this is supplied in typical usage: + * + * MALI_ERROR(MALI_ERROR_OUT_OF_MEMORY); + */ +#define MALI_ERROR(error_code) return (error_code) + +/** + * Basic error macro, to indicate success. + * Note no closing semicolon - this is supplied in typical usage: + * + * MALI_SUCCESS; + */ +#define MALI_SUCCESS MALI_ERROR(_MALI_OSK_ERR_OK) + +/** + * Basic error macro. This checks whether the given condition is true, and if not returns + * from this function with the supplied error code. This is a macro so that we can override it + * for stress testing. + * + * Note that this uses the do-while-0 wrapping to ensure that we don't get problems with dangling + * else clauses. Note also no closing semicolon - this is supplied in typical usage: + * + * MALI_CHECK((p!=NULL), ERROR_NO_OBJECT); + */ +#define MALI_CHECK(condition, error_code) do { if(!(condition)) MALI_ERROR(error_code); } while(0) + +/** + * Error propagation macro. If the expression given is anything other than _MALI_OSK_NO_ERROR, + * then the value is returned from the enclosing function as an error code. This effectively + * acts as a guard clause, and propagates error values up the call stack. This uses a + * temporary value to ensure that the error expression is not evaluated twice. + * If the counter for forcing a failure has been set using _mali_force_error, this error will be + * returned without evaluating the expression in MALI_CHECK_NO_ERROR + */ +#define MALI_CHECK_NO_ERROR(expression) \ + do { _mali_osk_errcode_t _check_no_error_result=(expression); \ + if(_check_no_error_result != _MALI_OSK_ERR_OK) \ + MALI_ERROR(_check_no_error_result); \ + } while(0) + +/** + * Pointer check macro. Checks non-null pointer. + */ +#define MALI_CHECK_NON_NULL(pointer, error_code) MALI_CHECK( ((pointer)!=NULL), (error_code) ) + +/** + * Error macro with goto. This checks whether the given condition is true, and if not jumps + * to the specified label using a goto. The label must therefore be local to the function in + * which this macro appears. This is most usually used to execute some clean-up code before + * exiting with a call to ERROR. + * + * Like the other macros, this is a macro to allow us to override the condition if we wish, + * e.g. to force an error during stress testing. + */ +#define MALI_CHECK_GOTO(condition, label) do { if(!(condition)) goto label; } while(0) + +/** + * Explicitly ignore a parameter passed into a function, to suppress compiler warnings. + * Should only be used with parameter names. + */ +#define MALI_IGNORE(x) x=x + +#define MALI_PRINTF(args) _mali_osk_dbgmsg args; + +#define MALI_PRINT_ERROR(args) do{ \ + MALI_PRINTF(("Mali: ERR: %s\n" ,__FILE__)); \ + MALI_PRINTF((" %s()%4d\n ", __FUNCTION__, __LINE__)) ; \ + MALI_PRINTF(args); \ + MALI_PRINTF(("\n")); \ + } while(0) + +#define MALI_PRINT(args) do{ \ + MALI_PRINTF(("Mali: ")); \ + MALI_PRINTF(args); \ + } while (0) + +#ifdef DEBUG +#ifndef mali_debug_level +extern int mali_debug_level; +#endif + +#define MALI_DEBUG_CODE(code) code +#define MALI_DEBUG_PRINT(level, args) do { \ + if((level) <= mali_debug_level)\ + {MALI_PRINTF(("Mali<" #level ">: ")); MALI_PRINTF(args); } \ + } while (0) + +#define MALI_DEBUG_PRINT_ERROR(args) MALI_PRINT_ERROR(args) + +#define MALI_DEBUG_PRINT_IF(level,condition,args) \ + if((condition)&&((level) <= mali_debug_level))\ + {MALI_PRINTF(("Mali<" #level ">: ")); MALI_PRINTF(args); } + +#define MALI_DEBUG_PRINT_ELSE(level, args)\ + else if((level) <= mali_debug_level)\ + { MALI_PRINTF(("Mali<" #level ">: ")); MALI_PRINTF(args); } + +/** + * @note these variants of DEBUG ASSERTS will cause a debugger breakpoint + * to be entered (see _mali_osk_break() ). An alternative would be to call + * _mali_osk_abort(), on OSs that support it. + */ +#define MALI_DEBUG_PRINT_ASSERT(condition, args) do {if( !(condition)) { MALI_PRINT_ERROR(args); _mali_osk_break(); } } while(0) +#define MALI_DEBUG_ASSERT_POINTER(pointer) do {if( (pointer)== NULL) {MALI_PRINT_ERROR(("NULL pointer " #pointer)); _mali_osk_break();} } while(0) +#define MALI_DEBUG_ASSERT(condition) do {if( !(condition)) {MALI_PRINT_ERROR(("ASSERT failed: " #condition )); _mali_osk_break();} } while(0) + +#else /* DEBUG */ + +#define MALI_DEBUG_CODE(code) +#define MALI_DEBUG_PRINT(string,args) do {} while(0) +#define MALI_DEBUG_PRINT_ERROR(args) do {} while(0) +#define MALI_DEBUG_PRINT_IF(level,condition,args) do {} while(0) +#define MALI_DEBUG_PRINT_ELSE(level,condition,args) do {} while(0) +#define MALI_DEBUG_PRINT_ASSERT(condition,args) do {} while(0) +#define MALI_DEBUG_ASSERT_POINTER(pointer) do {} while(0) +#define MALI_DEBUG_ASSERT(condition) do {} while(0) + +#endif /* DEBUG */ + +/** + * variables from user space cannot be dereferenced from kernel space; tagging them + * with __user allows the GCC compiler to generate a warning. Other compilers may + * not support this so we define it here as an empty macro if the compiler doesn't + * define it. + */ +#ifndef __user +#define __user +#endif + +#endif /* __MALI_KERNEL_COMMON_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_core.c b/drivers/media/video/samsung/mali/common/mali_kernel_core.c new file mode 100644 index 0000000..45e86d2 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_kernel_core.c @@ -0,0 +1,980 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_kernel_common.h" +#include "mali_session.h" +#include "mali_osk.h" +#include "mali_osk_mali.h" +#include "mali_ukk.h" +#include "mali_kernel_core.h" +#include "mali_memory.h" +#include "mali_mem_validation.h" +#include "mali_mmu.h" +#include "mali_mmu_page_directory.h" +#include "mali_dlbu.h" +#include "mali_gp.h" +#include "mali_pp.h" +#include "mali_gp_scheduler.h" +#include "mali_pp_scheduler.h" +#include "mali_cluster.h" +#include "mali_group.h" +#include "mali_pm.h" +#include "mali_pmu.h" +#include "mali_scheduler.h" +#ifdef CONFIG_MALI400_GPU_UTILIZATION +#include "mali_kernel_utilization.h" +#endif +#include "mali_l2_cache.h" +#if MALI_TIMELINE_PROFILING_ENABLED +#include "mali_osk_profiling.h" +#endif + +/** Pointer to table of resource definitions available to the Mali driver. + * _mali_osk_resources_init() sets up the pointer to this table. + */ +static _mali_osk_resource_t *arch_configuration = NULL; + +/** Start profiling from module load? */ +int mali_boot_profiling = 0; + +/** Number of resources initialized by _mali_osk_resources_init() */ +static u32 num_resources; + +static _mali_product_id_t global_product_id = _MALI_PRODUCT_ID_UNKNOWN; +static u32 global_gpu_base_address = 0; +static u32 global_gpu_major_version = 0; +static u32 global_gpu_minor_version = 0; + +static u32 first_pp_offset = 0; + +#define HANG_CHECK_MSECS_DEFAULT 500 /* 500 ms */ +#define WATCHDOG_MSECS_DEFAULT 4000 /* 4 s */ + +/* timer related */ +int mali_max_job_runtime = WATCHDOG_MSECS_DEFAULT; +int mali_hang_check_interval = HANG_CHECK_MSECS_DEFAULT; + +static _mali_osk_resource_t *mali_find_resource(_mali_osk_resource_type_t type, u32 offset) +{ + int i; + u32 addr = global_gpu_base_address + offset; + + for (i = 0; i < num_resources; i++) + { + if (type == arch_configuration[i].type && arch_configuration[i].base == addr) + { + return &(arch_configuration[i]); + } + } + + return NULL; +} + +static u32 mali_count_resources(_mali_osk_resource_type_t type) +{ + int i; + u32 retval = 0; + + for (i = 0; i < num_resources; i++) + { + if (type == arch_configuration[i].type) + { + retval++; + } + } + + return retval; +} + + +static _mali_osk_errcode_t mali_parse_gpu_base_and_first_pp_offset_address(void) +{ + int i; + _mali_osk_resource_t *first_gp_resource = NULL; + _mali_osk_resource_t *first_pp_resource = NULL; + + for (i = 0; i < num_resources; i++) + { + if (MALI_GP == arch_configuration[i].type) + { + if (NULL == first_gp_resource || first_gp_resource->base > arch_configuration[i].base) + { + first_gp_resource = &(arch_configuration[i]); + } + } + if (MALI_PP == arch_configuration[i].type) + { + if (NULL == first_pp_resource || first_pp_resource->base > arch_configuration[i].base) + { + first_pp_resource = &(arch_configuration[i]); + } + } + } + + if (NULL == first_gp_resource || NULL == first_pp_resource) + { + MALI_PRINT_ERROR(("No GP+PP core specified in config file\n")); + return _MALI_OSK_ERR_FAULT; + } + + if (first_gp_resource->base < first_pp_resource->base) + { + /* GP is first, so we are dealing with Mali-300, Mali-400 or Mali-450 */ + global_gpu_base_address = first_gp_resource->base; + first_pp_offset = 0x8000; + } + else + { + /* PP is first, so we are dealing with Mali-200 */ + global_gpu_base_address = first_pp_resource->base; + first_pp_offset = 0x0; + } + MALI_SUCCESS; +} + +static _mali_osk_errcode_t mali_parse_product_info(void) +{ + _mali_osk_resource_t *first_pp_resource = NULL; + + /* Find the first PP core */ + first_pp_resource = mali_find_resource(MALI_PP, first_pp_offset); + if (NULL != first_pp_resource) + { + /* Create a dummy PP object for this core so that we can read the version register */ + struct mali_group *group = mali_group_create(NULL, NULL); + if (NULL != group) + { + /*struct mali_pp_core *pp_core = mali_pp_create(first_pp_resource, group, 0);*/ + struct mali_pp_core *pp_core = mali_pp_create(first_pp_resource, group); + if (NULL != pp_core) + { + u32 pp_version = mali_pp_core_get_version(pp_core); + mali_pp_delete(pp_core); + mali_group_delete(group); + + global_gpu_major_version = (pp_version >> 8) & 0xFF; + global_gpu_minor_version = pp_version & 0xFF; + + switch (pp_version >> 16) + { + case MALI200_PP_PRODUCT_ID: + global_product_id = _MALI_PRODUCT_ID_MALI200; + MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-200 r%up%u\n", global_gpu_major_version, global_gpu_minor_version)); + break; + case MALI300_PP_PRODUCT_ID: + global_product_id = _MALI_PRODUCT_ID_MALI300; + MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-300 r%up%u\n", global_gpu_major_version, global_gpu_minor_version)); + break; + case MALI400_PP_PRODUCT_ID: + global_product_id = _MALI_PRODUCT_ID_MALI400; + MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-400 MP r%up%u\n", global_gpu_major_version, global_gpu_minor_version)); + break; + case MALI450_PP_PRODUCT_ID: + global_product_id = _MALI_PRODUCT_ID_MALI450; + MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-450 MP r%up%u\n", global_gpu_major_version, global_gpu_minor_version)); + break; + default: + MALI_DEBUG_PRINT(2, ("Found unknown Mali GPU GPU (r%up%u)\n", global_gpu_major_version, global_gpu_minor_version)); + return _MALI_OSK_ERR_FAULT; + } + + return _MALI_OSK_ERR_OK; + } + else + { + MALI_PRINT_ERROR(("Failed to create initial PP object\n")); + } + } + else + { + MALI_PRINT_ERROR(("Failed to create initial group object\n")); + } + } + else + { + MALI_PRINT_ERROR(("First PP core not specified in config file\n")); + } + + return _MALI_OSK_ERR_FAULT; +} + +static void mali_delete_clusters(void) +{ + u32 i; + u32 number_of_clusters = mali_cluster_get_glob_num_clusters(); + + for (i = 0; i < number_of_clusters; i++) + { + mali_cluster_delete(mali_cluster_get_global_cluster(i)); + } +} + +static _mali_osk_errcode_t mali_create_cluster(_mali_osk_resource_t *resource) +{ + if (NULL != resource) + { + struct mali_l2_cache_core *l2_cache; + + if (mali_l2_cache_core_get_glob_num_l2_cores() >= mali_l2_cache_core_get_max_num_l2_cores()) + { + MALI_PRINT_ERROR(("Found too many L2 cache core objects, max %u is supported\n", mali_l2_cache_core_get_max_num_l2_cores())); + return _MALI_OSK_ERR_FAULT; + } + + MALI_DEBUG_PRINT(3, ("Found L2 cache %s, starting new cluster\n", resource->description)); + + /*l2_cache = mali_l2_cache_create(resource, global_num_l2_cache_cores);*/ + l2_cache = mali_l2_cache_create(resource); + if (NULL == l2_cache) + { + MALI_PRINT_ERROR(("Failed to create L2 cache object\n")); + return _MALI_OSK_ERR_FAULT; + } + + if (NULL == mali_cluster_create(l2_cache)) + { + MALI_PRINT_ERROR(("Failed to create cluster object\n")); + mali_l2_cache_delete(l2_cache); + return _MALI_OSK_ERR_FAULT; + } + } + else + { + mali_cluster_create(NULL); + if (NULL == mali_cluster_get_global_cluster(0)) + { + MALI_PRINT_ERROR(("Failed to create cluster object\n")); + return _MALI_OSK_ERR_FAULT; + } + } + + MALI_DEBUG_PRINT(3, ("Created cluster object\n")); + return _MALI_OSK_ERR_OK; +} + +static _mali_osk_errcode_t mali_parse_config_cluster(void) +{ + if (_MALI_PRODUCT_ID_MALI200 == global_product_id) + { + /* Create dummy cluster without L2 cache */ + return mali_create_cluster(NULL); + } + else if (_MALI_PRODUCT_ID_MALI300 == global_product_id || _MALI_PRODUCT_ID_MALI400 == global_product_id) + { + _mali_osk_resource_t *l2_resource = mali_find_resource(MALI_L2, 0x1000); + if (NULL == l2_resource) + { + MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache in config file\n")); + return _MALI_OSK_ERR_FAULT; + } + + return mali_create_cluster(l2_resource); + } + else if (_MALI_PRODUCT_ID_MALI450 == global_product_id) + { + /* + * L2 for GP at 0x10000 + * L2 for PP0-3 at 0x01000 + * L2 for PP4-7 at 0x11000 (optional) + */ + + _mali_osk_resource_t *l2_gp_resource; + _mali_osk_resource_t *l2_pp_grp0_resource; + _mali_osk_resource_t *l2_pp_grp1_resource; + + /* Make cluster for GP's L2 */ + l2_gp_resource = mali_find_resource(MALI_L2, 0x10000); + if (NULL != l2_gp_resource) + { + _mali_osk_errcode_t ret; + MALI_DEBUG_PRINT(3, ("Creating Mali-450 cluster for GP\n")); + ret = mali_create_cluster(l2_gp_resource); + if (_MALI_OSK_ERR_OK != ret) + { + return ret; + } + } + else + { + MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache for GP in config file\n")); + return _MALI_OSK_ERR_FAULT; + } + + /* Make cluster for first PP core group */ + l2_pp_grp0_resource = mali_find_resource(MALI_L2, 0x1000); + if (NULL != l2_pp_grp0_resource) + { + _mali_osk_errcode_t ret; + MALI_DEBUG_PRINT(3, ("Creating Mali-450 cluster for PP group 0\n")); + ret = mali_create_cluster(l2_pp_grp0_resource); + if (_MALI_OSK_ERR_OK != ret) + { + return ret; + } + } + else + { + MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache for PP group 0 in config file\n")); + return _MALI_OSK_ERR_FAULT; + } + + /* Second PP core group is optional, don't fail if we don't find it */ + l2_pp_grp1_resource = mali_find_resource(MALI_L2, 0x11000); + if (NULL != l2_pp_grp1_resource) + { + _mali_osk_errcode_t ret; + MALI_DEBUG_PRINT(3, ("Creating Mali-450 cluster for PP group 0\n")); + ret = mali_create_cluster(l2_pp_grp1_resource); + if (_MALI_OSK_ERR_OK != ret) + { + return ret; + } + } + } + + return _MALI_OSK_ERR_OK; +} + +static _mali_osk_errcode_t mali_create_group(struct mali_cluster *cluster, + _mali_osk_resource_t *resource_mmu, + _mali_osk_resource_t *resource_gp, + _mali_osk_resource_t *resource_pp) +{ + struct mali_mmu_core *mmu; + struct mali_group *group; + struct mali_pp_core *pp; + + MALI_DEBUG_PRINT(3, ("Starting new group for MMU %s\n", resource_mmu->description)); + + /* Create the MMU object */ + mmu = mali_mmu_create(resource_mmu); + if (NULL == mmu) + { + MALI_PRINT_ERROR(("Failed to create MMU object\n")); + return _MALI_OSK_ERR_FAULT; + } + + /* Create the group object */ + group = mali_group_create(cluster, mmu); + if (NULL == group) + { + MALI_PRINT_ERROR(("Failed to create group object for MMU %s\n", resource_mmu->description)); + mali_mmu_delete(mmu); + return _MALI_OSK_ERR_FAULT; + } + + /* Set pointer back to group in mmu.*/ + mali_mmu_set_group(mmu, group); + + /* Add this group to current cluster */ + mali_cluster_add_group(cluster, group); + + if (NULL != resource_gp) + { + /* Create the GP core object inside this group */ + /* global_gp_core = mali_gp_create(resource_gp, group); */ + if (NULL == mali_gp_create(resource_gp, group)) + { + /* No need to clean up now, as we will clean up everything linked in from the cluster when we fail this function */ + MALI_PRINT_ERROR(("Failed to create GP object\n")); + return _MALI_OSK_ERR_FAULT; + } + + /* Add GP object to this group */ + MALI_DEBUG_PRINT(3, ("Adding GP %s to group\n", resource_gp->description)); + mali_group_add_gp_core(group, mali_gp_get_global_gp_core()); + } + + if (NULL != resource_pp) + { + /* Create the PP core object inside this group */ + pp = mali_pp_create(resource_pp, group); + + if (NULL == pp) + { + /* No need to clean up now, as we will clean up everything linked in from the cluster when we fail this function */ + MALI_PRINT_ERROR(("Failed to create PP object\n")); + return _MALI_OSK_ERR_FAULT; + } + + /* Add PP object to this group */ + MALI_DEBUG_PRINT(3, ("Adding PP %s to group\n", resource_pp->description)); + mali_group_add_pp_core(group, pp); + } + + return _MALI_OSK_ERR_OK; +} + +static _mali_osk_errcode_t mali_parse_config_groups(void) +{ + if (_MALI_PRODUCT_ID_MALI200 == global_product_id) + { + _mali_osk_resource_t *resource_gp; + _mali_osk_resource_t *resource_pp; + _mali_osk_resource_t *resource_mmu; + + MALI_DEBUG_ASSERT(1 == mali_cluster_get_glob_num_clusters()); + + resource_gp = mali_find_resource(MALI_GP, 0x02000); + resource_pp = mali_find_resource(MALI_PP, 0x00000); + resource_mmu = mali_find_resource(MMU, 0x03000); + + if (NULL == resource_mmu || NULL == resource_gp || NULL == resource_pp) + { + /* Missing mandatory core(s) */ + return _MALI_OSK_ERR_FAULT; + } + + /*return mali_create_group(global_clusters[0], resource_mmu, resource_gp, resource_pp);*/ + return mali_create_group(mali_cluster_get_global_cluster(0), resource_mmu, resource_gp, resource_pp); + } + else if (_MALI_PRODUCT_ID_MALI300 == global_product_id || + _MALI_PRODUCT_ID_MALI400 == global_product_id || + _MALI_PRODUCT_ID_MALI450 == global_product_id) + { + _mali_osk_errcode_t err; + int cluster_id_gp = 0; + int cluster_id_pp_grp0 = 0; + int cluster_id_pp_grp1 = 0; + int i; + _mali_osk_resource_t *resource_gp; + _mali_osk_resource_t *resource_gp_mmu; + _mali_osk_resource_t *resource_pp[mali_pp_get_max_num_pp_cores()]; + _mali_osk_resource_t *resource_pp_mmu[mali_pp_get_max_num_pp_cores()]; + u32 max_num_pp_cores = mali_pp_get_max_num_pp_cores(); + + if (_MALI_PRODUCT_ID_MALI450 == global_product_id) + { + /* Mali-450 has separate L2s for GP, and PP core group(s) */ + cluster_id_pp_grp0 = 1; + cluster_id_pp_grp1 = 2; + } + + resource_gp = mali_find_resource(MALI_GP, 0x00000); + resource_gp_mmu = mali_find_resource(MMU, 0x03000); + resource_pp[0] = mali_find_resource(MALI_PP, 0x08000); + resource_pp[1] = mali_find_resource(MALI_PP, 0x0A000); + resource_pp[2] = mali_find_resource(MALI_PP, 0x0C000); + resource_pp[3] = mali_find_resource(MALI_PP, 0x0E000); + resource_pp[4] = mali_find_resource(MALI_PP, 0x28000); + resource_pp[5] = mali_find_resource(MALI_PP, 0x2A000); + resource_pp[6] = mali_find_resource(MALI_PP, 0x2C000); + resource_pp[7] = mali_find_resource(MALI_PP, 0x2E000); + resource_pp_mmu[0] = mali_find_resource(MMU, 0x04000); + resource_pp_mmu[1] = mali_find_resource(MMU, 0x05000); + resource_pp_mmu[2] = mali_find_resource(MMU, 0x06000); + resource_pp_mmu[3] = mali_find_resource(MMU, 0x07000); + resource_pp_mmu[4] = mali_find_resource(MMU, 0x1C000); + resource_pp_mmu[5] = mali_find_resource(MMU, 0x1D000); + resource_pp_mmu[6] = mali_find_resource(MMU, 0x1E000); + resource_pp_mmu[7] = mali_find_resource(MMU, 0x1F000); + + if (NULL == resource_gp || NULL == resource_gp_mmu || NULL == resource_pp[0] || NULL == resource_pp_mmu[0]) + { + /* Missing mandatory core(s) */ + MALI_DEBUG_PRINT(2, ("Missing mandatory resource, need at least one GP and one PP, both with a separate MMU (0x%08X, 0x%08X, 0x%08X, 0x%08X)\n", + resource_gp, resource_gp_mmu, resource_pp[0], resource_pp_mmu[0])); + return _MALI_OSK_ERR_FAULT; + } + + MALI_DEBUG_ASSERT(1 <= mali_cluster_get_glob_num_clusters()); + err = mali_create_group(mali_cluster_get_global_cluster(cluster_id_gp), resource_gp_mmu, resource_gp, NULL); + if (err != _MALI_OSK_ERR_OK) + { + return err; + } + + /* Create group for first (and mandatory) PP core */ + MALI_DEBUG_ASSERT(mali_cluster_get_glob_num_clusters() >= (cluster_id_pp_grp0 + 1)); /* >= 1 on Mali-300 and Mali-400, >= 2 on Mali-450 */ + err = mali_create_group(mali_cluster_get_global_cluster(cluster_id_pp_grp0), resource_pp_mmu[0], NULL, resource_pp[0]); + if (err != _MALI_OSK_ERR_OK) + { + return err; + } + + /* Create groups for rest of the cores in the first PP core group */ + for (i = 1; i < 4; i++) /* First half of the PP cores belong to first core group */ + { + if (NULL != resource_pp[i]) + { + err = mali_create_group(mali_cluster_get_global_cluster(cluster_id_pp_grp0), resource_pp_mmu[i], NULL, resource_pp[i]); + if (err != _MALI_OSK_ERR_OK) + { + return err; + } + } + } + + /* Create groups for cores in the second PP core group */ + for (i = 4; i < max_num_pp_cores; i++) /* Second half of the PP cores belong to second core group */ + { + if (NULL != resource_pp[i]) + { + MALI_DEBUG_ASSERT(mali_cluster_get_glob_num_clusters() >= 2); /* Only Mali-450 have more than 4 PPs, and these cores belong to second core group */ + err = mali_create_group(mali_cluster_get_global_cluster(cluster_id_pp_grp1), resource_pp_mmu[i], NULL, resource_pp[i]); + if (err != _MALI_OSK_ERR_OK) + { + return err; + } + } + } + } + + return _MALI_OSK_ERR_OK; +} + +static _mali_osk_errcode_t mali_parse_config_pmu(void) +{ + _mali_osk_errcode_t err = _MALI_OSK_ERR_OK; + _mali_osk_resource_t *resource_pmu; + u32 number_of_pp_cores; + u32 number_of_l2_caches; + + resource_pmu = mali_find_resource(PMU, 0x02000); + number_of_pp_cores = mali_count_resources(MALI_PP); + number_of_l2_caches = mali_count_resources(MALI_L2); + + if (NULL != resource_pmu) + { + if (NULL == mali_pmu_create(resource_pmu, number_of_pp_cores, number_of_l2_caches)) + { + err = _MALI_OSK_ERR_FAULT; + } + } + return err; +} + +static _mali_osk_errcode_t mali_parse_config_memory(void) +{ + int i; + _mali_osk_errcode_t ret; + + for(i = 0; i < num_resources; i++) + { + switch(arch_configuration[i].type) + { + case OS_MEMORY: + ret = mali_memory_core_resource_os_memory(&arch_configuration[i]); + if (_MALI_OSK_ERR_OK != ret) + { + MALI_PRINT_ERROR(("Failed to register OS_MEMORY\n")); + mali_memory_terminate(); + return ret; + } + break; + case MEMORY: + ret = mali_memory_core_resource_dedicated_memory(&arch_configuration[i]); + if (_MALI_OSK_ERR_OK != ret) + { + MALI_PRINT_ERROR(("Failed to register MEMORY\n")); + mali_memory_terminate(); + return ret; + } + break; + case MEM_VALIDATION: + ret = mali_mem_validation_add_range(&arch_configuration[i]); + if (_MALI_OSK_ERR_OK != ret) + { + MALI_PRINT_ERROR(("Failed to register MEM_VALIDATION\n")); + mali_memory_terminate(); + return ret; + } + break; + default: + break; + } + } + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t mali_initialize_subsystems(void) +{ + _mali_osk_errcode_t err; + mali_bool is_pmu_enabled; + + err = mali_session_initialize(); + if (_MALI_OSK_ERR_OK != err) goto session_init_failed; + +#if MALI_TIMELINE_PROFILING_ENABLED + err = _mali_osk_profiling_init(mali_boot_profiling ? MALI_TRUE : MALI_FALSE); + if (_MALI_OSK_ERR_OK != err) + { + /* No biggie if we wheren't able to initialize the profiling */ + MALI_PRINT_ERROR(("Failed to initialize profiling, feature will be unavailable\n")); + } +#endif + + /* Get data from config.h */ + err = _mali_osk_resources_init(&arch_configuration, &num_resources); + if (_MALI_OSK_ERR_OK != err) goto osk_resources_init_failed; + + /* Initialize driver subsystems */ + err = mali_memory_initialize(); + if (_MALI_OSK_ERR_OK != err) goto memory_init_failed; + + /* Configure memory early. Memory allocation needed for mali_mmu_initialize. */ + err = mali_parse_config_memory(); + if (_MALI_OSK_ERR_OK != err) goto parse_memory_config_failed; + + /* Parsing the GPU base address and first pp offset */ + err = mali_parse_gpu_base_and_first_pp_offset_address(); + if (_MALI_OSK_ERR_OK != err) goto parse_gpu_base_address_failed; + + /* Initialize the MALI PMU */ + err = mali_parse_config_pmu(); + if (_MALI_OSK_ERR_OK != err) goto parse_pmu_config_failed; + + is_pmu_enabled = mali_pmu_get_global_pmu_core() != NULL ? MALI_TRUE : MALI_FALSE; + + /* Initialize the power management module */ + err = mali_pm_initialize(); + if (_MALI_OSK_ERR_OK != err) goto pm_init_failed; + + /* Make sure the power stays on for the rest of this function */ + mali_pm_always_on(MALI_TRUE); + + /* Detect which Mali GPU we are dealing with */ + err = mali_parse_product_info(); + if (_MALI_OSK_ERR_OK != err) goto product_info_parsing_failed; + + /* The global_product_id is now populated with the correct Mali GPU */ + + /* Initialize MMU module */ + err = mali_mmu_initialize(); + if (_MALI_OSK_ERR_OK != err) goto mmu_init_failed; + + /* Initialize the DLBU module for Mali-450 */ + if (_MALI_PRODUCT_ID_MALI450 == global_product_id) + { + err = mali_dlbu_initialize(); + if (_MALI_OSK_ERR_OK != err) goto dlbu_init_failed; + } + + /* Start configuring the actual Mali hardware. */ + err = mali_parse_config_cluster(); + if (_MALI_OSK_ERR_OK != err) goto config_parsing_failed; + err = mali_parse_config_groups(); + if (_MALI_OSK_ERR_OK != err) goto config_parsing_failed; + + /* Initialize the schedulers */ + err = mali_scheduler_initialize(); + if (_MALI_OSK_ERR_OK != err) goto scheduler_init_failed; + err = mali_gp_scheduler_initialize(); + if (_MALI_OSK_ERR_OK != err) goto gp_scheduler_init_failed; + err = mali_pp_scheduler_initialize(); + if (_MALI_OSK_ERR_OK != err) goto pp_scheduler_init_failed; + +#ifdef CONFIG_MALI400_GPU_UTILIZATION + /* Initialize the GPU utilization tracking */ + err = mali_utilization_init(); + if (_MALI_OSK_ERR_OK != err) goto utilization_init_failed; +#endif + + /* We no longer need to stay */ + mali_pm_always_on(MALI_FALSE); + MALI_SUCCESS; /* all ok */ + + /* Error handling */ +#ifdef CONFIG_MALI400_GPU_UTILIZATION +utilization_init_failed: + mali_pp_scheduler_terminate(); +#endif +pp_scheduler_init_failed: + mali_gp_scheduler_terminate(); +gp_scheduler_init_failed: + mali_scheduler_terminate(); +scheduler_init_failed: +config_parsing_failed: + mali_delete_clusters(); /* Delete clusters even if config parsing failed. */ + if (_MALI_PRODUCT_ID_MALI450 == global_product_id) + { + mali_dlbu_terminate(); + } +dlbu_init_failed: + mali_mmu_terminate(); +mmu_init_failed: + /* Nothing to roll back */ +product_info_parsing_failed: + mali_pm_terminate(); +pm_init_failed: + if (is_pmu_enabled) + { + mali_pmu_delete(mali_pmu_get_global_pmu_core()); + } +parse_pmu_config_failed: +parse_gpu_base_address_failed: +parse_memory_config_failed: + mali_memory_terminate(); +memory_init_failed: + _mali_osk_resources_term(&arch_configuration, num_resources); +osk_resources_init_failed: +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_term(); +#endif + mali_session_terminate(); +session_init_failed: + return err; +} + +void mali_terminate_subsystems(void) +{ + struct mali_pmu_core *pmu; + + MALI_DEBUG_PRINT(2, ("terminate_subsystems() called\n")); + + /* shut down subsystems in reverse order from startup */ + + mali_pm_always_on(MALI_TRUE); /* Mali will be powered off once PM subsystem terminates */ + +#ifdef CONFIG_MALI400_GPU_UTILIZATION + mali_utilization_term(); +#endif + + mali_pp_scheduler_terminate(); + mali_gp_scheduler_terminate(); + mali_scheduler_terminate(); + + mali_delete_clusters(); /* Delete clusters even if config parsing failed. */ + + if (_MALI_PRODUCT_ID_MALI450 == global_product_id) + { + mali_dlbu_terminate(); + } + + mali_mmu_terminate(); + + pmu = mali_pmu_get_global_pmu_core(); + if (NULL != pmu) + { + mali_pmu_delete(pmu); + } + + mali_pm_terminate(); + + mali_memory_terminate(); + + _mali_osk_resources_term(&arch_configuration, num_resources); + +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_term(); +#endif + + mali_session_terminate(); +} + +_mali_product_id_t mali_kernel_core_get_product_id(void) +{ + return global_product_id; +} + +void mali_kernel_core_wakeup(void) +{ + u32 i; + u32 glob_num_clusters = mali_cluster_get_glob_num_clusters(); + struct mali_cluster *cluster; + + for (i = 0; i < glob_num_clusters; i++) + { + cluster = mali_cluster_get_global_cluster(i); + mali_cluster_reset(cluster); + } +} + +_mali_osk_errcode_t _mali_ukk_get_api_version( _mali_uk_get_api_version_s *args ) +{ + MALI_DEBUG_ASSERT_POINTER(args); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + + /* check compatability */ + if ( args->version == _MALI_UK_API_VERSION ) + { + args->compatible = 1; + } + else + { + args->compatible = 0; + } + + args->version = _MALI_UK_API_VERSION; /* report our version */ + + /* success regardless of being compatible or not */ + MALI_SUCCESS; +} + +_mali_osk_errcode_t _mali_ukk_wait_for_notification( _mali_uk_wait_for_notification_s *args ) +{ + _mali_osk_errcode_t err; + _mali_osk_notification_t *notification; + _mali_osk_notification_queue_t *queue; + + /* check input */ + MALI_DEBUG_ASSERT_POINTER(args); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + + queue = ((struct mali_session_data *)args->ctx)->ioctl_queue; + + /* if the queue does not exist we're currently shutting down */ + if (NULL == queue) + { + MALI_DEBUG_PRINT(1, ("No notification queue registered with the session. Asking userspace to stop querying\n")); + args->type = _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS; + MALI_SUCCESS; + } + + /* receive a notification, might sleep */ + err = _mali_osk_notification_queue_receive(queue, ¬ification); + if (_MALI_OSK_ERR_OK != err) + { + MALI_ERROR(err); /* errcode returned, pass on to caller */ + } + + /* copy the buffer to the user */ + args->type = (_mali_uk_notification_type)notification->notification_type; + _mali_osk_memcpy(&args->data, notification->result_buffer, notification->result_buffer_size); + + /* finished with the notification */ + _mali_osk_notification_delete( notification ); + + MALI_SUCCESS; /* all ok */ +} + +_mali_osk_errcode_t _mali_ukk_post_notification( _mali_uk_post_notification_s *args ) +{ + _mali_osk_notification_t * notification; + _mali_osk_notification_queue_t *queue; + + /* check input */ + MALI_DEBUG_ASSERT_POINTER(args); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + + queue = ((struct mali_session_data *)args->ctx)->ioctl_queue; + + /* if the queue does not exist we're currently shutting down */ + if (NULL == queue) + { + MALI_DEBUG_PRINT(1, ("No notification queue registered with the session. Asking userspace to stop querying\n")); + MALI_SUCCESS; + } + + notification = _mali_osk_notification_create(args->type, 0); + if ( NULL == notification) + { + MALI_PRINT_ERROR( ("Failed to create notification object\n")); + return _MALI_OSK_ERR_NOMEM; + } + + _mali_osk_notification_queue_send(queue, notification); + + MALI_SUCCESS; /* all ok */ +} + +_mali_osk_errcode_t _mali_ukk_open(void **context) +{ + struct mali_session_data *session_data; + + /* allocated struct to track this session */ + session_data = (struct mali_session_data *)_mali_osk_calloc(1, sizeof(struct mali_session_data)); + MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_NOMEM); + + MALI_DEBUG_PRINT(2, ("Session starting\n")); + + /* create a response queue for this session */ + session_data->ioctl_queue = _mali_osk_notification_queue_init(); + if (NULL == session_data->ioctl_queue) + { + _mali_osk_free(session_data); + MALI_ERROR(_MALI_OSK_ERR_NOMEM); + } + + session_data->page_directory = mali_mmu_pagedir_alloc(); + if (NULL == session_data->page_directory) + { + _mali_osk_notification_queue_term(session_data->ioctl_queue); + _mali_osk_free(session_data); + MALI_ERROR(_MALI_OSK_ERR_NOMEM); + } + + if (_MALI_OSK_ERR_OK != mali_mmu_pagedir_map(session_data->page_directory, MALI_DLB_VIRT_ADDR, _MALI_OSK_MALI_PAGE_SIZE)) + { + MALI_PRINT_ERROR(("Failed to map DLB page into session\n")); + _mali_osk_notification_queue_term(session_data->ioctl_queue); + _mali_osk_free(session_data); + MALI_ERROR(_MALI_OSK_ERR_NOMEM); + } + + if (0 != mali_dlbu_phys_addr) + { + mali_mmu_pagedir_update(session_data->page_directory, MALI_DLB_VIRT_ADDR, mali_dlbu_phys_addr, _MALI_OSK_MALI_PAGE_SIZE, MALI_CACHE_STANDARD); + } + + if (_MALI_OSK_ERR_OK != mali_memory_session_begin(session_data)) + { + mali_mmu_pagedir_free(session_data->page_directory); + _mali_osk_notification_queue_term(session_data->ioctl_queue); + _mali_osk_free(session_data); + MALI_ERROR(_MALI_OSK_ERR_NOMEM); + } + + *context = (void*)session_data; + + /* Add session to the list of all sessions. */ + mali_session_add(session_data); + + MALI_DEBUG_PRINT(3, ("Session started\n")); + MALI_SUCCESS; +} + +_mali_osk_errcode_t _mali_ukk_close(void **context) +{ + struct mali_session_data *session; + MALI_CHECK_NON_NULL(context, _MALI_OSK_ERR_INVALID_ARGS); + session = (struct mali_session_data *)*context; + + MALI_DEBUG_PRINT(3, ("Session ending\n")); + + /* Remove session from list of all sessions. */ + mali_session_remove(session); + + /* Abort queued and running jobs */ + mali_gp_scheduler_abort_session(session); + mali_pp_scheduler_abort_session(session); + + /* Flush pending work. + * Needed to make sure all bottom half processing related to this + * session has been completed, before we free internal data structures. + */ + _mali_osk_flush_workqueue(NULL); + + /* Free remaining memory allocated to this session */ + mali_memory_session_end(session); + + /* Free session data structures */ + mali_mmu_pagedir_free(session->page_directory); + _mali_osk_notification_queue_term(session->ioctl_queue); + _mali_osk_free(session); + + *context = NULL; + + MALI_DEBUG_PRINT(2, ("Session has ended\n")); + + MALI_SUCCESS; +} + +#if MALI_STATE_TRACKING +u32 _mali_kernel_core_dump_state(char* buf, u32 size) +{ + int n = 0; /* Number of bytes written to buf */ + + n += mali_gp_scheduler_dump_state(buf + n, size - n); + n += mali_pp_scheduler_dump_state(buf + n, size - n); + + return n; +} +#endif diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_core.h b/drivers/media/video/samsung/mali/common/mali_kernel_core.h new file mode 100644 index 0000000..d424c48 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_kernel_core.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_KERNEL_CORE_H__ +#define __MALI_KERNEL_CORE_H__ + +#include "mali_osk.h" + +extern int mali_hang_check_interval; +extern int mali_max_job_runtime; + +typedef enum +{ + _MALI_PRODUCT_ID_UNKNOWN, + _MALI_PRODUCT_ID_MALI200, + _MALI_PRODUCT_ID_MALI300, + _MALI_PRODUCT_ID_MALI400, + _MALI_PRODUCT_ID_MALI450, +} _mali_product_id_t; + +_mali_osk_errcode_t mali_initialize_subsystems(void); + +void mali_terminate_subsystems(void); + +void mali_kernel_core_wakeup(void); + +_mali_product_id_t mali_kernel_core_get_product_id(void); + +u32 _mali_kernel_core_dump_state(char* buf, u32 size); + +#endif /* __MALI_KERNEL_CORE_H__ */ + diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.c b/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.c new file mode 100644 index 0000000..b9f05ca --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.c @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_kernel_common.h" +#include "mali_kernel_descriptor_mapping.h" +#include "mali_osk.h" +#include "mali_osk_bitops.h" + +#define MALI_PAD_INT(x) (((x) + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1)) + +/** + * Allocate a descriptor table capable of holding 'count' mappings + * @param count Number of mappings in the table + * @return Pointer to a new table, NULL on error + */ +static mali_descriptor_table * descriptor_table_alloc(int count); + +/** + * Free a descriptor table + * @param table The table to free + */ +static void descriptor_table_free(mali_descriptor_table * table); + +mali_descriptor_mapping * mali_descriptor_mapping_create(int init_entries, int max_entries) +{ + mali_descriptor_mapping * map = _mali_osk_calloc(1, sizeof(mali_descriptor_mapping)); + + init_entries = MALI_PAD_INT(init_entries); + max_entries = MALI_PAD_INT(max_entries); + + if (NULL != map) + { + map->table = descriptor_table_alloc(init_entries); + if (NULL != map->table) + { + map->lock = _mali_osk_lock_init( (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, _MALI_OSK_LOCK_ORDER_DESCRIPTOR_MAP); + if (NULL != map->lock) + { + _mali_osk_set_nonatomic_bit(0, map->table->usage); /* reserve bit 0 to prevent NULL/zero logic to kick in */ + map->max_nr_mappings_allowed = max_entries; + map->current_nr_mappings = init_entries; + return map; + } + descriptor_table_free(map->table); + } + _mali_osk_free(map); + } + return NULL; +} + +void mali_descriptor_mapping_destroy(mali_descriptor_mapping * map) +{ + descriptor_table_free(map->table); + _mali_osk_lock_term(map->lock); + _mali_osk_free(map); +} + +_mali_osk_errcode_t mali_descriptor_mapping_allocate_mapping(mali_descriptor_mapping * map, void * target, int *odescriptor) +{ + _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT; + int new_descriptor; + + MALI_DEBUG_ASSERT_POINTER(map); + MALI_DEBUG_ASSERT_POINTER(odescriptor); + + _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW); + new_descriptor = _mali_osk_find_first_zero_bit(map->table->usage, map->current_nr_mappings); + if (new_descriptor == map->current_nr_mappings) + { + /* no free descriptor, try to expand the table */ + mali_descriptor_table * new_table, * old_table; + if (map->current_nr_mappings >= map->max_nr_mappings_allowed) goto unlock_and_exit; + + map->current_nr_mappings += BITS_PER_LONG; + new_table = descriptor_table_alloc(map->current_nr_mappings); + if (NULL == new_table) goto unlock_and_exit; + + old_table = map->table; + _mali_osk_memcpy(new_table->usage, old_table->usage, (sizeof(unsigned long)*map->current_nr_mappings) / BITS_PER_LONG); + _mali_osk_memcpy(new_table->mappings, old_table->mappings, map->current_nr_mappings * sizeof(void*)); + map->table = new_table; + descriptor_table_free(old_table); + } + + /* we have found a valid descriptor, set the value and usage bit */ + _mali_osk_set_nonatomic_bit(new_descriptor, map->table->usage); + map->table->mappings[new_descriptor] = target; + *odescriptor = new_descriptor; + err = _MALI_OSK_ERR_OK; + +unlock_and_exit: + _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RW); + MALI_ERROR(err); +} + +void mali_descriptor_mapping_call_for_each(mali_descriptor_mapping * map, void (*callback)(int, void*)) +{ + int i; + + MALI_DEBUG_ASSERT_POINTER(map); + MALI_DEBUG_ASSERT_POINTER(callback); + + _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO); + /* id 0 is skipped as it's an reserved ID not mapping to anything */ + for (i = 1; i < map->current_nr_mappings; ++i) + { + if (_mali_osk_test_bit(i, map->table->usage)) + { + callback(i, map->table->mappings[i]); + } + } + _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO); +} + +_mali_osk_errcode_t mali_descriptor_mapping_get(mali_descriptor_mapping * map, int descriptor, void** target) +{ + _mali_osk_errcode_t result = _MALI_OSK_ERR_FAULT; + MALI_DEBUG_ASSERT_POINTER(map); + _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO); + if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) ) + { + *target = map->table->mappings[descriptor]; + result = _MALI_OSK_ERR_OK; + } + else *target = NULL; + _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO); + MALI_ERROR(result); +} + +_mali_osk_errcode_t mali_descriptor_mapping_set(mali_descriptor_mapping * map, int descriptor, void * target) +{ + _mali_osk_errcode_t result = _MALI_OSK_ERR_FAULT; + _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO); + if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) ) + { + map->table->mappings[descriptor] = target; + result = _MALI_OSK_ERR_OK; + } + _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO); + MALI_ERROR(result); +} + +void *mali_descriptor_mapping_free(mali_descriptor_mapping * map, int descriptor) +{ + void *old_value = NULL; + + _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW); + if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) ) + { + old_value = map->table->mappings[descriptor]; + map->table->mappings[descriptor] = NULL; + _mali_osk_clear_nonatomic_bit(descriptor, map->table->usage); + } + _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RW); + + return old_value; +} + +static mali_descriptor_table * descriptor_table_alloc(int count) +{ + mali_descriptor_table * table; + + table = _mali_osk_calloc(1, sizeof(mali_descriptor_table) + ((sizeof(unsigned long) * count)/BITS_PER_LONG) + (sizeof(void*) * count)); + + if (NULL != table) + { + table->usage = (u32*)((u8*)table + sizeof(mali_descriptor_table)); + table->mappings = (void**)((u8*)table + sizeof(mali_descriptor_table) + ((sizeof(unsigned long) * count)/BITS_PER_LONG)); + } + + return table; +} + +static void descriptor_table_free(mali_descriptor_table * table) +{ + _mali_osk_free(table); +} diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.h b/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.h new file mode 100644 index 0000000..82ed94d --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_kernel_descriptor_mapping.h + */ + +#ifndef __MALI_KERNEL_DESCRIPTOR_MAPPING_H__ +#define __MALI_KERNEL_DESCRIPTOR_MAPPING_H__ + +#include "mali_osk.h" + +/** + * The actual descriptor mapping table, never directly accessed by clients + */ +typedef struct mali_descriptor_table +{ + u32 * usage; /**< Pointer to bitpattern indicating if a descriptor is valid/used or not */ + void** mappings; /**< Array of the pointers the descriptors map to */ +} mali_descriptor_table; + +/** + * The descriptor mapping object + * Provides a separate namespace where we can map an integer to a pointer + */ +typedef struct mali_descriptor_mapping +{ + _mali_osk_lock_t *lock; /**< Lock protecting access to the mapping object */ + int max_nr_mappings_allowed; /**< Max number of mappings to support in this namespace */ + int current_nr_mappings; /**< Current number of possible mappings */ + mali_descriptor_table * table; /**< Pointer to the current mapping table */ +} mali_descriptor_mapping; + +/** + * Create a descriptor mapping object + * Create a descriptor mapping capable of holding init_entries growable to max_entries + * @param init_entries Number of entries to preallocate memory for + * @param max_entries Number of entries to max support + * @return Pointer to a descriptor mapping object, NULL on failure + */ +mali_descriptor_mapping * mali_descriptor_mapping_create(int init_entries, int max_entries); + +/** + * Destroy a descriptor mapping object + * @param map The map to free + */ +void mali_descriptor_mapping_destroy(mali_descriptor_mapping * map); + +/** + * Allocate a new mapping entry (descriptor ID) + * Allocates a new entry in the map. + * @param map The map to allocate a new entry in + * @param target The value to map to + * @return The descriptor allocated, a negative value on error + */ +_mali_osk_errcode_t mali_descriptor_mapping_allocate_mapping(mali_descriptor_mapping * map, void * target, int *descriptor); + +/** + * Get the value mapped to by a descriptor ID + * @param map The map to lookup the descriptor id in + * @param descriptor The descriptor ID to lookup + * @param target Pointer to a pointer which will receive the stored value + * @return 0 on successful lookup, negative on error + */ +_mali_osk_errcode_t mali_descriptor_mapping_get(mali_descriptor_mapping * map, int descriptor, void** target); + +/** + * Set the value mapped to by a descriptor ID + * @param map The map to lookup the descriptor id in + * @param descriptor The descriptor ID to lookup + * @param target Pointer to replace the current value with + * @return 0 on successful lookup, negative on error + */ +_mali_osk_errcode_t mali_descriptor_mapping_set(mali_descriptor_mapping * map, int descriptor, void * target); + +/** + * Call the specified callback function for each descriptor in map. + * Entire function is mutex protected. + * @param map The map to do callbacks for + * @param callback A callback function which will be calle for each entry in map + */ +void mali_descriptor_mapping_call_for_each(mali_descriptor_mapping * map, void (*callback)(int, void*)); + +/** + * Free the descriptor ID + * For the descriptor to be reused it has to be freed + * @param map The map to free the descriptor from + * @param descriptor The descriptor ID to free + * + * @return old value of descriptor mapping + */ +void *mali_descriptor_mapping_free(mali_descriptor_mapping * map, int descriptor); + +#endif /* __MALI_KERNEL_DESCRIPTOR_MAPPING_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c b/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c new file mode 100644 index 0000000..8ff3d37 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c @@ -0,0 +1,354 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_kernel_common.h" +#include "mali_kernel_core.h" +#include "mali_kernel_memory_engine.h" +#include "mali_osk.h" + +typedef struct os_allocation +{ + u32 num_pages; + u32 offset_start; + mali_allocation_engine * engine; + mali_memory_allocation * descriptor; +} os_allocation; + +typedef struct os_allocator +{ + _mali_osk_lock_t *mutex; + + /** + * Maximum number of pages to allocate from the OS + */ + u32 num_pages_max; + + /** + * Number of pages allocated from the OS + */ + u32 num_pages_allocated; + + /** CPU Usage adjustment (add to mali physical address to get cpu physical address) */ + u32 cpu_usage_adjust; +} os_allocator; + +static mali_physical_memory_allocation_result os_allocator_allocate(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info); +static mali_physical_memory_allocation_result os_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block); +static void os_allocator_release(void * ctx, void * handle); +static void os_allocator_page_table_block_release( mali_page_table_block *page_table_block ); +static void os_allocator_destroy(mali_physical_memory_allocator * allocator); +static u32 os_allocator_stat(mali_physical_memory_allocator * allocator); + +mali_physical_memory_allocator * mali_os_allocator_create(u32 max_allocation, u32 cpu_usage_adjust, const char *name) +{ + mali_physical_memory_allocator * allocator; + os_allocator * info; + + max_allocation = (max_allocation + _MALI_OSK_CPU_PAGE_SIZE-1) & ~(_MALI_OSK_CPU_PAGE_SIZE-1); + + MALI_DEBUG_PRINT(2, ("Mali OS memory allocator created with max allocation size of 0x%X bytes, cpu_usage_adjust 0x%08X\n", max_allocation, cpu_usage_adjust)); + + allocator = _mali_osk_malloc(sizeof(mali_physical_memory_allocator)); + if (NULL != allocator) + { + info = _mali_osk_malloc(sizeof(os_allocator)); + if (NULL != info) + { + info->num_pages_max = max_allocation / _MALI_OSK_CPU_PAGE_SIZE; + info->num_pages_allocated = 0; + info->cpu_usage_adjust = cpu_usage_adjust; + + info->mutex = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_ORDERED, 0, _MALI_OSK_LOCK_ORDER_MEM_INFO); + if (NULL != info->mutex) + { + allocator->allocate = os_allocator_allocate; + allocator->allocate_page_table_block = os_allocator_allocate_page_table_block; + allocator->destroy = os_allocator_destroy; + allocator->stat = os_allocator_stat; + allocator->ctx = info; + allocator->name = name; + + return allocator; + } + _mali_osk_free(info); + } + _mali_osk_free(allocator); + } + + return NULL; +} + +static u32 os_allocator_stat(mali_physical_memory_allocator * allocator) +{ + os_allocator * info; + info = (os_allocator*)allocator->ctx; + return info->num_pages_allocated * _MALI_OSK_MALI_PAGE_SIZE; +} + +static void os_allocator_destroy(mali_physical_memory_allocator * allocator) +{ + os_allocator * info; + MALI_DEBUG_ASSERT_POINTER(allocator); + MALI_DEBUG_ASSERT_POINTER(allocator->ctx); + info = (os_allocator*)allocator->ctx; + _mali_osk_lock_term(info->mutex); + _mali_osk_free(info); + _mali_osk_free(allocator); +} + +static mali_physical_memory_allocation_result os_allocator_allocate(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info) +{ + mali_physical_memory_allocation_result result = MALI_MEM_ALLOC_NONE; + u32 left; + os_allocator * info; + os_allocation * allocation; + int pages_allocated = 0; + _mali_osk_errcode_t err = _MALI_OSK_ERR_OK; + + MALI_DEBUG_ASSERT_POINTER(ctx); + MALI_DEBUG_ASSERT_POINTER(engine); + MALI_DEBUG_ASSERT_POINTER(descriptor); + MALI_DEBUG_ASSERT_POINTER(offset); + MALI_DEBUG_ASSERT_POINTER(alloc_info); + + info = (os_allocator*)ctx; + left = descriptor->size - *offset; + + if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) return MALI_MEM_ALLOC_INTERNAL_FAILURE; + + /** @note this code may not work on Linux, or may require a more complex Linux implementation */ + allocation = _mali_osk_malloc(sizeof(os_allocation)); + if (NULL != allocation) + { + u32 os_mem_max_usage = info->num_pages_max * _MALI_OSK_CPU_PAGE_SIZE; + allocation->offset_start = *offset; + allocation->num_pages = ((left + _MALI_OSK_CPU_PAGE_SIZE - 1) & ~(_MALI_OSK_CPU_PAGE_SIZE - 1)) >> _MALI_OSK_CPU_PAGE_ORDER; + MALI_DEBUG_PRINT(6, ("Allocating page array of size %d bytes\n", allocation->num_pages * sizeof(struct page*))); + + while (left > 0) + { + err = mali_allocation_engine_map_physical(engine, descriptor, *offset, MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC, info->cpu_usage_adjust, _MALI_OSK_CPU_PAGE_SIZE); + if ( _MALI_OSK_ERR_OK != err) + { + if ( _MALI_OSK_ERR_NOMEM == err) + { + /* 'Partial' allocation (or, out-of-memory on first page) */ + break; + } + + MALI_DEBUG_PRINT(1, ("Mapping of physical memory failed\n")); + + /* Fatal error, cleanup any previous pages allocated. */ + if ( pages_allocated > 0 ) + { + mali_allocation_engine_unmap_physical( engine, descriptor, allocation->offset_start, _MALI_OSK_CPU_PAGE_SIZE*pages_allocated, _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR ); + /* (*offset) doesn't need to be restored; it will not be used by the caller on failure */ + } + + pages_allocated = 0; + + result = MALI_MEM_ALLOC_INTERNAL_FAILURE; + break; + } + + /* Loop iteration */ + if (left < _MALI_OSK_CPU_PAGE_SIZE) left = 0; + else left -= _MALI_OSK_CPU_PAGE_SIZE; + + pages_allocated++; + + *offset += _MALI_OSK_CPU_PAGE_SIZE; + } + + if (left) MALI_PRINT(("Out of memory. Mali memory allocated: %d kB Configured maximum OS memory usage: %d kB\n", + (info->num_pages_allocated * _MALI_OSK_CPU_PAGE_SIZE)/1024, (info->num_pages_max* _MALI_OSK_CPU_PAGE_SIZE)/1024)); + + /* Loop termination; decide on result */ + if (pages_allocated) + { + MALI_DEBUG_PRINT(6, ("Allocated %d pages\n", pages_allocated)); + if (left) result = MALI_MEM_ALLOC_PARTIAL; + else result = MALI_MEM_ALLOC_FINISHED; + + /* Some OS do not perform a full cache flush (including all outer caches) for uncached mapped memory. + * They zero the memory through a cached mapping, then flush the inner caches but not the outer caches. + * This is required for MALI to have the correct view of the memory. + */ + _mali_osk_cache_ensure_uncached_range_flushed( (void *)descriptor, allocation->offset_start, pages_allocated *_MALI_OSK_CPU_PAGE_SIZE ); + allocation->num_pages = pages_allocated; + allocation->engine = engine; /* Necessary to make the engine's unmap call */ + allocation->descriptor = descriptor; /* Necessary to make the engine's unmap call */ + info->num_pages_allocated += pages_allocated; + + MALI_DEBUG_PRINT(6, ("%d out of %d pages now allocated\n", info->num_pages_allocated, info->num_pages_max)); + + alloc_info->ctx = info; + alloc_info->handle = allocation; + alloc_info->release = os_allocator_release; + } + else + { + MALI_DEBUG_PRINT(6, ("Releasing pages array due to no pages allocated\n")); + _mali_osk_free( allocation ); + } + } + + _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); + + return result; +} + +static void os_allocator_release(void * ctx, void * handle) +{ + os_allocator * info; + os_allocation * allocation; + mali_allocation_engine * engine; + mali_memory_allocation * descriptor; + + MALI_DEBUG_ASSERT_POINTER(ctx); + MALI_DEBUG_ASSERT_POINTER(handle); + + info = (os_allocator*)ctx; + allocation = (os_allocation*)handle; + engine = allocation->engine; + descriptor = allocation->descriptor; + + MALI_DEBUG_ASSERT_POINTER( engine ); + MALI_DEBUG_ASSERT_POINTER( descriptor ); + + if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) + { + MALI_DEBUG_PRINT(1, ("allocator release: Failed to get mutex\n")); + return; + } + + MALI_DEBUG_PRINT(6, ("Releasing %d os pages\n", allocation->num_pages)); + + MALI_DEBUG_ASSERT( allocation->num_pages <= info->num_pages_allocated); + info->num_pages_allocated -= allocation->num_pages; + + mali_allocation_engine_unmap_physical( engine, descriptor, allocation->offset_start, _MALI_OSK_CPU_PAGE_SIZE*allocation->num_pages, _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR ); + + _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); + + _mali_osk_free(allocation); +} + +static mali_physical_memory_allocation_result os_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block) +{ +#if defined(CONFIG_MACH_KONA) +#ifndef CONFIG_FORCE_MAX_ZONEORDER + int allocation_order = 10; +#else + int allocation_order = CONFIG_FORCE_MAX_ZONEORDER - 1; +#endif +#else + int allocation_order = 11; /* _MALI_OSK_CPU_PAGE_SIZE << 6 */ +#endif + void *virt = NULL; + u32 size = _MALI_OSK_CPU_PAGE_SIZE << allocation_order; + os_allocator * info; + + u32 cpu_phys_base; + + MALI_DEBUG_ASSERT_POINTER(ctx); + info = (os_allocator*)ctx; + + /* Ensure we don't allocate more than we're supposed to from the ctx */ + if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) return MALI_MEM_ALLOC_INTERNAL_FAILURE; + + /* if the number of pages to be requested lead to exceeding the memory + * limit in info->num_pages_max, reduce the size that is to be requested. */ + while ( (info->num_pages_allocated + (1 << allocation_order) > info->num_pages_max) + && _mali_osk_mem_check_allocated(info->num_pages_max * _MALI_OSK_CPU_PAGE_SIZE) ) + { + if ( allocation_order > 0 ) { + --allocation_order; + } else { + /* return OOM */ + _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); + return MALI_MEM_ALLOC_NONE; + } + } + + /* try to allocate 2^(allocation_order) pages, if that fails, try + * allocation_order-1 to allocation_order 0 (inclusive) */ + while ( allocation_order >= 0 ) + { + size = _MALI_OSK_CPU_PAGE_SIZE << allocation_order; + virt = _mali_osk_mem_allocioregion( &cpu_phys_base, size ); + + if (NULL != virt) break; + + --allocation_order; + } + + if ( NULL == virt ) + { + MALI_DEBUG_PRINT(1, ("Failed to allocate consistent memory. Is CONSISTENT_DMA_SIZE set too low?\n")); + /* return OOM */ + _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); + return MALI_MEM_ALLOC_NONE; + } + + MALI_DEBUG_PRINT(5, ("os_allocator_allocate_page_table_block: Allocation of order %i succeeded\n", + allocation_order)); + + /* we now know the size of the allocation since we know for what + * allocation_order the allocation succeeded */ + size = _MALI_OSK_CPU_PAGE_SIZE << allocation_order; + + + block->release = os_allocator_page_table_block_release; + block->ctx = ctx; + block->handle = (void*)allocation_order; + block->size = size; + block->phys_base = cpu_phys_base - info->cpu_usage_adjust; + block->mapping = virt; + + info->num_pages_allocated += (1 << allocation_order); + + _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); + + return MALI_MEM_ALLOC_FINISHED; +} + +static void os_allocator_page_table_block_release( mali_page_table_block *page_table_block ) +{ + os_allocator * info; + u32 allocation_order; + u32 pages_allocated; + + MALI_DEBUG_ASSERT_POINTER( page_table_block ); + + info = (os_allocator*)page_table_block->ctx; + + MALI_DEBUG_ASSERT_POINTER( info ); + + allocation_order = (u32)page_table_block->handle; + + pages_allocated = 1 << allocation_order; + + MALI_DEBUG_ASSERT( pages_allocated * _MALI_OSK_CPU_PAGE_SIZE == page_table_block->size ); + + if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) + { + MALI_DEBUG_PRINT(1, ("allocator release: Failed to get mutex\n")); + return; + } + + MALI_DEBUG_ASSERT( pages_allocated <= info->num_pages_allocated); + info->num_pages_allocated -= pages_allocated; + + /* Adjust phys_base from mali physical address to CPU physical address */ + _mali_osk_mem_freeioregion( page_table_block->phys_base + info->cpu_usage_adjust, page_table_block->size, page_table_block->mapping ); + + _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); +} diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.h b/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.h new file mode 100644 index 0000000..59e6494 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_KERNEL_MEM_OS_H__ +#define __MALI_KERNEL_MEM_OS_H__ + +/** + * @brief Creates an object that manages allocating OS memory + * + * Creates an object that provides an interface to allocate OS memory and + * have it mapped into the Mali virtual memory space. + * + * The object exposes pointers to + * - allocate OS memory + * - allocate Mali page tables in OS memory + * - destroy the object + * + * Allocations from OS memory are of type mali_physical_memory_allocation + * which provides a function to release the allocation. + * + * @param max_allocation max. number of bytes that can be allocated from OS memory + * @param cpu_usage_adjust value to add to mali physical addresses to obtain CPU physical addresses + * @param name description of the allocator + * @return pointer to mali_physical_memory_allocator object. NULL on failure. + **/ +mali_physical_memory_allocator * mali_os_allocator_create(u32 max_allocation, u32 cpu_usage_adjust, const char *name); + +#endif /* __MALI_KERNEL_MEM_OS_H__ */ + + diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.c b/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.c new file mode 100644 index 0000000..d770e3e --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.c @@ -0,0 +1,376 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_kernel_common.h" +#include "mali_kernel_core.h" +#include "mali_kernel_memory_engine.h" +#include "mali_osk.h" +#include "mali_osk_list.h" + +typedef struct memory_engine +{ + mali_kernel_mem_address_manager * mali_address; + mali_kernel_mem_address_manager * process_address; +} memory_engine; + +mali_allocation_engine mali_allocation_engine_create(mali_kernel_mem_address_manager * mali_address_manager, mali_kernel_mem_address_manager * process_address_manager) +{ + memory_engine * engine; + + /* Mali Address Manager need not support unmap_physical */ + MALI_DEBUG_ASSERT_POINTER(mali_address_manager); + MALI_DEBUG_ASSERT_POINTER(mali_address_manager->allocate); + MALI_DEBUG_ASSERT_POINTER(mali_address_manager->release); + MALI_DEBUG_ASSERT_POINTER(mali_address_manager->map_physical); + + /* Process Address Manager must support unmap_physical for OS allocation + * error path handling */ + MALI_DEBUG_ASSERT_POINTER(process_address_manager); + MALI_DEBUG_ASSERT_POINTER(process_address_manager->allocate); + MALI_DEBUG_ASSERT_POINTER(process_address_manager->release); + MALI_DEBUG_ASSERT_POINTER(process_address_manager->map_physical); + MALI_DEBUG_ASSERT_POINTER(process_address_manager->unmap_physical); + + + engine = (memory_engine*)_mali_osk_malloc(sizeof(memory_engine)); + if (NULL == engine) return NULL; + + engine->mali_address = mali_address_manager; + engine->process_address = process_address_manager; + + return (mali_allocation_engine)engine; +} + +void mali_allocation_engine_destroy(mali_allocation_engine engine) +{ + MALI_DEBUG_ASSERT_POINTER(engine); + _mali_osk_free(engine); +} + +_mali_osk_errcode_t mali_allocation_engine_allocate_memory(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor, mali_physical_memory_allocator * physical_allocators, _mali_osk_list_t *tracking_list ) +{ + memory_engine * engine = (memory_engine*)mem_engine; + + MALI_DEBUG_ASSERT_POINTER(engine); + MALI_DEBUG_ASSERT_POINTER(descriptor); + MALI_DEBUG_ASSERT_POINTER(physical_allocators); + /* ASSERT that the list member has been initialized, even if it won't be + * used for tracking. We need it to be initialized to see if we need to + * delete it from a list in the release function. */ + MALI_DEBUG_ASSERT( NULL != descriptor->list.next && NULL != descriptor->list.prev ); + + if (_MALI_OSK_ERR_OK == engine->mali_address->allocate(descriptor)) + { + _mali_osk_errcode_t res = _MALI_OSK_ERR_OK; + if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE ) + { + res = engine->process_address->allocate(descriptor); + } + if ( _MALI_OSK_ERR_OK == res ) + { + /* address space setup OK, commit physical memory to the allocation */ + mali_physical_memory_allocator * active_allocator = physical_allocators; + struct mali_physical_memory_allocation * active_allocation_tracker = &descriptor->physical_allocation; + u32 offset = 0; + + while ( NULL != active_allocator ) + { + switch (active_allocator->allocate(active_allocator->ctx, mem_engine, descriptor, &offset, active_allocation_tracker)) + { + case MALI_MEM_ALLOC_FINISHED: + if ( NULL != tracking_list ) + { + /* Insert into the memory session list */ + /* ASSERT that it is not already part of a list */ + MALI_DEBUG_ASSERT( _mali_osk_list_empty( &descriptor->list ) ); + _mali_osk_list_add( &descriptor->list, tracking_list ); + } + + MALI_SUCCESS; /* all done */ + case MALI_MEM_ALLOC_NONE: + /* reuse current active_allocation_tracker */ + MALI_DEBUG_PRINT( 4, ("Memory Engine Allocate: No allocation on %s, resorting to %s\n", + ( active_allocator->name ) ? active_allocator->name : "UNNAMED", + ( active_allocator->next ) ? (( active_allocator->next->name )? active_allocator->next->name : "UNNAMED") : "NONE") ); + active_allocator = active_allocator->next; + break; + case MALI_MEM_ALLOC_PARTIAL: + if (NULL != active_allocator->next) + { + /* need a new allocation tracker */ + active_allocation_tracker->next = _mali_osk_calloc(1, sizeof(mali_physical_memory_allocation)); + if (NULL != active_allocation_tracker->next) + { + active_allocation_tracker = active_allocation_tracker->next; + MALI_DEBUG_PRINT( 2, ("Memory Engine Allocate: Partial allocation on %s, resorting to %s\n", + ( active_allocator->name ) ? active_allocator->name : "UNNAMED", + ( active_allocator->next ) ? (( active_allocator->next->name )? active_allocator->next->name : "UNNAMED") : "NONE") ); + active_allocator = active_allocator->next; + break; + } + } + /* FALL THROUGH */ + case MALI_MEM_ALLOC_INTERNAL_FAILURE: + active_allocator = NULL; /* end the while loop */ + break; + } + } + + MALI_PRINT(("Memory allocate failed, could not allocate size %d kB.\n", descriptor->size/1024)); + + /* allocation failure, start cleanup */ + /* loop over any potential partial allocations */ + active_allocation_tracker = &descriptor->physical_allocation; + while (NULL != active_allocation_tracker) + { + /* handle blank trackers which will show up during failure */ + if (NULL != active_allocation_tracker->release) + { + active_allocation_tracker->release(active_allocation_tracker->ctx, active_allocation_tracker->handle); + } + active_allocation_tracker = active_allocation_tracker->next; + } + + /* free the allocation tracker objects themselves, skipping the tracker stored inside the descriptor itself */ + for ( active_allocation_tracker = descriptor->physical_allocation.next; active_allocation_tracker != NULL; ) + { + void * buf = active_allocation_tracker; + active_allocation_tracker = active_allocation_tracker->next; + _mali_osk_free(buf); + } + + /* release the address spaces */ + + if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE ) + { + engine->process_address->release(descriptor); + } + } + engine->mali_address->release(descriptor); + } + + MALI_ERROR(_MALI_OSK_ERR_FAULT); +} + +void mali_allocation_engine_release_memory(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor) +{ + mali_allocation_engine_release_pt1_mali_pagetables_unmap(mem_engine, descriptor); + mali_allocation_engine_release_pt2_physical_memory_free(mem_engine, descriptor); +} + +void mali_allocation_engine_release_pt1_mali_pagetables_unmap(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor) +{ + memory_engine * engine = (memory_engine*)mem_engine; + + MALI_DEBUG_ASSERT_POINTER(engine); + MALI_DEBUG_ASSERT_POINTER(descriptor); + + /* Calling: mali_address_manager_release() */ + /* This function is allowed to be called several times, and it only does the release on the first call. */ + engine->mali_address->release(descriptor); +} + +void mali_allocation_engine_release_pt2_physical_memory_free(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor) +{ + memory_engine * engine = (memory_engine*)mem_engine; + mali_physical_memory_allocation * active_allocation_tracker; + + /* Remove this from a tracking list in session_data->memory_head */ + if ( ! _mali_osk_list_empty( &descriptor->list ) ) + { + _mali_osk_list_del( &descriptor->list ); + /* Clear the list for debug mode, catch use-after-free */ + MALI_DEBUG_CODE( descriptor->list.next = descriptor->list.prev = NULL; ) + } + + active_allocation_tracker = &descriptor->physical_allocation; + while (NULL != active_allocation_tracker) + { + MALI_DEBUG_ASSERT_POINTER(active_allocation_tracker->release); + active_allocation_tracker->release(active_allocation_tracker->ctx, active_allocation_tracker->handle); + active_allocation_tracker = active_allocation_tracker->next; + } + + /* free the allocation tracker objects themselves, skipping the tracker stored inside the descriptor itself */ + for ( active_allocation_tracker = descriptor->physical_allocation.next; active_allocation_tracker != NULL; ) + { + void * buf = active_allocation_tracker; + active_allocation_tracker = active_allocation_tracker->next; + _mali_osk_free(buf); + } + + if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE ) + { + engine->process_address->release(descriptor); + } +} + +_mali_osk_errcode_t mali_allocation_engine_map_physical(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor, u32 offset, u32 phys, u32 cpu_usage_adjust, u32 size) +{ + _mali_osk_errcode_t err; + memory_engine * engine = (memory_engine*)mem_engine; + _mali_osk_mem_mapregion_flags_t unmap_flags = (_mali_osk_mem_mapregion_flags_t)0; + + MALI_DEBUG_ASSERT_POINTER(engine); + MALI_DEBUG_ASSERT_POINTER(descriptor); + + MALI_DEBUG_PRINT(7, ("Mapping phys 0x%08X length 0x%08X at offset 0x%08X\n", phys, size, offset)); + + MALI_DEBUG_ASSERT_POINTER(engine->mali_address); + MALI_DEBUG_ASSERT_POINTER(engine->mali_address->map_physical); + + /* Handle process address manager first, because we may need them to + * allocate the physical page */ + if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE ) + { + /* Handle OS-allocated specially, since an adjustment may be required */ + if ( MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC == phys ) + { + MALI_DEBUG_ASSERT( _MALI_OSK_CPU_PAGE_SIZE == size ); + + /* Set flags to use on error path */ + unmap_flags |= _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR; + + err = engine->process_address->map_physical(descriptor, offset, &phys, size); + /* Adjust for cpu physical address to mali physical address */ + phys -= cpu_usage_adjust; + } + else + { + u32 cpu_phys; + /* Adjust mali physical address to cpu physical address */ + cpu_phys = phys + cpu_usage_adjust; + err = engine->process_address->map_physical(descriptor, offset, &cpu_phys, size); + } + + if ( _MALI_OSK_ERR_OK != err ) + { + MALI_DEBUG_PRINT(2, ("Map failed: %s %d\n", __FUNCTION__, __LINE__)); + MALI_ERROR( err ); + } + } + + MALI_DEBUG_PRINT(7, ("Mapping phys 0x%08X length 0x%08X at offset 0x%08X to CPUVA 0x%08X\n", phys, size, offset, (u32)(descriptor->mapping) + offset)); + + /* Mali address manager must use the physical address - no point in asking + * it to allocate another one for us */ + MALI_DEBUG_ASSERT( MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC != phys ); + + err = engine->mali_address->map_physical(descriptor, offset, &phys, size); + + if ( _MALI_OSK_ERR_OK != err ) + { + if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE ) + { + MALI_DEBUG_PRINT( 2, ("Process address manager succeeded, but Mali Address manager failed for phys=0x%08X size=0x%08X, offset=0x%08X. Will unmap.\n", phys, size, offset)); + engine->process_address->unmap_physical(descriptor, offset, size, unmap_flags); + } + MALI_DEBUG_PRINT(2, ("Map mali failed: %s %d\n", __FUNCTION__, __LINE__)); + MALI_ERROR( err ); + } + + MALI_SUCCESS; +} + +void mali_allocation_engine_unmap_physical(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t unmap_flags ) +{ + memory_engine * engine = (memory_engine*)mem_engine; + + MALI_DEBUG_ASSERT_POINTER(engine); + MALI_DEBUG_ASSERT_POINTER(descriptor); + + MALI_DEBUG_PRINT(7, ("UnMapping length 0x%08X at offset 0x%08X\n", size, offset)); + + MALI_DEBUG_ASSERT_POINTER(engine->mali_address); + MALI_DEBUG_ASSERT_POINTER(engine->process_address); + + if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE ) + { + /* Mandetory for process_address manager to have an unmap function*/ + engine->process_address->unmap_physical( descriptor, offset, size, unmap_flags ); + } + + /* Optional for mali_address manager to have an unmap function*/ + if ( NULL != engine->mali_address->unmap_physical ) + { + engine->mali_address->unmap_physical( descriptor, offset, size, unmap_flags ); + } +} + + +_mali_osk_errcode_t mali_allocation_engine_allocate_page_tables(mali_allocation_engine engine, mali_page_table_block * descriptor, mali_physical_memory_allocator * physical_provider) +{ + mali_physical_memory_allocator * active_allocator = physical_provider; + + MALI_DEBUG_ASSERT_POINTER(descriptor); + MALI_DEBUG_ASSERT_POINTER(physical_provider); + + while ( NULL != active_allocator ) + { + switch (active_allocator->allocate_page_table_block(active_allocator->ctx, descriptor)) + { + case MALI_MEM_ALLOC_FINISHED: + MALI_SUCCESS; /* all done */ + case MALI_MEM_ALLOC_NONE: + /* try next */ + MALI_DEBUG_PRINT( 2, ("Memory Engine Allocate PageTables: No allocation on %s, resorting to %s\n", + ( active_allocator->name ) ? active_allocator->name : "UNNAMED", + ( active_allocator->next ) ? (( active_allocator->next->name )? active_allocator->next->name : "UNNAMED") : "NONE") ); + active_allocator = active_allocator->next; + break; + case MALI_MEM_ALLOC_PARTIAL: + MALI_DEBUG_PRINT(1, ("Invalid return value from allocate_page_table_block call: MALI_MEM_ALLOC_PARTIAL\n")); + /* FALL THROUGH */ + case MALI_MEM_ALLOC_INTERNAL_FAILURE: + MALI_DEBUG_PRINT(1, ("Aborting due to allocation failure\n")); + active_allocator = NULL; /* end the while loop */ + break; + } + } + + MALI_ERROR(_MALI_OSK_ERR_FAULT); +} + + +void mali_allocation_engine_report_allocators( mali_physical_memory_allocator * physical_provider ) +{ + mali_physical_memory_allocator * active_allocator = physical_provider; + MALI_DEBUG_ASSERT_POINTER(physical_provider); + + MALI_DEBUG_PRINT( 1, ("Mali memory allocators will be used in this order of preference (lowest numbered first) :\n")); + while ( NULL != active_allocator ) + { + if ( NULL != active_allocator->name ) + { + MALI_DEBUG_PRINT( 1, ("\t%d: %s\n", active_allocator->alloc_order, active_allocator->name) ); + } + else + { + MALI_DEBUG_PRINT( 1, ("\t%d: (UNNAMED ALLOCATOR)\n", active_allocator->alloc_order) ); + } + active_allocator = active_allocator->next; + } + +} + +u32 mali_allocation_engine_memory_usage(mali_physical_memory_allocator *allocator) +{ + u32 sum = 0; + while(NULL != allocator) + { + /* Only count allocators that have set up a stat function. */ + if(allocator->stat) + sum += allocator->stat(allocator); + + allocator = allocator->next; + } + + return sum; +} diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.h b/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.h new file mode 100644 index 0000000..3b41cee --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.h @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_KERNEL_MEMORY_ENGINE_H__ +#define __MALI_KERNEL_MEMORY_ENGINE_H__ + +typedef void * mali_allocation_engine; + +typedef enum { MALI_MEM_ALLOC_FINISHED, MALI_MEM_ALLOC_PARTIAL, MALI_MEM_ALLOC_NONE, MALI_MEM_ALLOC_INTERNAL_FAILURE } mali_physical_memory_allocation_result; + +typedef struct mali_physical_memory_allocation +{ + void (*release)(void * ctx, void * handle); /**< Function to call on to release the physical memory */ + void * ctx; + void * handle; + struct mali_physical_memory_allocation * next; +} mali_physical_memory_allocation; + +struct mali_page_table_block; + +typedef struct mali_page_table_block +{ + void (*release)(struct mali_page_table_block *page_table_block); + void * ctx; + void * handle; + u32 size; /**< In bytes, should be a multiple of MALI_MMU_PAGE_SIZE to avoid internal fragementation */ + u32 phys_base; /**< Mali physical address */ + mali_io_address mapping; +} mali_page_table_block; + + +/** @addtogroup _mali_osk_low_level_memory + * @{ */ + +typedef enum +{ + MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE = 0x1, + MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE = 0x2, +} mali_memory_allocation_flag; + +/** + * Supplying this 'magic' physical address requests that the OS allocate the + * physical address at page commit time, rather than committing a specific page + */ +#define MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC ((u32)(-1)) + +typedef struct mali_memory_allocation +{ + /* Information about the allocation */ + void * mapping; /**< CPU virtual address where the memory is mapped at */ + u32 mali_address; /**< The Mali seen address of the memory allocation */ + u32 size; /**< Size of the allocation */ + u32 permission; /**< Permission settings */ + mali_memory_allocation_flag flags; + u32 cache_settings; /* type: mali_memory_cache_settings, found in Ump DD breaks if we include it...*/ + + _mali_osk_lock_t * lock; + + /* Manager specific information pointers */ + void * mali_addr_mapping_info; /**< Mali address allocation specific info */ + void * process_addr_mapping_info; /**< Mapping manager specific info */ + + mali_physical_memory_allocation physical_allocation; + + _mali_osk_list_t list; /**< List for linking together memory allocations into the session's memory head */ +} mali_memory_allocation; +/** @} */ /* end group _mali_osk_low_level_memory */ + + +typedef struct mali_physical_memory_allocator +{ + mali_physical_memory_allocation_result (*allocate)(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info); + mali_physical_memory_allocation_result (*allocate_page_table_block)(void * ctx, mali_page_table_block * block); /* MALI_MEM_ALLOC_PARTIAL not allowed */ + void (*destroy)(struct mali_physical_memory_allocator * allocator); + u32 (*stat)(struct mali_physical_memory_allocator * allocator); + void * ctx; + const char * name; /**< Descriptive name for use in mali_allocation_engine_report_allocators, or NULL */ + u32 alloc_order; /**< Order in which the allocations should happen */ + struct mali_physical_memory_allocator * next; +} mali_physical_memory_allocator; + +typedef struct mali_kernel_mem_address_manager +{ + _mali_osk_errcode_t (*allocate)(mali_memory_allocation *); /**< Function to call to reserve an address */ + void (*release)(mali_memory_allocation *); /**< Function to call to free the address allocated */ + + /** + * Function called for each physical sub allocation. + * Called for each physical block allocated by the physical memory manager. + * @param[in] descriptor The memory descriptor in question + * @param[in] off Offset from the start of range + * @param[in,out] phys_addr A pointer to the physical address of the start of the + * physical block. When *phys_addr == MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC + * is used, this requests the function to allocate the physical page + * itself, and return it through the pointer provided. + * @param[in] size Length in bytes of the physical block + * @return _MALI_OSK_ERR_OK on success. + * A value of type _mali_osk_errcode_t other than _MALI_OSK_ERR_OK indicates failure. + * Specifically, _MALI_OSK_ERR_UNSUPPORTED indicates that the function + * does not support allocating physical pages itself. + */ + _mali_osk_errcode_t (*map_physical)(mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size); + + /** + * Function called to remove a physical sub allocation. + * Called on error paths where one of the address managers fails. + * + * @note this is optional. For address managers where this is not + * implemented, the value of this member is NULL. The memory engine + * currently does not require the mali address manager to be able to + * unmap individual pages, but the process address manager must have this + * capability. + * + * @param[in] descriptor The memory descriptor in question + * @param[in] off Offset from the start of range + * @param[in] size Length in bytes of the physical block + * @param[in] flags flags to use on a per-page basis. For OS-allocated + * physical pages, this must include _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR. + * @return _MALI_OSK_ERR_OK on success. + * A value of type _mali_osk_errcode_t other than _MALI_OSK_ERR_OK indicates failure. + */ + void (*unmap_physical)(mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t flags); + +} mali_kernel_mem_address_manager; + +mali_allocation_engine mali_allocation_engine_create(mali_kernel_mem_address_manager * mali_address_manager, mali_kernel_mem_address_manager * process_address_manager); + +void mali_allocation_engine_destroy(mali_allocation_engine engine); + +int mali_allocation_engine_allocate_memory(mali_allocation_engine engine, mali_memory_allocation * descriptor, mali_physical_memory_allocator * physical_provider, _mali_osk_list_t *tracking_list ); +void mali_allocation_engine_release_memory(mali_allocation_engine engine, mali_memory_allocation * descriptor); + +void mali_allocation_engine_release_pt1_mali_pagetables_unmap(mali_allocation_engine engine, mali_memory_allocation * descriptor); +void mali_allocation_engine_release_pt2_physical_memory_free(mali_allocation_engine engine, mali_memory_allocation * descriptor); + +int mali_allocation_engine_map_physical(mali_allocation_engine engine, mali_memory_allocation * descriptor, u32 offset, u32 phys, u32 cpu_usage_adjust, u32 size); +void mali_allocation_engine_unmap_physical(mali_allocation_engine engine, mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t unmap_flags); + +int mali_allocation_engine_allocate_page_tables(mali_allocation_engine, mali_page_table_block * descriptor, mali_physical_memory_allocator * physical_provider); + +void mali_allocation_engine_report_allocators(mali_physical_memory_allocator * physical_provider); + +u32 mali_allocation_engine_memory_usage(mali_physical_memory_allocator *allocator); + +#endif /* __MALI_KERNEL_MEMORY_ENGINE_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_utilization.c b/drivers/media/video/samsung/mali/common/mali_kernel_utilization.c new file mode 100644 index 0000000..a374dbf --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_kernel_utilization.c @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_kernel_utilization.h" +#include "mali_osk.h" +#include "mali_platform.h" + +/* Define how often to calculate and report GPU utilization, in milliseconds */ +#define MALI_GPU_UTILIZATION_TIMEOUT 1000 + +static _mali_osk_lock_t *time_data_lock; + +static _mali_osk_atomic_t num_running_cores; + +static u64 period_start_time = 0; +static u64 work_start_time = 0; +static u64 accumulated_work_time = 0; + +static _mali_osk_timer_t *utilization_timer = NULL; +static mali_bool timer_running = MALI_FALSE; + + +static void calculate_gpu_utilization(void* arg) +{ + u64 time_now; + u64 time_period; + u32 leading_zeroes; + u32 shift_val; + u32 work_normalized; + u32 period_normalized; + u32 utilization; + + _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW); + + if (accumulated_work_time == 0 && work_start_time == 0) + { + /* Don't reschedule timer, this will be started if new work arrives */ + timer_running = MALI_FALSE; + + _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW); + + /* No work done for this period, report zero usage */ + mali_gpu_utilization_handler(0); + + return; + } + + time_now = _mali_osk_time_get_ns(); + time_period = time_now - period_start_time; + + /* If we are currently busy, update working period up to now */ + if (work_start_time != 0) + { + accumulated_work_time += (time_now - work_start_time); + work_start_time = time_now; + } + + /* + * We have two 64-bit values, a dividend and a divisor. + * To avoid dependencies to a 64-bit divider, we shift down the two values + * equally first. + * We shift the dividend up and possibly the divisor down, making the result X in 256. + */ + + /* Shift the 64-bit values down so they fit inside a 32-bit integer */ + leading_zeroes = _mali_osk_clz((u32)(time_period >> 32)); + shift_val = 32 - leading_zeroes; + work_normalized = (u32)(accumulated_work_time >> shift_val); + period_normalized = (u32)(time_period >> shift_val); + + /* + * Now, we should report the usage in parts of 256 + * this means we must shift up the dividend or down the divisor by 8 + * (we could do a combination, but we just use one for simplicity, + * but the end result should be good enough anyway) + */ + if (period_normalized > 0x00FFFFFF) + { + /* The divisor is so big that it is safe to shift it down */ + period_normalized >>= 8; + } + else + { + /* + * The divisor is so small that we can shift up the dividend, without loosing any data. + * (dividend is always smaller than the divisor) + */ + work_normalized <<= 8; + } + + utilization = work_normalized / period_normalized; + + accumulated_work_time = 0; + period_start_time = time_now; /* starting a new period */ + + _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW); + + _mali_osk_timer_add(utilization_timer, _mali_osk_time_mstoticks(MALI_GPU_UTILIZATION_TIMEOUT)); + + + mali_gpu_utilization_handler(utilization); +} + +_mali_osk_errcode_t mali_utilization_init(void) +{ + time_data_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ | + _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_UTILIZATION); + + if (NULL == time_data_lock) + { + return _MALI_OSK_ERR_FAULT; + } + + _mali_osk_atomic_init(&num_running_cores, 0); + + utilization_timer = _mali_osk_timer_init(); + if (NULL == utilization_timer) + { + _mali_osk_lock_term(time_data_lock); + return _MALI_OSK_ERR_FAULT; + } + _mali_osk_timer_setcallback(utilization_timer, calculate_gpu_utilization, NULL); + + return _MALI_OSK_ERR_OK; +} + +void mali_utilization_suspend(void) +{ + if (NULL != utilization_timer) + { + _mali_osk_timer_del(utilization_timer); + timer_running = MALI_FALSE; + } +} + +void mali_utilization_term(void) +{ + if (NULL != utilization_timer) + { + _mali_osk_timer_del(utilization_timer); + timer_running = MALI_FALSE; + _mali_osk_timer_term(utilization_timer); + utilization_timer = NULL; + } + + _mali_osk_atomic_term(&num_running_cores); + + _mali_osk_lock_term(time_data_lock); +} + +void mali_utilization_core_start(u64 time_now) +{ + if (_mali_osk_atomic_inc_return(&num_running_cores) == 1) + { + /* + * We went from zero cores working, to one core working, + * we now consider the entire GPU for being busy + */ + + _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW); + + if (time_now < period_start_time) + { + /* + * This might happen if the calculate_gpu_utilization() was able + * to run between the sampling of time_now and us grabbing the lock above + */ + time_now = period_start_time; + } + + work_start_time = time_now; + if (timer_running != MALI_TRUE) + { + timer_running = MALI_TRUE; + period_start_time = work_start_time; /* starting a new period */ + + _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW); + + _mali_osk_timer_add(utilization_timer, _mali_osk_time_mstoticks(MALI_GPU_UTILIZATION_TIMEOUT)); + } + else + { + _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW); + } + } +} + +void mali_utilization_core_end(u64 time_now) +{ + if (_mali_osk_atomic_dec_return(&num_running_cores) == 0) + { + /* + * No more cores are working, so accumulate the time we was busy. + */ + _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW); + + if (time_now < work_start_time) + { + /* + * This might happen if the calculate_gpu_utilization() was able + * to run between the sampling of time_now and us grabbing the lock above + */ + time_now = work_start_time; + } + + accumulated_work_time += (time_now - work_start_time); + work_start_time = 0; + + _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW); + } +} diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_utilization.h b/drivers/media/video/samsung/mali/common/mali_kernel_utilization.h new file mode 100644 index 0000000..1f60517 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_kernel_utilization.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_KERNEL_UTILIZATION_H__ +#define __MALI_KERNEL_UTILIZATION_H__ + +#include "mali_osk.h" + +/** + * Initialize/start the Mali GPU utilization metrics reporting. + * + * @return _MALI_OSK_ERR_OK on success, otherwise failure. + */ +_mali_osk_errcode_t mali_utilization_init(void); + +/** + * Terminate the Mali GPU utilization metrics reporting + */ +void mali_utilization_term(void); + +/** + * Should be called when a job is about to execute a job + */ +void mali_utilization_core_start(u64 time_now); + +/** + * Should be called to stop the utilization timer during system suspend + */ +void mali_utilization_suspend(void); + +/** + * Should be called when a job has completed executing a job + */ +void mali_utilization_core_end(u64 time_now); + + +#endif /* __MALI_KERNEL_UTILIZATION_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_vsync.c b/drivers/media/video/samsung/mali/common/mali_kernel_vsync.c new file mode 100644 index 0000000..63c9f5b --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_kernel_vsync.c @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_kernel_common.h" +#include "mali_osk.h" +#include "mali_ukk.h" + +#if MALI_TIMELINE_PROFILING_ENABLED +#include "mali_osk_profiling.h" +#endif + +_mali_osk_errcode_t _mali_ukk_vsync_event_report(_mali_uk_vsync_event_report_s *args) +{ + _mali_uk_vsync_event event = (_mali_uk_vsync_event)args->event; + MALI_IGNORE(event); /* event is not used for release code, and that is OK */ + +#if MALI_TIMELINE_PROFILING_ENABLED + /* + * Manually generate user space events in kernel space. + * This saves user space from calling kernel space twice in this case. + * We just need to remember to add pid and tid manually. + */ + if ( event==_MALI_UK_VSYNC_EVENT_BEGIN_WAIT) + { + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SUSPEND | + MALI_PROFILING_EVENT_CHANNEL_SOFTWARE | + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VSYNC, + _mali_osk_get_pid(), _mali_osk_get_tid(), 0, 0, 0); + } + + if (event==_MALI_UK_VSYNC_EVENT_END_WAIT) + { + + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_RESUME | + MALI_PROFILING_EVENT_CHANNEL_SOFTWARE | + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VSYNC, + _mali_osk_get_pid(), _mali_osk_get_tid(), 0, 0, 0); + } +#endif + + MALI_DEBUG_PRINT(4, ("Received VSYNC event: %d\n", event)); + MALI_SUCCESS; +} + diff --git a/drivers/media/video/samsung/mali/common/mali_l2_cache.c b/drivers/media/video/samsung/mali/common/mali_l2_cache.c new file mode 100644 index 0000000..b7267f1 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_l2_cache.c @@ -0,0 +1,414 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "mali_kernel_common.h" +#include "mali_osk.h" + +#include "mali_l2_cache.h" +#include "mali_hw_core.h" +#include "mali_pm.h" + +/** + * Size of the Mali L2 cache registers in bytes + */ +#define MALI400_L2_CACHE_REGISTERS_SIZE 0x30 + +#define MALI_MAX_NUMBER_OF_L2_CACHE_CORES 3 + +/** + * Mali L2 cache register numbers + * Used in the register read/write routines. + * See the hardware documentation for more information about each register + */ +typedef enum mali_l2_cache_register { + MALI400_L2_CACHE_REGISTER_STATUS = 0x0008, + /*unused = 0x000C */ + MALI400_L2_CACHE_REGISTER_COMMAND = 0x0010, /**< Misc cache commands, e.g. clear */ + MALI400_L2_CACHE_REGISTER_CLEAR_PAGE = 0x0014, + MALI400_L2_CACHE_REGISTER_MAX_READS = 0x0018, /**< Limit of outstanding read requests */ + MALI400_L2_CACHE_REGISTER_ENABLE = 0x001C, /**< Enable misc cache features */ + MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0 = 0x0020, + MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0 = 0x0024, + MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1 = 0x0028, + MALI400_L2_CACHE_REGISTER_PERFCNT_VAL1 = 0x002C, +} mali_l2_cache_register; + +/** + * Mali L2 cache commands + * These are the commands that can be sent to the Mali L2 cache unit + */ +typedef enum mali_l2_cache_command +{ + MALI400_L2_CACHE_COMMAND_CLEAR_ALL = 0x01, /**< Clear the entire cache */ + /* Read HW TRM carefully before adding/using other commands than the clear above */ +} mali_l2_cache_command; + +/** + * Mali L2 cache commands + * These are the commands that can be sent to the Mali L2 cache unit + */ +typedef enum mali_l2_cache_enable +{ + MALI400_L2_CACHE_ENABLE_DEFAULT = 0x0, /**< Default state of enable register */ + MALI400_L2_CACHE_ENABLE_ACCESS = 0x01, /**< Permit cacheable accesses */ + MALI400_L2_CACHE_ENABLE_READ_ALLOCATE = 0x02, /**< Permit cache read allocate */ +} mali_l2_cache_enable; + +/** + * Mali L2 cache status bits + */ +typedef enum mali_l2_cache_status +{ + MALI400_L2_CACHE_STATUS_COMMAND_BUSY = 0x01, /**< Command handler of L2 cache is busy */ + MALI400_L2_CACHE_STATUS_DATA_BUSY = 0x02, /**< L2 cache is busy handling data requests */ +} mali_l2_cache_status; + +/** + * Definition of the L2 cache core struct + * Used to track a L2 cache unit in the system. + * Contains information about the mapping of the registers + */ +struct mali_l2_cache_core +{ + struct mali_hw_core hw_core; /**< Common for all HW cores */ + u32 core_id; /**< Unique core ID */ + _mali_osk_lock_t *command_lock; /**< Serialize all L2 cache commands */ + _mali_osk_lock_t *counter_lock; /**< Synchronize L2 cache counter access */ + u32 counter_src0; /**< Performance counter 0, MALI_HW_CORE_NO_COUNTER for disabled */ + u32 counter_src1; /**< Performance counter 1, MALI_HW_CORE_NO_COUNTER for disabled */ +}; + +#define MALI400_L2_MAX_READS_DEFAULT 0x1C + +static struct mali_l2_cache_core *mali_global_l2_cache_cores[MALI_MAX_NUMBER_OF_L2_CACHE_CORES]; +static u32 mali_global_num_l2_cache_cores = 0; + +int mali_l2_max_reads = MALI400_L2_MAX_READS_DEFAULT; + +/* Local helper functions */ +static _mali_osk_errcode_t mali_l2_cache_send_command(struct mali_l2_cache_core *cache, u32 reg, u32 val); + + +struct mali_l2_cache_core *mali_l2_cache_create(_mali_osk_resource_t *resource) +{ + struct mali_l2_cache_core *cache = NULL; + + MALI_DEBUG_PRINT(2, ("Mali L2 cache: Creating Mali L2 cache: %s\n", resource->description)); + + if (mali_global_num_l2_cache_cores >= MALI_MAX_NUMBER_OF_L2_CACHE_CORES) + { + MALI_PRINT_ERROR(("Mali L2 cache: Too many L2 cache core objects created\n")); + return NULL; + } + + cache = _mali_osk_malloc(sizeof(struct mali_l2_cache_core)); + if (NULL != cache) + { + cache->core_id = mali_global_num_l2_cache_cores; + cache->counter_src0 = MALI_HW_CORE_NO_COUNTER; + cache->counter_src1 = MALI_HW_CORE_NO_COUNTER; + if (_MALI_OSK_ERR_OK == mali_hw_core_create(&cache->hw_core, resource, MALI400_L2_CACHE_REGISTERS_SIZE)) + { + cache->command_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, + 0, _MALI_OSK_LOCK_ORDER_L2_COMMAND); + if (NULL != cache->command_lock) + { + cache->counter_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, + 0, _MALI_OSK_LOCK_ORDER_L2_COUNTER); + if (NULL != cache->counter_lock) + { + if (_MALI_OSK_ERR_OK == mali_l2_cache_reset(cache)) + { + mali_global_l2_cache_cores[mali_global_num_l2_cache_cores] = cache; + mali_global_num_l2_cache_cores++; + + return cache; + } + else + { + MALI_PRINT_ERROR(("Mali L2 cache: Failed to reset L2 cache core %s\n", cache->hw_core.description)); + } + + _mali_osk_lock_term(cache->counter_lock); + } + else + { + MALI_PRINT_ERROR(("Mali L2 cache: Failed to create counter lock for L2 cache core %s\n", cache->hw_core.description)); + } + + _mali_osk_lock_term(cache->command_lock); + } + else + { + MALI_PRINT_ERROR(("Mali L2 cache: Failed to create command lock for L2 cache core %s\n", cache->hw_core.description)); + } + + mali_hw_core_delete(&cache->hw_core); + } + + _mali_osk_free(cache); + } + else + { + MALI_PRINT_ERROR(("Mali L2 cache: Failed to allocate memory for L2 cache core\n")); + } + + return NULL; +} + +void mali_l2_cache_delete(struct mali_l2_cache_core *cache) +{ + u32 i; + + /* reset to defaults */ + mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_MAX_READS, (u32)MALI400_L2_MAX_READS_DEFAULT); + mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_ENABLE, (u32)MALI400_L2_CACHE_ENABLE_DEFAULT); + + _mali_osk_lock_term(cache->counter_lock); + _mali_osk_lock_term(cache->command_lock); + mali_hw_core_delete(&cache->hw_core); + + for (i = 0; i < mali_global_num_l2_cache_cores; i++) + { + if (mali_global_l2_cache_cores[i] == cache) + { + mali_global_l2_cache_cores[i] = NULL; + mali_global_num_l2_cache_cores--; + } + } + + _mali_osk_free(cache); +} + +u32 mali_l2_cache_get_id(struct mali_l2_cache_core *cache) +{ + return cache->core_id; +} + +mali_bool mali_l2_cache_core_set_counter_src0(struct mali_l2_cache_core *cache, u32 counter) +{ + u32 value = 0; /* disabled src */ + mali_bool core_is_on; + + MALI_DEBUG_ASSERT_POINTER(cache); + + core_is_on = mali_l2_cache_lock_power_state(cache); + + _mali_osk_lock_wait(cache->counter_lock, _MALI_OSK_LOCKMODE_RW); + + cache->counter_src0 = counter; + + if (MALI_HW_CORE_NO_COUNTER != counter) + { + value = counter; + } + + if (MALI_TRUE == core_is_on) + { + mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0, value); + } + + _mali_osk_lock_signal(cache->counter_lock, _MALI_OSK_LOCKMODE_RW); + + mali_l2_cache_unlock_power_state(cache); + + return MALI_TRUE; +} + +mali_bool mali_l2_cache_core_set_counter_src1(struct mali_l2_cache_core *cache, u32 counter) +{ + u32 value = 0; /* disabled src */ + mali_bool core_is_on; + + MALI_DEBUG_ASSERT_POINTER(cache); + + core_is_on = mali_l2_cache_lock_power_state(cache); + + _mali_osk_lock_wait(cache->counter_lock, _MALI_OSK_LOCKMODE_RW); + + cache->counter_src1 = counter; + + if (MALI_HW_CORE_NO_COUNTER != counter) + { + value = counter; + } + + if (MALI_TRUE == core_is_on) + { + mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1, value); + } + + _mali_osk_lock_signal(cache->counter_lock, _MALI_OSK_LOCKMODE_RW); + + mali_l2_cache_unlock_power_state(cache); + + return MALI_TRUE; +} + +u32 mali_l2_cache_core_get_counter_src0(struct mali_l2_cache_core *cache) +{ + return cache->counter_src0; +} + +u32 mali_l2_cache_core_get_counter_src1(struct mali_l2_cache_core *cache) +{ + return cache->counter_src1; +} + +void mali_l2_cache_core_get_counter_values(struct mali_l2_cache_core *cache, u32 *src0, u32 *value0, u32 *src1, u32 *value1) +{ + MALI_DEBUG_ASSERT(NULL != src0); + MALI_DEBUG_ASSERT(NULL != value0); + MALI_DEBUG_ASSERT(NULL != src1); + MALI_DEBUG_ASSERT(NULL != value1); + + /* Caller must hold the PM lock and know that we are powered on */ + + _mali_osk_lock_wait(cache->counter_lock, _MALI_OSK_LOCKMODE_RW); + + *src0 = cache->counter_src0; + *src1 = cache->counter_src1; + + if (cache->counter_src0 != MALI_HW_CORE_NO_COUNTER) + { + *value0 = mali_hw_core_register_read(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0); + } + + if (cache->counter_src0 != MALI_HW_CORE_NO_COUNTER) + { + *value1 = mali_hw_core_register_read(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_VAL1); + } + + _mali_osk_lock_signal(cache->counter_lock, _MALI_OSK_LOCKMODE_RW); +} + +struct mali_l2_cache_core *mali_l2_cache_core_get_glob_l2_core(u32 index) +{ + if (MALI_MAX_NUMBER_OF_L2_CACHE_CORES > index) + { + return mali_global_l2_cache_cores[index]; + } + + return NULL; +} + +u32 mali_l2_cache_core_get_glob_num_l2_cores(void) +{ + return mali_global_num_l2_cache_cores; +} + +u32 mali_l2_cache_core_get_max_num_l2_cores(void) +{ + return MALI_MAX_NUMBER_OF_L2_CACHE_CORES; +} + +_mali_osk_errcode_t mali_l2_cache_reset(struct mali_l2_cache_core *cache) +{ + /* Invalidate cache (just to keep it in a known state at startup) */ + mali_l2_cache_invalidate_all(cache); + + /* Enable cache */ + mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_ENABLE, (u32)MALI400_L2_CACHE_ENABLE_ACCESS | (u32)MALI400_L2_CACHE_ENABLE_READ_ALLOCATE); + mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_MAX_READS, (u32)mali_l2_max_reads); + + /* Restart any performance counters (if enabled) */ + _mali_osk_lock_wait(cache->counter_lock, _MALI_OSK_LOCKMODE_RW); + + if (cache->counter_src0 != MALI_HW_CORE_NO_COUNTER) + { + mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0, cache->counter_src0); + } + + if (cache->counter_src1 != MALI_HW_CORE_NO_COUNTER) + { + mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1, cache->counter_src1); + } + + _mali_osk_lock_signal(cache->counter_lock, _MALI_OSK_LOCKMODE_RW); + + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t mali_l2_cache_invalidate_all(struct mali_l2_cache_core *cache) +{ + return mali_l2_cache_send_command(cache, MALI400_L2_CACHE_REGISTER_COMMAND, MALI400_L2_CACHE_COMMAND_CLEAR_ALL); +} + +_mali_osk_errcode_t mali_l2_cache_invalidate_pages(struct mali_l2_cache_core *cache, u32 *pages, u32 num_pages) +{ + u32 i; + _mali_osk_errcode_t ret1, ret = _MALI_OSK_ERR_OK; + + for (i = 0; i < num_pages; i++) + { + ret1 = mali_l2_cache_send_command(cache, MALI400_L2_CACHE_REGISTER_CLEAR_PAGE, pages[i]); + if (_MALI_OSK_ERR_OK != ret1) + { + ret = ret1; + } + } + + return ret; +} + +mali_bool mali_l2_cache_lock_power_state(struct mali_l2_cache_core *cache) +{ + /* + * Take PM lock and check power state. + * Returns MALI_TRUE if module is powered on. + * Power state will not change until mali_l2_cache_unlock_power_state() is called. + */ + mali_pm_lock(); + return mali_pm_is_powered_on(); +} + +void mali_l2_cache_unlock_power_state(struct mali_l2_cache_core *cache) +{ + /* Release PM lock */ + mali_pm_unlock(); +} + +/* -------- local helper functions below -------- */ + + +static _mali_osk_errcode_t mali_l2_cache_send_command(struct mali_l2_cache_core *cache, u32 reg, u32 val) +{ + int i = 0; + const int loop_count = 100000; + + /* + * Grab lock in order to send commands to the L2 cache in a serialized fashion. + * The L2 cache will ignore commands if it is busy. + */ + _mali_osk_lock_wait(cache->command_lock, _MALI_OSK_LOCKMODE_RW); + + /* First, wait for L2 cache command handler to go idle */ + + for (i = 0; i < loop_count; i++) + { + if (!(mali_hw_core_register_read(&cache->hw_core, MALI400_L2_CACHE_REGISTER_STATUS) & (u32)MALI400_L2_CACHE_STATUS_COMMAND_BUSY)) + { + break; + } + } + + if (i == loop_count) + { + _mali_osk_lock_signal(cache->command_lock, _MALI_OSK_LOCKMODE_RW); + MALI_DEBUG_PRINT(1, ( "Mali L2 cache: aborting wait for command interface to go idle\n")); + MALI_ERROR( _MALI_OSK_ERR_FAULT ); + } + + /* then issue the command */ + mali_hw_core_register_write(&cache->hw_core, reg, val); + + _mali_osk_lock_signal(cache->command_lock, _MALI_OSK_LOCKMODE_RW); + + MALI_SUCCESS; +} diff --git a/drivers/media/video/samsung/mali/common/mali_l2_cache.h b/drivers/media/video/samsung/mali/common/mali_l2_cache.h new file mode 100644 index 0000000..5a8e4da --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_l2_cache.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_KERNEL_L2_CACHE_H__ +#define __MALI_KERNEL_L2_CACHE_H__ + +#include "mali_osk.h" + +struct mali_l2_cache_core; + +_mali_osk_errcode_t mali_l2_cache_initialize(void); +void mali_l2_cache_terminate(void); + +struct mali_l2_cache_core *mali_l2_cache_create(_mali_osk_resource_t * resource); +void mali_l2_cache_delete(struct mali_l2_cache_core *cache); + +u32 mali_l2_cache_get_id(struct mali_l2_cache_core *cache); + +mali_bool mali_l2_cache_core_set_counter_src0(struct mali_l2_cache_core *cache, u32 counter); +mali_bool mali_l2_cache_core_set_counter_src1(struct mali_l2_cache_core *cache, u32 counter); +u32 mali_l2_cache_core_get_counter_src0(struct mali_l2_cache_core *cache); +u32 mali_l2_cache_core_get_counter_src1(struct mali_l2_cache_core *cache); +void mali_l2_cache_core_get_counter_values(struct mali_l2_cache_core *cache, u32 *src0, u32 *value0, u32 *src1, u32 *value1); +struct mali_l2_cache_core *mali_l2_cache_core_get_glob_l2_core(u32 index); +u32 mali_l2_cache_core_get_glob_num_l2_cores(void); +u32 mali_l2_cache_core_get_max_num_l2_cores(void); + +_mali_osk_errcode_t mali_l2_cache_reset(struct mali_l2_cache_core *cache); + +_mali_osk_errcode_t mali_l2_cache_invalidate_all(struct mali_l2_cache_core *cache); +_mali_osk_errcode_t mali_l2_cache_invalidate_pages(struct mali_l2_cache_core *cache, u32 *pages, u32 num_pages); + +mali_bool mali_l2_cache_lock_power_state(struct mali_l2_cache_core *cache); +void mali_l2_cache_unlock_power_state(struct mali_l2_cache_core *cache); + +#endif /* __MALI_KERNEL_L2_CACHE_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_mem_validation.c b/drivers/media/video/samsung/mali/common/mali_mem_validation.c new file mode 100644 index 0000000..ea9c428 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_mem_validation.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_mem_validation.h" +#include "mali_osk.h" +#include "mali_kernel_common.h" + +#define MALI_INVALID_MEM_ADDR 0xFFFFFFFF + +typedef struct +{ + u32 phys_base; /**< Mali physical base of the memory, page aligned */ + u32 size; /**< size in bytes of the memory, multiple of page size */ +} _mali_mem_validation_t; + +static _mali_mem_validation_t mali_mem_validator = { MALI_INVALID_MEM_ADDR, MALI_INVALID_MEM_ADDR }; + +_mali_osk_errcode_t mali_mem_validation_add_range(const _mali_osk_resource_t *resource) +{ + /* Check that no other MEM_VALIDATION resources exist */ + if (MALI_INVALID_MEM_ADDR != mali_mem_validator.phys_base) + { + MALI_PRINT_ERROR(("Failed to add MEM_VALIDATION resource %s; another range is already specified\n", resource->description)); + return _MALI_OSK_ERR_FAULT; + } + + /* Check restrictions on page alignment */ + if ((0 != (resource->base & (~_MALI_OSK_CPU_PAGE_MASK))) || + (0 != (resource->size & (~_MALI_OSK_CPU_PAGE_MASK)))) + { + MALI_PRINT_ERROR(("Failed to add MEM_VALIDATION resource %s; incorrect alignment\n", resource->description)); + return _MALI_OSK_ERR_FAULT; + } + + mali_mem_validator.phys_base = resource->base; + mali_mem_validator.size = resource->size; + MALI_DEBUG_PRINT(2, ("Memory Validator '%s' installed for Mali physical address base=0x%08X, size=0x%08X\n", + resource->description, mali_mem_validator.phys_base, mali_mem_validator.size)); + + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t mali_mem_validation_check(u32 phys_addr, u32 size) +{ + if (phys_addr < (phys_addr + size)) /* Don't allow overflow (or zero size) */ + { + if ((0 == ( phys_addr & (~_MALI_OSK_CPU_PAGE_MASK))) && + (0 == ( size & (~_MALI_OSK_CPU_PAGE_MASK)))) + { + if ((phys_addr >= mali_mem_validator.phys_base) && + ((phys_addr + (size - 1)) >= mali_mem_validator.phys_base) && + (phys_addr <= (mali_mem_validator.phys_base + (mali_mem_validator.size - 1))) && + ((phys_addr + (size - 1)) <= (mali_mem_validator.phys_base + (mali_mem_validator.size - 1))) ) + { + MALI_DEBUG_PRINT(3, ("Accepted range 0x%08X + size 0x%08X (= 0x%08X)\n", phys_addr, size, (phys_addr + size - 1))); + return _MALI_OSK_ERR_OK; + } + } + } + + MALI_PRINT_ERROR(("MALI PHYSICAL RANGE VALIDATION ERROR: The range supplied was: phys_base=0x%08X, size=0x%08X\n", phys_addr, size)); + + return _MALI_OSK_ERR_FAULT; +} diff --git a/drivers/media/video/samsung/mali/common/mali_mem_validation.h b/drivers/media/video/samsung/mali/common/mali_mem_validation.h new file mode 100644 index 0000000..2043b44 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_mem_validation.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_MEM_VALIDATION_H__ +#define __MALI_MEM_VALIDATION_H__ + +#include "mali_osk.h" + +_mali_osk_errcode_t mali_mem_validation_add_range(const _mali_osk_resource_t * resource); +_mali_osk_errcode_t mali_mem_validation_check(u32 phys_addr, u32 size); + +#endif /* __MALI_MEM_VALIDATION_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_memory.c b/drivers/media/video/samsung/mali/common/mali_memory.c new file mode 100644 index 0000000..75506ed --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_memory.c @@ -0,0 +1,1319 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_kernel_common.h" +#include "mali_kernel_descriptor_mapping.h" +#include "mali_mem_validation.h" +#include "mali_memory.h" +#include "mali_mmu_page_directory.h" +#include "mali_kernel_memory_engine.h" +#include "mali_block_allocator.h" +#include "mali_kernel_mem_os.h" +#include "mali_session.h" +#include "mali_l2_cache.h" +#include "mali_cluster.h" +#include "mali_group.h" +#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 +#include "ump_kernel_interface.h" +#endif + +/* kernel side OS functions and user-kernel interface */ +#include "mali_osk.h" +#include "mali_osk_mali.h" +#include "mali_ukk.h" +#include "mali_osk_list.h" +#include "mali_osk_bitops.h" + +/** + * Per-session memory descriptor mapping table sizes + */ +#define MALI_MEM_DESCRIPTORS_INIT 64 +#define MALI_MEM_DESCRIPTORS_MAX 65536 + +typedef struct dedicated_memory_info +{ + u32 base; + u32 size; + struct dedicated_memory_info * next; +} dedicated_memory_info; + +/* types used for external_memory and ump_memory physical memory allocators, which are using the mali_allocation_engine */ +#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 +typedef struct ump_mem_allocation +{ + mali_allocation_engine * engine; + mali_memory_allocation * descriptor; + u32 initial_offset; + u32 size_allocated; + ump_dd_handle ump_mem; +} ump_mem_allocation ; +#endif + +typedef struct external_mem_allocation +{ + mali_allocation_engine * engine; + mali_memory_allocation * descriptor; + u32 initial_offset; + u32 size; +} external_mem_allocation; + +/** + * @brief Internal function for unmapping memory + * + * Worker function for unmapping memory from a user-process. We assume that the + * session/descriptor's lock was obtained before entry. For example, the + * wrapper _mali_ukk_mem_munmap() will lock the descriptor, then call this + * function to do the actual unmapping. mali_memory_core_session_end() could + * also call this directly (depending on compilation options), having locked + * the descriptor. + * + * This function will fail if it is unable to put the MMU in stall mode (which + * might be the case if a page fault is also being processed). + * + * @param args see _mali_uk_mem_munmap_s in "mali_utgard_uk_types.h" + * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. + */ +static _mali_osk_errcode_t _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args ); + +#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 +static void ump_memory_release(void * ctx, void * handle); +static mali_physical_memory_allocation_result ump_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info); +#endif /* MALI_USE_UNIFIED_MEMORY_PROVIDER != 0*/ + + +static void external_memory_release(void * ctx, void * handle); +static mali_physical_memory_allocation_result external_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info); + + +/* nop functions */ + +/* mali address manager needs to allocate page tables on allocate, write to page table(s) on map, write to page table(s) and release page tables on release */ +static _mali_osk_errcode_t mali_address_manager_allocate(mali_memory_allocation * descriptor); /* validates the range, allocates memory for the page tables if needed */ +static _mali_osk_errcode_t mali_address_manager_map(mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size); +static void mali_address_manager_release(mali_memory_allocation * descriptor); + +/* MMU variables */ + +typedef struct mali_mmu_page_table_allocation +{ + _mali_osk_list_t list; + u32 * usage_map; + u32 usage_count; + u32 num_pages; + mali_page_table_block pages; +} mali_mmu_page_table_allocation; + +typedef struct mali_mmu_page_table_allocations +{ + _mali_osk_lock_t *lock; + _mali_osk_list_t partial; + _mali_osk_list_t full; + /* we never hold on to a empty allocation */ +} mali_mmu_page_table_allocations; + +static mali_kernel_mem_address_manager mali_address_manager = +{ + mali_address_manager_allocate, /* allocate */ + mali_address_manager_release, /* release */ + mali_address_manager_map, /* map_physical */ + NULL /* unmap_physical not present*/ +}; + +/* the mmu page table cache */ +static struct mali_mmu_page_table_allocations page_table_cache; + + +static mali_kernel_mem_address_manager process_address_manager = +{ + _mali_osk_mem_mapregion_init, /* allocate */ + _mali_osk_mem_mapregion_term, /* release */ + _mali_osk_mem_mapregion_map, /* map_physical */ + _mali_osk_mem_mapregion_unmap /* unmap_physical */ +}; + +static _mali_osk_errcode_t mali_mmu_page_table_cache_create(void); +static void mali_mmu_page_table_cache_destroy(void); + +static mali_allocation_engine memory_engine = NULL; +static mali_physical_memory_allocator * physical_memory_allocators = NULL; + +static dedicated_memory_info * mem_region_registrations = NULL; + +mali_allocation_engine mali_mem_get_memory_engine(void) +{ + return memory_engine; +} + +/* called during module init */ +_mali_osk_errcode_t mali_memory_initialize(void) +{ + _mali_osk_errcode_t err; + + MALI_DEBUG_PRINT(2, ("Memory system initializing\n")); + + err = mali_mmu_page_table_cache_create(); + if(_MALI_OSK_ERR_OK != err) + { + MALI_ERROR(err); + } + + memory_engine = mali_allocation_engine_create(&mali_address_manager, &process_address_manager); + MALI_CHECK_NON_NULL( memory_engine, _MALI_OSK_ERR_FAULT); + + MALI_SUCCESS; +} + +/* called if/when our module is unloaded */ +void mali_memory_terminate(void) +{ + MALI_DEBUG_PRINT(2, ("Memory system terminating\n")); + + mali_mmu_page_table_cache_destroy(); + + while ( NULL != mem_region_registrations) + { + dedicated_memory_info * m; + m = mem_region_registrations; + mem_region_registrations = m->next; + _mali_osk_mem_unreqregion(m->base, m->size); + _mali_osk_free(m); + } + + while ( NULL != physical_memory_allocators) + { + mali_physical_memory_allocator * m; + m = physical_memory_allocators; + physical_memory_allocators = m->next; + m->destroy(m); + } + + if (NULL != memory_engine) + { + mali_allocation_engine_destroy(memory_engine); + memory_engine = NULL; + } +} + +_mali_osk_errcode_t mali_memory_session_begin(struct mali_session_data * session_data) +{ + MALI_DEBUG_PRINT(5, ("Memory session begin\n")); + + /* create descriptor mapping table */ + session_data->descriptor_mapping = mali_descriptor_mapping_create(MALI_MEM_DESCRIPTORS_INIT, MALI_MEM_DESCRIPTORS_MAX); + + if (NULL == session_data->descriptor_mapping) + { + MALI_ERROR(_MALI_OSK_ERR_NOMEM); + } + + session_data->memory_lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_ONELOCK + | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_MEM_SESSION); + if (NULL == session_data->memory_lock) + { + mali_descriptor_mapping_destroy(session_data->descriptor_mapping); + _mali_osk_free(session_data); + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } + + /* Init the session's memory allocation list */ + _MALI_OSK_INIT_LIST_HEAD( &session_data->memory_head ); + + MALI_DEBUG_PRINT(5, ("MMU session begin: success\n")); + MALI_SUCCESS; +} + +static void descriptor_table_cleanup_callback(int descriptor_id, void* map_target) +{ + mali_memory_allocation * descriptor; + + descriptor = (mali_memory_allocation*)map_target; + + MALI_DEBUG_PRINT(3, ("Cleanup of descriptor %d mapping to 0x%x in descriptor table\n", descriptor_id, map_target)); + MALI_DEBUG_ASSERT(descriptor); + + mali_allocation_engine_release_memory(memory_engine, descriptor); + _mali_osk_free(descriptor); +} + +void mali_memory_session_end(struct mali_session_data *session_data) +{ + _mali_osk_errcode_t err = _MALI_OSK_ERR_BUSY; + + MALI_DEBUG_PRINT(3, ("MMU session end\n")); + + if (NULL == session_data) + { + MALI_DEBUG_PRINT(1, ("No session data found during session end\n")); + return; + } + + while (err == _MALI_OSK_ERR_BUSY) + { + /* Lock the session so we can modify the memory list */ + _mali_osk_lock_wait( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW ); + err = _MALI_OSK_ERR_OK; + + /* Free all memory engine allocations */ + if (0 == _mali_osk_list_empty(&session_data->memory_head)) + { + mali_memory_allocation *descriptor; + mali_memory_allocation *temp; + _mali_uk_mem_munmap_s unmap_args; + + MALI_DEBUG_PRINT(1, ("Memory found on session usage list during session termination\n")); + + unmap_args.ctx = session_data; + + /* use the 'safe' list iterator, since freeing removes the active block from the list we're iterating */ + _MALI_OSK_LIST_FOREACHENTRY(descriptor, temp, &session_data->memory_head, mali_memory_allocation, list) + { + MALI_DEBUG_PRINT(4, ("Freeing block with mali address 0x%x size %d mapped in user space at 0x%x\n", + descriptor->mali_address, descriptor->size, descriptor->size, descriptor->mapping) + ); + /* ASSERT that the descriptor's lock references the correct thing */ + MALI_DEBUG_ASSERT( descriptor->lock == session_data->memory_lock ); + /* Therefore, we have already locked the descriptor */ + + unmap_args.size = descriptor->size; + unmap_args.mapping = descriptor->mapping; + unmap_args.cookie = (u32)descriptor; + + /* + * This removes the descriptor from the list, and frees the descriptor + * + * Does not handle the _MALI_OSK_SPECIFIC_INDIRECT_MMAP case, since + * the only OS we are aware of that requires indirect MMAP also has + * implicit mmap cleanup. + */ + err = _mali_ukk_mem_munmap_internal( &unmap_args ); + + if (err == _MALI_OSK_ERR_BUSY) + { + _mali_osk_lock_signal( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW ); + /* + * Reason for this; + * We where unable to stall the MMU, probably because we are in page fault handling. + * Sleep for a while with the session lock released, then try again. + * Abnormal termination of programs with running Mali jobs is a normal reason for this. + */ + _mali_osk_time_ubusydelay(10); + break; /* Will jump back into: "while (err == _MALI_OSK_ERR_BUSY)" */ + } + } + } + } + /* Assert that we really did free everything */ + MALI_DEBUG_ASSERT( _mali_osk_list_empty(&session_data->memory_head) ); + + if (NULL != session_data->descriptor_mapping) + { + mali_descriptor_mapping_call_for_each(session_data->descriptor_mapping, descriptor_table_cleanup_callback); + mali_descriptor_mapping_destroy(session_data->descriptor_mapping); + session_data->descriptor_mapping = NULL; + } + + _mali_osk_lock_signal( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW ); + + /** + * @note Could the VMA close handler mean that we use the session data after it was freed? + * In which case, would need to refcount the session data, and free on VMA close + */ + + /* Free the lock */ + _mali_osk_lock_term( session_data->memory_lock ); + + return; +} + +_mali_osk_errcode_t mali_memory_core_resource_os_memory(_mali_osk_resource_t * resource) +{ + mali_physical_memory_allocator * allocator; + mali_physical_memory_allocator ** next_allocator_list; + + u32 alloc_order = resource->alloc_order; + + allocator = mali_os_allocator_create(resource->size, resource->cpu_usage_adjust, resource->description); + if (NULL == allocator) + { + MALI_DEBUG_PRINT(1, ("Failed to create OS memory allocator\n")); + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } + + allocator->alloc_order = alloc_order; + + /* link in the allocator: insertion into ordered list + * resources of the same alloc_order will be Last-in-first */ + next_allocator_list = &physical_memory_allocators; + + while (NULL != *next_allocator_list && + (*next_allocator_list)->alloc_order < alloc_order ) + { + next_allocator_list = &((*next_allocator_list)->next); + } + + allocator->next = (*next_allocator_list); + (*next_allocator_list) = allocator; + + MALI_SUCCESS; +} + +_mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(_mali_osk_resource_t * resource) +{ + mali_physical_memory_allocator * allocator; + mali_physical_memory_allocator ** next_allocator_list; + dedicated_memory_info * cleanup_data; + + u32 alloc_order = resource->alloc_order; + + /* do the low level linux operation first */ + + /* Request ownership of the memory */ + if (_MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(resource->base, resource->size, resource->description)) + { + MALI_DEBUG_PRINT(1, ("Failed to request memory region %s (0x%08X - 0x%08X)\n", resource->description, resource->base, resource->base + resource->size - 1)); + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } + + /* create generic block allocator object to handle it */ + allocator = mali_block_allocator_create(resource->base, resource->cpu_usage_adjust, resource->size, resource->description ); + + if (NULL == allocator) + { + MALI_DEBUG_PRINT(1, ("Memory bank registration failed\n")); + _mali_osk_mem_unreqregion(resource->base, resource->size); + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } + + /* save low level cleanup info */ + allocator->alloc_order = alloc_order; + + cleanup_data = _mali_osk_malloc(sizeof(dedicated_memory_info)); + + if (NULL == cleanup_data) + { + _mali_osk_mem_unreqregion(resource->base, resource->size); + allocator->destroy(allocator); + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } + + cleanup_data->base = resource->base; + cleanup_data->size = resource->size; + + cleanup_data->next = mem_region_registrations; + mem_region_registrations = cleanup_data; + + /* link in the allocator: insertion into ordered list + * resources of the same alloc_order will be Last-in-first */ + next_allocator_list = &physical_memory_allocators; + + while ( NULL != *next_allocator_list && + (*next_allocator_list)->alloc_order < alloc_order ) + { + next_allocator_list = &((*next_allocator_list)->next); + } + + allocator->next = (*next_allocator_list); + (*next_allocator_list) = allocator; + + MALI_SUCCESS; +} + +#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 +static mali_physical_memory_allocation_result ump_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info) +{ + ump_dd_handle ump_mem; + u32 nr_blocks; + u32 i; + ump_dd_physical_block * ump_blocks; + ump_mem_allocation *ret_allocation; + + MALI_DEBUG_ASSERT_POINTER(ctx); + MALI_DEBUG_ASSERT_POINTER(engine); + MALI_DEBUG_ASSERT_POINTER(descriptor); + MALI_DEBUG_ASSERT_POINTER(alloc_info); + + ret_allocation = _mali_osk_malloc( sizeof( ump_mem_allocation ) ); + if ( NULL==ret_allocation ) return MALI_MEM_ALLOC_INTERNAL_FAILURE; + + ump_mem = (ump_dd_handle)ctx; + + MALI_DEBUG_PRINT(4, ("In ump_memory_commit\n")); + + nr_blocks = ump_dd_phys_block_count_get(ump_mem); + + MALI_DEBUG_PRINT(4, ("Have %d blocks\n", nr_blocks)); + + if (nr_blocks == 0) + { + MALI_DEBUG_PRINT(1, ("No block count\n")); + _mali_osk_free( ret_allocation ); + return MALI_MEM_ALLOC_INTERNAL_FAILURE; + } + + ump_blocks = _mali_osk_malloc(sizeof(*ump_blocks)*nr_blocks ); + if ( NULL==ump_blocks ) + { + _mali_osk_free( ret_allocation ); + return MALI_MEM_ALLOC_INTERNAL_FAILURE; + } + + if (UMP_DD_INVALID == ump_dd_phys_blocks_get(ump_mem, ump_blocks, nr_blocks)) + { + _mali_osk_free(ump_blocks); + _mali_osk_free( ret_allocation ); + return MALI_MEM_ALLOC_INTERNAL_FAILURE; + } + + /* Store away the initial offset for unmapping purposes */ + ret_allocation->initial_offset = *offset; + + for(i=0; iinitial_offset; + MALI_DEBUG_PRINT(1, ("Mapping of external memory failed\n")); + + /* unmap all previous blocks (if any) */ + mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->initial_offset, size_allocated, (_mali_osk_mem_mapregion_flags_t)0 ); + + _mali_osk_free(ump_blocks); + _mali_osk_free(ret_allocation); + return MALI_MEM_ALLOC_INTERNAL_FAILURE; + } + *offset += ump_blocks[i].size; + } + + if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE) + { + /* Map in an extra virtual guard page at the end of the VMA */ + MALI_DEBUG_PRINT(4, ("Mapping in extra guard page\n")); + if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, ump_blocks[0].addr , 0, _MALI_OSK_MALI_PAGE_SIZE )) + { + u32 size_allocated = *offset - ret_allocation->initial_offset; + MALI_DEBUG_PRINT(1, ("Mapping of external memory (guard page) failed\n")); + + /* unmap all previous blocks (if any) */ + mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->initial_offset, size_allocated, (_mali_osk_mem_mapregion_flags_t)0 ); + + _mali_osk_free(ump_blocks); + _mali_osk_free(ret_allocation); + return MALI_MEM_ALLOC_INTERNAL_FAILURE; + } + *offset += _MALI_OSK_MALI_PAGE_SIZE; + } + + _mali_osk_free( ump_blocks ); + + ret_allocation->engine = engine; + ret_allocation->descriptor = descriptor; + ret_allocation->ump_mem = ump_mem; + ret_allocation->size_allocated = *offset - ret_allocation->initial_offset; + + alloc_info->ctx = NULL; + alloc_info->handle = ret_allocation; + alloc_info->next = NULL; + alloc_info->release = ump_memory_release; + + return MALI_MEM_ALLOC_FINISHED; +} + +static void ump_memory_release(void * ctx, void * handle) +{ + ump_dd_handle ump_mem; + ump_mem_allocation *allocation; + + allocation = (ump_mem_allocation *)handle; + + MALI_DEBUG_ASSERT_POINTER( allocation ); + + ump_mem = allocation->ump_mem; + + MALI_DEBUG_ASSERT(UMP_DD_HANDLE_INVALID!=ump_mem); + + /* At present, this is a no-op. But, it allows the mali_address_manager to + * do unmapping of a subrange in future. */ + mali_allocation_engine_unmap_physical( allocation->engine, + allocation->descriptor, + allocation->initial_offset, + allocation->size_allocated, + (_mali_osk_mem_mapregion_flags_t)0 + ); + _mali_osk_free( allocation ); + + + ump_dd_reference_release(ump_mem) ; + return; +} + +_mali_osk_errcode_t _mali_ukk_attach_ump_mem( _mali_uk_attach_ump_mem_s *args ) +{ + ump_dd_handle ump_mem; + mali_physical_memory_allocator external_memory_allocator; + struct mali_session_data *session_data; + mali_memory_allocation * descriptor; + int md; + + MALI_DEBUG_ASSERT_POINTER(args); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + + session_data = (struct mali_session_data *)args->ctx; + MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS); + + /* check arguments */ + /* NULL might be a valid Mali address */ + if ( ! args->size) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); + + /* size must be a multiple of the system page size */ + if ( args->size % _MALI_OSK_MALI_PAGE_SIZE ) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); + + MALI_DEBUG_PRINT(3, + ("Requested to map ump memory with secure id %d into virtual memory 0x%08X, size 0x%08X\n", + args->secure_id, args->mali_address, args->size)); + + ump_mem = ump_dd_handle_create_from_secure_id( (int)args->secure_id ) ; + + if ( UMP_DD_HANDLE_INVALID==ump_mem ) MALI_ERROR(_MALI_OSK_ERR_FAULT); + + descriptor = _mali_osk_calloc(1, sizeof(mali_memory_allocation)); + if (NULL == descriptor) + { + ump_dd_reference_release(ump_mem); + MALI_ERROR(_MALI_OSK_ERR_NOMEM); + } + + descriptor->size = args->size; + descriptor->mapping = NULL; + descriptor->mali_address = args->mali_address; + descriptor->mali_addr_mapping_info = (void*)session_data; + descriptor->process_addr_mapping_info = NULL; /* do not map to process address space */ + descriptor->cache_settings = (u32) MALI_CACHE_STANDARD; + descriptor->lock = session_data->memory_lock; + + if (args->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) + { + descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE; + } + _mali_osk_list_init( &descriptor->list ); + + if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session_data->descriptor_mapping, descriptor, &md)) + { + ump_dd_reference_release(ump_mem); + _mali_osk_free(descriptor); + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } + + external_memory_allocator.allocate = ump_memory_commit; + external_memory_allocator.allocate_page_table_block = NULL; + external_memory_allocator.ctx = ump_mem; + external_memory_allocator.name = "UMP Memory"; + external_memory_allocator.next = NULL; + + _mali_osk_lock_wait(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); + + if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_memory(memory_engine, descriptor, &external_memory_allocator, NULL)) + { + _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); + mali_descriptor_mapping_free(session_data->descriptor_mapping, md); + ump_dd_reference_release(ump_mem); + _mali_osk_free(descriptor); + MALI_ERROR(_MALI_OSK_ERR_NOMEM); + } + + _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); + + args->cookie = md; + + MALI_DEBUG_PRINT(5,("Returning from UMP attach\n")); + + /* All OK */ + MALI_SUCCESS; +} + + +_mali_osk_errcode_t _mali_ukk_release_ump_mem( _mali_uk_release_ump_mem_s *args ) +{ + mali_memory_allocation * descriptor; + struct mali_session_data *session_data; + + MALI_DEBUG_ASSERT_POINTER(args); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + + session_data = (struct mali_session_data *)args->ctx; + MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS); + + if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_get(session_data->descriptor_mapping, args->cookie, (void**)&descriptor)) + { + MALI_DEBUG_PRINT(1, ("Invalid memory descriptor %d used to release ump memory\n", args->cookie)); + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } + + descriptor = mali_descriptor_mapping_free(session_data->descriptor_mapping, args->cookie); + + if (NULL != descriptor) + { + _mali_osk_lock_wait( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW ); + + mali_allocation_engine_release_memory(memory_engine, descriptor); + + _mali_osk_lock_signal( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW ); + + _mali_osk_free(descriptor); + } + + MALI_SUCCESS; + +} +#endif /* MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 */ + + +static mali_physical_memory_allocation_result external_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info) +{ + u32 * data; + external_mem_allocation * ret_allocation; + + MALI_DEBUG_ASSERT_POINTER(ctx); + MALI_DEBUG_ASSERT_POINTER(engine); + MALI_DEBUG_ASSERT_POINTER(descriptor); + MALI_DEBUG_ASSERT_POINTER(alloc_info); + + ret_allocation = _mali_osk_malloc( sizeof(external_mem_allocation) ); + + if ( NULL == ret_allocation ) + { + return MALI_MEM_ALLOC_INTERNAL_FAILURE; + } + + data = (u32*)ctx; + + ret_allocation->engine = engine; + ret_allocation->descriptor = descriptor; + ret_allocation->initial_offset = *offset; + + alloc_info->ctx = NULL; + alloc_info->handle = ret_allocation; + alloc_info->next = NULL; + alloc_info->release = external_memory_release; + + MALI_DEBUG_PRINT(5, ("External map: mapping phys 0x%08X at mali virtual address 0x%08X staring at offset 0x%08X length 0x%08X\n", data[0], descriptor->mali_address, *offset, data[1])); + + if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, data[0], 0, data[1])) + { + MALI_DEBUG_PRINT(1, ("Mapping of external memory failed\n")); + _mali_osk_free(ret_allocation); + return MALI_MEM_ALLOC_INTERNAL_FAILURE; + } + *offset += data[1]; + + if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE) + { + /* Map in an extra virtual guard page at the end of the VMA */ + MALI_DEBUG_PRINT(4, ("Mapping in extra guard page\n")); + if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, data[0], 0, _MALI_OSK_MALI_PAGE_SIZE)) + { + u32 size_allocated = *offset - ret_allocation->initial_offset; + MALI_DEBUG_PRINT(1, ("Mapping of external memory (guard page) failed\n")); + + /* unmap what we previously mapped */ + mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->initial_offset, size_allocated, (_mali_osk_mem_mapregion_flags_t)0 ); + _mali_osk_free(ret_allocation); + return MALI_MEM_ALLOC_INTERNAL_FAILURE; + } + *offset += _MALI_OSK_MALI_PAGE_SIZE; + } + + ret_allocation->size = *offset - ret_allocation->initial_offset; + + return MALI_MEM_ALLOC_FINISHED; +} + +static void external_memory_release(void * ctx, void * handle) +{ + external_mem_allocation * allocation; + + allocation = (external_mem_allocation *) handle; + MALI_DEBUG_ASSERT_POINTER( allocation ); + + /* At present, this is a no-op. But, it allows the mali_address_manager to + * do unmapping of a subrange in future. */ + + mali_allocation_engine_unmap_physical( allocation->engine, + allocation->descriptor, + allocation->initial_offset, + allocation->size, + (_mali_osk_mem_mapregion_flags_t)0 + ); + + _mali_osk_free( allocation ); + + return; +} + +_mali_osk_errcode_t _mali_ukk_map_external_mem( _mali_uk_map_external_mem_s *args ) +{ + mali_physical_memory_allocator external_memory_allocator; + struct mali_session_data *session_data; + u32 info[2]; + mali_memory_allocation * descriptor; + int md; + + MALI_DEBUG_ASSERT_POINTER(args); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + + session_data = (struct mali_session_data *)args->ctx; + MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS); + + external_memory_allocator.allocate = external_memory_commit; + external_memory_allocator.allocate_page_table_block = NULL; + external_memory_allocator.ctx = &info[0]; + external_memory_allocator.name = "External Memory"; + external_memory_allocator.next = NULL; + + /* check arguments */ + /* NULL might be a valid Mali address */ + if ( ! args->size) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); + + /* size must be a multiple of the system page size */ + if ( args->size % _MALI_OSK_MALI_PAGE_SIZE ) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); + + MALI_DEBUG_PRINT(3, + ("Requested to map physical memory 0x%x-0x%x into virtual memory 0x%x\n", + (void*)args->phys_addr, + (void*)(args->phys_addr + args->size -1), + (void*)args->mali_address) + ); + + /* Validate the mali physical range */ + if (_MALI_OSK_ERR_OK != mali_mem_validation_check(args->phys_addr, args->size)) + { + return _MALI_OSK_ERR_FAULT; + } + + info[0] = args->phys_addr; + info[1] = args->size; + + descriptor = _mali_osk_calloc(1, sizeof(mali_memory_allocation)); + if (NULL == descriptor) MALI_ERROR(_MALI_OSK_ERR_NOMEM); + + descriptor->size = args->size; + descriptor->mapping = NULL; + descriptor->mali_address = args->mali_address; + descriptor->mali_addr_mapping_info = (void*)session_data; + descriptor->process_addr_mapping_info = NULL; /* do not map to process address space */ + descriptor->cache_settings = (u32)MALI_CACHE_STANDARD; + descriptor->lock = session_data->memory_lock; + if (args->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) + { + descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE; + } + _mali_osk_list_init( &descriptor->list ); + + _mali_osk_lock_wait(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); + + if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_memory(memory_engine, descriptor, &external_memory_allocator, NULL)) + { + _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); + _mali_osk_free(descriptor); + MALI_ERROR(_MALI_OSK_ERR_NOMEM); + } + + _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); + + if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session_data->descriptor_mapping, descriptor, &md)) + { + mali_allocation_engine_release_memory(memory_engine, descriptor); + _mali_osk_free(descriptor); + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } + + args->cookie = md; + + MALI_DEBUG_PRINT(5,("Returning from range_map_external_memory\n")); + + /* All OK */ + MALI_SUCCESS; +} + + +_mali_osk_errcode_t _mali_ukk_unmap_external_mem( _mali_uk_unmap_external_mem_s *args ) +{ + mali_memory_allocation * descriptor; + void* old_value; + struct mali_session_data *session_data; + + MALI_DEBUG_ASSERT_POINTER(args); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + + session_data = (struct mali_session_data *)args->ctx; + MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS); + + if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_get(session_data->descriptor_mapping, args->cookie, (void**)&descriptor)) + { + MALI_DEBUG_PRINT(1, ("Invalid memory descriptor %d used to unmap external memory\n", args->cookie)); + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } + + old_value = mali_descriptor_mapping_free(session_data->descriptor_mapping, args->cookie); + + if (NULL != old_value) + { + _mali_osk_lock_wait( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW ); + + mali_allocation_engine_release_memory(memory_engine, descriptor); + + _mali_osk_lock_signal( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW ); + + _mali_osk_free(descriptor); + } + + MALI_SUCCESS; +} + +_mali_osk_errcode_t _mali_ukk_init_mem( _mali_uk_init_mem_s *args ) +{ + MALI_DEBUG_ASSERT_POINTER(args); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + + args->memory_size = 2 * 1024 * 1024 * 1024UL; /* 2GB address space */ + args->mali_address_base = 1 * 1024 * 1024 * 1024UL; /* staring at 1GB, causing this layout: (0-1GB unused)(1GB-3G usage by Mali)(3G-4G unused) */ + MALI_SUCCESS; +} + +_mali_osk_errcode_t _mali_ukk_term_mem( _mali_uk_term_mem_s *args ) +{ + MALI_DEBUG_ASSERT_POINTER(args); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + MALI_SUCCESS; +} + +static _mali_osk_errcode_t mali_address_manager_allocate(mali_memory_allocation * descriptor) +{ + struct mali_session_data *session_data; + u32 actual_size; + + MALI_DEBUG_ASSERT_POINTER(descriptor); + + session_data = (struct mali_session_data *)descriptor->mali_addr_mapping_info; + + actual_size = descriptor->size; + + if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE) + { + actual_size += _MALI_OSK_MALI_PAGE_SIZE; + } + + return mali_mmu_pagedir_map(session_data->page_directory, descriptor->mali_address, actual_size); +} + +static void mali_address_manager_release(mali_memory_allocation * descriptor) +{ + const u32 illegal_mali_address = 0xffffffff; + struct mali_session_data *session_data; + MALI_DEBUG_ASSERT_POINTER(descriptor); + + /* It is allowed to call this function several times on the same descriptor. + When memory is released we set the illegal_mali_address so we can early out here. */ + if ( illegal_mali_address == descriptor->mali_address) return; + + session_data = (struct mali_session_data *)descriptor->mali_addr_mapping_info; + mali_mmu_pagedir_unmap(session_data->page_directory, descriptor->mali_address, descriptor->size); + + descriptor->mali_address = illegal_mali_address ; +} + +static _mali_osk_errcode_t mali_address_manager_map(mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size) +{ + struct mali_session_data *session_data; + u32 mali_address; + + MALI_DEBUG_ASSERT_POINTER(descriptor); + MALI_DEBUG_ASSERT_POINTER(phys_addr); + + session_data = (struct mali_session_data *)descriptor->mali_addr_mapping_info; + MALI_DEBUG_ASSERT_POINTER(session_data); + + mali_address = descriptor->mali_address + offset; + + MALI_DEBUG_PRINT(7, ("Mali map: mapping 0x%08X to Mali address 0x%08X length 0x%08X\n", *phys_addr, mali_address, size)); + + mali_mmu_pagedir_update(session_data->page_directory, mali_address, *phys_addr, size, descriptor->cache_settings); + + MALI_SUCCESS; +} + +/* This handler registered to mali_mmap for MMU builds */ +_mali_osk_errcode_t _mali_ukk_mem_mmap( _mali_uk_mem_mmap_s *args ) +{ + struct mali_session_data *session_data; + mali_memory_allocation * descriptor; + + /* validate input */ + if (NULL == args) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: args was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); } + + /* Unpack arguments */ + session_data = (struct mali_session_data *)args->ctx; + + /* validate input */ + if (NULL == session_data) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: session data was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_FAULT); } + + descriptor = (mali_memory_allocation*) _mali_osk_calloc( 1, sizeof(mali_memory_allocation) ); + if (NULL == descriptor) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: descriptor was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_NOMEM); } + + descriptor->size = args->size; + descriptor->mali_address = args->phys_addr; + descriptor->mali_addr_mapping_info = (void*)session_data; + + descriptor->process_addr_mapping_info = args->ukk_private; /* save to be used during physical manager callback */ + descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE; + descriptor->cache_settings = (u32) args->cache_settings ; + descriptor->lock = session_data->memory_lock; + _mali_osk_list_init( &descriptor->list ); + + _mali_osk_lock_wait(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); + + if (0 == mali_allocation_engine_allocate_memory(memory_engine, descriptor, physical_memory_allocators, &session_data->memory_head)) + { + /* We do not FLUSH nor TLB_ZAP on MMAP, since we do both of those on job start*/ + _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); + + args->mapping = descriptor->mapping; + args->cookie = (u32)descriptor; + + MALI_DEBUG_PRINT(7, ("MMAP OK\n")); + MALI_SUCCESS; + } + else + { + _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); + /* OOM, but not a fatal error */ + MALI_DEBUG_PRINT(4, ("Memory allocation failure, OOM\n")); + _mali_osk_free(descriptor); + /* Linux will free the CPU address allocation, userspace client the Mali address allocation */ + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } +} + +static _mali_osk_errcode_t _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args ) +{ + struct mali_session_data *session_data; + mali_memory_allocation * descriptor; + + u32 num_groups = mali_group_get_glob_num_groups(); + struct mali_group *group; + u32 i; + + descriptor = (mali_memory_allocation *)args->cookie; + MALI_DEBUG_ASSERT_POINTER(descriptor); + + /** @note args->context unused; we use the memory_session from the cookie */ + /* args->mapping and args->size are also discarded. They are only necessary + for certain do_munmap implementations. However, they could be used to check the + descriptor at this point. */ + + session_data = (struct mali_session_data *)descriptor->mali_addr_mapping_info; + MALI_DEBUG_ASSERT_POINTER(session_data); + + /* Unmapping the memory from the mali virtual address space. + It is allowed to call this function severeal times, which might happen if zapping below fails. */ + mali_allocation_engine_release_pt1_mali_pagetables_unmap(memory_engine, descriptor); + +#ifdef MALI_UNMAP_FLUSH_ALL_MALI_L2 + { + u32 number_of_clusters = mali_cluster_get_glob_num_clusters(); + for (i = 0; i < number_of_clusters; i++) + { + struct mali_cluster *cluster; + cluster = mali_cluster_get_global_cluster(i); + if( mali_cluster_power_is_enabled_get(cluster) ) + { + mali_cluster_l2_cache_invalidate_all_force(cluster); + } + } + } +#endif + + for (i = 0; i < num_groups; i++) + { + group = mali_group_get_glob_group(i); + mali_group_lock(group); + mali_group_remove_session_if_unused(group, session_data); + if (mali_group_get_session(group) == session_data) + { + /* The Zap also does the stall and disable_stall */ + mali_bool zap_success = mali_mmu_zap_tlb(mali_group_get_mmu(group)); + if (MALI_TRUE != zap_success) + { + MALI_DEBUG_PRINT(2, ("Mali memory unmap failed. Doing pagefault handling.\n")); + mali_group_bottom_half(group, GROUP_EVENT_MMU_PAGE_FAULT); + /* The bottom half will also do the unlock */ + continue; + } + } + mali_group_unlock(group); + } + + /* Removes the descriptor from the session's memory list, releases physical memory, releases descriptor */ + mali_allocation_engine_release_pt2_physical_memory_free(memory_engine, descriptor); + + _mali_osk_free(descriptor); + + return _MALI_OSK_ERR_OK; +} + +/* Handler for unmapping memory for MMU builds */ +_mali_osk_errcode_t _mali_ukk_mem_munmap( _mali_uk_mem_munmap_s *args ) +{ + mali_memory_allocation * descriptor; + _mali_osk_lock_t *descriptor_lock; + _mali_osk_errcode_t err; + + descriptor = (mali_memory_allocation *)args->cookie; + MALI_DEBUG_ASSERT_POINTER(descriptor); + + /** @note args->context unused; we use the memory_session from the cookie */ + /* args->mapping and args->size are also discarded. They are only necessary + for certain do_munmap implementations. However, they could be used to check the + descriptor at this point. */ + + MALI_DEBUG_ASSERT_POINTER((struct mali_session_data *)descriptor->mali_addr_mapping_info); + + descriptor_lock = descriptor->lock; /* should point to the session data lock... */ + + err = _MALI_OSK_ERR_BUSY; + while (err == _MALI_OSK_ERR_BUSY) + { + if (descriptor_lock) + { + _mali_osk_lock_wait( descriptor_lock, _MALI_OSK_LOCKMODE_RW ); + } + + err = _mali_ukk_mem_munmap_internal( args ); + + if (descriptor_lock) + { + _mali_osk_lock_signal( descriptor_lock, _MALI_OSK_LOCKMODE_RW ); + } + + if (err == _MALI_OSK_ERR_BUSY) + { + /* + * Reason for this; + * We where unable to stall the MMU, probably because we are in page fault handling. + * Sleep for a while with the session lock released, then try again. + * Abnormal termination of programs with running Mali jobs is a normal reason for this. + */ + _mali_osk_time_ubusydelay(10); + } + } + + return err; +} + +u32 _mali_ukk_report_memory_usage(void) +{ + return mali_allocation_engine_memory_usage(physical_memory_allocators); +} + +_mali_osk_errcode_t mali_mmu_get_table_page(u32 *table_page, mali_io_address *mapping) +{ + _mali_osk_lock_wait(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); + + if (0 == _mali_osk_list_empty(&page_table_cache.partial)) + { + mali_mmu_page_table_allocation * alloc = _MALI_OSK_LIST_ENTRY(page_table_cache.partial.next, mali_mmu_page_table_allocation, list); + int page_number = _mali_osk_find_first_zero_bit(alloc->usage_map, alloc->num_pages); + MALI_DEBUG_PRINT(6, ("Partial page table allocation found, using page offset %d\n", page_number)); + _mali_osk_set_nonatomic_bit(page_number, alloc->usage_map); + alloc->usage_count++; + if (alloc->num_pages == alloc->usage_count) + { + /* full, move alloc to full list*/ + _mali_osk_list_move(&alloc->list, &page_table_cache.full); + } + _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); + + *table_page = (MALI_MMU_PAGE_SIZE * page_number) + alloc->pages.phys_base; + *mapping = (mali_io_address)((MALI_MMU_PAGE_SIZE * page_number) + (u32)alloc->pages.mapping); + MALI_DEBUG_PRINT(4, ("Page table allocated for VA=0x%08X, MaliPA=0x%08X\n", *mapping, *table_page )); + MALI_SUCCESS; + } + else + { + mali_mmu_page_table_allocation * alloc; + /* no free pages, allocate a new one */ + + alloc = (mali_mmu_page_table_allocation *)_mali_osk_calloc(1, sizeof(mali_mmu_page_table_allocation)); + if (NULL == alloc) + { + _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); + *table_page = MALI_INVALID_PAGE; + MALI_ERROR(_MALI_OSK_ERR_NOMEM); + } + + _MALI_OSK_INIT_LIST_HEAD(&alloc->list); + + if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_page_tables(memory_engine, &alloc->pages, physical_memory_allocators)) + { + MALI_DEBUG_PRINT(1, ("No more memory for page tables\n")); + _mali_osk_free(alloc); + _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); + *table_page = MALI_INVALID_PAGE; + *mapping = NULL; + MALI_ERROR(_MALI_OSK_ERR_NOMEM); + } + + /* create the usage map */ + alloc->num_pages = alloc->pages.size / MALI_MMU_PAGE_SIZE; + alloc->usage_count = 1; + MALI_DEBUG_PRINT(3, ("New page table cache expansion, %d pages in new cache allocation\n", alloc->num_pages)); + alloc->usage_map = _mali_osk_calloc(1, ((alloc->num_pages + BITS_PER_LONG - 1) & ~(BITS_PER_LONG-1) / BITS_PER_LONG) * sizeof(unsigned long)); + if (NULL == alloc->usage_map) + { + MALI_DEBUG_PRINT(1, ("Failed to allocate memory to describe MMU page table cache usage\n")); + alloc->pages.release(&alloc->pages); + _mali_osk_free(alloc); + _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); + *table_page = MALI_INVALID_PAGE; + *mapping = NULL; + MALI_ERROR(_MALI_OSK_ERR_NOMEM); + } + + _mali_osk_set_nonatomic_bit(0, alloc->usage_map); + + if (alloc->num_pages > 1) + { + _mali_osk_list_add(&alloc->list, &page_table_cache.partial); + } + else + { + _mali_osk_list_add(&alloc->list, &page_table_cache.full); + } + + _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); + *table_page = alloc->pages.phys_base; /* return the first page */ + *mapping = alloc->pages.mapping; /* Mapping for first page */ + MALI_DEBUG_PRINT(4, ("Page table allocated: VA=0x%08X, MaliPA=0x%08X\n", *mapping, *table_page )); + MALI_SUCCESS; + } +} + +void mali_mmu_release_table_page(u32 pa) +{ + mali_mmu_page_table_allocation * alloc, * temp_alloc; + + MALI_DEBUG_PRINT_IF(1, pa & 4095, ("Bad page address 0x%x given to mali_mmu_release_table_page\n", (void*)pa)); + + MALI_DEBUG_PRINT(4, ("Releasing table page 0x%08X to the cache\n", pa)); + + _mali_osk_lock_wait(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); + + /* find the entry this address belongs to */ + /* first check the partial list */ + _MALI_OSK_LIST_FOREACHENTRY(alloc, temp_alloc, &page_table_cache.partial, mali_mmu_page_table_allocation, list) + { + u32 start = alloc->pages.phys_base; + u32 last = start + (alloc->num_pages - 1) * MALI_MMU_PAGE_SIZE; + if (pa >= start && pa <= last) + { + MALI_DEBUG_ASSERT(0 != _mali_osk_test_bit((pa - start)/MALI_MMU_PAGE_SIZE, alloc->usage_map)); + _mali_osk_clear_nonatomic_bit((pa - start)/MALI_MMU_PAGE_SIZE, alloc->usage_map); + alloc->usage_count--; + + _mali_osk_memset((void*)( ((u32)alloc->pages.mapping) + (pa - start) ), 0, MALI_MMU_PAGE_SIZE); + + if (0 == alloc->usage_count) + { + /* empty, release whole page alloc */ + _mali_osk_list_del(&alloc->list); + alloc->pages.release(&alloc->pages); + _mali_osk_free(alloc->usage_map); + _mali_osk_free(alloc); + } + _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); + MALI_DEBUG_PRINT(4, ("(partial list)Released table page 0x%08X to the cache\n", pa)); + return; + } + } + + /* the check the full list */ + _MALI_OSK_LIST_FOREACHENTRY(alloc, temp_alloc, &page_table_cache.full, mali_mmu_page_table_allocation, list) + { + u32 start = alloc->pages.phys_base; + u32 last = start + (alloc->num_pages - 1) * MALI_MMU_PAGE_SIZE; + if (pa >= start && pa <= last) + { + _mali_osk_clear_nonatomic_bit((pa - start)/MALI_MMU_PAGE_SIZE, alloc->usage_map); + alloc->usage_count--; + + _mali_osk_memset((void*)( ((u32)alloc->pages.mapping) + (pa - start) ), 0, MALI_MMU_PAGE_SIZE); + + + if (0 == alloc->usage_count) + { + /* empty, release whole page alloc */ + _mali_osk_list_del(&alloc->list); + alloc->pages.release(&alloc->pages); + _mali_osk_free(alloc->usage_map); + _mali_osk_free(alloc); + } + else + { + /* transfer to partial list */ + _mali_osk_list_move(&alloc->list, &page_table_cache.partial); + } + + _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); + MALI_DEBUG_PRINT(4, ("(full list)Released table page 0x%08X to the cache\n", pa)); + return; + } + } + + MALI_DEBUG_PRINT(1, ("pa 0x%x not found in the page table cache\n", (void*)pa)); + + _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); +} + +static _mali_osk_errcode_t mali_mmu_page_table_cache_create(void) +{ + page_table_cache.lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_ONELOCK + | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_MEM_PT_CACHE); + MALI_CHECK_NON_NULL( page_table_cache.lock, _MALI_OSK_ERR_FAULT ); + _MALI_OSK_INIT_LIST_HEAD(&page_table_cache.partial); + _MALI_OSK_INIT_LIST_HEAD(&page_table_cache.full); + MALI_SUCCESS; +} + +static void mali_mmu_page_table_cache_destroy(void) +{ + mali_mmu_page_table_allocation * alloc, *temp; + + _MALI_OSK_LIST_FOREACHENTRY(alloc, temp, &page_table_cache.partial, mali_mmu_page_table_allocation, list) + { + MALI_DEBUG_PRINT_IF(1, 0 != alloc->usage_count, ("Destroying page table cache while pages are tagged as in use. %d allocations still marked as in use.\n", alloc->usage_count)); + _mali_osk_list_del(&alloc->list); + alloc->pages.release(&alloc->pages); + _mali_osk_free(alloc->usage_map); + _mali_osk_free(alloc); + } + + MALI_DEBUG_PRINT_IF(1, 0 == _mali_osk_list_empty(&page_table_cache.full), ("Page table cache full list contains one or more elements \n")); + + _MALI_OSK_LIST_FOREACHENTRY(alloc, temp, &page_table_cache.full, mali_mmu_page_table_allocation, list) + { + MALI_DEBUG_PRINT(1, ("Destroy alloc 0x%08X with usage count %d\n", (u32)alloc, alloc->usage_count)); + _mali_osk_list_del(&alloc->list); + alloc->pages.release(&alloc->pages); + _mali_osk_free(alloc->usage_map); + _mali_osk_free(alloc); + } + + _mali_osk_lock_term(page_table_cache.lock); +} diff --git a/drivers/media/video/samsung/mali/common/mali_memory.h b/drivers/media/video/samsung/mali/common/mali_memory.h new file mode 100644 index 0000000..78e2945 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_memory.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_MEMORY_H__ +#define __MALI_MEMORY_H__ + +#include "mali_osk.h" +#include "mali_session.h" + +struct mali_cluster; +struct mali_group; + +/** @brief Initialize Mali memory subsystem + * + * Allocate and initialize internal data structures. Must be called before + * allocating Mali memory. + * + * @return On success _MALI_OSK_ERR_OK, othervise some error code describing the error. + */ +_mali_osk_errcode_t mali_memory_initialize(void); + +/** @brief Terminate Mali memory system + * + * Clean up and release internal data structures. + */ +void mali_memory_terminate(void); + +/** @brief Start new Mali memory session + * + * Allocate and prepare session specific memory allocation data data. The + * session page directory, lock, and descriptor map is set up. + * + * @param mali_session_data pointer to the session data structure + */ +_mali_osk_errcode_t mali_memory_session_begin(struct mali_session_data *mali_session_data); + +/** @brief Close a Mali memory session + * + * Release session specific memory allocation related data. + * + * @param mali_session_data pointer to the session data structure + */ +void mali_memory_session_end(struct mali_session_data *mali_session_data); + +/** @brief Allocate a page table page + * + * Allocate a page for use as a page directory or page table. The page is + * mapped into kernel space. + * + * @return _MALI_OSK_ERR_OK on success, othervise an error code + * @param table_page GPU pointer to the allocated page + * @param mapping CPU pointer to the mapping of the allocated page + */ +_mali_osk_errcode_t mali_mmu_get_table_page(u32 *table_page, mali_io_address *mapping); + +/** @brief Release a page table page + * + * Release a page table page allocated through \a mali_mmu_get_table_page + * + * @param pa the GPU address of the page to release + */ +void mali_mmu_release_table_page(u32 pa); + + +/** @brief Parse resource and prepare the OS memory allocator + */ +_mali_osk_errcode_t mali_memory_core_resource_os_memory(_mali_osk_resource_t * resource); + +/** @brief Parse resource and prepare the dedicated memory allocator + */ +_mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(_mali_osk_resource_t * resource); + +mali_allocation_engine mali_mem_get_memory_engine(void); + +#endif /* __MALI_MEMORY_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_mmu.c b/drivers/media/video/samsung/mali/common/mali_mmu.c new file mode 100644 index 0000000..2f2fa4d --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_mmu.c @@ -0,0 +1,619 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_kernel_common.h" +#include "mali_osk.h" +#include "mali_osk_bitops.h" +#include "mali_osk_list.h" +#include "mali_ukk.h" + +#include "mali_mmu.h" +#include "mali_hw_core.h" +#include "mali_group.h" +#include "mali_mmu_page_directory.h" + +/** + * Size of the MMU registers in bytes + */ +#define MALI_MMU_REGISTERS_SIZE 0x24 + +/** + * MMU register numbers + * Used in the register read/write routines. + * See the hardware documentation for more information about each register + */ +typedef enum mali_mmu_register { + MALI_MMU_REGISTER_DTE_ADDR = 0x0000, /**< Current Page Directory Pointer */ + MALI_MMU_REGISTER_STATUS = 0x0004, /**< Status of the MMU */ + MALI_MMU_REGISTER_COMMAND = 0x0008, /**< Command register, used to control the MMU */ + MALI_MMU_REGISTER_PAGE_FAULT_ADDR = 0x000C, /**< Logical address of the last page fault */ + MALI_MMU_REGISTER_ZAP_ONE_LINE = 0x010, /**< Used to invalidate the mapping of a single page from the MMU */ + MALI_MMU_REGISTER_INT_RAWSTAT = 0x0014, /**< Raw interrupt status, all interrupts visible */ + MALI_MMU_REGISTER_INT_CLEAR = 0x0018, /**< Indicate to the MMU that the interrupt has been received */ + MALI_MMU_REGISTER_INT_MASK = 0x001C, /**< Enable/disable types of interrupts */ + MALI_MMU_REGISTER_INT_STATUS = 0x0020 /**< Interrupt status based on the mask */ +} mali_mmu_register; + +/** + * MMU interrupt register bits + * Each cause of the interrupt is reported + * through the (raw) interrupt status registers. + * Multiple interrupts can be pending, so multiple bits + * can be set at once. + */ +typedef enum mali_mmu_interrupt +{ + MALI_MMU_INTERRUPT_PAGE_FAULT = 0x01, /**< A page fault occured */ + MALI_MMU_INTERRUPT_READ_BUS_ERROR = 0x02 /**< A bus read error occured */ +} mali_mmu_interrupt; + +/** + * MMU commands + * These are the commands that can be sent + * to the MMU unit. + */ +typedef enum mali_mmu_command +{ + MALI_MMU_COMMAND_ENABLE_PAGING = 0x00, /**< Enable paging (memory translation) */ + MALI_MMU_COMMAND_DISABLE_PAGING = 0x01, /**< Disable paging (memory translation) */ + MALI_MMU_COMMAND_ENABLE_STALL = 0x02, /**< Enable stall on page fault */ + MALI_MMU_COMMAND_DISABLE_STALL = 0x03, /**< Disable stall on page fault */ + MALI_MMU_COMMAND_ZAP_CACHE = 0x04, /**< Zap the entire page table cache */ + MALI_MMU_COMMAND_PAGE_FAULT_DONE = 0x05, /**< Page fault processed */ + MALI_MMU_COMMAND_HARD_RESET = 0x06 /**< Reset the MMU back to power-on settings */ +} mali_mmu_command; + +typedef enum mali_mmu_status_bits +{ + MALI_MMU_STATUS_BIT_PAGING_ENABLED = 1 << 0, + MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE = 1 << 1, + MALI_MMU_STATUS_BIT_STALL_ACTIVE = 1 << 2, + MALI_MMU_STATUS_BIT_IDLE = 1 << 3, + MALI_MMU_STATUS_BIT_REPLAY_BUFFER_EMPTY = 1 << 4, + MALI_MMU_STATUS_BIT_PAGE_FAULT_IS_WRITE = 1 << 5, +} mali_mmu_status_bits; + +/** + * Definition of the MMU struct + * Used to track a MMU unit in the system. + * Contains information about the mapping of the registers + */ +struct mali_mmu_core +{ + struct mali_hw_core hw_core; /**< Common for all HW cores */ + struct mali_group *group; /**< Parent core group */ + _mali_osk_irq_t *irq; /**< IRQ handler */ +}; + +/** + * The MMU interrupt handler + * Upper half of the MMU interrupt processing. + * Called by the kernel when the MMU has triggered an interrupt. + * The interrupt function supports IRQ sharing. So it'll probe the MMU in question + * @param irq The irq number (not used) + * @param dev_id Points to the MMU object being handled + * @param regs Registers of interrupted process (not used) + * @return Standard Linux interrupt result. + * Subset used by the driver is IRQ_HANDLED processed + * IRQ_NONE Not processed + */ +static _mali_osk_errcode_t mali_mmu_upper_half(void * data); + +/** + * The MMU reset hander + * Bottom half of the MMU interrupt processing for page faults and bus errors + * @param work The item to operate on, NULL in our case + */ +static void mali_mmu_bottom_half(void *data); + +static void mali_mmu_probe_trigger(void *data); +static _mali_osk_errcode_t mali_mmu_probe_ack(void *data); + +MALI_STATIC_INLINE _mali_osk_errcode_t mali_mmu_raw_reset(struct mali_mmu_core *mmu); + +/* page fault queue flush helper pages + * note that the mapping pointers are currently unused outside of the initialization functions */ +static u32 mali_page_fault_flush_page_directory = MALI_INVALID_PAGE; +static u32 mali_page_fault_flush_page_table = MALI_INVALID_PAGE; +static u32 mali_page_fault_flush_data_page = MALI_INVALID_PAGE; + +/* an empty page directory (no address valid) which is active on any MMU not currently marked as in use */ +static u32 mali_empty_page_directory = MALI_INVALID_PAGE; + +_mali_osk_errcode_t mali_mmu_initialize(void) +{ + /* allocate the helper pages */ + mali_empty_page_directory = mali_allocate_empty_page(); + if(0 == mali_empty_page_directory) + { + mali_empty_page_directory = MALI_INVALID_PAGE; + return _MALI_OSK_ERR_NOMEM; + } + + if (_MALI_OSK_ERR_OK != mali_create_fault_flush_pages(&mali_page_fault_flush_page_directory, + &mali_page_fault_flush_page_table, &mali_page_fault_flush_data_page)) + { + mali_free_empty_page(mali_empty_page_directory); + return _MALI_OSK_ERR_FAULT; + } + + return _MALI_OSK_ERR_OK; +} + +void mali_mmu_terminate(void) +{ + MALI_DEBUG_PRINT(3, ("Mali MMU: terminating\n")); + + /* Free global helper pages */ + mali_free_empty_page(mali_empty_page_directory); + + /* Free the page fault flush pages */ + mali_destroy_fault_flush_pages(&mali_page_fault_flush_page_directory, + &mali_page_fault_flush_page_table, &mali_page_fault_flush_data_page); +} + +struct mali_mmu_core *mali_mmu_create(_mali_osk_resource_t *resource) +{ + struct mali_mmu_core* mmu = NULL; + + MALI_DEBUG_ASSERT_POINTER(resource); + + MALI_DEBUG_PRINT(2, ("Mali MMU: Creating Mali MMU: %s\n", resource->description)); + + mmu = _mali_osk_calloc(1,sizeof(struct mali_mmu_core)); + if (NULL != mmu) + { + if (_MALI_OSK_ERR_OK == mali_hw_core_create(&mmu->hw_core, resource, MALI_MMU_REGISTERS_SIZE)) + { + if (_MALI_OSK_ERR_OK == mali_mmu_reset(mmu)) + { + /* Setup IRQ handlers (which will do IRQ probing if needed) */ + mmu->irq = _mali_osk_irq_init(resource->irq, + mali_mmu_upper_half, + mali_mmu_bottom_half, + mali_mmu_probe_trigger, + mali_mmu_probe_ack, + mmu, + "mali_mmu_irq_handlers"); + if (NULL != mmu->irq) + { + return mmu; + } + else + { + MALI_PRINT_ERROR(("Failed to setup interrupt handlers for MMU %s\n", mmu->hw_core.description)); + } + } + mali_hw_core_delete(&mmu->hw_core); + } + + _mali_osk_free(mmu); + } + else + { + MALI_PRINT_ERROR(("Failed to allocate memory for MMU\n")); + } + + return NULL; +} + +void mali_mmu_delete(struct mali_mmu_core *mmu) +{ + _mali_osk_irq_term(mmu->irq); + mali_hw_core_delete(&mmu->hw_core); + _mali_osk_free(mmu); +} + +void mali_mmu_set_group(struct mali_mmu_core *mmu, struct mali_group *group) +{ + mmu->group = group; +} + +static void mali_mmu_enable_paging(struct mali_mmu_core *mmu) +{ + const int max_loop_count = 100; + const int delay_in_usecs = 1; + int i; + + mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_PAGING); + + for (i = 0; i < max_loop_count; ++i) + { + if (mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_PAGING_ENABLED) + { + break; + } + _mali_osk_time_ubusydelay(delay_in_usecs); + } + if (max_loop_count == i) + { + MALI_PRINT_ERROR(("Enable paging request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS))); + } +} + +mali_bool mali_mmu_enable_stall(struct mali_mmu_core *mmu) +{ + const int max_loop_count = 100; + const int delay_in_usecs = 999; + int i; + u32 mmu_status; + + /* There are no group when it is called from mali_mmu_create */ + if ( mmu->group ) MALI_ASSERT_GROUP_LOCKED(mmu->group); + + mmu_status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS); + + if ( 0 == (mmu_status & MALI_MMU_STATUS_BIT_PAGING_ENABLED) ) + { + MALI_DEBUG_PRINT(4, ("MMU stall is implicit when Paging is not enebled.\n")); + return MALI_TRUE; + } + + if ( mmu_status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE ) + { + MALI_DEBUG_PRINT(3, ("Aborting MMU stall request since it is in pagefault state.\n")); + return MALI_FALSE; + } + + mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_STALL); + + for (i = 0; i < max_loop_count; ++i) + { + mmu_status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS); + if ( mmu_status & (MALI_MMU_STATUS_BIT_STALL_ACTIVE|MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE)) + { + break; + } + if ( 0 == (mmu_status & ( MALI_MMU_STATUS_BIT_PAGING_ENABLED ))) + { + break; + } + _mali_osk_time_ubusydelay(delay_in_usecs); + } + if (max_loop_count == i) + { + MALI_PRINT_ERROR(("Enable stall request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS))); + return MALI_FALSE; + } + + if ( mmu_status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE ) + { + MALI_DEBUG_PRINT(3, ("Aborting MMU stall request since it has a pagefault.\n")); + return MALI_FALSE; + } + + return MALI_TRUE; +} + +void mali_mmu_disable_stall(struct mali_mmu_core *mmu) +{ + const int max_loop_count = 100; + const int delay_in_usecs = 1; + int i; + u32 mmu_status; + /* There are no group when it is called from mali_mmu_create */ + if ( mmu->group ) MALI_ASSERT_GROUP_LOCKED(mmu->group); + + mmu_status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS); + + if ( 0 == (mmu_status & MALI_MMU_STATUS_BIT_PAGING_ENABLED )) + { + MALI_DEBUG_PRINT(3, ("MMU disable skipped since it was not enabled.\n")); + return; + } + if (mmu_status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE) + { + MALI_DEBUG_PRINT(2, ("Aborting MMU disable stall request since it is in pagefault state.\n")); + return; + } + + mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_DISABLE_STALL); + + for (i = 0; i < max_loop_count; ++i) + { + u32 status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS); + if ( 0 == (status & MALI_MMU_STATUS_BIT_STALL_ACTIVE) ) + { + break; + } + if ( status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE ) + { + break; + } + if ( 0 == (mmu_status & MALI_MMU_STATUS_BIT_PAGING_ENABLED )) + { + break; + } + _mali_osk_time_ubusydelay(delay_in_usecs); + } + if (max_loop_count == i) MALI_DEBUG_PRINT(1,("Disable stall request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS))); +} + +void mali_mmu_page_fault_done(struct mali_mmu_core *mmu) +{ + MALI_ASSERT_GROUP_LOCKED(mmu->group); + MALI_DEBUG_PRINT(4, ("Mali MMU: %s: Leaving page fault mode\n", mmu->hw_core.description)); + mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_PAGE_FAULT_DONE); +} + +MALI_STATIC_INLINE _mali_osk_errcode_t mali_mmu_raw_reset(struct mali_mmu_core *mmu) +{ + const int max_loop_count = 100; + const int delay_in_usecs = 1; + int i; + /* The _if_ is neccessary when called from mali_mmu_create and NULL==group */ + if (mmu->group)MALI_ASSERT_GROUP_LOCKED(mmu->group); + + mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR, 0xCAFEBABE); + mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_HARD_RESET); + + for (i = 0; i < max_loop_count; ++i) + { + if (mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR) == 0) + { + break; + } + _mali_osk_time_ubusydelay(delay_in_usecs); + } + if (max_loop_count == i) + { + MALI_PRINT_ERROR(("Reset request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS))); + return _MALI_OSK_ERR_FAULT; + } + + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t mali_mmu_reset(struct mali_mmu_core *mmu) +{ + _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT; + mali_bool stall_success; + MALI_DEBUG_ASSERT_POINTER(mmu); + /* The _if_ is neccessary when called from mali_mmu_create and NULL==group */ + if (mmu->group) + { + MALI_ASSERT_GROUP_LOCKED(mmu->group); + } + + stall_success = mali_mmu_enable_stall(mmu); + + /* The stall can not fail in current hw-state */ + MALI_DEBUG_ASSERT(stall_success); + + MALI_DEBUG_PRINT(3, ("Mali MMU: mali_kernel_mmu_reset: %s\n", mmu->hw_core.description)); + + if (_MALI_OSK_ERR_OK == mali_mmu_raw_reset(mmu)) + { + mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK, MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR); + /* no session is active, so just activate the empty page directory */ + mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR, mali_empty_page_directory); + mali_mmu_enable_paging(mmu); + err = _MALI_OSK_ERR_OK; + } + mali_mmu_disable_stall(mmu); + + return err; +} + + +/* ------------- interrupt handling below ------------------ */ + +static _mali_osk_errcode_t mali_mmu_upper_half(void * data) +{ + struct mali_mmu_core *mmu = (struct mali_mmu_core *)data; + u32 int_stat; + + MALI_DEBUG_ASSERT_POINTER(mmu); + + /* Check if it was our device which caused the interrupt (we could be sharing the IRQ line) */ + int_stat = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_STATUS); + if (0 != int_stat) + { + mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK, 0); + mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS); + + if (int_stat & MALI_MMU_INTERRUPT_PAGE_FAULT) + { + _mali_osk_irq_schedulework(mmu->irq); + } + + if (int_stat & MALI_MMU_INTERRUPT_READ_BUS_ERROR) + { + /* clear interrupt flag */ + mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_READ_BUS_ERROR); + /* reenable it */ + mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK, + mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK) | MALI_MMU_INTERRUPT_READ_BUS_ERROR); + MALI_PRINT_ERROR(("Mali MMU: Read bus error\n")); + } + return _MALI_OSK_ERR_OK; + } + + return _MALI_OSK_ERR_FAULT; +} + +static void mali_mmu_bottom_half(void * data) +{ + struct mali_mmu_core *mmu = (struct mali_mmu_core*)data; + u32 raw, status, fault_address; + + MALI_DEBUG_ASSERT_POINTER(mmu); + + MALI_DEBUG_PRINT(3, ("Mali MMU: Page fault bottom half: Locking subsystems\n")); + + mali_group_lock(mmu->group); /* Unlocked in mali_group_bottom_half */ + + if ( MALI_FALSE == mali_group_power_is_on(mmu->group) ) + { + MALI_PRINT_ERROR(("Interrupt bottom half of %s when core is OFF.",mmu->hw_core.description)); + mali_group_unlock(mmu->group); + return; + } + + raw = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_RAWSTAT); + status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS); + + if ( (0==(raw & MALI_MMU_INTERRUPT_PAGE_FAULT)) && (0==(status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE)) ) + { + MALI_DEBUG_PRINT(2, ("Mali MMU: Page fault bottom half: No Irq found.\n")); + mali_group_unlock(mmu->group); + /* MALI_DEBUG_ASSERT(0); */ + return; + } + + /* An actual page fault has occurred. */ + + fault_address = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_PAGE_FAULT_ADDR); + + MALI_DEBUG_PRINT(2,("Mali MMU: Page fault detected at 0x%x from bus id %d of type %s on %s\n", + (void*)fault_address, + (status >> 6) & 0x1F, + (status & 32) ? "write" : "read", + mmu->hw_core.description)); + + mali_group_bottom_half(mmu->group, GROUP_EVENT_MMU_PAGE_FAULT); /* Unlocks the group lock */ +} + +mali_bool mali_mmu_zap_tlb(struct mali_mmu_core *mmu) +{ + mali_bool stall_success; + MALI_ASSERT_GROUP_LOCKED(mmu->group); + + stall_success = mali_mmu_enable_stall(mmu); + + mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE); + + if (MALI_FALSE == stall_success) + { + /* False means that it is in Pagefault state. Not possible to disable_stall then */ + return MALI_FALSE; + } + + mali_mmu_disable_stall(mmu); + return MALI_TRUE; +} + +void mali_mmu_zap_tlb_without_stall(struct mali_mmu_core *mmu) +{ + MALI_ASSERT_GROUP_LOCKED(mmu->group); + mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE); +} + + +void mali_mmu_invalidate_page(struct mali_mmu_core *mmu, u32 mali_address) +{ + MALI_ASSERT_GROUP_LOCKED(mmu->group); + mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_ZAP_ONE_LINE, MALI_MMU_PDE_ENTRY(mali_address)); +} + +static void mali_mmu_activate_address_space(struct mali_mmu_core *mmu, u32 page_directory) +{ + MALI_ASSERT_GROUP_LOCKED(mmu->group); + /* The MMU must be in stalled or page fault mode, for this writing to work */ + MALI_DEBUG_ASSERT( 0 != ( mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS) + & (MALI_MMU_STATUS_BIT_STALL_ACTIVE|MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE) ) ); + mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR, page_directory); + mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE); + +} + +mali_bool mali_mmu_activate_page_directory(struct mali_mmu_core *mmu, struct mali_page_directory *pagedir) +{ + mali_bool stall_success; + MALI_DEBUG_ASSERT_POINTER(mmu); + MALI_ASSERT_GROUP_LOCKED(mmu->group); + + MALI_DEBUG_PRINT(5, ("Asked to activate page directory 0x%x on MMU %s\n", pagedir, mmu->hw_core.description)); + stall_success = mali_mmu_enable_stall(mmu); + + if ( MALI_FALSE==stall_success ) return MALI_FALSE; + mali_mmu_activate_address_space(mmu, pagedir->page_directory); + mali_mmu_disable_stall(mmu); + return MALI_TRUE; +} + +void mali_mmu_activate_empty_page_directory(struct mali_mmu_core* mmu) +{ + mali_bool stall_success; + MALI_DEBUG_ASSERT_POINTER(mmu); + MALI_ASSERT_GROUP_LOCKED(mmu->group); + MALI_DEBUG_PRINT(3, ("Activating the empty page directory on MMU %s\n", mmu->hw_core.description)); + + stall_success = mali_mmu_enable_stall(mmu); + /* This function can only be called when the core is idle, so it could not fail. */ + MALI_DEBUG_ASSERT( stall_success ); + mali_mmu_activate_address_space(mmu, mali_empty_page_directory); + mali_mmu_disable_stall(mmu); +} + +void mali_mmu_activate_fault_flush_page_directory(struct mali_mmu_core* mmu) +{ + mali_bool stall_success; + MALI_DEBUG_ASSERT_POINTER(mmu); + MALI_ASSERT_GROUP_LOCKED(mmu->group); + + MALI_DEBUG_PRINT(3, ("Activating the page fault flush page directory on MMU %s\n", mmu->hw_core.description)); + stall_success = mali_mmu_enable_stall(mmu); + /* This function is expect to fail the stalling, since it might be in PageFault mode when it is called */ + mali_mmu_activate_address_space(mmu, mali_page_fault_flush_page_directory); + if ( MALI_TRUE==stall_success ) mali_mmu_disable_stall(mmu); +} + +/* Is called when we want the mmu to give an interrupt */ +static void mali_mmu_probe_trigger(void *data) +{ + struct mali_mmu_core *mmu = (struct mali_mmu_core *)data; + mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_RAWSTAT, MALI_MMU_INTERRUPT_PAGE_FAULT|MALI_MMU_INTERRUPT_READ_BUS_ERROR); +} + +/* Is called when the irq probe wants the mmu to acknowledge an interrupt from the hw */ +static _mali_osk_errcode_t mali_mmu_probe_ack(void *data) +{ + struct mali_mmu_core *mmu = (struct mali_mmu_core *)data; + u32 int_stat; + + int_stat = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_STATUS); + + MALI_DEBUG_PRINT(2, ("mali_mmu_probe_irq_acknowledge: intstat 0x%x\n", int_stat)); + if (int_stat & MALI_MMU_INTERRUPT_PAGE_FAULT) + { + MALI_DEBUG_PRINT(2, ("Probe: Page fault detect: PASSED\n")); + mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_PAGE_FAULT); + } + else + { + MALI_DEBUG_PRINT(1, ("Probe: Page fault detect: FAILED\n")); + } + + if (int_stat & MALI_MMU_INTERRUPT_READ_BUS_ERROR) + { + MALI_DEBUG_PRINT(2, ("Probe: Bus read error detect: PASSED\n")); + mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_READ_BUS_ERROR); + } + else + { + MALI_DEBUG_PRINT(1, ("Probe: Bus read error detect: FAILED\n")); + } + + if ( (int_stat & (MALI_MMU_INTERRUPT_PAGE_FAULT|MALI_MMU_INTERRUPT_READ_BUS_ERROR)) == + (MALI_MMU_INTERRUPT_PAGE_FAULT|MALI_MMU_INTERRUPT_READ_BUS_ERROR)) + { + return _MALI_OSK_ERR_OK; + } + + return _MALI_OSK_ERR_FAULT; +} + +#if 0 +void mali_mmu_print_state(struct mali_mmu_core *mmu) +{ + MALI_DEBUG_PRINT(2, ("MMU: State of %s is 0x%08x\n", mmu->hw_core.description, mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS))); +} +#endif diff --git a/drivers/media/video/samsung/mali/common/mali_mmu.h b/drivers/media/video/samsung/mali/common/mali_mmu.h new file mode 100644 index 0000000..c7274b8 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_mmu.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_MMU_H__ +#define __MALI_MMU_H__ + +#include "mali_osk.h" +#include "mali_mmu_page_directory.h" + +/* Forward declaration from mali_group.h */ +struct mali_group; + +struct mali_mmu_core; + +_mali_osk_errcode_t mali_mmu_initialize(void); + +void mali_mmu_terminate(void); + +struct mali_mmu_core *mali_mmu_create(_mali_osk_resource_t *resource); +void mali_mmu_set_group(struct mali_mmu_core *mmu, struct mali_group *group); +void mali_mmu_delete(struct mali_mmu_core *mmu); + +_mali_osk_errcode_t mali_mmu_reset(struct mali_mmu_core *mmu); +mali_bool mali_mmu_zap_tlb(struct mali_mmu_core *mmu); +void mali_mmu_zap_tlb_without_stall(struct mali_mmu_core *mmu); +void mali_mmu_invalidate_page(struct mali_mmu_core *mmu, u32 mali_address); + +mali_bool mali_mmu_activate_page_directory(struct mali_mmu_core* mmu, struct mali_page_directory *pagedir); +void mali_mmu_activate_empty_page_directory(struct mali_mmu_core* mmu); +void mali_mmu_activate_fault_flush_page_directory(struct mali_mmu_core* mmu); + +/** + * Issues the enable stall command to the MMU and waits for HW to complete the request + * @param mmu The MMU to enable paging for + * @return MALI_TRUE if HW stall was successfully engaged, otherwise MALI_FALSE (req timed out) + */ +mali_bool mali_mmu_enable_stall(struct mali_mmu_core *mmu); + +/** + * Issues the disable stall command to the MMU and waits for HW to complete the request + * @param mmu The MMU to enable paging for + */ +void mali_mmu_disable_stall(struct mali_mmu_core *mmu); + +void mali_mmu_page_fault_done(struct mali_mmu_core *mmu); + + +#endif /* __MALI_MMU_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.c b/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.c new file mode 100644 index 0000000..cc91ae9 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.c @@ -0,0 +1,475 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_kernel_common.h" +#include "mali_kernel_core.h" +#include "mali_osk.h" +#include "mali_uk_types.h" +#include "mali_mmu_page_directory.h" +#include "mali_memory.h" + +#include "mali_cluster.h" +#include "mali_group.h" + +static _mali_osk_errcode_t fill_page(mali_io_address mapping, u32 data); + +u32 mali_allocate_empty_page(void) +{ + _mali_osk_errcode_t err; + mali_io_address mapping; + u32 address; + + if(_MALI_OSK_ERR_OK != mali_mmu_get_table_page(&address, &mapping)) + { + /* Allocation failed */ + return 0; + } + + MALI_DEBUG_ASSERT_POINTER( mapping ); + + err = fill_page(mapping, 0); + if (_MALI_OSK_ERR_OK != err) + { + mali_mmu_release_table_page(address); + } + return address; +} + +void mali_free_empty_page(u32 address) +{ + if (MALI_INVALID_PAGE != address) + { + mali_mmu_release_table_page(address); + } +} + +_mali_osk_errcode_t mali_create_fault_flush_pages(u32 *page_directory, u32 *page_table, u32 *data_page) +{ + _mali_osk_errcode_t err; + mali_io_address page_directory_mapping; + mali_io_address page_table_mapping; + mali_io_address data_page_mapping; + + err = mali_mmu_get_table_page(data_page, &data_page_mapping); + if (_MALI_OSK_ERR_OK == err) + { + err = mali_mmu_get_table_page(page_table, &page_table_mapping); + if (_MALI_OSK_ERR_OK == err) + { + err = mali_mmu_get_table_page(page_directory, &page_directory_mapping); + if (_MALI_OSK_ERR_OK == err) + { + fill_page(data_page_mapping, 0); + fill_page(page_table_mapping, *data_page | MALI_MMU_FLAGS_WRITE_PERMISSION | MALI_MMU_FLAGS_READ_PERMISSION | MALI_MMU_FLAGS_PRESENT); + fill_page(page_directory_mapping, *page_table | MALI_MMU_FLAGS_PRESENT); + MALI_SUCCESS; + } + mali_mmu_release_table_page(*page_table); + *page_table = MALI_INVALID_PAGE; + } + mali_mmu_release_table_page(*data_page); + *data_page = MALI_INVALID_PAGE; + } + return err; +} + +void mali_destroy_fault_flush_pages(u32 *page_directory, u32 *page_table, u32 *data_page) +{ + if (MALI_INVALID_PAGE != *page_directory) + { + mali_mmu_release_table_page(*page_directory); + *page_directory = MALI_INVALID_PAGE; + } + + if (MALI_INVALID_PAGE != *page_table) + { + mali_mmu_release_table_page(*page_table); + *page_table = MALI_INVALID_PAGE; + } + + if (MALI_INVALID_PAGE != *data_page) + { + mali_mmu_release_table_page(*data_page); + *data_page = MALI_INVALID_PAGE; + } +} + +static _mali_osk_errcode_t fill_page(mali_io_address mapping, u32 data) +{ + int i; + MALI_DEBUG_ASSERT_POINTER( mapping ); + + for(i = 0; i < MALI_MMU_PAGE_SIZE/4; i++) + { + _mali_osk_mem_iowrite32_relaxed( mapping, i * sizeof(u32), data); + } + _mali_osk_mem_barrier(); + MALI_SUCCESS; +} + +_mali_osk_errcode_t mali_mmu_pagedir_map(struct mali_page_directory *pagedir, u32 mali_address, u32 size) +{ + const int first_pde = MALI_MMU_PDE_ENTRY(mali_address); + const int last_pde = MALI_MMU_PDE_ENTRY(mali_address + size - 1); + _mali_osk_errcode_t err; + mali_io_address pde_mapping; + u32 pde_phys; + int i; + + for(i = first_pde; i <= last_pde; i++) + { + if(0 == (_mali_osk_mem_ioread32(pagedir->page_directory_mapped, i*sizeof(u32)) & MALI_MMU_FLAGS_PRESENT)) + { + /* Page table not present */ + MALI_DEBUG_ASSERT(0 == pagedir->page_entries_usage_count[i]); + MALI_DEBUG_ASSERT(NULL == pagedir->page_entries_mapped[i]); + + err = mali_mmu_get_table_page(&pde_phys, &pde_mapping); + if(_MALI_OSK_ERR_OK != err) + { + MALI_PRINT_ERROR(("Failed to allocate page table page.\n")); + return err; + } + pagedir->page_entries_mapped[i] = pde_mapping; + + /* Update PDE, mark as present */ + _mali_osk_mem_iowrite32_relaxed(pagedir->page_directory_mapped, i*sizeof(u32), + pde_phys | MALI_MMU_FLAGS_PRESENT); + + MALI_DEBUG_ASSERT(0 == pagedir->page_entries_usage_count[i]); + pagedir->page_entries_usage_count[i] = 1; + } + else + { + pagedir->page_entries_usage_count[i]++; + } + } + _mali_osk_write_mem_barrier(); + + MALI_SUCCESS; +} + +MALI_STATIC_INLINE void mali_mmu_zero_pte(mali_io_address page_table, u32 mali_address, u32 size) +{ + int i; + const int first_pte = MALI_MMU_PTE_ENTRY(mali_address); + const int last_pte = MALI_MMU_PTE_ENTRY(mali_address + size - 1); + + for (i = first_pte; i <= last_pte; i++) + { + _mali_osk_mem_iowrite32_relaxed(page_table, i * sizeof(u32), 0); + } +} + +_mali_osk_errcode_t mali_mmu_pagedir_unmap(struct mali_page_directory *pagedir, u32 mali_address, u32 size) +{ + const int first_pde = MALI_MMU_PDE_ENTRY(mali_address); + const int last_pde = MALI_MMU_PDE_ENTRY(mali_address + size - 1); + u32 left = size; + int i; +#ifndef MALI_UNMAP_FLUSH_ALL_MALI_L2 + mali_bool pd_changed = MALI_FALSE; + u32 pages_to_invalidate[3]; /* hard-coded to 3: max two pages from the PT level plus max one page from PD level */ + u32 num_pages_inv = 0; +#endif + + /* For all page directory entries in range. */ + for (i = first_pde; i <= last_pde; i++) + { + u32 size_in_pde, offset; + + MALI_DEBUG_ASSERT_POINTER(pagedir->page_entries_mapped[i]); + MALI_DEBUG_ASSERT(0 != pagedir->page_entries_usage_count[i]); + + /* Offset into page table, 0 if mali_address is 4MiB aligned */ + offset = (mali_address & (MALI_MMU_VIRTUAL_PAGE_SIZE - 1)); + if (left < MALI_MMU_VIRTUAL_PAGE_SIZE - offset) + { + size_in_pde = left; + } + else + { + size_in_pde = MALI_MMU_VIRTUAL_PAGE_SIZE - offset; + } + + pagedir->page_entries_usage_count[i]--; + + /* If entire page table is unused, free it */ + if (0 == pagedir->page_entries_usage_count[i]) + { + u32 page_address; + MALI_DEBUG_PRINT(4, ("Releasing page table as this is the last reference\n")); + /* last reference removed, no need to zero out each PTE */ + + page_address = MALI_MMU_ENTRY_ADDRESS(_mali_osk_mem_ioread32(pagedir->page_directory_mapped, i*sizeof(u32))); + pagedir->page_entries_mapped[i] = NULL; + _mali_osk_mem_iowrite32_relaxed(pagedir->page_directory_mapped, i*sizeof(u32), 0); + + mali_mmu_release_table_page(page_address); +#ifndef MALI_UNMAP_FLUSH_ALL_MALI_L2 + pd_changed = MALI_TRUE; +#endif + } + else + { +#ifndef MALI_UNMAP_FLUSH_ALL_MALI_L2 + pages_to_invalidate[num_pages_inv] = mali_page_directory_get_phys_address(pagedir, i); + num_pages_inv++; + MALI_DEBUG_ASSERT(num_pages_inv<3); +#endif + + /* If part of the page table is still in use, zero the relevant PTEs */ + mali_mmu_zero_pte(pagedir->page_entries_mapped[i], mali_address, size_in_pde); + } + + left -= size_in_pde; + mali_address += size_in_pde; + } + _mali_osk_write_mem_barrier(); + +#ifndef MALI_UNMAP_FLUSH_ALL_MALI_L2 + /* L2 pages invalidation */ + if (MALI_TRUE == pd_changed) + { + pages_to_invalidate[num_pages_inv] = pagedir->page_directory; + num_pages_inv++; + MALI_DEBUG_ASSERT(num_pages_inv<3); + } + + if (_MALI_PRODUCT_ID_MALI200 != mali_kernel_core_get_product_id()) + { + mali_cluster_invalidate_pages(pages_to_invalidate, num_pages_inv); + } +#endif + + MALI_SUCCESS; +} + +struct mali_page_directory *mali_mmu_pagedir_alloc(void) +{ + struct mali_page_directory *pagedir; + + pagedir = _mali_osk_calloc(1, sizeof(struct mali_page_directory)); + if(NULL == pagedir) + { + return NULL; + } + + if(_MALI_OSK_ERR_OK != mali_mmu_get_table_page(&pagedir->page_directory, &pagedir->page_directory_mapped)) + { + _mali_osk_free(pagedir); + return NULL; + } + + /* Zero page directory */ + fill_page(pagedir->page_directory_mapped, 0); + + return pagedir; +} + +void mali_mmu_pagedir_free(struct mali_page_directory *pagedir) +{ + const int num_page_table_entries = sizeof(pagedir->page_entries_mapped) / sizeof(pagedir->page_entries_mapped[0]); + int i; + + /* Free referenced page tables and zero PDEs. */ + for (i = 0; i < num_page_table_entries; i++) + { + if (pagedir->page_directory_mapped && (_mali_osk_mem_ioread32(pagedir->page_directory_mapped, sizeof(u32)*i) & MALI_MMU_FLAGS_PRESENT)) + { + mali_mmu_release_table_page( _mali_osk_mem_ioread32(pagedir->page_directory_mapped, i*sizeof(u32)) & ~MALI_MMU_FLAGS_MASK); + _mali_osk_mem_iowrite32_relaxed(pagedir->page_directory_mapped, i * sizeof(u32), 0); + } + } + _mali_osk_write_mem_barrier(); + + /* Free the page directory page. */ + mali_mmu_release_table_page(pagedir->page_directory); + + _mali_osk_free(pagedir); +} + + +void mali_mmu_pagedir_update(struct mali_page_directory *pagedir, u32 mali_address, u32 phys_address, u32 size, mali_memory_cache_settings cache_settings) +{ + u32 end_address = mali_address + size; + u32 permission_bits; + + switch ( cache_settings ) + { + case MALI_CACHE_GP_READ_ALLOCATE: + MALI_DEBUG_PRINT(3, ("Map L2 GP_Read_allocate\n")); + permission_bits = MALI_MMU_FLAGS_FORCE_GP_READ_ALLOCATE; + break; + + case MALI_CACHE_STANDARD: + MALI_DEBUG_PRINT(3, ("Map L2 Standard\n")); + /*falltrough */ + default: + if ( MALI_CACHE_STANDARD != cache_settings) MALI_PRINT_ERROR(("Wrong cache settings\n")); + permission_bits = MALI_MMU_FLAGS_WRITE_PERMISSION | MALI_MMU_FLAGS_READ_PERMISSION | MALI_MMU_FLAGS_PRESENT; + } + + /* Map physical pages into MMU page tables */ + for ( ; mali_address < end_address; mali_address += MALI_MMU_PAGE_SIZE, phys_address += MALI_MMU_PAGE_SIZE) + { + MALI_DEBUG_ASSERT_POINTER(pagedir->page_entries_mapped[MALI_MMU_PDE_ENTRY(mali_address)]); + _mali_osk_mem_iowrite32_relaxed(pagedir->page_entries_mapped[MALI_MMU_PDE_ENTRY(mali_address)], + MALI_MMU_PTE_ENTRY(mali_address) * sizeof(u32), + phys_address | permission_bits); + } + _mali_osk_write_mem_barrier(); +} + +u32 mali_page_directory_get_phys_address(struct mali_page_directory *pagedir, u32 index) +{ + return (_mali_osk_mem_ioread32(pagedir->page_directory_mapped, index*sizeof(u32)) & ~MALI_MMU_FLAGS_MASK); +} + +/* For instrumented */ +struct dump_info +{ + u32 buffer_left; + u32 register_writes_size; + u32 page_table_dump_size; + u32 *buffer; +}; + +static _mali_osk_errcode_t writereg(u32 where, u32 what, const char *comment, struct dump_info *info) +{ + if (NULL != info) + { + info->register_writes_size += sizeof(u32)*2; /* two 32-bit words */ + + if (NULL != info->buffer) + { + /* check that we have enough space */ + if (info->buffer_left < sizeof(u32)*2) MALI_ERROR(_MALI_OSK_ERR_NOMEM); + + *info->buffer = where; + info->buffer++; + + *info->buffer = what; + info->buffer++; + + info->buffer_left -= sizeof(u32)*2; + } + } + + MALI_SUCCESS; +} + +static _mali_osk_errcode_t dump_page(mali_io_address page, u32 phys_addr, struct dump_info * info) +{ + if (NULL != info) + { + /* 4096 for the page and 4 bytes for the address */ + const u32 page_size_in_elements = MALI_MMU_PAGE_SIZE / 4; + const u32 page_size_in_bytes = MALI_MMU_PAGE_SIZE; + const u32 dump_size_in_bytes = MALI_MMU_PAGE_SIZE + 4; + + info->page_table_dump_size += dump_size_in_bytes; + + if (NULL != info->buffer) + { + if (info->buffer_left < dump_size_in_bytes) MALI_ERROR(_MALI_OSK_ERR_NOMEM); + + *info->buffer = phys_addr; + info->buffer++; + + _mali_osk_memcpy(info->buffer, page, page_size_in_bytes); + info->buffer += page_size_in_elements; + + info->buffer_left -= dump_size_in_bytes; + } + } + + MALI_SUCCESS; +} + +static _mali_osk_errcode_t dump_mmu_page_table(struct mali_page_directory *pagedir, struct dump_info * info) +{ + MALI_DEBUG_ASSERT_POINTER(pagedir); + MALI_DEBUG_ASSERT_POINTER(info); + + if (NULL != pagedir->page_directory_mapped) + { + int i; + + MALI_CHECK_NO_ERROR( + dump_page(pagedir->page_directory_mapped, pagedir->page_directory, info) + ); + + for (i = 0; i < 1024; i++) + { + if (NULL != pagedir->page_entries_mapped[i]) + { + MALI_CHECK_NO_ERROR( + dump_page(pagedir->page_entries_mapped[i], + _mali_osk_mem_ioread32(pagedir->page_directory_mapped, + i * sizeof(u32)) & ~MALI_MMU_FLAGS_MASK, info) + ); + } + } + } + + MALI_SUCCESS; +} + +static _mali_osk_errcode_t dump_mmu_registers(struct mali_page_directory *pagedir, struct dump_info * info) +{ + MALI_CHECK_NO_ERROR(writereg(0x00000000, pagedir->page_directory, + "set the page directory address", info)); + MALI_CHECK_NO_ERROR(writereg(0x00000008, 4, "zap???", info)); + MALI_CHECK_NO_ERROR(writereg(0x00000008, 0, "enable paging", info)); + MALI_SUCCESS; +} + +_mali_osk_errcode_t _mali_ukk_query_mmu_page_table_dump_size( _mali_uk_query_mmu_page_table_dump_size_s *args ) +{ + struct dump_info info = { 0, 0, 0, NULL }; + struct mali_session_data * session_data; + + MALI_DEBUG_ASSERT_POINTER(args); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + + session_data = (struct mali_session_data *)(args->ctx); + + MALI_CHECK_NO_ERROR(dump_mmu_registers(session_data->page_directory, &info)); + MALI_CHECK_NO_ERROR(dump_mmu_page_table(session_data->page_directory, &info)); + args->size = info.register_writes_size + info.page_table_dump_size; + MALI_SUCCESS; +} + +_mali_osk_errcode_t _mali_ukk_dump_mmu_page_table( _mali_uk_dump_mmu_page_table_s * args ) +{ + struct dump_info info = { 0, 0, 0, NULL }; + struct mali_session_data * session_data; + + MALI_DEBUG_ASSERT_POINTER(args); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + MALI_CHECK_NON_NULL(args->buffer, _MALI_OSK_ERR_INVALID_ARGS); + + session_data = (struct mali_session_data *)(args->ctx); + + info.buffer_left = args->size; + info.buffer = args->buffer; + + args->register_writes = info.buffer; + MALI_CHECK_NO_ERROR(dump_mmu_registers(session_data->page_directory, &info)); + + args->page_table_dump = info.buffer; + MALI_CHECK_NO_ERROR(dump_mmu_page_table(session_data->page_directory, &info)); + + args->register_writes_size = info.register_writes_size; + args->page_table_dump_size = info.page_table_dump_size; + + MALI_SUCCESS; +} diff --git a/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.h b/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.h new file mode 100644 index 0000000..628833a --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_MMU_PAGE_DIRECTORY_H__ +#define __MALI_MMU_PAGE_DIRECTORY_H__ + +#include "mali_osk.h" + +/** + * Size of an MMU page in bytes + */ +#define MALI_MMU_PAGE_SIZE 0x1000 + +/* + * Size of the address space referenced by a page table page + */ +#define MALI_MMU_VIRTUAL_PAGE_SIZE 0x400000 /* 4 MiB */ + +/** + * Page directory index from address + * Calculates the page directory index from the given address + */ +#define MALI_MMU_PDE_ENTRY(address) (((address)>>22) & 0x03FF) + +/** + * Page table index from address + * Calculates the page table index from the given address + */ +#define MALI_MMU_PTE_ENTRY(address) (((address)>>12) & 0x03FF) + +/** + * Extract the memory address from an PDE/PTE entry + */ +#define MALI_MMU_ENTRY_ADDRESS(value) ((value) & 0xFFFFFC00) + +#define MALI_INVALID_PAGE ((u32)(~0)) + +/** + * + */ +typedef enum mali_mmu_entry_flags +{ + MALI_MMU_FLAGS_PRESENT = 0x01, + MALI_MMU_FLAGS_READ_PERMISSION = 0x02, + MALI_MMU_FLAGS_WRITE_PERMISSION = 0x04, + MALI_MMU_FLAGS_OVERRIDE_CACHE = 0x8, + MALI_MMU_FLAGS_WRITE_CACHEABLE = 0x10, + MALI_MMU_FLAGS_WRITE_ALLOCATE = 0x20, + MALI_MMU_FLAGS_WRITE_BUFFERABLE = 0x40, + MALI_MMU_FLAGS_READ_CACHEABLE = 0x80, + MALI_MMU_FLAGS_READ_ALLOCATE = 0x100, + MALI_MMU_FLAGS_MASK = 0x1FF, +} mali_mmu_entry_flags; + + +#define MALI_MMU_FLAGS_FORCE_GP_READ_ALLOCATE ( \ +MALI_MMU_FLAGS_PRESENT | \ + MALI_MMU_FLAGS_READ_PERMISSION | \ + MALI_MMU_FLAGS_WRITE_PERMISSION | \ + MALI_MMU_FLAGS_OVERRIDE_CACHE | \ + MALI_MMU_FLAGS_WRITE_CACHEABLE | \ + MALI_MMU_FLAGS_WRITE_BUFFERABLE | \ + MALI_MMU_FLAGS_READ_CACHEABLE | \ + MALI_MMU_FLAGS_READ_ALLOCATE ) + + +struct mali_page_directory +{ + u32 page_directory; /**< Physical address of the memory session's page directory */ + mali_io_address page_directory_mapped; /**< Pointer to the mapped version of the page directory into the kernel's address space */ + + mali_io_address page_entries_mapped[1024]; /**< Pointers to the page tables which exists in the page directory mapped into the kernel's address space */ + u32 page_entries_usage_count[1024]; /**< Tracks usage count of the page table pages, so they can be releases on the last reference */ +}; + +/* Map Mali virtual address space (i.e. ensure page tables exist for the virtual range) */ +_mali_osk_errcode_t mali_mmu_pagedir_map(struct mali_page_directory *pagedir, u32 mali_address, u32 size); +_mali_osk_errcode_t mali_mmu_pagedir_unmap(struct mali_page_directory *pagedir, u32 mali_address, u32 size); + +/* Back virtual address space with actual pages. Assumes input is contiguous and 4k aligned. */ +void mali_mmu_pagedir_update(struct mali_page_directory *pagedir, u32 mali_address, u32 phys_address, u32 size, u32 cache_settings); + +u32 mali_page_directory_get_phys_address(struct mali_page_directory *pagedir, u32 index); + +u32 mali_allocate_empty_page(void); +void mali_free_empty_page(u32 address); +_mali_osk_errcode_t mali_create_fault_flush_pages(u32 *page_directory, u32 *page_table, u32 *data_page); +void mali_destroy_fault_flush_pages(u32 *page_directory, u32 *page_table, u32 *data_page); + +struct mali_page_directory *mali_mmu_pagedir_alloc(void); +void mali_mmu_pagedir_free(struct mali_page_directory *pagedir); + +#endif /* __MALI_MMU_PAGE_DIRECTORY_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_osk.h b/drivers/media/video/samsung/mali/common/mali_osk.h new file mode 100644 index 0000000..e32d15d --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_osk.h @@ -0,0 +1,1798 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk.h + * Defines the OS abstraction layer for the kernel device driver (OSK) + */ + +#ifndef __MALI_OSK_H__ +#define __MALI_OSK_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @addtogroup uddapi Unified Device Driver (UDD) APIs + * + * @{ + */ + +/** + * @addtogroup oskapi UDD OS Abstraction for Kernel-side (OSK) APIs + * + * @{ + */ + +/** @defgroup _mali_osk_miscellaneous OSK Miscellaneous functions, constants and types + * @{ */ + +/* Define integer types used by OSK. Note: these currently clash with Linux so we only define them if not defined already */ +#ifndef __KERNEL__ + typedef unsigned char u8; + typedef signed char s8; + typedef unsigned short u16; + typedef signed short s16; + typedef unsigned int u32; + typedef signed int s32; + typedef unsigned long long u64; + #define BITS_PER_LONG (sizeof(long)*8) +#else + /* Ensure Linux types u32, etc. are defined */ + #include +#endif + +/** @brief Mali Boolean type which uses MALI_TRUE and MALI_FALSE + */ + typedef unsigned long mali_bool; + +#ifndef MALI_TRUE + #define MALI_TRUE ((mali_bool)1) +#endif + +#ifndef MALI_FALSE + #define MALI_FALSE ((mali_bool)0) +#endif + +/** + * @brief OSK Error codes + * + * Each OS may use its own set of error codes, and may require that the + * User/Kernel interface take certain error code. This means that the common + * error codes need to be sufficiently rich to pass the correct error code + * thorugh from the OSK to U/K layer, across all OSs. + * + * The result is that some error codes will appear redundant on some OSs. + * Under all OSs, the OSK layer must translate native OS error codes to + * _mali_osk_errcode_t codes. Similarly, the U/K layer must translate from + * _mali_osk_errcode_t codes to native OS error codes. + */ +typedef enum +{ + _MALI_OSK_ERR_OK = 0, /**< Success. */ + _MALI_OSK_ERR_FAULT = -1, /**< General non-success */ + _MALI_OSK_ERR_INVALID_FUNC = -2, /**< Invalid function requested through User/Kernel interface (e.g. bad IOCTL number) */ + _MALI_OSK_ERR_INVALID_ARGS = -3, /**< Invalid arguments passed through User/Kernel interface */ + _MALI_OSK_ERR_NOMEM = -4, /**< Insufficient memory */ + _MALI_OSK_ERR_TIMEOUT = -5, /**< Timeout occurred */ + _MALI_OSK_ERR_RESTARTSYSCALL = -6, /**< Special: On certain OSs, must report when an interruptable mutex is interrupted. Ignore otherwise. */ + _MALI_OSK_ERR_ITEM_NOT_FOUND = -7, /**< Table Lookup failed */ + _MALI_OSK_ERR_BUSY = -8, /**< Device/operation is busy. Try again later */ + _MALI_OSK_ERR_UNSUPPORTED = -9, /**< Optional part of the interface used, and is unsupported */ +} _mali_osk_errcode_t; + +/** @} */ /* end group _mali_osk_miscellaneous */ + + +/** @defgroup _mali_osk_irq OSK IRQ handling + * @{ */ + +/** @brief Private type for IRQ handling objects */ +typedef struct _mali_osk_irq_t_struct _mali_osk_irq_t; + +/** @brief Optional function to trigger an irq from a resource + * + * This function is implemented by the common layer to allow probing of a resource's IRQ. + * @param arg resource-specific data */ +typedef void (*_mali_osk_irq_trigger_t)( void * arg ); + +/** @brief Optional function to acknowledge an irq from a resource + * + * This function is implemented by the common layer to allow probing of a resource's IRQ. + * @param arg resource-specific data + * @return _MALI_OSK_ERR_OK if the IRQ was successful, or a suitable _mali_osk_errcode_t on failure. */ +typedef _mali_osk_errcode_t (*_mali_osk_irq_ack_t)( void * arg ); + +/** @brief IRQ 'upper-half' handler callback. + * + * This function is implemented by the common layer to do the initial handling of a + * resource's IRQ. This maps on to the concept of an ISR that does the minimum + * work necessary before handing off to an IST. + * + * The communication of the resource-specific data from the ISR to the IST is + * handled by the OSK implementation. + * + * On most systems, the IRQ upper-half handler executes in IRQ context. + * Therefore, the system may have restrictions about what can be done in this + * context + * + * If an IRQ upper-half handler requires more work to be done than can be + * acheived in an IRQ context, then it may defer the work with + * _mali_osk_irq_schedulework(). Refer to \ref _mali_osk_irq_schedulework() for + * more information. + * + * @param arg resource-specific data + * @return _MALI_OSK_ERR_OK if the IRQ was correctly handled, or a suitable + * _mali_osk_errcode_t otherwise. + */ +typedef _mali_osk_errcode_t (*_mali_osk_irq_uhandler_t)( void * arg ); + +/** @brief IRQ 'bottom-half' handler callback. + * + * This function is implemented by the common layer to do the deferred handling + * of a resource's IRQ. Usually, this work cannot be carried out in IRQ context + * by the IRQ upper-half handler. + * + * The IRQ bottom-half handler maps on to the concept of an IST that may + * execute some time after the actual IRQ has fired. + * + * All OSK-registered IRQ bottom-half handlers will be serialized, across all + * CPU-cores in the system. + * + * Refer to \ref _mali_osk_irq_schedulework() for more information on the + * IRQ work-queue, and the calling of the IRQ bottom-half handler. + * + * @param arg resource-specific data + */ +typedef void (*_mali_osk_irq_bhandler_t)( void * arg ); +/** @} */ /* end group _mali_osk_irq */ + + +/** @defgroup _mali_osk_atomic OSK Atomic counters + * @{ */ + +/** @brief Public type of atomic counters + * + * This is public for allocation on stack. On systems that support it, this is just a single 32-bit value. + * On others, it could be encapsulating an object stored elsewhere. + * + * Regardless of implementation, the \ref _mali_osk_atomic functions \b must be used + * for all accesses to the variable's value, even if atomicity is not required. + * Do not access u.val or u.obj directly. + */ +typedef struct +{ + union + { + u32 val; + void *obj; + } u; +} _mali_osk_atomic_t; +/** @} */ /* end group _mali_osk_atomic */ + + +/** @defgroup _mali_osk_lock OSK Mutual Exclusion Locks + * @{ */ + + +/** @brief OSK Mutual Exclusion Lock ordered list + * + * This lists the various types of locks in the system and is used to check + * that locks are taken in the correct order. + * + * Holding more than one lock of the same order at the same time is not + * allowed. + * + */ +typedef enum +{ + _MALI_OSK_LOCK_ORDER_LAST = 0, + + _MALI_OSK_LOCK_ORDER_PM_EXECUTE, + _MALI_OSK_LOCK_ORDER_UTILIZATION, + _MALI_OSK_LOCK_ORDER_L2_COUNTER, + _MALI_OSK_LOCK_ORDER_PROFILING, + _MALI_OSK_LOCK_ORDER_L2_COMMAND, + _MALI_OSK_LOCK_ORDER_PM_CORE_STATE, + _MALI_OSK_LOCK_ORDER_GROUP, + _MALI_OSK_LOCK_ORDER_SCHEDULER, + + _MALI_OSK_LOCK_ORDER_DESCRIPTOR_MAP, + _MALI_OSK_LOCK_ORDER_MEM_PT_CACHE, + _MALI_OSK_LOCK_ORDER_MEM_INFO, + _MALI_OSK_LOCK_ORDER_MEM_SESSION, + + _MALI_OSK_LOCK_ORDER_SESSIONS, + + _MALI_OSK_LOCK_ORDER_FIRST +} _mali_osk_lock_order_t; + + +/** @brief OSK Mutual Exclusion Lock flags type + * + * Flags are supplied at the point where the Lock is initialized. Each flag can + * be combined with others using bitwise OR, '|'. + * + * The flags must be sufficiently rich to cope with all our OSs. This means + * that on some OSs, certain flags can be completely ignored. We define a + * number of terms that are significant across all OSs: + * + * - Sleeping/non-sleeping mutexs. Sleeping mutexs can block on waiting, and so + * schedule out the current thread. This is significant on OSs where there are + * situations in which the current thread must not be put to sleep. On OSs + * without this restriction, sleeping and non-sleeping mutexes can be treated + * as the same (if that is required). + * - Interruptable/non-interruptable mutexes. For sleeping mutexes, it may be + * possible for the sleep to be interrupted for a reason other than the thread + * being able to obtain the lock. OSs behaving in this way may provide a + * mechanism to control whether sleeping mutexes can be interrupted. On OSs + * that do not support the concept of interruption, \b or they do not support + * control of mutex interruption, then interruptable mutexes may be treated + * as non-interruptable. + * + * Some constrains apply to the lock type flags: + * + * - Spinlocks are by nature, non-interruptable. Hence, they must always be + * combined with the NONINTERRUPTABLE flag, because it is meaningless to ask + * for a spinlock that is interruptable (and this highlights its + * non-interruptable-ness). For example, on certain OSs they should be used when + * you must not sleep. + * - Reader/writer is an optimization hint, and any type of lock can be + * reader/writer. Since this is an optimization hint, the implementation need + * not respect this for any/all types of lock. For example, on certain OSs, + * there's no interruptable reader/writer mutex. If such a thing were requested + * on that OS, the fact that interruptable was requested takes priority over the + * reader/writer-ness, because reader/writer-ness is not necessary for correct + * operation. + * - Any lock can use the order parameter. + * - A onelock is an optimization hint specific to certain OSs. It can be + * specified when it is known that only one lock will be held by the thread, + * and so can provide faster mutual exclusion. This can be safely ignored if + * such optimization is not required/present. + * + * The absence of any flags (the value 0) results in a sleeping-mutex, which is interruptable. + */ +typedef enum +{ + _MALI_OSK_LOCKFLAG_SPINLOCK = 0x1, /**< Specifically, don't sleep on those architectures that require it */ + _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE = 0x2, /**< The mutex cannot be interrupted, e.g. delivery of signals on those architectures where this is required */ + _MALI_OSK_LOCKFLAG_READERWRITER = 0x4, /**< Optimise for readers/writers */ + _MALI_OSK_LOCKFLAG_ORDERED = 0x8, /**< Use the order parameter; otherwise use automatic ordering */ + _MALI_OSK_LOCKFLAG_ONELOCK = 0x10, /**< Each thread can only hold one lock at a time */ + _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ = 0x20, /**< IRQ version of spinlock */ + /** @enum _mali_osk_lock_flags_t + * + * Flags from 0x10000--0x80000000 are RESERVED for User-mode */ + +} _mali_osk_lock_flags_t; + +/** @brief Mutual Exclusion Lock Mode Optimization hint + * + * The lock mode is used to implement the read/write locking of locks specified + * as _MALI_OSK_LOCKFLAG_READERWRITER. In this case, the RO mode can be used + * to allow multiple concurrent readers, but no writers. The RW mode is used for + * writers, and so will wait for all readers to release the lock (if any present). + * Further readers and writers will wait until the writer releases the lock. + * + * The mode is purely an optimization hint: for example, it is permissible for + * all locks to behave in RW mode, regardless of that supplied. + * + * It is an error to attempt to use locks in anything other that RW mode when + * _MALI_OSK_LOCKFLAG_READERWRITER is not supplied. + * + */ +typedef enum +{ + _MALI_OSK_LOCKMODE_UNDEF = -1, /**< Undefined lock mode. For internal use only */ + _MALI_OSK_LOCKMODE_RW = 0x0, /**< Read-write mode, default. All readers and writers are mutually-exclusive */ + _MALI_OSK_LOCKMODE_RO, /**< Read-only mode, to support multiple concurrent readers, but mutual exclusion in the presence of writers. */ + /** @enum _mali_osk_lock_mode_t + * + * Lock modes 0x40--0x7F are RESERVED for User-mode */ +} _mali_osk_lock_mode_t; + +/** @brief Private type for Mutual Exclusion lock objects */ +typedef struct _mali_osk_lock_t_struct _mali_osk_lock_t; + +#ifdef DEBUG +/** @brief Macro for asserting that the current thread holds a given lock + */ +#define MALI_DEBUG_ASSERT_LOCK_HELD(l) MALI_DEBUG_ASSERT(_mali_osk_lock_get_owner(l) == _mali_osk_get_tid()); + +/** @brief returns a lock's owner (thread id) if debugging is enabled + */ +u32 _mali_osk_lock_get_owner( _mali_osk_lock_t *lock ); +#endif + +/** @} */ /* end group _mali_osk_lock */ + +/** @defgroup _mali_osk_low_level_memory OSK Low-level Memory Operations + * @{ */ + +/** + * @brief Private data type for use in IO accesses to/from devices. + * + * This represents some range that is accessible from the device. Examples + * include: + * - Device Registers, which could be readable and/or writeable. + * - Memory that the device has access to, for storing configuration structures. + * + * Access to this range must be made through the _mali_osk_mem_ioread32() and + * _mali_osk_mem_iowrite32() functions. + */ +typedef struct _mali_io_address * mali_io_address; + +/** @defgroup _MALI_OSK_CPU_PAGE CPU Physical page size macros. + * + * The order of the page size is supplied for + * ease of use by algorithms that might require it, since it is easier to know + * it ahead of time rather than calculating it. + * + * The Mali Page Mask macro masks off the lower bits of a physical address to + * give the start address of the page for that physical address. + * + * @note The Mali device driver code is designed for systems with 4KB page size. + * Changing these macros will not make the entire Mali device driver work with + * page sizes other than 4KB. + * + * @note The CPU Physical Page Size has been assumed to be the same as the Mali + * Physical Page Size. + * + * @{ + */ + +/** CPU Page Order, as log to base 2 of the Page size. @see _MALI_OSK_CPU_PAGE_SIZE */ +#define _MALI_OSK_CPU_PAGE_ORDER ((u32)12) +/** CPU Page Size, in bytes. */ +#define _MALI_OSK_CPU_PAGE_SIZE (((u32)1) << (_MALI_OSK_CPU_PAGE_ORDER)) +/** CPU Page Mask, which masks off the offset within a page */ +#define _MALI_OSK_CPU_PAGE_MASK (~((((u32)1) << (_MALI_OSK_CPU_PAGE_ORDER)) - ((u32)1))) +/** @} */ /* end of group _MALI_OSK_CPU_PAGE */ + +/** @defgroup _MALI_OSK_MALI_PAGE Mali Physical Page size macros + * + * Mali Physical page size macros. The order of the page size is supplied for + * ease of use by algorithms that might require it, since it is easier to know + * it ahead of time rather than calculating it. + * + * The Mali Page Mask macro masks off the lower bits of a physical address to + * give the start address of the page for that physical address. + * + * @note The Mali device driver code is designed for systems with 4KB page size. + * Changing these macros will not make the entire Mali device driver work with + * page sizes other than 4KB. + * + * @note The Mali Physical Page Size has been assumed to be the same as the CPU + * Physical Page Size. + * + * @{ + */ + +/** Mali Page Order, as log to base 2 of the Page size. @see _MALI_OSK_MALI_PAGE_SIZE */ +#define _MALI_OSK_MALI_PAGE_ORDER ((u32)12) +/** Mali Page Size, in bytes. */ +#define _MALI_OSK_MALI_PAGE_SIZE (((u32)1) << (_MALI_OSK_MALI_PAGE_ORDER)) +/** Mali Page Mask, which masks off the offset within a page */ +#define _MALI_OSK_MALI_PAGE_MASK (~((((u32)1) << (_MALI_OSK_MALI_PAGE_ORDER)) - ((u32)1))) +/** @} */ /* end of group _MALI_OSK_MALI_PAGE*/ + +/** @brief flags for mapping a user-accessible memory range + * + * Where a function with prefix '_mali_osk_mem_mapregion' accepts flags as one + * of the function parameters, it will use one of these. These allow per-page + * control over mappings. Compare with the mali_memory_allocation_flag type, + * which acts over an entire range + * + * These may be OR'd together with bitwise OR (|), but must be cast back into + * the type after OR'ing. + */ +typedef enum +{ + _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR = 0x1, /**< Physical address is OS Allocated */ +} _mali_osk_mem_mapregion_flags_t; +/** @} */ /* end group _mali_osk_low_level_memory */ + +/** @defgroup _mali_osk_notification OSK Notification Queues + * @{ */ + +/** @brief Private type for notification queue objects */ +typedef struct _mali_osk_notification_queue_t_struct _mali_osk_notification_queue_t; + +/** @brief Public notification data object type */ +typedef struct _mali_osk_notification_t_struct +{ + u32 notification_type; /**< The notification type */ + u32 result_buffer_size; /**< Size of the result buffer to copy to user space */ + void * result_buffer; /**< Buffer containing any type specific data */ +} _mali_osk_notification_t; + +/** @} */ /* end group _mali_osk_notification */ + + +/** @defgroup _mali_osk_timer OSK Timer Callbacks + * @{ */ + +/** @brief Function to call when a timer expires + * + * When a timer expires, this function is called. Note that on many systems, + * a timer callback will be executed in IRQ context. Therefore, restrictions + * may apply on what can be done inside the timer callback. + * + * If a timer requires more work to be done than can be acheived in an IRQ + * context, then it may defer the work with a work-queue. For example, it may + * use \ref _mali_osk_irq_schedulework() to make use of the IRQ bottom-half handler + * to carry out the remaining work. + * + * Stopping the timer with \ref _mali_osk_timer_del() blocks on compeletion of + * the callback. Therefore, the callback may not obtain any mutexes also held + * by any callers of _mali_osk_timer_del(). Otherwise, a deadlock may occur. + * + * @param arg Function-specific data */ +typedef void (*_mali_osk_timer_callback_t)(void * arg ); + +/** @brief Private type for Timer Callback Objects */ +typedef struct _mali_osk_timer_t_struct _mali_osk_timer_t; +/** @} */ /* end group _mali_osk_timer */ + + +/** @addtogroup _mali_osk_list OSK Doubly-Linked Circular Lists + * @{ */ + +/** @brief Public List objects. + * + * To use, add a _mali_osk_list_t member to the structure that may become part + * of a list. When traversing the _mali_osk_list_t objects, use the + * _MALI_OSK_CONTAINER_OF() macro to recover the structure from its + *_mali_osk_list_t member + * + * Each structure may have multiple _mali_osk_list_t members, so that the + * structure is part of multiple lists. When traversing lists, ensure that the + * correct _mali_osk_list_t member is used, because type-checking will be + * lost by the compiler. + */ +typedef struct _mali_osk_list_s +{ + struct _mali_osk_list_s *next; + struct _mali_osk_list_s *prev; +} _mali_osk_list_t; + +/** @brief Initialize a list to be a head of an empty list + * @param exp the list to initialize. */ +#define _MALI_OSK_INIT_LIST_HEAD(exp) _mali_osk_list_init(exp) + +/** @brief Define a list variable, which is uninitialized. + * @param exp the name of the variable that the list will be defined as. */ +#define _MALI_OSK_LIST_HEAD(exp) _mali_osk_list_t exp + +/** @brief Find the containing structure of another structure + * + * This is the reverse of the operation 'offsetof'. This means that the + * following condition is satisfied: + * + * ptr == _MALI_OSK_CONTAINER_OF( &ptr->member, type, member ) + * + * When ptr is of type 'type'. + * + * Its purpose it to recover a larger structure that has wrapped a smaller one. + * + * @note no type or memory checking occurs to ensure that a wrapper structure + * does in fact exist, and that it is being recovered with respect to the + * correct member. + * + * @param ptr the pointer to the member that is contained within the larger + * structure + * @param type the type of the structure that contains the member + * @param member the name of the member in the structure that ptr points to. + * @return a pointer to a \a type object which contains \a member, as pointed + * to by \a ptr. + */ +#define _MALI_OSK_CONTAINER_OF(ptr, type, member) \ + ((type *)( ((char *)ptr) - offsetof(type,member) )) + +/** @brief Find the containing structure of a list + * + * When traversing a list, this is used to recover the containing structure, + * given that is contains a _mali_osk_list_t member. + * + * Each list must be of structures of one type, and must link the same members + * together, otherwise it will not be possible to correctly recover the + * sturctures that the lists link. + * + * @note no type or memory checking occurs to ensure that a structure does in + * fact exist for the list entry, and that it is being recovered with respect + * to the correct list member. + * + * @param ptr the pointer to the _mali_osk_list_t member in this structure + * @param type the type of the structure that contains the member + * @param member the member of the structure that ptr points to. + * @return a pointer to a \a type object which contains the _mali_osk_list_t + * \a member, as pointed to by the _mali_osk_list_t \a *ptr. + */ +#define _MALI_OSK_LIST_ENTRY(ptr, type, member) \ + _MALI_OSK_CONTAINER_OF(ptr, type, member) + +/** @brief Enumerate a list safely + * + * With this macro, lists can be enumerated in a 'safe' manner. That is, + * entries can be deleted from the list without causing an error during + * enumeration. To achieve this, a 'temporary' pointer is required, which must + * be provided to the macro. + * + * Use it like a 'for()', 'while()' or 'do()' construct, and so it must be + * followed by a statement or compound-statement which will be executed for + * each list entry. + * + * Upon loop completion, providing that an early out was not taken in the + * loop body, then it is guaranteed that ptr->member == list, even if the loop + * body never executed. + * + * @param ptr a pointer to an object of type 'type', which points to the + * structure that contains the currently enumerated list entry. + * @param tmp a pointer to an object of type 'type', which must not be used + * inside the list-execution statement. + * @param list a pointer to a _mali_osk_list_t, from which enumeration will + * begin + * @param type the type of the structure that contains the _mali_osk_list_t + * member that is part of the list to be enumerated. + * @param member the _mali_osk_list_t member of the structure that is part of + * the list to be enumerated. + */ +#define _MALI_OSK_LIST_FOREACHENTRY(ptr, tmp, list, type, member) \ + for (ptr = _MALI_OSK_LIST_ENTRY((list)->next, type, member), \ + tmp = _MALI_OSK_LIST_ENTRY(ptr->member.next, type, member); \ + &ptr->member != (list); \ + ptr = tmp, tmp = _MALI_OSK_LIST_ENTRY(tmp->member.next, type, member)) +/** @} */ /* end group _mali_osk_list */ + + +/** @addtogroup _mali_osk_miscellaneous + * @{ */ + +/** @brief The known resource types + * + * @note \b IMPORTANT: these must remain fixed, and only be extended. This is + * because not all systems use a header file for reading in their resources. + * The resources may instead come from a data file where these resources are + * 'hard-coded' in, because there's no easy way of transferring the enum values + * into such data files. E.g. the C-Pre-processor does \em not process enums. + */ +typedef enum _mali_osk_resource_type +{ + RESOURCE_TYPE_FIRST =0, /**< Duplicate resource marker for the first resource*/ + + MEMORY =0, /**< Physically contiguous memory block, not managed by the OS */ + OS_MEMORY =1, /**< Memory managed by and shared with the OS */ + + MALI_PP =2, /**< Mali Pixel Processor core */ + MALI450PP =2, /**< Compatibility option */ + MALI400PP =2, /**< Compatibility option */ + MALI300PP =2, /**< Compatibility option */ + MALI200 =2, /**< Compatibility option */ + + MALI_GP =3, /**< Mali Geometry Processor core */ + MALI450GP =3, /**< Compatibility option */ + MALI400GP =3, /**< Compatibility option */ + MALI300GP =3, /**< Compatibility option */ + MALIGP2 =3, /**< Compatibility option */ + + MMU =4, /**< Mali MMU (Memory Management Unit) */ + + FPGA_FRAMEWORK =5, /**< Mali registers specific to FPGA implementations */ + + MALI_L2 =6, /**< Mali Level 2 cache core */ + MALI450L2 =6, /**< Compatibility option */ + MALI400L2 =6, /**< Compatibility option */ + MALI300L2 =6, /**< Compatibility option */ + + MEM_VALIDATION =7, /**< External Memory Validator */ + + PMU =8, /**< Power Manangement Unit */ + + RESOURCE_TYPE_COUNT /**< The total number of known resources */ +} _mali_osk_resource_type_t; + +/** @brief resource description struct + * + * _mali_osk_resources_init() will enumerate objects of this type. Not all + * members have a valid meaning across all types. + * + * The mmu_id is used to group resources to a certain MMU, since there may be + * more than one MMU in the system, and each resource may be using a different + * MMU: + * - For MMU resources, the setting of mmu_id is a uniquely identifying number. + * - For Other resources, the setting of mmu_id determines which MMU the + * resource uses. + */ +typedef struct _mali_osk_resource +{ + _mali_osk_resource_type_t type; /**< type of the resource */ + const char * description; /**< short description of the resource */ + u32 base; /**< Physical base address of the resource, as seen by Mali resources. */ + s32 cpu_usage_adjust; /**< Offset added to the base address of the resource to arrive at the CPU physical address of the resource (if different from the Mali physical address) */ + u32 size; /**< Size in bytes of the resource - either the size of its register range, or the size of the memory block. */ + u32 irq; /**< IRQ number delivered to the CPU, or -1 to tell the driver to probe for it (if possible) */ + u32 flags; /**< Resources-specific flags. */ + u32 mmu_id; /**< Identifier for Mali MMU resources. */ + u32 alloc_order; /**< Order in which MEMORY/OS_MEMORY resources are used */ +} _mali_osk_resource_t; +/** @} */ /* end group _mali_osk_miscellaneous */ + + +#include "mali_kernel_memory_engine.h" /* include for mali_memory_allocation and mali_physical_memory_allocation type */ + +/** @addtogroup _mali_osk_irq + * @{ */ + +/** @brief Fake IRQ number for testing purposes + */ +#define _MALI_OSK_IRQ_NUMBER_FAKE ((u32)0xFFFFFFF1) + +/** @addtogroup _mali_osk_irq + * @{ */ + +/** @brief PMM Virtual IRQ number + */ +#define _MALI_OSK_IRQ_NUMBER_PMM ((u32)0xFFFFFFF2) + + +/** @brief Initialize IRQ handling for a resource + * + * The _mali_osk_irq_t returned must be written into the resource-specific data + * pointed to by data. This is so that the upper and lower handlers can call + * _mali_osk_irq_schedulework(). + * + * @note The caller must ensure that the resource does not generate an + * interrupt after _mali_osk_irq_init() finishes, and before the + * _mali_osk_irq_t is written into the resource-specific data. Otherwise, + * the upper-half handler will fail to call _mali_osk_irq_schedulework(). + * + * @param irqnum The IRQ number that the resource uses, as seen by the CPU. + * The value -1 has a special meaning which indicates the use of probing, and trigger_func and ack_func must be + * non-NULL. + * @param uhandler The upper-half handler, corresponding to a ISR handler for + * the resource + * @param bhandler The lower-half handler, corresponding to an IST handler for + * the resource + * @param trigger_func Optional: a function to trigger the resource's irq, to + * probe for the interrupt. Use NULL if irqnum != -1. + * @param ack_func Optional: a function to acknowledge the resource's irq, to + * probe for the interrupt. Use NULL if irqnum != -1. + * @param data resource-specific data, which will be passed to uhandler, + * bhandler and (if present) trigger_func and ack_funnc + * @param description textual description of the IRQ resource. + * @return on success, a pointer to a _mali_osk_irq_t object, which represents + * the IRQ handling on this resource. NULL on failure. + */ +_mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandler, _mali_osk_irq_bhandler_t bhandler, _mali_osk_irq_trigger_t trigger_func, _mali_osk_irq_ack_t ack_func, void *data, const char *description ); + +/** @brief Cause a queued, deferred call of the IRQ bottom-half. + * + * _mali_osk_irq_schedulework provides a mechanism for enqueuing deferred calls + * to the IRQ bottom-half handler. The queue is known as the IRQ work-queue. + * After calling _mali_osk_irq_schedulework(), the IRQ bottom-half handler will + * be scheduled to run at some point in the future. + * + * This is called by the IRQ upper-half to defer further processing of + * IRQ-related work to the IRQ bottom-half handler. This is necessary for work + * that cannot be done in an IRQ context by the IRQ upper-half handler. Timer + * callbacks also use this mechanism, because they are treated as though they + * operate in an IRQ context. Refer to \ref _mali_osk_timer_t for more + * information. + * + * Code that operates in a kernel-process context (with no IRQ context + * restrictions) may also enqueue deferred calls to the IRQ bottom-half. The + * advantage over direct calling is that deferred calling allows the caller and + * IRQ bottom half to hold the same mutex, with a guarantee that they will not + * deadlock just by using this mechanism. + * + * _mali_osk_irq_schedulework() places deferred call requests on a queue, to + * allow for more than one thread to make a deferred call. Therfore, if it is + * called 'K' times, then the IRQ bottom-half will be scheduled 'K' times too. + * 'K' is a number that is implementation-specific. + * + * _mali_osk_irq_schedulework() is guaranteed to not block on: + * - enqueuing a deferred call request. + * - the completion of the IRQ bottom-half handler. + * + * This is to prevent deadlock. For example, if _mali_osk_irq_schedulework() + * blocked, then it would cause a deadlock when the following two conditions + * hold: + * - The IRQ bottom-half callback (of type _mali_osk_irq_bhandler_t) locks + * a mutex + * - And, at the same time, the caller of _mali_osk_irq_schedulework() also + * holds the same mutex + * + * @note care must be taken to not overflow the queue that + * _mali_osk_irq_schedulework() operates on. Code must be structured to + * ensure that the number of requests made to the queue is bounded. Otherwise, + * IRQs will be lost. + * + * The queue that _mali_osk_irq_schedulework implements is a FIFO of N-writer, + * 1-reader type. The writers are the callers of _mali_osk_irq_schedulework + * (all OSK-registered IRQ upper-half handlers in the system, watchdog timers, + * callers from a Kernel-process context). The reader is a single thread that + * handles all OSK-registered IRQs. + * + * The consequence of the queue being a 1-reader type is that calling + * _mali_osk_irq_schedulework() on different _mali_osk_irq_t objects causes + * their IRQ bottom-halves to be serialized, across all CPU-cores in the + * system. + * + * @param irq a pointer to the _mali_osk_irq_t object corresponding to the + * resource whose IRQ bottom-half must begin processing. + */ +void _mali_osk_irq_schedulework( _mali_osk_irq_t *irq ); + +/** @brief Terminate IRQ handling on a resource. + * + * This will disable the interrupt from the device, and then waits for the + * IRQ work-queue to finish the work that is currently in the queue. That is, + * for every deferred call currently in the IRQ work-queue, it waits for each + * of those to be processed by their respective IRQ bottom-half handler. + * + * This function is used to ensure that the bottom-half handler of the supplied + * IRQ object will not be running at the completion of this function call. + * However, the caller must ensure that no other sources could call the + * _mali_osk_irq_schedulework() on the same IRQ object. For example, the + * relevant timers must be stopped. + * + * @note While this function is being called, other OSK-registered IRQs in the + * system may enqueue work for their respective bottom-half handlers. This + * function will not wait for those entries in the work-queue to be flushed. + * + * Since this blocks on the completion of work in the IRQ work-queue, the + * caller of this function \b must \b not hold any mutexes that are taken by + * any OSK-registered IRQ bottom-half handler. To do so may cause a deadlock. + * + * @param irq a pointer to the _mali_osk_irq_t object corresponding to the + * resource whose IRQ handling is to be terminated. + */ +void _mali_osk_irq_term( _mali_osk_irq_t *irq ); + +/** @brief flushing workqueue. + * + * This will flush the workqueue. + * + * @param irq a pointer to the _mali_osk_irq_t object corresponding to the + * resource whose IRQ handling is to be terminated. + */ +void _mali_osk_flush_workqueue( _mali_osk_irq_t *irq ); + +/** @} */ /* end group _mali_osk_irq */ + + +/** @addtogroup _mali_osk_atomic + * @{ */ + +/** @brief Decrement an atomic counter + * + * @note It is an error to decrement the counter beyond -(1<<23) + * + * @param atom pointer to an atomic counter */ +void _mali_osk_atomic_dec( _mali_osk_atomic_t *atom ); + +/** @brief Decrement an atomic counter, return new value + * + * @param atom pointer to an atomic counter + * @return The new value, after decrement */ +u32 _mali_osk_atomic_dec_return( _mali_osk_atomic_t *atom ); + +/** @brief Increment an atomic counter + * + * @note It is an error to increment the counter beyond (1<<23)-1 + * + * @param atom pointer to an atomic counter */ +void _mali_osk_atomic_inc( _mali_osk_atomic_t *atom ); + +/** @brief Increment an atomic counter, return new value + * + * @param atom pointer to an atomic counter */ +u32 _mali_osk_atomic_inc_return( _mali_osk_atomic_t *atom ); + +/** @brief Initialize an atomic counter + * + * @note the parameter required is a u32, and so signed integers should be + * cast to u32. + * + * @param atom pointer to an atomic counter + * @param val the value to initialize the atomic counter. + * @return _MALI_OSK_ERR_OK on success, otherwise, a suitable + * _mali_osk_errcode_t on failure. + */ +_mali_osk_errcode_t _mali_osk_atomic_init( _mali_osk_atomic_t *atom, u32 val ); + +/** @brief Read a value from an atomic counter + * + * This can only be safely used to determine the value of the counter when it + * is guaranteed that other threads will not be modifying the counter. This + * makes its usefulness limited. + * + * @param atom pointer to an atomic counter + */ +u32 _mali_osk_atomic_read( _mali_osk_atomic_t *atom ); + +/** @brief Terminate an atomic counter + * + * @param atom pointer to an atomic counter + */ +void _mali_osk_atomic_term( _mali_osk_atomic_t *atom ); +/** @} */ /* end group _mali_osk_atomic */ + + +/** @defgroup _mali_osk_memory OSK Memory Allocation + * @{ */ + +/** @brief Allocate zero-initialized memory. + * + * Returns a buffer capable of containing at least \a n elements of \a size + * bytes each. The buffer is initialized to zero. + * + * If there is a need for a bigger block of memory (16KB or bigger), then + * consider to use _mali_osk_vmalloc() instead, as this function might + * map down to a OS function with size limitations. + * + * The buffer is suitably aligned for storage and subsequent access of every + * type that the compiler supports. Therefore, the pointer to the start of the + * buffer may be cast into any pointer type, and be subsequently accessed from + * such a pointer, without loss of information. + * + * When the buffer is no longer in use, it must be freed with _mali_osk_free(). + * Failure to do so will cause a memory leak. + * + * @note Most toolchains supply memory allocation functions that meet the + * compiler's alignment requirements. + * + * @param n Number of elements to allocate + * @param size Size of each element + * @return On success, the zero-initialized buffer allocated. NULL on failure + */ +void *_mali_osk_calloc( u32 n, u32 size ); + +/** @brief Allocate memory. + * + * Returns a buffer capable of containing at least \a size bytes. The + * contents of the buffer are undefined. + * + * If there is a need for a bigger block of memory (16KB or bigger), then + * consider to use _mali_osk_vmalloc() instead, as this function might + * map down to a OS function with size limitations. + * + * The buffer is suitably aligned for storage and subsequent access of every + * type that the compiler supports. Therefore, the pointer to the start of the + * buffer may be cast into any pointer type, and be subsequently accessed from + * such a pointer, without loss of information. + * + * When the buffer is no longer in use, it must be freed with _mali_osk_free(). + * Failure to do so will cause a memory leak. + * + * @note Most toolchains supply memory allocation functions that meet the + * compiler's alignment requirements. + * + * Remember to free memory using _mali_osk_free(). + * @param size Number of bytes to allocate + * @return On success, the buffer allocated. NULL on failure. + */ +void *_mali_osk_malloc( u32 size ); + +/** @brief Free memory. + * + * Reclaims the buffer pointed to by the parameter \a ptr for the system. + * All memory returned from _mali_osk_malloc() and _mali_osk_calloc() + * must be freed before the application exits. Otherwise, + * a memory leak will occur. + * + * Memory must be freed once. It is an error to free the same non-NULL pointer + * more than once. + * + * It is legal to free the NULL pointer. + * + * @param ptr Pointer to buffer to free + */ +void _mali_osk_free( void *ptr ); + +/** @brief Allocate memory. + * + * Returns a buffer capable of containing at least \a size bytes. The + * contents of the buffer are undefined. + * + * This function is potentially slower than _mali_osk_malloc() and _mali_osk_calloc(), + * but do support bigger sizes. + * + * The buffer is suitably aligned for storage and subsequent access of every + * type that the compiler supports. Therefore, the pointer to the start of the + * buffer may be cast into any pointer type, and be subsequently accessed from + * such a pointer, without loss of information. + * + * When the buffer is no longer in use, it must be freed with _mali_osk_free(). + * Failure to do so will cause a memory leak. + * + * @note Most toolchains supply memory allocation functions that meet the + * compiler's alignment requirements. + * + * Remember to free memory using _mali_osk_free(). + * @param size Number of bytes to allocate + * @return On success, the buffer allocated. NULL on failure. + */ +void *_mali_osk_valloc( u32 size ); + +/** @brief Free memory. + * + * Reclaims the buffer pointed to by the parameter \a ptr for the system. + * All memory returned from _mali_osk_valloc() must be freed before the + * application exits. Otherwise a memory leak will occur. + * + * Memory must be freed once. It is an error to free the same non-NULL pointer + * more than once. + * + * It is legal to free the NULL pointer. + * + * @param ptr Pointer to buffer to free + */ +void _mali_osk_vfree( void *ptr ); + +/** @brief Copies memory. + * + * Copies the \a len bytes from the buffer pointed by the parameter \a src + * directly to the buffer pointed by \a dst. + * + * It is an error for \a src to overlap \a dst anywhere in \a len bytes. + * + * @param dst Pointer to the destination array where the content is to be + * copied. + * @param src Pointer to the source of data to be copied. + * @param len Number of bytes to copy. + * @return \a dst is always passed through unmodified. + */ +void *_mali_osk_memcpy( void *dst, const void *src, u32 len ); + +/** @brief Fills memory. + * + * Sets the first \a n bytes of the block of memory pointed to by \a s to + * the specified value + * @param s Pointer to the block of memory to fill. + * @param c Value to be set, passed as u32. Only the 8 Least Significant Bits (LSB) + * are used. + * @param n Number of bytes to be set to the value. + * @return \a s is always passed through unmodified + */ +void *_mali_osk_memset( void *s, u32 c, u32 n ); +/** @} */ /* end group _mali_osk_memory */ + + +/** @brief Checks the amount of memory allocated + * + * Checks that not more than \a max_allocated bytes are allocated. + * + * Some OS bring up an interactive out of memory dialogue when the + * system runs out of memory. This can stall non-interactive + * apps (e.g. automated test runs). This function can be used to + * not trigger the OOM dialogue by keeping allocations + * within a certain limit. + * + * @return MALI_TRUE when \a max_allocated bytes are not in use yet. MALI_FALSE + * when at least \a max_allocated bytes are in use. + */ +mali_bool _mali_osk_mem_check_allocated( u32 max_allocated ); + +/** @addtogroup _mali_osk_lock + * @{ */ + +/** @brief Initialize a Mutual Exclusion Lock + * + * Locks are created in the signalled (unlocked) state. + * + * initial must be zero, since there is currently no means of expressing + * whether a reader/writer lock should be initially locked as a reader or + * writer. This would require some encoding to be used. + * + * 'Automatic' ordering means that locks must be obtained in the order that + * they were created. For all locks that can be held at the same time, they must + * either all provide the order parameter, or they all must use 'automatic' + * ordering - because there is no way of mixing 'automatic' and 'manual' + * ordering. + * + * @param flags flags combined with bitwise OR ('|'), or zero. There are + * restrictions on which flags can be combined, @see _mali_osk_lock_flags_t. + * @param initial For future expansion into semaphores. SBZ. + * @param order The locking order of the mutex. That is, locks obtained by the + * same thread must have been created with an increasing order parameter, for + * deadlock prevention. Setting to zero causes 'automatic' ordering to be used. + * @return On success, a pointer to a _mali_osk_lock_t object. NULL on failure. + */ +_mali_osk_lock_t *_mali_osk_lock_init( _mali_osk_lock_flags_t flags, u32 initial, u32 order ); + +/** @brief Wait for a lock to be signalled (obtained) + + * After a thread has successfully waited on the lock, the lock is obtained by + * the thread, and is marked as unsignalled. The thread releases the lock by + * signalling it. + * + * In the case of Reader/Writer locks, multiple readers can obtain a lock in + * the absence of writers, which is a performance optimization (providing that + * the readers never write to the protected resource). + * + * To prevent deadlock, locks must always be obtained in the same order. + * + * For locks marked as _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, it is a + * programming error for the function to exit without obtaining the lock. This + * means that the error code must only be checked for interruptible locks. + * + * @param lock the lock to wait upon (obtain). + * @param mode the mode in which the lock should be obtained. Unless the lock + * was created with _MALI_OSK_LOCKFLAG_READERWRITER, this must be + * _MALI_OSK_LOCKMODE_RW. + * @return On success, _MALI_OSK_ERR_OK. For interruptible locks, a suitable + * _mali_osk_errcode_t will be returned on failure, and the lock will not be + * obtained. In this case, the error code must be propagated up to the U/K + * interface. + */ +_mali_osk_errcode_t _mali_osk_lock_wait( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode); + + +/** @brief Signal (release) a lock + * + * Locks may only be signalled by the thread that originally waited upon the + * lock. + * + * @note In the OSU, a flag exists to allow any thread to signal a + * lock. Such functionality is not present in the OSK. + * + * @param lock the lock to signal (release). + * @param mode the mode in which the lock should be obtained. This must match + * the mode in which the lock was waited upon. + */ +void _mali_osk_lock_signal( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode ); + +/** @brief Terminate a lock + * + * This terminates a lock and frees all associated resources. + * + * It is a programming error to terminate the lock when it is held (unsignalled) + * by a thread. + * + * @param lock the lock to terminate. + */ +void _mali_osk_lock_term( _mali_osk_lock_t *lock ); +/** @} */ /* end group _mali_osk_lock */ + + +/** @addtogroup _mali_osk_low_level_memory + * @{ */ + +/** @brief Issue a memory barrier + * + * This defines an arbitrary memory barrier operation, which forces an ordering constraint + * on memory read and write operations. + */ +void _mali_osk_mem_barrier( void ); + +/** @brief Issue a write memory barrier + * + * This defines an write memory barrier operation which forces an ordering constraint + * on memory write operations. + */ +void _mali_osk_write_mem_barrier( void ); + +/** @brief Map a physically contiguous region into kernel space + * + * This is primarily used for mapping in registers from resources, and Mali-MMU + * page tables. The mapping is only visable from kernel-space. + * + * Access has to go through _mali_osk_mem_ioread32 and _mali_osk_mem_iowrite32 + * + * @param phys CPU-physical base address of the memory to map in. This must + * be aligned to the system's page size, which is assumed to be 4K. + * @param size the number of bytes of physically contiguous address space to + * map in + * @param description A textual description of the memory being mapped in. + * @return On success, a Mali IO address through which the mapped-in + * memory/registers can be accessed. NULL on failure. + */ +mali_io_address _mali_osk_mem_mapioregion( u32 phys, u32 size, const char *description ); + +/** @brief Unmap a physically contiguous address range from kernel space. + * + * The address range should be one previously mapped in through + * _mali_osk_mem_mapioregion. + * + * It is a programming error to do (but not limited to) the following: + * - attempt an unmap twice + * - unmap only part of a range obtained through _mali_osk_mem_mapioregion + * - unmap more than the range obtained through _mali_osk_mem_mapioregion + * - unmap an address range that was not successfully mapped using + * _mali_osk_mem_mapioregion + * - provide a mapping that does not map to phys. + * + * @param phys CPU-physical base address of the memory that was originally + * mapped in. This must be aligned to the system's page size, which is assumed + * to be 4K + * @param size The number of bytes that were originally mapped in. + * @param mapping The Mali IO address through which the mapping is + * accessed. + */ +void _mali_osk_mem_unmapioregion( u32 phys, u32 size, mali_io_address mapping ); + +/** @brief Allocate and Map a physically contiguous region into kernel space + * + * This is used for allocating physically contiguous regions (such as Mali-MMU + * page tables) and mapping them into kernel space. The mapping is only + * visible from kernel-space. + * + * The alignment of the returned memory is guaranteed to be at least + * _MALI_OSK_CPU_PAGE_SIZE. + * + * Access must go through _mali_osk_mem_ioread32 and _mali_osk_mem_iowrite32 + * + * @note This function is primarily to provide support for OSs that are + * incapable of separating the tasks 'allocate physically contiguous memory' + * and 'map it into kernel space' + * + * @param[out] phys CPU-physical base address of memory that was allocated. + * (*phys) will be guaranteed to be aligned to at least + * _MALI_OSK_CPU_PAGE_SIZE on success. + * + * @param[in] size the number of bytes of physically contiguous memory to + * allocate. This must be a multiple of _MALI_OSK_CPU_PAGE_SIZE. + * + * @return On success, a Mali IO address through which the mapped-in + * memory/registers can be accessed. NULL on failure, and (*phys) is unmodified. + */ +mali_io_address _mali_osk_mem_allocioregion( u32 *phys, u32 size ); + +/** @brief Free a physically contiguous address range from kernel space. + * + * The address range should be one previously mapped in through + * _mali_osk_mem_allocioregion. + * + * It is a programming error to do (but not limited to) the following: + * - attempt a free twice on the same ioregion + * - free only part of a range obtained through _mali_osk_mem_allocioregion + * - free more than the range obtained through _mali_osk_mem_allocioregion + * - free an address range that was not successfully mapped using + * _mali_osk_mem_allocioregion + * - provide a mapping that does not map to phys. + * + * @param phys CPU-physical base address of the memory that was originally + * mapped in, which was aligned to _MALI_OSK_CPU_PAGE_SIZE. + * @param size The number of bytes that were originally mapped in, which was + * a multiple of _MALI_OSK_CPU_PAGE_SIZE. + * @param mapping The Mali IO address through which the mapping is + * accessed. + */ +void _mali_osk_mem_freeioregion( u32 phys, u32 size, mali_io_address mapping ); + +/** @brief Request a region of physically contiguous memory + * + * This is used to ensure exclusive access to a region of physically contigous + * memory. + * + * It is acceptable to implement this as a stub. However, it is then the job + * of the System Integrator to ensure that no other device driver will be using + * the physical address ranges used by Mali, while the Mali device driver is + * loaded. + * + * @param phys CPU-physical base address of the memory to request. This must + * be aligned to the system's page size, which is assumed to be 4K. + * @param size the number of bytes of physically contiguous address space to + * request. + * @param description A textual description of the memory being requested. + * @return _MALI_OSK_ERR_OK on success. Otherwise, a suitable + * _mali_osk_errcode_t on failure. + */ +_mali_osk_errcode_t _mali_osk_mem_reqregion( u32 phys, u32 size, const char *description ); + +/** @brief Un-request a region of physically contiguous memory + * + * This is used to release a regious of physically contiguous memory previously + * requested through _mali_osk_mem_reqregion, so that other device drivers may + * use it. This will be called at time of Mali device driver termination. + * + * It is a programming error to attempt to: + * - unrequest a region twice + * - unrequest only part of a range obtained through _mali_osk_mem_reqregion + * - unrequest more than the range obtained through _mali_osk_mem_reqregion + * - unrequest an address range that was not successfully requested using + * _mali_osk_mem_reqregion + * + * @param phys CPU-physical base address of the memory to un-request. This must + * be aligned to the system's page size, which is assumed to be 4K + * @param size the number of bytes of physically contiguous address space to + * un-request. + */ +void _mali_osk_mem_unreqregion( u32 phys, u32 size ); + +/** @brief Read from a location currently mapped in through + * _mali_osk_mem_mapioregion + * + * This reads a 32-bit word from a 32-bit aligned location. It is a programming + * error to provide unaligned locations, or to read from memory that is not + * mapped in, or not mapped through either _mali_osk_mem_mapioregion() or + * _mali_osk_mem_allocioregion(). + * + * @param mapping Mali IO address to read from + * @param offset Byte offset from the given IO address to operate on, must be a multiple of 4 + * @return the 32-bit word from the specified location. + */ +u32 _mali_osk_mem_ioread32( volatile mali_io_address mapping, u32 offset ); + +/** @brief Write to a location currently mapped in through + * _mali_osk_mem_mapioregion without memory barriers + * + * This write a 32-bit word to a 32-bit aligned location without using memory barrier. + * It is a programming error to provide unaligned locations, or to write to memory that is not + * mapped in, or not mapped through either _mali_osk_mem_mapioregion() or + * _mali_osk_mem_allocioregion(). + * + * @param mapping Mali IO address to write to + * @param offset Byte offset from the given IO address to operate on, must be a multiple of 4 + * @param val the 32-bit word to write. + */ +void _mali_osk_mem_iowrite32_relaxed( volatile mali_io_address addr, u32 offset, u32 val ); + +/** @brief Write to a location currently mapped in through + * _mali_osk_mem_mapioregion with write memory barrier + * + * This write a 32-bit word to a 32-bit aligned location. It is a programming + * error to provide unaligned locations, or to write to memory that is not + * mapped in, or not mapped through either _mali_osk_mem_mapioregion() or + * _mali_osk_mem_allocioregion(). + * + * @param mapping Mali IO address to write to + * @param offset Byte offset from the given IO address to operate on, must be a multiple of 4 + * @param val the 32-bit word to write. + */ +void _mali_osk_mem_iowrite32( volatile mali_io_address mapping, u32 offset, u32 val ); + +/** @brief Flush all CPU caches + * + * This should only be implemented if flushing of the cache is required for + * memory mapped in through _mali_osk_mem_mapregion. + */ +void _mali_osk_cache_flushall( void ); + +/** @brief Flush any caches necessary for the CPU and MALI to have the same view of a range of uncached mapped memory + * + * This should only be implemented if your OS doesn't do a full cache flush (inner & outer) + * after allocating uncached mapped memory. + * + * Some OS do not perform a full cache flush (including all outer caches) for uncached mapped memory. + * They zero the memory through a cached mapping, then flush the inner caches but not the outer caches. + * This is required for MALI to have the correct view of the memory. + */ +void _mali_osk_cache_ensure_uncached_range_flushed( void *uncached_mapping, u32 offset, u32 size ); + +/** @} */ /* end group _mali_osk_low_level_memory */ + + +/** @addtogroup _mali_osk_notification + * + * User space notification framework + * + * Communication with user space of asynchronous events is performed through a + * synchronous call to the \ref u_k_api. + * + * Since the events are asynchronous, the events have to be queued until a + * synchronous U/K API call can be made by user-space. A U/K API call might also + * be received before any event has happened. Therefore the notifications the + * different subsystems wants to send to user space has to be queued for later + * reception, or a U/K API call has to be blocked until an event has occured. + * + * Typical uses of notifications are after running of jobs on the hardware or + * when changes to the system is detected that needs to be relayed to user + * space. + * + * After an event has occured user space has to be notified using some kind of + * message. The notification framework supports sending messages to waiting + * threads or queueing of messages until a U/K API call is made. + * + * The notification queue is a FIFO. There are no restrictions on the numbers + * of readers or writers in the queue. + * + * A message contains what user space needs to identifiy how to handle an + * event. This includes a type field and a possible type specific payload. + * + * A notification to user space is represented by a + * \ref _mali_osk_notification_t object. A sender gets hold of such an object + * using _mali_osk_notification_create(). The buffer given by the + * _mali_osk_notification_t::result_buffer field in the object is used to store + * any type specific data. The other fields are internal to the queue system + * and should not be touched. + * + * @{ */ + +/** @brief Create a notification object + * + * Returns a notification object which can be added to the queue of + * notifications pending for user space transfer. + * + * The implementation will initialize all members of the + * \ref _mali_osk_notification_t object. In particular, the + * _mali_osk_notification_t::result_buffer member will be initialized to point + * to \a size bytes of storage, and that storage will be suitably aligned for + * storage of any structure. That is, the created buffer meets the same + * requirements as _mali_osk_malloc(). + * + * The notification object must be deleted when not in use. Use + * _mali_osk_notification_delete() for deleting it. + * + * @note You \b must \b not call _mali_osk_free() on a \ref _mali_osk_notification_t, + * object, or on a _mali_osk_notification_t::result_buffer. You must only use + * _mali_osk_notification_delete() to free the resources assocaited with a + * \ref _mali_osk_notification_t object. + * + * @param type The notification type + * @param size The size of the type specific buffer to send + * @return Pointer to a notification object with a suitable buffer, or NULL on error. + */ +_mali_osk_notification_t *_mali_osk_notification_create( u32 type, u32 size ); + +/** @brief Delete a notification object + * + * This must be called to reclaim the resources of a notification object. This + * includes: + * - The _mali_osk_notification_t::result_buffer + * - The \ref _mali_osk_notification_t itself. + * + * A notification object \b must \b not be used after it has been deleted by + * _mali_osk_notification_delete(). + * + * In addition, the notification object may not be deleted while it is in a + * queue. That is, if it has been placed on a queue with + * _mali_osk_notification_queue_send(), then it must not be deleted until + * it has been received by a call to _mali_osk_notification_queue_receive(). + * Otherwise, the queue may be corrupted. + * + * @param object the notification object to delete. + */ +void _mali_osk_notification_delete( _mali_osk_notification_t *object ); + +/** @brief Create a notification queue + * + * Creates a notification queue which can be used to queue messages for user + * delivery and get queued messages from + * + * The queue is a FIFO, and has no restrictions on the numbers of readers or + * writers. + * + * When the queue is no longer in use, it must be terminated with + * \ref _mali_osk_notification_queue_term(). Failure to do so will result in a + * memory leak. + * + * @return Pointer to a new notification queue or NULL on error. + */ +_mali_osk_notification_queue_t *_mali_osk_notification_queue_init( void ); + +/** @brief Destroy a notification queue + * + * Destroys a notification queue and frees associated resources from the queue. + * + * A notification queue \b must \b not be destroyed in the following cases: + * - while there are \ref _mali_osk_notification_t objects in the queue. + * - while there are writers currently acting upon the queue. That is, while + * a thread is currently calling \ref _mali_osk_notification_queue_send() on + * the queue, or while a thread may call + * \ref _mali_osk_notification_queue_send() on the queue in the future. + * - while there are readers currently waiting upon the queue. That is, while + * a thread is currently calling \ref _mali_osk_notification_queue_receive() on + * the queue, or while a thread may call + * \ref _mali_osk_notification_queue_receive() on the queue in the future. + * + * Therefore, all \ref _mali_osk_notification_t objects must be flushed and + * deleted by the code that makes use of the notification queues, since only + * they know the structure of the _mali_osk_notification_t::result_buffer + * (even if it may only be a flat sturcture). + * + * @note Since the queue is a FIFO, the code using notification queues may + * create its own 'flush' type of notification, to assist in flushing the + * queue. + * + * Once the queue has been destroyed, it must not be used again. + * + * @param queue The queue to destroy + */ +void _mali_osk_notification_queue_term( _mali_osk_notification_queue_t *queue ); + +/** @brief Schedule notification for delivery + * + * When a \ref _mali_osk_notification_t object has been created successfully + * and set up, it may be added to the queue of objects waiting for user space + * transfer. + * + * The sending will not block if the queue is full. + * + * A \ref _mali_osk_notification_t object \b must \b not be put on two different + * queues at the same time, or enqueued twice onto a single queue before + * reception. However, it is acceptable for it to be requeued \em after reception + * from a call to _mali_osk_notification_queue_receive(), even onto the same queue. + * + * Again, requeuing must also not enqueue onto two different queues at the same + * time, or enqueue onto the same queue twice before reception. + * + * @param queue The notification queue to add this notification to + * @param object The entry to add + */ +void _mali_osk_notification_queue_send( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t *object ); + +#if MALI_STATE_TRACKING +/** @brief Receive a notification from a queue + * + * Check if a notification queue is empty. + * + * @param queue The queue to check. + * @return MALI_TRUE if queue is empty, otherwise MALI_FALSE. + */ +mali_bool _mali_osk_notification_queue_is_empty( _mali_osk_notification_queue_t *queue ); +#endif + +/** @brief Receive a notification from a queue + * + * Receives a single notification from the given queue. + * + * If no notifciations are ready the thread will sleep until one becomes ready. + * Therefore, notifications may not be received into an + * IRQ or 'atomic' context (that is, a context where sleeping is disallowed). + * + * @param queue The queue to receive from + * @param result Pointer to storage of a pointer of type + * \ref _mali_osk_notification_t*. \a result will be written to such that the + * expression \a (*result) will evaluate to a pointer to a valid + * \ref _mali_osk_notification_t object, or NULL if none were received. + * @return _MALI_OSK_ERR_OK on success. _MALI_OSK_ERR_RESTARTSYSCALL if the sleep was interrupted. + */ +_mali_osk_errcode_t _mali_osk_notification_queue_receive( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t **result ); + +/** @brief Dequeues a notification from a queue + * + * Receives a single notification from the given queue. + * + * If no notifciations are ready the function call will return an error code. + * + * @param queue The queue to receive from + * @param result Pointer to storage of a pointer of type + * \ref _mali_osk_notification_t*. \a result will be written to such that the + * expression \a (*result) will evaluate to a pointer to a valid + * \ref _mali_osk_notification_t object, or NULL if none were received. + * @return _MALI_OSK_ERR_OK on success, _MALI_OSK_ERR_ITEM_NOT_FOUND if queue was empty. + */ +_mali_osk_errcode_t _mali_osk_notification_queue_dequeue( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t **result ); + +/** @} */ /* end group _mali_osk_notification */ + + +/** @addtogroup _mali_osk_timer + * + * Timers use the OS's representation of time, which are 'ticks'. This is to + * prevent aliasing problems between the internal timer time, and the time + * asked for. + * + * @{ */ + +/** @brief Initialize a timer + * + * Allocates resources for a new timer, and initializes them. This does not + * start the timer. + * + * @return a pointer to the allocated timer object, or NULL on failure. + */ +_mali_osk_timer_t *_mali_osk_timer_init(void); + +/** @brief Start a timer + * + * It is an error to start a timer without setting the callback via + * _mali_osk_timer_setcallback(). + * + * It is an error to use this to start an already started timer. + * + * The timer will expire in \a ticks_to_expire ticks, at which point, the + * callback function will be invoked with the callback-specific data, + * as registered by _mali_osk_timer_setcallback(). + * + * @param tim the timer to start + * @param ticks_to_expire the amount of time in ticks for the timer to run + * before triggering. + */ +void _mali_osk_timer_add( _mali_osk_timer_t *tim, u32 ticks_to_expire ); + +/** @brief Modify a timer + * + * Set the absolute time at which a timer will expire, and start it if it is + * stopped. If \a expiry_tick is in the past (determined by + * _mali_osk_time_after() ), the timer fires immediately. + * + * It is an error to modify a timer without setting the callback via + * _mali_osk_timer_setcallback(). + * + * The timer will expire at absolute time \a expiry_tick, at which point, the + * callback function will be invoked with the callback-specific data, as set + * by _mali_osk_timer_setcallback(). + * + * @param tim the timer to modify, and start if necessary + * @param expiry_tick the \em absolute time in ticks at which this timer should + * trigger. + * + */ +void _mali_osk_timer_mod( _mali_osk_timer_t *tim, u32 expiry_tick); + +/** @brief Stop a timer, and block on its completion. + * + * Stop the timer. When the function returns, it is guaranteed that the timer's + * callback will not be running on any CPU core. + * + * Since stoping the timer blocks on compeletion of the callback, the callback + * may not obtain any mutexes that the caller holds. Otherwise, a deadlock will + * occur. + * + * @note While the callback itself is guaranteed to not be running, work + * enqueued on the IRQ work-queue by the timer (with + * \ref _mali_osk_irq_schedulework()) may still run. The timer callback and IRQ + * bottom-half handler must take this into account. + * + * It is legal to stop an already stopped timer. + * + * @param tim the timer to stop. + * + */ +void _mali_osk_timer_del( _mali_osk_timer_t *tim ); + +/** @brief Set a timer's callback parameters. + * + * This must be called at least once before a timer is started/modified. + * + * After a timer has been stopped or expires, the callback remains set. This + * means that restarting the timer will call the same function with the same + * parameters on expiry. + * + * @param tim the timer to set callback on. + * @param callback Function to call when timer expires + * @param data Function-specific data to supply to the function on expiry. + */ +void _mali_osk_timer_setcallback( _mali_osk_timer_t *tim, _mali_osk_timer_callback_t callback, void *data ); + +/** @brief Terminate a timer, and deallocate resources. + * + * The timer must first be stopped by calling _mali_osk_timer_del(). + * + * It is a programming error for _mali_osk_timer_term() to be called on: + * - timer that is currently running + * - a timer that is currently executing its callback. + * + * @param tim the timer to deallocate. + */ +void _mali_osk_timer_term( _mali_osk_timer_t *tim ); +/** @} */ /* end group _mali_osk_timer */ + + +/** @defgroup _mali_osk_time OSK Time functions + * + * \ref _mali_osk_time use the OS's representation of time, which are + * 'ticks'. This is to prevent aliasing problems between the internal timer + * time, and the time asked for. + * + * OS tick time is measured as a u32. The time stored in a u32 may either be + * an absolute time, or a time delta between two events. Whilst it is valid to + * use math opeartors to \em change the tick value represented as a u32, it + * is often only meaningful to do such operations on time deltas, rather than + * on absolute time. However, it is meaningful to add/subtract time deltas to + * absolute times. + * + * Conversion between tick time and milliseconds (ms) may not be loss-less, + * and are \em implementation \em depenedant. + * + * Code use OS time must take this into account, since: + * - a small OS time may (or may not) be rounded + * - a large time may (or may not) overflow + * + * @{ */ + +/** @brief Return whether ticka occurs after tickb + * + * Some OSs handle tick 'rollover' specially, and so can be more robust against + * tick counters rolling-over. This function must therefore be called to + * determine if a time (in ticks) really occurs after another time (in ticks). + * + * @param ticka ticka + * @param tickb tickb + * @return non-zero if ticka represents a time that occurs after tickb. + * Zero otherwise. + */ +int _mali_osk_time_after( u32 ticka, u32 tickb ); + +/** @brief Convert milliseconds to OS 'ticks' + * + * @param ms time interval in milliseconds + * @return the corresponding time interval in OS ticks. + */ +u32 _mali_osk_time_mstoticks( u32 ms ); + +/** @brief Convert OS 'ticks' to milliseconds + * + * @param ticks time interval in OS ticks. + * @return the corresponding time interval in milliseconds + */ +u32 _mali_osk_time_tickstoms( u32 ticks ); + + +/** @brief Get the current time in OS 'ticks'. + * @return the current time in OS 'ticks'. + */ +u32 _mali_osk_time_tickcount( void ); + +/** @brief Cause a microsecond delay + * + * The delay will have microsecond resolution, and is necessary for correct + * operation of the driver. At worst, the delay will be \b at least \a usecs + * microseconds, and so may be (significantly) more. + * + * This function may be implemented as a busy-wait, which is the most sensible + * implementation. On OSs where there are situations in which a thread must not + * sleep, this is definitely implemented as a busy-wait. + * + * @param usecs the number of microseconds to wait for. + */ +void _mali_osk_time_ubusydelay( u32 usecs ); + +/** @brief Return time in nano seconds, since any given reference. + * + * @return Time in nano seconds + */ +u64 _mali_osk_time_get_ns( void ); + + +/** @} */ /* end group _mali_osk_time */ + +/** @defgroup _mali_osk_math OSK Math + * @{ */ + +/** @brief Count Leading Zeros (Little-endian) + * + * @note This function must be implemented to support the reference + * implementation of _mali_osk_find_first_zero_bit, as defined in + * mali_osk_bitops.h. + * + * @param val 32-bit words to count leading zeros on + * @return the number of leading zeros. + */ +u32 _mali_osk_clz( u32 val ); +/** @} */ /* end group _mali_osk_math */ + +/** @defgroup _mali_osk_wait_queue OSK Wait Queue functionality + * @{ */ +/** @brief Private type for wait queue objects */ +typedef struct _mali_osk_wait_queue_t_struct _mali_osk_wait_queue_t; + +/** @brief Initialize an empty Wait Queue */ +_mali_osk_wait_queue_t* _mali_osk_wait_queue_init( void ); + +/** @brief Sleep if condition is false + * + * @param queue the queue to use + * @param condition function pointer to a boolean function + * + * Put thread to sleep if the given \a codition function returns false. When + * being asked to wake up again, the condition will be re-checked and the + * thread only woken up if the condition is now true. + */ +void _mali_osk_wait_queue_wait_event( _mali_osk_wait_queue_t *queue, mali_bool (*condition)(void) ); + +/** @brief Wake up all threads in wait queue if their respective conditions are + * true + * + * @param queue the queue whose threads should be woken up + * + * Wake up all threads in wait queue \a queue whose condition is now true. + */ +void _mali_osk_wait_queue_wake_up( _mali_osk_wait_queue_t *queue ); + +/** @brief terminate a wait queue + * + * @param queue the queue to terminate. + */ +void _mali_osk_wait_queue_term( _mali_osk_wait_queue_t *queue ); +/** @} */ /* end group _mali_osk_wait_queue */ + + +/** @addtogroup _mali_osk_miscellaneous + * @{ */ + +/** @brief Output a device driver debug message. + * + * The interpretation of \a fmt is the same as the \c format parameter in + * _mali_osu_vsnprintf(). + * + * @param fmt a _mali_osu_vsnprintf() style format string + * @param ... a variable-number of parameters suitable for \a fmt + */ +void _mali_osk_dbgmsg( const char *fmt, ... ); + +/** @brief Print fmt into buf. + * + * The interpretation of \a fmt is the same as the \c format parameter in + * _mali_osu_vsnprintf(). + * + * @param buf a pointer to the result buffer + * @param size the total number of bytes allowed to write to \a buf + * @param fmt a _mali_osu_vsnprintf() style format string + * @param ... a variable-number of parameters suitable for \a fmt + * @return The number of bytes written to \a buf + */ +u32 _mali_osk_snprintf( char *buf, u32 size, const char *fmt, ... ); + +/** @brief Abnormal process abort. + * + * Terminates the caller-process if this function is called. + * + * This function will be called from Debug assert-macros in mali_kernel_common.h. + * + * This function will never return - because to continue from a Debug assert + * could cause even more problems, and hinder debugging of the initial problem. + * + * This function is only used in Debug builds, and is not used in Release builds. + */ +void _mali_osk_abort(void); + +/** @brief Sets breakpoint at point where function is called. + * + * This function will be called from Debug assert-macros in mali_kernel_common.h, + * to assist in debugging. If debugging at this level is not required, then this + * function may be implemented as a stub. + * + * This function is only used in Debug builds, and is not used in Release builds. + */ +void _mali_osk_break(void); + +/** @brief Return an identificator for calling process. + * + * @return Identificator for calling process. + */ +u32 _mali_osk_get_pid(void); + +/** @brief Return an identificator for calling thread. + * + * @return Identificator for calling thread. + */ +u32 _mali_osk_get_tid(void); + +/** @brief Enable OS controlled runtime power management + */ +void _mali_osk_pm_dev_enable(void); + +/** @brief Tells the OS that device is now idle + */ +_mali_osk_errcode_t _mali_osk_pm_dev_idle(void); + +/** @brief Tells the OS that the device is about to become active + */ +_mali_osk_errcode_t _mali_osk_pm_dev_activate(void); + +/** @} */ /* end group _mali_osk_miscellaneous */ + +/** @} */ /* end group osuapi */ + +/** @} */ /* end group uddapi */ + + +#ifdef __cplusplus +} +#endif + +#include "mali_osk_specific.h" /* include any per-os specifics */ + +/* Check standard inlines */ +#ifndef MALI_STATIC_INLINE + #error MALI_STATIC_INLINE not defined on your OS +#endif + +#ifndef MALI_NON_STATIC_INLINE + #error MALI_NON_STATIC_INLINE not defined on your OS +#endif + +#endif /* __MALI_OSK_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_osk_bitops.h b/drivers/media/video/samsung/mali/common/mali_osk_bitops.h new file mode 100644 index 0000000..ada1488 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_osk_bitops.h @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_bitops.h + * Implementation of the OS abstraction layer for the kernel device driver + */ + +#ifndef __MALI_OSK_BITOPS_H__ +#define __MALI_OSK_BITOPS_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +MALI_STATIC_INLINE void _mali_internal_clear_bit( u32 bit, u32 *addr ) +{ + MALI_DEBUG_ASSERT( bit < 32 ); + MALI_DEBUG_ASSERT( NULL != addr ); + + (*addr) &= ~(1 << bit); +} + +MALI_STATIC_INLINE void _mali_internal_set_bit( u32 bit, u32 *addr ) +{ + MALI_DEBUG_ASSERT( bit < 32 ); + MALI_DEBUG_ASSERT( NULL != addr ); + + (*addr) |= (1 << bit); +} + +MALI_STATIC_INLINE u32 _mali_internal_test_bit( u32 bit, u32 value ) +{ + MALI_DEBUG_ASSERT( bit < 32 ); + return value & (1 << bit); +} + +MALI_STATIC_INLINE int _mali_internal_find_first_zero_bit( u32 value ) +{ + u32 inverted; + u32 negated; + u32 isolated; + u32 leading_zeros; + + /* Begin with xxx...x0yyy...y, where ys are 1, number of ys is in range 0..31 */ + inverted = ~value; /* zzz...z1000...0 */ + /* Using count_trailing_zeros on inverted value - + * See ARM System Developers Guide for details of count_trailing_zeros */ + + /* Isolate the zero: it is preceeded by a run of 1s, so add 1 to it */ + negated = (u32)-inverted ; /* -a == ~a + 1 (mod 2^n) for n-bit numbers */ + /* negated = xxx...x1000...0 */ + + isolated = negated & inverted ; /* xxx...x1000...0 & zzz...z1000...0, zs are ~xs */ + /* And so the first zero bit is in the same position as the 1 == number of 1s that preceeded it + * Note that the output is zero if value was all 1s */ + + leading_zeros = _mali_osk_clz( isolated ); + + return 31 - leading_zeros; +} + + +/** @defgroup _mali_osk_bitops OSK Non-atomic Bit-operations + * @{ */ + +/** + * These bit-operations do not work atomically, and so locks must be used if + * atomicity is required. + * + * Reference implementations for Little Endian are provided, and so it should + * not normally be necessary to re-implement these. Efficient bit-twiddling + * techniques are used where possible, implemented in portable C. + * + * Note that these reference implementations rely on _mali_osk_clz() being + * implemented. + */ + +/** @brief Clear a bit in a sequence of 32-bit words + * @param nr bit number to clear, starting from the (Little-endian) least + * significant bit + * @param addr starting point for counting. + */ +MALI_STATIC_INLINE void _mali_osk_clear_nonatomic_bit( u32 nr, u32 *addr ) +{ + addr += nr >> 5; /* find the correct word */ + nr = nr & ((1 << 5)-1); /* The bit number within the word */ + + _mali_internal_clear_bit( nr, addr ); +} + +/** @brief Set a bit in a sequence of 32-bit words + * @param nr bit number to set, starting from the (Little-endian) least + * significant bit + * @param addr starting point for counting. + */ +MALI_STATIC_INLINE void _mali_osk_set_nonatomic_bit( u32 nr, u32 *addr ) +{ + addr += nr >> 5; /* find the correct word */ + nr = nr & ((1 << 5)-1); /* The bit number within the word */ + + _mali_internal_set_bit( nr, addr ); +} + +/** @brief Test a bit in a sequence of 32-bit words + * @param nr bit number to test, starting from the (Little-endian) least + * significant bit + * @param addr starting point for counting. + * @return zero if bit was clear, non-zero if set. Do not rely on the return + * value being related to the actual word under test. + */ +MALI_STATIC_INLINE u32 _mali_osk_test_bit( u32 nr, u32 *addr ) +{ + addr += nr >> 5; /* find the correct word */ + nr = nr & ((1 << 5)-1); /* The bit number within the word */ + + return _mali_internal_test_bit( nr, *addr ); +} + +/* Return maxbit if not found */ +/** @brief Find the first zero bit in a sequence of 32-bit words + * @param addr starting point for search. + * @param maxbit the maximum number of bits to search + * @return the number of the first zero bit found, or maxbit if none were found + * in the specified range. + */ +MALI_STATIC_INLINE u32 _mali_osk_find_first_zero_bit( const u32 *addr, u32 maxbit ) +{ + u32 total; + + for ( total = 0; total < maxbit; total += 32, ++addr ) + { + int result; + result = _mali_internal_find_first_zero_bit( *addr ); + + /* non-negative signifies the bit was found */ + if ( result >= 0 ) + { + total += (u32)result; + break; + } + } + + /* Now check if we reached maxbit or above */ + if ( total >= maxbit ) + { + total = maxbit; + } + + return total; /* either the found bit nr, or maxbit if not found */ +} +/** @} */ /* end group _mali_osk_bitops */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MALI_OSK_BITOPS_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_osk_list.h b/drivers/media/video/samsung/mali/common/mali_osk_list.h new file mode 100644 index 0000000..5987b0a --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_osk_list.h @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_list.h + * Implementation of the OS abstraction layer for the kernel device driver + */ + +#ifndef __MALI_OSK_LIST_H__ +#define __MALI_OSK_LIST_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +MALI_STATIC_INLINE void __mali_osk_list_add(_mali_osk_list_t *new_entry, _mali_osk_list_t *prev, _mali_osk_list_t *next) +{ + next->prev = new_entry; + new_entry->next = next; + new_entry->prev = prev; + prev->next = new_entry; +} + +MALI_STATIC_INLINE void __mali_osk_list_del(_mali_osk_list_t *prev, _mali_osk_list_t *next) +{ + next->prev = prev; + prev->next = next; +} + +/** @addtogroup _mali_osk_list + * @{ */ + +/** Reference implementations of Doubly-linked Circular Lists are provided. + * There is often no need to re-implement these. + * + * @note The implementation may differ subtly from any lists the OS provides. + * For this reason, these lists should not be mixed with OS-specific lists + * inside the OSK/UKK implementation. */ + +/** @brief Initialize a list element. + * + * All list elements must be initialized before use. + * + * Do not use on any list element that is present in a list without using + * _mali_osk_list_del first, otherwise this will break the list. + * + * @param list the list element to initialize + */ +MALI_STATIC_INLINE void _mali_osk_list_init( _mali_osk_list_t *list ) +{ + list->next = list; + list->prev = list; +} + +/** @brief Insert a single list element after an entry in a list + * + * As an example, if this is inserted to the head of a list, then this becomes + * the first element of the list. + * + * Do not use to move list elements from one list to another, as it will break + * the originating list. + * + * + * @param newlist the list element to insert + * @param list the list in which to insert. The new element will be the next + * entry in this list + */ +MALI_STATIC_INLINE void _mali_osk_list_add( _mali_osk_list_t *new_entry, _mali_osk_list_t *list ) +{ + __mali_osk_list_add(new_entry, list, list->next); +} + +/** @brief Insert a single list element before an entry in a list + * + * As an example, if this is inserted to the head of a list, then this becomes + * the last element of the list. + * + * Do not use to move list elements from one list to another, as it will break + * the originating list. + * + * @param newlist the list element to insert + * @param list the list in which to insert. The new element will be the previous + * entry in this list + */ +MALI_STATIC_INLINE void _mali_osk_list_addtail( _mali_osk_list_t *new_entry, _mali_osk_list_t *list ) +{ + __mali_osk_list_add(new_entry, list->prev, list); +} + +/** @brief Remove a single element from a list + * + * The element will no longer be present in the list. The removed list element + * will be uninitialized, and so should not be traversed. It must be + * initialized before further use. + * + * @param list the list element to remove. + */ +MALI_STATIC_INLINE void _mali_osk_list_del( _mali_osk_list_t *list ) +{ + __mali_osk_list_del(list->prev, list->next); +} + +/** @brief Remove a single element from a list, and re-initialize it + * + * The element will no longer be present in the list. The removed list element + * will initialized, and so can be used as normal. + * + * @param list the list element to remove and initialize. + */ +MALI_STATIC_INLINE void _mali_osk_list_delinit( _mali_osk_list_t *list ) +{ + __mali_osk_list_del(list->prev, list->next); + _mali_osk_list_init(list); +} + +/** @brief Determine whether a list is empty. + * + * An empty list is one that contains a single element that points to itself. + * + * @param list the list to check. + * @return non-zero if the list is empty, and zero otherwise. + */ +MALI_STATIC_INLINE int _mali_osk_list_empty( _mali_osk_list_t *list ) +{ + return list->next == list; +} + +/** @brief Move a list element from one list to another. + * + * The list element must be initialized. + * + * As an example, moving a list item to the head of a new list causes this item + * to be the first element in the new list. + * + * @param move the list element to move + * @param list the new list into which the element will be inserted, as the next + * element in the list. + */ +MALI_STATIC_INLINE void _mali_osk_list_move( _mali_osk_list_t *move_entry, _mali_osk_list_t *list ) +{ + __mali_osk_list_del(move_entry->prev, move_entry->next); + _mali_osk_list_add(move_entry, list); +} + +/** @brief Join two lists + * + * The list element must be initialized. + * + * Allows you to join a list into another list at a specific location + * + * @param list the new list to add + * @param at the location in a list to add the new list into + */ +MALI_STATIC_INLINE void _mali_osk_list_splice( _mali_osk_list_t *list, _mali_osk_list_t *at ) +{ + if (!_mali_osk_list_empty(list)) + { + /* insert all items from 'list' after 'at' */ + _mali_osk_list_t *first = list->next; + _mali_osk_list_t *last = list->prev; + _mali_osk_list_t *split = at->next; + + first->prev = at; + at->next = first; + + last->next = split; + split->prev = last; + } +} +/** @} */ /* end group _mali_osk_list */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MALI_OSK_LIST_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_osk_mali.h b/drivers/media/video/samsung/mali/common/mali_osk_mali.h new file mode 100644 index 0000000..427fcc8 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_osk_mali.h @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_mali.h + * Defines the OS abstraction layer which is specific for the Mali kernel device driver (OSK) + */ + +#ifndef __MALI_OSK_MALI_H__ +#define __MALI_OSK_MALI_H__ + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** @addtogroup _mali_osk_miscellaneous + * @{ */ + +/** @brief Read the Mali Resource configuration + * + * Populates a _mali_arch_resource_t array from configuration settings, which + * are stored in an OS-specific way. + * + * For example, these may be compiled in to a static structure, or read from + * the filesystem at startup. + * + * On failure, do not call _mali_osk_resources_term. + * + * @param arch_config a pointer to the store the pointer to the resources + * @param num_resources the number of resources read + * @return _MALI_OSK_ERR_OK on success. _MALI_OSK_ERR_NOMEM on allocation + * error. For other failures, a suitable _mali_osk_errcode_t is returned. + */ +_mali_osk_errcode_t _mali_osk_resources_init( _mali_osk_resource_t **arch_config, u32 *num_resources ); + +/** @brief Free resources allocated by _mali_osk_resources_init. + * + * Frees the _mali_arch_resource_t array allocated by _mali_osk_resources_init + * + * @param arch_config a pointer to the stored the pointer to the resources + * @param num_resources the number of resources in the array + */ +void _mali_osk_resources_term( _mali_osk_resource_t **arch_config, u32 num_resources); +/** @} */ /* end group _mali_osk_miscellaneous */ + +/** @addtogroup _mali_osk_low_level_memory + * @{ */ + +/** @brief Initialize a user-space accessible memory range + * + * This initializes a virtual address range such that it is reserved for the + * current process, but does not map any physical pages into this range. + * + * This function may initialize or adjust any members of the + * mali_memory_allocation \a descriptor supplied, before the physical pages are + * mapped in with _mali_osk_mem_mapregion_map(). + * + * The function will always be called with MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE + * set in \a descriptor->flags. It is an error to call this function without + * setting this flag. Otherwise, \a descriptor->flags bits are reserved for + * future expansion + * + * The \a descriptor's process_addr_mapping_info member can be modified to + * allocate OS-specific information. Note that on input, this will be a + * ukk_private word from the U/K inteface, as inserted by _mali_ukk_mem_mmap(). + * This is used to pass information from the U/K interface to the OSK interface, + * if necessary. The precise usage of the process_addr_mapping_info member + * depends on the U/K implementation of _mali_ukk_mem_mmap(). + * + * Therefore, the U/K implementation of _mali_ukk_mem_mmap() and the OSK + * implementation of _mali_osk_mem_mapregion_init() must agree on the meaning and + * usage of the ukk_private word and process_addr_mapping_info member. + * + * Refer to \ref u_k_api for more information on the U/K interface. + * + * On successful return, \a descriptor's mapping member will be correct for + * use with _mali_osk_mem_mapregion_term() and _mali_osk_mem_mapregion_map(). + * + * @param descriptor the mali_memory_allocation to initialize. + */ +_mali_osk_errcode_t _mali_osk_mem_mapregion_init( mali_memory_allocation * descriptor ); + +/** @brief Terminate a user-space accessible memory range + * + * This terminates a virtual address range reserved in the current user process, + * where none, some or all of the virtual address ranges have mappings to + * physical pages. + * + * It will unmap any physical pages that had been mapped into a reserved + * virtual address range for the current process, and then releases the virtual + * address range. Any extra book-keeping information or resources allocated + * during _mali_osk_mem_mapregion_init() will also be released. + * + * The \a descriptor itself is not freed - this must be handled by the caller of + * _mali_osk_mem_mapregion_term(). + * + * The function will always be called with MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE + * set in descriptor->flags. It is an error to call this function without + * setting this flag. Otherwise, descriptor->flags bits are reserved for + * future expansion + * + * @param descriptor the mali_memory_allocation to terminate. + */ +void _mali_osk_mem_mapregion_term( mali_memory_allocation * descriptor ); + +/** @brief Map physical pages into a user process's virtual address range + * + * This is used to map a number of physically contigous pages into a + * user-process's virtual address range, which was previously reserved by a + * call to _mali_osk_mem_mapregion_init(). + * + * This need not provide a mapping for the entire virtual address range + * reserved for \a descriptor - it may be used to map single pages per call. + * + * The function will always be called with MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE + * set in \a descriptor->flags. It is an error to call this function without + * setting this flag. Otherwise, \a descriptor->flags bits are reserved for + * future expansion + * + * The function may supply \a *phys_addr == \ref MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC. + * In this case, \a size must be set to \ref _MALI_OSK_CPU_PAGE_SIZE, and the function + * will allocate the physical page itself. The physical address of the + * allocated page will be returned through \a phys_addr. + * + * It is an error to set \a size != \ref _MALI_OSK_CPU_PAGE_SIZE while + * \a *phys_addr == \ref MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC, + * since it is not always possible for OSs to support such a setting through this + * interface. + * + * @note \b IMPORTANT: This code must validate the input parameters. If the + * range defined by \a offset and \a size is outside the range allocated in + * \a descriptor, then this function \b MUST not attempt any mapping, and must + * instead return a suitable \ref _mali_osk_errcode_t \b failure code. + * + * @param[in,out] descriptor the mali_memory_allocation representing the + * user-process's virtual address range to map into. + * + * @param[in] offset the offset into the virtual address range. This is only added + * to the mapping member of the \a descriptor, and not the \a phys_addr parameter. + * It must be a multiple of \ref _MALI_OSK_CPU_PAGE_SIZE. + * + * @param[in,out] phys_addr a pointer to the physical base address to begin the + * mapping from. If \a size == \ref _MALI_OSK_CPU_PAGE_SIZE and + * \a *phys_addr == \ref MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC, then this + * function will allocate the physical page itself, and return the + * physical address of the page through \a phys_addr, which will be aligned to + * \ref _MALI_OSK_CPU_PAGE_SIZE. Otherwise, \a *phys_addr must be aligned to + * \ref _MALI_OSK_CPU_PAGE_SIZE, and is unmodified after the call. + * \a phys_addr is unaffected by the \a offset parameter. + * + * @param[in] size the number of bytes to map in. This must be a multiple of + * \ref _MALI_OSK_CPU_PAGE_SIZE. + * + * @return _MALI_OSK_ERR_OK on sucess, otherwise a _mali_osk_errcode_t value + * on failure + * + * @note could expand to use _mali_osk_mem_mapregion_flags_t instead of + * \ref MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC, but note that we must + * also modify the mali process address manager in the mmu/memory engine code. + */ +_mali_osk_errcode_t _mali_osk_mem_mapregion_map( mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size ); + + +/** @brief Unmap physical pages from a user process's virtual address range + * + * This is used to unmap a number of physically contigous pages from a + * user-process's virtual address range, which were previously mapped by a + * call to _mali_osk_mem_mapregion_map(). If the range specified was allocated + * from OS memory, then that memory will be returned to the OS. Whilst pages + * will be mapped out, the Virtual address range remains reserved, and at the + * same base address. + * + * When this function is used to unmap pages from OS memory + * (_mali_osk_mem_mapregion_map() was called with *phys_addr == + * \ref MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC), then the \a flags must + * include \ref _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR. This is because + * it is not always easy for an OS implementation to discover whether the + * memory was OS allocated or not (and so, how it should release the memory). + * + * For this reason, only a range of pages of the same allocation type (all OS + * allocated, or none OS allocacted) may be unmapped in one call. Multiple + * calls must be made if allocations of these different types exist across the + * entire region described by the \a descriptor. + * + * The function will always be called with MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE + * set in \a descriptor->flags. It is an error to call this function without + * setting this flag. Otherwise, \a descriptor->flags bits are reserved for + * future expansion + * + * @param[in,out] descriptor the mali_memory_allocation representing the + * user-process's virtual address range to map into. + * + * @param[in] offset the offset into the virtual address range. This is only added + * to the mapping member of the \a descriptor. \a offset must be a multiple of + * \ref _MALI_OSK_CPU_PAGE_SIZE. + * + * @param[in] size the number of bytes to unmap. This must be a multiple of + * \ref _MALI_OSK_CPU_PAGE_SIZE. + * + * @param[in] flags specifies how the memory should be unmapped. For a range + * of pages that were originally OS allocated, this must have + * \ref _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR set. + */ +void _mali_osk_mem_mapregion_unmap( mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t flags ); +/** @} */ /* end group _mali_osk_low_level_memory */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __MALI_OSK_MALI_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_osk_profiling.h b/drivers/media/video/samsung/mali/common/mali_osk_profiling.h new file mode 100644 index 0000000..fd9a8fb --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_osk_profiling.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_OSK_PROFILING_H__ +#define __MALI_OSK_PROFILING_H__ + +#if MALI_TIMELINE_PROFILING_ENABLED + +#if defined (CONFIG_TRACEPOINTS) && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED +#include "mali_linux_trace.h" +#endif /* CONFIG_TRACEPOINTS && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED */ + +#include "mali_profiling_events.h" + +#define MALI_PROFILING_MAX_BUFFER_ENTRIES 1048576 + +#define MALI_PROFILING_NO_HW_COUNTER = ((u32)-1) + +/** @defgroup _mali_osk_profiling External profiling connectivity + * @{ */ + +/** + * Initialize the profiling module. + * @return _MALI_OSK_ERR_OK on success, otherwise failure. + */ +_mali_osk_errcode_t _mali_osk_profiling_init(mali_bool auto_start); + +/* + * Terminate the profiling module. + */ +void _mali_osk_profiling_term(void); + +/** + * Start recording profiling data + * + * The specified limit will determine how large the capture buffer is. + * MALI_PROFILING_MAX_BUFFER_ENTRIES determines the maximum size allowed by the device driver. + * + * @param limit The desired maximum number of events to record on input, the actual maximum on output. + * @return _MALI_OSK_ERR_OK on success, otherwise failure. + */ +_mali_osk_errcode_t _mali_osk_profiling_start(u32 * limit); + +/** + * Add an profiling event + * + * @param event_id The event identificator. + * @param data0 First data parameter, depending on event_id specified. + * @param data1 Second data parameter, depending on event_id specified. + * @param data2 Third data parameter, depending on event_id specified. + * @param data3 Fourth data parameter, depending on event_id specified. + * @param data4 Fifth data parameter, depending on event_id specified. + * @return _MALI_OSK_ERR_OK on success, otherwise failure. + */ +#if defined (CONFIG_TRACEPOINTS) && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED +/* Call Linux tracepoint directly */ +#define _mali_osk_profiling_add_event(event_id, data0, data1, data2, data3, data4) trace_mali_timeline_event((event_id), (data0), (data1), (data2), (data3), (data4)) +#else +/* Internal profiling is handled like a plain function call */ +void _mali_osk_profiling_add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4); +#endif + +/** + * Report a hardware counter event. + * + * @param counter_id The ID of the counter. + * @param value The value of the counter. + */ + +#if defined (CONFIG_TRACEPOINTS) && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED +/* Call Linux tracepoint directly */ +#define _mali_osk_profiling_report_hw_counter(counter_id, value) trace_mali_hw_counter(counter_id, value) +#else +/* Internal profiling is handled like a plain function call */ +void _mali_osk_profiling_report_hw_counter(u32 counter_id, u32 value); +#endif + +/** + * Report SW counters + * + * @param counters array of counter values + */ +void _mali_osk_profiling_report_sw_counters(u32 *counters); + +/** + * Stop recording profiling data + * + * @param count Returns the number of recorded events. + * @return _MALI_OSK_ERR_OK on success, otherwise failure. + */ +_mali_osk_errcode_t _mali_osk_profiling_stop(u32 * count); + +/** + * Retrieves the number of events that can be retrieved + * + * @return The number of recorded events that can be retrieved. + */ +u32 _mali_osk_profiling_get_count(void); + +/** + * Retrieve an event + * + * @param index Event index (start with 0 and continue until this function fails to retrieve all events) + * @param timestamp The timestamp for the retrieved event will be stored here. + * @param event_id The event ID for the retrieved event will be stored here. + * @param data The 5 data values for the retrieved event will be stored here. + * @return _MALI_OSK_ERR_OK on success, otherwise failure. + */ +_mali_osk_errcode_t _mali_osk_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5]); + +/** + * Clear the recorded buffer. + * + * This is needed in order to start another recording. + * + * @return _MALI_OSK_ERR_OK on success, otherwise failure. + */ +_mali_osk_errcode_t _mali_osk_profiling_clear(void); + +/** + * Checks if a recording of profiling data is in progress + * + * @return MALI_TRUE if recording of profiling data is in progress, MALI_FALSE if not + */ +mali_bool _mali_osk_profiling_is_recording(void); + +/** + * Checks if profiling data is available for retrival + * + * @return MALI_TRUE if profiling data is avaiable, MALI_FALSE if not + */ +mali_bool _mali_osk_profiling_have_recording(void); + +/** @} */ /* end group _mali_osk_profiling */ + +#endif /* MALI_TIMELINE_PROFILING_ENABLED */ + +#endif /* __MALI_OSK_PROFILING_H__ */ + + diff --git a/drivers/media/video/samsung/mali/common/mali_pm.c b/drivers/media/video/samsung/mali/common/mali_pm.c new file mode 100644 index 0000000..933e54e --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_pm.c @@ -0,0 +1,552 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_pm.h" +#include "mali_kernel_common.h" +#include "mali_osk.h" +#include "mali_gp_scheduler.h" +#include "mali_pp_scheduler.h" +#include "mali_platform.h" +#include "mali_kernel_utilization.h" +#include "mali_kernel_core.h" +#include "mali_group.h" + +#define MALI_PM_LIGHT_SLEEP_TIMEOUT 1000 + +enum mali_pm_scheme +{ + MALI_PM_SCHEME_DYNAMIC, + MALI_PM_SCHEME_OS_SUSPENDED, + MALI_PM_SCHEME_ALWAYS_ON +}; + +enum mali_pm_level +{ + MALI_PM_LEVEL_1_ON, + MALI_PM_LEVEL_2_STANDBY, + MALI_PM_LEVEL_3_LIGHT_SLEEP, + MALI_PM_LEVEL_4_DEEP_SLEEP +}; +static _mali_osk_lock_t *mali_pm_lock_set_next_state; +static _mali_osk_lock_t *mali_pm_lock_set_core_states; +static _mali_osk_lock_t *mali_pm_lock_execute_state_change; +static _mali_osk_irq_t *wq_irq; + +static _mali_osk_timer_t *idle_timer = NULL; +static mali_bool idle_timer_running = MALI_FALSE; +static u32 mali_pm_event_number = 0; + +static u32 num_active_gps = 0; +static u32 num_active_pps = 0; + +static enum mali_pm_scheme current_scheme = MALI_PM_SCHEME_DYNAMIC; +static enum mali_pm_level current_level = MALI_PM_LEVEL_1_ON; +static enum mali_pm_level next_level_dynamic = MALI_PM_LEVEL_2_STANDBY; /* Should be the state we go to when we go out of MALI_PM_SCHEME_ALWAYS_ON during init */ + + + +static _mali_osk_errcode_t mali_pm_upper_half(void *data); +static void mali_pm_bottom_half(void *data); +static void mali_pm_powerup(void); +static void mali_pm_powerdown(mali_power_mode power_mode); + +static void timeout_light_sleep(void* arg); +#if 0 +/* Deep sleep timout not supported */ +static void timeout_deep_sleep(void* arg); +#endif +static u32 mali_pm_event_number_get(void); +static void mali_pm_event(enum mali_pm_event pm_event, mali_bool schedule_work, u32 timer_time ); + +_mali_osk_errcode_t mali_pm_initialize(void) +{ + mali_pm_lock_execute_state_change = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_ORDERED |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_PM_EXECUTE); + + if (NULL != mali_pm_lock_execute_state_change ) + { + mali_pm_lock_set_next_state = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ONELOCK| _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_LAST); + + if (NULL != mali_pm_lock_set_next_state) + { + mali_pm_lock_set_core_states = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_PM_CORE_STATE); + + if (NULL != mali_pm_lock_set_core_states) + { + idle_timer = _mali_osk_timer_init(); + if (NULL != idle_timer) + { + wq_irq = _mali_osk_irq_init(_MALI_OSK_IRQ_NUMBER_PMM, + mali_pm_upper_half, + mali_pm_bottom_half, + NULL, + NULL, + (void *)NULL, + "Mali PM deferred work"); + if (NULL != wq_irq) + { + if (_MALI_OSK_ERR_OK == mali_platform_init()) + { +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON + _mali_osk_pm_dev_enable(); + mali_pm_powerup(); +#endif + return _MALI_OSK_ERR_OK; + } + + _mali_osk_irq_term(wq_irq); + } + + _mali_osk_timer_del(idle_timer); + _mali_osk_timer_term(idle_timer); + } + _mali_osk_lock_term(mali_pm_lock_set_core_states); + } + _mali_osk_lock_term(mali_pm_lock_set_next_state); + } + _mali_osk_lock_term(mali_pm_lock_execute_state_change); + } + + return _MALI_OSK_ERR_FAULT; +} + +void mali_pm_terminate(void) +{ + mali_platform_deinit(); + _mali_osk_irq_term(wq_irq); + _mali_osk_timer_del(idle_timer); + _mali_osk_timer_term(idle_timer); + _mali_osk_lock_term(mali_pm_lock_execute_state_change); + _mali_osk_lock_term(mali_pm_lock_set_next_state); + _mali_osk_lock_term(mali_pm_lock_set_core_states); +} + + +inline void mali_pm_lock(void) +{ + _mali_osk_lock_wait(mali_pm_lock_set_next_state, _MALI_OSK_LOCKMODE_RW); +} + +inline void mali_pm_unlock(void) +{ + _mali_osk_lock_signal(mali_pm_lock_set_next_state, _MALI_OSK_LOCKMODE_RW); +} + +inline void mali_pm_execute_state_change_lock(void) +{ + _mali_osk_lock_wait(mali_pm_lock_execute_state_change,_MALI_OSK_LOCKMODE_RW); +} + +inline void mali_pm_execute_state_change_unlock(void) +{ + _mali_osk_lock_signal(mali_pm_lock_execute_state_change, _MALI_OSK_LOCKMODE_RW); +} + +static void mali_pm_powerup(void) +{ +#if !MALI_PMM_RUNTIME_JOB_CONTROL_ON + MALI_DEBUG_PRINT(3, ("Mali PM: Setting GPU power mode to MALI_POWER_MODE_ON\n")); + mali_platform_power_mode_change(MALI_POWER_MODE_ON); +#else + /* Aquire our reference */ + _mali_osk_pm_dev_activate(); +#endif + mali_group_power_on(); +} + +static void mali_pm_powerdown(mali_power_mode power_mode) +{ + if ( (MALI_PM_LEVEL_1_ON == current_level) || (MALI_PM_LEVEL_2_STANDBY == current_level) ) + { + mali_group_power_off(); + } + +#if !MALI_PMM_RUNTIME_JOB_CONTROL_ON + mali_platform_power_mode_change(power_mode); +#else + _mali_osk_pm_dev_idle(); + + if (MALI_POWER_MODE_DEEP_SLEEP == power_mode) + { + mali_platform_power_mode_change(power_mode); + } +#endif +} + +mali_bool mali_pm_is_powered_on(void) +{ + mali_bool is_on = MALI_TRUE; + + if( ! (MALI_PM_SCHEME_ALWAYS_ON == current_scheme || MALI_PM_SCHEME_DYNAMIC == current_scheme) ) + { + is_on = MALI_FALSE; + } + else if ( ! (MALI_PM_LEVEL_1_ON == current_level || MALI_PM_LEVEL_2_STANDBY == current_level)) + { + is_on = MALI_FALSE; + } + else if ( ! (MALI_PM_LEVEL_1_ON == next_level_dynamic || MALI_PM_LEVEL_2_STANDBY == next_level_dynamic)) + { + is_on = MALI_FALSE; + } + + return is_on; +} + +MALI_DEBUG_CODE( +static const char *state_as_string(enum mali_pm_level level) +{ + switch(level) + { + case MALI_PM_LEVEL_1_ON: + return "MALI_PM_LEVEL_1_ON"; + case MALI_PM_LEVEL_2_STANDBY: + return "MALI_PM_LEVEL_2_STANDBY"; + case MALI_PM_LEVEL_3_LIGHT_SLEEP: + return "MALI_PM_LEVEL_3_LIGHT_SLEEP"; + case MALI_PM_LEVEL_4_DEEP_SLEEP: + return "MALI_PM_LEVEL_4_DEEP_SLEEP"; + default: + return "UNKNOWN LEVEL"; + } +}); + +/* This could be used from another thread (work queue), if we need that */ +static void mali_pm_process_next(void) +{ + enum mali_pm_level pm_level_to_set; + + _mali_osk_lock_wait(mali_pm_lock_execute_state_change, _MALI_OSK_LOCKMODE_RW); + + pm_level_to_set = current_level; + + if (MALI_PM_SCHEME_DYNAMIC == current_scheme) + { + pm_level_to_set = next_level_dynamic; + + MALI_DEBUG_PRINT(4, ("Mali PM: Dynamic scheme; Changing Mali GPU power state from %s to: %s\n", state_as_string(current_level), state_as_string(pm_level_to_set))); + + if (current_level == pm_level_to_set) + { + goto end_function; /* early out, no change in power level */ + } + + /* Start timers according to new state, so we get STANDBY -> LIGHT_SLEEP -> DEEP_SLEEP */ + + if (MALI_TRUE == idle_timer_running) + { + /* There is an existing timeout, so delete it */ + _mali_osk_timer_del(idle_timer); + idle_timer_running = MALI_FALSE; + } + + /* Making sure that we turn on through the platform file + Since it was turned OFF directly through the platform file. + This might lead to double turn-on, but the plaform file supports that.*/ + if ( current_level == MALI_PM_LEVEL_4_DEEP_SLEEP) + { + mali_pm_powerup(); + mali_kernel_core_wakeup(); + + } + if (MALI_PM_LEVEL_1_ON == pm_level_to_set) + { + if (MALI_PM_LEVEL_2_STANDBY != current_level) + { + /* We only need to do anything if we came from one of the sleeping states */ + mali_pm_powerup(); + + /* Wake up Mali cores since we came from a sleep state */ + mali_kernel_core_wakeup(); + } + } + else if (MALI_PM_LEVEL_2_STANDBY == pm_level_to_set) + { + /* This is just an internal state, so we don't bother to report it to the platform file */ + idle_timer_running = MALI_TRUE; + _mali_osk_timer_setcallback(idle_timer, timeout_light_sleep, (void*) mali_pm_event_number_get()); + _mali_osk_timer_add(idle_timer, _mali_osk_time_mstoticks(MALI_PM_LIGHT_SLEEP_TIMEOUT)); + } + else if (MALI_PM_LEVEL_3_LIGHT_SLEEP == pm_level_to_set) + { + mali_pm_powerdown(MALI_POWER_MODE_LIGHT_SLEEP); + } + else if (MALI_PM_LEVEL_4_DEEP_SLEEP == pm_level_to_set) + { + MALI_DEBUG_PRINT(2, ("Mali PM: Setting GPU power mode to MALI_POWER_MODE_DEEP_SLEEP\n")); + mali_pm_powerdown(MALI_POWER_MODE_DEEP_SLEEP); + } + } + else if (MALI_PM_SCHEME_OS_SUSPENDED == current_scheme) + { + MALI_DEBUG_PRINT(4, ("Mali PM: OS scheme; Changing Mali GPU power state from %s to: %s\n", state_as_string(current_level), state_as_string(MALI_PM_LEVEL_4_DEEP_SLEEP))); + + pm_level_to_set = MALI_PM_LEVEL_4_DEEP_SLEEP; + + if (current_level == pm_level_to_set) + { + goto end_function; /* early out, no change in power level */ + } + + /* Cancel any timers */ + if (MALI_TRUE == idle_timer_running) + { + /* There is an existing timeout, so delete it */ + _mali_osk_timer_del(idle_timer); + idle_timer_running = MALI_FALSE; + } + + MALI_DEBUG_PRINT(2, ("Mali PM: Setting GPU power mode to MALI_POWER_MODE_DEEP_SLEEP\n")); + mali_pm_powerdown(MALI_POWER_MODE_DEEP_SLEEP); + next_level_dynamic = current_level; + } + else if (MALI_PM_SCHEME_ALWAYS_ON == current_scheme) + { + MALI_DEBUG_PRINT(4, ("Mali PM: Always on scheme; Changing Mali GPU power state from %s to: %s\n", state_as_string(current_level), state_as_string(MALI_PM_LEVEL_1_ON))); + + pm_level_to_set = MALI_PM_LEVEL_1_ON; + if (current_level == pm_level_to_set) + { + goto end_function; /* early out, no change in power level */ + } + + MALI_DEBUG_PRINT(2, ("Mali PM: Setting GPU power mode to MALI_POWER_MODE_ON\n")); + mali_pm_powerup(); + if (MALI_PM_LEVEL_2_STANDBY != current_level) + { + /* Wake up Mali cores since we came from a sleep state */ + mali_kernel_core_wakeup(); + } + } + else + { + MALI_PRINT_ERROR(("MALI PM: Illegal scheme")); + } + + current_level = pm_level_to_set; + +end_function: + _mali_osk_lock_signal(mali_pm_lock_execute_state_change, _MALI_OSK_LOCKMODE_RW); + +} + +void mali_pm_always_on(mali_bool enable) +{ + if (MALI_TRUE == enable) + { + /* The event is processed in current thread synchronously */ + mali_pm_event(MALI_PM_EVENT_SCHEME_ALWAYS_ON, MALI_FALSE, 0 ); + } + else + { + /* The event is processed in current thread synchronously */ + mali_pm_event(MALI_PM_EVENT_SCHEME_DYNAMIC_CONTROLL, MALI_FALSE, 0 ); + } +} + +static _mali_osk_errcode_t mali_pm_upper_half(void *data) +{ + /* not used */ + return _MALI_OSK_ERR_OK; +} + +static void mali_pm_bottom_half(void *data) +{ + mali_pm_process_next(); +} + +static u32 mali_pm_event_number_get(void) +{ + u32 retval; + + mali_pm_lock(); /* spinlock: mali_pm_lock_set_next_state */ + retval = ++mali_pm_event_number; + if (0==retval ) retval = ++mali_pm_event_number; + mali_pm_unlock(); + + return retval; +} + +static void mali_pm_event(enum mali_pm_event pm_event, mali_bool schedule_work, u32 timer_time ) +{ + mali_pm_lock(); /* spinlock: mali_pm_lock_set_next_state */ + /* Only timer events should set this variable, all other events must set it to zero. */ + if ( 0 != timer_time ) + { + MALI_DEBUG_ASSERT( (pm_event==MALI_PM_EVENT_TIMER_LIGHT_SLEEP) || (pm_event==MALI_PM_EVENT_TIMER_DEEP_SLEEP) ); + if ( mali_pm_event_number != timer_time ) + { + /* In this case there have been processed newer events since the timer event was set up. + If so we always ignore the timing event */ + mali_pm_unlock(); + return; + } + } + else + { + /* Delete possible ongoing timers + if ( (MALI_PM_LEVEL_2_STANDBY==current_level) || (MALI_PM_LEVEL_3_LIGHT_SLEEP==current_level) ) + { + _mali_osk_timer_del(idle_timer); + } + */ + } + mali_pm_event_number++; + switch (pm_event) + { + case MALI_PM_EVENT_CORES_WORKING: + next_level_dynamic = MALI_PM_LEVEL_1_ON; + MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme ); + break; + case MALI_PM_EVENT_CORES_IDLE: + next_level_dynamic = MALI_PM_LEVEL_2_STANDBY; + /*MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme );*/ + break; + case MALI_PM_EVENT_TIMER_LIGHT_SLEEP: + MALI_DEBUG_ASSERT( MALI_PM_SCHEME_ALWAYS_ON != current_scheme ); + MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme ); + next_level_dynamic = MALI_PM_LEVEL_3_LIGHT_SLEEP; + break; + case MALI_PM_EVENT_TIMER_DEEP_SLEEP: + MALI_DEBUG_ASSERT( MALI_PM_SCHEME_ALWAYS_ON != current_scheme ); + MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme ); + next_level_dynamic = MALI_PM_LEVEL_4_DEEP_SLEEP; + break; + case MALI_PM_EVENT_OS_SUSPEND: + MALI_DEBUG_ASSERT( MALI_PM_SCHEME_ALWAYS_ON != current_scheme ); + MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme ); + current_scheme = MALI_PM_SCHEME_OS_SUSPENDED; + next_level_dynamic = MALI_PM_LEVEL_4_DEEP_SLEEP; /* Dynamic scheme will go into level when we are resumed */ + break; + case MALI_PM_EVENT_OS_RESUME: + MALI_DEBUG_ASSERT(MALI_PM_SCHEME_OS_SUSPENDED == current_scheme ); + current_scheme = MALI_PM_SCHEME_DYNAMIC; + break; + case MALI_PM_EVENT_SCHEME_ALWAYS_ON: + MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme ); + current_scheme = MALI_PM_SCHEME_ALWAYS_ON; + break; + case MALI_PM_EVENT_SCHEME_DYNAMIC_CONTROLL: + MALI_DEBUG_ASSERT( MALI_PM_SCHEME_ALWAYS_ON == current_scheme || MALI_PM_SCHEME_DYNAMIC == current_scheme ); + current_scheme = MALI_PM_SCHEME_DYNAMIC; + break; + default: + MALI_DEBUG_PRINT_ERROR(("Unknown next state.")); + mali_pm_unlock(); + return; + } + mali_pm_unlock(); + + if (MALI_TRUE == schedule_work) + { + _mali_osk_irq_schedulework(wq_irq); + } + else + { + mali_pm_process_next(); + } +} + +static void timeout_light_sleep(void* arg) +{ + /* State change only if no newer power events have happend from the time in arg. + Actual work will be scheduled on worker thread. */ + mali_pm_event(MALI_PM_EVENT_TIMER_LIGHT_SLEEP, MALI_TRUE, (u32) arg); +} + +void mali_pm_core_event(enum mali_core_event core_event) +{ + mali_bool transition_working = MALI_FALSE; + mali_bool transition_idle = MALI_FALSE; + + _mali_osk_lock_wait(mali_pm_lock_set_core_states, _MALI_OSK_LOCKMODE_RW); + + switch (core_event) + { + case MALI_CORE_EVENT_GP_START: + if (num_active_pps + num_active_gps == 0) + { + transition_working = MALI_TRUE; + } + num_active_gps++; + break; + case MALI_CORE_EVENT_GP_STOP: + if (num_active_pps + num_active_gps == 1) + { + transition_idle = MALI_TRUE; + } + num_active_gps--; + break; + case MALI_CORE_EVENT_PP_START: + if (num_active_pps + num_active_gps == 0) + { + transition_working = MALI_TRUE; + } + num_active_pps++; + break; + case MALI_CORE_EVENT_PP_STOP: + if (num_active_pps + num_active_gps == 1) + { + transition_idle = MALI_TRUE; + } + num_active_pps--; + break; + } + + if (transition_working == MALI_TRUE) + { +#ifdef CONFIG_MALI400_GPU_UTILIZATION + mali_utilization_core_start(_mali_osk_time_get_ns()); +#endif + mali_pm_event(MALI_PM_EVENT_CORES_WORKING, MALI_FALSE, 0); /* process event in same thread */ + } + else if (transition_idle == MALI_TRUE) + { +#ifdef CONFIG_MALI400_GPU_UTILIZATION + mali_utilization_core_end(_mali_osk_time_get_ns()); +#endif + mali_pm_event(MALI_PM_EVENT_CORES_IDLE, MALI_FALSE, 0); /* process event in same thread */ + } + + _mali_osk_lock_signal(mali_pm_lock_set_core_states, _MALI_OSK_LOCKMODE_RW); +} + +void mali_pm_os_suspend(void) +{ + MALI_DEBUG_PRINT(2, ("Mali PM: OS suspending...\n")); + + mali_gp_scheduler_suspend(); + mali_pp_scheduler_suspend(); + mali_pm_event(MALI_PM_EVENT_OS_SUSPEND, MALI_FALSE, 0); /* process event in same thread */ + + MALI_DEBUG_PRINT(2, ("Mali PM: OS suspend completed\n")); +} + +void mali_pm_os_resume(void) +{ + MALI_DEBUG_PRINT(2, ("Mali PM: OS resuming...\n")); + + mali_pm_event(MALI_PM_EVENT_OS_RESUME, MALI_FALSE, 0); /* process event in same thread */ + mali_gp_scheduler_resume(); + mali_pp_scheduler_resume(); + + MALI_DEBUG_PRINT(2, ("Mali PM: OS resume completed\n")); +} + +void mali_pm_runtime_suspend(void) +{ + MALI_DEBUG_PRINT(2, ("Mali PM: OS runtime suspended\n")); + mali_platform_power_mode_change(MALI_POWER_MODE_LIGHT_SLEEP); +} + +void mali_pm_runtime_resume(void) +{ + MALI_DEBUG_PRINT(2, ("Mali PM: OS runtime resumed\n")); + mali_platform_power_mode_change(MALI_POWER_MODE_ON); +} diff --git a/drivers/media/video/samsung/mali/common/mali_pm.h b/drivers/media/video/samsung/mali/common/mali_pm.h new file mode 100644 index 0000000..d4ccfde --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_pm.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_PM_H__ +#define __MALI_PM_H__ + +#include "mali_osk.h" + +enum mali_core_event +{ + MALI_CORE_EVENT_GP_START, + MALI_CORE_EVENT_GP_STOP, + MALI_CORE_EVENT_PP_START, + MALI_CORE_EVENT_PP_STOP +}; + +enum mali_pm_event +{ + MALI_PM_EVENT_CORES_WORKING, + MALI_PM_EVENT_CORES_IDLE, + MALI_PM_EVENT_TIMER_LIGHT_SLEEP, + MALI_PM_EVENT_TIMER_DEEP_SLEEP, + MALI_PM_EVENT_OS_SUSPEND, + MALI_PM_EVENT_OS_RESUME, + MALI_PM_EVENT_SCHEME_ALWAYS_ON, + MALI_PM_EVENT_SCHEME_DYNAMIC_CONTROLL, +}; + +_mali_osk_errcode_t mali_pm_initialize(void); +void mali_pm_terminate(void); +void mali_pm_always_on(mali_bool enable); + +void mali_pm_lock(void); +void mali_pm_unlock(void); +void mali_pm_execute_state_change_lock(void); + +void mali_pm_execute_state_change_unlock(void); + +mali_bool mali_pm_is_powered_on(void); + +void mali_pm_core_event(enum mali_core_event core_event); + +void mali_pm_os_suspend(void); +void mali_pm_os_resume(void); +void mali_pm_runtime_suspend(void); +void mali_pm_runtime_resume(void); + + +#endif /* __MALI_PM_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_pmu.c b/drivers/media/video/samsung/mali/common/mali_pmu.c new file mode 100644 index 0000000..348b5dc --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_pmu.c @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_pmu.c + * Mali driver functions for Mali 400 PMU hardware + */ +#include "mali_hw_core.h" +#include "mali_pmu.h" +#include "mali_pp.h" +#include "mali_kernel_common.h" +#include "mali_osk.h" + +static u32 mali_pmu_detect_mask(u32 number_of_pp_cores, u32 number_of_l2_caches); + +/** @brief MALI inbuilt PMU hardware info and PMU hardware has knowledge of cores power mask + */ +struct mali_pmu_core +{ + struct mali_hw_core hw_core; + u32 mali_registered_cores_power_mask; +}; + +static struct mali_pmu_core *mali_global_pmu_core = NULL; + +/** @brief Register layout for hardware PMU + */ +typedef enum { + PMU_REG_ADDR_MGMT_POWER_UP = 0x00, /*< Power up register */ + PMU_REG_ADDR_MGMT_POWER_DOWN = 0x04, /*< Power down register */ + PMU_REG_ADDR_MGMT_STATUS = 0x08, /*< Core sleep status register */ + PMU_REG_ADDR_MGMT_INT_MASK = 0x0C, /*< Interrupt mask register */ + PMU_REGISTER_ADDRESS_SPACE_SIZE = 0x10, /*< Size of register space */ +} pmu_reg_addr_mgmt_addr; + +struct mali_pmu_core *mali_pmu_create(_mali_osk_resource_t *resource, u32 number_of_pp_cores, u32 number_of_l2_caches) +{ + struct mali_pmu_core* pmu; + + MALI_DEBUG_ASSERT(NULL == mali_global_pmu_core); + MALI_DEBUG_PRINT(2, ("Mali PMU: Creating Mali PMU core\n")); + + pmu = (struct mali_pmu_core *)_mali_osk_malloc(sizeof(struct mali_pmu_core)); + if (NULL != pmu) + { + pmu->mali_registered_cores_power_mask = mali_pmu_detect_mask(number_of_pp_cores, number_of_l2_caches); + if (_MALI_OSK_ERR_OK == mali_hw_core_create(&pmu->hw_core, resource, PMU_REGISTER_ADDRESS_SPACE_SIZE)) + { + if (_MALI_OSK_ERR_OK == mali_pmu_reset(pmu)) + { + mali_global_pmu_core = pmu; + return pmu; + } + mali_hw_core_delete(&pmu->hw_core); + } + _mali_osk_free(pmu); + } + + return NULL; +} + +void mali_pmu_delete(struct mali_pmu_core *pmu) +{ + MALI_DEBUG_ASSERT_POINTER(pmu); + + mali_hw_core_delete(&pmu->hw_core); + _mali_osk_free(pmu); + pmu = NULL; +} + +_mali_osk_errcode_t mali_pmu_reset(struct mali_pmu_core *pmu) +{ + /* Don't use interrupts - just poll status */ + mali_hw_core_register_write(&pmu->hw_core, PMU_REG_ADDR_MGMT_INT_MASK, 0); + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t mali_pmu_powerdown_all(struct mali_pmu_core *pmu) +{ + u32 stat; + u32 timeout; + + MALI_DEBUG_ASSERT_POINTER(pmu); + MALI_DEBUG_ASSERT( pmu->mali_registered_cores_power_mask != 0 ); + MALI_DEBUG_PRINT( 4, ("Mali PMU: power down (0x%08X)\n", pmu->mali_registered_cores_power_mask) ); + + mali_hw_core_register_write(&pmu->hw_core, PMU_REG_ADDR_MGMT_POWER_DOWN, pmu->mali_registered_cores_power_mask); + + /* Wait for cores to be powered down (100 x 100us = 100ms) */ + timeout = 100; + do + { + /* Get status of sleeping cores */ + stat = mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_STATUS); + stat &= pmu->mali_registered_cores_power_mask; + if( stat == pmu->mali_registered_cores_power_mask ) break; /* All cores we wanted are now asleep */ + _mali_osk_time_ubusydelay(100); + timeout--; + } while( timeout > 0 ); + + if( timeout == 0 ) + { + return _MALI_OSK_ERR_TIMEOUT; + } + + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t mali_pmu_powerup_all(struct mali_pmu_core *pmu) +{ + u32 stat; + u32 timeout; + + MALI_DEBUG_ASSERT_POINTER(pmu); + MALI_DEBUG_ASSERT( pmu->mali_registered_cores_power_mask != 0 ); /* Shouldn't be zero */ + MALI_DEBUG_PRINT( 4, ("Mali PMU: power up (0x%08X)\n", pmu->mali_registered_cores_power_mask) ); + + mali_hw_core_register_write(&pmu->hw_core, PMU_REG_ADDR_MGMT_POWER_UP, pmu->mali_registered_cores_power_mask); + + /* Wait for cores to be powered up (100 x 100us = 100ms) */ + timeout = 100; + do + { + /* Get status of sleeping cores */ + stat = mali_hw_core_register_read(&pmu->hw_core,PMU_REG_ADDR_MGMT_STATUS); + stat &= pmu->mali_registered_cores_power_mask; + if( stat == 0 ) break; /* All cores we wanted are now awake */ + _mali_osk_time_ubusydelay(100); + timeout--; + } while( timeout > 0 ); + + if( timeout == 0 ) + { + return _MALI_OSK_ERR_TIMEOUT; + } + + return _MALI_OSK_ERR_OK; +} + +struct mali_pmu_core *mali_pmu_get_global_pmu_core(void) +{ + return mali_global_pmu_core; +} + +static u32 mali_pmu_detect_mask(u32 number_of_pp_cores, u32 number_of_l2_caches) +{ + u32 mask = 0; + + if (number_of_l2_caches == 1) + { + /* Mali-300 or Mali-400 */ + u32 i; + + /* GP */ + mask = 0x01; + + /* L2 cache */ + mask |= 0x01<<1; + + /* Set bit for each PP core */ + for (i = 0; i < number_of_pp_cores; i++) + { + mask |= 0x01<<(i+2); + } + } + else if (number_of_l2_caches > 1) + { + /* Mali-450 */ + + /* GP (including its L2 cache) */ + mask = 0x01; + + /* There is always at least one PP (including its L2 cache) */ + mask |= 0x01<<1; + + /* Additional PP cores in same L2 cache */ + if (number_of_pp_cores >= 2) + { + mask |= 0x01<<2; + } + + /* Additional PP cores in a third L2 cache */ + if (number_of_pp_cores >= 5) + { + mask |= 0x01<<3; + } + } + + MALI_DEBUG_PRINT(4, ("Mali PMU: Power mask is 0x%08X (%u + %u)\n", mask, number_of_pp_cores, number_of_l2_caches)); + + return mask; +} diff --git a/drivers/media/video/samsung/mali/common/mali_pmu.h b/drivers/media/video/samsung/mali/common/mali_pmu.h new file mode 100644 index 0000000..fd10c08 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_pmu.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_platform.h + * Platform specific Mali driver functions + */ + +#include "mali_osk.h" + +struct mali_pmu_core; + +/** @brief Initialisation of MALI PMU + * + * This is called from entry point of the driver in order to create and intialize the PMU resource + * + * @param resource it will be a pointer to a PMU resource + * @param number_of_pp_cores Number of found PP resources in configuration + * @param number_of_l2_caches Number of found L2 cache resources in configuration + * @return The created PMU object, or NULL in case of failure. + */ +struct mali_pmu_core *mali_pmu_create(_mali_osk_resource_t *resource, u32 number_of_pp_cores, u32 number_of_l2_caches); + +/** @brief It deallocates the PMU resource + * + * This is called on the exit of the driver to terminate the PMU resource + * + * @param pmu Pointer to PMU core object to delete + */ +void mali_pmu_delete(struct mali_pmu_core *pmu); + +/** @brief Reset PMU core + * + * @param pmu Pointer to PMU core object to reset + * @return _MALI_OSK_ERR_OK on success, otherwise failure. + */ +_mali_osk_errcode_t mali_pmu_reset(struct mali_pmu_core *pmu); + +/** @brief MALI GPU power down using MALI in-built PMU + * + * called to power down all cores + * + * @param pmu Pointer to PMU core object to power down + * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. + */ +_mali_osk_errcode_t mali_pmu_powerdown_all(struct mali_pmu_core *pmu); + + +/** @brief MALI GPU power up using MALI in-built PMU + * + * called to power up all cores + * + * @param pmu Pointer to PMU core object to power up + * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. + */ +_mali_osk_errcode_t mali_pmu_powerup_all(struct mali_pmu_core *pmu); + + +/** @brief Retrieves the Mali PMU core object (if any) + * + * @return The Mali PMU object, or NULL if no PMU exists. + */ +struct mali_pmu_core *mali_pmu_get_global_pmu_core(void); diff --git a/drivers/media/video/samsung/mali/common/mali_pp.c b/drivers/media/video/samsung/mali/common/mali_pp.c new file mode 100644 index 0000000..5549f82 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_pp.c @@ -0,0 +1,710 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_pp.h" +#include "mali_hw_core.h" +#include "mali_group.h" +#include "mali_osk.h" +#include "regs/mali_200_regs.h" +#include "mali_kernel_common.h" +#include "mali_kernel_core.h" +#if MALI_TIMELINE_PROFILING_ENABLED +#include "mali_osk_profiling.h" +#endif + +/* See mali_gp.c file for description on how to handle the interrupt mask. + * This is how to do it on PP: mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED); + */ + +#define MALI_MAX_NUMBER_OF_PP_CORES 8 + +/** + * Definition of the PP core struct + * Used to track a PP core in the system. + */ +struct mali_pp_core +{ + struct mali_hw_core hw_core; /**< Common for all HW cores */ + struct mali_group *group; /**< Parent group for this core */ + _mali_osk_irq_t *irq; /**< IRQ handler */ + u32 core_id; /**< Unique core ID */ + struct mali_pp_job *running_job; /**< Current running (super) job */ + u32 running_sub_job; /**< Current running sub job */ + _mali_osk_timer_t *timeout_timer; /**< timeout timer for this core */ + u32 timeout_job_id; /**< job id for the timed out job - relevant only if pp_core_timed_out == MALI_TRUE */ + mali_bool core_timed_out; /**< if MALI_TRUE, this pp core has timed out; if MALI_FALSE, no timeout on this pp core */ + u32 counter_src0; /**< Performance counter 0, MALI_HW_CORE_NO_COUNTER for disabled */ + u32 counter_src1; /**< Performance counter 1, MALI_HW_CORE_NO_COUNTER for disabled */ + u32 counter_src0_used; /**< The selected performance counter 0 when a job is running */ + u32 counter_src1_used; /**< The selected performance counter 1 when a job is running */ +}; + +static struct mali_pp_core* mali_global_pp_cores[MALI_MAX_NUMBER_OF_PP_CORES]; +static u32 mali_global_num_pp_cores = 0; + +/* Interrupt handlers */ +static _mali_osk_errcode_t mali_pp_upper_half(void *data); +static void mali_pp_bottom_half(void *data); +static void mali_pp_irq_probe_trigger(void *data); +static _mali_osk_errcode_t mali_pp_irq_probe_ack(void *data); +static void mali_pp_post_process_job(struct mali_pp_core *core); +static void mali_pp_timeout(void *data); + +struct mali_pp_core *mali_pp_create(const _mali_osk_resource_t *resource, struct mali_group *group) +{ + struct mali_pp_core* core = NULL; + + MALI_DEBUG_PRINT(2, ("Mali PP: Creating Mali PP core: %s\n", resource->description)); + MALI_DEBUG_PRINT(2, ("Mali PP: Base address of PP core: 0x%x\n", resource->base)); + + if (mali_global_num_pp_cores >= MALI_MAX_NUMBER_OF_PP_CORES) + { + MALI_PRINT_ERROR(("Mali PP: Too many PP core objects created\n")); + return NULL; + } + + core = _mali_osk_malloc(sizeof(struct mali_pp_core)); + if (NULL != core) + { + core->group = group; + core->core_id = mali_global_num_pp_cores; + core->running_job = NULL; + core->counter_src0 = MALI_HW_CORE_NO_COUNTER; + core->counter_src1 = MALI_HW_CORE_NO_COUNTER; + core->counter_src0_used = MALI_HW_CORE_NO_COUNTER; + core->counter_src1_used = MALI_HW_CORE_NO_COUNTER; + if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALI200_REG_SIZEOF_REGISTER_BANK)) + { + _mali_osk_errcode_t ret; + + mali_group_lock(group); + ret = mali_pp_reset(core); + mali_group_unlock(group); + + if (_MALI_OSK_ERR_OK == ret) + { + /* Setup IRQ handlers (which will do IRQ probing if needed) */ + core->irq = _mali_osk_irq_init(resource->irq, + mali_pp_upper_half, + mali_pp_bottom_half, + mali_pp_irq_probe_trigger, + mali_pp_irq_probe_ack, + core, + "mali_pp_irq_handlers"); + if (NULL != core->irq) + { + /* Initialise the timeout timer */ + core->timeout_timer = _mali_osk_timer_init(); + if(NULL != core->timeout_timer) + { + _mali_osk_timer_setcallback(core->timeout_timer, mali_pp_timeout, (void *)core); + + mali_global_pp_cores[mali_global_num_pp_cores] = core; + mali_global_num_pp_cores++; + + return core; + } + else + { + MALI_PRINT_ERROR(("Failed to setup timeout timer for PP core %s\n", core->hw_core.description)); + /* Release IRQ handlers */ + _mali_osk_irq_term(core->irq); + } + } + else + { + MALI_PRINT_ERROR(("Mali PP: Failed to setup interrupt handlers for PP core %s\n", core->hw_core.description)); + } + } + mali_hw_core_delete(&core->hw_core); + } + + _mali_osk_free(core); + } + else + { + MALI_PRINT_ERROR(("Mali PP: Failed to allocate memory for PP core\n")); + } + + return NULL; +} + +void mali_pp_delete(struct mali_pp_core *core) +{ + u32 i; + + MALI_DEBUG_ASSERT_POINTER(core); + + _mali_osk_timer_term(core->timeout_timer); + _mali_osk_irq_term(core->irq); + mali_hw_core_delete(&core->hw_core); + + /* Remove core from global list */ + for (i = 0; i < mali_global_num_pp_cores; i++) + { + if (mali_global_pp_cores[i] == core) + { + mali_global_pp_cores[i] = NULL; + mali_global_num_pp_cores--; + break; + } + } + + _mali_osk_free(core); +} + +void mali_pp_stop_bus(struct mali_pp_core *core) +{ + MALI_DEBUG_ASSERT_POINTER(core); + /* Will only send the stop bus command, and not wait for it to complete */ + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_STOP_BUS); +} + +_mali_osk_errcode_t mali_pp_stop_bus_wait(struct mali_pp_core *core) +{ + int i; + const int request_loop_count = 20; + + MALI_DEBUG_ASSERT_POINTER(core); + MALI_ASSERT_GROUP_LOCKED(core->group); + + /* Send the stop bus command. */ + mali_pp_stop_bus(core); + + /* Wait for bus to be stopped */ + for (i = 0; i < request_loop_count; i++) + { + if (mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS) & MALI200_REG_VAL_STATUS_BUS_STOPPED) + break; + _mali_osk_time_ubusydelay(10); + } + + if (request_loop_count == i) + { + MALI_PRINT_ERROR(("Mali PP: Failed to stop bus on %s. Status: 0x%08x\n", core->hw_core.description, mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS))); + return _MALI_OSK_ERR_FAULT; + } + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t mali_pp_hard_reset(struct mali_pp_core *core) +{ + /* Bus must be stopped before calling this function */ + const int reset_finished_loop_count = 15; + const u32 reset_invalid_value = 0xC0FFE000; + const u32 reset_check_value = 0xC01A0000; + int i; + + MALI_DEBUG_ASSERT_POINTER(core); + MALI_DEBUG_PRINT(2, ("Mali PP: Hard reset of core %s\n", core->hw_core.description)); + MALI_ASSERT_GROUP_LOCKED(core->group); + + mali_pp_post_process_job(core); /* @@@@ is there some cases where it is unsafe to post process the job here? */ + + /* Set register to a bogus value. The register will be used to detect when reset is complete */ + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, reset_invalid_value); + + /* Force core to reset */ + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_FORCE_RESET); + + /* Wait for reset to be complete */ + for (i = 0; i < reset_finished_loop_count; i++) + { + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, reset_check_value); + if (reset_check_value == mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW)) + { + break; + } + _mali_osk_time_ubusydelay(10); + } + + if (i == reset_finished_loop_count) + { + MALI_PRINT_ERROR(("Mali PP: The hard reset loop didn't work, unable to recover\n")); + } + + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, 0x00000000); /* set it back to the default */ + /* Re-enable interrupts */ + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL); + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED); + + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t mali_pp_reset(struct mali_pp_core *core) +{ + int i; + const int request_loop_count = 20; + + MALI_DEBUG_ASSERT_POINTER(core); + MALI_DEBUG_PRINT(4, ("Mali PP: Reset of core %s\n", core->hw_core.description)); + MALI_ASSERT_GROUP_LOCKED(core->group); + + mali_pp_post_process_job(core); /* @@@@ is there some cases where it is unsafe to post process the job here? */ + + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, 0); /* disable the IRQs */ + +#if defined(USING_MALI200) + + /* On Mali-200, stop the bus, then do a hard reset of the core */ + + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_STOP_BUS); + + for (i = 0; i < request_loop_count; i++) + { + if (mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS) & MALI200_REG_VAL_STATUS_BUS_STOPPED) + { + break; + } + _mali_osk_time_ubusydelay(10); + } + + if (request_loop_count == i) + { + MALI_PRINT_ERROR(("Mali PP: Failed to stop bus for core %s, unable to recover\n", core->hw_core.description)); + return _MALI_OSK_ERR_FAULT ; + } + + /* the bus was stopped OK, do the hard reset */ + mali_pp_hard_reset(core); + +#elif defined(USING_MALI400) + + /* Mali-300 and Mali-400 have a safe reset command which we use */ + + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI400PP_REG_VAL_IRQ_RESET_COMPLETED); + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI400PP_REG_VAL_CTRL_MGMT_SOFT_RESET); + + for (i = 0; i < request_loop_count; i++) + { + if (mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT) & MALI400PP_REG_VAL_IRQ_RESET_COMPLETED) + { + break; + } + _mali_osk_time_ubusydelay(10); + } + + if (request_loop_count == i) + { + MALI_DEBUG_PRINT(2, ("Mali PP: Failed to reset core %s, Status: 0x%08x\n", core->hw_core.description, mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS))); + return _MALI_OSK_ERR_FAULT; + } +#else +#error "no supported mali core defined" +#endif + + /* Re-enable interrupts */ + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL); + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED); + + return _MALI_OSK_ERR_OK; +} + +void mali_pp_job_start(struct mali_pp_core *core, struct mali_pp_job *job, u32 sub_job) +{ + u32 *frame_registers = mali_pp_job_get_frame_registers(job); + u32 *wb0_registers = mali_pp_job_get_wb0_registers(job); + u32 *wb1_registers = mali_pp_job_get_wb1_registers(job); + u32 *wb2_registers = mali_pp_job_get_wb2_registers(job); + core->counter_src0_used = core->counter_src0; + core->counter_src1_used = core->counter_src1; + + MALI_DEBUG_ASSERT_POINTER(core); + MALI_ASSERT_GROUP_LOCKED(core->group); + + mali_hw_core_register_write_array_relaxed(&core->hw_core, MALI200_REG_ADDR_FRAME, frame_registers, MALI200_NUM_REGS_FRAME); + if (0 != sub_job) + { + /* + * There are two frame registers which are different for each sub job. + * For the first sub job, these are correctly represented in the frame register array, + * but we need to patch these for all other sub jobs + */ + mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_FRAME, mali_pp_job_get_addr_frame(job, sub_job)); + mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_STACK, mali_pp_job_get_addr_stack(job, sub_job)); + } + + if (wb0_registers[0]) /* M200_WB0_REG_SOURCE_SELECT register */ + { + mali_hw_core_register_write_array_relaxed(&core->hw_core, MALI200_REG_ADDR_WB0, wb0_registers, MALI200_NUM_REGS_WBx); + } + + if (wb1_registers[0]) /* M200_WB1_REG_SOURCE_SELECT register */ + { + mali_hw_core_register_write_array_relaxed(&core->hw_core, MALI200_REG_ADDR_WB1, wb1_registers, MALI200_NUM_REGS_WBx); + } + + if (wb2_registers[0]) /* M200_WB2_REG_SOURCE_SELECT register */ + { + mali_hw_core_register_write_array_relaxed(&core->hw_core, MALI200_REG_ADDR_WB2, wb2_registers, MALI200_NUM_REGS_WBx); + } + + /* This selects which performance counters we are reading */ + if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used || MALI_HW_CORE_NO_COUNTER != core->counter_src1_used) + { + /* global_config has enabled HW counters, this will override anything specified by user space */ + if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used) + { + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used); + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE); + } + if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used) + { + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used); + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE); + } + } + else + { + /* Use HW counters from job object, if any */ + u32 perf_counter_flag = mali_pp_job_get_perf_counter_flag(job); + if (0 != perf_counter_flag) + { + if (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE) + { + core->counter_src0_used = mali_pp_job_get_perf_counter_src0(job); + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used); + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE); + } + + if (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE) + { + core->counter_src1_used = mali_pp_job_get_perf_counter_src1(job); + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used); + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE); + } + } + } + + MALI_DEBUG_PRINT(3, ("Mali PP: Starting job 0x%08X part %u/%u on PP core %s\n", job, sub_job + 1, mali_pp_job_get_sub_job_count(job), core->hw_core.description)); + + /* Adding barrier to make sure all rester writes are finished */ + _mali_osk_write_mem_barrier(); + + /* This is the command that starts the core. */ + mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_START_RENDERING); + + /* Adding barrier to make sure previous rester writes is finished */ + _mali_osk_write_mem_barrier(); + + /* Setup the timeout timer value and save the job id for the job running on the pp core */ + _mali_osk_timer_add(core->timeout_timer, _mali_osk_time_mstoticks(mali_max_job_runtime)); + core->timeout_job_id = mali_pp_job_get_id(job); + +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_id) | MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH, job->frame_builder_id, job->flush_id, 0, 0, 0); + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_id), job->pid, job->tid, 0, 0, 0); +#endif + + core->running_job = job; + core->running_sub_job = sub_job; +} + +u32 mali_pp_core_get_version(struct mali_pp_core *core) +{ + MALI_DEBUG_ASSERT_POINTER(core); + return mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_VERSION); +} + +u32 mali_pp_core_get_id(struct mali_pp_core *core) +{ + MALI_DEBUG_ASSERT_POINTER(core); + return core->core_id; +} + +mali_bool mali_pp_core_set_counter_src0(struct mali_pp_core *core, u32 counter) +{ + MALI_DEBUG_ASSERT_POINTER(core); + + core->counter_src0 = counter; + return MALI_TRUE; +} + +mali_bool mali_pp_core_set_counter_src1(struct mali_pp_core *core, u32 counter) +{ + MALI_DEBUG_ASSERT_POINTER(core); + + core->counter_src1 = counter; + return MALI_TRUE; +} + +u32 mali_pp_core_get_counter_src0(struct mali_pp_core *core) +{ + MALI_DEBUG_ASSERT_POINTER(core); + return core->counter_src0; +} + +u32 mali_pp_core_get_counter_src1(struct mali_pp_core *core) +{ + MALI_DEBUG_ASSERT_POINTER(core); + return core->counter_src1; +} + +struct mali_pp_core* mali_pp_get_global_pp_core(u32 index) +{ + if (MALI_MAX_NUMBER_OF_PP_CORES > index) + { + return mali_global_pp_cores[index]; + } + + return NULL; +} + +u32 mali_pp_get_glob_num_pp_cores(void) +{ + return mali_global_num_pp_cores; +} + +u32 mali_pp_get_max_num_pp_cores(void) +{ + return MALI_MAX_NUMBER_OF_PP_CORES; +} + +/* ------------- interrupt handling below ------------------ */ +static _mali_osk_errcode_t mali_pp_upper_half(void *data) +{ + struct mali_pp_core *core = (struct mali_pp_core *)data; + u32 irq_readout; + + irq_readout = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_STATUS); + if (MALI200_REG_VAL_IRQ_MASK_NONE != irq_readout) + { + /* Mask out all IRQs from this core until IRQ is handled */ + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_NONE); + +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_id)|MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT, irq_readout, 0, 0, 0, 0); +#endif + + /* We do need to handle this in a bottom half */ + _mali_osk_irq_schedulework(core->irq); + return _MALI_OSK_ERR_OK; + } + + return _MALI_OSK_ERR_FAULT; +} + +static void mali_pp_bottom_half(void *data) +{ + struct mali_pp_core *core = (struct mali_pp_core *)data; + u32 irq_readout; + u32 irq_errors; + +#if MALI_TIMELINE_PROFILING_ENABLED +#if 0 /* Bottom half TLP logging is currently not supported */ + _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_START| MALI_PROFILING_EVENT_CHANNEL_SOFTWARE , _mali_osk_get_pid(), _mali_osk_get_tid(), 0, 0, 0); +#endif +#endif + + mali_group_lock(core->group); /* Group lock grabbed in core handlers, but released in common group handler */ + + if ( MALI_FALSE == mali_group_power_is_on(core->group) ) + { + MALI_PRINT_ERROR(("Interrupt bottom half of %s when core is OFF.", core->hw_core.description)); + mali_group_unlock(core->group); + return; + } + + irq_readout = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT) & MALI200_REG_VAL_IRQ_MASK_USED; + + MALI_DEBUG_PRINT(4, ("Mali PP: Bottom half IRQ 0x%08X from core %s\n", irq_readout, core->hw_core.description)); + + if (irq_readout & MALI200_REG_VAL_IRQ_END_OF_FRAME) + { + mali_pp_post_process_job(core); + MALI_DEBUG_PRINT(3, ("Mali PP: Job completed, calling group handler\n")); + mali_group_bottom_half(core->group, GROUP_EVENT_PP_JOB_COMPLETED); /* Will release group lock */ + return; + } + + /* + * Now lets look at the possible error cases (IRQ indicating error or timeout) + * END_OF_FRAME and HANG interrupts are not considered error. + */ + irq_errors = irq_readout & ~(MALI200_REG_VAL_IRQ_END_OF_FRAME|MALI200_REG_VAL_IRQ_HANG); + if (0 != irq_errors) + { + mali_pp_post_process_job(core); + MALI_PRINT_ERROR(("Mali PP: Unknown interrupt 0x%08X from core %s, aborting job\n", + irq_readout, core->hw_core.description)); + mali_group_bottom_half(core->group, GROUP_EVENT_PP_JOB_FAILED); /* Will release group lock */ + return; + } + else if (MALI_TRUE == core->core_timed_out) /* SW timeout */ + { + if (core->timeout_job_id == mali_pp_job_get_id(core->running_job)) + { + mali_pp_post_process_job(core); + MALI_DEBUG_PRINT(2, ("Mali PP: Job %d timed out on core %s\n", + mali_pp_job_get_id(core->running_job), core->hw_core.description)); + mali_group_bottom_half(core->group, GROUP_EVENT_PP_JOB_TIMED_OUT); /* Will release group lock */ + } + else + { + mali_group_unlock(core->group); + } + core->core_timed_out = MALI_FALSE; + return; + } + else if (irq_readout & MALI200_REG_VAL_IRQ_HANG) + { + /* Just ignore hang interrupts, the job timer will detect hanging jobs anyways */ + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_HANG); + } + + /* + * The only way to get here is if we got a HANG interrupt, which we ignore. + * Re-enable interrupts and let core continue to run + */ + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED); + mali_group_unlock(core->group); + +#if MALI_TIMELINE_PROFILING_ENABLED +#if 0 /* Bottom half TLP logging is currently not supported */ + _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_STOP| MALI_PROFILING_EVENT_CHANNEL_SOFTWARE , _mali_osk_get_pid(), _mali_osk_get_tid(), 0, 0, 0); +#endif +#endif +} + +static void mali_pp_irq_probe_trigger(void *data) +{ + struct mali_pp_core *core = (struct mali_pp_core *)data; + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED); /* @@@@ This should not be needed */ + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT, MALI200_REG_VAL_IRQ_FORCE_HANG); + _mali_osk_mem_barrier(); +} + +static _mali_osk_errcode_t mali_pp_irq_probe_ack(void *data) +{ + struct mali_pp_core *core = (struct mali_pp_core *)data; + u32 irq_readout; + + irq_readout = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_STATUS); + if (MALI200_REG_VAL_IRQ_FORCE_HANG & irq_readout) + { + mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_FORCE_HANG); + _mali_osk_mem_barrier(); + return _MALI_OSK_ERR_OK; + } + + return _MALI_OSK_ERR_FAULT; +} + + +/* ------ local helper functions below --------- */ +static void mali_pp_post_process_job(struct mali_pp_core *core) +{ + MALI_ASSERT_GROUP_LOCKED(core->group); + + if (NULL != core->running_job) + { + u32 val0 = 0; + u32 val1 = 0; +#if MALI_TIMELINE_PROFILING_ENABLED + int counter_index = COUNTER_FP0_C0 + (2 * core->core_id); +#endif + + if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used) + { + val0 = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE); + if (mali_pp_job_get_perf_counter_flag(core->running_job) && + _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE && mali_pp_job_get_perf_counter_src0(core->running_job) == core->counter_src0_used) + { + /* We retrieved the counter that user space asked for, so return the value through the job object */ + mali_pp_job_set_perf_counter_value0(core->running_job, core->running_sub_job, val0); + } + else + { + /* User space asked for a counter, but this is not what we retrived (overridden by counter src set on core) */ + mali_pp_job_set_perf_counter_value0(core->running_job, core->running_sub_job, MALI_HW_CORE_INVALID_VALUE); + } + +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_report_hw_counter(counter_index, val0); +#endif + } + + if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used) + { + val1 = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE); + if (mali_pp_job_get_perf_counter_flag(core->running_job) && + _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE && mali_pp_job_get_perf_counter_src1(core->running_job) == core->counter_src1_used) + { + /* We retrieved the counter that user space asked for, so return the value through the job object */ + mali_pp_job_set_perf_counter_value1(core->running_job, core->running_sub_job, val1); + } + else + { + /* User space asked for a counter, but this is not what we retrived (overridden by counter src set on core) */ + mali_pp_job_set_perf_counter_value1(core->running_job, core->running_sub_job, MALI_HW_CORE_INVALID_VALUE); + } + +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_report_hw_counter(counter_index + 1, val1); +#endif + } + +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_id), + val0, val1, core->counter_src0_used | (core->counter_src1_used << 8), 0, 0); +#endif + + /* We are no longer running a job... */ + core->running_job = NULL; + _mali_osk_timer_del(core->timeout_timer); + } +} + +/* callback function for pp core timeout */ +static void mali_pp_timeout(void *data) +{ + struct mali_pp_core * core = ((struct mali_pp_core *)data); + + MALI_DEBUG_PRINT(3, ("Mali PP: TIMEOUT callback \n")); + core->core_timed_out = MALI_TRUE; + _mali_osk_irq_schedulework(core->irq); +} + +#if 0 +static void mali_pp_print_registers(struct mali_pp_core *core) +{ + MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_VERSION = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_VERSION))); + MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_CURRENT_REND_LIST_ADDR = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_CURRENT_REND_LIST_ADDR))); + MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS))); + MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_RAWSTAT = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT))); + MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_MASK = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK))); + MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_STATUS))); + MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_BUS_ERROR_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_BUS_ERROR_STATUS))); + MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE))); + MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC))); + MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE))); + MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE))); + MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC))); + MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE))); +} +#endif + +#if 0 +void mali_pp_print_state(struct mali_pp_core *core) +{ + MALI_DEBUG_PRINT(2, ("Mali PP: State: 0x%08x\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS) )); +} +#endif + +#if MALI_STATE_TRACKING +u32 mali_pp_dump_state(struct mali_pp_core *core, char *buf, u32 size) +{ + int n = 0; + + n += _mali_osk_snprintf(buf + n, size - n, "\tPP #%d: %s\n", core->core_id, core->hw_core.description); + + return n; +} +#endif diff --git a/drivers/media/video/samsung/mali/common/mali_pp.h b/drivers/media/video/samsung/mali/common/mali_pp.h new file mode 100644 index 0000000..9b425a0 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_pp.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_PP_H__ +#define __MALI_PP_H__ + +#include "mali_osk.h" +#include "mali_pp_job.h" + +struct mali_pp_core; +struct mali_group; + +_mali_osk_errcode_t mali_pp_initialize(void); +void mali_pp_terminate(void); + +struct mali_pp_core *mali_pp_create(const _mali_osk_resource_t * resource, struct mali_group *group); +void mali_pp_delete(struct mali_pp_core *core); + +void mali_pp_stop_bus(struct mali_pp_core *core); +_mali_osk_errcode_t mali_pp_stop_bus_wait(struct mali_pp_core *core); +_mali_osk_errcode_t mali_pp_reset(struct mali_pp_core *core); +_mali_osk_errcode_t mali_pp_hard_reset(struct mali_pp_core *core); + +void mali_pp_job_start(struct mali_pp_core *core, struct mali_pp_job *job, u32 sub_job); + +u32 mali_pp_core_get_version(struct mali_pp_core *core); + +u32 mali_pp_core_get_id(struct mali_pp_core *core); + +mali_bool mali_pp_core_set_counter_src0(struct mali_pp_core *core, u32 counter); +mali_bool mali_pp_core_set_counter_src1(struct mali_pp_core *core, u32 counter); +u32 mali_pp_core_get_counter_src0(struct mali_pp_core *core); +u32 mali_pp_core_get_counter_src1(struct mali_pp_core *core); +struct mali_pp_core* mali_pp_get_global_pp_core(u32 index); +u32 mali_pp_get_glob_num_pp_cores(void); +u32 mali_pp_get_max_num_pp_cores(void); +/* Debug */ +u32 mali_pp_dump_state(struct mali_pp_core *core, char *buf, u32 size); + +#endif /* __MALI_PP_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_pp_job.c b/drivers/media/video/samsung/mali/common/mali_pp_job.c new file mode 100644 index 0000000..47b8a0a --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_pp_job.c @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_pp_job.h" +#include "mali_osk.h" +#include "mali_osk_list.h" +#include "mali_kernel_common.h" +#include "mali_uk_types.h" + +struct mali_pp_job *mali_pp_job_create(struct mali_session_data *session, _mali_uk_pp_start_job_s *args, u32 id) +{ + struct mali_pp_job *job; + + if (args->num_cores > _MALI_PP_MAX_SUB_JOBS) + { + MALI_PRINT_ERROR(("Mali PP job: Too many sub jobs specified in job object\n")); + return NULL; + } + + job = _mali_osk_malloc(sizeof(struct mali_pp_job)); + if (NULL != job) + { + u32 i; + _mali_osk_list_init(&job->list); + job->session = session; + job->id = id; + job->user_id = args->user_job_ptr; + job->barrier = args->flags & _MALI_PP_JOB_FLAG_BARRIER ? MALI_TRUE : MALI_FALSE; + job->active_barrier = job->barrier; + job->no_notification = args->flags & _MALI_PP_JOB_FLAG_NO_NOTIFICATION ? MALI_TRUE : MALI_FALSE; + _mali_osk_memcpy(job->frame_registers, args->frame_registers, sizeof(job->frame_registers)); + _mali_osk_memcpy(job->frame_registers_addr_frame, args->frame_registers_addr_frame, sizeof(job->frame_registers_addr_frame)); + _mali_osk_memcpy(job->frame_registers_addr_stack, args->frame_registers_addr_stack, sizeof(job->frame_registers_addr_stack)); + + /* Only copy write back registers for the units that are enabled */ + job->wb0_registers[0] = 0; + job->wb1_registers[0] = 0; + job->wb2_registers[0] = 0; + if (args->wb0_registers[0]) /* M200_WB0_REG_SOURCE_SELECT register */ + { + _mali_osk_memcpy(job->wb0_registers, args->wb0_registers, sizeof(job->wb0_registers)); + } + if (args->wb1_registers[0]) /* M200_WB1_REG_SOURCE_SELECT register */ + { + _mali_osk_memcpy(job->wb1_registers, args->wb1_registers, sizeof(job->wb1_registers)); + } + if (args->wb2_registers[0]) /* M200_WB2_REG_SOURCE_SELECT register */ + { + _mali_osk_memcpy(job->wb2_registers, args->wb2_registers, sizeof(job->wb2_registers)); + } + + job->perf_counter_flag = args->perf_counter_flag; + job->perf_counter_src0 = args->perf_counter_src0; + job->perf_counter_src1 = args->perf_counter_src1; + for (i = 0; i < args->num_cores; i++) + { + job->perf_counter_value0[i] = 0; + job->perf_counter_value1[i] = 0; + } + job->sub_job_count = args->num_cores; + job->sub_jobs_started = 0; + job->sub_jobs_completed = 0; + job->sub_job_errors = 0; + + job->pid = _mali_osk_get_pid(); + job->tid = _mali_osk_get_tid(); + job->frame_builder_id = args->frame_builder_id; + job->flush_id = args->flush_id; + + return job; + } + + return NULL; +} + +void mali_pp_job_delete(struct mali_pp_job *job) +{ + _mali_osk_free(job); +} + +_mali_osk_errcode_t mali_pp_job_check(struct mali_pp_job *job) +{ + if ((0 == job->frame_registers[0]) || (0 == job->frame_registers[1])) + { + return _MALI_OSK_ERR_FAULT; + } + return _MALI_OSK_ERR_OK; +} diff --git a/drivers/media/video/samsung/mali/common/mali_pp_job.h b/drivers/media/video/samsung/mali/common/mali_pp_job.h new file mode 100644 index 0000000..4399c1d --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_pp_job.h @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_PP_JOB_H__ +#define __MALI_PP_JOB_H__ + +#include "mali_osk.h" +#include "mali_osk_list.h" +#include "mali_uk_types.h" +#include "mali_session.h" +#include "mali_kernel_common.h" +#include "regs/mali_200_regs.h" + +/** + * The structure represends a PP job, including all sub-jobs + * (This struct unfortunatly needs to be public because of how the _mali_osk_list_* + * mechanism works) + */ +struct mali_pp_job +{ + _mali_osk_list_t list; /**< Used to link jobs together in the scheduler queue */ + struct mali_session_data *session; /**< Session which submitted this job */ + u32 id; /**< identifier for this job in kernel space (sequencial numbering) */ + u32 user_id; /**< identifier for the job in user space */ + u32 frame_registers[_MALI_PP_MAX_FRAME_REGISTERS]; /**< core specific registers associated with this job, see ARM DDI0415A */ + u32 frame_registers_addr_frame[_MALI_PP_MAX_SUB_JOBS - 1]; /**< ADDR_FRAME registers for sub job 1-7 */ + u32 frame_registers_addr_stack[_MALI_PP_MAX_SUB_JOBS - 1]; /**< ADDR_STACK registers for sub job 1-7 */ + u32 wb0_registers[_MALI_PP_MAX_WB_REGISTERS]; /**< Write back unit 0 registers */ + u32 wb1_registers[_MALI_PP_MAX_WB_REGISTERS]; /**< Write back unit 1 registers */ + u32 wb2_registers[_MALI_PP_MAX_WB_REGISTERS]; /**< Write back unit 2 registers */ + u32 perf_counter_flag; /**< bitmask indicating which performance counters to enable, see \ref _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE and related macro definitions */ + u32 perf_counter_src0; /**< Source id for performance counter 0 (see ARM DDI0415A, Table 3-60) */ + u32 perf_counter_src1; /**< Source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */ + u32 perf_counter_value0[_MALI_PP_MAX_SUB_JOBS]; /**< Value of performance counter 0 (to be returned to user space), one for each sub job */ + u32 perf_counter_value1[_MALI_PP_MAX_SUB_JOBS]; /**< Value of performance counter 1 (to be returned to user space), one for each sub job */ + u32 sub_job_count; /**< Total number of sub-jobs in this superjob */ + u32 sub_jobs_started; /**< Total number of sub-jobs started (always started in ascending order) */ + u32 sub_jobs_completed; /**< Number of completed sub-jobs in this superjob */ + u32 sub_job_errors; /**< Bitfield with errors (errors for each single sub-job is or'ed together) */ + u32 pid; /**< Process ID of submitting process */ + u32 tid; /**< Thread ID of submitting thread */ + u32 frame_builder_id; /**< id of the originating frame builder */ + u32 flush_id; /**< flush id within the originating frame builder */ + mali_bool barrier; /**< [in] MALI_TRUE means wait for all my previous jobs to complete before scheduling this one */ + mali_bool active_barrier; /**< [in] Changes from MALI_TRUE to MALI_FALSE when barrier has been resolved */ + mali_bool no_notification; /**< [in] MALI_TRUE means do not notify user space when this job has completed */ +}; + +struct mali_pp_job *mali_pp_job_create(struct mali_session_data *session, _mali_uk_pp_start_job_s *args, u32 id); +void mali_pp_job_delete(struct mali_pp_job *job); + +_mali_osk_errcode_t mali_pp_job_check(struct mali_pp_job *job); + +/****************************************************** + * simple utility functions for dealing with pp jobs: + *****************************************************/ + +MALI_STATIC_INLINE u32 mali_pp_job_get_id(struct mali_pp_job *job) +{ + return (NULL == job) ? 0 : job->id; +} + +MALI_STATIC_INLINE u32 mali_pp_job_get_user_id(struct mali_pp_job *job) +{ + return job->user_id; +} + +MALI_STATIC_INLINE u32 mali_pp_job_get_frame_builder_id(struct mali_pp_job *job) +{ + return job->frame_builder_id; +} + +MALI_STATIC_INLINE u32 mali_pp_job_get_flush_id(struct mali_pp_job *job) +{ + return job->flush_id; +} + +MALI_STATIC_INLINE u32* mali_pp_job_get_frame_registers(struct mali_pp_job *job) +{ + return job->frame_registers; +} + +MALI_STATIC_INLINE u32 mali_pp_job_get_addr_frame(struct mali_pp_job *job, u32 sub_job) +{ + if (sub_job == 0) + { + return job->frame_registers[MALI200_REG_ADDR_FRAME / sizeof(u32)]; + } + else if (sub_job < _MALI_PP_MAX_SUB_JOBS) + { + return job->frame_registers_addr_frame[sub_job - 1]; + } + + return 0; +} + +MALI_STATIC_INLINE u32 mali_pp_job_get_addr_stack(struct mali_pp_job *job, u32 sub_job) +{ + if (sub_job == 0) + { + return job->frame_registers[MALI200_REG_ADDR_STACK / sizeof(u32)]; + } + else if (sub_job < _MALI_PP_MAX_SUB_JOBS) + { + return job->frame_registers_addr_stack[sub_job - 1]; + } + + return 0; +} + +MALI_STATIC_INLINE u32* mali_pp_job_get_wb0_registers(struct mali_pp_job *job) +{ + return job->wb0_registers; +} + +MALI_STATIC_INLINE u32* mali_pp_job_get_wb1_registers(struct mali_pp_job *job) +{ + return job->wb1_registers; +} + +MALI_STATIC_INLINE u32* mali_pp_job_get_wb2_registers(struct mali_pp_job *job) +{ + return job->wb2_registers; +} + +MALI_STATIC_INLINE void mali_pp_job_disable_wb0(struct mali_pp_job *job) +{ + job->wb0_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0; +} + +MALI_STATIC_INLINE void mali_pp_job_disable_wb1(struct mali_pp_job *job) +{ + job->wb1_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0; +} + +MALI_STATIC_INLINE void mali_pp_job_disable_wb2(struct mali_pp_job *job) +{ + job->wb2_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0; +} + +MALI_STATIC_INLINE struct mali_session_data *mali_pp_job_get_session(struct mali_pp_job *job) +{ + return job->session; +} + +MALI_STATIC_INLINE mali_bool mali_pp_job_has_unstarted_sub_jobs(struct mali_pp_job *job) +{ + return (job->sub_jobs_started < job->sub_job_count) ? MALI_TRUE : MALI_FALSE; +} + +/* Function used when we are terminating a session with jobs. Return TRUE if it has a rendering job. + Makes sure that no new subjobs is started. */ +MALI_STATIC_INLINE mali_bool mali_pp_job_is_currently_rendering_and_if_so_abort_new_starts(struct mali_pp_job *job) +{ + /* All can not be started, since then it would not be in the job queue */ + MALI_DEBUG_ASSERT( job->sub_jobs_started != job->sub_job_count ); + + /* If at least one job is started */ + if ( (job->sub_jobs_started > 0) ) + { + /* If at least one job is currently being rendered, and thus assigned to a group and core */ + if (job->sub_jobs_started > job->sub_jobs_completed ) + { + u32 jobs_remaining = job->sub_job_count - job->sub_jobs_started; + job->sub_jobs_started += jobs_remaining; + job->sub_jobs_completed += jobs_remaining; + job->sub_job_errors += jobs_remaining; + /* Returning TRUE indicating that we can not delete this job which is being redered */ + return MALI_TRUE; + } + } + /* The job is not being rendered to at the moment and can then safely be deleted */ + return MALI_FALSE; +} + +MALI_STATIC_INLINE mali_bool mali_pp_job_is_complete(struct mali_pp_job *job) +{ + return (job->sub_job_count == job->sub_jobs_completed) ? MALI_TRUE : MALI_FALSE; +} + +MALI_STATIC_INLINE u32 mali_pp_job_get_first_unstarted_sub_job(struct mali_pp_job *job) +{ + return job->sub_jobs_started; +} + +MALI_STATIC_INLINE u32 mali_pp_job_get_sub_job_count(struct mali_pp_job *job) +{ + return job->sub_job_count; +} + +MALI_STATIC_INLINE void mali_pp_job_mark_sub_job_started(struct mali_pp_job *job, u32 sub_job) +{ + /* Assert that we are marking the "first unstarted sub job" as started */ + MALI_DEBUG_ASSERT(job->sub_jobs_started == sub_job); + job->sub_jobs_started++; +} + +MALI_STATIC_INLINE void mali_pp_job_mark_sub_job_completed(struct mali_pp_job *job, mali_bool success) +{ + job->sub_jobs_completed++; + if ( MALI_FALSE == success ) + { + job->sub_job_errors++; + } +} + +MALI_STATIC_INLINE mali_bool mali_pp_job_was_success(struct mali_pp_job *job) +{ + if ( 0 == job->sub_job_errors ) + { + return MALI_TRUE; + } + return MALI_FALSE; +} + +MALI_STATIC_INLINE mali_bool mali_pp_job_has_active_barrier(struct mali_pp_job *job) +{ + return job->active_barrier; +} + +MALI_STATIC_INLINE void mali_pp_job_barrier_enforced(struct mali_pp_job *job) +{ + job->active_barrier = MALI_FALSE; +} + +MALI_STATIC_INLINE mali_bool mali_pp_job_use_no_notification(struct mali_pp_job *job) +{ + return job->no_notification; +} + +MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_flag(struct mali_pp_job *job) +{ + return job->perf_counter_flag; +} + +MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_src0(struct mali_pp_job *job) +{ + return job->perf_counter_src0; +} + +MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_src1(struct mali_pp_job *job) +{ + return job->perf_counter_src1; +} + +MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_value0(struct mali_pp_job *job, u32 sub_job) +{ + return job->perf_counter_value0[sub_job]; +} + +MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_value1(struct mali_pp_job *job, u32 sub_job) +{ + return job->perf_counter_value1[sub_job]; +} + +MALI_STATIC_INLINE void mali_pp_job_set_perf_counter_value0(struct mali_pp_job *job, u32 sub_job, u32 value) +{ + job->perf_counter_value0[sub_job] = value; +} + +MALI_STATIC_INLINE void mali_pp_job_set_perf_counter_value1(struct mali_pp_job *job, u32 sub_job, u32 value) +{ + job->perf_counter_value1[sub_job] = value; +} + +#endif /* __MALI_PP_JOB_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_pp_scheduler.c b/drivers/media/video/samsung/mali/common/mali_pp_scheduler.c new file mode 100644 index 0000000..a944055 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_pp_scheduler.c @@ -0,0 +1,594 @@ +/* + * Copyright (C) 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_pp_scheduler.h" +#include "mali_kernel_common.h" +#include "mali_osk.h" +#include "mali_osk_list.h" +#include "mali_scheduler.h" +#include "mali_pp.h" +#include "mali_pp_job.h" +#include "mali_group.h" +#include "mali_cluster.h" + +/* Maximum of 8 PP cores (a group can only have maximum of 1 PP core) */ +#define MALI_MAX_NUMBER_OF_PP_GROUPS 8 + +static mali_bool mali_pp_scheduler_is_suspended(void); + +enum mali_pp_slot_state +{ + MALI_PP_SLOT_STATE_IDLE, + MALI_PP_SLOT_STATE_WORKING, +}; + +/* A render slot is an entity which jobs can be scheduled onto */ +struct mali_pp_slot +{ + struct mali_group *group; + /* + * We keep track of the state here as well as in the group object + * so we don't need to take the group lock so often (and also avoid clutter with the working lock) + */ + enum mali_pp_slot_state state; + struct mali_session_data *session; +}; + +static u32 pp_version = 0; +static _MALI_OSK_LIST_HEAD(job_queue); /* List of jobs with some unscheduled work */ +static struct mali_pp_slot slots[MALI_MAX_NUMBER_OF_PP_GROUPS]; +static u32 num_slots = 0; +static u32 num_slots_idle = 0; + +/* Variables to allow safe pausing of the scheduler */ +static _mali_osk_wait_queue_t *pp_scheduler_working_wait_queue = NULL; +static u32 pause_count = 0; + +static _mali_osk_lock_t *pp_scheduler_lock = NULL; +/* Contains tid of thread that locked the scheduler or 0, if not locked */ +MALI_DEBUG_CODE(static u32 pp_scheduler_lock_owner = 0); + +_mali_osk_errcode_t mali_pp_scheduler_initialize(void) +{ + u32 i; + + _MALI_OSK_INIT_LIST_HEAD(&job_queue); + + pp_scheduler_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_SCHEDULER); + if (NULL == pp_scheduler_lock) + { + return _MALI_OSK_ERR_NOMEM; + } + + pp_scheduler_working_wait_queue = _mali_osk_wait_queue_init(); + if (NULL == pp_scheduler_working_wait_queue) + { + _mali_osk_lock_term(pp_scheduler_lock); + return _MALI_OSK_ERR_NOMEM; + } + + /* Find all the available PP cores */ + for (i = 0; i < mali_cluster_get_glob_num_clusters(); i++) + { + u32 group_id = 0; + struct mali_cluster *curr_cluster = mali_cluster_get_global_cluster(i); + struct mali_group *group = mali_cluster_get_group(curr_cluster, group_id); + while (NULL != group) + { + struct mali_pp_core *pp_core = mali_group_get_pp_core(group); + if (NULL != pp_core) + { + if (0 == pp_version) + { + /* Retrieve PP version from first avaiable PP core */ + pp_version = mali_pp_core_get_version(pp_core); + } + slots[num_slots].group = group; + slots[num_slots].state = MALI_PP_SLOT_STATE_IDLE; + slots[num_slots].session = NULL; + num_slots++; + num_slots_idle++; + } + group_id++; + group = mali_cluster_get_group(curr_cluster, group_id); + } + } + + return _MALI_OSK_ERR_OK; +} + +void mali_pp_scheduler_terminate(void) +{ + _mali_osk_wait_queue_term(pp_scheduler_working_wait_queue); + _mali_osk_lock_term(pp_scheduler_lock); +} + +MALI_STATIC_INLINE void mali_pp_scheduler_lock(void) +{ + if(_MALI_OSK_ERR_OK != _mali_osk_lock_wait(pp_scheduler_lock, _MALI_OSK_LOCKMODE_RW)) + { + /* Non-interruptable lock failed: this should never happen. */ + MALI_DEBUG_ASSERT(0); + } + MALI_DEBUG_PRINT(5, ("Mali PP scheduler: PP scheduler lock taken\n")); + MALI_DEBUG_ASSERT(0 == pp_scheduler_lock_owner); + MALI_DEBUG_CODE(pp_scheduler_lock_owner = _mali_osk_get_tid()); +} + +MALI_STATIC_INLINE void mali_pp_scheduler_unlock(void) +{ + MALI_DEBUG_PRINT(5, ("Mali PP scheduler: Releasing PP scheduler lock\n")); + MALI_DEBUG_ASSERT(_mali_osk_get_tid() == pp_scheduler_lock_owner); + MALI_DEBUG_CODE(pp_scheduler_lock_owner = 0); + _mali_osk_lock_signal(pp_scheduler_lock, _MALI_OSK_LOCKMODE_RW); +} + +#ifdef DEBUG +MALI_STATIC_INLINE void mali_pp_scheduler_assert_locked(void) +{ + MALI_DEBUG_ASSERT(_mali_osk_get_tid() == pp_scheduler_lock_owner); +} +#define MALI_ASSERT_PP_SCHEDULER_LOCKED() mali_pp_scheduler_assert_locked() +#else +#define MALI_ASSERT_PP_SCHEDULER_LOCKED() +#endif + +static mali_bool mali_pp_scheduler_session_has_running_jobs(struct mali_session_data *session) +{ + u32 i; + + MALI_ASSERT_PP_SCHEDULER_LOCKED(); + + if (num_slots_idle == num_slots) + { + return MALI_FALSE; + } + + for (i = 0; i < num_slots; i++) + { + if (MALI_PP_SLOT_STATE_WORKING == slots[i].state) + { + if (slots[i].session == session) + { + return MALI_TRUE; + } + } + } + + return MALI_FALSE; +} + +static void mali_pp_scheduler_schedule(void) +{ + u32 i; + struct mali_pp_job *job; +#if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS + struct mali_session_data * session; +#endif + + MALI_ASSERT_PP_SCHEDULER_LOCKED(); + + if (0 < pause_count || 0 == num_slots_idle || _mali_osk_list_empty(&job_queue)) + { + MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Nothing to schedule (paused=%u, idle slots=%u)\n", + pause_count, num_slots_idle)); + return; /* Nothing to do, so early out */ + } + + +#if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP + if ( num_slots_idle < num_slots ) + { + MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job not started, since only %d/%d cores are available\n", num_slots_idle,num_slots)); + return; + } +#endif + +#if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS + /* Finding initial session for the PP cores */ + job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_pp_job, list); + session = job->session; + if ( num_slots != num_slots_idle ) + { + for (i = 0; (i < num_slots) ; i++) + { + if ( slots[i].state == MALI_PP_SLOT_STATE_IDLE ) + { + continue; + } + session = mali_group_get_session(slots[i].group); + break; + } + } +#endif + + for (i = 0; (i < num_slots) && (0 < num_slots_idle); i++) + { + u32 sub_job; + + if (_mali_osk_list_empty(&job_queue)) /* move this check down to where we know we have started all sub jobs for this job??? */ + { + break; /* No more jobs to schedule, so early out */ + } + + if (MALI_PP_SLOT_STATE_IDLE != slots[i].state) + { + continue; + } + + job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_pp_job, list); + MALI_DEBUG_ASSERT(mali_pp_job_has_unstarted_sub_jobs(job)); /* All jobs on the job_queue should have unstarted sub jobs */ + + if (MALI_TRUE == mali_pp_job_has_active_barrier(job)) + { + if (MALI_TRUE == mali_pp_scheduler_session_has_running_jobs(mali_pp_job_get_session(job))) + { + /* There is already a running job from this session, so we need to enforce the barrier */ + return; + } + else + { + /* Barrier is now enforced, update job object so we don't delay execution of sub-jobs */ + mali_pp_job_barrier_enforced(job); + } + } + + #if MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED + if ( (0==job->sub_jobs_started) && (num_slots_idle < num_slots) && (job->sub_job_count > num_slots_idle)) + { + MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job with %d subjobs not started, since only %d/%d cores are available\n", job->sub_job_count, num_slots_idle,num_slots)); + return; + } + #endif + + #if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS + if ( job->session != session ) + { + MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job not started since existing job is from another application\n")); + return; + } + #endif + + sub_job = mali_pp_job_get_first_unstarted_sub_job(job); + + MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Starting job %u (0x%08X) part %u/%u\n", mali_pp_job_get_id(job), job, sub_job + 1, mali_pp_job_get_sub_job_count(job))); + if (_MALI_OSK_ERR_OK == mali_group_start_pp_job(slots[i].group, job, sub_job)) + { + MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job %u (0x%08X) part %u/%u started\n", mali_pp_job_get_id(job), job, sub_job + 1, mali_pp_job_get_sub_job_count(job))); + + /* Mark this sub job as started */ + mali_pp_job_mark_sub_job_started(job, sub_job); + + /* Mark slot as busy */ + slots[i].state = MALI_PP_SLOT_STATE_WORKING; + slots[i].session = mali_pp_job_get_session(job); + num_slots_idle--; + + if (!mali_pp_job_has_unstarted_sub_jobs(job)) + { + /* + * All sub jobs have now started for this job, remove this job from the job queue. + * The job will now only be referred to by the slots which are running it. + * The last slot to complete will make sure it is returned to user space. + */ + _mali_osk_list_del(&job->list); +#if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP + MALI_DEBUG_PRINT(6, ("Mali PP scheduler: Skip scheduling more jobs when MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP is set.\n")); + return; +#endif + } + } + else + { + MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Failed to start PP job\n")); + return; + } + } +} + +static void mali_pp_scheduler_return_job_to_user(struct mali_pp_job *job) +{ + if (MALI_FALSE == mali_pp_job_use_no_notification(job)) + { + _mali_osk_notification_t *notobj = _mali_osk_notification_create(_MALI_NOTIFICATION_PP_FINISHED, sizeof(_mali_uk_pp_job_finished_s)); + if (NULL != notobj) + { + u32 i; + u32 sub_jobs = mali_pp_job_get_sub_job_count(job); + mali_bool success = mali_pp_job_was_success(job); + + _mali_uk_pp_job_finished_s *jobres = notobj->result_buffer; + _mali_osk_memset(jobres, 0, sizeof(_mali_uk_pp_job_finished_s)); /* @@@@ can be removed once we initialize all members in this struct */ + jobres->user_job_ptr = mali_pp_job_get_user_id(job); + if (MALI_TRUE == success) + { + jobres->status = _MALI_UK_JOB_STATUS_END_SUCCESS; + } + else + { + jobres->status = _MALI_UK_JOB_STATUS_END_UNKNOWN_ERR; + } + + for (i = 0; i < sub_jobs; i++) + { + jobres->perf_counter0[i] = mali_pp_job_get_perf_counter_value0(job, i); + jobres->perf_counter1[i] = mali_pp_job_get_perf_counter_value1(job, i); + } + + mali_session_send_notification(mali_pp_job_get_session(job), notobj); + } + else + { + MALI_PRINT_ERROR(("Mali PP scheduler: Unable to allocate notification object\n")); + } + } + + mali_pp_job_delete(job); +} + +void mali_pp_scheduler_do_schedule(void) +{ + mali_pp_scheduler_lock(); + + mali_pp_scheduler_schedule(); + + mali_pp_scheduler_unlock(); +} + +void mali_pp_scheduler_job_done(struct mali_group *group, struct mali_pp_job *job, u32 sub_job, mali_bool success) +{ + u32 i; + mali_bool job_is_done; + + MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Job %u (0x%08X) part %u/%u completed (%s)\n", mali_pp_job_get_id(job), job, sub_job + 1, mali_pp_job_get_sub_job_count(job), success ? "success" : "failure")); + + mali_pp_scheduler_lock(); + + /* Find slot which was running this job */ + for (i = 0; i < num_slots; i++) + { + if (slots[i].group == group) + { + MALI_DEBUG_ASSERT(MALI_PP_SLOT_STATE_WORKING == slots[i].state); + slots[i].state = MALI_PP_SLOT_STATE_IDLE; + slots[i].session = NULL; + num_slots_idle++; + mali_pp_job_mark_sub_job_completed(job, success); + } + } + + /* If paused, then this was the last job, so wake up sleeping workers */ + if (pause_count > 0) + { + /* Wake up sleeping workers. Their wake-up condition is that + * num_slots == num_slots_idle, so unless we are done working, no + * threads will actually be woken up. + */ + _mali_osk_wait_queue_wake_up(pp_scheduler_working_wait_queue); + } + else + { + mali_pp_scheduler_schedule(); + } + + job_is_done = mali_pp_job_is_complete(job); + + mali_pp_scheduler_unlock(); + + if (job_is_done) + { + /* Send notification back to user space */ + MALI_DEBUG_PRINT(4, ("Mali PP scheduler: All parts completed for job %u (0x%08X)\n", mali_pp_job_get_id(job), job)); + mali_pp_scheduler_return_job_to_user(job); + } +} + +void mali_pp_scheduler_suspend(void) +{ + mali_pp_scheduler_lock(); + pause_count++; /* Increment the pause_count so that no more jobs will be scheduled */ + mali_pp_scheduler_unlock(); + + /*mali_pp_scheduler_working_lock();*/ + /* We have now aquired the working lock, which means that we have successfully paused the scheduler */ + /*mali_pp_scheduler_working_unlock();*/ + + /* go to sleep. When woken up again (in mali_pp_scheduler_job_done), the + * mali_pp_scheduler_suspended() function will be called. This will return true + * iff state is idle and pause_count > 0, so if the core is active this + * will not do anything. + */ + _mali_osk_wait_queue_wait_event(pp_scheduler_working_wait_queue, mali_pp_scheduler_is_suspended); +} + +void mali_pp_scheduler_resume(void) +{ + mali_pp_scheduler_lock(); + pause_count--; /* Decrement pause_count to allow scheduling again (if it reaches 0) */ + if (0 == pause_count) + { + mali_pp_scheduler_schedule(); + } + mali_pp_scheduler_unlock(); +} + +_mali_osk_errcode_t _mali_ukk_pp_start_job(_mali_uk_pp_start_job_s *args) +{ + struct mali_session_data *session; + struct mali_pp_job *job; + + MALI_DEBUG_ASSERT_POINTER(args); + MALI_DEBUG_ASSERT_POINTER(args->ctx); + + session = (struct mali_session_data*)args->ctx; + + job = mali_pp_job_create(session, args, mali_scheduler_get_new_id()); + if (NULL == job) + { + return _MALI_OSK_ERR_NOMEM; + } + + if (_MALI_OSK_ERR_OK != mali_pp_job_check(job)) + { + /* Not a valid job, return to user immediately */ + mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */ + mali_pp_scheduler_return_job_to_user(job); /* This will also delete the job object */ + return _MALI_OSK_ERR_OK; /* User is notified via a notification, so this call is ok */ + } + +#if PROFILING_SKIP_PP_JOBS || PROFILING_SKIP_PP_AND_GP_JOBS +#warning PP jobs will not be executed + mali_pp_scheduler_return_job_to_user(job); + return _MALI_OSK_ERR_OK; +#endif + + mali_pp_scheduler_lock(); + + _mali_osk_list_addtail(&job->list, &job_queue); + + MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Job %u (0x%08X) with %u parts queued\n", mali_pp_job_get_id(job), job, mali_pp_job_get_sub_job_count(job))); + + mali_pp_scheduler_schedule(); + + mali_pp_scheduler_unlock(); + + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t _mali_ukk_get_pp_number_of_cores(_mali_uk_get_pp_number_of_cores_s *args) +{ + MALI_DEBUG_ASSERT_POINTER(args); + MALI_DEBUG_ASSERT_POINTER(args->ctx); + args->number_of_cores = num_slots; + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t _mali_ukk_get_pp_core_version(_mali_uk_get_pp_core_version_s *args) +{ + MALI_DEBUG_ASSERT_POINTER(args); + MALI_DEBUG_ASSERT_POINTER(args->ctx); + args->version = pp_version; + return _MALI_OSK_ERR_OK; +} + +void _mali_ukk_pp_job_disable_wb(_mali_uk_pp_disable_wb_s *args) +{ + struct mali_session_data *session; + struct mali_pp_job *job; + struct mali_pp_job *tmp; + + MALI_DEBUG_ASSERT_POINTER(args); + MALI_DEBUG_ASSERT_POINTER(args->ctx); + + session = (struct mali_session_data*)args->ctx; + + mali_pp_scheduler_lock(); + + /* Check queue for jobs that match */ + _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &job_queue, struct mali_pp_job, list) + { + if (mali_pp_job_get_session(job) == session && + mali_pp_job_get_frame_builder_id(job) == (u32)args->fb_id && + mali_pp_job_get_flush_id(job) == (u32)args->flush_id) + { + if (args->wbx & _MALI_UK_PP_JOB_WB0) + { + mali_pp_job_disable_wb0(job); + } + if (args->wbx & _MALI_UK_PP_JOB_WB1) + { + mali_pp_job_disable_wb1(job); + } + if (args->wbx & _MALI_UK_PP_JOB_WB2) + { + mali_pp_job_disable_wb2(job); + } + break; + } + } + + mali_pp_scheduler_unlock(); +} + +void mali_pp_scheduler_abort_session(struct mali_session_data *session) +{ + struct mali_pp_job *job, *tmp; + int i; + + mali_pp_scheduler_lock(); + MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Aborting all jobs from session 0x%08x\n", session)); + + /* Check queue for jobs and remove */ + _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &job_queue, struct mali_pp_job, list) + { + if (mali_pp_job_get_session(job) == session) + { + _mali_osk_list_del(&(job->list)); + + if ( mali_pp_job_is_currently_rendering_and_if_so_abort_new_starts(job) ) + { + /* The job is in the render pipeline, we can not delete it yet. */ + /* It will be deleted in the mali_group_abort_session() call below */ + MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Keeping partially started PP job 0x%08x in queue\n", job)); + continue; + } + MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Removing PP job 0x%08x from queue\n", job)); + mali_pp_job_delete(job); + } + } + + mali_pp_scheduler_unlock(); + + /* Abort running jobs from this session */ + for (i = 0; i < num_slots; i++) + { + struct mali_group *group = slots[i].group; + + MALI_DEBUG_PRINT(5, ("PP sched abort: Looking at group 0x%08x\n", group)); + + if (MALI_PP_SLOT_STATE_WORKING == slots[i].state) + { + MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Aborting session 0x%08x from group 0x%08x\n", session, group)); + + mali_group_abort_session(group, session); + } + } +} + +static mali_bool mali_pp_scheduler_is_suspended(void) +{ + mali_bool ret; + + mali_pp_scheduler_lock(); + ret = pause_count > 0 && num_slots == num_slots_idle; + mali_pp_scheduler_unlock(); + + return ret; +} + +#if MALI_STATE_TRACKING +u32 mali_pp_scheduler_dump_state(char *buf, u32 size) +{ + int n = 0; + int i; + + n += _mali_osk_snprintf(buf + n, size - n, "PP:\n"); + n += _mali_osk_snprintf(buf + n, size - n, "\tQueue is %s\n", _mali_osk_list_empty(&job_queue) ? "empty" : "not empty"); + n += _mali_osk_snprintf(buf + n, size - n, "\n"); + + for (i = 0; i < num_slots; i++) + { + n += mali_group_dump_state(slots[i].group, buf + n, size - n); + n += _mali_osk_snprintf(buf + n, size - n, "\t\tState: %d\n", slots[i].state); + } + + return n; +} +#endif diff --git a/drivers/media/video/samsung/mali/common/mali_pp_scheduler.h b/drivers/media/video/samsung/mali/common/mali_pp_scheduler.h new file mode 100644 index 0000000..48eb3bd --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_pp_scheduler.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_PP_SCHEDULER_H__ +#define __MALI_PP_SCHEDULER_H__ + +#include "mali_osk.h" +#include "mali_cluster.h" +#include "mali_pp_job.h" + +_mali_osk_errcode_t mali_pp_scheduler_initialize(void); +void mali_pp_scheduler_terminate(void); + +void mali_pp_scheduler_do_schedule(void); +void mali_pp_scheduler_job_done(struct mali_group *group, struct mali_pp_job *job, u32 sub_job, mali_bool success); + +void mali_pp_scheduler_suspend(void); +void mali_pp_scheduler_resume(void); + +/** @brief Abort all PP jobs from session running or queued + * + * This functions aborts all PP jobs from the specified session. Queued jobs are removed from the queue and jobs + * currently running on a core will be aborted. + * + * @param session Pointer to session whose jobs should be aborted + */ +void mali_pp_scheduler_abort_session(struct mali_session_data *session); + +u32 mali_pp_scheduler_dump_state(char *buf, u32 size); + +#endif /* __MALI_PP_SCHEDULER_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_scheduler.c b/drivers/media/video/samsung/mali/common/mali_scheduler.c new file mode 100644 index 0000000..f360209 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_scheduler.c @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_kernel_common.h" +#include "mali_osk.h" + +static _mali_osk_atomic_t mali_job_autonumber; + +_mali_osk_errcode_t mali_scheduler_initialize(void) +{ + if ( _MALI_OSK_ERR_OK != _mali_osk_atomic_init(&mali_job_autonumber, 0)) + { + MALI_DEBUG_PRINT(1, ("Initialization of atomic job id counter failed.\n")); + return _MALI_OSK_ERR_FAULT; + } + + return _MALI_OSK_ERR_OK; +} + +void mali_scheduler_terminate(void) +{ + _mali_osk_atomic_term(&mali_job_autonumber); +} + +u32 mali_scheduler_get_new_id(void) +{ + u32 job_id = _mali_osk_atomic_inc_return(&mali_job_autonumber); + return job_id; +} + diff --git a/drivers/media/video/samsung/mali/common/mali_scheduler.h b/drivers/media/video/samsung/mali/common/mali_scheduler.h new file mode 100644 index 0000000..74f0947 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_scheduler.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_SCHEDULER_H__ +#define __MALI_SCHEDULER_H__ + +#include "mali_osk.h" + +_mali_osk_errcode_t mali_scheduler_initialize(void); +void mali_scheduler_terminate(void); + +u32 mali_scheduler_get_new_id(void); + +#endif /* __MALI_SCHEDULER_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_session.c b/drivers/media/video/samsung/mali/common/mali_session.c new file mode 100644 index 0000000..2394bb9 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_session.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_osk.h" +#include "mali_osk_list.h" +#include "mali_session.h" + +_MALI_OSK_LIST_HEAD(mali_sessions); + +_mali_osk_lock_t *mali_sessions_lock; + +_mali_osk_errcode_t mali_session_initialize(void) +{ + _MALI_OSK_INIT_LIST_HEAD(&mali_sessions); + + mali_sessions_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_ORDERED, 0, _MALI_OSK_LOCK_ORDER_SESSIONS); + + if (NULL == mali_sessions_lock) return _MALI_OSK_ERR_NOMEM; + + return _MALI_OSK_ERR_OK; +} + +void mali_session_terminate(void) +{ + _mali_osk_lock_term(mali_sessions_lock); +} + +void mali_session_add(struct mali_session_data *session) +{ + mali_session_lock(); + _mali_osk_list_add(&session->link, &mali_sessions); + mali_session_unlock(); +} + +void mali_session_remove(struct mali_session_data *session) +{ + mali_session_lock(); + _mali_osk_list_delinit(&session->link); + mali_session_unlock(); +} diff --git a/drivers/media/video/samsung/mali/common/mali_session.h b/drivers/media/video/samsung/mali/common/mali_session.h new file mode 100644 index 0000000..c8640b5 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_session.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_SESSION_H__ +#define __MALI_SESSION_H__ + +#include "mali_mmu_page_directory.h" +#include "mali_kernel_descriptor_mapping.h" +#include "mali_osk.h" +#include "mali_osk_list.h" + +struct mali_session_data +{ + _mali_osk_notification_queue_t * ioctl_queue; + + _mali_osk_lock_t *memory_lock; /**< Lock protecting the vm manipulation */ + mali_descriptor_mapping * descriptor_mapping; /**< Mapping between userspace descriptors and our pointers */ + _mali_osk_list_t memory_head; /**< Track all the memory allocated in this session, for freeing on abnormal termination */ + + struct mali_page_directory *page_directory; /**< MMU page directory for this session */ + + _MALI_OSK_LIST_HEAD(link); /**< Link for list of all sessions */ +}; + +_mali_osk_errcode_t mali_session_initialize(void); +void mali_session_terminate(void); + +/* List of all sessions. Actual list head in mali_kernel_core.c */ +extern _mali_osk_list_t mali_sessions; +/* Lock to protect modification and access to the mali_sessions list */ +extern _mali_osk_lock_t *mali_sessions_lock; + +MALI_STATIC_INLINE void mali_session_lock(void) +{ + _mali_osk_lock_wait(mali_sessions_lock, _MALI_OSK_LOCKMODE_RW); +} + +MALI_STATIC_INLINE void mali_session_unlock(void) +{ + _mali_osk_lock_signal(mali_sessions_lock, _MALI_OSK_LOCKMODE_RW); +} + +void mali_session_add(struct mali_session_data *session); +void mali_session_remove(struct mali_session_data *session); +#define MALI_SESSION_FOREACH(session, tmp, link) \ + _MALI_OSK_LIST_FOREACHENTRY(session, tmp, &mali_sessions, struct mali_session_data, link) + +MALI_STATIC_INLINE struct mali_page_directory *mali_session_get_page_directory(struct mali_session_data *session) +{ + return session->page_directory; +} + +MALI_STATIC_INLINE void mali_session_send_notification(struct mali_session_data *session, _mali_osk_notification_t *object) +{ + _mali_osk_notification_queue_send(session->ioctl_queue, object); +} + +#endif /* __MALI_SESSION_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_ukk.h b/drivers/media/video/samsung/mali/common/mali_ukk.h new file mode 100644 index 0000000..6b018d0 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_ukk.h @@ -0,0 +1,612 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_ukk.h + * Defines the kernel-side interface of the user-kernel interface + */ + +#ifndef __MALI_UKK_H__ +#define __MALI_UKK_H__ + +#include "mali_osk.h" +#include "mali_uk_types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @addtogroup uddapi Unified Device Driver (UDD) APIs + * + * @{ + */ + +/** + * @addtogroup u_k_api UDD User/Kernel Interface (U/K) APIs + * + * - The _mali_uk functions are an abstraction of the interface to the device + * driver. On certain OSs, this would be implemented via the IOCTL interface. + * On other OSs, it could be via extension of some Device Driver Class, or + * direct function call for Bare metal/RTOSs. + * - It is important to note that: + * - The Device Driver has implemented the _mali_ukk set of functions + * - The Base Driver calls the corresponding set of _mali_uku functions. + * - What requires porting is solely the calling mechanism from User-side to + * Kernel-side, and propagating back the results. + * - Each U/K function is associated with a (group, number) pair from + * \ref _mali_uk_functions to make it possible for a common function in the + * Base Driver and Device Driver to route User/Kernel calls from/to the + * correct _mali_uk function. For example, in an IOCTL system, the IOCTL number + * would be formed based on the group and number assigned to the _mali_uk + * function, as listed in \ref _mali_uk_functions. On the user-side, each + * _mali_uku function would just make an IOCTL with the IOCTL-code being an + * encoded form of the (group, number) pair. On the kernel-side, the Device + * Driver's IOCTL handler decodes the IOCTL-code back into a (group, number) + * pair, and uses this to determine which corresponding _mali_ukk should be + * called. + * - Refer to \ref _mali_uk_functions for more information about this + * (group, number) pairing. + * - In a system where there is no distinction between user and kernel-side, + * the U/K interface may be implemented as:@code + * MALI_STATIC_INLINE _mali_osk_errcode_t _mali_uku_examplefunction( _mali_uk_examplefunction_s *args ) + * { + * return mali_ukk_examplefunction( args ); + * } + * @endcode + * - Therefore, all U/K calls behave \em as \em though they were direct + * function calls (but the \b implementation \em need \em not be a direct + * function calls) + * + * @note Naming the _mali_uk functions the same on both User and Kernel sides + * on non-RTOS systems causes debugging issues when setting breakpoints. In + * this case, it is not clear which function the breakpoint is put on. + * Therefore the _mali_uk functions in user space are prefixed with \c _mali_uku + * and in kernel space with \c _mali_ukk. The naming for the argument + * structures is unaffected. + * + * - The _mali_uk functions are synchronous. + * - Arguments to the _mali_uk functions are passed in a structure. The only + * parameter passed to the _mali_uk functions is a pointer to this structure. + * This first member of this structure, ctx, is a pointer to a context returned + * by _mali_uku_open(). For example:@code + * typedef struct + * { + * void *ctx; + * u32 number_of_cores; + * } _mali_uk_get_gp_number_of_cores_s; + * @endcode + * + * - Each _mali_uk function has its own argument structure named after the + * function. The argument is distinguished by the _s suffix. + * - The argument types are defined by the base driver and user-kernel + * interface. + * - All _mali_uk functions return a standard \ref _mali_osk_errcode_t. + * - Only arguments of type input or input/output need be initialized before + * calling a _mali_uk function. + * - Arguments of type output and input/output are only valid when the + * _mali_uk function returns \ref _MALI_OSK_ERR_OK. + * - The \c ctx member is always invalid after it has been used by a + * _mali_uk function, except for the context management functions + * + * + * \b Interface \b restrictions + * + * The requirements of the interface mean that an implementation of the + * User-kernel interface may do no 'real' work. For example, the following are + * illegal in the User-kernel implementation: + * - Calling functions necessary for operation on all systems, which would + * not otherwise get called on RTOS systems. + * - For example, a U/K interface that calls multiple _mali_ukk functions + * during one particular U/K call. This could not be achieved by the same code + * which uses direct function calls for the U/K interface. + * - Writing in values to the args members, when otherwise these members would + * not hold a useful value for a direct function call U/K interface. + * - For example, U/K interface implementation that take NULL members in + * their arguments structure from the user side, but those members are + * replaced with non-NULL values in the kernel-side of the U/K interface + * implementation. A scratch area for writing data is one such example. In this + * case, a direct function call U/K interface would segfault, because no code + * would be present to replace the NULL pointer with a meaningful pointer. + * - Note that we discourage the case where the U/K implementation changes + * a NULL argument member to non-NULL, and then the Device Driver code (outside + * of the U/K layer) re-checks this member for NULL, and corrects it when + * necessary. Whilst such code works even on direct function call U/K + * intefaces, it reduces the testing coverage of the Device Driver code. This + * is because we have no way of testing the NULL == value path on an OS + * implementation. + * + * A number of allowable examples exist where U/K interfaces do 'real' work: + * - The 'pointer switching' technique for \ref _mali_ukk_get_system_info + * - In this case, without the pointer switching on direct function call + * U/K interface, the Device Driver code still sees the same thing: a pointer + * to which it can write memory. This is because such a system has no + * distinction between a user and kernel pointer. + * - Writing an OS-specific value into the ukk_private member for + * _mali_ukk_mem_mmap(). + * - In this case, this value is passed around by Device Driver code, but + * its actual value is never checked. Device Driver code simply passes it from + * the U/K layer to the OSK layer, where it can be acted upon. In this case, + * \em some OS implementations of the U/K (_mali_ukk_mem_mmap()) and OSK + * (_mali_osk_mem_mapregion_init()) functions will collaborate on the + * meaning of ukk_private member. On other OSs, it may be unused by both + * U/K and OSK layers + * - Therefore, on error inside the U/K interface implementation itself, + * it will be as though the _mali_ukk function itself had failed, and cleaned + * up after itself. + * - Compare this to a direct function call U/K implementation, where all + * error cleanup is handled by the _mali_ukk function itself. The direct + * function call U/K interface implementation is automatically atomic. + * + * The last example highlights a consequence of all U/K interface + * implementations: they must be atomic with respect to the Device Driver code. + * And therefore, should Device Driver code succeed but the U/K implementation + * fail afterwards (but before return to user-space), then the U/K + * implementation must cause appropriate cleanup actions to preserve the + * atomicity of the interface. + * + * @{ + */ + + +/** @defgroup _mali_uk_context U/K Context management + * + * These functions allow for initialisation of the user-kernel interface once per process. + * + * Generally the context will store the OS specific object to communicate with the kernel device driver and further + * state information required by the specific implementation. The context is shareable among all threads in the caller process. + * + * On IOCTL systems, this is likely to be a file descriptor as a result of opening the kernel device driver. + * + * On a bare-metal/RTOS system with no distinction between kernel and + * user-space, the U/K interface simply calls the _mali_ukk variant of the + * function by direct function call. In this case, the context returned is the + * mali_session_data from _mali_ukk_open(). + * + * The kernel side implementations of the U/K interface expect the first member of the argument structure to + * be the context created by _mali_uku_open(). On some OS implementations, the meaning of this context + * will be different between user-side and kernel-side. In which case, the kernel-side will need to replace this context + * with the kernel-side equivalent, because user-side will not have access to kernel-side data. The context parameter + * in the argument structure therefore has to be of type input/output. + * + * It should be noted that the caller cannot reuse the \c ctx member of U/K + * argument structure after a U/K call, because it may be overwritten. Instead, + * the context handle must always be stored elsewhere, and copied into + * the appropriate U/K argument structure for each user-side call to + * the U/K interface. This is not usually a problem, since U/K argument + * structures are usually placed on the stack. + * + * @{ */ + +/** @brief Begin a new Mali Device Driver session + * + * This is used to obtain a per-process context handle for all future U/K calls. + * + * @param context pointer to storage to return a (void*)context handle. + * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. + */ +_mali_osk_errcode_t _mali_ukk_open( void **context ); + +/** @brief End a Mali Device Driver session + * + * This should be called when the process no longer requires use of the Mali Device Driver. + * + * The context handle must not be used after it has been closed. + * + * @param context pointer to a stored (void*)context handle. + * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. + */ +_mali_osk_errcode_t _mali_ukk_close( void **context ); + +/** @} */ /* end group _mali_uk_context */ + + +/** @addtogroup _mali_uk_core U/K Core + * + * The core functions provide the following functionality: + * - verify that the user and kernel API are compatible + * - retrieve information about the cores and memory banks in the system + * - wait for the result of jobs started on a core + * + * @{ */ + +/** @brief Waits for a job notification. + * + * Sleeps until notified or a timeout occurs. Returns information about the notification. + * + * @param args see _mali_uk_wait_for_notification_s in "mali_utgard_uk_types.h" + * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. + */ +_mali_osk_errcode_t _mali_ukk_wait_for_notification( _mali_uk_wait_for_notification_s *args ); + +/** @brief Post a notification to the notification queue of this application. + * + * @param args see _mali_uk_post_notification_s in "mali_utgard_uk_types.h" + * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. + */ +_mali_osk_errcode_t _mali_ukk_post_notification( _mali_uk_post_notification_s *args ); + +/** @brief Verifies if the user and kernel side of this API are compatible. + * + * @param args see _mali_uk_get_api_version_s in "mali_utgard_uk_types.h" + * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. + */ +_mali_osk_errcode_t _mali_ukk_get_api_version( _mali_uk_get_api_version_s *args ); + +/** @brief Get the user space settings applicable for calling process. + * + * @param args see _mali_uk_get_user_settings_s in "mali_utgard_uk_types.h" + */ +_mali_osk_errcode_t _mali_ukk_get_user_settings(_mali_uk_get_user_settings_s *args); + +/** @brief Get a user space setting applicable for calling process. + * + * @param args see _mali_uk_get_user_setting_s in "mali_utgard_uk_types.h" + */ +_mali_osk_errcode_t _mali_ukk_get_user_setting(_mali_uk_get_user_setting_s *args); + +/** @} */ /* end group _mali_uk_core */ + + +/** @addtogroup _mali_uk_memory U/K Memory + * + * The memory functions provide functionality with and without a Mali-MMU present. + * + * For Mali-MMU based systems, the following functionality is provided: + * - Initialize and terminate MALI virtual address space + * - Allocate/deallocate physical memory to a MALI virtual address range and map into/unmap from the + * current process address space + * - Map/unmap external physical memory into the MALI virtual address range + * + * For Mali-nonMMU based systems: + * - Allocate/deallocate MALI memory + * + * @{ */ + +/** + * @brief Initialize the Mali-MMU Memory system + * + * For Mali-MMU builds of the drivers, this function must be called before any + * other functions in the \ref _mali_uk_memory group are called. + * + * @note This function is for Mali-MMU builds \b only. It should not be called + * when the drivers are built without Mali-MMU support. + * + * @param args see \ref _mali_uk_init_mem_s in mali_utgard_uk_types.h + * @return _MALI_OSK_ERR_OK on success, otherwise a suitable + * _mali_osk_errcode_t on failure. + */ +_mali_osk_errcode_t _mali_ukk_init_mem( _mali_uk_init_mem_s *args ); + +/** + * @brief Terminate the MMU Memory system + * + * For Mali-MMU builds of the drivers, this function must be called when + * functions in the \ref _mali_uk_memory group will no longer be called. This + * function must be called before the application terminates. + * + * @note This function is for Mali-MMU builds \b only. It should not be called + * when the drivers are built without Mali-MMU support. + * + * @param args see \ref _mali_uk_term_mem_s in mali_utgard_uk_types.h + * @return _MALI_OSK_ERR_OK on success, otherwise a suitable + * _mali_osk_errcode_t on failure. + */ +_mali_osk_errcode_t _mali_ukk_term_mem( _mali_uk_term_mem_s *args ); + +/** @brief Map Mali Memory into the current user process + * + * Maps Mali memory into the current user process in a generic way. + * + * This function is to be used for Mali-MMU mode. The function is available in both Mali-MMU and Mali-nonMMU modes, + * but should not be called by a user process in Mali-nonMMU mode. + * + * The implementation and operation of _mali_ukk_mem_mmap() is dependant on whether the driver is built for Mali-MMU + * or Mali-nonMMU: + * - In the nonMMU case, _mali_ukk_mem_mmap() requires a physical address to be specified. For this reason, an OS U/K + * implementation should not allow this to be called from user-space. In any case, nonMMU implementations are + * inherently insecure, and so the overall impact is minimal. Mali-MMU mode should be used if security is desired. + * - In the MMU case, _mali_ukk_mem_mmap() the _mali_uk_mem_mmap_s::phys_addr + * member is used for the \em Mali-virtual address desired for the mapping. The + * implementation of _mali_ukk_mem_mmap() will allocate both the CPU-virtual + * and CPU-physical addresses, and can cope with mapping a contiguous virtual + * address range to a sequence of non-contiguous physical pages. In this case, + * the CPU-physical addresses are not communicated back to the user-side, as + * they are unnecsessary; the \em Mali-virtual address range must be used for + * programming Mali structures. + * + * In the second (MMU) case, _mali_ukk_mem_mmap() handles management of + * CPU-virtual and CPU-physical ranges, but the \em caller must manage the + * \em Mali-virtual address range from the user-side. + * + * @note Mali-virtual address ranges are entirely separate between processes. + * It is not possible for a process to accidentally corrupt another process' + * \em Mali-virtual address space. + * + * @param args see _mali_uk_mem_mmap_s in "mali_utgard_uk_types.h" + * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. + */ +_mali_osk_errcode_t _mali_ukk_mem_mmap( _mali_uk_mem_mmap_s *args ); + +/** @brief Unmap Mali Memory from the current user process + * + * Unmaps Mali memory from the current user process in a generic way. This only operates on Mali memory supplied + * from _mali_ukk_mem_mmap(). + * + * @param args see _mali_uk_mem_munmap_s in "mali_utgard_uk_types.h" + * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. + */ +_mali_osk_errcode_t _mali_ukk_mem_munmap( _mali_uk_mem_munmap_s *args ); + +/** @brief Determine the buffer size necessary for an MMU page table dump. + * @param args see _mali_uk_query_mmu_page_table_dump_size_s in mali_utgard_uk_types.h + * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. + */ +_mali_osk_errcode_t _mali_ukk_query_mmu_page_table_dump_size( _mali_uk_query_mmu_page_table_dump_size_s *args ); +/** @brief Dump MMU Page tables. + * @param args see _mali_uk_dump_mmu_page_table_s in mali_utgard_uk_types.h + * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. + */ +_mali_osk_errcode_t _mali_ukk_dump_mmu_page_table( _mali_uk_dump_mmu_page_table_s * args ); + +/** @brief Map a physically contiguous range of memory into Mali + * @param args see _mali_uk_map_external_mem_s in mali_utgard_uk_types.h + * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. + */ +_mali_osk_errcode_t _mali_ukk_map_external_mem( _mali_uk_map_external_mem_s *args ); + +/** @brief Unmap a physically contiguous range of memory from Mali + * @param args see _mali_uk_unmap_external_mem_s in mali_utgard_uk_types.h + * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. + */ +_mali_osk_errcode_t _mali_ukk_unmap_external_mem( _mali_uk_unmap_external_mem_s *args ); + +#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 +/** @brief Map UMP memory into Mali + * @param args see _mali_uk_attach_ump_mem_s in mali_utgard_uk_types.h + * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. + */ +_mali_osk_errcode_t _mali_ukk_attach_ump_mem( _mali_uk_attach_ump_mem_s *args ); +/** @brief Unmap UMP memory from Mali + * @param args see _mali_uk_release_ump_mem_s in mali_utgard_uk_types.h + * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. + */ +_mali_osk_errcode_t _mali_ukk_release_ump_mem( _mali_uk_release_ump_mem_s *args ); +#endif /* MALI_USE_UNIFIED_MEMORY_PROVIDER */ + +/** @brief Determine virtual-to-physical mapping of a contiguous memory range + * (optional) + * + * This allows the user-side to do a virtual-to-physical address translation. + * In conjunction with _mali_uku_map_external_mem, this can be used to do + * direct rendering. + * + * This function will only succeed on a virtual range that is mapped into the + * current process, and that is contigious. + * + * If va is not page-aligned, then it is rounded down to the next page + * boundary. The remainer is added to size, such that ((u32)va)+size before + * rounding is equal to ((u32)va)+size after rounding. The rounded modified + * va and size will be written out into args on success. + * + * If the supplied size is zero, or not a multiple of the system's PAGE_SIZE, + * then size will be rounded up to the next multiple of PAGE_SIZE before + * translation occurs. The rounded up size will be written out into args on + * success. + * + * On most OSs, virtual-to-physical address translation is a priveledged + * function. Therefore, the implementer must validate the range supplied, to + * ensure they are not providing arbitrary virtual-to-physical address + * translations. While it is unlikely such a mechanism could be used to + * compromise the security of a system on its own, it is possible it could be + * combined with another small security risk to cause a much larger security + * risk. + * + * @note This is an optional part of the interface, and is only used by certain + * implementations of libEGL. If the platform layer in your libEGL + * implementation does not require Virtual-to-Physical address translation, + * then this function need not be implemented. A stub implementation should not + * be required either, as it would only be removed by the compiler's dead code + * elimination. + * + * @note if implemented, this function is entirely platform-dependant, and does + * not exist in common code. + * + * @param args see _mali_uk_va_to_mali_pa_s in "mali_utgard_uk_types.h" + * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. + */ +_mali_osk_errcode_t _mali_ukk_va_to_mali_pa( _mali_uk_va_to_mali_pa_s * args ); + +/** @} */ /* end group _mali_uk_memory */ + + +/** @addtogroup _mali_uk_pp U/K Fragment Processor + * + * The Fragment Processor (aka PP (Pixel Processor)) functions provide the following functionality: + * - retrieving version of the fragment processors + * - determine number of fragment processors + * - starting a job on a fragment processor + * + * @{ */ + +/** @brief Issue a request to start a new job on a Fragment Processor. + * + * If the request fails args->status is set to _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE and you can + * try to start the job again. + * + * An existing job could be returned for requeueing if the new job has a higher priority than a previously started job + * which the hardware hasn't actually started processing yet. In this case the new job will be started instead and the + * existing one returned, otherwise the new job is started and the status field args->status is set to + * _MALI_UK_START_JOB_STARTED. + * + * Job completion can be awaited with _mali_ukk_wait_for_notification(). + * + * @param args see _mali_uk_pp_start_job_s in "mali_utgard_uk_types.h" + * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. + */ +_mali_osk_errcode_t _mali_ukk_pp_start_job( _mali_uk_pp_start_job_s *args ); + +/** @brief Returns the number of Fragment Processors in the system + * + * @param args see _mali_uk_get_pp_number_of_cores_s in "mali_utgard_uk_types.h" + * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. + */ +_mali_osk_errcode_t _mali_ukk_get_pp_number_of_cores( _mali_uk_get_pp_number_of_cores_s *args ); + +/** @brief Returns the version that all Fragment Processor cores are compatible with. + * + * This function may only be called when _mali_ukk_get_pp_number_of_cores() indicated at least one Fragment + * Processor core is available. + * + * @param args see _mali_uk_get_pp_core_version_s in "mali_utgard_uk_types.h" + * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. + */ +_mali_osk_errcode_t _mali_ukk_get_pp_core_version( _mali_uk_get_pp_core_version_s *args ); + +/** @brief Disable Write-back unit(s) on specified job + * + * @param args see _mali_uk_get_pp_core_version_s in "mali_utgard_uk_types.h" + */ +void _mali_ukk_pp_job_disable_wb(_mali_uk_pp_disable_wb_s *args); + + +/** @} */ /* end group _mali_uk_pp */ + + +/** @addtogroup _mali_uk_gp U/K Vertex Processor + * + * The Vertex Processor (aka GP (Geometry Processor)) functions provide the following functionality: + * - retrieving version of the Vertex Processors + * - determine number of Vertex Processors available + * - starting a job on a Vertex Processor + * + * @{ */ + +/** @brief Issue a request to start a new job on a Vertex Processor. + * + * If the request fails args->status is set to _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE and you can + * try to start the job again. + * + * An existing job could be returned for requeueing if the new job has a higher priority than a previously started job + * which the hardware hasn't actually started processing yet. In this case the new job will be started and the + * existing one returned, otherwise the new job is started and the status field args->status is set to + * _MALI_UK_START_JOB_STARTED. + * + * Job completion can be awaited with _mali_ukk_wait_for_notification(). + * + * @param args see _mali_uk_gp_start_job_s in "mali_utgard_uk_types.h" + * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. + */ +_mali_osk_errcode_t _mali_ukk_gp_start_job( _mali_uk_gp_start_job_s *args ); + +/** @brief Returns the number of Vertex Processors in the system. + * + * @param args see _mali_uk_get_gp_number_of_cores_s in "mali_utgard_uk_types.h" + * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. + */ +_mali_osk_errcode_t _mali_ukk_get_gp_number_of_cores( _mali_uk_get_gp_number_of_cores_s *args ); + +/** @brief Returns the version that all Vertex Processor cores are compatible with. + * + * This function may only be called when _mali_uk_get_gp_number_of_cores() indicated at least one Vertex + * Processor core is available. + * + * @param args see _mali_uk_get_gp_core_version_s in "mali_utgard_uk_types.h" + * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. + */ +_mali_osk_errcode_t _mali_ukk_get_gp_core_version( _mali_uk_get_gp_core_version_s *args ); + +/** @brief Resume or abort suspended Vertex Processor jobs. + * + * After receiving notification that a Vertex Processor job was suspended from + * _mali_ukk_wait_for_notification() you can use this function to resume or abort the job. + * + * @param args see _mali_uk_gp_suspend_response_s in "mali_utgard_uk_types.h" + * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. + */ +_mali_osk_errcode_t _mali_ukk_gp_suspend_response( _mali_uk_gp_suspend_response_s *args ); + +/** @} */ /* end group _mali_uk_gp */ + +#if MALI_TIMELINE_PROFILING_ENABLED +/** @addtogroup _mali_uk_profiling U/K Timeline profiling module + * @{ */ + +/** @brief Start recording profiling events. + * + * @param args see _mali_uk_profiling_start_s in "mali_utgard_uk_types.h" + */ +_mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args); + +/** @brief Add event to profiling buffer. + * + * @param args see _mali_uk_profiling_add_event_s in "mali_utgard_uk_types.h" + */ +_mali_osk_errcode_t _mali_ukk_profiling_add_event(_mali_uk_profiling_add_event_s *args); + +/** @brief Stop recording profiling events. + * + * @param args see _mali_uk_profiling_stop_s in "mali_utgard_uk_types.h" + */ +_mali_osk_errcode_t _mali_ukk_profiling_stop(_mali_uk_profiling_stop_s *args); + +/** @brief Retrieve a recorded profiling event. + * + * @param args see _mali_uk_profiling_get_event_s in "mali_utgard_uk_types.h" + */ +_mali_osk_errcode_t _mali_ukk_profiling_get_event(_mali_uk_profiling_get_event_s *args); + +/** @brief Clear recorded profiling events. + * + * @param args see _mali_uk_profiling_clear_s in "mali_utgard_uk_types.h" + */ +_mali_osk_errcode_t _mali_ukk_profiling_clear(_mali_uk_profiling_clear_s *args); + +/** @} */ /* end group _mali_uk_profiling */ +#endif + +/** @addtogroup _mali_uk_vsync U/K VSYNC reporting module + * @{ */ + +/** @brief Report events related to vsync. + * + * @note Events should be reported when starting to wait for vsync and when the + * waiting is finished. This information can then be used in kernel space to + * complement the GPU utilization metric. + * + * @param args see _mali_uk_vsync_event_report_s in "mali_utgard_uk_types.h" + */ +_mali_osk_errcode_t _mali_ukk_vsync_event_report(_mali_uk_vsync_event_report_s *args); + +/** @} */ /* end group _mali_uk_vsync */ + +/** @addtogroup _mali_sw_counters_report U/K Software counter reporting + * @{ */ + +/** @brief Report software counters. + * + * @param args see _mali_uk_sw_counters_report_s in "mali_uk_types.h" + */ +_mali_osk_errcode_t _mali_ukk_sw_counters_report(_mali_uk_sw_counters_report_s *args); + +/** @} */ /* end group _mali_sw_counters_report */ + +/** @} */ /* end group u_k_api */ + +/** @} */ /* end group uddapi */ + +u32 _mali_ukk_report_memory_usage(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __MALI_UKK_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_user_settings_db.c b/drivers/media/video/samsung/mali/common/mali_user_settings_db.c new file mode 100644 index 0000000..d3f1e50 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_user_settings_db.c @@ -0,0 +1,88 @@ +/** + * Copyright (C) 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_osk.h" +#include "mali_kernel_common.h" +#include "mali_uk_types.h" +#include "mali_user_settings_db.h" +#include "mali_session.h" + +static u32 mali_user_settings[_MALI_UK_USER_SETTING_MAX]; +const char *_mali_uk_user_setting_descriptions[] = _MALI_UK_USER_SETTING_DESCRIPTIONS; + +static void mali_user_settings_notify(_mali_uk_user_setting_t setting, u32 value) +{ + struct mali_session_data *session, *tmp; + + mali_session_lock(); + MALI_SESSION_FOREACH(session, tmp, link) + { + _mali_osk_notification_t *notobj = _mali_osk_notification_create(_MALI_NOTIFICATION_SETTINGS_CHANGED, sizeof(_mali_uk_settings_changed_s)); + _mali_uk_settings_changed_s *data = notobj->result_buffer; + data->setting = setting; + data->value = value; + + mali_session_send_notification(session, notobj); + } + mali_session_unlock(); +} + +void mali_set_user_setting(_mali_uk_user_setting_t setting, u32 value) +{ + mali_bool notify = MALI_FALSE; + + MALI_DEBUG_ASSERT(setting < _MALI_UK_USER_SETTING_MAX && setting >= 0); + + if (mali_user_settings[setting] != value) + { + notify = MALI_TRUE; + } + + mali_user_settings[setting] = value; + + if (notify) + { + mali_user_settings_notify(setting, value); + } +} + +u32 mali_get_user_setting(_mali_uk_user_setting_t setting) +{ + MALI_DEBUG_ASSERT(setting < _MALI_UK_USER_SETTING_MAX && setting >= 0); + + return mali_user_settings[setting]; +} + +_mali_osk_errcode_t _mali_ukk_get_user_setting(_mali_uk_get_user_setting_s *args) +{ + _mali_uk_user_setting_t setting; + MALI_DEBUG_ASSERT_POINTER(args); + + setting = args->setting; + + if (0 <= setting && _MALI_UK_USER_SETTING_MAX > setting) + { + args->value = mali_user_settings[setting]; + return _MALI_OSK_ERR_OK; + } + else + { + return _MALI_OSK_ERR_INVALID_ARGS; + } +} + +_mali_osk_errcode_t _mali_ukk_get_user_settings(_mali_uk_get_user_settings_s *args) +{ + MALI_DEBUG_ASSERT_POINTER(args); + + _mali_osk_memcpy(args->settings, mali_user_settings, sizeof(mali_user_settings)); + + return _MALI_OSK_ERR_OK; +} diff --git a/drivers/media/video/samsung/mali/common/mali_user_settings_db.h b/drivers/media/video/samsung/mali/common/mali_user_settings_db.h new file mode 100644 index 0000000..fbb9415 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_user_settings_db.h @@ -0,0 +1,40 @@ +/** + * Copyright (C) 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_USER_SETTINGS_DB_H__ +#define __MALI_USER_SETTINGS_DB_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "mali_uk_types.h" + +/** @brief Set Mali user setting in DB + * + * Update the DB with a new value for \a setting. If the value is different from theprevious set value running sessions will be notified of the change. + * + * @param setting the setting to be changed + * @param value the new value to set + */ +void mali_set_user_setting(_mali_uk_user_setting_t setting, u32 value); + +/** @brief Get current Mali user setting value from DB + * + * @param setting the setting to extract + * @return the value of the selected setting + */ +u32 mali_get_user_setting(_mali_uk_user_setting_t setting); + +#ifdef __cplusplus +} +#endif +#endif /* __MALI_KERNEL_USER_SETTING__ */ diff --git a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard.h b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard.h new file mode 100644 index 0000000..7c78947 --- /dev/null +++ b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_UTGARD_H__ +#define __MALI_UTGARD_H__ + +/** @brief MALI GPU power down using MALI in-built PMU + * + * called to power down all cores + */ +int mali_pmu_powerdown(void); + + +/** @brief MALI GPU power up using MALI in-built PMU + * + * called to power up all cores + */ +int mali_pmu_powerup(void); + +#endif /* __MALI_UTGARD_H__ */ + diff --git a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_counters.h b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_counters.h new file mode 100644 index 0000000..40822f7 --- /dev/null +++ b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_counters.h @@ -0,0 +1,264 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MALI_UTGARD_COUNTERS_H_ +#define _MALI_UTGARD_COUNTERS_H_ + +typedef struct +{ + void *unused; +} mali_cinstr_counter_info; + +typedef enum +{ + MALI_CINSTR_COUNTER_SOURCE_EGL = 0, + MALI_CINSTR_COUNTER_SOURCE_OPENGLES = 1000, + MALI_CINSTR_COUNTER_SOURCE_OPENVG = 2000, + MALI_CINSTR_COUNTER_SOURCE_GP = 3000, + MALI_CINSTR_COUNTER_SOURCE_PP = 4000, +} cinstr_counter_source; + +#define MALI_CINSTR_EGL_FIRST_COUNTER MALI_CINSTR_COUNTER_SOURCE_EGL +#define MALI_CINSTR_EGL_LAST_COUNTER (MALI_CINSTR_COUNTER_SOURCE_EGL + 999) + +#define MALI_CINSTR_GLES_FIRST_COUNTER MALI_CINSTR_COUNTER_SOURCE_OPENGLES +#define MALI_CINSTR_GLES_LAST_COUNTER (MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 999) + +#define MALI_CINSTR_VG_FIRST_COUNTER MALI_CINSTR_COUNTER_SOURCE_OPENVG +#define MALI_CINSTR_VG_LAST_COUNTER (MALI_CINSTR_COUNTER_SOURCE_OPENVG + 999) + +#define MALI_CINSTR_GP_FIRST_COUNTER MALI_CINSTR_COUNTER_SOURCE_GP +#define MALI_CINSTR_GP_LAST_COUNTER (MALI_CINSTR_COUNTER_SOURCE_GP + 999) + +#define MALI_CINSTR_PP_FIRST_COUNTER MALI_CINSTR_COUNTER_SOURCE_PP +#define MALI_CINSTR_PP_LAST_COUNTER (MALI_CINSTR_COUNTER_SOURCE_PP + 999) + + +typedef enum +{ + /* EGL counters */ + + MALI_CINSTR_EGL_BLIT_TIME = MALI_CINSTR_COUNTER_SOURCE_EGL + 0, + + /* Last counter in the EGL set */ + MALI_CINSTR_EGL_MAX_COUNTER = MALI_CINSTR_COUNTER_SOURCE_EGL + 1, + + /* GLES counters */ + + MALI_CINSTR_GLES_DRAW_ELEMENTS_CALLS = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 0, + MALI_CINSTR_GLES_DRAW_ELEMENTS_NUM_INDICES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 1, + MALI_CINSTR_GLES_DRAW_ELEMENTS_NUM_TRANSFORMED = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 2, + MALI_CINSTR_GLES_DRAW_ARRAYS_CALLS = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 3, + MALI_CINSTR_GLES_DRAW_ARRAYS_NUM_TRANSFORMED = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 4, + MALI_CINSTR_GLES_DRAW_POINTS = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 5, + MALI_CINSTR_GLES_DRAW_LINES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 6, + MALI_CINSTR_GLES_DRAW_LINE_LOOP = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 7, + MALI_CINSTR_GLES_DRAW_LINE_STRIP = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 8, + MALI_CINSTR_GLES_DRAW_TRIANGLES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 9, + MALI_CINSTR_GLES_DRAW_TRIANGLE_STRIP = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 10, + MALI_CINSTR_GLES_DRAW_TRIANGLE_FAN = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 11, + MALI_CINSTR_GLES_NON_VBO_DATA_COPY_TIME = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 12, + MALI_CINSTR_GLES_UNIFORM_BYTES_COPIED_TO_MALI = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 13, + MALI_CINSTR_GLES_UPLOAD_TEXTURE_TIME = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 14, + MALI_CINSTR_GLES_UPLOAD_VBO_TIME = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 15, + MALI_CINSTR_GLES_NUM_FLUSHES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 16, + MALI_CINSTR_GLES_NUM_VSHADERS_GENERATED = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 17, + MALI_CINSTR_GLES_NUM_FSHADERS_GENERATED = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 18, + MALI_CINSTR_GLES_VSHADER_GEN_TIME = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 19, + MALI_CINSTR_GLES_FSHADER_GEN_TIME = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 20, + MALI_CINSTR_GLES_INPUT_TRIANGLES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 21, + MALI_CINSTR_GLES_VXCACHE_HIT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 22, + MALI_CINSTR_GLES_VXCACHE_MISS = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 23, + MALI_CINSTR_GLES_VXCACHE_COLLISION = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 24, + MALI_CINSTR_GLES_CULLED_TRIANGLES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 25, + MALI_CINSTR_GLES_CULLED_LINES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 26, + MALI_CINSTR_GLES_BACKFACE_TRIANGLES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 27, + MALI_CINSTR_GLES_GBCLIP_TRIANGLES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 28, + MALI_CINSTR_GLES_GBCLIP_LINES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 29, + MALI_CINSTR_GLES_TRIANGLES_DRAWN = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 30, + MALI_CINSTR_GLES_DRAWCALL_TIME = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 31, + MALI_CINSTR_GLES_TRIANGLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 32, + MALI_CINSTR_GLES_INDEPENDENT_TRIANGLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 33, + MALI_CINSTR_GLES_STRIP_TRIANGLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 34, + MALI_CINSTR_GLES_FAN_TRIANGLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 35, + MALI_CINSTR_GLES_LINES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 36, + MALI_CINSTR_GLES_INDEPENDENT_LINES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 37, + MALI_CINSTR_GLES_STRIP_LINES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 38, + MALI_CINSTR_GLES_LOOP_LINES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 39, + MALI_CINSTR_GLES_POINTS_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 40, + + /* Last counter in the GLES set */ + MALI_CINSTR_GLES_MAX_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 41, + + /* OpenVG counters */ + + MALI_CINSTR_VG_MASK_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 0, + MALI_CINSTR_VG_CLEAR_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 1, + MALI_CINSTR_VG_APPEND_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 2, + MALI_CINSTR_VG_APPEND_PATH_DATA_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 3, + MALI_CINSTR_VG_MODIFY_PATH_COORDS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 4, + MALI_CINSTR_VG_TRANSFORM_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 5, + MALI_CINSTR_VG_INTERPOLATE_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 6, + MALI_CINSTR_VG_PATH_LENGTH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 7, + MALI_CINSTR_VG_POINT_ALONG_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 8, + MALI_CINSTR_VG_PATH_BOUNDS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 9, + MALI_CINSTR_VG_PATH_TRANSFORMED_BOUNDS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 10, + MALI_CINSTR_VG_DRAW_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 11, + MALI_CINSTR_VG_CLEAR_IMAGE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 12, + MALI_CINSTR_VG_IMAGE_SUB_DATA_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 13, + MALI_CINSTR_VG_GET_IMAGE_SUB_DATA_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 14, + MALI_CINSTR_VG_COPY_IMAGE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 15, + MALI_CINSTR_VG_DRAW_IMAGE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 16, + MALI_CINSTR_VG_SET_PIXELS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 17, + MALI_CINSTR_VG_WRITE_PIXELS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 18, + MALI_CINSTR_VG_GET_PIXELS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 19, + MALI_CINSTR_VG_READ_PIXELS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 20, + MALI_CINSTR_VG_COPY_PIXELS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 21, + MALI_CINSTR_VG_COLOR_MATRIX_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 22, + MALI_CINSTR_VG_CONVOLVE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 23, + MALI_CINSTR_VG_SEPARABLE_CONVOLVE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 24, + MALI_CINSTR_VG_GAUSSIAN_BLUR_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 25, + MALI_CINSTR_VG_LOOKUP_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 26, + MALI_CINSTR_VG_LOOKUP_SINGLE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 27, + MALI_CINSTR_VG_CONTEXT_CREATE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 28, + MALI_CINSTR_VG_STROKED_CUBICS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 29, + MALI_CINSTR_VG_STROKED_QUADS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 30, + MALI_CINSTR_VG_STROKED_ARCS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 31, + MALI_CINSTR_VG_STROKED_LINES_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 32, + MALI_CINSTR_VG_FILLED_CUBICS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 33, + MALI_CINSTR_VG_FILLED_QUADS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 34, + MALI_CINSTR_VG_FILLED_ARCS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 35, + MALI_CINSTR_VG_FILLED_LINES_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 36, + MALI_CINSTR_VG_DRAW_PATH_CALLS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 37, + MALI_CINSTR_VG_TRIANGLES_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 38, + MALI_CINSTR_VG_VERTICES_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 39, + MALI_CINSTR_VG_INDICES_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 40, + MALI_CINSTR_VG_FILLED_PATHS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 41, + MALI_CINSTR_VG_STROKED_PATHS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 42, + MALI_CINSTR_VG_FILL_EXTRACT_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 43, + MALI_CINSTR_VG_DRAW_FILLED_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 44, + MALI_CINSTR_VG_STROKE_EXTRACT_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 45, + MALI_CINSTR_VG_DRAW_STROKED_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 46, + MALI_CINSTR_VG_DRAW_PAINT_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 47, + MALI_CINSTR_VG_DATA_STRUCTURES_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 48, + MALI_CINSTR_VG_MEM_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 49, + MALI_CINSTR_VG_RSW_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 50, + + /* Last counter in the VG set */ + MALI_CINSTR_VG_MAX_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 51, + + /* Mali GP counters */ + + MALI_CINSTR_GP_DEPRECATED_0 = MALI_CINSTR_COUNTER_SOURCE_GP + 0, + MALI_CINSTR_GP_ACTIVE_CYCLES_GP = MALI_CINSTR_COUNTER_SOURCE_GP + 1, + MALI_CINSTR_GP_ACTIVE_CYCLES_VERTEX_SHADER = MALI_CINSTR_COUNTER_SOURCE_GP + 2, + MALI_CINSTR_GP_ACTIVE_CYCLES_VERTEX_STORER = MALI_CINSTR_COUNTER_SOURCE_GP + 3, + MALI_CINSTR_GP_ACTIVE_CYCLES_VERTEX_LOADER = MALI_CINSTR_COUNTER_SOURCE_GP + 4, + MALI_CINSTR_GP_CYCLES_VERTEX_LOADER_WAITING_FOR_VERTEX_SHADER = MALI_CINSTR_COUNTER_SOURCE_GP + 5, + MALI_CINSTR_GP_NUMBER_OF_WORDS_READ = MALI_CINSTR_COUNTER_SOURCE_GP + 6, + MALI_CINSTR_GP_NUMBER_OF_WORDS_WRITTEN = MALI_CINSTR_COUNTER_SOURCE_GP + 7, + MALI_CINSTR_GP_NUMBER_OF_READ_BURSTS = MALI_CINSTR_COUNTER_SOURCE_GP + 8, + MALI_CINSTR_GP_NUMBER_OF_WRITE_BURSTS = MALI_CINSTR_COUNTER_SOURCE_GP + 9, + MALI_CINSTR_GP_NUMBER_OF_VERTICES_PROCESSED = MALI_CINSTR_COUNTER_SOURCE_GP + 10, + MALI_CINSTR_GP_NUMBER_OF_VERTICES_FETCHED = MALI_CINSTR_COUNTER_SOURCE_GP + 11, + MALI_CINSTR_GP_NUMBER_OF_PRIMITIVES_FETCHED = MALI_CINSTR_COUNTER_SOURCE_GP + 12, + MALI_CINSTR_GP_RESERVED_13 = MALI_CINSTR_COUNTER_SOURCE_GP + 13, + MALI_CINSTR_GP_NUMBER_OF_BACKFACE_CULLINGS_DONE = MALI_CINSTR_COUNTER_SOURCE_GP + 14, + MALI_CINSTR_GP_NUMBER_OF_COMMANDS_WRITTEN_TO_TILES = MALI_CINSTR_COUNTER_SOURCE_GP + 15, + MALI_CINSTR_GP_NUMBER_OF_MEMORY_BLOCKS_ALLOCATED = MALI_CINSTR_COUNTER_SOURCE_GP + 16, + MALI_CINSTR_GP_RESERVED_17 = MALI_CINSTR_COUNTER_SOURCE_GP + 17, + MALI_CINSTR_GP_RESERVED_18 = MALI_CINSTR_COUNTER_SOURCE_GP + 18, + MALI_CINSTR_GP_NUMBER_OF_VERTEX_LOADER_CACHE_MISSES = MALI_CINSTR_COUNTER_SOURCE_GP + 19, + MALI_CINSTR_GP_RESERVED_20 = MALI_CINSTR_COUNTER_SOURCE_GP + 20, + MALI_CINSTR_GP_RESERVED_21 = MALI_CINSTR_COUNTER_SOURCE_GP + 21, + MALI_CINSTR_GP_ACTIVE_CYCLES_VERTEX_SHADER_COMMAND_PROCESSOR = MALI_CINSTR_COUNTER_SOURCE_GP + 22, + MALI_CINSTR_GP_ACTIVE_CYCLES_PLBU_COMMAND_PROCESSOR = MALI_CINSTR_COUNTER_SOURCE_GP + 23, + MALI_CINSTR_GP_ACTIVE_CYCLES_PLBU_LIST_WRITER = MALI_CINSTR_COUNTER_SOURCE_GP + 24, + MALI_CINSTR_GP_ACTIVE_CYCLES_THROUGH_THE_PREPARE_LIST_COMMANDS = MALI_CINSTR_COUNTER_SOURCE_GP + 25, + MALI_CINSTR_GP_RESERVED_26 = MALI_CINSTR_COUNTER_SOURCE_GP + 26, + MALI_CINSTR_GP_ACTIVE_CYCLES_PRIMITIVE_ASSEMBLY = MALI_CINSTR_COUNTER_SOURCE_GP + 27, + MALI_CINSTR_GP_ACTIVE_CYCLES_PLBU_VERTEX_FETCHER = MALI_CINSTR_COUNTER_SOURCE_GP + 28, + MALI_CINSTR_GP_RESERVED_29 = MALI_CINSTR_COUNTER_SOURCE_GP + 29, + MALI_CINSTR_GP_ACTIVE_CYCLES_BOUNDINGBOX_AND_COMMAND_GENERATOR = MALI_CINSTR_COUNTER_SOURCE_GP + 30, + MALI_CINSTR_GP_RESERVED_31 = MALI_CINSTR_COUNTER_SOURCE_GP + 31, + MALI_CINSTR_GP_ACTIVE_CYCLES_SCISSOR_TILE_ITERATOR = MALI_CINSTR_COUNTER_SOURCE_GP + 32, + MALI_CINSTR_GP_ACTIVE_CYCLES_PLBU_TILE_ITERATOR = MALI_CINSTR_COUNTER_SOURCE_GP + 33, + MALI_CINSTR_GP_JOB_COUNT = MALI_CINSTR_COUNTER_SOURCE_GP + 900, + + /* Mali PP counters */ + + MALI_CINSTR_PP_ACTIVE_CLOCK_CYCLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 0, + MALI_CINSTR_PP_TOTAL_CLOCK_CYCLES_COUNT_REMOVED = MALI_CINSTR_COUNTER_SOURCE_PP + 1, + MALI_CINSTR_PP_TOTAL_BUS_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 2, + MALI_CINSTR_PP_TOTAL_BUS_WRITES = MALI_CINSTR_COUNTER_SOURCE_PP + 3, + MALI_CINSTR_PP_BUS_READ_REQUEST_CYCLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 4, + MALI_CINSTR_PP_BUS_WRITE_REQUEST_CYCLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 5, + MALI_CINSTR_PP_BUS_READ_TRANSACTIONS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 6, + MALI_CINSTR_PP_BUS_WRITE_TRANSACTIONS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 7, + MALI_CINSTR_PP_RESERVED_08 = MALI_CINSTR_COUNTER_SOURCE_PP + 8, + MALI_CINSTR_PP_TILE_WRITEBACK_WRITES = MALI_CINSTR_COUNTER_SOURCE_PP + 9, + MALI_CINSTR_PP_STORE_UNIT_WRITES = MALI_CINSTR_COUNTER_SOURCE_PP + 10, + MALI_CINSTR_PP_RESERVED_11 = MALI_CINSTR_COUNTER_SOURCE_PP + 11, + MALI_CINSTR_PP_PALETTE_CACHE_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 12, + MALI_CINSTR_PP_TEXTURE_CACHE_UNCOMPRESSED_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 13, + MALI_CINSTR_PP_POLYGON_LIST_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 14, + MALI_CINSTR_PP_RSW_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 15, + MALI_CINSTR_PP_VERTEX_CACHE_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 16, + MALI_CINSTR_PP_UNIFORM_REMAPPING_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 17, + MALI_CINSTR_PP_PROGRAM_CACHE_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 19, + MALI_CINSTR_PP_VARYING_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 19, + MALI_CINSTR_PP_TEXTURE_DESCRIPTORS_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 20, + MALI_CINSTR_PP_TEXTURE_DESCRIPTORS_REMAPPING_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 21, + MALI_CINSTR_PP_TEXTURE_CACHE_COMPRESSED_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 22, + MALI_CINSTR_PP_LOAD_UNIT_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 23, + MALI_CINSTR_PP_POLYGON_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 24, + MALI_CINSTR_PP_PIXEL_RECTANGLE_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 25, + MALI_CINSTR_PP_LINES_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 26, + MALI_CINSTR_PP_POINTS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 27, + MALI_CINSTR_PP_STALL_CYCLES_POLYGON_LIST_READER = MALI_CINSTR_COUNTER_SOURCE_PP + 28, + MALI_CINSTR_PP_STALL_CYCLES_TRIANGLE_SETUP = MALI_CINSTR_COUNTER_SOURCE_PP + 29, + MALI_CINSTR_PP_QUAD_RASTERIZED_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 30, + MALI_CINSTR_PP_FRAGMENT_RASTERIZED_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 31, + MALI_CINSTR_PP_FRAGMENT_REJECTED_FRAGMENT_KILL_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 32, + MALI_CINSTR_PP_FRAGMENT_REJECTED_FWD_FRAGMENT_KILL_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 33, + MALI_CINSTR_PP_FRAGMENT_PASSED_ZSTENCIL_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 34, + MALI_CINSTR_PP_PATCHES_REJECTED_EARLY_Z_STENCIL_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 35, + MALI_CINSTR_PP_PATCHES_EVALUATED = MALI_CINSTR_COUNTER_SOURCE_PP + 36, + MALI_CINSTR_PP_INSTRUCTION_COMPLETED_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 37, + MALI_CINSTR_PP_INSTRUCTION_FAILED_RENDEZVOUS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 38, + MALI_CINSTR_PP_INSTRUCTION_FAILED_VARYING_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 39, + MALI_CINSTR_PP_INSTRUCTION_FAILED_TEXTURE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 40, + MALI_CINSTR_PP_INSTRUCTION_FAILED_LOAD_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 41, + MALI_CINSTR_PP_INSTRUCTION_FAILED_TILE_READ_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 42, + MALI_CINSTR_PP_INSTRUCTION_FAILED_STORE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 43, + MALI_CINSTR_PP_RENDEZVOUS_BREAKAGE_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 44, + MALI_CINSTR_PP_PIPELINE_BUBBLES_CYCLE_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 45, + MALI_CINSTR_PP_TEXTURE_MAPPER_MULTIPASS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 46, + MALI_CINSTR_PP_TEXTURE_MAPPER_CYCLE_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 47, + MALI_CINSTR_PP_VERTEX_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 48, + MALI_CINSTR_PP_VERTEX_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 49, + MALI_CINSTR_PP_VARYING_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 50, + MALI_CINSTR_PP_VARYING_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 51, + MALI_CINSTR_PP_VARYING_CACHE_CONFLICT_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 52, + MALI_CINSTR_PP_TEXTURE_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 53, + MALI_CINSTR_PP_TEXTURE_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 54, + MALI_CINSTR_PP_TEXTURE_CACHE_CONFLICT_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 55, + MALI_CINSTR_PP_PALETTE_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 56, /* Mali 200 only */ + MALI_CINSTR_PP_PALETTE_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 57, /* Mali 200 only */ + MALI_CINSTR_PP_COMPRESSED_TEXTURE_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 56, /* Mali 400 class only */ + MALI_CINSTR_PP_COMPRESSED_TEXTURE_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 57, /* Mali 400 class only */ + MALI_CINSTR_PP_LOAD_STORE_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 58, + MALI_CINSTR_PP_LOAD_STORE_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 59, + MALI_CINSTR_PP_PROGRAM_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 60, + MALI_CINSTR_PP_PROGRAM_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 61, + MALI_CINSTR_PP_JOB_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 900, +} cinstr_counters_m200_t; + +#endif /*_MALI_UTGARD_COUNTERS_H_*/ diff --git a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_ioctl.h b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_ioctl.h new file mode 100644 index 0000000..7935448 --- /dev/null +++ b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_ioctl.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_UTGARD_IOCTL_H__ +#define __MALI_UTGARD_IOCTL_H__ + +#include +#include +#include /* file system operations */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @file mali_kernel_ioctl.h + * Interface to the Linux device driver. + * This file describes the interface needed to use the Linux device driver. + * Its interface is designed to used by the HAL implementation through a thin arch layer. + */ + +/** + * ioctl commands + */ + +#define MALI_IOC_BASE 0x82 +#define MALI_IOC_CORE_BASE (_MALI_UK_CORE_SUBSYSTEM + MALI_IOC_BASE) +#define MALI_IOC_MEMORY_BASE (_MALI_UK_MEMORY_SUBSYSTEM + MALI_IOC_BASE) +#define MALI_IOC_PP_BASE (_MALI_UK_PP_SUBSYSTEM + MALI_IOC_BASE) +#define MALI_IOC_GP_BASE (_MALI_UK_GP_SUBSYSTEM + MALI_IOC_BASE) +#define MALI_IOC_PROFILING_BASE (_MALI_UK_PROFILING_SUBSYSTEM + MALI_IOC_BASE) +#define MALI_IOC_VSYNC_BASE (_MALI_UK_VSYNC_SUBSYSTEM + MALI_IOC_BASE) + +#define MALI_IOC_WAIT_FOR_NOTIFICATION _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_WAIT_FOR_NOTIFICATION, _mali_uk_wait_for_notification_s *) +#define MALI_IOC_GET_API_VERSION _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_GET_API_VERSION, _mali_uk_get_api_version_s *) +#define MALI_IOC_POST_NOTIFICATION _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_POST_NOTIFICATION, _mali_uk_post_notification_s *) +#define MALI_IOC_GET_USER_SETTING _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_GET_USER_SETTING, _mali_uk_get_user_setting_s *) +#define MALI_IOC_GET_USER_SETTINGS _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_GET_USER_SETTINGS, _mali_uk_get_user_settings_s *) + +#define MALI_IOC_MEM_GET_BIG_BLOCK _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_GET_BIG_BLOCK, void *) +#define MALI_IOC_MEM_FREE_BIG_BLOCK _IOW (MALI_IOC_MEMORY_BASE, _MALI_UK_FREE_BIG_BLOCK, void *) +#define MALI_IOC_MEM_INIT _IOR (MALI_IOC_MEMORY_BASE, _MALI_UK_INIT_MEM, _mali_uk_init_mem_s *) +#define MALI_IOC_MEM_TERM _IOW (MALI_IOC_MEMORY_BASE, _MALI_UK_TERM_MEM, _mali_uk_term_mem_s *) +#define MALI_IOC_MEM_MAP_EXT _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_MAP_EXT_MEM, _mali_uk_map_external_mem_s *) +#define MALI_IOC_MEM_UNMAP_EXT _IOW (MALI_IOC_MEMORY_BASE, _MALI_UK_UNMAP_EXT_MEM, _mali_uk_unmap_external_mem_s *) +#define MALI_IOC_MEM_ATTACH_DMA_BUF _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_ATTACH_DMA_BUF, _mali_uk_attach_dma_buf_s *) +#define MALI_IOC_MEM_RELEASE_DMA_BUF _IOW(MALI_IOC_MEMORY_BASE, _MALI_UK_RELEASE_DMA_BUF, _mali_uk_release_dma_buf_s *) +#define MALI_IOC_MEM_DMA_BUF_GET_SIZE _IOR(MALI_IOC_MEMORY_BASE, _MALI_UK_DMA_BUF_GET_SIZE, _mali_uk_dma_buf_get_size_s *) +#define MALI_IOC_MEM_ATTACH_UMP _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_ATTACH_UMP_MEM, _mali_uk_attach_ump_mem_s *) +#define MALI_IOC_MEM_RELEASE_UMP _IOW(MALI_IOC_MEMORY_BASE, _MALI_UK_RELEASE_UMP_MEM, _mali_uk_release_ump_mem_s *) +#define MALI_IOC_MEM_QUERY_MMU_PAGE_TABLE_DUMP_SIZE _IOR (MALI_IOC_MEMORY_BASE, _MALI_UK_QUERY_MMU_PAGE_TABLE_DUMP_SIZE, _mali_uk_query_mmu_page_table_dump_size_s *) +#define MALI_IOC_MEM_DUMP_MMU_PAGE_TABLE _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_DUMP_MMU_PAGE_TABLE, _mali_uk_dump_mmu_page_table_s *) + +#define MALI_IOC_PP_START_JOB _IOWR(MALI_IOC_PP_BASE, _MALI_UK_PP_START_JOB, _mali_uk_pp_start_job_s *) +#define MALI_IOC_PP_NUMBER_OF_CORES_GET _IOR (MALI_IOC_PP_BASE, _MALI_UK_GET_PP_NUMBER_OF_CORES, _mali_uk_get_pp_number_of_cores_s *) +#define MALI_IOC_PP_CORE_VERSION_GET _IOR (MALI_IOC_PP_BASE, _MALI_UK_GET_PP_CORE_VERSION, _mali_uk_get_pp_core_version_s * ) +#define MALI_IOC_PP_DISABLE_WB _IOW (MALI_IOC_PP_BASE, _MALI_UK_PP_DISABLE_WB, _mali_uk_pp_disable_wb_s * ) + +#define MALI_IOC_GP2_START_JOB _IOWR(MALI_IOC_GP_BASE, _MALI_UK_GP_START_JOB, _mali_uk_gp_start_job_s *) +#define MALI_IOC_GP2_NUMBER_OF_CORES_GET _IOR (MALI_IOC_GP_BASE, _MALI_UK_GET_GP_NUMBER_OF_CORES, _mali_uk_get_gp_number_of_cores_s *) +#define MALI_IOC_GP2_CORE_VERSION_GET _IOR (MALI_IOC_GP_BASE, _MALI_UK_GET_GP_CORE_VERSION, _mali_uk_get_gp_core_version_s *) +#define MALI_IOC_GP2_SUSPEND_RESPONSE _IOW (MALI_IOC_GP_BASE, _MALI_UK_GP_SUSPEND_RESPONSE,_mali_uk_gp_suspend_response_s *) + +#define MALI_IOC_PROFILING_START _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_START, _mali_uk_profiling_start_s *) +#define MALI_IOC_PROFILING_ADD_EVENT _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_ADD_EVENT, _mali_uk_profiling_add_event_s*) +#define MALI_IOC_PROFILING_STOP _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_STOP, _mali_uk_profiling_stop_s *) +#define MALI_IOC_PROFILING_GET_EVENT _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_GET_EVENT, _mali_uk_profiling_get_event_s *) +#define MALI_IOC_PROFILING_CLEAR _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_CLEAR, _mali_uk_profiling_clear_s *) +#define MALI_IOC_PROFILING_GET_CONFIG _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_GET_CONFIG, _mali_uk_get_user_settings_s *) +#define MALI_IOC_PROFILING_REPORT_SW_COUNTERS _IOW (MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_REPORT_SW_COUNTERS, _mali_uk_sw_counters_report_s *) + +#define MALI_IOC_VSYNC_EVENT_REPORT _IOW (MALI_IOC_VSYNC_BASE, _MALI_UK_VSYNC_EVENT_REPORT, _mali_uk_vsync_event_report_s *) + +#ifdef __cplusplus +} +#endif + +#endif /* __MALI_UTGARD_IOCTL_H__ */ diff --git a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_profiling_events.h b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_profiling_events.h new file mode 100644 index 0000000..b96596e --- /dev/null +++ b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_profiling_events.h @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MALI_UTGARD_PROFILING_EVENTS_H_ +#define _MALI_UTGARD_PROFILING_EVENTS_H_ + +/* + * The event ID is a 32 bit value consisting of different fields + * reserved, 4 bits, for future use + * event type, 4 bits, cinstr_profiling_event_type_t + * event channel, 8 bits, the source of the event. + * event data, 16 bit field, data depending on event type + */ + +/** + * Specifies what kind of event this is + */ +typedef enum +{ + MALI_PROFILING_EVENT_TYPE_SINGLE = 0 << 24, + MALI_PROFILING_EVENT_TYPE_START = 1 << 24, + MALI_PROFILING_EVENT_TYPE_STOP = 2 << 24, + MALI_PROFILING_EVENT_TYPE_SUSPEND = 3 << 24, + MALI_PROFILING_EVENT_TYPE_RESUME = 4 << 24, +} cinstr_profiling_event_type_t; + + +/** + * Secifies the channel/source of the event + */ +typedef enum +{ + MALI_PROFILING_EVENT_CHANNEL_SOFTWARE = 0 << 16, + MALI_PROFILING_EVENT_CHANNEL_GP0 = 1 << 16, + MALI_PROFILING_EVENT_CHANNEL_PP0 = 5 << 16, + MALI_PROFILING_EVENT_CHANNEL_PP1 = 6 << 16, + MALI_PROFILING_EVENT_CHANNEL_PP2 = 7 << 16, + MALI_PROFILING_EVENT_CHANNEL_PP3 = 8 << 16, + MALI_PROFILING_EVENT_CHANNEL_PP4 = 9 << 16, + MALI_PROFILING_EVENT_CHANNEL_PP5 = 10 << 16, + MALI_PROFILING_EVENT_CHANNEL_PP6 = 11 << 16, + MALI_PROFILING_EVENT_CHANNEL_PP7 = 12 << 16, + MALI_PROFILING_EVENT_CHANNEL_GPU = 21 << 16, +} cinstr_profiling_event_channel_t; + + +#define MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(num) (((MALI_PROFILING_EVENT_CHANNEL_GP0 >> 16) + (num)) << 16) +#define MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(num) (((MALI_PROFILING_EVENT_CHANNEL_PP0 >> 16) + (num)) << 16) + +/** + * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SINGLE is used from software channel + */ +typedef enum +{ + MALI_PROFILING_EVENT_REASON_SINGLE_SW_NONE = 0, + MALI_PROFILING_EVENT_REASON_SINGLE_SW_EGL_NEW_FRAME = 1, + MALI_PROFILING_EVENT_REASON_SINGLE_SW_FLUSH = 2, + MALI_PROFILING_EVENT_REASON_SINGLE_SW_EGL_SWAP_BUFFERS = 3, + MALI_PROFILING_EVENT_REASON_SINGLE_SW_FB_EVENT = 4, + MALI_PROFILING_EVENT_REASON_SINGLE_SW_GP_ENQUEUE = 5, + MALI_PROFILING_EVENT_REASON_SINGLE_SW_PP_ENQUEUE = 6, + MALI_PROFILING_EVENT_REASON_SINGLE_SW_ENTER_API_FUNC = 10, + MALI_PROFILING_EVENT_REASON_SINGLE_SW_LEAVE_API_FUNC = 11, + MALI_PROFILING_EVENT_REASON_SINGLE_SW_UMP_TRY_LOCK = 53, + MALI_PROFILING_EVENT_REASON_SINGLE_SW_UMP_LOCK = 54, + MALI_PROFILING_EVENT_REASON_SINGLE_SW_UMP_UNLOCK = 55, +} cinstr_profiling_event_reason_single_sw_t; + +/** + * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_START/STOP is used from software channel + */ +typedef enum +{ + MALI_PROFILING_EVENT_REASON_START_STOP_SW_NONE = 0, + MALI_PROFILING_EVENT_REASON_START_STOP_MALI = 1, +} cinstr_profiling_event_reason_start_stop_sw_t; + +/** + * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SUSPEND/RESUME is used from software channel + */ +typedef enum +{ + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_NONE = 0, /* NOT used */ + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_PIPELINE_FULL = 1, /* NOT used */ + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VSYNC = 26, /* used in some build configurations */ + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_FB_IFRAME_WAIT = 27, /* USED */ + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_FB_IFRAME_SYNC = 28, /* USED */ + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VG_WAIT_FILTER_CLEANUP = 29, /* used */ + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VG_WAIT_TEXTURE = 30, /* used */ + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_GLES_WAIT_MIPLEVEL = 31, /* used */ + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_GLES_WAIT_READPIXELS = 32, /* used */ + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_EGL_WAIT_SWAP_IMMEDIATE= 33, /* NOT used */ + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_ICS_QUEUE_BUFFER = 34, /* USED */ + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_ICS_DEQUEUE_BUFFER = 35, /* USED */ + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_UMP_LOCK = 36, /* Not currently used */ + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_X11_GLOBAL_LOCK = 37, /* Not currently used */ + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_X11_SWAP = 38, /* Not currently used */ + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_MALI_EGL_IMAGE_SYNC_WAIT = 39, /* USED */ +} cinstr_profiling_event_reason_suspend_resume_sw_t; + +/** + * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SINGLE is used from a HW channel (GPx+PPx) + */ +typedef enum +{ + MALI_PROFILING_EVENT_REASON_SINGLE_HW_NONE = 0, + MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT = 1, + MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH = 2, +} cinstr_profiling_event_reason_single_hw_t; + +/** + * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SINGLE is used from the GPU channel + */ +typedef enum +{ + MALI_PROFILING_EVENT_REASON_SINGLE_GPU_NONE = 0, + MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE = 1, +} cinstr_profiling_event_reason_single_gpu_t; + +#endif /*_MALI_UTGARD_PROFILING_EVENTS_H_*/ diff --git a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_uk_types.h b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_uk_types.h new file mode 100644 index 0000000..b35a715 --- /dev/null +++ b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_uk_types.h @@ -0,0 +1,1095 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_uk_types.h + * Defines the types and constants used in the user-kernel interface + */ + +#ifndef __MALI_UTGARD_UK_TYPES_H__ +#define __MALI_UTGARD_UK_TYPES_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @addtogroup uddapi Unified Device Driver (UDD) APIs + * + * @{ + */ + +/** + * @addtogroup u_k_api UDD User/Kernel Interface (U/K) APIs + * + * @{ + */ + +/** @defgroup _mali_uk_core U/K Core + * @{ */ + +/** Definition of subsystem numbers, to assist in creating a unique identifier + * for each U/K call. + * + * @see _mali_uk_functions */ +typedef enum +{ + _MALI_UK_CORE_SUBSYSTEM, /**< Core Group of U/K calls */ + _MALI_UK_MEMORY_SUBSYSTEM, /**< Memory Group of U/K calls */ + _MALI_UK_PP_SUBSYSTEM, /**< Fragment Processor Group of U/K calls */ + _MALI_UK_GP_SUBSYSTEM, /**< Vertex Processor Group of U/K calls */ + _MALI_UK_PROFILING_SUBSYSTEM, /**< Profiling Group of U/K calls */ + _MALI_UK_PMM_SUBSYSTEM, /**< Power Management Module Group of U/K calls */ + _MALI_UK_VSYNC_SUBSYSTEM, /**< VSYNC Group of U/K calls */ +} _mali_uk_subsystem_t; + +/** Within a function group each function has its unique sequence number + * to assist in creating a unique identifier for each U/K call. + * + * An ordered pair of numbers selected from + * ( \ref _mali_uk_subsystem_t,\ref _mali_uk_functions) will uniquely identify the + * U/K call across all groups of functions, and all functions. */ +typedef enum +{ + /** Core functions */ + + _MALI_UK_OPEN = 0, /**< _mali_ukk_open() */ + _MALI_UK_CLOSE, /**< _mali_ukk_close() */ + _MALI_UK_WAIT_FOR_NOTIFICATION, /**< _mali_ukk_wait_for_notification() */ + _MALI_UK_GET_API_VERSION, /**< _mali_ukk_get_api_version() */ + _MALI_UK_POST_NOTIFICATION, /**< _mali_ukk_post_notification() */ + _MALI_UK_GET_USER_SETTING, /**< _mali_ukk_get_user_setting() *//**< [out] */ + _MALI_UK_GET_USER_SETTINGS, /**< _mali_ukk_get_user_settings() *//**< [out] */ + + /** Memory functions */ + + _MALI_UK_INIT_MEM = 0, /**< _mali_ukk_init_mem() */ + _MALI_UK_TERM_MEM, /**< _mali_ukk_term_mem() */ + _MALI_UK_GET_BIG_BLOCK, /**< _mali_ukk_get_big_block() */ + _MALI_UK_FREE_BIG_BLOCK, /**< _mali_ukk_free_big_block() */ + _MALI_UK_MAP_MEM, /**< _mali_ukk_mem_mmap() */ + _MALI_UK_UNMAP_MEM, /**< _mali_ukk_mem_munmap() */ + _MALI_UK_QUERY_MMU_PAGE_TABLE_DUMP_SIZE, /**< _mali_ukk_mem_get_mmu_page_table_dump_size() */ + _MALI_UK_DUMP_MMU_PAGE_TABLE, /**< _mali_ukk_mem_dump_mmu_page_table() */ + _MALI_UK_ATTACH_DMA_BUF, /**< _mali_ukk_attach_dma_buf() */ + _MALI_UK_RELEASE_DMA_BUF, /**< _mali_ukk_release_dma_buf() */ + _MALI_UK_DMA_BUF_GET_SIZE, /**< _mali_ukk_dma_buf_get_size() */ + _MALI_UK_ATTACH_UMP_MEM, /**< _mali_ukk_attach_ump_mem() */ + _MALI_UK_RELEASE_UMP_MEM, /**< _mali_ukk_release_ump_mem() */ + _MALI_UK_MAP_EXT_MEM, /**< _mali_uku_map_external_mem() */ + _MALI_UK_UNMAP_EXT_MEM, /**< _mali_uku_unmap_external_mem() */ + _MALI_UK_VA_TO_MALI_PA, /**< _mali_uku_va_to_mali_pa() */ + + /** Common functions for each core */ + + _MALI_UK_START_JOB = 0, /**< Start a Fragment/Vertex Processor Job on a core */ + _MALI_UK_GET_NUMBER_OF_CORES, /**< Get the number of Fragment/Vertex Processor cores */ + _MALI_UK_GET_CORE_VERSION, /**< Get the Fragment/Vertex Processor version compatible with all cores */ + + /** Fragment Processor Functions */ + + _MALI_UK_PP_START_JOB = _MALI_UK_START_JOB, /**< _mali_ukk_pp_start_job() */ + _MALI_UK_GET_PP_NUMBER_OF_CORES = _MALI_UK_GET_NUMBER_OF_CORES, /**< _mali_ukk_get_pp_number_of_cores() */ + _MALI_UK_GET_PP_CORE_VERSION = _MALI_UK_GET_CORE_VERSION, /**< _mali_ukk_get_pp_core_version() */ + _MALI_UK_PP_DISABLE_WB, /**< _mali_ukk_pp_job_disable_wb() */ + + /** Vertex Processor Functions */ + + _MALI_UK_GP_START_JOB = _MALI_UK_START_JOB, /**< _mali_ukk_gp_start_job() */ + _MALI_UK_GET_GP_NUMBER_OF_CORES = _MALI_UK_GET_NUMBER_OF_CORES, /**< _mali_ukk_get_gp_number_of_cores() */ + _MALI_UK_GET_GP_CORE_VERSION = _MALI_UK_GET_CORE_VERSION, /**< _mali_ukk_get_gp_core_version() */ + _MALI_UK_GP_SUSPEND_RESPONSE, /**< _mali_ukk_gp_suspend_response() */ + + /** Profiling functions */ + + _MALI_UK_PROFILING_START = 0, /**< __mali_uku_profiling_start() */ + _MALI_UK_PROFILING_ADD_EVENT, /**< __mali_uku_profiling_add_event() */ + _MALI_UK_PROFILING_STOP, /**< __mali_uku_profiling_stop() */ + _MALI_UK_PROFILING_GET_EVENT, /**< __mali_uku_profiling_get_event() */ + _MALI_UK_PROFILING_CLEAR, /**< __mali_uku_profiling_clear() */ + _MALI_UK_PROFILING_GET_CONFIG, /**< __mali_uku_profiling_get_config() */ + _MALI_UK_PROFILING_REPORT_SW_COUNTERS,/**< __mali_uku_profiling_report_sw_counters() */ + + /** VSYNC reporting fuctions */ + _MALI_UK_VSYNC_EVENT_REPORT = 0, /**< _mali_ukk_vsync_event_report() */ + +} _mali_uk_functions; + +/** @brief Get the size necessary for system info + * + * @see _mali_ukk_get_system_info_size() + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 size; /**< [out] size of buffer necessary to hold system information data, in bytes */ +} _mali_uk_get_system_info_size_s; + + +/** @defgroup _mali_uk_getsysteminfo U/K Get System Info + * @{ */ + +/** + * Type definition for the core version number. + * Used when returning the version number read from a core + * + * Its format is that of the 32-bit Version register for a particular core. + * Refer to the "Mali200 and MaliGP2 3D Graphics Processor Technical Reference + * Manual", ARM DDI 0415C, for more information. + */ +typedef u32 _mali_core_version; + +/** + * Enum values for the different modes the driver can be put in. + * Normal is the default mode. The driver then uses a job queue and takes job objects from the clients. + * Job completion is reported using the _mali_ukk_wait_for_notification call. + * The driver blocks this io command until a job has completed or failed or a timeout occurs. + * + * The 'raw' mode is reserved for future expansion. + */ +typedef enum _mali_driver_mode +{ + _MALI_DRIVER_MODE_RAW = 1, /**< Reserved for future expansion */ + _MALI_DRIVER_MODE_NORMAL = 2 /**< Normal mode of operation */ +} _mali_driver_mode; + +/** @brief List of possible cores + * + * add new entries to the end of this enum */ +typedef enum _mali_core_type +{ + _MALI_GP2 = 2, /**< MaliGP2 Programmable Vertex Processor */ + _MALI_200 = 5, /**< Mali200 Programmable Fragment Processor */ + _MALI_400_GP = 6, /**< Mali400 Programmable Vertex Processor */ + _MALI_400_PP = 7, /**< Mali400 Programmable Fragment Processor */ + /* insert new core here, do NOT alter the existing values */ +} _mali_core_type; + + +/** @brief Capabilities of Memory Banks + * + * These may be used to restrict memory banks for certain uses. They may be + * used when access is not possible (e.g. Bus does not support access to it) + * or when access is possible but not desired (e.g. Access is slow). + * + * In the case of 'possible but not desired', there is no way of specifying + * the flags as an optimization hint, so that the memory could be used as a + * last resort. + * + * @see _mali_mem_info + */ +typedef enum _mali_bus_usage +{ + + _MALI_PP_READABLE = (1<<0), /** Readable by the Fragment Processor */ + _MALI_PP_WRITEABLE = (1<<1), /** Writeable by the Fragment Processor */ + _MALI_GP_READABLE = (1<<2), /** Readable by the Vertex Processor */ + _MALI_GP_WRITEABLE = (1<<3), /** Writeable by the Vertex Processor */ + _MALI_CPU_READABLE = (1<<4), /** Readable by the CPU */ + _MALI_CPU_WRITEABLE = (1<<5), /** Writeable by the CPU */ + _MALI_GP_L2_ALLOC = (1<<6), /** GP allocate mali L2 cache lines*/ + _MALI_MMU_READABLE = _MALI_PP_READABLE | _MALI_GP_READABLE, /** Readable by the MMU (including all cores behind it) */ + _MALI_MMU_WRITEABLE = _MALI_PP_WRITEABLE | _MALI_GP_WRITEABLE, /** Writeable by the MMU (including all cores behind it) */ +} _mali_bus_usage; + +typedef enum mali_memory_cache_settings +{ + MALI_CACHE_STANDARD = 0, + MALI_CACHE_GP_READ_ALLOCATE = 1, +} mali_memory_cache_settings ; + + +/** @brief Information about the Mali Memory system + * + * Information is stored in a linked list, which is stored entirely in the + * buffer pointed to by the system_info member of the + * _mali_uk_get_system_info_s arguments provided to _mali_ukk_get_system_info() + * + * Each element of the linked list describes a single Mali Memory bank. + * Each allocation can only come from one bank, and will not cross multiple + * banks. + * + * On Mali-MMU systems, there is only one bank, which describes the maximum + * possible address range that could be allocated (which may be much less than + * the available physical memory) + * + * The flags member describes the capabilities of the memory. It is an error + * to attempt to build a job for a particular core (PP or GP) when the memory + * regions used do not have the capabilities for supporting that core. This + * would result in a job abort from the Device Driver. + * + * For example, it is correct to build a PP job where read-only data structures + * are taken from a memory with _MALI_PP_READABLE set and + * _MALI_PP_WRITEABLE clear, and a framebuffer with _MALI_PP_WRITEABLE set and + * _MALI_PP_READABLE clear. However, it would be incorrect to use a framebuffer + * where _MALI_PP_WRITEABLE is clear. + */ +typedef struct _mali_mem_info +{ + u32 size; /**< Size of the memory bank in bytes */ + _mali_bus_usage flags; /**< Capabilitiy flags of the memory */ + u32 maximum_order_supported; /**< log2 supported size */ + u32 identifier; /* mali_memory_cache_settings cache_settings; */ + struct _mali_mem_info * next; /**< Next List Link */ +} _mali_mem_info; + + + +/** @} */ /* end group _mali_uk_core */ + + +/** @defgroup _mali_uk_gp U/K Vertex Processor + * @{ */ + +/** @defgroup _mali_uk_gp_suspend_response_s Vertex Processor Suspend Response + * @{ */ + +/** @brief Arguments for _mali_ukk_gp_suspend_response() + * + * When _mali_wait_for_notification() receives notification that a + * Vertex Processor job was suspended, you need to send a response to indicate + * what needs to happen with this job. You can either abort or resume the job. + * + * - set @c code to indicate response code. This is either @c _MALIGP_JOB_ABORT or + * @c _MALIGP_JOB_RESUME_WITH_NEW_HEAP to indicate you will provide a new heap + * for the job that will resolve the out of memory condition for the job. + * - copy the @c cookie value from the @c _mali_uk_gp_job_suspended_s notification; + * this is an identifier for the suspended job + * - set @c arguments[0] and @c arguments[1] to zero if you abort the job. If + * you resume it, @c argument[0] should specify the Mali start address for the new + * heap and @c argument[1] the Mali end address of the heap. + * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open() + * + */ +typedef enum _maligp_job_suspended_response_code +{ + _MALIGP_JOB_ABORT, /**< Abort the Vertex Processor job */ + _MALIGP_JOB_RESUME_WITH_NEW_HEAP /**< Resume the Vertex Processor job with a new heap */ +} _maligp_job_suspended_response_code; + +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 cookie; /**< [in] cookie from the _mali_uk_gp_job_suspended_s notification */ + _maligp_job_suspended_response_code code; /**< [in] abort or resume response code, see \ref _maligp_job_suspended_response_code */ + u32 arguments[2]; /**< [in] 0 when aborting a job. When resuming a job, the Mali start and end address for a new heap to resume the job with */ +} _mali_uk_gp_suspend_response_s; + +/** @} */ /* end group _mali_uk_gp_suspend_response_s */ + +/** @defgroup _mali_uk_gpstartjob_s Vertex Processor Start Job + * @{ */ + +/** @brief Status indicating the result of starting a Vertex or Fragment processor job */ +typedef enum +{ + _MALI_UK_START_JOB_STARTED, /**< Job started */ + _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE /**< Job could not be started at this time. Try starting the job again */ +} _mali_uk_start_job_status; + +/** @brief Status indicating the result of the execution of a Vertex or Fragment processor job */ + +typedef enum +{ + _MALI_UK_JOB_STATUS_END_SUCCESS = 1<<(16+0), + _MALI_UK_JOB_STATUS_END_OOM = 1<<(16+1), + _MALI_UK_JOB_STATUS_END_ABORT = 1<<(16+2), + _MALI_UK_JOB_STATUS_END_TIMEOUT_SW = 1<<(16+3), + _MALI_UK_JOB_STATUS_END_HANG = 1<<(16+4), + _MALI_UK_JOB_STATUS_END_SEG_FAULT = 1<<(16+5), + _MALI_UK_JOB_STATUS_END_ILLEGAL_JOB = 1<<(16+6), + _MALI_UK_JOB_STATUS_END_UNKNOWN_ERR = 1<<(16+7), + _MALI_UK_JOB_STATUS_END_SHUTDOWN = 1<<(16+8), + _MALI_UK_JOB_STATUS_END_SYSTEM_UNUSABLE = 1<<(16+9) +} _mali_uk_job_status; + +#define MALIGP2_NUM_REGS_FRAME (6) + +/** @brief Arguments for _mali_ukk_gp_start_job() + * + * To start a Vertex Processor job + * - associate the request with a reference to a @c mali_gp_job_info by setting + * user_job_ptr to the address of the @c mali_gp_job_info of the job. + * - set @c priority to the priority of the @c mali_gp_job_info + * - specify a timeout for the job by setting @c watchdog_msecs to the number of + * milliseconds the job is allowed to run. Specifying a value of 0 selects the + * default timeout in use by the device driver. + * - copy the frame registers from the @c mali_gp_job_info into @c frame_registers. + * - set the @c perf_counter_flag, @c perf_counter_src0 and @c perf_counter_src1 to zero + * for a non-instrumented build. For an instrumented build you can use up + * to two performance counters. Set the corresponding bit in @c perf_counter_flag + * to enable them. @c perf_counter_src0 and @c perf_counter_src1 specify + * the source of what needs to get counted (e.g. number of vertex loader + * cache hits). For source id values, see ARM DDI0415A, Table 3-60. + * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open() + * + * When @c _mali_ukk_gp_start_job() returns @c _MALI_OSK_ERR_OK, status contains the + * result of the request (see \ref _mali_uk_start_job_status). If the job could + * not get started (@c _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE) it should be + * tried again. + * + * After the job has started, @c _mali_wait_for_notification() will be notified + * that the job finished or got suspended. It may get suspended due to + * resource shortage. If it finished (see _mali_ukk_wait_for_notification()) + * the notification will contain a @c _mali_uk_gp_job_finished_s result. If + * it got suspended the notification will contain a @c _mali_uk_gp_job_suspended_s + * result. + * + * The @c _mali_uk_gp_job_finished_s contains the job status (see \ref _mali_uk_job_status), + * the number of milliseconds the job took to render, and values of core registers + * when the job finished (irq status, performance counters, renderer list + * address). A job has finished succesfully when its status is + * @c _MALI_UK_JOB_STATUS_FINISHED. If the hardware detected a timeout while rendering + * the job, or software detected the job is taking more than watchdog_msecs to + * complete, the status will indicate @c _MALI_UK_JOB_STATUS_HANG. + * If the hardware detected a bus error while accessing memory associated with the + * job, status will indicate @c _MALI_UK_JOB_STATUS_SEG_FAULT. + * status will indicate @c _MALI_UK_JOB_STATUS_NOT_STARTED if the driver had to + * stop the job but the job didn't start on the hardware yet, e.g. when the + * driver shutdown. + * + * In case the job got suspended, @c _mali_uk_gp_job_suspended_s contains + * the @c user_job_ptr identifier used to start the job with, the @c reason + * why the job stalled (see \ref _maligp_job_suspended_reason) and a @c cookie + * to identify the core on which the job stalled. This @c cookie will be needed + * when responding to this nofication by means of _mali_ukk_gp_suspend_response(). + * (see _mali_ukk_gp_suspend_response()). The response is either to abort or + * resume the job. If the job got suspended due to an out of memory condition + * you may be able to resolve this by providing more memory and resuming the job. + * + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 user_job_ptr; /**< [in] identifier for the job in user space, a @c mali_gp_job_info* */ + u32 priority; /**< [in] job priority. A lower number means higher priority */ + u32 frame_registers[MALIGP2_NUM_REGS_FRAME]; /**< [in] core specific registers associated with this job */ + u32 perf_counter_flag; /**< [in] bitmask indicating which performance counters to enable, see \ref _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE and related macro definitions */ + u32 perf_counter_src0; /**< [in] source id for performance counter 0 (see ARM DDI0415A, Table 3-60) */ + u32 perf_counter_src1; /**< [in] source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */ + u32 frame_builder_id; /**< [in] id of the originating frame builder */ + u32 flush_id; /**< [in] flush id within the originating frame builder */ +} _mali_uk_gp_start_job_s; + +#define _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE (1<<0) /**< Enable performance counter SRC0 for a job */ +#define _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE (1<<1) /**< Enable performance counter SRC1 for a job */ + +/** @} */ /* end group _mali_uk_gpstartjob_s */ + +typedef struct +{ + u32 user_job_ptr; /**< [out] identifier for the job in user space */ + _mali_uk_job_status status; /**< [out] status of finished job */ + u32 heap_current_addr; /**< [out] value of the GP PLB PL heap start address register */ + u32 perf_counter0; /**< [out] value of perfomance counter 0 (see ARM DDI0415A) */ + u32 perf_counter1; /**< [out] value of perfomance counter 1 (see ARM DDI0415A) */ +} _mali_uk_gp_job_finished_s; + +typedef enum _maligp_job_suspended_reason +{ + _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY /**< Polygon list builder unit (PLBU) has run out of memory */ +} _maligp_job_suspended_reason; + +typedef struct +{ + u32 user_job_ptr; /**< [out] identifier for the job in user space */ + _maligp_job_suspended_reason reason; /**< [out] reason why the job stalled */ + u32 cookie; /**< [out] identifier for the core in kernel space on which the job stalled */ +} _mali_uk_gp_job_suspended_s; + +/** @} */ /* end group _mali_uk_gp */ + + +/** @defgroup _mali_uk_pp U/K Fragment Processor + * @{ */ + +#define _MALI_PP_MAX_SUB_JOBS 8 + +#define _MALI_PP_MAX_FRAME_REGISTERS ((0x058/4)+1) + +#define _MALI_PP_MAX_WB_REGISTERS ((0x02C/4)+1) + +/** Flag for _mali_uk_pp_start_job_s */ +#define _MALI_PP_JOB_FLAG_NO_NOTIFICATION (1<<0) +#define _MALI_PP_JOB_FLAG_BARRIER (1<<1) + +/** @defgroup _mali_uk_ppstartjob_s Fragment Processor Start Job + * @{ */ + +/** @brief Arguments for _mali_ukk_pp_start_job() + * + * To start a Fragment Processor job + * - associate the request with a reference to a mali_pp_job by setting + * @c user_job_ptr to the address of the @c mali_pp_job of the job. + * - set @c priority to the priority of the mali_pp_job + * - specify a timeout for the job by setting @c watchdog_msecs to the number of + * milliseconds the job is allowed to run. Specifying a value of 0 selects the + * default timeout in use by the device driver. + * - copy the frame registers from the @c mali_pp_job into @c frame_registers. + * For MALI200 you also need to copy the write back 0,1 and 2 registers. + * - set the @c perf_counter_flag, @c perf_counter_src0 and @c perf_counter_src1 to zero + * for a non-instrumented build. For an instrumented build you can use up + * to two performance counters. Set the corresponding bit in @c perf_counter_flag + * to enable them. @c perf_counter_src0 and @c perf_counter_src1 specify + * the source of what needs to get counted (e.g. number of vertex loader + * cache hits). For source id values, see ARM DDI0415A, Table 3-60. + * - pass in the user-kernel context in @c ctx that was returned from _mali_ukk_open() + * + * When _mali_ukk_pp_start_job() returns @c _MALI_OSK_ERR_OK, @c status contains the + * result of the request (see \ref _mali_uk_start_job_status). If the job could + * not get started (@c _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE) it should be + * tried again. + * + * After the job has started, _mali_wait_for_notification() will be notified + * when the job finished. The notification will contain a + * @c _mali_uk_pp_job_finished_s result. It contains the @c user_job_ptr + * identifier used to start the job with, the job @c status (see \ref _mali_uk_job_status), + * the number of milliseconds the job took to render, and values of core registers + * when the job finished (irq status, performance counters, renderer list + * address). A job has finished succesfully when its status is + * @c _MALI_UK_JOB_STATUS_FINISHED. If the hardware detected a timeout while rendering + * the job, or software detected the job is taking more than @c watchdog_msecs to + * complete, the status will indicate @c _MALI_UK_JOB_STATUS_HANG. + * If the hardware detected a bus error while accessing memory associated with the + * job, status will indicate @c _MALI_UK_JOB_STATUS_SEG_FAULT. + * status will indicate @c _MALI_UK_JOB_STATUS_NOT_STARTED if the driver had to + * stop the job but the job didn't start on the hardware yet, e.g. when the + * driver shutdown. + * + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 user_job_ptr; /**< [in] identifier for the job in user space */ + u32 priority; /**< [in] job priority. A lower number means higher priority */ + u32 frame_registers[_MALI_PP_MAX_FRAME_REGISTERS]; /**< [in] core specific registers associated with first sub job, see ARM DDI0415A */ + u32 frame_registers_addr_frame[_MALI_PP_MAX_SUB_JOBS - 1]; /**< [in] ADDR_FRAME registers for sub job 1-7 */ + u32 frame_registers_addr_stack[_MALI_PP_MAX_SUB_JOBS - 1]; /**< [in] ADDR_STACK registers for sub job 1-7 */ + u32 wb0_registers[_MALI_PP_MAX_WB_REGISTERS]; + u32 wb1_registers[_MALI_PP_MAX_WB_REGISTERS]; + u32 wb2_registers[_MALI_PP_MAX_WB_REGISTERS]; + u32 num_cores; /**< [in] Number of cores to set up (valid range: 1-4) */ + u32 perf_counter_flag; /**< [in] bitmask indicating which performance counters to enable, see \ref _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE and related macro definitions */ + u32 perf_counter_src0; /**< [in] source id for performance counter 0 (see ARM DDI0415A, Table 3-60) */ + u32 perf_counter_src1; /**< [in] source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */ + u32 frame_builder_id; /**< [in] id of the originating frame builder */ + u32 flush_id; /**< [in] flush id within the originating frame builder */ + u32 flags; /**< [in] See _MALI_PP_JOB_FLAG_* for a list of avaiable flags */ +} _mali_uk_pp_start_job_s; +/** @} */ /* end group _mali_uk_ppstartjob_s */ + +typedef struct +{ + u32 user_job_ptr; /**< [out] identifier for the job in user space */ + _mali_uk_job_status status; /**< [out] status of finished job */ + u32 perf_counter0[_MALI_PP_MAX_SUB_JOBS]; /**< [out] value of perfomance counter 0 (see ARM DDI0415A), one for each sub job */ + u32 perf_counter1[_MALI_PP_MAX_SUB_JOBS]; /**< [out] value of perfomance counter 1 (see ARM DDI0415A), one for each sub job */ +} _mali_uk_pp_job_finished_s; + +/** + * Flags to indicate write-back units + */ +typedef enum +{ + _MALI_UK_PP_JOB_WB0 = 1, + _MALI_UK_PP_JOB_WB1 = 2, + _MALI_UK_PP_JOB_WB2 = 4, +} _mali_uk_pp_job_wbx_flag; + +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 fb_id; /**< [in] Frame builder ID of job to disable WB units for */ + u32 flush_id; /**< [in] Flush ID of job to disable WB units for */ + _mali_uk_pp_job_wbx_flag wbx; /**< [in] write-back units to disable */ +} _mali_uk_pp_disable_wb_s; + + +/** @} */ /* end group _mali_uk_pp */ + + +/** @addtogroup _mali_uk_core U/K Core + * @{ */ + +/** @defgroup _mali_uk_waitfornotification_s Wait For Notification + * @{ */ + +/** @brief Notification type encodings + * + * Each Notification type is an ordered pair of (subsystem,id), and is unique. + * + * The encoding of subsystem,id into a 32-bit word is: + * encoding = (( subsystem << _MALI_NOTIFICATION_SUBSYSTEM_SHIFT ) & _MALI_NOTIFICATION_SUBSYSTEM_MASK) + * | (( id << _MALI_NOTIFICATION_ID_SHIFT ) & _MALI_NOTIFICATION_ID_MASK) + * + * @see _mali_uk_wait_for_notification_s + */ +typedef enum +{ + /** core notifications */ + + _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS = (_MALI_UK_CORE_SUBSYSTEM << 16) | 0x20, + _MALI_NOTIFICATION_APPLICATION_QUIT = (_MALI_UK_CORE_SUBSYSTEM << 16) | 0x40, + _MALI_NOTIFICATION_SETTINGS_CHANGED = (_MALI_UK_CORE_SUBSYSTEM << 16) | 0x80, + + /** Fragment Processor notifications */ + + _MALI_NOTIFICATION_PP_FINISHED = (_MALI_UK_PP_SUBSYSTEM << 16) | 0x10, + + /** Vertex Processor notifications */ + + _MALI_NOTIFICATION_GP_FINISHED = (_MALI_UK_GP_SUBSYSTEM << 16) | 0x10, + _MALI_NOTIFICATION_GP_STALLED = (_MALI_UK_GP_SUBSYSTEM << 16) | 0x20, + +} _mali_uk_notification_type; + +/** to assist in splitting up 32-bit notification value in subsystem and id value */ +#define _MALI_NOTIFICATION_SUBSYSTEM_MASK 0xFFFF0000 +#define _MALI_NOTIFICATION_SUBSYSTEM_SHIFT 16 +#define _MALI_NOTIFICATION_ID_MASK 0x0000FFFF +#define _MALI_NOTIFICATION_ID_SHIFT 0 + + +/** @brief Enumeration of possible settings which match mali_setting_t in user space + * + * + */ +typedef enum +{ + _MALI_UK_USER_SETTING_SW_EVENTS_ENABLE = 0, + _MALI_UK_USER_SETTING_COLORBUFFER_CAPTURE_ENABLED, + _MALI_UK_USER_SETTING_DEPTHBUFFER_CAPTURE_ENABLED, + _MALI_UK_USER_SETTING_STENCILBUFFER_CAPTURE_ENABLED, + _MALI_UK_USER_SETTING_PER_TILE_COUNTERS_CAPTURE_ENABLED, + _MALI_UK_USER_SETTING_BUFFER_CAPTURE_COMPOSITOR, + _MALI_UK_USER_SETTING_BUFFER_CAPTURE_WINDOW, + _MALI_UK_USER_SETTING_BUFFER_CAPTURE_OTHER, + _MALI_UK_USER_SETTING_BUFFER_CAPTURE_N_FRAMES, + _MALI_UK_USER_SETTING_BUFFER_CAPTURE_RESIZE_FACTOR, + _MALI_UK_USER_SETTING_SW_COUNTER_ENABLED, + _MALI_UK_USER_SETTING_MAX, +} _mali_uk_user_setting_t; + +/* See mali_user_settings_db.c */ +extern const char *_mali_uk_user_setting_descriptions[]; +#define _MALI_UK_USER_SETTING_DESCRIPTIONS \ +{ \ + "sw_events_enable", \ + "colorbuffer_capture_enable", \ + "depthbuffer_capture_enable", \ + "stencilbuffer_capture_enable", \ + "per_tile_counters_enable", \ + "buffer_capture_compositor", \ + "buffer_capture_window", \ + "buffer_capture_other", \ + "buffer_capture_n_frames", \ + "buffer_capture_resize_factor", \ + "sw_counters_enable", \ +}; + +/** @brief struct to hold the value to a particular setting as seen in the kernel space + */ +typedef struct +{ + _mali_uk_user_setting_t setting; + u32 value; +} _mali_uk_settings_changed_s; + +/** @brief Arguments for _mali_ukk_wait_for_notification() + * + * On successful return from _mali_ukk_wait_for_notification(), the members of + * this structure will indicate the reason for notification. + * + * Specifically, the source of the notification can be identified by the + * subsystem and id fields of the mali_uk_notification_type in the code.type + * member. The type member is encoded in a way to divide up the types into a + * subsystem field, and a per-subsystem ID field. See + * _mali_uk_notification_type for more information. + * + * Interpreting the data union member depends on the notification type: + * + * - type == _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS + * - The kernel side is shutting down. No further + * _mali_uk_wait_for_notification() calls should be made. + * - In this case, the value of the data union member is undefined. + * - This is used to indicate to the user space client that it should close + * the connection to the Mali Device Driver. + * - type == _MALI_NOTIFICATION_PP_FINISHED + * - The notification data is of type _mali_uk_pp_job_finished_s. It contains the user_job_ptr + * identifier used to start the job with, the job status, the number of milliseconds the job took to render, + * and values of core registers when the job finished (irq status, performance counters, renderer list + * address). + * - A job has finished succesfully when its status member is _MALI_UK_JOB_STATUS_FINISHED. + * - If the hardware detected a timeout while rendering the job, or software detected the job is + * taking more than watchdog_msecs (see _mali_ukk_pp_start_job()) to complete, the status member will + * indicate _MALI_UK_JOB_STATUS_HANG. + * - If the hardware detected a bus error while accessing memory associated with the job, status will + * indicate _MALI_UK_JOB_STATUS_SEG_FAULT. + * - Status will indicate MALI_UK_JOB_STATUS_NOT_STARTED if the driver had to stop the job but the job + * didn't start the hardware yet, e.g. when the driver closes. + * - type == _MALI_NOTIFICATION_GP_FINISHED + * - The notification data is of type _mali_uk_gp_job_finished_s. The notification is similar to that of + * type == _MALI_NOTIFICATION_PP_FINISHED, except that several other GP core register values are returned. + * The status values have the same meaning for type == _MALI_NOTIFICATION_PP_FINISHED. + * - type == _MALI_NOTIFICATION_GP_STALLED + * - The nofication data is of type _mali_uk_gp_job_suspended_s. It contains the user_job_ptr + * identifier used to start the job with, the reason why the job stalled and a cookie to identify the core on + * which the job stalled. + * - The reason member of gp_job_suspended is set to _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY + * when the polygon list builder unit has run out of memory. + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + _mali_uk_notification_type type; /**< [out] Type of notification available */ + union + { + _mali_uk_gp_job_suspended_s gp_job_suspended;/**< [out] Notification data for _MALI_NOTIFICATION_GP_STALLED notification type */ + _mali_uk_gp_job_finished_s gp_job_finished; /**< [out] Notification data for _MALI_NOTIFICATION_GP_FINISHED notification type */ + _mali_uk_pp_job_finished_s pp_job_finished; /**< [out] Notification data for _MALI_NOTIFICATION_PP_FINISHED notification type */ + _mali_uk_settings_changed_s setting_changed;/**< [out] Notification data for _MALI_NOTIFICAATION_SETTINGS_CHANGED notification type */ + } data; +} _mali_uk_wait_for_notification_s; + +/** @brief Arguments for _mali_ukk_post_notification() + * + * Posts the specified notification to the notification queue for this application. + * This is used to send a quit message to the callback thread. + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + _mali_uk_notification_type type; /**< [in] Type of notification to post */ +} _mali_uk_post_notification_s; + +/** @} */ /* end group _mali_uk_waitfornotification_s */ + +/** @defgroup _mali_uk_getapiversion_s Get API Version + * @{ */ + +/** helpers for Device Driver API version handling */ + +/** @brief Encode a version ID from a 16-bit input + * + * @note the input is assumed to be 16 bits. It must not exceed 16 bits. */ +#define _MAKE_VERSION_ID(x) (((x) << 16UL) | (x)) + +/** @brief Check whether a 32-bit value is likely to be Device Driver API + * version ID. */ +#define _IS_VERSION_ID(x) (((x) & 0xFFFF) == (((x) >> 16UL) & 0xFFFF)) + +/** @brief Decode a 16-bit version number from a 32-bit Device Driver API version + * ID */ +#define _GET_VERSION(x) (((x) >> 16UL) & 0xFFFF) + +/** @brief Determine whether two 32-bit encoded version IDs match */ +#define _IS_API_MATCH(x, y) (IS_VERSION_ID((x)) && IS_VERSION_ID((y)) && (GET_VERSION((x)) == GET_VERSION((y)))) + +/** + * API version define. + * Indicates the version of the kernel API + * The version is a 16bit integer incremented on each API change. + * The 16bit integer is stored twice in a 32bit integer + * For example, for version 1 the value would be 0x00010001 + */ +#define _MALI_API_VERSION 17 +#define _MALI_UK_API_VERSION _MAKE_VERSION_ID(_MALI_API_VERSION) + +/** + * The API version is a 16-bit integer stored in both the lower and upper 16-bits + * of a 32-bit value. The 16-bit API version value is incremented on each API + * change. Version 1 would be 0x00010001. Used in _mali_uk_get_api_version_s. + */ +typedef u32 _mali_uk_api_version; + +/** @brief Arguments for _mali_uk_get_api_version() + * + * The user-side interface version must be written into the version member, + * encoded using _MAKE_VERSION_ID(). It will be compared to the API version of + * the kernel-side interface. + * + * On successful return, the version member will be the API version of the + * kernel-side interface. _MALI_UK_API_VERSION macro defines the current version + * of the API. + * + * The compatible member must be checked to see if the version of the user-side + * interface is compatible with the kernel-side interface, since future versions + * of the interface may be backwards compatible. + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + _mali_uk_api_version version; /**< [in,out] API version of user-side interface. */ + int compatible; /**< [out] @c 1 when @version is compatible, @c 0 otherwise */ +} _mali_uk_get_api_version_s; +/** @} */ /* end group _mali_uk_getapiversion_s */ + +/** @defgroup _mali_uk_get_user_settings_s Get user space settings */ + +/** @brief struct to keep the matching values of the user space settings within certain context + * + * Each member of the settings array corresponds to a matching setting in the user space and its value is the value + * of that particular setting. + * + * All settings are given reference to the context pointed to by the ctx pointer. + * + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 settings[_MALI_UK_USER_SETTING_MAX]; /**< [out] The values for all settings */ +} _mali_uk_get_user_settings_s; + +/** @brief struct to hold the value of a particular setting from the user space within a given context + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + _mali_uk_user_setting_t setting; /**< [in] setting to get */ + u32 value; /**< [out] value of setting */ +} _mali_uk_get_user_setting_s; + +/** @} */ /* end group _mali_uk_core */ + + +/** @defgroup _mali_uk_memory U/K Memory + * @{ */ + +/** @brief Arguments for _mali_ukk_init_mem(). */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 mali_address_base; /**< [out] start of MALI address space */ + u32 memory_size; /**< [out] total MALI address space available */ +} _mali_uk_init_mem_s; + +/** @brief Arguments for _mali_ukk_term_mem(). */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ +} _mali_uk_term_mem_s; + +/** Flag for _mali_uk_map_external_mem_s, _mali_uk_attach_ump_mem_s and _mali_uk_attach_dma_buf_s */ +#define _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE (1<<0) + +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 phys_addr; /**< [in] physical address */ + u32 size; /**< [in] size */ + u32 mali_address; /**< [in] mali address to map the physical memory to */ + u32 rights; /**< [in] rights necessary for accessing memory */ + u32 flags; /**< [in] flags, see \ref _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE */ + u32 cookie; /**< [out] identifier for mapped memory object in kernel space */ +} _mali_uk_map_external_mem_s; + +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 cookie; /**< [out] identifier for mapped memory object in kernel space */ +} _mali_uk_unmap_external_mem_s; + +/** @note This is identical to _mali_uk_map_external_mem_s above, however phys_addr is replaced by memory descriptor */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 mem_fd; /**< [in] Memory descriptor */ + u32 size; /**< [in] size */ + u32 mali_address; /**< [in] mali address to map the physical memory to */ + u32 rights; /**< [in] rights necessary for accessing memory */ + u32 flags; /**< [in] flags, see \ref _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE */ + u32 cookie; /**< [out] identifier for mapped memory object in kernel space */ +} _mali_uk_attach_dma_buf_s; + +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 mem_fd; /**< [in] Memory descriptor */ + u32 size; /**< [out] size */ +} _mali_uk_dma_buf_get_size_s; + +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 cookie; /**< [in] identifier for mapped memory object in kernel space */ +} _mali_uk_release_dma_buf_s; + +/** @note This is identical to _mali_uk_map_external_mem_s above, however phys_addr is replaced by secure_id */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 secure_id; /**< [in] secure id */ + u32 size; /**< [in] size */ + u32 mali_address; /**< [in] mali address to map the physical memory to */ + u32 rights; /**< [in] rights necessary for accessing memory */ + u32 flags; /**< [in] flags, see \ref _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE */ + u32 cookie; /**< [out] identifier for mapped memory object in kernel space */ +} _mali_uk_attach_ump_mem_s; + +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 cookie; /**< [in] identifier for mapped memory object in kernel space */ +} _mali_uk_release_ump_mem_s; + +/** @brief Arguments for _mali_ukk_va_to_mali_pa() + * + * if size is zero or not a multiple of the system's page size, it will be + * rounded up to the next multiple of the page size. This will occur before + * any other use of the size parameter. + * + * if va is not PAGE_SIZE aligned, it will be rounded down to the next page + * boundary. + * + * The range (va) to ((u32)va)+(size-1) inclusive will be checked for physical + * contiguity. + * + * The implementor will check that the entire physical range is allowed to be mapped + * into user-space. + * + * Failure will occur if either of the above are not satisfied. + * + * Otherwise, the physical base address of the range is returned through pa, + * va is updated to be page aligned, and size is updated to be a non-zero + * multiple of the system's pagesize. + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + void *va; /**< [in,out] Virtual address of the start of the range */ + u32 pa; /**< [out] Physical base address of the range */ + u32 size; /**< [in,out] Size of the range, in bytes. */ +} _mali_uk_va_to_mali_pa_s; + + +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 size; /**< [out] size of MMU page table information (registers + page tables) */ +} _mali_uk_query_mmu_page_table_dump_size_s; + +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 size; /**< [in] size of buffer to receive mmu page table information */ + void *buffer; /**< [in,out] buffer to receive mmu page table information */ + u32 register_writes_size; /**< [out] size of MMU register dump */ + u32 *register_writes; /**< [out] pointer within buffer where MMU register dump is stored */ + u32 page_table_dump_size; /**< [out] size of MMU page table dump */ + u32 *page_table_dump; /**< [out] pointer within buffer where MMU page table dump is stored */ +} _mali_uk_dump_mmu_page_table_s; + +/** @} */ /* end group _mali_uk_memory */ + + +/** @addtogroup _mali_uk_pp U/K Fragment Processor + * @{ */ + +/** @brief Arguments for _mali_ukk_get_pp_number_of_cores() + * + * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open() + * - Upon successful return from _mali_ukk_get_pp_number_of_cores(), @c number_of_cores + * will contain the number of Fragment Processor cores in the system. + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 number_of_cores; /**< [out] number of Fragment Processor cores in the system */ +} _mali_uk_get_pp_number_of_cores_s; + +/** @brief Arguments for _mali_ukk_get_pp_core_version() + * + * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open() + * - Upon successful return from _mali_ukk_get_pp_core_version(), @c version contains + * the version that all Fragment Processor cores are compatible with. + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + _mali_core_version version; /**< [out] version returned from core, see \ref _mali_core_version */ +} _mali_uk_get_pp_core_version_s; + +/** @} */ /* end group _mali_uk_pp */ + + +/** @addtogroup _mali_uk_gp U/K Vertex Processor + * @{ */ + +/** @brief Arguments for _mali_ukk_get_gp_number_of_cores() + * + * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open() + * - Upon successful return from _mali_ukk_get_gp_number_of_cores(), @c number_of_cores + * will contain the number of Vertex Processor cores in the system. + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 number_of_cores; /**< [out] number of Vertex Processor cores in the system */ +} _mali_uk_get_gp_number_of_cores_s; + +/** @brief Arguments for _mali_ukk_get_gp_core_version() + * + * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open() + * - Upon successful return from _mali_ukk_get_gp_core_version(), @c version contains + * the version that all Vertex Processor cores are compatible with. + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + _mali_core_version version; /**< [out] version returned from core, see \ref _mali_core_version */ +} _mali_uk_get_gp_core_version_s; + +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 limit; /**< [in,out] The desired limit for number of events to record on input, actual limit on output */ +} _mali_uk_profiling_start_s; + +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 event_id; /**< [in] event id to register (see enum mali_profiling_events for values) */ + u32 data[5]; /**< [in] event specific data */ +} _mali_uk_profiling_add_event_s; + +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 count; /**< [out] The number of events sampled */ +} _mali_uk_profiling_stop_s; + +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 index; /**< [in] which index to get (starting at zero) */ + u64 timestamp; /**< [out] timestamp of event */ + u32 event_id; /**< [out] event id of event (see enum mali_profiling_events for values) */ + u32 data[5]; /**< [out] event specific data */ +} _mali_uk_profiling_get_event_s; + +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ +} _mali_uk_profiling_clear_s; + +/** @} */ /* end group _mali_uk_gp */ + + +/** @addtogroup _mali_uk_memory U/K Memory + * @{ */ + +/** @brief Arguments to _mali_ukk_mem_mmap() + * + * Use of the phys_addr member depends on whether the driver is compiled for + * Mali-MMU or nonMMU: + * - in the nonMMU case, this is the physical address of the memory as seen by + * the CPU (which may be a constant offset from that used by Mali) + * - in the MMU case, this is the Mali Virtual base address of the memory to + * allocate, and the particular physical pages used to back the memory are + * entirely determined by _mali_ukk_mem_mmap(). The details of the physical pages + * are not reported to user-space for security reasons. + * + * The cookie member must be stored for use later when freeing the memory by + * calling _mali_ukk_mem_munmap(). In the Mali-MMU case, the cookie is secure. + * + * The ukk_private word must be set to zero when calling from user-space. On + * Kernel-side, the OS implementation of the U/K interface can use it to + * communicate data to the OS implementation of the OSK layer. In particular, + * _mali_ukk_get_big_block() directly calls _mali_ukk_mem_mmap directly, and + * will communicate its own ukk_private word through the ukk_private member + * here. The common code itself will not inspect or modify the ukk_private + * word, and so it may be safely used for whatever purposes necessary to + * integrate Mali Memory handling into the OS. + * + * The uku_private member is currently reserved for use by the user-side + * implementation of the U/K interface. Its value must be zero. + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + void *mapping; /**< [out] Returns user-space virtual address for the mapping */ + u32 size; /**< [in] Size of the requested mapping */ + u32 phys_addr; /**< [in] Physical address - could be offset, depending on caller+callee convention */ + u32 cookie; /**< [out] Returns a cookie for use in munmap calls */ + void *uku_private; /**< [in] User-side Private word used by U/K interface */ + void *ukk_private; /**< [in] Kernel-side Private word used by U/K interface */ + mali_memory_cache_settings cache_settings; /**< [in] Option to set special cache flags, tuning L2 efficency */ +} _mali_uk_mem_mmap_s; + +/** @brief Arguments to _mali_ukk_mem_munmap() + * + * The cookie and mapping members must be that returned from the same previous + * call to _mali_ukk_mem_mmap(). The size member must correspond to cookie + * and mapping - that is, it must be the value originally supplied to a call to + * _mali_ukk_mem_mmap that returned the values of mapping and cookie. + * + * An error will be returned if an attempt is made to unmap only part of the + * originally obtained range, or to unmap more than was originally obtained. + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + void *mapping; /**< [in] The mapping returned from mmap call */ + u32 size; /**< [in] The size passed to mmap call */ + u32 cookie; /**< [in] Cookie from mmap call */ +} _mali_uk_mem_munmap_s; +/** @} */ /* end group _mali_uk_memory */ + +/** @defgroup _mali_uk_vsync U/K VSYNC Wait Reporting Module + * @{ */ + +/** @brief VSYNC events + * + * These events are reported when DDK starts to wait for vsync and when the + * vsync has occured and the DDK can continue on the next frame. + */ +typedef enum _mali_uk_vsync_event +{ + _MALI_UK_VSYNC_EVENT_BEGIN_WAIT = 0, + _MALI_UK_VSYNC_EVENT_END_WAIT +} _mali_uk_vsync_event; + +/** @brief Arguments to _mali_ukk_vsync_event() + * + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + _mali_uk_vsync_event event; /**< [in] VSYNCH event type */ +} _mali_uk_vsync_event_report_s; + +/** @} */ /* end group _mali_uk_vsync */ + +/** @defgroup _mali_uk_sw_counters_report U/K Software Counter Reporting + * @{ */ + +/** @brief Software counter values + * + * Values recorded for each of the software counters during a single renderpass. + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32* counters; /**< [in] The array of counter values */ + u32 num_counters; /**< [in] The number of elements in counters array */ +} _mali_uk_sw_counters_report_s; + +/** @} */ /* end group _mali_uk_sw_counters_report */ + +/** @} */ /* end group u_k_api */ + +/** @} */ /* end group uddapi */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MALI_UTGARD_UK_TYPES_H__ */ diff --git a/drivers/media/video/samsung/mali/linux/license/gpl/mali_kernel_license.h b/drivers/media/video/samsung/mali/linux/license/gpl/mali_kernel_license.h new file mode 100644 index 0000000..52bb5e0 --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/license/gpl/mali_kernel_license.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_kernel_license.h + * Defines for the macro MODULE_LICENSE. + */ + +#ifndef __MALI_KERNEL_LICENSE_H__ +#define __MALI_KERNEL_LICENSE_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define MALI_KERNEL_LINUX_LICENSE "GPL" +#define MALI_LICENSE_IS_GPL 1 + +#ifdef __cplusplus +} +#endif + +#endif /* __MALI_KERNEL_LICENSE_H__ */ diff --git a/drivers/media/video/samsung/mali/linux/mali_dma_buf.c b/drivers/media/video/samsung/mali/linux/mali_dma_buf.c new file mode 100644 index 0000000..4dd711f --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_dma_buf.c @@ -0,0 +1,392 @@ +/* + * Copyright (C) 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include /* file system operations */ +#include /* user space access */ +#include +#include +#include + +#include "mali_ukk.h" +#include "mali_osk.h" +#include "mali_kernel_common.h" +#include "mali_session.h" +#include "mali_kernel_linux.h" + +#include "mali_kernel_memory_engine.h" +#include "mali_memory.h" + +#include "mali_kernel_sysfs.h" + + +struct mali_dma_buf_attachment { + struct dma_buf *buf; + struct dma_buf_attachment *attachment; + struct sg_table *sgt; + _mali_osk_atomic_t ref; + struct rb_node rb_node; +}; + +static struct rb_root mali_dma_bufs = RB_ROOT; +static DEFINE_SPINLOCK(mali_dma_bufs_lock); + +static inline struct mali_dma_buf_attachment *mali_dma_buf_lookup(struct rb_root *root, struct dma_buf *target) +{ + struct rb_node *node = root->rb_node; + struct mali_dma_buf_attachment *res; + + spin_lock(&mali_dma_bufs_lock); + while (node) + { + res = rb_entry(node, struct mali_dma_buf_attachment, rb_node); + + if (target < res->buf) node = node->rb_left; + else if (target > res->buf) node = node->rb_right; + else + { + _mali_osk_atomic_inc(&res->ref); + spin_unlock(&mali_dma_bufs_lock); + return res; + } + } + spin_unlock(&mali_dma_bufs_lock); + + return NULL; +} + +static void mali_dma_buf_add(struct rb_root *root, struct mali_dma_buf_attachment *new) +{ + struct rb_node **node = &root->rb_node; + struct rb_node *parent = NULL; + struct mali_dma_buf_attachment *res; + + spin_lock(&mali_dma_bufs_lock); + while (*node) + { + parent = *node; + res = rb_entry(*node, struct mali_dma_buf_attachment, rb_node); + + if (new->buf < res->buf) node = &(*node)->rb_left; + else node = &(*node)->rb_right; + } + + rb_link_node(&new->rb_node, parent, node); + rb_insert_color(&new->rb_node, &mali_dma_bufs); + + spin_unlock(&mali_dma_bufs_lock); + + return; +} + + +static void mali_dma_buf_release(void *ctx, void *handle) +{ + struct mali_dma_buf_attachment *mem; + u32 ref; + + mem = (struct mali_dma_buf_attachment *)handle; + + MALI_DEBUG_ASSERT_POINTER(mem); + MALI_DEBUG_ASSERT_POINTER(mem->attachment); + MALI_DEBUG_ASSERT_POINTER(mem->buf); + + spin_lock(&mali_dma_bufs_lock); + ref = _mali_osk_atomic_dec_return(&mem->ref); + + MALI_DEBUG_ASSERT(ref >= 0); + + if (0 == ref) + { + rb_erase(&mem->rb_node, &mali_dma_bufs); + spin_unlock(&mali_dma_bufs_lock); + + MALI_DEBUG_ASSERT(0 == _mali_osk_atomic_read(&mem->ref)); + + dma_buf_unmap_attachment(mem->attachment, mem->sgt, DMA_BIDIRECTIONAL); + + dma_buf_detach(mem->buf, mem->attachment); + dma_buf_put(mem->buf); + + _mali_osk_free(mem); + } + else + { + spin_unlock(&mali_dma_bufs_lock); + } +} + +/* Callback from memory engine which will map into Mali virtual address space */ +static mali_physical_memory_allocation_result mali_dma_buf_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info) +{ + struct mali_session_data *session; + struct mali_page_directory *pagedir; + struct mali_dma_buf_attachment *mem; + struct scatterlist *sg; + int i; + u32 virt; + + MALI_DEBUG_ASSERT_POINTER(ctx); + MALI_DEBUG_ASSERT_POINTER(engine); + MALI_DEBUG_ASSERT_POINTER(descriptor); + MALI_DEBUG_ASSERT_POINTER(offset); + MALI_DEBUG_ASSERT_POINTER(alloc_info); + + /* Mapping dma-buf with an offset is not supported. */ + MALI_DEBUG_ASSERT(0 == *offset); + + virt = descriptor->mali_address; + session = (struct mali_session_data *)descriptor->mali_addr_mapping_info; + pagedir = mali_session_get_page_directory(session); + + MALI_DEBUG_ASSERT_POINTER(session); + + mem = (struct mali_dma_buf_attachment *)ctx; + + MALI_DEBUG_ASSERT_POINTER(mem); + + mem->sgt = dma_buf_map_attachment(mem->attachment, DMA_BIDIRECTIONAL); + if (IS_ERR_OR_NULL(mem->sgt)) + { + MALI_PRINT_ERROR(("Failed to map dma-buf attachment\n")); + return MALI_MEM_ALLOC_INTERNAL_FAILURE; + } + + for_each_sg(mem->sgt->sgl, sg, mem->sgt->nents, i) + { + u32 size = sg_dma_len(sg); + dma_addr_t phys = sg_dma_address(sg); + + /* sg must be page aligned. */ + MALI_DEBUG_ASSERT(0 == size % MALI_MMU_PAGE_SIZE); + + mali_mmu_pagedir_update(pagedir, virt, phys, size, MALI_CACHE_STANDARD); + + virt += size; + *offset += size; + } + + if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE) + { + u32 guard_phys; + MALI_DEBUG_PRINT(7, ("Mapping in extra guard page\n")); + + guard_phys = sg_dma_address(mem->sgt->sgl); + mali_mmu_pagedir_update(mali_session_get_page_directory(session), virt, guard_phys, MALI_MMU_PAGE_SIZE, MALI_CACHE_STANDARD); + } + + MALI_DEBUG_ASSERT(*offset == descriptor->size); + + alloc_info->ctx = NULL; + alloc_info->handle = mem; + alloc_info->next = NULL; + alloc_info->release = mali_dma_buf_release; + + return MALI_MEM_ALLOC_FINISHED; +} + +int mali_attach_dma_buf(struct mali_session_data *session, _mali_uk_attach_dma_buf_s __user *user_arg) +{ + mali_physical_memory_allocator external_memory_allocator; + struct dma_buf *buf; + struct mali_dma_buf_attachment *mem; + _mali_uk_attach_dma_buf_s args; + mali_memory_allocation *descriptor; + int md; + int fd; + + /* Get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */ + if (0 != copy_from_user(&args, (void __user *)user_arg, sizeof(_mali_uk_attach_dma_buf_s))) + { + return -EFAULT; + } + + + fd = args.mem_fd; + + buf = dma_buf_get(fd); + if (IS_ERR_OR_NULL(buf)) + { + MALI_DEBUG_PRINT(2, ("Failed to get dma-buf from fd: %d\n", fd)); + return PTR_RET(buf); + } + + /* Currently, mapping of the full buffer are supported. */ + if (args.size != buf->size) + { + MALI_DEBUG_PRINT(2, ("dma-buf size doesn't match mapping size.\n")); + dma_buf_put(buf); + return -EINVAL; + } + + + mem = mali_dma_buf_lookup(&mali_dma_bufs, buf); + if (NULL == mem) + { + /* dma-buf is not already attached to Mali */ + mem = _mali_osk_calloc(1, sizeof(struct mali_dma_buf_attachment)); + if (NULL == mem) + { + MALI_PRINT_ERROR(("Failed to allocate dma-buf tracing struct\n")); + dma_buf_put(mem->buf); + return -ENOMEM; + } + _mali_osk_atomic_init(&mem->ref, 1); + mem->buf = buf; + + mem->attachment = dma_buf_attach(mem->buf, mali_device); + if (NULL == mem->attachment) + { + MALI_DEBUG_PRINT(2, ("Failed to attach to dma-buf %d\n", fd)); + dma_buf_put(mem->buf); + _mali_osk_free(mem); + return -EFAULT; + } + + mali_dma_buf_add(&mali_dma_bufs, mem); + } + else + { + /* dma-buf is already attached to Mali */ + /* Give back the reference we just took, mali_dma_buf_lookup grabbed a new reference for us. */ + dma_buf_put(buf); + } + + /* Map dma-buf into this session's page tables */ + + /* Set up Mali memory descriptor */ + descriptor = _mali_osk_calloc(1, sizeof(mali_memory_allocation)); + if (NULL == descriptor) + { + MALI_PRINT_ERROR(("Failed to allocate descriptor dma-buf %d\n", fd)); + mali_dma_buf_release(NULL, mem); + return -ENOMEM; + } + + descriptor->size = args.size; + descriptor->mapping = NULL; + descriptor->mali_address = args.mali_address; + descriptor->mali_addr_mapping_info = (void*)session; + descriptor->process_addr_mapping_info = NULL; /* do not map to process address space */ + descriptor->lock = session->memory_lock; + + if (args.flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) + { + descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE; + } + _mali_osk_list_init( &descriptor->list ); + + /* Get descriptor mapping for memory. */ + if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session->descriptor_mapping, descriptor, &md)) + { + MALI_PRINT_ERROR(("Failed to create descriptor mapping for dma-buf %d\n", fd)); + _mali_osk_free(descriptor); + mali_dma_buf_release(NULL, mem); + return -EFAULT; + } + + external_memory_allocator.allocate = mali_dma_buf_commit; + external_memory_allocator.allocate_page_table_block = NULL; + external_memory_allocator.ctx = mem; + external_memory_allocator.name = "DMA-BUF Memory"; + external_memory_allocator.next = NULL; + + /* Map memory into session's Mali virtual address space. */ + _mali_osk_lock_wait(session->memory_lock, _MALI_OSK_LOCKMODE_RW); + if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_memory(mali_mem_get_memory_engine(), descriptor, &external_memory_allocator, NULL)) + { + _mali_osk_lock_signal(session->memory_lock, _MALI_OSK_LOCKMODE_RW); + + MALI_PRINT_ERROR(("Failed to map dma-buf %d into Mali address space\n", fd)); + mali_descriptor_mapping_free(session->descriptor_mapping, md); + mali_dma_buf_release(NULL, mem); + return -ENOMEM; + } + _mali_osk_lock_signal(session->memory_lock, _MALI_OSK_LOCKMODE_RW); + + /* Return stuff to user space */ + if (0 != put_user(md, &user_arg->cookie)) + { + /* Roll back */ + MALI_PRINT_ERROR(("Failed to return descriptor to user space for dma-buf %d\n", fd)); + mali_descriptor_mapping_free(session->descriptor_mapping, md); + mali_dma_buf_release(NULL, mem); + return -EFAULT; + } + + return 0; +} + +int mali_release_dma_buf(struct mali_session_data *session, _mali_uk_release_dma_buf_s __user *user_arg) +{ + _mali_uk_release_dma_buf_s args; + mali_memory_allocation *descriptor; + + /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */ + if ( 0 != copy_from_user(&args, (void __user *)user_arg, sizeof(_mali_uk_release_dma_buf_s)) ) + { + return -EFAULT; + } + + if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_get(session->descriptor_mapping, args.cookie, (void**)&descriptor)) + { + MALI_DEBUG_PRINT(1, ("Invalid memory descriptor %d used to release dma-buf\n", args.cookie)); + return -EINVAL; + } + + descriptor = mali_descriptor_mapping_free(session->descriptor_mapping, args.cookie); + + if (NULL != descriptor) + { + _mali_osk_lock_wait( session->memory_lock, _MALI_OSK_LOCKMODE_RW ); + + /* Will call back to mali_dma_buf_release() which will release the dma-buf attachment. */ + mali_allocation_engine_release_memory(mali_mem_get_memory_engine(), descriptor); + + _mali_osk_lock_signal( session->memory_lock, _MALI_OSK_LOCKMODE_RW ); + + _mali_osk_free(descriptor); + } + + /* Return the error that _mali_ukk_map_external_ump_mem produced */ + return 0; +} + +int mali_dma_buf_get_size(struct mali_session_data *session, _mali_uk_dma_buf_get_size_s __user *user_arg) +{ + _mali_uk_dma_buf_get_size_s args; + int fd; + struct dma_buf *buf; + + /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */ + if ( 0 != copy_from_user(&args, (void __user *)user_arg, sizeof(_mali_uk_dma_buf_get_size_s)) ) + { + return -EFAULT; + } + + /* Do DMA-BUF stuff */ + fd = args.mem_fd; + + buf = dma_buf_get(fd); + if (IS_ERR_OR_NULL(buf)) + { + MALI_DEBUG_PRINT(2, ("Failed to get dma-buf from fd: %d\n", fd)); + return PTR_RET(buf); + } + + if (0 != put_user(buf->size, &user_arg->size)) + { + dma_buf_put(buf); + return -EFAULT; + } + + dma_buf_put(buf); + + return 0; +} diff --git a/drivers/media/video/samsung/mali/linux/mali_dma_buf.h b/drivers/media/video/samsung/mali/linux/mali_dma_buf.h new file mode 100644 index 0000000..ee9a0ed --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_dma_buf.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_DMA_BUF_H__ +#define __MALI_DMA_BUF_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "mali_osk.h" + +int mali_attach_dma_buf(struct mali_session_data *session, _mali_uk_attach_dma_buf_s __user *arg); +int mali_release_dma_buf(struct mali_session_data *session, _mali_uk_release_dma_buf_s __user *arg); +int mali_dma_buf_get_size(struct mali_session_data *session, _mali_uk_dma_buf_get_size_s __user *arg); + +#ifdef __cplusplus +} +#endif + +#endif /* __MALI_KERNEL_LINUX_H__ */ diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_linux.c b/drivers/media/video/samsung/mali/linux/mali_kernel_linux.c new file mode 100644 index 0000000..233c0ca --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_kernel_linux.c @@ -0,0 +1,634 @@ +/** + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_kernel_linux.c + * Implementation of the Linux device driver entrypoints + */ +#include /* kernel module definitions */ +#include /* file system operations */ +#include /* character device definitions */ +#include /* memory manager definitions */ +#include +#include "mali_kernel_common.h" +#include "mali_session.h" +#include "mali_kernel_core.h" +#include "mali_osk.h" +#include "mali_kernel_linux.h" +#include "mali_ukk.h" +#include "mali_ukk_wrappers.h" +#include "mali_kernel_pm.h" +#include "mali_kernel_sysfs.h" +#include "mali_platform.h" +#include "mali_kernel_license.h" +#include "mali_dma_buf.h" + +/* Streamline support for the Mali driver */ +#if defined(CONFIG_TRACEPOINTS) && MALI_TIMELINE_PROFILING_ENABLED +/* Ask Linux to create the tracepoints */ +#define CREATE_TRACE_POINTS +#include "mali_linux_trace.h" +#endif /* CONFIG_TRACEPOINTS */ + +static _mali_osk_errcode_t initialize_kernel_device(void); +static int initialize_sysfs(void); +static void terminate_kernel_device(void); + + +/* from the __malidrv_build_info.c file that is generated during build */ +extern const char *__malidrv_build_info(void); + +/* Module parameter to control log level */ +int mali_debug_level = 2; +module_param(mali_debug_level, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); /* rw-rw-r-- */ +MODULE_PARM_DESC(mali_debug_level, "Higher number, more dmesg output"); + +/* By default the module uses any available major, but it's possible to set it at load time to a specific number */ +#if MALI_MAJOR_PREDEFINE +int mali_major = 244; +#else +int mali_major = 0; +#endif +module_param(mali_major, int, S_IRUGO); /* r--r--r-- */ +MODULE_PARM_DESC(mali_major, "Device major number"); + +module_param(mali_hang_check_interval, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(mali_hang_check_interval, "Interval at which to check for progress after the hw watchdog has been triggered"); + +module_param(mali_max_job_runtime, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(mali_max_job_runtime, "Maximum allowed job runtime in msecs.\nJobs will be killed after this no matter what"); + +extern int mali_l2_max_reads; +module_param(mali_l2_max_reads, int, S_IRUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(mali_l2_max_reads, "Maximum reads for Mali L2 cache"); + +#if MALI_TIMELINE_PROFILING_ENABLED +extern int mali_boot_profiling; +module_param(mali_boot_profiling, int, S_IRUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(mali_boot_profiling, "Start profiling as a part of Mali driver initialization"); +#endif + +/* Export symbols from common code: mali_user_settings.c */ +#include "mali_user_settings_db.h" +EXPORT_SYMBOL(mali_set_user_setting); +EXPORT_SYMBOL(mali_get_user_setting); +#if MALI_DVFS_ENABLED +extern int mali_dvfs_control; +module_param(mali_dvfs_control, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ +MODULE_PARM_DESC(mali_dvfs_control, "Mali Current DVFS"); +#if defined(CONFIG_CPU_EXYNOS4210) +#else +extern int step0_clk; +module_param(step0_clk, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ +MODULE_PARM_DESC(step0_clk, "Mali Current step0_clk"); +#ifdef DEBUG +extern int step0_vol; +module_param(step0_vol, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ +MODULE_PARM_DESC(step0_vol, "Mali Current step0_vol"); +#endif + +#if (MALI_DVFS_STEPS > 1) +extern int step1_clk; +module_param(step1_clk, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ +MODULE_PARM_DESC(step1_clk, "Mali Current step1_clk"); + +extern int step0_up; +module_param(step0_up, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ +MODULE_PARM_DESC(step0_up, "Mali Current step0_up"); + +extern int step1_down; +module_param(step1_down, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ +MODULE_PARM_DESC(step1_down, "Mali Current step1_down"); +#ifdef DEBUG +extern int step1_vol; +module_param(step1_vol, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ +MODULE_PARM_DESC(step1_vol, "Mali Current step1_vol"); +#endif + +#if (MALI_DVFS_STEPS > 2) +extern int step2_clk; +module_param(step2_clk, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ +MODULE_PARM_DESC(step2_clk, "Mali Current step2_clk"); + +extern int step1_up; +module_param(step1_up, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ +MODULE_PARM_DESC(step1_up, "Mali Current step1_up"); + +extern int step2_down; +module_param(step2_down, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ +MODULE_PARM_DESC(step2_down, "Mali Current step2_down"); +#ifdef DEBUG +extern int step2_vol; +module_param(step2_vol, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ +MODULE_PARM_DESC(step2_vol, "Mali Current step2_vol"); +#endif + +#if (MALI_DVFS_STEPS > 3) +extern int step3_clk; +module_param(step3_clk, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ +MODULE_PARM_DESC(step3_clk, "Mali Current step3_clk"); + +extern int step2_up; +module_param(step2_up, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ +MODULE_PARM_DESC(step2_up, "Mali Current step2_up"); + +extern int step3_down; +module_param(step3_down, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ +MODULE_PARM_DESC(step3_down, "Mali Current step3_down"); +#ifdef DEBUG +extern int step3_vol; +module_param(step3_vol, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */ +MODULE_PARM_DESC(step3_vol, "Mali Current step3_vol"); +#endif +#endif +#endif +#endif +#endif + +extern int mali_gpu_clk; +module_param(mali_gpu_clk, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */ +MODULE_PARM_DESC(mali_gpu_clk, "Mali Current Clock"); + +extern int mali_gpu_vol; +module_param(mali_gpu_vol, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */ +MODULE_PARM_DESC(mali_gpu_vol, "Mali Current Voltage"); + +extern int gpu_power_state; +module_param(gpu_power_state, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */ +MODULE_PARM_DESC(gpu_power_state, "Mali Power State"); +#endif + + +static char mali_dev_name[] = "mali"; /* should be const, but the functions we call requires non-cost */ + +/* the mali device */ +static struct mali_dev device; + + +static int mali_open(struct inode *inode, struct file *filp); +static int mali_release(struct inode *inode, struct file *filp); +#ifdef HAVE_UNLOCKED_IOCTL +static long mali_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +#else +static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); +#endif + +static int mali_mmap(struct file * filp, struct vm_area_struct * vma); + +/* Linux char file operations provided by the Mali module */ +struct file_operations mali_fops = +{ + .owner = THIS_MODULE, + .open = mali_open, + .release = mali_release, +#ifdef HAVE_UNLOCKED_IOCTL + .unlocked_ioctl = mali_ioctl, +#else + .ioctl = mali_ioctl, +#endif + .mmap = mali_mmap +}; + + +int mali_driver_init(void) +{ + int ret = 0; + + MALI_DEBUG_PRINT(2, ("\n")); + MALI_DEBUG_PRINT(2, ("Inserting Mali v%d device driver. \n",_MALI_API_VERSION)); + MALI_DEBUG_PRINT(2, ("Compiled: %s, time: %s.\n", __DATE__, __TIME__)); + MALI_DEBUG_PRINT(2, ("Driver revision: %s\n", SVN_REV_STRING)); + + ret = _mali_dev_platform_register(); + if (0 != ret) goto platform_register_failed; + ret = map_errcode(initialize_kernel_device()); + if (0 != ret) goto initialize_kernel_device_failed; + + ret = map_errcode(mali_platform_init()); + if (0 != ret) goto platform_init_failed; + + mali_osk_low_level_mem_init(); + + ret = map_errcode(mali_initialize_subsystems()); + if (0 != ret) goto initialize_subsystems_failed; + + ret = initialize_sysfs(); + if (0 != ret) goto initialize_sysfs_failed; + + MALI_PRINT(("Mali device driver loaded\n")); + + return 0; /* Success */ + + /* Error handling */ +initialize_sysfs_failed: + mali_terminate_subsystems(); +initialize_subsystems_failed: + mali_osk_low_level_mem_term(); + mali_platform_deinit(); +platform_init_failed: + terminate_kernel_device(); +initialize_kernel_device_failed: + _mali_dev_platform_unregister(); +platform_register_failed: + return ret; +} + +void mali_driver_exit(void) +{ + MALI_DEBUG_PRINT(2, ("\n")); + MALI_DEBUG_PRINT(2, ("Unloading Mali v%d device driver.\n",_MALI_API_VERSION)); + + /* No need to terminate sysfs, this will be done automatically along with device termination */ + + mali_terminate_subsystems(); + + mali_osk_low_level_mem_term(); + + mali_platform_deinit(); + + terminate_kernel_device(); + _mali_dev_platform_unregister(); + +#if MALI_LICENSE_IS_GPL + /* @@@@ clean up the work queues! This should not be terminated here, since it isn't inited in the function above! */ + flush_workqueue(mali_wq); + destroy_workqueue(mali_wq); + mali_wq = NULL; +#endif + + MALI_PRINT(("Mali device driver unloaded\n")); +} + +static int initialize_kernel_device(void) +{ + int err; + dev_t dev = 0; + if (0 == mali_major) + { + /* auto select a major */ + err = alloc_chrdev_region(&dev, 0/*first minor*/, 1/*count*/, mali_dev_name); + mali_major = MAJOR(dev); + } + else + { + /* use load time defined major number */ + dev = MKDEV(mali_major, 0); + err = register_chrdev_region(dev, 1/*count*/, mali_dev_name); + } + + if (err) + { + goto init_chrdev_err; + } + + memset(&device, 0, sizeof(device)); + + /* initialize our char dev data */ + cdev_init(&device.cdev, &mali_fops); + device.cdev.owner = THIS_MODULE; + device.cdev.ops = &mali_fops; + + /* register char dev with the kernel */ + err = cdev_add(&device.cdev, dev, 1/*count*/); + if (err) + { + goto init_cdev_err; + } + + /* Success! */ + return 0; + +init_cdev_err: + unregister_chrdev_region(dev, 1/*count*/); +init_chrdev_err: + return err; +} + +static int initialize_sysfs(void) +{ + dev_t dev = MKDEV(mali_major, 0); + return mali_sysfs_register(&device, dev, mali_dev_name); +} + +static void terminate_kernel_device(void) +{ + dev_t dev = MKDEV(mali_major, 0); + + mali_sysfs_unregister(&device, dev, mali_dev_name); + + /* unregister char device */ + cdev_del(&device.cdev); + /* free major */ + unregister_chrdev_region(dev, 1/*count*/); + return; +} + +/** @note munmap handler is done by vma close handler */ +static int mali_mmap(struct file * filp, struct vm_area_struct * vma) +{ + struct mali_session_data * session_data; + _mali_uk_mem_mmap_s args = {0, }; + + session_data = (struct mali_session_data *)filp->private_data; + if (NULL == session_data) + { + MALI_PRINT_ERROR(("mmap called without any session data available\n")); + return -EFAULT; + } + + MALI_DEBUG_PRINT(4, ("MMap() handler: start=0x%08X, phys=0x%08X, size=0x%08X vma->flags 0x%08x\n", (unsigned int)vma->vm_start, (unsigned int)(vma->vm_pgoff << PAGE_SHIFT), (unsigned int)(vma->vm_end - vma->vm_start), vma->vm_flags)); + + /* Re-pack the arguments that mmap() packed for us */ + args.ctx = session_data; + args.phys_addr = vma->vm_pgoff << PAGE_SHIFT; + args.size = vma->vm_end - vma->vm_start; + args.ukk_private = vma; + + if ( VM_SHARED== (VM_SHARED & vma->vm_flags)) + { + args.cache_settings = MALI_CACHE_STANDARD ; + MALI_DEBUG_PRINT(3,("Allocate - Standard - Size: %d kb\n", args.size/1024)); + } + else + { + args.cache_settings = MALI_CACHE_GP_READ_ALLOCATE; + MALI_DEBUG_PRINT(3,("Allocate - GP Cached - Size: %d kb\n", args.size/1024)); + } + /* Setting it equal to VM_SHARED and not Private, which would have made the later io_remap fail for MALI_CACHE_GP_READ_ALLOCATE */ + vma->vm_flags = 0x000000fb; + + /* Call the common mmap handler */ + MALI_CHECK(_MALI_OSK_ERR_OK ==_mali_ukk_mem_mmap( &args ), -EFAULT); + + return 0; +} + +static int mali_open(struct inode *inode, struct file *filp) +{ + struct mali_session_data * session_data; + _mali_osk_errcode_t err; + + /* input validation */ + if (0 != MINOR(inode->i_rdev)) return -ENODEV; + + /* allocated struct to track this session */ + err = _mali_ukk_open((void **)&session_data); + if (_MALI_OSK_ERR_OK != err) return map_errcode(err); + + /* initialize file pointer */ + filp->f_pos = 0; + + /* link in our session data */ + filp->private_data = (void*)session_data; + + return 0; +} + +static int mali_release(struct inode *inode, struct file *filp) +{ + _mali_osk_errcode_t err; + + /* input validation */ + if (0 != MINOR(inode->i_rdev)) return -ENODEV; + + err = _mali_ukk_close((void **)&filp->private_data); + if (_MALI_OSK_ERR_OK != err) return map_errcode(err); + + return 0; +} + +int map_errcode( _mali_osk_errcode_t err ) +{ + switch(err) + { + case _MALI_OSK_ERR_OK : return 0; + case _MALI_OSK_ERR_FAULT: return -EFAULT; + case _MALI_OSK_ERR_INVALID_FUNC: return -ENOTTY; + case _MALI_OSK_ERR_INVALID_ARGS: return -EINVAL; + case _MALI_OSK_ERR_NOMEM: return -ENOMEM; + case _MALI_OSK_ERR_TIMEOUT: return -ETIMEDOUT; + case _MALI_OSK_ERR_RESTARTSYSCALL: return -ERESTARTSYS; + case _MALI_OSK_ERR_ITEM_NOT_FOUND: return -ENOENT; + default: return -EFAULT; + } +} + +#ifdef HAVE_UNLOCKED_IOCTL +static long mali_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +#else +static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) +#endif +{ + int err; + struct mali_session_data *session_data; + +#ifndef HAVE_UNLOCKED_IOCTL + /* inode not used */ + (void)inode; +#endif + + MALI_DEBUG_PRINT(7, ("Ioctl received 0x%08X 0x%08lX\n", cmd, arg)); + + session_data = (struct mali_session_data *)filp->private_data; + if (NULL == session_data) + { + MALI_DEBUG_PRINT(7, ("filp->private_data was NULL\n")); + return -ENOTTY; + } + + if (NULL == (void *)arg) + { + MALI_DEBUG_PRINT(7, ("arg was NULL\n")); + return -ENOTTY; + } + + switch(cmd) + { + case MALI_IOC_WAIT_FOR_NOTIFICATION: + err = wait_for_notification_wrapper(session_data, (_mali_uk_wait_for_notification_s __user *)arg); + break; + + case MALI_IOC_GET_API_VERSION: + err = get_api_version_wrapper(session_data, (_mali_uk_get_api_version_s __user *)arg); + break; + + case MALI_IOC_POST_NOTIFICATION: + err = post_notification_wrapper(session_data, (_mali_uk_post_notification_s __user *)arg); + break; + + case MALI_IOC_GET_USER_SETTINGS: + err = get_user_settings_wrapper(session_data, (_mali_uk_get_user_settings_s __user *)arg); + break; + +#if MALI_TIMELINE_PROFILING_ENABLED + case MALI_IOC_PROFILING_START: + err = profiling_start_wrapper(session_data, (_mali_uk_profiling_start_s __user *)arg); + break; + + case MALI_IOC_PROFILING_ADD_EVENT: + err = profiling_add_event_wrapper(session_data, (_mali_uk_profiling_add_event_s __user *)arg); + break; + + case MALI_IOC_PROFILING_STOP: + err = profiling_stop_wrapper(session_data, (_mali_uk_profiling_stop_s __user *)arg); + break; + + case MALI_IOC_PROFILING_GET_EVENT: + err = profiling_get_event_wrapper(session_data, (_mali_uk_profiling_get_event_s __user *)arg); + break; + + case MALI_IOC_PROFILING_CLEAR: + err = profiling_clear_wrapper(session_data, (_mali_uk_profiling_clear_s __user *)arg); + break; + + case MALI_IOC_PROFILING_GET_CONFIG: + /* Deprecated: still compatible with get_user_settings */ + err = get_user_settings_wrapper(session_data, (_mali_uk_get_user_settings_s __user *)arg); + break; + + case MALI_IOC_PROFILING_REPORT_SW_COUNTERS: + err = profiling_report_sw_counters_wrapper(session_data, (_mali_uk_sw_counters_report_s __user *)arg); + break; + +#else + + case MALI_IOC_PROFILING_START: /* FALL-THROUGH */ + case MALI_IOC_PROFILING_ADD_EVENT: /* FALL-THROUGH */ + case MALI_IOC_PROFILING_STOP: /* FALL-THROUGH */ + case MALI_IOC_PROFILING_GET_EVENT: /* FALL-THROUGH */ + case MALI_IOC_PROFILING_CLEAR: /* FALL-THROUGH */ + case MALI_IOC_PROFILING_GET_CONFIG: /* FALL-THROUGH */ + case MALI_IOC_PROFILING_REPORT_SW_COUNTERS: /* FALL-THROUGH */ + MALI_DEBUG_PRINT(2, ("Profiling not supported\n")); + err = -ENOTTY; + break; + +#endif + + case MALI_IOC_MEM_INIT: + err = mem_init_wrapper(session_data, (_mali_uk_init_mem_s __user *)arg); + break; + + case MALI_IOC_MEM_TERM: + err = mem_term_wrapper(session_data, (_mali_uk_term_mem_s __user *)arg); + break; + + case MALI_IOC_MEM_MAP_EXT: + err = mem_map_ext_wrapper(session_data, (_mali_uk_map_external_mem_s __user *)arg); + break; + + case MALI_IOC_MEM_UNMAP_EXT: + err = mem_unmap_ext_wrapper(session_data, (_mali_uk_unmap_external_mem_s __user *)arg); + break; + + case MALI_IOC_MEM_QUERY_MMU_PAGE_TABLE_DUMP_SIZE: + err = mem_query_mmu_page_table_dump_size_wrapper(session_data, (_mali_uk_query_mmu_page_table_dump_size_s __user *)arg); + break; + + case MALI_IOC_MEM_DUMP_MMU_PAGE_TABLE: + err = mem_dump_mmu_page_table_wrapper(session_data, (_mali_uk_dump_mmu_page_table_s __user *)arg); + break; + +#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 + + case MALI_IOC_MEM_ATTACH_UMP: + err = mem_attach_ump_wrapper(session_data, (_mali_uk_attach_ump_mem_s __user *)arg); + break; + + case MALI_IOC_MEM_RELEASE_UMP: + err = mem_release_ump_wrapper(session_data, (_mali_uk_release_ump_mem_s __user *)arg); + break; + +#else + + case MALI_IOC_MEM_ATTACH_UMP: + case MALI_IOC_MEM_RELEASE_UMP: /* FALL-THROUGH */ + MALI_DEBUG_PRINT(2, ("UMP not supported\n")); + err = -ENOTTY; + break; +#endif + +#ifdef CONFIG_DMA_SHARED_BUFFER + case MALI_IOC_MEM_ATTACH_DMA_BUF: + err = mali_attach_dma_buf(session_data, (_mali_uk_attach_dma_buf_s __user *)arg); + break; + + case MALI_IOC_MEM_RELEASE_DMA_BUF: + err = mali_release_dma_buf(session_data, (_mali_uk_release_dma_buf_s __user *)arg); + break; + + case MALI_IOC_MEM_DMA_BUF_GET_SIZE: + err = mali_dma_buf_get_size(session_data, (_mali_uk_dma_buf_get_size_s __user *)arg); + break; +#else + + case MALI_IOC_MEM_DMA_BUF_GET_SIZE: /* FALL-THROUGH */ + MALI_DEBUG_PRINT(2, ("DMA-BUF not supported\n")); + err = -ENOTTY; + break; +#endif + + case MALI_IOC_PP_START_JOB: + err = pp_start_job_wrapper(session_data, (_mali_uk_pp_start_job_s __user *)arg); + break; + + case MALI_IOC_PP_NUMBER_OF_CORES_GET: + err = pp_get_number_of_cores_wrapper(session_data, (_mali_uk_get_pp_number_of_cores_s __user *)arg); + break; + + case MALI_IOC_PP_CORE_VERSION_GET: + err = pp_get_core_version_wrapper(session_data, (_mali_uk_get_pp_core_version_s __user *)arg); + break; + + case MALI_IOC_PP_DISABLE_WB: + err = pp_disable_wb_wrapper(session_data, (_mali_uk_pp_disable_wb_s __user *)arg); + break; + + case MALI_IOC_GP2_START_JOB: + err = gp_start_job_wrapper(session_data, (_mali_uk_gp_start_job_s __user *)arg); + break; + + case MALI_IOC_GP2_NUMBER_OF_CORES_GET: + err = gp_get_number_of_cores_wrapper(session_data, (_mali_uk_get_gp_number_of_cores_s __user *)arg); + break; + + case MALI_IOC_GP2_CORE_VERSION_GET: + err = gp_get_core_version_wrapper(session_data, (_mali_uk_get_gp_core_version_s __user *)arg); + break; + + case MALI_IOC_GP2_SUSPEND_RESPONSE: + err = gp_suspend_response_wrapper(session_data, (_mali_uk_gp_suspend_response_s __user *)arg); + break; + + case MALI_IOC_VSYNC_EVENT_REPORT: + err = vsync_event_report_wrapper(session_data, (_mali_uk_vsync_event_report_s __user *)arg); + break; + + case MALI_IOC_MEM_GET_BIG_BLOCK: /* Fallthrough */ + case MALI_IOC_MEM_FREE_BIG_BLOCK: + MALI_PRINT_ERROR(("Non-MMU mode is no longer supported.\n")); + err = -ENOTTY; + break; + + default: + MALI_DEBUG_PRINT(2, ("No handler for ioctl 0x%08X 0x%08lX\n", cmd, arg)); + err = -ENOTTY; + }; + + return err; +} + + +module_init(mali_driver_init); +module_exit(mali_driver_exit); + +MODULE_LICENSE(MALI_KERNEL_LINUX_LICENSE); +MODULE_AUTHOR("ARM Ltd."); +MODULE_VERSION(SVN_REV_STRING); diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_linux.h b/drivers/media/video/samsung/mali/linux/mali_kernel_linux.h new file mode 100644 index 0000000..22dc9a4 --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_kernel_linux.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_KERNEL_LINUX_H__ +#define __MALI_KERNEL_LINUX_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include /* character device definitions */ +#include "mali_kernel_license.h" +#include "mali_osk.h" + +struct mali_dev +{ + struct cdev cdev; +#if MALI_LICENSE_IS_GPL + struct class * mali_class; +#endif +}; + +#if MALI_LICENSE_IS_GPL +/* Defined in mali_osk_irq.h */ +extern struct workqueue_struct * mali_wq; +#endif + +void mali_osk_low_level_mem_init(void); +void mali_osk_low_level_mem_term(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __MALI_KERNEL_LINUX_H__ */ diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_pm.c b/drivers/media/video/samsung/mali/linux/mali_kernel_pm.c new file mode 100644 index 0000000..4639d55 --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_kernel_pm.c @@ -0,0 +1,268 @@ +/** + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_kernel_pm.c + * Linux Power Management integration + */ + +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_PM_RUNTIME +#include +#endif +#include "mali_osk.h" +#include "mali_uk_types.h" +#include "mali_kernel_common.h" +#include "mali_kernel_license.h" +#include "mali_linux_pm.h" +#include "mali_pm.h" +#include "mali_platform.h" + +#if ! MALI_LICENSE_IS_GPL +#undef CONFIG_PM_RUNTIME +#endif + +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON +extern void set_mali_parent_power_domain(struct platform_device* dev); +#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ +static int mali_probe(struct platform_device *pdev); +static int mali_remove(struct platform_device *pdev); + +#ifdef CONFIG_PM_RUNTIME +static int mali_runtime_suspend(struct device *dev); +static int mali_runtime_resume(struct device *dev); +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) +static int mali_os_suspend(struct platform_device *pdev, pm_message_t state); +static int mali_os_resume(struct platform_device *pdev); +#else +static int mali_os_suspend(struct device *dev); +static int mali_os_resume(struct device *dev); +#endif + + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) +static const struct dev_pm_ops mali_dev_pm_ops = +{ +#ifdef CONFIG_PM_RUNTIME + .runtime_suspend = mali_runtime_suspend, + .runtime_resume = mali_runtime_resume, + .runtime_idle = NULL, +#else + .suspend = mali_os_suspend, + .resume = mali_os_resume, +#endif + .freeze = mali_os_suspend, + .poweroff = mali_os_suspend, + .thaw = mali_os_resume, + .restore = mali_os_resume, +}; +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) +struct pm_ext_ops mali_ext_pm_operations = +{ + .base = + { + .freeze = mali_os_suspend, + .thaw = mali_os_resume, + .poweroff = mali_os_suspend, + .restore = mali_os_resume, + }, +}; +#endif + + +static struct platform_driver mali_plat_driver = +{ + .probe = mali_probe, + .remove = mali_remove, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) + .suspend = mali_os_suspend, + .resume = mali_os_resume, + .pm = &mali_ext_pm_operations, +#endif + + .driver = + { + .name = "mali_dev", + .owner = THIS_MODULE, +#if MALI_LICENSE_IS_GPL + .bus = &platform_bus_type, +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) + .pm = &mali_dev_pm_ops, +#endif + }, +}; + +#ifdef CONFIG_PM_RUNTIME +static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long event,void* dummy); + +static struct notifier_block mali_pwr_notif_block = +{ + .notifier_call = mali_pwr_suspend_notifier +}; +#endif + +/** This function is called when platform device is unregistered. This function + * is necessary when the platform device is unregistered. + */ +static void _mali_release_pm(struct device *device) +{ +} +struct platform_device mali_gpu_device = +{ + .name = "mali_dev", + .id = 0, + .dev.release = _mali_release_pm +}; + +/** This function is called when the device is probed */ +static int mali_probe(struct platform_device *pdev) +{ + return 0; +} + +static int mali_remove(struct platform_device *pdev) +{ +#ifdef CONFIG_PM_RUNTIME + pm_runtime_disable(&pdev->dev); +#endif + return 0; +} + +#ifdef CONFIG_PM_RUNTIME +static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long event,void* dummy) +{ + switch (event) + { + case PM_SUSPEND_PREPARE: + MALI_DEBUG_PRINT(2, ("mali_pwr_suspend_notifier(PM_SUSPEND_PREPARE) called\n")); + mali_pm_os_suspend(); + break; + case PM_POST_SUSPEND: + MALI_DEBUG_PRINT(2, ("mali_pwr_suspend_notifier(PM_SUSPEND_PREPARE) called\n")); + mali_pm_os_resume(); + break; + default: + break; + } + return 0; +} +#endif + + +#ifdef CONFIG_PM_RUNTIME + +static int mali_runtime_suspend(struct device *dev) +{ + MALI_DEBUG_PRINT(3, ("mali_runtime_suspend() called\n")); + mali_pm_runtime_suspend(); + return 0; /* all ok */ +} + +static int mali_runtime_resume(struct device *dev) +{ + MALI_DEBUG_PRINT(3, ("mali_runtime_resume() called\n")); + mali_pm_runtime_resume(); + return 0; /* all ok */ +} + +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) + +static int mali_os_suspend(struct platform_device *pdev, pm_message_t state) +{ + MALI_DEBUG_PRINT(3, ("mali_os_suspend(old) called\n")); + mali_pm_os_suspend(); + return 0; /* all ok */ +} + +static int mali_os_resume(struct platform_device *pdev) +{ + MALI_DEBUG_PRINT(3, ("mali_os_resume(old) called\n")); + mali_pm_os_resume(); + return 0; /* all ok */ +} + +#else + +static int mali_os_suspend(struct device *dev) +{ + MALI_DEBUG_PRINT(3, ("mali_os_suspend(new) called\n")); + mali_pm_os_suspend(); + return 0; /* all ok */ +} + +static int mali_os_resume(struct device *dev) +{ + MALI_DEBUG_PRINT(3, ("mali_os_resume(new) called\n")); + mali_pm_os_resume(); + return 0; /* all ok */ +} + +#endif + +/** This function is called when Mali GPU device is initialized + */ +int _mali_dev_platform_register(void) +{ + int err; + +#ifdef CONFIG_PM_RUNTIME + set_mali_parent_power_domain((void *)&mali_gpu_device); +#endif + +#ifdef CONFIG_PM_RUNTIME + err = register_pm_notifier(&mali_pwr_notif_block); + if (err) + { + return err; + } +#endif + +#if MALI_LICENSE_IS_GPL + err = platform_device_register(&mali_gpu_device); + if (!err) + { + err = platform_driver_register(&mali_plat_driver); + if (err) + { +#ifdef CONFIG_PM_RUNTIME + unregister_pm_notifier(&mali_pwr_notif_block); +#endif + platform_device_unregister(&mali_gpu_device); + } + } +#endif + + return err; +} + +/** This function is called when Mali GPU device is unloaded + */ +void _mali_dev_platform_unregister(void) +{ +#ifdef CONFIG_PM_RUNTIME + unregister_pm_notifier(&mali_pwr_notif_block); +#endif + +#if MALI_LICENSE_IS_GPL + platform_driver_unregister(&mali_plat_driver); + platform_device_unregister(&mali_gpu_device); +#endif +} + diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_pm.h b/drivers/media/video/samsung/mali/linux/mali_kernel_pm.h new file mode 100644 index 0000000..6ef7270 --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_kernel_pm.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_KERNEL_PM_H__ +#define __MALI_KERNEL_PM_H__ + +int _mali_dev_platform_register(void); +void _mali_dev_platform_unregister(void); + +#endif /* __MALI_KERNEL_PM_H__ */ diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.c b/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.c new file mode 100644 index 0000000..e2dc17b --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.c @@ -0,0 +1,1280 @@ +/** + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +/** + * @file mali_kernel_sysfs.c + * Implementation of some sysfs data exports + */ + +#include +#include +#include +#include +#include "mali_kernel_license.h" +#include "mali_kernel_common.h" +#include "mali_kernel_linux.h" +#include "mali_ukk.h" + +#if MALI_LICENSE_IS_GPL + +#include +#include +#include +#include +#include "mali_kernel_sysfs.h" +#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED +#include +#include "mali_osk_profiling.h" +#endif +#include "mali_pm.h" +#include "mali_cluster.h" +#include "mali_group.h" +#include "mali_gp.h" +#include "mali_pp.h" +#include "mali_l2_cache.h" +#include "mali_hw_core.h" +#include "mali_kernel_core.h" +#include "mali_user_settings_db.h" +#include "mali_device_pause_resume.h" + +#define POWER_BUFFER_SIZE 3 + +struct device *mali_device; +static struct dentry *mali_debugfs_dir = NULL; + +typedef enum +{ + _MALI_DEVICE_SUSPEND, + _MALI_DEVICE_RESUME, + _MALI_DEVICE_DVFS_PAUSE, + _MALI_DEVICE_DVFS_RESUME, + _MALI_MAX_EVENTS +} _mali_device_debug_power_events; + +static const char* const mali_power_events[_MALI_MAX_EVENTS] = { + [_MALI_DEVICE_SUSPEND] = "suspend", + [_MALI_DEVICE_RESUME] = "resume", + [_MALI_DEVICE_DVFS_PAUSE] = "dvfs_pause", + [_MALI_DEVICE_DVFS_RESUME] = "dvfs_resume", +}; + +static u32 virtual_power_status_register=0; +static char pwr_buf[POWER_BUFFER_SIZE]; + +static int open_copy_private_data(struct inode *inode, struct file *filp) +{ + filp->private_data = inode->i_private; + return 0; +} + +static ssize_t gp_gpx_counter_srcx_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *gpos, u32 src_id) +{ + char buf[64]; + int r; + u32 val; + struct mali_gp_core *gp_core = (struct mali_gp_core *)filp->private_data; + + if (0 == src_id) + { + val = mali_gp_core_get_counter_src0(gp_core); + } + else + { + val = mali_gp_core_get_counter_src1(gp_core); + } + + if (MALI_HW_CORE_NO_COUNTER == val) + { + r = sprintf(buf, "-1\n"); + } + else + { + r = sprintf(buf, "%u\n", val); + } + return simple_read_from_buffer(ubuf, cnt, gpos, buf, r); +} + +static ssize_t gp_gpx_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos, u32 src_id) +{ + struct mali_gp_core *gp_core = (struct mali_gp_core *)filp->private_data; + char buf[64]; + long val; + int ret; + + if (cnt >= sizeof(buf)) + { + return -EINVAL; + } + + if (copy_from_user(&buf, ubuf, cnt)) + { + return -EFAULT; + } + + buf[cnt] = 0; + + ret = strict_strtol(buf, 10, &val); + if (ret < 0) + { + return ret; + } + + if (val < 0) + { + /* any negative input will disable counter */ + val = MALI_HW_CORE_NO_COUNTER; + } + + if (0 == src_id) + { + if (MALI_TRUE != mali_gp_core_set_counter_src0(gp_core, (u32)val)) + { + return 0; + } + } + else + { + if (MALI_TRUE != mali_gp_core_set_counter_src1(gp_core, (u32)val)) + { + return 0; + } + } + + *gpos += cnt; + return cnt; +} + +static ssize_t gp_all_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos, u32 src_id) +{ + char buf[64]; + long val; + int ret; + u32 ci; + struct mali_cluster *cluster; + + if (cnt >= sizeof(buf)) + { + return -EINVAL; + } + + if (copy_from_user(&buf, ubuf, cnt)) + { + return -EFAULT; + } + + buf[cnt] = 0; + + ret = strict_strtol(buf, 10, &val); + if (ret < 0) + { + return ret; + } + + if (val < 0) + { + /* any negative input will disable counter */ + val = MALI_HW_CORE_NO_COUNTER; + } + + ci = 0; + cluster = mali_cluster_get_global_cluster(ci); + while (NULL != cluster) + { + u32 gi = 0; + struct mali_group *group = mali_cluster_get_group(cluster, gi); + while (NULL != group) + { + struct mali_gp_core *gp_core = mali_group_get_gp_core(group); + if (NULL != gp_core) + { + if (0 == src_id) + { + if (MALI_TRUE != mali_gp_core_set_counter_src0(gp_core, (u32)val)) + { + return 0; + } + } + else + { + if (MALI_TRUE != mali_gp_core_set_counter_src1(gp_core, (u32)val)) + { + return 0; + } + } + } + + /* try next group */ + gi++; + group = mali_cluster_get_group(cluster, gi); + } + + /* try next cluster */ + ci++; + cluster = mali_cluster_get_global_cluster(ci); + } + + *gpos += cnt; + return cnt; +} + +static ssize_t gp_gpx_counter_src0_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *gpos) +{ + return gp_gpx_counter_srcx_read(filp, ubuf, cnt, gpos, 0); +} + +static ssize_t gp_gpx_counter_src1_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *gpos) +{ + return gp_gpx_counter_srcx_read(filp, ubuf, cnt, gpos, 1); +} + +static ssize_t gp_gpx_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos) +{ + return gp_gpx_counter_srcx_write(filp, ubuf, cnt, gpos, 0); +} + +static ssize_t gp_gpx_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos) +{ + return gp_gpx_counter_srcx_write(filp, ubuf, cnt, gpos, 1); +} + +static ssize_t gp_all_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos) +{ + return gp_all_counter_srcx_write(filp, ubuf, cnt, gpos, 0); +} + +static ssize_t gp_all_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos) +{ + return gp_all_counter_srcx_write(filp, ubuf, cnt, gpos, 1); +} + +static const struct file_operations gp_gpx_counter_src0_fops = { + .owner = THIS_MODULE, + .open = open_copy_private_data, + .read = gp_gpx_counter_src0_read, + .write = gp_gpx_counter_src0_write, +}; + +static const struct file_operations gp_gpx_counter_src1_fops = { + .owner = THIS_MODULE, + .open = open_copy_private_data, + .read = gp_gpx_counter_src1_read, + .write = gp_gpx_counter_src1_write, +}; + +static const struct file_operations gp_all_counter_src0_fops = { + .owner = THIS_MODULE, + .write = gp_all_counter_src0_write, +}; + +static const struct file_operations gp_all_counter_src1_fops = { + .owner = THIS_MODULE, + .write = gp_all_counter_src1_write, +}; + +static ssize_t pp_ppx_counter_srcx_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id) +{ + char buf[64]; + int r; + u32 val; + struct mali_pp_core *pp_core = (struct mali_pp_core *)filp->private_data; + + if (0 == src_id) + { + val = mali_pp_core_get_counter_src0(pp_core); + } + else + { + val = mali_pp_core_get_counter_src1(pp_core); + } + + if (MALI_HW_CORE_NO_COUNTER == val) + { + r = sprintf(buf, "-1\n"); + } + else + { + r = sprintf(buf, "%u\n", val); + } + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); +} + +static ssize_t pp_ppx_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id) +{ + struct mali_pp_core *pp_core = (struct mali_pp_core *)filp->private_data; + char buf[64]; + long val; + int ret; + + if (cnt >= sizeof(buf)) + { + return -EINVAL; + } + + if (copy_from_user(&buf, ubuf, cnt)) + { + return -EFAULT; + } + + buf[cnt] = 0; + + ret = strict_strtol(buf, 10, &val); + if (ret < 0) + { + return ret; + } + + if (val < 0) + { + /* any negative input will disable counter */ + val = MALI_HW_CORE_NO_COUNTER; + } + + if (0 == src_id) + { + if (MALI_TRUE != mali_pp_core_set_counter_src0(pp_core, (u32)val)) + { + return 0; + } + } + else + { + if (MALI_TRUE != mali_pp_core_set_counter_src1(pp_core, (u32)val)) + { + return 0; + } + } + + *ppos += cnt; + return cnt; +} + +static ssize_t pp_all_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id) +{ + char buf[64]; + long val; + int ret; + u32 ci; + struct mali_cluster *cluster; + + if (cnt >= sizeof(buf)) + { + return -EINVAL; + } + + if (copy_from_user(&buf, ubuf, cnt)) + { + return -EFAULT; + } + + buf[cnt] = 0; + + ret = strict_strtol(buf, 10, &val); + if (ret < 0) + { + return ret; + } + + if (val < 0) + { + /* any negative input will disable counter */ + val = MALI_HW_CORE_NO_COUNTER; + } + + ci = 0; + cluster = mali_cluster_get_global_cluster(ci); + while (NULL != cluster) + { + u32 gi = 0; + struct mali_group *group = mali_cluster_get_group(cluster, gi); + while (NULL != group) + { + struct mali_pp_core *pp_core = mali_group_get_pp_core(group); + if (NULL != pp_core) + { + if (0 == src_id) + { + if (MALI_TRUE != mali_pp_core_set_counter_src0(pp_core, (u32)val)) + { + return 0; + } + } + else + { + if (MALI_TRUE != mali_pp_core_set_counter_src1(pp_core, (u32)val)) + { + return 0; + } + } + } + + /* try next group */ + gi++; + group = mali_cluster_get_group(cluster, gi); + } + + /* try next cluster */ + ci++; + cluster = mali_cluster_get_global_cluster(ci); + } + + *ppos += cnt; + return cnt; +} + +static ssize_t pp_ppx_counter_src0_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +{ + return pp_ppx_counter_srcx_read(filp, ubuf, cnt, ppos, 0); +} + +static ssize_t pp_ppx_counter_src1_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +{ + return pp_ppx_counter_srcx_read(filp, ubuf, cnt, ppos, 1); +} + +static ssize_t pp_ppx_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + return pp_ppx_counter_srcx_write(filp, ubuf, cnt, ppos, 0); +} + +static ssize_t pp_ppx_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + return pp_ppx_counter_srcx_write(filp, ubuf, cnt, ppos, 1); +} + +static ssize_t pp_all_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + return pp_all_counter_srcx_write(filp, ubuf, cnt, ppos, 0); +} + +static ssize_t pp_all_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + return pp_all_counter_srcx_write(filp, ubuf, cnt, ppos, 1); +} + +static const struct file_operations pp_ppx_counter_src0_fops = { + .owner = THIS_MODULE, + .open = open_copy_private_data, + .read = pp_ppx_counter_src0_read, + .write = pp_ppx_counter_src0_write, +}; + +static const struct file_operations pp_ppx_counter_src1_fops = { + .owner = THIS_MODULE, + .open = open_copy_private_data, + .read = pp_ppx_counter_src1_read, + .write = pp_ppx_counter_src1_write, +}; + +static const struct file_operations pp_all_counter_src0_fops = { + .owner = THIS_MODULE, + .write = pp_all_counter_src0_write, +}; + +static const struct file_operations pp_all_counter_src1_fops = { + .owner = THIS_MODULE, + .write = pp_all_counter_src1_write, +}; + + + + + + +static ssize_t l2_l2x_counter_srcx_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id) +{ + char buf[64]; + int r; + u32 val; + struct mali_l2_cache_core *l2_core = (struct mali_l2_cache_core *)filp->private_data; + + if (0 == src_id) + { + val = mali_l2_cache_core_get_counter_src0(l2_core); + } + else + { + val = mali_l2_cache_core_get_counter_src1(l2_core); + } + + if (MALI_HW_CORE_NO_COUNTER == val) + { + r = sprintf(buf, "-1\n"); + } + else + { + r = sprintf(buf, "%u\n", val); + } + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); +} + +static ssize_t l2_l2x_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id) +{ + struct mali_l2_cache_core *l2_core = (struct mali_l2_cache_core *)filp->private_data; + char buf[64]; + long val; + int ret; + + if (cnt >= sizeof(buf)) + { + return -EINVAL; + } + + if (copy_from_user(&buf, ubuf, cnt)) + { + return -EFAULT; + } + + buf[cnt] = 0; + + ret = strict_strtol(buf, 10, &val); + if (ret < 0) + { + return ret; + } + + if (val < 0) + { + /* any negative input will disable counter */ + val = MALI_HW_CORE_NO_COUNTER; + } + + if (0 == src_id) + { + if (MALI_TRUE != mali_l2_cache_core_set_counter_src0(l2_core, (u32)val)) + { + return 0; + } + } + else + { + if (MALI_TRUE != mali_l2_cache_core_set_counter_src1(l2_core, (u32)val)) + { + return 0; + } + } + + *ppos += cnt; + return cnt; +} + +static ssize_t l2_all_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id) +{ + char buf[64]; + long val; + int ret; + u32 l2_id; + struct mali_l2_cache_core *l2_cache; + + if (cnt >= sizeof(buf)) + { + return -EINVAL; + } + + if (copy_from_user(&buf, ubuf, cnt)) + { + return -EFAULT; + } + + buf[cnt] = 0; + + ret = strict_strtol(buf, 10, &val); + if (ret < 0) + { + return ret; + } + + if (val < 0) + { + /* any negative input will disable counter */ + val = MALI_HW_CORE_NO_COUNTER; + } + + l2_id = 0; + l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id); + while (NULL != l2_cache) + { + if (0 == src_id) + { + if (MALI_TRUE != mali_l2_cache_core_set_counter_src0(l2_cache, (u32)val)) + { + return 0; + } + } + else + { + if (MALI_TRUE != mali_l2_cache_core_set_counter_src1(l2_cache, (u32)val)) + { + return 0; + } + } + + /* try next L2 */ + l2_id++; + l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id); + } + + *ppos += cnt; + return cnt; +} + +static ssize_t l2_l2x_counter_src0_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +{ + return l2_l2x_counter_srcx_read(filp, ubuf, cnt, ppos, 0); +} + +static ssize_t l2_l2x_counter_src1_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +{ + return l2_l2x_counter_srcx_read(filp, ubuf, cnt, ppos, 1); +} + +static ssize_t l2_l2x_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + return l2_l2x_counter_srcx_write(filp, ubuf, cnt, ppos, 0); +} + +static ssize_t l2_l2x_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + return l2_l2x_counter_srcx_write(filp, ubuf, cnt, ppos, 1); +} + +static ssize_t l2_all_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + return l2_all_counter_srcx_write(filp, ubuf, cnt, ppos, 0); +} + +static ssize_t l2_all_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + return l2_all_counter_srcx_write(filp, ubuf, cnt, ppos, 1); +} + +static const struct file_operations l2_l2x_counter_src0_fops = { + .owner = THIS_MODULE, + .open = open_copy_private_data, + .read = l2_l2x_counter_src0_read, + .write = l2_l2x_counter_src0_write, +}; + +static const struct file_operations l2_l2x_counter_src1_fops = { + .owner = THIS_MODULE, + .open = open_copy_private_data, + .read = l2_l2x_counter_src1_read, + .write = l2_l2x_counter_src1_write, +}; + +static const struct file_operations l2_all_counter_src0_fops = { + .owner = THIS_MODULE, + .write = l2_all_counter_src0_write, +}; + +static const struct file_operations l2_all_counter_src1_fops = { + .owner = THIS_MODULE, + .write = l2_all_counter_src1_write, +}; + +static ssize_t power_events_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + + memset(pwr_buf,0,POWER_BUFFER_SIZE); + virtual_power_status_register = 0; + if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_SUSPEND],strlen(mali_power_events[_MALI_DEVICE_SUSPEND]))) + { + mali_pm_os_suspend(); + /* @@@@ assuming currently suspend is successful later on to tune as per previous*/ + virtual_power_status_register =1; + + } + else if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_RESUME],strlen(mali_power_events[_MALI_DEVICE_RESUME]))) + { + mali_pm_os_resume(); + + /* @@@@ assuming currently resume is successful later on to tune as per previous */ + virtual_power_status_register = 1; + } + else if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_DVFS_PAUSE],strlen(mali_power_events[_MALI_DEVICE_DVFS_PAUSE]))) + { + mali_bool power_on; + mali_dev_pause(&power_on); + if (!power_on) + { + virtual_power_status_register = 2; + mali_dev_resume(); + } + else + { + /* @@@@ assuming currently resume is successful later on to tune as per previous */ + virtual_power_status_register =1; + } + } + else if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_DVFS_RESUME],strlen(mali_power_events[_MALI_DEVICE_DVFS_RESUME]))) + { + mali_dev_resume(); + /* @@@@ assuming currently resume is successful later on to tune as per previous */ + virtual_power_status_register = 1; + + } + *ppos += cnt; + sprintf(pwr_buf, "%d",virtual_power_status_register); + return cnt; +} + +static ssize_t power_events_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +{ + return simple_read_from_buffer(ubuf, cnt, ppos, pwr_buf, POWER_BUFFER_SIZE); +} + +static loff_t power_events_seek(struct file *file, loff_t offset, int orig) +{ + file->f_pos = offset; + return 0; +} + +static const struct file_operations power_events_fops = { + .owner = THIS_MODULE, + .read = power_events_read, + .write = power_events_write, + .llseek = power_events_seek, +}; + + +#if MALI_STATE_TRACKING +static int mali_seq_internal_state_show(struct seq_file *seq_file, void *v) +{ + u32 len = 0; + u32 size; + char *buf; + + size = seq_get_buf(seq_file, &buf); + + if(!size) + { + return -ENOMEM; + } + + /* Create the internal state dump. */ + len = snprintf(buf+len, size-len, "Mali device driver %s\n", SVN_REV_STRING); + len += snprintf(buf+len, size-len, "License: %s\n\n", MALI_KERNEL_LINUX_LICENSE); + + len += _mali_kernel_core_dump_state(buf + len, size - len); + + seq_commit(seq_file, len); + + return 0; +} + +static int mali_seq_internal_state_open(struct inode *inode, struct file *file) +{ + return single_open(file, mali_seq_internal_state_show, NULL); +} + +static const struct file_operations mali_seq_internal_state_fops = { + .owner = THIS_MODULE, + .open = mali_seq_internal_state_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +#endif /* MALI_STATE_TRACKING */ + + +#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED +static ssize_t profiling_record_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char buf[64]; + int r; + + r = sprintf(buf, "%u\n", _mali_osk_profiling_is_recording() ? 1 : 0); + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); +} + +static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char buf[64]; + unsigned long val; + int ret; + + if (cnt >= sizeof(buf)) + { + return -EINVAL; + } + + if (copy_from_user(&buf, ubuf, cnt)) + { + return -EFAULT; + } + + buf[cnt] = 0; + + ret = strict_strtoul(buf, 10, &val); + if (ret < 0) + { + return ret; + } + + if (val != 0) + { + u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* This can be made configurable at a later stage if we need to */ + + /* check if we are already recording */ + if (MALI_TRUE == _mali_osk_profiling_is_recording()) + { + MALI_DEBUG_PRINT(3, ("Recording of profiling events already in progress\n")); + return -EFAULT; + } + + /* check if we need to clear out an old recording first */ + if (MALI_TRUE == _mali_osk_profiling_have_recording()) + { + if (_MALI_OSK_ERR_OK != _mali_osk_profiling_clear()) + { + MALI_DEBUG_PRINT(3, ("Failed to clear existing recording of profiling events\n")); + return -EFAULT; + } + } + + /* start recording profiling data */ + if (_MALI_OSK_ERR_OK != _mali_osk_profiling_start(&limit)) + { + MALI_DEBUG_PRINT(3, ("Failed to start recording of profiling events\n")); + return -EFAULT; + } + + MALI_DEBUG_PRINT(3, ("Profiling recording started (max %u events)\n", limit)); + } + else + { + /* stop recording profiling data */ + u32 count = 0; + if (_MALI_OSK_ERR_OK != _mali_osk_profiling_stop(&count)) + { + MALI_DEBUG_PRINT(2, ("Failed to stop recording of profiling events\n")); + return -EFAULT; + } + + MALI_DEBUG_PRINT(2, ("Profiling recording stopped (recorded %u events)\n", count)); + } + + *ppos += cnt; + return cnt; +} + +static const struct file_operations profiling_record_fops = { + .owner = THIS_MODULE, + .read = profiling_record_read, + .write = profiling_record_write, +}; + +static void *profiling_events_start(struct seq_file *s, loff_t *pos) +{ + loff_t *spos; + + /* check if we have data avaiable */ + if (MALI_TRUE != _mali_osk_profiling_have_recording()) + { + return NULL; + } + + spos = kmalloc(sizeof(loff_t), GFP_KERNEL); + if (NULL == spos) + { + return NULL; + } + + *spos = *pos; + return spos; +} + +static void *profiling_events_next(struct seq_file *s, void *v, loff_t *pos) +{ + loff_t *spos = v; + + /* check if we have data avaiable */ + if (MALI_TRUE != _mali_osk_profiling_have_recording()) + { + return NULL; + } + + /* check if the next entry actually is avaiable */ + if (_mali_osk_profiling_get_count() <= (u32)(*spos + 1)) + { + return NULL; + } + + *pos = ++*spos; + return spos; +} + +static void profiling_events_stop(struct seq_file *s, void *v) +{ + kfree(v); +} + +static int profiling_events_show(struct seq_file *seq_file, void *v) +{ + loff_t *spos = v; + u32 index; + u64 timestamp; + u32 event_id; + u32 data[5]; + + index = (u32)*spos; + + /* Retrieve all events */ + if (_MALI_OSK_ERR_OK == _mali_osk_profiling_get_event(index, ×tamp, &event_id, data)) + { + seq_printf(seq_file, "%llu %u %u %u %u %u %u\n", timestamp, event_id, data[0], data[1], data[2], data[3], data[4]); + return 0; + } + + return 0; +} + +static const struct seq_operations profiling_events_seq_ops = { + .start = profiling_events_start, + .next = profiling_events_next, + .stop = profiling_events_stop, + .show = profiling_events_show +}; + +static int profiling_events_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &profiling_events_seq_ops); +} + +static const struct file_operations profiling_events_fops = { + .owner = THIS_MODULE, + .open = profiling_events_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; +#endif + +static ssize_t memory_used_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char buf[64]; + size_t r; + u32 mem = _mali_ukk_report_memory_usage(); + + r = snprintf(buf, 64, "%u\n", mem); + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); +} + +static const struct file_operations memory_usage_fops = { + .owner = THIS_MODULE, + .read = memory_used_read, +}; + + +static ssize_t user_settings_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + unsigned long val; + int ret; + _mali_uk_user_setting_t setting; + char buf[32]; + + cnt = min(cnt, sizeof(buf) - 1); + if (copy_from_user(buf, ubuf, cnt)) + { + return -EFAULT; + } + buf[cnt] = '\0'; + + ret = strict_strtoul(buf, 10, &val); + if (0 != ret) + { + return ret; + } + + /* Update setting */ + setting = (_mali_uk_user_setting_t)(filp->private_data); + mali_set_user_setting(setting, val); + + *ppos += cnt; + return cnt; +} + +static ssize_t user_settings_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char buf[64]; + size_t r; + u32 value; + _mali_uk_user_setting_t setting; + + setting = (_mali_uk_user_setting_t)(filp->private_data); + value = mali_get_user_setting(setting); + + r = snprintf(buf, 64, "%u\n", value); + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); +} + +static const struct file_operations user_settings_fops = { + .owner = THIS_MODULE, + .open = open_copy_private_data, + .read = user_settings_read, + .write = user_settings_write, +}; + +static int mali_sysfs_user_settings_register(void) +{ + struct dentry *mali_user_settings_dir = debugfs_create_dir("userspace_settings", mali_debugfs_dir); + + if (mali_user_settings_dir != NULL) + { + int i; + for (i = 0; i < _MALI_UK_USER_SETTING_MAX; i++) + { + debugfs_create_file(_mali_uk_user_setting_descriptions[i], 0600, mali_user_settings_dir, (void*)i, &user_settings_fops); + } + } + + return 0; +} + +int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev_name) +{ + int err = 0; + + device->mali_class = class_create(THIS_MODULE, mali_dev_name); + if (IS_ERR(device->mali_class)) + { + err = PTR_ERR(device->mali_class); + goto init_class_err; + } + mali_device = device_create(device->mali_class, NULL, dev, NULL, mali_dev_name); + if (IS_ERR(mali_device)) + { + err = PTR_ERR(mali_device); + goto init_mdev_err; + } + + mali_debugfs_dir = debugfs_create_dir(mali_dev_name, NULL); + if(ERR_PTR(-ENODEV) == mali_debugfs_dir) + { + /* Debugfs not supported. */ + mali_debugfs_dir = NULL; + } + else + { + if(NULL != mali_debugfs_dir) + { + /* Debugfs directory created successfully; create files now */ + struct dentry *mali_power_dir; + struct dentry *mali_gp_dir; + struct dentry *mali_pp_dir; + struct dentry *mali_l2_dir; +#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED + struct dentry *mali_profiling_dir; +#endif + + mali_power_dir = debugfs_create_dir("power", mali_debugfs_dir); + if (mali_power_dir != NULL) + { + debugfs_create_file("power_events", 0400, mali_power_dir, NULL, &power_events_fops); + } + + mali_gp_dir = debugfs_create_dir("gp", mali_debugfs_dir); + if (mali_gp_dir != NULL) + { + struct dentry *mali_gp_all_dir; + u32 ci; + struct mali_cluster *cluster; + + mali_gp_all_dir = debugfs_create_dir("all", mali_gp_dir); + if (mali_gp_all_dir != NULL) + { + debugfs_create_file("counter_src0", 0400, mali_gp_all_dir, NULL, &gp_all_counter_src0_fops); + debugfs_create_file("counter_src1", 0400, mali_gp_all_dir, NULL, &gp_all_counter_src1_fops); + } + + ci = 0; + cluster = mali_cluster_get_global_cluster(ci); + while (NULL != cluster) + { + u32 gi = 0; + struct mali_group *group = mali_cluster_get_group(cluster, gi); + while (NULL != group) + { + struct mali_gp_core *gp_core = mali_group_get_gp_core(group); + if (NULL != gp_core) + { + struct dentry *mali_gp_gpx_dir; + mali_gp_gpx_dir = debugfs_create_dir("gp0", mali_gp_dir); + if (NULL != mali_gp_gpx_dir) + { + debugfs_create_file("counter_src0", 0600, mali_gp_gpx_dir, gp_core, &gp_gpx_counter_src0_fops); + debugfs_create_file("counter_src1", 0600, mali_gp_gpx_dir, gp_core, &gp_gpx_counter_src1_fops); + } + break; /* no need to look for any other GP cores */ + } + + /* try next group */ + gi++; + group = mali_cluster_get_group(cluster, gi); + } + + /* try next cluster */ + ci++; + cluster = mali_cluster_get_global_cluster(ci); + } + } + + mali_pp_dir = debugfs_create_dir("pp", mali_debugfs_dir); + if (mali_pp_dir != NULL) + { + struct dentry *mali_pp_all_dir; + u32 ci; + struct mali_cluster *cluster; + + mali_pp_all_dir = debugfs_create_dir("all", mali_pp_dir); + if (mali_pp_all_dir != NULL) + { + debugfs_create_file("counter_src0", 0400, mali_pp_all_dir, NULL, &pp_all_counter_src0_fops); + debugfs_create_file("counter_src1", 0400, mali_pp_all_dir, NULL, &pp_all_counter_src1_fops); + } + + ci = 0; + cluster = mali_cluster_get_global_cluster(ci); + while (NULL != cluster) + { + u32 gi = 0; + struct mali_group *group = mali_cluster_get_group(cluster, gi); + while (NULL != group) + { + struct mali_pp_core *pp_core = mali_group_get_pp_core(group); + if (NULL != pp_core) + { + char buf[16]; + struct dentry *mali_pp_ppx_dir; + _mali_osk_snprintf(buf, sizeof(buf), "pp%u", mali_pp_core_get_id(pp_core)); + mali_pp_ppx_dir = debugfs_create_dir(buf, mali_pp_dir); + if (NULL != mali_pp_ppx_dir) + { + debugfs_create_file("counter_src0", 0600, mali_pp_ppx_dir, pp_core, &pp_ppx_counter_src0_fops); + debugfs_create_file("counter_src1", 0600, mali_pp_ppx_dir, pp_core, &pp_ppx_counter_src1_fops); + } + } + + /* try next group */ + gi++; + group = mali_cluster_get_group(cluster, gi); + } + + /* try next cluster */ + ci++; + cluster = mali_cluster_get_global_cluster(ci); + } + } + + mali_l2_dir = debugfs_create_dir("l2", mali_debugfs_dir); + if (mali_l2_dir != NULL) + { + struct dentry *mali_l2_all_dir; + u32 l2_id; + struct mali_l2_cache_core *l2_cache; + + mali_l2_all_dir = debugfs_create_dir("all", mali_l2_dir); + if (mali_l2_all_dir != NULL) + { + debugfs_create_file("counter_src0", 0400, mali_l2_all_dir, NULL, &l2_all_counter_src0_fops); + debugfs_create_file("counter_src1", 0400, mali_l2_all_dir, NULL, &l2_all_counter_src1_fops); + } + + l2_id = 0; + l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id); + while (NULL != l2_cache) + { + char buf[16]; + struct dentry *mali_l2_l2x_dir; + _mali_osk_snprintf(buf, sizeof(buf), "l2%u", l2_id); + mali_l2_l2x_dir = debugfs_create_dir(buf, mali_l2_dir); + if (NULL != mali_l2_l2x_dir) + { + debugfs_create_file("counter_src0", 0600, mali_l2_l2x_dir, l2_cache, &l2_l2x_counter_src0_fops); + debugfs_create_file("counter_src1", 0600, mali_l2_l2x_dir, l2_cache, &l2_l2x_counter_src1_fops); + } + + /* try next L2 */ + l2_id++; + l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id); + } + } + + debugfs_create_file("memory_usage", 0400, mali_debugfs_dir, NULL, &memory_usage_fops); + +#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED + mali_profiling_dir = debugfs_create_dir("profiling", mali_debugfs_dir); + if (mali_profiling_dir != NULL) + { + struct dentry *mali_profiling_proc_dir = debugfs_create_dir("proc", mali_profiling_dir); + if (mali_profiling_proc_dir != NULL) + { + struct dentry *mali_profiling_proc_default_dir = debugfs_create_dir("default", mali_profiling_proc_dir); + if (mali_profiling_proc_default_dir != NULL) + { + debugfs_create_file("enable", 0600, mali_profiling_proc_default_dir, (void*)_MALI_UK_USER_SETTING_SW_EVENTS_ENABLE, &user_settings_fops); + } + } + debugfs_create_file("record", 0600, mali_profiling_dir, NULL, &profiling_record_fops); + debugfs_create_file("events", 0400, mali_profiling_dir, NULL, &profiling_events_fops); + } +#endif + +#if MALI_STATE_TRACKING + debugfs_create_file("state_dump", 0400, mali_debugfs_dir, NULL, &mali_seq_internal_state_fops); +#endif + + if (mali_sysfs_user_settings_register()) + { + /* Failed to create the debugfs entries for the user settings DB. */ + MALI_DEBUG_PRINT(2, ("Failed to create user setting debugfs files. Ignoring...\n")); + } + } + } + + /* Success! */ + return 0; + + /* Error handling */ +init_mdev_err: + class_destroy(device->mali_class); +init_class_err: + + return err; +} + +int mali_sysfs_unregister(struct mali_dev *device, dev_t dev, const char *mali_dev_name) +{ + if(NULL != mali_debugfs_dir) + { + debugfs_remove_recursive(mali_debugfs_dir); + } + device_destroy(device->mali_class, dev); + class_destroy(device->mali_class); + + return 0; +} + +#else + +/* Dummy implementations for non-GPL */ + +int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev_name) +{ + return 0; +} + +int mali_sysfs_unregister(struct mali_dev *device, dev_t dev, const char *mali_dev_name) +{ + return 0; +} + + +#endif diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.h b/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.h new file mode 100644 index 0000000..24acca9 --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_KERNEL_SYSFS_H__ +#define __MALI_KERNEL_SYSFS_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +#define MALI_PROC_DIR "driver/mali" + +extern struct device *mali_device; +struct mali_dev; + +int mali_sysfs_register(struct mali_dev *mali_class, dev_t dev, const char *mali_dev_name); + +int mali_sysfs_unregister(struct mali_dev *mali_class, dev_t dev, const char *mali_dev_name); + + +#ifdef __cplusplus +} +#endif + +#endif /* __MALI_KERNEL_LINUX_H__ */ diff --git a/drivers/media/video/samsung/mali/linux/mali_linux_pm.h b/drivers/media/video/samsung/mali/linux/mali_linux_pm.h new file mode 100644 index 0000000..10f633e --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_linux_pm.h @@ -0,0 +1,50 @@ + +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_LINUX_PM_H__ +#define __MALI_LINUX_PM_H__ + +#ifdef CONFIG_PM +/* Number of power states supported for making power up and down */ +typedef enum +{ + _MALI_DEVICE_SUSPEND, /* Suspend */ + _MALI_DEVICE_RESUME, /* Resume */ + _MALI_DEVICE_MAX_POWER_STATES, /* Maximum power states */ +} _mali_device_power_states; + +/* Number of DVFS events */ +typedef enum +{ + _MALI_DVFS_PAUSE_EVENT = _MALI_DEVICE_MAX_POWER_STATES, /* DVFS Pause event */ + _MALI_DVFS_RESUME_EVENT, /* DVFS Resume event */ + _MALI_MAX_DEBUG_OPERATIONS, +} _mali_device_dvfs_events; + +extern _mali_device_power_states mali_device_state; +extern _mali_device_power_states mali_dvfs_device_state; +extern _mali_osk_lock_t *lock; +extern short is_wake_up_needed; +extern int timeout_fired; +extern struct platform_device mali_gpu_device; + +/* dvfs pm thread */ +extern struct task_struct *dvfs_pm_thread; + +/* Power management thread */ +extern struct task_struct *pm_thread; + +int mali_device_suspend(u32 event_id, struct task_struct **pwr_mgmt_thread); +int mali_device_resume(u32 event_id, struct task_struct **pwr_mgmt_thread); +int mali_get_ospmm_thread_state(void); + +#endif /* CONFIG_PM */ +#endif /* __MALI_LINUX_PM_H___ */ diff --git a/drivers/media/video/samsung/mali/linux/mali_linux_pm_testsuite.h b/drivers/media/video/samsung/mali/linux/mali_linux_pm_testsuite.h new file mode 100644 index 0000000..7d811bd --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_linux_pm_testsuite.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef __MALI_LINUX_PM_TESTSUITE_H__ +#define __MALI_LINUX_PM_TESTSUITE_H__ + +#if MALI_POWER_MGMT_TEST_SUITE && defined(CONFIG_PM) + +typedef enum +{ + _MALI_DEVICE_PMM_TIMEOUT_EVENT, + _MALI_DEVICE_PMM_JOB_SCHEDULING_EVENTS, + _MALI_DEVICE_PMM_REGISTERED_CORES, + _MALI_DEVICE_MAX_PMM_EVENTS + +} _mali_device_pmm_recording_events; + +extern unsigned int mali_timeout_event_recording_on; +extern unsigned int mali_job_scheduling_events_recording_on; +extern unsigned int pwr_mgmt_status_reg; +extern unsigned int is_mali_pmm_testsuite_enabled; +extern unsigned int is_mali_pmu_present; + +#endif /* MALI_POWER_MGMT_TEST_SUITE && defined(CONFIG_PM) */ + +#endif /* __MALI_LINUX_PM_TESTSUITE_H__ */ diff --git a/drivers/media/video/samsung/mali/linux/mali_linux_trace.h b/drivers/media/video/samsung/mali/linux/mali_linux_trace.h new file mode 100644 index 0000000..5329ba3 --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_linux_trace.h @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#if !defined (MALI_LINUX_TRACE_H) || defined (TRACE_HEADER_MULTI_READ) +#define MALI_LINUX_TRACE_H + +#include + +#include +#include + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM mali +#define TRACE_SYSTEM_STRING __stringfy(TRACE_SYSTEM) + +#define TRACE_INCLUDE_PATH . +#define TRACE_INCLUDE_FILE mali_linux_trace + +/** + * Define the tracepoint used to communicate the status of a GPU. Called + * when a GPU turns on or turns off. + * + * @param event_id The type of the event. This parameter is a bitfield + * encoding the type of the event. + * + * @param d0 First data parameter. + * @param d1 Second data parameter. + * @param d2 Third data parameter. + * @param d3 Fourth data parameter. + * @param d4 Fifth data parameter. + */ +TRACE_EVENT(mali_timeline_event, + + TP_PROTO(unsigned int event_id, unsigned int d0, unsigned int d1, + unsigned int d2, unsigned int d3, unsigned int d4), + + TP_ARGS(event_id, d0, d1, d2, d3, d4), + + TP_STRUCT__entry( + __field(unsigned int, event_id) + __field(unsigned int, d0) + __field(unsigned int, d1) + __field(unsigned int, d2) + __field(unsigned int, d3) + __field(unsigned int, d4) + ), + + TP_fast_assign( + __entry->event_id = event_id; + __entry->d0 = d0; + __entry->d1 = d1; + __entry->d2 = d2; + __entry->d3 = d3; + __entry->d4 = d4; + ), + + TP_printk("event=%d", __entry->event_id) +); + +/** + * Define a tracepoint used to regsiter the value of a hardware counter. + * Hardware counters belonging to the vertex or fragment processor are + * reported via this tracepoint each frame, whilst L2 cache hardware + * counters are reported continuously. + * + * @param counter_id The counter ID. + * @param value The value of the counter. + */ +TRACE_EVENT(mali_hw_counter, + + TP_PROTO(unsigned int counter_id, unsigned int value), + + TP_ARGS(counter_id, value), + + TP_STRUCT__entry( + __field(unsigned int, counter_id) + __field(unsigned int, value) + ), + + TP_fast_assign( + __entry->counter_id = counter_id; + ), + + TP_printk("event %d = %d", __entry->counter_id, __entry->value) +); + +/** + * Define a tracepoint used to send a bundle of software counters. + * + * @param counters The bundle of counters. + */ +TRACE_EVENT(mali_sw_counters, + + TP_PROTO(pid_t pid, pid_t tid, void * surface_id, unsigned int * counters), + + TP_ARGS(pid, tid, surface_id, counters), + + TP_STRUCT__entry( + __field(pid_t, pid) + __field(pid_t, tid) + __field(void *, surface_id) + __field(unsigned int *, counters) + ), + + TP_fast_assign( + __entry->pid = pid; + __entry->tid = tid; + __entry->surface_id = surface_id; + __entry->counters = counters; + ), + + TP_printk("counters were %s", __entry->counters == NULL? "NULL" : "not NULL") +); + +#endif /* MALI_LINUX_TRACE_H */ + +/* This part must exist outside the header guard. */ +#include + diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_atomics.c b/drivers/media/video/samsung/mali/linux/mali_osk_atomics.c new file mode 100644 index 0000000..32f8e6b --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_osk_atomics.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_atomics.c + * Implementation of the OS abstraction layer for the kernel device driver + */ + +#include "mali_osk.h" +#include +#include "mali_kernel_common.h" + +void _mali_osk_atomic_dec( _mali_osk_atomic_t *atom ) +{ + atomic_dec((atomic_t *)&atom->u.val); +} + +u32 _mali_osk_atomic_dec_return( _mali_osk_atomic_t *atom ) +{ + return atomic_dec_return((atomic_t *)&atom->u.val); +} + +void _mali_osk_atomic_inc( _mali_osk_atomic_t *atom ) +{ + atomic_inc((atomic_t *)&atom->u.val); +} + +u32 _mali_osk_atomic_inc_return( _mali_osk_atomic_t *atom ) +{ + return atomic_inc_return((atomic_t *)&atom->u.val); +} + +_mali_osk_errcode_t _mali_osk_atomic_init( _mali_osk_atomic_t *atom, u32 val ) +{ + MALI_CHECK_NON_NULL(atom, _MALI_OSK_ERR_INVALID_ARGS); + atomic_set((atomic_t *)&atom->u.val, val); + return _MALI_OSK_ERR_OK; +} + +u32 _mali_osk_atomic_read( _mali_osk_atomic_t *atom ) +{ + return atomic_read((atomic_t *)&atom->u.val); +} + +void _mali_osk_atomic_term( _mali_osk_atomic_t *atom ) +{ + MALI_IGNORE(atom); +} diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_irq.c b/drivers/media/video/samsung/mali/linux/mali_osk_irq.c new file mode 100644 index 0000000..ddfe564 --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_osk_irq.c @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_irq.c + * Implementation of the OS abstraction layer for the kernel device driver + */ + +#include /* For memory allocation */ +#include +#include + +#include "mali_osk.h" +#include "mali_kernel_common.h" +#include "mali_kernel_license.h" +#include "mali_kernel_linux.h" +#include "linux/interrupt.h" + +typedef struct _mali_osk_irq_t_struct +{ + u32 irqnum; + void *data; + _mali_osk_irq_uhandler_t uhandler; + _mali_osk_irq_bhandler_t bhandler; + struct work_struct work_queue_irq_handle; /* Workqueue for the bottom half of the IRQ-handling. This job is activated when this core gets an IRQ.*/ +} mali_osk_irq_object_t; + +#if MALI_LICENSE_IS_GPL +static struct workqueue_struct *pmm_wq = NULL; +struct workqueue_struct *mali_wq = NULL; +#endif + +typedef void (*workqueue_func_t)(void *); +typedef irqreturn_t (*irq_handler_func_t)(int, void *, struct pt_regs *); +static irqreturn_t irq_handler_upper_half (int port_name, void* dev_id ); /* , struct pt_regs *regs*/ + +#if defined(INIT_DELAYED_WORK) +static void irq_handler_bottom_half ( struct work_struct *work ); +#else +static void irq_handler_bottom_half ( void * input ); +#endif + +/** + * Linux kernel version has marked SA_SHIRQ as deprecated, IRQF_SHARED should be used. + * This is to handle older kernels which haven't done this swap. + */ +#ifndef IRQF_SHARED +#define IRQF_SHARED SA_SHIRQ +#endif /* IRQF_SHARED */ + +_mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandler, _mali_osk_irq_bhandler_t bhandler, _mali_osk_irq_trigger_t trigger_func, _mali_osk_irq_ack_t ack_func, void *data, const char *description ) +{ + mali_osk_irq_object_t *irq_object; + + irq_object = kmalloc(sizeof(mali_osk_irq_object_t), GFP_KERNEL); + if (NULL == irq_object) return NULL; + +#if MALI_LICENSE_IS_GPL + if (NULL == mali_wq) + { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) + mali_wq = alloc_workqueue("mali", WQ_UNBOUND, 0); +#else + mali_wq = create_workqueue("mali"); +#endif + if(NULL == mali_wq) + { + MALI_PRINT_ERROR(("Unable to create Mali workqueue\n")); + kfree(irq_object); + return NULL; + } + } +#endif + + /* workqueue API changed in 2.6.20, support both versions: */ +#if defined(INIT_DELAYED_WORK) + /* New syntax: INIT_WORK( struct work_struct *work, void (*function)(struct work_struct *)) */ + INIT_WORK( &irq_object->work_queue_irq_handle, irq_handler_bottom_half); +#else + /* Old syntax: INIT_WORK( struct work_struct *work, void (*function)(void *), void *data) */ + INIT_WORK( &irq_object->work_queue_irq_handle, irq_handler_bottom_half, irq_object); +#endif /* defined(INIT_DELAYED_WORK) */ + + if (-1 == irqnum) + { + /* Probe for IRQ */ + if ( (NULL != trigger_func) && (NULL != ack_func) ) + { + unsigned long probe_count = 3; + _mali_osk_errcode_t err; + int irq; + + MALI_DEBUG_PRINT(2, ("Probing for irq\n")); + + do + { + unsigned long mask; + + mask = probe_irq_on(); + trigger_func(data); + + _mali_osk_time_ubusydelay(5); + + irq = probe_irq_off(mask); + err = ack_func(data); + } + while (irq < 0 && (err == _MALI_OSK_ERR_OK) && probe_count--); + + if (irq < 0 || (_MALI_OSK_ERR_OK != err)) irqnum = -1; + else irqnum = irq; + } + else irqnum = -1; /* no probe functions, fault */ + + if (-1 != irqnum) + { + /* found an irq */ + MALI_DEBUG_PRINT(2, ("Found irq %d\n", irqnum)); + } + else + { + MALI_DEBUG_PRINT(2, ("Probe for irq failed\n")); + } + } + + irq_object->irqnum = irqnum; + irq_object->uhandler = uhandler; + irq_object->bhandler = bhandler; + irq_object->data = data; + + /* Is this a real IRQ handler we need? */ + if (irqnum != _MALI_OSK_IRQ_NUMBER_FAKE && irqnum != _MALI_OSK_IRQ_NUMBER_PMM) + { + if (-1 == irqnum) + { + MALI_DEBUG_PRINT(2, ("No IRQ for core '%s' found during probe\n", description)); + kfree(irq_object); + return NULL; + } + + if (0 != request_irq(irqnum, irq_handler_upper_half, IRQF_SHARED, description, irq_object)) + { + MALI_DEBUG_PRINT(2, ("Unable to install IRQ handler for core '%s'\n", description)); + kfree(irq_object); + return NULL; + } + } + +#if MALI_LICENSE_IS_GPL + if ( _MALI_OSK_IRQ_NUMBER_PMM == irqnum ) + { + pmm_wq = create_singlethread_workqueue("mali-pmm-wq"); + } +#endif + + return irq_object; +} + +void _mali_osk_irq_schedulework( _mali_osk_irq_t *irq ) +{ + mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq; +#if MALI_LICENSE_IS_GPL + if ( irq_object->irqnum == _MALI_OSK_IRQ_NUMBER_PMM ) + { + queue_work( pmm_wq,&irq_object->work_queue_irq_handle ); + } + else + { + queue_work(mali_wq, &irq_object->work_queue_irq_handle); + } +#else + schedule_work(&irq_object->work_queue_irq_handle); +#endif +} + +void _mali_osk_flush_workqueue( _mali_osk_irq_t *irq ) +{ +#if MALI_LICENSE_IS_GPL + if (NULL != irq) + { + mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq; + if(irq_object->irqnum == _MALI_OSK_IRQ_NUMBER_PMM ) + { + flush_workqueue(pmm_wq); + } + else + { + flush_workqueue(mali_wq); + } + } + else + { + flush_workqueue(mali_wq); + } +#endif +} + +void _mali_osk_irq_term( _mali_osk_irq_t *irq ) +{ + mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq; + +#if MALI_LICENSE_IS_GPL + if(irq_object->irqnum == _MALI_OSK_IRQ_NUMBER_PMM ) + { + flush_workqueue(pmm_wq); + destroy_workqueue(pmm_wq); + } +#endif + free_irq(irq_object->irqnum, irq_object); + kfree(irq_object); + flush_scheduled_work(); +} + + +/** This function is called directly in interrupt context from the OS just after + * the CPU get the hw-irq from mali, or other devices on the same IRQ-channel. + * It is registered one of these function for each mali core. When an interrupt + * arrives this function will be called equal times as registered mali cores. + * That means that we only check one mali core in one function call, and the + * core we check for each turn is given by the \a dev_id variable. + * If we detect an pending interrupt on the given core, we mask the interrupt + * out by settging the core's IRQ_MASK register to zero. + * Then we schedule the mali_core_irq_handler_bottom_half to run as high priority + * work queue job. + */ +static irqreturn_t irq_handler_upper_half (int port_name, void* dev_id ) /* , struct pt_regs *regs*/ +{ + mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)dev_id; + + if (irq_object->uhandler(irq_object->data) == _MALI_OSK_ERR_OK) + { + return IRQ_HANDLED; + } + return IRQ_NONE; +} + +/* Is executed when an interrupt occur on one core */ +/* workqueue API changed in 2.6.20, support both versions: */ +#if defined(INIT_DELAYED_WORK) +static void irq_handler_bottom_half ( struct work_struct *work ) +#else +static void irq_handler_bottom_half ( void * input ) +#endif +{ + mali_osk_irq_object_t *irq_object; + +#if defined(INIT_DELAYED_WORK) + irq_object = _MALI_OSK_CONTAINER_OF(work, mali_osk_irq_object_t, work_queue_irq_handle); +#else + if ( NULL == input ) + { + MALI_PRINT_ERROR(("IRQ: Null pointer! Illegal!")); + return; /* Error */ + } + irq_object = (mali_osk_irq_object_t *) input; +#endif + + irq_object->bhandler(irq_object->data); +} + diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_locks.c b/drivers/media/video/samsung/mali/linux/mali_osk_locks.c new file mode 100644 index 0000000..ee857d5 --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_osk_locks.c @@ -0,0 +1,340 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_locks.c + * Implemenation of the OS abstraction layer for the kernel device driver + */ + +/* needed to detect kernel version specific code */ +#include + +#include +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) +#include +#else /* pre 2.6.26 the file was in the arch specific location */ +#include +#endif + +#include +#include "mali_osk.h" +#include "mali_kernel_common.h" + +/* These are all the locks we implement: */ +typedef enum +{ + _MALI_OSK_INTERNAL_LOCKTYPE_SPIN, /* Mutex, implicitly non-interruptable, use spin_lock/spin_unlock */ + _MALI_OSK_INTERNAL_LOCKTYPE_SPIN_IRQ, /* Mutex, IRQ version of spinlock, use spin_lock_irqsave/spin_unlock_irqrestore */ + _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX, /* Interruptable, use up()/down_interruptable() */ + _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT, /* Non-Interruptable, use up()/down() */ + _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW, /* Non-interruptable, Reader/Writer, use {up,down}{read,write}() */ + + /* Linux supports, but we do not support: + * Non-Interruptable Reader/Writer spinlock mutexes - RW optimization will be switched off + */ + + /* Linux does not support: + * One-locks, of any sort - no optimization for this fact will be made. + */ + +} _mali_osk_internal_locktype; + +struct _mali_osk_lock_t_struct +{ + _mali_osk_internal_locktype type; + unsigned long flags; + union + { + spinlock_t spinlock; + struct semaphore sema; + struct rw_semaphore rw_sema; + } obj; + MALI_DEBUG_CODE( + /** original flags for debug checking */ + _mali_osk_lock_flags_t orig_flags; + + /* id of the thread currently holding this lock, 0 if no + * threads hold it. */ + u32 owner; + /* number of owners this lock currently has (can be > 1 if + * taken in R/O mode. */ + u32 nOwners; + /* what mode the lock was taken in */ + _mali_osk_lock_mode_t mode; + ); /* MALI_DEBUG_CODE */ +}; + +_mali_osk_lock_t *_mali_osk_lock_init( _mali_osk_lock_flags_t flags, u32 initial, u32 order ) +{ + _mali_osk_lock_t *lock = NULL; + + /* Validate parameters: */ + /* Flags acceptable */ + MALI_DEBUG_ASSERT( 0 == ( flags & ~(_MALI_OSK_LOCKFLAG_SPINLOCK + | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ + | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE + | _MALI_OSK_LOCKFLAG_READERWRITER + | _MALI_OSK_LOCKFLAG_ORDERED + | _MALI_OSK_LOCKFLAG_ONELOCK )) ); + /* Spinlocks are always non-interruptable */ + MALI_DEBUG_ASSERT( (((flags & _MALI_OSK_LOCKFLAG_SPINLOCK) || (flags & _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ)) && (flags & _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE)) + || !(flags & _MALI_OSK_LOCKFLAG_SPINLOCK)); + /* Parameter initial SBZ - for future expansion */ + MALI_DEBUG_ASSERT( 0 == initial ); + + lock = kmalloc(sizeof(_mali_osk_lock_t), GFP_KERNEL); + + if ( NULL == lock ) + { + return lock; + } + + /* Determine type of mutex: */ + /* defaults to interruptable mutex if no flags are specified */ + + if ( (flags & _MALI_OSK_LOCKFLAG_SPINLOCK) ) + { + /* Non-interruptable Spinlocks override all others */ + lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_SPIN; + spin_lock_init( &lock->obj.spinlock ); + } + else if ( (flags & _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ ) ) + { + lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_SPIN_IRQ; + lock->flags = 0; + spin_lock_init( &lock->obj.spinlock ); + } + else if ( (flags & _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE) + && (flags & _MALI_OSK_LOCKFLAG_READERWRITER) ) + { + lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW; + init_rwsem( &lock->obj.rw_sema ); + } + else + { + /* Usual mutex types */ + if ( (flags & _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE) ) + { + lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT; + } + else + { + lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX; + } + + /* Initially unlocked */ + sema_init( &lock->obj.sema, 1 ); + } + +#ifdef DEBUG + /* Debug tracking of flags */ + lock->orig_flags = flags; + + /* Debug tracking of lock owner */ + lock->owner = 0; + lock->nOwners = 0; +#endif /* DEBUG */ + + return lock; +} + +#ifdef DEBUG +u32 _mali_osk_lock_get_owner( _mali_osk_lock_t *lock ) +{ + return lock->owner; +} + +u32 _mali_osk_lock_get_number_owners( _mali_osk_lock_t *lock ) +{ + return lock->nOwners; +} + +u32 _mali_osk_lock_get_mode( _mali_osk_lock_t *lock ) +{ + return lock->mode; +} +#endif /* DEBUG */ + +_mali_osk_errcode_t _mali_osk_lock_wait( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode) +{ + _mali_osk_errcode_t err = _MALI_OSK_ERR_OK; + + /* Parameter validation */ + MALI_DEBUG_ASSERT_POINTER( lock ); + + MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_RW == mode + || _MALI_OSK_LOCKMODE_RO == mode ); + + /* Only allow RO locks when the initial object was a Reader/Writer lock + * Since information is lost on the internal locktype, we use the original + * information, which is only stored when built for DEBUG */ + MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_RW == mode + || (_MALI_OSK_LOCKMODE_RO == mode && (_MALI_OSK_LOCKFLAG_READERWRITER & lock->orig_flags)) ); + + switch ( lock->type ) + { + case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN: + spin_lock(&lock->obj.spinlock); + break; + case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN_IRQ: + { + unsigned long tmp_flags; + spin_lock_irqsave(&lock->obj.spinlock, tmp_flags); + lock->flags = tmp_flags; + } + break; + + case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX: + if ( down_interruptible(&lock->obj.sema) ) + { + MALI_PRINT_ERROR(("Can not lock mutex\n")); + err = _MALI_OSK_ERR_RESTARTSYSCALL; + } + break; + + case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT: + down(&lock->obj.sema); + break; + + case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW: + if (mode == _MALI_OSK_LOCKMODE_RO) + { + down_read(&lock->obj.rw_sema); + } + else + { + down_write(&lock->obj.rw_sema); + } + break; + + default: + /* Reaching here indicates a programming error, so you will not get here + * on non-DEBUG builds */ + MALI_DEBUG_PRINT_ERROR( ("Invalid internal lock type: %.8X", lock->type ) ); + break; + } + +#ifdef DEBUG + /* This thread is now the owner of this lock */ + if (_MALI_OSK_ERR_OK == err) + { + if (mode == _MALI_OSK_LOCKMODE_RW) + { + /*MALI_DEBUG_ASSERT(0 == lock->owner);*/ + if (0 != lock->owner) + { + printk(KERN_ERR "%d: ERROR: Lock %p already has owner %d\n", _mali_osk_get_tid(), lock, lock->owner); + dump_stack(); + } + lock->owner = _mali_osk_get_tid(); + lock->mode = mode; + ++lock->nOwners; + } + else /* mode == _MALI_OSK_LOCKMODE_RO */ + { + lock->owner |= _mali_osk_get_tid(); + lock->mode = mode; + ++lock->nOwners; + } + } +#endif + + return err; +} + +void _mali_osk_lock_signal( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode ) +{ + /* Parameter validation */ + MALI_DEBUG_ASSERT_POINTER( lock ); + + MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_RW == mode + || _MALI_OSK_LOCKMODE_RO == mode ); + + /* Only allow RO locks when the initial object was a Reader/Writer lock + * Since information is lost on the internal locktype, we use the original + * information, which is only stored when built for DEBUG */ + MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_RW == mode + || (_MALI_OSK_LOCKMODE_RO == mode && (_MALI_OSK_LOCKFLAG_READERWRITER & lock->orig_flags)) ); + +#ifdef DEBUG + /* make sure the thread releasing the lock actually was the owner */ + if (mode == _MALI_OSK_LOCKMODE_RW) + { + /*MALI_DEBUG_ASSERT(_mali_osk_get_tid() == lock->owner);*/ + if (_mali_osk_get_tid() != lock->owner) + { + printk(KERN_ERR "%d: ERROR: Lock %p owner was %d\n", _mali_osk_get_tid(), lock, lock->owner); + dump_stack(); + } + /* This lock now has no owner */ + lock->owner = 0; + --lock->nOwners; + } + else /* mode == _MALI_OSK_LOCKMODE_RO */ + { + if ((_mali_osk_get_tid() & lock->owner) != _mali_osk_get_tid()) + { + printk(KERN_ERR "%d: ERROR: Not an owner of %p lock.\n", _mali_osk_get_tid(), lock); + dump_stack(); + } + + /* if this is the last thread holding this lock in R/O mode, set owner + * back to 0 */ + if (0 == --lock->nOwners) + { + lock->owner = 0; + } + } +#endif /* DEBUG */ + + switch ( lock->type ) + { + case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN: + spin_unlock(&lock->obj.spinlock); + break; + case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN_IRQ: + spin_unlock_irqrestore(&lock->obj.spinlock, lock->flags); + break; + + case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX: + /* FALLTHROUGH */ + case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT: + up(&lock->obj.sema); + break; + + case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW: + if (mode == _MALI_OSK_LOCKMODE_RO) + { + up_read(&lock->obj.rw_sema); + } + else + { + up_write(&lock->obj.rw_sema); + } + break; + + default: + /* Reaching here indicates a programming error, so you will not get here + * on non-DEBUG builds */ + MALI_DEBUG_PRINT_ERROR( ("Invalid internal lock type: %.8X", lock->type ) ); + break; + } +} + +void _mali_osk_lock_term( _mali_osk_lock_t *lock ) +{ + /* Parameter validation */ + MALI_DEBUG_ASSERT_POINTER( lock ); + + /* Linux requires no explicit termination of spinlocks, semaphores, or rw_semaphores */ + kfree(lock); +} diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_low_level_mem.c b/drivers/media/video/samsung/mali/linux/mali_osk_low_level_mem.c new file mode 100644 index 0000000..02558a0 --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_osk_low_level_mem.c @@ -0,0 +1,660 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_low_level_mem.c + * Implementation of the OS abstraction layer for the kernel device driver + */ + +/* needed to detect kernel version specific code */ +#include + +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0) +#include +#endif + +#include "mali_osk.h" +#include "mali_ukk.h" /* required to hook in _mali_ukk_mem_mmap handling */ +#include "mali_kernel_common.h" +#include "mali_kernel_linux.h" + +static void mali_kernel_memory_vma_open(struct vm_area_struct * vma); +static void mali_kernel_memory_vma_close(struct vm_area_struct * vma); + + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) +static int mali_kernel_memory_cpu_page_fault_handler(struct vm_area_struct *vma, struct vm_fault *vmf); +#else +static unsigned long mali_kernel_memory_cpu_page_fault_handler(struct vm_area_struct * vma, unsigned long address); +#endif + + +typedef struct mali_vma_usage_tracker +{ + int references; + u32 cookie; +} mali_vma_usage_tracker; + + +/* Linked list structure to hold details of all OS allocations in a particular + * mapping + */ +struct AllocationList +{ + struct AllocationList *next; + u32 offset; + u32 physaddr; +}; + +typedef struct AllocationList AllocationList; + +/* Private structure to store details of a mapping region returned + * from _mali_osk_mem_mapregion_init + */ +struct MappingInfo +{ + struct vm_area_struct *vma; + struct AllocationList *list; + struct AllocationList *tail; +}; + +typedef struct MappingInfo MappingInfo; + + +static u32 _kernel_page_allocate(void); +static void _kernel_page_release(u32 physical_address); +static AllocationList * _allocation_list_item_get(void); +static void _allocation_list_item_release(AllocationList * item); + + +/* Variable declarations */ +static DEFINE_SPINLOCK(allocation_list_spinlock); +static AllocationList * pre_allocated_memory = (AllocationList*) NULL ; +static int pre_allocated_memory_size_current = 0; +#ifdef MALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB + static int pre_allocated_memory_size_max = MALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB * 1024 * 1024; +#else + static int pre_allocated_memory_size_max = 16 * 1024 * 1024; /* 6 MiB */ +#endif + +static struct vm_operations_struct mali_kernel_vm_ops = +{ + .open = mali_kernel_memory_vma_open, + .close = mali_kernel_memory_vma_close, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) + .fault = mali_kernel_memory_cpu_page_fault_handler +#else + .nopfn = mali_kernel_memory_cpu_page_fault_handler +#endif +}; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) +static int mali_mem_shrink(int nr_to_scan, gfp_t gfp_mask) + #else +static int mali_mem_shrink(struct shrinker *shrinker, int nr_to_scan, gfp_t gfp_mask) + #endif +#else +static int mali_mem_shrink(struct shrinker *shrinker, struct shrink_control *sc) +#endif +{ + unsigned long flags; + AllocationList *item; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) + int nr = nr_to_scan; +#else + int nr = sc->nr_to_scan; +#endif + + if (0 == nr) + { + return pre_allocated_memory_size_current / PAGE_SIZE; + } + + if (0 == pre_allocated_memory_size_current) + { + /* No pages availble */ + return 0; + } + + if (0 == spin_trylock_irqsave(&allocation_list_spinlock, flags)) + { + /* Not able to lock. */ + return -1; + } + + while (pre_allocated_memory && nr > 0) + { + item = pre_allocated_memory; + pre_allocated_memory = item->next; + + _kernel_page_release(item->physaddr); + _mali_osk_free(item); + + pre_allocated_memory_size_current -= PAGE_SIZE; + --nr; + } + spin_unlock_irqrestore(&allocation_list_spinlock,flags); + + return pre_allocated_memory_size_current / PAGE_SIZE; +} + +struct shrinker mali_mem_shrinker = { + .shrink = mali_mem_shrink, + .seeks = DEFAULT_SEEKS, +}; + +void mali_osk_low_level_mem_init(void) +{ + pre_allocated_memory = (AllocationList*) NULL ; + + register_shrinker(&mali_mem_shrinker); +} + +void mali_osk_low_level_mem_term(void) +{ + unregister_shrinker(&mali_mem_shrinker); + + while ( NULL != pre_allocated_memory ) + { + AllocationList *item; + item = pre_allocated_memory; + pre_allocated_memory = item->next; + _kernel_page_release(item->physaddr); + _mali_osk_free( item ); + } + pre_allocated_memory_size_current = 0; +} + +static u32 _kernel_page_allocate(void) +{ + struct page *new_page; + u32 linux_phys_addr; + + new_page = alloc_page(GFP_HIGHUSER | __GFP_ZERO | __GFP_REPEAT | __GFP_NOWARN | __GFP_COLD); + + if ( NULL == new_page ) + { + return 0; + } + + /* Ensure page is flushed from CPU caches. */ + linux_phys_addr = dma_map_page(NULL, new_page, 0, PAGE_SIZE, DMA_BIDIRECTIONAL); + + return linux_phys_addr; +} + +static void _kernel_page_release(u32 physical_address) +{ + struct page *unmap_page; + + #if 1 + dma_unmap_page(NULL, physical_address, PAGE_SIZE, DMA_BIDIRECTIONAL); + #endif + + unmap_page = pfn_to_page( physical_address >> PAGE_SHIFT ); + MALI_DEBUG_ASSERT_POINTER( unmap_page ); + __free_page( unmap_page ); +} + +static AllocationList * _allocation_list_item_get(void) +{ + AllocationList *item = NULL; + unsigned long flags; + + spin_lock_irqsave(&allocation_list_spinlock,flags); + if ( pre_allocated_memory ) + { + item = pre_allocated_memory; + pre_allocated_memory = pre_allocated_memory->next; + pre_allocated_memory_size_current -= PAGE_SIZE; + + spin_unlock_irqrestore(&allocation_list_spinlock,flags); + return item; + } + spin_unlock_irqrestore(&allocation_list_spinlock,flags); + + item = _mali_osk_malloc( sizeof(AllocationList) ); + if ( NULL == item) + { + return NULL; + } + + item->physaddr = _kernel_page_allocate(); + if ( 0 == item->physaddr ) + { + /* Non-fatal error condition, out of memory. Upper levels will handle this. */ + _mali_osk_free( item ); + return NULL; + } + return item; +} + +static void _allocation_list_item_release(AllocationList * item) +{ + unsigned long flags; + spin_lock_irqsave(&allocation_list_spinlock,flags); + if ( pre_allocated_memory_size_current < pre_allocated_memory_size_max) + { + item->next = pre_allocated_memory; + pre_allocated_memory = item; + pre_allocated_memory_size_current += PAGE_SIZE; + spin_unlock_irqrestore(&allocation_list_spinlock,flags); + return; + } + spin_unlock_irqrestore(&allocation_list_spinlock,flags); + + _kernel_page_release(item->physaddr); + _mali_osk_free( item ); +} + + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) +static int mali_kernel_memory_cpu_page_fault_handler(struct vm_area_struct *vma, struct vm_fault *vmf) +#else +static unsigned long mali_kernel_memory_cpu_page_fault_handler(struct vm_area_struct * vma, unsigned long address) +#endif +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) + void __user * address; + address = vmf->virtual_address; +#endif + /* + * We always fail the call since all memory is pre-faulted when assigned to the process. + * Only the Mali cores can use page faults to extend buffers. + */ + + MALI_DEBUG_PRINT(1, ("Page-fault in Mali memory region caused by the CPU.\n")); + MALI_DEBUG_PRINT(1, ("Tried to access %p (process local virtual address) which is not currently mapped to any Mali memory.\n", (void*)address)); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) + return VM_FAULT_SIGBUS; +#else + return NOPFN_SIGBUS; +#endif +} + +static void mali_kernel_memory_vma_open(struct vm_area_struct * vma) +{ + mali_vma_usage_tracker * vma_usage_tracker; + MALI_DEBUG_PRINT(4, ("Open called on vma %p\n", vma)); + + vma_usage_tracker = (mali_vma_usage_tracker*)vma->vm_private_data; + vma_usage_tracker->references++; + + return; +} + +static void mali_kernel_memory_vma_close(struct vm_area_struct * vma) +{ + _mali_uk_mem_munmap_s args = {0, }; + mali_memory_allocation * descriptor; + mali_vma_usage_tracker * vma_usage_tracker; + MALI_DEBUG_PRINT(3, ("Close called on vma %p\n", vma)); + + vma_usage_tracker = (mali_vma_usage_tracker*)vma->vm_private_data; + + BUG_ON(!vma_usage_tracker); + BUG_ON(0 == vma_usage_tracker->references); + + vma_usage_tracker->references--; + + if (0 != vma_usage_tracker->references) + { + MALI_DEBUG_PRINT(3, ("Ignoring this close, %d references still exists\n", vma_usage_tracker->references)); + return; + } + + /** @note args->context unused, initialized to 0. + * Instead, we use the memory_session from the cookie */ + + descriptor = (mali_memory_allocation *)vma_usage_tracker->cookie; + + args.cookie = (u32)descriptor; + args.mapping = descriptor->mapping; + args.size = descriptor->size; + + _mali_ukk_mem_munmap( &args ); + + /* vma_usage_tracker is free()d by _mali_osk_mem_mapregion_term(). + * In the case of the memory engine, it is called as the release function that has been registered with the engine*/ +} + + +void _mali_osk_mem_barrier( void ) +{ + mb(); +} + +void _mali_osk_write_mem_barrier( void ) +{ + wmb(); +} + +mali_io_address _mali_osk_mem_mapioregion( u32 phys, u32 size, const char *description ) +{ + return (mali_io_address)ioremap_nocache(phys, size); +} + +void _mali_osk_mem_unmapioregion( u32 phys, u32 size, mali_io_address virt ) +{ + iounmap((void*)virt); +} + +mali_io_address _mali_osk_mem_allocioregion( u32 *phys, u32 size ) +{ + void * virt; + MALI_DEBUG_ASSERT_POINTER( phys ); + MALI_DEBUG_ASSERT( 0 == (size & ~_MALI_OSK_CPU_PAGE_MASK) ); + MALI_DEBUG_ASSERT( 0 != size ); + + /* dma_alloc_* uses a limited region of address space. On most arch/marchs + * 2 to 14 MiB is available. This should be enough for the page tables, which + * currently is the only user of this function. */ + virt = dma_alloc_coherent(NULL, size, phys, GFP_KERNEL | GFP_DMA ); + + MALI_DEBUG_PRINT(3, ("Page table virt: 0x%x = dma_alloc_coherent(size:%d, phys:0x%x, )\n", virt, size, phys)); + + if ( NULL == virt ) + { + MALI_DEBUG_PRINT(5, ("allocioregion: Failed to allocate Pagetable memory, size=0x%.8X\n", size )); + return 0; + } + + MALI_DEBUG_ASSERT( 0 == (*phys & ~_MALI_OSK_CPU_PAGE_MASK) ); + + return (mali_io_address)virt; +} + +void _mali_osk_mem_freeioregion( u32 phys, u32 size, mali_io_address virt ) +{ + MALI_DEBUG_ASSERT_POINTER( (void*)virt ); + MALI_DEBUG_ASSERT( 0 != size ); + MALI_DEBUG_ASSERT( 0 == (phys & ( (1 << PAGE_SHIFT) - 1 )) ); + + dma_free_coherent(NULL, size, virt, phys); +} + +_mali_osk_errcode_t inline _mali_osk_mem_reqregion( u32 phys, u32 size, const char *description ) +{ + return ((NULL == request_mem_region(phys, size, description)) ? _MALI_OSK_ERR_NOMEM : _MALI_OSK_ERR_OK); +} + +void inline _mali_osk_mem_unreqregion( u32 phys, u32 size ) +{ + release_mem_region(phys, size); +} + +void inline _mali_osk_mem_iowrite32_relaxed( volatile mali_io_address addr, u32 offset, u32 val ) +{ + __raw_writel(cpu_to_le32(val),((u8*)addr) + offset); +} + +u32 inline _mali_osk_mem_ioread32( volatile mali_io_address addr, u32 offset ) +{ + return ioread32(((u8*)addr) + offset); +} + +void inline _mali_osk_mem_iowrite32( volatile mali_io_address addr, u32 offset, u32 val ) +{ + iowrite32(val, ((u8*)addr) + offset); +} + +void _mali_osk_cache_flushall( void ) +{ + /** @note Cached memory is not currently supported in this implementation */ +} + +void _mali_osk_cache_ensure_uncached_range_flushed( void *uncached_mapping, u32 offset, u32 size ) +{ + _mali_osk_write_mem_barrier(); +} + +_mali_osk_errcode_t _mali_osk_mem_mapregion_init( mali_memory_allocation * descriptor ) +{ + struct vm_area_struct *vma; + mali_vma_usage_tracker * vma_usage_tracker; + MappingInfo *mappingInfo; + + if (NULL == descriptor) return _MALI_OSK_ERR_FAULT; + + MALI_DEBUG_ASSERT( 0 != (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE) ); + + vma = (struct vm_area_struct*)descriptor->process_addr_mapping_info; + + if (NULL == vma ) return _MALI_OSK_ERR_FAULT; + + /* Re-write the process_addr_mapping_info */ + mappingInfo = _mali_osk_calloc( 1, sizeof(MappingInfo) ); + + if ( NULL == mappingInfo ) return _MALI_OSK_ERR_FAULT; + + vma_usage_tracker = _mali_osk_calloc( 1, sizeof(mali_vma_usage_tracker) ); + + if (NULL == vma_usage_tracker) + { + MALI_DEBUG_PRINT(2, ("Failed to allocate memory to track memory usage\n")); + _mali_osk_free( mappingInfo ); + return _MALI_OSK_ERR_FAULT; + } + + mappingInfo->vma = vma; + descriptor->process_addr_mapping_info = mappingInfo; + + /* Do the va range allocation - in this case, it was done earlier, so we copy in that information */ + descriptor->mapping = (void __user*)vma->vm_start; + /* list member is already NULL */ + + /* + set some bits which indicate that: + The memory is IO memory, meaning that no paging is to be performed and the memory should not be included in crash dumps + The memory is reserved, meaning that it's present and can never be paged out (see also previous entry) + */ + vma->vm_flags |= VM_IO; + vma->vm_flags |= VM_RESERVED; + vma->vm_flags |= VM_DONTCOPY; + + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + vma->vm_ops = &mali_kernel_vm_ops; /* Operations used on any memory system */ + + vma_usage_tracker->references = 1; /* set initial reference count to be 1 as vma_open won't be called for the first mmap call */ + vma_usage_tracker->cookie = (u32)descriptor; /* cookie for munmap */ + + vma->vm_private_data = vma_usage_tracker; + + return _MALI_OSK_ERR_OK; +} + +void _mali_osk_mem_mapregion_term( mali_memory_allocation * descriptor ) +{ + struct vm_area_struct* vma; + mali_vma_usage_tracker * vma_usage_tracker; + MappingInfo *mappingInfo; + + if (NULL == descriptor) return; + + MALI_DEBUG_ASSERT( 0 != (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE) ); + + mappingInfo = (MappingInfo *)descriptor->process_addr_mapping_info; + + MALI_DEBUG_ASSERT_POINTER( mappingInfo ); + + /* Linux does the right thing as part of munmap to remove the mapping + * All that remains is that we remove the vma_usage_tracker setup in init() */ + vma = mappingInfo->vma; + + MALI_DEBUG_ASSERT_POINTER( vma ); + + /* ASSERT that there are no allocations on the list. Unmap should've been + * called on all OS allocations. */ + MALI_DEBUG_ASSERT( NULL == mappingInfo->list ); + + vma_usage_tracker = vma->vm_private_data; + + /* We only get called if mem_mapregion_init succeeded */ + _mali_osk_free(vma_usage_tracker); + + _mali_osk_free( mappingInfo ); + return; +} + +_mali_osk_errcode_t _mali_osk_mem_mapregion_map( mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size ) +{ + struct vm_area_struct *vma; + MappingInfo *mappingInfo; + + if (NULL == descriptor) return _MALI_OSK_ERR_FAULT; + + MALI_DEBUG_ASSERT_POINTER( phys_addr ); + + MALI_DEBUG_ASSERT( 0 != (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE) ); + + MALI_DEBUG_ASSERT( 0 == (size & ~_MALI_OSK_CPU_PAGE_MASK) ); + + MALI_DEBUG_ASSERT( 0 == (offset & ~_MALI_OSK_CPU_PAGE_MASK)); + + if (NULL == descriptor->mapping) return _MALI_OSK_ERR_INVALID_ARGS; + + if (size > (descriptor->size - offset)) + { + MALI_DEBUG_PRINT(1,("_mali_osk_mem_mapregion_map: virtual memory area not large enough to map physical 0x%x size %x into area 0x%x at offset 0x%xr\n", + *phys_addr, size, descriptor->mapping, offset)); + return _MALI_OSK_ERR_FAULT; + } + + mappingInfo = (MappingInfo *)descriptor->process_addr_mapping_info; + + MALI_DEBUG_ASSERT_POINTER( mappingInfo ); + + vma = mappingInfo->vma; + + if (NULL == vma ) return _MALI_OSK_ERR_FAULT; + + MALI_DEBUG_PRINT(7, ("Process map: mapping 0x%08X to process address 0x%08lX length 0x%08X\n", *phys_addr, (long unsigned int)(descriptor->mapping + offset), size)); + + if ( MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC == *phys_addr ) + { + _mali_osk_errcode_t ret; + AllocationList *alloc_item; + u32 linux_phys_frame_num; + + alloc_item = _allocation_list_item_get(); + if (NULL == alloc_item) + { + MALI_DEBUG_PRINT(1, ("Failed to allocate list item\n")); + return _MALI_OSK_ERR_NOMEM; + } + + linux_phys_frame_num = alloc_item->physaddr >> PAGE_SHIFT; + + ret = ( remap_pfn_range( vma, ((u32)descriptor->mapping) + offset, linux_phys_frame_num, size, vma->vm_page_prot) ) ? _MALI_OSK_ERR_FAULT : _MALI_OSK_ERR_OK; + + if ( ret != _MALI_OSK_ERR_OK) + { + MALI_PRINT_ERROR(("%s %d could not remap_pfn_range()\n", __FUNCTION__, __LINE__)); + _allocation_list_item_release(alloc_item); + return ret; + } + + /* Put our alloc_item into the list of allocations on success */ + if (NULL == mappingInfo->list) + { + mappingInfo->list = alloc_item; + } + else + { + mappingInfo->tail->next = alloc_item; + } + + mappingInfo->tail = alloc_item; + alloc_item->next = NULL; + alloc_item->offset = offset; + + /* Write out new physical address on success */ + *phys_addr = alloc_item->physaddr; + + return ret; + } + + /* Otherwise, Use the supplied physical address */ + + /* ASSERT that supplied phys_addr is page aligned */ + MALI_DEBUG_ASSERT( 0 == ((*phys_addr) & ~_MALI_OSK_CPU_PAGE_MASK) ); + + return ( remap_pfn_range( vma, ((u32)descriptor->mapping) + offset, *phys_addr >> PAGE_SHIFT, size, vma->vm_page_prot) ) ? _MALI_OSK_ERR_FAULT : _MALI_OSK_ERR_OK; + +} + +void _mali_osk_mem_mapregion_unmap( mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t flags ) +{ + MappingInfo *mappingInfo; + + if (NULL == descriptor) return; + + MALI_DEBUG_ASSERT( 0 != (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE) ); + + MALI_DEBUG_ASSERT( 0 == (size & ~_MALI_OSK_CPU_PAGE_MASK) ); + + MALI_DEBUG_ASSERT( 0 == (offset & ~_MALI_OSK_CPU_PAGE_MASK) ); + + if (NULL == descriptor->mapping) return; + + if (size > (descriptor->size - offset)) + { + MALI_DEBUG_PRINT(1,("_mali_osk_mem_mapregion_unmap: virtual memory area not large enough to unmap size %x from area 0x%x at offset 0x%x\n", + size, descriptor->mapping, offset)); + return; + } + mappingInfo = (MappingInfo *)descriptor->process_addr_mapping_info; + + MALI_DEBUG_ASSERT_POINTER( mappingInfo ); + + if ( 0 != (flags & _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR) ) + { + /* This physical RAM was allocated in _mali_osk_mem_mapregion_map and + * so needs to be unmapped + */ + while (size) + { + /* First find the allocation in the list of allocations */ + AllocationList *alloc = mappingInfo->list; + AllocationList **prev = &(mappingInfo->list); + + while (NULL != alloc && alloc->offset != offset) + { + prev = &(alloc->next); + alloc = alloc->next; + } + if (alloc == NULL) { + MALI_DEBUG_PRINT(1, ("Unmapping memory that isn't mapped\n")); + size -= _MALI_OSK_CPU_PAGE_SIZE; + offset += _MALI_OSK_CPU_PAGE_SIZE; + continue; + } + + *prev = alloc->next; + _allocation_list_item_release(alloc); + + /* Move onto the next allocation */ + size -= _MALI_OSK_CPU_PAGE_SIZE; + offset += _MALI_OSK_CPU_PAGE_SIZE; + } + } + + /* Linux does the right thing as part of munmap to remove the mapping */ + + return; +} diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_mali.c b/drivers/media/video/samsung/mali/linux/mali_osk_mali.c new file mode 100644 index 0000000..06cb215 --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_osk_mali.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_mali.c + * Implementation of the OS abstraction layer which is specific for the Mali kernel device driver + */ +#include +#include +#include + +#include "mali_kernel_common.h" /* MALI_xxx macros */ +#include "mali_osk.h" /* kernel side OS functions */ +#include "mali_uk_types.h" +#include "arch/config.h" /* contains the configuration of the arch we are compiling for */ + +_mali_osk_errcode_t _mali_osk_resources_init( _mali_osk_resource_t **arch_config, u32 *num_resources ) +{ + *num_resources = sizeof(arch_configuration) / sizeof(arch_configuration[0]); + *arch_config = arch_configuration; + return _MALI_OSK_ERR_OK; +} + +void _mali_osk_resources_term( _mali_osk_resource_t **arch_config, u32 num_resources ) +{ + /* Nothing to do */ +} diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_math.c b/drivers/media/video/samsung/mali/linux/mali_osk_math.c new file mode 100644 index 0000000..bb25e7d --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_osk_math.c @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_math.c + * Implementation of the OS abstraction layer for the kernel device driver + */ + +#include "mali_osk.h" +#include + +u32 inline _mali_osk_clz( u32 input ) +{ + return 32-fls(input); +} diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_memory.c b/drivers/media/video/samsung/mali/linux/mali_osk_memory.c new file mode 100644 index 0000000..5354e85 --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_osk_memory.c @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_memory.c + * Implementation of the OS abstraction layer for the kernel device driver + */ + +#include "mali_osk.h" +#include +#include + +void inline *_mali_osk_calloc( u32 n, u32 size ) +{ + return kcalloc(n, size, GFP_KERNEL); +} + +void inline *_mali_osk_malloc( u32 size ) +{ + return kmalloc(size, GFP_KERNEL); +} + +void inline _mali_osk_free( void *ptr ) +{ + kfree(ptr); +} + +void inline *_mali_osk_valloc( u32 size ) +{ + return vmalloc(size); +} + +void inline _mali_osk_vfree( void *ptr ) +{ + vfree(ptr); +} + +void inline *_mali_osk_memcpy( void *dst, const void *src, u32 len ) +{ + return memcpy(dst, src, len); +} + +void inline *_mali_osk_memset( void *s, u32 c, u32 n ) +{ + return memset(s, c, n); +} + +mali_bool _mali_osk_mem_check_allocated( u32 max_allocated ) +{ + /* No need to prevent an out-of-memory dialogue appearing on Linux, + * so we always return MALI_TRUE. + */ + return MALI_TRUE; +} diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_misc.c b/drivers/media/video/samsung/mali/linux/mali_osk_misc.c new file mode 100644 index 0000000..ad486db --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_osk_misc.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_misc.c + * Implementation of the OS abstraction layer for the kernel device driver + */ +#include +#include +#include +#include +#include +#include "mali_osk.h" + +void _mali_osk_dbgmsg( const char *fmt, ... ) +{ + va_list args; + va_start(args, fmt); + vprintk(fmt, args); + va_end(args); +} + +u32 _mali_osk_snprintf( char *buf, u32 size, const char *fmt, ... ) +{ + int res; + va_list args; + va_start(args, fmt); + + res = vscnprintf(buf, (size_t)size, fmt, args); + + va_end(args); + return res; +} + +void _mali_osk_abort(void) +{ + /* make a simple fault by dereferencing a NULL pointer */ + dump_stack(); + *(int *)0 = 0; +} + +void _mali_osk_break(void) +{ + _mali_osk_abort(); +} + +u32 _mali_osk_get_pid(void) +{ + /* Thread group ID is the process ID on Linux */ + return (u32)current->tgid; +} + +u32 _mali_osk_get_tid(void) +{ + /* pid is actually identifying the thread on Linux */ + return (u32)current->pid; +} diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_notification.c b/drivers/media/video/samsung/mali/linux/mali_osk_notification.c new file mode 100644 index 0000000..c14c0d5 --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_osk_notification.c @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_notification.c + * Implementation of the OS abstraction layer for the kernel device driver + */ + +#include "mali_osk.h" +#include "mali_kernel_common.h" + +/* needed to detect kernel version specific code */ +#include + +#include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) +#include +#else /* pre 2.6.26 the file was in the arch specific location */ +#include +#endif + +/** + * Declaration of the notification queue object type + * Contains a linked list of notification pending delivery to user space. + * It also contains a wait queue of exclusive waiters blocked in the ioctl + * When a new notification is posted a single thread is resumed. + */ +struct _mali_osk_notification_queue_t_struct +{ + struct semaphore mutex; /**< Mutex protecting the list */ + wait_queue_head_t receive_queue; /**< Threads waiting for new entries to the queue */ + struct list_head head; /**< List of notifications waiting to be picked up */ +}; + +typedef struct _mali_osk_notification_wrapper_t_struct +{ + struct list_head list; /**< Internal linked list variable */ + _mali_osk_notification_t data; /**< Notification data */ +} _mali_osk_notification_wrapper_t; + +_mali_osk_notification_queue_t *_mali_osk_notification_queue_init( void ) +{ + _mali_osk_notification_queue_t * result; + + result = (_mali_osk_notification_queue_t *)kmalloc(sizeof(_mali_osk_notification_queue_t), GFP_KERNEL); + if (NULL == result) return NULL; + + sema_init(&result->mutex, 1); + init_waitqueue_head(&result->receive_queue); + INIT_LIST_HEAD(&result->head); + + return result; +} + +_mali_osk_notification_t *_mali_osk_notification_create( u32 type, u32 size ) +{ + /* OPT Recycling of notification objects */ + _mali_osk_notification_wrapper_t *notification; + + notification = (_mali_osk_notification_wrapper_t *)kmalloc( sizeof(_mali_osk_notification_wrapper_t) + size, + GFP_KERNEL | __GFP_HIGH | __GFP_REPEAT); + if (NULL == notification) + { + MALI_DEBUG_PRINT(1, ("Failed to create a notification object\n")); + return NULL; + } + + /* Init the list */ + INIT_LIST_HEAD(¬ification->list); + + if (0 != size) + { + notification->data.result_buffer = ((u8*)notification) + sizeof(_mali_osk_notification_wrapper_t); + } + else + { + notification->data.result_buffer = NULL; + } + + /* set up the non-allocating fields */ + notification->data.notification_type = type; + notification->data.result_buffer_size = size; + + /* all ok */ + return &(notification->data); +} + +void _mali_osk_notification_delete( _mali_osk_notification_t *object ) +{ + _mali_osk_notification_wrapper_t *notification; + MALI_DEBUG_ASSERT_POINTER( object ); + + notification = container_of( object, _mali_osk_notification_wrapper_t, data ); + + /* Free the container */ + kfree(notification); +} + +void _mali_osk_notification_queue_term( _mali_osk_notification_queue_t *queue ) +{ + MALI_DEBUG_ASSERT_POINTER( queue ); + + /* not much to do, just free the memory */ + kfree(queue); +} + +void _mali_osk_notification_queue_send( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t *object ) +{ + _mali_osk_notification_wrapper_t *notification; + MALI_DEBUG_ASSERT_POINTER( queue ); + MALI_DEBUG_ASSERT_POINTER( object ); + + notification = container_of( object, _mali_osk_notification_wrapper_t, data ); + + /* lock queue access */ + down(&queue->mutex); + /* add to list */ + list_add_tail(¬ification->list, &queue->head); + /* unlock the queue */ + up(&queue->mutex); + + /* and wake up one possible exclusive waiter */ + wake_up(&queue->receive_queue); +} + +static int _mali_notification_queue_is_empty( _mali_osk_notification_queue_t *queue ) +{ + int ret; + + down(&queue->mutex); + ret = list_empty(&queue->head); + up(&queue->mutex); + return ret; +} + +#if MALI_STATE_TRACKING +mali_bool _mali_osk_notification_queue_is_empty( _mali_osk_notification_queue_t *queue ) +{ + return _mali_notification_queue_is_empty(queue) ? MALI_TRUE : MALI_FALSE; +} +#endif + +_mali_osk_errcode_t _mali_osk_notification_queue_dequeue( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t **result ) +{ + _mali_osk_errcode_t ret = _MALI_OSK_ERR_ITEM_NOT_FOUND; + _mali_osk_notification_wrapper_t *wrapper_object; + + down(&queue->mutex); + + if (!list_empty(&queue->head)) + { + wrapper_object = list_entry(queue->head.next, _mali_osk_notification_wrapper_t, list); + *result = &(wrapper_object->data); + list_del_init(&wrapper_object->list); + ret = _MALI_OSK_ERR_OK; + } + + up(&queue->mutex); + + return ret; +} + +_mali_osk_errcode_t _mali_osk_notification_queue_receive( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t **result ) +{ + /* check input */ + MALI_DEBUG_ASSERT_POINTER( queue ); + MALI_DEBUG_ASSERT_POINTER( result ); + + /* default result */ + *result = NULL; + + while (_MALI_OSK_ERR_OK != _mali_osk_notification_queue_dequeue(queue, result)) + { + if (wait_event_interruptible(queue->receive_queue, !_mali_notification_queue_is_empty(queue))) + { + return _MALI_OSK_ERR_RESTARTSYSCALL; + } + } + + return _MALI_OSK_ERR_OK; /* all ok */ +} diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_pm.c b/drivers/media/video/samsung/mali/linux/mali_osk_pm.c new file mode 100644 index 0000000..491a603 --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_osk_pm.c @@ -0,0 +1,83 @@ +/** + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_pm.c + * Implementation of the callback functions from common power management + */ + +#include + +#ifdef CONFIG_PM_RUNTIME +#include +#endif /* CONFIG_PM_RUNTIME */ +#include +#include "mali_platform.h" +#include "mali_osk.h" +#include "mali_uk_types.h" +#include "mali_kernel_common.h" +#include "mali_kernel_license.h" +#include "mali_linux_pm.h" +#include "mali_kernel_license.h" + +#if ! MALI_LICENSE_IS_GPL +#undef CONFIG_PM_RUNTIME +#endif + +extern struct platform_device mali_gpu_device; + +#ifdef CONFIG_PM_RUNTIME +static mali_bool have_runtime_reference = MALI_FALSE; +#endif + +void _mali_osk_pm_dev_enable(void) +{ +#ifdef CONFIG_PM_RUNTIME + pm_runtime_enable(&(mali_gpu_device.dev)); +#endif +} + +/* NB: Function is not thread safe */ +_mali_osk_errcode_t _mali_osk_pm_dev_idle(void) +{ +#ifdef CONFIG_PM_RUNTIME + if (MALI_TRUE == have_runtime_reference) + { + int err; + err = pm_runtime_put_sync(&(mali_gpu_device.dev)); + if (0 > err) + { + MALI_PRINT_ERROR(("OSK PM: pm_runtime_put_sync() returned error code %d\n", err)); + return _MALI_OSK_ERR_FAULT; + } + have_runtime_reference = MALI_FALSE; + } +#endif + return _MALI_OSK_ERR_OK; +} + +/* NB: Function is not thread safe */ +_mali_osk_errcode_t _mali_osk_pm_dev_activate(void) +{ +#ifdef CONFIG_PM_RUNTIME + if (MALI_TRUE != have_runtime_reference) + { + int err; + err = pm_runtime_get_sync(&(mali_gpu_device.dev)); + if (0 > err) + { + MALI_PRINT_ERROR(("OSK PM: pm_runtime_get_sync() returned error code %d\n", err)); + return _MALI_OSK_ERR_FAULT; + } + have_runtime_reference = MALI_TRUE; + } +#endif + return _MALI_OSK_ERR_OK; +} diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_profiling_gator.c b/drivers/media/video/samsung/mali/linux/mali_osk_profiling_gator.c new file mode 100644 index 0000000..95bee53 --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_osk_profiling_gator.c @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include "mali_kernel_common.h" +#include "mali_osk.h" +#include "mali_ukk.h" +#include "mali_uk_types.h" +#include "mali_osk_profiling.h" +#include "mali_linux_trace.h" +#include "mali_gp.h" +#include "mali_pp.h" +#include "mali_l2_cache.h" +#include "mali_user_settings_db.h" + +_mali_osk_errcode_t _mali_osk_profiling_init(mali_bool auto_start) +{ + if (MALI_TRUE == auto_start) + { + mali_set_user_setting(_MALI_UK_USER_SETTING_SW_EVENTS_ENABLE, MALI_TRUE); + } + + return _MALI_OSK_ERR_OK; +} + +void _mali_osk_profiling_term(void) +{ + /* Nothing to do */ +} + +_mali_osk_errcode_t _mali_osk_profiling_start(u32 * limit) +{ + /* Nothing to do */ + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t _mali_osk_profiling_stop(u32 *count) +{ + /* Nothing to do */ + return _MALI_OSK_ERR_OK; +} + +u32 _mali_osk_profiling_get_count(void) +{ + return 0; +} + +_mali_osk_errcode_t _mali_osk_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5]) +{ + /* Nothing to do */ + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t _mali_osk_profiling_clear(void) +{ + /* Nothing to do */ + return _MALI_OSK_ERR_OK; +} + +mali_bool _mali_osk_profiling_is_recording(void) +{ + return MALI_FALSE; +} + +mali_bool _mali_osk_profiling_have_recording(void) +{ + return MALI_FALSE; +} + +void _mali_osk_profiling_report_sw_counters(u32 *counters) +{ + trace_mali_sw_counters(_mali_osk_get_pid(), _mali_osk_get_tid(), NULL, counters); +} + + +_mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args) +{ + return _mali_osk_profiling_start(&args->limit); +} + +_mali_osk_errcode_t _mali_ukk_profiling_add_event(_mali_uk_profiling_add_event_s *args) +{ + /* Always add process and thread identificator in the first two data elements for events from user space */ + _mali_osk_profiling_add_event(args->event_id, _mali_osk_get_pid(), _mali_osk_get_tid(), args->data[2], args->data[3], args->data[4]); + + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t _mali_ukk_profiling_stop(_mali_uk_profiling_stop_s *args) +{ + return _mali_osk_profiling_stop(&args->count); +} + +_mali_osk_errcode_t _mali_ukk_profiling_get_event(_mali_uk_profiling_get_event_s *args) +{ + return _mali_osk_profiling_get_event(args->index, &args->timestamp, &args->event_id, args->data); +} + +_mali_osk_errcode_t _mali_ukk_profiling_clear(_mali_uk_profiling_clear_s *args) +{ + return _mali_osk_profiling_clear(); +} + +_mali_osk_errcode_t _mali_ukk_sw_counters_report(_mali_uk_sw_counters_report_s *args) +{ + _mali_osk_profiling_report_sw_counters(args->counters); + return _MALI_OSK_ERR_OK; +} + +/** + * Called by gator.ko to set HW counters + * + * @param counter_id The counter ID. + * @param event_id Event ID that the counter should count (HW counter value from TRM). + * + * @return 1 on success, 0 on failure. + */ +int _mali_profiling_set_event(u32 counter_id, s32 event_id) +{ + + if (COUNTER_VP_C0 == counter_id) + { + struct mali_gp_core* gp_core = mali_gp_get_global_gp_core(); + if (NULL != gp_core) + { + if (MALI_TRUE == mali_gp_core_set_counter_src0(gp_core, event_id)) + { + return 1; + } + } + } + if (COUNTER_VP_C1 == counter_id) + { + struct mali_gp_core* gp_core = mali_gp_get_global_gp_core(); + if (NULL != gp_core) + { + if (MALI_TRUE == mali_gp_core_set_counter_src1(gp_core, event_id)) + { + return 1; + } + } + } + if (COUNTER_FP0_C0 <= counter_id && COUNTER_FP3_C1 >= counter_id) + { + u32 core_id = (counter_id - COUNTER_FP0_C0) >> 1; + struct mali_pp_core* pp_core = mali_pp_get_global_pp_core(core_id); + if (NULL != pp_core) + { + u32 counter_src = (counter_id - COUNTER_FP0_C0) & 1; + if (0 == counter_src) + { + if (MALI_TRUE == mali_pp_core_set_counter_src0(pp_core, event_id)) + { + return 1; + } + } + else + { + if (MALI_TRUE == mali_pp_core_set_counter_src1(pp_core, event_id)) + { + return 1; + } + } + } + } + if (COUNTER_L2_C0 <= counter_id && COUNTER_L2_C1 >= counter_id) + { + u32 core_id = (counter_id - COUNTER_L2_C0) >> 1; + struct mali_l2_cache_core* l2_cache_core = mali_l2_cache_core_get_glob_l2_core(core_id); + if (NULL != l2_cache_core) + { + u32 counter_src = (counter_id - COUNTER_L2_C0) & 1; + if (0 == counter_src) + { + if (MALI_TRUE == mali_l2_cache_core_set_counter_src0(l2_cache_core, event_id)) + { + return 1; + } + } + else + { + if (MALI_TRUE == mali_l2_cache_core_set_counter_src1(l2_cache_core, event_id)) + { + return 1; + } + } + } + } + + return 0; +} + +/** + * Called by gator.ko to retrieve the L2 cache counter values for the first L2 cache. + * The L2 cache counters are unique in that they are polled by gator, rather than being + * transmitted via the tracepoint mechanism. + * + * @param src0 First L2 cache counter ID. + * @param val0 First L2 cache counter value. + * @param src1 Second L2 cache counter ID. + * @param val1 Second L2 cache counter value. + */ +void _mali_profiling_get_counters(u32 *src0, u32 *val0, u32 *src1, u32 *val1) +{ + struct mali_l2_cache_core *l2_cache = mali_l2_cache_core_get_glob_l2_core(0); + if (NULL != l2_cache) + { + if (MALI_TRUE == mali_l2_cache_lock_power_state(l2_cache)) + { + /* It is now safe to access the L2 cache core in order to retrieve the counters */ + mali_l2_cache_core_get_counter_values(l2_cache, src0, val0, src1, val1); + } + mali_l2_cache_unlock_power_state(l2_cache); + } +} + +/* + * List of possible actions to be controlled by Streamline. + * The following numbers are used by gator to control the frame buffer dumping and s/w counter reporting. + * We cannot use the enums in mali_uk_types.h because they are unknown inside gator. + */ +#define FBDUMP_CONTROL_ENABLE (1) +#define FBDUMP_CONTROL_RATE (2) +#define SW_COUNTER_ENABLE (3) +#define FBDUMP_CONTROL_RESIZE_FACTOR (4) + +/** + * Called by gator to control the production of profiling information at runtime. + */ +void _mali_profiling_control(u32 action, u32 value) +{ + switch(action) + { + case FBDUMP_CONTROL_ENABLE: + mali_set_user_setting(_MALI_UK_USER_SETTING_COLORBUFFER_CAPTURE_ENABLED, (value == 0 ? MALI_FALSE : MALI_TRUE)); + break; + case FBDUMP_CONTROL_RATE: + mali_set_user_setting(_MALI_UK_USER_SETTING_BUFFER_CAPTURE_N_FRAMES, value); + break; + case SW_COUNTER_ENABLE: + mali_set_user_setting(_MALI_UK_USER_SETTING_SW_COUNTER_ENABLED, value); + break; + case FBDUMP_CONTROL_RESIZE_FACTOR: + mali_set_user_setting(_MALI_UK_USER_SETTING_BUFFER_CAPTURE_RESIZE_FACTOR, value); + break; + default: + break; /* Ignore unimplemented actions */ + } +} + +EXPORT_SYMBOL(_mali_profiling_set_event); +EXPORT_SYMBOL(_mali_profiling_get_counters); +EXPORT_SYMBOL(_mali_profiling_control); diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_profiling_internal.c b/drivers/media/video/samsung/mali/linux/mali_osk_profiling_internal.c new file mode 100644 index 0000000..2df935d --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_osk_profiling_internal.c @@ -0,0 +1,324 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_kernel_common.h" +#include "mali_osk.h" +#include "mali_osk_mali.h" +#include "mali_ukk.h" +#include "mali_timestamp.h" +#include "mali_osk_profiling.h" +#include "mali_user_settings_db.h" + +typedef struct mali_profiling_entry +{ + u64 timestamp; + u32 event_id; + u32 data[5]; +} mali_profiling_entry; + + +typedef enum mali_profiling_state +{ + MALI_PROFILING_STATE_UNINITIALIZED, + MALI_PROFILING_STATE_IDLE, + MALI_PROFILING_STATE_RUNNING, + MALI_PROFILING_STATE_RETURN, +} mali_profiling_state; + +static _mali_osk_lock_t *lock = NULL; +static mali_profiling_state prof_state = MALI_PROFILING_STATE_UNINITIALIZED; +static mali_profiling_entry* profile_entries = NULL; +static u32 profile_entry_count = 0; +static _mali_osk_atomic_t profile_insert_index; +static _mali_osk_atomic_t profile_entries_written; + +_mali_osk_errcode_t _mali_osk_profiling_init(mali_bool auto_start) +{ + profile_entries = NULL; + profile_entry_count = 0; + _mali_osk_atomic_init(&profile_insert_index, 0); + _mali_osk_atomic_init(&profile_entries_written, 0); + + lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_PROFILING); + if (NULL == lock) + { + return _MALI_OSK_ERR_FAULT; + } + + prof_state = MALI_PROFILING_STATE_IDLE; + + if (MALI_TRUE == auto_start) + { + u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* Use maximum buffer size */ + + mali_set_user_setting(_MALI_UK_USER_SETTING_SW_EVENTS_ENABLE, MALI_TRUE); + if (_MALI_OSK_ERR_OK != _mali_osk_profiling_start(&limit)) + { + return _MALI_OSK_ERR_FAULT; + } + } + + return _MALI_OSK_ERR_OK; +} + +void _mali_osk_profiling_term(void) +{ + prof_state = MALI_PROFILING_STATE_UNINITIALIZED; + + /* wait for all elements to be completely inserted into array */ + while (_mali_osk_atomic_read(&profile_insert_index) != _mali_osk_atomic_read(&profile_entries_written)) + { + /* do nothing */; + } + + if (NULL != profile_entries) + { + _mali_osk_vfree(profile_entries); + profile_entries = NULL; + } + + if (NULL != lock) + { + _mali_osk_lock_term(lock); + lock = NULL; + } +} + +inline _mali_osk_errcode_t _mali_osk_profiling_start(u32 * limit) +{ + _mali_osk_errcode_t ret; + + mali_profiling_entry *new_profile_entries = _mali_osk_valloc(*limit * sizeof(mali_profiling_entry)); + + if(NULL == new_profile_entries) + { + return _MALI_OSK_ERR_NOMEM; + } + + _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); + + if (prof_state != MALI_PROFILING_STATE_IDLE) + { + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + _mali_osk_vfree(new_profile_entries); + return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */ + } + + if (*limit > MALI_PROFILING_MAX_BUFFER_ENTRIES) + { + *limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; + } + + profile_entries = new_profile_entries; + profile_entry_count = *limit; + + ret = _mali_timestamp_reset(); + + if (ret == _MALI_OSK_ERR_OK) + { + prof_state = MALI_PROFILING_STATE_RUNNING; + } + else + { + _mali_osk_vfree(profile_entries); + profile_entries = NULL; + } + + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + return ret; +} + +inline void _mali_osk_profiling_add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4) +{ + if (prof_state == MALI_PROFILING_STATE_RUNNING) + { + u32 cur_index = (_mali_osk_atomic_inc_return(&profile_insert_index) - 1) % profile_entry_count; + + profile_entries[cur_index].timestamp = _mali_timestamp_get(); + profile_entries[cur_index].event_id = event_id; + profile_entries[cur_index].data[0] = data0; + profile_entries[cur_index].data[1] = data1; + profile_entries[cur_index].data[2] = data2; + profile_entries[cur_index].data[3] = data3; + profile_entries[cur_index].data[4] = data4; + + /* If event is "leave API function", add current memory usage to the event + * as data point 4. This is used in timeline profiling to indicate how + * much memory was used when leaving a function. */ + if (event_id == (MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_SINGLE_SW_LEAVE_API_FUNC)) + { + profile_entries[cur_index].data[4] = _mali_ukk_report_memory_usage(); + } + + _mali_osk_atomic_inc(&profile_entries_written); + } +} + +inline void _mali_osk_profiling_report_hw_counter(u32 counter_id, u32 value) +{ + /* Not implemented */ +} + +void _mali_osk_profiling_report_sw_counters(u32 *counters) +{ + /* Not implemented */ +} + +inline _mali_osk_errcode_t _mali_osk_profiling_stop(u32 * count) +{ + _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); + + if (prof_state != MALI_PROFILING_STATE_RUNNING) + { + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */ + } + + /* go into return state (user to retreive events), no more events will be added after this */ + prof_state = MALI_PROFILING_STATE_RETURN; + + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + + /* wait for all elements to be completely inserted into array */ + while (_mali_osk_atomic_read(&profile_insert_index) != _mali_osk_atomic_read(&profile_entries_written)) + { + /* do nothing */; + } + + *count = _mali_osk_atomic_read(&profile_insert_index); + if(*count>profile_entry_count) *count=profile_entry_count; + + return _MALI_OSK_ERR_OK; +} + +inline u32 _mali_osk_profiling_get_count(void) +{ + u32 retval = 0; + + _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); + if (prof_state == MALI_PROFILING_STATE_RETURN) + { + retval = _mali_osk_atomic_read(&profile_entries_written); + if(retval>profile_entry_count) retval = profile_entry_count; + } + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + + return retval; +} + +inline _mali_osk_errcode_t _mali_osk_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5]) +{ + _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); + + if(index=profile_entry_count) + { + idx = (index + _mali_osk_atomic_read(&profile_insert_index)) % profile_entry_count; + } + + if (prof_state != MALI_PROFILING_STATE_RETURN) + { + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */ + } + + if (idx >= _mali_osk_atomic_read(&profile_entries_written)) + { + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + return _MALI_OSK_ERR_FAULT; + } + + *timestamp = profile_entries[idx].timestamp; + *event_id = profile_entries[idx].event_id; + data[0] = profile_entries[idx].data[0]; + data[1] = profile_entries[idx].data[1]; + data[2] = profile_entries[idx].data[2]; + data[3] = profile_entries[idx].data[3]; + data[4] = profile_entries[idx].data[4]; + } + else + { + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + return _MALI_OSK_ERR_FAULT; + } + + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + return _MALI_OSK_ERR_OK; +} + +inline _mali_osk_errcode_t _mali_osk_profiling_clear(void) +{ + _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); + + if (prof_state != MALI_PROFILING_STATE_RETURN) + { + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */ + } + + prof_state = MALI_PROFILING_STATE_IDLE; + profile_entry_count = 0; + _mali_osk_atomic_init(&profile_insert_index, 0); + _mali_osk_atomic_init(&profile_entries_written, 0); + if (NULL != profile_entries) + { + _mali_osk_vfree(profile_entries); + profile_entries = NULL; + } + + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + return _MALI_OSK_ERR_OK; +} + +mali_bool _mali_osk_profiling_is_recording(void) +{ + return prof_state == MALI_PROFILING_STATE_RUNNING ? MALI_TRUE : MALI_FALSE; +} + +mali_bool _mali_osk_profiling_have_recording(void) +{ + return prof_state == MALI_PROFILING_STATE_RETURN ? MALI_TRUE : MALI_FALSE; +} + +_mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args) +{ + return _mali_osk_profiling_start(&args->limit); +} + +_mali_osk_errcode_t _mali_ukk_profiling_add_event(_mali_uk_profiling_add_event_s *args) +{ + /* Always add process and thread identificator in the first two data elements for events from user space */ + _mali_osk_profiling_add_event(args->event_id, _mali_osk_get_pid(), _mali_osk_get_tid(), args->data[2], args->data[3], args->data[4]); + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t _mali_ukk_profiling_stop(_mali_uk_profiling_stop_s *args) +{ + return _mali_osk_profiling_stop(&args->count); +} + +_mali_osk_errcode_t _mali_ukk_profiling_get_event(_mali_uk_profiling_get_event_s *args) +{ + return _mali_osk_profiling_get_event(args->index, &args->timestamp, &args->event_id, args->data); +} + +_mali_osk_errcode_t _mali_ukk_profiling_clear(_mali_uk_profiling_clear_s *args) +{ + return _mali_osk_profiling_clear(); +} + +_mali_osk_errcode_t _mali_ukk_sw_counters_report(_mali_uk_sw_counters_report_s *args) +{ + _mali_osk_profiling_report_sw_counters(args->counters); + return _MALI_OSK_ERR_OK; +} + diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_specific.h b/drivers/media/video/samsung/mali/linux/mali_osk_specific.h new file mode 100644 index 0000000..83ee906 --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_osk_specific.h @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_specific.h + * Defines per-OS Kernel level specifics, such as unusual workarounds for + * certain OSs. + */ + +#ifndef __MALI_OSK_SPECIFIC_H__ +#define __MALI_OSK_SPECIFIC_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define MALI_STATIC_INLINE static inline +#define MALI_NON_STATIC_INLINE inline + +#ifdef __cplusplus +} +#endif + +/** The list of events supported by the Mali DDK. */ +typedef enum +{ + /* Vertex processor activity */ + ACTIVITY_VP = 0, + + /* Fragment processor activity */ + ACTIVITY_FP0, + ACTIVITY_FP1, + ACTIVITY_FP2, + ACTIVITY_FP3, + + /* L2 cache counters */ + COUNTER_L2_C0, + COUNTER_L2_C1, + + /* Vertex processor counters */ + COUNTER_VP_C0, + COUNTER_VP_C1, + + /* Fragment processor counters */ + COUNTER_FP0_C0, + COUNTER_FP0_C1, + COUNTER_FP1_C0, + COUNTER_FP1_C1, + COUNTER_FP2_C0, + COUNTER_FP2_C1, + COUNTER_FP3_C0, + COUNTER_FP3_C1, + + /* + * If more hardware counters are added, the _mali_osk_hw_counter_table + * below should also be updated. + */ + + /* EGL software counters */ + COUNTER_EGL_BLIT_TIME, + + /* GLES software counters */ + COUNTER_GLES_DRAW_ELEMENTS_CALLS, + COUNTER_GLES_DRAW_ELEMENTS_NUM_INDICES, + COUNTER_GLES_DRAW_ELEMENTS_NUM_TRANSFORMED, + COUNTER_GLES_DRAW_ARRAYS_CALLS, + COUNTER_GLES_DRAW_ARRAYS_NUM_TRANSFORMED, + COUNTER_GLES_DRAW_POINTS, + COUNTER_GLES_DRAW_LINES, + COUNTER_GLES_DRAW_LINE_LOOP, + COUNTER_GLES_DRAW_LINE_STRIP, + COUNTER_GLES_DRAW_TRIANGLES, + COUNTER_GLES_DRAW_TRIANGLE_STRIP, + COUNTER_GLES_DRAW_TRIANGLE_FAN, + COUNTER_GLES_NON_VBO_DATA_COPY_TIME, + COUNTER_GLES_UNIFORM_BYTES_COPIED_TO_MALI, + COUNTER_GLES_UPLOAD_TEXTURE_TIME, + COUNTER_GLES_UPLOAD_VBO_TIME, + COUNTER_GLES_NUM_FLUSHES, + COUNTER_GLES_NUM_VSHADERS_GENERATED, + COUNTER_GLES_NUM_FSHADERS_GENERATED, + COUNTER_GLES_VSHADER_GEN_TIME, + COUNTER_GLES_FSHADER_GEN_TIME, + COUNTER_GLES_INPUT_TRIANGLES, + COUNTER_GLES_VXCACHE_HIT, + COUNTER_GLES_VXCACHE_MISS, + COUNTER_GLES_VXCACHE_COLLISION, + COUNTER_GLES_CULLED_TRIANGLES, + COUNTER_GLES_CULLED_LINES, + COUNTER_GLES_BACKFACE_TRIANGLES, + COUNTER_GLES_GBCLIP_TRIANGLES, + COUNTER_GLES_GBCLIP_LINES, + COUNTER_GLES_TRIANGLES_DRAWN, + COUNTER_GLES_DRAWCALL_TIME, + COUNTER_GLES_TRIANGLES_COUNT, + COUNTER_GLES_INDEPENDENT_TRIANGLES_COUNT, + COUNTER_GLES_STRIP_TRIANGLES_COUNT, + COUNTER_GLES_FAN_TRIANGLES_COUNT, + COUNTER_GLES_LINES_COUNT, + COUNTER_GLES_INDEPENDENT_LINES_COUNT, + COUNTER_GLES_STRIP_LINES_COUNT, + COUNTER_GLES_LOOP_LINES_COUNT, + + /* Framebuffer capture pseudo-counter */ + COUNTER_FILMSTRIP, + + NUMBER_OF_EVENTS +} _mali_osk_counter_id; + +#define FIRST_ACTIVITY_EVENT ACTIVITY_VP +#define LAST_ACTIVITY_EVENT ACTIVITY_FP3 + +#define FIRST_HW_COUNTER COUNTER_L2_C0 +#define LAST_HW_COUNTER COUNTER_FP3_C1 + +#define FIRST_SW_COUNTER COUNTER_EGL_BLIT_TIME +#define LAST_SW_COUNTER COUNTER_GLES_LOOP_LINES_COUNT + +#define FIRST_SPECIAL_COUNTER COUNTER_FILMSTRIP +#define LAST_SPECIAL_COUNTER COUNTER_FILMSTRIP + +#endif /* __MALI_OSK_SPECIFIC_H__ */ diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_time.c b/drivers/media/video/samsung/mali/linux/mali_osk_time.c new file mode 100644 index 0000000..b399b87 --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_osk_time.c @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_time.c + * Implementation of the OS abstraction layer for the kernel device driver + */ + +#include "mali_osk.h" +#include +#include +#include + +int _mali_osk_time_after( u32 ticka, u32 tickb ) +{ + return time_after((unsigned long)ticka, (unsigned long)tickb); +} + +u32 _mali_osk_time_mstoticks( u32 ms ) +{ + return msecs_to_jiffies(ms); +} + +u32 _mali_osk_time_tickstoms( u32 ticks ) +{ + return jiffies_to_msecs(ticks); +} + +u32 _mali_osk_time_tickcount( void ) +{ + return jiffies; +} + +void _mali_osk_time_ubusydelay( u32 usecs ) +{ + udelay(usecs); +} + +u64 _mali_osk_time_get_ns( void ) +{ + struct timespec tsval; + getnstimeofday(&tsval); + return (u64)timespec_to_ns(&tsval); +} diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_timers.c b/drivers/media/video/samsung/mali/linux/mali_osk_timers.c new file mode 100644 index 0000000..e5829a3 --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_osk_timers.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_timers.c + * Implementation of the OS abstraction layer for the kernel device driver + */ + +#include +#include +#include "mali_osk.h" +#include "mali_kernel_common.h" + +struct _mali_osk_timer_t_struct +{ + struct timer_list timer; +}; + +typedef void (*timer_timeout_function_t)(unsigned long); + +_mali_osk_timer_t *_mali_osk_timer_init(void) +{ + _mali_osk_timer_t *t = (_mali_osk_timer_t*)kmalloc(sizeof(_mali_osk_timer_t), GFP_KERNEL); + if (NULL != t) init_timer(&t->timer); + return t; +} + +void _mali_osk_timer_add( _mali_osk_timer_t *tim, u32 ticks_to_expire ) +{ + MALI_DEBUG_ASSERT_POINTER(tim); + tim->timer.expires = _mali_osk_time_tickcount() + ticks_to_expire; + add_timer(&(tim->timer)); +} + +void _mali_osk_timer_mod( _mali_osk_timer_t *tim, u32 expiry_tick) +{ + MALI_DEBUG_ASSERT_POINTER(tim); + mod_timer(&(tim->timer), expiry_tick); +} + +void _mali_osk_timer_del( _mali_osk_timer_t *tim ) +{ + MALI_DEBUG_ASSERT_POINTER(tim); + del_timer_sync(&(tim->timer)); +} + +void _mali_osk_timer_setcallback( _mali_osk_timer_t *tim, _mali_osk_timer_callback_t callback, void *data ) +{ + MALI_DEBUG_ASSERT_POINTER(tim); + tim->timer.data = (unsigned long)data; + tim->timer.function = (timer_timeout_function_t)callback; +} + +void _mali_osk_timer_term( _mali_osk_timer_t *tim ) +{ + MALI_DEBUG_ASSERT_POINTER(tim); + kfree(tim); +} diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_wait_queue.c b/drivers/media/video/samsung/mali/linux/mali_osk_wait_queue.c new file mode 100644 index 0000000..ce0561d --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_osk_wait_queue.c @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_wait_queue.c + * Implemenation of the OS abstraction layer for the kernel device driver + */ + +#include +#include +#include + +#include "mali_osk.h" +#include "mali_kernel_common.h" + +struct _mali_osk_wait_queue_t_struct +{ + wait_queue_head_t wait_queue; +}; + +_mali_osk_wait_queue_t* _mali_osk_wait_queue_init( void ) +{ + _mali_osk_wait_queue_t* ret = NULL; + + ret = kmalloc(sizeof(_mali_osk_wait_queue_t), GFP_KERNEL); + + if (NULL == ret) + { + return ret; + } + + init_waitqueue_head(&ret->wait_queue); + MALI_DEBUG_ASSERT(!waitqueue_active(&ret->wait_queue)); + + return ret; +} + +void _mali_osk_wait_queue_wait_event( _mali_osk_wait_queue_t *queue, mali_bool (*condition)(void) ) +{ + MALI_DEBUG_ASSERT_POINTER( queue ); + MALI_DEBUG_PRINT(6, ("Adding to wait queue %p\n", queue)); + wait_event(queue->wait_queue, condition()); +} + +void _mali_osk_wait_queue_wake_up( _mali_osk_wait_queue_t *queue ) +{ + MALI_DEBUG_ASSERT_POINTER( queue ); + + /* if queue is empty, don't attempt to wake up its elements */ + if (!waitqueue_active(&queue->wait_queue)) return; + + MALI_DEBUG_PRINT(6, ("Waking up elements in wait queue %p ....\n", queue)); + + wake_up_all(&queue->wait_queue); + + MALI_DEBUG_PRINT(6, ("... elements in wait queue %p woken up\n", queue)); +} + +void _mali_osk_wait_queue_term( _mali_osk_wait_queue_t *queue ) +{ + /* Parameter validation */ + MALI_DEBUG_ASSERT_POINTER( queue ); + + /* Linux requires no explicit termination of wait queues */ + kfree(queue); +} diff --git a/drivers/media/video/samsung/mali/linux/mali_pmu_power_up_down.c b/drivers/media/video/samsung/mali/linux/mali_pmu_power_up_down.c new file mode 100644 index 0000000..f3b0a2c --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_pmu_power_up_down.c @@ -0,0 +1,65 @@ +/** + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_pmu_power_up_down.c + */ + +#include +#include +#include +#include "mali_osk.h" +#include "mali_kernel_common.h" +#include "mali_pmu.h" +#include "linux/mali/mali_utgard.h" + +/* Mali PMU power up/down APIs */ + +int mali_pmu_powerup(void) +{ + struct mali_pmu_core *pmu = mali_pmu_get_global_pmu_core(); + + MALI_DEBUG_PRINT(5, ("Mali PMU: Power up\n")); + + if (NULL == pmu) + { + return -ENXIO; + } + + if (_MALI_OSK_ERR_OK != mali_pmu_powerup_all(pmu)) + { + return -EFAULT; + } + + return 0; +} + +EXPORT_SYMBOL(mali_pmu_powerup); + +int mali_pmu_powerdown(void) +{ + struct mali_pmu_core *pmu = mali_pmu_get_global_pmu_core(); + + MALI_DEBUG_PRINT(5, ("Mali PMU: Power down\n")); + + if (NULL == pmu) + { + return -ENXIO; + } + + if (_MALI_OSK_ERR_OK != mali_pmu_powerdown_all(pmu)) + { + return -EFAULT; + } + + return 0; +} + +EXPORT_SYMBOL(mali_pmu_powerdown); diff --git a/drivers/media/video/samsung/mali/linux/mali_profiling_events.h b/drivers/media/video/samsung/mali/linux/mali_profiling_events.h new file mode 100644 index 0000000..2639a40 --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_profiling_events.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_PROFILING_EVENTS_H__ +#define __MALI_PROFILING_EVENTS_H__ + +/* Simple wrapper in order to find the OS specific location of this file */ +#include + +#endif /* __MALI_PROFILING_EVENTS_H__ */ diff --git a/drivers/media/video/samsung/mali/linux/mali_uk_types.h b/drivers/media/video/samsung/mali/linux/mali_uk_types.h new file mode 100644 index 0000000..1a81246 --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_uk_types.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_UK_TYPES_H__ +#define __MALI_UK_TYPES_H__ + +/* Simple wrapper in order to find the OS specific location of this file */ +//#include +#include "../include/linux/mali/mali_utgard_uk_types.h" + +#endif /* __MALI_UK_TYPES_H__ */ diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_core.c b/drivers/media/video/samsung/mali/linux/mali_ukk_core.c new file mode 100644 index 0000000..22262fe --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_ukk_core.c @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include /* file system operations */ +#include /* memort allocation functions */ +#include /* user space access */ + +#include "mali_ukk.h" +#include "mali_osk.h" +#include "mali_kernel_common.h" +#include "mali_session.h" +#include "mali_ukk_wrappers.h" + +int get_api_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_api_version_s __user *uargs) +{ + _mali_uk_get_api_version_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + if (0 != get_user(kargs.version, &uargs->version)) return -EFAULT; + + kargs.ctx = session_data; + err = _mali_ukk_get_api_version(&kargs); + if (_MALI_OSK_ERR_OK != err) return map_errcode(err); + + if (0 != put_user(kargs.version, &uargs->version)) return -EFAULT; + if (0 != put_user(kargs.compatible, &uargs->compatible)) return -EFAULT; + + return 0; +} + +int wait_for_notification_wrapper(struct mali_session_data *session_data, _mali_uk_wait_for_notification_s __user *uargs) +{ + _mali_uk_wait_for_notification_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + kargs.ctx = session_data; + err = _mali_ukk_wait_for_notification(&kargs); + if (_MALI_OSK_ERR_OK != err) return map_errcode(err); + + if(_MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS != kargs.type) + { + kargs.ctx = NULL; /* prevent kernel address to be returned to user space */ + if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_wait_for_notification_s))) return -EFAULT; + } + else + { + if (0 != put_user(kargs.type, &uargs->type)) return -EFAULT; + } + + return 0; +} + +int post_notification_wrapper(struct mali_session_data *session_data, _mali_uk_post_notification_s __user *uargs) +{ + _mali_uk_post_notification_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + kargs.ctx = session_data; + + if (0 != get_user(kargs.type, &uargs->type)) + { + return -EFAULT; + } + + err = _mali_ukk_post_notification(&kargs); + if (_MALI_OSK_ERR_OK != err) + { + return map_errcode(err); + } + + return 0; +} + +int get_user_settings_wrapper(struct mali_session_data *session_data, _mali_uk_get_user_settings_s __user *uargs) +{ + _mali_uk_get_user_settings_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + kargs.ctx = session_data; + err = _mali_ukk_get_user_settings(&kargs); + if (_MALI_OSK_ERR_OK != err) + { + return map_errcode(err); + } + + kargs.ctx = NULL; /* prevent kernel address to be returned to user space */ + if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_get_user_settings_s))) return -EFAULT; + + return 0; +} diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_gp.c b/drivers/media/video/samsung/mali/linux/mali_ukk_gp.c new file mode 100644 index 0000000..7070016 --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_ukk_gp.c @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include /* file system operations */ +#include /* user space access */ + +#include "mali_ukk.h" +#include "mali_osk.h" +#include "mali_kernel_common.h" +#include "mali_session.h" +#include "mali_ukk_wrappers.h" + +int gp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_gp_start_job_s __user *uargs) +{ + _mali_uk_gp_start_job_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + MALI_CHECK_NON_NULL(session_data, -EINVAL); + + if (!access_ok(VERIFY_WRITE, uargs, sizeof(_mali_uk_gp_start_job_s))) + { + return -EFAULT; + } + + if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_gp_start_job_s))) return -EFAULT; + + kargs.ctx = session_data; + err = _mali_ukk_gp_start_job(&kargs); + if (_MALI_OSK_ERR_OK != err) return map_errcode(err); + + kargs.ctx = NULL; /* prevent kernel address to be returned to user space */ + + if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_gp_start_job_s))) + { + /* + * If this happens, then user space will not know that the job was actually started, + * and if we return a queued job, then user space will still think that one is still queued. + * This will typically lead to a deadlock in user space. + * This could however only happen if user space deliberately passes a user buffer which + * passes the access_ok(VERIFY_WRITE) check, but isn't fully writable at the time of copy_to_user(). + * The official Mali driver will never attempt to do that, and kernel space should not be affected. + * That is why we do not bother to do a complex rollback in this very very very rare case. + */ + return -EFAULT; + } + + return 0; +} + +int gp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_gp_core_version_s __user *uargs) +{ + _mali_uk_get_gp_core_version_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + MALI_CHECK_NON_NULL(session_data, -EINVAL); + + kargs.ctx = session_data; + err = _mali_ukk_get_gp_core_version(&kargs); + if (_MALI_OSK_ERR_OK != err) return map_errcode(err); + + /* no known transactions to roll-back */ + + if (0 != put_user(kargs.version, &uargs->version)) return -EFAULT; + + return 0; +} + +int gp_suspend_response_wrapper(struct mali_session_data *session_data, _mali_uk_gp_suspend_response_s __user *uargs) +{ + _mali_uk_gp_suspend_response_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + MALI_CHECK_NON_NULL(session_data, -EINVAL); + + if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_gp_suspend_response_s))) return -EFAULT; + + kargs.ctx = session_data; + err = _mali_ukk_gp_suspend_response(&kargs); + if (_MALI_OSK_ERR_OK != err) return map_errcode(err); + + if (0 != put_user(kargs.cookie, &uargs->cookie)) return -EFAULT; + + /* no known transactions to roll-back */ + return 0; +} + +int gp_get_number_of_cores_wrapper(struct mali_session_data *session_data, _mali_uk_get_gp_number_of_cores_s __user *uargs) +{ + _mali_uk_get_gp_number_of_cores_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + MALI_CHECK_NON_NULL(session_data, -EINVAL); + + kargs.ctx = session_data; + err = _mali_ukk_get_gp_number_of_cores(&kargs); + if (_MALI_OSK_ERR_OK != err) return map_errcode(err); + + /* no known transactions to roll-back */ + + if (0 != put_user(kargs.number_of_cores, &uargs->number_of_cores)) return -EFAULT; + + return 0; +} diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_mem.c b/drivers/media/video/samsung/mali/linux/mali_ukk_mem.c new file mode 100644 index 0000000..260f257 --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_ukk_mem.c @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include /* file system operations */ +#include /* user space access */ + +#include "mali_ukk.h" +#include "mali_osk.h" +#include "mali_kernel_common.h" +#include "mali_session.h" +#include "mali_ukk_wrappers.h" + +int mem_init_wrapper(struct mali_session_data *session_data, _mali_uk_init_mem_s __user *uargs) +{ + _mali_uk_init_mem_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + kargs.ctx = session_data; + err = _mali_ukk_init_mem(&kargs); + if (_MALI_OSK_ERR_OK != err) + { + return map_errcode(err); + } + + if (0 != put_user(kargs.mali_address_base, &uargs->mali_address_base)) goto mem_init_rollback; + if (0 != put_user(kargs.memory_size, &uargs->memory_size)) goto mem_init_rollback; + + return 0; + +mem_init_rollback: + { + _mali_uk_term_mem_s kargs; + kargs.ctx = session_data; + err = _mali_ukk_term_mem(&kargs); + if (_MALI_OSK_ERR_OK != err) + { + MALI_DEBUG_PRINT(4, ("reverting _mali_ukk_init_mem, as a result of failing put_user(), failed\n")); + } + } + return -EFAULT; +} + +int mem_term_wrapper(struct mali_session_data *session_data, _mali_uk_term_mem_s __user *uargs) +{ + _mali_uk_term_mem_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + kargs.ctx = session_data; + err = _mali_ukk_term_mem(&kargs); + if (_MALI_OSK_ERR_OK != err) + { + return map_errcode(err); + } + + return 0; +} + +int mem_map_ext_wrapper(struct mali_session_data *session_data, _mali_uk_map_external_mem_s __user * argument) +{ + _mali_uk_map_external_mem_s uk_args; + _mali_osk_errcode_t err_code; + + /* validate input */ + /* the session_data pointer was validated by caller */ + MALI_CHECK_NON_NULL( argument, -EINVAL); + + /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */ + if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_map_external_mem_s)) ) + { + return -EFAULT; + } + + uk_args.ctx = session_data; + err_code = _mali_ukk_map_external_mem( &uk_args ); + + if (0 != put_user(uk_args.cookie, &argument->cookie)) + { + if (_MALI_OSK_ERR_OK == err_code) + { + /* Rollback */ + _mali_uk_unmap_external_mem_s uk_args_unmap; + + uk_args_unmap.ctx = session_data; + uk_args_unmap.cookie = uk_args.cookie; + err_code = _mali_ukk_unmap_external_mem( &uk_args_unmap ); + if (_MALI_OSK_ERR_OK != err_code) + { + MALI_DEBUG_PRINT(4, ("reverting _mali_ukk_unmap_external_mem, as a result of failing put_user(), failed\n")); + } + } + return -EFAULT; + } + + /* Return the error that _mali_ukk_free_big_block produced */ + return map_errcode(err_code); +} + +int mem_unmap_ext_wrapper(struct mali_session_data *session_data, _mali_uk_unmap_external_mem_s __user * argument) +{ + _mali_uk_unmap_external_mem_s uk_args; + _mali_osk_errcode_t err_code; + + /* validate input */ + /* the session_data pointer was validated by caller */ + MALI_CHECK_NON_NULL( argument, -EINVAL); + + /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */ + if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_unmap_external_mem_s)) ) + { + return -EFAULT; + } + + uk_args.ctx = session_data; + err_code = _mali_ukk_unmap_external_mem( &uk_args ); + + /* Return the error that _mali_ukk_free_big_block produced */ + return map_errcode(err_code); +} + +#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 +int mem_release_ump_wrapper(struct mali_session_data *session_data, _mali_uk_release_ump_mem_s __user * argument) +{ + _mali_uk_release_ump_mem_s uk_args; + _mali_osk_errcode_t err_code; + + /* validate input */ + /* the session_data pointer was validated by caller */ + MALI_CHECK_NON_NULL( argument, -EINVAL); + + /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */ + if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_release_ump_mem_s)) ) + { + return -EFAULT; + } + + uk_args.ctx = session_data; + err_code = _mali_ukk_release_ump_mem( &uk_args ); + + /* Return the error that _mali_ukk_free_big_block produced */ + return map_errcode(err_code); +} + +int mem_attach_ump_wrapper(struct mali_session_data *session_data, _mali_uk_attach_ump_mem_s __user * argument) +{ + _mali_uk_attach_ump_mem_s uk_args; + _mali_osk_errcode_t err_code; + + /* validate input */ + /* the session_data pointer was validated by caller */ + MALI_CHECK_NON_NULL( argument, -EINVAL); + + /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */ + if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_attach_ump_mem_s)) ) + { + return -EFAULT; + } + + uk_args.ctx = session_data; + err_code = _mali_ukk_attach_ump_mem( &uk_args ); + + if (0 != put_user(uk_args.cookie, &argument->cookie)) + { + if (_MALI_OSK_ERR_OK == err_code) + { + /* Rollback */ + _mali_uk_release_ump_mem_s uk_args_unmap; + + uk_args_unmap.ctx = session_data; + uk_args_unmap.cookie = uk_args.cookie; + err_code = _mali_ukk_release_ump_mem( &uk_args_unmap ); + if (_MALI_OSK_ERR_OK != err_code) + { + MALI_DEBUG_PRINT(4, ("reverting _mali_ukk_attach_mem, as a result of failing put_user(), failed\n")); + } + } + return -EFAULT; + } + + /* Return the error that _mali_ukk_map_external_ump_mem produced */ + return map_errcode(err_code); +} +#endif /* MALI_USE_UNIFIED_MEMORY_PROVIDER */ + +int mem_query_mmu_page_table_dump_size_wrapper(struct mali_session_data *session_data, _mali_uk_query_mmu_page_table_dump_size_s __user * uargs) +{ + _mali_uk_query_mmu_page_table_dump_size_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + MALI_CHECK_NON_NULL(session_data, -EINVAL); + + kargs.ctx = session_data; + + err = _mali_ukk_query_mmu_page_table_dump_size(&kargs); + if (_MALI_OSK_ERR_OK != err) return map_errcode(err); + + if (0 != put_user(kargs.size, &uargs->size)) return -EFAULT; + + return 0; +} + +int mem_dump_mmu_page_table_wrapper(struct mali_session_data *session_data, _mali_uk_dump_mmu_page_table_s __user * uargs) +{ + _mali_uk_dump_mmu_page_table_s kargs; + _mali_osk_errcode_t err; + void *buffer; + int rc = -EFAULT; + + /* validate input */ + MALI_CHECK_NON_NULL(uargs, -EINVAL); + /* the session_data pointer was validated by caller */ + + kargs.buffer = NULL; + + /* get location of user buffer */ + if (0 != get_user(buffer, &uargs->buffer)) goto err_exit; + /* get size of mmu page table info buffer from user space */ + if ( 0 != get_user(kargs.size, &uargs->size) ) goto err_exit; + /* verify we can access the whole of the user buffer */ + if (!access_ok(VERIFY_WRITE, buffer, kargs.size)) goto err_exit; + + /* allocate temporary buffer (kernel side) to store mmu page table info */ + kargs.buffer = _mali_osk_valloc(kargs.size); + if (NULL == kargs.buffer) + { + rc = -ENOMEM; + goto err_exit; + } + + kargs.ctx = session_data; + err = _mali_ukk_dump_mmu_page_table(&kargs); + if (_MALI_OSK_ERR_OK != err) + { + rc = map_errcode(err); + goto err_exit; + } + + /* copy mmu page table info back to user space and update pointers */ + if (0 != copy_to_user(uargs->buffer, kargs.buffer, kargs.size) ) goto err_exit; + if (0 != put_user((kargs.register_writes - (u32 *)kargs.buffer) + (u32 *)uargs->buffer, &uargs->register_writes)) goto err_exit; + if (0 != put_user((kargs.page_table_dump - (u32 *)kargs.buffer) + (u32 *)uargs->buffer, &uargs->page_table_dump)) goto err_exit; + if (0 != put_user(kargs.register_writes_size, &uargs->register_writes_size)) goto err_exit; + if (0 != put_user(kargs.page_table_dump_size, &uargs->page_table_dump_size)) goto err_exit; + rc = 0; + +err_exit: + if (kargs.buffer) _mali_osk_vfree(kargs.buffer); + return rc; +} diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_pp.c b/drivers/media/video/samsung/mali/linux/mali_ukk_pp.c new file mode 100644 index 0000000..c11c61b --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_ukk_pp.c @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include /* file system operations */ +#include /* user space access */ + +#include "mali_ukk.h" +#include "mali_osk.h" +#include "mali_kernel_common.h" +#include "mali_session.h" +#include "mali_ukk_wrappers.h" + +int pp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_start_job_s __user *uargs) +{ + _mali_uk_pp_start_job_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + MALI_CHECK_NON_NULL(session_data, -EINVAL); + + if (!access_ok(VERIFY_WRITE, uargs, sizeof(_mali_uk_pp_start_job_s))) + { + return -EFAULT; + } + + if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_pp_start_job_s))) return -EFAULT; + + kargs.ctx = session_data; + err = _mali_ukk_pp_start_job(&kargs); + if (_MALI_OSK_ERR_OK != err) return map_errcode(err); + + return 0; +} + +int pp_get_number_of_cores_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_number_of_cores_s __user *uargs) +{ + _mali_uk_get_pp_number_of_cores_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + MALI_CHECK_NON_NULL(session_data, -EINVAL); + + kargs.ctx = session_data; + err = _mali_ukk_get_pp_number_of_cores(&kargs); + if (_MALI_OSK_ERR_OK != err) return map_errcode(err); + + if (0 != put_user(kargs.number_of_cores, &uargs->number_of_cores)) return -EFAULT; + + return 0; +} + +int pp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_core_version_s __user *uargs) +{ + _mali_uk_get_pp_core_version_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + MALI_CHECK_NON_NULL(session_data, -EINVAL); + + kargs.ctx = session_data; + err = _mali_ukk_get_pp_core_version(&kargs); + if (_MALI_OSK_ERR_OK != err) return map_errcode(err); + + if (0 != put_user(kargs.version, &uargs->version)) return -EFAULT; + + return 0; +} + +int pp_disable_wb_wrapper(struct mali_session_data *session_data, _mali_uk_pp_disable_wb_s __user *uargs) +{ + _mali_uk_pp_disable_wb_s kargs; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + MALI_CHECK_NON_NULL(session_data, -EINVAL); + + if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_pp_disable_wb_s))) return -EFAULT; + + kargs.ctx = session_data; + _mali_ukk_pp_job_disable_wb(&kargs); + + return 0; +} diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_profiling.c b/drivers/media/video/samsung/mali/linux/mali_ukk_profiling.c new file mode 100644 index 0000000..f4e31c9 --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_ukk_profiling.c @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include /* file system operations */ +#include /* user space access */ +#include + +#include "mali_ukk.h" +#include "mali_osk.h" +#include "mali_kernel_common.h" +#include "mali_session.h" +#include "mali_ukk_wrappers.h" + +int profiling_start_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_start_s __user *uargs) +{ + _mali_uk_profiling_start_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_profiling_start_s))) + { + return -EFAULT; + } + + kargs.ctx = session_data; + err = _mali_ukk_profiling_start(&kargs); + if (_MALI_OSK_ERR_OK != err) + { + return map_errcode(err); + } + + if (0 != put_user(kargs.limit, &uargs->limit)) + { + return -EFAULT; + } + + return 0; +} + +int profiling_add_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_add_event_s __user *uargs) +{ + _mali_uk_profiling_add_event_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_profiling_add_event_s))) + { + return -EFAULT; + } + + kargs.ctx = session_data; + err = _mali_ukk_profiling_add_event(&kargs); + if (_MALI_OSK_ERR_OK != err) + { + return map_errcode(err); + } + + return 0; +} + +int profiling_stop_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_stop_s __user *uargs) +{ + _mali_uk_profiling_stop_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + kargs.ctx = session_data; + err = _mali_ukk_profiling_stop(&kargs); + if (_MALI_OSK_ERR_OK != err) + { + return map_errcode(err); + } + + if (0 != put_user(kargs.count, &uargs->count)) + { + return -EFAULT; + } + + return 0; +} + +int profiling_get_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_get_event_s __user *uargs) +{ + _mali_uk_profiling_get_event_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + if (0 != get_user(kargs.index, &uargs->index)) + { + return -EFAULT; + } + + kargs.ctx = session_data; + + err = _mali_ukk_profiling_get_event(&kargs); + if (_MALI_OSK_ERR_OK != err) + { + return map_errcode(err); + } + + kargs.ctx = NULL; /* prevent kernel address to be returned to user space */ + if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_profiling_get_event_s))) + { + return -EFAULT; + } + + return 0; +} + +int profiling_clear_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_clear_s __user *uargs) +{ + _mali_uk_profiling_clear_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + kargs.ctx = session_data; + err = _mali_ukk_profiling_clear(&kargs); + if (_MALI_OSK_ERR_OK != err) + { + return map_errcode(err); + } + + return 0; +} + +int profiling_report_sw_counters_wrapper(struct mali_session_data *session_data, _mali_uk_sw_counters_report_s __user *uargs) +{ + _mali_uk_sw_counters_report_s kargs; + _mali_osk_errcode_t err; + u32 *counter_buffer; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_sw_counters_report_s))) + { + return -EFAULT; + } + + /* make sure that kargs.num_counters is [at least somewhat] sane */ + if (kargs.num_counters > 10000) { + MALI_DEBUG_PRINT(1, ("User space attempted to allocate too many counters.\n")); + return -EINVAL; + } + + counter_buffer = (u32*)kmalloc(sizeof(u32) * kargs.num_counters, GFP_KERNEL); + if (NULL == counter_buffer) + { + return -ENOMEM; + } + + if (0 != copy_from_user(counter_buffer, kargs.counters, sizeof(u32) * kargs.num_counters)) + { + kfree(counter_buffer); + return -EFAULT; + } + + kargs.ctx = session_data; + kargs.counters = counter_buffer; + + err = _mali_ukk_sw_counters_report(&kargs); + + kfree(counter_buffer); + + if (_MALI_OSK_ERR_OK != err) + { + return map_errcode(err); + } + + return 0; +} + + diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_vsync.c b/drivers/media/video/samsung/mali/linux/mali_ukk_vsync.c new file mode 100644 index 0000000..f9b5a3e --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_ukk_vsync.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include /* file system operations */ +#include /* user space access */ + +#include "mali_ukk.h" +#include "mali_osk.h" +#include "mali_kernel_common.h" +#include "mali_session.h" +#include "mali_ukk_wrappers.h" + + +int vsync_event_report_wrapper(struct mali_session_data *session_data, _mali_uk_vsync_event_report_s __user *uargs) +{ + _mali_uk_vsync_event_report_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_vsync_event_report_s))) + { + return -EFAULT; + } + + kargs.ctx = session_data; + err = _mali_ukk_vsync_event_report(&kargs); + if (_MALI_OSK_ERR_OK != err) + { + return map_errcode(err); + } + + return 0; +} + diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_wrappers.h b/drivers/media/video/samsung/mali/linux/mali_ukk_wrappers.h new file mode 100644 index 0000000..65857fd --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_ukk_wrappers.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_ukk_wrappers.h + * Defines the wrapper functions for each user-kernel function + */ + +#ifndef __MALI_UKK_WRAPPERS_H__ +#define __MALI_UKK_WRAPPERS_H__ + +#include "mali_uk_types.h" +#include "mali_osk.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +int wait_for_notification_wrapper(struct mali_session_data *session_data, _mali_uk_wait_for_notification_s __user *uargs); +int get_api_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_api_version_s __user *uargs); +int get_user_settings_wrapper(struct mali_session_data *session_data, _mali_uk_get_user_settings_s __user *uargs); +int post_notification_wrapper(struct mali_session_data *session_data, _mali_uk_post_notification_s __user *uargs); +int mem_init_wrapper(struct mali_session_data *session_data, _mali_uk_init_mem_s __user *uargs); +int mem_term_wrapper(struct mali_session_data *session_data, _mali_uk_term_mem_s __user *uargs); +int mem_map_ext_wrapper(struct mali_session_data *session_data, _mali_uk_map_external_mem_s __user * argument); +int mem_unmap_ext_wrapper(struct mali_session_data *session_data, _mali_uk_unmap_external_mem_s __user * argument); +int mem_query_mmu_page_table_dump_size_wrapper(struct mali_session_data *session_data, _mali_uk_query_mmu_page_table_dump_size_s __user * uargs); +int mem_dump_mmu_page_table_wrapper(struct mali_session_data *session_data, _mali_uk_dump_mmu_page_table_s __user * uargs); + +#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 +int mem_attach_ump_wrapper(struct mali_session_data *session_data, _mali_uk_attach_ump_mem_s __user * argument); +int mem_release_ump_wrapper(struct mali_session_data *session_data, _mali_uk_release_ump_mem_s __user * argument); +#endif /* MALI_USE_UNIFIED_MEMORY_PROVIDER */ + +int pp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_start_job_s __user *uargs); +int pp_get_number_of_cores_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_number_of_cores_s __user *uargs); +int pp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_core_version_s __user *uargs); +int pp_disable_wb_wrapper(struct mali_session_data *session_data, _mali_uk_pp_disable_wb_s __user *uargs); +int gp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_gp_start_job_s __user *uargs); +int gp_get_number_of_cores_wrapper(struct mali_session_data *session_data, _mali_uk_get_gp_number_of_cores_s __user *uargs); +int gp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_gp_core_version_s __user *uargs); +int gp_suspend_response_wrapper(struct mali_session_data *session_data, _mali_uk_gp_suspend_response_s __user *uargs); + +int profiling_start_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_start_s __user *uargs); +int profiling_add_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_add_event_s __user *uargs); +int profiling_stop_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_stop_s __user *uargs); +int profiling_get_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_get_event_s __user *uargs); +int profiling_clear_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_clear_s __user *uargs); +int profiling_report_sw_counters_wrapper(struct mali_session_data *session_data, _mali_uk_sw_counters_report_s __user *uargs); + +int vsync_event_report_wrapper(struct mali_session_data *session_data, _mali_uk_vsync_event_report_s __user *uargs); + + +int map_errcode( _mali_osk_errcode_t err ); + +#ifdef __cplusplus +} +#endif + +#endif /* __MALI_UKK_WRAPPERS_H__ */ diff --git a/drivers/media/video/samsung/mali/platform/default/mali_platform.c b/drivers/media/video/samsung/mali/platform/default/mali_platform.c new file mode 100644 index 0000000..d966f25 --- /dev/null +++ b/drivers/media/video/samsung/mali/platform/default/mali_platform.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_platform.c + * Platform specific Mali driver functions for a default platform + */ +#include "mali_kernel_common.h" +#include "mali_osk.h" +#include "mali_platform.h" + + +_mali_osk_errcode_t mali_platform_init(void) +{ + MALI_SUCCESS; +} + +_mali_osk_errcode_t mali_platform_deinit(void) +{ + MALI_SUCCESS; +} + +_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode) +{ + MALI_SUCCESS; +} + +void mali_gpu_utilization_handler(u32 utilization) +{ +} + +void set_mali_parent_power_domain(void* dev) +{ +} + + diff --git a/drivers/media/video/samsung/mali/platform/mali_platform.h b/drivers/media/video/samsung/mali/platform/mali_platform.h new file mode 100644 index 0000000..888f57a --- /dev/null +++ b/drivers/media/video/samsung/mali/platform/mali_platform.h @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_platform.h + * Platform specific Mali driver functions + */ + +#ifndef __MALI_PLATFORM_H__ +#define __MALI_PLATFORM_H__ + +#include "mali_osk.h" + +#ifdef CONFIG_CPU_EXYNOS4210 +#define MALI_DVFS_STEPS 3 +#else +#define MALI_DVFS_STEPS 5 +#endif + +/* @Enable or Disable Mali GPU Bottom Lock feature */ +#define MALI_GPU_BOTTOM_LOCK 1 + +#define MALI_VOLTAGE_LOCK 1 + +/* @Enable or Disable the CPU frequency lock when the GPU clock is 440 Mhz */ +#define CPUFREQ_LOCK_DURING_440 0 + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief description of power change reasons + */ +typedef enum mali_power_mode_tag +{ + MALI_POWER_MODE_ON, /**< Power Mali on */ + MALI_POWER_MODE_LIGHT_SLEEP, /**< Mali has been idle for a short time, or runtime PM suspend */ + MALI_POWER_MODE_DEEP_SLEEP, /**< Mali has been idle for a long time, or OS suspend */ +} mali_power_mode; + +/** @brief Platform specific setup and initialisation of MALI + * + * This is called from the entrypoint of the driver to initialize the platform + * + * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. + */ +_mali_osk_errcode_t mali_platform_init(void); + +/** @brief Platform specific deinitialisation of MALI + * + * This is called on the exit of the driver to terminate the platform + * + * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. + */ +_mali_osk_errcode_t mali_platform_deinit(void); + +/** @brief Platform specific powerdown sequence of MALI + * + * Notification from the Mali device driver stating the new desired power mode. + * MALI_POWER_MODE_ON must be obeyed, while the other modes are optional. + * @param power_mode defines the power modes + * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. + */ +_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode); + + +/** @brief Platform specific handling of GPU utilization data + * + * When GPU utilization data is enabled, this function will be + * periodically called. + * + * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization. + */ +void mali_gpu_utilization_handler(u32 utilization); + +/** @brief Setting the power domain of MALI + * + * This function sets the power domain of MALI if Linux run time power management is enabled + * + * @param dev Reference to struct platform_device (defined in linux) used by MALI GPU + */ +//void set_mali_parent_power_domain(void* dev); +void mali_utilization_suspend(void); + +#ifdef CONFIG_REGULATOR +int mali_regulator_get_usecount(void); +void mali_regulator_disable(void); +void mali_regulator_enable(void); +void mali_regulator_set_voltage(int min_uV, int max_uV); +#endif +mali_bool mali_clk_set_rate(unsigned int clk, unsigned int mhz); +unsigned long mali_clk_get_rate(void); +void mali_clk_put(mali_bool binc_mali_clk); + +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON +_mali_osk_errcode_t mali_platform_powerdown(u32 cores); +_mali_osk_errcode_t mali_platform_powerup(u32 cores); +#endif + + +#if USING_MALI_PMM +#if MALI_POWER_MGMT_TEST_SUITE +/** @brief function to get status of individual cores + * + * This function is used by power management test suite to get the status of powered up/down the number + * of cores + * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization. + */ +u32 pmu_get_power_up_down_info(void); +#endif +#endif + +#if MALI_DVFS_ENABLED +mali_bool init_mali_dvfs_status(int step); +void deinit_mali_dvfs_status(void); +mali_bool mali_dvfs_handler(u32 utilization); +int mali_dvfs_is_running(void); +void mali_dvfs_late_resume(void); +int get_mali_dvfs_control_status(void); +mali_bool set_mali_dvfs_current_step(unsigned int step); +void mali_default_step_set(int step, mali_bool boostup); +int change_dvfs_tableset(int change_clk, int change_step); +#ifdef CONFIG_CPU_EXYNOS4210 +#if MALI_GPU_BOTTOM_LOCK +int mali_dvfs_bottom_lock_push(void); +int mali_dvfs_bottom_lock_pop(void); +#endif +#else +int mali_dvfs_bottom_lock_push(int lock_step); +int mali_dvfs_bottom_lock_pop(void); +#endif +#endif + +int mali_dvfs_get_vol(int step); + +#if MALI_VOLTAGE_LOCK +int mali_voltage_lock_push(int lock_vol); +int mali_voltage_lock_pop(void); +int mali_voltage_lock_init(void); +int mali_vol_get_from_table(int vol); +#endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/drivers/media/video/samsung/mali/platform/mali_platform_pmu_testing/mali_platform.c b/drivers/media/video/samsung/mali/platform/mali_platform_pmu_testing/mali_platform.c new file mode 100644 index 0000000..cb95dc6 --- /dev/null +++ b/drivers/media/video/samsung/mali/platform/mali_platform_pmu_testing/mali_platform.c @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_platform.c + * Platform specific Mali driver functions for a default platform + */ +#include "mali_kernel_common.h" +#include "mali_osk.h" +#include "mali_platform.h" +#include "mali_pmu.h" +#include "linux/mali/mali_utgard.h" + +static u32 bPowerOff = 1; + +_mali_osk_errcode_t mali_platform_init(void) +{ + MALI_SUCCESS; +} + +_mali_osk_errcode_t mali_platform_deinit(void) +{ + MALI_SUCCESS; +} + +_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode) +{ + switch (power_mode) + { + case MALI_POWER_MODE_ON: + if (bPowerOff == 1) + { + mali_pmu_powerup(); + bPowerOff = 0; + } + break; + case MALI_POWER_MODE_LIGHT_SLEEP: + case MALI_POWER_MODE_DEEP_SLEEP: + + if (bPowerOff == 0) + { + mali_pmu_powerdown(); + bPowerOff = 1; + } + + break; + } + MALI_SUCCESS; +} + +void mali_gpu_utilization_handler(u32 utilization) +{ +} + +void set_mali_parent_power_domain(void* dev) +{ +} + + diff --git a/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform.c b/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform.c new file mode 100644 index 0000000..119831d --- /dev/null +++ b/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform.c @@ -0,0 +1,656 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_platform.c + * Platform specific Mali driver functions for a default platform + */ +#include +#include "mali_kernel_common.h" +#include "mali_osk.h" +#include "mali_platform.h" +#include "mali_linux_pm.h" + +#if USING_MALI_PMM +#include "mali_pm.h" +#endif + +#include +#include +#include +#include +#include + +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON +#include +#endif + +#if MALI_TIMELINE_PROFILING_ENABLED +#include "mali_kernel_profiling.h" +#endif + +#include +#include + +#define EXTXTALCLK_NAME "ext_xtal" +#define VPLLSRCCLK_NAME "vpll_src" +#define FOUTVPLLCLK_NAME "fout_vpll" +#define SCLVPLLCLK_NAME "sclk_vpll" +#define GPUMOUT1CLK_NAME "mout_g3d1" + +#define MPLLCLK_NAME "mout_mpll" +#define GPUMOUT0CLK_NAME "mout_g3d0" +#define GPUCLK_NAME "sclk_g3d" +#define CLK_DIV_STAT_G3D 0x1003C62C +#define CLK_DESC "clk-divider-status" + +static struct clk *ext_xtal_clock = 0; +static struct clk *vpll_src_clock = 0; +static struct clk *fout_vpll_clock = 0; +static struct clk *sclk_vpll_clock = 0; + +static struct clk *mpll_clock = 0; +static struct clk *mali_parent_clock = 0; +static struct clk *mali_clock = 0; + +int mali_gpu_clk = 160; +static unsigned int GPU_MHZ = 1000000; +#ifdef CONFIG_S5PV310_ASV +int mali_gpu_vol = 1100000; /* 1.10V for ASV */ +#else +int mali_gpu_vol = 1100000; /* 1.10V */ +#endif + +#if MALI_DVFS_ENABLED +#define MALI_DVFS_DEFAULT_STEP 0 // 134Mhz default +#endif + +int gpu_power_state; +static int bPoweroff; + +#ifdef CONFIG_REGULATOR +struct regulator { + struct device *dev; + struct list_head list; + int uA_load; + int min_uV; + int max_uV; + char *supply_name; + struct device_attribute dev_attr; + struct regulator_dev *rdev; +}; + +struct regulator *g3d_regulator=NULL; +#endif + +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36) +extern struct platform_device s5pv310_device_pd[]; +#else +extern struct platform_device exynos4_device_pd[]; +#endif +#endif + +mali_io_address clk_register_map=0; + +#if MALI_GPU_BOTTOM_LOCK +_mali_osk_lock_t *mali_dvfs_lock; +#else +static _mali_osk_lock_t *mali_dvfs_lock; +#endif + +#ifdef CONFIG_REGULATOR +int mali_regulator_get_usecount(void) +{ + struct regulator_dev *rdev; + + if( IS_ERR_OR_NULL(g3d_regulator) ) + { + MALI_DEBUG_PRINT(1, ("error on mali_regulator_get_usecount : g3d_regulator is null\n")); + return 0; + } + rdev = g3d_regulator->rdev; + return rdev->use_count; +} + +void mali_regulator_disable(void) +{ + bPoweroff = 1; + if( IS_ERR_OR_NULL(g3d_regulator) ) + { + MALI_DEBUG_PRINT(1, ("error on mali_regulator_disable : g3d_regulator is null\n")); + return; + } + regulator_disable(g3d_regulator); + MALI_DEBUG_PRINT(1, ("regulator_disable -> use cnt: %d \n",mali_regulator_get_usecount())); +} + +void mali_regulator_enable(void) +{ + bPoweroff = 0; + if( IS_ERR_OR_NULL(g3d_regulator) ) + { + MALI_DEBUG_PRINT(1, ("error on mali_regulator_enable : g3d_regulator is null\n")); + return; + } + regulator_enable(g3d_regulator); + MALI_DEBUG_PRINT(1, ("regulator_enable -> use cnt: %d \n",mali_regulator_get_usecount())); +} + +void mali_regulator_set_voltage(int min_uV, int max_uV) +{ + int voltage; + + _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); + + if( IS_ERR_OR_NULL(g3d_regulator) ) + { + MALI_DEBUG_PRINT(1, ("error on mali_regulator_set_voltage : g3d_regulator is null\n")); + return; + } + MALI_DEBUG_PRINT(2, ("= regulator_set_voltage: %d, %d \n",min_uV, max_uV)); + +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE | + MALI_PROFILING_EVENT_CHANNEL_SOFTWARE | + MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_VOLTS, + min_uV, max_uV, 0, 0, 0); +#endif + + regulator_set_voltage(g3d_regulator,min_uV,max_uV); + voltage = regulator_get_voltage(g3d_regulator); + +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE | + MALI_PROFILING_EVENT_CHANNEL_SOFTWARE | + MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_VOLTS, + voltage, 0, 1, 0, 0); +#endif + mali_gpu_vol = voltage; + MALI_DEBUG_PRINT(1, ("= regulator_get_voltage: %d \n",mali_gpu_vol)); + + _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); +} +#endif + +unsigned long mali_clk_get_rate(void) +{ + return clk_get_rate(mali_clock); +} + +mali_bool mali_clk_get(mali_bool bis_vpll) +{ + if (bis_vpll == MALI_TRUE) + { + if (ext_xtal_clock == NULL) + { + ext_xtal_clock = clk_get(NULL,EXTXTALCLK_NAME); + if (IS_ERR(ext_xtal_clock)) { + MALI_PRINT( ("MALI Error : failed to get source ext_xtal_clock\n")); + return MALI_FALSE; + } + } + + if (vpll_src_clock == NULL) + { + vpll_src_clock = clk_get(NULL,VPLLSRCCLK_NAME); + if (IS_ERR(vpll_src_clock)) { + MALI_PRINT( ("MALI Error : failed to get source vpll_src_clock\n")); + return MALI_FALSE; + } + } + + if (fout_vpll_clock == NULL) + { + fout_vpll_clock = clk_get(NULL,FOUTVPLLCLK_NAME); + if (IS_ERR(fout_vpll_clock)) { + MALI_PRINT( ("MALI Error : failed to get source fout_vpll_clock\n")); + return MALI_FALSE; + } + } + + if (sclk_vpll_clock == NULL) + { + sclk_vpll_clock = clk_get(NULL,SCLVPLLCLK_NAME); + if (IS_ERR(sclk_vpll_clock)) { + MALI_PRINT( ("MALI Error : failed to get source sclk_vpll_clock\n")); + return MALI_FALSE; + } + } + + if (mali_parent_clock == NULL) + { + mali_parent_clock = clk_get(NULL, GPUMOUT1CLK_NAME); + + if (IS_ERR(mali_parent_clock)) { + MALI_PRINT( ( "MALI Error : failed to get source mali parent clock\n")); + return MALI_FALSE; + } + } + } + else // mpll + { + if (mpll_clock == NULL) + { + mpll_clock = clk_get(NULL,MPLLCLK_NAME); + + if (IS_ERR(mpll_clock)) { + MALI_PRINT( ("MALI Error : failed to get source mpll clock\n")); + return MALI_FALSE; + } + } + + if (mali_parent_clock == NULL) + { + mali_parent_clock = clk_get(NULL, GPUMOUT0CLK_NAME); + + if (IS_ERR(mali_parent_clock)) { + MALI_PRINT( ( "MALI Error : failed to get source mali parent clock\n")); + return MALI_FALSE; + } + } + } + + // mali clock get always. + if (mali_clock == NULL) + { + mali_clock = clk_get(NULL, GPUCLK_NAME); + + if (IS_ERR(mali_clock)) { + MALI_PRINT( ("MALI Error : failed to get source mali clock\n")); + return MALI_FALSE; + } + } + + return MALI_TRUE; +} + +void mali_clk_put(mali_bool binc_mali_clock) +{ + if (mali_parent_clock) + { + clk_put(mali_parent_clock); + mali_parent_clock = 0; + } + + if (mpll_clock) + { + clk_put(mpll_clock); + mpll_clock = 0; + } + + if (sclk_vpll_clock) + { + clk_put(sclk_vpll_clock); + sclk_vpll_clock = 0; + } + + if (fout_vpll_clock) + { + clk_put(fout_vpll_clock); + fout_vpll_clock = 0; + } + + if (vpll_src_clock) + { + clk_put(vpll_src_clock); + vpll_src_clock = 0; + } + + if (ext_xtal_clock) + { + clk_put(ext_xtal_clock); + ext_xtal_clock = 0; + } + + if (binc_mali_clock == MALI_TRUE && mali_clock) + { + clk_put(mali_clock); + mali_clock = 0; + } + +} + + +mali_bool mali_clk_set_rate(unsigned int clk, unsigned int mhz) +{ + unsigned long rate = 0; + mali_bool bis_vpll = MALI_FALSE; + +#ifdef CONFIG_VPLL_USE_FOR_TVENC + bis_vpll = MALI_TRUE; +#endif + + _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); + + if (mali_clk_get(bis_vpll) == MALI_FALSE) + return MALI_FALSE; + + rate = (unsigned long)clk * (unsigned long)mhz; + MALI_DEBUG_PRINT(3,("= clk_set_rate : %d , %d \n",clk, mhz )); + + if (bis_vpll) + { + clk_set_rate(fout_vpll_clock, (unsigned int)clk * GPU_MHZ); + clk_set_parent(vpll_src_clock, ext_xtal_clock); + clk_set_parent(sclk_vpll_clock, fout_vpll_clock); + + clk_set_parent(mali_parent_clock, sclk_vpll_clock); + clk_set_parent(mali_clock, mali_parent_clock); + } + else + { + clk_set_parent(mali_parent_clock, mpll_clock); + clk_set_parent(mali_clock, mali_parent_clock); + } + + if (clk_enable(mali_clock) < 0) + return MALI_FALSE; + +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE | + MALI_PROFILING_EVENT_CHANNEL_SOFTWARE | + MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_FREQ, + rate, 0, 0, 0, 0); +#endif + + clk_set_rate(mali_clock, rate); + rate = clk_get_rate(mali_clock); + +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE | + MALI_PROFILING_EVENT_CHANNEL_SOFTWARE | + MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_FREQ, + rate, 0, 0, 0, 0); +#endif + + if (bis_vpll) + mali_gpu_clk = (int)(rate / mhz); + else + mali_gpu_clk = (int)((rate + 500000) / mhz); + + GPU_MHZ = mhz; + MALI_DEBUG_PRINT(3,("= clk_get_rate: %d \n",mali_gpu_clk)); + + mali_clk_put(MALI_FALSE); + + _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); + + return MALI_TRUE; +} + +static mali_bool init_mali_clock(void) +{ + mali_bool ret = MALI_TRUE; + + gpu_power_state = 0; + + if (mali_clock != 0) + return ret; // already initialized + + mali_dvfs_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE + | _MALI_OSK_LOCKFLAG_ONELOCK, 0, 0); + if (mali_dvfs_lock == NULL) + return _MALI_OSK_ERR_FAULT; + + if (mali_clk_set_rate(mali_gpu_clk, GPU_MHZ) == MALI_FALSE) + { + ret = MALI_FALSE; + goto err_clock_get; + } + + MALI_PRINT(("init_mali_clock mali_clock %p \n", mali_clock)); + + +#ifdef CONFIG_REGULATOR +#if USING_MALI_PMM + g3d_regulator = regulator_get(&mali_gpu_device.dev, "vdd_g3d"); +#else + g3d_regulator = regulator_get(NULL, "vdd_g3d"); +#endif + + if (IS_ERR(g3d_regulator)) + { + MALI_PRINT( ("MALI Error : failed to get vdd_g3d\n")); + ret = MALI_FALSE; + goto err_regulator; + } + + regulator_enable(g3d_regulator); + MALI_DEBUG_PRINT(1, ("= regulator_enable -> use cnt: %d \n",mali_regulator_get_usecount())); + mali_regulator_set_voltage(mali_gpu_vol, mali_gpu_vol); +#endif + + MALI_DEBUG_PRINT(2, ("MALI Clock is set at mali driver\n")); + MALI_DEBUG_PRINT(3,("::clk_put:: %s mali_parent_clock - normal\n", __FUNCTION__)); + MALI_DEBUG_PRINT(3,("::clk_put:: %s mpll_clock - normal\n", __FUNCTION__)); + + mali_clk_put(MALI_FALSE); + + return MALI_TRUE; + + +#ifdef CONFIG_REGULATOR +err_regulator: + regulator_put(g3d_regulator); +#endif + +err_clock_get: + mali_clk_put(MALI_TRUE); + + return ret; +} + +static mali_bool deinit_mali_clock(void) +{ + if (mali_clock == 0) + return MALI_TRUE; + +#ifdef CONFIG_REGULATOR + if (g3d_regulator) + { + regulator_put(g3d_regulator); + g3d_regulator=NULL; + } +#endif + + mali_clk_put(MALI_TRUE); + + return MALI_TRUE; +} + + +static _mali_osk_errcode_t enable_mali_clocks(void) +{ + int err; + err = clk_enable(mali_clock); + MALI_DEBUG_PRINT(3,("enable_mali_clocks mali_clock %p error %d \n", mali_clock, err)); + + // set clock rate + mali_clk_set_rate(mali_gpu_clk, GPU_MHZ); + + MALI_SUCCESS; +} + +static _mali_osk_errcode_t disable_mali_clocks(void) +{ + clk_disable(mali_clock); + MALI_DEBUG_PRINT(3,("disable_mali_clocks mali_clock %p \n", mali_clock)); + + MALI_SUCCESS; +} + +void set_mali_parent_power_domain(struct platform_device* dev) +{ +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36) + dev->dev.parent = &s5pv310_device_pd[PD_G3D].dev; +#else + dev->dev.parent = &exynos4_device_pd[PD_G3D].dev; +#endif + +#endif +} + +_mali_osk_errcode_t g3d_power_domain_control(int bpower_on) +{ + if (bpower_on) + { +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON + MALI_DEBUG_PRINT(3,("_mali_osk_pm_dev_activate \n")); + _mali_osk_pm_dev_activate(); +#else //MALI_PMM_RUNTIME_JOB_CONTROL_ON + void __iomem *status; + u32 timeout; + __raw_writel(S5P_INT_LOCAL_PWR_EN, S5P_PMU_G3D_CONF); + status = S5P_PMU_G3D_CONF + 0x4; + + timeout = 10; + while ((__raw_readl(status) & S5P_INT_LOCAL_PWR_EN) + != S5P_INT_LOCAL_PWR_EN) { + if (timeout == 0) { + MALI_PRINTF(("Power domain enable failed.\n")); + return -ETIMEDOUT; + } + timeout--; + _mali_osk_time_ubusydelay(100); + } +#endif //MALI_PMM_RUNTIME_JOB_CONTROL_ON + } + else + { +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON + MALI_DEBUG_PRINT( 4,("_mali_osk_pm_dev_idle\n")); + _mali_osk_pm_dev_idle(); + +#else //MALI_PMM_RUNTIME_JOB_CONTROL_ON + void __iomem *status; + u32 timeout; + __raw_writel(0, S5P_PMU_G3D_CONF); + + status = S5P_PMU_G3D_CONF + 0x4; + /* Wait max 1ms */ + timeout = 10; + while (__raw_readl(status) & S5P_INT_LOCAL_PWR_EN) + { + if (timeout == 0) { + MALI_PRINTF(("Power domain disable failed.\n" )); + return -ETIMEDOUT; + } + timeout--; + _mali_osk_time_ubusydelay( 100); + } +#endif //MALI_PMM_RUNTIME_JOB_CONTROL_ON + } + + MALI_SUCCESS; +} + +_mali_osk_errcode_t mali_platform_init() +{ + MALI_CHECK(init_mali_clock(), _MALI_OSK_ERR_FAULT); +#if MALI_DVFS_ENABLED + if (!clk_register_map) clk_register_map = _mali_osk_mem_mapioregion( CLK_DIV_STAT_G3D, 0x20, CLK_DESC ); + if(!init_mali_dvfs_status(MALI_DVFS_DEFAULT_STEP)) + MALI_DEBUG_PRINT(1, ("mali_platform_init failed\n")); +#endif + + MALI_SUCCESS; +} + +_mali_osk_errcode_t mali_platform_deinit() +{ + deinit_mali_clock(); + +#if MALI_DVFS_ENABLED + deinit_mali_dvfs_status(); + if (clk_register_map ) + { + _mali_osk_mem_unmapioregion(CLK_DIV_STAT_G3D, 0x20, clk_register_map); + clk_register_map=0; + } +#endif + + MALI_SUCCESS; +} + +_mali_osk_errcode_t mali_platform_powerdown(u32 cores) +{ + MALI_DEBUG_PRINT(3,("power down is called in mali_platform_powerdown state %x core %x \n", gpu_power_state, cores)); + + if (gpu_power_state != 0) // power down after state is 0 + { + gpu_power_state = gpu_power_state & (~cores); + if (gpu_power_state == 0) + { + MALI_DEBUG_PRINT( 3,("disable clock\n")); + disable_mali_clocks(); + } + } + else + { + MALI_PRINT(("mali_platform_powerdown gpu_power_state == 0 and cores %x \n", cores)); + } + + bPoweroff=1; + + + + MALI_SUCCESS; +} + +_mali_osk_errcode_t mali_platform_powerup(u32 cores) +{ + MALI_DEBUG_PRINT(3,("power up is called in mali_platform_powerup state %x core %x \n", gpu_power_state, cores)); + + if (gpu_power_state == 0) // power up only before state is 0 + { + gpu_power_state = gpu_power_state | cores; + + if (gpu_power_state != 0) + { + MALI_DEBUG_PRINT(4,("enable clock \n")); + enable_mali_clocks(); + } + } + else + { + gpu_power_state = gpu_power_state | cores; + } + + bPoweroff=0; + + + MALI_SUCCESS; +} + +void mali_gpu_utilization_handler(u32 utilization) +{ + if (bPoweroff==0) + { +#if MALI_DVFS_ENABLED + if(!mali_dvfs_handler(utilization)) + MALI_DEBUG_PRINT(1,( "error on mali dvfs status in utilization\n")); +#endif + } +} + +#if MALI_POWER_MGMT_TEST_SUITE +u32 pmu_get_power_up_down_info(void) +{ + return 4095; +} + +#endif +_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode) +{ + MALI_SUCCESS; +} + diff --git a/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c b/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c new file mode 100644 index 0000000..4efa759 --- /dev/null +++ b/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c @@ -0,0 +1,448 @@ +/* * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_platform_dvfs.c + * Platform specific Mali driver dvfs functions + */ + +#include "mali_kernel_common.h" +#include "mali_osk.h" +#include "mali_platform.h" + +#include +#include +#include +#include + +#include + +#ifdef CONFIG_CPU_FREQ +#include +#include +#define EXYNOS4_ASV_ENABLED +#endif + +#include "mali_device_pause_resume.h" +#include + +#define MALI_DVFS_WATING 10 // msec + +static int bMaliDvfsRun=0; + +#if MALI_GPU_BOTTOM_LOCK +static _mali_osk_atomic_t bottomlock_status; +#endif + +typedef struct mali_dvfs_tableTag{ + unsigned int clock; + unsigned int freq; + unsigned int vol; +}mali_dvfs_table; + +typedef struct mali_dvfs_statusTag{ + unsigned int currentStep; + mali_dvfs_table * pCurrentDvfs; + +}mali_dvfs_currentstatus; + +typedef struct mali_dvfs_thresholdTag{ + unsigned int downthreshold; + unsigned int upthreshold; +}mali_dvfs_threshold_table; + +typedef struct mali_dvfs_staycount{ + unsigned int staycount; +}mali_dvfs_staycount_table; + +mali_dvfs_staycount_table mali_dvfs_staycount[MALI_DVFS_STEPS]={ + /*step 0*/{1}, + /*step 1*/{1}, + /*step 2*/{1} }; + +/*dvfs threshold*/ +mali_dvfs_threshold_table mali_dvfs_threshold[MALI_DVFS_STEPS]={ + /*step 0*/{((int)((255*0)/100)) ,((int)((255*85)/100))}, + /*step 1*/{((int)((255*75)/100)) ,((int)((255*85)/100))}, + /*step 2*/{((int)((255*75)/100)) ,((int)((255*100)/100))} }; + +/*dvfs status*/ +mali_dvfs_currentstatus maliDvfsStatus; +int mali_dvfs_control=0; + +/*dvfs table*/ +mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={ +#ifdef CONFIG_EXYNOS4210_1400MHZ_SUPPORT + /*step 0*/{134 ,1000000 , 950000}, +#else + /*step 0*/{100 ,1000000 , 950000}, +#endif + /*step 1*/{160 ,1000000 , 950000}, + /*step 2*/{267 ,1000000 ,1000000} }; + +#ifdef EXYNOS4_ASV_ENABLED + +#define ASV_8_LEVEL 8 +#define ASV_5_LEVEL 5 + +static unsigned int asv_3d_volt_5_table[ASV_5_LEVEL][MALI_DVFS_STEPS] = { + /* L3 (100/134MHz) L2(160MHz), L1(267MHz) */ + {1000000, 1000000, 1100000}, /* S */ + {1000000, 1000000, 1100000}, /* A */ + { 950000, 950000, 1000000}, /* B */ + { 950000, 950000, 1000000}, /* C */ + { 950000, 950000, 950000}, /* D */ +}; + +static unsigned int asv_3d_volt_8_table[ASV_8_LEVEL][MALI_DVFS_STEPS] = { + /* L3 (100/134MHz) L2(160MHz), L1(267MHz) */ + {1000000, 1000000, 1100000}, /* SS */ + {1000000, 1000000, 1100000}, /* A1 */ + {1000000, 1000000, 1100000}, /* A2 */ + { 950000, 950000, 1000000}, /* B1 */ + { 950000, 950000, 1000000}, /* B2 */ + { 950000, 950000, 1000000}, /* C1 */ + { 950000, 950000, 1000000}, /* C2 */ + { 950000, 950000, 950000}, /* D1 */ +}; +#endif + +static u32 mali_dvfs_utilization = 255; + +static void mali_dvfs_work_handler(struct work_struct *w); + +static struct workqueue_struct *mali_dvfs_wq = 0; +extern mali_io_address clk_register_map; + +#if MALI_GPU_BOTTOM_LOCK +extern _mali_osk_lock_t *mali_dvfs_lock; +#endif + +static DECLARE_WORK(mali_dvfs_work, mali_dvfs_work_handler); + +static unsigned int get_mali_dvfs_status(void) +{ + return maliDvfsStatus.currentStep; +} + +#if MALI_GPU_BOTTOM_LOCK +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON +int get_mali_dvfs_control_status(void) +{ + return mali_dvfs_control; +} + +mali_bool set_mali_dvfs_current_step(unsigned int step) +{ + _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); + maliDvfsStatus.currentStep = step; + _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); + return MALI_TRUE; +} +#endif +#endif + +static mali_bool set_mali_dvfs_status(u32 step,mali_bool boostup) +{ + u32 validatedStep=step; + +#ifdef CONFIG_REGULATOR + if (mali_regulator_get_usecount()==0) { + MALI_DEBUG_PRINT(1, ("regulator use_count is 0 \n")); + return MALI_FALSE; + } +#endif + + if (boostup) { +#ifdef CONFIG_REGULATOR + /*change the voltage*/ + mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol); +#endif + /*change the clock*/ + mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq); + } else { + /*change the clock*/ + mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq); +#ifdef CONFIG_REGULATOR + /*change the voltage*/ + mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol); +#endif + } + + maliDvfsStatus.currentStep = validatedStep; + /*for future use*/ + maliDvfsStatus.pCurrentDvfs = &mali_dvfs[validatedStep]; + + return MALI_TRUE; +} + +static void mali_platform_wating(u32 msec) +{ + /*sample wating + change this in the future with proper check routine. + */ + unsigned int read_val; + while(1) { + read_val = _mali_osk_mem_ioread32(clk_register_map, 0x00); + if ((read_val & 0x8000)==0x0000) break; + + _mali_osk_time_ubusydelay(100); // 1000 -> 100 : 20101218 + } + /* _mali_osk_time_ubusydelay(msec*1000);*/ +} + +static mali_bool change_mali_dvfs_status(u32 step, mali_bool boostup ) +{ + + MALI_DEBUG_PRINT(1, ("> change_mali_dvfs_status: %d, %d \n",step, boostup)); + + if (!set_mali_dvfs_status(step, boostup)) { + MALI_DEBUG_PRINT(1, ("error on set_mali_dvfs_status: %d, %d \n",step, boostup)); + return MALI_FALSE; + } + + /*wait until clock and voltage is stablized*/ + mali_platform_wating(MALI_DVFS_WATING); /*msec*/ + + return MALI_TRUE; +} + +static unsigned int decideNextStatus(unsigned int utilization) +{ + unsigned int level=0; // 0:stay, 1:up + + if (!mali_dvfs_control) { +#if MALI_GPU_BOTTOM_LOCK + if (_mali_osk_atomic_read(&bottomlock_status) > 0) + level = 1; /* or bigger */ + else +#endif + switch(maliDvfsStatus.currentStep) + { + case 0: + if( utilization > mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold) + level=1; + else + level = maliDvfsStatus.currentStep; + break; + case 1: + if( utilization > mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold) + level=2; + else if( utilization < + (mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold*mali_dvfs[maliDvfsStatus.currentStep-1].clock)/ + mali_dvfs[maliDvfsStatus.currentStep].clock) + level=0; + else + level = maliDvfsStatus.currentStep; + break; + case 2: + if( utilization < + (mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold*mali_dvfs[maliDvfsStatus.currentStep-1].clock)/ + mali_dvfs[maliDvfsStatus.currentStep].clock) + level=1; + else + level = maliDvfsStatus.currentStep; + break; + } + } + else + { + if((mali_dvfs_control == 1)||(( mali_dvfs_control > 3) && (mali_dvfs_control < mali_dvfs[0].clock+1))) + { + level=0; + } + else if((mali_dvfs_control == 2)||(( mali_dvfs_control > mali_dvfs[0].clock) && (mali_dvfs_control < mali_dvfs[1].clock+1))) + { + level=1; + } + else + { + level=2; + } + } + + return level; +} + +#ifdef EXYNOS4_ASV_ENABLED +static mali_bool mali_dvfs_table_update(void) +{ + unsigned int exynos_result_of_asv_group; + unsigned int target_asv; + unsigned int i; + exynos_result_of_asv_group = exynos_result_of_asv & 0xf; + target_asv = exynos_result_of_asv >> 28; + MALI_PRINT(("exynos_result_of_asv_group = 0x%x, target_asv = 0x%x\n", exynos_result_of_asv_group, target_asv)); + + if (target_asv == 0x8) { //SUPPORT_1400MHZ + for (i = 0; i < MALI_DVFS_STEPS; i++) { + mali_dvfs[i].vol = asv_3d_volt_5_table[exynos_result_of_asv_group][i]; + MALI_PRINT(("mali_dvfs[%d].vol = %d\n", i, mali_dvfs[i].vol)); + } + } else if (target_asv == 0x4){ //SUPPORT_1200MHZ + for (i = 0; i < MALI_DVFS_STEPS; i++) { + mali_dvfs[i].vol = asv_3d_volt_8_table[exynos_result_of_asv_group][i]; + MALI_PRINT(("mali_dvfs[%d].vol = %d\n", i, mali_dvfs[i].vol)); + } + } + + return MALI_TRUE; + +} +#endif + +static mali_bool mali_dvfs_status(u32 utilization) +{ + unsigned int nextStatus = 0; + unsigned int curStatus = 0; + mali_bool boostup = MALI_FALSE; +#ifdef EXYNOS4_ASV_ENABLED + static mali_bool asv_applied = MALI_FALSE; +#endif + static int stay_count = 0; // to prevent frequent switch + + MALI_DEBUG_PRINT(1, ("> mali_dvfs_status: %d \n",utilization)); +#ifdef EXYNOS4_ASV_ENABLED + if (asv_applied == MALI_FALSE) { + mali_dvfs_table_update(); + change_mali_dvfs_status(0,0); + asv_applied = MALI_TRUE; + + return MALI_TRUE; + } +#endif + + /*decide next step*/ + curStatus = get_mali_dvfs_status(); + nextStatus = decideNextStatus(utilization); + + MALI_DEBUG_PRINT(1, ("= curStatus %d, nextStatus %d, maliDvfsStatus.currentStep %d \n", curStatus, nextStatus, maliDvfsStatus.currentStep)); + + /*if next status is same with current status, don't change anything*/ + if ((curStatus!=nextStatus && stay_count==0)) { + /*check if boost up or not*/ + if (nextStatus > maliDvfsStatus.currentStep) + boostup = 1; + + /*change mali dvfs status*/ + if (!change_mali_dvfs_status(nextStatus,boostup)) { + MALI_DEBUG_PRINT(1, ("error on change_mali_dvfs_status \n")); + return MALI_FALSE; + } + stay_count = mali_dvfs_staycount[maliDvfsStatus.currentStep].staycount; + } else { + if (stay_count>0) + stay_count--; + } + + return MALI_TRUE; +} + + + +int mali_dvfs_is_running(void) +{ + return bMaliDvfsRun; +} + + + +void mali_dvfs_late_resume(void) +{ + // set the init clock as low when resume + set_mali_dvfs_status(0,0); +} + + +static void mali_dvfs_work_handler(struct work_struct *w) +{ + bMaliDvfsRun=1; + + MALI_DEBUG_PRINT(3, ("=== mali_dvfs_work_handler\n")); + + if (!mali_dvfs_status(mali_dvfs_utilization)) + MALI_DEBUG_PRINT(1,( "error on mali dvfs status in mali_dvfs_work_handler")); + + bMaliDvfsRun=0; +} + + +mali_bool init_mali_dvfs_status(int step) +{ + /*default status + add here with the right function to get initilization value. + */ + if (!mali_dvfs_wq) + mali_dvfs_wq = create_singlethread_workqueue("mali_dvfs"); + +#if MALI_GPU_BOTTOM_LOCK + _mali_osk_atomic_init(&bottomlock_status, 0); +#endif + + /*add a error handling here*/ + maliDvfsStatus.currentStep = step; + + return MALI_TRUE; +} + +void deinit_mali_dvfs_status(void) +{ +#if MALI_GPU_BOTTOM_LOCK + _mali_osk_atomic_term(&bottomlock_status); +#endif + + if (mali_dvfs_wq) + destroy_workqueue(mali_dvfs_wq); + mali_dvfs_wq = NULL; +} + +mali_bool mali_dvfs_handler(u32 utilization) +{ + mali_dvfs_utilization = utilization; + queue_work_on(0, mali_dvfs_wq,&mali_dvfs_work); + + /*add error handle here*/ + return MALI_TRUE; +} + +void mali_default_step_set(int step, mali_bool boostup) +{ + mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq); + + if (maliDvfsStatus.currentStep == 1) + set_mali_dvfs_status(step, boostup); +} + +#if MALI_GPU_BOTTOM_LOCK +int mali_dvfs_bottom_lock_push(void) +{ + int prev_status = _mali_osk_atomic_read(&bottomlock_status); + + if (prev_status < 0) { + MALI_PRINT(("gpu bottom lock status is not valid for push")); + return -1; + } + + if (prev_status == 0) { + mali_regulator_set_voltage(mali_dvfs[1].vol, mali_dvfs[1].vol); + mali_clk_set_rate(mali_dvfs[1].clock, mali_dvfs[1].freq); + set_mali_dvfs_current_step(1); + } + + return _mali_osk_atomic_inc_return(&bottomlock_status); +} + +int mali_dvfs_bottom_lock_pop(void) +{ + if (_mali_osk_atomic_read(&bottomlock_status) <= 0) { + MALI_PRINT(("gpu bottom lock status is not valid for pop")); + return -1; + } + + return _mali_osk_atomic_dec_return(&bottomlock_status); +} +#endif diff --git a/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c b/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c new file mode 100644 index 0000000..a08bc97 --- /dev/null +++ b/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c @@ -0,0 +1,801 @@ +/* Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_platform.c + * Platform specific Mali driver functions for a default platform + */ +#include +#include "mali_kernel_common.h" +#include "mali_osk.h" +#include "mali_platform.h" +#include "mali_linux_pm.h" + +#if USING_MALI_PMM +#include "mali_pm.h" +#endif + +#include +#include +#include +#include +#include + +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON +#include +#endif + +#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED +#include "mali_osk_profiling.h" +unsigned long gFreq = 366; +int gVolt = 5000; +#endif + +#include +#include + +#define EXTXTALCLK_NAME "ext_xtal" +#define VPLLSRCCLK_NAME "vpll_src" +#define FOUTVPLLCLK_NAME "fout_vpll" +#define SCLVPLLCLK_NAME "sclk_vpll" +#define GPUMOUT1CLK_NAME "mout_g3d1" + +#define MPLLCLK_NAME "mout_mpll" +#define GPUMOUT0CLK_NAME "mout_g3d0" +#define GPUCLK_NAME "sclk_g3d" +#define CLK_DIV_STAT_G3D 0x1003C62C +#define CLK_DESC "clk-divider-status" + +#define MALI_BOTTOMLOCK_VOL 900000 + +typedef struct mali_runtime_resumeTag{ + int clk; + int vol; +}mali_runtime_resume_table; + +mali_runtime_resume_table mali_runtime_resume = {266, 900000}; + +/* lock/unlock CPU freq by Mali */ +extern int cpufreq_lock_by_mali(unsigned int freq); +extern void cpufreq_unlock_by_mali(void); + +/* start of modification by skkim */ +extern mali_bool init_mali_dvfs_status(int step); +extern void deinit_mali_dvfs_status(void); +extern mali_bool mali_dvfs_handler(u32 utilization); +extern int get_mali_dvfs_control_status(void); +extern mali_bool set_mali_dvfs_current_step(unsigned int step); +/* end of modification by skkim */ + +static struct clk *ext_xtal_clock = 0; +static struct clk *vpll_src_clock = 0; +static struct clk *fout_vpll_clock = 0; +static struct clk *sclk_vpll_clock = 0; + +static struct clk *mpll_clock = 0; +static struct clk *mali_parent_clock = 0; +static struct clk *mali_clock = 0; + + +static unsigned int GPU_MHZ = 1000000; + +int mali_gpu_clk = 266; +int mali_gpu_vol = 900000; + +#if MALI_DVFS_ENABLED +#define MALI_DVFS_DEFAULT_STEP 1 +#endif +#if MALI_VOLTAGE_LOCK +int mali_lock_vol = 0; +static _mali_osk_atomic_t voltage_lock_status; +static mali_bool mali_vol_lock_flag = 0; +#endif + +int gpu_power_state; +static int bPoweroff; + +#ifdef CONFIG_REGULATOR +struct regulator { + struct device *dev; + struct list_head list; + int uA_load; + int min_uV; + int max_uV; + char *supply_name; + struct device_attribute dev_attr; + struct regulator_dev *rdev; +}; + +struct regulator *g3d_regulator=NULL; +#endif + +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36) +extern struct platform_device s5pv310_device_pd[]; +#else +extern struct platform_device exynos4_device_pd[]; +#endif +#endif + +mali_io_address clk_register_map=0; + +_mali_osk_lock_t *mali_dvfs_lock = 0; + +#ifdef CONFIG_REGULATOR +int mali_regulator_get_usecount(void) +{ + struct regulator_dev *rdev; + + if( IS_ERR_OR_NULL(g3d_regulator) ) + { + MALI_DEBUG_PRINT(1, ("error on mali_regulator_get_usecount : g3d_regulator is null\n")); + return 0; + } + rdev = g3d_regulator->rdev; + return rdev->use_count; +} + +void mali_regulator_disable(void) +{ + if( IS_ERR_OR_NULL(g3d_regulator) ) + { + MALI_DEBUG_PRINT(1, ("error on mali_regulator_disable : g3d_regulator is null\n")); + return; + } + regulator_disable(g3d_regulator); + MALI_DEBUG_PRINT(1, ("regulator_disable -> use cnt: %d \n",mali_regulator_get_usecount())); + bPoweroff = 1; +} + +void mali_regulator_enable(void) +{ + if( IS_ERR_OR_NULL(g3d_regulator) ) + { + MALI_DEBUG_PRINT(1, ("error on mali_regulator_enable : g3d_regulator is null\n")); + return; + } + regulator_enable(g3d_regulator); + MALI_DEBUG_PRINT(1, ("regulator_enable -> use cnt: %d \n",mali_regulator_get_usecount())); + bPoweroff = 0; +} + +void mali_regulator_set_voltage(int min_uV, int max_uV) +{ + int voltage; +#if !MALI_DVFS_ENABLED + min_uV = mali_gpu_vol; + max_uV = mali_gpu_vol; +#endif +#if MALI_VOLTAGE_LOCK + if (mali_vol_lock_flag == MALI_FALSE) { + if (min_uV < MALI_BOTTOMLOCK_VOL || max_uV < MALI_BOTTOMLOCK_VOL) { + min_uV = MALI_BOTTOMLOCK_VOL; + max_uV = MALI_BOTTOMLOCK_VOL; + } + } else if (_mali_osk_atomic_read(&voltage_lock_status) > 0 ) { + if (min_uV < mali_lock_vol || max_uV < mali_lock_vol) { +#if MALI_DVFS_ENABLED + int mali_vol_get; + mali_vol_get = mali_vol_get_from_table(mali_lock_vol); + if (mali_vol_get) { + min_uV = mali_vol_get; + max_uV = mali_vol_get; + } +#else + min_uV = mali_lock_vol; + max_uV = mali_lock_vol; +#endif + } + } +#endif + + _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); + + if( IS_ERR_OR_NULL(g3d_regulator) ) + { + MALI_DEBUG_PRINT(1, ("error on mali_regulator_set_voltage : g3d_regulator is null\n")); + return; + } + + MALI_DEBUG_PRINT(2, ("= regulator_set_voltage: %d, %d \n",min_uV, max_uV)); + + regulator_set_voltage(g3d_regulator,min_uV,max_uV); + voltage = regulator_get_voltage(g3d_regulator); + +#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED + gVolt = voltage/1000; + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | + MALI_PROFILING_EVENT_CHANNEL_GPU | + MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, gFreq, gVolt, + 0, 0, 0); +#endif + + mali_gpu_vol = voltage; + MALI_DEBUG_PRINT(1, ("= regulator_get_voltage: %d \n",mali_gpu_vol)); + + _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); +} +#endif + +unsigned long mali_clk_get_rate(void) +{ + return clk_get_rate(mali_clock); +} + +mali_bool mali_clk_get(mali_bool bis_vpll) +{ + if (bis_vpll == MALI_TRUE) + { + if (ext_xtal_clock == NULL) + { + ext_xtal_clock = clk_get(NULL,EXTXTALCLK_NAME); + if (IS_ERR(ext_xtal_clock)) { + MALI_PRINT( ("MALI Error : failed to get source ext_xtal_clock\n")); + return MALI_FALSE; + } + } + + if (vpll_src_clock == NULL) + { + vpll_src_clock = clk_get(NULL,VPLLSRCCLK_NAME); + if (IS_ERR(vpll_src_clock)) { + MALI_PRINT( ("MALI Error : failed to get source vpll_src_clock\n")); + return MALI_FALSE; + } + } + + if (fout_vpll_clock == NULL) + { + fout_vpll_clock = clk_get(NULL,FOUTVPLLCLK_NAME); + if (IS_ERR(fout_vpll_clock)) { + MALI_PRINT( ("MALI Error : failed to get source fout_vpll_clock\n")); + return MALI_FALSE; + } + } + + if (sclk_vpll_clock == NULL) + { + sclk_vpll_clock = clk_get(NULL,SCLVPLLCLK_NAME); + if (IS_ERR(sclk_vpll_clock)) { + MALI_PRINT( ("MALI Error : failed to get source sclk_vpll_clock\n")); + return MALI_FALSE; + } + } + + if (mali_parent_clock == NULL) + { + mali_parent_clock = clk_get(NULL, GPUMOUT1CLK_NAME); + + if (IS_ERR(mali_parent_clock)) { + MALI_PRINT( ( "MALI Error : failed to get source mali parent clock\n")); + return MALI_FALSE; + } + } + } + else // mpll + { + if (mpll_clock == NULL) + { + mpll_clock = clk_get(NULL,MPLLCLK_NAME); + + if (IS_ERR(mpll_clock)) { + MALI_PRINT( ("MALI Error : failed to get source mpll clock\n")); + return MALI_FALSE; + } + } + + if (mali_parent_clock == NULL) + { + mali_parent_clock = clk_get(NULL, GPUMOUT0CLK_NAME); + + if (IS_ERR(mali_parent_clock)) { + MALI_PRINT( ( "MALI Error : failed to get source mali parent clock\n")); + return MALI_FALSE; + } + } + } + + // mali clock get always. + if (mali_clock == NULL) + { + mali_clock = clk_get(NULL, GPUCLK_NAME); + + if (IS_ERR(mali_clock)) { + MALI_PRINT( ("MALI Error : failed to get source mali clock\n")); + return MALI_FALSE; + } + } + + return MALI_TRUE; +} + +void mali_clk_put(mali_bool binc_mali_clock) +{ + if (mali_parent_clock) + { + clk_put(mali_parent_clock); + mali_parent_clock = 0; + } + + if (mpll_clock) + { + clk_put(mpll_clock); + mpll_clock = 0; + } + + if (sclk_vpll_clock) + { + clk_put(sclk_vpll_clock); + sclk_vpll_clock = 0; + } + + if (fout_vpll_clock) + { + clk_put(fout_vpll_clock); + fout_vpll_clock = 0; + } + + if (vpll_src_clock) + { + clk_put(vpll_src_clock); + vpll_src_clock = 0; + } + + if (ext_xtal_clock) + { + clk_put(ext_xtal_clock); + ext_xtal_clock = 0; + } + + if (binc_mali_clock == MALI_TRUE && mali_clock) + { + clk_put(mali_clock); + mali_clock = 0; + } + +} + + +mali_bool mali_clk_set_rate(unsigned int clk, unsigned int mhz) +{ + unsigned long rate = 0; + mali_bool bis_vpll = MALI_TRUE; + +#ifndef CONFIG_VPLL_USE_FOR_TVENC + bis_vpll = MALI_TRUE; +#endif + +#if !MALI_DVFS_ENABLED + clk = mali_gpu_clk; +#endif + trace_printk("SPI_GPUFREQ_%uMHz\n", mali_gpu_clk); + _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); + + if (mali_clk_get(bis_vpll) == MALI_FALSE) + return MALI_FALSE; + + rate = (unsigned long)clk * (unsigned long)mhz; + MALI_DEBUG_PRINT(3,("= clk_set_rate : %d , %d \n",clk, mhz )); + + if (bis_vpll) + { + clk_set_rate(fout_vpll_clock, (unsigned int)clk * GPU_MHZ); + clk_set_parent(vpll_src_clock, ext_xtal_clock); + clk_set_parent(sclk_vpll_clock, fout_vpll_clock); + + clk_set_parent(mali_parent_clock, sclk_vpll_clock); + clk_set_parent(mali_clock, mali_parent_clock); + } + else + { + clk_set_parent(mali_parent_clock, mpll_clock); + clk_set_parent(mali_clock, mali_parent_clock); + } + + if (clk_enable(mali_clock) < 0) + return MALI_FALSE; + + + clk_set_rate(mali_clock, rate); + rate = clk_get_rate(mali_clock); + +#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED + gFreq = rate/1000000; + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | + MALI_PROFILING_EVENT_CHANNEL_GPU | + MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, + gFreq, gVolt, 0, 0, 0); +#endif + + if (bis_vpll) + mali_gpu_clk = (int)(rate / mhz); + else + mali_gpu_clk = (int)((rate + 500000) / mhz); + + GPU_MHZ = mhz; + MALI_DEBUG_PRINT(3,("= clk_get_rate: %d \n",mali_gpu_clk)); + + mali_clk_put(MALI_FALSE); + + _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); + + return MALI_TRUE; +} + +static mali_bool init_mali_clock(void) +{ + mali_bool ret = MALI_TRUE; + + if (mali_clock != 0) + return ret; // already initialized + + mali_dvfs_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE + | _MALI_OSK_LOCKFLAG_ONELOCK, 0, 0); + if (mali_dvfs_lock == NULL) + return _MALI_OSK_ERR_FAULT; + + if (mali_clk_set_rate(mali_gpu_clk, GPU_MHZ) == MALI_FALSE) + { + ret = MALI_FALSE; + goto err_clock_get; + } + + MALI_PRINT(("init_mali_clock mali_clock %p \n", mali_clock)); + + +#ifdef CONFIG_REGULATOR +#if USING_MALI_PMM + g3d_regulator = regulator_get(&mali_gpu_device.dev, "vdd_g3d"); +#else + g3d_regulator = regulator_get(NULL, "vdd_g3d"); +#endif + + if (IS_ERR(g3d_regulator)) + { + MALI_PRINT( ("MALI Error : failed to get vdd_g3d\n")); + ret = MALI_FALSE; + goto err_regulator; + } + + regulator_enable(g3d_regulator); + + MALI_DEBUG_PRINT(1, ("= regulator_enable -> use cnt: %d \n",mali_regulator_get_usecount())); + mali_regulator_set_voltage(mali_gpu_vol, mali_gpu_vol); +#endif + + MALI_DEBUG_PRINT(2, ("MALI Clock is set at mali driver\n")); + + MALI_DEBUG_PRINT(3,("::clk_put:: %s mali_parent_clock - normal\n", __FUNCTION__)); + MALI_DEBUG_PRINT(3,("::clk_put:: %s mpll_clock - normal\n", __FUNCTION__)); + + mali_clk_put(MALI_FALSE); + + gpu_power_state=0; + bPoweroff=1; + + return MALI_TRUE; +#ifdef CONFIG_REGULATOR +err_regulator: + regulator_put(g3d_regulator); +#endif + +err_clock_get: + mali_clk_put(MALI_TRUE); + + return ret; +} + +static mali_bool deinit_mali_clock(void) +{ + if (mali_clock == 0) + return MALI_TRUE; + +#ifdef CONFIG_REGULATOR + if (g3d_regulator) + { + regulator_put(g3d_regulator); + g3d_regulator=NULL; + } +#endif + + mali_clk_put(MALI_TRUE); + + return MALI_TRUE; +} +static _mali_osk_errcode_t enable_mali_clocks(void) +{ + int err; + err = clk_enable(mali_clock); + MALI_DEBUG_PRINT(3,("enable_mali_clocks mali_clock %p error %d \n", mali_clock, err)); + + mali_runtime_resume.vol = mali_dvfs_get_vol(MALI_DVFS_DEFAULT_STEP); +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON +#if MALI_DVFS_ENABLED + // set clock rate + if (get_mali_dvfs_control_status() != 0 || mali_gpu_clk >= mali_runtime_resume.clk) + mali_clk_set_rate(mali_gpu_clk, GPU_MHZ); + else { + mali_regulator_set_voltage(mali_runtime_resume.vol, mali_runtime_resume.vol); + mali_clk_set_rate(mali_runtime_resume.clk, GPU_MHZ); + set_mali_dvfs_current_step(MALI_DVFS_DEFAULT_STEP); + } +#if CPUFREQ_LOCK_DURING_440 + /* lock/unlock CPU freq by Mali */ + if (mali_gpu_clk >= 440) + err = cpufreq_lock_by_mali(1200); +#endif +#else + mali_regulator_set_voltage(mali_runtime_resume.vol, mali_runtime_resume.vol); + mali_clk_set_rate(mali_runtime_resume.clk, GPU_MHZ); +#endif +#else + mali_clk_set_rate(mali_gpu_clk, GPU_MHZ); +#endif + MALI_SUCCESS; +} + +static _mali_osk_errcode_t disable_mali_clocks(void) +{ + clk_disable(mali_clock); + MALI_DEBUG_PRINT(3,("disable_mali_clocks mali_clock %p \n", mali_clock)); + +#if MALI_DVFS_ENABLED && CPUFREQ_LOCK_DURING_440 + /* lock/unlock CPU freq by Mali */ + cpufreq_unlock_by_mali(); +#endif + MALI_SUCCESS; +} + +void set_mali_parent_power_domain(struct platform_device* dev) +{ +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36) + dev->dev.parent = &s5pv310_device_pd[PD_G3D].dev; +#else + dev->dev.parent = &exynos4_device_pd[PD_G3D].dev; +#endif +#endif +} + +_mali_osk_errcode_t g3d_power_domain_control(int bpower_on) +{ + if (bpower_on) + { +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON + MALI_DEBUG_PRINT(3,("_mali_osk_pmm_dev_activate \n")); + _mali_osk_pm_dev_activate(); +#else //MALI_PMM_RUNTIME_JOB_CONTROL_ON + void __iomem *status; + u32 timeout; + __raw_writel(S5P_INT_LOCAL_PWR_EN, S5P_PMU_G3D_CONF); + status = S5P_PMU_G3D_CONF + 0x4; + + timeout = 10; + while ((__raw_readl(status) & S5P_INT_LOCAL_PWR_EN) + != S5P_INT_LOCAL_PWR_EN) { + if (timeout == 0) { + MALI_PRINTF(("Power domain enable failed.\n")); + return -ETIMEDOUT; + } + timeout--; + _mali_osk_time_ubusydelay(100); + } +#endif //MALI_PMM_RUNTIME_JOB_CONTROL_ON + } + else + { +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON + MALI_DEBUG_PRINT( 4,("_mali_osk_pmm_dev_idle\n")); + _mali_osk_pm_dev_idle(); +#else //MALI_PMM_RUNTIME_JOB_CONTROL_ON + void __iomem *status; + u32 timeout; + __raw_writel(0, S5P_PMU_G3D_CONF); + + status = S5P_PMU_G3D_CONF + 0x4; + /* Wait max 1ms */ + timeout = 10; + while (__raw_readl(status) & S5P_INT_LOCAL_PWR_EN) + { + if (timeout == 0) { + MALI_PRINTF(("Power domain disable failed.\n" )); + return -ETIMEDOUT; + } + timeout--; + _mali_osk_time_ubusydelay( 100); + } +#endif //MALI_PMM_RUNTIME_JOB_CONTROL_ON + } + + MALI_SUCCESS; +} + +_mali_osk_errcode_t mali_platform_init() +{ + MALI_CHECK(init_mali_clock(), _MALI_OSK_ERR_FAULT); +#if MALI_VOLTAGE_LOCK + _mali_osk_atomic_init(&voltage_lock_status, 0); +#endif +#if MALI_DVFS_ENABLED + if (!clk_register_map) clk_register_map = _mali_osk_mem_mapioregion( CLK_DIV_STAT_G3D, 0x20, CLK_DESC ); + if(!init_mali_dvfs_status(MALI_DVFS_DEFAULT_STEP)) + MALI_DEBUG_PRINT(1, ("mali_platform_init failed\n")); +#endif + + MALI_SUCCESS; +} + +_mali_osk_errcode_t mali_platform_deinit() +{ + deinit_mali_clock(); +#if MALI_VOLTAGE_LOCK + _mali_osk_atomic_term(&voltage_lock_status); +#endif +#if MALI_DVFS_ENABLED + deinit_mali_dvfs_status(); + if (clk_register_map ) + { + _mali_osk_mem_unmapioregion(CLK_DIV_STAT_G3D, 0x20, clk_register_map); + clk_register_map=0; + } +#endif + + MALI_SUCCESS; +} + +_mali_osk_errcode_t mali_platform_powerdown(u32 cores) +{ + trace_printk("SPI_GPU_PWR Idle\n"); + MALI_DEBUG_PRINT(3,("power down is called in mali_platform_powerdown state %x core %x \n", gpu_power_state, cores)); + + if (gpu_power_state != 0) // power down after state is 0 + { + gpu_power_state = gpu_power_state & (~cores); + if (gpu_power_state == 0) + { + MALI_DEBUG_PRINT( 3,("disable clock\n")); + disable_mali_clocks(); + } + } + else + { + MALI_PRINT(("mali_platform_powerdown gpu_power_state == 0 and cores %x \n", cores)); + } + + MALI_SUCCESS; +} + +_mali_osk_errcode_t mali_platform_powerup(u32 cores) +{ + trace_printk("SPI_GPU_PWR Start\n"); + MALI_DEBUG_PRINT(3,("power up is called in mali_platform_powerup state %x core %x \n", gpu_power_state, cores)); + + if (gpu_power_state == 0) // power up only before state is 0 + { + gpu_power_state = gpu_power_state | cores; + + if (gpu_power_state != 0) + { + MALI_DEBUG_PRINT(4,("enable clock \n")); + enable_mali_clocks(); + } + } + else + { + gpu_power_state = gpu_power_state | cores; + } + + MALI_SUCCESS; +} + +void mali_gpu_utilization_handler(u32 utilization) +{ + if (bPoweroff==0) + { +#if MALI_DVFS_ENABLED + if(!mali_dvfs_handler(utilization)) + MALI_DEBUG_PRINT(1,( "error on mali dvfs status in utilization\n")); +#endif + } +} + +#if MALI_POWER_MGMT_TEST_SUITE +u32 pmu_get_power_up_down_info(void) +{ + return 4095; +} + +#endif + +_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode) +{ + switch (power_mode) + { + case MALI_POWER_MODE_ON: + MALI_DEBUG_PRINT(1, ("Mali platform: Got MALI_POWER_MODE_ON event, %s\n", bPoweroff ? "powering on" : "already on")); + if (bPoweroff == 1) + { + /** If run time power management is used, donot call this function */ +#ifndef CONFIG_PM_RUNTIME + g3d_power_domain_control(1); +#endif + + MALI_DEBUG_PRINT(4,("enable clock \n")); + enable_mali_clocks(); +#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE| MALI_PROFILING_EVENT_CHANNEL_GPU|MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0); +#endif + //MALI_PRINTF(("Mali Platform powered up")); + gpu_power_state=1; + bPoweroff=0; + } + break; + case MALI_POWER_MODE_LIGHT_SLEEP: + case MALI_POWER_MODE_DEEP_SLEEP: + MALI_DEBUG_PRINT(1, ("Mali platform: Got %s event, %s\n", + power_mode == MALI_POWER_MODE_LIGHT_SLEEP ? "MALI_POWER_MODE_LIGHT_SLEEP" : "MALI_POWER_MODE_DEEP_SLEEP", + bPoweroff ? "already off" : "powering off")); + if (bPoweroff == 0) + { + disable_mali_clocks(); +#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE| MALI_PROFILING_EVENT_CHANNEL_GPU|MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, 0, 0, 0, 0, 0); +#endif + +#ifndef CONFIG_PM_RUNTIME + g3d_power_domain_control(0); +#endif + + //MALI_PRINTF(("Mali Platform powered down")); + gpu_power_state=0; + bPoweroff=1; + } + + break; + } + MALI_SUCCESS; +} + +#if MALI_VOLTAGE_LOCK +int mali_voltage_lock_push(int lock_vol) +{ + int prev_status = _mali_osk_atomic_read(&voltage_lock_status); + + if (prev_status < 0) { + MALI_PRINT(("gpu voltage lock status is not valid for push\n")); + return -1; + } + if (prev_status == 0) { + mali_lock_vol = lock_vol; + if (mali_gpu_vol < mali_lock_vol) + mali_regulator_set_voltage(mali_lock_vol, mali_lock_vol); + } else { + MALI_PRINT(("gpu voltage lock status is already pushed, current lock voltage : %d\n", mali_lock_vol)); + return -1; + } + + return _mali_osk_atomic_inc_return(&voltage_lock_status); +} + +int mali_voltage_lock_pop(void) +{ + if (_mali_osk_atomic_read(&voltage_lock_status) <= 0) { + MALI_PRINT(("gpu voltage lock status is not valid for pop\n")); + return -1; + } + return _mali_osk_atomic_dec_return(&voltage_lock_status); +} + +int mali_voltage_lock_init(void) +{ + mali_vol_lock_flag = MALI_TRUE; + + MALI_SUCCESS; +} +#endif diff --git a/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c b/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c new file mode 100644 index 0000000..cc1164e --- /dev/null +++ b/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c @@ -0,0 +1,847 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_platform_dvfs.c + * Platform specific Mali driver dvfs functions + */ + +#include "mali_kernel_common.h" +#include "mali_osk.h" +#include "mali_platform.h" + +#include +#include +#include +#include + +#include + +#include "mali_device_pause_resume.h" +#include + +#define MAX_MALI_DVFS_STEPS 5 +#define MALI_DVFS_WATING 10 // msec + +#ifdef CONFIG_CPU_FREQ +#include +#define EXYNOS4_ASV_ENABLED +#endif + +#include + +static int bMaliDvfsRun=0; + +static _mali_osk_atomic_t bottomlock_status; +int bottom_lock_step = 0; + +typedef struct mali_dvfs_tableTag{ + unsigned int clock; + unsigned int freq; + unsigned int vol; +}mali_dvfs_table; + +typedef struct mali_dvfs_statusTag{ + unsigned int currentStep; + mali_dvfs_table * pCurrentDvfs; + +}mali_dvfs_currentstatus; + +typedef struct mali_dvfs_thresholdTag{ + unsigned int downthreshold; + unsigned int upthreshold; +}mali_dvfs_threshold_table; + +typedef struct mali_dvfs_staycount{ + unsigned int staycount; +}mali_dvfs_staycount_table; + +typedef struct mali_dvfs_stepTag{ + int clk; + int vol; +}mali_dvfs_step; + +mali_dvfs_step step[MALI_DVFS_STEPS]={ + /*step 0 clk*/ {160, 875000}, +#if (MALI_DVFS_STEPS > 1) + /*step 1 clk*/ {266, 900000}, +#if (MALI_DVFS_STEPS > 2) + /*step 2 clk*/ {350, 950000}, +#if (MALI_DVFS_STEPS > 3) + /*step 3 clk*/ {440, 1025000}, +#if (MALI_DVFS_STEPS > 4) + /*step 4 clk*/ {533, 1075000} +#endif +#endif +#endif +#endif +}; + +mali_dvfs_staycount_table mali_dvfs_staycount[MALI_DVFS_STEPS]={ + /*step 0*/{0}, +#if (MALI_DVFS_STEPS > 1) + /*step 1*/{0}, +#if (MALI_DVFS_STEPS > 2) + /*step 2*/{0}, +#if (MALI_DVFS_STEPS > 3) + /*step 3*/{0}, +#if (MALI_DVFS_STEPS > 4) + /*step 4*/{0} +#endif +#endif +#endif +#endif +}; + +/* dvfs information */ +// L0 = 533Mhz, 1.075V +// L1 = 440Mhz, 1.025V +// L2 = 350Mhz, 0.95V +// L3 = 266Mhz, 0.90V +// L4 = 160Mhz, 0.875V + +int step0_clk = 160; +int step0_vol = 875000; +#if (MALI_DVFS_STEPS > 1) +int step1_clk = 266; +int step1_vol = 900000; +int step0_up = 70; +int step1_down = 62; +#if (MALI_DVFS_STEPS > 2) +int step2_clk = 350; +int step2_vol = 950000; +int step1_up = 90; +int step2_down = 85; +#if (MALI_DVFS_STEPS > 3) +int step3_clk = 440; +int step3_vol = 1025000; +int step2_up = 90; +int step3_down = 85; +#if (MALI_DVFS_STEPS > 4) +int step4_clk = 533; +int step4_vol = 1075000; +int step3_up = 90; +int step4_down = 95; +#endif +#endif +#endif +#endif + +mali_dvfs_table mali_dvfs_all[MAX_MALI_DVFS_STEPS]={ + {160 ,1000000 , 875000}, + {266 ,1000000 , 900000}, + {350 ,1000000 , 950000}, + {440 ,1000000 , 1025000}, + {533 ,1000000 , 1075000} }; + +mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={ + {160 ,1000000 , 875000}, +#if (MALI_DVFS_STEPS > 1) + {266 ,1000000 , 900000}, +#if (MALI_DVFS_STEPS > 2) + {350 ,1000000 , 950000}, +#if (MALI_DVFS_STEPS > 3) + {440 ,1000000 ,1025000}, +#if (MALI_DVFS_STEPS > 4) + {533 ,1000000 ,1075000} +#endif +#endif +#endif +#endif +}; + +mali_dvfs_threshold_table mali_dvfs_threshold[MALI_DVFS_STEPS]={ + {0 , 70}, +#if (MALI_DVFS_STEPS > 1) + {62 , 90}, +#if (MALI_DVFS_STEPS > 2) + {85 , 90}, +#if (MALI_DVFS_STEPS > 3) + {85 ,90}, +#if (MALI_DVFS_STEPS > 4) + {95 ,100} +#endif +#endif +#endif +#endif +}; + +#ifdef EXYNOS4_ASV_ENABLED +#define ASV_LEVEL 12 /* ASV0, 1, 11 is reserved */ +#define ASV_LEVEL_PRIME 13 /* ASV0, 1, 12 is reserved */ + +static unsigned int asv_3d_volt_9_table_1ghz_type[MALI_DVFS_STEPS-1][ASV_LEVEL] = { + { 975000, 950000, 950000, 950000, 925000, 925000, 925000, 900000, 900000, 900000, 900000, 875000}, /* L3(160Mhz) */ +#if (MALI_DVFS_STEPS > 1) + { 1000000, 975000, 975000, 975000, 950000, 950000, 950000, 900000, 900000, 900000, 900000, 875000}, /* L2(266Mhz) */ +#if (MALI_DVFS_STEPS > 2) + { 1075000, 1050000, 1050000, 1050000, 1000000, 1000000, 1000000, 975000, 975000, 975000, 975000, 925000}, /* L1(350Mhz) */ +#if (MALI_DVFS_STEPS > 3) + { 1125000, 1100000, 1100000, 1100000, 1075000, 1075000, 1075000, 1025000, 1025000, 1025000, 1025000, 975000}, /* L0(440Mhz) */ +#endif +#endif +#endif +}; + +static unsigned int asv_3d_volt_9_table[MALI_DVFS_STEPS-1][ASV_LEVEL] = { + { 950000, 925000, 900000, 900000, 875000, 875000, 875000, 875000, 850000, 850000, 850000, 850000}, /* L3(160Mhz) */ +#if (MALI_DVFS_STEPS > 1) + { 975000, 950000, 925000, 925000, 925000, 900000, 900000, 875000, 875000, 875000, 875000, 850000}, /* L2(266Mhz) */ +#if (MALI_DVFS_STEPS > 2) + { 1050000, 1025000, 1000000, 1000000, 975000, 950000, 950000, 950000, 925000, 925000, 925000, 900000}, /* L1(350Mhz) */ +#if (MALI_DVFS_STEPS > 3) + { 1100000, 1075000, 1050000, 1050000, 1050000, 1025000, 1025000, 1000000, 1000000, 1000000, 975000, 950000}, /* L0(440Mhz) */ +#endif +#endif +#endif +}; + +static unsigned int asv_3d_volt_9_table_for_prime[MALI_DVFS_STEPS][ASV_LEVEL_PRIME] = { + { 950000, 937500, 925000, 912500, 900000, 887500, 875000, 862500, 875000, 862500, 850000, 850000}, /* L4(160Mhz) */ +#if (MALI_DVFS_STEPS > 1) + { 975000, 962500, 950000, 937500, 925000, 912500, 900000, 887500, 900000, 887500, 875000, 862500}, /* L3(266Mhz) */ +#if (MALI_DVFS_STEPS > 2) + { 1025000, 1012500, 1000000, 987500, 975000, 962500, 950000, 937500, 950000, 937500, 925000, 912500}, /* L2(350Mhz) */ +#if (MALI_DVFS_STEPS > 3) + { 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 1012500, 1000000, 987500, 975000}, /* L1(440Mhz) */ +#if (MALI_DVFS_STEPS > 4) + { 1150000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1087500, 1075000, 1062500, 1050000}, /* L0(600Mhz) */ +#endif +#endif +#endif +#endif +}; +#endif /* ASV_LEVEL */ + +/*dvfs status*/ +mali_dvfs_currentstatus maliDvfsStatus; +int mali_dvfs_control=0; + +static u32 mali_dvfs_utilization = 255; + +static void mali_dvfs_work_handler(struct work_struct *w); + +static struct workqueue_struct *mali_dvfs_wq = 0; +extern mali_io_address clk_register_map; +extern _mali_osk_lock_t *mali_dvfs_lock; + +int mali_runtime_resumed = -1; + +static DECLARE_WORK(mali_dvfs_work, mali_dvfs_work_handler); + +/* lock/unlock CPU freq by Mali */ +#include +#include + +atomic_t mali_cpufreq_lock; + +int cpufreq_lock_by_mali(unsigned int freq) +{ +#ifdef CONFIG_EXYNOS4_CPUFREQ +/* #if defined(CONFIG_CPU_FREQ) && defined(CONFIG_ARCH_EXYNOS4) */ + unsigned int level; + + if (atomic_read(&mali_cpufreq_lock) == 0) { + if (exynos_cpufreq_get_level(freq * 1000, &level)) { + printk(KERN_ERR + "Mali: failed to get cpufreq level for %dMHz", + freq); + return -EINVAL; + } + + if (exynos_cpufreq_lock(DVFS_LOCK_ID_G3D, level)) { + printk(KERN_ERR + "Mali: failed to cpufreq lock for L%d", level); + return -EINVAL; + } + + atomic_set(&mali_cpufreq_lock, 1); + printk(KERN_DEBUG "Mali: cpufreq locked on <%d>%dMHz\n", level, + freq); + } +#endif + return 0; +} + +void cpufreq_unlock_by_mali(void) +{ +#ifdef CONFIG_EXYNOS4_CPUFREQ +/* #if defined(CONFIG_CPU_FREQ) && defined(CONFIG_ARCH_EXYNOS4) */ + if (atomic_read(&mali_cpufreq_lock) == 1) { + exynos_cpufreq_lock_free(DVFS_LOCK_ID_G3D); + atomic_set(&mali_cpufreq_lock, 0); + printk(KERN_DEBUG "Mali: cpufreq locked off\n"); + } +#endif +} + +static unsigned int get_mali_dvfs_status(void) +{ + return maliDvfsStatus.currentStep; +} +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON +int get_mali_dvfs_control_status(void) +{ + return mali_dvfs_control; +} + +mali_bool set_mali_dvfs_current_step(unsigned int step) +{ + _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); + maliDvfsStatus.currentStep = step % MAX_MALI_DVFS_STEPS; + if (step >= MAX_MALI_DVFS_STEPS) + mali_runtime_resumed = maliDvfsStatus.currentStep; + _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); + return MALI_TRUE; +} +#endif +static mali_bool set_mali_dvfs_status(u32 step,mali_bool boostup) +{ + u32 validatedStep=step; + int err; + +#ifdef CONFIG_REGULATOR + if (mali_regulator_get_usecount() == 0) { + MALI_DEBUG_PRINT(1, ("regulator use_count is 0 \n")); + return MALI_FALSE; + } +#endif + + if (boostup) { +#ifdef CONFIG_REGULATOR + /*change the voltage*/ + mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol); +#endif + /*change the clock*/ + mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq); + } else { + /*change the clock*/ + mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq); +#ifdef CONFIG_REGULATOR + /*change the voltage*/ + mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol); +#endif + } + +#ifdef EXYNOS4_ASV_ENABLED + if (samsung_rev() < EXYNOS4412_REV_2_0) { + if (mali_dvfs[step].clock == 160) + exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_100V); + else + exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_130V); + } +#endif + + + set_mali_dvfs_current_step(validatedStep); + /*for future use*/ + maliDvfsStatus.pCurrentDvfs = &mali_dvfs[validatedStep]; + +#if CPUFREQ_LOCK_DURING_440 + /* lock/unlock CPU freq by Mali */ + if (mali_dvfs[step].clock == 440) + err = cpufreq_lock_by_mali(1200); + else + cpufreq_unlock_by_mali(); +#endif + + return MALI_TRUE; +} + +static void mali_platform_wating(u32 msec) +{ + /*sample wating + change this in the future with proper check routine. + */ + unsigned int read_val; + while(1) { + read_val = _mali_osk_mem_ioread32(clk_register_map, 0x00); + if ((read_val & 0x8000)==0x0000) break; + _mali_osk_time_ubusydelay(100); // 1000 -> 100 : 20101218 + } + /* _mali_osk_time_ubusydelay(msec*1000);*/ +} + +static mali_bool change_mali_dvfs_status(u32 step, mali_bool boostup ) +{ + + MALI_DEBUG_PRINT(1, ("> change_mali_dvfs_status: %d, %d \n",step, boostup)); + + if (!set_mali_dvfs_status(step, boostup)) { + MALI_DEBUG_PRINT(1, ("error on set_mali_dvfs_status: %d, %d \n",step, boostup)); + return MALI_FALSE; + } + + /*wait until clock and voltage is stablized*/ + mali_platform_wating(MALI_DVFS_WATING); /*msec*/ + + return MALI_TRUE; +} + +#ifdef EXYNOS4_ASV_ENABLED +extern unsigned int exynos_result_of_asv; + +static mali_bool mali_dvfs_table_update(void) +{ + unsigned int i; + unsigned int step_num = MALI_DVFS_STEPS; + + if(samsung_rev() < EXYNOS4412_REV_2_0) + step_num = MALI_DVFS_STEPS - 1; + + if(soc_is_exynos4412()) { + if (exynos_armclk_max == 1000000) { + MALI_PRINT(("::C::exynos_result_of_asv : %d\n", exynos_result_of_asv)); + for (i = 0; i < step_num; i++) { + mali_dvfs[i].vol = asv_3d_volt_9_table_1ghz_type[i][exynos_result_of_asv]; + MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol)); + } + } else if(((is_special_flag() >> G3D_LOCK_FLAG) & 0x1) && (samsung_rev() >= EXYNOS4412_REV_2_0)) { + MALI_PRINT(("::L::exynos_result_of_asv : %d\n", exynos_result_of_asv)); + for (i = 0; i < step_num; i++) { + mali_dvfs[i].vol = asv_3d_volt_9_table_for_prime[i][exynos_result_of_asv] + 25000; + MALI_PRINT(("mali_dvfs[%d].vol = %d \n ", i, mali_dvfs[i].vol)); + } + } else if (samsung_rev() >= EXYNOS4412_REV_2_0) { + MALI_PRINT(("::P::exynos_result_of_asv : %d\n", exynos_result_of_asv)); + for (i = 0; i < step_num; i++) { + mali_dvfs[i].vol = asv_3d_volt_9_table_for_prime[i][exynos_result_of_asv]; + MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol)); + } + } else { + MALI_PRINT(("::Q::exynos_result_of_asv : %d\n", exynos_result_of_asv)); + for (i = 0; i < step_num; i++) { + mali_dvfs[i].vol = asv_3d_volt_9_table[i][exynos_result_of_asv]; + MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol)); + } + } + } + + return MALI_TRUE; +} +#endif + +static unsigned int decideNextStatus(unsigned int utilization) +{ + static unsigned int level = 0; // 0:stay, 1:up + static int mali_dvfs_clk = 0; + + if (mali_runtime_resumed >= 0) { + level = mali_runtime_resumed; + mali_runtime_resumed = -1; + } + + if (mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold + <= mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold) { + MALI_PRINT(("upthreadshold is smaller than downthreshold: %d < %d\n", + mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold, + mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold)); + return level; + } + + if (!mali_dvfs_control && level == maliDvfsStatus.currentStep) { + if (utilization > (int)(255 * mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold / 100) && + level < MALI_DVFS_STEPS - 1) { + level++; + if ((samsung_rev() < EXYNOS4412_REV_2_0) && (maliDvfsStatus.currentStep == 3)) { + level=get_mali_dvfs_status(); + } + } + if (utilization < (int)(255 * mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold / 100) && + level > 0) { + level--; + } + } else if (mali_dvfs_control == 999) { + int i = 0; + for (i = 0; i < MALI_DVFS_STEPS; i++) { + step[i].clk = mali_dvfs_all[i].clock; + } +#ifdef EXYNOS4_ASV_ENABLED + mali_dvfs_table_update(); +#endif + i = 0; + for (i = 0; i < MALI_DVFS_STEPS; i++) { + mali_dvfs[i].clock = step[i].clk; + } + mali_dvfs_control = 0; + level = 0; + + step0_clk = step[0].clk; + change_dvfs_tableset(step0_clk, 0); +#if (MALI_DVFS_STEPS > 1) + step1_clk = step[1].clk; + change_dvfs_tableset(step1_clk, 1); +#if (MALI_DVFS_STEPS > 2) + step2_clk = step[2].clk; + change_dvfs_tableset(step2_clk, 2); +#if (MALI_DVFS_STEPS > 3) + step3_clk = step[3].clk; + change_dvfs_tableset(step3_clk, 3); +#if (MALI_DVFS_STEPS > 4) + step4_clk = step[4].clk; + change_dvfs_tableset(step4_clk, 4); +#endif +#endif +#endif +#endif + } else if (mali_dvfs_control != mali_dvfs_clk && mali_dvfs_control != 999) { + if (mali_dvfs_control < mali_dvfs_all[1].clock && mali_dvfs_control > 0) { + int i = 0; + for (i = 0; i < MALI_DVFS_STEPS; i++) { + step[i].clk = mali_dvfs_all[0].clock; + } + maliDvfsStatus.currentStep = 0; + } else if (mali_dvfs_control < mali_dvfs_all[2].clock && mali_dvfs_control >= mali_dvfs_all[1].clock) { + int i = 0; + for (i = 0; i < MALI_DVFS_STEPS; i++) { + step[i].clk = mali_dvfs_all[1].clock; + } + maliDvfsStatus.currentStep = 1; + } else if (mali_dvfs_control < mali_dvfs_all[3].clock && mali_dvfs_control >= mali_dvfs_all[2].clock) { + int i = 0; + for (i = 0; i < MALI_DVFS_STEPS; i++) { + step[i].clk = mali_dvfs_all[2].clock; + } + maliDvfsStatus.currentStep = 2; + } else if (mali_dvfs_control < mali_dvfs_all[4].clock && mali_dvfs_control >= mali_dvfs_all[3].clock) { + int i = 0; + for (i = 0; i < MALI_DVFS_STEPS; i++) { + step[i].clk = mali_dvfs_all[3].clock; + } + maliDvfsStatus.currentStep = 3; + } else { + int i = 0; + for (i = 0; i < MALI_DVFS_STEPS; i++) { + step[i].clk = mali_dvfs_all[4].clock; + } + maliDvfsStatus.currentStep = 4; + } + step0_clk = step[0].clk; + change_dvfs_tableset(step0_clk, 0); +#if (MALI_DVFS_STEPS > 1) + step1_clk = step[1].clk; + change_dvfs_tableset(step1_clk, 1); +#if (MALI_DVFS_STEPS > 2) + step2_clk = step[2].clk; + change_dvfs_tableset(step2_clk, 2); +#if (MALI_DVFS_STEPS > 3) + step3_clk = step[3].clk; + change_dvfs_tableset(step3_clk, 3); +#if (MALI_DVFS_STEPS > 4) + step4_clk = step[4].clk; + change_dvfs_tableset(step4_clk, 4); +#endif +#endif +#endif +#endif + level = maliDvfsStatus.currentStep; + } + + mali_dvfs_clk = mali_dvfs_control; + + if (_mali_osk_atomic_read(&bottomlock_status) > 0) { + if (level < bottom_lock_step) + level = bottom_lock_step; + } + + return level; +} + +static mali_bool mali_dvfs_status(u32 utilization) +{ + unsigned int nextStatus = 0; + unsigned int curStatus = 0; + mali_bool boostup = MALI_FALSE; + static int stay_count = 0; +#ifdef EXYNOS4_ASV_ENABLED + static mali_bool asv_applied = MALI_FALSE; +#endif + + MALI_DEBUG_PRINT(1, ("> mali_dvfs_status: %d \n",utilization)); +#ifdef EXYNOS4_ASV_ENABLED + if (asv_applied == MALI_FALSE) { + mali_dvfs_table_update(); + change_mali_dvfs_status(1, 0); + asv_applied = MALI_TRUE; + + return MALI_TRUE; + } +#endif + + /*decide next step*/ + curStatus = get_mali_dvfs_status(); + nextStatus = decideNextStatus(utilization); + + MALI_DEBUG_PRINT(1, ("= curStatus %d, nextStatus %d, maliDvfsStatus.currentStep %d \n", curStatus, nextStatus, maliDvfsStatus.currentStep)); + + /*if next status is same with current status, don't change anything*/ + if ((curStatus != nextStatus && stay_count == 0)) { + /*check if boost up or not*/ + if (nextStatus > maliDvfsStatus.currentStep) boostup = 1; + + /*change mali dvfs status*/ + if (!change_mali_dvfs_status(nextStatus,boostup)) { + MALI_DEBUG_PRINT(1, ("error on change_mali_dvfs_status \n")); + return MALI_FALSE; + } + stay_count = mali_dvfs_staycount[maliDvfsStatus.currentStep].staycount; + } else { + if (stay_count > 0) + stay_count--; + } + + return MALI_TRUE; +} + + + +int mali_dvfs_is_running(void) +{ + return bMaliDvfsRun; + +} + + + +void mali_dvfs_late_resume(void) +{ + // set the init clock as low when resume + set_mali_dvfs_status(0,0); +} + + +static void mali_dvfs_work_handler(struct work_struct *w) +{ + int change_clk = 0; + int change_step = 0; + bMaliDvfsRun=1; + + /* dvfs table change when clock was changed */ + if (step0_clk != mali_dvfs[0].clock) { + MALI_PRINT(("::: step0_clk change to %d Mhz\n", step0_clk)); + change_clk = step0_clk; + change_step = 0; + step0_clk = change_dvfs_tableset(change_clk, change_step); + } +#if (MALI_DVFS_STEPS > 1) + if (step1_clk != mali_dvfs[1].clock) { + MALI_PRINT(("::: step1_clk change to %d Mhz\n", step1_clk)); + change_clk = step1_clk; + change_step = 1; + step1_clk = change_dvfs_tableset(change_clk, change_step); + } + if (step0_up != mali_dvfs_threshold[0].upthreshold) { + MALI_PRINT(("::: step0_up change to %d %\n", step0_up)); + mali_dvfs_threshold[0].upthreshold = step0_up; + } + if (step1_down != mali_dvfs_threshold[1].downthreshold) { + MALI_PRINT((":::step1_down change to %d %\n", step1_down)); + mali_dvfs_threshold[1].downthreshold = step1_down; + } +#if (MALI_DVFS_STEPS > 2) + if (step2_clk != mali_dvfs[2].clock) { + MALI_PRINT(("::: step2_clk change to %d Mhz\n", step2_clk)); + change_clk = step2_clk; + change_step = 2; + step2_clk = change_dvfs_tableset(change_clk, change_step); + } + if (step1_up != mali_dvfs_threshold[1].upthreshold) { + MALI_PRINT((":::step1_up change to %d %\n", step1_up)); + mali_dvfs_threshold[1].upthreshold = step1_up; + } + if (step2_down != mali_dvfs_threshold[2].downthreshold) { + MALI_PRINT((":::step2_down change to %d %\n", step2_down)); + mali_dvfs_threshold[2].downthreshold = step2_down; + } +#if (MALI_DVFS_STEPS > 3) + if (step3_clk != mali_dvfs[3].clock) { + MALI_PRINT(("::: step3_clk change to %d Mhz\n", step3_clk)); + change_clk = step3_clk; + change_step = 3; + step3_clk = change_dvfs_tableset(change_clk, change_step); + } + if (step2_up != mali_dvfs_threshold[2].upthreshold) { + MALI_PRINT((":::step2_up change to %d %\n", step2_up)); + mali_dvfs_threshold[2].upthreshold = step2_up; + } + if (step3_down != mali_dvfs_threshold[3].downthreshold) { + MALI_PRINT((":::step3_down change to %d %\n", step3_down)); + mali_dvfs_threshold[3].downthreshold = step3_down; + } +#if (MALI_DVFS_STEPS > 4) + if (step4_clk != mali_dvfs[4].clock) { + MALI_PRINT(("::: step4_clk change to %d Mhz\n", step4_clk)); + change_clk = step4_clk; + change_step = 4; + step4_clk = change_dvfs_tableset(change_clk, change_step); + } + if (step3_up != mali_dvfs_threshold[3].upthreshold) { + MALI_PRINT((":::step3_up change to %d %\n", step3_up)); + mali_dvfs_threshold[3].upthreshold = step3_up; + } + if (step4_down != mali_dvfs_threshold[4].downthreshold) { + MALI_PRINT((":::step4_down change to %d %\n", step4_down)); + mali_dvfs_threshold[4].downthreshold = step4_down; + } +#endif +#endif +#endif +#endif + + +#ifdef DEBUG + mali_dvfs[0].vol = step0_vol; + mali_dvfs[1].vol = step1_vol; + mali_dvfs[2].vol = step2_vol; + mali_dvfs[3].vol = step3_vol; + mali_dvfs[4].vol = step4_vol; +#endif + MALI_DEBUG_PRINT(3, ("=== mali_dvfs_work_handler\n")); + + if (!mali_dvfs_status(mali_dvfs_utilization)) + MALI_DEBUG_PRINT(1,( "error on mali dvfs status in mali_dvfs_work_handler")); + + bMaliDvfsRun=0; +} + +mali_bool init_mali_dvfs_status(int step) +{ + /*default status + add here with the right function to get initilization value. + */ + if (!mali_dvfs_wq) + mali_dvfs_wq = create_singlethread_workqueue("mali_dvfs"); + + _mali_osk_atomic_init(&bottomlock_status, 0); + + /*add a error handling here*/ + set_mali_dvfs_current_step(step); + + return MALI_TRUE; +} + +void deinit_mali_dvfs_status(void) +{ + if (mali_dvfs_wq) + destroy_workqueue(mali_dvfs_wq); + + _mali_osk_atomic_term(&bottomlock_status); + + mali_dvfs_wq = NULL; +} + +mali_bool mali_dvfs_handler(u32 utilization) +{ + mali_dvfs_utilization = utilization; + queue_work_on(0, mali_dvfs_wq,&mali_dvfs_work); + + /*add error handle here*/ + return MALI_TRUE; +} + +int change_dvfs_tableset(int change_clk, int change_step) +{ + int err; + + if (change_clk < mali_dvfs_all[1].clock) { + mali_dvfs[change_step].clock = mali_dvfs_all[0].clock; + } else if (change_clk < mali_dvfs_all[2].clock && change_clk >= mali_dvfs_all[1].clock) { + mali_dvfs[change_step].clock = mali_dvfs_all[1].clock; + } else if (change_clk < mali_dvfs_all[3].clock && change_clk >= mali_dvfs_all[2].clock) { + mali_dvfs[change_step].clock = mali_dvfs_all[2].clock; + } else if (change_clk < mali_dvfs_all[4].clock && change_clk >= mali_dvfs_all[3].clock) { + mali_dvfs[change_step].clock = mali_dvfs_all[3].clock; + } else { + mali_dvfs[change_step].clock = mali_dvfs_all[4].clock; + } + + MALI_PRINT((":::mali dvfs step %d clock and voltage = %d Mhz, %d V\n",change_step, mali_dvfs[change_step].clock, mali_dvfs[change_step].vol)); + + if (maliDvfsStatus.currentStep == change_step) { +#ifdef CONFIG_REGULATOR + /*change the voltage*/ + mali_regulator_set_voltage(mali_dvfs[change_step].vol, mali_dvfs[change_step].vol); +#endif + /*change the clock*/ + mali_clk_set_rate(mali_dvfs[change_step].clock, mali_dvfs[change_step].freq); + +#if CPUFREQ_LOCK_DURING_440 + /* lock/unlock CPU freq by Mali */ + if (mali_dvfs[change_step].clock == 440) + err = cpufreq_lock_by_mali(1200); + else + cpufreq_unlock_by_mali(); +#endif + } + + return mali_dvfs[change_step].clock; +} + +void mali_default_step_set(int step, mali_bool boostup) +{ + mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq); + + if (maliDvfsStatus.currentStep == 1) + set_mali_dvfs_status(step, boostup); +} + +int mali_dvfs_bottom_lock_push(int lock_step) +{ + int prev_status = _mali_osk_atomic_read(&bottomlock_status); + + if (prev_status < 0) { + MALI_PRINT(("gpu bottom lock status is not valid for push\n")); + return -1; + } + if (bottom_lock_step < lock_step) { + bottom_lock_step = lock_step; + if (get_mali_dvfs_status() < lock_step) { + mali_regulator_set_voltage(mali_dvfs[lock_step].vol, mali_dvfs[lock_step].vol); + mali_clk_set_rate(mali_dvfs[lock_step].clock, mali_dvfs[lock_step].freq); + set_mali_dvfs_current_step(lock_step); + } + } + return _mali_osk_atomic_inc_return(&bottomlock_status); +} + +int mali_dvfs_bottom_lock_pop(void) +{ + int prev_status = _mali_osk_atomic_read(&bottomlock_status); + if (prev_status <= 0) { + MALI_PRINT(("gpu bottom lock status is not valid for pop\n")); + return -1; + } else if (prev_status == 1) { + bottom_lock_step = 0; + MALI_PRINT(("gpu bottom lock release\n")); + } + + return _mali_osk_atomic_dec_return(&bottomlock_status); +} + +int mali_dvfs_get_vol(int step) +{ + step = step % MAX_MALI_DVFS_STEPS; + MALI_DEBUG_ASSERT(step= vol) + return mali_dvfs[i].vol; + } + MALI_PRINT(("Failed to get voltage from mali_dvfs table, maximum voltage is %d uV\n", mali_dvfs[MALI_DVFS_STEPS-1].vol)); + return 0; +} +#endif diff --git a/drivers/media/video/samsung/mali/regs/mali_200_regs.h b/drivers/media/video/samsung/mali/regs/mali_200_regs.h new file mode 100644 index 0000000..59e92c8 --- /dev/null +++ b/drivers/media/video/samsung/mali/regs/mali_200_regs.h @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MALI200_REGS_H_ +#define _MALI200_REGS_H_ + +/** + * Enum for management register addresses. + */ +enum mali200_mgmt_reg +{ + MALI200_REG_ADDR_MGMT_VERSION = 0x1000, + MALI200_REG_ADDR_MGMT_CURRENT_REND_LIST_ADDR = 0x1004, + MALI200_REG_ADDR_MGMT_STATUS = 0x1008, + MALI200_REG_ADDR_MGMT_CTRL_MGMT = 0x100c, + + MALI200_REG_ADDR_MGMT_INT_RAWSTAT = 0x1020, + MALI200_REG_ADDR_MGMT_INT_CLEAR = 0x1024, + MALI200_REG_ADDR_MGMT_INT_MASK = 0x1028, + MALI200_REG_ADDR_MGMT_INT_STATUS = 0x102c, + + MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW = 0x1044, + + MALI200_REG_ADDR_MGMT_BUS_ERROR_STATUS = 0x1050, + + MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE = 0x1080, + MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC = 0x1084, + MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE = 0x108c, + + MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE = 0x10a0, + MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC = 0x10a4, + MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE = 0x10ac, + + MALI200_REG_SIZEOF_REGISTER_BANK = 0x10f0 + +}; + +#define MALI200_REG_VAL_PERF_CNT_ENABLE 1 + +enum mali200_mgmt_ctrl_mgmt { + MALI200_REG_VAL_CTRL_MGMT_STOP_BUS = (1<<0), +#if defined(USING_MALI200) + MALI200_REG_VAL_CTRL_MGMT_FLUSH_CACHES = (1<<3), +#endif + MALI200_REG_VAL_CTRL_MGMT_FORCE_RESET = (1<<5), + MALI200_REG_VAL_CTRL_MGMT_START_RENDERING = (1<<6), +#if defined(USING_MALI400) || defined(USING_MALI450) + MALI400PP_REG_VAL_CTRL_MGMT_SOFT_RESET = (1<<7), +#endif +}; + +enum mali200_mgmt_irq { + MALI200_REG_VAL_IRQ_END_OF_FRAME = (1<<0), + MALI200_REG_VAL_IRQ_END_OF_TILE = (1<<1), + MALI200_REG_VAL_IRQ_HANG = (1<<2), + MALI200_REG_VAL_IRQ_FORCE_HANG = (1<<3), + MALI200_REG_VAL_IRQ_BUS_ERROR = (1<<4), + MALI200_REG_VAL_IRQ_BUS_STOP = (1<<5), + MALI200_REG_VAL_IRQ_CNT_0_LIMIT = (1<<6), + MALI200_REG_VAL_IRQ_CNT_1_LIMIT = (1<<7), + MALI200_REG_VAL_IRQ_WRITE_BOUNDARY_ERROR = (1<<8), + MALI400PP_REG_VAL_IRQ_INVALID_PLIST_COMMAND = (1<<9), + MALI400PP_REG_VAL_IRQ_CALL_STACK_UNDERFLOW = (1<<10), + MALI400PP_REG_VAL_IRQ_CALL_STACK_OVERFLOW = (1<<11), + MALI400PP_REG_VAL_IRQ_RESET_COMPLETED = (1<<12), +}; + +#if defined(USING_MALI200) +#define MALI200_REG_VAL_IRQ_MASK_ALL ((enum mali200_mgmt_irq) (\ + MALI200_REG_VAL_IRQ_END_OF_FRAME |\ + MALI200_REG_VAL_IRQ_END_OF_TILE |\ + MALI200_REG_VAL_IRQ_HANG |\ + MALI200_REG_VAL_IRQ_FORCE_HANG |\ + MALI200_REG_VAL_IRQ_BUS_ERROR |\ + MALI200_REG_VAL_IRQ_BUS_STOP |\ + MALI200_REG_VAL_IRQ_CNT_0_LIMIT |\ + MALI200_REG_VAL_IRQ_CNT_1_LIMIT |\ + MALI200_REG_VAL_IRQ_WRITE_BOUNDARY_ERROR)) +#elif defined(USING_MALI400) || defined(USING_MALI450) +#define MALI200_REG_VAL_IRQ_MASK_ALL ((enum mali200_mgmt_irq) (\ + MALI200_REG_VAL_IRQ_END_OF_FRAME |\ + MALI200_REG_VAL_IRQ_END_OF_TILE |\ + MALI200_REG_VAL_IRQ_HANG |\ + MALI200_REG_VAL_IRQ_FORCE_HANG |\ + MALI200_REG_VAL_IRQ_BUS_ERROR |\ + MALI200_REG_VAL_IRQ_BUS_STOP |\ + MALI200_REG_VAL_IRQ_CNT_0_LIMIT |\ + MALI200_REG_VAL_IRQ_CNT_1_LIMIT |\ + MALI200_REG_VAL_IRQ_WRITE_BOUNDARY_ERROR |\ + MALI400PP_REG_VAL_IRQ_INVALID_PLIST_COMMAND |\ + MALI400PP_REG_VAL_IRQ_CALL_STACK_UNDERFLOW |\ + MALI400PP_REG_VAL_IRQ_CALL_STACK_OVERFLOW |\ + MALI400PP_REG_VAL_IRQ_RESET_COMPLETED)) +#else +#error "No supported mali core defined" +#endif + +#if defined(USING_MALI200) +#define MALI200_REG_VAL_IRQ_MASK_USED ((enum mali200_mgmt_irq) (\ + MALI200_REG_VAL_IRQ_END_OF_FRAME |\ + MALI200_REG_VAL_IRQ_HANG |\ + MALI200_REG_VAL_IRQ_FORCE_HANG |\ + MALI200_REG_VAL_IRQ_BUS_ERROR |\ + MALI200_REG_VAL_IRQ_WRITE_BOUNDARY_ERROR)) +#elif defined(USING_MALI400) || defined(USING_MALI450) +#define MALI200_REG_VAL_IRQ_MASK_USED ((enum mali200_mgmt_irq) (\ + MALI200_REG_VAL_IRQ_END_OF_FRAME |\ + MALI200_REG_VAL_IRQ_HANG |\ + MALI200_REG_VAL_IRQ_FORCE_HANG |\ + MALI200_REG_VAL_IRQ_BUS_ERROR |\ + MALI200_REG_VAL_IRQ_BUS_STOP |\ + MALI200_REG_VAL_IRQ_WRITE_BOUNDARY_ERROR |\ + MALI400PP_REG_VAL_IRQ_INVALID_PLIST_COMMAND |\ + MALI400PP_REG_VAL_IRQ_CALL_STACK_UNDERFLOW |\ + MALI400PP_REG_VAL_IRQ_CALL_STACK_OVERFLOW)) +#else +#error "No supported mali core defined" +#endif + +#define MALI200_REG_VAL_IRQ_MASK_NONE ((enum mali200_mgmt_irq)(0)) + +enum mali200_mgmt_status { + MALI200_REG_VAL_STATUS_RENDERING_ACTIVE = (1<<0), + MALI200_REG_VAL_STATUS_BUS_STOPPED = (1<<4), +}; + +enum mali200_render_unit +{ + MALI200_REG_ADDR_FRAME = 0x0000, + MALI200_REG_ADDR_STACK = 0x0030 +}; + +#if defined(USING_MALI200) +#define MALI200_NUM_REGS_FRAME ((0x04C/4)+1) +#elif defined(USING_MALI400) +#define MALI200_NUM_REGS_FRAME ((0x058/4)+1) +#elif defined(USING_MALI450) +#define MALI200_NUM_REGS_FRAME ((0x058/4)+1) +#else +#error "No supported mali core defined" +#endif + +enum mali200_wb_unit { + MALI200_REG_ADDR_WB0 = 0x0100, + MALI200_REG_ADDR_WB1 = 0x0200, + MALI200_REG_ADDR_WB2 = 0x0300 +}; + +enum mali200_wb_unit_regs { + MALI200_REG_ADDR_WB_SOURCE_SELECT = 0x0000, +}; + +/** The number of registers in one single writeback unit */ +#ifndef MALI200_NUM_REGS_WBx +#define MALI200_NUM_REGS_WBx ((0x02C/4)+1) +#endif + +/* This should be in the top 16 bit of the version register of Mali PP */ +#define MALI200_PP_PRODUCT_ID 0xC807 +#define MALI300_PP_PRODUCT_ID 0xCE07 +#define MALI400_PP_PRODUCT_ID 0xCD07 +#define MALI450_PP_PRODUCT_ID 0xCF07 + + +#endif /* _MALI200_REGS_H_ */ diff --git a/drivers/media/video/samsung/mali/regs/mali_gp_regs.h b/drivers/media/video/samsung/mali/regs/mali_gp_regs.h new file mode 100644 index 0000000..21c83c0 --- /dev/null +++ b/drivers/media/video/samsung/mali/regs/mali_gp_regs.h @@ -0,0 +1,214 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MALIGP2_CONROL_REGS_H_ +#define _MALIGP2_CONROL_REGS_H_ + +/** + * These are the different geometry processor control registers. + * Their usage is to control and monitor the operation of the + * Vertex Shader and the Polygon List Builder in the geometry processor. + * Addresses are in 32-bit word relative sizes. + * @see [P0081] "Geometry Processor Data Structures" for details + */ + +typedef enum { + MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR = 0x00, + MALIGP2_REG_ADDR_MGMT_VSCL_END_ADDR = 0x04, + MALIGP2_REG_ADDR_MGMT_PLBUCL_START_ADDR = 0x08, + MALIGP2_REG_ADDR_MGMT_PLBUCL_END_ADDR = 0x0c, + MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR = 0x10, + MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR = 0x14, + MALIGP2_REG_ADDR_MGMT_CMD = 0x20, + MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT = 0x24, + MALIGP2_REG_ADDR_MGMT_INT_CLEAR = 0x28, + MALIGP2_REG_ADDR_MGMT_INT_MASK = 0x2C, + MALIGP2_REG_ADDR_MGMT_INT_STAT = 0x30, + MALIGP2_REG_ADDR_MGMT_WRITE_BOUND_LOW = 0x34, + MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE = 0x3C, + MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE = 0x40, + MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC = 0x44, + MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC = 0x48, + MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE = 0x4C, + MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE = 0x50, + MALIGP2_REG_ADDR_MGMT_STATUS = 0x68, + MALIGP2_REG_ADDR_MGMT_VERSION = 0x6C, + MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR_READ = 0x80, + MALIGP2_REG_ADDR_MGMT_PLBCL_START_ADDR_READ = 0x84, + MALIGP2_CONTR_AXI_BUS_ERROR_STAT = 0x94, + MALIGP2_REGISTER_ADDRESS_SPACE_SIZE = 0x98, +} maligp_reg_addr_mgmt_addr; + +#define MALIGP2_REG_VAL_PERF_CNT_ENABLE 1 + +/** + * Commands to geometry processor. + * @see MALIGP2_CTRL_REG_CMD + */ +typedef enum +{ + MALIGP2_REG_VAL_CMD_START_VS = (1<< 0), + MALIGP2_REG_VAL_CMD_START_PLBU = (1<< 1), + MALIGP2_REG_VAL_CMD_UPDATE_PLBU_ALLOC = (1<< 4), + MALIGP2_REG_VAL_CMD_RESET = (1<< 5), + MALIGP2_REG_VAL_CMD_FORCE_HANG = (1<< 6), + MALIGP2_REG_VAL_CMD_STOP_BUS = (1<< 9), +#if defined(USING_MALI400) || defined(USING_MALI450) + MALI400GP_REG_VAL_CMD_SOFT_RESET = (1<<10), +#endif +} mgp_contr_reg_val_cmd; + + +/** @defgroup MALIGP2_IRQ + * Interrupt status of geometry processor. + * @see MALIGP2_CTRL_REG_INT_RAWSTAT, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, + * MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_ADDR_MGMT_INT_STAT + * @{ + */ +#define MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST (1 << 0) +#define MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST (1 << 1) +#define MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM (1 << 2) +#define MALIGP2_REG_VAL_IRQ_VS_SEM_IRQ (1 << 3) +#define MALIGP2_REG_VAL_IRQ_PLBU_SEM_IRQ (1 << 4) +#define MALIGP2_REG_VAL_IRQ_HANG (1 << 5) +#define MALIGP2_REG_VAL_IRQ_FORCE_HANG (1 << 6) +#define MALIGP2_REG_VAL_IRQ_PERF_CNT_0_LIMIT (1 << 7) +#define MALIGP2_REG_VAL_IRQ_PERF_CNT_1_LIMIT (1 << 8) +#define MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR (1 << 9) +#define MALIGP2_REG_VAL_IRQ_SYNC_ERROR (1 << 10) +#define MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR (1 << 11) +#if defined(USING_MALI400) || defined(USING_MALI450) +#define MALI400GP_REG_VAL_IRQ_AXI_BUS_STOPPED (1 << 12) +#define MALI400GP_REG_VAL_IRQ_VS_INVALID_CMD (1 << 13) +#define MALI400GP_REG_VAL_IRQ_PLB_INVALID_CMD (1 << 14) +#define MALI400GP_REG_VAL_IRQ_RESET_COMPLETED (1 << 19) +#define MALI400GP_REG_VAL_IRQ_SEMAPHORE_UNDERFLOW (1 << 20) +#define MALI400GP_REG_VAL_IRQ_SEMAPHORE_OVERFLOW (1 << 21) +#define MALI400GP_REG_VAL_IRQ_PTR_ARRAY_OUT_OF_BOUNDS (1 << 22) +#elif !defined USING_MALI200 +#error "No supported mali core defined" +#endif + +/* Mask defining all IRQs in MaliGP2 */ +#if defined(USING_MALI200) +#define MALIGP2_REG_VAL_IRQ_MASK_ALL \ + (\ + MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | \ + MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST | \ + MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | \ + MALIGP2_REG_VAL_IRQ_VS_SEM_IRQ | \ + MALIGP2_REG_VAL_IRQ_PLBU_SEM_IRQ | \ + MALIGP2_REG_VAL_IRQ_HANG | \ + MALIGP2_REG_VAL_IRQ_FORCE_HANG | \ + MALIGP2_REG_VAL_IRQ_PERF_CNT_0_LIMIT | \ + MALIGP2_REG_VAL_IRQ_PERF_CNT_1_LIMIT | \ + MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR | \ + MALIGP2_REG_VAL_IRQ_SYNC_ERROR | \ + MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR) +#elif defined(USING_MALI400) || defined(USING_MALI450) +#define MALIGP2_REG_VAL_IRQ_MASK_ALL \ + (\ + MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | \ + MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST | \ + MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | \ + MALIGP2_REG_VAL_IRQ_VS_SEM_IRQ | \ + MALIGP2_REG_VAL_IRQ_PLBU_SEM_IRQ | \ + MALIGP2_REG_VAL_IRQ_HANG | \ + MALIGP2_REG_VAL_IRQ_FORCE_HANG | \ + MALIGP2_REG_VAL_IRQ_PERF_CNT_0_LIMIT | \ + MALIGP2_REG_VAL_IRQ_PERF_CNT_1_LIMIT | \ + MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR | \ + MALIGP2_REG_VAL_IRQ_SYNC_ERROR | \ + MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR | \ + MALI400GP_REG_VAL_IRQ_AXI_BUS_STOPPED | \ + MALI400GP_REG_VAL_IRQ_VS_INVALID_CMD | \ + MALI400GP_REG_VAL_IRQ_PLB_INVALID_CMD | \ + MALI400GP_REG_VAL_IRQ_RESET_COMPLETED | \ + MALI400GP_REG_VAL_IRQ_SEMAPHORE_UNDERFLOW | \ + MALI400GP_REG_VAL_IRQ_SEMAPHORE_OVERFLOW | \ + MALI400GP_REG_VAL_IRQ_PTR_ARRAY_OUT_OF_BOUNDS) +#else +#error "No supported mali core defined" +#endif + +/* Mask defining the IRQs in MaliGP2 which we use*/ +#if defined(USING_MALI200) +#define MALIGP2_REG_VAL_IRQ_MASK_USED \ + (\ + MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | \ + MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST | \ + MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | \ + MALIGP2_REG_VAL_IRQ_HANG | \ + MALIGP2_REG_VAL_IRQ_FORCE_HANG | \ + MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR | \ + MALIGP2_REG_VAL_IRQ_SYNC_ERROR | \ + MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR) +#elif defined(USING_MALI400) || defined(USING_MALI450) +#define MALIGP2_REG_VAL_IRQ_MASK_USED \ + (\ + MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | \ + MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST | \ + MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | \ + MALIGP2_REG_VAL_IRQ_HANG | \ + MALIGP2_REG_VAL_IRQ_FORCE_HANG | \ + MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR | \ + MALIGP2_REG_VAL_IRQ_SYNC_ERROR | \ + MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR | \ + MALI400GP_REG_VAL_IRQ_VS_INVALID_CMD | \ + MALI400GP_REG_VAL_IRQ_PLB_INVALID_CMD | \ + MALI400GP_REG_VAL_IRQ_SEMAPHORE_UNDERFLOW | \ + MALI400GP_REG_VAL_IRQ_SEMAPHORE_OVERFLOW | \ + MALI400GP_REG_VAL_IRQ_PTR_ARRAY_OUT_OF_BOUNDS) +#else +#error "No supported mali core defined" +#endif + +/* Mask defining non IRQs on MaliGP2*/ +#define MALIGP2_REG_VAL_IRQ_MASK_NONE 0 + +/** }@ defgroup MALIGP2_IRQ*/ + +/** @defgroup MALIGP2_STATUS + * The different Status values to the geometry processor. + * @see MALIGP2_CTRL_REG_STATUS + * @{ + */ +#define MALIGP2_REG_VAL_STATUS_VS_ACTIVE 0x0002 +#define MALIGP2_REG_VAL_STATUS_BUS_STOPPED 0x0004 +#define MALIGP2_REG_VAL_STATUS_PLBU_ACTIVE 0x0008 +#define MALIGP2_REG_VAL_STATUS_BUS_ERROR 0x0040 +#define MALIGP2_REG_VAL_STATUS_WRITE_BOUND_ERR 0x0100 +/** }@ defgroup MALIGP2_STATUS*/ + +#define MALIGP2_REG_VAL_STATUS_MASK_ACTIVE (\ + MALIGP2_REG_VAL_STATUS_VS_ACTIVE|\ + MALIGP2_REG_VAL_STATUS_PLBU_ACTIVE) + + +#define MALIGP2_REG_VAL_STATUS_MASK_ERROR (\ + MALIGP2_REG_VAL_STATUS_BUS_ERROR |\ + MALIGP2_REG_VAL_STATUS_WRITE_BOUND_ERR ) + +/* This should be in the top 16 bit of the version register of gp.*/ +#define MALI200_GP_PRODUCT_ID 0xA07 +#define MALI300_GP_PRODUCT_ID 0xC07 +#define MALI400_GP_PRODUCT_ID 0xB07 +#define MALI450_GP_PRODUCT_ID 0xD07 + +/** + * The different sources for instrumented on the geometry processor. + * @see MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC + */ + +enum MALIGP2_cont_reg_perf_cnt_src { + MALIGP2_REG_VAL_PERF_CNT1_SRC_NUMBER_OF_VERTICES_PROCESSED = 0x0a, +}; + +#endif diff --git a/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.c b/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.c new file mode 100644 index 0000000..2426853 --- /dev/null +++ b/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.c @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_timestamp.h" + +/* This file is intentionally left empty, as all functions are inlined in mali_profiling_sampler.h */ diff --git a/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.h b/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.h new file mode 100644 index 0000000..0551726 --- /dev/null +++ b/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_TIMESTAMP_H__ +#define __MALI_TIMESTAMP_H__ + +#include "mali_osk.h" + +MALI_STATIC_INLINE _mali_osk_errcode_t _mali_timestamp_reset(void) +{ + /* + * reset counters and overflow flags + */ + + u32 mask = (1 << 0) | /* enable all three counters */ + (0 << 1) | /* reset both Count Registers to 0x0 */ + (1 << 2) | /* reset the Cycle Counter Register to 0x0 */ + (0 << 3) | /* 1 = Cycle Counter Register counts every 64th processor clock cycle */ + (0 << 4) | /* Count Register 0 interrupt enable */ + (0 << 5) | /* Count Register 1 interrupt enable */ + (0 << 6) | /* Cycle Counter interrupt enable */ + (0 << 8) | /* Count Register 0 overflow flag (clear or write, flag on read) */ + (0 << 9) | /* Count Register 1 overflow flag (clear or write, flag on read) */ + (1 << 10); /* Cycle Counter Register overflow flag (clear or write, flag on read) */ + + __asm__ __volatile__ ("MCR p15, 0, %0, c15, c12, 0" : : "r" (mask) ); + + return _MALI_OSK_ERR_OK; +} + +MALI_STATIC_INLINE u64 _mali_timestamp_get(void) +{ + u32 result; + + /* this is for the clock cycles */ + __asm__ __volatile__ ("MRC p15, 0, %0, c15, c12, 1" : "=r" (result)); + + return (u64)result; +} + +#endif /* __MALI_TIMESTAMP_H__ */ diff --git a/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.c b/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.c new file mode 100644 index 0000000..2426853 --- /dev/null +++ b/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.c @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_timestamp.h" + +/* This file is intentionally left empty, as all functions are inlined in mali_profiling_sampler.h */ diff --git a/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.h b/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.h new file mode 100644 index 0000000..e6d3f2a --- /dev/null +++ b/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_TIMESTAMP_H__ +#define __MALI_TIMESTAMP_H__ + +#include "mali_osk.h" + +MALI_STATIC_INLINE _mali_osk_errcode_t _mali_timestamp_reset(void) +{ + return _MALI_OSK_ERR_OK; +} + +MALI_STATIC_INLINE u64 _mali_timestamp_get(void) +{ + return _mali_osk_time_get_ns(); +} + +#endif /* __MALI_TIMESTAMP_H__ */ diff --git a/drivers/media/video/samsung/ump/Kconfig b/drivers/media/video/samsung/ump/Kconfig new file mode 100644 index 0000000..09e8daf --- /dev/null +++ b/drivers/media/video/samsung/ump/Kconfig @@ -0,0 +1,58 @@ + +# +## S3C Multimedia Mali configuration +## +# +# For UMP +config VIDEO_UMP + bool "Enable UMP(Unified Memory Provider)" + default n + ---help--- + This enables UMP memory provider + +config UMP_VCM_ALLOC + depends on VIDEO_UMP && VCM + default y + bool "Enable ump-vcm(virtual contiguous memory) memory" + help + Use VCM(virtual-contiguous-memory) to allocate physical memory. + + +config UMP_R3P1_LSI + bool "Uses the R3P1 as a ump module" + depends on VIDEO_UMP + default n + ---help--- + This uses the r3p1 as a UMP kernel module + +choice +depends on VIDEO_UMP +prompt "UMP MEMEMORY OPTION" +default UMP_OSMEM_ONLY +config UMP_DED_ONLY + bool "ump dedicated memory only" + ---help--- + This enables UMP dedicated memory only option +config UMP_OSMEM_ONLY + bool "ump OS memory only" + ---help--- + This enables UMP OS memory only option +config UMP_VCM_ONLY + bool "ump VCM memory" + ---help--- + This enables UMP VCM memory only option + +endchoice +config UMP_MEM_SIZE +int "UMP Memory Size" + depends on VIDEO_UMP + default "512" + ---help--- + This value is dedicated memory size of UMP (unit is MByte). +# For UMP_DEBUG +config VIDEO_UMP_DEBUG + bool "Enables debug messages" + depends on VIDEO_UMP + default n + help + This enables UMP driver debug messages. diff --git a/drivers/media/video/samsung/ump/Kconfig_module b/drivers/media/video/samsung/ump/Kconfig_module new file mode 100644 index 0000000..3ae316c --- /dev/null +++ b/drivers/media/video/samsung/ump/Kconfig_module @@ -0,0 +1,16 @@ +config UMP + tristate "UMP support" + depends on ARM + ---help--- + This enables support for the UMP memory allocation and sharing API. + + To compile this driver as a module, choose M here: the module will be + called ump. + +config UMP_DEBUG + bool "Enable extra debug in UMP" + depends on UMP + default y + ---help--- + This enabled extra debug checks and messages in UMP. + diff --git a/drivers/media/video/samsung/ump/Makefile b/drivers/media/video/samsung/ump/Makefile new file mode 100644 index 0000000..3a1aac0 --- /dev/null +++ b/drivers/media/video/samsung/ump/Makefile @@ -0,0 +1,93 @@ +# +# Copyright (C) 2010-2012 ARM Limited. All rights reserved. +# +# This program is free software and is provided to you under the terms of the GNU General Public License version 2 +# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. +# +# A copy of the licence is included with the program, and can also be obtained from Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# + +ifeq ($(CONFIG_UMP_DED_ONLY),y) +UMP_MEM_SIZE= $(CONFIG_UMP_MEM_SIZE) +USING_MEMORY=0 +endif + +ifeq ($(CONFIG_UMP_OSMEM_ONLY),y) +UMP_MEM_SIZE= $(CONFIG_UMP_MEM_SIZE) +USING_MEMORY=1 +endif + +ifeq ($(CONFIG_UMP_VCM_ONLY),y) +UMP_MEM_SIZE= $(CONFIG_UMP_MEM_SIZE) +USING_MEMORY=2 +endif + + +# For UMP Debug +ifeq ($(CONFIG_VIDEO_UMP_DEBUG),y) +DEFINES += -DDEBUG +endif + +# Set up our defines, which will be passed to gcc +DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER +DEFINES += -DUSING_MEMORY=$(USING_MEMORY) +DEFINES += -DUMP_MEM_SIZE=$(UMP_MEM_SIZE) +DEFINES += -DMALI_STATE_TRACKING=1 + +UDD_FILE_PREFIX := drivers/media/video/samsung/ump/ +KBUILDROOT = + +# linux build system integration + +obj-$(CONFIG_VIDEO_UMP) += ump.o + +# For customer releases the Linux Device Drivers will be provided as ARM proprietary and GPL releases: +# The ARM proprietary product will only include the license/proprietary directory +# The GPL product will only include the license/gpl directory + +INCLUDES += \ + -I$(UDD_FILE_PREFIX)\ + -I$(UDD_FILE_PREFIX)common\ + -I$(UDD_FILE_PREFIX)linux\ + -I$(UDD_FILE_PREFIX)include\ + -I$(UDD_FILE_PREFIX)linux/license/gpl/\ + -I$(UDD_FILE_PREFIX)../mali/common\ + -I$(UDD_FILE_PREFIX)../mali/linux + +OSKFILES+=\ + $(KBUILDROOT)../mali/linux/mali_osk_atomics.o \ + $(KBUILDROOT)../mali/linux/mali_osk_locks.o \ + $(KBUILDROOT)../mali/linux/mali_osk_math.o \ + $(KBUILDROOT)../mali/linux/mali_osk_memory.o \ + $(KBUILDROOT)../mali/linux/mali_osk_misc.o + +ump-y := \ + $(KBUILDROOT)linux/ump_kernel_linux.o \ + $(KBUILDROOT)linux/ump_kernel_memory_backend_os.o \ + $(KBUILDROOT)linux/ump_kernel_memory_backend_dedicated.o \ + $(KBUILDROOT)linux/ump_memory_backend.o \ + $(KBUILDROOT)linux/ump_ukk_wrappers.o \ + $(KBUILDROOT)linux/ump_ukk_ref_wrappers.o \ + $(KBUILDROOT)linux/ump_osk_atomics.o \ + $(KBUILDROOT)linux/ump_osk_low_level_mem.o \ + $(KBUILDROOT)linux/ump_osk_misc.o \ + $(KBUILDROOT)common/ump_kernel_common.o \ + $(KBUILDROOT)common/ump_kernel_descriptor_mapping.o \ + $(KBUILDROOT)common/ump_kernel_api.o \ + $(KBUILDROOT)common/ump_kernel_ref_drv.o\ + $(OSKFILES) + +ump-$(CONFIG_UMP_VCM_ALLOC) += \ + $(KBUILDROOT)linux/ump_kernel_memory_backend_vcm.o \ + +EXTRA_CFLAGS += $(INCLUDES) \ + $(DEFINES) + + +# Get subversion revision number, fall back to 0000 if no svn info is available +SVN_REV:=$(shell ((svnversion | grep -E "^[0-9]+" && echo -n 'Revision: ' && svnversion) || git svn info | sed -e 's/$$$$/M/' | grep '^Revision: ' || echo ${MALI_RELEASE_NAME}) 2>/dev/null | sed -e 's/^Revision: //') + +EXTRA_CFLAGS += -DSVN_REV=$(SVN_REV) +EXTRA_CFLAGS += -DSVN_REV_STRING=\"$(SVN_REV)\" + diff --git a/drivers/media/video/samsung/ump/Makefile.common b/drivers/media/video/samsung/ump/Makefile.common new file mode 100644 index 0000000..26a3d6c --- /dev/null +++ b/drivers/media/video/samsung/ump/Makefile.common @@ -0,0 +1,20 @@ +# +# Copyright (C) 2010-2012 ARM Limited. All rights reserved. +# +# This program is free software and is provided to you under the terms of the GNU General Public License version 2 +# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. +# +# A copy of the licence is included with the program, and can also be obtained from Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# + +SRC = $(UMP_FILE_PREFIX)common/ump_kernel_common.c \ + $(UMP_FILE_PREFIX)common/ump_kernel_descriptor_mapping.c \ + $(UMP_FILE_PREFIX)common/ump_kernel_api.c \ + $(UMP_FILE_PREFIX)common/ump_kernel_ref_drv.c + +# Get subversion revision number, fall back to 0000 if no svn info is available +SVN_REV:=$(shell ((svnversion | grep -E "^[0-9]+" && echo -n 'Revision: ' && svnversion) || git svn info | sed -e 's/$$$$/M/' | grep '^Revision: ' || echo ${MALI_RELEASE_NAME}) 2>/dev/null | sed -e 's/^Revision: //') + +EXTRA_CFLAGS += -DSVN_REV=$(SVN_REV) +EXTRA_CFLAGS += -DSVN_REV_STRING=\"$(SVN_REV)\" diff --git a/drivers/media/video/samsung/ump/arch b/drivers/media/video/samsung/ump/arch new file mode 120000 index 0000000..58ffbe7 --- /dev/null +++ b/drivers/media/video/samsung/ump/arch @@ -0,0 +1 @@ +arch-release \ No newline at end of file diff --git a/drivers/media/video/samsung/ump/arch-debug b/drivers/media/video/samsung/ump/arch-debug new file mode 120000 index 0000000..0ed0909 --- /dev/null +++ b/drivers/media/video/samsung/ump/arch-debug @@ -0,0 +1 @@ +arch-pegasus-m400/ \ No newline at end of file diff --git a/drivers/media/video/samsung/ump/arch-orion-m400/config.h b/drivers/media/video/samsung/ump/arch-orion-m400/config.h new file mode 100644 index 0000000..7afbca6 --- /dev/null +++ b/drivers/media/video/samsung/ump/arch-orion-m400/config.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __ARCH_CONFIG_UMP_H__ +#define __ARCH_CONFIG_UMP_H__ + +#define ARCH_UMP_BACKEND_DEFAULT USING_MEMORY +#if (USING_MEMORY == 0) /* Dedicated Memory */ +#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0x2C000000 +#else +#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0 +#endif + +#define ARCH_UMP_MEMORY_SIZE_DEFAULT UMP_MEM_SIZE*1024*1024 +#endif /* __ARCH_CONFIG_UMP_H__ */ diff --git a/drivers/media/video/samsung/ump/arch-pb-virtex5/config.h b/drivers/media/video/samsung/ump/arch-pb-virtex5/config.h new file mode 100644 index 0000000..532fc94 --- /dev/null +++ b/drivers/media/video/samsung/ump/arch-pb-virtex5/config.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __ARCH_CONFIG_H__ +#define __ARCH_CONFIG_H__ + +#define ARCH_UMP_BACKEND_DEFAULT 0 +#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0xCE000000 +#define ARCH_UMP_MEMORY_SIZE_DEFAULT 32UL * 1024UL * 1024UL + +#endif /* __ARCH_CONFIG_H__ */ diff --git a/drivers/media/video/samsung/ump/arch-pegasus-m400/config.h b/drivers/media/video/samsung/ump/arch-pegasus-m400/config.h new file mode 100644 index 0000000..7afbca6 --- /dev/null +++ b/drivers/media/video/samsung/ump/arch-pegasus-m400/config.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __ARCH_CONFIG_UMP_H__ +#define __ARCH_CONFIG_UMP_H__ + +#define ARCH_UMP_BACKEND_DEFAULT USING_MEMORY +#if (USING_MEMORY == 0) /* Dedicated Memory */ +#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0x2C000000 +#else +#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0 +#endif + +#define ARCH_UMP_MEMORY_SIZE_DEFAULT UMP_MEM_SIZE*1024*1024 +#endif /* __ARCH_CONFIG_UMP_H__ */ diff --git a/drivers/media/video/samsung/ump/arch-release b/drivers/media/video/samsung/ump/arch-release new file mode 120000 index 0000000..0ed0909 --- /dev/null +++ b/drivers/media/video/samsung/ump/arch-release @@ -0,0 +1 @@ +arch-pegasus-m400/ \ No newline at end of file diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_api.c b/drivers/media/video/samsung/ump/common/ump_kernel_api.c new file mode 100644 index 0000000..83f0d30 --- /dev/null +++ b/drivers/media/video/samsung/ump/common/ump_kernel_api.c @@ -0,0 +1,551 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_osk.h" +#include "mali_osk_list.h" +#include "ump_osk.h" +#include "ump_uk_types.h" +#include "ump_kernel_interface.h" +#include "ump_kernel_common.h" + + + +/* ---------------- UMP kernel space API functions follows ---------------- */ + + + +UMP_KERNEL_API_EXPORT ump_secure_id ump_dd_secure_id_get(ump_dd_handle memh) +{ + ump_dd_mem * mem = (ump_dd_mem *)memh; + + DEBUG_ASSERT_POINTER(mem); + + DBG_MSG(5, ("Returning secure ID. ID: %u\n", mem->secure_id)); + + return mem->secure_id; +} + + + +UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_secure_id(ump_secure_id secure_id) +{ + ump_dd_mem * mem; + + _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + + DBG_MSG(5, ("Getting handle from secure ID. ID: %u\n", secure_id)); + if (0 != ump_descriptor_mapping_get(device.secure_id_map, (int)secure_id, (void**)&mem)) + { + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + DBG_MSG(1, ("Secure ID not found. ID: %u\n", secure_id)); + return UMP_DD_HANDLE_INVALID; + } + + ump_dd_reference_add(mem); + + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + + return (ump_dd_handle)mem; +} + +UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_get(ump_secure_id secure_id) +{ + ump_dd_mem * mem; + + _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + + DBG_MSG(5, ("Getting handle from secure ID. ID: %u\n", secure_id)); + if (0 != ump_descriptor_mapping_get(device.secure_id_map, (int)secure_id, (void**)&mem)) + { + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + DBG_MSG(1, ("Secure ID not found. ID: %u\n", secure_id)); + return UMP_DD_HANDLE_INVALID; + } + + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + + return (ump_dd_handle)mem; +} + +UMP_KERNEL_API_EXPORT unsigned long ump_dd_phys_block_count_get(ump_dd_handle memh) +{ + ump_dd_mem * mem = (ump_dd_mem*) memh; + + DEBUG_ASSERT_POINTER(mem); + + return mem->nr_blocks; +} + + + +UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_phys_blocks_get(ump_dd_handle memh, ump_dd_physical_block * blocks, unsigned long num_blocks) +{ + ump_dd_mem * mem = (ump_dd_mem *)memh; + + DEBUG_ASSERT_POINTER(mem); + + if (blocks == NULL) + { + DBG_MSG(1, ("NULL parameter in ump_dd_phys_blocks_get()\n")); + return UMP_DD_INVALID; + } + + if (mem->nr_blocks != num_blocks) + { + DBG_MSG(1, ("Specified number of blocks do not match actual number of blocks\n")); + return UMP_DD_INVALID; + } + + DBG_MSG(5, ("Returning physical block information. ID: %u\n", mem->secure_id)); + + _mali_osk_memcpy(blocks, mem->block_array, sizeof(ump_dd_physical_block) * mem->nr_blocks); + + return UMP_DD_SUCCESS; +} + + + +UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_phys_block_get(ump_dd_handle memh, unsigned long index, ump_dd_physical_block * block) +{ + ump_dd_mem * mem = (ump_dd_mem *)memh; + + DEBUG_ASSERT_POINTER(mem); + + if (block == NULL) + { + DBG_MSG(1, ("NULL parameter in ump_dd_phys_block_get()\n")); + return UMP_DD_INVALID; + } + + if (index >= mem->nr_blocks) + { + DBG_MSG(5, ("Invalid index specified in ump_dd_phys_block_get()\n")); + return UMP_DD_INVALID; + } + + DBG_MSG(5, ("Returning physical block information. ID: %u, index: %lu\n", mem->secure_id, index)); + + *block = mem->block_array[index]; + + return UMP_DD_SUCCESS; +} + + + +UMP_KERNEL_API_EXPORT unsigned long ump_dd_size_get(ump_dd_handle memh) +{ + ump_dd_mem * mem = (ump_dd_mem*)memh; + + DEBUG_ASSERT_POINTER(mem); + + DBG_MSG(5, ("Returning size. ID: %u, size: %lu\n", mem->secure_id, mem->size_bytes)); + + return mem->size_bytes; +} + + + +UMP_KERNEL_API_EXPORT void ump_dd_reference_add(ump_dd_handle memh) +{ + ump_dd_mem * mem = (ump_dd_mem*)memh; + int new_ref; + + DEBUG_ASSERT_POINTER(mem); + + new_ref = _ump_osk_atomic_inc_and_read(&mem->ref_count); + + DBG_MSG(5, ("Memory reference incremented. ID: %u, new value: %d\n", mem->secure_id, new_ref)); +} + + + +UMP_KERNEL_API_EXPORT void ump_dd_reference_release(ump_dd_handle memh) +{ + int new_ref; + ump_dd_mem * mem = (ump_dd_mem*)memh; + + DEBUG_ASSERT_POINTER(mem); + + /* We must hold this mutex while doing the atomic_dec_and_read, to protect + that elements in the ump_descriptor_mapping table is always valid. If they + are not, userspace may accidently map in this secure_ids right before its freed + giving a mapped backdoor into unallocated memory.*/ + _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + + new_ref = _ump_osk_atomic_dec_and_read(&mem->ref_count); + + DBG_MSG(5, ("Memory reference decremented. ID: %u, new value: %d\n", mem->secure_id, new_ref)); + + if (0 == new_ref) + { + DBG_MSG(3, ("Final release of memory. ID: %u\n", mem->secure_id)); + + ump_descriptor_mapping_free(device.secure_id_map, (int)mem->secure_id); + + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + mem->release_func(mem->ctx, mem); + _mali_osk_free(mem); + } + else + { + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + } +} + + + +/* --------------- Handling of user space requests follows --------------- */ + + +_mali_osk_errcode_t _ump_uku_get_api_version( _ump_uk_api_version_s *args ) +{ + ump_session_data * session_data; + + DEBUG_ASSERT_POINTER( args ); + DEBUG_ASSERT_POINTER( args->ctx ); + + session_data = (ump_session_data *)args->ctx; + + /* check compatability */ + if (args->version == UMP_IOCTL_API_VERSION) + { + DBG_MSG(3, ("API version set to newest %d (compatible)\n", GET_VERSION(args->version))); + args->compatible = 1; + session_data->api_version = args->version; + } + else if (args->version == MAKE_VERSION_ID(1)) + { + DBG_MSG(2, ("API version set to depricated: %d (compatible)\n", GET_VERSION(args->version))); + args->compatible = 1; + session_data->api_version = args->version; + } + else + { + DBG_MSG(2, ("API version set to %d (incompatible with client version %d)\n", GET_VERSION(UMP_IOCTL_API_VERSION), GET_VERSION(args->version))); + args->compatible = 0; + args->version = UMP_IOCTL_API_VERSION; /* report our version */ + } + + return _MALI_OSK_ERR_OK; +} + + +_mali_osk_errcode_t _ump_ukk_release( _ump_uk_release_s *release_info ) +{ + ump_session_memory_list_element * session_memory_element; + ump_session_memory_list_element * tmp; + ump_session_data * session_data; + _mali_osk_errcode_t ret = _MALI_OSK_ERR_INVALID_FUNC; + int secure_id; + + DEBUG_ASSERT_POINTER( release_info ); + DEBUG_ASSERT_POINTER( release_info->ctx ); + + /* Retreive the session data */ + session_data = (ump_session_data*)release_info->ctx; + + /* If there are many items in the memory session list we + * could be de-referencing this pointer a lot so keep a local copy + */ + secure_id = release_info->secure_id; + + DBG_MSG(4, ("Releasing memory with IOCTL, ID: %u\n", secure_id)); + + /* Iterate through the memory list looking for the requested secure ID */ + _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); + _MALI_OSK_LIST_FOREACHENTRY(session_memory_element, tmp, &session_data->list_head_session_memory_list, ump_session_memory_list_element, list) + { + if ( session_memory_element->mem->secure_id == secure_id) + { + ump_dd_mem *release_mem; + + release_mem = session_memory_element->mem; + _mali_osk_list_del(&session_memory_element->list); + ump_dd_reference_release(release_mem); + _mali_osk_free(session_memory_element); + + ret = _MALI_OSK_ERR_OK; + break; + } + } + + _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); + DBG_MSG_IF(1, _MALI_OSK_ERR_OK != ret, ("UMP memory with ID %u does not belong to this session.\n", secure_id)); + + DBG_MSG(4, ("_ump_ukk_release() returning 0x%x\n", ret)); + return ret; +} + +_mali_osk_errcode_t _ump_ukk_size_get( _ump_uk_size_get_s *user_interaction ) +{ + ump_dd_mem * mem; + _mali_osk_errcode_t ret = _MALI_OSK_ERR_FAULT; + + DEBUG_ASSERT_POINTER( user_interaction ); + + /* We lock the mappings so things don't get removed while we are looking for the memory */ + _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + if (0 == ump_descriptor_mapping_get(device.secure_id_map, (int)user_interaction->secure_id, (void**)&mem)) + { + user_interaction->size = mem->size_bytes; + DBG_MSG(4, ("Returning size. ID: %u, size: %lu ", (ump_secure_id)user_interaction->secure_id, (unsigned long)user_interaction->size)); + ret = _MALI_OSK_ERR_OK; + } + else + { + user_interaction->size = 0; + DBG_MSG(1, ("Failed to look up mapping in ump_ioctl_size_get(). ID: %u\n", (ump_secure_id)user_interaction->secure_id)); + } + + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + return ret; +} + + + +void _ump_ukk_msync( _ump_uk_msync_s *args ) +{ + ump_dd_mem * mem = NULL; + void *virtual = NULL; + u32 size = 0; + u32 offset = 0; + + _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + ump_descriptor_mapping_get(device.secure_id_map, (int)args->secure_id, (void**)&mem); + + if (NULL == mem) + { + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + DBG_MSG(1, ("Failed to look up mapping in _ump_ukk_msync(). ID: %u\n", (ump_secure_id)args->secure_id)); + return; + } + /* Ensure the memory doesn't dissapear when we are flushing it. */ + ump_dd_reference_add(mem); + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + + /* Returns the cache settings back to Userspace */ + args->is_cached=mem->is_cached; + + /* If this flag is the only one set, we should not do the actual flush, only the readout */ + if ( _UMP_UK_MSYNC_READOUT_CACHE_ENABLED==args->op ) + { + DBG_MSG(3, ("_ump_ukk_msync READOUT ID: %u Enabled: %d\n", (ump_secure_id)args->secure_id, mem->is_cached)); + goto msync_release_and_return; + } + + /* Nothing to do if the memory is not caches */ + if ( 0==mem->is_cached ) + { + DBG_MSG(3, ("_ump_ukk_msync IGNORING ID: %u Enabled: %d OP: %d\n", (ump_secure_id)args->secure_id, mem->is_cached, args->op)); + goto msync_release_and_return; + } + DBG_MSG(3, ("UMP[%02u] _ump_ukk_msync Flush OP: %d Address: 0x%08x Mapping: 0x%08x\n", + (ump_secure_id)args->secure_id, args->op, args->address, args->mapping)); + + if ( args->address ) + { + virtual = (void *)((u32)args->address); + offset = (u32)((args->address) - (args->mapping)); + } else { + /* Flush entire mapping when no address is specified. */ + virtual = args->mapping; + } + if ( args->size ) + { + size = args->size; + } else { + /* Flush entire mapping when no size is specified. */ + size = mem->size_bytes - offset; + } + + if ( (offset + size) > mem->size_bytes ) + { + DBG_MSG(1, ("Trying to flush more than the entire UMP allocation: offset: %u + size: %u > %u\n", offset, size, mem->size_bytes)); + goto msync_release_and_return; + } + + /* The actual cache flush - Implemented for each OS*/ + _ump_osk_msync( mem, virtual, offset, size, args->op, NULL); + +msync_release_and_return: + ump_dd_reference_release(mem); + return; +} + +void _ump_ukk_cache_operations_control(_ump_uk_cache_operations_control_s* args) +{ + ump_session_data * session_data; + ump_uk_cache_op_control op; + + DEBUG_ASSERT_POINTER( args ); + DEBUG_ASSERT_POINTER( args->ctx ); + + op = args->op; + session_data = (ump_session_data *)args->ctx; + + _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); + if ( op== _UMP_UK_CACHE_OP_START ) + { + session_data->cache_operations_ongoing++; + DBG_MSG(4, ("Cache ops start\n" )); + if ( session_data->cache_operations_ongoing != 1 ) + { + DBG_MSG(2, ("UMP: Number of simultanious cache control ops: %d\n", session_data->cache_operations_ongoing) ); + } + } + else if ( op== _UMP_UK_CACHE_OP_FINISH ) + { + DBG_MSG(4, ("Cache ops finish\n")); + session_data->cache_operations_ongoing--; + #if 0 + if ( session_data->has_pending_level1_cache_flush) + { + /* This function will set has_pending_level1_cache_flush=0 */ + _ump_osk_msync( NULL, NULL, 0, 0, _UMP_UK_MSYNC_FLUSH_L1, session_data); + } + #endif + + /* to be on the safe side: always flush l1 cache when cache operations are done */ + _ump_osk_msync( NULL, NULL, 0, 0, _UMP_UK_MSYNC_FLUSH_L1, session_data); + DBG_MSG(4, ("Cache ops finish end\n" )); + } + else + { + DBG_MSG(1, ("Illegal call to %s at line %d\n", __FUNCTION__, __LINE__)); + } + _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); + +} + +void _ump_ukk_switch_hw_usage(_ump_uk_switch_hw_usage_s *args ) +{ + ump_dd_mem * mem = NULL; + ump_uk_user old_user; + ump_uk_msync_op cache_op = _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE; + ump_session_data *session_data; + + DEBUG_ASSERT_POINTER( args ); + DEBUG_ASSERT_POINTER( args->ctx ); + + session_data = (ump_session_data *)args->ctx; + + _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + ump_descriptor_mapping_get(device.secure_id_map, (int)args->secure_id, (void**)&mem); + + if (NULL == mem) + { + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + DBG_MSG(1, ("Failed to look up mapping in _ump_ukk_switch_hw_usage(). ID: %u\n", (ump_secure_id)args->secure_id)); + return; + } + + old_user = mem->hw_device; + mem->hw_device = args->new_user; + + DBG_MSG(3, ("UMP[%02u] Switch usage Start New: %s Prev: %s.\n", (ump_secure_id)args->secure_id, args->new_user?"MALI":"CPU",old_user?"MALI":"CPU")); + + if ( ! mem->is_cached ) + { + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + DBG_MSG(3, ("UMP[%02u] Changing owner of uncached memory. Cache flushing not needed.\n", (ump_secure_id)args->secure_id)); + return; + } + + if ( old_user == args->new_user) + { + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + DBG_MSG(4, ("UMP[%02u] Setting the new_user equal to previous for. Cache flushing not needed.\n", (ump_secure_id)args->secure_id)); + return; + } + if ( + /* Previous AND new is both different from CPU */ + (old_user != _UMP_UK_USED_BY_CPU) && (args->new_user != _UMP_UK_USED_BY_CPU ) + ) + { + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + DBG_MSG(4, ("UMP[%02u] Previous and new user is not CPU. Cache flushing not needed.\n", (ump_secure_id)args->secure_id)); + return; + } + + if ( (old_user != _UMP_UK_USED_BY_CPU ) && (args->new_user==_UMP_UK_USED_BY_CPU) ) + { + cache_op =_UMP_UK_MSYNC_INVALIDATE; + DBG_MSG(4, ("UMP[%02u] Cache invalidation needed\n", (ump_secure_id)args->secure_id)); +#ifdef UMP_SKIP_INVALIDATION +#error + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + DBG_MSG(4, ("UMP[%02u] Performing Cache invalidation SKIPPED\n", (ump_secure_id)args->secure_id)); + return; +#endif + } + /* Ensure the memory doesn't dissapear when we are flushing it. */ + ump_dd_reference_add(mem); + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + + /* Take lock to protect: session->cache_operations_ongoing and session->has_pending_level1_cache_flush */ + _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); + /* Actual cache flush */ + _ump_osk_msync( mem, NULL, 0, mem->size_bytes, cache_op, session_data); + _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); + + ump_dd_reference_release(mem); + DBG_MSG(4, ("UMP[%02u] Switch usage Finish\n", (ump_secure_id)args->secure_id)); + return; +} + +void _ump_ukk_lock(_ump_uk_lock_s *args ) +{ + ump_dd_mem * mem = NULL; + + _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + ump_descriptor_mapping_get(device.secure_id_map, (int)args->secure_id, (void**)&mem); + + if (NULL == mem) + { + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + DBG_MSG(1, ("UMP[%02u] Failed to look up mapping in _ump_ukk_lock(). ID: %u\n", (ump_secure_id)args->secure_id)); + return; + } + ump_dd_reference_add(mem); + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + + DBG_MSG(1, ("UMP[%02u] Lock. New lock flag: %d. Old Lock flag:\n", (u32)args->secure_id, (u32)args->lock_usage, (u32) mem->lock_usage )); + + mem->lock_usage = (ump_lock_usage) args->lock_usage; + + /** TODO: TAKE LOCK HERE */ + + ump_dd_reference_release(mem); +} + +void _ump_ukk_unlock(_ump_uk_unlock_s *args ) +{ + ump_dd_mem * mem = NULL; + + _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + ump_descriptor_mapping_get(device.secure_id_map, (int)args->secure_id, (void**)&mem); + + if (NULL == mem) + { + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + DBG_MSG(1, ("Failed to look up mapping in _ump_ukk_unlock(). ID: %u\n", (ump_secure_id)args->secure_id)); + return; + } + ump_dd_reference_add(mem); + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + + DBG_MSG(1, ("UMP[%02u] Unlocking. Old Lock flag:\n", (u32)args->secure_id, (u32) mem->lock_usage )); + + mem->lock_usage = (ump_lock_usage) UMP_NOT_LOCKED; + + /** TODO: RELEASE LOCK HERE */ + + ump_dd_reference_release(mem); +} diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_common.c b/drivers/media/video/samsung/ump/common/ump_kernel_common.c new file mode 100644 index 0000000..a27bc77 --- /dev/null +++ b/drivers/media/video/samsung/ump/common/ump_kernel_common.c @@ -0,0 +1,414 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_kernel_common.h" +#include "mali_osk.h" +#include "mali_osk_bitops.h" +#include "mali_osk_list.h" +#include "ump_osk.h" +#include "ump_uk_types.h" +#include "ump_ukk.h" +#include "ump_kernel_common.h" +#include "ump_kernel_descriptor_mapping.h" +#include "ump_kernel_memory_backend.h" + + + +/** + * Define the initial and maximum size of number of secure_ids on the system + */ +#define UMP_SECURE_ID_TABLE_ENTRIES_INITIAL (128 ) +#define UMP_SECURE_ID_TABLE_ENTRIES_MAXIMUM (4096 ) + + +/** + * Define the initial and maximum size of the ump_session_data::cookies_map, + * which is a \ref ump_descriptor_mapping. This limits how many secure_ids + * may be mapped into a particular process using _ump_ukk_map_mem(). + */ + +#define UMP_COOKIES_PER_SESSION_INITIAL (UMP_SECURE_ID_TABLE_ENTRIES_INITIAL ) +#define UMP_COOKIES_PER_SESSION_MAXIMUM (UMP_SECURE_ID_TABLE_ENTRIES_MAXIMUM) + +struct ump_dev device; + +_mali_osk_errcode_t ump_kernel_constructor(void) +{ + _mali_osk_errcode_t err; + + /* Perform OS Specific initialization */ + err = _ump_osk_init(); + if( _MALI_OSK_ERR_OK != err ) + { + MSG_ERR(("Failed to initiaze the UMP Device Driver")); + return err; + } + + /* Init the global device */ + _mali_osk_memset(&device, 0, sizeof(device) ); + + /* Create the descriptor map, which will be used for mapping secure ID to ump_dd_mem structs */ + device.secure_id_map_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0 , 0); + if (NULL == device.secure_id_map_lock) + { + MSG_ERR(("Failed to create OSK lock for secure id lookup table\n")); + return _MALI_OSK_ERR_NOMEM; + } + + device.secure_id_map = ump_descriptor_mapping_create(UMP_SECURE_ID_TABLE_ENTRIES_INITIAL, UMP_SECURE_ID_TABLE_ENTRIES_MAXIMUM); + if (NULL == device.secure_id_map) + { + _mali_osk_lock_term(device.secure_id_map_lock); + MSG_ERR(("Failed to create secure id lookup table\n")); + return _MALI_OSK_ERR_NOMEM; + } + + /* Init memory backend */ + device.backend = ump_memory_backend_create(); + if (NULL == device.backend) + { + MSG_ERR(("Failed to create memory backend\n")); + _mali_osk_lock_term(device.secure_id_map_lock); + ump_descriptor_mapping_destroy(device.secure_id_map); + return _MALI_OSK_ERR_NOMEM; + } + + return _MALI_OSK_ERR_OK; +} + +void ump_kernel_destructor(void) +{ + DEBUG_ASSERT_POINTER(device.secure_id_map); + DEBUG_ASSERT_POINTER(device.secure_id_map_lock); + + _mali_osk_lock_term(device.secure_id_map_lock); + device.secure_id_map_lock = NULL; + + ump_descriptor_mapping_destroy(device.secure_id_map); + device.secure_id_map = NULL; + + device.backend->shutdown(device.backend); + device.backend = NULL; + + ump_memory_backend_destroy(); + + _ump_osk_term(); +} + +/** Creates a new UMP session + */ +_mali_osk_errcode_t _ump_ukk_open( void** context ) +{ + struct ump_session_data * session_data; + + /* allocated struct to track this session */ + session_data = (struct ump_session_data *)_mali_osk_malloc(sizeof(struct ump_session_data)); + if (NULL == session_data) + { + MSG_ERR(("Failed to allocate ump_session_data in ump_file_open()\n")); + return _MALI_OSK_ERR_NOMEM; + } + + session_data->lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, 0); + if( NULL == session_data->lock ) + { + MSG_ERR(("Failed to initialize lock for ump_session_data in ump_file_open()\n")); + _mali_osk_free(session_data); + return _MALI_OSK_ERR_NOMEM; + } + + session_data->cookies_map = ump_descriptor_mapping_create( UMP_COOKIES_PER_SESSION_INITIAL, UMP_COOKIES_PER_SESSION_MAXIMUM ); + + if ( NULL == session_data->cookies_map ) + { + MSG_ERR(("Failed to create descriptor mapping for _ump_ukk_map_mem cookies\n")); + + _mali_osk_lock_term( session_data->lock ); + _mali_osk_free( session_data ); + return _MALI_OSK_ERR_NOMEM; + } + + _MALI_OSK_INIT_LIST_HEAD(&session_data->list_head_session_memory_list); + + _MALI_OSK_INIT_LIST_HEAD(&session_data->list_head_session_memory_mappings_list); + + /* Since initial version of the UMP interface did not use the API_VERSION ioctl we have to assume + that it is this version, and not the "latest" one: UMP_IOCTL_API_VERSION + Current and later API versions would do an additional call to this IOCTL and update this variable + to the correct one.*/ + session_data->api_version = MAKE_VERSION_ID(1); + + *context = (void*)session_data; + + session_data->cache_operations_ongoing = 0 ; + session_data->has_pending_level1_cache_flush = 0; + + DBG_MSG(2, ("New session opened\n")); + + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t _ump_ukk_close( void** context ) +{ + struct ump_session_data * session_data; + ump_session_memory_list_element * item; + ump_session_memory_list_element * tmp; + + session_data = (struct ump_session_data *)*context; + if (NULL == session_data) + { + MSG_ERR(("Session data is NULL in _ump_ukk_close()\n")); + return _MALI_OSK_ERR_INVALID_ARGS; + } + + /* Unmap any descriptors mapped in. */ + if (0 == _mali_osk_list_empty(&session_data->list_head_session_memory_mappings_list)) + { + ump_memory_allocation *descriptor; + ump_memory_allocation *temp; + + DBG_MSG(1, ("Memory mappings found on session usage list during session termination\n")); + + /* use the 'safe' list iterator, since freeing removes the active block from the list we're iterating */ + _MALI_OSK_LIST_FOREACHENTRY(descriptor, temp, &session_data->list_head_session_memory_mappings_list, ump_memory_allocation, list) + { + _ump_uk_unmap_mem_s unmap_args; + DBG_MSG(4, ("Freeing block with phys address 0x%x size 0x%x mapped in user space at 0x%x\n", + descriptor->phys_addr, descriptor->size, descriptor->mapping)); + unmap_args.ctx = (void*)session_data; + unmap_args.mapping = descriptor->mapping; + unmap_args.size = descriptor->size; + unmap_args._ukk_private = NULL; /* NOTE: unused */ + unmap_args.cookie = descriptor->cookie; + + /* NOTE: This modifies the list_head_session_memory_mappings_list */ + _ump_ukk_unmap_mem( &unmap_args ); + } + } + + /* ASSERT that we really did free everything, because _ump_ukk_unmap_mem() + * can fail silently. */ + DEBUG_ASSERT( _mali_osk_list_empty(&session_data->list_head_session_memory_mappings_list) ); + + _MALI_OSK_LIST_FOREACHENTRY(item, tmp, &session_data->list_head_session_memory_list, ump_session_memory_list_element, list) + { + _mali_osk_list_del(&item->list); + DBG_MSG(2, ("Releasing UMP memory %u as part of file close\n", item->mem->secure_id)); + ump_dd_reference_release(item->mem); + _mali_osk_free(item); + } + + ump_descriptor_mapping_destroy( session_data->cookies_map ); + + _mali_osk_lock_term(session_data->lock); + _mali_osk_free(session_data); + + DBG_MSG(2, ("Session closed\n")); + + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t _ump_ukk_map_mem( _ump_uk_map_mem_s *args ) +{ + struct ump_session_data * session_data; + ump_memory_allocation * descriptor; /* Describes current mapping of memory */ + _mali_osk_errcode_t err; + unsigned long offset = 0; + unsigned long left; + ump_dd_handle handle; /* The real UMP handle for this memory. Its real datatype is ump_dd_mem* */ + ump_dd_mem * mem; /* The real UMP memory. It is equal to the handle, but with exposed struct */ + u32 block; + int map_id; + + session_data = (ump_session_data *)args->ctx; + if( NULL == session_data ) + { + MSG_ERR(("Session data is NULL in _ump_ukk_map_mem()\n")); + return _MALI_OSK_ERR_INVALID_ARGS; + } + /* SEC kernel stability 2012-02-17 */ + if (NULL == session_data->cookies_map) + { + MSG_ERR(("session_data->cookies_map is NULL in _ump_ukk_map_mem()\n")); + return _MALI_OSK_ERR_INVALID_ARGS; + } + descriptor = (ump_memory_allocation*) _mali_osk_calloc( 1, sizeof(ump_memory_allocation)); + if (NULL == descriptor) + { + MSG_ERR(("ump_ukk_map_mem: descriptor allocation failed\n")); + return _MALI_OSK_ERR_NOMEM; + } + + handle = ump_dd_handle_create_from_secure_id(args->secure_id); + if ( UMP_DD_HANDLE_INVALID == handle) + { + _mali_osk_free(descriptor); + DBG_MSG(1, ("Trying to map unknown secure ID %u\n", args->secure_id)); + return _MALI_OSK_ERR_FAULT; + } + + mem = (ump_dd_mem*)handle; + DEBUG_ASSERT(mem); + if (mem->size_bytes != args->size) + { + _mali_osk_free(descriptor); + ump_dd_reference_release(handle); + DBG_MSG(1, ("Trying to map too much or little. ID: %u, virtual size=%lu, UMP size: %lu\n", args->secure_id, args->size, mem->size_bytes)); + return _MALI_OSK_ERR_FAULT; + } + + map_id = ump_descriptor_mapping_allocate_mapping( session_data->cookies_map, (void*) descriptor ); + + if (map_id < 0) + { + _mali_osk_free(descriptor); + ump_dd_reference_release(handle); + DBG_MSG(1, ("ump_ukk_map_mem: unable to allocate a descriptor_mapping for return cookie\n")); + + return _MALI_OSK_ERR_NOMEM; + } + + descriptor->size = args->size; + descriptor->handle = handle; + descriptor->phys_addr = args->phys_addr; + descriptor->process_mapping_info = args->_ukk_private; + descriptor->ump_session = session_data; + descriptor->cookie = (u32)map_id; + + if ( mem->is_cached ) + { + descriptor->is_cached = 1; + args->is_cached = 1; + DBG_MSG(3, ("Mapping UMP secure_id: %d as cached.\n", args->secure_id)); + } + else if ( args->is_cached) + { + mem->is_cached = 1; + descriptor->is_cached = 1; + DBG_MSG(3, ("Warning mapping UMP secure_id: %d. As cached, while it was allocated uncached.\n", args->secure_id)); + } + else + { + descriptor->is_cached = 0; + args->is_cached = 0; + DBG_MSG(3, ("Mapping UMP secure_id: %d as Uncached.\n", args->secure_id)); + } + + _mali_osk_list_init( &descriptor->list ); + + err = _ump_osk_mem_mapregion_init( descriptor ); + if( _MALI_OSK_ERR_OK != err ) + { + DBG_MSG(1, ("Failed to initialize memory mapping in _ump_ukk_map_mem(). ID: %u\n", args->secure_id)); + ump_descriptor_mapping_free( session_data->cookies_map, map_id ); + _mali_osk_free(descriptor); + ump_dd_reference_release(mem); + return err; + } + + DBG_MSG(4, ("Mapping virtual to physical memory: ID: %u, size:%lu, first physical addr: 0x%08lx, number of regions: %lu\n", + mem->secure_id, + mem->size_bytes, + ((NULL != mem->block_array) ? mem->block_array->addr : 0), + mem->nr_blocks)); + + left = descriptor->size; + /* loop over all blocks and map them in */ + for (block = 0; block < mem->nr_blocks; block++) + { + unsigned long size_to_map; + + if (left > mem->block_array[block].size) + { + size_to_map = mem->block_array[block].size; + } + else + { + size_to_map = left; + } + + if (_MALI_OSK_ERR_OK != _ump_osk_mem_mapregion_map(descriptor, offset, (u32 *)&(mem->block_array[block].addr), size_to_map ) ) + { + DBG_MSG(1, ("WARNING: _ump_ukk_map_mem failed to map memory into userspace\n")); + ump_descriptor_mapping_free( session_data->cookies_map, map_id ); + ump_dd_reference_release(mem); + _ump_osk_mem_mapregion_term( descriptor ); + _mali_osk_free(descriptor); + return _MALI_OSK_ERR_FAULT; + } + left -= size_to_map; + offset += size_to_map; + } + + /* Add to the ump_memory_allocation tracking list */ + _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); + _mali_osk_list_add( &descriptor->list, &session_data->list_head_session_memory_mappings_list ); + _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); + + args->mapping = descriptor->mapping; + args->cookie = descriptor->cookie; + + return _MALI_OSK_ERR_OK; +} + +void _ump_ukk_unmap_mem( _ump_uk_unmap_mem_s *args ) +{ + struct ump_session_data * session_data; + ump_memory_allocation * descriptor; + ump_dd_handle handle; + + session_data = (ump_session_data *)args->ctx; + + if( NULL == session_data ) + { + MSG_ERR(("Session data is NULL in _ump_ukk_map_mem()\n")); + return; + } + /* SEC kernel stability 2012-02-17 */ + if (NULL == session_data->cookies_map) + { + MSG_ERR(("session_data->cookies_map is NULL in _ump_ukk_map_mem()\n")); + return; + } + if (0 != ump_descriptor_mapping_get( session_data->cookies_map, (int)args->cookie, (void**)&descriptor) ) + { + MSG_ERR(("_ump_ukk_map_mem: cookie 0x%X not found for this session\n", args->cookie )); + return; + } + + DEBUG_ASSERT_POINTER(descriptor); + + handle = descriptor->handle; + if ( UMP_DD_HANDLE_INVALID == handle) + { + DBG_MSG(1, ("WARNING: Trying to unmap unknown handle: UNKNOWN\n")); + return; + } + + /* Remove the ump_memory_allocation from the list of tracked mappings */ + _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); + _mali_osk_list_del( &descriptor->list ); + _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); + + ump_descriptor_mapping_free( session_data->cookies_map, (int)args->cookie ); + + ump_dd_reference_release(handle); + + _ump_osk_mem_mapregion_term( descriptor ); + _mali_osk_free(descriptor); +} + +u32 _ump_ukk_report_memory_usage( void ) +{ + if(device.backend->stat) + return device.backend->stat(device.backend); + else + return 0; +} diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_common.h b/drivers/media/video/samsung/ump/common/ump_kernel_common.h new file mode 100644 index 0000000..6e3a2e9 --- /dev/null +++ b/drivers/media/video/samsung/ump/common/ump_kernel_common.h @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __UMP_KERNEL_COMMON_H__ +#define __UMP_KERNEL_COMMON_H__ + +#include "ump_kernel_types.h" +#include "ump_kernel_interface.h" +#include "ump_kernel_descriptor_mapping.h" +#include "ump_kernel_memory_backend.h" + + +#ifdef DEBUG + extern int ump_debug_level; + #define UMP_DEBUG_PRINT(args) _mali_osk_dbgmsg args + #define UMP_DEBUG_CODE(args) args + #define DBG_MSG(level,args) do { /* args should be in brackets */ \ + ((level) <= ump_debug_level)?\ + UMP_DEBUG_PRINT(("UMP<" #level ">: ")), \ + UMP_DEBUG_PRINT(args):0; \ + } while (0) + + #define DBG_MSG_IF(level,condition,args) /* args should be in brackets */ \ + if((condition)&&((level) <= ump_debug_level)) {\ + UMP_DEBUG_PRINT(("UMP<" #level ">: ")); \ + UMP_DEBUG_PRINT(args); \ + } + + #define DBG_MSG_ELSE(level,args) /* args should be in brackets */ \ + else if((level) <= ump_debug_level) { \ + UMP_DEBUG_PRINT(("UMP<" #level ">: ")); \ + UMP_DEBUG_PRINT(args); \ + } + + #define DEBUG_ASSERT_POINTER(pointer) do {if( (pointer)== NULL) MSG_ERR(("NULL pointer " #pointer)); } while(0) + #define DEBUG_ASSERT(condition) do {if(!(condition)) MSG_ERR(("ASSERT failed: " #condition)); } while(0) +#else /* DEBUG */ + #define UMP_DEBUG_PRINT(args) do {} while(0) + #define UMP_DEBUG_CODE(args) + #define DBG_MSG(level,args) do {} while(0) + #define DBG_MSG_IF(level,condition,args) do {} while(0) + #define DBG_MSG_ELSE(level,args) do {} while(0) + #define DEBUG_ASSERT(condition) do {} while(0) + #define DEBUG_ASSERT_POINTER(pointer) do {} while(0) +#endif /* DEBUG */ + +#define MSG_ERR(args) do{ /* args should be in brackets */ \ + _mali_osk_dbgmsg("UMP: ERR: %s\n" ,__FILE__); \ + _mali_osk_dbgmsg( " %s()%4d\n", __FUNCTION__, __LINE__) ; \ + _mali_osk_dbgmsg args ; \ + _mali_osk_dbgmsg("\n"); \ + } while(0) + +#define MSG(args) do{ /* args should be in brackets */ \ + _mali_osk_dbgmsg("UMP: "); \ + _mali_osk_dbgmsg args; \ + } while (0) + + + +/* + * This struct is used to store per session data. + * A session is created when someone open() the device, and + * closed when someone close() it or the user space application terminates. + */ +typedef struct ump_session_data +{ + _mali_osk_list_t list_head_session_memory_list; /**< List of ump allocations made by the process (elements are ump_session_memory_list_element) */ + _mali_osk_list_t list_head_session_memory_mappings_list; /**< List of ump_memory_allocations mapped in */ + int api_version; + _mali_osk_lock_t * lock; + ump_descriptor_mapping * cookies_map; /**< Secure mapping of cookies from _ump_ukk_map_mem() */ + int cache_operations_ongoing; + int has_pending_level1_cache_flush; +} ump_session_data; + + + +/* + * This struct is used to track the UMP memory references a session has. + * We need to track this in order to be able to clean up after user space processes + * which don't do it themself (e.g. due to a crash or premature termination). + */ +typedef struct ump_session_memory_list_element +{ + struct ump_dd_mem * mem; + _mali_osk_list_t list; +} ump_session_memory_list_element; + + + +/* + * Device specific data, created when device driver is loaded, and then kept as the global variable device. + */ +typedef struct ump_dev +{ + _mali_osk_lock_t * secure_id_map_lock; + ump_descriptor_mapping * secure_id_map; + ump_memory_backend * backend; +} ump_dev; + + + +extern int ump_debug_level; +extern struct ump_dev device; + +_mali_osk_errcode_t ump_kernel_constructor(void); +void ump_kernel_destructor(void); +int map_errcode( _mali_osk_errcode_t err ); + +/** + * variables from user space cannot be dereferenced from kernel space; tagging them + * with __user allows the GCC compiler to generate a warning. Other compilers may + * not support this so we define it here as an empty macro if the compiler doesn't + * define it. + */ +#ifndef __user +#define __user +#endif + +#endif /* __UMP_KERNEL_COMMON_H__ */ diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.c b/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.c new file mode 100644 index 0000000..cc7b8be --- /dev/null +++ b/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.c @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_kernel_common.h" +#include "mali_osk.h" +#include "mali_osk_bitops.h" +#include "ump_kernel_common.h" +#include "ump_kernel_descriptor_mapping.h" + +#define MALI_PAD_INT(x) (((x) + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1)) + +/** + * Allocate a descriptor table capable of holding 'count' mappings + * @param count Number of mappings in the table + * @return Pointer to a new table, NULL on error + */ +static ump_descriptor_table * descriptor_table_alloc(int count); + +/** + * Free a descriptor table + * @param table The table to free + */ +static void descriptor_table_free(ump_descriptor_table * table); + +ump_descriptor_mapping * ump_descriptor_mapping_create(int init_entries, int max_entries) +{ + ump_descriptor_mapping * map = _mali_osk_calloc(1, sizeof(ump_descriptor_mapping) ); + + init_entries = MALI_PAD_INT(init_entries); + max_entries = MALI_PAD_INT(max_entries); + + if (NULL != map) + { + map->table = descriptor_table_alloc(init_entries); + if (NULL != map->table) + { + map->lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_READERWRITER, 0 , 0); + if ( NULL != map->lock ) + { + _mali_osk_set_nonatomic_bit(0, map->table->usage); /* reserve bit 0 to prevent NULL/zero logic to kick in */ + map->max_nr_mappings_allowed = max_entries; + map->current_nr_mappings = init_entries; + return map; + } + descriptor_table_free(map->table); + } + _mali_osk_free(map); + } + return NULL; +} + +void ump_descriptor_mapping_destroy(ump_descriptor_mapping * map) +{ + descriptor_table_free(map->table); + _mali_osk_lock_term( map->lock ); + _mali_osk_free(map); +} + +int ump_descriptor_mapping_allocate_mapping(ump_descriptor_mapping * map, void * target) +{ + int descriptor = -1;/*-EFAULT;*/ + _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW); + descriptor = _mali_osk_find_first_zero_bit(map->table->usage, map->current_nr_mappings); + if (descriptor == map->current_nr_mappings) + { + int nr_mappings_new; + /* no free descriptor, try to expand the table */ + ump_descriptor_table * new_table; + ump_descriptor_table * old_table = map->table; + nr_mappings_new= map->current_nr_mappings *2; + + if (map->current_nr_mappings >= map->max_nr_mappings_allowed) + { + descriptor = -1; + goto unlock_and_exit; + } + + new_table = descriptor_table_alloc(nr_mappings_new); + if (NULL == new_table) + { + descriptor = -1; + goto unlock_and_exit; + } + + _mali_osk_memcpy(new_table->usage, old_table->usage, (sizeof(unsigned long)*map->current_nr_mappings) / BITS_PER_LONG); + _mali_osk_memcpy(new_table->mappings, old_table->mappings, map->current_nr_mappings * sizeof(void*)); + map->table = new_table; + map->current_nr_mappings = nr_mappings_new; + descriptor_table_free(old_table); + } + + /* we have found a valid descriptor, set the value and usage bit */ + _mali_osk_set_nonatomic_bit(descriptor, map->table->usage); + map->table->mappings[descriptor] = target; + +unlock_and_exit: + _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RW); + return descriptor; +} + +int ump_descriptor_mapping_get(ump_descriptor_mapping * map, int descriptor, void** target) +{ + int result = -1;/*-EFAULT;*/ + DEBUG_ASSERT(map); + _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO); + if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) ) + { + *target = map->table->mappings[descriptor]; + result = 0; + } + else *target = NULL; + _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO); + return result; +} + +int ump_descriptor_mapping_set(ump_descriptor_mapping * map, int descriptor, void * target) +{ + int result = -1;/*-EFAULT;*/ + _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO); + if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) ) + { + map->table->mappings[descriptor] = target; + result = 0; + } + _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO); + return result; +} + +void ump_descriptor_mapping_free(ump_descriptor_mapping * map, int descriptor) +{ + _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW); + if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) ) + { + map->table->mappings[descriptor] = NULL; + _mali_osk_clear_nonatomic_bit(descriptor, map->table->usage); + } + _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RW); +} + +static ump_descriptor_table * descriptor_table_alloc(int count) +{ + ump_descriptor_table * table; + + table = _mali_osk_calloc(1, sizeof(ump_descriptor_table) + ((sizeof(unsigned long) * count)/BITS_PER_LONG) + (sizeof(void*) * count) ); + + if (NULL != table) + { + table->usage = (u32*)((u8*)table + sizeof(ump_descriptor_table)); + table->mappings = (void**)((u8*)table + sizeof(ump_descriptor_table) + ((sizeof(unsigned long) * count)/BITS_PER_LONG)); + } + + return table; +} + +static void descriptor_table_free(ump_descriptor_table * table) +{ + _mali_osk_free(table); +} diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.h b/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.h new file mode 100644 index 0000000..05b3982 --- /dev/null +++ b/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file ump_kernel_descriptor_mapping.h + */ + +#ifndef __UMP_KERNEL_DESCRIPTOR_MAPPING_H__ +#define __UMP_KERNEL_DESCRIPTOR_MAPPING_H__ + +#include "mali_osk.h" + +/** + * The actual descriptor mapping table, never directly accessed by clients + */ +typedef struct ump_descriptor_table +{ + u32 * usage; /**< Pointer to bitpattern indicating if a descriptor is valid/used or not */ + void** mappings; /**< Array of the pointers the descriptors map to */ +} ump_descriptor_table; + +/** + * The descriptor mapping object + * Provides a separate namespace where we can map an integer to a pointer + */ +typedef struct ump_descriptor_mapping +{ + _mali_osk_lock_t *lock; /**< Lock protecting access to the mapping object */ + int max_nr_mappings_allowed; /**< Max number of mappings to support in this namespace */ + int current_nr_mappings; /**< Current number of possible mappings */ + ump_descriptor_table * table; /**< Pointer to the current mapping table */ +} ump_descriptor_mapping; + +/** + * Create a descriptor mapping object + * Create a descriptor mapping capable of holding init_entries growable to max_entries + * @param init_entries Number of entries to preallocate memory for + * @param max_entries Number of entries to max support + * @return Pointer to a descriptor mapping object, NULL on failure + */ +ump_descriptor_mapping * ump_descriptor_mapping_create(int init_entries, int max_entries); + +/** + * Destroy a descriptor mapping object + * @param map The map to free + */ +void ump_descriptor_mapping_destroy(ump_descriptor_mapping * map); + +/** + * Allocate a new mapping entry (descriptor ID) + * Allocates a new entry in the map. + * @param map The map to allocate a new entry in + * @param target The value to map to + * @return The descriptor allocated, a negative value on error + */ +int ump_descriptor_mapping_allocate_mapping(ump_descriptor_mapping * map, void * target); + +/** + * Get the value mapped to by a descriptor ID + * @param map The map to lookup the descriptor id in + * @param descriptor The descriptor ID to lookup + * @param target Pointer to a pointer which will receive the stored value + * @return 0 on successful lookup, negative on error + */ +int ump_descriptor_mapping_get(ump_descriptor_mapping * map, int descriptor, void** target); + +/** + * Set the value mapped to by a descriptor ID + * @param map The map to lookup the descriptor id in + * @param descriptor The descriptor ID to lookup + * @param target Pointer to replace the current value with + * @return 0 on successful lookup, negative on error + */ +int ump_descriptor_mapping_set(ump_descriptor_mapping * map, int descriptor, void * target); + +/** + * Free the descriptor ID + * For the descriptor to be reused it has to be freed + * @param map The map to free the descriptor from + * @param descriptor The descriptor ID to free + */ +void ump_descriptor_mapping_free(ump_descriptor_mapping * map, int descriptor); + +#endif /* __UMP_KERNEL_DESCRIPTOR_MAPPING_H__ */ diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_memory_backend.h b/drivers/media/video/samsung/ump/common/ump_kernel_memory_backend.h new file mode 100644 index 0000000..73915ee --- /dev/null +++ b/drivers/media/video/samsung/ump/common/ump_kernel_memory_backend.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file ump_kernel_memory_mapping.h + */ + +#ifndef __UMP_KERNEL_MEMORY_BACKEND_H__ +#define __UMP_KERNEL_MEMORY_BACKEND_H__ + +#include "ump_kernel_interface.h" +#include "ump_kernel_types.h" + + +typedef struct ump_memory_allocation +{ + void * phys_addr; + void * mapping; + unsigned long size; + ump_dd_handle handle; + void * process_mapping_info; + u32 cookie; /**< necessary on some U/K interface implementations */ + struct ump_session_data * ump_session; /**< Session that this allocation belongs to */ + _mali_osk_list_t list; /**< List for linking together memory allocations into the session's memory head */ + u32 is_cached; +} ump_memory_allocation; + +typedef struct ump_memory_backend +{ + int (*allocate)(void* ctx, ump_dd_mem * descriptor); + void (*release)(void* ctx, ump_dd_mem * descriptor); + void (*shutdown)(struct ump_memory_backend * backend); + u32 (*stat)(struct ump_memory_backend *backend); + int (*pre_allocate_physical_check)(void *ctx, u32 size); + u32 (*adjust_to_mali_phys)(void *ctx, u32 cpu_phys); + void *(*get)(ump_dd_mem *mem, void *args); + void (*set)(ump_dd_mem *mem, void *args); + void * ctx; +} ump_memory_backend; + +ump_memory_backend * ump_memory_backend_create ( void ); +void ump_memory_backend_destroy( void ); + +#endif /*__UMP_KERNEL_MEMORY_BACKEND_H__ */ diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_ref_drv.c b/drivers/media/video/samsung/ump/common/ump_kernel_ref_drv.c new file mode 100644 index 0000000..cb13232 --- /dev/null +++ b/drivers/media/video/samsung/ump/common/ump_kernel_ref_drv.c @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_osk.h" +#include "mali_osk_list.h" +#include "ump_osk.h" +#include "ump_uk_types.h" + +#include "ump_kernel_interface_ref_drv.h" +#include "ump_kernel_common.h" +#include "ump_kernel_descriptor_mapping.h" + +#define UMP_MINIMUM_SIZE 4096 +#define UMP_MINIMUM_SIZE_MASK (~(UMP_MINIMUM_SIZE-1)) +#define UMP_SIZE_ALIGN(x) (((x)+UMP_MINIMUM_SIZE-1)&UMP_MINIMUM_SIZE_MASK) +#define UMP_ADDR_ALIGN_OFFSET(x) ((x)&(UMP_MINIMUM_SIZE-1)) +static void phys_blocks_release(void * ctx, struct ump_dd_mem * descriptor); + +UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_phys_blocks(ump_dd_physical_block * blocks, unsigned long num_blocks) +{ + ump_dd_mem * mem; + unsigned long size_total = 0; + int map_id; + u32 i; + + /* Go through the input blocks and verify that they are sane */ + for (i=0; i < num_blocks; i++) + { + unsigned long addr = blocks[i].addr; + unsigned long size = blocks[i].size; + + DBG_MSG(5, ("Adding physical memory to new handle. Address: 0x%08lx, size: %lu\n", addr, size)); + size_total += blocks[i].size; + + if (0 != UMP_ADDR_ALIGN_OFFSET(addr)) + { + MSG_ERR(("Trying to create UMP memory from unaligned physical address. Address: 0x%08lx\n", addr)); + return UMP_DD_HANDLE_INVALID; + } + + if (0 != UMP_ADDR_ALIGN_OFFSET(size)) + { + MSG_ERR(("Trying to create UMP memory with unaligned size. Size: %lu\n", size)); + return UMP_DD_HANDLE_INVALID; + } + } + + /* Allocate the ump_dd_mem struct for this allocation */ + mem = _mali_osk_malloc(sizeof(*mem)); + if (NULL == mem) + { + DBG_MSG(1, ("Could not allocate ump_dd_mem in ump_dd_handle_create_from_phys_blocks()\n")); + return UMP_DD_HANDLE_INVALID; + } + + /* Find a secure ID for this allocation */ + _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + map_id = ump_descriptor_mapping_allocate_mapping(device.secure_id_map, (void*) mem); + + if (map_id < 0) + { + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + _mali_osk_free(mem); + DBG_MSG(1, ("Failed to allocate secure ID in ump_dd_handle_create_from_phys_blocks()\n")); + return UMP_DD_HANDLE_INVALID; + } + + /* Now, make a copy of the block information supplied by the user */ + mem->block_array = _mali_osk_malloc(sizeof(ump_dd_physical_block)* num_blocks); + if (NULL == mem->block_array) + { + ump_descriptor_mapping_free(device.secure_id_map, map_id); + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + _mali_osk_free(mem); + DBG_MSG(1, ("Could not allocate a mem handle for function ump_dd_handle_create_from_phys_blocks().\n")); + return UMP_DD_HANDLE_INVALID; + } + + _mali_osk_memcpy(mem->block_array, blocks, sizeof(ump_dd_physical_block) * num_blocks); + + /* And setup the rest of the ump_dd_mem struct */ + _mali_osk_atomic_init(&mem->ref_count, 1); + mem->secure_id = (ump_secure_id)map_id; + mem->size_bytes = size_total; + mem->nr_blocks = num_blocks; + mem->backend_info = NULL; + mem->ctx = NULL; + mem->release_func = phys_blocks_release; + /* For now UMP handles created by ump_dd_handle_create_from_phys_blocks() is forced to be Uncached */ + mem->is_cached = 0; + mem->hw_device = _UMP_UK_USED_BY_CPU; + mem->lock_usage = UMP_NOT_LOCKED; + + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + DBG_MSG(3, ("UMP memory created. ID: %u, size: %lu\n", mem->secure_id, mem->size_bytes)); + + return (ump_dd_handle)mem; +} + +static void phys_blocks_release(void * ctx, struct ump_dd_mem * descriptor) +{ + _mali_osk_free(descriptor->block_array); + descriptor->block_array = NULL; +} + +_mali_osk_errcode_t _ump_ukk_allocate( _ump_uk_allocate_s *user_interaction ) +{ + ump_session_data * session_data = NULL; + ump_dd_mem *new_allocation = NULL; + ump_session_memory_list_element * session_memory_element = NULL; + int map_id; + + DEBUG_ASSERT_POINTER( user_interaction ); + DEBUG_ASSERT_POINTER( user_interaction->ctx ); + + session_data = (ump_session_data *) user_interaction->ctx; + + session_memory_element = _mali_osk_calloc( 1, sizeof(ump_session_memory_list_element)); + if (NULL == session_memory_element) + { + DBG_MSG(1, ("Failed to allocate ump_session_memory_list_element in ump_ioctl_allocate()\n")); + return _MALI_OSK_ERR_NOMEM; + } + + + new_allocation = _mali_osk_calloc( 1, sizeof(ump_dd_mem)); + if (NULL==new_allocation) + { + _mali_osk_free(session_memory_element); + DBG_MSG(1, ("Failed to allocate ump_dd_mem in _ump_ukk_allocate()\n")); + return _MALI_OSK_ERR_NOMEM; + } + + /* Create a secure ID for this allocation */ + _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + map_id = ump_descriptor_mapping_allocate_mapping(device.secure_id_map, (void*)new_allocation); + + if (map_id < 0) + { + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + _mali_osk_free(session_memory_element); + _mali_osk_free(new_allocation); + DBG_MSG(1, ("Failed to allocate secure ID in ump_ioctl_allocate()\n")); + return - _MALI_OSK_ERR_INVALID_FUNC; + } + + /* Initialize the part of the new_allocation that we know so for */ + new_allocation->secure_id = (ump_secure_id)map_id; + _mali_osk_atomic_init(&new_allocation->ref_count,1); + if ( 0==(UMP_REF_DRV_UK_CONSTRAINT_USE_CACHE & user_interaction->constraints) ) + new_allocation->is_cached = 0; + else new_allocation->is_cached = 1; + + /* special case a size of 0, we should try to emulate what malloc does in this case, which is to return a valid pointer that must be freed, but can't be dereferences */ + if (0 == user_interaction->size) + { + user_interaction->size = 1; /* emulate by actually allocating the minimum block size */ + } + + new_allocation->size_bytes = UMP_SIZE_ALIGN(user_interaction->size); /* Page align the size */ + new_allocation->lock_usage = UMP_NOT_LOCKED; + + /* Now, ask the active memory backend to do the actual memory allocation */ + if (!device.backend->allocate( device.backend->ctx, new_allocation ) ) + { + DBG_MSG(3, ("OOM: No more UMP memory left. Failed to allocate memory in ump_ioctl_allocate(). Size: %lu, requested size: %lu\n", new_allocation->size_bytes, (unsigned long)user_interaction->size)); + ump_descriptor_mapping_free(device.secure_id_map, map_id); + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + _mali_osk_free(new_allocation); + _mali_osk_free(session_memory_element); + return _MALI_OSK_ERR_INVALID_FUNC; + } + new_allocation->hw_device = _UMP_UK_USED_BY_CPU; + new_allocation->ctx = device.backend->ctx; + new_allocation->release_func = device.backend->release; + + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + + /* Initialize the session_memory_element, and add it to the session object */ + session_memory_element->mem = new_allocation; + _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); + _mali_osk_list_add(&(session_memory_element->list), &(session_data->list_head_session_memory_list)); + _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); + + user_interaction->secure_id = new_allocation->secure_id; + user_interaction->size = new_allocation->size_bytes; + DBG_MSG(3, ("UMP memory allocated. ID: %u, size: %lu\n", new_allocation->secure_id, new_allocation->size_bytes)); + + return _MALI_OSK_ERR_OK; +} + + +UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_meminfo_set(ump_dd_handle memh, void* args) +{ + ump_dd_mem * mem; + ump_secure_id secure_id; + + DEBUG_ASSERT_POINTER(memh); + + secure_id = ump_dd_secure_id_get(memh); + + _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + if (0 == ump_descriptor_mapping_get(device.secure_id_map, (int)secure_id, (void**)&mem)) + { + device.backend->set(mem, args); + } + else + { + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + DBG_MSG(1, ("Failed to look up mapping in ump_meminfo_set(). ID: %u\n", (ump_secure_id)secure_id)); + return UMP_DD_INVALID; + } + + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + + return UMP_DD_SUCCESS; +} + +UMP_KERNEL_API_EXPORT void *ump_dd_meminfo_get(ump_secure_id secure_id, void* args) +{ + ump_dd_mem * mem; + void *result; + + _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + if (0 == ump_descriptor_mapping_get(device.secure_id_map, (int)secure_id, (void**)&mem)) + { + result = device.backend->get(mem, args); + } + else + { + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + DBG_MSG(1, ("Failed to look up mapping in ump_meminfo_get(). ID: %u\n", (ump_secure_id)secure_id)); + return UMP_DD_HANDLE_INVALID; + } + + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + + return result; +} + +UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_get_from_vaddr(unsigned long vaddr) +{ + ump_dd_mem * mem; + + DBG_MSG(5, ("Getting handle from Virtual address. vaddr: %u\n", vaddr)); + + _ump_osk_mem_mapregion_get(&mem, vaddr); + + DBG_MSG(1, ("Getting handle's Handle : 0x%8lx\n", mem)); + + return (ump_dd_handle)mem; +} + diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_types.h b/drivers/media/video/samsung/ump/common/ump_kernel_types.h new file mode 100644 index 0000000..19a9755 --- /dev/null +++ b/drivers/media/video/samsung/ump/common/ump_kernel_types.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __UMP_KERNEL_TYPES_H__ +#define __UMP_KERNEL_TYPES_H__ + +#include "ump_kernel_interface.h" +#include "mali_osk.h" + + +typedef enum +{ + UMP_USED_BY_CPU = 0, + UMP_USED_BY_MALI = 1, + UMP_USED_BY_UNKNOWN_DEVICE= 100, +} ump_hw_usage; + +typedef enum +{ + UMP_NOT_LOCKED = 0, + UMP_READ = 1, + UMP_READ_WRITE = 3, +} ump_lock_usage; + + +/* + * This struct is what is "behind" a ump_dd_handle + */ +typedef struct ump_dd_mem +{ + ump_secure_id secure_id; + _mali_osk_atomic_t ref_count; + unsigned long size_bytes; + unsigned long nr_blocks; + ump_dd_physical_block * block_array; + void (*release_func)(void * ctx, struct ump_dd_mem * descriptor); + void * ctx; + void * backend_info; + int is_cached; + ump_hw_usage hw_device; + ump_lock_usage lock_usage; +} ump_dd_mem; + + + +#endif /* __UMP_KERNEL_TYPES_H__ */ diff --git a/drivers/media/video/samsung/ump/common/ump_osk.h b/drivers/media/video/samsung/ump/common/ump_osk.h new file mode 100644 index 0000000..dabdc7f --- /dev/null +++ b/drivers/media/video/samsung/ump/common/ump_osk.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file ump_osk.h + * Defines the OS abstraction layer for the UMP kernel device driver (OSK) + */ + +#ifndef __UMP_OSK_H__ +#define __UMP_OSK_H__ + +#include +#include +#include "ump_uk_types.h" +#include "ump_kernel_common.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +_mali_osk_errcode_t _ump_osk_init( void ); + +_mali_osk_errcode_t _ump_osk_term( void ); + +int _ump_osk_atomic_inc_and_read( _mali_osk_atomic_t *atom ); + +int _ump_osk_atomic_dec_and_read( _mali_osk_atomic_t *atom ); + +_mali_osk_errcode_t _ump_osk_mem_mapregion_init( ump_memory_allocation *descriptor ); + +_mali_osk_errcode_t _ump_osk_mem_mapregion_map( ump_memory_allocation * descriptor, u32 offset, u32 * phys_addr, unsigned long size ); + +void _ump_osk_mem_mapregion_term( ump_memory_allocation * descriptor ); + +void _ump_osk_msync( ump_dd_mem * mem, void * virt, u32 offset, u32 size, ump_uk_msync_op op, ump_session_data * session_data ); + +void _ump_osk_mem_mapregion_get( ump_dd_mem ** mem, unsigned long vaddr); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/media/video/samsung/ump/common/ump_uk_types.h b/drivers/media/video/samsung/ump/common/ump_uk_types.h new file mode 100644 index 0000000..143588d --- /dev/null +++ b/drivers/media/video/samsung/ump/common/ump_uk_types.h @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file ump_uk_types.h + * Defines the types and constants used in the user-kernel interface + */ + +#ifndef __UMP_UK_TYPES_H__ +#define __UMP_UK_TYPES_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Helpers for API version handling */ +#define MAKE_VERSION_ID(x) (((x) << 16UL) | (x)) +#define IS_VERSION_ID(x) (((x) & 0xFFFF) == (((x) >> 16UL) & 0xFFFF)) +#define GET_VERSION(x) (((x) >> 16UL) & 0xFFFF) +#define IS_API_MATCH(x, y) (IS_VERSION_ID((x)) && IS_VERSION_ID((y)) && (GET_VERSION((x)) == GET_VERSION((y)))) + +/** + * API version define. + * Indicates the version of the kernel API + * The version is a 16bit integer incremented on each API change. + * The 16bit integer is stored twice in a 32bit integer + * So for version 1 the value would be 0x00010001 + */ +#define UMP_IOCTL_API_VERSION MAKE_VERSION_ID(2) + +typedef enum +{ + _UMP_IOC_QUERY_API_VERSION = 1, + _UMP_IOC_ALLOCATE, + _UMP_IOC_RELEASE, + _UMP_IOC_SIZE_GET, + _UMP_IOC_MAP_MEM, /* not used in Linux */ + _UMP_IOC_UNMAP_MEM, /* not used in Linux */ + _UMP_IOC_MSYNC, + _UMP_IOC_CACHE_OPERATIONS_CONTROL, + _UMP_IOC_SWITCH_HW_USAGE, + _UMP_IOC_LOCK, + _UMP_IOC_UNLOCK, +#ifdef CONFIG_ION_EXYNOS + _UMP_IOC_ION_IMPORT, +#endif +}_ump_uk_functions; + +typedef enum +{ + UMP_REF_DRV_UK_CONSTRAINT_NONE = 0, + UMP_REF_DRV_UK_CONSTRAINT_PHYSICALLY_LINEAR = 1, + UMP_REF_DRV_UK_CONSTRAINT_USE_CACHE = 128, +} ump_uk_alloc_constraints; + +typedef enum +{ + _UMP_UK_MSYNC_CLEAN = 0, + _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE = 1, + _UMP_UK_MSYNC_INVALIDATE = 2, + _UMP_UK_MSYNC_FLUSH_L1 = 3, + _UMP_UK_MSYNC_READOUT_CACHE_ENABLED = 128, +} ump_uk_msync_op; + +typedef enum +{ + _UMP_UK_CACHE_OP_START = 0, + _UMP_UK_CACHE_OP_FINISH = 1, +} ump_uk_cache_op_control; + +typedef enum +{ + _UMP_UK_READ = 1, + _UMP_UK_READ_WRITE = 3, +} ump_uk_lock_usage; + +typedef enum +{ + _UMP_UK_USED_BY_CPU = 0, + _UMP_UK_USED_BY_MALI = 1, + _UMP_UK_USED_BY_UNKNOWN_DEVICE= 100, +} ump_uk_user; + +/** + * Get API version ([in,out] u32 api_version, [out] u32 compatible) + */ +typedef struct _ump_uk_api_version_s +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 version; /**< Set to the user space version on entry, stores the device driver version on exit */ + u32 compatible; /**< Non-null if the device is compatible with the client */ +} _ump_uk_api_version_s; + +/** + * ALLOCATE ([out] u32 secure_id, [in,out] u32 size, [in] contraints) + */ +typedef struct _ump_uk_allocate_s +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 secure_id; /**< Return value from DD to Userdriver */ + u32 size; /**< Input and output. Requested size; input. Returned size; output */ + ump_uk_alloc_constraints constraints; /**< Only input to Devicedriver */ +} _ump_uk_allocate_s; + +#ifdef CONFIG_ION_EXYNOS +typedef struct _ump_uk_ion_import_s +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + int ion_fd; /**< ion_fd */ + u32 secure_id; /**< Return value from DD to Userdriver */ + u32 size; /**< Input and output. Requested size; input. Returned size; output */ + ump_uk_alloc_constraints constraints; /**< Only input to Devicedriver */ +} _ump_uk_ion_import_s; +#endif + +/** + * SIZE_GET ([in] u32 secure_id, [out]size ) + */ +typedef struct _ump_uk_size_get_s +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 secure_id; /**< Input to DD */ + u32 size; /**< Returned size; output */ +} _ump_uk_size_get_s; + +/** + * Release ([in] u32 secure_id) + */ +typedef struct _ump_uk_release_s +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 secure_id; /**< Input to DD */ +} _ump_uk_release_s; + +typedef struct _ump_uk_map_mem_s +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + void *mapping; /**< [out] Returns user-space virtual address for the mapping */ + void *phys_addr; /**< [in] physical address */ + unsigned long size; /**< [in] size */ + u32 secure_id; /**< [in] secure_id to assign to mapping */ + void * _ukk_private; /**< Only used inside linux port between kernel frontend and common part to store vma */ + u32 cookie; + u32 is_cached; /**< [in,out] caching of CPU mappings */ +} _ump_uk_map_mem_s; + +typedef struct _ump_uk_unmap_mem_s +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + void *mapping; + u32 size; + void * _ukk_private; + u32 cookie; +} _ump_uk_unmap_mem_s; + +typedef struct _ump_uk_msync_s +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + void *mapping; /**< [in] mapping addr */ + void *address; /**< [in] flush start addr */ + u32 size; /**< [in] size to flush */ + ump_uk_msync_op op; /**< [in] flush operation */ + u32 cookie; /**< [in] cookie stored with reference to the kernel mapping internals */ + u32 secure_id; /**< [in] secure_id that identifies the ump buffer */ + u32 is_cached; /**< [out] caching of CPU mappings */ +} _ump_uk_msync_s; + +typedef struct _ump_uk_cache_operations_control_s +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + ump_uk_cache_op_control op; /**< [in] cache operations start/stop */ +} _ump_uk_cache_operations_control_s; + + +typedef struct _ump_uk_switch_hw_usage_s +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 secure_id; /**< [in] secure_id that identifies the ump buffer */ + ump_uk_user new_user; /**< [in] cookie stored with reference to the kernel mapping internals */ + +} _ump_uk_switch_hw_usage_s; + +typedef struct _ump_uk_lock_s +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 secure_id; /**< [in] secure_id that identifies the ump buffer */ + ump_uk_lock_usage lock_usage; +} _ump_uk_lock_s; + +typedef struct _ump_uk_unlock_s +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 secure_id; /**< [in] secure_id that identifies the ump buffer */ +} _ump_uk_unlock_s; + +#ifdef __cplusplus +} +#endif + +#endif /* __UMP_UK_TYPES_H__ */ diff --git a/drivers/media/video/samsung/ump/common/ump_ukk.h b/drivers/media/video/samsung/ump/common/ump_ukk.h new file mode 100644 index 0000000..56e4be3 --- /dev/null +++ b/drivers/media/video/samsung/ump/common/ump_ukk.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file ump_ukk.h + * Defines the kernel-side interface of the user-kernel interface + */ + +#ifndef __UMP_UKK_H__ +#define __UMP_UKK_H__ + +#include "mali_osk.h" +#include "ump_uk_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +_mali_osk_errcode_t _ump_ukk_open( void** context ); + +_mali_osk_errcode_t _ump_ukk_close( void** context ); + +_mali_osk_errcode_t _ump_ukk_allocate( _ump_uk_allocate_s *user_interaction ); + +_mali_osk_errcode_t _ump_ukk_release( _ump_uk_release_s *release_info ); + +_mali_osk_errcode_t _ump_ukk_size_get( _ump_uk_size_get_s *user_interaction ); + +_mali_osk_errcode_t _ump_ukk_map_mem( _ump_uk_map_mem_s *args ); + +_mali_osk_errcode_t _ump_uku_get_api_version( _ump_uk_api_version_s *args ); + +void _ump_ukk_unmap_mem( _ump_uk_unmap_mem_s *args ); + +void _ump_ukk_msync( _ump_uk_msync_s *args ); + +void _ump_ukk_cache_operations_control(_ump_uk_cache_operations_control_s* args); + +void _ump_ukk_switch_hw_usage(_ump_uk_switch_hw_usage_s *args ); + +void _ump_ukk_lock(_ump_uk_lock_s *args ); + +void _ump_ukk_unlock(_ump_uk_unlock_s *args ); + +u32 _ump_ukk_report_memory_usage( void ); + +#ifdef __cplusplus +} +#endif + +#endif /* __UMP_UKK_H__ */ diff --git a/drivers/media/video/samsung/ump/include/ump_kernel_interface.h b/drivers/media/video/samsung/ump/include/ump_kernel_interface.h new file mode 100644 index 0000000..042c8b1 --- /dev/null +++ b/drivers/media/video/samsung/ump/include/ump_kernel_interface.h @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file ump_kernel_interface.h + * + * This file contains the kernel space part of the UMP API. + */ + +#ifndef __UMP_KERNEL_INTERFACE_H__ +#define __UMP_KERNEL_INTERFACE_H__ + + +/** @defgroup ump_kernel_space_api UMP Kernel Space API + * @{ */ + + +#include "ump_kernel_platform.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** + * External representation of a UMP handle in kernel space. + */ +typedef void * ump_dd_handle; + +/** + * Typedef for a secure ID, a system wide identificator for UMP memory buffers. + */ +typedef unsigned int ump_secure_id; + + +/** + * Value to indicate an invalid UMP memory handle. + */ +#define UMP_DD_HANDLE_INVALID ((ump_dd_handle)0) + + +/** + * Value to indicate an invalid secure Id. + */ +#define UMP_INVALID_SECURE_ID ((ump_secure_id)-1) + + +/** + * UMP error codes for kernel space. + */ +typedef enum +{ + UMP_DD_SUCCESS, /**< indicates success */ + UMP_DD_INVALID, /**< indicates failure */ +} ump_dd_status_code; + + +/** + * Struct used to describe a physical block used by UMP memory + */ +typedef struct ump_dd_physical_block +{ + unsigned long addr; /**< The physical address of the block */ + unsigned long size; /**< The length of the block, typically page aligned */ +} ump_dd_physical_block; + + +/** + * Retrieves the secure ID for the specified UMP memory. + * + * This identificator is unique across the entire system, and uniquely identifies + * the specified UMP memory. This identificator can later be used through the + * @ref ump_dd_handle_create_from_secure_id "ump_dd_handle_create_from_secure_id" or + * @ref ump_handle_create_from_secure_id "ump_handle_create_from_secure_id" + * functions in order to access this UMP memory, for instance from another process. + * + * @note There is a user space equivalent function called @ref ump_secure_id_get "ump_secure_id_get" + * + * @see ump_dd_handle_create_from_secure_id + * @see ump_handle_create_from_secure_id + * @see ump_secure_id_get + * + * @param mem Handle to UMP memory. + * + * @return Returns the secure ID for the specified UMP memory. + */ +UMP_KERNEL_API_EXPORT ump_secure_id ump_dd_secure_id_get(ump_dd_handle mem); + + +/** + * Retrieves a handle to allocated UMP memory. + * + * The usage of UMP memory is reference counted, so this will increment the reference + * count by one for the specified UMP memory. + * Use @ref ump_dd_reference_release "ump_dd_reference_release" when there is no longer any + * use for the retrieved handle. + * + * @note There is a user space equivalent function called @ref ump_handle_create_from_secure_id "ump_handle_create_from_secure_id" + * + * @see ump_dd_reference_release + * @see ump_handle_create_from_secure_id + * + * @param secure_id The secure ID of the UMP memory to open, that can be retrieved using the @ref ump_secure_id_get "ump_secure_id_get " function. + * + * @return UMP_INVALID_MEMORY_HANDLE indicates failure, otherwise a valid handle is returned. + */ +UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_secure_id(ump_secure_id secure_id); + + +/** + * Retrieves the number of physical blocks used by the specified UMP memory. + * + * This function retrieves the number of @ref ump_dd_physical_block "ump_dd_physical_block" structs needed + * to describe the physical memory layout of the given UMP memory. This can later be used when calling + * the functions @ref ump_dd_phys_blocks_get "ump_dd_phys_blocks_get" and + * @ref ump_dd_phys_block_get "ump_dd_phys_block_get". + * + * @see ump_dd_phys_blocks_get + * @see ump_dd_phys_block_get + * + * @param mem Handle to UMP memory. + * + * @return The number of ump_dd_physical_block structs required to describe the physical memory layout of the specified UMP memory. + */ +UMP_KERNEL_API_EXPORT unsigned long ump_dd_phys_block_count_get(ump_dd_handle mem); + + +/** + * Retrieves all physical memory block information for specified UMP memory. + * + * This function can be used by other device drivers in order to create MMU tables. + * + * @note This function will fail if the num_blocks parameter is either to large or to small. + * + * @see ump_dd_phys_block_get + * + * @param mem Handle to UMP memory. + * @param blocks An array of @ref ump_dd_physical_block "ump_dd_physical_block" structs that will receive the physical description. + * @param num_blocks The number of blocks to return in the blocks array. Use the function + * @ref ump_dd_phys_block_count_get "ump_dd_phys_block_count_get" first to determine the number of blocks required. + * + * @return UMP_DD_SUCCESS indicates success, UMP_DD_INVALID indicates failure. + */ +UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_phys_blocks_get(ump_dd_handle mem, ump_dd_physical_block * blocks, unsigned long num_blocks); + + +/** + * Retrieves the physical memory block information for specified block for the specified UMP memory. + * + * This function can be used by other device drivers in order to create MMU tables. + * + * @note This function will return UMP_DD_INVALID if the specified index is out of range. + * + * @see ump_dd_phys_blocks_get + * + * @param mem Handle to UMP memory. + * @param index Which physical info block to retrieve. + * @param block Pointer to a @ref ump_dd_physical_block "ump_dd_physical_block" struct which will receive the requested information. + * + * @return UMP_DD_SUCCESS indicates success, UMP_DD_INVALID indicates failure. + */ +UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_phys_block_get(ump_dd_handle mem, unsigned long index, ump_dd_physical_block * block); + + +/** + * Retrieves the actual size of the specified UMP memory. + * + * The size is reported in bytes, and is typically page aligned. + * + * @note There is a user space equivalent function called @ref ump_size_get "ump_size_get" + * + * @see ump_size_get + * + * @param mem Handle to UMP memory. + * + * @return Returns the allocated size of the specified UMP memory, in bytes. + */ +UMP_KERNEL_API_EXPORT unsigned long ump_dd_size_get(ump_dd_handle mem); + + +/** + * Adds an extra reference to the specified UMP memory. + * + * This function adds an extra reference to the specified UMP memory. This function should + * be used every time a UMP memory handle is duplicated, that is, assigned to another ump_dd_handle + * variable. The function @ref ump_dd_reference_release "ump_dd_reference_release" must then be used + * to release each copy of the UMP memory handle. + * + * @note You are not required to call @ref ump_dd_reference_add "ump_dd_reference_add" + * for UMP handles returned from + * @ref ump_dd_handle_create_from_secure_id "ump_dd_handle_create_from_secure_id", + * because these handles are already reference counted by this function. + * + * @note There is a user space equivalent function called @ref ump_reference_add "ump_reference_add" + * + * @see ump_reference_add + * + * @param mem Handle to UMP memory. + */ +UMP_KERNEL_API_EXPORT void ump_dd_reference_add(ump_dd_handle mem); + + +/** + * Releases a reference from the specified UMP memory. + * + * This function should be called once for every reference to the UMP memory handle. + * When the last reference is released, all resources associated with this UMP memory + * handle are freed. + * + * @note There is a user space equivalent function called @ref ump_reference_release "ump_reference_release" + * + * @see ump_reference_release + * + * @param mem Handle to UMP memory. + */ +UMP_KERNEL_API_EXPORT void ump_dd_reference_release(ump_dd_handle mem); + + +#ifdef __cplusplus +} +#endif + + +/** @} */ /* end group ump_kernel_space_api */ + + +#endif /* __UMP_KERNEL_INTERFACE_H__ */ diff --git a/drivers/media/video/samsung/ump/include/ump_kernel_interface_ref_drv.h b/drivers/media/video/samsung/ump/include/ump_kernel_interface_ref_drv.h new file mode 100644 index 0000000..36c5c9d --- /dev/null +++ b/drivers/media/video/samsung/ump/include/ump_kernel_interface_ref_drv.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file ump_kernel_interface.h + */ + +#ifndef __UMP_KERNEL_INTERFACE_REF_DRV_H__ +#define __UMP_KERNEL_INTERFACE_REF_DRV_H__ + +#include "ump_kernel_interface.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Turn specified physical memory into UMP memory. */ +UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_phys_blocks(ump_dd_physical_block * blocks, unsigned long num_blocks); +UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_get(ump_secure_id secure_id); +UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_meminfo_set(ump_dd_handle memh, void* args); +UMP_KERNEL_API_EXPORT void *ump_dd_meminfo_get(ump_secure_id secure_id, void* args); +UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_get_from_vaddr(unsigned long vaddr); + +#ifdef __cplusplus +} +#endif + +#endif /* __UMP_KERNEL_INTERFACE_REF_DRV_H__ */ diff --git a/drivers/media/video/samsung/ump/include/ump_kernel_platform.h b/drivers/media/video/samsung/ump/include/ump_kernel_platform.h new file mode 100644 index 0000000..4349605 --- /dev/null +++ b/drivers/media/video/samsung/ump/include/ump_kernel_platform.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file ump_kernel_platform.h + * + * This file should define UMP_KERNEL_API_EXPORT, + * which dictates how the UMP kernel API should be exported/imported. + * Modify this file, if needed, to match your platform setup. + */ + +#ifndef __UMP_KERNEL_PLATFORM_H__ +#define __UMP_KERNEL_PLATFORM_H__ + +/** @addtogroup ump_kernel_space_api + * @{ */ + +/** + * A define which controls how UMP kernel space API functions are imported and exported. + * This define should be set by the implementor of the UMP API. + */ + +#if defined(_WIN32) + +#if defined(UMP_BUILDING_UMP_LIBRARY) +#define UMP_KERNEL_API_EXPORT __declspec(dllexport) +#else +#define UMP_KERNEL_API_EXPORT __declspec(dllimport) +#endif + +#else + +#define UMP_KERNEL_API_EXPORT + +#endif + + +/** @} */ /* end group ump_kernel_space_api */ + + +#endif /* __UMP_KERNEL_PLATFORM_H__ */ diff --git a/drivers/media/video/samsung/ump/linux/license/gpl/ump_kernel_license.h b/drivers/media/video/samsung/ump/linux/license/gpl/ump_kernel_license.h new file mode 100644 index 0000000..187e33b --- /dev/null +++ b/drivers/media/video/samsung/ump/linux/license/gpl/ump_kernel_license.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file ump_kernel_license.h + * Defines for the macro MODULE_LICENSE. + */ + +#ifndef __UMP_KERNEL_LICENSE_H__ +#define __UMP_KERNEL_LICENSE_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define UMP_KERNEL_LINUX_LICENSE "GPL" +#define UMP_LICENSE_IS_GPL 1 + +#ifdef __cplusplus +} +#endif + +#endif /* __UMP_KERNEL_LICENSE_H__ */ diff --git a/drivers/media/video/samsung/ump/linux/ump_ioctl.h b/drivers/media/video/samsung/ump/linux/ump_ioctl.h new file mode 100644 index 0000000..83bb2a4 --- /dev/null +++ b/drivers/media/video/samsung/ump/linux/ump_ioctl.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __UMP_IOCTL_H__ +#define __UMP_IOCTL_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include + +#include + +#ifndef __user +#define __user +#endif + + +/** + * @file UMP_ioctl.h + * This file describes the interface needed to use the Linux device driver. + * The interface is used by the userpace UMP driver. + */ + +#define UMP_IOCTL_NR 0x90 + + +#define UMP_IOC_QUERY_API_VERSION _IOR(UMP_IOCTL_NR, _UMP_IOC_QUERY_API_VERSION, _ump_uk_api_version_s) +#define UMP_IOC_ALLOCATE _IOWR(UMP_IOCTL_NR, _UMP_IOC_ALLOCATE, _ump_uk_allocate_s) +#define UMP_IOC_RELEASE _IOR(UMP_IOCTL_NR, _UMP_IOC_RELEASE, _ump_uk_release_s) +#define UMP_IOC_SIZE_GET _IOWR(UMP_IOCTL_NR, _UMP_IOC_SIZE_GET, _ump_uk_size_get_s) +#define UMP_IOC_MSYNC _IOW(UMP_IOCTL_NR, _UMP_IOC_MSYNC, _ump_uk_msync_s) +#ifdef CONFIG_ION_EXYNOS +#define UMP_IOC_ION_IMPORT _IOW(UMP_IOCTL_NR, _UMP_IOC_ION_IMPORT, _ump_uk_ion_import_s) +#endif +#ifdef CONFIG_DMA_SHARED_BUFFER +#define UMP_IOC_DMABUF_IMPORT _IOW(UMP_IOCTL_NR, _UMP_IOC_DMABUF_IMPORT,\ + struct ump_uk_dmabuf) +#endif + +#define UMP_IOC_CACHE_OPERATIONS_CONTROL _IOW(UMP_IOCTL_NR, _UMP_IOC_CACHE_OPERATIONS_CONTROL, _ump_uk_cache_operations_control_s) +#define UMP_IOC_SWITCH_HW_USAGE _IOW(UMP_IOCTL_NR, _UMP_IOC_SWITCH_HW_USAGE, _ump_uk_switch_hw_usage_s) +#define UMP_IOC_LOCK _IOW(UMP_IOCTL_NR, _UMP_IOC_LOCK, _ump_uk_lock_s) +#define UMP_IOC_UNLOCK _IOW(UMP_IOCTL_NR, _UMP_IOC_UNLOCK, _ump_uk_unlock_s) + + +#ifdef __cplusplus +} +#endif + +#endif /* __UMP_IOCTL_H__ */ diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_linux.c b/drivers/media/video/samsung/ump/linux/ump_kernel_linux.c new file mode 100644 index 0000000..a358a3c --- /dev/null +++ b/drivers/media/video/samsung/ump/linux/ump_kernel_linux.c @@ -0,0 +1,492 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include /* kernel module definitions */ +#include /* file system operations */ +#include /* character device definitions */ +#include /* request_mem_region */ +#include /* memory management functions and types */ +#include /* user space access */ +#include +#include +#include + +#include "arch/config.h" /* Configuration for current platform. The symlinc for arch is set by Makefile */ +#include "ump_ioctl.h" +#include "ump_kernel_common.h" +#include "ump_kernel_interface.h" +#include "ump_kernel_interface_ref_drv.h" +#include "ump_kernel_descriptor_mapping.h" +#include "ump_kernel_memory_backend.h" +#include "ump_kernel_memory_backend_os.h" +#include "ump_kernel_memory_backend_dedicated.h" +#include "ump_kernel_license.h" + +#include "ump_osk.h" +#include "ump_ukk.h" +#include "ump_uk_types.h" +#include "ump_ukk_wrappers.h" +#include "ump_ukk_ref_wrappers.h" + +#ifdef CONFIG_ION_EXYNOS +#include +extern struct ion_device *ion_exynos; +struct ion_client *ion_client_ump = NULL; +#endif + +/* Module parameter to control log level */ +int ump_debug_level = 2; +module_param(ump_debug_level, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); /* rw-rw-r-- */ +MODULE_PARM_DESC(ump_debug_level, "Higher number, more dmesg output"); + +/* By default the module uses any available major, but it's possible to set it at load time to a specific number */ +int ump_major = 243; +module_param(ump_major, int, S_IRUGO); /* r--r--r-- */ +MODULE_PARM_DESC(ump_major, "Device major number"); + +/* Name of the UMP device driver */ +static char ump_dev_name[] = "ump"; /* should be const, but the functions we call requires non-cost */ + + +#if UMP_LICENSE_IS_GPL +static struct dentry *ump_debugfs_dir = NULL; +#endif + +/* + * The data which we attached to each virtual memory mapping request we get. + * Each memory mapping has a reference to the UMP memory it maps. + * We release this reference when the last memory mapping is unmapped. + */ +typedef struct ump_vma_usage_tracker +{ + int references; + ump_dd_handle handle; +} ump_vma_usage_tracker; + +struct ump_device +{ + struct cdev cdev; +#if UMP_LICENSE_IS_GPL + struct class * ump_class; +#endif +}; + +/* The global variable containing the global device data */ +static struct ump_device ump_device; + + +/* Forward declare static functions */ +static int ump_file_open(struct inode *inode, struct file *filp); +static int ump_file_release(struct inode *inode, struct file *filp); +#ifdef HAVE_UNLOCKED_IOCTL +static long ump_file_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +#else +static int ump_file_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); +#endif +static int ump_file_mmap(struct file * filp, struct vm_area_struct * vma); + +#if defined(CONFIG_VIDEO_UMP) +extern int map_errcode( _mali_osk_errcode_t err ); +#endif + +/* This variable defines the file operations this UMP device driver offer */ +static struct file_operations ump_fops = +{ + .owner = THIS_MODULE, + .open = ump_file_open, + .release = ump_file_release, +#ifdef HAVE_UNLOCKED_IOCTL + .unlocked_ioctl = ump_file_ioctl, +#else + .ioctl = ump_file_ioctl, +#endif + .mmap = ump_file_mmap +}; + + +/* This function is called by Linux to initialize this module. + * All we do is initialize the UMP device driver. + */ +static int ump_initialize_module(void) +{ + _mali_osk_errcode_t err; + + DBG_MSG(2, ("Inserting UMP device driver. Compiled: %s, time: %s\n", __DATE__, __TIME__)); + + err = ump_kernel_constructor(); + if (_MALI_OSK_ERR_OK != err) + { + MSG_ERR(("UMP device driver init failed\n")); + return map_errcode(err); + } + + MSG(("UMP device driver %s loaded\n", SVN_REV_STRING)); + return 0; +} + + + +/* + * This function is called by Linux to unload/terminate/exit/cleanup this module. + * All we do is terminate the UMP device driver. + */ +static void ump_cleanup_module(void) +{ +#ifdef CONFIG_ION_EXYNOS + if (ion_client_ump) + ion_client_destroy(ion_client_ump); +#endif + + DBG_MSG(2, ("Unloading UMP device driver\n")); + ump_kernel_destructor(); + DBG_MSG(2, ("Module unloaded\n")); +} + + + +static ssize_t ump_memory_used_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char buf[64]; + size_t r; + u32 mem = _ump_ukk_report_memory_usage(); + + r = snprintf(buf, 64, "%u\n", mem); + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); +} + +static const struct file_operations ump_memory_usage_fops = { + .owner = THIS_MODULE, + .read = ump_memory_used_read, +}; + +/* + * Initialize the UMP device driver. + */ +int ump_kernel_device_initialize(void) +{ + int err; + dev_t dev = 0; +#if UMP_LICENSE_IS_GPL + ump_debugfs_dir = debugfs_create_dir(ump_dev_name, NULL); + if (ERR_PTR(-ENODEV) == ump_debugfs_dir) + { + ump_debugfs_dir = NULL; + } + else + { + debugfs_create_file("memory_usage", 0400, ump_debugfs_dir, NULL, &ump_memory_usage_fops); + } +#endif + + if (0 == ump_major) + { + /* auto select a major */ + err = alloc_chrdev_region(&dev, 0, 1, ump_dev_name); + ump_major = MAJOR(dev); + } + else + { + /* use load time defined major number */ + dev = MKDEV(ump_major, 0); + err = register_chrdev_region(dev, 1, ump_dev_name); + } + + if (0 == err) + { + memset(&ump_device, 0, sizeof(ump_device)); + + /* initialize our char dev data */ + cdev_init(&ump_device.cdev, &ump_fops); + ump_device.cdev.owner = THIS_MODULE; + ump_device.cdev.ops = &ump_fops; + + /* register char dev with the kernel */ + err = cdev_add(&ump_device.cdev, dev, 1/*count*/); + if (0 == err) + { + +#if UMP_LICENSE_IS_GPL + ump_device.ump_class = class_create(THIS_MODULE, ump_dev_name); + if (IS_ERR(ump_device.ump_class)) + { + err = PTR_ERR(ump_device.ump_class); + } + else + { + struct device * mdev; + mdev = device_create(ump_device.ump_class, NULL, dev, NULL, ump_dev_name); + if (!IS_ERR(mdev)) + { + return 0; + } + + err = PTR_ERR(mdev); + } + cdev_del(&ump_device.cdev); +#else + return 0; +#endif + } + + unregister_chrdev_region(dev, 1); + } + + return err; +} + + + +/* + * Terminate the UMP device driver + */ +void ump_kernel_device_terminate(void) +{ + dev_t dev = MKDEV(ump_major, 0); + +#if UMP_LICENSE_IS_GPL + device_destroy(ump_device.ump_class, dev); + class_destroy(ump_device.ump_class); +#endif + + /* unregister char device */ + cdev_del(&ump_device.cdev); + + /* free major */ + unregister_chrdev_region(dev, 1); + +#if UMP_LICENSE_IS_GPL + if(ump_debugfs_dir) + debugfs_remove_recursive(ump_debugfs_dir); +#endif +} + +/* + * Open a new session. User space has called open() on us. + */ +static int ump_file_open(struct inode *inode, struct file *filp) +{ + struct ump_session_data * session_data; + _mali_osk_errcode_t err; + + /* input validation */ + if (0 != MINOR(inode->i_rdev)) + { + MSG_ERR(("Minor not zero in ump_file_open()\n")); + return -ENODEV; + } + + /* Call the OS-Independent UMP Open function */ + err = _ump_ukk_open((void**) &session_data ); + if( _MALI_OSK_ERR_OK != err ) + { + MSG_ERR(("Ump failed to open a new session\n")); + return map_errcode( err ); + } + + filp->private_data = (void*)session_data; + filp->f_pos = 0; + + return 0; /* success */ +} + + + +/* + * Close a session. User space has called close() or crashed/terminated. + */ +static int ump_file_release(struct inode *inode, struct file *filp) +{ + _mali_osk_errcode_t err; + + err = _ump_ukk_close((void**) &filp->private_data ); + if( _MALI_OSK_ERR_OK != err ) + { + return map_errcode( err ); + } + + return 0; /* success */ +} + + + +/* + * Handle IOCTL requests. + */ +#ifdef HAVE_UNLOCKED_IOCTL +static long ump_file_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +#else +static int ump_file_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) +#endif +{ + int err = -ENOTTY; + void __user * argument; + struct ump_session_data * session_data; + +#ifndef HAVE_UNLOCKED_IOCTL + (void)inode; /* inode not used */ +#endif + + session_data = (struct ump_session_data *)filp->private_data; + if (NULL == session_data) + { + MSG_ERR(("No session data attached to file object\n")); + return -ENOTTY; + } + + /* interpret the argument as a user pointer to something */ + argument = (void __user *)arg; + + switch (cmd) + { + case UMP_IOC_QUERY_API_VERSION: + err = ump_get_api_version_wrapper((u32 __user *)argument, session_data); + break; + + case UMP_IOC_ALLOCATE : + err = ump_allocate_wrapper((u32 __user *)argument, session_data); + break; +#ifdef CONFIG_ION_EXYNOS + case UMP_IOC_ION_IMPORT: + err = ump_ion_import_wrapper((u32 __user *)argument, session_data); + break; +#endif +#ifdef CONFIG_DMA_SHARED_BUFFER + case UMP_IOC_DMABUF_IMPORT: + err = ump_dmabuf_import_wrapper((u32 __user *)argument, + session_data); + break; +#endif + case UMP_IOC_RELEASE: + err = ump_release_wrapper((u32 __user *)argument, session_data); + break; + + case UMP_IOC_SIZE_GET: + err = ump_size_get_wrapper((u32 __user *)argument, session_data); + break; + + case UMP_IOC_MSYNC: + err = ump_msync_wrapper((u32 __user *)argument, session_data); + break; + + case UMP_IOC_CACHE_OPERATIONS_CONTROL: + err = ump_cache_operations_control_wrapper((u32 __user *)argument, session_data); + break; + + case UMP_IOC_SWITCH_HW_USAGE: + err = ump_switch_hw_usage_wrapper((u32 __user *)argument, session_data); + break; + + case UMP_IOC_LOCK: + err = ump_lock_wrapper((u32 __user *)argument, session_data); + break; + + case UMP_IOC_UNLOCK: + err = ump_unlock_wrapper((u32 __user *)argument, session_data); + break; + + default: + DBG_MSG(1, ("No handler for IOCTL. cmd: 0x%08x, arg: 0x%08lx\n", cmd, arg)); + err = -EFAULT; + break; + } + + return err; +} + +#ifndef CONFIG_VIDEO_UMP +int map_errcode( _mali_osk_errcode_t err ) +{ + switch(err) + { + case _MALI_OSK_ERR_OK : return 0; + case _MALI_OSK_ERR_FAULT: return -EFAULT; + case _MALI_OSK_ERR_INVALID_FUNC: return -ENOTTY; + case _MALI_OSK_ERR_INVALID_ARGS: return -EINVAL; + case _MALI_OSK_ERR_NOMEM: return -ENOMEM; + case _MALI_OSK_ERR_TIMEOUT: return -ETIMEDOUT; + case _MALI_OSK_ERR_RESTARTSYSCALL: return -ERESTARTSYS; + case _MALI_OSK_ERR_ITEM_NOT_FOUND: return -ENOENT; + default: return -EFAULT; + } +} +#endif + +/* + * Handle from OS to map specified virtual memory to specified UMP memory. + */ +static int ump_file_mmap(struct file * filp, struct vm_area_struct * vma) +{ + _ump_uk_map_mem_s args; + _mali_osk_errcode_t err; + struct ump_session_data * session_data; + + /* Validate the session data */ + session_data = (struct ump_session_data *)filp->private_data; + if (NULL == session_data || NULL == session_data->cookies_map->table->mappings) + { + MSG_ERR(("mmap() called without any session data available\n")); + return -EFAULT; + } + + /* Re-pack the arguments that mmap() packed for us */ + args.ctx = session_data; + args.phys_addr = 0; + args.size = vma->vm_end - vma->vm_start; + args._ukk_private = vma; + args.secure_id = vma->vm_pgoff; + args.is_cached = 0; + + if (!(vma->vm_flags & VM_SHARED)) + { + args.is_cached = 1; + vma->vm_flags = vma->vm_flags | VM_SHARED | VM_MAYSHARE ; + DBG_MSG(3, ("UMP Map function: Forcing the CPU to use cache\n")); + } + /* By setting this flag, during a process fork; the child process will not have the parent UMP mappings */ + vma->vm_flags |= VM_DONTCOPY; + + DBG_MSG(4, ("UMP vma->flags: %x\n", vma->vm_flags )); + + /* Call the common mmap handler */ + err = _ump_ukk_map_mem( &args ); + if ( _MALI_OSK_ERR_OK != err) + { + MSG_ERR(("_ump_ukk_map_mem() failed in function ump_file_mmap()")); + return map_errcode( err ); + } + + return 0; /* success */ +} + +/* Export UMP kernel space API functions */ +EXPORT_SYMBOL(ump_dd_secure_id_get); +EXPORT_SYMBOL(ump_dd_handle_create_from_secure_id); +EXPORT_SYMBOL(ump_dd_phys_block_count_get); +EXPORT_SYMBOL(ump_dd_phys_block_get); +EXPORT_SYMBOL(ump_dd_phys_blocks_get); +EXPORT_SYMBOL(ump_dd_size_get); +EXPORT_SYMBOL(ump_dd_reference_add); +EXPORT_SYMBOL(ump_dd_reference_release); +EXPORT_SYMBOL(ump_dd_meminfo_get); +EXPORT_SYMBOL(ump_dd_meminfo_set); +EXPORT_SYMBOL(ump_dd_handle_get_from_vaddr); + +/* Export our own extended kernel space allocator */ +EXPORT_SYMBOL(ump_dd_handle_create_from_phys_blocks); + +/* Setup init and exit functions for this module */ +//module_init(ump_initialize_module); +arch_initcall(ump_initialize_module); +module_exit(ump_cleanup_module); + +/* And some module informatio */ +MODULE_LICENSE(UMP_KERNEL_LINUX_LICENSE); +MODULE_AUTHOR("ARM Ltd."); +MODULE_VERSION(SVN_REV_STRING); diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_linux.h b/drivers/media/video/samsung/ump/linux/ump_kernel_linux.h new file mode 100644 index 0000000..4985bb7 --- /dev/null +++ b/drivers/media/video/samsung/ump/linux/ump_kernel_linux.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __UMP_KERNEL_LINUX_H__ +#define __UMP_KERNEL_LINUX_H__ + +int ump_kernel_device_initialize(void); +void ump_kernel_device_terminate(void); + + +#endif /* __UMP_KERNEL_H__ */ diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c new file mode 100644 index 0000000..82c16cc --- /dev/null +++ b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c @@ -0,0 +1,287 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* needed to detect kernel version specific code */ +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) +#include +#else /* pre 2.6.26 the file was in the arch specific location */ +#include +#endif + +#include +#include +#include +#include +#include "ump_kernel_common.h" +#include "ump_kernel_memory_backend.h" + + + +#define UMP_BLOCK_SIZE (256UL * 1024UL) /* 256kB, remember to keep the ()s */ + + + +typedef struct block_info +{ + struct block_info * next; +} block_info; + + + +typedef struct block_allocator +{ + struct semaphore mutex; + block_info * all_blocks; + block_info * first_free; + u32 base; + u32 num_blocks; + u32 num_free; +} block_allocator; + + +static void block_allocator_shutdown(ump_memory_backend * backend); +static int block_allocator_allocate(void* ctx, ump_dd_mem * mem); +static void block_allocator_release(void * ctx, ump_dd_mem * handle); +static inline u32 get_phys(block_allocator * allocator, block_info * block); +static u32 block_allocator_stat(struct ump_memory_backend *backend); + + + +/* + * Create dedicated memory backend + */ +ump_memory_backend * ump_block_allocator_create(u32 base_address, u32 size) +{ + ump_memory_backend * backend; + block_allocator * allocator; + u32 usable_size; + u32 num_blocks; + + usable_size = (size + UMP_BLOCK_SIZE - 1) & ~(UMP_BLOCK_SIZE - 1); + num_blocks = usable_size / UMP_BLOCK_SIZE; + + if (0 == usable_size) + { + DBG_MSG(1, ("Memory block of size %u is unusable\n", size)); + return NULL; + } + + DBG_MSG(5, ("Creating dedicated UMP memory backend. Base address: 0x%08x, size: 0x%08x\n", base_address, size)); + DBG_MSG(6, ("%u usable bytes which becomes %u blocks\n", usable_size, num_blocks)); + + backend = kzalloc(sizeof(ump_memory_backend), GFP_KERNEL); + if (NULL != backend) + { + allocator = kmalloc(sizeof(block_allocator), GFP_KERNEL); + if (NULL != allocator) + { + allocator->all_blocks = kmalloc(sizeof(block_allocator) * num_blocks, GFP_KERNEL); + if (NULL != allocator->all_blocks) + { + int i; + + allocator->first_free = NULL; + allocator->num_blocks = num_blocks; + allocator->num_free = num_blocks; + allocator->base = base_address; + sema_init(&allocator->mutex, 1); + + for (i = 0; i < num_blocks; i++) + { + allocator->all_blocks[i].next = allocator->first_free; + allocator->first_free = &allocator->all_blocks[i]; + } + + backend->ctx = allocator; + backend->allocate = block_allocator_allocate; + backend->release = block_allocator_release; + backend->shutdown = block_allocator_shutdown; + backend->stat = block_allocator_stat; + backend->pre_allocate_physical_check = NULL; + backend->adjust_to_mali_phys = NULL; + backend->get = NULL; + backend->set = NULL; + + return backend; + } + kfree(allocator); + } + kfree(backend); + } + + return NULL; +} + + + +/* + * Destroy specified dedicated memory backend + */ +static void block_allocator_shutdown(ump_memory_backend * backend) +{ + block_allocator * allocator; + + BUG_ON(!backend); + BUG_ON(!backend->ctx); + + allocator = (block_allocator*)backend->ctx; + + DBG_MSG_IF(1, allocator->num_free != allocator->num_blocks, ("%u blocks still in use during shutdown\n", allocator->num_blocks - allocator->num_free)); + + kfree(allocator->all_blocks); + kfree(allocator); + kfree(backend); +} + + + +static int block_allocator_allocate(void* ctx, ump_dd_mem * mem) +{ + block_allocator * allocator; + u32 left; + block_info * last_allocated = NULL; + int i = 0; + + BUG_ON(!ctx); + BUG_ON(!mem); + + allocator = (block_allocator*)ctx; + left = mem->size_bytes; + + BUG_ON(!left); + BUG_ON(!&allocator->mutex); + + mem->nr_blocks = ((left + UMP_BLOCK_SIZE - 1) & ~(UMP_BLOCK_SIZE - 1)) / UMP_BLOCK_SIZE; + mem->block_array = (ump_dd_physical_block*)vmalloc(sizeof(ump_dd_physical_block) * mem->nr_blocks); + if (NULL == mem->block_array) + { + MSG_ERR(("Failed to allocate block array\n")); + return 0; + } + + if (down_interruptible(&allocator->mutex)) + { + MSG_ERR(("Could not get mutex to do block_allocate\n")); + return 0; + } + + mem->size_bytes = 0; + + while ((left > 0) && (allocator->first_free)) + { + block_info * block; + + block = allocator->first_free; + allocator->first_free = allocator->first_free->next; + block->next = last_allocated; + last_allocated = block; + allocator->num_free--; + + mem->block_array[i].addr = get_phys(allocator, block); + mem->block_array[i].size = UMP_BLOCK_SIZE; + mem->size_bytes += UMP_BLOCK_SIZE; + + i++; + + if (left < UMP_BLOCK_SIZE) left = 0; + else left -= UMP_BLOCK_SIZE; + } + + if (left) + { + block_info * block; + /* release all memory back to the pool */ + while (last_allocated) + { + block = last_allocated->next; + last_allocated->next = allocator->first_free; + allocator->first_free = last_allocated; + last_allocated = block; + allocator->num_free++; + } + + vfree(mem->block_array); + mem->backend_info = NULL; + mem->block_array = NULL; + + DBG_MSG(4, ("Could not find a mem-block for the allocation.\n")); + up(&allocator->mutex); + + return 0; + } + + mem->backend_info = last_allocated; + + up(&allocator->mutex); + mem->is_cached=0; + + return 1; +} + + + +static void block_allocator_release(void * ctx, ump_dd_mem * handle) +{ + block_allocator * allocator; + block_info * block, * next; + + BUG_ON(!ctx); + BUG_ON(!handle); + + allocator = (block_allocator*)ctx; + block = (block_info*)handle->backend_info; + BUG_ON(!block); + + if (down_interruptible(&allocator->mutex)) + { + MSG_ERR(("Allocator release: Failed to get mutex - memory leak\n")); + return; + } + + while (block) + { + next = block->next; + + BUG_ON( (block < allocator->all_blocks) || (block > (allocator->all_blocks + allocator->num_blocks))); + + block->next = allocator->first_free; + allocator->first_free = block; + allocator->num_free++; + + block = next; + } + DBG_MSG(3, ("%d blocks free after release call\n", allocator->num_free)); + up(&allocator->mutex); + + vfree(handle->block_array); + handle->block_array = NULL; +} + + + +/* + * Helper function for calculating the physical base adderss of a memory block + */ +static inline u32 get_phys(block_allocator * allocator, block_info * block) +{ + return allocator->base + ((block - allocator->all_blocks) * UMP_BLOCK_SIZE); +} + +static u32 block_allocator_stat(struct ump_memory_backend *backend) +{ + block_allocator *allocator; + BUG_ON(!backend); + allocator = (block_allocator*)backend->ctx; + BUG_ON(!allocator); + + return (allocator->num_blocks - allocator->num_free)* UMP_BLOCK_SIZE; +} diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.h b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.h new file mode 100644 index 0000000..ca8faae --- /dev/null +++ b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file ump_kernel_memory_backend_dedicated.h + */ + +#ifndef __UMP_KERNEL_MEMORY_BACKEND_DEDICATED_H__ +#define __UMP_KERNEL_MEMORY_BACKEND_DEDICATED_H__ + +#include "ump_kernel_memory_backend.h" + +ump_memory_backend * ump_block_allocator_create(u32 base_address, u32 size); + +#endif /* __UMP_KERNEL_MEMORY_BACKEND_DEDICATED_H__ */ + diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c new file mode 100644 index 0000000..8f6a9b3 --- /dev/null +++ b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* needed to detect kernel version specific code */ +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) +#include +#else /* pre 2.6.26 the file was in the arch specific location */ +#include +#endif + +#include +#include +#include +#include +#include +#include +#include "ump_kernel_common.h" +#include "ump_kernel_memory_backend.h" + + + +typedef struct os_allocator +{ + struct semaphore mutex; + u32 num_pages_max; /**< Maximum number of pages to allocate from the OS */ + u32 num_pages_allocated; /**< Number of pages allocated from the OS */ +} os_allocator; + + + +static void os_free(void* ctx, ump_dd_mem * descriptor); +static int os_allocate(void* ctx, ump_dd_mem * descriptor); +static void os_memory_backend_destroy(ump_memory_backend * backend); +static u32 os_stat(struct ump_memory_backend *backend); + + + +/* + * Create OS memory backend + */ +ump_memory_backend * ump_os_memory_backend_create(const int max_allocation) +{ + ump_memory_backend * backend; + os_allocator * info; + + info = kmalloc(sizeof(os_allocator), GFP_KERNEL); + if (NULL == info) + { + return NULL; + } + + info->num_pages_max = max_allocation >> PAGE_SHIFT; + info->num_pages_allocated = 0; + + sema_init(&info->mutex, 1); + + backend = kmalloc(sizeof(ump_memory_backend), GFP_KERNEL); + if (NULL == backend) + { + kfree(info); + return NULL; + } + + backend->ctx = info; + backend->allocate = os_allocate; + backend->release = os_free; + backend->shutdown = os_memory_backend_destroy; + backend->stat = os_stat; + backend->pre_allocate_physical_check = NULL; + backend->adjust_to_mali_phys = NULL; + backend->get = NULL; + backend->set = NULL; + + return backend; +} + + + +/* + * Destroy specified OS memory backend + */ +static void os_memory_backend_destroy(ump_memory_backend * backend) +{ + os_allocator * info = (os_allocator*)backend->ctx; + + DBG_MSG_IF(1, 0 != info->num_pages_allocated, ("%d pages still in use during shutdown\n", info->num_pages_allocated)); + + kfree(info); + kfree(backend); +} + + + +/* + * Allocate UMP memory + */ +static int os_allocate(void* ctx, ump_dd_mem * descriptor) +{ + u32 left; + os_allocator * info; + int pages_allocated = 0; + int is_cached; + + BUG_ON(!descriptor); + BUG_ON(!ctx); + + info = (os_allocator*)ctx; + left = descriptor->size_bytes; + is_cached = descriptor->is_cached; + + if (down_interruptible(&info->mutex)) + { + DBG_MSG(1, ("Failed to get mutex in os_free\n")); + return 0; /* failure */ + } + + descriptor->backend_info = NULL; + descriptor->nr_blocks = ((left + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) >> PAGE_SHIFT; + + DBG_MSG(5, ("Allocating page array. Size: %lu\n", descriptor->nr_blocks * sizeof(ump_dd_physical_block))); + + descriptor->block_array = (ump_dd_physical_block *)vmalloc(sizeof(ump_dd_physical_block) * descriptor->nr_blocks); + if (NULL == descriptor->block_array) + { + up(&info->mutex); + DBG_MSG(1, ("Block array could not be allocated\n")); + return 0; /* failure */ + } + + while (left > 0) + { + struct page * new_page; + + if (is_cached) + { + new_page = alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_NORETRY | __GFP_NOWARN ); + } else + { + new_page = alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_NORETRY | __GFP_NOWARN | __GFP_COLD); + } + if (NULL == new_page) + { + MSG_ERR(("UMP memory allocated: Out of Memory !!\n")); + break; + } + + /* Ensure page caches are flushed. */ + if ( is_cached ) + { + descriptor->block_array[pages_allocated].addr = page_to_phys(new_page); + descriptor->block_array[pages_allocated].size = PAGE_SIZE; + } else + { + descriptor->block_array[pages_allocated].addr = dma_map_page(NULL, new_page, 0, PAGE_SIZE, DMA_BIDIRECTIONAL ); + descriptor->block_array[pages_allocated].size = PAGE_SIZE; + } + + DBG_MSG(5, ("Allocated page 0x%08lx cached: %d\n", descriptor->block_array[pages_allocated].addr, is_cached)); + + if (left < PAGE_SIZE) + { + left = 0; + } + else + { + left -= PAGE_SIZE; + } + + pages_allocated++; + } + + DBG_MSG(5, ("Alloce for ID:%2d got %d pages, cached: %d\n", descriptor->secure_id, pages_allocated)); + + if (left) + { + DBG_MSG(1, ("Failed to allocate needed pages\n")); + DBG_MSG(1, ("UMP memory allocated: %d kB Configured maximum OS memory usage: %d kB\n", + (pages_allocated * _MALI_OSK_CPU_PAGE_SIZE)/1024, (info->num_pages_max* _MALI_OSK_CPU_PAGE_SIZE)/1024)); + + while(pages_allocated) + { + pages_allocated--; + if ( !is_cached ) + { + dma_unmap_page(NULL, descriptor->block_array[pages_allocated].addr, PAGE_SIZE, DMA_BIDIRECTIONAL); + } + __free_page(pfn_to_page(descriptor->block_array[pages_allocated].addr >> PAGE_SHIFT) ); + } + + up(&info->mutex); + + return 0; /* failure */ + } + + info->num_pages_allocated += pages_allocated; + + DBG_MSG(6, ("%d out of %d pages now allocated\n", info->num_pages_allocated, info->num_pages_max)); + + up(&info->mutex); + + return 1; /* success*/ +} + + +/* + * Free specified UMP memory + */ +static void os_free(void* ctx, ump_dd_mem * descriptor) +{ + os_allocator * info; + int i; + + BUG_ON(!ctx); + BUG_ON(!descriptor); + + info = (os_allocator*)ctx; + + BUG_ON(descriptor->nr_blocks > info->num_pages_allocated); + + if (down_interruptible(&info->mutex)) + { + DBG_MSG(1, ("Failed to get mutex in os_free\n")); + return; + } + + DBG_MSG(5, ("Releasing %lu OS pages\n", descriptor->nr_blocks)); + + info->num_pages_allocated -= descriptor->nr_blocks; + + up(&info->mutex); + + for ( i = 0; i < descriptor->nr_blocks; i++) + { + DBG_MSG(6, ("Freeing physical page. Address: 0x%08lx\n", descriptor->block_array[i].addr)); + if ( ! descriptor->is_cached) + { + dma_unmap_page(NULL, descriptor->block_array[i].addr, PAGE_SIZE, DMA_BIDIRECTIONAL); + } + __free_page(pfn_to_page(descriptor->block_array[i].addr>>PAGE_SHIFT) ); + } + + vfree(descriptor->block_array); +} + + +static u32 os_stat(struct ump_memory_backend *backend) +{ + os_allocator *info; + info = (os_allocator*)backend->ctx; + return info->num_pages_allocated * _MALI_OSK_MALI_PAGE_SIZE; +} diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.h b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.h new file mode 100644 index 0000000..6f7e610 --- /dev/null +++ b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file ump_kernel_memory_backend_os.h + */ + +#ifndef __UMP_KERNEL_MEMORY_BACKEND_OS_H__ +#define __UMP_KERNEL_MEMORY_BACKEND_OS_H__ + +#include "ump_kernel_memory_backend.h" + +ump_memory_backend * ump_os_memory_backend_create(const int max_allocation); + +#endif /* __UMP_KERNEL_MEMORY_BACKEND_OS_H__ */ + diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.c b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.c new file mode 100644 index 0000000..46797ea --- /dev/null +++ b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.c @@ -0,0 +1,290 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* create by boojin.kim@samsung.com */ +/* needed to detect kernel version specific code */ +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) +#include +#else /* pre 2.6.26 the file was in the arch specific location */ +#include +#endif + +#include +#include +#include +#include +#include +#include "ump_kernel_common.h" +#include "ump_kernel_memory_backend.h" +#include "ump_kernel_interface_ref_drv.h" +#include "ump_kernel_memory_backend_vcm.h" +#include "../common/ump_uk_types.h" +#include +#include +#include + +#define UMP_REF_DRV_UK_VCM_DEV_G2D 12 + +typedef struct ump_vcm { + struct vcm *vcm; + struct vcm_res *vcm_res; + unsigned int dev_id; +} ump_vcm; + +typedef struct vcm_allocator { + struct semaphore mutex; + u32 num_vcm_blocks; +} vcm_allocator; + +static void ump_vcm_free(void* ctx, ump_dd_mem * descriptor); +static int ump_vcm_allocate(void* ctx, ump_dd_mem * descriptor); +static void *vcm_res_get(ump_dd_mem *mem, void* args); +static void vcm_attr_set(ump_dd_mem *mem, void* args); +static int vcm_mem_allocator(vcm_allocator *info, ump_dd_mem *descriptor); +static void vcm_memory_backend_destroy(ump_memory_backend * backend); + + +/* + * Create VCM memory backend + */ +ump_memory_backend * ump_vcm_memory_backend_create(const int max_allocation) +{ + ump_memory_backend * backend; + vcm_allocator * info; + + info = kmalloc(sizeof(vcm_allocator), GFP_KERNEL); + if (NULL == info) + { + return NULL; + } + + info->num_vcm_blocks = 0; + + + sema_init(&info->mutex, 1); + + backend = kmalloc(sizeof(ump_memory_backend), GFP_KERNEL); + if (NULL == backend) + { + kfree(info); + return NULL; + } + + backend->ctx = info; + backend->allocate = ump_vcm_allocate; + backend->release = ump_vcm_free; + backend->shutdown = vcm_memory_backend_destroy; + backend->pre_allocate_physical_check = NULL; + backend->adjust_to_mali_phys = NULL; + + backend->get = vcm_res_get; + backend->set = vcm_attr_set; + + + return backend; +} + +/* + * Destroy specified VCM memory backend + */ +static void vcm_memory_backend_destroy(ump_memory_backend * backend) +{ + vcm_allocator * info = (vcm_allocator*)backend->ctx; +#if 0 + DBG_MSG_IF(1, 0 != info->num_pages_allocated, ("%d pages still in use during shutdown\n", info->num_pages_allocated)); +#endif + kfree(info); + kfree(backend); +} + +/* + * Allocate UMP memory + */ +static int ump_vcm_allocate(void *ctx, ump_dd_mem * descriptor) +{ + int ret; /* success */ + vcm_allocator *info; + struct ump_vcm *ump_vcm; + + BUG_ON(!descriptor); + BUG_ON(!ctx); + + info = (vcm_allocator*)ctx; + + ump_vcm = kmalloc(sizeof(struct ump_vcm), GFP_KERNEL); + if (NULL == ump_vcm) + { + return 0; + } + + ump_vcm->dev_id = (int)descriptor->backend_info & ~UMP_REF_DRV_UK_CONSTRAINT_USE_CACHE; + + if(ump_vcm->dev_id == UMP_REF_DRV_UK_CONSTRAINT_NONE) { /* None */ + ump_vcm->dev_id = UMP_REF_DRV_UK_VCM_DEV_G2D; /* this ID is G2D */ + } + else if(ump_vcm->dev_id == UMP_REF_DRV_UK_CONSTRAINT_PHYSICALLY_LINEAR) { /* Physical Linear */ + return 0; + } + else { /* Other VCM */ + ump_vcm->dev_id -= 2; + } + + DBG_MSG(5, ("Device ID for VCM : %d\n", ump_vcm->dev_id)); + ump_vcm->vcm = vcm_find_vcm(ump_vcm->dev_id); + + if (!ump_vcm->vcm) + { + return 0; + } + descriptor->backend_info = (void*)ump_vcm; + + if (down_interruptible(&info->mutex)) { + DBG_MSG(1, ("Failed to get mutex in ump_vcm_allocate\n")); + return 0; /* failure */ + } + + ret = vcm_mem_allocator(info, descriptor); + up(&info->mutex); + + return ret; /* success */ +} + +static int vcm_mem_allocator(vcm_allocator *info, ump_dd_mem *descriptor) +{ + unsigned long num_blocks; + int i; + struct vcm_phys *phys; + struct vcm_phys_part *part; + int size_total = 0; + struct ump_vcm *ump_vcm; + + ump_vcm = (struct ump_vcm*)descriptor->backend_info; + + ump_vcm->vcm_res = + vcm_make_binding(ump_vcm->vcm, descriptor->size_bytes, + ump_vcm->dev_id, 0); + + phys = ump_vcm->vcm_res->phys; + part = phys->parts; + num_blocks = phys->count; + + DBG_MSG(5, + ("Allocating page array. Size: %lu, VCM Reservation : 0x%x\n", + phys->count * sizeof(ump_dd_physical_block), + ump_vcm->vcm_res->start)); + + /* Now, make a copy of the block information supplied by the user */ + descriptor->block_array = + (ump_dd_physical_block *) vmalloc(sizeof(ump_dd_physical_block) * + num_blocks); + + if (NULL == descriptor->block_array) { + vfree(descriptor->block_array); + DBG_MSG(1, ("Could not allocate a mem handle for function.\n")); + return 0; /* failure */ + } + + for (i = 0; i < num_blocks; i++) { + descriptor->block_array[i].addr = part->start; + descriptor->block_array[i].size = part->size; + + dmac_unmap_area(phys_to_virt(part->start), part->size, DMA_FROM_DEVICE); + outer_inv_range(part->start, part->start + part->size); + + ++part; + size_total += descriptor->block_array[i].size; + DBG_MSG(6, + ("UMP memory created with VCM. addr 0x%x, size: 0x%x\n", + descriptor->block_array[i].addr, + descriptor->block_array[i].size)); + } + + descriptor->size_bytes = size_total; + descriptor->nr_blocks = num_blocks; + descriptor->ctx = NULL; + + info->num_vcm_blocks += num_blocks; + return 1; +} + +/* + * Free specified UMP memory + */ +static void ump_vcm_free(void *ctx, ump_dd_mem * descriptor) +{ + struct ump_vcm *ump_vcm; + vcm_allocator *info; + + BUG_ON(!descriptor); + BUG_ON(!ctx); + + ump_vcm = (struct ump_vcm*)descriptor->backend_info; + info = (vcm_allocator*)ctx; + + BUG_ON(descriptor->nr_blocks > info->num_vcm_blocks); + + if (down_interruptible(&info->mutex)) { + DBG_MSG(1, ("Failed to get mutex in ump_vcm_free\n")); + return; + } + + DBG_MSG(5, ("Releasing %lu VCM pages\n", descriptor->nr_blocks)); + + info->num_vcm_blocks -= descriptor->nr_blocks; + + up(&info->mutex); + + DBG_MSG(6, ("Freeing physical page by VCM\n")); + vcm_destroy_binding(ump_vcm->vcm_res); + ump_vcm->vcm = NULL; + ump_vcm->vcm_res = NULL; + + kfree(ump_vcm); + vfree(descriptor->block_array); +} + +static void *vcm_res_get(ump_dd_mem *mem, void *args) +{ + struct ump_vcm *ump_vcm; + enum vcm_dev_id vcm_id; + + ump_vcm = (struct ump_vcm*)mem->backend_info; + vcm_id = (enum vcm_dev_id)args; + + if (vcm_reservation_in_vcm + (vcm_find_vcm(vcm_id), ump_vcm->vcm_res) + == S5PVCM_RES_NOT_IN_VCM) + return NULL; + else + return ump_vcm->vcm_res; +} + +static void vcm_attr_set(ump_dd_mem *mem, void *args) +{ + struct ump_vcm *ump_vcm, *ump_vcmh; + + ump_vcm = (struct ump_vcm*)args; + + ump_vcmh = kmalloc(sizeof(struct ump_vcm), GFP_KERNEL); + if (NULL == ump_vcmh) + { + return; + } + + ump_vcmh->dev_id = ump_vcm->dev_id; + ump_vcmh->vcm = ump_vcm->vcm; + ump_vcmh->vcm_res = ump_vcm->vcm_res; + + mem->backend_info= (void*)ump_vcmh; + + return; +} diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.h b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.h new file mode 100644 index 0000000..c1ead0d --- /dev/null +++ b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file ump_kernel_memory_backend_vcm.h + */ + +#ifndef __UMP_KERNEL_MEMORY_BACKEND_VCM_H__ +#define __UMP_KERNEL_MEMORY_BACKEND_VCM_H__ + +#include "ump_kernel_memory_backend.h" + +ump_memory_backend * ump_vcm_memory_backend_create(const int max_allocation); + +#endif /* __UMP_KERNEL_MEMORY_BACKEND_VCM_H__ */ diff --git a/drivers/media/video/samsung/ump/linux/ump_memory_backend.c b/drivers/media/video/samsung/ump/linux/ump_memory_backend.c new file mode 100644 index 0000000..d067cfe --- /dev/null +++ b/drivers/media/video/samsung/ump/linux/ump_memory_backend.c @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include /* kernel module definitions */ +#include /* request_mem_region */ + +#include "arch/config.h" /* Configuration for current platform. The symlink for arch is set by Makefile */ + +#include "ump_osk.h" +#include "ump_kernel_common.h" +#include "ump_kernel_memory_backend_os.h" +#include "ump_kernel_memory_backend_dedicated.h" + +/* Configure which dynamic memory allocator to use */ +int ump_backend = ARCH_UMP_BACKEND_DEFAULT; +module_param(ump_backend, int, S_IRUGO); /* r--r--r-- */ +MODULE_PARM_DESC(ump_backend, "0 = dedicated memory backend (default), 1 = OS memory backend"); + +/* The base address of the memory block for the dedicated memory backend */ +unsigned int ump_memory_address = ARCH_UMP_MEMORY_ADDRESS_DEFAULT; +module_param(ump_memory_address, uint, S_IRUGO); /* r--r--r-- */ +MODULE_PARM_DESC(ump_memory_address, "The physical address to map for the dedicated memory backend"); + +/* The size of the memory block for the dedicated memory backend */ +unsigned int ump_memory_size = ARCH_UMP_MEMORY_SIZE_DEFAULT; +module_param(ump_memory_size, uint, S_IRUGO); /* r--r--r-- */ +MODULE_PARM_DESC(ump_memory_size, "The size of fixed memory to map in the dedicated memory backend"); + +ump_memory_backend* ump_memory_backend_create ( void ) +{ + ump_memory_backend * backend = NULL; + + /* Create the dynamic memory allocator backend */ + if (0 == ump_backend) + { + DBG_MSG(2, ("Using dedicated memory backend\n")); + + DBG_MSG(2, ("Requesting dedicated memory: 0x%08x, size: %u\n", ump_memory_address, ump_memory_size)); + /* Ask the OS if we can use the specified physical memory */ + if (NULL == request_mem_region(ump_memory_address, ump_memory_size, "UMP Memory")) + { + MSG_ERR(("Failed to request memory region (0x%08X - 0x%08X). Is Mali DD already loaded?\n", ump_memory_address, ump_memory_address + ump_memory_size - 1)); + return NULL; + } + backend = ump_block_allocator_create(ump_memory_address, ump_memory_size); + } + else if (1 == ump_backend) + { + DBG_MSG(2, ("Using OS memory backend, allocation limit: %d\n", ump_memory_size)); + backend = ump_os_memory_backend_create(ump_memory_size); + } +#ifdef CONFIG_UMP_VCM_ALLOC + else if (2 == ump_backend) + { + DBG_MSG(2, ("Using VCM memory backend, allocation limit: %d\n", ump_memory_size)); + backend = ump_vcm_memory_backend_create(ump_memory_size); + } +#endif + + return backend; +} + +void ump_memory_backend_destroy( void ) +{ + if (0 == ump_backend) + { + DBG_MSG(2, ("Releasing dedicated memory: 0x%08x\n", ump_memory_address)); + release_mem_region(ump_memory_address, ump_memory_size); + } +} diff --git a/drivers/media/video/samsung/ump/linux/ump_osk_atomics.c b/drivers/media/video/samsung/ump/linux/ump_osk_atomics.c new file mode 100644 index 0000000..b117d99 --- /dev/null +++ b/drivers/media/video/samsung/ump/linux/ump_osk_atomics.c @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file ump_osk_atomics.c + * Implementation of the OS abstraction layer for the UMP kernel device driver + */ + +#include "ump_osk.h" +#include + +int _ump_osk_atomic_dec_and_read( _mali_osk_atomic_t *atom ) +{ + return atomic_dec_return((atomic_t *)&atom->u.val); +} + +int _ump_osk_atomic_inc_and_read( _mali_osk_atomic_t *atom ) +{ + return atomic_inc_return((atomic_t *)&atom->u.val); +} diff --git a/drivers/media/video/samsung/ump/linux/ump_osk_low_level_mem.c b/drivers/media/video/samsung/ump/linux/ump_osk_low_level_mem.c new file mode 100644 index 0000000..8ae169a --- /dev/null +++ b/drivers/media/video/samsung/ump/linux/ump_osk_low_level_mem.c @@ -0,0 +1,485 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file ump_osk_memory.c + * Implementation of the OS abstraction layer for the kernel device driver + */ + +/* needed to detect kernel version specific code */ +#include + +#include "ump_osk.h" +#include "ump_uk_types.h" +#include "ump_ukk.h" +#include "ump_kernel_common.h" +#include /* kernel module definitions */ +#include +#include +#include +#include + +#include +#include /* to verify pointers from user space */ +#include +#include + +typedef struct ump_vma_usage_tracker +{ + atomic_t references; + ump_memory_allocation *descriptor; +} ump_vma_usage_tracker; + +static void ump_vma_open(struct vm_area_struct * vma); +static void ump_vma_close(struct vm_area_struct * vma); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) +static int ump_cpu_page_fault_handler(struct vm_area_struct *vma, struct vm_fault *vmf); +#else +static unsigned long ump_cpu_page_fault_handler(struct vm_area_struct * vma, unsigned long address); +#endif + +static struct vm_operations_struct ump_vm_ops = +{ + .open = ump_vma_open, + .close = ump_vma_close, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) + .fault = ump_cpu_page_fault_handler +#else + .nopfn = ump_cpu_page_fault_handler +#endif +}; + +/* + * Page fault for VMA region + * This should never happen since we always map in the entire virtual memory range. + */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) +static int ump_cpu_page_fault_handler(struct vm_area_struct *vma, struct vm_fault *vmf) +#else +static unsigned long ump_cpu_page_fault_handler(struct vm_area_struct * vma, unsigned long address) +#endif +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) + void __user * address; + address = vmf->virtual_address; +#endif + MSG_ERR(("Page-fault in UMP memory region caused by the CPU\n")); + MSG_ERR(("VMA: 0x%08lx, virtual address: 0x%08lx\n", (unsigned long)vma, address)); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) + return VM_FAULT_SIGBUS; +#else + return NOPFN_SIGBUS; +#endif +} + +static void ump_vma_open(struct vm_area_struct * vma) +{ + ump_vma_usage_tracker * vma_usage_tracker; + int new_val; + + vma_usage_tracker = (ump_vma_usage_tracker*)vma->vm_private_data; + BUG_ON(NULL == vma_usage_tracker); + + new_val = atomic_inc_return(&vma_usage_tracker->references); + + DBG_MSG(4, ("VMA open, VMA reference count incremented. VMA: 0x%08lx, reference count: %d\n", (unsigned long)vma, new_val)); +} + +static void ump_vma_close(struct vm_area_struct * vma) +{ + ump_vma_usage_tracker * vma_usage_tracker; + _ump_uk_unmap_mem_s args; + int new_val; + + vma_usage_tracker = (ump_vma_usage_tracker*)vma->vm_private_data; + BUG_ON(NULL == vma_usage_tracker); + + new_val = atomic_dec_return(&vma_usage_tracker->references); + + DBG_MSG(4, ("VMA close, VMA reference count decremented. VMA: 0x%08lx, reference count: %d\n", (unsigned long)vma, new_val)); + + if (0 == new_val) + { + ump_memory_allocation * descriptor; + + descriptor = vma_usage_tracker->descriptor; + + args.ctx = descriptor->ump_session; + args.cookie = descriptor->cookie; + args.mapping = descriptor->mapping; + args.size = descriptor->size; + + args._ukk_private = NULL; /** @note unused */ + + DBG_MSG(4, ("No more VMA references left, releasing UMP memory\n")); + _ump_ukk_unmap_mem( & args ); + + /* vma_usage_tracker is free()d by _ump_osk_mem_mapregion_term() */ + } +} + +_mali_osk_errcode_t _ump_osk_mem_mapregion_init( ump_memory_allocation * descriptor ) +{ + ump_vma_usage_tracker * vma_usage_tracker; + struct vm_area_struct *vma; + + if (NULL == descriptor) return _MALI_OSK_ERR_FAULT; + + vma_usage_tracker = kmalloc(sizeof(ump_vma_usage_tracker), GFP_KERNEL); + if (NULL == vma_usage_tracker) + { + DBG_MSG(1, ("Failed to allocate memory for ump_vma_usage_tracker in _mali_osk_mem_mapregion_init\n")); + return -_MALI_OSK_ERR_FAULT; + } + + vma = (struct vm_area_struct*)descriptor->process_mapping_info; + if (NULL == vma ) + { + kfree(vma_usage_tracker); + return _MALI_OSK_ERR_FAULT; + } + + vma->vm_private_data = vma_usage_tracker; + vma->vm_flags |= VM_IO; + vma->vm_flags |= VM_RESERVED; + + if (0==descriptor->is_cached) + { + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + } + DBG_MSG(3, ("Mapping with page_prot: 0x%x\n", vma->vm_page_prot )); + + /* Setup the functions which handle further VMA handling */ + vma->vm_ops = &ump_vm_ops; + + /* Do the va range allocation - in this case, it was done earlier, so we copy in that information */ + descriptor->mapping = (void __user*)vma->vm_start; + + atomic_set(&vma_usage_tracker->references, 1); /*this can later be increased if process is forked, see ump_vma_open() */ + vma_usage_tracker->descriptor = descriptor; + + return _MALI_OSK_ERR_OK; +} + +void _ump_osk_mem_mapregion_term( ump_memory_allocation * descriptor ) +{ + struct vm_area_struct* vma; + ump_vma_usage_tracker * vma_usage_tracker; + + if (NULL == descriptor) return; + + /* Linux does the right thing as part of munmap to remove the mapping + * All that remains is that we remove the vma_usage_tracker setup in init() */ + vma = (struct vm_area_struct*)descriptor->process_mapping_info; + + vma_usage_tracker = vma->vm_private_data; + + /* We only get called if mem_mapregion_init succeeded */ + kfree(vma_usage_tracker); + return; +} + +_mali_osk_errcode_t _ump_osk_mem_mapregion_map( ump_memory_allocation * descriptor, u32 offset, u32 * phys_addr, unsigned long size ) +{ + struct vm_area_struct *vma; + _mali_osk_errcode_t retval; + + if (NULL == descriptor) return _MALI_OSK_ERR_FAULT; + + vma = (struct vm_area_struct*)descriptor->process_mapping_info; + + if (NULL == vma ) return _MALI_OSK_ERR_FAULT; + + retval = remap_pfn_range( vma, ((u32)descriptor->mapping) + offset, (*phys_addr) >> PAGE_SHIFT, size, vma->vm_page_prot) ? _MALI_OSK_ERR_FAULT : _MALI_OSK_ERR_OK;; + + DBG_MSG(4, ("Mapping virtual to physical memory. ID: %u, vma: 0x%08lx, virtual addr:0x%08lx, physical addr: 0x%08lx, size:%lu, prot:0x%x, vm_flags:0x%x RETVAL: 0x%x\n", + ump_dd_secure_id_get(descriptor->handle), + (unsigned long)vma, + (unsigned long)(vma->vm_start + offset), + (unsigned long)*phys_addr, + size, + (unsigned int)vma->vm_page_prot, vma->vm_flags, retval)); + + return retval; +} + +static u32 _ump_osk_virt_to_phys_start(ump_dd_mem * mem, u32 start, u32 address, int *index) +{ + int i; + u32 offset = address - start; + ump_dd_physical_block *block; + u32 sum = 0; + + for (i=0; inr_blocks; i++) { + block = &mem->block_array[i]; + sum += block->size; + if (sum > offset) { + *index = i; + DBG_MSG(3, ("_ump_osk_virt_to_phys : index : %d, virtual 0x%x, phys 0x%x\n", i, address, (u32)block->addr + offset - (sum -block->size))); + return (u32)block->addr + offset - (sum -block->size); + } + } + + return _MALI_OSK_ERR_FAULT; +} + +static u32 _ump_osk_virt_to_phys_end(ump_dd_mem * mem, u32 start, u32 address, int *index) +{ + int i; + u32 offset = address - start; + ump_dd_physical_block *block; + u32 sum = 0; + + for (i=0; inr_blocks; i++) { + block = &mem->block_array[i]; + sum += block->size; + if (sum >= offset) { + *index = i; + DBG_MSG(3, ("_ump_osk_virt_to_phys : index : %d, virtual 0x%x, phys 0x%x\n", i, address, (u32)block->addr + offset - (sum -block->size))); + return (u32)block->addr + offset - (sum -block->size); + } + } + + return _MALI_OSK_ERR_FAULT; +} + +static void _ump_osk_msync_with_virt(ump_dd_mem * mem, ump_uk_msync_op op, u32 start, u32 address, u32 size) +{ + int start_index, end_index; + u32 start_p, end_p; + + DBG_MSG(3, ("Cache flush with user virtual address. start : 0x%x, end : 0x%x, address 0x%x, size 0x%x\n", start, start+mem->size_bytes, address, size)); + + start_p = _ump_osk_virt_to_phys_start(mem, start, address, &start_index); + end_p = _ump_osk_virt_to_phys_end(mem, start, address+size, &end_index); + + if (start_index==end_index) { + if (op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE) + outer_flush_range(start_p, end_p); + else + outer_clean_range(start_p, end_p); + } else { + ump_dd_physical_block *block; + int i; + + for (i=start_index; i<=end_index; i++) { + block = &mem->block_array[i]; + + if (i == start_index) { + if (op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE) { + outer_flush_range(start_p, block->addr+block->size); + } else { + outer_clean_range(start_p, block->addr+block->size); + } + } + else if (i == end_index) { + if (op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE) { + outer_flush_range(block->addr, end_p); + } else { + outer_clean_range(block->addr, end_p); + } + break; + } + else { + if (op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE) { + outer_flush_range(block->addr, block->addr+block->size); + } else { + outer_clean_range(block->addr, block->addr+block->size); + } + } + } + } + return; +} + +static void level1_cache_flush_all(void) +{ + DBG_MSG(4, ("UMP[xx] Flushing complete L1 cache\n")); + __cpuc_flush_kern_all(); +} + +void _ump_osk_msync( ump_dd_mem * mem, void * virt, u32 offset, u32 size, ump_uk_msync_op op, ump_session_data * session_data ) +{ + int i; + const void *start_v, *end_v; + + /* Flush L1 using virtual address, the entire range in one go. + * Only flush if user space process has a valid write mapping on given address. */ + if( (mem) && (virt!=NULL) && (access_ok(VERIFY_WRITE, virt, size)) ) + { + start_v = (void *)virt; + end_v = (void *)(start_v + size - 1); + /* There is no dmac_clean_range, so the L1 is always flushed, + * also for UMP_MSYNC_CLEAN. */ + if (size >= SZ_64K) + flush_all_cpu_caches(); + else + dmac_flush_range(start_v, end_v); + + DBG_MSG(3, ("UMP[%02u] Flushing CPU L1 Cache. Cpu address: %x-%x\n", mem->secure_id, start_v,end_v)); + } + else + { + if (session_data) + { + if (op == _UMP_UK_MSYNC_FLUSH_L1 ) + { + DBG_MSG(4, ("UMP Pending L1 cache flushes: %d\n", session_data->has_pending_level1_cache_flush)); + session_data->has_pending_level1_cache_flush = 0; + level1_cache_flush_all(); + return; + } + else + { + if (session_data->cache_operations_ongoing) + { + session_data->has_pending_level1_cache_flush++; + DBG_MSG(4, ("UMP[%02u] Defering the L1 flush. Nr pending:%d\n", mem->secure_id, session_data->has_pending_level1_cache_flush) ); + } + else + { + /* Flushing the L1 cache for each switch_user() if ump_cache_operations_control(START) is not called */ + level1_cache_flush_all(); + } + } + } + else + { + DBG_MSG(4, ("Unkown state %s %d\n", __FUNCTION__, __LINE__)); + level1_cache_flush_all(); + } + } + + if ( NULL == mem ) return; + + if ( mem->size_bytes==size) + { + DBG_MSG(3, ("UMP[%02u] Flushing CPU L2 Cache\n",mem->secure_id)); + } + else + { + DBG_MSG(3, ("UMP[%02u] Flushing CPU L2 Cache. Blocks:%u, TotalSize:%u. FlushSize:%u Offset:0x%x FirstPaddr:0x%08x\n", + mem->secure_id, mem->nr_blocks, mem->size_bytes, size, offset, mem->block_array[0].addr)); + } + + + /* Flush L2 using physical addresses, block for block. */ + if ((virt!=NULL) && (mem->size_bytes >= SZ_1M)) { + if (op == _UMP_UK_MSYNC_CLEAN) + outer_clean_all(); + else if ((op == _UMP_UK_MSYNC_INVALIDATE) || (op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE)) + outer_flush_all(); + return; + } + + for (i=0 ; i < mem->nr_blocks; i++) + { + u32 start_p, end_p; + ump_dd_physical_block *block; + block = &mem->block_array[i]; + + if(offset >= block->size) + { + offset -= block->size; + continue; + } + + if(offset) + { + start_p = (u32)block->addr + offset; + /* We'll zero the offset later, after using it to calculate end_p. */ + } + else + { + start_p = (u32)block->addr; + } + + if(size < block->size - offset) + { + end_p = start_p + size - 1; + size = 0; + } + else + { + if(offset) + { + end_p = start_p + (block->size - offset - 1); + size -= block->size - offset; + offset = 0; + } + else + { + end_p = start_p + block->size - 1; + size -= block->size; + } + } + + switch(op) + { + case _UMP_UK_MSYNC_CLEAN: + outer_clean_range(start_p, end_p); + break; + case _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE: + outer_flush_range(start_p, end_p); + break; + case _UMP_UK_MSYNC_INVALIDATE: + outer_inv_range(start_p, end_p); + break; + default: + break; + } + + if(0 == size) + { + /* Nothing left to flush. */ + break; + } + } + + return; +} + +void _ump_osk_mem_mapregion_get( ump_dd_mem ** mem, unsigned long vaddr) +{ + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + ump_vma_usage_tracker * vma_usage_tracker; + ump_memory_allocation *descriptor; + ump_dd_handle handle; + + DBG_MSG(3, ("_ump_osk_mem_mapregion_get: vaddr 0x%08lx\n", vaddr)); + + down_read(&mm->mmap_sem); + vma = find_vma(mm, vaddr); + up_read(&mm->mmap_sem); + if(!vma) + { + DBG_MSG(3, ("Not found VMA\n")); + *mem = NULL; + return; + } + DBG_MSG(4, ("Get vma: 0x%08lx vma->vm_start: 0x%08lx\n", (unsigned long)vma, vma->vm_start)); + + vma_usage_tracker = (struct ump_vma_usage_tracker*)vma->vm_private_data; + if(vma_usage_tracker == NULL) + { + DBG_MSG(3, ("Not found vma_usage_tracker\n")); + *mem = NULL; + return; + } + + descriptor = (struct ump_memory_allocation*)vma_usage_tracker->descriptor; + handle = (ump_dd_handle)descriptor->handle; + + DBG_MSG(3, ("Get handle: 0x%08lx\n", handle)); + *mem = (ump_dd_mem*)handle; +} + diff --git a/drivers/media/video/samsung/ump/linux/ump_osk_misc.c b/drivers/media/video/samsung/ump/linux/ump_osk_misc.c new file mode 100644 index 0000000..3be6fed --- /dev/null +++ b/drivers/media/video/samsung/ump/linux/ump_osk_misc.c @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file ump_osk_misc.c + * Implementation of the OS abstraction layer for the UMP kernel device driver + */ + + +#include "ump_osk.h" + +#include +#include "ump_kernel_linux.h" + +/* is called from ump_kernel_constructor in common code */ +_mali_osk_errcode_t _ump_osk_init( void ) +{ + if (0 != ump_kernel_device_initialize()) + { + return _MALI_OSK_ERR_FAULT; + } + + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t _ump_osk_term( void ) +{ + ump_kernel_device_terminate(); + return _MALI_OSK_ERR_OK; +} diff --git a/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.c b/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.c new file mode 100644 index 0000000..a6691ed --- /dev/null +++ b/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.c @@ -0,0 +1,320 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file ump_ukk_wrappers.c + * Defines the wrapper functions which turn Linux IOCTL calls into _ukk_ calls for the reference implementation + */ + + +#include /* user space access */ + +#include "ump_osk.h" +#include "ump_uk_types.h" +#include "ump_ukk.h" +#include "ump_kernel_common.h" + +#if defined(CONFIG_ION_EXYNOS) || defined(CONFIG_DMA_SHARED_BUFFER) +#include +#include "ump_kernel_interface_ref_drv.h" +#include "mali_osk_list.h" +#ifdef CONFIG_ION_EXYNOS +#include +#include "../../../../../gpu/ion/ion_priv.h" +extern struct ion_device *ion_exynos; +extern struct ion_client *ion_client_ump; +#endif +#ifdef CONFIG_DMA_SHARED_BUFFER +#include +#endif +#endif + +/* + * IOCTL operation; Allocate UMP memory + */ +int ump_allocate_wrapper(u32 __user * argument, struct ump_session_data * session_data) +{ + _ump_uk_allocate_s user_interaction; + _mali_osk_errcode_t err; + + /* Sanity check input parameters */ + if (NULL == argument || NULL == session_data) + { + MSG_ERR(("NULL parameter in ump_ioctl_allocate()\n")); + return -ENOTTY; + } + + /* Copy the user space memory to kernel space (so we safely can read it) */ + if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction))) + { + MSG_ERR(("copy_from_user() in ump_ioctl_allocate()\n")); + return -EFAULT; + } + + user_interaction.ctx = (void *) session_data; + + err = _ump_ukk_allocate( &user_interaction ); + if( _MALI_OSK_ERR_OK != err ) + { + DBG_MSG(1, ("_ump_ukk_allocate() failed in ump_ioctl_allocate()\n")); + return map_errcode(err); + } + user_interaction.ctx = NULL; + + if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction))) + { + /* If the copy fails then we should release the memory. We can use the IOCTL release to accomplish this */ + _ump_uk_release_s release_args; + + MSG_ERR(("copy_to_user() failed in ump_ioctl_allocate()\n")); + + release_args.ctx = (void *) session_data; + release_args.secure_id = user_interaction.secure_id; + + err = _ump_ukk_release( &release_args ); + if(_MALI_OSK_ERR_OK != err) + { + MSG_ERR(("_ump_ukk_release() also failed when trying to release newly allocated memory in ump_ioctl_allocate()\n")); + } + + return -EFAULT; + } + + return 0; /* success */ +} +#ifdef CONFIG_ION_EXYNOS +/* + * IOCTL operation; Import fd to UMP memory + */ +int ump_ion_import_wrapper(u32 __user * argument, struct ump_session_data * session_data) +{ + _ump_uk_ion_import_s user_interaction; + ump_dd_handle *ump_handle; + ump_dd_physical_block * blocks; + unsigned long num_blocks; + struct ion_handle *ion_hnd; + struct scatterlist *sg; + struct scatterlist *sg_ion; + unsigned long i = 0; + + ump_session_memory_list_element * session_memory_element = NULL; + if (ion_client_ump==NULL) + ion_client_ump = ion_client_create(ion_exynos, -1, "ump"); + + /* Sanity check input parameters */ + if (NULL == argument || NULL == session_data) + { + MSG_ERR(("NULL parameter in ump_ioctl_allocate()\n")); + return -ENOTTY; + } + + /* Copy the user space memory to kernel space (so we safely can read it) */ + if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction))) + { + MSG_ERR(("copy_from_user() in ump_ioctl_allocate()\n")); + return -EFAULT; + } + + user_interaction.ctx = (void *) session_data; + + /* translate fd to secure ID*/ + ion_hnd = ion_import_fd(ion_client_ump, user_interaction.ion_fd); + sg_ion = ion_map_dma(ion_client_ump,ion_hnd); + + blocks = (ump_dd_physical_block*)_mali_osk_malloc(sizeof(ump_dd_physical_block)*1024); + + if (NULL == blocks) { + MSG_ERR(("Failed to allocate blocks in ump_ioctl_allocate()\n")); + return -ENOMEM; + } + + sg = sg_ion; + do { + blocks[i].addr = sg_phys(sg); + blocks[i].size = sg_dma_len(sg); + i++; + if (i>=1024) { + _mali_osk_free(blocks); + MSG_ERR(("ion_import fail() in ump_ioctl_allocate()\n")); + return -EFAULT; + } + sg = sg_next(sg); + } while(sg); + + num_blocks = i; + + /* Initialize the session_memory_element, and add it to the session object */ + session_memory_element = _mali_osk_calloc( 1, sizeof(ump_session_memory_list_element)); + + if (NULL == session_memory_element) + { + _mali_osk_free(blocks); + DBG_MSG(1, ("Failed to allocate ump_session_memory_list_element in ump_ioctl_allocate()\n")); + return -EFAULT; + } + + ump_handle = ump_dd_handle_create_from_phys_blocks(blocks, num_blocks); + if (UMP_DD_HANDLE_INVALID == ump_handle) + { + _mali_osk_free(session_memory_element); + _mali_osk_free(blocks); + DBG_MSG(1, ("Failed to allocate ump_session_memory_list_element in ump_ioctl_allocate()\n")); + return -EFAULT; + } + + session_memory_element->mem = (ump_dd_mem*)ump_handle; + _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); + _mali_osk_list_add(&(session_memory_element->list), &(session_data->list_head_session_memory_list)); + _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); + ion_unmap_dma(ion_client_ump,ion_hnd); + ion_free(ion_client_ump, ion_hnd); + + _mali_osk_free(blocks); + + user_interaction.secure_id = ump_dd_secure_id_get(ump_handle); + user_interaction.size = ump_dd_size_get(ump_handle); + user_interaction.ctx = NULL; + + if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction))) + { + /* If the copy fails then we should release the memory. We can use the IOCTL release to accomplish this */ + + MSG_ERR(("copy_to_user() failed in ump_ioctl_allocate()\n")); + + return -EFAULT; + } + return 0; /* success */ +} +#endif + +#ifdef CONFIG_DMA_SHARED_BUFFER +int ump_dmabuf_import_wrapper(u32 __user *argument, + struct ump_session_data *session_data) +{ + ump_session_memory_list_element *session = NULL; + struct ump_uk_dmabuf ump_dmabuf; + ump_dd_handle *ump_handle; + ump_dd_physical_block *blocks; + struct dma_buf_attachment *attach; + struct dma_buf *dma_buf; + struct sg_table *sgt; + struct scatterlist *sgl; + unsigned long block_size; + /* FIXME */ + struct device dev; + unsigned int i = 0, npages; + int ret; + + /* Sanity check input parameters */ + if (!argument || !session_data) { + MSG_ERR(("NULL parameter.\n")); + return -EINVAL; + } + + if (copy_from_user(&ump_dmabuf, argument, + sizeof(struct ump_uk_dmabuf))) { + MSG_ERR(("copy_from_user() failed.\n")); + return -EFAULT; + } + + dma_buf = dma_buf_get(ump_dmabuf.fd); + if (IS_ERR(dma_buf)) + return PTR_ERR(dma_buf); + + /* + * check whether dma_buf imported already exists or not. + * + * TODO + * if already imported then dma_buf_put() should be called + * and then just return dma_buf imported. + */ + + attach = dma_buf_attach(dma_buf, &dev); + if (IS_ERR(attach)) { + ret = PTR_ERR(attach); + goto err_dma_buf_put; + } + + sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); + if (IS_ERR(sgt)) { + ret = PTR_ERR(sgt); + goto err_dma_buf_detach; + } + + npages = sgt->nents; + + /* really need? */ + ump_dmabuf.ctx = (void *)session_data; + + block_size = sizeof(ump_dd_physical_block) * npages; + + blocks = (ump_dd_physical_block *)_mali_osk_malloc(block_size); + sgl = sgt->sgl; + + while (i < npages) { + blocks[i].addr = sg_phys(sgl); + blocks[i].size = sg_dma_len(sgl); + sgl = sg_next(sgl); + i++; + } + + /* + * Initialize the session memory list element, and add it + * to the session object + */ + session = _mali_osk_calloc(1, sizeof(*session)); + if (!session) { + DBG_MSG(1, ("Failed to allocate session.\n")); + ret = -EFAULT; + goto err_free_block; + } + + ump_handle = ump_dd_handle_create_from_phys_blocks(blocks, i); + if (UMP_DD_HANDLE_INVALID == ump_handle) { + DBG_MSG(1, ("Failed to create ump handle.\n")); + ret = -EFAULT; + goto err_free_session; + } + + session->mem = (ump_dd_mem *)ump_handle; + + _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); + _mali_osk_list_add(&(session->list), + &(session_data->list_head_session_memory_list)); + _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); + + _mali_osk_free(blocks); + + ump_dmabuf.ump_handle = (uint32_t)ump_handle; + ump_dmabuf.size = ump_dd_size_get(ump_handle); + + if (copy_to_user(argument, &ump_dmabuf, + sizeof(struct ump_uk_dmabuf))) { + MSG_ERR(("copy_to_user() failed.\n")); + ret = -EFAULT; + goto err_release_ump_handle; + } + + return 0; + +err_release_ump_handle: + ump_dd_reference_release(ump_handle); +err_free_session: + _mali_osk_free(session); +err_free_block: + _mali_osk_free(blocks); + dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); +err_dma_buf_detach: + dma_buf_detach(dma_buf, attach); +err_dma_buf_put: + dma_buf_put(dma_buf); + return ret; +} +#endif diff --git a/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.h b/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.h new file mode 100644 index 0000000..416a584 --- /dev/null +++ b/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file ump_ukk_wrappers.h + * Defines the wrapper functions which turn Linux IOCTL calls into _ukk_ calls for the reference implementation + */ + +#ifndef __UMP_UKK_REF_WRAPPERS_H__ +#define __UMP_UKK_REF_WRAPPERS_H__ + +#include +#include "ump_kernel_common.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + +int ump_allocate_wrapper(u32 __user * argument, struct ump_session_data * session_data); + +#ifdef CONFIG_ION_EXYNOS +int ump_ion_import_wrapper(u32 __user * argument, struct ump_session_data * session_data); +#endif + +#ifdef CONFIG_DMA_SHARED_BUFFER +int ump_dmabuf_import_wrapper(u32 __user *argument, + struct ump_session_data *session_data); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __UMP_UKK_REF_WRAPPERS_H__ */ diff --git a/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.c b/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.c new file mode 100644 index 0000000..780f311 --- /dev/null +++ b/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.c @@ -0,0 +1,306 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file ump_ukk_wrappers.c + * Defines the wrapper functions which turn Linux IOCTL calls into _ukk_ calls + */ + +#include /* user space access */ + +#include "ump_osk.h" +#include "ump_uk_types.h" +#include "ump_ukk.h" +#include "ump_kernel_common.h" + +/* + * IOCTL operation; Negotiate version of IOCTL API + */ +int ump_get_api_version_wrapper(u32 __user * argument, struct ump_session_data * session_data) +{ + _ump_uk_api_version_s version_info; + _mali_osk_errcode_t err; + + /* Sanity check input parameters */ + if (NULL == argument || NULL == session_data) + { + MSG_ERR(("NULL parameter in ump_ioctl_get_api_version()\n")); + return -ENOTTY; + } + + /* Copy the user space memory to kernel space (so we safely can read it) */ + if (0 != copy_from_user(&version_info, argument, sizeof(version_info))) + { + MSG_ERR(("copy_from_user() in ump_ioctl_get_api_version()\n")); + return -EFAULT; + } + + version_info.ctx = (void*) session_data; + err = _ump_uku_get_api_version( &version_info ); + if( _MALI_OSK_ERR_OK != err ) + { + MSG_ERR(("_ump_uku_get_api_version() failed in ump_ioctl_get_api_version()\n")); + return map_errcode(err); + } + + version_info.ctx = NULL; + + /* Copy ouput data back to user space */ + if (0 != copy_to_user(argument, &version_info, sizeof(version_info))) + { + MSG_ERR(("copy_to_user() failed in ump_ioctl_get_api_version()\n")); + return -EFAULT; + } + + return 0; /* success */ +} + + +/* + * IOCTL operation; Release reference to specified UMP memory. + */ +int ump_release_wrapper(u32 __user * argument, struct ump_session_data * session_data) +{ + _ump_uk_release_s release_args; + _mali_osk_errcode_t err; + + /* Sanity check input parameters */ + if (NULL == session_data) + { + MSG_ERR(("NULL parameter in ump_ioctl_release()\n")); + return -ENOTTY; + } + + /* Copy the user space memory to kernel space (so we safely can read it) */ + if (0 != copy_from_user(&release_args, argument, sizeof(release_args))) + { + MSG_ERR(("copy_from_user() in ump_ioctl_get_api_version()\n")); + return -EFAULT; + } + + release_args.ctx = (void*) session_data; + err = _ump_ukk_release( &release_args ); + if( _MALI_OSK_ERR_OK != err ) + { + MSG_ERR(("_ump_ukk_release() failed in ump_ioctl_release()\n")); + return map_errcode(err); + } + + + return 0; /* success */ +} + +/* + * IOCTL operation; Return size for specified UMP memory. + */ +int ump_size_get_wrapper(u32 __user * argument, struct ump_session_data * session_data) +{ + _ump_uk_size_get_s user_interaction; + _mali_osk_errcode_t err; + + /* Sanity check input parameters */ + if (NULL == argument || NULL == session_data) + { + MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n")); + return -ENOTTY; + } + + if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction))) + { + MSG_ERR(("copy_from_user() in ump_ioctl_size_get()\n")); + return -EFAULT; + } + + user_interaction.ctx = (void *) session_data; + err = _ump_ukk_size_get( &user_interaction ); + if( _MALI_OSK_ERR_OK != err ) + { + MSG_ERR(("_ump_ukk_size_get() failed in ump_ioctl_size_get()\n")); + return map_errcode(err); + } + + user_interaction.ctx = NULL; + + if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction))) + { + MSG_ERR(("copy_to_user() failed in ump_ioctl_size_get()\n")); + return -EFAULT; + } + + return 0; /* success */ +} + +/* + * IOCTL operation; Do cache maintenance on specified UMP memory. + */ +int ump_msync_wrapper(u32 __user * argument, struct ump_session_data * session_data) +{ + _ump_uk_msync_s user_interaction; + + /* Sanity check input parameters */ + if (NULL == argument || NULL == session_data) + { + MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n")); + return -ENOTTY; + } + + if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction))) + { + MSG_ERR(("copy_from_user() in ump_ioctl_msync()\n")); + return -EFAULT; + } + + user_interaction.ctx = (void *) session_data; + + _ump_ukk_msync( &user_interaction ); + + user_interaction.ctx = NULL; + + if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction))) + { + MSG_ERR(("copy_to_user() failed in ump_ioctl_msync()\n")); + return -EFAULT; + } + + return 0; /* success */ +} +int ump_cache_operations_control_wrapper(u32 __user * argument, struct ump_session_data * session_data) +{ + _ump_uk_cache_operations_control_s user_interaction; + + /* Sanity check input parameters */ + if (NULL == argument || NULL == session_data) + { + MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n")); + return -ENOTTY; + } + + if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction))) + { + MSG_ERR(("copy_from_user() in ump_ioctl_cache_operations_control()\n")); + return -EFAULT; + } + + user_interaction.ctx = (void *) session_data; + + _ump_ukk_cache_operations_control((_ump_uk_cache_operations_control_s*) &user_interaction ); + + user_interaction.ctx = NULL; + +#if 0 /* No data to copy back */ + if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction))) + { + MSG_ERR(("copy_to_user() failed in ump_ioctl_cache_operations_control()\n")); + return -EFAULT; + } +#endif + return 0; /* success */ +} + +int ump_switch_hw_usage_wrapper(u32 __user * argument, struct ump_session_data * session_data) +{ + _ump_uk_switch_hw_usage_s user_interaction; + + /* Sanity check input parameters */ + if (NULL == argument || NULL == session_data) + { + MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n")); + return -ENOTTY; + } + + if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction))) + { + MSG_ERR(("copy_from_user() in ump_ioctl_switch_hw_usage()\n")); + return -EFAULT; + } + + user_interaction.ctx = (void *) session_data; + + _ump_ukk_switch_hw_usage( &user_interaction ); + + user_interaction.ctx = NULL; + +#if 0 /* No data to copy back */ + if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction))) + { + MSG_ERR(("copy_to_user() failed in ump_ioctl_switch_hw_usage()\n")); + return -EFAULT; + } +#endif + return 0; /* success */ +} + +int ump_lock_wrapper(u32 __user * argument, struct ump_session_data * session_data) +{ + _ump_uk_lock_s user_interaction; + + /* Sanity check input parameters */ + if (NULL == argument || NULL == session_data) + { + MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n")); + return -ENOTTY; + } + + if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction))) + { + MSG_ERR(("copy_from_user() in ump_ioctl_switch_hw_usage()\n")); + return -EFAULT; + } + + user_interaction.ctx = (void *) session_data; + + _ump_ukk_lock( &user_interaction ); + + user_interaction.ctx = NULL; + +#if 0 /* No data to copy back */ + if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction))) + { + MSG_ERR(("copy_to_user() failed in ump_ioctl_switch_hw_usage()\n")); + return -EFAULT; + } +#endif + + return 0; /* success */ +} + +int ump_unlock_wrapper(u32 __user * argument, struct ump_session_data * session_data) +{ + _ump_uk_unlock_s user_interaction; + + /* Sanity check input parameters */ + if (NULL == argument || NULL == session_data) + { + MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n")); + return -ENOTTY; + } + + if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction))) + { + MSG_ERR(("copy_from_user() in ump_ioctl_switch_hw_usage()\n")); + return -EFAULT; + } + + user_interaction.ctx = (void *) session_data; + + _ump_ukk_unlock( &user_interaction ); + + user_interaction.ctx = NULL; + +#if 0 /* No data to copy back */ + if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction))) + { + MSG_ERR(("copy_to_user() failed in ump_ioctl_switch_hw_usage()\n")); + return -EFAULT; + } +#endif + + return 0; /* success */ +} diff --git a/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.h b/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.h new file mode 100644 index 0000000..e87a903 --- /dev/null +++ b/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file ump_ukk_wrappers.h + * Defines the wrapper functions which turn Linux IOCTL calls into _ukk_ calls + */ + +#ifndef __UMP_UKK_WRAPPERS_H__ +#define __UMP_UKK_WRAPPERS_H__ + +#include +#include "ump_kernel_common.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + + +int ump_get_api_version_wrapper(u32 __user * argument, struct ump_session_data * session_data); +int ump_release_wrapper(u32 __user * argument, struct ump_session_data * session_data); +int ump_size_get_wrapper(u32 __user * argument, struct ump_session_data * session_data); +int ump_msync_wrapper(u32 __user * argument, struct ump_session_data * session_data); +int ump_cache_operations_control_wrapper(u32 __user * argument, struct ump_session_data * session_data); +int ump_switch_hw_usage_wrapper(u32 __user * argument, struct ump_session_data * session_data); +int ump_lock_wrapper(u32 __user * argument, struct ump_session_data * session_data); +int ump_unlock_wrapper(u32 __user * argument, struct ump_session_data * session_data); + + + + +#ifdef __cplusplus +} +#endif + + + +#endif /* __UMP_UKK_WRAPPERS_H__ */ -- cgit v1.1