0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/kernel.h>
0012 #include <linux/via-core.h>
0013 #include "via_modesetting.h"
0014 #include "share.h"
0015 #include "debug.h"
0016
0017
0018 void via_set_primary_timing(const struct via_display_timing *timing)
0019 {
0020 struct via_display_timing raw;
0021
0022 raw.hor_total = timing->hor_total / 8 - 5;
0023 raw.hor_addr = timing->hor_addr / 8 - 1;
0024 raw.hor_blank_start = timing->hor_blank_start / 8 - 1;
0025 raw.hor_blank_end = timing->hor_blank_end / 8 - 1;
0026 raw.hor_sync_start = timing->hor_sync_start / 8;
0027 raw.hor_sync_end = timing->hor_sync_end / 8;
0028 raw.ver_total = timing->ver_total - 2;
0029 raw.ver_addr = timing->ver_addr - 1;
0030 raw.ver_blank_start = timing->ver_blank_start - 1;
0031 raw.ver_blank_end = timing->ver_blank_end - 1;
0032 raw.ver_sync_start = timing->ver_sync_start - 1;
0033 raw.ver_sync_end = timing->ver_sync_end - 1;
0034
0035
0036 via_write_reg_mask(VIACR, 0x11, 0x00, 0x80);
0037
0038 via_write_reg(VIACR, 0x00, raw.hor_total & 0xFF);
0039 via_write_reg(VIACR, 0x01, raw.hor_addr & 0xFF);
0040 via_write_reg(VIACR, 0x02, raw.hor_blank_start & 0xFF);
0041 via_write_reg_mask(VIACR, 0x03, raw.hor_blank_end & 0x1F, 0x1F);
0042 via_write_reg(VIACR, 0x04, raw.hor_sync_start & 0xFF);
0043 via_write_reg_mask(VIACR, 0x05, (raw.hor_sync_end & 0x1F)
0044 | (raw.hor_blank_end << (7 - 5) & 0x80), 0x9F);
0045 via_write_reg(VIACR, 0x06, raw.ver_total & 0xFF);
0046 via_write_reg_mask(VIACR, 0x07, (raw.ver_total >> 8 & 0x01)
0047 | (raw.ver_addr >> (8 - 1) & 0x02)
0048 | (raw.ver_sync_start >> (8 - 2) & 0x04)
0049 | (raw.ver_blank_start >> (8 - 3) & 0x08)
0050 | (raw.ver_total >> (9 - 5) & 0x20)
0051 | (raw.ver_addr >> (9 - 6) & 0x40)
0052 | (raw.ver_sync_start >> (9 - 7) & 0x80), 0xEF);
0053 via_write_reg_mask(VIACR, 0x09, raw.ver_blank_start >> (9 - 5) & 0x20,
0054 0x20);
0055 via_write_reg(VIACR, 0x10, raw.ver_sync_start & 0xFF);
0056 via_write_reg_mask(VIACR, 0x11, raw.ver_sync_end & 0x0F, 0x0F);
0057 via_write_reg(VIACR, 0x12, raw.ver_addr & 0xFF);
0058 via_write_reg(VIACR, 0x15, raw.ver_blank_start & 0xFF);
0059 via_write_reg(VIACR, 0x16, raw.ver_blank_end & 0xFF);
0060 via_write_reg_mask(VIACR, 0x33, (raw.hor_sync_start >> (8 - 4) & 0x10)
0061 | (raw.hor_blank_end >> (6 - 5) & 0x20), 0x30);
0062 via_write_reg_mask(VIACR, 0x35, (raw.ver_total >> 10 & 0x01)
0063 | (raw.ver_sync_start >> (10 - 1) & 0x02)
0064 | (raw.ver_addr >> (10 - 2) & 0x04)
0065 | (raw.ver_blank_start >> (10 - 3) & 0x08), 0x0F);
0066 via_write_reg_mask(VIACR, 0x36, raw.hor_total >> (8 - 3) & 0x08, 0x08);
0067
0068
0069 via_write_reg_mask(VIACR, 0x11, 0x80, 0x80);
0070
0071
0072 via_write_reg_mask(VIACR, 0x17, 0x00, 0x80);
0073 via_write_reg_mask(VIACR, 0x17, 0x80, 0x80);
0074 }
0075
0076 void via_set_secondary_timing(const struct via_display_timing *timing)
0077 {
0078 struct via_display_timing raw;
0079
0080 raw.hor_total = timing->hor_total - 1;
0081 raw.hor_addr = timing->hor_addr - 1;
0082 raw.hor_blank_start = timing->hor_blank_start - 1;
0083 raw.hor_blank_end = timing->hor_blank_end - 1;
0084 raw.hor_sync_start = timing->hor_sync_start - 1;
0085 raw.hor_sync_end = timing->hor_sync_end - 1;
0086 raw.ver_total = timing->ver_total - 1;
0087 raw.ver_addr = timing->ver_addr - 1;
0088 raw.ver_blank_start = timing->ver_blank_start - 1;
0089 raw.ver_blank_end = timing->ver_blank_end - 1;
0090 raw.ver_sync_start = timing->ver_sync_start - 1;
0091 raw.ver_sync_end = timing->ver_sync_end - 1;
0092
0093 via_write_reg(VIACR, 0x50, raw.hor_total & 0xFF);
0094 via_write_reg(VIACR, 0x51, raw.hor_addr & 0xFF);
0095 via_write_reg(VIACR, 0x52, raw.hor_blank_start & 0xFF);
0096 via_write_reg(VIACR, 0x53, raw.hor_blank_end & 0xFF);
0097 via_write_reg(VIACR, 0x54, (raw.hor_blank_start >> 8 & 0x07)
0098 | (raw.hor_blank_end >> (8 - 3) & 0x38)
0099 | (raw.hor_sync_start >> (8 - 6) & 0xC0));
0100 via_write_reg_mask(VIACR, 0x55, (raw.hor_total >> 8 & 0x0F)
0101 | (raw.hor_addr >> (8 - 4) & 0x70), 0x7F);
0102 via_write_reg(VIACR, 0x56, raw.hor_sync_start & 0xFF);
0103 via_write_reg(VIACR, 0x57, raw.hor_sync_end & 0xFF);
0104 via_write_reg(VIACR, 0x58, raw.ver_total & 0xFF);
0105 via_write_reg(VIACR, 0x59, raw.ver_addr & 0xFF);
0106 via_write_reg(VIACR, 0x5A, raw.ver_blank_start & 0xFF);
0107 via_write_reg(VIACR, 0x5B, raw.ver_blank_end & 0xFF);
0108 via_write_reg(VIACR, 0x5C, (raw.ver_blank_start >> 8 & 0x07)
0109 | (raw.ver_blank_end >> (8 - 3) & 0x38)
0110 | (raw.hor_sync_end >> (8 - 6) & 0x40)
0111 | (raw.hor_sync_start >> (10 - 7) & 0x80));
0112 via_write_reg(VIACR, 0x5D, (raw.ver_total >> 8 & 0x07)
0113 | (raw.ver_addr >> (8 - 3) & 0x38)
0114 | (raw.hor_blank_end >> (11 - 6) & 0x40)
0115 | (raw.hor_sync_start >> (11 - 7) & 0x80));
0116 via_write_reg(VIACR, 0x5E, raw.ver_sync_start & 0xFF);
0117 via_write_reg(VIACR, 0x5F, (raw.ver_sync_end & 0x1F)
0118 | (raw.ver_sync_start >> (8 - 5) & 0xE0));
0119 }
0120
0121 void via_set_primary_address(u32 addr)
0122 {
0123 DEBUG_MSG(KERN_DEBUG "via_set_primary_address(0x%08X)\n", addr);
0124 via_write_reg(VIACR, 0x0D, addr & 0xFF);
0125 via_write_reg(VIACR, 0x0C, (addr >> 8) & 0xFF);
0126 via_write_reg(VIACR, 0x34, (addr >> 16) & 0xFF);
0127 via_write_reg_mask(VIACR, 0x48, (addr >> 24) & 0x1F, 0x1F);
0128 }
0129
0130 void via_set_secondary_address(u32 addr)
0131 {
0132 DEBUG_MSG(KERN_DEBUG "via_set_secondary_address(0x%08X)\n", addr);
0133
0134 via_write_reg_mask(VIACR, 0x62, (addr >> 2) & 0xFE, 0xFE);
0135 via_write_reg(VIACR, 0x63, (addr >> 10) & 0xFF);
0136 via_write_reg(VIACR, 0x64, (addr >> 18) & 0xFF);
0137 via_write_reg_mask(VIACR, 0xA3, (addr >> 26) & 0x07, 0x07);
0138 }
0139
0140 void via_set_primary_pitch(u32 pitch)
0141 {
0142 DEBUG_MSG(KERN_DEBUG "via_set_primary_pitch(0x%08X)\n", pitch);
0143
0144
0145
0146 pitch = pitch >> 3;
0147 via_write_reg(VIACR, 0x13, pitch & 0xFF);
0148 via_write_reg_mask(VIACR, 0x35, (pitch >> (8 - 5)) & 0xE0, 0xE0);
0149 }
0150
0151 void via_set_secondary_pitch(u32 pitch)
0152 {
0153 DEBUG_MSG(KERN_DEBUG "via_set_secondary_pitch(0x%08X)\n", pitch);
0154 pitch = pitch >> 3;
0155 via_write_reg(VIACR, 0x66, pitch & 0xFF);
0156 via_write_reg_mask(VIACR, 0x67, (pitch >> 8) & 0x03, 0x03);
0157 via_write_reg_mask(VIACR, 0x71, (pitch >> (10 - 7)) & 0x80, 0x80);
0158 }
0159
0160 void via_set_primary_color_depth(u8 depth)
0161 {
0162 u8 value;
0163
0164 DEBUG_MSG(KERN_DEBUG "via_set_primary_color_depth(%d)\n", depth);
0165 switch (depth) {
0166 case 8:
0167 value = 0x00;
0168 break;
0169 case 15:
0170 value = 0x04;
0171 break;
0172 case 16:
0173 value = 0x14;
0174 break;
0175 case 24:
0176 value = 0x0C;
0177 break;
0178 case 30:
0179 value = 0x08;
0180 break;
0181 default:
0182 printk(KERN_WARNING "via_set_primary_color_depth: "
0183 "Unsupported depth: %d\n", depth);
0184 return;
0185 }
0186
0187 via_write_reg_mask(VIASR, 0x15, value, 0x1C);
0188 }
0189
0190 void via_set_secondary_color_depth(u8 depth)
0191 {
0192 u8 value;
0193
0194 DEBUG_MSG(KERN_DEBUG "via_set_secondary_color_depth(%d)\n", depth);
0195 switch (depth) {
0196 case 8:
0197 value = 0x00;
0198 break;
0199 case 16:
0200 value = 0x40;
0201 break;
0202 case 24:
0203 value = 0xC0;
0204 break;
0205 case 30:
0206 value = 0x80;
0207 break;
0208 default:
0209 printk(KERN_WARNING "via_set_secondary_color_depth: "
0210 "Unsupported depth: %d\n", depth);
0211 return;
0212 }
0213
0214 via_write_reg_mask(VIACR, 0x67, value, 0xC0);
0215 }