coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
ast_main.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
2 /*
3  * Authors: Dave Airlie <airlied@redhat.com>
4  */
5 
6 #include <device/pci_def.h>
7 
8 #include "ast_drv.h"
9 #include "ast_dram_tables.h"
10 
12  uint32_t base, uint8_t index,
14 {
15  u8 tmp;
16  ast_io_write8(ast, base, index);
17  tmp = (ast_io_read8(ast, base + 1) & mask) | val;
18  ast_set_index_reg(ast, base, index, tmp);
19 }
20 
22  uint32_t base, uint8_t index)
23 {
24  uint8_t ret;
25  ast_io_write8(ast, base, index);
26  ret = ast_io_read8(ast, base + 1);
27  return ret;
28 }
29 
32 {
33  uint8_t ret;
34  ast_io_write8(ast, base, index);
35  ret = ast_io_read8(ast, base + 1) & mask;
36  return ret;
37 }
38 
39 static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev)
40 {
41  struct ast_private *ast = dev->dev_private;
42  uint32_t data, jregd0, jregd1;
43 
44  /* Defaults */
46  *scu_rev = 0xffffffff;
47 
48  /* Not all families have a P2A bridge */
49  if (dev->pdev->device != PCI_CHIP_AST2000)
50  return;
51 
52  /*
53  * The BMC will set SCU 0x40 D[12] to 1 if the P2 bridge
54  * is disabled. We force using P2A if VGA only mode bit
55  * is set D[7]
56  */
57  jregd0 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
58  jregd1 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
59  if (!(jregd0 & 0x80) || !(jregd1 & 0x10)) {
60  /* Double check it's actually working */
61  data = ast_read32(ast, 0xf004);
62  if (data != 0xFFFFFFFF) {
63  /* P2A works, grab silicon revision */
65 
66  DRM_INFO("Using P2A bridge for configuration\n");
67 
68  /* Read SCU7c (silicon revision register) */
69  ast_write32(ast, 0xf004, 0x1e6e0000);
70  ast_write32(ast, 0xf000, 0x1);
71  *scu_rev = ast_read32(ast, 0x1207c);
72  return;
73  }
74  }
75 
76  /* We have a P2A bridge but it's disabled */
77  DRM_INFO("P2A bridge disabled, using default configuration\n");
78 }
79 
80 static int ast_detect_chip(struct drm_device *dev, bool *need_post)
81 {
82  struct ast_private *ast = dev->dev_private;
83  uint32_t jreg, scu_rev;
84 
85  /*
86  * If VGA isn't enabled, we need to enable now or subsequent
87  * access to the scratch registers will fail. We also inform
88  * our caller that it needs to POST the chip
89  * (Assumption: VGA not enabled -> need to POST)
90  */
91  if (!ast_is_vga_enabled(dev)) {
93  DRM_INFO("VGA not enabled on entry, requesting chip POST\n");
94  *need_post = true;
95  } else
96  *need_post = false;
97 
98 
99  /* Enable extended register access */
101  ast_open_key(ast);
102 
103  /* Find out whether P2A works or whether to use device-tree */
104  ast_detect_config_mode(dev, &scu_rev);
105 
106  /* Identify chipset */
107  if (dev->pdev->device == PCI_CHIP_AST1180) {
108  ast->chip = AST1100;
109  DRM_INFO("AST 1180 detected\n");
110  } else {
111  uint32_t data;
112  pci_read_config_dword(ast->dev->pdev, 0x08, &data);
113  uint8_t revision = data & 0xff;
114  if (revision >= 0x40) {
115  ast->chip = AST2500;
116  DRM_INFO("AST 2500 detected\n");
117  } else if (revision >= 0x30) {
118  ast->chip = AST2400;
119  DRM_INFO("AST 2400 detected\n");
120  } else if (revision >= 0x20) {
121  ast->chip = AST2300;
122  DRM_INFO("AST 2300 detected\n");
123  } else if (revision >= 0x10) {
124  switch (scu_rev & 0x0300) {
125  case 0x0200:
126  ast->chip = AST1100;
127  DRM_INFO("AST 1100 detected\n");
128  break;
129  case 0x0100:
130  ast->chip = AST2200;
131  DRM_INFO("AST 2200 detected\n");
132  break;
133  case 0x0000:
134  ast->chip = AST2150;
135  DRM_INFO("AST 2150 detected\n");
136  break;
137  default:
138  ast->chip = AST2100;
139  DRM_INFO("AST 2100 detected\n");
140  break;
141  }
142  ast->vga2_clone = false;
143  } else {
144  ast->chip = AST2000;
145  DRM_INFO("AST 2000 detected\n");
146  }
147  }
148 
149  /* Check if we support wide screen */
150  switch (ast->chip) {
151  case AST1180:
152  ast->support_wide_screen = true;
153  break;
154  case AST2000:
155  ast->support_wide_screen = false;
156  break;
157  default:
158  jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
159  if (!(jreg & 0x80))
160  ast->support_wide_screen = true;
161  else if (jreg & 0x01)
162  ast->support_wide_screen = true;
163  else {
164  ast->support_wide_screen = false;
165  if (ast->chip == AST2300 &&
166  (scu_rev & 0x300) == 0x0) /* ast1300 */
167  ast->support_wide_screen = true;
168  if (ast->chip == AST2400 &&
169  (scu_rev & 0x300) == 0x100) /* ast1400 */
170  ast->support_wide_screen = true;
171  if (ast->chip == AST2500 &&
172  scu_rev == 0x100) /* ast2510 */
173  ast->support_wide_screen = true;
174  }
175  break;
176  }
177 
178  /* Check 3rd Tx option (digital output afaik) */
180 
181  /*
182  * VGACRA3 Enhanced Color Mode Register, check if DVO is already
183  * enabled, in that case, assume we have a SIL164 TMDS transmitter
184  *
185  * Don't make that assumption if we the chip wasn't enabled and
186  * is at power-on reset, otherwise we'll incorrectly "detect" a
187  * SIL164 when there is none.
188  */
189  if (!*need_post) {
190  jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xff);
191  if (jreg & 0x80)
193  }
194 
195  if ((ast->chip == AST2300) || (ast->chip == AST2400)) {
196  /*
197  * On AST2300 and 2400, look the configuration set by the SoC in
198  * the SOC scratch register #1 bits 11:8 (interestingly marked
199  * as "reserved" in the spec)
200  */
201  jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
202  switch (jreg) {
203  case 0x04:
205  break;
206  case 0x08:
207  ast->dp501_fw_addr = kzalloc(32*1024, GFP_KERNEL);
208  if (ast->dp501_fw_addr) {
209  /* backup firmware */
210  if (ast_backup_fw(dev, ast->dp501_fw_addr, 32*1024)) {
213  }
214  }
216  case 0x0c:
218  }
219  }
220 
221  /* Print stuff for diagnostic purposes */
222  switch (ast->tx_chip_type) {
223  case AST_TX_SIL164:
224  DRM_INFO("Using Sil164 TMDS transmitter\n");
225  break;
226  case AST_TX_DP501:
227  DRM_INFO("Using DP501 DisplayPort transmitter\n");
228  break;
229  default:
230  DRM_INFO("Analog VGA only\n");
231  }
232  return 0;
233 }
234 
235 static int ast_get_dram_info(struct drm_device *dev)
236 {
237  struct ast_private *ast = dev->dev_private;
238  uint32_t mcr_cfg, mcr_scu_mpll, mcr_scu_strap;
239  uint32_t denum, num, div, ref_pll, dsel;
240 
241  switch (ast->config_mode) {
242  case ast_use_dt:
243  /*
244  * If some properties are missing, use reasonable
245  * defaults for AST2400
246  */
247  mcr_cfg = 0x00000577;
248  mcr_scu_mpll = 0x000050C0;
249  mcr_scu_strap = 0;
250  break;
251  case ast_use_p2a:
252  ast_write32(ast, 0xf004, 0x1e6e0000);
253  ast_write32(ast, 0xf000, 0x1);
254  mcr_cfg = ast_read32(ast, 0x10004);
255  mcr_scu_mpll = ast_read32(ast, 0x10120);
256  mcr_scu_strap = ast_read32(ast, 0x10170);
257  break;
258  case ast_use_defaults:
259  default:
260  ast->dram_bus_width = 16;
262  if (ast->chip == AST2500)
263  ast->mclk = 800;
264  else
265  ast->mclk = 396;
266  return 0;
267  }
268 
269  if (mcr_cfg & 0x40)
270  ast->dram_bus_width = 16;
271  else
272  ast->dram_bus_width = 32;
273 
274  if (ast->chip == AST2500) {
275  switch (mcr_cfg & 0x03) {
276  case 0:
278  break;
279  default:
280  case 1:
282  break;
283  case 2:
285  break;
286  case 3:
288  break;
289  }
290  } else if (ast->chip == AST2300 || ast->chip == AST2400) {
291  switch (mcr_cfg & 0x03) {
292  case 0:
294  break;
295  default:
296  case 1:
298  break;
299  case 2:
301  break;
302  case 3:
304  break;
305  }
306  } else {
307  switch (mcr_cfg & 0x0c) {
308  case 0:
309  case 4:
311  break;
312  case 8:
313  if (mcr_cfg & 0x40)
315  else
317  break;
318  case 0xc:
320  break;
321  }
322  }
323 
324  if (mcr_scu_strap & 0x2000)
325  ref_pll = 14318;
326  else
327  ref_pll = 12000;
328 
329  denum = mcr_scu_mpll & 0x1f;
330  num = (mcr_scu_mpll & 0x3fe0) >> 5;
331  dsel = (mcr_scu_mpll & 0xc000) >> 14;
332  switch (dsel) {
333  case 3:
334  div = 0x4;
335  break;
336  case 2:
337  case 1:
338  div = 0x2;
339  break;
340  default:
341  div = 0x1;
342  break;
343  }
344  ast->mclk = ref_pll * (num + 2) / (denum + 2) * (div * 1000);
345  return 0;
346 }
347 
349 {
350  struct ast_private *ast = dev->dev_private;
351  u8 jreg;
352  u32 vram_size;
353  ast_open_key(ast);
354 
356  jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xaa, 0xff);
357  switch (jreg & 3) {
358  case 0: vram_size = AST_VIDMEM_SIZE_8M; break;
359  case 1: vram_size = AST_VIDMEM_SIZE_16M; break;
360  case 2: vram_size = AST_VIDMEM_SIZE_32M; break;
361  case 3: vram_size = AST_VIDMEM_SIZE_64M; break;
362  }
363 
364  jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xff);
365  switch (jreg & 0x03) {
366  case 1:
367  vram_size -= 0x100000;
368  break;
369  case 2:
370  vram_size -= 0x200000;
371  break;
372  case 3:
373  vram_size -= 0x400000;
374  break;
375  }
376 
377  return vram_size;
378 }
379 
380 int ast_driver_load(struct drm_device *dev, unsigned long flags)
381 {
382  struct ast_private *ast;
383  bool need_post;
384  int ret = 0;
385  struct resource *res;
386 
387  ast = kzalloc(sizeof(struct ast_private), GFP_KERNEL);
388  if (!ast)
389  return -ENOMEM;
390 
391  dev->dev_private = ast;
392  ast->dev = dev;
393 
394  /* PCI BAR 1 */
396  if (!res) {
397  dev_err(dev->pdev, "BAR1 resource not found.\n");
398  ret = -EIO;
399  goto out_free;
400  }
401  ast->regs = res2mmio(res, 0, 0);
402  if (!ast->regs) {
403  ret = -EIO;
404  goto out_free;
405  }
406 
407  /* PCI BAR 2 */
408  ast->io_space_uses_mmap = false;
410  if (!res)
411  dev_err(dev->pdev, "BAR2 resource not found.\n");
412 
413  /*
414  * If we don't have IO space at all, use MMIO now and
415  * assume the chip has MMIO enabled by default (rev 0x20
416  * and higher).
417  */
418  if (!res || !(res->flags & IORESOURCE_IO)) {
419  DRM_INFO("platform has no IO space, trying MMIO\n");
421  ast->io_space_uses_mmap = true;
422  }
423 
424  /* "map" IO regs if the above hasn't done so already */
425  if (!ast->ioregs) {
426  ast->ioregs = res2mmio(res, 0, 0);
427  if (!ast->ioregs) {
428  ret = -EIO;
429  goto out_free;
430  }
431  }
432 
433  ast_detect_chip(dev, &need_post);
434 
435  if (need_post)
436  ast_post_gpu(dev);
437 
438  if (ast->chip != AST1180) {
439  ret = ast_get_dram_info(dev);
440  if (ret)
441  goto out_free;
443  DRM_INFO("dram MCLK=%u Mhz type=%d bus_width=%d size=%08x\n",
444  ast->mclk, ast->dram_type,
446  }
447 
448  return 0;
449 out_free:
450  kfree(ast);
451  dev->dev_private = NULL;
452  return ret;
453 }
#define GFP_KERNEL
static int pci_read_config_dword(struct pci_dev *dev, int where, u32 *val)
#define kfree(address)
#define DRM_INFO
#define dev_err(dev, format, arg...)
static void * kzalloc(size_t size, int flags)
bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size)
Definition: ast_dp501.c:123
#define AST_VIDMEM_SIZE_8M
Definition: ast_drv.h:161
void ast_post_gpu(struct drm_device *dev)
Definition: ast_post.c:356
@ AST_TX_DP501
Definition: ast_drv.h:30
@ AST_TX_SIL164
Definition: ast_drv.h:28
@ AST_TX_NONE
Definition: ast_drv.h:27
#define AST_DRAM_512Mx16
Definition: ast_drv.h:33
#define AST_DRAM_8Gx16
Definition: ast_drv.h:39
#define AST_DRAM_1Gx16
Definition: ast_drv.h:34
#define AST_VIDMEM_SIZE_16M
Definition: ast_drv.h:162
#define AST_IO_CRTC_PORT
Definition: ast_drv.h:89
#define AST_DRAM_4Gx16
Definition: ast_drv.h:38
#define PCI_CHIP_AST2000
Definition: ast_drv.h:10
#define AST_DRAM_512Mx32
Definition: ast_drv.h:35
@ AST2200
Definition: ast_drv.h:18
@ AST2400
Definition: ast_drv.h:21
@ AST2500
Definition: ast_drv.h:22
@ AST2100
Definition: ast_drv.h:16
@ AST1100
Definition: ast_drv.h:17
@ AST2000
Definition: ast_drv.h:15
@ AST2150
Definition: ast_drv.h:19
@ AST1180
Definition: ast_drv.h:23
@ AST2300
Definition: ast_drv.h:20
void ast_enable_mmio(struct drm_device *dev)
Definition: ast_post.c:22
static void ast_set_index_reg(struct ast_private *ast, uint32_t base, uint8_t index, uint8_t val)
Definition: ast_drv.h:141
#define AST_IO_MM_OFFSET
Definition: ast_drv.h:93
void ast_enable_vga(struct drm_device *dev)
Definition: ast_post.c:14
#define AST_DRAM_1Gx32
Definition: ast_drv.h:36
bool ast_is_vga_enabled(struct drm_device *dev)
Definition: ast_post.c:29
#define AST_DRAM_2Gx16
Definition: ast_drv.h:37
#define AST_VIDMEM_SIZE_32M
Definition: ast_drv.h:163
#define AST_VIDMEM_SIZE_64M
Definition: ast_drv.h:164
#define PCI_CHIP_AST1180
Definition: ast_drv.h:12
static void ast_open_key(struct ast_private *ast)
Definition: ast_drv.h:156
#define AST_VIDMEM_DEFAULT_SIZE
Definition: ast_drv.h:167
static struct ast_private * ast
Definition: ast_i2c.c:10
uint8_t ast_get_index_reg_mask(struct ast_private *ast, uint32_t base, uint8_t index, uint8_t mask)
Definition: ast_main.c:30
static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev)
Definition: ast_main.c:39
static int ast_get_dram_info(struct drm_device *dev)
Definition: ast_main.c:235
void ast_set_index_reg_mask(struct ast_private *ast, uint32_t base, uint8_t index, uint8_t mask, uint8_t val)
Definition: ast_main.c:11
static u32 ast_get_vram_info(struct drm_device *dev)
Definition: ast_main.c:348
int ast_driver_load(struct drm_device *dev, unsigned long flags)
Definition: ast_main.c:380
uint8_t ast_get_index_reg(struct ast_private *ast, uint32_t base, uint8_t index)
Definition: ast_main.c:21
static int ast_detect_chip(struct drm_device *dev, bool *need_post)
Definition: ast_main.c:80
#define __fallthrough
Definition: compiler.h:39
struct resource * probe_resource(const struct device *dev, unsigned int index)
See if a resource structure already exists for a given index.
Definition: device_util.c:323
#define ENOMEM
Definition: errno.h:17
#define EIO
Definition: errno.h:10
#define PCI_BASE_ADDRESS_2
Definition: pci_def.h:65
#define PCI_BASE_ADDRESS_1
Definition: pci_def.h:64
#define IORESOURCE_IO
Definition: resource.h:9
static void * res2mmio(const struct resource *res, unsigned long offset, unsigned long mask)
Definition: resource.h:87
uintptr_t base
Definition: uart.c:17
static const int mask[4]
Definition: gpio.c:308
#define NULL
Definition: stddef.h:19
unsigned int uint32_t
Definition: stdint.h:14
uint32_t u32
Definition: stdint.h:51
uint8_t u8
Definition: stdint.h:45
unsigned char uint8_t
Definition: stdint.h:8
void __iomem * regs
Definition: ast_drv.h:46
enum ast_private::@25 config_mode
uint32_t mclk
Definition: ast_drv.h:54
struct drm_device * dev
Definition: ast_drv.h:44
@ ast_use_p2a
Definition: ast_drv.h:67
@ ast_use_defaults
Definition: ast_drv.h:69
@ ast_use_dt
Definition: ast_drv.h:68
uint32_t vram_size
Definition: ast_drv.h:55
enum ast_chip chip
Definition: ast_drv.h:50
uint32_t dram_type
Definition: ast_drv.h:53
u8 * dp501_fw_addr
Definition: ast_drv.h:74
uint32_t dram_bus_width
Definition: ast_drv.h:52
bool support_wide_screen
Definition: ast_drv.h:65
bool io_space_uses_mmap
Definition: ast_drv.h:48
enum ast_tx_chip tx_chip_type
Definition: ast_drv.h:72
void __iomem * ioregs
Definition: ast_drv.h:47
bool vga2_clone
Definition: ast_drv.h:51
void * dev_private
struct pci_dev * pdev
unsigned long flags
Definition: resource.h:49
u8 val
Definition: sys.c:300