* [PATCH v5 10/12] ARM: dts: imx7s-warp: add ov2680 sensor node
From: Rui Miguel Silva @ 2018-05-18 9:28 UTC (permalink / raw)
To: mchehab, sakari.ailus, Steve Longerbeam, Philipp Zabel,
Rob Herring
Cc: devel, devicetree, Greg Kroah-Hartman, Ryan Harkin,
Rui Miguel Silva, Fabio Estevam, Shawn Guo, linux-clk,
linux-media
In-Reply-To: <20180518092806.3829-1-rui.silva@linaro.org>
Warp7 comes with a Omnivision OV2680 sensor, add the node here to make complete
the camera data path for this system. Add the needed regulator to the analog
voltage supply, the port and endpoints in mipi_csi node and the pinctrl for the
reset gpio.
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
arch/arm/boot/dts/imx7s-warp.dts | 44 ++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/arch/arm/boot/dts/imx7s-warp.dts b/arch/arm/boot/dts/imx7s-warp.dts
index cb175ee2fc9d..bf04e13afd02 100644
--- a/arch/arm/boot/dts/imx7s-warp.dts
+++ b/arch/arm/boot/dts/imx7s-warp.dts
@@ -91,6 +91,14 @@
regulator-always-on;
};
+ reg_peri_3p15v: regulator-peri-3p15v {
+ compatible = "regulator-fixed";
+ regulator-name = "peri_3p15v_reg";
+ regulator-min-microvolt = <3150000>;
+ regulator-max-microvolt = <3150000>;
+ regulator-always-on;
+ };
+
sound {
compatible = "simple-audio-card";
simple-audio-card,name = "imx7-sgtl5000";
@@ -218,6 +226,27 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>;
status = "okay";
+
+ ov2680: camera@36 {
+ compatible = "ovti,ov2680";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ov2680>;
+ reg = <0x36>;
+ clocks = <&osc>;
+ clock-names = "xvclk";
+ reset-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
+ DOVDD-supply = <&sw2_reg>;
+ DVDD-supply = <&sw2_reg>;
+ AVDD-supply = <®_peri_3p15v>;
+
+ port {
+ ov2680_to_mipi: endpoint {
+ remote-endpoint = <&mipi_from_sensor>;
+ clock-lanes = <0>;
+ data-lanes = <1>;
+ };
+ };
+ };
};
&i2c4 {
@@ -352,6 +381,15 @@
#size-cells = <0>;
fsl,csis-hs-settle = <3>;
+ port@0 {
+ reg = <0>;
+
+ mipi_from_sensor: endpoint {
+ remote-endpoint = <&ov2680_to_mipi>;
+ data-lanes = <1>;
+ };
+ };
+
port@1 {
reg = <1>;
@@ -408,6 +446,12 @@
>;
};
+ pinctrl_ov2680: ov2660grp {
+ fsl,pins = <
+ MX7D_PAD_LPSR_GPIO1_IO03__GPIO1_IO3 0x14
+ >;
+ };
+
pinctrl_sai1: sai1grp {
fsl,pins = <
MX7D_PAD_SAI1_RX_DATA__SAI1_RX_DATA0 0x1f
--
2.17.0
^ permalink raw reply related
* [PATCH RFC 13/24] drm/lima: add PP related functions
From: Qiang Yu @ 2018-05-18 9:28 UTC (permalink / raw)
To: dri-devel, devicetree
Cc: Simon Shields, Marek Vasut, Connor Abbott, Neil Armstrong,
Andrei Paulau, Vasily Khoruzhick, Qiang Yu, Erico Nunes
In-Reply-To: <20180518092815.25280-1-yuq825@gmail.com>
From: Lima Project Developers <dri-devel@lists.freedesktop.org>
PP is a processor used for OpenGL fragment shader
processing.
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
drivers/gpu/drm/lima/lima_pp.c | 418 +++++++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_pp.h | 37 +++
2 files changed, 455 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_pp.c
create mode 100644 drivers/gpu/drm/lima/lima_pp.h
diff --git a/drivers/gpu/drm/lima/lima_pp.c b/drivers/gpu/drm/lima/lima_pp.c
new file mode 100644
index 000000000000..371d6b70c271
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_pp.c
@@ -0,0 +1,418 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+
+#include <drm/lima_drm.h>
+
+#include "lima_device.h"
+#include "lima_pp.h"
+#include "lima_dlbu.h"
+#include "lima_bcast.h"
+#include "lima_vm.h"
+#include "lima_regs.h"
+
+#define pp_write(reg, data) writel(data, ip->iomem + LIMA_PP_##reg)
+#define pp_read(reg) readl(ip->iomem + LIMA_PP_##reg)
+
+static void lima_pp_handle_irq(struct lima_ip *ip, u32 state)
+{
+ struct lima_device *dev = ip->dev;
+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
+
+ if (state & LIMA_PP_IRQ_MASK_ERROR) {
+ u32 status = pp_read(STATUS);
+
+ dev_err(dev->dev, "pp error irq state=%x status=%x\n",
+ state, status);
+
+ pipe->error = true;
+
+ /* mask all interrupts before hard reset */
+ pp_write(INT_MASK, 0);
+ }
+
+ pp_write(INT_CLEAR, state);
+}
+
+static irqreturn_t lima_pp_irq_handler(int irq, void *data)
+{
+ struct lima_ip *ip = data;
+ struct lima_device *dev = ip->dev;
+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
+ u32 state = pp_read(INT_STATUS);
+
+ /* for shared irq case */
+ if (!state)
+ return IRQ_NONE;
+
+ lima_pp_handle_irq(ip, state);
+
+ if (atomic_dec_and_test(&pipe->task))
+ lima_sched_pipe_task_done(pipe);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t lima_pp_bcast_irq_handler(int irq, void *data)
+{
+ int i;
+ irqreturn_t ret = IRQ_NONE;
+ struct lima_ip *pp_bcast = data;
+ struct lima_device *dev = pp_bcast->dev;
+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
+
+ for (i = 0; i < pipe->num_processor; i++) {
+ struct lima_ip *ip = pipe->processor[i];
+ u32 status, state;
+
+ if (pipe->done & (1 << i))
+ continue;
+
+ /* status read first in case int state change in the middle
+ * which may miss the interrupt handling */
+ status = pp_read(STATUS);
+ state = pp_read(INT_STATUS);
+
+ if (state) {
+ lima_pp_handle_irq(ip, state);
+ ret = IRQ_HANDLED;
+ }
+ else {
+ if (status & LIMA_PP_STATUS_RENDERING_ACTIVE)
+ continue;
+ }
+
+ pipe->done |= (1 << i);
+ if (atomic_dec_and_test(&pipe->task))
+ lima_sched_pipe_task_done(pipe);
+ }
+
+ return ret;
+}
+
+static void lima_pp_soft_reset_async(struct lima_ip *ip)
+{
+ if (ip->data.async_reset)
+ return;
+
+ pp_write(INT_MASK, 0);
+ pp_write(INT_RAWSTAT, LIMA_PP_IRQ_MASK_ALL);
+ pp_write(CTRL, LIMA_PP_CTRL_SOFT_RESET);
+ ip->data.async_reset = true;
+}
+
+static int lima_pp_soft_reset_async_wait_one(struct lima_ip *ip)
+{
+ struct lima_device *dev = ip->dev;
+ int timeout;
+
+ for (timeout = 1000; timeout > 0; timeout--) {
+ if (!(pp_read(STATUS) & LIMA_PP_STATUS_RENDERING_ACTIVE) &&
+ pp_read(INT_RAWSTAT) == LIMA_PP_IRQ_RESET_COMPLETED)
+ break;
+ }
+ if (!timeout) {
+ dev_err(dev->dev, "pp %s reset time out\n", lima_ip_name(ip));
+ return -ETIMEDOUT;
+ }
+
+ pp_write(INT_CLEAR, LIMA_PP_IRQ_MASK_ALL);
+ pp_write(INT_MASK, LIMA_PP_IRQ_MASK_USED);
+ return 0;
+}
+
+static int lima_pp_soft_reset_async_wait(struct lima_ip *ip)
+{
+ int i, err = 0;
+
+ if (!ip->data.async_reset)
+ return 0;
+
+ if (ip->id == lima_ip_pp_bcast) {
+ struct lima_device *dev = ip->dev;
+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
+ for (i = 0; i < pipe->num_processor; i++)
+ err |= lima_pp_soft_reset_async_wait_one(pipe->processor[i]);
+ }
+ else
+ err = lima_pp_soft_reset_async_wait_one(ip);
+
+ ip->data.async_reset = false;
+ return err;
+}
+
+static void lima_pp_start_task(struct lima_ip *ip, u32 *frame, u32 *wb,
+ bool skip_stack_addr)
+{
+ int i, j, n = 0;
+
+ for (i = 0; i < LIMA_PP_FRAME_REG_NUM; i++) {
+ if (skip_stack_addr && i * 4 == LIMA_PP_STACK)
+ continue;
+
+ writel(frame[i], ip->iomem + LIMA_PP_FRAME + i * 4);
+ }
+
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < LIMA_PP_WB_REG_NUM; j++)
+ writel(wb[n++], ip->iomem + LIMA_PP_WB(i) + j * 4);
+ }
+
+ pp_write(CTRL, LIMA_PP_CTRL_START_RENDERING);
+}
+
+static int lima_pp_hard_reset(struct lima_ip *ip)
+{
+ struct lima_device *dev = ip->dev;
+ int timeout;
+
+ pp_write(PERF_CNT_0_LIMIT, 0xC0FFE000);
+ pp_write(INT_MASK, 0);
+ pp_write(CTRL, LIMA_PP_CTRL_FORCE_RESET);
+ for (timeout = 1000; timeout > 0; timeout--) {
+ pp_write(PERF_CNT_0_LIMIT, 0xC01A0000);
+ if (pp_read(PERF_CNT_0_LIMIT) == 0xC01A0000)
+ break;
+ }
+ if (!timeout) {
+ dev_err(dev->dev, "pp hard reset timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ pp_write(PERF_CNT_0_LIMIT, 0);
+ pp_write(INT_CLEAR, LIMA_PP_IRQ_MASK_ALL);
+ pp_write(INT_MASK, LIMA_PP_IRQ_MASK_USED);
+ return 0;
+}
+
+static void lima_pp_print_version(struct lima_ip *ip)
+{
+ u32 version, major, minor;
+ char *name;
+
+ version = pp_read(VERSION);
+ major = (version >> 8) & 0xFF;
+ minor = version & 0xFF;
+ switch (version >> 16) {
+ case 0xC807:
+ name = "mali200";
+ break;
+ case 0xCE07:
+ name = "mali300";
+ break;
+ case 0xCD07:
+ name = "mali400";
+ break;
+ case 0xCF07:
+ name = "mali450";
+ break;
+ default:
+ name = "unknow";
+ break;
+ }
+ dev_info(ip->dev->dev, "%s - %s version major %d minor %d\n",
+ lima_ip_name(ip), name, major, minor);
+}
+
+int lima_pp_init(struct lima_ip *ip)
+{
+ struct lima_device *dev = ip->dev;
+ int err;
+
+ lima_pp_print_version(ip);
+
+ ip->data.async_reset = false;
+ lima_pp_soft_reset_async(ip);
+ err = lima_pp_soft_reset_async_wait(ip);
+ if (err)
+ return err;
+
+ err = devm_request_irq(dev->dev, ip->irq, lima_pp_irq_handler,
+ IRQF_SHARED, lima_ip_name(ip), ip);
+ if (err) {
+ dev_err(dev->dev, "pp %s fail to request irq\n",
+ lima_ip_name(ip));
+ return err;
+ }
+
+ return 0;
+}
+
+void lima_pp_fini(struct lima_ip *ip)
+{
+
+}
+
+int lima_pp_bcast_init(struct lima_ip *ip)
+{
+ struct lima_device *dev = ip->dev;
+ int err;
+
+ err = devm_request_irq(dev->dev, ip->irq, lima_pp_bcast_irq_handler,
+ IRQF_SHARED, lima_ip_name(ip), ip);
+ if (err) {
+ dev_err(dev->dev, "pp %s fail to request irq\n",
+ lima_ip_name(ip));
+ return err;
+ }
+
+ return 0;
+}
+
+void lima_pp_bcast_fini(struct lima_ip *ip)
+{
+
+}
+
+static int lima_pp_task_validate(struct lima_sched_pipe *pipe,
+ struct lima_sched_task *task)
+{
+ if (!pipe->bcast_processor) {
+ struct drm_lima_m400_pp_frame *f = task->frame;
+
+ if (f->num_pp > pipe->num_processor)
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void lima_pp_task_run(struct lima_sched_pipe *pipe,
+ struct lima_sched_task *task)
+{
+ if (pipe->bcast_processor) {
+ struct drm_lima_m450_pp_frame *frame = task->frame;
+ struct lima_device *dev = pipe->bcast_processor->dev;
+ int i;
+
+ pipe->done = 0;
+ atomic_set(&pipe->task, pipe->num_processor);
+
+ frame->frame[LIMA_PP_FRAME >> 2] = LIMA_VA_RESERVE_DLBU;
+ lima_dlbu_set_reg(dev->ip + lima_ip_dlbu, frame->dlbu_regs);
+
+ lima_pp_soft_reset_async_wait(pipe->bcast_processor);
+
+ for (i = 0; i < pipe->num_processor; i++) {
+ struct lima_ip *ip = pipe->processor[i];
+ pp_write(STACK, frame->fragment_stack_address[i]);
+ }
+
+ lima_pp_start_task(pipe->bcast_processor, frame->frame,
+ frame->wb, true);
+ }
+ else {
+ struct drm_lima_m400_pp_frame *frame = task->frame;
+ int i;
+
+ atomic_set(&pipe->task, frame->num_pp);
+
+ for (i = 0; i < frame->num_pp; i++) {
+ frame->frame[LIMA_PP_FRAME >> 2] =
+ frame->plbu_array_address[i];
+ frame->frame[LIMA_PP_STACK >> 2] =
+ frame->fragment_stack_address[i];
+
+ lima_pp_soft_reset_async_wait(pipe->processor[i]);
+
+ lima_pp_start_task(pipe->processor[i], frame->frame,
+ frame->wb, false);
+ }
+ }
+}
+
+static void lima_pp_task_fini(struct lima_sched_pipe *pipe)
+{
+ if (pipe->bcast_processor)
+ lima_pp_soft_reset_async(pipe->bcast_processor);
+ else {
+ int i;
+ for (i = 0; i < pipe->num_processor; i++)
+ lima_pp_soft_reset_async(pipe->processor[i]);
+ }
+}
+
+static void lima_pp_task_error(struct lima_sched_pipe *pipe)
+{
+ int i;
+
+ if (pipe->bcast_processor)
+ lima_bcast_disable(pipe->bcast_processor->dev);
+
+ for (i = 0; i < pipe->num_processor; i++)
+ lima_pp_hard_reset(pipe->processor[i]);
+
+ if (pipe->bcast_processor)
+ lima_bcast_enable(pipe->bcast_processor->dev);
+}
+
+static void lima_pp_task_mmu_error(struct lima_sched_pipe *pipe)
+{
+ if (atomic_dec_and_test(&pipe->task))
+ lima_sched_pipe_task_done(pipe);
+}
+
+static struct kmem_cache *lima_pp_task_slab = NULL;
+static int lima_pp_task_slab_refcnt = 0;
+
+int lima_pp_pipe_init(struct lima_device *dev)
+{
+ int frame_size;
+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
+
+ if (dev->id == lima_gpu_mali400)
+ frame_size = sizeof(struct drm_lima_m400_pp_frame);
+ else
+ frame_size = sizeof(struct drm_lima_m450_pp_frame);
+
+ if (!lima_pp_task_slab) {
+ lima_pp_task_slab = kmem_cache_create(
+ "lima_pp_task", sizeof(struct lima_sched_task) + frame_size,
+ 0, SLAB_HWCACHE_ALIGN, NULL);
+ if (!lima_pp_task_slab)
+ return -ENOMEM;
+ }
+ lima_pp_task_slab_refcnt++;
+
+ pipe->frame_size = frame_size;
+ pipe->task_slab = lima_pp_task_slab;
+
+ pipe->task_validate = lima_pp_task_validate;
+ pipe->task_run = lima_pp_task_run;
+ pipe->task_fini = lima_pp_task_fini;
+ pipe->task_error = lima_pp_task_error;
+ pipe->task_mmu_error = lima_pp_task_mmu_error;
+
+ return 0;
+}
+
+void lima_pp_pipe_fini(struct lima_device *dev)
+{
+ if (!--lima_pp_task_slab_refcnt) {
+ kmem_cache_destroy(lima_pp_task_slab);
+ lima_pp_task_slab = NULL;
+ }
+}
diff --git a/drivers/gpu/drm/lima/lima_pp.h b/drivers/gpu/drm/lima/lima_pp.h
new file mode 100644
index 000000000000..4bd1d9fcbcdf
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_pp.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIMA_PP_H__
+#define __LIMA_PP_H__
+
+struct lima_ip;
+struct lima_device;
+
+int lima_pp_init(struct lima_ip *ip);
+void lima_pp_fini(struct lima_ip *ip);
+
+int lima_pp_bcast_init(struct lima_ip *ip);
+void lima_pp_bcast_fini(struct lima_ip *ip);
+
+int lima_pp_pipe_init(struct lima_device *dev);
+void lima_pp_pipe_fini(struct lima_device *dev);
+
+#endif
--
2.17.0
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related
* [PATCH v5 11/12] media: imx7.rst: add documentation for i.MX7 media driver
From: Rui Miguel Silva @ 2018-05-18 9:28 UTC (permalink / raw)
To: mchehab, sakari.ailus, Steve Longerbeam, Philipp Zabel,
Rob Herring
Cc: devel, devicetree, Greg Kroah-Hartman, Ryan Harkin,
Rui Miguel Silva, Fabio Estevam, Shawn Guo, linux-clk,
linux-media
In-Reply-To: <20180518092806.3829-1-rui.silva@linaro.org>
Add rst document to describe the i.MX7 media driver and also a working
example from the Warp7 board usage with a OV2680 sensor.
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
Documentation/media/v4l-drivers/imx7.rst | 157 ++++++++++++++++++++++
Documentation/media/v4l-drivers/index.rst | 1 +
2 files changed, 158 insertions(+)
create mode 100644 Documentation/media/v4l-drivers/imx7.rst
diff --git a/Documentation/media/v4l-drivers/imx7.rst b/Documentation/media/v4l-drivers/imx7.rst
new file mode 100644
index 000000000000..cd1195d391c5
--- /dev/null
+++ b/Documentation/media/v4l-drivers/imx7.rst
@@ -0,0 +1,157 @@
+i.MX7 Video Capture Driver
+==========================
+
+Introduction
+------------
+
+The i.MX7 contrary to the i.MX5/6 family does not contain an Image Processing
+Unit (IPU); because of that the capabilities to perform operations or
+manipulation of the capture frames are less feature rich.
+
+For image capture the i.MX7 has three units:
+- CMOS Sensor Interface (CSI)
+- Video Multiplexer
+- MIPI CSI-2 Receiver
+
+::
+ |\
+ MIPI Camera Input ---> MIPI CSI-2 --- > | \
+ | \
+ | M |
+ | U | ------> CSI ---> Capture
+ | X |
+ | /
+ Parallel Camera Input ----------------> | /
+ |/
+
+For additional information, please refer to the latest versions of the i.MX7
+reference manual [#f1]_.
+
+Entities
+--------
+
+imx7-mipi-csi2
+--------------
+
+This is the MIPI CSI-2 receiver entity. It has one sink pad to receive the pixel
+data from MIPI CSI-2 camera sensor. It has one source pad, corresponding to the
+virtual channel 0. This module is compliant to previous version of Samsung
+D-phy, and supports two D-PHY Rx Data lanes.
+
+csi_mux
+-------
+
+This is the video multiplexer. It has two sink pads to select from either camera
+sensor with a parallel interface or from MIPI CSI-2 virtual channel 0. It has
+a single source pad that routes to the CSI.
+
+csi
+---
+
+The CSI enables the chip to connect directly to external CMOS image sensor. CSI
+can interface directly with Parallel and MIPI CSI-2 buses. It has 256 x 64 FIFO
+to store received image pixel data and embedded DMA controllers to transfer data
+from the FIFO through AHB bus.
+
+This entity has one sink pad that receives from the csi_mux entity and a single
+source pad that routes video frames directly to memory buffers. This pad is
+routed to a capture device node.
+
+Usage Notes
+-----------
+
+To aid in configuration and for backward compatibility with V4L2 applications
+that access controls only from video device nodes, the capture device interfaces
+inherit controls from the active entities in the current pipeline, so controls
+can be accessed either directly from the subdev or from the active capture
+device interface. For example, the sensor controls are available either from the
+sensor subdevs or from the active capture device.
+
+Warp7 with OV2680
+-----------------
+
+On this platform an OV2680 MIPI CSI-2 module is connected to the internal MIPI
+CSI-2 receiver. The following example configures a video capture pipeline with
+an output of 800x600, and BGGR 10 bit bayer format:
+
+.. code-block:: none
+ # Setup links
+ media-ctl -l "'ov2680 1-0036':0 -> 'imx7-mipi-csis.0':0[1]"
+ media-ctl -l "'imx7-mipi-csis.0':1 -> 'csi_mux':1[1]"
+ media-ctl -l "'csi_mux':2 -> 'csi':0[1]"
+ media-ctl -l "'csi':1 -> 'csi capture':0[1]"
+
+ # Configure pads for pipeline
+ media-ctl -V "'ov2680 1-0036':0 [fmt:SBGGR10_1X10/800x600 field:none]"
+ media-ctl -V "'csi_mux':1 [fmt:SBGGR10_1X10/800x600 field:none]"
+ media-ctl -V "'csi_mux':2 [fmt:SBGGR10_1X10/800x600 field:none]"
+ media-ctl -V "'imx7-mipi-csis.0':0 [fmt:SBGGR10_1X10/800x600 field:none]"
+ media-ctl -V "'csi':0 [fmt:SBGGR10_1X10/800x600 field:none]"
+
+After this streaming can start. The v4l2-ctl tool can be used to select any of
+the resolutions supported by the sensor.
+
+.. code-block:: none
+ root@imx7s-warp:~# media-ctl -p
+ Media controller API version 4.17.0
+
+ Media device information
+ ------------------------
+ driver imx-media
+ model imx-media
+ serial
+ bus info
+ hw revision 0x0
+ driver version 4.17.0
+
+ Device topology
+ - entity 1: csi (2 pads, 2 links)
+ type V4L2 subdev subtype Unknown flags 0
+ device node name /dev/v4l-subdev0
+ pad0: Sink
+ [fmt:SBGGR10_1X10/800x600 field:none]
+ <- "csi_mux":2 [ENABLED]
+ pad1: Source
+ [fmt:SBGGR10_1X10/800x600 field:none]
+ -> "csi capture":0 [ENABLED]
+
+ - entity 4: csi capture (1 pad, 1 link)
+ type Node subtype V4L flags 0
+ device node name /dev/video0
+ pad0: Sink
+ <- "csi":1 [ENABLED]
+
+ - entity 10: csi_mux (3 pads, 2 links)
+ type V4L2 subdev subtype Unknown flags 0
+ device node name /dev/v4l-subdev1
+ pad0: Sink
+ [fmt:unknown/0x0]
+ pad1: Sink
+ [fmt:unknown/800x600 field:none]
+ <- "imx7-mipi-csis.0":1 [ENABLED]
+ pad2: Source
+ [fmt:unknown/800x600 field:none]
+ -> "csi":0 [ENABLED]
+
+ - entity 14: imx7-mipi-csis.0 (2 pads, 2 links)
+ type V4L2 subdev subtype Unknown flags 0
+ device node name /dev/v4l-subdev2
+ pad0: Sink
+ [fmt:SBGGR10_1X10/800x600 field:none]
+ <- "ov2680 1-0036":0 [ENABLED]
+ pad1: Source
+ [fmt:SBGGR10_1X10/800x600 field:none]
+ -> "csi_mux":1 [ENABLED]
+
+ - entity 17: ov2680 1-0036 (1 pad, 1 link)
+ type V4L2 subdev subtype Sensor flags 0
+ device node name /dev/v4l-subdev3
+ pad0: Source
+ [fmt:SBGGR10_1X10/800x600 field:none]
+ -> "imx7-mipi-csis.0":0 [ENABLED]
+
+
+References
+----------
+
+.. [#f1] https://www.nxp.com/docs/en/reference-manual/IMX7SRM.pdf
diff --git a/Documentation/media/v4l-drivers/index.rst b/Documentation/media/v4l-drivers/index.rst
index 679238e786a7..693295bbc53f 100644
--- a/Documentation/media/v4l-drivers/index.rst
+++ b/Documentation/media/v4l-drivers/index.rst
@@ -44,6 +44,7 @@ For more details see the file COPYING in the source distribution of Linux.
davinci-vpbe
fimc
imx
+ imx7
ivtv
max2175
meye
--
2.17.0
^ permalink raw reply related
* [PATCH RFC 14/24] drm/lima: add MMU related functions
From: Qiang Yu @ 2018-05-18 9:28 UTC (permalink / raw)
To: dri-devel, devicetree
Cc: Simon Shields, Marek Vasut, Connor Abbott, Neil Armstrong,
Andrei Paulau, Vasily Khoruzhick, Qiang Yu, Erico Nunes
In-Reply-To: <20180518092815.25280-1-yuq825@gmail.com>
From: Lima Project Developers <dri-devel@lists.freedesktop.org>
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Signed-off-by: Marek Vasut <marex@denx.de>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
drivers/gpu/drm/lima/lima_mmu.c | 154 ++++++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_mmu.h | 34 +++++++
2 files changed, 188 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_mmu.c
create mode 100644 drivers/gpu/drm/lima/lima_mmu.h
diff --git a/drivers/gpu/drm/lima/lima_mmu.c b/drivers/gpu/drm/lima/lima_mmu.c
new file mode 100644
index 000000000000..22ac4db07849
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_mmu.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/device.h>
+
+#include "lima_device.h"
+#include "lima_mmu.h"
+#include "lima_vm.h"
+#include "lima_object.h"
+#include "lima_regs.h"
+
+#define mmu_write(reg, data) writel(data, ip->iomem + LIMA_MMU_##reg)
+#define mmu_read(reg) readl(ip->iomem + LIMA_MMU_##reg)
+
+#define lima_mmu_send_command(command, condition) \
+({ \
+ int __timeout, __ret = 0; \
+ \
+ mmu_write(COMMAND, command); \
+ for (__timeout = 1000; __timeout > 0; __timeout--) { \
+ if (condition) \
+ break; \
+ } \
+ if (!__timeout) { \
+ dev_err(dev->dev, "mmu command %x timeout\n", command); \
+ __ret = -ETIMEDOUT; \
+ } \
+ __ret; \
+})
+
+static irqreturn_t lima_mmu_irq_handler(int irq, void *data)
+{
+ struct lima_ip *ip = data;
+ struct lima_device *dev = ip->dev;
+ u32 status = mmu_read(INT_STATUS);
+ struct lima_sched_pipe *pipe;
+
+ /* for shared irq case */
+ if (!status)
+ return IRQ_NONE;
+
+ if (status & LIMA_MMU_INT_PAGE_FAULT) {
+ u32 fault = mmu_read(PAGE_FAULT_ADDR);
+ dev_err(dev->dev, "mmu page fault at 0x%x from bus id %d of type %s on %s\n",
+ fault, LIMA_MMU_STATUS_BUS_ID(status),
+ status & LIMA_MMU_STATUS_PAGE_FAULT_IS_WRITE ? "write" : "read",
+ lima_ip_name(ip));
+ }
+
+ if (status & LIMA_MMU_INT_READ_BUS_ERROR) {
+ dev_err(dev->dev, "mmu %s irq bus error\n", lima_ip_name(ip));
+ }
+
+ /* mask all interrupts before resume */
+ mmu_write(INT_MASK, 0);
+ mmu_write(INT_CLEAR, status);
+
+ pipe = dev->pipe + (ip->id == lima_ip_gpmmu ? lima_pipe_gp : lima_pipe_pp);
+ lima_sched_pipe_mmu_error(pipe);
+
+ return IRQ_HANDLED;
+}
+
+int lima_mmu_init(struct lima_ip *ip)
+{
+ struct lima_device *dev = ip->dev;
+ int err;
+
+ if (ip->id == lima_ip_ppmmu_bcast)
+ return 0;
+
+ mmu_write(DTE_ADDR, 0xCAFEBABE);
+ if (mmu_read(DTE_ADDR) != 0xCAFEB000) {
+ dev_err(dev->dev, "mmu %s dte write test fail\n", lima_ip_name(ip));
+ return -EIO;
+ }
+
+ err = lima_mmu_send_command(LIMA_MMU_COMMAND_HARD_RESET, mmu_read(DTE_ADDR) == 0);
+ if (err)
+ return err;
+
+ err = devm_request_irq(dev->dev, ip->irq, lima_mmu_irq_handler,
+ IRQF_SHARED, lima_ip_name(ip), ip);
+ if (err) {
+ dev_err(dev->dev, "mmu %s fail to request irq\n", lima_ip_name(ip));
+ return err;
+ }
+
+ mmu_write(INT_MASK, LIMA_MMU_INT_PAGE_FAULT | LIMA_MMU_INT_READ_BUS_ERROR);
+ mmu_write(DTE_ADDR, *lima_bo_get_pages(dev->empty_vm->pd));
+ return lima_mmu_send_command(LIMA_MMU_COMMAND_ENABLE_PAGING,
+ mmu_read(STATUS) & LIMA_MMU_STATUS_PAGING_ENABLED);
+}
+
+void lima_mmu_fini(struct lima_ip *ip)
+{
+
+}
+
+void lima_mmu_switch_vm(struct lima_ip *ip, struct lima_vm *vm)
+{
+ struct lima_device *dev = ip->dev;
+
+ lima_mmu_send_command(LIMA_MMU_COMMAND_ENABLE_STALL,
+ mmu_read(STATUS) & LIMA_MMU_STATUS_STALL_ACTIVE);
+
+ if (vm)
+ mmu_write(DTE_ADDR, *lima_bo_get_pages(vm->pd));
+
+ /* flush the TLB */
+ mmu_write(COMMAND, LIMA_MMU_COMMAND_ZAP_CACHE);
+
+ lima_mmu_send_command(LIMA_MMU_COMMAND_DISABLE_STALL,
+ !(mmu_read(STATUS) & LIMA_MMU_STATUS_STALL_ACTIVE));
+}
+
+void lima_mmu_page_fault_resume(struct lima_ip *ip)
+{
+ struct lima_device *dev = ip->dev;
+ u32 status = mmu_read(STATUS);
+
+ if (status & LIMA_MMU_STATUS_PAGE_FAULT_ACTIVE) {
+ dev_info(dev->dev, "mmu resume\n");
+
+ mmu_write(INT_MASK, 0);
+ mmu_write(DTE_ADDR, 0xCAFEBABE);
+ lima_mmu_send_command(LIMA_MMU_COMMAND_HARD_RESET, mmu_read(DTE_ADDR) == 0);
+ mmu_write(INT_MASK, LIMA_MMU_INT_PAGE_FAULT | LIMA_MMU_INT_READ_BUS_ERROR);
+ mmu_write(DTE_ADDR, *lima_bo_get_pages(dev->empty_vm->pd));
+ lima_mmu_send_command(LIMA_MMU_COMMAND_ENABLE_PAGING,
+ mmu_read(STATUS) & LIMA_MMU_STATUS_PAGING_ENABLED);
+ }
+}
diff --git a/drivers/gpu/drm/lima/lima_mmu.h b/drivers/gpu/drm/lima/lima_mmu.h
new file mode 100644
index 000000000000..9930521ddfa1
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_mmu.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIMA_MMU_H__
+#define __LIMA_MMU_H__
+
+struct lima_ip;
+struct lima_vm;
+
+int lima_mmu_init(struct lima_ip *ip);
+void lima_mmu_fini(struct lima_ip *ip);
+
+void lima_mmu_switch_vm(struct lima_ip *ip, struct lima_vm *vm);
+void lima_mmu_page_fault_resume(struct lima_ip *ip);
+
+#endif
--
2.17.0
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related
* [PATCH v5 12/12] media: staging/imx: add i.MX7 entries to TODO file
From: Rui Miguel Silva @ 2018-05-18 9:28 UTC (permalink / raw)
To: mchehab, sakari.ailus, Steve Longerbeam, Philipp Zabel,
Rob Herring
Cc: devel, devicetree, Greg Kroah-Hartman, Ryan Harkin,
Rui Miguel Silva, Fabio Estevam, Shawn Guo, linux-clk,
linux-media
In-Reply-To: <20180518092806.3829-1-rui.silva@linaro.org>
Add some i.MX7 related entries to TODO file.
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
drivers/staging/media/imx/TODO | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/staging/media/imx/TODO b/drivers/staging/media/imx/TODO
index aeeb15494a49..6f29b5ca5324 100644
--- a/drivers/staging/media/imx/TODO
+++ b/drivers/staging/media/imx/TODO
@@ -45,3 +45,12 @@
Which means a port must not contain mixed-use endpoints, they
must all refer to media links between V4L2 subdevices.
+
+- i.MX7: all of the above, since it uses the imx media core
+
+- i.MX7: use Frame Interval Monitor
+
+- i.MX7: runtime testing with parallel sensor, links setup and streaming
+
+- i.MX7: runtime testing with different formats, for the time only 10-bit bayer
+ is tested
--
2.17.0
^ permalink raw reply related
* [PATCH RFC 15/24] drm/lima: add BCAST related function
From: Qiang Yu @ 2018-05-18 9:28 UTC (permalink / raw)
To: dri-devel, devicetree
Cc: Simon Shields, Marek Vasut, Connor Abbott, Neil Armstrong,
Andrei Paulau, Vasily Khoruzhick, Qiang Yu, Erico Nunes
In-Reply-To: <20180518092815.25280-1-yuq825@gmail.com>
BCAST is a hardware module to broadcast register
read/write for PPs. It can also merge IRQs from
different PPs into one IRQ.
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_bcast.c | 65 +++++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_bcast.h | 34 ++++++++++++++++
2 files changed, 99 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_bcast.c
create mode 100644 drivers/gpu/drm/lima/lima_bcast.h
diff --git a/drivers/gpu/drm/lima/lima_bcast.c b/drivers/gpu/drm/lima/lima_bcast.c
new file mode 100644
index 000000000000..32012a61ea6a
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_bcast.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/io.h>
+#include <linux/device.h>
+
+#include "lima_device.h"
+#include "lima_bcast.h"
+#include "lima_regs.h"
+
+#define bcast_write(reg, data) writel(data, ip->iomem + LIMA_BCAST_##reg)
+#define bcast_read(reg) readl(ip->iomem + LIMA_BCAST_##reg)
+
+void lima_bcast_enable(struct lima_device *dev)
+{
+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
+ struct lima_ip *ip = dev->ip + lima_ip_bcast;
+ int i, mask = 0;
+
+ for (i = 0; i < pipe->num_processor; i++) {
+ struct lima_ip *pp = pipe->processor[i];
+ mask |= 1 << (pp->id - lima_ip_pp0);
+ }
+
+ bcast_write(BROADCAST_MASK, (mask << 16) | mask);
+ bcast_write(INTERRUPT_MASK, mask);
+}
+
+void lima_bcast_disable(struct lima_device *dev)
+{
+ struct lima_ip *ip = dev->ip + lima_ip_bcast;
+
+ bcast_write(BROADCAST_MASK, 0);
+ bcast_write(INTERRUPT_MASK, 0);
+}
+
+int lima_bcast_init(struct lima_ip *ip)
+{
+ return 0;
+}
+
+void lima_bcast_fini(struct lima_ip *ip)
+{
+
+}
+
diff --git a/drivers/gpu/drm/lima/lima_bcast.h b/drivers/gpu/drm/lima/lima_bcast.h
new file mode 100644
index 000000000000..abafd4f613c7
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_bcast.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __LIMA_BCAST_H__
+#define __LIMA_BCAST_H__
+
+struct lima_ip;
+
+int lima_bcast_init(struct lima_ip *ip);
+void lima_bcast_fini(struct lima_ip *ip);
+
+void lima_bcast_enable(struct lima_device *dev);
+void lima_bcast_disable(struct lima_device *dev);
+
+#endif
--
2.17.0
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related
* [PATCH RFC 16/24] drm/lima: add DLBU related functions
From: Qiang Yu @ 2018-05-18 9:28 UTC (permalink / raw)
To: dri-devel, devicetree
Cc: Simon Shields, Marek Vasut, Connor Abbott, Neil Armstrong,
Andrei Paulau, Vasily Khoruzhick, Qiang Yu, Erico Nunes
In-Reply-To: <20180518092815.25280-1-yuq825@gmail.com>
DLBU is used to balance load among PPs.
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_dlbu.c | 75 ++++++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_dlbu.h | 37 ++++++++++++++++
2 files changed, 112 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_dlbu.c
create mode 100644 drivers/gpu/drm/lima/lima_dlbu.h
diff --git a/drivers/gpu/drm/lima/lima_dlbu.c b/drivers/gpu/drm/lima/lima_dlbu.c
new file mode 100644
index 000000000000..5281dd3c0417
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_dlbu.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/io.h>
+#include <linux/device.h>
+
+#include "lima_device.h"
+#include "lima_dlbu.h"
+#include "lima_vm.h"
+#include "lima_regs.h"
+
+#define dlbu_write(reg, data) writel(data, ip->iomem + LIMA_DLBU_##reg)
+#define dlbu_read(reg) readl(ip->iomem + LIMA_DLBU_##reg)
+
+void lima_dlbu_enable(struct lima_device *dev)
+{
+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
+ struct lima_ip *ip = dev->ip + lima_ip_dlbu;
+ int i, mask = 0;
+
+ for (i = 0; i < pipe->num_processor; i++) {
+ struct lima_ip *pp = pipe->processor[i];
+ mask |= 1 << (pp->id - lima_ip_pp0);
+ }
+
+ dlbu_write(PP_ENABLE_MASK, mask);
+}
+
+void lima_dlbu_disable(struct lima_device *dev)
+{
+ struct lima_ip *ip = dev->ip + lima_ip_dlbu;
+ dlbu_write(PP_ENABLE_MASK, 0);
+}
+
+void lima_dlbu_set_reg(struct lima_ip *ip, u32 *reg)
+{
+ dlbu_write(TLLIST_VBASEADDR, reg[0]);
+ dlbu_write(FB_DIM, reg[1]);
+ dlbu_write(TLLIST_CONF, reg[2]);
+ dlbu_write(START_TILE_POS, reg[3]);
+}
+
+int lima_dlbu_init(struct lima_ip *ip)
+{
+ struct lima_device *dev = ip->dev;
+
+ dlbu_write(MASTER_TLLIST_PHYS_ADDR, dev->dlbu_dma | 1);
+ dlbu_write(MASTER_TLLIST_VADDR, LIMA_VA_RESERVE_DLBU);
+
+ return 0;
+}
+
+void lima_dlbu_fini(struct lima_ip *ip)
+{
+
+}
diff --git a/drivers/gpu/drm/lima/lima_dlbu.h b/drivers/gpu/drm/lima/lima_dlbu.h
new file mode 100644
index 000000000000..4521a5dda9e0
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_dlbu.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __LIMA_DLBU_H__
+#define __LIMA_DLBU_H__
+
+struct lima_ip;
+struct lima_device;
+
+void lima_dlbu_enable(struct lima_device *dev);
+void lima_dlbu_disable(struct lima_device *dev);
+
+void lima_dlbu_set_reg(struct lima_ip *ip, u32 *reg);
+
+int lima_dlbu_init(struct lima_ip *ip);
+void lima_dlbu_fini(struct lima_ip *ip);
+
+#endif
--
2.17.0
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related
* [PATCH RFC 17/24] drm/lima: add GPU virtual memory space handing
From: Qiang Yu @ 2018-05-18 9:28 UTC (permalink / raw)
To: dri-devel, devicetree
Cc: Simon Shields, Marek Vasut, Connor Abbott, Neil Armstrong,
Andrei Paulau, Vasily Khoruzhick, Qiang Yu, Erico Nunes
In-Reply-To: <20180518092815.25280-1-yuq825@gmail.com>
From: Lima Project Developers <dri-devel@lists.freedesktop.org>
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
---
drivers/gpu/drm/lima/lima_vm.c | 312 +++++++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_vm.h | 73 ++++++++
2 files changed, 385 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_vm.c
create mode 100644 drivers/gpu/drm/lima/lima_vm.h
diff --git a/drivers/gpu/drm/lima/lima_vm.c b/drivers/gpu/drm/lima/lima_vm.c
new file mode 100644
index 000000000000..00a3f6b59a33
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_vm.c
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/interval_tree_generic.h>
+
+#include "lima_device.h"
+#include "lima_vm.h"
+#include "lima_object.h"
+#include "lima_regs.h"
+
+struct lima_bo_va_mapping {
+ struct list_head list;
+ struct rb_node rb;
+ uint32_t start;
+ uint32_t last;
+ uint32_t __subtree_last;
+};
+
+struct lima_bo_va {
+ struct list_head list;
+ unsigned ref_count;
+
+ struct list_head mapping;
+
+ struct lima_vm *vm;
+};
+
+#define LIMA_PDE(va) (va >> 22)
+#define LIMA_PTE(va) ((va & 0x3FFFFF) >> 12)
+
+#define START(node) ((node)->start)
+#define LAST(node) ((node)->last)
+
+INTERVAL_TREE_DEFINE(struct lima_bo_va_mapping, rb, uint32_t, __subtree_last,
+ START, LAST, static, lima_vm_it)
+
+#undef START
+#undef LAST
+
+static void lima_vm_unmap_page_table(struct lima_vm *vm, u32 start, u32 end)
+{
+ u32 addr;
+
+ for (addr = start; addr <= end; addr += LIMA_PAGE_SIZE) {
+ u32 pde = LIMA_PDE(addr);
+ u32 pte = LIMA_PTE(addr);
+ u32 *pt;
+
+ pt = lima_bo_kmap(vm->pt[pde]);
+ pt[pte] = 0;
+ }
+}
+
+static int lima_vm_map_page_table(struct lima_vm *vm, dma_addr_t *dma,
+ u32 start, u32 end)
+{
+ u64 addr;
+ int err, i = 0;
+
+ for (addr = start; addr <= end; addr += LIMA_PAGE_SIZE) {
+ u32 pde = LIMA_PDE(addr);
+ u32 pte = LIMA_PTE(addr);
+ u32 *pd, *pt;
+
+ if (vm->pt[pde])
+ pt = lima_bo_kmap(vm->pt[pde]);
+ else {
+ vm->pt[pde] = lima_bo_create(
+ vm->dev, LIMA_PAGE_SIZE, 0, ttm_bo_type_kernel,
+ NULL, vm->pd->tbo.resv);
+ if (IS_ERR(vm->pt[pde])) {
+ err = PTR_ERR(vm->pt[pde]);
+ goto err_out;
+ }
+
+ pt = lima_bo_kmap(vm->pt[pde]);
+ if (IS_ERR(pt)) {
+ err = PTR_ERR(pt);
+ goto err_out;
+ }
+
+ pd = lima_bo_kmap(vm->pd);
+ pd[pde] = *lima_bo_get_pages(vm->pt[pde]) | LIMA_VM_FLAG_PRESENT;
+ }
+
+ pt[pte] = dma[i++] | LIMA_VM_FLAGS_CACHE;
+ }
+
+ return 0;
+
+err_out:
+ if (addr != start)
+ lima_vm_unmap_page_table(vm, start, addr - 1);
+ return err;
+}
+
+static struct lima_bo_va *
+lima_vm_bo_find(struct lima_vm *vm, struct lima_bo *bo)
+{
+ struct lima_bo_va *bo_va, *ret = NULL;
+
+ list_for_each_entry(bo_va, &bo->va, list) {
+ if (bo_va->vm == vm) {
+ ret = bo_va;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+int lima_vm_bo_map(struct lima_vm *vm, struct lima_bo *bo, u32 start)
+{
+ int err;
+ struct lima_bo_va_mapping *it, *mapping;
+ u32 end = start + bo->gem.size - 1;
+ dma_addr_t *pages_dma = lima_bo_get_pages(bo);
+ struct lima_bo_va *bo_va;
+
+ it = lima_vm_it_iter_first(&vm->va, start, end);
+ if (it) {
+ dev_dbg(bo->gem.dev->dev, "lima vm map va overlap %x-%x %x-%x\n",
+ start, end, it->start, it->last);
+ return -EINVAL;
+ }
+
+ mapping = kmalloc(sizeof(*mapping), GFP_KERNEL);
+ if (!mapping)
+ return -ENOMEM;
+ mapping->start = start;
+ mapping->last = end;
+
+ err = lima_vm_map_page_table(vm, pages_dma, start, end);
+ if (err) {
+ kfree(mapping);
+ return err;
+ }
+
+ lima_vm_it_insert(mapping, &vm->va);
+
+ bo_va = lima_vm_bo_find(vm, bo);
+ list_add_tail(&mapping->list, &bo_va->mapping);
+
+ return 0;
+}
+
+static void lima_vm_unmap(struct lima_vm *vm,
+ struct lima_bo_va_mapping *mapping)
+{
+ lima_vm_it_remove(mapping, &vm->va);
+
+ lima_vm_unmap_page_table(vm, mapping->start, mapping->last);
+
+ list_del(&mapping->list);
+ kfree(mapping);
+}
+
+int lima_vm_bo_unmap(struct lima_vm *vm, struct lima_bo *bo, u32 start)
+{
+ struct lima_bo_va *bo_va;
+ struct lima_bo_va_mapping *mapping;
+
+ bo_va = lima_vm_bo_find(vm, bo);
+ list_for_each_entry(mapping, &bo_va->mapping, list) {
+ if (mapping->start == start) {
+ lima_vm_unmap(vm, mapping);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+int lima_vm_bo_add(struct lima_vm *vm, struct lima_bo *bo)
+{
+ struct lima_bo_va *bo_va;
+
+ bo_va = lima_vm_bo_find(vm, bo);
+ if (bo_va) {
+ bo_va->ref_count++;
+ return 0;
+ }
+
+ bo_va = kmalloc(sizeof(*bo_va), GFP_KERNEL);
+ if (!bo_va)
+ return -ENOMEM;
+
+ bo_va->vm = vm;
+ bo_va->ref_count = 1;
+ INIT_LIST_HEAD(&bo_va->mapping);
+ list_add_tail(&bo_va->list, &bo->va);
+ return 0;
+}
+
+int lima_vm_bo_del(struct lima_vm *vm, struct lima_bo *bo)
+{
+ struct lima_bo_va *bo_va;
+ struct lima_bo_va_mapping *mapping, *tmp;
+
+ bo_va = lima_vm_bo_find(vm, bo);
+ if (--bo_va->ref_count > 0)
+ return 0;
+
+ list_for_each_entry_safe(mapping, tmp, &bo_va->mapping, list) {
+ lima_vm_unmap(vm, mapping);
+ }
+ list_del(&bo_va->list);
+ kfree(bo_va);
+ return 0;
+}
+
+struct lima_vm *lima_vm_create(struct lima_device *dev)
+{
+ struct lima_vm *vm;
+ void *pd;
+
+ vm = kzalloc(sizeof(*vm), GFP_KERNEL);
+ if (!vm)
+ return NULL;
+
+ vm->dev = dev;
+ vm->va = RB_ROOT_CACHED;
+ kref_init(&vm->refcount);
+
+ vm->pd = lima_bo_create(dev, LIMA_PAGE_SIZE, 0,
+ ttm_bo_type_kernel, NULL, NULL);
+ if (IS_ERR(vm->pd))
+ goto err_out0;
+
+ pd = lima_bo_kmap(vm->pd);
+ if (IS_ERR(pd))
+ goto err_out1;
+
+ if (dev->dlbu_cpu) {
+ int err = lima_vm_map_page_table(
+ vm, &dev->dlbu_dma, LIMA_VA_RESERVE_DLBU,
+ LIMA_VA_RESERVE_DLBU + LIMA_PAGE_SIZE - 1);
+ if (err)
+ goto err_out1;
+ }
+
+ return vm;
+
+err_out1:
+ lima_bo_unref(vm->pd);
+err_out0:
+ kfree(vm);
+ return NULL;
+}
+
+void lima_vm_release(struct kref *kref)
+{
+ struct lima_vm *vm = container_of(kref, struct lima_vm, refcount);
+ struct lima_device *dev = vm->dev;
+ int i;
+
+ if (!RB_EMPTY_ROOT(&vm->va.rb_root)) {
+ dev_err(dev->dev, "still active bo inside vm\n");
+ }
+
+ for (i = 0; i < LIMA_PAGE_ENT_NUM; i++) {
+ if (vm->pt[i])
+ lima_bo_unref(vm->pt[i]);
+ }
+
+ if (vm->pd)
+ lima_bo_unref(vm->pd);
+
+ kfree(vm);
+}
+
+void lima_vm_print(struct lima_vm *vm)
+{
+ int i, j;
+ u32 *pd = lima_bo_kmap(vm->pd);
+
+ /* to avoid the defined by not used warning */
+ (void)&lima_vm_it_iter_next;
+
+ for (i = 0; i < LIMA_PAGE_ENT_NUM; i++) {
+ if (pd[i]) {
+ u32 *pt = lima_bo_kmap(vm->pt[i]);
+
+ printk(KERN_INFO "lima vm pd %03x:%08x\n", i, pd[i]);
+ for (j = 0; j < LIMA_PAGE_ENT_NUM; j++) {
+ if (pt[j])
+ printk(KERN_INFO " pt %03x:%08x\n", j, pt[j]);
+ }
+ }
+ }
+}
diff --git a/drivers/gpu/drm/lima/lima_vm.h b/drivers/gpu/drm/lima/lima_vm.h
new file mode 100644
index 000000000000..20506459def0
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_vm.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIMA_VM_H__
+#define __LIMA_VM_H__
+
+#include <linux/rbtree.h>
+#include <linux/kref.h>
+
+#define LIMA_PAGE_SIZE 4096
+#define LIMA_PAGE_MASK (LIMA_PAGE_SIZE - 1)
+#define LIMA_PAGE_ENT_NUM (LIMA_PAGE_SIZE / sizeof(u32))
+
+#define LIMA_VA_RESERVE_START 0xFFF00000
+#define LIMA_VA_RESERVE_DLBU LIMA_VA_RESERVE_START
+#define LIMA_VA_RESERVE_END 0x100000000
+
+struct lima_bo;
+struct lima_device;
+
+struct lima_vm {
+ struct kref refcount;
+
+ /* tree of virtual addresses mapped */
+ struct rb_root_cached va;
+
+ struct lima_device *dev;
+
+ struct lima_bo *pd;
+ struct lima_bo *pt[LIMA_PAGE_ENT_NUM];
+};
+
+int lima_vm_bo_map(struct lima_vm *vm, struct lima_bo *bo, u32 start);
+int lima_vm_bo_unmap(struct lima_vm *vm, struct lima_bo *bo, u32 start);
+
+int lima_vm_bo_add(struct lima_vm *vm, struct lima_bo *bo);
+int lima_vm_bo_del(struct lima_vm *vm, struct lima_bo *bo);
+
+struct lima_vm *lima_vm_create(struct lima_device *dev);
+void lima_vm_release(struct kref *kref);
+
+static inline struct lima_vm *lima_vm_get(struct lima_vm *vm)
+{
+ kref_get(&vm->refcount);
+ return vm;
+}
+
+static inline void lima_vm_put(struct lima_vm *vm)
+{
+ kref_put(&vm->refcount, lima_vm_release);
+}
+
+void lima_vm_print(struct lima_vm *vm);
+
+#endif
--
2.17.0
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related
* [PATCH RFC 18/24] drm/lima: add TTM subsystem functions
From: Qiang Yu @ 2018-05-18 9:28 UTC (permalink / raw)
To: dri-devel, devicetree
Cc: Simon Shields, Marek Vasut, Connor Abbott, Neil Armstrong,
Andrei Paulau, Vasily Khoruzhick, Qiang Yu, Erico Nunes
In-Reply-To: <20180518092815.25280-1-yuq825@gmail.com>
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_ttm.c | 409 ++++++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_ttm.h | 44 ++++
2 files changed, 453 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_ttm.c
create mode 100644 drivers/gpu/drm/lima/lima_ttm.h
diff --git a/drivers/gpu/drm/lima/lima_ttm.c b/drivers/gpu/drm/lima/lima_ttm.c
new file mode 100644
index 000000000000..5325f3f48ae7
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_ttm.c
@@ -0,0 +1,409 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/mm.h>
+#include <drm/ttm/ttm_page_alloc.h>
+
+#include "lima_drv.h"
+#include "lima_device.h"
+#include "lima_object.h"
+
+
+static int lima_ttm_mem_global_init(struct drm_global_reference *ref)
+{
+ return ttm_mem_global_init(ref->object);
+}
+
+static void lima_ttm_mem_global_release(struct drm_global_reference *ref)
+{
+ ttm_mem_global_release(ref->object);
+}
+
+static int lima_ttm_global_init(struct lima_device *dev)
+{
+ struct drm_global_reference *global_ref;
+ int err;
+
+ dev->mman.mem_global_referenced = false;
+ global_ref = &dev->mman.mem_global_ref;
+ global_ref->global_type = DRM_GLOBAL_TTM_MEM;
+ global_ref->size = sizeof(struct ttm_mem_global);
+ global_ref->init = &lima_ttm_mem_global_init;
+ global_ref->release = &lima_ttm_mem_global_release;
+
+ err = drm_global_item_ref(global_ref);
+ if (err != 0) {
+ dev_err(dev->dev, "Failed setting up TTM memory accounting "
+ "subsystem.\n");
+ return err;
+ }
+
+ dev->mman.bo_global_ref.mem_glob =
+ dev->mman.mem_global_ref.object;
+ global_ref = &dev->mman.bo_global_ref.ref;
+ global_ref->global_type = DRM_GLOBAL_TTM_BO;
+ global_ref->size = sizeof(struct ttm_bo_global);
+ global_ref->init = &ttm_bo_global_init;
+ global_ref->release = &ttm_bo_global_release;
+ err = drm_global_item_ref(global_ref);
+ if (err != 0) {
+ dev_err(dev->dev, "Failed setting up TTM BO subsystem.\n");
+ drm_global_item_unref(&dev->mman.mem_global_ref);
+ return err;
+ }
+
+ dev->mman.mem_global_referenced = true;
+ return 0;
+}
+
+static void lima_ttm_global_fini(struct lima_device *dev)
+{
+ if (dev->mman.mem_global_referenced) {
+ drm_global_item_unref(&dev->mman.bo_global_ref.ref);
+ drm_global_item_unref(&dev->mman.mem_global_ref);
+ dev->mman.mem_global_referenced = false;
+ }
+}
+
+struct lima_tt_mgr {
+ spinlock_t lock;
+ unsigned long available;
+};
+
+static int lima_ttm_bo_man_init(struct ttm_mem_type_manager *man,
+ unsigned long p_size)
+{
+ struct lima_tt_mgr *mgr;
+
+ mgr = kmalloc(sizeof(*mgr), GFP_KERNEL);
+ if (!mgr)
+ return -ENOMEM;
+
+ spin_lock_init(&mgr->lock);
+ mgr->available = p_size;
+ man->priv = mgr;
+ return 0;
+}
+
+static int lima_ttm_bo_man_takedown(struct ttm_mem_type_manager *man)
+{
+ struct lima_tt_mgr *mgr = man->priv;
+
+ kfree(mgr);
+ man->priv = NULL;
+ return 0;
+}
+
+static int lima_ttm_bo_man_get_node(struct ttm_mem_type_manager *man,
+ struct ttm_buffer_object *bo,
+ const struct ttm_place *place,
+ struct ttm_mem_reg *mem)
+{
+ struct lima_tt_mgr *mgr = man->priv;
+
+ /* don't exceed the mem limit */
+ spin_lock(&mgr->lock);
+ if (mgr->available < mem->num_pages) {
+ spin_unlock(&mgr->lock);
+ return 0;
+ }
+ mgr->available -= mem->num_pages;
+ spin_unlock(&mgr->lock);
+
+ /* just fake a non-null pointer to tell caller success */
+ mem->mm_node = (void *)1;
+ return 0;
+}
+
+static void lima_ttm_bo_man_put_node(struct ttm_mem_type_manager *man,
+ struct ttm_mem_reg *mem)
+{
+ struct lima_tt_mgr *mgr = man->priv;
+
+ spin_lock(&mgr->lock);
+ mgr->available += mem->num_pages;
+ spin_unlock(&mgr->lock);
+
+ mem->mm_node = NULL;
+}
+
+static void lima_ttm_bo_man_debug(struct ttm_mem_type_manager *man,
+ struct drm_printer *printer)
+{
+}
+
+static const struct ttm_mem_type_manager_func lima_bo_manager_func = {
+ .init = lima_ttm_bo_man_init,
+ .takedown = lima_ttm_bo_man_takedown,
+ .get_node = lima_ttm_bo_man_get_node,
+ .put_node = lima_ttm_bo_man_put_node,
+ .debug = lima_ttm_bo_man_debug
+};
+
+static int lima_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
+ struct ttm_mem_type_manager *man)
+{
+ struct lima_device *dev = ttm_to_lima_dev(bdev);
+
+ switch (type) {
+ case TTM_PL_SYSTEM:
+ /* System memory */
+ man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
+ man->available_caching = TTM_PL_MASK_CACHING;
+ man->default_caching = TTM_PL_FLAG_CACHED;
+ break;
+ case TTM_PL_TT:
+ man->func = &lima_bo_manager_func;
+ man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
+ man->available_caching = TTM_PL_MASK_CACHING;
+ man->default_caching = TTM_PL_FLAG_CACHED;
+ break;
+ default:
+ dev_err(dev->dev, "Unsupported memory type %u\n",
+ (unsigned int)type);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int lima_ttm_backend_bind(struct ttm_tt *ttm,
+ struct ttm_mem_reg *bo_mem)
+{
+ return 0;
+}
+
+static int lima_ttm_backend_unbind(struct ttm_tt *ttm)
+{
+ return 0;
+}
+
+static void lima_ttm_backend_destroy(struct ttm_tt *ttm)
+{
+ struct lima_ttm_tt *tt = (void *)ttm;
+
+ ttm_dma_tt_fini(&tt->ttm);
+ kfree(tt);
+}
+
+static struct ttm_backend_func lima_ttm_backend_func = {
+ .bind = &lima_ttm_backend_bind,
+ .unbind = &lima_ttm_backend_unbind,
+ .destroy = &lima_ttm_backend_destroy,
+};
+
+static struct ttm_tt *lima_ttm_tt_create(struct ttm_buffer_object *bo,
+ uint32_t page_flags)
+{
+ struct lima_ttm_tt *tt;
+
+ tt = kzalloc(sizeof(struct lima_ttm_tt), GFP_KERNEL);
+ if (tt == NULL)
+ return NULL;
+
+ tt->ttm.ttm.func = &lima_ttm_backend_func;
+
+ if (ttm_sg_tt_init(&tt->ttm, bo, page_flags)) {
+ kfree(tt);
+ return NULL;
+ }
+
+ return &tt->ttm.ttm;
+}
+
+static int lima_ttm_tt_populate(struct ttm_tt *ttm,
+ struct ttm_operation_ctx *ctx)
+{
+ struct lima_device *dev = ttm_to_lima_dev(ttm->bdev);
+ struct lima_ttm_tt *tt = (void *)ttm;
+ bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
+
+ if (slave) {
+ drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
+ tt->ttm.dma_address,
+ ttm->num_pages);
+ ttm->state = tt_unbound;
+ return 0;
+ }
+
+ return ttm_populate_and_map_pages(dev->dev, &tt->ttm, ctx);
+}
+
+static void lima_ttm_tt_unpopulate(struct ttm_tt *ttm)
+{
+ struct lima_device *dev = ttm_to_lima_dev(ttm->bdev);
+ struct lima_ttm_tt *tt = (void *)ttm;
+ bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
+
+ if (slave)
+ return;
+
+ ttm_unmap_and_unpopulate_pages(dev->dev, &tt->ttm);
+}
+
+static int lima_invalidate_caches(struct ttm_bo_device *bdev,
+ uint32_t flags)
+{
+ struct lima_device *dev = ttm_to_lima_dev(bdev);
+
+ dev_err(dev->dev, "%s not implemented\n", __FUNCTION__);
+ return 0;
+}
+
+static void lima_evict_flags(struct ttm_buffer_object *tbo,
+ struct ttm_placement *placement)
+{
+ struct lima_bo *bo = ttm_to_lima_bo(tbo);
+ struct lima_device *dev = to_lima_dev(bo->gem.dev);
+
+ dev_err(dev->dev, "%s not implemented\n", __FUNCTION__);
+}
+
+static int lima_verify_access(struct ttm_buffer_object *tbo,
+ struct file *filp)
+{
+ struct lima_bo *bo = ttm_to_lima_bo(tbo);
+
+ return drm_vma_node_verify_access(&bo->gem.vma_node,
+ filp->private_data);
+}
+
+static int lima_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
+ struct ttm_mem_reg *mem)
+{
+ struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
+
+ mem->bus.addr = NULL;
+ mem->bus.offset = 0;
+ mem->bus.size = mem->num_pages << PAGE_SHIFT;
+ mem->bus.base = 0;
+ mem->bus.is_iomem = false;
+
+ if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
+ return -EINVAL;
+
+ switch (mem->mem_type) {
+ case TTM_PL_SYSTEM:
+ case TTM_PL_TT:
+ return 0;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static void lima_ttm_io_mem_free(struct ttm_bo_device *bdev,
+ struct ttm_mem_reg *mem)
+{
+
+}
+
+static void lima_bo_move_notify(struct ttm_buffer_object *tbo, bool evict,
+ struct ttm_mem_reg *new_mem)
+{
+ struct lima_bo *bo = ttm_to_lima_bo(tbo);
+ struct lima_device *dev = to_lima_dev(bo->gem.dev);
+
+ if (evict)
+ dev_err(dev->dev, "%s not implemented\n", __FUNCTION__);
+}
+
+static void lima_bo_swap_notify(struct ttm_buffer_object *tbo)
+{
+ struct lima_bo *bo = ttm_to_lima_bo(tbo);
+ struct lima_device *dev = to_lima_dev(bo->gem.dev);
+
+ dev_err(dev->dev, "%s not implemented\n", __FUNCTION__);
+}
+
+static struct ttm_bo_driver lima_bo_driver = {
+ .ttm_tt_create = lima_ttm_tt_create,
+ .ttm_tt_populate = lima_ttm_tt_populate,
+ .ttm_tt_unpopulate = lima_ttm_tt_unpopulate,
+ .invalidate_caches = lima_invalidate_caches,
+ .init_mem_type = lima_init_mem_type,
+ .eviction_valuable = ttm_bo_eviction_valuable,
+ .evict_flags = lima_evict_flags,
+ .verify_access = lima_verify_access,
+ .io_mem_reserve = lima_ttm_io_mem_reserve,
+ .io_mem_free = lima_ttm_io_mem_free,
+ .move_notify = lima_bo_move_notify,
+ .swap_notify = lima_bo_swap_notify,
+};
+
+int lima_ttm_init(struct lima_device *dev)
+{
+ int err;
+ bool need_dma32;
+ u64 gtt_size;
+
+ err = lima_ttm_global_init(dev);
+ if (err)
+ return err;
+
+#if defined(CONFIG_ARM) && !defined(CONFIG_ARM_LPAE)
+ need_dma32 = false;
+#else
+ need_dma32 = true;
+#endif
+
+ err = ttm_bo_device_init(&dev->mman.bdev,
+ dev->mman.bo_global_ref.ref.object,
+ &lima_bo_driver,
+ dev->ddev->anon_inode->i_mapping,
+ DRM_FILE_PAGE_OFFSET,
+ need_dma32);
+ if (err) {
+ dev_err(dev->dev, "failed initializing buffer object "
+ "driver(%d).\n", err);
+ goto err_out0;
+ }
+
+ if (lima_max_mem < 0) {
+ struct sysinfo si;
+ si_meminfo(&si);
+ /* TODO: better to have lower 32 mem size */
+ gtt_size = min(((u64)si.totalram * si.mem_unit * 3/4),
+ 0x100000000ULL);
+ }
+ else
+ gtt_size = (u64)lima_max_mem << 20;
+
+ err = ttm_bo_init_mm(&dev->mman.bdev, TTM_PL_TT, gtt_size >> PAGE_SHIFT);
+ if (err) {
+ dev_err(dev->dev, "Failed initializing GTT heap.\n");
+ goto err_out1;
+ }
+ return 0;
+
+err_out1:
+ ttm_bo_device_release(&dev->mman.bdev);
+err_out0:
+ lima_ttm_global_fini(dev);
+ return err;
+}
+
+void lima_ttm_fini(struct lima_device *dev)
+{
+ ttm_bo_device_release(&dev->mman.bdev);
+ lima_ttm_global_fini(dev);
+ dev_info(dev->dev, "ttm finalized\n");
+}
diff --git a/drivers/gpu/drm/lima/lima_ttm.h b/drivers/gpu/drm/lima/lima_ttm.h
new file mode 100644
index 000000000000..1d36d06a47a3
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_ttm.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIMA_TTM_H__
+#define __LIMA_TTM_H__
+
+#include <drm/ttm/ttm_bo_driver.h>
+
+struct lima_mman {
+ struct ttm_bo_global_ref bo_global_ref;
+ struct drm_global_reference mem_global_ref;
+ struct ttm_bo_device bdev;
+ bool mem_global_referenced;
+};
+
+struct lima_ttm_tt {
+ struct ttm_dma_tt ttm;
+};
+
+struct lima_device;
+struct lima_bo;
+
+int lima_ttm_init(struct lima_device *dev);
+void lima_ttm_fini(struct lima_device *dev);
+
+#endif
--
2.17.0
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related
* [PATCH RFC 19/24] drm/lima: add buffer object functions
From: Qiang Yu @ 2018-05-18 9:28 UTC (permalink / raw)
To: dri-devel, devicetree
Cc: Simon Shields, Marek Vasut, Connor Abbott, Neil Armstrong,
Andrei Paulau, Vasily Khoruzhick, Qiang Yu, Erico Nunes
In-Reply-To: <20180518092815.25280-1-yuq825@gmail.com>
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_object.c | 120 +++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_object.h | 87 +++++++++++++++++++++
2 files changed, 207 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_object.c
create mode 100644 drivers/gpu/drm/lima/lima_object.h
diff --git a/drivers/gpu/drm/lima/lima_object.c b/drivers/gpu/drm/lima/lima_object.c
new file mode 100644
index 000000000000..5a22b235626b
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_object.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <drm/drm_prime.h>
+
+#include "lima_object.h"
+
+static void lima_bo_init_placement(struct lima_bo *bo)
+{
+ struct ttm_placement *placement = &bo->placement;
+ struct ttm_place *place = &bo->place;
+
+ place->fpfn = 0;
+ place->lpfn = 0;
+ place->flags = TTM_PL_FLAG_TT | TTM_PL_FLAG_WC;
+
+ /* pin all bo for now */
+ place->flags |= TTM_PL_FLAG_NO_EVICT;
+
+ placement->num_placement = 1;
+ placement->placement = place;
+
+ placement->num_busy_placement = 1;
+ placement->busy_placement = place;
+}
+
+static void lima_bo_destroy(struct ttm_buffer_object *tbo)
+{
+ struct lima_bo *bo = ttm_to_lima_bo(tbo);
+
+ if (bo->gem.import_attach)
+ drm_prime_gem_destroy(&bo->gem, bo->tbo.sg);
+ drm_gem_object_release(&bo->gem);
+ kfree(bo);
+}
+
+struct lima_bo *lima_bo_create(struct lima_device *dev, u64 size,
+ u32 flags, enum ttm_bo_type type,
+ struct sg_table *sg,
+ struct reservation_object *resv)
+{
+ struct lima_bo *bo;
+ struct ttm_mem_type_manager *man;
+ size_t acc_size;
+ int err;
+
+ size = PAGE_ALIGN(size);
+ man = dev->mman.bdev.man + TTM_PL_TT;
+ if (size >= (man->size << PAGE_SHIFT))
+ return ERR_PTR(-ENOMEM);
+
+ acc_size = ttm_bo_dma_acc_size(&dev->mman.bdev, size,
+ sizeof(struct lima_bo));
+
+ bo = kzalloc(sizeof(*bo), GFP_KERNEL);
+ if (!bo)
+ return ERR_PTR(-ENOMEM);
+
+ drm_gem_private_object_init(dev->ddev, &bo->gem, size);
+
+ INIT_LIST_HEAD(&bo->va);
+
+ bo->tbo.bdev = &dev->mman.bdev;
+
+ lima_bo_init_placement(bo);
+
+ err = ttm_bo_init(&dev->mman.bdev, &bo->tbo, size, type,
+ &bo->placement, 0, type != ttm_bo_type_kernel,
+ acc_size, sg, resv, &lima_bo_destroy);
+ if (err)
+ goto err_out;
+
+ return bo;
+
+err_out:
+ kfree(bo);
+ return ERR_PTR(err);
+}
+
+dma_addr_t *lima_bo_get_pages(struct lima_bo *bo)
+{
+ struct lima_ttm_tt *ttm = (void *)bo->tbo.ttm;
+ return ttm->ttm.dma_address;
+}
+
+void *lima_bo_kmap(struct lima_bo *bo)
+{
+ bool is_iomem;
+ void *ret;
+ int err;
+
+ ret = ttm_kmap_obj_virtual(&bo->kmap, &is_iomem);
+ if (ret)
+ return ret;
+
+ err = ttm_bo_kmap(&bo->tbo, 0, bo->tbo.num_pages, &bo->kmap);
+ if (err)
+ return ERR_PTR(err);
+
+ return ttm_kmap_obj_virtual(&bo->kmap, &is_iomem);
+}
diff --git a/drivers/gpu/drm/lima/lima_object.h b/drivers/gpu/drm/lima/lima_object.h
new file mode 100644
index 000000000000..2b8b8fcb9063
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_object.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIMA_OBJECT_H__
+#define __LIMA_OBJECT_H__
+
+#include <drm/drm_gem.h>
+#include <drm/ttm/ttm_placement.h>
+#include <drm/ttm/ttm_bo_api.h>
+
+#include "lima_device.h"
+
+struct lima_bo {
+ struct drm_gem_object gem;
+
+ struct ttm_place place;
+ struct ttm_placement placement;
+ struct ttm_buffer_object tbo;
+ struct ttm_bo_kmap_obj kmap;
+
+ struct list_head va;
+};
+
+static inline struct lima_bo *
+to_lima_bo(struct drm_gem_object *obj)
+{
+ return container_of(obj, struct lima_bo, gem);
+}
+
+static inline struct lima_bo *
+ttm_to_lima_bo(struct ttm_buffer_object *tbo)
+{
+ return container_of(tbo, struct lima_bo, tbo);
+}
+
+static inline int lima_bo_reserve(struct lima_bo *bo, bool intr)
+{
+ struct lima_device *dev = ttm_to_lima_dev(bo->tbo.bdev);
+ int r;
+
+ r = ttm_bo_reserve(&bo->tbo, intr, false, NULL);
+ if (unlikely(r != 0)) {
+ if (r != -ERESTARTSYS)
+ dev_err(dev->dev, "%p reserve failed\n", bo);
+ return r;
+ }
+ return 0;
+}
+
+static inline void lima_bo_unreserve(struct lima_bo *bo)
+{
+ ttm_bo_unreserve(&bo->tbo);
+}
+
+struct lima_bo *lima_bo_create(struct lima_device *dev, u64 size,
+ u32 flags, enum ttm_bo_type type,
+ struct sg_table *sg,
+ struct reservation_object *resv);
+
+static inline void lima_bo_unref(struct lima_bo *bo)
+{
+ struct ttm_buffer_object *tbo = &bo->tbo;
+ ttm_bo_unref(&tbo);
+}
+
+dma_addr_t *lima_bo_get_pages(struct lima_bo *bo);
+void *lima_bo_kmap(struct lima_bo *bo);
+
+#endif
--
2.17.0
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related
* [PATCH RFC 20/24] drm/lima: add GEM related functions
From: Qiang Yu @ 2018-05-18 9:28 UTC (permalink / raw)
To: dri-devel, devicetree
Cc: Simon Shields, Marek Vasut, Connor Abbott, Neil Armstrong,
Andrei Paulau, Vasily Khoruzhick, Qiang Yu, Erico Nunes
In-Reply-To: <20180518092815.25280-1-yuq825@gmail.com>
From: Lima Project Developers <dri-devel@lists.freedesktop.org>
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Signed-off-by: Erico Nunes <nunes.erico@gmail.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
drivers/gpu/drm/lima/lima_gem.c | 459 ++++++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_gem.h | 41 +++
2 files changed, 500 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_gem.c
create mode 100644 drivers/gpu/drm/lima/lima_gem.h
diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c
new file mode 100644
index 000000000000..1ad3f38ddfde
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_gem.c
@@ -0,0 +1,459 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <drm/drmP.h>
+#include <linux/dma-mapping.h>
+#include <linux/pagemap.h>
+#include <linux/sync_file.h>
+
+#include <drm/lima_drm.h>
+
+#include "lima_drv.h"
+#include "lima_gem.h"
+#include "lima_vm.h"
+#include "lima_object.h"
+
+int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file,
+ u32 size, u32 flags, u32 *handle)
+{
+ int err;
+ struct lima_bo *bo;
+ struct lima_device *ldev = to_lima_dev(dev);
+
+ bo = lima_bo_create(ldev, size, flags, ttm_bo_type_device, NULL, NULL);
+ if (IS_ERR(bo))
+ return PTR_ERR(bo);
+
+ err = drm_gem_handle_create(file, &bo->gem, handle);
+
+ /* drop reference from allocate - handle holds it now */
+ drm_gem_object_put_unlocked(&bo->gem);
+
+ return err;
+}
+
+void lima_gem_free_object(struct drm_gem_object *obj)
+{
+ struct lima_bo *bo = to_lima_bo(obj);
+
+ if (!list_empty(&bo->va))
+ dev_err(obj->dev->dev, "lima gem free bo still has va\n");
+
+ lima_bo_unref(bo);
+}
+
+int lima_gem_object_open(struct drm_gem_object *obj, struct drm_file *file)
+{
+ struct lima_bo *bo = to_lima_bo(obj);
+ struct lima_drm_priv *priv = to_lima_drm_priv(file);
+ struct lima_vm *vm = priv->vm;
+ int err;
+
+ err = lima_bo_reserve(bo, true);
+ if (err)
+ return err;
+
+ err = lima_vm_bo_add(vm, bo);
+
+ lima_bo_unreserve(bo);
+ return err;
+}
+
+void lima_gem_object_close(struct drm_gem_object *obj, struct drm_file *file)
+{
+ struct lima_bo *bo = to_lima_bo(obj);
+ struct lima_device *dev = to_lima_dev(obj->dev);
+ struct lima_drm_priv *priv = to_lima_drm_priv(file);
+ struct lima_vm *vm = priv->vm;
+
+ LIST_HEAD(list);
+ struct ttm_validate_buffer tv_bo, tv_pd;
+ struct ww_acquire_ctx ticket;
+ int r;
+
+ tv_bo.bo = &bo->tbo;
+ tv_bo.shared = true;
+ list_add(&tv_bo.head, &list);
+
+ tv_pd.bo = &vm->pd->tbo;
+ tv_pd.shared = true;
+ list_add(&tv_pd.head, &list);
+
+ r = ttm_eu_reserve_buffers(&ticket, &list, false, NULL);
+ if (r) {
+ dev_err(dev->dev, "leeking bo va because we "
+ "fail to reserve bo (%d)\n", r);
+ return;
+ }
+
+ lima_vm_bo_del(vm, bo);
+
+ ttm_eu_backoff_reservation(&ticket, &list);
+}
+
+int lima_gem_mmap_offset(struct drm_file *file, u32 handle, u64 *offset)
+{
+ struct drm_gem_object *obj;
+ struct lima_bo *bo;
+
+ obj = drm_gem_object_lookup(file, handle);
+ if (!obj)
+ return -ENOENT;
+
+ bo = to_lima_bo(obj);
+ *offset = drm_vma_node_offset_addr(&bo->tbo.vma_node);
+
+ drm_gem_object_put_unlocked(obj);
+ return 0;
+}
+
+int lima_gem_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ struct drm_file *file_priv;
+ struct lima_device *dev;
+
+ if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET))
+ return -EINVAL;
+
+ file_priv = filp->private_data;
+ dev = file_priv->minor->dev->dev_private;
+ if (dev == NULL)
+ return -EINVAL;
+
+ return ttm_bo_mmap(filp, vma, &dev->mman.bdev);
+}
+
+int lima_gem_va_map(struct drm_file *file, u32 handle, u32 flags, u32 va)
+{
+ struct lima_drm_priv *priv = to_lima_drm_priv(file);
+ struct lima_vm *vm = priv->vm;
+ struct drm_gem_object *obj;
+ struct lima_bo *bo;
+ struct lima_device *dev;
+ int err;
+
+ LIST_HEAD(list);
+ struct ttm_validate_buffer tv_bo, tv_pd;
+ struct ww_acquire_ctx ticket;
+
+ if (!PAGE_ALIGNED(va))
+ return -EINVAL;
+
+ obj = drm_gem_object_lookup(file, handle);
+ if (!obj)
+ return -ENOENT;
+
+ bo = to_lima_bo(obj);
+ dev = to_lima_dev(obj->dev);
+
+ /* carefully handle overflow when calculate range */
+ if (va < dev->va_start || dev->va_end - obj->size < va) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ tv_bo.bo = &bo->tbo;
+ tv_bo.shared = true;
+ list_add(&tv_bo.head, &list);
+
+ tv_pd.bo = &vm->pd->tbo;
+ tv_pd.shared = true;
+ list_add(&tv_pd.head, &list);
+
+ err = ttm_eu_reserve_buffers(&ticket, &list, false, NULL);
+ if (err)
+ goto out;
+
+ err = lima_vm_bo_map(vm, bo, va);
+
+ ttm_eu_backoff_reservation(&ticket, &list);
+out:
+ drm_gem_object_put_unlocked(obj);
+ return err;
+}
+
+int lima_gem_va_unmap(struct drm_file *file, u32 handle, u32 va)
+{
+ struct lima_drm_priv *priv = to_lima_drm_priv(file);
+ struct lima_vm *vm = priv->vm;
+ struct drm_gem_object *obj;
+ struct lima_bo *bo;
+ int err;
+
+ LIST_HEAD(list);
+ struct ttm_validate_buffer tv_bo, tv_pd;
+ struct ww_acquire_ctx ticket;
+
+ if (!PAGE_ALIGNED(va))
+ return -EINVAL;
+
+ obj = drm_gem_object_lookup(file, handle);
+ if (!obj)
+ return -ENOENT;
+
+ bo = to_lima_bo(obj);
+
+ tv_bo.bo = &bo->tbo;
+ tv_bo.shared = true;
+ list_add(&tv_bo.head, &list);
+
+ tv_pd.bo = &vm->pd->tbo;
+ tv_pd.shared = true;
+ list_add(&tv_pd.head, &list);
+
+ err = ttm_eu_reserve_buffers(&ticket, &list, false, NULL);
+ if (err)
+ goto out;
+
+ err = lima_vm_bo_unmap(vm, bo, va);
+
+ ttm_eu_backoff_reservation(&ticket, &list);
+out:
+ drm_gem_object_put_unlocked(obj);
+ return err;
+}
+
+static int lima_gem_sync_bo(struct lima_sched_task *task, struct lima_bo *bo,
+ bool write, bool explicit)
+{
+ int i, err;
+ struct dma_fence *f;
+ u64 context = task->base.s_fence->finished.context;
+
+ if (!write) {
+ err = reservation_object_reserve_shared(bo->tbo.resv);
+ if (err)
+ return err;
+ }
+
+ /* explicit sync use user passed dep fence */
+ if (explicit)
+ return 0;
+
+ /* implicit sync use bo fence in resv obj */
+ if (write) {
+ struct reservation_object_list *fobj =
+ reservation_object_get_list(bo->tbo.resv);
+
+ if (fobj && fobj->shared_count > 0) {
+ for (i = 0; i < fobj->shared_count; i++) {
+ f = rcu_dereference_protected(
+ fobj->shared[i],
+ reservation_object_held(bo->tbo.resv));
+ if (f->context != context) {
+ err = lima_sched_task_add_dep(task, f);
+ if (err)
+ return err;
+ }
+ }
+ }
+ }
+
+ f = reservation_object_get_excl(bo->tbo.resv);
+ if (f) {
+ err = lima_sched_task_add_dep(task, f);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+static int lima_gem_add_deps(struct lima_ctx_mgr *mgr, struct lima_submit *submit)
+{
+ int i, err = 0;
+
+ for (i = 0; i < submit->nr_deps; i++) {
+ union drm_lima_gem_submit_dep *dep = submit->deps + i;
+ struct dma_fence *fence;
+
+ if (dep->type == LIMA_SUBMIT_DEP_FENCE) {
+ fence = lima_ctx_get_native_fence(
+ mgr, dep->fence.ctx, dep->fence.pipe,
+ dep->fence.seq);
+ if (IS_ERR(fence)) {
+ err = PTR_ERR(fence);
+ break;
+ }
+ }
+ else if (dep->type == LIMA_SUBMIT_DEP_SYNC_FD) {
+ fence = sync_file_get_fence(dep->sync_fd.fd);
+ if (!fence) {
+ err = -EINVAL;
+ break;
+ }
+ }
+ else {
+ err = -EINVAL;
+ break;
+ }
+
+ if (fence) {
+ err = lima_sched_task_add_dep(submit->task, fence);
+ dma_fence_put(fence);
+ if (err)
+ break;
+ }
+ }
+
+ return err;
+}
+
+static int lima_gem_get_sync_fd(struct dma_fence *fence)
+{
+ struct sync_file *sync_file;
+ int fd;
+
+ fd = get_unused_fd_flags(O_CLOEXEC);
+ if (fd < 0)
+ return fd;
+
+ sync_file = sync_file_create(fence);
+ if (!sync_file) {
+ put_unused_fd(fd);
+ return -ENOMEM;
+ }
+
+ fd_install(fd, sync_file->file);
+ return fd;
+}
+
+int lima_gem_submit(struct drm_file *file, struct lima_submit *submit)
+{
+ int i, err = 0;
+ struct lima_drm_priv *priv = to_lima_drm_priv(file);
+ struct lima_vm *vm = priv->vm;
+
+ INIT_LIST_HEAD(&submit->validated);
+ INIT_LIST_HEAD(&submit->duplicates);
+
+ for (i = 0; i < submit->nr_bos; i++) {
+ struct drm_gem_object *obj;
+ struct drm_lima_gem_submit_bo *bo = submit->bos + i;
+ struct ttm_validate_buffer *vb = submit->vbs + i;
+
+ obj = drm_gem_object_lookup(file, bo->handle);
+ if (!obj) {
+ err = -ENOENT;
+ goto out0;
+ }
+
+ vb->bo = &to_lima_bo(obj)->tbo;
+ vb->shared = !(bo->flags & LIMA_SUBMIT_BO_WRITE);
+ list_add_tail(&vb->head, &submit->validated);
+ }
+
+ submit->vm_pd_vb.bo = &vm->pd->tbo;
+ submit->vm_pd_vb.shared = true;
+ list_add(&submit->vm_pd_vb.head, &submit->validated);
+
+ err = ttm_eu_reserve_buffers(&submit->ticket, &submit->validated,
+ true, &submit->duplicates);
+ if (err)
+ goto out0;
+
+ err = lima_sched_task_init(
+ submit->task, submit->ctx->context + submit->pipe, vm);
+ if (err)
+ goto out1;
+
+ err = lima_gem_add_deps(&priv->ctx_mgr, submit);
+ if (err)
+ goto out2;
+
+ for (i = 0; i < submit->nr_bos; i++) {
+ struct ttm_validate_buffer *vb = submit->vbs + i;
+ struct lima_bo *bo = ttm_to_lima_bo(vb->bo);
+ err = lima_gem_sync_bo(
+ submit->task, bo, !vb->shared,
+ submit->flags & LIMA_SUBMIT_FLAG_EXPLICIT_FENCE);
+ if (err)
+ goto out2;
+ }
+
+ if (submit->flags & LIMA_SUBMIT_FLAG_SYNC_FD_OUT) {
+ int fd = lima_gem_get_sync_fd(
+ &submit->task->base.s_fence->finished);
+ if (fd < 0) {
+ err = fd;
+ goto out2;
+ }
+ submit->sync_fd = fd;
+ }
+
+ submit->fence = lima_sched_context_queue_task(
+ submit->ctx->context + submit->pipe, submit->task,
+ &submit->done);
+
+ ttm_eu_fence_buffer_objects(&submit->ticket, &submit->validated,
+ &submit->task->base.s_fence->finished);
+
+out2:
+ if (err)
+ lima_sched_task_fini(submit->task);
+out1:
+ if (err)
+ ttm_eu_backoff_reservation(&submit->ticket, &submit->validated);
+out0:
+ for (i = 0; i < submit->nr_bos; i++) {
+ struct ttm_validate_buffer *vb = submit->vbs + i;
+ if (!vb->bo)
+ break;
+ drm_gem_object_put_unlocked(&ttm_to_lima_bo(vb->bo)->gem);
+ }
+ return err;
+}
+
+int lima_gem_wait(struct drm_file *file, u32 handle, u32 op, u64 timeout_ns)
+{
+ bool write = op & LIMA_GEM_WAIT_WRITE;
+ struct drm_gem_object *obj;
+ struct lima_bo *bo;
+ signed long ret;
+ unsigned long timeout;
+
+ obj = drm_gem_object_lookup(file, handle);
+ if (!obj)
+ return -ENOENT;
+
+ bo = to_lima_bo(obj);
+
+ timeout = timeout_ns ? lima_timeout_to_jiffies(timeout_ns) : 0;
+
+ ret = lima_bo_reserve(bo, true);
+ if (ret)
+ goto out;
+
+ /* must use long for result check because in 64bit arch int
+ * will overflow if timeout is too large and get <0 result
+ */
+ ret = reservation_object_wait_timeout_rcu(bo->tbo.resv, write, true, timeout);
+ if (ret == 0)
+ ret = timeout ? -ETIMEDOUT : -EBUSY;
+ else if (ret > 0)
+ ret = 0;
+
+ lima_bo_unreserve(bo);
+out:
+ drm_gem_object_put_unlocked(obj);
+ return ret;
+}
diff --git a/drivers/gpu/drm/lima/lima_gem.h b/drivers/gpu/drm/lima/lima_gem.h
new file mode 100644
index 000000000000..8e3c4110825d
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_gem.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIMA_GEM_H__
+#define __LIMA_GEM_H__
+
+struct lima_bo;
+struct lima_submit;
+
+struct lima_bo *lima_gem_create_bo(struct drm_device *dev, u32 size, u32 flags);
+int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file,
+ u32 size, u32 flags, u32 *handle);
+void lima_gem_free_object(struct drm_gem_object *obj);
+int lima_gem_object_open(struct drm_gem_object *obj, struct drm_file *file);
+void lima_gem_object_close(struct drm_gem_object *obj, struct drm_file *file);
+int lima_gem_mmap_offset(struct drm_file *file, u32 handle, u64 *offset);
+int lima_gem_mmap(struct file *filp, struct vm_area_struct *vma);
+int lima_gem_va_map(struct drm_file *file, u32 handle, u32 flags, u32 va);
+int lima_gem_va_unmap(struct drm_file *file, u32 handle, u32 va);
+int lima_gem_submit(struct drm_file *file, struct lima_submit *submit);
+int lima_gem_wait(struct drm_file *file, u32 handle, u32 op, u64 timeout_ns);
+
+#endif
--
2.17.0
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related
* [PATCH RFC 21/24] drm/lima: add GEM Prime related functions
From: Qiang Yu @ 2018-05-18 9:28 UTC (permalink / raw)
To: dri-devel, devicetree
Cc: Simon Shields, Marek Vasut, Connor Abbott, Neil Armstrong,
Andrei Paulau, Vasily Khoruzhick, Qiang Yu, Erico Nunes
In-Reply-To: <20180518092815.25280-1-yuq825@gmail.com>
From: Lima Project Developers <dri-devel@lists.freedesktop.org>
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Signed-off-by: Erico Nunes <nunes.erico@gmail.com>
---
drivers/gpu/drm/lima/lima_gem_prime.c | 66 +++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_gem_prime.h | 31 +++++++++++++
2 files changed, 97 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_gem_prime.c
create mode 100644 drivers/gpu/drm/lima/lima_gem_prime.h
diff --git a/drivers/gpu/drm/lima/lima_gem_prime.c b/drivers/gpu/drm/lima/lima_gem_prime.c
new file mode 100644
index 000000000000..74da43a4378f
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_gem_prime.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/dma-buf.h>
+#include <drm/drm_prime.h>
+
+#include "lima_device.h"
+#include "lima_object.h"
+#include "lima_gem_prime.h"
+
+struct drm_gem_object *lima_gem_prime_import_sg_table(
+ struct drm_device *dev, struct dma_buf_attachment *attach,
+ struct sg_table *sgt)
+{
+ struct reservation_object *resv = attach->dmabuf->resv;
+ struct lima_device *ldev = to_lima_dev(dev);
+ struct lima_bo *bo;
+
+ ww_mutex_lock(&resv->lock, NULL);
+
+ bo = lima_bo_create(ldev, attach->dmabuf->size, 0,
+ ttm_bo_type_sg, sgt, resv);
+ if (IS_ERR(bo))
+ goto err_out;
+
+ ww_mutex_unlock(&resv->lock);
+ return &bo->gem;
+
+err_out:
+ ww_mutex_unlock(&resv->lock);
+ return (void *)bo;
+}
+
+struct reservation_object *lima_gem_prime_res_obj(struct drm_gem_object *obj)
+{
+ struct lima_bo *bo = to_lima_bo(obj);
+
+ return bo->tbo.resv;
+}
+
+struct sg_table *lima_gem_prime_get_sg_table(struct drm_gem_object *obj)
+{
+ struct lima_bo *bo = to_lima_bo(obj);
+ int npages = bo->tbo.num_pages;
+
+ return drm_prime_pages_to_sg(bo->tbo.ttm->pages, npages);
+}
diff --git a/drivers/gpu/drm/lima/lima_gem_prime.h b/drivers/gpu/drm/lima/lima_gem_prime.h
new file mode 100644
index 000000000000..023bf5ba2d7b
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_gem_prime.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIMA_GEM_PRIME_H__
+#define __LIMA_GEM_PRIME_H__
+
+struct drm_gem_object *lima_gem_prime_import_sg_table(
+ struct drm_device *dev, struct dma_buf_attachment *attach,
+ struct sg_table *sgt);
+struct sg_table *lima_gem_prime_get_sg_table(struct drm_gem_object *obj);
+struct reservation_object *lima_gem_prime_res_obj(struct drm_gem_object *obj);
+
+#endif
--
2.17.0
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related
* [PATCH RFC 22/24] drm/lima: add GPU schedule using DRM_SCHED
From: Qiang Yu @ 2018-05-18 9:28 UTC (permalink / raw)
To: dri-devel, devicetree
Cc: Simon Shields, Marek Vasut, Connor Abbott, Neil Armstrong,
Andrei Paulau, Vasily Khoruzhick, Qiang Yu, Erico Nunes
In-Reply-To: <20180518092815.25280-1-yuq825@gmail.com>
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_sched.c | 497 ++++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_sched.h | 126 ++++++++
2 files changed, 623 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_sched.c
create mode 100644 drivers/gpu/drm/lima/lima_sched.h
diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c
new file mode 100644
index 000000000000..190932955e9b
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_sched.c
@@ -0,0 +1,497 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/kthread.h>
+#include <linux/slab.h>
+
+#include "lima_drv.h"
+#include "lima_sched.h"
+#include "lima_vm.h"
+#include "lima_mmu.h"
+#include "lima_l2_cache.h"
+
+struct lima_fence {
+ struct dma_fence base;
+ struct lima_sched_pipe *pipe;
+};
+
+static struct kmem_cache *lima_fence_slab = NULL;
+
+int lima_sched_slab_init(void)
+{
+ lima_fence_slab = kmem_cache_create(
+ "lima_fence", sizeof(struct lima_fence), 0,
+ SLAB_HWCACHE_ALIGN, NULL);
+ if (!lima_fence_slab)
+ return -ENOMEM;
+
+ return 0;
+}
+
+void lima_sched_slab_fini(void)
+{
+ if (lima_fence_slab)
+ kmem_cache_destroy(lima_fence_slab);
+}
+
+static inline struct lima_fence *to_lima_fence(struct dma_fence *fence)
+{
+ return container_of(fence, struct lima_fence, base);
+}
+
+static const char *lima_fence_get_driver_name(struct dma_fence *fence)
+{
+ return "lima";
+}
+
+static const char *lima_fence_get_timeline_name(struct dma_fence *fence)
+{
+ struct lima_fence *f = to_lima_fence(fence);
+
+ return f->pipe->base.name;
+}
+
+static bool lima_fence_enable_signaling(struct dma_fence *fence)
+{
+ return true;
+}
+
+static void lima_fence_release_rcu(struct rcu_head *rcu)
+{
+ struct dma_fence *f = container_of(rcu, struct dma_fence, rcu);
+ struct lima_fence *fence = to_lima_fence(f);
+
+ kmem_cache_free(lima_fence_slab, fence);
+}
+
+static void lima_fence_release(struct dma_fence *fence)
+{
+ struct lima_fence *f = to_lima_fence(fence);
+
+ call_rcu(&f->base.rcu, lima_fence_release_rcu);
+}
+
+static const struct dma_fence_ops lima_fence_ops = {
+ .get_driver_name = lima_fence_get_driver_name,
+ .get_timeline_name = lima_fence_get_timeline_name,
+ .enable_signaling = lima_fence_enable_signaling,
+ .wait = dma_fence_default_wait,
+ .release = lima_fence_release,
+};
+
+static struct lima_fence *lima_fence_create(struct lima_sched_pipe *pipe)
+{
+ struct lima_fence *fence;
+
+ fence = kmem_cache_zalloc(lima_fence_slab, GFP_KERNEL);
+ if (!fence)
+ return NULL;
+
+ fence->pipe = pipe;
+ dma_fence_init(&fence->base, &lima_fence_ops, &pipe->fence_lock,
+ pipe->fence_context, ++pipe->fence_seqno);
+
+ return fence;
+}
+
+static inline struct lima_sched_task *to_lima_task(struct drm_sched_job *job)
+{
+ return container_of(job, struct lima_sched_task, base);
+}
+
+static inline struct lima_sched_pipe *to_lima_pipe(struct drm_gpu_scheduler *sched)
+{
+ return container_of(sched, struct lima_sched_pipe, base);
+}
+
+int lima_sched_task_init(struct lima_sched_task *task,
+ struct lima_sched_context *context,
+ struct lima_vm *vm)
+{
+ int err;
+
+ err = drm_sched_job_init(&task->base, context->base.sched,
+ &context->base, context);
+ if (err)
+ return err;
+
+ task->vm = lima_vm_get(vm);
+ return 0;
+}
+
+void lima_sched_task_fini(struct lima_sched_task *task)
+{
+ dma_fence_put(&task->base.s_fence->finished);
+ lima_vm_put(task->vm);
+}
+
+int lima_sched_task_add_dep(struct lima_sched_task *task, struct dma_fence *fence)
+{
+ int i, new_dep = 4;
+
+ if (task->dep && task->num_dep == task->max_dep)
+ new_dep = task->max_dep * 2;
+
+ if (task->max_dep < new_dep) {
+ void *dep = krealloc(task->dep, sizeof(*task->dep) * new_dep, GFP_KERNEL);
+ if (!dep)
+ return -ENOMEM;
+ task->max_dep = new_dep;
+ task->dep = dep;
+ }
+
+ dma_fence_get(fence);
+ for (i = 0; i < task->num_dep; i++) {
+ if (task->dep[i]->context == fence->context &&
+ dma_fence_is_later(fence, task->dep[i])) {
+ dma_fence_put(task->dep[i]);
+ task->dep[i] = fence;
+ return 0;
+ }
+ }
+
+ task->dep[task->num_dep++] = fence;
+ return 0;
+}
+
+int lima_sched_context_init(struct lima_sched_pipe *pipe,
+ struct lima_sched_context *context,
+ atomic_t *guilty)
+{
+ struct drm_sched_rq *rq = pipe->base.sched_rq + DRM_SCHED_PRIORITY_NORMAL;
+ int err;
+
+ context->fences =
+ kzalloc(sizeof(*context->fences) * lima_sched_max_tasks, GFP_KERNEL);
+ if (!context->fences)
+ return -ENOMEM;
+
+ mutex_init(&context->lock);
+ err = drm_sched_entity_init(&pipe->base, &context->base, rq,
+ lima_sched_max_tasks, guilty);
+ if (err) {
+ kfree(context->fences);
+ context->fences = NULL;
+ return err;
+ }
+
+ return 0;
+}
+
+void lima_sched_context_fini(struct lima_sched_pipe *pipe,
+ struct lima_sched_context *context)
+{
+ drm_sched_entity_fini(&pipe->base, &context->base);
+
+ mutex_destroy(&context->lock);
+
+ if (context->fences)
+ kfree(context->fences);
+}
+
+static uint32_t lima_sched_context_add_fence(struct lima_sched_context *context,
+ struct dma_fence *fence,
+ uint32_t *done)
+{
+ uint32_t seq, idx, i;
+ struct dma_fence *other;
+
+ mutex_lock(&context->lock);
+
+ seq = context->sequence;
+ idx = seq & (lima_sched_max_tasks - 1);
+ other = context->fences[idx];
+
+ if (other) {
+ int err = dma_fence_wait(other, false);
+ if (err)
+ DRM_ERROR("Error %d waiting context fence\n", err);
+ }
+
+ context->fences[idx] = dma_fence_get(fence);
+ context->sequence++;
+
+ /* get finished fence offset from seq */
+ for (i = 1; i < lima_sched_max_tasks; i++) {
+ idx = (seq - i) & (lima_sched_max_tasks - 1);
+ if (!context->fences[idx] ||
+ dma_fence_is_signaled(context->fences[idx]))
+ break;
+ }
+
+ mutex_unlock(&context->lock);
+
+ dma_fence_put(other);
+
+ *done = i;
+ return seq;
+}
+
+struct dma_fence *lima_sched_context_get_fence(
+ struct lima_sched_context *context, uint32_t seq)
+{
+ struct dma_fence *fence;
+ int idx;
+ uint32_t max, min;
+
+ mutex_lock(&context->lock);
+
+ max = context->sequence - 1;
+ min = context->sequence - lima_sched_max_tasks;
+
+ /* handle overflow case */
+ if ((min < max && (seq < min || seq > max)) ||
+ (min > max && (seq < min && seq > max))) {
+ fence = NULL;
+ goto out;
+ }
+
+ idx = seq & (lima_sched_max_tasks - 1);
+ fence = dma_fence_get(context->fences[idx]);
+
+out:
+ mutex_unlock(&context->lock);
+
+ return fence;
+}
+
+uint32_t lima_sched_context_queue_task(struct lima_sched_context *context,
+ struct lima_sched_task *task,
+ uint32_t *done)
+{
+ uint32_t seq = lima_sched_context_add_fence(
+ context, &task->base.s_fence->finished, done);
+ drm_sched_entity_push_job(&task->base, &context->base);
+ return seq;
+}
+
+static struct dma_fence *lima_sched_dependency(struct drm_sched_job *job,
+ struct drm_sched_entity *entity)
+{
+ struct lima_sched_task *task = to_lima_task(job);
+ int i;
+
+ for (i = 0; i < task->num_dep; i++) {
+ struct dma_fence *fence = task->dep[i];
+
+ if (!task->dep[i])
+ continue;
+
+ task->dep[i] = NULL;
+
+ if (!dma_fence_is_signaled(fence))
+ return fence;
+
+ dma_fence_put(fence);
+ }
+
+ return NULL;
+}
+
+static struct dma_fence *lima_sched_run_job(struct drm_sched_job *job)
+{
+ struct lima_sched_task *task = to_lima_task(job);
+ struct lima_sched_pipe *pipe = to_lima_pipe(job->sched);
+ struct lima_fence *fence;
+ struct dma_fence *ret;
+ struct lima_vm *vm = NULL, *last_vm = NULL;
+ int i;
+
+ /* after GPU reset */
+ if (job->s_fence->finished.error < 0)
+ return NULL;
+
+ fence = lima_fence_create(pipe);
+ if (!fence)
+ return NULL;
+ task->fence = &fence->base;
+
+ /* for caller usage of the fence, otherwise irq handler
+ * may consume the fence before caller use it */
+ ret = dma_fence_get(task->fence);
+
+ pipe->current_task = task;
+
+ /* this is needed for MMU to work correctly, otherwise GP/PP
+ * will hang or page fault for unknown reason after running for
+ * a while.
+ *
+ * Need to investigate:
+ * 1. is it related to TLB
+ * 2. how much performance will be affected by L2 cache flush
+ * 3. can we reduce the calling of this function because all
+ * GP/PP use the same L2 cache on mali400
+ *
+ * TODO:
+ * 1. move this to task fini to save some wait time?
+ * 2. when GP/PP use different l2 cache, need PP wait GP l2
+ * cache flush?
+ */
+ for (i = 0; i < pipe->num_l2_cache; i++)
+ lima_l2_cache_flush(pipe->l2_cache[i]);
+
+ if (task->vm != pipe->current_vm) {
+ vm = lima_vm_get(task->vm);
+ last_vm = pipe->current_vm;
+ pipe->current_vm = task->vm;
+ }
+
+ if (pipe->bcast_mmu)
+ lima_mmu_switch_vm(pipe->bcast_mmu, vm);
+ else {
+ for (i = 0; i < pipe->num_mmu; i++)
+ lima_mmu_switch_vm(pipe->mmu[i], vm);
+ }
+
+ if (last_vm)
+ lima_vm_put(last_vm);
+
+ pipe->error = false;
+ pipe->task_run(pipe, task);
+
+ return task->fence;
+}
+
+static void lima_sched_handle_error_task(struct lima_sched_pipe *pipe,
+ struct lima_sched_task *task)
+{
+ kthread_park(pipe->base.thread);
+ drm_sched_hw_job_reset(&pipe->base, &task->base);
+
+ pipe->task_error(pipe);
+
+ if (pipe->bcast_mmu)
+ lima_mmu_page_fault_resume(pipe->bcast_mmu);
+ else {
+ int i;
+ for (i = 0; i < pipe->num_mmu; i++)
+ lima_mmu_page_fault_resume(pipe->mmu[i]);
+ }
+
+ if (pipe->current_vm)
+ lima_vm_put(pipe->current_vm);
+
+ pipe->current_vm = NULL;
+ pipe->current_task = NULL;
+
+ drm_sched_job_recovery(&pipe->base);
+ kthread_unpark(pipe->base.thread);
+}
+
+static void lima_sched_timedout_job(struct drm_sched_job *job)
+{
+ struct lima_sched_pipe *pipe = to_lima_pipe(job->sched);
+ struct lima_sched_task *task = to_lima_task(job);
+
+ lima_sched_handle_error_task(pipe, task);
+}
+
+static void lima_sched_free_job(struct drm_sched_job *job)
+{
+ struct lima_sched_task *task = to_lima_task(job);
+ struct lima_sched_pipe *pipe = to_lima_pipe(job->sched);
+ int i;
+
+ dma_fence_put(task->fence);
+
+ for (i = 0; i < task->num_dep; i++) {
+ if (task->dep[i])
+ dma_fence_put(task->dep[i]);
+ }
+
+ if (task->dep)
+ kfree(task->dep);
+
+ lima_vm_put(task->vm);
+ kmem_cache_free(pipe->task_slab, task);
+}
+
+const struct drm_sched_backend_ops lima_sched_ops = {
+ .dependency = lima_sched_dependency,
+ .run_job = lima_sched_run_job,
+ .timedout_job = lima_sched_timedout_job,
+ .free_job = lima_sched_free_job,
+};
+
+static void lima_sched_error_work(struct work_struct *work)
+{
+ struct lima_sched_pipe *pipe =
+ container_of(work, struct lima_sched_pipe, error_work);
+ struct lima_sched_task *task = pipe->current_task;
+
+ lima_sched_handle_error_task(pipe, task);
+}
+
+int lima_sched_pipe_init(struct lima_sched_pipe *pipe, const char *name)
+{
+ long timeout;
+
+ if (lima_sched_timeout_ms <= 0)
+ timeout = MAX_SCHEDULE_TIMEOUT;
+ else
+ timeout = msecs_to_jiffies(lima_sched_timeout_ms);
+
+ pipe->fence_context = dma_fence_context_alloc(1);
+ spin_lock_init(&pipe->fence_lock);
+
+ INIT_WORK(&pipe->error_work, lima_sched_error_work);
+
+ return drm_sched_init(&pipe->base, &lima_sched_ops, 1, 0, timeout, name);
+}
+
+void lima_sched_pipe_fini(struct lima_sched_pipe *pipe)
+{
+ drm_sched_fini(&pipe->base);
+}
+
+unsigned long lima_timeout_to_jiffies(u64 timeout_ns)
+{
+ unsigned long timeout_jiffies;
+ ktime_t timeout;
+
+ /* clamp timeout if it's to large */
+ if (((s64)timeout_ns) < 0)
+ return MAX_SCHEDULE_TIMEOUT;
+
+ timeout = ktime_sub(ns_to_ktime(timeout_ns), ktime_get());
+ if (ktime_to_ns(timeout) < 0)
+ return 0;
+
+ timeout_jiffies = nsecs_to_jiffies(ktime_to_ns(timeout));
+ /* clamp timeout to avoid unsigned-> signed overflow */
+ if (timeout_jiffies > MAX_SCHEDULE_TIMEOUT )
+ return MAX_SCHEDULE_TIMEOUT;
+
+ return timeout_jiffies;
+}
+
+void lima_sched_pipe_task_done(struct lima_sched_pipe *pipe)
+{
+ if (pipe->error)
+ schedule_work(&pipe->error_work);
+ else {
+ struct lima_sched_task *task = pipe->current_task;
+
+ pipe->task_fini(pipe);
+ dma_fence_signal(task->fence);
+ }
+}
diff --git a/drivers/gpu/drm/lima/lima_sched.h b/drivers/gpu/drm/lima/lima_sched.h
new file mode 100644
index 000000000000..b93b7b4eded4
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_sched.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIMA_SCHED_H__
+#define __LIMA_SCHED_H__
+
+#include <drm/gpu_scheduler.h>
+
+struct lima_vm;
+
+struct lima_sched_task {
+ struct drm_sched_job base;
+
+ struct lima_vm *vm;
+ void *frame;
+
+ struct dma_fence **dep;
+ int num_dep;
+ int max_dep;
+
+ /* pipe fence */
+ struct dma_fence *fence;
+};
+
+struct lima_sched_context {
+ struct drm_sched_entity base;
+ struct mutex lock;
+ struct dma_fence **fences;
+ uint32_t sequence;
+};
+
+#define LIMA_SCHED_PIPE_MAX_MMU 8
+#define LIMA_SCHED_PIPE_MAX_L2_CACHE 2
+#define LIMA_SCHED_PIPE_MAX_PROCESSOR 8
+
+struct lima_ip;
+
+struct lima_sched_pipe {
+ struct drm_gpu_scheduler base;
+
+ u64 fence_context;
+ u32 fence_seqno;
+ spinlock_t fence_lock;
+
+ struct lima_sched_task *current_task;
+ struct lima_vm *current_vm;
+
+ struct lima_ip *mmu[LIMA_SCHED_PIPE_MAX_MMU];
+ int num_mmu;
+
+ struct lima_ip *l2_cache[LIMA_SCHED_PIPE_MAX_L2_CACHE];
+ int num_l2_cache;
+
+ struct lima_ip *processor[LIMA_SCHED_PIPE_MAX_PROCESSOR];
+ int num_processor;
+
+ struct lima_ip *bcast_processor;
+ struct lima_ip *bcast_mmu;
+
+ u32 done;
+ bool error;
+ atomic_t task;
+
+ int frame_size;
+ struct kmem_cache *task_slab;
+
+ int (*task_validate)(struct lima_sched_pipe *pipe, struct lima_sched_task *task);
+ void (*task_run)(struct lima_sched_pipe *pipe, struct lima_sched_task *task);
+ void (*task_fini)(struct lima_sched_pipe *pipe);
+ void (*task_error)(struct lima_sched_pipe *pipe);
+ void (*task_mmu_error)(struct lima_sched_pipe *pipe);
+
+ struct work_struct error_work;
+};
+
+int lima_sched_task_init(struct lima_sched_task *task,
+ struct lima_sched_context *context,
+ struct lima_vm *vm);
+void lima_sched_task_fini(struct lima_sched_task *task);
+int lima_sched_task_add_dep(struct lima_sched_task *task, struct dma_fence *fence);
+
+int lima_sched_context_init(struct lima_sched_pipe *pipe,
+ struct lima_sched_context *context,
+ atomic_t *guilty);
+void lima_sched_context_fini(struct lima_sched_pipe *pipe,
+ struct lima_sched_context *context);
+uint32_t lima_sched_context_queue_task(struct lima_sched_context *context,
+ struct lima_sched_task *task,
+ uint32_t *done);
+struct dma_fence *lima_sched_context_get_fence(
+ struct lima_sched_context *context, uint32_t seq);
+
+int lima_sched_pipe_init(struct lima_sched_pipe *pipe, const char *name);
+void lima_sched_pipe_fini(struct lima_sched_pipe *pipe);
+void lima_sched_pipe_task_done(struct lima_sched_pipe *pipe);
+
+static inline void lima_sched_pipe_mmu_error(struct lima_sched_pipe *pipe)
+{
+ pipe->error = true;
+ pipe->task_mmu_error(pipe);
+}
+
+int lima_sched_slab_init(void);
+void lima_sched_slab_fini(void);
+
+unsigned long lima_timeout_to_jiffies(u64 timeout_ns);
+
+#endif
--
2.17.0
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related
* [PATCH RFC 23/24] drm/lima: add context related functions
From: Qiang Yu @ 2018-05-18 9:28 UTC (permalink / raw)
To: dri-devel, devicetree
Cc: Simon Shields, Marek Vasut, Connor Abbott, Neil Armstrong,
Andrei Paulau, Vasily Khoruzhick, Qiang Yu, Erico Nunes
In-Reply-To: <20180518092815.25280-1-yuq825@gmail.com>
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_ctx.c | 143 ++++++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_ctx.h | 51 ++++++++++++
2 files changed, 194 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_ctx.c
create mode 100644 drivers/gpu/drm/lima/lima_ctx.h
diff --git a/drivers/gpu/drm/lima/lima_ctx.c b/drivers/gpu/drm/lima/lima_ctx.c
new file mode 100644
index 000000000000..7243861760b4
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_ctx.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/slab.h>
+
+#include "lima_device.h"
+#include "lima_ctx.h"
+
+int lima_ctx_create(struct lima_device *dev, struct lima_ctx_mgr *mgr, u32 *id)
+{
+ struct lima_ctx *ctx;
+ int i, err;
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+ ctx->dev = dev;
+ kref_init(&ctx->refcnt);
+
+ for (i = 0; i < lima_pipe_num; i++) {
+ err = lima_sched_context_init(dev->pipe + i, ctx->context + i, &ctx->guilty);
+ if (err)
+ goto err_out0;
+ }
+
+ idr_preload(GFP_KERNEL);
+ spin_lock(&mgr->lock);
+ err = idr_alloc(&mgr->handles, ctx, 1, 0, GFP_ATOMIC);
+ spin_unlock(&mgr->lock);
+ idr_preload_end();
+ if (err < 0)
+ goto err_out0;
+
+ *id = err;
+ return 0;
+
+err_out0:
+ for (i--; i >= 0; i--)
+ lima_sched_context_fini(dev->pipe + i, ctx->context + i);
+ kfree(ctx);
+ return err;
+}
+
+static void lima_ctx_do_release(struct kref *ref)
+{
+ struct lima_ctx *ctx = container_of(ref, struct lima_ctx, refcnt);
+ int i;
+
+ for (i = 0; i < lima_pipe_num; i++)
+ lima_sched_context_fini(ctx->dev->pipe + i, ctx->context + i);
+ kfree(ctx);
+}
+
+int lima_ctx_free(struct lima_ctx_mgr *mgr, u32 id)
+{
+ struct lima_ctx *ctx;
+
+ spin_lock(&mgr->lock);
+ ctx = idr_remove(&mgr->handles, id);
+ spin_unlock(&mgr->lock);
+
+ if (ctx) {
+ kref_put(&ctx->refcnt, lima_ctx_do_release);
+ return 0;
+ }
+ return -EINVAL;
+}
+
+struct lima_ctx *lima_ctx_get(struct lima_ctx_mgr *mgr, u32 id)
+{
+ struct lima_ctx *ctx;
+
+ spin_lock(&mgr->lock);
+ ctx = idr_find(&mgr->handles, id);
+ if (ctx)
+ kref_get(&ctx->refcnt);
+ spin_unlock(&mgr->lock);
+ return ctx;
+}
+
+void lima_ctx_put(struct lima_ctx *ctx)
+{
+ kref_put(&ctx->refcnt, lima_ctx_do_release);
+}
+
+void lima_ctx_mgr_init(struct lima_ctx_mgr *mgr)
+{
+ spin_lock_init(&mgr->lock);
+ idr_init(&mgr->handles);
+}
+
+void lima_ctx_mgr_fini(struct lima_ctx_mgr *mgr)
+{
+ struct lima_ctx *ctx;
+ struct idr *idp;
+ uint32_t id;
+
+ idp = &mgr->handles;
+
+ idr_for_each_entry(idp, ctx, id) {
+ kref_put(&ctx->refcnt, lima_ctx_do_release);
+ }
+
+ idr_destroy(&mgr->handles);
+}
+
+struct dma_fence *lima_ctx_get_native_fence(struct lima_ctx_mgr *mgr,
+ u32 ctx, u32 pipe, u32 seq)
+{
+ struct lima_ctx *c;
+ struct dma_fence *ret;
+
+ if (pipe >= lima_pipe_num)
+ return ERR_PTR(-EINVAL);
+
+ c = lima_ctx_get(mgr, ctx);
+ if (!c)
+ return ERR_PTR(-ENOENT);
+
+ ret = lima_sched_context_get_fence(c->context + pipe, seq);
+
+ lima_ctx_put(c);
+ return ret;
+}
diff --git a/drivers/gpu/drm/lima/lima_ctx.h b/drivers/gpu/drm/lima/lima_ctx.h
new file mode 100644
index 000000000000..591f64532772
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_ctx.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIMA_CTX_H__
+#define __LIMA_CTX_H__
+
+#include <linux/idr.h>
+
+#include "lima_device.h"
+
+struct lima_ctx {
+ struct kref refcnt;
+ struct lima_device *dev;
+ struct lima_sched_context context[lima_pipe_num];
+ atomic_t guilty;
+};
+
+struct lima_ctx_mgr {
+ spinlock_t lock;
+ struct idr handles;
+};
+
+int lima_ctx_create(struct lima_device *dev, struct lima_ctx_mgr *mgr, u32 *id);
+int lima_ctx_free(struct lima_ctx_mgr *mgr, u32 id);
+struct lima_ctx *lima_ctx_get(struct lima_ctx_mgr *mgr, u32 id);
+void lima_ctx_put(struct lima_ctx *ctx);
+void lima_ctx_mgr_init(struct lima_ctx_mgr *mgr);
+void lima_ctx_mgr_fini(struct lima_ctx_mgr *mgr);
+
+struct dma_fence *lima_ctx_get_native_fence(struct lima_ctx_mgr *mgr,
+ u32 ctx, u32 pipe, u32 seq);
+
+#endif
--
2.17.0
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related
* [PATCH RFC 24/24] drm/lima: add makefile and kconfig
From: Qiang Yu @ 2018-05-18 9:28 UTC (permalink / raw)
To: dri-devel, devicetree
Cc: Simon Shields, Marek Vasut, Connor Abbott, Neil Armstrong,
Andrei Paulau, Vasily Khoruzhick, Qiang Yu, Erico Nunes
In-Reply-To: <20180518092815.25280-1-yuq825@gmail.com>
From: Lima Project Developers <dri-devel@lists.freedesktop.org>
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Simon Shields <simon@lineageos.org>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
drivers/gpu/drm/Kconfig | 2 ++
drivers/gpu/drm/Makefile | 1 +
drivers/gpu/drm/lima/Kconfig | 9 +++++++++
drivers/gpu/drm/lima/Makefile | 19 +++++++++++++++++++
4 files changed, 31 insertions(+)
create mode 100644 drivers/gpu/drm/lima/Kconfig
create mode 100644 drivers/gpu/drm/lima/Makefile
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index deeefa7a1773..f00d529ee034 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -289,6 +289,8 @@ source "drivers/gpu/drm/pl111/Kconfig"
source "drivers/gpu/drm/tve200/Kconfig"
+source "drivers/gpu/drm/lima/Kconfig"
+
# Keep legacy drivers last
menuconfig DRM_LEGACY
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 50093ff4479b..aba686e41d6b 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -103,3 +103,4 @@ obj-$(CONFIG_DRM_MXSFB) += mxsfb/
obj-$(CONFIG_DRM_TINYDRM) += tinydrm/
obj-$(CONFIG_DRM_PL111) += pl111/
obj-$(CONFIG_DRM_TVE200) += tve200/
+obj-$(CONFIG_DRM_LIMA) += lima/
diff --git a/drivers/gpu/drm/lima/Kconfig b/drivers/gpu/drm/lima/Kconfig
new file mode 100644
index 000000000000..4ce9ac2e8204
--- /dev/null
+++ b/drivers/gpu/drm/lima/Kconfig
@@ -0,0 +1,9 @@
+
+config DRM_LIMA
+ tristate "LIMA (DRM support for ARM Mali 400/450 GPU)"
+ depends on DRM
+ depends on ARCH_SUNXI || ARCH_ROCKCHIP || ARCH_EXYNOS || ARCH_MESON
+ select DRM_SCHED
+ select DRM_TTM
+ help
+ DRM driver for ARM Mali 400/450 GPUs.
diff --git a/drivers/gpu/drm/lima/Makefile b/drivers/gpu/drm/lima/Makefile
new file mode 100644
index 000000000000..0a1d6605f164
--- /dev/null
+++ b/drivers/gpu/drm/lima/Makefile
@@ -0,0 +1,19 @@
+lima-y := \
+ lima_drv.o \
+ lima_device.o \
+ lima_pmu.o \
+ lima_l2_cache.o \
+ lima_mmu.o \
+ lima_gp.o \
+ lima_pp.o \
+ lima_gem.o \
+ lima_vm.o \
+ lima_sched.o \
+ lima_ctx.o \
+ lima_gem_prime.o \
+ lima_dlbu.o \
+ lima_bcast.o \
+ lima_ttm.o \
+ lima_object.o
+
+obj-$(CONFIG_DRM_LIMA) += lima.o
--
2.17.0
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related
* Re: [PATCH RFC 06/24] drm/lima: add lima uapi header
From: Marek Vasut @ 2018-05-18 9:33 UTC (permalink / raw)
To: Qiang Yu, dri-devel, devicetree
Cc: Simon Shields, Connor Abbott, Neil Armstrong, Andrei Paulau,
Vasily Khoruzhick, Erico Nunes
In-Reply-To: <20180518092815.25280-7-yuq825@gmail.com>
On 05/18/2018 11:27 AM, Qiang Yu wrote:
Commit message is missing
> Signed-off-by: Qiang Yu <yuq825@gmail.com>
> ---
> include/uapi/drm/lima_drm.h | 195 ++++++++++++++++++++++++++++++++++++
> 1 file changed, 195 insertions(+)
> create mode 100644 include/uapi/drm/lima_drm.h
>
> diff --git a/include/uapi/drm/lima_drm.h b/include/uapi/drm/lima_drm.h
> new file mode 100644
> index 000000000000..9df95e46fb2c
> --- /dev/null
> +++ b/include/uapi/drm/lima_drm.h
Please convert this to the SPDX license identifiers, that is
// SPDX...
> @@ -0,0 +1,195 @@
> +/*
> + * Copyright (C) 2017-2018 Lima Project
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
[...]
> +#if defined(__cplusplus)
> +extern "C" {
> +#endif
Is this C++ stuff needed ?
[...]
> +#define LIMA_SUBMIT_FLAG_EXPLICIT_FENCE (1 << 0)
> +#define LIMA_SUBMIT_FLAG_SYNC_FD_OUT (1 << 1)
BIT(0) and BIT(1) if applicable
[...]
--
Best regards,
Marek Vasut
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* [PATCH v2 00/26] arm64: allwinner: Add A64 DE2 HDMI support
From: Jagan Teki @ 2018-05-18 9:45 UTC (permalink / raw)
To: Maxime Ripard, Chen-Yu Tsai, Icenowy Zheng, Jernej Skrabec,
Rob Herring, Mark Rutland, Catalin Marinas, Will Deacon,
David Airlie, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
Michael Turquette, Stephen Boyd, linux-clk-u79uwXL29TY76Z2rM5mHXA,
Michael Trimarchi,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
Cc: Jagan Teki
Allwinner A64 has display engine pipeline like other Allwinner SOC's A83T/H3/H5.
A64 behaviour similar to Allwinner A83T where
Mixer0 => TCON0 => LVDS/RGB/MIPI-DSI
Mixer1 => TCON1 => HDMI
as per Display System Block DiagramAllwinner_A64_User_Manual_V1.1.pdf
This is second patch-set followed with previous RFC[1] and first series[2]
and merely concentrated on HDMI pipeline through TCON1 and rest will add eventually.
This series fixed previous version comments
- about documenting fallback compatibles
- adding new compatible for mixer1
- support for multiple DW HDMI PHY clock parents (thanks, to Jernej)
Note:
Pine64 boards are unable to get edid by default like other A64 boards,
but forcing 'video=HDMI-A-1:1920x1080@60D' kernel command line can
create edid with display on penel.
Log:
[ 1.613196] sun4i-drm display-engine: bound 1200000.mixer (ops sun8i_mixer_ops)
[ 1.620764] sun4i-drm display-engine: No panel or bridge found... RGB output disabled
[ 1.628612] sun4i-drm display-engine: bound 1c0d000.lcd-controller (ops sun4i_tcon_ops)
[ 1.637677] sun8i-dw-hdmi 1ee0000.hdmi: Detected HDMI TX controller v1.32a with HDCP (sun8i_dw_hdmi_ph
y)
[ 1.647699] sun8i-dw-hdmi 1ee0000.hdmi: registered DesignWare HDMI I2C bus driver
[ 1.656090] [drm] forcing HDMI-A-1 connector on
[ 1.660664] sun4i-drm display-engine: bound 1ee0000.hdmi (ops sun8i_dw_hdmi_ops)
[ 1.668063] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
[ 1.674684] [drm] No driver support for vblank timestamp query.
[ 2.497502] Console: switching to colour frame buffer device 240x67
[ 2.551795] sun4i-drm display-engine: fb0: frame buffer device
[ 2.558166] [drm] Initialized sun4i-drm 1.0.0 20150629 for display-engine on minor 0
[2] https://lkml.org/lkml/2018/4/30/288
[1] https://lkml.org/lkml/2018/4/24/547
Icenowy Zheng (1):
drm: sun4i: add support for HVCC regulator for DWC HDMI glue
Jagan Teki (22):
dt-bindings: clock: Add compatible for A64 DE2 CCU
arm64: dts: allwinner: a64: Add DE2 CCU
clk: sunxi-ng: Enable DE2_CCU for SUN8I and SUN50I
clk: sunxi-ng: a64: Add minimal rate for video PLLs
drm/sun4i: Add support for A64 mixer1
dt-bindings: display: Add compatible for A64 DE2 tcon1 blocks
drm/sun4i: Add support for A64 display engine
arm64: dts: allwinner: a64: Add DE2 tcon1 pipeline
drm/sun4i: Enable DE2 Mixer for SUN8I and SUN50I
arm64: defconfig: Enable CONFIG_DRM_SUN4I
dt-bindings: display: Add compatible for A64 HDMI
dt-bindings: display: Add compatible for A64 HDMI PHY
dt-bindings: clock: sun50i-a64-ccu: Add PLL_VIDEO[0-1] macros
arm64: dts: allwinner: a64: Add HDMI support
drm/sun4i: Enable DesignWare HDMI for SUN8I and SUN50I
arm64: dts: allwinner: a64: Add HDMI pipeline
arm64: dts: allwinner: a64: bananapi-m64: Enable HDMI output
arm64: dts: allwinner: a64: nanopi-a64: Enable HDMI output
arm64: dts: allwinner: a64: orangepi-win: Enable HDMI output
arm64: dts: allwinner: a64: a64-olinuxino: Enable HDMI output
arm64: dts: allwinner: a64: pine64: Enable HDMI output
arm64: dts: allwinner: a64: sopine: Enable HDMI output
Jernej Skrabec (3):
drm/sun4i: DE2 mixer: Add index quirk
drm/sun4i: Add support for multiple DW HDMI PHY clock parents
drm/sun4i: Add support for A64 HDMI PHY
.../devicetree/bindings/clock/sun8i-de2.txt | 1 +
.../bindings/display/sunxi/sun4i-drm.txt | 5 +
.../boot/dts/allwinner/sun50i-a64-bananapi-m64.dts | 26 +++++
.../boot/dts/allwinner/sun50i-a64-nanopi-a64.dts | 26 +++++
.../boot/dts/allwinner/sun50i-a64-olinuxino.dts | 26 +++++
.../boot/dts/allwinner/sun50i-a64-orangepi-win.dts | 26 +++++
.../arm64/boot/dts/allwinner/sun50i-a64-pine64.dts | 26 +++++
.../dts/allwinner/sun50i-a64-sopine-baseboard.dts | 26 +++++
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 124 +++++++++++++++++++++
arch/arm64/configs/defconfig | 1 +
drivers/clk/sunxi-ng/Kconfig | 2 +
drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 46 ++++----
drivers/gpu/drm/sun4i/Kconfig | 3 +-
drivers/gpu/drm/sun4i/sun4i_drv.c | 1 +
drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 14 +++
drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 11 +-
drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 44 ++++++--
drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c | 89 +++++++++++----
drivers/gpu/drm/sun4i/sun8i_mixer.c | 17 ++-
drivers/gpu/drm/sun4i/sun8i_mixer.h | 2 +
include/dt-bindings/clock/sun50i-a64-ccu.h | 2 +
21 files changed, 458 insertions(+), 60 deletions(-)
--
2.14.3
^ permalink raw reply
* [PATCH v2 01/26] dt-bindings: clock: Add compatible for A64 DE2 CCU
From: Jagan Teki @ 2018-05-18 9:45 UTC (permalink / raw)
To: Maxime Ripard, Chen-Yu Tsai, Icenowy Zheng, Jernej Skrabec,
Rob Herring, Mark Rutland, Catalin Marinas, Will Deacon,
David Airlie, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
Michael Turquette, Stephen Boyd, linux-clk-u79uwXL29TY76Z2rM5mHXA,
Michael Trimarchi,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
Cc: Jagan Teki
In-Reply-To: <20180518094536.17201-1-jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
Allwinner A64 has DE2 CCU is similar to H3/H5 SoC.
So add compatible for A64 which is fallback compatible
for H5, so update fallback binding.
Signed-off-by: Jagan Teki <jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
Reviewed-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
Changes for v2:
- Add fallback compatible
Documentation/devicetree/bindings/clock/sun8i-de2.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/clock/sun8i-de2.txt b/Documentation/devicetree/bindings/clock/sun8i-de2.txt
index f2fa87c4765c..e3ffe0bcd0a0 100644
--- a/Documentation/devicetree/bindings/clock/sun8i-de2.txt
+++ b/Documentation/devicetree/bindings/clock/sun8i-de2.txt
@@ -7,6 +7,7 @@ Required properties :
- "allwinner,sun8i-h3-de2-clk"
- "allwinner,sun8i-v3s-de2-clk"
- "allwinner,sun50i-h5-de2-clk"
+ - "allwinner,sun50i-a64-de2-clk", "allwinner,sun50i-h5-de2-clk"
- reg: Must contain the registers base address and length
- clocks: phandle to the clocks feeding the display engine subsystem.
--
2.14.3
^ permalink raw reply related
* [PATCH v2 02/26] arm64: dts: allwinner: a64: Add DE2 CCU
From: Jagan Teki @ 2018-05-18 9:45 UTC (permalink / raw)
To: Maxime Ripard, Chen-Yu Tsai, Icenowy Zheng, Jernej Skrabec,
Rob Herring, Mark Rutland, Catalin Marinas, Will Deacon,
David Airlie, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
Michael Turquette, Stephen Boyd, linux-clk-u79uwXL29TY76Z2rM5mHXA,
Michael Trimarchi,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
Cc: Jagan Teki
In-Reply-To: <20180518094536.17201-1-jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
DE2 CCU in Allwinner A64 has same like H5, so use the
similar dts details for A64 with fallback compatible.
Signed-off-by: Jagan Teki <jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
---
Changes for v2:
- Add h5 compatible first since A64 came first.
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 1b2ef28c42bd..26c2a9c44727 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -43,9 +43,11 @@
*/
#include <dt-bindings/clock/sun50i-a64-ccu.h>
+#include <dt-bindings/clock/sun8i-de2.h>
#include <dt-bindings/clock/sun8i-r-ccu.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/reset/sun50i-a64-ccu.h>
+#include <dt-bindings/reset/sun8i-de2.h>
/ {
interrupt-parent = <&gic>;
@@ -168,6 +170,19 @@
#size-cells = <1>;
ranges;
+ display_clocks: clock@1000000 {
+ compatible = "allwinner,sun50i-h5-de2-clk",
+ "allwinner,sun50i-a64-de2-clk";
+ reg = <0x01000000 0x100000>;
+ clocks = <&ccu CLK_DE>,
+ <&ccu CLK_BUS_DE>;
+ clock-names = "mod",
+ "bus";
+ resets = <&ccu RST_BUS_DE>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
syscon: syscon@1c00000 {
compatible = "allwinner,sun50i-a64-system-controller",
"syscon";
--
2.14.3
^ permalink raw reply related
* [PATCH v2 03/26] clk: sunxi-ng: Enable DE2_CCU for SUN8I and SUN50I
From: Jagan Teki @ 2018-05-18 9:45 UTC (permalink / raw)
To: Maxime Ripard, Chen-Yu Tsai, Icenowy Zheng, Jernej Skrabec,
Rob Herring, Mark Rutland, Catalin Marinas, Will Deacon,
David Airlie, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
Michael Turquette, Stephen Boyd, linux-clk-u79uwXL29TY76Z2rM5mHXA,
Michael Trimarchi,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
Cc: Jagan Teki
In-Reply-To: <20180518094536.17201-1-jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
Allwinner SoC like SUN8I and SUN50I has DE2 CCU so enable them
as default.
Signed-off-by: Jagan Teki <jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
---
Changes for v2:
- Enable for MACH_SUN8I
drivers/clk/sunxi-ng/Kconfig | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
index 826674d090fd..e20182aa9748 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -63,6 +63,8 @@ config SUN8I_V3S_CCU
config SUN8I_DE2_CCU
bool "Support for the Allwinner SoCs DE2 CCU"
+ default MACH_SUN8I || (ARM64 && ARCH_SUNXI)
+ depends on DRM_SUN4I && (MACH_SUN8I || (ARM64 && ARCH_SUNXI))
config SUN8I_R40_CCU
bool "Support for the Allwinner R40 CCU"
--
2.14.3
^ permalink raw reply related
* [PATCH v2 04/26] clk: sunxi-ng: a64: Add minimal rate for video PLLs
From: Jagan Teki @ 2018-05-18 9:45 UTC (permalink / raw)
To: Maxime Ripard, Chen-Yu Tsai, Icenowy Zheng, Jernej Skrabec,
Rob Herring, Mark Rutland, Catalin Marinas, Will Deacon,
David Airlie, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
Michael Turquette, Stephen Boyd, linux-clk-u79uwXL29TY76Z2rM5mHXA,
Michael Trimarchi,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
Cc: Jagan Teki
In-Reply-To: <20180518094536.17201-1-jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
According to documentation and experience with other similar SoCs, video
PLLs don't work stable if their output frequency is set below 192 MHz.
Because of that, set minimal rate to both A64 video PLLs to 192 MHz.
Signed-off-by: Jagan Teki <jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
---
Changes for v2:
- New patch
drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 46 ++++++++++++++++++-----------------
1 file changed, 24 insertions(+), 22 deletions(-)
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
index ee9c12cf3f08..d0e30192f0cf 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
@@ -64,17 +64,18 @@ static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
BIT(28), /* lock */
CLK_SET_RATE_UNGATE);
-static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video0_clk, "pll-video0",
- "osc24M", 0x010,
- 8, 7, /* N */
- 0, 4, /* M */
- BIT(24), /* frac enable */
- BIT(25), /* frac select */
- 270000000, /* frac rate 0 */
- 297000000, /* frac rate 1 */
- BIT(31), /* gate */
- BIT(28), /* lock */
- CLK_SET_RATE_UNGATE);
+static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video0_clk, "pll-video0",
+ "osc24M", 0x010,
+ 192000000, /* Minimum rate */
+ 8, 7, /* N */
+ 0, 4, /* M */
+ BIT(24), /* frac enable */
+ BIT(25), /* frac select */
+ 270000000, /* frac rate 0 */
+ 297000000, /* frac rate 1 */
+ BIT(31), /* gate */
+ BIT(28), /* lock */
+ CLK_SET_RATE_UNGATE);
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
"osc24M", 0x018,
@@ -125,17 +126,18 @@ static struct ccu_nk pll_periph1_clk = {
},
};
-static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video1_clk, "pll-video1",
- "osc24M", 0x030,
- 8, 7, /* N */
- 0, 4, /* M */
- BIT(24), /* frac enable */
- BIT(25), /* frac select */
- 270000000, /* frac rate 0 */
- 297000000, /* frac rate 1 */
- BIT(31), /* gate */
- BIT(28), /* lock */
- CLK_SET_RATE_UNGATE);
+static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video1_clk, "pll-video1",
+ "osc24M", 0x030,
+ 192000000, /* Minimum rate */
+ 8, 7, /* N */
+ 0, 4, /* M */
+ BIT(24), /* frac enable */
+ BIT(25), /* frac select */
+ 270000000, /* frac rate 0 */
+ 297000000, /* frac rate 1 */
+ BIT(31), /* gate */
+ BIT(28), /* lock */
+ CLK_SET_RATE_UNGATE);
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu",
"osc24M", 0x038,
--
2.14.3
^ permalink raw reply related
* [PATCH v2 05/26] drm/sun4i: DE2 mixer: Add index quirk
From: Jagan Teki @ 2018-05-18 9:45 UTC (permalink / raw)
To: Maxime Ripard, Chen-Yu Tsai, Icenowy Zheng, Jernej Skrabec,
Rob Herring, Mark Rutland, Catalin Marinas, Will Deacon,
David Airlie, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
Michael Turquette, Stephen Boyd, linux-clk-u79uwXL29TY76Z2rM5mHXA,
Michael Trimarchi,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
Cc: Jagan Teki
In-Reply-To: <20180518094536.17201-1-jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
From: Jernej Skrabec <jernej.skrabec-gGgVlfcn5nU@public.gmane.org>
When TCON set up TCON TOP, it needs to know mixer index. Here we do that
by setting engine ID to number provided in mixer index quirk.
Signed-off-by: Jernej Skrabec <jernej.skrabec-gGgVlfcn5nU@public.gmane.org>
Signed-off-by: Jagan Teki <jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
---
Changes for v2:
- New patch
drivers/gpu/drm/sun4i/sun8i_mixer.c | 4 ++--
drivers/gpu/drm/sun4i/sun8i_mixer.h | 2 ++
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index 126899d6f0d3..36d90c76317a 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -353,13 +353,13 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
dev_set_drvdata(dev, mixer);
mixer->engine.ops = &sun8i_engine_ops;
mixer->engine.node = dev->of_node;
- /* The ID of the mixer currently doesn't matter */
- mixer->engine.id = -1;
mixer->cfg = of_device_get_match_data(dev);
if (!mixer->cfg)
return -EINVAL;
+ mixer->engine.id = mixer->cfg->index;
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
regs = devm_ioremap_resource(dev, res);
if (IS_ERR(regs))
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h
index f34e70c42adf..aeda6e9a7627 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
@@ -123,6 +123,7 @@ struct de2_fmt_info {
* are invalid.
* @mod_rate: module clock rate that needs to be set in order to have
* a functional block.
+ * @index: mixer index, needed to properly set TCON TOP
*/
struct sun8i_mixer_cfg {
int vi_num;
@@ -130,6 +131,7 @@ struct sun8i_mixer_cfg {
int scaler_mask;
int ccsc;
unsigned long mod_rate;
+ int index;
};
struct sun8i_mixer {
--
2.14.3
^ permalink raw reply related
* [PATCH v2 06/26] drm/sun4i: Add support for A64 mixer1
From: Jagan Teki @ 2018-05-18 9:45 UTC (permalink / raw)
To: Maxime Ripard, Chen-Yu Tsai, Icenowy Zheng, Jernej Skrabec,
Rob Herring, Mark Rutland, Catalin Marinas, Will Deacon,
David Airlie, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
Michael Turquette, Stephen Boyd, linux-clk-u79uwXL29TY76Z2rM5mHXA,
Michael Trimarchi,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
Cc: Jagan Teki
In-Reply-To: <20180518094536.17201-1-jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
Mixers in Allwinner have similar capabilities as others SoCs with DE2.
Mixer1 has 1 VI and 1 UI planes and supports HW scaling on all
planes.
Signed-off-by: Jagan Teki <jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
---
Changes for v2:
- New patch
drivers/gpu/drm/sun4i/sun8i_mixer.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index 36d90c76317a..5b02c6ee2be6 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -508,6 +508,15 @@ static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = {
.mod_rate = 150000000,
};
+static const struct sun8i_mixer_cfg sun50i_a64_mixer1_cfg = {
+ .ccsc = 1,
+ .index = 1,
+ .mod_rate = 297000000,
+ .scaler_mask = 0x3,
+ .ui_num = 1,
+ .vi_num = 1,
+};
+
static const struct of_device_id sun8i_mixer_of_table[] = {
{
.compatible = "allwinner,sun8i-a83t-de2-mixer-0",
@@ -525,6 +534,10 @@ static const struct of_device_id sun8i_mixer_of_table[] = {
.compatible = "allwinner,sun8i-v3s-de2-mixer",
.data = &sun8i_v3s_mixer_cfg,
},
+ {
+ .compatible = "allwinner,sun50i-a64-de2-mixer-1",
+ .data = &sun50i_a64_mixer1_cfg,
+ },
{ }
};
MODULE_DEVICE_TABLE(of, sun8i_mixer_of_table);
--
2.14.3
^ permalink raw reply related
* [PATCH v2 07/26] dt-bindings: display: Add compatible for A64 DE2 tcon1 blocks
From: Jagan Teki @ 2018-05-18 9:45 UTC (permalink / raw)
To: Maxime Ripard, Chen-Yu Tsai, Icenowy Zheng, Jernej Skrabec,
Rob Herring, Mark Rutland, Catalin Marinas, Will Deacon,
David Airlie, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
Michael Turquette, Stephen Boyd, linux-clk-u79uwXL29TY76Z2rM5mHXA,
Michael Trimarchi,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
Cc: Jagan Teki
In-Reply-To: <20180518094536.17201-1-jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
Allwinner A64 has DE2 pipeline with tcon0 and tcon1 block
which is similar Allwinner A83T.
This patch adds dt-binding documentation for A64 DE2 tcon1 blocks.
Mixer1 has different configuration for A64 so use separate compatible
but tcon1 has similar behaviour with A83T so add fallback compatible.
Signed-off-by: Jagan Teki <jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
---
Changes for v2:
- Add fallback compatible for tcon1
- Add separate compatible for mixer1
Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
index 3346c1e2a7a0..863afad6a4df 100644
--- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
+++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
@@ -148,6 +148,7 @@ Required properties:
* allwinner,sun8i-v3s-tcon
* allwinner,sun9i-a80-tcon-lcd
* allwinner,sun9i-a80-tcon-tv
+ * "allwinner,sun50i-a64-tcon-tv", "allwinner,sun8i-a83t-tcon-tv"
- reg: base address and size of memory-mapped region
- interrupts: interrupt associated to this IP
- clocks: phandles to the clocks feeding the TCON.
@@ -311,6 +312,7 @@ Required properties:
* allwinner,sun8i-a83t-de2-mixer-1
* allwinner,sun8i-h3-de2-mixer-0
* allwinner,sun8i-v3s-de2-mixer
+ * allwinner,sun50i-a64-de2-mixer-1"
- reg: base address and size of the memory-mapped region.
- clocks: phandles to the clocks feeding the mixer
* bus: the mixer interface clock
@@ -343,6 +345,7 @@ Required properties:
* allwinner,sun8i-h3-display-engine
* allwinner,sun8i-v3s-display-engine
* allwinner,sun9i-a80-display-engine
+ * allwinner,sun50i-a64-display-engine
- allwinner,pipelines: list of phandle to the display engine
frontends (DE 1.0) or mixers (DE 2.0) available.
--
2.14.3
^ permalink raw reply related
* [PATCH v2 08/26] drm/sun4i: Add support for A64 display engine
From: Jagan Teki @ 2018-05-18 9:45 UTC (permalink / raw)
To: Maxime Ripard, Chen-Yu Tsai, Icenowy Zheng, Jernej Skrabec,
Rob Herring, Mark Rutland, Catalin Marinas, Will Deacon,
David Airlie, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
Michael Turquette, Stephen Boyd, linux-clk-u79uwXL29TY76Z2rM5mHXA,
Michael Trimarchi,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
Cc: Jagan Teki
In-Reply-To: <20180518094536.17201-1-jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
Display Engine(DE2) in Allwinner A64 has two mixers and tcons.
The routing for mixer0 is through tcon0 and connected to
LVDS/RGB/MIPI-DSI controller.
The routing for mixer1 is through tcon1 and connected to HDMI.
Signed-off-by: Jagan Teki <jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
---
Changes for v2:
- none
drivers/gpu/drm/sun4i/sun4i_drv.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index 50d19605c38f..c84102a750f8 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -368,6 +368,7 @@ static const struct of_device_id sun4i_drv_of_table[] = {
{ .compatible = "allwinner,sun8i-h3-display-engine" },
{ .compatible = "allwinner,sun8i-v3s-display-engine" },
{ .compatible = "allwinner,sun9i-a80-display-engine" },
+ { .compatible = "allwinner,sun50i-a64-display-engine" },
{ }
};
MODULE_DEVICE_TABLE(of, sun4i_drv_of_table);
--
2.14.3
^ permalink raw reply related
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