@@ -65,6 +65,7 @@ uint8_t ast_get_index_reg_mask(struct ast_private *ast,
static int ast_detect_chip(struct drm_device *dev, bool *need_post)
{
+ struct device_node *np = dev->pdev->dev.of_node;
struct ast_private *ast = dev->dev_private;
uint32_t data, jreg;
ast_open_key(ast);
@@ -140,10 +141,16 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
ast->support_wide_screen = true;
else {
ast->support_wide_screen = false;
- /* Read SCU7c (silicon revision register) */
- ast_write32(ast, 0xf004, 0x1e6e0000);
- ast_write32(ast, 0xf000, 0x1);
- data = ast_read32(ast, 0x1207c);
+
+ if (!np || of_property_read_u32(np,
+ "ast,scu-revision-id",
+ &data)) {
+ /* Read SCU7c (silicon revision register) */
+ ast_write32(ast, 0xf004, 0x1e6e0000);
+ ast_write32(ast, 0xf000, 0x1);
+ data = ast_read32(ast, 0x1207c);
+ }
+
data &= 0x300;
if (ast->chip == AST2300 && data == 0x0) /* ast1300 */
ast->support_wide_screen = true;
@@ -212,21 +219,24 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
static int ast_get_dram_info(struct drm_device *dev)
{
+ struct device_node *np = dev->pdev->dev.of_node;
struct ast_private *ast = dev->dev_private;
uint32_t data, data2;
uint32_t denum, num, div, ref_pll;
- ast_write32(ast, 0xf004, 0x1e6e0000);
- ast_write32(ast, 0xf000, 0x1);
+ if (!np || of_property_read_u32(np, "ast,mcr-configuration", &data)) {
+ ast_write32(ast, 0xf004, 0x1e6e0000);
+ ast_write32(ast, 0xf000, 0x1);
+ ast_write32(ast, 0x10000, 0xfc600309);
- ast_write32(ast, 0x10000, 0xfc600309);
-
- do {
- if (pci_channel_offline(dev->pdev))
- return -EIO;
- } while (ast_read32(ast, 0x10000) != 0x01);
- data = ast_read32(ast, 0x10004);
+ /* poll until unlocked */
+ do {
+ if (pci_channel_offline(dev->pdev))
+ return -EIO;
+ } while (ast_read32(ast, 0x10000) != 0x01);
+ data = ast_read32(ast, 0x10004);
+ }
if (data & 0x40)
ast->dram_bus_width = 16;
@@ -267,8 +277,14 @@ static int ast_get_dram_info(struct drm_device *dev)
}
}
- data = ast_read32(ast, 0x10120);
- data2 = ast_read32(ast, 0x10170);
+ if (!np || of_property_read_u32(np, "ast,mcr-scu-mpll", &data)) {
+ data = ast_read32(ast, 0x10120);
+ data2 = ast_read32(ast, 0x10170);
+ } else {
+ /* always 0 for AST2400 and AST2500 */
+ data2 = 0;
+ }
+
if (data2 & 0x2000)
ref_pll = 14318;
else
The ast driver configures a window to enable access into BMC memory space in order to read some configuration registers. If this window is disabled, which it can be from the BMC side, the ast driver can't function. Closing this window is a necessity for security if a machine's host side and BMC side are controlled by different parties; i.e. a cloud provider offering machines "bare metal". To work around this, enable reading these configuration values from the device tree instead of through the window into BMC memory. This enables the driver to work when the window is closed; if the window is open, the driver functions as usual regardless of whether it uses the device tree or register accesses. Signed-off-by: Russell Currey <ruscur@russell.cc> --- This patch applies on top of my other patch "drivers/gpu/drm/ast: Fix infinite loop if read fails" which was recently applied to drm-misc-fixes. --- drivers/gpu/drm/ast/ast_main.c | 46 ++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 15 deletions(-)