2009-01-26 15:13:40 +02:00
/*
* omap iommu : main structures
*
* Copyright ( C ) 2008 - 2009 Nokia Corporation
*
* Written by Hiroshi DOYU < Hiroshi . DOYU @ nokia . com >
*
* This program 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 .
*/
# ifndef __MACH_IOMMU_H
# define __MACH_IOMMU_H
struct iotlb_entry {
u32 da ;
u32 pa ;
u32 pgsz , prsvd , valid ;
union {
u16 ap ;
struct {
u32 endian , elsz , mixed ;
} ;
} ;
} ;
struct iommu {
const char * name ;
struct module * owner ;
struct clk * clk ;
void __iomem * regbase ;
struct device * dev ;
2011-02-16 19:35:51 +00:00
void * isr_priv ;
2009-01-26 15:13:40 +02:00
unsigned int refcount ;
2011-06-02 01:46:12 +03:00
spinlock_t iommu_lock ; /* global for this whole object */
2009-01-26 15:13:40 +02:00
/*
* We don ' t change iopgd for a situation like pgd for a task ,
* but share it globally for each iommu .
*/
u32 * iopgd ;
spinlock_t page_table_lock ; /* protect iopgd */
int nr_tlb_entries ;
struct list_head mmap ;
struct mutex mmap_lock ; /* protect mmap */
2011-02-16 19:35:51 +00:00
int ( * isr ) ( struct iommu * obj , u32 da , u32 iommu_errs , void * priv ) ;
2009-01-26 15:13:40 +02:00
void * ctx ; /* iommu context: registres saved area */
2010-12-15 00:54:03 +00:00
u32 da_start ;
u32 da_end ;
2009-01-26 15:13:40 +02:00
} ;
struct cr_regs {
union {
struct {
u16 cam_l ;
u16 cam_h ;
} ;
u32 cam ;
} ;
union {
struct {
u16 ram_l ;
u16 ram_h ;
} ;
u32 ram ;
} ;
} ;
struct iotlb_lock {
short base ;
short vict ;
} ;
/* architecture specific functions */
struct iommu_functions {
unsigned long version ;
int ( * enable ) ( struct iommu * obj ) ;
void ( * disable ) ( struct iommu * obj ) ;
2010-05-24 02:01:51 +00:00
void ( * set_twl ) ( struct iommu * obj , bool on ) ;
2009-01-26 15:13:40 +02:00
u32 ( * fault_isr ) ( struct iommu * obj , u32 * ra ) ;
void ( * tlb_read_cr ) ( struct iommu * obj , struct cr_regs * cr ) ;
void ( * tlb_load_cr ) ( struct iommu * obj , struct cr_regs * cr ) ;
struct cr_regs * ( * alloc_cr ) ( struct iommu * obj , struct iotlb_entry * e ) ;
int ( * cr_valid ) ( struct cr_regs * cr ) ;
u32 ( * cr_to_virt ) ( struct cr_regs * cr ) ;
void ( * cr_to_e ) ( struct cr_regs * cr , struct iotlb_entry * e ) ;
ssize_t ( * dump_cr ) ( struct iommu * obj , struct cr_regs * cr , char * buf ) ;
u32 ( * get_pte_attr ) ( struct iotlb_entry * e ) ;
void ( * save_ctx ) ( struct iommu * obj ) ;
void ( * restore_ctx ) ( struct iommu * obj ) ;
2009-08-28 10:54:41 -07:00
ssize_t ( * dump_ctx ) ( struct iommu * obj , char * buf , ssize_t len ) ;
2009-01-26 15:13:40 +02:00
} ;
struct iommu_platform_data {
const char * name ;
const char * clk_name ;
const int nr_tlb_entries ;
2010-12-15 00:54:03 +00:00
u32 da_start ;
u32 da_end ;
2009-01-26 15:13:40 +02:00
} ;
2011-02-16 19:35:51 +00:00
/* IOMMU errors */
# define OMAP_IOMMU_ERR_TLB_MISS (1 << 0)
# define OMAP_IOMMU_ERR_TRANS_FAULT (1 << 1)
# define OMAP_IOMMU_ERR_EMU_MISS (1 << 2)
# define OMAP_IOMMU_ERR_TBLWALK_FAULT (1 << 3)
# define OMAP_IOMMU_ERR_MULTIHIT_FAULT (1 << 4)
2009-01-26 15:13:40 +02:00
# if defined(CONFIG_ARCH_OMAP1)
# error "iommu for this processor not implemented yet"
# else
2009-10-20 09:40:47 -07:00
# include <plat/iommu2.h>
2009-01-26 15:13:40 +02:00
# endif
/*
* utilities for super page ( 16 MB , 1 MB , 64 KB and 4 KB )
*/
# define iopgsz_max(bytes) \
( ( ( bytes ) > = SZ_16M ) ? SZ_16M : \
( ( bytes ) > = SZ_1M ) ? SZ_1M : \
( ( bytes ) > = SZ_64K ) ? SZ_64K : \
( ( bytes ) > = SZ_4K ) ? SZ_4K : 0 )
# define bytes_to_iopgsz(bytes) \
( ( ( bytes ) = = SZ_16M ) ? MMU_CAM_PGSZ_16M : \
( ( bytes ) = = SZ_1M ) ? MMU_CAM_PGSZ_1M : \
( ( bytes ) = = SZ_64K ) ? MMU_CAM_PGSZ_64K : \
( ( bytes ) = = SZ_4K ) ? MMU_CAM_PGSZ_4K : - 1 )
# define iopgsz_to_bytes(iopgsz) \
( ( ( iopgsz ) = = MMU_CAM_PGSZ_16M ) ? SZ_16M : \
( ( iopgsz ) = = MMU_CAM_PGSZ_1M ) ? SZ_1M : \
( ( iopgsz ) = = MMU_CAM_PGSZ_64K ) ? SZ_64K : \
( ( iopgsz ) = = MMU_CAM_PGSZ_4K ) ? SZ_4K : 0 )
# define iopgsz_ok(bytes) (bytes_to_iopgsz(bytes) >= 0)
/*
* global functions
*/
extern u32 iommu_arch_version ( void ) ;
extern void iotlb_cr_to_e ( struct cr_regs * cr , struct iotlb_entry * e ) ;
extern int iopgtable_store_entry ( struct iommu * obj , struct iotlb_entry * e ) ;
2011-02-16 19:35:51 +00:00
extern int iommu_set_isr ( const char * name ,
int ( * isr ) ( struct iommu * obj , u32 da , u32 iommu_errs ,
void * priv ) ,
void * isr_priv ) ;
2009-01-26 15:13:40 +02:00
extern void iommu_save_ctx ( struct iommu * obj ) ;
extern void iommu_restore_ctx ( struct iommu * obj ) ;
extern int install_iommu_arch ( const struct iommu_functions * ops ) ;
extern void uninstall_iommu_arch ( const struct iommu_functions * ops ) ;
extern int foreach_iommu_device ( void * data ,
int ( * fn ) ( struct device * , void * ) ) ;
2009-08-28 10:54:41 -07:00
extern ssize_t iommu_dump_ctx ( struct iommu * obj , char * buf , ssize_t len ) ;
extern size_t dump_tlb_entries ( struct iommu * obj , char * buf , ssize_t len ) ;
2011-06-02 01:46:12 +03:00
struct device * omap_find_iommu_device ( const char * name ) ;
2009-01-26 15:13:40 +02:00
# endif /* __MACH_IOMMU_H */