summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/imx/hdp/imx-hdp.h
blob: e115743283fe0eb186684dedfea50ebe2a14a243 (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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
/*
 * Copyright 2017 NXP
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
#ifndef _IMX_HDP_H_
#define _IMX_HDP_H_

#include <linux/regmap.h>
#include <linux/mutex.h>
#include <drm/drm_of.h>
#include <drm/drmP.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_encoder_slave.h>
#include <soc/imx8/sc/sci.h>

#include <drm/drm_dp_helper.h>
#include "../../../../mxc/hdp/all.h"

#define PLL_1188MHZ (1188000000)
#define PLL_675MHZ (675000000)

#define HDP_TX_SS_LIS_BASE   0x0000
#define HDP_TX_SS_CSR_BASE   0x1000
#define HDP_TX_SS_GPIO_BASE  0x2000
#define HDP_TX_SS_CTRL0_BASE 0x8000

#define CSR_PIXEL_LINK_MUX_CTL		0x00
#define PL_MUX_CTL_VCP_OFFSET		5
#define PL_MUX_CTL_HCP_OFFSET		4
#define PL_MUX_CTL_PL_MUX_OFFSET	2
#define PL_MUX_CTL_PL_SEL_OFFSET	0

#define CSR_PIXEL_LINK_MUX_STATUS	0x04
#define PL_MUX_STATUS_PL1_INT_OFFSET 18
#define PL_MUX_STATUS_PL1_ADD_OFFSET 16
#define PL_MUX_STATUS_PL1_TYP_OFFSET 11
#define PL_MUX_STATUS_PL0_INT_OFFSET 9
#define PL_MUX_STATUS_PL0_ADD_OFFSET 7
#define PL_MUX_STATUS_PL0_TYP_OFFSET 2
#define PL_MUX_STATUS_PL_DLY_OFFSET 0

#define CSR_HDP_TX_CTRL_CTRL0		0x08
#define CSR_HDP_TX_CTRL_CTRL1		0x0c

/**
 * imx_hdp_call - Calls a struct imx hdp_operations operation on
 *	an entity
 *
 * @entity: entity where the @operation will be called
 * @operation: type of the operation. Should be the name of a member of
 *	struct &media_entity_operations.
 *
 * This helper function will check if @operation is not %NULL. On such case,
 * it will issue a call to @operation\(@args\).
 */

#define imx_hdp_call(hdp, operation, args...)			\
	(!(hdp) ? -ENODEV : (((hdp)->ops && (hdp)->ops->operation) ?	\
	 (hdp)->ops->operation(args) : -ENOIOCTLCMD))

struct hdp_ops {
	void (*fw_load)(state_struct *state);
	void (*fw_init)(state_struct *state, u32 rate);
	void (*phy_init)(state_struct *state, int vic, int format, int color_depth);
	void (*mode_set)(state_struct *state, int vic, int format, int color_depth, int max_link);
	int (*get_edid_block)(void *data, u8 *buf, u32 block, size_t len);
	void (*get_hpd_state)(state_struct *state, u8 *hpd);
};

struct hdp_devtype {
	u8 load_fw;
	u8 is_hdmi;
	struct hdp_ops *ops;
	struct hdp_rw_func *rw;
};

struct hdp_video {
	u32 bpp;
	u32 format;
	u32 lanes;
	u32 color_type; /* bt */
	u32 color_depth;  /* bpc */
	struct drm_display_mode cur_mode;
	struct drm_display_mode pre_mode;
	void __iomem *regs_base;
};

struct hdp_audio {
	u32 interface;  /* I2S SPDIF  */
	u32 freq;
	u32 nlanes;
	u32 nChannels;
	u32 sample_width;
	u32 sample_rate;
	u32 audio_cts;
	u32 audio_n;
	bool audio_enable;
	spinlock_t audio_lock;
	struct mutex audio_mutex;
	void __iomem *regs_base;
};

struct hdp_hdcp {
	void __iomem *regs_base;
};

struct hdp_phy {
	u32 index;
	u32 number;
	bool enabled;
	struct phy *phy;
	void __iomem *regs_base;
};

struct hdp_clks {
	struct clk *av_pll;
	struct clk *dig_pll;
	struct clk *clk_ipg;
	struct clk *clk_core;
	struct clk *clk_pxl;
	struct clk *clk_pxl_mux;
	struct clk *clk_pxl_link;

	struct clk *clk_hdp;
	struct clk *clk_phy;
	struct clk *clk_apb;

	struct clk *clk_lis;
	struct clk *clk_msi;
	struct clk *clk_lpcg;
	struct clk *clk_even;
	struct clk *clk_dbl;
	struct clk *clk_vif;
	struct clk *clk_apb_csr;
	struct clk *clk_apb_ctrl;
	struct clk *av_pll_div;
	struct clk *dig_pll_div;
	struct clk *clk_i2s;
	struct clk *clk_i2s_bypass;
};

struct imx_hdp {
	struct device *dev;
	struct drm_connector connector;
	struct drm_encoder encoder;
	struct drm_bridge bridge;

	struct edid *edid;
	char cable_state;
	char fw_running;

	void __iomem *regs_base; /* Controller regs base */
	void __iomem *ss_base; /* HDP Subsystem regs base */

	u8 load_fw;
	u8 is_hdmi;

	struct mutex mutex;		/* for state below and previous_mode */
	enum drm_connector_force force;	/* mutex-protected force state */

	struct hdp_video video;

	struct drm_dp_aux aux;
	struct mutex aux_mutex;

	struct drm_dp_link dp_link;
	S_LINK_STAT lkstat;
	ENUM_AFE_LINK_RATE link_rate;

	sc_ipc_t ipcHndl;
	u32 mu_id;
	u32 dual_mode;
	struct hdp_ops *ops;
	struct hdp_rw_func *rw;
	struct hdp_clks clks;
	state_struct state;
	int vic;
	/* thread */
	struct task_struct *hpd_worker;
};

int imx_hdpaux_init(struct device *dev,	struct imx_hdp *dp);
void imx_hdpaux_destroy(struct device *dev, struct imx_hdp *dp);
void hdp_phy_reset(u8 reset);
u32 imx_hdp_audio(AUDIO_TYPE type, u32 sample_rate, u32 channels, u32 width);

#endif