diff options
Diffstat (limited to 'drivers/video/aty/radeon_base.c')
-rw-r--r-- | drivers/video/aty/radeon_base.c | 118 |
1 files changed, 94 insertions, 24 deletions
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index e8eb124754b1..ee25b9e8db60 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c | |||
@@ -1057,13 +1057,14 @@ static int radeonfb_blank (int blank, struct fb_info *info) | |||
1057 | return radeon_screen_blank(rinfo, blank, 0); | 1057 | return radeon_screen_blank(rinfo, blank, 0); |
1058 | } | 1058 | } |
1059 | 1059 | ||
1060 | static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green, | 1060 | static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green, |
1061 | unsigned blue, unsigned transp, struct fb_info *info) | 1061 | unsigned blue, unsigned transp, |
1062 | struct radeonfb_info *rinfo) | ||
1062 | { | 1063 | { |
1063 | struct radeonfb_info *rinfo = info->par; | ||
1064 | u32 pindex; | 1064 | u32 pindex; |
1065 | unsigned int i; | 1065 | unsigned int i; |
1066 | 1066 | ||
1067 | |||
1067 | if (regno > 255) | 1068 | if (regno > 255) |
1068 | return 1; | 1069 | return 1; |
1069 | 1070 | ||
@@ -1078,20 +1079,7 @@ static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green, | |||
1078 | pindex = regno; | 1079 | pindex = regno; |
1079 | 1080 | ||
1080 | if (!rinfo->asleep) { | 1081 | if (!rinfo->asleep) { |
1081 | u32 dac_cntl2, vclk_cntl = 0; | ||
1082 | |||
1083 | radeon_fifo_wait(9); | 1082 | radeon_fifo_wait(9); |
1084 | if (rinfo->is_mobility) { | ||
1085 | vclk_cntl = INPLL(VCLK_ECP_CNTL); | ||
1086 | OUTPLL(VCLK_ECP_CNTL, vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb); | ||
1087 | } | ||
1088 | |||
1089 | /* Make sure we are on first palette */ | ||
1090 | if (rinfo->has_CRTC2) { | ||
1091 | dac_cntl2 = INREG(DAC_CNTL2); | ||
1092 | dac_cntl2 &= ~DAC2_PALETTE_ACCESS_CNTL; | ||
1093 | OUTREG(DAC_CNTL2, dac_cntl2); | ||
1094 | } | ||
1095 | 1083 | ||
1096 | if (rinfo->bpp == 16) { | 1084 | if (rinfo->bpp == 16) { |
1097 | pindex = regno * 8; | 1085 | pindex = regno * 8; |
@@ -1101,24 +1089,27 @@ static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green, | |||
1101 | if (rinfo->depth == 15 && regno > 31) | 1089 | if (rinfo->depth == 15 && regno > 31) |
1102 | return 1; | 1090 | return 1; |
1103 | 1091 | ||
1104 | /* For 565, the green component is mixed one order below */ | 1092 | /* For 565, the green component is mixed one order |
1093 | * below | ||
1094 | */ | ||
1105 | if (rinfo->depth == 16) { | 1095 | if (rinfo->depth == 16) { |
1106 | OUTREG(PALETTE_INDEX, pindex>>1); | 1096 | OUTREG(PALETTE_INDEX, pindex>>1); |
1107 | OUTREG(PALETTE_DATA, (rinfo->palette[regno>>1].red << 16) | | 1097 | OUTREG(PALETTE_DATA, |
1108 | (green << 8) | (rinfo->palette[regno>>1].blue)); | 1098 | (rinfo->palette[regno>>1].red << 16) | |
1099 | (green << 8) | | ||
1100 | (rinfo->palette[regno>>1].blue)); | ||
1109 | green = rinfo->palette[regno<<1].green; | 1101 | green = rinfo->palette[regno<<1].green; |
1110 | } | 1102 | } |
1111 | } | 1103 | } |
1112 | 1104 | ||
1113 | if (rinfo->depth != 16 || regno < 32) { | 1105 | if (rinfo->depth != 16 || regno < 32) { |
1114 | OUTREG(PALETTE_INDEX, pindex); | 1106 | OUTREG(PALETTE_INDEX, pindex); |
1115 | OUTREG(PALETTE_DATA, (red << 16) | (green << 8) | blue); | 1107 | OUTREG(PALETTE_DATA, (red << 16) | |
1108 | (green << 8) | blue); | ||
1116 | } | 1109 | } |
1117 | if (rinfo->is_mobility) | ||
1118 | OUTPLL(VCLK_ECP_CNTL, vclk_cntl); | ||
1119 | } | 1110 | } |
1120 | if (regno < 16) { | 1111 | if (regno < 16) { |
1121 | u32 *pal = info->pseudo_palette; | 1112 | u32 *pal = rinfo->info->pseudo_palette; |
1122 | switch (rinfo->depth) { | 1113 | switch (rinfo->depth) { |
1123 | case 15: | 1114 | case 15: |
1124 | pal[regno] = (regno << 10) | (regno << 5) | regno; | 1115 | pal[regno] = (regno << 10) | (regno << 5) | regno; |
@@ -1138,6 +1129,84 @@ static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green, | |||
1138 | return 0; | 1129 | return 0; |
1139 | } | 1130 | } |
1140 | 1131 | ||
1132 | static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green, | ||
1133 | unsigned blue, unsigned transp, | ||
1134 | struct fb_info *info) | ||
1135 | { | ||
1136 | struct radeonfb_info *rinfo = info->par; | ||
1137 | u32 dac_cntl2, vclk_cntl = 0; | ||
1138 | int rc; | ||
1139 | |||
1140 | if (!rinfo->asleep) { | ||
1141 | if (rinfo->is_mobility) { | ||
1142 | vclk_cntl = INPLL(VCLK_ECP_CNTL); | ||
1143 | OUTPLL(VCLK_ECP_CNTL, | ||
1144 | vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb); | ||
1145 | } | ||
1146 | |||
1147 | /* Make sure we are on first palette */ | ||
1148 | if (rinfo->has_CRTC2) { | ||
1149 | dac_cntl2 = INREG(DAC_CNTL2); | ||
1150 | dac_cntl2 &= ~DAC2_PALETTE_ACCESS_CNTL; | ||
1151 | OUTREG(DAC_CNTL2, dac_cntl2); | ||
1152 | } | ||
1153 | } | ||
1154 | |||
1155 | rc = radeon_setcolreg (regno, red, green, blue, transp, rinfo); | ||
1156 | |||
1157 | if (!rinfo->asleep && rinfo->is_mobility) | ||
1158 | OUTPLL(VCLK_ECP_CNTL, vclk_cntl); | ||
1159 | |||
1160 | return rc; | ||
1161 | } | ||
1162 | |||
1163 | static int radeonfb_setcmap(struct fb_cmap *cmap, struct fb_info *info) | ||
1164 | { | ||
1165 | struct radeonfb_info *rinfo = info->par; | ||
1166 | u16 *red, *green, *blue, *transp; | ||
1167 | u32 dac_cntl2, vclk_cntl = 0; | ||
1168 | int i, start, rc = 0; | ||
1169 | |||
1170 | if (!rinfo->asleep) { | ||
1171 | if (rinfo->is_mobility) { | ||
1172 | vclk_cntl = INPLL(VCLK_ECP_CNTL); | ||
1173 | OUTPLL(VCLK_ECP_CNTL, | ||
1174 | vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb); | ||
1175 | } | ||
1176 | |||
1177 | /* Make sure we are on first palette */ | ||
1178 | if (rinfo->has_CRTC2) { | ||
1179 | dac_cntl2 = INREG(DAC_CNTL2); | ||
1180 | dac_cntl2 &= ~DAC2_PALETTE_ACCESS_CNTL; | ||
1181 | OUTREG(DAC_CNTL2, dac_cntl2); | ||
1182 | } | ||
1183 | } | ||
1184 | |||
1185 | red = cmap->red; | ||
1186 | green = cmap->green; | ||
1187 | blue = cmap->blue; | ||
1188 | transp = cmap->transp; | ||
1189 | start = cmap->start; | ||
1190 | |||
1191 | for (i = 0; i < cmap->len; i++) { | ||
1192 | u_int hred, hgreen, hblue, htransp = 0xffff; | ||
1193 | |||
1194 | hred = *red++; | ||
1195 | hgreen = *green++; | ||
1196 | hblue = *blue++; | ||
1197 | if (transp) | ||
1198 | htransp = *transp++; | ||
1199 | rc = radeon_setcolreg (start++, hred, hgreen, hblue, htransp, | ||
1200 | rinfo); | ||
1201 | if (rc) | ||
1202 | break; | ||
1203 | } | ||
1204 | |||
1205 | if (!rinfo->asleep && rinfo->is_mobility) | ||
1206 | OUTPLL(VCLK_ECP_CNTL, vclk_cntl); | ||
1207 | |||
1208 | return rc; | ||
1209 | } | ||
1141 | 1210 | ||
1142 | static void radeon_save_state (struct radeonfb_info *rinfo, | 1211 | static void radeon_save_state (struct radeonfb_info *rinfo, |
1143 | struct radeon_regs *save) | 1212 | struct radeon_regs *save) |
@@ -1796,6 +1865,7 @@ static struct fb_ops radeonfb_ops = { | |||
1796 | .fb_check_var = radeonfb_check_var, | 1865 | .fb_check_var = radeonfb_check_var, |
1797 | .fb_set_par = radeonfb_set_par, | 1866 | .fb_set_par = radeonfb_set_par, |
1798 | .fb_setcolreg = radeonfb_setcolreg, | 1867 | .fb_setcolreg = radeonfb_setcolreg, |
1868 | .fb_setcmap = radeonfb_setcmap, | ||
1799 | .fb_pan_display = radeonfb_pan_display, | 1869 | .fb_pan_display = radeonfb_pan_display, |
1800 | .fb_blank = radeonfb_blank, | 1870 | .fb_blank = radeonfb_blank, |
1801 | .fb_ioctl = radeonfb_ioctl, | 1871 | .fb_ioctl = radeonfb_ioctl, |