brintos

brintos / linux-shallow public Read only

0
0
Text · 7.0 KiB · 47dccc8 Raw
216 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.4 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.5 * Copyright 2010 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>6 */7/*8 * basic modesetting functions9 */10 11#include <linux/kernel.h>12#include <linux/via-core.h>13#include "via_modesetting.h"14#include "share.h"15#include "debug.h"16 17 18void via_set_primary_timing(const struct via_display_timing *timing)19{20	struct via_display_timing raw;21 22	raw.hor_total = timing->hor_total / 8 - 5;23	raw.hor_addr = timing->hor_addr / 8 - 1;24	raw.hor_blank_start = timing->hor_blank_start / 8 - 1;25	raw.hor_blank_end = timing->hor_blank_end / 8 - 1;26	raw.hor_sync_start = timing->hor_sync_start / 8;27	raw.hor_sync_end = timing->hor_sync_end / 8;28	raw.ver_total = timing->ver_total - 2;29	raw.ver_addr = timing->ver_addr - 1;30	raw.ver_blank_start = timing->ver_blank_start - 1;31	raw.ver_blank_end = timing->ver_blank_end - 1;32	raw.ver_sync_start = timing->ver_sync_start - 1;33	raw.ver_sync_end = timing->ver_sync_end - 1;34 35	/* unlock timing registers */36	via_write_reg_mask(VIACR, 0x11, 0x00, 0x80);37 38	via_write_reg(VIACR, 0x00, raw.hor_total & 0xFF);39	via_write_reg(VIACR, 0x01, raw.hor_addr & 0xFF);40	via_write_reg(VIACR, 0x02, raw.hor_blank_start & 0xFF);41	via_write_reg_mask(VIACR, 0x03, raw.hor_blank_end & 0x1F, 0x1F);42	via_write_reg(VIACR, 0x04, raw.hor_sync_start & 0xFF);43	via_write_reg_mask(VIACR, 0x05, (raw.hor_sync_end & 0x1F)44		| (raw.hor_blank_end << (7 - 5) & 0x80), 0x9F);45	via_write_reg(VIACR, 0x06, raw.ver_total & 0xFF);46	via_write_reg_mask(VIACR, 0x07, (raw.ver_total >> 8 & 0x01)47		| (raw.ver_addr >> (8 - 1) & 0x02)48		| (raw.ver_sync_start >> (8 - 2) & 0x04)49		| (raw.ver_blank_start >> (8 - 3) & 0x08)50		| (raw.ver_total >> (9 - 5) & 0x20)51		| (raw.ver_addr >> (9 - 6) & 0x40)52		| (raw.ver_sync_start >> (9 - 7) & 0x80), 0xEF);53	via_write_reg_mask(VIACR, 0x09, raw.ver_blank_start >> (9 - 5) & 0x20,54		0x20);55	via_write_reg(VIACR, 0x10, raw.ver_sync_start & 0xFF);56	via_write_reg_mask(VIACR, 0x11, raw.ver_sync_end & 0x0F, 0x0F);57	via_write_reg(VIACR, 0x12, raw.ver_addr & 0xFF);58	via_write_reg(VIACR, 0x15, raw.ver_blank_start & 0xFF);59	via_write_reg(VIACR, 0x16, raw.ver_blank_end & 0xFF);60	via_write_reg_mask(VIACR, 0x33, (raw.hor_sync_start >> (8 - 4) & 0x10)61		| (raw.hor_blank_end >> (6 - 5) & 0x20), 0x30);62	via_write_reg_mask(VIACR, 0x35, (raw.ver_total >> 10 & 0x01)63		| (raw.ver_sync_start >> (10 - 1) & 0x02)64		| (raw.ver_addr >> (10 - 2) & 0x04)65		| (raw.ver_blank_start >> (10 - 3) & 0x08), 0x0F);66	via_write_reg_mask(VIACR, 0x36, raw.hor_total >> (8 - 3) & 0x08, 0x08);67 68	/* lock timing registers */69	via_write_reg_mask(VIACR, 0x11, 0x80, 0x80);70 71	/* reset timing control */72	via_write_reg_mask(VIACR, 0x17, 0x00, 0x80);73	via_write_reg_mask(VIACR, 0x17, 0x80, 0x80);74}75 76void via_set_secondary_timing(const struct via_display_timing *timing)77{78	struct via_display_timing raw;79 80	raw.hor_total = timing->hor_total - 1;81	raw.hor_addr = timing->hor_addr - 1;82	raw.hor_blank_start = timing->hor_blank_start - 1;83	raw.hor_blank_end = timing->hor_blank_end - 1;84	raw.hor_sync_start = timing->hor_sync_start - 1;85	raw.hor_sync_end = timing->hor_sync_end - 1;86	raw.ver_total = timing->ver_total - 1;87	raw.ver_addr = timing->ver_addr - 1;88	raw.ver_blank_start = timing->ver_blank_start - 1;89	raw.ver_blank_end = timing->ver_blank_end - 1;90	raw.ver_sync_start = timing->ver_sync_start - 1;91	raw.ver_sync_end = timing->ver_sync_end - 1;92 93	via_write_reg(VIACR, 0x50, raw.hor_total & 0xFF);94	via_write_reg(VIACR, 0x51, raw.hor_addr & 0xFF);95	via_write_reg(VIACR, 0x52, raw.hor_blank_start & 0xFF);96	via_write_reg(VIACR, 0x53, raw.hor_blank_end & 0xFF);97	via_write_reg(VIACR, 0x54, (raw.hor_blank_start >> 8 & 0x07)98		| (raw.hor_blank_end >> (8 - 3) & 0x38)99		| (raw.hor_sync_start >> (8 - 6) & 0xC0));100	via_write_reg_mask(VIACR, 0x55, (raw.hor_total >> 8 & 0x0F)101		| (raw.hor_addr >> (8 - 4) & 0x70), 0x7F);102	via_write_reg(VIACR, 0x56, raw.hor_sync_start & 0xFF);103	via_write_reg(VIACR, 0x57, raw.hor_sync_end & 0xFF);104	via_write_reg(VIACR, 0x58, raw.ver_total & 0xFF);105	via_write_reg(VIACR, 0x59, raw.ver_addr & 0xFF);106	via_write_reg(VIACR, 0x5A, raw.ver_blank_start & 0xFF);107	via_write_reg(VIACR, 0x5B, raw.ver_blank_end & 0xFF);108	via_write_reg(VIACR, 0x5C, (raw.ver_blank_start >> 8 & 0x07)109		| (raw.ver_blank_end >> (8 - 3) & 0x38)110		| (raw.hor_sync_end >> (8 - 6) & 0x40)111		| (raw.hor_sync_start >> (10 - 7) & 0x80));112	via_write_reg(VIACR, 0x5D, (raw.ver_total >> 8 & 0x07)113		| (raw.ver_addr >> (8 - 3) & 0x38)114		| (raw.hor_blank_end >> (11 - 6) & 0x40)115		| (raw.hor_sync_start >> (11 - 7) & 0x80));116	via_write_reg(VIACR, 0x5E, raw.ver_sync_start & 0xFF);117	via_write_reg(VIACR, 0x5F, (raw.ver_sync_end & 0x1F)118		| (raw.ver_sync_start >> (8 - 5) & 0xE0));119}120 121void via_set_primary_address(u32 addr)122{123	DEBUG_MSG(KERN_DEBUG "via_set_primary_address(0x%08X)\n", addr);124	via_write_reg(VIACR, 0x0D, addr & 0xFF);125	via_write_reg(VIACR, 0x0C, (addr >> 8) & 0xFF);126	via_write_reg(VIACR, 0x34, (addr >> 16) & 0xFF);127	via_write_reg_mask(VIACR, 0x48, (addr >> 24) & 0x1F, 0x1F);128}129 130void via_set_secondary_address(u32 addr)131{132	DEBUG_MSG(KERN_DEBUG "via_set_secondary_address(0x%08X)\n", addr);133	/* secondary display supports only quadword aligned memory */134	via_write_reg_mask(VIACR, 0x62, (addr >> 2) & 0xFE, 0xFE);135	via_write_reg(VIACR, 0x63, (addr >> 10) & 0xFF);136	via_write_reg(VIACR, 0x64, (addr >> 18) & 0xFF);137	via_write_reg_mask(VIACR, 0xA3, (addr >> 26) & 0x07, 0x07);138}139 140void via_set_primary_pitch(u32 pitch)141{142	DEBUG_MSG(KERN_DEBUG "via_set_primary_pitch(0x%08X)\n", pitch);143	/* spec does not say that first adapter skips 3 bits but old144	 * code did it and seems to be reasonable in analogy to 2nd adapter145	 */146	pitch = pitch >> 3;147	via_write_reg(VIACR, 0x13, pitch & 0xFF);148	via_write_reg_mask(VIACR, 0x35, (pitch >> (8 - 5)) & 0xE0, 0xE0);149}150 151void via_set_secondary_pitch(u32 pitch)152{153	DEBUG_MSG(KERN_DEBUG "via_set_secondary_pitch(0x%08X)\n", pitch);154	pitch = pitch >> 3;155	via_write_reg(VIACR, 0x66, pitch & 0xFF);156	via_write_reg_mask(VIACR, 0x67, (pitch >> 8) & 0x03, 0x03);157	via_write_reg_mask(VIACR, 0x71, (pitch >> (10 - 7)) & 0x80, 0x80);158}159 160void via_set_primary_color_depth(u8 depth)161{162	u8 value;163 164	DEBUG_MSG(KERN_DEBUG "via_set_primary_color_depth(%d)\n", depth);165	switch (depth) {166	case 8:167		value = 0x00;168		break;169	case 15:170		value = 0x04;171		break;172	case 16:173		value = 0x14;174		break;175	case 24:176		value = 0x0C;177		break;178	case 30:179		value = 0x08;180		break;181	default:182		printk(KERN_WARNING "via_set_primary_color_depth: "183			"Unsupported depth: %d\n", depth);184		return;185	}186 187	via_write_reg_mask(VIASR, 0x15, value, 0x1C);188}189 190void via_set_secondary_color_depth(u8 depth)191{192	u8 value;193 194	DEBUG_MSG(KERN_DEBUG "via_set_secondary_color_depth(%d)\n", depth);195	switch (depth) {196	case 8:197		value = 0x00;198		break;199	case 16:200		value = 0x40;201		break;202	case 24:203		value = 0xC0;204		break;205	case 30:206		value = 0x80;207		break;208	default:209		printk(KERN_WARNING "via_set_secondary_color_depth: "210			"Unsupported depth: %d\n", depth);211		return;212	}213 214	via_write_reg_mask(VIACR, 0x67, value, 0xC0);215}216