2 * Copyright 2012 Red Hat Inc.
3 * Parts based on xf86-video-ast
4 * Copyright (c) 2005 ASPEED Technology Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
28 * Authors: Dave Airlie <airlied@redhat.com>
31 #include <linux/export.h>
32 #include <linux/pci.h>
34 #include <drm/drm_atomic.h>
35 #include <drm/drm_atomic_helper.h>
36 #include <drm/drm_atomic_state_helper.h>
37 #include <drm/drm_crtc.h>
38 #include <drm/drm_crtc_helper.h>
39 #include <drm/drm_fourcc.h>
40 #include <drm/drm_gem_vram_helper.h>
41 #include <drm/drm_plane_helper.h>
42 #include <drm/drm_probe_helper.h>
45 #include "ast_tables.h"
47 static struct ast_i2c_chan
*ast_i2c_create(struct drm_device
*dev
);
48 static void ast_i2c_destroy(struct ast_i2c_chan
*i2c
);
49 static int ast_cursor_move(struct drm_crtc
*crtc
,
53 static u32
copy_cursor_image(u8
*src
, u8
*dst
, int width
, int height
);
54 static int ast_cursor_update(void *dst
, void *src
, unsigned int width
,
56 static void ast_cursor_set_base(struct ast_private
*ast
, u64 address
);
57 static int ast_cursor_move(struct drm_crtc
*crtc
,
60 static inline void ast_load_palette_index(struct ast_private
*ast
,
61 u8 index
, u8 red
, u8 green
,
64 ast_io_write8(ast
, AST_IO_DAC_INDEX_WRITE
, index
);
65 ast_io_read8(ast
, AST_IO_SEQ_PORT
);
66 ast_io_write8(ast
, AST_IO_DAC_DATA
, red
);
67 ast_io_read8(ast
, AST_IO_SEQ_PORT
);
68 ast_io_write8(ast
, AST_IO_DAC_DATA
, green
);
69 ast_io_read8(ast
, AST_IO_SEQ_PORT
);
70 ast_io_write8(ast
, AST_IO_DAC_DATA
, blue
);
71 ast_io_read8(ast
, AST_IO_SEQ_PORT
);
74 static void ast_crtc_load_lut(struct ast_private
*ast
, struct drm_crtc
*crtc
)
82 r
= crtc
->gamma_store
;
83 g
= r
+ crtc
->gamma_size
;
84 b
= g
+ crtc
->gamma_size
;
86 for (i
= 0; i
< 256; i
++)
87 ast_load_palette_index(ast
, i
, *r
++ >> 8, *g
++ >> 8, *b
++ >> 8);
90 static bool ast_get_vbios_mode_info(const struct drm_format_info
*format
,
91 const struct drm_display_mode
*mode
,
92 struct drm_display_mode
*adjusted_mode
,
93 struct ast_vbios_mode_info
*vbios_mode
)
95 u32 refresh_rate_index
= 0, refresh_rate
;
96 const struct ast_vbios_enhtable
*best
= NULL
;
100 switch (format
->cpp
[0] * 8) {
102 vbios_mode
->std_table
= &vbios_stdtable
[VGAModeIndex
];
105 vbios_mode
->std_table
= &vbios_stdtable
[HiCModeIndex
];
109 vbios_mode
->std_table
= &vbios_stdtable
[TrueCModeIndex
];
115 switch (mode
->crtc_hdisplay
) {
117 vbios_mode
->enh_table
= &res_640x480
[refresh_rate_index
];
120 vbios_mode
->enh_table
= &res_800x600
[refresh_rate_index
];
123 vbios_mode
->enh_table
= &res_1024x768
[refresh_rate_index
];
126 if (mode
->crtc_vdisplay
== 800)
127 vbios_mode
->enh_table
= &res_1280x800
[refresh_rate_index
];
129 vbios_mode
->enh_table
= &res_1280x1024
[refresh_rate_index
];
132 vbios_mode
->enh_table
= &res_1360x768
[refresh_rate_index
];
135 vbios_mode
->enh_table
= &res_1440x900
[refresh_rate_index
];
138 if (mode
->crtc_vdisplay
== 900)
139 vbios_mode
->enh_table
= &res_1600x900
[refresh_rate_index
];
141 vbios_mode
->enh_table
= &res_1600x1200
[refresh_rate_index
];
144 vbios_mode
->enh_table
= &res_1680x1050
[refresh_rate_index
];
147 if (mode
->crtc_vdisplay
== 1080)
148 vbios_mode
->enh_table
= &res_1920x1080
[refresh_rate_index
];
150 vbios_mode
->enh_table
= &res_1920x1200
[refresh_rate_index
];
156 refresh_rate
= drm_mode_vrefresh(mode
);
157 check_sync
= vbios_mode
->enh_table
->flags
& WideScreenMode
;
160 const struct ast_vbios_enhtable
*loop
= vbios_mode
->enh_table
;
162 while (loop
->refresh_rate
!= 0xff) {
164 (((mode
->flags
& DRM_MODE_FLAG_NVSYNC
) &&
165 (loop
->flags
& PVSync
)) ||
166 ((mode
->flags
& DRM_MODE_FLAG_PVSYNC
) &&
167 (loop
->flags
& NVSync
)) ||
168 ((mode
->flags
& DRM_MODE_FLAG_NHSYNC
) &&
169 (loop
->flags
& PHSync
)) ||
170 ((mode
->flags
& DRM_MODE_FLAG_PHSYNC
) &&
171 (loop
->flags
& NHSync
)))) {
175 if (loop
->refresh_rate
<= refresh_rate
176 && (!best
|| loop
->refresh_rate
> best
->refresh_rate
))
180 if (best
|| !check_sync
)
186 vbios_mode
->enh_table
= best
;
188 hborder
= (vbios_mode
->enh_table
->flags
& HBorder
) ? 8 : 0;
189 vborder
= (vbios_mode
->enh_table
->flags
& VBorder
) ? 8 : 0;
191 adjusted_mode
->crtc_htotal
= vbios_mode
->enh_table
->ht
;
192 adjusted_mode
->crtc_hblank_start
= vbios_mode
->enh_table
->hde
+ hborder
;
193 adjusted_mode
->crtc_hblank_end
= vbios_mode
->enh_table
->ht
- hborder
;
194 adjusted_mode
->crtc_hsync_start
= vbios_mode
->enh_table
->hde
+ hborder
+
195 vbios_mode
->enh_table
->hfp
;
196 adjusted_mode
->crtc_hsync_end
= (vbios_mode
->enh_table
->hde
+ hborder
+
197 vbios_mode
->enh_table
->hfp
+
198 vbios_mode
->enh_table
->hsync
);
200 adjusted_mode
->crtc_vtotal
= vbios_mode
->enh_table
->vt
;
201 adjusted_mode
->crtc_vblank_start
= vbios_mode
->enh_table
->vde
+ vborder
;
202 adjusted_mode
->crtc_vblank_end
= vbios_mode
->enh_table
->vt
- vborder
;
203 adjusted_mode
->crtc_vsync_start
= vbios_mode
->enh_table
->vde
+ vborder
+
204 vbios_mode
->enh_table
->vfp
;
205 adjusted_mode
->crtc_vsync_end
= (vbios_mode
->enh_table
->vde
+ vborder
+
206 vbios_mode
->enh_table
->vfp
+
207 vbios_mode
->enh_table
->vsync
);
212 static void ast_set_vbios_color_reg(struct ast_private
*ast
,
213 const struct drm_format_info
*format
,
214 const struct ast_vbios_mode_info
*vbios_mode
)
218 switch (format
->cpp
[0]) {
220 color_index
= VGAModeIndex
- 1;
223 color_index
= HiCModeIndex
;
227 color_index
= TrueCModeIndex
;
232 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0x8c, (u8
)((color_index
& 0x0f) << 4));
234 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0x91, 0x00);
236 if (vbios_mode
->enh_table
->flags
& NewModeInfo
) {
237 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0x91, 0xa8);
238 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0x92, format
->cpp
[0] * 8);
242 static void ast_set_vbios_mode_reg(struct ast_private
*ast
,
243 const struct drm_display_mode
*adjusted_mode
,
244 const struct ast_vbios_mode_info
*vbios_mode
)
246 u32 refresh_rate_index
, mode_id
;
248 refresh_rate_index
= vbios_mode
->enh_table
->refresh_rate_index
;
249 mode_id
= vbios_mode
->enh_table
->mode_id
;
251 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0x8d, refresh_rate_index
& 0xff);
252 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0x8e, mode_id
& 0xff);
254 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0x91, 0x00);
256 if (vbios_mode
->enh_table
->flags
& NewModeInfo
) {
257 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0x91, 0xa8);
258 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0x93, adjusted_mode
->clock
/ 1000);
259 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0x94, adjusted_mode
->crtc_hdisplay
);
260 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0x95, adjusted_mode
->crtc_hdisplay
>> 8);
261 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0x96, adjusted_mode
->crtc_vdisplay
);
262 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0x97, adjusted_mode
->crtc_vdisplay
>> 8);
266 static void ast_set_std_reg(struct ast_private
*ast
,
267 struct drm_display_mode
*mode
,
268 struct ast_vbios_mode_info
*vbios_mode
)
270 const struct ast_vbios_stdtable
*stdtable
;
274 stdtable
= vbios_mode
->std_table
;
276 jreg
= stdtable
->misc
;
277 ast_io_write8(ast
, AST_IO_MISC_PORT_WRITE
, jreg
);
279 /* Set SEQ; except Screen Disable field */
280 ast_set_index_reg(ast
, AST_IO_SEQ_PORT
, 0x00, 0x03);
281 ast_set_index_reg_mask(ast
, AST_IO_SEQ_PORT
, 0x01, 0xdf, stdtable
->seq
[0]);
282 for (i
= 1; i
< 4; i
++) {
283 jreg
= stdtable
->seq
[i
];
284 ast_set_index_reg(ast
, AST_IO_SEQ_PORT
, (i
+ 1) , jreg
);
287 /* Set CRTC; except base address and offset */
288 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0x11, 0x7f, 0x00);
289 for (i
= 0; i
< 12; i
++)
290 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, i
, stdtable
->crtc
[i
]);
291 for (i
= 14; i
< 19; i
++)
292 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, i
, stdtable
->crtc
[i
]);
293 for (i
= 20; i
< 25; i
++)
294 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, i
, stdtable
->crtc
[i
]);
297 jreg
= ast_io_read8(ast
, AST_IO_INPUT_STATUS1_READ
);
298 for (i
= 0; i
< 20; i
++) {
299 jreg
= stdtable
->ar
[i
];
300 ast_io_write8(ast
, AST_IO_AR_PORT_WRITE
, (u8
)i
);
301 ast_io_write8(ast
, AST_IO_AR_PORT_WRITE
, jreg
);
303 ast_io_write8(ast
, AST_IO_AR_PORT_WRITE
, 0x14);
304 ast_io_write8(ast
, AST_IO_AR_PORT_WRITE
, 0x00);
306 jreg
= ast_io_read8(ast
, AST_IO_INPUT_STATUS1_READ
);
307 ast_io_write8(ast
, AST_IO_AR_PORT_WRITE
, 0x20);
310 for (i
= 0; i
< 9; i
++)
311 ast_set_index_reg(ast
, AST_IO_GR_PORT
, i
, stdtable
->gr
[i
]);
314 static void ast_set_crtc_reg(struct ast_private
*ast
,
315 struct drm_display_mode
*mode
,
316 struct ast_vbios_mode_info
*vbios_mode
)
318 u8 jreg05
= 0, jreg07
= 0, jreg09
= 0, jregAC
= 0, jregAD
= 0, jregAE
= 0;
319 u16 temp
, precache
= 0;
321 if ((ast
->chip
== AST2500
) &&
322 (vbios_mode
->enh_table
->flags
& AST2500PreCatchCRT
))
325 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0x11, 0x7f, 0x00);
327 temp
= (mode
->crtc_htotal
>> 3) - 5;
329 jregAC
|= 0x01; /* HT D[8] */
330 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0x00, 0x00, temp
);
332 temp
= (mode
->crtc_hdisplay
>> 3) - 1;
334 jregAC
|= 0x04; /* HDE D[8] */
335 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0x01, 0x00, temp
);
337 temp
= (mode
->crtc_hblank_start
>> 3) - 1;
339 jregAC
|= 0x10; /* HBS D[8] */
340 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0x02, 0x00, temp
);
342 temp
= ((mode
->crtc_hblank_end
>> 3) - 1) & 0x7f;
344 jreg05
|= 0x80; /* HBE D[5] */
346 jregAD
|= 0x01; /* HBE D[5] */
347 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0x03, 0xE0, (temp
& 0x1f));
349 temp
= ((mode
->crtc_hsync_start
-precache
) >> 3) - 1;
351 jregAC
|= 0x40; /* HRS D[5] */
352 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0x04, 0x00, temp
);
354 temp
= (((mode
->crtc_hsync_end
-precache
) >> 3) - 1) & 0x3f;
356 jregAD
|= 0x04; /* HRE D[5] */
357 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0x05, 0x60, (u8
)((temp
& 0x1f) | jreg05
));
359 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0xAC, 0x00, jregAC
);
360 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0xAD, 0x00, jregAD
);
363 temp
= (mode
->crtc_vtotal
) - 2;
370 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0x06, 0x00, temp
);
372 temp
= (mode
->crtc_vsync_start
) - 1;
379 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0x10, 0x00, temp
);
381 temp
= (mode
->crtc_vsync_end
- 1) & 0x3f;
386 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0x11, 0x70, temp
& 0xf);
388 temp
= mode
->crtc_vdisplay
- 1;
395 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0x12, 0x00, temp
);
397 temp
= mode
->crtc_vblank_start
- 1;
404 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0x15, 0x00, temp
);
406 temp
= mode
->crtc_vblank_end
- 1;
409 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0x16, 0x00, temp
);
411 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0x07, 0x00, jreg07
);
412 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0x09, 0xdf, jreg09
);
413 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0xAE, 0x00, (jregAE
| 0x80));
416 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0xb6, 0x3f, 0x80);
418 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0xb6, 0x3f, 0x00);
420 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0x11, 0x7f, 0x80);
423 static void ast_set_offset_reg(struct ast_private
*ast
,
424 struct drm_framebuffer
*fb
)
428 offset
= fb
->pitches
[0] >> 3;
429 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0x13, (offset
& 0xff));
430 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0xb0, (offset
>> 8) & 0x3f);
433 static void ast_set_dclk_reg(struct ast_private
*ast
,
434 struct drm_display_mode
*mode
,
435 struct ast_vbios_mode_info
*vbios_mode
)
437 const struct ast_vbios_dclk_info
*clk_info
;
439 if (ast
->chip
== AST2500
)
440 clk_info
= &dclk_table_ast2500
[vbios_mode
->enh_table
->dclk_index
];
442 clk_info
= &dclk_table
[vbios_mode
->enh_table
->dclk_index
];
444 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0xc0, 0x00, clk_info
->param1
);
445 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0xc1, 0x00, clk_info
->param2
);
446 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0xbb, 0x0f,
447 (clk_info
->param3
& 0xc0) |
448 ((clk_info
->param3
& 0x3) << 4));
451 static void ast_set_color_reg(struct ast_private
*ast
,
452 const struct drm_format_info
*format
)
454 u8 jregA0
= 0, jregA3
= 0, jregA8
= 0;
456 switch (format
->cpp
[0] * 8) {
475 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0xa0, 0x8f, jregA0
);
476 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0xa3, 0xf0, jregA3
);
477 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0xa8, 0xfd, jregA8
);
480 static void ast_set_crtthd_reg(struct ast_private
*ast
)
483 if (ast
->chip
== AST2300
|| ast
->chip
== AST2400
||
484 ast
->chip
== AST2500
) {
485 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0xa7, 0x78);
486 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0xa6, 0x60);
487 } else if (ast
->chip
== AST2100
||
488 ast
->chip
== AST1100
||
489 ast
->chip
== AST2200
||
490 ast
->chip
== AST2150
) {
491 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0xa7, 0x3f);
492 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0xa6, 0x2f);
494 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0xa7, 0x2f);
495 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0xa6, 0x1f);
499 static void ast_set_sync_reg(struct ast_private
*ast
,
500 struct drm_display_mode
*mode
,
501 struct ast_vbios_mode_info
*vbios_mode
)
505 jreg
= ast_io_read8(ast
, AST_IO_MISC_PORT_READ
);
507 if (vbios_mode
->enh_table
->flags
& NVSync
) jreg
|= 0x80;
508 if (vbios_mode
->enh_table
->flags
& NHSync
) jreg
|= 0x40;
509 ast_io_write8(ast
, AST_IO_MISC_PORT_WRITE
, jreg
);
512 static void ast_set_start_address_crt1(struct ast_private
*ast
,
518 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0x0d, (u8
)(addr
& 0xff));
519 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0x0c, (u8
)((addr
>> 8) & 0xff));
520 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0xaf, (u8
)((addr
>> 16) & 0xff));
528 static const uint32_t ast_primary_plane_formats
[] = {
534 static int ast_primary_plane_helper_atomic_check(struct drm_plane
*plane
,
535 struct drm_plane_state
*state
)
537 struct drm_crtc_state
*crtc_state
;
538 struct ast_crtc_state
*ast_crtc_state
;
544 crtc_state
= drm_atomic_get_new_crtc_state(state
->state
, state
->crtc
);
546 ret
= drm_atomic_helper_check_plane_state(state
, crtc_state
,
547 DRM_PLANE_HELPER_NO_SCALING
,
548 DRM_PLANE_HELPER_NO_SCALING
,
556 ast_crtc_state
= to_ast_crtc_state(crtc_state
);
558 ast_crtc_state
->format
= state
->fb
->format
;
563 void ast_primary_plane_helper_atomic_update(struct drm_plane
*plane
,
564 struct drm_plane_state
*old_state
)
566 struct ast_private
*ast
= plane
->dev
->dev_private
;
567 struct drm_plane_state
*state
= plane
->state
;
568 struct drm_gem_vram_object
*gbo
;
571 gbo
= drm_gem_vram_of_gem(state
->fb
->obj
[0]);
572 gpu_addr
= drm_gem_vram_offset(gbo
);
573 if (WARN_ON_ONCE(gpu_addr
< 0))
574 return; /* Bug: we didn't pin the BO to VRAM in prepare_fb. */
576 ast_set_offset_reg(ast
, state
->fb
);
577 ast_set_start_address_crt1(ast
, (u32
)gpu_addr
);
579 ast_set_index_reg_mask(ast
, AST_IO_SEQ_PORT
, 0x1, 0xdf, 0x00);
583 ast_primary_plane_helper_atomic_disable(struct drm_plane
*plane
,
584 struct drm_plane_state
*old_state
)
586 struct ast_private
*ast
= plane
->dev
->dev_private
;
588 ast_set_index_reg_mask(ast
, AST_IO_SEQ_PORT
, 0x1, 0xdf, 0x20);
591 static const struct drm_plane_helper_funcs ast_primary_plane_helper_funcs
= {
592 .prepare_fb
= drm_gem_vram_plane_helper_prepare_fb
,
593 .cleanup_fb
= drm_gem_vram_plane_helper_cleanup_fb
,
594 .atomic_check
= ast_primary_plane_helper_atomic_check
,
595 .atomic_update
= ast_primary_plane_helper_atomic_update
,
596 .atomic_disable
= ast_primary_plane_helper_atomic_disable
,
599 static const struct drm_plane_funcs ast_primary_plane_funcs
= {
600 .update_plane
= drm_atomic_helper_update_plane
,
601 .disable_plane
= drm_atomic_helper_disable_plane
,
602 .destroy
= drm_plane_cleanup
,
603 .reset
= drm_atomic_helper_plane_reset
,
604 .atomic_duplicate_state
= drm_atomic_helper_plane_duplicate_state
,
605 .atomic_destroy_state
= drm_atomic_helper_plane_destroy_state
,
612 static const uint32_t ast_cursor_plane_formats
[] = {
617 ast_cursor_plane_helper_prepare_fb(struct drm_plane
*plane
,
618 struct drm_plane_state
*new_state
)
620 struct drm_framebuffer
*fb
= new_state
->fb
;
621 struct drm_crtc
*crtc
= new_state
->crtc
;
622 struct drm_gem_vram_object
*gbo
;
623 struct ast_private
*ast
;
630 if (WARN_ON_ONCE(fb
->width
> AST_MAX_HWC_WIDTH
) ||
631 WARN_ON_ONCE(fb
->height
> AST_MAX_HWC_HEIGHT
))
632 return -EINVAL
; /* BUG: didn't test in atomic_check() */
634 ast
= crtc
->dev
->dev_private
;
636 gbo
= drm_gem_vram_of_gem(fb
->obj
[0]);
637 src
= drm_gem_vram_vmap(gbo
);
640 goto err_drm_gem_vram_unpin
;
643 dst
= drm_gem_vram_vmap(ast
->cursor
.gbo
[ast
->cursor
.next_index
]);
646 goto err_drm_gem_vram_vunmap_src
;
649 ret
= ast_cursor_update(dst
, src
, fb
->width
, fb
->height
);
651 goto err_drm_gem_vram_vunmap_dst
;
653 /* Always unmap buffers here. Destination buffers are
654 * perma-pinned while the driver is active. We're only
655 * changing ref-counters here.
657 drm_gem_vram_vunmap(ast
->cursor
.gbo
[ast
->cursor
.next_index
], dst
);
658 drm_gem_vram_vunmap(gbo
, src
);
662 err_drm_gem_vram_vunmap_dst
:
663 drm_gem_vram_vunmap(ast
->cursor
.gbo
[ast
->cursor
.next_index
], dst
);
664 err_drm_gem_vram_vunmap_src
:
665 drm_gem_vram_vunmap(gbo
, src
);
666 err_drm_gem_vram_unpin
:
667 drm_gem_vram_unpin(gbo
);
671 static int ast_cursor_plane_helper_atomic_check(struct drm_plane
*plane
,
672 struct drm_plane_state
*state
)
674 struct drm_framebuffer
*fb
= state
->fb
;
675 struct drm_crtc_state
*crtc_state
;
681 crtc_state
= drm_atomic_get_new_crtc_state(state
->state
, state
->crtc
);
683 ret
= drm_atomic_helper_check_plane_state(state
, crtc_state
,
684 DRM_PLANE_HELPER_NO_SCALING
,
685 DRM_PLANE_HELPER_NO_SCALING
,
693 if (fb
->width
> AST_MAX_HWC_WIDTH
|| fb
->height
> AST_MAX_HWC_HEIGHT
)
700 ast_cursor_plane_helper_atomic_update(struct drm_plane
*plane
,
701 struct drm_plane_state
*old_state
)
703 struct drm_plane_state
*state
= plane
->state
;
704 struct drm_crtc
*crtc
= state
->crtc
;
705 struct drm_framebuffer
*fb
= state
->fb
;
706 struct ast_private
*ast
= plane
->dev
->dev_private
;
707 struct ast_crtc
*ast_crtc
= to_ast_crtc(crtc
);
708 struct drm_gem_vram_object
*gbo
;
712 ast_crtc
->offset_x
= AST_MAX_HWC_WIDTH
- fb
->width
;
713 ast_crtc
->offset_y
= AST_MAX_HWC_WIDTH
- fb
->height
;
715 if (state
->fb
!= old_state
->fb
) {
716 /* A new cursor image was installed. */
717 gbo
= ast
->cursor
.gbo
[ast
->cursor
.next_index
];
718 off
= drm_gem_vram_offset(gbo
);
719 if (WARN_ON_ONCE(off
< 0))
720 return; /* Bug: we didn't pin cursor HW BO to VRAM. */
721 ast_cursor_set_base(ast
, off
);
723 ++ast
->cursor
.next_index
;
724 ast
->cursor
.next_index
%= ARRAY_SIZE(ast
->cursor
.gbo
);
727 ast_cursor_move(crtc
, state
->crtc_x
, state
->crtc_y
);
730 /* enable ARGB cursor */
732 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0xcb, 0xfc, jreg
);
736 ast_cursor_plane_helper_atomic_disable(struct drm_plane
*plane
,
737 struct drm_plane_state
*old_state
)
739 struct ast_private
*ast
= plane
->dev
->dev_private
;
741 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0xcb, 0xfc, 0x00);
744 static const struct drm_plane_helper_funcs ast_cursor_plane_helper_funcs
= {
745 .prepare_fb
= ast_cursor_plane_helper_prepare_fb
,
746 .cleanup_fb
= NULL
, /* not required for cursor plane */
747 .atomic_check
= ast_cursor_plane_helper_atomic_check
,
748 .atomic_update
= ast_cursor_plane_helper_atomic_update
,
749 .atomic_disable
= ast_cursor_plane_helper_atomic_disable
,
752 static const struct drm_plane_funcs ast_cursor_plane_funcs
= {
753 .update_plane
= drm_atomic_helper_update_plane
,
754 .disable_plane
= drm_atomic_helper_disable_plane
,
755 .destroy
= drm_plane_cleanup
,
756 .reset
= drm_atomic_helper_plane_reset
,
757 .atomic_duplicate_state
= drm_atomic_helper_plane_duplicate_state
,
758 .atomic_destroy_state
= drm_atomic_helper_plane_destroy_state
,
765 static void ast_crtc_dpms(struct drm_crtc
*crtc
, int mode
)
767 struct ast_private
*ast
= crtc
->dev
->dev_private
;
769 if (ast
->chip
== AST1180
)
772 /* TODO: Maybe control display signal generation with
773 * Sync Enable (bit CR17.7).
776 case DRM_MODE_DPMS_ON
:
777 case DRM_MODE_DPMS_STANDBY
:
778 case DRM_MODE_DPMS_SUSPEND
:
779 if (ast
->tx_chip_type
== AST_TX_DP501
)
780 ast_set_dp501_video_output(crtc
->dev
, 1);
781 ast_crtc_load_lut(ast
, crtc
);
783 case DRM_MODE_DPMS_OFF
:
784 if (ast
->tx_chip_type
== AST_TX_DP501
)
785 ast_set_dp501_video_output(crtc
->dev
, 0);
790 static int ast_crtc_helper_atomic_check(struct drm_crtc
*crtc
,
791 struct drm_crtc_state
*state
)
793 struct ast_private
*ast
= crtc
->dev
->dev_private
;
794 struct ast_crtc_state
*ast_state
;
795 const struct drm_format_info
*format
;
798 if (ast
->chip
== AST1180
) {
799 DRM_ERROR("AST 1180 modesetting not supported\n");
803 ast_state
= to_ast_crtc_state(state
);
805 format
= ast_state
->format
;
809 succ
= ast_get_vbios_mode_info(format
, &state
->mode
,
810 &state
->adjusted_mode
,
811 &ast_state
->vbios_mode_info
);
818 static void ast_crtc_helper_atomic_begin(struct drm_crtc
*crtc
,
819 struct drm_crtc_state
*old_crtc_state
)
821 struct ast_private
*ast
= crtc
->dev
->dev_private
;
826 static void ast_crtc_helper_atomic_flush(struct drm_crtc
*crtc
,
827 struct drm_crtc_state
*old_crtc_state
)
829 struct drm_device
*dev
= crtc
->dev
;
830 struct ast_private
*ast
= dev
->dev_private
;
831 struct ast_crtc_state
*ast_state
;
832 const struct drm_format_info
*format
;
833 struct ast_vbios_mode_info
*vbios_mode_info
;
834 struct drm_display_mode
*adjusted_mode
;
836 crtc
->state
->no_vblank
= true;
838 ast_state
= to_ast_crtc_state(crtc
->state
);
840 format
= ast_state
->format
;
844 vbios_mode_info
= &ast_state
->vbios_mode_info
;
846 ast_set_color_reg(ast
, format
);
847 ast_set_vbios_color_reg(ast
, format
, vbios_mode_info
);
849 if (!crtc
->state
->mode_changed
)
852 adjusted_mode
= &crtc
->state
->adjusted_mode
;
854 ast_set_vbios_mode_reg(ast
, adjusted_mode
, vbios_mode_info
);
855 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0xa1, 0x06);
856 ast_set_std_reg(ast
, adjusted_mode
, vbios_mode_info
);
857 ast_set_crtc_reg(ast
, adjusted_mode
, vbios_mode_info
);
858 ast_set_dclk_reg(ast
, adjusted_mode
, vbios_mode_info
);
859 ast_set_crtthd_reg(ast
);
860 ast_set_sync_reg(ast
, adjusted_mode
, vbios_mode_info
);
864 ast_crtc_helper_atomic_enable(struct drm_crtc
*crtc
,
865 struct drm_crtc_state
*old_crtc_state
)
867 ast_crtc_dpms(crtc
, DRM_MODE_DPMS_ON
);
871 ast_crtc_helper_atomic_disable(struct drm_crtc
*crtc
,
872 struct drm_crtc_state
*old_crtc_state
)
874 ast_crtc_dpms(crtc
, DRM_MODE_DPMS_OFF
);
877 static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs
= {
878 .atomic_check
= ast_crtc_helper_atomic_check
,
879 .atomic_begin
= ast_crtc_helper_atomic_begin
,
880 .atomic_flush
= ast_crtc_helper_atomic_flush
,
881 .atomic_enable
= ast_crtc_helper_atomic_enable
,
882 .atomic_disable
= ast_crtc_helper_atomic_disable
,
885 static void ast_crtc_destroy(struct drm_crtc
*crtc
)
887 drm_crtc_cleanup(crtc
);
891 static struct drm_crtc_state
*
892 ast_crtc_atomic_duplicate_state(struct drm_crtc
*crtc
)
894 struct ast_crtc_state
*new_ast_state
, *ast_state
;
896 if (WARN_ON(!crtc
->state
))
899 new_ast_state
= kmalloc(sizeof(*new_ast_state
), GFP_KERNEL
);
902 __drm_atomic_helper_crtc_duplicate_state(crtc
, &new_ast_state
->base
);
904 ast_state
= to_ast_crtc_state(crtc
->state
);
906 new_ast_state
->format
= ast_state
->format
;
907 memcpy(&new_ast_state
->vbios_mode_info
, &ast_state
->vbios_mode_info
,
908 sizeof(new_ast_state
->vbios_mode_info
));
910 return &new_ast_state
->base
;
913 static void ast_crtc_atomic_destroy_state(struct drm_crtc
*crtc
,
914 struct drm_crtc_state
*state
)
916 struct ast_crtc_state
*ast_state
= to_ast_crtc_state(state
);
918 __drm_atomic_helper_crtc_destroy_state(&ast_state
->base
);
922 static const struct drm_crtc_funcs ast_crtc_funcs
= {
923 .reset
= drm_atomic_helper_crtc_reset
,
924 .set_config
= drm_crtc_helper_set_config
,
925 .gamma_set
= drm_atomic_helper_legacy_gamma_set
,
926 .destroy
= ast_crtc_destroy
,
927 .set_config
= drm_atomic_helper_set_config
,
928 .page_flip
= drm_atomic_helper_page_flip
,
929 .atomic_duplicate_state
= ast_crtc_atomic_duplicate_state
,
930 .atomic_destroy_state
= ast_crtc_atomic_destroy_state
,
933 static int ast_crtc_init(struct drm_device
*dev
)
935 struct ast_private
*ast
= dev
->dev_private
;
936 struct ast_crtc
*crtc
;
939 crtc
= kzalloc(sizeof(struct ast_crtc
), GFP_KERNEL
);
943 ret
= drm_crtc_init_with_planes(dev
, &crtc
->base
, &ast
->primary_plane
,
944 &ast
->cursor_plane
, &ast_crtc_funcs
,
949 drm_mode_crtc_set_gamma_size(&crtc
->base
, 256);
950 drm_crtc_helper_add(&crtc
->base
, &ast_crtc_helper_funcs
);
962 static void ast_encoder_destroy(struct drm_encoder
*encoder
)
964 drm_encoder_cleanup(encoder
);
968 static const struct drm_encoder_funcs ast_enc_funcs
= {
969 .destroy
= ast_encoder_destroy
,
972 static int ast_encoder_init(struct drm_device
*dev
)
974 struct ast_encoder
*ast_encoder
;
976 ast_encoder
= kzalloc(sizeof(struct ast_encoder
), GFP_KERNEL
);
980 drm_encoder_init(dev
, &ast_encoder
->base
, &ast_enc_funcs
,
981 DRM_MODE_ENCODER_DAC
, NULL
);
983 ast_encoder
->base
.possible_crtcs
= 1;
991 static int ast_get_modes(struct drm_connector
*connector
)
993 struct ast_connector
*ast_connector
= to_ast_connector(connector
);
994 struct ast_private
*ast
= connector
->dev
->dev_private
;
998 if (ast
->tx_chip_type
== AST_TX_DP501
) {
999 ast
->dp501_maxclk
= 0xff;
1000 edid
= kmalloc(128, GFP_KERNEL
);
1004 flags
= ast_dp501_read_edid(connector
->dev
, (u8
*)edid
);
1006 ast
->dp501_maxclk
= ast_get_dp501_max_clk(connector
->dev
);
1011 edid
= drm_get_edid(connector
, &ast_connector
->i2c
->adapter
);
1013 drm_connector_update_edid_property(&ast_connector
->base
, edid
);
1014 ret
= drm_add_edid_modes(connector
, edid
);
1018 drm_connector_update_edid_property(&ast_connector
->base
, NULL
);
1022 static enum drm_mode_status
ast_mode_valid(struct drm_connector
*connector
,
1023 struct drm_display_mode
*mode
)
1025 struct ast_private
*ast
= connector
->dev
->dev_private
;
1026 int flags
= MODE_NOMODE
;
1029 if (ast
->support_wide_screen
) {
1030 if ((mode
->hdisplay
== 1680) && (mode
->vdisplay
== 1050))
1032 if ((mode
->hdisplay
== 1280) && (mode
->vdisplay
== 800))
1034 if ((mode
->hdisplay
== 1440) && (mode
->vdisplay
== 900))
1036 if ((mode
->hdisplay
== 1360) && (mode
->vdisplay
== 768))
1038 if ((mode
->hdisplay
== 1600) && (mode
->vdisplay
== 900))
1041 if ((ast
->chip
== AST2100
) || (ast
->chip
== AST2200
) ||
1042 (ast
->chip
== AST2300
) || (ast
->chip
== AST2400
) ||
1043 (ast
->chip
== AST2500
) || (ast
->chip
== AST1180
)) {
1044 if ((mode
->hdisplay
== 1920) && (mode
->vdisplay
== 1080))
1047 if ((mode
->hdisplay
== 1920) && (mode
->vdisplay
== 1200)) {
1048 jtemp
= ast_get_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0xd1, 0xff);
1056 switch (mode
->hdisplay
) {
1058 if (mode
->vdisplay
== 480) flags
= MODE_OK
;
1061 if (mode
->vdisplay
== 600) flags
= MODE_OK
;
1064 if (mode
->vdisplay
== 768) flags
= MODE_OK
;
1067 if (mode
->vdisplay
== 1024) flags
= MODE_OK
;
1070 if (mode
->vdisplay
== 1200) flags
= MODE_OK
;
1079 static void ast_connector_destroy(struct drm_connector
*connector
)
1081 struct ast_connector
*ast_connector
= to_ast_connector(connector
);
1082 ast_i2c_destroy(ast_connector
->i2c
);
1083 drm_connector_unregister(connector
);
1084 drm_connector_cleanup(connector
);
1088 static const struct drm_connector_helper_funcs ast_connector_helper_funcs
= {
1089 .get_modes
= ast_get_modes
,
1090 .mode_valid
= ast_mode_valid
,
1093 static const struct drm_connector_funcs ast_connector_funcs
= {
1094 .reset
= drm_atomic_helper_connector_reset
,
1095 .fill_modes
= drm_helper_probe_single_connector_modes
,
1096 .destroy
= ast_connector_destroy
,
1097 .atomic_duplicate_state
= drm_atomic_helper_connector_duplicate_state
,
1098 .atomic_destroy_state
= drm_atomic_helper_connector_destroy_state
,
1101 static int ast_connector_init(struct drm_device
*dev
)
1103 struct ast_connector
*ast_connector
;
1104 struct drm_connector
*connector
;
1105 struct drm_encoder
*encoder
;
1107 ast_connector
= kzalloc(sizeof(struct ast_connector
), GFP_KERNEL
);
1111 connector
= &ast_connector
->base
;
1112 ast_connector
->i2c
= ast_i2c_create(dev
);
1113 if (!ast_connector
->i2c
)
1114 DRM_ERROR("failed to add ddc bus for connector\n");
1116 drm_connector_init_with_ddc(dev
, connector
,
1117 &ast_connector_funcs
,
1118 DRM_MODE_CONNECTOR_VGA
,
1119 &ast_connector
->i2c
->adapter
);
1121 drm_connector_helper_add(connector
, &ast_connector_helper_funcs
);
1123 connector
->interlace_allowed
= 0;
1124 connector
->doublescan_allowed
= 0;
1126 drm_connector_register(connector
);
1128 connector
->polled
= DRM_CONNECTOR_POLL_CONNECT
;
1130 encoder
= list_first_entry(&dev
->mode_config
.encoder_list
, struct drm_encoder
, head
);
1131 drm_connector_attach_encoder(connector
, encoder
);
1136 /* allocate cursor cache and pin at start of VRAM */
1137 static int ast_cursor_init(struct drm_device
*dev
)
1139 struct ast_private
*ast
= dev
->dev_private
;
1141 struct drm_gem_vram_object
*gbo
;
1144 size
= roundup(AST_HWC_SIZE
+ AST_HWC_SIGNATURE_SIZE
, PAGE_SIZE
);
1146 for (i
= 0; i
< ARRAY_SIZE(ast
->cursor
.gbo
); ++i
) {
1147 gbo
= drm_gem_vram_create(dev
, size
, 0);
1150 goto err_drm_gem_vram_put
;
1152 ret
= drm_gem_vram_pin(gbo
, DRM_GEM_VRAM_PL_FLAG_VRAM
|
1153 DRM_GEM_VRAM_PL_FLAG_TOPDOWN
);
1155 drm_gem_vram_put(gbo
);
1156 goto err_drm_gem_vram_put
;
1159 ast
->cursor
.gbo
[i
] = gbo
;
1164 err_drm_gem_vram_put
:
1167 gbo
= ast
->cursor
.gbo
[i
];
1168 drm_gem_vram_unpin(gbo
);
1169 drm_gem_vram_put(gbo
);
1170 ast
->cursor
.gbo
[i
] = NULL
;
1175 static void ast_cursor_fini(struct drm_device
*dev
)
1177 struct ast_private
*ast
= dev
->dev_private
;
1179 struct drm_gem_vram_object
*gbo
;
1181 for (i
= 0; i
< ARRAY_SIZE(ast
->cursor
.gbo
); ++i
) {
1182 gbo
= ast
->cursor
.gbo
[i
];
1183 drm_gem_vram_unpin(gbo
);
1184 drm_gem_vram_put(gbo
);
1188 int ast_mode_init(struct drm_device
*dev
)
1190 struct ast_private
*ast
= dev
->dev_private
;
1193 memset(&ast
->primary_plane
, 0, sizeof(ast
->primary_plane
));
1194 ret
= drm_universal_plane_init(dev
, &ast
->primary_plane
, 0x01,
1195 &ast_primary_plane_funcs
,
1196 ast_primary_plane_formats
,
1197 ARRAY_SIZE(ast_primary_plane_formats
),
1198 NULL
, DRM_PLANE_TYPE_PRIMARY
, NULL
);
1200 DRM_ERROR("ast: drm_universal_plane_init() failed: %d\n", ret
);
1203 drm_plane_helper_add(&ast
->primary_plane
,
1204 &ast_primary_plane_helper_funcs
);
1206 ret
= drm_universal_plane_init(dev
, &ast
->cursor_plane
, 0x01,
1207 &ast_cursor_plane_funcs
,
1208 ast_cursor_plane_formats
,
1209 ARRAY_SIZE(ast_cursor_plane_formats
),
1210 NULL
, DRM_PLANE_TYPE_CURSOR
, NULL
);
1212 DRM_ERROR("drm_universal_plane_failed(): %d\n", ret
);
1215 drm_plane_helper_add(&ast
->cursor_plane
,
1216 &ast_cursor_plane_helper_funcs
);
1218 ast_cursor_init(dev
);
1220 ast_encoder_init(dev
);
1221 ast_connector_init(dev
);
1226 void ast_mode_fini(struct drm_device
*dev
)
1228 ast_cursor_fini(dev
);
1231 static int get_clock(void *i2c_priv
)
1233 struct ast_i2c_chan
*i2c
= i2c_priv
;
1234 struct ast_private
*ast
= i2c
->dev
->dev_private
;
1235 uint32_t val
, val2
, count
, pass
;
1239 val
= (ast_get_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0xb7, 0x10) >> 4) & 0x01;
1241 val2
= (ast_get_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0xb7, 0x10) >> 4) & 0x01;
1246 val
= (ast_get_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0xb7, 0x10) >> 4) & 0x01;
1248 } while ((pass
< 5) && (count
++ < 0x10000));
1250 return val
& 1 ? 1 : 0;
1253 static int get_data(void *i2c_priv
)
1255 struct ast_i2c_chan
*i2c
= i2c_priv
;
1256 struct ast_private
*ast
= i2c
->dev
->dev_private
;
1257 uint32_t val
, val2
, count
, pass
;
1261 val
= (ast_get_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0xb7, 0x20) >> 5) & 0x01;
1263 val2
= (ast_get_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0xb7, 0x20) >> 5) & 0x01;
1268 val
= (ast_get_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0xb7, 0x20) >> 5) & 0x01;
1270 } while ((pass
< 5) && (count
++ < 0x10000));
1272 return val
& 1 ? 1 : 0;
1275 static void set_clock(void *i2c_priv
, int clock
)
1277 struct ast_i2c_chan
*i2c
= i2c_priv
;
1278 struct ast_private
*ast
= i2c
->dev
->dev_private
;
1282 for (i
= 0; i
< 0x10000; i
++) {
1283 ujcrb7
= ((clock
& 0x01) ? 0 : 1);
1284 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0xb7, 0xf4, ujcrb7
);
1285 jtemp
= ast_get_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0xb7, 0x01);
1286 if (ujcrb7
== jtemp
)
1291 static void set_data(void *i2c_priv
, int data
)
1293 struct ast_i2c_chan
*i2c
= i2c_priv
;
1294 struct ast_private
*ast
= i2c
->dev
->dev_private
;
1298 for (i
= 0; i
< 0x10000; i
++) {
1299 ujcrb7
= ((data
& 0x01) ? 0 : 1) << 2;
1300 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0xb7, 0xf1, ujcrb7
);
1301 jtemp
= ast_get_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0xb7, 0x04);
1302 if (ujcrb7
== jtemp
)
1307 static struct ast_i2c_chan
*ast_i2c_create(struct drm_device
*dev
)
1309 struct ast_i2c_chan
*i2c
;
1312 i2c
= kzalloc(sizeof(struct ast_i2c_chan
), GFP_KERNEL
);
1316 i2c
->adapter
.owner
= THIS_MODULE
;
1317 i2c
->adapter
.class = I2C_CLASS_DDC
;
1318 i2c
->adapter
.dev
.parent
= &dev
->pdev
->dev
;
1320 i2c_set_adapdata(&i2c
->adapter
, i2c
);
1321 snprintf(i2c
->adapter
.name
, sizeof(i2c
->adapter
.name
),
1323 i2c
->adapter
.algo_data
= &i2c
->bit
;
1325 i2c
->bit
.udelay
= 20;
1326 i2c
->bit
.timeout
= 2;
1327 i2c
->bit
.data
= i2c
;
1328 i2c
->bit
.setsda
= set_data
;
1329 i2c
->bit
.setscl
= set_clock
;
1330 i2c
->bit
.getsda
= get_data
;
1331 i2c
->bit
.getscl
= get_clock
;
1332 ret
= i2c_bit_add_bus(&i2c
->adapter
);
1334 DRM_ERROR("Failed to register bit i2c\n");
1344 static void ast_i2c_destroy(struct ast_i2c_chan
*i2c
)
1348 i2c_del_adapter(&i2c
->adapter
);
1352 static u32
copy_cursor_image(u8
*src
, u8
*dst
, int width
, int height
)
1357 } srcdata32
[2], data32
;
1363 s32 alpha_dst_delta
, last_alpha_dst_delta
;
1364 u8
*srcxor
, *dstxor
;
1366 u32 per_pixel_copy
, two_pixel_copy
;
1368 alpha_dst_delta
= AST_MAX_HWC_WIDTH
<< 1;
1369 last_alpha_dst_delta
= alpha_dst_delta
- (width
<< 1);
1372 dstxor
= (u8
*)dst
+ last_alpha_dst_delta
+ (AST_MAX_HWC_HEIGHT
- height
) * alpha_dst_delta
;
1373 per_pixel_copy
= width
& 1;
1374 two_pixel_copy
= width
>> 1;
1376 for (j
= 0; j
< height
; j
++) {
1377 for (i
= 0; i
< two_pixel_copy
; i
++) {
1378 srcdata32
[0].ul
= *((u32
*)srcxor
) & 0xf0f0f0f0;
1379 srcdata32
[1].ul
= *((u32
*)(srcxor
+ 4)) & 0xf0f0f0f0;
1380 data32
.b
[0] = srcdata32
[0].b
[1] | (srcdata32
[0].b
[0] >> 4);
1381 data32
.b
[1] = srcdata32
[0].b
[3] | (srcdata32
[0].b
[2] >> 4);
1382 data32
.b
[2] = srcdata32
[1].b
[1] | (srcdata32
[1].b
[0] >> 4);
1383 data32
.b
[3] = srcdata32
[1].b
[3] | (srcdata32
[1].b
[2] >> 4);
1385 writel(data32
.ul
, dstxor
);
1393 for (i
= 0; i
< per_pixel_copy
; i
++) {
1394 srcdata32
[0].ul
= *((u32
*)srcxor
) & 0xf0f0f0f0;
1395 data16
.b
[0] = srcdata32
[0].b
[1] | (srcdata32
[0].b
[0] >> 4);
1396 data16
.b
[1] = srcdata32
[0].b
[3] | (srcdata32
[0].b
[2] >> 4);
1397 writew(data16
.us
, dstxor
);
1398 csum
+= (u32
)data16
.us
;
1403 dstxor
+= last_alpha_dst_delta
;
1408 static int ast_cursor_update(void *dst
, void *src
, unsigned int width
,
1409 unsigned int height
)
1413 /* do data transfer to cursor cache */
1414 csum
= copy_cursor_image(src
, dst
, width
, height
);
1416 /* write checksum + signature */
1417 dst
+= AST_HWC_SIZE
;
1419 writel(width
, dst
+ AST_HWC_SIGNATURE_SizeX
);
1420 writel(height
, dst
+ AST_HWC_SIGNATURE_SizeY
);
1421 writel(0, dst
+ AST_HWC_SIGNATURE_HOTSPOTX
);
1422 writel(0, dst
+ AST_HWC_SIGNATURE_HOTSPOTY
);
1427 static void ast_cursor_set_base(struct ast_private
*ast
, u64 address
)
1429 u8 addr0
= (address
>> 3) & 0xff;
1430 u8 addr1
= (address
>> 11) & 0xff;
1431 u8 addr2
= (address
>> 19) & 0xff;
1433 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0xc8, addr0
);
1434 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0xc9, addr1
);
1435 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0xca, addr2
);
1438 static int ast_cursor_move(struct drm_crtc
*crtc
,
1441 struct ast_crtc
*ast_crtc
= to_ast_crtc(crtc
);
1442 struct ast_private
*ast
= crtc
->dev
->dev_private
;
1443 struct drm_gem_vram_object
*gbo
;
1444 int x_offset
, y_offset
;
1448 gbo
= ast
->cursor
.gbo
[ast
->cursor
.next_index
];
1449 dst
= drm_gem_vram_vmap(gbo
);
1451 return PTR_ERR(dst
);
1453 sig
= dst
+ AST_HWC_SIZE
;
1454 writel(x
, sig
+ AST_HWC_SIGNATURE_X
);
1455 writel(y
, sig
+ AST_HWC_SIGNATURE_Y
);
1457 x_offset
= ast_crtc
->offset_x
;
1458 y_offset
= ast_crtc
->offset_y
;
1460 x_offset
= (-x
) + ast_crtc
->offset_x
;
1465 y_offset
= (-y
) + ast_crtc
->offset_y
;
1468 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0xc2, x_offset
);
1469 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0xc3, y_offset
);
1470 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0xc4, (x
& 0xff));
1471 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0xc5, ((x
>> 8) & 0x0f));
1472 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0xc6, (y
& 0xff));
1473 ast_set_index_reg(ast
, AST_IO_CRTC_PORT
, 0xc7, ((y
>> 8) & 0x07));
1475 /* dummy write to fire HWC */
1477 0x01; /* enable ARGB4444 cursor */
1478 ast_set_index_reg_mask(ast
, AST_IO_CRTC_PORT
, 0xcb, 0xfc, jreg
);
1480 drm_gem_vram_vunmap(gbo
, dst
);