File Index
Files and directories
Sign in
FILE

via_modesetting.c

File preview with syntax highlighting.

linux-6.19.14/drivers/video/fbdev/via/via_modesetting.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  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 functions
  9 */
 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 old
144	 * code did it and seems to be reasonable in analogy to 2nd adapter
145	 */
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}
~/ Read-only file preview.