summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/armada/armada_crtc.h
blob: 4da56a171b13e4d886c630e28bb0cdca1fea2065 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
 * Copyright (C) 2012 Russell King
 *
 * 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 ARMADA_CRTC_H
#define ARMADA_CRTC_H

struct armada_gem_object;

struct armada_regs {
	uint32_t offset;
	uint32_t mask;
	uint32_t val;
};

#define armada_reg_queue_mod(_r, _i, _v, _m, _o)	\
	do {					\
		struct armada_regs *__reg = _r;	\
		__reg[_i].offset = _o;		\
		__reg[_i].mask = ~(_m);		\
		__reg[_i].val = _v;		\
		_i++;				\
	} while (0)

#define armada_reg_queue_set(_r, _i, _v, _o)	\
	armada_reg_queue_mod(_r, _i, _v, ~0, _o)

#define armada_reg_queue_end(_r, _i)		\
	armada_reg_queue_mod(_r, _i, 0, 0, ~0)

struct armada_crtc;
struct armada_plane;
struct armada_variant;

struct armada_plane_work {
	void (*fn)(struct armada_crtc *, struct armada_plane_work *);
	void (*cancel)(struct armada_crtc *, struct armada_plane_work *);
	bool need_kfree;
	struct drm_plane *plane;
	struct drm_framebuffer *old_fb;
	struct drm_pending_vblank_event *event;
	struct armada_regs regs[14];
};

struct armada_plane_state {
	u16 src_x;
	u16 src_y;
	u32 src_hw;
	u32 dst_hw;
	u32 dst_yx;
	u32 ctrl0;
	bool changed;
	bool vsync_update;
};

struct armada_plane {
	struct drm_plane	base;
	wait_queue_head_t	frame_wait;
	bool			next_work;
	struct armada_plane_work works[2];
	struct armada_plane_work *work;
	struct armada_plane_state state;
};
#define drm_to_armada_plane(p) container_of(p, struct armada_plane, base)

int armada_drm_plane_init(struct armada_plane *plane);
int armada_drm_plane_work_queue(struct armada_crtc *dcrtc,
	struct armada_plane_work *work);
int armada_drm_plane_work_wait(struct armada_plane *plane, long timeout);
void armada_drm_plane_work_cancel(struct armada_crtc *dcrtc,
	struct armada_plane *plane);
void armada_drm_plane_calc_addrs(u32 *addrs, struct drm_framebuffer *fb,
	int x, int y);

int armada_drm_plane_prepare_fb(struct drm_plane *plane,
	struct drm_plane_state *state);
void armada_drm_plane_cleanup_fb(struct drm_plane *plane,
	struct drm_plane_state *old_state);
int armada_drm_plane_atomic_check(struct drm_plane *plane,
	struct drm_plane_state *state);

struct armada_crtc {
	struct drm_crtc		crtc;
	const struct armada_variant *variant;
	unsigned		num;
	void __iomem		*base;
	struct clk		*clk;
	struct clk		*extclk[2];
	struct {
		uint32_t	spu_v_h_total;
		uint32_t	spu_v_porch;
		uint32_t	spu_adv_reg;
	} v[2];
	bool			interlaced;
	bool			cursor_update;
	uint8_t			csc_yuv_mode;
	uint8_t			csc_rgb_mode;

	struct drm_plane	*plane;

	struct armada_gem_object	*cursor_obj;
	int			cursor_x;
	int			cursor_y;
	uint32_t		cursor_hw_pos;
	uint32_t		cursor_hw_sz;
	uint32_t		cursor_w;
	uint32_t		cursor_h;

	int			dpms;
	uint32_t		cfg_dumb_ctrl;
	uint32_t		dumb_ctrl;
	uint32_t		spu_iopad_ctrl;

	spinlock_t		irq_lock;
	uint32_t		irq_ena;

	struct armada_regs	atomic_regs[32];
	struct armada_regs	*regs;
	unsigned int		regs_idx;
};
#define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc)

void armada_drm_crtc_update_regs(struct armada_crtc *, struct armada_regs *);

extern struct platform_driver armada_lcd_platform_driver;

#endif