sun4i_tcon.h 8.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 * Copyright (C) 2015 Free Electrons
 * Copyright (C) 2015 NextThing Co
 *
 * Boris Brezillon <boris.brezillon@free-electrons.com>
 * Maxime Ripard <maxime.ripard@free-electrons.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 */

#ifndef __SUN4I_TCON_H__
#define __SUN4I_TCON_H__

#include <drm/drm_crtc.h>

#include <linux/kernel.h>
20
#include <linux/list.h>
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
#include <linux/reset.h>

#define SUN4I_TCON_GCTL_REG			0x0
#define SUN4I_TCON_GCTL_TCON_ENABLE			BIT(31)
#define SUN4I_TCON_GCTL_IOMAP_MASK			BIT(0)
#define SUN4I_TCON_GCTL_IOMAP_TCON1			(1 << 0)
#define SUN4I_TCON_GCTL_IOMAP_TCON0			(0 << 0)

#define SUN4I_TCON_GINT0_REG			0x4
#define SUN4I_TCON_GINT0_VBLANK_ENABLE(pipe)		BIT(31 - (pipe))
#define SUN4I_TCON_GINT0_VBLANK_INT(pipe)		BIT(15 - (pipe))

#define SUN4I_TCON_GINT1_REG			0x8
#define SUN4I_TCON_FRM_CTL_REG			0x10

#define SUN4I_TCON0_CTL_REG			0x40
#define SUN4I_TCON0_CTL_TCON_ENABLE			BIT(31)
#define SUN4I_TCON0_CTL_CLK_DELAY_MASK			GENMASK(8, 4)
#define SUN4I_TCON0_CTL_CLK_DELAY(delay)		((delay << 4) & SUN4I_TCON0_CTL_CLK_DELAY_MASK)
40
#define SUN4I_TCON0_CTL_SRC_SEL_MASK			GENMASK(2, 0)
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55

#define SUN4I_TCON0_DCLK_REG			0x44
#define SUN4I_TCON0_DCLK_GATE_BIT			(31)
#define SUN4I_TCON0_DCLK_DIV_SHIFT			(0)
#define SUN4I_TCON0_DCLK_DIV_WIDTH			(7)

#define SUN4I_TCON0_BASIC0_REG			0x48
#define SUN4I_TCON0_BASIC0_X(width)			((((width) - 1) & 0xfff) << 16)
#define SUN4I_TCON0_BASIC0_Y(height)			(((height) - 1) & 0xfff)

#define SUN4I_TCON0_BASIC1_REG			0x4c
#define SUN4I_TCON0_BASIC1_H_TOTAL(total)		((((total) - 1) & 0x1fff) << 16)
#define SUN4I_TCON0_BASIC1_H_BACKPORCH(bp)		(((bp) - 1) & 0xfff)

#define SUN4I_TCON0_BASIC2_REG			0x50
56
#define SUN4I_TCON0_BASIC2_V_TOTAL(total)		(((total) & 0x1fff) << 16)
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
#define SUN4I_TCON0_BASIC2_V_BACKPORCH(bp)		(((bp) - 1) & 0xfff)

#define SUN4I_TCON0_BASIC3_REG			0x54
#define SUN4I_TCON0_BASIC3_H_SYNC(width)		((((width) - 1) & 0x7ff) << 16)
#define SUN4I_TCON0_BASIC3_V_SYNC(height)		(((height) - 1) & 0x7ff)

#define SUN4I_TCON0_HV_IF_REG			0x58
#define SUN4I_TCON0_CPU_IF_REG			0x60
#define SUN4I_TCON0_CPU_WR_REG			0x64
#define SUN4I_TCON0_CPU_RD0_REG			0x68
#define SUN4I_TCON0_CPU_RDA_REG			0x6c
#define SUN4I_TCON0_TTL0_REG			0x70
#define SUN4I_TCON0_TTL1_REG			0x74
#define SUN4I_TCON0_TTL2_REG			0x78
#define SUN4I_TCON0_TTL3_REG			0x7c
#define SUN4I_TCON0_TTL4_REG			0x80
M
Maxime Ripard 已提交
73

74
#define SUN4I_TCON0_LVDS_IF_REG			0x84
M
Maxime Ripard 已提交
75 76 77 78 79 80 81 82 83 84 85 86 87
#define SUN4I_TCON0_LVDS_IF_EN				BIT(31)
#define SUN4I_TCON0_LVDS_IF_BITWIDTH_MASK		BIT(26)
#define SUN4I_TCON0_LVDS_IF_BITWIDTH_18BITS		(1 << 26)
#define SUN4I_TCON0_LVDS_IF_BITWIDTH_24BITS		(0 << 26)
#define SUN4I_TCON0_LVDS_IF_CLK_SEL_MASK		BIT(20)
#define SUN4I_TCON0_LVDS_IF_CLK_SEL_TCON0		(1 << 20)
#define SUN4I_TCON0_LVDS_IF_CLK_POL_MASK		BIT(4)
#define SUN4I_TCON0_LVDS_IF_CLK_POL_NORMAL		(1 << 4)
#define SUN4I_TCON0_LVDS_IF_CLK_POL_INV			(0 << 4)
#define SUN4I_TCON0_LVDS_IF_DATA_POL_MASK		GENMASK(3, 0)
#define SUN4I_TCON0_LVDS_IF_DATA_POL_NORMAL		(0xf)
#define SUN4I_TCON0_LVDS_IF_DATA_POL_INV		(0)

88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
#define SUN4I_TCON0_IO_POL_REG			0x88
#define SUN4I_TCON0_IO_POL_DCLK_PHASE(phase)		((phase & 3) << 28)
#define SUN4I_TCON0_IO_POL_HSYNC_POSITIVE		BIT(25)
#define SUN4I_TCON0_IO_POL_VSYNC_POSITIVE		BIT(24)

#define SUN4I_TCON0_IO_TRI_REG			0x8c
#define SUN4I_TCON0_IO_TRI_HSYNC_DISABLE		BIT(25)
#define SUN4I_TCON0_IO_TRI_VSYNC_DISABLE		BIT(24)
#define SUN4I_TCON0_IO_TRI_DATA_PINS_DISABLE(pins)	GENMASK(pins, 0)

#define SUN4I_TCON1_CTL_REG			0x90
#define SUN4I_TCON1_CTL_TCON_ENABLE			BIT(31)
#define SUN4I_TCON1_CTL_INTERLACE_ENABLE		BIT(20)
#define SUN4I_TCON1_CTL_CLK_DELAY_MASK			GENMASK(8, 4)
#define SUN4I_TCON1_CTL_CLK_DELAY(delay)		((delay << 4) & SUN4I_TCON1_CTL_CLK_DELAY_MASK)
103
#define SUN4I_TCON1_CTL_SRC_SEL_MASK			GENMASK(1, 0)
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 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147

#define SUN4I_TCON1_BASIC0_REG			0x94
#define SUN4I_TCON1_BASIC0_X(width)			((((width) - 1) & 0xfff) << 16)
#define SUN4I_TCON1_BASIC0_Y(height)			(((height) - 1) & 0xfff)

#define SUN4I_TCON1_BASIC1_REG			0x98
#define SUN4I_TCON1_BASIC1_X(width)			((((width) - 1) & 0xfff) << 16)
#define SUN4I_TCON1_BASIC1_Y(height)			(((height) - 1) & 0xfff)

#define SUN4I_TCON1_BASIC2_REG			0x9c
#define SUN4I_TCON1_BASIC2_X(width)			((((width) - 1) & 0xfff) << 16)
#define SUN4I_TCON1_BASIC2_Y(height)			(((height) - 1) & 0xfff)

#define SUN4I_TCON1_BASIC3_REG			0xa0
#define SUN4I_TCON1_BASIC3_H_TOTAL(total)		((((total) - 1) & 0x1fff) << 16)
#define SUN4I_TCON1_BASIC3_H_BACKPORCH(bp)		(((bp) - 1) & 0xfff)

#define SUN4I_TCON1_BASIC4_REG			0xa4
#define SUN4I_TCON1_BASIC4_V_TOTAL(total)		(((total) & 0x1fff) << 16)
#define SUN4I_TCON1_BASIC4_V_BACKPORCH(bp)		(((bp) - 1) & 0xfff)

#define SUN4I_TCON1_BASIC5_REG			0xa8
#define SUN4I_TCON1_BASIC5_H_SYNC(width)		((((width) - 1) & 0x3ff) << 16)
#define SUN4I_TCON1_BASIC5_V_SYNC(height)		(((height) - 1) & 0x3ff)

#define SUN4I_TCON1_IO_POL_REG			0xf0
#define SUN4I_TCON1_IO_TRI_REG			0xf4
#define SUN4I_TCON_CEU_CTL_REG			0x100
#define SUN4I_TCON_CEU_MUL_RR_REG		0x110
#define SUN4I_TCON_CEU_MUL_RG_REG		0x114
#define SUN4I_TCON_CEU_MUL_RB_REG		0x118
#define SUN4I_TCON_CEU_ADD_RC_REG		0x11c
#define SUN4I_TCON_CEU_MUL_GR_REG		0x120
#define SUN4I_TCON_CEU_MUL_GG_REG		0x124
#define SUN4I_TCON_CEU_MUL_GB_REG		0x128
#define SUN4I_TCON_CEU_ADD_GC_REG		0x12c
#define SUN4I_TCON_CEU_MUL_BR_REG		0x130
#define SUN4I_TCON_CEU_MUL_BG_REG		0x134
#define SUN4I_TCON_CEU_MUL_BB_REG		0x138
#define SUN4I_TCON_CEU_ADD_BC_REG		0x13c
#define SUN4I_TCON_CEU_RANGE_R_REG		0x140
#define SUN4I_TCON_CEU_RANGE_G_REG		0x144
#define SUN4I_TCON_CEU_RANGE_B_REG		0x148
#define SUN4I_TCON_MUX_CTRL_REG			0x200
M
Maxime Ripard 已提交
148 149 150 151 152 153 154 155 156 157

#define SUN4I_TCON0_LVDS_ANA0_REG		0x220
#define SUN6I_TCON0_LVDS_ANA0_EN_MB			BIT(31)
#define SUN6I_TCON0_LVDS_ANA0_EN_LDO			BIT(30)
#define SUN6I_TCON0_LVDS_ANA0_EN_DRVC			BIT(24)
#define SUN6I_TCON0_LVDS_ANA0_EN_DRVD(x)		(((x) & 0xf) << 20)
#define SUN6I_TCON0_LVDS_ANA0_C(x)			(((x) & 3) << 17)
#define SUN6I_TCON0_LVDS_ANA0_V(x)			(((x) & 3) << 8)
#define SUN6I_TCON0_LVDS_ANA0_PD(x)			(((x) & 3) << 4)

158 159 160 161 162 163 164 165 166 167 168 169 170 171
#define SUN4I_TCON1_FILL_CTL_REG		0x300
#define SUN4I_TCON1_FILL_BEG0_REG		0x304
#define SUN4I_TCON1_FILL_END0_REG		0x308
#define SUN4I_TCON1_FILL_DATA0_REG		0x30c
#define SUN4I_TCON1_FILL_BEG1_REG		0x310
#define SUN4I_TCON1_FILL_END1_REG		0x314
#define SUN4I_TCON1_FILL_DATA1_REG		0x318
#define SUN4I_TCON1_FILL_BEG2_REG		0x31c
#define SUN4I_TCON1_FILL_END2_REG		0x320
#define SUN4I_TCON1_FILL_DATA2_REG		0x324
#define SUN4I_TCON1_GAMMA_TABLE_REG		0x400

#define SUN4I_TCON_MAX_CHANNELS		2

172 173
struct sun4i_tcon;

174
struct sun4i_tcon_quirks {
175
	bool	has_channel_0;	/* a83t does not have channel 0 on second TCON */
176
	bool	has_channel_1;	/* a33 does not have channel 1 */
M
Maxime Ripard 已提交
177
	bool	has_lvds_alt;	/* Does the LVDS clock have a parent other than the TCON clock? */
178
	bool	needs_de_be_mux; /* sun6i needs mux to select backend */
179
	bool    needs_edp_reset; /* a80 edp reset needed for tcon0 access */
180 181

	/* callback to handle tcon muxing options */
182
	int	(*set_mux)(struct sun4i_tcon *, const struct drm_encoder *);
183 184
};

185
struct sun4i_tcon {
186
	struct device			*dev;
187 188 189 190 191 192 193 194 195 196
	struct drm_device		*drm;
	struct regmap			*regs;

	/* Main bus clock */
	struct clk			*clk;

	/* Clocks for the TCON channels */
	struct clk			*sclk0;
	struct clk			*sclk1;

M
Maxime Ripard 已提交
197 198 199
	/* Possible mux for the LVDS clock */
	struct clk			*lvds_pll;

200 201
	/* Pixel clock */
	struct clk			*dclk;
202 203
	u8				dclk_max_div;
	u8				dclk_min_div;
204 205 206

	/* Reset control */
	struct reset_control		*lcd_rst;
M
Maxime Ripard 已提交
207
	struct reset_control		*lvds_rst;
208

M
Maxime Ripard 已提交
209
	struct drm_panel		*panel;
210

211 212
	/* Platform adjustments */
	const struct sun4i_tcon_quirks	*quirks;
213 214 215

	/* Associated crtc */
	struct sun4i_crtc		*crtc;
216

217 218
	int				id;

219 220
	/* TCON list management */
	struct list_head		list;
221 222
};

M
Maxime Ripard 已提交
223
struct drm_bridge *sun4i_tcon_find_bridge(struct device_node *node);
224 225
struct drm_panel *sun4i_tcon_find_panel(struct device_node *node);

226
void sun4i_tcon_enable_vblank(struct sun4i_tcon *tcon, bool enable);
227 228 229
void sun4i_tcon_mode_set(struct sun4i_tcon *tcon,
			 const struct drm_encoder *encoder,
			 const struct drm_display_mode *mode);
230 231
void sun4i_tcon_set_status(struct sun4i_tcon *crtc,
			   const struct drm_encoder *encoder, bool enable);
232

233 234
extern const struct of_device_id sun4i_tcon_of_table[];

235
#endif /* __SUN4I_TCON_H__ */