From owner-freebsd-current@FreeBSD.ORG Wed Oct 27 08:01:10 2010 Return-Path: Delivered-To: current@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8A7381065674 for ; Wed, 27 Oct 2010 08:01:10 +0000 (UTC) (envelope-from ianf@clue.co.za) Received: from inbound01.jnb1.gp-online.net (inbound01.jnb1.gp-online.net [41.161.16.135]) by mx1.freebsd.org (Postfix) with ESMTP id 7F2B58FC14 for ; Wed, 27 Oct 2010 08:01:09 +0000 (UTC) Received: from [41.154.88.20] (helo=clue.co.za) by inbound01.jnb1.gp-online.net with esmtpsa (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.63) (envelope-from ) id 1PB0wU-0002Vw-7L; Wed, 27 Oct 2010 10:01:06 +0200 Received: from localhost ([127.0.0.1] helo=clue.co.za) by clue.co.za with esmtp (Exim 4.72 (FreeBSD)) (envelope-from ) id 1PB0wT-0000h0-AQ; Wed, 27 Oct 2010 10:01:05 +0200 Message-Id: X-Mailer: exmh version 2.7.2 01/07/2005 with nmh-1.2 X-Exmh-Isig-CompType: comp X-Exmh-Isig-Folder: lists/FreeBSD-current To: current@FreeBSD.org From: "Ian FREISLICH" X-Attribution: BOFH Mime-Version: 1.0 Content-Type: multipart/mixed ; boundary="==_Exmh_1288166009_18860" Date: Wed, 27 Oct 2010 10:01:05 +0200 Cc: rnoland@FreeBSD.org Subject: [patch] via_dma.c X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 27 Oct 2010 08:01:10 -0000 This is a multipart MIME message. --==_Exmh_1288166009_18860 Content-Type: text/plain Hi While trying to make googleearth work on a Via Epia LN board with openchrome and GL we noticed that the X server crashed after about 30 seconds of use. I got a flood of the following messages. Oct 26 12:13:24 test kernel: error: [drm:pid97391:via_hook_segment] *ERROR* Paused at incorrect address. 0xe1fcf300, 0xe1fc4900 0x00000000 Oct 26 12:13:24 test kernel: error: [drm:pid97391:via_hook_segment] *ERROR* Paused at incorrect address. 0xe1fd0300, 0xe1fc4900 0x00000000 Oct 26 12:13:24 test kernel: error: [drm:pid97391:via_cmdbuf_size] *ERROR* VIA_CMDBUF_LAG timed out. Some research showed that occasionally the GPU pauses and when the pipe is restarted, commands are reordered and the next command after the paused command is dropped. I located a patch which I hand applied because every chunk failed. It has fixed the stability issue and gpu pipe restarting issue. I still have a problem with googleearth only displaying its image in part of the window. It looks like the plane size is correct but it gets the offset wrong so there is a blank on the right side the size of the left menu pane and a blank at the bottom the size of the window bar and menu bar at the top of the window. Do you have any ideas how to fix this? Ian -- Ian Freislich --==_Exmh_1288166009_18860 Content-Type: text/plain ; name="viadrm.patch" Content-Description: viadrm.patch Content-Disposition: attachment; filename="viadrm.patch" Index: sys/dev/drm/via_dma.c =================================================================== RCS file: /home/ncvs/src/sys/dev/drm/via_dma.c,v retrieving revision 1.2 diff -u -d -r1.2 via_dma.c --- sys/dev/drm/via_dma.c 22 Apr 2010 18:21:25 -0000 1.2 +++ sys/dev/drm/via_dma.c 26 Oct 2010 15:03:04 -0000 @@ -119,10 +119,12 @@ uint32_t count; hw_addr_ptr = dev_priv->hw_addr_ptr; cur_addr = dev_priv->dma_low; - next_addr = cur_addr + size + 512 * 1024; + next_addr = cur_addr + size + 64 * 1024; count = 1000000; do { - hw_addr = *hw_addr_ptr - agp_base; + (void) *hw_addr_ptr; + DRM_MEMORYBARRIER(); + hw_addr = (*hw_addr_ptr - agp_base); if (count-- == 0) { DRM_ERROR ("via_cmdbuf_wait timed out hw %x cur_addr %x next_addr %x\n", @@ -272,7 +274,9 @@ { drm_via_private_t *dev_priv; uint32_t *vb; +#if 0 int ret; +#endif dev_priv = (drm_via_private_t *) dev->dev_private; @@ -285,7 +289,12 @@ return -ENOMEM; } - if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size)) + vb = via_check_dma(dev_priv, (cmd->size < 0x100) ? 0x102 : cmd->size); + if (vb == NULL) { + return -EAGAIN; + } + + if (DRM_COPY_FROM_USER(vb, cmd->buf, cmd->size)) return -EFAULT; /* @@ -294,19 +303,15 @@ * copy it to AGP memory when ready. */ +#if 0 if ((ret = via_verify_command_stream((uint32_t *) dev_priv->pci_buf, cmd->size, dev, 1))) { return ret; } - vb = via_check_dma(dev_priv, (cmd->size < 0x100) ? 0x102 : cmd->size); - if (vb == NULL) { - return -EAGAIN; - } - memcpy(vb, dev_priv->pci_buf, cmd->size); - +#endif dev_priv->dma_low += cmd->size; /* @@ -467,11 +472,28 @@ reader = *(dev_priv->hw_addr_ptr); diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff; diff &= (dev_priv->dma_high - 1); - if (diff != 0 && diff < (dev_priv->dma_high >> 1)) { - DRM_ERROR("Paused at incorrect address. " - "0x%08x, 0x%08x 0x%08x\n", - ptr, reader, dev_priv->dma_diff); - } else if (diff == 0) { + if (diff < (dev_priv->dma_high >> 1)) { + if (diff != 0) { + volatile uint32_t *rekick; + + DRM_INFO("Paused at incorrect address. " + "0x%08x, 0x%08x 0x%08x. Restarting.\n", + ptr, reader, dev_priv->dma_diff); + + /* + * Obtain the new pause address the command + * reader was supposed to pick up. + */ + + rekick = (volatile uint32_t *) + dev_priv->dma_ptr + + ((reader - dev_priv->dma_offset - + (uint32_t) dev_priv->agpAddr + + dev_priv->dma_diff - 4) >> 2); + pause_addr_lo = *rekick; + pause_addr_hi = *(--rekick); + } + /* * There is a concern that these writes may stall the PCI bus * if the GPU is not idle. However, idling the GPU first @@ -612,13 +634,16 @@ { uint32_t agp_base; uint32_t pause_addr_lo, pause_addr_hi; - uint32_t jump_addr_lo, jump_addr_hi; - volatile uint32_t *last_pause_ptr; + uint32_t jump_addr_lo, jump_addr_hi, hook_addr; + volatile uint32_t *hook_ptr; uint32_t dma_low_save1, dma_low_save2; agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr; + hook_ptr = via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, + &jump_addr_hi, &jump_addr_lo, 0); via_align_cmd(dev_priv, HC_HAGPBpID_JUMP, 0, &jump_addr_hi, - &jump_addr_lo, 0); + &hook_addr, 0); + *(--hook_ptr) = hook_addr; dev_priv->dma_wrap = dev_priv->dma_low; @@ -634,13 +659,13 @@ via_dummy_bitblt(dev_priv); via_dummy_bitblt(dev_priv); - last_pause_ptr = + hook_ptr = via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, - &pause_addr_lo, 0) - 1; + &pause_addr_lo, 0); via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, &pause_addr_lo, 0); - *last_pause_ptr = pause_addr_lo; + *(--hook_ptr) = pause_addr_lo; dma_low_save1 = dev_priv->dma_low; /* @@ -652,12 +677,12 @@ * does not seem to get updated immediately when a jump occurs. */ - last_pause_ptr = + hook_ptr = via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, - &pause_addr_lo, 0) - 1; + &pause_addr_lo, 0); via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, &pause_addr_lo, 0); - *last_pause_ptr = pause_addr_lo; + *(--hook_ptr) = pause_addr_lo; dma_low_save2 = dev_priv->dma_low; dev_priv->dma_low = dma_low_save1; @@ -674,9 +699,16 @@ static void via_cmdbuf_flush(drm_via_private_t * dev_priv, uint32_t cmd_type) { - uint32_t pause_addr_lo, pause_addr_hi; + uint32_t pause_addr_lo, pause_addr_hi, hook; + volatile uint32_t *hook_addr; - via_align_cmd(dev_priv, cmd_type, 0, &pause_addr_hi, &pause_addr_lo, 0); + hook_addr = via_align_cmd(dev_priv, cmd_type, 0, &pause_addr_hi, &pause_addr_lo, 0); +#if 1 + if (cmd_type == HC_HAGPBpID_PAUSE) { + via_align_cmd(dev_priv, cmd_type, 0, &pause_addr_hi, &hook, 0); + *(--hook_addr) = hook; + } +#endif via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0); } --==_Exmh_1288166009_18860--