1 /* 2 * Copyright 2012 Red Hat Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the 6 * "Software"), to deal in the Software without restriction, including 7 * without limitation the rights to use, copy, modify, merge, publish, 8 * distribute, sub license, and/or sell copies of the Software, and to 9 * permit persons to whom the Software is furnished to do so, subject to 10 * the following conditions: 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 15 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 16 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 17 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 18 * USE OR OTHER DEALINGS IN THE SOFTWARE. 19 * 20 * The above copyright notice and this permission notice (including the 21 * next paragraph) shall be included in all copies or substantial portions 22 * of the Software. 23 * 24 */ 25 /* 26 * Authors: Dave Airlie <airlied@redhat.com> 27 */ 28 29 #include <linux/of.h> 30 #include <linux/pci.h> 31 32 #include <drm/drm_atomic_helper.h> 33 #include <drm/drm_drv.h> 34 #include <drm/drm_gem.h> 35 #include <drm/drm_managed.h> 36 37 #include "ast_drv.h" 38 39 /* Try to detect WSXGA+ on Gen2+ */ 40 static bool __ast_2100_detect_wsxga_p(struct ast_device *ast) 41 { 42 u8 vgacrd0 = ast_get_index_reg(ast, AST_IO_VGACRI, 0xd0); 43 44 if (!(vgacrd0 & AST_IO_VGACRD0_VRAM_INIT_BY_BMC)) 45 return true; 46 if (vgacrd0 & AST_IO_VGACRD0_IKVM_WIDESCREEN) 47 return true; 48 49 return false; 50 } 51 52 /* Try to detect WUXGA on Gen2+ */ 53 static bool __ast_2100_detect_wuxga(struct ast_device *ast) 54 { 55 u8 vgacrd1; 56 57 if (ast->support_fullhd) { 58 vgacrd1 = ast_get_index_reg(ast, AST_IO_VGACRI, 0xd1); 59 if (!(vgacrd1 & AST_IO_VGACRD1_SUPPORTS_WUXGA)) 60 return true; 61 } 62 63 return false; 64 } 65 66 static void ast_detect_widescreen(struct ast_device *ast) 67 { 68 ast->support_wsxga_p = false; 69 ast->support_fullhd = false; 70 ast->support_wuxga = false; 71 72 if (AST_GEN(ast) >= 7) { 73 ast->support_wsxga_p = true; 74 ast->support_fullhd = true; 75 if (__ast_2100_detect_wuxga(ast)) 76 ast->support_wuxga = true; 77 } else if (AST_GEN(ast) >= 6) { 78 if (__ast_2100_detect_wsxga_p(ast)) 79 ast->support_wsxga_p = true; 80 else if (ast->chip == AST2510) 81 ast->support_wsxga_p = true; 82 if (ast->support_wsxga_p) 83 ast->support_fullhd = true; 84 if (__ast_2100_detect_wuxga(ast)) 85 ast->support_wuxga = true; 86 } else if (AST_GEN(ast) >= 5) { 87 if (__ast_2100_detect_wsxga_p(ast)) 88 ast->support_wsxga_p = true; 89 else if (ast->chip == AST1400) 90 ast->support_wsxga_p = true; 91 if (ast->support_wsxga_p) 92 ast->support_fullhd = true; 93 if (__ast_2100_detect_wuxga(ast)) 94 ast->support_wuxga = true; 95 } else if (AST_GEN(ast) >= 4) { 96 if (__ast_2100_detect_wsxga_p(ast)) 97 ast->support_wsxga_p = true; 98 else if (ast->chip == AST1300) 99 ast->support_wsxga_p = true; 100 if (ast->support_wsxga_p) 101 ast->support_fullhd = true; 102 if (__ast_2100_detect_wuxga(ast)) 103 ast->support_wuxga = true; 104 } else if (AST_GEN(ast) >= 3) { 105 if (__ast_2100_detect_wsxga_p(ast)) 106 ast->support_wsxga_p = true; 107 if (ast->support_wsxga_p) { 108 if (ast->chip == AST2200) 109 ast->support_fullhd = true; 110 } 111 if (__ast_2100_detect_wuxga(ast)) 112 ast->support_wuxga = true; 113 } else if (AST_GEN(ast) >= 2) { 114 if (__ast_2100_detect_wsxga_p(ast)) 115 ast->support_wsxga_p = true; 116 if (ast->support_wsxga_p) { 117 if (ast->chip == AST2100) 118 ast->support_fullhd = true; 119 } 120 if (__ast_2100_detect_wuxga(ast)) 121 ast->support_wuxga = true; 122 } 123 } 124 125 static void ast_detect_tx_chip(struct ast_device *ast, bool need_post) 126 { 127 static const char * const info_str[] = { 128 "analog VGA", 129 "Sil164 TMDS transmitter", 130 "DP501 DisplayPort transmitter", 131 "ASPEED DisplayPort transmitter", 132 }; 133 134 struct drm_device *dev = &ast->base; 135 u8 vgacra3, vgacrd1; 136 137 /* Check 3rd Tx option (digital output afaik) */ 138 ast->tx_chip = AST_TX_NONE; 139 140 if (AST_GEN(ast) <= 3) { 141 /* 142 * VGACRA3 Enhanced Color Mode Register, check if DVO is already 143 * enabled, in that case, assume we have a SIL164 TMDS transmitter 144 * 145 * Don't make that assumption if we the chip wasn't enabled and 146 * is at power-on reset, otherwise we'll incorrectly "detect" a 147 * SIL164 when there is none. 148 */ 149 if (!need_post) { 150 vgacra3 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xff); 151 if (vgacra3 & AST_IO_VGACRA3_DVO_ENABLED) 152 ast->tx_chip = AST_TX_SIL164; 153 } 154 } else { 155 /* 156 * On AST GEN4+, look at the configuration set by the SoC in 157 * the SOC scratch register #1 bits 11:8 (interestingly marked 158 * as "reserved" in the spec) 159 */ 160 vgacrd1 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 161 AST_IO_VGACRD1_TX_TYPE_MASK); 162 switch (vgacrd1) { 163 /* 164 * GEN4 to GEN6 165 */ 166 case AST_IO_VGACRD1_TX_SIL164_VBIOS: 167 ast->tx_chip = AST_TX_SIL164; 168 break; 169 case AST_IO_VGACRD1_TX_DP501_VBIOS: 170 ast->dp501_fw_addr = drmm_kzalloc(dev, 32*1024, GFP_KERNEL); 171 if (ast->dp501_fw_addr) { 172 /* backup firmware */ 173 if (ast_backup_fw(ast, ast->dp501_fw_addr, 32*1024)) { 174 drmm_kfree(dev, ast->dp501_fw_addr); 175 ast->dp501_fw_addr = NULL; 176 } 177 } 178 fallthrough; 179 case AST_IO_VGACRD1_TX_FW_EMBEDDED_FW: 180 ast->tx_chip = AST_TX_DP501; 181 break; 182 /* 183 * GEN7+ 184 */ 185 case AST_IO_VGACRD1_TX_ASTDP: 186 ast->tx_chip = AST_TX_ASTDP; 187 break; 188 /* 189 * Several of the listed TX chips are not explicitly supported 190 * by the ast driver. If these exist in real-world devices, they 191 * are most likely reported as VGA or SIL164 outputs. We warn here 192 * to get bug reports for these devices. If none come in for some 193 * time, we can begin to fail device probing on these values. 194 */ 195 case AST_IO_VGACRD1_TX_ITE66121_VBIOS: 196 drm_warn(dev, "ITE IT66121 detected, 0x%x, Gen%lu\n", 197 vgacrd1, AST_GEN(ast)); 198 break; 199 case AST_IO_VGACRD1_TX_CH7003_VBIOS: 200 drm_warn(dev, "Chrontel CH7003 detected, 0x%x, Gen%lu\n", 201 vgacrd1, AST_GEN(ast)); 202 break; 203 case AST_IO_VGACRD1_TX_ANX9807_VBIOS: 204 drm_warn(dev, "Analogix ANX9807 detected, 0x%x, Gen%lu\n", 205 vgacrd1, AST_GEN(ast)); 206 break; 207 } 208 } 209 210 drm_info(dev, "Using %s\n", info_str[ast->tx_chip]); 211 } 212 213 static int ast_get_dram_info(struct ast_device *ast) 214 { 215 struct drm_device *dev = &ast->base; 216 struct device_node *np = dev->dev->of_node; 217 uint32_t mcr_cfg, mcr_scu_mpll, mcr_scu_strap; 218 uint32_t denum, num, div, ref_pll, dsel; 219 220 switch (ast->config_mode) { 221 case ast_use_dt: 222 /* 223 * If some properties are missing, use reasonable 224 * defaults for GEN5 225 */ 226 if (of_property_read_u32(np, "aspeed,mcr-configuration", 227 &mcr_cfg)) 228 mcr_cfg = 0x00000577; 229 if (of_property_read_u32(np, "aspeed,mcr-scu-mpll", 230 &mcr_scu_mpll)) 231 mcr_scu_mpll = 0x000050C0; 232 if (of_property_read_u32(np, "aspeed,mcr-scu-strap", 233 &mcr_scu_strap)) 234 mcr_scu_strap = 0; 235 break; 236 case ast_use_p2a: 237 ast_write32(ast, 0xf004, 0x1e6e0000); 238 ast_write32(ast, 0xf000, 0x1); 239 mcr_cfg = ast_read32(ast, 0x10004); 240 mcr_scu_mpll = ast_read32(ast, 0x10120); 241 mcr_scu_strap = ast_read32(ast, 0x10170); 242 break; 243 case ast_use_defaults: 244 default: 245 ast->dram_bus_width = 16; 246 ast->dram_type = AST_DRAM_1Gx16; 247 if (IS_AST_GEN6(ast)) 248 ast->mclk = 800; 249 else 250 ast->mclk = 396; 251 return 0; 252 } 253 254 if (mcr_cfg & 0x40) 255 ast->dram_bus_width = 16; 256 else 257 ast->dram_bus_width = 32; 258 259 if (IS_AST_GEN6(ast)) { 260 switch (mcr_cfg & 0x03) { 261 case 0: 262 ast->dram_type = AST_DRAM_1Gx16; 263 break; 264 default: 265 case 1: 266 ast->dram_type = AST_DRAM_2Gx16; 267 break; 268 case 2: 269 ast->dram_type = AST_DRAM_4Gx16; 270 break; 271 case 3: 272 ast->dram_type = AST_DRAM_8Gx16; 273 break; 274 } 275 } else if (IS_AST_GEN4(ast) || IS_AST_GEN5(ast)) { 276 switch (mcr_cfg & 0x03) { 277 case 0: 278 ast->dram_type = AST_DRAM_512Mx16; 279 break; 280 default: 281 case 1: 282 ast->dram_type = AST_DRAM_1Gx16; 283 break; 284 case 2: 285 ast->dram_type = AST_DRAM_2Gx16; 286 break; 287 case 3: 288 ast->dram_type = AST_DRAM_4Gx16; 289 break; 290 } 291 } else { 292 switch (mcr_cfg & 0x0c) { 293 case 0: 294 case 4: 295 ast->dram_type = AST_DRAM_512Mx16; 296 break; 297 case 8: 298 if (mcr_cfg & 0x40) 299 ast->dram_type = AST_DRAM_1Gx16; 300 else 301 ast->dram_type = AST_DRAM_512Mx32; 302 break; 303 case 0xc: 304 ast->dram_type = AST_DRAM_1Gx32; 305 break; 306 } 307 } 308 309 if (mcr_scu_strap & 0x2000) 310 ref_pll = 14318; 311 else 312 ref_pll = 12000; 313 314 denum = mcr_scu_mpll & 0x1f; 315 num = (mcr_scu_mpll & 0x3fe0) >> 5; 316 dsel = (mcr_scu_mpll & 0xc000) >> 14; 317 switch (dsel) { 318 case 3: 319 div = 0x4; 320 break; 321 case 2: 322 case 1: 323 div = 0x2; 324 break; 325 default: 326 div = 0x1; 327 break; 328 } 329 ast->mclk = ref_pll * (num + 2) / ((denum + 2) * (div * 1000)); 330 return 0; 331 } 332 333 struct drm_device *ast_device_create(struct pci_dev *pdev, 334 const struct drm_driver *drv, 335 enum ast_chip chip, 336 enum ast_config_mode config_mode, 337 void __iomem *regs, 338 void __iomem *ioregs, 339 bool need_post) 340 { 341 struct drm_device *dev; 342 struct ast_device *ast; 343 int ret; 344 345 ast = devm_drm_dev_alloc(&pdev->dev, drv, struct ast_device, base); 346 if (IS_ERR(ast)) 347 return ERR_CAST(ast); 348 dev = &ast->base; 349 350 ast->chip = chip; 351 ast->config_mode = config_mode; 352 ast->regs = regs; 353 ast->ioregs = ioregs; 354 355 ret = ast_get_dram_info(ast); 356 if (ret) 357 return ERR_PTR(ret); 358 drm_info(dev, "dram MCLK=%u Mhz type=%d bus_width=%d\n", 359 ast->mclk, ast->dram_type, ast->dram_bus_width); 360 361 ast_detect_tx_chip(ast, need_post); 362 switch (ast->tx_chip) { 363 case AST_TX_ASTDP: 364 ret = ast_post_gpu(ast); 365 break; 366 default: 367 ret = 0; 368 if (need_post) 369 ret = ast_post_gpu(ast); 370 break; 371 } 372 if (ret) 373 return ERR_PTR(ret); 374 375 ret = ast_mm_init(ast); 376 if (ret) 377 return ERR_PTR(ret); 378 379 /* map reserved buffer */ 380 ast->dp501_fw_buf = NULL; 381 if (ast->vram_size < pci_resource_len(pdev, 0)) { 382 ast->dp501_fw_buf = pci_iomap_range(pdev, 0, ast->vram_size, 0); 383 if (!ast->dp501_fw_buf) 384 drm_info(dev, "failed to map reserved buffer!\n"); 385 } 386 387 ast_detect_widescreen(ast); 388 389 ret = ast_mode_config_init(ast); 390 if (ret) 391 return ERR_PTR(ret); 392 393 return dev; 394 } 395