Re: [v1 2/2] drm/panel: ili9882t: Avoid blurred screen from fast sleep
Hi, On Wed, Oct 11, 2023 at 3:11 AM Doug Anderson wrote: > > Hi, > > On Tue, Oct 10, 2023 at 4:36 AM cong yang > wrote: > > > > Hi, > > > > On Tue, Oct 10, 2023 at 4:44 AM Doug Anderson wrote: > > > > > > Hi, > > > > > > On Fri, Oct 6, 2023 at 11:07 PM Cong Yang > > > wrote: > > > > > > > > At present, we have found that there may be a problem of blurred > > > > screen during fast sleep/resume. The direct cause of the blurred > > > > screen is that the IC does not receive 0x28/0x10. Because of the > > > > particularity of the IC, before the panel enters sleep hid must > > > > stop scanning, i2c_hid_core_suspend before ili9882t_disable. > > > > This doesn't look very spec-compliant. > > > > > > Presumably you could be more spec compliant if we used > > > "panel_follower" in this case? Would that be a better solution? > > > > In the "panel_follower" solution, the phenomenon is the same. > > The current order is > > ili9882t_disable=>i2c_hid_core_suspend=>elan_i2c_hid_power_down=>ili9882t_unprepare, > > ili9882t need touchpanel stop scanning,i2c_hid_core_suspend before > > ili9882t_disable. > > Ugh, that's unfortunate. Though is there a reason why you couldn't > just move the `ili9882t_enter_sleep_mode()` to `ili9882t_unprepare()`? > That seems like it should be OK and even perhaps makes it more > symmetric with thue enable? Thank you for your suggestion. If the timing is met and there is no problem, I will implement it in V3. > > > > > > @@ -507,7 +526,7 @@ static int ili9882t_prepare(struct drm_panel *panel) > > > > gpiod_set_value(ili->enable_gpio, 1); > > > > usleep_range(1000, 2000); > > > > gpiod_set_value(ili->enable_gpio, 0); > > > > - usleep_range(1000, 2000); > > > > + usleep_range(4, 5); > > > > > > nit: use 4, 41000 instead of 4, 5. Linux almost always > > > uses the longer delay, so that'll save ~9 ms. The only reason for the > > > range is to optimize kernel wakeups which is really not a concern > > > here. > > > > We need 50ms delay to meet the requirement. > > I'll respond to your v2, but if you need 50 ms then your current delay is > wrong. > > > -Doug
Re: [v2 1/3] drm/panel: ili9882t: Break out as separate driver
Hi, On Wed, Oct 11, 2023 at 3:11 AM Doug Anderson wrote: > > Hi, > > On Tue, Oct 10, 2023 at 5:14 AM Cong Yang > wrote: > > > > diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c > > b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c > > new file mode 100644 > > index ..e095ad91c4bc > > --- /dev/null > > +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c > > @@ -0,0 +1,762 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Panels based on the Ilitek ILI9882T display controller. > > + */ > > +#include > > +#include > > +#include > > +#include > > +#include > > nit: remove include of linux/of_device.h since you don't use any of > the functions declared there. It seems that of_device_get_match_data will be used. > > > > +#include > > + > > +#include > > +#include > > +#include > > +#include > > + > > +#include > > + > > +/* > > + * Use this descriptor struct to describe different panels using the > > + * Ilitek ILI9882T display controller. > > + */ > > +struct panel_desc { > > + const struct drm_display_mode *modes; > > + unsigned int bpc; > > + > > + /** > > +* @width_mm: width of the panel's active display area > > +* @height_mm: height of the panel's active display area > > +*/ > > + struct { > > + unsigned int width_mm; > > + unsigned int height_mm; > > + } size; > > + > > + unsigned long mode_flags; > > + enum mipi_dsi_pixel_format format; > > + const struct panel_init_cmd *init_cmds; > > + unsigned int init_cmd_length; > > Remove "init_cmd_length" since it's now unused. Done,thanks. > > > > +static void ili9882t_remove(struct mipi_dsi_device *dsi) > > +{ > > + struct ili9882t *ili = mipi_dsi_get_drvdata(dsi); > > + int ret; > > + > > + > > + ret = mipi_dsi_detach(dsi); > > nit: remove extra blank line above. Done,thanks. > > > Other than nits, this looks good to me now. > > Reviewed-by: Douglas Anderson
Re: [PATCH v3] drm/virtio: add new virtio gpu capset definitions
On Tue, Oct 10, 2023 at 11:52:14PM +0800, Dmitry Osipenko wrote: > On 10/10/23 18:40, Dmitry Osipenko wrote: > > On 10/10/23 16:57, Huang Rui wrote: > >> These definitions are used fro qemu, and qemu imports this marco in the > >> headers to enable gfxstream, venus, cross domain, and drm (native > >> context) for virtio gpu. So it should add them even kernel doesn't use > >> this. > >> > >> Signed-off-by: Huang Rui > >> Reviewed-by: Akihiko Odaki > >> --- > >> > >> Changes V1 -> V2: > >> - Add all capsets including gfxstream and venus in kernel header (Dmitry > >> Osipenko) > >> > >> Changes V2 -> V3: > >> - Add missed capsets including cross domain and drm (native context) > >> (Dmitry Osipenko) > >> > >> v1: > >> https://lore.kernel.org/lkml/20230915105918.3763061-1-ray.hu...@amd.com/ > >> v2: > >> https://lore.kernel.org/lkml/20231010032553.1138036-1-ray.hu...@amd.com/ > >> > >> include/uapi/linux/virtio_gpu.h | 4 > >> 1 file changed, 4 insertions(+) > >> > >> diff --git a/include/uapi/linux/virtio_gpu.h > >> b/include/uapi/linux/virtio_gpu.h > >> index f556fde07b76..240911c8da31 100644 > >> --- a/include/uapi/linux/virtio_gpu.h > >> +++ b/include/uapi/linux/virtio_gpu.h > >> @@ -309,6 +309,10 @@ struct virtio_gpu_cmd_submit { > >> > >> #define VIRTIO_GPU_CAPSET_VIRGL 1 > >> #define VIRTIO_GPU_CAPSET_VIRGL2 2 > >> +#define VIRTIO_GPU_CAPSET_GFXSTREAM 3 > > > > The GFXSTREAM capset isn't correct, it should be GFXSTREAM_VULKAN in > > accordance to [1] and [2]. There are more capsets for GFXSTREAM. > > > > [1] > > https://github.com/google/crosvm/blob/main/rutabaga_gfx/src/rutabaga_utils.rs#L172 > > > > [2] > > https://patchwork.kernel.org/project/qemu-devel/patch/20231006010835.444-7-gurchetansi...@chromium.org/ > > Though, maybe those are "rutabaga" capsets that not related to > virtio-gpu because crosvm has another defs for virtio-gpu capsets [3]. > The DRM capset is oddly missing in [3] and code uses "rutabaga" capset > for DRM and virtio-gpu. > > [3] > https://github.com/google/crosvm/blob/main/devices/src/virtio/gpu/protocol.rs#L416 Yes, [3] is the file that I referred to add these capsets definitions. And it's defined as gfxstream not gfxstream_vulkan. > > Gurchetan, could you please clarify which capsets definitions are > related to virtio-gpu and gfxstream. The > GFXSTREAM_VULKAN/GLES/MAGMA/COMPOSER or just the single GFXSTREAM? > Gurchetan, may we have your insight? Thanks, Ray > -- > Best regards, > Dmitry >
Re: [PATCH v1 0/2] [PATCH] hwmon: (pmbus/max31785) Add minimum delay between bus accesses
On Wed, 11 Oct 2023, at 09:29, Guenter Roeck wrote: > On Tue, Oct 10, 2023 at 08:58:06PM +0200, Wolfram Sang wrote: >> Hi Guenter, >> >> > > > Reference to Andrew's previous proposal: >> > > > https://lore.kernel.org/all/20200914122811.3295678-1-and...@aj.id.au/ >> > > >> > > I do totally agree with Guenter's comment[1], though. This just affects >> > > a few drivers and this patch is way too intrusive for the I2C core. The >> > > later suggested prepare_device() callback[2] sounds better to me. I >> > > still haven't fully understood why this all cannot be handled in the >> > > driver's probe. Could someone give me a small summary about that? >> > > >> > >> > Lots of PMBus devices have the same problem, we have always handled >> > it in PMBus drivers by implementing local wait code, and your references >> > point that out. >> >> I am confused now. Reading your reply: >> >> "I am not sure if an implementation in the i2c core is desirable. It >> looks quite invasive to me, and it won't solve the problem for all >> devices since it isn't always a simple "wait microseconds between >> accesses". For example, some devices may require a wait after a write >> but not after a read, or a wait only after certain commands (such as >> commands writing to an EEPROM)." >> >> I get the impression you don't prefer to have a generic mechanism in the >> I2C core. This I share. Your response now sounds like you do support >> that idea now? >> > > I didn't (want to) say that. I am perfectly happy with driver specific > code, and I would personally still very much prefer it. I only wanted to > suggest that _if_ a generic solution is implemented, it should cover all > existing use cases and not just this one. But, really, I'd rather leave > that alone and not risk introducing regressions to existing drivers. We had an out-of-tree patch for the max31785[1] that I wrote a little after the initial discussion on this generic throttling and possibly somewhat before the other drivers had their delays added. Recently Joel pointed out the addition of the delays in the other drivers and I raised the idea that we could get rid of that out-of-tree patch by doing the same. Guenter's point about the work-arounds being very particular to the device is good justification for not trying to fix drivers that we can't immediately test - not that the series did that, but arguably if we're shooting for the generic solution then it should. So I agree with Guenter that we probably want to do down the path of adding the delays directly into the max31785 driver and not trying to over-generalise. Lakshmi: Apologies for misleading you in some way there - unfortunately I can't go back to understand exactly what I suggested as I've changed jobs in the mean time. Andrew [1]: https://github.com/openbmc/linux/commit/44e1397368a70ffe9cdad1f9212ffdef8c16b9be
Re: linux-next: manual merge of the drm-msm tree with the mm, drm trees
Hey Dave, lmk how you want me to handle this to make it easier for you when I send my pull request for 6.7.. I can merge drm-next to take care of *that* conflict (either before I send my PR or push it somewhere where you can see the resolution) but not sure about the mm conflict since pulling that might get me ahead of drm-next. Either way, Stephen's resolution looks correct. BR, -R On Mon, Oct 9, 2023 at 6:33 PM Stephen Rothwell wrote: > > Hi all, > > FIXME: Add owner of second tree to To: >Add author(s)/SOB of conflicting commits. > > Today's linux-next merge of the drm-msm tree got conflicts in: > > drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c > drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c > drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c > drivers/gpu/drm/msm/msm_drv.c > > between commits: > > 01790d5e372f ("drm/msm: Convert to platform remove callback returning void") > cd61a76c210a ("drm/msm: dynamically allocate the drm-msm_gem shrinker") > > from the mm, drm trees and commits: > > 283add3e6405 ("drm/msm: remove shutdown callback from msm_platform_driver") > 506efcba3129 ("drm/msm: carve out KMS code from msm_drv.c") > > from the drm-msm tree. > > I fixed it up (see below) and can carry the fix as necessary. This > is now fixed as far as linux-next is concerned, but any non trivial > conflicts should be mentioned to your upstream maintainer when your tree > is submitted for merging. You may also want to consider cooperating > with the maintainer of the conflicting tree to minimise any particularly > complex conflicts. > > -- > Cheers, > Stephen Rothwell > > diff --cc drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c > index 82381d12414d,d14ae316796c.. > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c > @@@ -1299,12 -1230,72 +1230,70 @@@ static int dpu_kms_init(struct drm_devi > > static int dpu_dev_probe(struct platform_device *pdev) > { > - return msm_drv_probe(>dev, dpu_kms_init); > + struct device *dev = >dev; > + struct dpu_kms *dpu_kms; > + int irq; > + int ret = 0; > + > + dpu_kms = devm_kzalloc(dev, sizeof(*dpu_kms), GFP_KERNEL); > + if (!dpu_kms) > + return -ENOMEM; > + > + dpu_kms->pdev = pdev; > + > + ret = devm_pm_opp_set_clkname(dev, "core"); > + if (ret) > + return ret; > + /* OPP table is optional */ > + ret = devm_pm_opp_of_add_table(dev); > + if (ret && ret != -ENODEV) > + return dev_err_probe(dev, ret, "invalid OPP table in device > tree\n"); > + > + ret = devm_clk_bulk_get_all(>dev, _kms->clocks); > + if (ret < 0) > + return dev_err_probe(dev, ret, "failed to parse clocks\n"); > + > + dpu_kms->num_clocks = ret; > + > + irq = platform_get_irq(pdev, 0); > + if (irq < 0) > + return dev_err_probe(dev, irq, "failed to get irq\n"); > + > + dpu_kms->base.irq = irq; > + > + dpu_kms->mmio = msm_ioremap(pdev, "mdp"); > + if (IS_ERR(dpu_kms->mmio)) { > + ret = PTR_ERR(dpu_kms->mmio); > + DPU_ERROR("mdp register memory map failed: %d\n", ret); > + dpu_kms->mmio = NULL; > + return ret; > + } > + DRM_DEBUG("mapped dpu address space @%pK\n", dpu_kms->mmio); > + > + dpu_kms->vbif[VBIF_RT] = msm_ioremap(pdev, "vbif"); > + if (IS_ERR(dpu_kms->vbif[VBIF_RT])) { > + ret = PTR_ERR(dpu_kms->vbif[VBIF_RT]); > + DPU_ERROR("vbif register memory map failed: %d\n", ret); > + dpu_kms->vbif[VBIF_RT] = NULL; > + return ret; > + } > + > + dpu_kms->vbif[VBIF_NRT] = msm_ioremap_quiet(pdev, "vbif_nrt"); > + if (IS_ERR(dpu_kms->vbif[VBIF_NRT])) { > + dpu_kms->vbif[VBIF_NRT] = NULL; > + DPU_DEBUG("VBIF NRT is not defined"); > + } > + > + ret = dpu_kms_parse_data_bus_icc_path(dpu_kms); > + if (ret) > + return ret; > + > + return msm_drv_probe(>dev, dpu_kms_init, _kms->base); > } > > -static int dpu_dev_remove(struct platform_device *pdev) > +static void dpu_dev_remove(struct platform_device *pdev) > { > component_master_del(>dev, _drm_ops); > - > - return 0; > } > > static int __maybe_unused dpu_runtime_suspend(struct device *dev) > @@@ -1380,8 -1371,8 +1369,8 @@@ MODULE_DEVICE_TABLE(of, dpu_dt_match) > > static struct platform_driver dpu_driver = { > .probe = dpu_dev_probe, > - .remove = dpu_dev_remove, > + .remove_new = dpu_dev_remove, > - .shutdown = msm_drv_shutdown, > + .shutdown = msm_kms_shutdown, > .driver = { > .name = "msm_dpu", > .of_match_table = dpu_dt_match, > diff --cc drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c > index e5012fa6771f,982b7689e5b6.. > --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c > +++
Re: [PATCH v3 04/16] platform/x86/amd/pmf: Add support for PMF Policy Binary
On 10/10/2023 9:56 PM, Mario Limonciello wrote: > On 10/10/2023 07:59, Shyam Sundar S K wrote: >> PMF Policy binary is a encrypted and signed binary that will be part >> of the BIOS. PMF driver via the ACPI interface checks the existence >> of Smart PC bit. If the advertised bit is found, PMF driver walks >> the acpi namespace to find out the policy binary size and the address >> which has to be passed to the TA during the TA init sequence. >> >> The policy binary is comprised of inputs (or the events) and outputs >> (or the actions). With the PMF ecosystem, OEMs generate the policy >> binary (or could be multiple binaries) that contains a supported set >> of inputs and outputs which could be specifically carved out for each >> usage segment (or for each user also) that could influence the system >> behavior either by enriching the user experience or/and boost/throttle >> power limits. >> >> Once the TA init command succeeds, the PMF driver sends the changing >> events in the current environment to the TA for a constant sampling >> frequency time (the event here could be a lid close or open) and >> if the policy binary has corresponding action built within it, the >> TA sends the action for it in the subsequent enact command. >> >> If the inputs sent to the TA has no output defined in the policy >> binary generated by OEMs, there will be no action to be performed >> by the PMF driver. >> >> Example policies: >> >> 1) if slider is performance ; set the SPL to 40W >> Here PMF driver registers with the platform profile interface and >> when the slider position is changed, PMF driver lets the TA know >> about this. TA sends back an action to update the Sustained >> Power Limit (SPL). PMF driver updates this limit via the PMFW mailbox. >> >> 2) if user_away ; then lock the system >> Here PMF driver hooks to the AMD SFH driver to know the user presence >> and send the inputs to TA and if the condition is met, the TA sends >> the action of locking the system. PMF driver generates a uevent and >> based on the udev rule in the userland the system gets locked with >> systemctl. >> >> The intent here is to provide the OEM's to make a policy to lock the >> system when the user is away ; but the userland can make a choice to >> ignore it. >> >> and so on. >> >> The OEMs will have an utility to create numerous such policies and >> the policies shall be reviewed by AMD before signing and encrypting >> them. Policies are shared between operating systems to have seemless >> user >> experience. >> >> Since all this action has to happen via the "amdtee" driver, currently >> there is no caller for it in the kernel which can load the amdtee >> driver. >> Without amdtee driver loading onto the system the "tee" calls shall >> fail >> from the PMF driver. Hence an explicit "request_module" has been added >> to address this. >> >> Signed-off-by: Shyam Sundar S K >> --- >> drivers/platform/x86/amd/pmf/Kconfig | 2 +- >> drivers/platform/x86/amd/pmf/acpi.c | 37 +++ >> drivers/platform/x86/amd/pmf/core.c | 13 +++ >> drivers/platform/x86/amd/pmf/pmf.h | 136 >> drivers/platform/x86/amd/pmf/tee-if.c | 146 >> +- >> 5 files changed, 331 insertions(+), 3 deletions(-) >> >> diff --git a/drivers/platform/x86/amd/pmf/Kconfig >> b/drivers/platform/x86/amd/pmf/Kconfig >> index 32a029e8db80..f246252bddd8 100644 >> --- a/drivers/platform/x86/amd/pmf/Kconfig >> +++ b/drivers/platform/x86/amd/pmf/Kconfig >> @@ -9,7 +9,7 @@ config AMD_PMF >> depends on POWER_SUPPLY >> depends on AMD_NB >> select ACPI_PLATFORM_PROFILE >> - depends on TEE >> + depends on TEE && AMDTEE >> help >> This driver provides support for the AMD Platform Management >> Framework. >> The goal is to enhance end user experience by making AMD PCs >> smarter, >> diff --git a/drivers/platform/x86/amd/pmf/acpi.c >> b/drivers/platform/x86/amd/pmf/acpi.c >> index 3fc5e4547d9f..d0512af2cd42 100644 >> --- a/drivers/platform/x86/amd/pmf/acpi.c >> +++ b/drivers/platform/x86/amd/pmf/acpi.c >> @@ -286,6 +286,43 @@ int apmf_install_handler(struct amd_pmf_dev >> *pmf_dev) >> return 0; >> } >> +static acpi_status apmf_walk_resources(struct acpi_resource *res, >> void *data) >> +{ >> + struct amd_pmf_dev *dev = data; >> + >> + switch (res->type) { >> + case ACPI_RESOURCE_TYPE_ADDRESS64: >> + dev->policy_addr = res->data.address64.address.minimum; >> + dev->policy_sz = res->data.address64.address.address_length; >> + break; >> + case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: >> + dev->policy_addr = res->data.fixed_memory32.address; >> + dev->policy_sz = res->data.fixed_memory32.address_length; >> + break; >> + } >> + >> + if (!dev->policy_addr || dev->policy_sz > POLICY_BUF_MAX_SZ || >> dev->policy_sz == 0) { >> + pr_err("Incorrect Policy params, possibly a SBIOS bug\n"); >> + return AE_ERROR; >> +
Re: [PATCH 1/2] drm/tegra: Return an error code if fails
Hi, On 2023/10/10 23:31, Thierry Reding wrote: On Tue, Oct 10, 2023 at 03:22:56PM +0200, Thierry Reding wrote: On Mon, Jun 26, 2023 at 10:33:30PM +0800, Sui Jingfeng wrote: Return -ENOMEM if tegra_bo_mmap() fails. Signed-off-by: Sui Jingfeng --- drivers/gpu/drm/tegra/gem.c | 2 ++ 1 file changed, 2 insertions(+) Sorry, this fell through the cracks. I think it'd be better if tegra_bo_mmap() were to be improved to always return either an ERR_PTR() encoded error code or a valid pointer. Throwing NULL into the mix isn't useful because it typically means something like -ENOMEM anyway. Error codes are more explicit, so since we're already using them for some cases, might as well return them for all. Actually, looks like tegra_bo_mmap() never actually returns an ERR_PTR() encoded error code. It's either obj->vaddr, the return value of vmap() (which is either NULL or the address of the mapping), or the address obtained from dma_buf_vmap_unlocked() (i.e. map.vaddr) or NULL on failure. So I think it would equally make sense to keep your patch and to remove the IS_ERR() check below it. I would slightly prefer the first option, but either is fine. How about the attached patch? I also prefer the prefer the first option. The attached patch is more better, because it solve the problem at lower level. Reviewed-by: Sui Jingfeng Thierry
Re: [PATCH v3 08/16] platform/x86/amd/pmf: Add support to update system state
On 10/10/2023 9:33 PM, Mario Limonciello wrote: > On 10/10/2023 07:59, Shyam Sundar S K wrote: >> PMF driver based on the output actions from the TA can request to >> update >> the system states like entering s0i3, lock screen etc. by generating >> an uevent. Based on the udev rules set in the userspace the event id >> matching the uevent shall get updated accordingly using the systemctl. >> >> Sample udev rules under Documentation/admin-guide/pmf.rst. >> >> Signed-off-by: Shyam Sundar S K > > One minor nit below. > > Reviewed-by: Mario Limonciello > >> --- >> Documentation/admin-guide/index.rst | 1 + >> Documentation/admin-guide/pmf.rst | 25 +++ >> drivers/platform/x86/amd/pmf/pmf.h | 9 +++ >> drivers/platform/x86/amd/pmf/tee-if.c | 36 >> ++- >> 4 files changed, 70 insertions(+), 1 deletion(-) >> create mode 100644 Documentation/admin-guide/pmf.rst >> >> diff --git a/Documentation/admin-guide/index.rst >> b/Documentation/admin-guide/index.rst >> index 43ea35613dfc..fb40a1f6f79e 100644 >> --- a/Documentation/admin-guide/index.rst >> +++ b/Documentation/admin-guide/index.rst >> @@ -119,6 +119,7 @@ configure specific aspects of kernel behavior to >> your liking. >> parport >> perf-security >> pm/index >> + pmf >> pnp >> rapidio >> ras >> diff --git a/Documentation/admin-guide/pmf.rst >> b/Documentation/admin-guide/pmf.rst >> new file mode 100644 >> index ..6985bb5b9452 >> --- /dev/null >> +++ b/Documentation/admin-guide/pmf.rst >> @@ -0,0 +1,25 @@ >> +.. SPDX-License-Identifier: GPL-2.0 >> + >> +Set udev rules for PMF Smart PC Builder >> +--- >> + >> +AMD PMF(Platform Management Framework) Smart PC Solution builder >> has to set the system states >> +like S0i3, Screen lock, hibernate etc, based on the output actions >> provided by the PMF >> +TA (Trusted Application). >> + >> +In order for this to work the PMF driver generates a uevent for >> userspace to react to. Below are >> +sample udev rules that can facilitate this experience when a >> machine has PMF Smart PC solution builder >> +enabled. >> + >> +Please add the following line(s) to >> +``/etc/udev/rules.d/99-local.rules``:: >> + >> + DRIVERS=="amd-pmf", ACTION=="change", ENV{EVENT_ID}=="0", >> RUN+="/usr/bin/systemctl suspend" >> + DRIVERS=="amd-pmf", ACTION=="change", ENV{EVENT_ID}=="1", >> RUN+="/usr/bin/systemctl hibernate" >> + DRIVERS=="amd-pmf", ACTION=="change", ENV{EVENT_ID}=="2", >> RUN+="/bin/loginctl lock-sessions" >> + >> +EVENT_ID values: >> +0= Put the system to S0i3/S2Idle >> +1= Put the system to hibernate >> +2= Lock the screen >> + >> diff --git a/drivers/platform/x86/amd/pmf/pmf.h >> b/drivers/platform/x86/amd/pmf/pmf.h >> index 20f3e16b0a32..67f3d5a7 100644 >> --- a/drivers/platform/x86/amd/pmf/pmf.h >> +++ b/drivers/platform/x86/amd/pmf/pmf.h >> @@ -73,6 +73,7 @@ >> #define PMF_POLICY_STT_MIN 6 >> #define PMF_POLICY_STT_SKINTEMP_APU 7 >> #define PMF_POLICY_STT_SKINTEMP_HS2 8 >> +#define PMF_POLICY_SYSTEM_STATE 9 >> #define PMF_POLICY_P3T 38 >> /* TA macros */ >> @@ -440,6 +441,13 @@ struct apmf_dyn_slider_output { >> } __packed; >> /* Smart PC - TA internals */ > > I know that Ilpo had a comment about this in an earlier version that > there is a "__" instead of "_". I know this is intended behavior for > consistency with internal usage, but maybe it's worth having a comment > somewhere mentioning it's intended behavior? I'm not sure where. > I missed to change here. I have changed at other places too. >> +enum system_state { >> + SYSTEM_STATE__S0i3, >> + SYSTEM_STATE__S4, >> + SYSTEM_STATE__SCREEN_LOCK, >> + SYSTEM_STATE__MAX >> +}; >> + >> enum ta_slider { >> TA_BEST_BATTERY, /* Best Battery */ >> TA_BETTER_BATTERY, /* Better Battery */ >> @@ -471,6 +479,7 @@ enum ta_pmf_error_type { >> }; >> struct pmf_action_table { >> + enum system_state system_state; >> u32 spl; /* in mW */ >> u32 sppt; /* in mW */ >> u32 sppt_apuonly; /* in mW */ >> diff --git a/drivers/platform/x86/amd/pmf/tee-if.c >> b/drivers/platform/x86/amd/pmf/tee-if.c >> index 92879ae4f8f0..c08ef13a1494 100644 >> --- a/drivers/platform/x86/amd/pmf/tee-if.c >> +++ b/drivers/platform/x86/amd/pmf/tee-if.c >> @@ -24,6 +24,20 @@ MODULE_PARM_DESC(pb_actions_ms, "Policy binary >> actions sampling frequency (defau >> static const uuid_t amd_pmf_ta_uuid = UUID_INIT(0x6fd93b77, >> 0x3fb8, 0x524d, >> 0xb1, 0x2d, 0xc5, 0x29, 0xb1, 0x3d, 0x85, >> 0x43); >> +static const char *amd_pmf_uevent_as_str(unsigned int state) >> +{ >> + switch (state) { >> + case SYSTEM_STATE__S0i3: >> + return "S0i3"; >> + case SYSTEM_STATE__S4: >> + return "S4"; >> + case
Re: [PATCH RFC] dt-bindings: display: document display panel occlusions
On Wed Oct 11, 2023 at 1:35 AM CEST, Caleb Connolly wrote: > On 10/10/2023 23:53, Piotr Masłowski wrote: > They don't need to be correct, you don't need to complicate it, you just > need a value that plays nice. When it comes down to it you're much more > likely to be constrained by UI layout limitations by not being able to > model the precise corner curves of your device. The difference between a > circular and elliptical arc is negligible in all real world use cases. Well, with a large, weirdly-shaped display the curve will have to pass through more-or-less the right pixels for things like a-couple-px-thick frame to look right. I would expect e.g. a smartwatch UI to sometimes want to draw a constant-width frame along the screen border. Using a significantly different curve there will break that, so you would need to let them be similarly arbitrary to notches. >> That being said, imperfection isn't my main issue with curves. It's all >> the non-discreteness they bring to the table. As in, you now need to care >> about approximations, rounding, imprecise measurements and so on. > > My point is that actually you don't. Other than for animated visual > effects (where an undersized curve would absolutely be acceptable) I > can't conceive of a situation where plain triangles wouldn't be > suitable, again slightly undersized of course. Well, what I meant is not that you "have to care or it won't look good", but rather "that's an unnecessary degree of freedom" and I'm sure pepole will spend non-insignificant amounts of time caring about it. Both while gathering the data and while processing it. But you're right that it won't matter for typical corners – they are simply too small to make any difference here. >> Frankly, I don't see any significant cost here. It's very easy to gather >> and rather easy to process. > > Unless I'm mistaken, it would mean that for "odd" shapes like rounded > corners, the number of values you need to record would be directly > proportional to the number of rows. You can do some optimisations, but > that worst case is really not great. Especially when the arc > approximation requires a single value and covers all the same usecases > as well or better. You mean the devicetrees getting bloated? The blobs are already dozens of KiB in size. As for the sources, I don't have any real experience with them so I'm not sure what would be the best way of representing masks. Worst-case, they can be treated as raw bitmaps. But since the features will consist of typically one (or just a few) contiguous blobs they can be efficiently represented using for example chain codes. > You'd probably want your status bar icons to be equi-distant from the > top and side, at least that's what my Android phone does. But hey, maybe > you don't, we can't bikeshed UX design all day but I'd think a simple > radius is gonna be easier to deal with than a pixel mask in most cases > (especially considering that most UI frameworks don't work in the pixel > space anyway because of scaling). Good point! (Though don't they need to still align stuff to the pixel grid to avoid needless antialiasing?) Hmm, but known radius only helps you with the corners. For the notch, you would need a complex (and shape-shifting) equation, so you might as well figure out the constant-distance based on a mask I guess. > GNOME doesn't even use real pixels, macOS doesn't use real pixels. When > scaling comes into play the advantage is lost either way. Fractional scaling is a worthwile cause, but I don't think my argument really changes much when you're working with scaled pixels instead of real ones. >> >> Is there actually any use case that instead of ending up with pixels >> either way, would be better served by a (possibly inaccurate) curve? >> (future me here: that spline-along-the-border from earlier I guess) > > I feel like the burden of proof still lies with you here. I feel much > more comfortable with a handful of easy to reason about and explain > values (that can be easily reviewed by maintainers) over a blob of data > that grows with the resolution of your display. How are these reviewable without testing them on a device though? True that with corners a maintainer can make sure the values make some sense. But for notches they can only try visualizing the data to see if it more or less looks right. And that's equally true for pixel masks. Drawing the shape by hand would be less tedious for a curve I guess. Thanks for going over these things with me. It has definitely clarified many points and gave me a better understanding overall. I guess we won't convince each other that easily, so maybe let's see what others think. (but if you want to discuss it further, I'm all ears) And now that I think about it, maybe it's chain codes that could be the best of both worlds? They operate on pixels and so remain exact, but also are basically curves – just very simple ones. I'll have to think this through. -- Cheers, Piotr
[PATCH] drm/edid: fix a possible null pointer dereference
In drm_mode_std(), the return value of drm_gtf_mode(), drm_gtf_mode() and drm_cvt_mode() is assigned to mode, which will lead to a NULL pointer dereference on failure of drm_gtf_mode(), drm_gtf_mode() and drm_cvt_mode(). Add a check to avoid null point dereference. Signed-off-by: Ma Ke --- drivers/gpu/drm/drm_edid.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 340da8257b51..e2c154c2b896 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -3381,6 +3381,8 @@ static struct drm_display_mode *drm_mode_std(struct drm_connector *connector, false); break; } + if (!mode) + return NULL; return mode; } -- 2.37.2
[PATCH] drm/radeon: fix a possible null pointer dereference
In radeon_tv_get_modes(), the return value of drm_cvt_mode() is assigned to mode, which will lead to a NULL pointer dereference on failure of drm_cvt_mode(). Add a check to avoid null point dereference. Signed-off-by: Ma Ke --- drivers/gpu/drm/radeon/radeon_connectors.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index d2f02c3dfce2..b84b58926106 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -1119,6 +1119,8 @@ static int radeon_tv_get_modes(struct drm_connector *connector) else { /* only 800x600 is supported right now on pre-avivo chips */ tv_mode = drm_cvt_mode(dev, 800, 600, 60, false, false, false); + if (!tv_mode) + return 0; tv_mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; drm_mode_probed_add(connector, tv_mode); } -- 2.37.2
Re: [PATCH RFC] dt-bindings: display: document display panel occlusions
On 10/10/2023 23:53, Piotr Masłowski wrote: > On Tue Oct 10, 2023 at 10:36 PM CEST, Caleb Connolly wrote: > >>> So why am I writing all of this? Well, the problem I see is that any >>> shape-based approach will likely suffer from both accuracy and >>> complexity issues. Describing curves is hard and processing them is >>> not something that should be included in e.g. whatever handles VTs. >> >> My proposal here doesn't require processing curves or doing any >> complicated calculations. If you know that the display has a 30px radius >> on all corners, you can adjust the VT to not use the top 30px of the >> screen and it will start exactly where the radius stops. > > Just a nitpick, but on a round smartwatch this approach will give you > a $width × 0px famebuffer ;D right right, it's a little more complicated, but not more or less with either approach. [...] >>> - gathering the data is very straightforward – just light the relevant >>> pixels one-by-one and check if you see them >>> - pixel-perfect accuracy is the default >> >> I think it would be fairly straightforward to do this for curve data >> too. You just bump the radius up/down until it looks right, or "good enough" > > Well, different people will have different standards and what might be > good enough for some will annoy others. I'm not saying that we need to > be perfect at all cost, but if there's a relatively easy way to cut down > on inconsistency, it might be worth taking. > > Additionally, having a very clear-cut quality indicator could remove a > whole class of bikeshedding options. (speaking of the devil xD) > > > The problem I have with curves is, the more 'correct' you make them, the > more convoluted they become. Like take for example the corners. Rounded > corners are circular right? But what if someone makes them 'squircular'? > Well, they are usually quite small anyway so maybe it will work out. > > But then what about a smartwatch with big, squircle-shaped display? Bam, > now you need to complicate how corners are handled. They don't need to be correct, you don't need to complicate it, you just need a value that plays nice. When it comes down to it you're much more likely to be constrained by UI layout limitations by not being able to model the precise corner curves of your device. The difference between a circular and elliptical arc is negligible in all real world use cases. > > But also: are rounded coners typically circular? Just now I've thrown a > OnePlus 6 (thank you so much for the great mainline support btw!) onto a > flatbed scanner. While a circle fits decently well there it's not really > a perfect fit, so maybe they went with a different curve after all. > > That being said, imperfection isn't my main issue with curves. It's all > the non-discreteness they bring to the table. As in, you now need to care > about approximations, rounding, imprecise measurements and so on. My point is that actually you don't. Other than for animated visual effects (where an undersized curve would absolutely be acceptable) I can't conceive of a situation where plain triangles wouldn't be suitable, again slightly undersized of course. > > >> I think the unfortunate truth is that approximating notches and rounded >> corners exclusively with regular arcs at the cost of pixel accuracy is >> just such a no-brainer. Pixel masks would be pixel accurate, but there >> is no benefit compared to a slightly underfit curve. > > Frankly, I don't see any significant cost here. It's very easy to gather > and rather easy to process. Unless I'm mistaken, it would mean that for "odd" shapes like rounded corners, the number of values you need to record would be directly proportional to the number of rows. You can do some optimisations, but that worst case is really not great. Especially when the arc approximation requires a single value and covers all the same usecases as well or better. > > Let me think about it… The most common operations I see people actually > doing with this data would be: > > * letterboxing – easy with both curves and masks > * ensuring padding | margins for icons on the screen – with curves you > can use a formula, but won't it be easier to just count pixels anyway? You'd probably want your status bar icons to be equi-distant from the top and side, at least that's what my Android phone does. But hey, maybe you don't, we can't bikeshed UX design all day but I'd think a simple radius is gonna be easier to deal with than a pixel mask in most cases (especially considering that most UI frameworks don't work in the pixel space anyway because of scaling). > * routing a spline along the border – like if you want to have some > periodic pattern drawn there, it's probably a bit easier to do with > curves > * drawing something at a constant distance from the border – with curves > you can again use exact formulas. But isn't that an overkill really? > I'd think most people will go for something like a
[PATCH v4 3/3] usb: typec: nb7vpq904m: switch to DRM_AUX_BRIDGE
Switch to using the new DRM_AUX_BRIDGE helper to create the transparent DRM bridge device instead of handcoding corresponding functionality. Reviewed-by: Heikki Krogerus Acked-by: Greg Kroah-Hartman Signed-off-by: Dmitry Baryshkov --- drivers/usb/typec/mux/Kconfig | 2 +- drivers/usb/typec/mux/nb7vpq904m.c | 44 ++ 2 files changed, 3 insertions(+), 43 deletions(-) diff --git a/drivers/usb/typec/mux/Kconfig b/drivers/usb/typec/mux/Kconfig index 65da61150ba7..e3fee531548f 100644 --- a/drivers/usb/typec/mux/Kconfig +++ b/drivers/usb/typec/mux/Kconfig @@ -40,7 +40,7 @@ config TYPEC_MUX_NB7VPQ904M tristate "On Semiconductor NB7VPQ904M Type-C redriver driver" depends on I2C depends on DRM || DRM=n - select DRM_PANEL_BRIDGE if DRM + select DRM_AUX_BRIDGE if DRM && OF select REGMAP_I2C help Say Y or M if your system has a On Semiconductor NB7VPQ904M Type-C diff --git a/drivers/usb/typec/mux/nb7vpq904m.c b/drivers/usb/typec/mux/nb7vpq904m.c index cda206cf0c38..b17826713753 100644 --- a/drivers/usb/typec/mux/nb7vpq904m.c +++ b/drivers/usb/typec/mux/nb7vpq904m.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include @@ -70,8 +70,6 @@ struct nb7vpq904m { bool swap_data_lanes; struct typec_switch *typec_switch; - struct drm_bridge bridge; - struct mutex lock; /* protect non-concurrent retimer & switch */ enum typec_orientation orientation; @@ -297,44 +295,6 @@ static int nb7vpq904m_retimer_set(struct typec_retimer *retimer, struct typec_re return ret; } -#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DRM_PANEL_BRIDGE) -static int nb7vpq904m_bridge_attach(struct drm_bridge *bridge, - enum drm_bridge_attach_flags flags) -{ - struct nb7vpq904m *nb7 = container_of(bridge, struct nb7vpq904m, bridge); - struct drm_bridge *next_bridge; - - if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) - return -EINVAL; - - next_bridge = devm_drm_of_get_bridge(>client->dev, nb7->client->dev.of_node, 0, 0); - if (IS_ERR(next_bridge)) { - dev_err(>client->dev, "failed to acquire drm_bridge: %pe\n", next_bridge); - return PTR_ERR(next_bridge); - } - - return drm_bridge_attach(bridge->encoder, next_bridge, bridge, -DRM_BRIDGE_ATTACH_NO_CONNECTOR); -} - -static const struct drm_bridge_funcs nb7vpq904m_bridge_funcs = { - .attach = nb7vpq904m_bridge_attach, -}; - -static int nb7vpq904m_register_bridge(struct nb7vpq904m *nb7) -{ - nb7->bridge.funcs = _bridge_funcs; - nb7->bridge.of_node = nb7->client->dev.of_node; - - return devm_drm_bridge_add(>client->dev, >bridge); -} -#else -static int nb7vpq904m_register_bridge(struct nb7vpq904m *nb7) -{ - return 0; -} -#endif - static const struct regmap_config nb7_regmap = { .max_register = 0x1f, .reg_bits = 8, @@ -461,7 +421,7 @@ static int nb7vpq904m_probe(struct i2c_client *client) gpiod_set_value(nb7->enable_gpio, 1); - ret = nb7vpq904m_register_bridge(nb7); + ret = drm_aux_bridge_register(dev); if (ret) goto err_disable_gpio; -- 2.39.2
[PATCH v4 2/3] phy: qcom: qmp-combo: switch to DRM_AUX_BRIDGE
Switch to using the new DRM_AUX_BRIDGE helper to create the transparent DRM bridge device instead of handcoding corresponding functionality. Acked-by: Vinod Koul Signed-off-by: Dmitry Baryshkov --- drivers/phy/qualcomm/Kconfig | 2 +- drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 44 ++- 2 files changed, 3 insertions(+), 43 deletions(-) diff --git a/drivers/phy/qualcomm/Kconfig b/drivers/phy/qualcomm/Kconfig index d891058b7c39..b57a0e786a61 100644 --- a/drivers/phy/qualcomm/Kconfig +++ b/drivers/phy/qualcomm/Kconfig @@ -63,7 +63,7 @@ config PHY_QCOM_QMP_COMBO depends on DRM || DRM=n select GENERIC_PHY select MFD_SYSCON - select DRM_PANEL_BRIDGE if DRM + select DRM_AUX_BRIDGE if DRM_BRIDGE && OF help Enable this to support the QMP Combo PHY transceiver that is used with USB3 and DisplayPort controllers on Qualcomm chips. diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c index 5e6fc8103e9d..fbca9c0fcba4 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c @@ -21,7 +21,7 @@ #include #include -#include +#include #include @@ -1419,8 +1419,6 @@ struct qmp_combo { struct clk_hw dp_link_hw; struct clk_hw dp_pixel_hw; - struct drm_bridge bridge; - struct typec_switch_dev *sw; enum typec_orientation orientation; }; @@ -3191,44 +3189,6 @@ static int qmp_combo_typec_switch_register(struct qmp_combo *qmp) } #endif -#if IS_ENABLED(CONFIG_DRM) -static int qmp_combo_bridge_attach(struct drm_bridge *bridge, - enum drm_bridge_attach_flags flags) -{ - struct qmp_combo *qmp = container_of(bridge, struct qmp_combo, bridge); - struct drm_bridge *next_bridge; - - if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) - return -EINVAL; - - next_bridge = devm_drm_of_get_bridge(qmp->dev, qmp->dev->of_node, 0, 0); - if (IS_ERR(next_bridge)) { - dev_err(qmp->dev, "failed to acquire drm_bridge: %pe\n", next_bridge); - return PTR_ERR(next_bridge); - } - - return drm_bridge_attach(bridge->encoder, next_bridge, bridge, -DRM_BRIDGE_ATTACH_NO_CONNECTOR); -} - -static const struct drm_bridge_funcs qmp_combo_bridge_funcs = { - .attach = qmp_combo_bridge_attach, -}; - -static int qmp_combo_dp_register_bridge(struct qmp_combo *qmp) -{ - qmp->bridge.funcs = _combo_bridge_funcs; - qmp->bridge.of_node = qmp->dev->of_node; - - return devm_drm_bridge_add(qmp->dev, >bridge); -} -#else -static int qmp_combo_dp_register_bridge(struct qmp_combo *qmp) -{ - return 0; -} -#endif - static int qmp_combo_parse_dt_lecacy_dp(struct qmp_combo *qmp, struct device_node *np) { struct device *dev = qmp->dev; @@ -3440,7 +3400,7 @@ static int qmp_combo_probe(struct platform_device *pdev) if (ret) return ret; - ret = qmp_combo_dp_register_bridge(qmp); + ret = drm_aux_bridge_register(dev); if (ret) return ret; -- 2.39.2
[PATCH v4 1/3] drm/bridge: add transparent bridge helper
Define a helper for creating simple transparent bridges which serve the only purpose of linking devices into the bridge chain up to the last bridge representing the connector. This is especially useful for DP/USB-C bridge chains, which can span across several devices, but do not require any additional functionality from the intermediate bridges. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/bridge/Kconfig | 9 ++ drivers/gpu/drm/bridge/Makefile | 1 + drivers/gpu/drm/bridge/aux-bridge.c | 132 include/drm/bridge/aux-bridge.h | 19 4 files changed, 161 insertions(+) create mode 100644 drivers/gpu/drm/bridge/aux-bridge.c create mode 100644 include/drm/bridge/aux-bridge.h diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index ba82a1142adf..f12eab62799f 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -12,6 +12,15 @@ config DRM_PANEL_BRIDGE help DRM bridge wrapper of DRM panels +config DRM_AUX_BRIDGE + tristate + depends on DRM_BRIDGE && OF + select AUXILIARY_BUS + select DRM_PANEL_BRIDGE + help + Simple transparent bridge that is used by several non-DRM drivers to + build bridges chain. + menu "Display Interface Bridges" depends on DRM && DRM_BRIDGE diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index 2b892b7ed59e..918e3bfff079 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_DRM_AUX_BRIDGE) += aux-bridge.o obj-$(CONFIG_DRM_CHIPONE_ICN6211) += chipone-icn6211.o obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o obj-$(CONFIG_DRM_CROS_EC_ANX7688) += cros-ec-anx7688.o diff --git a/drivers/gpu/drm/bridge/aux-bridge.c b/drivers/gpu/drm/bridge/aux-bridge.c new file mode 100644 index ..13fe794592f2 --- /dev/null +++ b/drivers/gpu/drm/bridge/aux-bridge.c @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2023 Linaro Ltd. + * + * Author: Dmitry Baryshkov + */ +#include +#include + +#include +#include + +static DEFINE_IDA(aux_bridge_ida); + +static void drm_aux_bridge_release(struct device *dev) +{ + struct auxiliary_device *adev = to_auxiliary_dev(dev); + + ida_free(_bridge_ida, adev->id); + + kfree(adev); +} + +static void drm_aux_bridge_unregister_adev(void *_adev) +{ + struct auxiliary_device *adev = _adev; + + auxiliary_device_delete(adev); + auxiliary_device_uninit(adev); +} + +int drm_aux_bridge_register(struct device *parent) +{ + struct auxiliary_device *adev; + int ret; + + adev = kzalloc(sizeof(*adev), GFP_KERNEL); + if (!adev) + return -ENOMEM; + + ret = ida_alloc(_bridge_ida, GFP_KERNEL); + if (ret < 0) { + kfree(adev); + return ret; + } + + adev->id = ret; + adev->name = "aux_bridge"; + adev->dev.parent = parent; +#ifdef CONFIG_OF + adev->dev.of_node = parent->of_node; +#endif + adev->dev.release = drm_aux_bridge_release; + + ret = auxiliary_device_init(adev); + if (ret) { + ida_free(_bridge_ida, adev->id); + kfree(adev); + return ret; + } + + ret = auxiliary_device_add(adev); + if (ret) { + auxiliary_device_uninit(adev); + return ret; + } + + return devm_add_action_or_reset(parent, drm_aux_bridge_unregister_adev, adev); +} +EXPORT_SYMBOL_GPL(drm_aux_bridge_register); + +struct drm_aux_bridge_data { + struct drm_bridge bridge; + struct drm_bridge *next_bridge; + struct device *dev; +}; + +static int drm_aux_bridge_attach(struct drm_bridge *bridge, + enum drm_bridge_attach_flags flags) +{ + struct drm_aux_bridge_data *data; + + if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) + return -EINVAL; + + data = container_of(bridge, struct drm_aux_bridge_data, bridge); + + return drm_bridge_attach(bridge->encoder, data->next_bridge, bridge, +DRM_BRIDGE_ATTACH_NO_CONNECTOR); +} + +static const struct drm_bridge_funcs drm_aux_bridge_funcs = { + .attach = drm_aux_bridge_attach, +}; + +static int drm_aux_bridge_probe(struct auxiliary_device *auxdev, + const struct auxiliary_device_id *id) +{ + struct drm_aux_bridge_data *data; + + data = devm_kzalloc(>dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->dev = >dev; + data->next_bridge = devm_drm_of_get_bridge(>dev, auxdev->dev.of_node, 0, 0); + if (IS_ERR(data->next_bridge)) + return dev_err_probe(>dev, PTR_ERR(data->next_bridge), +"failed to acquire
[PATCH v4 0/3 RESEND] drm: simplify support for transparent DRM bridges
[Resending since the discussion with Laurent has died with no response received for more than three weeks] Supporting DP/USB-C can result in a chain of several transparent bridges (PHY, redrivers, mux, etc). All attempts to implement DP support in a different way resulted either in series of hacks or in device tree not reflecting the actual hardware design. This results in drivers having similar boilerplate code for such bridges. Next, these drivers are susceptible to -EPROBE_DEFER loops: the next bridge can either be probed from the bridge->attach callback, when it is too late to return -EPROBE_DEFER, or from the probe() callback, when the next bridge might not yet be available, because it depends on the resources provided by the probing device. Device links can not fully solve this problem since there are mutual dependencies between adjancent devices. Last, but not least, this results in the the internal knowledge of DRM subsystem slowly diffusing into other subsystems, like PHY or USB/TYPEC. To solve all these issues, define a separate DRM helper, which creates separate aux device just for the bridge. During probe such aux device doesn't result in the EPROBE_DEFER loops. Instead it allows the device drivers to probe properly, according to the actual resource dependencies. The bridge auxdevs are then probed when the next bridge becomes available, sparing drivers from drm_bridge_attach() returning -EPROBE_DEFER. Changes since v3: - Moved bridge driver to gpu/drm/bridge (Neil Armstrong) - Renamed it to aux-bridge (since there is already a simple_bridge driver) - Made CONFIG_OF mandatory for this driver (Neil Armstrong) - Added missing kfree and ida_free (Dan Carpenter) Changes since v2: - ifdef'ed bridge->of_node access (LKP) Changes since v1: - Added EXPORT_SYMBOL_GPL / MODULE_LICENSE / etc. to drm_simple_bridge Dmitry Baryshkov (3): drm/bridge: add transparent bridge helper phy: qcom: qmp-combo: switch to DRM_AUX_BRIDGE usb: typec: nb7vpq904m: switch to DRM_AUX_BRIDGE drivers/gpu/drm/bridge/Kconfig| 9 ++ drivers/gpu/drm/bridge/Makefile | 1 + drivers/gpu/drm/bridge/aux-bridge.c | 132 ++ drivers/phy/qualcomm/Kconfig | 2 +- drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 44 +--- drivers/usb/typec/mux/Kconfig | 2 +- drivers/usb/typec/mux/nb7vpq904m.c| 44 +--- include/drm/bridge/aux-bridge.h | 19 8 files changed, 167 insertions(+), 86 deletions(-) create mode 100644 drivers/gpu/drm/bridge/aux-bridge.c create mode 100644 include/drm/bridge/aux-bridge.h -- 2.39.2
Re: [PATCH v1 0/2] [PATCH] hwmon: (pmbus/max31785) Add minimum delay between bus accesses
On Tue, Oct 10, 2023 at 08:58:06PM +0200, Wolfram Sang wrote: > Hi Guenter, > > > > > Reference to Andrew's previous proposal: > > > > https://lore.kernel.org/all/20200914122811.3295678-1-and...@aj.id.au/ > > > > > > I do totally agree with Guenter's comment[1], though. This just affects > > > a few drivers and this patch is way too intrusive for the I2C core. The > > > later suggested prepare_device() callback[2] sounds better to me. I > > > still haven't fully understood why this all cannot be handled in the > > > driver's probe. Could someone give me a small summary about that? > > > > > > > Lots of PMBus devices have the same problem, we have always handled > > it in PMBus drivers by implementing local wait code, and your references > > point that out. > > I am confused now. Reading your reply: > > "I am not sure if an implementation in the i2c core is desirable. It > looks quite invasive to me, and it won't solve the problem for all > devices since it isn't always a simple "wait microseconds between > accesses". For example, some devices may require a wait after a write > but not after a read, or a wait only after certain commands (such as > commands writing to an EEPROM)." > > I get the impression you don't prefer to have a generic mechanism in the > I2C core. This I share. Your response now sounds like you do support > that idea now? > I didn't (want to) say that. I am perfectly happy with driver specific code, and I would personally still very much prefer it. I only wanted to suggest that _if_ a generic solution is implemented, it should cover all existing use cases and not just this one. But, really, I'd rather leave that alone and not risk introducing regressions to existing drivers. > > What other summary are you looking for ? > > What the actual problem is with these devices. The cover letter only > mentions "issues with small command turn-around times". More details > would be nice. Is it between transfers? Or even between messages within > one transfer? Has it been tried to lower the bus frequency? Stuff like > this. > I don't know about this device, but in general the problem is that the devices need some delay between some or all transfers or otherwise react badly in one way or another. The problem is not always the same. Lower bus frequencies don't help, at least not for the devices where I have seen to problem myself. The issue is not bus speed, but time between transfers. Typically the underlying problem is that there is some microcontroller on the affected chips, and the microcode is less than perfect. For example, the microcode may not poll its I2C interface while it is busy writing into the chip's internal EEPROM or while it is updating some internal parameters as result of a previous I2C transfer. > > On a side note, if anyone plans to implement the prepare_device() callback, > > please make sure that it covers all requirements. It would be unfortunate > > if such a callback was implemented if that would still require per-driver > > code (besides the callback). > > Is there a list of that somewhere? Or does it mean going through all the > drivers and see what they currently do? > The latter. I never bothered trying to write up a list. Typically the behavior is not documented and needs to be tweaked a couple of times, and it may be different across chips supported by the same driver, or even across chip revisions. Any list trying to keep track of the various details would be difficult to maintain and notoriously be outdated. Guenter
Re: [PATCH RFC] dt-bindings: display: document display panel occlusions
On Tue Oct 10, 2023 at 10:36 PM CEST, Caleb Connolly wrote: >> So why am I writing all of this? Well, the problem I see is that any >> shape-based approach will likely suffer from both accuracy and >> complexity issues. Describing curves is hard and processing them is >> not something that should be included in e.g. whatever handles VTs. > > My proposal here doesn't require processing curves or doing any > complicated calculations. If you know that the display has a 30px radius > on all corners, you can adjust the VT to not use the top 30px of the > screen and it will start exactly where the radius stops. Just a nitpick, but on a round smartwatch this approach will give you a $width × 0px famebuffer ;D > > If you know that there is a (potentially very curvy) notch at the top of > the screen, you can just iterate over the arcs, add their radius to > their Y coordinate and take the maximum. This will always give you at > least the height of the notch (you'd probably want to check that their > angle is vaguely downward, but again this is trivial fast integer math). Yeah, I was talking about curves in general. Your proposal is on the low-complexity side thankfully. >> - gathering the data is very straightforward – just light the relevant >> pixels one-by-one and check if you see them >> - pixel-perfect accuracy is the default > > I think it would be fairly straightforward to do this for curve data > too. You just bump the radius up/down until it looks right, or "good enough" Well, different people will have different standards and what might be good enough for some will annoy others. I'm not saying that we need to be perfect at all cost, but if there's a relatively easy way to cut down on inconsistency, it might be worth taking. Additionally, having a very clear-cut quality indicator could remove a whole class of bikeshedding options. (speaking of the devil xD) The problem I have with curves is, the more 'correct' you make them, the more convoluted they become. Like take for example the corners. Rounded corners are circular right? But what if someone makes them 'squircular'? Well, they are usually quite small anyway so maybe it will work out. But then what about a smartwatch with big, squircle-shaped display? Bam, now you need to complicate how corners are handled. But also: are rounded coners typically circular? Just now I've thrown a OnePlus 6 (thank you so much for the great mainline support btw!) onto a flatbed scanner. While a circle fits decently well there it's not really a perfect fit, so maybe they went with a different curve after all. That being said, imperfection isn't my main issue with curves. It's all the non-discreteness they bring to the table. As in, you now need to care about approximations, rounding, imprecise measurements and so on. > I think the unfortunate truth is that approximating notches and rounded > corners exclusively with regular arcs at the cost of pixel accuracy is > just such a no-brainer. Pixel masks would be pixel accurate, but there > is no benefit compared to a slightly underfit curve. Frankly, I don't see any significant cost here. It's very easy to gather and rather easy to process. Let me think about it… The most common operations I see people actually doing with this data would be: * letterboxing – easy with both curves and masks * ensuring padding | margins for icons on the screen – with curves you can use a formula, but won't it be easier to just count pixels anyway? * routing a spline along the border – like if you want to have some periodic pattern drawn there, it's probably a bit easier to do with curves * drawing something at a constant distance from the border – with curves you can again use exact formulas. But isn't that an overkill really? I'd think most people will go for something like a morphological dilation instead > > Any program which wanted to make use of the curve information would have > to run a whole curve fitting algorithm, whereas there simply aren't any > programs which need to know about display occlusions to a pixel-accurate > level. For padding a status bar you do a single trig equation, for > avoiding the notch in fullscreen you would query the DRM subsystem which > presumably would export the dimensions of a letterboxed "usable size". What could the curve information be needed for though? The more I think about it, the less value I see in it really. Like, if you're adjusting the screen contents, pixels _are_ the smallest unit you need to concern yourself with. The only thing that comes up to my mind is if you were to animate the cutout shape somewhere else, zoomed in. And thats already a quite contrived scenario. Is there actually any use case that instead of ending up with pixels either way, would be better served by a (possibly inaccurate) curve? (future me here: that spline-along-the-border from earlier I guess) -- Cheers, Piotr Masłowski
Re: [PATCH v2 00/15] sysctl: Remove sentinel elements from drivers
On Mon, Oct 02, 2023 at 10:55:17AM +0200, Joel Granados via B4 Relay wrote: > Changes in v2: > - Left the dangling comma in the ctl_table arrays. > - Link to v1: > https://lore.kernel.org/r/20230928-jag-sysctl_remove_empty_elem_drivers-v1-0-e59120fca...@samsung.com Thanks! Pushed onto sysctl-next for wider testing. Luis
[PATCH 1/3] drm/ci: Add SM8250 job to CI
Add job for testing the Qualcomm RB5 board to CI. This will allow developers working on MSM chipsets to test their changes on the SM8250 chipset. This board shall be hosted and maintained by Qualcomm. For now, keep the test a manual-run only. We will drop the tag after stabilizing the tests and addressing some outstanding failures. Signed-off-by: Abhinav Kumar Signed-off-by: Jessica Zhang --- drivers/gpu/drm/ci/build.sh | 1 + drivers/gpu/drm/ci/test.yml | 15 +++ 2 files changed, 16 insertions(+) diff --git a/drivers/gpu/drm/ci/build.sh b/drivers/gpu/drm/ci/build.sh index 7b014287a041..63bfdcaa897e 100644 --- a/drivers/gpu/drm/ci/build.sh +++ b/drivers/gpu/drm/ci/build.sh @@ -26,6 +26,7 @@ if [[ "$KERNEL_ARCH" = "arm64" ]]; then DEVICE_TREES+=" arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-juniper-sku16.dtb" DEVICE_TREES+=" arch/arm64/boot/dts/mediatek/mt8192-asurada-spherion-r0.dtb" DEVICE_TREES+=" arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r5.dtb" +DEVICE_TREES+=" arch/arm64/boot/dts/qcom/qrb5165-rb5.dtb" elif [[ "$KERNEL_ARCH" = "arm" ]]; then GCC_ARCH="arm-linux-gnueabihf" DEBIAN_ARCH="armhf" diff --git a/drivers/gpu/drm/ci/test.yml b/drivers/gpu/drm/ci/test.yml index 6473cddaa7a9..7ef0d261216e 100644 --- a/drivers/gpu/drm/ci/test.yml +++ b/drivers/gpu/drm/ci/test.yml @@ -138,6 +138,21 @@ msm:sdm845: script: - ./install/bare-metal/cros-servo.sh +msm:sm8250: + extends: +- .baremetal-igt-arm64 + stage: msm + variables: +DRIVER_NAME: msm +BM_DTB: https://${PIPELINE_ARTIFACTS_BASE}/arm64/qrb5165-rb5.dtb +GPU_VERSION: sm8250 +RUNNER_TAG: qcom-freedreno-rb5 +TEST_PHASE_TIMEOUT: 180 + script: +- ./install/bare-metal/fastboot.sh + rules: +- when: manual + rockchip:rk3288: extends: - .lava-igt:arm32 -- 2.42.0
[PATCH 3/3] drm/ci: Add skips, fails and flakes for SM8250
Add skips, fails and flakes for the SM8250 test. Generated using update-xfails.py [1] [1] https://patchwork.freedesktop.org/patch/561453/?series=124793=1 Signed-off-by: Abhinav Kumar Signed-off-by: Jessica Zhang --- drivers/gpu/drm/ci/xfails/msm-sm8250-fails.txt | 29 + drivers/gpu/drm/ci/xfails/msm-sm8250-flakes.txt | 3 +++ drivers/gpu/drm/ci/xfails/msm-sm8250-skips.txt | 8 +++ 3 files changed, 40 insertions(+) diff --git a/drivers/gpu/drm/ci/xfails/msm-sm8250-fails.txt b/drivers/gpu/drm/ci/xfails/msm-sm8250-fails.txt new file mode 100644 index ..cc8ae32e90e7 --- /dev/null +++ b/drivers/gpu/drm/ci/xfails/msm-sm8250-fails.txt @@ -0,0 +1,29 @@ +kms_3d,Fail +kms_atomic_transition@plane-all-modeset-transition,Timeout +kms_color@ctm-0-25,Fail +kms_color@ctm-0-50,Fail +kms_color@ctm-0-75,Fail +kms_color@ctm-blue-to-red,Fail +kms_color@ctm-negative,Fail +kms_color@ctm-red-to-blue,Fail +kms_color@ctm-signed,Fail +kms_cursor_legacy@basic-flip-after-cursor-varying-size,Fail +kms_cursor_legacy@basic-flip-before-cursor-varying-size,Fail +kms_cursor_legacy@cursor-vs-flip-atomic-transitions-varying-size,Fail +kms_cursor_legacy@cursor-vs-flip-toggle,Fail +kms_cursor_legacy@cursor-vs-flip-varying-size,Fail +kms_cursor_legacy@short-flip-after-cursor-atomic-transitions-varying-size,Fail +kms_cursor_legacy@short-flip-before-cursor-atomic-transitions-varying-size,Fail +kms_cursor_legacy@short-flip-before-cursor-toggle,Fail +kms_hdmi_inject@inject-4k,Fail +kms_pipe_crc_basic@compare-crc-sanitycheck-nv12,Fail +kms_plane@pixel-format,Fail +kms_plane@pixel-format-source-clamping,Fail +kms_plane@plane-position-covered,Fail +kms_plane@plane-position-hole,Fail +kms_plane@plane-position-hole-dpms,Fail +kms_plane_alpha_blend@alpha-7efc,Fail +kms_plane_alpha_blend@coverage-7efc,Fail +kms_plane_alpha_blend@coverage-vs-premult-vs-constant,Fail +kms_plane_cursor@overlay,Fail +kms_rmfb@close-fd,Fail diff --git a/drivers/gpu/drm/ci/xfails/msm-sm8250-flakes.txt b/drivers/gpu/drm/ci/xfails/msm-sm8250-flakes.txt new file mode 100644 index ..0b55665184c1 --- /dev/null +++ b/drivers/gpu/drm/ci/xfails/msm-sm8250-flakes.txt @@ -0,0 +1,3 @@ +kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size +kms_cursor_legacy@flip-vs-cursor-varying-size +kms_plane_cursor@viewport diff --git a/drivers/gpu/drm/ci/xfails/msm-sm8250-skips.txt b/drivers/gpu/drm/ci/xfails/msm-sm8250-skips.txt new file mode 100644 index ..c20422c58e4d --- /dev/null +++ b/drivers/gpu/drm/ci/xfails/msm-sm8250-skips.txt @@ -0,0 +1,8 @@ +# Suspend to RAM seems to be broken on this machine +.*suspend.* + +# reboots device +kms_plane_scaling.* + +# long execution time +kms_flip.* -- 2.42.0
[PATCH 0/3] drm/ci: Add support for SM8250 Gitlab Runner
Recently, we've registered a Gitlab runner for a Qualcomm RB5 device that will be hosted and maintained in Qualcomm labs. This series will add a corresponding CI job for testing SM8250 devices and add the skip/fails/flakes list. We were able to complete a successful run [1] with these changes. For now, we will keep the job as manual trigger only and drop that rule later after we stabilize the tests. [1] https://gitlab.freedesktop.org/drm/msm/-/jobs/50092719 --- Jessica Zhang (3): drm/ci: Add SM8250 job to CI drm/ci: enable CONFIG_INTERCONNECT_QCOM_SM8250 for arm64 config drm/ci: Add skips, fails and flakes for SM8250 drivers/gpu/drm/ci/arm64.config | 1 + drivers/gpu/drm/ci/build.sh | 1 + drivers/gpu/drm/ci/test.yml | 15 + drivers/gpu/drm/ci/xfails/msm-sm8250-fails.txt | 29 + drivers/gpu/drm/ci/xfails/msm-sm8250-flakes.txt | 3 +++ drivers/gpu/drm/ci/xfails/msm-sm8250-skips.txt | 8 +++ 6 files changed, 57 insertions(+) --- base-commit: dcd88f8c63341ed11a8c5019408f62202cd9d1f2 change-id: 20230919-rb5-runner-77ec32bd61e7 Best regards, -- Jessica Zhang
[PATCH 2/3] drm/ci: enable CONFIG_INTERCONNECT_QCOM_SM8250 for arm64 config
Set CONFIG_INTERCONNECT_QCOM_SM8250 needs to =y so that the ASIX AX88179 USB Ethernet driver can be probed in time to set up nfsroot. Signed-off-by: Abhinav Kumar Signed-off-by: Jessica Zhang --- drivers/gpu/drm/ci/arm64.config | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/ci/arm64.config b/drivers/gpu/drm/ci/arm64.config index 817e18ddfd4f..7273a37cbc4f 100644 --- a/drivers/gpu/drm/ci/arm64.config +++ b/drivers/gpu/drm/ci/arm64.config @@ -75,6 +75,7 @@ CONFIG_INTERCONNECT_QCOM_MSM8916=y CONFIG_INTERCONNECT_QCOM_MSM8996=y CONFIG_INTERCONNECT_QCOM_OSM_L3=y CONFIG_INTERCONNECT_QCOM_SC7180=y +CONFIG_INTERCONNECT_QCOM_SM8250=y CONFIG_INTERCONNECT_QCOM_SM8350=y CONFIG_CRYPTO_DEV_QCOM_RNG=y CONFIG_SC_DISPCC_7180=y -- 2.42.0
[PATCH v1] drm/tiny: correctly print `struct resource *` on error
The `res` variable is already a `struct resource *`, don't take the address of it. Fixes incorrect output: simple-framebuffer 9e20dc000.framebuffer: [drm] *ERROR* could not acquire memory range [??? 0x4be88a387d00-0xfefffde0a240 flags 0x0]: -16 To be correct: simple-framebuffer 9e20dc000.framebuffer: [drm] *ERROR* could not acquire memory range [mem 0x9e20dc000-0x9e307bfff flags 0x200]: -16 Signed-off-by: Joey Gouly Cc: Thomas Zimmermann Cc: Javier Martinez Canillas --- drivers/gpu/drm/tiny/simpledrm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c index ff86ba1ae1b8..8ea120eb8674 100644 --- a/drivers/gpu/drm/tiny/simpledrm.c +++ b/drivers/gpu/drm/tiny/simpledrm.c @@ -745,7 +745,7 @@ static struct simpledrm_device *simpledrm_device_create(struct drm_driver *drv, ret = devm_aperture_acquire_from_firmware(dev, res->start, resource_size(res)); if (ret) { - drm_err(dev, "could not acquire memory range %pr: %d\n", , ret); + drm_err(dev, "could not acquire memory range %pr: %d\n", res, ret); return ERR_PTR(ret); } -- 2.25.1
Re: [PATCH RESEND v2 1/2] drm/print: Add drm_dbg_ratelimited
On 10/10/23 08:15, Andi Shyti wrote: From: Nirmoy Das Add a function for ratelimitted debug print. Signed-off-by: Nirmoy Das Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann Cc: David Airlie Cc: Daniel Vetter Reviewed-by: Matthew Auld Reviewed-by: Andrzej Hajda Reviewed-by: Andi Shyti Reviewed-by: Sam Ravnborg Signed-off-by: Andi Shyti --- include/drm/drm_print.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h index a93a387f8a1a..ad77ac4b6808 100644 --- a/include/drm/drm_print.h +++ b/include/drm/drm_print.h @@ -602,6 +602,9 @@ void __drm_err(const char *format, ...); drm_dev_printk(drm_ ? drm_->dev : NULL, KERN_DEBUG, fmt, ## __VA_ARGS__);\ }) +#define drm_dbg_ratelimited(drm, fmt, ...) \ + __DRM_DEFINE_DBG_RATELIMITED(DRIVER, drm, fmt, ## __VA_ARGS__) + I guess since this was last sent drm_dbg_driver() was introduced, with drm_dbg() only being grandfathered in since it's already widely used, so it would probably be better to call this drm_dbg_driver_ratelimited() instead. #define drm_dbg_kms_ratelimited(drm, fmt, ...) \ __DRM_DEFINE_DBG_RATELIMITED(KMS, drm, fmt, ## __VA_ARGS__) -- Hamza
Re: [PATCH RFC] dt-bindings: display: document display panel occlusions
On 10/10/2023 21:01, Piotr Masłowski wrote: > Hi Caleb, > > Thanks for posting this. I've been meaning to chime in on the discussion > about notches and co. for months now, so this makes a perfect opportunity > to finally do so. > > On Mon Oct 9, 2023 at 7:32 PM CEST, Caleb Connolly wrote: > >> Some folks have previously suggested that this information belongs in >> userspace and not in devicetree. I would like to be clear that >> devicetree is for describing hardware, and parts of a display which can >> never actually be seen are very much properties of the underlying >> hardware. > > Yes, thank you! Seeing the kernel log (or Tuxes) partially hidden behind > the notch (or the top-left rounded corner) is just so annoying, so DT is > definitely the way to go here. Exactly! Glad that others care about the _real_ issue here ;P [...] > > > So why am I writing all of this? Well, the problem I see is that any > shape-based approach will likely suffer from both accuracy and > complexity issues. Describing curves is hard and processing them is > not something that should be included in e.g. whatever handles VTs. My proposal here doesn't require processing curves or doing any complicated calculations. If you know that the display has a 30px radius on all corners, you can adjust the VT to not use the top 30px of the screen and it will start exactly where the radius stops. If you know that there is a (potentially very curvy) notch at the top of the screen, you can just iterate over the arcs, add their radius to their Y coordinate and take the maximum. This will always give you at least the height of the notch (you'd probably want to check that their angle is vaguely downward, but again this is trivial fast integer math). [...] > > However, there's a different approach that is both extremely simple and > yet trivially correct – pixel masks! > > Basically, instead of trying to describe what shape a cutout, notch or > other feature has, we just say which pixels belong to it. In short, this: > > - can be easily processed even by 'dumb' programs – for example, you can > derive minimal margins to 'letterbox' the screen As above (and as mentioned in the patch) this is also trivial to derive from the curves. > - gathering the data is very straightforward – just light the relevant > pixels one-by-one and check if you see them > - pixel-perfect accuracy is the default I think it would be fairly straightforward to do this for curve data too. You just bump the radius up/down until it looks right, or "good enough" > > Of course this is not a perfect solution. Here are the drawback that I > can see: > > - low resolution screens mean low resolution data > - 'smart' programs may or may not need a bit more logic than otherwise > - sub-pixel accuracy is impossible or requires extending this scheme > - non-binary (fractional) weights > - partially-occluded pixels on a separate mask (so each feature would > have two adjacent masks – for its interior and for the border) > > > As a futher improvement, besides looking at pixels we could think about > subpixels instead. Still, this can easily be added later and likely even > in a backwards-compatible manner. > > An orthogonal issue is labeling all of those regions. I think we should > start with fully obscured areas and maybe less readable ones like the > waterfall edges. Still, different features should live on different > masks – even if we don't attach meaningfull labels (like 'notch' or > 'camera cutout') to them right away. > > > What do you all think of that? I didn't see this approach considered in > any of the earlier discussions, yet it seems so elegant to me. Am I > missing something? I think the unfortunate truth is that approximating notches and rounded corners exclusively with regular arcs at the cost of pixel accuracy is just such a no-brainer. Pixel masks would be pixel accurate, but there is no benefit compared to a slightly underfit curve. Any program which wanted to make use of the curve information would have to run a whole curve fitting algorithm, whereas there simply aren't any programs which need to know about display occlusions to a pixel-accurate level. For padding a status bar you do a single trig equation, for avoiding the notch in fullscreen you would query the DRM subsystem which presumably would export the dimensions of a letterboxed "usable size". To be clear though, I wouldn't mind being proven wrong on this, but I'm yet to find some information which doesn't line up with this conclusion. > > -- > Cheers, > Piotr Masłowski -- // Caleb (they/them)
Re: [PATCH v2] drm/panel: Enable DSC and CMD mode for Visionox VTDR6130 panel
On 10/9/2023 3:32 AM, neil.armstr...@linaro.org wrote: Hi Paloma, On 28/07/2023 03:26, Paloma Arellano wrote: Enable display compression (DSC v1.2) and CMD mode for 1080x2400 Visionox VTDR6130 AMOLED DSI panel. In addition, this patch will set the default to command mode with DSC enabled. Note: This patch has only been validated DSC over command mode as DSC over video mode has never been validated for the MSM driver before. I was able to test this on the QRD8550 on top of v6.6-rc5, display works fine, but when runnning: # modetest -r -v setting mode 1080x2400-144.00Hz on connectors 32, crtc 95 failed to set gamma: Function not implemented freq: 74.22Hz freq: 73.09Hz freq: 72.48Hz We get a correct 144Hz vsync test in video mode. Do you know why this happens ? Hi Neil, Thanks for reporting this. FWIW, I saw a slight drop in FPS (from 120 to 90Hz) when enabling DSC for the r66451 command mode panel though the drop reported here seems more drastic. I'll try recreating this on SM8550 MTP and investigate it. Thanks, Jessica Zhang Neil Depends on: "Add prepare_prev_first flag to Visionox VTDR6130" [1] Changes since v1: - Changed from email address [1] https://patchwork.freedesktop.org/series/121337/ Suggested-by: Jessica Zhang Signed-off-by: Paloma Arellano --- .../gpu/drm/panel/panel-visionox-vtdr6130.c | 77 ++- 1 file changed, 73 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c b/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c index e1363e128e7e..5658d39a3a6b 100644 --- a/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c +++ b/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -20,7 +21,8 @@ struct visionox_vtdr6130 { struct mipi_dsi_device *dsi; struct gpio_desc *reset_gpio; struct regulator_bulk_data supplies[3]; - bool prepared; + bool prepared, enabled; + bool video_mode; }; static inline struct visionox_vtdr6130 *to_visionox_vtdr6130(struct drm_panel *panel) @@ -50,12 +52,18 @@ static int visionox_vtdr6130_on(struct visionox_vtdr6130 *ctx) if (ret) return ret; + mipi_dsi_dcs_write_seq(dsi, 0x03, 0x01); mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x20); mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, 0x00, 0x00); mipi_dsi_dcs_write_seq(dsi, 0x59, 0x09); mipi_dsi_dcs_write_seq(dsi, 0x6c, 0x01); mipi_dsi_dcs_write_seq(dsi, 0x6d, 0x00); - mipi_dsi_dcs_write_seq(dsi, 0x6f, 0x01); + + if (ctx->video_mode) + mipi_dsi_dcs_write_seq(dsi, 0x6f, 0x01); + else + mipi_dsi_dcs_write_seq(dsi, 0x6f, 0x02); + mipi_dsi_dcs_write_seq(dsi, 0x70, 0x12, 0x00, 0x00, 0xab, 0x30, 0x80, 0x09, 0x60, 0x04, 0x38, 0x00, 0x28, 0x02, 0x1c, 0x02, 0x1c, 0x02, 0x00, @@ -214,6 +222,42 @@ static const struct drm_display_mode visionox_vtdr6130_mode = { .height_mm = 157, }; +static int visionox_vtdr6130_enable(struct drm_panel *panel) +{ + struct visionox_vtdr6130 *ctx = to_visionox_vtdr6130(panel); + struct mipi_dsi_device *dsi = ctx->dsi; + struct drm_dsc_picture_parameter_set pps; + int ret; + + if (ctx->enabled) + return 0; + + if (!dsi->dsc) { + dev_err(>dev, "DSC not attached to DSI\n"); + return -ENODEV; + } + + drm_dsc_pps_payload_pack(, dsi->dsc); + ret = mipi_dsi_picture_parameter_set(dsi, ); + if (ret) { + dev_err(>dev, "Failed to set PPS\n"); + return ret; + } + + ctx->enabled = true; + + return 0; +} + +static int visionox_vtdr6130_disable(struct drm_panel *panel) +{ + struct visionox_vtdr6130 *ctx = to_visionox_vtdr6130(panel); + + ctx->enabled = false; + + return 0; +} + static int visionox_vtdr6130_get_modes(struct drm_panel *panel, struct drm_connector *connector) { @@ -237,6 +281,8 @@ static const struct drm_panel_funcs visionox_vtdr6130_panel_funcs = { .prepare = visionox_vtdr6130_prepare, .unprepare = visionox_vtdr6130_unprepare, .get_modes = visionox_vtdr6130_get_modes, + .enable = visionox_vtdr6130_enable, + .disable = visionox_vtdr6130_disable, }; static int visionox_vtdr6130_bl_update_status(struct backlight_device *bl) @@ -269,11 +315,31 @@ static int visionox_vtdr6130_probe(struct mipi_dsi_device *dsi) { struct device *dev = >dev; struct visionox_vtdr6130 *ctx; + struct drm_dsc_config *dsc; int ret; ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; + + ctx->video_mode = of_property_read_bool(dev->of_node, "enforce-video-mode"); + + dsc = devm_kzalloc(dev, sizeof(*dsc), GFP_KERNEL); + if (!dsc) + return -ENOMEM; + + /* Set DSC params */ + dsc->dsc_version_major = 0x1; + dsc->dsc_version_minor =
Re: [PATCH RESEND v2 0/2] Add drm_dbg_ratelimited()
Hi John, On Tue, Oct 10, 2023 at 11:25:03AM -0700, John Harrison wrote: > On 10/10/2023 05:15, Andi Shyti wrote: > > Hi, > > > > I might have picked up the wrong series and missed some reviews > > and the extra patch from Nirmoy with a real use of the > > drm_dbg_ratelimited() that John was looking for. > > > > Thanks, > > Andi > I just found the original post of this from back in January > (https://patchwork.freedesktop.org/series/112925/). Is there a reason why it > was never merged? As noted, it appears to have a whole bunch of r-b's on it. yes, the patch was widely appreciated by reviewers... but I think somehow it was forgotten... that's why I am resending it :-) Andi
please backmerge drm/drm-next into drm-misc/drm-misc-next
Hello, drm-misc-next is currently stuck at 6.5-rc2. Could you please backmerge drm-next into drm-misc-next to bring it to 6.6-rc2? I was going to apply one of the pending series ([1]), but got conflicts because of the outdated source tree. Thank you. [1] https://patchwork.freedesktop.org/series/120393/#rev5 -- With best wishes Dmitry
Re: [PATCH drm-misc-next 2/3] drm/gpuva_mgr: generalize dma_resv/extobj handling and GEM validation
> I think we're then optimizing for different scenarios. Our compute > driver will use mostly external objects only, and if shared, I don't > forsee them bound to many VMs. What saves us currently here is that in > compute mode we only really traverse the extobj list after a preempt > fence wait, or when a vm is using a new context for the first time. So > vm's extobj list is pretty large. Each bo's vma list will typically be > pretty small. Can I ask why we are optimising for this userspace, this seems incredibly broken. We've has this sort of problem in the past with Intel letting the tail wag the horse, does anyone remember optimising relocations for a userspace that didn't actually need to use relocations? We need to ask why this userspace is doing this, can we get some pointers to it? compute driver should have no reason to use mostly external objects, the OpenCL and level0 APIs should be good enough to figure this out. Dave.
Re: [Intel-gfx] [PATCH 2/2] drm/i915: More use of GT specific print helpers
Hi John, On Mon, Oct 09, 2023 at 12:57:55PM -0700, John Harrison wrote: > On 10/9/2023 12:54, Andi Shyti wrote: > > Hi John, > > > > ... > > > > > --- a/drivers/gpu/drm/i915/i915_driver.c > > > +++ b/drivers/gpu/drm/i915/i915_driver.c > > > @@ -71,6 +71,7 @@ > > > #include "gem/i915_gem_pm.h" > > > #include "gt/intel_gt.h" > > > #include "gt/intel_gt_pm.h" > > > +#include "gt/intel_gt_print.h" > > > #include "gt/intel_rc6.h" > > > #include "pxp/intel_pxp.h" > > > @@ -429,7 +430,7 @@ static int i915_pcode_init(struct drm_i915_private > > > *i915) > > > for_each_gt(gt, i915, id) { > > > ret = intel_pcode_init(gt->uncore); > > > if (ret) { > > > - drm_err(>i915->drm, "gt%d: intel_pcode_init failed > > > %d\n", id, ret); > > > + gt_err(gt, "intel_pcode_init failed %d\n", ret); > > using gt_*() print functions in the upper layers looks a bit > > wrong to me. If we need GT printing, the prints need to be done > > inside the function called, in this case would be > > intel_pcode_init(). > It is less wrong that using gt->i915->drm as a parameter and 'gt%d' in the > format string. That is the whole point of the helper. The code has access to > a gt object so it should use the gt helper to make use of that object rather > than unrolling it and diving in to the gt internals. yes, it's an improvement Reviewed-by: Andi Shyti > As for moving the error message inside the init function itself. That is > maybe a valid change but that potentially counts as a functional change and > should be done by someone who actually knows the code. All I'm doing is > improving the code layering by using the correct helper to hide the internal > details of an object this layer should not know about. maybe one day we need to revisit all the gt dependency in the higher levels and the i915 dependencies in gt. Thanks, Andi
Re: [PATCH RFC] dt-bindings: display: document display panel occlusions
Hi Caleb, Thanks for posting this. I've been meaning to chime in on the discussion about notches and co. for months now, so this makes a perfect opportunity to finally do so. On Mon Oct 9, 2023 at 7:32 PM CEST, Caleb Connolly wrote: > Some folks have previously suggested that this information belongs in > userspace and not in devicetree. I would like to be clear that > devicetree is for describing hardware, and parts of a display which can > never actually be seen are very much properties of the underlying > hardware. Yes, thank you! Seeing the kernel log (or Tuxes) partially hidden behind the notch (or the top-left rounded corner) is just so annoying, so DT is definitely the way to go here. > Some discussion has been underway previously on how best to describe > these features [1][2], including a reference userspace implementation > using SVG paths [3]. Using this previous discussion as a jumping off > point, this RFC allows for describing the following display features: > > * Corner radius (on a per-corner basis) > * Circular or pill-shaped cutouts > * Notches with arbitrary shapes > > It's easy to make a case for only using rectangles to describe these > missing parts of a display, however this severely limits their utility. > Describing display occlusions as accurately as possible allows for a lot of > useful UX features. For example, displaying a ring around a hole-punch > camera when it's in use, or wrapping UI elements around a notch. These > behaviours are only possible to implement when the dimensions are known > with near pixel-perfect accuracy. There are two aspects at play here: simplicity and correctness. Fully sacrificing one for the other would be a grave mistake. But that does not mean those two are inherently opposed. I'd argue that they actually go hand in hand. Keeping the format simple will make gathering and submitting high-quality data easier. Conversly, accurately describing the hardware requires *not including* redundant or non-applicable information. So why am I writing all of this? Well, the problem I see is that any shape-based approach will likely suffer from both accuracy and complexity issues. Describing curves is hard and processing them is not something that should be included in e.g. whatever handles VTs. [TLDR: you can skip ahead] Morover, short of some Turing-complete arbitrary path function, it sacrifices a bit of expressivity and thus correctness as there will always be shapes you cannot describe accurately. This may be irrelevant because in practice you don't need those details. But that highlights a different problem: there will be many distinct ways to describe many similar things. It's also hard to tell if a given curve really has the right shape: * similar shapes exist – How do you tell whether e.g. a rounded corner is circular or not? If a DT gets that wrong and the UI decides to for example draw constant-width padding around such feature it will likely look very off and ugly. * measurement precision is a thing – Unless you measure everything on a scale significantly smaller than individual pixels, sections of your curves may end up on different pixels than in reality. * different people have different standards – And so the quality will vary greatly between devices. * corners will be cut – This is basically the previous point but I liked the pun way too much to just delete it, lol * pixels vs millimeters – Converting between these two will also increase the overall wobbliness and worsen the user experience. But is it feasible to measure everything in pixels accurately? Picking a very small set of basic curve shapes might be a good option if that can cover all the shapes we expect to find in the wild. It does not resolve the possible accuracy problems but it would at least be simple. [TLDR – skip to here]: However, there's a different approach that is both extremely simple and yet trivially correct – pixel masks! Basically, instead of trying to describe what shape a cutout, notch or other feature has, we just say which pixels belong to it. In short, this: - can be easily processed even by 'dumb' programs – for example, you can derive minimal margins to 'letterbox' the screen - gathering the data is very straightforward – just light the relevant pixels one-by-one and check if you see them - pixel-perfect accuracy is the default Of course this is not a perfect solution. Here are the drawback that I can see: - low resolution screens mean low resolution data - 'smart' programs may or may not need a bit more logic than otherwise - sub-pixel accuracy is impossible or requires extending this scheme - non-binary (fractional) weights - partially-occluded pixels on a separate mask (so each feature would have two adjacent masks – for its interior and for the border) As a futher improvement, besides looking at pixels we could think about subpixels instead. Still, this can easily be added later and likely even in a
Re: [PATCH v3 6/6] arm64: dts: qcom: sdm670: add display subsystem
On 10/10/23 01:33, Richard Acayan wrote: The Snapdragon 670 has a display subsystem for controlling and outputting to the display. Add support for it in the device tree. Reviewed-by: Dmitry Baryshkov Signed-off-by: Richard Acayan --- [...] + interconnects = <_noc MASTER_MDP_PORT0 0 _noc SLAVE_EBI_CH0 0>, + <_noc MASTER_MDP_PORT1 0 _noc SLAVE_EBI_CH0 0>; 0 -> QCOM_ICC_TAG_ALWAYS (dt-bindings/interconnect/qcom,icc.h) + interconnect-names = "mdp0-mem", "mdp1-mem"; + + iommus = <_smmu 0x880 0x8>, +<_smmu 0xc80 0x8>; + + status = "disabled"; status after the block below, please and similarly below Konrad
Re: [PATCH RFC] dt-bindings: display: document display panel occlusions
On 10/10/2023 17:52, Rob Herring wrote: > On Mon, Oct 09, 2023 at 06:32:50PM +0100, Caleb Connolly wrote: >> Some display panels found in modern phones and laptops feature >> non-standard display shapes with features like rounded corners, notches >> (sections of the display that are cut-out from the edge), and cutouts >> (such as circular "hole punch" camera cutouts, or wider pill-shaped >> "islands"). >> >> Some discussion has been underway previously on how best to describe >> these features [1][2], including a reference userspace implementation >> using SVG paths [3]. Using this previous discussion as a jumping off >> point, this RFC allows for describing the following display features: >> >> * Corner radius (on a per-corner basis) >> * Circular or pill-shaped cutouts >> * Notches with arbitrary shapes >> >> It's easy to make a case for only using rectangles to describe these >> missing parts of a display, however this severely limits their utility. >> Describing display occlusions as accurately as possible allows for a lot of >> useful UX features. For example, displaying a ring around a hole-punch >> camera when it's in use, or wrapping UI elements around a notch. These >> behaviours are only possible to implement when the dimensions are known >> with near pixel-perfect accuracy. >> >> Cutouts are described as rectangles with a width, height, and corner >> radius. >> A radius of half the width longest edge will definitionally be an ellipse. >> This simple description is suitable for describing hole-punch cameras, >> as well >> as pill-shaped cutouts. I'm not aware of any devices that can't be >> described like this. >> >> Notches are a little more complicated, they usually feature convex and >> concave corners as well as straight lines. Here they are described as a >> sequence of optionally disjoint arcs, where the space between one arc ending >> and another starting is inferred to be a straight line. >> >> Each arc is described with an X and Y pixel coordinate, a radius, and a >> start and end point in degrees. These arcs can precisely describe the >> shape of a notch, and easily allow for a basic bounding box to be >> derived using the min/max coordinates specified in the path. >> >> Some displays feature partially occluded edges ("waterfall edges") where >> the screen bends, it may be useful for user interfaces to avoid placing >> certain UI elements like buttons too close to these edges. These edges >> are described by a distance from the edge where it begins to be >> occluded, and the number of degrees that the display curves (this >> directly affects how usable this edge of the screen is). >> >> [1]: >> https://lore.kernel.org/dri-devel/f8747f99-0695-5be0-841f-4f72ba5d5...@connolly.tech/ >> [2]: https://gitlab.freedesktop.org/wayland/wayland-protocols/-/issues/87 >> [3]: https://gitlab.gnome.org/World/Phosh/gmobile >> >> Signed-off-by: Caleb Connolly >> --- >> Some folks have previously suggested that this information belongs in >> userspace and not in devicetree. I would like to be clear that >> devicetree is for describing hardware, and parts of a display which can >> never actually be seen are very much properties of the underlying >> hardware. > > Makes sense to me. > > There's similar work happening for touchscreens/pads here[1]. Seems like > there might be some overlap in terms of what the binding needs. hmm, maybe for the cutouts it would make sense to have a common overlay binding, we would just need to add a radius property. > >> --- >> base-commit: 268c4b354d66908697299063c44c0b553b01d935 >> >> // Caleb (they/them) >> --- >> .../bindings/display/panel/panel-common.yaml | 7 + >> .../bindings/display/panel/panel-occlusions.yaml | 182 >> + >> 2 files changed, 189 insertions(+) >> >> diff --git >> a/Documentation/devicetree/bindings/display/panel/panel-common.yaml >> b/Documentation/devicetree/bindings/display/panel/panel-common.yaml >> index 0a57a31f4f3d..6ea52a031872 100644 >> --- a/Documentation/devicetree/bindings/display/panel/panel-common.yaml >> +++ b/Documentation/devicetree/bindings/display/panel/panel-common.yaml >> @@ -150,6 +150,13 @@ properties: >>controller, this property contains a phandle that references the >>controller. >> >> + occlusions: >> +$ref: panel-occlusions.yaml# >> +description: >> + Some panels have non-standard shapes due to features like rounded >> corners, >> + notches, cutouts, and "waterfall" edges. The panel-occlusions bindings >> + can be used to describe these features. >> + >> dependencies: >>width-mm: [ height-mm ] >>height-mm: [ width-mm ] >> diff --git >> a/Documentation/devicetree/bindings/display/panel/panel-occlusions.yaml >> b/Documentation/devicetree/bindings/display/panel/panel-occlusions.yaml >> new file mode 100644 >> index ..0932026bbd8c >> --- /dev/null >> +++
Re: [PATCH v7 0/7] incorporate pm runtime framework and eDP clean up
Quoting Kuogee Hsieh (2023-10-06 15:55:03) > The purpose of this patch series is to incorporate pm runtime framework > into MSM eDP/DP driver so that eDP panel can be detected by DRM eDP panel > driver during system probe time. During incorporating procedure, original > customized pm realted fucntions, such as dp_pm_prepare(), dp_pm_suspend(), > dp_pm_resume() and dp_pm_prepare(), are removed and replaced with functions > provided by pm runtiem framework such as pm_runtime_force_suspend() and > pm_runtime_force_resume(). In addition, both eDP aux-bus and irq handler > are bound at system probe time too. > > Kuogee Hsieh (7): > drm/msm/dp: tie dp_display_irq_handler() with dp driver > drm/msm/dp: rename is_connected with link_ready > drm/msm/dp: use drm_bridge_hpd_notify() to report HPD status changes > drm/msm/dp: move parser->parse() and dp_power_client_init() to probe > drm/msm/dp: incorporate pm_runtime framework into DP driver > drm/msm/dp: delete EV_HPD_INIT_SETUP > drm/msm/dp: move of_dp_aux_populate_bus() to eDP probe() > > drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 4 - > drivers/gpu/drm/msm/dp/dp_aux.c | 39 +++- > drivers/gpu/drm/msm/dp/dp_display.c | 333 > Tested-by: Stephen Boyd # Trogdor.Lazor I ran some suspend cycles too with the lid open and closed.
Re: [v1 2/2] drm/panel: ili9882t: Avoid blurred screen from fast sleep
Hi, On Tue, Oct 10, 2023 at 4:36 AM cong yang wrote: > > Hi, > > On Tue, Oct 10, 2023 at 4:44 AM Doug Anderson wrote: > > > > Hi, > > > > On Fri, Oct 6, 2023 at 11:07 PM Cong Yang > > wrote: > > > > > > At present, we have found that there may be a problem of blurred > > > screen during fast sleep/resume. The direct cause of the blurred > > > screen is that the IC does not receive 0x28/0x10. Because of the > > > particularity of the IC, before the panel enters sleep hid must > > > stop scanning, i2c_hid_core_suspend before ili9882t_disable. > > > This doesn't look very spec-compliant. > > > > Presumably you could be more spec compliant if we used > > "panel_follower" in this case? Would that be a better solution? > > In the "panel_follower" solution, the phenomenon is the same. > The current order is > ili9882t_disable=>i2c_hid_core_suspend=>elan_i2c_hid_power_down=>ili9882t_unprepare, > ili9882t need touchpanel stop scanning,i2c_hid_core_suspend before > ili9882t_disable. Ugh, that's unfortunate. Though is there a reason why you couldn't just move the `ili9882t_enter_sleep_mode()` to `ili9882t_unprepare()`? That seems like it should be OK and even perhaps makes it more symmetric with thue enable? > > > @@ -507,7 +526,7 @@ static int ili9882t_prepare(struct drm_panel *panel) > > > gpiod_set_value(ili->enable_gpio, 1); > > > usleep_range(1000, 2000); > > > gpiod_set_value(ili->enable_gpio, 0); > > > - usleep_range(1000, 2000); > > > + usleep_range(4, 5); > > > > nit: use 4, 41000 instead of 4, 5. Linux almost always > > uses the longer delay, so that'll save ~9 ms. The only reason for the > > range is to optimize kernel wakeups which is really not a concern > > here. > > We need 50ms delay to meet the requirement. I'll respond to your v2, but if you need 50 ms then your current delay is wrong. -Doug
Re: [v2 3/3] arm64: defconfig: Enable ILITEK_ILI9882T panel
Hi, On Tue, Oct 10, 2023 at 5:14 AM Cong Yang wrote: > > Enable ILITEK_ILI9882T panel. Could you add a little background? Maybe something like: DRM_PANEL_ILITEK_ILI9882T is being split out from DRM_PANEL_BOE_TV101WUM_NL6. Since the arm64 defconfig had the BOE panel driver enabled, let's also enable the Ilitek driver. > Signed-off-by: Cong Yang > --- > arch/arm64/configs/defconfig | 1 + > 1 file changed, 1 insertion(+) Reviewed-by: Douglas Anderson
Re: [v2 2/3] drm/panel: ili9882t: Avoid blurred screen from fast sleep
Hi, On Tue, Oct 10, 2023 at 5:14 AM Cong Yang wrote: > > At present, we have found that there may be a problem of blurred > screen during fast sleep/resume. The direct cause of the blurred > screen is that the IC does not receive 0x28/0x10. Because of the > particularity of the IC, before the panel enters sleep hid must > stop scanning, i2c_hid_core_suspend before ili9882t_disable. > This doesn't look very spec-compliant. So in order to solve this > problem, the IC can handle it through the exception mechanism when > it cannot receive 0X28/0X10 command. Handling exceptions requires a reset very nitty, but can you make the "X" lowercase? ...so 0x28 not 0X28. > 50ms delay. Refer to vendor detailed analysis [1]. > > Ilitek vendor also suggested switching the page before entering sleep to > avoid panel IC not receiving 0x28/0x10 command. > > Note: 0x28 is display off, 0x10 is sleep in. > > [1]: > https://github.com/ILITEK-LoganLin/Document/tree/main/ILITEK_Power_Sequence > > Signed-off-by: Cong Yang > --- > drivers/gpu/drm/panel/panel-ilitek-ili9882t.c | 22 ++- > 1 file changed, 21 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c > b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c > index e095ad91c4bc..20ae370ebe2f 100644 > --- a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c > +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c > @@ -465,6 +465,24 @@ static int ili9882t_init_dcs_cmd(struct ili9882t *ili) > return 0; > } > > +static int ili9882t_switch_page(struct mipi_dsi_device *dsi, u8 page) > +{ > + int ret; > + const struct panel_init_cmd cmd = _INIT_SWITCH_PAGE_CMD(page); > + > + ret = mipi_dsi_dcs_write(dsi, cmd.data[0], > +cmd.len <= 1 ? NULL : > +[1], > +cmd.len - 1); > + if (ret) { > + dev_err(>dev, > + "error switching panel controller page (%d)\n", ret); > + return ret; > + } > + > + return 0; > +} > + > static int ili9882t_enter_sleep_mode(struct ili9882t *ili) > { > struct mipi_dsi_device *dsi = ili->dsi; > @@ -486,8 +504,10 @@ static int ili9882t_enter_sleep_mode(struct ili9882t > *ili) > static int ili9882t_disable(struct drm_panel *panel) > { > struct ili9882t *ili = to_ili9882t(panel); > + struct mipi_dsi_device *dsi = ili->dsi; > int ret; > > + ili9882t_switch_page(dsi, 0x00); > ret = ili9882t_enter_sleep_mode(ili); > if (ret < 0) { > dev_err(panel->dev, "failed to set panel off: %d\n", ret); > @@ -548,7 +568,7 @@ static int ili9882t_prepare(struct drm_panel *panel) > gpiod_set_value(ili->enable_gpio, 1); > usleep_range(1000, 2000); > gpiod_set_value(ili->enable_gpio, 0); > - usleep_range(1000, 2000); > + usleep_range(4, 5); In response to v1 you said that you actually needed 50 ms here. Oh, I guess that's also in the patch description. The above allows the kernel to delay 40 ms. We need to change it to something that will force the kernel to do 50 ms. That could be: "usleep_range(5, 51000)", but actually when we're this order of magnitude it should be just "msleep(50)".
Re: [v2 1/3] drm/panel: ili9882t: Break out as separate driver
Hi, On Tue, Oct 10, 2023 at 5:14 AM Cong Yang wrote: > > diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c > b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c > new file mode 100644 > index ..e095ad91c4bc > --- /dev/null > +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c > @@ -0,0 +1,762 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Panels based on the Ilitek ILI9882T display controller. > + */ > +#include > +#include > +#include > +#include > +#include nit: remove include of linux/of_device.h since you don't use any of the functions declared there. > +#include > + > +#include > +#include > +#include > +#include > + > +#include > + > +/* > + * Use this descriptor struct to describe different panels using the > + * Ilitek ILI9882T display controller. > + */ > +struct panel_desc { > + const struct drm_display_mode *modes; > + unsigned int bpc; > + > + /** > +* @width_mm: width of the panel's active display area > +* @height_mm: height of the panel's active display area > +*/ > + struct { > + unsigned int width_mm; > + unsigned int height_mm; > + } size; > + > + unsigned long mode_flags; > + enum mipi_dsi_pixel_format format; > + const struct panel_init_cmd *init_cmds; > + unsigned int init_cmd_length; Remove "init_cmd_length" since it's now unused. > +static void ili9882t_remove(struct mipi_dsi_device *dsi) > +{ > + struct ili9882t *ili = mipi_dsi_get_drvdata(dsi); > + int ret; > + > + > + ret = mipi_dsi_detach(dsi); nit: remove extra blank line above. Other than nits, this looks good to me now. Reviewed-by: Douglas Anderson
Re: [PATCH v1 0/2] [PATCH] hwmon: (pmbus/max31785) Add minimum delay between bus accesses
Hi Guenter, > > > Reference to Andrew's previous proposal: > > > https://lore.kernel.org/all/20200914122811.3295678-1-and...@aj.id.au/ > > > > I do totally agree with Guenter's comment[1], though. This just affects > > a few drivers and this patch is way too intrusive for the I2C core. The > > later suggested prepare_device() callback[2] sounds better to me. I > > still haven't fully understood why this all cannot be handled in the > > driver's probe. Could someone give me a small summary about that? > > > > Lots of PMBus devices have the same problem, we have always handled > it in PMBus drivers by implementing local wait code, and your references > point that out. I am confused now. Reading your reply: "I am not sure if an implementation in the i2c core is desirable. It looks quite invasive to me, and it won't solve the problem for all devices since it isn't always a simple "wait microseconds between accesses". For example, some devices may require a wait after a write but not after a read, or a wait only after certain commands (such as commands writing to an EEPROM)." I get the impression you don't prefer to have a generic mechanism in the I2C core. This I share. Your response now sounds like you do support that idea now? > What other summary are you looking for ? What the actual problem is with these devices. The cover letter only mentions "issues with small command turn-around times". More details would be nice. Is it between transfers? Or even between messages within one transfer? Has it been tried to lower the bus frequency? Stuff like this. > On a side note, if anyone plans to implement the prepare_device() callback, > please make sure that it covers all requirements. It would be unfortunate > if such a callback was implemented if that would still require per-driver > code (besides the callback). Is there a list of that somewhere? Or does it mean going through all the drivers and see what they currently do? Regards, Wolfram signature.asc Description: PGP signature
Re: [PATCH RESEND v2 0/2] Add drm_dbg_ratelimited()
On 10/10/2023 05:15, Andi Shyti wrote: Hi, I might have picked up the wrong series and missed some reviews and the extra patch from Nirmoy with a real use of the drm_dbg_ratelimited() that John was looking for. Thanks, Andi I just found the original post of this from back in January (https://patchwork.freedesktop.org/series/112925/). Is there a reason why it was never merged? As noted, it appears to have a whole bunch of r-b's on it. John. v2: pick the right patch with the following changes: - add more r-b's - add a patch 2 where the drm_dbg_ratelimited is actually used. Nirmoy Das (2): drm/print: Add drm_dbg_ratelimited drm/i915: Ratelimit debug log in vm_fault_ttm drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 5 +++-- include/drm/drm_print.h | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-)
Re: [PATCH] drm/amd/pm: Fix a memory leak on an error path
Applied. Thanks! Alex On Tue, Oct 10, 2023 at 2:32 AM Wang, Yang(Kevin) wrote: > > [AMD Official Use Only - General] > > Reviewed-by: Yang Wang > > Best Regards, > Kevin > > -Original Message- > From: Kunwu.Chan > Sent: Tuesday, October 10, 2023 2:11 PM > To: Wang, Yang(Kevin) > Cc: Deucher, Alexander ; Kamal, Asad > ; Koenig, Christian ; Zhang, > Hawking ; Ma, Le ; Lazar, Lijo > ; Pan, Xinhui ; airl...@gmail.com; > amd-...@lists.freedesktop.org; chen...@kylinos.cn; dan.carpen...@linaro.org; > dan...@ffwll.ch; dri-devel@lists.freedesktop.org; evan.q...@amd.com; > kunwu.c...@hotmail.com; linux-ker...@vger.kernel.org > Subject: [PATCH] drm/amd/pm: Fix a memory leak on an error path > > Add missing free on an error path. > > Fixes: 511a95552ec8 ("drm/amd/pm: Add SMU 13.0.6 support") > Signed-off-by: Kunwu.Chan > --- > drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c > b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c > index ce971a93d28b..c26e12ff532c 100644 > --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c > +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c > @@ -1981,8 +1981,10 @@ static ssize_t smu_v13_0_6_get_gpu_metrics(struct > smu_context *smu, void **table > > metrics = kzalloc(sizeof(MetricsTable_t), GFP_KERNEL); > ret = smu_v13_0_6_get_metrics_table(smu, metrics, true); > - if (ret) > + if (ret) { > + kfree(metrics); > return ret; > + } > > smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 3); > > -- > 2.25.1 >
Re: [PATCH 2/2] backlight: Add Kinetic KTD2801 driver
Hi Duje, kernel test robot noticed the following build warnings: [auto build test WARNING on 8a749fd1a8720d4619c91c8b6e7528c0a355c0aa] url: https://github.com/intel-lab-lkp/linux/commits/Duje-Mihanovi/dt-bindings-backlight-add-Kinetic-KTD2801-binding/20231006-025106 base: 8a749fd1a8720d4619c91c8b6e7528c0a355c0aa patch link: https://lore.kernel.org/r/20231005-ktd2801-v1-2-43cd85b0629a%40skole.hr patch subject: [PATCH 2/2] backlight: Add Kinetic KTD2801 driver config: i386-allyesconfig (https://download.01.org/0day-ci/archive/20231011/202310110122.syu9ojqi-...@intel.com/config) compiler: gcc-12 (Debian 12.2.0-14) 12.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231011/202310110122.syu9ojqi-...@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/202310110122.syu9ojqi-...@intel.com/ All warnings (new ones prefixed by >>): >> drivers/video/backlight/ktd2801-backlight.c:15: warning: "DS" redefined 15 | #define DS 5 | In file included from arch/x86/include/uapi/asm/ptrace.h:6, from arch/x86/include/asm/ptrace.h:7, from arch/x86/include/asm/math_emu.h:5, from arch/x86/include/asm/processor.h:13, from arch/x86/include/asm/cpufeature.h:5, from arch/x86/include/asm/thread_info.h:53, from include/linux/thread_info.h:60, from arch/x86/include/asm/preempt.h:9, from include/linux/preempt.h:79, from include/linux/rcupdate.h:27, from include/linux/rculist.h:11, from include/linux/pid.h:5, from include/linux/sched.h:14, from include/linux/ratelimit.h:6, from include/linux/dev_printk.h:16, from include/linux/device.h:15, from include/linux/backlight.h:12, from drivers/video/backlight/ktd2801-backlight.c:2: arch/x86/include/uapi/asm/ptrace-abi.h:14: note: this is the location of the previous definition 14 | #define DS 7 | vim +/DS +15 drivers/video/backlight/ktd2801-backlight.c 8 9 #define EW_DELAY150 10 #define EW_DET 270 11 #define LOW_BIT_HIGH5 12 #define LOW_BIT_LOW (4 * HIGH_BIT_LOW) 13 #define HIGH_BIT_LOW5 14 #define HIGH_BIT_HIGH (4 * HIGH_BIT_LOW) > 15 #define DS 5 16 #define EOD_L 10 17 #define EOD_H 350 18 #define PWR_DOWN_DELAY 2600 19 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
[PATCH] drm/atomic: clarify the rules around drm_atomic_state->allow_modeset
msm is automagically upgrading normal commits to full modesets, and that's a big no-no: - for one this results in full on->off->on transitions on all these crtc, at least if you're using the usual helpers. Which seems to be the case, and is breaking uapi - further even if the ctm change itself would not result in flicker, this can hide modesets for other reasons. Which again breaks the uapi Signed-off-by: Daniel Vetter Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann Cc: David Airlie Cc: Daniel Vetter Cc: Pekka Paalanen Cc: Rob Clark Cc: Simon Ser Signed-off-by: Daniel Vetter --- include/drm/drm_atomic.h | 18 -- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index cf8e1220a4ac..09bef1b6c170 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -372,8 +372,22 @@ struct drm_atomic_state { * * Allow full modeset. This is used by the ATOMIC IOCTL handler to * implement the DRM_MODE_ATOMIC_ALLOW_MODESET flag. Drivers should -* never consult this flag, instead looking at the output of -* drm_atomic_crtc_needs_modeset(). +* not consult this flag, instead looking at the output of +* drm_atomic_crtc_needs_modeset(). The detailed rules are: +* +* - Drivers must not consult @allow_modeset in the atomic commit path, +* and instead use drm_atomic_crtc_needs_modeset(). +* +* - Drivers may consult @allow_modeset in the atomic check path, if +* they have the choice between an optimal hardware configuration +* which requires a modeset, and a less optimal configuration which +* can be committed without a modeset. An example would be suboptimal +* scanout FIFO allocation resulting in increased idle power +* consumption. This allows userspace to avoid flickering and delays +* for the normal composition loop at reasonable cost. +* +* - Drivers must never change this flag, it is only under the control +* of userspace. */ bool allow_modeset : 1; /** -- 2.40.1
Re: [PATCH 8/8] dt-bindings: display: Add SSD132x OLED controllers
On Mon, Oct 09, 2023 at 08:34:22PM +0200, Javier Martinez Canillas wrote: > Add a Device Tree binding schema for the OLED panels based on the Solomon > SSD132x family of controllers. Looks like the same binding as solomon,ssd1307fb.yaml. Why a different binding? Why does that binding need a slew of custom properties and here you don't? > > Signed-off-by: Javier Martinez Canillas > --- > > .../bindings/display/solomon,ssd132x.yaml | 116 ++ > 1 file changed, 116 insertions(+) > create mode 100644 > Documentation/devicetree/bindings/display/solomon,ssd132x.yaml > > diff --git a/Documentation/devicetree/bindings/display/solomon,ssd132x.yaml > b/Documentation/devicetree/bindings/display/solomon,ssd132x.yaml > new file mode 100644 > index ..b64904703a3a > --- /dev/null > +++ b/Documentation/devicetree/bindings/display/solomon,ssd132x.yaml > @@ -0,0 +1,116 @@ > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/display/solomon,ssd132x.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Solomon SSD132x OLED Controllers > + > +maintainers: > + - Javier Martinez Canillas > + > +properties: > + compatible: > +oneOf: > + - enum: > + - solomon,ssd1322 > + - solomon,ssd1325 > + - solomon,ssd1327 > + > + reg: > +maxItems: 1 > + > + reset-gpios: > +maxItems: 1 > + > + # Only required for SPI > + dc-gpios: > +description: > + GPIO connected to the controller's D/C# (Data/Command) pin, > + that is needed for 4-wire SPI to tell the controller if the > + data sent is for a command register or the display data RAM > +maxItems: 1 > + > + solomon,height: > +$ref: /schemas/types.yaml#/definitions/uint32 > +description: > + Height in pixel of the screen driven by the controller. > + The default value is controller-dependent. > + > + solomon,width: > +$ref: /schemas/types.yaml#/definitions/uint32 > +description: > + Width in pixel of the screen driven by the controller. > + The default value is controller-dependent. Don't define the same properties twice. Either share the binding or split out the common properties into their own schema file. Rob
Re: [PATCH 1/3] drm/panel: ltk050h3146w: add mipi_dsi_device.mode_flags to of_match_data
Am Dienstag, 10. Oktober 2023, 18:54:11 CEST schrieb Heiko Stuebner: > On Mon, 31 Jan 2022 17:47:21 +0100, quentin.sch...@theobroma-systems.com > wrote: > > From: Quentin Schulz > > > > To prepare for a new display to be supported by this driver which has a > > slightly different set of DSI mode related flags, let's move the > > currently hardcoded mode flags to the .data field of of_device_id > > structure. > > > > [...] > > Applied, thanks! > > [1/3] drm/panel: ltk050h3146w: add mipi_dsi_device.mode_flags to of_match_data > commit: 99403d747ae8c7b3bfb5cd14c8908930ec6801c6 > [2/3] drm/panel: ltk050h3146w: add support for Leadtek LTK050H3148W-CTA6 > variant > commit: e5f9d543419c78ac58f3b3557bc5a76b20ff600b > [3/3] dt-bindings: ltk050h3146w: add compatible for LTK050H3148W-CTA6 variant > commit: 29d8e38c36cb662331a833699c359ec1af1edbec forgot to add, I included the move to the generic mipi_dsi_dcs_write_seq() for the new sequence.
Re: [PATCH 1/3] drm/panel: ltk050h3146w: add mipi_dsi_device.mode_flags to of_match_data
On Mon, 31 Jan 2022 17:47:21 +0100, quentin.sch...@theobroma-systems.com wrote: > From: Quentin Schulz > > To prepare for a new display to be supported by this driver which has a > slightly different set of DSI mode related flags, let's move the > currently hardcoded mode flags to the .data field of of_device_id > structure. > > [...] Applied, thanks! [1/3] drm/panel: ltk050h3146w: add mipi_dsi_device.mode_flags to of_match_data commit: 99403d747ae8c7b3bfb5cd14c8908930ec6801c6 [2/3] drm/panel: ltk050h3146w: add support for Leadtek LTK050H3148W-CTA6 variant commit: e5f9d543419c78ac58f3b3557bc5a76b20ff600b [3/3] dt-bindings: ltk050h3146w: add compatible for LTK050H3148W-CTA6 variant commit: 29d8e38c36cb662331a833699c359ec1af1edbec Best regards, -- Heiko Stuebner
Re: [PATCH RFC] dt-bindings: display: document display panel occlusions
On Mon, Oct 09, 2023 at 06:32:50PM +0100, Caleb Connolly wrote: > Some display panels found in modern phones and laptops feature > non-standard display shapes with features like rounded corners, notches > (sections of the display that are cut-out from the edge), and cutouts > (such as circular "hole punch" camera cutouts, or wider pill-shaped > "islands"). > > Some discussion has been underway previously on how best to describe > these features [1][2], including a reference userspace implementation > using SVG paths [3]. Using this previous discussion as a jumping off > point, this RFC allows for describing the following display features: > > * Corner radius (on a per-corner basis) > * Circular or pill-shaped cutouts > * Notches with arbitrary shapes > > It's easy to make a case for only using rectangles to describe these > missing parts of a display, however this severely limits their utility. > Describing display occlusions as accurately as possible allows for a lot of > useful UX features. For example, displaying a ring around a hole-punch > camera when it's in use, or wrapping UI elements around a notch. These > behaviours are only possible to implement when the dimensions are known > with near pixel-perfect accuracy. > > Cutouts are described as rectangles with a width, height, and corner > radius. > A radius of half the width longest edge will definitionally be an ellipse. > This simple description is suitable for describing hole-punch cameras, > as well > as pill-shaped cutouts. I'm not aware of any devices that can't be > described like this. > > Notches are a little more complicated, they usually feature convex and > concave corners as well as straight lines. Here they are described as a > sequence of optionally disjoint arcs, where the space between one arc ending > and another starting is inferred to be a straight line. > > Each arc is described with an X and Y pixel coordinate, a radius, and a > start and end point in degrees. These arcs can precisely describe the > shape of a notch, and easily allow for a basic bounding box to be > derived using the min/max coordinates specified in the path. > > Some displays feature partially occluded edges ("waterfall edges") where > the screen bends, it may be useful for user interfaces to avoid placing > certain UI elements like buttons too close to these edges. These edges > are described by a distance from the edge where it begins to be > occluded, and the number of degrees that the display curves (this > directly affects how usable this edge of the screen is). > > [1]: > https://lore.kernel.org/dri-devel/f8747f99-0695-5be0-841f-4f72ba5d5...@connolly.tech/ > [2]: https://gitlab.freedesktop.org/wayland/wayland-protocols/-/issues/87 > [3]: https://gitlab.gnome.org/World/Phosh/gmobile > > Signed-off-by: Caleb Connolly > --- > Some folks have previously suggested that this information belongs in > userspace and not in devicetree. I would like to be clear that > devicetree is for describing hardware, and parts of a display which can > never actually be seen are very much properties of the underlying > hardware. Makes sense to me. There's similar work happening for touchscreens/pads here[1]. Seems like there might be some overlap in terms of what the binding needs. > --- > base-commit: 268c4b354d66908697299063c44c0b553b01d935 > > // Caleb (they/them) > --- > .../bindings/display/panel/panel-common.yaml | 7 + > .../bindings/display/panel/panel-occlusions.yaml | 182 > + > 2 files changed, 189 insertions(+) > > diff --git > a/Documentation/devicetree/bindings/display/panel/panel-common.yaml > b/Documentation/devicetree/bindings/display/panel/panel-common.yaml > index 0a57a31f4f3d..6ea52a031872 100644 > --- a/Documentation/devicetree/bindings/display/panel/panel-common.yaml > +++ b/Documentation/devicetree/bindings/display/panel/panel-common.yaml > @@ -150,6 +150,13 @@ properties: >controller, this property contains a phandle that references the >controller. > > + occlusions: > +$ref: panel-occlusions.yaml# > +description: > + Some panels have non-standard shapes due to features like rounded > corners, > + notches, cutouts, and "waterfall" edges. The panel-occlusions bindings > + can be used to describe these features. > + > dependencies: >width-mm: [ height-mm ] >height-mm: [ width-mm ] > diff --git > a/Documentation/devicetree/bindings/display/panel/panel-occlusions.yaml > b/Documentation/devicetree/bindings/display/panel/panel-occlusions.yaml > new file mode 100644 > index ..0932026bbd8c > --- /dev/null > +++ b/Documentation/devicetree/bindings/display/panel/panel-occlusions.yaml > @@ -0,0 +1,182 @@ > +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/display/panel/panel-occlusions.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Common Properties for
Re: [PATCH 8/8] dt-bindings: display: Add SSD132x OLED controllers
Hey, On Mon, Oct 09, 2023 at 08:34:22PM +0200, Javier Martinez Canillas wrote: > Add a Device Tree binding schema for the OLED panels based on the Solomon > SSD132x family of controllers. > > Signed-off-by: Javier Martinez Canillas > --- > > .../bindings/display/solomon,ssd132x.yaml | 116 ++ > 1 file changed, 116 insertions(+) > create mode 100644 > Documentation/devicetree/bindings/display/solomon,ssd132x.yaml > > diff --git a/Documentation/devicetree/bindings/display/solomon,ssd132x.yaml > b/Documentation/devicetree/bindings/display/solomon,ssd132x.yaml > new file mode 100644 > index ..b64904703a3a > --- /dev/null > +++ b/Documentation/devicetree/bindings/display/solomon,ssd132x.yaml > @@ -0,0 +1,116 @@ > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/display/solomon,ssd132x.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Solomon SSD132x OLED Controllers > + > +maintainers: > + - Javier Martinez Canillas > + > +properties: > + compatible: > +oneOf: > + - enum: > + - solomon,ssd1322 > + - solomon,ssd1325 > + - solomon,ssd1327 You don't need the oneOf here here as there is only the enum as a possible item. I didn't get anything else in the series, I have to ask - are these controllers not compatible with eachother? > + > + reg: > +maxItems: 1 > + > + reset-gpios: > +maxItems: 1 > + > + # Only required for SPI > + dc-gpios: > +description: > + GPIO connected to the controller's D/C# (Data/Command) pin, > + that is needed for 4-wire SPI to tell the controller if the > + data sent is for a command register or the display data RAM > +maxItems: 1 > + > + solomon,height: > +$ref: /schemas/types.yaml#/definitions/uint32 > +description: > + Height in pixel of the screen driven by the controller. > + The default value is controller-dependent. You probably know better than me, operating in drm stuff, but are there really no generic properties for the weidth/height of a display? > + > + solomon,width: > +$ref: /schemas/types.yaml#/definitions/uint32 > +description: > + Width in pixel of the screen driven by the controller. > + The default value is controller-dependent. > + > +required: > + - compatible > + - reg > + > +allOf: > + - $ref: /schemas/spi/spi-peripheral-props.yaml# > + > + - if: > + properties: > +compatible: > + contains: > +const: solomon,ssd1322 > +then: > + properties: > +width: > + default: 480 > +height: > + default: 128 > + > + - if: > + properties: > +compatible: > + contains: > +const: solomon,ssd1325 > +then: > + properties: > +width: > + default: 128 > +height: > + default: 80 > + > + - if: > + properties: > +compatible: > + contains: > +const: solomon,ssd1327 > +then: > + properties: > +width: > + default: 128 > +height: > + default: 128 Unless you did it like this for clarity, 2 of these have the same default width and 2 have the same default height. You could cut this down to a pair of if/then/else on that basis AFAICT. :wq > + > +unevaluatedProperties: false > + > +examples: > + - | > +i2c { > +#address-cells = <1>; > +#size-cells = <0>; > + > +ssd1327_i2c: oled@3c { This label is unused as far as I can tell. Ditto below. Cheers, Conor. > +compatible = "solomon,ssd1327"; > +reg = <0x3c>; > +reset-gpios = < 7>; > +}; > + > +}; > + - | > +spi { > +#address-cells = <1>; > +#size-cells = <0>; > + > +ssd1327_spi: oled@0 { > +compatible = "solomon,ssd1327"; > +reg = <0x0>; > +reset-gpios = < 7>; > +dc-gpios = < 8>; > +spi-max-frequency = <1000>; > +}; > +}; > -- > 2.41.0 > > signature.asc Description: PGP signature
Re: [PATCH v7 02/20] drm/gpuvm: Helper to get range of unmap from a remap op.
On 10/10/23 15:37, Sarah Walker wrote: From: Donald Robson Determining the start and range of the unmap stage of a remap op is a common piece of code currently implemented by multiple drivers. Add a helper for this. Changes since v6: - Remove use of __always_inline Signed-off-by: Donald Robson Signed-off-by: Sarah Walker --- include/drm/drm_gpuvm.h | 27 +++ 1 file changed, 27 insertions(+) diff --git a/include/drm/drm_gpuvm.h b/include/drm/drm_gpuvm.h index c7ed6bf441d4..932e942da921 100644 --- a/include/drm/drm_gpuvm.h +++ b/include/drm/drm_gpuvm.h @@ -702,4 +702,31 @@ void drm_gpuva_remap(struct drm_gpuva *prev, void drm_gpuva_unmap(struct drm_gpuva_op_unmap *op); +/** + * drm_gpuva_op_remap_get_unmap_range() - Helper to get the start and range of Not a strong opinion on that, but maybe drm_gpuva_op_remap_to_unmap_range() would be a bit better. + * the unmap stage of a remap op. + * @op: Remap op. + * @start_addr: Output pointer for the start of the required unmap. + * @range: Output pointer for the length of the required unmap. + * + * These parameters can then be used by the caller to unmap memory pages that + * are no longer required. I think we should be a bit more precise on what this is good for. Maybe something like: "The given start address and range will be set such that they represent the range of the address space that was previously covered by the mapping getting re-mapped, but is empty now." + */ +static inline void +drm_gpuva_op_remap_get_unmap_range(const struct drm_gpuva_op_remap *op, + u64 *start_addr, u64 *range) +{ + const u64 va_start = op->prev ? +op->prev->va.addr + op->prev->va.range : +op->unmap->va->va.addr; + const u64 va_end = op->next ? + op->next->va.addr : + op->unmap->va->va.addr + op->unmap->va->va.range; + + if (start_addr) + *start_addr = va_start; + if (range) + *range = va_end - va_start; +} + #endif /* __DRM_GPUVM_H__ */
Re: [RFC PATCH 10/10] drm/vkms: Add enumerated 1D curve colorop
On 09/08, Harry Wentland wrote: > Signed-off-by: Harry Wentland > Cc: Ville Syrjala > Cc: Pekka Paalanen > Cc: Simon Ser > Cc: Harry Wentland > Cc: Melissa Wen > Cc: Jonas Ådahl > Cc: Sebastian Wick > Cc: Shashank Sharma > Cc: Alexander Goins > Cc: Joshua Ashton > Cc: Michel Dänzer > Cc: Aleix Pol > Cc: Xaver Hugl > Cc: Victoria Brekenfeld > Cc: Daniel Vetter > Cc: Uma Shankar > Cc: Naseer Ahmed > Cc: Christopher Braga > --- > drivers/gpu/drm/vkms/Makefile| 3 +- > drivers/gpu/drm/vkms/vkms_colorop.c | 108 + > drivers/gpu/drm/vkms/vkms_composer.c | 316 +++ > drivers/gpu/drm/vkms/vkms_drv.h | 4 + > drivers/gpu/drm/vkms/vkms_plane.c| 2 + > 5 files changed, 432 insertions(+), 1 deletion(-) > create mode 100644 drivers/gpu/drm/vkms/vkms_colorop.c > > diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile > index 1b28a6a32948..bcf508873622 100644 > --- a/drivers/gpu/drm/vkms/Makefile > +++ b/drivers/gpu/drm/vkms/Makefile > @@ -6,6 +6,7 @@ vkms-y := \ > vkms_formats.o \ > vkms_crtc.o \ > vkms_composer.o \ > - vkms_writeback.o > + vkms_writeback.o \ > + vkms_colorop.o > > obj-$(CONFIG_DRM_VKMS) += vkms.o > diff --git a/drivers/gpu/drm/vkms/vkms_colorop.c > b/drivers/gpu/drm/vkms/vkms_colorop.c > new file mode 100644 > index ..b3da0705bca7 > --- /dev/null > +++ b/drivers/gpu/drm/vkms/vkms_colorop.c > @@ -0,0 +1,108 @@ > +/* > + * Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > + * OTHER DEALINGS IN THE SOFTWARE. > + * > + * Authors: AMD > + * > + */ > + > +#include > +#include > +#include > +#include > +#include > + > +#define MAX_COLOR_PIPELINES 5 > + > +const int vkms_initialize_tf_pipeline(struct drm_plane *plane, struct > drm_prop_enum_list *list) > +{ > + > + struct drm_colorop *op, *prev_op; > + struct drm_device *dev = plane->dev; > + int ret; > + > + /* 1st op: 1d curve */ > + op = kzalloc(sizeof(struct drm_colorop), GFP_KERNEL); > + if (!op) { > + DRM_ERROR("KMS: Failed to allocate colorop\n"); > + return -ENOMEM; > + } > + > + ret = drm_colorop_init(dev, op, plane, DRM_COLOROP_1D_CURVE); > + if (ret) > + return ret; > + > + list->type = op->base.id; > + list->name = kasprintf(GFP_KERNEL, "Color Pipeline %d", op->base.id); > + > + prev_op = op; > + > + /* 2nd op: 1d curve */ > + op = kzalloc(sizeof(struct drm_colorop), GFP_KERNEL); > + if (!op) { > + DRM_ERROR("KMS: Failed to allocate colorop\n"); > + return -ENOMEM; > + } > + > + ret = drm_colorop_init(dev, op, plane, DRM_COLOROP_1D_CURVE); > + if (ret) > + return ret; > + > + drm_colorop_set_next_property(prev_op, op); > + > + return 0; > +} > + > +int vkms_initialize_colorops(struct drm_plane *plane) > +{ > + struct drm_device *dev = plane->dev; > + struct drm_property *prop; > + struct drm_prop_enum_list pipelines[MAX_COLOR_PIPELINES]; > + int len = 0; > + int ret; > + > + /* Add "Bypass" (i.e. NULL) pipeline */ > + pipelines[len].type = 0; > + pipelines[len].name = "Bypass"; > + len++; > + > + /* Add pipeline consisting of transfer functions */ > + ret = vkms_initialize_tf_pipeline(plane, &(pipelines[len])); > + if (ret) > + return ret; > + len++; > + > + /* Create COLOR_PIPELINE property and attach */ > + prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, > + "COLOR_PIPELINE", > + pipelines, len); > + if (!prop) > + return -ENOMEM; > + > + plane->color_pipeline_property = prop; > + > + drm_object_attach_property(>base, prop, 0); > + > + /* TODO do we even need this? */ > +
Re: [PATCH v3 04/16] platform/x86/amd/pmf: Add support for PMF Policy Binary
On 10/10/2023 07:59, Shyam Sundar S K wrote: PMF Policy binary is a encrypted and signed binary that will be part of the BIOS. PMF driver via the ACPI interface checks the existence of Smart PC bit. If the advertised bit is found, PMF driver walks the acpi namespace to find out the policy binary size and the address which has to be passed to the TA during the TA init sequence. The policy binary is comprised of inputs (or the events) and outputs (or the actions). With the PMF ecosystem, OEMs generate the policy binary (or could be multiple binaries) that contains a supported set of inputs and outputs which could be specifically carved out for each usage segment (or for each user also) that could influence the system behavior either by enriching the user experience or/and boost/throttle power limits. Once the TA init command succeeds, the PMF driver sends the changing events in the current environment to the TA for a constant sampling frequency time (the event here could be a lid close or open) and if the policy binary has corresponding action built within it, the TA sends the action for it in the subsequent enact command. If the inputs sent to the TA has no output defined in the policy binary generated by OEMs, there will be no action to be performed by the PMF driver. Example policies: 1) if slider is performance ; set the SPL to 40W Here PMF driver registers with the platform profile interface and when the slider position is changed, PMF driver lets the TA know about this. TA sends back an action to update the Sustained Power Limit (SPL). PMF driver updates this limit via the PMFW mailbox. 2) if user_away ; then lock the system Here PMF driver hooks to the AMD SFH driver to know the user presence and send the inputs to TA and if the condition is met, the TA sends the action of locking the system. PMF driver generates a uevent and based on the udev rule in the userland the system gets locked with systemctl. The intent here is to provide the OEM's to make a policy to lock the system when the user is away ; but the userland can make a choice to ignore it. and so on. The OEMs will have an utility to create numerous such policies and the policies shall be reviewed by AMD before signing and encrypting them. Policies are shared between operating systems to have seemless user experience. Since all this action has to happen via the "amdtee" driver, currently there is no caller for it in the kernel which can load the amdtee driver. Without amdtee driver loading onto the system the "tee" calls shall fail from the PMF driver. Hence an explicit "request_module" has been added to address this. Signed-off-by: Shyam Sundar S K --- drivers/platform/x86/amd/pmf/Kconfig | 2 +- drivers/platform/x86/amd/pmf/acpi.c | 37 +++ drivers/platform/x86/amd/pmf/core.c | 13 +++ drivers/platform/x86/amd/pmf/pmf.h| 136 drivers/platform/x86/amd/pmf/tee-if.c | 146 +- 5 files changed, 331 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/amd/pmf/Kconfig b/drivers/platform/x86/amd/pmf/Kconfig index 32a029e8db80..f246252bddd8 100644 --- a/drivers/platform/x86/amd/pmf/Kconfig +++ b/drivers/platform/x86/amd/pmf/Kconfig @@ -9,7 +9,7 @@ config AMD_PMF depends on POWER_SUPPLY depends on AMD_NB select ACPI_PLATFORM_PROFILE - depends on TEE + depends on TEE && AMDTEE help This driver provides support for the AMD Platform Management Framework. The goal is to enhance end user experience by making AMD PCs smarter, diff --git a/drivers/platform/x86/amd/pmf/acpi.c b/drivers/platform/x86/amd/pmf/acpi.c index 3fc5e4547d9f..d0512af2cd42 100644 --- a/drivers/platform/x86/amd/pmf/acpi.c +++ b/drivers/platform/x86/amd/pmf/acpi.c @@ -286,6 +286,43 @@ int apmf_install_handler(struct amd_pmf_dev *pmf_dev) return 0; } +static acpi_status apmf_walk_resources(struct acpi_resource *res, void *data) +{ + struct amd_pmf_dev *dev = data; + + switch (res->type) { + case ACPI_RESOURCE_TYPE_ADDRESS64: + dev->policy_addr = res->data.address64.address.minimum; + dev->policy_sz = res->data.address64.address.address_length; + break; + case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: + dev->policy_addr = res->data.fixed_memory32.address; + dev->policy_sz = res->data.fixed_memory32.address_length; + break; + } + + if (!dev->policy_addr || dev->policy_sz > POLICY_BUF_MAX_SZ || dev->policy_sz == 0) { + pr_err("Incorrect Policy params, possibly a SBIOS bug\n"); + return AE_ERROR; + } + + return AE_OK; +} + +int apmf_check_smart_pc(struct amd_pmf_dev *pmf_dev) +{ + acpi_handle ahandle = ACPI_HANDLE(pmf_dev->dev); + acpi_status status; + + status = acpi_walk_resources(ahandle, METHOD_NAME__CRS, apmf_walk_resources, pmf_dev); +
Re: [RFC PATCH 02/10] drm/colorop: Introduce new drm_colorop mode object
On 09/08, Harry Wentland wrote: > This patches introduces a new drm_colorop mode object. This > object represents color transformations and can be used to > define color pipelines. > > We also introduce the drm_colorop_state here, as well as > various helpers and state tracking bits. > > Signed-off-by: Harry Wentland > Cc: Ville Syrjala > Cc: Pekka Paalanen > Cc: Simon Ser > Cc: Harry Wentland > Cc: Melissa Wen > Cc: Jonas Ådahl > Cc: Sebastian Wick > Cc: Shashank Sharma > Cc: Alexander Goins > Cc: Joshua Ashton > Cc: Michel Dänzer > Cc: Aleix Pol > Cc: Xaver Hugl > Cc: Victoria Brekenfeld > Cc: Daniel Vetter > Cc: Uma Shankar > Cc: Naseer Ahmed > Cc: Christopher Braga > --- > drivers/gpu/drm/Makefile| 1 + > drivers/gpu/drm/drm_atomic.c| 79 + > drivers/gpu/drm/drm_atomic_helper.c | 12 ++ > drivers/gpu/drm/drm_atomic_uapi.c | 48 > drivers/gpu/drm/drm_colorop.c | 169 > drivers/gpu/drm/drm_mode_config.c | 7 ++ > drivers/gpu/drm/drm_plane_helper.c | 2 +- > include/drm/drm_atomic.h| 82 ++ > include/drm/drm_atomic_uapi.h | 1 + > include/drm/drm_colorop.h | 157 ++ > include/drm/drm_mode_config.h | 18 +++ > include/drm/drm_plane.h | 2 + > include/uapi/drm/drm.h | 3 + > include/uapi/drm/drm_mode.h | 1 + > 14 files changed, 581 insertions(+), 1 deletion(-) > create mode 100644 drivers/gpu/drm/drm_colorop.c > create mode 100644 include/drm/drm_colorop.h > > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile > index 1855863b4d7a..941de0269709 100644 > --- a/drivers/gpu/drm/Makefile > +++ b/drivers/gpu/drm/Makefile > @@ -16,6 +16,7 @@ drm-y := \ > drm_client.o \ > drm_client_modeset.o \ > drm_color_mgmt.o \ > + drm_colorop.o \ > drm_connector.o \ > drm_crtc.o \ > drm_displayid.o \ > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c > index 11f3a130f6f4..d734e9d5bfed 100644 > --- a/drivers/gpu/drm/drm_atomic.c > +++ b/drivers/gpu/drm/drm_atomic.c > @@ -42,6 +42,7 @@ > #include > #include > #include > +#include > > #include "drm_crtc_internal.h" > #include "drm_internal.h" > @@ -108,6 +109,7 @@ void drm_atomic_state_default_release(struct > drm_atomic_state *state) > kfree(state->connectors); > kfree(state->crtcs); > kfree(state->planes); > + kfree(state->colorops); > kfree(state->private_objs); > } > EXPORT_SYMBOL(drm_atomic_state_default_release); > @@ -139,6 +141,10 @@ drm_atomic_state_init(struct drm_device *dev, struct > drm_atomic_state *state) > sizeof(*state->planes), GFP_KERNEL); > if (!state->planes) > goto fail; > + state->colorops = kcalloc(dev->mode_config.num_colorop, > + sizeof(*state->colorops), GFP_KERNEL); > + if (!state->colorops) > + goto fail; > > state->dev = dev; > > @@ -244,6 +250,20 @@ void drm_atomic_state_default_clear(struct > drm_atomic_state *state) > state->planes[i].new_state = NULL; > } > > + for (i = 0; i < config->num_colorop; i++) { > + struct drm_colorop *colorop = state->colorops[i].ptr; > + > + if (!colorop) > + continue; > + > + drm_colorop_atomic_destroy_state(colorop, > + state->colorops[i].state); > + state->colorops[i].ptr = NULL; > + state->colorops[i].state = NULL; > + state->colorops[i].old_state = NULL; > + state->colorops[i].new_state = NULL; > + } > + > for (i = 0; i < state->num_private_objs; i++) { > struct drm_private_obj *obj = state->private_objs[i].ptr; > > @@ -562,6 +582,65 @@ drm_atomic_get_plane_state(struct drm_atomic_state > *state, > } > EXPORT_SYMBOL(drm_atomic_get_plane_state); > > + > +/** > + * drm_atomic_get_colorop_state - get colorop state > + * @state: global atomic state object > + * @colorop: colorop to get state object for > + * > + * This function returns the colorop state for the given colorop, allocating > it > + * if needed. It will also grab the relevant plane lock to make sure that the > + * state is consistent. > + * > + * Returns: > + * > + * Either the allocated state or the error code encoded into the pointer. > When > + * the error is EDEADLK then the w/w mutex code has detected a deadlock and > the > + * entire atomic sequence must be restarted. All other errors are fatal. > + */ > +struct drm_colorop_state * > +drm_atomic_get_colorop_state(struct drm_atomic_state *state, > + struct drm_colorop *colorop) > +{ > + int ret, index = drm_colorop_index(colorop); > + struct drm_colorop_state *colorop_state; > + struct drm_plane_state
Re: [PATCH v4 1/2] dt-bindings: backlight: Add MPS MP3309C
On Tue, Oct 10, 2023 at 02:16:21PM +0200, Flavio Suligoi wrote: > The Monolithic Power (MPS) MP3309C is a WLED step-up converter, featuring a > programmable switching frequency to optimize efficiency. > The brightness can be controlled either by I2C commands (called "analog" > mode) or by a PWM input signal (PWM mode). > This driver supports both modes. > > For device driver details, please refer to: > - drivers/video/backlight/mp3309c_bl.c > > The datasheet is available at: > - https://www.monolithicpower.com/en/mp3309c.html > > Signed-off-by: Flavio Suligoi > --- > > v4: > - remove not more used allOf keyword > - add brightness-levels and default-brightness properties > - remove max-brightness and default-brightness from required properties > - update example, adding brightness-levels and default-brightness properties > v3: > - add default value for mps,overvoltage-protection-microvolt property > - fix the example, changing from "mps,mp3309c-backlight" to "mps,mp3309c" in >compatible property > v2: > - remove useless properties (dimming-mode, pinctrl-names, pinctrl-0, >switch-on-delay-ms, switch-off-delay-ms, reset-gpios, reset-on-delay-ms, >reset-on-length-ms) > - add common.yaml# > - remove already included properties (default-brightness, max-brightness) > - substitute three boolean properties, used for the overvoltage-protection >values, with a single enum property > - remove some conditional definitions > - remove the 2nd example > v1: > - first version > > .../bindings/leds/backlight/mps,mp3309c.yaml | 82 +++ > 1 file changed, 82 insertions(+) > create mode 100644 > Documentation/devicetree/bindings/leds/backlight/mps,mp3309c.yaml > > diff --git > a/Documentation/devicetree/bindings/leds/backlight/mps,mp3309c.yaml > b/Documentation/devicetree/bindings/leds/backlight/mps,mp3309c.yaml > new file mode 100644 > index ..e2f9ae2b3fb4 > --- /dev/null > +++ b/Documentation/devicetree/bindings/leds/backlight/mps,mp3309c.yaml > @@ -0,0 +1,82 @@ > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/leds/backlight/mps,mp3309c.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: MPS MP3309C backlight > + > +maintainers: > + - Flavio Suligoi > + > +description: | > + The Monolithic Power (MPS) MP3309C is a WLED step-up converter, featuring a > + programmable switching frequency to optimize efficiency. > + It supports two different dimming modes: > + > + - analog mode, via I2C commands, as default mode (32 dimming levels) > + - PWM controlled mode (optional) > + > + The datasheet is available at: > + https://www.monolithicpower.com/en/mp3309c.html > + > +properties: > + compatible: > +const: mps,mp3309c > + > + reg: > +maxItems: 1 > + > + pwms: > +description: if present, the backlight is controlled in PWM mode. > +maxItems: 1 > + > + enable-gpios: > +description: GPIO used to enable the backlight in "analog-i2c" dimming > mode. > +maxItems: 1 > + > + brightness-levels: > +description: > + Array of distinct brightness levels, in PWM dimming mode. > + Typically these are in the range from 0 to 255, but any range starting > + at 0 will do. > + The 0 value means a 0% duty cycle (darkest/off), while the last value > in > + the array represents a 100% duty cycle (brightest). > +$ref: /schemas/types.yaml#/definitions/uint32-array This already has a type defined. Please add it to backlight/common.yaml and remove from led-backlight.yaml and pwm-backlight.yaml. You say 0-255 here, but your example is 0-10. One of those seems wrong. Anyways, don't define constraints in prose, use a schema: items: maximum: 10 (or 255?) > + > + default-brightness: > +description: > + The default brightness (index into the levels array). > +$ref: /schemas/types.yaml#/definitions/uint32 Already has a type. You need to reference backlight/common.yaml. > + > + mps,overvoltage-protection-microvolt: > +description: Overvoltage protection (13.5V, 24V or 35.5V). > +enum: [ 1350, 2400, 3550 ] > +default: 3550 > + > + mps,no-sync-mode: > +description: disable synchronous rectification mode > +type: boolean > + > +required: > + - compatible > + - reg > + > +unevaluatedProperties: false > + > +examples: > + - | > +i2c { > +#address-cells = <1>; > +#size-cells = <0>; > + > +/* Backlight with PWM control */ > +backlight_pwm: backlight@17 { > +compatible = "mps,mp3309c"; > +reg = <0x17>; > +pwms = < 0 333 0>; /* 300 Hz --> (1/f) * 1*10^9 */ > +brightness-levels = <0 1 2 3 4 5 6 7 8 9 10>; > +default-brightness = <8>; > +mps,overvoltage-protection-microvolt = <2400>; > +}; > +}; > -- > 2.34.1 >
Re: [RFC PATCH 01/10] drm/doc/rfc: Describe why prescriptive color pipeline is needed
O 09/08, Harry Wentland wrote: > Signed-off-by: Harry Wentland > Cc: Ville Syrjala > Cc: Pekka Paalanen > Cc: Simon Ser > Cc: Harry Wentland > Cc: Melissa Wen > Cc: Jonas Ådahl > Cc: Sebastian Wick > Cc: Shashank Sharma > Cc: Alexander Goins > Cc: Joshua Ashton > Cc: Michel Dänzer > Cc: Aleix Pol > Cc: Xaver Hugl > Cc: Victoria Brekenfeld > Cc: Daniel Vetter > Cc: Uma Shankar > Cc: Naseer Ahmed > Cc: Christopher Braga > --- > Documentation/gpu/rfc/color_pipeline.rst | 278 +++ > 1 file changed, 278 insertions(+) > create mode 100644 Documentation/gpu/rfc/color_pipeline.rst > > diff --git a/Documentation/gpu/rfc/color_pipeline.rst > b/Documentation/gpu/rfc/color_pipeline.rst > new file mode 100644 > index ..bfa4a8f12087 > --- /dev/null > +++ b/Documentation/gpu/rfc/color_pipeline.rst > @@ -0,0 +1,278 @@ > + > +Linux Color Pipeline API > + > + > +What problem are we solving? > + > + > +We would like to support pre-, and post-blending complex color > transformations > +in order to allow for HW-supported HDR use-cases, as well as to provide > support > +to color-managed applications, such as video or image editors. > + > +While it is possible to support an HDR output on HW supporting the Colorspace > +and HDR Metadata drm_connector properties that requires the compositor or > +application to render and compose the content into one final buffer intended > for > +display. Doing so is costly. > + > +Most modern display HW offers various 1D LUTs, 3D LUTs, matrices, and other > +operations to support color transformations. These operations are often > +implemented in fixed-function HW and therefore much more power efficient than > +performing similar operations via shaders or CPU. > + > +We would like to make use of this HW functionality to support complex color > +transformations with no, or minimal CPU or shader load. > + > + > +How are other OSes solving this problem? > + > + > +The most widely supported use-cases regard HDR content, whether video or > +gaming. > + > +Most OSes will specify the source content format (color gamut, encoding > transfer > +function, and other metadata, such as max and average light levels) to a > driver. > +Drivers will then program their fixed-function HW accordingly to map from a > +source content buffer's space to a display's space. > + > +When fixed-function HW is not available the compositor will assemble a > shader to > +ask the GPU to perform the transformation from the source content format to > the > +display's format. > + > +A compositor's mapping function and a driver's mapping function are usually > +entirely separate concepts. On OSes where a HW vendor has no insight into > +closed-source compositor code such a vendor will tune their color management > +code to visually match the compositor's. On other OSes, where both mapping > +functions are open to an implementer they will ensure both mappings match. > + > + > +Why is Linux different? > +=== > + > +Unlike other OSes, where there is one compositor for one or more drivers, on > +Linux we have a many-to-many relationship. Many compositors; many drivers. > +In addition each compositor vendor or community has their own view of how > +color management should be done. This is what makes Linux so beautiful. > + > +This means that a HW vendor can now no longer tune their driver to one > +compositor, as tuning it to one will almost inevitably make it look very > +different from another compositor's color mapping. > + > +We need a better solution. > + > + > +Descriptive API > +=== > + > +An API that describes the source and destination colorspaces is a descriptive > +API. It describes the input and output color spaces but does not describe > +how precisely they should be mapped. Such a mapping includes many minute > +design decision that can greatly affect the look of the final result. > + > +It is not feasible to describe such mapping with enough detail to ensure the > +same result from each implementation. In fact, these mappings are a very > active > +research area. > + > + > +Prescriptive API > + > + > +A prescriptive API describes not the source and destination colorspaces. It > +instead prescribes a recipe for how to manipulate pixel values to arrive at > the > +desired outcome. > + > +This recipe is generally an order straight-forward operations, with clear > +mathematical definitions, such as 1D LUTs, 3D LUTs, matrices, or other > +operations that can be described in a precise manner. > + > + > +The Color Pipeline API > +== > + > +HW color management pipelines can significantly differ between HW > +vendors in terms of availability, ordering, and capabilities of HW > +blocks. This makes a common definition of color management blocks and > +their ordering nigh impossible.
Re: [PATCH v3 08/16] platform/x86/amd/pmf: Add support to update system state
On 10/10/2023 07:59, Shyam Sundar S K wrote: PMF driver based on the output actions from the TA can request to update the system states like entering s0i3, lock screen etc. by generating an uevent. Based on the udev rules set in the userspace the event id matching the uevent shall get updated accordingly using the systemctl. Sample udev rules under Documentation/admin-guide/pmf.rst. Signed-off-by: Shyam Sundar S K One minor nit below. Reviewed-by: Mario Limonciello --- Documentation/admin-guide/index.rst | 1 + Documentation/admin-guide/pmf.rst | 25 +++ drivers/platform/x86/amd/pmf/pmf.h| 9 +++ drivers/platform/x86/amd/pmf/tee-if.c | 36 ++- 4 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 Documentation/admin-guide/pmf.rst diff --git a/Documentation/admin-guide/index.rst b/Documentation/admin-guide/index.rst index 43ea35613dfc..fb40a1f6f79e 100644 --- a/Documentation/admin-guide/index.rst +++ b/Documentation/admin-guide/index.rst @@ -119,6 +119,7 @@ configure specific aspects of kernel behavior to your liking. parport perf-security pm/index + pmf pnp rapidio ras diff --git a/Documentation/admin-guide/pmf.rst b/Documentation/admin-guide/pmf.rst new file mode 100644 index ..6985bb5b9452 --- /dev/null +++ b/Documentation/admin-guide/pmf.rst @@ -0,0 +1,25 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Set udev rules for PMF Smart PC Builder +--- + +AMD PMF(Platform Management Framework) Smart PC Solution builder has to set the system states +like S0i3, Screen lock, hibernate etc, based on the output actions provided by the PMF +TA (Trusted Application). + +In order for this to work the PMF driver generates a uevent for userspace to react to. Below are +sample udev rules that can facilitate this experience when a machine has PMF Smart PC solution builder +enabled. + +Please add the following line(s) to +``/etc/udev/rules.d/99-local.rules``:: + +DRIVERS=="amd-pmf", ACTION=="change", ENV{EVENT_ID}=="0", RUN+="/usr/bin/systemctl suspend" +DRIVERS=="amd-pmf", ACTION=="change", ENV{EVENT_ID}=="1", RUN+="/usr/bin/systemctl hibernate" +DRIVERS=="amd-pmf", ACTION=="change", ENV{EVENT_ID}=="2", RUN+="/bin/loginctl lock-sessions" + +EVENT_ID values: +0= Put the system to S0i3/S2Idle +1= Put the system to hibernate +2= Lock the screen + diff --git a/drivers/platform/x86/amd/pmf/pmf.h b/drivers/platform/x86/amd/pmf/pmf.h index 20f3e16b0a32..67f3d5a7 100644 --- a/drivers/platform/x86/amd/pmf/pmf.h +++ b/drivers/platform/x86/amd/pmf/pmf.h @@ -73,6 +73,7 @@ #define PMF_POLICY_STT_MIN6 #define PMF_POLICY_STT_SKINTEMP_APU 7 #define PMF_POLICY_STT_SKINTEMP_HS2 8 +#define PMF_POLICY_SYSTEM_STATE9 #define PMF_POLICY_P3T38 /* TA macros */ @@ -440,6 +441,13 @@ struct apmf_dyn_slider_output { } __packed; /* Smart PC - TA internals */ I know that Ilpo had a comment about this in an earlier version that there is a "__" instead of "_". I know this is intended behavior for consistency with internal usage, but maybe it's worth having a comment somewhere mentioning it's intended behavior? I'm not sure where. +enum system_state { + SYSTEM_STATE__S0i3, + SYSTEM_STATE__S4, + SYSTEM_STATE__SCREEN_LOCK, + SYSTEM_STATE__MAX +}; + enum ta_slider { TA_BEST_BATTERY,/* Best Battery */ TA_BETTER_BATTERY, /* Better Battery */ @@ -471,6 +479,7 @@ enum ta_pmf_error_type { }; struct pmf_action_table { + enum system_state system_state; u32 spl;/* in mW */ u32 sppt; /* in mW */ u32 sppt_apuonly; /* in mW */ diff --git a/drivers/platform/x86/amd/pmf/tee-if.c b/drivers/platform/x86/amd/pmf/tee-if.c index 92879ae4f8f0..c08ef13a1494 100644 --- a/drivers/platform/x86/amd/pmf/tee-if.c +++ b/drivers/platform/x86/amd/pmf/tee-if.c @@ -24,6 +24,20 @@ MODULE_PARM_DESC(pb_actions_ms, "Policy binary actions sampling frequency (defau static const uuid_t amd_pmf_ta_uuid = UUID_INIT(0x6fd93b77, 0x3fb8, 0x524d, 0xb1, 0x2d, 0xc5, 0x29, 0xb1, 0x3d, 0x85, 0x43); +static const char *amd_pmf_uevent_as_str(unsigned int state) +{ + switch (state) { + case SYSTEM_STATE__S0i3: + return "S0i3"; + case SYSTEM_STATE__S4: + return "S4"; + case SYSTEM_STATE__SCREEN_LOCK: + return "SCREEN_LOCK"; + default: + return "Unknown Smart PC event"; + } +} + static void amd_pmf_prepare_args(struct amd_pmf_dev *dev, int cmd, struct tee_ioctl_invoke_arg *arg,
Re: [PATCH v3 11/16] platform/x86/amd/pmf: dump policy binary data
On 10/10/2023 07:59, Shyam Sundar S K wrote: Sometimes policy binary retrieved from the BIOS maybe incorrect that can end up in failing to enable the Smart PC solution feature. Use print_hex_dump_debug() to dump the policy binary in hex, so that we debug the issues related to the binary even before sending that to TA. Signed-off-by: Shyam Sundar S K Reviewed-by: Mario Limonciello --- drivers/platform/x86/amd/pmf/tee-if.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/platform/x86/amd/pmf/tee-if.c b/drivers/platform/x86/amd/pmf/tee-if.c index 994daf945795..e4386f503ad0 100644 --- a/drivers/platform/x86/amd/pmf/tee-if.c +++ b/drivers/platform/x86/amd/pmf/tee-if.c @@ -275,6 +275,12 @@ static int amd_pmf_start_policy_engine(struct amd_pmf_dev *dev) } #ifdef CONFIG_AMD_PMF_DEBUG +static void amd_pmf_hex_dump_pb(struct amd_pmf_dev *dev) +{ + print_hex_dump_debug("(pb): ", DUMP_PREFIX_OFFSET, 16, 1, dev->policy_buf, +dev->policy_sz, false); +} + static ssize_t amd_pmf_get_pb_data(struct file *filp, const char __user *buf, size_t length, loff_t *pos) { @@ -289,6 +295,7 @@ static ssize_t amd_pmf_get_pb_data(struct file *filp, const char __user *buf, if (copy_from_user(dev->policy_buf, buf, dev->policy_sz)) return -EFAULT; + amd_pmf_hex_dump_pb(dev); ret = amd_pmf_start_policy_engine(dev); if (ret) return -EINVAL; @@ -327,6 +334,7 @@ static int amd_pmf_open_pb(struct amd_pmf_dev *dev, struct dentry *debugfs_root) } static void amd_pmf_remove_pb(struct amd_pmf_dev *dev) {} +static void amd_pmf_hex_dump_pb(struct amd_pmf_dev *dev) {} #endif static int amd_pmf_get_bios_buffer(struct amd_pmf_dev *dev) @@ -341,6 +349,7 @@ static int amd_pmf_get_bios_buffer(struct amd_pmf_dev *dev) memcpy(dev->policy_buf, dev->policy_base, dev->policy_sz); + amd_pmf_hex_dump_pb(dev); if (pb_side_load) amd_pmf_open_pb(dev, dev->dbgfs_dir);
Re: [PATCH v3 16/16] platform/x86/amd/pmf: Add PMF-AMDSFH interface for ALS
On 10/10/2023 07:59, Shyam Sundar S K wrote: From: Basavaraj Natikar AMDSFH has information about the Ambient light via the Ambient Light Sensor (ALS) which is part of the AMD sensor fusion hub. Add PMF and AMDSFH interface to get this information. make amd_sfh_float_to_int() as non-static function so that this can be called outside of the current file. Co-developed-by: Shyam Sundar S K Signed-off-by: Shyam Sundar S K Signed-off-by: Basavaraj Natikar Reviewed-by: Mario Limonciello --- drivers/hid/amd-sfh-hid/amd_sfh_common.h | 1 + drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c | 2 +- drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c | 6 ++ .../amd-sfh-hid/sfh1_1/amd_sfh_interface.c| 20 +++ .../amd-sfh-hid/sfh1_1/amd_sfh_interface.h| 1 + drivers/platform/x86/amd/pmf/spc.c| 7 +++ include/linux/amd-pmf-io.h| 2 ++ 7 files changed, 38 insertions(+), 1 deletion(-) diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_common.h b/drivers/hid/amd-sfh-hid/amd_sfh_common.h index cd57037bf217..a1950bc6e6ce 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_common.h +++ b/drivers/hid/amd-sfh-hid/amd_sfh_common.h @@ -39,6 +39,7 @@ struct amd_mp2_sensor_info { struct sfh_dev_status { bool is_hpd_present; + bool is_als_present; }; struct amd_mp2_dev { diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c index 47a87b28e00e..dbc8c6943ca1 100644 --- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c +++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c @@ -132,7 +132,7 @@ static void get_common_inputs(struct common_input_property *common, int report_i common->event_type = HID_USAGE_SENSOR_EVENT_DATA_UPDATED_ENUM; } -static int amd_sfh_float_to_int(u32 flt32_val) +int amd_sfh_float_to_int(u32 flt32_val) This change might roll into patch 14, but I don't think it's that big of a deal. { int fraction, shift, mantissa, sign, exp, zeropre; diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c index 3dc652d41d7d..f2890d329459 100644 --- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c +++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c @@ -77,6 +77,9 @@ static int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata) case HPD_IDX: privdata->dev_en.is_hpd_present = false; break; + case ALS_IDX: + privdata->dev_en.is_als_present = false; + break; } if (cl_data->sensor_sts[i] == SENSOR_ENABLED) { @@ -188,6 +191,9 @@ static int amd_sfh1_1_hid_client_init(struct amd_mp2_dev *privdata) case HPD_IDX: privdata->dev_en.is_hpd_present = true; break; + case ALS_IDX: + privdata->dev_en.is_als_present = true; + break; } } dev_dbg(dev, "sid 0x%x (%s) status 0x%x\n", diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c index 7637da0dec6f..48a7a450e029 100644 --- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c +++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c @@ -94,12 +94,32 @@ static int amd_sfh_hpd_info(u8 *user_present) return -ENODEV; } +static int amd_sfh_als_info(u32 *ambient_light) +{ + if (emp2 && emp2->dev_en.is_als_present) { + struct sfh_als_data als_data; + void __iomem *sensoraddr; + + sensoraddr = emp2->vsbase + + (ALS_IDX * SENSOR_DATA_MEM_SIZE_DEFAULT) + + OFFSET_SENSOR_DATA_DEFAULT; + memcpy_fromio(_data, sensoraddr, sizeof(struct sfh_als_data)); + *ambient_light = amd_sfh_float_to_int(als_data.lux); + + return 0; + } + + return -ENODEV; +} + int amd_get_sfh_info(struct amd_sfh_info *sfh_info, enum sfh_message_type op) { if (sfh_info) { switch (op) { case MT_HPD: return amd_sfh_hpd_info(_info->user_present); + case MT_ALS: + return amd_sfh_als_info(_info->ambient_light); } } return -EINVAL; diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h index 9d31d5b510eb..7ecddad430e4 100644 --- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h +++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h @@ -149,6 +149,7 @@ struct hpd_status { }; }; +int amd_sfh_float_to_int(u32 flt32_val); void sfh_interface_init(struct amd_mp2_dev *mp2); void amd_sfh1_1_set_desc_ops(struct
Re: [PATCH v3] drm/virtio: add new virtio gpu capset definitions
On 10/10/23 18:40, Dmitry Osipenko wrote: > On 10/10/23 16:57, Huang Rui wrote: >> These definitions are used fro qemu, and qemu imports this marco in the >> headers to enable gfxstream, venus, cross domain, and drm (native >> context) for virtio gpu. So it should add them even kernel doesn't use >> this. >> >> Signed-off-by: Huang Rui >> Reviewed-by: Akihiko Odaki >> --- >> >> Changes V1 -> V2: >> - Add all capsets including gfxstream and venus in kernel header (Dmitry >> Osipenko) >> >> Changes V2 -> V3: >> - Add missed capsets including cross domain and drm (native context) >> (Dmitry Osipenko) >> >> v1: https://lore.kernel.org/lkml/20230915105918.3763061-1-ray.hu...@amd.com/ >> v2: https://lore.kernel.org/lkml/20231010032553.1138036-1-ray.hu...@amd.com/ >> >> include/uapi/linux/virtio_gpu.h | 4 >> 1 file changed, 4 insertions(+) >> >> diff --git a/include/uapi/linux/virtio_gpu.h >> b/include/uapi/linux/virtio_gpu.h >> index f556fde07b76..240911c8da31 100644 >> --- a/include/uapi/linux/virtio_gpu.h >> +++ b/include/uapi/linux/virtio_gpu.h >> @@ -309,6 +309,10 @@ struct virtio_gpu_cmd_submit { >> >> #define VIRTIO_GPU_CAPSET_VIRGL 1 >> #define VIRTIO_GPU_CAPSET_VIRGL2 2 >> +#define VIRTIO_GPU_CAPSET_GFXSTREAM 3 > > The GFXSTREAM capset isn't correct, it should be GFXSTREAM_VULKAN in > accordance to [1] and [2]. There are more capsets for GFXSTREAM. > > [1] > https://github.com/google/crosvm/blob/main/rutabaga_gfx/src/rutabaga_utils.rs#L172 > > [2] > https://patchwork.kernel.org/project/qemu-devel/patch/20231006010835.444-7-gurchetansi...@chromium.org/ Though, maybe those are "rutabaga" capsets that not related to virtio-gpu because crosvm has another defs for virtio-gpu capsets [3]. The DRM capset is oddly missing in [3] and code uses "rutabaga" capset for DRM and virtio-gpu. [3] https://github.com/google/crosvm/blob/main/devices/src/virtio/gpu/protocol.rs#L416 Gurchetan, could you please clarify which capsets definitions are related to virtio-gpu and gfxstream. The GFXSTREAM_VULKAN/GLES/MAGMA/COMPOSER or just the single GFXSTREAM? -- Best regards, Dmitry
Re: [RFT PATCH v2 09/12] drm/exynos: Call drm_atomic_helper_shutdown() at shutdown/unbind time
Hi, 2023년 10월 6일 (금) 오후 10:51, Doug Anderson 님이 작성: > > Hi, > > On Thu, Oct 5, 2023 at 7:20 PM Inki Dae wrote: > > > > Thanks for testing. :) > > > > Acked-by : Inki Dae > > Inki: does that mean you'd like this to go through drm-misc? I'm happy > to do that, but there are no dependencies here so this could easily go > through your tree. Ah, you are right. No dependency here. I will pick it up. Thanks, Inki Dae > > > > 2023년 9월 22일 (금) 오후 3:00, Marek Szyprowski 님이 작성: > > > > > > > > > On 21.09.2023 21:26, Douglas Anderson wrote: > > > > Based on grepping through the source code this driver appears to be > > > > missing a call to drm_atomic_helper_shutdown() at system shutdown time > > > > and at driver unbind time. Among other things, this means that if a > > > > panel is in use that it won't be cleanly powered off at system > > > > shutdown time. > > > > > > > > The fact that we should call drm_atomic_helper_shutdown() in the case > > > > of OS shutdown/restart and at driver remove (or unbind) time comes > > > > straight out of the kernel doc "driver instance overview" in > > > > drm_drv.c. > > > > > > > > A few notes about this fix: > > > > - When adding drm_atomic_helper_shutdown() to the unbind path, I added > > > >it after drm_kms_helper_poll_fini() since that's when other drivers > > > >seemed to have it. > > > > - Technically with a previous patch, ("drm/atomic-helper: > > > >drm_atomic_helper_shutdown(NULL) should be a noop"), we don't > > > >actually need to check to see if our "drm" pointer is NULL before > > > >calling drm_atomic_helper_shutdown(). We'll leave the "if" test in, > > > >though, so that this patch can land without any dependencies. It > > > >could potentially be removed later. > > > > - This patch also makes sure to set the drvdata to NULL in the case of > > > >bind errors to make sure that shutdown can't access freed data. > > > > > > > > Suggested-by: Maxime Ripard > > > > Reviewed-by: Maxime Ripard > > > > Signed-off-by: Douglas Anderson > > > > > > Seems to be working fine on all my test Exynos-based boards with display. > > > > > > Tested-by: Marek Szyprowski > > > > > > Reviewed-by: Marek Szyprowski > > > > > > > --- > > > > This commit is only compile-time tested. > > > > > > > > (no changes since v1) > > > > > > > > drivers/gpu/drm/exynos/exynos_drm_drv.c | 11 +++ > > > > 1 file changed, 11 insertions(+) > > > > > > > > diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c > > > > b/drivers/gpu/drm/exynos/exynos_drm_drv.c > > > > index 8399256cb5c9..5380fb6c55ae 100644 > > > > --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c > > > > +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c > > > > @@ -300,6 +300,7 @@ static int exynos_drm_bind(struct device *dev) > > > > drm_mode_config_cleanup(drm); > > > > exynos_drm_cleanup_dma(drm); > > > > kfree(private); > > > > + dev_set_drvdata(dev, NULL); > > > > err_free_drm: > > > > drm_dev_put(drm); > > > > > > > > @@ -313,6 +314,7 @@ static void exynos_drm_unbind(struct device *dev) > > > > drm_dev_unregister(drm); > > > > > > > > drm_kms_helper_poll_fini(drm); > > > > + drm_atomic_helper_shutdown(drm); > > > > > > > > component_unbind_all(drm->dev, drm); > > > > drm_mode_config_cleanup(drm); > > > > @@ -350,9 +352,18 @@ static int exynos_drm_platform_remove(struct > > > > platform_device *pdev) > > > > return 0; > > > > } > > > > > > > > +static void exynos_drm_platform_shutdown(struct platform_device *pdev) > > > > +{ > > > > + struct drm_device *drm = platform_get_drvdata(pdev); > > > > + > > > > + if (drm) > > > > + drm_atomic_helper_shutdown(drm); > > > > +} > > > > + > > > > static struct platform_driver exynos_drm_platform_driver = { > > > > .probe = exynos_drm_platform_probe, > > > > .remove = exynos_drm_platform_remove, > > > > + .shutdown = exynos_drm_platform_shutdown, > > > > .driver = { > > > > .name = "exynos-drm", > > > > .pm = _drm_pm_ops, > > > > > > Best regards > > > -- > > > Marek Szyprowski, PhD > > > Samsung R Institute Poland > > >
Re: (subset) [PATCH v3 0/5] Support bridge/connector by Tegra HDMI
From: Thierry Reding On Mon, 07 Aug 2023 17:35:10 +0300, Svyatoslav Ryhel wrote: > This patch adds support for the bridge/connector attached to the > HDMI output, allowing to model the hardware properly. It keeps > backwards compatibility with existing bindings and is required > by devices which have a simple or MHL bridge connected to HDMI > output like ASUS P1801-T or LG P880/P895 or HTC One X. > > Tested on ASUS Transformers which have no dedicated bridge but > have type d HDMI connector directly available. Tests went smoothly. > > [...] Applied, thanks! [1/5] ARM: dts: tegra: Drop unit-address from parallel RGB output port (no commit info) Best regards, -- Thierry Reding
Re: [PATCH v3] drm/virtio: add new virtio gpu capset definitions
On 10/10/23 16:57, Huang Rui wrote: > These definitions are used fro qemu, and qemu imports this marco in the > headers to enable gfxstream, venus, cross domain, and drm (native > context) for virtio gpu. So it should add them even kernel doesn't use > this. > > Signed-off-by: Huang Rui > Reviewed-by: Akihiko Odaki > --- > > Changes V1 -> V2: > - Add all capsets including gfxstream and venus in kernel header (Dmitry > Osipenko) > > Changes V2 -> V3: > - Add missed capsets including cross domain and drm (native context) > (Dmitry Osipenko) > > v1: https://lore.kernel.org/lkml/20230915105918.3763061-1-ray.hu...@amd.com/ > v2: https://lore.kernel.org/lkml/20231010032553.1138036-1-ray.hu...@amd.com/ > > include/uapi/linux/virtio_gpu.h | 4 > 1 file changed, 4 insertions(+) > > diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h > index f556fde07b76..240911c8da31 100644 > --- a/include/uapi/linux/virtio_gpu.h > +++ b/include/uapi/linux/virtio_gpu.h > @@ -309,6 +309,10 @@ struct virtio_gpu_cmd_submit { > > #define VIRTIO_GPU_CAPSET_VIRGL 1 > #define VIRTIO_GPU_CAPSET_VIRGL2 2 > +#define VIRTIO_GPU_CAPSET_GFXSTREAM 3 The GFXSTREAM capset isn't correct, it should be GFXSTREAM_VULKAN in accordance to [1] and [2]. There are more capsets for GFXSTREAM. [1] https://github.com/google/crosvm/blob/main/rutabaga_gfx/src/rutabaga_utils.rs#L172 [2] https://patchwork.kernel.org/project/qemu-devel/patch/20231006010835.444-7-gurchetansi...@chromium.org/ -- Best regards, Dmitry
Re: [PATCH -next] drm/tegra: Remove two unused function declarations
On Wed, Aug 09, 2023 at 11:02:26AM +0800, Yue Haibing wrote: > Commit 776dc3840367 ("drm/tegra: Move subdevice infrastructure to host1x") > removed the implementation but not the declaration. > > Signed-off-by: Yue Haibing > --- > drivers/gpu/drm/tegra/drm.h | 3 --- > 1 file changed, 3 deletions(-) Applied, thanks. Thierry signature.asc Description: PGP signature
Re: [PATCH 1/2] drm/tegra: Return an error code if fails
On Tue, Oct 10, 2023 at 03:22:56PM +0200, Thierry Reding wrote: > On Mon, Jun 26, 2023 at 10:33:30PM +0800, Sui Jingfeng wrote: > > Return -ENOMEM if tegra_bo_mmap() fails. > > > > Signed-off-by: Sui Jingfeng > > --- > > drivers/gpu/drm/tegra/gem.c | 2 ++ > > 1 file changed, 2 insertions(+) > > Sorry, this fell through the cracks. I think it'd be better if > tegra_bo_mmap() were to be improved to always return either an ERR_PTR() > encoded error code or a valid pointer. Throwing NULL into the mix isn't > useful because it typically means something like -ENOMEM anyway. Error > codes are more explicit, so since we're already using them for some > cases, might as well return them for all. > > Actually, looks like tegra_bo_mmap() never actually returns an ERR_PTR() > encoded error code. It's either obj->vaddr, the return value of vmap() > (which is either NULL or the address of the mapping), or the address > obtained from dma_buf_vmap_unlocked() (i.e. map.vaddr) or NULL on > failure. So I think it would equally make sense to keep your patch and > to remove the IS_ERR() check below it. > > I would slightly prefer the first option, but either is fine. How about the attached patch? Thierry From b34a09efcf7b1d2c25d3baf8c6d91c5ca09b4e0f Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 10 Oct 2023 17:26:14 +0200 Subject: [PATCH] drm/tegra: gem: Do not return NULL in tegra_bo_mmap() It's confusing for a function to return NULL and ERR_PTR()-encoded error codes on failure. Make sure we only ever return the latter since that's what callers already expect. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/gem.c | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index 11296de59c5a..679460e05c05 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -178,6 +178,7 @@ static void *tegra_bo_mmap(struct host1x_bo *bo) { struct tegra_bo *obj = host1x_to_tegra_bo(bo); struct iosys_map map; + void *vaddr; int ret; if (obj->vaddr) @@ -185,10 +186,18 @@ static void *tegra_bo_mmap(struct host1x_bo *bo) if (obj->gem.import_attach) { ret = dma_buf_vmap_unlocked(obj->gem.import_attach->dmabuf, ); - return ret ? NULL : map.vaddr; + if (ret < 0) + return ERR_PTR(ret); + + return map.vaddr; } - return vmap(obj->pages, obj->num_pages, VM_MAP, pgprot_writecombine(PAGE_KERNEL)); + vaddr = vmap(obj->pages, obj->num_pages, VM_MAP, +pgprot_writecombine(PAGE_KERNEL)); + if (!vaddr) + return -ENOMEM; + + return vaddr; } static void tegra_bo_munmap(struct host1x_bo *bo, void *addr) -- 2.42.0 signature.asc Description: PGP signature
Re: [PATCH 2/2] drm/tegra: Remove surplus else after return
On Mon, Jun 26, 2023 at 10:33:31PM +0800, Sui Jingfeng wrote: > else is not generally useful after return > > Signed-off-by: Sui Jingfeng > --- > drivers/gpu/drm/tegra/gem.c | 19 ++- > 1 file changed, 10 insertions(+), 9 deletions(-) Applied, thanks. Thierry signature.asc Description: PGP signature
[PATCH] drm/gpuvm: Dual-licence the drm_gpuvm code GPL-2.0 OR MIT
Dual-licence in order to make it possible for other non-GPL os'es to re-implement the code. The use of EXPORT_SYMBOL_GPL() is intentionally left untouched to prevent use of drm_gpuvm as a proxy for non-GPL drivers to access GPL-only kernel symbols. Much of the ideas and algorithms used in the drm_gpuvm code is already present in one way or another in MIT-licensed code. Cc: Danilo Krummrich Cc: airl...@gmail.com Cc: dan...@ffwll.ch Cc: linux-ker...@vger.kernel.org Signed-off-by: Thomas Hellström --- drivers/gpu/drm/drm_gpuvm.c | 2 +- include/drm/drm_gpuvm.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c index 02ce6baacdad..08c088319652 100644 --- a/drivers/gpu/drm/drm_gpuvm.c +++ b/drivers/gpu/drm/drm_gpuvm.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0-only +// SPDX-License-Identifier: GPL-2.0 OR MIT /* * Copyright (c) 2022 Red Hat. * diff --git a/include/drm/drm_gpuvm.h b/include/drm/drm_gpuvm.h index 361fea5cb849..21bbf11415b3 100644 --- a/include/drm/drm_gpuvm.h +++ b/include/drm/drm_gpuvm.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ #ifndef __DRM_GPUVM_H__ #define __DRM_GPUVM_H__ -- 2.41.0
Re: [PATCH v3 11/16] platform/x86/amd/pmf: dump policy binary data
On Tue, 10 Oct 2023, Shyam Sundar S K wrote: > On 10/10/2023 6:38 PM, Ilpo Järvinen wrote: > > On Tue, 10 Oct 2023, Shyam Sundar S K wrote: > > > >> Sometimes policy binary retrieved from the BIOS maybe incorrect that can > >> end up in failing to enable the Smart PC solution feature. > >> > >> Use print_hex_dump_debug() to dump the policy binary in hex, so that we > >> debug the issues related to the binary even before sending that to TA. > >> > >> Signed-off-by: Shyam Sundar S K > >> --- > >> drivers/platform/x86/amd/pmf/tee-if.c | 9 + > >> 1 file changed, 9 insertions(+) > >> > >> diff --git a/drivers/platform/x86/amd/pmf/tee-if.c > >> b/drivers/platform/x86/amd/pmf/tee-if.c > >> index 994daf945795..e4386f503ad0 100644 > >> --- a/drivers/platform/x86/amd/pmf/tee-if.c > >> +++ b/drivers/platform/x86/amd/pmf/tee-if.c > >> @@ -275,6 +275,12 @@ static int amd_pmf_start_policy_engine(struct > >> amd_pmf_dev *dev) > >> } > >> > >> #ifdef CONFIG_AMD_PMF_DEBUG > >> +static void amd_pmf_hex_dump_pb(struct amd_pmf_dev *dev) > >> +{ > >> + print_hex_dump_debug("(pb): ", DUMP_PREFIX_OFFSET, 16, 1, > >> dev->policy_buf, > >> + dev->policy_sz, false); > >> +} > >> + > > > > You forgot to add the empty version of amd_pmf_hex_dump_pb function into > > #else part (so the compile fails if CONFIG_AMD_PMF_DEBUG is not set). > > > > It's there (see below). I have just grouped the functions that come > under #ifdef CONFIG_AMD_PMF_DEBUG and #else so that's more readable. > > >> static ssize_t amd_pmf_get_pb_data(struct file *filp, const char __user > >> *buf, > >> size_t length, loff_t *pos) > >> { > >> @@ -289,6 +295,7 @@ static ssize_t amd_pmf_get_pb_data(struct file *filp, > >> const char __user *buf, > >>if (copy_from_user(dev->policy_buf, buf, dev->policy_sz)) > >>return -EFAULT; > >> > >> + amd_pmf_hex_dump_pb(dev); > >>ret = amd_pmf_start_policy_engine(dev); > >>if (ret) > >>return -EINVAL; > >> @@ -327,6 +334,7 @@ static int amd_pmf_open_pb(struct amd_pmf_dev *dev, > >> struct dentry *debugfs_root) > >> } > >> > >> static void amd_pmf_remove_pb(struct amd_pmf_dev *dev) {} > >> +static void amd_pmf_hex_dump_pb(struct amd_pmf_dev *dev) {} > > Here is the empty amd_pmf_hex_dump_pb(). Ah, sorry. I was confused by the intermediate change. -- i.
Re: [PATCH RFC] dt-bindings: display: document display panel occlusions
Hi Caleb, thanks for putting this out. On Mon, Oct 09, 2023 at 06:32:50PM +0100, Caleb Connolly wrote: > Some display panels found in modern phones and laptops feature > non-standard display shapes with features like rounded corners, notches > (sections of the display that are cut-out from the edge), and cutouts > (such as circular "hole punch" camera cutouts, or wider pill-shaped > "islands"). > > Some discussion has been underway previously on how best to describe > these features [1][2], including a reference userspace implementation > using SVG paths [3]. Using this previous discussion as a jumping off > point, this RFC allows for describing the following display features: > > * Corner radius (on a per-corner basis) > * Circular or pill-shaped cutouts > * Notches with arbitrary shapes The coordinate systems is 0,0 at top,left display corner? > It's easy to make a case for only using rectangles to describe these > missing parts of a display, however this severely limits their utility. > Describing display occlusions as accurately as possible allows for a lot of > useful UX features. For example, displaying a ring around a hole-punch > camera when it's in use, or wrapping UI elements around a notch. These > behaviours are only possible to implement when the dimensions are known > with near pixel-perfect accuracy. > > Cutouts are described as rectangles with a width, height, and corner > radius. > A radius of half the width longest edge will definitionally be an ellipse. > This simple description is suitable for describing hole-punch cameras, > as well > as pill-shaped cutouts. I'm not aware of any devices that can't be > described like this. I wonder if we shouldn't just use a closed SVG path and put this and notches in one bucket that way. We need to indicate the "type" of a notch/cutout anyway as there's e.g. ones which aren't fully opaque but "just" lower resolution areas. We could start out with one type "fully opaque". > Notches are a little more complicated, they usually feature convex and > concave corners as well as straight lines. Here they are described as a > sequence of optionally disjoint arcs, where the space between one arc ending > and another starting is inferred to be a straight line. gmobile is using a subset of a closed SVG path (so does Android afaik). The upside of "just arcs" would be that bounding box is even simpler but as this affects userspace I think getting a better approximation using a path would be worth it and we could treat it the same as cutouts. > Each arc is described with an X and Y pixel coordinate, a radius, and a > start and end point in degrees. These arcs can precisely describe the > shape of a notch, and easily allow for a basic bounding box to be > derived using the min/max coordinates specified in the path. > > Some displays feature partially occluded edges ("waterfall edges") where > the screen bends, it may be useful for user interfaces to avoid placing > certain UI elements like buttons too close to these edges. These edges > are described by a distance from the edge where it begins to be > occluded, and the number of degrees that the display curves (this > directly affects how usable this edge of the screen is). I've not yet seen a device with this on Linux. Would it make sense to leave it out until we have those coming. E.g. are all waterfalls the same or are some more usable for displaying information than others? What is your plan on informing userspace about that? Feed it through DRM via drm properties or would userspace poke at /sys and try to find the right panel for the connector? drm would have the upside of not being bound to device-tree using platforms. Cheers, -- Guido > > [1]: > https://lore.kernel.org/dri-devel/f8747f99-0695-5be0-841f-4f72ba5d5...@connolly.tech/ > [2]: https://gitlab.freedesktop.org/wayland/wayland-protocols/-/issues/87 > [3]: https://gitlab.gnome.org/World/Phosh/gmobile > > Signed-off-by: Caleb Connolly > --- > Some folks have previously suggested that this information belongs in > userspace and not in devicetree. I would like to be clear that > devicetree is for describing hardware, and parts of a display which can > never actually be seen are very much properties of the underlying > hardware. > --- > base-commit: 268c4b354d66908697299063c44c0b553b01d935 > > // Caleb (they/them) > --- > .../bindings/display/panel/panel-common.yaml | 7 + > .../bindings/display/panel/panel-occlusions.yaml | 182 > + > 2 files changed, 189 insertions(+) > > diff --git > a/Documentation/devicetree/bindings/display/panel/panel-common.yaml > b/Documentation/devicetree/bindings/display/panel/panel-common.yaml > index 0a57a31f4f3d..6ea52a031872 100644 > --- a/Documentation/devicetree/bindings/display/panel/panel-common.yaml > +++ b/Documentation/devicetree/bindings/display/panel/panel-common.yaml > @@ -150,6 +150,13 @@ properties: >controller, this property contains a phandle that
[PATCH v3] drm/virtio: add new virtio gpu capset definitions
These definitions are used fro qemu, and qemu imports this marco in the headers to enable gfxstream, venus, cross domain, and drm (native context) for virtio gpu. So it should add them even kernel doesn't use this. Signed-off-by: Huang Rui Reviewed-by: Akihiko Odaki --- Changes V1 -> V2: - Add all capsets including gfxstream and venus in kernel header (Dmitry Osipenko) Changes V2 -> V3: - Add missed capsets including cross domain and drm (native context) (Dmitry Osipenko) v1: https://lore.kernel.org/lkml/20230915105918.3763061-1-ray.hu...@amd.com/ v2: https://lore.kernel.org/lkml/20231010032553.1138036-1-ray.hu...@amd.com/ include/uapi/linux/virtio_gpu.h | 4 1 file changed, 4 insertions(+) diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h index f556fde07b76..240911c8da31 100644 --- a/include/uapi/linux/virtio_gpu.h +++ b/include/uapi/linux/virtio_gpu.h @@ -309,6 +309,10 @@ struct virtio_gpu_cmd_submit { #define VIRTIO_GPU_CAPSET_VIRGL 1 #define VIRTIO_GPU_CAPSET_VIRGL2 2 +#define VIRTIO_GPU_CAPSET_GFXSTREAM 3 +#define VIRTIO_GPU_CAPSET_VENUS 4 +#define VIRTIO_GPU_CAPSET_CROSS_DOMAIN 5 +#define VIRTIO_GPU_CAPSET_DRM 6 /* VIRTIO_GPU_CMD_GET_CAPSET_INFO */ struct virtio_gpu_get_capset_info { -- 2.25.1
Re: [PATCH v1 1/3] mm/gup: Introduce pin_user_pages_fd() for pinning shmem/hugetlbfs file pages
On Tue, Oct 03, 2023 at 12:44:45AM -0700, Vivek Kasireddy wrote: > +/** > + * pin_user_pages_fd() - pin user pages associated with a file > + * @fd: the fd whose pages are to be pinned > + * @start: starting file offset > + * @nr_pages: number of pages from start to pin > + * @gup_flags: flags modifying pin behaviour > + * @pages: array that receives pointers to the pages pinned. > + * Should be at least nr_pages long. > + * > + * Attempt to pin (and migrate) pages associated with a file belonging to > + * either shmem or hugetlbfs. An error is returned if pages associated with > + * hugetlbfs files are not present in the page cache. However, shmem pages > + * are swapped in or allocated if they are not present in the page cache. > + * > + * Returns number of pages pinned. This would be equal to the number of > + * pages requested. > + * If nr_pages is 0 or negative, returns 0. If no pages were pinned, returns > + * -errno. > + */ > +long pin_user_pages_fd(int fd, pgoff_t start, unsigned long nr_pages, > +unsigned int gup_flags, struct page **pages) > +{ > + struct page *page; > + struct file *filep; > + unsigned int flags, i; > + long ret; > + > + if (nr_pages <= 0) > + return 0; > + if (!is_valid_gup_args(pages, NULL, _flags, FOLL_PIN)) > + return 0; > + > + if (start < 0) > + return -EINVAL; > + > + filep = fget(fd); > + if (!filep) > + return -EINVAL; I think the caller should pass in the file * In some cases we will need to hold a reference on it for a long time. > + if (!shmem_file(filep) && !is_file_hugepages(filep)) > + return -EINVAL; > + > + flags = memalloc_pin_save(); > + do { > + for (i = 0; i < nr_pages; i++) { > + if (shmem_mapping(filep->f_mapping)) { > + page = shmem_read_mapping_page(filep->f_mapping, > +start + i); > + if (IS_ERR(page)) { > + ret = PTR_ERR(page); > + goto err; > + } > + } else { > + page = find_get_page_flags(filep->f_mapping, > +start + i, > +FGP_ACCESSED); > + if (!page) { > + ret = -EINVAL; > + goto err; > + } I don't know these APIs at all, but I admit to being surprised we need the special case for shmem ? > + ret = try_grab_page(page, FOLL_PIN); > + if (unlikely(ret)) > + goto err; > + > + pages[i] = page; > + put_page(pages[i]); > + } > + > + ret = check_and_migrate_movable_pages(nr_pages, pages); > + } while (ret == -EAGAIN); It seems OK, but I do wish it was faster :) Maybe for another day. Jason
Re: [PATCH v1 0/2] [PATCH] hwmon: (pmbus/max31785) Add minimum delay between bus accesses
On Tue, Oct 10, 2023 at 11:31:56AM +0200, Wolfram Sang wrote: > Hi, > > thanks for this series! > > > Reference to Andrew's previous proposal: > > https://lore.kernel.org/all/20200914122811.3295678-1-and...@aj.id.au/ > > I do totally agree with Guenter's comment[1], though. This just affects > a few drivers and this patch is way too intrusive for the I2C core. The > later suggested prepare_device() callback[2] sounds better to me. I > still haven't fully understood why this all cannot be handled in the > driver's probe. Could someone give me a small summary about that? > Lots of PMBus devices have the same problem, we have always handled it in PMBus drivers by implementing local wait code, and your references point that out. What other summary are you looking for ? On a side note, if anyone plans to implement the prepare_device() callback, please make sure that it covers all requirements. It would be unfortunate if such a callback was implemented if that would still require per-driver code (besides the callback). Thanks, Guenter
[PATCH v7 10/20] drm/imagination: Add GPU ID parsing and firmware loading
Read the GPU ID register at probe time and select the correct features/quirks/enhancements. Use the GPU ID to form the firmware file name and load the firmware. The features/quirks/enhancements arrays are currently hardcoded in the driver for the supported GPUs. We are looking at moving this information to the firmware image. Changes since v5: - Add BRN 71242 to device info Changes since v4: - Retrieve device information from firmware header - Pull forward firmware header parsing from FW infrastructure patch - Use devm_add_action_or_reset to release firmware Changes since v3: - Use drm_dev_{enter,exit} Co-developed-by: Frank Binns Signed-off-by: Frank Binns Co-developed-by: Matt Coster Signed-off-by: Matt Coster Co-developed-by: Donald Robson Signed-off-by: Donald Robson Signed-off-by: Sarah Walker --- drivers/gpu/drm/imagination/Makefile | 2 + drivers/gpu/drm/imagination/pvr_device.c | 323 ++- drivers/gpu/drm/imagination/pvr_device.h | 220 drivers/gpu/drm/imagination/pvr_device_info.c | 254 + drivers/gpu/drm/imagination/pvr_device_info.h | 186 +++ drivers/gpu/drm/imagination/pvr_drv.c | 521 +- drivers/gpu/drm/imagination/pvr_drv.h | 107 drivers/gpu/drm/imagination/pvr_fw.c | 145 + drivers/gpu/drm/imagination/pvr_fw.h | 34 ++ drivers/gpu/drm/imagination/pvr_fw_info.h | 135 + 10 files changed, 1925 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/imagination/pvr_device_info.c create mode 100644 drivers/gpu/drm/imagination/pvr_device_info.h create mode 100644 drivers/gpu/drm/imagination/pvr_fw.c create mode 100644 drivers/gpu/drm/imagination/pvr_fw.h create mode 100644 drivers/gpu/drm/imagination/pvr_fw_info.h diff --git a/drivers/gpu/drm/imagination/Makefile b/drivers/gpu/drm/imagination/Makefile index b4aa190c9d4a..9e144ff2742b 100644 --- a/drivers/gpu/drm/imagination/Makefile +++ b/drivers/gpu/drm/imagination/Makefile @@ -5,6 +5,8 @@ subdir-ccflags-y := -I$(srctree)/$(src) powervr-y := \ pvr_device.o \ + pvr_device_info.o \ pvr_drv.o \ + pvr_fw.o obj-$(CONFIG_DRM_POWERVR) += powervr.o diff --git a/drivers/gpu/drm/imagination/pvr_device.c b/drivers/gpu/drm/imagination/pvr_device.c index cef3511c0c42..b1fae182c4f6 100644 --- a/drivers/gpu/drm/imagination/pvr_device.c +++ b/drivers/gpu/drm/imagination/pvr_device.c @@ -2,19 +2,31 @@ /* Copyright (c) 2023 Imagination Technologies Ltd. */ #include "pvr_device.h" +#include "pvr_device_info.h" + +#include "pvr_fw.h" +#include "pvr_rogue_cr_defs.h" #include +#include #include #include #include #include #include +#include #include +#include #include +#include #include #include #include +#include + +/* Major number for the supported version of the firmware. */ +#define PVR_FW_VERSION_MAJOR 1 /** * pvr_device_reg_init() - Initialize kernel access to a PowerVR device's @@ -100,6 +112,209 @@ static int pvr_device_clk_init(struct pvr_device *pvr_dev) return 0; } +/** + * pvr_build_firmware_filename() - Construct a PowerVR firmware filename + * @pvr_dev: Target PowerVR device. + * @base: First part of the filename. + * @major: Major version number. + * + * A PowerVR firmware filename consists of three parts separated by underscores + * (``'_'``) along with a '.fw' file suffix. The first part is the exact value + * of @base, the second part is the hardware version string derived from @pvr_fw + * and the final part is the firmware version number constructed from @major with + * a 'v' prefix, e.g. powervr/rogue_4.40.2.51_v1.fw. + * + * The returned string will have been slab allocated and must be freed with + * kfree(). + * + * Return: + * * The constructed filename on success, or + * * Any error returned by kasprintf(). + */ +static char * +pvr_build_firmware_filename(struct pvr_device *pvr_dev, const char *base, + u8 major) +{ + struct pvr_gpu_id *gpu_id = _dev->gpu_id; + + return kasprintf(GFP_KERNEL, "%s_%d.%d.%d.%d_v%d.fw", base, gpu_id->b, +gpu_id->v, gpu_id->n, gpu_id->c, major); +} + +static void +pvr_release_firmware(void *data) +{ + struct pvr_device *pvr_dev = data; + + release_firmware(pvr_dev->fw_dev.firmware); +} + +/** + * pvr_request_firmware() - Load firmware for a PowerVR device + * @pvr_dev: Target PowerVR device. + * + * See pvr_build_firmware_filename() for details on firmware file naming. + * + * Return: + * * 0 on success, + * * Any error returned by pvr_build_firmware_filename(), or + * * Any error returned by request_firmware(). + */ +static int +pvr_request_firmware(struct pvr_device *pvr_dev) +{ + struct drm_device *drm_dev = _dev->base; + char *filename; + const struct firmware *fw; + int err; + + filename = pvr_build_firmware_filename(pvr_dev, "powervr/rogue", +
[PATCH v7 17/20] drm/imagination: Implement job submission and scheduling
Implement job submission ioctl. Job scheduling is implemented using drm_sched. Jobs are submitted in a stream format. This is intended to allow the UAPI data format to be independent of the actual FWIF structures in use, which vary depending on the GPU in use. The stream formats are documented at: https://gitlab.freedesktop.org/mesa/mesa/-/blob/f8d2b42ae65c2f16f36a43e0ae39d288431e4263/src/imagination/csbgen/rogue_kmd_stream.xml This patch depends on: drm/sched: Convert drm scheduler to use a work queue rather than kthread: https://lore.kernel.org/dri-devel/20230404002211.3611376-2-matthew.br...@intel.com/ drm/sched: Move schedule policy to scheduler / entity: https://lore.kernel.org/dri-devel/20230404002211.3611376-3-matthew.br...@intel.com/ drm/sched: Add DRM_SCHED_POLICY_SINGLE_ENTITY scheduling policy: https://lore.kernel.org/dri-devel/20230404002211.3611376-4-matthew.br...@intel.com/ drm/sched: Start run wq before TDR in drm_sched_start: https://lore.kernel.org/dri-devel/20230404002211.3611376-6-matthew.br...@intel.com/ drm/sched: Submit job before starting TDR: https://lore.kernel.org/dri-devel/20230404002211.3611376-7-matthew.br...@intel.com/ drm/sched: Add helper to set TDR timeout: https://lore.kernel.org/dri-devel/20230404002211.3611376-8-matthew.br...@intel.com/ Changes since v6: - Fix fence handling in pvr_sync_signal_array_add() - Add handling for SUBMIT_JOB_FRAG_CMD_DISABLE_PIXELMERGE flag - Fix missing dma_resv locking in job submit path Changes since v5: - Fix leak in job creation error path Changes since v4: - Use a regular workqueue for job scheduling Changes since v3: - Support partial render jobs - Add job timeout handler - Split sync handling out of job code - Use drm_dev_{enter,exit} Changes since v2: - Use drm_sched for job scheduling Co-developed-by: Boris Brezillon Signed-off-by: Boris Brezillon Co-developed-by: Donald Robson Signed-off-by: Donald Robson Signed-off-by: Sarah Walker --- drivers/gpu/drm/imagination/Kconfig |1 + drivers/gpu/drm/imagination/Makefile |3 + drivers/gpu/drm/imagination/pvr_context.c | 125 +- drivers/gpu/drm/imagination/pvr_context.h | 44 + drivers/gpu/drm/imagination/pvr_device.c | 31 + drivers/gpu/drm/imagination/pvr_device.h | 21 + drivers/gpu/drm/imagination/pvr_drv.c | 40 +- drivers/gpu/drm/imagination/pvr_job.c | 777 + drivers/gpu/drm/imagination/pvr_job.h | 161 ++ drivers/gpu/drm/imagination/pvr_power.c | 28 + drivers/gpu/drm/imagination/pvr_queue.c | 1455 + drivers/gpu/drm/imagination/pvr_queue.h | 179 ++ drivers/gpu/drm/imagination/pvr_stream_defs.c | 226 +++ drivers/gpu/drm/imagination/pvr_sync.c| 289 drivers/gpu/drm/imagination/pvr_sync.h| 84 + 15 files changed, 3460 insertions(+), 4 deletions(-) create mode 100644 drivers/gpu/drm/imagination/pvr_job.c create mode 100644 drivers/gpu/drm/imagination/pvr_job.h create mode 100644 drivers/gpu/drm/imagination/pvr_queue.c create mode 100644 drivers/gpu/drm/imagination/pvr_queue.h create mode 100644 drivers/gpu/drm/imagination/pvr_sync.c create mode 100644 drivers/gpu/drm/imagination/pvr_sync.h diff --git a/drivers/gpu/drm/imagination/Kconfig b/drivers/gpu/drm/imagination/Kconfig index 2639fbf3ebac..084e72aa82eb 100644 --- a/drivers/gpu/drm/imagination/Kconfig +++ b/drivers/gpu/drm/imagination/Kconfig @@ -6,6 +6,7 @@ config DRM_POWERVR depends on ARM64 depends on DRM depends on PM + select DRM_EXEC select DRM_GEM_SHMEM_HELPER select DRM_SCHED select DRM_GPUVM diff --git a/drivers/gpu/drm/imagination/Makefile b/drivers/gpu/drm/imagination/Makefile index 0c8ab120f277..313af5312d7b 100644 --- a/drivers/gpu/drm/imagination/Makefile +++ b/drivers/gpu/drm/imagination/Makefile @@ -18,10 +18,13 @@ powervr-y := \ pvr_fw_trace.o \ pvr_gem.o \ pvr_hwrt.o \ + pvr_job.o \ pvr_mmu.o \ pvr_power.o \ + pvr_queue.o \ pvr_stream.o \ pvr_stream_defs.o \ + pvr_sync.o \ pvr_vm.o \ pvr_vm_mips.o diff --git a/drivers/gpu/drm/imagination/pvr_context.c b/drivers/gpu/drm/imagination/pvr_context.c index 7ade4d395d1d..42385eb15271 100644 --- a/drivers/gpu/drm/imagination/pvr_context.c +++ b/drivers/gpu/drm/imagination/pvr_context.c @@ -6,10 +6,12 @@ #include "pvr_device.h" #include "pvr_drv.h" #include "pvr_gem.h" +#include "pvr_job.h" #include "pvr_power.h" #include "pvr_rogue_fwif.h" #include "pvr_rogue_fwif_common.h" #include "pvr_rogue_fwif_resetframework.h" +#include "pvr_stream.h" #include "pvr_stream_defs.h" #include "pvr_vm.h" @@ -164,6 +166,116 @@ ctx_fw_data_init(void *cpu_ptr, void *priv) memcpy(cpu_ptr, ctx->data, ctx->data_size); } +/** + * pvr_context_destroy_queues() - Destroy all queues attached to a context. + * @ctx: Context to destroy queues
[PATCH v7 04/20] drm/imagination/uapi: Add PowerVR driver UAPI
Add the UAPI implementation for the PowerVR driver. Changes from v6 - Add padding to struct drm_pvr_dev_query_gpu_info - Improve BYPASS_CACHE flag documentation - Add SUBMIT_JOB_FRAG_CMD_DISABLE_PIXELMERGE flag Changes from v4: - Remove CREATE_ZEROED flag for BO creation (all buffers are now zeroed) Co-developed-by: Frank Binns Signed-off-by: Frank Binns Co-developed-by: Boris Brezillon Signed-off-by: Boris Brezillon Co-developed-by: Matt Coster Signed-off-by: Matt Coster Co-developed-by: Donald Robson Signed-off-by: Donald Robson Signed-off-by: Sarah Walker --- MAINTAINERS|1 + include/uapi/drm/pvr_drm.h | 1319 2 files changed, 1320 insertions(+) create mode 100644 include/uapi/drm/pvr_drm.h diff --git a/MAINTAINERS b/MAINTAINERS index eea8e618746a..cfdc7ec02972 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10233,6 +10233,7 @@ M: Frank Binns M: Donald Robson S: Supported F: Documentation/devicetree/bindings/gpu/img,powervr.yaml +F: include/uapi/drm/pvr_drm.h IMON SOUNDGRAPH USB IR RECEIVER M: Sean Young diff --git a/include/uapi/drm/pvr_drm.h b/include/uapi/drm/pvr_drm.h new file mode 100644 index ..ca021dae7de7 --- /dev/null +++ b/include/uapi/drm/pvr_drm.h @@ -0,0 +1,1319 @@ +/* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) OR MIT */ +/* Copyright (c) 2023 Imagination Technologies Ltd. */ + +#ifndef PVR_DRM_UAPI_H +#define PVR_DRM_UAPI_H + +#include "drm.h" + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +/** + * DOC: PowerVR UAPI + * + * The PowerVR IOCTL argument structs have a few limitations in place, in + * addition to the standard kernel restrictions: + * + * - All members must be type-aligned. + * - The overall struct must be padded to 64-bit alignment. + * - Explicit padding is almost always required. This takes the form of + *``_padding_[x]`` members of sufficient size to pad to the next power-of-two + *alignment, where [x] is the offset into the struct in hexadecimal. Arrays + *are never used for alignment. Padding fields must be zeroed; this is + *always checked. + * - Unions may only appear as the last member of a struct. + * - Individual union members may grow in the future. The space between the + *end of a union member and the end of its containing union is considered + *"implicit padding" and must be zeroed. This is always checked. + * + * In addition to the IOCTL argument structs, the PowerVR UAPI makes use of + * DEV_QUERY argument structs. These are used to fetch information about the + * device and runtime. These structs are subject to the same rules set out + * above. + */ + +/** + * struct drm_pvr_obj_array - Container used to pass arrays of objects + * + * It is not unusual to have to extend objects to pass new parameters, and the DRM + * ioctl infrastructure is supporting that by padding ioctl arguments with zeros + * when the data passed by userspace is smaller than the struct defined in the + * drm_ioctl_desc, thus keeping things backward compatible. This type is just + * applying the same concepts to indirect objects passed through arrays referenced + * from the main ioctl arguments structure: the stride basically defines the size + * of the object passed by userspace, which allows the kernel driver to pad with + * zeros when it's smaller than the size of the object it expects. + * + * Use ``DRM_PVR_OBJ_ARRAY()`` to fill object array fields, unless you + * have a very good reason not to. + */ +struct drm_pvr_obj_array { + /** @stride: Stride of object struct. Used for versioning. */ + __u32 stride; + + /** @count: Number of objects in the array. */ + __u32 count; + + /** @array: User pointer to an array of objects. */ + __u64 array; +}; + +/** + * DRM_PVR_OBJ_ARRAY() - Helper macro for filling drm_pvr_obj_array. + * @cnt: Number of elements pointed to py @ptr. + * @ptr: Pointer to start of a C array. + * + * Return: Literal of type drm_pvr_obj_array. + */ +#define DRM_PVR_OBJ_ARRAY(cnt, ptr) \ + { .stride = sizeof((ptr)[0]), .count = (cnt), .array = (__u64)(uintptr_t)(ptr) } + +/** + * DOC: PowerVR IOCTL interface + */ + +/** + * PVR_IOCTL() - Build a PowerVR IOCTL number + * @_ioctl: An incrementing id for this IOCTL. Added to %DRM_COMMAND_BASE. + * @_mode: Must be one of %DRM_IOR, %DRM_IOW or %DRM_IOWR. + * @_data: The type of the args struct passed by this IOCTL. + * + * The struct referred to by @_data must have a ``drm_pvr_ioctl_`` prefix and an + * ``_args suffix``. They are therefore omitted from @_data. + * + * This should only be used to build the constants described below; it should + * never be used to call an IOCTL directly. + * + * Return: An IOCTL number to be passed to ioctl() from userspace. + */ +#define PVR_IOCTL(_ioctl, _mode, _data) \ + _mode(DRM_COMMAND_BASE + (_ioctl), struct drm_pvr_ioctl_##_data##_args) +
[PATCH v7 15/20] drm/imagination: Implement free list and HWRT create and destroy ioctls
Implement ioctls to create and destroy free lists and HWRT datasets. Free lists are used for GPU-side memory allocation during geometry processing. HWRT datasets are the FW-side structures representing render targets. Changes since v6: - Fix out-of-bounds shift in get_cr_multisamplectl_val() Changes since v4: - Remove use of drm_gem_shmem_get_pages() Changes since v3: - Support free list grow requests from FW - Use drm_dev_{enter,exit} Co-developed-by: Boris Brezillon Signed-off-by: Boris Brezillon Co-developed-by: Donald Robson Signed-off-by: Donald Robson Signed-off-by: Sarah Walker --- drivers/gpu/drm/imagination/Makefile| 2 + drivers/gpu/drm/imagination/pvr_ccb.c | 10 + drivers/gpu/drm/imagination/pvr_device.h| 24 + drivers/gpu/drm/imagination/pvr_drv.c | 112 +++- drivers/gpu/drm/imagination/pvr_free_list.c | 625 drivers/gpu/drm/imagination/pvr_free_list.h | 195 ++ drivers/gpu/drm/imagination/pvr_hwrt.c | 549 + drivers/gpu/drm/imagination/pvr_hwrt.h | 165 ++ 8 files changed, 1678 insertions(+), 4 deletions(-) create mode 100644 drivers/gpu/drm/imagination/pvr_free_list.c create mode 100644 drivers/gpu/drm/imagination/pvr_free_list.h create mode 100644 drivers/gpu/drm/imagination/pvr_hwrt.c create mode 100644 drivers/gpu/drm/imagination/pvr_hwrt.h diff --git a/drivers/gpu/drm/imagination/Makefile b/drivers/gpu/drm/imagination/Makefile index 0a6532d30c00..fca2ee2efbac 100644 --- a/drivers/gpu/drm/imagination/Makefile +++ b/drivers/gpu/drm/imagination/Makefile @@ -8,12 +8,14 @@ powervr-y := \ pvr_device.o \ pvr_device_info.o \ pvr_drv.o \ + pvr_free_list.o \ pvr_fw.o \ pvr_fw_meta.o \ pvr_fw_mips.o \ pvr_fw_startstop.o \ pvr_fw_trace.o \ pvr_gem.o \ + pvr_hwrt.o \ pvr_mmu.o \ pvr_power.o \ pvr_vm.o \ diff --git a/drivers/gpu/drm/imagination/pvr_ccb.c b/drivers/gpu/drm/imagination/pvr_ccb.c index 64b58b8989ca..f0ea71f72776 100644 --- a/drivers/gpu/drm/imagination/pvr_ccb.c +++ b/drivers/gpu/drm/imagination/pvr_ccb.c @@ -4,6 +4,7 @@ #include "pvr_ccb.h" #include "pvr_device.h" #include "pvr_drv.h" +#include "pvr_free_list.h" #include "pvr_fw.h" #include "pvr_gem.h" #include "pvr_power.h" @@ -139,6 +140,15 @@ process_fwccb_command(struct pvr_device *pvr_dev, struct rogue_fwif_fwccb_cmd *c pvr_power_reset(pvr_dev, false); break; + case ROGUE_FWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION: + pvr_free_list_process_reconstruct_req(pvr_dev, + >cmd_data.cmd_freelists_reconstruction); + break; + + case ROGUE_FWIF_FWCCB_CMD_FREELIST_GROW: + pvr_free_list_process_grow_req(pvr_dev, >cmd_data.cmd_free_list_gs); + break; + default: drm_info(from_pvr_device(pvr_dev), "Received unknown FWCCB command %x\n", cmd->cmd_type); diff --git a/drivers/gpu/drm/imagination/pvr_device.h b/drivers/gpu/drm/imagination/pvr_device.h index cbcfc5d4b845..84166266ace8 100644 --- a/drivers/gpu/drm/imagination/pvr_device.h +++ b/drivers/gpu/drm/imagination/pvr_device.h @@ -146,6 +146,14 @@ struct pvr_device { /** @fw_dev: Firmware related data. */ struct pvr_fw_device fw_dev; + /** +* @free_list_ids: Array of free lists belonging to this device. Array members +* are of type "struct pvr_free_list *". +* +* This array is used to allocate IDs used by the firmware. +*/ + struct xarray free_list_ids; + struct { /** @work: Work item for watchdog callback. */ struct delayed_work work; @@ -241,6 +249,22 @@ struct pvr_file { */ struct pvr_device *pvr_dev; + /** +* @free_list_handles: Array of free lists belonging to this file. Array +* members are of type "struct pvr_free_list *". +* +* This array is used to allocate handles returned to userspace. +*/ + struct xarray free_list_handles; + + /** +* @hwrt_handles: Array of HWRT datasets belonging to this file. Array +* members are of type "struct pvr_hwrt_dataset *". +* +* This array is used to allocate handles returned to userspace. +*/ + struct xarray hwrt_handles; + /** * @vm_ctx_handles: Array of VM contexts belonging to this file. Array * members are of type "struct pvr_vm_context *". diff --git a/drivers/gpu/drm/imagination/pvr_drv.c b/drivers/gpu/drm/imagination/pvr_drv.c index fb37d8e41d84..9a3f34fdced1 100644 --- a/drivers/gpu/drm/imagination/pvr_drv.c +++ b/drivers/gpu/drm/imagination/pvr_drv.c @@ -3,7 +3,9 @@ #include "pvr_device.h" #include "pvr_drv.h" +#include "pvr_free_list.h" #include "pvr_gem.h"
Re: [PATCH v3 11/16] platform/x86/amd/pmf: dump policy binary data
On 10/10/2023 6:38 PM, Ilpo Järvinen wrote: > On Tue, 10 Oct 2023, Shyam Sundar S K wrote: > >> Sometimes policy binary retrieved from the BIOS maybe incorrect that can >> end up in failing to enable the Smart PC solution feature. >> >> Use print_hex_dump_debug() to dump the policy binary in hex, so that we >> debug the issues related to the binary even before sending that to TA. >> >> Signed-off-by: Shyam Sundar S K >> --- >> drivers/platform/x86/amd/pmf/tee-if.c | 9 + >> 1 file changed, 9 insertions(+) >> >> diff --git a/drivers/platform/x86/amd/pmf/tee-if.c >> b/drivers/platform/x86/amd/pmf/tee-if.c >> index 994daf945795..e4386f503ad0 100644 >> --- a/drivers/platform/x86/amd/pmf/tee-if.c >> +++ b/drivers/platform/x86/amd/pmf/tee-if.c >> @@ -275,6 +275,12 @@ static int amd_pmf_start_policy_engine(struct >> amd_pmf_dev *dev) >> } >> >> #ifdef CONFIG_AMD_PMF_DEBUG >> +static void amd_pmf_hex_dump_pb(struct amd_pmf_dev *dev) >> +{ >> +print_hex_dump_debug("(pb): ", DUMP_PREFIX_OFFSET, 16, 1, >> dev->policy_buf, >> + dev->policy_sz, false); >> +} >> + > > You forgot to add the empty version of amd_pmf_hex_dump_pb function into > #else part (so the compile fails if CONFIG_AMD_PMF_DEBUG is not set). > It's there (see below). I have just grouped the functions that come under #ifdef CONFIG_AMD_PMF_DEBUG and #else so that's more readable. >> static ssize_t amd_pmf_get_pb_data(struct file *filp, const char __user >> *buf, >> size_t length, loff_t *pos) >> { >> @@ -289,6 +295,7 @@ static ssize_t amd_pmf_get_pb_data(struct file *filp, >> const char __user *buf, >> if (copy_from_user(dev->policy_buf, buf, dev->policy_sz)) >> return -EFAULT; >> >> +amd_pmf_hex_dump_pb(dev); >> ret = amd_pmf_start_policy_engine(dev); >> if (ret) >> return -EINVAL; >> @@ -327,6 +334,7 @@ static int amd_pmf_open_pb(struct amd_pmf_dev *dev, >> struct dentry *debugfs_root) >> } >> >> static void amd_pmf_remove_pb(struct amd_pmf_dev *dev) {} >> +static void amd_pmf_hex_dump_pb(struct amd_pmf_dev *dev) {} Here is the empty amd_pmf_hex_dump_pb(). Thanks, Shyam >> #endif >> >> static int amd_pmf_get_bios_buffer(struct amd_pmf_dev *dev) >> @@ -341,6 +349,7 @@ static int amd_pmf_get_bios_buffer(struct amd_pmf_dev >> *dev) >> >> memcpy(dev->policy_buf, dev->policy_base, dev->policy_sz); >> >> +amd_pmf_hex_dump_pb(dev); >> if (pb_side_load) >> amd_pmf_open_pb(dev, dev->dbgfs_dir); >> >> >
[PATCH v7 08/20] drm/imagination: Add firmware and MMU related headers
Changes since v5: - Split up header commit due to size Signed-off-by: Sarah Walker Acked-by: Maxime Ripard --- .../drm/imagination/pvr_rogue_heap_config.h | 113 ++ drivers/gpu/drm/imagination/pvr_rogue_meta.h | 356 ++ drivers/gpu/drm/imagination/pvr_rogue_mips.h | 335 .../drm/imagination/pvr_rogue_mips_check.h| 58 +++ .../gpu/drm/imagination/pvr_rogue_mmu_defs.h | 136 +++ 5 files changed, 998 insertions(+) create mode 100644 drivers/gpu/drm/imagination/pvr_rogue_heap_config.h create mode 100644 drivers/gpu/drm/imagination/pvr_rogue_meta.h create mode 100644 drivers/gpu/drm/imagination/pvr_rogue_mips.h create mode 100644 drivers/gpu/drm/imagination/pvr_rogue_mips_check.h create mode 100644 drivers/gpu/drm/imagination/pvr_rogue_mmu_defs.h diff --git a/drivers/gpu/drm/imagination/pvr_rogue_heap_config.h b/drivers/gpu/drm/imagination/pvr_rogue_heap_config.h new file mode 100644 index ..632221b88281 --- /dev/null +++ b/drivers/gpu/drm/imagination/pvr_rogue_heap_config.h @@ -0,0 +1,113 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +/* Copyright (c) 2023 Imagination Technologies Ltd. */ + +#ifndef PVR_ROGUE_HEAP_CONFIG_H +#define PVR_ROGUE_HEAP_CONFIG_H + +#include + +/* + * ROGUE Device Virtual Address Space Definitions + * + * This file defines the ROGUE virtual address heaps that are used in + * application memory contexts. It also shows where the Firmware memory heap + * fits into this, but the firmware heap is only ever created in the + * kernel driver and never exposed to userspace. + * + * ROGUE_PDSCODEDATA_HEAP_BASE and ROGUE_USCCODE_HEAP_BASE will be programmed, + * on a global basis, into ROGUE_CR_PDS_EXEC_BASE and ROGUE_CR_USC_CODE_BASE_* + * respectively. Therefore if client drivers use multiple configs they must + * still be consistent with their definitions for these heaps. + * + * Base addresses have to be a multiple of 4MiB. + * Heaps must not start at 0x00, as this is reserved for internal + * use within the driver. + * Range comments, those starting in column 0 below are a section heading of + * sorts and are above the heaps in that range. Often this is the reserved + * size of the heap within the range. + */ + +/* 0x00__ / + +/* 0x00__ - 0x00_0040_ */ +/* 0 MiB to 4 MiB, size of 4 MiB : RESERVED */ + +/* 0x00_0040_ - 0x7F_FFC0_ **/ +/* 4 MiB to 512 GiB, size of 512 GiB less 4 MiB : RESERVED **/ + +/* 0x80__ / + +/* 0x80__ - 0x9F__ **/ +/* 512 GiB to 640 GiB, size of 128 GiB : GENERAL_HEAP **/ +#define ROGUE_GENERAL_HEAP_BASE 0x80ull +#define ROGUE_GENERAL_HEAP_SIZE SZ_128G + +/* 0xA0__ - 0xAF__ */ +/* 640 GiB to 704 GiB, size of 64 GiB : FREE */ + +/* B0__ - 0xB7__ */ +/* 704 GiB to 736 GiB, size of 32 GiB : FREE */ + +/* 0xB8__ - 0xBF__ */ +/* 736 GiB to 768 GiB, size of 32 GiB : RESERVED */ + +/* 0xC0__ / + +/* 0xC0__ - 0xD9__ */ +/* 768 GiB to 872 GiB, size of 104 GiB : FREE */ + +/* 0xDA__ - 0xDA__ */ +/* 872 GiB to 876 GiB, size of 4 GiB : PDSCODEDATA_HEAP */ +#define ROGUE_PDSCODEDATA_HEAP_BASE 0xDAull +#define ROGUE_PDSCODEDATA_HEAP_SIZE SZ_4G + +/* 0xDB__ - 0xDB__ */ +/* 876 GiB to 880 GiB, size of 256 MiB (reserved 4GiB) : BRN **/ +/* + * The BRN63142 quirk workaround requires Region Header memory to be at the top + * of a 16GiB aligned range. This is so when masked with 0x03 the + * address will avoid aliasing PB addresses. Start at 879.75GiB. Size of 256MiB. + */ +#define ROGUE_RGNHDR_HEAP_BASE 0xDBF000ull +#define ROGUE_RGNHDR_HEAP_SIZE SZ_256M + +/* 0xDC__ - 0xDF__ */ +/* 880 GiB to 896 GiB, size of 16 GiB : FREE */ + +/* 0xE0__ - 0xE0__ */ +/* 896 GiB to 900 GiB, size of 4 GiB : USCCODE_HEAP */ +#define ROGUE_USCCODE_HEAP_BASE 0xE0ull +#define ROGUE_USCCODE_HEAP_SIZE SZ_4G + +/* 0xE1__ - 0xE1_BFFF_ */ +/* 900 GiB to 903 GiB, size of 3 GiB : RESERVED */ + +/* 0xE1_C000_000 - 0xE1__ */ +/* 903 GiB to 904 GiB, reserved 1 GiB, : FIRMWARE_HEAP */ +#define ROGUE_FW_HEAP_BASE 0xE1C000ull + +/* 0xE2__ - 0xE3__ */ +/* 904 GiB to 912 GiB, size of 8 GiB : FREE */ + +/* 0xE4__ - 0xE7__ */ +/* 912 GiB to 968 GiB, size of 16 GiB : TRANSFER_FRAG */ +#define ROGUE_TRANSFER_FRAG_HEAP_BASE 0xE4ull +#define ROGUE_TRANSFER_FRAG_HEAP_SIZE SZ_16G + +/* 0xE8__ - 0xF1__ */ +/* 928 GiB to 968 GiB, size of 40 GiB : RESERVED */ + +/* 0xF2__ - 0xF2_001F_ **/ +/* 968 GiB to 969 GiB, size of 2 MiB : VISTEST_HEAP */ +#define ROGUE_VISTEST_HEAP_BASE 0xF2ull +#define ROGUE_VISTEST_HEAP_SIZE SZ_2M + +/* 0xF2_4000_ -
[PATCH v7 14/20] drm/imagination: Implement MIPS firmware processor and MMU support
Add support for the MIPS firmware processor, used in the Series AXE GPU. The MIPS firmware processor uses a separate MMU to the rest of the GPU, so this patch adds support for that as well. Changes since v6: - Fix integer overflow in VM map error path Changes since v5: - Use alloc_page() when allocating MIPS pagetable Changes since v3: - Get regs resource (removed from GPU resources commit) Signed-off-by: Sarah Walker --- drivers/gpu/drm/imagination/Makefile | 4 +- drivers/gpu/drm/imagination/pvr_device.c | 5 +- drivers/gpu/drm/imagination/pvr_device.h | 3 + drivers/gpu/drm/imagination/pvr_fw.c | 2 + drivers/gpu/drm/imagination/pvr_fw_mips.c | 252 ++ drivers/gpu/drm/imagination/pvr_fw_mips.h | 48 + drivers/gpu/drm/imagination/pvr_vm_mips.c | 236 drivers/gpu/drm/imagination/pvr_vm_mips.h | 22 ++ 8 files changed, 570 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/imagination/pvr_fw_mips.c create mode 100644 drivers/gpu/drm/imagination/pvr_fw_mips.h create mode 100644 drivers/gpu/drm/imagination/pvr_vm_mips.c create mode 100644 drivers/gpu/drm/imagination/pvr_vm_mips.h diff --git a/drivers/gpu/drm/imagination/Makefile b/drivers/gpu/drm/imagination/Makefile index 5b02440841be..0a6532d30c00 100644 --- a/drivers/gpu/drm/imagination/Makefile +++ b/drivers/gpu/drm/imagination/Makefile @@ -10,11 +10,13 @@ powervr-y := \ pvr_drv.o \ pvr_fw.o \ pvr_fw_meta.o \ + pvr_fw_mips.o \ pvr_fw_startstop.o \ pvr_fw_trace.o \ pvr_gem.o \ pvr_mmu.o \ pvr_power.o \ - pvr_vm.o + pvr_vm.o \ + pvr_vm_mips.o obj-$(CONFIG_DRM_POWERVR) += powervr.o diff --git a/drivers/gpu/drm/imagination/pvr_device.c b/drivers/gpu/drm/imagination/pvr_device.c index 6055cf6054f7..aac5e62d6cbe 100644 --- a/drivers/gpu/drm/imagination/pvr_device.c +++ b/drivers/gpu/drm/imagination/pvr_device.c @@ -50,16 +50,19 @@ pvr_device_reg_init(struct pvr_device *pvr_dev) { struct drm_device *drm_dev = from_pvr_device(pvr_dev); struct platform_device *plat_dev = to_platform_device(drm_dev->dev); + struct resource *regs_resource; void __iomem *regs; + pvr_dev->regs_resource = NULL; pvr_dev->regs = NULL; - regs = devm_platform_ioremap_resource(plat_dev, 0); + regs = devm_platform_get_and_ioremap_resource(plat_dev, 0, _resource); if (IS_ERR(regs)) return dev_err_probe(drm_dev->dev, PTR_ERR(regs), "failed to ioremap gpu registers\n"); pvr_dev->regs = regs; + pvr_dev->regs_resource = regs_resource; return 0; } diff --git a/drivers/gpu/drm/imagination/pvr_device.h b/drivers/gpu/drm/imagination/pvr_device.h index b5de9574a116..cbcfc5d4b845 100644 --- a/drivers/gpu/drm/imagination/pvr_device.h +++ b/drivers/gpu/drm/imagination/pvr_device.h @@ -93,6 +93,9 @@ struct pvr_device { /** @fw_version: Firmware version detected at runtime. */ struct pvr_fw_version fw_version; + /** @regs_resource: Resource representing device control registers. */ + struct resource *regs_resource; + /** * @regs: Device control registers. * diff --git a/drivers/gpu/drm/imagination/pvr_fw.c b/drivers/gpu/drm/imagination/pvr_fw.c index 4ea663be4596..d3edcb74f29d 100644 --- a/drivers/gpu/drm/imagination/pvr_fw.c +++ b/drivers/gpu/drm/imagination/pvr_fw.c @@ -933,6 +933,8 @@ pvr_fw_init(struct pvr_device *pvr_dev) if (fw_dev->processor_type == PVR_FW_PROCESSOR_TYPE_META) fw_dev->defs = _fw_defs_meta; + else if (fw_dev->processor_type == PVR_FW_PROCESSOR_TYPE_MIPS) + fw_dev->defs = _fw_defs_mips; else return -EINVAL; diff --git a/drivers/gpu/drm/imagination/pvr_fw_mips.c b/drivers/gpu/drm/imagination/pvr_fw_mips.c new file mode 100644 index ..bf13b05d1248 --- /dev/null +++ b/drivers/gpu/drm/imagination/pvr_fw_mips.c @@ -0,0 +1,252 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* Copyright (c) 2023 Imagination Technologies Ltd. */ + +#include "pvr_device.h" +#include "pvr_fw.h" +#include "pvr_fw_mips.h" +#include "pvr_gem.h" +#include "pvr_rogue_mips.h" +#include "pvr_vm_mips.h" + +#include +#include +#include + +#define ROGUE_FW_HEAP_MIPS_BASE 0xC000 +#define ROGUE_FW_HEAP_MIPS_SHIFT 24 /* 16 MB */ +#define ROGUE_FW_HEAP_MIPS_RESERVED_SIZE SZ_1M + +/** + * process_elf_command_stream() - Process ELF firmware image and populate + *firmware sections + * @pvr_dev: Device pointer. + * @fw: Pointer to firmware image. + * @fw_code_ptr: Pointer to FW code section. + * @fw_data_ptr: Pointer to FW data section. + * @fw_core_code_ptr: Pointer to FW coremem code section. + * @fw_core_data_ptr: Pointer to FW coremem data section. + * + * Returns : + * * 0 on success, or + * * -EINVAL on any
[PATCH v7 05/20] drm/imagination: Add skeleton PowerVR driver
This adds the basic skeleton of the driver. The driver registers itself with DRM on probe. Ioctl handlers are currently implemented as stubs. Changes since v5: - Update compatible string & description to match marketing name - Checkpatch fixes in to/from_pvr_device/file macros Changes since v3: - Clarify supported GPU generations in driver description - Use drm_dev_unplug() when removing device - Change from_* and to_* functions to macros - Fix IS_PTR/PTR_ERR confusion in pvr_probe() - Remove err_out labels in favour of direct returning - Remove specific am62 compatible match string - Drop MODULE_FIRMWARE() Co-developed-by: Frank Binns Signed-off-by: Frank Binns Co-developed-by: Matt Coster Signed-off-by: Matt Coster Signed-off-by: Sarah Walker Reviewed-by: Maxime Ripard --- MAINTAINERS | 1 + drivers/gpu/drm/Kconfig | 2 + drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/imagination/Kconfig | 15 + drivers/gpu/drm/imagination/Makefile | 9 + drivers/gpu/drm/imagination/pvr_device.h | 153 +++ drivers/gpu/drm/imagination/pvr_drv.c| 509 +++ drivers/gpu/drm/imagination/pvr_drv.h| 22 + 8 files changed, 712 insertions(+) create mode 100644 drivers/gpu/drm/imagination/Kconfig create mode 100644 drivers/gpu/drm/imagination/Makefile create mode 100644 drivers/gpu/drm/imagination/pvr_device.h create mode 100644 drivers/gpu/drm/imagination/pvr_drv.c create mode 100644 drivers/gpu/drm/imagination/pvr_drv.h diff --git a/MAINTAINERS b/MAINTAINERS index cfdc7ec02972..6bcd86fb44ee 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10233,6 +10233,7 @@ M: Frank Binns M: Donald Robson S: Supported F: Documentation/devicetree/bindings/gpu/img,powervr.yaml +F: drivers/gpu/drm/imagination/ F: include/uapi/drm/pvr_drm.h IMON SOUNDGRAPH USB IR RECEIVER diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 48ca28a2e4ff..f42550d4ec68 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -394,6 +394,8 @@ source "drivers/gpu/drm/solomon/Kconfig" source "drivers/gpu/drm/sprd/Kconfig" +source "drivers/gpu/drm/imagination/Kconfig" + config DRM_HYPERV tristate "DRM Support for Hyper-V synthetic video device" depends on DRM && PCI && MMU && HYPERV diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 8e1bde059170..d236103e3361 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -198,3 +198,4 @@ obj-$(CONFIG_DRM_HYPERV) += hyperv/ obj-y += solomon/ obj-$(CONFIG_DRM_SPRD) += sprd/ obj-$(CONFIG_DRM_LOONGSON) += loongson/ +obj-$(CONFIG_DRM_POWERVR) += imagination/ diff --git a/drivers/gpu/drm/imagination/Kconfig b/drivers/gpu/drm/imagination/Kconfig new file mode 100644 index ..e9aaa5313485 --- /dev/null +++ b/drivers/gpu/drm/imagination/Kconfig @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0 OR MIT +# Copyright (c) 2023 Imagination Technologies Ltd. + +config DRM_POWERVR + tristate "Imagination Technologies PowerVR (Series 6 and later) & IMG Graphics" + depends on ARM64 + depends on DRM + select DRM_GEM_SHMEM_HELPER + select DRM_SCHED + select FW_LOADER + help + Choose this option if you have a system that has an Imagination + Technologies PowerVR (Series 6 or later) or IMG GPU. + + If "M" is selected, the module will be called powervr. diff --git a/drivers/gpu/drm/imagination/Makefile b/drivers/gpu/drm/imagination/Makefile new file mode 100644 index ..19b40c2d7356 --- /dev/null +++ b/drivers/gpu/drm/imagination/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 OR MIT +# Copyright (c) 2023 Imagination Technologies Ltd. + +subdir-ccflags-y := -I$(srctree)/$(src) + +powervr-y := \ + pvr_drv.o \ + +obj-$(CONFIG_DRM_POWERVR) += powervr.o diff --git a/drivers/gpu/drm/imagination/pvr_device.h b/drivers/gpu/drm/imagination/pvr_device.h new file mode 100644 index ..53b1cdb5a6a6 --- /dev/null +++ b/drivers/gpu/drm/imagination/pvr_device.h @@ -0,0 +1,153 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +/* Copyright (c) 2023 Imagination Technologies Ltd. */ + +#ifndef PVR_DEVICE_H +#define PVR_DEVICE_H + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/** + * struct pvr_device - powervr-specific wrapper for drm_device + */ +struct pvr_device { + /** +* @base: The underlying drm_device. +* +* Do not access this member directly, instead call +* from_pvr_device(). +*/ + struct drm_device base; +}; + +/** + * struct pvr_file - powervr-specific data to be assigned to + * drm_file.driver_priv + */ +struct pvr_file { + /** +* @file: A reference to the parent drm_file. +* +* Do not access this member directly, instead call
[PATCH v7 03/20] dt-bindings: gpu: Add Imagination Technologies PowerVR/IMG GPU
Add the device tree binding documentation for the IMG AXE GPU used in TI AM62 SoCs. Co-developed-by: Frank Binns Signed-off-by: Frank Binns Signed-off-by: Sarah Walker Reviewed-by: Maxime Ripard Reviewed-by: Linus Walleij Reviewed-by: Conor Dooley --- Changes since v6: - Remove unused gpu label from example - Updated maintainer Changes since v5: - Update compatible string & description to match marketing name - Remove unnecessary clock-names definition in ti,am62-gpu constraints - Document that GPU revision is discoverable Changes since v4: - Add clocks constraint for ti,am62-gpu - Remove excess address and size cells in example - Remove interrupt name and add maxItems - Make property order consistent between dts and bindings doc - Update example to match dts Changes since v3: - Remove oneOf in compatible property - Remove power-supply (not used on AM62) Changes since v2: - Add commit message description - Remove mt8173-gpu support (not currently supported) - Drop quotes from $id and $schema - Remove reg: minItems - Drop _clk suffixes from clock-names - Remove operating-points-v2 property and cooling-cells (not currently used) - Add additionalProperties: false - Remove stray blank line at the end of file .../devicetree/bindings/gpu/img,powervr.yaml | 73 +++ MAINTAINERS | 6 ++ 2 files changed, 79 insertions(+) create mode 100644 Documentation/devicetree/bindings/gpu/img,powervr.yaml diff --git a/Documentation/devicetree/bindings/gpu/img,powervr.yaml b/Documentation/devicetree/bindings/gpu/img,powervr.yaml new file mode 100644 index ..e81db87a1f46 --- /dev/null +++ b/Documentation/devicetree/bindings/gpu/img,powervr.yaml @@ -0,0 +1,73 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (c) 2023 Imagination Technologies Ltd. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/gpu/img,powervr.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Imagination Technologies PowerVR and IMG GPU + +maintainers: + - Donald Robson + +properties: + compatible: +items: + - enum: + - ti,am62-gpu + - const: img,img-axe # IMG AXE GPU model/revision is fully discoverable + + reg: +maxItems: 1 + + clocks: +minItems: 1 +maxItems: 3 + + clock-names: +items: + - const: core + - const: mem + - const: sys +minItems: 1 + + interrupts: +maxItems: 1 + + power-domains: +maxItems: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - interrupts + +additionalProperties: false + +allOf: + - if: + properties: +compatible: + contains: +const: ti,am62-gpu +then: + properties: +clocks: + maxItems: 1 + +examples: + - | +#include +#include +#include + +gpu@fd0 { +compatible = "ti,am62-gpu", "img,img-axe"; +reg = <0x0fd0 0x2>; +clocks = <_clks 187 0>; +clock-names = "core"; +interrupts = ; +power-domains = <_pds 187 TI_SCI_PD_EXCLUSIVE>; +}; diff --git a/MAINTAINERS b/MAINTAINERS index e05506ea8917..eea8e618746a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10228,6 +10228,12 @@ IMGTEC IR DECODER DRIVER S: Orphan F: drivers/media/rc/img-ir/ +IMGTEC POWERVR DRM DRIVER +M: Frank Binns +M: Donald Robson +S: Supported +F: Documentation/devicetree/bindings/gpu/img,powervr.yaml + IMON SOUNDGRAPH USB IR RECEIVER M: Sean Young L: linux-me...@vger.kernel.org -- 2.42.0
[PATCH v7 06/20] drm/imagination: Get GPU resources
Acquire clock and register resources, and enable/map as appropriate. Changes since v3: - Remove regulator resource (not used on supported platform) - Use devm helpers - Use devm_clk_get_optional() for optional clocks - Don't prepare clocks on resource acquisition - Drop pvr_device_clk_core_get_freq() helper - Drop pvr_device_reg_fini() - Drop NULLing of clocks in pvr_device_clk_init() - Use dev_err_probe() on clock acquisition failure - Remove PVR_CR_READ/WRITE helper macros - Improve documentation for GPU clocks - Remove regs resource (not used in this commit) Co-developed-by: Frank Binns Signed-off-by: Frank Binns Co-developed-by: Matt Coster Signed-off-by: Matt Coster Signed-off-by: Sarah Walker Reviewed-by: Maxime Ripard --- drivers/gpu/drm/imagination/Makefile | 1 + drivers/gpu/drm/imagination/pvr_device.c | 147 ++ drivers/gpu/drm/imagination/pvr_device.h | 152 +++ drivers/gpu/drm/imagination/pvr_drv.c| 18 ++- 4 files changed, 317 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/imagination/pvr_device.c diff --git a/drivers/gpu/drm/imagination/Makefile b/drivers/gpu/drm/imagination/Makefile index 19b40c2d7356..b4aa190c9d4a 100644 --- a/drivers/gpu/drm/imagination/Makefile +++ b/drivers/gpu/drm/imagination/Makefile @@ -4,6 +4,7 @@ subdir-ccflags-y := -I$(srctree)/$(src) powervr-y := \ + pvr_device.o \ pvr_drv.o \ obj-$(CONFIG_DRM_POWERVR) += powervr.o diff --git a/drivers/gpu/drm/imagination/pvr_device.c b/drivers/gpu/drm/imagination/pvr_device.c new file mode 100644 index ..cef3511c0c42 --- /dev/null +++ b/drivers/gpu/drm/imagination/pvr_device.c @@ -0,0 +1,147 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* Copyright (c) 2023 Imagination Technologies Ltd. */ + +#include "pvr_device.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * pvr_device_reg_init() - Initialize kernel access to a PowerVR device's + * control registers. + * @pvr_dev: Target PowerVR device. + * + * Sets struct pvr_device->regs. + * + * This method of mapping the device control registers into memory ensures that + * they are unmapped when the driver is detached (i.e. no explicit cleanup is + * required). + * + * Return: + * * 0 on success, or + * * Any error returned by devm_platform_ioremap_resource(). + */ +static int +pvr_device_reg_init(struct pvr_device *pvr_dev) +{ + struct drm_device *drm_dev = from_pvr_device(pvr_dev); + struct platform_device *plat_dev = to_platform_device(drm_dev->dev); + void __iomem *regs; + + pvr_dev->regs = NULL; + + regs = devm_platform_ioremap_resource(plat_dev, 0); + if (IS_ERR(regs)) + return dev_err_probe(drm_dev->dev, PTR_ERR(regs), +"failed to ioremap gpu registers\n"); + + pvr_dev->regs = regs; + + return 0; +} + +/** + * pvr_device_clk_init() - Initialize clocks required by a PowerVR device + * @pvr_dev: Target PowerVR device. + * + * Sets struct pvr_device->core_clk, struct pvr_device->sys_clk and + * struct pvr_device->mem_clk. + * + * Three clocks are required by the PowerVR device: core, sys and mem. On + * return, this function guarantees that the clocks are in one of the following + * states: + * + * * All successfully initialized, + * * Core errored, sys and mem uninitialized, + * * Core deinitialized, sys errored, mem uninitialized, or + * * Core and sys deinitialized, mem errored. + * + * Return: + * * 0 on success, + * * Any error returned by devm_clk_get(), or + * * Any error returned by devm_clk_get_optional(). + */ +static int pvr_device_clk_init(struct pvr_device *pvr_dev) +{ + struct drm_device *drm_dev = from_pvr_device(pvr_dev); + struct clk *core_clk; + struct clk *sys_clk; + struct clk *mem_clk; + + core_clk = devm_clk_get(drm_dev->dev, "core"); + if (IS_ERR(core_clk)) + return dev_err_probe(drm_dev->dev, PTR_ERR(core_clk), +"failed to get core clock\n"); + + sys_clk = devm_clk_get_optional(drm_dev->dev, "sys"); + if (IS_ERR(sys_clk)) + return dev_err_probe(drm_dev->dev, PTR_ERR(core_clk), +"failed to get sys clock\n"); + + mem_clk = devm_clk_get_optional(drm_dev->dev, "mem"); + if (IS_ERR(mem_clk)) + return dev_err_probe(drm_dev->dev, PTR_ERR(core_clk), +"failed to get mem clock\n"); + + pvr_dev->core_clk = core_clk; + pvr_dev->sys_clk = sys_clk; + pvr_dev->mem_clk = mem_clk; + + return 0; +} + +/** + * pvr_device_init() - Initialize a PowerVR device + * @pvr_dev: Target PowerVR device. + * + * If this function returns successfully, the device will have been fully + * initialized. Otherwise, any parts of the device initialized before
[PATCH v7 13/20] drm/imagination: Implement firmware infrastructure and META FW support
The infrastructure includes parsing of the firmware image, initialising FW-side structures, handling the kernel and firmware command ringbuffers and starting & stopping the firmware processor. This patch also adds the necessary support code for the META firmware processor. Changes since v6: - Add a minimum retry count to pvr_kccb_reserve_slot_sync() Changes since v5: - Add workaround for BRN 71242 - Attempt to recover GPU on MMU flush command failure Changes since v4: - Remove use of drm_gem_shmem_get_pages() - Remove interrupt resource name Changes since v3: - Hard reset FW processor on watchdog timeout - Switch to threaded IRQ - Rework FW object creation/initialisation to aid hard reset - Added MODULE_FIRMWARE() - Use drm_dev_{enter,exit} Signed-off-by: Sarah Walker --- drivers/gpu/drm/imagination/Makefile |4 + drivers/gpu/drm/imagination/pvr_ccb.c | 638 drivers/gpu/drm/imagination/pvr_ccb.h | 71 + drivers/gpu/drm/imagination/pvr_device.c | 103 ++ drivers/gpu/drm/imagination/pvr_device.h | 60 + drivers/gpu/drm/imagination/pvr_drv.c |1 + drivers/gpu/drm/imagination/pvr_fw.c | 1342 + drivers/gpu/drm/imagination/pvr_fw.h | 474 ++ drivers/gpu/drm/imagination/pvr_fw_meta.c | 554 +++ drivers/gpu/drm/imagination/pvr_fw_meta.h | 14 + .../gpu/drm/imagination/pvr_fw_startstop.c| 306 .../gpu/drm/imagination/pvr_fw_startstop.h| 13 + drivers/gpu/drm/imagination/pvr_fw_trace.c| 120 ++ drivers/gpu/drm/imagination/pvr_fw_trace.h| 78 + drivers/gpu/drm/imagination/pvr_gem.h |7 + drivers/gpu/drm/imagination/pvr_mmu.c | 67 +- drivers/gpu/drm/imagination/pvr_power.c | 166 +- drivers/gpu/drm/imagination/pvr_power.h |2 + drivers/gpu/drm/imagination/pvr_vm.c | 26 +- 19 files changed, 4023 insertions(+), 23 deletions(-) create mode 100644 drivers/gpu/drm/imagination/pvr_ccb.c create mode 100644 drivers/gpu/drm/imagination/pvr_ccb.h create mode 100644 drivers/gpu/drm/imagination/pvr_fw_meta.c create mode 100644 drivers/gpu/drm/imagination/pvr_fw_meta.h create mode 100644 drivers/gpu/drm/imagination/pvr_fw_startstop.c create mode 100644 drivers/gpu/drm/imagination/pvr_fw_startstop.h create mode 100644 drivers/gpu/drm/imagination/pvr_fw_trace.c create mode 100644 drivers/gpu/drm/imagination/pvr_fw_trace.h diff --git a/drivers/gpu/drm/imagination/Makefile b/drivers/gpu/drm/imagination/Makefile index 235e2d329e29..5b02440841be 100644 --- a/drivers/gpu/drm/imagination/Makefile +++ b/drivers/gpu/drm/imagination/Makefile @@ -4,10 +4,14 @@ subdir-ccflags-y := -I$(srctree)/$(src) powervr-y := \ + pvr_ccb.o \ pvr_device.o \ pvr_device_info.o \ pvr_drv.o \ pvr_fw.o \ + pvr_fw_meta.o \ + pvr_fw_startstop.o \ + pvr_fw_trace.o \ pvr_gem.o \ pvr_mmu.o \ pvr_power.o \ diff --git a/drivers/gpu/drm/imagination/pvr_ccb.c b/drivers/gpu/drm/imagination/pvr_ccb.c new file mode 100644 index ..64b58b8989ca --- /dev/null +++ b/drivers/gpu/drm/imagination/pvr_ccb.c @@ -0,0 +1,638 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* Copyright (c) 2023 Imagination Technologies Ltd. */ + +#include "pvr_ccb.h" +#include "pvr_device.h" +#include "pvr_drv.h" +#include "pvr_fw.h" +#include "pvr_gem.h" +#include "pvr_power.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#define RESERVE_SLOT_TIMEOUT (1 * HZ) /* 1s */ +#define RESERVE_SLOT_MIN_RETRIES 10 + +static void +ccb_ctrl_init(void *cpu_ptr, void *priv) +{ + struct rogue_fwif_ccb_ctl *ctrl = cpu_ptr; + struct pvr_ccb *pvr_ccb = priv; + + ctrl->write_offset = 0; + ctrl->read_offset = 0; + ctrl->wrap_mask = pvr_ccb->num_cmds - 1; + ctrl->cmd_size = pvr_ccb->cmd_size; +} + +/** + * pvr_ccb_init() - Initialise a CCB + * @pvr_dev: Device pointer. + * @pvr_ccb: Pointer to CCB structure to initialise. + * @num_cmds_log2: Log2 of number of commands in this CCB. + * @cmd_size: Command size for this CCB. + * + * Return: + * * Zero on success, or + * * Any error code returned by pvr_fw_object_create_and_map(). + */ +static int +pvr_ccb_init(struct pvr_device *pvr_dev, struct pvr_ccb *pvr_ccb, +u32 num_cmds_log2, size_t cmd_size) +{ + u32 num_cmds = 1 << num_cmds_log2; + u32 ccb_size = num_cmds * cmd_size; + int err; + + pvr_ccb->num_cmds = num_cmds; + pvr_ccb->cmd_size = cmd_size; + + err = drmm_mutex_init(from_pvr_device(pvr_dev), _ccb->lock); + if (err) + return err; + + /* +* Map CCB and control structure as uncached, so we don't have to flush +* CPU cache repeatedly when polling for space. +*/ + pvr_ccb->ctrl = pvr_fw_object_create_and_map(pvr_dev, sizeof(*pvr_ccb->ctrl), +
[PATCH v7 12/20] drm/imagination: Implement power management
Add power management to the driver, using runtime pm. The power off sequence depends on firmware commands which are not implemented in this patch. Changes since v5: - Use RUNTIME_PM_OPS() to declare PM callbacks - Add Kconfig dependency on CONFIG_PM Changes since v4: - Suspend runtime PM before unplugging device on rmmod Changes since v3: - Don't power device when calling pvr_device_gpu_fini() - Documentation for pvr_dev->lost has been improved - pvr_power_init() renamed to pvr_watchdog_init() - Use drm_dev_{enter,exit} Changes since v2: - Use runtime PM - Implement watchdog Signed-off-by: Sarah Walker Reviewed-by: Maxime Ripard --- drivers/gpu/drm/imagination/Kconfig | 1 + drivers/gpu/drm/imagination/Makefile | 1 + drivers/gpu/drm/imagination/pvr_device.c | 23 +- drivers/gpu/drm/imagination/pvr_device.h | 22 ++ drivers/gpu/drm/imagination/pvr_drv.c| 20 +- drivers/gpu/drm/imagination/pvr_mmu.c| 6 +- drivers/gpu/drm/imagination/pvr_power.c | 271 +++ drivers/gpu/drm/imagination/pvr_power.h | 39 8 files changed, 378 insertions(+), 5 deletions(-) create mode 100644 drivers/gpu/drm/imagination/pvr_power.c create mode 100644 drivers/gpu/drm/imagination/pvr_power.h diff --git a/drivers/gpu/drm/imagination/Kconfig b/drivers/gpu/drm/imagination/Kconfig index 3e167d5470b4..2639fbf3ebac 100644 --- a/drivers/gpu/drm/imagination/Kconfig +++ b/drivers/gpu/drm/imagination/Kconfig @@ -5,6 +5,7 @@ config DRM_POWERVR tristate "Imagination Technologies PowerVR (Series 6 and later) & IMG Graphics" depends on ARM64 depends on DRM + depends on PM select DRM_GEM_SHMEM_HELPER select DRM_SCHED select DRM_GPUVM diff --git a/drivers/gpu/drm/imagination/Makefile b/drivers/gpu/drm/imagination/Makefile index 8fcabc1bea36..235e2d329e29 100644 --- a/drivers/gpu/drm/imagination/Makefile +++ b/drivers/gpu/drm/imagination/Makefile @@ -10,6 +10,7 @@ powervr-y := \ pvr_fw.o \ pvr_gem.o \ pvr_mmu.o \ + pvr_power.o \ pvr_vm.o obj-$(CONFIG_DRM_POWERVR) += powervr.o diff --git a/drivers/gpu/drm/imagination/pvr_device.c b/drivers/gpu/drm/imagination/pvr_device.c index f71e400ea24e..51ff10522d23 100644 --- a/drivers/gpu/drm/imagination/pvr_device.c +++ b/drivers/gpu/drm/imagination/pvr_device.c @@ -5,6 +5,7 @@ #include "pvr_device_info.h" #include "pvr_fw.h" +#include "pvr_power.h" #include "pvr_rogue_cr_defs.h" #include "pvr_vm.h" @@ -361,6 +362,8 @@ pvr_device_gpu_fini(struct pvr_device *pvr_dev) int pvr_device_init(struct pvr_device *pvr_dev) { + struct drm_device *drm_dev = from_pvr_device(pvr_dev); + struct device *dev = drm_dev->dev; int err; /* Enable and initialize clocks required for the device to operate. */ @@ -368,13 +371,29 @@ pvr_device_init(struct pvr_device *pvr_dev) if (err) return err; + /* Explicitly power the GPU so we can access control registers before the FW is booted. */ + err = pm_runtime_resume_and_get(dev); + if (err) + return err; + /* Map the control registers into memory. */ err = pvr_device_reg_init(pvr_dev); if (err) - return err; + goto err_pm_runtime_put; /* Perform GPU-specific initialization steps. */ - return pvr_device_gpu_init(pvr_dev); + err = pvr_device_gpu_init(pvr_dev); + if (err) + goto err_pm_runtime_put; + + pm_runtime_put(dev); + + return 0; + +err_pm_runtime_put: + pm_runtime_put_sync_suspend(dev); + + return err; } /** diff --git a/drivers/gpu/drm/imagination/pvr_device.h b/drivers/gpu/drm/imagination/pvr_device.h index 350e894a2939..f7eb14942195 100644 --- a/drivers/gpu/drm/imagination/pvr_device.h +++ b/drivers/gpu/drm/imagination/pvr_device.h @@ -135,6 +135,28 @@ struct pvr_device { /** @fw_dev: Firmware related data. */ struct pvr_fw_device fw_dev; + + struct { + /** @work: Work item for watchdog callback. */ + struct delayed_work work; + + /** @old_kccb_cmds_executed: KCCB command execution count at last watchdog poll. */ + u32 old_kccb_cmds_executed; + + /** @kccb_stall_count: Number of watchdog polls KCCB has been stalled for. */ + u32 kccb_stall_count; + } watchdog; + + /** +* @lost: %true if the device has been lost. +* +* This variable is set if the device has become irretrievably unavailable, e.g. if the +* firmware processor has stopped responding and can not be revived via a hard reset. +*/ + bool lost; + + /** @sched_wq: Workqueue for schedulers. */ + struct workqueue_struct *sched_wq; }; /** diff --git a/drivers/gpu/drm/imagination/pvr_drv.c b/drivers/gpu/drm/imagination/pvr_drv.c index 4b0c52118735..cfd4cea5a69c
[PATCH v7 18/20] drm/imagination: Add firmware trace header
Changes since v5: - Split up header commit due to size Signed-off-by: Sarah Walker --- .../gpu/drm/imagination/pvr_rogue_fwif_sf.h | 1648 + 1 file changed, 1648 insertions(+) create mode 100644 drivers/gpu/drm/imagination/pvr_rogue_fwif_sf.h diff --git a/drivers/gpu/drm/imagination/pvr_rogue_fwif_sf.h b/drivers/gpu/drm/imagination/pvr_rogue_fwif_sf.h new file mode 100644 index ..0fcc500fab21 --- /dev/null +++ b/drivers/gpu/drm/imagination/pvr_rogue_fwif_sf.h @@ -0,0 +1,1648 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +/* Copyright (c) 2023 Imagination Technologies Ltd. */ + +#ifndef PVR_ROGUE_FWIF_SF_H +#define PVR_ROGUE_FWIF_SF_H + +/* + ** + * *DO*NOT* rearrange or delete lines in rogue_fw_log_sfgroups or stid_fmts + * WILL BREAK fw tracing message compatibility with previous + * fw versions. Only add new ones, if so required. + ** + */ + +/* Available log groups. */ +enum rogue_fw_log_sfgroups { + ROGUE_FW_GROUP_NULL, + ROGUE_FW_GROUP_MAIN, + ROGUE_FW_GROUP_CLEANUP, + ROGUE_FW_GROUP_CSW, + ROGUE_FW_GROUP_PM, + ROGUE_FW_GROUP_RTD, + ROGUE_FW_GROUP_SPM, + ROGUE_FW_GROUP_MTS, + ROGUE_FW_GROUP_BIF, + ROGUE_FW_GROUP_MISC, + ROGUE_FW_GROUP_POW, + ROGUE_FW_GROUP_HWR, + ROGUE_FW_GROUP_HWP, + ROGUE_FW_GROUP_RPM, + ROGUE_FW_GROUP_DMA, + ROGUE_FW_GROUP_DBG, +}; + +#define PVR_SF_STRING_MAX_SIZE 256U + +/* pair of string format id and string formats */ +struct rogue_fw_stid_fmt { + u32 id; + char name[PVR_SF_STRING_MAX_SIZE]; +}; + +/* + * The symbolic names found in the table above are assigned an u32 value of + * the following format: + * 31 30 28 27 20 19 1615 12 110 bits + * - --- + * 0-11: id number + *12-15: group id number + *16-19: number of parameters + *20-27: unused + *28-30: active: identify SF packet, otherwise regular int32 + * 31: reserved for signed/unsigned compatibility + * + * The following macro assigns those values to the enum generated SF ids list. + */ +#define ROGUE_FW_LOG_IDMARKER (0x7000U) +#define ROGUE_FW_LOG_CREATESFID(a, b, e) ((u32)(a) | ((u32)(b) << 12) | ((u32)(e) << 16) | \ + ROGUE_FW_LOG_IDMARKER) + +#define ROGUE_FW_LOG_IDMASK (0xFFF0) +#define ROGUE_FW_LOG_VALIDID(I) (((I) & ROGUE_FW_LOG_IDMASK) == ROGUE_FW_LOG_IDMARKER) + +/* Return the group id that the given (enum generated) id belongs to */ +#define ROGUE_FW_SF_GID(x) (((u32)(x) >> 12) & 0xfU) +/* Returns how many arguments the SF(string format) for the given (enum generated) id requires */ +#define ROGUE_FW_SF_PARAMNUM(x) (((u32)(x) >> 16) & 0xfU) + +/* pair of string format id and string formats */ +struct rogue_km_stid_fmt { + u32 id; + const char *name; +}; + +static const struct rogue_km_stid_fmt stid_fmts[] = { + { ROGUE_FW_LOG_CREATESFID(0, ROGUE_FW_GROUP_NULL, 0), + "You should not use this string" }, + + { ROGUE_FW_LOG_CREATESFID(1, ROGUE_FW_GROUP_MAIN, 6), + "Kick 3D: FWCtx 0x%08.8x @ %d, RTD 0x%08x. Partial render:%d, CSW resume:%d, prio:%d" }, + { ROGUE_FW_LOG_CREATESFID(2, ROGUE_FW_GROUP_MAIN, 2), + "3D finished, HWRTData0State=%x, HWRTData1State=%x" }, + { ROGUE_FW_LOG_CREATESFID(3, ROGUE_FW_GROUP_MAIN, 4), + "Kick 3D TQ: FWCtx 0x%08.8x @ %d, CSW resume:%d, prio: %d" }, + { ROGUE_FW_LOG_CREATESFID(4, ROGUE_FW_GROUP_MAIN, 0), + "3D Transfer finished" }, + { ROGUE_FW_LOG_CREATESFID(5, ROGUE_FW_GROUP_MAIN, 3), + "Kick Compute: FWCtx 0x%08.8x @ %d, prio: %d" }, + { ROGUE_FW_LOG_CREATESFID(6, ROGUE_FW_GROUP_MAIN, 0), + "Compute finished" }, + { ROGUE_FW_LOG_CREATESFID(7, ROGUE_FW_GROUP_MAIN, 7), + "Kick TA: FWCtx 0x%08.8x @ %d, RTD 0x%08x. First kick:%d, Last kick:%d, CSW resume:%d, prio:%d" }, + { ROGUE_FW_LOG_CREATESFID(8, ROGUE_FW_GROUP_MAIN, 0), + "TA finished" }, + { ROGUE_FW_LOG_CREATESFID(9, ROGUE_FW_GROUP_MAIN, 0), + "Restart TA after partial render" }, + { ROGUE_FW_LOG_CREATESFID(10, ROGUE_FW_GROUP_MAIN, 0), + "Resume TA without partial render" }, + { ROGUE_FW_LOG_CREATESFID(11, ROGUE_FW_GROUP_MAIN, 2), + "Out of memory! Context 0x%08x, HWRTData 0x%x" }, + { ROGUE_FW_LOG_CREATESFID(12, ROGUE_FW_GROUP_MAIN, 3), + "Kick TLA: FWCtx 0x%08.8x @ %d, prio:%d" }, + { ROGUE_FW_LOG_CREATESFID(13, ROGUE_FW_GROUP_MAIN, 0), + "TLA finished" }, + { ROGUE_FW_LOG_CREATESFID(14, ROGUE_FW_GROUP_MAIN, 3), + "cCCB Woff update = %d, DM = %d, FWCtx = 0x%08.8x" }, + { ROGUE_FW_LOG_CREATESFID(16, ROGUE_FW_GROUP_MAIN,
[PATCH v7 20/20] drm/imagination: Add driver documentation
Add documentation for the UAPI. Changes since v5: - Remove obsolete VM documentation Co-developed-by: Matt Coster Signed-off-by: Matt Coster Co-developed-by: Donald Robson Signed-off-by: Donald Robson Signed-off-by: Sarah Walker Reviewed-by: Maxime Ripard --- Documentation/gpu/drivers.rst | 2 + Documentation/gpu/imagination/index.rst | 13 ++ Documentation/gpu/imagination/uapi.rst | 174 MAINTAINERS | 1 + 4 files changed, 190 insertions(+) create mode 100644 Documentation/gpu/imagination/index.rst create mode 100644 Documentation/gpu/imagination/uapi.rst diff --git a/Documentation/gpu/drivers.rst b/Documentation/gpu/drivers.rst index 3a52f48215a3..5487deb218a3 100644 --- a/Documentation/gpu/drivers.rst +++ b/Documentation/gpu/drivers.rst @@ -3,9 +3,11 @@ GPU Driver Documentation .. toctree:: + :maxdepth: 3 amdgpu/index i915 + imagination/index mcde meson pl111 diff --git a/Documentation/gpu/imagination/index.rst b/Documentation/gpu/imagination/index.rst new file mode 100644 index ..dc9579e758c3 --- /dev/null +++ b/Documentation/gpu/imagination/index.rst @@ -0,0 +1,13 @@ +=== +drm/imagination PowerVR Graphics Driver +=== + +.. kernel-doc:: drivers/gpu/drm/imagination/pvr_drv.c + :doc: PowerVR Graphics Driver + +Contents + +.. toctree:: + :maxdepth: 2 + + uapi diff --git a/Documentation/gpu/imagination/uapi.rst b/Documentation/gpu/imagination/uapi.rst new file mode 100644 index ..2227ea7e6222 --- /dev/null +++ b/Documentation/gpu/imagination/uapi.rst @@ -0,0 +1,174 @@ + +UAPI + +The sources associated with this section can be found in ``pvr_drm.h``. + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :doc: PowerVR UAPI + +OBJECT ARRAYS += +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: drm_pvr_obj_array + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: DRM_PVR_OBJ_ARRAY + +IOCTLS +== +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :doc: PowerVR IOCTL interface + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: PVR_IOCTL + +DEV_QUERY +- +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :doc: PowerVR IOCTL DEV_QUERY interface + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: drm_pvr_dev_query + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: drm_pvr_ioctl_dev_query_args + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: drm_pvr_dev_query_gpu_info + drm_pvr_dev_query_runtime_info + drm_pvr_dev_query_hwrt_info + drm_pvr_dev_query_quirks + drm_pvr_dev_query_enhancements + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: drm_pvr_heap_id + drm_pvr_heap + drm_pvr_dev_query_heap_info + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :doc: Flags for DRM_PVR_DEV_QUERY_HEAP_INFO_GET. + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: drm_pvr_static_data_area_usage + drm_pvr_static_data_area + drm_pvr_dev_query_static_data_areas + +CREATE_BO +- +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :doc: PowerVR IOCTL CREATE_BO interface + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: drm_pvr_ioctl_create_bo_args + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :doc: Flags for CREATE_BO + +GET_BO_MMAP_OFFSET +-- +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :doc: PowerVR IOCTL GET_BO_MMAP_OFFSET interface + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: drm_pvr_ioctl_get_bo_mmap_offset_args + +CREATE_VM_CONTEXT and DESTROY_VM_CONTEXT + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :doc: PowerVR IOCTL CREATE_VM_CONTEXT and DESTROY_VM_CONTEXT interfaces + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: drm_pvr_ioctl_create_vm_context_args + drm_pvr_ioctl_destroy_vm_context_args + +VM_MAP and VM_UNMAP +--- +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :doc: PowerVR IOCTL VM_MAP and VM_UNMAP interfaces + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: drm_pvr_ioctl_vm_map_args + drm_pvr_ioctl_vm_unmap_args + +CREATE_CONTEXT and DESTROY_CONTEXT +-- +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :doc: PowerVR IOCTL CREATE_CONTEXT and DESTROY_CONTEXT interfaces + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: drm_pvr_ioctl_create_context_args + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: drm_pvr_ctx_priority + drm_pvr_ctx_type + drm_pvr_static_render_context_state + drm_pvr_static_render_context_state_format +
[PATCH v7 16/20] drm/imagination: Implement context creation/destruction ioctls
Implement ioctls for the creation and destruction of contexts. Contexts are used for job submission and each is associated with a particular job type. Changes since v5: - Fix context release in final error path in pvr_context_create() Changes since v3: - Use drm_dev_{enter,exit} Co-developed-by: Boris Brezillon Signed-off-by: Boris Brezillon Signed-off-by: Sarah Walker --- drivers/gpu/drm/imagination/Makefile | 4 + drivers/gpu/drm/imagination/pvr_cccb.c| 267 ++ drivers/gpu/drm/imagination/pvr_cccb.h| 109 ++ drivers/gpu/drm/imagination/pvr_context.c | 341 ++ drivers/gpu/drm/imagination/pvr_context.h | 161 + drivers/gpu/drm/imagination/pvr_device.h | 21 ++ drivers/gpu/drm/imagination/pvr_drv.c | 29 +- drivers/gpu/drm/imagination/pvr_stream.c | 285 +++ drivers/gpu/drm/imagination/pvr_stream.h | 75 drivers/gpu/drm/imagination/pvr_stream_defs.c | 125 +++ drivers/gpu/drm/imagination/pvr_stream_defs.h | 16 + 11 files changed, 1431 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/imagination/pvr_cccb.c create mode 100644 drivers/gpu/drm/imagination/pvr_cccb.h create mode 100644 drivers/gpu/drm/imagination/pvr_context.c create mode 100644 drivers/gpu/drm/imagination/pvr_context.h create mode 100644 drivers/gpu/drm/imagination/pvr_stream.c create mode 100644 drivers/gpu/drm/imagination/pvr_stream.h create mode 100644 drivers/gpu/drm/imagination/pvr_stream_defs.c create mode 100644 drivers/gpu/drm/imagination/pvr_stream_defs.h diff --git a/drivers/gpu/drm/imagination/Makefile b/drivers/gpu/drm/imagination/Makefile index fca2ee2efbac..0c8ab120f277 100644 --- a/drivers/gpu/drm/imagination/Makefile +++ b/drivers/gpu/drm/imagination/Makefile @@ -5,6 +5,8 @@ subdir-ccflags-y := -I$(srctree)/$(src) powervr-y := \ pvr_ccb.o \ + pvr_cccb.o \ + pvr_context.o \ pvr_device.o \ pvr_device_info.o \ pvr_drv.o \ @@ -18,6 +20,8 @@ powervr-y := \ pvr_hwrt.o \ pvr_mmu.o \ pvr_power.o \ + pvr_stream.o \ + pvr_stream_defs.o \ pvr_vm.o \ pvr_vm_mips.o diff --git a/drivers/gpu/drm/imagination/pvr_cccb.c b/drivers/gpu/drm/imagination/pvr_cccb.c new file mode 100644 index ..8dfc157c3c10 --- /dev/null +++ b/drivers/gpu/drm/imagination/pvr_cccb.c @@ -0,0 +1,267 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* Copyright (c) 2023 Imagination Technologies Ltd. */ + +#include "pvr_ccb.h" +#include "pvr_cccb.h" +#include "pvr_device.h" +#include "pvr_gem.h" +#include "pvr_hwrt.h" + +#include +#include +#include +#include +#include + +static __always_inline u32 +get_ccb_space(u32 w_off, u32 r_off, u32 ccb_size) +{ + return (((r_off) - (w_off)) + ((ccb_size) - 1)) & ((ccb_size) - 1); +} + +static void +cccb_ctrl_init(void *cpu_ptr, void *priv) +{ + struct rogue_fwif_cccb_ctl *ctrl = cpu_ptr; + struct pvr_cccb *pvr_cccb = priv; + + WRITE_ONCE(ctrl->write_offset, 0); + WRITE_ONCE(ctrl->read_offset, 0); + WRITE_ONCE(ctrl->dep_offset, 0); + WRITE_ONCE(ctrl->wrap_mask, pvr_cccb->wrap_mask); +} + +/** + * pvr_cccb_init() - Initialise a Client CCB + * @pvr_dev: Device pointer. + * @pvr_cccb: Pointer to Client CCB structure to initialise. + * @size_log2: Log2 size of Client CCB in bytes. + * @name: Name of owner of Client CCB. Used for fence context. + * + * Return: + * * Zero on success, or + * * Any error code returned by pvr_fw_object_create_and_map(). + */ +int +pvr_cccb_init(struct pvr_device *pvr_dev, struct pvr_cccb *pvr_cccb, + u32 size_log2, const char *name) +{ + size_t size = 1 << size_log2; + int err; + + pvr_cccb->size = size; + pvr_cccb->write_offset = 0; + pvr_cccb->wrap_mask = size - 1; + + /* +* Map CCCB and control structure as uncached, so we don't have to flush +* CPU cache repeatedly when polling for space. +*/ + pvr_cccb->ctrl = pvr_fw_object_create_and_map(pvr_dev, sizeof(*pvr_cccb->ctrl), + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, + cccb_ctrl_init, pvr_cccb, + _cccb->ctrl_obj); + if (IS_ERR(pvr_cccb->ctrl)) + return PTR_ERR(pvr_cccb->ctrl); + + pvr_cccb->cccb = pvr_fw_object_create_and_map(pvr_dev, size, + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, + NULL, NULL, _cccb->cccb_obj); + if (IS_ERR(pvr_cccb->cccb)) { + err = PTR_ERR(pvr_cccb->cccb); + goto err_free_ctrl; + } + + pvr_fw_object_get_fw_addr(pvr_cccb->ctrl_obj, _cccb->ctrl_fw_addr); + pvr_fw_object_get_fw_addr(pvr_cccb->cccb_obj, _cccb->cccb_fw_addr); + +
[PATCH v7 19/20] drm/imagination: Add firmware trace to debugfs
Firmware trace is exposed at /sys/debug/dri//pvr_fw/trace_0. Trace is enabled via the group mask at /sys/debug/dri//pvr_params/fw_trace_mask. Changes since v3: - Use drm_dev_{enter,exit} Co-developed-by: Matt Coster Signed-off-by: Matt Coster Signed-off-by: Sarah Walker --- drivers/gpu/drm/imagination/Makefile | 4 + drivers/gpu/drm/imagination/pvr_debugfs.c | 53 +++ drivers/gpu/drm/imagination/pvr_debugfs.h | 29 ++ drivers/gpu/drm/imagination/pvr_device.c | 9 + drivers/gpu/drm/imagination/pvr_device.h | 10 + drivers/gpu/drm/imagination/pvr_drv.c | 4 + drivers/gpu/drm/imagination/pvr_fw_trace.c | 395 + drivers/gpu/drm/imagination/pvr_params.c | 147 drivers/gpu/drm/imagination/pvr_params.h | 72 9 files changed, 723 insertions(+) create mode 100644 drivers/gpu/drm/imagination/pvr_debugfs.c create mode 100644 drivers/gpu/drm/imagination/pvr_debugfs.h create mode 100644 drivers/gpu/drm/imagination/pvr_params.c create mode 100644 drivers/gpu/drm/imagination/pvr_params.h diff --git a/drivers/gpu/drm/imagination/Makefile b/drivers/gpu/drm/imagination/Makefile index 313af5312d7b..1db003cf39ee 100644 --- a/drivers/gpu/drm/imagination/Makefile +++ b/drivers/gpu/drm/imagination/Makefile @@ -20,6 +20,7 @@ powervr-y := \ pvr_hwrt.o \ pvr_job.o \ pvr_mmu.o \ + pvr_params.o \ pvr_power.o \ pvr_queue.o \ pvr_stream.o \ @@ -28,4 +29,7 @@ powervr-y := \ pvr_vm.o \ pvr_vm_mips.o +powervr-$(CONFIG_DEBUG_FS) += \ + pvr_debugfs.o + obj-$(CONFIG_DRM_POWERVR) += powervr.o diff --git a/drivers/gpu/drm/imagination/pvr_debugfs.c b/drivers/gpu/drm/imagination/pvr_debugfs.c new file mode 100644 index ..fa0d7c89773c --- /dev/null +++ b/drivers/gpu/drm/imagination/pvr_debugfs.c @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* Copyright (c) 2023 Imagination Technologies Ltd. */ + +#include "pvr_debugfs.h" + +#include "pvr_device.h" +#include "pvr_fw_trace.h" +#include "pvr_params.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +static const struct pvr_debugfs_entry pvr_debugfs_entries[] = { + {"pvr_params", pvr_params_debugfs_init}, + {"pvr_fw", pvr_fw_trace_debugfs_init}, +}; + +void +pvr_debugfs_init(struct drm_minor *minor) +{ + struct drm_device *drm_dev = minor->dev; + struct pvr_device *pvr_dev = to_pvr_device(drm_dev); + struct dentry *root = minor->debugfs_root; + size_t i; + + for (i = 0; i < ARRAY_SIZE(pvr_debugfs_entries); ++i) { + const struct pvr_debugfs_entry *entry = _debugfs_entries[i]; + struct dentry *dir; + + dir = debugfs_create_dir(entry->name, root); + if (IS_ERR(dir)) { + drm_warn(drm_dev, +"failed to create debugfs dir '%s' (err=%d)", +entry->name, (int)PTR_ERR(dir)); + continue; + } + + entry->init(pvr_dev, dir); + } +} + +/* + * Since all entries are created under _minor->debugfs_root, there's no + * need for a pvr_debugfs_fini() as DRM will clean up everything under its root + * automatically. + */ diff --git a/drivers/gpu/drm/imagination/pvr_debugfs.h b/drivers/gpu/drm/imagination/pvr_debugfs.h new file mode 100644 index ..7b7ff384053e --- /dev/null +++ b/drivers/gpu/drm/imagination/pvr_debugfs.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +/* Copyright (c) 2023 Imagination Technologies Ltd. */ + +#ifndef PVR_DEBUGFS_H +#define PVR_DEBUGFS_H + +/* Forward declaration from . */ +struct drm_minor; + +#if defined(CONFIG_DEBUG_FS) +/* Forward declaration from "pvr_device.h". */ +struct pvr_device; + +/* Forward declaration from . */ +struct dentry; + +struct pvr_debugfs_entry { + const char *name; + void (*init)(struct pvr_device *pvr_dev, struct dentry *dir); +}; + +void pvr_debugfs_init(struct drm_minor *minor); +#else /* defined(CONFIG_DEBUG_FS) */ +#include + +static __always_inline void pvr_debugfs_init(struct drm_minor *minor) {} +#endif /* defined(CONFIG_DEBUG_FS) */ + +#endif /* PVR_DEBUGFS_H */ diff --git a/drivers/gpu/drm/imagination/pvr_device.c b/drivers/gpu/drm/imagination/pvr_device.c index e22a62ba21a4..53c9db71e882 100644 --- a/drivers/gpu/drm/imagination/pvr_device.c +++ b/drivers/gpu/drm/imagination/pvr_device.c @@ -5,6 +5,7 @@ #include "pvr_device_info.h" #include "pvr_fw.h" +#include "pvr_params.h" #include "pvr_power.h" #include "pvr_queue.h" #include "pvr_rogue_cr_defs.h" @@ -495,6 +496,14 @@ pvr_device_init(struct pvr_device *pvr_dev) struct device *dev = drm_dev->dev; int err; + /* +* Setup device parameters. We do this first in case other steps +* depend on them. +*/ + err =
[PATCH v7 00/20] Imagination Technologies PowerVR DRM driver
This patch series adds the initial DRM driver for Imagination Technologies PowerVR GPUs, starting with those based on our Rogue architecture. It's worth pointing out that this is a new driver, written from the ground up, rather than a refactored version of our existing downstream driver (pvrsrvkm). This new DRM driver supports: - GEM shmem allocations - dma-buf / PRIME - Per-context userspace managed virtual address space - DRM sync objects (binary and timeline) - Power management suspend / resume - GPU job submission (geometry, fragment, compute, transfer) - META firmware processor - MIPS firmware processor - GPU hang detection and recovery Currently our main focus is on the AXE-1-16M GPU. Testing so far has been done using a TI SK-AM62 board (AXE-1-16M GPU). Firmware for the AXE-1-16M can be found here: https://gitlab.freedesktop.org/frankbinns/linux-firmware/-/tree/powervr A Vulkan driver that works with our downstream kernel driver has already been merged into Mesa [1][2]. Support for this new DRM driver is being maintained in a merge request [3], with the branch located here: https://gitlab.freedesktop.org/frankbinns/mesa/-/tree/powervr-winsys Job stream formats are documented at: https://gitlab.freedesktop.org/mesa/mesa/-/blob/f8d2b42ae65c2f16f36a43e0ae39d288431e4263/src/imagination/csbgen/rogue_kmd_stream.xml The Vulkan driver is progressing towards Vulkan 1.0. The current combination of this kernel driver with the Mesa Vulkan driver (powervr-mesa-next branch) successfully completes Vulkan CTS 1.3.4.1 in our local runs. The driver is expected to pass the Khronos Conformance Process once the submission is made. The code in this patch series, along with the needed dts changes can be found here: https://gitlab.freedesktop.org/sarah-walker-imgtec/powervr/-/tree/dev/v7_dts The full development history can be found here: https://gitlab.freedesktop.org/frankbinns/powervr/-/tree/powervr-next This patch series has dependencies on a number of patches not yet merged. They are listed below : drm/sched: Convert drm scheduler to use a work queue rather than kthread: https://lore.kernel.org/dri-devel/20230404002211.3611376-2-matthew.br...@intel.com/ drm/sched: Move schedule policy to scheduler / entity: https://lore.kernel.org/dri-devel/20230404002211.3611376-3-matthew.br...@intel.com/ drm/sched: Add DRM_SCHED_POLICY_SINGLE_ENTITY scheduling policy: https://lore.kernel.org/dri-devel/20230404002211.3611376-4-matthew.br...@intel.com/ drm/sched: Start run wq before TDR in drm_sched_start: https://lore.kernel.org/dri-devel/20230404002211.3611376-6-matthew.br...@intel.com/ drm/sched: Submit job before starting TDR: https://lore.kernel.org/dri-devel/20230404002211.3611376-7-matthew.br...@intel.com/ drm/sched: Add helper to set TDR timeout: https://lore.kernel.org/dri-devel/20230404002211.3611376-8-matthew.br...@intel.com/ [1] https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15243 [2] https://gitlab.freedesktop.org/mesa/mesa/-/tree/main/src/imagination/vulkan [3] https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15507 High level summary of changes: v7: * Fix fence handling in pvr_sync_signal_array_add() * Add a minimum retry count to pvr_kccb_reserve_slot_sync() * Don't initialise kernel_vm_ctx when using MIPS firmware processor * Remove unused gpu label from dt bindings example * Improve UAPI BYPASS_CACHE documentation * Add DRM_PVR_SUBMIT_JOB_FRAG_CMD_DISABLE_PIXELMERGE flag to UAPI * Rename gpuva_manager usage to gpuvm * Sync GEM objects to device on creation * Fix out-of-bounds shift bug * Fix integer overflow in MIPS MMU map error path * Add missing commit messages v6: * Fix a number of error paths * Attempt to recover GPU on MMU flush command failure * Defer freeing/releasing page table backing pages until after TLB flush * Add memory barriers and use WRITE_ONCE() when writing to page tables * Add Kconfig dependency on CONFIG_PM * Fix a few issues with GPU VA manager usage * Split up header commit due to size * Update compatible string and driver description to match marketing name * Use alloc_page() to allocate MIPS pagetable * Remove obsolete documentation v5: * Retrieve GPU device information from firmware image header * Address issues with DT binding and example DTS * Update VM code for upstream GPU VA manager * BOs are always zeroed on allocation * Update copyright v4: * Implemented hang recovery via firmware hard reset * Add support for partial render jobs * Move to a threaded IRQ * Remove unnecessary read/write and clock helpers * Remove device tree elements not relevant to AXE-1-16M * Clean up resource acquisition * Remove unused DT binding attributes v3: * Use drm_sched for scheduling * Use GPU VA manager * Use runtime PM * Use drm_gem_shmem * GPU watchdog and device loss handling * DT binding changes: remove unused attributes, add additionProperties:false v2: * Redesigned and simplified UAPI based on RFC feedback from XDC 2022 * Support for transfer
[PATCH v7 01/20] sizes.h: Add entries between SZ_32G and SZ_64T
From: Matt Coster sizes.h has a gap in defines between SZ_32G and SZ_64T. Add the missing defines so they can be used in drivers. Signed-off-by: Matt Coster Signed-off-by: Sarah Walker Reviewed-by: Linus Walleij --- include/linux/sizes.h | 9 + 1 file changed, 9 insertions(+) diff --git a/include/linux/sizes.h b/include/linux/sizes.h index 84aa448d8bb3..c3a00b967d18 100644 --- a/include/linux/sizes.h +++ b/include/linux/sizes.h @@ -47,8 +47,17 @@ #define SZ_8G _AC(0x2, ULL) #define SZ_16G _AC(0x4, ULL) #define SZ_32G _AC(0x8, ULL) +#define SZ_64G _AC(0x10, ULL) +#define SZ_128G_AC(0x20, ULL) +#define SZ_256G_AC(0x40, ULL) +#define SZ_512G_AC(0x80, ULL) #define SZ_1T _AC(0x100, ULL) +#define SZ_2T _AC(0x200, ULL) +#define SZ_4T _AC(0x400, ULL) +#define SZ_8T _AC(0x800, ULL) +#define SZ_16T _AC(0x1000, ULL) +#define SZ_32T _AC(0x2000, ULL) #define SZ_64T _AC(0x4000, ULL) #endif /* __LINUX_SIZES_H__ */ -- 2.42.0
[PATCH v7 02/20] drm/gpuvm: Helper to get range of unmap from a remap op.
From: Donald Robson Determining the start and range of the unmap stage of a remap op is a common piece of code currently implemented by multiple drivers. Add a helper for this. Changes since v6: - Remove use of __always_inline Signed-off-by: Donald Robson Signed-off-by: Sarah Walker --- include/drm/drm_gpuvm.h | 27 +++ 1 file changed, 27 insertions(+) diff --git a/include/drm/drm_gpuvm.h b/include/drm/drm_gpuvm.h index c7ed6bf441d4..932e942da921 100644 --- a/include/drm/drm_gpuvm.h +++ b/include/drm/drm_gpuvm.h @@ -702,4 +702,31 @@ void drm_gpuva_remap(struct drm_gpuva *prev, void drm_gpuva_unmap(struct drm_gpuva_op_unmap *op); +/** + * drm_gpuva_op_remap_get_unmap_range() - Helper to get the start and range of + * the unmap stage of a remap op. + * @op: Remap op. + * @start_addr: Output pointer for the start of the required unmap. + * @range: Output pointer for the length of the required unmap. + * + * These parameters can then be used by the caller to unmap memory pages that + * are no longer required. + */ +static inline void +drm_gpuva_op_remap_get_unmap_range(const struct drm_gpuva_op_remap *op, + u64 *start_addr, u64 *range) +{ + const u64 va_start = op->prev ? +op->prev->va.addr + op->prev->va.range : +op->unmap->va->va.addr; + const u64 va_end = op->next ? + op->next->va.addr : + op->unmap->va->va.addr + op->unmap->va->va.range; + + if (start_addr) + *start_addr = va_start; + if (range) + *range = va_end - va_start; +} + #endif /* __DRM_GPUVM_H__ */ -- 2.42.0
Re: [PATCH v4 2/4] drm/panic: Add a drm panic handler
On 10/10/2023 15:05, Thomas Zimmermann wrote: Hi Am 10.10.23 um 11:33 schrieb Maxime Ripard: [...] We also have discussions about kexec/kdump support. Here we'd need to retrieve the scanout address, forward it to the kexec kernel and put simpledrm onto that framebuffer until the regular driver takes over. Generically speaking, there's strictly no guarantee that the current scanout buffer is accessible by the CPU. It's not even a driver issue, it's a workload issue, so it will affect 100% of the times some users, and some 0% of the time. And I'd be OK with that. It's all best effort anyway. An interface like get_scanout_buffer will be helpful for this use case. So it makes sense to use it for the panic handler as well. It won't be helpful because the vast majority of the ARM drivers (and thus the vast majority of the KMS drivers) won't be able to implement it properly and reliably. The barrier for firmware-based drivers is low: a pre-configured display and mmap'able framebuffer memory. And it's assumed that a callback for kexec would attempt to configure hardware accordingly. If a system really cannot provide this, so be it. run the atomic_update() on it, and return this commit's framebuffer ? That way each driver have a better control on what the panic handler will do. It can even call directly its internal functions, to avoid the locks of the drm generic functions, and make sure it will only change the format and base address. That's a bit more work for each driver, but should be more reliable I think. I don't think that better control there is a good idea, it's a path that won't get tested much so we'd be better off not allowing drivers to deviate too much from the "ideal" design. What I had in mind is something like: - Add a panic hook in drm_mode_config_funcs, with a drm_atomic_helper_panic helper; - Provide an atomic_panic hook or something in drm_plane_helper_funcs; - If they are set, we register the drm_panic handler; - The handler will call drm_mode_config_funcs.panic, which will take its prepared state, fill the framebuffer it allocated with the penguin and backtrace, call drm_plane_helper_funcs.atomic_panic(). - The driver now updates the format and fb address. - Halt and catch fire Does that make sense? Please see my other replies. I find this fragile, and unnecessary for cases where there already is a working scanout buffer in place. And please see my other replies. Depending on a working scanout buffer in place being accessible by the CPU is incredibly limiting. Ignoring it when I'm pointing that out won't get us to a solution acceptable for everyone. It's something a driver could implement internally to provide a scanout buffer if none has been set up already. Some drivers need extra resources when setting up a plane. VC4 for example need for every plane to allocate multiple internal SRAM buffers. Just allocating an extra framebuffer won't cut it. This is tied to the state so far, so I guess we would need to allocate a new state. Oh, and if we have several drivers that need to allocate that extra framebuffer and state, we could make it part of the core or turn it into a helper? I mentioned that even the simple drivers hold locks during the atomic commit. Some of the drivers use vmap/vunmap, which might make problems as well. It's used in the context of damage handling, which also makes no sense here. So the regular atomic helpers most likely won't work. It sounds to me as if you're essentially asking for something like a flush or sync operation. Stepping back from get_scanout_buffer for a moment and adopting your proposal from above, I can see something like this working: - the driver provides a panic callback in struct drm_driver - DRM registers a panic handler to invokes the callback - the panic callback has a scanout buffer from somewhere (currently active, prepared, from firmware, plain memory, etc) - we provide a helper that fills the scanout buffer with information - the driver then updates the hardware from/with the scanout buffer; details depend on the hardware The final step is like a flush or commit operation. To give some examples: The simple drivers of this patchset probably don't have to do anything. Drivers with command/packet queues could attempt to send the necessary commands to the device. Yes that was the second question in the cover letter. Some drivers probably want a flush_scanout_buffer() to send the framebuffer to the hardware. That callback can be in struct drm_driver as well. -- Jocelyn Best regards Thomas Maxime
Re: [PATCH v4 2/4] drm/panic: Add a drm panic handler
On 10/10/2023 14:59, Daniel Vetter wrote: On Tue, Oct 10, 2023 at 02:15:47PM +0200, Maxime Ripard wrote: On Tue, Oct 10, 2023 at 01:29:52PM +0200, Noralf Trønnes wrote: On 10/10/23 11:25, Maxime Ripard wrote: On Tue, Oct 10, 2023 at 10:55:09AM +0200, Thomas Zimmermann wrote: So if I understand correctly, drm_panic would pre-allocate a plane/commit, and use that when a panic occurs ? And have it checked already, yes. We would only wait for a panic to happen to pull the trigger on the commit. I have two concern about this approach: - How much memory would be allocated for this ? a whole framebuffer can be big for just this use case. As I outlined in my email at [1], there are a number of different scenarios. The question of atomic state and commits is entirely separate from the DRM panic handler. We should not throw them together. Whatever is necessary is get a scanout buffer, should happen on the driver side of get_scanout_buffer, not on the drm_panic side. [1] https://lore.kernel.org/dri-devel/39bd4c35-8a61-42ee-8675-ccea4f5d4...@suse.de/T/#m22f116e9438e00a5f0a9dc43987d4153424f8be1 I'dd expect a whole framebuffer for the current configuration/resolution. It would be typically 4MB for a full-HD system which isn't a lot really and I guess we can always add an option to disable the mechanism if needed. - I find it risky to completely reconfigure the hardware in a panic handler. I would expect to only change the format and base address of the framebuffer. I guess it can fail, but it doesn't seem that different to the async plane update we already have and works well. The one thing I don't understand is: Why should we use atomic commits in the first place? It doesn't make sense for firmware-based drivers. Because this is generic infrastructure that is valuable for any drivers and not only firmware-based drivers? In some drivers, even the simple ast, we hold locks during the regular commit. Trying to run the panic commit concurrently will likely give a deadlock. You're in the middle of a panic. Don't take any locks and you won't deadlock. In the end it's a per-driver decision, but in most cases, the driver can easily switch to a default mode with some ad-hoc code. When was the last time a per-driver decision has been a good thing? I'm sorry, but the get_scanout_buffer approach buffer won't work for any driver out there. I'm fine with discussing alternatives if you don't like the ones I suggested, but they must allow the panic handler infrastructure to work with any driver we have, not just 4. Why can't we use the model[1] suggested by Daniel using a draw_pixel callback giving drivers full control on how they can put a pixel on the display? I share kind of the same general ideas/conclusions: "qthe idea is that all the fb selection and lookup is handled in shared code (and with proper locking, but only for atomic drivers)." 2016 is a bit old though and multiple developments happened since (secure playback is a thing now, framebuffer compression too), so I still think that their expectation that the framebuffer is accessible to / writable by the CPU no longer holds true. I think largely it should still be ok, because the idea behind the draw_xy callback was that the driver could take care of anything special, like - tiling - clearing compression bits so that just writing the raw pixels works (if your compression format allows for that) - handling any differences in how the pixels need to be written, like cache flushing, mmio_write vs normal memory, amd also has peek/poke registers to be able to write even into unmappable memory What would probably be a good idea is to do an s/void */uinptr_t/ over my interface proposal, or maybe an even more opaque cookie since really the only thing you can do is get the void * that ->panic_vmap returns and pass it into ->panic_draw_xy. I thought (but I didn't dig through details) that the panic fb struct is essentially meant to serve this purpose in the current series? Yes, in this series there is a struct drm_scanout_buffer, that the driver has to provide when a panic occurs: struct drm_scanout_buffer { const struct drm_format_info *format; struct iosys_map map; unsigned int pitch; unsigned int width; unsigned int height; }; That works well for CPU accessible, linear format. It should be possible to support YUV, or simple tiling with that, but for the more complex case, I proposed to add a draw_pixel() callback. This will even work for the AMD debug interface. In the linear CPU accessible buffer case, we can provide a helper for that, maybe we can do helpers for other common cases as well. Yeah, their idea of a panic_draw would work great for that. Adding to that we would need a panic_setup/enter and panic_teardown/exit callback. What for? So panic teardown would be for testing in CI, to make it non-destructive and clean up anything panic_vmap (or _enter or
Re: [PATCH v4 2/4] drm/panic: Add a drm panic handler
Hi Am 10.10.23 um 14:59 schrieb Daniel Vetter: [...] Why can't we use the model[1] suggested by Daniel using a draw_pixel callback giving drivers full control on how they can put a pixel on the display? I share kind of the same general ideas/conclusions: "qthe idea is that all the fb selection and lookup is handled in shared code (and with proper locking, but only for atomic drivers)." 2016 is a bit old though and multiple developments happened since (secure playback is a thing now, framebuffer compression too), so I still think that their expectation that the framebuffer is accessible to / writable by the CPU no longer holds true. I think largely it should still be ok, because the idea behind the draw_xy callback was that the driver could take care of anything special, like - tiling - clearing compression bits so that just writing the raw pixels works (if your compression format allows for that) - handling any differences in how the pixels need to be written, like cache flushing, mmio_write vs normal memory, amd also has peek/poke registers to be able to write even into unmappable memory What would probably be a good idea is to do an s/void */uinptr_t/ over my interface proposal, or maybe an even more opaque cookie since really the only thing you can do is get the void * that ->panic_vmap returns and pass it into ->panic_draw_xy. I thought (but I didn't dig through details) that the panic fb struct is essentially meant to serve this purpose in the current series? I have one detail about the code: While working on the format-conversion code, I've always found struct drm_framebuffer to be clunky to work with. It's build around the idea of managing GEM buffers, but not accessing them. So I've been thinking about something like a drm_pixmap that contains size, color format and data pointers in one place. Reads and writes would be callbacks. It could abstract access to any kind of buffer. IIRC Jocelyn had something like that in the very first patchset. or maybe fb_pixmap could be repurposed. Best regards Thomas This will even work for the AMD debug interface. In the linear CPU accessible buffer case, we can provide a helper for that, maybe we can do helpers for other common cases as well. Yeah, their idea of a panic_draw would work great for that. Adding to that we would need a panic_setup/enter and panic_teardown/exit callback. What for? So panic teardown would be for testing in CI, to make it non-destructive and clean up anything panic_vmap (or _enter or whatever you call it) has done. I thought John Oggness was also looking into how the new panic handlers/consoles could be made testable in the panic paths, including lock stealing and getting called from nmi. -Sima -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg) OpenPGP_signature.asc Description: OpenPGP digital signature
Re: [PATCH 1/2] drm/tegra: Return an error code if fails
On Mon, Jun 26, 2023 at 10:33:30PM +0800, Sui Jingfeng wrote: > Return -ENOMEM if tegra_bo_mmap() fails. > > Signed-off-by: Sui Jingfeng > --- > drivers/gpu/drm/tegra/gem.c | 2 ++ > 1 file changed, 2 insertions(+) Sorry, this fell through the cracks. I think it'd be better if tegra_bo_mmap() were to be improved to always return either an ERR_PTR() encoded error code or a valid pointer. Throwing NULL into the mix isn't useful because it typically means something like -ENOMEM anyway. Error codes are more explicit, so since we're already using them for some cases, might as well return them for all. Actually, looks like tegra_bo_mmap() never actually returns an ERR_PTR() encoded error code. It's either obj->vaddr, the return value of vmap() (which is either NULL or the address of the mapping), or the address obtained from dma_buf_vmap_unlocked() (i.e. map.vaddr) or NULL on failure. So I think it would equally make sense to keep your patch and to remove the IS_ERR() check below it. I would slightly prefer the first option, but either is fine. Thierry > diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c > index dea38892d6e6..0ce22935fbd3 100644 > --- a/drivers/gpu/drm/tegra/gem.c > +++ b/drivers/gpu/drm/tegra/gem.c > @@ -710,6 +710,8 @@ static int tegra_gem_prime_vmap(struct dma_buf *buf, > struct iosys_map *map) > void *vaddr; > > vaddr = tegra_bo_mmap(>base); > + if (!vaddr) > + return -ENOMEM; > if (IS_ERR(vaddr)) > return PTR_ERR(vaddr); > > -- > 2.25.1 > signature.asc Description: PGP signature
Re: [PATCH 1/2] accel/qaic: Add support for periodic timesync
Hi Jeffrey, kernel test robot noticed the following build errors: [auto build test ERROR on drm-misc/drm-misc-next] [also build test ERROR on next-20231010] [cannot apply to linus/master v6.6-rc5] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Jeffrey-Hugo/accel-qaic-Add-support-for-periodic-timesync/20231007-003324 base: git://anongit.freedesktop.org/drm/drm-misc drm-misc-next patch link: https://lore.kernel.org/r/20231006163210.21319-2-quic_jhugo%40quicinc.com patch subject: [PATCH 1/2] accel/qaic: Add support for periodic timesync config: powerpc-randconfig-003-20231010 (https://download.01.org/0day-ci/archive/20231010/202310102021.xkvfihrt-...@intel.com/config) compiler: powerpc-linux-gcc (GCC) 13.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231010/202310102021.xkvfihrt-...@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot | Closes: https://lore.kernel.org/oe-kbuild-all/202310102021.xkvfihrt-...@intel.com/ All errors (new ones prefixed by >>): drivers/accel/qaic/qaic_timesync.c: In function 'qaic_timesync_timer': >> drivers/accel/qaic/qaic_timesync.c:125:25: error: implicit declaration of >> function 'readq'; did you mean 'readl'? >> [-Werror=implicit-function-declaration] 125 | device_qtimer = readq(mqtsdev->qtimer_addr); | ^ | readl cc1: some warnings being treated as errors vim +125 drivers/accel/qaic/qaic_timesync.c 102 103 static void qaic_timesync_timer(struct timer_list *t) 104 { 105 struct mqts_dev *mqtsdev = from_timer(mqtsdev, t, timer); 106 struct qts_host_time_sync_msg_data *sync_msg; 107 u64 device_qtimer_us; 108 u64 device_qtimer; 109 u64 host_time_us; 110 u64 offset_us; 111 u64 host_sec; 112 int ret; 113 114 if (atomic_read(>buff_in_use)) { 115 dev_dbg(mqtsdev->dev, "%s buffer not free, schedule next cycle\n", __func__); 116 goto mod_timer; 117 } 118 atomic_set(>buff_in_use, 1); 119 120 sync_msg = mqtsdev->sync_msg; 121 sync_msg->header.signature = cpu_to_le16(QAIC_TIMESYNC_SIGNATURE); 122 sync_msg->header.msg_type = QAIC_TS_SYNC_REQ; 123 /* Read host UTC time and convert to uS*/ 124 host_time_us = div_u64(ktime_get_real_ns(), NSEC_PER_USEC); > 125 device_qtimer = readq(mqtsdev->qtimer_addr); 126 device_qtimer_us = QAIC_CONV_QTIMER_TO_US(device_qtimer); 127 /* Offset between host UTC and device time */ 128 offset_us = host_time_us - device_qtimer_us; 129 130 host_sec = div_u64(offset_us, USEC_PER_SEC); 131 sync_msg->data.tv_usec = cpu_to_le64(offset_us - host_sec * USEC_PER_SEC); 132 sync_msg->data.tv_sec = cpu_to_le64(host_sec); 133 ret = mhi_queue_buf(mqtsdev->mhi_dev, DMA_TO_DEVICE, sync_msg, sizeof(*sync_msg), MHI_EOT); 134 if (ret && (ret != -EAGAIN)) { 135 dev_err(mqtsdev->dev, "%s unable to queue to mhi:%d\n", __func__, ret); 136 return; 137 } else if (ret == -EAGAIN) { 138 atomic_set(>buff_in_use, 0); 139 } 140 141 mod_timer: 142 ret = mod_timer(t, jiffies + msecs_to_jiffies(timesync_delay_ms)); 143 if (ret) 144 dev_err(mqtsdev->dev, "%s mod_timer error:%d\n", __func__, ret); 145 } 146 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Re: [PATCH v3 11/16] platform/x86/amd/pmf: dump policy binary data
On Tue, 10 Oct 2023, Shyam Sundar S K wrote: > Sometimes policy binary retrieved from the BIOS maybe incorrect that can > end up in failing to enable the Smart PC solution feature. > > Use print_hex_dump_debug() to dump the policy binary in hex, so that we > debug the issues related to the binary even before sending that to TA. > > Signed-off-by: Shyam Sundar S K > --- > drivers/platform/x86/amd/pmf/tee-if.c | 9 + > 1 file changed, 9 insertions(+) > > diff --git a/drivers/platform/x86/amd/pmf/tee-if.c > b/drivers/platform/x86/amd/pmf/tee-if.c > index 994daf945795..e4386f503ad0 100644 > --- a/drivers/platform/x86/amd/pmf/tee-if.c > +++ b/drivers/platform/x86/amd/pmf/tee-if.c > @@ -275,6 +275,12 @@ static int amd_pmf_start_policy_engine(struct > amd_pmf_dev *dev) > } > > #ifdef CONFIG_AMD_PMF_DEBUG > +static void amd_pmf_hex_dump_pb(struct amd_pmf_dev *dev) > +{ > + print_hex_dump_debug("(pb): ", DUMP_PREFIX_OFFSET, 16, 1, > dev->policy_buf, > + dev->policy_sz, false); > +} > + You forgot to add the empty version of amd_pmf_hex_dump_pb function into #else part (so the compile fails if CONFIG_AMD_PMF_DEBUG is not set). > static ssize_t amd_pmf_get_pb_data(struct file *filp, const char __user *buf, > size_t length, loff_t *pos) > { > @@ -289,6 +295,7 @@ static ssize_t amd_pmf_get_pb_data(struct file *filp, > const char __user *buf, > if (copy_from_user(dev->policy_buf, buf, dev->policy_sz)) > return -EFAULT; > > + amd_pmf_hex_dump_pb(dev); > ret = amd_pmf_start_policy_engine(dev); > if (ret) > return -EINVAL; > @@ -327,6 +334,7 @@ static int amd_pmf_open_pb(struct amd_pmf_dev *dev, > struct dentry *debugfs_root) > } > > static void amd_pmf_remove_pb(struct amd_pmf_dev *dev) {} > +static void amd_pmf_hex_dump_pb(struct amd_pmf_dev *dev) {} > #endif > > static int amd_pmf_get_bios_buffer(struct amd_pmf_dev *dev) > @@ -341,6 +349,7 @@ static int amd_pmf_get_bios_buffer(struct amd_pmf_dev > *dev) > > memcpy(dev->policy_buf, dev->policy_base, dev->policy_sz); > > + amd_pmf_hex_dump_pb(dev); > if (pb_side_load) > amd_pmf_open_pb(dev, dev->dbgfs_dir); > > -- i.
Re: [PATCH v4 2/4] drm/panic: Add a drm panic handler
Hi Am 10.10.23 um 11:33 schrieb Maxime Ripard: [...] We also have discussions about kexec/kdump support. Here we'd need to retrieve the scanout address, forward it to the kexec kernel and put simpledrm onto that framebuffer until the regular driver takes over. Generically speaking, there's strictly no guarantee that the current scanout buffer is accessible by the CPU. It's not even a driver issue, it's a workload issue, so it will affect 100% of the times some users, and some 0% of the time. And I'd be OK with that. It's all best effort anyway. An interface like get_scanout_buffer will be helpful for this use case. So it makes sense to use it for the panic handler as well. It won't be helpful because the vast majority of the ARM drivers (and thus the vast majority of the KMS drivers) won't be able to implement it properly and reliably. The barrier for firmware-based drivers is low: a pre-configured display and mmap'able framebuffer memory. And it's assumed that a callback for kexec would attempt to configure hardware accordingly. If a system really cannot provide this, so be it. run the atomic_update() on it, and return this commit's framebuffer ? That way each driver have a better control on what the panic handler will do. It can even call directly its internal functions, to avoid the locks of the drm generic functions, and make sure it will only change the format and base address. That's a bit more work for each driver, but should be more reliable I think. I don't think that better control there is a good idea, it's a path that won't get tested much so we'd be better off not allowing drivers to deviate too much from the "ideal" design. What I had in mind is something like: - Add a panic hook in drm_mode_config_funcs, with a drm_atomic_helper_panic helper; - Provide an atomic_panic hook or something in drm_plane_helper_funcs; - If they are set, we register the drm_panic handler; - The handler will call drm_mode_config_funcs.panic, which will take its prepared state, fill the framebuffer it allocated with the penguin and backtrace, call drm_plane_helper_funcs.atomic_panic(). - The driver now updates the format and fb address. - Halt and catch fire Does that make sense? Please see my other replies. I find this fragile, and unnecessary for cases where there already is a working scanout buffer in place. And please see my other replies. Depending on a working scanout buffer in place being accessible by the CPU is incredibly limiting. Ignoring it when I'm pointing that out won't get us to a solution acceptable for everyone. It's something a driver could implement internally to provide a scanout buffer if none has been set up already. Some drivers need extra resources when setting up a plane. VC4 for example need for every plane to allocate multiple internal SRAM buffers. Just allocating an extra framebuffer won't cut it. This is tied to the state so far, so I guess we would need to allocate a new state. Oh, and if we have several drivers that need to allocate that extra framebuffer and state, we could make it part of the core or turn it into a helper? I mentioned that even the simple drivers hold locks during the atomic commit. Some of the drivers use vmap/vunmap, which might make problems as well. It's used in the context of damage handling, which also makes no sense here. So the regular atomic helpers most likely won't work. It sounds to me as if you're essentially asking for something like a flush or sync operation. Stepping back from get_scanout_buffer for a moment and adopting your proposal from above, I can see something like this working: - the driver provides a panic callback in struct drm_driver - DRM registers a panic handler to invokes the callback - the panic callback has a scanout buffer from somewhere (currently active, prepared, from firmware, plain memory, etc) - we provide a helper that fills the scanout buffer with information - the driver then updates the hardware from/with the scanout buffer; details depend on the hardware The final step is like a flush or commit operation. To give some examples: The simple drivers of this patchset probably don't have to do anything. Drivers with command/packet queues could attempt to send the necessary commands to the device. Best regards Thomas Maxime -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg) OpenPGP_signature.asc Description: OpenPGP digital signature
[PATCH v3 16/16] platform/x86/amd/pmf: Add PMF-AMDSFH interface for ALS
From: Basavaraj Natikar AMDSFH has information about the Ambient light via the Ambient Light Sensor (ALS) which is part of the AMD sensor fusion hub. Add PMF and AMDSFH interface to get this information. make amd_sfh_float_to_int() as non-static function so that this can be called outside of the current file. Co-developed-by: Shyam Sundar S K Signed-off-by: Shyam Sundar S K Signed-off-by: Basavaraj Natikar --- drivers/hid/amd-sfh-hid/amd_sfh_common.h | 1 + drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c | 2 +- drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c | 6 ++ .../amd-sfh-hid/sfh1_1/amd_sfh_interface.c| 20 +++ .../amd-sfh-hid/sfh1_1/amd_sfh_interface.h| 1 + drivers/platform/x86/amd/pmf/spc.c| 7 +++ include/linux/amd-pmf-io.h| 2 ++ 7 files changed, 38 insertions(+), 1 deletion(-) diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_common.h b/drivers/hid/amd-sfh-hid/amd_sfh_common.h index cd57037bf217..a1950bc6e6ce 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_common.h +++ b/drivers/hid/amd-sfh-hid/amd_sfh_common.h @@ -39,6 +39,7 @@ struct amd_mp2_sensor_info { struct sfh_dev_status { bool is_hpd_present; + bool is_als_present; }; struct amd_mp2_dev { diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c index 47a87b28e00e..dbc8c6943ca1 100644 --- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c +++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c @@ -132,7 +132,7 @@ static void get_common_inputs(struct common_input_property *common, int report_i common->event_type = HID_USAGE_SENSOR_EVENT_DATA_UPDATED_ENUM; } -static int amd_sfh_float_to_int(u32 flt32_val) +int amd_sfh_float_to_int(u32 flt32_val) { int fraction, shift, mantissa, sign, exp, zeropre; diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c index 3dc652d41d7d..f2890d329459 100644 --- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c +++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c @@ -77,6 +77,9 @@ static int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata) case HPD_IDX: privdata->dev_en.is_hpd_present = false; break; + case ALS_IDX: + privdata->dev_en.is_als_present = false; + break; } if (cl_data->sensor_sts[i] == SENSOR_ENABLED) { @@ -188,6 +191,9 @@ static int amd_sfh1_1_hid_client_init(struct amd_mp2_dev *privdata) case HPD_IDX: privdata->dev_en.is_hpd_present = true; break; + case ALS_IDX: + privdata->dev_en.is_als_present = true; + break; } } dev_dbg(dev, "sid 0x%x (%s) status 0x%x\n", diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c index 7637da0dec6f..48a7a450e029 100644 --- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c +++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c @@ -94,12 +94,32 @@ static int amd_sfh_hpd_info(u8 *user_present) return -ENODEV; } +static int amd_sfh_als_info(u32 *ambient_light) +{ + if (emp2 && emp2->dev_en.is_als_present) { + struct sfh_als_data als_data; + void __iomem *sensoraddr; + + sensoraddr = emp2->vsbase + + (ALS_IDX * SENSOR_DATA_MEM_SIZE_DEFAULT) + + OFFSET_SENSOR_DATA_DEFAULT; + memcpy_fromio(_data, sensoraddr, sizeof(struct sfh_als_data)); + *ambient_light = amd_sfh_float_to_int(als_data.lux); + + return 0; + } + + return -ENODEV; +} + int amd_get_sfh_info(struct amd_sfh_info *sfh_info, enum sfh_message_type op) { if (sfh_info) { switch (op) { case MT_HPD: return amd_sfh_hpd_info(_info->user_present); + case MT_ALS: + return amd_sfh_als_info(_info->ambient_light); } } return -EINVAL; diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h index 9d31d5b510eb..7ecddad430e4 100644 --- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h +++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h @@ -149,6 +149,7 @@ struct hpd_status { }; }; +int amd_sfh_float_to_int(u32 flt32_val); void sfh_interface_init(struct amd_mp2_dev *mp2); void amd_sfh1_1_set_desc_ops(struct amd_mp2_ops *mp2_ops); #endif diff --git a/drivers/platform/x86/amd/pmf/spc.c b/drivers/platform/x86/amd/pmf/spc.c index e33bbf8a3de4..b6cf6d7e6ef5 100644 ---
[PATCH v3 15/16] platform/x86/amd/pmf: Add PMF-AMDSFH interface for HPD
From: Basavaraj Natikar AMDSFH has information about the User presence information via the Human Presence Detection (HPD) sensor which is part of the AMD sensor fusion hub. Add PMF and AMDSFH interface to get this information. Co-developed-by: Shyam Sundar S K Signed-off-by: Shyam Sundar S K Signed-off-by: Basavaraj Natikar --- drivers/hid/amd-sfh-hid/amd_sfh_common.h | 5 drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c | 11 .../amd-sfh-hid/sfh1_1/amd_sfh_interface.c| 28 +++ drivers/platform/x86/amd/pmf/Kconfig | 1 + drivers/platform/x86/amd/pmf/spc.c| 21 ++ include/linux/amd-pmf-io.h| 20 - 6 files changed, 85 insertions(+), 1 deletion(-) diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_common.h b/drivers/hid/amd-sfh-hid/amd_sfh_common.h index 2643bb14fee2..cd57037bf217 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_common.h +++ b/drivers/hid/amd-sfh-hid/amd_sfh_common.h @@ -37,6 +37,10 @@ struct amd_mp2_sensor_info { dma_addr_t dma_address; }; +struct sfh_dev_status { + bool is_hpd_present; +}; + struct amd_mp2_dev { struct pci_dev *pdev; struct amdtp_cl_data *cl_data; @@ -47,6 +51,7 @@ struct amd_mp2_dev { struct amd_input_data in_data; /* mp2 active control status */ u32 mp2_acs; + struct sfh_dev_status dev_en; }; struct amd_mp2_ops { diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c index e9c6413af24a..3dc652d41d7d 100644 --- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c +++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c @@ -73,6 +73,12 @@ static int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata) int i, status; for (i = 0; i < cl_data->num_hid_devices; i++) { + switch (cl_data->sensor_idx[i]) { + case HPD_IDX: + privdata->dev_en.is_hpd_present = false; + break; + } + if (cl_data->sensor_sts[i] == SENSOR_ENABLED) { privdata->mp2_ops->stop(privdata, cl_data->sensor_idx[i]); status = amd_sfh_wait_for_response @@ -178,6 +184,11 @@ static int amd_sfh1_1_hid_client_init(struct amd_mp2_dev *privdata) rc = amdtp_hid_probe(i, cl_data); if (rc) goto cleanup; + switch (cl_data->sensor_idx[i]) { + case HPD_IDX: + privdata->dev_en.is_hpd_present = true; + break; + } } dev_dbg(dev, "sid 0x%x (%s) status 0x%x\n", cl_data->sensor_idx[i], get_sensor_name(cl_data->sensor_idx[i]), diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c index 4f81ef2d4f56..7637da0dec6f 100644 --- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c +++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c @@ -7,11 +7,14 @@ * * Author: Basavaraj Natikar */ +#include #include #include #include "amd_sfh_interface.h" +static struct amd_mp2_dev *emp2; + static int amd_sfh_wait_response(struct amd_mp2_dev *mp2, u8 sid, u32 cmd_id) { struct sfh_cmd_response cmd_resp; @@ -76,4 +79,29 @@ static struct amd_mp2_ops amd_sfh_ops = { void sfh_interface_init(struct amd_mp2_dev *mp2) { mp2->mp2_ops = _sfh_ops; + emp2 = mp2; +} + +static int amd_sfh_hpd_info(u8 *user_present) +{ + if (emp2 && emp2->dev_en.is_hpd_present) { + struct hpd_status hpdstatus; + + hpdstatus.val = readl(emp2->mmio + AMD_C2P_MSG(4)); + *user_present = hpdstatus.shpd.presence; + return 0; + } + return -ENODEV; +} + +int amd_get_sfh_info(struct amd_sfh_info *sfh_info, enum sfh_message_type op) +{ + if (sfh_info) { + switch (op) { + case MT_HPD: + return amd_sfh_hpd_info(_info->user_present); + } + } + return -EINVAL; } +EXPORT_SYMBOL_GPL(amd_get_sfh_info); diff --git a/drivers/platform/x86/amd/pmf/Kconfig b/drivers/platform/x86/amd/pmf/Kconfig index 7f430de7af44..d368d35a49ac 100644 --- a/drivers/platform/x86/amd/pmf/Kconfig +++ b/drivers/platform/x86/amd/pmf/Kconfig @@ -11,6 +11,7 @@ config AMD_PMF select ACPI_PLATFORM_PROFILE depends on TEE && AMDTEE depends on DRM_AMDGPU + depends on AMD_SFH_HID help This driver provides support for the AMD Platform Management Framework. The goal is to enhance end user experience by making AMD PCs smarter, diff --git a/drivers/platform/x86/amd/pmf/spc.c b/drivers/platform/x86/amd/pmf/spc.c index 58b51e11e424..e33bbf8a3de4 100644 ---
[PATCH v3 14/16] HID: amd_sfh: rename float_to_int() to amd_sfh_float_to_int()
From: Basavaraj Natikar Current amd_sfh driver has float_to_int() to convert units from float to int. This is fine until this function gets called outside of the current scope of file. Add a prefix "amd_sfh" to float_to_int() so that function represents the driver name. This function will be called by multiple callers in the next patch. Co-developed-by: Shyam Sundar S K Signed-off-by: Shyam Sundar S K Signed-off-by: Basavaraj Natikar --- drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c | 22 +-- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c index 06bdcf072d10..47a87b28e00e 100644 --- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c +++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c @@ -132,7 +132,7 @@ static void get_common_inputs(struct common_input_property *common, int report_i common->event_type = HID_USAGE_SENSOR_EVENT_DATA_UPDATED_ENUM; } -static int float_to_int(u32 flt32_val) +static int amd_sfh_float_to_int(u32 flt32_val) { int fraction, shift, mantissa, sign, exp, zeropre; @@ -200,9 +200,9 @@ static u8 get_input_rep(u8 current_index, int sensor_idx, int report_id, OFFSET_SENSOR_DATA_DEFAULT; memcpy_fromio(_data, sensoraddr, sizeof(struct sfh_accel_data)); get_common_inputs(_input.common_property, report_id); - acc_input.in_accel_x_value = float_to_int(accel_data.acceldata.x) / 100; - acc_input.in_accel_y_value = float_to_int(accel_data.acceldata.y) / 100; - acc_input.in_accel_z_value = float_to_int(accel_data.acceldata.z) / 100; + acc_input.in_accel_x_value = amd_sfh_float_to_int(accel_data.acceldata.x) / 100; + acc_input.in_accel_y_value = amd_sfh_float_to_int(accel_data.acceldata.y) / 100; + acc_input.in_accel_z_value = amd_sfh_float_to_int(accel_data.acceldata.z) / 100; memcpy(input_report, _input, sizeof(acc_input)); report_size = sizeof(acc_input); break; @@ -211,9 +211,9 @@ static u8 get_input_rep(u8 current_index, int sensor_idx, int report_id, OFFSET_SENSOR_DATA_DEFAULT; memcpy_fromio(_data, sensoraddr, sizeof(struct sfh_gyro_data)); get_common_inputs(_input.common_property, report_id); - gyro_input.in_angel_x_value = float_to_int(gyro_data.gyrodata.x) / 1000; - gyro_input.in_angel_y_value = float_to_int(gyro_data.gyrodata.y) / 1000; - gyro_input.in_angel_z_value = float_to_int(gyro_data.gyrodata.z) / 1000; + gyro_input.in_angel_x_value = amd_sfh_float_to_int(gyro_data.gyrodata.x) / 1000; + gyro_input.in_angel_y_value = amd_sfh_float_to_int(gyro_data.gyrodata.y) / 1000; + gyro_input.in_angel_z_value = amd_sfh_float_to_int(gyro_data.gyrodata.z) / 1000; memcpy(input_report, _input, sizeof(gyro_input)); report_size = sizeof(gyro_input); break; @@ -222,9 +222,9 @@ static u8 get_input_rep(u8 current_index, int sensor_idx, int report_id, OFFSET_SENSOR_DATA_DEFAULT; memcpy_fromio(_data, sensoraddr, sizeof(struct sfh_mag_data)); get_common_inputs(_input.common_property, report_id); - magno_input.in_magno_x = float_to_int(mag_data.magdata.x) / 100; - magno_input.in_magno_y = float_to_int(mag_data.magdata.y) / 100; - magno_input.in_magno_z = float_to_int(mag_data.magdata.z) / 100; + magno_input.in_magno_x = amd_sfh_float_to_int(mag_data.magdata.x) / 100; + magno_input.in_magno_y = amd_sfh_float_to_int(mag_data.magdata.y) / 100; + magno_input.in_magno_z = amd_sfh_float_to_int(mag_data.magdata.z) / 100; magno_input.in_magno_accuracy = mag_data.accuracy / 100; memcpy(input_report, _input, sizeof(magno_input)); report_size = sizeof(magno_input); @@ -234,7 +234,7 @@ static u8 get_input_rep(u8 current_index, int sensor_idx, int report_id, OFFSET_SENSOR_DATA_DEFAULT; memcpy_fromio(_data, sensoraddr, sizeof(struct sfh_als_data)); get_common_inputs(_input.common_property, report_id); - als_input.illuminance_value = float_to_int(als_data.lux); + als_input.illuminance_value = amd_sfh_float_to_int(als_data.lux); report_size = sizeof(als_input); memcpy(input_report, _input, sizeof(als_input)); break; -- 2.25.1