Re: [PATCH] accel/qaic: Support for 0 resize slice execution in BO

2023-10-29 Thread Stanislaw Gruszka
On Fri, Oct 27, 2023 at 10:43:30AM -0600, Jeffrey Hugo wrote:
> From: Pranjal Ramajor Asha Kanojiya 
> 
> Add support to partially execute a slice which is resized to zero.
> Executing a zero size slice in a BO should mean that there is no DMA
> transfers involved but you should still configure doorbell and semaphores.
> 
> For example consider a BO of size 18K and it is sliced into 3 6K slices
> and user calls partial execute ioctl with resize as 10K.
> slice 0 - size is 6k and offset is 0, so resize of 10K will not cut short
>   this slice hence we send the entire slice for execution.
> slice 1 - size is 6k and offset is 6k, so resize of 10K will cut short this
>   slice and only the first 4k should be DMA along with configuring
>   doorbell and semaphores.
> slice 2 - size is 6k and offset is 12k, so resize of 10k will cut short
>   this slice and no DMA transfer would be involved but we should
>   would configure doorbell and semaphores.
> 
> This change begs to change the behavior of 0 resize. Currently, 0 resize
> partial execute ioctl behaves exactly like execute ioctl i.e. no resize.
> After this patch all the slice in BO should behave exactly like slice 2 in
> above example.
> 
> Refactor copy_partial_exec_reqs() to make it more readable and less
> complex.
> 
> Signed-off-by: Pranjal Ramajor Asha Kanojiya 
> Reviewed-by: Jeffrey Hugo 
> Signed-off-by: Jeffrey Hugo 
Reviewed-by: Stanislaw Gruszka 


Re: [PATCH] accel/qaic: Quiet array bounds check on DMA abort message

2023-10-29 Thread Stanislaw Gruszka
On Fri, Oct 27, 2023 at 12:08:10PM -0600, Jeffrey Hugo wrote:
> From: Carl Vanderlip 
> 
> Current wrapper is right-sized to the message being transferred;
> however, this is smaller than the structure defining message wrappers
> since the trailing element is a union of message/transfer headers of
> various sizes (8 and 32 bytes on 32-bit system where issue was
> reported). Using the smaller header with a small message
> (wire_trans_dma_xfer is 24 bytes including header) ends up being smaller
> than a wrapper with the larger header. There are no accesses outside of
> the defined size, however they are possible if the larger union member
> is referenced.
> 
> Abort messages are outside of hot-path and changing the wrapper struct
> would require a larger rewrite, so having the memory allocated to the
> message be 8 bytes too big is acceptable.
> 
> Reported-by: kernel test robot 
> Closes: 
> https://lore.kernel.org/oe-kbuild-all/202310182253.bcb9jcyj-...@intel.com/
> Signed-off-by: Carl Vanderlip 
> Reviewed-by: Pranjal Ramajor Asha Kanojiya 
> Reviewed-by: Jeffrey Hugo 
> Signed-off-by: Jeffrey Hugo 
Reviewed-by: Stanislaw Gruszka 


Re: [PATCH Resend] Fix line Length

2023-10-29 Thread Julia Lawall



On Mon, 30 Oct 2023, Bagas Sanjaya wrote:

> On Sun, Oct 29, 2023 at 04:11:01PM +0100, Julia Lawall wrote:
> >
> >
> > On Sun, 29 Oct 2023, Dorine Tipo wrote:
> >
> > > Signed-off-by: Dorine Tipo 
> > >
> > > Fix the line lengths of lines 8 and 49
> >
> > The Signed off by line should be here, below the log message.  Please see
> > the patches sent by others.
> >
> > >  export IGT_FORCE_DRIVER=${DRIVER_NAME}
> > >  export PATH=$PATH:/igt/bin/
> > > -export 
> > > LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/igt/lib/aarch64-linux-gnu/:/igt/lib/x86_64-linux-gnu:/igt/lib:/igt/lib64
> > > +export 
> > > LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/igt/lib/aarch64-linux-gnu/:/igt/lib/x86_64-linux-gnu
> > > +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/igt/lib:/igt/lib64
> >
> > There was a suggestion that it was better to keep this as one line.
> >
>
> Hi Julia,
>
> The submitter touched one of CI scripts for the DRM subsystem. To test
> this patch, there must be a way to run these scripts locally (which
> may requires non-trivial setup).
>
> Cc'ed DRM maintainers.

There is a DRM outreachy project.  I think that motivated this patch.

julia


Re: [RFC v4 0/5] Proposal to use netlink for RAS and Telemetry across drm subsystem

2023-10-29 Thread Aravind Iddamsetty


On 26/10/23 15:34, Lazar, Lijo wrote:

Hi Lijo,

Thank you for your comments.

>
>
> On 10/23/2023 8:59 PM, Alex Deucher wrote:
>> On Fri, Oct 20, 2023 at 7:42 PM Aravind Iddamsetty
>>  wrote:
>>>
>>> Our hardware supports RAS(Reliability, Availability, Serviceability) by
>>> reporting the errors to the host, which the KMD processes and exposes a
>>> set of error counters which can be used by observability tools to take
>>> corrective actions or repairs. Traditionally there were being exposed
>>> via PMU (for relative counters) and sysfs interface (for absolute
>>> value) in our internal branch. But, due to the limitations in this
>>> approach to use two interfaces and also not able to have an event based
>>> reporting or configurability, an alternative approach to try netlink
>>> was suggested by community for drm subsystem wide UAPI for RAS and
>>> telemetry as discussed in [1].
>>>
>>> This [1] is the inspiration to this series. It uses the generic
>>> netlink(genl) family subsystem and exposes a set of commands that can
>>> be used by every drm driver, the framework provides a means to have
>>> custom commands too. Each drm driver instance in this example xe driver
>>> instance registers a family and operations to the genl subsystem through
>>> which it enumerates and reports the error counters. An event based
>>> notification is also supported to which userpace can subscribe to and
>>> be notified when any error occurs and read the error counter this avoids
>>> continuous polling on error counter. This can also be extended to
>>> threshold based notification.
>
> The commands used seems very limited. In AMD SOCs, IP blocks, instances of IP 
> blocks, block types which support RAS will change across generations.
>
> This series has a single command to query the counters supported. Within that 
> it seems to assign unique ids for every combination of error type, IP block 
> type and then another for each instance. Not sure how good this kind of 
> approach is for an end user. The Ids won't necessarily the stay the same 
> across multiple generations. Users will generally be interested in specific 
> IP blocks.

Exactly the IDs are UAPI and won't change once defined for a platform and any 
new SKU or platform will add on top of existing ones. Userspace can include the 
header and use the defines. The query is used to know what all errors exists on 
a platform and userspace can process the IDs of IP block of interest. I believe 
even if we list block wise a query will be needed without which userspace 
wouldn't know which blocks exist on a platform.

>
> For ex: to get HBM errors, it looks like the current patch series supports 
> READALL which dumps the whole set of errors. Or, users have to figure out the 
> ids of HBM stack instance (whose capacity can change depending on the SOC and 
> within a single family multiple configurations can exist) errors and do 
> multiple READ_ONE calls. Both don't look good.
>
> It would be better if the command argument format can be well defined so that 
> it can be queried based on IP block type, instance, and error types supported 
> (CE/UE/fatal/parity/deferred etc.).

so to mitigate multiple read limitation, we can introduce a new GENL command 
like READ_MULTI which accepts a list of errors ids which userspace can pass and 
get all interested error counter as response at once. Also, listing individual 
errors helps if userspace wants to read a particular error at regular 
intervals. The intention is also to keep KMD logic simple, userspace can build 
required model on top of flat enumeration.

Please let me know if this sounds reasonable to you.

Thanks,
Aravind.
>
> Thanks,
> Lijo
>
>>
>> @Hawking Zhang, @Lazar, Lijo
>>
>> Can you take a look at this series and API and see if it would align
>> with our RAS requirements going forward?
>>
>> Alex
>>
>>
>>>
>>> [1]: 
>>> https://airlied.blogspot.com/2022/09/accelerators-bof-outcomes-summary.html
>>>
>>> this series is on top of https://patchwork.freedesktop.org/series/125373/,
>>>
>>> v4:
>>> 1. Rebase
>>> 2. rename drm_genl_send to drm_genl_reply
>>> 3. catch error from xa_store and handle appropriately
>>> 4. presently xe_list_errors fills blank data for IGFX, prevent it by
>>> having an early check of IS_DGFX (Michael J. Ruhl)
>>>
>>> v3:
>>> 1. Rebase on latest RAS series for XE
>>> 2. drop DRIVER_NETLINK flag and use the driver_genl_ops structure to
>>> register to netlink subsystem
>>>
>>> v2: define common interfaces to genl netlink subsystem that all drm drivers
>>> can leverage.
>>>
>>> Below is an example tool drm_ras which demonstrates the use of the
>>> supported commands. The tool will be sent to ML with the subject
>>> "[RFC i-g-t v2 0/1] A tool to demonstrate use of netlink sockets to read 
>>> RAS error counters"
>>> https://patchwork.freedesktop.org/series/118437/#rev2
>>>
>>> read single error counter:
>>>
>>> $ ./drm_ras READ_ONE --device=drm:/dev/dri/card1 
>>> --error_id=0x0005
>>> 

Re: [PATCH] accel/ivpu: avoid build failure with CONFIG_PM=n

2023-10-29 Thread Stanislaw Gruszka
On Fri, Oct 27, 2023 at 05:26:23PM +0200, Arnd Bergmann wrote:
> From: Arnd Bergmann 
> 
> The usage count of struct dev_pm_info is an implementation detail that
> is only available if CONFIG_PM is enabled, so printing it in a debug message
> causes a build failure in configurations without PM:
> 
> In file included from include/linux/device.h:15,
>  from include/linux/pci.h:37,
>  from drivers/accel/ivpu/ivpu_pm.c:8:
> drivers/accel/ivpu/ivpu_pm.c: In function 'ivpu_rpm_get_if_active':
> drivers/accel/ivpu/ivpu_pm.c:254:51: error: 'struct dev_pm_info' has no 
> member named 'usage_count'
>   254 |  atomic_read(&vdev->drm.dev->power.usage_count));
>   |   ^
> include/linux/dev_printk.h:129:48: note: in definition of macro 'dev_printk'
>   129 | _dev_printk(level, dev, fmt, ##__VA_ARGS__);  
>   \
>   |^~~
> drivers/accel/ivpu/ivpu_drv.h:75:17: note: in expansion of macro 'dev_dbg'
>75 | dev_dbg((vdev)->drm.dev, "[%s] " fmt, #type, ##args); 
>  \
>   | ^~~
> drivers/accel/ivpu/ivpu_pm.c:253:9: note: in expansion of macro 'ivpu_dbg'
>   253 | ivpu_dbg(vdev, RPM, "rpm_get_if_active count %d\n",
>   | ^~~~
> 
> The print message does not seem essential, so the easiest workaround is
> to just remove it.
> 
> Fixes: c39dc15191c4 ("accel/ivpu: Read clock rate only if device is up")
> Signed-off-by: Arnd Bergmann 
Applied to drm-misc-next

Thanks
Stanislaw


Re: [PATCH 3/8] drm/loongson: Allow attach drm bridge driver by calling lsdc_output_init()

2023-10-29 Thread Sui Jingfeng

Hi,


On 2023/10/30 07:10, Dmitry Baryshkov wrote:

+
+/* Built-in HDMI encoder funcs on display pipe 0 */
+
+static void lsdc_pipe0_hdmi_encoder_reset(struct drm_encoder *encoder)
+{
+   struct drm_device *ddev = encoder->dev;
+   struct lsdc_device *ldev = to_lsdc(ddev);
+   u32 val;
+
+   val = PHY_CLOCK_POL | PHY_CLOCK_EN | PHY_DATA_EN;
+   lsdc_wreg32(ldev, LSDC_CRTC0_DVO_CONF_REG, val);
+
+   /* Using built-in GPIO emulated I2C instead of the hardware I2C */
+   lsdc_ureg32_clr(ldev, LSDC_HDMI0_INTF_CTRL_REG, HW_I2C_EN);
+
+   /* Help the HDMI phy get out of reset state */
+   lsdc_wreg32(ldev, LSDC_HDMI0_PHY_CTRL_REG, HDMI_PHY_RESET_N);
+
+   drm_dbg(ddev, "%s reset\n", encoder->name);
+
+   mdelay(20);
+}
+
+const struct drm_encoder_funcs lsdc_pipe0_hdmi_encoder_funcs = {
+   .reset = lsdc_pipe0_hdmi_encoder_reset,
+   .destroy = drm_encoder_cleanup,
+};
+
+/* Built-in HDMI encoder funcs on display pipe 1 */

All pipe 1 code looks like a pipe0, just the registers were changed.
Could you please refactor that to use a single instance of all
functions and pass pipe id through the data struct?
Then you can use macros to determine whether to use pipe 0 or pipe 1 register.



Yes, you are right. But please allow me to explain something.

In the past, Thomas told me to untangle it, despite this idea lead to 
duplicated code(or pattern).
but at the long run, this pay off.

Because the method of passing pipe id will introduce the "if and else" side 
effects.
But my functions have no if and else.


```
if (pipe == 0) {
...
} else if (pipe == 1) {
...
}
```

Using the C program language's Macro(#define XXX) to generate code is not fun 
to me.
Because every time you want to change it, It needs my brains to thinking it 
twice. Maybe
more than twice.

1) It needs my brains to replace the macros manually each time I saw the code.

2) When I want to change(alter) the prototype, I need to worry about all of the 
instances.
   sometimes it is not symmetry. The DVO port and HDMI phy itself is symmetry, 
but the
   external display bridge connected with them are not symmetry. So, there are 
some registers
   located at the domain of this display controller side should change 
according to the
   different type of external display bridge.

3) Code duplication is actually less harmful than unmaintainable.
   macros are abstract, as noob level programmer, we completely drop the idea 
of abstract.
   Bad abstract means design failure, this is what we are most afraid of.
   Generally, we would like divide the whole into small cases, handle them one 
by one.
   It is actually to review and understand.

4) From the viewpoint of the hardware, the display output hardware suffer from 
changes.
   Because users always want *new* display interface. The need of the users are 
also varies.
   Personally, I think macros are best for the symmetry case, while the output 
part of a
   display pipe always suffer from change.


+
+static void lsdc_pipe1_hdmi_encoder_reset(struct drm_encoder *encoder)
+{
+   struct drm_device *ddev = encoder->dev;
+   struct lsdc_device *ldev = to_lsdc(ddev);
+   u32 val;
+
+   val = PHY_CLOCK_POL | PHY_CLOCK_EN | PHY_DATA_EN;
+   lsdc_wreg32(ldev, LSDC_CRTC1_DVO_CONF_REG, val);
+
+   /* Using built-in GPIO emulated I2C instead of the hardware I2C */
+   lsdc_ureg32_clr(ldev, LSDC_HDMI1_INTF_CTRL_REG, HW_I2C_EN);
+
+   /* Help the HDMI phy get out of reset state */
+   lsdc_wreg32(ldev, LSDC_HDMI1_PHY_CTRL_REG, HDMI_PHY_RESET_N);
+
+   drm_dbg(ddev, "%s reset\n", encoder->name);
+
+   mdelay(20);
+}
+
+const struct drm_encoder_funcs lsdc_pipe1_hdmi_encoder_funcs = {
+   .reset = lsdc_pipe1_hdmi_encoder_reset,
+   .destroy = drm_encoder_cleanup,
+};




Re: [PATCH 1/8] drm/loongson: Introduce a minimal support for Loongson VBIOS

2023-10-29 Thread Sui Jingfeng

Hi,


Thanks a lot for reviewing!


On 2023/10/30 06:59, Dmitry Baryshkov wrote:

On Sun, 29 Oct 2023 at 21:46, Sui Jingfeng  wrote:

Because some boards are equipped with non-transparent display bridges,
which need the VBIOS to provided parameters.

Signed-off-by: Sui Jingfeng 
---
  drivers/gpu/drm/loongson/Makefile  |   3 +-
  drivers/gpu/drm/loongson/loongson_device.c |   4 +
  drivers/gpu/drm/loongson/loongson_vbios.c  | 420 +
  drivers/gpu/drm/loongson/loongson_vbios.h  |  59 +++
  drivers/gpu/drm/loongson/lsdc_drv.c|   4 +
  drivers/gpu/drm/loongson/lsdc_drv.h|   8 +
  6 files changed, 497 insertions(+), 1 deletion(-)
  create mode 100644 drivers/gpu/drm/loongson/loongson_vbios.c
  create mode 100644 drivers/gpu/drm/loongson/loongson_vbios.h

diff --git a/drivers/gpu/drm/loongson/Makefile 
b/drivers/gpu/drm/loongson/Makefile
index 91e72bd900c1..bef00b2c5569 100644
--- a/drivers/gpu/drm/loongson/Makefile
+++ b/drivers/gpu/drm/loongson/Makefile
@@ -17,6 +17,7 @@ loongson-y := \
 lsdc_ttm.o

  loongson-y += loongson_device.o \
- loongson_module.o
+ loongson_module.o \
+ loongson_vbios.o

  obj-$(CONFIG_DRM_LOONGSON) += loongson.o
diff --git a/drivers/gpu/drm/loongson/loongson_device.c 
b/drivers/gpu/drm/loongson/loongson_device.c
index 9986c8a2a255..64096ad5466e 100644
--- a/drivers/gpu/drm/loongson/loongson_device.c
+++ b/drivers/gpu/drm/loongson/loongson_device.c
@@ -7,6 +7,8 @@

  #include "lsdc_drv.h"

+extern struct loongson_vbios __loongson_vbios;

Usually names with two underscores in front of them are reserved for
the compiler internals or low level stuff.



Then, is singleunderscore(_loongson_vbios) OK ?

I'm using underscores because I want to tell that the __loongson_vbios is 
opaque handle,
I want to tell that this is nearly a internals stuff, outside program should 
not poke into it.
Outside program can only reference it and should use helpers created in 
loongson_vbios.c to access.

Despite "extern-ed", but it just to take a reference of it. not de-reference.
If a specific SoC don't has VBIOS support, we can use .vbios = NULL; instead.
which is known at compile-time.

If singleunderscore(_loongson_vbios) is OK?
has a underscore  denote that it is a variable, probably helpful to understand.
If OK, I will update it to singleunderscore  at the next version.
 




+
  static const struct lsdc_kms_funcs ls7a1000_kms_funcs = {
 .create_i2c = lsdc_create_i2c_chan,
 .irq_handler = ls7a1000_dc_irq_handler,
@@ -53,6 +55,7 @@ static const struct loongson_gfx_desc ls7a1000_gfx = {
 .reg_size = 8,
 },
 },
+   .vbios = &__loongson_vbios,
 .chip_id = CHIP_LS7A1000,
 .model = "LS7A1000 bridge chipset",
  };
@@ -85,6 +88,7 @@ static const struct loongson_gfx_desc ls7a2000_gfx = {
 .reg_size = 8,
 },
 },
+   .vbios = &__loongson_vbios,
 .chip_id = CHIP_LS7A2000,
 .model = "LS7A2000 bridge chipset",
  };
diff --git a/drivers/gpu/drm/loongson/loongson_vbios.c 
b/drivers/gpu/drm/loongson/loongson_vbios.c
new file mode 100644
index ..dc304018779e
--- /dev/null
+++ b/drivers/gpu/drm/loongson/loongson_vbios.c
@@ -0,0 +1,420 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Loongson Technology Corporation Limited
+ */
+
+#include 
+#include 
+
+#include "loongson_vbios.h"
+#include "lsdc_drv.h"
+
+#define LOONGSON_VBIOS_HEADER_STR   "Loongson-VBIOS"
+/* Legacy VBIOS is stored at offset 0 */
+#define LOONGSON_VBIOS_LEGACY_OFFSET 0
+/* The size of legacy VBIOS is 1 KiB */
+#define LOONGSON_VBIOS_LEGACY_SIZE   0x000400
+
+/* Data Control Block of Newer version of the VBIOS started at here */
+#define LOONGSON_VBIOS_DCB_OFFSET0x006000
+/* The last 1 MiB of the VRAM contains the raw VBIOS data */
+#define LOONGSON_VBIOS_BLOCK_OFFSET  0x10
+/* Only 256KB of the 1 MiB are used for now */
+#define LOONGSON_VBIOS_BLOCK_SIZE0x04
+
+struct loongson_vbios __loongson_vbios;
+
+/*
+ * vbios data control block is a kind of metadata, which is used to index
+ * real hardware device data block.
+ */
+struct loongson_vbios_dcb {
+   u16 type;/* what is it */
+   u8 version;  /* version of it, useless */
+   u8 id;   /* index (usually same with the display pipe) of the 
hardware */
+   u32 offset;  /* the offset of the real data */
+   u32 size;/* the size of the real data */
+   u64 ext0;/* for extension purpose */
+   u64 ext1;/* extra space reserved for future use */
+} __packed;
+
+/*
+ * Loongson-VBIOS Data Block Layout
+ *
+ *
+ * _   0x0
+ *|_|
+ *| |  [0x, 0x0400) : legacy vbios storage
+ *|Not Used Yet |
+ *| |
+ *|--

Re: [PATCH 5/8] drm/loongson: Using vbios for the LS7A2000 output initialization

2023-10-29 Thread kernel test robot
Hi Sui,

kernel test robot noticed the following build warnings:

[auto build test WARNING on drm-misc/drm-misc-next]
[also build test WARNING on linus/master v6.6-rc7 next-20231027]
[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/Sui-Jingfeng/drm-loongson-Introduce-a-minimal-support-for-Loongson-VBIOS/20231030-034730
base:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link:
https://lore.kernel.org/r/20231029194607.379459-6-suijingfeng%40loongson.cn
patch subject: [PATCH 5/8] drm/loongson: Using vbios for the LS7A2000 output 
initialization
config: loongarch-randconfig-002-20231030 
(https://download.01.org/0day-ci/archive/20231030/202310301026.haj8zohj-...@intel.com/config)
compiler: loongarch64-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): 
(https://download.01.org/0day-ci/archive/20231030/202310301026.haj8zohj-...@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/202310301026.haj8zohj-...@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/loongson/lsdc_output_7a2000.c:568:1: warning: no previous 
>> prototype for 'ls7a2000_query_output_configuration' [-Wmissing-prototypes]
 568 | ls7a2000_query_output_configuration(struct drm_device *ddev, 
unsigned int pipe)
 | ^~~
   drivers/gpu/drm/loongson/lsdc_output_7a2000.c:498:46: warning: 
'ls7a2000_encoder_helper_funcs' defined but not used [-Wunused-const-variable=]
 498 | static const struct drm_encoder_helper_funcs 
ls7a2000_encoder_helper_funcs = {
 |  
^
   drivers/gpu/drm/loongson/lsdc_output_7a2000.c:272:39: warning: 
'ls7a2000_encoder_funcs' defined but not used [-Wunused-const-variable=]
 272 | static const struct drm_encoder_funcs ls7a2000_encoder_funcs[2] = {
 |   ^~
   drivers/gpu/drm/loongson/lsdc_output_7a2000.c:201:41: warning: 
'ls7a2000_hdmi_connector_funcs' defined but not used [-Wunused-const-variable=]
 201 | static const struct drm_connector_funcs 
ls7a2000_hdmi_connector_funcs[2] = {
 | ^
   drivers/gpu/drm/loongson/lsdc_output_7a2000.c:77:48: warning: 
'ls7a2000_connector_helpers' defined but not used [-Wunused-const-variable=]
  77 | static const struct drm_connector_helper_funcs 
ls7a2000_connector_helpers = {
 |
^~


vim +/ls7a2000_query_output_configuration +568 
drivers/gpu/drm/loongson/lsdc_output_7a2000.c

   559  
   560  /*
   561   * For LS7A2000, the built-in VGA encoder is transparent. If there are
   562   * external encoder exist, then the internal HDMI encoder MUST be 
enabled
   563   * and initialized. As the internal HDMI encoder is always connected, so
   564   * only the transmitters which take HDMI signal (such as HDMI to eDP, 
HDMI
   565   * to LVDS, etc) are usable with.
   566   */
   567  const struct lsdc_output_desc *
 > 568  ls7a2000_query_output_configuration(struct drm_device *ddev, unsigned 
 > int pipe)
   569  {
   570  enum loongson_vbios_encoder_name encoder_name = 0;
   571  bool ret;
   572  
   573  ret = loongson_vbios_query_encoder_info(ddev, pipe, NULL,
   574  &encoder_name, NULL);
   575  if (!ret)
   576  goto bailout;
   577  
   578  if (pipe == 0) {
   579  switch (encoder_name) {
   580  case ENCODER_CHIP_INTERNAL_HDMI:
   581  return &ls7a2000_hdmi_pipe0;
   582  
   583  /*
   584   * For LS7A2000, the built-in VGA encoder is 
transparent.
   585   */
   586  case ENCODER_CHIP_INTERNAL_VGA:
   587  return &ls7a2000_vga_pipe0;
   588  
   589  /*
   590   * External display bridge exists, the internal HDMI 
encoder
   591   * MUST be enabled and initialized. Please add a drm 
bridge
   592   * driver, and attach to this encoder.
   593   */
   594  default:
   595  return &ls7a2000_hdmi_pipe0;
   596  }
   597  }
   598  
   599  if (pipe == 1) {
   600  switch (encoder_name) {
   601  case ENCODER_CHIP_INTERNAL_HDMI:
   602  return &ls7a20

[PATCH 1/2] nouveau: fix r535 build on 32-bit arm.

2023-10-29 Thread Dave Airlie
From: Dave Airlie 

This needs the proper division macros.

Signed-off-by: Dave Airlie 
---
 drivers/gpu/drm/nouveau/nvkm/engine/fifo/r535.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/r535.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/r535.c
index 14a67cf96204..0f9b8087d5e6 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/r535.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/r535.c
@@ -267,7 +267,7 @@ r535_chan_id_get_locked(struct nvkm_chan *chan, struct 
nvkm_memory *muserd, u64
return -EINVAL;
}
 
-   chid = ouserd / chan->func->userd->size;
+   chid = div_u64(ouserd, chan->func->userd->size);
 
list_for_each_entry(userd, &fifo->userd.list, head) {
if (userd->mem == muserd) {
-- 
2.41.0



[PATCH 2/2] nouveau/disp: fix post-gsp build on 32-bit arm.

2023-10-29 Thread Dave Airlie
From: Dave Airlie 

This converts a bunch of divides into the proper macros.

Signed-off-by: Dave Airlie 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 24 +---
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index d2be40337b92..7840b6428afb 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -1644,7 +1644,7 @@ nv50_sor_dp_watermark_sst(struct nouveau_encoder *outp,
// 0 active symbols. This may cause HW hang. Bug 200379426
//
if ((bEnableDsc) &&
-   ((pixelClockHz * depth) < ((8 * minRate * outp->dp.link_nr * 
DSC_FACTOR) / 64)))
+   ((pixelClockHz * depth) < div_u64(8 * minRate * outp->dp.link_nr * 
DSC_FACTOR, 64)))
{
return false;
}
@@ -1654,20 +1654,20 @@ nv50_sor_dp_watermark_sst(struct nouveau_encoder *outp,
//  For auto mode the watermark calculation does not need to track 
accumulated error the
//  formulas for manual mode will not work.  So below calculation 
was extracted from the DTB.
//
-   ratioF = ((u64)pixelClockHz * depth * PrecisionFactor) / DSC_FACTOR;
+   ratioF = div_u64((u64)pixelClockHz * depth * PrecisionFactor, 
DSC_FACTOR);
 
-   ratioF /= 8 * (u64) minRate * outp->dp.link_nr;
+   ratioF = div_u64(ratioF, 8 * (u64) minRate * outp->dp.link_nr);
 
if (PrecisionFactor < ratioF) // Assert if we will end up with a 
negative number in below
return false;
 
-   watermarkF = ratioF * tuSize * (PrecisionFactor - ratioF)  / 
PrecisionFactor;
-   waterMark = (unsigned)(watermarkAdjust + ((2 * (depth * PrecisionFactor 
/ (8 * numLanesPerLink * DSC_FACTOR)) + watermarkF) / PrecisionFactor));
+   watermarkF = div_u64(ratioF * tuSize * (PrecisionFactor - ratioF), 
PrecisionFactor);
+   waterMark = (unsigned)(watermarkAdjust + (div_u64(2 * div_u64(depth * 
PrecisionFactor, 8 * numLanesPerLink * DSC_FACTOR) + watermarkF, 
PrecisionFactor)));
 
//
//  Bounds check the watermark
//
-   numSymbolsPerLine = (surfaceWidth * depth) / (8 * outp->dp.link_nr * 
DSC_FACTOR);
+   numSymbolsPerLine = div_u64(surfaceWidth * depth, 8 * outp->dp.link_nr 
* DSC_FACTOR);
 
if (WARN_ON(waterMark > 39 || waterMark > numSymbolsPerLine))
return false;
@@ -1688,11 +1688,13 @@ nv50_sor_dp_watermark_sst(struct nouveau_encoder *outp,
surfaceWidthPerLink = surfaceWidth;
 
//Extra bits sent due to pixel steering
-   PixelSteeringBits = (surfaceWidthPerLink % numLanesPerLink) ? 
(((numLanesPerLink - surfaceWidthPerLink % numLanesPerLink) * depth) / 
DSC_FACTOR) : 0;
+   u32 remain;
+   div_u64_rem(surfaceWidthPerLink, numLanesPerLink, &remain);
+   PixelSteeringBits = remain ? div_u64((numLanesPerLink - remain) * 
depth, DSC_FACTOR) : 0;
 
BlankingBits += PixelSteeringBits;
-   NumBlankingLinkClocks = (u64)BlankingBits * PrecisionFactor / (8 * 
numLanesPerLink);
-   MinHBlank = (u32)(NumBlankingLinkClocks * pixelClockHz/ minRate / 
PrecisionFactor);
+   NumBlankingLinkClocks = div_u64((u64)BlankingBits * PrecisionFactor, (8 
* numLanesPerLink));
+   MinHBlank = (u32)(div_u64(div_u64(NumBlankingLinkClocks * pixelClockHz, 
minRate), PrecisionFactor));
MinHBlank += 12;
 
if (WARN_ON(MinHBlank > rasterWidth - surfaceWidth))
@@ -1703,7 +1705,7 @@ nv50_sor_dp_watermark_sst(struct nouveau_encoder *outp,
return false;
 
 
-   hblank_symbols = (s32)(((u64)(rasterWidth - surfaceWidth - MinHBlank) * 
minRate) / pixelClockHz);
+   hblank_symbols = (s32)(div_u64((u64)(rasterWidth - surfaceWidth - 
MinHBlank) * minRate, pixelClockHz));
 
//reduce HBlank Symbols to account for secondary data packet
hblank_symbols -= 1; //Stuffer latency to send BS
@@ -1722,7 +1724,7 @@ nv50_sor_dp_watermark_sst(struct nouveau_encoder *outp,
}
else
{
-   vblank_symbols = (s32)(((u64)(surfaceWidth - 40) * minRate) /  
pixelClockHz) - 1;
+   vblank_symbols = (s32)((div_u64((u64)(surfaceWidth - 40) * 
minRate, pixelClockHz))) - 1;
 
vblank_symbols -= numLanesPerLink == 1 ? 39  : numLanesPerLink 
== 2 ? 21 : 12;
}
-- 
2.41.0



Re: [PATCH 3/8] drm/loongson: Allow attach drm bridge driver by calling lsdc_output_init()

2023-10-29 Thread kernel test robot
Hi Sui,

kernel test robot noticed the following build warnings:

[auto build test WARNING on drm-misc/drm-misc-next]
[also build test WARNING on linus/master v6.6-rc7 next-20231027]
[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/Sui-Jingfeng/drm-loongson-Introduce-a-minimal-support-for-Loongson-VBIOS/20231030-034730
base:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link:
https://lore.kernel.org/r/20231029194607.379459-4-suijingfeng%40loongson.cn
patch subject: [PATCH 3/8] drm/loongson: Allow attach drm bridge driver by 
calling lsdc_output_init()
config: loongarch-randconfig-002-20231030 
(https://download.01.org/0day-ci/archive/20231030/202310300738.zcudnqfj-...@intel.com/config)
compiler: loongarch64-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): 
(https://download.01.org/0day-ci/archive/20231030/202310300738.zcudnqfj-...@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/202310300738.zcudnqfj-...@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/loongson/lsdc_output.c:555:5: warning: no previous prototype 
>> for 'lsdc_encoder_init' [-Wmissing-prototypes]
 555 | int lsdc_encoder_init(struct drm_device *ddev,
 | ^
>> drivers/gpu/drm/loongson/lsdc_output.c:578:5: warning: no previous prototype 
>> for 'lsdc_connector_init' [-Wmissing-prototypes]
 578 | int lsdc_connector_init(struct drm_device *ddev,
 | ^~~


vim +/lsdc_encoder_init +555 drivers/gpu/drm/loongson/lsdc_output.c

   554  
 > 555  int lsdc_encoder_init(struct drm_device *ddev,
   556struct lsdc_output *output,
   557unsigned int pipe)
   558  {
   559  const struct lsdc_output_desc *descp = output->descp;
   560  struct drm_encoder *encoder = &output->encoder;
   561  int ret;
   562  
   563  ret = drm_encoder_init(ddev,
   564 encoder,
   565 descp->encoder_funcs,
   566 descp->encoder_type,
   567 descp->name);
   568  if (ret)
   569  return ret;
   570  
   571  encoder->possible_crtcs = BIT(pipe);
   572  
   573  drm_encoder_helper_add(encoder, descp->encoder_helper_funcs);
   574  
   575  return 0;
   576  }
   577  
 > 578  int lsdc_connector_init(struct drm_device *ddev,
   579  struct lsdc_output *output,
   580  struct i2c_adapter *ddc,
   581  unsigned int pipe)
   582  {
   583  const struct lsdc_output_desc *descp = output->descp;
   584  struct drm_connector *connector = &output->connector;
   585  int ret;
   586  
   587  ret = drm_connector_init_with_ddc(ddev,
   588connector,
   589descp->connector_funcs,
   590descp->connector_type,
   591ddc);
   592  if (ret)
   593  return ret;
   594  
   595  drm_connector_helper_add(connector, 
descp->connector_helper_funcs);
   596  
   597  drm_connector_attach_encoder(connector, &output->encoder);
   598  
   599  connector->polled = DRM_CONNECTOR_POLL_CONNECT |
   600  DRM_CONNECTOR_POLL_DISCONNECT;
   601  
   602  connector->interlace_allowed = 0;
   603  connector->doublescan_allowed = 0;
   604  
   605  drm_info(ddev, "DisplayPipe-%u has %s\n", pipe, descp->name);
   606  
   607  return 0;
   608  }
   609  

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


Re: [PATCH Resend] Fix line Length

2023-10-29 Thread Bagas Sanjaya
On Sun, Oct 29, 2023 at 04:11:01PM +0100, Julia Lawall wrote:
> 
> 
> On Sun, 29 Oct 2023, Dorine Tipo wrote:
> 
> > Signed-off-by: Dorine Tipo 
> >
> > Fix the line lengths of lines 8 and 49
> 
> The Signed off by line should be here, below the log message.  Please see
> the patches sent by others.
> 
> >  export IGT_FORCE_DRIVER=${DRIVER_NAME}
> >  export PATH=$PATH:/igt/bin/
> > -export 
> > LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/igt/lib/aarch64-linux-gnu/:/igt/lib/x86_64-linux-gnu:/igt/lib:/igt/lib64
> > +export 
> > LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/igt/lib/aarch64-linux-gnu/:/igt/lib/x86_64-linux-gnu
> > +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/igt/lib:/igt/lib64
> 
> There was a suggestion that it was better to keep this as one line.
> 

Hi Julia,

The submitter touched one of CI scripts for the DRM subsystem. To test
this patch, there must be a way to run these scripts locally (which
may requires non-trivial setup).

Cc'ed DRM maintainers.

Thanks.

-- 
An old man doll... just what I always wanted! - Clara


signature.asc
Description: PGP signature


Re: [PATCH 7/8] drm/loongson: Support to infer DC reversion from CPU's PRID value

2023-10-29 Thread Dmitry Baryshkov
On Sun, 29 Oct 2023 at 21:46, Sui Jingfeng  wrote:
>
> Due to the fact that the same display IP core has been integrated into
> different platform, there is a need to differentiate them on the runtime.
> The DC in LS7A1000/LS2K1000 has the PCI vendor & device ID of 0x0014:0x7A06
> The DC in LS7A2000/LS2K2000 has the PCI vendor & device ID of 0x0014:0x7A36
>
> Because the output ports and host platform of the DC IP varies, without a
> revision information we can't achieve fine-grained controls. The canonical
> approach to do such a thing is to read reversion register from the PCIe
> device. But LS2K1000 SoC was taped out at 2017, it is rather old. Our BIOS
> engineer don't assign a different revision ID to it, probably because of
> ignorance.
>
> LS2K2000 SoC was newly taped on 2023, we strictly force the BIOS engineer
> assign a different revision ID(0x10) to it. But the problem is that it is
> too casual, there is no formal convention or public documented rule
> established. For Loongson LS2K series SoC, the display controller IP is
> taped togather with the CPU core. For Loongson LS7A series bridge chips,
> the display controller IP is taped togather with the bridge chips itself.
> Consider the fact the all Loongson CPU has a unique PRID, this patch choose
> to infer DC reversion from CPU's PRID value.
>
>  - LS3A4000/LS3A5000 has 0xC0 as its processor ID.
>  - LS2K2000 has 0xB0 as its processor ID.
>  - LS2K2000LA has 0xA0 as its processor ID.
>
> The provided approach has no dependency on DT or ACPI, thus is preferfed.
> Besides, this approach can be used to acquire more addtional HW features.
> So the provided method has the potential to bring more benifits.
>
> Signed-off-by: Sui Jingfeng 
> ---
>  drivers/gpu/drm/loongson/lsdc_drv.h   |  2 ++
>  drivers/gpu/drm/loongson/lsdc_probe.c | 35 +++
>  drivers/gpu/drm/loongson/lsdc_probe.h |  2 ++
>  3 files changed, 39 insertions(+)
>
> diff --git a/drivers/gpu/drm/loongson/lsdc_drv.h 
> b/drivers/gpu/drm/loongson/lsdc_drv.h
> index 46ba9b88a30d..e1f4a2db2a0a 100644
> --- a/drivers/gpu/drm/loongson/lsdc_drv.h
> +++ b/drivers/gpu/drm/loongson/lsdc_drv.h
> @@ -42,6 +42,8 @@
>  enum loongson_chip_id {
> CHIP_LS7A1000 = 0,
> CHIP_LS7A2000 = 1,
> +   CHIP_LS2K1000 = 2,
> +   CHIP_LS2K2000 = 3,
> CHIP_LS_LAST,
>  };
>
> diff --git a/drivers/gpu/drm/loongson/lsdc_probe.c 
> b/drivers/gpu/drm/loongson/lsdc_probe.c
> index 48ba69bb8a98..f49b642d8f65 100644
> --- a/drivers/gpu/drm/loongson/lsdc_probe.c
> +++ b/drivers/gpu/drm/loongson/lsdc_probe.c
> @@ -54,3 +54,38 @@ unsigned int loongson_cpu_get_prid(u8 *imp, u8 *rev)
>
> return prid;
>  }
> +
> +enum loongson_chip_id loongson_chip_id_fixup(enum loongson_chip_id chip_id)
> +{
> +   u8 impl;
> +
> +   if (loongson_cpu_get_prid(&impl, NULL)) {
> +   /*
> +* LS2K2000 only has the LoongArch edition.
> +*/
> +   if (chip_id == CHIP_LS7A2000) {
> +   if (impl == LOONGARCH_CPU_IMP_LS2K2000)
> +   return CHIP_LS2K2000;
> +   }
> +
> +   /*
> +* LS2K1000 has the LoongArch edition(with two LA264 CPU core)
> +* and the Mips edition(with two mips64r2 CPU core), Only the
> +* instruction set of the CPU are changed, the peripheral
> +* devices are basically same.
> +*/
> +   if (chip_id == CHIP_LS7A1000) {
> +#if defined(__loongarch__)
> +   if (impl == LOONGARCH_CPU_IMP_LS2K1000)
> +   return CHIP_LS2K1000;
> +#endif
> +
> +#if defined(__mips__)
> +   if (impl == LOONGSON_CPU_MIPS_IMP_LS2K)
> +   return CHIP_LS2K1000;
> +#endif

Can you drop the ifdefs here? The code blocks do not seem to conflict
with each other.

> +   }
> +   }
> +
> +   return chip_id;
> +}
> diff --git a/drivers/gpu/drm/loongson/lsdc_probe.h 
> b/drivers/gpu/drm/loongson/lsdc_probe.h
> index 8bb6de2e3c64..8c630c5c90ce 100644
> --- a/drivers/gpu/drm/loongson/lsdc_probe.h
> +++ b/drivers/gpu/drm/loongson/lsdc_probe.h
> @@ -9,4 +9,6 @@
>  /* Helpers for chip detection */
>  unsigned int loongson_cpu_get_prid(u8 *impl, u8 *rev);
>
> +enum loongson_chip_id loongson_chip_id_fixup(enum loongson_chip_id chip_id);
> +
>  #endif
> --
> 2.34.1
>


-- 
With best wishes
Dmitry


Re: [PATCH 6/8] drm/loongson: Clean up the output part of LS7A2000

2023-10-29 Thread Dmitry Baryshkov
On Sun, 29 Oct 2023 at 21:46, Sui Jingfeng  wrote:
>
> Since the majority of sharable subroutines have been move to lsdc_output.c,
> and functional changes are done with previous patch. We finally see the
> light to cleanup, no functional change.

Please refactor your patches so that code moves can be reviewed as
code being moved, instead of add + remove patches.

>
> Signed-off-by: Sui Jingfeng 
> ---
>  drivers/gpu/drm/loongson/lsdc_output_7a2000.c | 469 --
>  1 file changed, 469 deletions(-)
>
> diff --git a/drivers/gpu/drm/loongson/lsdc_output_7a2000.c 
> b/drivers/gpu/drm/loongson/lsdc_output_7a2000.c
> index bf558b61802b..981ab2045e91 100644
> --- a/drivers/gpu/drm/loongson/lsdc_output_7a2000.c
> +++ b/drivers/gpu/drm/loongson/lsdc_output_7a2000.c
> @@ -42,465 +42,6 @@
>   *  |__|
>   */
>
> -static int ls7a2000_connector_get_modes(struct drm_connector *connector)
> -{
> -   unsigned int num = 0;
> -   struct edid *edid;
> -
> -   if (connector->ddc) {
> -   edid = drm_get_edid(connector, connector->ddc);
> -   if (edid) {
> -   drm_connector_update_edid_property(connector, edid);
> -   num = drm_add_edid_modes(connector, edid);
> -   kfree(edid);
> -   }
> -
> -   return num;
> -   }
> -
> -   num = drm_add_modes_noedid(connector, 1920, 1200);
> -
> -   drm_set_preferred_mode(connector, 1024, 768);
> -
> -   return num;
> -}
> -
> -static struct drm_encoder *
> -ls7a2000_connector_get_best_encoder(struct drm_connector *connector,
> -   struct drm_atomic_state *state)
> -{
> -   struct lsdc_output *output = connector_to_lsdc_output(connector);
> -
> -   return &output->encoder;
> -}
> -
> -static const struct drm_connector_helper_funcs ls7a2000_connector_helpers = {
> -   .atomic_best_encoder = ls7a2000_connector_get_best_encoder,
> -   .get_modes = ls7a2000_connector_get_modes,
> -};
> -
> -/* debugfs */
> -
> -#define LSDC_HDMI_REG(i, reg) {   \
> -   .name = __stringify_1(LSDC_HDMI##i##_##reg##_REG),\
> -   .offset = LSDC_HDMI##i##_##reg##_REG, \
> -}
> -
> -static const struct lsdc_reg32 ls7a2000_hdmi0_encoder_regs[] = {
> -   LSDC_HDMI_REG(0, ZONE),
> -   LSDC_HDMI_REG(0, INTF_CTRL),
> -   LSDC_HDMI_REG(0, PHY_CTRL),
> -   LSDC_HDMI_REG(0, PHY_PLL),
> -   LSDC_HDMI_REG(0, AVI_INFO_CRTL),
> -   LSDC_HDMI_REG(0, PHY_CAL),
> -   LSDC_HDMI_REG(0, AUDIO_PLL_LO),
> -   LSDC_HDMI_REG(0, AUDIO_PLL_HI),
> -   {NULL, 0},  /* MUST be {NULL, 0} terminated */
> -};
> -
> -static const struct lsdc_reg32 ls7a2000_hdmi1_encoder_regs[] = {
> -   LSDC_HDMI_REG(1, ZONE),
> -   LSDC_HDMI_REG(1, INTF_CTRL),
> -   LSDC_HDMI_REG(1, PHY_CTRL),
> -   LSDC_HDMI_REG(1, PHY_PLL),
> -   LSDC_HDMI_REG(1, AVI_INFO_CRTL),
> -   LSDC_HDMI_REG(1, PHY_CAL),
> -   LSDC_HDMI_REG(1, AUDIO_PLL_LO),
> -   LSDC_HDMI_REG(1, AUDIO_PLL_HI),
> -   {NULL, 0},  /* MUST be {NULL, 0} terminated */
> -};
> -
> -static int ls7a2000_hdmi_encoder_regs_show(struct seq_file *m, void *data)
> -{
> -   struct drm_info_node *node = (struct drm_info_node *)m->private;
> -   struct drm_device *ddev = node->minor->dev;
> -   struct lsdc_device *ldev = to_lsdc(ddev);
> -   const struct lsdc_reg32 *preg;
> -
> -   preg = (const struct lsdc_reg32 *)node->info_ent->data;
> -
> -   while (preg->name) {
> -   u32 offset = preg->offset;
> -
> -   seq_printf(m, "%s (0x%04x): 0x%08x\n",
> -  preg->name, offset, lsdc_rreg32(ldev, offset));
> -   ++preg;
> -   }
> -
> -   return 0;
> -}
> -
> -static const struct drm_info_list ls7a2000_hdmi0_debugfs_files[] = {
> -   { "regs", ls7a2000_hdmi_encoder_regs_show, 0, (void 
> *)ls7a2000_hdmi0_encoder_regs },
> -};
> -
> -static const struct drm_info_list ls7a2000_hdmi1_debugfs_files[] = {
> -   { "regs", ls7a2000_hdmi_encoder_regs_show, 0, (void 
> *)ls7a2000_hdmi1_encoder_regs },
> -};
> -
> -static void ls7a2000_hdmi0_late_register(struct drm_connector *connector,
> -struct dentry *root)
> -{
> -   struct drm_device *ddev = connector->dev;
> -   struct drm_minor *minor = ddev->primary;
> -
> -   drm_debugfs_create_files(ls7a2000_hdmi0_debugfs_files,
> -ARRAY_SIZE(ls7a2000_hdmi0_debugfs_files),
> -root, minor);
> -}
> -
> -static void ls7a2000_hdmi1_late_register(struct drm_connector *connector,
> -struct dentry *root)
> -{
> -   struct drm_device *ddev = connector->dev;
> -   struct drm_minor *minor = ddev->primary;
> -
> -   drm_debugfs_create_files(ls7a2000_hdmi1_debugfs_files,
> -

Re: [PATCH 4/8] drm/loongson: Started to attach display bridge driver for LS7A1000

2023-10-29 Thread Dmitry Baryshkov
On Sun, 29 Oct 2023 at 21:46, Sui Jingfeng  wrote:
>
> Loongson ML5B_MA board using ITE IT66121 HDMI transmitter to support HDMI
> display output, with the vbios provided the necessary information, we are
> able to create a minimal drm bridge driver for it. After apply this patch
> we are able to change mode freely.

Please see the Documentation/process/submitting-patches.rst:

Describe your changes in imperative mood, e.g. "make xyzzy do frotz"
instead of "[This patch] makes xyzzy do frotz" or "[I] changed xyzzy
to do frotz", as if you are giving orders to the codebase to change
its behaviour.

>
> Tested on LS3A5000+LS7A1000 ML5B_MA board.
>
> $ dmesg | grep drm
>
>  [drm] dc: 264MHz, gmc: 529MHz, gpu: 529MHz
>  [drm] Dedicated vram start: 0xe003000, size: 64MiB
>  [drm] Loongson VBIOS version: 0.3
>  [drm] Loongson VBIOS: has 8 DCBs
>  [drm] VRAM: 4096 pages ready
>  [drm] GTT: 32768 pages ready
>  [drm] lsdc-i2c0(sda pin mask=1, scl pin mask=2) created
>  [drm] lsdc-i2c1(sda pin mask=4, scl pin mask=8) created
>  [drm] DisplayPipe-0 has DVO-0
>  [drm] device address(0x4d) is not correct
>  [drm] i2c client IT66121@0x4c created
>  [drm] IT66121 attached, Vendor ID: 0x4954, Device ID: 0x612
>  [drm] Total 2 outputs
>  [drm] registered irq: 40
>  [drm] Initialized loongson 1.0.0 20220701 for :00:06.1 on minor 0
>  loongson :00:06.1: [drm] fb0: loongsondrmfb frame buffer device
>
> Signed-off-by: Sui Jingfeng 
> ---
>  drivers/gpu/drm/loongson/lsdc_output_7a1000.c | 144 +++---
>  1 file changed, 55 insertions(+), 89 deletions(-)
>
> diff --git a/drivers/gpu/drm/loongson/lsdc_output_7a1000.c 
> b/drivers/gpu/drm/loongson/lsdc_output_7a1000.c
> index 6fc8dd1c7d9a..e12f9a0157d0 100644
> --- a/drivers/gpu/drm/loongson/lsdc_output_7a1000.c
> +++ b/drivers/gpu/drm/loongson/lsdc_output_7a1000.c
> @@ -10,6 +10,7 @@
>  #include "lsdc_drv.h"
>  #include "lsdc_output.h"
>
> +#include "ite_it66121.h"
>  /*
>   * The display controller in the LS7A1000 exports two DVO interfaces, thus
>   * external encoder is required, except connected to the DPI panel directly.
> @@ -38,68 +39,6 @@
>   *  TODO: Add support for non-transparent encoders
>   */
>
> -static int ls7a1000_dpi_connector_get_modes(struct drm_connector *conn)
> -{
> -   unsigned int num = 0;
> -   struct edid *edid;
> -
> -   if (conn->ddc) {
> -   edid = drm_get_edid(conn, conn->ddc);
> -   if (edid) {
> -   drm_connector_update_edid_property(conn, edid);
> -   num = drm_add_edid_modes(conn, edid);
> -   kfree(edid);
> -   }
> -
> -   return num;
> -   }
> -
> -   num = drm_add_modes_noedid(conn, 1920, 1200);
> -
> -   drm_set_preferred_mode(conn, 1024, 768);
> -
> -   return num;
> -}
> -
> -static struct drm_encoder *
> -ls7a1000_dpi_connector_get_best_encoder(struct drm_connector *connector,
> -   struct drm_atomic_state *state)
> -{
> -   struct lsdc_output *output = connector_to_lsdc_output(connector);
> -
> -   return &output->encoder;
> -}
> -
> -static const struct drm_connector_helper_funcs
> -ls7a1000_dpi_connector_helpers = {
> -   .atomic_best_encoder = ls7a1000_dpi_connector_get_best_encoder,
> -   .get_modes = ls7a1000_dpi_connector_get_modes,
> -};
> -
> -static enum drm_connector_status
> -ls7a1000_dpi_connector_detect(struct drm_connector *connector, bool force)
> -{
> -   struct i2c_adapter *ddc = connector->ddc;
> -
> -   if (ddc) {
> -   if (drm_probe_ddc(ddc))
> -   return connector_status_connected;
> -
> -   return connector_status_disconnected;
> -   }
> -
> -   return connector_status_unknown;
> -}
> -
> -static const struct drm_connector_funcs ls7a1000_dpi_connector_funcs = {
> -   .detect = ls7a1000_dpi_connector_detect,
> -   .fill_modes = drm_helper_probe_single_connector_modes,
> -   .destroy = drm_connector_cleanup,
> -   .reset = drm_atomic_helper_connector_reset,
> -   .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
> -   .atomic_destroy_state = drm_atomic_helper_connector_destroy_state
> -};
> -
>  static void ls7a1000_pipe0_encoder_reset(struct drm_encoder *encoder)
>  {
> struct drm_device *ddev = encoder->dev;
> @@ -139,40 +78,67 @@ static const struct drm_encoder_funcs 
> ls7a1000_encoder_funcs[2] = {
> },
>  };
>
> +/*
> + * This is a default output description for LS7A1000/LS2K1000, this is always
> + * true from the hardware perspective. It is just that when there are 
> external
> + * display bridge connected, this description no longer complete. As it 
> cannot
> + * describe the topology about the external encoders.
> + */
> +static const struct lsdc_output_desc ls7a1000_output_desc[2] = {
> +   {
> +   .pipe = 0,
> +   .encoder_type = DRM_MODE_ENCODER_DPI,
> 

Re: [PATCH 3/8] drm/loongson: Allow attach drm bridge driver by calling lsdc_output_init()

2023-10-29 Thread Dmitry Baryshkov
On Sun, 29 Oct 2023 at 21:46, Sui Jingfeng  wrote:
>
> Move the sharable subroutine into lsdc_output.c and refactor.
>
> Signed-off-by: Sui Jingfeng 
> ---
>  drivers/gpu/drm/loongson/Makefile  |   1 +
>  drivers/gpu/drm/loongson/lsdc_drv.h|  17 -
>  drivers/gpu/drm/loongson/lsdc_output.c | 640 +
>  drivers/gpu/drm/loongson/lsdc_output.h |  52 +-

This diffstat doesn't match patch description.

>  4 files changed, 691 insertions(+), 19 deletions(-)
>  create mode 100644 drivers/gpu/drm/loongson/lsdc_output.c
>
> diff --git a/drivers/gpu/drm/loongson/Makefile 
> b/drivers/gpu/drm/loongson/Makefile
> index 1459d19b2c90..393709e686aa 100644
> --- a/drivers/gpu/drm/loongson/Makefile
> +++ b/drivers/gpu/drm/loongson/Makefile
> @@ -9,6 +9,7 @@ loongson-y := \
> lsdc_gfxpll.o \
> lsdc_i2c.o \
> lsdc_irq.o \
> +   lsdc_output.o \
> lsdc_output_7a1000.o \
> lsdc_output_7a2000.o \
> lsdc_plane.o \
> diff --git a/drivers/gpu/drm/loongson/lsdc_drv.h 
> b/drivers/gpu/drm/loongson/lsdc_drv.h
> index 335953c988d1..46ba9b88a30d 100644
> --- a/drivers/gpu/drm/loongson/lsdc_drv.h
> +++ b/drivers/gpu/drm/loongson/lsdc_drv.h
> @@ -175,23 +175,6 @@ struct lsdc_cursor {
> struct lsdc_device *ldev;
>  };
>
> -struct lsdc_output {
> -   struct drm_encoder encoder;
> -   struct drm_connector connector;
> -};
> -
> -static inline struct lsdc_output *
> -connector_to_lsdc_output(struct drm_connector *connector)
> -{
> -   return container_of(connector, struct lsdc_output, connector);
> -}
> -
> -static inline struct lsdc_output *
> -encoder_to_lsdc_output(struct drm_encoder *encoder)
> -{
> -   return container_of(encoder, struct lsdc_output, encoder);
> -}
> -
>  struct lsdc_display_pipe {
> struct lsdc_crtc crtc;
> struct lsdc_primary primary;
> diff --git a/drivers/gpu/drm/loongson/lsdc_output.c 
> b/drivers/gpu/drm/loongson/lsdc_output.c
> new file mode 100644
> index ..8262c3f91ebe
> --- /dev/null
> +++ b/drivers/gpu/drm/loongson/lsdc_output.c
> @@ -0,0 +1,640 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2023 Loongson Technology Corporation Limited
> + */
> +
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "lsdc_drv.h"
> +#include "lsdc_output.h"
> +
> +/* This file contain shared subroutines for the output part */
> +
> +/* Usable for generic DVO, VGA and buitl-in HDMI connector */
> +
> +static int lsdc_connector_get_modes(struct drm_connector *connector)
> +{
> +   unsigned int num = 0;
> +   struct edid *edid;
> +
> +   if (connector->ddc) {
> +   edid = drm_get_edid(connector, connector->ddc);
> +   if (edid) {
> +   drm_connector_update_edid_property(connector, edid);
> +   num = drm_add_edid_modes(connector, edid);
> +   kfree(edid);
> +   }
> +
> +   return num;

drm_connector_helper_get_modes_from_ddc()

> +   }
> +
> +   num = drm_add_modes_noedid(connector, 1920, 1200);
> +
> +   drm_set_preferred_mode(connector, 1024, 768);
> +
> +   return num;
> +}
> +
> +static struct drm_encoder *
> +lsdc_connector_get_best_encoder(struct drm_connector *connector,
> +   struct drm_atomic_state *state)
> +{
> +   struct lsdc_output *output = connector_to_lsdc_output(connector);
> +
> +   return &output->encoder;

Do you really need it? Does drm_connector_get_single_encoder() work
for your case?

> +}
> +
> +const struct drm_connector_helper_funcs lsdc_connector_helper_funcs = {
> +   .atomic_best_encoder = lsdc_connector_get_best_encoder,
> +   .get_modes = lsdc_connector_get_modes,
> +};
> +
> +static enum drm_connector_status
> +lsdc_connector_detect(struct drm_connector *connector, bool force)
> +{
> +   struct i2c_adapter *ddc = connector->ddc;
> +
> +   if (ddc) {
> +   if (drm_probe_ddc(ddc))
> +   return connector_status_connected;
> +
> +   return connector_status_disconnected;
> +   }
> +
> +   return connector_status_unknown;
> +}
> +
> +const struct drm_connector_funcs lsdc_connector_funcs = {
> +   .detect = lsdc_connector_detect,
> +   .fill_modes = drm_helper_probe_single_connector_modes,
> +   .destroy = drm_connector_cleanup,
> +   .reset = drm_atomic_helper_connector_reset,
> +   .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
> +   .atomic_destroy_state = drm_atomic_helper_connector_destroy_state
> +};
> +
> +/* debugfs */
> +
> +#define LSDC_HDMI_REG(i, reg) {   \
> +   .name = __stringify_1(LSDC_HDMI##i##_##reg##_REG),\
> +   .offset = LSDC_HDMI##i##_##reg##_REG, \
> +}
> +
> +static int lsdc_hdmi_regs_show(struct seq_file *m, void *data)
> +{
> +   struct drm_inf

[PATCH v18 14/26] drm/lima: Explicitly get and put drm-shmem pages

2023-10-29 Thread Dmitry Osipenko
To simplify the drm-shmem refcnt handling, we're moving away from
the implicit get_pages() that is used by get_pages_sgt(). From now on
drivers will have to pin pages while they use sgt. Lima driver doesn't
have shrinker, hence pages are pinned and sgt is valid as long as pages'
use-count > 0.

Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/lima/lima_gem.c | 18 --
 drivers/gpu/drm/lima/lima_gem.h |  1 +
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c
index 988e74f67465..d255f5775dac 100644
--- a/drivers/gpu/drm/lima/lima_gem.c
+++ b/drivers/gpu/drm/lima/lima_gem.c
@@ -46,6 +46,7 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm)
return -ENOMEM;
}
 
+   bo->put_pages = true;
bo->base.pages = pages;
refcount_set(&bo->base.pages_use_count, 1);
 
@@ -115,6 +116,7 @@ int lima_gem_create_handle(struct drm_device *dev, struct 
drm_file *file,
return PTR_ERR(shmem);
 
obj = &shmem->base;
+   bo = to_lima_bo(obj);
 
/* Mali Utgard GPU can only support 32bit address space */
mask = mapping_gfp_mask(obj->filp->f_mapping);
@@ -123,13 +125,19 @@ int lima_gem_create_handle(struct drm_device *dev, struct 
drm_file *file,
mapping_set_gfp_mask(obj->filp->f_mapping, mask);
 
if (is_heap) {
-   bo = to_lima_bo(obj);
err = lima_heap_alloc(bo, NULL);
if (err)
goto out;
} else {
-   struct sg_table *sgt = drm_gem_shmem_get_pages_sgt(shmem);
+   struct sg_table *sgt;
+
+   err = drm_gem_shmem_get_pages(shmem);
+   if (err)
+   goto out;
+
+   bo->put_pages = true;
 
+   sgt = drm_gem_shmem_get_pages_sgt(shmem);
if (IS_ERR(sgt)) {
err = PTR_ERR(sgt);
goto out;
@@ -139,6 +147,9 @@ int lima_gem_create_handle(struct drm_device *dev, struct 
drm_file *file,
err = drm_gem_handle_create(file, obj, handle);
 
 out:
+   if (err && bo->put_pages)
+   drm_gem_shmem_put_pages(shmem);
+
/* drop reference from allocate - handle holds it now */
drm_gem_object_put(obj);
 
@@ -152,6 +163,9 @@ static void lima_gem_free_object(struct drm_gem_object *obj)
if (!list_empty(&bo->va))
dev_err(obj->dev->dev, "lima gem free bo still has va\n");
 
+   if (bo->put_pages)
+   drm_gem_shmem_put_pages(&bo->base);
+
drm_gem_shmem_free(&bo->base);
 }
 
diff --git a/drivers/gpu/drm/lima/lima_gem.h b/drivers/gpu/drm/lima/lima_gem.h
index ccea06142f4b..dc5a6d465c80 100644
--- a/drivers/gpu/drm/lima/lima_gem.h
+++ b/drivers/gpu/drm/lima/lima_gem.h
@@ -16,6 +16,7 @@ struct lima_bo {
struct list_head va;
 
size_t heap_size;
+   bool put_pages;
 };
 
 static inline struct lima_bo *
-- 
2.41.0



[PATCH v18 25/26] drm/virtio: Support shmem shrinking

2023-10-29 Thread Dmitry Osipenko
Support generic drm-shmem memory shrinker and add new madvise IOCTL to
the VirtIO-GPU driver. BO cache manager of Mesa driver will mark BOs as
"don't need" using the new IOCTL to let shrinker purge the marked BOs on
OOM, the shrinker will also evict unpurgeable shmem BOs from memory if
guest supports SWAP file or partition.

Acked-by: Gerd Hoffmann 
Signed-off-by: Daniel Almeida 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/virtio/virtgpu_drv.h| 13 +-
 drivers/gpu/drm/virtio/virtgpu_gem.c| 35 ++
 drivers/gpu/drm/virtio/virtgpu_ioctl.c  | 25 ++
 drivers/gpu/drm/virtio/virtgpu_kms.c|  8 
 drivers/gpu/drm/virtio/virtgpu_object.c | 61 +
 drivers/gpu/drm/virtio/virtgpu_vq.c | 40 
 include/uapi/drm/virtgpu_drm.h  | 14 ++
 7 files changed, 195 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h 
b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 421f524ae1de..33a78b24c272 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -278,7 +278,7 @@ struct virtio_gpu_fpriv {
 };
 
 /* virtgpu_ioctl.c */
-#define DRM_VIRTIO_NUM_IOCTLS 12
+#define DRM_VIRTIO_NUM_IOCTLS 13
 extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS];
 void virtio_gpu_create_context(struct drm_device *dev, struct drm_file *file);
 
@@ -316,6 +316,8 @@ void virtio_gpu_array_put_free_delayed(struct 
virtio_gpu_device *vgdev,
 void virtio_gpu_array_put_free_work(struct work_struct *work);
 int virtio_gpu_array_prepare(struct virtio_gpu_device *vgdev,
 struct virtio_gpu_object_array *objs);
+int virtio_gpu_gem_host_mem_release(struct virtio_gpu_object *bo);
+int virtio_gpu_gem_madvise(struct virtio_gpu_object *obj, int madv);
 int virtio_gpu_gem_pin(struct virtio_gpu_object *bo);
 void virtio_gpu_gem_unpin(struct virtio_gpu_object *bo);
 
@@ -329,6 +331,8 @@ void virtio_gpu_cmd_create_resource(struct 
virtio_gpu_device *vgdev,
struct virtio_gpu_fence *fence);
 void virtio_gpu_cmd_unref_resource(struct virtio_gpu_device *vgdev,
   struct virtio_gpu_object *bo);
+int virtio_gpu_cmd_release_resource(struct virtio_gpu_device *vgdev,
+   struct virtio_gpu_object *bo);
 void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev,
uint64_t offset,
uint32_t width, uint32_t height,
@@ -349,6 +353,9 @@ void virtio_gpu_object_attach(struct virtio_gpu_device 
*vgdev,
  struct virtio_gpu_object *obj,
  struct virtio_gpu_mem_entry *ents,
  unsigned int nents);
+void virtio_gpu_object_detach(struct virtio_gpu_device *vgdev,
+ struct virtio_gpu_object *obj,
+ struct virtio_gpu_fence *fence);
 void virtio_gpu_cursor_ping(struct virtio_gpu_device *vgdev,
struct virtio_gpu_output *output);
 int virtio_gpu_cmd_get_display_info(struct virtio_gpu_device *vgdev);
@@ -492,4 +499,8 @@ void virtio_gpu_vram_unmap_dma_buf(struct device *dev,
 int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data,
struct drm_file *file);
 
+/* virtgpu_gem_shrinker.c */
+int virtio_gpu_gem_shrinker_init(struct virtio_gpu_device *vgdev);
+void virtio_gpu_gem_shrinker_fini(struct virtio_gpu_device *vgdev);
+
 #endif
diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c 
b/drivers/gpu/drm/virtio/virtgpu_gem.c
index 97e67064c97e..748f7bbb0e6d 100644
--- a/drivers/gpu/drm/virtio/virtgpu_gem.c
+++ b/drivers/gpu/drm/virtio/virtgpu_gem.c
@@ -147,10 +147,20 @@ void virtio_gpu_gem_object_close(struct drm_gem_object 
*obj,
struct virtio_gpu_device *vgdev = obj->dev->dev_private;
struct virtio_gpu_fpriv *vfpriv = file->driver_priv;
struct virtio_gpu_object_array *objs;
+   struct virtio_gpu_object *bo;
 
if (!vgdev->has_virgl_3d)
return;
 
+   bo = gem_to_virtio_gpu_obj(obj);
+
+   /*
+* Purged BO was already detached and released, the resource ID
+* is invalid by now.
+*/
+   if (!virtio_gpu_gem_madvise(bo, VIRTGPU_MADV_WILLNEED))
+   return;
+
objs = virtio_gpu_array_alloc(1);
if (!objs)
return;
@@ -315,6 +325,31 @@ int virtio_gpu_array_prepare(struct virtio_gpu_device 
*vgdev,
return ret;
 }
 
+int virtio_gpu_gem_madvise(struct virtio_gpu_object *bo, int madv)
+{
+   if (virtio_gpu_is_shmem(bo))
+   return drm_gem_shmem_object_madvise(&bo->base.base, madv);
+
+   return 1;
+}
+
+int virtio_gpu_gem_host_mem_release(struct virtio_gpu_object *bo)
+{
+   struct virtio_gpu_device *vgdev = bo->base.base.dev->dev_private;
+   int err;
+
+   if

[PATCH v18 08/26] drm/shmem-helper: Add and use lockless drm_gem_shmem_get_pages()

2023-10-29 Thread Dmitry Osipenko
Add lockless drm_gem_shmem_get_pages() helper that skips taking reservation
lock if pages_use_count is non-zero, leveraging from atomicity of the
refcount_t. Make drm_gem_shmem_mmap() to utilize the new helper.

Reviewed-by: Boris Brezillon 
Suggested-by: Boris Brezillon 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 19 +++
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 6e02643ed87e..41b749bedb11 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -226,6 +226,20 @@ void drm_gem_shmem_put_pages_locked(struct 
drm_gem_shmem_object *shmem)
 }
 EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages_locked);
 
+static int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem)
+{
+   int ret;
+
+   if (refcount_inc_not_zero(&shmem->pages_use_count))
+   return 0;
+
+   dma_resv_lock(shmem->base.resv, NULL);
+   ret = drm_gem_shmem_get_pages_locked(shmem);
+   dma_resv_unlock(shmem->base.resv);
+
+   return ret;
+}
+
 static int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem)
 {
int ret;
@@ -609,10 +623,7 @@ int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, 
struct vm_area_struct
return ret;
}
 
-   dma_resv_lock(shmem->base.resv, NULL);
-   ret = drm_gem_shmem_get_pages_locked(shmem);
-   dma_resv_unlock(shmem->base.resv);
-
+   ret = drm_gem_shmem_get_pages(shmem);
if (ret)
return ret;
 
-- 
2.41.0



[PATCH v18 19/26] drm/shmem-helper: Add common memory shrinker

2023-10-29 Thread Dmitry Osipenko
Introduce common drm-shmem shrinker for DRM drivers.

To start using drm-shmem shrinker drivers should do the following:

1. Implement evict() callback of GEM object where driver should check
   whether object is purgeable or evictable using drm-shmem helpers and
   perform the shrinking action

2. Initialize drm-shmem internals using drmm_gem_shmem_init(drm_device),
   which will register drm-shmem shrinker

3. Implement madvise IOCTL that will use drm_gem_shmem_madvise()

Signed-off-by: Daniel Almeida 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c| 386 +-
 .../gpu/drm/panfrost/panfrost_gem_shrinker.c  |   9 +-
 include/drm/drm_device.h  |  10 +-
 include/drm/drm_gem_shmem_helper.h|  68 ++-
 4 files changed, 450 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 1420d2166b76..007521bea302 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -88,8 +89,6 @@ __drm_gem_shmem_create(struct drm_device *dev, size_t size, 
bool private)
if (ret)
goto err_release;
 
-   INIT_LIST_HEAD(&shmem->madv_list);
-
if (!private) {
/*
 * Our buffers are kept pinned, so allocating them
@@ -128,11 +127,49 @@ struct drm_gem_shmem_object *drm_gem_shmem_create(struct 
drm_device *dev, size_t
 }
 EXPORT_SYMBOL_GPL(drm_gem_shmem_create);
 
+static bool drm_gem_shmem_is_evictable(struct drm_gem_shmem_object *shmem)
+{
+   return (shmem->madv >= 0) && shmem->base.funcs->evict &&
+   refcount_read(&shmem->pages_use_count) &&
+   !refcount_read(&shmem->pages_pin_count) &&
+   !shmem->base.dma_buf && !shmem->base.import_attach &&
+   !shmem->evicted;
+}
+
+static void
+drm_gem_shmem_shrinker_update_lru_locked(struct drm_gem_shmem_object *shmem)
+{
+   struct drm_gem_object *obj = &shmem->base;
+   struct drm_gem_shmem *shmem_mm = obj->dev->shmem_mm;
+   struct drm_gem_shmem_shrinker *shmem_shrinker = &shmem_mm->shrinker;
+
+   dma_resv_assert_held(shmem->base.resv);
+
+   if (!shmem_shrinker || obj->import_attach)
+   return;
+
+   if (shmem->madv < 0)
+   drm_gem_lru_remove(&shmem->base);
+   else if (drm_gem_shmem_is_evictable(shmem) || 
drm_gem_shmem_is_purgeable(shmem))
+   drm_gem_lru_move_tail(&shmem_shrinker->lru_evictable, 
&shmem->base);
+   else if (shmem->evicted)
+   drm_gem_lru_move_tail(&shmem_shrinker->lru_evicted, 
&shmem->base);
+   else if (!shmem->pages)
+   drm_gem_lru_remove(&shmem->base);
+   else
+   drm_gem_lru_move_tail(&shmem_shrinker->lru_pinned, 
&shmem->base);
+}
+
 static void
 drm_gem_shmem_free_pages(struct drm_gem_shmem_object *shmem)
 {
struct drm_gem_object *obj = &shmem->base;
 
+   if (!shmem->pages) {
+   drm_WARN_ON(obj->dev, !shmem->evicted && shmem->madv >= 0);
+   return;
+   }
+
if (shmem->sgt) {
dma_unmap_sgtable(obj->dev->dev, shmem->sgt,
  DMA_BIDIRECTIONAL, 0);
@@ -175,15 +212,25 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object 
*shmem)
 }
 EXPORT_SYMBOL_GPL(drm_gem_shmem_free);
 
-static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem)
+static int
+drm_gem_shmem_acquire_pages(struct drm_gem_shmem_object *shmem)
 {
struct drm_gem_object *obj = &shmem->base;
struct page **pages;
 
+   drm_WARN_ON(obj->dev, obj->import_attach);
+
dma_resv_assert_held(shmem->base.resv);
 
-   if (refcount_inc_not_zero(&shmem->pages_use_count))
+   if (shmem->madv < 0) {
+   drm_WARN_ON(obj->dev, shmem->pages);
+   return -ENOMEM;
+   }
+
+   if (shmem->pages) {
+   drm_WARN_ON(obj->dev, !shmem->evicted);
return 0;
+   }
 
pages = drm_gem_get_pages(obj);
if (IS_ERR(pages)) {
@@ -204,8 +251,29 @@ static int drm_gem_shmem_get_pages_locked(struct 
drm_gem_shmem_object *shmem)
 
shmem->pages = pages;
 
+   return 0;
+}
+
+static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem)
+{
+   int err;
+
+   dma_resv_assert_held(shmem->base.resv);
+
+   if (shmem->madv < 0)
+   return -ENOMEM;
+
+   if (refcount_inc_not_zero(&shmem->pages_use_count))
+   return 0;
+
+   err = drm_gem_shmem_acquire_pages(shmem);
+   if (err)
+   return err;
+
refcount_set(&shmem->pages_use_count, 1);
 
+   drm_gem_shmem_shrinker_update_lru_locked(shmem);
+
return 0;
 }
 
@@ -222,6 +290,8 @@ void drm_gem_shmem_put_pages_locked(struct 
drm_gem_shmem_object *shmem)
 

[PATCH v18 13/26] drm/shmem-helper: Add drm_gem_shmem_put_pages()

2023-10-29 Thread Dmitry Osipenko
We're going to move away from having implicit get_pages() done by
get_pages_sgt() to ease simplify refcnt handling. Drivers will manage
get/put_pages() by themselves. Add drm_gem_shmem_put_pages().

Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 20 
 include/drm/drm_gem_shmem_helper.h |  1 +
 2 files changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index ca6f422c0dfc..f371ebc6f85c 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -217,6 +217,7 @@ static int drm_gem_shmem_get_pages_locked(struct 
drm_gem_shmem_object *shmem)
  * @shmem: shmem GEM object
  *
  * This function decreases the use count and puts the backing pages when use 
drops to zero.
+ * Caller must hold GEM's reservation lock.
  */
 void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem)
 {
@@ -227,6 +228,25 @@ void drm_gem_shmem_put_pages_locked(struct 
drm_gem_shmem_object *shmem)
 }
 EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages_locked);
 
+/*
+ * drm_gem_shmem_put_pages - Decrease use count on the backing pages for a 
shmem GEM object
+ * @shmem: shmem GEM object
+ *
+ * This function decreases the use count and puts the backing pages when use 
drops to zero.
+ * It's unlocked version of drm_gem_shmem_put_pages_locked(), caller must not 
hold
+ * GEM's reservation lock.
+ */
+void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem)
+{
+   if (refcount_dec_not_one(&shmem->pages_use_count))
+   return;
+
+   dma_resv_lock(shmem->base.resv, NULL);
+   drm_gem_shmem_put_pages_locked(shmem);
+   dma_resv_unlock(shmem->base.resv);
+}
+EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages);
+
 /*
  * drm_gem_shmem_get_pages - Increase use count on the backing pages for a 
shmem GEM object
  * @shmem: shmem GEM object
diff --git a/include/drm/drm_gem_shmem_helper.h 
b/include/drm/drm_gem_shmem_helper.h
index 45cd293e10a4..6aad3e27d7ee 100644
--- a/include/drm/drm_gem_shmem_helper.h
+++ b/include/drm/drm_gem_shmem_helper.h
@@ -111,6 +111,7 @@ struct drm_gem_shmem_object *drm_gem_shmem_create(struct 
drm_device *dev, size_t
 void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem);
 
 int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem);
+void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem);
 void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem);
 int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem);
 void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem);
-- 
2.41.0



[PATCH v18 12/26] drm/shmem-helper: Make drm_gem_shmem_get_pages() public

2023-10-29 Thread Dmitry Osipenko
We're going to move away from having implicit get_pages() done by
get_pages_sgt() to ease simplify refcnt handling. Drivers will manage
get/put_pages() by themselves. Expose the drm_gem_shmem_get_pages()
in a public drm-shmem API.

Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 10 +-
 include/drm/drm_gem_shmem_helper.h |  1 +
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 24ff2b99e75b..ca6f422c0dfc 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -227,7 +227,14 @@ void drm_gem_shmem_put_pages_locked(struct 
drm_gem_shmem_object *shmem)
 }
 EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages_locked);
 
-static int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem)
+/*
+ * drm_gem_shmem_get_pages - Increase use count on the backing pages for a 
shmem GEM object
+ * @shmem: shmem GEM object
+ *
+ * This function Increases the use count and allocates the backing pages if
+ * use-count equals to zero.
+ */
+int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem)
 {
int ret;
 
@@ -240,6 +247,7 @@ static int drm_gem_shmem_get_pages(struct 
drm_gem_shmem_object *shmem)
 
return ret;
 }
+EXPORT_SYMBOL_GPL(drm_gem_shmem_get_pages);
 
 static int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem)
 {
diff --git a/include/drm/drm_gem_shmem_helper.h 
b/include/drm/drm_gem_shmem_helper.h
index e7b3f4c02bf5..45cd293e10a4 100644
--- a/include/drm/drm_gem_shmem_helper.h
+++ b/include/drm/drm_gem_shmem_helper.h
@@ -110,6 +110,7 @@ struct drm_gem_shmem_object {
 struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, 
size_t size);
 void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem);
 
+int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem);
 void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem);
 int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem);
 void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem);
-- 
2.41.0



[PATCH v18 18/26] drm/shmem-helper: Change sgt allocation policy

2023-10-29 Thread Dmitry Osipenko
In a preparation to addition of drm-shmem memory shrinker support, change
the SGT allocation policy in this way:

1. SGT can be allocated only if shmem pages are pinned at the
time of allocation, otherwise allocation fails.

2. Drivers must ensure that pages are pinned during the time of SGT usage
and should get new SGT if pages were unpinned.

This new policy is required by the shrinker because it will move pages
to/from SWAP unless pages are pinned, invalidating SGT pointer once pages
are relocated.

Previous patches prepared drivers to the new policy.

Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 51 +-
 1 file changed, 26 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index f371ebc6f85c..1420d2166b76 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -133,6 +133,14 @@ drm_gem_shmem_free_pages(struct drm_gem_shmem_object 
*shmem)
 {
struct drm_gem_object *obj = &shmem->base;
 
+   if (shmem->sgt) {
+   dma_unmap_sgtable(obj->dev->dev, shmem->sgt,
+ DMA_BIDIRECTIONAL, 0);
+   sg_free_table(shmem->sgt);
+   kfree(shmem->sgt);
+   shmem->sgt = NULL;
+   }
+
 #ifdef CONFIG_X86
if (shmem->map_wc)
set_pages_array_wb(shmem->pages, obj->size >> PAGE_SHIFT);
@@ -155,23 +163,12 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object 
*shmem)
 {
struct drm_gem_object *obj = &shmem->base;
 
-   if (obj->import_attach) {
+   if (obj->import_attach)
drm_prime_gem_destroy(obj, shmem->sgt);
-   } else {
-   drm_WARN_ON(obj->dev, refcount_read(&shmem->vmap_use_count));
-
-   if (shmem->sgt) {
-   dma_unmap_sgtable(obj->dev->dev, shmem->sgt,
- DMA_BIDIRECTIONAL, 0);
-   sg_free_table(shmem->sgt);
-   kfree(shmem->sgt);
-   }
-   if (shmem->pages)
-   drm_gem_shmem_put_pages_locked(shmem);
 
-   drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_use_count));
-   drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_pin_count));
-   }
+   drm_WARN_ON(obj->dev, refcount_read(&shmem->vmap_use_count));
+   drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_use_count));
+   drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_pin_count));
 
drm_gem_object_release(obj);
kfree(shmem);
@@ -705,6 +702,9 @@ struct sg_table *drm_gem_shmem_get_sg_table(struct 
drm_gem_shmem_object *shmem)
 
drm_WARN_ON(obj->dev, obj->import_attach);
 
+   if (drm_WARN_ON(obj->dev, !shmem->pages))
+   return ERR_PTR(-ENOMEM);
+
return drm_prime_pages_to_sg(obj->dev, shmem->pages, obj->size >> 
PAGE_SHIFT);
 }
 EXPORT_SYMBOL_GPL(drm_gem_shmem_get_sg_table);
@@ -720,15 +720,10 @@ static struct sg_table 
*drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_
 
drm_WARN_ON(obj->dev, obj->import_attach);
 
-   ret = drm_gem_shmem_get_pages_locked(shmem);
-   if (ret)
-   return ERR_PTR(ret);
-
sgt = drm_gem_shmem_get_sg_table(shmem);
-   if (IS_ERR(sgt)) {
-   ret = PTR_ERR(sgt);
-   goto err_put_pages;
-   }
+   if (IS_ERR(sgt))
+   return sgt;
+
/* Map the pages for use by the h/w. */
ret = dma_map_sgtable(obj->dev->dev, sgt, DMA_BIDIRECTIONAL, 0);
if (ret)
@@ -741,8 +736,6 @@ static struct sg_table 
*drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_
 err_free_sgt:
sg_free_table(sgt);
kfree(sgt);
-err_put_pages:
-   drm_gem_shmem_put_pages_locked(shmem);
return ERR_PTR(ret);
 }
 
@@ -759,6 +752,14 @@ static struct sg_table 
*drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_
  * and difference between dma-buf imported and natively allocated objects.
  * drm_gem_shmem_get_sg_table() should not be directly called by drivers.
  *
+ * Drivers should adhere to these SGT usage rules:
+ *
+ * 1. SGT should be allocated only if shmem pages are pinned at the
+ *time of allocation, otherwise allocation will fail.
+ *
+ * 2. Drivers should ensure that pages are pinned during the time of
+ *SGT usage and should get new SGT if pages were unpinned.
+ *
  * Returns:
  * A pointer to the scatter/gather table of pinned pages or errno on failure.
  */
-- 
2.41.0



[PATCH v18 26/26] drm/panfrost: Switch to generic memory shrinker

2023-10-29 Thread Dmitry Osipenko
Replace Panfrost's custom memory shrinker with a common drm-shmem
memory shrinker.

Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/panfrost/Makefile |   1 -
 drivers/gpu/drm/panfrost/panfrost_device.h|   4 -
 drivers/gpu/drm/panfrost/panfrost_drv.c   |  27 ++--
 drivers/gpu/drm/panfrost/panfrost_gem.c   |  34 +++--
 drivers/gpu/drm/panfrost/panfrost_gem.h   |   9 --
 .../gpu/drm/panfrost/panfrost_gem_shrinker.c  | 129 --
 drivers/gpu/drm/panfrost/panfrost_job.c   |  18 ++-
 drivers/gpu/drm/panfrost/panfrost_mmu.c   |  18 ++-
 include/drm/drm_gem_shmem_helper.h|   7 -
 9 files changed, 66 insertions(+), 181 deletions(-)
 delete mode 100644 drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c

diff --git a/drivers/gpu/drm/panfrost/Makefile 
b/drivers/gpu/drm/panfrost/Makefile
index 2c01c1e7523e..f2cb1ab0a32d 100644
--- a/drivers/gpu/drm/panfrost/Makefile
+++ b/drivers/gpu/drm/panfrost/Makefile
@@ -5,7 +5,6 @@ panfrost-y := \
panfrost_device.o \
panfrost_devfreq.o \
panfrost_gem.o \
-   panfrost_gem_shrinker.o \
panfrost_gpu.o \
panfrost_job.o \
panfrost_mmu.o \
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h 
b/drivers/gpu/drm/panfrost/panfrost_device.h
index 1e85656dc2f7..2b24a0d4f85e 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.h
+++ b/drivers/gpu/drm/panfrost/panfrost_device.h
@@ -117,10 +117,6 @@ struct panfrost_device {
atomic_t pending;
} reset;
 
-   struct mutex shrinker_lock;
-   struct list_head shrinker_list;
-   struct shrinker shrinker;
-
struct panfrost_devfreq pfdevfreq;
 
struct {
diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c 
b/drivers/gpu/drm/panfrost/panfrost_drv.c
index 7f2aba96d5b9..ef520d2cc1d2 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -171,7 +171,6 @@ panfrost_lookup_bos(struct drm_device *dev,
break;
}
 
-   atomic_inc(&bo->gpu_usecount);
job->mappings[i] = mapping;
}
 
@@ -397,7 +396,6 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, 
void *data,
 {
struct panfrost_file_priv *priv = file_priv->driver_priv;
struct drm_panfrost_madvise *args = data;
-   struct panfrost_device *pfdev = dev->dev_private;
struct drm_gem_object *gem_obj;
struct panfrost_gem_object *bo;
int ret = 0;
@@ -410,11 +408,15 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, 
void *data,
 
bo = to_panfrost_bo(gem_obj);
 
+   if (bo->is_heap) {
+   args->retained = 1;
+   goto out_put_object;
+   }
+
ret = dma_resv_lock_interruptible(bo->base.base.resv, NULL);
if (ret)
goto out_put_object;
 
-   mutex_lock(&pfdev->shrinker_lock);
mutex_lock(&bo->mappings.lock);
if (args->madv == PANFROST_MADV_DONTNEED) {
struct panfrost_gem_mapping *first;
@@ -440,17 +442,8 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, 
void *data,
 
args->retained = drm_gem_shmem_madvise_locked(&bo->base, args->madv);
 
-   if (args->retained) {
-   if (args->madv == PANFROST_MADV_DONTNEED)
-   list_move_tail(&bo->base.madv_list,
-  &pfdev->shrinker_list);
-   else if (args->madv == PANFROST_MADV_WILLNEED)
-   list_del_init(&bo->base.madv_list);
-   }
-
 out_unlock_mappings:
mutex_unlock(&bo->mappings.lock);
-   mutex_unlock(&pfdev->shrinker_lock);
dma_resv_unlock(bo->base.base.resv);
 out_put_object:
drm_gem_object_put(gem_obj);
@@ -635,9 +628,6 @@ static int panfrost_probe(struct platform_device *pdev)
ddev->dev_private = pfdev;
pfdev->ddev = ddev;
 
-   mutex_init(&pfdev->shrinker_lock);
-   INIT_LIST_HEAD(&pfdev->shrinker_list);
-
err = panfrost_device_init(pfdev);
if (err) {
if (err != -EPROBE_DEFER)
@@ -659,10 +649,14 @@ static int panfrost_probe(struct platform_device *pdev)
if (err < 0)
goto err_out1;
 
-   panfrost_gem_shrinker_init(ddev);
+   err = drmm_gem_shmem_init(ddev);
+   if (err < 0)
+   goto err_out2;
 
return 0;
 
+err_out2:
+   drm_dev_unregister(ddev);
 err_out1:
pm_runtime_disable(pfdev->dev);
panfrost_device_fini(pfdev);
@@ -678,7 +672,6 @@ static void panfrost_remove(struct platform_device *pdev)
struct drm_device *ddev = pfdev->ddev;
 
drm_dev_unregister(ddev);
-   panfrost_gem_shrinker_cleanup(ddev);
 
pm_runtime_get_sync(pfdev->dev);
pm_runtime_disable(pfdev->dev);
diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c 
b/drivers/gpu/drm/panfrost/panfrost_gem.c
index bb9d43cf7c3c..a6128e32f303 100644
--- a/

[PATCH AUTOSEL 4.14 09/11] fbdev: core: syscopyarea: fix sloppy typing

2023-10-29 Thread Sasha Levin
From: Sergey Shtylyov 

[ Upstream commit e8e4a470b677511f9d1ad4f3cef32adc1d9a60ca ]

In sys_copyarea(), the local variable bits_per_line is needlessly typed as
*unsigned long* -- which is a 32-bit type on the 32-bit arches and a 64-bit
type on the 64-bit arches; that variable's value is derived from the __u32
typed fb_fix_screeninfo::line_length field (multiplied by 8u) and a 32-bit
*unsigned int* type should still be enough to store the # of bits per line.

Found by Linux Verification Center (linuxtesting.org) with the Svace static
analysis tool.

Signed-off-by: Sergey Shtylyov 
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/core/syscopyarea.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/core/syscopyarea.c 
b/drivers/video/fbdev/core/syscopyarea.c
index c1eda31909682..7b8bd3a2bedc5 100644
--- a/drivers/video/fbdev/core/syscopyarea.c
+++ b/drivers/video/fbdev/core/syscopyarea.c
@@ -316,7 +316,7 @@ void sys_copyarea(struct fb_info *p, const struct 
fb_copyarea *area)
 {
u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
u32 height = area->height, width = area->width;
-   unsigned long const bits_per_line = p->fix.line_length*8u;
+   unsigned int const bits_per_line = p->fix.line_length * 8u;
unsigned long *base = NULL;
int bits = BITS_PER_LONG, bytes = bits >> 3;
unsigned dst_idx = 0, src_idx = 0, rev_copy = 0;
-- 
2.42.0



[PATCH v18 06/26] drm/shmem-helper: Add and use pages_pin_count

2023-10-29 Thread Dmitry Osipenko
Add separate pages_pin_count for tracking of whether drm-shmem pages are
moveable or not. With the addition of memory shrinker support to drm-shmem,
the pages_use_count will no longer determine whether pages are hard-pinned
in memory, but whether pages exist and are soft-pinned (and could be swapped
out). The pages_pin_count > 1 will hard-pin pages in memory.

Reviewed-by: Boris Brezillon 
Suggested-by: Boris Brezillon 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 25 +
 include/drm/drm_gem_shmem_helper.h | 11 +++
 2 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 2cc0601865f6..b9b71a1a563a 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -156,6 +156,7 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem)
drm_gem_shmem_put_pages_locked(shmem);
 
drm_WARN_ON(obj->dev, shmem->pages_use_count);
+   drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_pin_count));
 
dma_resv_unlock(shmem->base.resv);
}
@@ -234,18 +235,16 @@ static int drm_gem_shmem_pin_locked(struct 
drm_gem_shmem_object *shmem)
 
dma_resv_assert_held(shmem->base.resv);
 
+   if (refcount_inc_not_zero(&shmem->pages_pin_count))
+   return 0;
+
ret = drm_gem_shmem_get_pages_locked(shmem);
+   if (!ret)
+   refcount_set(&shmem->pages_pin_count, 1);
 
return ret;
 }
 
-static void drm_gem_shmem_unpin_locked(struct drm_gem_shmem_object *shmem)
-{
-   dma_resv_assert_held(shmem->base.resv);
-
-   drm_gem_shmem_put_pages_locked(shmem);
-}
-
 /**
  * drm_gem_shmem_pin - Pin backing pages for a shmem GEM object
  * @shmem: shmem GEM object
@@ -263,6 +262,9 @@ int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem)
 
drm_WARN_ON(obj->dev, obj->import_attach);
 
+   if (refcount_inc_not_zero(&shmem->pages_pin_count))
+   return 0;
+
ret = dma_resv_lock_interruptible(shmem->base.resv, NULL);
if (ret)
return ret;
@@ -286,8 +288,14 @@ void drm_gem_shmem_unpin(struct drm_gem_shmem_object 
*shmem)
 
drm_WARN_ON(obj->dev, obj->import_attach);
 
+   if (refcount_dec_not_one(&shmem->pages_pin_count))
+   return;
+
dma_resv_lock(shmem->base.resv, NULL);
-   drm_gem_shmem_unpin_locked(shmem);
+
+   if (refcount_dec_and_test(&shmem->pages_pin_count))
+   drm_gem_shmem_put_pages_locked(shmem);
+
dma_resv_unlock(shmem->base.resv);
 }
 EXPORT_SYMBOL_GPL(drm_gem_shmem_unpin);
@@ -632,6 +640,7 @@ void drm_gem_shmem_print_info(const struct 
drm_gem_shmem_object *shmem,
if (shmem->base.import_attach)
return;
 
+   drm_printf_indent(p, indent, "pages_pin_count=%u\n", 
refcount_read(&shmem->pages_pin_count));
drm_printf_indent(p, indent, "pages_use_count=%u\n", 
shmem->pages_use_count);
drm_printf_indent(p, indent, "vmap_use_count=%u\n", 
shmem->vmap_use_count);
drm_printf_indent(p, indent, "vaddr=%p\n", shmem->vaddr);
diff --git a/include/drm/drm_gem_shmem_helper.h 
b/include/drm/drm_gem_shmem_helper.h
index 6ee4a4046980..5088bd623518 100644
--- a/include/drm/drm_gem_shmem_helper.h
+++ b/include/drm/drm_gem_shmem_helper.h
@@ -39,6 +39,17 @@ struct drm_gem_shmem_object {
 */
unsigned int pages_use_count;
 
+   /**
+* @pages_pin_count:
+*
+* Reference count on the pinned pages table.
+*
+* Pages are hard-pinned and reside in memory if count
+* greater than zero. Otherwise, when count is zero, the pages are
+* allowed to be evicted and purged by memory shrinker.
+*/
+   refcount_t pages_pin_count;
+
/**
 * @madv: State for madvise
 *
-- 
2.41.0



[PATCH v18 22/26] drm/shmem-helper: Don't free refcounted GEM

2023-10-29 Thread Dmitry Osipenko
Don't free refcounted shmem object to prevent use-after-free bug that
is worse than a memory leak.

Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 6dd087f19ea3..4253c367dc07 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -203,9 +203,10 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem)
if (obj->import_attach)
drm_prime_gem_destroy(obj, shmem->sgt);
 
-   drm_WARN_ON(obj->dev, refcount_read(&shmem->vmap_use_count));
-   drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_use_count));
-   drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_pin_count));
+   if (drm_WARN_ON(obj->dev, refcount_read(&shmem->vmap_use_count)) ||
+   drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_use_count)) ||
+   drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_pin_count)))
+   return;
 
drm_gem_object_release(obj);
kfree(shmem);
-- 
2.41.0



[PATCH v18 24/26] drm/virtio: Attach shmem BOs dynamically

2023-10-29 Thread Dmitry Osipenko
Prepare for addition of memory shrinker support by attaching shmem pages
to host dynamically on first use. Previously the attachment vq command
wasn't fenced and there was no vq kick made in the BO creation code path,
hence the attachment already was happening dynamically, but implicitly.
Making attachment explicitly dynamic will allow to simplify and reuse more
code when shrinker will be added. The virtio_gpu_object_shmem_init() now
works under the held reservation lock, which will be important to have for
shrinker to avoid moving pages while they are in active use by the driver.

Acked-by: Gerd Hoffmann 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/virtio/virtgpu_drv.h|  7 +++
 drivers/gpu/drm/virtio/virtgpu_gem.c| 26 +
 drivers/gpu/drm/virtio/virtgpu_ioctl.c  | 32 +++
 drivers/gpu/drm/virtio/virtgpu_object.c | 73 -
 drivers/gpu/drm/virtio/virtgpu_submit.c | 15 -
 5 files changed, 125 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h 
b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 56269814fb6d..421f524ae1de 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -89,6 +89,7 @@ struct virtio_gpu_object {
uint32_t hw_res_handle;
bool dumb;
bool created;
+   bool detached;
bool host3d_blob, guest_blob;
uint32_t blob_mem, blob_flags;
 
@@ -313,6 +314,8 @@ void virtio_gpu_array_put_free(struct 
virtio_gpu_object_array *objs);
 void virtio_gpu_array_put_free_delayed(struct virtio_gpu_device *vgdev,
   struct virtio_gpu_object_array *objs);
 void virtio_gpu_array_put_free_work(struct work_struct *work);
+int virtio_gpu_array_prepare(struct virtio_gpu_device *vgdev,
+struct virtio_gpu_object_array *objs);
 int virtio_gpu_gem_pin(struct virtio_gpu_object *bo);
 void virtio_gpu_gem_unpin(struct virtio_gpu_object *bo);
 
@@ -453,6 +456,10 @@ int virtio_gpu_object_create(struct virtio_gpu_device 
*vgdev,
 
 bool virtio_gpu_is_shmem(struct virtio_gpu_object *bo);
 
+int virtio_gpu_reattach_shmem_object_locked(struct virtio_gpu_object *bo);
+
+int virtio_gpu_reattach_shmem_object(struct virtio_gpu_object *bo);
+
 int virtio_gpu_resource_id_get(struct virtio_gpu_device *vgdev,
   uint32_t *resid);
 /* virtgpu_prime.c */
diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c 
b/drivers/gpu/drm/virtio/virtgpu_gem.c
index 625c05d625bf..97e67064c97e 100644
--- a/drivers/gpu/drm/virtio/virtgpu_gem.c
+++ b/drivers/gpu/drm/virtio/virtgpu_gem.c
@@ -295,6 +295,26 @@ void virtio_gpu_array_put_free_work(struct work_struct 
*work)
spin_unlock(&vgdev->obj_free_lock);
 }
 
+int virtio_gpu_array_prepare(struct virtio_gpu_device *vgdev,
+struct virtio_gpu_object_array *objs)
+{
+   struct virtio_gpu_object *bo;
+   int ret = 0;
+   u32 i;
+
+   for (i = 0; i < objs->nents; i++) {
+   bo = gem_to_virtio_gpu_obj(objs->objs[i]);
+
+   if (virtio_gpu_is_shmem(bo) && bo->detached) {
+   ret = virtio_gpu_reattach_shmem_object_locked(bo);
+   if (ret)
+   break;
+   }
+   }
+
+   return ret;
+}
+
 int virtio_gpu_gem_pin(struct virtio_gpu_object *bo)
 {
int err;
@@ -303,6 +323,12 @@ int virtio_gpu_gem_pin(struct virtio_gpu_object *bo)
err = drm_gem_shmem_pin(&bo->base);
if (err)
return err;
+
+   err = virtio_gpu_reattach_shmem_object(bo);
+   if (err) {
+   drm_gem_shmem_unpin(&bo->base);
+   return err;
+   }
}
 
return 0;
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c 
b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index b24b11f25197..070c29cea26a 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -246,6 +246,10 @@ static int virtio_gpu_transfer_from_host_ioctl(struct 
drm_device *dev,
if (ret != 0)
goto err_put_free;
 
+   ret = virtio_gpu_array_prepare(vgdev, objs);
+   if (ret)
+   goto err_unlock;
+
fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context, 0);
if (!fence) {
ret = -ENOMEM;
@@ -288,11 +292,25 @@ static int virtio_gpu_transfer_to_host_ioctl(struct 
drm_device *dev, void *data,
goto err_put_free;
}
 
+   ret = virtio_gpu_array_lock_resv(objs);
+   if (ret != 0)
+   goto err_put_free;
+
+   ret = virtio_gpu_array_prepare(vgdev, objs);
+   if (ret)
+   goto err_unlock;
+
+   fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context, 0);
+   if (!fence) {
+   ret = -ENOMEM;
+   goto err_unlock;
+   }
+
if (!vgdev->has

[PATCH v18 11/26] drm/shmem-helper: Prepare drm_gem_shmem_free() to shrinker addition

2023-10-29 Thread Dmitry Osipenko
Prepare drm_gem_shmem_free() to addition of memory shrinker support
to drm-shmem by adding and using variant of put_pages() that doesn't
touch reservation lock. Reservation shouldn't be touched because lockdep
will trigger a bogus warning about locking contention with fs_reclaim
code paths that can't happen during the time when GEM is freed and
lockdep doesn't know about that.

Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 35 +-
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 08b5a57c59d8..24ff2b99e75b 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -128,6 +128,22 @@ struct drm_gem_shmem_object *drm_gem_shmem_create(struct 
drm_device *dev, size_t
 }
 EXPORT_SYMBOL_GPL(drm_gem_shmem_create);
 
+static void
+drm_gem_shmem_free_pages(struct drm_gem_shmem_object *shmem)
+{
+   struct drm_gem_object *obj = &shmem->base;
+
+#ifdef CONFIG_X86
+   if (shmem->map_wc)
+   set_pages_array_wb(shmem->pages, obj->size >> PAGE_SHIFT);
+#endif
+
+   drm_gem_put_pages(obj, shmem->pages,
+ shmem->pages_mark_dirty_on_put,
+ shmem->pages_mark_accessed_on_put);
+   shmem->pages = NULL;
+}
+
 /**
  * drm_gem_shmem_free - Free resources associated with a shmem GEM object
  * @shmem: shmem GEM object to free
@@ -142,8 +158,6 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem)
if (obj->import_attach) {
drm_prime_gem_destroy(obj, shmem->sgt);
} else {
-   dma_resv_lock(shmem->base.resv, NULL);
-
drm_WARN_ON(obj->dev, refcount_read(&shmem->vmap_use_count));
 
if (shmem->sgt) {
@@ -157,8 +171,6 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem)
 
drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_use_count));
drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_pin_count));
-
-   dma_resv_unlock(shmem->base.resv);
}
 
drm_gem_object_release(obj);
@@ -208,21 +220,10 @@ static int drm_gem_shmem_get_pages_locked(struct 
drm_gem_shmem_object *shmem)
  */
 void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem)
 {
-   struct drm_gem_object *obj = &shmem->base;
-
dma_resv_assert_held(shmem->base.resv);
 
-   if (refcount_dec_and_test(&shmem->pages_use_count)) {
-#ifdef CONFIG_X86
-   if (shmem->map_wc)
-   set_pages_array_wb(shmem->pages, obj->size >> 
PAGE_SHIFT);
-#endif
-
-   drm_gem_put_pages(obj, shmem->pages,
- shmem->pages_mark_dirty_on_put,
- shmem->pages_mark_accessed_on_put);
-   shmem->pages = NULL;
-   }
+   if (refcount_dec_and_test(&shmem->pages_use_count))
+   drm_gem_shmem_free_pages(shmem);
 }
 EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages_locked);
 
-- 
2.41.0



[PATCH v18 05/26] drm/shmem-helper: Remove obsoleted is_iomem test

2023-10-29 Thread Dmitry Osipenko
Everything that uses the mapped buffer should be agnostic to is_iomem.
The only reason for the is_iomem test is that we're setting shmem->vaddr
to the returned map->vaddr. Now that the shmem->vaddr code is gone, remove
the obsoleted is_iomem test to clean up the code.

Suggested-by: Thomas Zimmermann 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 154585ddae08..2cc0601865f6 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -315,12 +315,6 @@ int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object 
*shmem,
 
if (obj->import_attach) {
ret = dma_buf_vmap(obj->import_attach->dmabuf, map);
-   if (!ret) {
-   if (drm_WARN_ON(obj->dev, map->is_iomem)) {
-   dma_buf_vunmap(obj->import_attach->dmabuf, map);
-   return -EIO;
-   }
-   }
} else {
pgprot_t prot = PAGE_KERNEL;
 
-- 
2.41.0



[PATCH v18 17/26] drm/v3d: Explicitly get and put drm-shmem pages

2023-10-29 Thread Dmitry Osipenko
To simplify the drm-shmem refcnt handling, we're moving away from
the implicit get_pages() that is used by get_pages_sgt(). From now on
drivers will have to pin pages while they use sgt. V3D driver doesn't
support shrinker, hence pages are pinned and sgt is valid as long as
pages' use-count > 0.

Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/v3d/v3d_bo.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/v3d/v3d_bo.c b/drivers/gpu/drm/v3d/v3d_bo.c
index 42cd874f6810..0597c6b01b6c 100644
--- a/drivers/gpu/drm/v3d/v3d_bo.c
+++ b/drivers/gpu/drm/v3d/v3d_bo.c
@@ -47,6 +47,9 @@ void v3d_free_object(struct drm_gem_object *obj)
/* GPU execution may have dirtied any pages in the BO. */
bo->base.pages_mark_dirty_on_put = true;
 
+   if (!obj->import_attach)
+   drm_gem_shmem_put_pages(&bo->base);
+
drm_gem_shmem_free(&bo->base);
 }
 
@@ -135,12 +138,18 @@ struct v3d_bo *v3d_bo_create(struct drm_device *dev, 
struct drm_file *file_priv,
return ERR_CAST(shmem_obj);
bo = to_v3d_bo(&shmem_obj->base);
 
-   ret = v3d_bo_create_finish(&shmem_obj->base);
+   ret = drm_gem_shmem_get_pages(shmem_obj);
if (ret)
goto free_obj;
 
+   ret = v3d_bo_create_finish(&shmem_obj->base);
+   if (ret)
+   goto put_pages;
+
return bo;
 
+put_pages:
+   drm_gem_shmem_put_pages(shmem_obj);
 free_obj:
drm_gem_shmem_free(shmem_obj);
return ERR_PTR(ret);
-- 
2.41.0



[PATCH v18 20/26] drm/shmem-helper: Export drm_gem_shmem_get_pages_sgt_locked()

2023-10-29 Thread Dmitry Osipenko
Export drm_gem_shmem_get_pages_sgt_locked() that will be used by virtio-gpu
shrinker during GEM swap-in operation done under the held reservation lock.

Reviewed-by: Boris Brezillon 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 22 +-
 include/drm/drm_gem_shmem_helper.h |  1 +
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 007521bea302..560ce565f376 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -872,12 +872,31 @@ struct sg_table *drm_gem_shmem_get_sg_table(struct 
drm_gem_shmem_object *shmem)
 }
 EXPORT_SYMBOL_GPL(drm_gem_shmem_get_sg_table);
 
-static struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct 
drm_gem_shmem_object *shmem)
+/**
+ * drm_gem_shmem_get_pages_sgt_locked - Provide a scatter/gather table of 
pinned
+ *  pages for a shmem GEM object
+ * @shmem: shmem GEM object
+ *
+ * This is a locked version of @drm_gem_shmem_get_sg_table that exports a
+ * scatter/gather table suitable for PRIME usage by calling the standard
+ * DMA mapping API.
+ *
+ * Drivers must hold GEM's reservation lock when using this function.
+ *
+ * Drivers who need to acquire an scatter/gather table for objects need to call
+ * drm_gem_shmem_get_pages_sgt() instead.
+ *
+ * Returns:
+ * A pointer to the scatter/gather table of pinned pages or error pointer on 
failure.
+ */
+struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct 
drm_gem_shmem_object *shmem)
 {
struct drm_gem_object *obj = &shmem->base;
int ret;
struct sg_table *sgt;
 
+   dma_resv_assert_held(shmem->base.resv);
+
if (shmem->sgt)
return shmem->sgt;
 
@@ -901,6 +920,7 @@ static struct sg_table 
*drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_
kfree(sgt);
return ERR_PTR(ret);
 }
+EXPORT_SYMBOL_GPL(drm_gem_shmem_get_pages_sgt_locked);
 
 /**
  * drm_gem_shmem_get_pages_sgt - Pin pages, dma map them, and return a
diff --git a/include/drm/drm_gem_shmem_helper.h 
b/include/drm/drm_gem_shmem_helper.h
index 3bb70616d095..6ac77c2082ed 100644
--- a/include/drm/drm_gem_shmem_helper.h
+++ b/include/drm/drm_gem_shmem_helper.h
@@ -149,6 +149,7 @@ void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object 
*shmem);
 
 struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object 
*shmem);
 struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_shmem_object 
*shmem);
+struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct 
drm_gem_shmem_object *shmem);
 
 void drm_gem_shmem_print_info(const struct drm_gem_shmem_object *shmem,
  struct drm_printer *p, unsigned int indent);
-- 
2.41.0



[PATCH v18 07/26] drm/shmem-helper: Use refcount_t for pages_use_count

2023-10-29 Thread Dmitry Osipenko
Use atomic refcount_t helper for pages_use_count to optimize pin/unpin
functions by skipping reservation locking while GEM's pin refcount > 1.

Reviewed-by: Boris Brezillon 
Suggested-by: Boris Brezillon 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c  | 33 +++--
 drivers/gpu/drm/lima/lima_gem.c |  2 +-
 drivers/gpu/drm/panfrost/panfrost_mmu.c |  2 +-
 include/drm/drm_gem_shmem_helper.h  |  2 +-
 4 files changed, 18 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index b9b71a1a563a..6e02643ed87e 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -155,7 +155,7 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem)
if (shmem->pages)
drm_gem_shmem_put_pages_locked(shmem);
 
-   drm_WARN_ON(obj->dev, shmem->pages_use_count);
+   drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_use_count));
drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_pin_count));
 
dma_resv_unlock(shmem->base.resv);
@@ -173,14 +173,13 @@ static int drm_gem_shmem_get_pages_locked(struct 
drm_gem_shmem_object *shmem)
 
dma_resv_assert_held(shmem->base.resv);
 
-   if (shmem->pages_use_count++ > 0)
+   if (refcount_inc_not_zero(&shmem->pages_use_count))
return 0;
 
pages = drm_gem_get_pages(obj);
if (IS_ERR(pages)) {
drm_dbg_kms(obj->dev, "Failed to get pages (%ld)\n",
PTR_ERR(pages));
-   shmem->pages_use_count = 0;
return PTR_ERR(pages);
}
 
@@ -196,6 +195,8 @@ static int drm_gem_shmem_get_pages_locked(struct 
drm_gem_shmem_object *shmem)
 
shmem->pages = pages;
 
+   refcount_set(&shmem->pages_use_count, 1);
+
return 0;
 }
 
@@ -211,21 +212,17 @@ void drm_gem_shmem_put_pages_locked(struct 
drm_gem_shmem_object *shmem)
 
dma_resv_assert_held(shmem->base.resv);
 
-   if (drm_WARN_ON_ONCE(obj->dev, !shmem->pages_use_count))
-   return;
-
-   if (--shmem->pages_use_count > 0)
-   return;
-
+   if (refcount_dec_and_test(&shmem->pages_use_count)) {
 #ifdef CONFIG_X86
-   if (shmem->map_wc)
-   set_pages_array_wb(shmem->pages, obj->size >> PAGE_SHIFT);
+   if (shmem->map_wc)
+   set_pages_array_wb(shmem->pages, obj->size >> 
PAGE_SHIFT);
 #endif
 
-   drm_gem_put_pages(obj, shmem->pages,
- shmem->pages_mark_dirty_on_put,
- shmem->pages_mark_accessed_on_put);
-   shmem->pages = NULL;
+   drm_gem_put_pages(obj, shmem->pages,
+ shmem->pages_mark_dirty_on_put,
+ shmem->pages_mark_accessed_on_put);
+   shmem->pages = NULL;
+   }
 }
 EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages_locked);
 
@@ -552,8 +549,8 @@ static void drm_gem_shmem_vm_open(struct vm_area_struct 
*vma)
 * mmap'd, vm_open() just grabs an additional reference for the new
 * mm the vma is getting copied into (ie. on fork()).
 */
-   if (!drm_WARN_ON_ONCE(obj->dev, !shmem->pages_use_count))
-   shmem->pages_use_count++;
+   drm_WARN_ON_ONCE(obj->dev,
+!refcount_inc_not_zero(&shmem->pages_use_count));
 
dma_resv_unlock(shmem->base.resv);
 
@@ -641,7 +638,7 @@ void drm_gem_shmem_print_info(const struct 
drm_gem_shmem_object *shmem,
return;
 
drm_printf_indent(p, indent, "pages_pin_count=%u\n", 
refcount_read(&shmem->pages_pin_count));
-   drm_printf_indent(p, indent, "pages_use_count=%u\n", 
shmem->pages_use_count);
+   drm_printf_indent(p, indent, "pages_use_count=%u\n", 
refcount_read(&shmem->pages_use_count));
drm_printf_indent(p, indent, "vmap_use_count=%u\n", 
shmem->vmap_use_count);
drm_printf_indent(p, indent, "vaddr=%p\n", shmem->vaddr);
 }
diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c
index 62d4a409faa8..988e74f67465 100644
--- a/drivers/gpu/drm/lima/lima_gem.c
+++ b/drivers/gpu/drm/lima/lima_gem.c
@@ -47,7 +47,7 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm)
}
 
bo->base.pages = pages;
-   bo->base.pages_use_count = 1;
+   refcount_set(&bo->base.pages_use_count, 1);
 
mapping_set_unevictable(mapping);
}
diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c 
b/drivers/gpu/drm/panfrost/panfrost_mmu.c
index 9fd4a89c52dd..770dab1942c2 100644
--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
+++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
@@ -487,7 +487,7 @@ static int panfrost_mmu_map_fault_addr(struct 
panfrost_device *pfdev, int as,
goto err_unlock;
  

[PATCH v18 21/26] drm/shmem-helper: Optimize unlocked get_pages_sgt()

2023-10-29 Thread Dmitry Osipenko
SGT isn't refcounted. Once SGT pointer has been obtained, it remains the
same for both locked and unlocked get_pages_sgt(). Return cached SGT
directly without taking a potentially expensive lock.

Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 560ce565f376..6dd087f19ea3 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -955,6 +955,9 @@ struct sg_table *drm_gem_shmem_get_pages_sgt(struct 
drm_gem_shmem_object *shmem)
drm_WARN_ON(obj->dev, drm_gem_shmem_is_evictable(shmem));
drm_WARN_ON(obj->dev, drm_gem_shmem_is_purgeable(shmem));
 
+   if (shmem->sgt)
+   return shmem->sgt;
+
ret = dma_resv_lock_interruptible(shmem->base.resv, NULL);
if (ret)
return ERR_PTR(ret);
-- 
2.41.0



[PATCH v18 09/26] drm/shmem-helper: Switch drm_gem_shmem_vmap/vunmap to use pin/unpin

2023-10-29 Thread Dmitry Osipenko
The vmapped pages shall be pinned in memory and previously get/put_pages()
were implicitly hard-pinning/unpinning the pages. This will no longer be
the case with addition of memory shrinker because pages_use_count > 0 won't
determine anymore whether pages are hard-pinned (they will be soft-pinned),
while the new pages_pin_count will do the hard-pinning. Switch the
vmap/vunmap() to use pin/unpin() functions in a preparation of addition
of the memory shrinker support to drm-shmem.

Reviewed-by: Boris Brezillon 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 19 ---
 include/drm/drm_gem_shmem_helper.h |  2 +-
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 41b749bedb11..6f963c2c1ecc 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -256,6 +256,14 @@ static int drm_gem_shmem_pin_locked(struct 
drm_gem_shmem_object *shmem)
return ret;
 }
 
+static void drm_gem_shmem_unpin_locked(struct drm_gem_shmem_object *shmem)
+{
+   dma_resv_assert_held(shmem->base.resv);
+
+   if (refcount_dec_and_test(&shmem->pages_pin_count))
+   drm_gem_shmem_put_pages_locked(shmem);
+}
+
 /**
  * drm_gem_shmem_pin - Pin backing pages for a shmem GEM object
  * @shmem: shmem GEM object
@@ -303,10 +311,7 @@ void drm_gem_shmem_unpin(struct drm_gem_shmem_object 
*shmem)
return;
 
dma_resv_lock(shmem->base.resv, NULL);
-
-   if (refcount_dec_and_test(&shmem->pages_pin_count))
-   drm_gem_shmem_put_pages_locked(shmem);
-
+   drm_gem_shmem_unpin_locked(shmem);
dma_resv_unlock(shmem->base.resv);
 }
 EXPORT_SYMBOL_GPL(drm_gem_shmem_unpin);
@@ -344,7 +349,7 @@ int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object 
*shmem,
return 0;
}
 
-   ret = drm_gem_shmem_get_pages_locked(shmem);
+   ret = drm_gem_shmem_pin_locked(shmem);
if (ret)
goto err_zero_use;
 
@@ -367,7 +372,7 @@ int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object 
*shmem,
 
 err_put_pages:
if (!obj->import_attach)
-   drm_gem_shmem_put_pages_locked(shmem);
+   drm_gem_shmem_unpin_locked(shmem);
 err_zero_use:
shmem->vmap_use_count = 0;
 
@@ -404,7 +409,7 @@ void drm_gem_shmem_vunmap_locked(struct 
drm_gem_shmem_object *shmem,
return;
 
vunmap(shmem->vaddr);
-   drm_gem_shmem_put_pages_locked(shmem);
+   drm_gem_shmem_unpin_locked(shmem);
}
 
shmem->vaddr = NULL;
diff --git a/include/drm/drm_gem_shmem_helper.h 
b/include/drm/drm_gem_shmem_helper.h
index bd3596e54abe..a6de11001048 100644
--- a/include/drm/drm_gem_shmem_helper.h
+++ b/include/drm/drm_gem_shmem_helper.h
@@ -124,7 +124,7 @@ int drm_gem_shmem_madvise_locked(struct 
drm_gem_shmem_object *shmem, int madv);
 static inline bool drm_gem_shmem_is_purgeable(struct drm_gem_shmem_object 
*shmem)
 {
return (shmem->madv > 0) &&
-   !shmem->vmap_use_count && shmem->sgt &&
+   !refcount_read(&shmem->pages_pin_count) && shmem->sgt &&
!shmem->base.dma_buf && !shmem->base.import_attach;
 }
 
-- 
2.41.0



[PATCH v18 23/26] drm/virtio: Pin display framebuffer BO

2023-10-29 Thread Dmitry Osipenko
Prepare to addition of memory shrinker support by pinning display
framebuffer BO pages in memory while they are in use by display on host.
Shrinker is free to relocate framebuffer BO pages if it doesn't know that
pages are in use, thus pin the pages to disallow shrinker to move them.

Acked-by: Gerd Hoffmann 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/virtio/virtgpu_drv.h   |  2 ++
 drivers/gpu/drm/virtio/virtgpu_gem.c   | 19 +++
 drivers/gpu/drm/virtio/virtgpu_plane.c | 17 +++--
 3 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h 
b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 96365a772f77..56269814fb6d 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -313,6 +313,8 @@ void virtio_gpu_array_put_free(struct 
virtio_gpu_object_array *objs);
 void virtio_gpu_array_put_free_delayed(struct virtio_gpu_device *vgdev,
   struct virtio_gpu_object_array *objs);
 void virtio_gpu_array_put_free_work(struct work_struct *work);
+int virtio_gpu_gem_pin(struct virtio_gpu_object *bo);
+void virtio_gpu_gem_unpin(struct virtio_gpu_object *bo);
 
 /* virtgpu_vq.c */
 int virtio_gpu_alloc_vbufs(struct virtio_gpu_device *vgdev);
diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c 
b/drivers/gpu/drm/virtio/virtgpu_gem.c
index 7db48d17ee3a..625c05d625bf 100644
--- a/drivers/gpu/drm/virtio/virtgpu_gem.c
+++ b/drivers/gpu/drm/virtio/virtgpu_gem.c
@@ -294,3 +294,22 @@ void virtio_gpu_array_put_free_work(struct work_struct 
*work)
}
spin_unlock(&vgdev->obj_free_lock);
 }
+
+int virtio_gpu_gem_pin(struct virtio_gpu_object *bo)
+{
+   int err;
+
+   if (virtio_gpu_is_shmem(bo)) {
+   err = drm_gem_shmem_pin(&bo->base);
+   if (err)
+   return err;
+   }
+
+   return 0;
+}
+
+void virtio_gpu_gem_unpin(struct virtio_gpu_object *bo)
+{
+   if (virtio_gpu_is_shmem(bo))
+   drm_gem_shmem_unpin(&bo->base);
+}
diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c 
b/drivers/gpu/drm/virtio/virtgpu_plane.c
index a2e045f3a000..def57b01a826 100644
--- a/drivers/gpu/drm/virtio/virtgpu_plane.c
+++ b/drivers/gpu/drm/virtio/virtgpu_plane.c
@@ -238,20 +238,28 @@ static int virtio_gpu_plane_prepare_fb(struct drm_plane 
*plane,
struct virtio_gpu_device *vgdev = dev->dev_private;
struct virtio_gpu_framebuffer *vgfb;
struct virtio_gpu_object *bo;
+   int err;
 
if (!new_state->fb)
return 0;
 
vgfb = to_virtio_gpu_framebuffer(new_state->fb);
bo = gem_to_virtio_gpu_obj(vgfb->base.obj[0]);
-   if (!bo || (plane->type == DRM_PLANE_TYPE_PRIMARY && !bo->guest_blob))
+
+   err = virtio_gpu_gem_pin(bo);
+   if (err)
+   return err;
+
+   if (plane->type == DRM_PLANE_TYPE_PRIMARY && !bo->guest_blob)
return 0;
 
if (bo->dumb && (plane->state->fb != new_state->fb)) {
vgfb->fence = virtio_gpu_fence_alloc(vgdev, 
vgdev->fence_drv.context,
 0);
-   if (!vgfb->fence)
+   if (!vgfb->fence) {
+   virtio_gpu_gem_unpin(bo);
return -ENOMEM;
+   }
}
 
return 0;
@@ -261,15 +269,20 @@ static void virtio_gpu_plane_cleanup_fb(struct drm_plane 
*plane,
struct drm_plane_state *state)
 {
struct virtio_gpu_framebuffer *vgfb;
+   struct virtio_gpu_object *bo;
 
if (!state->fb)
return;
 
vgfb = to_virtio_gpu_framebuffer(state->fb);
+   bo = gem_to_virtio_gpu_obj(vgfb->base.obj[0]);
+
if (vgfb->fence) {
dma_fence_put(&vgfb->fence->f);
vgfb->fence = NULL;
}
+
+   virtio_gpu_gem_unpin(bo);
 }
 
 static void virtio_gpu_cursor_plane_update(struct drm_plane *plane,
-- 
2.41.0



[PATCH v18 16/26] drm/virtio: Explicitly get and put drm-shmem pages

2023-10-29 Thread Dmitry Osipenko
We're moving away from implicit get_pages() that is done by
get_pages_sgt() to simplify the refcnt handling. Drivers will have
to pin pages while they use sgt. VirtIO-GPU doesn't support shrinker,
hence pages are pinned and sgt is valid as long as pages' use-count > 0.

Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/virtio/virtgpu_object.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c 
b/drivers/gpu/drm/virtio/virtgpu_object.c
index ee5d2a70656b..998f8b05ceb1 100644
--- a/drivers/gpu/drm/virtio/virtgpu_object.c
+++ b/drivers/gpu/drm/virtio/virtgpu_object.c
@@ -67,6 +67,7 @@ void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo)
 
virtio_gpu_resource_id_put(vgdev, bo->hw_res_handle);
if (virtio_gpu_is_shmem(bo)) {
+   drm_gem_shmem_put_pages(&bo->base);
drm_gem_shmem_free(&bo->base);
} else if (virtio_gpu_is_vram(bo)) {
struct virtio_gpu_object_vram *vram = to_virtio_gpu_vram(bo);
@@ -196,9 +197,13 @@ int virtio_gpu_object_create(struct virtio_gpu_device 
*vgdev,
return PTR_ERR(shmem_obj);
bo = gem_to_virtio_gpu_obj(&shmem_obj->base);
 
+   ret = drm_gem_shmem_get_pages(shmem_obj);
+   if (ret)
+   goto err_free_gem;
+
ret = virtio_gpu_resource_id_get(vgdev, &bo->hw_res_handle);
if (ret < 0)
-   goto err_free_gem;
+   goto err_put_pages;
 
bo->dumb = params->dumb;
 
@@ -243,6 +248,8 @@ int virtio_gpu_object_create(struct virtio_gpu_device 
*vgdev,
kvfree(ents);
 err_put_id:
virtio_gpu_resource_id_put(vgdev, bo->hw_res_handle);
+err_put_pages:
+   drm_gem_shmem_put_pages(shmem_obj);
 err_free_gem:
drm_gem_shmem_free(shmem_obj);
return ret;
-- 
2.41.0



[PATCH v18 10/26] drm/shmem-helper: Use refcount_t for vmap_use_count

2023-10-29 Thread Dmitry Osipenko
Use refcount_t helper for vmap_use_count to make refcounting consistent
with pages_use_count and pages_pin_count that use refcount_t. This also
makes vmapping to benefit from the refcount_t's overflow checks.

Reviewed-by: Boris Brezillon 
Suggested-by: Boris Brezillon 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 28 +++---
 include/drm/drm_gem_shmem_helper.h |  2 +-
 2 files changed, 13 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 6f963c2c1ecc..08b5a57c59d8 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -144,7 +144,7 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem)
} else {
dma_resv_lock(shmem->base.resv, NULL);
 
-   drm_WARN_ON(obj->dev, shmem->vmap_use_count);
+   drm_WARN_ON(obj->dev, refcount_read(&shmem->vmap_use_count));
 
if (shmem->sgt) {
dma_unmap_sgtable(obj->dev->dev, shmem->sgt,
@@ -344,23 +344,25 @@ int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object 
*shmem,
 
dma_resv_assert_held(shmem->base.resv);
 
-   if (shmem->vmap_use_count++ > 0) {
+   if (refcount_inc_not_zero(&shmem->vmap_use_count)) {
iosys_map_set_vaddr(map, shmem->vaddr);
return 0;
}
 
ret = drm_gem_shmem_pin_locked(shmem);
if (ret)
-   goto err_zero_use;
+   return ret;
 
if (shmem->map_wc)
prot = pgprot_writecombine(prot);
shmem->vaddr = vmap(shmem->pages, obj->size >> PAGE_SHIFT,
VM_MAP, prot);
-   if (!shmem->vaddr)
+   if (!shmem->vaddr) {
ret = -ENOMEM;
-   else
+   } else {
iosys_map_set_vaddr(map, shmem->vaddr);
+   refcount_set(&shmem->vmap_use_count, 1);
+   }
}
 
if (ret) {
@@ -373,8 +375,6 @@ int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object 
*shmem,
 err_put_pages:
if (!obj->import_attach)
drm_gem_shmem_unpin_locked(shmem);
-err_zero_use:
-   shmem->vmap_use_count = 0;
 
return ret;
 }
@@ -402,14 +402,10 @@ void drm_gem_shmem_vunmap_locked(struct 
drm_gem_shmem_object *shmem,
} else {
dma_resv_assert_held(shmem->base.resv);
 
-   if (drm_WARN_ON_ONCE(obj->dev, !shmem->vmap_use_count))
-   return;
-
-   if (--shmem->vmap_use_count > 0)
-   return;
-
-   vunmap(shmem->vaddr);
-   drm_gem_shmem_unpin_locked(shmem);
+   if (refcount_dec_and_test(&shmem->vmap_use_count)) {
+   vunmap(shmem->vaddr);
+   drm_gem_shmem_unpin_locked(shmem);
+   }
}
 
shmem->vaddr = NULL;
@@ -655,7 +651,7 @@ void drm_gem_shmem_print_info(const struct 
drm_gem_shmem_object *shmem,
 
drm_printf_indent(p, indent, "pages_pin_count=%u\n", 
refcount_read(&shmem->pages_pin_count));
drm_printf_indent(p, indent, "pages_use_count=%u\n", 
refcount_read(&shmem->pages_use_count));
-   drm_printf_indent(p, indent, "vmap_use_count=%u\n", 
shmem->vmap_use_count);
+   drm_printf_indent(p, indent, "vmap_use_count=%u\n", 
refcount_read(&shmem->vmap_use_count));
drm_printf_indent(p, indent, "vaddr=%p\n", shmem->vaddr);
 }
 EXPORT_SYMBOL_GPL(drm_gem_shmem_print_info);
diff --git a/include/drm/drm_gem_shmem_helper.h 
b/include/drm/drm_gem_shmem_helper.h
index a6de11001048..e7b3f4c02bf5 100644
--- a/include/drm/drm_gem_shmem_helper.h
+++ b/include/drm/drm_gem_shmem_helper.h
@@ -82,7 +82,7 @@ struct drm_gem_shmem_object {
 * Reference count on the virtual address.
 * The address are un-mapped when the count reaches zero.
 */
-   unsigned int vmap_use_count;
+   refcount_t vmap_use_count;
 
/**
 * @pages_mark_dirty_on_put:
-- 
2.41.0



[PATCH v18 15/26] drm/panfrost: Explicitly get and put drm-shmem pages

2023-10-29 Thread Dmitry Osipenko
To simplify the drm-shmem refcnt handling, we're moving away from
the implicit get_pages() that is used by get_pages_sgt(). From now on
drivers will have to pin pages while they use sgt. Panfrost's shrinker
doesn't support swapping out BOs, hence pages are pinned and sgt is valid
as long as pages' use-count > 0.

Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/panfrost/panfrost_gem.c | 17 +
 drivers/gpu/drm/panfrost/panfrost_mmu.c |  6 ++
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c 
b/drivers/gpu/drm/panfrost/panfrost_gem.c
index 6b77d8cebcb2..bb9d43cf7c3c 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
@@ -47,8 +47,13 @@ static void panfrost_gem_free_object(struct drm_gem_object 
*obj)
}
}
kvfree(bo->sgts);
+
+   drm_gem_shmem_put_pages(&bo->base);
}
 
+   if (!bo->is_heap && !obj->import_attach)
+   drm_gem_shmem_put_pages(&bo->base);
+
drm_gem_shmem_free(&bo->base);
 }
 
@@ -269,6 +274,7 @@ panfrost_gem_create(struct drm_device *dev, size_t size, 
u32 flags)
 {
struct drm_gem_shmem_object *shmem;
struct panfrost_gem_object *bo;
+   int err;
 
/* Round up heap allocations to 2MB to keep fault handling simple */
if (flags & PANFROST_BO_HEAP)
@@ -282,7 +288,18 @@ panfrost_gem_create(struct drm_device *dev, size_t size, 
u32 flags)
bo->noexec = !!(flags & PANFROST_BO_NOEXEC);
bo->is_heap = !!(flags & PANFROST_BO_HEAP);
 
+   if (!bo->is_heap) {
+   err = drm_gem_shmem_get_pages(shmem);
+   if (err)
+   goto err_free;
+   }
+
return bo;
+
+err_free:
+   drm_gem_shmem_free(&bo->base);
+
+   return ERR_PTR(err);
 }
 
 struct drm_gem_object *
diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c 
b/drivers/gpu/drm/panfrost/panfrost_mmu.c
index 770dab1942c2..ac145a98377b 100644
--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
+++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
@@ -504,7 +504,7 @@ static int panfrost_mmu_map_fault_addr(struct 
panfrost_device *pfdev, int as,
if (IS_ERR(pages[i])) {
ret = PTR_ERR(pages[i]);
pages[i] = NULL;
-   goto err_pages;
+   goto err_unlock;
}
}
 
@@ -512,7 +512,7 @@ static int panfrost_mmu_map_fault_addr(struct 
panfrost_device *pfdev, int as,
ret = sg_alloc_table_from_pages(sgt, pages + page_offset,
NUM_FAULT_PAGES, 0, SZ_2M, GFP_KERNEL);
if (ret)
-   goto err_pages;
+   goto err_unlock;
 
ret = dma_map_sgtable(pfdev->dev, sgt, DMA_BIDIRECTIONAL, 0);
if (ret)
@@ -535,8 +535,6 @@ static int panfrost_mmu_map_fault_addr(struct 
panfrost_device *pfdev, int as,
 
 err_map:
sg_free_table(sgt);
-err_pages:
-   drm_gem_shmem_put_pages_locked(&bo->base);
 err_unlock:
dma_resv_unlock(obj->resv);
 err_bo:
-- 
2.41.0



[PATCH v18 03/26] drm/shmem-helper: Make all exported symbols GPL

2023-10-29 Thread Dmitry Osipenko
Make all drm-shmem exported symbols GPL to make them consistent with
the rest of drm-shmem symbols.

Reviewed-by: Boris Brezillon 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index e435f986cd13..0d61f2b3e213 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -226,7 +226,7 @@ void drm_gem_shmem_put_pages(struct drm_gem_shmem_object 
*shmem)
  shmem->pages_mark_accessed_on_put);
shmem->pages = NULL;
 }
-EXPORT_SYMBOL(drm_gem_shmem_put_pages);
+EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages);
 
 static int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem)
 {
@@ -271,7 +271,7 @@ int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem)
 
return ret;
 }
-EXPORT_SYMBOL(drm_gem_shmem_pin);
+EXPORT_SYMBOL_GPL(drm_gem_shmem_pin);
 
 /**
  * drm_gem_shmem_unpin - Unpin backing pages for a shmem GEM object
@@ -290,7 +290,7 @@ void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem)
drm_gem_shmem_unpin_locked(shmem);
dma_resv_unlock(shmem->base.resv);
 }
-EXPORT_SYMBOL(drm_gem_shmem_unpin);
+EXPORT_SYMBOL_GPL(drm_gem_shmem_unpin);
 
 /*
  * drm_gem_shmem_vmap - Create a virtual mapping for a shmem GEM object
@@ -360,7 +360,7 @@ int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem,
 
return ret;
 }
-EXPORT_SYMBOL(drm_gem_shmem_vmap);
+EXPORT_SYMBOL_GPL(drm_gem_shmem_vmap);
 
 /*
  * drm_gem_shmem_vunmap - Unmap a virtual mapping for a shmem GEM object
@@ -396,7 +396,7 @@ void drm_gem_shmem_vunmap(struct drm_gem_shmem_object 
*shmem,
 
shmem->vaddr = NULL;
 }
-EXPORT_SYMBOL(drm_gem_shmem_vunmap);
+EXPORT_SYMBOL_GPL(drm_gem_shmem_vunmap);
 
 static int
 drm_gem_shmem_create_with_handle(struct drm_file *file_priv,
@@ -435,7 +435,7 @@ int drm_gem_shmem_madvise(struct drm_gem_shmem_object 
*shmem, int madv)
 
return (madv >= 0);
 }
-EXPORT_SYMBOL(drm_gem_shmem_madvise);
+EXPORT_SYMBOL_GPL(drm_gem_shmem_madvise);
 
 void drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem)
 {
@@ -467,7 +467,7 @@ void drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem)
 
invalidate_mapping_pages(file_inode(obj->filp)->i_mapping, 0, 
(loff_t)-1);
 }
-EXPORT_SYMBOL(drm_gem_shmem_purge);
+EXPORT_SYMBOL_GPL(drm_gem_shmem_purge);
 
 /**
  * drm_gem_shmem_dumb_create - Create a dumb shmem buffer object
@@ -642,7 +642,7 @@ void drm_gem_shmem_print_info(const struct 
drm_gem_shmem_object *shmem,
drm_printf_indent(p, indent, "vmap_use_count=%u\n", 
shmem->vmap_use_count);
drm_printf_indent(p, indent, "vaddr=%p\n", shmem->vaddr);
 }
-EXPORT_SYMBOL(drm_gem_shmem_print_info);
+EXPORT_SYMBOL_GPL(drm_gem_shmem_print_info);
 
 /**
  * drm_gem_shmem_get_sg_table - Provide a scatter/gather table of pinned
-- 
2.41.0



[PATCH AUTOSEL 4.14 08/11] fbdev: core: cfbcopyarea: fix sloppy typing

2023-10-29 Thread Sasha Levin
From: Sergey Shtylyov 

[ Upstream commit 7f33df94cf0156f64eee9509bd9b4a178990f613 ]

In cfb_copyarea(), the local variable bits_per_line is needlessly typed as
*unsigned long* -- which is a 32-bit type on the 32-bit arches and a 64-bit
type on the 64-bit arches; that variable's value is derived from the __u32
typed fb_fix_screeninfo::line_length field (multiplied by 8u) and a 32-bit
*unsigned int* type should still be enough to store the # of bits per line.

Found by Linux Verification Center (linuxtesting.org) with the Svace static
analysis tool.

Signed-off-by: Sergey Shtylyov 
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/core/cfbcopyarea.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/core/cfbcopyarea.c 
b/drivers/video/fbdev/core/cfbcopyarea.c
index 6d4bfeecee350..5b80bf3dae504 100644
--- a/drivers/video/fbdev/core/cfbcopyarea.c
+++ b/drivers/video/fbdev/core/cfbcopyarea.c
@@ -382,7 +382,7 @@ void cfb_copyarea(struct fb_info *p, const struct 
fb_copyarea *area)
 {
u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
u32 height = area->height, width = area->width;
-   unsigned long const bits_per_line = p->fix.line_length*8u;
+   unsigned int const bits_per_line = p->fix.line_length * 8u;
unsigned long __iomem *base = NULL;
int bits = BITS_PER_LONG, bytes = bits >> 3;
unsigned dst_idx = 0, src_idx = 0, rev_copy = 0;
-- 
2.42.0



[PATCH v18 04/26] drm/shmem-helper: Refactor locked/unlocked functions

2023-10-29 Thread Dmitry Osipenko
Add locked and remove unlocked postfixes from drm-shmem function names,
making names consistent with the drm/gem core code.

Reviewed-by: Boris Brezillon 
Suggested-by: Boris Brezillon 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c| 64 +--
 drivers/gpu/drm/lima/lima_gem.c   |  8 +--
 drivers/gpu/drm/panfrost/panfrost_drv.c   |  2 +-
 drivers/gpu/drm/panfrost/panfrost_gem.c   |  6 +-
 .../gpu/drm/panfrost/panfrost_gem_shrinker.c  |  2 +-
 drivers/gpu/drm/panfrost/panfrost_mmu.c   |  2 +-
 drivers/gpu/drm/v3d/v3d_bo.c  |  4 +-
 drivers/gpu/drm/virtio/virtgpu_object.c   |  4 +-
 include/drm/drm_gem_shmem_helper.h| 36 +--
 9 files changed, 64 insertions(+), 64 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 0d61f2b3e213..154585ddae08 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -43,8 +43,8 @@ static const struct drm_gem_object_funcs drm_gem_shmem_funcs 
= {
.pin = drm_gem_shmem_object_pin,
.unpin = drm_gem_shmem_object_unpin,
.get_sg_table = drm_gem_shmem_object_get_sg_table,
-   .vmap = drm_gem_shmem_object_vmap,
-   .vunmap = drm_gem_shmem_object_vunmap,
+   .vmap = drm_gem_shmem_object_vmap_locked,
+   .vunmap = drm_gem_shmem_object_vunmap_locked,
.mmap = drm_gem_shmem_object_mmap,
.vm_ops = &drm_gem_shmem_vm_ops,
 };
@@ -153,7 +153,7 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem)
kfree(shmem->sgt);
}
if (shmem->pages)
-   drm_gem_shmem_put_pages(shmem);
+   drm_gem_shmem_put_pages_locked(shmem);
 
drm_WARN_ON(obj->dev, shmem->pages_use_count);
 
@@ -165,7 +165,7 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem)
 }
 EXPORT_SYMBOL_GPL(drm_gem_shmem_free);
 
-static int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem)
+static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem)
 {
struct drm_gem_object *obj = &shmem->base;
struct page **pages;
@@ -199,12 +199,12 @@ static int drm_gem_shmem_get_pages(struct 
drm_gem_shmem_object *shmem)
 }
 
 /*
- * drm_gem_shmem_put_pages - Decrease use count on the backing pages for a 
shmem GEM object
+ * drm_gem_shmem_put_pages_locked - Decrease use count on the backing pages 
for a shmem GEM object
  * @shmem: shmem GEM object
  *
  * This function decreases the use count and puts the backing pages when use 
drops to zero.
  */
-void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem)
+void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem)
 {
struct drm_gem_object *obj = &shmem->base;
 
@@ -226,7 +226,7 @@ void drm_gem_shmem_put_pages(struct drm_gem_shmem_object 
*shmem)
  shmem->pages_mark_accessed_on_put);
shmem->pages = NULL;
 }
-EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages);
+EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages_locked);
 
 static int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem)
 {
@@ -234,7 +234,7 @@ static int drm_gem_shmem_pin_locked(struct 
drm_gem_shmem_object *shmem)
 
dma_resv_assert_held(shmem->base.resv);
 
-   ret = drm_gem_shmem_get_pages(shmem);
+   ret = drm_gem_shmem_get_pages_locked(shmem);
 
return ret;
 }
@@ -243,7 +243,7 @@ static void drm_gem_shmem_unpin_locked(struct 
drm_gem_shmem_object *shmem)
 {
dma_resv_assert_held(shmem->base.resv);
 
-   drm_gem_shmem_put_pages(shmem);
+   drm_gem_shmem_put_pages_locked(shmem);
 }
 
 /**
@@ -293,7 +293,7 @@ void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem)
 EXPORT_SYMBOL_GPL(drm_gem_shmem_unpin);
 
 /*
- * drm_gem_shmem_vmap - Create a virtual mapping for a shmem GEM object
+ * drm_gem_shmem_vmap_locked - Create a virtual mapping for a shmem GEM object
  * @shmem: shmem GEM object
  * @map: Returns the kernel virtual address of the SHMEM GEM object's backing
  *   store.
@@ -302,13 +302,13 @@ EXPORT_SYMBOL_GPL(drm_gem_shmem_unpin);
  * exists for the buffer backing the shmem GEM object. It hides the differences
  * between dma-buf imported and natively allocated objects.
  *
- * Acquired mappings should be cleaned up by calling drm_gem_shmem_vunmap().
+ * Acquired mappings should be cleaned up by calling 
drm_gem_shmem_vunmap_locked().
  *
  * Returns:
  * 0 on success or a negative error code on failure.
  */
-int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem,
-  struct iosys_map *map)
+int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem,
+ struct iosys_map *map)
 {
struct drm_gem_object *obj = &shmem->base;
int ret = 0;
@@ -331,7 +331,7 @@ int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem,
  

[PATCH v18 01/26] drm/gem: Change locked/unlocked postfix of drm_gem_v/unmap() function names

2023-10-29 Thread Dmitry Osipenko
Make drm/gem API function names consistent by having locked function
use the _locked postfix in the name, while the unlocked variants don't
use the _unlocked postfix. Rename drm_gem_v/unmap() function names to
make them consistent with the rest of the API functions.

Reviewed-by: Boris Brezillon 
Suggested-by: Boris Brezillon 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_client.c |  6 +++---
 drivers/gpu/drm/drm_gem.c| 20 ++--
 drivers/gpu/drm/drm_gem_framebuffer_helper.c |  6 +++---
 drivers/gpu/drm/drm_internal.h   |  4 ++--
 drivers/gpu/drm/drm_prime.c  |  4 ++--
 drivers/gpu/drm/lima/lima_sched.c|  4 ++--
 drivers/gpu/drm/panfrost/panfrost_dump.c |  4 ++--
 drivers/gpu/drm/panfrost/panfrost_perfcnt.c  |  6 +++---
 include/drm/drm_gem.h|  4 ++--
 9 files changed, 29 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
index 2762572f286e..c935db1ba918 100644
--- a/drivers/gpu/drm/drm_client.c
+++ b/drivers/gpu/drm/drm_client.c
@@ -265,7 +265,7 @@ void drm_client_dev_restore(struct drm_device *dev)
 static void drm_client_buffer_delete(struct drm_client_buffer *buffer)
 {
if (buffer->gem) {
-   drm_gem_vunmap_unlocked(buffer->gem, &buffer->map);
+   drm_gem_vunmap(buffer->gem, &buffer->map);
drm_gem_object_put(buffer->gem);
}
 
@@ -349,7 +349,7 @@ drm_client_buffer_vmap(struct drm_client_buffer *buffer,
 * fd_install step out of the driver backend hooks, to make that
 * final step optional for internal users.
 */
-   ret = drm_gem_vmap_unlocked(buffer->gem, map);
+   ret = drm_gem_vmap(buffer->gem, map);
if (ret)
return ret;
 
@@ -371,7 +371,7 @@ void drm_client_buffer_vunmap(struct drm_client_buffer 
*buffer)
 {
struct iosys_map *map = &buffer->map;
 
-   drm_gem_vunmap_unlocked(buffer->gem, map);
+   drm_gem_vunmap(buffer->gem, map);
 }
 EXPORT_SYMBOL(drm_client_buffer_vunmap);
 
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 44a948b80ee1..95327b003692 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -1175,7 +1175,7 @@ void drm_gem_unpin(struct drm_gem_object *obj)
obj->funcs->unpin(obj);
 }
 
-int drm_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map)
+int drm_gem_vmap_locked(struct drm_gem_object *obj, struct iosys_map *map)
 {
int ret;
 
@@ -1192,9 +1192,9 @@ int drm_gem_vmap(struct drm_gem_object *obj, struct 
iosys_map *map)
 
return 0;
 }
-EXPORT_SYMBOL(drm_gem_vmap);
+EXPORT_SYMBOL(drm_gem_vmap_locked);
 
-void drm_gem_vunmap(struct drm_gem_object *obj, struct iosys_map *map)
+void drm_gem_vunmap_locked(struct drm_gem_object *obj, struct iosys_map *map)
 {
dma_resv_assert_held(obj->resv);
 
@@ -1207,27 +1207,27 @@ void drm_gem_vunmap(struct drm_gem_object *obj, struct 
iosys_map *map)
/* Always set the mapping to NULL. Callers may rely on this. */
iosys_map_clear(map);
 }
-EXPORT_SYMBOL(drm_gem_vunmap);
+EXPORT_SYMBOL(drm_gem_vunmap_locked);
 
-int drm_gem_vmap_unlocked(struct drm_gem_object *obj, struct iosys_map *map)
+int drm_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map)
 {
int ret;
 
dma_resv_lock(obj->resv, NULL);
-   ret = drm_gem_vmap(obj, map);
+   ret = drm_gem_vmap_locked(obj, map);
dma_resv_unlock(obj->resv);
 
return ret;
 }
-EXPORT_SYMBOL(drm_gem_vmap_unlocked);
+EXPORT_SYMBOL(drm_gem_vmap);
 
-void drm_gem_vunmap_unlocked(struct drm_gem_object *obj, struct iosys_map *map)
+void drm_gem_vunmap(struct drm_gem_object *obj, struct iosys_map *map)
 {
dma_resv_lock(obj->resv, NULL);
-   drm_gem_vunmap(obj, map);
+   drm_gem_vunmap_locked(obj, map);
dma_resv_unlock(obj->resv);
 }
-EXPORT_SYMBOL(drm_gem_vunmap_unlocked);
+EXPORT_SYMBOL(drm_gem_vunmap);
 
 /**
  * drm_gem_lock_reservations - Sets up the ww context and acquires
diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
index 3bdb6ba37ff4..3808f47310bf 100644
--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -362,7 +362,7 @@ int drm_gem_fb_vmap(struct drm_framebuffer *fb, struct 
iosys_map *map,
ret = -EINVAL;
goto err_drm_gem_vunmap;
}
-   ret = drm_gem_vmap_unlocked(obj, &map[i]);
+   ret = drm_gem_vmap(obj, &map[i]);
if (ret)
goto err_drm_gem_vunmap;
}
@@ -384,7 +384,7 @@ int drm_gem_fb_vmap(struct drm_framebuffer *fb, struct 
iosys_map *map,
obj = drm_gem_fb_get_obj(fb, i);
if (!obj)
continue;
-   drm_gem_vunmap_unlocked(obj, 

[PATCH v18 02/26] drm/gem: Add _locked postfix to functions that have unlocked counterpart

2023-10-29 Thread Dmitry Osipenko
Add _locked postfix to drm_gem functions that have unlocked counterpart
functions to make GEM functions naming more consistent and intuitive in
regards to the locking requirements.

Reviewed-by: Boris Brezillon 
Suggested-by: Boris Brezillon 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem.c | 6 +++---
 include/drm/drm_gem.h | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 95327b003692..4523cd40fb2f 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -1490,10 +1490,10 @@ drm_gem_lru_scan(struct drm_gem_lru *lru,
 EXPORT_SYMBOL(drm_gem_lru_scan);
 
 /**
- * drm_gem_evict - helper to evict backing pages for a GEM object
+ * drm_gem_evict_locked - helper to evict backing pages for a GEM object
  * @obj: obj in question
  */
-int drm_gem_evict(struct drm_gem_object *obj)
+int drm_gem_evict_locked(struct drm_gem_object *obj)
 {
dma_resv_assert_held(obj->resv);
 
@@ -1505,4 +1505,4 @@ int drm_gem_evict(struct drm_gem_object *obj)
 
return 0;
 }
-EXPORT_SYMBOL(drm_gem_evict);
+EXPORT_SYMBOL(drm_gem_evict_locked);
diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
index 3daa8db644c3..c55d8571dbb3 100644
--- a/include/drm/drm_gem.h
+++ b/include/drm/drm_gem.h
@@ -551,7 +551,7 @@ unsigned long drm_gem_lru_scan(struct drm_gem_lru *lru,
   unsigned long *remaining,
   bool (*shrink)(struct drm_gem_object *obj));
 
-int drm_gem_evict(struct drm_gem_object *obj);
+int drm_gem_evict_locked(struct drm_gem_object *obj);
 
 #ifdef CONFIG_LOCKDEP
 /**
-- 
2.41.0



[PATCH AUTOSEL 4.14 07/11] fbdev: uvesafb: Call cn_del_callback() at the end of uvesafb_exit()

2023-10-29 Thread Sasha Levin
From: Jorge Maidana 

[ Upstream commit 1022e7e2f40574c74ed32c3811b03d26b0b81daf ]

Delete the v86d netlink only after all the VBE tasks have been
completed.

Fixes initial state restore on module unload:
uvesafb: VBE state restore call failed (eax=0x4f04, err=-19)

Signed-off-by: Jorge Maidana 
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/uvesafb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c
index ee86c62e36728..72255715bbee0 100644
--- a/drivers/video/fbdev/uvesafb.c
+++ b/drivers/video/fbdev/uvesafb.c
@@ -1931,10 +1931,10 @@ static void uvesafb_exit(void)
}
}
 
-   cn_del_callback(&uvesafb_cn_id);
driver_remove_file(&uvesafb_driver.driver, &driver_attr_v86d);
platform_device_unregister(uvesafb_device);
platform_driver_unregister(&uvesafb_driver);
+   cn_del_callback(&uvesafb_cn_id);
 }
 
 module_exit(uvesafb_exit);
-- 
2.42.0



[PATCH v18 00/26] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers

2023-10-29 Thread Dmitry Osipenko
This series:

  1. Adds common drm-shmem memory shrinker
  2. Enables shrinker for VirtIO-GPU driver
  3. Switches Panfrost driver to the common shrinker
  4. Fixes bugs and improves drm-shmem code

Mesa: https://gitlab.freedesktop.org/digetx/mesa/-/commits/virgl-madvise
IGT:  
https://gitlab.freedesktop.org/digetx/igt-gpu-tools/-/commits/virtio-madvise
  
https://gitlab.freedesktop.org/digetx/igt-gpu-tools/-/commits/panfrost-madvise

Changelog:

v18:- Added new pathes that change sgt allocation policy. Previously once
  sgt was allocated, it exsited till GEM was freed. Now sgt is destroyed
  once pages are unpinned and drivers have to manage the pages' pinning
  refcounting by themselves using get/put() and pin/unpin() pages.
  This removes pages refcounting ambiguity from the drm-shmem core.

- Dropped patch that changed drm_gem_shmem_vmap_locked() error handling,
  like was requested by Boris Brezillon.

- Added new patches that make minor improvements:

- Optimize unlocked get_pages_sgt()
- Don't free refcounted GEM

- Dropped t-b from the Panfrost shrinker patch that was given for older
  patch version since code changed with the new sgt allocation policy.

v17:- Dropped patches that added new drm-shmem sgt flags, fixing dma-buf UAF
  in drm-prime error code path and preventing invalid page_count when GEM
  is freed. Will revist them later on and then factor them out into a
  seprate patchset.

- Dropped patches that replaced drm_gem_shmem_free() with
  drm_gem_object_put(), they not needed anymore after changing
  drm_gem_shmem_free() to not touch reservation lock.

- Addressed review comments from Boris Brezillon:

- Added new patch to clean up error unwinding in
  drm_gem_shmem_vmap_locked()

- Added new __drm_gem_shmem_put_pages() to let the callers
  to assert the held reservation lock themselves

- Moved replacement of shmem->pages check with refcount_read()
  in drm_gem_shmem_free() to the shrinker addition patch

- Improved commit message of the vmap_use_count patch

- Added r-bs from Boris Brezillon that he gave to v16

v16:- Added more comments to the code for the new drm-shmem flags

- Added r-bs from Boris Brezillon

- Fixed typos and made impovements pointed out by Boris Brezillon

- Replaced kref with refcount_t as was suggested by Boris Brezillon

- Corrected placement of got_sgt flag in the Lima driver, also renamed
  flag to got_pages_sgt

- Removed drm_gem_shmem_resv_assert_held() and made drm_gem_shmem_free()
  to free pages without a new func that doesn't touch resv lock, as was
  suggested by Boris Brezillon

- Added pages_pin_count to drm_gem_shmem_print_info()

v15:- Moved drm-shmem reference counters to use kref that allows to
  optimize unlocked functions, like was suggested by Boris Brezillon.

- Changed drm/gem/shmem function names to use _locked postfix and
  dropped the _unlocked, making the naming scheme consistent across
  DRM code, like was suggested by Boris Brezillon.

- Added patch that fixes UAF in drm-shmem for drivers that import
  dma-buf and then release buffer in the import error code path.

- Added patch that makes drm-shmem use new flag for SGT's get_pages()
  refcounting, preventing unbalanced refcounting when GEM is freed.

- Fixed guest blob pinning in virtio-gpu driver that was missed
  previously in the shrinker patch.

- Moved VC4 and virtio-gpu drivers to use drm_gem_put() in
  GEM-creation error code paths, which is now required by drm-shmem
  and was missed in a previous patch versions.

- Virtio-GPU now attaches shmem pages to host on first use and not
  when BO is created. In older patch versions there was a potential
  race condition in the BO creation code path where both
  get_sgt()+object_attach() should've been made under same resv lock,
  otherwise pages could be evicted before attachment is invoked.

- Virtio-GPU and drm-shmem shrinker patches are split into smaller
  ones.

v14:- All the prerequisite reservation locking patches landed upstream,
  previously were a part of this series in v13 and older.


https://lore.kernel.org/dri-devel/20230529223935.2672495-1-dmitry.osipe...@collabora.com/

- Added patches to improve locked/unlocked function names, like was
  suggested by Boris Brezillon for v13.

- Made all exported drm-shmem symbols GPL, like was previously
  discussed with Thomas Zimmermann on this series.

- Improved virtio-gpu shrinker patch. Now it won't detach purged BO
  when userspace closes GEM. Crosvm (and not qemu) checks res_id on
  CMD_CTX_DETACH_RESOURCE and prints noisy error message if ID is
  invalid, which wasn't noticed before.

v13:- Updated virtio-gpu shrinker patch to use drm_gem_shmem_object_pin()
  directly inst

[PATCH AUTOSEL 4.14 01/11] fbdev: atyfb: only use ioremap_uc() on i386 and ia64

2023-10-29 Thread Sasha Levin
From: Arnd Bergmann 

[ Upstream commit c1a8d1d0edb71dec15c9649cb56866c71c1ecd9e ]

ioremap_uc() is only meaningful on old x86-32 systems with the PAT
extension, and on ia64 with its slightly unconventional ioremap()
behavior, everywhere else this is the same as ioremap() anyway.

Change the only driver that still references ioremap_uc() to only do so
on x86-32/ia64 in order to allow removing that interface at some
point in the future for the other architectures.

On some architectures, ioremap_uc() just returns NULL, changing
the driver to call ioremap() means that they now have a chance
of working correctly.

Signed-off-by: Arnd Bergmann 
Signed-off-by: Baoquan He 
Reviewed-by: Luis Chamberlain 
Cc: Helge Deller 
Cc: Thomas Zimmermann 
Cc: Christophe Leroy 
Cc: linux-fb...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/aty/atyfb_base.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/video/fbdev/aty/atyfb_base.c 
b/drivers/video/fbdev/aty/atyfb_base.c
index d4b938276d238..71e95533613cd 100644
--- a/drivers/video/fbdev/aty/atyfb_base.c
+++ b/drivers/video/fbdev/aty/atyfb_base.c
@@ -3435,11 +3435,15 @@ static int atyfb_setup_generic(struct pci_dev *pdev, 
struct fb_info *info,
}
 
info->fix.mmio_start = raddr;
+#if defined(__i386__) || defined(__ia64__)
/*
 * By using strong UC we force the MTRR to never have an
 * effect on the MMIO region on both non-PAT and PAT systems.
 */
par->ati_regbase = ioremap_uc(info->fix.mmio_start, 0x1000);
+#else
+   par->ati_regbase = ioremap(info->fix.mmio_start, 0x1000);
+#endif
if (par->ati_regbase == NULL)
return -ENOMEM;
 
-- 
2.42.0



[PATCH AUTOSEL 4.19 09/12] fbdev: core: syscopyarea: fix sloppy typing

2023-10-29 Thread Sasha Levin
From: Sergey Shtylyov 

[ Upstream commit e8e4a470b677511f9d1ad4f3cef32adc1d9a60ca ]

In sys_copyarea(), the local variable bits_per_line is needlessly typed as
*unsigned long* -- which is a 32-bit type on the 32-bit arches and a 64-bit
type on the 64-bit arches; that variable's value is derived from the __u32
typed fb_fix_screeninfo::line_length field (multiplied by 8u) and a 32-bit
*unsigned int* type should still be enough to store the # of bits per line.

Found by Linux Verification Center (linuxtesting.org) with the Svace static
analysis tool.

Signed-off-by: Sergey Shtylyov 
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/core/syscopyarea.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/core/syscopyarea.c 
b/drivers/video/fbdev/core/syscopyarea.c
index c1eda31909682..7b8bd3a2bedc5 100644
--- a/drivers/video/fbdev/core/syscopyarea.c
+++ b/drivers/video/fbdev/core/syscopyarea.c
@@ -316,7 +316,7 @@ void sys_copyarea(struct fb_info *p, const struct 
fb_copyarea *area)
 {
u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
u32 height = area->height, width = area->width;
-   unsigned long const bits_per_line = p->fix.line_length*8u;
+   unsigned int const bits_per_line = p->fix.line_length * 8u;
unsigned long *base = NULL;
int bits = BITS_PER_LONG, bytes = bits >> 3;
unsigned dst_idx = 0, src_idx = 0, rev_copy = 0;
-- 
2.42.0



[PATCH AUTOSEL 4.19 08/12] fbdev: core: cfbcopyarea: fix sloppy typing

2023-10-29 Thread Sasha Levin
From: Sergey Shtylyov 

[ Upstream commit 7f33df94cf0156f64eee9509bd9b4a178990f613 ]

In cfb_copyarea(), the local variable bits_per_line is needlessly typed as
*unsigned long* -- which is a 32-bit type on the 32-bit arches and a 64-bit
type on the 64-bit arches; that variable's value is derived from the __u32
typed fb_fix_screeninfo::line_length field (multiplied by 8u) and a 32-bit
*unsigned int* type should still be enough to store the # of bits per line.

Found by Linux Verification Center (linuxtesting.org) with the Svace static
analysis tool.

Signed-off-by: Sergey Shtylyov 
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/core/cfbcopyarea.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/core/cfbcopyarea.c 
b/drivers/video/fbdev/core/cfbcopyarea.c
index 6d4bfeecee350..5b80bf3dae504 100644
--- a/drivers/video/fbdev/core/cfbcopyarea.c
+++ b/drivers/video/fbdev/core/cfbcopyarea.c
@@ -382,7 +382,7 @@ void cfb_copyarea(struct fb_info *p, const struct 
fb_copyarea *area)
 {
u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
u32 height = area->height, width = area->width;
-   unsigned long const bits_per_line = p->fix.line_length*8u;
+   unsigned int const bits_per_line = p->fix.line_length * 8u;
unsigned long __iomem *base = NULL;
int bits = BITS_PER_LONG, bytes = bits >> 3;
unsigned dst_idx = 0, src_idx = 0, rev_copy = 0;
-- 
2.42.0



[PATCH AUTOSEL 4.19 07/12] fbdev: uvesafb: Call cn_del_callback() at the end of uvesafb_exit()

2023-10-29 Thread Sasha Levin
From: Jorge Maidana 

[ Upstream commit 1022e7e2f40574c74ed32c3811b03d26b0b81daf ]

Delete the v86d netlink only after all the VBE tasks have been
completed.

Fixes initial state restore on module unload:
uvesafb: VBE state restore call failed (eax=0x4f04, err=-19)

Signed-off-by: Jorge Maidana 
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/uvesafb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c
index f6ebca8839127..1ded93f106f07 100644
--- a/drivers/video/fbdev/uvesafb.c
+++ b/drivers/video/fbdev/uvesafb.c
@@ -1932,10 +1932,10 @@ static void uvesafb_exit(void)
}
}
 
-   cn_del_callback(&uvesafb_cn_id);
driver_remove_file(&uvesafb_driver.driver, &driver_attr_v86d);
platform_device_unregister(uvesafb_device);
platform_driver_unregister(&uvesafb_driver);
+   cn_del_callback(&uvesafb_cn_id);
 }
 
 module_exit(uvesafb_exit);
-- 
2.42.0



[PATCH AUTOSEL 4.19 01/12] fbdev: atyfb: only use ioremap_uc() on i386 and ia64

2023-10-29 Thread Sasha Levin
From: Arnd Bergmann 

[ Upstream commit c1a8d1d0edb71dec15c9649cb56866c71c1ecd9e ]

ioremap_uc() is only meaningful on old x86-32 systems with the PAT
extension, and on ia64 with its slightly unconventional ioremap()
behavior, everywhere else this is the same as ioremap() anyway.

Change the only driver that still references ioremap_uc() to only do so
on x86-32/ia64 in order to allow removing that interface at some
point in the future for the other architectures.

On some architectures, ioremap_uc() just returns NULL, changing
the driver to call ioremap() means that they now have a chance
of working correctly.

Signed-off-by: Arnd Bergmann 
Signed-off-by: Baoquan He 
Reviewed-by: Luis Chamberlain 
Cc: Helge Deller 
Cc: Thomas Zimmermann 
Cc: Christophe Leroy 
Cc: linux-fb...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/aty/atyfb_base.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/video/fbdev/aty/atyfb_base.c 
b/drivers/video/fbdev/aty/atyfb_base.c
index 05111e90f1681..5ef008e9c61c3 100644
--- a/drivers/video/fbdev/aty/atyfb_base.c
+++ b/drivers/video/fbdev/aty/atyfb_base.c
@@ -3435,11 +3435,15 @@ static int atyfb_setup_generic(struct pci_dev *pdev, 
struct fb_info *info,
}
 
info->fix.mmio_start = raddr;
+#if defined(__i386__) || defined(__ia64__)
/*
 * By using strong UC we force the MTRR to never have an
 * effect on the MMIO region on both non-PAT and PAT systems.
 */
par->ati_regbase = ioremap_uc(info->fix.mmio_start, 0x1000);
+#else
+   par->ati_regbase = ioremap(info->fix.mmio_start, 0x1000);
+#endif
if (par->ati_regbase == NULL)
return -ENOMEM;
 
-- 
2.42.0



[PATCH AUTOSEL 5.4 10/13] fbdev: core: syscopyarea: fix sloppy typing

2023-10-29 Thread Sasha Levin
From: Sergey Shtylyov 

[ Upstream commit e8e4a470b677511f9d1ad4f3cef32adc1d9a60ca ]

In sys_copyarea(), the local variable bits_per_line is needlessly typed as
*unsigned long* -- which is a 32-bit type on the 32-bit arches and a 64-bit
type on the 64-bit arches; that variable's value is derived from the __u32
typed fb_fix_screeninfo::line_length field (multiplied by 8u) and a 32-bit
*unsigned int* type should still be enough to store the # of bits per line.

Found by Linux Verification Center (linuxtesting.org) with the Svace static
analysis tool.

Signed-off-by: Sergey Shtylyov 
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/core/syscopyarea.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/core/syscopyarea.c 
b/drivers/video/fbdev/core/syscopyarea.c
index c1eda31909682..7b8bd3a2bedc5 100644
--- a/drivers/video/fbdev/core/syscopyarea.c
+++ b/drivers/video/fbdev/core/syscopyarea.c
@@ -316,7 +316,7 @@ void sys_copyarea(struct fb_info *p, const struct 
fb_copyarea *area)
 {
u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
u32 height = area->height, width = area->width;
-   unsigned long const bits_per_line = p->fix.line_length*8u;
+   unsigned int const bits_per_line = p->fix.line_length * 8u;
unsigned long *base = NULL;
int bits = BITS_PER_LONG, bytes = bits >> 3;
unsigned dst_idx = 0, src_idx = 0, rev_copy = 0;
-- 
2.42.0



[PATCH AUTOSEL 5.4 09/13] fbdev: core: cfbcopyarea: fix sloppy typing

2023-10-29 Thread Sasha Levin
From: Sergey Shtylyov 

[ Upstream commit 7f33df94cf0156f64eee9509bd9b4a178990f613 ]

In cfb_copyarea(), the local variable bits_per_line is needlessly typed as
*unsigned long* -- which is a 32-bit type on the 32-bit arches and a 64-bit
type on the 64-bit arches; that variable's value is derived from the __u32
typed fb_fix_screeninfo::line_length field (multiplied by 8u) and a 32-bit
*unsigned int* type should still be enough to store the # of bits per line.

Found by Linux Verification Center (linuxtesting.org) with the Svace static
analysis tool.

Signed-off-by: Sergey Shtylyov 
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/core/cfbcopyarea.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/core/cfbcopyarea.c 
b/drivers/video/fbdev/core/cfbcopyarea.c
index 6d4bfeecee350..5b80bf3dae504 100644
--- a/drivers/video/fbdev/core/cfbcopyarea.c
+++ b/drivers/video/fbdev/core/cfbcopyarea.c
@@ -382,7 +382,7 @@ void cfb_copyarea(struct fb_info *p, const struct 
fb_copyarea *area)
 {
u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
u32 height = area->height, width = area->width;
-   unsigned long const bits_per_line = p->fix.line_length*8u;
+   unsigned int const bits_per_line = p->fix.line_length * 8u;
unsigned long __iomem *base = NULL;
int bits = BITS_PER_LONG, bytes = bits >> 3;
unsigned dst_idx = 0, src_idx = 0, rev_copy = 0;
-- 
2.42.0



[PATCH AUTOSEL 5.4 08/13] fbdev: uvesafb: Call cn_del_callback() at the end of uvesafb_exit()

2023-10-29 Thread Sasha Levin
From: Jorge Maidana 

[ Upstream commit 1022e7e2f40574c74ed32c3811b03d26b0b81daf ]

Delete the v86d netlink only after all the VBE tasks have been
completed.

Fixes initial state restore on module unload:
uvesafb: VBE state restore call failed (eax=0x4f04, err=-19)

Signed-off-by: Jorge Maidana 
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/uvesafb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c
index 7d3af1d19ad3f..115653ba761c0 100644
--- a/drivers/video/fbdev/uvesafb.c
+++ b/drivers/video/fbdev/uvesafb.c
@@ -1933,10 +1933,10 @@ static void uvesafb_exit(void)
}
}
 
-   cn_del_callback(&uvesafb_cn_id);
driver_remove_file(&uvesafb_driver.driver, &driver_attr_v86d);
platform_device_unregister(uvesafb_device);
platform_driver_unregister(&uvesafb_driver);
+   cn_del_callback(&uvesafb_cn_id);
 }
 
 module_exit(uvesafb_exit);
-- 
2.42.0



[PATCH AUTOSEL 5.4 01/13] fbdev: atyfb: only use ioremap_uc() on i386 and ia64

2023-10-29 Thread Sasha Levin
From: Arnd Bergmann 

[ Upstream commit c1a8d1d0edb71dec15c9649cb56866c71c1ecd9e ]

ioremap_uc() is only meaningful on old x86-32 systems with the PAT
extension, and on ia64 with its slightly unconventional ioremap()
behavior, everywhere else this is the same as ioremap() anyway.

Change the only driver that still references ioremap_uc() to only do so
on x86-32/ia64 in order to allow removing that interface at some
point in the future for the other architectures.

On some architectures, ioremap_uc() just returns NULL, changing
the driver to call ioremap() means that they now have a chance
of working correctly.

Signed-off-by: Arnd Bergmann 
Signed-off-by: Baoquan He 
Reviewed-by: Luis Chamberlain 
Cc: Helge Deller 
Cc: Thomas Zimmermann 
Cc: Christophe Leroy 
Cc: linux-fb...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/aty/atyfb_base.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/video/fbdev/aty/atyfb_base.c 
b/drivers/video/fbdev/aty/atyfb_base.c
index 6dda5d885a03b..bb9ecf12e7630 100644
--- a/drivers/video/fbdev/aty/atyfb_base.c
+++ b/drivers/video/fbdev/aty/atyfb_base.c
@@ -3410,11 +3410,15 @@ static int atyfb_setup_generic(struct pci_dev *pdev, 
struct fb_info *info,
}
 
info->fix.mmio_start = raddr;
+#if defined(__i386__) || defined(__ia64__)
/*
 * By using strong UC we force the MTRR to never have an
 * effect on the MMIO region on both non-PAT and PAT systems.
 */
par->ati_regbase = ioremap_uc(info->fix.mmio_start, 0x1000);
+#else
+   par->ati_regbase = ioremap(info->fix.mmio_start, 0x1000);
+#endif
if (par->ati_regbase == NULL)
return -ENOMEM;
 
-- 
2.42.0



[PATCH AUTOSEL 5.10 11/16] fbdev: core: syscopyarea: fix sloppy typing

2023-10-29 Thread Sasha Levin
From: Sergey Shtylyov 

[ Upstream commit e8e4a470b677511f9d1ad4f3cef32adc1d9a60ca ]

In sys_copyarea(), the local variable bits_per_line is needlessly typed as
*unsigned long* -- which is a 32-bit type on the 32-bit arches and a 64-bit
type on the 64-bit arches; that variable's value is derived from the __u32
typed fb_fix_screeninfo::line_length field (multiplied by 8u) and a 32-bit
*unsigned int* type should still be enough to store the # of bits per line.

Found by Linux Verification Center (linuxtesting.org) with the Svace static
analysis tool.

Signed-off-by: Sergey Shtylyov 
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/core/syscopyarea.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/core/syscopyarea.c 
b/drivers/video/fbdev/core/syscopyarea.c
index c1eda31909682..7b8bd3a2bedc5 100644
--- a/drivers/video/fbdev/core/syscopyarea.c
+++ b/drivers/video/fbdev/core/syscopyarea.c
@@ -316,7 +316,7 @@ void sys_copyarea(struct fb_info *p, const struct 
fb_copyarea *area)
 {
u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
u32 height = area->height, width = area->width;
-   unsigned long const bits_per_line = p->fix.line_length*8u;
+   unsigned int const bits_per_line = p->fix.line_length * 8u;
unsigned long *base = NULL;
int bits = BITS_PER_LONG, bytes = bits >> 3;
unsigned dst_idx = 0, src_idx = 0, rev_copy = 0;
-- 
2.42.0



[PATCH AUTOSEL 5.10 10/16] fbdev: core: cfbcopyarea: fix sloppy typing

2023-10-29 Thread Sasha Levin
From: Sergey Shtylyov 

[ Upstream commit 7f33df94cf0156f64eee9509bd9b4a178990f613 ]

In cfb_copyarea(), the local variable bits_per_line is needlessly typed as
*unsigned long* -- which is a 32-bit type on the 32-bit arches and a 64-bit
type on the 64-bit arches; that variable's value is derived from the __u32
typed fb_fix_screeninfo::line_length field (multiplied by 8u) and a 32-bit
*unsigned int* type should still be enough to store the # of bits per line.

Found by Linux Verification Center (linuxtesting.org) with the Svace static
analysis tool.

Signed-off-by: Sergey Shtylyov 
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/core/cfbcopyarea.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/core/cfbcopyarea.c 
b/drivers/video/fbdev/core/cfbcopyarea.c
index 6d4bfeecee350..5b80bf3dae504 100644
--- a/drivers/video/fbdev/core/cfbcopyarea.c
+++ b/drivers/video/fbdev/core/cfbcopyarea.c
@@ -382,7 +382,7 @@ void cfb_copyarea(struct fb_info *p, const struct 
fb_copyarea *area)
 {
u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
u32 height = area->height, width = area->width;
-   unsigned long const bits_per_line = p->fix.line_length*8u;
+   unsigned int const bits_per_line = p->fix.line_length * 8u;
unsigned long __iomem *base = NULL;
int bits = BITS_PER_LONG, bytes = bits >> 3;
unsigned dst_idx = 0, src_idx = 0, rev_copy = 0;
-- 
2.42.0



[PATCH AUTOSEL 5.10 09/16] fbdev: uvesafb: Call cn_del_callback() at the end of uvesafb_exit()

2023-10-29 Thread Sasha Levin
From: Jorge Maidana 

[ Upstream commit 1022e7e2f40574c74ed32c3811b03d26b0b81daf ]

Delete the v86d netlink only after all the VBE tasks have been
completed.

Fixes initial state restore on module unload:
uvesafb: VBE state restore call failed (eax=0x4f04, err=-19)

Signed-off-by: Jorge Maidana 
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/uvesafb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c
index 661f12742e4f0..d999a7cdb5409 100644
--- a/drivers/video/fbdev/uvesafb.c
+++ b/drivers/video/fbdev/uvesafb.c
@@ -1933,10 +1933,10 @@ static void uvesafb_exit(void)
}
}
 
-   cn_del_callback(&uvesafb_cn_id);
driver_remove_file(&uvesafb_driver.driver, &driver_attr_v86d);
platform_device_unregister(uvesafb_device);
platform_driver_unregister(&uvesafb_driver);
+   cn_del_callback(&uvesafb_cn_id);
 }
 
 module_exit(uvesafb_exit);
-- 
2.42.0



[PATCH AUTOSEL 5.10 01/16] fbdev: atyfb: only use ioremap_uc() on i386 and ia64

2023-10-29 Thread Sasha Levin
From: Arnd Bergmann 

[ Upstream commit c1a8d1d0edb71dec15c9649cb56866c71c1ecd9e ]

ioremap_uc() is only meaningful on old x86-32 systems with the PAT
extension, and on ia64 with its slightly unconventional ioremap()
behavior, everywhere else this is the same as ioremap() anyway.

Change the only driver that still references ioremap_uc() to only do so
on x86-32/ia64 in order to allow removing that interface at some
point in the future for the other architectures.

On some architectures, ioremap_uc() just returns NULL, changing
the driver to call ioremap() means that they now have a chance
of working correctly.

Signed-off-by: Arnd Bergmann 
Signed-off-by: Baoquan He 
Reviewed-by: Luis Chamberlain 
Cc: Helge Deller 
Cc: Thomas Zimmermann 
Cc: Christophe Leroy 
Cc: linux-fb...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/aty/atyfb_base.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/video/fbdev/aty/atyfb_base.c 
b/drivers/video/fbdev/aty/atyfb_base.c
index c8feff0ee8da9..eb32ff0910d3e 100644
--- a/drivers/video/fbdev/aty/atyfb_base.c
+++ b/drivers/video/fbdev/aty/atyfb_base.c
@@ -3440,11 +3440,15 @@ static int atyfb_setup_generic(struct pci_dev *pdev, 
struct fb_info *info,
}
 
info->fix.mmio_start = raddr;
+#if defined(__i386__) || defined(__ia64__)
/*
 * By using strong UC we force the MTRR to never have an
 * effect on the MMIO region on both non-PAT and PAT systems.
 */
par->ati_regbase = ioremap_uc(info->fix.mmio_start, 0x1000);
+#else
+   par->ati_regbase = ioremap(info->fix.mmio_start, 0x1000);
+#endif
if (par->ati_regbase == NULL)
return -ENOMEM;
 
-- 
2.42.0



[PATCH AUTOSEL 5.15 21/28] fbdev: core: cfbcopyarea: fix sloppy typing

2023-10-29 Thread Sasha Levin
From: Sergey Shtylyov 

[ Upstream commit 7f33df94cf0156f64eee9509bd9b4a178990f613 ]

In cfb_copyarea(), the local variable bits_per_line is needlessly typed as
*unsigned long* -- which is a 32-bit type on the 32-bit arches and a 64-bit
type on the 64-bit arches; that variable's value is derived from the __u32
typed fb_fix_screeninfo::line_length field (multiplied by 8u) and a 32-bit
*unsigned int* type should still be enough to store the # of bits per line.

Found by Linux Verification Center (linuxtesting.org) with the Svace static
analysis tool.

Signed-off-by: Sergey Shtylyov 
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/core/cfbcopyarea.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/core/cfbcopyarea.c 
b/drivers/video/fbdev/core/cfbcopyarea.c
index 6d4bfeecee350..5b80bf3dae504 100644
--- a/drivers/video/fbdev/core/cfbcopyarea.c
+++ b/drivers/video/fbdev/core/cfbcopyarea.c
@@ -382,7 +382,7 @@ void cfb_copyarea(struct fb_info *p, const struct 
fb_copyarea *area)
 {
u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
u32 height = area->height, width = area->width;
-   unsigned long const bits_per_line = p->fix.line_length*8u;
+   unsigned int const bits_per_line = p->fix.line_length * 8u;
unsigned long __iomem *base = NULL;
int bits = BITS_PER_LONG, bytes = bits >> 3;
unsigned dst_idx = 0, src_idx = 0, rev_copy = 0;
-- 
2.42.0



[PATCH AUTOSEL 5.15 22/28] fbdev: core: syscopyarea: fix sloppy typing

2023-10-29 Thread Sasha Levin
From: Sergey Shtylyov 

[ Upstream commit e8e4a470b677511f9d1ad4f3cef32adc1d9a60ca ]

In sys_copyarea(), the local variable bits_per_line is needlessly typed as
*unsigned long* -- which is a 32-bit type on the 32-bit arches and a 64-bit
type on the 64-bit arches; that variable's value is derived from the __u32
typed fb_fix_screeninfo::line_length field (multiplied by 8u) and a 32-bit
*unsigned int* type should still be enough to store the # of bits per line.

Found by Linux Verification Center (linuxtesting.org) with the Svace static
analysis tool.

Signed-off-by: Sergey Shtylyov 
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/core/syscopyarea.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/core/syscopyarea.c 
b/drivers/video/fbdev/core/syscopyarea.c
index c1eda31909682..7b8bd3a2bedc5 100644
--- a/drivers/video/fbdev/core/syscopyarea.c
+++ b/drivers/video/fbdev/core/syscopyarea.c
@@ -316,7 +316,7 @@ void sys_copyarea(struct fb_info *p, const struct 
fb_copyarea *area)
 {
u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
u32 height = area->height, width = area->width;
-   unsigned long const bits_per_line = p->fix.line_length*8u;
+   unsigned int const bits_per_line = p->fix.line_length * 8u;
unsigned long *base = NULL;
int bits = BITS_PER_LONG, bytes = bits >> 3;
unsigned dst_idx = 0, src_idx = 0, rev_copy = 0;
-- 
2.42.0



[PATCH AUTOSEL 5.15 20/28] fbdev: uvesafb: Call cn_del_callback() at the end of uvesafb_exit()

2023-10-29 Thread Sasha Levin
From: Jorge Maidana 

[ Upstream commit 1022e7e2f40574c74ed32c3811b03d26b0b81daf ]

Delete the v86d netlink only after all the VBE tasks have been
completed.

Fixes initial state restore on module unload:
uvesafb: VBE state restore call failed (eax=0x4f04, err=-19)

Signed-off-by: Jorge Maidana 
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/uvesafb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c
index 1f3b7e013568c..3a285af76f7ed 100644
--- a/drivers/video/fbdev/uvesafb.c
+++ b/drivers/video/fbdev/uvesafb.c
@@ -1935,10 +1935,10 @@ static void uvesafb_exit(void)
}
}
 
-   cn_del_callback(&uvesafb_cn_id);
driver_remove_file(&uvesafb_driver.driver, &driver_attr_v86d);
platform_device_unregister(uvesafb_device);
platform_driver_unregister(&uvesafb_driver);
+   cn_del_callback(&uvesafb_cn_id);
 }
 
 module_exit(uvesafb_exit);
-- 
2.42.0



[PATCH AUTOSEL 5.15 19/28] drm/ttm: Reorder sys manager cleanup step

2023-10-29 Thread Sasha Levin
From: Karolina Stolarek 

[ Upstream commit 3b401e30c249849d803de6c332dad2a595a58658 ]

With the current cleanup flow, we could trigger a NULL pointer
dereference if there is a delayed destruction of a BO with a
system resource that gets executed on drain_workqueue() call,
as we attempt to free a resource using an already released
resource manager.

Remove the device from the device list and drain its workqueue
before releasing the system domain manager in ttm_device_fini().

Signed-off-by: Karolina Stolarek 
Reviewed-by: Christian König 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20231016121525.2237838-1-karolina.stola...@intel.com
Signed-off-by: Christian König 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/ttm/ttm_device.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_device.c b/drivers/gpu/drm/ttm/ttm_device.c
index 2df59b3c2ea16..291cdd893fc50 100644
--- a/drivers/gpu/drm/ttm/ttm_device.c
+++ b/drivers/gpu/drm/ttm/ttm_device.c
@@ -234,10 +234,6 @@ void ttm_device_fini(struct ttm_device *bdev)
struct ttm_resource_manager *man;
unsigned i;
 
-   man = ttm_manager_type(bdev, TTM_PL_SYSTEM);
-   ttm_resource_manager_set_used(man, false);
-   ttm_set_driver_manager(bdev, TTM_PL_SYSTEM, NULL);
-
mutex_lock(&ttm_global_mutex);
list_del(&bdev->device_list);
mutex_unlock(&ttm_global_mutex);
@@ -247,6 +243,10 @@ void ttm_device_fini(struct ttm_device *bdev)
if (ttm_bo_delayed_delete(bdev, true))
pr_debug("Delayed destroy list was clean\n");
 
+   man = ttm_manager_type(bdev, TTM_PL_SYSTEM);
+   ttm_resource_manager_set_used(man, false);
+   ttm_set_driver_manager(bdev, TTM_PL_SYSTEM, NULL);
+
spin_lock(&bdev->lru_lock);
for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i)
if (list_empty(&man->lru[0]))
-- 
2.42.0



Re: [PATCH 1/8] drm/loongson: Introduce a minimal support for Loongson VBIOS

2023-10-29 Thread Dmitry Baryshkov
On Sun, 29 Oct 2023 at 21:46, Sui Jingfeng  wrote:
>
> Because some boards are equipped with non-transparent display bridges,
> which need the VBIOS to provided parameters.
>
> Signed-off-by: Sui Jingfeng 
> ---
>  drivers/gpu/drm/loongson/Makefile  |   3 +-
>  drivers/gpu/drm/loongson/loongson_device.c |   4 +
>  drivers/gpu/drm/loongson/loongson_vbios.c  | 420 +
>  drivers/gpu/drm/loongson/loongson_vbios.h  |  59 +++
>  drivers/gpu/drm/loongson/lsdc_drv.c|   4 +
>  drivers/gpu/drm/loongson/lsdc_drv.h|   8 +
>  6 files changed, 497 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/loongson/loongson_vbios.c
>  create mode 100644 drivers/gpu/drm/loongson/loongson_vbios.h
>
> diff --git a/drivers/gpu/drm/loongson/Makefile 
> b/drivers/gpu/drm/loongson/Makefile
> index 91e72bd900c1..bef00b2c5569 100644
> --- a/drivers/gpu/drm/loongson/Makefile
> +++ b/drivers/gpu/drm/loongson/Makefile
> @@ -17,6 +17,7 @@ loongson-y := \
> lsdc_ttm.o
>
>  loongson-y += loongson_device.o \
> - loongson_module.o
> + loongson_module.o \
> + loongson_vbios.o
>
>  obj-$(CONFIG_DRM_LOONGSON) += loongson.o
> diff --git a/drivers/gpu/drm/loongson/loongson_device.c 
> b/drivers/gpu/drm/loongson/loongson_device.c
> index 9986c8a2a255..64096ad5466e 100644
> --- a/drivers/gpu/drm/loongson/loongson_device.c
> +++ b/drivers/gpu/drm/loongson/loongson_device.c
> @@ -7,6 +7,8 @@
>
>  #include "lsdc_drv.h"
>
> +extern struct loongson_vbios __loongson_vbios;

Usually names with two underscores in front of them are reserved for
the compiler internals or low level stuff.

> +
>  static const struct lsdc_kms_funcs ls7a1000_kms_funcs = {
> .create_i2c = lsdc_create_i2c_chan,
> .irq_handler = ls7a1000_dc_irq_handler,
> @@ -53,6 +55,7 @@ static const struct loongson_gfx_desc ls7a1000_gfx = {
> .reg_size = 8,
> },
> },
> +   .vbios = &__loongson_vbios,
> .chip_id = CHIP_LS7A1000,
> .model = "LS7A1000 bridge chipset",
>  };
> @@ -85,6 +88,7 @@ static const struct loongson_gfx_desc ls7a2000_gfx = {
> .reg_size = 8,
> },
> },
> +   .vbios = &__loongson_vbios,
> .chip_id = CHIP_LS7A2000,
> .model = "LS7A2000 bridge chipset",
>  };
> diff --git a/drivers/gpu/drm/loongson/loongson_vbios.c 
> b/drivers/gpu/drm/loongson/loongson_vbios.c
> new file mode 100644
> index ..dc304018779e
> --- /dev/null
> +++ b/drivers/gpu/drm/loongson/loongson_vbios.c
> @@ -0,0 +1,420 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2023 Loongson Technology Corporation Limited
> + */
> +
> +#include 
> +#include 
> +
> +#include "loongson_vbios.h"
> +#include "lsdc_drv.h"
> +
> +#define LOONGSON_VBIOS_HEADER_STR   "Loongson-VBIOS"
> +/* Legacy VBIOS is stored at offset 0 */
> +#define LOONGSON_VBIOS_LEGACY_OFFSET 0
> +/* The size of legacy VBIOS is 1 KiB */
> +#define LOONGSON_VBIOS_LEGACY_SIZE   0x000400
> +
> +/* Data Control Block of Newer version of the VBIOS started at here */
> +#define LOONGSON_VBIOS_DCB_OFFSET0x006000
> +/* The last 1 MiB of the VRAM contains the raw VBIOS data */
> +#define LOONGSON_VBIOS_BLOCK_OFFSET  0x10
> +/* Only 256KB of the 1 MiB are used for now */
> +#define LOONGSON_VBIOS_BLOCK_SIZE0x04
> +
> +struct loongson_vbios __loongson_vbios;
> +
> +/*
> + * vbios data control block is a kind of metadata, which is used to index
> + * real hardware device data block.
> + */
> +struct loongson_vbios_dcb {
> +   u16 type;/* what is it */
> +   u8 version;  /* version of it, useless */
> +   u8 id;   /* index (usually same with the display pipe) of the 
> hardware */
> +   u32 offset;  /* the offset of the real data */
> +   u32 size;/* the size of the real data */
> +   u64 ext0;/* for extension purpose */
> +   u64 ext1;/* extra space reserved for future use */
> +} __packed;
> +
> +/*
> + * Loongson-VBIOS Data Block Layout
> + *
> + *
> + * _   0x0
> + *|_|
> + *| |  [0x, 0x0400) : legacy vbios storage
> + *|Not Used Yet |
> + *| |
> + *|-|<--- 0x6000
> + *   +|DCB 0|
> + *   ||-|
> + *   ||DCB 1|
> + *   ||-|  Format of Data Control Blocks
> + *   || One by one, packed  |++
> + *   ||-||  u16 type  |
> + *   ||DCB N|+   ||
> + *   ||-||   ++
> + *   ||  .  ||   | u8 version |
> + *   ||  .  ||   |  u8 index  |
> + *   ||   

[PATCH AUTOSEL 5.15 01/28] fbdev: atyfb: only use ioremap_uc() on i386 and ia64

2023-10-29 Thread Sasha Levin
From: Arnd Bergmann 

[ Upstream commit c1a8d1d0edb71dec15c9649cb56866c71c1ecd9e ]

ioremap_uc() is only meaningful on old x86-32 systems with the PAT
extension, and on ia64 with its slightly unconventional ioremap()
behavior, everywhere else this is the same as ioremap() anyway.

Change the only driver that still references ioremap_uc() to only do so
on x86-32/ia64 in order to allow removing that interface at some
point in the future for the other architectures.

On some architectures, ioremap_uc() just returns NULL, changing
the driver to call ioremap() means that they now have a chance
of working correctly.

Signed-off-by: Arnd Bergmann 
Signed-off-by: Baoquan He 
Reviewed-by: Luis Chamberlain 
Cc: Helge Deller 
Cc: Thomas Zimmermann 
Cc: Christophe Leroy 
Cc: linux-fb...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/aty/atyfb_base.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/video/fbdev/aty/atyfb_base.c 
b/drivers/video/fbdev/aty/atyfb_base.c
index 1aef3d6ebd880..246bf67b32ea0 100644
--- a/drivers/video/fbdev/aty/atyfb_base.c
+++ b/drivers/video/fbdev/aty/atyfb_base.c
@@ -3447,11 +3447,15 @@ static int atyfb_setup_generic(struct pci_dev *pdev, 
struct fb_info *info,
}
 
info->fix.mmio_start = raddr;
+#if defined(__i386__) || defined(__ia64__)
/*
 * By using strong UC we force the MTRR to never have an
 * effect on the MMIO region on both non-PAT and PAT systems.
 */
par->ati_regbase = ioremap_uc(info->fix.mmio_start, 0x1000);
+#else
+   par->ati_regbase = ioremap(info->fix.mmio_start, 0x1000);
+#endif
if (par->ati_regbase == NULL)
return -ENOMEM;
 
-- 
2.42.0



[PATCH AUTOSEL 6.1 39/39] drm/amdgpu: Reserve fences for VM update

2023-10-29 Thread Sasha Levin
From: Felix Kuehling 

[ Upstream commit 316baf09d355aec1179981b6dfe28eba50c5ee5b ]

In amdgpu_dma_buf_move_notify reserve fences for the page table updates
in amdgpu_vm_clear_freed and amdgpu_vm_handle_moved. This fixes a BUG_ON
in dma_resv_add_fence when using SDMA for page table updates.

Signed-off-by: Felix Kuehling 
Reviewed-by: Christian König 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
index 7bd8e33b14be5..e8b3e9520cf6e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
@@ -400,7 +400,10 @@ amdgpu_dma_buf_move_notify(struct dma_buf_attachment 
*attach)
continue;
}
 
-   r = amdgpu_vm_clear_freed(adev, vm, NULL);
+   /* Reserve fences for two SDMA page table updates */
+   r = dma_resv_reserve_fences(resv, 2);
+   if (!r)
+   r = amdgpu_vm_clear_freed(adev, vm, NULL);
if (!r)
r = amdgpu_vm_handle_moved(adev, vm);
 
-- 
2.42.0



[PATCH AUTOSEL 6.1 29/39] gpu/drm: Eliminate DRM_SCHED_PRIORITY_UNSET

2023-10-29 Thread Sasha Levin
From: Luben Tuikov 

[ Upstream commit fa8391ad68c16716e2c06ada397e99ceed2fb647 ]

Eliminate DRM_SCHED_PRIORITY_UNSET, value of -2, whose only user was
amdgpu. Furthermore, eliminate an index bug, in that when amdgpu boots, it
calls drm_sched_entity_init() with DRM_SCHED_PRIORITY_UNSET, which uses it to
index sched->sched_rq[].

Cc: Alex Deucher 
Cc: Christian König 
Signed-off-by: Luben Tuikov 
Acked-by: Alex Deucher 
Link: https://lore.kernel.org/r/20231017035656.8211-2-luben.tui...@amd.com
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 3 ++-
 include/drm/gpu_scheduler.h | 3 +--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
index fdbeafda4e80a..1ed2142a6e7bf 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
@@ -64,7 +64,8 @@ amdgpu_ctx_to_drm_sched_prio(int32_t ctx_prio)
 {
switch (ctx_prio) {
case AMDGPU_CTX_PRIORITY_UNSET:
-   return DRM_SCHED_PRIORITY_UNSET;
+   pr_warn_once("AMD-->DRM context priority value UNSET-->NORMAL");
+   return DRM_SCHED_PRIORITY_NORMAL;
 
case AMDGPU_CTX_PRIORITY_VERY_LOW:
return DRM_SCHED_PRIORITY_MIN;
diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
index 2ae4fd62e01c4..17e7e3145a058 100644
--- a/include/drm/gpu_scheduler.h
+++ b/include/drm/gpu_scheduler.h
@@ -55,8 +55,7 @@ enum drm_sched_priority {
DRM_SCHED_PRIORITY_HIGH,
DRM_SCHED_PRIORITY_KERNEL,
 
-   DRM_SCHED_PRIORITY_COUNT,
-   DRM_SCHED_PRIORITY_UNSET = -2
+   DRM_SCHED_PRIORITY_COUNT
 };
 
 /**
-- 
2.42.0



[PATCH AUTOSEL 6.1 28/39] drm/amdgpu: Unset context priority is now invalid

2023-10-29 Thread Sasha Levin
From: Luben Tuikov 

[ Upstream commit eab0261967aeab528db4d0a51806df8209aec179 ]

A context priority value of AMD_CTX_PRIORITY_UNSET is now invalid--instead of
carrying it around and passing it to the Direct Rendering Manager--and it
becomes AMD_CTX_PRIORITY_NORMAL in amdgpu_ctx_ioctl(), the gateway to context
creation.

Cc: Alex Deucher 
Cc: Christian König 
Signed-off-by: Luben Tuikov 
Acked-by: Alex Deucher 
Link: https://lore.kernel.org/r/20231017035656.8211-1-luben.tui...@amd.com
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
index d2139ac121595..fdbeafda4e80a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
@@ -47,7 +47,6 @@ const unsigned int amdgpu_ctx_num_entities[AMDGPU_HW_IP_NUM] 
= {
 bool amdgpu_ctx_priority_is_valid(int32_t ctx_prio)
 {
switch (ctx_prio) {
-   case AMDGPU_CTX_PRIORITY_UNSET:
case AMDGPU_CTX_PRIORITY_VERY_LOW:
case AMDGPU_CTX_PRIORITY_LOW:
case AMDGPU_CTX_PRIORITY_NORMAL:
@@ -55,6 +54,7 @@ bool amdgpu_ctx_priority_is_valid(int32_t ctx_prio)
case AMDGPU_CTX_PRIORITY_VERY_HIGH:
return true;
default:
+   case AMDGPU_CTX_PRIORITY_UNSET:
return false;
}
 }
-- 
2.42.0



[PATCH AUTOSEL 6.1 26/39] fbdev: core: syscopyarea: fix sloppy typing

2023-10-29 Thread Sasha Levin
From: Sergey Shtylyov 

[ Upstream commit e8e4a470b677511f9d1ad4f3cef32adc1d9a60ca ]

In sys_copyarea(), the local variable bits_per_line is needlessly typed as
*unsigned long* -- which is a 32-bit type on the 32-bit arches and a 64-bit
type on the 64-bit arches; that variable's value is derived from the __u32
typed fb_fix_screeninfo::line_length field (multiplied by 8u) and a 32-bit
*unsigned int* type should still be enough to store the # of bits per line.

Found by Linux Verification Center (linuxtesting.org) with the Svace static
analysis tool.

Signed-off-by: Sergey Shtylyov 
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/core/syscopyarea.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/core/syscopyarea.c 
b/drivers/video/fbdev/core/syscopyarea.c
index c1eda31909682..7b8bd3a2bedc5 100644
--- a/drivers/video/fbdev/core/syscopyarea.c
+++ b/drivers/video/fbdev/core/syscopyarea.c
@@ -316,7 +316,7 @@ void sys_copyarea(struct fb_info *p, const struct 
fb_copyarea *area)
 {
u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
u32 height = area->height, width = area->width;
-   unsigned long const bits_per_line = p->fix.line_length*8u;
+   unsigned int const bits_per_line = p->fix.line_length * 8u;
unsigned long *base = NULL;
int bits = BITS_PER_LONG, bytes = bits >> 3;
unsigned dst_idx = 0, src_idx = 0, rev_copy = 0;
-- 
2.42.0



[PATCH AUTOSEL 6.1 25/39] fbdev: core: cfbcopyarea: fix sloppy typing

2023-10-29 Thread Sasha Levin
From: Sergey Shtylyov 

[ Upstream commit 7f33df94cf0156f64eee9509bd9b4a178990f613 ]

In cfb_copyarea(), the local variable bits_per_line is needlessly typed as
*unsigned long* -- which is a 32-bit type on the 32-bit arches and a 64-bit
type on the 64-bit arches; that variable's value is derived from the __u32
typed fb_fix_screeninfo::line_length field (multiplied by 8u) and a 32-bit
*unsigned int* type should still be enough to store the # of bits per line.

Found by Linux Verification Center (linuxtesting.org) with the Svace static
analysis tool.

Signed-off-by: Sergey Shtylyov 
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/core/cfbcopyarea.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/core/cfbcopyarea.c 
b/drivers/video/fbdev/core/cfbcopyarea.c
index 6d4bfeecee350..5b80bf3dae504 100644
--- a/drivers/video/fbdev/core/cfbcopyarea.c
+++ b/drivers/video/fbdev/core/cfbcopyarea.c
@@ -382,7 +382,7 @@ void cfb_copyarea(struct fb_info *p, const struct 
fb_copyarea *area)
 {
u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
u32 height = area->height, width = area->width;
-   unsigned long const bits_per_line = p->fix.line_length*8u;
+   unsigned int const bits_per_line = p->fix.line_length * 8u;
unsigned long __iomem *base = NULL;
int bits = BITS_PER_LONG, bytes = bits >> 3;
unsigned dst_idx = 0, src_idx = 0, rev_copy = 0;
-- 
2.42.0



[PATCH AUTOSEL 6.1 24/39] fbdev: uvesafb: Call cn_del_callback() at the end of uvesafb_exit()

2023-10-29 Thread Sasha Levin
From: Jorge Maidana 

[ Upstream commit 1022e7e2f40574c74ed32c3811b03d26b0b81daf ]

Delete the v86d netlink only after all the VBE tasks have been
completed.

Fixes initial state restore on module unload:
uvesafb: VBE state restore call failed (eax=0x4f04, err=-19)

Signed-off-by: Jorge Maidana 
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/uvesafb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c
index 0e3cabbec4b40..a85463db9f986 100644
--- a/drivers/video/fbdev/uvesafb.c
+++ b/drivers/video/fbdev/uvesafb.c
@@ -1935,10 +1935,10 @@ static void uvesafb_exit(void)
}
}
 
-   cn_del_callback(&uvesafb_cn_id);
driver_remove_file(&uvesafb_driver.driver, &driver_attr_v86d);
platform_device_unregister(uvesafb_device);
platform_driver_unregister(&uvesafb_driver);
+   cn_del_callback(&uvesafb_cn_id);
 }
 
 module_exit(uvesafb_exit);
-- 
2.42.0



[PATCH AUTOSEL 6.1 23/39] fbdev: omapfb: fix some error codes

2023-10-29 Thread Sasha Levin
From: Dan Carpenter 

[ Upstream commit dc608db793731426938baa2f0e75a4a3cce5f5cf ]

Return negative -ENXIO instead of positive ENXIO.

Signed-off-by: Dan Carpenter 
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/omap/omapfb_main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/omap/omapfb_main.c 
b/drivers/video/fbdev/omap/omapfb_main.c
index 17cda57656838..5ea7c52baa5a8 100644
--- a/drivers/video/fbdev/omap/omapfb_main.c
+++ b/drivers/video/fbdev/omap/omapfb_main.c
@@ -1643,13 +1643,13 @@ static int omapfb_do_probe(struct platform_device *pdev,
}
fbdev->int_irq = platform_get_irq(pdev, 0);
if (fbdev->int_irq < 0) {
-   r = ENXIO;
+   r = -ENXIO;
goto cleanup;
}
 
fbdev->ext_irq = platform_get_irq(pdev, 1);
if (fbdev->ext_irq < 0) {
-   r = ENXIO;
+   r = -ENXIO;
goto cleanup;
}
 
-- 
2.42.0



[PATCH AUTOSEL 6.1 22/39] drm/ttm: Reorder sys manager cleanup step

2023-10-29 Thread Sasha Levin
From: Karolina Stolarek 

[ Upstream commit 3b401e30c249849d803de6c332dad2a595a58658 ]

With the current cleanup flow, we could trigger a NULL pointer
dereference if there is a delayed destruction of a BO with a
system resource that gets executed on drain_workqueue() call,
as we attempt to free a resource using an already released
resource manager.

Remove the device from the device list and drain its workqueue
before releasing the system domain manager in ttm_device_fini().

Signed-off-by: Karolina Stolarek 
Reviewed-by: Christian König 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20231016121525.2237838-1-karolina.stola...@intel.com
Signed-off-by: Christian König 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/ttm/ttm_device.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_device.c b/drivers/gpu/drm/ttm/ttm_device.c
index b84f74807ca13..ec9ddaad56a05 100644
--- a/drivers/gpu/drm/ttm/ttm_device.c
+++ b/drivers/gpu/drm/ttm/ttm_device.c
@@ -239,10 +239,6 @@ void ttm_device_fini(struct ttm_device *bdev)
struct ttm_resource_manager *man;
unsigned i;
 
-   man = ttm_manager_type(bdev, TTM_PL_SYSTEM);
-   ttm_resource_manager_set_used(man, false);
-   ttm_set_driver_manager(bdev, TTM_PL_SYSTEM, NULL);
-
mutex_lock(&ttm_global_mutex);
list_del(&bdev->device_list);
mutex_unlock(&ttm_global_mutex);
@@ -252,6 +248,10 @@ void ttm_device_fini(struct ttm_device *bdev)
if (ttm_bo_delayed_delete(bdev, true))
pr_debug("Delayed destroy list was clean\n");
 
+   man = ttm_manager_type(bdev, TTM_PL_SYSTEM);
+   ttm_resource_manager_set_used(man, false);
+   ttm_set_driver_manager(bdev, TTM_PL_SYSTEM, NULL);
+
spin_lock(&bdev->lru_lock);
for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i)
if (list_empty(&man->lru[0]))
-- 
2.42.0



[PATCH AUTOSEL 6.1 01/39] fbdev: atyfb: only use ioremap_uc() on i386 and ia64

2023-10-29 Thread Sasha Levin
From: Arnd Bergmann 

[ Upstream commit c1a8d1d0edb71dec15c9649cb56866c71c1ecd9e ]

ioremap_uc() is only meaningful on old x86-32 systems with the PAT
extension, and on ia64 with its slightly unconventional ioremap()
behavior, everywhere else this is the same as ioremap() anyway.

Change the only driver that still references ioremap_uc() to only do so
on x86-32/ia64 in order to allow removing that interface at some
point in the future for the other architectures.

On some architectures, ioremap_uc() just returns NULL, changing
the driver to call ioremap() means that they now have a chance
of working correctly.

Signed-off-by: Arnd Bergmann 
Signed-off-by: Baoquan He 
Reviewed-by: Luis Chamberlain 
Cc: Helge Deller 
Cc: Thomas Zimmermann 
Cc: Christophe Leroy 
Cc: linux-fb...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/aty/atyfb_base.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/video/fbdev/aty/atyfb_base.c 
b/drivers/video/fbdev/aty/atyfb_base.c
index b3463d1371520..faaa64fa5dfe9 100644
--- a/drivers/video/fbdev/aty/atyfb_base.c
+++ b/drivers/video/fbdev/aty/atyfb_base.c
@@ -3447,11 +3447,15 @@ static int atyfb_setup_generic(struct pci_dev *pdev, 
struct fb_info *info,
}
 
info->fix.mmio_start = raddr;
+#if defined(__i386__) || defined(__ia64__)
/*
 * By using strong UC we force the MTRR to never have an
 * effect on the MMIO region on both non-PAT and PAT systems.
 */
par->ati_regbase = ioremap_uc(info->fix.mmio_start, 0x1000);
+#else
+   par->ati_regbase = ioremap(info->fix.mmio_start, 0x1000);
+#endif
if (par->ati_regbase == NULL)
return -ENOMEM;
 
-- 
2.42.0



[PATCH AUTOSEL 6.5 52/52] drm/amdgpu: Reserve fences for VM update

2023-10-29 Thread Sasha Levin
From: Felix Kuehling 

[ Upstream commit 316baf09d355aec1179981b6dfe28eba50c5ee5b ]

In amdgpu_dma_buf_move_notify reserve fences for the page table updates
in amdgpu_vm_clear_freed and amdgpu_vm_handle_moved. This fixes a BUG_ON
in dma_resv_add_fence when using SDMA for page table updates.

Signed-off-by: Felix Kuehling 
Reviewed-by: Christian König 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
index 12210598e5b8e..ba3a87cb88ccc 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
@@ -403,7 +403,10 @@ amdgpu_dma_buf_move_notify(struct dma_buf_attachment 
*attach)
continue;
}
 
-   r = amdgpu_vm_clear_freed(adev, vm, NULL);
+   /* Reserve fences for two SDMA page table updates */
+   r = dma_resv_reserve_fences(resv, 2);
+   if (!r)
+   r = amdgpu_vm_clear_freed(adev, vm, NULL);
if (!r)
r = amdgpu_vm_handle_moved(adev, vm);
 
-- 
2.42.0



[PATCH AUTOSEL 6.5 50/52] Revert "accel/ivpu: Use cached buffers for FW loading"

2023-10-29 Thread Sasha Levin
From: Stanislaw Gruszka 

[ Upstream commit 610b5d219d1ccac8064556310cc0e62e3c202389 ]

This reverts commit 645d694559cab36fe6a57c717efcfa27d9321396.

The commit cause issues with memory access from the device side.
Switch back to write-combined memory mappings until the issues
will be properly addressed.

Add extra wmb() needed when boot_params->save_restore_ret_address() is
modified.

Reviewed-by: Karol Wachowski 
Signed-off-by: Stanislaw Gruszka 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20231017121353.532466-1-stanislaw.grus...@linux.intel.com
Signed-off-by: Sasha Levin 
---
 drivers/accel/ivpu/ivpu_fw.c  | 9 -
 drivers/accel/ivpu/ivpu_gem.h | 5 -
 2 files changed, 4 insertions(+), 10 deletions(-)

diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c
index 93c69aaa6218d..34e4026c77589 100644
--- a/drivers/accel/ivpu/ivpu_fw.c
+++ b/drivers/accel/ivpu/ivpu_fw.c
@@ -195,8 +195,7 @@ static int ivpu_fw_mem_init(struct ivpu_device *vdev)
if (ret)
return ret;
 
-   fw->mem = ivpu_bo_alloc_internal(vdev, fw->runtime_addr, 
fw->runtime_size,
-DRM_IVPU_BO_CACHED | 
DRM_IVPU_BO_NOSNOOP);
+   fw->mem = ivpu_bo_alloc_internal(vdev, fw->runtime_addr, 
fw->runtime_size, DRM_IVPU_BO_WC);
if (!fw->mem) {
ivpu_err(vdev, "Failed to allocate firmware runtime memory\n");
return -ENOMEM;
@@ -273,7 +272,7 @@ int ivpu_fw_load(struct ivpu_device *vdev)
memset(start, 0, size);
}
 
-   clflush_cache_range(fw->mem->kvaddr, fw->mem->base.size);
+   wmb(); /* Flush WC buffers after writing fw->mem */
 
return 0;
 }
@@ -375,7 +374,7 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, 
struct vpu_boot_params
if (!ivpu_fw_is_cold_boot(vdev)) {
boot_params->save_restore_ret_address = 0;
vdev->pm->is_warmboot = true;
-   clflush_cache_range(vdev->fw->mem->kvaddr, SZ_4K);
+   wmb(); /* Flush WC buffers after writing 
save_restore_ret_address */
return;
}
 
@@ -430,7 +429,7 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, 
struct vpu_boot_params
boot_params->punit_telemetry_sram_size = 
ivpu_hw_reg_telemetry_size_get(vdev);
boot_params->vpu_telemetry_enable = 
ivpu_hw_reg_telemetry_enable_get(vdev);
 
-   clflush_cache_range(vdev->fw->mem->kvaddr, SZ_4K);
+   wmb(); /* Flush WC buffers after writing bootparams */
 
ivpu_fw_boot_params_print(vdev, boot_params);
 }
diff --git a/drivers/accel/ivpu/ivpu_gem.h b/drivers/accel/ivpu/ivpu_gem.h
index f4130586ff1b2..6b0ceda5f2537 100644
--- a/drivers/accel/ivpu/ivpu_gem.h
+++ b/drivers/accel/ivpu/ivpu_gem.h
@@ -8,8 +8,6 @@
 #include 
 #include 
 
-#define DRM_IVPU_BO_NOSNOOP   0x1000
-
 struct dma_buf;
 struct ivpu_bo_ops;
 struct ivpu_file_priv;
@@ -85,9 +83,6 @@ static inline u32 ivpu_bo_cache_mode(struct ivpu_bo *bo)
 
 static inline bool ivpu_bo_is_snooped(struct ivpu_bo *bo)
 {
-   if (bo->flags & DRM_IVPU_BO_NOSNOOP)
-   return false;
-
return ivpu_bo_cache_mode(bo) == DRM_IVPU_BO_CACHED;
 }
 
-- 
2.42.0



[PATCH AUTOSEL 6.5 39/52] gpu/drm: Eliminate DRM_SCHED_PRIORITY_UNSET

2023-10-29 Thread Sasha Levin
From: Luben Tuikov 

[ Upstream commit fa8391ad68c16716e2c06ada397e99ceed2fb647 ]

Eliminate DRM_SCHED_PRIORITY_UNSET, value of -2, whose only user was
amdgpu. Furthermore, eliminate an index bug, in that when amdgpu boots, it
calls drm_sched_entity_init() with DRM_SCHED_PRIORITY_UNSET, which uses it to
index sched->sched_rq[].

Cc: Alex Deucher 
Cc: Christian König 
Signed-off-by: Luben Tuikov 
Acked-by: Alex Deucher 
Link: https://lore.kernel.org/r/20231017035656.8211-2-luben.tui...@amd.com
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 3 ++-
 include/drm/gpu_scheduler.h | 3 +--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
index 092962b93064f..aac52d9754e6d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
@@ -64,7 +64,8 @@ amdgpu_ctx_to_drm_sched_prio(int32_t ctx_prio)
 {
switch (ctx_prio) {
case AMDGPU_CTX_PRIORITY_UNSET:
-   return DRM_SCHED_PRIORITY_UNSET;
+   pr_warn_once("AMD-->DRM context priority value UNSET-->NORMAL");
+   return DRM_SCHED_PRIORITY_NORMAL;
 
case AMDGPU_CTX_PRIORITY_VERY_LOW:
return DRM_SCHED_PRIORITY_MIN;
diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
index f9544d9b670d3..ac65f0626cfc9 100644
--- a/include/drm/gpu_scheduler.h
+++ b/include/drm/gpu_scheduler.h
@@ -68,8 +68,7 @@ enum drm_sched_priority {
DRM_SCHED_PRIORITY_HIGH,
DRM_SCHED_PRIORITY_KERNEL,
 
-   DRM_SCHED_PRIORITY_COUNT,
-   DRM_SCHED_PRIORITY_UNSET = -2
+   DRM_SCHED_PRIORITY_COUNT
 };
 
 /* Used to chose between FIFO and RR jobs scheduling */
-- 
2.42.0



[PATCH AUTOSEL 6.5 38/52] drm/amdgpu: Unset context priority is now invalid

2023-10-29 Thread Sasha Levin
From: Luben Tuikov 

[ Upstream commit eab0261967aeab528db4d0a51806df8209aec179 ]

A context priority value of AMD_CTX_PRIORITY_UNSET is now invalid--instead of
carrying it around and passing it to the Direct Rendering Manager--and it
becomes AMD_CTX_PRIORITY_NORMAL in amdgpu_ctx_ioctl(), the gateway to context
creation.

Cc: Alex Deucher 
Cc: Christian König 
Signed-off-by: Luben Tuikov 
Acked-by: Alex Deucher 
Link: https://lore.kernel.org/r/20231017035656.8211-1-luben.tui...@amd.com
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
index 0dc9c655c4fbd..092962b93064f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
@@ -47,7 +47,6 @@ const unsigned int amdgpu_ctx_num_entities[AMDGPU_HW_IP_NUM] 
= {
 bool amdgpu_ctx_priority_is_valid(int32_t ctx_prio)
 {
switch (ctx_prio) {
-   case AMDGPU_CTX_PRIORITY_UNSET:
case AMDGPU_CTX_PRIORITY_VERY_LOW:
case AMDGPU_CTX_PRIORITY_LOW:
case AMDGPU_CTX_PRIORITY_NORMAL:
@@ -55,6 +54,7 @@ bool amdgpu_ctx_priority_is_valid(int32_t ctx_prio)
case AMDGPU_CTX_PRIORITY_VERY_HIGH:
return true;
default:
+   case AMDGPU_CTX_PRIORITY_UNSET:
return false;
}
 }
-- 
2.42.0



[PATCH AUTOSEL 6.5 35/52] fbdev: core: syscopyarea: fix sloppy typing

2023-10-29 Thread Sasha Levin
From: Sergey Shtylyov 

[ Upstream commit e8e4a470b677511f9d1ad4f3cef32adc1d9a60ca ]

In sys_copyarea(), the local variable bits_per_line is needlessly typed as
*unsigned long* -- which is a 32-bit type on the 32-bit arches and a 64-bit
type on the 64-bit arches; that variable's value is derived from the __u32
typed fb_fix_screeninfo::line_length field (multiplied by 8u) and a 32-bit
*unsigned int* type should still be enough to store the # of bits per line.

Found by Linux Verification Center (linuxtesting.org) with the Svace static
analysis tool.

Signed-off-by: Sergey Shtylyov 
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/core/syscopyarea.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/core/syscopyarea.c 
b/drivers/video/fbdev/core/syscopyarea.c
index c1eda31909682..7b8bd3a2bedc5 100644
--- a/drivers/video/fbdev/core/syscopyarea.c
+++ b/drivers/video/fbdev/core/syscopyarea.c
@@ -316,7 +316,7 @@ void sys_copyarea(struct fb_info *p, const struct 
fb_copyarea *area)
 {
u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
u32 height = area->height, width = area->width;
-   unsigned long const bits_per_line = p->fix.line_length*8u;
+   unsigned int const bits_per_line = p->fix.line_length * 8u;
unsigned long *base = NULL;
int bits = BITS_PER_LONG, bytes = bits >> 3;
unsigned dst_idx = 0, src_idx = 0, rev_copy = 0;
-- 
2.42.0



[PATCH AUTOSEL 6.5 34/52] fbdev: core: cfbcopyarea: fix sloppy typing

2023-10-29 Thread Sasha Levin
From: Sergey Shtylyov 

[ Upstream commit 7f33df94cf0156f64eee9509bd9b4a178990f613 ]

In cfb_copyarea(), the local variable bits_per_line is needlessly typed as
*unsigned long* -- which is a 32-bit type on the 32-bit arches and a 64-bit
type on the 64-bit arches; that variable's value is derived from the __u32
typed fb_fix_screeninfo::line_length field (multiplied by 8u) and a 32-bit
*unsigned int* type should still be enough to store the # of bits per line.

Found by Linux Verification Center (linuxtesting.org) with the Svace static
analysis tool.

Signed-off-by: Sergey Shtylyov 
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/core/cfbcopyarea.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/core/cfbcopyarea.c 
b/drivers/video/fbdev/core/cfbcopyarea.c
index 6d4bfeecee350..5b80bf3dae504 100644
--- a/drivers/video/fbdev/core/cfbcopyarea.c
+++ b/drivers/video/fbdev/core/cfbcopyarea.c
@@ -382,7 +382,7 @@ void cfb_copyarea(struct fb_info *p, const struct 
fb_copyarea *area)
 {
u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
u32 height = area->height, width = area->width;
-   unsigned long const bits_per_line = p->fix.line_length*8u;
+   unsigned int const bits_per_line = p->fix.line_length * 8u;
unsigned long __iomem *base = NULL;
int bits = BITS_PER_LONG, bytes = bits >> 3;
unsigned dst_idx = 0, src_idx = 0, rev_copy = 0;
-- 
2.42.0



[PATCH AUTOSEL 6.5 33/52] fbdev: uvesafb: Call cn_del_callback() at the end of uvesafb_exit()

2023-10-29 Thread Sasha Levin
From: Jorge Maidana 

[ Upstream commit 1022e7e2f40574c74ed32c3811b03d26b0b81daf ]

Delete the v86d netlink only after all the VBE tasks have been
completed.

Fixes initial state restore on module unload:
uvesafb: VBE state restore call failed (eax=0x4f04, err=-19)

Signed-off-by: Jorge Maidana 
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/uvesafb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c
index 78d85dae8ec80..c4559768f00f6 100644
--- a/drivers/video/fbdev/uvesafb.c
+++ b/drivers/video/fbdev/uvesafb.c
@@ -1931,10 +1931,10 @@ static void uvesafb_exit(void)
}
}
 
-   cn_del_callback(&uvesafb_cn_id);
driver_remove_file(&uvesafb_driver.driver, &driver_attr_v86d);
platform_device_unregister(uvesafb_device);
platform_driver_unregister(&uvesafb_driver);
+   cn_del_callback(&uvesafb_cn_id);
 }
 
 module_exit(uvesafb_exit);
-- 
2.42.0



[PATCH AUTOSEL 6.5 32/52] fbdev: omapfb: fix some error codes

2023-10-29 Thread Sasha Levin
From: Dan Carpenter 

[ Upstream commit dc608db793731426938baa2f0e75a4a3cce5f5cf ]

Return negative -ENXIO instead of positive ENXIO.

Signed-off-by: Dan Carpenter 
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/omap/omapfb_main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/omap/omapfb_main.c 
b/drivers/video/fbdev/omap/omapfb_main.c
index ad65554b33c35..0be95b4e14fdb 100644
--- a/drivers/video/fbdev/omap/omapfb_main.c
+++ b/drivers/video/fbdev/omap/omapfb_main.c
@@ -1648,13 +1648,13 @@ static int omapfb_do_probe(struct platform_device *pdev,
}
fbdev->int_irq = platform_get_irq(pdev, 0);
if (fbdev->int_irq < 0) {
-   r = ENXIO;
+   r = -ENXIO;
goto cleanup;
}
 
fbdev->ext_irq = platform_get_irq(pdev, 1);
if (fbdev->ext_irq < 0) {
-   r = ENXIO;
+   r = -ENXIO;
goto cleanup;
}
 
-- 
2.42.0



[PATCH AUTOSEL 6.5 31/52] drm/ttm: Reorder sys manager cleanup step

2023-10-29 Thread Sasha Levin
From: Karolina Stolarek 

[ Upstream commit 3b401e30c249849d803de6c332dad2a595a58658 ]

With the current cleanup flow, we could trigger a NULL pointer
dereference if there is a delayed destruction of a BO with a
system resource that gets executed on drain_workqueue() call,
as we attempt to free a resource using an already released
resource manager.

Remove the device from the device list and drain its workqueue
before releasing the system domain manager in ttm_device_fini().

Signed-off-by: Karolina Stolarek 
Reviewed-by: Christian König 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20231016121525.2237838-1-karolina.stola...@intel.com
Signed-off-by: Christian König 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/ttm/ttm_device.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_device.c b/drivers/gpu/drm/ttm/ttm_device.c
index 7726a72befc54..d48b39132b324 100644
--- a/drivers/gpu/drm/ttm/ttm_device.c
+++ b/drivers/gpu/drm/ttm/ttm_device.c
@@ -232,10 +232,6 @@ void ttm_device_fini(struct ttm_device *bdev)
struct ttm_resource_manager *man;
unsigned i;
 
-   man = ttm_manager_type(bdev, TTM_PL_SYSTEM);
-   ttm_resource_manager_set_used(man, false);
-   ttm_set_driver_manager(bdev, TTM_PL_SYSTEM, NULL);
-
mutex_lock(&ttm_global_mutex);
list_del(&bdev->device_list);
mutex_unlock(&ttm_global_mutex);
@@ -243,6 +239,10 @@ void ttm_device_fini(struct ttm_device *bdev)
drain_workqueue(bdev->wq);
destroy_workqueue(bdev->wq);
 
+   man = ttm_manager_type(bdev, TTM_PL_SYSTEM);
+   ttm_resource_manager_set_used(man, false);
+   ttm_set_driver_manager(bdev, TTM_PL_SYSTEM, NULL);
+
spin_lock(&bdev->lru_lock);
for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i)
if (list_empty(&man->lru[0]))
-- 
2.42.0



[PATCH AUTOSEL 6.5 01/52] fbdev: atyfb: only use ioremap_uc() on i386 and ia64

2023-10-29 Thread Sasha Levin
From: Arnd Bergmann 

[ Upstream commit c1a8d1d0edb71dec15c9649cb56866c71c1ecd9e ]

ioremap_uc() is only meaningful on old x86-32 systems with the PAT
extension, and on ia64 with its slightly unconventional ioremap()
behavior, everywhere else this is the same as ioremap() anyway.

Change the only driver that still references ioremap_uc() to only do so
on x86-32/ia64 in order to allow removing that interface at some
point in the future for the other architectures.

On some architectures, ioremap_uc() just returns NULL, changing
the driver to call ioremap() means that they now have a chance
of working correctly.

Signed-off-by: Arnd Bergmann 
Signed-off-by: Baoquan He 
Reviewed-by: Luis Chamberlain 
Cc: Helge Deller 
Cc: Thomas Zimmermann 
Cc: Christophe Leroy 
Cc: linux-fb...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/aty/atyfb_base.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/video/fbdev/aty/atyfb_base.c 
b/drivers/video/fbdev/aty/atyfb_base.c
index cba2b113b28b0..a73114c1c6918 100644
--- a/drivers/video/fbdev/aty/atyfb_base.c
+++ b/drivers/video/fbdev/aty/atyfb_base.c
@@ -3440,11 +3440,15 @@ static int atyfb_setup_generic(struct pci_dev *pdev, 
struct fb_info *info,
}
 
info->fix.mmio_start = raddr;
+#if defined(__i386__) || defined(__ia64__)
/*
 * By using strong UC we force the MTRR to never have an
 * effect on the MMIO region on both non-PAT and PAT systems.
 */
par->ati_regbase = ioremap_uc(info->fix.mmio_start, 0x1000);
+#else
+   par->ati_regbase = ioremap(info->fix.mmio_start, 0x1000);
+#endif
if (par->ati_regbase == NULL)
return -ENOMEM;
 
-- 
2.42.0



Re: [PATCH 2/8] drm/loongson: Introduce a drm bridge driver for it66121 HDMI transmitter

2023-10-29 Thread Dmitry Baryshkov
On Sun, 29 Oct 2023 at 21:46, Sui Jingfeng  wrote:
>
> The IT66121 is a DVO to HDMI converter, LS3A5000+LS7A1000 ML5A_MB use this
> chip to support HDMI output. Thus add a drm bridge based driver for it.
> This patch is developed with drivers/gpu/drm/bridge/ite-it66121.c as base.

Please use the original bridge driver instead of adding a new one. If
it needs to be changed in any way, please help everyone else by
improving it instead of introducing new driver.

>
> Signed-off-by: Sui Jingfeng 
> ---
>  drivers/gpu/drm/loongson/Kconfig|   1 +
>  drivers/gpu/drm/loongson/Makefile   |   2 +
>  drivers/gpu/drm/loongson/ite_it66121.c  | 749 
>  drivers/gpu/drm/loongson/ite_it66121.h  |  19 +
>  drivers/gpu/drm/loongson/ite_it66121_regs.h | 268 +++
>  5 files changed, 1039 insertions(+)
>  create mode 100644 drivers/gpu/drm/loongson/ite_it66121.c
>  create mode 100644 drivers/gpu/drm/loongson/ite_it66121.h
>  create mode 100644 drivers/gpu/drm/loongson/ite_it66121_regs.h


-- 
With best wishes
Dmitry


[PATCH 4/8] drm/loongson: Started to attach display bridge driver for LS7A1000

2023-10-29 Thread Sui Jingfeng
Loongson ML5B_MA board using ITE IT66121 HDMI transmitter to support HDMI
display output, with the vbios provided the necessary information, we are
able to create a minimal drm bridge driver for it. After apply this patch
we are able to change mode freely.

Tested on LS3A5000+LS7A1000 ML5B_MA board.

$ dmesg | grep drm

 [drm] dc: 264MHz, gmc: 529MHz, gpu: 529MHz
 [drm] Dedicated vram start: 0xe003000, size: 64MiB
 [drm] Loongson VBIOS version: 0.3
 [drm] Loongson VBIOS: has 8 DCBs
 [drm] VRAM: 4096 pages ready
 [drm] GTT: 32768 pages ready
 [drm] lsdc-i2c0(sda pin mask=1, scl pin mask=2) created
 [drm] lsdc-i2c1(sda pin mask=4, scl pin mask=8) created
 [drm] DisplayPipe-0 has DVO-0
 [drm] device address(0x4d) is not correct
 [drm] i2c client IT66121@0x4c created
 [drm] IT66121 attached, Vendor ID: 0x4954, Device ID: 0x612
 [drm] Total 2 outputs
 [drm] registered irq: 40
 [drm] Initialized loongson 1.0.0 20220701 for :00:06.1 on minor 0
 loongson :00:06.1: [drm] fb0: loongsondrmfb frame buffer device

Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/loongson/lsdc_output_7a1000.c | 144 +++---
 1 file changed, 55 insertions(+), 89 deletions(-)

diff --git a/drivers/gpu/drm/loongson/lsdc_output_7a1000.c 
b/drivers/gpu/drm/loongson/lsdc_output_7a1000.c
index 6fc8dd1c7d9a..e12f9a0157d0 100644
--- a/drivers/gpu/drm/loongson/lsdc_output_7a1000.c
+++ b/drivers/gpu/drm/loongson/lsdc_output_7a1000.c
@@ -10,6 +10,7 @@
 #include "lsdc_drv.h"
 #include "lsdc_output.h"
 
+#include "ite_it66121.h"
 /*
  * The display controller in the LS7A1000 exports two DVO interfaces, thus
  * external encoder is required, except connected to the DPI panel directly.
@@ -38,68 +39,6 @@
  *  TODO: Add support for non-transparent encoders
  */
 
-static int ls7a1000_dpi_connector_get_modes(struct drm_connector *conn)
-{
-   unsigned int num = 0;
-   struct edid *edid;
-
-   if (conn->ddc) {
-   edid = drm_get_edid(conn, conn->ddc);
-   if (edid) {
-   drm_connector_update_edid_property(conn, edid);
-   num = drm_add_edid_modes(conn, edid);
-   kfree(edid);
-   }
-
-   return num;
-   }
-
-   num = drm_add_modes_noedid(conn, 1920, 1200);
-
-   drm_set_preferred_mode(conn, 1024, 768);
-
-   return num;
-}
-
-static struct drm_encoder *
-ls7a1000_dpi_connector_get_best_encoder(struct drm_connector *connector,
-   struct drm_atomic_state *state)
-{
-   struct lsdc_output *output = connector_to_lsdc_output(connector);
-
-   return &output->encoder;
-}
-
-static const struct drm_connector_helper_funcs
-ls7a1000_dpi_connector_helpers = {
-   .atomic_best_encoder = ls7a1000_dpi_connector_get_best_encoder,
-   .get_modes = ls7a1000_dpi_connector_get_modes,
-};
-
-static enum drm_connector_status
-ls7a1000_dpi_connector_detect(struct drm_connector *connector, bool force)
-{
-   struct i2c_adapter *ddc = connector->ddc;
-
-   if (ddc) {
-   if (drm_probe_ddc(ddc))
-   return connector_status_connected;
-
-   return connector_status_disconnected;
-   }
-
-   return connector_status_unknown;
-}
-
-static const struct drm_connector_funcs ls7a1000_dpi_connector_funcs = {
-   .detect = ls7a1000_dpi_connector_detect,
-   .fill_modes = drm_helper_probe_single_connector_modes,
-   .destroy = drm_connector_cleanup,
-   .reset = drm_atomic_helper_connector_reset,
-   .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
-   .atomic_destroy_state = drm_atomic_helper_connector_destroy_state
-};
-
 static void ls7a1000_pipe0_encoder_reset(struct drm_encoder *encoder)
 {
struct drm_device *ddev = encoder->dev;
@@ -139,40 +78,67 @@ static const struct drm_encoder_funcs 
ls7a1000_encoder_funcs[2] = {
},
 };
 
+/*
+ * This is a default output description for LS7A1000/LS2K1000, this is always
+ * true from the hardware perspective. It is just that when there are external
+ * display bridge connected, this description no longer complete. As it cannot
+ * describe the topology about the external encoders.
+ */
+static const struct lsdc_output_desc ls7a1000_output_desc[2] = {
+   {
+   .pipe = 0,
+   .encoder_type = DRM_MODE_ENCODER_DPI,
+   .connector_type = DRM_MODE_CONNECTOR_DPI,
+   .encoder_funcs = &ls7a1000_encoder_funcs[0],
+   .encoder_helper_funcs = &lsdc_encoder_helper_funcs,
+   .connector_funcs = &lsdc_connector_funcs,
+   .connector_helper_funcs = &lsdc_connector_helper_funcs,
+   .name = "DVO-0",
+   },
+   {
+   .pipe = 1,
+   .encoder_type = DRM_MODE_ENCODER_DPI,
+   .connector_type = DRM_MODE_CONNECTOR_DPI,
+   .encoder_funcs = &ls7a1000_encoder_funcs[1],
+   .enc

[PATCH 2/8] drm/loongson: Introduce a drm bridge driver for it66121 HDMI transmitter

2023-10-29 Thread Sui Jingfeng
The IT66121 is a DVO to HDMI converter, LS3A5000+LS7A1000 ML5A_MB use this
chip to support HDMI output. Thus add a drm bridge based driver for it.
This patch is developed with drivers/gpu/drm/bridge/ite-it66121.c as base.

Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/loongson/Kconfig|   1 +
 drivers/gpu/drm/loongson/Makefile   |   2 +
 drivers/gpu/drm/loongson/ite_it66121.c  | 749 
 drivers/gpu/drm/loongson/ite_it66121.h  |  19 +
 drivers/gpu/drm/loongson/ite_it66121_regs.h | 268 +++
 5 files changed, 1039 insertions(+)
 create mode 100644 drivers/gpu/drm/loongson/ite_it66121.c
 create mode 100644 drivers/gpu/drm/loongson/ite_it66121.h
 create mode 100644 drivers/gpu/drm/loongson/ite_it66121_regs.h

diff --git a/drivers/gpu/drm/loongson/Kconfig b/drivers/gpu/drm/loongson/Kconfig
index df6946d505fa..a96f5699099e 100644
--- a/drivers/gpu/drm/loongson/Kconfig
+++ b/drivers/gpu/drm/loongson/Kconfig
@@ -7,6 +7,7 @@ config DRM_LOONGSON
select DRM_TTM
select I2C
select I2C_ALGOBIT
+   select REGMAP_I2C
help
  This is a DRM driver for Loongson Graphics, it may including
  LS7A2000, LS7A1000, LS2K2000 and LS2K1000 etc. Loongson LS7A
diff --git a/drivers/gpu/drm/loongson/Makefile 
b/drivers/gpu/drm/loongson/Makefile
index bef00b2c5569..1459d19b2c90 100644
--- a/drivers/gpu/drm/loongson/Makefile
+++ b/drivers/gpu/drm/loongson/Makefile
@@ -20,4 +20,6 @@ loongson-y += loongson_device.o \
  loongson_module.o \
  loongson_vbios.o
 
+loongson-y += ite_it66121.o
+
 obj-$(CONFIG_DRM_LOONGSON) += loongson.o
diff --git a/drivers/gpu/drm/loongson/ite_it66121.c 
b/drivers/gpu/drm/loongson/ite_it66121.c
new file mode 100644
index ..7b085575f864
--- /dev/null
+++ b/drivers/gpu/drm/loongson/ite_it66121.c
@@ -0,0 +1,749 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 BayLibre, SAS
+ * Author: Phong LE 
+ * Copyright (C) 2018-2019, Artem Mygaiev
+ * Copyright (C) 2017, Fresco Logic, Incorporated.
+ *
+ * IT66121 HDMI transmitter driver
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ite_it66121.h"
+#include "ite_it66121_regs.h"
+
+#define IT66121_CHIP_NAME   "IT66121"
+
+struct it66121_bridge {
+   struct drm_bridge bridge;
+   struct drm_connector connector;
+   struct regmap *regmap;
+   struct i2c_client *client;
+   /* Protects fields below and device registers */
+   struct mutex lock;
+   u16 vendor_id;
+   u16 device_id;
+   u32 revision;
+};
+
+static inline struct it66121_bridge *
+bridge_to_it66121(struct drm_bridge *bridge)
+{
+   return container_of(bridge, struct it66121_bridge, bridge);
+}
+
+static inline struct it66121_bridge *
+connector_to_it66121(struct drm_connector *connector)
+{
+   return container_of(connector, struct it66121_bridge, connector);
+}
+
+static const struct regmap_range_cfg it66121_regmap_banks[] = {
+   {
+   .name = IT66121_CHIP_NAME,
+   .range_min = 0x00,
+   .range_max = 0x1FF,
+   .selector_reg = IT66121_CLK_BANK_REG,
+   .selector_mask = 0x1,
+   .selector_shift = 0,
+   .window_start = 0x00,
+   .window_len = 0x100,
+   },
+};
+
+static const struct regmap_config it66121_regmap_config = {
+   .val_bits = 8,
+   .reg_bits = 8,
+   .max_register = 0x1FF,
+   .ranges = it66121_regmap_banks,
+   .num_ranges = ARRAY_SIZE(it66121_regmap_banks),
+};
+
+static inline int it66121_preamble_ddc(struct it66121_bridge *itb)
+{
+   return regmap_write(itb->regmap, IT66121_MASTER_SEL_REG,
+   IT66121_MASTER_SEL_HOST);
+}
+
+static inline int it66121_fire_afe(struct it66121_bridge *itb)
+{
+   return regmap_write(itb->regmap, IT66121_AFE_DRV_REG, 0);
+}
+
+static int it66121_configure_input(struct it66121_bridge *itb)
+{
+   int ret;
+
+   ret = regmap_write(itb->regmap, IT66121_INPUT_MODE_REG,
+  IT66121_INPUT_MODE_RGB888);
+   if (ret)
+   return ret;
+
+   return regmap_write(itb->regmap, IT66121_INPUT_CSC_REG,
+   IT66121_INPUT_CSC_NO_CONV);
+}
+
+/*
+ * it66121_configure_afe() - Configure the analog front end
+ * @ctx: it66121_ctx object
+ * @mode: mode to configure
+ *
+ * RETURNS:
+ * zero if success, a negative error code otherwise.
+ */
+static int it66121_configure_afe(struct it66121_bridge *itb,
+const struct drm_display_mode *mode)
+{
+   int ret;
+
+   ret = regmap_write(itb->regmap, IT66121_AFE_DRV_REG,
+  IT66121_AFE_DRV_RST);
+   if (ret)
+   return ret;
+
+   if (mode->clock > IT66121_AFE_CLK_HIGH) {
+   ret = regmap_write_bits(itb->reg

[PATCH 6/8] drm/loongson: Clean up the output part of LS7A2000

2023-10-29 Thread Sui Jingfeng
Since the majority of sharable subroutines have been move to lsdc_output.c,
and functional changes are done with previous patch. We finally see the
light to cleanup, no functional change.

Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/loongson/lsdc_output_7a2000.c | 469 --
 1 file changed, 469 deletions(-)

diff --git a/drivers/gpu/drm/loongson/lsdc_output_7a2000.c 
b/drivers/gpu/drm/loongson/lsdc_output_7a2000.c
index bf558b61802b..981ab2045e91 100644
--- a/drivers/gpu/drm/loongson/lsdc_output_7a2000.c
+++ b/drivers/gpu/drm/loongson/lsdc_output_7a2000.c
@@ -42,465 +42,6 @@
  *  |__|
  */
 
-static int ls7a2000_connector_get_modes(struct drm_connector *connector)
-{
-   unsigned int num = 0;
-   struct edid *edid;
-
-   if (connector->ddc) {
-   edid = drm_get_edid(connector, connector->ddc);
-   if (edid) {
-   drm_connector_update_edid_property(connector, edid);
-   num = drm_add_edid_modes(connector, edid);
-   kfree(edid);
-   }
-
-   return num;
-   }
-
-   num = drm_add_modes_noedid(connector, 1920, 1200);
-
-   drm_set_preferred_mode(connector, 1024, 768);
-
-   return num;
-}
-
-static struct drm_encoder *
-ls7a2000_connector_get_best_encoder(struct drm_connector *connector,
-   struct drm_atomic_state *state)
-{
-   struct lsdc_output *output = connector_to_lsdc_output(connector);
-
-   return &output->encoder;
-}
-
-static const struct drm_connector_helper_funcs ls7a2000_connector_helpers = {
-   .atomic_best_encoder = ls7a2000_connector_get_best_encoder,
-   .get_modes = ls7a2000_connector_get_modes,
-};
-
-/* debugfs */
-
-#define LSDC_HDMI_REG(i, reg) {   \
-   .name = __stringify_1(LSDC_HDMI##i##_##reg##_REG),\
-   .offset = LSDC_HDMI##i##_##reg##_REG, \
-}
-
-static const struct lsdc_reg32 ls7a2000_hdmi0_encoder_regs[] = {
-   LSDC_HDMI_REG(0, ZONE),
-   LSDC_HDMI_REG(0, INTF_CTRL),
-   LSDC_HDMI_REG(0, PHY_CTRL),
-   LSDC_HDMI_REG(0, PHY_PLL),
-   LSDC_HDMI_REG(0, AVI_INFO_CRTL),
-   LSDC_HDMI_REG(0, PHY_CAL),
-   LSDC_HDMI_REG(0, AUDIO_PLL_LO),
-   LSDC_HDMI_REG(0, AUDIO_PLL_HI),
-   {NULL, 0},  /* MUST be {NULL, 0} terminated */
-};
-
-static const struct lsdc_reg32 ls7a2000_hdmi1_encoder_regs[] = {
-   LSDC_HDMI_REG(1, ZONE),
-   LSDC_HDMI_REG(1, INTF_CTRL),
-   LSDC_HDMI_REG(1, PHY_CTRL),
-   LSDC_HDMI_REG(1, PHY_PLL),
-   LSDC_HDMI_REG(1, AVI_INFO_CRTL),
-   LSDC_HDMI_REG(1, PHY_CAL),
-   LSDC_HDMI_REG(1, AUDIO_PLL_LO),
-   LSDC_HDMI_REG(1, AUDIO_PLL_HI),
-   {NULL, 0},  /* MUST be {NULL, 0} terminated */
-};
-
-static int ls7a2000_hdmi_encoder_regs_show(struct seq_file *m, void *data)
-{
-   struct drm_info_node *node = (struct drm_info_node *)m->private;
-   struct drm_device *ddev = node->minor->dev;
-   struct lsdc_device *ldev = to_lsdc(ddev);
-   const struct lsdc_reg32 *preg;
-
-   preg = (const struct lsdc_reg32 *)node->info_ent->data;
-
-   while (preg->name) {
-   u32 offset = preg->offset;
-
-   seq_printf(m, "%s (0x%04x): 0x%08x\n",
-  preg->name, offset, lsdc_rreg32(ldev, offset));
-   ++preg;
-   }
-
-   return 0;
-}
-
-static const struct drm_info_list ls7a2000_hdmi0_debugfs_files[] = {
-   { "regs", ls7a2000_hdmi_encoder_regs_show, 0, (void 
*)ls7a2000_hdmi0_encoder_regs },
-};
-
-static const struct drm_info_list ls7a2000_hdmi1_debugfs_files[] = {
-   { "regs", ls7a2000_hdmi_encoder_regs_show, 0, (void 
*)ls7a2000_hdmi1_encoder_regs },
-};
-
-static void ls7a2000_hdmi0_late_register(struct drm_connector *connector,
-struct dentry *root)
-{
-   struct drm_device *ddev = connector->dev;
-   struct drm_minor *minor = ddev->primary;
-
-   drm_debugfs_create_files(ls7a2000_hdmi0_debugfs_files,
-ARRAY_SIZE(ls7a2000_hdmi0_debugfs_files),
-root, minor);
-}
-
-static void ls7a2000_hdmi1_late_register(struct drm_connector *connector,
-struct dentry *root)
-{
-   struct drm_device *ddev = connector->dev;
-   struct drm_minor *minor = ddev->primary;
-
-   drm_debugfs_create_files(ls7a2000_hdmi1_debugfs_files,
-ARRAY_SIZE(ls7a2000_hdmi1_debugfs_files),
-root, minor);
-}
-
-/* monitor present detection */
-
-static enum drm_connector_status
-ls7a2000_hdmi0_vga_connector_detect(struct drm_connector *connector, bool 
force)
-{
-   struct drm_device *ddev = connector->dev;
-   struct lsdc_device *ldev = to_lsdc(ddev);
-   u32 val;
-
-   val = lsdc_rreg32(ldev, LSDC_HDMI_HPD_STATUS_REG);
-
- 

[PATCH 3/8] drm/loongson: Allow attach drm bridge driver by calling lsdc_output_init()

2023-10-29 Thread Sui Jingfeng
Move the sharable subroutine into lsdc_output.c and refactor.

Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/loongson/Makefile  |   1 +
 drivers/gpu/drm/loongson/lsdc_drv.h|  17 -
 drivers/gpu/drm/loongson/lsdc_output.c | 640 +
 drivers/gpu/drm/loongson/lsdc_output.h |  52 +-
 4 files changed, 691 insertions(+), 19 deletions(-)
 create mode 100644 drivers/gpu/drm/loongson/lsdc_output.c

diff --git a/drivers/gpu/drm/loongson/Makefile 
b/drivers/gpu/drm/loongson/Makefile
index 1459d19b2c90..393709e686aa 100644
--- a/drivers/gpu/drm/loongson/Makefile
+++ b/drivers/gpu/drm/loongson/Makefile
@@ -9,6 +9,7 @@ loongson-y := \
lsdc_gfxpll.o \
lsdc_i2c.o \
lsdc_irq.o \
+   lsdc_output.o \
lsdc_output_7a1000.o \
lsdc_output_7a2000.o \
lsdc_plane.o \
diff --git a/drivers/gpu/drm/loongson/lsdc_drv.h 
b/drivers/gpu/drm/loongson/lsdc_drv.h
index 335953c988d1..46ba9b88a30d 100644
--- a/drivers/gpu/drm/loongson/lsdc_drv.h
+++ b/drivers/gpu/drm/loongson/lsdc_drv.h
@@ -175,23 +175,6 @@ struct lsdc_cursor {
struct lsdc_device *ldev;
 };
 
-struct lsdc_output {
-   struct drm_encoder encoder;
-   struct drm_connector connector;
-};
-
-static inline struct lsdc_output *
-connector_to_lsdc_output(struct drm_connector *connector)
-{
-   return container_of(connector, struct lsdc_output, connector);
-}
-
-static inline struct lsdc_output *
-encoder_to_lsdc_output(struct drm_encoder *encoder)
-{
-   return container_of(encoder, struct lsdc_output, encoder);
-}
-
 struct lsdc_display_pipe {
struct lsdc_crtc crtc;
struct lsdc_primary primary;
diff --git a/drivers/gpu/drm/loongson/lsdc_output.c 
b/drivers/gpu/drm/loongson/lsdc_output.c
new file mode 100644
index ..8262c3f91ebe
--- /dev/null
+++ b/drivers/gpu/drm/loongson/lsdc_output.c
@@ -0,0 +1,640 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Loongson Technology Corporation Limited
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "lsdc_drv.h"
+#include "lsdc_output.h"
+
+/* This file contain shared subroutines for the output part */
+
+/* Usable for generic DVO, VGA and buitl-in HDMI connector */
+
+static int lsdc_connector_get_modes(struct drm_connector *connector)
+{
+   unsigned int num = 0;
+   struct edid *edid;
+
+   if (connector->ddc) {
+   edid = drm_get_edid(connector, connector->ddc);
+   if (edid) {
+   drm_connector_update_edid_property(connector, edid);
+   num = drm_add_edid_modes(connector, edid);
+   kfree(edid);
+   }
+
+   return num;
+   }
+
+   num = drm_add_modes_noedid(connector, 1920, 1200);
+
+   drm_set_preferred_mode(connector, 1024, 768);
+
+   return num;
+}
+
+static struct drm_encoder *
+lsdc_connector_get_best_encoder(struct drm_connector *connector,
+   struct drm_atomic_state *state)
+{
+   struct lsdc_output *output = connector_to_lsdc_output(connector);
+
+   return &output->encoder;
+}
+
+const struct drm_connector_helper_funcs lsdc_connector_helper_funcs = {
+   .atomic_best_encoder = lsdc_connector_get_best_encoder,
+   .get_modes = lsdc_connector_get_modes,
+};
+
+static enum drm_connector_status
+lsdc_connector_detect(struct drm_connector *connector, bool force)
+{
+   struct i2c_adapter *ddc = connector->ddc;
+
+   if (ddc) {
+   if (drm_probe_ddc(ddc))
+   return connector_status_connected;
+
+   return connector_status_disconnected;
+   }
+
+   return connector_status_unknown;
+}
+
+const struct drm_connector_funcs lsdc_connector_funcs = {
+   .detect = lsdc_connector_detect,
+   .fill_modes = drm_helper_probe_single_connector_modes,
+   .destroy = drm_connector_cleanup,
+   .reset = drm_atomic_helper_connector_reset,
+   .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+   .atomic_destroy_state = drm_atomic_helper_connector_destroy_state
+};
+
+/* debugfs */
+
+#define LSDC_HDMI_REG(i, reg) {   \
+   .name = __stringify_1(LSDC_HDMI##i##_##reg##_REG),\
+   .offset = LSDC_HDMI##i##_##reg##_REG, \
+}
+
+static int lsdc_hdmi_regs_show(struct seq_file *m, void *data)
+{
+   struct drm_info_node *node = (struct drm_info_node *)m->private;
+   struct drm_device *ddev = node->minor->dev;
+   struct lsdc_device *ldev = to_lsdc(ddev);
+   const struct lsdc_reg32 *preg;
+
+   preg = (const struct lsdc_reg32 *)node->info_ent->data;
+
+   while (preg->name) {
+   u32 offset = preg->offset;
+
+   seq_printf(m, "%s (0x%04x): 0x%08x\n",
+  preg->name, offset, lsdc_rreg32(ldev, offset));
+   ++preg;
+   }
+
+   return 0;
+}
+
+/* LS

[PATCH 8/8] drm/loongson: Add support for the display subsystem in LS2K2000

2023-10-29 Thread Sui Jingfeng
Before apply this patch, drm/loongson is basically works on LS2K2000.
Because majority of hardware features of the DC are same with LS7A2000's
counterpart. Despite LS2K2000 is a SoC, it don't has a dedicated VRAM.
But the firmware will carve out part of system RAM as VRAM, and write the
base address and size of this reserved RAM to the PCI Bar 2 of the GPU.
So this kind of reserved RAM is nearly same with the dedicated video RAM.

In short, the display subsystem in LS2K2000 are nearly compatible with the
display subsystem in LS7A2000. But LS2K2000 has only one built-in HDMI
encoder, which is connected with the CRTC-0 (display pipe 0). Display pipe
1 exports a generic DVO interface. So there still need a trivial fix.

Before apply this patch:

$ dmesg | grep :00:06.1

 pci :00:06.1: [0014:7a36] type 00 class 0x03
 pci :00:06.1: reg 0x10: [mem 0x5125-0x5125 64bit]
 pci :00:06.1: reg 0x18: [mem 0x512b6000-0x512b60ff]
 pci :00:06.1: BAR 0: assigned [mem 0x5125-0x5125 64bit]
 pci :00:06.1: BAR 2: assigned [mem 0x512b7f00-0x512b7fff]
 pci :00:06.1: vgaarb: setting as boot VGA device
 loongson :00:06.1: Found LS7A2000 bridge chipset, revision: 16
 loongson :00:06.1: [drm] dc: 400MHz, gmc: 800MHz, gpu: 533MHz
 loongson :00:06.1: [drm] Dedicated vram start: 0x4000, size: 256MiB
 loongson :00:06.1: [drm] Loongson VBIOS version: 2.1
 loongson :00:06.1: [drm] Loongson VBIOS: has 8 DCBs
 loongson :00:06.1: [drm] VRAM: 16384 pages ready
 loongson :00:06.1: [drm] GTT: 32768 pages ready
 loongson :00:06.1: [drm] lsdc-i2c0(sda pin mask=1, scl pin mask=2) created
 loongson :00:06.1: [drm] lsdc-i2c1(sda pin mask=4, scl pin mask=8) created
 loongson :00:06.1: [drm] DisplayPipe-0 has HDMI-0
 loongson :00:06.1: [drm] DisplayPipe-1 has HDMI-1
 loongson :00:06.1: [drm] Total 2 outputs
 loongson :00:06.1: [drm] registered irq: 42
 [drm] Initialized loongson 1.0.0 20220701 for :00:06.1 on minor 0
 loongson :00:06.1: [drm] *ERROR* Setting HDMI-1 PLL failed
 loongson :00:06.1: [drm] fb0: loongsondrmfb frame buffer device

After apply this patch, the error "*ERROR* Setting HDMI-1 PLL failed" got
fixed.

$ dmesg | grep :00:06.1

 pci :00:06.1: [0014:7a36] type 00 class 0x03
 pci :00:06.1: reg 0x10: [mem 0x5125-0x5125 64bit]
 pci :00:06.1: reg 0x18: [mem 0x512b6000-0x512b60ff]
 pci :00:06.1: BAR 0: assigned [mem 0x5125-0x5125 64bit]
 pci :00:06.1: BAR 2: assigned [mem 0x512b7f00-0x512b7fff]
 pci :00:06.1: vgaarb: setting as boot VGA device
 loongson :00:06.1: Found LS2K2000 SoC, revision: 16
 loongson :00:06.1: [drm] dc: 400MHz, gmc: 800MHz, gpu: 533MHz
 loongson :00:06.1: [drm] Dedicated vram start: 0x4000, size: 256MiB
 loongson :00:06.1: [drm] Loongson VBIOS version: 2.1
 loongson :00:06.1: [drm] Loongson VBIOS: has 8 DCBs
 loongson :00:06.1: [drm] VRAM: 16384 pages ready
 loongson :00:06.1: [drm] GTT: 32768 pages ready
 loongson :00:06.1: [drm] lsdc-i2c0(sda pin mask=1, scl pin mask=2) created
 loongson :00:06.1: [drm] lsdc-i2c1(sda pin mask=4, scl pin mask=8) created
 loongson :00:06.1: [drm] DisplayPipe-0 has HDMI-0
 loongson :00:06.1: [drm] DisplayPipe-1 has DVO-1
 loongson :00:06.1: [drm] Total 2 outputs
 loongson :00:06.1: [drm] registered irq: 42
 [drm] Initialized loongson 1.0.0 20220701 for :00:06.1 on minor 0
 loongson :00:06.1: [drm] fb0: loongsondrmfb frame buffer device

Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/loongson/Makefile |  1 +
 drivers/gpu/drm/loongson/loongson_device.c| 46 ++
 drivers/gpu/drm/loongson/lsdc_output.h|  5 ++
 drivers/gpu/drm/loongson/lsdc_output_2k2000.c | 84 +++
 4 files changed, 136 insertions(+)
 create mode 100644 drivers/gpu/drm/loongson/lsdc_output_2k2000.c

diff --git a/drivers/gpu/drm/loongson/Makefile 
b/drivers/gpu/drm/loongson/Makefile
index 393709e686aa..7d3d82ddd5ff 100644
--- a/drivers/gpu/drm/loongson/Makefile
+++ b/drivers/gpu/drm/loongson/Makefile
@@ -10,6 +10,7 @@ loongson-y := \
lsdc_i2c.o \
lsdc_irq.o \
lsdc_output.o \
+   lsdc_output_2k2000.o \
lsdc_output_7a1000.o \
lsdc_output_7a2000.o \
lsdc_plane.o \
diff --git a/drivers/gpu/drm/loongson/loongson_device.c 
b/drivers/gpu/drm/loongson/loongson_device.c
index 64096ad5466e..33aae403f0b0 100644
--- a/drivers/gpu/drm/loongson/loongson_device.c
+++ b/drivers/gpu/drm/loongson/loongson_device.c
@@ -6,6 +6,7 @@
 #include 
 
 #include "lsdc_drv.h"
+#include "lsdc_probe.h"
 
 extern struct loongson_vbios __loongson_vbios;
 
@@ -27,6 +28,15 @@ static const struct lsdc_kms_funcs ls7a2000_kms_funcs = {
.crtc_init = ls7a2000_crtc_init,
 };
 
+static const struct lsdc_kms_funcs ls2k2000_kms_funcs = {
+   .create_i2c = lsdc_create_i2c_chan,
+   .irq_handler = ls7a2000_dc_irq_handler,
+   .o

[PATCH 5/8] drm/loongson: Using vbios for the LS7A2000 output initialization

2023-10-29 Thread Sui Jingfeng
For LS7A2000, the built-in VGA encoder is transparent. Connect another
external transmitter with this internal VGA encoder is not sane, thus is
not allowed. Because there are two internal encoders hardware resource on
the first display pipe, call loongson_vbios_query_encoder_info() to know
what exatly the output configutaion is. Either VGA or HDMI display output
interface, but not both. And formal products should not export three
display connector interfaces. As the hardware has two-way I2Cs and two
CRTCs. So with this observation, we can untangle more.

If there a need to extend(transform) the output interface type, then the
internal HDMI phy MUST be enabled and initialized. External transmitters
must take the HDMI signal as input, this is the only choices. Such as
lt6711(HDMI to eDP), lt8619(HDMI to LVDS) etc.

Before apply this patch, ls7a2000_output_init() is simplified function
which assumed that there is no external display bridge attached. This
naive abstraction no longer suit the needs in the long run. Hence, switch
to call the newly implemented lsdc_output_init() function, which allow us
model the external encoder as a drm display bridge. The driver of this drm
display bridge should reside in the same kernel module with drm/loongson.
We will attach it by ourself, and rely on the VBIOS tell us which display
pipe has what display bridge connected.

Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/loongson/lsdc_output_7a2000.c | 154 ++
 1 file changed, 124 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/loongson/lsdc_output_7a2000.c 
b/drivers/gpu/drm/loongson/lsdc_output_7a2000.c
index ce3dabec887e..bf558b61802b 100644
--- a/drivers/gpu/drm/loongson/lsdc_output_7a2000.c
+++ b/drivers/gpu/drm/loongson/lsdc_output_7a2000.c
@@ -501,6 +501,126 @@ static const struct drm_encoder_helper_funcs 
ls7a2000_encoder_helper_funcs = {
.atomic_mode_set = ls7a2000_hdmi_atomic_mode_set,
 };
 
+/* The built-in tranparent VGA encoder is only available on display pipe 0 */
+static void ls7a2000_pipe0_vga_encoder_reset(struct drm_encoder *encoder)
+{
+   struct lsdc_device *ldev = to_lsdc(encoder->dev);
+   u32 val = PHY_CLOCK_POL | PHY_CLOCK_EN | PHY_DATA_EN;
+
+   lsdc_wreg32(ldev, LSDC_CRTC0_DVO_CONF_REG, val);
+
+   /*
+* The firmware set LSDC_HDMIx_CTRL_REG blindly to use hardware I2C,
+* which is may not works because of hardware bug. We using built-in
+* GPIO emulated I2C instead of the hardware I2C here.
+*/
+   lsdc_ureg32_clr(ldev, LSDC_HDMI0_INTF_CTRL_REG, HW_I2C_EN);
+
+   mdelay(20);
+}
+
+static const struct drm_encoder_funcs ls7a2000_pipe0_vga_encoder_funcs = {
+   .reset = ls7a2000_pipe0_vga_encoder_reset,
+   .destroy = drm_encoder_cleanup,
+};
+
+static const struct lsdc_output_desc ls7a2000_vga_pipe0 = {
+   .pipe = 0,
+   .encoder_type = DRM_MODE_ENCODER_DAC,
+   .connector_type = DRM_MODE_CONNECTOR_VGA,
+   .encoder_funcs = &ls7a2000_pipe0_vga_encoder_funcs,
+   .encoder_helper_funcs = &lsdc_pipe0_hdmi_encoder_helper_funcs,
+   .connector_funcs = &lsdc_connector_funcs,
+   .connector_helper_funcs = &lsdc_connector_helper_funcs,
+   .name = "VGA-0",
+};
+
+static const struct lsdc_output_desc ls7a2000_hdmi_pipe0 = {
+   .pipe = 0,
+   .encoder_type = DRM_MODE_ENCODER_TMDS,
+   .connector_type = DRM_MODE_CONNECTOR_HDMIA,
+   .encoder_funcs = &lsdc_pipe0_hdmi_encoder_funcs,
+   .encoder_helper_funcs = &lsdc_pipe0_hdmi_encoder_helper_funcs,
+   .connector_funcs = &lsdc_pipe0_hdmi_connector_funcs,
+   .connector_helper_funcs = &lsdc_connector_helper_funcs,
+   .name = "HDMI-0",
+};
+
+static const struct lsdc_output_desc ls7a2000_hdmi_pipe1 = {
+   .pipe = 1,
+   .encoder_type = DRM_MODE_ENCODER_TMDS,
+   .connector_type = DRM_MODE_CONNECTOR_HDMIA,
+   .encoder_funcs = &lsdc_pipe1_hdmi_encoder_funcs,
+   .encoder_helper_funcs = &lsdc_pipe1_hdmi_encoder_helper_funcs,
+   .connector_funcs = &lsdc_pipe1_hdmi_connector_funcs,
+   .connector_helper_funcs = &lsdc_connector_helper_funcs,
+   .name = "HDMI-1",
+};
+
+/*
+ * For LS7A2000, the built-in VGA encoder is transparent. If there are
+ * external encoder exist, then the internal HDMI encoder MUST be enabled
+ * and initialized. As the internal HDMI encoder is always connected, so
+ * only the transmitters which take HDMI signal (such as HDMI to eDP, HDMI
+ * to LVDS, etc) are usable with.
+ */
+const struct lsdc_output_desc *
+ls7a2000_query_output_configuration(struct drm_device *ddev, unsigned int pipe)
+{
+   enum loongson_vbios_encoder_name encoder_name = 0;
+   bool ret;
+
+   ret = loongson_vbios_query_encoder_info(ddev, pipe, NULL,
+   &encoder_name, NULL);
+   if (!ret)
+   goto bailout;
+
+   if (pipe == 0) {
+   switch (encoder_name) {
+   case ENCODER_

[PATCH 1/8] drm/loongson: Introduce a minimal support for Loongson VBIOS

2023-10-29 Thread Sui Jingfeng
Because some boards are equipped with non-transparent display bridges,
which need the VBIOS to provided parameters.

Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/loongson/Makefile  |   3 +-
 drivers/gpu/drm/loongson/loongson_device.c |   4 +
 drivers/gpu/drm/loongson/loongson_vbios.c  | 420 +
 drivers/gpu/drm/loongson/loongson_vbios.h  |  59 +++
 drivers/gpu/drm/loongson/lsdc_drv.c|   4 +
 drivers/gpu/drm/loongson/lsdc_drv.h|   8 +
 6 files changed, 497 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/loongson/loongson_vbios.c
 create mode 100644 drivers/gpu/drm/loongson/loongson_vbios.h

diff --git a/drivers/gpu/drm/loongson/Makefile 
b/drivers/gpu/drm/loongson/Makefile
index 91e72bd900c1..bef00b2c5569 100644
--- a/drivers/gpu/drm/loongson/Makefile
+++ b/drivers/gpu/drm/loongson/Makefile
@@ -17,6 +17,7 @@ loongson-y := \
lsdc_ttm.o
 
 loongson-y += loongson_device.o \
- loongson_module.o
+ loongson_module.o \
+ loongson_vbios.o
 
 obj-$(CONFIG_DRM_LOONGSON) += loongson.o
diff --git a/drivers/gpu/drm/loongson/loongson_device.c 
b/drivers/gpu/drm/loongson/loongson_device.c
index 9986c8a2a255..64096ad5466e 100644
--- a/drivers/gpu/drm/loongson/loongson_device.c
+++ b/drivers/gpu/drm/loongson/loongson_device.c
@@ -7,6 +7,8 @@
 
 #include "lsdc_drv.h"
 
+extern struct loongson_vbios __loongson_vbios;
+
 static const struct lsdc_kms_funcs ls7a1000_kms_funcs = {
.create_i2c = lsdc_create_i2c_chan,
.irq_handler = ls7a1000_dc_irq_handler,
@@ -53,6 +55,7 @@ static const struct loongson_gfx_desc ls7a1000_gfx = {
.reg_size = 8,
},
},
+   .vbios = &__loongson_vbios,
.chip_id = CHIP_LS7A1000,
.model = "LS7A1000 bridge chipset",
 };
@@ -85,6 +88,7 @@ static const struct loongson_gfx_desc ls7a2000_gfx = {
.reg_size = 8,
},
},
+   .vbios = &__loongson_vbios,
.chip_id = CHIP_LS7A2000,
.model = "LS7A2000 bridge chipset",
 };
diff --git a/drivers/gpu/drm/loongson/loongson_vbios.c 
b/drivers/gpu/drm/loongson/loongson_vbios.c
new file mode 100644
index ..dc304018779e
--- /dev/null
+++ b/drivers/gpu/drm/loongson/loongson_vbios.c
@@ -0,0 +1,420 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Loongson Technology Corporation Limited
+ */
+
+#include 
+#include 
+
+#include "loongson_vbios.h"
+#include "lsdc_drv.h"
+
+#define LOONGSON_VBIOS_HEADER_STR   "Loongson-VBIOS"
+/* Legacy VBIOS is stored at offset 0 */
+#define LOONGSON_VBIOS_LEGACY_OFFSET 0
+/* The size of legacy VBIOS is 1 KiB */
+#define LOONGSON_VBIOS_LEGACY_SIZE   0x000400
+
+/* Data Control Block of Newer version of the VBIOS started at here */
+#define LOONGSON_VBIOS_DCB_OFFSET0x006000
+/* The last 1 MiB of the VRAM contains the raw VBIOS data */
+#define LOONGSON_VBIOS_BLOCK_OFFSET  0x10
+/* Only 256KB of the 1 MiB are used for now */
+#define LOONGSON_VBIOS_BLOCK_SIZE0x04
+
+struct loongson_vbios __loongson_vbios;
+
+/*
+ * vbios data control block is a kind of metadata, which is used to index
+ * real hardware device data block.
+ */
+struct loongson_vbios_dcb {
+   u16 type;/* what is it */
+   u8 version;  /* version of it, useless */
+   u8 id;   /* index (usually same with the display pipe) of the 
hardware */
+   u32 offset;  /* the offset of the real data */
+   u32 size;/* the size of the real data */
+   u64 ext0;/* for extension purpose */
+   u64 ext1;/* extra space reserved for future use */
+} __packed;
+
+/*
+ * Loongson-VBIOS Data Block Layout
+ *
+ *
+ * _   0x0
+ *|_|
+ *| |  [0x, 0x0400) : legacy vbios storage
+ *|Not Used Yet |
+ *| |
+ *|-|<--- 0x6000
+ *   +|DCB 0|
+ *   ||-|
+ *   ||DCB 1|
+ *   ||-|  Format of Data Control Blocks
+ *   || One by one, packed  |++
+ *   ||-||  u16 type  |
+ *   ||DCB N|+   ||
+ *   ||-||   ++
+ *   ||  .  ||   | u8 version |
+ *   ||  .  ||   |  u8 index  |
+ *   ||  .  ||   ++
+ *   ||-||   ||
+ *   ||DCB end  ||   | u32 offset |
+ *   ||-||   +--- |
+ *   || ||   |   ||
+ *   ||_||   |   ++
+ *   ||_||   |   ||
+ *  

[PATCH 7/8] drm/loongson: Support to infer DC reversion from CPU's PRID value

2023-10-29 Thread Sui Jingfeng
Due to the fact that the same display IP core has been integrated into
different platform, there is a need to differentiate them on the runtime.
The DC in LS7A1000/LS2K1000 has the PCI vendor & device ID of 0x0014:0x7A06
The DC in LS7A2000/LS2K2000 has the PCI vendor & device ID of 0x0014:0x7A36

Because the output ports and host platform of the DC IP varies, without a
revision information we can't achieve fine-grained controls. The canonical
approach to do such a thing is to read reversion register from the PCIe
device. But LS2K1000 SoC was taped out at 2017, it is rather old. Our BIOS
engineer don't assign a different revision ID to it, probably because of
ignorance.

LS2K2000 SoC was newly taped on 2023, we strictly force the BIOS engineer
assign a different revision ID(0x10) to it. But the problem is that it is
too casual, there is no formal convention or public documented rule
established. For Loongson LS2K series SoC, the display controller IP is
taped togather with the CPU core. For Loongson LS7A series bridge chips,
the display controller IP is taped togather with the bridge chips itself.
Consider the fact the all Loongson CPU has a unique PRID, this patch choose
to infer DC reversion from CPU's PRID value.

 - LS3A4000/LS3A5000 has 0xC0 as its processor ID.
 - LS2K2000 has 0xB0 as its processor ID.
 - LS2K2000LA has 0xA0 as its processor ID.

The provided approach has no dependency on DT or ACPI, thus is preferfed.
Besides, this approach can be used to acquire more addtional HW features.
So the provided method has the potential to bring more benifits.

Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/loongson/lsdc_drv.h   |  2 ++
 drivers/gpu/drm/loongson/lsdc_probe.c | 35 +++
 drivers/gpu/drm/loongson/lsdc_probe.h |  2 ++
 3 files changed, 39 insertions(+)

diff --git a/drivers/gpu/drm/loongson/lsdc_drv.h 
b/drivers/gpu/drm/loongson/lsdc_drv.h
index 46ba9b88a30d..e1f4a2db2a0a 100644
--- a/drivers/gpu/drm/loongson/lsdc_drv.h
+++ b/drivers/gpu/drm/loongson/lsdc_drv.h
@@ -42,6 +42,8 @@
 enum loongson_chip_id {
CHIP_LS7A1000 = 0,
CHIP_LS7A2000 = 1,
+   CHIP_LS2K1000 = 2,
+   CHIP_LS2K2000 = 3,
CHIP_LS_LAST,
 };
 
diff --git a/drivers/gpu/drm/loongson/lsdc_probe.c 
b/drivers/gpu/drm/loongson/lsdc_probe.c
index 48ba69bb8a98..f49b642d8f65 100644
--- a/drivers/gpu/drm/loongson/lsdc_probe.c
+++ b/drivers/gpu/drm/loongson/lsdc_probe.c
@@ -54,3 +54,38 @@ unsigned int loongson_cpu_get_prid(u8 *imp, u8 *rev)
 
return prid;
 }
+
+enum loongson_chip_id loongson_chip_id_fixup(enum loongson_chip_id chip_id)
+{
+   u8 impl;
+
+   if (loongson_cpu_get_prid(&impl, NULL)) {
+   /*
+* LS2K2000 only has the LoongArch edition.
+*/
+   if (chip_id == CHIP_LS7A2000) {
+   if (impl == LOONGARCH_CPU_IMP_LS2K2000)
+   return CHIP_LS2K2000;
+   }
+
+   /*
+* LS2K1000 has the LoongArch edition(with two LA264 CPU core)
+* and the Mips edition(with two mips64r2 CPU core), Only the
+* instruction set of the CPU are changed, the peripheral
+* devices are basically same.
+*/
+   if (chip_id == CHIP_LS7A1000) {
+#if defined(__loongarch__)
+   if (impl == LOONGARCH_CPU_IMP_LS2K1000)
+   return CHIP_LS2K1000;
+#endif
+
+#if defined(__mips__)
+   if (impl == LOONGSON_CPU_MIPS_IMP_LS2K)
+   return CHIP_LS2K1000;
+#endif
+   }
+   }
+
+   return chip_id;
+}
diff --git a/drivers/gpu/drm/loongson/lsdc_probe.h 
b/drivers/gpu/drm/loongson/lsdc_probe.h
index 8bb6de2e3c64..8c630c5c90ce 100644
--- a/drivers/gpu/drm/loongson/lsdc_probe.h
+++ b/drivers/gpu/drm/loongson/lsdc_probe.h
@@ -9,4 +9,6 @@
 /* Helpers for chip detection */
 unsigned int loongson_cpu_get_prid(u8 *impl, u8 *rev);
 
+enum loongson_chip_id loongson_chip_id_fixup(enum loongson_chip_id chip_id);
+
 #endif
-- 
2.34.1



[PATCH 0/8] drm/loongson: Submit a mini VBIOS support and a display bridge driver

2023-10-29 Thread Sui Jingfeng
Loongson boards using various external display bridges to extend output
display interface. To complete the support, we have to introduce VBIOS(
or DT/ACPI support) and display bridge drivers.

Sui Jingfeng (8):
  drm/loongson: Introduce a minimal support for Loongson VBIOS
  drm/loongson: Introduce a drm bridge driver for it66121 HDMI
transmitter
  drm/loongson: Allow attach drm bridge driver by calling
lsdc_output_init()
  drm/loongson: Started to attach display bridge driver for LS7A1000
  drm/loongson: Using vbios for the LS7A2000 output initialization
  drm/loongson: Clean up the output part of LS7A2000
  drm/loongson: Support to infer DC reversion from CPU's PRID value
  drm/loongson: Add support for the display subsystem in LS2K2000

 drivers/gpu/drm/loongson/Kconfig  |   1 +
 drivers/gpu/drm/loongson/Makefile |   7 +-
 drivers/gpu/drm/loongson/ite_it66121.c| 749 ++
 drivers/gpu/drm/loongson/ite_it66121.h|  19 +
 drivers/gpu/drm/loongson/ite_it66121_regs.h   | 268 +++
 drivers/gpu/drm/loongson/loongson_device.c|  50 ++
 drivers/gpu/drm/loongson/loongson_vbios.c | 420 ++
 drivers/gpu/drm/loongson/loongson_vbios.h |  59 ++
 drivers/gpu/drm/loongson/lsdc_drv.c   |   4 +
 drivers/gpu/drm/loongson/lsdc_drv.h   |  27 +-
 drivers/gpu/drm/loongson/lsdc_output.c| 643 +++
 drivers/gpu/drm/loongson/lsdc_output.h|  57 +-
 drivers/gpu/drm/loongson/lsdc_output_2k2000.c |  84 ++
 drivers/gpu/drm/loongson/lsdc_output_7a1000.c | 144 ++--
 drivers/gpu/drm/loongson/lsdc_output_7a2000.c | 575 +++---
 drivers/gpu/drm/loongson/lsdc_probe.c |  35 +
 drivers/gpu/drm/loongson/lsdc_probe.h |   2 +
 17 files changed, 2560 insertions(+), 584 deletions(-)
 create mode 100644 drivers/gpu/drm/loongson/ite_it66121.c
 create mode 100644 drivers/gpu/drm/loongson/ite_it66121.h
 create mode 100644 drivers/gpu/drm/loongson/ite_it66121_regs.h
 create mode 100644 drivers/gpu/drm/loongson/loongson_vbios.c
 create mode 100644 drivers/gpu/drm/loongson/loongson_vbios.h
 create mode 100644 drivers/gpu/drm/loongson/lsdc_output.c
 create mode 100644 drivers/gpu/drm/loongson/lsdc_output_2k2000.c

-- 
2.34.1



Re: [PATCH v2 6/6] drm/vs: Add hdmi driver

2023-10-29 Thread Dmitry Baryshkov
On Thu, 26 Oct 2023 at 14:53, Maxime Ripard  wrote:
>
> On Thu, Oct 26, 2023 at 11:57:22AM +0300, Dmitry Baryshkov wrote:
> > On Thu, 26 Oct 2023 at 11:07, Maxime Ripard  wrote:
> > >
> > > On Thu, Oct 26, 2023 at 01:23:53AM +0300, Dmitry Baryshkov wrote:
> > > > > +static int starfive_hdmi_register(struct drm_device *drm, struct 
> > > > > starfive_hdmi *hdmi)
> > > > > +{
> > > > > +   struct drm_encoder *encoder = &hdmi->encoder;
> > > > > +   struct device *dev = hdmi->dev;
> > > > > +
> > > > > +   encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, 
> > > > > dev->of_node);
> > > > > +
> > > > > +   /*
> > > > > +* If we failed to find the CRTC(s) which this encoder is
> > > > > +* supposed to be connected to, it's because the CRTC has
> > > > > +* not been registered yet.  Defer probing, and hope that
> > > > > +* the required CRTC is added later.
> > > > > +*/
> > > > > +   if (encoder->possible_crtcs == 0)
> > > > > +   return -EPROBE_DEFER;
> > > > > +
> > > > > +   drm_encoder_helper_add(encoder, 
> > > > > &starfive_hdmi_encoder_helper_funcs);
> > > > > +
> > > > > +   hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
> > > > > +
> > > > > +   drm_connector_helper_add(&hdmi->connector,
> > > > > +&starfive_hdmi_connector_helper_funcs);
> > > > > +   drmm_connector_init(drm, &hdmi->connector,
> > > > > +   &starfive_hdmi_connector_funcs,
> > > > > +   DRM_MODE_CONNECTOR_HDMIA,
> > > >
> > > > On an embedded device one can not be so sure. There can be MHL or HDMI
> > > > Alternative Mode. Usually we use drm_bridge here and 
> > > > drm_bridge_connector.
> > >
> > > On an HDMI driver, it's far from being a requirement, especially given
> > > the limitations bridges have.
> >
> > It's a blessing that things like MHL / HDMI-in-USB-C / HDMI-to-MyDP
> > are not widely used in the wild and are mostly non-existing except
> > several phones that preate wide DP usage.
>
> And those can be supported without relying on bridges.

Yes, they likely can, in the way that nouveau handles I2C TV encoders.
But I don't think this can scale. We can have different devices
attached to the DSI, LVDS, HDMI and even DP image sources. I don't see
a scalable solution for either of them. E.g. by switching drm/msm to
use panel bridges for DSI panels we were able to significantly unify
and simplify code paths.

> > Using drm_connector directly prevents one from handling possible
> > modifications on the board level. For example, with the DRM connector
> > in place, handling a separate HPD GPIO will result in code duplication
> > from the hdmi-connector driver. Handling any other variations in the
> > board design (which are pretty common in the embedded world) will also
> > require changing the driver itself. drm_bridge / drm_bridge_connector
> > save us from those issues.
>
> And we have other solutions there too. Like, EDIDs are pretty much in
> the same spot with a lot of device variations, but it also works without
> a common driver. I'd really wish we were having less bridges and more
> helpers, but here we are.
>
> > BTW: what are the limitations of the drm_bridge wrt. HDMI output? I'm
> > asking because we heavily depend on the bridge infrastructure for HDMI
> > output. Maybe we are missing something there, which went unnoticed to
> > me and my colleagues.
>
> A bridge cannot extend the connector state or use properties, for
> example. It works for basic stuff but falls apart as soon as you're
> trying to do something slightly advanced.

Ack. I agree, we didn't have a necessity to implement properties up to
now. But that sounds like an interesting topic for DSI-to-HDMI bridges
and HDCP support. I'll need to check if any of the RB3/RB5/Dragonboard
bridges are programmed with the HDCP keys.
--
With best wishes
Dmitry


Re: [PATCH v2 1/2] drm/msm: Small uabi fixes

2023-10-29 Thread Dmitry Baryshkov
On Sun, 29 Oct 2023 at 17:07, Rob Clark  wrote:
>
> From: Rob Clark 
>
> Correct the minor version exposed and error return value for
> MSM_INFO_GET_NAME.
>
> Signed-off-by: Rob Clark 
> ---
>  drivers/gpu/drm/msm/msm_drv.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Reviewed-by: Dmitry Baryshkov 




-- 
With best wishes
Dmitry


Re: [PATCH v2 2/2] drm/msm/gem: Add metadata

2023-10-29 Thread Dmitry Baryshkov
On Sun, 29 Oct 2023 at 17:07, Rob Clark  wrote:
>
> From: Rob Clark 
>
> The EXT_external_objects extension is a bit awkward as it doesn't pass
> explicit modifiers, leaving the importer to guess with incomplete
> information.  In the case of vk (turnip) exporting and gl (freedreno)
> importing, the "OPTIMAL_TILING_EXT" layout depends on VkImageCreateInfo
> flags (among other things), which the importer does not know.  Which
> unfortunately leaves us with the need for a metadata back-channel.
>
> The contents of the metadata are defined by userspace.  The
> EXT_external_objects extension is only required to work between
> compatible versions of gl and vk drivers, as defined by device and
> driver UUIDs.
>
> v2: add missing metadata kfree
>
> Signed-off-by: Rob Clark 

Reviewed-by: Dmitry Baryshkov 

> ---
>  drivers/gpu/drm/msm/msm_drv.c | 57 ++-
>  drivers/gpu/drm/msm/msm_gem.c |  1 +
>  drivers/gpu/drm/msm/msm_gem.h |  4 +++
>  include/uapi/drm/msm_drm.h|  2 ++
>  4 files changed, 63 insertions(+), 1 deletion(-)

-- 
With best wishes
Dmitry


[PATCH v2 2/2] drm/msm/gem: Add metadata

2023-10-29 Thread Rob Clark
From: Rob Clark 

The EXT_external_objects extension is a bit awkward as it doesn't pass
explicit modifiers, leaving the importer to guess with incomplete
information.  In the case of vk (turnip) exporting and gl (freedreno)
importing, the "OPTIMAL_TILING_EXT" layout depends on VkImageCreateInfo
flags (among other things), which the importer does not know.  Which
unfortunately leaves us with the need for a metadata back-channel.

The contents of the metadata are defined by userspace.  The
EXT_external_objects extension is only required to work between
compatible versions of gl and vk drivers, as defined by device and
driver UUIDs.

v2: add missing metadata kfree

Signed-off-by: Rob Clark 
---
 drivers/gpu/drm/msm/msm_drv.c | 57 ++-
 drivers/gpu/drm/msm/msm_gem.c |  1 +
 drivers/gpu/drm/msm/msm_gem.h |  4 +++
 include/uapi/drm/msm_drm.h|  2 ++
 4 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 781db689fb16..9ec74ab4cfea 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -49,9 +49,10 @@
  * - 1.9.0 - Add MSM_SUBMIT_FENCE_SN_IN
  * - 1.10.0 - Add MSM_SUBMIT_BO_NO_IMPLICIT
  * - 1.11.0 - Add wait boost (MSM_WAIT_FENCE_BOOST, MSM_PREP_BOOST)
+ * - 1.12.0 - Add MSM_INFO_SET_METADATA and MSM_INFO_GET_METADATA
  */
 #define MSM_VERSION_MAJOR  1
-#define MSM_VERSION_MINOR  11
+#define MSM_VERSION_MINOR  12
 #define MSM_VERSION_PATCHLEVEL 0
 
 static void msm_deinit_vram(struct drm_device *ddev);
@@ -844,6 +845,8 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void 
*data,
break;
case MSM_INFO_SET_NAME:
case MSM_INFO_GET_NAME:
+   case MSM_INFO_SET_METADATA:
+   case MSM_INFO_GET_METADATA:
break;
default:
return -EINVAL;
@@ -905,6 +908,58 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void 
*data,
 msm_obj->name, args->len))
ret = -EFAULT;
}
+   break;
+   case MSM_INFO_SET_METADATA:
+   /* Impose a moderate upper bound on metadata size: */
+   if (args->len > 128) {
+   ret = -EOVERFLOW;
+   break;
+   }
+
+   ret = msm_gem_lock_interruptible(obj);
+   if (ret)
+   break;
+
+   msm_obj->metadata =
+   krealloc(msm_obj->metadata, args->len, GFP_KERNEL);
+   msm_obj->metadata_size = args->len;
+
+   if (copy_from_user(msm_obj->metadata, 
u64_to_user_ptr(args->value),
+  args->len)) {
+   msm_obj->metadata_size = 0;
+   ret = -EFAULT;
+   }
+
+   msm_gem_unlock(obj);
+
+   break;
+   case MSM_INFO_GET_METADATA:
+   if (!args->value) {
+   /*
+* Querying the size is inherently racey, but
+* EXT_external_objects expects the app to confirm
+* via device and driver UUIDs that the exporter and
+* importer versions match.  All we can do from the
+* kernel side is check the length under obj lock
+* when userspace tries to retrieve the metadata
+*/
+   args->len = msm_obj->metadata_size;
+   break;
+   }
+
+   ret = msm_gem_lock_interruptible(obj);
+   if (ret)
+   break;
+
+   if (args->len < msm_obj->metadata_size) {
+   ret = -ETOOSMALL;
+   } else if (copy_to_user(u64_to_user_ptr(args->value),
+   msm_obj->metadata, args->len)) {
+   ret = -EFAULT;
+   }
+
+   msm_gem_unlock(obj);
+
break;
}
 
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 1113e6b2ec8e..175ee4ab8a6f 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -1058,6 +1058,7 @@ static void msm_gem_free_object(struct drm_gem_object 
*obj)
 
drm_gem_object_release(obj);
 
+   kfree(msm_obj->metadata);
kfree(msm_obj);
 }
 
diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h
index 7f34263048a3..8d414b072c29 100644
--- a/drivers/gpu/drm/msm/msm_gem.h
+++ b/drivers/gpu/drm/msm/msm_gem.h
@@ -109,6 +109,10 @@ struct msm_gem_object {
 
char name[32]; /* Identifier to print for the debugfs files */
 
+   /* userspace metadata backchannel */
+   void *metadata;
+   u32 metadata_size;
+
/**
 * pin_count: Number of times the pages are pinned
 *
diff --git

[PATCH v2 1/2] drm/msm: Small uabi fixes

2023-10-29 Thread Rob Clark
From: Rob Clark 

Correct the minor version exposed and error return value for
MSM_INFO_GET_NAME.

Signed-off-by: Rob Clark 
---
 drivers/gpu/drm/msm/msm_drv.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 4bd028fa7500..781db689fb16 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -51,7 +51,7 @@
  * - 1.11.0 - Add wait boost (MSM_WAIT_FENCE_BOOST, MSM_PREP_BOOST)
  */
 #define MSM_VERSION_MAJOR  1
-#define MSM_VERSION_MINOR  10
+#define MSM_VERSION_MINOR  11
 #define MSM_VERSION_PATCHLEVEL 0
 
 static void msm_deinit_vram(struct drm_device *ddev);
@@ -896,7 +896,7 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void 
*data,
break;
case MSM_INFO_GET_NAME:
if (args->value && (args->len < strlen(msm_obj->name))) {
-   ret = -EINVAL;
+   ret = -ETOOSMALL;
break;
}
args->len = strlen(msm_obj->name);
-- 
2.41.0



[PATCH v2 0/2] drm/msm/gem: Add metadata uapi

2023-10-29 Thread Rob Clark
From: Rob Clark 

Add metadata mechanism to provide a back-channel to communicate image
layout information between vk and gl, because EXT_external_objects
doesn't support explicit modifiers and "OPTIMAL_TILING_EXT" is not
enough information for the importer to deduce the layout.

Rob Clark (2):
  drm/msm: Small uabi fixes
  drm/msm/gem: Add metadata

 drivers/gpu/drm/msm/msm_drv.c | 59 +--
 drivers/gpu/drm/msm/msm_gem.c |  1 +
 drivers/gpu/drm/msm/msm_gem.h |  4 +++
 include/uapi/drm/msm_drm.h|  2 ++
 4 files changed, 64 insertions(+), 2 deletions(-)

-- 
2.41.0



  1   2   >