summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/ast
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/ast')
-rw-r--r--drivers/gpu/drm/ast/ast_drv.c2
-rw-r--r--drivers/gpu/drm/ast/ast_drv.h6
-rw-r--r--drivers/gpu/drm/ast/ast_main.c5
-rw-r--r--drivers/gpu/drm/ast/ast_mode.c54
-rw-r--r--drivers/gpu/drm/ast/ast_post.c91
5 files changed, 116 insertions, 42 deletions
diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
index 5aa452b4efe6..86d5cd7b6318 100644
--- a/drivers/gpu/drm/ast/ast_drv.c
+++ b/drivers/gpu/drm/ast/ast_drv.c
@@ -100,7 +100,7 @@ static int ast_remove_conflicting_framebuffers(struct pci_dev *pdev)
primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
#endif
- return drm_aperture_remove_conflicting_framebuffers(base, size, primary, "astdrmfb");
+ return drm_aperture_remove_conflicting_framebuffers(base, size, primary, &ast_driver);
}
static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index 911f9f414774..39ca338eb80b 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -337,6 +337,11 @@ int ast_mode_config_init(struct ast_private *ast);
#define AST_DP501_LINKRATE 0xf014
#define AST_DP501_EDID_DATA 0xf020
+/* Define for Soc scratched reg */
+#define AST_VRAM_INIT_STATUS_MASK GENMASK(7, 6)
+//#define AST_VRAM_INIT_BY_BMC BIT(7)
+//#define AST_VRAM_INIT_READY BIT(6)
+
int ast_mm_init(struct ast_private *ast);
/* ast post */
@@ -346,6 +351,7 @@ bool ast_is_vga_enabled(struct drm_device *dev);
void ast_post_gpu(struct drm_device *dev);
u32 ast_mindwm(struct ast_private *ast, u32 r);
void ast_moutdwm(struct ast_private *ast, u32 r, u32 v);
+void ast_patch_ahb_2500(struct ast_private *ast);
/* ast dp501 */
void ast_set_dp501_video_output(struct drm_device *dev, u8 mode);
bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size);
diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
index 2aff2e6cf450..79a361867955 100644
--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
@@ -97,6 +97,11 @@ static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev)
jregd0 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
jregd1 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
if (!(jregd0 & 0x80) || !(jregd1 & 0x10)) {
+ /* Patch AST2500 */
+ if (((pdev->revision & 0xF0) == 0x40)
+ && ((jregd0 & AST_VRAM_INIT_STATUS_MASK) == 0))
+ ast_patch_ahb_2500(ast);
+
/* Double check it's actually working */
data = ast_read32(ast, 0xf004);
if ((data != 0xFFFFFFFF) && (data != 0x00)) {
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index 36d9575aa27b..6bfaefa01818 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -275,7 +275,7 @@ static void ast_set_std_reg(struct ast_private *ast,
ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, stdtable->seq[0]);
for (i = 1; i < 4; i++) {
jreg = stdtable->seq[i];
- ast_set_index_reg(ast, AST_IO_SEQ_PORT, (i + 1) , jreg);
+ ast_set_index_reg(ast, AST_IO_SEQ_PORT, (i + 1), jreg);
}
/* Set CRTC; except base address and offset */
@@ -498,13 +498,15 @@ static void ast_set_sync_reg(struct ast_private *ast,
jreg = ast_io_read8(ast, AST_IO_MISC_PORT_READ);
jreg &= ~0xC0;
- if (vbios_mode->enh_table->flags & NVSync) jreg |= 0x80;
- if (vbios_mode->enh_table->flags & NHSync) jreg |= 0x40;
+ if (vbios_mode->enh_table->flags & NVSync)
+ jreg |= 0x80;
+ if (vbios_mode->enh_table->flags & NHSync)
+ jreg |= 0x40;
ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg);
}
static void ast_set_start_address_crt1(struct ast_private *ast,
- unsigned offset)
+ unsigned int offset)
{
u32 addr;
@@ -612,8 +614,7 @@ ast_primary_plane_helper_atomic_disable(struct drm_plane *plane,
}
static const struct drm_plane_helper_funcs ast_primary_plane_helper_funcs = {
- .prepare_fb = drm_gem_vram_plane_helper_prepare_fb,
- .cleanup_fb = drm_gem_vram_plane_helper_cleanup_fb,
+ DRM_GEM_VRAM_PLANE_HELPER_FUNCS,
.atomic_check = ast_primary_plane_helper_atomic_check,
.atomic_update = ast_primary_plane_helper_atomic_update,
.atomic_disable = ast_primary_plane_helper_atomic_disable,
@@ -807,7 +808,7 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].map;
u64 dst_off =
ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].off;
- struct dma_buf_map src_map = shadow_plane_state->map[0];
+ struct dma_buf_map src_map = shadow_plane_state->data[0];
unsigned int offset_x, offset_y;
u16 x, y;
u8 x_offset, y_offset;
@@ -1212,6 +1213,7 @@ static int ast_get_modes(struct drm_connector *connector)
struct edid *edid;
int ret;
bool flags = false;
+
if (ast->tx_chip_type == AST_TX_DP501) {
ast->dp501_maxclk = 0xff;
edid = kmalloc(128, GFP_KERNEL);
@@ -1231,8 +1233,8 @@ static int ast_get_modes(struct drm_connector *connector)
ret = drm_add_edid_modes(connector, edid);
kfree(edid);
return ret;
- } else
- drm_connector_update_edid_property(&ast_connector->base, NULL);
+ }
+ drm_connector_update_edid_property(&ast_connector->base, NULL);
return 0;
}
@@ -1272,19 +1274,24 @@ static enum drm_mode_status ast_mode_valid(struct drm_connector *connector,
}
switch (mode->hdisplay) {
case 640:
- if (mode->vdisplay == 480) flags = MODE_OK;
+ if (mode->vdisplay == 480)
+ flags = MODE_OK;
break;
case 800:
- if (mode->vdisplay == 600) flags = MODE_OK;
+ if (mode->vdisplay == 600)
+ flags = MODE_OK;
break;
case 1024:
- if (mode->vdisplay == 768) flags = MODE_OK;
+ if (mode->vdisplay == 768)
+ flags = MODE_OK;
break;
case 1280:
- if (mode->vdisplay == 1024) flags = MODE_OK;
+ if (mode->vdisplay == 1024)
+ flags = MODE_OK;
break;
case 1600:
- if (mode->vdisplay == 1200) flags = MODE_OK;
+ if (mode->vdisplay == 1200)
+ flags = MODE_OK;
break;
default:
return flags;
@@ -1293,9 +1300,22 @@ static enum drm_mode_status ast_mode_valid(struct drm_connector *connector,
return flags;
}
+static enum drm_connector_status ast_connector_detect(struct drm_connector
+ *connector, bool force)
+{
+ int r;
+
+ r = ast_get_modes(connector);
+ if (r <= 0)
+ return connector_status_disconnected;
+
+ return connector_status_connected;
+}
+
static void ast_connector_destroy(struct drm_connector *connector)
{
struct ast_connector *ast_connector = to_ast_connector(connector);
+
ast_i2c_destroy(ast_connector->i2c);
drm_connector_cleanup(connector);
}
@@ -1307,6 +1327,7 @@ static const struct drm_connector_helper_funcs ast_connector_helper_funcs = {
static const struct drm_connector_funcs ast_connector_funcs = {
.reset = drm_atomic_helper_connector_reset,
+ .detect = ast_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = ast_connector_destroy,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
@@ -1334,7 +1355,8 @@ static int ast_connector_init(struct drm_device *dev)
connector->interlace_allowed = 0;
connector->doublescan_allowed = 0;
- connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+ connector->polled = DRM_CONNECTOR_POLL_CONNECT |
+ DRM_CONNECTOR_POLL_DISCONNECT;
drm_connector_attach_encoder(connector, encoder);
@@ -1403,6 +1425,8 @@ int ast_mode_config_init(struct ast_private *ast)
drm_mode_config_reset(dev);
+ drm_kms_helper_poll_init(dev);
+
return 0;
}
diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c
index 0607658dde51..b5d92f652fd8 100644
--- a/drivers/gpu/drm/ast/ast_post.c
+++ b/drivers/gpu/drm/ast/ast_post.c
@@ -2028,6 +2028,40 @@ static bool ast_dram_init_2500(struct ast_private *ast)
return true;
}
+void ast_patch_ahb_2500(struct ast_private *ast)
+{
+ u32 data;
+
+ /* Clear bus lock condition */
+ ast_moutdwm(ast, 0x1e600000, 0xAEED1A03);
+ ast_moutdwm(ast, 0x1e600084, 0x00010000);
+ ast_moutdwm(ast, 0x1e600088, 0x00000000);
+ ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8);
+ data = ast_mindwm(ast, 0x1e6e2070);
+ if (data & 0x08000000) { /* check fast reset */
+ /*
+ * If "Fast restet" is enabled for ARM-ICE debugger,
+ * then WDT needs to enable, that
+ * WDT04 is WDT#1 Reload reg.
+ * WDT08 is WDT#1 counter restart reg to avoid system deadlock
+ * WDT0C is WDT#1 control reg
+ * [6:5]:= 01:Full chip
+ * [4]:= 1:1MHz clock source
+ * [1]:= 1:WDT will be cleeared and disabled after timeout occurs
+ * [0]:= 1:WDT enable
+ */
+ ast_moutdwm(ast, 0x1E785004, 0x00000010);
+ ast_moutdwm(ast, 0x1E785008, 0x00004755);
+ ast_moutdwm(ast, 0x1E78500c, 0x00000033);
+ udelay(1000);
+ }
+ do {
+ ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8);
+ data = ast_mindwm(ast, 0x1e6e2000);
+ } while (data != 1);
+ ast_moutdwm(ast, 0x1e6e207c, 0x08000000); /* clear fast reset */
+}
+
void ast_post_chip_2500(struct drm_device *dev)
{
struct ast_private *ast = to_ast_private(dev);
@@ -2035,39 +2069,44 @@ void ast_post_chip_2500(struct drm_device *dev)
u8 reg;
reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
- if ((reg & 0x80) == 0) {/* vga only */
+ if ((reg & AST_VRAM_INIT_STATUS_MASK) == 0) {/* vga only */
/* Clear bus lock condition */
- ast_moutdwm(ast, 0x1e600000, 0xAEED1A03);
- ast_moutdwm(ast, 0x1e600084, 0x00010000);
- ast_moutdwm(ast, 0x1e600088, 0x00000000);
- ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8);
- ast_write32(ast, 0xf004, 0x1e6e0000);
- ast_write32(ast, 0xf000, 0x1);
- ast_write32(ast, 0x12000, 0x1688a8a8);
- while (ast_read32(ast, 0x12000) != 0x1)
- ;
-
- ast_write32(ast, 0x10000, 0xfc600309);
- while (ast_read32(ast, 0x10000) != 0x1)
- ;
+ ast_patch_ahb_2500(ast);
+
+ /* Disable watchdog */
+ ast_moutdwm(ast, 0x1E78502C, 0x00000000);
+ ast_moutdwm(ast, 0x1E78504C, 0x00000000);
+
+ /*
+ * Reset USB port to patch USB unknown device issue
+ * SCU90 is Multi-function Pin Control #5
+ * [29]:= 1:Enable USB2.0 Host port#1 (that the mutually shared USB2.0 Hub
+ * port).
+ * SCU94 is Multi-function Pin Control #6
+ * [14:13]:= 1x:USB2.0 Host2 controller
+ * SCU70 is Hardware Strap reg
+ * [23]:= 1:CLKIN is 25MHz and USBCK1 = 24/48 MHz (determined by
+ * [18]: 0(24)/1(48) MHz)
+ * SCU7C is Write clear reg to SCU70
+ * [23]:= write 1 and then SCU70[23] will be clear as 0b.
+ */
+ ast_moutdwm(ast, 0x1E6E2090, 0x20000000);
+ ast_moutdwm(ast, 0x1E6E2094, 0x00004000);
+ if (ast_mindwm(ast, 0x1E6E2070) & 0x00800000) {
+ ast_moutdwm(ast, 0x1E6E207C, 0x00800000);
+ mdelay(100);
+ ast_moutdwm(ast, 0x1E6E2070, 0x00800000);
+ }
+ /* Modify eSPI reset pin */
+ temp = ast_mindwm(ast, 0x1E6E2070);
+ if (temp & 0x02000000)
+ ast_moutdwm(ast, 0x1E6E207C, 0x00004000);
/* Slow down CPU/AHB CLK in VGA only mode */
temp = ast_read32(ast, 0x12008);
temp |= 0x73;
ast_write32(ast, 0x12008, temp);
- /* Reset USB port to patch USB unknown device issue */
- ast_moutdwm(ast, 0x1e6e2090, 0x20000000);
- temp = ast_mindwm(ast, 0x1e6e2094);
- temp |= 0x00004000;
- ast_moutdwm(ast, 0x1e6e2094, temp);
- temp = ast_mindwm(ast, 0x1e6e2070);
- if (temp & 0x00800000) {
- ast_moutdwm(ast, 0x1e6e207c, 0x00800000);
- mdelay(100);
- ast_moutdwm(ast, 0x1e6e2070, 0x00800000);
- }
-
if (!ast_dram_init_2500(ast))
drm_err(dev, "DRAM init failed !\n");