aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/crystalhd/crystalhd_hw.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/crystalhd/crystalhd_hw.h')
-rw-r--r--drivers/staging/crystalhd/crystalhd_hw.h398
1 files changed, 398 insertions, 0 deletions
diff --git a/drivers/staging/crystalhd/crystalhd_hw.h b/drivers/staging/crystalhd/crystalhd_hw.h
new file mode 100644
index 000000000000..1c6318e912ac
--- /dev/null
+++ b/drivers/staging/crystalhd/crystalhd_hw.h
@@ -0,0 +1,398 @@
+/***************************************************************************
+ * Copyright (c) 2005-2009, Broadcom Corporation.
+ *
+ * Name: crystalhd_hw . h
+ *
+ * Description:
+ * BCM70012 Linux driver hardware layer.
+ *
+ * HISTORY:
+ *
+ **********************************************************************
+ * This file is part of the crystalhd device driver.
+ *
+ * This driver is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ *
+ * This driver 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this driver. If not, see <http://www.gnu.org/licenses/>.
+ **********************************************************************/
+
+#ifndef _CRYSTALHD_HW_H_
+#define _CRYSTALHD_HW_H_
+
+#include "crystalhd_misc.h"
+#include "crystalhd_fw_if.h"
+
+/* HW constants..*/
+#define DMA_ENGINE_CNT 2
+#define MAX_PIB_Q_DEPTH 64
+#define MIN_PIB_Q_DEPTH 2
+#define WR_POINTER_OFF 4
+
+#define ASPM_L1_ENABLE (BC_BIT(27))
+
+/*************************************************
+ 7412 Decoder Registers.
+**************************************************/
+#define FW_CMD_BUFF_SZ 64
+#define TS_Host2CpuSnd 0x00000100
+#define Hst2CpuMbx1 0x00100F00
+#define Cpu2HstMbx1 0x00100F04
+#define MbxStat1 0x00100F08
+#define Stream2Host_Intr_Sts 0x00100F24
+#define C011_RET_SUCCESS 0x0 /* Reutrn status of firmware command. */
+
+/* TS input status register */
+#define TS_StreamAFIFOStatus 0x0010044C
+#define TS_StreamBFIFOStatus 0x0010084C
+
+/*UART Selection definitions*/
+#define UartSelectA 0x00100300
+#define UartSelectB 0x00100304
+
+#define BSVS_UART_DEC_NONE 0x00
+#define BSVS_UART_DEC_OUTER 0x01
+#define BSVS_UART_DEC_INNER 0x02
+#define BSVS_UART_STREAM 0x03
+
+/* Code-In fifo */
+#define REG_DecCA_RegCinCTL 0xa00
+#define REG_DecCA_RegCinBase 0xa0c
+#define REG_DecCA_RegCinEnd 0xa10
+#define REG_DecCA_RegCinWrPtr 0xa04
+#define REG_DecCA_RegCinRdPtr 0xa08
+
+#define REG_Dec_TsUser0Base 0x100864
+#define REG_Dec_TsUser0Rdptr 0x100868
+#define REG_Dec_TsUser0Wrptr 0x10086C
+#define REG_Dec_TsUser0End 0x100874
+
+/* ASF Case ...*/
+#define REG_Dec_TsAudCDB2Base 0x10036c
+#define REG_Dec_TsAudCDB2Rdptr 0x100378
+#define REG_Dec_TsAudCDB2Wrptr 0x100374
+#define REG_Dec_TsAudCDB2End 0x100370
+
+/* DRAM bringup Registers */
+#define SDRAM_PARAM 0x00040804
+#define SDRAM_PRECHARGE 0x000408B0
+#define SDRAM_EXT_MODE 0x000408A4
+#define SDRAM_MODE 0x000408A0
+#define SDRAM_REFRESH 0x00040890
+#define SDRAM_REF_PARAM 0x00040808
+
+#define DecHt_PllACtl 0x34000C
+#define DecHt_PllBCtl 0x340010
+#define DecHt_PllCCtl 0x340014
+#define DecHt_PllDCtl 0x340034
+#define DecHt_PllECtl 0x340038
+#define AUD_DSP_MISC_SOFT_RESET 0x00240104
+#define AIO_MISC_PLL_RESET 0x0026000C
+#define PCIE_CLK_REQ_REG 0xDC
+#define PCI_CLK_REQ_ENABLE (BC_BIT(8))
+
+/*************************************************
+ F/W Copy engine definitions..
+**************************************************/
+#define BC_FWIMG_ST_ADDR 0x00000000
+/* FIXME: jarod: there's a kernel function that'll do this for us... */
+#define rotr32_1(x, n) (((x) >> n) | ((x) << (32 - n)))
+#define bswap_32_1(x) ((rotr32_1((x), 24) & 0x00ff00ff) | (rotr32_1((x), 8) & 0xff00ff00))
+
+#define DecHt_HostSwReset 0x340000
+#define BC_DRAM_FW_CFG_ADDR 0x001c2000
+
+typedef union _addr_64_ {
+ struct {
+ uint32_t low_part;
+ uint32_t high_part;
+ };
+
+ uint64_t full_addr;
+
+} addr_64;
+
+typedef union _intr_mask_reg_ {
+ struct {
+ uint32_t mask_tx_done:1;
+ uint32_t mask_tx_err:1;
+ uint32_t mask_rx_done:1;
+ uint32_t mask_rx_err:1;
+ uint32_t mask_pcie_err:1;
+ uint32_t mask_pcie_rbusmast_err:1;
+ uint32_t mask_pcie_rgr_bridge:1;
+ uint32_t reserved:25;
+ };
+
+ uint32_t whole_reg;
+
+} intr_mask_reg;
+
+typedef union _link_misc_perst_deco_ctrl_ {
+ struct {
+ uint32_t bcm7412_rst:1; /* 1 -> BCM7412 is held in reset. Reset value 1.*/
+ uint32_t reserved0:3; /* Reserved.No Effect*/
+ uint32_t stop_bcm_7412_clk:1; /* 1 ->Stops branch of 27MHz clk used to clk BCM7412*/
+ uint32_t reserved1:27; /* Reseved. No Effect*/
+ };
+
+ uint32_t whole_reg;
+
+} link_misc_perst_deco_ctrl;
+
+typedef union _link_misc_perst_clk_ctrl_ {
+ struct {
+ uint32_t sel_alt_clk:1; /* When set, selects a 6.75MHz clock as the source of core_clk */
+ uint32_t stop_core_clk:1; /* When set, stops the branch of core_clk that is not needed for low power operation */
+ uint32_t pll_pwr_dn:1; /* When set, powers down the main PLL. The alternate clock bit should be set
+ to select an alternate clock before setting this bit.*/
+ uint32_t reserved0:5; /* Reserved */
+ uint32_t pll_mult:8; /* This setting controls the multiplier for the PLL. */
+ uint32_t pll_div:4; /* This setting controls the divider for the PLL. */
+ uint32_t reserved1:12; /* Reserved */
+ };
+
+ uint32_t whole_reg;
+
+} link_misc_perst_clk_ctrl;
+
+
+typedef union _link_misc_perst_decoder_ctrl_ {
+ struct {
+ uint32_t bcm_7412_rst:1; /* 1 -> BCM7412 is held in reset. Reset value 1.*/
+ uint32_t res0:3; /* Reserved.No Effect*/
+ uint32_t stop_7412_clk:1; /* 1 ->Stops branch of 27MHz clk used to clk BCM7412*/
+ uint32_t res1:27; /* Reseved. No Effect */
+ };
+
+ uint32_t whole_reg;
+
+} link_misc_perst_decoder_ctrl;
+
+
+typedef union _desc_low_addr_reg_ {
+ struct {
+ uint32_t list_valid:1;
+ uint32_t reserved:4;
+ uint32_t low_addr:27;
+ };
+
+ uint32_t whole_reg;
+
+} desc_low_addr_reg;
+
+typedef struct _dma_descriptor_ { /* 8 32-bit values */
+ /* 0th u32 */
+ uint32_t sdram_buff_addr:28; /* bits 0-27: SDRAM Address */
+ uint32_t res0:4; /* bits 28-31: Reserved */
+
+ /* 1st u32 */
+ uint32_t buff_addr_low; /* 1 buffer address low */
+ uint32_t buff_addr_high; /* 2 buffer address high */
+
+ /* 3rd u32 */
+ uint32_t res2:2; /* 0-1 - Reserved */
+ uint32_t xfer_size:23; /* 2-24 = Xfer size in words */
+ uint32_t res3:6; /* 25-30 reserved */
+ uint32_t intr_enable:1; /* 31 - Interrupt After this desc */
+
+ /* 4th u32 */
+ uint32_t endian_xlat_align:2; /* 0-1 Endian Translation */
+ uint32_t next_desc_cont:1; /* 2 - Next desc is in contig memory */
+ uint32_t res4:25; /* 3 - 27 Reserved bits */
+ uint32_t fill_bytes:2; /* 28-29 Bits Fill Bytes */
+ uint32_t dma_dir:1; /* 30 bit DMA Direction */
+ uint32_t last_rec_indicator:1; /* 31 bit Last Record Indicator */
+
+ /* 5th u32 */
+ uint32_t next_desc_addr_low; /* 32-bits Next Desc Addr lower */
+
+ /* 6th u32 */
+ uint32_t next_desc_addr_high; /* 32-bits Next Desc Addr Higher */
+
+ /* 7th u32 */
+ uint32_t res8; /* Last 32bits reserved */
+
+} dma_descriptor, *pdma_descriptor;
+
+/*
+ * We will allocate the memory in 4K pages
+ * the linked list will be a list of 32 byte descriptors.
+ * The virtual address will determine what should be freed.
+ */
+typedef struct _dma_desc_mem_ {
+ pdma_descriptor pdma_desc_start; /* 32-bytes for dma descriptor. should be first element */
+ dma_addr_t phy_addr; /* physical address of each DMA desc */
+ uint32_t sz;
+ struct _dma_desc_mem_ *Next; /* points to Next Descriptor in chain */
+
+} dma_desc_mem, *pdma_desc_mem;
+
+
+
+typedef enum _list_sts_ {
+ sts_free = 0,
+
+ /* RX-Y Bits 0:7 */
+ rx_waiting_y_intr = 0x00000001,
+ rx_y_error = 0x00000004,
+
+ /* RX-UV Bits 8:16 */
+ rx_waiting_uv_intr = 0x0000100,
+ rx_uv_error = 0x0000400,
+
+ rx_sts_waiting = (rx_waiting_y_intr|rx_waiting_uv_intr),
+ rx_sts_error = (rx_y_error|rx_uv_error),
+
+ rx_y_mask = 0x000000FF,
+ rx_uv_mask = 0x0000FF00,
+
+} list_sts;
+
+typedef struct _tx_dma_pkt_ {
+ dma_desc_mem desc_mem;
+ hw_comp_callback call_back;
+ crystalhd_dio_req *dio_req;
+ wait_queue_head_t *cb_event;
+ uint32_t list_tag;
+
+} tx_dma_pkt;
+
+typedef struct _crystalhd_rx_dma_pkt {
+ dma_desc_mem desc_mem;
+ crystalhd_dio_req *dio_req;
+ uint32_t pkt_tag;
+ uint32_t flags;
+ BC_PIC_INFO_BLOCK pib;
+ dma_addr_t uv_phy_addr;
+ struct _crystalhd_rx_dma_pkt *next;
+
+} crystalhd_rx_dma_pkt;
+
+struct crystalhd_hw_stats{
+ uint32_t rx_errors;
+ uint32_t tx_errors;
+ uint32_t freeq_count;
+ uint32_t rdyq_count;
+ uint32_t num_interrupts;
+ uint32_t dev_interrupts;
+ uint32_t cin_busy;
+ uint32_t pause_cnt;
+};
+
+struct crystalhd_hw {
+ tx_dma_pkt tx_pkt_pool[DMA_ENGINE_CNT];
+ spinlock_t lock;
+
+ uint32_t tx_ioq_tag_seed;
+ uint32_t tx_list_post_index;
+
+ crystalhd_rx_dma_pkt *rx_pkt_pool_head;
+ uint32_t rx_pkt_tag_seed;
+
+ bool dev_started;
+ void *adp;
+
+ wait_queue_head_t *pfw_cmd_event;
+ int fwcmd_evt_sts;
+
+ uint32_t pib_del_Q_addr;
+ uint32_t pib_rel_Q_addr;
+
+ crystalhd_dioq_t *tx_freeq;
+ crystalhd_dioq_t *tx_actq;
+
+ /* Rx DMA Engine Specific Locks */
+ spinlock_t rx_lock;
+ uint32_t rx_list_post_index;
+ list_sts rx_list_sts[DMA_ENGINE_CNT];
+ crystalhd_dioq_t *rx_rdyq;
+ crystalhd_dioq_t *rx_freeq;
+ crystalhd_dioq_t *rx_actq;
+ uint32_t stop_pending;
+
+ /* HW counters.. */
+ struct crystalhd_hw_stats stats;
+
+ /* Core clock in MHz */
+ uint32_t core_clock_mhz;
+ uint32_t prev_n;
+ uint32_t pwr_lock;
+};
+
+/* Clock defines for power control */
+#define CLOCK_PRESET 175
+
+/* DMA engine register BIT mask wrappers.. */
+#define DMA_START_BIT MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_MASK
+
+#define GET_RX_INTR_MASK (INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_MASK | \
+ INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_MASK | \
+ INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_MASK | \
+ INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_MASK | \
+ INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_MASK | \
+ INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_MASK | \
+ INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_MASK | \
+ INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_MASK)
+
+#define GET_Y0_ERR_MSK (MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK | \
+ MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK | \
+ MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK | \
+ MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK)
+
+#define GET_UV0_ERR_MSK (MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK | \
+ MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK | \
+ MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK | \
+ MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK)
+
+#define GET_Y1_ERR_MSK (MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK | \
+ MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK | \
+ MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK | \
+ MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK)
+
+#define GET_UV1_ERR_MSK (MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK | \
+ MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK | \
+ MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK | \
+ MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK)
+
+
+/**** API Exposed to the other layers ****/
+BC_STATUS crystalhd_download_fw(struct crystalhd_adp *adp,
+ void *buffer, uint32_t sz);
+BC_STATUS crystalhd_do_fw_cmd(struct crystalhd_hw *hw, BC_FW_CMD *fw_cmd);
+bool crystalhd_hw_interrupt(struct crystalhd_adp *adp, struct crystalhd_hw *hw);
+BC_STATUS crystalhd_hw_open(struct crystalhd_hw *, struct crystalhd_adp *);
+BC_STATUS crystalhd_hw_close(struct crystalhd_hw *);
+BC_STATUS crystalhd_hw_setup_dma_rings(struct crystalhd_hw *);
+BC_STATUS crystalhd_hw_free_dma_rings(struct crystalhd_hw *);
+
+
+BC_STATUS crystalhd_hw_post_tx(struct crystalhd_hw *hw, crystalhd_dio_req *ioreq,
+ hw_comp_callback call_back,
+ wait_queue_head_t *cb_event,
+ uint32_t *list_id, uint8_t data_flags);
+
+BC_STATUS crystalhd_hw_pause(struct crystalhd_hw *hw);
+BC_STATUS crystalhd_hw_unpause(struct crystalhd_hw *hw);
+BC_STATUS crystalhd_hw_suspend(struct crystalhd_hw *hw);
+BC_STATUS crystalhd_hw_cancel_tx(struct crystalhd_hw *hw, uint32_t list_id);
+BC_STATUS crystalhd_hw_add_cap_buffer(struct crystalhd_hw *hw,
+ crystalhd_dio_req *ioreq, bool en_post);
+BC_STATUS crystalhd_hw_get_cap_buffer(struct crystalhd_hw *hw,
+ BC_PIC_INFO_BLOCK *pib,
+ crystalhd_dio_req **ioreq);
+BC_STATUS crystalhd_hw_stop_capture(struct crystalhd_hw *hw);
+BC_STATUS crystalhd_hw_start_capture(struct crystalhd_hw *hw);
+void crystalhd_hw_stats(struct crystalhd_hw *hw, struct crystalhd_hw_stats *stats);
+
+/* API to program the core clock on the decoder */
+BC_STATUS crystalhd_hw_set_core_clock(struct crystalhd_hw *);
+
+#endif