提交 999e07d6 编写于 作者: O Omar Ramirez Luna 提交者: Greg Kroah-Hartman

staging: ti dspbridge: add core driver sources

Add TI's DSP Bridge core driver sources
Signed-off-by: NOmar Ramirez Luna <omar.ramirez@ti.com>
Signed-off-by: NKanigeri, Hari <h-kanigeri2@ti.com>
Signed-off-by: NAmeya Palande <ameya.palande@nokia.com>
Signed-off-by: NGuzman Lugo, Fernando <fernando.lugo@ti.com>
Signed-off-by: NHebbar, Shivananda <x0hebbar@ti.com>
Signed-off-by: NRamos Falcon, Ernesto <ernesto@ti.com>
Signed-off-by: NFelipe Contreras <felipe.contreras@gmail.com>
Signed-off-by: NAnna, Suman <s-anna@ti.com>
Signed-off-by: NGupta, Ramesh <grgupta@ti.com>
Signed-off-by: NGomez Castellanos, Ivan <ivan.gomez@ti.com>
Signed-off-by: NAndy Shevchenko <ext-andriy.shevchenko@nokia.com>
Signed-off-by: NArmando Uribe De Leon <x0095078@ti.com>
Signed-off-by: NDeepak Chitriki <deepak.chitriki@ti.com>
Signed-off-by: NMenon, Nishanth <nm@ti.com>
Signed-off-by: NPhil Carmody <ext-phil.2.carmody@nokia.com>
Signed-off-by: NOhad Ben-Cohen <ohad@wizery.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
上级 6c5fe838
/*
* _cmm.h
*
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
*
* Private header file defining CMM manager objects and defines needed
* by IO manager to register shared memory regions when DSP base image
* is loaded(bridge_io_on_loaded).
*
* Copyright (C) 2005-2006 Texas Instruments, Inc.
*
* This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef _CMM_
#define _CMM_
/*
* These target side symbols define the beginning and ending addresses
* of the section of shared memory used for shared memory manager CMM.
* They are defined in the *cfg.cmd file by cdb code.
*/
#define SHM0_SHARED_BASE_SYM "_SHM0_BEG"
#define SHM0_SHARED_END_SYM "_SHM0_END"
#define SHM0_SHARED_RESERVED_BASE_SYM "_SHM0_RSVDSTRT"
/*
* Shared Memory Region #0(SHMSEG0) is used in the following way:
*
* |(_SHM0_BEG) | (_SHM0_RSVDSTRT) | (_SHM0_END)
* V V V
* ------------------------------------------------------------
* | DSP-side allocations | GPP-side allocations |
* ------------------------------------------------------------
*
*
*/
#endif /* _CMM_ */
/*
* _deh.h
*
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
*
* Private header for DEH module.
*
* Copyright (C) 2005-2006 Texas Instruments, Inc.
*
* This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef _DEH_
#define _DEH_
#include <dspbridge/ntfy.h>
#include <dspbridge/dspdefs.h>
/* DEH Manager: only one created per board: */
struct deh_mgr {
struct bridge_dev_context *hbridge_context; /* Bridge context. */
struct ntfy_object *ntfy_obj; /* NTFY object */
struct dsp_errorinfo err_info; /* DSP exception info. */
/* MMU Fault DPC */
struct tasklet_struct dpc_tasklet;
};
#endif /* _DEH_ */
/*
* _msg_sm.h
*
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
*
* Private header file defining msg_ctrl manager objects and defines needed
* by IO manager.
*
* Copyright (C) 2005-2006 Texas Instruments, Inc.
*
* This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef _MSG_SM_
#define _MSG_SM_
#include <dspbridge/list.h>
#include <dspbridge/msgdefs.h>
/*
* These target side symbols define the beginning and ending addresses
* of the section of shared memory used for messages. They are
* defined in the *cfg.cmd file by cdb code.
*/
#define MSG_SHARED_BUFFER_BASE_SYM "_MSG_BEG"
#define MSG_SHARED_BUFFER_LIMIT_SYM "_MSG_END"
#ifndef _CHNL_WORDSIZE
#define _CHNL_WORDSIZE 4 /* default _CHNL_WORDSIZE is 2 bytes/word */
#endif
/*
* ======== msg_ctrl ========
* There is a control structure for messages to the DSP, and a control
* structure for messages from the DSP. The shared memory region for
* transferring messages is partitioned as follows:
*
* ----------------------------------------------------------
* |Control | Messages from DSP | Control | Messages to DSP |
* ----------------------------------------------------------
*
* msg_ctrl control structure for messages to the DSP is used in the following
* way:
*
* buf_empty - This flag is set to FALSE by the GPP after it has output
* messages for the DSP. The DSP host driver sets it to
* TRUE after it has copied the messages.
* post_swi - Set to 1 by the GPP after it has written the messages,
* set the size, and set buf_empty to FALSE.
* The DSP Host driver uses SWI_andn of the post_swi field
* when a host interrupt occurs. The host driver clears
* this after posting the SWI.
* size - Number of messages to be read by the DSP.
*
* For messages from the DSP:
* buf_empty - This flag is set to FALSE by the DSP after it has output
* messages for the GPP. The DPC on the GPP sets it to
* TRUE after it has copied the messages.
* post_swi - Set to 1 the DPC on the GPP after copying the messages.
* size - Number of messages to be read by the GPP.
*/
struct msg_ctrl {
u32 buf_empty; /* to/from DSP buffer is empty */
u32 post_swi; /* Set to "1" to post msg_ctrl SWI */
u32 size; /* Number of messages to/from the DSP */
u32 resvd;
};
/*
* ======== msg_mgr ========
* The msg_mgr maintains a list of all MSG_QUEUEs. Each NODE object can
* have msg_queue to hold all messages that come up from the corresponding
* node on the DSP. The msg_mgr also has a shared queue of messages
* ready to go to the DSP.
*/
struct msg_mgr {
/* The first field must match that in msgobj.h */
/* Function interface to Bridge driver */
struct bridge_drv_interface *intf_fxns;
struct io_mgr *hio_mgr; /* IO manager */
struct lst_list *queue_list; /* List of MSG_QUEUEs */
spinlock_t msg_mgr_lock; /* For critical sections */
/* Signalled when MsgFrame is available */
struct sync_object *sync_event;
struct lst_list *msg_free_list; /* Free MsgFrames ready to be filled */
struct lst_list *msg_used_list; /* MsgFrames ready to go to DSP */
u32 msgs_pending; /* # of queued messages to go to DSP */
u32 max_msgs; /* Max # of msgs that fit in buffer */
msg_onexit on_exit; /* called when RMS_EXIT is received */
};
/*
* ======== msg_queue ========
* Each NODE has a msg_queue for receiving messages from the
* corresponding node on the DSP. The msg_queue object maintains a list
* of messages that have been sent to the host, but not yet read (MSG_Get),
* and a list of free frames that can be filled when new messages arrive
* from the DSP.
* The msg_queue's hSynEvent gets posted when a message is ready.
*/
struct msg_queue {
struct list_head list_elem;
struct msg_mgr *hmsg_mgr;
u32 max_msgs; /* Node message depth */
u32 msgq_id; /* Node environment pointer */
struct lst_list *msg_free_list; /* Free MsgFrames ready to be filled */
/* Filled MsgFramess waiting to be read */
struct lst_list *msg_used_list;
void *arg; /* Handle passed to mgr on_exit callback */
struct sync_object *sync_event; /* Signalled when message is ready */
struct sync_object *sync_done; /* For synchronizing cleanup */
struct sync_object *sync_done_ack; /* For synchronizing cleanup */
struct ntfy_object *ntfy_obj; /* For notification of message ready */
bool done; /* TRUE <==> deleting the object */
u32 io_msg_pend; /* Number of pending MSG_get/put calls */
};
/*
* ======== msg_dspmsg ========
*/
struct msg_dspmsg {
struct dsp_msg msg;
u32 msgq_id; /* Identifies the node the message goes to */
};
/*
* ======== msg_frame ========
*/
struct msg_frame {
struct list_head list_elem;
struct msg_dspmsg msg_data;
};
#endif /* _MSG_SM_ */
/*
* _tiomap.h
*
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
*
* Definitions and types private to this Bridge driver.
*
* Copyright (C) 2005-2006 Texas Instruments, Inc.
*
* This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef _TIOMAP_
#define _TIOMAP_
#include <plat/powerdomain.h>
#include <plat/clockdomain.h>
#include <mach-omap2/prm-regbits-34xx.h>
#include <mach-omap2/cm-regbits-34xx.h>
#include <dspbridge/devdefs.h>
#include <hw_defs.h>
#include <dspbridge/dspioctl.h> /* for bridge_ioctl_extproc defn */
#include <dspbridge/sync.h>
#include <dspbridge/clk.h>
struct map_l4_peripheral {
u32 phys_addr;
u32 dsp_virt_addr;
};
#define ARM_MAILBOX_START 0xfffcf000
#define ARM_MAILBOX_LENGTH 0x800
/* New Registers in OMAP3.1 */
#define TESTBLOCK_ID_START 0xfffed400
#define TESTBLOCK_ID_LENGTH 0xff
/* ID Returned by OMAP1510 */
#define TBC_ID_VALUE 0xB47002F
#define SPACE_LENGTH 0x2000
#define API_CLKM_DPLL_DMA 0xfffec000
#define ARM_INTERRUPT_OFFSET 0xb00
#define BIOS24XX
#define L4_PERIPHERAL_NULL 0x0
#define DSPVA_PERIPHERAL_NULL 0x0
#define MAX_LOCK_TLB_ENTRIES 15
#define L4_PERIPHERAL_PRM 0x48306000 /*PRM L4 Peripheral */
#define DSPVA_PERIPHERAL_PRM 0x1181e000
#define L4_PERIPHERAL_SCM 0x48002000 /*SCM L4 Peripheral */
#define DSPVA_PERIPHERAL_SCM 0x1181f000
#define L4_PERIPHERAL_MMU 0x5D000000 /*MMU L4 Peripheral */
#define DSPVA_PERIPHERAL_MMU 0x11820000
#define L4_PERIPHERAL_CM 0x48004000 /* Core L4, Clock Management */
#define DSPVA_PERIPHERAL_CM 0x1181c000
#define L4_PERIPHERAL_PER 0x48005000 /* PER */
#define DSPVA_PERIPHERAL_PER 0x1181d000
#define L4_PERIPHERAL_GPIO1 0x48310000
#define DSPVA_PERIPHERAL_GPIO1 0x11809000
#define L4_PERIPHERAL_GPIO2 0x49050000
#define DSPVA_PERIPHERAL_GPIO2 0x1180a000
#define L4_PERIPHERAL_GPIO3 0x49052000
#define DSPVA_PERIPHERAL_GPIO3 0x1180b000
#define L4_PERIPHERAL_GPIO4 0x49054000
#define DSPVA_PERIPHERAL_GPIO4 0x1180c000
#define L4_PERIPHERAL_GPIO5 0x49056000
#define DSPVA_PERIPHERAL_GPIO5 0x1180d000
#define L4_PERIPHERAL_IVA2WDT 0x49030000
#define DSPVA_PERIPHERAL_IVA2WDT 0x1180e000
#define L4_PERIPHERAL_DISPLAY 0x48050000
#define DSPVA_PERIPHERAL_DISPLAY 0x1180f000
#define L4_PERIPHERAL_SSI 0x48058000
#define DSPVA_PERIPHERAL_SSI 0x11804000
#define L4_PERIPHERAL_GDD 0x48059000
#define DSPVA_PERIPHERAL_GDD 0x11805000
#define L4_PERIPHERAL_SS1 0x4805a000
#define DSPVA_PERIPHERAL_SS1 0x11806000
#define L4_PERIPHERAL_SS2 0x4805b000
#define DSPVA_PERIPHERAL_SS2 0x11807000
#define L4_PERIPHERAL_CAMERA 0x480BC000
#define DSPVA_PERIPHERAL_CAMERA 0x11819000
#define L4_PERIPHERAL_SDMA 0x48056000
#define DSPVA_PERIPHERAL_SDMA 0x11810000 /* 0x1181d000 conflict w/ PER */
#define L4_PERIPHERAL_UART1 0x4806a000
#define DSPVA_PERIPHERAL_UART1 0x11811000
#define L4_PERIPHERAL_UART2 0x4806c000
#define DSPVA_PERIPHERAL_UART2 0x11812000
#define L4_PERIPHERAL_UART3 0x49020000
#define DSPVA_PERIPHERAL_UART3 0x11813000
#define L4_PERIPHERAL_MCBSP1 0x48074000
#define DSPVA_PERIPHERAL_MCBSP1 0x11814000
#define L4_PERIPHERAL_MCBSP2 0x49022000
#define DSPVA_PERIPHERAL_MCBSP2 0x11815000
#define L4_PERIPHERAL_MCBSP3 0x49024000
#define DSPVA_PERIPHERAL_MCBSP3 0x11816000
#define L4_PERIPHERAL_MCBSP4 0x49026000
#define DSPVA_PERIPHERAL_MCBSP4 0x11817000
#define L4_PERIPHERAL_MCBSP5 0x48096000
#define DSPVA_PERIPHERAL_MCBSP5 0x11818000
#define L4_PERIPHERAL_GPTIMER5 0x49038000
#define DSPVA_PERIPHERAL_GPTIMER5 0x11800000
#define L4_PERIPHERAL_GPTIMER6 0x4903a000
#define DSPVA_PERIPHERAL_GPTIMER6 0x11801000
#define L4_PERIPHERAL_GPTIMER7 0x4903c000
#define DSPVA_PERIPHERAL_GPTIMER7 0x11802000
#define L4_PERIPHERAL_GPTIMER8 0x4903e000
#define DSPVA_PERIPHERAL_GPTIMER8 0x11803000
#define L4_PERIPHERAL_SPI1 0x48098000
#define DSPVA_PERIPHERAL_SPI1 0x1181a000
#define L4_PERIPHERAL_SPI2 0x4809a000
#define DSPVA_PERIPHERAL_SPI2 0x1181b000
#define L4_PERIPHERAL_MBOX 0x48094000
#define DSPVA_PERIPHERAL_MBOX 0x11808000
#define PM_GRPSEL_BASE 0x48307000
#define DSPVA_GRPSEL_BASE 0x11821000
#define L4_PERIPHERAL_SIDETONE_MCBSP2 0x49028000
#define DSPVA_PERIPHERAL_SIDETONE_MCBSP2 0x11824000
#define L4_PERIPHERAL_SIDETONE_MCBSP3 0x4902a000
#define DSPVA_PERIPHERAL_SIDETONE_MCBSP3 0x11825000
/* define a static array with L4 mappings */
static const struct map_l4_peripheral l4_peripheral_table[] = {
{L4_PERIPHERAL_MBOX, DSPVA_PERIPHERAL_MBOX},
{L4_PERIPHERAL_SCM, DSPVA_PERIPHERAL_SCM},
{L4_PERIPHERAL_MMU, DSPVA_PERIPHERAL_MMU},
{L4_PERIPHERAL_GPTIMER5, DSPVA_PERIPHERAL_GPTIMER5},
{L4_PERIPHERAL_GPTIMER6, DSPVA_PERIPHERAL_GPTIMER6},
{L4_PERIPHERAL_GPTIMER7, DSPVA_PERIPHERAL_GPTIMER7},
{L4_PERIPHERAL_GPTIMER8, DSPVA_PERIPHERAL_GPTIMER8},
{L4_PERIPHERAL_GPIO1, DSPVA_PERIPHERAL_GPIO1},
{L4_PERIPHERAL_GPIO2, DSPVA_PERIPHERAL_GPIO2},
{L4_PERIPHERAL_GPIO3, DSPVA_PERIPHERAL_GPIO3},
{L4_PERIPHERAL_GPIO4, DSPVA_PERIPHERAL_GPIO4},
{L4_PERIPHERAL_GPIO5, DSPVA_PERIPHERAL_GPIO5},
{L4_PERIPHERAL_IVA2WDT, DSPVA_PERIPHERAL_IVA2WDT},
{L4_PERIPHERAL_DISPLAY, DSPVA_PERIPHERAL_DISPLAY},
{L4_PERIPHERAL_SSI, DSPVA_PERIPHERAL_SSI},
{L4_PERIPHERAL_GDD, DSPVA_PERIPHERAL_GDD},
{L4_PERIPHERAL_SS1, DSPVA_PERIPHERAL_SS1},
{L4_PERIPHERAL_SS2, DSPVA_PERIPHERAL_SS2},
{L4_PERIPHERAL_UART1, DSPVA_PERIPHERAL_UART1},
{L4_PERIPHERAL_UART2, DSPVA_PERIPHERAL_UART2},
{L4_PERIPHERAL_UART3, DSPVA_PERIPHERAL_UART3},
{L4_PERIPHERAL_MCBSP1, DSPVA_PERIPHERAL_MCBSP1},
{L4_PERIPHERAL_MCBSP2, DSPVA_PERIPHERAL_MCBSP2},
{L4_PERIPHERAL_MCBSP3, DSPVA_PERIPHERAL_MCBSP3},
{L4_PERIPHERAL_MCBSP4, DSPVA_PERIPHERAL_MCBSP4},
{L4_PERIPHERAL_MCBSP5, DSPVA_PERIPHERAL_MCBSP5},
{L4_PERIPHERAL_CAMERA, DSPVA_PERIPHERAL_CAMERA},
{L4_PERIPHERAL_SPI1, DSPVA_PERIPHERAL_SPI1},
{L4_PERIPHERAL_SPI2, DSPVA_PERIPHERAL_SPI2},
{L4_PERIPHERAL_PRM, DSPVA_PERIPHERAL_PRM},
{L4_PERIPHERAL_CM, DSPVA_PERIPHERAL_CM},
{L4_PERIPHERAL_PER, DSPVA_PERIPHERAL_PER},
{PM_GRPSEL_BASE, DSPVA_GRPSEL_BASE},
{L4_PERIPHERAL_SIDETONE_MCBSP2, DSPVA_PERIPHERAL_SIDETONE_MCBSP2},
{L4_PERIPHERAL_SIDETONE_MCBSP3, DSPVA_PERIPHERAL_SIDETONE_MCBSP3},
{L4_PERIPHERAL_NULL, DSPVA_PERIPHERAL_NULL}
};
/*
* 15 10 0
* ---------------------------------
* |0|0|1|0|0|0|c|c|c|i|i|i|i|i|i|i|
* ---------------------------------
* | (class) | (module specific) |
*
* where c -> Externel Clock Command: Clk & Autoidle Disable/Enable
* i -> External Clock ID Timers 5,6,7,8, McBSP1,2 and WDT3
*/
/* MBX_PM_CLK_IDMASK: DSP External clock id mask. */
#define MBX_PM_CLK_IDMASK 0x7F
/* MBX_PM_CLK_CMDSHIFT: DSP External clock command shift. */
#define MBX_PM_CLK_CMDSHIFT 7
/* MBX_PM_CLK_CMDMASK: DSP External clock command mask. */
#define MBX_PM_CLK_CMDMASK 7
/* MBX_PM_MAX_RESOURCES: CORE 1 Clock resources. */
#define MBX_CORE1_RESOURCES 7
/* MBX_PM_MAX_RESOURCES: CORE 2 Clock Resources. */
#define MBX_CORE2_RESOURCES 1
/* MBX_PM_MAX_RESOURCES: TOTAL Clock Reosurces. */
#define MBX_PM_MAX_RESOURCES 11
/* Power Management Commands */
#define BPWR_DISABLE_CLOCK 0
#define BPWR_ENABLE_CLOCK 1
/* OMAP242x specific resources */
enum bpwr_ext_clock_id {
BPWR_GP_TIMER5 = 0x10,
BPWR_GP_TIMER6,
BPWR_GP_TIMER7,
BPWR_GP_TIMER8,
BPWR_WD_TIMER3,
BPWR_MCBSP1,
BPWR_MCBSP2,
BPWR_MCBSP3,
BPWR_MCBSP4,
BPWR_MCBSP5,
BPWR_SSI = 0x20
};
static const u32 bpwr_clkid[] = {
(u32) BPWR_GP_TIMER5,
(u32) BPWR_GP_TIMER6,
(u32) BPWR_GP_TIMER7,
(u32) BPWR_GP_TIMER8,
(u32) BPWR_WD_TIMER3,
(u32) BPWR_MCBSP1,
(u32) BPWR_MCBSP2,
(u32) BPWR_MCBSP3,
(u32) BPWR_MCBSP4,
(u32) BPWR_MCBSP5,
(u32) BPWR_SSI
};
struct bpwr_clk_t {
u32 clk_id;
enum dsp_clk_id clk;
};
static const struct bpwr_clk_t bpwr_clks[] = {
{(u32) BPWR_GP_TIMER5, DSP_CLK_GPT5},
{(u32) BPWR_GP_TIMER6, DSP_CLK_GPT6},
{(u32) BPWR_GP_TIMER7, DSP_CLK_GPT7},
{(u32) BPWR_GP_TIMER8, DSP_CLK_GPT8},
{(u32) BPWR_WD_TIMER3, DSP_CLK_WDT3},
{(u32) BPWR_MCBSP1, DSP_CLK_MCBSP1},
{(u32) BPWR_MCBSP2, DSP_CLK_MCBSP2},
{(u32) BPWR_MCBSP3, DSP_CLK_MCBSP3},
{(u32) BPWR_MCBSP4, DSP_CLK_MCBSP4},
{(u32) BPWR_MCBSP5, DSP_CLK_MCBSP5},
{(u32) BPWR_SSI, DSP_CLK_SSI}
};
/* Interrupt Register Offsets */
#define INTH_IT_REG_OFFSET 0x00 /* Interrupt register offset */
#define INTH_MASK_IT_REG_OFFSET 0x04 /* Mask Interrupt reg offset */
#define DSP_MAILBOX1_INT 10
/*
* Bit definition of Interrupt Level Registers
*/
/* Mail Box defines */
#define MB_ARM2DSP1_REG_OFFSET 0x00
#define MB_ARM2DSP1B_REG_OFFSET 0x04
#define MB_DSP2ARM1B_REG_OFFSET 0x0C
#define MB_ARM2DSP1_FLAG_REG_OFFSET 0x18
#define MB_ARM2DSP_FLAG 0x0001
#define MBOX_ARM2DSP HW_MBOX_ID0
#define MBOX_DSP2ARM HW_MBOX_ID1
#define MBOX_ARM HW_MBOX_U0_ARM
#define MBOX_DSP HW_MBOX_U1_DSP1
#define ENABLE true
#define DISABLE false
#define HIGH_LEVEL true
#define LOW_LEVEL false
/* Macro's */
#define REG16(A) (*(reg_uword16 *)(A))
#define CLEAR_BIT(reg, mask) (reg &= ~mask)
#define SET_BIT(reg, mask) (reg |= mask)
#define SET_GROUP_BITS16(reg, position, width, value) \
do {\
reg &= ~((0xFFFF >> (16 - (width))) << (position)) ; \
reg |= ((value & (0xFFFF >> (16 - (width)))) << (position)); \
} while (0);
#define CLEAR_BIT_INDEX(reg, index) (reg &= ~(1 << (index)))
/* This Bridge driver's device context: */
struct bridge_dev_context {
struct dev_object *hdev_obj; /* Handle to Bridge device object. */
u32 dw_dsp_base_addr; /* Arm's API to DSP virt base addr */
/*
* DSP External memory prog address as seen virtually by the OS on
* the host side.
*/
u32 dw_dsp_ext_base_addr; /* See the comment above */
u32 dw_api_reg_base; /* API mem map'd registers */
void __iomem *dw_dsp_mmu_base; /* DSP MMU Mapped registers */
u32 dw_api_clk_base; /* CLK Registers */
u32 dw_dsp_clk_m2_base; /* DSP Clock Module m2 */
u32 dw_public_rhea; /* Pub Rhea */
u32 dw_int_addr; /* MB INTR reg */
u32 dw_tc_endianism; /* TC Endianism register */
u32 dw_test_base; /* DSP MMU Mapped registers */
u32 dw_self_loop; /* Pointer to the selfloop */
u32 dw_dsp_start_add; /* API Boot vector */
u32 dw_internal_size; /* Internal memory size */
struct omap_mbox *mbox; /* Mail box handle */
struct cfg_hostres *resources; /* Host Resources */
/*
* Processor specific info is set when prog loaded and read from DCD.
* [See bridge_dev_ctrl()] PROC info contains DSP-MMU TLB entries.
*/
/* DMMU TLB entries */
struct bridge_ioctl_extproc atlb_entry[BRDIOCTL_NUMOFMMUTLB];
u32 dw_brd_state; /* Last known board state. */
u32 ul_int_mask; /* int mask */
u16 io_base; /* Board I/O base */
u32 num_tlb_entries; /* DSP MMU TLB entry counter */
u32 fixed_tlb_entries; /* Fixed DSPMMU TLB entry count */
/* TC Settings */
bool tc_word_swap_on; /* Traffic Controller Word Swap */
struct pg_table_attrs *pt_attrs;
u32 dsp_per_clks;
};
/*
* If dsp_debug is true, do not branch to the DSP entry
* point and wait for DSP to boot.
*/
extern s32 dsp_debug;
/*
* ======== sm_interrupt_dsp ========
* Purpose:
* Set interrupt value & send an interrupt to the DSP processor(s).
* This is typicaly used when mailbox interrupt mechanisms allow data
* to be associated with interrupt such as for OMAP's CMD/DATA regs.
* Parameters:
* dev_context: Handle to Bridge driver defined device info.
* mb_val: Value associated with interrupt(e.g. mailbox value).
* Returns:
* 0: Interrupt sent;
* else: Unable to send interrupt.
* Requires:
* Ensures:
*/
int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val);
#endif /* _TIOMAP_ */
/*
* _tiomap_pwr.h
*
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
*
* Definitions and types for the DSP wake/sleep routines.
*
* Copyright (C) 2005-2006 Texas Instruments, Inc.
*
* This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef _TIOMAP_PWR_
#define _TIOMAP_PWR_
#ifdef CONFIG_PM
extern s32 dsp_test_sleepstate;
#endif
extern struct mailbox_context mboxsetting;
/*
* ======== wake_dsp =========
* Wakes up the DSP from DeepSleep
*/
extern int wake_dsp(struct bridge_dev_context *dev_context,
IN void *pargs);
/*
* ======== sleep_dsp =========
* Places the DSP in DeepSleep.
*/
extern int sleep_dsp(struct bridge_dev_context *dev_context,
IN u32 dw_cmd, IN void *pargs);
/*
* ========interrupt_dsp========
* Sends an interrupt to DSP unconditionally.
*/
extern void interrupt_dsp(struct bridge_dev_context *dev_context,
IN u16 mb_val);
/*
* ======== wake_dsp =========
* Wakes up the DSP from DeepSleep
*/
extern int dsp_peripheral_clk_ctrl(struct bridge_dev_context
*dev_context, IN void *pargs);
/*
* ======== handle_hibernation_from_dsp ========
* Handle Hibernation requested from DSP
*/
int handle_hibernation_from_dsp(struct bridge_dev_context *dev_context);
/*
* ======== post_scale_dsp ========
* Handle Post Scale notification to DSP
*/
int post_scale_dsp(struct bridge_dev_context *dev_context,
IN void *pargs);
/*
* ======== pre_scale_dsp ========
* Handle Pre Scale notification to DSP
*/
int pre_scale_dsp(struct bridge_dev_context *dev_context,
IN void *pargs);
/*
* ======== handle_constraints_set ========
* Handle constraints request from DSP
*/
int handle_constraints_set(struct bridge_dev_context *dev_context,
IN void *pargs);
/*
* ======== dsp_clk_wakeup_event_ctrl ========
* This function sets the group selction bits for while
* enabling/disabling.
*/
void dsp_clk_wakeup_event_ctrl(u32 ClkId, bool enable);
#endif /* _TIOMAP_PWR_ */
此差异已折叠。
/*
* clk.c
*
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
*
* Clock and Timer services.
*
* Copyright (C) 2005-2006 Texas Instruments, Inc.
*
* This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/* ----------------------------------- Host OS */
#include <dspbridge/host_os.h>
#include <plat/dmtimer.h>
#include <plat/mcbsp.h>
/* ----------------------------------- DSP/BIOS Bridge */
#include <dspbridge/std.h>
#include <dspbridge/dbdefs.h>
#include <dspbridge/cfg.h>
#include <dspbridge/drv.h>
#include <dspbridge/dev.h>
#include "_tiomap.h"
/* ----------------------------------- Trace & Debug */
#include <dspbridge/dbc.h>
/* ----------------------------------- This */
#include <dspbridge/clk.h>
/* ----------------------------------- Defines, Data Structures, Typedefs */
#define OMAP_SSI_OFFSET 0x58000
#define OMAP_SSI_SIZE 0x1000
#define OMAP_SSI_SYSCONFIG_OFFSET 0x10
#define SSI_AUTOIDLE (1 << 0)
#define SSI_SIDLE_SMARTIDLE (2 << 3)
#define SSI_MIDLE_NOIDLE (1 << 12)
/* Clk types requested by the dsp */
#define IVA2_CLK 0
#define GPT_CLK 1
#define WDT_CLK 2
#define MCBSP_CLK 3
#define SSI_CLK 4
/* Bridge GPT id (1 - 4), DM Timer id (5 - 8) */
#define DMT_ID(id) ((id) + 4)
/* Bridge MCBSP id (6 - 10), OMAP Mcbsp id (0 - 4) */
#define MCBSP_ID(id) ((id) - 6)
static struct omap_dm_timer *timer[4];
struct clk *iva2_clk;
struct dsp_ssi {
struct clk *sst_fck;
struct clk *ssr_fck;
struct clk *ick;
};
static struct dsp_ssi ssi;
static u32 dsp_clocks;
static inline u32 is_dsp_clk_active(u32 clk, u8 id)
{
return clk & (1 << id);
}
static inline void set_dsp_clk_active(u32 *clk, u8 id)
{
*clk |= (1 << id);
}
static inline void set_dsp_clk_inactive(u32 *clk, u8 id)
{
*clk &= ~(1 << id);
}
static s8 get_clk_type(u8 id)
{
s8 type;
if (id == DSP_CLK_IVA2)
type = IVA2_CLK;
else if (id <= DSP_CLK_GPT8)
type = GPT_CLK;
else if (id == DSP_CLK_WDT3)
type = WDT_CLK;
else if (id <= DSP_CLK_MCBSP5)
type = MCBSP_CLK;
else if (id == DSP_CLK_SSI)
type = SSI_CLK;
else
type = -1;
return type;
}
/*
* ======== dsp_clk_exit ========
* Purpose:
* Cleanup CLK module.
*/
void dsp_clk_exit(void)
{
dsp_clock_disable_all(dsp_clocks);
clk_put(iva2_clk);
clk_put(ssi.sst_fck);
clk_put(ssi.ssr_fck);
clk_put(ssi.ick);
}
/*
* ======== dsp_clk_init ========
* Purpose:
* Initialize CLK module.
*/
void dsp_clk_init(void)
{
static struct platform_device dspbridge_device;
dspbridge_device.dev.bus = &platform_bus_type;
iva2_clk = clk_get(&dspbridge_device.dev, "iva2_ck");
if (IS_ERR(iva2_clk))
dev_err(bridge, "failed to get iva2 clock %p\n", iva2_clk);
ssi.sst_fck = clk_get(&dspbridge_device.dev, "ssi_sst_fck");
ssi.ssr_fck = clk_get(&dspbridge_device.dev, "ssi_ssr_fck");
ssi.ick = clk_get(&dspbridge_device.dev, "ssi_ick");
if (IS_ERR(ssi.sst_fck) || IS_ERR(ssi.ssr_fck) || IS_ERR(ssi.ick))
dev_err(bridge, "failed to get ssi: sst %p, ssr %p, ick %p\n",
ssi.sst_fck, ssi.ssr_fck, ssi.ick);
}
#ifdef CONFIG_OMAP_MCBSP
static void mcbsp_clk_prepare(bool flag, u8 id)
{
struct cfg_hostres *resources;
struct dev_object *hdev_object = NULL;
struct bridge_dev_context *bridge_context = NULL;
u32 val;
hdev_object = (struct dev_object *)drv_get_first_dev_object();
if (!hdev_object)
return;
dev_get_bridge_context(hdev_object, &bridge_context);
if (!bridge_context)
return;
resources = bridge_context->resources;
if (!resources)
return;
if (flag) {
if (id == DSP_CLK_MCBSP1) {
/* set MCBSP1_CLKS, on McBSP1 ON */
val = __raw_readl(resources->dw_sys_ctrl_base + 0x274);
val |= 1 << 2;
__raw_writel(val, resources->dw_sys_ctrl_base + 0x274);
} else if (id == DSP_CLK_MCBSP2) {
/* set MCBSP2_CLKS, on McBSP2 ON */
val = __raw_readl(resources->dw_sys_ctrl_base + 0x274);
val |= 1 << 6;
__raw_writel(val, resources->dw_sys_ctrl_base + 0x274);
}
} else {
if (id == DSP_CLK_MCBSP1) {
/* clear MCBSP1_CLKS, on McBSP1 OFF */
val = __raw_readl(resources->dw_sys_ctrl_base + 0x274);
val &= ~(1 << 2);
__raw_writel(val, resources->dw_sys_ctrl_base + 0x274);
} else if (id == DSP_CLK_MCBSP2) {
/* clear MCBSP2_CLKS, on McBSP2 OFF */
val = __raw_readl(resources->dw_sys_ctrl_base + 0x274);
val &= ~(1 << 6);
__raw_writel(val, resources->dw_sys_ctrl_base + 0x274);
}
}
}
#endif
/**
* dsp_gpt_wait_overflow - set gpt overflow and wait for fixed timeout
* @clk_id: GP Timer clock id.
* @load: Overflow value.
*
* Sets an overflow interrupt for the desired GPT waiting for a timeout
* of 5 msecs for the interrupt to occur.
*/
void dsp_gpt_wait_overflow(short int clk_id, unsigned int load)
{
struct omap_dm_timer *gpt = timer[clk_id - 1];
unsigned long timeout;
if (!gpt)
return;
/* Enable overflow interrupt */
omap_dm_timer_set_int_enable(gpt, OMAP_TIMER_INT_OVERFLOW);
/*
* Set counter value to overflow counter after
* one tick and start timer.
*/
omap_dm_timer_set_load_start(gpt, 0, load);
/* Wait 80us for timer to overflow */
udelay(80);
timeout = msecs_to_jiffies(5);
/* Check interrupt status and wait for interrupt */
while (!(omap_dm_timer_read_status(gpt) & OMAP_TIMER_INT_OVERFLOW)) {
if (time_is_after_jiffies(timeout)) {
pr_err("%s: GPTimer interrupt failed\n", __func__);
break;
}
}
}
/*
* ======== dsp_clk_enable ========
* Purpose:
* Enable Clock .
*
*/
int dsp_clk_enable(IN enum dsp_clk_id clk_id)
{
int status = 0;
if (is_dsp_clk_active(dsp_clocks, clk_id)) {
dev_err(bridge, "WARN: clock id %d already enabled\n", clk_id);
goto out;
}
switch (get_clk_type(clk_id)) {
case IVA2_CLK:
clk_enable(iva2_clk);
break;
case GPT_CLK:
timer[clk_id - 1] =
omap_dm_timer_request_specific(DMT_ID(clk_id));
break;
#ifdef CONFIG_OMAP_MCBSP
case MCBSP_CLK:
mcbsp_clk_prepare(true, clk_id);
omap_mcbsp_set_io_type(MCBSP_ID(clk_id), OMAP_MCBSP_POLL_IO);
omap_mcbsp_request(MCBSP_ID(clk_id));
break;
#endif
case WDT_CLK:
dev_err(bridge, "ERROR: DSP requested to enable WDT3 clk\n");
break;
case SSI_CLK:
clk_enable(ssi.sst_fck);
clk_enable(ssi.ssr_fck);
clk_enable(ssi.ick);
/*
* The SSI module need to configured not to have the Forced
* idle for master interface. If it is set to forced idle,
* the SSI module is transitioning to standby thereby causing
* the client in the DSP hang waiting for the SSI module to
* be active after enabling the clocks
*/
ssi_clk_prepare(true);
break;
default:
dev_err(bridge, "Invalid clock id for enable\n");
status = -EPERM;
}
if (DSP_SUCCEEDED(status))
set_dsp_clk_active(&dsp_clocks, clk_id);
out:
return status;
}
/**
* dsp_clock_enable_all - Enable clocks used by the DSP
* @dev_context Driver's device context strucure
*
* This function enables all the peripheral clocks that were requested by DSP.
*/
u32 dsp_clock_enable_all(u32 dsp_per_clocks)
{
u32 clk_id;
u32 status = -EPERM;
for (clk_id = 0; clk_id < DSP_CLK_NOT_DEFINED; clk_id++) {
if (is_dsp_clk_active(dsp_per_clocks, clk_id))
status = dsp_clk_enable(clk_id);
}
return status;
}
/*
* ======== dsp_clk_disable ========
* Purpose:
* Disable the clock.
*
*/
int dsp_clk_disable(IN enum dsp_clk_id clk_id)
{
int status = 0;
if (!is_dsp_clk_active(dsp_clocks, clk_id)) {
dev_err(bridge, "ERR: clock id %d already disabled\n", clk_id);
goto out;
}
switch (get_clk_type(clk_id)) {
case IVA2_CLK:
clk_disable(iva2_clk);
break;
case GPT_CLK:
omap_dm_timer_free(timer[clk_id - 1]);
break;
#ifdef CONFIG_OMAP_MCBSP
case MCBSP_CLK:
mcbsp_clk_prepare(false, clk_id);
omap_mcbsp_free(MCBSP_ID(clk_id));
break;
#endif
case WDT_CLK:
dev_err(bridge, "ERROR: DSP requested to disable WDT3 clk\n");
break;
case SSI_CLK:
ssi_clk_prepare(false);
ssi_clk_prepare(false);
clk_disable(ssi.sst_fck);
clk_disable(ssi.ssr_fck);
clk_disable(ssi.ick);
break;
default:
dev_err(bridge, "Invalid clock id for disable\n");
status = -EPERM;
}
if (DSP_SUCCEEDED(status))
set_dsp_clk_inactive(&dsp_clocks, clk_id);
out:
return status;
}
/**
* dsp_clock_disable_all - Disable all active clocks
* @dev_context Driver's device context structure
*
* This function disables all the peripheral clocks that were enabled by DSP.
* It is meant to be called only when DSP is entering hibernation or when DSP
* is in error state.
*/
u32 dsp_clock_disable_all(u32 dsp_per_clocks)
{
u32 clk_id;
u32 status = -EPERM;
for (clk_id = 0; clk_id < DSP_CLK_NOT_DEFINED; clk_id++) {
if (is_dsp_clk_active(dsp_per_clocks, clk_id))
status = dsp_clk_disable(clk_id);
}
return status;
}
u32 dsp_clk_get_iva2_rate(void)
{
u32 clk_speed_khz;
clk_speed_khz = clk_get_rate(iva2_clk);
clk_speed_khz /= 1000;
dev_dbg(bridge, "%s: clk speed Khz = %d\n", __func__, clk_speed_khz);
return clk_speed_khz;
}
void ssi_clk_prepare(bool FLAG)
{
void __iomem *ssi_base;
unsigned int value;
ssi_base = ioremap(L4_34XX_BASE + OMAP_SSI_OFFSET, OMAP_SSI_SIZE);
if (!ssi_base) {
pr_err("%s: error, SSI not configured\n", __func__);
return;
}
if (FLAG) {
/* Set Autoidle, SIDLEMode to smart idle, and MIDLEmode to
* no idle
*/
value = SSI_AUTOIDLE | SSI_SIDLE_SMARTIDLE | SSI_MIDLE_NOIDLE;
} else {
/* Set Autoidle, SIDLEMode to forced idle, and MIDLEmode to
* forced idle
*/
value = SSI_AUTOIDLE;
}
__raw_writel(value, ssi_base + OMAP_SSI_SYSCONFIG_OFFSET);
iounmap(ssi_base);
}
此差异已折叠。
/*
* mmu_fault.c
*
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
*
* Implements DSP MMU fault handling functions.
*
* Copyright (C) 2005-2006 Texas Instruments, Inc.
*
* This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/* ----------------------------------- DSP/BIOS Bridge */
#include <dspbridge/std.h>
#include <dspbridge/dbdefs.h>
/* ----------------------------------- Trace & Debug */
#include <dspbridge/host_os.h>
#include <dspbridge/dbc.h>
/* ----------------------------------- OS Adaptation Layer */
#include <dspbridge/drv.h>
/* ----------------------------------- Link Driver */
#include <dspbridge/dspdeh.h>
/* ------------------------------------ Hardware Abstraction Layer */
#include <hw_defs.h>
#include <hw_mmu.h>
/* ----------------------------------- This */
#include "_deh.h"
#include <dspbridge/cfg.h>
#include "_tiomap.h"
#include "mmu_fault.h"
static u32 dmmu_event_mask;
u32 fault_addr;
static bool mmu_check_if_fault(struct bridge_dev_context *dev_context);
/*
* ======== mmu_fault_dpc ========
* Deferred procedure call to handle DSP MMU fault.
*/
void mmu_fault_dpc(IN unsigned long pRefData)
{
struct deh_mgr *hdeh_mgr = (struct deh_mgr *)pRefData;
if (hdeh_mgr)
bridge_deh_notify(hdeh_mgr, DSP_MMUFAULT, 0L);
}
/*
* ======== mmu_fault_isr ========
* ISR to be triggered by a DSP MMU fault interrupt.
*/
irqreturn_t mmu_fault_isr(int irq, IN void *pRefData)
{
struct deh_mgr *deh_mgr_obj = (struct deh_mgr *)pRefData;
struct bridge_dev_context *dev_context;
struct cfg_hostres *resources;
DBC_REQUIRE(irq == INT_DSP_MMU_IRQ);
DBC_REQUIRE(deh_mgr_obj);
if (deh_mgr_obj) {
dev_context =
(struct bridge_dev_context *)deh_mgr_obj->hbridge_context;
resources = dev_context->resources;
if (!resources) {
dev_dbg(bridge, "%s: Failed to get Host Resources\n",
__func__);
return IRQ_HANDLED;
}
if (mmu_check_if_fault(dev_context)) {
printk(KERN_INFO "***** DSPMMU FAULT ***** IRQStatus "
"0x%x\n", dmmu_event_mask);
printk(KERN_INFO "***** DSPMMU FAULT ***** fault_addr "
"0x%x\n", fault_addr);
/*
* Schedule a DPC directly. In the future, it may be
* necessary to check if DSP MMU fault is intended for
* Bridge.
*/
tasklet_schedule(&deh_mgr_obj->dpc_tasklet);
/* Reset err_info structure before use. */
deh_mgr_obj->err_info.dw_err_mask = DSP_MMUFAULT;
deh_mgr_obj->err_info.dw_val1 = fault_addr >> 16;
deh_mgr_obj->err_info.dw_val2 = fault_addr & 0xFFFF;
deh_mgr_obj->err_info.dw_val3 = 0L;
/* Disable the MMU events, else once we clear it will
* start to raise INTs again */
hw_mmu_event_disable(resources->dw_dmmu_base,
HW_MMU_TRANSLATION_FAULT);
} else {
hw_mmu_event_disable(resources->dw_dmmu_base,
HW_MMU_ALL_INTERRUPTS);
}
}
return IRQ_HANDLED;
}
/*
* ======== mmu_check_if_fault ========
* Check to see if MMU Fault is valid TLB miss from DSP
* Note: This function is called from an ISR
*/
static bool mmu_check_if_fault(struct bridge_dev_context *dev_context)
{
bool ret = false;
hw_status hw_status_obj;
struct cfg_hostres *resources = dev_context->resources;
if (!resources) {
dev_dbg(bridge, "%s: Failed to get Host Resources in\n",
__func__);
return ret;
}
hw_status_obj =
hw_mmu_event_status(resources->dw_dmmu_base, &dmmu_event_mask);
if (dmmu_event_mask == HW_MMU_TRANSLATION_FAULT) {
hw_mmu_fault_addr_read(resources->dw_dmmu_base, &fault_addr);
ret = true;
}
return ret;
}
/*
* mmu_fault.h
*
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
*
* Defines DSP MMU fault handling functions.
*
* Copyright (C) 2005-2006 Texas Instruments, Inc.
*
* This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef MMU_FAULT_
#define MMU_FAULT_
extern u32 fault_addr;
/*
* ======== mmu_fault_dpc ========
* Deferred procedure call to handle DSP MMU fault.
*/
void mmu_fault_dpc(IN unsigned long pRefData);
/*
* ======== mmu_fault_isr ========
* ISR to be triggered by a DSP MMU fault interrupt.
*/
irqreturn_t mmu_fault_isr(int irq, IN void *pRefData);
#endif /* MMU_FAULT_ */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
/*
* tiomap_io.h
*
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
*
* Definitions, types and function prototypes for the io (r/w external mem).
*
* Copyright (C) 2005-2006 Texas Instruments, Inc.
*
* This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef _TIOMAP_IO_
#define _TIOMAP_IO_
/*
* Symbol that defines beginning of shared memory.
* For OMAP (Helen) this is the DSP Virtual base address of SDRAM.
* This will be used to program DSP MMU to map DSP Virt to GPP phys.
* (see dspMmuTlbEntry()).
*/
#define SHMBASENAME "SHM_BEG"
#define EXTBASE "EXT_BEG"
#define EXTEND "_EXT_END"
#define DYNEXTBASE "_DYNEXT_BEG"
#define DYNEXTEND "_DYNEXT_END"
#define IVAEXTMEMBASE "_IVAEXTMEM_BEG"
#define IVAEXTMEMEND "_IVAEXTMEM_END"
#define DSP_TRACESEC_BEG "_BRIDGE_TRACE_BEG"
#define DSP_TRACESEC_END "_BRIDGE_TRACE_END"
#define SYS_PUTCBEG "_SYS_PUTCBEG"
#define SYS_PUTCEND "_SYS_PUTCEND"
#define BRIDGE_SYS_PUTC_CURRENT "_BRIDGE_SYS_PUTC_current"
#define WORDSWAP_ENABLE 0x3 /* Enable word swap */
/*
* ======== read_ext_dsp_data ========
* Reads it from DSP External memory. The external memory for the DSP
* is configured by the combination of DSP MMU and shm Memory manager in the CDB
*/
extern int read_ext_dsp_data(struct bridge_dev_context *dev_context,
OUT u8 *pbHostBuf, u32 dwDSPAddr,
u32 ul_num_bytes, u32 ulMemType);
/*
* ======== write_dsp_data ========
*/
extern int write_dsp_data(struct bridge_dev_context *dev_context,
OUT u8 *pbHostBuf, u32 dwDSPAddr,
u32 ul_num_bytes, u32 ulMemType);
/*
* ======== write_ext_dsp_data ========
* Writes to the DSP External memory for external program.
* The ext mem for progra is configured by the combination of DSP MMU and
* shm Memory manager in the CDB
*/
extern int write_ext_dsp_data(struct bridge_dev_context *dev_context,
IN u8 *pbHostBuf, u32 dwDSPAddr,
u32 ul_num_bytes, u32 ulMemType,
bool bDynamicLoad);
/*
* ======== write_ext32_bit_dsp_data ========
* Writes 32 bit data to the external memory
*/
extern inline void write_ext32_bit_dsp_data(IN const
struct bridge_dev_context *dev_context,
IN u32 dwDSPAddr, IN u32 val)
{
*(u32 *) dwDSPAddr = ((dev_context->tc_word_swap_on) ? (((val << 16) &
0xFFFF0000) |
((val >> 16) &
0x0000FFFF)) :
val);
}
/*
* ======== read_ext32_bit_dsp_data ========
* Reads 32 bit data from the external memory
*/
extern inline u32 read_ext32_bit_dsp_data(IN const struct bridge_dev_context
*dev_context, IN u32 dwDSPAddr)
{
u32 ret;
ret = *(u32 *) dwDSPAddr;
ret = ((dev_context->tc_word_swap_on) ? (((ret << 16)
& 0xFFFF0000) | ((ret >> 16) &
0x0000FFFF))
: ret);
return ret;
}
#endif /* _TIOMAP_IO_ */
此差异已折叠。
/*
* wdt.c
*
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
*
* IO dispatcher for a shared memory channel driver.
*
* Copyright (C) 2010 Texas Instruments, Inc.
*
* This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#include <dspbridge/std.h>
#include <dspbridge/dbdefs.h>
#include <dspbridge/dspdeh.h>
#include <dspbridge/dev.h>
#include <dspbridge/_chnl_sm.h>
#include <dspbridge/wdt.h>
#include <dspbridge/host_os.h>
#ifdef CONFIG_BRIDGE_WDT3
#define OMAP34XX_WDT3_BASE (L4_PER_34XX_BASE + 0x30000)
static struct dsp_wdt_setting dsp_wdt;
void dsp_wdt_dpc(unsigned long data)
{
struct deh_mgr *deh_mgr;
dev_get_deh_mgr(dev_get_first(), &deh_mgr);
if (deh_mgr)
bridge_deh_notify(deh_mgr, DSP_WDTOVERFLOW, 0);
}
irqreturn_t dsp_wdt_isr(int irq, void *data)
{
u32 value;
/* ack wdt3 interrupt */
value = __raw_readl(dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
__raw_writel(value, dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
tasklet_schedule(&dsp_wdt.wdt3_tasklet);
return IRQ_HANDLED;
}
int dsp_wdt_init(void)
{
int ret = 0;
dsp_wdt.sm_wdt = NULL;
dsp_wdt.reg_base = OMAP2_L4_IO_ADDRESS(OMAP34XX_WDT3_BASE);
tasklet_init(&dsp_wdt.wdt3_tasklet, dsp_wdt_dpc, 0);
dsp_wdt.fclk = clk_get(NULL, "wdt3_fck");
if (dsp_wdt.fclk) {
dsp_wdt.iclk = clk_get(NULL, "wdt3_ick");
if (!dsp_wdt.iclk) {
clk_put(dsp_wdt.fclk);
dsp_wdt.fclk = NULL;
ret = -EFAULT;
}
} else
ret = -EFAULT;
if (!ret)
ret = request_irq(INT_34XX_WDT3_IRQ, dsp_wdt_isr, 0,
"dsp_wdt", &dsp_wdt);
/* Disable at this moment, it will be enabled when DSP starts */
if (!ret)
disable_irq(INT_34XX_WDT3_IRQ);
return ret;
}
void dsp_wdt_sm_set(void *data)
{
dsp_wdt.sm_wdt = data;
dsp_wdt.sm_wdt->wdt_overflow = CONFIG_WDT_TIMEOUT;
}
void dsp_wdt_exit(void)
{
free_irq(INT_34XX_WDT3_IRQ, &dsp_wdt);
tasklet_kill(&dsp_wdt.wdt3_tasklet);
if (dsp_wdt.fclk)
clk_put(dsp_wdt.fclk);
if (dsp_wdt.iclk)
clk_put(dsp_wdt.iclk);
dsp_wdt.fclk = NULL;
dsp_wdt.iclk = NULL;
dsp_wdt.sm_wdt = NULL;
dsp_wdt.reg_base = NULL;
}
void dsp_wdt_enable(bool enable)
{
u32 tmp;
static bool wdt_enable;
if (wdt_enable == enable || !dsp_wdt.fclk || !dsp_wdt.iclk)
return;
wdt_enable = enable;
if (enable) {
clk_enable(dsp_wdt.fclk);
clk_enable(dsp_wdt.iclk);
dsp_wdt.sm_wdt->wdt_setclocks = 1;
tmp = __raw_readl(dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
__raw_writel(tmp, dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
enable_irq(INT_34XX_WDT3_IRQ);
} else {
disable_irq(INT_34XX_WDT3_IRQ);
dsp_wdt.sm_wdt->wdt_setclocks = 0;
clk_disable(dsp_wdt.iclk);
clk_disable(dsp_wdt.fclk);
}
}
#else
void dsp_wdt_enable(bool enable)
{
}
void dsp_wdt_sm_set(void *data)
{
}
int dsp_wdt_init(void)
{
return 0;
}
void dsp_wdt_exit(void)
{
}
#endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册