From 8e4bff4cab0ddac6060645b0715210484d02ff40 Mon Sep 17 00:00:00 2001 From: Yuval Adam <_@yuv.al> Date: Wed, 30 Aug 2017 08:25:59 +0000 Subject: Initial file dump from open source release --- drivers/media/sprd_gsp/Kconfig | 6 + drivers/media/sprd_gsp/Makefile | 22 + drivers/media/sprd_gsp/gsp_config_if.c | 293 +++++++ drivers/media/sprd_gsp/gsp_config_if.h | 484 ++++++++++++ drivers/media/sprd_gsp/gsp_debug.h | 336 ++++++++ drivers/media/sprd_gsp/gsp_drv.c | 1253 ++++++++++++++++++++++++++++++ drivers/media/sprd_gsp/gsp_drv_common.h | 103 +++ drivers/media/sprd_gsp/scaler_coef_cal.c | 811 +++++++++++++++++++ drivers/media/sprd_gsp/scaler_coef_cal.h | 72 ++ drivers/media/sprd_gsp/sin_cos.c | 153 ++++ drivers/media/sprd_gsp/sin_cos.h | 24 + 11 files changed, 3557 insertions(+) create mode 100644 drivers/media/sprd_gsp/Kconfig create mode 100644 drivers/media/sprd_gsp/Makefile create mode 100644 drivers/media/sprd_gsp/gsp_config_if.c create mode 100644 drivers/media/sprd_gsp/gsp_config_if.h create mode 100644 drivers/media/sprd_gsp/gsp_debug.h create mode 100644 drivers/media/sprd_gsp/gsp_drv.c create mode 100644 drivers/media/sprd_gsp/gsp_drv_common.h create mode 100644 drivers/media/sprd_gsp/scaler_coef_cal.c create mode 100644 drivers/media/sprd_gsp/scaler_coef_cal.h create mode 100644 drivers/media/sprd_gsp/sin_cos.c create mode 100644 drivers/media/sprd_gsp/sin_cos.h (limited to 'drivers/media/sprd_gsp') diff --git a/drivers/media/sprd_gsp/Kconfig b/drivers/media/sprd_gsp/Kconfig new file mode 100644 index 00000000..47a4f909 --- /dev/null +++ b/drivers/media/sprd_gsp/Kconfig @@ -0,0 +1,6 @@ +config VIDEO_GSP_SPRD + tristate "SPRD GSP driver" + # depends on ARCH_SC8825 + # default m + help + Support GSP for SPRD diff --git a/drivers/media/sprd_gsp/Makefile b/drivers/media/sprd_gsp/Makefile new file mode 100644 index 00000000..2360bf7d --- /dev/null +++ b/drivers/media/sprd_gsp/Makefile @@ -0,0 +1,22 @@ +# SC88XX Platform Support + + +ifeq ($(CONFIG_ARCH_SCX35),y) + +# CONFIG_VIDEO_GSP_SPRD = m +ifeq ($(CONFIG_VIDEO_GSP_SPRD),y) +sprd_gsp-objs := scaler_coef_cal.o gsp_config_if.o gsp_drv.o +obj-$(CONFIG_VIDEO_GSP_SPRD) += sprd_gsp.o +else +sprd_gsp-objs := sin_cos.o scaler_coef_cal.o gsp_config_if.o gsp_drv.o +obj-m += sprd_gsp.o +endif + +# $(warning ytc-------------------------- : $(CONFIG_VIDEO_GSP_SPRD)) + + +# EXTRA_CFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=neon +EXTRA_CFLAGS += $(arch_variant_cflags) +# arch_variant_ldflags := -Wl,--fix-cortex-a8 + +endif diff --git a/drivers/media/sprd_gsp/gsp_config_if.c b/drivers/media/sprd_gsp/gsp_config_if.c new file mode 100644 index 00000000..190a77ee --- /dev/null +++ b/drivers/media/sprd_gsp/gsp_config_if.c @@ -0,0 +1,293 @@ +/* + * Copyright (C) 2012 Spreadtrum Communications Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + */ + +/**---------------------------------------------------------------------------* +** Dependencies * +**---------------------------------------------------------------------------*/ +//#include + + +#include "gsp_config_if.h" + + + +/**---------------------------------------------------------------------------* + ** Dependencies * + **---------------------------------------------------------------------------*/ + +/**---------------------------------------------------------------------------* + ** Macro Definition * + **---------------------------------------------------------------------------*/ + + +/**---------------------------------------------------------------------------* + ** Function Define * + **---------------------------------------------------------------------------*/ + +LOCAL void GSP_SetLayer0Parameter(gsp_context_t *gspCtx) +{ + if(!gspCtx->gsp_cfg.layer0_info.layer_en) { + GSP_L0_ENABLE_SET(0); + return ; + } + + GSP_L0_ADDR_SET(gspCtx->gsp_cfg.layer0_info.src_addr); + GSP_L0_PITCH_SET(gspCtx->gsp_cfg.layer0_info.pitch); + GSP_L0_CLIPRECT_SET(gspCtx->gsp_cfg.layer0_info.clip_rect); + GSP_L0_DESRECT_SET(gspCtx->gsp_cfg.layer0_info.des_rect); + GSP_L0_GREY_SET(gspCtx->gsp_cfg.layer0_info.grey); + GSP_L0_ENDIAN_SET(gspCtx->gsp_cfg.layer0_info.endian_mode); + GSP_L0_ALPHA_SET(gspCtx->gsp_cfg.layer0_info.alpha); + GSP_L0_COLORKEY_SET(gspCtx->gsp_cfg.layer0_info.colorkey); + GSP_L0_IMGFORMAT_SET(gspCtx->gsp_cfg.layer0_info.img_format); + GSP_L0_ROTMODE_SET(gspCtx->gsp_cfg.layer0_info.rot_angle); + GSP_L0_COLORKEYENABLE_SET(gspCtx->gsp_cfg.layer0_info.colorkey_en); + GSP_L0_PALLETENABLE_SET(gspCtx->gsp_cfg.layer0_info.pallet_en); + //GSP_L0_SCALETAPMODE_SET(gspCtx->gsp_cfg.layer0_info.row_tap_mode,gspCtx->gsp_cfg.layer0_info.col_tap_mode); + +} + + +LOCAL void GSP_SetLayer1Parameter(gsp_context_t *gspCtx) +{ + if(!gspCtx->gsp_cfg.layer1_info.layer_en) { + GSP_L1_ENABLE_SET(0); + return ; + } + + GSP_L1_ADDR_SET(gspCtx->gsp_cfg.layer1_info.src_addr); + GSP_L1_PITCH_SET(gspCtx->gsp_cfg.layer1_info.pitch); + GSP_L1_CLIPRECT_SET(gspCtx->gsp_cfg.layer1_info.clip_rect); + GSP_L1_DESPOS_SET(gspCtx->gsp_cfg.layer1_info.des_pos); + GSP_L1_GREY_SET(gspCtx->gsp_cfg.layer1_info.grey); + GSP_L1_ENDIAN_SET(gspCtx->gsp_cfg.layer1_info.endian_mode); + GSP_L1_ALPHA_SET(gspCtx->gsp_cfg.layer1_info.alpha); + GSP_L1_COLORKEY_SET(gspCtx->gsp_cfg.layer1_info.colorkey); + GSP_L1_IMGFORMAT_SET(gspCtx->gsp_cfg.layer1_info.img_format); + GSP_L1_ROTMODE_SET(gspCtx->gsp_cfg.layer1_info.rot_angle); + GSP_L1_COLORKEYENABLE_SET(gspCtx->gsp_cfg.layer1_info.colorkey_en); + GSP_L1_PALLETENABLE_SET(gspCtx->gsp_cfg.layer1_info.pallet_en); + +} + + +LOCAL void GSP_SetLayerDesParameter(gsp_context_t *gspCtx) +{ + if(!gspCtx->gsp_cfg.layer0_info.layer_en && !gspCtx->gsp_cfg.layer1_info.layer_en) { + return ; + } + + GSP_Ld_ADDR_SET(gspCtx->gsp_cfg.layer_des_info.src_addr); + GSP_Ld_PITCH_SET(gspCtx->gsp_cfg.layer_des_info.pitch); + GSP_Ld_ENDIAN_SET(gspCtx->gsp_cfg.layer_des_info.endian_mode); + GSP_Ld_IMGFORMAT_SET(gspCtx->gsp_cfg.layer_des_info.img_format); + GSP_Ld_COMPRESSRGB888_SET(gspCtx->gsp_cfg.layer_des_info.compress_r8_en); +} + +LOCAL void GSP_SetMiscParameter(gsp_context_t *gspCtx) +{ + if(!gspCtx->gsp_cfg.layer0_info.layer_en && !gspCtx->gsp_cfg.layer1_info.layer_en) { + return ; + } + + GSP_L0_ENABLE_SET(gspCtx->gsp_cfg.layer0_info.layer_en); + GSP_L1_ENABLE_SET(gspCtx->gsp_cfg.layer1_info.layer_en); + + if(gspCtx->gsp_cfg.layer0_info.scaling_en == 1) { + GSP_SCALESTATUS_RESET(); + } + GSP_SCALE_ENABLE_SET(gspCtx->gsp_cfg.layer0_info.scaling_en); + + + GSP_PMARGB_ENABLE_SET(gspCtx->gsp_cfg.layer0_info.pmargb_en||gspCtx->gsp_cfg.layer1_info.pmargb_en); + GSP_L0_PMARGBMODE_SET(gspCtx->gsp_cfg.layer0_info.pmargb_mod); + GSP_L1_PMARGBMODE_SET(gspCtx->gsp_cfg.layer1_info.pmargb_mod); + GSP_PAGES_BOARDER_SPLIT_SET(gspCtx->gsp_cfg.misc_info.split_pages); + GSP_Y2R_OPT_SET(gspCtx->gsp_cfg.misc_info.y2r_opt); + GSP_DITHER_ENABLE_SET(gspCtx->gsp_cfg.misc_info.dithering_en); + //GSP_AHB_CLOCK_SET(gspCtx->gsp_cfg.misc_info.ahb_clock); + GSP_CLOCK_SET(gspCtx->gsp_cfg.misc_info.gsp_clock); + GSP_EMC_GAP_SET(gspCtx->gsp_cfg.misc_info.gsp_gap); +} + +PUBLIC void GSP_module_enable(gsp_context_t *gspCtx) +{ + int ret = 0; + //GSP_HWMODULE_ENABLE(); + if(gspCtx->gsp_clk != NULL) { + ret = clk_prepare_enable(gspCtx->gsp_clk); + if(ret) { + GSP_TRACE(KERN_ERR "%s: enable clock failed!\n",__FUNCTION__); + return; + } else { + pr_debug(KERN_INFO "%s: enable clock ok!\n",__FUNCTION__); + } + } else { + GSP_TRACE(KERN_ERR "%s: gsp_clk not init yet!\n",__FUNCTION__); + } +} +PUBLIC void GSP_module_disable(gsp_context_t *gspCtx) +{ + if(gspCtx->gsp_clk != NULL) { + //GSP_HWMODULE_DISABLE();//disable may not use the enable regiter + clk_disable_unprepare(gspCtx->gsp_clk); + } else { + printk(KERN_ERR "%s: gsp_clk not init yet!\n",__FUNCTION__); + } +} + +/* +func:GSP_ClocksCheckPhase0 +desc: check all clock except iommu +*/ +PUBLIC int GSP_ClocksCheckPhase0(void) +{ + int ret = 0; + + //check GSP enable + if(0==(GSP_REG_READ(GSP_MOD_EN)&GSP_MOD_EN_BIT)) { + printk(KERN_ERR "%s: err: gsp enable is not set!%lx:%08x\n",__FUNCTION__, + (ulong)GSP_MOD_EN,GSP_REG_READ(GSP_MOD_EN)); + ret++; + } else { + if(GSP_WORKSTATUS_GET() != 0) { + printk(KERN_ERR "%s: err:busy is still on!!!!\n",__FUNCTION__); + ret++; + } + } + + //check GSP clock select + if(GSP_CLK_SEL_BIT_MASK!=(GSP_REG_READ(GSP_CLOCK_BASE)&GSP_CLK_SEL_BIT_MASK)) { + printk(KERN_INFO "%s: info: gsp clock select is not set to hightest freq!%lx:%08x\n",__FUNCTION__, + (ulong)GSP_CLOCK_BASE,GSP_REG_READ(GSP_CLOCK_BASE)); + } + + //check GSP AUTO_GATE clock + if(0==(GSP_REG_READ(GSP_AUTO_GATE_ENABLE_BASE)&GSP_AUTO_GATE_ENABLE_BIT)) { + printk(KERN_ERR "%s: err: gsp auto gate clock is not enable!%lx:%08x\n",__FUNCTION__, + (ulong)GSP_AUTO_GATE_ENABLE_BASE,GSP_REG_READ(GSP_AUTO_GATE_ENABLE_BASE)); + ret++; + } + + //check GSP EMC clock + if(0==(GSP_REG_READ(GSP_EMC_MATRIX_BASE)&GSP_EMC_MATRIX_BIT)) { + printk(KERN_ERR "%s: err: gsp emc clock is not enable!%lx:%08x\n",__FUNCTION__, + (ulong)GSP_EMC_MATRIX_BASE,GSP_REG_READ(GSP_EMC_MATRIX_BASE)); + ret++; + } + return (ret>0)?GSP_KERNEL_CLOCK_ERR:GSP_NO_ERR; +} + +/* +func:GSP_ClocksCheckPhase1 +desc: check iommu cfg +*/ +PUBLIC int GSP_ClocksCheckPhase1(void) +{ + int ret = 0; + uint32_t ctl_val = GSP_REG_READ(GSP_MMU_CTRL_BASE); + uint32_t addr_y0 = GSP_L0_ADDRY_GET(); + uint32_t addr_uv0 = GSP_L0_ADDRUV_GET(); + uint32_t addr_va0 = GSP_L0_ADDRVA_GET(); + uint32_t addr_y1 = GSP_L1_ADDRY_GET(); + uint32_t addr_uv1 = GSP_L1_ADDRUV_GET(); + uint32_t addr_va1 = GSP_L1_ADDRVA_GET(); + uint32_t addr_yd = GSP_Ld_ADDRY_GET(); + uint32_t addr_uvd = GSP_Ld_ADDRUV_GET(); + uint32_t addr_vad = GSP_Ld_ADDRVA_GET(); + +#define IOVA_CHECK(addr) (0x10000000<= (addr) && (addr) < 0x80000000) + + //check GSP IOMMU ENABLE + if(((ctl_val & 0x1)==0 || (ctl_val & 0xF0000000)==0)/*IOMMU be disabled*/ + &&(((GSP_L0_ENABLE_GET() == 1) && (IOVA_CHECK(addr_y0) || IOVA_CHECK(addr_uv0) || IOVA_CHECK(addr_va0)))/*L0 is enabled and use iova*/ + ||((GSP_L1_ENABLE_GET() == 1) && (IOVA_CHECK(addr_y1) || IOVA_CHECK(addr_uv1) || IOVA_CHECK(addr_va1)))/*L1 is enabled and use iova*/ + ||((GSP_L0_ENABLE_GET() == 1 ||GSP_L1_ENABLE_GET() == 1 ) && (IOVA_CHECK(addr_yd) || IOVA_CHECK(addr_uvd) || IOVA_CHECK(addr_vad))))) { + printk(KERN_ERR "%s: err: gsp iommu is not enable or iova base is null!%lx:%08x\n",__FUNCTION__, + (ulong)GSP_MMU_CTRL_BASE,GSP_REG_READ(GSP_MMU_CTRL_BASE)); + ret++; + } + return (ret>0)?GSP_KERNEL_CLOCK_ERR:GSP_NO_ERR; +} + +PUBLIC int GSP_Init(gsp_context_t *gspCtx) +{ + int ret = 0; + GSP_module_enable(gspCtx); + ret = clk_prepare_enable(gspCtx->gsp_emc_clk); + //GSP_AUTO_GATE_ENABLE();//gsp driver take charge of auto_gate bit instead of pm + if(ret) { + printk(KERN_ERR "%s: enable emc clock failed!\n",__FUNCTION__); + return GSP_KERNEL_CLOCK_ERR; + } else { + pr_debug(KERN_INFO "%s: enable emc clock ok!\n",__FUNCTION__); + } + + //GSP_HWMODULE_SOFTRESET();//sharkL bug 350028 + GSP_IRQMODE_SET(GSP_IRQ_MODE_LEVEL); + ret = GSP_ClocksCheckPhase0(); + return ret; +} +PUBLIC void GSP_Deinit(gsp_context_t *gspCtx) +{ + clk_disable_unprepare(gspCtx->gsp_emc_clk); + GSP_IRQSTATUS_CLEAR(); + GSP_IRQENABLE_SET(GSP_IRQ_TYPE_DISABLE); + GSP_module_disable(gspCtx); +} + +PUBLIC void GSP_ConfigLayer(GSP_MODULE_ID_E layer_id, gsp_context_t *gspCtx) +{ + switch(layer_id) { + case GSP_MODULE_LAYER0: + GSP_SetLayer0Parameter(gspCtx); + break; + + case GSP_MODULE_LAYER1: + GSP_SetLayer1Parameter(gspCtx); + break; + + case GSP_MODULE_DST: + GSP_SetLayerDesParameter(gspCtx); + break; + + default: + GSP_SetMiscParameter(gspCtx); + break; + } +} + +PUBLIC void GSP_Wait_Finish(void) +{ + if(GSP_WORKSTATUS_GET() != 0) { + printk(KERN_ERR "%s: err:busy is still on!!!!\n",__FUNCTION__); + } +} + + +PUBLIC uint32_t GSP_Trigger(void) +{ + int ret = GSP_ClocksCheckPhase1(); + if(ret) { + return ret; + } + if(GSP_ERRFLAG_GET()) { + //GSP_ASSERT(); + return GSP_ERRCODE_GET(); + } + + GSP_IRQENABLE_SET(GSP_IRQ_TYPE_ENABLE); + GSP_ENGINE_TRIGGER(); + return 0; +} + diff --git a/drivers/media/sprd_gsp/gsp_config_if.h b/drivers/media/sprd_gsp/gsp_config_if.h new file mode 100644 index 00000000..48c2fe70 --- /dev/null +++ b/drivers/media/sprd_gsp/gsp_config_if.h @@ -0,0 +1,484 @@ +/* + * Copyright (C) 2012 Spreadtrum Communications Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __GSP_CONFIG_IF_H_ +#define __GSP_CONFIG_IF_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + + /**---------------------------------------------------------------------------* + ** Dependencies * + **---------------------------------------------------------------------------*/ + + +#include