14
#include <drivers/common/memory.h>
15
#include <drivers/video/fb.h>
16
#include <drivers/clk/ccm_imx6.h>
17
#include <kernel/irq.h>
21
#include "ipu_param_mem.h"
23
extern void _ipu_dc_init(struct ipu_soc *ipu, int dc_chan, int di, bool interlaced, uint32_t pixel_fmt);
24
extern void _ipu_dc_uninit(struct ipu_soc *ipu, int dc_chan);
25
extern void _ipu_init_dc_mappings(struct ipu_soc *ipu);
26
extern void _ipu_dp_dc_enable(struct ipu_soc *ipu, ipu_channel_t channel);
28
static struct ipu_soc ipu_soc;
30
#define idma_mask(ch) (1UL << (ch & 0x1F))
31
#define idma_is_set(ipu, reg, dma) (ipu_idmac_read(ipu, reg(dma)) & idma_mask(dma))
36
static void ipu_reset(void) {
37
#define SRC_BASE 0x20D8000
38
# define SRC_IPU_RESET (1 << 3)
39
REG32_ORIN(SRC_BASE, SRC_IPU_RESET);
42
if (!(REG32_LOAD(SRC_BASE) & SRC_IPU_RESET)) {
48
log_error("IPU reset timeout!\n");
50
log_debug("IPU reset ok!\n");
54
static int ipu_mem_reset(struct ipu_soc *ipu) {
57
ipu_cm_write(ipu, 0x807FFFFF, IPU_MEM_RST);
60
if (!(ipu_cm_read(ipu, IPU_MEM_RST) & (1u << 31)))
65
log_error("Failed to reset IPU internal memories");
71
struct ipu_soc *ipu_get() {
76
struct ipu_soc *ipu = ipu_get();
79
memset(ipu, 0, sizeof(struct ipu_soc));
81
ipu->cm_reg = (void*) IPU_BASE + IPU_CM_REG_BASE;
82
ipu->ic_reg = (void*) IPU_BASE + IPU_IC_REG_BASE;
83
ipu->idmac_reg = (void*) IPU_BASE + IPU_IDMAC_REG_BASE;
84
ipu->dp_reg = (void*) IPU_BASE + IPU_SRM_REG_BASE;
85
ipu->dc_reg = (void*) IPU_BASE + IPU_DC_REG_BASE;
86
ipu->dmfc_reg = (void*) IPU_BASE + IPU_DMFC_REG_BASE;
87
ipu->di_reg[0] = (void*) IPU_BASE + IPU_DI0_REG_BASE;
88
ipu->di_reg[1] = (void*) IPU_BASE + IPU_DI1_REG_BASE;
89
ipu->smfc_reg = (void*) IPU_BASE + IPU_SMFC_REG_BASE;
90
ipu->cpmem_base = (void*) IPU_BASE + IPU_CPMEM_REG_BASE;
91
ipu->tpmem_base = (void*) IPU_BASE + IPU_TPM_REG_BASE;
92
ipu->dc_tmpl_reg = (void*) IPU_BASE + IPU_DC_TMPL_REG_BASE;
93
ipu->vdi_reg = (void*) IPU_BASE + IPU_VDI_REG_BASE;
94
ipu->disp_base[1] = (void*) IPU_BASE + IPU_DISP1_BASE;
99
ipu_idmac_write(ipu, 0x0, IDMAC_WM_EN(0));
100
ipu_idmac_write(ipu, 0x0, IDMAC_WM_EN(32));
102
ipu_idmac_write(ipu, 0x0, IDMAC_WM_EN(0));
103
ipu_idmac_write(ipu, 0x0, IDMAC_WM_EN(32));
105
ipu_cm_write(ipu, 0xFFFFFFFF, IPU_CHA_CUR_BUF(0));
106
ipu_cm_write(ipu, 0xFFFFFFFF, IPU_CHA_CUR_BUF(32));
108
ipu_cm_write(ipu, 0x0, IPU_CHA_DB_MODE_SEL(0));
109
ipu_cm_write(ipu, 0x0, IPU_CHA_DB_MODE_SEL(32));
111
memset((void*) ipu->cpmem_base, 0, IPU_CPMEM_REG_LEN);
114
clk_enable("ipu1_di0");
115
clk_enable("ldb_di0");
119
_ipu_init_dc_mappings(ipu);
122
ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(5));
123
ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(6));
124
ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(9));
125
ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(10));
130
int32_t ipu_init_channel(struct ipu_soc *ipu, ipu_channel_t channel, ipu_channel_params_t *params) {
133
log_debug("init channel = %d", IPU_CHAN_VIDEO_IN_DMA(channel));
135
ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(5));
136
ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(6));
137
ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(9));
138
ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(10));
140
ipu->dc_di_assignment[5] = 0;
142
_ipu_dc_init(ipu, 5, 0, 0, IPU_PIX_FMT_RGB666);
147
void ipu_uninit_channel(struct ipu_soc *ipu, ipu_channel_t channel) {
150
_ipu_dc_uninit(ipu, 5);
152
ipu_conf = ipu_cm_read(ipu, IPU_CONF);
153
ipu_conf &= ~IPU_CONF_DC_EN;
154
ipu_conf &= ~IPU_CONF_DP_EN;
155
ipu_conf &= ~IPU_CONF_DMFC_EN;
156
ipu_conf &= ~IPU_CONF_DI0_EN;
157
ipu_cm_write(ipu, ipu_conf, IPU_CONF);
160
int32_t ipu_init_channel_buffer(struct ipu_soc *ipu, ipu_channel_t channel,
163
uint16_t width, uint16_t height,
165
dma_addr_t phyaddr_0) {
166
uint32_t dma_chan = IPU_CHAN_VIDEO_IN_DMA(channel);
168
assert(dma_chan == 23);
170
_ipu_ch_param_init(ipu, dma_chan, pixel_fmt, width, height, stride, 0, 0, 0,
176
int32_t ipu_enable_channel(struct ipu_soc *ipu, ipu_channel_t channel) {
179
uint32_t in_dma = IPU_CHAN_VIDEO_IN_DMA(channel);
181
assert(in_dma == 23);
183
ipu_conf = IPU_CONF_DP_EN | IPU_CONF_DC_EN | IPU_CONF_DMFC_EN;
184
ipu_conf |= IPU_CONF_DI0_EN;
185
ipu_cm_write(ipu, ipu_conf, IPU_CONF);
187
reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(in_dma));
188
ipu_idmac_write(ipu, reg | idma_mask(in_dma), IDMAC_CHA_EN(in_dma));
189
reg = ipu_idmac_read(ipu, IDMAC_WM_EN(in_dma));
190
ipu_idmac_write(ipu, reg | idma_mask(in_dma), IDMAC_WM_EN(in_dma));
192
_ipu_dp_dc_enable(ipu, channel);
194
ipu_cm_write(ipu, 0x1400000, IPU_DISP_GEN);
199
void _ipu_clear_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
201
uint32_t dma_ch = IPU_CHAN_VIDEO_IN_DMA(channel);
203
assert(dma_ch == 23);
205
ipu_cm_write(ipu, 0xF0300000, IPU_GPR);
206
ipu_cm_write(ipu, idma_mask(dma_ch), IPU_CHA_BUF0_RDY(dma_ch));
207
ipu_cm_write(ipu, 0x0, IPU_GPR);
210
void ipu_clear_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
212
_ipu_clear_buffer_ready(ipu, channel, type, bufNum);
215
int32_t ipu_disable_channel(struct ipu_soc *ipu, ipu_channel_t channel, bool wait_for_stop) {
217
uint32_t in_dma = IPU_CHAN_VIDEO_IN_DMA(channel);
219
assert(in_dma == 23);
221
reg = ipu_idmac_read(ipu, IDMAC_WM_EN(in_dma));
222
ipu_idmac_write(ipu, reg & ~idma_mask(in_dma), IDMAC_WM_EN(in_dma));
224
reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(in_dma));
225
ipu_idmac_write(ipu, reg & ~idma_mask(in_dma), IDMAC_CHA_EN(in_dma));
226
ipu_cm_write(ipu, idma_mask(in_dma), IPU_CHA_CUR_BUF(in_dma));
228
_ipu_clear_buffer_ready(ipu, channel, IPU_VIDEO_IN_BUFFER, 0);
233
void ipu_disable_irq(struct ipu_soc *ipu, uint32_t irq) {
236
reg = ipu_cm_read(ipu, IPUIRQ_2_CTRLREG(irq));
237
reg &= ~IPUIRQ_2_MASK(irq);
238
ipu_cm_write(ipu, reg, IPUIRQ_2_CTRLREG(irq));
241
void ipu_clear_irq(struct ipu_soc *ipu, uint32_t irq) {
242
ipu_cm_write(ipu, IPUIRQ_2_MASK(irq), IPUIRQ_2_STATREG(irq));
245
int ipu_request_irq(struct ipu_soc *ipu, uint32_t irq,
247
uint32_t irq_flags, const char *devname, void *dev_id) {
250
ipu_cm_write(ipu, IPUIRQ_2_MASK(irq), IPUIRQ_2_STATREG(irq));
251
reg = ipu_cm_read(ipu, IPUIRQ_2_CTRLREG(irq));
252
reg |= IPUIRQ_2_MASK(irq);
253
ipu_cm_write(ipu, reg, IPUIRQ_2_CTRLREG(irq));
258
void ipu_free_irq(struct ipu_soc *ipu, uint32_t irq, void *dev_id) {
261
reg = ipu_cm_read(ipu, IPUIRQ_2_CTRLREG(irq));
262
reg &= ~IPUIRQ_2_MASK(irq);
263
ipu_cm_write(ipu, reg, IPUIRQ_2_CTRLREG(irq));
266
PERIPH_MEMORY_DEFINE(ipu, IPU_BASE, 0x200000);
268
#define DCIC1_BASE 0x20E4000
269
#define DCIC2_BASE 0x20E8000
271
PERIPH_MEMORY_DEFINE(ipu_dcic1, DCIC1_BASE, 0x20);
273
PERIPH_MEMORY_DEFINE(ipu_dcic2, DCIC2_BASE, 0x20);
275
PERIPH_MEMORY_DEFINE(ipu_src, SRC_BASE, 0x4);