Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755201Ab1CABLo (ORCPT ); Mon, 28 Feb 2011 20:11:44 -0500 Received: from wolverine02.qualcomm.com ([199.106.114.251]:4838 "EHLO wolverine02.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754051Ab1CABLm (ORCPT ); Mon, 28 Feb 2011 20:11:42 -0500 X-IronPort-AV: E=McAfee;i="5400,1158,6271"; a="77024111" From: Kenneth Heitke To: davidb@codeaurora.org, bryanh@codeaurora.org, dwalker@fifo99.com Cc: linux-arm-msm@vger.kernel.org, linux-arm-kernel@lists.intradead.org, yanhe@codeaurora.org, palnatim@codeaurora.org, subhashj@codeaurora.org, Amir Samuelovi , Kenneth Heitke , linux-arm-kernel@lists.infradead.org (open list:ARM PORT), linux-kernel@vger.kernel.org (open list) Subject: [RFC PATCH 1/5] RFC: msm: sps: Bus Access Manager (BAM) Hardware driver Date: Mon, 28 Feb 2011 18:11:28 -0700 Message-Id: <1298941892-25173-2-git-send-email-kheitke@codeaurora.org> X-Mailer: git-send-email 1.7.3.3 In-Reply-To: <1298941892-25173-1-git-send-email-kheitke@codeaurora.org> References: <1298941892-25173-1-git-send-email-kheitke@codeaurora.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 27807 Lines: 1006 From: Amir Samuelovi A primary component of the Smart Peripheral Subsytem (SPS) is the Bus Access Manager (BAM). The BAM serves as a DMA engine for a peripheral core. A BAM can provide multiple DMA channels, referred to as "pipes", which can perform DMA between other BAM pipes or to system memory under control of a host CPU. The BAM driver handles the following: - BAM and endpoint hardware configuration - BAM interrupt routing and dispatching Signed-off-by: Amir Samuelov Signed-off-by: Kenneth Heitke --- arch/arm/mach-msm/sps/bam.c | 588 +++++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-msm/sps/bam.h | 375 +++++++++++++++++++++++++++ 2 files changed, 963 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-msm/sps/bam.c create mode 100644 arch/arm/mach-msm/sps/bam.h diff --git a/arch/arm/mach-msm/sps/bam.c b/arch/arm/mach-msm/sps/bam.c new file mode 100644 index 0000000..be6b038 --- /dev/null +++ b/arch/arm/mach-msm/sps/bam.c @@ -0,0 +1,588 @@ +/* Copyright (c) 2011, Code Aurora Forum. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + */ + +/* Bus-Access-Manager (BAM) Hardware manager. */ + +#include /* u32 */ +#include /* pr_info() */ +#include /* ioread32() */ +#include /* find_first_bit() */ +#include /* ENODEV */ + +#include "bam.h" + +/** + * Valid BAM Hardware version. + * + */ +#define BAM_MIN_VERSION 2 +#define BAM_MAX_VERSION 2 + +/** + * BAM Hardware registers. + * + */ +#define CTRL (0xf80) +#define REVISION (0xf84) +#define NUM_PIPES (0xfbc) +#define DESC_CNT_TRSHLD (0xf88) +#define IRQ_SRCS (0xf8c) +#define IRQ_SRCS_MSK (0xf90) +#define IRQ_SRCS_UNMASKED (0xfb0) +#define IRQ_STTS (0xf94) +#define IRQ_CLR (0xf98) +#define IRQ_EN (0xf9c) +#define IRQ_SIC_SEL (0xfa0) +#define AHB_MASTER_ERR_CTRLS (0xfa4) +#define AHB_MASTER_ERR_ADDR (0xfa8) +#define AHB_MASTER_ERR_DATA (0xfac) +#define IRQ_DEST (0xfb4) +#define PERIPH_IRQ_DEST (0xfb8) +#define TEST_BUS_REG (0xff8) +#define CNFG_BITS (0xffc) + +#define P_CTRL(n) (0x0000 + 128 * (n)) +#define P_RST(n) (0x0004 + 128 * (n)) +#define P_HALT(n) (0x0008 + 128 * (n)) +#define P_IRQ_STTS(n) (0x0010 + 128 * (n)) +#define P_IRQ_CLR(n) (0x0014 + 128 * (n)) +#define P_IRQ_EN(n) (0x0018 + 128 * (n)) +#define P_TIMER(n) (0x001c + 128 * (n)) +#define P_TIMER_CTRL(n) (0x0020 + 128 * (n)) +#define P_EVNT_DEST_ADDR(n) (0x102c + 64 * (n)) +#define P_EVNT_REG(n) (0x1018 + 64 * (n)) +#define P_SW_OFSTS(n) (0x1000 + 64 * (n)) +#define P_DATA_FIFO_ADDR(n) (0x1024 + 64 * (n)) +#define P_DESC_FIFO_ADDR(n) (0x101c + 64 * (n)) +#define P_EVNT_GEN_TRSHLD(n) (0x1028 + 64 * (n)) +#define P_FIFO_SIZES(n) (0x1020 + 64 * (n)) +#define P_IRQ_DEST_ADDR(n) (0x103c + 64 * (n)) +#define P_RETR_CNTXT(n) (0x1034 + 64 * (n)) +#define P_SI_CNTXT(n) (0x1038 + 64 * (n)) +#define P_AU_PSM_CNTXT_1(n) (0x1004 + 64 * (n)) +#define P_PSM_CNTXT_2(n) (0x1008 + 64 * (n)) +#define P_PSM_CNTXT_3(n) (0x100c + 64 * (n)) +#define P_PSM_CNTXT_4(n) (0x1010 + 64 * (n)) +#define P_PSM_CNTXT_5(n) (0x1014 + 64 * (n)) + +/** + * BAM Hardware registers bitmask. + * format: _ + * + */ +/* CTRL */ +#define BAM_CACHED_DESC_STORE 0x8000 +#define BAM_DESC_CACHE_SEL 0x6000 +#define BAM_PERIPH_IRQ_SIC_SEL 0x1000 +#define BAM_TESTBUS_SEL 0xfe0 +#define BAM_EN_ACCUM 0x10 +#define BAM_EN 0x2 +#define BAM_SW_RST 0x1 + +/* IRQ_SRCS */ +#define BAM_IRQ 0x80000000 +#define P_IRQ 0x7fffffff + +#define IRQ_STTS_BAM_ERROR_IRQ 0x4 +#define IRQ_STTS_BAM_HRESP_ERR_IRQ 0x2 +#define IRQ_CLR_BAM_ERROR_CLR 0x4 +#define IRQ_CLR_BAM_HRESP_ERR_CLR 0x2 +#define IRQ_EN_BAM_ERROR_EN 0x4 +#define IRQ_EN_BAM_HRESP_ERR_EN 0x2 +#define IRQ_SIC_SEL_BAM_IRQ_SIC_SEL 0x80000000 +#define IRQ_SIC_SEL_P_IRQ_SIC_SEL 0x7fffffff +#define AHB_MASTER_ERR_CTRLS_BAM_ERR_DIRECT_MODE 0x10000 +#define AHB_MASTER_ERR_CTRLS_BAM_ERR_HCID 0xf000 +#define AHB_MASTER_ERR_CTRLS_BAM_ERR_HPROT 0xf00 +#define AHB_MASTER_ERR_CTRLS_BAM_ERR_HBURST 0xe0 +#define AHB_MASTER_ERR_CTRLS_BAM_ERR_HSIZE 0x18 +#define AHB_MASTER_ERR_CTRLS_BAM_ERR_HWRITE 0x4 +#define AHB_MASTER_ERR_CTRLS_BAM_ERR_HTRANS 0x3 +#define CNFG_BITS_BAM_FULL_PIPE 0x800 +#define CNFG_BITS_BAM_PIPE_CNFG 0x4 + +/* P_ctrln */ +#define P_SYS_MODE 0x20 +#define P_SYS_STRM 0x10 +#define P_DIRECTION 0x8 +#define P_EN 0x2 + +#define P_RST_P_SW_RST 0x1 + +#define P_HALT_P_PROD_HALTED 0x2 +#define P_HALT_P_HALT 0x1 + +#define P_IRQ_STTS_P_TRNSFR_END_IRQ 0x20 +#define P_IRQ_STTS_P_ERR_IRQ 0x10 +#define P_IRQ_STTS_P_OUT_OF_DESC_IRQ 0x8 +#define P_IRQ_STTS_P_WAKE_IRQ 0x4 +#define P_IRQ_STTS_P_TIMER_IRQ 0x2 +#define P_IRQ_STTS_P_PRCSD_DESC_IRQ 0x1 + +#define P_IRQ_CLR_P_TRNSFR_END_CLR 0x20 +#define P_IRQ_CLR_P_ERR_CLR 0x10 +#define P_IRQ_CLR_P_OUT_OF_DESC_CLR 0x8 +#define P_IRQ_CLR_P_WAKE_CLR 0x4 +#define P_IRQ_CLR_P_TIMER_CLR 0x2 +#define P_IRQ_CLR_P_PRCSD_DESC_CLR 0x1 + +#define P_IRQ_EN_P_TRNSFR_END_EN 0x20 +#define P_IRQ_EN_P_ERR_EN 0x10 +#define P_IRQ_EN_P_OUT_OF_DESC_EN 0x8 +#define P_IRQ_EN_P_WAKE_EN 0x4 +#define P_IRQ_EN_P_TIMER_EN 0x2 +#define P_IRQ_EN_P_PRCSD_DESC_EN 0x1 + +#define P_TIMER_P_TIMER 0xffff + +/* P_TIMER_ctrln */ +#define P_TIMER_RST 0x80000000 +#define P_TIMER_RUN 0x40000000 +#define P_TIMER_MODE 0x20000000 +#define P_TIMER_TRSHLD 0xffff + +/* P_EVNT_regn */ +#define P_BYTES_CONSUMED 0xffff0000 +#define P_DESC_FIFO_PEER_OFST 0xffff + +/* P_SW_ofstsn */ +#define SW_OFST_IN_DESC 0xffff0000 +#define SW_DESC_OFST 0xffff + +#define P_EVNT_GEN_TRSHLD_P_TRSHLD 0xffff + +/* P_FIFO_sizesn */ +#define P_DATA_FIFO_SIZE 0xffff0000 +#define P_DESC_FIFO_SIZE 0xffff + +#define P_RETR_CNTXT_RETR_DESC_OFST 0xffff0000 +#define P_RETR_CNTXT_RETR_OFST_IN_DESC 0xffff +#define P_SI_CNTXT_SI_DESC_OFST 0xffff +#define P_AU_PSM_CNTXT_1_AU_PSM_ACCUMED 0xffff0000 +#define P_AU_PSM_CNTXT_1_AU_ACKED 0xffff +#define P_PSM_CNTXT_2_PSM_DESC_VALID 0x80000000 +#define P_PSM_CNTXT_2_PSM_DESC_IRQ 0x40000000 +#define P_PSM_CNTXT_2_PSM_DESC_IRQ_DONE 0x20000000 +#define P_PSM_CNTXT_2_PSM_GENERAL_BITS 0x1e000000 +#define P_PSM_CNTXT_2_PSM_CONS_STATE 0x1c00000 +#define P_PSM_CNTXT_2_PSM_PROD_SYS_STATE 0x380000 +#define P_PSM_CNTXT_2_PSM_PROD_B2B_STATE 0x70000 +#define P_PSM_CNTXT_2_PSM_DESC_SIZE 0xffff +#define P_PSM_CNTXT_4_PSM_DESC_OFST 0xffff0000 +#define P_PSM_CNTXT_4_PSM_SAVED_ACCUMED_SIZE 0xffff +#define P_PSM_CNTXT_5_PSM_BLOCK_BYTE_CNT 0xffff0000 +#define P_PSM_CNTXT_5_PSM_OFST_IN_DESC 0xffff + +#define BAM_ERROR (-1) + +/** + * + * Read register with debug info. + * + * @base - bam base virtual address. + * @offset - register offset. + * + * @return u32 + */ +static inline u32 bam_read_reg(void *base, u32 offset) +{ + u32 val = ioread32(base + offset); + pr_debug("bam: read reg 0x%x r_val 0x%x.\n", offset, val); + return val; +} + +/** + * Read register masked field with debug info. + * + * @base - bam base virtual address. + * @offset - register offset. + * @mask - register bitmask. + * + * @return u32 + */ +static inline u32 bam_read_reg_field(void *base, u32 offset, const u32 mask) +{ + u32 shift = find_first_bit((void *)&mask, 32); + u32 val = ioread32(base + offset); + val &= mask; /* clear other bits */ + val >>= shift; + pr_debug("bam: read reg 0x%x mask 0x%x r_val 0x%x.\n", + offset, mask, val); + return val; +} + +/** + * + * Write register with debug info. + * + * @base - bam base virtual address. + * @offset - register offset. + * @val - value to write. + * + */ +static inline void bam_write_reg(void *base, u32 offset, u32 val) +{ + iowrite32(val, base + offset); + pr_debug("bam: write reg 0x%x w_val 0x%x.\n", offset, val); +} + +/** + * Write register masked field with debug info. + * + * @base - bam base virtual address. + * @offset - register offset. + * @mask - register bitmask. + * @val - value to write. + * + */ +static inline void bam_write_reg_field(void *base, u32 offset, + const u32 mask, u32 val) +{ + u32 shift = find_first_bit((void *)&mask, 32); + u32 tmp = ioread32(base + offset); + + tmp &= ~mask; /* clear written bits */ + val = tmp | (val << shift); + iowrite32(val, base + offset); + pr_debug("bam: write reg 0x%x w_val 0x%x.\n", offset, val); +} + +/** + * Initialize a BAM device + * + */ +int bam_init(void *base, u32 ee, + u16 summing_threshold, + u32 irq_mask, u32 *version, u32 *num_pipes) +{ + /* disable bit#11 because of HW bug */ + u32 cfg_bits = 0xffffffff & ~(1 << 11); + u32 ver = 0; + + ver = bam_read_reg(base, REVISION); + + if ((ver < BAM_MIN_VERSION) || (ver > BAM_MAX_VERSION)) { + pr_err("bam:Invalid BAM version 0x%x.\n", ver); + return -ENODEV; + } + + if (summing_threshold == 0) { + summing_threshold = 4; + pr_err("bam:summing_threshold is zero , use default 4.\n"); + } + + bam_write_reg_field(base, CTRL, BAM_SW_RST, 1); + /* No delay needed */ + bam_write_reg_field(base, CTRL, BAM_SW_RST, 0); + + bam_write_reg_field(base, CTRL, BAM_EN, 1); + + bam_write_reg(base, DESC_CNT_TRSHLD, summing_threshold); + + bam_write_reg(base, CNFG_BITS, cfg_bits); + + /* + * Enable Global BAM Interrupt - for error reasons , + * filter with mask. + * Note: Pipes interrupts are disabled until BAM_P_IRQ_enn is set + */ + bam_write_reg_field(base, IRQ_SRCS_MSK, BAM_IRQ, 1); + + bam_write_reg(base, IRQ_EN, irq_mask); + + *num_pipes = bam_read_reg(base, NUM_PIPES); + *version = ver; + + return 0; +} + +/** + * Verify that a BAM device is enabled and gathers the hardware + * configuration. + * + */ +int bam_check(void *base, u32 *version, u32 *num_pipes) +{ + u32 ver = 0; + + if (!bam_read_reg_field(base, CTRL, BAM_EN)) + return -ENODEV; + + ver = bam_read_reg(base, REVISION); + + /* + * Discover the hardware version number and the number of pipes + * supported by this BAM + */ + *num_pipes = bam_read_reg(base, NUM_PIPES); + *version = ver; + + /* Check BAM version */ + if ((ver < BAM_MIN_VERSION) || (ver > BAM_MAX_VERSION)) { + pr_err("bam:Invalid BAM version 0x%x.\n", ver); + return -ENODEV; + } + + return 0; +} + +/** + * Disable a BAM device + * + */ +void bam_exit(void *base, u32 ee) +{ + bam_write_reg_field(base, IRQ_SRCS_MSK, BAM_IRQ, 0); + + bam_write_reg(base, IRQ_EN, 0); + + /* Disable the BAM */ + bam_write_reg_field(base, CTRL, BAM_EN, 0); +} + +/** + * Get and Clear BAM global IRQ status + * + * note: clear status only for pipes controlled by this + * processor + */ +u32 bam_get_and_clear_irq_status(void *base, u32 ee, u32 mask) +{ + u32 status = bam_read_reg(base, IRQ_SRCS); + u32 clr = status &= mask; + + bam_write_reg(base, IRQ_CLR, clr); + + return status; +} + +/** + * Initialize a BAM pipe + */ +int bam_pipe_init(void *base, u32 pipe, struct bam_pipe_parameters *param) +{ + /* Reset the BAM pipe */ + bam_write_reg(base, P_RST(pipe), 1); + /* No delay needed */ + bam_write_reg(base, P_RST(pipe), 0); + + /* Enable the Pipe Interrupt at the BAM level */ + bam_write_reg_field(base, IRQ_SRCS_MSK, (1 << pipe), 1); + + bam_write_reg(base, P_IRQ_EN(pipe), param->pipe_irq_mask); + + bam_write_reg_field(base, P_CTRL(pipe), P_DIRECTION, param->dir); + bam_write_reg_field(base, P_CTRL(pipe), P_SYS_MODE, param->mode); + + bam_write_reg(base, P_EVNT_GEN_TRSHLD(pipe), param->event_threshold); + + bam_write_reg(base, P_DESC_FIFO_ADDR(pipe), param->desc_base); + bam_write_reg_field(base, P_FIFO_SIZES(pipe), P_DESC_FIFO_SIZE, + param->desc_size); + + bam_write_reg_field(base, P_CTRL(pipe), P_SYS_STRM, + param->stream_mode); + + if (param->mode == BAM_PIPE_MODE_BAM2BAM) { + u32 peer_dest_addr = param->peer_phys_addr + + P_EVNT_REG(param->peer_pipe); + + bam_write_reg(base, P_DATA_FIFO_ADDR(pipe), + param->data_base); + bam_write_reg_field(base, P_FIFO_SIZES(pipe), + P_DATA_FIFO_SIZE, param->data_size); + + bam_write_reg(base, P_EVNT_DEST_ADDR(pipe), peer_dest_addr); + + pr_debug("bam:Bam=0x%x.Pipe=%d.peer_bam=0x%x.peer_pipe=%d.\n", + (u32) base, pipe, + (u32) param->peer_phys_addr, + param->peer_pipe); + } + + /* Pipe Enable - at last */ + bam_write_reg_field(base, P_CTRL(pipe), P_EN, 1); + + return 0; +} + +/** + * Reset the BAM pipe + * + */ +void bam_pipe_exit(void *base, u32 pipe, u32 ee) +{ + bam_write_reg(base, P_IRQ_EN(pipe), 0); + + /* Disable the Pipe Interrupt at the BAM level */ + bam_write_reg_field(base, IRQ_SRCS_MSK, (1 << pipe), 0); + + /* Pipe Disable */ + bam_write_reg_field(base, P_CTRL(pipe), P_EN, 0); +} + +/** + * Enable a BAM pipe + * + */ +void bam_pipe_enable(void *base, u32 pipe) +{ + bam_write_reg_field(base, P_CTRL(pipe), P_EN, 1); +} + +/** + * Diasble a BAM pipe + * + */ +void bam_pipe_disable(void *base, u32 pipe) +{ + bam_write_reg_field(base, P_CTRL(pipe), P_EN, 0); +} + +/** + * Check if a BAM pipe is enabled. + * + */ +int bam_pipe_is_enabled(void *base, u32 pipe) +{ + return bam_read_reg_field(base, P_CTRL(pipe), P_EN); +} + +/** + * Configure interrupt for a BAM pipe + * + */ +void bam_pipe_set_irq(void *base, u32 pipe, enum bam_enable irq_en, + u32 src_mask, u32 ee) +{ + bam_write_reg(base, P_IRQ_EN(pipe), src_mask); + bam_write_reg_field(base, IRQ_SRCS_MSK, (1 << pipe), irq_en); +} + +/** + * Configure a BAM pipe for satellite MTI use + * + */ +void bam_pipe_satellite_mti(void *base, u32 pipe, u32 irq_gen_addr, u32 ee) +{ + bam_write_reg(base, P_IRQ_EN(pipe), 0); + bam_write_reg(base, P_IRQ_DEST_ADDR(pipe), irq_gen_addr); + + bam_write_reg_field(base, IRQ_SIC_SEL, (1 << pipe), 1); + bam_write_reg_field(base, IRQ_SRCS_MSK, (1 << pipe), 1); +} + +/** + * Configure MTI for a BAM pipe + * + */ +void bam_pipe_set_mti(void *base, u32 pipe, enum bam_enable irq_en, + u32 src_mask, u32 irq_gen_addr) +{ + /* + * MTI use is only supported on BAMs when global config is controlled + * by a remote processor. + * Consequently, the global configuration register to enable SIC (MTI) + * support cannot be accessed. + * The remote processor must be relied upon to enable the SIC and the + * interrupt. Since the remote processor enable both SIC and interrupt, + * the interrupt enable mask must be set to zero for polling mode. + */ + + bam_write_reg(base, P_IRQ_DEST_ADDR(pipe), irq_gen_addr); + + if (!irq_en) + src_mask = 0; + + bam_write_reg(base, P_IRQ_EN(pipe), src_mask); +} + +/** + * Get and Clear BAM pipe IRQ status + * + */ +u32 bam_pipe_get_and_clear_irq_status(void *base, u32 pipe) +{ + u32 status = 0; + + status = bam_read_reg(base, P_IRQ_STTS(pipe)); + bam_write_reg(base, P_IRQ_CLR(pipe), status); + + return status; +} + +/** + * Set write offset for a BAM pipe + * + */ +void bam_pipe_set_desc_write_offset(void *base, u32 pipe, u32 next_write) +{ + /* + * It is not necessary to perform a read-modify-write masking to write + * the P_DESC_FIFO_PEER_OFST value, since the other field in the + * register (P_BYTES_CONSUMED) is read-only. + */ + bam_write_reg_field(base, P_EVNT_REG(pipe), P_DESC_FIFO_PEER_OFST, + next_write); +} + +/** + * Get write offset for a BAM pipe + * + */ +u32 bam_pipe_get_desc_write_offset(void *base, u32 pipe) +{ + return bam_read_reg_field(base, P_EVNT_REG(pipe), + P_DESC_FIFO_PEER_OFST); +} + +/** + * Get read offset for a BAM pipe + * + */ +u32 bam_pipe_get_desc_read_offset(void *base, u32 pipe) +{ + return bam_read_reg_field(base, P_SW_OFSTS(pipe), SW_DESC_OFST); +} + +/** + * Configure inactivity timer count for a BAM pipe + * + */ +void bam_pipe_timer_config(void *base, u32 pipe, enum bam_pipe_timer_mode mode, + u32 timeout_count) +{ + bam_write_reg_field(base, P_TIMER_CTRL(pipe), P_TIMER_MODE, mode); + bam_write_reg_field(base, P_TIMER_CTRL(pipe), P_TIMER_TRSHLD, + timeout_count); +} + +/** + * Reset inactivity timer for a BAM pipe + * + */ +void bam_pipe_timer_reset(void *base, u32 pipe) +{ + /* reset */ + bam_write_reg_field(base, P_TIMER_CTRL(pipe), P_TIMER_RST, 0); + /* active */ + bam_write_reg_field(base, P_TIMER_CTRL(pipe), P_TIMER_RST, 1); +} + +/** + * Get inactivity timer count for a BAM pipe + * + */ +u32 bam_pipe_timer_get_count(void *base, u32 pipe) +{ + return bam_read_reg(base, P_TIMER(pipe)); +} diff --git a/arch/arm/mach-msm/sps/bam.h b/arch/arm/mach-msm/sps/bam.h new file mode 100644 index 0000000..5681f96 --- /dev/null +++ b/arch/arm/mach-msm/sps/bam.h @@ -0,0 +1,375 @@ +/* Copyright (c) 2011, Code Aurora Forum. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + */ + +/* Bus-Access-Manager (BAM) Hardware manager functions API. */ + +#ifndef _BAM_H_ +#define _BAM_H_ + +#include /* u32 */ +#include /* ioread32() */ +#include /* find_first_bit() */ + +/* Pipe mode */ +enum bam_pipe_mode { + BAM_PIPE_MODE_BAM2BAM = 0, /* BAM to BAM */ + BAM_PIPE_MODE_SYSTEM = 1, /* BAM to/from System Memory */ +}; + +/* Pipe direction */ +enum bam_pipe_dir { + /* The Pipe Reads data from data-fifo or system-memory */ + BAM_PIPE_CONSUMER = 0, + /* The Pipe Writes data to data-fifo or system-memory */ + BAM_PIPE_PRODUCER = 1, +}; + +/* Stream mode Type */ +enum bam_stream_mode { + BAM_STREAM_MODE_DISABLE = 0, + BAM_STREAM_MODE_ENABLE = 1, +}; + +/* Enable Type */ +enum bam_enable { + BAM_DISABLE = 0, + BAM_ENABLE = 1, +}; + +/* Pipe timer mode */ +enum bam_pipe_timer_mode { + BAM_PIPE_TIMER_ONESHOT = 0, + BAM_PIPE_TIMER_PERIODIC = 1, +}; + +struct transfer_descriptor { + u32 addr; /* Buffer physical address */ + u32 size:16; /* Buffer size in bytes */ + u32 flags:16; /* Flag bitmask (see SPS_IOVEC_FLAG_ #defines) */ +} __packed; + +/* BAM pipe initialization parameters */ +struct bam_pipe_parameters { + u16 event_threshold; + u32 pipe_irq_mask; + enum bam_pipe_dir dir; + enum bam_pipe_mode mode; + u32 desc_base; /* Physical address of descriptor FIFO */ + u32 desc_size; /* Size (bytes) of descriptor FIFO */ + enum bam_stream_mode stream_mode; + u32 ee; /* BAM execution environment index */ + + /* The following are only valid if mode is BAM2BAM */ + u32 peer_phys_addr; + u32 peer_pipe; + u32 data_base; /* Physical address of data FIFO */ + u32 data_size; /* Size (bytes) of data FIFO */ +}; + +/** + * Initialize a BAM device + * + * This function initializes a BAM device. + * + * @base - BAM virtual base address. + * + * @ee - BAM execution environment index + * + * @summing_threshold - summing threshold (global for all pipes) + * + * @irq_mask - error interrupts mask + * + * @version - return BAM hardware version + * + * @num_pipes - return number of pipes + * + * @return 0 on success, negative value on error + * + */ +int bam_init(void *base, + u32 ee, + u16 summing_threshold, + u32 irq_mask, u32 *version, u32 *num_pipes); + +/** + * Check a BAM device + * + * This function verifies that a BAM device is enabled and gathers + * the hardware configuration. + * + * @base - BAM virtual base address. + * + * @version - return BAM hardware version + * + * @num_pipes - return number of pipes + * + * @return 0 on success, negative value on error + * + */ +int bam_check(void *base, u32 *version, u32 *num_pipes); + +/** + * Disable a BAM device + * + * This function disables a BAM device. + * + * @base - BAM virtual base address. + * + * @ee - BAM execution environment index + * + */ +void bam_exit(void *base, u32 ee); + +/** + * Get and Clear BAM global IRQ status + * + * This function gets and clears BAM global IRQ status. + * + * @base - BAM virtual base address. + * + * @ee - BAM execution environment index + * + * @mask - active pipes mask. + * + * @return IRQ status + * + */ +u32 bam_get_and_clear_irq_status(void *base, u32 ee, u32 mask); + +/** + * Initialize a BAM pipe + * + * This function initializes a BAM pipe. + * + * @base - BAM virtual base address. + * + * @pipe - pipe index + * + * @param - bam pipe parameters. + * + * @return 0 on success, negative value on error + * + */ +int bam_pipe_init(void *base, u32 pipe, struct bam_pipe_parameters *param); + +/** + * Reset the BAM pipe + * + * This function resets the BAM pipe. + * + * @base - BAM virtual base address. + * + * @pipe - pipe index + * + * @ee - BAM execution environment index + * + */ +void bam_pipe_exit(void *base, u32 pipe, u32 ee); + +/** + * Enable a BAM pipe + * + * This function enables a BAM pipe. + * + * @base - BAM virtual base address. + * + * @pipe - pipe index + * + */ +void bam_pipe_enable(void *base, u32 pipe); + +/** + * Disable a BAM pipe + * + * This function disables a BAM pipe. + * + * @base - BAM virtual base address. + * + * @pipe - pipe index + * + */ +void bam_pipe_disable(void *base, u32 pipe); + +/** + * Get a BAM pipe enable state + * + * This function determines if a BAM pipe is enabled. + * + * @base - BAM virtual base address. + * + * @pipe - pipe index + * + * @return true if enabled, false if disabled + * + */ +int bam_pipe_is_enabled(void *base, u32 pipe); + +/** + * Configure interrupt for a BAM pipe + * + * This function configures the interrupt for a BAM pipe. + * + * @base - BAM virtual base address. + * + * @pipe - pipe index + * + * @irq_en - enable or disable interrupt + * + * @src_mask - interrupt source mask, set regardless of whether + * interrupt is disabled + * + * @ee - BAM execution environment index + * + */ +void bam_pipe_set_irq(void *base, u32 pipe, enum bam_enable irq_en, + u32 src_mask, u32 ee); + +/** + * Configure a BAM pipe for satellite MTI use + * + * This function configures a BAM pipe for satellite MTI use. + * + * @base - BAM virtual base address. + * + * @pipe - pipe index + * + * @irq_gen_addr - physical address written to generate MTI + * + * @ee - BAM execution environment index + * + */ +void bam_pipe_satellite_mti(void *base, u32 pipe, u32 irq_gen_addr, u32 ee); + +/** + * Configure MTI for a BAM pipe + * + * This function configures the interrupt for a BAM pipe. + * + * @base - BAM virtual base address. + * + * @pipe - pipe index + * + * @irq_en - enable or disable interrupt + * + * @src_mask - interrupt source mask, set regardless of whether + * interrupt is disabled + * + * @irq_gen_addr - physical address written to generate MTI + * + */ +void bam_pipe_set_mti(void *base, u32 pipe, enum bam_enable irq_en, + u32 src_mask, u32 irq_gen_addr); + +/** + * Get and Clear BAM pipe IRQ status + * + * This function gets and clears BAM pipe IRQ status. + * + * @base - BAM virtual base address. + * + * @pipe - pipe index + * + * @return IRQ status + * + */ +u32 bam_pipe_get_and_clear_irq_status(void *base, u32 pipe); + +/** + * Set write offset for a BAM pipe + * + * This function sets the write offset for a BAM pipe. This is + * the offset that is maintained by software in system mode. + * + * @base - BAM virtual base address. + * + * @pipe - pipe index + * + * @next_write - descriptor FIFO write offset + * + */ +void bam_pipe_set_desc_write_offset(void *base, u32 pipe, u32 next_write); + +/** + * Get write offset for a BAM pipe + * + * This function gets the write offset for a BAM pipe. This is + * the offset that is maintained by the pipe's peer pipe or by software. + * + * @base - BAM virtual base address. + * + * @pipe - pipe index + * + * @return descriptor FIFO write offset + * + */ +u32 bam_pipe_get_desc_write_offset(void *base, u32 pipe); + +/** + * Get read offset for a BAM pipe + * + * This function gets the read offset for a BAM pipe. This is + * the offset that is maintained by the pipe in system mode. + * + * @base - BAM virtual base address. + * + * @pipe - pipe index + * + * @return descriptor FIFO read offset + * + */ +u32 bam_pipe_get_desc_read_offset(void *base, u32 pipe); + +/** + * Configure inactivity timer count for a BAM pipe + * + * This function configures the inactivity timer count for a BAM pipe. + * + * @base - BAM virtual base address. + * + * @pipe - pipe index + * + * @mode - timer operating mode + * + * @timeout_count - timeout count + * + */ +void bam_pipe_timer_config(void *base, u32 pipe, + enum bam_pipe_timer_mode mode, + u32 timeout_count); + +/** + * Reset inactivity timer for a BAM pipe + * + * This function resets the inactivity timer count for a BAM pipe. + * + * @base - BAM virtual base address. + * + * @pipe - pipe index + * + */ +void bam_pipe_timer_reset(void *base, u32 pipe); + +/** + * Get inactivity timer count for a BAM pipe + * + * This function gets the inactivity timer count for a BAM pipe. + * + * @base - BAM virtual base address. + * + * @pipe - pipe index + * + * @return inactivity timer count + * + */ +u32 bam_pipe_timer_get_count(void *base, u32 pipe); + +#endif /* _BAM_H_ */ -- 1.7.3.3 Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/