| @@ -27,10 +27,6 @@ · 26 unmodified lines |
| 27 | #include "state_hi.xml.h" | 27 | #include "state_hi.xml.h" |
| 28 | #include "cmdstream.xml.h" | 28 | #include "cmdstream.xml.h" |
| 29 | | 29 | |
| 30 | #ifndef PHYS_OFFSET | | |
| 31 | #define PHYS_OFFSET 0 | | |
| 32 | #endif | | |
| 33 | | | |
| 34 | static const struct platform_device_id gpu_ids[] = { | 30 | static const struct platform_device_id gpu_ids[] = { |
| 35 | { .name = "etnaviv-gpu,2d" }, | 31 | { .name = "etnaviv-gpu,2d" }, |
| 36 | { }, | 32 | { }, |
| @@ -156,6 +152,18 @@ int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 param, u64 *value) · 119 unmodified lines |
| 156 | *value = ~0ULL; | 152 | *value = ~0ULL; |
| 157 | break; | 153 | break; |
| 158 | | 154 | |
| | 155 | case ETNAVIV_PARAM_GPU_PRODUCT_ID: |
| | 156 | *value = gpu->identity.product_id; |
| | 157 | break; |
| | 158 | |
| | 159 | case ETNAVIV_PARAM_GPU_CUSTOMER_ID: |
| | 160 | *value = gpu->identity.customer_id; |
| | 161 | break; |
| | 162 | |
| | 163 | case ETNAVIV_PARAM_GPU_ECO_ID: |
| | 164 | *value = gpu->identity.eco_id; |
| | 165 | break; |
| | 166 | |
| 159 | default: | 167 | default: |
| 160 | DBG("%s: invalid param: %u", dev_name(gpu->dev), param); | 168 | DBG("%s: invalid param: %u", dev_name(gpu->dev), param); |
| 161 | return -EINVAL; | 169 | return -EINVAL; |
| @@ -724,6 +732,7 @@ static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu) · 562 unmodified lines |
| 724 | int etnaviv_gpu_init(struct etnaviv_gpu *gpu) | 732 | int etnaviv_gpu_init(struct etnaviv_gpu *gpu) |
| 725 | { | 733 | { |
| 726 | struct etnaviv_drm_private *priv = gpu->drm->dev_private; | 734 | struct etnaviv_drm_private *priv = gpu->drm->dev_private; |
| | 735 | dma_addr_t cmdbuf_paddr; |
| 727 | int ret, i; | 736 | int ret, i; |
| 728 | | 737 | |
| 729 | ret = pm_runtime_get_sync(gpu->dev); | 738 | ret = pm_runtime_get_sync(gpu->dev); |
| @@ -766,28 +775,6 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu) · 36 unmodified lines |
| 766 | if (ret) | 775 | if (ret) |
| 767 | goto fail; | 776 | goto fail; |
| 768 | | 777 | |
| 769 | /* | | |
| 770 | * Set the GPU linear window to be at the end of the DMA window, where | | |
| 771 | * the CMA area is likely to reside. This ensures that we are able to | | |
| 772 | * map the command buffers while having the linear window overlap as | | |
| 773 | * much RAM as possible, so we can optimize mappings for other buffers. | | |
| 774 | * | | |
| 775 | * For 3D cores only do this if MC2.0 is present, as with MC1.0 it leads | | |
| 776 | * to different views of the memory on the individual engines. | | |
| 777 | */ | | |
| 778 | if (!(gpu->identity.features & chipFeatures_PIPE_3D) || | | |
| 779 | (gpu->identity.minor_features0 & chipMinorFeatures0_MC20)) { | | |
| 780 | u32 dma_mask = (u32)dma_get_required_mask(gpu->dev); | | |
| 781 | if (dma_mask < PHYS_OFFSET + SZ_2G) | | |
| 782 | priv->mmu_global->memory_base = PHYS_OFFSET; | | |
| 783 | else | | |
| 784 | priv->mmu_global->memory_base = dma_mask - SZ_2G + 1; | | |
| 785 | } else if (PHYS_OFFSET >= SZ_2G) { | | |
| 786 | dev_info(gpu->dev, "Need to move linear window on MC1.0, disabling TS\n"); | | |
| 787 | priv->mmu_global->memory_base = PHYS_OFFSET; | | |
| 788 | gpu->identity.features &= ~chipFeatures_FAST_CLEAR; | | |
| 789 | } | | |
| 790 | | | |
| 791 | /* | 778 | /* |
| 792 | * If the GPU is part of a system with DMA addressing limitations, | 779 | * If the GPU is part of a system with DMA addressing limitations, |
| 793 | * request pages for our SHM backend buffers from the DMA32 zone to | 780 | * request pages for our SHM backend buffers from the DMA32 zone to |
| @@ -804,6 +791,31 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu) · 10 unmodified lines |
| 804 | goto fail; | 791 | goto fail; |
| 805 | } | 792 | } |
| 806 | | 793 | |
| | 794 | /* |
| | 795 | * Set the GPU linear window to cover the cmdbuf region, as the GPU |
| | 796 | * won't be able to start execution otherwise. The alignment to 128M is |
| | 797 | * chosen arbitrarily but helps in debugging, as the MMU offset |
| | 798 | * calculations are much more straight forward this way. |
| | 799 | * |
| | 800 | * On MC1.0 cores the linear window offset is ignored by the TS engine, |
| | 801 | * leading to inconsistent memory views. Avoid using the offset on those |
| | 802 | * cores if possible, otherwise disable the TS feature. |
| | 803 | */ |
| | 804 | cmdbuf_paddr = ALIGN_DOWN(etnaviv_cmdbuf_get_pa(&gpu->buffer), SZ_128M); |
| | 805 | |
| | 806 | if (!(gpu->identity.features & chipFeatures_PIPE_3D) || |
| | 807 | (gpu->identity.minor_features0 & chipMinorFeatures0_MC20)) { |
| | 808 | if (cmdbuf_paddr >= SZ_2G) |
| | 809 | priv->mmu_global->memory_base = SZ_2G; |
| | 810 | else |
| | 811 | priv->mmu_global->memory_base = cmdbuf_paddr; |
| | 812 | } else if (cmdbuf_paddr + SZ_128M >= SZ_2G) { |
| | 813 | dev_info(gpu->dev, |
| | 814 | "Need to move linear window on MC1.0, disabling TS\n"); |
| | 815 | gpu->identity.features &= ~chipFeatures_FAST_CLEAR; |
| | 816 | priv->mmu_global->memory_base = SZ_2G; |
| | 817 | } |
| | 818 | |
| 807 | /* Setup event management */ | 819 | /* Setup event management */ |
| 808 | spin_lock_init(&gpu->event_spinlock); | 820 | spin_lock_init(&gpu->event_spinlock); |
| 809 | init_completion(&gpu->event_free); | 821 | init_completion(&gpu->event_free); |
| @@ -1771,10 +1783,8 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev) · 961 unmodified lines |
| 1771 | | 1783 | |
| 1772 | /* Get Interrupt: */ | 1784 | /* Get Interrupt: */ |
| 1773 | gpu->irq = platform_get_irq(pdev, 0); | 1785 | gpu->irq = platform_get_irq(pdev, 0); |
| 1774 | if (gpu->irq < 0) { | 1786 | if (gpu->irq < 0) |
| 1775 | dev_err(dev, "failed to get irq: %d\n", gpu->irq); | | |
| 1776 | return gpu->irq; | 1787 | return gpu->irq; |
| 1777 | } | | |
| 1778 | | 1788 | |
| 1779 | err = devm_request_irq(&pdev->dev, gpu->irq, irq_handler, 0, | 1789 | err = devm_request_irq(&pdev->dev, gpu->irq, irq_handler, 0, |
| 1780 | dev_name(gpu->dev), gpu); | 1790 | dev_name(gpu->dev), gpu); |