[PATCH 04/12] drm/nouveau/bar/nvc0: support chips without BAR3

2014-04-02 Thread Alexandre Courbot
On Tue, Mar 25, 2014 at 7:10 AM, Thierry Reding
 wrote:
> On Mon, Mar 24, 2014 at 05:42:26PM +0900, Alexandre Courbot wrote:
> [...]
>> diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c 
>> b/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
> [...]
>>  static int
>> -nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
>> -   struct nouveau_oclass *oclass, void *data, u32 size,
>> -   struct nouveau_object **pobject)
>> +nvc0_bar_init_vm(struct nvc0_bar_priv *priv, int nr, int bar)
>>  {
> [...]
>> - /* BAR3 */
>>   ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0, 0,
>> - >bar[0].mem);
>> - mem = priv->bar[0].mem;
>> + >bar[nr].mem);
>> + mem = priv->bar[nr].mem;
>>   if (ret)
>>   return ret;
>>
>>   ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0, 0,
>> - >bar[0].pgd);
>> + >bar[nr].pgd);
>>   if (ret)
>>   return ret;
> [...]
>> +static int
>> +nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
>> +   struct nouveau_oclass *oclass, void *data, u32 size,
>> +   struct nouveau_object **pobject)
>> +{
> [...]
>> + /* BAR3 */
>> + if (has_bar3) {
>> + ret = nvc0_bar_init_vm(priv, 0, 3);
> [...]
>> + /* BAR1 */
>> + ret = nvc0_bar_init_vm(priv, 1, 1);
>>   if (ret)
>>   return ret;
>
> The calls to nvc0_bar_init_vm() are somewhat confusing in my opinion. It
> is hard to see from the invocation what these numbers mean and therefore
> distinguish which parameter is which.
>
> Perhaps a slightly more readable way would be to pass in a pointer to a
> structure as second parameter instead of the index into an array. So
> it'd look somewhat like this:
>
> if (has_bar3) {
> ret = nvc0_bar_init_vm(priv, >bar[0], 3);
> ...
> }
> ...
> ret = nvc0_bar_init_vm(priv, >bar[1], 1);
> ...
>
> Unfortunately that would require a new type to be created for the bar[]
> structures, so it'd be slightly more intrusive.

These types are local to nvc0.c anyway, so I don't think it would
hurt. And you are right that the code would become more readable as a
result, passing array indexes as arguments is not a common practice
(and should not be).

Alex.


[PATCH 04/12] drm/nouveau/bar/nvc0: support chips without BAR3

2014-03-25 Thread Thierry Reding
On Mon, Mar 24, 2014 at 05:42:26PM +0900, Alexandre Courbot wrote:
[...]
> diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c 
> b/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
[...]
>  static int
> -nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
> -   struct nouveau_oclass *oclass, void *data, u32 size,
> -   struct nouveau_object **pobject)
> +nvc0_bar_init_vm(struct nvc0_bar_priv *priv, int nr, int bar)
>  {
[...]
> - /* BAR3 */
>   ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0, 0,
> - >bar[0].mem);
> - mem = priv->bar[0].mem;
> + >bar[nr].mem);
> + mem = priv->bar[nr].mem;
>   if (ret)
>   return ret;
>  
>   ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0, 0,
> - >bar[0].pgd);
> + >bar[nr].pgd);
>   if (ret)
>   return ret;
[...]
> +static int
> +nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
> +   struct nouveau_oclass *oclass, void *data, u32 size,
> +   struct nouveau_object **pobject)
> +{
[...]
> + /* BAR3 */
> + if (has_bar3) {
> + ret = nvc0_bar_init_vm(priv, 0, 3);
[...]
> + /* BAR1 */
> + ret = nvc0_bar_init_vm(priv, 1, 1);
>   if (ret)
>   return ret;

The calls to nvc0_bar_init_vm() are somewhat confusing in my opinion. It
is hard to see from the invocation what these numbers mean and therefore
distinguish which parameter is which.

Perhaps a slightly more readable way would be to pass in a pointer to a
structure as second parameter instead of the index into an array. So
it'd look somewhat like this:

if (has_bar3) {
ret = nvc0_bar_init_vm(priv, >bar[0], 3);
...
}
...
ret = nvc0_bar_init_vm(priv, >bar[1], 1);
...

Unfortunately that would require a new type to be created for the bar[]
structures, so it'd be slightly more intrusive.

Thierry
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: 



[PATCH 04/12] drm/nouveau/bar/nvc0: support chips without BAR3

2014-03-24 Thread Alexandre Courbot
Adapt the NVC0 BAR driver to make it able to support chips that do not
expose a BAR3. When this happens, BAR1 is then used for USERD mapping
and the BAR alloc() functions is disabled, making GPU objects unable
to rely on BAR for data access and falling back to PRAMIN.

Signed-off-by: Alexandre Courbot 
---
 drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c | 101 +
 1 file changed, 52 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c 
b/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
index 3f30db62e656..5da1b9447af0 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
@@ -79,87 +79,88 @@ nvc0_bar_unmap(struct nouveau_bar *bar, struct nouveau_vma 
*vma)
 }

 static int
-nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nvc0_bar_init_vm(struct nvc0_bar_priv *priv, int nr, int bar)
 {
-   struct nouveau_device *device = nv_device(parent);
-   struct nvc0_bar_priv *priv;
+   struct nouveau_device *device = nv_device(>base);
struct nouveau_gpuobj *mem;
struct nouveau_vm *vm;
+   resource_size_t bar_len;
int ret;

-   ret = nouveau_bar_create(parent, engine, oclass, );
-   *pobject = nv_object(priv);
-   if (ret)
-   return ret;
-
-   /* BAR3 */
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0, 0,
-   >bar[0].mem);
-   mem = priv->bar[0].mem;
+   >bar[nr].mem);
+   mem = priv->bar[nr].mem;
if (ret)
return ret;

ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0, 0,
-   >bar[0].pgd);
+   >bar[nr].pgd);
if (ret)
return ret;

-   ret = nouveau_vm_new(device, 0, nv_device_resource_len(device, 3), 0, 
);
+   bar_len = nv_device_resource_len(device, bar);
+
+   ret = nouveau_vm_new(device, 0, bar_len, 0, );
if (ret)
return ret;

atomic_inc(>engref[NVDEV_SUBDEV_BAR]);

-   ret = nouveau_gpuobj_new(nv_object(priv), NULL,
-(nv_device_resource_len(device, 3) >> 12) * 8,
-0x1000, NVOBJ_FLAG_ZERO_ALLOC,
->pgt[0].obj[0]);
-   vm->pgt[0].refcount[0] = 1;
-   if (ret)
-   return ret;
+   /*
+* Bootstrap page table lookup.
+*/
+   if (bar == 3) {
+   ret = nouveau_gpuobj_new(nv_object(priv), NULL,
+(bar_len >> 12) * 8, 0x1000,
+NVOBJ_FLAG_ZERO_ALLOC,
+   >pgt[0].obj[0]);
+   vm->pgt[0].refcount[0] = 1;
+   if (ret)
+   return ret;
+   }

-   ret = nouveau_vm_ref(vm, >bar[0].vm, priv->bar[0].pgd);
+   ret = nouveau_vm_ref(vm, >bar[nr].vm, priv->bar[nr].pgd);
nouveau_vm_ref(NULL, , NULL);
if (ret)
return ret;

-   nv_wo32(mem, 0x0200, lower_32_bits(priv->bar[0].pgd->addr));
-   nv_wo32(mem, 0x0204, upper_32_bits(priv->bar[0].pgd->addr));
-   nv_wo32(mem, 0x0208, lower_32_bits(nv_device_resource_len(device, 3) - 
1));
-   nv_wo32(mem, 0x020c, upper_32_bits(nv_device_resource_len(device, 3) - 
1));
+   nv_wo32(mem, 0x0200, lower_32_bits(priv->bar[nr].pgd->addr));
+   nv_wo32(mem, 0x0204, upper_32_bits(priv->bar[nr].pgd->addr));
+   nv_wo32(mem, 0x0208, lower_32_bits(bar_len - 1));
+   nv_wo32(mem, 0x020c, upper_32_bits(bar_len - 1));

-   /* BAR1 */
-   ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0, 0,
-   >bar[1].mem);
-   mem = priv->bar[1].mem;
-   if (ret)
-   return ret;
+   return 0;
+}

-   ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0, 0,
-   >bar[1].pgd);
-   if (ret)
-   return ret;
+static int
+nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+   struct nouveau_device *device = nv_device(parent);
+   struct nvc0_bar_priv *priv;
+   bool has_bar3 = nv_device_resource_len(device, 3) != 0;
+   int ret;

-   ret = nouveau_vm_new(device, 0, nv_device_resource_len(device, 1), 0, 
);
+   ret = nouveau_bar_create(parent, engine, oclass, );
+   *pobject = nv_object(priv);
if (ret)
return ret;

-   atomic_inc(>engref[NVDEV_SUBDEV_BAR]);
+   /* BAR3 */
+   if (has_bar3) {
+   ret = nvc0_bar_init_vm(priv, 0, 3);
+   if (ret)
+