blob: cd0105da6a8f0a987196e3517532db46f4a5bdd7 [file] [log] [blame] [edit]
/*
* Remote Processor Framework
*
* Copyright(c) 2011 Texas Instruments. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name Texas Instruments nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef REMOTEPROC_H
#define REMOTEPROC_H
#include <linux/mutex.h>
#include <linux/completion.h>
#include <linux/workqueue.h>
#include <linux/notifier.h>
#include <linux/pm_qos_params.h>
/* Must match the BIOS version embeded in the BIOS firmware image */
#define RPROC_BIOS_VERSION 2
/* Maximum number of entries that can be added for lookup */
#define RPROC_MAX_MEM_ENTRIES 20
/**
* The following enums and structures define the binary format of the images
* we load and run the remote processors with.
*
* The binary format is as follows:
*
* struct {
* char magic[4] = { 'R', 'P', 'R', 'C' };
* u32 version;
* u32 header_len;
* char header[...] = { header_len bytes of unformatted, textual header };
* struct section {
* u32 type;
* u64 da;
* u32 len;
* u8 content[...] = { len bytes of binary data };
* } [ no limit on number of sections ];
* } __packed;
*/
struct fw_header {
char magic[4];
u32 version;
u32 header_len;
char header[0];
} __packed;
struct fw_section {
u32 type;
u64 da;
u32 len;
char content[0];
} __packed;
enum fw_section_type {
FW_RESOURCE = 0,
FW_TEXT = 1,
FW_DATA = 2,
FW_MMU = 3,
FW_SIGNATURE = 4,
};
struct fw_resource {
u32 type;
u64 da;
u64 pa;
u32 len;
u32 reserved;
u8 name[48];
} __packed;
enum fw_resource_type {
RSC_CARVEOUT = 0,
RSC_DEVMEM = 1,
RSC_DEVICE = 2,
RSC_IRQ = 3,
RSC_TRACE = 4,
RSC_BOOTADDR = 5,
RSC_CRASHDUMP = 6,
RSC_END = 7,
};
/**
* struct rproc_mem_pool - descriptor for the rproc's contiguous memory pool data
*
* @mem_base: starting physical address of the dynamic pool
* @mem_size: size of the initial dynamic pool
* @cur_base: current available physical address in the pool
* @cur_size: remaining available memory in the pool
* @st_base: starting physical address of the static pool
* @st_size: size of the static pool
*/
struct rproc_mem_pool {
phys_addr_t mem_base;
u32 mem_size;
phys_addr_t cur_base;
u32 cur_size;
phys_addr_t st_base;
u32 st_size;
};
/**
* struct rproc_mem_entry - descriptor of a remote memory region
*
* @da: virtual address as seen by the device (aka device address)
* @pa: physical address
* @size: size of this memory region
*/
struct rproc_mem_entry {
u64 da;
phys_addr_t pa;
u32 size;
bool core;
};
enum rproc_constraint {
RPROC_CONSTRAINT_SCALE,
RPROC_CONSTRAINT_LATENCY,
RPROC_CONSTRAINT_BANDWIDTH,
};
struct rproc;
struct rproc_ops {
int (*start)(struct rproc *rproc, u64 bootaddr);
int (*stop)(struct rproc *rproc);
int (*suspend)(struct rproc *rproc, bool force);
int (*resume)(struct rproc *rproc);
int (*iommu_init)(struct rproc *, int (*)(struct rproc *, u64, u32));
int (*iommu_exit)(struct rproc *);
int (*set_lat)(struct rproc *rproc, long v);
int (*set_bw)(struct rproc *rproc, long v);
int (*scale)(struct rproc *rproc, long v);
int (*watchdog_init)(struct rproc *, int (*)(struct rproc *));
int (*watchdog_exit)(struct rproc *);
void (*dump_registers)(struct rproc *);
};
/*
* enum rproc_state - remote processor states
*
* @RPROC_OFFLINE: needs firmware load and init to exit this state.
*
* @RPROC_SUSPENDED: needs to be woken up to receive a message.
*
* @RPROC_RUNNING: up and running.
*
* @RPROC_LOADING: asynchronous firmware loading has started
*
* @RPROC_CRASHED: needs to be logged, connections torn down, resources
* released, and returned to OFFLINE.
*/
enum rproc_state {
RPROC_OFFLINE,
RPROC_SUSPENDED,
RPROC_RUNNING,
RPROC_LOADING,
RPROC_CRASHED,
};
/*
* enum rproc_event - remote processor events
*
* @RPROC_ERROR: Fatal error has happened on the remote processor.
*
* @RPROC_PRE_SUSPEND: users can register for that event in order to cancel
* autosuspend, they just need to return an error in the
* callback function.
*
* @RPROC_POS_SUSPEND: users can register for that event in order to release
* resources not needed when the remote processor is
* sleeping or if they need to save some context.
*
* @RPROC_RESUME: users should use this event to revert what was done in the
* POS_SUSPEND event.
*
* @RPROC_SECURE: remote processor secure mode has changed.
*/
enum rproc_event {
RPROC_ERROR,
RPROC_PRE_SUSPEND,
RPROC_POS_SUSPEND,
RPROC_RESUME,
RPROC_SECURE,
};
#define RPROC_MAX_NAME 100
/*
* struct rproc - a physical remote processor device
*
* @next: next rproc entry in the list
* @name: human readable name of the rproc, cannot exceed RPROC_MAX_NAME bytes
* @memory_maps: table of da-to-pa memory maps (relevant if device is behind
* an iommu)
* @memory_pool: platform-specific contiguous memory pool data (relevant for
* allocating memory needed for the remote processor image)
* @firmware: name of firmware file to be loaded
* @owner: reference to the platform-specific rproc module
* @priv: private data which belongs to the platform-specific rproc module
* @ops: platform-specific start/stop rproc handlers
* @dev: reference to the platform-specific rproc dev
* @count: usage refcount
* @state: rproc_state enum value representing the state of the device
* @lock: lock which protects concurrent manipulations of the rproc
* @dbg_dir: debugfs directory of this rproc device
* @trace_buf0: main trace buffer of the remote processor
* @trace_buf1: second, optional, trace buffer of the remote processor
* @trace_len0: length of main trace buffer of the remote processor
* @trace_len1: length of the second (and optional) trace buffer
* @cdump_buf0: main exception/crash dump buffer of the remote processor
* @cdump_buf1: second exception/crash dump buffer of the remote processor
* @cdump_len0: length of main crash dump buffer of the remote processor
* @cdump_len1: length of the second (and optional) crash dump buffer
* @firmware_loading_complete: flags e/o asynchronous firmware loading
* @mmufault_work: work in charge of notifing mmufault
* @nb_error: notify block for fatal errors
* @error_comp: completion used when an error happens
* @secure_ttb: private data for configuring iommu in secure mode
* @secure_restart: completion event notifier for the secure restart process
* @secure_mode: flag to dictate whether to enable secure loading
* @secure_ok: restart status flag to be looked up upon the event's completion
* @secure_reset: flag to uninstall the firewalls
*/
struct rproc {
struct list_head next;
const char *name;
struct rproc_mem_entry memory_maps[RPROC_MAX_MEM_ENTRIES];
struct rproc_mem_pool *memory_pool;
const char *firmware;
struct module *owner;
void *priv;
const struct rproc_ops *ops;
struct device *dev;
int count;
int state;
struct mutex lock;
struct dentry *dbg_dir;
char *trace_buf0, *trace_buf1;
char *last_trace_buf0, *last_trace_buf1;
int trace_len0, trace_len1;
int last_trace_len0, last_trace_len1;
void *cdump_buf0, *cdump_buf1;
int cdump_len0, cdump_len1;
struct mutex tlock;
struct completion firmware_loading_complete;
struct work_struct error_work;
struct blocking_notifier_head nbh;
struct completion error_comp;
#ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND
unsigned sus_timeout;
bool force_suspend;
bool need_resume;
struct mutex pm_lock;
#endif
struct pm_qos_request_list *qos_request;
void *secure_ttb;
struct completion secure_restart;
struct mutex secure_lock;
bool secure_mode;
bool secure_ok;
bool secure_reset;
bool halt_on_crash;
char *header;
int header_len;
};
int rproc_set_secure(const char *, bool);
struct rproc *rproc_get(const char *);
void rproc_put(struct rproc *);
int rproc_event_register(struct rproc *, struct notifier_block *);
int rproc_event_unregister(struct rproc *, struct notifier_block *);
int rproc_register(struct device *, const char *, const struct rproc_ops *,
const char *, struct rproc_mem_pool *, struct module *,
unsigned int timeout);
int rproc_unregister(const char *);
void rproc_last_busy(struct rproc *);
#ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND
extern const struct dev_pm_ops rproc_gen_pm_ops;
#define GENERIC_RPROC_PM_OPS (&rproc_gen_pm_ops)
#else
#define GENERIC_RPROC_PM_OPS NULL
#endif
int rproc_set_constraints(struct rproc *, enum rproc_constraint type, long v);
int rproc_error_notify(struct rproc *rproc);
#endif /* REMOTEPROC_H */