Re: Potential BUG: [PATCH 2/8] drm/amdgpu: add a generic fb accessing helper function(v3)

2019-11-20 Thread Christian König

Hi Luben & Iago,

no the code is completely correct and intentional like this.

See the code path which takes the lock in amdgpu_mm_wreg() is a 
workaround when the rmmio_size doesn't allow access to the full register 
BAR.


In this case the MM_INDEX/MM_DATA registers are used as side path and 
because of this we need the lock.


But this case can't happen when you use the MM_INDEX/MM_DATA pair 
directly as parameters for the function.


Regards,
Christian.

Am 20.11.19 um 01:23 schrieb Luben Tuikov:

Hi Iago,

Thank you for finding and reporting this potential double lock.

Yes indeed, I see it--it can indeed happen.

Now, since the primitives used--macros using "amdgpu_mm_(r|w)reg\(.*\)"--in
"amdgpu_device_vram_access()" do use their own register-access spinlocks,
it maybe wise to remove the spinlock take/release in 
"amdgpu_device_vram_access()".

We'll look into it and possibly submit another patch.

Thanks again.

Regards,
Luben

On 2019-11-16 11:21 a.m., Iago Abal wrote:

Hi,

With the help of a static bug finder (EBA - https://github.com/IagoAbal/eba) I 
have found a potential double lock in Linux Next tag next-20191115, file 
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c.

This bug seems to be introduced by commit
e35e2b117f4 ("drm/amdgpu: add a generic fb accessing helper function(v3)").

The steps to reproduce it would be:

1. Start in function `amdgpu_device_vram_access`.
2. Enter for-loop `for (last += pos; pos <= last; pos += 4)`.
3. First lock: `spin_lock_irqsave(&adev->mmio_idx_lock, flags)`.
4. Call to `WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)pos) | 0x8000)`.
    5. Note `#define WREG32_NO_KIQ(reg, v) amdgpu_mm_wreg(adev, (reg), (v), 
AMDGPU_REGS_NO_KIQ)`.
    6. Continue in function `amdgpu_mm_wreg`.
    7. Take else-branch in the third if-statement.
    8. Double lock: `spin_lock_irqsave(&adev->mmio_idx_lock, flags)`.

I think the control flow could reach that second lock, but you may know better.

Hope it helps!

-- iago

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: Potential BUG: [PATCH 2/8] drm/amdgpu: add a generic fb accessing helper function(v3)

2019-11-19 Thread Luben Tuikov
Hi Iago,

Thank you for finding and reporting this potential double lock.

Yes indeed, I see it--it can indeed happen.

Now, since the primitives used--macros using "amdgpu_mm_(r|w)reg\(.*\)"--in
"amdgpu_device_vram_access()" do use their own register-access spinlocks,
it maybe wise to remove the spinlock take/release in 
"amdgpu_device_vram_access()".

We'll look into it and possibly submit another patch.

Thanks again.

Regards,
Luben

On 2019-11-16 11:21 a.m., Iago Abal wrote:
> Hi,
> 
> With the help of a static bug finder (EBA - https://github.com/IagoAbal/eba) 
> I have found a potential double lock in Linux Next tag next-20191115, file 
> drivers/gpu/drm/amd/amdgpu/amdgpu_device.c.
> 
> This bug seems to be introduced by commit
> e35e2b117f4 ("drm/amdgpu: add a generic fb accessing helper function(v3)").
> 
> The steps to reproduce it would be:
> 
> 1. Start in function `amdgpu_device_vram_access`.
> 2. Enter for-loop `for (last += pos; pos <= last; pos += 4)`.
> 3. First lock: `spin_lock_irqsave(&adev->mmio_idx_lock, flags)`.
> 4. Call to `WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)pos) | 0x8000)`.
>    5. Note `#define WREG32_NO_KIQ(reg, v) amdgpu_mm_wreg(adev, (reg), (v), 
> AMDGPU_REGS_NO_KIQ)`.
>    6. Continue in function `amdgpu_mm_wreg`.
>    7. Take else-branch in the third if-statement.
>    8. Double lock: `spin_lock_irqsave(&adev->mmio_idx_lock, flags)`.
> 
> I think the control flow could reach that second lock, but you may know 
> better.
> 
> Hope it helps!
> 
> -- iago

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Potential BUG: [PATCH 2/8] drm/amdgpu: add a generic fb accessing helper function(v3)

2019-11-16 Thread Iago Abal
Hi,

With the help of a static bug finder (EBA - https://github.com/IagoAbal/eba)
I have found a potential double lock in Linux Next tag next-20191115, file
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c.

This bug seems to be introduced by commit
e35e2b117f4 ("drm/amdgpu: add a generic fb accessing helper function(v3)").

The steps to reproduce it would be:

1. Start in function `amdgpu_device_vram_access`.
2. Enter for-loop `for (last += pos; pos <= last; pos += 4)`.
3. First lock: `spin_lock_irqsave(&adev->mmio_idx_lock, flags)`.
4. Call to `WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)pos) | 0x8000)`.
   5. Note `#define WREG32_NO_KIQ(reg, v) amdgpu_mm_wreg(adev, (reg), (v),
AMDGPU_REGS_NO_KIQ)`.
   6. Continue in function `amdgpu_mm_wreg`.
   7. Take else-branch in the third if-statement.
   8. Double lock: `spin_lock_irqsave(&adev->mmio_idx_lock, flags)`.

I think the control flow could reach that second lock, but you may know
better.

Hope it helps!

-- iago
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 2/8] drm/amdgpu: add a generic fb accessing helper function(v3)

2019-10-13 Thread Tianci Yin
From: "Tianci.Yin" 

add a generic helper function for accessing framebuffer via MMIO

Change-Id: I4baa0aa53c93a94c2eff98c6211a61f369239982
Reviewed-by: Alex Deucher 
Signed-off-by: Tianci.Yin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h   |  2 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c| 30 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 12 +---
 3 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 7fa8e438f679..64a43b65a197 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -992,6 +992,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
 void amdgpu_device_fini(struct amdgpu_device *adev);
 int amdgpu_gpu_wait_for_idle(struct amdgpu_device *adev);
 
+void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
+  uint32_t *buf, size_t size, bool write);
 uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg,
uint32_t acc_flags);
 void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 598158e95ec1..13cc3aa52b8f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -154,6 +154,36 @@ bool amdgpu_device_is_px(struct drm_device *dev)
return false;
 }
 
+/**
+ * VRAM access helper functions.
+ *
+ * amdgpu_device_vram_access - read/write a buffer in vram
+ *
+ * @adev: amdgpu_device pointer
+ * @pos: offset of the buffer in vram
+ * @buf: virtual address of the buffer in system memory
+ * @size: read/write size, sizeof(@buf) must > @size
+ * @write: true - write to vram, otherwise - read from vram
+ */
+void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
+  uint32_t *buf, size_t size, bool write)
+{
+   uint64_t last;
+   unsigned long flags;
+
+   last = size - 4;
+   for (last += pos; pos <= last; pos += 4) {
+   spin_lock_irqsave(&adev->mmio_idx_lock, flags);
+   WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)pos) | 0x8000);
+   WREG32_NO_KIQ(mmMM_INDEX_HI, pos >> 31);
+   if (write)
+   WREG32_NO_KIQ(mmMM_DATA, *buf++);
+   else
+   *buf++ = RREG32_NO_KIQ(mmMM_DATA);
+   spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
+   }
+}
+
 /*
  * MMIO register access helper functions.
  */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index ddd8364102a2..f95092741c38 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -134,20 +134,10 @@ static int hw_id_map[MAX_HWIP] = {
 
 static int amdgpu_discovery_read_binary(struct amdgpu_device *adev, uint8_t 
*binary)
 {
-   uint32_t *p = (uint32_t *)binary;
uint64_t vram_size = (uint64_t)RREG32(mmRCC_CONFIG_MEMSIZE) << 20;
uint64_t pos = vram_size - DISCOVERY_TMR_SIZE;
-   unsigned long flags;
-
-   while (pos < vram_size) {
-   spin_lock_irqsave(&adev->mmio_idx_lock, flags);
-   WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)pos) | 0x8000);
-   WREG32_NO_KIQ(mmMM_INDEX_HI, pos >> 31);
-   *p++ = RREG32_NO_KIQ(mmMM_DATA);
-   spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
-   pos += 4;
-   }
 
+   amdgpu_device_vram_access(adev, pos, (uint32_t *)binary, 
DISCOVERY_TMR_SIZE, false);
return 0;
 }
 
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH 2/8] drm/amdgpu: add a generic fb accessing helper function

2019-10-11 Thread Tuikov, Luben
On 2019-10-10 11:50 p.m., Tianci Yin wrote:
> From: "Tianci.Yin" 
> 
> add a generic helper function for accessing framebuffer via MMIO
> 
> Change-Id: I4baa0aa53c93a94c2eff98c6211a61f369239982
> Reviewed-by: Alex Deucher 
> Signed-off-by: Tianci.Yin 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h   |  2 ++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c| 34 +++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 13 +--
>  3 files changed, 37 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 51ccf175cda0..1102e6bae5d5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -991,6 +991,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
>  void amdgpu_device_fini(struct amdgpu_device *adev);
>  int amdgpu_gpu_wait_for_idle(struct amdgpu_device *adev);
>  
> +int amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
> +   uint32_t *buf, size_t size, bool write);
>  uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg,
>   uint32_t acc_flags);
>  void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 598158e95ec1..fb21ec1f8a61 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -154,6 +154,40 @@ bool amdgpu_device_is_px(struct drm_device *dev)
>   return false;
>  }
>  
> +/**
> + * VRAM access helper functions.
> + *
> + * amdgpu_device_vram_access - read/write a buffer in vram
> + *
> + * @adev: amdgpu_device pointer
> + * @pos: offset of the buffer in vram
> + * @buf: virtual address of the buffer in system memory
> + * @size: read/write size, sizeof(@buf) must > @size
> + * @write: true - write to vram, otherwise - read from vram
> + *
> + * Returns 0 on success or an -error on failure.

Really? Where?
This function seems to return 0.
Traditionally read/write functions
return the number of bytes read/written or error.
You do neither. Just define it void.

> + */
> +int amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
> +   uint32_t *buf, size_t size, bool write)
> +{
> + uint64_t end = pos + size;

NAK! to preinitializing automatic variables.

> + unsigned long flags;
> +
> + while (pos < end) {
> + spin_lock_irqsave(&adev->mmio_idx_lock, flags);
> + WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)pos) | 0x8000);
> + WREG32_NO_KIQ(mmMM_INDEX_HI, pos >> 31);
> + if (write)
> + WREG32_NO_KIQ(mmMM_DATA, *buf++);
> + else
> + *buf++ = RREG32_NO_KIQ(mmMM_DATA);
> + spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
> + pos += 4;
> + }

NAK! to this this:

while (pos < end) { <---+
  |--> Part of the loop definition
pos += 4;   <---+
}

Instead of breaking up the loop definition like this,
use a for-loop, and DO NOT preinitialize the "end" variable,
and also protect from overflow, all like this:

last = size - 1;
for (last += pos; pos <= last; pos += 4) {

}

I mentioned the why of this in my previous review of the same
topic patchset over the same while loop fiasco.

Regards,
Luben

> +
> + return 0;
> +}
> +
>  /*
>   * MMIO register access helper functions.
>   */
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
> index db2dab3a6dff..324c2d605f54 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
> @@ -134,21 +134,10 @@ static int hw_id_map[MAX_HWIP] = {
>  
>  static int amdgpu_discovery_read_binary(struct amdgpu_device *adev, uint8_t 
> *binary)
>  {
> - uint32_t *p = (uint32_t *)binary;
>   uint64_t vram_size = (uint64_t)RREG32(mmRCC_CONFIG_MEMSIZE) << 20;
>   uint64_t pos = vram_size - BINARY_MAX_SIZE;
> - unsigned long flags;
> -
> - while (pos < vram_size) {
> - spin_lock_irqsave(&adev->mmio_idx_lock, flags);
> - WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)pos) | 0x8000);
> - WREG32_NO_KIQ(mmMM_INDEX_HI, pos >> 31);
> - *p++ = RREG32_NO_KIQ(mmMM_DATA);
> - spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
> - pos += 4;
> - }
>  
> - return 0;
> + return amdgpu_device_vram_access(adev, pos, (uint32_t *)binary, 
> BINARY_MAX_SIZE, false);
>  }
>  
>  static uint16_t amdgpu_discovery_calculate_checksum(uint8_t *data, uint32_t 
> size)
> 

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 2/8] drm/amdgpu: add a generic fb accessing helper function

2019-10-10 Thread Tianci Yin
From: "Tianci.Yin" 

add a generic helper function for accessing framebuffer via MMIO

Change-Id: I4baa0aa53c93a94c2eff98c6211a61f369239982
Reviewed-by: Alex Deucher 
Signed-off-by: Tianci.Yin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h   |  2 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c| 34 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 13 +--
 3 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 51ccf175cda0..1102e6bae5d5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -991,6 +991,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
 void amdgpu_device_fini(struct amdgpu_device *adev);
 int amdgpu_gpu_wait_for_idle(struct amdgpu_device *adev);
 
+int amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
+ uint32_t *buf, size_t size, bool write);
 uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg,
uint32_t acc_flags);
 void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 598158e95ec1..fb21ec1f8a61 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -154,6 +154,40 @@ bool amdgpu_device_is_px(struct drm_device *dev)
return false;
 }
 
+/**
+ * VRAM access helper functions.
+ *
+ * amdgpu_device_vram_access - read/write a buffer in vram
+ *
+ * @adev: amdgpu_device pointer
+ * @pos: offset of the buffer in vram
+ * @buf: virtual address of the buffer in system memory
+ * @size: read/write size, sizeof(@buf) must > @size
+ * @write: true - write to vram, otherwise - read from vram
+ *
+ * Returns 0 on success or an -error on failure.
+ */
+int amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
+ uint32_t *buf, size_t size, bool write)
+{
+   uint64_t end = pos + size;
+   unsigned long flags;
+
+   while (pos < end) {
+   spin_lock_irqsave(&adev->mmio_idx_lock, flags);
+   WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)pos) | 0x8000);
+   WREG32_NO_KIQ(mmMM_INDEX_HI, pos >> 31);
+   if (write)
+   WREG32_NO_KIQ(mmMM_DATA, *buf++);
+   else
+   *buf++ = RREG32_NO_KIQ(mmMM_DATA);
+   spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
+   pos += 4;
+   }
+
+   return 0;
+}
+
 /*
  * MMIO register access helper functions.
  */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index db2dab3a6dff..324c2d605f54 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -134,21 +134,10 @@ static int hw_id_map[MAX_HWIP] = {
 
 static int amdgpu_discovery_read_binary(struct amdgpu_device *adev, uint8_t 
*binary)
 {
-   uint32_t *p = (uint32_t *)binary;
uint64_t vram_size = (uint64_t)RREG32(mmRCC_CONFIG_MEMSIZE) << 20;
uint64_t pos = vram_size - BINARY_MAX_SIZE;
-   unsigned long flags;
-
-   while (pos < vram_size) {
-   spin_lock_irqsave(&adev->mmio_idx_lock, flags);
-   WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)pos) | 0x8000);
-   WREG32_NO_KIQ(mmMM_INDEX_HI, pos >> 31);
-   *p++ = RREG32_NO_KIQ(mmMM_DATA);
-   spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
-   pos += 4;
-   }
 
-   return 0;
+   return amdgpu_device_vram_access(adev, pos, (uint32_t *)binary, 
BINARY_MAX_SIZE, false);
 }
 
 static uint16_t amdgpu_discovery_calculate_checksum(uint8_t *data, uint32_t 
size)
-- 
2.17.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH 2/8] drm/amdgpu: add a generic fb accessing helper function

2019-10-09 Thread Yin, Tianci (Rico)
Ok,

Thanks for your reviewing!

Rico

From: Christian K?nig 
Sent: Wednesday, October 9, 2019 16:25
To: Alex Deucher ; amd-gfx@lists.freedesktop.org 

Cc: Deucher, Alexander ; Yin, Tianci (Rico) 

Subject: Re: [PATCH 2/8] drm/amdgpu: add a generic fb accessing helper function

Am 08.10.19 um 21:29 schrieb Alex Deucher:
> From: "Tianci.Yin" 
>
> add a generic helper function for accessing framebuffer via MMIO
>
> Change-Id: I4baa0aa53c93a94c2eff98c6211a61f369239982
> Reviewed-by: Alex Deucher 
> Signed-off-by: Tianci.Yin 
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu.h   |  2 +
>   drivers/gpu/drm/amd/amdgpu/amdgpu_device.c| 42 +++
>   drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 13 +-
>   3 files changed, 45 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 17ccb9015141..0d60c2e6c592 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -985,6 +985,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
>   void amdgpu_device_fini(struct amdgpu_device *adev);
>   int amdgpu_gpu_wait_for_idle(struct amdgpu_device *adev);
>
> +int amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
> +uint32_t *buf, size_t size, bool write);
>   uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg,
>uint32_t acc_flags);
>   void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index f25275abf408..53ce227f759c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -153,6 +153,48 @@ bool amdgpu_device_is_px(struct drm_device *dev)
>return false;
>   }
>
> +/**
> + * VRAM access helper functions.
> + *
> + * amdgpu_device_vram_access - read/write a buffer in vram
> + *
> + * @adev: amdgpu_device pointer
> + * @pos: offset of the buffer in vram
> + * @buf: virtual address of the buffer in system memory
> + * @size: read/write size, sizeof(@buf) must > @size
> + * @write: true - write to vram, otherwise - read from vram
> + *
> + * Returns 0 on success or an -error on failure.
> + */
> +int amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
> +uint32_t *buf, size_t size, bool write)

Indentation seems to be incorrect here.

> +{
> + uint64_t end = pos + size;
> + unsigned long flags;
> +
> + if (IS_ERR_OR_NULL(buf) ||
> + (adev->gmc.mc_vram_size > 0 &&
> +  end > adev->gmc.mc_vram_size)) {
> + DRM_ERROR("parameter error! pos:%llx, buf:%llx, size:%zx.\n",
> +   pos, (u64)buf, size);
> + return -EINVAL;
> + }

Please drop that, this is a purely internal functions and parameter
checking like this doesn't really make sense.

Regards,
Christian.

> +
> + while (pos < end) {
> + spin_lock_irqsave(&adev->mmio_idx_lock, flags);
> + WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)pos) | 0x8000);
> + WREG32_NO_KIQ(mmMM_INDEX_HI, pos >> 31);
> + if (write)
> + WREG32_NO_KIQ(mmMM_DATA, *buf++);
> + else
> + *buf++ = RREG32_NO_KIQ(mmMM_DATA);
> + spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
> + pos += 4;
> + }
> +
> + return 0;
> +}
> +
>   /*
>* MMIO register access helper functions.
>*/
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
> index db2dab3a6dff..324c2d605f54 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
> @@ -134,21 +134,10 @@ static int hw_id_map[MAX_HWIP] = {
>
>   static int amdgpu_discovery_read_binary(struct amdgpu_device *adev, uint8_t 
> *binary)
>   {
> - uint32_t *p = (uint32_t *)binary;
>uint64_t vram_size = (uint64_t)RREG32(mmRCC_CONFIG_MEMSIZE) << 20;
>uint64_t pos = vram_size - BINARY_MAX_SIZE;
> - unsigned long flags;
> -
> - while (pos < vram_size) {
> - spin_lock_irqsave(&adev->mmio_idx_lock, flags);
> - WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)pos) | 0x8000);
> - WREG32_NO_KIQ(mmMM_INDEX_HI, pos >> 31);
> - *p++ = RREG32_NO_KIQ(mmMM_DATA);
> - spin_unlock_irqrestore(&adev->mmio_idx_lock, flags

Re: [PATCH 2/8] drm/amdgpu: add a generic fb accessing helper function

2019-10-09 Thread Christian König

Am 08.10.19 um 21:29 schrieb Alex Deucher:

From: "Tianci.Yin" 

add a generic helper function for accessing framebuffer via MMIO

Change-Id: I4baa0aa53c93a94c2eff98c6211a61f369239982
Reviewed-by: Alex Deucher 
Signed-off-by: Tianci.Yin 
---
  drivers/gpu/drm/amd/amdgpu/amdgpu.h   |  2 +
  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c| 42 +++
  drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 13 +-
  3 files changed, 45 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 17ccb9015141..0d60c2e6c592 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -985,6 +985,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
  void amdgpu_device_fini(struct amdgpu_device *adev);
  int amdgpu_gpu_wait_for_idle(struct amdgpu_device *adev);
  
+int amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,

+  uint32_t *buf, size_t size, bool write);
  uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg,
uint32_t acc_flags);
  void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index f25275abf408..53ce227f759c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -153,6 +153,48 @@ bool amdgpu_device_is_px(struct drm_device *dev)
return false;
  }
  
+/**

+ * VRAM access helper functions.
+ *
+ * amdgpu_device_vram_access - read/write a buffer in vram
+ *
+ * @adev: amdgpu_device pointer
+ * @pos: offset of the buffer in vram
+ * @buf: virtual address of the buffer in system memory
+ * @size: read/write size, sizeof(@buf) must > @size
+ * @write: true - write to vram, otherwise - read from vram
+ *
+ * Returns 0 on success or an -error on failure.
+ */
+int amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
+  uint32_t *buf, size_t size, bool write)


Indentation seems to be incorrect here.


+{
+   uint64_t end = pos + size;
+   unsigned long flags;
+
+   if (IS_ERR_OR_NULL(buf) ||
+   (adev->gmc.mc_vram_size > 0 &&
+end > adev->gmc.mc_vram_size)) {
+   DRM_ERROR("parameter error! pos:%llx, buf:%llx, size:%zx.\n",
+ pos, (u64)buf, size);
+   return -EINVAL;
+   }


Please drop that, this is a purely internal functions and parameter 
checking like this doesn't really make sense.


Regards,
Christian.


+
+   while (pos < end) {
+   spin_lock_irqsave(&adev->mmio_idx_lock, flags);
+   WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)pos) | 0x8000);
+   WREG32_NO_KIQ(mmMM_INDEX_HI, pos >> 31);
+   if (write)
+   WREG32_NO_KIQ(mmMM_DATA, *buf++);
+   else
+   *buf++ = RREG32_NO_KIQ(mmMM_DATA);
+   spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
+   pos += 4;
+   }
+
+   return 0;
+}
+
  /*
   * MMIO register access helper functions.
   */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index db2dab3a6dff..324c2d605f54 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -134,21 +134,10 @@ static int hw_id_map[MAX_HWIP] = {
  
  static int amdgpu_discovery_read_binary(struct amdgpu_device *adev, uint8_t *binary)

  {
-   uint32_t *p = (uint32_t *)binary;
uint64_t vram_size = (uint64_t)RREG32(mmRCC_CONFIG_MEMSIZE) << 20;
uint64_t pos = vram_size - BINARY_MAX_SIZE;
-   unsigned long flags;
-
-   while (pos < vram_size) {
-   spin_lock_irqsave(&adev->mmio_idx_lock, flags);
-   WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)pos) | 0x8000);
-   WREG32_NO_KIQ(mmMM_INDEX_HI, pos >> 31);
-   *p++ = RREG32_NO_KIQ(mmMM_DATA);
-   spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
-   pos += 4;
-   }
  
-	return 0;

+   return amdgpu_device_vram_access(adev, pos, (uint32_t *)binary, 
BINARY_MAX_SIZE, false);
  }
  
  static uint16_t amdgpu_discovery_calculate_checksum(uint8_t *data, uint32_t size)


___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 2/8] drm/amdgpu: add a generic fb accessing helper function

2019-10-08 Thread Alex Deucher
From: "Tianci.Yin" 

add a generic helper function for accessing framebuffer via MMIO

Change-Id: I4baa0aa53c93a94c2eff98c6211a61f369239982
Reviewed-by: Alex Deucher 
Signed-off-by: Tianci.Yin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h   |  2 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c| 42 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 13 +-
 3 files changed, 45 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 17ccb9015141..0d60c2e6c592 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -985,6 +985,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
 void amdgpu_device_fini(struct amdgpu_device *adev);
 int amdgpu_gpu_wait_for_idle(struct amdgpu_device *adev);
 
+int amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
+  uint32_t *buf, size_t size, bool write);
 uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg,
uint32_t acc_flags);
 void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index f25275abf408..53ce227f759c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -153,6 +153,48 @@ bool amdgpu_device_is_px(struct drm_device *dev)
return false;
 }
 
+/**
+ * VRAM access helper functions.
+ *
+ * amdgpu_device_vram_access - read/write a buffer in vram
+ *
+ * @adev: amdgpu_device pointer
+ * @pos: offset of the buffer in vram
+ * @buf: virtual address of the buffer in system memory
+ * @size: read/write size, sizeof(@buf) must > @size
+ * @write: true - write to vram, otherwise - read from vram
+ *
+ * Returns 0 on success or an -error on failure.
+ */
+int amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
+  uint32_t *buf, size_t size, bool write)
+{
+   uint64_t end = pos + size;
+   unsigned long flags;
+
+   if (IS_ERR_OR_NULL(buf) ||
+   (adev->gmc.mc_vram_size > 0 &&
+end > adev->gmc.mc_vram_size)) {
+   DRM_ERROR("parameter error! pos:%llx, buf:%llx, size:%zx.\n",
+ pos, (u64)buf, size);
+   return -EINVAL;
+   }
+
+   while (pos < end) {
+   spin_lock_irqsave(&adev->mmio_idx_lock, flags);
+   WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)pos) | 0x8000);
+   WREG32_NO_KIQ(mmMM_INDEX_HI, pos >> 31);
+   if (write)
+   WREG32_NO_KIQ(mmMM_DATA, *buf++);
+   else
+   *buf++ = RREG32_NO_KIQ(mmMM_DATA);
+   spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
+   pos += 4;
+   }
+
+   return 0;
+}
+
 /*
  * MMIO register access helper functions.
  */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index db2dab3a6dff..324c2d605f54 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -134,21 +134,10 @@ static int hw_id_map[MAX_HWIP] = {
 
 static int amdgpu_discovery_read_binary(struct amdgpu_device *adev, uint8_t 
*binary)
 {
-   uint32_t *p = (uint32_t *)binary;
uint64_t vram_size = (uint64_t)RREG32(mmRCC_CONFIG_MEMSIZE) << 20;
uint64_t pos = vram_size - BINARY_MAX_SIZE;
-   unsigned long flags;
-
-   while (pos < vram_size) {
-   spin_lock_irqsave(&adev->mmio_idx_lock, flags);
-   WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)pos) | 0x8000);
-   WREG32_NO_KIQ(mmMM_INDEX_HI, pos >> 31);
-   *p++ = RREG32_NO_KIQ(mmMM_DATA);
-   spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
-   pos += 4;
-   }
 
-   return 0;
+   return amdgpu_device_vram_access(adev, pos, (uint32_t *)binary, 
BINARY_MAX_SIZE, false);
 }
 
 static uint16_t amdgpu_discovery_calculate_checksum(uint8_t *data, uint32_t 
size)
-- 
2.20.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx