embox

Форк
0
/
ipuv3_fb.c 
136 строк · 3.5 Кб
1
/**
2
 * @file ipuv3_fb.c
3
 * @brief Framebuffer for IPU (no regs/cloks/etc here)
4
 * @author Denis Deryugin <deryugin.denis@gmail.com>
5
 * @version
6
 * @date 05.10.2017
7
 */
8
#include <util/log.h>
9

10
#include <string.h>
11

12
#include <hal/cache.h>
13
#include <drivers/video/fb.h>
14
#include <embox/unit.h>
15
#include <kernel/irq.h>
16

17
#include "ipu_regs.h"
18
#include "ipu_priv.h"
19

20
#define IPU_MAX_WIDTH  OPTION_GET(NUMBER, xres)
21
#define IPU_MAX_HEIGHT OPTION_GET(NUMBER, yres)
22

23
/* TODO handle this other way! */
24
#define UPPER_MARGIN OPTION_GET(NUMBER, upper_margin)
25
#define LOWER_MARGIN OPTION_GET(NUMBER, lower_margin)
26
#define LEFT_MARGIN  OPTION_GET(NUMBER, left_margin)
27
#define RIGHT_MARGIN OPTION_GET(NUMBER, right_margin)
28
#define VSYNC_LEN    OPTION_GET(NUMBER, vsync_len)
29
#define HSYNC_LEN    OPTION_GET(NUMBER, hsync_len)
30

31
static uint16_t ipu_fb[IPU_MAX_WIDTH * IPU_MAX_HEIGHT]
32
			__attribute__ ((aligned (0x8)));
33

34
struct mxcfb_info {
35
	ipu_channel_t ipu_ch;
36
	int ipu_id;
37
	int ipu_di;
38
	void *ipu;
39

40
	struct fb_info *fbi;
41
};
42

43
static struct mxcfb_info mxc_fbi;
44

45
static int mxcfb_set_par(struct fb_info *fbi, const struct fb_var_screeninfo *var) {
46
	if (mxc_fbi.ipu_ch != MEM_BG_SYNC)
47
		return 0;
48

49
	ipu_disable_channel(mxc_fbi.ipu, mxc_fbi.ipu_ch, 0);
50
	ipu_uninit_channel(mxc_fbi.ipu, mxc_fbi.ipu_ch);
51

52
	fbi->screen_base = (void*) ipu_fb;
53
	fbi->screen_size = IPU_MAX_WIDTH * IPU_MAX_HEIGHT * 2;
54

55
	memset((char *)fbi->screen_base, 0x00, fbi->screen_size);
56

57
	ipu_init_channel(mxc_fbi.ipu, mxc_fbi.ipu_ch, 0);
58

59
	fbi->var = (struct fb_var_screeninfo) {
60
		.xres           = IPU_MAX_WIDTH,
61
		.yres           = IPU_MAX_HEIGHT,
62
		.bits_per_pixel = 16, /* Always use R5G6B5 */
63
		.upper_margin   = UPPER_MARGIN,
64
		.lower_margin   = LOWER_MARGIN,
65
		.left_margin    = LEFT_MARGIN,
66
		.right_margin   = RIGHT_MARGIN,
67
		.hsync_len      = HSYNC_LEN,
68
		.vsync_len      = VSYNC_LEN,
69
	};
70

71
	ipu_init_sync_panel(mxc_fbi.ipu, mxc_fbi.ipu_di,
72
				fbi,
73
				IPU_PIX_FMT_RGB666);
74

75
	ipu_init_channel_buffer(mxc_fbi.ipu,
76
					 mxc_fbi.ipu_ch, IPU_INPUT_BUFFER,
77
					 IPU_PIX_FMT_RGB565,
78
					 fbi->var.xres, fbi->var.yres,
79
					 fbi->var.xres * fbi->var.bits_per_pixel / 8,
80
					 (dma_addr_t) fbi->screen_base);
81

82
	ipu_enable_channel(mxc_fbi.ipu, mxc_fbi.ipu_ch);
83

84
	return 0;
85
}
86

87
static int mxcfb_set_base(struct fb_info *fbi, void *new_base) {
88
	ipu_init_channel_buffer(mxc_fbi.ipu,
89
					 mxc_fbi.ipu_ch, IPU_INPUT_BUFFER,
90
					 IPU_PIX_FMT_RGB565,
91
					 fbi->var.xres, fbi->var.yres,
92
					 fbi->var.xres * fbi->var.bits_per_pixel / 8,
93
					 (uint32_t) new_base);
94
	return 0;
95
}
96

97
static struct fb_ops mxcfb_ops = {
98
	.fb_set_var  = mxcfb_set_par,
99
	.fb_set_base = mxcfb_set_base,
100
};
101

102
static irq_return_t mxcfb_irq_handler(unsigned int irq, void *data) {
103
	struct ipu_soc *ipu = mxc_fbi.ipu;
104
	int i;
105
	uint32_t int_stat, int_ctrl;
106
	const int int_reg[] = { 1, 2, 3, 4, 11, 12, 13, 14, 15, 0 };
107

108
	dcache_flush(ipu_fb, sizeof(ipu_fb) * 2);
109

110
	for (i = 0; int_reg[i] != 0; i++) {
111
		int_stat = ipu_cm_read(ipu, IPU_INT_STAT(int_reg[i]));
112
		int_ctrl = ipu_cm_read(ipu, IPU_INT_CTRL(int_reg[i]));
113
		int_stat &= int_ctrl;
114
		ipu_cm_write(ipu, int_stat, IPU_INT_STAT(int_reg[i]));
115
	}
116

117
	return IRQ_HANDLED;
118
}
119

120
static int ipu_init(void) {
121
	ipu_probe();
122

123
	mxc_fbi.fbi    = fb_create(&mxcfb_ops,
124
			              (char *) ipu_fb,
125
				      2 * IPU_MAX_WIDTH * IPU_MAX_HEIGHT);
126
	mxc_fbi.ipu    = ipu_get();
127
	mxc_fbi.ipu_ch = MEM_BG_SYNC;
128

129
	irq_attach(IPU1_SYNC_IRQ, mxcfb_irq_handler, 0, NULL, "IPU framebuffer");
130
	ipu_request_irq(ipu_get(), 23, /*NULL,*/ 0, "", NULL);
131

132
	mxcfb_set_par(mxc_fbi.fbi, &mxc_fbi.fbi->var);
133

134
	return 0;
135
}
136
EMBOX_UNIT_INIT(ipu_init);
137

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.