Re: linux-next: manual merge of the drm-msm tree with the mm, drm trees

2023-10-10 Thread Uwe Kleine-König
Hello Stephen,

On Tue, Oct 10, 2023 at 12:33:45PM +1100, Stephen Rothwell wrote:
> Today's linux-next merge of the drm-msm tree got conflicts in:
> 
>   drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
>   drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
>   drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
>   drivers/gpu/drm/msm/msm_drv.c
> 
> between commits:
> 
>   01790d5e372f ("drm/msm: Convert to platform remove callback returning void")
>   cd61a76c210a ("drm/msm: dynamically allocate the drm-msm_gem shrinker")
> 
> from the mm, drm trees and commits:
> 
>   283add3e6405 ("drm/msm: remove shutdown callback from msm_platform_driver")
>   506efcba3129 ("drm/msm: carve out KMS code from msm_drv.c")
> 
> from the drm-msm tree.
> 
> I fixed it up (see below) and can carry the fix as necessary. This
> is now fixed as far as linux-next is concerned, but any non trivial
> conflicts should be mentioned to your upstream maintainer when your tree
> is submitted for merging.  You may also want to consider cooperating
> with the maintainer of the conflicting tree to minimise any particularly
> complex conflicts.

FTR: The conflict resolution looks right to me. Thanks!

Best regards
Uwe

-- 
Pengutronix e.K.   | Uwe Kleine-König|
Industrial Linux Solutions | https://www.pengutronix.de/ |


signature.asc
Description: PGP signature


[PATCH v1 2/2] hwmon: (pmbus/max31785) Add minimum delay between bus accesses

2023-10-10 Thread Lakshmi Yadlapati
The MAX31785 has shown erratic behaviour across multiple system
designs, unexpectedly clock stretching and NAKing transactions.
Inserting a small delay (250us) after register writes makes the
issue go away.

Signed-off-by: Lakshmi Yadlapati 
---
 drivers/hwmon/pmbus/max31785.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/hwmon/pmbus/max31785.c b/drivers/hwmon/pmbus/max31785.c
index f9aa576495a5..532e1c8f632c 100644
--- a/drivers/hwmon/pmbus/max31785.c
+++ b/drivers/hwmon/pmbus/max31785.c
@@ -5,6 +5,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -24,6 +25,9 @@ enum max31785_regs {
 #define MAX31785_NR_PAGES  23
 #define MAX31785_NR_FAN_PAGES  6
 
+static unsigned long throttle_delay_us = 250;
+module_param(throttle_delay_us, ulong, 0664);
+
 static int max31785_read_byte_data(struct i2c_client *client, int page,
   int reg)
 {
@@ -337,6 +341,10 @@ static int max31785_probe(struct i2c_client *client)
 I2C_FUNC_SMBUS_WORD_DATA))
return -ENODEV;
 
+   ret = i2c_smbus_throttle_client(client, throttle_delay_us);
+   if (ret)
+   return ret;
+
info = devm_kzalloc(dev, sizeof(struct pmbus_driver_info), GFP_KERNEL);
if (!info)
return -ENOMEM;
-- 
2.39.2



[PATCH v1 0/2] [PATCH] hwmon: (pmbus/max31785) Add minimum delay between bus accesses

2023-10-10 Thread Lakshmi Yadlapati
Reintroduce per-client throttling of transfers for improved compatibility.

Some devices have experienced issues with small command turn-around times when 
using in-kernel device drivers. While a previous proposal was rejected due to 
concerns about error-prone open-coding of delays, recent upstream changes for 
similar problems in I2C devices (e.g., max15301 and ucd90320) and now max31785 
make it sensible to reintroduce Andrew's generic solution. This change aims to 
improve compatibility for affected devices and may help avoid duplicating 
implementations of handlers for I2C and PMBus calls in driver code.

Reference to Andrew's previous proposal:
https://lore.kernel.org/all/20200914122811.3295678-1-and...@aj.id.au/

Lakshmi Yadlapati (2):
  i2c: smbus: Allow throttling of transfers to client devices
  hwmon: (pmbus/max31785) Add minimum delay between bus accesses

 drivers/hwmon/pmbus/max31785.c |   8 ++
 drivers/i2c/i2c-core-base.c|   8 +-
 drivers/i2c/i2c-core-smbus.c   | 143 ++---
 drivers/i2c/i2c-core.h |  23 ++
 include/linux/i2c.h|   2 +
 5 files changed, 153 insertions(+), 31 deletions(-)

-- 
2.39.2



[PATCH] drm/amd/pm: Fix a memory leak on an error path

2023-10-10 Thread Kunwu.Chan
Add missing free on an error path.

Fixes: 511a95552ec8 ("drm/amd/pm: Add SMU 13.0.6 support")
Signed-off-by: Kunwu.Chan 
---
 drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
index ce971a93d28b..c26e12ff532c 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
@@ -1981,8 +1981,10 @@ static ssize_t smu_v13_0_6_get_gpu_metrics(struct 
smu_context *smu, void **table
 
metrics = kzalloc(sizeof(MetricsTable_t), GFP_KERNEL);
ret = smu_v13_0_6_get_metrics_table(smu, metrics, true);
-   if (ret)
+   if (ret) {
+   kfree(metrics);
return ret;
+   }
 
smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 3);
 
-- 
2.25.1



Re: [PATCH v1 0/2] [PATCH] hwmon: (pmbus/max31785) Add minimum delay between bus accesses

2023-10-10 Thread Lakshmi Yadlapati
Correct Link to Andrew's previous proposal:
https://lore.kernel.org/all/20200914122811.3295678-1-and...@aj.id.au/


On 10/9/23, 4:21 PM, "Lakshmi Yadlapati" mailto:laksh...@us.ibm.com>> wrote:


Reintroduce per-client throttling of transfers for improved compatibility.


Some devices have experienced issues with small command turn-around times when 
using in-kernel device drivers. While a previous proposal was rejected due to 
concerns about error-prone open-coding of delays, recent upstream changes for 
similar problems in I2C devices (e.g., max15301 and ucd90320) and now max31785 
make it sensible to reintroduce Andrew's generic solution. This change aims to 
improve compatibility for affected devices and may help avoid duplicating 
implementations of handlers for I2C and PMBus calls in driver code.


Reference to Andrew's previous proposal:
https://lore.kernel.org/all/20200914122811.3295678-1-and...@aj.id.au 
/


Lakshmi Yadlapati (2):
i2c: smbus: Allow throttling of transfers to client devices
hwmon: (pmbus/max31785) Add minimum delay between bus accesses


drivers/hwmon/pmbus/max31785.c | 8 ++
drivers/i2c/i2c-core-base.c | 8 +-
drivers/i2c/i2c-core-smbus.c | 143 ++---
drivers/i2c/i2c-core.h | 23 ++
include/linux/i2c.h | 2 +
5 files changed, 153 insertions(+), 31 deletions(-)


-- 
2.39.2







[PATCH v1 1/2] i2c: smbus: Allow throttling of transfers to client devices

2023-10-10 Thread Lakshmi Yadlapati
Signed-off-by: Lakshmi Yadlapati 
---
 drivers/i2c/i2c-core-base.c  |   8 +-
 drivers/i2c/i2c-core-smbus.c | 143 ---
 drivers/i2c/i2c-core.h   |  23 ++
 include/linux/i2c.h  |   2 +
 4 files changed, 145 insertions(+), 31 deletions(-)

diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index 60746652fd52..c27cb054d462 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -931,13 +931,17 @@ int i2c_dev_irq_from_resources(const struct resource 
*resources,
 struct i2c_client *
 i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const 
*info)
 {
+   struct i2c_client_priv  *priv;
struct i2c_client   *client;
int status;
 
-   client = kzalloc(sizeof *client, GFP_KERNEL);
-   if (!client)
+   priv = kzalloc(sizeof *priv, GFP_KERNEL);
+   if (!priv)
return ERR_PTR(-ENOMEM);
 
+   mutex_init(&priv->throttle_lock);
+   client = &priv->client;
+
client->adapter = adap;
 
client->dev.platform_data = info->platform_data;
diff --git a/drivers/i2c/i2c-core-smbus.c b/drivers/i2c/i2c-core-smbus.c
index e3b96fc53b5c..bcf1b15d6bd2 100644
--- a/drivers/i2c/i2c-core-smbus.c
+++ b/drivers/i2c/i2c-core-smbus.c
@@ -10,6 +10,7 @@
  * SMBus 2.0 support by Mark Studebaker  and
  * Jean Delvare 
  */
+#include 
 #include 
 #include 
 #include 
@@ -22,6 +23,9 @@
 #define CREATE_TRACE_POINTS
 #include 
 
+static s32 i2c_smbus_throttle_xfer(const struct i2c_client *client,
+  char read_write, u8 command, int protocol,
+  union i2c_smbus_data *data);
 
 /* The SMBus parts */
 
@@ -104,9 +108,8 @@ s32 i2c_smbus_read_byte(const struct i2c_client *client)
union i2c_smbus_data data;
int status;
 
-   status = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
-   I2C_SMBUS_READ, 0,
-   I2C_SMBUS_BYTE, &data);
+   status = i2c_smbus_throttle_xfer(client, I2C_SMBUS_READ, 0,
+I2C_SMBUS_BYTE, &data);
return (status < 0) ? status : data.byte;
 }
 EXPORT_SYMBOL(i2c_smbus_read_byte);
@@ -121,8 +124,8 @@ EXPORT_SYMBOL(i2c_smbus_read_byte);
  */
 s32 i2c_smbus_write_byte(const struct i2c_client *client, u8 value)
 {
-   return i2c_smbus_xfer(client->adapter, client->addr, client->flags,
- I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL);
+   return i2c_smbus_throttle_xfer(client, I2C_SMBUS_WRITE, value,
+  I2C_SMBUS_BYTE, NULL);
 }
 EXPORT_SYMBOL(i2c_smbus_write_byte);
 
@@ -139,9 +142,8 @@ s32 i2c_smbus_read_byte_data(const struct i2c_client 
*client, u8 command)
union i2c_smbus_data data;
int status;
 
-   status = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
-   I2C_SMBUS_READ, command,
-   I2C_SMBUS_BYTE_DATA, &data);
+   status = i2c_smbus_throttle_xfer(client, I2C_SMBUS_READ, command,
+I2C_SMBUS_BYTE_DATA, &data);
return (status < 0) ? status : data.byte;
 }
 EXPORT_SYMBOL(i2c_smbus_read_byte_data);
@@ -160,9 +162,8 @@ s32 i2c_smbus_write_byte_data(const struct i2c_client 
*client, u8 command,
 {
union i2c_smbus_data data;
data.byte = value;
-   return i2c_smbus_xfer(client->adapter, client->addr, client->flags,
- I2C_SMBUS_WRITE, command,
- I2C_SMBUS_BYTE_DATA, &data);
+   return i2c_smbus_throttle_xfer(client, I2C_SMBUS_WRITE, command,
+  I2C_SMBUS_BYTE_DATA, &data);
 }
 EXPORT_SYMBOL(i2c_smbus_write_byte_data);
 
@@ -179,9 +180,8 @@ s32 i2c_smbus_read_word_data(const struct i2c_client 
*client, u8 command)
union i2c_smbus_data data;
int status;
 
-   status = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
-   I2C_SMBUS_READ, command,
-   I2C_SMBUS_WORD_DATA, &data);
+   status = i2c_smbus_throttle_xfer(client, I2C_SMBUS_READ, command,
+I2C_SMBUS_WORD_DATA, &data);
return (status < 0) ? status : data.word;
 }
 EXPORT_SYMBOL(i2c_smbus_read_word_data);
@@ -200,9 +200,8 @@ s32 i2c_smbus_write_word_data(const struct i2c_client 
*client, u8 command,
 {
union i2c_smbus_data data;
data.word = value;
-   return i2c_smbus_xfer(client->adapter, client->addr, client->flags,
- I2C_SMBUS_WRITE, command,
- I2C_SMBUS_WORD_DATA, &data);
+   return i2c_smbus_throttle_xfer(client, I2C_SMBUS_WRITE, command,
+  I2C_SMBUS_WORD_DATA, &data);
 }
 EXPORT_SYMBOL(i2c_smbus_write_word_

[PATCH] drm/amd/pm: Fix a memory leak on an error path

2023-10-10 Thread Kunwu.Chan
Add missing free on an error path.

Signed-off-by: Kunwu.Chan 
---
 drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
index ce971a93d28b..c26e12ff532c 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
@@ -1981,8 +1981,10 @@ static ssize_t smu_v13_0_6_get_gpu_metrics(struct 
smu_context *smu, void **table
 
metrics = kzalloc(sizeof(MetricsTable_t), GFP_KERNEL);
ret = smu_v13_0_6_get_metrics_table(smu, metrics, true);
-   if (ret)
+   if (ret) {
+   kfree(metrics);
return ret;
+   }
 
smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 3);
 
-- 
2.25.1



Re: [PATCH drm-misc-next v2] drm/sched: implement dynamic job-flow control

2023-10-10 Thread Boris Brezillon
On Tue, 10 Oct 2023 00:35:53 +0200
Danilo Krummrich  wrote:

> Currently, job flow control is implemented simply by limiting the number
> of jobs in flight. Therefore, a scheduler is initialized with a
> submission limit that corresponds to the number of jobs which can be
> sent to the hardware.
> 
> This implies that for each job, drivers need to account for the maximum
> job size possible in order to not overflow the ring buffer.
> 
> However, there are drivers, such as Nouveau, where the job size has a
> rather large range. For such drivers it can easily happen that job
> submissions not even filling the ring by 1% can block subsequent
> submissions, which, in the worst case, can lead to the ring run dry.
> 
> In order to overcome this issue, allow for tracking the actual job size
> instead of the number of jobs. Therefore, add a field to track a job's
> submission credits, which represents the number of credits a job
> contributes to the scheduler's submission limit.
> 
> Signed-off-by: Danilo Krummrich 
> ---
> Changes in V2:
> ==
>   - fixed up influence on scheduling fairness due to consideration of a job's
> size
> - If we reach a ready entity in drm_sched_select_entity() but can't 
> actually
>   queue a job from it due to size limitations, just give up and go to 
> sleep
>   until woken up due to a pending job finishing, rather than continue to 
> try
>   other entities.
>   - added a callback to dynamically update a job's credits (Boris)
>   - renamed 'units' to 'credits'
>   - fixed commit message and comments as requested by Luben
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_job.c   |   2 +-
>  drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c  |   2 +-
>  drivers/gpu/drm/lima/lima_sched.c |   2 +-
>  drivers/gpu/drm/msm/msm_gem_submit.c  |   2 +-
>  drivers/gpu/drm/nouveau/nouveau_sched.c   |   2 +-
>  drivers/gpu/drm/panfrost/panfrost_drv.c   |   2 +-
>  .../gpu/drm/scheduler/gpu_scheduler_trace.h   |   2 +-
>  drivers/gpu/drm/scheduler/sched_entity.c  |   5 +-
>  drivers/gpu/drm/scheduler/sched_main.c| 101 +-
>  drivers/gpu/drm/v3d/v3d_gem.c |   2 +-
>  include/drm/gpu_scheduler.h   |  33 --
>  11 files changed, 115 insertions(+), 40 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
> index 78476bc75b4e..d54daaf64bf1 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
> @@ -115,7 +115,7 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, struct 
> amdgpu_vm *vm,
>   if (!entity)
>   return 0;
>  
> - return drm_sched_job_init(&(*job)->base, entity, owner);
> + return drm_sched_job_init(&(*job)->base, entity, 1, owner);
>  }
>  
>  int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev,
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c 
> b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
> index 45403ea38906..74a446711207 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
> @@ -538,7 +538,7 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void 
> *data,
>  
>   ret = drm_sched_job_init(&submit->sched_job,
>&ctx->sched_entity[args->pipe],
> -  submit->ctx);
> +  1, submit->ctx);
>   if (ret)
>   goto err_submit_put;
>  
> diff --git a/drivers/gpu/drm/lima/lima_sched.c 
> b/drivers/gpu/drm/lima/lima_sched.c
> index 50c2075228aa..5dc6678e1eb9 100644
> --- a/drivers/gpu/drm/lima/lima_sched.c
> +++ b/drivers/gpu/drm/lima/lima_sched.c
> @@ -123,7 +123,7 @@ int lima_sched_task_init(struct lima_sched_task *task,
>   for (i = 0; i < num_bos; i++)
>   drm_gem_object_get(&bos[i]->base.base);
>  
> - err = drm_sched_job_init(&task->base, &context->base, vm);
> + err = drm_sched_job_init(&task->base, &context->base, 1, vm);
>   if (err) {
>   kfree(task->bos);
>   return err;
> diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c 
> b/drivers/gpu/drm/msm/msm_gem_submit.c
> index 3f1aa4de3b87..6d230c38e4f5 100644
> --- a/drivers/gpu/drm/msm/msm_gem_submit.c
> +++ b/drivers/gpu/drm/msm/msm_gem_submit.c
> @@ -48,7 +48,7 @@ static struct msm_gem_submit *submit_create(struct 
> drm_device *dev,
>   return ERR_PTR(ret);
>   }
>  
> - ret = drm_sched_job_init(&submit->base, queue->entity, queue);
> + ret = drm_sched_job_init(&submit->base, queue->entity, 1, queue);
>   if (ret) {
>   kfree(submit->hw_fence);
>   kfree(submit);
> diff --git a/drivers/gpu/drm/nouveau/nouveau_sched.c 
> b/drivers/gpu/drm/nouveau/nouveau_sched.c
> index f26a814a9920..e991426d86e4 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_sched.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_sched.c
> @@ -89,7 +8

Re: [PATCH 3/9] drm/ci: add helper script update-xfails.py

2023-10-10 Thread Vignesh Raman

Hi Helen,

On 09/10/23 06:19, Helen Koike wrote:

Add helper script that given a gitlab pipeline url, analyse which are
the failures and flakes and update the xfails folder accordingly.

Example:
Trigger a pipeline in gitlab infrastructure, than re-try a few jobs more
than once (so we can have data if failues are consistent across jobs
with the same name or if they are flakes) and execute:

update-xfails.py 
https://gitlab.freedesktop.org/helen.fornazier/linux/-/pipelines/970661

git diff should show you that it updated files in xfails folder.

Signed-off-by: Helen Koike 

---

Hello,

This script is being very handy for me, so I suppose it could be handy
to others, since I'm publishing it in the xfails folder.

Let me know your thoughts.


Thanks for the script.

Tested-by: Vignesh Raman 

Regards,
Vignesh


Re: [PATCH v4 2/4] drm/panic: Add a drm panic handler

2023-10-10 Thread Jocelyn Falempe

On 09/10/2023 18:07, Maxime Ripard wrote:

On Mon, Oct 09, 2023 at 04:05:19PM +0200, Jocelyn Falempe wrote:

- I find it risky to completely reconfigure the hardware in a panic handler.


I would expect to only change the format and base address of the
framebuffer. I guess it can fail, but it doesn't seem that different to
the async plane update we already have and works well.


In this case it can work, but by using generic drm api, it's hard to know
what the driver will do.


We should document extensively what we expect drivers to do in those
hooks, and possibly call cant_sleep() in the framework function to have
some reporting at least.


Also how many drivers would need this ?

Currently I was mostly considering x86 platform, so:

simpledrm/ast/mgag200 which works well with the get_scanout_buffer().

i915/amdgpu/nouveau, which are quite complex, and will need to do their own
thing anyway.


I guess we're not entirely aligned there then. I would expect that
mechanism to work with any atomic KMS driver. You are right that i915,
amdgpu and nouveau are special enough that some extra internal plumbing
is going to be required, but I'd expect it to be easy to support with
any other driver for a memory-mapped device.

I guess what I'm trying to say is, even though it's totally fine that
you only support those drivers at first, supporting in vc4 for example
shouldn't require to rewrite the whole thing.


Would that work for you to put that in a drm_panic_helper.c,
so that drivers can opt-in ?

So the driver can call a drm_panic_helper_prepare_commit() at
initialization, and then in the get_scanout_buffer() function


If we have a full blown commit with a new framebuffer, why do we need
get_scanout_buffer? It should be either the framebuffer itself, or in
the plane state if you have a conversion.


run the atomic_update() on it, and return this commit's framebuffer ?

That way each driver have a better control on what the panic handler will
do.
It can even call directly its internal functions, to avoid the locks of the
drm generic functions, and make sure it will only change the format and base
address.
That's a bit more work for each driver, but should be more reliable I think.


I don't think that better control there is a good idea, it's a path that
won't get tested much so we'd be better off not allowing drivers to
deviate too much from the "ideal" design.

What I had in mind is something like:

   - Add a panic hook in drm_mode_config_funcs, with a
 drm_atomic_helper_panic helper;

   - Provide an atomic_panic hook or something in drm_plane_helper_funcs;

   - If they are set, we register the drm_panic handler;

   - The handler will call drm_mode_config_funcs.panic, which will take
 its prepared state, fill the framebuffer it allocated with the
 penguin and backtrace, call drm_plane_helper_funcs.atomic_panic().

   - The driver now updates the format and fb address.

   - Halt and catch fire

Does that make sense?


Yes, I will do some experiment with that, and see if I can make it work 
this way.
If possible I still want to have a way for simple drivers like 
simpledrm/mgag200 to not allocate a full framebuffer.



Maxime


--

Jocelyn



Re: [PATCH RFC 4/5] drm/msm: dpu1: call wb & sspp clk_force_ctrl op if split clock control

2023-10-10 Thread Neil Armstrong

On 09/10/2023 19:07, Dmitry Baryshkov wrote:

On 09/10/2023 19:36, Neil Armstrong wrote:

Now clk_ctrl IDs can be optional and the clk_ctrl_reg can be specified
on the SSPP & WB caps directly, pass the SSPP & WB hw struct to the
qos & limit params then call the clk_force_ctrl() op accordingly.

Signed-off-by: Neil Armstrong 
---
  .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c    |  4 +--
  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c  |  9 +++---
  drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c   | 37 +++---
  drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.h   | 12 ---
  4 files changed, 40 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
index 78037a697633..e4dfe0be7207 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
@@ -45,6 +45,7 @@ static void dpu_encoder_phys_wb_set_ot_limit(
  struct dpu_vbif_set_ot_params ot_params;
  memset(&ot_params, 0, sizeof(ot_params));
+    ot_params.wb = hw_wb;
  ot_params.xin_id = hw_wb->caps->xin_id;
  ot_params.num = hw_wb->idx - WB_0;
  ot_params.width = phys_enc->cached_mode.hdisplay;
@@ -52,7 +53,6 @@ static void dpu_encoder_phys_wb_set_ot_limit(
  ot_params.is_wfd = true;
  ot_params.frame_rate = drm_mode_vrefresh(&phys_enc->cached_mode);
  ot_params.vbif_idx = hw_wb->caps->vbif_idx;
-    ot_params.clk_ctrl = hw_wb->caps->clk_ctrl;
  ot_params.rd = false;
  dpu_vbif_set_ot_limit(phys_enc->dpu_kms, &ot_params);
@@ -81,9 +81,9 @@ static void dpu_encoder_phys_wb_set_qos_remap(
  hw_wb = phys_enc->hw_wb;
  memset(&qos_params, 0, sizeof(qos_params));
+    qos_params.wb = hw_wb;
  qos_params.vbif_idx = hw_wb->caps->vbif_idx;
  qos_params.xin_id = hw_wb->caps->xin_id;
-    qos_params.clk_ctrl = hw_wb->caps->clk_ctrl;
  qos_params.num = hw_wb->idx - WB_0;
  qos_params.is_rt = false;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index c2aaaded07ed..b0b662068377 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -350,6 +350,7 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
  struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
  memset(&ot_params, 0, sizeof(ot_params));
+    ot_params.sspp = pipe->sspp;
  ot_params.xin_id = pipe->sspp->cap->xin_id;
  ot_params.num = pipe->sspp->idx - SSPP_NONE;
  ot_params.width = drm_rect_width(&pipe_cfg->src_rect);
@@ -357,7 +358,6 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
  ot_params.is_wfd = !pdpu->is_rt_pipe;
  ot_params.frame_rate = frame_rate;
  ot_params.vbif_idx = VBIF_RT;
-    ot_params.clk_ctrl = pipe->sspp->cap->clk_ctrl;
  ot_params.rd = true;
  dpu_vbif_set_ot_limit(dpu_kms, &ot_params);
@@ -377,16 +377,15 @@ static void _dpu_plane_set_qos_remap(struct drm_plane 
*plane,
  memset(&qos_params, 0, sizeof(qos_params));
  qos_params.vbif_idx = VBIF_RT;
-    qos_params.clk_ctrl = pipe->sspp->cap->clk_ctrl;
+    qos_params.sspp = pipe->sspp;
  qos_params.xin_id = pipe->sspp->cap->xin_id;
  qos_params.num = pipe->sspp->idx - SSPP_VIG0;
  qos_params.is_rt = pdpu->is_rt_pipe;
-    DPU_DEBUG_PLANE(pdpu, "pipe:%d vbif:%d xin:%d rt:%d, clk_ctrl:%d\n",
+    DPU_DEBUG_PLANE(pdpu, "pipe:%d vbif:%d xin:%d rt:%d\n",
  qos_params.num,
  qos_params.vbif_idx,
-    qos_params.xin_id, qos_params.is_rt,
-    qos_params.clk_ctrl);
+    qos_params.xin_id, qos_params.is_rt);
  dpu_vbif_set_qos_remap(dpu_kms, &qos_params);
  }
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
index 2ae5cba1848b..a79559084a91 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
@@ -158,11 +158,19 @@ static u32 _dpu_vbif_get_ot_limit(struct dpu_hw_vbif 
*vbif,
  return ot_lim;
  }
-static bool dpu_vbif_setup_clk_force_ctrl(struct dpu_hw_mdp *mdp,
-  unsigned int clk_ctrl,
+static bool dpu_vbif_setup_clk_force_ctrl(struct dpu_hw_sspp *sspp,
+  struct dpu_hw_wb *wb,
+  struct dpu_hw_mdp *mdp,
    bool enable)
  {
-    return mdp->ops.setup_clk_force_ctrl(mdp, clk_ctrl, enable);
+    if (sspp && sspp->cap->clk_ctrl_reg)
+    return sspp->ops.setup_clk_force_ctrl(sspp, enable);
+    else if (wb && wb->caps->clk_ctrl_reg)
+    return wb->ops.setup_clk_force_ctrl(wb, enable);
+    else


This is what I wanted to avoid.

If we move the caller function to the sspp / WB, we will not need this kind of 
wrapper.


I tried it, but it requires passing the mdp pointer to the setup_clk_force_ctrl 
op,
which is IMHO not super clean... or if you have a way to get dpu_hw_mdp from
within h

Re: [PATCH RFC 5/5] drm/msm: dpu1: sm8550: move split clock controls to sspp entries

2023-10-10 Thread Neil Armstrong

On 09/10/2023 19:10, Dmitry Baryshkov wrote:

On 09/10/2023 19:36, Neil Armstrong wrote:

The SM8550 has the SSPP clk_ctrl in the SSPP registers, move them
out of the MDP top.

Signed-off-by: Neil Armstrong 
---
  .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 35 ++
  1 file changed, 15 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h 
b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h
index 7bed819dfc39..527ec020fba4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h
@@ -24,16 +24,6 @@ static const struct dpu_mdp_cfg sm8550_mdp = {
  .base = 0, .len = 0x494,
  .features = BIT(DPU_MDP_PERIPH_0_REMOVED),
  .clk_ctrls = {
-    [DPU_CLK_CTRL_VIG0] = { .reg_off = 0x4330, .bit_off = 0 },
-    [DPU_CLK_CTRL_VIG1] = { .reg_off = 0x6330, .bit_off = 0 },
-    [DPU_CLK_CTRL_VIG2] = { .reg_off = 0x8330, .bit_off = 0 },
-    [DPU_CLK_CTRL_VIG3] = { .reg_off = 0xa330, .bit_off = 0 },
-    [DPU_CLK_CTRL_DMA0] = { .reg_off = 0x24330, .bit_off = 0 },
-    [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x26330, .bit_off = 0 },
-    [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x28330, .bit_off = 0 },
-    [DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2a330, .bit_off = 0 },
-    [DPU_CLK_CTRL_DMA4] = { .reg_off = 0x2c330, .bit_off = 0 },
-    [DPU_CLK_CTRL_DMA5] = { .reg_off = 0x2e330, .bit_off = 0 },
  [DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 },


Hmm, interesting. I even double-checked this. SSPP and WB have their own clock 
registers now. But the REG_DMA uses the main area (0x2bc).


yeah




  },
  };
@@ -73,6 +63,11 @@ static const struct dpu_ctl_cfg sm8550_ctl[] = {
  },
  };
+static const struct dpu_clk_ctrl_reg sm8550_sspp_clk_ctrl = {
+    .reg_off = 0x330,
+    .bit_off = 0
+};


I don't think we even need this outside of dpu_hw_sspp. You can use 
core_major_rev to check whether the driver should use global clocks or per-SSPP 
/ per-WB clocks register instead.


Ack




+
  static const struct dpu_sspp_cfg sm8550_sspp[] = {
  {
  .name = "sspp_0", .id = SSPP_VIG0,
@@ -81,7 +76,7 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = {
  .sblk = &sm8550_vig_sblk_0,
  .xin_id = 0,
  .type = SSPP_TYPE_VIG,
-    .clk_ctrl = DPU_CLK_CTRL_VIG0,
+    .clk_ctrl_reg = &sm8550_sspp_clk_ctrl,
  }, {
  .name = "sspp_1", .id = SSPP_VIG1,
  .base = 0x6000, .len = 0x344,
@@ -89,7 +84,7 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = {
  .sblk = &sm8550_vig_sblk_1,
  .xin_id = 4,
  .type = SSPP_TYPE_VIG,
-    .clk_ctrl = DPU_CLK_CTRL_VIG1,
+    .clk_ctrl_reg = &sm8550_sspp_clk_ctrl,
  }, {
  .name = "sspp_2", .id = SSPP_VIG2,
  .base = 0x8000, .len = 0x344,
@@ -97,7 +92,7 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = {
  .sblk = &sm8550_vig_sblk_2,
  .xin_id = 8,
  .type = SSPP_TYPE_VIG,
-    .clk_ctrl = DPU_CLK_CTRL_VIG2,
+    .clk_ctrl_reg = &sm8550_sspp_clk_ctrl,
  }, {
  .name = "sspp_3", .id = SSPP_VIG3,
  .base = 0xa000, .len = 0x344,
@@ -105,7 +100,7 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = {
  .sblk = &sm8550_vig_sblk_3,
  .xin_id = 12,
  .type = SSPP_TYPE_VIG,
-    .clk_ctrl = DPU_CLK_CTRL_VIG3,
+    .clk_ctrl_reg = &sm8550_sspp_clk_ctrl,
  }, {
  .name = "sspp_8", .id = SSPP_DMA0,
  .base = 0x24000, .len = 0x344,
@@ -113,7 +108,7 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = {
  .sblk = &sdm845_dma_sblk_0,
  .xin_id = 1,
  .type = SSPP_TYPE_DMA,
-    .clk_ctrl = DPU_CLK_CTRL_DMA0,
+    .clk_ctrl_reg = &sm8550_sspp_clk_ctrl,
  }, {
  .name = "sspp_9", .id = SSPP_DMA1,
  .base = 0x26000, .len = 0x344,
@@ -121,7 +116,7 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = {
  .sblk = &sdm845_dma_sblk_1,
  .xin_id = 5,
  .type = SSPP_TYPE_DMA,
-    .clk_ctrl = DPU_CLK_CTRL_DMA1,
+    .clk_ctrl_reg = &sm8550_sspp_clk_ctrl,
  }, {
  .name = "sspp_10", .id = SSPP_DMA2,
  .base = 0x28000, .len = 0x344,
@@ -129,7 +124,7 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = {
  .sblk = &sdm845_dma_sblk_2,
  .xin_id = 9,
  .type = SSPP_TYPE_DMA,
-    .clk_ctrl = DPU_CLK_CTRL_DMA2,
+    .clk_ctrl_reg = &sm8550_sspp_clk_ctrl,
  }, {
  .name = "sspp_11", .id = SSPP_DMA3,
  .base = 0x2a000, .len = 0x344,
@@ -137,7 +132,7 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = {
  .sblk = &sdm845_dma_sblk_3,
  .xin_id = 13,
  .type = SSPP_TYPE_DMA,
-    .clk_ctrl = DPU_CLK_CTRL_DMA3,
+    .clk_ctrl_reg = &sm8550_sspp_clk_ctrl,
  }, {
  .name = "sspp_12", .id = SSPP_DMA4,
  .base = 0x2c00

Re: [PATCH RFC 5/5] drm/msm: dpu1: sm8550: move split clock controls to sspp entries

2023-10-10 Thread Neil Armstrong

On 09/10/2023 19:10, Dmitry Baryshkov wrote:

On 09/10/2023 19:36, Neil Armstrong wrote:

The SM8550 has the SSPP clk_ctrl in the SSPP registers, move them
out of the MDP top.

Signed-off-by: Neil Armstrong 
---
  .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 35 ++
  1 file changed, 15 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h 
b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h
index 7bed819dfc39..527ec020fba4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h
@@ -24,16 +24,6 @@ static const struct dpu_mdp_cfg sm8550_mdp = {
  .base = 0, .len = 0x494,
  .features = BIT(DPU_MDP_PERIPH_0_REMOVED),
  .clk_ctrls = {
-    [DPU_CLK_CTRL_VIG0] = { .reg_off = 0x4330, .bit_off = 0 },
-    [DPU_CLK_CTRL_VIG1] = { .reg_off = 0x6330, .bit_off = 0 },
-    [DPU_CLK_CTRL_VIG2] = { .reg_off = 0x8330, .bit_off = 0 },
-    [DPU_CLK_CTRL_VIG3] = { .reg_off = 0xa330, .bit_off = 0 },
-    [DPU_CLK_CTRL_DMA0] = { .reg_off = 0x24330, .bit_off = 0 },
-    [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x26330, .bit_off = 0 },
-    [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x28330, .bit_off = 0 },
-    [DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2a330, .bit_off = 0 },
-    [DPU_CLK_CTRL_DMA4] = { .reg_off = 0x2c330, .bit_off = 0 },
-    [DPU_CLK_CTRL_DMA5] = { .reg_off = 0x2e330, .bit_off = 0 },
  [DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 },


Hmm, interesting. I even double-checked this. SSPP and WB have their own clock 
registers now. But the REG_DMA uses the main area (0x2bc).


yeah




  },
  };
@@ -73,6 +63,11 @@ static const struct dpu_ctl_cfg sm8550_ctl[] = {
  },
  };
+static const struct dpu_clk_ctrl_reg sm8550_sspp_clk_ctrl = {
+    .reg_off = 0x330,
+    .bit_off = 0
+};


I don't think we even need this outside of dpu_hw_sspp. You can use 
core_major_rev to check whether the driver should use global clocks or per-SSPP 
/ per-WB clocks register instead.


Ack




+
  static const struct dpu_sspp_cfg sm8550_sspp[] = {
  {
  .name = "sspp_0", .id = SSPP_VIG0,
@@ -81,7 +76,7 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = {
  .sblk = &sm8550_vig_sblk_0,
  .xin_id = 0,
  .type = SSPP_TYPE_VIG,
-    .clk_ctrl = DPU_CLK_CTRL_VIG0,
+    .clk_ctrl_reg = &sm8550_sspp_clk_ctrl,
  }, {
  .name = "sspp_1", .id = SSPP_VIG1,
  .base = 0x6000, .len = 0x344,
@@ -89,7 +84,7 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = {
  .sblk = &sm8550_vig_sblk_1,
  .xin_id = 4,
  .type = SSPP_TYPE_VIG,
-    .clk_ctrl = DPU_CLK_CTRL_VIG1,
+    .clk_ctrl_reg = &sm8550_sspp_clk_ctrl,
  }, {
  .name = "sspp_2", .id = SSPP_VIG2,
  .base = 0x8000, .len = 0x344,
@@ -97,7 +92,7 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = {
  .sblk = &sm8550_vig_sblk_2,
  .xin_id = 8,
  .type = SSPP_TYPE_VIG,
-    .clk_ctrl = DPU_CLK_CTRL_VIG2,
+    .clk_ctrl_reg = &sm8550_sspp_clk_ctrl,
  }, {
  .name = "sspp_3", .id = SSPP_VIG3,
  .base = 0xa000, .len = 0x344,
@@ -105,7 +100,7 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = {
  .sblk = &sm8550_vig_sblk_3,
  .xin_id = 12,
  .type = SSPP_TYPE_VIG,
-    .clk_ctrl = DPU_CLK_CTRL_VIG3,
+    .clk_ctrl_reg = &sm8550_sspp_clk_ctrl,
  }, {
  .name = "sspp_8", .id = SSPP_DMA0,
  .base = 0x24000, .len = 0x344,
@@ -113,7 +108,7 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = {
  .sblk = &sdm845_dma_sblk_0,
  .xin_id = 1,
  .type = SSPP_TYPE_DMA,
-    .clk_ctrl = DPU_CLK_CTRL_DMA0,
+    .clk_ctrl_reg = &sm8550_sspp_clk_ctrl,
  }, {
  .name = "sspp_9", .id = SSPP_DMA1,
  .base = 0x26000, .len = 0x344,
@@ -121,7 +116,7 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = {
  .sblk = &sdm845_dma_sblk_1,
  .xin_id = 5,
  .type = SSPP_TYPE_DMA,
-    .clk_ctrl = DPU_CLK_CTRL_DMA1,
+    .clk_ctrl_reg = &sm8550_sspp_clk_ctrl,
  }, {
  .name = "sspp_10", .id = SSPP_DMA2,
  .base = 0x28000, .len = 0x344,
@@ -129,7 +124,7 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = {
  .sblk = &sdm845_dma_sblk_2,
  .xin_id = 9,
  .type = SSPP_TYPE_DMA,
-    .clk_ctrl = DPU_CLK_CTRL_DMA2,
+    .clk_ctrl_reg = &sm8550_sspp_clk_ctrl,
  }, {
  .name = "sspp_11", .id = SSPP_DMA3,
  .base = 0x2a000, .len = 0x344,
@@ -137,7 +132,7 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = {
  .sblk = &sdm845_dma_sblk_3,
  .xin_id = 13,
  .type = SSPP_TYPE_DMA,
-    .clk_ctrl = DPU_CLK_CTRL_DMA3,
+    .clk_ctrl_reg = &sm8550_sspp_clk_ctrl,
  }, {
  .name = "sspp_12", .id = SSPP_DMA4,
  .base = 0x2c00

Re: [PATCH 1/8] drm/solomon: Rename ssd130x driver to ssd13xx

2023-10-10 Thread Maxime Ripard
Hi,

On Mon, Oct 09, 2023 at 08:34:15PM +0200, Javier Martinez Canillas wrote:
> The driver only supports the SSD130x family of Solomon OLED controllers
> now, but will be extended to also support the SSD132x (4-bit grayscale)
> and SSD133x (16-bit RGB) controller families. Rename driver to ssd13xx.
> 
> Signed-off-by: Javier Martinez Canillas 

I'm not sure it's worth it. I understand what you want to achieve, but
this will create conflicts, affect the configuration of everyone
enabling that driver, etc.

And we have plenty of drivers that don't match all the devices they
support anyway.

Plus 

> @@ -11,10 +11,10 @@
>  #include 
>  #include 
>  
> -#include "ssd130x.h"
> +#include "ssd13xx.h"
>  
> -#define DRIVER_NAME  "ssd130x-i2c"
> -#define DRIVER_DESC  "DRM driver for Solomon SSD130x OLED displays (I2C)"
> +#define DRIVER_NAME  "ssd13xx-i2c"
> +#define DRIVER_DESC  "DRM driver for Solomon SSD13xx OLED displays (I2C)"
>  
>  static const struct regmap_config ssd130x_i2c_regmap_config = {
>   .reg_bits = 8,

... We now end up with a lot of inconsistencies where some things are
called ssd130x and others ssd13xx.

Maxime


signature.asc
Description: PGP signature


Re: [PATCH RFC 0/5] drm/msm: dpu1: correctly implement SSPP & WB Clock Control Split

2023-10-10 Thread Marijn Suijten
On 2023-10-09 18:36:11, Neil Armstrong wrote:
> Starting with the SM8550 platform, the SSPP & WB Clock Controls are
> no more in the MDP TOP registers, but in the SSPP & WB register space.
> 
> Add the corresponding SSPP & WB ops and use them from the vbif QoS
> and OT limit setup functions.
> 
> Signed-off-by: Neil Armstrong 
> ---
> Neil Armstrong (5):
>   drm/msm: dpu1: create a dpu_hw_clk_force_ctrl() helper
>   drm/msm: dpu1: add setup_clk_force_ctrl() op to sspp & wb
>   drm/msm: dpu1: vbif: add dpu_vbif_setup_clk_force_ctrl() helper
>   drm/msm: dpu1: call wb & sspp clk_force_ctrl op if split clock control
>   drm/msm: dpu1: sm8550: move split clock controls to sspp entries

Fyi we're all using drm/msm/dpu: now :)

- Marijn

> 
>  .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 35 +---
>  .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c|  4 +--
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  4 +++
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c|  9 +
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h|  9 +
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 23 +
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c| 21 
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h|  4 +++
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c  |  9 +
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h  |  4 +++
>  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c  |  9 +++--
>  drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c   | 38 
> +-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.h   | 12 ---
>  13 files changed, 120 insertions(+), 61 deletions(-)
> ---
> base-commit: 9119cf579b4432b36be9d33a92f4331922067d92
> change-id: 20231009-topic-sm8550-graphics-sspp-split-clk-43c32e37b6aa
> 
> Best regards,
> -- 
> Neil Armstrong 
> 


Re: [PATCH RFC 0/5] drm/msm: dpu1: correctly implement SSPP & WB Clock Control Split

2023-10-10 Thread Neil Armstrong

On 10/10/2023 10:10, Marijn Suijten wrote:

On 2023-10-09 18:36:11, Neil Armstrong wrote:

Starting with the SM8550 platform, the SSPP & WB Clock Controls are
no more in the MDP TOP registers, but in the SSPP & WB register space.

Add the corresponding SSPP & WB ops and use them from the vbif QoS
and OT limit setup functions.

Signed-off-by: Neil Armstrong 
---
Neil Armstrong (5):
   drm/msm: dpu1: create a dpu_hw_clk_force_ctrl() helper
   drm/msm: dpu1: add setup_clk_force_ctrl() op to sspp & wb
   drm/msm: dpu1: vbif: add dpu_vbif_setup_clk_force_ctrl() helper
   drm/msm: dpu1: call wb & sspp clk_force_ctrl op if split clock control
   drm/msm: dpu1: sm8550: move split clock controls to sspp entries


Fyi we're all using drm/msm/dpu: now :)


Ack, thx, will change for v2



- Marijn



  .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 35 +---
  .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c|  4 +--
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  4 +++
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c|  9 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h|  9 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 23 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c| 21 
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h|  4 +++
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c  |  9 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h  |  4 +++
  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c  |  9 +++--
  drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c   | 38 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.h   | 12 ---
  13 files changed, 120 insertions(+), 61 deletions(-)
---
base-commit: 9119cf579b4432b36be9d33a92f4331922067d92
change-id: 20231009-topic-sm8550-graphics-sspp-split-clk-43c32e37b6aa

Best regards,
--
Neil Armstrong 





Re: [PATCH v4 2/4] drm/panic: Add a drm panic handler

2023-10-10 Thread Maxime Ripard
On Tue, Oct 10, 2023 at 09:55:46AM +0200, Jocelyn Falempe wrote:
> On 09/10/2023 18:07, Maxime Ripard wrote:
> > On Mon, Oct 09, 2023 at 04:05:19PM +0200, Jocelyn Falempe wrote:
> > > > > - I find it risky to completely reconfigure the hardware in a panic 
> > > > > handler.
> > > > 
> > > > I would expect to only change the format and base address of the
> > > > framebuffer. I guess it can fail, but it doesn't seem that different to
> > > > the async plane update we already have and works well.
> > > > 
> > > In this case it can work, but by using generic drm api, it's hard to know
> > > what the driver will do.
> > 
> > We should document extensively what we expect drivers to do in those
> > hooks, and possibly call cant_sleep() in the framework function to have
> > some reporting at least.
> > 
> > > > > Also how many drivers would need this ?
> > > > > 
> > > > > Currently I was mostly considering x86 platform, so:
> > > > > 
> > > > > simpledrm/ast/mgag200 which works well with the get_scanout_buffer().
> > > > > 
> > > > > i915/amdgpu/nouveau, which are quite complex, and will need to do 
> > > > > their own
> > > > > thing anyway.
> > > > 
> > > > I guess we're not entirely aligned there then. I would expect that
> > > > mechanism to work with any atomic KMS driver. You are right that i915,
> > > > amdgpu and nouveau are special enough that some extra internal plumbing
> > > > is going to be required, but I'd expect it to be easy to support with
> > > > any other driver for a memory-mapped device.
> > > > 
> > > > I guess what I'm trying to say is, even though it's totally fine that
> > > > you only support those drivers at first, supporting in vc4 for example
> > > > shouldn't require to rewrite the whole thing.
> > > 
> > > Would that work for you to put that in a drm_panic_helper.c,
> > > so that drivers can opt-in ?
> > > 
> > > So the driver can call a drm_panic_helper_prepare_commit() at
> > > initialization, and then in the get_scanout_buffer() function
> > 
> > If we have a full blown commit with a new framebuffer, why do we need
> > get_scanout_buffer? It should be either the framebuffer itself, or in
> > the plane state if you have a conversion.
> > 
> > > run the atomic_update() on it, and return this commit's framebuffer ?
> > > 
> > > That way each driver have a better control on what the panic handler will
> > > do.
> > > It can even call directly its internal functions, to avoid the locks of 
> > > the
> > > drm generic functions, and make sure it will only change the format and 
> > > base
> > > address.
> > > That's a bit more work for each driver, but should be more reliable I 
> > > think.
> > 
> > I don't think that better control there is a good idea, it's a path that
> > won't get tested much so we'd be better off not allowing drivers to
> > deviate too much from the "ideal" design.
> > 
> > What I had in mind is something like:
> > 
> >- Add a panic hook in drm_mode_config_funcs, with a
> >  drm_atomic_helper_panic helper;
> > 
> >- Provide an atomic_panic hook or something in drm_plane_helper_funcs;
> > 
> >- If they are set, we register the drm_panic handler;
> > 
> >- The handler will call drm_mode_config_funcs.panic, which will take
> >  its prepared state, fill the framebuffer it allocated with the
> >  penguin and backtrace, call drm_plane_helper_funcs.atomic_panic().
> > 
> >- The driver now updates the format and fb address.
> > 
> >- Halt and catch fire
> > 
> > Does that make sense?
> 
> Yes, I will do some experiment with that, and see if I can make it
> work this way.

Thanks :)

> If possible I still want to have a way for simple drivers like
> simpledrm/mgag200 to not allocate a full framebuffer.

I guess the split isn't going to be whether the driver is simple or not,
but whether it always has access to the buffer used by the scanout.

Like for simpledrm, we have that guarantee so it makes sense. For other,
if we allow "direct" dma-buf, it's game over and we just can't.

Maxime


signature.asc
Description: PGP signature


Re: [PATCH] drm/panel: fix a possible null pointer dereference

2023-10-10 Thread Neil Armstrong
Hi,

On Sat, 07 Oct 2023 11:31:05 +0800, Ma Ke wrote:
> In versatile_panel_get_modes(), the return value of drm_mode_duplicate()
> is assigned to mode, which will lead to a NULL pointer dereference
> on failure of drm_mode_duplicate(). Add a check to avoid npd.
> 
> 

Thanks, Applied to https://anongit.freedesktop.org/git/drm/drm-misc.git 
(drm-misc-next)

[1/1] drm/panel: fix a possible null pointer dereference
  
https://cgit.freedesktop.org/drm/drm-misc/commit/?id=924e5814d1f84e6fa5cb19c6eceb69f066225229

-- 
Neil



Re: [PATCH v2] drm/panel/panel-tpo-tpg110: fix a possible null pointer dereference

2023-10-10 Thread Neil Armstrong
Hi,

On Mon, 09 Oct 2023 17:04:46 +0800, Ma Ke wrote:
> In tpg110_get_modes(), the return value of drm_mode_duplicate() is
> assigned to mode, which will lead to a NULL pointer dereference on
> failure of drm_mode_duplicate(). Add a check to avoid npd.
> 
> 

Thanks, Applied to https://anongit.freedesktop.org/git/drm/drm-misc.git 
(drm-misc-next)

[1/1] drm/panel/panel-tpo-tpg110: fix a possible null pointer dereference
  
https://cgit.freedesktop.org/drm/drm-misc/commit/?id=f22def5970c423ea7f87d5247bd0ef91416b0658

-- 
Neil



Re: [PATCH 1/8] drm/solomon: Rename ssd130x driver to ssd13xx

2023-10-10 Thread Javier Martinez Canillas
Maxime Ripard  writes:

Hello Maxime,

Thanks for the feedback.

> Hi,
>
> On Mon, Oct 09, 2023 at 08:34:15PM +0200, Javier Martinez Canillas wrote:
>> The driver only supports the SSD130x family of Solomon OLED controllers
>> now, but will be extended to also support the SSD132x (4-bit grayscale)
>> and SSD133x (16-bit RGB) controller families. Rename driver to ssd13xx.
>> 
>> Signed-off-by: Javier Martinez Canillas 
>
> I'm not sure it's worth it. I understand what you want to achieve, but
> this will create conflicts, affect the configuration of everyone
> enabling that driver, etc.
>
> And we have plenty of drivers that don't match all the devices they
> support anyway.
>

Yeah, I was on the fence and even discussed this with others. I'm OK with
dropping this patch if the agreegment is that isn't worth it to make the
name more accurate.

> Plus 
>
>> @@ -11,10 +11,10 @@
>>  #include 
>>  #include 
>>  
>> -#include "ssd130x.h"
>> +#include "ssd13xx.h"
>>  
>> -#define DRIVER_NAME "ssd130x-i2c"
>> -#define DRIVER_DESC "DRM driver for Solomon SSD130x OLED displays (I2C)"
>> +#define DRIVER_NAME "ssd13xx-i2c"
>> +#define DRIVER_DESC "DRM driver for Solomon SSD13xx OLED displays (I2C)"
>>  
>>  static const struct regmap_config ssd130x_i2c_regmap_config = {
>>  .reg_bits = 8,
>
> ... We now end up with a lot of inconsistencies where some things are
> called ssd130x and others ssd13xx.
>

Yes, but I fix that in patch #2.

> Maxime

-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat



Re: [PATCH v2] drm/panel: boe-tv101wum-nl6: Completely pull GPW to VGL before TP term

2023-10-10 Thread Neil Armstrong
Hi,

On Sat, 07 Oct 2023 14:49:49 +0800, Ruihai Zhou wrote:
> The sta_himax83102 panel sometimes shows abnormally flickering
> horizontal lines. The front gate output will precharge the X point of
> the next pole circuit before TP(TouchPanel Enable) term starts, and wait
> until the end of the TP term to resume the CLK. For this reason, the X
> point must be maintained during the TP term. In abnormal case, we
> measured a slight leakage at point X. This because during the TP term,
> the GPW does not fully pull the VGL low, causing the TFT to not be
> closed tightly.
> 
> [...]

Thanks, Applied to https://anongit.freedesktop.org/git/drm/drm-misc.git 
(drm-misc-fixes)

[1/1] drm/panel: boe-tv101wum-nl6: Completely pull GPW to VGL before TP term
  
https://cgit.freedesktop.org/drm/drm-misc/commit/?id=258dd5e6e65995ee85a941eed9a06708a36b1bfe

-- 
Neil



Re: [PATCH v4 2/4] drm/panic: Add a drm panic handler

2023-10-10 Thread Thomas Zimmermann

Hi

Am 09.10.23 um 13:33 schrieb Maxime Ripard:
[...]

And you don't need to support all kinds of tiling, YUV or RGB variants.


We should indeed not use YUV at all. For RGB, we already have plenty of 
conversion code from XRGB-to-, so we are more flexible there.




So if I understand correctly, drm_panic would pre-allocate a plane/commit,
and use that when a panic occurs ?


And have it checked already, yes. We would only wait for a panic to
happen to pull the trigger on the commit.


I have two concern about this approach:
- How much memory would be allocated for this ? a whole framebuffer can be
big for just this use case.


As I outlined in my email at [1], there are a number of different 
scenarios. The question of atomic state and commits is entirely separate 
from the DRM panic handler. We should not throw them together. Whatever 
is necessary is get a scanout buffer, should happen on the driver side 
of get_scanout_buffer, not on the drm_panic side.


[1] 
https://lore.kernel.org/dri-devel/39bd4c35-8a61-42ee-8675-ccea4f5d4...@suse.de/T/#m22f116e9438e00a5f0a9dc43987d4153424f8be1




I'dd expect a whole framebuffer for the current
configuration/resolution. It would be typically 4MB for a full-HD system
which isn't a lot really and I guess we can always add an option to
disable the mechanism if needed.


- I find it risky to completely reconfigure the hardware in a panic handler.


I would expect to only change the format and base address of the
framebuffer. I guess it can fail, but it doesn't seem that different to
the async plane update we already have and works well.


The one thing I don't understand is: Why should we use atomic commits in 
the first place? It doesn't make sense for firmware-based drivers. In 
some drivers, even the simple ast, we hold locks during the regular 
commit. Trying to run the panic commit concurrently will likely give a 
deadlock.


In the end it's a per-driver decision, but in most cases, the driver can 
easily switch to a default mode with some ad-hoc code.


Best regards
Thomas




Also how many drivers would need this ?

Currently I was mostly considering x86 platform, so:

simpledrm/ast/mgag200 which works well with the get_scanout_buffer().

i915/amdgpu/nouveau, which are quite complex, and will need to do their own
thing anyway.


I guess we're not entirely aligned there then. I would expect that
mechanism to work with any atomic KMS driver. You are right that i915,
amdgpu and nouveau are special enough that some extra internal plumbing
is going to be required, but I'd expect it to be easy to support with
any other driver for a memory-mapped device.

I guess what I'm trying to say is, even though it's totally fine that
you only support those drivers at first, supporting in vc4 for example
shouldn't require to rewrite the whole thing.


I'm more in favor of an emergency function, that each driver has to
implement, and use what the hardware can do to display a simple frame
quickly. get_scanout_buffer() is a good start for simple driver, but
will need refactoring for the more complex case, like adding a
callback to write pixels one by one, if there is no memory mapped
buffer available.


Sorry, I'm not quite sure what you mean there, where would you write the
pixel to?


It was mentioned by Noralf, about the amdgpu driver:

https://lore.kernel.org/dri-devel/d233c376-ed07-2127-6084-8292d313d...@amd.com/

They have a slow "debug interface" that you can write to, and can be used
for the panic handler. It's not memory mapped, so you have to write pixels
one by one.

So for the struct drm_scanout_buffer, I can add a function pointer to a
write_pixel(u32 x, u32 y, u32 color)
So if the iosys map is null, it will use that instead.


It would be nice to support indeed, but it's a fairly rare feature afaik
so I'd rather focus on getting something that can work for everyone first

Maxime


--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [PATCH v4 2/4] drm/panic: Add a drm panic handler

2023-10-10 Thread Thomas Zimmermann

Hi

Am 09.10.23 um 18:07 schrieb Maxime Ripard:

On Mon, Oct 09, 2023 at 04:05:19PM +0200, Jocelyn Falempe wrote:

- I find it risky to completely reconfigure the hardware in a panic handler.


I would expect to only change the format and base address of the
framebuffer. I guess it can fail, but it doesn't seem that different to
the async plane update we already have and works well.


In this case it can work, but by using generic drm api, it's hard to know
what the driver will do.


We should document extensively what we expect drivers to do in those
hooks, and possibly call cant_sleep() in the framework function to have
some reporting at least.


Also how many drivers would need this ?

Currently I was mostly considering x86 platform, so:

simpledrm/ast/mgag200 which works well with the get_scanout_buffer().

i915/amdgpu/nouveau, which are quite complex, and will need to do their own
thing anyway.


I guess we're not entirely aligned there then. I would expect that
mechanism to work with any atomic KMS driver. You are right that i915,
amdgpu and nouveau are special enough that some extra internal plumbing
is going to be required, but I'd expect it to be easy to support with
any other driver for a memory-mapped device.

I guess what I'm trying to say is, even though it's totally fine that
you only support those drivers at first, supporting in vc4 for example
shouldn't require to rewrite the whole thing.


Would that work for you to put that in a drm_panic_helper.c,
so that drivers can opt-in ?

So the driver can call a drm_panic_helper_prepare_commit() at
initialization, and then in the get_scanout_buffer() function


If we have a full blown commit with a new framebuffer, why do we need
get_scanout_buffer? It should be either the framebuffer itself, or in
the plane state if you have a conversion.


We also have discussions about kexec/kdump support. Here we'd need to 
retrieve the scanout address, forward it to the kexec kernel and put 
simpledrm onto that framebuffer until the regular driver takes over. An 
interface like get_scanout_buffer will be helpful for this use case. So 
it makes sense to use it for the panic handler as well.





run the atomic_update() on it, and return this commit's framebuffer ?

That way each driver have a better control on what the panic handler will
do.
It can even call directly its internal functions, to avoid the locks of the
drm generic functions, and make sure it will only change the format and base
address.
That's a bit more work for each driver, but should be more reliable I think.


I don't think that better control there is a good idea, it's a path that
won't get tested much so we'd be better off not allowing drivers to
deviate too much from the "ideal" design.

What I had in mind is something like:

   - Add a panic hook in drm_mode_config_funcs, with a
 drm_atomic_helper_panic helper;

   - Provide an atomic_panic hook or something in drm_plane_helper_funcs;

   - If they are set, we register the drm_panic handler;

   - The handler will call drm_mode_config_funcs.panic, which will take
 its prepared state, fill the framebuffer it allocated with the
 penguin and backtrace, call drm_plane_helper_funcs.atomic_panic().

   - The driver now updates the format and fb address.

   - Halt and catch fire

Does that make sense?


Please see my other replies. I find this fragile, and unnecessary for 
cases where there already is a working scanout buffer in place. It's 
something a driver could implement internally to provide a scanout 
buffer if none has been set up already.


Best regards
Thomas


Maxime


--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [PATCH v4 4/4] drm/mgag200: Add drm_panic support

2023-10-10 Thread Thomas Zimmermann

Hi

Am 03.10.23 um 16:22 schrieb Jocelyn Falempe:

Add support for the drm_panic module, which displays a message to
the screen when a kernel panic occurs.

Signed-off-by: Jocelyn Falempe 
---
  drivers/gpu/drm/mgag200/mgag200_drv.c | 24 
  1 file changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c 
b/drivers/gpu/drm/mgag200/mgag200_drv.c
index 976f0ab2006b..229d9c116b42 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -12,10 +12,12 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
  #include 
+#include 
  #include 
  
  #include "mgag200_drv.h"

@@ -83,6 +85,27 @@ resource_size_t mgag200_probe_vram(void __iomem *mem, 
resource_size_t size)
return offset - 65536;
  }
  
+static int mgag200_get_scanout_buffer(struct drm_device *dev,

+ struct drm_scanout_buffer *sb)
+{
+   struct drm_plane *plane;
+   struct mga_device *mdev = to_mga_device(dev);
+   struct iosys_map map = IOSYS_MAP_INIT_VADDR_IOMEM(mdev->vram);
+
+   /* mgag200 has only one plane */
+   drm_for_each_plane(plane, dev) {
+   if (!plane->state || !plane->state->fb)


Better test for plane->state->visible. You should also check if it's a 
primary plane.


Best regards
Thomas


+   return -ENODEV;
+   sb->format = plane->state->fb->format;
+   sb->width = plane->state->fb->width;
+   sb->height = plane->state->fb->height;
+   sb->pitch = plane->state->fb->pitches[0];
+   sb->map = map;
+   return 0;
+   }
+   return -ENODEV;
+}
+
  /*
   * DRM driver
   */
@@ -98,6 +121,7 @@ static const struct drm_driver mgag200_driver = {
.major = DRIVER_MAJOR,
.minor = DRIVER_MINOR,
.patchlevel = DRIVER_PATCHLEVEL,
+   .get_scanout_buffer = mgag200_get_scanout_buffer,
DRM_GEM_SHMEM_DRIVER_OPS,
  };
  


--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [PATCH v4 2/4] drm/panic: Add a drm panic handler

2023-10-10 Thread Maxime Ripard


On Tue, Oct 10, 2023 at 10:55:09AM +0200, Thomas Zimmermann wrote:
> > > So if I understand correctly, drm_panic would pre-allocate a plane/commit,
> > > and use that when a panic occurs ?
> > 
> > And have it checked already, yes. We would only wait for a panic to
> > happen to pull the trigger on the commit.
> > 
> > > I have two concern about this approach:
> > > - How much memory would be allocated for this ? a whole framebuffer can be
> > > big for just this use case.
> 
> As I outlined in my email at [1], there are a number of different scenarios.
> The question of atomic state and commits is entirely separate from the DRM
> panic handler. We should not throw them together. Whatever is necessary is
> get a scanout buffer, should happen on the driver side of
> get_scanout_buffer, not on the drm_panic side.
> 
> [1] 
> https://lore.kernel.org/dri-devel/39bd4c35-8a61-42ee-8675-ccea4f5d4...@suse.de/T/#m22f116e9438e00a5f0a9dc43987d4153424f8be1
> 
> > 
> > I'dd expect a whole framebuffer for the current
> > configuration/resolution. It would be typically 4MB for a full-HD system
> > which isn't a lot really and I guess we can always add an option to
> > disable the mechanism if needed.
> > 
> > > - I find it risky to completely reconfigure the hardware in a panic 
> > > handler.
> > 
> > I would expect to only change the format and base address of the
> > framebuffer. I guess it can fail, but it doesn't seem that different to
> > the async plane update we already have and works well.
> 
> The one thing I don't understand is: Why should we use atomic commits in the
> first place? It doesn't make sense for firmware-based drivers.

Because this is generic infrastructure that is valuable for any drivers
and not only firmware-based drivers?

> In some drivers, even the simple ast, we hold locks during the regular
> commit. Trying to run the panic commit concurrently will likely give a
> deadlock.

You're in the middle of a panic. Don't take any locks and you won't deadlock.

> In the end it's a per-driver decision, but in most cases, the driver can
> easily switch to a default mode with some ad-hoc code.

When was the last time a per-driver decision has been a good thing? I'm
sorry, but the get_scanout_buffer approach buffer won't work for any
driver out there.

I'm fine with discussing alternatives if you don't like the ones I
suggested, but they must allow the panic handler infrastructure to work
with any driver we have, not just 4.

Maxime


signature.asc
Description: PGP signature


Re: [PATCH v1 0/2] [PATCH] hwmon: (pmbus/max31785) Add minimum delay between bus accesses

2023-10-10 Thread Wolfram Sang
Hi,

thanks for this series!

> Reference to Andrew's previous proposal:
> https://lore.kernel.org/all/20200914122811.3295678-1-and...@aj.id.au/

I do totally agree with Guenter's comment[1], though. This just affects
a few drivers and this patch is way too intrusive for the I2C core. The
later suggested prepare_device() callback[2] sounds better to me. I
still haven't fully understood why this all cannot be handled in the
driver's probe. Could someone give me a small summary about that?

All the best,

   Wolfram


[1] 
https://lore.kernel.org/all/e7a64983-fe1d-1ba2-b0c3-ae4a791f7...@roeck-us.net/
[2] 
https://lore.kernel.org/all/120342ec-f44a-4550-8c54-45b97db41...@www.fastmail.com/



signature.asc
Description: PGP signature


Re: [PATCH v4 2/4] drm/panic: Add a drm panic handler

2023-10-10 Thread Maxime Ripard
On Tue, Oct 10, 2023 at 11:04:33AM +0200, Thomas Zimmermann wrote:
> Am 09.10.23 um 18:07 schrieb Maxime Ripard:
> > On Mon, Oct 09, 2023 at 04:05:19PM +0200, Jocelyn Falempe wrote:
> > > > > - I find it risky to completely reconfigure the hardware in a panic 
> > > > > handler.
> > > > 
> > > > I would expect to only change the format and base address of the
> > > > framebuffer. I guess it can fail, but it doesn't seem that different to
> > > > the async plane update we already have and works well.
> > > > 
> > > In this case it can work, but by using generic drm api, it's hard to know
> > > what the driver will do.
> > 
> > We should document extensively what we expect drivers to do in those
> > hooks, and possibly call cant_sleep() in the framework function to have
> > some reporting at least.
> > 
> > > > > Also how many drivers would need this ?
> > > > > 
> > > > > Currently I was mostly considering x86 platform, so:
> > > > > 
> > > > > simpledrm/ast/mgag200 which works well with the get_scanout_buffer().
> > > > > 
> > > > > i915/amdgpu/nouveau, which are quite complex, and will need to do 
> > > > > their own
> > > > > thing anyway.
> > > > 
> > > > I guess we're not entirely aligned there then. I would expect that
> > > > mechanism to work with any atomic KMS driver. You are right that i915,
> > > > amdgpu and nouveau are special enough that some extra internal plumbing
> > > > is going to be required, but I'd expect it to be easy to support with
> > > > any other driver for a memory-mapped device.
> > > > 
> > > > I guess what I'm trying to say is, even though it's totally fine that
> > > > you only support those drivers at first, supporting in vc4 for example
> > > > shouldn't require to rewrite the whole thing.
> > > 
> > > Would that work for you to put that in a drm_panic_helper.c,
> > > so that drivers can opt-in ?
> > > 
> > > So the driver can call a drm_panic_helper_prepare_commit() at
> > > initialization, and then in the get_scanout_buffer() function
> > 
> > If we have a full blown commit with a new framebuffer, why do we need
> > get_scanout_buffer? It should be either the framebuffer itself, or in
> > the plane state if you have a conversion.
> 
> We also have discussions about kexec/kdump support. Here we'd need to
> retrieve the scanout address, forward it to the kexec kernel and put
> simpledrm onto that framebuffer until the regular driver takes over.

Generically speaking, there's strictly no guarantee that the current
scanout buffer is accessible by the CPU. It's not even a driver issue,
it's a workload issue, so it will affect 100% of the times some users,
and some 0% of the time.

> An interface like get_scanout_buffer will be helpful for this use
> case. So it makes sense to use it for the panic handler as well.

It won't be helpful because the vast majority of the ARM drivers (and
thus the vast majority of the KMS drivers) won't be able to implement it
properly and reliably.

> > > run the atomic_update() on it, and return this commit's framebuffer ?
> > > 
> > > That way each driver have a better control on what the panic handler will
> > > do.
> > > It can even call directly its internal functions, to avoid the locks of 
> > > the
> > > drm generic functions, and make sure it will only change the format and 
> > > base
> > > address.
> > > That's a bit more work for each driver, but should be more reliable I 
> > > think.
> > 
> > I don't think that better control there is a good idea, it's a path that
> > won't get tested much so we'd be better off not allowing drivers to
> > deviate too much from the "ideal" design.
> > 
> > What I had in mind is something like:
> > 
> >- Add a panic hook in drm_mode_config_funcs, with a
> >  drm_atomic_helper_panic helper;
> > 
> >- Provide an atomic_panic hook or something in drm_plane_helper_funcs;
> > 
> >- If they are set, we register the drm_panic handler;
> > 
> >- The handler will call drm_mode_config_funcs.panic, which will take
> >  its prepared state, fill the framebuffer it allocated with the
> >  penguin and backtrace, call drm_plane_helper_funcs.atomic_panic().
> > 
> >- The driver now updates the format and fb address.
> > 
> >- Halt and catch fire
> > 
> > Does that make sense?
> 
> Please see my other replies. I find this fragile, and unnecessary for cases
> where there already is a working scanout buffer in place.

And please see my other replies. Depending on a working scanout buffer
in place being accessible by the CPU is incredibly limiting. Ignoring it
when I'm pointing that out won't get us to a solution acceptable for
everyone.

> It's something a driver could implement internally to provide a
> scanout buffer if none has been set up already.

Some drivers need extra resources when setting up a plane. VC4 for
example need for every plane to allocate multiple internal SRAM buffers.
Just allocating an extra framebuffer won't cut it.

This is tied to the state so far, so I guess 

Re: [PATCH v3 9/9] efi: move screen_info into efi init code

2023-10-10 Thread Catalin Marinas
On Mon, Oct 09, 2023 at 11:18:45PM +0200, Arnd Bergmann wrote:
> From: Arnd Bergmann 
> 
> After the vga console no longer relies on global screen_info, there are
> only two remaining use cases:
> 
>  - on the x86 architecture, it is used for multiple boot methods
>(bzImage, EFI, Xen, kexec) to commucate the initial VGA or framebuffer
>settings to a number of device drivers.
> 
>  - on other architectures, it is only used as part of the EFI stub,
>and only for the three sysfb framebuffers (simpledrm, simplefb, efifb).
> 
> Remove the duplicate data structure definitions by moving it into the
> efi-init.c file that sets it up initially for the EFI case, leaving x86
> as an exception that retains its own definition for non-EFI boots.
> 
> The added #ifdefs here are optional, I added them to further limit the
> reach of screen_info to configurations that have at least one of the
> users enabled.
> 
> Reviewed-by: Ard Biesheuvel 
> Reviewed-by: Javier Martinez Canillas 
> Acked-by: Helge Deller 
> Signed-off-by: Arnd Bergmann 
> ---
>  arch/arm/kernel/setup.c   |  4 
>  arch/arm64/kernel/efi.c   |  4 
>  arch/arm64/kernel/image-vars.h|  2 ++

It's more Ard's thing and he reviewed it already but if you need another
ack:

Acked-by: Catalin Marinas 


Re: [PATCH v5 2/7] drm/atomic-helper: Add format-conversion state to shadow-plane state

2023-10-10 Thread Maxime Ripard
On Mon, Oct 09, 2023 at 04:22:29PM +0200, Javier Martinez Canillas wrote:
> Thomas Zimmermann  writes:
> > Store an instance of struct drm_format_conv_state in the shadow-plane
> > state struct drm_shadow_plane_state. Many drivers with shadow planes
> > use DRM's format helpers to copy or convert the framebuffer data to
> > backing storage in the scanout buffer. The shadow plane provides the
> > necessary state and manages the conversion's intermediate buffer memory.
> >
> 
> I would argue this is one of the primary selling points for this series
> (since Maxime was asking about the motivation). As you point out, many
> drivers that use a shadow-buffer can also expose a different format than
> the native one to user-space, so makes sense to have the buffer used for
> conversion as a part of the shadow-plane state.

I'm confused, can we convert between formats or not? Or is it about
XRGB vs whatever native format is used by the device?

Maxime


signature.asc
Description: PGP signature


Re: [Intel-gfx] [PATCH] drm/i915/mtl: Remove the 'force_probe' requirement for Meteor Lake

2023-10-10 Thread Tvrtko Ursulin



On 08/10/2023 17:48, Andi Shyti wrote:

From: Radhakrishna Sripada 

Meteor Lake has demonstrated consistent stability for some time.
All user-space API modifications tide to its core platform
functions are operational.

The necessary firmware components are set up and comprehensive
testing has been condused over a period.

Given the recent faborable CI results, as well, we believe it's
time to eliminate the 'force_probe' prerequisite and activate the
platform by default.

Signed-off-by: Aditya Chauhan 
Signed-off-by: Andrzej Hajda 
Signed-off-by: Chris Wilson 
Signed-off-by: Janusz Krzysztofik 
Signed-off-by: Jonathan Cavitt 
Signed-off-by: Nirmoy Das 
Signed-off-by: Radhakrishna Sripada 
Signed-off-by: Andi Shyti 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Rodrigo Vivi 
Cc: Tvrtko Ursulin 
---
Hello,

This patch eliminates the 'force probe' for the MTL platforms. Over the recent
weeks, MTL has demonstrated stability, consistently passing BAT tests with
success rates ranging from 98% to 100%.

There's a single issue hindering us from achieving a 100% BAT test coverage.
Fortunately, we've identified the issue, and the proposed solution can be found
here[*]. The CI results are encouraging.

Once all reviews are addressed, we plan to submit this series with the "Fixes:"
tag.

Thank you and best regards,
Andi and Radhakrishna

[*] https://patchwork.freedesktop.org/series/124744/


Have there been any more recent developments, given 
https://patchwork.freedesktop.org/series/124866/, or proposal is still 
to remove force probe?


Regards,

Tvrtko



  drivers/gpu/drm/i915/i915_pci.c | 1 -
  1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index df7c261410f7..fe748906c06f 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -836,7 +836,6 @@ static const struct intel_device_info mtl_info = {
.has_pxp = 1,
.memory_regions = REGION_SMEM | REGION_STOLEN_LMEM,
.platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(CCS0),
-   .require_force_probe = 1,
MTL_CACHELEVEL,
  };
  


Re: [PATCH v4 0/7] drm: Reuse temporary memory for format conversion

2023-10-10 Thread Maxime Ripard
On Mon, Oct 09, 2023 at 10:23:02AM +0200, Thomas Zimmermann wrote:
> Hi Maxime
> 
> Am 06.10.23 um 16:49 schrieb Maxime Ripard:
> > Hi,
> > 
> > On Thu, Oct 05, 2023 at 11:04:20AM +0200, Thomas Zimmermann wrote:
> > > DRM's format-conversion helpers require temporary memory. Pass the
> > > buffer from the caller and keep it allocated over several calls. Allow
> > > the caller to preallocate the buffer memory.
> > 
> > I'm sorry... but why? Why do you need to keep it allocated over several
> > calls and preallocate the buffer? It's not clear to me at all.
> >
> > > The motivation for this patchset is the recent work on a DRM panic
> > > handler. [1] The panic handler requires format conversion to display an
> > > error to the screen. But allocating memory during kernel panics is
> > > fragile.
> > 
> > We agree that we shouldn't allocate memory during the panic. I still
> > have concerns about how the panic handler will handle the driver
> > currently set up for a plane that isn't using an RGB format, or a buffer
> > not accessible by the kernel or CPU.
> > 
> > You can't expect to get away with just a copy to the current active
> > buffer.
> 
> In our current design, the panic handler calls get_scanout_buffer from
> struct drm_driver to retrieve a scanout buffer. What happens within that
> callback depends on the driver and hardware. Here are some of the expected
> scenarios:
> 
>  * simpledrm or ofdrm can return the firmware-provided scanout buffer. No
> further action is required.
> 
>  * Devices on a PCI-like bus:
>  * With a working mode in RGB colors, drivers can return the current
> scanout buffer as well.

Nothing guarantees that this is true. Even if in RGB, the buffer could
be unaccessible by the CPU, or still in an opaque format (when using
AFBC for example).

>  * Without a working mode, drivers likely attempt to program a common
> display mode with RGB colors.

Which would potentially require extra allocations, computations, etc.
that probably aren't doable in a panic handler path.

>  * Drivers for devices behind other busses, such as USB, will probably not
> be able to reprogram during a panic or provide a useful scanout buffer at
> all.
> 
>  * The scanout buffer has to be mapped into kernel address space. This
> operation might be fragile during a panic. So drivers could set aside a
> slice of graphics memory and pre-map it; then use it during panic (requires
> some mode programming).
> 
> I expect that we will eventually have helpers for the various scenarios.
> Drivers will be able to implement their get_scanout_buffer with these
> helpers.

What I'm trying to say is that it's not just about providing new
helpers. Sure, we can make drivers do whatever they want and provide a
scanout buffer. We still have to put that buffer into an active plane at
some point. The current design doesn't provide any way to do that
properly.

That's what I'd like to see addressed, and I will disagree with any
proposal that just ignores it.

> The font glyphs are 1-bit bitmaps. So we have to convert them to the scanout
> buffer's format in any case. We want to use the existing format-conversion
> helpers were possible.
> 
> > 
> > If that's the assumption that underlines that patch series, then I don't
> > know why we need it at all, because that assumption is wrong to begin
> > with, and way too restrictive.
> > 
> > > The changes in this patchset enable the DRM panic handler to
> > > preallocate buffer storage before the panic occurs.
> > > 
> > > As an additonal benefit, drivers can now keep the temporary storage
> > > across multiple updates. Avoiding memory allocation slightly reduces
> > > the CPU overhead of the format helpers.
> > 
> > I'm sorry to go over that again, but you can't write a performance
> > improvement mechanism without some kind of benchmark. kmalloc has
> > built-in caching, why do we absolutely need our own cache on top of it?
> > 
> > If you never measured it, for all we know, we simply don't need it and
> > kmalloc is good enough.
> 
> I'll remove that paragraph if you find it so annoying. Let me just say again
> that overhead is not the primary motivation behind these patches.

I mean, I don't want to sweep the code under the rug but keep it. I want
to know why we need that code in the first place. If there's no reason
then we just shouldn't have that caching at all.

Maxime


signature.asc
Description: PGP signature


[git pull] habanalabs for drm-next-6.7

2023-10-10 Thread Oded Gabbay
Hi Dave, Daniel.

Habanalabs pull request for 6.7.

It's a bit all over the place, a few uapi changes, mostly improvements and
bug fixes.

Notable things are the move to the accel subsystem in the code itself,
meaning we removed the habanalabs class and the code to created device char
and instead we are registering to accel. Also notable is moving some
firmware interface files to include/linux/habanalabs. This is needed as
a pre-requisite for upstreaming the Gaudi2 NIC drivers, which will include
those files.

Full details are in the signed tag.

Thanks,
Oded

The following changes since commit 389af786f92ecdff35883551d54bf4e507ffcccb:

  Merge tag 'drm-intel-next-2023-09-29' of 
git://anongit.freedesktop.org/drm/drm-intel into drm-next (2023-10-04 13:55:19 
+1000)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/ogabbay/linux.git 
tags/drm-habanalabs-next-2023-10-10

for you to fetch changes up to 4db74c0fdeb8138f6438d42a015c5dcdb2e6874c:

  accel/habanalabs/gaudi2: fix spmu mask creation (2023-10-09 12:37:24 +0300)


This tag contains habanalabs driver changes for v6.7.

The notable changes are:

- uAPI changes:
  - Expose tsc clock sampling to better sync clock information in profiler.
  - Enhance engine error reporting in the info ioctl.
  - Block access to the eventfd operations through the control device.
  - Disable the option of the user to register multiple times with the same
offset for timestamp dump by the driver. If a user wants to use the same
offset in the timestamp buffer for different interrupt, it needs to first
de-register the offset.
  - When exporting dma-buf (for p2p), force the user to specify size/offset
in multiples of PAGE_SIZE. This is instead of the driver doing the
rounding to PAGE_SIZE, which has caused the driver to map more memory
than was intended by the user.

- New features and improvements:
  - Complete the move of the driver to the accel subsystem by removing the
custom habanalabs class and major and registering to accel subsystem.
  - Move the firmware interface files to include/linux/habanalabs. This is
a pre-requisite for upstreaming the NIC drivers of Gaudi (as they need to
include those files).
  - Perform device hard-reset upon PCIe AXI drain event to prevent the failure
from cascading to different IP blocks in the SoC. In secured environments,
this is done automatically by the firmware.
  - Print device name when it is removed for better debuggability.
  - Add support for trace of dma map sgtable operations.
  - Optimize handling of user interrupts by splitting the interrupts to two
lists. One list for fast handling and second list for handling with
timestamp recording, which is slower.
  - Prevent double device hard-reset due to 2 adjacent H/W events.
  - Set device status 'malfunction' while in rmmod.

- Firmware related fixes:
  - Extend preboot timeout because preboot loading might take longer than
expected in certain cases.
  - Add a protection mechanism for the Event Queue. In case it is full, the
firmware will be able to notify about it through a dedicated interrupt.
  - Perform device hard-reset in case scrubbing of memory has failed.

- Bug fixes and code cleanups:
  - Small fixes of dma-buf handling in Gaudi2, such as handling an offset != 0,
using the correct exported size, creation of sg table.
  - Fix spmu mask creation.
  - Fix bug in wait for cs completion for decoder workloads.
  - Cleanup Greco name from documentation.
  - Fix bug in recording timestamp during cs completion interrupt handling.
  - Fix CoreSight ETF configuration and flush logic.
  - Fix small bug in hpriv_list handling (the list that contains the private
data per process that opens our device).


Ariel Suller (1):
  accel/habanalabs: update boot status print

Arnd Bergmann (1):
  accel/habanalabs: add missing debugfs function stubs

Benjamin Dotan (3):
  accel/habanalabs/gaudi2 : remove psoc_arc access
  accel/habanalabs: fix ETR/ETF flush logic
  accel/habanalabs: improve etf configuration

Christophe JAILLET (1):
  accel/habanalabs/gaudi2: Fix incorrect string length computation in 
gaudi2_psoc_razwi_get_engines()

Dafna Hirschfeld (5):
  accel/habanalabs: disable events ioctls on control device
  accel/habanalabs: fix inline doc typos
  accel/habanalabs: add fw status SHUTDOWN_PREP
  accel/habanalabs: extend preboot timeout when preboot might take longer
  accel/habanalabs: remove wrong doc for init_phys_pg_pack_from_userptr

Dani Liberman (2):
  accel/habanalabs: handle arc farm razwi
  accel/habanalabs: handle f/w reserved dram space request

David Meriin (1):
  accel/habanalabs: move cpucp interface to linux/habanalabs

Hen Alon (1):
  accel/habanalabs: add tsc clock sampling to c

Re: [PATCH v2] drm/virtio: add definitions for gfxstream and venus capset

2023-10-10 Thread Dmitry Osipenko
Hi,

On 10/10/23 06:25, Huang Rui wrote:
> These definitions are used fro qemu, and qemu imports this marco in the
> headers to enable gfxstream or venus for virtio gpu. So it should add it
> even kernel doesn't use this.
> 
> Signed-off-by: Huang Rui 
> ---
> 
> Changes V1 -> V2:
> - Add all capsets including gfxstream and venus in kernel header (Dmitry 
> Osipenko)
> 
> v1: https://lore.kernel.org/lkml/20230915105918.3763061-1-ray.hu...@amd.com/
> 
>  include/uapi/linux/virtio_gpu.h | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h
> index f556fde07b76..327792658bdc 100644
> --- a/include/uapi/linux/virtio_gpu.h
> +++ b/include/uapi/linux/virtio_gpu.h
> @@ -309,6 +309,8 @@ struct virtio_gpu_cmd_submit {
>  
>  #define VIRTIO_GPU_CAPSET_VIRGL 1
>  #define VIRTIO_GPU_CAPSET_VIRGL2 2
> +#define VIRTIO_GPU_CAPSET_GFXSTREAM 3
> +#define VIRTIO_GPU_CAPSET_VENUS 4
>  
>  /* VIRTIO_GPU_CMD_GET_CAPSET_INFO */
>  struct virtio_gpu_get_capset_info {

By the "all" capsets, I meant to pick up all definitions from crosvm.
There should be VIRTIO_GPU_CAPSET_DRM at minimum, could you please add it?

-- 
Best regards,
Dmitry



Re: [PATCH v3 1/9] vgacon: rework Kconfig dependencies

2023-10-10 Thread Geert Uytterhoeven
Hi Arnd,

On Mon, Oct 9, 2023 at 11:19 PM Arnd Bergmann  wrote:
> From: Arnd Bergmann 
>
> The list of dependencies here is phrased as an opt-out, but this is missing
> a lot of architectures that don't actually support VGA consoles, and some
> of the entries are stale:
>
>  - powerpc used to support VGA consoles in the old arch/ppc codebase, but
>the merged arch/powerpc never did
>
>  - arm lists footbridge, integrator and netwinder, but netwinder is actually
>part of footbridge, and integrator does not appear to have an actual
>VGA hardware, or list it in its ATAG or DT.
>
>  - mips has a few platforms (malta, sibyte, and sni) that initialize
>screen_info, on everything else the console is selected but cannot
>actually work.
>
>  - csky, hexgagon, loongarch, nios2, riscv and xtensa are not listed
>in the opt-out table and declare a screen_info to allow building
>vga_con, but this cannot work because the console is never selected.
>
> Replace this with an opt-in table that lists only the platforms that
> remain. This is effectively x86, plus a couple of historic workstation
> and server machines that reused parts of the x86 system architecture.
>
> Reviewed-by: Javier Martinez Canillas 
> Reviewed-by: Thomas Zimmermann 
> Reviewed-by: Khalid Aziz 
> Acked-by: Helge Deller 
> Signed-off-by: Arnd Bergmann 

Thanks for your patch!

Reviewed-by: Geert Uytterhoeven 

A few suggestions for simplification below...

> --- a/drivers/video/console/Kconfig
> +++ b/drivers/video/console/Kconfig
> @@ -7,9 +7,9 @@ menu "Console display driver support"
>
>  config VGA_CONSOLE
> bool "VGA text console" if EXPERT || !X86
> -   depends on !4xx && !PPC_8xx && !SPARC && !M68K && !PARISC &&  !SUPERH 
> && \
> -   (!ARM || ARCH_FOOTBRIDGE || ARCH_INTEGRATOR || 
> ARCH_NETWINDER) && \
> -   !ARM64 && !ARC && !MICROBLAZE && !OPENRISC && !S390 && !UML
> +   depends on ALPHA || IA64 || X86 || \
> +   (ARM && ARCH_FOOTBRIDGE) || \

You can drop "ARM &&", as it is implied by ARCH_FOOTBRIDGE.

> +   (MIPS && (MIPS_MALTA || SIBYTE_BCM112X || SIBYTE_SB1250 || 
> SIBYTE_BCM1x80 || SNI_RM))

Likewise for "MIPS &&".

The 3 SIBYTE dependencies can be replaced by SIBYTE_SB1xxx_SOC.

> select APERTURE_HELPERS if (DRM || FB || VFIO_PCI_CORE)
> default y
> help

Gr{oetje,eeting}s,

Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds


Re: [PATCH v5 2/7] drm/atomic-helper: Add format-conversion state to shadow-plane state

2023-10-10 Thread Javier Martinez Canillas
Maxime Ripard  writes:

> On Mon, Oct 09, 2023 at 04:22:29PM +0200, Javier Martinez Canillas wrote:
>> Thomas Zimmermann  writes:
>> > Store an instance of struct drm_format_conv_state in the shadow-plane
>> > state struct drm_shadow_plane_state. Many drivers with shadow planes
>> > use DRM's format helpers to copy or convert the framebuffer data to
>> > backing storage in the scanout buffer. The shadow plane provides the
>> > necessary state and manages the conversion's intermediate buffer memory.
>> >
>> 
>> I would argue this is one of the primary selling points for this series
>> (since Maxime was asking about the motivation). As you point out, many
>> drivers that use a shadow-buffer can also expose a different format than
>> the native one to user-space, so makes sense to have the buffer used for
>> conversion as a part of the shadow-plane state.
>
> I'm confused, can we convert between formats or not? Or is it about
> XRGB vs whatever native format is used by the device?
>

It is about the latter, converting XRGB to the native format.

-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat



Re: [PATCH v2] drm/virtio: add definitions for gfxstream and venus capset

2023-10-10 Thread Huang Rui
On Tue, Oct 10, 2023 at 06:20:03PM +0800, Dmitry Osipenko wrote:
> Hi,
> 
> On 10/10/23 06:25, Huang Rui wrote:
> > These definitions are used fro qemu, and qemu imports this marco in the
> > headers to enable gfxstream or venus for virtio gpu. So it should add it
> > even kernel doesn't use this.
> > 
> > Signed-off-by: Huang Rui 
> > ---
> > 
> > Changes V1 -> V2:
> > - Add all capsets including gfxstream and venus in kernel header (Dmitry 
> > Osipenko)
> > 
> > v1: https://lore.kernel.org/lkml/20230915105918.3763061-1-ray.hu...@amd.com/
> > 
> >  include/uapi/linux/virtio_gpu.h | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/include/uapi/linux/virtio_gpu.h 
> > b/include/uapi/linux/virtio_gpu.h
> > index f556fde07b76..327792658bdc 100644
> > --- a/include/uapi/linux/virtio_gpu.h
> > +++ b/include/uapi/linux/virtio_gpu.h
> > @@ -309,6 +309,8 @@ struct virtio_gpu_cmd_submit {
> >  
> >  #define VIRTIO_GPU_CAPSET_VIRGL 1
> >  #define VIRTIO_GPU_CAPSET_VIRGL2 2
> > +#define VIRTIO_GPU_CAPSET_GFXSTREAM 3
> > +#define VIRTIO_GPU_CAPSET_VENUS 4
> >  
> >  /* VIRTIO_GPU_CMD_GET_CAPSET_INFO */
> >  struct virtio_gpu_get_capset_info {
> 
> By the "all" capsets, I meant to pick up all definitions from crosvm.
> There should be VIRTIO_GPU_CAPSET_DRM at minimum, could you please add it?
> 

Sure. Thanks for the reminder.

Best Regards,
Ray


Re: [Intel-gfx] [PATCH] drm/i915/mtl: Remove the 'force_probe' requirement for Meteor Lake

2023-10-10 Thread Andi Shyti
Hi Tvrtko,

> > Meteor Lake has demonstrated consistent stability for some time.
> > All user-space API modifications tide to its core platform
> > functions are operational.
> > 
> > The necessary firmware components are set up and comprehensive
> > testing has been condused over a period.
> > 
> > Given the recent faborable CI results, as well, we believe it's
> > time to eliminate the 'force_probe' prerequisite and activate the
> > platform by default.
> > 
> > Signed-off-by: Aditya Chauhan 
> > Signed-off-by: Andrzej Hajda 
> > Signed-off-by: Chris Wilson 
> > Signed-off-by: Janusz Krzysztofik 
> > Signed-off-by: Jonathan Cavitt 
> > Signed-off-by: Nirmoy Das 
> > Signed-off-by: Radhakrishna Sripada 
> > Signed-off-by: Andi Shyti 
> > Cc: Jani Nikula 
> > Cc: Joonas Lahtinen 
> > Cc: Rodrigo Vivi 
> > Cc: Tvrtko Ursulin 
> > ---
> > Hello,
> > 
> > This patch eliminates the 'force probe' for the MTL platforms. Over the 
> > recent
> > weeks, MTL has demonstrated stability, consistently passing BAT tests with
> > success rates ranging from 98% to 100%.
> > 
> > There's a single issue hindering us from achieving a 100% BAT test coverage.
> > Fortunately, we've identified the issue, and the proposed solution can be 
> > found
> > here[*]. The CI results are encouraging.
> > 
> > Once all reviews are addressed, we plan to submit this series with the 
> > "Fixes:"
> > tag.
> > 
> > Thank you and best regards,
> > Andi and Radhakrishna
> > 
> > [*] https://patchwork.freedesktop.org/series/124744/
> 
> Have there been any more recent developments, given
> https://patchwork.freedesktop.org/series/124866/, or proposal is still to
> remove force probe?

I think that patch is functional to the force_probe removal
because it would have been the fix we needed in order to have a
full 100% green CI results.

But unfortunately, the patch doesn't fix it. I think the GuC TLB
invalidation is still the best fix.

Andi


Re: [v1 1/2] drm/panel: ili9882t: Break out as separate driver

2023-10-10 Thread cong yang
Thanks for the review,I will modify these in V2.

On Tue, Oct 10, 2023 at 4:44 AM Doug Anderson  wrote:
>
> Hi,
>
> On Fri, Oct 6, 2023 at 11:07 PM Cong Yang
>  wrote:
> >
> > From: Linus Walleij 
> >
> > The Starry ILI9882t-based panel should never have been part of the boe
> > tv101wum driver, it is clearly based on the Ilitek ILI9882t display
> > controller and if you look at the custom command sequences for the
> > panel these clearly contain the signature Ilitek page switch (0xff)
> > commands. The hardware has nothing in common with the other panels
> > supported by this driver.
> >
> > Break this out into a separate driver and config symbol instead.
> >
> > If the placement here is out of convenience for using similar code,
> > we should consider creating a helper library instead.
> >
> > Signed-off-by: Linus Walleij 
> > Signed-off-by: Cong Yang 
> > ---
> >  drivers/gpu/drm/panel/Kconfig |   9 +
> >  drivers/gpu/drm/panel/Makefile|   1 +
> >  .../gpu/drm/panel/panel-boe-tv101wum-nl6.c| 371 -
> >  drivers/gpu/drm/panel/panel-ilitek-ili9882t.c | 752 ++
> >  4 files changed, 762 insertions(+), 371 deletions(-)
> >  create mode 100644 drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
> >
> > diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
> > index ecb22ea326cb..99e14dc212ec 100644
> > --- a/drivers/gpu/drm/panel/Kconfig
> > +++ b/drivers/gpu/drm/panel/Kconfig
> > @@ -203,6 +203,15 @@ config DRM_PANEL_ILITEK_ILI9881C
> >   Say Y if you want to enable support for panels based on the
> >   Ilitek ILI9881c controller.
> >
> > +config DRM_PANEL_ILITEK_ILI9882T
> > +   tristate "Ilitek ILI9882t-based panels"
> > +   depends on OF
> > +   depends on DRM_MIPI_DSI
> > +   depends on BACKLIGHT_CLASS_DEVICE
> > +   help
> > + Say Y if you want to enable support for panels based on the
> > + Ilitek ILI9882t controller.
>
> We'll of course run into the same problem we always run into when
> Kconfig symbols get renamed or broken apart: people will have to know
> to update their configs to include this. Not much we can do about it,
> though. :-/ optional: I guess you could theoretically also include an
> extra patch in your series to 'arch/arm64/configs/defconfig' enabling
> this new config, since the old panel was enabled there...
>
>
> > diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c 
> > b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
> > new file mode 100644
> > index ..bbfcffe65623
> > --- /dev/null
> > +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
> > @@ -0,0 +1,752 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Panels based on the Ilitek ILI9882T display controller.
> > + */
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +
> > +/*
> > + * Use this descriptor struct to describe different panels using the
> > + * Ilitek ILI9882T display controller.
> > + */
> > +struct panel_desc {
> > +   const struct drm_display_mode *modes;
> > +   unsigned int bpc;
> > +
> > +   /**
> > +* @width_mm: width of the panel's active display area
> > +* @height_mm: height of the panel's active display area
> > +*/
> > +   struct {
> > +   unsigned int width_mm;
> > +   unsigned int height_mm;
> > +   } size;
> > +
> > +   unsigned long mode_flags;
> > +   enum mipi_dsi_pixel_format format;
> > +   const struct panel_init_cmd *init_cmds;
> > +   unsigned int init_cmd_length;
>
> Why do you need 'init_cmd_length'? It seems like an arbitrary
> difference between the two drivers. Your 'panel_init_cmd' in the new
> driver still ends with a 0-length command so just use that so you
> don't need to store the length.
>
>
> > +/* ILI9882-specific commands, add new commands as you decode them */
> > +#define ILI9882T_DCS_SWITCH_PAGE   0xFF
> > +
> > +static const struct panel_init_cmd starry_ili9882t_init_cmd[] = {
> > +   _INIT_DELAY_CMD(5),
> > +   _INIT_DCS_CMD(ILI9882T_DCS_SWITCH_PAGE, 0x98, 0x82, 0x01),
>
> Slightly cleaner, can you do:
>
> #define _INIT_SWITCH_PAGE_CMD(page) \
>   _INIT_DCS_CMD(ILI9882T_DCS_SWITCH_PAGE, 0x98, 0x82, (page))
>
> Then in your array you can use stuff like
>
> _INIT_SWITCH_PAGE_CMD(0x01);
>
>
> > +static int ili9882t_prepare(struct drm_panel *panel)
> > +{
> > +   struct ili9882t *ili = to_ili9882t(panel);
> > +   struct mipi_dsi_device *dsi = ili->dsi;
> > +   int i, ret;
> > +
> > +   gpiod_set_value(ili->enable_gpio, 0);
> > +   usleep_range(1000, 1500);
> > +
> > +   ret = regulator_enable(ili->pp3300);
> > +   if (ret < 0)
> > +   return ret;
> > +
> > +   ret = regulator_enable(ili->pp1800);
> > +   if (ret < 0)
> > +   return ret;
> > +
> 

Re: [PATCH v4 2/4] drm/panic: Add a drm panic handler

2023-10-10 Thread Noralf Trønnes



On 10/10/23 11:25, Maxime Ripard wrote:
> 
> 
> On Tue, Oct 10, 2023 at 10:55:09AM +0200, Thomas Zimmermann wrote:
 So if I understand correctly, drm_panic would pre-allocate a plane/commit,
 and use that when a panic occurs ?
>>>
>>> And have it checked already, yes. We would only wait for a panic to
>>> happen to pull the trigger on the commit.
>>>
 I have two concern about this approach:
 - How much memory would be allocated for this ? a whole framebuffer can be
 big for just this use case.
>>
>> As I outlined in my email at [1], there are a number of different scenarios.
>> The question of atomic state and commits is entirely separate from the DRM
>> panic handler. We should not throw them together. Whatever is necessary is
>> get a scanout buffer, should happen on the driver side of
>> get_scanout_buffer, not on the drm_panic side.
>>
>> [1] 
>> https://lore.kernel.org/dri-devel/39bd4c35-8a61-42ee-8675-ccea4f5d4...@suse.de/T/#m22f116e9438e00a5f0a9dc43987d4153424f8be1
>>
>>>
>>> I'dd expect a whole framebuffer for the current
>>> configuration/resolution. It would be typically 4MB for a full-HD system
>>> which isn't a lot really and I guess we can always add an option to
>>> disable the mechanism if needed.
>>>
 - I find it risky to completely reconfigure the hardware in a panic 
 handler.
>>>
>>> I would expect to only change the format and base address of the
>>> framebuffer. I guess it can fail, but it doesn't seem that different to
>>> the async plane update we already have and works well.
>>
>> The one thing I don't understand is: Why should we use atomic commits in the
>> first place? It doesn't make sense for firmware-based drivers.
> 
> Because this is generic infrastructure that is valuable for any drivers
> and not only firmware-based drivers?
> 
>> In some drivers, even the simple ast, we hold locks during the regular
>> commit. Trying to run the panic commit concurrently will likely give a
>> deadlock.
> 
> You're in the middle of a panic. Don't take any locks and you won't deadlock.
> 
>> In the end it's a per-driver decision, but in most cases, the driver can
>> easily switch to a default mode with some ad-hoc code.
> 
> When was the last time a per-driver decision has been a good thing? I'm
> sorry, but the get_scanout_buffer approach buffer won't work for any
> driver out there.
> 
> I'm fine with discussing alternatives if you don't like the ones I
> suggested, but they must allow the panic handler infrastructure to work
> with any driver we have, not just 4.
> 

Why can't we use the model[1] suggested by Daniel using a draw_pixel
callback giving drivers full control on how they can put a pixel on the
display?

This will even work for the AMD debug interface.
In the linear CPU accessible buffer case, we can provide a helper for
that, maybe we can do helpers for other common cases as well.

Adding to that we would need a panic_setup/enter and panic_teardown/exit
callback.

Noralf.

[1]
https://lore.kernel.org/dri-devel/20160810091529.GQ6232@phenom.ffwll.local/


Re: [v1 2/2] drm/panel: ili9882t: Avoid blurred screen from fast sleep

2023-10-10 Thread cong yang
Hi,

On Tue, Oct 10, 2023 at 4:44 AM Doug Anderson  wrote:
>
> Hi,
>
> On Fri, Oct 6, 2023 at 11:07 PM Cong Yang
>  wrote:
> >
> > At present, we have found that there may be a problem of blurred
> > screen during fast sleep/resume. The direct cause of the blurred
> > screen is that the IC does not receive 0x28/0x10. Because of the
> > particularity of the IC, before the panel enters sleep hid must
> > stop scanning, i2c_hid_core_suspend before ili9882t_disable.
> > This doesn't look very spec-compliant.
>
> Presumably you could be more spec compliant if we used
> "panel_follower" in this case? Would that be a better solution?

In the "panel_follower" solution, the phenomenon is the same.
The current order is
ili9882t_disable=>i2c_hid_core_suspend=>elan_i2c_hid_power_down=>ili9882t_unprepare,
ili9882t need touchpanel stop scanning,i2c_hid_core_suspend before
ili9882t_disable.
>
>
> > So in order to solve this
> > problem, the IC can handle it through the exception mechanism when
> > it cannot receive 0X28/0X10 command. Handling exceptions requires a reset
> > 50ms delay. Refer to vendor detailed analysis [1].
> >
> > Ilitek vendor also suggested switching the page before entering sleep to
> > avoid panel IC not receiving 0x28/0x10 command.
> >
> > Note: 0x28 is display off, 0x10 is sleep in.
> >
> > [1]: 
> > https://github.com/ILITEK-LoganLin/Document/tree/main/ILITEK_Power_Sequence
> >
> > Signed-off-by: Cong Yang 
> > ---
> >  drivers/gpu/drm/panel/panel-ilitek-ili9882t.c | 21 ++-
> >  1 file changed, 20 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c 
> > b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
> > index bbfcffe65623..0a1dd987b204 100644
> > --- a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
> > +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
> > @@ -423,6 +423,23 @@ static inline struct ili9882t *to_ili9882t(struct 
> > drm_panel *panel)
> > return container_of(panel, struct ili9882t, base);
> >  }
> >
> > +static int ili9882t_switch_page(struct mipi_dsi_device *dsi, u8 page)
> > +{
> > +   u8 switch_cmd[] = {0x98, 0x82, 0x00};
>
> Can't you just replace the last 0x00 above with "page" and get rid of
> the manual assignment below?
>
>
> > +   int ret;
> > +
> > +   switch_cmd[2] = page;
> > +
> > +   ret = mipi_dsi_dcs_write(dsi, ILI9882T_DCS_SWITCH_PAGE, switch_cmd, 
> > 3);
>
> Instead of hardcoding 3, should use ARRAY_SIZE().
>
>
> > +   if (ret) {
> > +   dev_err(&dsi->dev,
> > +   "error switching panel controller page (%d)\n", 
> > ret);
> > +   return ret;
> > +   }
> > +
> > +   return 0;
> > +}
>
> optional: It feels like it would be nice to somehow use the
> "_INIT_SWITCH_PAGE_CMD" macro I suggested in patch #1 instead of
> having to hardcode 0x98, 0x82 again. In patch #1 I already suggested
> breaking out the function to send a sequence of commands. If you had
> that function take a pointer instead of hardcoding it to look at
> ->init_cmds then you could probably use the same function that you do
> at init time?
>
>
> >  static int ili9882t_enter_sleep_mode(struct ili9882t *ili)
> >  {
> > struct mipi_dsi_device *dsi = ili->dsi;
> > @@ -444,8 +461,10 @@ static int ili9882t_enter_sleep_mode(struct ili9882t 
> > *ili)
> >  static int ili9882t_disable(struct drm_panel *panel)
> >  {
> > struct ili9882t *ili = to_ili9882t(panel);
> > +   struct mipi_dsi_device *dsi = ili->dsi;
> > int ret;
> >
> > +   ili9882t_switch_page(dsi, 0x00);
> > ret = ili9882t_enter_sleep_mode(ili);
> > if (ret < 0) {
> > dev_err(panel->dev, "failed to set panel off: %d\n", ret);
> > @@ -507,7 +526,7 @@ static int ili9882t_prepare(struct drm_panel *panel)
> > gpiod_set_value(ili->enable_gpio, 1);
> > usleep_range(1000, 2000);
> > gpiod_set_value(ili->enable_gpio, 0);
> > -   usleep_range(1000, 2000);
> > +   usleep_range(4, 5);
>
> nit: use 4, 41000 instead of 4, 5. Linux almost always
> uses the longer delay, so that'll save ~9 ms. The only reason for the
> range is to optimize kernel wakeups which is really not a concern
> here.

We need 50ms delay to meet the requirement.


Re: [PATCH] drm/atomic: Perform blocking commits on workqueue

2023-10-10 Thread Daniel Vetter
On Thu, Oct 05, 2023 at 01:16:27PM +0300, Ville Syrjälä wrote:
> On Thu, Oct 05, 2023 at 11:57:41AM +0200, Daniel Vetter wrote:
> > On Tue, Sep 26, 2023 at 01:05:49PM -0400, Ray Strode wrote:
> > > From: Ray Strode 
> > > 
> > > A drm atomic commit can be quite slow on some hardware. It can lead
> > > to a lengthy queue of commands that need to get processed and waited
> > > on before control can go back to user space.
> > > 
> > > If user space is a real-time thread, that delay can have severe
> > > consequences, leading to the process getting killed for exceeding
> > > rlimits.
> > > 
> > > This commit addresses the problem by always running the slow part of
> > > a commit on a workqueue, separated from the task initiating the
> > > commit.
> > > 
> > > This change makes the nonblocking and blocking paths work in the same way,
> > > and as a result allows the task to sleep and not use up its
> > > RLIMIT_RTTIME allocation.
> > > 
> > > Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2861
> > > Signed-off-by: Ray Strode 
> > 
> > So imo the trouble with this is that we suddenly start to make
> > realtime/cpu usage guarantees in the atomic ioctl. That's a _huge_ uapi
> > change, because even limited to the case of !ALLOW_MODESET we do best
> > effort guarantees at best. And some drivers (again amd's dc) spend a ton
> > of cpu time recomputing state even for pure plane changes without any crtc
> > changes like dpms on/off (at least I remember some bug reports about
> > that). And that state recomputation has to happen synchronously, because
> > it always influences the ioctl errno return value.
> > 
> > My take is that you're papering over a performance problem here of the
> > "the driver is too slow/wastes too much cpu time". We should fix the
> > driver, if that's possible.
> > 
> > Another option would be if userspace drops realtime priorities for these
> > known-slow operations. And right now _all_ kms operations are potentially
> > cpu and real-time wasters, the entire uapi is best effort.
> > 
> > We can also try to change the atomic uapi to give some hard real-time
> > guarantees so that running compositors as SCHED_RT is possible, but that
> > - means a very serious stream of bugs to fix all over
> > - therefore needs some very wide buy-in from drivers that they're willing
> >   to make this guarantee
> > - probably needs some really carefully carved out limitations, because
> >   there's imo flat-out no way we'll make all atomic ioctl hard time limit
> >   bound
> > 
> > Also, as König has pointed out, you can roll this duct-tape out in
> > userspace by making the commit non-blocking and immediately waiting for
> > the fences.
> > 
> > One thing I didn't see mention is that there's a very subtle uapi
> > difference between non-blocking and blocking:
> > - non-blocking is not allowed to get ahead of the previous commit, and
> >   will return EBUSY in that case. See the comment in
> >   drm_atomic_helper_commit()
> > - blocking otoh will just block until any previous pending commit has
> >   finished
> > 
> > Not taking that into account in your patch here breaks uapi because
> > userspace will suddenly get EBUSY when they don't expect that.
> 
> The -EBUSY logic already checks whether the current commit is
> non-blocking vs. blocking commit, so I don't see how there would
> be any change in behaviour from simply stuffing the commit_tail
> onto a workqueue, especially as the locks will be still held across
> the flush.

Hm right, I forgot the patch context when I was chasing the EBUSY logic, I
thought it just pushed a nonblocking commit in somehow.

> In my earlier series [1] where I move the flush to happen after dropping
> the locks there is a far more subtle issue because currently even
> non-blocking commits can actually block due to the mutex. Changing
> that might break something, so I preserved that behaviour explicitly.
> Full explanation in the first patch there.
> 
> [1] https://patchwork.freedesktop.org/series/108668/

Yeah there's a can of tricky details here for sure ...
-Sima
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Re: [PATCH] drm/atomic: Perform blocking commits on workqueue

2023-10-10 Thread Daniel Vetter
On Mon, Oct 09, 2023 at 02:36:17PM +0200, Christian König wrote:
> Am 09.10.23 um 14:19 schrieb Ville Syrjälä:
> > On Mon, Oct 09, 2023 at 08:42:24AM +0200, Christian König wrote:
> > > Am 06.10.23 um 20:48 schrieb Ray Strode:
> > > > Hi,
> > > > 
> > > > On Fri, Oct 6, 2023 at 3:12 AM Christian König 
> > > >  wrote:
> > > > > When the operation busy waits then that *should* get accounted to the
> > > > > CPU time of the current process. When the operation sleeps and waits 
> > > > > for
> > > > > some interrupt for example it should not get accounted.
> > > > > What you suggest is to put the parts of the operation which busy wait
> > > > > into a background task and then sleep for that task to complete. This 
> > > > > is
> > > > > not a solution to the problem, but just hides it.
> > > > Actually, I think we both probably agree that there shouldn't be long
> > > > busy waits in the context of the current process. After all, we both
> > > > agree what the AMD DC driver code is doing is wrong.
> > > > 
> > > > To be clear, my take is, if driver code is running in process context
> > > > and needs to wait for periods of time on the order of or in excess of
> > > > a typical process time slice it should be sleeping during the waiting.
> > > > If the operation is at a point where it can be cancelled without side
> > > > effects, the sleeping should be INTERRUPTIBLE. If it's past the point
> > > > of no return, sleeping should be UNINTERRUPTIBLE. At no point, in my
> > > > opinion, should kernel code busy block a typical process for dozens of
> > > > milliseconds while keeping the process RUNNING. I don't think this is
> > > > a controversial take.
> > > Exactly that's what I completely disagree on.
> > > 
> > > When the driver is burning CPU cycles on behalves of a process then
> > > those CPU cycles should be accounted to the process causing this.
> > > 
> > > That the driver should probably improve it's behavior is a different 
> > > issue.
> > > 
> > > > Actually, I think (maybe?) you might even agree with that, but you're
> > > > also saying: user space processes aren't special here. While it's not
> > > > okay to busy block them, it's also not okay to busy block on the
> > > > system unbound workqueue either. If that's your sentiment, I don't
> > > > disagree with it.
> > > No, it's absolutely ok to busy block them it's just not nice to do so.
> > > 
> > > As Daniel pointed out this behavior is not incorrect at all. The DRM
> > > subsystem doesn't make any guarantee that drmModeAtomicCommit() will not
> > > burn CPU cycles.
> > > 
> > > > So I think we both agree the busy waiting is a problem, but maybe we
> > > > disagree on the best place for the problem to manifest when it
> > > > happens.
> > > > 
> > > > One thought re the DC code is regardless of where the code is running,
> > > > the scheduler is going to forcefully preempt it at some point right?
> > > > Any writereg/udelay(1)/readreg loop is going to get disrupted by a
> > > > much bigger than 1us delay by the kernel if the loop goes on long
> > > > enough. I'm not wrong about that? if that's true, the code might as
> > > > well switch out the udelay(1) for a usleep(1) and call it a day (well
> > > > modulo the fact I think it can be called from an interrupt handler; at
> > > > least "git grep" says there's a link_set_dpms_off in
> > > > link_dp_irq_handler.c)
> > > > 
> > > > > Stuff like that is not a valid justification for the change. Ville
> > > > > changes on the other hand tried to prevent lock contention which is a
> > > > > valid goal here.
> > > > Okay so let's land his patchset! (assuming it's ready to go in).
> > > > Ville, is that something you'd want to resend for review?
> > > Well, while Ville patch has at least some justification I would still
> > > strongly object to move the work into a background thread to prevent
> > > userspace from being accounted for the work it causes.
> > Aren't most wayland compositors using nonblocking commits anyway?
> > If so they would already be bypassing proper CPU time accounting.
> > Not saying we shouldn't try to fix that, but just pointing out that
> > it already is an issue with nonblocking commits.
> 
> That's a rather good argument, but for async operations background work is
> simply a necessity because you otherwise can't implement them.

Yeah I don't think we can use "we need to properly account" stuff to
reject this, because we don't. Also we already do fail with inheriting the
priority properly, so another nail in the "kms is best effort".

> The key point here is that the patch puts the work into the background just
> to avoid that it is accounted to the thread issuing it, and that in turn is
> not valid as far as I can see.

Yeah it's that aspect I'm really worried about, because we essentially
start to support some gurantees that a) most drivers can't uphold without
a huge amount of work, some of the DC state recomputations are _really_
expensive b) without actually making the sem

Re: [PATCH] video: fbdev: arkfb: fix possible object reference leak

2023-10-10 Thread Daniel Vetter
On Fri, Oct 06, 2023 at 04:34:01PM +0200, Ondrej Zary wrote:
> On Friday 06 October 2023, Helge Deller wrote:
> > On 10/5/23 09:01, Zhang Shurong wrote:
> > > Add missing pci_disable_device() in error path in ark_pci_probe().
> > 
> > Do you have this hardware and tested your patch?
> > I'm sure there is a reason, why "pci_disable_device()" was commented
> > out in the original submission in commit 681e14730c73c...
> 
> pci_disable_device() call is disabled in many fbdev drivers because
> calling it might prevent display from working.

Yeah I've recently hit some _really_ interesting regression report where
essentially fbdev driver and vgacon where managing the hardware
collaboratively. There's enormous amounts of "this shouldn't work like
that, but it is how it does" going on in old fbdev drivers, and what you
brought up is also what I immediately thought of.

This patch feels way too risky to me that we should apply it ...
-Sima

> 
> > 
> > Additionally I'm wondering why your patch doesn't show up in
> > the fbdev patchwork, although you added linux-fbdev mailing list.
> > Probably a vger issue.
> > 
> > Helge
> > 
> > 
> > > Signed-off-by: Zhang Shurong 
> > > ---
> > >   drivers/video/fbdev/arkfb.c | 4 ++--
> > >   1 file changed, 2 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/video/fbdev/arkfb.c b/drivers/video/fbdev/arkfb.c
> > > index 60a96fdb5dd8..6c4e5065646f 100644
> > > --- a/drivers/video/fbdev/arkfb.c
> > > +++ b/drivers/video/fbdev/arkfb.c
> > > @@ -1064,7 +1064,7 @@ static int ark_pci_probe(struct pci_dev *dev, const 
> > > struct pci_device_id *id)
> > >   err_dac:
> > >   pci_release_regions(dev);
> > >   err_request_regions:
> > > -/*   pci_disable_device(dev); */
> > > + pci_disable_device(dev);
> > >   err_enable_device:
> > >   framebuffer_release(info);
> > >   return rc;
> > > @@ -1085,7 +1085,7 @@ static void ark_pci_remove(struct pci_dev *dev)
> > >
> > >   pci_iounmap(dev, info->screen_base);
> > >   pci_release_regions(dev);
> > > -/*   pci_disable_device(dev); */
> > > + pci_disable_device(dev);
> > >
> > >   framebuffer_release(info);
> > >   }
> > 
> > 
> 
> 
> 
> -- 
> Ondrej Zary

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Re: [PATCH v3 0/9] video: screen_info cleanups

2023-10-10 Thread Daniel Vetter
On Mon, Oct 09, 2023 at 11:18:36PM +0200, Arnd Bergmann wrote:
> From: Arnd Bergmann 
> 
> v3 changelog
> 
> No real changes, just rebased for context changes, and picked up the Acks.
> 
> This now conflicts with the ia64 removal and introduces one new dependency
> on IA64, but that is harmless and trivial to deal with later.
> 
> Link: https://lore.kernel.org/lkml/20230719123944.3438363-1-a...@kernel.org/
> ---
> v2 changelog
> 
> I refreshed the first four patches that I sent before with very minor
> updates, and then added some more to further disaggregate the use
> of screen_info:
> 
>  - I found that powerpc wasn't using vga16fb any more
> 
>  - vgacon can be almost entirely separated from the global
>screen_info, except on x86
> 
>  - similarly, the EFI framebuffer initialization can be
>kept separate, except on x86.
> 
> I did extensive build testing on arm/arm64/x86 and the normal built bot
> testing for the other architectures.
> 
> Which tree should this get merged through?

I guess if no one else volunteers (Greg maybe?) I can stuff this into
drm-misc ...
-Sima

> 
> Link: https://lore.kernel.org/lkml/20230707095415.1449376-1-a...@kernel.org/
> 
> 
> Arnd Bergmann (9):
>   vgacon: rework Kconfig dependencies
>   vgacon: rework screen_info #ifdef checks
>   dummycon: limit Arm console size hack to footbridge
>   vgacon, arch/*: remove unused screen_info definitions
>   vgacon: remove screen_info dependency
>   vgacon: clean up global screen_info instances
>   vga16fb: drop powerpc support
>   hyperv: avoid dependency on screen_info
>   efi: move screen_info into efi init code
> 
>  arch/alpha/kernel/proto.h |  2 +
>  arch/alpha/kernel/setup.c |  8 +--
>  arch/alpha/kernel/sys_sio.c   |  8 ++-
>  arch/arm/include/asm/setup.h  |  5 ++
>  arch/arm/kernel/atags_parse.c | 20 +++---
>  arch/arm/kernel/efi.c |  6 --
>  arch/arm/kernel/setup.c   | 11 +--
>  arch/arm64/kernel/efi.c   |  4 --
>  arch/arm64/kernel/image-vars.h|  2 +
>  arch/csky/kernel/setup.c  | 12 
>  arch/hexagon/kernel/Makefile  |  2 -
>  arch/hexagon/kernel/screen_info.c |  3 -
>  arch/ia64/kernel/setup.c  | 53 ---
>  arch/loongarch/kernel/efi.c   |  3 +-
>  arch/loongarch/kernel/image-vars.h|  2 +
>  arch/loongarch/kernel/setup.c |  3 -
>  arch/mips/jazz/setup.c|  9 ---
>  arch/mips/kernel/setup.c  | 11 ---
>  arch/mips/mti-malta/malta-setup.c |  4 +-
>  arch/mips/sibyte/swarm/setup.c| 26 ---
>  arch/mips/sni/setup.c | 18 ++---
>  arch/nios2/kernel/setup.c |  5 --
>  arch/powerpc/kernel/setup-common.c| 16 -
>  arch/riscv/kernel/image-vars.h|  2 +
>  arch/riscv/kernel/setup.c | 12 
>  arch/sh/kernel/setup.c|  5 --
>  arch/sparc/kernel/setup_32.c  | 13 
>  arch/sparc/kernel/setup_64.c  | 13 
>  arch/x86/kernel/setup.c   |  2 +-
>  arch/xtensa/kernel/setup.c| 12 
>  drivers/firmware/efi/efi-init.c   | 14 +++-
>  drivers/firmware/efi/libstub/efi-stub-entry.c |  8 ++-
>  drivers/firmware/pcdp.c   |  1 -
>  drivers/gpu/drm/hyperv/hyperv_drm_drv.c   |  7 +-
>  drivers/hv/vmbus_drv.c|  6 +-
>  drivers/video/console/Kconfig | 11 +--
>  drivers/video/console/dummycon.c  |  2 +-
>  drivers/video/console/vgacon.c| 68 +++
>  drivers/video/fbdev/Kconfig   |  2 +-
>  drivers/video/fbdev/hyperv_fb.c   |  8 +--
>  drivers/video/fbdev/vga16fb.c |  9 +--
>  include/linux/console.h   |  7 ++
>  42 files changed, 183 insertions(+), 252 deletions(-)
>  delete mode 100644 arch/hexagon/kernel/screen_info.c
> 
> -- 
> 2.39.2
> 
> Cc: "David S. Miller" 
> Cc: "K. Y. Srinivasan" 
> Cc: Ard Biesheuvel 
> Cc: Borislav Petkov 
> Cc: Brian Cain 
> Cc: Catalin Marinas 
> Cc: Christophe Leroy 
> Cc: Daniel Vetter 
> Cc: Dave Hansen 
> Cc: David Airlie 
> Cc: Deepak Rawat 
> Cc: Dexuan Cui 
> Cc: Dinh Nguyen 
> Cc: Greg Kroah-Hartman 
> Cc: Guo Ren 
> Cc: Haiyang Zhang 
> Cc: Helge Deller 
> Cc: Huacai Chen 
> Cc: Ingo Molnar 
> Cc: Javier Martinez Canillas 
> Cc: John Paul Adrian Glaubitz 
> Cc: Khalid Aziz 
> Cc: Linus Walleij 
> Cc: Matt Turner 
> Cc: Max Filippov 
> Cc: Michael Ellerman 
> Cc: Nicholas Piggin 
> Cc: Palmer Dabbelt 
> Cc: Russell King 
> Cc: Thomas Bogendoerfer 
> Cc: Thomas Gleixner 
> Cc: Thomas Zimmermann 
> Cc: WANG Xuerui 
> Cc: Wei Liu 
> Cc: Will Deacon 
> Cc: x...@kernel.org
> Cc: li

[v2 0/3] Break out as separate driver from boe-tv101wum-nl6 panel driver

2023-10-10 Thread Cong Yang
Linus series proposed to break out ili9882t as separate driver, 
but he didn't have time for that extensive rework of the driver.
As discussed by Linus and Doug [1], keep macro using the "struct panel_init_cmd"
until we get some resolution about the binary size issue.

[1]: 
https://lore.kernel.org/all/20230703-fix-boe-tv101wum-nl6-v3-0-bd6e9432c...@linaro.org

Changes in v2:
- PATCH 1/3: fix Doug comments,define "_INIT_SWITCH_PAGE_CMD" and remove the 
"shutdown".
- PATCH 2/3: Modify ili9882t_switch_page function instead of hardcoding.
- PATCH 3/3: Enable new config in defconfig.
- Link to v1: 
https://lore.kernel.org/all/20231007060639.725350-1-yangco...@huaqin.corp-partner.google.com/

Cong Yang (3):
  drm/panel: ili9882t: Break out as separate driver
  drm/panel: ili9882t: Avoid blurred screen from fast sleep
  arm64: defconfig: Enable ILITEK_ILI9882T panel

 arch/arm64/configs/defconfig  |   1 +
 drivers/gpu/drm/panel/Kconfig |   9 +
 drivers/gpu/drm/panel/Makefile|   1 +
 .../gpu/drm/panel/panel-boe-tv101wum-nl6.c| 371 -
 drivers/gpu/drm/panel/panel-ilitek-ili9882t.c | 782 ++
 5 files changed, 793 insertions(+), 371 deletions(-)
 create mode 100644 drivers/gpu/drm/panel/panel-ilitek-ili9882t.c

-- 
2.25.1



[v2 1/3] drm/panel: ili9882t: Break out as separate driver

2023-10-10 Thread Cong Yang
The Starry ILI9882t-based panel should never have been part of the boe
tv101wum driver, it is clearly based on the Ilitek ILI9882t display
controller and if you look at the custom command sequences for the
panel these clearly contain the signature Ilitek page switch (0xff)
commands. The hardware has nothing in common with the other panels
supported by this driver.

Break this out into a separate driver and config symbol instead.

If the placement here is out of convenience for using similar code,
we should consider creating a helper library instead.

Co-developed-by: Linus Walleij 
Signed-off-by: Linus Walleij 
Reviewed-by: Linus Walleij 
Signed-off-by: Cong Yang 
---
 drivers/gpu/drm/panel/Kconfig |   9 +
 drivers/gpu/drm/panel/Makefile|   1 +
 .../gpu/drm/panel/panel-boe-tv101wum-nl6.c| 371 -
 drivers/gpu/drm/panel/panel-ilitek-ili9882t.c | 762 ++
 4 files changed, 772 insertions(+), 371 deletions(-)
 create mode 100644 drivers/gpu/drm/panel/panel-ilitek-ili9882t.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index ecb22ea326cb..99e14dc212ec 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -203,6 +203,15 @@ config DRM_PANEL_ILITEK_ILI9881C
  Say Y if you want to enable support for panels based on the
  Ilitek ILI9881c controller.
 
+config DRM_PANEL_ILITEK_ILI9882T
+   tristate "Ilitek ILI9882t-based panels"
+   depends on OF
+   depends on DRM_MIPI_DSI
+   depends on BACKLIGHT_CLASS_DEVICE
+   help
+ Say Y if you want to enable support for panels based on the
+ Ilitek ILI9882t controller.
+
 config DRM_PANEL_INNOLUX_EJ030NA
 tristate "Innolux EJ030NA 320x480 LCD panel"
 depends on OF && SPI
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index e14ce55a0875..d10c3de51c6d 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_DRM_PANEL_HIMAX_HX8394) += panel-himax-hx8394.o
 obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o
 obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9341) += panel-ilitek-ili9341.o
 obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o
+obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9882T) += panel-ilitek-ili9882t.o
 obj-$(CONFIG_DRM_PANEL_INNOLUX_EJ030NA) += panel-innolux-ej030na.o
 obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o
 obj-$(CONFIG_DRM_PANEL_JADARD_JD9365DA_H3) += panel-jadard-jd9365da-h3.o
diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c 
b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
index 5ac926281d2c..4f370bc6dca8 100644
--- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
+++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
@@ -1370,346 +1370,6 @@ static const struct panel_init_cmd 
starry_himax83102_j02_init_cmd[] = {
{},
 };
 
-static const struct panel_init_cmd starry_ili9882t_init_cmd[] = {
-   _INIT_DELAY_CMD(5),
-   _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x01),
-   _INIT_DCS_CMD(0x00, 0x42),
-   _INIT_DCS_CMD(0x01, 0x11),
-   _INIT_DCS_CMD(0x02, 0x00),
-   _INIT_DCS_CMD(0x03, 0x00),
-
-   _INIT_DCS_CMD(0x04, 0x01),
-   _INIT_DCS_CMD(0x05, 0x11),
-   _INIT_DCS_CMD(0x06, 0x00),
-   _INIT_DCS_CMD(0x07, 0x00),
-
-   _INIT_DCS_CMD(0x08, 0x80),
-   _INIT_DCS_CMD(0x09, 0x81),
-   _INIT_DCS_CMD(0x0A, 0x71),
-   _INIT_DCS_CMD(0x0B, 0x00),
-
-   _INIT_DCS_CMD(0x0C, 0x00),
-   _INIT_DCS_CMD(0x0E, 0x1A),
-
-   _INIT_DCS_CMD(0x24, 0x00),
-   _INIT_DCS_CMD(0x25, 0x00),
-   _INIT_DCS_CMD(0x26, 0x00),
-   _INIT_DCS_CMD(0x27, 0x00),
-
-   _INIT_DCS_CMD(0x2C, 0xD4),
-   _INIT_DCS_CMD(0xB9, 0x40),
-
-   _INIT_DCS_CMD(0xB0, 0x11),
-
-   _INIT_DCS_CMD(0xE6, 0x32),
-   _INIT_DCS_CMD(0xD1, 0x30),
-
-   _INIT_DCS_CMD(0xD6, 0x55),
-
-   _INIT_DCS_CMD(0xD0, 0x01),
-   _INIT_DCS_CMD(0xE3, 0x93),
-   _INIT_DCS_CMD(0xE4, 0x00),
-   _INIT_DCS_CMD(0xE5, 0x80),
-
-   _INIT_DCS_CMD(0x31, 0x07),
-   _INIT_DCS_CMD(0x32, 0x07),
-   _INIT_DCS_CMD(0x33, 0x07),
-   _INIT_DCS_CMD(0x34, 0x07),
-   _INIT_DCS_CMD(0x35, 0x07),
-   _INIT_DCS_CMD(0x36, 0x01),
-   _INIT_DCS_CMD(0x37, 0x00),
-   _INIT_DCS_CMD(0x38, 0x28),
-   _INIT_DCS_CMD(0x39, 0x29),
-   _INIT_DCS_CMD(0x3A, 0x11),
-   _INIT_DCS_CMD(0x3B, 0x13),
-   _INIT_DCS_CMD(0x3C, 0x15),
-   _INIT_DCS_CMD(0x3D, 0x17),
-   _INIT_DCS_CMD(0x3E, 0x09),
-   _INIT_DCS_CMD(0x3F, 0x0D),
-   _INIT_DCS_CMD(0x40, 0x02),
-   _INIT_DCS_CMD(0x41, 0x02),
-   _INIT_DCS_CMD(0x42, 0x02),
-   _INIT_DCS_CMD(0x43, 0x02),
-   _INIT_DCS_CMD(0x44, 0x02),
-   _INIT_DCS_CMD(0x45, 0x02),
-   _INIT_DCS_CMD(0x46, 0x02),
-
-   _INIT_DCS_CMD(0x47, 0x07),
-   _INIT_DCS_CMD(0x48, 0x07),
-   _INIT_DCS_CMD(0x49, 0x07),
-   _INIT_DCS_CMD(0x4A, 0x07),
-   _INIT_

[v2 2/3] drm/panel: ili9882t: Avoid blurred screen from fast sleep

2023-10-10 Thread Cong Yang
At present, we have found that there may be a problem of blurred
screen during fast sleep/resume. The direct cause of the blurred
screen is that the IC does not receive 0x28/0x10. Because of the
particularity of the IC, before the panel enters sleep hid must
stop scanning, i2c_hid_core_suspend before ili9882t_disable.
This doesn't look very spec-compliant. So in order to solve this
problem, the IC can handle it through the exception mechanism when
it cannot receive 0X28/0X10 command. Handling exceptions requires a reset
50ms delay. Refer to vendor detailed analysis [1].

Ilitek vendor also suggested switching the page before entering sleep to
avoid panel IC not receiving 0x28/0x10 command.

Note: 0x28 is display off, 0x10 is sleep in.

[1]: https://github.com/ILITEK-LoganLin/Document/tree/main/ILITEK_Power_Sequence

Signed-off-by: Cong Yang 
---
 drivers/gpu/drm/panel/panel-ilitek-ili9882t.c | 22 ++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c 
b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
index e095ad91c4bc..20ae370ebe2f 100644
--- a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
@@ -465,6 +465,24 @@ static int ili9882t_init_dcs_cmd(struct ili9882t *ili)
return 0;
 }
 
+static int ili9882t_switch_page(struct mipi_dsi_device *dsi, u8 page)
+{
+   int ret;
+   const struct panel_init_cmd cmd = _INIT_SWITCH_PAGE_CMD(page);
+
+   ret = mipi_dsi_dcs_write(dsi, cmd.data[0],
+cmd.len <= 1 ? NULL :
+&cmd.data[1],
+cmd.len - 1);
+   if (ret) {
+   dev_err(&dsi->dev,
+   "error switching panel controller page (%d)\n", ret);
+   return ret;
+   }
+
+   return 0;
+}
+
 static int ili9882t_enter_sleep_mode(struct ili9882t *ili)
 {
struct mipi_dsi_device *dsi = ili->dsi;
@@ -486,8 +504,10 @@ static int ili9882t_enter_sleep_mode(struct ili9882t *ili)
 static int ili9882t_disable(struct drm_panel *panel)
 {
struct ili9882t *ili = to_ili9882t(panel);
+   struct mipi_dsi_device *dsi = ili->dsi;
int ret;
 
+   ili9882t_switch_page(dsi, 0x00);
ret = ili9882t_enter_sleep_mode(ili);
if (ret < 0) {
dev_err(panel->dev, "failed to set panel off: %d\n", ret);
@@ -548,7 +568,7 @@ static int ili9882t_prepare(struct drm_panel *panel)
gpiod_set_value(ili->enable_gpio, 1);
usleep_range(1000, 2000);
gpiod_set_value(ili->enable_gpio, 0);
-   usleep_range(1000, 2000);
+   usleep_range(4, 5);
gpiod_set_value(ili->enable_gpio, 1);
usleep_range(6000, 1);
 
-- 
2.25.1



[v2 3/3] arm64: defconfig: Enable ILITEK_ILI9882T panel

2023-10-10 Thread Cong Yang
Enable ILITEK_ILI9882T panel.

Signed-off-by: Cong Yang 
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 0777bcae9104..c3453dcbad3e 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -813,6 +813,7 @@ CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
 CONFIG_DRM_PANEL_LVDS=m
 CONFIG_DRM_PANEL_SIMPLE=m
 CONFIG_DRM_PANEL_EDP=m
+CONFIG_DRM_PANEL_ILITEK_ILI9882T=m
 CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m
 CONFIG_DRM_PANEL_RAYDIUM_RM67191=m
 CONFIG_DRM_PANEL_SITRONIX_ST7703=m
-- 
2.25.1



Re: [PATCH v4 2/4] drm/panic: Add a drm panic handler

2023-10-10 Thread Maxime Ripard
On Tue, Oct 10, 2023 at 01:29:52PM +0200, Noralf Trønnes wrote:
> 
> 
> On 10/10/23 11:25, Maxime Ripard wrote:
> > 
> > 
> > On Tue, Oct 10, 2023 at 10:55:09AM +0200, Thomas Zimmermann wrote:
>  So if I understand correctly, drm_panic would pre-allocate a 
>  plane/commit,
>  and use that when a panic occurs ?
> >>>
> >>> And have it checked already, yes. We would only wait for a panic to
> >>> happen to pull the trigger on the commit.
> >>>
>  I have two concern about this approach:
>  - How much memory would be allocated for this ? a whole framebuffer can 
>  be
>  big for just this use case.
> >>
> >> As I outlined in my email at [1], there are a number of different 
> >> scenarios.
> >> The question of atomic state and commits is entirely separate from the DRM
> >> panic handler. We should not throw them together. Whatever is necessary is
> >> get a scanout buffer, should happen on the driver side of
> >> get_scanout_buffer, not on the drm_panic side.
> >>
> >> [1] 
> >> https://lore.kernel.org/dri-devel/39bd4c35-8a61-42ee-8675-ccea4f5d4...@suse.de/T/#m22f116e9438e00a5f0a9dc43987d4153424f8be1
> >>
> >>>
> >>> I'dd expect a whole framebuffer for the current
> >>> configuration/resolution. It would be typically 4MB for a full-HD system
> >>> which isn't a lot really and I guess we can always add an option to
> >>> disable the mechanism if needed.
> >>>
>  - I find it risky to completely reconfigure the hardware in a panic 
>  handler.
> >>>
> >>> I would expect to only change the format and base address of the
> >>> framebuffer. I guess it can fail, but it doesn't seem that different to
> >>> the async plane update we already have and works well.
> >>
> >> The one thing I don't understand is: Why should we use atomic commits in 
> >> the
> >> first place? It doesn't make sense for firmware-based drivers.
> > 
> > Because this is generic infrastructure that is valuable for any drivers
> > and not only firmware-based drivers?
> > 
> >> In some drivers, even the simple ast, we hold locks during the regular
> >> commit. Trying to run the panic commit concurrently will likely give a
> >> deadlock.
> > 
> > You're in the middle of a panic. Don't take any locks and you won't 
> > deadlock.
> > 
> >> In the end it's a per-driver decision, but in most cases, the driver can
> >> easily switch to a default mode with some ad-hoc code.
> > 
> > When was the last time a per-driver decision has been a good thing? I'm
> > sorry, but the get_scanout_buffer approach buffer won't work for any
> > driver out there.
> > 
> > I'm fine with discussing alternatives if you don't like the ones I
> > suggested, but they must allow the panic handler infrastructure to work
> > with any driver we have, not just 4.
> > 
> 
> Why can't we use the model[1] suggested by Daniel using a draw_pixel
> callback giving drivers full control on how they can put a pixel on the
> display?

I share kind of the same general ideas/conclusions: "qthe idea is that
all the fb selection and lookup is handled in shared code (and with
proper locking, but only for atomic drivers)."

2016 is a bit old though and multiple developments happened since
(secure playback is a thing now, framebuffer compression too), so I
still think that their expectation that the framebuffer is accessible to
/ writable by the CPU no longer holds true.

> This will even work for the AMD debug interface.
> In the linear CPU accessible buffer case, we can provide a helper for
> that, maybe we can do helpers for other common cases as well.

Yeah, their idea of a panic_draw would work great for that.

> Adding to that we would need a panic_setup/enter and panic_teardown/exit
> callback.

What for?

Maxime


signature.asc
Description: PGP signature


[PATCH RESEND v2 0/2] Add drm_dbg_ratelimited()

2023-10-10 Thread Andi Shyti
Hi,

I might have picked up the wrong series and missed some reviews
and the extra patch from Nirmoy with a real use of the
drm_dbg_ratelimited() that John was looking for.

Thanks,
Andi

v2:
pick the right patch with the following changes:
 - add more r-b's
 - add a patch 2 where the drm_dbg_ratelimited is actually used.

Nirmoy Das (2):
  drm/print: Add drm_dbg_ratelimited
  drm/i915: Ratelimit debug log in vm_fault_ttm

 drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 5 +++--
 include/drm/drm_print.h | 3 +++
 2 files changed, 6 insertions(+), 2 deletions(-)

-- 
2.40.1



[PATCH v4 1/2] dt-bindings: backlight: Add MPS MP3309C

2023-10-10 Thread Flavio Suligoi
The Monolithic Power (MPS) MP3309C is a WLED step-up converter, featuring a
programmable switching frequency to optimize efficiency.
The brightness can be controlled either by I2C commands (called "analog"
mode) or by a PWM input signal (PWM mode).
This driver supports both modes.

For device driver details, please refer to:
- drivers/video/backlight/mp3309c_bl.c

The datasheet is available at:
- https://www.monolithicpower.com/en/mp3309c.html

Signed-off-by: Flavio Suligoi 
---

v4:
 - remove not more used allOf keyword
 - add brightness-levels and default-brightness properties
 - remove max-brightness and default-brightness from required properties
 - update example, adding brightness-levels and default-brightness properties
v3:
 - add default value for mps,overvoltage-protection-microvolt property
 - fix the example, changing from "mps,mp3309c-backlight" to "mps,mp3309c" in
   compatible property
v2:
 - remove useless properties (dimming-mode, pinctrl-names, pinctrl-0,
   switch-on-delay-ms, switch-off-delay-ms, reset-gpios, reset-on-delay-ms,
   reset-on-length-ms)
 - add common.yaml#
 - remove already included properties (default-brightness, max-brightness)
 - substitute three boolean properties, used for the overvoltage-protection
   values, with a single enum property
 - remove some conditional definitions
 - remove the 2nd example
v1:
 - first version

 .../bindings/leds/backlight/mps,mp3309c.yaml  | 82 +++
 1 file changed, 82 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/leds/backlight/mps,mp3309c.yaml

diff --git a/Documentation/devicetree/bindings/leds/backlight/mps,mp3309c.yaml 
b/Documentation/devicetree/bindings/leds/backlight/mps,mp3309c.yaml
new file mode 100644
index ..e2f9ae2b3fb4
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/backlight/mps,mp3309c.yaml
@@ -0,0 +1,82 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/backlight/mps,mp3309c.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MPS MP3309C backlight
+
+maintainers:
+  - Flavio Suligoi 
+
+description: |
+  The Monolithic Power (MPS) MP3309C is a WLED step-up converter, featuring a
+  programmable switching frequency to optimize efficiency.
+  It supports two different dimming modes:
+
+  - analog mode, via I2C commands, as default mode (32 dimming levels)
+  - PWM controlled mode (optional)
+
+  The datasheet is available at:
+  https://www.monolithicpower.com/en/mp3309c.html
+
+properties:
+  compatible:
+const: mps,mp3309c
+
+  reg:
+maxItems: 1
+
+  pwms:
+description: if present, the backlight is controlled in PWM mode.
+maxItems: 1
+
+  enable-gpios:
+description: GPIO used to enable the backlight in "analog-i2c" dimming 
mode.
+maxItems: 1
+
+  brightness-levels:
+description:
+  Array of distinct brightness levels, in PWM dimming mode.
+  Typically these are in the range from 0 to 255, but any range starting
+  at 0 will do.
+  The 0 value means a 0% duty cycle (darkest/off), while the last value in
+  the array represents a 100% duty cycle (brightest).
+$ref: /schemas/types.yaml#/definitions/uint32-array
+
+  default-brightness:
+description:
+  The default brightness (index into the levels array).
+$ref: /schemas/types.yaml#/definitions/uint32
+
+  mps,overvoltage-protection-microvolt:
+description: Overvoltage protection (13.5V, 24V or 35.5V).
+enum: [ 1350, 2400, 3550 ]
+default: 3550
+
+  mps,no-sync-mode:
+description: disable synchronous rectification mode
+type: boolean
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+i2c {
+#address-cells = <1>;
+#size-cells = <0>;
+
+/* Backlight with PWM control */
+backlight_pwm: backlight@17 {
+compatible = "mps,mp3309c";
+reg = <0x17>;
+pwms = <&pwm1 0 333 0>; /* 300 Hz --> (1/f) * 1*10^9 */
+brightness-levels = <0 1 2 3 4 5 6 7 8 9 10>;
+default-brightness = <8>;
+mps,overvoltage-protection-microvolt = <2400>;
+};
+};
-- 
2.34.1



[PATCH RESEND v2 1/2] drm/print: Add drm_dbg_ratelimited

2023-10-10 Thread Andi Shyti
From: Nirmoy Das 

Add a function for ratelimitted debug print.

Signed-off-by: Nirmoy Das 
Cc: Maarten Lankhorst 
Cc: Maxime Ripard 
Cc: Thomas Zimmermann 
Cc: David Airlie 
Cc: Daniel Vetter 
Reviewed-by: Matthew Auld 
Reviewed-by: Andrzej Hajda 
Reviewed-by: Andi Shyti 
Reviewed-by: Sam Ravnborg 
Signed-off-by: Andi Shyti 
---
 include/drm/drm_print.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index a93a387f8a1a..ad77ac4b6808 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -602,6 +602,9 @@ void __drm_err(const char *format, ...);
drm_dev_printk(drm_ ? drm_->dev : NULL, KERN_DEBUG, fmt, ## 
__VA_ARGS__);   \
 })
 
+#define drm_dbg_ratelimited(drm, fmt, ...) \
+   __DRM_DEFINE_DBG_RATELIMITED(DRIVER, drm, fmt, ## __VA_ARGS__)
+
 #define drm_dbg_kms_ratelimited(drm, fmt, ...) \
__DRM_DEFINE_DBG_RATELIMITED(KMS, drm, fmt, ## __VA_ARGS__)
 
-- 
2.40.1



[PATCH v4 2/2] backlight: mp3309c: Add support for MPS MP3309C

2023-10-10 Thread Flavio Suligoi
The Monolithic Power (MPS) MP3309C is a WLED step-up converter, featuring a
programmable switching frequency to optimize efficiency.
The brightness can be controlled either by I2C commands (called "analog"
mode) or by a PWM input signal (PWM mode).
This driver supports both modes.

For DT configuration details, please refer to:
- Documentation/devicetree/bindings/leds/backlight/mps,mp3309c.yaml

The datasheet is available at:
- https://www.monolithicpower.com/en/mp3309c.html

Signed-off-by: Flavio Suligoi 
---

v4:
 - add brightness-levels property
 - force fixed 32 brightness levels (0..31) in analog-i2c dimming mode
 - remove useless irq and reset_gpio from mp3309c_chip structure
v3:
 - fix SPDX obsolete spelling
 - in mp3309c_bl_update_status, change from msleep_interruptible() to msleep()
   and improve the related comment
v2:
 - fix dependecies in Kconfig
 - fix Kconfig MP3309C entry order
 - remove switch-on-delay-ms property
 - remove optional gpio property to reset external devices
 - remove dimming-mode property (the analog-i2c dimming mode is the default; the
   presence of the pwms property, in DT, selects automatically the pwm dimming
   mode)
 - substitute three boolean properties, used for the overvoltage-protection
   values, with a single enum property
 - drop simple tracing messages
 - use dev_err_probe() in probe function
 - change device name from mp3309c_bl to the simple mp3309c
 - remove shutdown function
v1:
 - first version

 MAINTAINERS   |   6 +
 drivers/video/backlight/Kconfig   |  11 +
 drivers/video/backlight/Makefile  |   1 +
 drivers/video/backlight/mp3309c.c | 443 ++
 4 files changed, 461 insertions(+)
 create mode 100644 drivers/video/backlight/mp3309c.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 3be1bdfe8ecc..f779df433af1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14333,6 +14333,12 @@ S: Maintained
 F: Documentation/driver-api/tty/moxa-smartio.rst
 F: drivers/tty/mxser.*
 
+MP3309C BACKLIGHT DRIVER
+M: Flavio Suligoi 
+S: Maintained
+F: Documentation/devicetree/bindings/leds/backlight/mps,mp3309c.yaml
+F: drivers/video/backlight/mp3309c.c
+
 MR800 AVERMEDIA USB FM RADIO DRIVER
 M: Alexey Klimov 
 L: linux-me...@vger.kernel.org
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 51387b1ef012..1144a54a35c0 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -402,6 +402,17 @@ config BACKLIGHT_LP8788
help
  This supports TI LP8788 backlight driver.
 
+config BACKLIGHT_MP3309C
+   tristate "Backlight Driver for MPS MP3309C"
+   depends on I2C && PWM
+   select REGMAP_I2C
+   help
+ This supports MPS MP3309C backlight WLED driver in both PWM and
+ analog/I2C dimming modes.
+
+ To compile this driver as a module, choose M here: the module will
+ be called mp3309c.
+
 config BACKLIGHT_PANDORA
tristate "Backlight driver for Pandora console"
depends on TWL4030_CORE
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index f72e1c3c59e9..1af583de665b 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_BACKLIGHT_LP855X)+= lp855x_bl.o
 obj-$(CONFIG_BACKLIGHT_LP8788) += lp8788_bl.o
 obj-$(CONFIG_BACKLIGHT_LV5207LP)   += lv5207lp.o
 obj-$(CONFIG_BACKLIGHT_MAX8925)+= max8925_bl.o
+obj-$(CONFIG_BACKLIGHT_MP3309C)+= mp3309c.o
 obj-$(CONFIG_BACKLIGHT_MT6370) += mt6370-backlight.o
 obj-$(CONFIG_BACKLIGHT_OMAP1)  += omap1_bl.o
 obj-$(CONFIG_BACKLIGHT_PANDORA)+= pandora_bl.o
diff --git a/drivers/video/backlight/mp3309c.c 
b/drivers/video/backlight/mp3309c.c
new file mode 100644
index ..3fe4469ef43f
--- /dev/null
+++ b/drivers/video/backlight/mp3309c.c
@@ -0,0 +1,443 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Driver for MPS MP3309C White LED driver with I2C interface
+ *
+ * This driver support both analog (by I2C commands) and PWM dimming control
+ * modes.
+ *
+ * Copyright (C) 2023 ASEM Srl
+ * Author: Flavio Suligoi 
+ *
+ * Based on pwm_bl.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define REG_I2C_0  0x00
+#define REG_I2C_1  0x01
+
+#define REG_I2C_0_EN   0x80
+#define REG_I2C_0_D0   0x40
+#define REG_I2C_0_D1   0x20
+#define REG_I2C_0_D2   0x10
+#define REG_I2C_0_D3   0x08
+#define REG_I2C_0_D4   0x04
+#define REG_I2C_0_RSRV10x02
+#define REG_I2C_0_RSRV20x01
+
+#define REG_I2C_1_RSRV10x80
+#define REG_I2C_1_DIMS 0x40
+#define REG_I2C_1_SYNC 0x20
+#define REG_I2C_1_OVP0 0x10
+#define REG_I2C_1_OVP1 0x08
+#define REG_I2C_1_VOS  0x04
+#define REG_I2C_1_LEDO 0x02
+#define REG_I2C_1_OTP  0x01
+
+#define ANALOG_I2C_NUM_LEVELS  32  /* 0..31 */
+#define ANALOG_I2C_REG_MASK0x7c

[PATCH RESEND v2 2/2] drm/i915: Ratelimit debug log in vm_fault_ttm

2023-10-10 Thread Andi Shyti
From: Nirmoy Das 

Test like i915_gem_mman_live_selftests/igt_mmap_migrate can cause
dmesg spamming. Use ratelimit api to reduce log rate.

References: https://gitlab.freedesktop.org/drm/intel/-/issues/7038
Signed-off-by: Nirmoy Das 
Cc: Matthew Auld 
Reviewed-by: Matthew Auld 
Reviewed-by: Andrzej Hajda 
Reviewed-by: Andi Shyti 
Signed-off-by: Andi Shyti 
---
 drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c 
b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
index 9227f8146a58..6b69ef0cdbb4 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
@@ -1101,8 +1101,9 @@ static vm_fault_t vm_fault_ttm(struct vm_fault *vmf)
}
 
if (err) {
-   drm_dbg(dev, "Unable to make resource CPU 
accessible(err = %pe)\n",
-   ERR_PTR(err));
+   drm_dbg_ratelimited(dev,
+   "Unable to make resource CPU 
accessible(err = %pe)\n",
+   ERR_PTR(err));
dma_resv_unlock(bo->base.resv);
ret = VM_FAULT_SIGBUS;
goto out_rpm;
-- 
2.40.1



Re: [PATCH v3 0/9] video: screen_info cleanups

2023-10-10 Thread Greg Kroah-Hartman
On Tue, Oct 10, 2023 at 01:48:07PM +0200, Daniel Vetter wrote:
> On Mon, Oct 09, 2023 at 11:18:36PM +0200, Arnd Bergmann wrote:
> > From: Arnd Bergmann 
> > 
> > v3 changelog
> > 
> > No real changes, just rebased for context changes, and picked up the Acks.
> > 
> > This now conflicts with the ia64 removal and introduces one new dependency
> > on IA64, but that is harmless and trivial to deal with later.
> > 
> > Link: https://lore.kernel.org/lkml/20230719123944.3438363-1-a...@kernel.org/
> > ---
> > v2 changelog
> > 
> > I refreshed the first four patches that I sent before with very minor
> > updates, and then added some more to further disaggregate the use
> > of screen_info:
> > 
> >  - I found that powerpc wasn't using vga16fb any more
> > 
> >  - vgacon can be almost entirely separated from the global
> >screen_info, except on x86
> > 
> >  - similarly, the EFI framebuffer initialization can be
> >kept separate, except on x86.
> > 
> > I did extensive build testing on arm/arm64/x86 and the normal built bot
> > testing for the other architectures.
> > 
> > Which tree should this get merged through?
> 
> I guess if no one else volunteers (Greg maybe?) I can stuff this into
> drm-misc ...

Oh, hey, console code is for me, I keep forgetting.

I can take it, looks like we have enough acks now, thanks for reminding
me!

greg k-h



Re: [PATCH v4 2/4] drm/panic: Add a drm panic handler

2023-10-10 Thread Daniel Vetter
On Tue, Oct 10, 2023 at 02:15:47PM +0200, Maxime Ripard wrote:
> On Tue, Oct 10, 2023 at 01:29:52PM +0200, Noralf Trønnes wrote:
> > 
> > 
> > On 10/10/23 11:25, Maxime Ripard wrote:
> > > 
> > > 
> > > On Tue, Oct 10, 2023 at 10:55:09AM +0200, Thomas Zimmermann wrote:
> >  So if I understand correctly, drm_panic would pre-allocate a 
> >  plane/commit,
> >  and use that when a panic occurs ?
> > >>>
> > >>> And have it checked already, yes. We would only wait for a panic to
> > >>> happen to pull the trigger on the commit.
> > >>>
> >  I have two concern about this approach:
> >  - How much memory would be allocated for this ? a whole framebuffer 
> >  can be
> >  big for just this use case.
> > >>
> > >> As I outlined in my email at [1], there are a number of different 
> > >> scenarios.
> > >> The question of atomic state and commits is entirely separate from the 
> > >> DRM
> > >> panic handler. We should not throw them together. Whatever is necessary 
> > >> is
> > >> get a scanout buffer, should happen on the driver side of
> > >> get_scanout_buffer, not on the drm_panic side.
> > >>
> > >> [1] 
> > >> https://lore.kernel.org/dri-devel/39bd4c35-8a61-42ee-8675-ccea4f5d4...@suse.de/T/#m22f116e9438e00a5f0a9dc43987d4153424f8be1
> > >>
> > >>>
> > >>> I'dd expect a whole framebuffer for the current
> > >>> configuration/resolution. It would be typically 4MB for a full-HD system
> > >>> which isn't a lot really and I guess we can always add an option to
> > >>> disable the mechanism if needed.
> > >>>
> >  - I find it risky to completely reconfigure the hardware in a panic 
> >  handler.
> > >>>
> > >>> I would expect to only change the format and base address of the
> > >>> framebuffer. I guess it can fail, but it doesn't seem that different to
> > >>> the async plane update we already have and works well.
> > >>
> > >> The one thing I don't understand is: Why should we use atomic commits in 
> > >> the
> > >> first place? It doesn't make sense for firmware-based drivers.
> > > 
> > > Because this is generic infrastructure that is valuable for any drivers
> > > and not only firmware-based drivers?
> > > 
> > >> In some drivers, even the simple ast, we hold locks during the regular
> > >> commit. Trying to run the panic commit concurrently will likely give a
> > >> deadlock.
> > > 
> > > You're in the middle of a panic. Don't take any locks and you won't 
> > > deadlock.
> > > 
> > >> In the end it's a per-driver decision, but in most cases, the driver can
> > >> easily switch to a default mode with some ad-hoc code.
> > > 
> > > When was the last time a per-driver decision has been a good thing? I'm
> > > sorry, but the get_scanout_buffer approach buffer won't work for any
> > > driver out there.
> > > 
> > > I'm fine with discussing alternatives if you don't like the ones I
> > > suggested, but they must allow the panic handler infrastructure to work
> > > with any driver we have, not just 4.
> > > 
> > 
> > Why can't we use the model[1] suggested by Daniel using a draw_pixel
> > callback giving drivers full control on how they can put a pixel on the
> > display?
> 
> I share kind of the same general ideas/conclusions: "qthe idea is that
> all the fb selection and lookup is handled in shared code (and with
> proper locking, but only for atomic drivers)."
> 
> 2016 is a bit old though and multiple developments happened since
> (secure playback is a thing now, framebuffer compression too), so I
> still think that their expectation that the framebuffer is accessible to
> / writable by the CPU no longer holds true.

I think largely it should still be ok, because the idea behind the draw_xy
callback was that the driver could take care of anything special, like
- tiling
- clearing compression bits so that just writing the raw pixels works (if
  your compression format allows for that)
- handling any differences in how the pixels need to be written, like
  cache flushing, mmio_write vs normal memory, amd also has peek/poke
  registers to be able to write even into unmappable memory

What would probably be a good idea is to do an s/void */uinptr_t/ over my
interface proposal, or maybe an even more opaque cookie since really the
only thing you can do is get the void * that ->panic_vmap returns and pass
it into ->panic_draw_xy.

I thought (but I didn't dig through details) that the panic fb struct is
essentially meant to serve this purpose in the current series?

> > This will even work for the AMD debug interface.
> > In the linear CPU accessible buffer case, we can provide a helper for
> > that, maybe we can do helpers for other common cases as well.
> 
> Yeah, their idea of a panic_draw would work great for that.
> 
> > Adding to that we would need a panic_setup/enter and panic_teardown/exit
> > callback.
> 
> What for?

So panic teardown would be for testing in CI, to make it non-destructive
and clean up anything panic_vmap (or _enter or whatever you call it) has
done. I tho

[PATCH v3 00/16] Introduce PMF Smart PC Solution Builder Feature

2023-10-10 Thread Shyam Sundar S K
Smart PC Solutions Builder allows for OEM to define a large number of
custom system states to dynamically switch to. The system states are
referred to as policies, and multiple policies can be loaded onto the
system at any given time, however only one policy can be active at a
given time.

Policy is a combination of PMF input and output capabilities. The inputs
are the incoming information from the other kernel subsystems like LID
state, Sensor info, GPU info etc and the actions are the updating the 
power limits of SMU etc.

The policy binary is signed and encrypted by a special key from AMD. This
policy binary shall have the inputs and outputs which the OEMs can build
for the platform customization that can enhance the user experience and
system behavior.

This series adds the initial support for Smart PC solution to PMF driver.

Note that, on platforms where CnQF and Smart PC is advertised, Smart PC
shall have higher precedence and same applies for Auto Mode.

v2->v3:
-
- Remove pci_get_device() for getting gpu handle
- add .suspend handler for pmf driver
- remove unwanted type caste
- Align comments, spaces etc.
- add wrapper for print_hex_dump_debug()
- Remove lkp tags in commit-msg
- Add macros for magic numbers
- use right format specifiers for printing
- propagate error codes back to the caller
- remove unwanted comments


v1->v2:
-
- Remove __func__ macros
- Remove manual function names inside prints
- Handle tee_shm_get_va() failure
- Remove double _
- Add meaningful prints
- pass amd_pmf_set_dram_addr() failure errors
- Add more information to commit messages
- use right format specifiers
- use devm_ioremap() instead of ioremap()
- address unsigned long vs u32 problems
- Fix lkp reported issues
- Add amd_pmf_remove_pb() to remove the debugfs files created(if any).
- Make amd_pmf_open_pb() as static.
- Add cooling device APIs for controlling amdgpu backlight
- handle amd_pmf_apply_policies() failures
- Split v1 14/15 into 2 patches further
- use linux/units.h for better handling
- add "depends on" AMD_SFH_HID for interaction with SFH
- other cosmetic remarks

Basavaraj Natikar (3):
  HID: amd_sfh: rename float_to_int() to amd_sfh_float_to_int()
  platform/x86/amd/pmf: Add PMF-AMDSFH interface for HPD
  platform/x86/amd/pmf: Add PMF-AMDSFH interface for ALS

Shyam Sundar S K (13):
  platform/x86/amd/pmf: Add PMF TEE interface
  platform/x86/amd/pmf: Add support PMF-TA interaction
  platform/x86/amd/pmf: Change return type of amd_pmf_set_dram_addr()
  platform/x86/amd/pmf: Add support for PMF Policy Binary
  platform/x86/amd/pmf: change amd_pmf_init_features() call sequence
  platform/x86/amd/pmf: Add support to get inputs from other subsystems
  platform/x86/amd/pmf: Add support update p3t limit
  platform/x86/amd/pmf: Add support to update system state
  platform/x86/amd/pmf: Add facility to dump TA inputs
  platform/x86/amd/pmf: Add capability to sideload of policy binary
  platform/x86/amd/pmf: dump policy binary data
  platform/x86/amd/pmf: Add PMF-AMDGPU get interface
  platform/x86/amd/pmf: Add PMF-AMDGPU set interface

 Documentation/admin-guide/index.rst   |   1 +
 Documentation/admin-guide/pmf.rst |  25 +
 drivers/gpu/drm/amd/amdgpu/Makefile   |   2 +
 drivers/gpu/drm/amd/amdgpu/amdgpu.h   |   1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c   | 154 ++
 drivers/hid/amd-sfh-hid/amd_sfh_common.h  |   6 +
 drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c |  22 +-
 drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c |  17 +
 .../amd-sfh-hid/sfh1_1/amd_sfh_interface.c|  48 ++
 .../amd-sfh-hid/sfh1_1/amd_sfh_interface.h|   1 +
 drivers/platform/x86/amd/pmf/Kconfig  |   3 +
 drivers/platform/x86/amd/pmf/Makefile |   3 +-
 drivers/platform/x86/amd/pmf/acpi.c   |  37 ++
 drivers/platform/x86/amd/pmf/core.c   |  68 ++-
 drivers/platform/x86/amd/pmf/pmf.h| 202 +++
 drivers/platform/x86/amd/pmf/spc.c| 197 +++
 drivers/platform/x86/amd/pmf/sps.c|   2 +-
 drivers/platform/x86/amd/pmf/tee-if.c | 507 ++
 include/linux/amd-pmf-io.h|  55 ++
 19 files changed, 1324 insertions(+), 27 deletions(-)
 create mode 100644 Documentation/admin-guide/pmf.rst
 create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c
 create mode 100644 drivers/platform/x86/amd/pmf/spc.c
 create mode 100644 drivers/platform/x86/amd/pmf/tee-if.c
 create mode 100644 include/linux/amd-pmf-io.h

-- 
2.25.1



Re: [PATCH] drm/atomic-helper: relax unregistered connector check

2023-10-10 Thread Simon Ser
Thank you both for the reviews! Some wlroots users have confirmed it
fixes their issues. I've pushed the patch.


[PATCH v3 01/16] platform/x86/amd/pmf: Add PMF TEE interface

2023-10-10 Thread Shyam Sundar S K
AMD PMF driver loads the PMF TA (Trusted Application) into the AMD
ASP's (AMD Security Processor) TEE (Trusted Execution Environment).

PMF Trusted Application is a secured firmware placed under
/lib/firmware/amdtee gets loaded only when the TEE environment is
initialized. Add the initial code path to build these pipes.

Reviewed-by: Mario Limonciello 
Signed-off-by: Shyam Sundar S K 
---
 drivers/platform/x86/amd/pmf/Kconfig  |   1 +
 drivers/platform/x86/amd/pmf/Makefile |   3 +-
 drivers/platform/x86/amd/pmf/core.c   |  10 ++-
 drivers/platform/x86/amd/pmf/pmf.h|  16 
 drivers/platform/x86/amd/pmf/tee-if.c | 105 ++
 5 files changed, 130 insertions(+), 5 deletions(-)
 create mode 100644 drivers/platform/x86/amd/pmf/tee-if.c

diff --git a/drivers/platform/x86/amd/pmf/Kconfig 
b/drivers/platform/x86/amd/pmf/Kconfig
index 3064bc8ea167..32a029e8db80 100644
--- a/drivers/platform/x86/amd/pmf/Kconfig
+++ b/drivers/platform/x86/amd/pmf/Kconfig
@@ -9,6 +9,7 @@ config AMD_PMF
depends on POWER_SUPPLY
depends on AMD_NB
select ACPI_PLATFORM_PROFILE
+   depends on TEE
help
  This driver provides support for the AMD Platform Management 
Framework.
  The goal is to enhance end user experience by making AMD PCs smarter,
diff --git a/drivers/platform/x86/amd/pmf/Makefile 
b/drivers/platform/x86/amd/pmf/Makefile
index fdededf54392..d2746ee7369f 100644
--- a/drivers/platform/x86/amd/pmf/Makefile
+++ b/drivers/platform/x86/amd/pmf/Makefile
@@ -6,4 +6,5 @@
 
 obj-$(CONFIG_AMD_PMF) += amd-pmf.o
 amd-pmf-objs := core.o acpi.o sps.o \
-   auto-mode.o cnqf.o
+   auto-mode.o cnqf.o \
+   tee-if.o
diff --git a/drivers/platform/x86/amd/pmf/core.c 
b/drivers/platform/x86/amd/pmf/core.c
index 78ed3ee22555..d57ed038f0c9 100644
--- a/drivers/platform/x86/amd/pmf/core.c
+++ b/drivers/platform/x86/amd/pmf/core.c
@@ -309,13 +309,13 @@ static void amd_pmf_init_features(struct amd_pmf_dev *dev)
dev_dbg(dev->dev, "SPS enabled and Platform Profiles 
registered\n");
}
 
-   /* Enable Auto Mode */
-   if (is_apmf_func_supported(dev, APMF_FUNC_AUTO_MODE)) {
+   if (amd_pmf_init_smart_pc(dev)) {
+   dev_dbg(dev->dev, "Smart PC Solution Enabled\n");
+   } else if (is_apmf_func_supported(dev, APMF_FUNC_AUTO_MODE)) {
amd_pmf_init_auto_mode(dev);
dev_dbg(dev->dev, "Auto Mode Init done\n");
} else if (is_apmf_func_supported(dev, APMF_FUNC_DYN_SLIDER_AC) ||
  is_apmf_func_supported(dev, APMF_FUNC_DYN_SLIDER_DC)) 
{
-   /* Enable Cool n Quiet Framework (CnQF) */
ret = amd_pmf_init_cnqf(dev);
if (ret)
dev_warn(dev->dev, "CnQF Init failed\n");
@@ -330,7 +330,9 @@ static void amd_pmf_deinit_features(struct amd_pmf_dev *dev)
amd_pmf_deinit_sps(dev);
}
 
-   if (is_apmf_func_supported(dev, APMF_FUNC_AUTO_MODE)) {
+   if (dev->smart_pc_enabled) {
+   amd_pmf_deinit_smart_pc(dev);
+   } else if (is_apmf_func_supported(dev, APMF_FUNC_AUTO_MODE)) {
amd_pmf_deinit_auto_mode(dev);
} else if (is_apmf_func_supported(dev, APMF_FUNC_DYN_SLIDER_AC) ||
  is_apmf_func_supported(dev, APMF_FUNC_DYN_SLIDER_DC)) 
{
diff --git a/drivers/platform/x86/amd/pmf/pmf.h 
b/drivers/platform/x86/amd/pmf/pmf.h
index deba88e6e4c8..bd40458937ba 100644
--- a/drivers/platform/x86/amd/pmf/pmf.h
+++ b/drivers/platform/x86/amd/pmf/pmf.h
@@ -179,6 +179,12 @@ struct amd_pmf_dev {
bool cnqf_enabled;
bool cnqf_supported;
struct notifier_block pwr_src_notifier;
+   /* Smart PC solution builder */
+   struct tee_context *tee_ctx;
+   struct tee_shm *fw_shm_pool;
+   u32 session_id;
+   void *shbuf;
+   bool smart_pc_enabled;
 };
 
 struct apmf_sps_prop_granular {
@@ -389,6 +395,13 @@ struct apmf_dyn_slider_output {
struct apmf_cnqf_power_set ps[APMF_CNQF_MAX];
 } __packed;
 
+struct ta_pmf_shared_memory {
+   int command_id;
+   int resp_id;
+   u32 pmf_result;
+   u32 if_version;
+};
+
 /* Core Layer */
 int apmf_acpi_init(struct amd_pmf_dev *pmf_dev);
 void apmf_acpi_deinit(struct amd_pmf_dev *pmf_dev);
@@ -433,4 +446,7 @@ void amd_pmf_deinit_cnqf(struct amd_pmf_dev *dev);
 int amd_pmf_trans_cnqf(struct amd_pmf_dev *dev, int socket_power, ktime_t 
time_lapsed_ms);
 extern const struct attribute_group cnqf_feature_attribute_group;
 
+/* Smart PC builder Layer */
+int amd_pmf_init_smart_pc(struct amd_pmf_dev *dev);
+void amd_pmf_deinit_smart_pc(struct amd_pmf_dev *dev);
 #endif /* PMF_H */
diff --git a/drivers/platform/x86/amd/pmf/tee-if.c 
b/drivers/platform/x86/amd/pmf/tee-if.c
new file mode 100644
index ..6ec8c3726624
--- /dev/null
+++ b/drivers/platform/x86/amd/pmf/tee-if.c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier:

[PATCH v3 02/16] platform/x86/amd/pmf: Add support PMF-TA interaction

2023-10-10 Thread Shyam Sundar S K
PMF TA (Trusted Application) loads via the TEE environment into the
AMD ASP.

PMF-TA supports two commands:
1) Init: Initialize the TA with the PMF Smart PC policy binary and
start the policy engine. A policy is a combination of inputs and
outputs, where;
 - the inputs are the changing dynamics of the system like the user
   behaviour, system heuristics etc.
 - the outputs, which are the actions to be set on the system which
   lead to better power management and enhanced user experience.

PMF driver acts as a central manager in this case to supply the
inputs required to the TA (either by getting the information from
the other kernel subsystems or from userland)

2) Enact: Enact the output actions from the TA. The action could be
applying a new thermal limit to boost/throttle the power limits or
change system behavior.

Reviewed-by: Mario Limonciello 
Signed-off-by: Shyam Sundar S K 
---
 drivers/platform/x86/amd/pmf/pmf.h| 10 +++
 drivers/platform/x86/amd/pmf/tee-if.c | 97 ++-
 2 files changed, 106 insertions(+), 1 deletion(-)

diff --git a/drivers/platform/x86/amd/pmf/pmf.h 
b/drivers/platform/x86/amd/pmf/pmf.h
index bd40458937ba..4da5c4eb053c 100644
--- a/drivers/platform/x86/amd/pmf/pmf.h
+++ b/drivers/platform/x86/amd/pmf/pmf.h
@@ -59,6 +59,9 @@
 #define ARG_NONE 0
 #define AVG_SAMPLE_SIZE 3
 
+/* TA macros */
+#define PMF_TA_IF_VERSION_MAJOR1
+
 /* AMD PMF BIOS interfaces */
 struct apmf_verify_interface {
u16 size;
@@ -184,6 +187,7 @@ struct amd_pmf_dev {
struct tee_shm *fw_shm_pool;
u32 session_id;
void *shbuf;
+   struct delayed_work pb_work;
bool smart_pc_enabled;
 };
 
@@ -395,6 +399,12 @@ struct apmf_dyn_slider_output {
struct apmf_cnqf_power_set ps[APMF_CNQF_MAX];
 } __packed;
 
+/* cmd ids for TA communication */
+enum ta_pmf_command {
+   TA_PMF_COMMAND_POLICY_BUILDER_INITIALIZE,
+   TA_PMF_COMMAND_POLICY_BUILDER_ENACT_POLICIES,
+};
+
 struct ta_pmf_shared_memory {
int command_id;
int resp_id;
diff --git a/drivers/platform/x86/amd/pmf/tee-if.c 
b/drivers/platform/x86/amd/pmf/tee-if.c
index 6ec8c3726624..4036f435f1e2 100644
--- a/drivers/platform/x86/amd/pmf/tee-if.c
+++ b/drivers/platform/x86/amd/pmf/tee-if.c
@@ -13,9 +13,96 @@
 #include "pmf.h"
 
 #define MAX_TEE_PARAM  4
+
+/* Policy binary actions sampling frequency (in ms) */
+static int pb_actions_ms = MSEC_PER_SEC;
+#ifdef CONFIG_AMD_PMF_DEBUG
+module_param(pb_actions_ms, int, 0644);
+MODULE_PARM_DESC(pb_actions_ms, "Policy binary actions sampling frequency 
(default = 1000ms)");
+#endif
+
 static const uuid_t amd_pmf_ta_uuid = UUID_INIT(0x6fd93b77, 0x3fb8, 0x524d,
0xb1, 0x2d, 0xc5, 0x29, 0xb1, 
0x3d, 0x85, 0x43);
 
+static void amd_pmf_prepare_args(struct amd_pmf_dev *dev, int cmd,
+struct tee_ioctl_invoke_arg *arg,
+struct tee_param *param)
+{
+   memset(arg, 0, sizeof(*arg));
+   memset(param, 0, MAX_TEE_PARAM * sizeof(*param));
+
+   arg->func = cmd;
+   arg->session = dev->session_id;
+   arg->num_params = MAX_TEE_PARAM;
+
+   /* Fill invoke cmd params */
+   param[0].u.memref.size = sizeof(struct ta_pmf_shared_memory);
+   param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT;
+   param[0].u.memref.shm = dev->fw_shm_pool;
+   param[0].u.memref.shm_offs = 0;
+}
+
+static int amd_pmf_invoke_cmd_enact(struct amd_pmf_dev *dev)
+{
+   struct ta_pmf_shared_memory *ta_sm = NULL;
+   struct tee_param param[MAX_TEE_PARAM];
+   struct tee_ioctl_invoke_arg arg;
+   int ret = 0;
+
+   if (!dev->tee_ctx)
+   return -ENODEV;
+
+   ta_sm = dev->shbuf;
+   memset(ta_sm, 0, sizeof(*ta_sm));
+   ta_sm->command_id = TA_PMF_COMMAND_POLICY_BUILDER_ENACT_POLICIES;
+   ta_sm->if_version = PMF_TA_IF_VERSION_MAJOR;
+
+   amd_pmf_prepare_args(dev, TA_PMF_COMMAND_POLICY_BUILDER_ENACT_POLICIES, 
&arg, param);
+
+   ret = tee_client_invoke_func(dev->tee_ctx, &arg, param);
+   if (ret < 0 || arg.ret != 0) {
+   dev_err(dev->dev, "TEE enact cmd failed. err: %x, ret:%d\n", 
arg.ret, ret);
+   return ret;
+   }
+
+   return 0;
+}
+
+static int amd_pmf_invoke_cmd_init(struct amd_pmf_dev *dev)
+{
+   struct ta_pmf_shared_memory *ta_sm = NULL;
+   struct tee_param param[MAX_TEE_PARAM];
+   struct tee_ioctl_invoke_arg arg;
+   int ret = 0;
+
+   if (!dev->tee_ctx) {
+   dev_err(dev->dev, "Failed to get TEE context\n");
+   return -ENODEV;
+   }
+
+   ta_sm = dev->shbuf;
+   ta_sm->command_id = TA_PMF_COMMAND_POLICY_BUILDER_INITIALIZE;
+   ta_sm->if_version = PMF_TA_IF_VERSION_MAJOR;
+
+   amd_pmf_prepare_args(dev, TA_PMF_COMMAND_POLICY_BUILDER_INITIALIZE, 
&arg, param);
+
+   ret = tee_client_invoke_func(dev->tee_ctx, &arg, p

[PATCH v3 03/16] platform/x86/amd/pmf: Change return type of amd_pmf_set_dram_addr()

2023-10-10 Thread Shyam Sundar S K
In the current code, the metrics table information was required only
for auto-mode or CnQF at a given time. Hence keeping the return type
of amd_pmf_set_dram_addr() as static made sense.

But with the addition of Smart PC builder feature, the metrics table
information has to be shared by the Smart PC also and this feature
resides outside of core.c.

To make amd_pmf_set_dram_addr() visible outside of core.c make it
as a non-static function and move the allocation of memory for
metrics table from amd_pmf_init_metrics_table() to amd_pmf_set_dram_addr()
as amd_pmf_set_dram_addr() is the common function to set the DRAM
address.

Add a suspend handler that can free up the allocated memory for getting
the metrics table information.

Reviewed-by: Mario Limonciello 
Signed-off-by: Shyam Sundar S K 
---
 drivers/platform/x86/amd/pmf/core.c | 42 ++---
 drivers/platform/x86/amd/pmf/pmf.h  |  1 +
 2 files changed, 34 insertions(+), 9 deletions(-)

diff --git a/drivers/platform/x86/amd/pmf/core.c 
b/drivers/platform/x86/amd/pmf/core.c
index d57ed038f0c9..ffb78e9709d9 100644
--- a/drivers/platform/x86/amd/pmf/core.c
+++ b/drivers/platform/x86/amd/pmf/core.c
@@ -251,29 +251,35 @@ static const struct pci_device_id pmf_pci_ids[] = {
{ }
 };
 
-static void amd_pmf_set_dram_addr(struct amd_pmf_dev *dev)
+int amd_pmf_set_dram_addr(struct amd_pmf_dev *dev)
 {
u64 phys_addr;
u32 hi, low;
 
+   /* Get Metrics Table Address */
+   dev->buf = kzalloc(sizeof(dev->m_table), GFP_KERNEL);
+   if (!dev->buf)
+   return -ENOMEM;
+
phys_addr = virt_to_phys(dev->buf);
hi = phys_addr >> 32;
low = phys_addr & GENMASK(31, 0);
 
amd_pmf_send_cmd(dev, SET_DRAM_ADDR_HIGH, 0, hi, NULL);
amd_pmf_send_cmd(dev, SET_DRAM_ADDR_LOW, 0, low, NULL);
+
+   return 0;
 }
 
 int amd_pmf_init_metrics_table(struct amd_pmf_dev *dev)
 {
-   /* Get Metrics Table Address */
-   dev->buf = kzalloc(sizeof(dev->m_table), GFP_KERNEL);
-   if (!dev->buf)
-   return -ENOMEM;
+   int ret;
 
INIT_DELAYED_WORK(&dev->work_buffer, amd_pmf_get_metrics);
 
-   amd_pmf_set_dram_addr(dev);
+   ret = amd_pmf_set_dram_addr(dev);
+   if (ret)
+   return ret;
 
/*
 * Start collecting the metrics data after a small delay
@@ -284,17 +290,35 @@ int amd_pmf_init_metrics_table(struct amd_pmf_dev *dev)
return 0;
 }
 
+static int amd_pmf_suspend_handler(struct device *dev)
+{
+   struct amd_pmf_dev *pdev = dev_get_drvdata(dev);
+
+   /*
+* Free the buffer allocated for storing the metrics table
+* information, as will have to allocate it freshly after
+* resume.
+*/
+   kfree(pdev->buf);
+
+   return 0;
+}
+
 static int amd_pmf_resume_handler(struct device *dev)
 {
struct amd_pmf_dev *pdev = dev_get_drvdata(dev);
+   int ret;
 
-   if (pdev->buf)
-   amd_pmf_set_dram_addr(pdev);
+   if (pdev->buf) {
+   ret = amd_pmf_set_dram_addr(pdev);
+   if (ret)
+   return ret;
+   }
 
return 0;
 }
 
-static DEFINE_SIMPLE_DEV_PM_OPS(amd_pmf_pm, NULL, amd_pmf_resume_handler);
+static DEFINE_SIMPLE_DEV_PM_OPS(amd_pmf_pm, amd_pmf_suspend_handler, 
amd_pmf_resume_handler);
 
 static void amd_pmf_init_features(struct amd_pmf_dev *dev)
 {
diff --git a/drivers/platform/x86/amd/pmf/pmf.h 
b/drivers/platform/x86/amd/pmf/pmf.h
index 4da5c4eb053c..a91c22d9b532 100644
--- a/drivers/platform/x86/amd/pmf/pmf.h
+++ b/drivers/platform/x86/amd/pmf/pmf.h
@@ -421,6 +421,7 @@ int amd_pmf_init_metrics_table(struct amd_pmf_dev *dev);
 int amd_pmf_get_power_source(void);
 int apmf_install_handler(struct amd_pmf_dev *pmf_dev);
 int apmf_os_power_slider_update(struct amd_pmf_dev *dev, u8 flag);
+int amd_pmf_set_dram_addr(struct amd_pmf_dev *dev);
 
 /* SPS Layer */
 int amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf);
-- 
2.25.1



[PATCH v3 04/16] platform/x86/amd/pmf: Add support for PMF Policy Binary

2023-10-10 Thread Shyam Sundar S K
PMF Policy binary is a encrypted and signed binary that will be part
of the BIOS. PMF driver via the ACPI interface checks the existence
of Smart PC bit. If the advertised bit is found, PMF driver walks
the acpi namespace to find out the policy binary size and the address
which has to be passed to the TA during the TA init sequence.

The policy binary is comprised of inputs (or the events) and outputs
(or the actions). With the PMF ecosystem, OEMs generate the policy
binary (or could be multiple binaries) that contains a supported set
of inputs and outputs which could be specifically carved out for each
usage segment (or for each user also) that could influence the system
behavior either by enriching the user experience or/and boost/throttle
power limits.

Once the TA init command succeeds, the PMF driver sends the changing
events in the current environment to the TA for a constant sampling
frequency time (the event here could be a lid close or open) and
if the policy binary has corresponding action built within it, the
TA sends the action for it in the subsequent enact command.

If the inputs sent to the TA has no output defined in the policy
binary generated by OEMs, there will be no action to be performed
by the PMF driver.

Example policies:

1) if slider is performance ; set the SPL to 40W
Here PMF driver registers with the platform profile interface and
when the slider position is changed, PMF driver lets the TA know
about this. TA sends back an action to update the Sustained
Power Limit (SPL). PMF driver updates this limit via the PMFW mailbox.

2) if user_away ; then lock the system
Here PMF driver hooks to the AMD SFH driver to know the user presence
and send the inputs to TA and if the condition is met, the TA sends
the action of locking the system. PMF driver generates a uevent and
based on the udev rule in the userland the system gets locked with
systemctl.

The intent here is to provide the OEM's to make a policy to lock the
system when the user is away ; but the userland can make a choice to
ignore it.

and so on.

The OEMs will have an utility to create numerous such policies and
the policies shall be reviewed by AMD before signing and encrypting
them. Policies are shared between operating systems to have seemless user
experience.

Since all this action has to happen via the "amdtee" driver, currently
there is no caller for it in the kernel which can load the amdtee driver.
Without amdtee driver loading onto the system the "tee" calls shall fail
from the PMF driver. Hence an explicit "request_module" has been added
to address this.

Signed-off-by: Shyam Sundar S K 
---
 drivers/platform/x86/amd/pmf/Kconfig  |   2 +-
 drivers/platform/x86/amd/pmf/acpi.c   |  37 +++
 drivers/platform/x86/amd/pmf/core.c   |  13 +++
 drivers/platform/x86/amd/pmf/pmf.h| 136 
 drivers/platform/x86/amd/pmf/tee-if.c | 146 +-
 5 files changed, 331 insertions(+), 3 deletions(-)

diff --git a/drivers/platform/x86/amd/pmf/Kconfig 
b/drivers/platform/x86/amd/pmf/Kconfig
index 32a029e8db80..f246252bddd8 100644
--- a/drivers/platform/x86/amd/pmf/Kconfig
+++ b/drivers/platform/x86/amd/pmf/Kconfig
@@ -9,7 +9,7 @@ config AMD_PMF
depends on POWER_SUPPLY
depends on AMD_NB
select ACPI_PLATFORM_PROFILE
-   depends on TEE
+   depends on TEE && AMDTEE
help
  This driver provides support for the AMD Platform Management 
Framework.
  The goal is to enhance end user experience by making AMD PCs smarter,
diff --git a/drivers/platform/x86/amd/pmf/acpi.c 
b/drivers/platform/x86/amd/pmf/acpi.c
index 3fc5e4547d9f..d0512af2cd42 100644
--- a/drivers/platform/x86/amd/pmf/acpi.c
+++ b/drivers/platform/x86/amd/pmf/acpi.c
@@ -286,6 +286,43 @@ int apmf_install_handler(struct amd_pmf_dev *pmf_dev)
return 0;
 }
 
+static acpi_status apmf_walk_resources(struct acpi_resource *res, void *data)
+{
+   struct amd_pmf_dev *dev = data;
+
+   switch (res->type) {
+   case ACPI_RESOURCE_TYPE_ADDRESS64:
+   dev->policy_addr = res->data.address64.address.minimum;
+   dev->policy_sz = res->data.address64.address.address_length;
+   break;
+   case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
+   dev->policy_addr = res->data.fixed_memory32.address;
+   dev->policy_sz = res->data.fixed_memory32.address_length;
+   break;
+   }
+
+   if (!dev->policy_addr || dev->policy_sz > POLICY_BUF_MAX_SZ || 
dev->policy_sz == 0) {
+   pr_err("Incorrect Policy params, possibly a SBIOS bug\n");
+   return AE_ERROR;
+   }
+
+   return AE_OK;
+}
+
+int apmf_check_smart_pc(struct amd_pmf_dev *pmf_dev)
+{
+   acpi_handle ahandle = ACPI_HANDLE(pmf_dev->dev);
+   acpi_status status;
+
+   status = acpi_walk_resources(ahandle, METHOD_NAME__CRS, 
apmf_walk_resources, pmf_dev);
+   if (ACPI_FAILURE(status)) {
+   dev_err(pmf

[PATCH v3 05/16] platform/x86/amd/pmf: change amd_pmf_init_features() call sequence

2023-10-10 Thread Shyam Sundar S K
To sideload pmf policy binaries, the Smart PC Solution Builder provides a
debugfs file called "update_policy"; that gets created under a new debugfs
directory called "pb" and this new directory has to be associated with
existing parent directory for PMF driver called "amd_pmf".

In the current code structure, amd_pmf_dbgfs_register() is called after
amd_pmf_init_features(). This will not help when the Smart PC builder
feature has to be assoicated to the parent directory.

Hence change the order of amd_pmf_dbgfs_register() and call it before
amd_pmf_init_features() so that when the Smart PC init happens, it has the
parent debugfs directory to get itself hooked.

Reviewed-by: Mario Limonciello 
Signed-off-by: Shyam Sundar S K 
---
 drivers/platform/x86/amd/pmf/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/platform/x86/amd/pmf/core.c 
b/drivers/platform/x86/amd/pmf/core.c
index 96a41e7d4e7d..64af6ddc23ae 100644
--- a/drivers/platform/x86/amd/pmf/core.c
+++ b/drivers/platform/x86/amd/pmf/core.c
@@ -447,9 +447,9 @@ static int amd_pmf_probe(struct platform_device *pdev)
 
apmf_acpi_init(dev);
platform_set_drvdata(pdev, dev);
+   amd_pmf_dbgfs_register(dev);
amd_pmf_init_features(dev);
apmf_install_handler(dev);
-   amd_pmf_dbgfs_register(dev);
 
dev_info(dev->dev, "registered PMF device successfully\n");
 
-- 
2.25.1



[PATCH v3 06/16] platform/x86/amd/pmf: Add support to get inputs from other subsystems

2023-10-10 Thread Shyam Sundar S K
PMF driver sends changing inputs from each subystem to TA for evaluating
the conditions in the policy binary.

Add initial support of plumbing in the PMF driver for Smart PC to get
information from other subsystems in the kernel.

Signed-off-by: Shyam Sundar S K 
---
 drivers/platform/x86/amd/pmf/Makefile |   2 +-
 drivers/platform/x86/amd/pmf/pmf.h|  18 
 drivers/platform/x86/amd/pmf/spc.c| 119 ++
 drivers/platform/x86/amd/pmf/tee-if.c |   3 +
 4 files changed, 141 insertions(+), 1 deletion(-)
 create mode 100644 drivers/platform/x86/amd/pmf/spc.c

diff --git a/drivers/platform/x86/amd/pmf/Makefile 
b/drivers/platform/x86/amd/pmf/Makefile
index d2746ee7369f..6b26e48ce8ad 100644
--- a/drivers/platform/x86/amd/pmf/Makefile
+++ b/drivers/platform/x86/amd/pmf/Makefile
@@ -7,4 +7,4 @@
 obj-$(CONFIG_AMD_PMF) += amd-pmf.o
 amd-pmf-objs := core.o acpi.o sps.o \
auto-mode.o cnqf.o \
-   tee-if.o
+   tee-if.o spc.o
diff --git a/drivers/platform/x86/amd/pmf/pmf.h 
b/drivers/platform/x86/amd/pmf/pmf.h
index 51c0e17f7720..88ee3c705913 100644
--- a/drivers/platform/x86/amd/pmf/pmf.h
+++ b/drivers/platform/x86/amd/pmf/pmf.h
@@ -150,6 +150,21 @@ struct smu_pmf_metrics {
u16 infra_gfx_maxfreq; /* in MHz */
u16 skin_temp; /* in centi-Celsius */
u16 device_state;
+   u16 curtemp; /* in centi-Celsius */
+   u16 filter_alpha_value;
+   u16 avg_gfx_clkfrequency;
+   u16 avg_fclk_frequency;
+   u16 avg_gfx_activity;
+   u16 avg_socclk_frequency;
+   u16 avg_vclk_frequency;
+   u16 avg_vcn_activity;
+   u16 avg_dram_reads;
+   u16 avg_dram_writes;
+   u16 avg_socket_power;
+   u16 avg_core_power[2];
+   u16 avg_core_c0residency[16];
+   u16 spare1;
+   u32 metrics_counter;
 } __packed;
 
 enum amd_stt_skin_temp {
@@ -596,4 +611,7 @@ extern const struct attribute_group 
cnqf_feature_attribute_group;
 int amd_pmf_init_smart_pc(struct amd_pmf_dev *dev);
 void amd_pmf_deinit_smart_pc(struct amd_pmf_dev *dev);
 int apmf_check_smart_pc(struct amd_pmf_dev *pmf_dev);
+
+/* Smart PC - TA interfaces */
+void amd_pmf_populate_ta_inputs(struct amd_pmf_dev *dev, struct 
ta_pmf_enact_table *in);
 #endif /* PMF_H */
diff --git a/drivers/platform/x86/amd/pmf/spc.c 
b/drivers/platform/x86/amd/pmf/spc.c
new file mode 100644
index ..91a7f1da911c
--- /dev/null
+++ b/drivers/platform/x86/amd/pmf/spc.c
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD Platform Management Framework Driver - Smart PC Capabilities
+ *
+ * Copyright (c) 2023, Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * Authors: Shyam Sundar S K 
+ *  Patil Rajesh Reddy 
+ */
+
+#include 
+#include 
+#include 
+#include "pmf.h"
+
+static void amd_pmf_get_smu_info(struct amd_pmf_dev *dev, struct 
ta_pmf_enact_table *in)
+{
+   u16 max, avg = 0;
+   int i;
+
+   memset(dev->buf, 0, sizeof(dev->m_table));
+   amd_pmf_send_cmd(dev, SET_TRANSFER_TABLE, 0, 7, NULL);
+   memcpy(&dev->m_table, dev->buf, sizeof(dev->m_table));
+
+   in->ev_info.socket_power = dev->m_table.apu_power + 
dev->m_table.dgpu_power;
+   in->ev_info.skin_temperature = dev->m_table.skin_temp;
+
+   /* Get the avg and max C0 residency of all the cores */
+   max = dev->m_table.avg_core_c0residency[0];
+   for (i = 0; i < ARRAY_SIZE(dev->m_table.avg_core_c0residency); i++) {
+   avg += dev->m_table.avg_core_c0residency[i];
+   if (dev->m_table.avg_core_c0residency[i] > max)
+   max = dev->m_table.avg_core_c0residency[i];
+   }
+
+   in->ev_info.avg_c0residency = avg / 
ARRAY_SIZE(dev->m_table.avg_core_c0residency);
+   in->ev_info.max_c0residency = max;
+   in->ev_info.gfx_busy = dev->m_table.avg_gfx_activity;
+}
+
+static const char * const pmf_battery_supply_name[] = {
+   "BATT",
+   "BAT0",
+};
+
+static int amd_pmf_get_battery_prop(enum power_supply_property prop)
+{
+   union power_supply_propval value;
+   struct power_supply *psy;
+   int i, ret = -EINVAL;
+
+   for (i = 0; i < ARRAY_SIZE(pmf_battery_supply_name); i++) {
+   psy = power_supply_get_by_name(pmf_battery_supply_name[i]);
+   if (!psy)
+   continue;
+
+   ret = power_supply_get_property(psy, prop, &value);
+   if (ret) {
+   power_supply_put(psy);
+   return ret;
+   }
+   }
+
+   return value.intval;
+}
+
+static int amd_pmf_get_battery_info(struct amd_pmf_dev *dev, struct 
ta_pmf_enact_table *in)
+{
+   int val;
+
+   val = amd_pmf_get_battery_prop(POWER_SUPPLY_PROP_PRESENT);
+   if (val != 1)
+   return -EINVAL;
+
+   in->ev_info.bat_percentage = 
amd_pmf_get_battery_prop(POWER_SUPPLY_PROP_CAPACITY);
+   /* all values in mWh metrics */
+   in->ev_info.bat_des

[PATCH v3 07/16] platform/x86/amd/pmf: Add support update p3t limit

2023-10-10 Thread Shyam Sundar S K
P3T (Peak Package Power Limit) is a metric within the SMU controller
that can influence the power limits. Add support from the driver
to update P3T limits accordingly.

Reviewed-by: Mario Limonciello 
Signed-off-by: Shyam Sundar S K 
---
 drivers/platform/x86/amd/pmf/pmf.h| 3 +++
 drivers/platform/x86/amd/pmf/tee-if.c | 8 
 2 files changed, 11 insertions(+)

diff --git a/drivers/platform/x86/amd/pmf/pmf.h 
b/drivers/platform/x86/amd/pmf/pmf.h
index 88ee3c705913..20f3e16b0a32 100644
--- a/drivers/platform/x86/amd/pmf/pmf.h
+++ b/drivers/platform/x86/amd/pmf/pmf.h
@@ -49,6 +49,7 @@
 #define GET_STT_MIN_LIMIT  0x1F
 #define GET_STT_LIMIT_APU  0x20
 #define GET_STT_LIMIT_HS2  0x21
+#define SET_P3T0x23 /* P3T: Peak Package Power 
Limit */
 
 /* OS slider update notification */
 #define DC_BEST_PERF   0
@@ -72,6 +73,7 @@
 #define PMF_POLICY_STT_MIN 6
 #define PMF_POLICY_STT_SKINTEMP_APU7
 #define PMF_POLICY_STT_SKINTEMP_HS28
+#define PMF_POLICY_P3T 38
 
 /* TA macros */
 #define PMF_TA_IF_VERSION_MAJOR1
@@ -476,6 +478,7 @@ struct pmf_action_table {
u32 stt_minlimit;   /* in mW */
u32 stt_skintemp_apu;   /* in C */
u32 stt_skintemp_hs2;   /* in C */
+   u32 p3t_limit;  /* in mW */
 };
 
 /* Input conditions */
diff --git a/drivers/platform/x86/amd/pmf/tee-if.c 
b/drivers/platform/x86/amd/pmf/tee-if.c
index 277103e4346d..92879ae4f8f0 100644
--- a/drivers/platform/x86/amd/pmf/tee-if.c
+++ b/drivers/platform/x86/amd/pmf/tee-if.c
@@ -105,6 +105,14 @@ static void amd_pmf_apply_policies(struct amd_pmf_dev 
*dev, struct ta_pmf_enact_
dev->prev_data->stt_skintemp_hs2 = val;
}
break;
+
+   case PMF_POLICY_P3T:
+   if (dev->prev_data->p3t_limit != val) {
+   amd_pmf_send_cmd(dev, SET_P3T, false, val, 
NULL);
+   dev_dbg(dev->dev, "update P3T : %u\n", val);
+   dev->prev_data->p3t_limit = val;
+   }
+   break;
}
}
 }
-- 
2.25.1



[PATCH v3 08/16] platform/x86/amd/pmf: Add support to update system state

2023-10-10 Thread Shyam Sundar S K
PMF driver based on the output actions from the TA can request to update
the system states like entering s0i3, lock screen etc. by generating
an uevent. Based on the udev rules set in the userspace the event id
matching the uevent shall get updated accordingly using the systemctl.

Sample udev rules under Documentation/admin-guide/pmf.rst.

Signed-off-by: Shyam Sundar S K 
---
 Documentation/admin-guide/index.rst   |  1 +
 Documentation/admin-guide/pmf.rst | 25 +++
 drivers/platform/x86/amd/pmf/pmf.h|  9 +++
 drivers/platform/x86/amd/pmf/tee-if.c | 36 ++-
 4 files changed, 70 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/admin-guide/pmf.rst

diff --git a/Documentation/admin-guide/index.rst 
b/Documentation/admin-guide/index.rst
index 43ea35613dfc..fb40a1f6f79e 100644
--- a/Documentation/admin-guide/index.rst
+++ b/Documentation/admin-guide/index.rst
@@ -119,6 +119,7 @@ configure specific aspects of kernel behavior to your 
liking.
parport
perf-security
pm/index
+   pmf
pnp
rapidio
ras
diff --git a/Documentation/admin-guide/pmf.rst 
b/Documentation/admin-guide/pmf.rst
new file mode 100644
index ..6985bb5b9452
--- /dev/null
+++ b/Documentation/admin-guide/pmf.rst
@@ -0,0 +1,25 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Set udev rules for PMF Smart PC Builder
+---
+
+AMD PMF(Platform Management Framework) Smart PC Solution builder has to set 
the system states
+like S0i3, Screen lock, hibernate etc, based on the output actions provided by 
the PMF
+TA (Trusted Application).
+
+In order for this to work the PMF driver generates a uevent for userspace to 
react to. Below are
+sample udev rules that can facilitate this experience when a machine has PMF 
Smart PC solution builder
+enabled.
+
+Please add the following line(s) to
+``/etc/udev/rules.d/99-local.rules``::
+
+DRIVERS=="amd-pmf", ACTION=="change", ENV{EVENT_ID}=="0", 
RUN+="/usr/bin/systemctl suspend"
+DRIVERS=="amd-pmf", ACTION=="change", ENV{EVENT_ID}=="1", 
RUN+="/usr/bin/systemctl hibernate"
+DRIVERS=="amd-pmf", ACTION=="change", ENV{EVENT_ID}=="2", 
RUN+="/bin/loginctl lock-sessions"
+
+EVENT_ID values:
+0= Put the system to S0i3/S2Idle
+1= Put the system to hibernate
+2= Lock the screen
+
diff --git a/drivers/platform/x86/amd/pmf/pmf.h 
b/drivers/platform/x86/amd/pmf/pmf.h
index 20f3e16b0a32..67f3d5a7 100644
--- a/drivers/platform/x86/amd/pmf/pmf.h
+++ b/drivers/platform/x86/amd/pmf/pmf.h
@@ -73,6 +73,7 @@
 #define PMF_POLICY_STT_MIN 6
 #define PMF_POLICY_STT_SKINTEMP_APU7
 #define PMF_POLICY_STT_SKINTEMP_HS28
+#define PMF_POLICY_SYSTEM_STATE9
 #define PMF_POLICY_P3T 38
 
 /* TA macros */
@@ -440,6 +441,13 @@ struct apmf_dyn_slider_output {
 } __packed;
 
 /* Smart PC - TA internals */
+enum system_state {
+   SYSTEM_STATE__S0i3,
+   SYSTEM_STATE__S4,
+   SYSTEM_STATE__SCREEN_LOCK,
+   SYSTEM_STATE__MAX
+};
+
 enum ta_slider {
TA_BEST_BATTERY,/* Best Battery */
TA_BETTER_BATTERY,  /* Better Battery */
@@ -471,6 +479,7 @@ enum ta_pmf_error_type {
 };
 
 struct pmf_action_table {
+   enum system_state system_state;
u32 spl;/* in mW */
u32 sppt;   /* in mW */
u32 sppt_apuonly;   /* in mW */
diff --git a/drivers/platform/x86/amd/pmf/tee-if.c 
b/drivers/platform/x86/amd/pmf/tee-if.c
index 92879ae4f8f0..c08ef13a1494 100644
--- a/drivers/platform/x86/amd/pmf/tee-if.c
+++ b/drivers/platform/x86/amd/pmf/tee-if.c
@@ -24,6 +24,20 @@ MODULE_PARM_DESC(pb_actions_ms, "Policy binary actions 
sampling frequency (defau
 static const uuid_t amd_pmf_ta_uuid = UUID_INIT(0x6fd93b77, 0x3fb8, 0x524d,
0xb1, 0x2d, 0xc5, 0x29, 0xb1, 
0x3d, 0x85, 0x43);
 
+static const char *amd_pmf_uevent_as_str(unsigned int state)
+{
+   switch (state) {
+   case SYSTEM_STATE__S0i3:
+   return "S0i3";
+   case SYSTEM_STATE__S4:
+   return "S4";
+   case SYSTEM_STATE__SCREEN_LOCK:
+   return "SCREEN_LOCK";
+   default:
+   return "Unknown Smart PC event";
+   }
+}
+
 static void amd_pmf_prepare_args(struct amd_pmf_dev *dev, int cmd,
 struct tee_ioctl_invoke_arg *arg,
 struct tee_param *param)
@@ -42,9 +56,23 @@ static void amd_pmf_prepare_args(struct amd_pmf_dev *dev, 
int cmd,
param[0].u.memref.shm_offs = 0;
 }
 
+static int amd_pmf_update_uevents(struct amd_pmf_dev *dev, u16 event)
+{
+   char *envp[2] = {};
+
+   envp[0] = kasprintf(GFP_KERNEL, "EVENT_ID=%d", event);
+   if (!envp[0])
+   return -EINVAL;
+
+   kobject_uevent_env(&dev-

[PATCH v3 10/16] platform/x86/amd/pmf: Add capability to sideload of policy binary

2023-10-10 Thread Shyam Sundar S K
A policy binary is OS agnostic, and the same policies are expected to work
across the OSes.  At times it becomes difficult to debug when the policies
inside the policy binaries starts to misbehave. Add a way to sideload such
policies independently to debug them via a debugfs entry.

Reviewed-by: Mario Limonciello 
Signed-off-by: Shyam Sundar S K 
---
 drivers/platform/x86/amd/pmf/pmf.h|  1 +
 drivers/platform/x86/amd/pmf/tee-if.c | 67 +++
 2 files changed, 68 insertions(+)

diff --git a/drivers/platform/x86/amd/pmf/pmf.h 
b/drivers/platform/x86/amd/pmf/pmf.h
index 3d98d9bea96b..9b84121344f4 100644
--- a/drivers/platform/x86/amd/pmf/pmf.h
+++ b/drivers/platform/x86/amd/pmf/pmf.h
@@ -219,6 +219,7 @@ struct amd_pmf_dev {
bool cnqf_supported;
struct notifier_block pwr_src_notifier;
/* Smart PC solution builder */
+   struct dentry *esbin;
unsigned char *policy_buf;
u32 policy_sz;
struct tee_context *tee_ctx;
diff --git a/drivers/platform/x86/amd/pmf/tee-if.c 
b/drivers/platform/x86/amd/pmf/tee-if.c
index 80252309575b..994daf945795 100644
--- a/drivers/platform/x86/amd/pmf/tee-if.c
+++ b/drivers/platform/x86/amd/pmf/tee-if.c
@@ -8,6 +8,7 @@
  * Author: Shyam Sundar S K 
  */
 
+#include 
 #include 
 #include 
 #include "pmf.h"
@@ -16,9 +17,14 @@
 
 /* Policy binary actions sampling frequency (in ms) */
 static int pb_actions_ms = MSEC_PER_SEC;
+/* Sideload policy binaries to debug policy failures */
+static bool pb_side_load;
+
 #ifdef CONFIG_AMD_PMF_DEBUG
 module_param(pb_actions_ms, int, 0644);
 MODULE_PARM_DESC(pb_actions_ms, "Policy binary actions sampling frequency 
(default = 1000ms)");
+module_param(pb_side_load, bool, 0444);
+MODULE_PARM_DESC(pb_side_load, "Sideload policy binaries debug policy 
failures");
 #endif
 
 static const uuid_t amd_pmf_ta_uuid = UUID_INIT(0x6fd93b77, 0x3fb8, 0x524d,
@@ -268,6 +274,61 @@ static int amd_pmf_start_policy_engine(struct amd_pmf_dev 
*dev)
return 0;
 }
 
+#ifdef CONFIG_AMD_PMF_DEBUG
+static ssize_t amd_pmf_get_pb_data(struct file *filp, const char __user *buf,
+  size_t length, loff_t *pos)
+{
+   struct amd_pmf_dev *dev = filp->private_data;
+   int ret;
+
+   /* policy binary size cannot exceed POLICY_BUF_MAX_SZ */
+   if (length > POLICY_BUF_MAX_SZ || length == 0)
+   return -EINVAL;
+
+   dev->policy_sz = length;
+   if (copy_from_user(dev->policy_buf, buf, dev->policy_sz))
+   return -EFAULT;
+
+   ret = amd_pmf_start_policy_engine(dev);
+   if (ret)
+   return -EINVAL;
+
+   return length;
+}
+
+static const struct file_operations pb_fops = {
+   .write = amd_pmf_get_pb_data,
+   .open = simple_open,
+};
+
+static int amd_pmf_open_pb(struct amd_pmf_dev *dev, struct dentry 
*debugfs_root)
+{
+   struct dentry *file = NULL;
+
+   dev->esbin = debugfs_create_dir("pb", debugfs_root);
+   if (IS_ERR(dev->esbin))
+   return -EINVAL;
+
+   file = debugfs_create_file("update_policy", 0644, dev->esbin, dev, 
&pb_fops);
+   if (!file)
+   return -EINVAL;
+
+   return 0;
+}
+
+static void amd_pmf_remove_pb(struct amd_pmf_dev *dev)
+{
+   debugfs_remove_recursive(dev->esbin);
+}
+#else
+static int amd_pmf_open_pb(struct amd_pmf_dev *dev, struct dentry 
*debugfs_root)
+{
+   return 0;
+}
+
+static void amd_pmf_remove_pb(struct amd_pmf_dev *dev) {}
+#endif
+
 static int amd_pmf_get_bios_buffer(struct amd_pmf_dev *dev)
 {
dev->policy_buf = kzalloc(dev->policy_sz, GFP_KERNEL);
@@ -280,6 +341,9 @@ static int amd_pmf_get_bios_buffer(struct amd_pmf_dev *dev)
 
memcpy(dev->policy_buf, dev->policy_base, dev->policy_sz);
 
+   if (pb_side_load)
+   amd_pmf_open_pb(dev, dev->dbgfs_dir);
+
return amd_pmf_start_policy_engine(dev);
 }
 
@@ -381,6 +445,9 @@ int amd_pmf_init_smart_pc(struct amd_pmf_dev *dev)
 
 void amd_pmf_deinit_smart_pc(struct amd_pmf_dev *dev)
 {
+   if (pb_side_load)
+   amd_pmf_remove_pb(dev);
+
kfree(dev->prev_data);
kfree(dev->policy_buf);
cancel_delayed_work_sync(&dev->pb_work);
-- 
2.25.1



[PATCH v3 09/16] platform/x86/amd/pmf: Add facility to dump TA inputs

2023-10-10 Thread Shyam Sundar S K
PMF driver sends constant inputs to TA which its gets via the other
subsystems in the kernel. To debug certain TA issues knowing what inputs
being sent to TA becomes critical. Add debug facility to the driver which
can isolate Smart PC and TA related issues.

Also, make source_as_str() as non-static function as this helper is
required outside of sps.c file.

Reviewed-by: Mario Limonciello 
Signed-off-by: Shyam Sundar S K 
---
 drivers/platform/x86/amd/pmf/pmf.h|  3 +++
 drivers/platform/x86/amd/pmf/spc.c| 37 +++
 drivers/platform/x86/amd/pmf/sps.c|  2 +-
 drivers/platform/x86/amd/pmf/tee-if.c |  1 +
 4 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/drivers/platform/x86/amd/pmf/pmf.h 
b/drivers/platform/x86/amd/pmf/pmf.h
index 67f3d5a7..3d98d9bea96b 100644
--- a/drivers/platform/x86/amd/pmf/pmf.h
+++ b/drivers/platform/x86/amd/pmf/pmf.h
@@ -596,6 +596,7 @@ int apmf_get_static_slider_granular(struct amd_pmf_dev 
*pdev,
 bool is_pprof_balanced(struct amd_pmf_dev *pmf);
 int amd_pmf_power_slider_update_event(struct amd_pmf_dev *dev);
 
+const char *amd_pmf_source_as_str(unsigned int state);
 
 int apmf_update_fan_idx(struct amd_pmf_dev *pdev, bool manual, u32 idx);
 int amd_pmf_set_sps_power_limits(struct amd_pmf_dev *pmf);
@@ -626,4 +627,6 @@ int apmf_check_smart_pc(struct amd_pmf_dev *pmf_dev);
 
 /* Smart PC - TA interfaces */
 void amd_pmf_populate_ta_inputs(struct amd_pmf_dev *dev, struct 
ta_pmf_enact_table *in);
+void amd_pmf_dump_ta_inputs(struct amd_pmf_dev *dev, struct ta_pmf_enact_table 
*in);
+
 #endif /* PMF_H */
diff --git a/drivers/platform/x86/amd/pmf/spc.c 
b/drivers/platform/x86/amd/pmf/spc.c
index 91a7f1da911c..5cb70f183825 100644
--- a/drivers/platform/x86/amd/pmf/spc.c
+++ b/drivers/platform/x86/amd/pmf/spc.c
@@ -14,6 +14,43 @@
 #include 
 #include "pmf.h"
 
+#ifdef CONFIG_AMD_PMF_DEBUG
+static const char *ta_slider_as_str(unsigned int state)
+{
+   switch (state) {
+   case TA_BEST_PERFORMANCE:
+   return "PERFORMANCE";
+   case TA_BETTER_PERFORMANCE:
+   return "BALANCED";
+   case TA_BEST_BATTERY:
+   return "POWER_SAVER";
+   default:
+   return "Unknown TA Slider State";
+   }
+}
+
+void amd_pmf_dump_ta_inputs(struct amd_pmf_dev *dev, struct ta_pmf_enact_table 
*in)
+{
+   dev_dbg(dev->dev, " TA inputs START \n");
+   dev_dbg(dev->dev, "Slider State : %s\n", 
ta_slider_as_str(in->ev_info.power_slider));
+   dev_dbg(dev->dev, "Power Source : %s\n", 
amd_pmf_source_as_str(in->ev_info.power_source));
+   dev_dbg(dev->dev, "Battery Percentage : %u\n", 
in->ev_info.bat_percentage);
+   dev_dbg(dev->dev, "Designed Battery Capacity : %u\n", 
in->ev_info.bat_design);
+   dev_dbg(dev->dev, "Fully Charged Capacity : %u\n", 
in->ev_info.full_charge_capacity);
+   dev_dbg(dev->dev, "Drain Rate : %d\n", in->ev_info.drain_rate);
+   dev_dbg(dev->dev, "Socket Power : %u\n", in->ev_info.socket_power);
+   dev_dbg(dev->dev, "Skin Temperature : %u\n", 
in->ev_info.skin_temperature);
+   dev_dbg(dev->dev, "Avg C0 Residency : %u\n", 
in->ev_info.avg_c0residency);
+   dev_dbg(dev->dev, "Max C0 Residency : %u\n", 
in->ev_info.max_c0residency);
+   dev_dbg(dev->dev, "GFX Busy : %u\n", in->ev_info.gfx_busy);
+   dev_dbg(dev->dev, "Connected Display Count : %u\n", 
in->ev_info.monitor_count);
+   dev_dbg(dev->dev, "LID State : %s\n", in->ev_info.lid_state ? "Close" : 
"Open");
+   dev_dbg(dev->dev, " TA inputs END \n");
+}
+#else
+void amd_pmf_dump_ta_inputs(struct amd_pmf_dev *dev, struct ta_pmf_enact_table 
*in) {}
+#endif
+
 static void amd_pmf_get_smu_info(struct amd_pmf_dev *dev, struct 
ta_pmf_enact_table *in)
 {
u16 max, avg = 0;
diff --git a/drivers/platform/x86/amd/pmf/sps.c 
b/drivers/platform/x86/amd/pmf/sps.c
index a70e67749be3..781fde00e0e7 100644
--- a/drivers/platform/x86/amd/pmf/sps.c
+++ b/drivers/platform/x86/amd/pmf/sps.c
@@ -27,7 +27,7 @@ static const char *slider_as_str(unsigned int state)
}
 }
 
-static const char *source_as_str(unsigned int state)
+const char *amd_pmf_source_as_str(unsigned int state)
 {
switch (state) {
case POWER_SOURCE_AC:
diff --git a/drivers/platform/x86/amd/pmf/tee-if.c 
b/drivers/platform/x86/amd/pmf/tee-if.c
index c08ef13a1494..80252309575b 100644
--- a/drivers/platform/x86/amd/pmf/tee-if.c
+++ b/drivers/platform/x86/amd/pmf/tee-if.c
@@ -182,6 +182,7 @@ static int amd_pmf_invoke_cmd_enact(struct amd_pmf_dev *dev)
}
 
if (ta_sm->pmf_result == TA_PMF_TYPE_SUCCESS && out->actions_count) {
+   amd_pmf_dump_ta_inputs(dev, in);
dev_dbg(dev->dev, "action count:%u result:%x\n", 
out->actions_count,
ta_sm->pmf_result);
amd_pmf_apply_policies(dev, out);
-- 
2.25.1



[PATCH v3 11/16] platform/x86/amd/pmf: dump policy binary data

2023-10-10 Thread Shyam Sundar S K
Sometimes policy binary retrieved from the BIOS maybe incorrect that can
end up in failing to enable the Smart PC solution feature.

Use print_hex_dump_debug() to dump the policy binary in hex, so that we
debug the issues related to the binary even before sending that to TA.

Signed-off-by: Shyam Sundar S K 
---
 drivers/platform/x86/amd/pmf/tee-if.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/platform/x86/amd/pmf/tee-if.c 
b/drivers/platform/x86/amd/pmf/tee-if.c
index 994daf945795..e4386f503ad0 100644
--- a/drivers/platform/x86/amd/pmf/tee-if.c
+++ b/drivers/platform/x86/amd/pmf/tee-if.c
@@ -275,6 +275,12 @@ static int amd_pmf_start_policy_engine(struct amd_pmf_dev 
*dev)
 }
 
 #ifdef CONFIG_AMD_PMF_DEBUG
+static void amd_pmf_hex_dump_pb(struct amd_pmf_dev *dev)
+{
+   print_hex_dump_debug("(pb):  ", DUMP_PREFIX_OFFSET, 16, 1, 
dev->policy_buf,
+dev->policy_sz, false);
+}
+
 static ssize_t amd_pmf_get_pb_data(struct file *filp, const char __user *buf,
   size_t length, loff_t *pos)
 {
@@ -289,6 +295,7 @@ static ssize_t amd_pmf_get_pb_data(struct file *filp, const 
char __user *buf,
if (copy_from_user(dev->policy_buf, buf, dev->policy_sz))
return -EFAULT;
 
+   amd_pmf_hex_dump_pb(dev);
ret = amd_pmf_start_policy_engine(dev);
if (ret)
return -EINVAL;
@@ -327,6 +334,7 @@ static int amd_pmf_open_pb(struct amd_pmf_dev *dev, struct 
dentry *debugfs_root)
 }
 
 static void amd_pmf_remove_pb(struct amd_pmf_dev *dev) {}
+static void amd_pmf_hex_dump_pb(struct amd_pmf_dev *dev) {}
 #endif
 
 static int amd_pmf_get_bios_buffer(struct amd_pmf_dev *dev)
@@ -341,6 +349,7 @@ static int amd_pmf_get_bios_buffer(struct amd_pmf_dev *dev)
 
memcpy(dev->policy_buf, dev->policy_base, dev->policy_sz);
 
+   amd_pmf_hex_dump_pb(dev);
if (pb_side_load)
amd_pmf_open_pb(dev, dev->dbgfs_dir);
 
-- 
2.25.1



[PATCH v3 12/16] platform/x86/amd/pmf: Add PMF-AMDGPU get interface

2023-10-10 Thread Shyam Sundar S K
In order to provide GPU inputs to TA for the Smart PC solution to work, we
need to have interface between the PMF driver and the AMDGPU driver.

Add the initial code path for get interface from AMDGPU.

Co-developed-by: Mario Limonciello 
Signed-off-by: Mario Limonciello 
Signed-off-by: Shyam Sundar S K 
---
 drivers/gpu/drm/amd/amdgpu/Makefile |   2 +
 drivers/gpu/drm/amd/amdgpu/amdgpu.h |   1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c | 136 
 drivers/platform/x86/amd/pmf/Kconfig|   1 +
 drivers/platform/x86/amd/pmf/core.c |   1 +
 drivers/platform/x86/amd/pmf/pmf.h  |   3 +
 drivers/platform/x86/amd/pmf/spc.c  |  13 +++
 drivers/platform/x86/amd/pmf/tee-if.c   |  26 +
 include/linux/amd-pmf-io.h  |  35 ++
 9 files changed, 218 insertions(+)
 create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c
 create mode 100644 include/linux/amd-pmf-io.h

diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile 
b/drivers/gpu/drm/amd/amdgpu/Makefile
index 384b798a9bad..7fafccefbd7a 100644
--- a/drivers/gpu/drm/amd/amdgpu/Makefile
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -86,6 +86,8 @@ amdgpu-$(CONFIG_PROC_FS) += amdgpu_fdinfo.o
 
 amdgpu-$(CONFIG_PERF_EVENTS) += amdgpu_pmu.o
 
+amdgpu-$(CONFIG_AMD_PMF) += amdgpu_pmf.o
+
 # add asic specific block
 amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o \
dce_v8_0.o gfx_v7_0.o cik_sdma.o uvd_v4_2.o vce_v2_0.o
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index dc2d53081e80..475f3e248f35 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -50,6 +50,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c
new file mode 100644
index ..45a079c028d3
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2023 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+
+ * * Author: Shyam Sundar S K 
+ */
+
+#include 
+#include "amdgpu.h"
+
+int amd_pmf_get_gfx_data(struct amd_gpu_pmf_data *pmf)
+{
+   struct drm_device *drm_dev = pci_get_drvdata(pmf->gpu_dev);
+   struct drm_mode_config *mode_config = &drm_dev->mode_config;
+   struct amdgpu_device *adev = drm_to_adev(drm_dev);
+   struct drm_connector_list_iter iter;
+   struct drm_connector *connector;
+   int i = 0;
+
+   /* reset the count to zero */
+   pmf->display_count = 0;
+   if (!(adev->flags & AMD_IS_APU)) {
+   DRM_ERROR("PMF-AMDGPU interface not supported\n");
+   return -ENODEV;
+   }
+
+   mutex_lock(&mode_config->mutex);
+   drm_connector_list_iter_begin(drm_dev, &iter);
+   drm_for_each_connector_iter(connector, &iter) {
+   if (connector->status == connector_status_connected) {
+   pmf->con_status[i] = connector->status;
+   pmf->connector_type[i] = connector->connector_type;
+   pmf->display_count++;
+   }
+   i++;
+
+   if (i > MAX_SUPPORTED)
+   break;
+   }
+   drm_connector_list_iter_end(&iter);
+   mutex_unlock(&mode_config->mutex);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(amd_pmf_get_gfx_data);
+
+static int amd_pmf_gpu_get_cur_state(struct thermal_cooling_device 
*cooling_dev,
+unsigned long *state)
+{
+   struct backlight_device *bd;
+
+   if (!acpi_video_backlight_use_native())
+   return -ENODEV;
+
+   bd = backlight_device_get_by_type(BACKLIGHT_RAW);
+   if (!bd)
+   return -ENODEV;
+
+   *state = backlight_get_brightness(bd);
+
+   return 0;
+}
+
+static int amd_pmf_gpu_get_max_state(struct thermal_cooling_device 
*cooling_dev,
+

[PATCH v3 13/16] platform/x86/amd/pmf: Add PMF-AMDGPU set interface

2023-10-10 Thread Shyam Sundar S K
For the Smart PC Solution to fully work, it has to enact to the actions
coming from TA. Add the initial code path for set interface to AMDGPU.

Change amd_pmf_apply_policies() return type, so that it can return
errors when the call to retrieve information from amdgpu fails.

Co-developed-by: Mario Limonciello 
Signed-off-by: Mario Limonciello 
Signed-off-by: Shyam Sundar S K 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c | 18 ++
 drivers/platform/x86/amd/pmf/pmf.h  |  2 ++
 drivers/platform/x86/amd/pmf/tee-if.c   | 21 +++--
 3 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c
index 45a079c028d3..803e6bb66914 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c
@@ -61,6 +61,23 @@ int amd_pmf_get_gfx_data(struct amd_gpu_pmf_data *pmf)
 }
 EXPORT_SYMBOL_GPL(amd_pmf_get_gfx_data);
 
+static int amd_pmf_gpu_set_cur_state(struct thermal_cooling_device 
*cooling_dev,
+unsigned long state)
+{
+   struct backlight_device *bd;
+
+   if (!acpi_video_backlight_use_native())
+   return -ENODEV;
+
+   bd = backlight_device_get_by_type(BACKLIGHT_RAW);
+   if (!bd)
+   return -ENODEV;
+
+   backlight_device_set_brightness(bd, state);
+
+   return 0;
+}
+
 static int amd_pmf_gpu_get_cur_state(struct thermal_cooling_device 
*cooling_dev,
 unsigned long *state)
 {
@@ -101,6 +118,7 @@ static int amd_pmf_gpu_get_max_state(struct 
thermal_cooling_device *cooling_dev,
 static const struct thermal_cooling_device_ops bd_cooling_ops = {
.get_max_state = amd_pmf_gpu_get_max_state,
.get_cur_state = amd_pmf_gpu_get_cur_state,
+   .set_cur_state = amd_pmf_gpu_set_cur_state,
 };
 
 int amd_pmf_gpu_init(struct amd_gpu_pmf_data *pmf)
diff --git a/drivers/platform/x86/amd/pmf/pmf.h 
b/drivers/platform/x86/amd/pmf/pmf.h
index 0f1c0e0bc86a..d61cebc44d2b 100644
--- a/drivers/platform/x86/amd/pmf/pmf.h
+++ b/drivers/platform/x86/amd/pmf/pmf.h
@@ -75,6 +75,7 @@
 #define PMF_POLICY_STT_SKINTEMP_APU7
 #define PMF_POLICY_STT_SKINTEMP_HS28
 #define PMF_POLICY_SYSTEM_STATE9
+#define PMF_POLICY_DISPLAY_BRIGHTNESS  12
 #define PMF_POLICY_P3T 38
 
 /* TA macros */
@@ -483,6 +484,7 @@ enum ta_pmf_error_type {
 };
 
 struct pmf_action_table {
+   unsigned long display_brightness;
enum system_state system_state;
u32 spl;/* in mW */
u32 sppt;   /* in mW */
diff --git a/drivers/platform/x86/amd/pmf/tee-if.c 
b/drivers/platform/x86/amd/pmf/tee-if.c
index e9a257a91325..4f5de7f816d3 100644
--- a/drivers/platform/x86/amd/pmf/tee-if.c
+++ b/drivers/platform/x86/amd/pmf/tee-if.c
@@ -77,8 +77,10 @@ static int amd_pmf_update_uevents(struct amd_pmf_dev *dev, 
u16 event)
return 0;
 }
 
-static void amd_pmf_apply_policies(struct amd_pmf_dev *dev, struct 
ta_pmf_enact_result *out)
+static int amd_pmf_apply_policies(struct amd_pmf_dev *dev, struct 
ta_pmf_enact_result *out)
 {
+   struct thermal_cooling_device *cdev = dev->gfx_data.cooling_dev;
+   unsigned long state;
u32 val, event = 0;
int idx;
 
@@ -154,8 +156,21 @@ static void amd_pmf_apply_policies(struct amd_pmf_dev 
*dev, struct ta_pmf_enact_
dev_dbg(dev->dev, "update SYSTEM_STATE : %s\n",
amd_pmf_uevent_as_str(event));
break;
+
+   case PMF_POLICY_DISPLAY_BRIGHTNESS:
+   if (!dev->gfx_data.gpu_dev_en)
+   return -ENODEV;
+
+   cdev->ops->get_cur_state(cdev, &state);
+   if (state != val) {
+   cdev->ops->set_cur_state(cdev, val);
+   dev_dbg(dev->dev, "update DISPLAY_BRIGHTNESS : 
%u\n", val);
+   }
+   break;
}
}
+
+   return 0;
 }
 
 static int amd_pmf_invoke_cmd_enact(struct amd_pmf_dev *dev)
@@ -192,7 +207,9 @@ static int amd_pmf_invoke_cmd_enact(struct amd_pmf_dev *dev)
amd_pmf_dump_ta_inputs(dev, in);
dev_dbg(dev->dev, "action count:%u result:%x\n", 
out->actions_count,
ta_sm->pmf_result);
-   amd_pmf_apply_policies(dev, out);
+   ret = amd_pmf_apply_policies(dev, out);
+   if (ret)
+   return ret;
}
 
return 0;
-- 
2.25.1



[PATCH v3 15/16] platform/x86/amd/pmf: Add PMF-AMDSFH interface for HPD

2023-10-10 Thread Shyam Sundar S K
From: Basavaraj Natikar 

AMDSFH has information about the User presence information via the Human
Presence Detection (HPD) sensor which is part of the AMD sensor fusion hub.
Add PMF and AMDSFH interface to get this information.

Co-developed-by: Shyam Sundar S K 
Signed-off-by: Shyam Sundar S K 
Signed-off-by: Basavaraj Natikar 
---
 drivers/hid/amd-sfh-hid/amd_sfh_common.h  |  5 
 drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c | 11 
 .../amd-sfh-hid/sfh1_1/amd_sfh_interface.c| 28 +++
 drivers/platform/x86/amd/pmf/Kconfig  |  1 +
 drivers/platform/x86/amd/pmf/spc.c| 21 ++
 include/linux/amd-pmf-io.h| 20 -
 6 files changed, 85 insertions(+), 1 deletion(-)

diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_common.h 
b/drivers/hid/amd-sfh-hid/amd_sfh_common.h
index 2643bb14fee2..cd57037bf217 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_common.h
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_common.h
@@ -37,6 +37,10 @@ struct amd_mp2_sensor_info {
dma_addr_t dma_address;
 };
 
+struct sfh_dev_status {
+   bool is_hpd_present;
+};
+
 struct amd_mp2_dev {
struct pci_dev *pdev;
struct amdtp_cl_data *cl_data;
@@ -47,6 +51,7 @@ struct amd_mp2_dev {
struct amd_input_data in_data;
/* mp2 active control status */
u32 mp2_acs;
+   struct sfh_dev_status dev_en;
 };
 
 struct amd_mp2_ops {
diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c 
b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c
index e9c6413af24a..3dc652d41d7d 100644
--- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c
+++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c
@@ -73,6 +73,12 @@ static int amd_sfh_hid_client_deinit(struct amd_mp2_dev 
*privdata)
int i, status;
 
for (i = 0; i < cl_data->num_hid_devices; i++) {
+   switch (cl_data->sensor_idx[i]) {
+   case HPD_IDX:
+   privdata->dev_en.is_hpd_present = false;
+   break;
+   }
+
if (cl_data->sensor_sts[i] == SENSOR_ENABLED) {
privdata->mp2_ops->stop(privdata, 
cl_data->sensor_idx[i]);
status = amd_sfh_wait_for_response
@@ -178,6 +184,11 @@ static int amd_sfh1_1_hid_client_init(struct amd_mp2_dev 
*privdata)
rc = amdtp_hid_probe(i, cl_data);
if (rc)
goto cleanup;
+   switch (cl_data->sensor_idx[i]) {
+   case HPD_IDX:
+   privdata->dev_en.is_hpd_present = true;
+   break;
+   }
}
dev_dbg(dev, "sid 0x%x (%s) status 0x%x\n",
cl_data->sensor_idx[i], 
get_sensor_name(cl_data->sensor_idx[i]),
diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c 
b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c
index 4f81ef2d4f56..7637da0dec6f 100644
--- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c
+++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c
@@ -7,11 +7,14 @@
  *
  * Author: Basavaraj Natikar 
  */
+#include 
 #include 
 #include 
 
 #include "amd_sfh_interface.h"
 
+static struct amd_mp2_dev *emp2;
+
 static int amd_sfh_wait_response(struct amd_mp2_dev *mp2, u8 sid, u32 cmd_id)
 {
struct sfh_cmd_response cmd_resp;
@@ -76,4 +79,29 @@ static struct amd_mp2_ops amd_sfh_ops = {
 void sfh_interface_init(struct amd_mp2_dev *mp2)
 {
mp2->mp2_ops = &amd_sfh_ops;
+   emp2 = mp2;
+}
+
+static int amd_sfh_hpd_info(u8 *user_present)
+{
+   if (emp2 && emp2->dev_en.is_hpd_present) {
+   struct hpd_status hpdstatus;
+
+   hpdstatus.val = readl(emp2->mmio + AMD_C2P_MSG(4));
+   *user_present = hpdstatus.shpd.presence;
+   return 0;
+   }
+   return -ENODEV;
+}
+
+int amd_get_sfh_info(struct amd_sfh_info *sfh_info, enum sfh_message_type op)
+{
+   if (sfh_info) {
+   switch (op) {
+   case MT_HPD:
+   return amd_sfh_hpd_info(&sfh_info->user_present);
+   }
+   }
+   return -EINVAL;
 }
+EXPORT_SYMBOL_GPL(amd_get_sfh_info);
diff --git a/drivers/platform/x86/amd/pmf/Kconfig 
b/drivers/platform/x86/amd/pmf/Kconfig
index 7f430de7af44..d368d35a49ac 100644
--- a/drivers/platform/x86/amd/pmf/Kconfig
+++ b/drivers/platform/x86/amd/pmf/Kconfig
@@ -11,6 +11,7 @@ config AMD_PMF
select ACPI_PLATFORM_PROFILE
depends on TEE && AMDTEE
depends on DRM_AMDGPU
+   depends on AMD_SFH_HID
help
  This driver provides support for the AMD Platform Management 
Framework.
  The goal is to enhance end user experience by making AMD PCs smarter,
diff --git a/drivers/platform/x86/amd/pmf/spc.c 
b/drivers/platform/x86/amd/pmf/spc.c
index 58b51e11e424..e33bbf8a3de4 100644
--- a/drivers/platform/

[PATCH v3 14/16] HID: amd_sfh: rename float_to_int() to amd_sfh_float_to_int()

2023-10-10 Thread Shyam Sundar S K
From: Basavaraj Natikar 

Current amd_sfh driver has float_to_int() to convert units from
float to int. This is fine until this function gets called outside of
the current scope of file.

Add a prefix "amd_sfh" to float_to_int() so that function represents
the driver name. This function will be called by multiple callers in the
next patch.

Co-developed-by: Shyam Sundar S K 
Signed-off-by: Shyam Sundar S K 
Signed-off-by: Basavaraj Natikar 
---
 drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c | 22 +--
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c 
b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c
index 06bdcf072d10..47a87b28e00e 100644
--- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c
+++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c
@@ -132,7 +132,7 @@ static void get_common_inputs(struct common_input_property 
*common, int report_i
common->event_type = HID_USAGE_SENSOR_EVENT_DATA_UPDATED_ENUM;
 }
 
-static int float_to_int(u32 flt32_val)
+static int amd_sfh_float_to_int(u32 flt32_val)
 {
int fraction, shift, mantissa, sign, exp, zeropre;
 
@@ -200,9 +200,9 @@ static u8 get_input_rep(u8 current_index, int sensor_idx, 
int report_id,
 OFFSET_SENSOR_DATA_DEFAULT;
memcpy_fromio(&accel_data, sensoraddr, sizeof(struct 
sfh_accel_data));
get_common_inputs(&acc_input.common_property, report_id);
-   acc_input.in_accel_x_value = 
float_to_int(accel_data.acceldata.x) / 100;
-   acc_input.in_accel_y_value = 
float_to_int(accel_data.acceldata.y) / 100;
-   acc_input.in_accel_z_value = 
float_to_int(accel_data.acceldata.z) / 100;
+   acc_input.in_accel_x_value = 
amd_sfh_float_to_int(accel_data.acceldata.x) / 100;
+   acc_input.in_accel_y_value = 
amd_sfh_float_to_int(accel_data.acceldata.y) / 100;
+   acc_input.in_accel_z_value = 
amd_sfh_float_to_int(accel_data.acceldata.z) / 100;
memcpy(input_report, &acc_input, sizeof(acc_input));
report_size = sizeof(acc_input);
break;
@@ -211,9 +211,9 @@ static u8 get_input_rep(u8 current_index, int sensor_idx, 
int report_id,
 OFFSET_SENSOR_DATA_DEFAULT;
memcpy_fromio(&gyro_data, sensoraddr, sizeof(struct 
sfh_gyro_data));
get_common_inputs(&gyro_input.common_property, report_id);
-   gyro_input.in_angel_x_value = 
float_to_int(gyro_data.gyrodata.x) / 1000;
-   gyro_input.in_angel_y_value = 
float_to_int(gyro_data.gyrodata.y) / 1000;
-   gyro_input.in_angel_z_value = 
float_to_int(gyro_data.gyrodata.z) / 1000;
+   gyro_input.in_angel_x_value = 
amd_sfh_float_to_int(gyro_data.gyrodata.x) / 1000;
+   gyro_input.in_angel_y_value = 
amd_sfh_float_to_int(gyro_data.gyrodata.y) / 1000;
+   gyro_input.in_angel_z_value = 
amd_sfh_float_to_int(gyro_data.gyrodata.z) / 1000;
memcpy(input_report, &gyro_input, sizeof(gyro_input));
report_size = sizeof(gyro_input);
break;
@@ -222,9 +222,9 @@ static u8 get_input_rep(u8 current_index, int sensor_idx, 
int report_id,
 OFFSET_SENSOR_DATA_DEFAULT;
memcpy_fromio(&mag_data, sensoraddr, sizeof(struct 
sfh_mag_data));
get_common_inputs(&magno_input.common_property, report_id);
-   magno_input.in_magno_x = float_to_int(mag_data.magdata.x) / 100;
-   magno_input.in_magno_y = float_to_int(mag_data.magdata.y) / 100;
-   magno_input.in_magno_z = float_to_int(mag_data.magdata.z) / 100;
+   magno_input.in_magno_x = 
amd_sfh_float_to_int(mag_data.magdata.x) / 100;
+   magno_input.in_magno_y = 
amd_sfh_float_to_int(mag_data.magdata.y) / 100;
+   magno_input.in_magno_z = 
amd_sfh_float_to_int(mag_data.magdata.z) / 100;
magno_input.in_magno_accuracy = mag_data.accuracy / 100;
memcpy(input_report, &magno_input, sizeof(magno_input));
report_size = sizeof(magno_input);
@@ -234,7 +234,7 @@ static u8 get_input_rep(u8 current_index, int sensor_idx, 
int report_id,
 OFFSET_SENSOR_DATA_DEFAULT;
memcpy_fromio(&als_data, sensoraddr, sizeof(struct 
sfh_als_data));
get_common_inputs(&als_input.common_property, report_id);
-   als_input.illuminance_value = float_to_int(als_data.lux);
+   als_input.illuminance_value = 
amd_sfh_float_to_int(als_data.lux);
report_size = sizeof(als_input);
memcpy(input_report, &als_input, sizeof(als_input));
break;
-- 
2.25.1



[PATCH v3 16/16] platform/x86/amd/pmf: Add PMF-AMDSFH interface for ALS

2023-10-10 Thread Shyam Sundar S K
From: Basavaraj Natikar 

AMDSFH has information about the Ambient light via the Ambient
Light Sensor (ALS) which is part of the AMD sensor fusion hub.
Add PMF and AMDSFH interface to get this information.

make amd_sfh_float_to_int() as non-static function so that this can
be called outside of the current file.

Co-developed-by: Shyam Sundar S K 
Signed-off-by: Shyam Sundar S K 
Signed-off-by: Basavaraj Natikar 
---
 drivers/hid/amd-sfh-hid/amd_sfh_common.h  |  1 +
 drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c |  2 +-
 drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c |  6 ++
 .../amd-sfh-hid/sfh1_1/amd_sfh_interface.c| 20 +++
 .../amd-sfh-hid/sfh1_1/amd_sfh_interface.h|  1 +
 drivers/platform/x86/amd/pmf/spc.c|  7 +++
 include/linux/amd-pmf-io.h|  2 ++
 7 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_common.h 
b/drivers/hid/amd-sfh-hid/amd_sfh_common.h
index cd57037bf217..a1950bc6e6ce 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_common.h
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_common.h
@@ -39,6 +39,7 @@ struct amd_mp2_sensor_info {
 
 struct sfh_dev_status {
bool is_hpd_present;
+   bool is_als_present;
 };
 
 struct amd_mp2_dev {
diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c 
b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c
index 47a87b28e00e..dbc8c6943ca1 100644
--- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c
+++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c
@@ -132,7 +132,7 @@ static void get_common_inputs(struct common_input_property 
*common, int report_i
common->event_type = HID_USAGE_SENSOR_EVENT_DATA_UPDATED_ENUM;
 }
 
-static int amd_sfh_float_to_int(u32 flt32_val)
+int amd_sfh_float_to_int(u32 flt32_val)
 {
int fraction, shift, mantissa, sign, exp, zeropre;
 
diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c 
b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c
index 3dc652d41d7d..f2890d329459 100644
--- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c
+++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c
@@ -77,6 +77,9 @@ static int amd_sfh_hid_client_deinit(struct amd_mp2_dev 
*privdata)
case HPD_IDX:
privdata->dev_en.is_hpd_present = false;
break;
+   case ALS_IDX:
+   privdata->dev_en.is_als_present = false;
+   break;
}
 
if (cl_data->sensor_sts[i] == SENSOR_ENABLED) {
@@ -188,6 +191,9 @@ static int amd_sfh1_1_hid_client_init(struct amd_mp2_dev 
*privdata)
case HPD_IDX:
privdata->dev_en.is_hpd_present = true;
break;
+   case ALS_IDX:
+   privdata->dev_en.is_als_present = true;
+   break;
}
}
dev_dbg(dev, "sid 0x%x (%s) status 0x%x\n",
diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c 
b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c
index 7637da0dec6f..48a7a450e029 100644
--- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c
+++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c
@@ -94,12 +94,32 @@ static int amd_sfh_hpd_info(u8 *user_present)
return -ENODEV;
 }
 
+static int amd_sfh_als_info(u32 *ambient_light)
+{
+   if (emp2 && emp2->dev_en.is_als_present) {
+   struct sfh_als_data als_data;
+   void __iomem *sensoraddr;
+
+   sensoraddr = emp2->vsbase +
+   (ALS_IDX * SENSOR_DATA_MEM_SIZE_DEFAULT) +
+   OFFSET_SENSOR_DATA_DEFAULT;
+   memcpy_fromio(&als_data, sensoraddr, sizeof(struct 
sfh_als_data));
+   *ambient_light = amd_sfh_float_to_int(als_data.lux);
+
+   return 0;
+   }
+
+   return -ENODEV;
+}
+
 int amd_get_sfh_info(struct amd_sfh_info *sfh_info, enum sfh_message_type op)
 {
if (sfh_info) {
switch (op) {
case MT_HPD:
return amd_sfh_hpd_info(&sfh_info->user_present);
+   case MT_ALS:
+   return amd_sfh_als_info(&sfh_info->ambient_light);
}
}
return -EINVAL;
diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h 
b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h
index 9d31d5b510eb..7ecddad430e4 100644
--- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h
+++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h
@@ -149,6 +149,7 @@ struct hpd_status {
};
 };
 
+int amd_sfh_float_to_int(u32 flt32_val);
 void sfh_interface_init(struct amd_mp2_dev *mp2);
 void amd_sfh1_1_set_desc_ops(struct amd_mp2_ops *mp2_ops);
 #endif
diff --git a/drivers/platform/x86/amd/pmf/spc.c 
b/drivers/platform/x86/amd/pmf/spc.c
index e33bbf8a3de4..b6cf6d7e6ef5 100644
--- a/drivers/platform

Re: [PATCH v4 2/4] drm/panic: Add a drm panic handler

2023-10-10 Thread Thomas Zimmermann

Hi

Am 10.10.23 um 11:33 schrieb Maxime Ripard:
[...]

We also have discussions about kexec/kdump support. Here we'd need to
retrieve the scanout address, forward it to the kexec kernel and put
simpledrm onto that framebuffer until the regular driver takes over.


Generically speaking, there's strictly no guarantee that the current
scanout buffer is accessible by the CPU. It's not even a driver issue,
it's a workload issue, so it will affect 100% of the times some users,
and some 0% of the time.


And I'd be OK with that. It's all best effort anyway.




An interface like get_scanout_buffer will be helpful for this use
case. So it makes sense to use it for the panic handler as well.


It won't be helpful because the vast majority of the ARM drivers (and
thus the vast majority of the KMS drivers) won't be able to implement it
properly and reliably.


The barrier for firmware-based drivers is low: a pre-configured display 
and mmap'able framebuffer memory. And it's assumed that a callback for 
kexec would attempt to configure hardware accordingly. If a system 
really cannot provide this, so be it.





run the atomic_update() on it, and return this commit's framebuffer ?

That way each driver have a better control on what the panic handler will
do.
It can even call directly its internal functions, to avoid the locks of the
drm generic functions, and make sure it will only change the format and base
address.
That's a bit more work for each driver, but should be more reliable I think.


I don't think that better control there is a good idea, it's a path that
won't get tested much so we'd be better off not allowing drivers to
deviate too much from the "ideal" design.

What I had in mind is something like:

- Add a panic hook in drm_mode_config_funcs, with a
  drm_atomic_helper_panic helper;

- Provide an atomic_panic hook or something in drm_plane_helper_funcs;

- If they are set, we register the drm_panic handler;

- The handler will call drm_mode_config_funcs.panic, which will take
  its prepared state, fill the framebuffer it allocated with the
  penguin and backtrace, call drm_plane_helper_funcs.atomic_panic().

- The driver now updates the format and fb address.

- Halt and catch fire

Does that make sense?


Please see my other replies. I find this fragile, and unnecessary for cases
where there already is a working scanout buffer in place.


And please see my other replies. Depending on a working scanout buffer
in place being accessible by the CPU is incredibly limiting. Ignoring it
when I'm pointing that out won't get us to a solution acceptable for
everyone.


It's something a driver could implement internally to provide a
scanout buffer if none has been set up already.


Some drivers need extra resources when setting up a plane. VC4 for
example need for every plane to allocate multiple internal SRAM buffers.
Just allocating an extra framebuffer won't cut it.

This is tied to the state so far, so I guess we would need to allocate a
new state. Oh, and if we have several drivers that need to allocate that
extra framebuffer and state, we could make it part of the core or turn
it into a helper?


I mentioned that even the simple drivers hold locks during the atomic 
commit. Some of the drivers use vmap/vunmap, which might make problems 
as well. It's used in the context of damage handling, which also makes 
no sense here. So the regular atomic helpers most likely won't work.


It sounds to me as if you're essentially asking for something like a 
flush or sync operation.


Stepping back from get_scanout_buffer for a moment and adopting your 
proposal from above, I can see something like this working:


  - the driver provides a panic callback in struct drm_driver

  - DRM registers a panic handler to invokes the callback

  - the panic callback has a scanout buffer from somewhere (currently 
active, prepared, from firmware, plain memory, etc)


  - we provide a helper that fills the scanout buffer with information

  - the driver then updates the hardware from/with the scanout buffer; 
details depend on the hardware


The final step is like a flush or commit operation. To give some 
examples: The simple drivers of this patchset probably don't have to do 
anything. Drivers with command/packet queues could attempt to send the 
necessary commands to the device.


Best regards
Thomas



Maxime


--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [PATCH v3 11/16] platform/x86/amd/pmf: dump policy binary data

2023-10-10 Thread Ilpo Järvinen
On Tue, 10 Oct 2023, Shyam Sundar S K wrote:

> Sometimes policy binary retrieved from the BIOS maybe incorrect that can
> end up in failing to enable the Smart PC solution feature.
> 
> Use print_hex_dump_debug() to dump the policy binary in hex, so that we
> debug the issues related to the binary even before sending that to TA.
> 
> Signed-off-by: Shyam Sundar S K 
> ---
>  drivers/platform/x86/amd/pmf/tee-if.c | 9 +
>  1 file changed, 9 insertions(+)
> 
> diff --git a/drivers/platform/x86/amd/pmf/tee-if.c 
> b/drivers/platform/x86/amd/pmf/tee-if.c
> index 994daf945795..e4386f503ad0 100644
> --- a/drivers/platform/x86/amd/pmf/tee-if.c
> +++ b/drivers/platform/x86/amd/pmf/tee-if.c
> @@ -275,6 +275,12 @@ static int amd_pmf_start_policy_engine(struct 
> amd_pmf_dev *dev)
>  }
>  
>  #ifdef CONFIG_AMD_PMF_DEBUG
> +static void amd_pmf_hex_dump_pb(struct amd_pmf_dev *dev)
> +{
> + print_hex_dump_debug("(pb):  ", DUMP_PREFIX_OFFSET, 16, 1, 
> dev->policy_buf,
> +  dev->policy_sz, false);
> +}
> +

You forgot to add the empty version of amd_pmf_hex_dump_pb function into 
#else part (so the compile fails if CONFIG_AMD_PMF_DEBUG is not set).

>  static ssize_t amd_pmf_get_pb_data(struct file *filp, const char __user *buf,
>  size_t length, loff_t *pos)
>  {
> @@ -289,6 +295,7 @@ static ssize_t amd_pmf_get_pb_data(struct file *filp, 
> const char __user *buf,
>   if (copy_from_user(dev->policy_buf, buf, dev->policy_sz))
>   return -EFAULT;
>  
> + amd_pmf_hex_dump_pb(dev);
>   ret = amd_pmf_start_policy_engine(dev);
>   if (ret)
>   return -EINVAL;
> @@ -327,6 +334,7 @@ static int amd_pmf_open_pb(struct amd_pmf_dev *dev, 
> struct dentry *debugfs_root)
>  }
>  
>  static void amd_pmf_remove_pb(struct amd_pmf_dev *dev) {}
> +static void amd_pmf_hex_dump_pb(struct amd_pmf_dev *dev) {}
>  #endif
>  
>  static int amd_pmf_get_bios_buffer(struct amd_pmf_dev *dev)
> @@ -341,6 +349,7 @@ static int amd_pmf_get_bios_buffer(struct amd_pmf_dev 
> *dev)
>  
>   memcpy(dev->policy_buf, dev->policy_base, dev->policy_sz);
>  
> + amd_pmf_hex_dump_pb(dev);
>   if (pb_side_load)
>   amd_pmf_open_pb(dev, dev->dbgfs_dir);
>  
> 

-- 
 i.



Re: [PATCH 1/2] accel/qaic: Add support for periodic timesync

2023-10-10 Thread kernel test robot
Hi Jeffrey,

kernel test robot noticed the following build errors:

[auto build test ERROR on drm-misc/drm-misc-next]
[also build test ERROR on next-20231010]
[cannot apply to linus/master v6.6-rc5]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:
https://github.com/intel-lab-lkp/linux/commits/Jeffrey-Hugo/accel-qaic-Add-support-for-periodic-timesync/20231007-003324
base:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link:
https://lore.kernel.org/r/20231006163210.21319-2-quic_jhugo%40quicinc.com
patch subject: [PATCH 1/2] accel/qaic: Add support for periodic timesync
config: powerpc-randconfig-003-20231010 
(https://download.01.org/0day-ci/archive/20231010/202310102021.xkvfihrt-...@intel.com/config)
compiler: powerpc-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): 
(https://download.01.org/0day-ci/archive/20231010/202310102021.xkvfihrt-...@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot 
| Closes: 
https://lore.kernel.org/oe-kbuild-all/202310102021.xkvfihrt-...@intel.com/

All errors (new ones prefixed by >>):

   drivers/accel/qaic/qaic_timesync.c: In function 'qaic_timesync_timer':
>> drivers/accel/qaic/qaic_timesync.c:125:25: error: implicit declaration of 
>> function 'readq'; did you mean 'readl'? 
>> [-Werror=implicit-function-declaration]
 125 | device_qtimer = readq(mqtsdev->qtimer_addr);
 | ^
 | readl
   cc1: some warnings being treated as errors


vim +125 drivers/accel/qaic/qaic_timesync.c

   102  
   103  static void qaic_timesync_timer(struct timer_list *t)
   104  {
   105  struct mqts_dev *mqtsdev = from_timer(mqtsdev, t, timer);
   106  struct qts_host_time_sync_msg_data *sync_msg;
   107  u64 device_qtimer_us;
   108  u64 device_qtimer;
   109  u64 host_time_us;
   110  u64 offset_us;
   111  u64 host_sec;
   112  int ret;
   113  
   114  if (atomic_read(&mqtsdev->buff_in_use)) {
   115  dev_dbg(mqtsdev->dev, "%s buffer not free, schedule 
next cycle\n", __func__);
   116  goto mod_timer;
   117  }
   118  atomic_set(&mqtsdev->buff_in_use, 1);
   119  
   120  sync_msg = mqtsdev->sync_msg;
   121  sync_msg->header.signature = 
cpu_to_le16(QAIC_TIMESYNC_SIGNATURE);
   122  sync_msg->header.msg_type = QAIC_TS_SYNC_REQ;
   123  /* Read host UTC time and convert to uS*/
   124  host_time_us = div_u64(ktime_get_real_ns(), NSEC_PER_USEC);
 > 125  device_qtimer = readq(mqtsdev->qtimer_addr);
   126  device_qtimer_us = QAIC_CONV_QTIMER_TO_US(device_qtimer);
   127  /* Offset between host UTC and device time */
   128  offset_us = host_time_us - device_qtimer_us;
   129  
   130  host_sec = div_u64(offset_us, USEC_PER_SEC);
   131  sync_msg->data.tv_usec = cpu_to_le64(offset_us - host_sec * 
USEC_PER_SEC);
   132  sync_msg->data.tv_sec = cpu_to_le64(host_sec);
   133  ret = mhi_queue_buf(mqtsdev->mhi_dev, DMA_TO_DEVICE, sync_msg, 
sizeof(*sync_msg), MHI_EOT);
   134  if (ret && (ret != -EAGAIN)) {
   135  dev_err(mqtsdev->dev, "%s unable to queue to mhi:%d\n", 
__func__, ret);
   136  return;
   137  } else if (ret == -EAGAIN) {
   138  atomic_set(&mqtsdev->buff_in_use, 0);
   139  }
   140  
   141  mod_timer:
   142  ret = mod_timer(t, jiffies + 
msecs_to_jiffies(timesync_delay_ms));
   143  if (ret)
   144  dev_err(mqtsdev->dev, "%s mod_timer error:%d\n", 
__func__, ret);
   145  }
   146  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


Re: [PATCH 1/2] drm/tegra: Return an error code if fails

2023-10-10 Thread Thierry Reding
On Mon, Jun 26, 2023 at 10:33:30PM +0800, Sui Jingfeng wrote:
> Return -ENOMEM if tegra_bo_mmap() fails.
> 
> Signed-off-by: Sui Jingfeng 
> ---
>  drivers/gpu/drm/tegra/gem.c | 2 ++
>  1 file changed, 2 insertions(+)

Sorry, this fell through the cracks. I think it'd be better if
tegra_bo_mmap() were to be improved to always return either an ERR_PTR()
encoded error code or a valid pointer. Throwing NULL into the mix isn't
useful because it typically means something like -ENOMEM anyway. Error
codes are more explicit, so since we're already using them for some
cases, might as well return them for all.

Actually, looks like tegra_bo_mmap() never actually returns an ERR_PTR()
encoded error code. It's either obj->vaddr, the return value of vmap()
(which is either NULL or the address of the mapping), or the address
obtained from dma_buf_vmap_unlocked() (i.e. map.vaddr) or NULL on
failure. So I think it would equally make sense to keep your patch and
to remove the IS_ERR() check below it.

I would slightly prefer the first option, but either is fine.

Thierry

> diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
> index dea38892d6e6..0ce22935fbd3 100644
> --- a/drivers/gpu/drm/tegra/gem.c
> +++ b/drivers/gpu/drm/tegra/gem.c
> @@ -710,6 +710,8 @@ static int tegra_gem_prime_vmap(struct dma_buf *buf, 
> struct iosys_map *map)
>   void *vaddr;
>  
>   vaddr = tegra_bo_mmap(&bo->base);
> + if (!vaddr)
> + return -ENOMEM;
>   if (IS_ERR(vaddr))
>   return PTR_ERR(vaddr);
>  
> -- 
> 2.25.1
> 


signature.asc
Description: PGP signature


Re: [PATCH v4 2/4] drm/panic: Add a drm panic handler

2023-10-10 Thread Thomas Zimmermann

Hi

Am 10.10.23 um 14:59 schrieb Daniel Vetter:
[...]




Why can't we use the model[1] suggested by Daniel using a draw_pixel
callback giving drivers full control on how they can put a pixel on the
display?


I share kind of the same general ideas/conclusions: "qthe idea is that
all the fb selection and lookup is handled in shared code (and with
proper locking, but only for atomic drivers)."

2016 is a bit old though and multiple developments happened since
(secure playback is a thing now, framebuffer compression too), so I
still think that their expectation that the framebuffer is accessible to
/ writable by the CPU no longer holds true.


I think largely it should still be ok, because the idea behind the draw_xy
callback was that the driver could take care of anything special, like
- tiling
- clearing compression bits so that just writing the raw pixels works (if
   your compression format allows for that)
- handling any differences in how the pixels need to be written, like
   cache flushing, mmio_write vs normal memory, amd also has peek/poke
   registers to be able to write even into unmappable memory

What would probably be a good idea is to do an s/void */uinptr_t/ over my
interface proposal, or maybe an even more opaque cookie since really the
only thing you can do is get the void * that ->panic_vmap returns and pass
it into ->panic_draw_xy.

I thought (but I didn't dig through details) that the panic fb struct is
essentially meant to serve this purpose in the current series?


I have one detail about the code: While working on the format-conversion 
code, I've always found struct drm_framebuffer to be clunky to work 
with. It's build around the idea of managing GEM buffers, but not 
accessing them.


So I've been thinking about something like a drm_pixmap that contains 
size, color format and data pointers in one place. Reads and writes 
would be callbacks. It could abstract access to any kind of buffer. 
IIRC Jocelyn had something like that in the very first patchset. or 
maybe fb_pixmap could be repurposed.


Best regards
Thomas




This will even work for the AMD debug interface.
In the linear CPU accessible buffer case, we can provide a helper for
that, maybe we can do helpers for other common cases as well.


Yeah, their idea of a panic_draw would work great for that.


Adding to that we would need a panic_setup/enter and panic_teardown/exit
callback.


What for?


So panic teardown would be for testing in CI, to make it non-destructive
and clean up anything panic_vmap (or _enter or whatever you call it) has
done. I thought John Oggness was also looking into how the new panic
handlers/consoles could be made testable in the panic paths, including
lock stealing and getting called from nmi.
-Sima


--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [PATCH v4 2/4] drm/panic: Add a drm panic handler

2023-10-10 Thread Jocelyn Falempe

On 10/10/2023 14:59, Daniel Vetter wrote:

On Tue, Oct 10, 2023 at 02:15:47PM +0200, Maxime Ripard wrote:

On Tue, Oct 10, 2023 at 01:29:52PM +0200, Noralf Trønnes wrote:



On 10/10/23 11:25, Maxime Ripard wrote:



On Tue, Oct 10, 2023 at 10:55:09AM +0200, Thomas Zimmermann wrote:

So if I understand correctly, drm_panic would pre-allocate a plane/commit,
and use that when a panic occurs ?


And have it checked already, yes. We would only wait for a panic to
happen to pull the trigger on the commit.


I have two concern about this approach:
- How much memory would be allocated for this ? a whole framebuffer can be
big for just this use case.


As I outlined in my email at [1], there are a number of different scenarios.
The question of atomic state and commits is entirely separate from the DRM
panic handler. We should not throw them together. Whatever is necessary is
get a scanout buffer, should happen on the driver side of
get_scanout_buffer, not on the drm_panic side.

[1] 
https://lore.kernel.org/dri-devel/39bd4c35-8a61-42ee-8675-ccea4f5d4...@suse.de/T/#m22f116e9438e00a5f0a9dc43987d4153424f8be1



I'dd expect a whole framebuffer for the current
configuration/resolution. It would be typically 4MB for a full-HD system
which isn't a lot really and I guess we can always add an option to
disable the mechanism if needed.


- I find it risky to completely reconfigure the hardware in a panic handler.


I would expect to only change the format and base address of the
framebuffer. I guess it can fail, but it doesn't seem that different to
the async plane update we already have and works well.


The one thing I don't understand is: Why should we use atomic commits in the
first place? It doesn't make sense for firmware-based drivers.


Because this is generic infrastructure that is valuable for any drivers
and not only firmware-based drivers?


In some drivers, even the simple ast, we hold locks during the regular
commit. Trying to run the panic commit concurrently will likely give a
deadlock.


You're in the middle of a panic. Don't take any locks and you won't deadlock.


In the end it's a per-driver decision, but in most cases, the driver can
easily switch to a default mode with some ad-hoc code.


When was the last time a per-driver decision has been a good thing? I'm
sorry, but the get_scanout_buffer approach buffer won't work for any
driver out there.

I'm fine with discussing alternatives if you don't like the ones I
suggested, but they must allow the panic handler infrastructure to work
with any driver we have, not just 4.



Why can't we use the model[1] suggested by Daniel using a draw_pixel
callback giving drivers full control on how they can put a pixel on the
display?


I share kind of the same general ideas/conclusions: "qthe idea is that
all the fb selection and lookup is handled in shared code (and with
proper locking, but only for atomic drivers)."

2016 is a bit old though and multiple developments happened since
(secure playback is a thing now, framebuffer compression too), so I
still think that their expectation that the framebuffer is accessible to
/ writable by the CPU no longer holds true.


I think largely it should still be ok, because the idea behind the draw_xy
callback was that the driver could take care of anything special, like
- tiling
- clearing compression bits so that just writing the raw pixels works (if
   your compression format allows for that)
- handling any differences in how the pixels need to be written, like
   cache flushing, mmio_write vs normal memory, amd also has peek/poke
   registers to be able to write even into unmappable memory

What would probably be a good idea is to do an s/void */uinptr_t/ over my
interface proposal, or maybe an even more opaque cookie since really the
only thing you can do is get the void * that ->panic_vmap returns and pass
it into ->panic_draw_xy.

I thought (but I didn't dig through details) that the panic fb struct is
essentially meant to serve this purpose in the current series?



Yes, in this series there is a struct drm_scanout_buffer, that the 
driver has to provide when a panic occurs:


struct drm_scanout_buffer {
const struct drm_format_info *format;
struct iosys_map map;
unsigned int pitch;
unsigned int width;
unsigned int height;
};

That works well for CPU accessible, linear format.
It should be possible to support YUV, or simple tiling with that, but 
for the more complex case, I proposed to add a draw_pixel() callback.



This will even work for the AMD debug interface.
In the linear CPU accessible buffer case, we can provide a helper for
that, maybe we can do helpers for other common cases as well.


Yeah, their idea of a panic_draw would work great for that.


Adding to that we would need a panic_setup/enter and panic_teardown/exit
callback.


What for?


So panic teardown would be for testing in CI, to make it non-destructive
and clean up anything panic_vmap (or _enter or whatever

Re: [PATCH v4 2/4] drm/panic: Add a drm panic handler

2023-10-10 Thread Jocelyn Falempe

On 10/10/2023 15:05, Thomas Zimmermann wrote:

Hi

Am 10.10.23 um 11:33 schrieb Maxime Ripard:
[...]

We also have discussions about kexec/kdump support. Here we'd need to
retrieve the scanout address, forward it to the kexec kernel and put
simpledrm onto that framebuffer until the regular driver takes over.


Generically speaking, there's strictly no guarantee that the current
scanout buffer is accessible by the CPU. It's not even a driver issue,
it's a workload issue, so it will affect 100% of the times some users,
and some 0% of the time.


And I'd be OK with that. It's all best effort anyway.




An interface like get_scanout_buffer will be helpful for this use
case. So it makes sense to use it for the panic handler as well.


It won't be helpful because the vast majority of the ARM drivers (and
thus the vast majority of the KMS drivers) won't be able to implement it
properly and reliably.


The barrier for firmware-based drivers is low: a pre-configured display 
and mmap'able framebuffer memory. And it's assumed that a callback for 
kexec would attempt to configure hardware accordingly. If a system 
really cannot provide this, so be it.





run the atomic_update() on it, and return this commit's framebuffer ?

That way each driver have a better control on what the panic 
handler will

do.
It can even call directly its internal functions, to avoid the 
locks of the
drm generic functions, and make sure it will only change the format 
and base

address.
That's a bit more work for each driver, but should be more reliable 
I think.


I don't think that better control there is a good idea, it's a path 
that

won't get tested much so we'd be better off not allowing drivers to
deviate too much from the "ideal" design.

What I had in mind is something like:

    - Add a panic hook in drm_mode_config_funcs, with a
  drm_atomic_helper_panic helper;

    - Provide an atomic_panic hook or something in 
drm_plane_helper_funcs;


    - If they are set, we register the drm_panic handler;

    - The handler will call drm_mode_config_funcs.panic, which will 
take

  its prepared state, fill the framebuffer it allocated with the
  penguin and backtrace, call 
drm_plane_helper_funcs.atomic_panic().


    - The driver now updates the format and fb address.

    - Halt and catch fire

Does that make sense?


Please see my other replies. I find this fragile, and unnecessary for 
cases

where there already is a working scanout buffer in place.


And please see my other replies. Depending on a working scanout buffer
in place being accessible by the CPU is incredibly limiting. Ignoring it
when I'm pointing that out won't get us to a solution acceptable for
everyone.


It's something a driver could implement internally to provide a
scanout buffer if none has been set up already.


Some drivers need extra resources when setting up a plane. VC4 for
example need for every plane to allocate multiple internal SRAM buffers.
Just allocating an extra framebuffer won't cut it.

This is tied to the state so far, so I guess we would need to allocate a
new state. Oh, and if we have several drivers that need to allocate that
extra framebuffer and state, we could make it part of the core or turn
it into a helper?


I mentioned that even the simple drivers hold locks during the atomic 
commit. Some of the drivers use vmap/vunmap, which might make problems 
as well. It's used in the context of damage handling, which also makes 
no sense here. So the regular atomic helpers most likely won't work.


It sounds to me as if you're essentially asking for something like a 
flush or sync operation.


Stepping back from get_scanout_buffer for a moment and adopting your 
proposal from above, I can see something like this working:


   - the driver provides a panic callback in struct drm_driver

   - DRM registers a panic handler to invokes the callback

   - the panic callback has a scanout buffer from somewhere (currently 
active, prepared, from firmware, plain memory, etc)


   - we provide a helper that fills the scanout buffer with information

   - the driver then updates the hardware from/with the scanout buffer; 
details depend on the hardware


The final step is like a flush or commit operation. To give some 
examples: The simple drivers of this patchset probably don't have to do 
anything. Drivers with command/packet queues could attempt to send the 
necessary commands to the device.


Yes that was the second question in the cover letter.
Some drivers probably want a flush_scanout_buffer() to send the 
framebuffer to the hardware.

That callback can be in struct drm_driver as well.

--

Jocelyn



Best regards
Thomas



Maxime






[PATCH v7 02/20] drm/gpuvm: Helper to get range of unmap from a remap op.

2023-10-10 Thread Sarah Walker
From: Donald Robson 

Determining the start and range of the unmap stage of a remap op is a
common piece of code currently implemented by multiple drivers. Add a
helper for this.

Changes since v6:
- Remove use of __always_inline

Signed-off-by: Donald Robson 
Signed-off-by: Sarah Walker 
---
 include/drm/drm_gpuvm.h | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/include/drm/drm_gpuvm.h b/include/drm/drm_gpuvm.h
index c7ed6bf441d4..932e942da921 100644
--- a/include/drm/drm_gpuvm.h
+++ b/include/drm/drm_gpuvm.h
@@ -702,4 +702,31 @@ void drm_gpuva_remap(struct drm_gpuva *prev,
 
 void drm_gpuva_unmap(struct drm_gpuva_op_unmap *op);
 
+/**
+ * drm_gpuva_op_remap_get_unmap_range() - Helper to get the start and range of
+ * the unmap stage of a remap op.
+ * @op: Remap op.
+ * @start_addr: Output pointer for the start of the required unmap.
+ * @range: Output pointer for the length of the required unmap.
+ *
+ * These parameters can then be used by the caller to unmap memory pages that
+ * are no longer required.
+ */
+static inline void
+drm_gpuva_op_remap_get_unmap_range(const struct drm_gpuva_op_remap *op,
+  u64 *start_addr, u64 *range)
+{
+   const u64 va_start = op->prev ?
+op->prev->va.addr + op->prev->va.range :
+op->unmap->va->va.addr;
+   const u64 va_end = op->next ?
+  op->next->va.addr :
+  op->unmap->va->va.addr + op->unmap->va->va.range;
+
+   if (start_addr)
+   *start_addr = va_start;
+   if (range)
+   *range = va_end - va_start;
+}
+
 #endif /* __DRM_GPUVM_H__ */
-- 
2.42.0



[PATCH v7 01/20] sizes.h: Add entries between SZ_32G and SZ_64T

2023-10-10 Thread Sarah Walker
From: Matt Coster 

sizes.h has a gap in defines between SZ_32G and SZ_64T. Add the missing
defines so they can be used in drivers.

Signed-off-by: Matt Coster 
Signed-off-by: Sarah Walker 
Reviewed-by: Linus Walleij 
---
 include/linux/sizes.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/include/linux/sizes.h b/include/linux/sizes.h
index 84aa448d8bb3..c3a00b967d18 100644
--- a/include/linux/sizes.h
+++ b/include/linux/sizes.h
@@ -47,8 +47,17 @@
 #define SZ_8G  _AC(0x2, ULL)
 #define SZ_16G _AC(0x4, ULL)
 #define SZ_32G _AC(0x8, ULL)
+#define SZ_64G _AC(0x10, ULL)
+#define SZ_128G_AC(0x20, ULL)
+#define SZ_256G_AC(0x40, ULL)
+#define SZ_512G_AC(0x80, ULL)
 
 #define SZ_1T  _AC(0x100, ULL)
+#define SZ_2T  _AC(0x200, ULL)
+#define SZ_4T  _AC(0x400, ULL)
+#define SZ_8T  _AC(0x800, ULL)
+#define SZ_16T _AC(0x1000, ULL)
+#define SZ_32T _AC(0x2000, ULL)
 #define SZ_64T _AC(0x4000, ULL)
 
 #endif /* __LINUX_SIZES_H__ */
-- 
2.42.0



[PATCH v7 00/20] Imagination Technologies PowerVR DRM driver

2023-10-10 Thread Sarah Walker
This patch series adds the initial DRM driver for Imagination Technologies 
PowerVR
GPUs, starting with those based on our Rogue architecture. It's worth pointing
out that this is a new driver, written from the ground up, rather than a
refactored version of our existing downstream driver (pvrsrvkm).

This new DRM driver supports:
- GEM shmem allocations
- dma-buf / PRIME
- Per-context userspace managed virtual address space
- DRM sync objects (binary and timeline)
- Power management suspend / resume
- GPU job submission (geometry, fragment, compute, transfer)
- META firmware processor
- MIPS firmware processor
- GPU hang detection and recovery

Currently our main focus is on the AXE-1-16M GPU. Testing so far has been done
using a TI SK-AM62 board (AXE-1-16M GPU). Firmware for the AXE-1-16M can be
found here:
https://gitlab.freedesktop.org/frankbinns/linux-firmware/-/tree/powervr

A Vulkan driver that works with our downstream kernel driver has already been
merged into Mesa [1][2]. Support for this new DRM driver is being maintained in
a merge request [3], with the branch located here:
https://gitlab.freedesktop.org/frankbinns/mesa/-/tree/powervr-winsys

Job stream formats are documented at:
https://gitlab.freedesktop.org/mesa/mesa/-/blob/f8d2b42ae65c2f16f36a43e0ae39d288431e4263/src/imagination/csbgen/rogue_kmd_stream.xml

The Vulkan driver is progressing towards Vulkan 1.0. The current combination of 
this
kernel driver with the Mesa Vulkan driver (powervr-mesa-next branch) 
successfully
completes Vulkan CTS 1.3.4.1 in our local runs. The driver is expected to pass 
the
Khronos Conformance Process once the submission is made.

The code in this patch series, along with the needed dts changes can be found 
here:
https://gitlab.freedesktop.org/sarah-walker-imgtec/powervr/-/tree/dev/v7_dts
The full development history can be found here:
https://gitlab.freedesktop.org/frankbinns/powervr/-/tree/powervr-next

This patch series has dependencies on a number of patches not yet merged. They
are listed below :

drm/sched: Convert drm scheduler to use a work queue rather than kthread:
  
https://lore.kernel.org/dri-devel/20230404002211.3611376-2-matthew.br...@intel.com/
drm/sched: Move schedule policy to scheduler / entity:
  
https://lore.kernel.org/dri-devel/20230404002211.3611376-3-matthew.br...@intel.com/
drm/sched: Add DRM_SCHED_POLICY_SINGLE_ENTITY scheduling policy:
  
https://lore.kernel.org/dri-devel/20230404002211.3611376-4-matthew.br...@intel.com/
drm/sched: Start run wq before TDR in drm_sched_start:
  
https://lore.kernel.org/dri-devel/20230404002211.3611376-6-matthew.br...@intel.com/
drm/sched: Submit job before starting TDR:
  
https://lore.kernel.org/dri-devel/20230404002211.3611376-7-matthew.br...@intel.com/
drm/sched: Add helper to set TDR timeout:
  
https://lore.kernel.org/dri-devel/20230404002211.3611376-8-matthew.br...@intel.com/

[1] https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15243
[2] https://gitlab.freedesktop.org/mesa/mesa/-/tree/main/src/imagination/vulkan
[3] https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15507

High level summary of changes:

v7:
* Fix fence handling in pvr_sync_signal_array_add()
* Add a minimum retry count to pvr_kccb_reserve_slot_sync()
* Don't initialise kernel_vm_ctx when using MIPS firmware processor
* Remove unused gpu label from dt bindings example
* Improve UAPI BYPASS_CACHE documentation
* Add DRM_PVR_SUBMIT_JOB_FRAG_CMD_DISABLE_PIXELMERGE flag to UAPI
* Rename gpuva_manager usage to gpuvm
* Sync GEM objects to device on creation
* Fix out-of-bounds shift bug
* Fix integer overflow in MIPS MMU map error path
* Add missing commit messages

v6:
* Fix a number of error paths
* Attempt to recover GPU on MMU flush command failure
* Defer freeing/releasing page table backing pages until after TLB flush
* Add memory barriers and use WRITE_ONCE() when writing to page tables
* Add Kconfig dependency on CONFIG_PM
* Fix a few issues with GPU VA manager usage
* Split up header commit due to size
* Update compatible string and driver description to match marketing name
* Use alloc_page() to allocate MIPS pagetable
* Remove obsolete documentation

v5:
* Retrieve GPU device information from firmware image header
* Address issues with DT binding and example DTS
* Update VM code for upstream GPU VA manager
* BOs are always zeroed on allocation
* Update copyright

v4:
* Implemented hang recovery via firmware hard reset
* Add support for partial render jobs
* Move to a threaded IRQ
* Remove unnecessary read/write and clock helpers
* Remove device tree elements not relevant to AXE-1-16M
* Clean up resource acquisition
* Remove unused DT binding attributes

v3:
* Use drm_sched for scheduling
* Use GPU VA manager
* Use runtime PM
* Use drm_gem_shmem
* GPU watchdog and device loss handling
* DT binding changes: remove unused attributes, add additionProperties:false

v2:
* Redesigned and simplified UAPI based on RFC feedback from XDC 2022
* Support for transfer 

[PATCH v7 19/20] drm/imagination: Add firmware trace to debugfs

2023-10-10 Thread Sarah Walker
Firmware trace is exposed at /sys/debug/dri//pvr_fw/trace_0.
Trace is enabled via the group mask at
/sys/debug/dri//pvr_params/fw_trace_mask.

Changes since v3:
- Use drm_dev_{enter,exit}

Co-developed-by: Matt Coster 
Signed-off-by: Matt Coster 
Signed-off-by: Sarah Walker 
---
 drivers/gpu/drm/imagination/Makefile   |   4 +
 drivers/gpu/drm/imagination/pvr_debugfs.c  |  53 +++
 drivers/gpu/drm/imagination/pvr_debugfs.h  |  29 ++
 drivers/gpu/drm/imagination/pvr_device.c   |   9 +
 drivers/gpu/drm/imagination/pvr_device.h   |  10 +
 drivers/gpu/drm/imagination/pvr_drv.c  |   4 +
 drivers/gpu/drm/imagination/pvr_fw_trace.c | 395 +
 drivers/gpu/drm/imagination/pvr_params.c   | 147 
 drivers/gpu/drm/imagination/pvr_params.h   |  72 
 9 files changed, 723 insertions(+)
 create mode 100644 drivers/gpu/drm/imagination/pvr_debugfs.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_debugfs.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_params.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_params.h

diff --git a/drivers/gpu/drm/imagination/Makefile 
b/drivers/gpu/drm/imagination/Makefile
index 313af5312d7b..1db003cf39ee 100644
--- a/drivers/gpu/drm/imagination/Makefile
+++ b/drivers/gpu/drm/imagination/Makefile
@@ -20,6 +20,7 @@ powervr-y := \
pvr_hwrt.o \
pvr_job.o \
pvr_mmu.o \
+   pvr_params.o \
pvr_power.o \
pvr_queue.o \
pvr_stream.o \
@@ -28,4 +29,7 @@ powervr-y := \
pvr_vm.o \
pvr_vm_mips.o
 
+powervr-$(CONFIG_DEBUG_FS) += \
+   pvr_debugfs.o
+
 obj-$(CONFIG_DRM_POWERVR) += powervr.o
diff --git a/drivers/gpu/drm/imagination/pvr_debugfs.c 
b/drivers/gpu/drm/imagination/pvr_debugfs.c
new file mode 100644
index ..fa0d7c89773c
--- /dev/null
+++ b/drivers/gpu/drm/imagination/pvr_debugfs.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/* Copyright (c) 2023 Imagination Technologies Ltd. */
+
+#include "pvr_debugfs.h"
+
+#include "pvr_device.h"
+#include "pvr_fw_trace.h"
+#include "pvr_params.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+static const struct pvr_debugfs_entry pvr_debugfs_entries[] = {
+   {"pvr_params", pvr_params_debugfs_init},
+   {"pvr_fw", pvr_fw_trace_debugfs_init},
+};
+
+void
+pvr_debugfs_init(struct drm_minor *minor)
+{
+   struct drm_device *drm_dev = minor->dev;
+   struct pvr_device *pvr_dev = to_pvr_device(drm_dev);
+   struct dentry *root = minor->debugfs_root;
+   size_t i;
+
+   for (i = 0; i < ARRAY_SIZE(pvr_debugfs_entries); ++i) {
+   const struct pvr_debugfs_entry *entry = &pvr_debugfs_entries[i];
+   struct dentry *dir;
+
+   dir = debugfs_create_dir(entry->name, root);
+   if (IS_ERR(dir)) {
+   drm_warn(drm_dev,
+"failed to create debugfs dir '%s' (err=%d)",
+entry->name, (int)PTR_ERR(dir));
+   continue;
+   }
+
+   entry->init(pvr_dev, dir);
+   }
+}
+
+/*
+ * Since all entries are created under &drm_minor->debugfs_root, there's no
+ * need for a pvr_debugfs_fini() as DRM will clean up everything under its root
+ * automatically.
+ */
diff --git a/drivers/gpu/drm/imagination/pvr_debugfs.h 
b/drivers/gpu/drm/imagination/pvr_debugfs.h
new file mode 100644
index ..7b7ff384053e
--- /dev/null
+++ b/drivers/gpu/drm/imagination/pvr_debugfs.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/* Copyright (c) 2023 Imagination Technologies Ltd. */
+
+#ifndef PVR_DEBUGFS_H
+#define PVR_DEBUGFS_H
+
+/* Forward declaration from . */
+struct drm_minor;
+
+#if defined(CONFIG_DEBUG_FS)
+/* Forward declaration from "pvr_device.h". */
+struct pvr_device;
+
+/* Forward declaration from . */
+struct dentry;
+
+struct pvr_debugfs_entry {
+   const char *name;
+   void (*init)(struct pvr_device *pvr_dev, struct dentry *dir);
+};
+
+void pvr_debugfs_init(struct drm_minor *minor);
+#else /* defined(CONFIG_DEBUG_FS) */
+#include 
+
+static __always_inline void pvr_debugfs_init(struct drm_minor *minor) {}
+#endif /* defined(CONFIG_DEBUG_FS) */
+
+#endif /* PVR_DEBUGFS_H */
diff --git a/drivers/gpu/drm/imagination/pvr_device.c 
b/drivers/gpu/drm/imagination/pvr_device.c
index e22a62ba21a4..53c9db71e882 100644
--- a/drivers/gpu/drm/imagination/pvr_device.c
+++ b/drivers/gpu/drm/imagination/pvr_device.c
@@ -5,6 +5,7 @@
 #include "pvr_device_info.h"
 
 #include "pvr_fw.h"
+#include "pvr_params.h"
 #include "pvr_power.h"
 #include "pvr_queue.h"
 #include "pvr_rogue_cr_defs.h"
@@ -495,6 +496,14 @@ pvr_device_init(struct pvr_device *pvr_dev)
struct device *dev = drm_dev->dev;
int err;
 
+   /*
+* Setup device parameters. We do this first in case other steps
+* depend on them.
+*/
+   err = pvr_device_params_init(&pvr_

[PATCH v7 16/20] drm/imagination: Implement context creation/destruction ioctls

2023-10-10 Thread Sarah Walker
Implement ioctls for the creation and destruction of contexts. Contexts are
used for job submission and each is associated with a particular job type.

Changes since v5:
- Fix context release in final error path in pvr_context_create()

Changes since v3:
- Use drm_dev_{enter,exit}

Co-developed-by: Boris Brezillon 
Signed-off-by: Boris Brezillon 
Signed-off-by: Sarah Walker 
---
 drivers/gpu/drm/imagination/Makefile  |   4 +
 drivers/gpu/drm/imagination/pvr_cccb.c| 267 ++
 drivers/gpu/drm/imagination/pvr_cccb.h| 109 ++
 drivers/gpu/drm/imagination/pvr_context.c | 341 ++
 drivers/gpu/drm/imagination/pvr_context.h | 161 +
 drivers/gpu/drm/imagination/pvr_device.h  |  21 ++
 drivers/gpu/drm/imagination/pvr_drv.c |  29 +-
 drivers/gpu/drm/imagination/pvr_stream.c  | 285 +++
 drivers/gpu/drm/imagination/pvr_stream.h  |  75 
 drivers/gpu/drm/imagination/pvr_stream_defs.c | 125 +++
 drivers/gpu/drm/imagination/pvr_stream_defs.h |  16 +
 11 files changed, 1431 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/imagination/pvr_cccb.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_cccb.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_context.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_context.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_stream.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_stream.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_stream_defs.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_stream_defs.h

diff --git a/drivers/gpu/drm/imagination/Makefile 
b/drivers/gpu/drm/imagination/Makefile
index fca2ee2efbac..0c8ab120f277 100644
--- a/drivers/gpu/drm/imagination/Makefile
+++ b/drivers/gpu/drm/imagination/Makefile
@@ -5,6 +5,8 @@ subdir-ccflags-y := -I$(srctree)/$(src)
 
 powervr-y := \
pvr_ccb.o \
+   pvr_cccb.o \
+   pvr_context.o \
pvr_device.o \
pvr_device_info.o \
pvr_drv.o \
@@ -18,6 +20,8 @@ powervr-y := \
pvr_hwrt.o \
pvr_mmu.o \
pvr_power.o \
+   pvr_stream.o \
+   pvr_stream_defs.o \
pvr_vm.o \
pvr_vm_mips.o
 
diff --git a/drivers/gpu/drm/imagination/pvr_cccb.c 
b/drivers/gpu/drm/imagination/pvr_cccb.c
new file mode 100644
index ..8dfc157c3c10
--- /dev/null
+++ b/drivers/gpu/drm/imagination/pvr_cccb.c
@@ -0,0 +1,267 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/* Copyright (c) 2023 Imagination Technologies Ltd. */
+
+#include "pvr_ccb.h"
+#include "pvr_cccb.h"
+#include "pvr_device.h"
+#include "pvr_gem.h"
+#include "pvr_hwrt.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static __always_inline u32
+get_ccb_space(u32 w_off, u32 r_off, u32 ccb_size)
+{
+   return (((r_off) - (w_off)) + ((ccb_size) - 1)) & ((ccb_size) - 1);
+}
+
+static void
+cccb_ctrl_init(void *cpu_ptr, void *priv)
+{
+   struct rogue_fwif_cccb_ctl *ctrl = cpu_ptr;
+   struct pvr_cccb *pvr_cccb = priv;
+
+   WRITE_ONCE(ctrl->write_offset, 0);
+   WRITE_ONCE(ctrl->read_offset, 0);
+   WRITE_ONCE(ctrl->dep_offset, 0);
+   WRITE_ONCE(ctrl->wrap_mask, pvr_cccb->wrap_mask);
+}
+
+/**
+ * pvr_cccb_init() - Initialise a Client CCB
+ * @pvr_dev: Device pointer.
+ * @pvr_cccb: Pointer to Client CCB structure to initialise.
+ * @size_log2: Log2 size of Client CCB in bytes.
+ * @name: Name of owner of Client CCB. Used for fence context.
+ *
+ * Return:
+ *  * Zero on success, or
+ *  * Any error code returned by pvr_fw_object_create_and_map().
+ */
+int
+pvr_cccb_init(struct pvr_device *pvr_dev, struct pvr_cccb *pvr_cccb,
+ u32 size_log2, const char *name)
+{
+   size_t size = 1 << size_log2;
+   int err;
+
+   pvr_cccb->size = size;
+   pvr_cccb->write_offset = 0;
+   pvr_cccb->wrap_mask = size - 1;
+
+   /*
+* Map CCCB and control structure as uncached, so we don't have to flush
+* CPU cache repeatedly when polling for space.
+*/
+   pvr_cccb->ctrl = pvr_fw_object_create_and_map(pvr_dev, 
sizeof(*pvr_cccb->ctrl),
+ 
PVR_BO_FW_FLAGS_DEVICE_UNCACHED,
+ cccb_ctrl_init, pvr_cccb,
+ &pvr_cccb->ctrl_obj);
+   if (IS_ERR(pvr_cccb->ctrl))
+   return PTR_ERR(pvr_cccb->ctrl);
+
+   pvr_cccb->cccb = pvr_fw_object_create_and_map(pvr_dev, size,
+ 
PVR_BO_FW_FLAGS_DEVICE_UNCACHED,
+ NULL, NULL, 
&pvr_cccb->cccb_obj);
+   if (IS_ERR(pvr_cccb->cccb)) {
+   err = PTR_ERR(pvr_cccb->cccb);
+   goto err_free_ctrl;
+   }
+
+   pvr_fw_object_get_fw_addr(pvr_cccb->ctrl_obj, &pvr_cccb->ctrl_fw_addr);
+   pvr_fw_object_get_fw_addr(pvr_cccb->cccb_obj, &pvr_cccb->cccb

[PATCH v7 20/20] drm/imagination: Add driver documentation

2023-10-10 Thread Sarah Walker
Add documentation for the UAPI.

Changes since v5:
- Remove obsolete VM documentation

Co-developed-by: Matt Coster 
Signed-off-by: Matt Coster 
Co-developed-by: Donald Robson 
Signed-off-by: Donald Robson 
Signed-off-by: Sarah Walker 
Reviewed-by: Maxime Ripard 
---
 Documentation/gpu/drivers.rst   |   2 +
 Documentation/gpu/imagination/index.rst |  13 ++
 Documentation/gpu/imagination/uapi.rst  | 174 
 MAINTAINERS |   1 +
 4 files changed, 190 insertions(+)
 create mode 100644 Documentation/gpu/imagination/index.rst
 create mode 100644 Documentation/gpu/imagination/uapi.rst

diff --git a/Documentation/gpu/drivers.rst b/Documentation/gpu/drivers.rst
index 3a52f48215a3..5487deb218a3 100644
--- a/Documentation/gpu/drivers.rst
+++ b/Documentation/gpu/drivers.rst
@@ -3,9 +3,11 @@ GPU Driver Documentation
 
 
 .. toctree::
+   :maxdepth: 3
 
amdgpu/index
i915
+   imagination/index
mcde
meson
pl111
diff --git a/Documentation/gpu/imagination/index.rst 
b/Documentation/gpu/imagination/index.rst
new file mode 100644
index ..dc9579e758c3
--- /dev/null
+++ b/Documentation/gpu/imagination/index.rst
@@ -0,0 +1,13 @@
+===
+drm/imagination PowerVR Graphics Driver
+===
+
+.. kernel-doc:: drivers/gpu/drm/imagination/pvr_drv.c
+   :doc: PowerVR Graphics Driver
+
+Contents
+
+.. toctree::
+   :maxdepth: 2
+
+   uapi
diff --git a/Documentation/gpu/imagination/uapi.rst 
b/Documentation/gpu/imagination/uapi.rst
new file mode 100644
index ..2227ea7e6222
--- /dev/null
+++ b/Documentation/gpu/imagination/uapi.rst
@@ -0,0 +1,174 @@
+
+UAPI
+
+The sources associated with this section can be found in ``pvr_drm.h``.
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :doc: PowerVR UAPI
+
+OBJECT ARRAYS
+=
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: drm_pvr_obj_array
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: DRM_PVR_OBJ_ARRAY
+
+IOCTLS
+==
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :doc: PowerVR IOCTL interface
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: PVR_IOCTL
+
+DEV_QUERY
+-
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :doc: PowerVR IOCTL DEV_QUERY interface
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: drm_pvr_dev_query
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: drm_pvr_ioctl_dev_query_args
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: drm_pvr_dev_query_gpu_info
+ drm_pvr_dev_query_runtime_info
+ drm_pvr_dev_query_hwrt_info
+ drm_pvr_dev_query_quirks
+ drm_pvr_dev_query_enhancements
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: drm_pvr_heap_id
+ drm_pvr_heap
+ drm_pvr_dev_query_heap_info
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :doc: Flags for DRM_PVR_DEV_QUERY_HEAP_INFO_GET.
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: drm_pvr_static_data_area_usage
+ drm_pvr_static_data_area
+ drm_pvr_dev_query_static_data_areas
+
+CREATE_BO
+-
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :doc: PowerVR IOCTL CREATE_BO interface
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: drm_pvr_ioctl_create_bo_args
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :doc: Flags for CREATE_BO
+
+GET_BO_MMAP_OFFSET
+--
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :doc: PowerVR IOCTL GET_BO_MMAP_OFFSET interface
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: drm_pvr_ioctl_get_bo_mmap_offset_args
+
+CREATE_VM_CONTEXT and DESTROY_VM_CONTEXT
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :doc: PowerVR IOCTL CREATE_VM_CONTEXT and DESTROY_VM_CONTEXT interfaces
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: drm_pvr_ioctl_create_vm_context_args
+ drm_pvr_ioctl_destroy_vm_context_args
+
+VM_MAP and VM_UNMAP
+---
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :doc: PowerVR IOCTL VM_MAP and VM_UNMAP interfaces
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: drm_pvr_ioctl_vm_map_args
+ drm_pvr_ioctl_vm_unmap_args
+
+CREATE_CONTEXT and DESTROY_CONTEXT
+--
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :doc: PowerVR IOCTL CREATE_CONTEXT and DESTROY_CONTEXT interfaces
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: drm_pvr_ioctl_create_context_args
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: drm_pvr_ctx_priority
+ drm_pvr_ctx_type
+ drm_pvr_static_render_context_state
+ drm_pvr_static_render_context_state_format
+ drm_pvr_reset_fram

[PATCH v7 18/20] drm/imagination: Add firmware trace header

2023-10-10 Thread Sarah Walker
Changes since v5:
- Split up header commit due to size

Signed-off-by: Sarah Walker 
---
 .../gpu/drm/imagination/pvr_rogue_fwif_sf.h   | 1648 +
 1 file changed, 1648 insertions(+)
 create mode 100644 drivers/gpu/drm/imagination/pvr_rogue_fwif_sf.h

diff --git a/drivers/gpu/drm/imagination/pvr_rogue_fwif_sf.h 
b/drivers/gpu/drm/imagination/pvr_rogue_fwif_sf.h
new file mode 100644
index ..0fcc500fab21
--- /dev/null
+++ b/drivers/gpu/drm/imagination/pvr_rogue_fwif_sf.h
@@ -0,0 +1,1648 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/* Copyright (c) 2023 Imagination Technologies Ltd. */
+
+#ifndef PVR_ROGUE_FWIF_SF_H
+#define PVR_ROGUE_FWIF_SF_H
+
+/*
+ **
+ * *DO*NOT* rearrange or delete lines in rogue_fw_log_sfgroups or stid_fmts
+ *   WILL BREAK fw tracing message compatibility with previous
+ *   fw versions. Only add new ones, if so required.
+ **
+ */
+
+/* Available log groups. */
+enum rogue_fw_log_sfgroups {
+   ROGUE_FW_GROUP_NULL,
+   ROGUE_FW_GROUP_MAIN,
+   ROGUE_FW_GROUP_CLEANUP,
+   ROGUE_FW_GROUP_CSW,
+   ROGUE_FW_GROUP_PM,
+   ROGUE_FW_GROUP_RTD,
+   ROGUE_FW_GROUP_SPM,
+   ROGUE_FW_GROUP_MTS,
+   ROGUE_FW_GROUP_BIF,
+   ROGUE_FW_GROUP_MISC,
+   ROGUE_FW_GROUP_POW,
+   ROGUE_FW_GROUP_HWR,
+   ROGUE_FW_GROUP_HWP,
+   ROGUE_FW_GROUP_RPM,
+   ROGUE_FW_GROUP_DMA,
+   ROGUE_FW_GROUP_DBG,
+};
+
+#define PVR_SF_STRING_MAX_SIZE 256U
+
+/* pair of string format id and string formats */
+struct rogue_fw_stid_fmt {
+   u32 id;
+   char name[PVR_SF_STRING_MAX_SIZE];
+};
+
+/*
+ *  The symbolic names found in the table above are assigned an u32 value of
+ *  the following format:
+ *  31 30 28 27   20   19  1615  12  110   bits
+ *  -   ---         
+ * 0-11: id number
+ *12-15: group id number
+ *16-19: number of parameters
+ *20-27: unused
+ *28-30: active: identify SF packet, otherwise regular int32
+ *   31: reserved for signed/unsigned compatibility
+ *
+ *   The following macro assigns those values to the enum generated SF ids 
list.
+ */
+#define ROGUE_FW_LOG_IDMARKER (0x7000U)
+#define ROGUE_FW_LOG_CREATESFID(a, b, e) ((u32)(a) | ((u32)(b) << 12) | 
((u32)(e) << 16) | \
+ ROGUE_FW_LOG_IDMARKER)
+
+#define ROGUE_FW_LOG_IDMASK (0xFFF0)
+#define ROGUE_FW_LOG_VALIDID(I) (((I) & ROGUE_FW_LOG_IDMASK) == 
ROGUE_FW_LOG_IDMARKER)
+
+/* Return the group id that the given (enum generated) id belongs to */
+#define ROGUE_FW_SF_GID(x) (((u32)(x) >> 12) & 0xfU)
+/* Returns how many arguments the SF(string format) for the given (enum 
generated) id requires */
+#define ROGUE_FW_SF_PARAMNUM(x) (((u32)(x) >> 16) & 0xfU)
+
+/* pair of string format id and string formats */
+struct rogue_km_stid_fmt {
+   u32 id;
+   const char *name;
+};
+
+static const struct rogue_km_stid_fmt stid_fmts[] = {
+   { ROGUE_FW_LOG_CREATESFID(0, ROGUE_FW_GROUP_NULL, 0),
+ "You should not use this string" },
+
+   { ROGUE_FW_LOG_CREATESFID(1, ROGUE_FW_GROUP_MAIN, 6),
+ "Kick 3D: FWCtx 0x%08.8x @ %d, RTD 0x%08x. Partial render:%d, CSW 
resume:%d, prio:%d" },
+   { ROGUE_FW_LOG_CREATESFID(2, ROGUE_FW_GROUP_MAIN, 2),
+ "3D finished, HWRTData0State=%x, HWRTData1State=%x" },
+   { ROGUE_FW_LOG_CREATESFID(3, ROGUE_FW_GROUP_MAIN, 4),
+ "Kick 3D TQ: FWCtx 0x%08.8x @ %d, CSW resume:%d, prio: %d" },
+   { ROGUE_FW_LOG_CREATESFID(4, ROGUE_FW_GROUP_MAIN, 0),
+ "3D Transfer finished" },
+   { ROGUE_FW_LOG_CREATESFID(5, ROGUE_FW_GROUP_MAIN, 3),
+ "Kick Compute: FWCtx 0x%08.8x @ %d, prio: %d" },
+   { ROGUE_FW_LOG_CREATESFID(6, ROGUE_FW_GROUP_MAIN, 0),
+ "Compute finished" },
+   { ROGUE_FW_LOG_CREATESFID(7, ROGUE_FW_GROUP_MAIN, 7),
+ "Kick TA: FWCtx 0x%08.8x @ %d, RTD 0x%08x. First kick:%d, Last 
kick:%d, CSW resume:%d, prio:%d" },
+   { ROGUE_FW_LOG_CREATESFID(8, ROGUE_FW_GROUP_MAIN, 0),
+ "TA finished" },
+   { ROGUE_FW_LOG_CREATESFID(9, ROGUE_FW_GROUP_MAIN, 0),
+ "Restart TA after partial render" },
+   { ROGUE_FW_LOG_CREATESFID(10, ROGUE_FW_GROUP_MAIN, 0),
+ "Resume TA without partial render" },
+   { ROGUE_FW_LOG_CREATESFID(11, ROGUE_FW_GROUP_MAIN, 2),
+ "Out of memory! Context 0x%08x, HWRTData 0x%x" },
+   { ROGUE_FW_LOG_CREATESFID(12, ROGUE_FW_GROUP_MAIN, 3),
+ "Kick TLA: FWCtx 0x%08.8x @ %d, prio:%d" },
+   { ROGUE_FW_LOG_CREATESFID(13, ROGUE_FW_GROUP_MAIN, 0),
+ "TLA finished" },
+   { ROGUE_FW_LOG_CREATESFID(14, ROGUE_FW_GROUP_MAIN, 3),
+ "cCCB Woff update = %d, DM = %d, FWCtx = 0x%08.8x" },
+   { ROGUE_FW_LOG_CREATESFID(16, ROGUE_FW_GROUP_MAIN, 2)

[PATCH v7 12/20] drm/imagination: Implement power management

2023-10-10 Thread Sarah Walker
Add power management to the driver, using runtime pm. The power off
sequence depends on firmware commands which are not implemented in this
patch.

Changes since v5:
- Use RUNTIME_PM_OPS() to declare PM callbacks
- Add Kconfig dependency on CONFIG_PM

Changes since v4:
- Suspend runtime PM before unplugging device on rmmod

Changes since v3:
- Don't power device when calling pvr_device_gpu_fini()
- Documentation for pvr_dev->lost has been improved
- pvr_power_init() renamed to pvr_watchdog_init()
- Use drm_dev_{enter,exit}

Changes since v2:
- Use runtime PM
- Implement watchdog

Signed-off-by: Sarah Walker 
Reviewed-by: Maxime Ripard 
---
 drivers/gpu/drm/imagination/Kconfig  |   1 +
 drivers/gpu/drm/imagination/Makefile |   1 +
 drivers/gpu/drm/imagination/pvr_device.c |  23 +-
 drivers/gpu/drm/imagination/pvr_device.h |  22 ++
 drivers/gpu/drm/imagination/pvr_drv.c|  20 +-
 drivers/gpu/drm/imagination/pvr_mmu.c|   6 +-
 drivers/gpu/drm/imagination/pvr_power.c  | 271 +++
 drivers/gpu/drm/imagination/pvr_power.h  |  39 
 8 files changed, 378 insertions(+), 5 deletions(-)
 create mode 100644 drivers/gpu/drm/imagination/pvr_power.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_power.h

diff --git a/drivers/gpu/drm/imagination/Kconfig 
b/drivers/gpu/drm/imagination/Kconfig
index 3e167d5470b4..2639fbf3ebac 100644
--- a/drivers/gpu/drm/imagination/Kconfig
+++ b/drivers/gpu/drm/imagination/Kconfig
@@ -5,6 +5,7 @@ config DRM_POWERVR
tristate "Imagination Technologies PowerVR (Series 6 and later) & IMG 
Graphics"
depends on ARM64
depends on DRM
+   depends on PM
select DRM_GEM_SHMEM_HELPER
select DRM_SCHED
select DRM_GPUVM
diff --git a/drivers/gpu/drm/imagination/Makefile 
b/drivers/gpu/drm/imagination/Makefile
index 8fcabc1bea36..235e2d329e29 100644
--- a/drivers/gpu/drm/imagination/Makefile
+++ b/drivers/gpu/drm/imagination/Makefile
@@ -10,6 +10,7 @@ powervr-y := \
pvr_fw.o \
pvr_gem.o \
pvr_mmu.o \
+   pvr_power.o \
pvr_vm.o
 
 obj-$(CONFIG_DRM_POWERVR) += powervr.o
diff --git a/drivers/gpu/drm/imagination/pvr_device.c 
b/drivers/gpu/drm/imagination/pvr_device.c
index f71e400ea24e..51ff10522d23 100644
--- a/drivers/gpu/drm/imagination/pvr_device.c
+++ b/drivers/gpu/drm/imagination/pvr_device.c
@@ -5,6 +5,7 @@
 #include "pvr_device_info.h"
 
 #include "pvr_fw.h"
+#include "pvr_power.h"
 #include "pvr_rogue_cr_defs.h"
 #include "pvr_vm.h"
 
@@ -361,6 +362,8 @@ pvr_device_gpu_fini(struct pvr_device *pvr_dev)
 int
 pvr_device_init(struct pvr_device *pvr_dev)
 {
+   struct drm_device *drm_dev = from_pvr_device(pvr_dev);
+   struct device *dev = drm_dev->dev;
int err;
 
/* Enable and initialize clocks required for the device to operate. */
@@ -368,13 +371,29 @@ pvr_device_init(struct pvr_device *pvr_dev)
if (err)
return err;
 
+   /* Explicitly power the GPU so we can access control registers before 
the FW is booted. */
+   err = pm_runtime_resume_and_get(dev);
+   if (err)
+   return err;
+
/* Map the control registers into memory. */
err = pvr_device_reg_init(pvr_dev);
if (err)
-   return err;
+   goto err_pm_runtime_put;
 
/* Perform GPU-specific initialization steps. */
-   return pvr_device_gpu_init(pvr_dev);
+   err = pvr_device_gpu_init(pvr_dev);
+   if (err)
+   goto err_pm_runtime_put;
+
+   pm_runtime_put(dev);
+
+   return 0;
+
+err_pm_runtime_put:
+   pm_runtime_put_sync_suspend(dev);
+
+   return err;
 }
 
 /**
diff --git a/drivers/gpu/drm/imagination/pvr_device.h 
b/drivers/gpu/drm/imagination/pvr_device.h
index 350e894a2939..f7eb14942195 100644
--- a/drivers/gpu/drm/imagination/pvr_device.h
+++ b/drivers/gpu/drm/imagination/pvr_device.h
@@ -135,6 +135,28 @@ struct pvr_device {
 
/** @fw_dev: Firmware related data. */
struct pvr_fw_device fw_dev;
+
+   struct {
+   /** @work: Work item for watchdog callback. */
+   struct delayed_work work;
+
+   /** @old_kccb_cmds_executed: KCCB command execution count at 
last watchdog poll. */
+   u32 old_kccb_cmds_executed;
+
+   /** @kccb_stall_count: Number of watchdog polls KCCB has been 
stalled for. */
+   u32 kccb_stall_count;
+   } watchdog;
+
+   /**
+* @lost: %true if the device has been lost.
+*
+* This variable is set if the device has become irretrievably 
unavailable, e.g. if the
+* firmware processor has stopped responding and can not be revived via 
a hard reset.
+*/
+   bool lost;
+
+   /** @sched_wq: Workqueue for schedulers. */
+   struct workqueue_struct *sched_wq;
 };
 
 /**
diff --git a/drivers/gpu/drm/imagination/pvr_drv.c 
b/drivers/gpu/drm/imagination/pvr_drv.c
index 4b0c52118735..cfd4cea5a69c 1

[PATCH v7 13/20] drm/imagination: Implement firmware infrastructure and META FW support

2023-10-10 Thread Sarah Walker
The infrastructure includes parsing of the firmware image, initialising
FW-side structures, handling the kernel and firmware command
ringbuffers and starting & stopping the firmware processor.

This patch also adds the necessary support code for the META firmware
processor.

Changes since v6:
- Add a minimum retry count to pvr_kccb_reserve_slot_sync()

Changes since v5:
- Add workaround for BRN 71242
- Attempt to recover GPU on MMU flush command failure

Changes since v4:
- Remove use of drm_gem_shmem_get_pages()
- Remove interrupt resource name

Changes since v3:
- Hard reset FW processor on watchdog timeout
- Switch to threaded IRQ
- Rework FW object creation/initialisation to aid hard reset
- Added MODULE_FIRMWARE()
- Use drm_dev_{enter,exit}

Signed-off-by: Sarah Walker 
---
 drivers/gpu/drm/imagination/Makefile  |4 +
 drivers/gpu/drm/imagination/pvr_ccb.c |  638 
 drivers/gpu/drm/imagination/pvr_ccb.h |   71 +
 drivers/gpu/drm/imagination/pvr_device.c  |  103 ++
 drivers/gpu/drm/imagination/pvr_device.h  |   60 +
 drivers/gpu/drm/imagination/pvr_drv.c |1 +
 drivers/gpu/drm/imagination/pvr_fw.c  | 1342 +
 drivers/gpu/drm/imagination/pvr_fw.h  |  474 ++
 drivers/gpu/drm/imagination/pvr_fw_meta.c |  554 +++
 drivers/gpu/drm/imagination/pvr_fw_meta.h |   14 +
 .../gpu/drm/imagination/pvr_fw_startstop.c|  306 
 .../gpu/drm/imagination/pvr_fw_startstop.h|   13 +
 drivers/gpu/drm/imagination/pvr_fw_trace.c|  120 ++
 drivers/gpu/drm/imagination/pvr_fw_trace.h|   78 +
 drivers/gpu/drm/imagination/pvr_gem.h |7 +
 drivers/gpu/drm/imagination/pvr_mmu.c |   67 +-
 drivers/gpu/drm/imagination/pvr_power.c   |  166 +-
 drivers/gpu/drm/imagination/pvr_power.h   |2 +
 drivers/gpu/drm/imagination/pvr_vm.c  |   26 +-
 19 files changed, 4023 insertions(+), 23 deletions(-)
 create mode 100644 drivers/gpu/drm/imagination/pvr_ccb.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_ccb.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_fw_meta.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_fw_meta.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_fw_startstop.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_fw_startstop.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_fw_trace.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_fw_trace.h

diff --git a/drivers/gpu/drm/imagination/Makefile 
b/drivers/gpu/drm/imagination/Makefile
index 235e2d329e29..5b02440841be 100644
--- a/drivers/gpu/drm/imagination/Makefile
+++ b/drivers/gpu/drm/imagination/Makefile
@@ -4,10 +4,14 @@
 subdir-ccflags-y := -I$(srctree)/$(src)
 
 powervr-y := \
+   pvr_ccb.o \
pvr_device.o \
pvr_device_info.o \
pvr_drv.o \
pvr_fw.o \
+   pvr_fw_meta.o \
+   pvr_fw_startstop.o \
+   pvr_fw_trace.o \
pvr_gem.o \
pvr_mmu.o \
pvr_power.o \
diff --git a/drivers/gpu/drm/imagination/pvr_ccb.c 
b/drivers/gpu/drm/imagination/pvr_ccb.c
new file mode 100644
index ..64b58b8989ca
--- /dev/null
+++ b/drivers/gpu/drm/imagination/pvr_ccb.c
@@ -0,0 +1,638 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/* Copyright (c) 2023 Imagination Technologies Ltd. */
+
+#include "pvr_ccb.h"
+#include "pvr_device.h"
+#include "pvr_drv.h"
+#include "pvr_fw.h"
+#include "pvr_gem.h"
+#include "pvr_power.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define RESERVE_SLOT_TIMEOUT (1 * HZ) /* 1s */
+#define RESERVE_SLOT_MIN_RETRIES 10
+
+static void
+ccb_ctrl_init(void *cpu_ptr, void *priv)
+{
+   struct rogue_fwif_ccb_ctl *ctrl = cpu_ptr;
+   struct pvr_ccb *pvr_ccb = priv;
+
+   ctrl->write_offset = 0;
+   ctrl->read_offset = 0;
+   ctrl->wrap_mask = pvr_ccb->num_cmds - 1;
+   ctrl->cmd_size = pvr_ccb->cmd_size;
+}
+
+/**
+ * pvr_ccb_init() - Initialise a CCB
+ * @pvr_dev: Device pointer.
+ * @pvr_ccb: Pointer to CCB structure to initialise.
+ * @num_cmds_log2: Log2 of number of commands in this CCB.
+ * @cmd_size: Command size for this CCB.
+ *
+ * Return:
+ *  * Zero on success, or
+ *  * Any error code returned by pvr_fw_object_create_and_map().
+ */
+static int
+pvr_ccb_init(struct pvr_device *pvr_dev, struct pvr_ccb *pvr_ccb,
+u32 num_cmds_log2, size_t cmd_size)
+{
+   u32 num_cmds = 1 << num_cmds_log2;
+   u32 ccb_size = num_cmds * cmd_size;
+   int err;
+
+   pvr_ccb->num_cmds = num_cmds;
+   pvr_ccb->cmd_size = cmd_size;
+
+   err = drmm_mutex_init(from_pvr_device(pvr_dev), &pvr_ccb->lock);
+   if (err)
+   return err;
+
+   /*
+* Map CCB and control structure as uncached, so we don't have to flush
+* CPU cache repeatedly when polling for space.
+*/
+   pvr_ccb->ctrl = pvr_fw_object_create_and_map(pvr_dev, 
sizeof(*pvr_ccb->ctrl),
+

[PATCH v7 06/20] drm/imagination: Get GPU resources

2023-10-10 Thread Sarah Walker
Acquire clock and register resources, and enable/map as appropriate.

Changes since v3:
- Remove regulator resource (not used on supported platform)
- Use devm helpers
- Use devm_clk_get_optional() for optional clocks
- Don't prepare clocks on resource acquisition
- Drop pvr_device_clk_core_get_freq() helper
- Drop pvr_device_reg_fini()
- Drop NULLing of clocks in pvr_device_clk_init()
- Use dev_err_probe() on clock acquisition failure
- Remove PVR_CR_READ/WRITE helper macros
- Improve documentation for GPU clocks
- Remove regs resource (not used in this commit)

Co-developed-by: Frank Binns 
Signed-off-by: Frank Binns 
Co-developed-by: Matt Coster 
Signed-off-by: Matt Coster 
Signed-off-by: Sarah Walker 
Reviewed-by: Maxime Ripard 
---
 drivers/gpu/drm/imagination/Makefile |   1 +
 drivers/gpu/drm/imagination/pvr_device.c | 147 ++
 drivers/gpu/drm/imagination/pvr_device.h | 152 +++
 drivers/gpu/drm/imagination/pvr_drv.c|  18 ++-
 4 files changed, 317 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/imagination/pvr_device.c

diff --git a/drivers/gpu/drm/imagination/Makefile 
b/drivers/gpu/drm/imagination/Makefile
index 19b40c2d7356..b4aa190c9d4a 100644
--- a/drivers/gpu/drm/imagination/Makefile
+++ b/drivers/gpu/drm/imagination/Makefile
@@ -4,6 +4,7 @@
 subdir-ccflags-y := -I$(srctree)/$(src)
 
 powervr-y := \
+   pvr_device.o \
pvr_drv.o \
 
 obj-$(CONFIG_DRM_POWERVR) += powervr.o
diff --git a/drivers/gpu/drm/imagination/pvr_device.c 
b/drivers/gpu/drm/imagination/pvr_device.c
new file mode 100644
index ..cef3511c0c42
--- /dev/null
+++ b/drivers/gpu/drm/imagination/pvr_device.c
@@ -0,0 +1,147 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/* Copyright (c) 2023 Imagination Technologies Ltd. */
+
+#include "pvr_device.h"
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+ * pvr_device_reg_init() - Initialize kernel access to a PowerVR device's
+ * control registers.
+ * @pvr_dev: Target PowerVR device.
+ *
+ * Sets struct pvr_device->regs.
+ *
+ * This method of mapping the device control registers into memory ensures that
+ * they are unmapped when the driver is detached (i.e. no explicit cleanup is
+ * required).
+ *
+ * Return:
+ *  * 0 on success, or
+ *  * Any error returned by devm_platform_ioremap_resource().
+ */
+static int
+pvr_device_reg_init(struct pvr_device *pvr_dev)
+{
+   struct drm_device *drm_dev = from_pvr_device(pvr_dev);
+   struct platform_device *plat_dev = to_platform_device(drm_dev->dev);
+   void __iomem *regs;
+
+   pvr_dev->regs = NULL;
+
+   regs = devm_platform_ioremap_resource(plat_dev, 0);
+   if (IS_ERR(regs))
+   return dev_err_probe(drm_dev->dev, PTR_ERR(regs),
+"failed to ioremap gpu registers\n");
+
+   pvr_dev->regs = regs;
+
+   return 0;
+}
+
+/**
+ * pvr_device_clk_init() - Initialize clocks required by a PowerVR device
+ * @pvr_dev: Target PowerVR device.
+ *
+ * Sets struct pvr_device->core_clk, struct pvr_device->sys_clk and
+ * struct pvr_device->mem_clk.
+ *
+ * Three clocks are required by the PowerVR device: core, sys and mem. On
+ * return, this function guarantees that the clocks are in one of the following
+ * states:
+ *
+ *  * All successfully initialized,
+ *  * Core errored, sys and mem uninitialized,
+ *  * Core deinitialized, sys errored, mem uninitialized, or
+ *  * Core and sys deinitialized, mem errored.
+ *
+ * Return:
+ *  * 0 on success,
+ *  * Any error returned by devm_clk_get(), or
+ *  * Any error returned by devm_clk_get_optional().
+ */
+static int pvr_device_clk_init(struct pvr_device *pvr_dev)
+{
+   struct drm_device *drm_dev = from_pvr_device(pvr_dev);
+   struct clk *core_clk;
+   struct clk *sys_clk;
+   struct clk *mem_clk;
+
+   core_clk = devm_clk_get(drm_dev->dev, "core");
+   if (IS_ERR(core_clk))
+   return dev_err_probe(drm_dev->dev, PTR_ERR(core_clk),
+"failed to get core clock\n");
+
+   sys_clk = devm_clk_get_optional(drm_dev->dev, "sys");
+   if (IS_ERR(sys_clk))
+   return dev_err_probe(drm_dev->dev, PTR_ERR(core_clk),
+"failed to get sys clock\n");
+
+   mem_clk = devm_clk_get_optional(drm_dev->dev, "mem");
+   if (IS_ERR(mem_clk))
+   return dev_err_probe(drm_dev->dev, PTR_ERR(core_clk),
+"failed to get mem clock\n");
+
+   pvr_dev->core_clk = core_clk;
+   pvr_dev->sys_clk = sys_clk;
+   pvr_dev->mem_clk = mem_clk;
+
+   return 0;
+}
+
+/**
+ * pvr_device_init() - Initialize a PowerVR device
+ * @pvr_dev: Target PowerVR device.
+ *
+ * If this function returns successfully, the device will have been fully
+ * initialized. Otherwise, any parts of the device initialized before a

[PATCH v7 03/20] dt-bindings: gpu: Add Imagination Technologies PowerVR/IMG GPU

2023-10-10 Thread Sarah Walker
Add the device tree binding documentation for the IMG AXE GPU used in
TI AM62 SoCs.

Co-developed-by: Frank Binns 
Signed-off-by: Frank Binns 
Signed-off-by: Sarah Walker 
Reviewed-by: Maxime Ripard 
Reviewed-by: Linus Walleij 
Reviewed-by: Conor Dooley 
---
Changes since v6:
- Remove unused gpu label from example
- Updated maintainer

Changes since v5:
- Update compatible string & description to match marketing name
- Remove unnecessary clock-names definition in ti,am62-gpu constraints
- Document that GPU revision is discoverable

Changes since v4:
- Add clocks constraint for ti,am62-gpu
- Remove excess address and size cells in example
- Remove interrupt name and add maxItems
- Make property order consistent between dts and bindings doc
- Update example to match dts

Changes since v3:
- Remove oneOf in compatible property
- Remove power-supply (not used on AM62)

Changes since v2:
- Add commit message description
- Remove mt8173-gpu support (not currently supported)
- Drop quotes from $id and $schema
- Remove reg: minItems
- Drop _clk suffixes from clock-names
- Remove operating-points-v2 property and cooling-cells (not currently
  used)
- Add additionalProperties: false
- Remove stray blank line at the end of file

 .../devicetree/bindings/gpu/img,powervr.yaml  | 73 +++
 MAINTAINERS   |  6 ++
 2 files changed, 79 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpu/img,powervr.yaml

diff --git a/Documentation/devicetree/bindings/gpu/img,powervr.yaml 
b/Documentation/devicetree/bindings/gpu/img,powervr.yaml
new file mode 100644
index ..e81db87a1f46
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpu/img,powervr.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (c) 2023 Imagination Technologies Ltd.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpu/img,powervr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Imagination Technologies PowerVR and IMG GPU
+
+maintainers:
+  - Donald Robson 
+
+properties:
+  compatible:
+items:
+  - enum:
+  - ti,am62-gpu
+  - const: img,img-axe # IMG AXE GPU model/revision is fully discoverable
+
+  reg:
+maxItems: 1
+
+  clocks:
+minItems: 1
+maxItems: 3
+
+  clock-names:
+items:
+  - const: core
+  - const: mem
+  - const: sys
+minItems: 1
+
+  interrupts:
+maxItems: 1
+
+  power-domains:
+maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+
+additionalProperties: false
+
+allOf:
+  - if:
+  properties:
+compatible:
+  contains:
+const: ti,am62-gpu
+then:
+  properties:
+clocks:
+  maxItems: 1
+
+examples:
+  - |
+#include 
+#include 
+#include 
+
+gpu@fd0 {
+compatible = "ti,am62-gpu", "img,img-axe";
+reg = <0x0fd0 0x2>;
+clocks = <&k3_clks 187 0>;
+clock-names = "core";
+interrupts = ;
+power-domains = <&k3_pds 187 TI_SCI_PD_EXCLUSIVE>;
+};
diff --git a/MAINTAINERS b/MAINTAINERS
index e05506ea8917..eea8e618746a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10228,6 +10228,12 @@ IMGTEC IR DECODER DRIVER
 S: Orphan
 F: drivers/media/rc/img-ir/
 
+IMGTEC POWERVR DRM DRIVER
+M: Frank Binns 
+M: Donald Robson 
+S: Supported
+F: Documentation/devicetree/bindings/gpu/img,powervr.yaml
+
 IMON SOUNDGRAPH USB IR RECEIVER
 M: Sean Young 
 L: linux-me...@vger.kernel.org
-- 
2.42.0



[PATCH v7 05/20] drm/imagination: Add skeleton PowerVR driver

2023-10-10 Thread Sarah Walker
This adds the basic skeleton of the driver. The driver registers
itself with DRM on probe. Ioctl handlers are currently implemented
as stubs.

Changes since v5:
- Update compatible string & description to match marketing name
- Checkpatch fixes in to/from_pvr_device/file macros

Changes since v3:
- Clarify supported GPU generations in driver description
- Use drm_dev_unplug() when removing device
- Change from_* and to_* functions to macros
- Fix IS_PTR/PTR_ERR confusion in pvr_probe()
- Remove err_out labels in favour of direct returning
- Remove specific am62 compatible match string
- Drop MODULE_FIRMWARE()

Co-developed-by: Frank Binns 
Signed-off-by: Frank Binns 
Co-developed-by: Matt Coster 
Signed-off-by: Matt Coster 
Signed-off-by: Sarah Walker 
Reviewed-by: Maxime Ripard 
---
 MAINTAINERS  |   1 +
 drivers/gpu/drm/Kconfig  |   2 +
 drivers/gpu/drm/Makefile |   1 +
 drivers/gpu/drm/imagination/Kconfig  |  15 +
 drivers/gpu/drm/imagination/Makefile |   9 +
 drivers/gpu/drm/imagination/pvr_device.h | 153 +++
 drivers/gpu/drm/imagination/pvr_drv.c| 509 +++
 drivers/gpu/drm/imagination/pvr_drv.h|  22 +
 8 files changed, 712 insertions(+)
 create mode 100644 drivers/gpu/drm/imagination/Kconfig
 create mode 100644 drivers/gpu/drm/imagination/Makefile
 create mode 100644 drivers/gpu/drm/imagination/pvr_device.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_drv.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_drv.h

diff --git a/MAINTAINERS b/MAINTAINERS
index cfdc7ec02972..6bcd86fb44ee 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10233,6 +10233,7 @@ M:  Frank Binns 
 M: Donald Robson 
 S: Supported
 F: Documentation/devicetree/bindings/gpu/img,powervr.yaml
+F: drivers/gpu/drm/imagination/
 F: include/uapi/drm/pvr_drm.h
 
 IMON SOUNDGRAPH USB IR RECEIVER
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 48ca28a2e4ff..f42550d4ec68 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -394,6 +394,8 @@ source "drivers/gpu/drm/solomon/Kconfig"
 
 source "drivers/gpu/drm/sprd/Kconfig"
 
+source "drivers/gpu/drm/imagination/Kconfig"
+
 config DRM_HYPERV
tristate "DRM Support for Hyper-V synthetic video device"
depends on DRM && PCI && MMU && HYPERV
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 8e1bde059170..d236103e3361 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -198,3 +198,4 @@ obj-$(CONFIG_DRM_HYPERV) += hyperv/
 obj-y  += solomon/
 obj-$(CONFIG_DRM_SPRD) += sprd/
 obj-$(CONFIG_DRM_LOONGSON) += loongson/
+obj-$(CONFIG_DRM_POWERVR) += imagination/
diff --git a/drivers/gpu/drm/imagination/Kconfig 
b/drivers/gpu/drm/imagination/Kconfig
new file mode 100644
index ..e9aaa5313485
--- /dev/null
+++ b/drivers/gpu/drm/imagination/Kconfig
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0 OR MIT
+# Copyright (c) 2023 Imagination Technologies Ltd.
+
+config DRM_POWERVR
+   tristate "Imagination Technologies PowerVR (Series 6 and later) & IMG 
Graphics"
+   depends on ARM64
+   depends on DRM
+   select DRM_GEM_SHMEM_HELPER
+   select DRM_SCHED
+   select FW_LOADER
+   help
+ Choose this option if you have a system that has an Imagination
+ Technologies PowerVR (Series 6 or later) or IMG GPU.
+
+ If "M" is selected, the module will be called powervr.
diff --git a/drivers/gpu/drm/imagination/Makefile 
b/drivers/gpu/drm/imagination/Makefile
new file mode 100644
index ..19b40c2d7356
--- /dev/null
+++ b/drivers/gpu/drm/imagination/Makefile
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0 OR MIT
+# Copyright (c) 2023 Imagination Technologies Ltd.
+
+subdir-ccflags-y := -I$(srctree)/$(src)
+
+powervr-y := \
+   pvr_drv.o \
+
+obj-$(CONFIG_DRM_POWERVR) += powervr.o
diff --git a/drivers/gpu/drm/imagination/pvr_device.h 
b/drivers/gpu/drm/imagination/pvr_device.h
new file mode 100644
index ..53b1cdb5a6a6
--- /dev/null
+++ b/drivers/gpu/drm/imagination/pvr_device.h
@@ -0,0 +1,153 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/* Copyright (c) 2023 Imagination Technologies Ltd. */
+
+#ifndef PVR_DEVICE_H
+#define PVR_DEVICE_H
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+ * struct pvr_device - powervr-specific wrapper for &struct drm_device
+ */
+struct pvr_device {
+   /**
+* @base: The underlying &struct drm_device.
+*
+* Do not access this member directly, instead call
+* from_pvr_device().
+*/
+   struct drm_device base;
+};
+
+/**
+ * struct pvr_file - powervr-specific data to be assigned to &struct
+ * drm_file.driver_priv
+ */
+struct pvr_file {
+   /**
+* @file: A reference to the parent &struct drm_file.
+*
+* Do not access this membe

[PATCH v7 14/20] drm/imagination: Implement MIPS firmware processor and MMU support

2023-10-10 Thread Sarah Walker
Add support for the MIPS firmware processor, used in the Series AXE GPU.
The MIPS firmware processor uses a separate MMU to the rest of the GPU, so
this patch adds support for that as well.

Changes since v6:
- Fix integer overflow in VM map error path

Changes since v5:
- Use alloc_page() when allocating MIPS pagetable

Changes since v3:
- Get regs resource (removed from GPU resources commit)

Signed-off-by: Sarah Walker 
---
 drivers/gpu/drm/imagination/Makefile  |   4 +-
 drivers/gpu/drm/imagination/pvr_device.c  |   5 +-
 drivers/gpu/drm/imagination/pvr_device.h  |   3 +
 drivers/gpu/drm/imagination/pvr_fw.c  |   2 +
 drivers/gpu/drm/imagination/pvr_fw_mips.c | 252 ++
 drivers/gpu/drm/imagination/pvr_fw_mips.h |  48 +
 drivers/gpu/drm/imagination/pvr_vm_mips.c | 236 
 drivers/gpu/drm/imagination/pvr_vm_mips.h |  22 ++
 8 files changed, 570 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/imagination/pvr_fw_mips.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_fw_mips.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_vm_mips.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_vm_mips.h

diff --git a/drivers/gpu/drm/imagination/Makefile 
b/drivers/gpu/drm/imagination/Makefile
index 5b02440841be..0a6532d30c00 100644
--- a/drivers/gpu/drm/imagination/Makefile
+++ b/drivers/gpu/drm/imagination/Makefile
@@ -10,11 +10,13 @@ powervr-y := \
pvr_drv.o \
pvr_fw.o \
pvr_fw_meta.o \
+   pvr_fw_mips.o \
pvr_fw_startstop.o \
pvr_fw_trace.o \
pvr_gem.o \
pvr_mmu.o \
pvr_power.o \
-   pvr_vm.o
+   pvr_vm.o \
+   pvr_vm_mips.o
 
 obj-$(CONFIG_DRM_POWERVR) += powervr.o
diff --git a/drivers/gpu/drm/imagination/pvr_device.c 
b/drivers/gpu/drm/imagination/pvr_device.c
index 6055cf6054f7..aac5e62d6cbe 100644
--- a/drivers/gpu/drm/imagination/pvr_device.c
+++ b/drivers/gpu/drm/imagination/pvr_device.c
@@ -50,16 +50,19 @@ pvr_device_reg_init(struct pvr_device *pvr_dev)
 {
struct drm_device *drm_dev = from_pvr_device(pvr_dev);
struct platform_device *plat_dev = to_platform_device(drm_dev->dev);
+   struct resource *regs_resource;
void __iomem *regs;
 
+   pvr_dev->regs_resource = NULL;
pvr_dev->regs = NULL;
 
-   regs = devm_platform_ioremap_resource(plat_dev, 0);
+   regs = devm_platform_get_and_ioremap_resource(plat_dev, 0, 
®s_resource);
if (IS_ERR(regs))
return dev_err_probe(drm_dev->dev, PTR_ERR(regs),
 "failed to ioremap gpu registers\n");
 
pvr_dev->regs = regs;
+   pvr_dev->regs_resource = regs_resource;
 
return 0;
 }
diff --git a/drivers/gpu/drm/imagination/pvr_device.h 
b/drivers/gpu/drm/imagination/pvr_device.h
index b5de9574a116..cbcfc5d4b845 100644
--- a/drivers/gpu/drm/imagination/pvr_device.h
+++ b/drivers/gpu/drm/imagination/pvr_device.h
@@ -93,6 +93,9 @@ struct pvr_device {
/** @fw_version: Firmware version detected at runtime. */
struct pvr_fw_version fw_version;
 
+   /** @regs_resource: Resource representing device control registers. */
+   struct resource *regs_resource;
+
/**
 * @regs: Device control registers.
 *
diff --git a/drivers/gpu/drm/imagination/pvr_fw.c 
b/drivers/gpu/drm/imagination/pvr_fw.c
index 4ea663be4596..d3edcb74f29d 100644
--- a/drivers/gpu/drm/imagination/pvr_fw.c
+++ b/drivers/gpu/drm/imagination/pvr_fw.c
@@ -933,6 +933,8 @@ pvr_fw_init(struct pvr_device *pvr_dev)
 
if (fw_dev->processor_type == PVR_FW_PROCESSOR_TYPE_META)
fw_dev->defs = &pvr_fw_defs_meta;
+   else if (fw_dev->processor_type == PVR_FW_PROCESSOR_TYPE_MIPS)
+   fw_dev->defs = &pvr_fw_defs_mips;
else
return -EINVAL;
 
diff --git a/drivers/gpu/drm/imagination/pvr_fw_mips.c 
b/drivers/gpu/drm/imagination/pvr_fw_mips.c
new file mode 100644
index ..bf13b05d1248
--- /dev/null
+++ b/drivers/gpu/drm/imagination/pvr_fw_mips.c
@@ -0,0 +1,252 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/* Copyright (c) 2023 Imagination Technologies Ltd. */
+
+#include "pvr_device.h"
+#include "pvr_fw.h"
+#include "pvr_fw_mips.h"
+#include "pvr_gem.h"
+#include "pvr_rogue_mips.h"
+#include "pvr_vm_mips.h"
+
+#include 
+#include 
+#include 
+
+#define ROGUE_FW_HEAP_MIPS_BASE 0xC000
+#define ROGUE_FW_HEAP_MIPS_SHIFT 24 /* 16 MB */
+#define ROGUE_FW_HEAP_MIPS_RESERVED_SIZE SZ_1M
+
+/**
+ * process_elf_command_stream() - Process ELF firmware image and populate
+ *firmware sections
+ * @pvr_dev: Device pointer.
+ * @fw: Pointer to firmware image.
+ * @fw_code_ptr: Pointer to FW code section.
+ * @fw_data_ptr: Pointer to FW data section.
+ * @fw_core_code_ptr: Pointer to FW coremem code section.
+ * @fw_core_data_ptr: Pointer to FW coremem data section.
+ *
+ * Returns :
+ *  * 0 on success, or
+ *  * -EINVAL o

[PATCH v7 08/20] drm/imagination: Add firmware and MMU related headers

2023-10-10 Thread Sarah Walker
Changes since v5:
- Split up header commit due to size

Signed-off-by: Sarah Walker 
Acked-by: Maxime Ripard 
---
 .../drm/imagination/pvr_rogue_heap_config.h   | 113 ++
 drivers/gpu/drm/imagination/pvr_rogue_meta.h  | 356 ++
 drivers/gpu/drm/imagination/pvr_rogue_mips.h  | 335 
 .../drm/imagination/pvr_rogue_mips_check.h|  58 +++
 .../gpu/drm/imagination/pvr_rogue_mmu_defs.h  | 136 +++
 5 files changed, 998 insertions(+)
 create mode 100644 drivers/gpu/drm/imagination/pvr_rogue_heap_config.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_rogue_meta.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_rogue_mips.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_rogue_mips_check.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_rogue_mmu_defs.h

diff --git a/drivers/gpu/drm/imagination/pvr_rogue_heap_config.h 
b/drivers/gpu/drm/imagination/pvr_rogue_heap_config.h
new file mode 100644
index ..632221b88281
--- /dev/null
+++ b/drivers/gpu/drm/imagination/pvr_rogue_heap_config.h
@@ -0,0 +1,113 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/* Copyright (c) 2023 Imagination Technologies Ltd. */
+
+#ifndef PVR_ROGUE_HEAP_CONFIG_H
+#define PVR_ROGUE_HEAP_CONFIG_H
+
+#include 
+
+/*
+ * ROGUE Device Virtual Address Space Definitions
+ *
+ * This file defines the ROGUE virtual address heaps that are used in
+ * application memory contexts. It also shows where the Firmware memory heap
+ * fits into this, but the firmware heap is only ever created in the
+ * kernel driver and never exposed to userspace.
+ *
+ * ROGUE_PDSCODEDATA_HEAP_BASE and ROGUE_USCCODE_HEAP_BASE will be programmed,
+ * on a global basis, into ROGUE_CR_PDS_EXEC_BASE and ROGUE_CR_USC_CODE_BASE_*
+ * respectively. Therefore if client drivers use multiple configs they must
+ * still be consistent with their definitions for these heaps.
+ *
+ * Base addresses have to be a multiple of 4MiB.
+ * Heaps must not start at 0x00, as this is reserved for internal
+ * use within the driver.
+ * Range comments, those starting in column 0 below are a section heading of
+ * sorts and are above the heaps in that range. Often this is the reserved
+ * size of the heap within the range.
+ */
+
+/* 0x00__ /
+
+/* 0x00__ - 0x00_0040_ */
+/* 0 MiB to 4 MiB, size of 4 MiB : RESERVED */
+
+/* 0x00_0040_ - 0x7F_FFC0_ **/
+/* 4 MiB to 512 GiB, size of 512 GiB less 4 MiB : RESERVED **/
+
+/* 0x80__ /
+
+/* 0x80__ - 0x9F__ **/
+/* 512 GiB to 640 GiB, size of 128 GiB : GENERAL_HEAP **/
+#define ROGUE_GENERAL_HEAP_BASE 0x80ull
+#define ROGUE_GENERAL_HEAP_SIZE SZ_128G
+
+/* 0xA0__ - 0xAF__ */
+/* 640 GiB to 704 GiB, size of 64 GiB : FREE */
+
+/* B0__ - 0xB7__ */
+/* 704 GiB to 736 GiB, size of 32 GiB : FREE */
+
+/* 0xB8__ - 0xBF__ */
+/* 736 GiB to 768 GiB, size of 32 GiB : RESERVED */
+
+/* 0xC0__ /
+
+/* 0xC0__ - 0xD9__ */
+/* 768 GiB to 872 GiB, size of 104 GiB : FREE */
+
+/* 0xDA__ - 0xDA__ */
+/* 872 GiB to 876 GiB, size of 4 GiB : PDSCODEDATA_HEAP */
+#define ROGUE_PDSCODEDATA_HEAP_BASE 0xDAull
+#define ROGUE_PDSCODEDATA_HEAP_SIZE SZ_4G
+
+/* 0xDB__ - 0xDB__ */
+/* 876 GiB to 880 GiB, size of 256 MiB (reserved 4GiB) : BRN **/
+/*
+ * The BRN63142 quirk workaround requires Region Header memory to be at the top
+ * of a 16GiB aligned range. This is so when masked with 0x03 the
+ * address will avoid aliasing PB addresses. Start at 879.75GiB. Size of 
256MiB.
+ */
+#define ROGUE_RGNHDR_HEAP_BASE 0xDBF000ull
+#define ROGUE_RGNHDR_HEAP_SIZE SZ_256M
+
+/* 0xDC__ - 0xDF__ */
+/* 880 GiB to 896 GiB, size of 16 GiB : FREE */
+
+/* 0xE0__ - 0xE0__ */
+/* 896 GiB to 900 GiB, size of 4 GiB : USCCODE_HEAP */
+#define ROGUE_USCCODE_HEAP_BASE 0xE0ull
+#define ROGUE_USCCODE_HEAP_SIZE SZ_4G
+
+/* 0xE1__ - 0xE1_BFFF_ */
+/* 900 GiB to 903 GiB, size of 3 GiB : RESERVED */
+
+/* 0xE1_C000_000 - 0xE1__ */
+/* 903 GiB to 904 GiB, reserved 1 GiB, : FIRMWARE_HEAP */
+#define ROGUE_FW_HEAP_BASE 0xE1C000ull
+
+/* 0xE2__ - 0xE3__ */
+/* 904 GiB to 912 GiB, size of 8 GiB : FREE */
+
+/* 0xE4__ - 0xE7__ */
+/* 912 GiB to 968 GiB, size of 16 GiB : TRANSFER_FRAG */
+#define ROGUE_TRANSFER_FRAG_HEAP_BASE 0xE4ull
+#define ROGUE_TRANSFER_FRAG_HEAP_SIZE SZ_16G
+
+/* 0xE8__ - 0xF1__ */
+/* 928 GiB to 968 GiB, size of 40 GiB : RESERVED */
+
+/* 0xF2__ - 0xF2_001F_ **/
+/* 968 GiB to 969 GiB, size of 2 MiB : VISTEST_HEAP */
+#define ROGUE_VISTEST_HEAP_BASE 0xF2ull
+#define ROGUE_VISTEST_HEAP_SIZE SZ_2M
+
+/* 0xF2_4000_ - 0xF2_FFF

Re: [PATCH v3 11/16] platform/x86/amd/pmf: dump policy binary data

2023-10-10 Thread Shyam Sundar S K



On 10/10/2023 6:38 PM, Ilpo Järvinen wrote:
> On Tue, 10 Oct 2023, Shyam Sundar S K wrote:
> 
>> Sometimes policy binary retrieved from the BIOS maybe incorrect that can
>> end up in failing to enable the Smart PC solution feature.
>>
>> Use print_hex_dump_debug() to dump the policy binary in hex, so that we
>> debug the issues related to the binary even before sending that to TA.
>>
>> Signed-off-by: Shyam Sundar S K 
>> ---
>>  drivers/platform/x86/amd/pmf/tee-if.c | 9 +
>>  1 file changed, 9 insertions(+)
>>
>> diff --git a/drivers/platform/x86/amd/pmf/tee-if.c 
>> b/drivers/platform/x86/amd/pmf/tee-if.c
>> index 994daf945795..e4386f503ad0 100644
>> --- a/drivers/platform/x86/amd/pmf/tee-if.c
>> +++ b/drivers/platform/x86/amd/pmf/tee-if.c
>> @@ -275,6 +275,12 @@ static int amd_pmf_start_policy_engine(struct 
>> amd_pmf_dev *dev)
>>  }
>>  
>>  #ifdef CONFIG_AMD_PMF_DEBUG
>> +static void amd_pmf_hex_dump_pb(struct amd_pmf_dev *dev)
>> +{
>> +print_hex_dump_debug("(pb):  ", DUMP_PREFIX_OFFSET, 16, 1, 
>> dev->policy_buf,
>> + dev->policy_sz, false);
>> +}
>> +
> 
> You forgot to add the empty version of amd_pmf_hex_dump_pb function into 
> #else part (so the compile fails if CONFIG_AMD_PMF_DEBUG is not set).
> 

It's there (see below). I have just grouped the functions that come
under #ifdef CONFIG_AMD_PMF_DEBUG and #else so that's more readable.

>>  static ssize_t amd_pmf_get_pb_data(struct file *filp, const char __user 
>> *buf,
>> size_t length, loff_t *pos)
>>  {
>> @@ -289,6 +295,7 @@ static ssize_t amd_pmf_get_pb_data(struct file *filp, 
>> const char __user *buf,
>>  if (copy_from_user(dev->policy_buf, buf, dev->policy_sz))
>>  return -EFAULT;
>>  
>> +amd_pmf_hex_dump_pb(dev);
>>  ret = amd_pmf_start_policy_engine(dev);
>>  if (ret)
>>  return -EINVAL;
>> @@ -327,6 +334,7 @@ static int amd_pmf_open_pb(struct amd_pmf_dev *dev, 
>> struct dentry *debugfs_root)
>>  }
>>  
>>  static void amd_pmf_remove_pb(struct amd_pmf_dev *dev) {}
>> +static void amd_pmf_hex_dump_pb(struct amd_pmf_dev *dev) {}

Here is the empty amd_pmf_hex_dump_pb().

Thanks,
Shyam

>>  #endif
>>  
>>  static int amd_pmf_get_bios_buffer(struct amd_pmf_dev *dev)
>> @@ -341,6 +349,7 @@ static int amd_pmf_get_bios_buffer(struct amd_pmf_dev 
>> *dev)
>>  
>>  memcpy(dev->policy_buf, dev->policy_base, dev->policy_sz);
>>  
>> +amd_pmf_hex_dump_pb(dev);
>>  if (pb_side_load)
>>  amd_pmf_open_pb(dev, dev->dbgfs_dir);
>>  
>>
> 


[PATCH v7 15/20] drm/imagination: Implement free list and HWRT create and destroy ioctls

2023-10-10 Thread Sarah Walker
Implement ioctls to create and destroy free lists and HWRT datasets. Free
lists are used for GPU-side memory allocation during geometry processing.
HWRT datasets are the FW-side structures representing render targets.

Changes since v6:
- Fix out-of-bounds shift in get_cr_multisamplectl_val()

Changes since v4:
- Remove use of drm_gem_shmem_get_pages()

Changes since v3:
- Support free list grow requests from FW
- Use drm_dev_{enter,exit}

Co-developed-by: Boris Brezillon 
Signed-off-by: Boris Brezillon 
Co-developed-by: Donald Robson 
Signed-off-by: Donald Robson 
Signed-off-by: Sarah Walker 
---
 drivers/gpu/drm/imagination/Makefile|   2 +
 drivers/gpu/drm/imagination/pvr_ccb.c   |  10 +
 drivers/gpu/drm/imagination/pvr_device.h|  24 +
 drivers/gpu/drm/imagination/pvr_drv.c   | 112 +++-
 drivers/gpu/drm/imagination/pvr_free_list.c | 625 
 drivers/gpu/drm/imagination/pvr_free_list.h | 195 ++
 drivers/gpu/drm/imagination/pvr_hwrt.c  | 549 +
 drivers/gpu/drm/imagination/pvr_hwrt.h  | 165 ++
 8 files changed, 1678 insertions(+), 4 deletions(-)
 create mode 100644 drivers/gpu/drm/imagination/pvr_free_list.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_free_list.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_hwrt.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_hwrt.h

diff --git a/drivers/gpu/drm/imagination/Makefile 
b/drivers/gpu/drm/imagination/Makefile
index 0a6532d30c00..fca2ee2efbac 100644
--- a/drivers/gpu/drm/imagination/Makefile
+++ b/drivers/gpu/drm/imagination/Makefile
@@ -8,12 +8,14 @@ powervr-y := \
pvr_device.o \
pvr_device_info.o \
pvr_drv.o \
+   pvr_free_list.o \
pvr_fw.o \
pvr_fw_meta.o \
pvr_fw_mips.o \
pvr_fw_startstop.o \
pvr_fw_trace.o \
pvr_gem.o \
+   pvr_hwrt.o \
pvr_mmu.o \
pvr_power.o \
pvr_vm.o \
diff --git a/drivers/gpu/drm/imagination/pvr_ccb.c 
b/drivers/gpu/drm/imagination/pvr_ccb.c
index 64b58b8989ca..f0ea71f72776 100644
--- a/drivers/gpu/drm/imagination/pvr_ccb.c
+++ b/drivers/gpu/drm/imagination/pvr_ccb.c
@@ -4,6 +4,7 @@
 #include "pvr_ccb.h"
 #include "pvr_device.h"
 #include "pvr_drv.h"
+#include "pvr_free_list.h"
 #include "pvr_fw.h"
 #include "pvr_gem.h"
 #include "pvr_power.h"
@@ -139,6 +140,15 @@ process_fwccb_command(struct pvr_device *pvr_dev, struct 
rogue_fwif_fwccb_cmd *c
pvr_power_reset(pvr_dev, false);
break;
 
+   case ROGUE_FWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION:
+   pvr_free_list_process_reconstruct_req(pvr_dev,
+ 
&cmd->cmd_data.cmd_freelists_reconstruction);
+   break;
+
+   case ROGUE_FWIF_FWCCB_CMD_FREELIST_GROW:
+   pvr_free_list_process_grow_req(pvr_dev, 
&cmd->cmd_data.cmd_free_list_gs);
+   break;
+
default:
drm_info(from_pvr_device(pvr_dev), "Received unknown FWCCB 
command %x\n",
 cmd->cmd_type);
diff --git a/drivers/gpu/drm/imagination/pvr_device.h 
b/drivers/gpu/drm/imagination/pvr_device.h
index cbcfc5d4b845..84166266ace8 100644
--- a/drivers/gpu/drm/imagination/pvr_device.h
+++ b/drivers/gpu/drm/imagination/pvr_device.h
@@ -146,6 +146,14 @@ struct pvr_device {
/** @fw_dev: Firmware related data. */
struct pvr_fw_device fw_dev;
 
+   /**
+* @free_list_ids: Array of free lists belonging to this device. Array 
members
+* are of type "struct pvr_free_list *".
+*
+* This array is used to allocate IDs used by the firmware.
+*/
+   struct xarray free_list_ids;
+
struct {
/** @work: Work item for watchdog callback. */
struct delayed_work work;
@@ -241,6 +249,22 @@ struct pvr_file {
 */
struct pvr_device *pvr_dev;
 
+   /**
+* @free_list_handles: Array of free lists belonging to this file. Array
+* members are of type "struct pvr_free_list *".
+*
+* This array is used to allocate handles returned to userspace.
+*/
+   struct xarray free_list_handles;
+
+   /**
+* @hwrt_handles: Array of HWRT datasets belonging to this file. Array
+* members are of type "struct pvr_hwrt_dataset *".
+*
+* This array is used to allocate handles returned to userspace.
+*/
+   struct xarray hwrt_handles;
+
/**
 * @vm_ctx_handles: Array of VM contexts belonging to this file. Array
 * members are of type "struct pvr_vm_context *".
diff --git a/drivers/gpu/drm/imagination/pvr_drv.c 
b/drivers/gpu/drm/imagination/pvr_drv.c
index fb37d8e41d84..9a3f34fdced1 100644
--- a/drivers/gpu/drm/imagination/pvr_drv.c
+++ b/drivers/gpu/drm/imagination/pvr_drv.c
@@ -3,7 +3,9 @@
 
 #include "pvr_device.h"
 #include "pvr_drv.h"
+#include "pvr_free_list.h"
 #include "p

[PATCH v7 04/20] drm/imagination/uapi: Add PowerVR driver UAPI

2023-10-10 Thread Sarah Walker
Add the UAPI implementation for the PowerVR driver.

Changes from v6
- Add padding to struct drm_pvr_dev_query_gpu_info
- Improve BYPASS_CACHE flag documentation
- Add SUBMIT_JOB_FRAG_CMD_DISABLE_PIXELMERGE flag

Changes from v4:
- Remove CREATE_ZEROED flag for BO creation (all buffers are now zeroed)

Co-developed-by: Frank Binns 
Signed-off-by: Frank Binns 
Co-developed-by: Boris Brezillon 
Signed-off-by: Boris Brezillon 
Co-developed-by: Matt Coster 
Signed-off-by: Matt Coster 
Co-developed-by: Donald Robson 
Signed-off-by: Donald Robson 
Signed-off-by: Sarah Walker 
---
 MAINTAINERS|1 +
 include/uapi/drm/pvr_drm.h | 1319 
 2 files changed, 1320 insertions(+)
 create mode 100644 include/uapi/drm/pvr_drm.h

diff --git a/MAINTAINERS b/MAINTAINERS
index eea8e618746a..cfdc7ec02972 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10233,6 +10233,7 @@ M:  Frank Binns 
 M: Donald Robson 
 S: Supported
 F: Documentation/devicetree/bindings/gpu/img,powervr.yaml
+F: include/uapi/drm/pvr_drm.h
 
 IMON SOUNDGRAPH USB IR RECEIVER
 M: Sean Young 
diff --git a/include/uapi/drm/pvr_drm.h b/include/uapi/drm/pvr_drm.h
new file mode 100644
index ..ca021dae7de7
--- /dev/null
+++ b/include/uapi/drm/pvr_drm.h
@@ -0,0 +1,1319 @@
+/* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) OR MIT */
+/* Copyright (c) 2023 Imagination Technologies Ltd. */
+
+#ifndef PVR_DRM_UAPI_H
+#define PVR_DRM_UAPI_H
+
+#include "drm.h"
+
+#include 
+#include 
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/**
+ * DOC: PowerVR UAPI
+ *
+ * The PowerVR IOCTL argument structs have a few limitations in place, in
+ * addition to the standard kernel restrictions:
+ *
+ *  - All members must be type-aligned.
+ *  - The overall struct must be padded to 64-bit alignment.
+ *  - Explicit padding is almost always required. This takes the form of
+ *``_padding_[x]`` members of sufficient size to pad to the next 
power-of-two
+ *alignment, where [x] is the offset into the struct in hexadecimal. Arrays
+ *are never used for alignment. Padding fields must be zeroed; this is
+ *always checked.
+ *  - Unions may only appear as the last member of a struct.
+ *  - Individual union members may grow in the future. The space between the
+ *end of a union member and the end of its containing union is considered
+ *"implicit padding" and must be zeroed. This is always checked.
+ *
+ * In addition to the IOCTL argument structs, the PowerVR UAPI makes use of
+ * DEV_QUERY argument structs. These are used to fetch information about the
+ * device and runtime. These structs are subject to the same rules set out
+ * above.
+ */
+
+/**
+ * struct drm_pvr_obj_array - Container used to pass arrays of objects
+ *
+ * It is not unusual to have to extend objects to pass new parameters, and the 
DRM
+ * ioctl infrastructure is supporting that by padding ioctl arguments with 
zeros
+ * when the data passed by userspace is smaller than the struct defined in the
+ * drm_ioctl_desc, thus keeping things backward compatible. This type is just
+ * applying the same concepts to indirect objects passed through arrays 
referenced
+ * from the main ioctl arguments structure: the stride basically defines the 
size
+ * of the object passed by userspace, which allows the kernel driver to pad 
with
+ * zeros when it's smaller than the size of the object it expects.
+ *
+ * Use ``DRM_PVR_OBJ_ARRAY()`` to fill object array fields, unless you
+ * have a very good reason not to.
+ */
+struct drm_pvr_obj_array {
+   /** @stride: Stride of object struct. Used for versioning. */
+   __u32 stride;
+
+   /** @count: Number of objects in the array. */
+   __u32 count;
+
+   /** @array: User pointer to an array of objects. */
+   __u64 array;
+};
+
+/**
+ * DRM_PVR_OBJ_ARRAY() - Helper macro for filling &struct drm_pvr_obj_array.
+ * @cnt: Number of elements pointed to py @ptr.
+ * @ptr: Pointer to start of a C array.
+ *
+ * Return: Literal of type &struct drm_pvr_obj_array.
+ */
+#define DRM_PVR_OBJ_ARRAY(cnt, ptr) \
+   { .stride = sizeof((ptr)[0]), .count = (cnt), .array = 
(__u64)(uintptr_t)(ptr) }
+
+/**
+ * DOC: PowerVR IOCTL interface
+ */
+
+/**
+ * PVR_IOCTL() - Build a PowerVR IOCTL number
+ * @_ioctl: An incrementing id for this IOCTL. Added to %DRM_COMMAND_BASE.
+ * @_mode: Must be one of %DRM_IOR, %DRM_IOW or %DRM_IOWR.
+ * @_data: The type of the args struct passed by this IOCTL.
+ *
+ * The struct referred to by @_data must have a ``drm_pvr_ioctl_`` prefix and 
an
+ * ``_args suffix``. They are therefore omitted from @_data.
+ *
+ * This should only be used to build the constants described below; it should
+ * never be used to call an IOCTL directly.
+ *
+ * Return: An IOCTL number to be passed to ioctl() from userspace.
+ */
+#define PVR_IOCTL(_ioctl, _mode, _data) \
+   _mode(DRM_COMMAND_BASE + (_ioctl), struct drm_pvr_ioctl_##_data

[PATCH v7 17/20] drm/imagination: Implement job submission and scheduling

2023-10-10 Thread Sarah Walker
Implement job submission ioctl. Job scheduling is implemented using
drm_sched.

Jobs are submitted in a stream format. This is intended to allow the UAPI
data format to be independent of the actual FWIF structures in use, which
vary depending on the GPU in use.

The stream formats are documented at:
https://gitlab.freedesktop.org/mesa/mesa/-/blob/f8d2b42ae65c2f16f36a43e0ae39d288431e4263/src/imagination/csbgen/rogue_kmd_stream.xml

This patch depends on:
drm/sched: Convert drm scheduler to use a work queue rather than kthread:
  
https://lore.kernel.org/dri-devel/20230404002211.3611376-2-matthew.br...@intel.com/
drm/sched: Move schedule policy to scheduler / entity:
  
https://lore.kernel.org/dri-devel/20230404002211.3611376-3-matthew.br...@intel.com/
drm/sched: Add DRM_SCHED_POLICY_SINGLE_ENTITY scheduling policy:
  
https://lore.kernel.org/dri-devel/20230404002211.3611376-4-matthew.br...@intel.com/
drm/sched: Start run wq before TDR in drm_sched_start:
  
https://lore.kernel.org/dri-devel/20230404002211.3611376-6-matthew.br...@intel.com/
drm/sched: Submit job before starting TDR:
  
https://lore.kernel.org/dri-devel/20230404002211.3611376-7-matthew.br...@intel.com/
drm/sched: Add helper to set TDR timeout:
  
https://lore.kernel.org/dri-devel/20230404002211.3611376-8-matthew.br...@intel.com/

Changes since v6:
- Fix fence handling in pvr_sync_signal_array_add()
- Add handling for SUBMIT_JOB_FRAG_CMD_DISABLE_PIXELMERGE flag
- Fix missing dma_resv locking in job submit path

Changes since v5:
- Fix leak in job creation error path

Changes since v4:
- Use a regular workqueue for job scheduling

Changes since v3:
- Support partial render jobs
- Add job timeout handler
- Split sync handling out of job code
- Use drm_dev_{enter,exit}

Changes since v2:
- Use drm_sched for job scheduling

Co-developed-by: Boris Brezillon 
Signed-off-by: Boris Brezillon 
Co-developed-by: Donald Robson 
Signed-off-by: Donald Robson 
Signed-off-by: Sarah Walker 
---
 drivers/gpu/drm/imagination/Kconfig   |1 +
 drivers/gpu/drm/imagination/Makefile  |3 +
 drivers/gpu/drm/imagination/pvr_context.c |  125 +-
 drivers/gpu/drm/imagination/pvr_context.h |   44 +
 drivers/gpu/drm/imagination/pvr_device.c  |   31 +
 drivers/gpu/drm/imagination/pvr_device.h  |   21 +
 drivers/gpu/drm/imagination/pvr_drv.c |   40 +-
 drivers/gpu/drm/imagination/pvr_job.c |  777 +
 drivers/gpu/drm/imagination/pvr_job.h |  161 ++
 drivers/gpu/drm/imagination/pvr_power.c   |   28 +
 drivers/gpu/drm/imagination/pvr_queue.c   | 1455 +
 drivers/gpu/drm/imagination/pvr_queue.h   |  179 ++
 drivers/gpu/drm/imagination/pvr_stream_defs.c |  226 +++
 drivers/gpu/drm/imagination/pvr_sync.c|  289 
 drivers/gpu/drm/imagination/pvr_sync.h|   84 +
 15 files changed, 3460 insertions(+), 4 deletions(-)
 create mode 100644 drivers/gpu/drm/imagination/pvr_job.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_job.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_queue.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_queue.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_sync.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_sync.h

diff --git a/drivers/gpu/drm/imagination/Kconfig 
b/drivers/gpu/drm/imagination/Kconfig
index 2639fbf3ebac..084e72aa82eb 100644
--- a/drivers/gpu/drm/imagination/Kconfig
+++ b/drivers/gpu/drm/imagination/Kconfig
@@ -6,6 +6,7 @@ config DRM_POWERVR
depends on ARM64
depends on DRM
depends on PM
+   select DRM_EXEC
select DRM_GEM_SHMEM_HELPER
select DRM_SCHED
select DRM_GPUVM
diff --git a/drivers/gpu/drm/imagination/Makefile 
b/drivers/gpu/drm/imagination/Makefile
index 0c8ab120f277..313af5312d7b 100644
--- a/drivers/gpu/drm/imagination/Makefile
+++ b/drivers/gpu/drm/imagination/Makefile
@@ -18,10 +18,13 @@ powervr-y := \
pvr_fw_trace.o \
pvr_gem.o \
pvr_hwrt.o \
+   pvr_job.o \
pvr_mmu.o \
pvr_power.o \
+   pvr_queue.o \
pvr_stream.o \
pvr_stream_defs.o \
+   pvr_sync.o \
pvr_vm.o \
pvr_vm_mips.o
 
diff --git a/drivers/gpu/drm/imagination/pvr_context.c 
b/drivers/gpu/drm/imagination/pvr_context.c
index 7ade4d395d1d..42385eb15271 100644
--- a/drivers/gpu/drm/imagination/pvr_context.c
+++ b/drivers/gpu/drm/imagination/pvr_context.c
@@ -6,10 +6,12 @@
 #include "pvr_device.h"
 #include "pvr_drv.h"
 #include "pvr_gem.h"
+#include "pvr_job.h"
 #include "pvr_power.h"
 #include "pvr_rogue_fwif.h"
 #include "pvr_rogue_fwif_common.h"
 #include "pvr_rogue_fwif_resetframework.h"
+#include "pvr_stream.h"
 #include "pvr_stream_defs.h"
 #include "pvr_vm.h"
 
@@ -164,6 +166,116 @@ ctx_fw_data_init(void *cpu_ptr, void *priv)
memcpy(cpu_ptr, ctx->data, ctx->data_size);
 }
 
+/**
+ * pvr_context_destroy_queues() - Destroy all queues attached to a context.
+ * @ctx: Context to destroy queues on

[PATCH v7 10/20] drm/imagination: Add GPU ID parsing and firmware loading

2023-10-10 Thread Sarah Walker
Read the GPU ID register at probe time and select the correct
features/quirks/enhancements. Use the GPU ID to form the firmware
file name and load the firmware.

The features/quirks/enhancements arrays are currently hardcoded in
the driver for the supported GPUs. We are looking at moving this
information to the firmware image.

Changes since v5:
- Add BRN 71242 to device info

Changes since v4:
- Retrieve device information from firmware header
- Pull forward firmware header parsing from FW infrastructure patch
- Use devm_add_action_or_reset to release firmware

Changes since v3:
- Use drm_dev_{enter,exit}

Co-developed-by: Frank Binns 
Signed-off-by: Frank Binns 
Co-developed-by: Matt Coster 
Signed-off-by: Matt Coster 
Co-developed-by: Donald Robson 
Signed-off-by: Donald Robson 
Signed-off-by: Sarah Walker 
---
 drivers/gpu/drm/imagination/Makefile  |   2 +
 drivers/gpu/drm/imagination/pvr_device.c  | 323 ++-
 drivers/gpu/drm/imagination/pvr_device.h  | 220 
 drivers/gpu/drm/imagination/pvr_device_info.c | 254 +
 drivers/gpu/drm/imagination/pvr_device_info.h | 186 +++
 drivers/gpu/drm/imagination/pvr_drv.c | 521 +-
 drivers/gpu/drm/imagination/pvr_drv.h | 107 
 drivers/gpu/drm/imagination/pvr_fw.c  | 145 +
 drivers/gpu/drm/imagination/pvr_fw.h  |  34 ++
 drivers/gpu/drm/imagination/pvr_fw_info.h | 135 +
 10 files changed, 1925 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/imagination/pvr_device_info.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_device_info.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_fw.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_fw.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_fw_info.h

diff --git a/drivers/gpu/drm/imagination/Makefile 
b/drivers/gpu/drm/imagination/Makefile
index b4aa190c9d4a..9e144ff2742b 100644
--- a/drivers/gpu/drm/imagination/Makefile
+++ b/drivers/gpu/drm/imagination/Makefile
@@ -5,6 +5,8 @@ subdir-ccflags-y := -I$(srctree)/$(src)
 
 powervr-y := \
pvr_device.o \
+   pvr_device_info.o \
pvr_drv.o \
+   pvr_fw.o
 
 obj-$(CONFIG_DRM_POWERVR) += powervr.o
diff --git a/drivers/gpu/drm/imagination/pvr_device.c 
b/drivers/gpu/drm/imagination/pvr_device.c
index cef3511c0c42..b1fae182c4f6 100644
--- a/drivers/gpu/drm/imagination/pvr_device.c
+++ b/drivers/gpu/drm/imagination/pvr_device.c
@@ -2,19 +2,31 @@
 /* Copyright (c) 2023 Imagination Technologies Ltd. */
 
 #include "pvr_device.h"
+#include "pvr_device_info.h"
+
+#include "pvr_fw.h"
+#include "pvr_rogue_cr_defs.h"
 
 #include 
 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
 #include 
+#include 
 #include 
 #include 
 #include 
+#include 
+
+/* Major number for the supported version of the firmware. */
+#define PVR_FW_VERSION_MAJOR 1
 
 /**
  * pvr_device_reg_init() - Initialize kernel access to a PowerVR device's
@@ -100,6 +112,209 @@ static int pvr_device_clk_init(struct pvr_device *pvr_dev)
return 0;
 }
 
+/**
+ * pvr_build_firmware_filename() - Construct a PowerVR firmware filename
+ * @pvr_dev: Target PowerVR device.
+ * @base: First part of the filename.
+ * @major: Major version number.
+ *
+ * A PowerVR firmware filename consists of three parts separated by underscores
+ * (``'_'``) along with a '.fw' file suffix. The first part is the exact value
+ * of @base, the second part is the hardware version string derived from 
@pvr_fw
+ * and the final part is the firmware version number constructed from @major 
with
+ * a 'v' prefix, e.g. powervr/rogue_4.40.2.51_v1.fw.
+ *
+ * The returned string will have been slab allocated and must be freed with
+ * kfree().
+ *
+ * Return:
+ *  * The constructed filename on success, or
+ *  * Any error returned by kasprintf().
+ */
+static char *
+pvr_build_firmware_filename(struct pvr_device *pvr_dev, const char *base,
+   u8 major)
+{
+   struct pvr_gpu_id *gpu_id = &pvr_dev->gpu_id;
+
+   return kasprintf(GFP_KERNEL, "%s_%d.%d.%d.%d_v%d.fw", base, gpu_id->b,
+gpu_id->v, gpu_id->n, gpu_id->c, major);
+}
+
+static void
+pvr_release_firmware(void *data)
+{
+   struct pvr_device *pvr_dev = data;
+
+   release_firmware(pvr_dev->fw_dev.firmware);
+}
+
+/**
+ * pvr_request_firmware() - Load firmware for a PowerVR device
+ * @pvr_dev: Target PowerVR device.
+ *
+ * See pvr_build_firmware_filename() for details on firmware file naming.
+ *
+ * Return:
+ *  * 0 on success,
+ *  * Any error returned by pvr_build_firmware_filename(), or
+ *  * Any error returned by request_firmware().
+ */
+static int
+pvr_request_firmware(struct pvr_device *pvr_dev)
+{
+   struct drm_device *drm_dev = &pvr_dev->base;
+   char *filename;
+   const struct firmware *fw;
+   int err;
+
+   filename = pvr_build_firmware_filename(pvr_dev, "powervr/rogue",
+  

  1   2   >