Linux Audio

Check our new training course

Loading...
v5.9
   1/*
   2 * Copyright 2012 Red Hat Inc.
   3 * Parts based on xf86-video-ast
   4 * Copyright (c) 2005 ASPEED Technology Inc.
   5 *
   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:
  13 *
  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.
  21 *
  22 * The above copyright notice and this permission notice (including the
  23 * next paragraph) shall be included in all copies or substantial portions
  24 * of the Software.
  25 *
  26 */
  27/*
  28 * Authors: Dave Airlie <airlied@redhat.com>
  29 */
  30
  31#include <linux/export.h>
  32#include <linux/pci.h>
  33
  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_framebuffer_helper.h>
  41#include <drm/drm_gem_vram_helper.h>
  42#include <drm/drm_plane_helper.h>
  43#include <drm/drm_probe_helper.h>
  44#include <drm/drm_simple_kms_helper.h>
  45
  46#include "ast_drv.h"
  47#include "ast_tables.h"
  48
  49static struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev);
  50static void ast_i2c_destroy(struct ast_i2c_chan *i2c);
  51
  52static inline void ast_load_palette_index(struct ast_private *ast,
  53				     u8 index, u8 red, u8 green,
  54				     u8 blue)
  55{
  56	ast_io_write8(ast, AST_IO_DAC_INDEX_WRITE, index);
  57	ast_io_read8(ast, AST_IO_SEQ_PORT);
  58	ast_io_write8(ast, AST_IO_DAC_DATA, red);
  59	ast_io_read8(ast, AST_IO_SEQ_PORT);
  60	ast_io_write8(ast, AST_IO_DAC_DATA, green);
  61	ast_io_read8(ast, AST_IO_SEQ_PORT);
  62	ast_io_write8(ast, AST_IO_DAC_DATA, blue);
  63	ast_io_read8(ast, AST_IO_SEQ_PORT);
  64}
  65
  66static void ast_crtc_load_lut(struct ast_private *ast, struct drm_crtc *crtc)
  67{
  68	u16 *r, *g, *b;
  69	int i;
  70
  71	if (!crtc->enabled)
  72		return;
  73
  74	r = crtc->gamma_store;
  75	g = r + crtc->gamma_size;
  76	b = g + crtc->gamma_size;
  77
  78	for (i = 0; i < 256; i++)
  79		ast_load_palette_index(ast, i, *r++ >> 8, *g++ >> 8, *b++ >> 8);
  80}
  81
  82static bool ast_get_vbios_mode_info(const struct drm_format_info *format,
  83				    const struct drm_display_mode *mode,
  84				    struct drm_display_mode *adjusted_mode,
  85				    struct ast_vbios_mode_info *vbios_mode)
  86{
  87	u32 refresh_rate_index = 0, refresh_rate;
  88	const struct ast_vbios_enhtable *best = NULL;
  89	u32 hborder, vborder;
  90	bool check_sync;
  91
  92	switch (format->cpp[0] * 8) {
  93	case 8:
  94		vbios_mode->std_table = &vbios_stdtable[VGAModeIndex];
  95		break;
  96	case 16:
  97		vbios_mode->std_table = &vbios_stdtable[HiCModeIndex];
  98		break;
  99	case 24:
 100	case 32:
 101		vbios_mode->std_table = &vbios_stdtable[TrueCModeIndex];
 102		break;
 103	default:
 104		return false;
 105	}
 106
 107	switch (mode->crtc_hdisplay) {
 108	case 640:
 109		vbios_mode->enh_table = &res_640x480[refresh_rate_index];
 110		break;
 111	case 800:
 112		vbios_mode->enh_table = &res_800x600[refresh_rate_index];
 113		break;
 114	case 1024:
 115		vbios_mode->enh_table = &res_1024x768[refresh_rate_index];
 116		break;
 117	case 1280:
 118		if (mode->crtc_vdisplay == 800)
 119			vbios_mode->enh_table = &res_1280x800[refresh_rate_index];
 120		else
 121			vbios_mode->enh_table = &res_1280x1024[refresh_rate_index];
 122		break;
 123	case 1360:
 124		vbios_mode->enh_table = &res_1360x768[refresh_rate_index];
 125		break;
 126	case 1440:
 127		vbios_mode->enh_table = &res_1440x900[refresh_rate_index];
 128		break;
 129	case 1600:
 130		if (mode->crtc_vdisplay == 900)
 131			vbios_mode->enh_table = &res_1600x900[refresh_rate_index];
 132		else
 133			vbios_mode->enh_table = &res_1600x1200[refresh_rate_index];
 134		break;
 135	case 1680:
 136		vbios_mode->enh_table = &res_1680x1050[refresh_rate_index];
 137		break;
 138	case 1920:
 139		if (mode->crtc_vdisplay == 1080)
 140			vbios_mode->enh_table = &res_1920x1080[refresh_rate_index];
 141		else
 142			vbios_mode->enh_table = &res_1920x1200[refresh_rate_index];
 143		break;
 144	default:
 145		return false;
 146	}
 147
 148	refresh_rate = drm_mode_vrefresh(mode);
 149	check_sync = vbios_mode->enh_table->flags & WideScreenMode;
 150
 151	while (1) {
 152		const struct ast_vbios_enhtable *loop = vbios_mode->enh_table;
 153
 154		while (loop->refresh_rate != 0xff) {
 155			if ((check_sync) &&
 156			    (((mode->flags & DRM_MODE_FLAG_NVSYNC)  &&
 157			      (loop->flags & PVSync))  ||
 158			     ((mode->flags & DRM_MODE_FLAG_PVSYNC)  &&
 159			      (loop->flags & NVSync))  ||
 160			     ((mode->flags & DRM_MODE_FLAG_NHSYNC)  &&
 161			      (loop->flags & PHSync))  ||
 162			     ((mode->flags & DRM_MODE_FLAG_PHSYNC)  &&
 163			      (loop->flags & NHSync)))) {
 164				loop++;
 165				continue;
 166			}
 167			if (loop->refresh_rate <= refresh_rate
 168			    && (!best || loop->refresh_rate > best->refresh_rate))
 169				best = loop;
 170			loop++;
 171		}
 172		if (best || !check_sync)
 173			break;
 174		check_sync = 0;
 175	}
 176
 177	if (best)
 178		vbios_mode->enh_table = best;
 179
 180	hborder = (vbios_mode->enh_table->flags & HBorder) ? 8 : 0;
 181	vborder = (vbios_mode->enh_table->flags & VBorder) ? 8 : 0;
 182
 183	adjusted_mode->crtc_htotal = vbios_mode->enh_table->ht;
 184	adjusted_mode->crtc_hblank_start = vbios_mode->enh_table->hde + hborder;
 185	adjusted_mode->crtc_hblank_end = vbios_mode->enh_table->ht - hborder;
 186	adjusted_mode->crtc_hsync_start = vbios_mode->enh_table->hde + hborder +
 187		vbios_mode->enh_table->hfp;
 188	adjusted_mode->crtc_hsync_end = (vbios_mode->enh_table->hde + hborder +
 189					 vbios_mode->enh_table->hfp +
 190					 vbios_mode->enh_table->hsync);
 191
 192	adjusted_mode->crtc_vtotal = vbios_mode->enh_table->vt;
 193	adjusted_mode->crtc_vblank_start = vbios_mode->enh_table->vde + vborder;
 194	adjusted_mode->crtc_vblank_end = vbios_mode->enh_table->vt - vborder;
 195	adjusted_mode->crtc_vsync_start = vbios_mode->enh_table->vde + vborder +
 196		vbios_mode->enh_table->vfp;
 197	adjusted_mode->crtc_vsync_end = (vbios_mode->enh_table->vde + vborder +
 198					 vbios_mode->enh_table->vfp +
 199					 vbios_mode->enh_table->vsync);
 200
 201	return true;
 202}
 203
 204static void ast_set_vbios_color_reg(struct ast_private *ast,
 205				    const struct drm_format_info *format,
 206				    const struct ast_vbios_mode_info *vbios_mode)
 207{
 208	u32 color_index;
 209
 210	switch (format->cpp[0]) {
 211	case 1:
 212		color_index = VGAModeIndex - 1;
 213		break;
 214	case 2:
 215		color_index = HiCModeIndex;
 216		break;
 217	case 3:
 218	case 4:
 219		color_index = TrueCModeIndex;
 220		break;
 221	default:
 222		return;
 223	}
 224
 225	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8c, (u8)((color_index & 0x0f) << 4));
 226
 227	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00);
 228
 229	if (vbios_mode->enh_table->flags & NewModeInfo) {
 230		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8);
 231		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, format->cpp[0] * 8);
 232	}
 233}
 234
 235static void ast_set_vbios_mode_reg(struct ast_private *ast,
 236				   const struct drm_display_mode *adjusted_mode,
 237				   const struct ast_vbios_mode_info *vbios_mode)
 238{
 239	u32 refresh_rate_index, mode_id;
 240
 241	refresh_rate_index = vbios_mode->enh_table->refresh_rate_index;
 242	mode_id = vbios_mode->enh_table->mode_id;
 243
 244	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8d, refresh_rate_index & 0xff);
 245	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8e, mode_id & 0xff);
 246
 247	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00);
 248
 249	if (vbios_mode->enh_table->flags & NewModeInfo) {
 250		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8);
 251		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x93, adjusted_mode->clock / 1000);
 252		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x94, adjusted_mode->crtc_hdisplay);
 253		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x95, adjusted_mode->crtc_hdisplay >> 8);
 254		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x96, adjusted_mode->crtc_vdisplay);
 255		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x97, adjusted_mode->crtc_vdisplay >> 8);
 256	}
 257}
 258
 259static void ast_set_std_reg(struct ast_private *ast,
 260			    struct drm_display_mode *mode,
 261			    struct ast_vbios_mode_info *vbios_mode)
 262{
 263	const struct ast_vbios_stdtable *stdtable;
 264	u32 i;
 265	u8 jreg;
 266
 267	stdtable = vbios_mode->std_table;
 268
 269	jreg = stdtable->misc;
 270	ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg);
 271
 272	/* Set SEQ; except Screen Disable field */
 273	ast_set_index_reg(ast, AST_IO_SEQ_PORT, 0x00, 0x03);
 274	ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, stdtable->seq[0]);
 275	for (i = 1; i < 4; i++) {
 276		jreg = stdtable->seq[i];
 277		ast_set_index_reg(ast, AST_IO_SEQ_PORT, (i + 1) , jreg);
 278	}
 279
 280	/* Set CRTC; except base address and offset */
 281	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00);
 282	for (i = 0; i < 12; i++)
 283		ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]);
 284	for (i = 14; i < 19; i++)
 285		ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]);
 286	for (i = 20; i < 25; i++)
 287		ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]);
 288
 289	/* set AR */
 290	jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ);
 291	for (i = 0; i < 20; i++) {
 292		jreg = stdtable->ar[i];
 293		ast_io_write8(ast, AST_IO_AR_PORT_WRITE, (u8)i);
 294		ast_io_write8(ast, AST_IO_AR_PORT_WRITE, jreg);
 295	}
 296	ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x14);
 297	ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x00);
 298
 299	jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ);
 300	ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x20);
 301
 302	/* Set GR */
 303	for (i = 0; i < 9; i++)
 304		ast_set_index_reg(ast, AST_IO_GR_PORT, i, stdtable->gr[i]);
 305}
 306
 307static void ast_set_crtc_reg(struct ast_private *ast,
 308			     struct drm_display_mode *mode,
 309			     struct ast_vbios_mode_info *vbios_mode)
 310{
 311	u8 jreg05 = 0, jreg07 = 0, jreg09 = 0, jregAC = 0, jregAD = 0, jregAE = 0;
 312	u16 temp, precache = 0;
 313
 314	if ((ast->chip == AST2500) &&
 315	    (vbios_mode->enh_table->flags & AST2500PreCatchCRT))
 316		precache = 40;
 317
 318	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00);
 319
 320	temp = (mode->crtc_htotal >> 3) - 5;
 321	if (temp & 0x100)
 322		jregAC |= 0x01; /* HT D[8] */
 323	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x00, 0x00, temp);
 324
 325	temp = (mode->crtc_hdisplay >> 3) - 1;
 326	if (temp & 0x100)
 327		jregAC |= 0x04; /* HDE D[8] */
 328	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x01, 0x00, temp);
 329
 330	temp = (mode->crtc_hblank_start >> 3) - 1;
 331	if (temp & 0x100)
 332		jregAC |= 0x10; /* HBS D[8] */
 333	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x02, 0x00, temp);
 334
 335	temp = ((mode->crtc_hblank_end >> 3) - 1) & 0x7f;
 336	if (temp & 0x20)
 337		jreg05 |= 0x80;  /* HBE D[5] */
 338	if (temp & 0x40)
 339		jregAD |= 0x01;  /* HBE D[5] */
 340	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x03, 0xE0, (temp & 0x1f));
 341
 342	temp = ((mode->crtc_hsync_start-precache) >> 3) - 1;
 343	if (temp & 0x100)
 344		jregAC |= 0x40; /* HRS D[5] */
 345	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x04, 0x00, temp);
 346
 347	temp = (((mode->crtc_hsync_end-precache) >> 3) - 1) & 0x3f;
 348	if (temp & 0x20)
 349		jregAD |= 0x04; /* HRE D[5] */
 350	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x05, 0x60, (u8)((temp & 0x1f) | jreg05));
 351
 352	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAC, 0x00, jregAC);
 353	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAD, 0x00, jregAD);
 354
 355	/* vert timings */
 356	temp = (mode->crtc_vtotal) - 2;
 357	if (temp & 0x100)
 358		jreg07 |= 0x01;
 359	if (temp & 0x200)
 360		jreg07 |= 0x20;
 361	if (temp & 0x400)
 362		jregAE |= 0x01;
 363	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x06, 0x00, temp);
 364
 365	temp = (mode->crtc_vsync_start) - 1;
 366	if (temp & 0x100)
 367		jreg07 |= 0x04;
 368	if (temp & 0x200)
 369		jreg07 |= 0x80;
 370	if (temp & 0x400)
 371		jregAE |= 0x08;
 372	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x10, 0x00, temp);
 373
 374	temp = (mode->crtc_vsync_end - 1) & 0x3f;
 375	if (temp & 0x10)
 376		jregAE |= 0x20;
 377	if (temp & 0x20)
 378		jregAE |= 0x40;
 379	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x70, temp & 0xf);
 380
 381	temp = mode->crtc_vdisplay - 1;
 382	if (temp & 0x100)
 383		jreg07 |= 0x02;
 384	if (temp & 0x200)
 385		jreg07 |= 0x40;
 386	if (temp & 0x400)
 387		jregAE |= 0x02;
 388	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x12, 0x00, temp);
 389
 390	temp = mode->crtc_vblank_start - 1;
 391	if (temp & 0x100)
 392		jreg07 |= 0x08;
 393	if (temp & 0x200)
 394		jreg09 |= 0x20;
 395	if (temp & 0x400)
 396		jregAE |= 0x04;
 397	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x15, 0x00, temp);
 398
 399	temp = mode->crtc_vblank_end - 1;
 400	if (temp & 0x100)
 401		jregAE |= 0x10;
 402	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x16, 0x00, temp);
 403
 404	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x07, 0x00, jreg07);
 405	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x09, 0xdf, jreg09);
 406	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAE, 0x00, (jregAE | 0x80));
 407
 408	if (precache)
 409		ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x80);
 410	else
 411		ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x00);
 412
 413	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x80);
 414}
 415
 416static void ast_set_offset_reg(struct ast_private *ast,
 417			       struct drm_framebuffer *fb)
 418{
 419	u16 offset;
 420
 421	offset = fb->pitches[0] >> 3;
 422	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x13, (offset & 0xff));
 423	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xb0, (offset >> 8) & 0x3f);
 424}
 425
 426static void ast_set_dclk_reg(struct ast_private *ast,
 427			     struct drm_display_mode *mode,
 428			     struct ast_vbios_mode_info *vbios_mode)
 429{
 430	const struct ast_vbios_dclk_info *clk_info;
 431
 432	if (ast->chip == AST2500)
 433		clk_info = &dclk_table_ast2500[vbios_mode->enh_table->dclk_index];
 434	else
 435		clk_info = &dclk_table[vbios_mode->enh_table->dclk_index];
 436
 437	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc0, 0x00, clk_info->param1);
 438	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc1, 0x00, clk_info->param2);
 439	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xbb, 0x0f,
 440			       (clk_info->param3 & 0xc0) |
 441			       ((clk_info->param3 & 0x3) << 4));
 442}
 443
 444static void ast_set_color_reg(struct ast_private *ast,
 445			      const struct drm_format_info *format)
 446{
 447	u8 jregA0 = 0, jregA3 = 0, jregA8 = 0;
 448
 449	switch (format->cpp[0] * 8) {
 450	case 8:
 451		jregA0 = 0x70;
 452		jregA3 = 0x01;
 453		jregA8 = 0x00;
 454		break;
 455	case 15:
 456	case 16:
 457		jregA0 = 0x70;
 458		jregA3 = 0x04;
 459		jregA8 = 0x02;
 460		break;
 461	case 32:
 462		jregA0 = 0x70;
 463		jregA3 = 0x08;
 464		jregA8 = 0x02;
 465		break;
 466	}
 467
 468	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa0, 0x8f, jregA0);
 469	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xf0, jregA3);
 470	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa8, 0xfd, jregA8);
 471}
 472
 473static void ast_set_crtthd_reg(struct ast_private *ast)
 474{
 475	/* Set Threshold */
 476	if (ast->chip == AST2300 || ast->chip == AST2400 ||
 477	    ast->chip == AST2500) {
 478		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x78);
 479		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x60);
 480	} else if (ast->chip == AST2100 ||
 481		   ast->chip == AST1100 ||
 482		   ast->chip == AST2200 ||
 483		   ast->chip == AST2150) {
 484		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x3f);
 485		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x2f);
 486	} else {
 487		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x2f);
 488		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x1f);
 489	}
 490}
 491
 492static void ast_set_sync_reg(struct ast_private *ast,
 493			     struct drm_display_mode *mode,
 494			     struct ast_vbios_mode_info *vbios_mode)
 495{
 496	u8 jreg;
 497
 498	jreg  = ast_io_read8(ast, AST_IO_MISC_PORT_READ);
 499	jreg &= ~0xC0;
 500	if (vbios_mode->enh_table->flags & NVSync) jreg |= 0x80;
 501	if (vbios_mode->enh_table->flags & NHSync) jreg |= 0x40;
 502	ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg);
 503}
 504
 505static void ast_set_start_address_crt1(struct ast_private *ast,
 506				       unsigned offset)
 507{
 508	u32 addr;
 509
 510	addr = offset >> 2;
 511	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0d, (u8)(addr & 0xff));
 512	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0c, (u8)((addr >> 8) & 0xff));
 513	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xaf, (u8)((addr >> 16) & 0xff));
 514
 515}
 516
 
 
 
 
 
 
 
 
 
 
 517/*
 518 * Primary plane
 519 */
 520
 521static const uint32_t ast_primary_plane_formats[] = {
 522	DRM_FORMAT_XRGB8888,
 523	DRM_FORMAT_RGB565,
 524	DRM_FORMAT_C8,
 525};
 526
 527static int ast_primary_plane_helper_atomic_check(struct drm_plane *plane,
 528						 struct drm_plane_state *state)
 529{
 
 
 530	struct drm_crtc_state *crtc_state;
 531	struct ast_crtc_state *ast_crtc_state;
 532	int ret;
 533
 534	if (!state->crtc)
 535		return 0;
 536
 537	crtc_state = drm_atomic_get_new_crtc_state(state->state, state->crtc);
 
 538
 539	ret = drm_atomic_helper_check_plane_state(state, crtc_state,
 540						  DRM_PLANE_HELPER_NO_SCALING,
 541						  DRM_PLANE_HELPER_NO_SCALING,
 542						  false, true);
 543	if (ret)
 544		return ret;
 545
 546	if (!state->visible)
 547		return 0;
 548
 549	ast_crtc_state = to_ast_crtc_state(crtc_state);
 550
 551	ast_crtc_state->format = state->fb->format;
 552
 553	return 0;
 554}
 555
 556static void
 557ast_primary_plane_helper_atomic_update(struct drm_plane *plane,
 558				       struct drm_plane_state *old_state)
 559{
 
 
 560	struct drm_device *dev = plane->dev;
 561	struct ast_private *ast = to_ast_private(dev);
 562	struct drm_plane_state *state = plane->state;
 
 563	struct drm_gem_vram_object *gbo;
 564	s64 gpu_addr;
 
 
 565
 566	gbo = drm_gem_vram_of_gem(state->fb->obj[0]);
 
 
 
 
 
 
 
 
 
 567	gpu_addr = drm_gem_vram_offset(gbo);
 568	if (drm_WARN_ON_ONCE(dev, gpu_addr < 0))
 569		return; /* Bug: we didn't pin the BO to VRAM in prepare_fb. */
 570
 571	ast_set_offset_reg(ast, state->fb);
 572	ast_set_start_address_crt1(ast, (u32)gpu_addr);
 573
 574	ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x00);
 575}
 576
 577static void
 578ast_primary_plane_helper_atomic_disable(struct drm_plane *plane,
 579					struct drm_plane_state *old_state)
 580{
 581	struct ast_private *ast = to_ast_private(plane->dev);
 582
 583	ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x20);
 584}
 585
 586static const struct drm_plane_helper_funcs ast_primary_plane_helper_funcs = {
 587	.prepare_fb = drm_gem_vram_plane_helper_prepare_fb,
 588	.cleanup_fb = drm_gem_vram_plane_helper_cleanup_fb,
 589	.atomic_check = ast_primary_plane_helper_atomic_check,
 590	.atomic_update = ast_primary_plane_helper_atomic_update,
 591	.atomic_disable = ast_primary_plane_helper_atomic_disable,
 592};
 593
 594static const struct drm_plane_funcs ast_primary_plane_funcs = {
 595	.update_plane = drm_atomic_helper_update_plane,
 596	.disable_plane = drm_atomic_helper_disable_plane,
 597	.destroy = drm_plane_cleanup,
 598	.reset = drm_atomic_helper_plane_reset,
 599	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
 600	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
 601};
 602
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 603/*
 604 * Cursor plane
 605 */
 606
 607static const uint32_t ast_cursor_plane_formats[] = {
 608	DRM_FORMAT_ARGB8888,
 609};
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 610
 611static int
 612ast_cursor_plane_helper_prepare_fb(struct drm_plane *plane,
 613				   struct drm_plane_state *new_state)
 
 
 
 
 
 
 
 
 
 
 
 
 
 614{
 615	struct drm_framebuffer *fb = new_state->fb;
 616	struct drm_crtc *crtc = new_state->crtc;
 617	struct ast_private *ast;
 618	int ret;
 619
 620	if (!crtc || !fb)
 621		return 0;
 
 
 622
 623	ast = to_ast_private(plane->dev);
 
 
 
 
 
 
 624
 625	ret = ast_cursor_blit(ast, fb);
 626	if (ret)
 627		return ret;
 
 
 
 
 628
 629	return 0;
 
 
 
 
 
 
 
 
 
 
 630}
 631
 
 
 
 
 632static int ast_cursor_plane_helper_atomic_check(struct drm_plane *plane,
 633						struct drm_plane_state *state)
 634{
 635	struct drm_framebuffer *fb = state->fb;
 
 
 636	struct drm_crtc_state *crtc_state;
 637	int ret;
 638
 639	if (!state->crtc)
 640		return 0;
 641
 642	crtc_state = drm_atomic_get_new_crtc_state(state->state, state->crtc);
 
 643
 644	ret = drm_atomic_helper_check_plane_state(state, crtc_state,
 645						  DRM_PLANE_HELPER_NO_SCALING,
 646						  DRM_PLANE_HELPER_NO_SCALING,
 647						  true, true);
 648	if (ret)
 649		return ret;
 650
 651	if (!state->visible)
 652		return 0;
 653
 654	if (fb->width > AST_MAX_HWC_WIDTH || fb->height > AST_MAX_HWC_HEIGHT)
 655		return -EINVAL;
 656
 657	return 0;
 658}
 659
 660static void
 661ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
 662				      struct drm_plane_state *old_state)
 663{
 664	struct drm_plane_state *state = plane->state;
 665	struct drm_framebuffer *fb = state->fb;
 666	struct ast_private *ast = plane->dev->dev_private;
 
 
 
 
 
 
 
 
 
 
 667	unsigned int offset_x, offset_y;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 668
 669	offset_x = AST_MAX_HWC_WIDTH - fb->width;
 670	offset_y = AST_MAX_HWC_WIDTH - fb->height;
 671
 672	if (state->fb != old_state->fb) {
 673		/* A new cursor image was installed. */
 674		ast_cursor_page_flip(ast);
 
 
 
 675	}
 
 
 
 
 
 
 
 
 
 676
 677	ast_cursor_show(ast, state->crtc_x, state->crtc_y,
 678			offset_x, offset_y);
 679}
 680
 681static void
 682ast_cursor_plane_helper_atomic_disable(struct drm_plane *plane,
 683				       struct drm_plane_state *old_state)
 684{
 685	struct ast_private *ast = to_ast_private(plane->dev);
 686
 687	ast_cursor_hide(ast);
 688}
 689
 690static const struct drm_plane_helper_funcs ast_cursor_plane_helper_funcs = {
 691	.prepare_fb = ast_cursor_plane_helper_prepare_fb,
 692	.cleanup_fb = NULL, /* not required for cursor plane */
 693	.atomic_check = ast_cursor_plane_helper_atomic_check,
 694	.atomic_update = ast_cursor_plane_helper_atomic_update,
 695	.atomic_disable = ast_cursor_plane_helper_atomic_disable,
 696};
 697
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 698static const struct drm_plane_funcs ast_cursor_plane_funcs = {
 699	.update_plane = drm_atomic_helper_update_plane,
 700	.disable_plane = drm_atomic_helper_disable_plane,
 701	.destroy = drm_plane_cleanup,
 702	.reset = drm_atomic_helper_plane_reset,
 703	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
 704	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
 705};
 706
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 707/*
 708 * CRTC
 709 */
 710
 711static void ast_crtc_dpms(struct drm_crtc *crtc, int mode)
 712{
 713	struct ast_private *ast = to_ast_private(crtc->dev);
 714
 715	/* TODO: Maybe control display signal generation with
 716	 *       Sync Enable (bit CR17.7).
 717	 */
 718	switch (mode) {
 719	case DRM_MODE_DPMS_ON:
 720	case DRM_MODE_DPMS_STANDBY:
 721	case DRM_MODE_DPMS_SUSPEND:
 722		if (ast->tx_chip_type == AST_TX_DP501)
 723			ast_set_dp501_video_output(crtc->dev, 1);
 724		ast_crtc_load_lut(ast, crtc);
 725		break;
 726	case DRM_MODE_DPMS_OFF:
 727		if (ast->tx_chip_type == AST_TX_DP501)
 728			ast_set_dp501_video_output(crtc->dev, 0);
 729		break;
 730	}
 731}
 732
 733static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc,
 734					struct drm_crtc_state *state)
 735{
 
 
 
 736	struct ast_crtc_state *ast_state;
 737	const struct drm_format_info *format;
 738	bool succ;
 739
 740	if (!state->enable)
 741		return 0; /* no mode checks if CRTC is being disabled */
 742
 743	ast_state = to_ast_crtc_state(state);
 744
 745	format = ast_state->format;
 746	if (!format)
 747		return 0;
 748
 749	succ = ast_get_vbios_mode_info(format, &state->mode,
 750				       &state->adjusted_mode,
 751				       &ast_state->vbios_mode_info);
 752	if (!succ)
 753		return -EINVAL;
 754
 755	return 0;
 756}
 757
 758static void ast_crtc_helper_atomic_begin(struct drm_crtc *crtc,
 759					 struct drm_crtc_state *old_crtc_state)
 
 760{
 
 
 
 
 761	struct ast_private *ast = to_ast_private(crtc->dev);
 
 
 762
 763	ast_open_key(ast);
 
 
 
 
 
 764}
 765
 766static void ast_crtc_helper_atomic_flush(struct drm_crtc *crtc,
 767					 struct drm_crtc_state *old_crtc_state)
 
 768{
 769	struct drm_device *dev = crtc->dev;
 770	struct ast_private *ast = to_ast_private(dev);
 771	struct ast_crtc_state *ast_state;
 772	const struct drm_format_info *format;
 773	struct ast_vbios_mode_info *vbios_mode_info;
 774	struct drm_display_mode *adjusted_mode;
 775
 776	ast_state = to_ast_crtc_state(crtc->state);
 777
 778	format = ast_state->format;
 779	if (!format)
 780		return;
 781
 782	vbios_mode_info = &ast_state->vbios_mode_info;
 783
 784	ast_set_color_reg(ast, format);
 785	ast_set_vbios_color_reg(ast, format, vbios_mode_info);
 786
 787	if (!crtc->state->mode_changed)
 788		return;
 789
 790	adjusted_mode = &crtc->state->adjusted_mode;
 791
 792	ast_set_vbios_mode_reg(ast, adjusted_mode, vbios_mode_info);
 793	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06);
 794	ast_set_std_reg(ast, adjusted_mode, vbios_mode_info);
 795	ast_set_crtc_reg(ast, adjusted_mode, vbios_mode_info);
 796	ast_set_dclk_reg(ast, adjusted_mode, vbios_mode_info);
 797	ast_set_crtthd_reg(ast);
 798	ast_set_sync_reg(ast, adjusted_mode, vbios_mode_info);
 799}
 800
 801static void
 802ast_crtc_helper_atomic_enable(struct drm_crtc *crtc,
 803			      struct drm_crtc_state *old_crtc_state)
 804{
 805	ast_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
 806}
 807
 808static void
 809ast_crtc_helper_atomic_disable(struct drm_crtc *crtc,
 810			       struct drm_crtc_state *old_crtc_state)
 811{
 
 
 
 
 
 812	ast_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 813}
 814
 815static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = {
 816	.atomic_check = ast_crtc_helper_atomic_check,
 817	.atomic_begin = ast_crtc_helper_atomic_begin,
 818	.atomic_flush = ast_crtc_helper_atomic_flush,
 819	.atomic_enable = ast_crtc_helper_atomic_enable,
 820	.atomic_disable = ast_crtc_helper_atomic_disable,
 821};
 822
 823static void ast_crtc_reset(struct drm_crtc *crtc)
 824{
 825	struct ast_crtc_state *ast_state =
 826		kzalloc(sizeof(*ast_state), GFP_KERNEL);
 827
 828	if (crtc->state)
 829		crtc->funcs->atomic_destroy_state(crtc, crtc->state);
 830
 831	__drm_atomic_helper_crtc_reset(crtc, &ast_state->base);
 832}
 833
 834static void ast_crtc_destroy(struct drm_crtc *crtc)
 835{
 836	drm_crtc_cleanup(crtc);
 837	kfree(crtc);
 838}
 839
 840static struct drm_crtc_state *
 841ast_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
 842{
 843	struct ast_crtc_state *new_ast_state, *ast_state;
 844	struct drm_device *dev = crtc->dev;
 845
 846	if (drm_WARN_ON(dev, !crtc->state))
 847		return NULL;
 848
 849	new_ast_state = kmalloc(sizeof(*new_ast_state), GFP_KERNEL);
 850	if (!new_ast_state)
 851		return NULL;
 852	__drm_atomic_helper_crtc_duplicate_state(crtc, &new_ast_state->base);
 853
 854	ast_state = to_ast_crtc_state(crtc->state);
 855
 856	new_ast_state->format = ast_state->format;
 857	memcpy(&new_ast_state->vbios_mode_info, &ast_state->vbios_mode_info,
 858	       sizeof(new_ast_state->vbios_mode_info));
 859
 860	return &new_ast_state->base;
 861}
 862
 863static void ast_crtc_atomic_destroy_state(struct drm_crtc *crtc,
 864					  struct drm_crtc_state *state)
 865{
 866	struct ast_crtc_state *ast_state = to_ast_crtc_state(state);
 867
 868	__drm_atomic_helper_crtc_destroy_state(&ast_state->base);
 869	kfree(ast_state);
 870}
 871
 872static const struct drm_crtc_funcs ast_crtc_funcs = {
 873	.reset = ast_crtc_reset,
 874	.gamma_set = drm_atomic_helper_legacy_gamma_set,
 875	.destroy = ast_crtc_destroy,
 876	.set_config = drm_atomic_helper_set_config,
 877	.page_flip = drm_atomic_helper_page_flip,
 878	.atomic_duplicate_state = ast_crtc_atomic_duplicate_state,
 879	.atomic_destroy_state = ast_crtc_atomic_destroy_state,
 880};
 881
 882static int ast_crtc_init(struct drm_device *dev)
 883{
 884	struct ast_private *ast = to_ast_private(dev);
 885	struct drm_crtc *crtc;
 886	int ret;
 887
 888	crtc = kzalloc(sizeof(*crtc), GFP_KERNEL);
 889	if (!crtc)
 890		return -ENOMEM;
 891
 892	ret = drm_crtc_init_with_planes(dev, crtc, &ast->primary_plane,
 893					&ast->cursor_plane, &ast_crtc_funcs,
 894					NULL);
 895	if (ret)
 896		goto err_kfree;
 897
 898	drm_mode_crtc_set_gamma_size(crtc, 256);
 899	drm_crtc_helper_add(crtc, &ast_crtc_helper_funcs);
 900
 901	return 0;
 902
 903err_kfree:
 904	kfree(crtc);
 905	return ret;
 906}
 907
 908/*
 909 * Encoder
 910 */
 911
 912static int ast_encoder_init(struct drm_device *dev)
 913{
 914	struct ast_private *ast = to_ast_private(dev);
 915	struct drm_encoder *encoder = &ast->encoder;
 916	int ret;
 917
 918	ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_DAC);
 919	if (ret)
 920		return ret;
 921
 922	encoder->possible_crtcs = 1;
 923
 924	return 0;
 925}
 926
 927/*
 928 * Connector
 929 */
 930
 931static int ast_get_modes(struct drm_connector *connector)
 932{
 933	struct ast_connector *ast_connector = to_ast_connector(connector);
 934	struct ast_private *ast = to_ast_private(connector->dev);
 935	struct edid *edid;
 936	int ret;
 937	bool flags = false;
 938	if (ast->tx_chip_type == AST_TX_DP501) {
 939		ast->dp501_maxclk = 0xff;
 940		edid = kmalloc(128, GFP_KERNEL);
 941		if (!edid)
 942			return -ENOMEM;
 943
 944		flags = ast_dp501_read_edid(connector->dev, (u8 *)edid);
 945		if (flags)
 946			ast->dp501_maxclk = ast_get_dp501_max_clk(connector->dev);
 947		else
 948			kfree(edid);
 949	}
 950	if (!flags)
 951		edid = drm_get_edid(connector, &ast_connector->i2c->adapter);
 952	if (edid) {
 953		drm_connector_update_edid_property(&ast_connector->base, edid);
 954		ret = drm_add_edid_modes(connector, edid);
 955		kfree(edid);
 956		return ret;
 957	} else
 958		drm_connector_update_edid_property(&ast_connector->base, NULL);
 959	return 0;
 960}
 961
 962static enum drm_mode_status ast_mode_valid(struct drm_connector *connector,
 963			  struct drm_display_mode *mode)
 964{
 965	struct ast_private *ast = to_ast_private(connector->dev);
 966	int flags = MODE_NOMODE;
 967	uint32_t jtemp;
 968
 969	if (ast->support_wide_screen) {
 970		if ((mode->hdisplay == 1680) && (mode->vdisplay == 1050))
 971			return MODE_OK;
 972		if ((mode->hdisplay == 1280) && (mode->vdisplay == 800))
 973			return MODE_OK;
 974		if ((mode->hdisplay == 1440) && (mode->vdisplay == 900))
 975			return MODE_OK;
 976		if ((mode->hdisplay == 1360) && (mode->vdisplay == 768))
 977			return MODE_OK;
 978		if ((mode->hdisplay == 1600) && (mode->vdisplay == 900))
 979			return MODE_OK;
 980
 981		if ((ast->chip == AST2100) || (ast->chip == AST2200) ||
 982		    (ast->chip == AST2300) || (ast->chip == AST2400) ||
 983		    (ast->chip == AST2500)) {
 984			if ((mode->hdisplay == 1920) && (mode->vdisplay == 1080))
 985				return MODE_OK;
 986
 987			if ((mode->hdisplay == 1920) && (mode->vdisplay == 1200)) {
 988				jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
 989				if (jtemp & 0x01)
 990					return MODE_NOMODE;
 991				else
 992					return MODE_OK;
 993			}
 994		}
 995	}
 996	switch (mode->hdisplay) {
 997	case 640:
 998		if (mode->vdisplay == 480) flags = MODE_OK;
 999		break;
1000	case 800:
1001		if (mode->vdisplay == 600) flags = MODE_OK;
1002		break;
1003	case 1024:
1004		if (mode->vdisplay == 768) flags = MODE_OK;
1005		break;
1006	case 1280:
1007		if (mode->vdisplay == 1024) flags = MODE_OK;
1008		break;
1009	case 1600:
1010		if (mode->vdisplay == 1200) flags = MODE_OK;
1011		break;
1012	default:
1013		return flags;
1014	}
1015
1016	return flags;
1017}
1018
1019static void ast_connector_destroy(struct drm_connector *connector)
1020{
1021	struct ast_connector *ast_connector = to_ast_connector(connector);
1022	ast_i2c_destroy(ast_connector->i2c);
1023	drm_connector_cleanup(connector);
1024	kfree(connector);
1025}
1026
1027static const struct drm_connector_helper_funcs ast_connector_helper_funcs = {
1028	.get_modes = ast_get_modes,
1029	.mode_valid = ast_mode_valid,
1030};
1031
1032static const struct drm_connector_funcs ast_connector_funcs = {
1033	.reset = drm_atomic_helper_connector_reset,
1034	.fill_modes = drm_helper_probe_single_connector_modes,
1035	.destroy = ast_connector_destroy,
1036	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
1037	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1038};
1039
1040static int ast_connector_init(struct drm_device *dev)
1041{
1042	struct ast_connector *ast_connector;
1043	struct drm_connector *connector;
1044	struct drm_encoder *encoder;
1045
1046	ast_connector = kzalloc(sizeof(struct ast_connector), GFP_KERNEL);
1047	if (!ast_connector)
1048		return -ENOMEM;
1049
1050	connector = &ast_connector->base;
1051	ast_connector->i2c = ast_i2c_create(dev);
1052	if (!ast_connector->i2c)
1053		drm_err(dev, "failed to add ddc bus for connector\n");
1054
1055	drm_connector_init_with_ddc(dev, connector,
1056				    &ast_connector_funcs,
1057				    DRM_MODE_CONNECTOR_VGA,
1058				    &ast_connector->i2c->adapter);
1059
1060	drm_connector_helper_add(connector, &ast_connector_helper_funcs);
1061
1062	connector->interlace_allowed = 0;
1063	connector->doublescan_allowed = 0;
1064
1065	connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1066
1067	encoder = list_first_entry(&dev->mode_config.encoder_list, struct drm_encoder, head);
1068	drm_connector_attach_encoder(connector, encoder);
1069
1070	return 0;
1071}
1072
1073/*
1074 * Mode config
1075 */
1076
 
 
 
 
 
1077static const struct drm_mode_config_funcs ast_mode_config_funcs = {
1078	.fb_create = drm_gem_fb_create,
1079	.mode_valid = drm_vram_helper_mode_valid,
1080	.atomic_check = drm_atomic_helper_check,
1081	.atomic_commit = drm_atomic_helper_commit,
1082};
1083
1084int ast_mode_config_init(struct ast_private *ast)
1085{
1086	struct drm_device *dev = ast->dev;
 
1087	int ret;
1088
1089	ret = ast_cursor_init(ast);
1090	if (ret)
1091		return ret;
1092
1093	ret = drmm_mode_config_init(dev);
1094	if (ret)
1095		return ret;
1096
1097	dev->mode_config.funcs = &ast_mode_config_funcs;
1098	dev->mode_config.min_width = 0;
1099	dev->mode_config.min_height = 0;
1100	dev->mode_config.preferred_depth = 24;
1101	dev->mode_config.prefer_shadow = 1;
1102	dev->mode_config.fb_base = pci_resource_start(ast->dev->pdev, 0);
1103
1104	if (ast->chip == AST2100 ||
1105	    ast->chip == AST2200 ||
1106	    ast->chip == AST2300 ||
1107	    ast->chip == AST2400 ||
1108	    ast->chip == AST2500) {
1109		dev->mode_config.max_width = 1920;
1110		dev->mode_config.max_height = 2048;
1111	} else {
1112		dev->mode_config.max_width = 1600;
1113		dev->mode_config.max_height = 1200;
1114	}
1115
1116	memset(&ast->primary_plane, 0, sizeof(ast->primary_plane));
1117	ret = drm_universal_plane_init(dev, &ast->primary_plane, 0x01,
1118				       &ast_primary_plane_funcs,
1119				       ast_primary_plane_formats,
1120				       ARRAY_SIZE(ast_primary_plane_formats),
1121				       NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
1122	if (ret) {
1123		drm_err(dev, "ast: drm_universal_plane_init() failed: %d\n", ret);
1124		return ret;
1125	}
1126	drm_plane_helper_add(&ast->primary_plane,
1127			     &ast_primary_plane_helper_funcs);
1128
1129	ret = drm_universal_plane_init(dev, &ast->cursor_plane, 0x01,
1130				       &ast_cursor_plane_funcs,
1131				       ast_cursor_plane_formats,
1132				       ARRAY_SIZE(ast_cursor_plane_formats),
1133				       NULL, DRM_PLANE_TYPE_CURSOR, NULL);
1134	if (ret) {
1135		drm_err(dev, "drm_universal_plane_failed(): %d\n", ret);
1136		return ret;
1137	}
1138	drm_plane_helper_add(&ast->cursor_plane,
1139			     &ast_cursor_plane_helper_funcs);
1140
1141	ast_crtc_init(dev);
1142	ast_encoder_init(dev);
1143	ast_connector_init(dev);
1144
1145	drm_mode_config_reset(dev);
1146
1147	return 0;
1148}
1149
1150static int get_clock(void *i2c_priv)
1151{
1152	struct ast_i2c_chan *i2c = i2c_priv;
1153	struct ast_private *ast = to_ast_private(i2c->dev);
1154	uint32_t val, val2, count, pass;
1155
1156	count = 0;
1157	pass = 0;
1158	val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
1159	do {
1160		val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
1161		if (val == val2) {
1162			pass++;
1163		} else {
1164			pass = 0;
1165			val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
1166		}
1167	} while ((pass < 5) && (count++ < 0x10000));
1168
1169	return val & 1 ? 1 : 0;
1170}
1171
1172static int get_data(void *i2c_priv)
1173{
1174	struct ast_i2c_chan *i2c = i2c_priv;
1175	struct ast_private *ast = to_ast_private(i2c->dev);
1176	uint32_t val, val2, count, pass;
1177
1178	count = 0;
1179	pass = 0;
1180	val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
1181	do {
1182		val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
1183		if (val == val2) {
1184			pass++;
1185		} else {
1186			pass = 0;
1187			val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
1188		}
1189	} while ((pass < 5) && (count++ < 0x10000));
1190
1191	return val & 1 ? 1 : 0;
1192}
1193
1194static void set_clock(void *i2c_priv, int clock)
1195{
1196	struct ast_i2c_chan *i2c = i2c_priv;
1197	struct ast_private *ast = to_ast_private(i2c->dev);
1198	int i;
1199	u8 ujcrb7, jtemp;
1200
1201	for (i = 0; i < 0x10000; i++) {
1202		ujcrb7 = ((clock & 0x01) ? 0 : 1);
1203		ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf4, ujcrb7);
1204		jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x01);
1205		if (ujcrb7 == jtemp)
1206			break;
1207	}
1208}
1209
1210static void set_data(void *i2c_priv, int data)
1211{
1212	struct ast_i2c_chan *i2c = i2c_priv;
1213	struct ast_private *ast = to_ast_private(i2c->dev);
1214	int i;
1215	u8 ujcrb7, jtemp;
1216
1217	for (i = 0; i < 0x10000; i++) {
1218		ujcrb7 = ((data & 0x01) ? 0 : 1) << 2;
1219		ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf1, ujcrb7);
1220		jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x04);
1221		if (ujcrb7 == jtemp)
1222			break;
1223	}
1224}
1225
1226static struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev)
1227{
1228	struct ast_i2c_chan *i2c;
1229	int ret;
1230
1231	i2c = kzalloc(sizeof(struct ast_i2c_chan), GFP_KERNEL);
1232	if (!i2c)
1233		return NULL;
1234
1235	i2c->adapter.owner = THIS_MODULE;
1236	i2c->adapter.class = I2C_CLASS_DDC;
1237	i2c->adapter.dev.parent = &dev->pdev->dev;
1238	i2c->dev = dev;
1239	i2c_set_adapdata(&i2c->adapter, i2c);
1240	snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
1241		 "AST i2c bit bus");
1242	i2c->adapter.algo_data = &i2c->bit;
1243
1244	i2c->bit.udelay = 20;
1245	i2c->bit.timeout = 2;
1246	i2c->bit.data = i2c;
1247	i2c->bit.setsda = set_data;
1248	i2c->bit.setscl = set_clock;
1249	i2c->bit.getsda = get_data;
1250	i2c->bit.getscl = get_clock;
1251	ret = i2c_bit_add_bus(&i2c->adapter);
1252	if (ret) {
1253		drm_err(dev, "Failed to register bit i2c\n");
1254		goto out_free;
1255	}
1256
1257	return i2c;
1258out_free:
1259	kfree(i2c);
1260	return NULL;
1261}
1262
1263static void ast_i2c_destroy(struct ast_i2c_chan *i2c)
1264{
1265	if (!i2c)
1266		return;
1267	i2c_del_adapter(&i2c->adapter);
1268	kfree(i2c);
1269}
v5.14.15
   1/*
   2 * Copyright 2012 Red Hat Inc.
   3 * Parts based on xf86-video-ast
   4 * Copyright (c) 2005 ASPEED Technology Inc.
   5 *
   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:
  13 *
  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.
  21 *
  22 * The above copyright notice and this permission notice (including the
  23 * next paragraph) shall be included in all copies or substantial portions
  24 * of the Software.
  25 *
  26 */
  27/*
  28 * Authors: Dave Airlie <airlied@redhat.com>
  29 */
  30
  31#include <linux/export.h>
  32#include <linux/pci.h>
  33
  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_atomic_helper.h>
  41#include <drm/drm_gem_framebuffer_helper.h>
  42#include <drm/drm_gem_vram_helper.h>
  43#include <drm/drm_plane_helper.h>
  44#include <drm/drm_probe_helper.h>
  45#include <drm/drm_simple_kms_helper.h>
  46
  47#include "ast_drv.h"
  48#include "ast_tables.h"
  49
  50static struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev);
  51static void ast_i2c_destroy(struct ast_i2c_chan *i2c);
  52
  53static inline void ast_load_palette_index(struct ast_private *ast,
  54				     u8 index, u8 red, u8 green,
  55				     u8 blue)
  56{
  57	ast_io_write8(ast, AST_IO_DAC_INDEX_WRITE, index);
  58	ast_io_read8(ast, AST_IO_SEQ_PORT);
  59	ast_io_write8(ast, AST_IO_DAC_DATA, red);
  60	ast_io_read8(ast, AST_IO_SEQ_PORT);
  61	ast_io_write8(ast, AST_IO_DAC_DATA, green);
  62	ast_io_read8(ast, AST_IO_SEQ_PORT);
  63	ast_io_write8(ast, AST_IO_DAC_DATA, blue);
  64	ast_io_read8(ast, AST_IO_SEQ_PORT);
  65}
  66
  67static void ast_crtc_load_lut(struct ast_private *ast, struct drm_crtc *crtc)
  68{
  69	u16 *r, *g, *b;
  70	int i;
  71
  72	if (!crtc->enabled)
  73		return;
  74
  75	r = crtc->gamma_store;
  76	g = r + crtc->gamma_size;
  77	b = g + crtc->gamma_size;
  78
  79	for (i = 0; i < 256; i++)
  80		ast_load_palette_index(ast, i, *r++ >> 8, *g++ >> 8, *b++ >> 8);
  81}
  82
  83static bool ast_get_vbios_mode_info(const struct drm_format_info *format,
  84				    const struct drm_display_mode *mode,
  85				    struct drm_display_mode *adjusted_mode,
  86				    struct ast_vbios_mode_info *vbios_mode)
  87{
  88	u32 refresh_rate_index = 0, refresh_rate;
  89	const struct ast_vbios_enhtable *best = NULL;
  90	u32 hborder, vborder;
  91	bool check_sync;
  92
  93	switch (format->cpp[0] * 8) {
  94	case 8:
  95		vbios_mode->std_table = &vbios_stdtable[VGAModeIndex];
  96		break;
  97	case 16:
  98		vbios_mode->std_table = &vbios_stdtable[HiCModeIndex];
  99		break;
 100	case 24:
 101	case 32:
 102		vbios_mode->std_table = &vbios_stdtable[TrueCModeIndex];
 103		break;
 104	default:
 105		return false;
 106	}
 107
 108	switch (mode->crtc_hdisplay) {
 109	case 640:
 110		vbios_mode->enh_table = &res_640x480[refresh_rate_index];
 111		break;
 112	case 800:
 113		vbios_mode->enh_table = &res_800x600[refresh_rate_index];
 114		break;
 115	case 1024:
 116		vbios_mode->enh_table = &res_1024x768[refresh_rate_index];
 117		break;
 118	case 1280:
 119		if (mode->crtc_vdisplay == 800)
 120			vbios_mode->enh_table = &res_1280x800[refresh_rate_index];
 121		else
 122			vbios_mode->enh_table = &res_1280x1024[refresh_rate_index];
 123		break;
 124	case 1360:
 125		vbios_mode->enh_table = &res_1360x768[refresh_rate_index];
 126		break;
 127	case 1440:
 128		vbios_mode->enh_table = &res_1440x900[refresh_rate_index];
 129		break;
 130	case 1600:
 131		if (mode->crtc_vdisplay == 900)
 132			vbios_mode->enh_table = &res_1600x900[refresh_rate_index];
 133		else
 134			vbios_mode->enh_table = &res_1600x1200[refresh_rate_index];
 135		break;
 136	case 1680:
 137		vbios_mode->enh_table = &res_1680x1050[refresh_rate_index];
 138		break;
 139	case 1920:
 140		if (mode->crtc_vdisplay == 1080)
 141			vbios_mode->enh_table = &res_1920x1080[refresh_rate_index];
 142		else
 143			vbios_mode->enh_table = &res_1920x1200[refresh_rate_index];
 144		break;
 145	default:
 146		return false;
 147	}
 148
 149	refresh_rate = drm_mode_vrefresh(mode);
 150	check_sync = vbios_mode->enh_table->flags & WideScreenMode;
 151
 152	while (1) {
 153		const struct ast_vbios_enhtable *loop = vbios_mode->enh_table;
 154
 155		while (loop->refresh_rate != 0xff) {
 156			if ((check_sync) &&
 157			    (((mode->flags & DRM_MODE_FLAG_NVSYNC)  &&
 158			      (loop->flags & PVSync))  ||
 159			     ((mode->flags & DRM_MODE_FLAG_PVSYNC)  &&
 160			      (loop->flags & NVSync))  ||
 161			     ((mode->flags & DRM_MODE_FLAG_NHSYNC)  &&
 162			      (loop->flags & PHSync))  ||
 163			     ((mode->flags & DRM_MODE_FLAG_PHSYNC)  &&
 164			      (loop->flags & NHSync)))) {
 165				loop++;
 166				continue;
 167			}
 168			if (loop->refresh_rate <= refresh_rate
 169			    && (!best || loop->refresh_rate > best->refresh_rate))
 170				best = loop;
 171			loop++;
 172		}
 173		if (best || !check_sync)
 174			break;
 175		check_sync = 0;
 176	}
 177
 178	if (best)
 179		vbios_mode->enh_table = best;
 180
 181	hborder = (vbios_mode->enh_table->flags & HBorder) ? 8 : 0;
 182	vborder = (vbios_mode->enh_table->flags & VBorder) ? 8 : 0;
 183
 184	adjusted_mode->crtc_htotal = vbios_mode->enh_table->ht;
 185	adjusted_mode->crtc_hblank_start = vbios_mode->enh_table->hde + hborder;
 186	adjusted_mode->crtc_hblank_end = vbios_mode->enh_table->ht - hborder;
 187	adjusted_mode->crtc_hsync_start = vbios_mode->enh_table->hde + hborder +
 188		vbios_mode->enh_table->hfp;
 189	adjusted_mode->crtc_hsync_end = (vbios_mode->enh_table->hde + hborder +
 190					 vbios_mode->enh_table->hfp +
 191					 vbios_mode->enh_table->hsync);
 192
 193	adjusted_mode->crtc_vtotal = vbios_mode->enh_table->vt;
 194	adjusted_mode->crtc_vblank_start = vbios_mode->enh_table->vde + vborder;
 195	adjusted_mode->crtc_vblank_end = vbios_mode->enh_table->vt - vborder;
 196	adjusted_mode->crtc_vsync_start = vbios_mode->enh_table->vde + vborder +
 197		vbios_mode->enh_table->vfp;
 198	adjusted_mode->crtc_vsync_end = (vbios_mode->enh_table->vde + vborder +
 199					 vbios_mode->enh_table->vfp +
 200					 vbios_mode->enh_table->vsync);
 201
 202	return true;
 203}
 204
 205static void ast_set_vbios_color_reg(struct ast_private *ast,
 206				    const struct drm_format_info *format,
 207				    const struct ast_vbios_mode_info *vbios_mode)
 208{
 209	u32 color_index;
 210
 211	switch (format->cpp[0]) {
 212	case 1:
 213		color_index = VGAModeIndex - 1;
 214		break;
 215	case 2:
 216		color_index = HiCModeIndex;
 217		break;
 218	case 3:
 219	case 4:
 220		color_index = TrueCModeIndex;
 221		break;
 222	default:
 223		return;
 224	}
 225
 226	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8c, (u8)((color_index & 0x0f) << 4));
 227
 228	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00);
 229
 230	if (vbios_mode->enh_table->flags & NewModeInfo) {
 231		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8);
 232		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, format->cpp[0] * 8);
 233	}
 234}
 235
 236static void ast_set_vbios_mode_reg(struct ast_private *ast,
 237				   const struct drm_display_mode *adjusted_mode,
 238				   const struct ast_vbios_mode_info *vbios_mode)
 239{
 240	u32 refresh_rate_index, mode_id;
 241
 242	refresh_rate_index = vbios_mode->enh_table->refresh_rate_index;
 243	mode_id = vbios_mode->enh_table->mode_id;
 244
 245	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8d, refresh_rate_index & 0xff);
 246	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8e, mode_id & 0xff);
 247
 248	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00);
 249
 250	if (vbios_mode->enh_table->flags & NewModeInfo) {
 251		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8);
 252		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x93, adjusted_mode->clock / 1000);
 253		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x94, adjusted_mode->crtc_hdisplay);
 254		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x95, adjusted_mode->crtc_hdisplay >> 8);
 255		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x96, adjusted_mode->crtc_vdisplay);
 256		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x97, adjusted_mode->crtc_vdisplay >> 8);
 257	}
 258}
 259
 260static void ast_set_std_reg(struct ast_private *ast,
 261			    struct drm_display_mode *mode,
 262			    struct ast_vbios_mode_info *vbios_mode)
 263{
 264	const struct ast_vbios_stdtable *stdtable;
 265	u32 i;
 266	u8 jreg;
 267
 268	stdtable = vbios_mode->std_table;
 269
 270	jreg = stdtable->misc;
 271	ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg);
 272
 273	/* Set SEQ; except Screen Disable field */
 274	ast_set_index_reg(ast, AST_IO_SEQ_PORT, 0x00, 0x03);
 275	ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, stdtable->seq[0]);
 276	for (i = 1; i < 4; i++) {
 277		jreg = stdtable->seq[i];
 278		ast_set_index_reg(ast, AST_IO_SEQ_PORT, (i + 1) , jreg);
 279	}
 280
 281	/* Set CRTC; except base address and offset */
 282	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00);
 283	for (i = 0; i < 12; i++)
 284		ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]);
 285	for (i = 14; i < 19; i++)
 286		ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]);
 287	for (i = 20; i < 25; i++)
 288		ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]);
 289
 290	/* set AR */
 291	jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ);
 292	for (i = 0; i < 20; i++) {
 293		jreg = stdtable->ar[i];
 294		ast_io_write8(ast, AST_IO_AR_PORT_WRITE, (u8)i);
 295		ast_io_write8(ast, AST_IO_AR_PORT_WRITE, jreg);
 296	}
 297	ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x14);
 298	ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x00);
 299
 300	jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ);
 301	ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x20);
 302
 303	/* Set GR */
 304	for (i = 0; i < 9; i++)
 305		ast_set_index_reg(ast, AST_IO_GR_PORT, i, stdtable->gr[i]);
 306}
 307
 308static void ast_set_crtc_reg(struct ast_private *ast,
 309			     struct drm_display_mode *mode,
 310			     struct ast_vbios_mode_info *vbios_mode)
 311{
 312	u8 jreg05 = 0, jreg07 = 0, jreg09 = 0, jregAC = 0, jregAD = 0, jregAE = 0;
 313	u16 temp, precache = 0;
 314
 315	if ((ast->chip == AST2500) &&
 316	    (vbios_mode->enh_table->flags & AST2500PreCatchCRT))
 317		precache = 40;
 318
 319	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00);
 320
 321	temp = (mode->crtc_htotal >> 3) - 5;
 322	if (temp & 0x100)
 323		jregAC |= 0x01; /* HT D[8] */
 324	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x00, 0x00, temp);
 325
 326	temp = (mode->crtc_hdisplay >> 3) - 1;
 327	if (temp & 0x100)
 328		jregAC |= 0x04; /* HDE D[8] */
 329	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x01, 0x00, temp);
 330
 331	temp = (mode->crtc_hblank_start >> 3) - 1;
 332	if (temp & 0x100)
 333		jregAC |= 0x10; /* HBS D[8] */
 334	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x02, 0x00, temp);
 335
 336	temp = ((mode->crtc_hblank_end >> 3) - 1) & 0x7f;
 337	if (temp & 0x20)
 338		jreg05 |= 0x80;  /* HBE D[5] */
 339	if (temp & 0x40)
 340		jregAD |= 0x01;  /* HBE D[5] */
 341	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x03, 0xE0, (temp & 0x1f));
 342
 343	temp = ((mode->crtc_hsync_start-precache) >> 3) - 1;
 344	if (temp & 0x100)
 345		jregAC |= 0x40; /* HRS D[5] */
 346	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x04, 0x00, temp);
 347
 348	temp = (((mode->crtc_hsync_end-precache) >> 3) - 1) & 0x3f;
 349	if (temp & 0x20)
 350		jregAD |= 0x04; /* HRE D[5] */
 351	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x05, 0x60, (u8)((temp & 0x1f) | jreg05));
 352
 353	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAC, 0x00, jregAC);
 354	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAD, 0x00, jregAD);
 355
 356	/* vert timings */
 357	temp = (mode->crtc_vtotal) - 2;
 358	if (temp & 0x100)
 359		jreg07 |= 0x01;
 360	if (temp & 0x200)
 361		jreg07 |= 0x20;
 362	if (temp & 0x400)
 363		jregAE |= 0x01;
 364	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x06, 0x00, temp);
 365
 366	temp = (mode->crtc_vsync_start) - 1;
 367	if (temp & 0x100)
 368		jreg07 |= 0x04;
 369	if (temp & 0x200)
 370		jreg07 |= 0x80;
 371	if (temp & 0x400)
 372		jregAE |= 0x08;
 373	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x10, 0x00, temp);
 374
 375	temp = (mode->crtc_vsync_end - 1) & 0x3f;
 376	if (temp & 0x10)
 377		jregAE |= 0x20;
 378	if (temp & 0x20)
 379		jregAE |= 0x40;
 380	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x70, temp & 0xf);
 381
 382	temp = mode->crtc_vdisplay - 1;
 383	if (temp & 0x100)
 384		jreg07 |= 0x02;
 385	if (temp & 0x200)
 386		jreg07 |= 0x40;
 387	if (temp & 0x400)
 388		jregAE |= 0x02;
 389	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x12, 0x00, temp);
 390
 391	temp = mode->crtc_vblank_start - 1;
 392	if (temp & 0x100)
 393		jreg07 |= 0x08;
 394	if (temp & 0x200)
 395		jreg09 |= 0x20;
 396	if (temp & 0x400)
 397		jregAE |= 0x04;
 398	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x15, 0x00, temp);
 399
 400	temp = mode->crtc_vblank_end - 1;
 401	if (temp & 0x100)
 402		jregAE |= 0x10;
 403	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x16, 0x00, temp);
 404
 405	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x07, 0x00, jreg07);
 406	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x09, 0xdf, jreg09);
 407	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAE, 0x00, (jregAE | 0x80));
 408
 409	if (precache)
 410		ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x80);
 411	else
 412		ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x00);
 413
 414	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x80);
 415}
 416
 417static void ast_set_offset_reg(struct ast_private *ast,
 418			       struct drm_framebuffer *fb)
 419{
 420	u16 offset;
 421
 422	offset = fb->pitches[0] >> 3;
 423	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x13, (offset & 0xff));
 424	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xb0, (offset >> 8) & 0x3f);
 425}
 426
 427static void ast_set_dclk_reg(struct ast_private *ast,
 428			     struct drm_display_mode *mode,
 429			     struct ast_vbios_mode_info *vbios_mode)
 430{
 431	const struct ast_vbios_dclk_info *clk_info;
 432
 433	if (ast->chip == AST2500)
 434		clk_info = &dclk_table_ast2500[vbios_mode->enh_table->dclk_index];
 435	else
 436		clk_info = &dclk_table[vbios_mode->enh_table->dclk_index];
 437
 438	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc0, 0x00, clk_info->param1);
 439	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc1, 0x00, clk_info->param2);
 440	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xbb, 0x0f,
 441			       (clk_info->param3 & 0xc0) |
 442			       ((clk_info->param3 & 0x3) << 4));
 443}
 444
 445static void ast_set_color_reg(struct ast_private *ast,
 446			      const struct drm_format_info *format)
 447{
 448	u8 jregA0 = 0, jregA3 = 0, jregA8 = 0;
 449
 450	switch (format->cpp[0] * 8) {
 451	case 8:
 452		jregA0 = 0x70;
 453		jregA3 = 0x01;
 454		jregA8 = 0x00;
 455		break;
 456	case 15:
 457	case 16:
 458		jregA0 = 0x70;
 459		jregA3 = 0x04;
 460		jregA8 = 0x02;
 461		break;
 462	case 32:
 463		jregA0 = 0x70;
 464		jregA3 = 0x08;
 465		jregA8 = 0x02;
 466		break;
 467	}
 468
 469	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa0, 0x8f, jregA0);
 470	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xf0, jregA3);
 471	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa8, 0xfd, jregA8);
 472}
 473
 474static void ast_set_crtthd_reg(struct ast_private *ast)
 475{
 476	/* Set Threshold */
 477	if (ast->chip == AST2300 || ast->chip == AST2400 ||
 478	    ast->chip == AST2500) {
 479		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x78);
 480		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x60);
 481	} else if (ast->chip == AST2100 ||
 482		   ast->chip == AST1100 ||
 483		   ast->chip == AST2200 ||
 484		   ast->chip == AST2150) {
 485		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x3f);
 486		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x2f);
 487	} else {
 488		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x2f);
 489		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x1f);
 490	}
 491}
 492
 493static void ast_set_sync_reg(struct ast_private *ast,
 494			     struct drm_display_mode *mode,
 495			     struct ast_vbios_mode_info *vbios_mode)
 496{
 497	u8 jreg;
 498
 499	jreg  = ast_io_read8(ast, AST_IO_MISC_PORT_READ);
 500	jreg &= ~0xC0;
 501	if (vbios_mode->enh_table->flags & NVSync) jreg |= 0x80;
 502	if (vbios_mode->enh_table->flags & NHSync) jreg |= 0x40;
 503	ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg);
 504}
 505
 506static void ast_set_start_address_crt1(struct ast_private *ast,
 507				       unsigned offset)
 508{
 509	u32 addr;
 510
 511	addr = offset >> 2;
 512	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0d, (u8)(addr & 0xff));
 513	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0c, (u8)((addr >> 8) & 0xff));
 514	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xaf, (u8)((addr >> 16) & 0xff));
 515
 516}
 517
 518static void ast_wait_for_vretrace(struct ast_private *ast)
 519{
 520	unsigned long timeout = jiffies + HZ;
 521	u8 vgair1;
 522
 523	do {
 524		vgair1 = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ);
 525	} while (!(vgair1 & AST_IO_VGAIR1_VREFRESH) && time_before(jiffies, timeout));
 526}
 527
 528/*
 529 * Primary plane
 530 */
 531
 532static const uint32_t ast_primary_plane_formats[] = {
 533	DRM_FORMAT_XRGB8888,
 534	DRM_FORMAT_RGB565,
 535	DRM_FORMAT_C8,
 536};
 537
 538static int ast_primary_plane_helper_atomic_check(struct drm_plane *plane,
 539						 struct drm_atomic_state *state)
 540{
 541	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
 542										 plane);
 543	struct drm_crtc_state *crtc_state;
 544	struct ast_crtc_state *ast_crtc_state;
 545	int ret;
 546
 547	if (!new_plane_state->crtc)
 548		return 0;
 549
 550	crtc_state = drm_atomic_get_new_crtc_state(state,
 551						   new_plane_state->crtc);
 552
 553	ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
 554						  DRM_PLANE_HELPER_NO_SCALING,
 555						  DRM_PLANE_HELPER_NO_SCALING,
 556						  false, true);
 557	if (ret)
 558		return ret;
 559
 560	if (!new_plane_state->visible)
 561		return 0;
 562
 563	ast_crtc_state = to_ast_crtc_state(crtc_state);
 564
 565	ast_crtc_state->format = new_plane_state->fb->format;
 566
 567	return 0;
 568}
 569
 570static void
 571ast_primary_plane_helper_atomic_update(struct drm_plane *plane,
 572				       struct drm_atomic_state *state)
 573{
 574	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
 575									   plane);
 576	struct drm_device *dev = plane->dev;
 577	struct ast_private *ast = to_ast_private(dev);
 578	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
 579									   plane);
 580	struct drm_gem_vram_object *gbo;
 581	s64 gpu_addr;
 582	struct drm_framebuffer *fb = new_state->fb;
 583	struct drm_framebuffer *old_fb = old_state->fb;
 584
 585	if (!old_fb || (fb->format != old_fb->format)) {
 586		struct drm_crtc_state *crtc_state = new_state->crtc->state;
 587		struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
 588		struct ast_vbios_mode_info *vbios_mode_info = &ast_crtc_state->vbios_mode_info;
 589
 590		ast_set_color_reg(ast, fb->format);
 591		ast_set_vbios_color_reg(ast, fb->format, vbios_mode_info);
 592	}
 593
 594	gbo = drm_gem_vram_of_gem(fb->obj[0]);
 595	gpu_addr = drm_gem_vram_offset(gbo);
 596	if (drm_WARN_ON_ONCE(dev, gpu_addr < 0))
 597		return; /* Bug: we didn't pin the BO to VRAM in prepare_fb. */
 598
 599	ast_set_offset_reg(ast, fb);
 600	ast_set_start_address_crt1(ast, (u32)gpu_addr);
 601
 602	ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x00);
 603}
 604
 605static void
 606ast_primary_plane_helper_atomic_disable(struct drm_plane *plane,
 607					struct drm_atomic_state *state)
 608{
 609	struct ast_private *ast = to_ast_private(plane->dev);
 610
 611	ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x20);
 612}
 613
 614static const struct drm_plane_helper_funcs ast_primary_plane_helper_funcs = {
 615	.prepare_fb = drm_gem_vram_plane_helper_prepare_fb,
 616	.cleanup_fb = drm_gem_vram_plane_helper_cleanup_fb,
 617	.atomic_check = ast_primary_plane_helper_atomic_check,
 618	.atomic_update = ast_primary_plane_helper_atomic_update,
 619	.atomic_disable = ast_primary_plane_helper_atomic_disable,
 620};
 621
 622static const struct drm_plane_funcs ast_primary_plane_funcs = {
 623	.update_plane = drm_atomic_helper_update_plane,
 624	.disable_plane = drm_atomic_helper_disable_plane,
 625	.destroy = drm_plane_cleanup,
 626	.reset = drm_atomic_helper_plane_reset,
 627	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
 628	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
 629};
 630
 631static int ast_primary_plane_init(struct ast_private *ast)
 632{
 633	struct drm_device *dev = &ast->base;
 634	struct drm_plane *primary_plane = &ast->primary_plane;
 635	int ret;
 636
 637	ret = drm_universal_plane_init(dev, primary_plane, 0x01,
 638				       &ast_primary_plane_funcs,
 639				       ast_primary_plane_formats,
 640				       ARRAY_SIZE(ast_primary_plane_formats),
 641				       NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
 642	if (ret) {
 643		drm_err(dev, "drm_universal_plane_init() failed: %d\n", ret);
 644		return ret;
 645	}
 646	drm_plane_helper_add(primary_plane, &ast_primary_plane_helper_funcs);
 647
 648	return 0;
 649}
 650
 651/*
 652 * Cursor plane
 653 */
 654
 655static void ast_update_cursor_image(u8 __iomem *dst, const u8 *src, int width, int height)
 656{
 657	union {
 658		u32 ul;
 659		u8 b[4];
 660	} srcdata32[2], data32;
 661	union {
 662		u16 us;
 663		u8 b[2];
 664	} data16;
 665	u32 csum = 0;
 666	s32 alpha_dst_delta, last_alpha_dst_delta;
 667	u8 __iomem *dstxor;
 668	const u8 *srcxor;
 669	int i, j;
 670	u32 per_pixel_copy, two_pixel_copy;
 671
 672	alpha_dst_delta = AST_MAX_HWC_WIDTH << 1;
 673	last_alpha_dst_delta = alpha_dst_delta - (width << 1);
 674
 675	srcxor = src;
 676	dstxor = (u8 *)dst + last_alpha_dst_delta + (AST_MAX_HWC_HEIGHT - height) * alpha_dst_delta;
 677	per_pixel_copy = width & 1;
 678	two_pixel_copy = width >> 1;
 679
 680	for (j = 0; j < height; j++) {
 681		for (i = 0; i < two_pixel_copy; i++) {
 682			srcdata32[0].ul = *((u32 *)srcxor) & 0xf0f0f0f0;
 683			srcdata32[1].ul = *((u32 *)(srcxor + 4)) & 0xf0f0f0f0;
 684			data32.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4);
 685			data32.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4);
 686			data32.b[2] = srcdata32[1].b[1] | (srcdata32[1].b[0] >> 4);
 687			data32.b[3] = srcdata32[1].b[3] | (srcdata32[1].b[2] >> 4);
 688
 689			writel(data32.ul, dstxor);
 690			csum += data32.ul;
 691
 692			dstxor += 4;
 693			srcxor += 8;
 694
 695		}
 696
 697		for (i = 0; i < per_pixel_copy; i++) {
 698			srcdata32[0].ul = *((u32 *)srcxor) & 0xf0f0f0f0;
 699			data16.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4);
 700			data16.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4);
 701			writew(data16.us, dstxor);
 702			csum += (u32)data16.us;
 703
 704			dstxor += 2;
 705			srcxor += 4;
 706		}
 707		dstxor += last_alpha_dst_delta;
 708	}
 709
 710	/* write checksum + signature */
 711	dst += AST_HWC_SIZE;
 712	writel(csum, dst);
 713	writel(width, dst + AST_HWC_SIGNATURE_SizeX);
 714	writel(height, dst + AST_HWC_SIGNATURE_SizeY);
 715	writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTX);
 716	writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTY);
 717}
 718
 719static void ast_set_cursor_base(struct ast_private *ast, u64 address)
 720{
 721	u8 addr0 = (address >> 3) & 0xff;
 722	u8 addr1 = (address >> 11) & 0xff;
 723	u8 addr2 = (address >> 19) & 0xff;
 
 724
 725	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc8, addr0);
 726	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc9, addr1);
 727	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xca, addr2);
 728}
 729
 730static void ast_set_cursor_location(struct ast_private *ast, u16 x, u16 y,
 731				    u8 x_offset, u8 y_offset)
 732{
 733	u8 x0 = (x & 0x00ff);
 734	u8 x1 = (x & 0x0f00) >> 8;
 735	u8 y0 = (y & 0x00ff);
 736	u8 y1 = (y & 0x0700) >> 8;
 737
 738	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc2, x_offset);
 739	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc3, y_offset);
 740	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc4, x0);
 741	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc5, x1);
 742	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc6, y0);
 743	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc7, y1);
 744}
 745
 746static void ast_set_cursor_enabled(struct ast_private *ast, bool enabled)
 747{
 748	static const u8 mask = (u8)~(AST_IO_VGACRCB_HWC_16BPP |
 749				     AST_IO_VGACRCB_HWC_ENABLED);
 750
 751	u8 vgacrcb = AST_IO_VGACRCB_HWC_16BPP;
 752
 753	if (enabled)
 754		vgacrcb |= AST_IO_VGACRCB_HWC_ENABLED;
 755
 756	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, mask, vgacrcb);
 757}
 758
 759static const uint32_t ast_cursor_plane_formats[] = {
 760	DRM_FORMAT_ARGB8888,
 761};
 762
 763static int ast_cursor_plane_helper_atomic_check(struct drm_plane *plane,
 764						struct drm_atomic_state *state)
 765{
 766	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
 767										 plane);
 768	struct drm_framebuffer *fb = new_plane_state->fb;
 769	struct drm_crtc_state *crtc_state;
 770	int ret;
 771
 772	if (!new_plane_state->crtc)
 773		return 0;
 774
 775	crtc_state = drm_atomic_get_new_crtc_state(state,
 776						   new_plane_state->crtc);
 777
 778	ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
 779						  DRM_PLANE_HELPER_NO_SCALING,
 780						  DRM_PLANE_HELPER_NO_SCALING,
 781						  true, true);
 782	if (ret)
 783		return ret;
 784
 785	if (!new_plane_state->visible)
 786		return 0;
 787
 788	if (fb->width > AST_MAX_HWC_WIDTH || fb->height > AST_MAX_HWC_HEIGHT)
 789		return -EINVAL;
 790
 791	return 0;
 792}
 793
 794static void
 795ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
 796				      struct drm_atomic_state *state)
 797{
 798	struct ast_cursor_plane *ast_cursor_plane = to_ast_cursor_plane(plane);
 799	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
 800									   plane);
 801	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
 802									   plane);
 803	struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(new_state);
 804	struct drm_framebuffer *fb = new_state->fb;
 805	struct ast_private *ast = to_ast_private(plane->dev);
 806	struct dma_buf_map dst_map =
 807		ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].map;
 808	u64 dst_off =
 809		ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].off;
 810	struct dma_buf_map src_map = shadow_plane_state->map[0];
 811	unsigned int offset_x, offset_y;
 812	u16 x, y;
 813	u8 x_offset, y_offset;
 814	u8 __iomem *dst;
 815	u8 __iomem *sig;
 816	const u8 *src;
 817
 818	src = src_map.vaddr; /* TODO: Use mapping abstraction properly */
 819	dst = dst_map.vaddr_iomem; /* TODO: Use mapping abstraction properly */
 820	sig = dst + AST_HWC_SIZE; /* TODO: Use mapping abstraction properly */
 821
 822	/*
 823	 * Do data transfer to HW cursor BO. If a new cursor image was installed,
 824	 * point the scanout engine to dst_gbo's offset and page-flip the HWC buffers.
 825	 */
 826
 827	ast_update_cursor_image(dst, src, fb->width, fb->height);
 828
 829	if (new_state->fb != old_state->fb) {
 830		ast_set_cursor_base(ast, dst_off);
 831
 832		++ast_cursor_plane->next_hwc_index;
 833		ast_cursor_plane->next_hwc_index %= ARRAY_SIZE(ast_cursor_plane->hwc);
 834	}
 835
 836	/*
 837	 * Update location in HWC signature and registers.
 838	 */
 839
 840	writel(new_state->crtc_x, sig + AST_HWC_SIGNATURE_X);
 841	writel(new_state->crtc_y, sig + AST_HWC_SIGNATURE_Y);
 842
 843	offset_x = AST_MAX_HWC_WIDTH - fb->width;
 844	offset_y = AST_MAX_HWC_HEIGHT - fb->height;
 845
 846	if (new_state->crtc_x < 0) {
 847		x_offset = (-new_state->crtc_x) + offset_x;
 848		x = 0;
 849	} else {
 850		x_offset = offset_x;
 851		x = new_state->crtc_x;
 852	}
 853	if (new_state->crtc_y < 0) {
 854		y_offset = (-new_state->crtc_y) + offset_y;
 855		y = 0;
 856	} else {
 857		y_offset = offset_y;
 858		y = new_state->crtc_y;
 859	}
 860
 861	ast_set_cursor_location(ast, x, y, x_offset, y_offset);
 862
 863	/* Dummy write to enable HWC and make the HW pick-up the changes. */
 864	ast_set_cursor_enabled(ast, true);
 865}
 866
 867static void
 868ast_cursor_plane_helper_atomic_disable(struct drm_plane *plane,
 869				       struct drm_atomic_state *state)
 870{
 871	struct ast_private *ast = to_ast_private(plane->dev);
 872
 873	ast_set_cursor_enabled(ast, false);
 874}
 875
 876static const struct drm_plane_helper_funcs ast_cursor_plane_helper_funcs = {
 877	DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
 
 878	.atomic_check = ast_cursor_plane_helper_atomic_check,
 879	.atomic_update = ast_cursor_plane_helper_atomic_update,
 880	.atomic_disable = ast_cursor_plane_helper_atomic_disable,
 881};
 882
 883static void ast_cursor_plane_destroy(struct drm_plane *plane)
 884{
 885	struct ast_cursor_plane *ast_cursor_plane = to_ast_cursor_plane(plane);
 886	size_t i;
 887	struct drm_gem_vram_object *gbo;
 888	struct dma_buf_map map;
 889
 890	for (i = 0; i < ARRAY_SIZE(ast_cursor_plane->hwc); ++i) {
 891		gbo = ast_cursor_plane->hwc[i].gbo;
 892		map = ast_cursor_plane->hwc[i].map;
 893		drm_gem_vram_vunmap(gbo, &map);
 894		drm_gem_vram_unpin(gbo);
 895		drm_gem_vram_put(gbo);
 896	}
 897
 898	drm_plane_cleanup(plane);
 899}
 900
 901static const struct drm_plane_funcs ast_cursor_plane_funcs = {
 902	.update_plane = drm_atomic_helper_update_plane,
 903	.disable_plane = drm_atomic_helper_disable_plane,
 904	.destroy = ast_cursor_plane_destroy,
 905	DRM_GEM_SHADOW_PLANE_FUNCS,
 
 
 906};
 907
 908static int ast_cursor_plane_init(struct ast_private *ast)
 909{
 910	struct drm_device *dev = &ast->base;
 911	struct ast_cursor_plane *ast_cursor_plane = &ast->cursor_plane;
 912	struct drm_plane *cursor_plane = &ast_cursor_plane->base;
 913	size_t size, i;
 914	struct drm_gem_vram_object *gbo;
 915	struct dma_buf_map map;
 916	int ret;
 917	s64 off;
 918
 919	/*
 920	 * Allocate backing storage for cursors. The BOs are permanently
 921	 * pinned to the top end of the VRAM.
 922	 */
 923
 924	size = roundup(AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE, PAGE_SIZE);
 925
 926	for (i = 0; i < ARRAY_SIZE(ast_cursor_plane->hwc); ++i) {
 927		gbo = drm_gem_vram_create(dev, size, 0);
 928		if (IS_ERR(gbo)) {
 929			ret = PTR_ERR(gbo);
 930			goto err_hwc;
 931		}
 932		ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM |
 933					    DRM_GEM_VRAM_PL_FLAG_TOPDOWN);
 934		if (ret)
 935			goto err_drm_gem_vram_put;
 936		ret = drm_gem_vram_vmap(gbo, &map);
 937		if (ret)
 938			goto err_drm_gem_vram_unpin;
 939		off = drm_gem_vram_offset(gbo);
 940		if (off < 0) {
 941			ret = off;
 942			goto err_drm_gem_vram_vunmap;
 943		}
 944		ast_cursor_plane->hwc[i].gbo = gbo;
 945		ast_cursor_plane->hwc[i].map = map;
 946		ast_cursor_plane->hwc[i].off = off;
 947	}
 948
 949	/*
 950	 * Create the cursor plane. The plane's destroy callback will release
 951	 * the backing storages' BO memory.
 952	 */
 953
 954	ret = drm_universal_plane_init(dev, cursor_plane, 0x01,
 955				       &ast_cursor_plane_funcs,
 956				       ast_cursor_plane_formats,
 957				       ARRAY_SIZE(ast_cursor_plane_formats),
 958				       NULL, DRM_PLANE_TYPE_CURSOR, NULL);
 959	if (ret) {
 960		drm_err(dev, "drm_universal_plane failed(): %d\n", ret);
 961		goto err_hwc;
 962	}
 963	drm_plane_helper_add(cursor_plane, &ast_cursor_plane_helper_funcs);
 964
 965	return 0;
 966
 967err_hwc:
 968	while (i) {
 969		--i;
 970		gbo = ast_cursor_plane->hwc[i].gbo;
 971		map = ast_cursor_plane->hwc[i].map;
 972err_drm_gem_vram_vunmap:
 973		drm_gem_vram_vunmap(gbo, &map);
 974err_drm_gem_vram_unpin:
 975		drm_gem_vram_unpin(gbo);
 976err_drm_gem_vram_put:
 977		drm_gem_vram_put(gbo);
 978	}
 979	return ret;
 980}
 981
 982/*
 983 * CRTC
 984 */
 985
 986static void ast_crtc_dpms(struct drm_crtc *crtc, int mode)
 987{
 988	struct ast_private *ast = to_ast_private(crtc->dev);
 989
 990	/* TODO: Maybe control display signal generation with
 991	 *       Sync Enable (bit CR17.7).
 992	 */
 993	switch (mode) {
 994	case DRM_MODE_DPMS_ON:
 995	case DRM_MODE_DPMS_STANDBY:
 996	case DRM_MODE_DPMS_SUSPEND:
 997		if (ast->tx_chip_type == AST_TX_DP501)
 998			ast_set_dp501_video_output(crtc->dev, 1);
 
 999		break;
1000	case DRM_MODE_DPMS_OFF:
1001		if (ast->tx_chip_type == AST_TX_DP501)
1002			ast_set_dp501_video_output(crtc->dev, 0);
1003		break;
1004	}
1005}
1006
1007static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc,
1008					struct drm_atomic_state *state)
1009{
1010	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
1011									  crtc);
1012	struct drm_device *dev = crtc->dev;
1013	struct ast_crtc_state *ast_state;
1014	const struct drm_format_info *format;
1015	bool succ;
1016
1017	if (!crtc_state->enable)
1018		return 0; /* no mode checks if CRTC is being disabled */
1019
1020	ast_state = to_ast_crtc_state(crtc_state);
1021
1022	format = ast_state->format;
1023	if (drm_WARN_ON_ONCE(dev, !format))
1024		return -EINVAL; /* BUG: We didn't set format in primary check(). */
1025
1026	succ = ast_get_vbios_mode_info(format, &crtc_state->mode,
1027				       &crtc_state->adjusted_mode,
1028				       &ast_state->vbios_mode_info);
1029	if (!succ)
1030		return -EINVAL;
1031
1032	return 0;
1033}
1034
1035static void
1036ast_crtc_helper_atomic_flush(struct drm_crtc *crtc,
1037			     struct drm_atomic_state *state)
1038{
1039	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
1040									  crtc);
1041	struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state,
1042									      crtc);
1043	struct ast_private *ast = to_ast_private(crtc->dev);
1044	struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
1045	struct ast_crtc_state *old_ast_crtc_state = to_ast_crtc_state(old_crtc_state);
1046
1047	/*
1048	 * The gamma LUT has to be reloaded after changing the primary
1049	 * plane's color format.
1050	 */
1051	if (old_ast_crtc_state->format != ast_crtc_state->format)
1052		ast_crtc_load_lut(ast, crtc);
1053}
1054
1055static void
1056ast_crtc_helper_atomic_enable(struct drm_crtc *crtc,
1057			      struct drm_atomic_state *state)
1058{
1059	struct drm_device *dev = crtc->dev;
1060	struct ast_private *ast = to_ast_private(dev);
1061	struct drm_crtc_state *crtc_state = crtc->state;
1062	struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
1063	struct ast_vbios_mode_info *vbios_mode_info =
1064		&ast_crtc_state->vbios_mode_info;
1065	struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1066
1067	ast_set_vbios_mode_reg(ast, adjusted_mode, vbios_mode_info);
1068	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06);
1069	ast_set_std_reg(ast, adjusted_mode, vbios_mode_info);
1070	ast_set_crtc_reg(ast, adjusted_mode, vbios_mode_info);
1071	ast_set_dclk_reg(ast, adjusted_mode, vbios_mode_info);
1072	ast_set_crtthd_reg(ast);
1073	ast_set_sync_reg(ast, adjusted_mode, vbios_mode_info);
 
1074
 
 
 
 
1075	ast_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
1076}
1077
1078static void
1079ast_crtc_helper_atomic_disable(struct drm_crtc *crtc,
1080			       struct drm_atomic_state *state)
1081{
1082	struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state,
1083									      crtc);
1084	struct drm_device *dev = crtc->dev;
1085	struct ast_private *ast = to_ast_private(dev);
1086
1087	ast_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
1088
1089	/*
1090	 * HW cursors require the underlying primary plane and CRTC to
1091	 * display a valid mode and image. This is not the case during
1092	 * full modeset operations. So we temporarily disable any active
1093	 * plane, including the HW cursor. Each plane's atomic_update()
1094	 * helper will re-enable it if necessary.
1095	 *
1096	 * We only do this during *full* modesets. It does not affect
1097	 * simple pageflips on the planes.
1098	 */
1099	drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false);
1100
1101	/*
1102	 * Ensure that no scanout takes place before reprogramming mode
1103	 * and format registers.
1104	 */
1105	ast_wait_for_vretrace(ast);
1106}
1107
1108static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = {
1109	.atomic_check = ast_crtc_helper_atomic_check,
 
1110	.atomic_flush = ast_crtc_helper_atomic_flush,
1111	.atomic_enable = ast_crtc_helper_atomic_enable,
1112	.atomic_disable = ast_crtc_helper_atomic_disable,
1113};
1114
1115static void ast_crtc_reset(struct drm_crtc *crtc)
1116{
1117	struct ast_crtc_state *ast_state =
1118		kzalloc(sizeof(*ast_state), GFP_KERNEL);
1119
1120	if (crtc->state)
1121		crtc->funcs->atomic_destroy_state(crtc, crtc->state);
1122
1123	__drm_atomic_helper_crtc_reset(crtc, &ast_state->base);
1124}
1125
 
 
 
 
 
 
1126static struct drm_crtc_state *
1127ast_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
1128{
1129	struct ast_crtc_state *new_ast_state, *ast_state;
1130	struct drm_device *dev = crtc->dev;
1131
1132	if (drm_WARN_ON(dev, !crtc->state))
1133		return NULL;
1134
1135	new_ast_state = kmalloc(sizeof(*new_ast_state), GFP_KERNEL);
1136	if (!new_ast_state)
1137		return NULL;
1138	__drm_atomic_helper_crtc_duplicate_state(crtc, &new_ast_state->base);
1139
1140	ast_state = to_ast_crtc_state(crtc->state);
1141
1142	new_ast_state->format = ast_state->format;
1143	memcpy(&new_ast_state->vbios_mode_info, &ast_state->vbios_mode_info,
1144	       sizeof(new_ast_state->vbios_mode_info));
1145
1146	return &new_ast_state->base;
1147}
1148
1149static void ast_crtc_atomic_destroy_state(struct drm_crtc *crtc,
1150					  struct drm_crtc_state *state)
1151{
1152	struct ast_crtc_state *ast_state = to_ast_crtc_state(state);
1153
1154	__drm_atomic_helper_crtc_destroy_state(&ast_state->base);
1155	kfree(ast_state);
1156}
1157
1158static const struct drm_crtc_funcs ast_crtc_funcs = {
1159	.reset = ast_crtc_reset,
1160	.destroy = drm_crtc_cleanup,
 
1161	.set_config = drm_atomic_helper_set_config,
1162	.page_flip = drm_atomic_helper_page_flip,
1163	.atomic_duplicate_state = ast_crtc_atomic_duplicate_state,
1164	.atomic_destroy_state = ast_crtc_atomic_destroy_state,
1165};
1166
1167static int ast_crtc_init(struct drm_device *dev)
1168{
1169	struct ast_private *ast = to_ast_private(dev);
1170	struct drm_crtc *crtc = &ast->crtc;
1171	int ret;
1172
 
 
 
 
1173	ret = drm_crtc_init_with_planes(dev, crtc, &ast->primary_plane,
1174					&ast->cursor_plane.base, &ast_crtc_funcs,
1175					NULL);
1176	if (ret)
1177		return ret;
1178
1179	drm_mode_crtc_set_gamma_size(crtc, 256);
1180	drm_crtc_helper_add(crtc, &ast_crtc_helper_funcs);
1181
1182	return 0;
 
 
 
 
1183}
1184
1185/*
1186 * Encoder
1187 */
1188
1189static int ast_encoder_init(struct drm_device *dev)
1190{
1191	struct ast_private *ast = to_ast_private(dev);
1192	struct drm_encoder *encoder = &ast->encoder;
1193	int ret;
1194
1195	ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_DAC);
1196	if (ret)
1197		return ret;
1198
1199	encoder->possible_crtcs = 1;
1200
1201	return 0;
1202}
1203
1204/*
1205 * Connector
1206 */
1207
1208static int ast_get_modes(struct drm_connector *connector)
1209{
1210	struct ast_connector *ast_connector = to_ast_connector(connector);
1211	struct ast_private *ast = to_ast_private(connector->dev);
1212	struct edid *edid;
1213	int ret;
1214	bool flags = false;
1215	if (ast->tx_chip_type == AST_TX_DP501) {
1216		ast->dp501_maxclk = 0xff;
1217		edid = kmalloc(128, GFP_KERNEL);
1218		if (!edid)
1219			return -ENOMEM;
1220
1221		flags = ast_dp501_read_edid(connector->dev, (u8 *)edid);
1222		if (flags)
1223			ast->dp501_maxclk = ast_get_dp501_max_clk(connector->dev);
1224		else
1225			kfree(edid);
1226	}
1227	if (!flags)
1228		edid = drm_get_edid(connector, &ast_connector->i2c->adapter);
1229	if (edid) {
1230		drm_connector_update_edid_property(&ast_connector->base, edid);
1231		ret = drm_add_edid_modes(connector, edid);
1232		kfree(edid);
1233		return ret;
1234	} else
1235		drm_connector_update_edid_property(&ast_connector->base, NULL);
1236	return 0;
1237}
1238
1239static enum drm_mode_status ast_mode_valid(struct drm_connector *connector,
1240			  struct drm_display_mode *mode)
1241{
1242	struct ast_private *ast = to_ast_private(connector->dev);
1243	int flags = MODE_NOMODE;
1244	uint32_t jtemp;
1245
1246	if (ast->support_wide_screen) {
1247		if ((mode->hdisplay == 1680) && (mode->vdisplay == 1050))
1248			return MODE_OK;
1249		if ((mode->hdisplay == 1280) && (mode->vdisplay == 800))
1250			return MODE_OK;
1251		if ((mode->hdisplay == 1440) && (mode->vdisplay == 900))
1252			return MODE_OK;
1253		if ((mode->hdisplay == 1360) && (mode->vdisplay == 768))
1254			return MODE_OK;
1255		if ((mode->hdisplay == 1600) && (mode->vdisplay == 900))
1256			return MODE_OK;
1257
1258		if ((ast->chip == AST2100) || (ast->chip == AST2200) ||
1259		    (ast->chip == AST2300) || (ast->chip == AST2400) ||
1260		    (ast->chip == AST2500)) {
1261			if ((mode->hdisplay == 1920) && (mode->vdisplay == 1080))
1262				return MODE_OK;
1263
1264			if ((mode->hdisplay == 1920) && (mode->vdisplay == 1200)) {
1265				jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
1266				if (jtemp & 0x01)
1267					return MODE_NOMODE;
1268				else
1269					return MODE_OK;
1270			}
1271		}
1272	}
1273	switch (mode->hdisplay) {
1274	case 640:
1275		if (mode->vdisplay == 480) flags = MODE_OK;
1276		break;
1277	case 800:
1278		if (mode->vdisplay == 600) flags = MODE_OK;
1279		break;
1280	case 1024:
1281		if (mode->vdisplay == 768) flags = MODE_OK;
1282		break;
1283	case 1280:
1284		if (mode->vdisplay == 1024) flags = MODE_OK;
1285		break;
1286	case 1600:
1287		if (mode->vdisplay == 1200) flags = MODE_OK;
1288		break;
1289	default:
1290		return flags;
1291	}
1292
1293	return flags;
1294}
1295
1296static void ast_connector_destroy(struct drm_connector *connector)
1297{
1298	struct ast_connector *ast_connector = to_ast_connector(connector);
1299	ast_i2c_destroy(ast_connector->i2c);
1300	drm_connector_cleanup(connector);
 
1301}
1302
1303static const struct drm_connector_helper_funcs ast_connector_helper_funcs = {
1304	.get_modes = ast_get_modes,
1305	.mode_valid = ast_mode_valid,
1306};
1307
1308static const struct drm_connector_funcs ast_connector_funcs = {
1309	.reset = drm_atomic_helper_connector_reset,
1310	.fill_modes = drm_helper_probe_single_connector_modes,
1311	.destroy = ast_connector_destroy,
1312	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
1313	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1314};
1315
1316static int ast_connector_init(struct drm_device *dev)
1317{
1318	struct ast_private *ast = to_ast_private(dev);
1319	struct ast_connector *ast_connector = &ast->connector;
1320	struct drm_connector *connector = &ast_connector->base;
1321	struct drm_encoder *encoder = &ast->encoder;
 
 
 
1322
 
1323	ast_connector->i2c = ast_i2c_create(dev);
1324	if (!ast_connector->i2c)
1325		drm_err(dev, "failed to add ddc bus for connector\n");
1326
1327	drm_connector_init_with_ddc(dev, connector,
1328				    &ast_connector_funcs,
1329				    DRM_MODE_CONNECTOR_VGA,
1330				    &ast_connector->i2c->adapter);
1331
1332	drm_connector_helper_add(connector, &ast_connector_helper_funcs);
1333
1334	connector->interlace_allowed = 0;
1335	connector->doublescan_allowed = 0;
1336
1337	connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1338
 
1339	drm_connector_attach_encoder(connector, encoder);
1340
1341	return 0;
1342}
1343
1344/*
1345 * Mode config
1346 */
1347
1348static const struct drm_mode_config_helper_funcs
1349ast_mode_config_helper_funcs = {
1350	.atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
1351};
1352
1353static const struct drm_mode_config_funcs ast_mode_config_funcs = {
1354	.fb_create = drm_gem_fb_create,
1355	.mode_valid = drm_vram_helper_mode_valid,
1356	.atomic_check = drm_atomic_helper_check,
1357	.atomic_commit = drm_atomic_helper_commit,
1358};
1359
1360int ast_mode_config_init(struct ast_private *ast)
1361{
1362	struct drm_device *dev = &ast->base;
1363	struct pci_dev *pdev = to_pci_dev(dev->dev);
1364	int ret;
1365
 
 
 
 
1366	ret = drmm_mode_config_init(dev);
1367	if (ret)
1368		return ret;
1369
1370	dev->mode_config.funcs = &ast_mode_config_funcs;
1371	dev->mode_config.min_width = 0;
1372	dev->mode_config.min_height = 0;
1373	dev->mode_config.preferred_depth = 24;
1374	dev->mode_config.prefer_shadow = 1;
1375	dev->mode_config.fb_base = pci_resource_start(pdev, 0);
1376
1377	if (ast->chip == AST2100 ||
1378	    ast->chip == AST2200 ||
1379	    ast->chip == AST2300 ||
1380	    ast->chip == AST2400 ||
1381	    ast->chip == AST2500) {
1382		dev->mode_config.max_width = 1920;
1383		dev->mode_config.max_height = 2048;
1384	} else {
1385		dev->mode_config.max_width = 1600;
1386		dev->mode_config.max_height = 1200;
1387	}
1388
1389	dev->mode_config.helper_private = &ast_mode_config_helper_funcs;
1390
1391
1392	ret = ast_primary_plane_init(ast);
1393	if (ret)
 
 
 
1394		return ret;
 
 
 
1395
1396	ret = ast_cursor_plane_init(ast);
1397	if (ret)
 
 
 
 
 
1398		return ret;
 
 
 
1399
1400	ast_crtc_init(dev);
1401	ast_encoder_init(dev);
1402	ast_connector_init(dev);
1403
1404	drm_mode_config_reset(dev);
1405
1406	return 0;
1407}
1408
1409static int get_clock(void *i2c_priv)
1410{
1411	struct ast_i2c_chan *i2c = i2c_priv;
1412	struct ast_private *ast = to_ast_private(i2c->dev);
1413	uint32_t val, val2, count, pass;
1414
1415	count = 0;
1416	pass = 0;
1417	val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
1418	do {
1419		val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
1420		if (val == val2) {
1421			pass++;
1422		} else {
1423			pass = 0;
1424			val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
1425		}
1426	} while ((pass < 5) && (count++ < 0x10000));
1427
1428	return val & 1 ? 1 : 0;
1429}
1430
1431static int get_data(void *i2c_priv)
1432{
1433	struct ast_i2c_chan *i2c = i2c_priv;
1434	struct ast_private *ast = to_ast_private(i2c->dev);
1435	uint32_t val, val2, count, pass;
1436
1437	count = 0;
1438	pass = 0;
1439	val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
1440	do {
1441		val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
1442		if (val == val2) {
1443			pass++;
1444		} else {
1445			pass = 0;
1446			val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
1447		}
1448	} while ((pass < 5) && (count++ < 0x10000));
1449
1450	return val & 1 ? 1 : 0;
1451}
1452
1453static void set_clock(void *i2c_priv, int clock)
1454{
1455	struct ast_i2c_chan *i2c = i2c_priv;
1456	struct ast_private *ast = to_ast_private(i2c->dev);
1457	int i;
1458	u8 ujcrb7, jtemp;
1459
1460	for (i = 0; i < 0x10000; i++) {
1461		ujcrb7 = ((clock & 0x01) ? 0 : 1);
1462		ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf4, ujcrb7);
1463		jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x01);
1464		if (ujcrb7 == jtemp)
1465			break;
1466	}
1467}
1468
1469static void set_data(void *i2c_priv, int data)
1470{
1471	struct ast_i2c_chan *i2c = i2c_priv;
1472	struct ast_private *ast = to_ast_private(i2c->dev);
1473	int i;
1474	u8 ujcrb7, jtemp;
1475
1476	for (i = 0; i < 0x10000; i++) {
1477		ujcrb7 = ((data & 0x01) ? 0 : 1) << 2;
1478		ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf1, ujcrb7);
1479		jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x04);
1480		if (ujcrb7 == jtemp)
1481			break;
1482	}
1483}
1484
1485static struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev)
1486{
1487	struct ast_i2c_chan *i2c;
1488	int ret;
1489
1490	i2c = kzalloc(sizeof(struct ast_i2c_chan), GFP_KERNEL);
1491	if (!i2c)
1492		return NULL;
1493
1494	i2c->adapter.owner = THIS_MODULE;
1495	i2c->adapter.class = I2C_CLASS_DDC;
1496	i2c->adapter.dev.parent = dev->dev;
1497	i2c->dev = dev;
1498	i2c_set_adapdata(&i2c->adapter, i2c);
1499	snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
1500		 "AST i2c bit bus");
1501	i2c->adapter.algo_data = &i2c->bit;
1502
1503	i2c->bit.udelay = 20;
1504	i2c->bit.timeout = 2;
1505	i2c->bit.data = i2c;
1506	i2c->bit.setsda = set_data;
1507	i2c->bit.setscl = set_clock;
1508	i2c->bit.getsda = get_data;
1509	i2c->bit.getscl = get_clock;
1510	ret = i2c_bit_add_bus(&i2c->adapter);
1511	if (ret) {
1512		drm_err(dev, "Failed to register bit i2c\n");
1513		goto out_free;
1514	}
1515
1516	return i2c;
1517out_free:
1518	kfree(i2c);
1519	return NULL;
1520}
1521
1522static void ast_i2c_destroy(struct ast_i2c_chan *i2c)
1523{
1524	if (!i2c)
1525		return;
1526	i2c_del_adapter(&i2c->adapter);
1527	kfree(i2c);
1528}