* [PATCH v2 04/10] drm/exynos: add non-panel path to exynos_dsi_enable()
From: Maciej Purski @ 2018-05-30 12:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527682561-1386-1-git-send-email-m.purski@samsung.com>
As DSIM can now have a bridge connected as a peripheral, it should be
possible to successfully enable exynos_dsi, when there is no panel
provided.
Signed-off-by: Maciej Purski <m.purski@samsung.com>
---
drivers/gpu/drm/exynos/exynos_drm_dsi.c | 26 ++++++++++++--------------
1 file changed, 12 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 7b50bad..7f6a0b1 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1382,27 +1382,25 @@ static void exynos_dsi_enable(struct drm_encoder *encoder)
if (dsi->state & DSIM_STATE_ENABLED)
return;
- pm_runtime_get_sync(dsi->dev);
-
- dsi->state |= DSIM_STATE_ENABLED;
-
- ret = drm_panel_prepare(dsi->panel);
- if (ret < 0) {
- dsi->state &= ~DSIM_STATE_ENABLED;
- return;
+ if (dsi->panel) {
+ ret = drm_panel_prepare(dsi->panel);
+ if (ret < 0)
+ return;
}
exynos_dsi_set_display_mode(dsi);
exynos_dsi_set_display_enable(dsi, true);
- ret = drm_panel_enable(dsi->panel);
- if (ret < 0) {
- dsi->state &= ~DSIM_STATE_ENABLED;
- exynos_dsi_set_display_enable(dsi, false);
- drm_panel_unprepare(dsi->panel);
- return;
+ if (dsi->panel) {
+ ret = drm_panel_enable(dsi->panel);
+ if (ret < 0) {
+ exynos_dsi_set_display_enable(dsi, false);
+ drm_panel_unprepare(dsi->panel);
+ return;
+ }
}
+ dsi->state |= DSIM_STATE_ENABLED;
dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;
}
--
2.7.4
^ permalink raw reply related
* [PATCH v2 05/10] panel/hv070wsa-100: add DT bindings
From: Maciej Purski @ 2018-05-30 12:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527682561-1386-1-git-send-email-m.purski@samsung.com>
From: Andrzej Hajda <a.hajda@samsung.com>
The patch adds bindings to BOE HV070-WSA WSVGA panel.
Bindings are compatible with simple panel bindings.
Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Maciej Purski <m.purski@samsung.com>
---
.../devicetree/bindings/display/panel/boe,hv070wsa-100.txt | 7 +++++++
1 file changed, 7 insertions(+)
create mode 100644 Documentation/devicetree/bindings/display/panel/boe,hv070wsa-100.txt
diff --git a/Documentation/devicetree/bindings/display/panel/boe,hv070wsa-100.txt b/Documentation/devicetree/bindings/display/panel/boe,hv070wsa-100.txt
new file mode 100644
index 0000000..bfc20ac
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/boe,hv070wsa-100.txt
@@ -0,0 +1,7 @@
+BOE HV070WSA-100 7.01" WSVGA TFT LCD panel
+
+Required properties:
+- compatible: should be "boe,hv070wsa-100"
+
+This binding is compatible with the simple-panel binding, which is specified
+in simple-panel.txt in this directory.
--
2.7.4
^ permalink raw reply related
* [PATCH v2 06/10] drm/panel: add support for BOE HV070WSA-100 panel to simple-panel
From: Maciej Purski @ 2018-05-30 12:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527682561-1386-1-git-send-email-m.purski@samsung.com>
From: Andrzej Hajda <a.hajda@samsung.com>
The patch adds support for BOE HV070WSA-100 WSVGA 7.01 inch panel
in panel-simple driver. The panel is used in Exynos5250-arndale boards.
Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Maciej Purski <m.purski@samsung.com>
---
drivers/gpu/drm/panel/panel-simple.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index cbf1ab4..d5da58d 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -745,6 +745,28 @@ static const struct panel_desc avic_tm070ddh03 = {
},
};
+static const struct drm_display_mode boe_hv070wsa_mode = {
+ .clock = 40800,
+ .hdisplay = 1024,
+ .hsync_start = 1024 + 90,
+ .hsync_end = 1024 + 90 + 90,
+ .htotal = 1024 + 90 + 90 + 90,
+ .vdisplay = 600,
+ .vsync_start = 600 + 3,
+ .vsync_end = 600 + 3 + 4,
+ .vtotal = 600 + 3 + 4 + 3,
+ .vrefresh = 60,
+};
+
+static const struct panel_desc boe_hv070wsa = {
+ .modes = &boe_hv070wsa_mode,
+ .num_modes = 1,
+ .size = {
+ .width = 154,
+ .height = 90,
+ },
+};
+
static const struct drm_display_mode boe_nv101wxmn51_modes[] = {
{
.clock = 71900,
@@ -2113,6 +2135,9 @@ static const struct of_device_id platform_of_match[] = {
.compatible = "avic,tm070ddh03",
.data = &avic_tm070ddh03,
}, {
+ .compatible = "boe,hv070wsa-100",
+ .data = &boe_hv070wsa
+ }, {
.compatible = "boe,nv101wxmn51",
.data = &boe_nv101wxmn51,
}, {
--
2.7.4
^ permalink raw reply related
* [PATCH v2 07/10] dt-bindings: tc358754: add DT bindings
From: Maciej Purski @ 2018-05-30 12:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527682561-1386-1-git-send-email-m.purski@samsung.com>
From: Andrzej Hajda <a.hajda@samsung.com>
The patch adds bindings to Toshiba DSI/LVDS bridge TC358764.
Bindings describe power supplies, reset gpio and video interfaces.
Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Maciej Purski <m.purski@samsung.com>
---
.../bindings/display/bridge/toshiba,tc358764.txt | 37 ++++++++++++++++++++++
1 file changed, 37 insertions(+)
create mode 100644 Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt
diff --git a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt
new file mode 100644
index 0000000..6eda14f
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt
@@ -0,0 +1,37 @@
+TC358764 MIPI-DSI to LVDS panel bridge
+
+Required properties:
+ - compatible: "toshiba,tc358764"
+ - reg: the virtual channel number of a DSI peripheral
+ - vddc-supply: core voltage supply, 1.2V
+ - vddio-supply: I/O voltage supply, 1.8V or 3.3V
+ - vddlvds-supply: LVDS1/2 voltage supply, 3.3V
+ - reset-gpios: a GPIO spec for the reset pin
+
+The device node can contain zero to two 'port' child nodes, each with one
+child 'endpoint' node, according to the bindings defined in [1].
+The following are properties specific to those nodes.
+
+port:
+ - reg: (required) can be 0 for DSI port or 1 for LVDS port;
+
+[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
+
+Example:
+
+ bridge at 0 {
+ reg = <0>;
+ compatible = "toshiba,tc358764";
+ vddc-supply = <&vcc_1v2_reg>;
+ vddio-supply = <&vcc_1v8_reg>;
+ vddlvds-supply = <&vcc_3v3_reg>;
+ reset-gpios = <&gpd1 6 GPIO_ACTIVE_LOW>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port at 1 {
+ reg = <1>;
+ lvds_ep: endpoint {
+ remote-endpoint = <&panel_ep>;
+ };
+ };
+ };
--
2.7.4
^ permalink raw reply related
* [PATCH v2 08/10] drm/bridge: tc358764: Add DSI to LVDS bridge driver
From: Maciej Purski @ 2018-05-30 12:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527682561-1386-1-git-send-email-m.purski@samsung.com>
From: Andrzej Hajda <a.hajda@samsung.com>
Add a drm_bridge driver for the Toshiba TC358764 DSI to LVDS bridge.
Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Maciej Purski <m.purski@samsung.com>
---
drivers/gpu/drm/bridge/Kconfig | 9 +
drivers/gpu/drm/bridge/Makefile | 1 +
drivers/gpu/drm/bridge/tc358764.c | 547 ++++++++++++++++++++++++++++++++++++++
3 files changed, 557 insertions(+)
create mode 100644 drivers/gpu/drm/bridge/tc358764.c
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index fa2c799..9bd3eb8 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -110,6 +110,15 @@ config DRM_THINE_THC63LVD1024
---help---
Thine THC63LVD1024 LVDS/parallel converter driver.
+config DRM_TOSHIBA_TC358764
+ tristate "TC358764 DSI/LVDS bridge"
+ depends on DRM && DRM_PANEL
+ depends on OF
+ select DRM_MIPI_DSI
+ select VIDEOMODE_HELPERS
+ help
+ Toshiba TC358764 DSI/LVDS bridge driver
+
config DRM_TOSHIBA_TC358767
tristate "Toshiba TC358767 eDP bridge"
depends on OF
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 35f88d4..bf7c0ce 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o
obj-$(CONFIG_DRM_SII902X) += sii902x.o
obj-$(CONFIG_DRM_SII9234) += sii9234.o
obj-$(CONFIG_DRM_THINE_THC63LVD1024) += thc63lvd1024.o
+obj-$(CONFIG_DRM_TOSHIBA_TC358764) += tc358764.o
obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o
obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/
obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/
diff --git a/drivers/gpu/drm/bridge/tc358764.c b/drivers/gpu/drm/bridge/tc358764.c
new file mode 100644
index 0000000..3109eba
--- /dev/null
+++ b/drivers/gpu/drm/bridge/tc358764.c
@@ -0,0 +1,547 @@
+/*
+ * Copyright (C) 2018 Samsung Electronics Co., Ltd
+ *
+ * Authors:
+ * Andrzej Hajda <a.hajda@samsung.com>
+ * Maciej Purski <m.purski@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ *
+ */
+
+#include <drm/drm_atomic_helper.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_panel.h>
+
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+
+#include <linux/gpio/consumer.h>
+#include <linux/of_graph.h>
+#include <linux/regulator/consumer.h>
+
+#include <video/mipi_display.h>
+#include <video/of_videomode.h>
+#include <video/videomode.h>
+
+#define FLD_MASK(start, end) (((1 << ((start) - (end) + 1)) - 1) << (end))
+#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end))
+
+/* PPI layer registers */
+#define PPI_STARTPPI 0x0104 /* START control bit */
+#define PPI_LPTXTIMECNT 0x0114 /* LPTX timing signal */
+#define PPI_LANEENABLE 0x0134 /* Enables each lane */
+#define PPI_TX_RX_TA 0x013C /* BTA timing parameters */
+#define PPI_D0S_CLRSIPOCOUNT 0x0164 /* Assertion timer for Lane 0 */
+#define PPI_D1S_CLRSIPOCOUNT 0x0168 /* Assertion timer for Lane 1 */
+#define PPI_D2S_CLRSIPOCOUNT 0x016C /* Assertion timer for Lane 2 */
+#define PPI_D3S_CLRSIPOCOUNT 0x0170 /* Assertion timer for Lane 3 */
+#define PPI_START_FUNCTION 1
+
+/* DSI layer registers */
+#define DSI_STARTDSI 0x0204 /* START control bit of DSI-TX */
+#define DSI_LANEENABLE 0x0210 /* Enables each lane */
+#define DSI_RX_START 1
+
+/* Video path registers */
+#define VP_CTRL 0x0450 /* Video Path Control */
+#define VP_CTRL_MSF(v) FLD_VAL(v, 0, 0) /* Magic square in RGB666 */
+#define VP_CTRL_VTGEN(v) FLD_VAL(v, 4, 4) /* Use chip clock for timing */
+#define VP_CTRL_EVTMODE(v) FLD_VAL(v, 5, 5) /* Event mode */
+#define VP_CTRL_RGB888(v) FLD_VAL(v, 8, 8) /* RGB888 mode */
+#define VP_CTRL_VSDELAY(v) FLD_VAL(v, 31, 20) /* VSYNC delay */
+#define VP_CTRL_HSPOL BIT(17) /* Polarity of HSYNC signal */
+#define VP_CTRL_DEPOL BIT(18) /* Polarity of DE signal */
+#define VP_CTRL_VSPOL BIT(19) /* Polarity of VSYNC signal */
+#define VP_HTIM1 0x0454 /* Horizontal Timing Control 1 */
+#define VP_HTIM1_HBP(v) FLD_VAL(v, 24, 16)
+#define VP_HTIM1_HSYNC(v) FLD_VAL(v, 8, 0)
+#define VP_HTIM2 0x0458 /* Horizontal Timing Control 2 */
+#define VP_HTIM2_HFP(v) FLD_VAL(v, 24, 16)
+#define VP_HTIM2_HACT(v) FLD_VAL(v, 10, 0)
+#define VP_VTIM1 0x045C /* Vertical Timing Control 1 */
+#define VP_VTIM1_VBP(v) FLD_VAL(v, 23, 16)
+#define VP_VTIM1_VSYNC(v) FLD_VAL(v, 7, 0)
+#define VP_VTIM2 0x0460 /* Vertical Timing Control 2 */
+#define VP_VTIM2_VFP(v) FLD_VAL(v, 23, 16)
+#define VP_VTIM2_VACT(v) FLD_VAL(v, 10, 0)
+#define VP_VFUEN 0x0464 /* Video Frame Timing Update Enable */
+
+/* LVDS registers */
+#define LV_MX0003 0x0480 /* Mux input bit 0 to 3 */
+#define LV_MX0407 0x0484 /* Mux input bit 4 to 7 */
+#define LV_MX0811 0x0488 /* Mux input bit 8 to 11 */
+#define LV_MX1215 0x048C /* Mux input bit 12 to 15 */
+#define LV_MX1619 0x0490 /* Mux input bit 16 to 19 */
+#define LV_MX2023 0x0494 /* Mux input bit 20 to 23 */
+#define LV_MX2427 0x0498 /* Mux input bit 24 to 27 */
+#define LV_MX(b0, b1, b2, b3) (FLD_VAL(b0, 4, 0) | FLD_VAL(b1, 12, 8) | \
+ FLD_VAL(b2, 20, 16) | FLD_VAL(b3, 28, 24))
+
+/* Input bit numbers used in mux registers */
+enum {
+ LVI_R0,
+ LVI_R1,
+ LVI_R2,
+ LVI_R3,
+ LVI_R4,
+ LVI_R5,
+ LVI_R6,
+ LVI_R7,
+ LVI_G0,
+ LVI_G1,
+ LVI_G2,
+ LVI_G3,
+ LVI_G4,
+ LVI_G5,
+ LVI_G6,
+ LVI_G7,
+ LVI_B0,
+ LVI_B1,
+ LVI_B2,
+ LVI_B3,
+ LVI_B4,
+ LVI_B5,
+ LVI_B6,
+ LVI_B7,
+ LVI_HS,
+ LVI_VS,
+ LVI_DE,
+ LVI_L0
+};
+
+#define LV_CFG 0x049C /* LVDS Configuration */
+#define LV_PHY0 0x04A0 /* LVDS PHY 0 */
+#define LV_PHY0_RST(v) FLD_VAL(v, 22, 22) /* PHY reset */
+#define LV_PHY0_IS(v) FLD_VAL(v, 15, 14)
+#define LV_PHY0_ND(v) FLD_VAL(v, 4, 0) /* Frequency range select */
+#define LV_PHY0_PRBS_ON(v) FLD_VAL(v, 20, 16) /* Clock/Data Flag pins */
+
+/* System registers */
+#define SYS_RST 0x0504 /* System Reset */
+#define SYS_ID 0x0580 /* System ID */
+
+#define SYS_RST_I2CS BIT(0) /* Reset I2C-Slave controller */
+#define SYS_RST_I2CM BIT(1) /* Reset I2C-Master controller */
+#define SYS_RST_LCD BIT(2) /* Reset LCD controller */
+#define SYS_RST_BM BIT(3) /* Reset Bus Management controller */
+#define SYS_RST_DSIRX BIT(4) /* Reset DSI-RX and App controller */
+#define SYS_RST_REG BIT(5) /* Reset Register module */
+
+#define LPX_PERIOD 2
+#define TTA_SURE 3
+#define TTA_GET 0x20000
+
+/* Lane enable PPI and DSI register bits */
+#define LANEENABLE_CLEN BIT(0)
+#define LANEENABLE_L0EN BIT(1)
+#define LANEENABLE_L1EN BIT(2)
+#define LANEENABLE_L2EN BIT(3)
+#define LANEENABLE_L3EN BIT(4)
+
+/* LVCFG fields */
+#define LV_CFG_LVEN BIT(0)
+#define LV_CFG_LVDLINK BIT(1)
+#define LV_CFG_CLKPOL1 BIT(2)
+#define LV_CFG_CLKPOL2 BIT(3)
+
+static const char * const tc358764_supplies[] = {
+ "vddc", "vddio", "vddmipi", "vddlvds133", "vddlvds112"
+};
+
+struct tc358764 {
+ struct device *dev;
+ struct drm_bridge bridge;
+ struct drm_connector connector;
+ struct regulator_bulk_data supplies[ARRAY_SIZE(tc358764_supplies)];
+ struct gpio_desc *gpio_reset;
+
+ struct drm_panel *panel;
+};
+
+static int tc358764_read(struct tc358764 *ctx, u16 addr, u32 *val)
+{
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+ const struct mipi_dsi_host_ops *ops = dsi->host->ops;
+ struct mipi_dsi_msg msg = {
+ .type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM,
+ .channel = dsi->channel,
+ .flags = MIPI_DSI_MSG_USE_LPM,
+ .tx_buf = &addr,
+ .tx_len = 2,
+ .rx_buf = val,
+ .rx_len = 4
+ };
+ ssize_t ret;
+
+ if (!ops || !ops->transfer)
+ return -EINVAL;
+
+ cpu_to_le16s(&addr);
+
+ ret = ops->transfer(dsi->host, &msg);
+ if (ret >= 0)
+ le32_to_cpus(val);
+
+ dev_dbg(ctx->dev, "read: %d, addr: %d\n", addr, *val);
+
+ return ret;
+}
+
+static int tc358764_write(struct tc358764 *ctx, u16 addr, u32 val)
+{
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+ const struct mipi_dsi_host_ops *ops = dsi->host->ops;
+ u8 data[6];
+ int ret;
+ struct mipi_dsi_msg msg = {
+ .type = MIPI_DSI_GENERIC_LONG_WRITE,
+ .channel = dsi->channel,
+ .flags = MIPI_DSI_MSG_USE_LPM | MIPI_DSI_MSG_REQ_ACK,
+ .tx_buf = data,
+ .tx_len = 6
+ };
+
+ if (!ops || !ops->transfer)
+ return -EINVAL;
+
+ data[0] = addr;
+ data[1] = addr >> 8;
+ data[2] = val;
+ data[3] = val >> 8;
+ data[4] = val >> 16;
+ data[5] = val >> 24;
+
+ ret = ops->transfer(dsi->host, &msg);
+
+ return ret;
+}
+
+static inline struct tc358764 *bridge_to_tc358764(struct drm_bridge *bridge)
+{
+ return container_of(bridge, struct tc358764, bridge);
+}
+
+static inline
+struct tc358764 *connector_to_tc358764(struct drm_connector *connector)
+{
+ return container_of(connector, struct tc358764, connector);
+}
+
+static int tc358764_init(struct tc358764 *ctx)
+{
+ u32 v = 0;
+
+ tc358764_read(ctx, SYS_ID, &v);
+ dev_info(ctx->dev, "ID: %#x\n", v);
+
+ /* configure PPI counters */
+ tc358764_write(ctx, PPI_TX_RX_TA, TTA_GET | TTA_SURE);
+ tc358764_write(ctx, PPI_LPTXTIMECNT, LPX_PERIOD);
+ tc358764_write(ctx, PPI_D0S_CLRSIPOCOUNT, 5);
+ tc358764_write(ctx, PPI_D1S_CLRSIPOCOUNT, 5);
+ tc358764_write(ctx, PPI_D2S_CLRSIPOCOUNT, 5);
+ tc358764_write(ctx, PPI_D3S_CLRSIPOCOUNT, 5);
+
+ /* enable four data lanes and clock lane */
+ tc358764_write(ctx, PPI_LANEENABLE, LANEENABLE_L3EN | LANEENABLE_L2EN |
+ LANEENABLE_L1EN | LANEENABLE_L0EN | LANEENABLE_CLEN);
+ tc358764_write(ctx, DSI_LANEENABLE, LANEENABLE_L3EN | LANEENABLE_L2EN |
+ LANEENABLE_L1EN | LANEENABLE_L0EN | LANEENABLE_CLEN);
+
+ /* start */
+ tc358764_write(ctx, PPI_STARTPPI, PPI_START_FUNCTION);
+ tc358764_write(ctx, DSI_STARTDSI, DSI_RX_START);
+
+ /* configure video path */
+ tc358764_write(ctx, VP_CTRL, VP_CTRL_VSDELAY(15) | VP_CTRL_RGB888(1) |
+ VP_CTRL_EVTMODE(1) | VP_CTRL_HSPOL | VP_CTRL_VSPOL);
+
+ /* reset PHY */
+ tc358764_write(ctx, LV_PHY0, LV_PHY0_RST(1) |
+ LV_PHY0_PRBS_ON(4) | LV_PHY0_IS(2) | LV_PHY0_ND(6));
+ tc358764_write(ctx, LV_PHY0, LV_PHY0_PRBS_ON(4) | LV_PHY0_IS(2) |
+ LV_PHY0_ND(6));
+
+ /* reset bridge */
+ tc358764_write(ctx, SYS_RST, SYS_RST_LCD);
+
+ /* set bit order */
+ tc358764_write(ctx, LV_MX0003, LV_MX(LVI_R0, LVI_R1, LVI_R2, LVI_R3));
+ tc358764_write(ctx, LV_MX0407, LV_MX(LVI_R4, LVI_R7, LVI_R5, LVI_G0));
+ tc358764_write(ctx, LV_MX0811, LV_MX(LVI_G1, LVI_G2, LVI_G6, LVI_G7));
+ tc358764_write(ctx, LV_MX1215, LV_MX(LVI_G3, LVI_G4, LVI_G5, LVI_B0));
+ tc358764_write(ctx, LV_MX1619, LV_MX(LVI_B6, LVI_B7, LVI_B1, LVI_B2));
+ tc358764_write(ctx, LV_MX2023, LV_MX(LVI_B3, LVI_B4, LVI_B5, LVI_L0));
+ tc358764_write(ctx, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, LVI_R6));
+ tc358764_write(ctx, LV_CFG, LV_CFG_CLKPOL2 | LV_CFG_CLKPOL1 |
+ LV_CFG_LVEN);
+
+ return 0;
+}
+
+static void tc358764_reset(struct tc358764 *ctx)
+{
+ msleep(20);
+ gpiod_set_value(ctx->gpio_reset, 0);
+ msleep(20);
+ gpiod_set_value(ctx->gpio_reset, 1);
+ msleep(40);
+}
+
+static void tc358764_poweroff(struct tc358764 *ctx)
+{
+ int ret;
+
+ tc358764_reset(ctx);
+
+ drm_panel_disable(ctx->panel);
+ msleep(40);
+
+ ret = regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+ if (ret < 0)
+ dev_err(ctx->dev, "error disabling regulators (%d)\n", ret);
+}
+
+static int tc358764_get_modes(struct drm_connector *connector)
+{
+ struct tc358764 *ctx = connector_to_tc358764(connector);
+
+ if (ctx->panel && ctx->panel->funcs && ctx->panel->funcs->get_modes)
+ return ctx->panel->funcs->get_modes(ctx->panel);
+
+ return 0;
+}
+
+static const
+struct drm_connector_helper_funcs tc358764_connector_helper_funcs = {
+ .get_modes = tc358764_get_modes,
+};
+
+static const struct drm_connector_funcs tc358764_connector_funcs = {
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .destroy = drm_connector_cleanup,
+ .reset = drm_atomic_helper_connector_reset,
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static void tc358764_disable(struct drm_bridge *bridge)
+{
+ struct tc358764 *ctx = bridge_to_tc358764(bridge);
+
+ tc358764_poweroff(ctx);
+}
+
+static void tc358764_pre_enable(struct drm_bridge *bridge)
+{
+ struct tc358764 *ctx = bridge_to_tc358764(bridge);
+ int ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies),
+ ctx->supplies);
+ if (ret < 0)
+ dev_err(ctx->dev, "error enabling regulators (%d)\n", ret);
+
+ tc358764_reset(ctx);
+ tc358764_init(ctx);
+}
+
+static void tc358764_enable(struct drm_bridge *bridge)
+{
+ struct tc358764 *ctx = bridge_to_tc358764(bridge);
+ int ret;
+
+ drm_panel_prepare(ctx->panel);
+
+ ret = drm_panel_enable(ctx->panel);
+ if (ret < 0)
+ pr_err("panel enable failed\n");
+
+ msleep(40);
+}
+
+static int tc358764_attach(struct drm_bridge *bridge)
+{
+ struct tc358764 *ctx = bridge_to_tc358764(bridge);
+ struct drm_device *drm = bridge->dev;
+ int ret;
+
+ if (!bridge->encoder) {
+ DRM_ERROR("Encoder not found\n");
+ return -ENODEV;
+ }
+
+ ctx->connector.polled = DRM_CONNECTOR_POLL_HPD;
+ ret = drm_connector_init(drm, &ctx->connector,
+ &tc358764_connector_funcs,
+ DRM_MODE_CONNECTOR_LVDS);
+ if (ret) {
+ DRM_ERROR("Failed to initialize connector\n");
+ return ret;
+ }
+
+ drm_connector_helper_add(&ctx->connector,
+ &tc358764_connector_helper_funcs);
+
+ drm_mode_connector_attach_encoder(&ctx->connector, bridge->encoder);
+
+ if (ctx->panel)
+ drm_panel_attach(ctx->panel, &ctx->connector);
+
+ drm_atomic_helper_connector_reset(&ctx->connector);
+ drm_connector_register(&ctx->connector);
+
+ return 0;
+}
+
+static const struct drm_bridge_funcs tc358764_bridge_funcs = {
+ .disable = tc358764_disable,
+ .enable = tc358764_enable,
+ .pre_enable = tc358764_pre_enable,
+ .attach = tc358764_attach,
+};
+
+static struct device_node *tc358764_of_find_panel_node(struct device *dev)
+{
+ struct device_node *np, *ep;
+
+ ep = of_graph_get_endpoint_by_regs(dev->of_node, 1, 0);
+ if (!ep) {
+ pr_err("faile to get endpoint\n");
+ return NULL;
+ }
+
+ np = of_graph_get_remote_port_parent(ep);
+
+ return np;
+}
+
+static int tc358764_parse_dt(struct tc358764 *ctx)
+{
+ struct device *dev = ctx->dev;
+ struct device_node *np = dev->of_node;
+ struct device_node *lvds;
+
+ ctx->gpio_reset = devm_gpiod_get_from_of_node(dev, np, "reset", 0,
+ GPIOD_OUT_LOW,
+ "tc358764-reset");
+ if (IS_ERR(ctx->gpio_reset)) {
+ dev_err(dev, "no reset GPIO pin provided\n");
+ return PTR_ERR(ctx->gpio_reset);
+ }
+
+ lvds = tc358764_of_find_panel_node(ctx->dev);
+ if (!lvds) {
+ dev_err(dev, "cannot find panel node\n");
+ return -EINVAL;
+ }
+
+ ctx->panel = of_drm_find_panel(lvds);
+ if (!ctx->panel) {
+ dev_err(dev, "panel not registered\n");
+ return -EPROBE_DEFER;
+ }
+
+ return 0;
+}
+
+static int tc358764_configure_regulators(struct tc358764 *ctx)
+{
+ int i, ret;
+
+ for (i = 0; i < ARRAY_SIZE(ctx->supplies); ++i)
+ ctx->supplies[i].supply = tc358764_supplies[i];
+
+ ret = devm_regulator_bulk_get(ctx->dev, ARRAY_SIZE(ctx->supplies),
+ ctx->supplies);
+ if (ret < 0)
+ dev_err(ctx->dev, "failed to get regulators: %d\n", ret);
+
+ return ret;
+}
+
+static int tc358764_probe(struct mipi_dsi_device *dsi)
+{
+ struct device *dev = &dsi->dev;
+ struct tc358764 *ctx;
+ int ret;
+
+ ctx = devm_kzalloc(dev, sizeof(struct tc358764), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ mipi_dsi_set_drvdata(dsi, ctx);
+
+ ctx->dev = dev;
+
+ dsi->lanes = 4;
+ dsi->format = MIPI_DSI_FMT_RGB888;
+ dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST
+ | MIPI_DSI_MODE_VIDEO_AUTO_VERT;
+
+ ret = tc358764_parse_dt(ctx);
+ if (ret < 0)
+ return ret;
+
+ ret = tc358764_configure_regulators(ctx);
+ if (ret < 0)
+ return ret;
+
+ ctx->bridge.funcs = &tc358764_bridge_funcs;
+ ctx->bridge.of_node = dev->of_node;
+
+ drm_bridge_add(&ctx->bridge);
+
+ ret = mipi_dsi_attach(dsi);
+ if (ret < 0) {
+ drm_bridge_remove(&ctx->bridge);
+ dev_err(dev, "failed to attach dsi\n");
+ }
+
+ return ret;
+}
+
+static int tc358764_remove(struct mipi_dsi_device *dsi)
+{
+ struct tc358764 *ctx = mipi_dsi_get_drvdata(dsi);
+
+ tc358764_poweroff(ctx);
+
+ mipi_dsi_detach(dsi);
+ drm_bridge_remove(&ctx->bridge);
+
+ return 0;
+}
+
+static const struct of_device_id tc358764_of_match[] = {
+ { .compatible = "toshiba,tc358764" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, tc358764_of_match);
+
+static struct mipi_dsi_driver tc358764_driver = {
+ .probe = tc358764_probe,
+ .remove = tc358764_remove,
+ .driver = {
+ .name = "tc358764",
+ .owner = THIS_MODULE,
+ .of_match_table = tc358764_of_match,
+ },
+};
+module_mipi_dsi_driver(tc358764_driver);
+
+MODULE_AUTHOR("Andrzej Hajda <a.hajda@samsung.com>");
+MODULE_AUTHOR("Maciej Purski <m.purski@samsung.com>");
+MODULE_DESCRIPTION("MIPI-DSI based Driver for TC358764 DSI/LVDS Bridge");
+MODULE_LICENSE("GPL v2");
--
2.7.4
^ permalink raw reply related
* [PATCH v2 09/10] ARM: dts: exynos5250: add DSI node
From: Maciej Purski @ 2018-05-30 12:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527682561-1386-1-git-send-email-m.purski@samsung.com>
From: Andrzej Hajda <a.hajda@samsung.com>
The patch adds common part of DSI node for Exynos5250 platforms
and a required mipi-phy node.
Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Maciej Purski <m.purski@samsung.com>
---
arch/arm/boot/dts/exynos5250.dtsi | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 2daf505..9965eca 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -733,6 +733,27 @@
#phy-cells = <0>;
};
+ mipi_phy: video-phy at 10040710 {
+ compatible = "samsung,s5pv210-mipi-video-phy";
+ reg = <0x10040710 0x100>;
+ #phy-cells = <1>;
+ syscon = <&pmu_system_controller>;
+ };
+
+ dsi_0: dsi at 14500000 {
+ compatible = "samsung,exynos4210-mipi-dsi";
+ reg = <0x14500000 0x10000>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ samsung,power-domain = <&pd_disp1>;
+ phys = <&mipi_phy 3>;
+ phy-names = "dsim";
+ clocks = <&clock CLK_DSIM0>, <&clock CLK_SCLK_MIPI1>;
+ clock-names = "bus_clk", "sclk_mipi";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
adc: adc at 12d10000 {
compatible = "samsung,exynos-adc-v1";
reg = <0x12D10000 0x100>;
--
2.7.4
^ permalink raw reply related
* [PATCH v2 10/10] ARM: dts: exynos5250-arndale: add DSI and panel nodes
From: Maciej Purski @ 2018-05-30 12:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527682561-1386-1-git-send-email-m.purski@samsung.com>
From: Andrzej Hajda <a.hajda@samsung.com>
The patch adds bridge and panel nodes.
It adds also DSI properties specific for arndale board and
regulators required by the bridge.
Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Maciej Purski <m.purski@samsung.com>
---
arch/arm/boot/dts/exynos5250-arndale.dts | 61 ++++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+)
diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
index 7a8a5c5..816d89d 100644
--- a/arch/arm/boot/dts/exynos5250-arndale.dts
+++ b/arch/arm/boot/dts/exynos5250-arndale.dts
@@ -71,6 +71,17 @@
};
};
+ panel: panel {
+ compatible = "boe,hv070wsa-100";
+ power-supply = <&vcc_3v3_reg>;
+ enable-gpios = <&gpd1 3 GPIO_ACTIVE_HIGH>;
+ port {
+ panel_ep: endpoint {
+ remote-endpoint = <&bridge_out_ep>;
+ };
+ };
+ };
+
regulators {
compatible = "simple-bus";
#address-cells = <1>;
@@ -97,6 +108,30 @@
reg = <2>;
regulator-name = "hdmi-en";
};
+
+ vcc_1v2_reg: regulator at 3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "VCC_1V2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ vcc_1v8_reg: regulator at 4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "VCC_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vcc_3v3_reg: regulator at 5 {
+ compatible = "regulator-fixed";
+ reg = <5>;
+ regulator-name = "VCC_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
};
fixed-rate-clocks {
@@ -119,6 +154,32 @@
cpu0-supply = <&buck2_reg>;
};
+&dsi_0 {
+ vddcore-supply = <&ldo8_reg>;
+ vddio-supply = <&ldo10_reg>;
+ samsung,pll-clock-frequency = <24000000>;
+ samsung,burst-clock-frequency = <320000000>;
+ samsung,esc-clock-frequency = <10000000>;
+ status = "okay";
+
+ bridge at 0 {
+ reg = <0>;
+ compatible = "toshiba,tc358764";
+ vddc-supply = <&vcc_1v2_reg>;
+ vddio-supply = <&vcc_1v8_reg>;
+ vddlvds-supply = <&vcc_3v3_reg>;
+ reset-gpios = <&gpd1 6 GPIO_ACTIVE_LOW>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port at 1 {
+ reg = <1>;
+ bridge_out_ep: endpoint {
+ remote-endpoint = <&panel_ep>;
+ };
+ };
+ };
+};
+
&dp {
status = "okay";
samsung,color-space = <0>;
--
2.7.4
^ permalink raw reply related
* [PATCH] ARM: debug: Add Iproc UART3 debug addresses
From: Clément Péron @ 2018-05-30 12:29 UTC (permalink / raw)
To: linux-arm-kernel
From: Cl?ment Peron <clement.peron@devialet.com>
Broadcom Iproc SoCs typically use the UART3 for
debug/console, provide a known good location for that.
Signed-off-by: Cl?ment Peron <clement.peron@devialet.com>
---
arch/arm/Kconfig.debug | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 199ebc1c4538..fa6fa1dae94d 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -207,6 +207,14 @@ choice
depends on ARCH_BCM_HR2
select DEBUG_UART_8250
+ config DEBUG_BCM_IPROC_UART3
+ bool "Kernel low-level debugging on BCM IPROC UART3"
+ depends on ARCH_BCM_CYGNUS
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the third serial port on these devices.
+
config DEBUG_BCM_KONA_UART
bool "Kernel low-level debugging messages via BCM KONA UART"
depends on ARCH_BCM_MOBILE
@@ -1564,6 +1572,7 @@ config DEBUG_UART_PHYS
default 0x20068000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3
default 0x20201000 if DEBUG_BCM2835
default 0x3f201000 if DEBUG_BCM2836
+ default 0x18023000 if DEBUG_BCM_IPROC_UART3
default 0x3e000000 if DEBUG_BCM_KONA_UART
default 0x4000e400 if DEBUG_LL_UART_EFM32
default 0x40028000 if DEBUG_AT91_SAMV7_USART1
@@ -1730,6 +1739,7 @@ config DEBUG_UART_VIRT
default 0xfe018000 if DEBUG_MMP_UART3
default 0xfe100000 if DEBUG_IMX23_UART || DEBUG_IMX28_UART
default 0xfe230000 if DEBUG_PICOXCELL_UART
+ default 0xf1023000 if DEBUG_BCM_IPROC_UART3
default 0xfe300000 if DEBUG_BCM_KONA_UART
default 0xfe800000 if ARCH_IOP32X
default 0xfeb00000 if DEBUG_HI3620_UART || DEBUG_HIX5HD2_UART
@@ -1791,7 +1801,7 @@ config DEBUG_UART_8250_WORD
DEBUG_KEYSTONE_UART0 || DEBUG_KEYSTONE_UART1 || \
DEBUG_ALPINE_UART0 || \
DEBUG_DAVINCI_DMx_UART0 || DEBUG_DAVINCI_DA8XX_UART1 || \
- DEBUG_DAVINCI_DA8XX_UART2 || \
+ DEBUG_DAVINCI_DA8XX_UART2 || DEBUG_BCM_IPROC_UART3 || \
DEBUG_BCM_KONA_UART || DEBUG_RK32_UART2
config DEBUG_UART_8250_PALMCHIP
--
2.17.0
^ permalink raw reply related
* [PATCH] usb/gadget: aspeed-vhub: add USB_LIBCOMPOSITE dependency
From: Felipe Balbi @ 2018-05-30 12:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180525160729.92026-1-arnd@arndb.de>
Hi,
Arnd Bergmann <arnd@arndb.de> writes:
> Without that option, we run into a link failure:
>
> drivers/usb/gadget/udc/aspeed-vhub/hub.o: In function `ast_vhub_std_hub_request':
> hub.c:(.text+0x5b0): undefined reference to `usb_gadget_get_string'
>
> Fixes: 7ecca2a4080c ("usb/gadget: Add driver for Aspeed SoC virtual hub")
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Felipe Balbi <felipe.balbi@linux.intel.com>
--
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 832 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180530/7fc655b2/attachment.sig>
^ permalink raw reply
* [PATCH 07/15] arm: dts: exynos: Add missing cooling device properties for CPUs
From: Krzysztof Kozlowski @ 2018-05-30 12:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180530043806.ksen4xyh3x3x4fqn@vireshk-i7>
On Wed, May 30, 2018 at 6:38 AM, Viresh Kumar <viresh.kumar@linaro.org> wrote:
> On 29-05-18, 15:18, Krzysztof Kozlowski wrote:
>> Thanks for the patch.
>>
>> In case of Exynos, the booting CPU always has these information in DT
>> and the booting CPU cannot be changed (chosen by firmware/hardware
>> configuration).
>
> But can the booting CPU be offlined ?
>
> If yes, then this is how things are broken right now.
>
> Build cpufreq driver as module, boot kernel, hotplug out CPU0, insert
> cpufreq driver and that will try to find these properties in CPU1.
OK, I see the possibility although it is still far away from use
cases. You cannot hotplug booting CPU (CPU0) on Exynos kernels. It
never worked. Strictly speaking - offlining will work. But bringing it
online will likely hang the system.
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH 3/3] ARM: imx: remove i.MX6SLL support in i.MX6SL cpu idle driver
From: Fabio Estevam @ 2018-05-30 12:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527664358-17844-3-git-send-email-Anson.Huang@nxp.com>
Hi Anson,
On Wed, May 30, 2018 at 4:12 AM, Anson Huang <Anson.Huang@nxp.com> wrote:
> i.MX6SLL supports ARM power off in cpu idle, better to reuse
> i.MX6SX cpu idle driver instead of i.MX6SL which does NOT
> support ARM power off.
>
> Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
> ---
> arch/arm/mach-imx/cpuidle-imx6sl.c | 7 ++-----
> 1 file changed, 2 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/mach-imx/cpuidle-imx6sl.c b/arch/arm/mach-imx/cpuidle-imx6sl.c
> index fa8ead1..8d866fb 100644
> --- a/arch/arm/mach-imx/cpuidle-imx6sl.c
> +++ b/arch/arm/mach-imx/cpuidle-imx6sl.c
> @@ -12,7 +12,6 @@
>
> #include "common.h"
> #include "cpuidle.h"
> -#include "hardware.h"
The removal of this header file seems to be an unrelated change.
^ permalink raw reply
* [PATCH 07/12] dt-bindings: tc358754: add DT bindings
From: Laurent Pinchart @ 2018-05-30 12:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180530095915eucas1p27f09c8424d0c3c0619d134c5e7319fa3~zY7uP6Y6R1391213912eucas1p23@eucas1p2.samsung.com>
Hi Andrzej,
On Wednesday, 30 May 2018 12:59:12 EEST Andrzej Hajda wrote:
> On 28.05.2018 12:18, Laurent Pinchart wrote:
> > On Monday, 28 May 2018 12:47:11 EEST Maciej Purski wrote:
> >> The patch adds bindings to Toshiba DSI/LVDS bridge TC358764.
> >> Bindings describe power supplies, reset gpio and video interfaces.
> >>
> >> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> >> Signed-off-by: Maciej Purski <m.purski@samsung.com>
> >> ---
> >>
> >> .../bindings/display/bridge/toshiba,tc358764.txt | 42 ++++++++++++++++
> >> 1 file changed, 42 insertions(+)
> >> create mode 100644
> >>
> >> Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt
> >>
> >> diff --git
> >> a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt
> >> b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt
> >> new
> >> file mode 100644
> >> index 0000000..d09bdc2
> >> --- /dev/null
> >> +++
> >> b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt
> >> @@ -0,0 +1,42 @@
> >> +TC358764 MIPI-DSI to LVDS panel bridge
> >> +
> >> +Required properties:
> >> + - compatible: "toshiba,tc358764"
> >> + - reg: the virtual channel number of a DSI peripheral
> >> + - vddc-supply: core voltage supply
> >> + - vddio-supply: I/O voltage supply
> >> + - vddmipi-supply: MIPI voltage supply
> >> + - vddlvds133-supply: LVDS1 3.3V voltage supply
> >> + - vddlvds112-supply: LVDS1 1.2V voltage supply
> >
> > That's a lot of power supplies. Could some of them be merged together ?
> > See https://patchwork.freedesktop.org/patch/216058/ for an earlier
> > discussion on the same subject.
>
> Specs says about 3 supply voltage values:
> - 1.2V - digital core, DSI-RX PHY
> - 1.8-3.3V - digital I/O
> - 3.3V - LVDS-TX PHY
>
> So I guess it should be minimal number of supplies. Natural candidates:
>
> - vddc-supply: core voltage supply, 1.2V
> - vddio-supply: I/O voltage supply, 1.8V or 3.3V
> - vddlvds-supply: LVDS1/2 voltage supply, 3.3V
>
> I have changed name of the latest supply to be more consistent with
> other supplies, and changed 1.8-3.3 (which incorrectly suggest voltage
> range), to more precise voltage alternative.
This looks fine to me.
> >> + - reset-gpios: a GPIO spec for the reset pin
> >> +
> >> +The device node can contain zero to two 'port' child nodes, each with
> >> one
> >> +child
> >> +'endpoint' node, according to the bindings defined in [1].
> >> +The following are properties specific to those nodes.
> >> +
> >> +port:
> >> + - reg: (required) can be 0 for DSI port or 1 for LVDS port;
> >
> > This seems pretty vague to me. It could be read as meaning that ports are
> > completely optional, and that the port number you list can be used, but
> > that something else could be used to.
> >
> > Let's make the port nodes mandatory. I propose the following.
> >
> > Required nodes:
> >
> > The TC358764 has DSI and LVDS ports whose connections are described using
> > the OF graph bindings defined in
> > Documentation/devicetree/bindings/graph.txt. The device node must contain
> > one 'port' child node per DSI and LVDS port. The port nodes are numbered
> > as follows.
> >
> > Port Number
> > -------------------------------------------------------------------
> > DSI Input 0
> > LVDS Output 1
> >
> > Each port node must contain endpoint nodes describing the hardware
> > connections.
>
> Since the bridge is controlled via DSI bus, DSI input port is not necessary.
I don't agree with this. Regardless of how the bridge is controlled, I think
we should always use ports to describe the data connections. Otherwise it
would get more complicated for display controller drivers to use different
types of bridges.
> >> +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
> >> +
> >> +Example:
> >> +
> >> + bridge at 0 {
> >> + reg = <0>;
> >> + compatible = "toshiba,tc358764";
> >> + vddc-supply = <&vcc_1v2_reg>;
> >> + vddio-supply = <&vcc_1v8_reg>;
> >> + vddmipi-supply = <&vcc_1v2_reg>;
> >> + vddlvds133-supply = <&vcc_3v3_reg>;
> >> + vddlvds112-supply = <&vcc_1v2_reg>;
> >> + reset-gpios = <&gpd1 6 GPIO_ACTIVE_LOW>;
> >> + #address-cells = <1>;
> >> + #size-cells = <0>;
> >> + port at 1 {
> >> + reg = <1>;
> >> + lvds_ep: endpoint {
> >> + remote-endpoint = <&panel_ep>;
> >> + };
> >> + };
> >> + };
--
Regards,
Laurent Pinchart
^ permalink raw reply
* [PATCH v2 07/10] dt-bindings: tc358754: add DT bindings
From: Laurent Pinchart @ 2018-05-30 12:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527682561-1386-8-git-send-email-m.purski@samsung.com>
Hi Maciej,
On Wednesday, 30 May 2018 15:15:58 EEST Maciej Purski wrote:
> From: Andrzej Hajda <a.hajda@samsung.com>
>
> The patch adds bindings to Toshiba DSI/LVDS bridge TC358764.
> Bindings describe power supplies, reset gpio and video interfaces.
>
> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> Signed-off-by: Maciej Purski <m.purski@samsung.com>
> ---
> .../bindings/display/bridge/toshiba,tc358764.txt | 37 +++++++++++++++++++
> 1 file changed, 37 insertions(+)
> create mode 100644
> Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt
>
> diff --git
> a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt
> b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt new
> file mode 100644
> index 0000000..6eda14f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358764.txt
> @@ -0,0 +1,37 @@
> +TC358764 MIPI-DSI to LVDS panel bridge
> +
> +Required properties:
> + - compatible: "toshiba,tc358764"
> + - reg: the virtual channel number of a DSI peripheral
> + - vddc-supply: core voltage supply, 1.2V
> + - vddio-supply: I/O voltage supply, 1.8V or 3.3V
> + - vddlvds-supply: LVDS1/2 voltage supply, 3.3V
> + - reset-gpios: a GPIO spec for the reset pin
> +
> +The device node can contain zero to two 'port' child nodes, each with one
> +child 'endpoint' node, according to the bindings defined in [1].
> +The following are properties specific to those nodes.
> +
> +port:
> + - reg: (required) can be 0 for DSI port or 1 for LVDS port;
> +
> +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
Could you please take the comments I made on v1 into account when you'll post
v3 ?
> +Example:
> +
> + bridge at 0 {
> + reg = <0>;
> + compatible = "toshiba,tc358764";
> + vddc-supply = <&vcc_1v2_reg>;
> + vddio-supply = <&vcc_1v8_reg>;
> + vddlvds-supply = <&vcc_3v3_reg>;
> + reset-gpios = <&gpd1 6 GPIO_ACTIVE_LOW>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + port at 1 {
> + reg = <1>;
> + lvds_ep: endpoint {
> + remote-endpoint = <&panel_ep>;
> + };
> + };
> + };
--
Regards,
Laurent Pinchart
^ permalink raw reply
* [PATCH] ARM: debug: Add Iproc UART3 debug addresses
From: Baruch Siach @ 2018-05-30 12:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180530122922.1041-1-peron.clem@gmail.com>
Hi Cl?ment,
On Wed, May 30, 2018 at 02:29:22PM +0200, Cl?ment P?ron wrote:
> From: Cl?ment Peron <clement.peron@devialet.com>
>
> Broadcom Iproc SoCs typically use the UART3 for
> debug/console, provide a known good location for that.
>
> Signed-off-by: Cl?ment Peron <clement.peron@devialet.com>
> ---
> arch/arm/Kconfig.debug | 12 +++++++++++-
> 1 file changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
> index 199ebc1c4538..fa6fa1dae94d 100644
> --- a/arch/arm/Kconfig.debug
> +++ b/arch/arm/Kconfig.debug
> @@ -207,6 +207,14 @@ choice
> depends on ARCH_BCM_HR2
> select DEBUG_UART_8250
>
> + config DEBUG_BCM_IPROC_UART3
> + bool "Kernel low-level debugging on BCM IPROC UART3"
> + depends on ARCH_BCM_CYGNUS
> + select DEBUG_UART_8250
> + help
> + Say Y here if you want the debug print routines to direct
> + their output to the third serial port on these devices.
> +
> config DEBUG_BCM_KONA_UART
> bool "Kernel low-level debugging messages via BCM KONA UART"
> depends on ARCH_BCM_MOBILE
> @@ -1564,6 +1572,7 @@ config DEBUG_UART_PHYS
> default 0x20068000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3
> default 0x20201000 if DEBUG_BCM2835
> default 0x3f201000 if DEBUG_BCM2836
> + default 0x18023000 if DEBUG_BCM_IPROC_UART3
Entries are sorted by the address value. Except that DEBUG_BCM_KONA_UART
should be listed above DEBUG_BCM2836.
> default 0x3e000000 if DEBUG_BCM_KONA_UART
> default 0x4000e400 if DEBUG_LL_UART_EFM32
> default 0x40028000 if DEBUG_AT91_SAMV7_USART1
> @@ -1730,6 +1739,7 @@ config DEBUG_UART_VIRT
> default 0xfe018000 if DEBUG_MMP_UART3
> default 0xfe100000 if DEBUG_IMX23_UART || DEBUG_IMX28_UART
> default 0xfe230000 if DEBUG_PICOXCELL_UART
> + default 0xf1023000 if DEBUG_BCM_IPROC_UART3
Same here.
> default 0xfe300000 if DEBUG_BCM_KONA_UART
> default 0xfe800000 if ARCH_IOP32X
> default 0xfeb00000 if DEBUG_HI3620_UART || DEBUG_HIX5HD2_UART
> @@ -1791,7 +1801,7 @@ config DEBUG_UART_8250_WORD
> DEBUG_KEYSTONE_UART0 || DEBUG_KEYSTONE_UART1 || \
> DEBUG_ALPINE_UART0 || \
> DEBUG_DAVINCI_DMx_UART0 || DEBUG_DAVINCI_DA8XX_UART1 || \
> - DEBUG_DAVINCI_DA8XX_UART2 || \
> + DEBUG_DAVINCI_DA8XX_UART2 || DEBUG_BCM_IPROC_UART3 || \
> DEBUG_BCM_KONA_UART || DEBUG_RK32_UART2
baruch
--
http://baruch.siach.name/blog/ ~. .~ Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
- baruch at tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -
^ permalink raw reply
* [PATCH v2 0/6] KVM/arm64: Cache maintenance relaxations
From: Marc Zyngier @ 2018-05-30 12:47 UTC (permalink / raw)
To: linux-arm-kernel
This small series makes use of features recently introduced in the
ARMv8 architecture to relax the cache maintenance operations on CPUs
that implement these features.
FWB is the most important one. It allows stage-2 to enforce the
cacheability of memory, no matter what the guest says. It also
mandates that the whole machine is cache coherent (no non-coherent
I/O), meaning we can drop a whole class of cache maintenance
operations.
FWB, when combined with CTL_EL0.{IDC,DIC} allows the removal of all
cache maintenance and tracking of pages being executed.
We also take the opportunity to drop a few useless CMOs that were
applied to the HYP page tables, but that were never necessary. This
ended up requiring quite a few changes in out page table accessors so
that they get consistent barriers. These barriers are a bit on the
heavy side, and could be further optimized, although that's probably
for a different patch series
* From v1:
- Reordered the series in a slightly more consistent order
- Added patches refactoring the PT accessors before dropping
the CMOs
- Removed final dsb(ishst) from the last patch, as all PT accessors
now have their own barriers
- Collected Acks from Catalin
Marc Zyngier (6):
arm64: KVM: Add support for Stage-2 control of memory types and
cacheability
arm64: KVM: Handle Set/Way CMOs as NOPs if FWB is present
arm64: KVM: Avoid marking pages as XN in Stage-2 if CTR_EL0.DIC is set
KVM: arm/arm64: Consolidate page-table accessors
KVM: arm/arm64: Stop using {pmd,pud,pgd}_populate
KVM: arm/arm64: Remove unnecessary CMOs when creating HYP page tables
arch/arm/include/asm/kvm_mmu.h | 14 ++-------
arch/arm64/include/asm/cpucaps.h | 3 +-
arch/arm64/include/asm/kvm_arm.h | 1 +
arch/arm64/include/asm/kvm_emulate.h | 2 ++
arch/arm64/include/asm/kvm_mmu.h | 32 +++++++++++++------
arch/arm64/include/asm/memory.h | 7 +++++
arch/arm64/include/asm/pgtable-prot.h | 24 ++++++++++++--
arch/arm64/include/asm/sysreg.h | 1 +
arch/arm64/kernel/cpufeature.c | 20 ++++++++++++
arch/arm64/kvm/sys_regs.c | 8 ++++-
virt/kvm/arm/mmu.c | 45 ++++++++++++++++++++++-----
11 files changed, 125 insertions(+), 32 deletions(-)
--
2.17.1
^ permalink raw reply
* [PATCH v2 1/6] arm64: KVM: Add support for Stage-2 control of memory types and cacheability
From: Marc Zyngier @ 2018-05-30 12:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180530124706.25284-1-marc.zyngier@arm.com>
Up to ARMv8.3, the combinaison of Stage-1 and Stage-2 attributes
results in the strongest attribute of the two stages. This means
that the hypervisor has to perform quite a lot of cache maintenance
just in case the guest has some non-cacheable mappings around.
ARMv8.4 solves this problem by offering a different mode (FWB) where
Stage-2 has total control over the memory attribute (this is limited
to systems where both I/O and instruction caches are coherent with
the dcache). This is achieved by having a different set of memory
attributes in the page tables, and a new bit set in HCR_EL2.
On such a system, we can then safely sidestep any form of dcache
management.
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm64/include/asm/cpucaps.h | 3 ++-
arch/arm64/include/asm/kvm_arm.h | 1 +
arch/arm64/include/asm/kvm_emulate.h | 2 ++
arch/arm64/include/asm/kvm_mmu.h | 24 +++++++++++++++++-------
arch/arm64/include/asm/memory.h | 7 +++++++
arch/arm64/include/asm/pgtable-prot.h | 14 ++++++++++++--
arch/arm64/include/asm/sysreg.h | 1 +
arch/arm64/kernel/cpufeature.c | 20 ++++++++++++++++++++
virt/kvm/arm/mmu.c | 4 ++++
9 files changed, 66 insertions(+), 10 deletions(-)
diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index bc51b72fafd4..90e06a49f3e1 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -48,7 +48,8 @@
#define ARM64_HAS_CACHE_IDC 27
#define ARM64_HAS_CACHE_DIC 28
#define ARM64_HW_DBM 29
+#define ARM64_HAS_STAGE2_FWB 30
-#define ARM64_NCAPS 30
+#define ARM64_NCAPS 31
#endif /* __ASM_CPUCAPS_H */
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 6dd285e979c9..aa45df752a16 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -23,6 +23,7 @@
#include <asm/types.h>
/* Hyp Configuration Register (HCR) bits */
+#define HCR_FWB (UL(1) << 46)
#define HCR_TEA (UL(1) << 37)
#define HCR_TERR (UL(1) << 36)
#define HCR_TLOR (UL(1) << 35)
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 1dab3a984608..dd98fdf33d99 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -63,6 +63,8 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu)
/* trap error record accesses */
vcpu->arch.hcr_el2 |= HCR_TERR;
}
+ if (cpus_have_const_cap(ARM64_HAS_STAGE2_FWB))
+ vcpu->arch.hcr_el2 |= HCR_FWB;
if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features))
vcpu->arch.hcr_el2 &= ~HCR_RW;
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 082110993647..9dbca5355029 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -258,6 +258,7 @@ static inline bool kvm_page_empty(void *ptr)
struct kvm;
#define kvm_flush_dcache_to_poc(a,l) __flush_dcache_area((a), (l))
+#define kvm_flush_dcache_to_pou(a,l) __clean_dcache_area_pou((a), (l))
static inline bool vcpu_has_cache_enabled(struct kvm_vcpu *vcpu)
{
@@ -268,7 +269,10 @@ static inline void __clean_dcache_guest_page(kvm_pfn_t pfn, unsigned long size)
{
void *va = page_address(pfn_to_page(pfn));
- kvm_flush_dcache_to_poc(va, size);
+ if (!cpus_have_const_cap(ARM64_HAS_STAGE2_FWB))
+ kvm_flush_dcache_to_poc(va, size);
+ else
+ kvm_flush_dcache_to_pou(va, size);
}
static inline void __invalidate_icache_guest_page(kvm_pfn_t pfn,
@@ -288,20 +292,26 @@ static inline void __invalidate_icache_guest_page(kvm_pfn_t pfn,
static inline void __kvm_flush_dcache_pte(pte_t pte)
{
- struct page *page = pte_page(pte);
- kvm_flush_dcache_to_poc(page_address(page), PAGE_SIZE);
+ if (!cpus_have_const_cap(ARM64_HAS_STAGE2_FWB)) {
+ struct page *page = pte_page(pte);
+ kvm_flush_dcache_to_poc(page_address(page), PAGE_SIZE);
+ }
}
static inline void __kvm_flush_dcache_pmd(pmd_t pmd)
{
- struct page *page = pmd_page(pmd);
- kvm_flush_dcache_to_poc(page_address(page), PMD_SIZE);
+ if (!cpus_have_const_cap(ARM64_HAS_STAGE2_FWB)) {
+ struct page *page = pmd_page(pmd);
+ kvm_flush_dcache_to_poc(page_address(page), PMD_SIZE);
+ }
}
static inline void __kvm_flush_dcache_pud(pud_t pud)
{
- struct page *page = pud_page(pud);
- kvm_flush_dcache_to_poc(page_address(page), PUD_SIZE);
+ if (!cpus_have_const_cap(ARM64_HAS_STAGE2_FWB)) {
+ struct page *page = pud_page(pud);
+ kvm_flush_dcache_to_poc(page_address(page), PUD_SIZE);
+ }
}
#define kvm_virt_to_phys(x) __pa_symbol(x)
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 49d99214f43c..b96442960aea 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -155,6 +155,13 @@
#define MT_S2_NORMAL 0xf
#define MT_S2_DEVICE_nGnRE 0x1
+/*
+ * Memory types for Stage-2 translation when ID_AA64MMFR2_EL1.FWB is 0001
+ * Stage-2 enforces Normal-WB and Device-nGnRE
+ */
+#define MT_S2_FWB_NORMAL 6
+#define MT_S2_FWB_DEVICE_nGnRE 1
+
#ifdef CONFIG_ARM64_4K_PAGES
#define IOREMAP_MAX_ORDER (PUD_SHIFT)
#else
diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
index 108ecad7acc5..c66c3047400e 100644
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -67,8 +67,18 @@
#define PAGE_HYP_RO __pgprot(_HYP_PAGE_DEFAULT | PTE_HYP | PTE_RDONLY | PTE_HYP_XN)
#define PAGE_HYP_DEVICE __pgprot(PROT_DEVICE_nGnRE | PTE_HYP)
-#define PAGE_S2 __pgprot(_PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY | PTE_S2_XN)
-#define PAGE_S2_DEVICE __pgprot(_PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDONLY | PTE_S2_XN)
+#define PAGE_S2_MEMATTR(attr) \
+ ({ \
+ u64 __val; \
+ if (cpus_have_const_cap(ARM64_HAS_STAGE2_FWB)) \
+ __val = PTE_S2_MEMATTR(MT_S2_FWB_ ## attr); \
+ else \
+ __val = PTE_S2_MEMATTR(MT_S2_ ## attr); \
+ __val; \
+ })
+
+#define PAGE_S2 __pgprot(_PROT_DEFAULT | PAGE_S2_MEMATTR(NORMAL) | PTE_S2_RDONLY | PTE_S2_XN)
+#define PAGE_S2_DEVICE __pgprot(_PROT_DEFAULT | PAGE_S2_MEMATTR(DEVICE_nGnRE) | PTE_S2_RDONLY | PTE_S2_XN)
#define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN)
#define PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 6171178075dc..385fb8c28981 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -576,6 +576,7 @@
#define ID_AA64MMFR1_VMIDBITS_16 2
/* id_aa64mmfr2 */
+#define ID_AA64MMFR2_FWB_SHIFT 40
#define ID_AA64MMFR2_AT_SHIFT 32
#define ID_AA64MMFR2_LVA_SHIFT 16
#define ID_AA64MMFR2_IESB_SHIFT 12
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 9d1b06d67c53..50185607026b 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -192,6 +192,7 @@ static const struct arm64_ftr_bits ftr_id_aa64mmfr1[] = {
};
static const struct arm64_ftr_bits ftr_id_aa64mmfr2[] = {
+ ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_FWB_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_AT_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_LVA_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_IESB_SHIFT, 4, 0),
@@ -1026,6 +1027,14 @@ static void cpu_copy_el2regs(const struct arm64_cpu_capabilities *__unused)
}
#endif
+static void cpu_has_fwb(const struct arm64_cpu_capabilities *__unused)
+{
+ u64 val = read_sysreg_s(SYS_CLIDR_EL1);
+
+ /* Check that CLIDR_EL1.LOU{U,IS} are both 0 */
+ WARN_ON(val & (7 << 27 | 7 << 21));
+}
+
static const struct arm64_cpu_capabilities arm64_features[] = {
{
.desc = "GIC system register CPU interface",
@@ -1182,6 +1191,17 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
.matches = has_cache_dic,
},
+ {
+ .desc = "Stage-2 Force Write-Back",
+ .type = ARM64_CPUCAP_SYSTEM_FEATURE,
+ .capability = ARM64_HAS_STAGE2_FWB,
+ .sys_reg = SYS_ID_AA64MMFR2_EL1,
+ .sign = FTR_UNSIGNED,
+ .field_pos = ID_AA64MMFR2_FWB_SHIFT,
+ .min_field_value = 1,
+ .matches = has_cpuid_feature,
+ .cpu_enable = cpu_has_fwb,
+ },
#ifdef CONFIG_ARM64_HW_AFDBM
{
/*
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
index 7f6a944db23d..ba66bf7ae299 100644
--- a/virt/kvm/arm/mmu.c
+++ b/virt/kvm/arm/mmu.c
@@ -196,6 +196,10 @@ static void clear_stage2_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr
* This is why right after unmapping a page/section and invalidating
* the corresponding TLBs, we call kvm_flush_dcache_p*() to make sure
* the IO subsystem will never hit in the cache.
+ *
+ * This is all avoided on systems that have ARM64_HAS_STAGE2_FWB, as
+ * we then fully enforce cacheability of RAM, no matter what the guest
+ * does.
*/
static void unmap_stage2_ptes(struct kvm *kvm, pmd_t *pmd,
phys_addr_t addr, phys_addr_t end)
--
2.17.1
^ permalink raw reply related
* [PATCH v2 2/6] arm64: KVM: Handle Set/Way CMOs as NOPs if FWB is present
From: Marc Zyngier @ 2018-05-30 12:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180530124706.25284-1-marc.zyngier@arm.com>
Set/Way handling is one of the ugliest corners of KVM. We shouldn't
have to handle that, but better safe than sorry.
Thankfully, FWB fixes this for us by not requiering any maintenance
whatsoever, which means we don't have to emulate S/W CMOs, and don't
have to track VM ops either.
We still have to trap S/W though, if only to prevent the guest from
doing something bad.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm64/kvm/sys_regs.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 6e3b969391fd..9a740f159245 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -195,7 +195,13 @@ static bool access_dcsw(struct kvm_vcpu *vcpu,
if (!p->is_write)
return read_from_write_only(vcpu, p, r);
- kvm_set_way_flush(vcpu);
+ /*
+ * Only track S/W ops if we don't have FWB. It still indicates
+ * that the guest is a bit broken...
+ */
+ if (!cpus_have_const_cap(ARM64_HAS_STAGE2_FWB))
+ kvm_set_way_flush(vcpu);
+
return true;
}
--
2.17.1
^ permalink raw reply related
* [PATCH v2 3/6] arm64: KVM: Avoid marking pages as XN in Stage-2 if CTR_EL0.DIC is set
From: Marc Zyngier @ 2018-05-30 12:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180530124706.25284-1-marc.zyngier@arm.com>
On systems where CTR_EL0.DIC is set, we don't need to perform
icache invalidation to guarantee that we'll fetch the right
instruction stream.
This also means that taking a permission fault to invalidate the
icache is an unnecessary overhead.
On such systems, we can safely leave the page as being executable.
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm64/include/asm/pgtable-prot.h | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
index c66c3047400e..78b942c1bea4 100644
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -77,8 +77,18 @@
__val; \
})
-#define PAGE_S2 __pgprot(_PROT_DEFAULT | PAGE_S2_MEMATTR(NORMAL) | PTE_S2_RDONLY | PTE_S2_XN)
-#define PAGE_S2_DEVICE __pgprot(_PROT_DEFAULT | PAGE_S2_MEMATTR(DEVICE_nGnRE) | PTE_S2_RDONLY | PTE_S2_XN)
+#define PAGE_S2_XN \
+ ({ \
+ u64 __val; \
+ if (cpus_have_const_cap(ARM64_HAS_CACHE_DIC)) \
+ __val = 0; \
+ else \
+ __val = PTE_S2_XN; \
+ __val; \
+ })
+
+#define PAGE_S2 __pgprot(_PROT_DEFAULT | PAGE_S2_MEMATTR(NORMAL) | PTE_S2_RDONLY | PAGE_S2_XN)
+#define PAGE_S2_DEVICE __pgprot(_PROT_DEFAULT | PAGE_S2_MEMATTR(DEVICE_nGnRE) | PTE_S2_RDONLY | PAGE_S2_XN)
#define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN)
#define PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
--
2.17.1
^ permalink raw reply related
* [PATCH v2 4/6] KVM: arm/arm64: Consolidate page-table accessors
From: Marc Zyngier @ 2018-05-30 12:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180530124706.25284-1-marc.zyngier@arm.com>
The arm and arm64 KVM page tables accessors are pointlessly different
between the two architectures, and likely both wrong one way or another:
arm64 lacks a dsb(), and arm doesn't use WRITE_ONCE.
Let's unify them.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/include/asm/kvm_mmu.h | 12 -----------
arch/arm64/include/asm/kvm_mmu.h | 3 ---
virt/kvm/arm/mmu.c | 35 ++++++++++++++++++++++++++++----
3 files changed, 31 insertions(+), 19 deletions(-)
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index 707a1f06dc5d..468ff945efa0 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -75,18 +75,6 @@ phys_addr_t kvm_get_idmap_vector(void);
int kvm_mmu_init(void);
void kvm_clear_hyp_idmap(void);
-static inline void kvm_set_pmd(pmd_t *pmd, pmd_t new_pmd)
-{
- *pmd = new_pmd;
- dsb(ishst);
-}
-
-static inline void kvm_set_pte(pte_t *pte, pte_t new_pte)
-{
- *pte = new_pte;
- dsb(ishst);
-}
-
static inline pte_t kvm_s2pte_mkwrite(pte_t pte)
{
pte_val(pte) |= L_PTE_S2_RDWR;
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 9dbca5355029..26c89b63f604 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -170,9 +170,6 @@ phys_addr_t kvm_get_idmap_vector(void);
int kvm_mmu_init(void);
void kvm_clear_hyp_idmap(void);
-#define kvm_set_pte(ptep, pte) set_pte(ptep, pte)
-#define kvm_set_pmd(pmdp, pmd) set_pmd(pmdp, pmd)
-
static inline pte_t kvm_s2pte_mkwrite(pte_t pte)
{
pte_val(pte) |= PTE_S2_RDWR;
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
index ba66bf7ae299..c9ed239c0840 100644
--- a/virt/kvm/arm/mmu.c
+++ b/virt/kvm/arm/mmu.c
@@ -177,6 +177,33 @@ static void clear_stage2_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr
put_page(virt_to_page(pmd));
}
+static inline void kvm_set_pte(pte_t *ptep, pte_t new_pte)
+{
+ WRITE_ONCE(*ptep, new_pte);
+ dsb(ishst);
+}
+
+static inline void kvm_set_pmd(pmd_t *pmdp, pmd_t new_pmd)
+{
+ WRITE_ONCE(*pmdp, new_pmd);
+ dsb(ishst);
+}
+
+static inline void kvm_pmd_populate(pmd_t *pmdp, pte_t *ptep)
+{
+ pmd_populate_kernel(NULL, pmdp, ptep);
+}
+
+static inline void kvm_pud_populate(pud_t *pudp, pmd_t *pmdp)
+{
+ pud_populate(NULL, pudp, pmdp);
+}
+
+static inline void kvm_pgd_populate(pgd_t *pgdp, pud_t *pudp)
+{
+ pgd_populate(NULL, pgdp, pudp);
+}
+
/*
* Unmapping vs dcache management:
*
@@ -603,7 +630,7 @@ static int create_hyp_pmd_mappings(pud_t *pud, unsigned long start,
kvm_err("Cannot allocate Hyp pte\n");
return -ENOMEM;
}
- pmd_populate_kernel(NULL, pmd, pte);
+ kvm_pmd_populate(pmd, pte);
get_page(virt_to_page(pmd));
kvm_flush_dcache_to_poc(pmd, sizeof(*pmd));
}
@@ -636,7 +663,7 @@ static int create_hyp_pud_mappings(pgd_t *pgd, unsigned long start,
kvm_err("Cannot allocate Hyp pmd\n");
return -ENOMEM;
}
- pud_populate(NULL, pud, pmd);
+ kvm_pud_populate(pud, pmd);
get_page(virt_to_page(pud));
kvm_flush_dcache_to_poc(pud, sizeof(*pud));
}
@@ -673,7 +700,7 @@ static int __create_hyp_mappings(pgd_t *pgdp, unsigned long ptrs_per_pgd,
err = -ENOMEM;
goto out;
}
- pgd_populate(NULL, pgd, pud);
+ kvm_pgd_populate(pgd, pud);
get_page(virt_to_page(pgd));
kvm_flush_dcache_to_poc(pgd, sizeof(*pgd));
}
@@ -1092,7 +1119,7 @@ static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
if (!cache)
return 0; /* ignore calls from kvm_set_spte_hva */
pte = mmu_memory_cache_alloc(cache);
- pmd_populate_kernel(NULL, pmd, pte);
+ kvm_pmd_populate(pmd, pte);
get_page(virt_to_page(pmd));
}
--
2.17.1
^ permalink raw reply related
* [PATCH v2 5/6] KVM: arm/arm64: Stop using {pmd,pud,pgd}_populate
From: Marc Zyngier @ 2018-05-30 12:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180530124706.25284-1-marc.zyngier@arm.com>
The {pmd,pud,pgd}_populate accessors usage in the kernel have always
been a bit weird in KVM. We don't have a struct mm to pass (and
neither does the kernel most of the time, but still...), and
the 32bit code has all kind of cache maintenance that doesn't make
sense on ARMv7+ when MP extensions are mandatory (which is the
case when the VEs are present).
Let's bite the bullet and provide our own implementations. The
only bit of architectural code left has to do with building the table
entry itself (arm64 having up to 52bit PA, arm lacking PUD level).
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/include/asm/kvm_mmu.h | 4 ++++
arch/arm64/include/asm/kvm_mmu.h | 7 +++++++
virt/kvm/arm/mmu.c | 8 +++++---
3 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index 468ff945efa0..a94ef9833bd3 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -75,6 +75,10 @@ phys_addr_t kvm_get_idmap_vector(void);
int kvm_mmu_init(void);
void kvm_clear_hyp_idmap(void);
+#define kvm_mk_pmd(ptep) __pmd(__pa(ptep) | PMD_TYPE_TABLE)
+#define kvm_mk_pud(pmdp) __pud(__pa(pmdp) | PMD_TYPE_TABLE)
+#define kvm_mk_pgd(pudp) ({ BUILD_BUG(); 0; })
+
static inline pte_t kvm_s2pte_mkwrite(pte_t pte)
{
pte_val(pte) |= L_PTE_S2_RDWR;
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 26c89b63f604..22c9f7cfdf93 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -170,6 +170,13 @@ phys_addr_t kvm_get_idmap_vector(void);
int kvm_mmu_init(void);
void kvm_clear_hyp_idmap(void);
+#define kvm_mk_pmd(ptep) \
+ __pmd(__phys_to_pmd_val(__pa(ptep) | PMD_TYPE_TABLE))
+#define kvm_mk_pud(pmdp) \
+ __pud(__phys_to_pud_val(__pa(pmdp) | PMD_TYPE_TABLE))
+#define kvm_mk_pgd(pudp) \
+ __pgd(__phys_to_pgd_val(__pa(pudp) | PUD_TYPE_TABLE))
+
static inline pte_t kvm_s2pte_mkwrite(pte_t pte)
{
pte_val(pte) |= PTE_S2_RDWR;
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
index c9ed239c0840..ad1980d2118a 100644
--- a/virt/kvm/arm/mmu.c
+++ b/virt/kvm/arm/mmu.c
@@ -191,17 +191,19 @@ static inline void kvm_set_pmd(pmd_t *pmdp, pmd_t new_pmd)
static inline void kvm_pmd_populate(pmd_t *pmdp, pte_t *ptep)
{
- pmd_populate_kernel(NULL, pmdp, ptep);
+ kvm_set_pmd(pmdp, kvm_mk_pmd(ptep));
}
static inline void kvm_pud_populate(pud_t *pudp, pmd_t *pmdp)
{
- pud_populate(NULL, pudp, pmdp);
+ WRITE_ONCE(*pudp, kvm_mk_pud(pmdp));
+ dsb(ishst);
}
static inline void kvm_pgd_populate(pgd_t *pgdp, pud_t *pudp)
{
- pgd_populate(NULL, pgdp, pudp);
+ WRITE_ONCE(*pgdp, kvm_mk_pgd(pudp));
+ dsb(ishst);
}
/*
--
2.17.1
^ permalink raw reply related
* [PATCH v2 6/6] KVM: arm/arm64: Remove unnecessary CMOs when creating HYP page tables
From: Marc Zyngier @ 2018-05-30 12:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180530124706.25284-1-marc.zyngier@arm.com>
There is no need to perform cache maintenance operations when
creating the HYP page tables if we have the multiprocessing
extensions. ARMv7 mandates them with the virtualization support,
and ARMv8 just mandates them unconditionally.
Let's remove these operations.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
virt/kvm/arm/mmu.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
index ad1980d2118a..ccdf544d44c0 100644
--- a/virt/kvm/arm/mmu.c
+++ b/virt/kvm/arm/mmu.c
@@ -607,7 +607,6 @@ static void create_hyp_pte_mappings(pmd_t *pmd, unsigned long start,
pte = pte_offset_kernel(pmd, addr);
kvm_set_pte(pte, pfn_pte(pfn, prot));
get_page(virt_to_page(pte));
- kvm_flush_dcache_to_poc(pte, sizeof(*pte));
pfn++;
} while (addr += PAGE_SIZE, addr != end);
}
@@ -634,7 +633,6 @@ static int create_hyp_pmd_mappings(pud_t *pud, unsigned long start,
}
kvm_pmd_populate(pmd, pte);
get_page(virt_to_page(pmd));
- kvm_flush_dcache_to_poc(pmd, sizeof(*pmd));
}
next = pmd_addr_end(addr, end);
@@ -667,7 +665,6 @@ static int create_hyp_pud_mappings(pgd_t *pgd, unsigned long start,
}
kvm_pud_populate(pud, pmd);
get_page(virt_to_page(pud));
- kvm_flush_dcache_to_poc(pud, sizeof(*pud));
}
next = pud_addr_end(addr, end);
@@ -704,7 +701,6 @@ static int __create_hyp_mappings(pgd_t *pgdp, unsigned long ptrs_per_pgd,
}
kvm_pgd_populate(pgd, pud);
get_page(virt_to_page(pgd));
- kvm_flush_dcache_to_poc(pgd, sizeof(*pgd));
}
next = pgd_addr_end(addr, end);
--
2.17.1
^ permalink raw reply related
* [PATCH V2] soc: imx: gpcv2: correct PGC offset
From: Fabio Estevam @ 2018-05-30 12:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527643842-17643-1-git-send-email-Anson.Huang@nxp.com>
Hi Anson,
On Tue, May 29, 2018 at 10:30 PM, Anson Huang <Anson.Huang@nxp.com> wrote:
> Correct MIPI/PCIe/USB_HSIC's PGC offset based on
> design RTL, the values in the Reference Manual
> (Rev. 1, 01/2018 and the older ones) are incorrect.
>
> The correct offset values should be as below:
>
> 0x800 ~ 0x83F: PGC for core0 of A7 platform;
> 0x840 ~ 0x87F: PGC for core1 of A7 platform;
> 0x880 ~ 0x8BF: PGC for SCU of A7 platform;
> 0xA00 ~ 0xA3F: PGC for fastmix/megamix;
> 0xC00 ~ 0xC3F: PGC for MIPI PHY;
> 0xC40 ~ 0xC7F: PGC for PCIe_PHY;
> 0xC80 ~ 0xCBF: PGC for USB OTG1 PHY;
> 0xCC0 ~ 0xCFF: PGC for USB OTG2 PHY;
> 0xD00 ~ 0xD3F: PGC for USB HSIC PHY;
>
> Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
> Acked-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Thanks for the fix:
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
^ permalink raw reply
* [PATCH v3 1/2] ARM: dma-mapping: Implement arm_dma_iommu_detach_device()
From: Thierry Reding @ 2018-05-30 12:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <eee02391-aa25-da84-f98a-b5fed6c69599@arm.com>
On Wed, May 30, 2018 at 10:59:30AM +0100, Robin Murphy wrote:
> On 30/05/18 09:03, Thierry Reding wrote:
> > From: Thierry Reding <treding@nvidia.com>
> >
> > Implement this function to enable drivers from detaching from any IOMMU
> > domains that architecture code might have attached them to so that they
> > can take exclusive control of the IOMMU via the IOMMU API.
> >
> > Signed-off-by: Thierry Reding <treding@nvidia.com>
> > ---
> > Changes in v3:
> > - make API 32-bit ARM specific
> > - avoid extra local variable
> >
> > Changes in v2:
> > - fix compilation
> >
> > arch/arm/include/asm/dma-mapping.h | 3 +++
> > arch/arm/mm/dma-mapping-nommu.c | 4 ++++
> > arch/arm/mm/dma-mapping.c | 16 ++++++++++++++++
> > 3 files changed, 23 insertions(+)
> >
> > diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
> > index 8436f6ade57d..5960e9f3a9d0 100644
> > --- a/arch/arm/include/asm/dma-mapping.h
> > +++ b/arch/arm/include/asm/dma-mapping.h
> > @@ -103,6 +103,9 @@ extern void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> > #define arch_teardown_dma_ops arch_teardown_dma_ops
> > extern void arch_teardown_dma_ops(struct device *dev);
> > +#define arm_dma_iommu_detach_device arm_dma_iommu_detach_device
> > +extern void arm_dma_iommu_detach_device(struct device *dev);
> > +
> > /* do not use this function in a driver */
> > static inline bool is_device_dma_coherent(struct device *dev)
> > {
> > diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c
> > index f448a0663b10..eb781369377b 100644
> > --- a/arch/arm/mm/dma-mapping-nommu.c
> > +++ b/arch/arm/mm/dma-mapping-nommu.c
> > @@ -241,3 +241,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> > void arch_teardown_dma_ops(struct device *dev)
> > {
> > }
> > +
> > +void arm_dma_iommu_detach_device(struct device *dev)
> > +{
> > +}
> > diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> > index af27f1c22d93..6d8af08b3e7d 100644
> > --- a/arch/arm/mm/dma-mapping.c
> > +++ b/arch/arm/mm/dma-mapping.c
> > @@ -2400,3 +2400,19 @@ void arch_teardown_dma_ops(struct device *dev)
> > arm_teardown_iommu_dma_ops(dev);
> > }
> > +
> > +void arm_dma_iommu_detach_device(struct device *dev)
> > +{
> > +#ifdef CONFIG_ARM_DMA_USE_IOMMU
> > + struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
> > +
> > + if (!mapping)
> > + return;
> > +
> > + arm_iommu_release_mapping(mapping);
>
> Potentially freeing the mapping before you try to operate on it is never the
> best idea. Plus arm_iommu_detach_device() already releases a reference
> appropriately anyway, so it's a double-free.
But the reference released by arm_iommu_detach_device() is to balance
out the reference acquired by arm_iommu_attach_device(), isn't it? In
the above, the arm_iommu_release_mapping() is supposed to drop the
final reference which was obtained by arm_iommu_create_mapping(). The
mapping shouldn't go away irrespective of the order in which these
will be called.
> > + arm_iommu_detach_device(dev);
> > +
> > + set_dma_ops(dev, arm_get_dma_map_ops(dev->archdata.dma_coherent));
> > +#endif
> > +}
> > +EXPORT_SYMBOL(arm_dma_iommu_detach_device);
>
> I really don't see why we need an extra function that essentially just
> duplicates arm_iommu_detach_device(). The only real difference here is that
> here you reset the DMA ops more appropriately, but I think the existing
> function should be fixed to do that anyway, since set_dma_ops(dev, NULL) now
> just behaves as an unconditional fallback to the noncoherent arm_dma_ops,
> which clearly isn't always right.
The idea behind making this an extra function is that we can call it
unconditionally and it will do the right things. Granted, that already
doesn't quite work as elegantly anymore as I had hoped since this is
now an ARM specific function, so we need an #ifdef guard anyway.
I don't care very strongly either way, so if you and Christoph can both
agree that we just want arm_iommu_detach_device() to call the proper
variant of set_dma_ops(), that's fine with me, too.
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180530/38fbec80/attachment-0001.sig>
^ permalink raw reply
* [PATCH] ARM: debug: Add Iproc UART3 debug addresses
From: Clément Péron @ 2018-05-30 12:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180530123809.khyzehg62ct6jzws@sapphire.tkos.co.il>
Hi Baruch,
On Wed, 30 May 2018 at 14:47, Baruch Siach <baruch@tkos.co.il> wrote:
> Hi Cl?ment,
> On Wed, May 30, 2018 at 02:29:22PM +0200, Cl?ment P?ron wrote:
> > From: Cl?ment Peron <clement.peron@devialet.com>
> >
> > Broadcom Iproc SoCs typically use the UART3 for
> > debug/console, provide a known good location for that.
> >
> > Signed-off-by: Cl?ment Peron <clement.peron@devialet.com>
> > ---
> > arch/arm/Kconfig.debug | 12 +++++++++++-
> > 1 file changed, 11 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
> > index 199ebc1c4538..fa6fa1dae94d 100644
> > --- a/arch/arm/Kconfig.debug
> > +++ b/arch/arm/Kconfig.debug
> > @@ -207,6 +207,14 @@ choice
> > depends on ARCH_BCM_HR2
> > select DEBUG_UART_8250
> >
> > + config DEBUG_BCM_IPROC_UART3
> > + bool "Kernel low-level debugging on BCM IPROC UART3"
> > + depends on ARCH_BCM_CYGNUS
> > + select DEBUG_UART_8250
> > + help
> > + Say Y here if you want the debug print routines to
direct
> > + their output to the third serial port on these devices.
> > +
> > config DEBUG_BCM_KONA_UART
> > bool "Kernel low-level debugging messages via BCM KONA
UART"
> > depends on ARCH_BCM_MOBILE
> > @@ -1564,6 +1572,7 @@ config DEBUG_UART_PHYS
> > default 0x20068000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3
> > default 0x20201000 if DEBUG_BCM2835
> > default 0x3f201000 if DEBUG_BCM2836
> > + default 0x18023000 if DEBUG_BCM_IPROC_UART3
> Entries are sorted by the address value. Except that DEBUG_BCM_KONA_UART
> should be listed above DEBUG_BCM2836.
Indeed, can I fix the DEBUG_BCM_KONA_UART entry in the same commit ?
> > default 0x3e000000 if DEBUG_BCM_KONA_UART
> > default 0x4000e400 if DEBUG_LL_UART_EFM32
> > default 0x40028000 if DEBUG_AT91_SAMV7_USART1
> > @@ -1730,6 +1739,7 @@ config DEBUG_UART_VIRT
> > default 0xfe018000 if DEBUG_MMP_UART3
> > default 0xfe100000 if DEBUG_IMX23_UART || DEBUG_IMX28_UART
> > default 0xfe230000 if DEBUG_PICOXCELL_UART
> > + default 0xf1023000 if DEBUG_BCM_IPROC_UART3
> Same here.
> > default 0xfe300000 if DEBUG_BCM_KONA_UART
> > default 0xfe800000 if ARCH_IOP32X
> > default 0xfeb00000 if DEBUG_HI3620_UART || DEBUG_HIX5HD2_UART
> > @@ -1791,7 +1801,7 @@ config DEBUG_UART_8250_WORD
> > DEBUG_KEYSTONE_UART0 || DEBUG_KEYSTONE_UART1 || \
> > DEBUG_ALPINE_UART0 || \
> > DEBUG_DAVINCI_DMx_UART0 || DEBUG_DAVINCI_DA8XX_UART1 || \
> > - DEBUG_DAVINCI_DA8XX_UART2 || \
> > + DEBUG_DAVINCI_DA8XX_UART2 || DEBUG_BCM_IPROC_UART3 || \
> > DEBUG_BCM_KONA_UART || DEBUG_RK32_UART2
> baruch
> --
> http://baruch.siach.name/blog/ ~. .~ Tk Open
Systems
=}------------------------------------------------ooO--U--Ooo------------{=
> - baruch at tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -
Clement
^ permalink raw reply
* [PATCH v3 2/2] drm/nouveau: tegra: Detach from ARM DMA/IOMMU mapping
From: Thierry Reding @ 2018-05-30 13:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <7960e4fc-f680-f8d1-0c5a-3ff1e13b3154@arm.com>
On Wed, May 30, 2018 at 11:30:25AM +0100, Robin Murphy wrote:
> On 30/05/18 09:03, Thierry Reding wrote:
> > From: Thierry Reding <treding@nvidia.com>
> >
> > Depending on the kernel configuration, early ARM architecture setup code
> > may have attached the GPU to a DMA/IOMMU mapping that transparently uses
> > the IOMMU to back the DMA API. Tegra requires special handling for IOMMU
> > backed buffers (a special bit in the GPU's MMU page tables indicates the
> > memory path to take: via the SMMU or directly to the memory controller).
> > Transparently backing DMA memory with an IOMMU prevents Nouveau from
> > properly handling such memory accesses and causes memory access faults.
> >
> > As a side-note: buffers other than those allocated in instance memory
> > don't need to be physically contiguous from the GPU's perspective since
> > the GPU can map them into contiguous buffers using its own MMU. Mapping
> > these buffers through the IOMMU is unnecessary and will even lead to
> > performance degradation because of the additional translation. One
> > exception to this are compressible buffers which need large pages. In
> > order to enable these large pages, multiple small pages will have to be
> > combined into one large (I/O virtually contiguous) mapping via the
> > IOMMU. However, that is a topic outside the scope of this fix and isn't
> > currently supported. An implementation will want to explicitly create
> > these large pages in the Nouveau driver, so detaching from a DMA/IOMMU
> > mapping would still be required.
>
> I wonder if it might make sense to have a hook in iommu_attach_device() to
> notify the arch DMA API code when moving devices between unmanaged and DMA
> ops domains? That seems like it might be the most low-impact way to address
> the overall problem long-term.
>
> > Signed-off-by: Thierry Reding <treding@nvidia.com>
> > ---
> > Changes in v3:
> > - clarify the use of IOMMU mapping for compressible buffers
> > - squash multiple patches into this
> >
> > drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c | 5 +++++
> > 1 file changed, 5 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
> > index 78597da6313a..d0538af1b967 100644
> > --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
> > +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
> > @@ -105,6 +105,11 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev)
> > unsigned long pgsize_bitmap;
> > int ret;
> > +#if IS_ENABLED(CONFIG_ARM)
>
> Wouldn't CONFIG_ARM_DMA_USE_IOMMU be even more appropriate?
Not necessarily. arm_dma_iommu_detach_device() is always defined on ARM,
only with CONFIG_ARM_DMA_USE_IOMMU=n it will be empty. So this check is
a guard to make sure we don't call the function when it isn't available,
but it may still not do anything.
>
> > + /* make sure we can use the IOMMU exclusively */
> > + arm_dma_iommu_detach_device(dev);
>
> As before, I would just use the existing infrastructure the same way the
> Exynos DRM driver currently does in __exynos_iommu_attach() (albeit without
> then reattaching to another DMA ops mapping).
That's pretty much what I initially did and which was shot down by
Christoph. As I said earlier, at this point I don't really care what
color the shed will be. Can you and Christoph come to an agreement
on what it should be?
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180530/b6e5bbcc/attachment.sig>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox