提交 f190be7f 编写于 作者: K Kristina Martšenko 提交者: Greg Kroah-Hartman

staging: tidspbridge: remove driver

The driver has been broken and disabled for several kernel versions now.
It doesn't have a maintainer anymore, and most of the people who've
worked on it have moved on. There's also still a long list of issues in
the TODO file before it can be moved out of staging. Until someone can
put in the work to make the driver work again and move it out of
staging, remove it from the kernel.
Signed-off-by: NKristina Martšenko <kristina.martsenko@gmail.com>
Cc: Omar Ramirez Luna <omar.ramirez@copitl.com>
Cc: Suman Anna <s-anna@ti.com>
Cc: Felipe Contreras <felipe.contreras@gmail.com>
Cc: Ohad Ben-Cohen <ohad@wizery.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
上级 cb3aadae
...@@ -8624,11 +8624,6 @@ W: http://www.linux-speakup.org/ ...@@ -8624,11 +8624,6 @@ W: http://www.linux-speakup.org/
S: Odd Fixes S: Odd Fixes
F: drivers/staging/speakup/ F: drivers/staging/speakup/
STAGING - TI DSP BRIDGE DRIVERS
M: Omar Ramirez Luna <omar.ramirez@copitl.com>
S: Odd Fixes
F: drivers/staging/tidspbridge/
STAGING - USB ENE SM/MS CARD READER DRIVER STAGING - USB ENE SM/MS CARD READER DRIVER
M: Al Cho <acho@novell.com> M: Al Cho <acho@novell.com>
S: Odd Fixes S: Odd Fixes
......
...@@ -74,8 +74,6 @@ source "drivers/staging/iio/Kconfig" ...@@ -74,8 +74,6 @@ source "drivers/staging/iio/Kconfig"
source "drivers/staging/xgifb/Kconfig" source "drivers/staging/xgifb/Kconfig"
source "drivers/staging/tidspbridge/Kconfig"
source "drivers/staging/quickstart/Kconfig" source "drivers/staging/quickstart/Kconfig"
source "drivers/staging/emxx_udc/Kconfig" source "drivers/staging/emxx_udc/Kconfig"
......
...@@ -31,7 +31,6 @@ obj-$(CONFIG_VME_BUS) += vme/ ...@@ -31,7 +31,6 @@ obj-$(CONFIG_VME_BUS) += vme/
obj-$(CONFIG_DX_SEP) += sep/ obj-$(CONFIG_DX_SEP) += sep/
obj-$(CONFIG_IIO) += iio/ obj-$(CONFIG_IIO) += iio/
obj-$(CONFIG_FB_XGI) += xgifb/ obj-$(CONFIG_FB_XGI) += xgifb/
obj-$(CONFIG_TIDSPBRIDGE) += tidspbridge/
obj-$(CONFIG_ACPI_QUICKSTART) += quickstart/ obj-$(CONFIG_ACPI_QUICKSTART) += quickstart/
obj-$(CONFIG_USB_EMXX) += emxx_udc/ obj-$(CONFIG_USB_EMXX) += emxx_udc/
obj-$(CONFIG_USB_ENESTORAGE) += keucr/ obj-$(CONFIG_USB_ENESTORAGE) += keucr/
......
TI DSP/Bridge Driver - Contributors File
The DSP/Bridge project wish to thank all of its contributors, current bridge
driver is the result of the work of all of them. If any name is accidentally
omitted, let us know by sending a mail to omar.ramirez@ti.com or
x095840@ti.com.
Please keep the following list in alphabetical order.
Suman Anna
Sripal Bagadia
Felipe Balbi
Ohad Ben-Cohen
Phil Carmody
Deepak Chitriki
Felipe Contreras
Hiroshi Doyu
Seth Forshee
Ivan Gomez Castellanos
Mark Grosen
Ramesh Gupta G
Fernando Guzman Lugo
Axel Haslam
Janet Head
Shivananda Hebbar
Hari Kanigeri
Tony Lindgren
Antonio Luna
Hari Nagalla
Nishanth Menon
Ameya Palande
Vijay Pasam
Gilbert Pitney
Omar Ramirez Luna
Ernesto Ramos
Chris Ring
Larry Schiefer
Rebecca Schultz Zavin
Bhavin Shah
Andy Shevchenko
Jeff Taylor
Roman Tereshonkov
Armando Uribe de Leon
Nischal Varide
Wenbiao Wang
Linux DSP/BIOS Bridge release
DSP/BIOS Bridge overview
========================
DSP/BIOS Bridge is designed for platforms that contain a GPP and one or more
attached DSPs. The GPP is considered the master or "host" processor, and the
attached DSPs are processing resources that can be utilized by applications
and drivers running on the GPP.
The abstraction that DSP/BIOS Bridge supplies, is a direct link between a GPP
program and a DSP task. This communication link is partitioned into two
types of sub-links: messaging (short, fixed-length packets) and data
streaming (multiple, large buffers). Each sub-link operates independently,
and features in-order delivery of data, meaning that messages are delivered
in the order they were submitted to the message link, and stream buffers are
delivered in the order they were submitted to the stream link.
In addition, a GPP client can specify what inputs and outputs a DSP task
uses. DSP tasks typically use message objects for passing control and status
information and stream objects for efficient streaming of real-time data.
GPP Software Architecture
=========================
A GPP application communicates with its associated DSP task running on the
DSP subsystem using the DSP/BIOS Bridge API. For example, a GPP audio
application can use the API to pass messages to a DSP task that is managing
data flowing from analog-to-digital converters (ADCs) to digital-to-analog
converters (DACs).
From the perspective of the GPP OS, the DSP is treated as just another
peripheral device. Most high level GPP OS typically support a device driver
model, whereby applications can safely access and share a hardware peripheral
through standard driver interfaces. Therefore, to allow multiple GPP
applications to share access to the DSP, the GPP side of DSP/BIOS Bridge
implements a device driver for the DSP.
Since driver interfaces are not always standard across GPP OS, and to provide
some level of interoperability of application code using DSP/BIOS Bridge
between GPP OS, DSP/BIOS Bridge provides a standard library of APIs which
wrap calls into the device driver. So, rather than calling GPP OS specific
driver interfaces, applications (and even other device drivers) can use the
standard API library directly.
DSP Software Architecture
=========================
For DSP/BIOS, DSP/BIOS Bridge adds a device-independent streaming I/O (STRM)
interface, a messaging interface (NODE), and a Resource Manager (RM) Server.
The RM Server runs as a task of DSP/BIOS and is subservient to commands
and queries from the GPP. It executes commands to start and stop DSP signal
processing nodes in response to GPP programs making requests through the
(GPP-side) API.
DSP tasks started by the RM Server are similar to any other DSP task with two
important differences: they must follow a specific task model consisting of
three C-callable functions (node create, execute, and delete), with specific
sets of arguments, and they have a pre-defined task environment established
by the RM Server.
Tasks started by the RM Server communicate using the STRM and NODE interfaces
and act as servers for their corresponding GPP clients, performing signal
processing functions as requested by messages sent by their GPP client.
Typically, a DSP task moves data from source devices to sink devices using
device independent I/O streams, performing application-specific processing
and transformations on the data while it is moved. For example, an audio
task might perform audio decompression (ADPCM, MPEG, CELP) on data received
from a GPP audio driver and then send the decompressed linear samples to a
digital-to-analog converter.
DSP/Bridge Error Code Guide
Success code is always taken as 0, except for one case where a success status
different than 0 can be possible, this is when enumerating a series of dsp
objects, if the enumeration doesn't have any more objects it is considered as a
successful case. In this case a positive ENODATA is returned (TODO: Change to
avoid this case).
Error codes are returned as a negative 1, if an specific code is expected, it
can be propagated to user space by reading errno symbol defined in errno.h, for
specific details on the implementation a copy of the standard used should be
read first.
The error codes used by this driver are:
[EPERM]
General driver failure.
According to the use case the following might apply:
- Device is in 'sleep/suspend' mode due to DPM.
- User cannot mark end of stream on an input channel.
- Requested operation is invalid for the node type.
- Invalid alignment for the node messaging buffer.
- The specified direction is invalid for the stream.
- Invalid stream mode.
[ENOENT]
The specified object or file was not found.
[ESRCH]
A shared memory buffer contained in a message or stream could not be mapped
to the GPP client process's virtual space.
[EIO]
Driver interface I/O error.
or:
- Unable to plug channel ISR for configured IRQ.
- No free I/O request packets are available.
[ENXIO]
Unable to find a named section in DSP executable or a non-existent memory
segment identifier was specified.
[EBADF]
General error for file handling:
- Unable to open file.
- Unable to read file.
- An error occurred while parsing the DSP executable file.
[ENOMEM]
A memory allocation failure occurred.
[EACCES]
- Unable to read content of DCD data section; this is typically caused by
improperly configured nodes.
- Unable to decode DCD data section content; this is typically caused by
changes to DSP/BIOS Bridge data structures.
- Unable to get pointer to DCD data section; this is typically caused by
improperly configured UUIDs.
- Unable to load file containing DCD data section; this is typically
caused by a missing COFF file.
- The specified COFF file does not contain a valid node registration
section.
[EFAULT]
Invalid pointer or handler.
[EEXIST]
Attempted to create a channel manager when one already exists.
[EINVAL]
Invalid argument.
[ESPIPE]
Symbol not found in the COFF file. DSPNode_Create will return this if
the iAlg function table for an xDAIS socket is not found in the COFF file.
In this case, force the symbol to be linked into the COFF file.
DSPNode_Create, DSPNode_Execute, and DSPNode_Delete will return this if
the create, execute, or delete phase function, respectively, could not be
found in the COFF file.
- No symbol table is loaded/found for this board.
- Unable to initialize the ZL COFF parsing module.
[EPIPE]
I/O is currently pending.
- End of stream was already requested on this output channel.
[EDOM]
A parameter is specified outside its valid range.
[ENOSYS]
The indicated operation is not supported.
[EIDRM]
During enumeration a change in the number or properties of the objects
has occurred.
[ECHRNG]
Attempt to created channel manager with too many channels or channel ID out
of range.
[EBADR]
The state of the specified object is incorrect for the requested operation.
- Invalid segment ID.
[ENODATA]
Unable to retrieve resource information from the registry.
- No more registry values.
[ETIME]
A timeout occurred before the requested operation could complete.
[ENOSR]
A stream has been issued the maximum number of buffers allowed in the
stream at once; buffers must be reclaimed from the stream before any more
can be issued.
- No free channels are available.
[EILSEQ]
Error occurred in a dynamic loader library function.
[EISCONN]
The Specified Connection already exists.
[ENOTCONN]
Nodes not connected.
[ETIMEDOUT]
Timeout occurred waiting for a response from the hardware.
- Wait for flush operation on an output channel timed out.
[ECONNREFUSED]
No more connections can be made for this node.
[EALREADY]
Channel is already in use.
[EREMOTEIO]
dwTimeOut parameter was CHNL_IOCNOWAIT, yet no I/O completions were
queued.
[ECANCELED]
I/O has been cancelled on this channel.
[ENOKEY]
Invalid subkey parameter.
- UUID not found in registry.
#
# DSP Bridge Driver Support
#
menuconfig TIDSPBRIDGE
tristate "DSP Bridge driver"
depends on ARCH_OMAP3 && !ARCH_MULTIPLATFORM && BROKEN
select MAILBOX
select OMAP2PLUS_MBOX
help
DSP/BIOS Bridge is designed for platforms that contain a GPP and
one or more attached DSPs. The GPP is considered the master or
"host" processor, and the attached DSPs are processing resources
that can be utilized by applications and drivers running on the GPP.
This driver depends on OMAP Mailbox (OMAP_MBOX_FWK).
config TIDSPBRIDGE_DVFS
bool "Enable Bridge Dynamic Voltage and Frequency Scaling (DVFS)"
depends on TIDSPBRIDGE && CPU_FREQ
help
DVFS allows DSP Bridge to initiate the operating point change to
scale the chip voltage and frequency in order to match the
performance and power consumption to the current processing
requirements.
config TIDSPBRIDGE_MEMPOOL_SIZE
hex "Physical memory pool size (Byte)"
depends on TIDSPBRIDGE
default 0x600000
help
Allocate specified size of memory at booting time to avoid allocation
failure under heavy memory fragmentation after some use time.
config TIDSPBRIDGE_RECOVERY
bool "Recovery Support"
depends on TIDSPBRIDGE
default y
help
In case of DSP fatal error, BRIDGE driver will try to
recover itself.
config TIDSPBRIDGE_CACHE_LINE_CHECK
bool "Check buffers to be 128 byte aligned"
depends on TIDSPBRIDGE
help
When the DSP processes data, the DSP cache controller loads 128-Byte
chunks (lines) from SDRAM and writes the data back in 128-Byte chunks.
If a DMM buffer does not start and end on a 128-Byte boundary, the data
preceding the start address (SA) from the 128-Byte boundary to the SA
and the data at addresses trailing the end address (EA) from the EA to
the next 128-Byte boundary will be loaded and written back as well.
This can lead to heap corruption. Say Y, to enforce the check for 128
byte alignment, buffers failing this check will be rejected.
config TIDSPBRIDGE_NTFY_PWRERR
bool "Notify power errors"
depends on TIDSPBRIDGE
help
Enable notifications to registered clients on the event of power error
trying to suspend bridge driver. Say Y, to signal this event as a fatal
error, this will require a bridge restart to recover.
config TIDSPBRIDGE_BACKTRACE
bool "Dump backtraces on fatal errors"
depends on TIDSPBRIDGE
help
Enable useful information to backtrace fatal errors. Say Y if you
want to dump information for testing purposes.
obj-$(CONFIG_TIDSPBRIDGE) += tidspbridge.o
libgen = gen/gh.o
libcore = core/chnl_sm.o core/msg_sm.o core/io_sm.o core/tiomap3430.o \
core/tiomap3430_pwr.o core/tiomap_io.o \
core/ue_deh.o core/wdt.o core/dsp-clock.o core/sync.o
libpmgr = pmgr/chnl.o pmgr/io.o pmgr/msg.o pmgr/cod.o pmgr/dev.o pmgr/dspapi.o \
pmgr/dmm.o pmgr/cmm.o pmgr/dbll.o
librmgr = rmgr/dbdcd.o rmgr/disp.o rmgr/drv.o rmgr/mgr.o rmgr/node.o \
rmgr/proc.o rmgr/pwr.o rmgr/rmm.o rmgr/strm.o rmgr/dspdrv.o \
rmgr/nldr.o rmgr/drv_interface.o
libdload = dynload/cload.o dynload/getsection.o dynload/reloc.o \
dynload/tramp.o
libhw = hw/hw_mmu.o
tidspbridge-y := $(libgen) $(libservices) $(libcore) $(libpmgr) $(librmgr) \
$(libdload) $(libhw)
#Machine dependent
ccflags-y += -D_TI_ -D_DB_TIOMAP -DTMS32060 \
-DTICFG_PROC_VER -DTICFG_EVM_TYPE -DCHNL_SMCLASS \
-DCHNL_MESSAGES -DUSE_LEVEL_1_MACROS
ccflags-y += -Idrivers/staging/tidspbridge/include
ccflags-y += -Idrivers/staging/tidspbridge/services
ccflags-y += -Idrivers/staging/tidspbridge/core
ccflags-y += -Idrivers/staging/tidspbridge/pmgr
ccflags-y += -Idrivers/staging/tidspbridge/rmgr
ccflags-y += -Idrivers/staging/tidspbridge/dynload
ccflags-y += -Idrivers/staging/tidspbridge/hw
ccflags-y += -Iarch/arm
* Migrate to (and if necessary, extend) existing upstream code such as
iommu, wdt, mcbsp, gptimers
* Decouple hardware-specific code (e.g. bridge_brd_start/stop/delete/monitor)
* DOFF binary loader: consider pushing to user space. at the very least
eliminate the direct filesystem access
* Eliminate general services and libraries - use or extend existing kernel
libraries instead (e.g. gcf/lcm in nldr.c, global helpers in gen/)
* Eliminate direct manipulation of OMAP_SYSC_BASE
* Eliminate DSP_SUCCEEDED macros and their imposed redundant indentations
(adopt the kernel way of checking for return values)
* Audit interfaces exposed to user space
* Audit and clean up header files folder
* Use kernel coding style
* checkpatch.pl fixes
* allocate ext_mem_pool from consistent memory instead of using ioremap
Please send any patches to Greg Kroah-Hartman <greg@kroah.com>
and Omar Ramirez Luna <omar.ramirez@ti.com>.
/*
* _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.
* Copyright (C) 2010 Felipe Contreras
*
* 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 *bridge_context; /* Bridge context. */
struct ntfy_object *ntfy_obj; /* NTFY object */
/* 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 <linux/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 *iomgr; /* IO manager */
struct list_head 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 list_head msg_free_list; /* Free MsgFrames ready to be filled */
struct list_head 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 *msg_mgr;
u32 max_msgs; /* Node message depth */
u32 msgq_id; /* Node environment pointer */
struct list_head msg_free_list; /* Free MsgFrames ready to be filled */
/* Filled MsgFramess waiting to be read */
struct list_head 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_
/*
* XXX These powerdomain.h/clockdomain.h includes are wrong and should
* be removed. No driver should call pwrdm_* or clkdm_* functions
* directly; they should rely on OMAP core code to do this.
*/
#include <mach-omap2/powerdomain.h>
#include <mach-omap2/clockdomain.h>
/*
* XXX These mach-omap2/ includes are wrong and should be removed. No
* driver should read or write to PRM/CM registers directly; they
* should rely on OMAP core code to do this.
*/
#include <mach-omap2/cm3xxx.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 Resources. */
#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 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 *dev_obj; /* Handle to Bridge device object. */
u32 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 dsp_ext_base_addr; /* See the comment above */
u32 api_reg_base; /* API mem map'd registers */
void __iomem *dsp_mmu_base; /* DSP MMU Mapped registers */
u32 api_clk_base; /* CLK Registers */
u32 dsp_clk_m2_base; /* DSP Clock Module m2 */
u32 public_rhea; /* Pub Rhea */
u32 int_addr; /* MB INTR reg */
u32 tc_endianism; /* TC Endianism register */
u32 test_base; /* DSP MMU Mapped registers */
u32 self_loop; /* Pointer to the selfloop */
u32 dsp_start_add; /* API Boot vector */
u32 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 brd_state; /* Last known board state. */
/* 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 typically 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,
void *pargs);
/*
* ======== sleep_dsp =========
* Places the DSP in DeepSleep.
*/
extern int sleep_dsp(struct bridge_dev_context *dev_context,
u32 dw_cmd, void *pargs);
/*
* ========interrupt_dsp========
* Sends an interrupt to DSP unconditionally.
*/
extern void interrupt_dsp(struct bridge_dev_context *dev_context,
u16 mb_val);
/*
* ======== wake_dsp =========
* Wakes up the DSP from DeepSleep
*/
extern int dsp_peripheral_clk_ctrl(struct bridge_dev_context
*dev_context, 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,
void *pargs);
/*
* ======== pre_scale_dsp ========
* Handle Pre Scale notification to DSP
*/
int pre_scale_dsp(struct bridge_dev_context *dev_context,
void *pargs);
/*
* ======== handle_constraints_set ========
* Handle constraints request from DSP
*/
int handle_constraints_set(struct bridge_dev_context *dev_context,
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 clock_id, 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.
*/
#define L4_34XX_BASE 0x48000000
#include <linux/types.h>
/* ----------------------------------- Host OS */
#include <dspbridge/host_os.h>
#include <plat/dmtimer.h>
#include <linux/platform_data/asoc-ti-mcbsp.h>
/* ----------------------------------- DSP/BIOS Bridge */
#include <dspbridge/dbdefs.h>
#include <dspbridge/drv.h>
#include <dspbridge/dev.h>
#include "_tiomap.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)
#define DM_TIMER_CLOCKS 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)
{
int i;
dsp_clock_disable_all(dsp_clocks);
for (i = 0; i < DM_TIMER_CLOCKS; i++)
omap_dm_timer_free(timer[i]);
clk_unprepare(iva2_clk);
clk_put(iva2_clk);
clk_unprepare(ssi.sst_fck);
clk_put(ssi.sst_fck);
clk_unprepare(ssi.ssr_fck);
clk_put(ssi.ssr_fck);
clk_unprepare(ssi.ick);
clk_put(ssi.ick);
}
/*
* ======== dsp_clk_init ========
* Purpose:
* Initialize CLK module.
*/
void dsp_clk_init(void)
{
static struct platform_device dspbridge_device;
int i, id;
dspbridge_device.dev.bus = &platform_bus_type;
for (i = 0, id = 5; i < DM_TIMER_CLOCKS; i++, id++)
timer[i] = omap_dm_timer_request_specific(id);
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);
else
clk_prepare(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);
} else {
clk_prepare(ssi.sst_fck);
clk_prepare(ssi.ssr_fck);
clk_prepare(ssi.ick);
}
}
/**
* 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(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:
status = omap_dm_timer_start(timer[clk_id - 1]);
break;
#ifdef CONFIG_SND_OMAP_SOC_MCBSP
case MCBSP_CLK:
omap_mcbsp_request(MCBSP_ID(clk_id));
omap2_mcbsp_set_clks_src(MCBSP_ID(clk_id), MCBSP_CLKS_PAD_SRC);
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 (!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(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:
status = omap_dm_timer_stop(timer[clk_id - 1]);
break;
#ifdef CONFIG_SND_OMAP_SOC_MCBSP
case MCBSP_CLK:
omap2_mcbsp_set_clks_src(MCBSP_ID(clk_id), MCBSP_CLKS_PRCM_SRC);
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 (!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);
}
此差异已折叠。
此差异已折叠。
/*
* sync.c
*
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
*
* Synchronization 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>
/* ----------------------------------- This */
#include <dspbridge/sync.h>
#include <dspbridge/ntfy.h>
DEFINE_SPINLOCK(sync_lock);
/**
* sync_set_event() - set or signal and specified event
* @event: Event to be set..
*
* set the @event, if there is an thread waiting for the event
* it will be waken up, this function only wakes one thread.
*/
void sync_set_event(struct sync_object *event)
{
spin_lock_bh(&sync_lock);
complete(&event->comp);
if (event->multi_comp)
complete(event->multi_comp);
spin_unlock_bh(&sync_lock);
}
/**
* sync_wait_on_multiple_events() - waits for multiple events to be set.
* @events: Array of events to wait for them.
* @count: number of elements of the array.
* @timeout timeout on waiting for the evetns.
* @pu_index index of the event set.
*
* These functions will wait until any of the array element is set or until
* timeout. In case of success the function will return 0 and
* @pu_index will store the index of the array element set or in case
* of timeout the function will return -ETIME or in case of
* interrupting by a signal it will return -EPERM.
*/
int sync_wait_on_multiple_events(struct sync_object **events,
unsigned count, unsigned timeout,
unsigned *index)
{
unsigned i;
int status = -EPERM;
struct completion m_comp;
init_completion(&m_comp);
if (SYNC_INFINITE == timeout)
timeout = MAX_SCHEDULE_TIMEOUT;
spin_lock_bh(&sync_lock);
for (i = 0; i < count; i++) {
if (completion_done(&events[i]->comp)) {
reinit_completion(&events[i]->comp);
*index = i;
spin_unlock_bh(&sync_lock);
status = 0;
goto func_end;
}
}
for (i = 0; i < count; i++)
events[i]->multi_comp = &m_comp;
spin_unlock_bh(&sync_lock);
if (!wait_for_completion_interruptible_timeout(&m_comp,
msecs_to_jiffies(timeout)))
status = -ETIME;
spin_lock_bh(&sync_lock);
for (i = 0; i < count; i++) {
if (completion_done(&events[i]->comp)) {
reinit_completion(&events[i]->comp);
*index = i;
status = 0;
}
events[i]->multi_comp = NULL;
}
spin_unlock_bh(&sync_lock);
func_end:
return status;
}
/**
* dsp_notifier_event() - callback function to nofity events
* @this: pointer to itself struct notifier_block
* @event: event to be notified.
* @data: Currently not used.
*
*/
int dsp_notifier_event(struct notifier_block *this, unsigned long event,
void *data)
{
struct ntfy_event *ne = container_of(this, struct ntfy_event,
noti_block);
if (ne->event & event)
sync_set_event(&ne->sync_obj);
return NOTIFY_OK;
}
此差异已折叠。
此差异已折叠。
/*
* 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_ctxt,
u8 *host_buff, u32 dsp_addr,
u32 ul_num_bytes, u32 mem_type);
/*
* ======== write_dsp_data ========
*/
extern int write_dsp_data(struct bridge_dev_context *dev_context,
u8 *host_buff, u32 dsp_addr,
u32 ul_num_bytes, u32 mem_type);
/*
* ======== 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,
u8 *host_buff, u32 dsp_addr,
u32 ul_num_bytes, u32 mem_type,
bool dynamic_load);
/*
* ======== write_ext32_bit_dsp_data ========
* Writes 32 bit data to the external memory
*/
extern inline void write_ext32_bit_dsp_data(const
struct bridge_dev_context *dev_context,
u32 dsp_addr, u32 val)
{
*(u32 *) dsp_addr = ((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(const struct bridge_dev_context
*dev_context, u32 dsp_addr)
{
u32 ret;
ret = *(u32 *) dsp_addr;
ret = ((dev_context->tc_word_swap_on) ? (((ret << 16)
& 0xFFFF0000) | ((ret >> 16) &
0x0000FFFF))
: ret);
return ret;
}
#endif /* _TIOMAP_IO_ */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
/*
* header.h
*
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
*
* 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.
*/
#include <linux/string.h>
#define DL_STRCMP strcmp
/* maximum parenthesis nesting in relocation stack expressions */
#define STATIC_EXPR_STK_SIZE 10
#include <linux/types.h>
#include "doff.h"
#include <dspbridge/dynamic_loader.h>
#include "params.h"
#include "dload_internal.h"
#include "reloc_table.h"
/*
* Plausibility limits
*
* These limits are imposed upon the input DOFF file as a check for validity.
* They are hard limits, in that the load will fail if they are exceeded.
* The numbers selected are arbitrary, in that the loader implementation does
* not require these limits.
*/
/* maximum number of bytes in string table */
#define MAX_REASONABLE_STRINGTAB (0x100000)
/* maximum number of code,data,etc. sections */
#define MAX_REASONABLE_SECTIONS (200)
/* maximum number of linker symbols */
#define MAX_REASONABLE_SYMBOLS (100000)
/* shift count to align F_BIG with DLOAD_LITTLE */
#define ALIGN_COFF_ENDIANNESS 7
#define ENDIANNESS_MASK (DF_BYTE_ORDER >> ALIGN_COFF_ENDIANNESS)
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
/*
* EasiGlobal.h
*
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
*
* Copyright (C) 2007 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 _EASIGLOBAL_H
#define _EASIGLOBAL_H
#include <linux/types.h>
/*
* DEFINE: READ_ONLY, WRITE_ONLY & READ_WRITE
*
* DESCRIPTION: Defines used to describe register types for EASI-checker tests.
*/
#define READ_ONLY 1
#define WRITE_ONLY 2
#define READ_WRITE 3
/*
* MACRO: _DEBUG_LEVEL1_EASI
*
* DESCRIPTION: A MACRO which can be used to indicate that a particular beach
* register access function was called.
*
* NOTE: We currently dont use this functionality.
*/
#define _DEBUG_LEVEL1_EASI(easi_num) ((void)0)
#endif /* _EASIGLOBAL_H */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
/*
* devdefs.h
*
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
*
* Definition of common include typedef between dspdefs.h and dev.h. Required
* to break circular dependency between Bridge driver and DEV include files.
*
* Copyright (C) 2008 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 DEVDEFS_
#define DEVDEFS_
/* Bridge Device Object */
struct dev_object;
#endif /* DEVDEFS_ */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册