From 7f99fd5d7aa1f0d2463907d9d8c483b6249ac831 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 3 Oct 2007 14:08:18 -0700 Subject: First round of byte-ordering fixes for PowerPC. This isn't 100% as command submission via PCI-e GART buffers doesn't work. I've hacked around that for the time being. This is essentially the code that was used at the POWER.org event to show Bimini. --- linux-core/xgi_cmdlist.c | 46 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 11 deletions(-) (limited to 'linux-core/xgi_cmdlist.c') diff --git a/linux-core/xgi_cmdlist.c b/linux-core/xgi_cmdlist.c index 261f4e13..35f7e1bd 100644 --- a/linux-core/xgi_cmdlist.c +++ b/linux-core/xgi_cmdlist.c @@ -45,7 +45,7 @@ static inline void dwWriteReg(struct drm_map * map, u32 addr, u32 data) DRM_INFO("mmio_map->handle = 0x%p, addr = 0x%x, data = 0x%x\n", map->handle, addr, data); #endif - DRM_WRITE32(map, addr, data); + DRM_WRITE32(map, addr, cpu_to_le32(data)); } @@ -98,6 +98,25 @@ int xgi_submit_cmdlist(struct drm_device * dev, void * data, const struct xgi_cmd_info *const pCmdInfo = (struct xgi_cmd_info *) data; const unsigned int cmd = get_batch_command(pCmdInfo->type); +#if __BIG_ENDIAN + const u32 *const ptr = xgi_find_pcie_virt(info, pCmdInfo->hw_addr); + unsigned i; + unsigned j; + + xgi_waitfor_pci_idle(info); + for (j = 4; j < pCmdInfo->size; j += 4) { + u32 reg = ptr[j]; + + for (i = 1; i < 4; i++) { + if ((reg & 1) != 0) { + const unsigned r = 0x2100 | (reg & 0x0fe); + DRM_WRITE32(info->mmio_map, r, ptr[j + i]); + } + + reg >>= 8; + } + } +#else u32 begin[4]; @@ -138,16 +157,17 @@ int xgi_submit_cmdlist(struct drm_device * dev, void * data, xgi_emit_flush(info, FALSE); } - info->cmdring.last_ptr[1] = begin[1]; - info->cmdring.last_ptr[2] = begin[2]; - info->cmdring.last_ptr[3] = begin[3]; + info->cmdring.last_ptr[1] = cpu_to_le32(begin[1]); + info->cmdring.last_ptr[2] = cpu_to_le32(begin[2]); + info->cmdring.last_ptr[3] = cpu_to_le32(begin[3]); DRM_WRITEMEMORYBARRIER(); - info->cmdring.last_ptr[0] = begin[0]; + info->cmdring.last_ptr[0] = cpu_to_le32(begin[0]); triggerHWCommandList(info); } info->cmdring.last_ptr = xgi_find_pcie_virt(info, pCmdInfo->hw_addr); +#endif drm_fence_flush_old(info->dev, 0, info->next_sequence); return 0; } @@ -258,6 +278,8 @@ void xgi_emit_flush(struct xgi_info * info, bool stop) const unsigned int flush_size = sizeof(flush_command); u32 *batch_addr; u32 hw_addr; + unsigned int i; + /* check buf is large enough to contain a new flush batch */ if ((info->cmdring.ring_offset + flush_size) >= info->cmdring.size) { @@ -269,18 +291,20 @@ void xgi_emit_flush(struct xgi_info * info, bool stop) batch_addr = info->cmdring.ptr + (info->cmdring.ring_offset / 4); - (void) memcpy(batch_addr, flush_command, flush_size); + for (i = 0; i < (flush_size / 4); i++) { + batch_addr[i] = cpu_to_le32(flush_command[i]); + } if (stop) { - *batch_addr |= BEGIN_STOP_STORE_CURRENT_POINTER_MASK; + *batch_addr |= cpu_to_le32(BEGIN_STOP_STORE_CURRENT_POINTER_MASK); } - info->cmdring.last_ptr[1] = BEGIN_LINK_ENABLE_MASK | (flush_size / 4); - info->cmdring.last_ptr[2] = hw_addr >> 4; + info->cmdring.last_ptr[1] = cpu_to_le32(BEGIN_LINK_ENABLE_MASK | (flush_size / 4)); + info->cmdring.last_ptr[2] = cpu_to_le32(hw_addr >> 4); info->cmdring.last_ptr[3] = 0; DRM_WRITEMEMORYBARRIER(); - info->cmdring.last_ptr[0] = (get_batch_command(BTYPE_CTRL) << 24) - | (BEGIN_VALID_MASK); + info->cmdring.last_ptr[0] = cpu_to_le32((get_batch_command(BTYPE_CTRL) << 24) + | (BEGIN_VALID_MASK)); triggerHWCommandList(info); -- cgit v1.2.3 From 0379919e99542bc50cf9d0a8a3996b2896ec4e64 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 3 Oct 2007 14:12:16 -0700 Subject: Use 'ifdef __BIG_ENDIAN' instead of 'if __BIG_ENDIAN' --- linux-core/xgi_cmdlist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux-core/xgi_cmdlist.c') diff --git a/linux-core/xgi_cmdlist.c b/linux-core/xgi_cmdlist.c index 35f7e1bd..c25b0e0d 100644 --- a/linux-core/xgi_cmdlist.c +++ b/linux-core/xgi_cmdlist.c @@ -98,7 +98,7 @@ int xgi_submit_cmdlist(struct drm_device * dev, void * data, const struct xgi_cmd_info *const pCmdInfo = (struct xgi_cmd_info *) data; const unsigned int cmd = get_batch_command(pCmdInfo->type); -#if __BIG_ENDIAN +#ifdef __BIG_ENDIAN const u32 *const ptr = xgi_find_pcie_virt(info, pCmdInfo->hw_addr); unsigned i; unsigned j; -- cgit v1.2.3 From 83da774b192966b8c3f00b531ecfd4ec2b5eceaa Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 10 Oct 2007 15:25:30 -0700 Subject: Fix command list submission on big-endian. --- linux-core/xgi_cmdlist.c | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-) (limited to 'linux-core/xgi_cmdlist.c') diff --git a/linux-core/xgi_cmdlist.c b/linux-core/xgi_cmdlist.c index c25b0e0d..69bf6465 100644 --- a/linux-core/xgi_cmdlist.c +++ b/linux-core/xgi_cmdlist.c @@ -45,7 +45,7 @@ static inline void dwWriteReg(struct drm_map * map, u32 addr, u32 data) DRM_INFO("mmio_map->handle = 0x%p, addr = 0x%x, data = 0x%x\n", map->handle, addr, data); #endif - DRM_WRITE32(map, addr, cpu_to_le32(data)); + DRM_WRITE32(map, addr, data); } @@ -98,25 +98,6 @@ int xgi_submit_cmdlist(struct drm_device * dev, void * data, const struct xgi_cmd_info *const pCmdInfo = (struct xgi_cmd_info *) data; const unsigned int cmd = get_batch_command(pCmdInfo->type); -#ifdef __BIG_ENDIAN - const u32 *const ptr = xgi_find_pcie_virt(info, pCmdInfo->hw_addr); - unsigned i; - unsigned j; - - xgi_waitfor_pci_idle(info); - for (j = 4; j < pCmdInfo->size; j += 4) { - u32 reg = ptr[j]; - - for (i = 1; i < 4; i++) { - if ((reg & 1) != 0) { - const unsigned r = 0x2100 | (reg & 0x0fe); - DRM_WRITE32(info->mmio_map, r, ptr[j + i]); - } - - reg >>= 8; - } - } -#else u32 begin[4]; @@ -167,7 +148,6 @@ int xgi_submit_cmdlist(struct drm_device * dev, void * data, } info->cmdring.last_ptr = xgi_find_pcie_virt(info, pCmdInfo->hw_addr); -#endif drm_fence_flush_old(info->dev, 0, info->next_sequence); return 0; } @@ -323,13 +303,13 @@ void xgi_emit_flush(struct xgi_info * info, bool stop) */ void xgi_emit_nop(struct xgi_info * info) { - info->cmdring.last_ptr[1] = BEGIN_LINK_ENABLE_MASK - | (BEGIN_BEGIN_IDENTIFICATION_MASK & info->next_sequence); + info->cmdring.last_ptr[1] = cpu_to_le32(BEGIN_LINK_ENABLE_MASK + | (BEGIN_BEGIN_IDENTIFICATION_MASK & info->next_sequence)); info->cmdring.last_ptr[2] = 0; info->cmdring.last_ptr[3] = 0; DRM_WRITEMEMORYBARRIER(); - info->cmdring.last_ptr[0] = (get_batch_command(BTYPE_CTRL) << 24) - | (BEGIN_VALID_MASK); + info->cmdring.last_ptr[0] = cpu_to_le32((get_batch_command(BTYPE_CTRL) << 24) + | (BEGIN_VALID_MASK)); triggerHWCommandList(info); -- cgit v1.2.3 From fc7d4d19d36b6a12ed23d4d9e50826346258299f Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 10 Oct 2007 15:27:07 -0700 Subject: Eliminate trailing whitespace from last commit. --- linux-core/xgi_cmdlist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux-core/xgi_cmdlist.c') diff --git a/linux-core/xgi_cmdlist.c b/linux-core/xgi_cmdlist.c index 69bf6465..d7b23c89 100644 --- a/linux-core/xgi_cmdlist.c +++ b/linux-core/xgi_cmdlist.c @@ -303,12 +303,12 @@ void xgi_emit_flush(struct xgi_info * info, bool stop) */ void xgi_emit_nop(struct xgi_info * info) { - info->cmdring.last_ptr[1] = cpu_to_le32(BEGIN_LINK_ENABLE_MASK + info->cmdring.last_ptr[1] = cpu_to_le32(BEGIN_LINK_ENABLE_MASK | (BEGIN_BEGIN_IDENTIFICATION_MASK & info->next_sequence)); info->cmdring.last_ptr[2] = 0; info->cmdring.last_ptr[3] = 0; DRM_WRITEMEMORYBARRIER(); - info->cmdring.last_ptr[0] = cpu_to_le32((get_batch_command(BTYPE_CTRL) << 24) + info->cmdring.last_ptr[0] = cpu_to_le32((get_batch_command(BTYPE_CTRL) << 24) | (BEGIN_VALID_MASK)); triggerHWCommandList(info); -- cgit v1.2.3