* Re: [PATCHv2 2/3] ARM: drm: Intel FPGA VIP Frame Buffer II drm driver
From: Eric Anholt @ 2017-05-03 20:34 UTC (permalink / raw)
To: daniel.vetter, dinguyen, robh+dt
Cc: hean.loong.ong, devicetree, tien.hock.loh, dri-devel, Ong
In-Reply-To: <1493086006-4392-3-git-send-email-hean.loong.ong@intel.com>
[-- Attachment #1.1: Type: text/plain, Size: 9774 bytes --]
hean.loong.ong@intel.com writes:
> From: "Ong, Hean Loong" <hean.loong.ong@intel.com>
>
> Driver for Intel FPGA Video and Image Processing
> Suite Frame Buffer II. The driver only supports the Intel
> Arria10 devkit and its variants. This driver can be either
> loaded staticlly or in modules. The OF device tree binding
> is located at:
> Documentation/devicetree/bindings/display/altr,vip-fb2.txt
>
> Signed-off-by: Ong, Hean Loong <hean.loong.ong@intel.com>
I'm not sure if this driver is going to make sense as-is, if it doesn't
actually do display of planes from system memory. But in case I was
wrong, here's my review:
> diff --git a/drivers/gpu/drm/ivip/intel_vip_conn.c b/drivers/gpu/drm/ivip/intel_vip_conn.c
> new file mode 100644
> index 0000000..499d3b4
> --- /dev/null
> +++ b/drivers/gpu/drm/ivip/intel_vip_conn.c
> @@ -0,0 +1,96 @@
> +/*
> + * intel_vip_conn.c -- Intel Video and Image Processing(VIP)
> + * Frame Buffer II driver
> + *
> + * This driver supports the Intel VIP Frame Reader component.
> + * More info on the hardware can be found in the Intel Video
> + * and Image Processing Suite User Guide at this address
> + * http://www.altera.com/literature/ug/ug_vip.pdf.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> + * more details.
> + *
> + * Authors:
> + * Ong, Hean-Loong <hean.loong.ong@intel.com>
> + *
> + */
> +
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_crtc_helper.h>
> +#include <drm/drm_encoder_slave.h>
> +#include <drm/drm_plane_helper.h>
> +
> +static enum drm_connector_status
> +intelvipfb_drm_connector_detect(struct drm_connector *connector, bool force)
> +{
> + return connector_status_connected;
> +}
> +
> +static void intelvipfb_drm_connector_destroy(struct drm_connector *connector)
> +{
> + drm_connector_unregister(connector);
> + drm_connector_cleanup(connector);
> +}
> +
> +static const struct drm_connector_funcs intelvipfb_drm_connector_funcs = {
> + .dpms = drm_helper_connector_dpms,
> + .reset = drm_atomic_helper_connector_reset,
> + .detect = intelvipfb_drm_connector_detect,
> + .fill_modes = drm_helper_probe_single_connector_modes,
> + .destroy = intelvipfb_drm_connector_destroy,
> + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
> + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
> +};
> +
> +static int intelvipfb_drm_connector_get_modes(struct drm_connector *connector)
> +{
> + struct drm_device *drm = connector->dev;
> + int count;
> +
> + count = drm_add_modes_noedid(connector, drm->mode_config.max_width,
> + drm->mode_config.max_height);
> + drm_set_preferred_mode(connector, drm->mode_config.max_width,
> + drm->mode_config.max_height);
> + return count;
> +}
You're adding a bunch of modes here, but I don't see anywhere in the
driver that you change the resolution being scanned out.
If you can't change resolution, then I'd probably use drm_gtf_mode() or
something to generate just the one mode (do you have a vrefresh for
it?). Also, in the simple display pipe's atomic_check, make sure that
the mode chosen is the width/height you can support.
> +
> +static const struct drm_connector_helper_funcs
> +intelvipfb_drm_connector_helper_funcs = {
> + .get_modes = intelvipfb_drm_connector_get_modes,
> +};
> +
> +struct drm_connector *
> +intelvipfb_conn_setup(struct drm_device *drm)
> +{
> + struct drm_connector *conn;
> + int ret;
> +
> + conn = devm_kzalloc(drm->dev, sizeof(*conn), GFP_KERNEL);
> + if (IS_ERR(conn))
> + return NULL;
> +
> + ret = drm_connector_init(drm, conn, &intelvipfb_drm_connector_funcs,
> + DRM_MODE_CONNECTOR_DisplayPort);
Are you actually outputting DisplayPort
(https://en.wikipedia.org/wiki/DisplayPort)?
You probably want something else from the DRM_MODE_CONNECTOR list, or
maybe just DRM_MODE_CONNECTOR_Unknown.
> + if (ret < 0) {
> + dev_err(drm->dev, "failed to initialize drm connector\n");
> + ret = -ENOMEM;
> + goto error_connector_cleanup;
> + }
> +
> + drm_connector_helper_add(conn, &intelvipfb_drm_connector_helper_funcs);
> +
> + return conn;
> +
> +error_connector_cleanup:
> + drm_connector_cleanup(conn);
> +
> + return NULL;
> +}
> diff --git a/drivers/gpu/drm/ivip/intel_vip_core.c b/drivers/gpu/drm/ivip/intel_vip_core.c
> new file mode 100644
> index 0000000..4e83343
> --- /dev/null
> +++ b/drivers/gpu/drm/ivip/intel_vip_core.c
> @@ -0,0 +1,171 @@
> +/*
> + * intel_vip_core.c -- Intel Video and Image Processing(VIP)
> + * Frame Buffer II driver
> + *
> + * This driver supports the Intel VIP Frame Reader component.
> + * More info on the hardware can be found in the Intel Video
> + * and Image Processing Suite User Guide at this address
> + * http://www.altera.com/literature/ug/ug_vip.pdf.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> + * more details.
> + *
> + * Authors:
> + * Ong, Hean-Loong <hean.loong.ong@intel.com>
> + *
> + */
> +
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +
> +#include <drm/drmP.h>
> +#include <drm/drm_atomic.h>
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_crtc_helper.h>
> +#include <drm/drm_fb_helper.h>
> +#include <drm/drm_fb_cma_helper.h>
> +#include <drm/drm_gem_cma_helper.h>
> +#include <drm/drm_plane_helper.h>
> +#include <drm/drm_simple_kms_helper.h>
> +
> +#include "intel_vip_drv.h"
> +
> +static const u32 fbpriv_formats[] = {
> + DRM_FORMAT_XRGB8888,
> + DRM_FORMAT_RGB565
> +};
You're registering that you support this set of formats, but I don't see
anything programming the hardware differently based on the format of the
plane.
> +static void intelvipfb_start_hw(void __iomem *base, resource_size_t addr)
> +{
> + /*
> + * The frameinfo variable has to correspond to the size of the VIP Suite
> + * Frame Reader register 7 which will determine the maximum size used
> + * in this frameinfo
> + */
> +
> + u32 frameinfo;
> +
> + frameinfo =
> + readl(base + INTELVIPFB_FRAME_READER) & 0x00ffffff;
> + writel(frameinfo, base + INTELVIPFB_FRAME_INFO);
> + writel(addr, base + INTELVIPFB_FRAME_START);
> + /* Finally set the control register to 1 to start streaming */
> + writel(1, base + INTELVIPFB_CONTROL);
> +}
The addr you're passing in here is from dev->mode_config.fb_base, which
is this weird sideband value from drm_fbdev_cma. It's the wrong value
to use if anything else uses the KMS interfaces to change the plane --
you should be using
drm_fb_cma_get_gem_addr(drm_simple_display_pipe->plane->state, 0)
instead.
> +
> +static void intelvipfb_disable_hw(void __iomem *base)
> +{
> + /* set the control register to 0 to stop streaming */
> + writel(0, base + INTELVIPFB_CONTROL);
> +}
These two functions should be be called from fbpriv_funcs.enable() and
.disable(), not device load/unload.
> +static const struct drm_mode_config_funcs intelvipfb_mode_config_funcs = {
> + .fb_create = drm_fb_cma_create,
> + .atomic_check = drm_atomic_helper_check,
> + .atomic_commit = drm_atomic_helper_commit,
> +};
> +
> +static struct drm_mode_config_helper_funcs intelvipfb_mode_config_helpers = {
> + .atomic_commit_tail = drm_atomic_helper_commit_tail,
> +};
> +
> +static void intelvipfb_setup_mode_config(struct drm_device *drm)
> +{
> + drm_mode_config_init(drm);
> + drm->mode_config.funcs = &intelvipfb_mode_config_funcs;
> + drm->mode_config.helper_private = &intelvipfb_mode_config_helpers;
> +}
> +
> +static int intelvipfb_pipe_prepare_fb(struct drm_simple_display_pipe *pipe,
> + struct drm_plane_state *plane_state)
> +{
> + return drm_fb_cma_prepare_fb(&pipe->plane, plane_state);
> +}
> +
> +static struct drm_simple_display_pipe_funcs fbpriv_funcs = {
> + .prepare_fb = intelvipfb_pipe_prepare_fb,
> +};
> +
> +int intelvipfb_probe(struct device *dev, void __iomem *base)
> +{
> + int retval;
> + struct drm_device *drm;
> + struct intelvipfb_priv *fbpriv = dev_get_drvdata(dev);
> + struct drm_connector *connector;
> +
> + dev_set_drvdata(dev, fbpriv);
> +
> + drm = fbpriv->drm;
> +
> + intelvipfb_setup_mode_config(drm);
> +
> + connector = intelvipfb_conn_setup(drm);
> + if (!connector) {
> + dev_err(drm->dev, "Connector setup failed\n");
> + goto err_mode_config;
> + }
> +
> + retval = drm_simple_display_pipe_init(drm, &fbpriv->pipe,
> + &fbpriv_funcs,
> + fbpriv_formats,
> + ARRAY_SIZE(fbpriv_formats),
> + connector);
> + if (retval < 0) {
> + dev_err(drm->dev, "Cannot setup simple display pipe\n");
> + goto err_mode_config;
> + }
> +
> + fbpriv->fbcma = drm_fbdev_cma_init(drm, PREF_BPP,
> + drm->mode_config.num_connector);
> + if (!fbpriv->fbcma) {
> + fbpriv->fbcma = NULL;
> + dev_err(drm->dev, "Failed to init FB CMA area\n");
> + goto err_mode_config;
> + }
On failure, drm_fbdev_cma_init() returns an ERR_PTR, not NULL.
Also, you're passing this PREF_BPP value here, ignoring
the altr,bits-per-symbol property. That seems wrong.
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
[-- Attachment #2: Type: text/plain, Size: 160 bytes --]
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* Re: [PATCH v3 1/1] of: Move OF property and graph API from base.c to property.c
From: Sakari Ailus @ 2017-05-03 20:41 UTC (permalink / raw)
To: Rob Herring
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Frank Rowand,
linux-acpi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Sudeep Holla,
Lorenzo Pieralisi,
mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org,
Rafael J. Wysocki, Mark Rutland, Mark Brown, Al Stone
In-Reply-To: <CAL_JsqKOnhaHW=GihiuaM6m8TjmREKNJsJaAaW96bKYmy=2MeQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Rob Herring wrote:
> Yes, but not now in the middle of the merge window. Maybe towards the
> end of the merge window for 4.12. Or it's not going to be until 4.13.
Ack. I'll repost the rest for review tomorrow.
--
Sakari Ailus
sakari.ailus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v4 1/2] dt-bindings: Document the STM32 QSPI bindings
From: Cyrille Pitchen @ 2017-05-03 20:49 UTC (permalink / raw)
To: Brian Norris
Cc: devicetree, Alexandre Torgue, Boris Brezillon, Richard Weinberger,
linux-kernel, Marek Vasut, Rob Herring, linux-mtd,
Cyrille Pitchen, David Woodhouse, Ludovic Barre
In-Reply-To: <20170502010947.GC18576@google.com>
Le 02/05/2017 à 03:09, Brian Norris a écrit :
> On Sun, Apr 16, 2017 at 06:53:06PM +0200, Cyrille Pitchen wrote:
>> Hi all,
>>
>> Rob, is this version ok for you? If so, I can take it into the
>> github/spi-nor tree.
>
> I see this was missing from your pull request. Rob has since acked,
> so...
>
> Applied to l2-mtd.git
>
Indeed, thanks!
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/
>
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply
* Re: [PATCH 2/5] mtd: nand: gpmi: add i.MX 7 SoC support
From: Stefan Agner @ 2017-05-03 21:24 UTC (permalink / raw)
To: Marek Vasut
Cc: Boris Brezillon, Han Xu, mark.rutland-5wv7dgnIgG8, Fabio Estevam,
devicetree-u79uwXL29TY76Z2rM5mHXA, Richard Weinberger,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Sascha Hauer, Han Xu,
Shawn Guo, Cyrille Pitchen, Brian Norris, David Woodhouse,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
LW-AvR2QvxeiV7DiMYJYoSAnRvVK+yQ3ZXh
In-Reply-To: <d0162bbe-c2de-73d1-0d37-9bdd68ceb94b-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
On 2017-05-02 04:18, Marek Vasut wrote:
> On 05/02/2017 11:17 AM, Boris Brezillon wrote:
>> Hi Han,
>>
>> On Fri, 21 Apr 2017 13:29:16 -0500
>> Han Xu <xhnjupt-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>>
>>>>>
>>>>>>>> But then, adding the type would only require 2-3 lines of change if I
>>>>>>>> add it to the GPMI_IS_MX6 macro...
>>>>>>>
>>>>>>> Then at least add a comment because using type = IMX6SX right under
>>>>>>> gpmi_data_mx7d can trigger some head-scratching. And put my R-B on V2.
>>>>>>
>>>>>> FWIW, I mentioned it in the commit message.
>>>>>>
>>>>>> I think rather then adding a comment it is cleaner to just add IS_IMX7D
>>>>>> and add it to the GPMI_IS_MX6 macro. That does not need a comment since
>>>>>> it implicitly says we have a i.MX 7 but treat it like i.MX 6 and it is a
>>>>>> rather small change. Does that sound acceptable?
>>>>>
>>>>> Sure, that's even better, thanks.
>>>>>
>>>>> btw isn't there some single-core mx7 (mx7s ?) , maybe we should just go
>>>>> with mx7 (without the d suffix). I dunno if it has GPMI NAND though, so
>>>>> maybe mx7d is the right thing to do here ...
>>>>>
>>>>
>>>> There is a Solo version yes, and it has GPMI NAND too. However, almost
>>>> all i.MX 7 IPs have been named imx7d by NXP for some reason (including
>>>> compatible strings, see grep -r -e imx7 Documentation/), so I thought I
>>>> stay consistent here...
>
> I missed the DT bit, sorry. the DT bindings say:
> - compatible : should be "fsl,<chip>-gpmi-nand"
> so if FSL invented their own buggy bindings, they need to get them
> through Rob :) IMO for MX7, this should be "imx7-gpmi-nand" , unless
> there's some incentive to discern the solo/dual chips and/or there
> is a future imx7 coming up with different GPMI NAND block version.
>
There is no incentive to discern solo/dual, afaict this are the same
chips, only some IP's "fused away"... From GPMI NAND perspective, they
are definitely the same.
So that leaves us with "imx7-gpmi-nand" vs. "imx7d-gpmi-nand".
All device tree compatible strings as well as Kconfig symbol,
preprocessor defines and function prefixes have been named "imx7d" or
IMX7D so far... Although they work just fine for i.MX7 Solo too... Not
sure why that exactly ended up to be that way, but I guess the reason
was that NXP started to upstream with the dual...
For the sake of continuity, I would prefer if we stick to that (as my
current patchsets do)... It is like imx6q, which also works for dual...
$ grep -r -w compatible.*imx7d arch/arm/boot/dts/*.dts* | wc -l
68
$ grep -r -w compatible.*imx7^d arch/arm/boot/dts/*.dts* | wc -l
0
>>> Hi Guys,
>>>
>>> Yes, there should be a i.MX7 Solo version with one core fused out. IMO, can
>>> we use QUIRK to distinguish them rather than SoC name. I know I also sent
>>> some patch set with SoC Name but I prefer to use QUIRK now.
>>
>> Not sure what this means. Are you okay with Stefan's v2?
>
> IMO the GPMI controller in solo and dual should be the same, so there's
> no need to have quirks for it.
Agreed.
--
Stefan
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v8 5/7] coresight: add support for CPU debug module
From: Mathieu Poirier @ 2017-05-03 22:24 UTC (permalink / raw)
To: Leo Yan
Cc: Jonathan Corbet, Rob Herring, Mark Rutland, Wei Xu,
Catalin Marinas, Will Deacon, Andy Gross, David Brown,
Greg Kroah-Hartman, Suzuki K Poulose, Stephen Boyd, linux-doc,
linux-kernel, devicetree, linux-arm-kernel, linux-arm-msm,
linux-soc, Mike Leach, Sudeep Holla
In-Reply-To: <1493719717-27698-6-git-send-email-leo.yan@linaro.org>
On Tue, May 02, 2017 at 06:08:35PM +0800, Leo Yan wrote:
> Coresight includes debug module and usually the module connects with CPU
> debug logic. ARMv8 architecture reference manual (ARM DDI 0487A.k) has
> description for related info in "Part H: External Debug".
>
> Chapter H7 "The Sample-based Profiling Extension" introduces several
> sampling registers, e.g. we can check program counter value with
> combined CPU exception level, secure state, etc. So this is helpful for
> analysis CPU lockup scenarios, e.g. if one CPU has run into infinite
> loop with IRQ disabled. In this case the CPU cannot switch context and
> handle any interrupt (including IPIs), as the result it cannot handle
> SMP call for stack dump.
>
> This patch is to enable coresight debug module, so firstly this driver
> is to bind apb clock for debug module and this is to ensure the debug
> module can be accessed from program or external debugger. And the driver
> uses sample-based registers for debug purpose, e.g. when system triggers
> panic, the driver will dump program counter and combined context
> registers (EDCIDSR, EDVIDSR); by parsing context registers so can
> quickly get to know CPU secure state, exception level, etc.
>
> Some of the debug module registers are located in CPU power domain, so
> this requires the CPU power domain stays on when access related debug
> registers, but the power management for CPU power domain is quite
> dependent on SoC integration for power management. For the platforms
> which with sane power controller implementations, this driver follows
> the method to set EDPRCR to try to pull the CPU out of low power state
> and then set 'no power down request' bit so the CPU has no chance to
> lose power.
>
> If the SoC has not followed up this design well for power management
> controller, the user should use the command line parameter or sysfs
> to constrain all or partial idle states to ensure the CPU power
> domain is enabled and access coresight CPU debug component safely.
>
> Signed-off-by: Leo Yan <leo.yan@linaro.org>
> ---
> drivers/hwtracing/coresight/Kconfig | 14 +
> drivers/hwtracing/coresight/Makefile | 1 +
> drivers/hwtracing/coresight/coresight-cpu-debug.c | 670 ++++++++++++++++++++++
> 3 files changed, 685 insertions(+)
> create mode 100644 drivers/hwtracing/coresight/coresight-cpu-debug.c
>
> diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig
> index 130cb21..8d55d6d 100644
> --- a/drivers/hwtracing/coresight/Kconfig
> +++ b/drivers/hwtracing/coresight/Kconfig
> @@ -89,4 +89,18 @@ config CORESIGHT_STM
> logging useful software events or data coming from various entities
> in the system, possibly running different OSs
>
> +config CORESIGHT_CPU_DEBUG
> + tristate "CoreSight CPU Debug driver"
> + depends on ARM || ARM64
> + depends on DEBUG_FS
> + help
> + This driver provides support for coresight debugging module. This
> + is primarily used to dump sample-based profiling registers when
> + system triggers panic, the driver will parse context registers so
> + can quickly get to know program counter (PC), secure state,
> + exception level, etc. Before use debugging functionality, platform
> + needs to ensure the clock domain and power domain are enabled
> + properly, please refer Documentation/trace/coresight-cpu-debug.txt
> + for detailed description and the example for usage.
> +
> endif
> diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
> index af480d9..433d590 100644
> --- a/drivers/hwtracing/coresight/Makefile
> +++ b/drivers/hwtracing/coresight/Makefile
> @@ -16,3 +16,4 @@ obj-$(CONFIG_CORESIGHT_SOURCE_ETM4X) += coresight-etm4x.o \
> coresight-etm4x-sysfs.o
> obj-$(CONFIG_CORESIGHT_QCOM_REPLICATOR) += coresight-replicator-qcom.o
> obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o
> +obj-$(CONFIG_CORESIGHT_CPU_DEBUG) += coresight-cpu-debug.o
> diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c
> new file mode 100644
> index 0000000..b77456d
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c
> @@ -0,0 +1,670 @@
> +/*
> + * Copyright (c) 2017 Linaro Limited. All rights reserved.
> + *
> + * Author: Leo Yan <leo.yan@linaro.org>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as published by
> + * the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + */
> +#include <linux/amba/bus.h>
> +#include <linux/coresight.h>
> +#include <linux/cpu.h>
> +#include <linux/debugfs.h>
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/moduleparam.h>
> +#include <linux/pm_qos.h>
> +#include <linux/slab.h>
> +#include <linux/smp.h>
> +#include <linux/types.h>
> +#include <linux/uaccess.h>
> +
> +#include "coresight-priv.h"
> +
> +#define EDPCSR 0x0A0
> +#define EDCIDSR 0x0A4
> +#define EDVIDSR 0x0A8
> +#define EDPCSR_HI 0x0AC
> +#define EDOSLAR 0x300
> +#define EDPRCR 0x310
> +#define EDPRSR 0x314
> +#define EDDEVID1 0xFC4
> +#define EDDEVID 0xFC8
> +
> +#define EDPCSR_PROHIBITED 0xFFFFFFFF
> +
> +/* bits definition for EDPCSR */
> +#define EDPCSR_THUMB BIT(0)
> +#define EDPCSR_ARM_INST_MASK GENMASK(31, 2)
> +#define EDPCSR_THUMB_INST_MASK GENMASK(31, 1)
> +
> +/* bits definition for EDPRCR */
> +#define EDPRCR_COREPURQ BIT(3)
> +#define EDPRCR_CORENPDRQ BIT(0)
> +
> +/* bits definition for EDPRSR */
> +#define EDPRSR_DLK BIT(6)
> +#define EDPRSR_PU BIT(0)
> +
> +/* bits definition for EDVIDSR */
> +#define EDVIDSR_NS BIT(31)
> +#define EDVIDSR_E2 BIT(30)
> +#define EDVIDSR_E3 BIT(29)
> +#define EDVIDSR_HV BIT(28)
> +#define EDVIDSR_VMID GENMASK(7, 0)
> +
> +/*
> + * bits definition for EDDEVID1:PSCROffset
> + *
> + * NOTE: armv8 and armv7 have different definition for the register,
> + * so consolidate the bits definition as below:
> + *
> + * 0b0000 - Sample offset applies based on the instruction state, we
> + * rely on EDDEVID to check if EDPCSR is implemented or not
> + * 0b0001 - No offset applies.
> + * 0b0010 - No offset applies, but do not use in AArch32 mode
>
> + */
> +#define EDDEVID1_PCSR_OFFSET_MASK GENMASK(3, 0)
> +#define EDDEVID1_PCSR_OFFSET_INS_SET (0x0)
> +#define EDDEVID1_PCSR_NO_OFFSET_DIS_AARCH32 (0x2)
> +
> +/* bits definition for EDDEVID */
> +#define EDDEVID_PCSAMPLE_MODE GENMASK(3, 0)
> +#define EDDEVID_IMPL_EDPCSR (0x1)
> +#define EDDEVID_IMPL_EDPCSR_EDCIDSR (0x2)
> +#define EDDEVID_IMPL_FULL (0x3)
> +
> +#define DEBUG_WAIT_SLEEP 1000
> +#define DEBUG_WAIT_TIMEOUT 32000
> +
> +struct debug_drvdata {
> + void __iomem *base;
> + struct device *dev;
> + int cpu;
> +
> + bool edpcsr_present;
> + bool edcidsr_present;
> + bool edvidsr_present;
> + bool pc_has_offset;
> +
> + u32 edpcsr;
> + u32 edpcsr_hi;
> + u32 edprsr;
> + u32 edvidsr;
> + u32 edcidsr;
> +};
> +
> +static DEFINE_MUTEX(debug_lock);
> +static DEFINE_PER_CPU(struct debug_drvdata *, debug_drvdata);
> +static int debug_count;
> +static struct dentry *debug_debugfs_dir;
> +
> +static bool debug_enable;
> +module_param_named(enable, debug_enable, bool, 0600);
> +MODULE_PARM_DESC(enable, "Knob to enable debug functionality "
> + "(default is 0, which means is disabled by default)");
> +
> +static void debug_os_unlock(struct debug_drvdata *drvdata)
> +{
> + /* Unlocks the debug registers */
> + writel_relaxed(0x0, drvdata->base + EDOSLAR);
> +
> + /* Make sure the registers are unlocked before accessing */
> + wmb();
> +}
> +
> +/*
> + * According to ARM DDI 0487A.k, before access external debug
> + * registers should firstly check the access permission; if any
> + * below condition has been met then cannot access debug
> + * registers to avoid lockup issue:
> + *
> + * - CPU power domain is powered off;
> + * - The OS Double Lock is locked;
> + *
> + * By checking EDPRSR can get to know if meet these conditions.
> + */
> +static bool debug_access_permitted(struct debug_drvdata *drvdata)
> +{
> + /* CPU is powered off */
> + if (!(drvdata->edprsr & EDPRSR_PU))
> + return false;
> +
> + /* The OS Double Lock is locked */
> + if (drvdata->edprsr & EDPRSR_DLK)
> + return false;
> +
> + return true;
> +}
> +
> +static void debug_force_cpu_powered_up(struct debug_drvdata *drvdata)
> +{
> + u32 edprcr;
> +
> +try_again:
> +
> + /*
> + * Send request to power management controller and assert
> + * DBGPWRUPREQ signal; if power management controller has
> + * sane implementation, it should enable CPU power domain
> + * in case CPU is in low power state.
> + */
> + edprcr = readl_relaxed(drvdata->base + EDPRCR);
> + edprcr |= EDPRCR_COREPURQ;
> + writel_relaxed(edprcr, drvdata->base + EDPRCR);
> +
> + /* Wait for CPU to be powered up (timeout~=32ms) */
> + if (readx_poll_timeout_atomic(readl_relaxed, drvdata->base + EDPRSR,
> + drvdata->edprsr, (drvdata->edprsr & EDPRSR_PU),
> + DEBUG_WAIT_SLEEP, DEBUG_WAIT_TIMEOUT)) {
> + /*
> + * Unfortunately the CPU cannot be powered up, so return
> + * back and later has no permission to access other
> + * registers. For this case, should disable CPU low power
> + * states to ensure CPU power domain is enabled!
> + */
> + pr_err("%s: power up request for CPU%d failed\n",
> + __func__, drvdata->cpu);
> + return;
> + }
> +
> + /*
> + * At this point the CPU is powered up, so set the no powerdown
> + * request bit so we don't lose power and emulate power down.
> + */
> + edprcr = readl_relaxed(drvdata->base + EDPRCR);
> + edprcr |= EDPRCR_COREPURQ | EDPRCR_CORENPDRQ;
> + writel_relaxed(edprcr, drvdata->base + EDPRCR);
> +
> + drvdata->edprsr = readl_relaxed(drvdata->base + EDPRSR);
> +
> + /* The core power domain got switched off on use, try again */
> + if (unlikely(!(drvdata->edprsr & EDPRSR_PU)))
> + goto try_again;
> +}
> +
> +static void debug_read_regs(struct debug_drvdata *drvdata)
> +{
> + u32 save_edprcr;
> +
> + CS_UNLOCK(drvdata->base);
> +
> + /* Unlock os lock */
> + debug_os_unlock(drvdata);
> +
> + /* Save EDPRCR register */
> + save_edprcr = readl_relaxed(drvdata->base + EDPRCR);
> +
> + /*
> + * Ensure CPU power domain is enabled to let registers
> + * are accessiable.
> + */
> + debug_force_cpu_powered_up(drvdata);
> +
> + if (!debug_access_permitted(drvdata))
> + goto out;
> +
> + drvdata->edpcsr = readl_relaxed(drvdata->base + EDPCSR);
> +
> + /*
> + * As described in ARM DDI 0487A.k, if the processing
> + * element (PE) is in debug state, or sample-based
> + * profiling is prohibited, EDPCSR reads as 0xFFFFFFFF;
> + * EDCIDSR, EDVIDSR and EDPCSR_HI registers also become
> + * UNKNOWN state. So directly bail out for this case.
> + */
> + if (drvdata->edpcsr == EDPCSR_PROHIBITED)
> + goto out;
> +
> + /*
> + * A read of the EDPCSR normally has the side-effect of
> + * indirectly writing to EDCIDSR, EDVIDSR and EDPCSR_HI;
> + * at this point it's safe to read value from them.
> + */
> + if (IS_ENABLED(CONFIG_64BIT))
> + drvdata->edpcsr_hi = readl_relaxed(drvdata->base + EDPCSR_HI);
> +
> + if (drvdata->edcidsr_present)
> + drvdata->edcidsr = readl_relaxed(drvdata->base + EDCIDSR);
> +
> + if (drvdata->edvidsr_present)
> + drvdata->edvidsr = readl_relaxed(drvdata->base + EDVIDSR);
> +
> +out:
> + /* Restore EDPRCR register */
> + writel_relaxed(save_edprcr, drvdata->base + EDPRCR);
> +
> + CS_LOCK(drvdata->base);
> +}
> +
> +static unsigned long debug_adjust_pc(struct debug_drvdata *drvdata)
> +{
> + unsigned long arm_inst_offset = 0, thumb_inst_offset = 0;
> + unsigned long pc;
> +
> + if (IS_ENABLED(CONFIG_64BIT))
> + return (unsigned long)drvdata->edpcsr_hi << 32 |
> + (unsigned long)drvdata->edpcsr;
> +
> + pc = (unsigned long)drvdata->edpcsr;
> +
> + if (drvdata->pc_has_offset) {
> + arm_inst_offset = 8;
> + thumb_inst_offset = 4;
> + }
> +
> + /* Handle thumb instruction */
> + if (pc & EDPCSR_THUMB) {
> + pc = (pc & EDPCSR_THUMB_INST_MASK) - thumb_inst_offset;
> + return pc;
> + }
> +
> + /*
> + * Handle arm instruction offset, if the arm instruction
> + * is not 4 byte alignment then it's possible the case
> + * for implementation defined; keep original value for this
> + * case and print info for notice.
> + */
> + if (pc & BIT(1))
> + pr_emerg("Instruction offset is implementation defined\n");
> + else
> + pc = (pc & EDPCSR_ARM_INST_MASK) - arm_inst_offset;
> +
> + return pc;
> +}
> +
> +static void debug_dump_regs(struct debug_drvdata *drvdata)
> +{
> + unsigned long pc;
> +
> + pr_emerg("\tEDPRSR: %08x (Power:%s DLK:%s)\n", drvdata->edprsr,
> + drvdata->edprsr & EDPRSR_PU ? "On" : "Off",
> + drvdata->edprsr & EDPRSR_DLK ? "Lock" : "Unlock");
> +
> + if (!debug_access_permitted(drvdata)) {
> + pr_emerg("No permission to access debug registers!\n");
> + return;
> + }
> +
> + if (drvdata->edpcsr == EDPCSR_PROHIBITED) {
> + pr_emerg("CPU is in Debug state or profiling is prohibited!\n");
> + return;
> + }
> +
> + pc = debug_adjust_pc(drvdata);
> + pr_emerg("\tEDPCSR: [<%p>] %pS\n", (void *)pc, (void *)pc);
> +
> + if (drvdata->edcidsr_present)
> + pr_emerg("\tEDCIDSR: %08x\n", drvdata->edcidsr);
> +
> + if (drvdata->edvidsr_present)
> + pr_emerg("\tEDVIDSR: %08x (State:%s Mode:%s Width:%dbits VMID:%x)\n",
> + drvdata->edvidsr,
> + drvdata->edvidsr & EDVIDSR_NS ? "Non-secure" : "Secure",
> + drvdata->edvidsr & EDVIDSR_E3 ? "EL3" :
> + (drvdata->edvidsr & EDVIDSR_E2 ? "EL2" : "EL1/0"),
> + drvdata->edvidsr & EDVIDSR_HV ? 64 : 32,
> + drvdata->edvidsr & (u32)EDVIDSR_VMID);
> +}
> +
> +static void debug_init_arch_data(void *info)
> +{
> + struct debug_drvdata *drvdata = info;
> + u32 mode, pcsr_offset;
> + u32 eddevid, eddevid1;
> +
> + CS_UNLOCK(drvdata->base);
> +
> + /* Read device info */
> + eddevid = readl_relaxed(drvdata->base + EDDEVID);
> + eddevid1 = readl_relaxed(drvdata->base + EDDEVID1);
> +
> + CS_LOCK(drvdata->base);
> +
> + /* Parse implementation feature */
> + mode = eddevid & EDDEVID_PCSAMPLE_MODE;
> + pcsr_offset = eddevid1 & EDDEVID1_PCSR_OFFSET_MASK;
> +
> + drvdata->edpcsr_present = false;
> + drvdata->edcidsr_present = false;
> + drvdata->edvidsr_present = false;
> + drvdata->pc_has_offset = false;
> +
> + switch (mode) {
> + case EDDEVID_IMPL_FULL:
> + drvdata->edvidsr_present = true;
> + /* Fall through */
> + case EDDEVID_IMPL_EDPCSR_EDCIDSR:
> + drvdata->edcidsr_present = true;
> + /* Fall through */
> + case EDDEVID_IMPL_EDPCSR:
> + /*
> + * In ARM DDI 0487A.k, the EDDEVID1.PCSROffset is used to
> + * define if has the offset for PC sampling value; if read
> + * back EDDEVID1.PCSROffset == 0x2, then this means the debug
> + * module does not sample the instruction set state when
> + * armv8 CPU in AArch32 state.
> + */
> + drvdata->edpcsr_present =
> + ((IS_ENABLED(CONFIG_64BIT) && pcsr_offset != 0) ||
> + (pcsr_offset != EDDEVID1_PCSR_NO_OFFSET_DIS_AARCH32));
> +
> + drvdata->pc_has_offset =
> + (pcsr_offset == EDDEVID1_PCSR_OFFSET_INS_SET);
> + break;
> + default:
> + break;
> + }
> +}
> +
> +/*
> + * Dump out information on panic.
> + */
> +static int debug_notifier_call(struct notifier_block *self,
> + unsigned long v, void *p)
> +{
> + int cpu;
> + struct debug_drvdata *drvdata;
> +
> + mutex_lock(&debug_lock);
> +
> + /* Bail out if the functionality is disabled */
> + if (!debug_enable)
> + goto skip_dump;
> +
> + pr_emerg("ARM external debug module:\n");
> +
> + for_each_possible_cpu(cpu) {
> + drvdata = per_cpu(debug_drvdata, cpu);
> + if (!drvdata)
> + continue;
> +
> + pr_emerg("CPU[%d]:\n", drvdata->cpu);
> +
> + debug_read_regs(drvdata);
> + debug_dump_regs(drvdata);
> + }
> +
> +skip_dump:
> + mutex_unlock(&debug_lock);
> + return 0;
> +}
> +
> +static struct notifier_block debug_notifier = {
> + .notifier_call = debug_notifier_call,
> +};
> +
> +static int debug_enable_func(void)
> +{
> + struct debug_drvdata *drvdata;
> + int cpu, ret = 0;
> +
> + for_each_possible_cpu(cpu) {
> + drvdata = per_cpu(debug_drvdata, cpu);
> + if (!drvdata)
> + continue;
> +
> + ret = pm_runtime_get_sync(drvdata->dev);
> + if (ret < 0) {
> + pm_runtime_put_noidle(drvdata->dev);
> + goto err;
> + }
Here pm_runtime_get_sync() has failed and as such there is no need to call
pm_runtime_put_noidle() on it. On the flip side we need to call it on all the
other CPUs that have been enabled before that. To fix this I suggest to
use a cpumask variable and set the bit for the CPUs that are successful. When
you encounter an error you call pm_runtime_put_noidle() for all the CPUs in the
cpumask variable that you have been keeping.
> + }
> +
> +err:
> + return ret;
> +}
> +
> +static int debug_disable_func(void)
> +{
> + struct debug_drvdata *drvdata;
> + int cpu, ret = 0;
> +
> + for_each_possible_cpu(cpu) {
> + drvdata = per_cpu(debug_drvdata, cpu);
> + if (!drvdata)
> + continue;
> +
> + ret = pm_runtime_put(drvdata->dev);
> + if (ret < 0)
> + goto err;
> + }
I would not bail out when an error has been encountered since there is nothing
you can do anyway. So record the error (as you did) and keep circling through
the list of processors. That way you can call pm_runtime_put() successfully on
other CPUs.
> +
> +err:
> + return ret;
> +}
> +
> +static ssize_t debug_func_knob_write(struct file *f,
> + const char __user *buf, size_t count, loff_t *ppos)
> +{
> + u8 val;
> + int ret;
> +
> + ret = kstrtou8_from_user(buf, count, 2, &val);
> + if (ret)
> + return ret;
> +
> + mutex_lock(&debug_lock);
> +
> + if (val == debug_enable)
> + goto out;
> +
> + if (val)
> + ret = debug_enable_func();
> + else
> + ret = debug_disable_func();
> +
> + if (ret) {
> + pr_err("%s: unable to %s debug function: %d\n",
> + __func__, val ? "enable" : "disable", ret);
> + goto err;
> + }
> +
> + debug_enable = val;
> +out:
> + ret = count;
> +err:
> + mutex_unlock(&debug_lock);
> + return ret;
> +}
> +
> +static ssize_t debug_func_knob_read(struct file *f,
> + char __user *ubuf, size_t count, loff_t *ppos)
> +{
> + ssize_t ret;
> + char buf[3];
> +
> + mutex_lock(&debug_lock);
> +
> + snprintf(buf, sizeof(buf), "%d\n", debug_enable);
> + ret = simple_read_from_buffer(ubuf, count, ppos, buf, sizeof(buf));
> +
> + mutex_unlock(&debug_lock);
Move this before simple_read_from_buffer()
> + return ret;
> +}
> +
> +static const struct file_operations debug_func_knob_fops = {
> + .open = simple_open,
> + .read = debug_func_knob_read,
> + .write = debug_func_knob_write,
> +};
> +
> +static int debug_func_init(void)
> +{
> + struct dentry *file;
> + int ret;
> +
> + /* Create debugfs node */
> + debug_debugfs_dir = debugfs_create_dir("coresight_cpu_debug", NULL);
> + if (!debug_debugfs_dir) {
> + pr_err("%s: unable to create debugfs directory\n", __func__);
> + return -ENOMEM;
> + }
> +
> + file = debugfs_create_file("enable", 0644, debug_debugfs_dir, NULL,
> + &debug_func_knob_fops);
> + if (!file) {
> + pr_err("%s: unable to create enable knob file\n", __func__);
> + ret = -ENOMEM;
> + goto err;
> + }
> +
> + /* Register function to be called for panic */
> + ret = atomic_notifier_chain_register(&panic_notifier_list,
> + &debug_notifier);
> + if (ret) {
> + pr_err("%s: unable to register notifier: %d\n",
> + __func__, ret);
> + goto err;
> + }
> +
> + return 0;
> +
> +err:
> + debugfs_remove_recursive(debug_debugfs_dir);
> + return ret;
> +}
> +
> +static void debug_func_exit(void)
> +{
> + atomic_notifier_chain_unregister(&panic_notifier_list,
> + &debug_notifier);
> + debugfs_remove_recursive(debug_debugfs_dir);
> +}
> +
> +static int debug_probe(struct amba_device *adev, const struct amba_id *id)
> +{
> + void __iomem *base;
> + struct device *dev = &adev->dev;
> + struct debug_drvdata *drvdata;
> + struct resource *res = &adev->res;
> + struct device_node *np = adev->dev.of_node;
> + int ret;
> +
> + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
> + if (!drvdata)
> + return -ENOMEM;
> +
> + drvdata->cpu = np ? of_coresight_get_cpu(np) : 0;
> + if (per_cpu(debug_drvdata, drvdata->cpu)) {
> + dev_err(dev, "CPU%d drvdata has been initialized, "
> + "may be caused by binding wrong CPU node in the DT\n",
> + drvdata->cpu);
> + return -EBUSY;
> + }
> +
> + drvdata->dev = &adev->dev;
> + amba_set_drvdata(adev, drvdata);
> +
> + /* Validity for the resource is already checked by the AMBA core */
> + base = devm_ioremap_resource(dev, res);
> + if (IS_ERR(base))
> + return PTR_ERR(base);
> +
> + drvdata->base = base;
> +
> + get_online_cpus();
> + per_cpu(debug_drvdata, drvdata->cpu) = drvdata;
> + ret = smp_call_function_single(drvdata->cpu, debug_init_arch_data,
> + drvdata, 1);
> + put_online_cpus();
> +
> + if (ret) {
> + dev_err(dev, "CPU%d debug arch init failed\n", drvdata->cpu);
> + goto err;
> + }
> +
> + if (!drvdata->edpcsr_present) {
> + dev_err(dev, "CPU%d sample-based profiling isn't implemented\n",
> + drvdata->cpu);
> + ret = -ENXIO;
> + goto err;
> + }
> +
> + if (!debug_count++) {
> + ret = debug_func_init();
> + if (ret)
> + goto err_func_init;
> + }
> +
> + mutex_lock(&debug_lock);
> + if (!debug_enable)
> + pm_runtime_put(dev);
I would add a comment here - that way your intentions are clear to everyone.
> + mutex_unlock(&debug_lock);
> +
> + dev_info(dev, "Coresight debug-CPU%d initialized\n", drvdata->cpu);
> + return 0;
> +
> +err_func_init:
> + debug_count--;
> +err:
> + per_cpu(debug_drvdata, drvdata->cpu) = NULL;
> + return ret;
> +}
> +
> +static int debug_remove(struct amba_device *adev)
> +{
> + struct device *dev = &adev->dev;
> + struct debug_drvdata *drvdata = amba_get_drvdata(adev);
> +
> + per_cpu(debug_drvdata, drvdata->cpu) = NULL;
> +
> + mutex_lock(&debug_lock);
> + if (debug_enable)
> + pm_runtime_put(dev);
> + mutex_unlock(&debug_lock);
> +
> + if (!--debug_count)
> + debug_func_exit();
> +
> + return 0;
> +}
> +
> +static struct amba_id debug_ids[] = {
> + { /* Debug for Cortex-A53 */
> + .id = 0x000bbd03,
> + .mask = 0x000fffff,
> + },
> + { /* Debug for Cortex-A57 */
> + .id = 0x000bbd07,
> + .mask = 0x000fffff,
> + },
> + { /* Debug for Cortex-A72 */
> + .id = 0x000bbd08,
> + .mask = 0x000fffff,
> + },
> + { 0, 0 },
> +};
> +
> +static struct amba_driver debug_driver = {
> + .drv = {
> + .name = "coresight-cpu-debug",
> + .suppress_bind_attrs = true,
> + },
> + .probe = debug_probe,
> + .remove = debug_remove,
> + .id_table = debug_ids,
> +};
> +
> +module_amba_driver(debug_driver);
> +
> +MODULE_AUTHOR("Leo Yan <leo.yan@linaro.org>");
> +MODULE_DESCRIPTION("ARM Coresight CPU Debug Driver");
> +MODULE_LICENSE("GPL");
> --
> 2.7.4
>
^ permalink raw reply
* Re: [PATCH 1/2] dt/bindings: Add bindings for Broadcom STB DRAM Sensors
From: Markus Mayer @ 2017-05-03 22:29 UTC (permalink / raw)
To: Rob Herring
Cc: Jean Delvare, Guenter Roeck, Mark Rutland, Broadcom Kernel List,
Linux HWMON List, Device Tree List, ARM Kernel List,
Linux Kernel Mailing List, Florian Fainelli
In-Reply-To: <90f011d6-9241-e860-7a0e-2fb52c2337ce-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Hi Rob,
On 27 April 2017 at 15:00, Florian Fainelli <f.fainelli-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> On 04/27/2017 02:57 PM, Rob Herring wrote:
>>>>> +Optional properties:
>>>>> + - cell-index: the index of the DPFE instance; will default to 0 if not set
>>
>> Don't use cell-index. It's not a valid property for FDT (only real
>> OpenFirmware).
>
> My bad, I was advising Markus to use this property since it was largely
> used throughout Documentation/devicetree/bindings/. What would be a more
> appropriate way to have the same information? Aliases?
Hopefully this will be the last time we need to pester you about this.
What should we be using instead of cell-index to identify multiple
instances of a device?
To give you an idea of what the code looks like right now:
ret = of_property_read_u32(dev->of_node, "cell-index", &index);
if (ret)
index = 0;
[...]
dev_set_name(dpfe_dev, "dpfe%u", index);
ret = device_register(dpfe_dev);
Enumerating the devices like this is what we are after.
Thanks,
-Markus
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v8 2/7] doc: Add documentation for Coresight CPU debug
From: Mathieu Poirier @ 2017-05-03 22:29 UTC (permalink / raw)
To: Leo Yan
Cc: Jonathan Corbet, Rob Herring, Mark Rutland, Wei Xu,
Catalin Marinas, Will Deacon, Andy Gross, David Brown,
Greg Kroah-Hartman, Suzuki K Poulose, Stephen Boyd,
linux-doc-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
linux-soc-u79uwXL29TY76Z2rM5mHXA, Mike Leach, Sudeep Holla
In-Reply-To: <1493719717-27698-3-git-send-email-leo.yan-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
On Tue, May 02, 2017 at 06:08:32PM +0800, Leo Yan wrote:
> Update kernel-parameters.txt to add new parameter:
> coresight_cpu_debug.enable is a knob to enable debugging at boot time.
>
> Add detailed documentation, which contains the implementation, Mike
> Leach excellent summary for "clock and power domain". At the end some
> examples on how to enable the debugging functionality are provided.
>
> Suggested-by: Mike Leach <mike.leach-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Signed-off-by: Leo Yan <leo.yan-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---
> Documentation/admin-guide/kernel-parameters.txt | 7 +
> Documentation/trace/coresight-cpu-debug.txt | 174 ++++++++++++++++++++++++
Please add coresight-cpu-debug.txt to the list of maintained files in
MAINTAINERS. Moreover I'm pretty sure John will want you to split this patch in
two, i.e one patch for kernel-parameters.txt and another for
coresight-cpu-debug.txt
> 2 files changed, 181 insertions(+)
> create mode 100644 Documentation/trace/coresight-cpu-debug.txt
>
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index facc20a..cf90146 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -650,6 +650,13 @@
> /proc/<pid>/coredump_filter.
> See also Documentation/filesystems/proc.txt.
>
> + coresight_cpu_debug.enable
> + [ARM,ARM64]
> + Format: <bool>
> + Enable/disable the CPU sampling based debugging.
> + 0: default value, disable debugging
> + 1: enable debugging at boot time
> +
> cpuidle.off=1 [CPU_IDLE]
> disable the cpuidle sub-system
>
> diff --git a/Documentation/trace/coresight-cpu-debug.txt b/Documentation/trace/coresight-cpu-debug.txt
> new file mode 100644
> index 0000000..0426d50
> --- /dev/null
> +++ b/Documentation/trace/coresight-cpu-debug.txt
> @@ -0,0 +1,174 @@
> + Coresight CPU Debug Module
> + ==========================
> +
> + Author: Leo Yan <leo.yan-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> + Date: April 5th, 2017
> +
> +Introduction
> +------------
> +
> +Coresight CPU debug module is defined in ARMv8-a architecture reference manual
> +(ARM DDI 0487A.k) Chapter 'Part H: External debug', the CPU can integrate
> +debug module and it is mainly used for two modes: self-hosted debug and
> +external debug. Usually the external debug mode is well known as the external
> +debugger connects with SoC from JTAG port; on the other hand the program can
> +explore debugging method which rely on self-hosted debug mode, this document
> +is to focus on this part.
> +
> +The debug module provides sample-based profiling extension, which can be used
> +to sample CPU program counter, secure state and exception level, etc; usually
> +every CPU has one dedicated debug module to be connected. Based on self-hosted
> +debug mechanism, Linux kernel can access these related registers from mmio
> +region when the kernel panic happens. The callback notifier for kernel panic
> +will dump related registers for every CPU; finally this is good for assistant
> +analysis for panic.
> +
> +
> +Implementation
> +--------------
> +
> +- During driver registration, use EDDEVID and EDDEVID1 two device ID
> + registers to decide if sample-based profiling is implemented or not. On some
> + platforms this hardware feature is fully or partialy implemented; and if
> + this feature is not supported then registration will fail.
> +
> +- When write this doc, the debug driver mainly relies on three sampling
> + registers. The kernel panic callback notifier gathers info from EDPCSR
> + EDVIDSR and EDCIDSR; from EDPCSR we can get program counter, EDVIDSR has
> + information for secure state, exception level, bit width, etc; EDCIDSR is
> + context ID value which contains the sampled value of CONTEXTIDR_EL1.
> +
> +- The driver supports CPU running mode with either AArch64 or AArch32. The
> + registers naming convention is a bit different between them, AArch64 uses
> + 'ED' for register prefix (ARM DDI 0487A.k, chapter H9.1) and AArch32 uses
> + 'DBG' as prefix (ARM DDI 0487A.k, chapter G5.1). The driver is unified to
> + use AArch64 naming convention.
> +
> +- ARMv8-a (ARM DDI 0487A.k) and ARMv7-a (ARM DDI 0406C.b) have different
> + register bits definition. So the driver consolidates two difference:
> +
> + If PCSROffset=0b0000, on ARMv8-a the feature of EDPCSR is not implemented;
> + but ARMv7-a defines "PCSR samples are offset by a value that depends on the
> + instruction set state". For ARMv7-a, the driver checks furthermore if CPU
> + runs with ARM or thumb instruction set and calibrate PCSR value, the
> + detailed description for offset is in ARMv7-a ARM (ARM DDI 0406C.b) chapter
> + C11.11.34 "DBGPCSR, Program Counter Sampling Register".
> +
> + If PCSROffset=0b0010, ARMv8-a defines "EDPCSR implemented, and samples have
> + no offset applied and do not sample the instruction set state in AArch32
> + state". So on ARMv8 if EDDEVID1.PCSROffset is 0b0010 and the CPU operates
> + in AArch32 state, EDPCSR is not sampled; when the CPU operates in AArch64
> + state EDPCSR is sampled and no offset are applied.
> +
> +
> +Clock and power domain
> +----------------------
> +
> +Before accessing debug registers, we should ensure the clock and power domain
> +have been enabled properly. In ARMv8-a ARM (ARM DDI 0487A.k) chapter 'H9.1
> +Debug registers', the debug registers are spread into two domains: the debug
> +domain and the CPU domain.
> +
> + +---------------+
> + | |
> + | |
> + +----------+--+ |
> + dbg_clk -->| |**| |<-- cpu_clk
> + | Debug |**| CPU |
> + dbg_pd -->| |**| |<-- cpu_pd
> + +----------+--+ |
> + | |
> + | |
> + +---------------+
> +
> +For debug domain, the user uses DT binding "clocks" and "power-domains" to
> +specify the corresponding clock source and power supply for the debug logic.
> +The driver calls the pm_runtime_{put|get} operations as needed to handle the
> +debug power domain.
> +
> +For CPU domain, the different SoC designs have different power management
> +schemes and finally this heavily impacts external debug module. So we can
> +divide into below cases:
> +
> +- On systems with a sane power controller which can behave correctly with
> + respect to CPU power domain, the CPU power domain can be controlled by
> + register EDPRCR in driver. The driver firstly writes bit EDPRCR.COREPURQ
> + to power up the CPU, and then writes bit EDPRCR.CORENPDRQ for emulation
> + of CPU power down. As result, this can ensure the CPU power domain is
> + powered on properly during the period when access debug related registers;
> +
> +- Some designs will power down an entire cluster if all CPUs on the cluster
> + are powered down - including the parts of the debug registers that should
> + remain powered in the debug power domain. The bits in EDPRCR are not
> + respected in these cases, so these designs do not support debug over
> + power down in the way that the CoreSight / Debug designers anticipated.
> + This means that even checking EDPRSR has the potential to cause a bus hang
> + if the target register is unpowered.
> +
> + In this case, accessing to the debug registers while they are not powered
> + is a recipe for disaster; so we need preventing CPU low power states at boot
> + time or when user enable module at the run time. Please see chapter
> + "How to use the module" for detailed usage info for this.
> +
> +
> +Device Tree Bindings
> +--------------------
> +
> +See Documentation/devicetree/bindings/arm/coresight-cpu-debug.txt for details.
> +
> +
> +How to use the module
> +---------------------
> +
> +If you want to enable debugging functionality at boot time, you can add
> +"coresight_cpu_debug.enable=1" to the kernel command line parameter.
> +
> +The driver also can work as module, so can enable the debugging when insmod
> +module:
> +# insmod coresight_cpu_debug.ko debug=1
> +
> +When boot time or insmod module you have not enabled the debugging, the driver
> +uses the debugfs file system to provide a knob to dynamically enable or disable
> +debugging:
> +
> +To enable it, write a '1' into /sys/kernel/debug/coresight_cpu_debug/enable:
> +# echo 1 > /sys/kernel/debug/coresight_cpu_debug/enable
> +
> +To disable it, write a '0' into /sys/kernel/debug/coresight_cpu_debug/enable:
> +# echo 0 > /sys/kernel/debug/coresight_cpu_debug/enable
> +
> +As explained in chapter "Clock and power domain", if you are working on one
> +platform which has idle states to power off debug logic and the power
> +controller cannot work well for the request from EDPRCR, then you should
> +firstly constraint CPU idle states before enable CPU debugging feature; so can
> +ensure the accessing to debug logic.
> +
> +If you want to limit idle states at boot time, you can use "nohlt" or
> +"cpuidle.off=1" in the kernel command line.
> +
> +At the runtime you can disable idle states with below methods:
> +
> +Set latency request to /dev/cpu_dma_latency to disable all CPUs specific idle
> +states (if latency = 0uS then disable all idle states):
> +# echo "what_ever_latency_you_need_in_uS" > /dev/cpu_dma_latency
> +
> +Disable specific CPU's specific idle state:
> +# echo 1 > /sys/devices/system/cpu/cpu$cpu/cpuidle/state$state/disable
> +
> +
> +Output format
> +-------------
> +
> +Here is an example of the debugging output format:
> +
> +ARM external debug module:
> +CPU[0]:
> + EDPRSR: 0000000b (Power:On DLK:Unlock)
> + EDPCSR: [<ffff00000808eb54>] handle_IPI+0xe4/0x150
> + EDCIDSR: 00000000
> + EDVIDSR: 90000000 (State:Non-secure Mode:EL1/0 Width:64bits VMID:0)
> +CPU[1]:
> + EDPRSR: 0000000b (Power:On DLK:Unlock)
> + EDPCSR: [<ffff0000087a64c0>] debug_notifier_call+0x108/0x288
> + EDCIDSR: 00000000
> + EDVIDSR: 90000000 (State:Non-secure Mode:EL1/0 Width:64bits VMID:0)
> --
> 2.7.4
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] of/unittest: Missing unlocks on error
From: Frank Rowand @ 2017-05-04 0:05 UTC (permalink / raw)
To: Dan Carpenter, Rob Herring
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
kernel-janitors-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170503194950.4xbdbwybvx6dkadx@mwanda>
On 05/03/17 12:49, Dan Carpenter wrote:
> Static checkers complain that we should unlock before returning. Which
> is true.
>
> Signed-off-by: Dan Carpenter <dan.carpenter-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>
>
> diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
> index 12597ff8cfb0..425338d6286d 100644
> --- a/drivers/of/unittest.c
> +++ b/drivers/of/unittest.c
> @@ -2210,14 +2210,14 @@ static __init void of_unittest_overlay_high_level(void)
> unittest(0,
> "duplicate property '%s' in overlay_base node __symbols__",
> prop->name);
> - return;
> + goto err_unlock;
> }
> ret = __of_add_property_sysfs(of_symbols, prop);
> if (ret) {
> unittest(0,
> "unable to add property '%s' in overlay_base node __symbols__ to sysfs",
> prop->name);
> - return;
> + goto err_unlock;
> }
> }
> }
> @@ -2232,6 +2232,10 @@ static __init void of_unittest_overlay_high_level(void)
>
> unittest(overlay_data_add(2),
> "Adding overlay 'overlay_bad_phandle' failed\n");
> + return;
> +
> +err_unlock:
> + mutex_unlock(&of_mutex);
> }
>
> #else
>
Thanks Dan.
Reviewed-by: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCHv2 1/2] Input: pwm-vibra: new driver
From: Tony Lindgren @ 2017-05-04 0:39 UTC (permalink / raw)
To: Sebastian Reichel
Cc: Sebastian Reichel, Dmitry Torokhov, Rob Herring, linux-input,
linux-omap, devicetree, linux-kernel
In-Reply-To: <20170503111128.15385-2-sebastian.reichel@collabora.co.uk>
* Sebastian Reichel <sebastian.reichel@collabora.co.uk> [170503 04:14]:
> Provide a simple driver for PWM controllable vibrators. It
> will be used by Motorola Droid 4.
>
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
> ---
> Changes since PATCHv1:
> - move driver removal code to input->close function
> - mark PM functions __maybe_unused and drop #ifdef CONFIG_PM_SLEEP
> - remove duplicate NULL check for vibrator in probe function
> - cancel work in suspend function
I'm getting this if CONFIG_INPUT_FF_MEMLESS is not selected:
ERROR: "input_ff_create_memless" [drivers/input/misc/pwm-vibra.ko] undefined!
Other than that works for me with your test app after
modprobe of pwm-omap-dmtimer and ff_memless:
Tested-by: Tony Lindgren <tony@atomide.com>
^ permalink raw reply
* Re: [PATCH][v2] arm64: dts: ls2081ardb: Add DTS support for NXP LS2081ARDB
From: Shawn Guo @ 2017-05-04 1:20 UTC (permalink / raw)
To: Priyanka Jain
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, robh-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8, leoyang.li-3arQi8VN3Tc,
stuart.yoder-3arQi8VN3Tc,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
scott.wood-3arQi8VN3Tc
In-Reply-To: <1493367930-10612-1-git-send-email-priyanka.jain-3arQi8VN3Tc@public.gmane.org>
On Fri, Apr 28, 2017 at 01:55:30PM +0530, Priyanka Jain wrote:
> This patch add support for NXP LS2081ARDB board which has
> LS2081A SoC.
>
> LS2081A SoC is 40-pin derivative of LS2088A SoC
> So, from functional perspective both are same.
> Hence,ls2088a SoC dtsi files are included from ls2081ARDB dts
>
> Signed-off-by: Priyanka Jain <priyanka.jain-3arQi8VN3Tc@public.gmane.org>
The following recipients couldn't be delivered. Please drop them in the
next posting.
scott.wood-3arQi8VN3Tc@public.gmane.org
stuart.yoder-3arQi8VN3Tc@public.gmane.org
Shawn
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCHv2 0/3] Intel FPGA VIP Frame Buffer II DRM Driver
From: Ong, Hean Loong @ 2017-05-04 1:39 UTC (permalink / raw)
To: eric-WhKQ6XTQaPysTnJN9+BGXg@public.gmane.org,
dinguyen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org, Vetter, Daniel,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org
Cc: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
Ong, Hean Loong, Loh, Tien Hock,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <87shklznuo.fsf-omZaPlIz5HhaEpDpdNBo/KxOck334EZe@public.gmane.org>
On Wed, 2017-05-03 at 13:28 -0700, Eric Anholt wrote:
> hean.loong.ong@intel.com writes:
>
> >
> > From: Ong Hean Loong <hean.loong.ong@intel.com>
> >
> > Hi,
> >
> > The new Intel Arria10 SOC FPGA devkit has a Display Port IP
> > component
> > which requires a new driver. This is a virtual driver in which the
> > FGPA hardware would enable the Display Port based on the
> > information
> > and data provided from the DRM frame buffer from the OS. Basically
> > all
> > all information with reagrds to resolution and bits per pixel are
> > pre-configured on the FPGA design and these information are fed to
> > the driver via the device tree information as part of the hardware
> > information.
> I started reviewing the code, but I want to make sure I understand
> what's going on:
>
> This IP core isn't displaying contents from system memory on some
> sort
> of actual physical display, right? It's a core that takes some input
> video stream (not described in the DT or in this driver) and stores
> it
> to memory?
If the IP Core you are referring to is some form of GPU then in this
case we are using the Intel FPGA Display Port Framebuffer IP. It does
display contents streamed from the ARM/Linux system to the Display Port
of the physical Monitor.
Below a simple illustration of the system:
ARM/Linux --DMA-->Intel FPGA Display Port Framebuffer IP
|
|
Physical Connection
Display Port
^ permalink raw reply
* Re: [PATCH] driver: input :touchscreen : Change Raydium firmware update parameter
From: jeffrey.lin @ 2017-05-04 1:43 UTC (permalink / raw)
To: dmitry.torokhov, bleung, groeck, Katherine.Hsieh
Cc: jeffrey.lin, ealin.chiu, calvin.tseng, KP.li, albert.shieh,
linux-kernel, linux-input, devicetree
In-Reply-To: <20170503153717.328-1-jeffrey.lin@rad-ic.com>
Hi Guenter:
>> Change boot mode trigger parameter of Raydium firmware update.
>>
>That is a bit vague. What is changed to what, and why ?
>In other words, what prevents someone else from changing it back to
>the old value, using the same description ?
This bit control erase type as doing firmware update. We want just reserve more infomation after pass through production line. This's convenient
for debug, so that it's okay as some one use old version.
>> Signed-off-by: jeffrey.lin <jeffrey.lin@rad-ic.com>
>> ---
>> drivers/input/touchscreen/raydium_i2c_ts.c | 4 ++--
>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/input/touchscreen/raydium_i2c_ts.c b/drivers/input/touchscreen/raydium_i2c_ts.c
>> index a99fb5cac5a0..8a81257634ba 100644
>> --- a/drivers/input/touchscreen/raydium_i2c_ts.c
>> +++ b/drivers/input/touchscreen/raydium_i2c_ts.c
>> @@ -450,7 +450,7 @@ static bool raydium_i2c_boot_trigger(struct i2c_client *client)
>> { 0x08, 0x04, 0x09, 0x00, 0x50, 0xA5 },
>> { 0x08, 0x0C, 0x09, 0x00, 0x50, 0x00 },
>> { 0x06, 0x01, 0x00, 0x00, 0x00, 0x00 },
>> - { 0x02, 0xA2, 0x00, 0x00, 0x00, 0x00 },
>> + { 0x02, 0xA1, 0x00, 0x00, 0x00, 0x00 },
>> };
Thanks.
Jeffrey
^ permalink raw reply
* Re: [PATCHv2 2/3] ARM: drm: Intel FPGA VIP Frame Buffer II drm driver
From: Ong, Hean Loong @ 2017-05-04 1:53 UTC (permalink / raw)
To: eric-WhKQ6XTQaPysTnJN9+BGXg@public.gmane.org,
dinguyen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org, Vetter, Daniel,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org
Cc: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
Loh, Tien Hock, Ong-CC+yJ3UmIYqDUpFQwHEjaQ@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <87o9v9znl1.fsf-omZaPlIz5HhaEpDpdNBo/KxOck334EZe@public.gmane.org>
On Wed, 2017-05-03 at 13:34 -0700, Eric Anholt wrote:
> hean.loong.ong@intel.com writes:
>
> >
> > From: "Ong, Hean Loong" <hean.loong.ong@intel.com>
> >
> > Driver for Intel FPGA Video and Image Processing
> > Suite Frame Buffer II. The driver only supports the Intel
> > Arria10 devkit and its variants. This driver can be either
> > loaded staticlly or in modules. The OF device tree binding
> > is located at:
> > Documentation/devicetree/bindings/display/altr,vip-fb2.txt
> >
> > Signed-off-by: Ong, Hean Loong <hean.loong.ong@intel.com>
> I'm not sure if this driver is going to make sense as-is, if it
> doesn't
> actually do display of planes from system memory. But in case I was
> wrong, here's my review:
>
>
> >
> > diff --git a/drivers/gpu/drm/ivip/intel_vip_conn.c
> > b/drivers/gpu/drm/ivip/intel_vip_conn.c
> > new file mode 100644
> > index 0000000..499d3b4
> > --- /dev/null
> > +++ b/drivers/gpu/drm/ivip/intel_vip_conn.c
> > @@ -0,0 +1,96 @@
> > +/*
> > + * intel_vip_conn.c -- Intel Video and Image Processing(VIP)
> > + * Frame Buffer II driver
> > + *
> > + * This driver supports the Intel VIP Frame Reader component.
> > + * More info on the hardware can be found in the Intel Video
> > + * and Image Processing Suite User Guide at this address
> > + * http://www.altera.com/literature/ug/ug_vip.pdf.
> > + *
> > + * This program is free software; you can redistribute it and/or
> > modify it
> > + * under the terms and conditions of the GNU General Public
> > License,
> > + * version 2, as published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope it will be useful, but
> > WITHOUT
> > + * ANY WARRANTY; without even the implied warranty of
> > MERCHANTABILITY or
> > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
> > License for
> > + * more details.
> > + *
> > + * Authors:
> > + * Ong, Hean-Loong <hean.loong.ong@intel.com>
> > + *
> > + */
> > +
> > +#include <linux/init.h>
> > +#include <linux/kernel.h>
> > +#include <drm/drm_atomic_helper.h>
> > +#include <drm/drm_crtc_helper.h>
> > +#include <drm/drm_encoder_slave.h>
> > +#include <drm/drm_plane_helper.h>
> > +
> > +static enum drm_connector_status
> > +intelvipfb_drm_connector_detect(struct drm_connector *connector,
> > bool force)
> > +{
> > + return connector_status_connected;
> > +}
> > +
> > +static void intelvipfb_drm_connector_destroy(struct drm_connector
> > *connector)
> > +{
> > + drm_connector_unregister(connector);
> > + drm_connector_cleanup(connector);
> > +}
> > +
> > +static const struct drm_connector_funcs
> > intelvipfb_drm_connector_funcs = {
> > + .dpms = drm_helper_connector_dpms,
> > + .reset = drm_atomic_helper_connector_reset,
> > + .detect = intelvipfb_drm_connector_detect,
> > + .fill_modes = drm_helper_probe_single_connector_modes,
> > + .destroy = intelvipfb_drm_connector_destroy,
> > + .atomic_duplicate_state =
> > drm_atomic_helper_connector_duplicate_state,
> > + .atomic_destroy_state =
> > drm_atomic_helper_connector_destroy_state,
> > +};
> > +
> > +static int intelvipfb_drm_connector_get_modes(struct drm_connector
> > *connector)
> > +{
> > + struct drm_device *drm = connector->dev;
> > + int count;
> > +
> > + count = drm_add_modes_noedid(connector, drm-
> > >mode_config.max_width,
> > + drm->mode_config.max_height);
> > + drm_set_preferred_mode(connector, drm-
> > >mode_config.max_width,
> > + drm->mode_config.max_height);
> > + return count;
> > +}
> You're adding a bunch of modes here, but I don't see anywhere in the
> driver that you change the resolution being scanned out.
>
> If you can't change resolution, then I'd probably use drm_gtf_mode()
> or
> something to generate just the one mode (do you have a vrefresh for
> it?). Also, in the simple display pipe's atomic_check, make sure
> that
> the mode chosen is the width/height you can support.
>
From the drivers perpective the resolution is dependant on how the FPGA
Display Port Framebuffer hardwware IP is designed. I would take a look
into how drm_gtf_mode() works compared to this.
> >
> > +
> > +static const struct drm_connector_helper_funcs
> > +intelvipfb_drm_connector_helper_funcs = {
> > + .get_modes = intelvipfb_drm_connector_get_modes,
> > +};
> > +
> > +struct drm_connector *
> > +intelvipfb_conn_setup(struct drm_device *drm)
> > +{
> > + struct drm_connector *conn;
> > + int ret;
> > +
> > + conn = devm_kzalloc(drm->dev, sizeof(*conn), GFP_KERNEL);
> > + if (IS_ERR(conn))
> > + return NULL;
> > +
> > + ret = drm_connector_init(drm, conn,
> > &intelvipfb_drm_connector_funcs,
> > + DRM_MODE_CONNECTOR_DisplayPort);
> Are you actually outputting DisplayPort
> (https://en.wikipedia.org/wiki/DisplayPort)?
>
> You probably want something else from the DRM_MODE_CONNECTOR list, or
> maybe just DRM_MODE_CONNECTOR_Unknown.
>
The Physical Connector is a Display Port connector. A simple
introduction of the product is found here.
https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literat
ure/an/an793.pdf
>
> >
> > + if (ret < 0) {
> > + dev_err(drm->dev, "failed to initialize drm
> > connector\n");
> > + ret = -ENOMEM;
> > + goto error_connector_cleanup;
> > + }
> > +
> > + drm_connector_helper_add(conn,
> > &intelvipfb_drm_connector_helper_funcs);
> > +
> > + return conn;
> > +
> > +error_connector_cleanup:
> > + drm_connector_cleanup(conn);
> > +
> > + return NULL;
> > +}
> > diff --git a/drivers/gpu/drm/ivip/intel_vip_core.c
> > b/drivers/gpu/drm/ivip/intel_vip_core.c
> > new file mode 100644
> > index 0000000..4e83343
> > --- /dev/null
> > +++ b/drivers/gpu/drm/ivip/intel_vip_core.c
> > @@ -0,0 +1,171 @@
> > +/*
> > + * intel_vip_core.c -- Intel Video and Image Processing(VIP)
> > + * Frame Buffer II driver
> > + *
> > + * This driver supports the Intel VIP Frame Reader component.
> > + * More info on the hardware can be found in the Intel Video
> > + * and Image Processing Suite User Guide at this address
> > + * http://www.altera.com/literature/ug/ug_vip.pdf.
> > + *
> > + * This program is free software; you can redistribute it and/or
> > modify it
> > + * under the terms and conditions of the GNU General Public
> > License,
> > + * version 2, as published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope it will be useful, but
> > WITHOUT
> > + * ANY WARRANTY; without even the implied warranty of
> > MERCHANTABILITY or
> > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
> > License for
> > + * more details.
> > + *
> > + * Authors:
> > + * Ong, Hean-Loong <hean.loong.ong@intel.com>
> > + *
> > + */
> > +
> > +#include <linux/init.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +
> > +#include <drm/drmP.h>
> > +#include <drm/drm_atomic.h>
> > +#include <drm/drm_atomic_helper.h>
> > +#include <drm/drm_crtc_helper.h>
> > +#include <drm/drm_fb_helper.h>
> > +#include <drm/drm_fb_cma_helper.h>
> > +#include <drm/drm_gem_cma_helper.h>
> > +#include <drm/drm_plane_helper.h>
> > +#include <drm/drm_simple_kms_helper.h>
> > +
> > +#include "intel_vip_drv.h"
> > +
> > +static const u32 fbpriv_formats[] = {
> > + DRM_FORMAT_XRGB8888,
> > + DRM_FORMAT_RGB565
> > +};
> You're registering that you support this set of formats, but I don't
> see
> anything programming the hardware differently based on the format of
> the
> plane.
>
> >
> > +static void intelvipfb_start_hw(void __iomem *base,
> > resource_size_t addr)
> > +{
> > + /*
> > + * The frameinfo variable has to correspond to the size of
> > the VIP Suite
> > + * Frame Reader register 7 which will determine the
> > maximum size used
> > + * in this frameinfo
> > + */
> > +
> > + u32 frameinfo;
> > +
> > + frameinfo =
> > + readl(base + INTELVIPFB_FRAME_READER) &
> > 0x00ffffff;
> > + writel(frameinfo, base + INTELVIPFB_FRAME_INFO);
> > + writel(addr, base + INTELVIPFB_FRAME_START);
> > + /* Finally set the control register to 1 to start
> > streaming */
> > + writel(1, base + INTELVIPFB_CONTROL);
> > +}
> The addr you're passing in here is from dev->mode_config.fb_base,
> which
> is this weird sideband value from drm_fbdev_cma. It's the wrong
> value
> to use if anything else uses the KMS interfaces to change the plane
> --
> you should be using
> drm_fb_cma_get_gem_addr(drm_simple_display_pipe->plane->state, 0)
> instead.
>
Thank you for highlighting this. Will look into using
drm_fb_cma_get_gem_addr(drm_simple_display_pipe->plane->state, 0)
> >
> > +
> > +static void intelvipfb_disable_hw(void __iomem *base)
> > +{
> > + /* set the control register to 0 to stop streaming */
> > + writel(0, base + INTELVIPFB_CONTROL);
> > +}
> These two functions should be be called from fbpriv_funcs.enable()
> and
> .disable(), not device load/unload.
>
Since I am not supporting hotplugging here would it make a difference?
>
> >
> > +static const struct drm_mode_config_funcs
> > intelvipfb_mode_config_funcs = {
> > + .fb_create = drm_fb_cma_create,
> > + .atomic_check = drm_atomic_helper_check,
> > + .atomic_commit = drm_atomic_helper_commit,
> > +};
> > +
> > +static struct drm_mode_config_helper_funcs
> > intelvipfb_mode_config_helpers = {
> > + .atomic_commit_tail = drm_atomic_helper_commit_tail,
> > +};
> > +
> > +static void intelvipfb_setup_mode_config(struct drm_device *drm)
> > +{
> > + drm_mode_config_init(drm);
> > + drm->mode_config.funcs = &intelvipfb_mode_config_funcs;
> > + drm->mode_config.helper_private =
> > &intelvipfb_mode_config_helpers;
> > +}
> > +
> > +static int intelvipfb_pipe_prepare_fb(struct
> > drm_simple_display_pipe *pipe,
> > + struct drm_plane_state
> > *plane_state)
> > +{
> > + return drm_fb_cma_prepare_fb(&pipe->plane, plane_state);
> > +}
> > +
> > +static struct drm_simple_display_pipe_funcs fbpriv_funcs = {
> > + .prepare_fb = intelvipfb_pipe_prepare_fb,
> > +};
> > +
> > +int intelvipfb_probe(struct device *dev, void __iomem *base)
> > +{
> > + int retval;
> > + struct drm_device *drm;
> > + struct intelvipfb_priv *fbpriv = dev_get_drvdata(dev);
> > + struct drm_connector *connector;
> > +
> > + dev_set_drvdata(dev, fbpriv);
> > +
> > + drm = fbpriv->drm;
> > +
> > + intelvipfb_setup_mode_config(drm);
> > +
> > + connector = intelvipfb_conn_setup(drm);
> > + if (!connector) {
> > + dev_err(drm->dev, "Connector setup failed\n");
> > + goto err_mode_config;
> > + }
> > +
> > + retval = drm_simple_display_pipe_init(drm, &fbpriv->pipe,
> > + &fbpriv_funcs,
> > + fbpriv_formats,
> > + ARRAY_SIZE(fbpriv_fo
> > rmats),
> > + connector);
> > + if (retval < 0) {
> > + dev_err(drm->dev, "Cannot setup simple display
> > pipe\n");
> > + goto err_mode_config;
> > + }
> > +
> > + fbpriv->fbcma = drm_fbdev_cma_init(drm, PREF_BPP,
> > + drm-
> > >mode_config.num_connector);
> > + if (!fbpriv->fbcma) {
> > + fbpriv->fbcma = NULL;
> > + dev_err(drm->dev, "Failed to init FB CMA area\n");
> > + goto err_mode_config;
> > + }
> On failure, drm_fbdev_cma_init() returns an ERR_PTR, not NULL.
>
> Also, you're passing this PREF_BPP value here, ignoring
> the altr,bits-per-symbol property. That seems wrong.
Noted thanks for highlighting.
^ permalink raw reply
* Re: [PATCH v2 3/8] clk: sunxi-ng: Add class of phase clocks supporting MMC new timing modes
From: Chen-Yu Tsai @ 2017-05-04 3:08 UTC (permalink / raw)
To: Maxime Ripard
Cc: Chen-Yu Tsai, Michael Turquette, Stephen Boyd, Rob Herring,
Mark Rutland, devicetree, linux-arm-kernel, linux-clk,
linux-kernel, linux-sunxi
In-Reply-To: <20170503203402.5mwhx5wjniav24nd@lukather>
Hi,
On Thu, May 4, 2017 at 4:34 AM, Maxime Ripard
<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> Hi,
>
> On Wed, May 03, 2017 at 11:16:53AM +0800, Chen-Yu Tsai wrote:
>> The MMC clocks on newer SoCs, such as the A83T and H3, support the
>> "new timing mode". Under this mode, the output of the clock is divided
>> by 2, and the clock delays no longer apply.
>>
>> Due to how the clock tree is modeled and setup, we need to model
>> this function in two places, the master mmc clock and the two
>> child phase clocks. In the mmc clock, we can easily model the
>> mode bit as an extra variable post-divider. In the phase clocks,
>> we check the bit and return -ENOTSUPP if the bit is set, signaling
>> that the phase clocks are not to be used.
>>
>> This patch introduces a class of phase clocks that checks the
>> timing mode bit.
>
> We've been over this quite some times already...
>
> How do you retrieve the mode used in the clock so that you can also
> switch the MMC driver in the new mode?
This part is covered. As mentioned above, the phase clks will return
-ENOTSUPP if the mmc clk is set in the new timing mode. The MMC driver
would try getting the current phase, check if it fails, and if it does,
realizes the clk is in new timing mode, and will switch the mmc controller
to it as well. I think this semantic fits the hardware well enough,
though it might be confusing without the accompanying comments.
See this commit for an example on how it should work.
https://github.com/wens/linux/commit/41e386f1f945a0a135a20a00601b977a001353da
> And do you prevent that from happening on the DT we already have that
> use the old clock drivers that do not support this new timing at all?
I admit this is not taken care of in this patch. Mostly because there
is no existing DT for the A83T to cater to. For the H3 and other SoCs
that do, we need some way of asking the CCU to switch the mode.
IIRC the output and sample clocks do not support a phase delay of 0.
So what if we design the semantic for this class of clocks as, if
phase == 0, switch to new timing mode, otherwise use old timing mode?
That would allow us to support this without adding extra functions,
and kind of matches what the hardware does. If you're using the new
timing mode, the delays in the mmc clk are bypassed.
Regards
ChenYu
^ permalink raw reply
* Re: [PATCH v2 2/20] clk: sunxi-ng: Pass the parent and a pointer to the clocks round rate
From: Chen-Yu Tsai @ 2017-05-04 3:19 UTC (permalink / raw)
To: Maxime Ripard
Cc: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, Daniel Vetter,
David Airlie, dri-devel, Mark Rutland, Rob Herring, devicetree,
linux-arm-kernel, linux-clk, linux-kernel, linux-sunxi
In-Reply-To: <83d508e254c6656aee02bbe5c410922ea66cf3d7.1493812478.git-series.maxime.ripard@free-electrons.com>
On Wed, May 3, 2017 at 7:59 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> The clocks might need to modify their parent clocks. In order to make that
> possible, give them access to the parent clock being evaluated, and to a
> pointer to the parent rate so that they can modify it if needed.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Acked-by: Chen-Yu Tsai <wens@csie.org>
^ permalink raw reply
* Re: [PATCH v2 3/20] clk: sunxi-ng: div: Switch to divider_round_rate
From: Chen-Yu Tsai @ 2017-05-04 3:20 UTC (permalink / raw)
To: Maxime Ripard
Cc: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, Daniel Vetter,
David Airlie, dri-devel, Mark Rutland, Rob Herring, devicetree,
linux-arm-kernel, linux-clk, linux-kernel, linux-sunxi
In-Reply-To: <8ea7c8c0ac01fe06f7ded94e03532a1838f2bf8f.1493812478.git-series.maxime.ripard@free-electrons.com>
On Wed, May 3, 2017 at 7:59 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> divider_round_rate already evaluates changing the parent rate if
^^^ Might want to update this, as you are now using the new function
you added in patch 1.
> CLK_SET_RATE_PARENT is set. Now that we can do that on muxes too, let's
> just use it.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Otherwise,
Acked-by: Chen-Yu Tsai <wens@csie.org>
^ permalink raw reply
* Re: [PATCH v2 4/20] clk: sunxi-ng: mux: Don't just rely on the parent for CLK_SET_RATE_PARENT
From: Chen-Yu Tsai @ 2017-05-04 3:23 UTC (permalink / raw)
To: Maxime Ripard
Cc: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, Daniel Vetter,
David Airlie, dri-devel, Mark Rutland, Rob Herring, devicetree,
linux-arm-kernel, linux-clk, linux-kernel, linux-sunxi
In-Reply-To: <27fcae13e64ef86d32001478f1923e9a02deb7b8.1493812478.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
On Wed, May 3, 2017 at 7:59 PM, Maxime Ripard
<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> The current code only rely on the parent to change its rate in the case
> where CLK_SET_RATE_PARENT is set.
>
> However, some clock rates might be obtained only through a modification of
> the parent and the clock divider. Just rely on the round rate of the clocks
> to give us the best computation that might be achieved for a given rate.
>
> round_rate functions now need to honor CLK_SET_RATE_PARENT, but either the
> functions already do that if they modify the parent, or don't modify the
> praents at all.
>
> Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Acked-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
^ permalink raw reply
* Re: [PATCH v2 5/20] clk: sunxi-ng: mux: split out the pre-divider computation code
From: Chen-Yu Tsai @ 2017-05-04 3:25 UTC (permalink / raw)
To: Maxime Ripard
Cc: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, Daniel Vetter,
David Airlie, dri-devel, Mark Rutland, Rob Herring, devicetree,
linux-arm-kernel, linux-clk, linux-kernel, linux-sunxi
In-Reply-To: <fcda95612e72a1a5bb6010993181e638a41511e9.1493812478.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
On Wed, May 3, 2017 at 7:59 PM, Maxime Ripard
<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> The pre-divider retrieval code was merged into the function to apply the
> current pre-divider onto the parent clock rate so that we can use that
> adjusted value to do our factors computation.
>
> However, since we'll need to do the reverse operation, we need to split out
> that code into a function that will be shared.
>
> Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Acked-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
Seems this would conflict with my "clk: sunxi-ng: Support multiple variable
pre-dividers" patch though. We'll see how this works out.
^ permalink raw reply
* Re: [PATCH v2 6/20] clk: sunxi-ng: mux: Change pre-divider application function prototype
From: Chen-Yu Tsai @ 2017-05-04 3:27 UTC (permalink / raw)
To: Maxime Ripard
Cc: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, Daniel Vetter,
David Airlie, dri-devel, Mark Rutland, Rob Herring, devicetree,
linux-arm-kernel, linux-clk, linux-kernel, linux-sunxi
In-Reply-To: <b7fab9142ae318f9188b93dfba0b6bd2b530a514.1493812478.git-series.maxime.ripard@free-electrons.com>
On Wed, May 3, 2017 at 7:59 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> The current function name is a bit confusing, and doesn't really allow to
> create an explicit function to reverse the operation.
>
> We also for now change the parent rate through a pointer, while we don't
> return anything.
>
> In order to be less confusing, and easier to use for downstream users,
> change the function name to something hopefully clearer, and return the
> adjusted rate instead of changing the pointer.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Acked-by: Chen-Yu Tsai <wens@csie.org>
^ permalink raw reply
* Re: [PATCH v2 7/20] clk: sunxi-ng: mux: Re-adjust parent rate
From: Chen-Yu Tsai @ 2017-05-04 3:28 UTC (permalink / raw)
To: Maxime Ripard
Cc: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, Daniel Vetter,
David Airlie, dri-devel, Mark Rutland, Rob Herring, devicetree,
linux-arm-kernel, linux-clk, linux-kernel, linux-sunxi
In-Reply-To: <0d8fc6d976c64be906fa86ead20aa10bb490386b.1493812478.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
On Wed, May 3, 2017 at 7:59 PM, Maxime Ripard
<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> Currently, the parent rate given back to the clock framework in our
> request is the original parent rate we calculated before trying to round
> the rate of our clock.
>
> This works fine unless our clock also changes its parent rate, in which
> case we will simply ignore that change and still use the previous parent
> rate.
>
> Create a new function to re-adjust the parent rate to take the pre-dividers
> into account, and give that back to the clock framework.
>
> Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> ---
> drivers/clk/sunxi-ng/ccu_mux.c | 33 ++++++++++++++++++++++++++++-----
> 1 file changed, 28 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/clk/sunxi-ng/ccu_mux.c b/drivers/clk/sunxi-ng/ccu_mux.c
> index c33210972581..1ce62cc23f8a 100644
> --- a/drivers/clk/sunxi-ng/ccu_mux.c
> +++ b/drivers/clk/sunxi-ng/ccu_mux.c
> @@ -64,6 +64,14 @@ unsigned long ccu_mux_helper_apply_prediv(struct ccu_common *common,
> return parent_rate / ccu_mux_get_prediv(common, cm, parent_index);
> }
>
> +unsigned long ccu_mux_helper_unapply_prediv(struct ccu_common *common,
> + struct ccu_mux_internal *cm,
> + int parent_index,
> + unsigned long parent_rate)
> +{
> + return parent_rate * ccu_mux_get_prediv(common, cm, parent_index);
> +}
> +
> int ccu_mux_helper_determine_rate(struct ccu_common *common,
> struct ccu_mux_internal *cm,
> struct clk_rate_request *req,
> @@ -89,22 +97,37 @@ int ccu_mux_helper_determine_rate(struct ccu_common *common,
> best_rate = round(cm, best_parent, &adj_parent_rate,
> req->rate, data);
>
> + /*
> + * parent_rate might have been modified by our clock.
> + * Re-apply the pre-divider if there's one, and give
Might want to reword the comments to match the new name.
> + * the actual frequency the parent needs to run at.
> + */
> + best_parent_rate = ccu_mux_helper_unapply_prediv(common, cm, -1,
> + adj_parent_rate);
> +
> goto out;
> }
>
> for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
> - unsigned long tmp_rate, parent_rate, adj_parent_rate;
> + unsigned long tmp_rate, parent_rate;
> struct clk_hw *parent;
>
> parent = clk_hw_get_parent_by_index(hw, i);
> if (!parent)
> continue;
>
> - parent_rate = clk_hw_get_rate(parent);
> - adj_parent_rate = ccu_mux_helper_apply_prediv(common, cm, i,
> - parent_rate);
> + parent_rate = ccu_mux_helper_apply_prediv(common, cm, i,
> + clk_hw_get_rate(parent));
> +
> + tmp_rate = round(cm, parent, &parent_rate, req->rate, data);
>
> - tmp_rate = round(cm, parent, &adj_parent_rate, req->rate, data);
> + /*
> + * parent_rate might have been modified by our clock.
> + * Re-apply the pre-divider if there's one, and give
Same here. Otherwise,
Acked-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
> + * the actual frequency the parent needs to run at.
> + */
> + parent_rate = ccu_mux_helper_unapply_prediv(common, cm, i,
> + parent_rate);
> if (tmp_rate == req->rate) {
> best_parent = parent;
> best_parent_rate = parent_rate;
> --
> git-series 0.8.11
^ permalink raw reply
* Re: [PATCH v2 8/20] clk: sunxi-ng: sun5i: Export video PLLs
From: Chen-Yu Tsai @ 2017-05-04 3:28 UTC (permalink / raw)
To: Maxime Ripard
Cc: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, Daniel Vetter,
David Airlie, dri-devel, Mark Rutland, Rob Herring, devicetree,
linux-arm-kernel, linux-clk, linux-kernel, linux-sunxi
In-Reply-To: <1fc17b7a14830306a83747b5086c0fd5d6dff290.1493812478.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
On Wed, May 3, 2017 at 7:59 PM, Maxime Ripard
<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> The video PLLs are used directly by the HDMI controller. Export them so
> that we can use them in our DT node.
>
> Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Acked-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
^ permalink raw reply
* Re: [PATCH v2 10/20] drm/sun4i: tcon: Move the muxing out of the mode set function
From: Chen-Yu Tsai @ 2017-05-04 3:54 UTC (permalink / raw)
To: Maxime Ripard
Cc: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, Daniel Vetter,
David Airlie, dri-devel, Mark Rutland, Rob Herring, devicetree,
linux-arm-kernel, linux-clk, linux-kernel, linux-sunxi
In-Reply-To: <ea29ffd2bc3c76203168d0fd1e969b045424b24c.1493812478.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
On Wed, May 3, 2017 at 7:59 PM, Maxime Ripard
<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> The muxing can actually happen on both channels on some SoCs, so it makes
> more sense to just move it out of the sun4i_tcon1_mode_set function and
> create a separate function that needs to be called by the encoders.
>
> Let's do that and convert the existing drivers.
>
> Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> ---
> drivers/gpu/drm/sun4i/sun4i_rgb.c | 1 +
> drivers/gpu/drm/sun4i/sun4i_tcon.c | 22 ++++++++++++++++------
> drivers/gpu/drm/sun4i/sun4i_tcon.h | 2 ++
> drivers/gpu/drm/sun4i/sun4i_tv.c | 1 +
> 4 files changed, 20 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/sun4i/sun4i_rgb.c b/drivers/gpu/drm/sun4i/sun4i_rgb.c
> index 67f0b91a99de..3003d290c635 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_rgb.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_rgb.c
> @@ -175,6 +175,7 @@ static void sun4i_rgb_encoder_mode_set(struct drm_encoder *encoder,
> struct sun4i_tcon *tcon = rgb->tcon;
>
> sun4i_tcon0_mode_set(tcon, mode);
> + sun4i_tcon_set_mux(tcon, 0, encoder);
>
> clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
>
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> index 66a5bb9b85e9..0204d9fadb66 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> @@ -108,6 +108,22 @@ void sun4i_tcon_enable_vblank(struct sun4i_tcon *tcon, bool enable)
> }
> EXPORT_SYMBOL(sun4i_tcon_enable_vblank);
>
> +void sun4i_tcon_set_mux(struct sun4i_tcon *tcon, int channel,
> + struct drm_encoder *encoder)
The channel doesn't really matter. What is needed is which TCON and encoder
are supposed to be muxed together. This is going to be per SoC type anyway.
I have something in the works, though it's not finished yet.
I think this works for now.
Acked-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
> +{
> + if (!tcon->quirks->has_unknown_mux)
> + return;
> +
> + if (channel != 1)
> + return;
> +
> + /*
> + * FIXME: Undocumented bits
> + */
> + regmap_write(tcon->regs, SUN4I_TCON_MUX_CTRL_REG, 1);
> +}
> +EXPORT_SYMBOL(sun4i_tcon_set_mux);
> +
> static int sun4i_tcon_get_clk_delay(struct drm_display_mode *mode,
> int channel)
> {
> @@ -266,12 +282,6 @@ void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon,
> regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
> SUN4I_TCON_GCTL_IOMAP_MASK,
> SUN4I_TCON_GCTL_IOMAP_TCON1);
> -
> - /*
> - * FIXME: Undocumented bits
> - */
> - if (tcon->quirks->has_unknown_mux)
> - regmap_write(tcon->regs, SUN4I_TCON_MUX_CTRL_REG, 1);
> }
> EXPORT_SYMBOL(sun4i_tcon1_mode_set);
>
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h
> index f636343a935d..0350936b413c 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
> +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
> @@ -190,6 +190,8 @@ void sun4i_tcon_enable_vblank(struct sun4i_tcon *tcon, bool enable);
> /* Mode Related Controls */
> void sun4i_tcon_switch_interlace(struct sun4i_tcon *tcon,
> bool enable);
> +void sun4i_tcon_set_mux(struct sun4i_tcon *tcon, int channel,
> + struct drm_encoder *encoder);
> void sun4i_tcon0_mode_set(struct sun4i_tcon *tcon,
> struct drm_display_mode *mode);
> void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon,
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c
> index 49c49431a053..03c494b8159c 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tv.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
> @@ -393,6 +393,7 @@ static void sun4i_tv_mode_set(struct drm_encoder *encoder,
> const struct tv_mode *tv_mode = sun4i_tv_find_tv_by_mode(mode);
>
> sun4i_tcon1_mode_set(tcon, mode);
> + sun4i_tcon_set_mux(tcon, 1, encoder);
>
> /* Enable and map the DAC to the output */
> regmap_update_bits(tv->regs, SUN4I_TVE_EN_REG,
> --
> git-series 0.8.11
^ permalink raw reply
* Re: [PATCH v2 11/20] drm/sun4i: tcon: Switch mux on only for composite
From: Chen-Yu Tsai @ 2017-05-04 3:57 UTC (permalink / raw)
To: Maxime Ripard
Cc: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, Daniel Vetter,
David Airlie, dri-devel, Mark Rutland, Rob Herring, devicetree,
linux-arm-kernel, linux-clk, linux-kernel, linux-sunxi
In-Reply-To: <9f97dbff6f99c108b5f4b7f144d02dde8c253ab6.1493812478.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
On Wed, May 3, 2017 at 7:59 PM, Maxime Ripard
<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> Even though that mux is undocumented, it seems like it needs to be set to 1
> when using composite, and 0 when using HDMI.
>
> Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Acked-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2 13/20] drm/sun4i: tcon: Change vertical total size computation inconsistency
From: Chen-Yu Tsai @ 2017-05-04 3:58 UTC (permalink / raw)
To: Maxime Ripard
Cc: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, Daniel Vetter,
David Airlie, dri-devel, Mark Rutland, Rob Herring, devicetree,
linux-arm-kernel, linux-clk, linux-kernel, linux-sunxi
In-Reply-To: <745b9fc450798635d50f449473e9263ab3ace48e.1493812478.git-series.maxime.ripard@free-electrons.com>
On Wed, May 3, 2017 at 7:59 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Both TCON channels need to have the resolution doubled, since the size the
> hardware is going to use is whatever we put in the register divided by two.
>
> However, we handle it differently for the two channels: in the channel 0,
> our register access macro does the multiplication of the value passed as
> paremeter, while in the channel 1, the macro doesn't do this, and we need
> to do it before calling it.
>
> Make this consistent by aligning the channel 0 with the channel 1
> behaviour.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Acked-by: Chen-Yu Tsai <wens@csie.org>
^ permalink raw reply
* Re: [PATCH v2 14/20] drm/sun4i: tcon: multiply the vtotal when not in interlace
From: Chen-Yu Tsai @ 2017-05-04 4:07 UTC (permalink / raw)
To: Maxime Ripard
Cc: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, Daniel Vetter,
David Airlie, dri-devel, Mark Rutland, Rob Herring, devicetree,
linux-arm-kernel, linux-clk, linux-kernel, linux-sunxi
In-Reply-To: <59bdbadc4d3adc6d75c2cef38df0af332bd313db.1493812478.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
On Wed, May 3, 2017 at 7:59 PM, Maxime Ripard
<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> It appears that the total vertical resolution needs to be doubled when
> we're not in interlaced. Make sure that is the case.
I think the total vertical resolution needs to be doubled in all cases.
It just happens that you should've been using mode->crtc_vtotal, which
is halved when the mode is interlaced. Instead you used mode->vtotal,
which is double the actual scan resolution in interlaced mode.
ChenYu
> Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> ---
> drivers/gpu/drm/sun4i/sun4i_tcon.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> index 0f91ec8a4b26..efa079c1a3f5 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> @@ -272,9 +272,9 @@ void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon,
> /* Set vertical display timings */
> bp = mode->crtc_vtotal - mode->crtc_vsync_start;
> DRM_DEBUG_DRIVER("Setting vertical total %d, backporch %d\n",
> - mode->vtotal, bp);
> + mode->crtc_vtotal, bp);
> regmap_write(tcon->regs, SUN4I_TCON1_BASIC4_REG,
> - SUN4I_TCON1_BASIC4_V_TOTAL(mode->vtotal) |
> + SUN4I_TCON1_BASIC4_V_TOTAL(mode->crtc_vtotal * 2) |
> SUN4I_TCON1_BASIC4_V_BACKPORCH(bp));
>
> /* Set Hsync and Vsync length */
> --
> git-series 0.8.11
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox