From patchwork Wed Oct 18 03:54:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhi, Yong" X-Patchwork-Id: 10013419 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id C490060215 for ; Wed, 18 Oct 2017 03:55:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ABE4428A82 for ; Wed, 18 Oct 2017 03:55:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A09EE28A9E; Wed, 18 Oct 2017 03:55:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F409B28A82 for ; Wed, 18 Oct 2017 03:55:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932355AbdJRDzO (ORCPT ); Tue, 17 Oct 2017 23:55:14 -0400 Received: from mga04.intel.com ([192.55.52.120]:46983 "EHLO mga04.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754696AbdJRDzL (ORCPT ); Tue, 17 Oct 2017 23:55:11 -0400 Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 17 Oct 2017 20:55:10 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.43,394,1503385200"; d="scan'208";a="131636" Received: from mssathyx-mobl1.amr.corp.intel.com (HELO yzhi-desktop.amr.corp.intel.com) ([10.254.125.146]) by orsmga002.jf.intel.com with ESMTP; 17 Oct 2017 20:55:09 -0700 From: Yong Zhi To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com Cc: jian.xu.zheng@intel.com, rajmohan.mani@intel.com, tuukka.toivonen@intel.com, jerry.w.hu@intel.com, Yong Zhi , Tomasz Figa Subject: [PATCH v4 07/12] intel-ipu3: css: firmware management Date: Tue, 17 Oct 2017 22:54:52 -0500 Message-Id: <1508298896-26096-4-git-send-email-yong.zhi@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1508298896-26096-1-git-send-email-yong.zhi@intel.com> References: <1508298896-26096-1-git-send-email-yong.zhi@intel.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Functions to load and install imgu FW blobs Signed-off-by: Yong Zhi Signed-off-by: Tomasz Figa --- drivers/media/pci/intel/ipu3/ipu3-abi.h | 1579 ++++++++++++++++++++++++++++ drivers/media/pci/intel/ipu3/ipu3-css-fw.c | 270 +++++ drivers/media/pci/intel/ipu3/ipu3-css-fw.h | 206 ++++ drivers/media/pci/intel/ipu3/ipu3-css.h | 54 + 4 files changed, 2109 insertions(+) create mode 100644 drivers/media/pci/intel/ipu3/ipu3-abi.h create mode 100644 drivers/media/pci/intel/ipu3/ipu3-css-fw.c create mode 100644 drivers/media/pci/intel/ipu3/ipu3-css-fw.h create mode 100644 drivers/media/pci/intel/ipu3/ipu3-css.h diff --git a/drivers/media/pci/intel/ipu3/ipu3-abi.h b/drivers/media/pci/intel/ipu3/ipu3-abi.h new file mode 100644 index 000000000000..33e7eaca598e --- /dev/null +++ b/drivers/media/pci/intel/ipu3/ipu3-abi.h @@ -0,0 +1,1579 @@ +/* + * Copyright (c) 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __IPU3_ABI_H +#define __IPU3_ABI_H + +#include + +/******************* IMGU Hardware information *******************/ + +#define IMGU_ISP_VMEM_ALIGN 128 +#define IMGU_DVS_BLOCK_W 64 +#define IMGU_DVS_BLOCK_H 32 +#define IMGU_GDC_BUF_X (2 * IMGU_DVS_BLOCK_W) +#define IMGU_GDC_BUF_Y IMGU_DVS_BLOCK_H +/* n = 0..1 */ +#define IMGU_SP_PMEM_BASE(n) (0x20000 + (n) * 0x4000) +#define IMGU_MAX_BQ_GRID_WIDTH 80 +#define IMGU_MAX_BQ_GRID_HEIGHT 60 +#define IMGU_OBGRID_TILE_SIZE 16 +#define IMGU_PIXELS_PER_WORD 50 +#define IMGU_BYTES_PER_WORD 64 +#define IMGU_STRIPE_FIXED_HALF_OVERLAP 2 +#define IMGU_SHD_SETS 3 +#define IMGU_BDS_MIN_CLIP_VAL 0 +#define IMGU_BDS_MAX_CLIP_VAL 2 +#define IPU3_ABI_AWB_MAX_CELLS_PER_SET 160 +#define IPU3_ABI_AF_MAX_CELLS_PER_SET 32 +#define IPU3_ABI_AWB_FR_MAX_CELLS_PER_SET 32 + +#define IMGU_ABI_ACC_OP_IDLE 0 +#define IMGU_ABI_ACC_OP_END_OF_ACK 1 +#define IMGU_ABI_ACC_OP_END_OF_OPS 2 +#define IMGU_ABI_ACC_OP_NO_OPS 3 + +#define IMGU_ABI_ACC_OPTYPE_PROCESS_LINES 0 +#define IMGU_ABI_ACC_OPTYPE_TRANSFER_DATA 1 + +#define IMGU_MMU_PADDR_SHIFT 12 + +/* Register definitions */ + +/* PM_CTRL_0_5_0_IMGHMMADR */ +#define IMGU_REG_PM_CTRL 0x0 +#define IMGU_PM_CTRL_START BIT(0) +#define IMGU_PM_CTRL_CFG_DONE BIT(1) +#define IMGU_PM_CTRL_RACE_TO_HALT BIT(2) +#define IMGU_PM_CTRL_NACK_ALL BIT(3) +#define IMGU_PM_CTRL_CSS_PWRDN BIT(4) +#define IMGU_PM_CTRL_RST_AT_EOF BIT(5) +#define IMGU_PM_CTRL_FORCE_HALT BIT(6) +#define IMGU_PM_CTRL_FORCE_UNHALT BIT(7) +#define IMGU_PM_CTRL_FORCE_PWRDN BIT(8) +#define IMGU_PM_CTRL_FORCE_RESET BIT(9) +#define IMGU_PM_CTRL_RETURN_LICENSE_AT_EOF BIT(10) +#define IMGU_PM_CTRL_POWER_DOWN_AT_EOF (IMGU_PM_CTRL_CSS_PWRDN | \ + IMGU_PM_CTRL_RACE_TO_HALT | \ + IMGU_PM_CTRL_RETURN_LICENSE_AT_EOF) +#define IMGU_PM_CTRL_RESET_AT_EOF (IMGU_PM_CTRL_RST_AT_EOF | \ + IMGU_PM_CTRL_RACE_TO_HALT | \ + IMGU_PM_CTRL_RETURN_LICENSE_AT_EOF) +/* SYSTEM_REQ_0_5_0_IMGHMMADR */ +#define IMGU_REG_SYSTEM_REQ 0x18 +#define IMGU_SYSTEM_REQ_FREQ_MASK 0x3f +#define IMGU_SYSTEM_REQ_FREQ_DIVIDER 25 +#define IMGU_REG_INT_STATUS 0x30 +#define IMGU_REG_INT_ENABLE 0x34 +#define IMGU_REG_INT_CSS_IRQ (1 << 31) +/* STATE_0_5_0_IMGHMMADR */ +#define IMGU_REG_STATE 0x130 +#define IMGU_STATE_HALT_STS BIT(0) +#define IMGU_STATE_IDLE_STS BIT(1) +#define IMGU_STATE_POWER_UP BIT(2) +#define IMGU_STATE_POWER_DOWN BIT(3) +#define IMGU_STATE_CSS_BUSY_MASK 0xc0 +#define IMGU_STATE_PM_FSM_MASK 0x180 +#define IMGU_STATE_PWRDNM_FSM_MASK 0x1E00000 +/* PM_STS_0_5_0_IMGHMMADR */ +#define IMGU_REG_PM_STS 0x140 + +#define IMGU_REG_BASE 0x4000 + +#define IMGU_REG_ISP_CTRL (IMGU_REG_BASE + 0x00) +#define IMGU_CTRL_RST BIT(0) +#define IMGU_CTRL_START BIT(1) +#define IMGU_CTRL_BREAK BIT(2) +#define IMGU_CTRL_RUN BIT(3) +#define IMGU_CTRL_BROKEN BIT(4) +#define IMGU_CTRL_IDLE BIT(5) +#define IMGU_CTRL_SLEEPING BIT(6) +#define IMGU_CTRL_STALLING BIT(7) +#define IMGU_CTRL_IRQ_CLEAR BIT(8) +#define IMGU_CTRL_IRQ_READY BIT(10) +#define IMGU_CTRL_IRQ_SLEEPING BIT(11) +#define IMGU_CTRL_ICACHE_INV BIT(12) +#define IMGU_CTRL_IPREFETCH_EN BIT(13) +#define IMGU_REG_ISP_START_ADDR (IMGU_REG_BASE + 0x04) +#define IMGU_REG_ISP_ICACHE_ADDR (IMGU_REG_BASE + 0x10) +#define IMGU_REG_ISP_PC (IMGU_REG_BASE + 0x1c) + +/* SP Registers, sp = 0:SP0; 1:SP1 */ +#define IMGU_REG_SP_CTRL(sp) (IMGU_REG_BASE + (sp) * 0x100 + 0x100) + /* For bits in IMGU_REG_SP_CTRL, see IMGU_CTRL_* */ +#define IMGU_REG_SP_START_ADDR(sp) (IMGU_REG_BASE + (sp) * 0x100 + 0x104) +#define IMGU_REG_SP_ICACHE_ADDR(sp) (IMGU_REG_BASE + (sp) * 0x100 + 0x11c) +#define IMGU_REG_SP_CTRL_SINK(sp) (IMGU_REG_BASE + (sp) * 0x100 + 0x130) +#define IMGU_REG_SP_PC(sp) (IMGU_REG_BASE + (sp) * 0x100 + 0x134) + +#define IMGU_REG_TLB_INVALIDATE (IMGU_REG_BASE + 0x300) +#define IMGU_TLB_INVALIDATE 1 +#define IMGU_REG_L1_PHYS (IMGU_REG_BASE + 0x304) /* 27-bit pfn */ + +#define IMGU_REG_CIO_GATE_BURST_STATE (IMGU_REG_BASE + 0x404) +#define IMGU_CIO_GATE_BURST_MASK 0x80 + +#define IMGU_REG_GP_BUSY (IMGU_REG_BASE + 0x500) +#define IMGU_REG_GP_STARVING (IMGU_REG_BASE + 0x504) +#define IMGU_REG_GP_WORKLOAD (IMGU_REG_BASE + 0x508) +#define IMGU_REG_GP_IRQ(n) (IMGU_REG_BASE + (n) * 4 + 0x50c) /* n = 0..4 */ +#define IMGU_REG_GP_SP1_STRMON_STAT (IMGU_REG_BASE + 0x520) +#define IMGU_REG_GP_SP2_STRMON_STAT (IMGU_REG_BASE + 0x524) +#define IMGU_REG_GP_ISP_STRMON_STAT (IMGU_REG_BASE + 0x528) +#define IMGU_REG_GP_MOD_STRMON_STAT (IMGU_REG_BASE + 0x52c) + +/* Port definitions for the streaming monitors. */ +/* For each definition there is signal pair : valid [bit 0]- accept [bit 1] */ +#define IMGU_GP_STRMON_STAT_SP1_PORT_SP12DMA BIT(0) +#define IMGU_GP_STRMON_STAT_SP1_PORT_DMA2SP1 BIT(2) +#define IMGU_GP_STRMON_STAT_SP1_PORT_SP12SP2 BIT(4) +#define IMGU_GP_STRMON_STAT_SP1_PORT_SP22SP1 BIT(6) +#define IMGU_GP_STRMON_STAT_SP1_PORT_SP12ISP BIT(8) +#define IMGU_GP_STRMON_STAT_SP1_PORT_ISP2SP1 BIT(10) +#define IMGU_GP_STRMON_STAT_SP1_PORT_SP12GDC BIT(12) +#define IMGU_GP_STRMON_STAT_SP1_PORT_GDC2SP1 BIT(14) +#define IMGU_GP_STRMON_STAT_SP1_PORT_SP12DECOMP BIT(16) +#define IMGU_GP_STRMON_STAT_SP1_PORT_DECOMP2SP1 BIT(18) +#define IMGU_GP_STRMON_STAT_SP1_PORT_OUTFORMACC BIT(20) +#define IMGU_GP_STRMON_STAT_SP1_PORT_OUTSCALER BIT(22) + +#define IMGU_GP_STRMON_STAT_SP2_PORT_SP22DMA BIT(0) +#define IMGU_GP_STRMON_STAT_SP2_PORT_DMA2SP2 BIT(2) +#define IMGU_GP_STRMON_STAT_SP2_PORT_SP22SP1 BIT(4) +#define IMGU_GP_STRMON_STAT_SP2_PORT_SP12SP2 BIT(6) +#define IMGU_GP_STRMON_STAT_SP2_PORT_SP22ISP BIT(8) +#define IMGU_GP_STRMON_STAT_SP2_PORT_ISP2SP2 BIT(10) +#define IMGU_GP_STRMON_STAT_SP2_PORT_SP22GDC BIT(12) +#define IMGU_GP_STRMON_STAT_SP2_PORT_GDC2SP2 BIT(14) +#define IMGU_GP_STRMON_STAT_SP2_PORT_SP22DECOMP BIT(16) +#define IMGU_GP_STRMON_STAT_SP2_PORT_DECOMP2SP2 BIT(18) +#define IMGU_GP_STRMON_STAT_SP2_PORT_OUTFORMACC BIT(20) +#define IMGU_GP_STRMON_STAT_SP2_PORT_OUTSCALER BIT(22) + +#define IMGU_GP_STRMON_STAT_ISP_PORT_ISP2DMA BIT(0) +#define IMGU_GP_STRMON_STAT_ISP_PORT_DMA2ISP BIT(2) +#define IMGU_GP_STRMON_STAT_ISP_PORT_ISP2SP1 BIT(4) +#define IMGU_GP_STRMON_STAT_ISP_PORT_SP12ISP BIT(6) +#define IMGU_GP_STRMON_STAT_ISP_PORT_ISP2SP2 BIT(8) +#define IMGU_GP_STRMON_STAT_ISP_PORT_SP22ISP BIT(10) +#define IMGU_GP_STRMON_STAT_ISP_PORT_ISP2GDC BIT(12) +#define IMGU_GP_STRMON_STAT_ISP_PORT_GDC2ISP BIT(14) +#define IMGU_GP_STRMON_STAT_ISP_PORT_ISP2DECOMP BIT(16) +#define IMGU_GP_STRMON_STAT_ISP_PORT_DECOMP2ISP BIT(18) +#define IMGU_GP_STRMON_STAT_ISP_PORT_S2V1 BIT(20) +#define IMGU_GP_STRMON_STAT_ISP_PORT_S2V2 BIT(22) +#define IMGU_GP_STRMON_STAT_ISP_PORT_S2V3 BIT(24) +#define IMGU_GP_STRMON_STAT_ISP_PORT_S2V4 BIT(26) +#define IMGU_GP_STRMON_STAT_ISP_PORT_S2V5 BIT(28) +#define IMGU_GP_STRMON_STAT_ISP_PORT_S2V6 BIT(30) + +/* Between the devices and the fifo */ +#define IMGU_GP_STRMON_STAT_MOD_PORT_SP12DMA BIT(0) +#define IMGU_GP_STRMON_STAT_MOD_PORT_DMA2SP1 BIT(2) +#define IMGU_GP_STRMON_STAT_MOD_PORT_SP22DMA BIT(4) +#define IMGU_GP_STRMON_STAT_MOD_PORT_DMA2SP2 BIT(6) +#define IMGU_GP_STRMON_STAT_MOD_PORT_ISP2DMA BIT(8) +#define IMGU_GP_STRMON_STAT_MOD_PORT_DMA2ISP BIT(10) +#define IMGU_GP_STRMON_STAT_MOD_PORT_CELLS2GDC BIT(12) +#define IMGU_GP_STRMON_STAT_MOD_PORT_GDC2CELLS BIT(14) +#define IMGU_GP_STRMON_STAT_MOD_PORT_CELLS2DECOMP BIT(16) +#define IMGU_GP_STRMON_STAT_MOD_PORT_DECOMP2CELLS BIT(18) +/* n = 1..6 */ +#define IMGU_GP_STRMON_STAT_MOD_PORT_S2V(n) (1 << (((n) - 1) * 2 + 20)) + +/* n = 1..15 */ +#define IMGU_GP_STRMON_STAT_ACCS_PORT_ACC(n) (1 << (((n) - 1) * 2)) + +/* After FIFO and demux before SP1, n = 1..15 */ +#define IMGU_GP_STRMON_STAT_ACCS2SP1_MON_PORT_ACC(n) (1 << (((n) - 1) * 2)) + +/* After FIFO and demux before SP2, n = 1..15 */ +#define IMGU_GP_STRMON_STAT_ACCS2SP2_MON_PORT_ACC(n) (1 << (((n) - 1) * 2)) + +#define IMGU_REG_GP_MOD_ISP_STRMON_STAT (IMGU_REG_BASE + 0x530) +#define IMGU_REG_GP_ACCS_STRMON_STAT (IMGU_REG_BASE + 0x534) +#define IMGU_REG_GP_ACCS_SP1_STRMON_STAT (IMGU_REG_BASE + 0x538) +#define IMGU_REG_GP_ACCS_SP2_STRMON_STAT (IMGU_REG_BASE + 0x53c) +#define IMGU_REG_GP_SP1_STRMON_STAT_IRQ_COND (IMGU_REG_BASE + 0x540) +#define IMGU_REG_GP_SP2_STRMON_STAT_IRQ_COND (IMGU_REG_BASE + 0x544) +#define IMGU_REG_GP_ISP_STRMON_STAT_IRQ_COND (IMGU_REG_BASE + 0x548) +#define IMGU_REG_GP_MOD_STRMON_STAT_IRQ_COND (IMGU_REG_BASE + 0x54c) +#define IMGU_REG_GP_MOD_ISP_STRMON_STAT_IRQ_COND (IMGU_REG_BASE + 0x550) +#define IMGU_REG_GP_ACCS_STRMON_STAT_IRQ_COND (IMGU_REG_BASE + 0x554) +#define IMGU_REG_GP_ACCS_SP1_STRMON_STAT_IRQ_COND (IMGU_REG_BASE + 0x558) +#define IMGU_REG_GP_ACCS_SP2_STRMON_STAT_IRQ_COND (IMGU_REG_BASE + 0x55c) +#define IMGU_REG_GP_SP1_STRMON_STAT_IRQ_ENABLE (IMGU_REG_BASE + 0x560) +#define IMGU_REG_GP_SP2_STRMON_STAT_IRQ_ENABLE (IMGU_REG_BASE + 0x564) +#define IMGU_REG_GP_ISP_STRMON_STAT_IRQ_ENABLE (IMGU_REG_BASE + 0x568) +#define IMGU_REG_GP_MOD_STRMON_STAT_IRQ_ENABLE (IMGU_REG_BASE + 0x56c) +#define IMGU_REG_GP_MOD_ISP_STRMON_STAT_IRQ_ENABLE (IMGU_REG_BASE + 0x570) +#define IMGU_REG_GP_ACCS_STRMON_STAT_IRQ_ENABLE (IMGU_REG_BASE + 0x574) +#define IMGU_REG_GP_ACCS_SP1_STRMON_STAT_IRQ_ENABLE (IMGU_REG_BASE + 0x578) +#define IMGU_REG_GP_ACCS_SP2_STRMON_STAT_IRQ_ENABLE_IDX (IMGU_REG_BASE + 0x57c) +#define IMGU_REG_GP_SWITCH_GDC (IMGU_REG_BASE + 0x580) +#define IMGU_REG_GP_SWITCH_DECOMP (IMGU_REG_BASE + 0x584) +#define IMGU_REG_GP_SWITCH_MAIN_IRQ_CTRL_MAIN (IMGU_REG_BASE + 0x588) +#define IMGU_REG_GP_SWITCH_ACC1 (IMGU_REG_BASE + 0x58c) +#define IMGU_REG_GP_SWITCH_ACC2 (IMGU_REG_BASE + 0x590) +#define IMGU_REG_GP_SWITCH_ACC3 (IMGU_REG_BASE + 0x594) +#define IMGU_REG_GP_SWITCH_ACC4 (IMGU_REG_BASE + 0x598) +#define IMGU_REG_GP_SWITCH_ACC5 (IMGU_REG_BASE + 0x59c) +#define IMGU_REG_GP_SWITCH_ACC6 (IMGU_REG_BASE + 0x5a0) +#define IMGU_REG_GP_SWITCH_ACC7 (IMGU_REG_BASE + 0x5a4) +#define IMGU_REG_GP_SWITCH_ACC8 (IMGU_REG_BASE + 0x5a8) +#define IMGU_REG_GP_SWITCH_ACC9 (IMGU_REG_BASE + 0x5ac) +#define IMGU_REG_GP_SWITCH_ACC10 (IMGU_REG_BASE + 0x5b0) +#define IMGU_REG_GP_SWITCH_ACC11 (IMGU_REG_BASE + 0x5b4) +#define IMGU_REG_GP_SWITCH_ACC12 (IMGU_REG_BASE + 0x5b8) +#define IMGU_REG_GP_SWITCH_ACC13 (IMGU_REG_BASE + 0x5bc) +#define IMGU_REG_GP_SWITCH_ACC14 (IMGU_REG_BASE + 0x5c0) +#define IMGU_REG_GP_SWITCH_ACC15 (IMGU_REG_BASE + 0x5c4) +#define IMGU_REG_GP_SWITCH_OUT_FORM_ACC (IMGU_REG_BASE + 0x5c8) +#define IMGU_REG_GP_SWITCH_OUT_FORM_SCALER (IMGU_REG_BASE + 0x5cc) +#define IMGU_REG_GP_SRST (IMGU_REG_BASE + 0x5d0) +#define IMGU_REG_GP_GACC_SRST (IMGU_REG_BASE + 0x5d4) +#define IMGU_REG_GP_SLV_REG_SRST (IMGU_REG_BASE + 0x5d8) +#define IMGU_REG_GP_HALT (IMGU_REG_BASE + 0x5dc) +#define IMGU_REG_GP_HALTED (IMGU_REG_BASE + 0x5e0) + + /* n = 0..2 (main ctrl, SP0, SP1) */ +#define IMGU_REG_IRQCTRL_BASE(n) (IMGU_REG_BASE + (n) * 0x100 + 0x700) +#define IMGU_IRQCTRL_MAIN 0 +#define IMGU_IRQCTRL_SP0 1 +#define IMGU_IRQCTRL_SP1 2 +#define IMGU_IRQCTRL_NUM 3 +#define IMGU_IRQCTRL_IRQ_SP1 BIT(0) +#define IMGU_IRQCTRL_IRQ_SP2 BIT(1) +#define IMGU_IRQCTRL_IRQ_ISP BIT(2) +#define IMGU_IRQCTRL_IRQ_SP1_STREAM_MON BIT(3) +#define IMGU_IRQCTRL_IRQ_SP2_STREAM_MON BIT(4) +#define IMGU_IRQCTRL_IRQ_ISP_STREAM_MON BIT(5) +#define IMGU_IRQCTRL_IRQ_MOD_STREAM_MON BIT(6) +#define IMGU_IRQCTRL_IRQ_MOD_ISP_STREAM_MON BIT(7) +#define IMGU_IRQCTRL_IRQ_ACCS_STREAM_MON BIT(8) +#define IMGU_IRQCTRL_IRQ_ACCS_SP1_STREAM_MON BIT(9) +#define IMGU_IRQCTRL_IRQ_ACCS_SP2_STREAM_MON BIT(10) +#define IMGU_IRQCTRL_IRQ_ISP_PMEM_ERROR BIT(11) +#define IMGU_IRQCTRL_IRQ_ISP_BAMEM_ERROR BIT(12) +#define IMGU_IRQCTRL_IRQ_ISP_VMEM_ERROR BIT(13) +#define IMGU_IRQCTRL_IRQ_ISP_DMEM_ERROR BIT(14) +#define IMGU_IRQCTRL_IRQ_SP1_ICACHE_MEM_ERROR BIT(15) +#define IMGU_IRQCTRL_IRQ_SP1_DMEM_ERROR BIT(16) +#define IMGU_IRQCTRL_IRQ_SP2_ICACHE_MEM_ERROR BIT(17) +#define IMGU_IRQCTRL_IRQ_SP2_DMEM_ERROR BIT(18) +#define IMGU_IRQCTRL_IRQ_ACCS_SCRATCH_MEM_ERROR BIT(19) +#define IMGU_IRQCTRL_IRQ_GP_TIMER(n) BIT(20 + (n)) /* n=0..1 */ +#define IMGU_IRQCTRL_IRQ_DMA BIT(22) +#define IMGU_IRQCTRL_IRQ_SW_PIN(n) BIT(23 + (n)) /* n=0..4 */ +#define IMGU_IRQCTRL_IRQ_ACC_SYS BIT(28) +#define IMGU_IRQCTRL_IRQ_OUT_FORM_IRQ_CTRL BIT(29) +#define IMGU_IRQCTRL_IRQ_SP1_IRQ_CTRL BIT(30) +#define IMGU_IRQCTRL_IRQ_SP2_IRQ_CTRL BIT(31) +#define IMGU_REG_IRQCTRL_EDGE(n) (IMGU_REG_IRQCTRL_BASE(n) + 0x00) +#define IMGU_REG_IRQCTRL_MASK(n) (IMGU_REG_IRQCTRL_BASE(n) + 0x04) +#define IMGU_REG_IRQCTRL_STATUS(n) (IMGU_REG_IRQCTRL_BASE(n) + 0x08) +#define IMGU_REG_IRQCTRL_CLEAR(n) (IMGU_REG_IRQCTRL_BASE(n) + 0x0c) +#define IMGU_REG_IRQCTRL_ENABLE(n) (IMGU_REG_IRQCTRL_BASE(n) + 0x10) +#define IMGU_REG_IRQCTRL_EDGE_NOT_PULSE(n) (IMGU_REG_IRQCTRL_BASE(n) + 0x14) +#define IMGU_REG_IRQCTRL_STR_OUT_ENABLE(n) (IMGU_REG_IRQCTRL_BASE(n) + 0x18) + +#define IMGU_REG_GP_TIMER (IMGU_REG_BASE + 0xa34) + +#define IMGU_REG_SP_DMEM_BASE(n) (IMGU_REG_BASE + (n) * 0x4000 + 0x4000) +#define IMGU_REG_ISP_DMEM_BASE (IMGU_REG_BASE + 0xc000) + +#define IMGU_REG_GDC_BASE (IMGU_REG_BASE + 0x18000) +#define IMGU_REG_GDC_LUT_BASE (IMGU_REG_GDC_BASE + 0x140) +#define IMGU_GDC_LUT_MASK ((1 << 12) - 1) /* Range -1024..+1024 */ + +#define IMGU_SCALER_PHASES 32 +#define IMGU_SCALER_COEFF_BITS 24 +#define IMGU_SCALER_PHASE_COUNTER_PREC_REF 6 +#define IMGU_SCALER_MAX_EXPONENT_SHIFT 3 +#define IMGU_SCALER_FILTER_TAPS 4 +#define IMGU_SCALER_TAPS_Y IMGU_SCALER_FILTER_TAPS +#define IMGU_SCALER_TAPS_UV (IMGU_SCALER_FILTER_TAPS / 2) +#define IMGU_SCALER_FIR_PHASES \ + (IMGU_SCALER_PHASES << IMGU_SCALER_PHASE_COUNTER_PREC_REF) +#define IMGU_OSYS_BLOCK_WIDTH (2 * IPU3_UAPI_ISP_VEC_ELEMS) +#define IMGU_OSYS_BLOCK_HEIGHT 32 + +/******************* imgu_abi_acc_param *******************/ + +#define IMGU_ABI_BNR_LUT_SIZE 32 + +/* number of elements in gamma correction LUT */ +#define IMGU_ABI_GAMMA_CORR_LUT_ENTRIES 256 + +#define IMGU_ABI_SHD_MAX_OPERATIONS \ + (IMGU_ABI_SHD_MAX_PROCESS_LINES + IMGU_ABI_SHD_MAX_TRANSFERS) +#define IMGU_ABI_SHD_MAX_PROCESS_LINES 31 +#define IMGU_ABI_SHD_MAX_TRANSFERS 31 +#define IMGU_ABI_SHD_MAX_CELLS_PER_SET 146 +/* largest grid is 73x56 */ +#define IMGU_ABI_SHD_MAX_CFG_SETS (2 * 28) + +#define IMGU_ABI_DVS_STAT_L0_MD_ENTRIES 84 +#define IMGU_ABI_DVS_STAT_PARTS_IN_MD_ENTRY 10 +#define IMGU_ABI_DVS_STAT_L1_MD_ENTRIES 66 +#define IMGU_ABI_DVS_STAT_L2_MD_ENTRIES 45 +#define IMGU_ABI_DVS_STAT_MAX_OPERATIONS 100 +#define IMGU_ABI_DVS_STAT_MAX_PROCESS_LINES 52 +#define IMGU_ABI_DVS_STAT_MAX_TRANSFERS 52 + +#define IMGU_ABI_YUVP2_YTM_LUT_ENTRIES 256 +#define IMGU_ABI_YUVP2_TCC_MACC_TABLE_ELEMENTS 16 +#define IMGU_ABI_YUVP2_TCC_INV_Y_LUT_ELEMENTS 14 +#define IMGU_ABI_YUVP2_TCC_GAIN_PCWL_LUT_ELEMENTS 258 +#define IMGU_ABI_YUVP2_TCC_R_SQR_LUT_ELEMENTS 24 + +#define IMGU_ABI_DPC_COMMANDS_PER_TRANSFER 2 +#define IMGU_ABI_DPC_MAX_SUPPORTED_HEIGHT 3840 +#define IMGU_ABI_DPC_STRIPE_SIZE 50 +#define IMGU_ABI_DPC_MAX_OPERATIONS \ + (IMGU_ABI_DPC_COMMANDS_PER_TRANSFER * IMGU_ABI_DPC_MAX_CFG_SETS) +#define IMGU_ABI_DPC_MAX_PROCESS_LINES IMGU_ABI_DPC_MAX_CFG_SETS +#define IMGU_ABI_DPC_MAX_TRANSFERS IMGU_ABI_DPC_MAX_CFG_SETS +#define IMGU_ABI_DPC_MAX_DP_FIRST_LINES_PAIR 70 +#define IMGU_ABI_DPC_MAX_DP_PER_SET 192 +#define IMGU_ABI_DPC_MAX_CFG_SETS \ + ((IMGU_ABI_DPC_MAX_SUPPORTED_HEIGHT + IMGU_ABI_DPC_STRIPE_SIZE - 1) \ + / IMGU_ABI_DPC_STRIPE_SIZE) + +#define IMGU_ABI_BDS_SAMPLE_PATTERN_ARRAY_SIZE 8 +#define IMGU_ABI_BDS_PHASE_COEFFS_ARRAY_SIZE 32 + +#define IMGU_ABI_ANR_LUT_SIZE 26 +#define IMGU_ABI_ANR_PYRAMID_SIZE 22 + +#define IMGU_ABI_AWB_FR_MAX_TRANSFERS 30 +#define IMGU_ABI_AWB_FR_MAX_PROCESS_LINES 30 +#define IMGU_ABI_AWB_FR_MAX_OPERATIONS \ + (IMGU_ABI_AWB_FR_MAX_TRANSFERS + IMGU_ABI_AWB_FR_MAX_PROCESS_LINES) + +#define IMGU_ABI_AE_WEIGHTS 96 + +#define IMGU_ABI_AF_MAX_TRANSFERS 30 +#define IMGU_ABI_AF_MAX_PROCESS_LINES 30 +#define IMGU_ABI_AF_MAX_OPERATIONS \ + (IMGU_ABI_AF_MAX_TRANSFERS + IMGU_ABI_AF_MAX_PROCESS_LINES) + +#define IMGU_ABI_AWB_MAX_PROCESS_LINES 68 +#define IMGU_ABI_AWB_MAX_TRANSFERS 68 +#define IMGU_ABI_AWB_MAX_OPERATIONS \ + (IMGU_ABI_AWB_MAX_PROCESS_LINES + IMGU_ABI_AWB_MAX_TRANSFERS) + +#define IMGU_ABI_OSYS_PIN_VF 0 +#define IMGU_ABI_OSYS_PIN_OUT 1 +#define IMGU_ABI_OSYS_PINS 2 + +enum imgu_abi_frame_format { + IMGU_ABI_FRAME_FORMAT_NV11, /* 12 bit YUV 411, Y, UV plane */ + IMGU_ABI_FRAME_FORMAT_NV12, /* 12 bit YUV 420, Y, UV plane */ + IMGU_ABI_FRAME_FORMAT_NV12_16, /* 16 bit YUV 420, Y, UV plane */ + IMGU_ABI_FRAME_FORMAT_NV12_TILEY,/* 12 bit YUV 420,Intel tiled format */ + IMGU_ABI_FRAME_FORMAT_NV16, /* 16 bit YUV 422, Y, UV plane */ + IMGU_ABI_FRAME_FORMAT_NV21, /* 12 bit YUV 420, Y, VU plane */ + IMGU_ABI_FRAME_FORMAT_NV61, /* 16 bit YUV 422, Y, VU plane */ + IMGU_ABI_FRAME_FORMAT_YV12, /* 12 bit YUV 420, Y, V, U plane */ + IMGU_ABI_FRAME_FORMAT_YV16, /* 16 bit YUV 422, Y, V, U plane */ + IMGU_ABI_FRAME_FORMAT_YUV420, /* 12 bit YUV 420, Y, U, V plane */ + IMGU_ABI_FRAME_FORMAT_YUV420_16,/* yuv420, 16 bits per subpixel */ + IMGU_ABI_FRAME_FORMAT_YUV422, /* 16 bit YUV 422, Y, U, V plane */ + IMGU_ABI_FRAME_FORMAT_YUV422_16,/* yuv422, 16 bits per subpixel */ + IMGU_ABI_FRAME_FORMAT_UYVY, /* 16 bit YUV 422, UYVY interleaved */ + IMGU_ABI_FRAME_FORMAT_YUYV, /* 16 bit YUV 422, YUYV interleaved */ + IMGU_ABI_FRAME_FORMAT_YUV444, /* 24 bit YUV 444, Y, U, V plane */ + IMGU_ABI_FRAME_FORMAT_YUV_LINE, /* Internal format, 2 y lines */ + /* followed by a uv-interleaved line */ + IMGU_ABI_FRAME_FORMAT_RAW, /* RAW, 1 plane */ + IMGU_ABI_FRAME_FORMAT_RGB565, /* 16 bit RGB, 1 plane. Each 3 sub + * pixels are packed into one 16 bit + * value, 5 bits for R, 6 bits for G + * and 5 bits for B. + */ + IMGU_ABI_FRAME_FORMAT_PLANAR_RGB888, /* 24 bit RGB, 3 planes */ + IMGU_ABI_FRAME_FORMAT_RGBA888, /* 32 bit RGBA, 1 plane, A=Alpha + * (alpha is unused) + */ + IMGU_ABI_FRAME_FORMAT_QPLANE6, /* Internal, for advanced ISP */ + IMGU_ABI_FRAME_FORMAT_BINARY_8, /* byte stream, used for jpeg. For + * frames of this type, we set the + * height to 1 and the width to the + * number of allocated bytes. + */ + IMGU_ABI_FRAME_FORMAT_MIPI, /* MIPI frame, 1 plane */ + IMGU_ABI_FRAME_FORMAT_RAW_PACKED, /* RAW, 1 plane, packed */ + IMGU_ABI_FRAME_FORMAT_CSI_MIPI_YUV420_8, /* 8 bit per Y/U/V. Y odd line + * UYVY interleaved even line + */ + IMGU_ABI_FRAME_FORMAT_CSI_MIPI_LEGACY_YUV420_8, /* Legacy YUV420. + * UY odd line; + * VY even line + */ + IMGU_ABI_FRAME_FORMAT_CSI_MIPI_YUV420_10,/* 10 bit per Y/U/V. Y odd + * line; UYVY interleaved + * even line + */ + IMGU_ABI_FRAME_FORMAT_YCgCo444_16, /* Internal format for ISP2.7, + * 16 bits per plane YUV 444, + * Y, U, V plane + */ + IMGU_ABI_FRAME_FORMAT_NUM +}; + +enum imgu_abi_bayer_order { + IMGU_ABI_BAYER_ORDER_GRBG, + IMGU_ABI_BAYER_ORDER_RGGB, + IMGU_ABI_BAYER_ORDER_BGGR, + IMGU_ABI_BAYER_ORDER_GBRG +}; + +enum imgu_abi_osys_format { + IMGU_ABI_OSYS_FORMAT_YUV420, + IMGU_ABI_OSYS_FORMAT_YV12, + IMGU_ABI_OSYS_FORMAT_NV12, + IMGU_ABI_OSYS_FORMAT_NV21, + IMGU_ABI_OSYS_FORMAT_YUV_LINE, + IMGU_ABI_OSYS_FORMAT_YUY2, /* = IMGU_ABI_OSYS_FORMAT_YUYV */ + IMGU_ABI_OSYS_FORMAT_NV16, + IMGU_ABI_OSYS_FORMAT_RGBA, + IMGU_ABI_OSYS_FORMAT_BGRA +}; + +enum imgu_abi_osys_tiling { + IMGU_ABI_OSYS_TILING_NONE, + IMGU_ABI_OSYS_TILING_Y, + IMGU_ABI_OSYS_TILING_YF, +}; + +struct imgu_abi_shd_grid_config { + /* reg 0 */ + u32 grid_width:8; + u32 grid_height:8; + u32 block_width:3; + u32 __reserved0:1; + u32 block_height:3; + u32 __reserved1:1; + u32 grid_height_per_slice:8; + /* reg 1 */ + s32 x_start:13; + s32 __reserved2:3; + s32 y_start:13; + s32 __reserved3:3; +} __packed; + +struct imgu_abi_shd_general_config { + u32 init_set_vrt_offst_ul:8; + u32 shd_enable:1; + /* aka 'gf' */ + u32 gain_factor:2; + u32 __reserved:21; +} __packed; + +struct imgu_abi_shd_black_level_config { + /* reg 0 */ + s32 bl_r:12; + s32 __reserved0:4; + s32 bl_gr:12; + u32 __reserved1:1; + /* aka 'nf' */ + u32 normalization_shift:3; + /* reg 1 */ + s32 bl_gb:12; + s32 __reserved2:4; + s32 bl_b:12; + s32 __reserved3:4; +} __packed; + +struct imgu_abi_shd_config_static { + /* B0: Fixed order: one transfer to GAC */ + struct imgu_abi_shd_grid_config grid; + struct imgu_abi_shd_general_config general; + struct imgu_abi_shd_black_level_config black_level; +} __packed; + +struct imgu_abi_shd_lut_elem { + u16 factors[2]; +} __packed; + +struct imgu_abi_shd_lut_set { + struct imgu_abi_shd_lut_elem elems[IMGU_ABI_SHD_MAX_CELLS_PER_SET] + IMGU_ABI_PAD; +} __packed; + +struct imgu_abi_shd_lut { + struct imgu_abi_shd_lut_set sets[IMGU_ABI_SHD_MAX_CFG_SETS]; +} __packed; + +struct imgu_abi_shd_config { + struct imgu_abi_shd_config_static shd IMGU_ABI_PAD; + struct ipu3_uapi_shd_intra_frame_operations_data shd_ops IMGU_ABI_PAD; + struct imgu_abi_shd_lut shd_lut IMGU_ABI_PAD; +} __packed; + +struct imgu_abi_dpc_param0 { + u32 enable:1; + u32 __reserved0:15; + u32 grad_threshold:13; + u32 __reserved1:3; +} __packed; + +struct imgu_abi_dpc_num_of_dp { + u32 num_of_dp_gr:8; + u32 num_of_dp_bg:8; + u32 __reserved0:16; +} __packed; + +struct imgu_abi_dpc_params { + struct imgu_abi_dpc_param0 enable_and_threshold; + struct imgu_abi_dpc_num_of_dp num_of_dp_set0; + struct imgu_abi_dpc_num_of_dp num_of_dp_set1; + struct imgu_abi_dpc_num_of_dp num_of_dp_first_line_pair; +} __packed; + +/******************* Firmware ABI definitions *******************/ + +/***** struct imgu_abi_sp_stage *****/ + +#define IMGU_ABI_BINARY_MAX_OUTPUT_PORTS 2 + +enum imgu_abi_queue_id { + IMGU_ABI_QUEUE_EVENT_ID = -1, + IMGU_ABI_QUEUE_A_ID = 0, + IMGU_ABI_QUEUE_B_ID, + IMGU_ABI_QUEUE_C_ID, + IMGU_ABI_QUEUE_D_ID, + IMGU_ABI_QUEUE_E_ID, + IMGU_ABI_QUEUE_F_ID, + IMGU_ABI_QUEUE_G_ID, + IMGU_ABI_QUEUE_H_ID, /* input frame queue for skycam */ + IMGU_ABI_QUEUE_NUM +}; + +enum imgu_abi_buffer_type { + IMGU_ABI_BUFFER_TYPE_INVALID = -1, + IMGU_ABI_BUFFER_TYPE_3A_STATISTICS = 0, + IMGU_ABI_BUFFER_TYPE_DIS_STATISTICS, + IMGU_ABI_BUFFER_TYPE_LACE_STATISTICS, + IMGU_ABI_BUFFER_TYPE_INPUT_FRAME, + IMGU_ABI_BUFFER_TYPE_OUTPUT_FRAME, + IMGU_ABI_BUFFER_TYPE_SEC_OUTPUT_FRAME, + IMGU_ABI_BUFFER_TYPE_VF_OUTPUT_FRAME, + IMGU_ABI_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME, + IMGU_ABI_BUFFER_TYPE_RAW_OUTPUT_FRAME, + IMGU_ABI_BUFFER_TYPE_CUSTOM_INPUT, + IMGU_ABI_BUFFER_TYPE_CUSTOM_OUTPUT, + IMGU_ABI_BUFFER_TYPE_METADATA, + IMGU_ABI_BUFFER_TYPE_PARAMETER_SET, + IMGU_ABI_BUFFER_TYPE_PER_FRAME_PARAMETER_SET, + IMGU_ABI_NUM_DYNAMIC_BUFFER_TYPE, + IMGU_ABI_NUM_BUFFER_TYPE +}; + +struct imgu_abi_crop_pos { + u16 x; + u16 y; +} __packed; + +struct imgu_abi_sp_resolution { + u16 width; /* Width of valid data in pixels */ + u16 height; /* Height of valid data in lines */ +} __packed; + +/* + * Frame info struct. This describes the contents of an image frame buffer. + */ +struct imgu_abi_frame_sp_info { + struct imgu_abi_sp_resolution res; + u16 padded_width; /* stride of line in memory + * (in pixels) + */ + u8 format; /* format of the frame data */ + u8 raw_bit_depth; /* number of valid bits per pixel, + * only valid for RAW bayer frames + */ + u8 raw_bayer_order; /* bayer order, only valid + * for RAW bayer frames + */ + u8 raw_type; /* To choose the proper raw frame type. for + * Legacy SKC pipes/Default is set to + * IMGU_ABI_RAW_TYPE_BAYER. For RGB IR sensor - + * driver should set it to: + * IronGr case - IMGU_ABI_RAW_TYPE_IR_ON_GR + * IronGb case - IMGU_ABI_RAW_TYPE_IR_ON_GB + */ +#define IMGU_ABI_RAW_TYPE_BAYER 0 +#define IMGU_ABI_RAW_TYPE_IR_ON_GR 1 +#define IMGU_ABI_RAW_TYPE_IR_ON_GB 2 + u8 padding[2]; /* Extend to 32 bit multiple */ +} __packed; + +struct imgu_abi_buffer_sp { + union { + imgu_addr_t xmem_addr; + enum imgu_abi_queue_id queue_id; + } buf_src; + enum imgu_abi_buffer_type buf_type; +} __packed; + +struct imgu_abi_frame_sp_plane { + u32 offset; /* offset in bytes to start of frame data */ + /* offset is wrt data in imgu_abi_sp_sp_frame */ +} __packed; + +struct imgu_abi_frame_sp_rgb_planes { + struct imgu_abi_frame_sp_plane r; + struct imgu_abi_frame_sp_plane g; + struct imgu_abi_frame_sp_plane b; +} __packed; + +struct imgu_abi_frame_sp_yuv_planes { + struct imgu_abi_frame_sp_plane y; + struct imgu_abi_frame_sp_plane u; + struct imgu_abi_frame_sp_plane v; +} __packed; + +struct imgu_abi_frame_sp_nv_planes { + struct imgu_abi_frame_sp_plane y; + struct imgu_abi_frame_sp_plane uv; +} __packed; + +struct imgu_abi_frame_sp_plane6 { + struct imgu_abi_frame_sp_plane r; + struct imgu_abi_frame_sp_plane r_at_b; + struct imgu_abi_frame_sp_plane gr; + struct imgu_abi_frame_sp_plane gb; + struct imgu_abi_frame_sp_plane b; + struct imgu_abi_frame_sp_plane b_at_r; +} __packed; + +struct imgu_abi_frame_sp_binary_plane { + u32 size; + struct imgu_abi_frame_sp_plane data; +} __packed; + +struct imgu_abi_frame_sp { + struct imgu_abi_frame_sp_info info; + struct imgu_abi_buffer_sp buf_attr; + union { + struct imgu_abi_frame_sp_plane raw; + struct imgu_abi_frame_sp_plane rgb; + struct imgu_abi_frame_sp_rgb_planes planar_rgb; + struct imgu_abi_frame_sp_plane yuyv; + struct imgu_abi_frame_sp_yuv_planes yuv; + struct imgu_abi_frame_sp_nv_planes nv; + struct imgu_abi_frame_sp_plane6 plane6; + struct imgu_abi_frame_sp_binary_plane binary; + } planes; +} __packed; + +struct imgu_abi_resolution { + u32 width; + u32 height; +} __packed; + +struct imgu_abi_frames_sp { + struct imgu_abi_frame_sp in; + struct imgu_abi_frame_sp out[IMGU_ABI_BINARY_MAX_OUTPUT_PORTS]; + struct imgu_abi_resolution effective_in_res; + struct imgu_abi_frame_sp out_vf; + struct imgu_abi_frame_sp_info internal_frame_info; + struct imgu_abi_buffer_sp s3a_buf; + struct imgu_abi_buffer_sp dvs_buf; + struct imgu_abi_buffer_sp lace_buf; +} __packed; + +struct imgu_abi_uds_info { + u16 curr_dx; + u16 curr_dy; + u16 xc; + u16 yc; +} __packed; + +/* Information for a single pipeline stage */ +struct imgu_abi_sp_stage { + /* Multiple boolean flags can be stored in an integer */ + u8 num; /* Stage number */ + u8 isp_online; + u8 isp_copy_vf; + u8 isp_copy_output; + u8 sp_enable_xnr; + u8 isp_deci_log_factor; + u8 isp_vf_downscale_bits; + u8 deinterleaved; + /* + * NOTE: Programming the input circuit can only be done at the + * start of a session. It is illegal to program it during execution + * The input circuit defines the connectivity + */ + u8 program_input_circuit; + u8 func; +#define IMGU_ABI_STAGE_FUNC_RAW_COPY 0 +#define IMGU_ABI_STAGE_FUNC_BIN_COPY 1 +#define IMGU_ABI_STAGE_FUNC_ISYS_COPY 2 +#define IMGU_ABI_STAGE_FUNC_NO_FUNC 3 + u8 stage_type; /* The type of the pipe-stage */ +#define IMGU_ABI_STAGE_TYPE_SP 0 +#define IMGU_ABI_STAGE_TYPE_ISP 1 + u8 num_stripes; + u8 isp_pipe_version; + struct { + u8 vf_output; + u8 s3a; + u8 sdis; + u8 dvs_stats; + u8 lace_stats; + } enable; + + struct imgu_abi_crop_pos sp_out_crop_pos; + u8 padding[2]; + struct imgu_abi_frames_sp frames; + struct imgu_abi_resolution dvs_envelope; + struct imgu_abi_uds_info uds; + imgu_addr_t isp_stage_addr; + imgu_addr_t xmem_bin_addr; + imgu_addr_t xmem_map_addr; + + u16 top_cropping; + u16 row_stripes_height; + u16 row_stripes_overlap_lines; + u8 if_config_index; /* Which should be applied by this stage. */ + u8 padding2; +} __packed; + +/***** struct imgu_abi_isp_stage *****/ + +#define IMGU_ABI_MAX_BINARY_NAME 64 + +enum imgu_abi_memories { + IMGU_ABI_MEM_ISP_PMEM0 = 0, + IMGU_ABI_MEM_ISP_DMEM0, + IMGU_ABI_MEM_ISP_VMEM0, + IMGU_ABI_MEM_ISP_VAMEM0, + IMGU_ABI_MEM_ISP_VAMEM1, + IMGU_ABI_MEM_ISP_VAMEM2, + IMGU_ABI_MEM_ISP_HMEM0, + IMGU_ABI_MEM_SP0_DMEM0, + IMGU_ABI_MEM_SP1_DMEM0, + IMGU_ABI_MEM_DDR, + IMGU_ABI_NUM_MEMORIES +}; + +enum imgu_abi_param_class { + IMGU_ABI_PARAM_CLASS_PARAM, /* Late binding parameters, like 3A */ + IMGU_ABI_PARAM_CLASS_CONFIG, /* Pipe config time parameters */ + IMGU_ABI_PARAM_CLASS_STATE, /* State parameters, eg. buffer index */ + IMGU_ABI_PARAM_CLASS_NUM +}; + +struct imgu_abi_isp_param_memory_offsets { + u32 offsets[IMGU_ABI_PARAM_CLASS_NUM]; /* offset wrt hdr in bytes */ +} __packed; + +/* + * Blob descriptor. + * This structure describes an SP or ISP blob. + * It describes the test, data and bss sections as well as position in a + * firmware file. + * For convenience, it contains dynamic data after loading. + */ +struct imgu_abi_blob_info { + /* Static blob data */ + u32 offset; /* Blob offset in fw file */ + struct imgu_abi_isp_param_memory_offsets memory_offsets; + /* offset wrt hdr in bytes */ + u32 prog_name_offset; /* offset wrt hdr in bytes */ + u32 size; /* Size of blob */ + u32 padding_size; /* total cummulative of bytes added + * due to section alignment + */ + u32 icache_source; /* Position of icache in blob */ + u32 icache_size; /* Size of icache section */ + u32 icache_padding; /* added due to icache section alignment */ + u32 text_source; /* Position of text in blob */ + u32 text_size; /* Size of text section */ + u32 text_padding; /* bytes added due to text section alignment */ + u32 data_source; /* Position of data in blob */ + u32 data_target; /* Start of data in SP dmem */ + u32 data_size; /* Size of text section */ + u32 data_padding; /* bytes added due to data section alignment */ + u32 bss_target; /* Start position of bss in SP dmem */ + u32 bss_size; /* Size of bss section + * Dynamic data filled by loader + */ + const void *code __aligned(8); /* Code section absolute pointer */ + /* within fw, code = icache + text */ + const void *data __aligned(8); /* Data section absolute pointer */ + /* within fw, data = data + bss */ +} __packed; + +struct imgu_abi_binary_pipeline_info { + u32 mode; + u32 isp_pipe_version; + u32 pipelining; + u32 c_subsampling; + u32 top_cropping; + u32 left_cropping; + u32 variable_resolution; +} __packed; + +struct imgu_abi_binary_input_info { + u32 min_width; + u32 min_height; + u32 max_width; + u32 max_height; + u32 source; /* memory, sensor, variable */ +#define IMGU_ABI_BINARY_INPUT_SOURCE_SENSOR 0 +#define IMGU_ABI_BINARY_INPUT_SOURCE_MEMORY 1 +#define IMGU_ABI_BINARY_INPUT_SOURCE_VARIABLE 2 +} __packed; + +struct imgu_abi_binary_output_info { + u32 min_width; + u32 min_height; + u32 max_width; + u32 max_height; + u32 num_chunks; + u32 variable_format; +} __packed; + +struct imgu_abi_binary_internal_info { + u32 max_width; + u32 max_height; +} __packed; + +struct imgu_abi_binary_bds_info { + u32 supported_bds_factors; +/* + * enumeration of the bayer downscale factors. When a binary supports multiple + * factors, the OR of these defines is used to build the mask of supported + * factors. The BDS factor is used in pre-processor expressions so we cannot + * use an enum here. + */ +#define IMGU_ABI_BDS_FACTOR_1_00 BIT(0) +#define IMGU_ABI_BDS_FACTOR_1_25 BIT(1) +#define IMGU_ABI_BDS_FACTOR_1_50 BIT(2) +#define IMGU_ABI_BDS_FACTOR_2_00 BIT(3) +#define IMGU_ABI_BDS_FACTOR_2_25 BIT(4) +#define IMGU_ABI_BDS_FACTOR_2_50 BIT(5) +#define IMGU_ABI_BDS_FACTOR_3_00 BIT(6) +#define IMGU_ABI_BDS_FACTOR_4_00 BIT(7) +#define IMGU_ABI_BDS_FACTOR_4_50 BIT(8) +#define IMGU_ABI_BDS_FACTOR_5_00 BIT(9) +#define IMGU_ABI_BDS_FACTOR_6_00 BIT(10) +#define IMGU_ABI_BDS_FACTOR_8_00 BIT(11) +} __packed; + +struct imgu_abi_binary_dvs_info { + u32 max_envelope_width; + u32 max_envelope_height; +} __packed; + +struct imgu_abi_binary_vf_dec_info { + u32 is_variable; + u32 max_log_downscale; +} __packed; + +struct imgu_abi_binary_s3a_info { + u32 s3atbl_use_dmem; + u32 fixed_s3a_deci_log; +} __packed; + +struct imgu_abi_binary_dpc_info { + u32 bnr_lite; /* bnr lite enable flag */ +} __packed; + +struct imgu_abi_binary_iterator_info { + u32 num_stripes; + u32 row_stripes_height; + u32 row_stripes_overlap_lines; +} __packed; + +struct imgu_abi_binary_address_info { + u32 isp_addresses; /* Address in ISP dmem */ + u32 main_entry; /* Address of entry fct */ + u32 in_frame; /* Address in ISP dmem */ + u32 out_frame; /* Address in ISP dmem */ + u32 in_data; /* Address in ISP dmem */ + u32 out_data; /* Address in ISP dmem */ + u32 sh_dma_cmd_ptr; /* In ISP dmem */ +} __packed; + +struct imgu_abi_binary_uds_info { + u16 bpp; + u16 use_bci; + u16 use_str; + u16 woix; + u16 woiy; + u16 extra_out_vecs; + u16 vectors_per_line_in; + u16 vectors_per_line_out; + u16 vectors_c_per_line_in; + u16 vectors_c_per_line_out; + u16 vmem_gdc_in_block_height_y; + u16 vmem_gdc_in_block_height_c; +} __packed; + +struct imgu_abi_binary_block_info { + u32 block_width; + u32 block_height; + u32 output_block_height; +} __packed; + +struct imgu_abi_isp_data { + imgu_addr_t address; /* ISP address */ + u32 size; /* Disabled if 0 */ +} __packed; + +struct imgu_abi_isp_param_segments { + struct imgu_abi_isp_data + params[IMGU_ABI_PARAM_CLASS_NUM][IMGU_ABI_NUM_MEMORIES]; +} __packed; + +struct imgu_abi_binary_info { + u32 id __aligned(8); /* IMGU_ABI_BINARY_ID_* */ + struct imgu_abi_binary_pipeline_info pipeline; + struct imgu_abi_binary_input_info input; + struct imgu_abi_binary_output_info output; + struct imgu_abi_binary_internal_info internal; + struct imgu_abi_binary_bds_info bds; + struct imgu_abi_binary_dvs_info dvs; + struct imgu_abi_binary_vf_dec_info vf_dec; + struct imgu_abi_binary_s3a_info s3a; + struct imgu_abi_binary_dpc_info dpc_bnr; /* DPC related binary info */ + struct imgu_abi_binary_iterator_info iterator; + struct imgu_abi_binary_address_info addresses; + struct imgu_abi_binary_uds_info uds; + struct imgu_abi_binary_block_info block; + struct imgu_abi_isp_param_segments mem_initializers; + struct { + u8 input_feeder; + u8 output_system; + u8 obgrid; + u8 lin; + u8 dpc_acc; + u8 bds_acc; + u8 shd_acc; + u8 shd_ff; + u8 stats_3a_raw_buffer; + u8 acc_bayer_denoise; + u8 bnr_ff; + u8 awb_acc; + u8 awb_fr_acc; + u8 anr_acc; + u8 rgbpp_acc; + u8 rgbpp_ff; + u8 demosaic_acc; + u8 demosaic_ff; + u8 dvs_stats; + u8 lace_stats; + u8 yuvp1_b0_acc; + u8 yuvp1_c0_acc; + u8 yuvp2_acc; + u8 ae; + u8 af; + u8 dergb; + u8 rgb2yuv; + u8 high_quality; + u8 kerneltest; + u8 routing_shd_to_bnr; /* connect SHD with BNR ACCs*/ + u8 routing_bnr_to_anr; /* connect BNR with ANR ACCs*/ + u8 routing_anr_to_de; /* connect ANR with DE ACCs */ + u8 routing_rgb_to_yuvp1; /* connect RGB with YUVP1 ACCs*/ + u8 routing_yuvp1_to_yuvp2; /* connect YUVP1 with YUVP2 ACCs*/ + u8 luma_only; + u8 input_yuv; + u8 input_raw; + u8 reduced_pipe; + u8 vf_veceven; + u8 dis; + u8 dvs_envelope; + u8 uds; + u8 dvs_6axis; + u8 block_output; + u8 streaming_dma; + u8 ds; + u8 bayer_fir_6db; + u8 raw_binning; + u8 continuous; + u8 s3a; + u8 fpnr; + u8 sc; + u8 macc; + u8 output; + u8 ref_frame; + u8 tnr; + u8 xnr; + u8 params; + u8 ca_gdc; + u8 isp_addresses; + u8 in_frame; + u8 out_frame; + u8 high_speed; + u8 dpc; + u8 padding[2]; + u8 rgbir; + } enable; + struct { + /* DMA channel ID: [0,...,IMGU_NUM_DMA_CHANNELS> */ +#define IMGU_NUM_DMA_CHANNELS 19 + u8 ref_y_channel; + u8 ref_c_channel; + u8 tnr_channel; + u8 tnr_out_channel; + u8 dvs_coords_channel; + u8 output_channel; + u8 c_channel; + u8 vfout_channel; + u8 vfout_c_channel; + u8 vfdec_bits_per_pixel; + u8 claimed_by_isp; + u8 padding[2]; + } dma; +} __packed; + +struct imgu_abi_isp_stage { + struct imgu_abi_blob_info blob_info; + struct imgu_abi_binary_info binary_info; + char binary_name[IMGU_ABI_MAX_BINARY_NAME]; + struct imgu_abi_isp_param_segments mem_initializers; +} __packed; + +/***** struct imgu_abi_ddr_address_map and parameter set *****/ + +#define IMGU_ABI_ISP_DDR_WORD_BITS 256 +#define IMGU_ABI_ISP_DDR_WORD_BYTES (IMGU_ABI_ISP_DDR_WORD_BITS / 8) +#define IMGU_ABI_MAX_STAGES 3 + +/* xmem address map allocation */ +struct imgu_abi_ddr_address_map { + imgu_addr_t isp_mem_param[IMGU_ABI_MAX_STAGES][IMGU_ABI_NUM_MEMORIES]; + imgu_addr_t obgrid_tbl[IPU3_UAPI_MAX_STRIPES]; + imgu_addr_t acc_cluster_params_for_sp; + imgu_addr_t dvs_6axis_params_y; +} __packed; + +struct imgu_abi_parameter_set_info { + /* Pointers to Parameters in ISP format IMPT */ + struct imgu_abi_ddr_address_map mem_map; + /* Unique ID to track per-frame configurations */ + u32 isp_parameters_id; + /* Output frame to which this config has to be applied (optional) */ + imgu_addr_t output_frame_ptr; +} __packed; + +/***** struct imgu_abi_sp_group *****/ + +#define IMGU_ABI_MAX_IF_CONFIGS 3 + +/* SP configuration information */ +struct imgu_abi_sp_config { + u8 no_isp_sync; /* Signal host immediately after start */ + u8 enable_raw_pool_locking; /* Enable Raw Buffer Locking for HALv3 */ + u8 lock_all; + u8 disable_cont_vf; + u8 disable_preview_on_capture; + u8 padding[3]; +} __packed; + +/* Information for a pipeline */ +struct imgu_abi_sp_pipeline { + u32 pipe_id; /* the pipe ID */ + u32 pipe_num; /* the dynamic pipe number */ + u32 thread_id; /* the sp thread ID */ + u32 pipe_config; /* the pipe config */ +#define IMGU_ABI_PIPE_CONFIG_ACQUIRE_ISP (1 << 31) + u32 pipe_qos_config; /* Bitmap of multiple QOS extension fw + * state, 0xffffffff indicates non + * QOS pipe. + */ + u32 inout_port_config; +#define IMGU_ABI_PORT_CONFIG_TYPE_INPUT_HOST (1 << 0) +#define IMGU_ABI_PORT_CONFIG_TYPE_INPUT_COPYSINK (1 << 1) +#define IMGU_ABI_PORT_CONFIG_TYPE_INPUT_TAGGERSINK (1 << 2) +#define IMGU_ABI_PORT_CONFIG_TYPE_OUTPUT_HOST (1 << 4) +#define IMGU_ABI_PORT_CONFIG_TYPE_OUTPUT_COPYSINK (1 << 5) +#define IMGU_ABI_PORT_CONFIG_TYPE_OUTPUT_TAGGERSINK (1 << 6) + u32 required_bds_factor; + u32 dvs_frame_delay; + u32 num_stages; /* the pipe config */ + u32 running; /* needed for pipe termination */ + imgu_addr_t sp_stage_addr[IMGU_ABI_MAX_STAGES]; + imgu_addr_t scaler_pp_lut; /* Early bound LUT */ + u32 stage; /* stage ptr is only used on sp */ + s32 num_execs; /* number of times to run if this is + * an acceleration pipe. + */ + union { + struct { + u32 bytes_available; + } bin; + struct { + u32 height; + u32 width; + u32 padded_width; + u32 max_input_width; + u32 raw_bit_depth; + } raw; + } copy; + + /* Parameters passed to Shading Correction kernel. */ + struct { + /* Origin X (bqs) of internal frame on shading table */ + u32 internal_frame_origin_x_bqs_on_sctbl; + /* Origin Y (bqs) of internal frame on shading table */ + u32 internal_frame_origin_y_bqs_on_sctbl; + } shading; +} __packed; + +struct imgu_abi_sp_debug_command { + /* + * The DMA software-mask, + * Bit 31...24: unused. + * Bit 23...16: unused. + * Bit 15...08: reading-request enabling bits for DMA channel 7..0 + * Bit 07...00: writing-request enabling bits for DMA channel 7..0 + * + * For example, "0...0 0...0 11111011 11111101" indicates that the + * writing request through DMA Channel 1 and the reading request + * through DMA channel 2 are both disabled. The others are enabled. + */ + u32 dma_sw_reg; +} __packed; + +#define IMGU_ABI_MAX_SP_THREADS 4 + +/* + * Group all host initialized SP variables into this struct. + * This is initialized every stage through dma. + * The stage part itself is transferred through imgu_abi_sp_stage. + */ +struct imgu_abi_sp_group { + struct imgu_abi_sp_config config; + struct imgu_abi_sp_pipeline pipe[IMGU_ABI_MAX_SP_THREADS]; + struct imgu_abi_sp_debug_command debug; +} __packed; + +/***** parameter and state class binary configurations *****/ + +#define IMGU_ABI_FRAMES_REF 3 +#define IMGU_ABI_FRAMES_TNR 4 +#define IMGU_ABI_BUF_SETS_TNR 1 + +struct imgu_abi_isp_iterator_config { + struct imgu_abi_frame_sp_info input_info; + struct imgu_abi_frame_sp_info internal_info; + struct imgu_abi_frame_sp_info output_info; + struct imgu_abi_frame_sp_info vf_info; + struct imgu_abi_sp_resolution dvs_envelope; +} __packed; + +struct imgu_abi_dma_port_config { + u8 crop, elems; + u16 width; + u32 stride; +} __packed; + +struct imgu_abi_isp_ref_config { + u32 width_a_over_b; + struct imgu_abi_dma_port_config port_b; + u32 ref_frame_addr_y[IMGU_ABI_FRAMES_REF]; + u32 ref_frame_addr_c[IMGU_ABI_FRAMES_REF]; + u32 dvs_frame_delay; +} __packed; + +struct imgu_abi_isp_ref_dmem_state { + u32 ref_in_buf_idx; + u32 ref_out_buf_idx; +} __packed; + +struct imgu_abi_isp_dvs_config { + u32 num_horizontal_blocks; + u32 num_vertical_blocks; +} __packed; + +struct imgu_abi_isp_tnr3_config { + u32 width_a_over_b; + u32 frame_height; + struct imgu_abi_dma_port_config port_b; + u32 delay_frame; + u32 frame_addr[IMGU_ABI_FRAMES_TNR]; +} __packed; + +struct imgu_abi_isp_tnr3_dmem_state { + u32 in_bufidx; + u32 out_bufidx; + u32 total_frame_counter; + u32 buffer_frame_counter[IMGU_ABI_BUF_SETS_TNR]; + u32 bypass_filter; +} __packed; + +/***** DVS statistics metadata *****/ + +#define IMGU_ABI_DVS_METADATA_L0_REGS (84 * 10) +#define IMGU_ABI_DVS_METADATA_L1_REGS (66 * 10) +#define IMGU_ABI_DVS_METADATA_L2_REGS (45 * 10) + +struct imgu_abi_dvs_meta_data { + u32 dvs_prev_frame_fe_l0[IMGU_ABI_DVS_METADATA_L0_REGS] + __aligned(IMGU_ABI_ISP_DDR_WORD_BYTES); + u32 dvs_prev_frame_fe_l1[IMGU_ABI_DVS_METADATA_L1_REGS] + __aligned(IMGU_ABI_ISP_DDR_WORD_BYTES); + u32 dvs_prev_frame_fe_l2[IMGU_ABI_DVS_METADATA_L2_REGS] + __aligned(IMGU_ABI_ISP_DDR_WORD_BYTES); +} __packed; + +/***** Queues *****/ + +#define IMGU_ABI_EVENT_BUFFER_ENQUEUED(thread, queue) \ + (0 << 24 | (thread) << 16 | (queue) << 8) +#define IMGU_ABI_EVENT_BUFFER_DEQUEUED(queue) (1 << 24 | (queue) << 8) +#define IMGU_ABI_EVENT_EVENT_DEQUEUED (2 << 24) +#define IMGU_ABI_EVENT_START_STREAM (3 << 24) +#define IMGU_ABI_EVENT_STOP_STREAM (4 << 24) +#define IMGU_ABI_EVENT_MIPI_BUFFERS_READY (5 << 24) +#define IMGU_ABI_EVENT_UNLOCK_RAW_BUFFER (6 << 24) +#define IMGU_ABI_EVENT_STAGE_ENABLE_DISABLE (7 << 24) + +#define IMGU_ABI_HOST2SP_BUFQ_SIZE 3 +#define IMGU_ABI_SP2HOST_BUFQ_SIZE (2 * IMGU_ABI_MAX_SP_THREADS) +#define IMGU_ABI_HOST2SP_EVTQ_SIZE (IMGU_ABI_QUEUE_NUM * \ + IMGU_ABI_MAX_SP_THREADS * 2 + IMGU_ABI_MAX_SP_THREADS * 4) +#define IMGU_ABI_SP2HOST_EVTQ_SIZE (6 * IMGU_ABI_MAX_SP_THREADS) + +#define IMGU_ABI_EVTTYPE_EVENT_SHIFT 0 +#define IMGU_ABI_EVTTYPE_EVENT_MASK (0xff << IMGU_ABI_EVTTYPE_EVENT_SHIFT) +#define IMGU_ABI_EVTTYPE_PIPE_SHIFT 8 +#define IMGU_ABI_EVTTYPE_PIPE_MASK (0xff << IMGU_ABI_EVTTYPE_PIPE_SHIFT) +#define IMGU_ABI_EVTTYPE_PIPEID_SHIFT 16 +#define IMGU_ABI_EVTTYPE_PIPEID_MASK (0xff << IMGU_ABI_EVTTYPE_PIPEID_SHIFT) +#define IMGU_ABI_EVTTYPE_MODULEID_SHIFT 8 +#define IMGU_ABI_EVTTYPE_MODULEID_MASK (0xff << IMGU_ABI_EVTTYPE_MODULEID_SHIFT) +#define IMGU_ABI_EVTTYPE_LINENO_SHIFT 16 +#define IMGU_ABI_EVTTYPE_LINENO_MASK (0xffff << IMGU_ABI_EVTTYPE_LINENO_SHIFT) + +/* Output frame ready */ +#define IMGU_ABI_EVTTYPE_OUT_FRAME_DONE 0 +/* Second output frame ready */ +#define IMGU_ABI_EVTTYPE_2ND_OUT_FRAME_DONE 1 +/* Viewfinder Output frame ready */ +#define IMGU_ABI_EVTTYPE_VF_OUT_FRAME_DONE 2 +/* Second viewfinder Output frame ready */ +#define IMGU_ABI_EVTTYPE_2ND_VF_OUT_FRAME_DONE 3 +/* Indication that 3A statistics are available */ +#define IMGU_ABI_EVTTYPE_3A_STATS_DONE 4 +/* Indication that DIS statistics are available */ +#define IMGU_ABI_EVTTYPE_DIS_STATS_DONE 5 +/* Pipeline Done event, sent after last pipeline stage */ +#define IMGU_ABI_EVTTYPE_PIPELINE_DONE 6 +/* Frame tagged */ +#define IMGU_ABI_EVTTYPE_FRAME_TAGGED 7 +/* Input frame ready */ +#define IMGU_ABI_EVTTYPE_INPUT_FRAME_DONE 8 +/* Metadata ready */ +#define IMGU_ABI_EVTTYPE_METADATA_DONE 9 +/* Indication that LACE statistics are available */ +#define IMGU_ABI_EVTTYPE_LACE_STATS_DONE 10 +/* Extension stage executed */ +#define IMGU_ABI_EVTTYPE_ACC_STAGE_COMPLETE 11 +/* Timing measurement data */ +#define IMGU_ABI_EVTTYPE_TIMER 12 +/* End Of Frame event, sent when in buffered sensor mode */ +#define IMGU_ABI_EVTTYPE_PORT_EOF 13 +/* Performance warning encountered by FW */ +#define IMGU_ABI_EVTTYPE_FW_WARNING 14 +/* Assertion hit by FW */ +#define IMGU_ABI_EVTTYPE_FW_ASSERT 15 + +struct imgu_abi_queue_info { + u8 size; /* the maximum number of elements*/ + u8 step; /* number of bytes per element */ + u8 start; /* index of the oldest element */ + u8 end; /* index at which to write the new element */ +} __packed; + +struct imgu_abi_queues { + /* + * Queues for the dynamic frame information, + * i.e. the "in_frame" buffer, the "out_frame" + * buffer and the "vf_out_frame" buffer. + */ + struct imgu_abi_queue_info host2sp_bufq_info + [IMGU_ABI_MAX_SP_THREADS][IMGU_ABI_QUEUE_NUM]; + u32 host2sp_bufq[IMGU_ABI_MAX_SP_THREADS][IMGU_ABI_QUEUE_NUM] + [IMGU_ABI_HOST2SP_BUFQ_SIZE]; + struct imgu_abi_queue_info sp2host_bufq_info[IMGU_ABI_QUEUE_NUM]; + u32 sp2host_bufq[IMGU_ABI_QUEUE_NUM][IMGU_ABI_SP2HOST_BUFQ_SIZE]; + + /* + * The queues for the events. + */ + struct imgu_abi_queue_info host2sp_evtq_info; + u32 host2sp_evtq[IMGU_ABI_HOST2SP_EVTQ_SIZE]; + struct imgu_abi_queue_info sp2host_evtq_info; + u32 sp2host_evtq[IMGU_ABI_SP2HOST_EVTQ_SIZE]; +} __packed; + +/***** Buffer descriptor *****/ + +struct imgu_abi_metadata_info { + struct imgu_abi_resolution resolution; /* Resolution */ + u32 stride; /* Stride in bytes */ + u32 size; /* Total size in bytes */ +} __packed; + +struct imgu_abi_isp_3a_statistics { + union { + struct { + imgu_addr_t s3a_tbl; + } dmem; + struct { + imgu_addr_t s3a_tbl_hi; + imgu_addr_t s3a_tbl_lo; + } vmem; + } data; + struct { + imgu_addr_t rgby_tbl; + } data_hmem; + u32 exp_id; /* exposure id, to match statistics to a frame, */ + u32 isp_config_id; /* Tracks per-frame configs */ + imgu_addr_t data_ptr; /* pointer to base of all data */ + u32 size; /* total size of all data */ + u32 dmem_size; + u32 vmem_size; /* both lo and hi have this size */ + u32 hmem_size; +} __packed; + +struct imgu_abi_isp_dvs_statistics { + imgu_addr_t hor_proj; + imgu_addr_t ver_proj; + u32 hor_size; + u32 ver_size; + u32 exp_id; + imgu_addr_t data_ptr; /* base pointer containing all memory */ + u32 size; /* size of memory in data_ptr */ +} __packed; + +struct imgu_abi_metadata { + struct imgu_abi_metadata_info info; /* Layout info */ + imgu_addr_t address; /* CSS virtual address */ + u32 exp_id; /* Exposure ID */ +} __packed; + +struct imgu_abi_time_meas { + u32 start_timer_value; /* measured time in ticks */ + u32 end_timer_value; /* measured time in ticks */ +} __packed; + +struct imgu_abi_buffer { + union { + struct imgu_abi_isp_3a_statistics s3a; + struct imgu_abi_isp_dvs_statistics dis; + imgu_addr_t skc_dvs_statistics; + imgu_addr_t lace_stat; + struct imgu_abi_metadata metadata; + struct { + imgu_addr_t frame_data; + u32 flashed; + u32 exp_id; + u32 isp_parameters_id; /* Tracks per-frame configs */ + u32 padded_width; + } frame; + imgu_addr_t ddr_ptrs; + } payload; + /* + * kernel_ptr is present for host administration purposes only. + * type is uint64_t in order to be 64-bit host compatible. + * uint64_t does not exist on SP/ISP. + * Size of the struct is checked by sp.hive.c. + */ + u64 cookie_ptr __aligned(8); + u64 kernel_ptr; + struct imgu_abi_time_meas timing_data; + u32 isys_eof_clock_tick; +} __packed; + +#define IMGU_ABI_NUM_CONTINUOUS_FRAMES 10 +#define IMGU_ABI_SP_COMM_COMMAND 0x00 + +/* + * The host2sp_cmd_ready command is the only command written by the SP + * It acknowledges that is previous command has been received. + * (this does not mean that the command has been executed) + * It also indicates that a new command can be send (it is a queue + * with depth 1). + */ +#define IMGU_ABI_SP_COMM_COMMAND_READY 1 +/* Command written by the Host */ +#define IMGU_ABI_SP_COMM_COMMAND_DUMMY 2 /* No action */ +#define IMGU_ABI_SP_COMM_COMMAND_START_FLASH 3 /* Start the flash */ +#define IMGU_ABI_SP_COMM_COMMAND_TERMINATE 4 /* Terminate */ + +/* n = 0..IMGU_ABI_NUM_CONTINUOUS_FRAMES-1 */ +#define IMGU_ABI_SP_COMM_OFFLINE_FRAME(n) ((n) * 4 + 0x04) +#define IMGU_ABI_SP_COMM_OFFLINE_METADATA(n) ((n) * 4 + 0x2c) +#define IMGU_ABI_SP_COMM_CONT_AVAIL_RAW_FRAMES 0x54 +#define IMGU_ABI_SP_COMM_CONT_EXTRA_RAW_FRAMES 0x58 +#define IMGU_ABI_SP_COMM_CONT_TARGET_RAW_FRAMES 0x5c +/* n = 0..IPU3_CSS_PIPE_ID_NUM-1 */ +#define IMGU_ABI_SP_COMM_EVENT_IRQ_MASK(n) ((n) * 4 + 0x60) +#define IMGU_ABI_SP_COMM_EVENT_IRQ_MASK_OR_SHIFT 0 +#define IMGU_ABI_SP_COMM_EVENT_IRQ_MASK_AND_SHIFT 16 + +struct imgu_abi_bl_dma_cmd_entry { + u32 src_addr; /* virtual DDR address */ + u32 size; /* number of bytes to transferred */ + u32 dst_type; +#define IMGU_ABI_BL_DMACMD_TYPE_SP_PMEM 1 /* sp_pmem */ + u32 dst_addr; /* hmm address of xMEM or MMIO */ +} __packed; + +struct imgu_abi_sp_init_dmem_cfg { + u32 ddr_data_addr; /* data segment address in ddr */ + u32 dmem_data_addr; /* data segment address in dmem */ + u32 dmem_bss_addr; /* bss segment address in dmem */ + u32 data_size; /* data segment size */ + u32 bss_size; /* bss segment size */ + u32 sp_id; /* sp id */ +} __packed; + +/***** For parameter computation *****/ + +#define IMGU_SCALER_ELEMS_PER_VEC 0x10 +#define IMGU_SCALER_FILTER_TAPS_Y 0x4 +#define IMGU_SCALER_OUT_BPP 0x8 + +#define IMGU_HIVE_OF_SYS_SCALER_TO_FA_OFFSET 0xC +#define IMGU_HIVE_OF_SYS_OF_TO_FA_OFFSET 0x8 + +#define IMGU_SCALER_MS_TO_OUTFORMACC_SL_ADDR 0x400 +#define IMGU_SCALER_TO_OF_ACK_FA_ADDR \ + (0xC00 + IMGU_HIVE_OF_SYS_SCALER_TO_FA_OFFSET) +#define IMGU_OF_TO_ACK_FA_ADDR (0xC00 + IMGU_HIVE_OF_SYS_OF_TO_FA_OFFSET) +#define IMGU_OUTFORMACC_MS_TO_SCALER_SL_ADDR 0 +#define IMGU_OSYS_PHASES 0x20 +#define IMGU_OSYS_FILTER_TAPS 0x4 +#define IMGU_SCALER_INTR_BPP 10 + +#define IMGU_PS_SNR_PRESERVE_BITS 3 +#define IMGU_CNTX_BPP 11 +#define IMGU_SCALER_FILTER_TAPS_UV (IMGU_SCALER_FILTER_TAPS_Y/2) + +#define IMGU_VMEM2_ELEMS_PER_VEC (IMGU_SCALER_ELEMS_PER_VEC) +#define IMGU_STRIDE_Y (IMGU_SCALER_FILTER_TAPS_Y + 1) +#define IMGU_MAX_FRAME_WIDTH 3840 +#define IMGU_VMEM3_ELEMS_PER_VEC (IMGU_SCALER_ELEMS_PER_VEC) + +#define IMGU_VER_CNTX_WORDS DIV_ROUND_UP((IMGU_SCALER_OUT_BPP + \ + IMGU_PS_SNR_PRESERVE_BITS), IMGU_CNTX_BPP) /* 1 */ +#define IMGU_MAX_INPUT_BLOCK_HEIGHT 64 +#define IMGU_HOR_CNTX_WORDS DIV_ROUND_UP((IMGU_SCALER_INTR_BPP + \ + IMGU_PS_SNR_PRESERVE_BITS), IMGU_CNTX_BPP) /* 2 */ +#define IMGU_MAX_OUTPUT_BLOCK_WIDTH 128 +#define IMGU_CNTX_STRIDE_UV (IMGU_SCALER_FILTER_TAPS_UV + 1) + +#define IMGU_OSYS_PHASE_COUNTER_PREC_REF 6 +#define IMGU_VMEM1_Y_SIZE \ + (IMGU_OSYS_BLOCK_HEIGHT * IMGU_VMEM1_Y_STRIDE) +#define IMGU_VMEM1_UV_SIZE (IMGU_VMEM1_Y_SIZE / 4) +#define IMGU_VMEM1_OUT_BUF_ADDR (IMGU_VMEM1_INP_BUF_ADDR + \ + (IMGU_OSYS_NUM_INPUT_BUFFERS * IMGU_VMEM1_BUF_SIZE)) +#define IMGU_OSYS_NUM_OUTPUT_BUFFERS 2 + +/* transpose of input height */ +#define IMGU_VMEM2_VECS_PER_LINE \ + (DIV_ROUND_UP(IMGU_OSYS_BLOCK_HEIGHT, IMGU_VMEM2_ELEMS_PER_VEC)) +/* size in words (vectors) */ +#define IMGU_VMEM2_BUF_SIZE \ + (IMGU_VMEM2_VECS_PER_LINE * IMGU_VMEM2_LINES_PER_BLOCK) +#define IMGU_VMEM3_VER_Y_SIZE \ + ((IMGU_STRIDE_Y * IMGU_MAX_FRAME_WIDTH \ + / IMGU_VMEM3_ELEMS_PER_VEC) * IMGU_VER_CNTX_WORDS) +#define IMGU_VMEM3_HOR_Y_SIZE \ + ((IMGU_STRIDE_Y * IMGU_MAX_INPUT_BLOCK_HEIGHT \ + / IMGU_VMEM3_ELEMS_PER_VEC) * IMGU_HOR_CNTX_WORDS) +#define IMGU_VMEM3_VER_Y_EXTRA \ + ((IMGU_STRIDE_Y * IMGU_MAX_OUTPUT_BLOCK_WIDTH \ + / IMGU_VMEM3_ELEMS_PER_VEC) * IMGU_VER_CNTX_WORDS) +#define IMGU_VMEM3_VER_U_SIZE \ + (((IMGU_CNTX_STRIDE_UV * IMGU_MAX_FRAME_WIDTH \ + / IMGU_VMEM3_ELEMS_PER_VEC) * IMGU_VER_CNTX_WORDS) / 2) +#define IMGU_VMEM3_HOR_U_SIZE \ + (((IMGU_STRIDE_Y * IMGU_MAX_INPUT_BLOCK_HEIGHT \ + / IMGU_VMEM3_ELEMS_PER_VEC) * IMGU_HOR_CNTX_WORDS) / 2) +#define IMGU_VMEM3_VER_U_EXTRA \ + (((IMGU_CNTX_STRIDE_UV * IMGU_MAX_OUTPUT_BLOCK_WIDTH \ + / IMGU_VMEM3_ELEMS_PER_VEC) * IMGU_VER_CNTX_WORDS) / 2) +#define IMGU_VMEM3_VER_V_SIZE \ + (((IMGU_CNTX_STRIDE_UV * IMGU_MAX_FRAME_WIDTH \ + / IMGU_VMEM3_ELEMS_PER_VEC) * IMGU_VER_CNTX_WORDS) / 2) + +#define IMGU_OSYS_DMA_CROP_W_LIMIT 64 +#define IMGU_OSYS_DMA_CROP_H_LIMIT 4 + +#define IMGU_ISP_VEC_NELEMS 64 +#define IMGU_LUMA_TO_CHROMA_RATIO 2 +#define IMGU_OSYS_FIR_PHASES \ + (IMGU_OSYS_PHASES << IMGU_OSYS_PHASE_COUNTER_PREC_REF) +#define IMGU_OSYS_TAPS_UV (IMGU_OSYS_FILTER_TAPS / 2) +#define IMGU_INPUT_BLOCK_WIDTH (128) +#define IMGU_OSYS_TAPS_Y (IMGU_OSYS_FILTER_TAPS) +#define IMGU_FIFO_ADDR_SCALER_TO_FMT \ + (IMGU_SCALER_MS_TO_OUTFORMACC_SL_ADDR >> 2) +#define IMGU_FIFO_ADDR_SCALER_TO_SP (IMGU_SCALER_TO_OF_ACK_FA_ADDR >> 2) +#define IMGU_VMEM1_INP_BUF_ADDR 0 +#define IMGU_VMEM1_Y_STRIDE \ + (IMGU_OSYS_BLOCK_WIDTH / IMGU_VMEM1_ELEMS_PER_VEC) +#define IMGU_VMEM1_BUF_SIZE (IMGU_VMEM1_V_OFFSET + IMGU_VMEM1_UV_SIZE) + +#define IMGU_VMEM1_U_OFFSET (IMGU_VMEM1_Y_SIZE) +#define IMGU_VMEM1_V_OFFSET (IMGU_VMEM1_U_OFFSET + IMGU_VMEM1_UV_SIZE) +#define IMGU_VMEM1_UV_STRIDE (IMGU_VMEM1_Y_STRIDE / 2) +#define IMGU_OSYS_NUM_INPUT_BUFFERS 2 +#define IMGU_VMEM1_INT_BUF_ADDR (IMGU_VMEM1_OUT_BUF_ADDR + \ + (IMGU_OSYS_NUM_OUTPUT_BUFFERS * IMGU_VMEM1_BUF_SIZE)) + +#define IMGU_VMEM1_ELEMS_PER_VEC (IMGU_HIVE_OF_SYS_OF_SYSTEM_NWAYS) +#define IMGU_OSYS_NUM_INTERM_BUFFERS 2 +#define IMGU_VMEM2_BUF_Y_ADDR 0 +#define IMGU_VMEM2_BUF_Y_STRIDE (IMGU_VMEM2_VECS_PER_LINE) +#define IMGU_VMEM2_BUF_U_ADDR \ + (IMGU_VMEM2_BUF_Y_ADDR + IMGU_VMEM2_BUF_SIZE) +#define IMGU_VMEM2_BUF_V_ADDR \ + (IMGU_VMEM2_BUF_U_ADDR + IMGU_VMEM2_BUF_SIZE/4) +#define IMGU_VMEM2_BUF_UV_STRIDE (IMGU_VMEM2_VECS_PER_LINE/2) +/* 1.5 x depth of intermediate buffer */ +#define IMGU_VMEM2_LINES_PER_BLOCK 192 +#define IMGU_VMEM3_HOR_Y_ADDR \ + (IMGU_VMEM3_VER_Y_ADDR + IMGU_VMEM3_VER_Y_SIZE) +#define IMGU_VMEM3_HOR_U_ADDR \ + (IMGU_VMEM3_VER_U_ADDR + IMGU_VMEM3_VER_U_SIZE) +#define IMGU_VMEM3_HOR_V_ADDR \ + (IMGU_VMEM3_VER_V_ADDR + IMGU_VMEM3_VER_V_SIZE) +#define IMGU_VMEM3_VER_Y_ADDR 0 +#define IMGU_VMEM3_VER_U_ADDR \ + (IMGU_VMEM3_VER_Y_ADDR + IMGU_VMEM3_VER_Y_SIZE + \ + max(IMGU_VMEM3_HOR_Y_SIZE, IMGU_VMEM3_VER_Y_EXTRA)) +#define IMGU_VMEM3_VER_V_ADDR \ + (IMGU_VMEM3_VER_U_ADDR + IMGU_VMEM3_VER_U_SIZE + \ + max(IMGU_VMEM3_HOR_U_SIZE, IMGU_VMEM3_VER_U_EXTRA)) +#define IMGU_HIVE_OF_SYS_OF_SYSTEM_NWAYS 32 +#define IMGU_FIFO_ADDR_FMT_TO_SP (IMGU_OF_TO_ACK_FA_ADDR >> 2) +#define IMGU_FIFO_ADDR_FMT_TO_SCALER (IMGU_OUTFORMACC_MS_TO_SCALER_SL_ADDR >> 2) +#define IMGU_VMEM1_HST_BUF_ADDR (IMGU_VMEM1_INT_BUF_ADDR + \ + (IMGU_OSYS_NUM_INTERM_BUFFERS * IMGU_VMEM1_BUF_SIZE)) +#define IMGU_VMEM1_HST_BUF_STRIDE 120 +#define IMGU_VMEM1_HST_BUF_NLINES 3 + +#endif diff --git a/drivers/media/pci/intel/ipu3/ipu3-css-fw.c b/drivers/media/pci/intel/ipu3/ipu3-css-fw.c new file mode 100644 index 000000000000..a95ad225487b --- /dev/null +++ b/drivers/media/pci/intel/ipu3/ipu3-css-fw.c @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2017 Intel Corporation. + * + * 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. + */ + +#include +#include +#include + +#include "ipu3-css.h" +#include "ipu3-css-fw.h" + +static void ipu3_css_fw_show_binary(struct device *dev, + struct imgu_fw_info *bi, const char *name) +{ + int i; + + dev_dbg(dev, "found firmware binary type %i size %i name %s\n", + bi->type, bi->blob.size, name); + if (bi->type != IMGU_FW_ISP_FIRMWARE) + return; + + dev_dbg(dev, " id %i mode %i bds 0x%x veceven %i/%i out_pins %i\n", + bi->info.isp.sp.id, bi->info.isp.sp.pipeline.mode, + bi->info.isp.sp.bds.supported_bds_factors, + bi->info.isp.sp.enable.vf_veceven, + bi->info.isp.sp.vf_dec.is_variable, + bi->info.isp.num_output_pins); + + dev_dbg(dev, " input (%i,%i)-(%i,%i) formats %s%s%s\n", + bi->info.isp.sp.input.min_width, + bi->info.isp.sp.input.min_height, + bi->info.isp.sp.input.max_width, + bi->info.isp.sp.input.max_height, + bi->info.isp.sp.enable.input_yuv ? "yuv420 " : "", + bi->info.isp.sp.enable.input_feeder || + bi->info.isp.sp.enable.input_raw ? "raw8 raw10 " : "", + bi->info.isp.sp.enable.input_raw ? "raw12" : ""); + + dev_dbg(dev, " internal (%i,%i)\n", + bi->info.isp.sp.internal.max_width, + bi->info.isp.sp.internal.max_height); + + dev_dbg(dev, " output (%i,%i)-(%i,%i) formats", + bi->info.isp.sp.output.min_width, + bi->info.isp.sp.output.min_height, + bi->info.isp.sp.output.max_width, + bi->info.isp.sp.output.max_height); + for (i = 0; i < bi->info.isp.num_output_formats; i++) + dev_dbg(dev, " %i", bi->info.isp.output_formats[i]); + dev_dbg(dev, " vf"); + for (i = 0; i < bi->info.isp.num_vf_formats; i++) + dev_dbg(dev, " %i", bi->info.isp.vf_formats[i]); + dev_dbg(dev, "\n"); +} + +const int ipu3_css_fw_obgrid_size(const struct imgu_fw_info *bi) +{ + unsigned int stripes = bi->info.isp.sp.iterator.num_stripes; + unsigned int width, height, obgrid_size; + + width = ALIGN(DIV_ROUND_UP(bi->info.isp.sp.internal.max_width, + IMGU_OBGRID_TILE_SIZE * 2) + 1, IPU3_UAPI_ISP_VEC_ELEMS / 4); + height = DIV_ROUND_UP(bi->info.isp.sp.internal.max_height, + IMGU_OBGRID_TILE_SIZE * 2) + 1; + obgrid_size = PAGE_ALIGN(width * height * + sizeof(struct ipu3_uapi_obgrid_param)) * stripes; + + return obgrid_size; +} + +void *ipu3_css_fw_pipeline_params(struct ipu3_css *css, + enum imgu_abi_param_class c, enum imgu_abi_memories m, + struct imgu_fw_isp_parameter *par, size_t par_size, + void *binary_params) +{ + struct imgu_fw_info *bi = &css->fwp->binary_header[css->current_binary]; + + if (par->offset + par->size > + bi->info.isp.sp.mem_initializers.params[c][m].size) + return NULL; + + if (par->size != par_size) + pr_warn("parameter size doesn't match defined size\n"); + + if (par->size < par_size) + return NULL; + + return binary_params + par->offset; +} + +void ipu3_css_fw_cleanup(struct ipu3_css *css) +{ + if (css->binary) { + int i; + + for (i = 0; i < css->fwp->file_header.binary_nr; i++) + ipu3_css_dma_free(css->dev, &css->binary[i]); + kfree(css->binary); + } + if (css->fw) + release_firmware(css->fw); + + css->binary = NULL; + css->fw = NULL; +} + +int ipu3_css_fw_init(struct ipu3_css *css) +{ + static const u32 BLOCK_MAX = 65536; + struct device *dev = css->dev; + int binary_nr = 0; + int i, j, r; + + r = request_firmware(&css->fw, IMGU_FW_NAME, css->dev); + if (r) + return r; + + /* Check and display fw header info */ + + css->fwp = (struct imgu_fw_header *)css->fw->data; + if (css->fw->size < sizeof(struct imgu_fw_header *) || + css->fwp->file_header.h_size != sizeof(struct imgu_fw_bi_file_h)) + goto bad_fw; + if (sizeof(struct imgu_fw_bi_file_h) + + css->fwp->file_header.binary_nr * sizeof(struct imgu_fw_info) > + css->fw->size) + goto bad_fw; + + dev_info(dev, "loaded firmware version %.64s, %u binaries, %zu bytes\n", + css->fwp->file_header.version, css->fwp->file_header.binary_nr, + css->fw->size); + + /* Validate and display info on fw binaries */ + + binary_nr = css->fwp->file_header.binary_nr; + + css->fw_bl = css->fw_sp[0] = css->fw_sp[1] = -1; + for (i = 0; i < binary_nr; i++) { + struct imgu_fw_info *bi = &css->fwp->binary_header[i]; + const char *name = (void *)css->fwp + bi->blob.prog_name_offset; + size_t len; + + if (bi->blob.prog_name_offset >= css->fw->size) + goto bad_fw; + len = strnlen(name, css->fw->size - bi->blob.prog_name_offset); + if (len + 1 > css->fw->size - bi->blob.prog_name_offset || + len + 1 >= IMGU_ABI_MAX_BINARY_NAME) + goto bad_fw; + + if (bi->blob.size != bi->blob.text_size + bi->blob.icache_size + + bi->blob.data_size + bi->blob.padding_size) + goto bad_fw; + if (bi->blob.offset + bi->blob.size > css->fw->size) + goto bad_fw; + + if (bi->type == IMGU_FW_BOOTLOADER_FIRMWARE) { + css->fw_bl = i; + if (bi->info.bl.sw_state >= css->iomem_length || + bi->info.bl.num_dma_cmds >= css->iomem_length + || bi->info.bl.dma_cmd_list >= + css->iomem_length) + goto bad_fw; + } + if (bi->type == IMGU_FW_SP_FIRMWARE || + bi->type == IMGU_FW_SP1_FIRMWARE) { + css->fw_sp[bi->type == IMGU_FW_SP_FIRMWARE ? 0 : 1] = i; + if (bi->info.sp.per_frame_data >= css->iomem_length + || bi->info.sp.init_dmem_data >= + css->iomem_length + || bi->info.sp.host_sp_queue >= + css->iomem_length + || bi->info.sp.isp_started >= css->iomem_length + || bi->info.sp.sw_state >= css->iomem_length + || bi->info.sp.host_sp_queues_initialized >= + css->iomem_length + || bi->info.sp.sleep_mode >= css->iomem_length + || bi->info.sp.invalidate_tlb >= + css->iomem_length + || bi->info.sp.host_sp_com >= css->iomem_length + || bi->info.sp.output + 12 >= + css->iomem_length) + goto bad_fw; + } + if (bi->type != IMGU_FW_ISP_FIRMWARE) + continue; + + if (bi->info.isp.sp.pipeline.mode >= IPU3_CSS_PIPE_ID_NUM) + goto bad_fw; + + if (bi->info.isp.sp.iterator.num_stripes > + IPU3_UAPI_MAX_STRIPES) + goto bad_fw; + + if (bi->info.isp.num_output_formats > IMGU_ABI_FRAME_FORMAT_NUM + || bi->info.isp.num_vf_formats > IMGU_ABI_FRAME_FORMAT_NUM) + goto bad_fw; + + for (j = 0; j < bi->info.isp.num_output_formats; j++) + if (bi->info.isp.output_formats[j] < 0 || + bi->info.isp.output_formats[j] >= + IMGU_ABI_FRAME_FORMAT_NUM) + goto bad_fw; + for (j = 0; j < bi->info.isp.num_vf_formats; j++) + if (bi->info.isp.vf_formats[j] < 0 || + bi->info.isp.vf_formats[j] >= + IMGU_ABI_FRAME_FORMAT_NUM) + goto bad_fw; + + if (bi->info.isp.sp.block.block_width <= 0 || + bi->info.isp.sp.block.block_width > BLOCK_MAX || + bi->info.isp.sp.block.output_block_height <= 0 || + bi->info.isp.sp.block.output_block_height > BLOCK_MAX) + goto bad_fw; + + if (bi->blob.memory_offsets.offsets[IMGU_ABI_PARAM_CLASS_PARAM] + + sizeof(struct imgu_fw_param_memory_offsets) + > css->fw->size || + bi->blob.memory_offsets.offsets[IMGU_ABI_PARAM_CLASS_CONFIG] + + sizeof(struct imgu_fw_config_memory_offsets) + > css->fw->size || + bi->blob.memory_offsets.offsets[IMGU_ABI_PARAM_CLASS_STATE] + + sizeof(struct imgu_fw_state_memory_offsets) + > css->fw->size) + goto bad_fw; + + ipu3_css_fw_show_binary(dev, bi, name); + } + + if (css->fw_bl == -1 || css->fw_sp[0] == -1 || css->fw_sp[1] == -1) + goto bad_fw; + + /* Allocate and map fw binaries into IMGU */ + + css->binary = kcalloc(binary_nr, sizeof(*css->binary), GFP_KERNEL); + if (!css->binary) { + r = -ENOMEM; + goto error_out; + } + + for (i = 0; i < css->fwp->file_header.binary_nr; i++) { + struct imgu_fw_info *bi = &css->fwp->binary_header[i]; + void *blob = (void *)css->fwp + bi->blob.offset; + size_t size = bi->blob.size; + + if (ipu3_css_dma_alloc(css->dev, &css->binary[i], size)) { + r = -ENOMEM; + goto error_out; + } + memcpy(css->binary[i].vaddr, blob, size); + } + + return 0; + +bad_fw: + dev_err(dev, "invalid firmware binary, size %u\n", (int)css->fw->size); + r = -ENODEV; + +error_out: + ipu3_css_fw_cleanup(css); + return r; +} diff --git a/drivers/media/pci/intel/ipu3/ipu3-css-fw.h b/drivers/media/pci/intel/ipu3/ipu3-css-fw.h new file mode 100644 index 000000000000..9b7f6d3b12bd --- /dev/null +++ b/drivers/media/pci/intel/ipu3/ipu3-css-fw.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __IPU3_CSS_FW_H +#define __IPU3_CSS_FW_H + +/******************* Firmware file definitions *******************/ + +#define IMGU_FW_NAME "ipu3-fw.bin" + +typedef u32 imgu_fw_ptr; + +enum imgu_fw_type { + IMGU_FW_SP_FIRMWARE, /* Firmware for the SP */ + IMGU_FW_SP1_FIRMWARE, /* Firmware for the SP1 */ + IMGU_FW_ISP_FIRMWARE, /* Firmware for the ISP */ + IMGU_FW_BOOTLOADER_FIRMWARE, /* Firmware for the BootLoader */ + IMGU_FW_ACC_FIRMWARE /* Firmware for accelerations */ +}; + +enum imgu_fw_acc_type { + IMGU_FW_ACC_NONE, /* Normal binary */ + IMGU_FW_ACC_OUTPUT, /* Accelerator stage on output frame */ + IMGU_FW_ACC_VIEWFINDER, /* Accelerator stage on viewfinder frame */ + IMGU_FW_ACC_STANDALONE, /* Stand-alone acceleration */ +}; + +struct imgu_fw_isp_parameter { + u32 offset; /* Offset in isp_ config, params, etc. */ + u32 size; /* Disabled if 0 */ +}; + +struct imgu_fw_param_memory_offsets { + struct { + struct imgu_fw_isp_parameter lin; /* lin_vmem_params */ + struct imgu_fw_isp_parameter tnr3; /* tnr3_vmem_params */ + struct imgu_fw_isp_parameter xnr3; /* xnr3_vmem_params */ + } vmem; + struct { + struct imgu_fw_isp_parameter tnr; + struct imgu_fw_isp_parameter tnr3; /* tnr3_params */ + struct imgu_fw_isp_parameter xnr3; /* xnr3_params */ + struct imgu_fw_isp_parameter plane_io_config; /* 192 bytes */ + struct imgu_fw_isp_parameter rgbir; /* rgbir_params */ + } dmem; +}; + +struct imgu_fw_config_memory_offsets { + struct { + struct imgu_fw_isp_parameter iterator; + struct imgu_fw_isp_parameter dvs; + struct imgu_fw_isp_parameter output; + struct imgu_fw_isp_parameter raw; + struct imgu_fw_isp_parameter input_yuv; + struct imgu_fw_isp_parameter tnr; + struct imgu_fw_isp_parameter tnr3; + struct imgu_fw_isp_parameter ref; + } dmem; +}; + +struct imgu_fw_state_memory_offsets { + struct { + struct imgu_fw_isp_parameter tnr; + struct imgu_fw_isp_parameter tnr3; + struct imgu_fw_isp_parameter ref; + } dmem; +}; + +union imgu_fw_all_memory_offsets { + struct { + u64 imgu_fw_mem_offsets[3]; /* params, config, state */ + } offsets; + struct { + u64 ptr; + } array[IMGU_ABI_PARAM_CLASS_NUM]; +}; + +struct imgu_fw_binary_xinfo { + /* Part that is of interest to the SP. */ + struct imgu_abi_binary_info sp; + + /* Rest of the binary info, only interesting to the host. */ + enum imgu_fw_acc_type type; + + u32 num_output_formats __aligned(8); + enum imgu_abi_frame_format output_formats[IMGU_ABI_FRAME_FORMAT_NUM]; + + /* number of supported vf formats */ + u32 num_vf_formats __aligned(8); + /* types of supported vf formats */ + enum imgu_abi_frame_format vf_formats[IMGU_ABI_FRAME_FORMAT_NUM]; + u8 num_output_pins; + imgu_fw_ptr xmem_addr; + + u64 imgu_fw_blob_descr_ptr __aligned(8); + u32 blob_index __aligned(8); + union imgu_fw_all_memory_offsets mem_offsets __aligned(8); + struct imgu_fw_binary_xinfo *next __aligned(8); +}; + +struct imgu_fw_sp_info { + u32 init_dmem_data; /* data sect config, stored to dmem */ + u32 per_frame_data; /* Per frame data, stored to dmem */ + u32 group; /* Per pipeline data, loaded by dma */ + u32 output; /* SP output data, loaded by dmem */ + u32 host_sp_queue; /* Host <-> SP queues */ + u32 host_sp_com; /* Host <-> SP commands */ + u32 isp_started; /* P'ed from sensor thread, csim only */ + u32 sw_state; /* Polled from css */ +#define IMGU_ABI_SP_SWSTATE_TERMINATED 0 +#define IMGU_ABI_SP_SWSTATE_INITIALIZED 1 +#define IMGU_ABI_SP_SWSTATE_CONNECTED 2 +#define IMGU_ABI_SP_SWSTATE_RUNNING 3 + u32 host_sp_queues_initialized; /* Polled from the SP */ + u32 sleep_mode; /* different mode to halt SP */ + u32 invalidate_tlb; /* inform SP to invalidate mmu TLB */ + u32 debug_buffer_ddr_address; /* inform SP the addr of DDR debug + * queue + */ + /* input system perf count array */ + u32 perf_counter_input_system_error; + u32 threads_stack; /* sp thread's stack pointers */ + u32 threads_stack_size; /* sp thread's stack sizes */ + u32 curr_binary_id; /* current binary id */ + u32 raw_copy_line_count; /* raw copy line counter */ + u32 ddr_parameter_address; /* acc param ddrptr, sp dmem */ + u32 ddr_parameter_size; /* acc param size, sp dmem */ + /* Entry functions */ + u32 sp_entry; /* The SP entry function */ + u32 tagger_frames_addr; /* Base address of tagger state */ +}; + +struct imgu_fw_bl_info { + u32 num_dma_cmds; /* Number of cmds sent by CSS */ + u32 dma_cmd_list; /* Dma command list sent by CSS */ + u32 sw_state; /* Polled from css */ +#define IMGU_ABI_BL_SWSTATE_OK 0x100 +#define IMGU_ABI_BL_SWSTATE_BUSY (IMGU_ABI_BL_SWSTATE_OK + 1) +#define IMGU_ABI_BL_SWSTATE_ERR (IMGU_ABI_BL_SWSTATE_OK + 2) + /* Entry functions */ + u32 bl_entry; /* The SP entry function */ +}; + +struct imgu_fw_acc_info { + u32 per_frame_data; /* Dummy for now */ +}; + +union imgu_fw_union { + struct imgu_fw_binary_xinfo isp; /* ISP info */ + struct imgu_fw_sp_info sp; /* SP info */ + struct imgu_fw_sp_info sp1; /* SP1 info */ + struct imgu_fw_bl_info bl; /* Bootloader info */ + struct imgu_fw_acc_info acc; /* Accelerator info */ +}; + +struct imgu_fw_info { + size_t header_size; /* size of fw header */ + enum imgu_fw_type type __aligned(8); + union imgu_fw_union info; /* Binary info */ + struct imgu_abi_blob_info blob; /* Blob info */ + /* Dynamic part */ + u64 next; + + u32 loaded __aligned(8); /* Firmware has been loaded */ + const u64 isp_code __aligned(8); /* ISP pointer to code */ + /* Firmware handle between user space and kernel */ + u32 handle __aligned(8); + /* Sections to copy from/to ISP */ + struct imgu_abi_isp_param_segments mem_initializers; + /* Initializer for local ISP memories */ +}; + +struct imgu_fw_bi_file_h { + char version[64]; /* branch tag + week day + time */ + int binary_nr; /* Number of binaries */ + unsigned int h_size; /* sizeof(struct imgu_fw_bi_file_h) */ +}; + +struct imgu_fw_header { + struct imgu_fw_bi_file_h file_header; + struct imgu_fw_info binary_header[1]; /* binary_nr items */ +}; + +/******************* Firmware functions *******************/ + +int ipu3_css_fw_init(struct ipu3_css *css); +void ipu3_css_fw_cleanup(struct ipu3_css *css); + +const int ipu3_css_fw_obgrid_size(const struct imgu_fw_info *bi); +void *ipu3_css_fw_pipeline_params(struct ipu3_css *css, + enum imgu_abi_param_class c, + enum imgu_abi_memories m, + struct imgu_fw_isp_parameter *par, + size_t par_size, void *binary_params); +#endif diff --git a/drivers/media/pci/intel/ipu3/ipu3-css.h b/drivers/media/pci/intel/ipu3/ipu3-css.h new file mode 100644 index 000000000000..79dbf0625740 --- /dev/null +++ b/drivers/media/pci/intel/ipu3/ipu3-css.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __IPU3_CSS_H +#define __IPU3_CSS_H + +#include "ipu3-abi.h" +#include "ipu3-css-pool.h" + +/* 2 stages for split isp pipeline, 1 for scaling */ +#define IMGU_NUM_SP 2 +#define IMGU_MAX_PIPELINE_NUM 20 + +/* + * The pipe id type, distinguishes the kind of pipes that + * can be run in parallel. + */ +enum ipu3_css_pipe_id { + IPU3_CSS_PIPE_ID_PREVIEW, + IPU3_CSS_PIPE_ID_COPY, + IPU3_CSS_PIPE_ID_VIDEO, + IPU3_CSS_PIPE_ID_CAPTURE, + IPU3_CSS_PIPE_ID_YUVPP, + IPU3_CSS_PIPE_ID_ACC, + IPU3_CSS_PIPE_ID_NUM +}; + +/* IPU3 Camera Sub System structure */ +struct ipu3_css { + struct device *dev; + void __iomem *base; + struct device *dma_dev; + const struct firmware *fw; + struct imgu_fw_header *fwp; + int iomem_length; + int fw_bl, fw_sp[IMGU_NUM_SP]; /* Indices of bl and SP binaries */ + struct ipu3_css_map *binary; /* fw binaries mapped to device */ + int current_binary; /* Currently selected binary or -1 */ + bool streaming; /* true when streaming is enabled */ + long frame; /* Latest frame not yet processed */ + enum ipu3_css_pipe_id pipe_id; /* CSS pipe ID. */ +}; + +#endif