summaryrefslogtreecommitdiff
path: root/linux-core/radeon_mode.h
blob: 3271375d3ce806f32620eedf68d4c8342f17b32f (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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
/*
 * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
 *                VA Linux Systems Inc., Fremont, California.
 * Copyright 2008 Red Hat Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Original Authors:
 *   Kevin E. Martin, Rickard E. Faith, Alan Hourihane
 *
 * Kernel port Author: Dave Airlie
 */

#ifndef RADEON_MODE_H
#define RADEON_MODE_H

#include <linux/i2c.h>
#include <linux/i2c-id.h>
#include <linux/i2c-algo-bit.h>

#define to_radeon_crtc(x) container_of(x, struct radeon_crtc, base)
#define to_radeon_connector(x) container_of(x, struct radeon_connector, base)
#define to_radeon_encoder(x) container_of(x, struct radeon_encoder, base)
#define to_radeon_framebuffer(x) container_of(x, struct radeon_framebuffer, base)

enum radeon_connector_type {
	CONNECTOR_NONE,
	CONNECTOR_VGA,
	CONNECTOR_DVI_I,
	CONNECTOR_DVI_D,
	CONNECTOR_DVI_A,
	CONNECTOR_STV,
	CONNECTOR_CTV,
	CONNECTOR_LVDS,
	CONNECTOR_DIGITAL,
	CONNECTOR_SCART,
	CONNECTOR_HDMI_TYPE_A,
	CONNECTOR_HDMI_TYPE_B,
	CONNECTOR_0XC,
	CONNECTOR_0XD,
	CONNECTOR_DIN,
	CONNECTOR_DISPLAY_PORT,
	CONNECTOR_UNSUPPORTED
};

enum radeon_dac_type {
	DAC_NONE = 0,
	DAC_PRIMARY = 1,
	DAC_TVDAC = 2,
	DAC_EXT = 3
};

enum radeon_tmds_type {
	TMDS_NONE = 0,
	TMDS_INT = 1,
	TMDS_EXT = 2,
	TMDS_LVTMA = 3,
	TMDS_DDIA = 4,
	TMDS_UNIPHY = 5
};

enum radeon_dvi_type {
	DVI_AUTO,
	DVI_DIGITAL,
	DVI_ANALOG
};

enum radeon_rmx_type {
	RMX_OFF,
	RMX_FULL,
	RMX_CENTER,
};

enum radeon_tv_std {
	TV_STD_NTSC,
	TV_STD_PAL,
	TV_STD_PAL_M,
	TV_STD_PAL_60,
	TV_STD_NTSC_J,
	TV_STD_SCART_PAL,
	TV_STD_SECAM,
	TV_STD_PAL_CN,
};

struct radeon_i2c_bus_rec {
	bool valid;
	uint32_t mask_clk_reg;
	uint32_t mask_data_reg;
	uint32_t a_clk_reg;
	uint32_t a_data_reg;
	uint32_t put_clk_reg;
	uint32_t put_data_reg;
	uint32_t get_clk_reg;
	uint32_t get_data_reg;
	uint32_t mask_clk_mask;
	uint32_t mask_data_mask;
	uint32_t put_clk_mask;
	uint32_t put_data_mask;
	uint32_t get_clk_mask;
	uint32_t get_data_mask;
	uint32_t a_clk_mask;
	uint32_t a_data_mask;
};

struct radeon_bios_connector {
	enum radeon_dac_type dac_type;
	enum radeon_tmds_type tmds_type;
	enum radeon_connector_type connector_type;
	bool valid;
	int output_id;
	int devices;
	int hpd_mask;
	struct radeon_i2c_bus_rec ddc_i2c;
	int igp_lane_info;
};

struct radeon_tmds_pll {
    uint32_t freq;
    uint32_t value;
};

#define RADEON_MAX_BIOS_CONNECTOR 16

#define RADEON_PLL_USE_BIOS_DIVS   (1 << 0)
#define RADEON_PLL_NO_ODD_POST_DIV (1 << 1)
#define RADEON_PLL_USE_REF_DIV     (1 << 2)
#define RADEON_PLL_LEGACY          (1 << 3)
#define RADEON_PLL_PREFER_LOW_REF_DIV (1 << 4)

struct radeon_pll {
	uint16_t reference_freq;
	uint16_t reference_div;
	uint32_t pll_in_min;
	uint32_t pll_in_max;
	uint32_t pll_out_min;
	uint32_t pll_out_max;
	uint16_t xclk;

	uint32_t min_ref_div;
	uint32_t max_ref_div;
	uint32_t min_post_div;
	uint32_t max_post_div;
	uint32_t min_feedback_div;
	uint32_t max_feedback_div;
	uint32_t best_vco;
};

#define MAX_H_CODE_TIMING_LEN 32
#define MAX_V_CODE_TIMING_LEN 32

struct radeon_legacy_state {

	uint32_t bus_cntl;

	/* DAC */
	uint32_t dac_cntl;
	uint32_t dac2_cntl;
	uint32_t dac_macro_cntl;

	/* CRTC 1 */
	uint32_t crtc_gen_cntl;
	uint32_t crtc_ext_cntl;
	uint32_t crtc_h_total_disp;
	uint32_t crtc_h_sync_strt_wid;
	uint32_t crtc_v_total_disp;
	uint32_t crtc_v_sync_strt_wid;
	uint32_t crtc_offset;
	uint32_t crtc_offset_cntl;
	uint32_t crtc_pitch;
	uint32_t disp_merge_cntl;
	uint32_t grph_buffer_cntl;
	uint32_t crtc_more_cntl;
	uint32_t crtc_tile_x0_y0;

	/* CRTC 2 */
	uint32_t crtc2_gen_cntl;
	uint32_t crtc2_h_total_disp;
	uint32_t crtc2_h_sync_strt_wid;
	uint32_t crtc2_v_total_disp;
	uint32_t crtc2_v_sync_strt_wid;
	uint32_t crtc2_offset;
	uint32_t crtc2_offset_cntl;
	uint32_t crtc2_pitch;
	uint32_t crtc2_tile_x0_y0;

	uint32_t disp_output_cntl;
	uint32_t disp_tv_out_cntl;
	uint32_t disp_hw_debug;
	uint32_t disp2_merge_cntl;
	uint32_t grph2_buffer_cntl;

	/* FP regs */
	uint32_t fp_crtc_h_total_disp;
	uint32_t fp_crtc_v_total_disp;
	uint32_t fp_gen_cntl;
	uint32_t fp2_gen_cntl;
	uint32_t fp_h_sync_strt_wid;
	uint32_t fp_h2_sync_strt_wid;
	uint32_t fp_horz_stretch;
	uint32_t fp_horz_vert_active;
	uint32_t fp_panel_cntl;
	uint32_t fp_v_sync_strt_wid;
	uint32_t fp_v2_sync_strt_wid;
	uint32_t fp_vert_stretch;
	uint32_t lvds_gen_cntl;
	uint32_t lvds_pll_cntl;
	uint32_t tmds_pll_cntl;
	uint32_t tmds_transmitter_cntl;

	/* Computed values for PLL */
	uint32_t dot_clock_freq;
	uint32_t pll_output_freq;
	int  feedback_div;
	int  reference_div;
	int  post_div;

	/* PLL registers */
	uint32_t ppll_ref_div;
	uint32_t ppll_div_3;
	uint32_t htotal_cntl;
	uint32_t vclk_ecp_cntl;

	/* Computed values for PLL2 */
	uint32_t dot_clock_freq_2;
	uint32_t pll_output_freq_2;
	int feedback_div_2;
	int reference_div_2;
	int post_div_2;

	/* PLL2 registers */
	uint32_t p2pll_ref_div;
	uint32_t p2pll_div_0;
	uint32_t htotal_cntl2;
	uint32_t pixclks_cntl;

	bool palette_valid;
	uint32_t palette[256];
	uint32_t palette2[256];

	uint32_t disp2_req_cntl1;
	uint32_t disp2_req_cntl2;
	uint32_t dmif_mem_cntl1;
	uint32_t disp1_req_cntl1;

	uint32_t fp_2nd_gen_cntl;
	uint32_t fp2_2_gen_cntl;
	uint32_t tmds2_cntl;
	uint32_t tmds2_transmitter_cntl;

	/* TV out registers */
	uint32_t tv_master_cntl;
	uint32_t tv_htotal;
	uint32_t tv_hsize;
	uint32_t tv_hdisp;
	uint32_t tv_hstart;
	uint32_t tv_vtotal;
	uint32_t tv_vdisp;
	uint32_t tv_timing_cntl;
	uint32_t tv_vscaler_cntl1;
	uint32_t tv_vscaler_cntl2;
	uint32_t tv_sync_size;
	uint32_t tv_vrestart;
	uint32_t tv_hrestart;
	uint32_t tv_frestart;
	uint32_t tv_ftotal;
	uint32_t tv_clock_sel_cntl;
	uint32_t tv_clkout_cntl;
	uint32_t tv_data_delay_a;
	uint32_t tv_data_delay_b;
	uint32_t tv_dac_cntl;
	uint32_t tv_pll_cntl;
	uint32_t tv_pll_cntl1;
	uint32_t tv_pll_fine_cntl;
	uint32_t tv_modulator_cntl1;
	uint32_t tv_modulator_cntl2;
	uint32_t tv_frame_lock_cntl;
	uint32_t tv_pre_dac_mux_cntl;
	uint32_t tv_rgb_cntl;
	uint32_t tv_y_saw_tooth_cntl;
	uint32_t tv_y_rise_cntl;
	uint32_t tv_y_fall_cntl;
	uint32_t tv_uv_adr;
	uint32_t tv_upsamp_and_gain_cntl;
	uint32_t tv_gain_limit_settings;
	uint32_t tv_linear_gain_settings;
	uint32_t tv_crc_cntl;
	uint32_t tv_sync_cntl;
	uint32_t gpiopad_a;
	uint32_t pll_test_cntl;

	uint16_t h_code_timing[MAX_H_CODE_TIMING_LEN];
	uint16_t v_code_timing[MAX_V_CODE_TIMING_LEN];


};

struct radeon_mode_info {
	struct atom_context *atom_context;
	struct radeon_bios_connector bios_connector[RADEON_MAX_BIOS_CONNECTOR];
	struct radeon_pll pll;
	struct radeon_legacy_state legacy_state;
};

struct radeon_crtc {
	struct drm_crtc base;
	int crtc_id;
	u8 lut_r[256], lut_g[256], lut_b[256];
	bool enabled;
	bool can_tile;
	uint32_t crtc_offset;
	struct radeon_framebuffer *fbdev_fb;
	struct drm_mode_set mode_set;
};

struct radeon_i2c_chan {
	struct drm_device *dev;
	struct i2c_adapter adapter;
	struct i2c_algo_bit_data algo;
	struct radeon_i2c_bus_rec rec;
};


#define RADEON_USE_RMX 1

struct radeon_encoder {
	struct drm_encoder base;
	uint32_t encoder_mode;
	uint32_t flags;
	enum radeon_rmx_type rmx_type;
	union {
		enum radeon_dac_type dac;
		enum radeon_tmds_type tmds;
	} type;
	int atom_device; /* atom devices */

	/* preferred mode */
	uint32_t panel_xres, panel_yres;
	uint32_t hoverplus, hsync_width;
	uint32_t hblank;
	uint32_t voverplus, vsync_width;
	uint32_t vblank;
	uint32_t dotclock;

	/* legacy lvds */
	uint16_t panel_vcc_delay;
	uint16_t panel_pwr_delay;
	uint16_t panel_digon_delay;
	uint16_t panel_blon_delay;
	uint32_t panel_ref_divider;
	uint32_t panel_post_divider;
	uint32_t panel_fb_divider;
	bool use_bios_dividers;
	uint32_t lvds_gen_cntl;

	/* legacy tv dac */
	uint32_t ps2_tvdac_adj;
	uint32_t ntsc_tvdac_adj;
	uint32_t pal_tvdac_adj;
	enum radeon_tv_std tv_std;

	/* legacy int tmds */
	struct radeon_tmds_pll tmds_pll[4];
};

struct radeon_connector {
	struct drm_connector base;
	struct radeon_i2c_chan *ddc_bus;
	int use_digital;
};

struct radeon_framebuffer {
	struct drm_framebuffer base;
	struct drm_gem_object *obj;
	struct drm_bo_kmap_obj kmap_obj;
};

extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
						 struct radeon_i2c_bus_rec *rec,
						 const char *name);
extern void radeon_i2c_destroy(struct radeon_i2c_chan *i2c);
extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector);
extern struct drm_connector *radeon_connector_add(struct drm_device *dev, int bios_index);

extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector);

extern void radeon_compute_pll(struct radeon_pll *pll,
			       uint64_t freq,
			       uint32_t *dot_clock_p,
			       uint32_t *fb_div_p,
			       uint32_t *ref_div_p,
			       uint32_t *post_div_p,
			       int flags);

struct drm_encoder *radeon_encoder_lvtma_add(struct drm_device *dev, int bios_index);
struct drm_encoder *radeon_encoder_atom_dac_add(struct drm_device *dev, int bios_index, int dac_id, int with_tv);
struct drm_encoder *radeon_encoder_atom_tmds_add(struct drm_device *dev, int bios_index, int tmds_type);
struct drm_encoder *radeon_encoder_legacy_lvds_add(struct drm_device *dev, int bios_index);
struct drm_encoder *radeon_encoder_legacy_primary_dac_add(struct drm_device *dev, int bios_index, int with_tv);
struct drm_encoder *radeon_encoder_legacy_tv_dac_add(struct drm_device *dev, int bios_index, int with_tv);
struct drm_encoder *radeon_encoder_legacy_tmds_int_add(struct drm_device *dev, int bios_index);
struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, int bios_index);

extern void radeon_crtc_load_lut(struct drm_crtc *crtc);
extern void atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y);
extern void atombios_crtc_mode_set(struct drm_crtc *crtc,
				   struct drm_display_mode *mode,
				   struct drm_display_mode *adjusted_mode,
				   int x, int y);
extern void atombios_crtc_dpms(struct drm_crtc *crtc, int mode);

extern int radeon_crtc_cursor_set(struct drm_crtc *crtc,
				  struct drm_file *file_priv,
				  uint32_t handle,
				  uint32_t width,
				  uint32_t height);
extern int radeon_crtc_cursor_move(struct drm_crtc *crtc,
				   int x, int y);

extern bool radeon_atom_get_clock_info(struct drm_device *dev);
extern bool radeon_combios_get_clock_info(struct drm_device *dev);
extern void radeon_get_lvds_info(struct radeon_encoder *encoder);
extern bool radeon_combios_get_lvds_info(struct radeon_encoder *encoder);
extern bool radeon_combios_get_tmds_info(struct radeon_encoder *encoder);
extern bool radeon_combios_get_tv_info(struct radeon_encoder *encoder);
extern bool radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder);
extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
				     u16 blue, int regno);
struct drm_framebuffer *radeon_user_framebuffer_create(struct drm_device *dev,
						       struct drm_file *filp,
						       struct drm_mode_fb_cmd *mode_cmd);

int radeonfb_probe(struct drm_device *dev);

int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb);
bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev);
void radeon_atombios_init_crtc(struct drm_device *dev,
			       struct radeon_crtc *radeon_crtc);
void radeon_legacy_init_crtc(struct drm_device *dev,
			     struct radeon_crtc *radeon_crtc);
void radeon_i2c_do_lock(struct radeon_connector *radeon_connector, int lock_state);

void radeon_atom_static_pwrmgt_setup(struct drm_device *dev, int enable);
void radeon_atom_dyn_clk_setup(struct drm_device *dev, int enable);
void radeon_get_clock_info(struct drm_device *dev);
extern bool radeon_get_atom_connector_info_from_bios_connector_table(struct drm_device *dev);

void radeon_rmx_mode_fixup(struct drm_encoder *encoder,
			   struct drm_display_mode *mode,
			   struct drm_display_mode *adjusted_mode);
void radeon_enc_destroy(struct drm_encoder *encoder);

#endif