/*
 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
 * Copyright 2010 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation;
 * either version 2, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE.See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc.,
 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
/*
 * basic modesetting functions
 */

#include <linux/kernel.h>
#include <linux/via-core.h>
#include "via_modesetting.h"
#include "share.h"
#include "debug.h"


void via_set_primary_timing(const struct display_timing *timing)
{
	struct display_timing raw;

	raw.hor_total = timing->hor_total / 8 - 5;
	raw.hor_addr = timing->hor_addr / 8 - 1;
	raw.hor_blank_start = timing->hor_blank_start / 8 - 1;
	raw.hor_blank_end = timing->hor_blank_end / 8 - 1;
	raw.hor_sync_start = timing->hor_sync_start / 8;
	raw.hor_sync_end = timing->hor_sync_end / 8;
	raw.ver_total = timing->ver_total - 2;
	raw.ver_addr = timing->ver_addr - 1;
	raw.ver_blank_start = timing->ver_blank_start - 1;
	raw.ver_blank_end = timing->ver_blank_end - 1;
	raw.ver_sync_start = timing->ver_sync_start - 1;
	raw.ver_sync_end = timing->ver_sync_end - 1;

	/* unlock timing registers */
	via_write_reg_mask(VIACR, 0x11, 0x00, 0x80);

	via_write_reg(VIACR, 0x00, raw.hor_total & 0xFF);
	via_write_reg(VIACR, 0x01, raw.hor_addr & 0xFF);
	via_write_reg(VIACR, 0x02, raw.hor_blank_start & 0xFF);
	via_write_reg_mask(VIACR, 0x03, raw.hor_blank_end & 0x1F, 0x1F);
	via_write_reg(VIACR, 0x04, raw.hor_sync_start & 0xFF);
	via_write_reg_mask(VIACR, 0x05, (raw.hor_sync_end & 0x1F)
		| (raw.hor_blank_end << (7 - 5) & 0x80), 0x9F);
	via_write_reg(VIACR, 0x06, raw.ver_total & 0xFF);
	via_write_reg_mask(VIACR, 0x07, (raw.ver_total >> 8 & 0x01)
		| (raw.ver_addr >> (8 - 1) & 0x02)
		| (raw.ver_sync_start >> (8 - 2) & 0x04)
		| (raw.ver_blank_start >> (8 - 3) & 0x08)
		| (raw.ver_total >> (9 - 5) & 0x20)
		| (raw.ver_addr >> (9 - 6) & 0x40)
		| (raw.ver_sync_start >> (9 - 7) & 0x80), 0xEF);
	via_write_reg_mask(VIACR, 0x09, raw.ver_blank_start >> (9 - 5) & 0x20,
		0x20);
	via_write_reg(VIACR, 0x10, raw.ver_sync_start & 0xFF);
	via_write_reg_mask(VIACR, 0x11, raw.ver_sync_end & 0x0F, 0x0F);
	via_write_reg(VIACR, 0x12, raw.ver_addr & 0xFF);
	via_write_reg(VIACR, 0x15, raw.ver_blank_start & 0xFF);
	via_write_reg(VIACR, 0x16, raw.ver_blank_end & 0xFF);
	via_write_reg_mask(VIACR, 0x33, (raw.hor_sync_start >> (8 - 4) & 0x10)
		| (raw.hor_blank_end >> (6 - 5) & 0x20), 0x30);
	via_write_reg_mask(VIACR, 0x35, (raw.ver_total >> 10 & 0x01)
		| (raw.ver_sync_start >> (10 - 1) & 0x02)
		| (raw.ver_addr >> (10 - 2) & 0x04)
		| (raw.ver_blank_start >> (10 - 3) & 0x08), 0x0F);
	via_write_reg_mask(VIACR, 0x36, raw.hor_total >> (8 - 3) & 0x08, 0x08);

	/* lock timing registers */
	via_write_reg_mask(VIACR, 0x11, 0x80, 0x80);

	/* reset timing control */
	via_write_reg_mask(VIACR, 0x17, 0x00, 0x80);
	via_write_reg_mask(VIACR, 0x17, 0x80, 0x80);
}

void via_set_secondary_timing(const struct display_timing *timing)
{
	struct display_timing raw;

	raw.hor_total = timing->hor_total - 1;
	raw.hor_addr = timing->hor_addr - 1;
	raw.hor_blank_start = timing->hor_blank_start - 1;
	raw.hor_blank_end = timing->hor_blank_end - 1;
	raw.hor_sync_start = timing->hor_sync_start - 1;
	raw.hor_sync_end = timing->hor_sync_end - 1;
	raw.ver_total = timing->ver_total - 1;
	raw.ver_addr = timing->ver_addr - 1;
	raw.ver_blank_start = timing->ver_blank_start - 1;
	raw.ver_blank_end = timing->ver_blank_end - 1;
	raw.ver_sync_start = timing->ver_sync_start - 1;
	raw.ver_sync_end = timing->ver_sync_end - 1;

	via_write_reg(VIACR, 0x50, raw.hor_total & 0xFF);
	via_write_reg(VIACR, 0x51, raw.hor_addr & 0xFF);
	via_write_reg(VIACR, 0x52, raw.hor_blank_start & 0xFF);
	via_write_reg(VIACR, 0x53, raw.hor_blank_end & 0xFF);
	via_write_reg(VIACR, 0x54, (raw.hor_blank_start >> 8 & 0x07)
		| (raw.hor_blank_end >> (8 - 3) & 0x38)
		| (raw.hor_sync_start >> (8 - 6) & 0xC0));
	via_write_reg_mask(VIACR, 0x55, (raw.hor_total >> 8 & 0x0F)
		| (raw.hor_addr >> (8 - 4) & 0x70), 0x7F);
	via_write_reg(VIACR, 0x56, raw.hor_sync_start & 0xFF);
	via_write_reg(VIACR, 0x57, raw.hor_sync_end & 0xFF);
	via_write_reg(VIACR, 0x58, raw.ver_total & 0xFF);
	via_write_reg(VIACR, 0x59, raw.ver_addr & 0xFF);
	via_write_reg(VIACR, 0x5A, raw.ver_blank_start & 0xFF);
	via_write_reg(VIACR, 0x5B, raw.ver_blank_end & 0xFF);
	via_write_reg(VIACR, 0x5C, (raw.ver_blank_start >> 8 & 0x07)
		| (raw.ver_blank_end >> (8 - 3) & 0x38)
		| (raw.hor_sync_end >> (8 - 6) & 0x40)
		| (raw.hor_sync_start >> (10 - 7) & 0x80));
	via_write_reg(VIACR, 0x5D, (raw.ver_total >> 8 & 0x07)
		| (raw.ver_addr >> (8 - 3) & 0x38)
		| (raw.hor_blank_end >> (11 - 6) & 0x40)
		| (raw.hor_sync_start >> (11 - 7) & 0x80));
	via_write_reg(VIACR, 0x5E, raw.ver_sync_start & 0xFF);
	via_write_reg(VIACR, 0x5F, (raw.ver_sync_end & 0x1F)
		| (raw.ver_sync_start >> (8 - 5) & 0xE0));
}

void via_set_primary_address(u32 addr)
{
	DEBUG_MSG(KERN_DEBUG "via_set_primary_address(0x%08X)\n", addr);
	via_write_reg(VIACR, 0x0D, addr & 0xFF);
	via_write_reg(VIACR, 0x0C, (addr >> 8) & 0xFF);
	via_write_reg(VIACR, 0x34, (addr >> 16) & 0xFF);
	via_write_reg_mask(VIACR, 0x48, (addr >> 24) & 0x1F, 0x1F);
}

void via_set_secondary_address(u32 addr)
{
	DEBUG_MSG(KERN_DEBUG "via_set_secondary_address(0x%08X)\n", addr);
	/* secondary display supports only quadword aligned memory */
	via_write_reg_mask(VIACR, 0x62, (addr >> 2) & 0xFE, 0xFE);
	via_write_reg(VIACR, 0x63, (addr >> 10) & 0xFF);
	via_write_reg(VIACR, 0x64, (addr >> 18) & 0xFF);
	via_write_reg_mask(VIACR, 0xA3, (addr >> 26) & 0x07, 0x07);
}

void via_set_primary_pitch(u32 pitch)
{
	DEBUG_MSG(KERN_DEBUG "via_set_primary_pitch(0x%08X)\n", pitch);
	/* spec does not say that first adapter skips 3 bits but old
	 * code did it and seems to be reasonable in analogy to 2nd adapter
	 */
	pitch = pitch >> 3;
	via_write_reg(VIACR, 0x13, pitch & 0xFF);
	via_write_reg_mask(VIACR, 0x35, (pitch >> (8 - 5)) & 0xE0, 0xE0);
}

void via_set_secondary_pitch(u32 pitch)
{
	DEBUG_MSG(KERN_DEBUG "via_set_secondary_pitch(0x%08X)\n", pitch);
	pitch = pitch >> 3;
	via_write_reg(VIACR, 0x66, pitch & 0xFF);
	via_write_reg_mask(VIACR, 0x67, (pitch >> 8) & 0x03, 0x03);
	via_write_reg_mask(VIACR, 0x71, (pitch >> (10 - 7)) & 0x80, 0x80);
}

void via_set_primary_color_depth(u8 depth)
{
	u8 value;

	DEBUG_MSG(KERN_DEBUG "via_set_primary_color_depth(%d)\n", depth);
	switch (depth) {
	case 8:
		value = 0x00;
		break;
	case 15:
		value = 0x04;
		break;
	case 16:
		value = 0x14;
		break;
	case 24:
		value = 0x0C;
		break;
	case 30:
		value = 0x08;
		break;
	default:
		printk(KERN_WARNING "via_set_primary_color_depth: "
			"Unsupported depth: %d\n", depth);
		return;
	}

	via_write_reg_mask(VIASR, 0x15, value, 0x1C);
}

void via_set_secondary_color_depth(u8 depth)
{
	u8 value;

	DEBUG_MSG(KERN_DEBUG "via_set_secondary_color_depth(%d)\n", depth);
	switch (depth) {
	case 8:
		value = 0x00;
		break;
	case 16:
		value = 0x40;
		break;
	case 24:
		value = 0xC0;
		break;
	case 30:
		value = 0x80;
		break;
	default:
		printk(KERN_WARNING "via_set_secondary_color_depth: "
			"Unsupported depth: %d\n", depth);
		return;
	}

	via_write_reg_mask(VIACR, 0x67, value, 0xC0);
}
