370 lines
10 KiB
C
370 lines
10 KiB
C
/*
|
|
* Copyright 2005-2016 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
*/
|
|
|
|
/*
|
|
* The code contained herein is licensed under the GNU General Public
|
|
* License. You may obtain a copy of the GNU General Public License
|
|
* Version 2 or later at the following locations:
|
|
*
|
|
* http://www.opensource.org/licenses/gpl-license.html
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
*/
|
|
#ifndef __INCLUDE_IPU_PRV_H__
|
|
#define __INCLUDE_IPU_PRV_H__
|
|
|
|
#include <linux/clkdev.h>
|
|
#include <linux/device.h>
|
|
#include <linux/fsl_devices.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/ipu-v3.h>
|
|
#include <linux/types.h>
|
|
|
|
#define MXC_IPU_MAX_NUM 2
|
|
#define MXC_DI_NUM_PER_IPU 2
|
|
|
|
/* Globals */
|
|
extern int dmfc_type_setup;
|
|
|
|
#define IDMA_CHAN_INVALID 0xFF
|
|
#define HIGH_RESOLUTION_WIDTH 1024
|
|
|
|
enum ipuv3_type {
|
|
IPUv3D, /* i.MX37 */
|
|
IPUv3EX, /* i.MX51 */
|
|
IPUv3M, /* i.MX53 */
|
|
IPUv3H, /* i.MX6Q/SDL */
|
|
};
|
|
|
|
#define IPU_MAX_VDI_IN_WIDTH(type) ({ (type) >= IPUv3M ? 968 : 720; })
|
|
|
|
struct ipu_irq_node {
|
|
irqreturn_t(*handler) (int, void *); /*!< the ISR */
|
|
const char *name; /*!< device associated with the interrupt */
|
|
void *dev_id; /*!< some unique information for the ISR */
|
|
__u32 flags; /*!< not used */
|
|
};
|
|
|
|
enum csc_type_t {
|
|
RGB2YUV = 0,
|
|
YUV2RGB,
|
|
RGB2RGB,
|
|
YUV2YUV,
|
|
CSC_NONE,
|
|
CSC_NUM
|
|
};
|
|
|
|
struct ipu_soc {
|
|
unsigned int id;
|
|
unsigned int devtype;
|
|
bool online;
|
|
|
|
/*clk*/
|
|
struct clk *ipu_clk;
|
|
struct clk *di_clk[2];
|
|
struct clk *di_clk_sel[2];
|
|
struct clk *pixel_clk[2];
|
|
bool pixel_clk_en[2];
|
|
struct clk *pixel_clk_sel[2];
|
|
struct clk *csi_clk[2];
|
|
struct clk *prg_clk;
|
|
|
|
/*irq*/
|
|
int irq_sync;
|
|
int irq_err;
|
|
struct ipu_irq_node irq_list[IPU_IRQ_COUNT];
|
|
|
|
/*reg*/
|
|
void __iomem *cm_reg;
|
|
void __iomem *idmac_reg;
|
|
void __iomem *dp_reg;
|
|
void __iomem *ic_reg;
|
|
void __iomem *dc_reg;
|
|
void __iomem *dc_tmpl_reg;
|
|
void __iomem *dmfc_reg;
|
|
void __iomem *di_reg[2];
|
|
void __iomem *smfc_reg;
|
|
void __iomem *csi_reg[2];
|
|
void __iomem *cpmem_base;
|
|
void __iomem *tpmem_base;
|
|
void __iomem *vdi_reg;
|
|
|
|
struct device *dev;
|
|
|
|
ipu_channel_t csi_channel[2];
|
|
ipu_channel_t using_ic_dirct_ch;
|
|
unsigned char dc_di_assignment[10];
|
|
bool sec_chan_en[IPU_MAX_CH];
|
|
bool thrd_chan_en[IPU_MAX_CH];
|
|
bool chan_is_interlaced[52];
|
|
uint32_t channel_init_mask;
|
|
uint32_t channel_enable_mask;
|
|
|
|
/*use count*/
|
|
int dc_use_count;
|
|
int dp_use_count;
|
|
int dmfc_use_count;
|
|
int smfc_use_count;
|
|
int ic_use_count;
|
|
int rot_use_count;
|
|
int vdi_use_count;
|
|
int di_use_count[2];
|
|
int csi_use_count[2];
|
|
|
|
struct mutex mutex_lock;
|
|
spinlock_t int_reg_spin_lock;
|
|
spinlock_t rdy_reg_spin_lock;
|
|
|
|
int dmfc_size_28;
|
|
int dmfc_size_29;
|
|
int dmfc_size_24;
|
|
int dmfc_size_27;
|
|
int dmfc_size_23;
|
|
|
|
enum csc_type_t fg_csc_type;
|
|
enum csc_type_t bg_csc_type;
|
|
bool color_key_4rgb;
|
|
bool dc_swap;
|
|
struct completion dc_comp;
|
|
struct completion csi_comp;
|
|
|
|
struct rot_mem {
|
|
void *vaddr;
|
|
dma_addr_t paddr;
|
|
int size;
|
|
} rot_dma[2];
|
|
|
|
int vdoa_en;
|
|
struct task_struct *thread[2];
|
|
|
|
/*
|
|
* Bypass reset to avoid display channel being
|
|
* stopped by probe since it may starts to work
|
|
* in bootloader.
|
|
*/
|
|
bool bypass_reset;
|
|
|
|
unsigned int ch0123_axi;
|
|
unsigned int ch23_axi;
|
|
unsigned int ch27_axi;
|
|
unsigned int ch28_axi;
|
|
unsigned int normal_axi;
|
|
|
|
bool smfc_idmac_12bit_3planar_bs_fixup; /* workaround little stripes */
|
|
};
|
|
|
|
struct ipu_channel {
|
|
u8 video_in_dma;
|
|
u8 alpha_in_dma;
|
|
u8 graph_in_dma;
|
|
u8 out_dma;
|
|
};
|
|
|
|
enum ipu_dmfc_type {
|
|
DMFC_NORMAL = 0,
|
|
DMFC_HIGH_RESOLUTION_DC,
|
|
DMFC_HIGH_RESOLUTION_DP,
|
|
DMFC_HIGH_RESOLUTION_ONLY_DP,
|
|
};
|
|
|
|
static inline int _ipu_is_smfc_chan(uint32_t dma_chan)
|
|
{
|
|
return dma_chan <= 3;
|
|
}
|
|
|
|
static inline u32 ipu_cm_read(struct ipu_soc *ipu, unsigned offset)
|
|
{
|
|
return readl(ipu->cm_reg + offset);
|
|
}
|
|
|
|
static inline void ipu_cm_write(struct ipu_soc *ipu,
|
|
u32 value, unsigned offset)
|
|
{
|
|
writel(value, ipu->cm_reg + offset);
|
|
}
|
|
|
|
static inline u32 ipu_idmac_read(struct ipu_soc *ipu, unsigned offset)
|
|
{
|
|
return readl(ipu->idmac_reg + offset);
|
|
}
|
|
|
|
static inline void ipu_idmac_write(struct ipu_soc *ipu,
|
|
u32 value, unsigned offset)
|
|
{
|
|
writel(value, ipu->idmac_reg + offset);
|
|
}
|
|
|
|
static inline u32 ipu_dc_read(struct ipu_soc *ipu, unsigned offset)
|
|
{
|
|
return readl(ipu->dc_reg + offset);
|
|
}
|
|
|
|
static inline void ipu_dc_write(struct ipu_soc *ipu,
|
|
u32 value, unsigned offset)
|
|
{
|
|
writel(value, ipu->dc_reg + offset);
|
|
}
|
|
|
|
static inline u32 ipu_dc_tmpl_read(struct ipu_soc *ipu, unsigned offset)
|
|
{
|
|
return readl(ipu->dc_tmpl_reg + offset);
|
|
}
|
|
|
|
static inline void ipu_dc_tmpl_write(struct ipu_soc *ipu,
|
|
u32 value, unsigned offset)
|
|
{
|
|
writel(value, ipu->dc_tmpl_reg + offset);
|
|
}
|
|
|
|
static inline u32 ipu_dmfc_read(struct ipu_soc *ipu, unsigned offset)
|
|
{
|
|
return readl(ipu->dmfc_reg + offset);
|
|
}
|
|
|
|
static inline void ipu_dmfc_write(struct ipu_soc *ipu,
|
|
u32 value, unsigned offset)
|
|
{
|
|
writel(value, ipu->dmfc_reg + offset);
|
|
}
|
|
|
|
static inline u32 ipu_dp_read(struct ipu_soc *ipu, unsigned offset)
|
|
{
|
|
return readl(ipu->dp_reg + offset);
|
|
}
|
|
|
|
static inline void ipu_dp_write(struct ipu_soc *ipu,
|
|
u32 value, unsigned offset)
|
|
{
|
|
writel(value, ipu->dp_reg + offset);
|
|
}
|
|
|
|
static inline u32 ipu_di_read(struct ipu_soc *ipu, int di, unsigned offset)
|
|
{
|
|
return readl(ipu->di_reg[di] + offset);
|
|
}
|
|
|
|
static inline void ipu_di_write(struct ipu_soc *ipu, int di,
|
|
u32 value, unsigned offset)
|
|
{
|
|
writel(value, ipu->di_reg[di] + offset);
|
|
}
|
|
|
|
static inline u32 ipu_csi_read(struct ipu_soc *ipu, int csi, unsigned offset)
|
|
{
|
|
return readl(ipu->csi_reg[csi] + offset);
|
|
}
|
|
|
|
static inline void ipu_csi_write(struct ipu_soc *ipu, int csi,
|
|
u32 value, unsigned offset)
|
|
{
|
|
writel(value, ipu->csi_reg[csi] + offset);
|
|
}
|
|
|
|
static inline u32 ipu_smfc_read(struct ipu_soc *ipu, unsigned offset)
|
|
{
|
|
return readl(ipu->smfc_reg + offset);
|
|
}
|
|
|
|
static inline void ipu_smfc_write(struct ipu_soc *ipu,
|
|
u32 value, unsigned offset)
|
|
{
|
|
writel(value, ipu->smfc_reg + offset);
|
|
}
|
|
|
|
static inline u32 ipu_vdi_read(struct ipu_soc *ipu, unsigned offset)
|
|
{
|
|
return readl(ipu->vdi_reg + offset);
|
|
}
|
|
|
|
static inline void ipu_vdi_write(struct ipu_soc *ipu,
|
|
u32 value, unsigned offset)
|
|
{
|
|
writel(value, ipu->vdi_reg + offset);
|
|
}
|
|
|
|
static inline u32 ipu_ic_read(struct ipu_soc *ipu, unsigned offset)
|
|
{
|
|
return readl(ipu->ic_reg + offset);
|
|
}
|
|
|
|
static inline void ipu_ic_write(struct ipu_soc *ipu,
|
|
u32 value, unsigned offset)
|
|
{
|
|
writel(value, ipu->ic_reg + offset);
|
|
}
|
|
|
|
int register_ipu_device(struct ipu_soc *ipu, int id);
|
|
void unregister_ipu_device(struct ipu_soc *ipu, int id);
|
|
ipu_color_space_t format_to_colorspace(uint32_t fmt);
|
|
bool ipu_pixel_format_has_alpha(uint32_t fmt);
|
|
|
|
void ipu_dump_registers(struct ipu_soc *ipu);
|
|
|
|
uint32_t _ipu_channel_status(struct ipu_soc *ipu, ipu_channel_t channel);
|
|
|
|
void ipu_disp_init(struct ipu_soc *ipu);
|
|
void _ipu_init_dc_mappings(struct ipu_soc *ipu);
|
|
int _ipu_dp_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t in_pixel_fmt,
|
|
uint32_t out_pixel_fmt);
|
|
void _ipu_dp_uninit(struct ipu_soc *ipu, ipu_channel_t channel);
|
|
void _ipu_dc_init(struct ipu_soc *ipu, int dc_chan, int di, bool interlaced, uint32_t pixel_fmt);
|
|
void _ipu_dc_uninit(struct ipu_soc *ipu, int dc_chan);
|
|
void _ipu_dp_dc_enable(struct ipu_soc *ipu, ipu_channel_t channel);
|
|
void _ipu_dp_dc_disable(struct ipu_soc *ipu, ipu_channel_t channel, bool swap);
|
|
void _ipu_dmfc_init(struct ipu_soc *ipu, int dmfc_type, int first);
|
|
void _ipu_dmfc_set_wait4eot(struct ipu_soc *ipu, int dma_chan, int width);
|
|
void _ipu_dmfc_set_burst_size(struct ipu_soc *ipu, int dma_chan, int burst_size);
|
|
int _ipu_disp_chan_is_interlaced(struct ipu_soc *ipu, ipu_channel_t channel);
|
|
|
|
void _ipu_ic_enable_task(struct ipu_soc *ipu, ipu_channel_t channel);
|
|
void _ipu_ic_disable_task(struct ipu_soc *ipu, ipu_channel_t channel);
|
|
int _ipu_ic_init_prpvf(struct ipu_soc *ipu, ipu_channel_params_t *params,
|
|
bool src_is_csi);
|
|
void _ipu_vdi_init(struct ipu_soc *ipu, ipu_channel_t channel, ipu_channel_params_t *params);
|
|
void _ipu_vdi_uninit(struct ipu_soc *ipu);
|
|
void _ipu_ic_uninit_prpvf(struct ipu_soc *ipu);
|
|
void _ipu_ic_init_rotate_vf(struct ipu_soc *ipu, ipu_channel_params_t *params);
|
|
void _ipu_ic_uninit_rotate_vf(struct ipu_soc *ipu);
|
|
void _ipu_ic_init_csi(struct ipu_soc *ipu, ipu_channel_params_t *params);
|
|
void _ipu_ic_uninit_csi(struct ipu_soc *ipu);
|
|
int _ipu_ic_init_prpenc(struct ipu_soc *ipu, ipu_channel_params_t *params,
|
|
bool src_is_csi);
|
|
void _ipu_ic_uninit_prpenc(struct ipu_soc *ipu);
|
|
void _ipu_ic_init_rotate_enc(struct ipu_soc *ipu, ipu_channel_params_t *params);
|
|
void _ipu_ic_uninit_rotate_enc(struct ipu_soc *ipu);
|
|
int _ipu_ic_init_pp(struct ipu_soc *ipu, ipu_channel_params_t *params);
|
|
void _ipu_ic_uninit_pp(struct ipu_soc *ipu);
|
|
void _ipu_ic_init_rotate_pp(struct ipu_soc *ipu, ipu_channel_params_t *params);
|
|
void _ipu_ic_uninit_rotate_pp(struct ipu_soc *ipu);
|
|
int _ipu_ic_idma_init(struct ipu_soc *ipu, int dma_chan, uint16_t width, uint16_t height,
|
|
int burst_size, ipu_rotate_mode_t rot);
|
|
void _ipu_vdi_toggle_top_field_man(struct ipu_soc *ipu);
|
|
int _ipu_csi_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t csi);
|
|
int _ipu_csi_set_mipi_di(struct ipu_soc *ipu, uint32_t num, uint32_t di_val, uint32_t csi);
|
|
void ipu_csi_set_test_generator(struct ipu_soc *ipu, bool active, uint32_t r_value,
|
|
uint32_t g_value, uint32_t b_value,
|
|
uint32_t pix_clk, uint32_t csi);
|
|
void _ipu_csi_ccir_err_detection_enable(struct ipu_soc *ipu, uint32_t csi);
|
|
void _ipu_csi_ccir_err_detection_disable(struct ipu_soc *ipu, uint32_t csi);
|
|
void _ipu_csi_wait4eof(struct ipu_soc *ipu, ipu_channel_t channel);
|
|
void _ipu_smfc_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t mipi_id, uint32_t csi);
|
|
void _ipu_smfc_set_burst_size(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t bs);
|
|
void _ipu_dp_set_csc_coefficients(struct ipu_soc *ipu, ipu_channel_t channel, int32_t param[][3]);
|
|
int32_t _ipu_disp_set_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
|
|
int16_t x_pos, int16_t y_pos);
|
|
int32_t _ipu_disp_get_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
|
|
int16_t *x_pos, int16_t *y_pos);
|
|
void _ipu_get(struct ipu_soc *ipu);
|
|
void _ipu_put(struct ipu_soc *ipu);
|
|
|
|
struct clk *clk_register_mux_pix_clk(struct device *dev, const char *name,
|
|
const char **parent_names, u8 num_parents, unsigned long flags,
|
|
u8 ipu_id, u8 di_id, u8 clk_mux_flags);
|
|
struct clk *clk_register_div_pix_clk(struct device *dev, const char *name,
|
|
const char *parent_name, unsigned long flags,
|
|
u8 ipu_id, u8 di_id, u8 clk_div_flags);
|
|
struct clk *clk_register_gate_pix_clk(struct device *dev, const char *name,
|
|
const char *parent_name, unsigned long flags,
|
|
u8 ipu_id, u8 di_id, u8 clk_gate_flags);
|
|
#endif /* __INCLUDE_IPU_PRV_H__ */
|