From: CK Hu ck.hu@mediatek.com
SOUT has many bits and need to be cleared before set new value. Write only could do the clear, but for MOUT, it clears bits that should not be cleared. So use a mask to reset only the needed bits.
this fixes HDMI issues on MT7623/BPI-R2 since 5.13
Cc: stable@vger.kernel.org Fixes: 440147639ac7 ("soc: mediatek: mmsys: Use an array for setting the routing registers") Signed-off-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: CK Hu ck.hu@mediatek.com --- code is taken from here (upstreamed without mask part) https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/2... basicly CK Hu's code so i set him as author --- drivers/soc/mediatek/mtk-mmsys.c | 7 +- drivers/soc/mediatek/mtk-mmsys.h | 133 +++++++++++++++++++++---------- 2 files changed, 98 insertions(+), 42 deletions(-)
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c index 080660ef11bf..0f949896fd06 100644 --- a/drivers/soc/mediatek/mtk-mmsys.c +++ b/drivers/soc/mediatek/mtk-mmsys.c @@ -68,7 +68,9 @@ void mtk_mmsys_ddp_connect(struct device *dev,
for (i = 0; i < mmsys->data->num_routes; i++) if (cur == routes[i].from_comp && next == routes[i].to_comp) { - reg = readl_relaxed(mmsys->regs + routes[i].addr) | routes[i].val; + reg = readl_relaxed(mmsys->regs + routes[i].addr); + reg &= ~routes[i].mask; + reg |= routes[i].val; writel_relaxed(reg, mmsys->regs + routes[i].addr); } } @@ -85,7 +87,8 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
for (i = 0; i < mmsys->data->num_routes; i++) if (cur == routes[i].from_comp && next == routes[i].to_comp) { - reg = readl_relaxed(mmsys->regs + routes[i].addr) & ~routes[i].val; + reg = readl_relaxed(mmsys->regs + routes[i].addr); + reg &= ~routes[i].mask; writel_relaxed(reg, mmsys->regs + routes[i].addr); } } diff --git a/drivers/soc/mediatek/mtk-mmsys.h b/drivers/soc/mediatek/mtk-mmsys.h index a760a34e6eca..5f3e2bf0c40b 100644 --- a/drivers/soc/mediatek/mtk-mmsys.h +++ b/drivers/soc/mediatek/mtk-mmsys.h @@ -35,41 +35,54 @@ #define RDMA0_SOUT_DSI1 0x1 #define RDMA0_SOUT_DSI2 0x4 #define RDMA0_SOUT_DSI3 0x5 +#define RDMA0_SOUT_MASK 0x7 #define RDMA1_SOUT_DPI0 0x2 #define RDMA1_SOUT_DPI1 0x3 #define RDMA1_SOUT_DSI1 0x1 #define RDMA1_SOUT_DSI2 0x4 #define RDMA1_SOUT_DSI3 0x5 +#define RDMA1_SOUT_MASK 0x7 #define RDMA2_SOUT_DPI0 0x2 #define RDMA2_SOUT_DPI1 0x3 #define RDMA2_SOUT_DSI1 0x1 #define RDMA2_SOUT_DSI2 0x4 #define RDMA2_SOUT_DSI3 0x5 +#define RDMA2_SOUT_MASK 0x7 #define DPI0_SEL_IN_RDMA1 0x1 #define DPI0_SEL_IN_RDMA2 0x3 +#define DPI0_SEL_IN_MASK 0x3 #define DPI1_SEL_IN_RDMA1 (0x1 << 8) #define DPI1_SEL_IN_RDMA2 (0x3 << 8) +#define DPI1_SEL_IN_MASK (0x3 << 8) #define DSI0_SEL_IN_RDMA1 0x1 #define DSI0_SEL_IN_RDMA2 0x4 +#define DSI0_SEL_IN_MASK 0x7 #define DSI1_SEL_IN_RDMA1 0x1 #define DSI1_SEL_IN_RDMA2 0x4 +#define DSI1_SEL_IN_MASK 0x7 #define DSI2_SEL_IN_RDMA1 (0x1 << 16) #define DSI2_SEL_IN_RDMA2 (0x4 << 16) +#define DSI2_SEL_IN_MASK (0x7 << 16) #define DSI3_SEL_IN_RDMA1 (0x1 << 16) #define DSI3_SEL_IN_RDMA2 (0x4 << 16) +#define DSI3_SEL_IN_MASK (0x7 << 16) #define COLOR1_SEL_IN_OVL1 0x1
#define OVL_MOUT_EN_RDMA 0x1 #define BLS_TO_DSI_RDMA1_TO_DPI1 0x8 #define BLS_TO_DPI_RDMA1_TO_DSI 0x2 +#define BLS_RDMA1_DSI_DPI_MASK 0xf #define DSI_SEL_IN_BLS 0x0 #define DPI_SEL_IN_BLS 0x0 +#define DPI_SEL_IN_MASK 0x1 #define DSI_SEL_IN_RDMA 0x1 +#define DSI_SEL_IN_MASK 0x1
struct mtk_mmsys_routes { u32 from_comp; u32 to_comp; u32 addr; + u32 mask; u32 val; };
@@ -91,124 +104,164 @@ struct mtk_mmsys_driver_data { static const struct mtk_mmsys_routes mmsys_default_routing_table[] = { { DDP_COMPONENT_BLS, DDP_COMPONENT_DSI0, - DISP_REG_CONFIG_OUT_SEL, BLS_TO_DSI_RDMA1_TO_DPI1 + DISP_REG_CONFIG_OUT_SEL, BLS_RDMA1_DSI_DPI_MASK, + BLS_TO_DSI_RDMA1_TO_DPI1 }, { DDP_COMPONENT_BLS, DDP_COMPONENT_DSI0, - DISP_REG_CONFIG_DSI_SEL, DSI_SEL_IN_BLS + DISP_REG_CONFIG_DSI_SEL, DSI_SEL_IN_MASK, + DSI_SEL_IN_BLS }, { DDP_COMPONENT_BLS, DDP_COMPONENT_DPI0, - DISP_REG_CONFIG_OUT_SEL, BLS_TO_DPI_RDMA1_TO_DSI + DISP_REG_CONFIG_OUT_SEL, BLS_RDMA1_DSI_DPI_MASK, + BLS_TO_DPI_RDMA1_TO_DSI }, { DDP_COMPONENT_BLS, DDP_COMPONENT_DPI0, - DISP_REG_CONFIG_DSI_SEL, DSI_SEL_IN_RDMA + DISP_REG_CONFIG_DSI_SEL, DSI_SEL_IN_MASK, + DSI_SEL_IN_RDMA }, { DDP_COMPONENT_BLS, DDP_COMPONENT_DPI0, - DISP_REG_CONFIG_DPI_SEL, DPI_SEL_IN_BLS + DISP_REG_CONFIG_DPI_SEL, DPI_SEL_IN_MASK, + DPI_SEL_IN_BLS }, { DDP_COMPONENT_GAMMA, DDP_COMPONENT_RDMA1, - DISP_REG_CONFIG_DISP_GAMMA_MOUT_EN, GAMMA_MOUT_EN_RDMA1 + DISP_REG_CONFIG_DISP_GAMMA_MOUT_EN, GAMMA_MOUT_EN_RDMA1, + GAMMA_MOUT_EN_RDMA1 }, { DDP_COMPONENT_OD0, DDP_COMPONENT_RDMA0, - DISP_REG_CONFIG_DISP_OD_MOUT_EN, OD_MOUT_EN_RDMA0 + DISP_REG_CONFIG_DISP_OD_MOUT_EN, OD_MOUT_EN_RDMA0, + OD_MOUT_EN_RDMA0 }, { DDP_COMPONENT_OD1, DDP_COMPONENT_RDMA1, - DISP_REG_CONFIG_DISP_OD_MOUT_EN, OD1_MOUT_EN_RDMA1 + DISP_REG_CONFIG_DISP_OD_MOUT_EN, OD1_MOUT_EN_RDMA1, + OD1_MOUT_EN_RDMA1 }, { DDP_COMPONENT_OVL0, DDP_COMPONENT_COLOR0, - DISP_REG_CONFIG_DISP_OVL0_MOUT_EN, OVL0_MOUT_EN_COLOR0 + DISP_REG_CONFIG_DISP_OVL0_MOUT_EN, OVL0_MOUT_EN_COLOR0, + OVL0_MOUT_EN_COLOR0 }, { DDP_COMPONENT_OVL0, DDP_COMPONENT_COLOR0, - DISP_REG_CONFIG_DISP_COLOR0_SEL_IN, COLOR0_SEL_IN_OVL0 + DISP_REG_CONFIG_DISP_COLOR0_SEL_IN, COLOR0_SEL_IN_OVL0, + COLOR0_SEL_IN_OVL0 }, { DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0, - DISP_REG_CONFIG_DISP_OVL_MOUT_EN, OVL_MOUT_EN_RDMA + DISP_REG_CONFIG_DISP_OVL_MOUT_EN, OVL_MOUT_EN_RDMA, + OVL_MOUT_EN_RDMA }, { DDP_COMPONENT_OVL1, DDP_COMPONENT_COLOR1, - DISP_REG_CONFIG_DISP_OVL1_MOUT_EN, OVL1_MOUT_EN_COLOR1 + DISP_REG_CONFIG_DISP_OVL1_MOUT_EN, OVL1_MOUT_EN_COLOR1, + OVL1_MOUT_EN_COLOR1 }, { DDP_COMPONENT_OVL1, DDP_COMPONENT_COLOR1, - DISP_REG_CONFIG_DISP_COLOR1_SEL_IN, COLOR1_SEL_IN_OVL1 + DISP_REG_CONFIG_DISP_COLOR1_SEL_IN, COLOR1_SEL_IN_OVL1, + COLOR1_SEL_IN_OVL1 }, { DDP_COMPONENT_RDMA0, DDP_COMPONENT_DPI0, - DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_DPI0 + DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_MASK, + RDMA0_SOUT_DPI0 }, { DDP_COMPONENT_RDMA0, DDP_COMPONENT_DPI1, - DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_DPI1 + DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_MASK, + RDMA0_SOUT_DPI1 }, { DDP_COMPONENT_RDMA0, DDP_COMPONENT_DSI1, - DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_DSI1 + DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_MASK, + RDMA0_SOUT_DSI1 }, { DDP_COMPONENT_RDMA0, DDP_COMPONENT_DSI2, - DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_DSI2 + DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_MASK, + RDMA0_SOUT_DSI2 }, { DDP_COMPONENT_RDMA0, DDP_COMPONENT_DSI3, - DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_DSI3 + DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_MASK, + RDMA0_SOUT_DSI3 }, { DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI0, - DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_DPI0 + DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_MASK, + RDMA1_SOUT_DPI0 }, { DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI0, - DISP_REG_CONFIG_DPI_SEL_IN, DPI0_SEL_IN_RDMA1 + DISP_REG_CONFIG_DPI_SEL_IN, DPI0_SEL_IN_MASK, + DPI0_SEL_IN_RDMA1 }, { DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI1, - DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_DPI1 + DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_MASK, + RDMA1_SOUT_DPI1 }, { DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI1, - DISP_REG_CONFIG_DPI_SEL_IN, DPI1_SEL_IN_RDMA1 + DISP_REG_CONFIG_DPI_SEL_IN, DPI1_SEL_IN_MASK, + DPI1_SEL_IN_RDMA1 }, { DDP_COMPONENT_RDMA1, DDP_COMPONENT_DSI0, - DISP_REG_CONFIG_DSIE_SEL_IN, DSI0_SEL_IN_RDMA1 + DISP_REG_CONFIG_DSIE_SEL_IN, DSI0_SEL_IN_MASK, + DSI0_SEL_IN_RDMA1 }, { DDP_COMPONENT_RDMA1, DDP_COMPONENT_DSI1, - DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_DSI1 + DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_MASK, + RDMA1_SOUT_DSI1 }, { DDP_COMPONENT_RDMA1, DDP_COMPONENT_DSI1, - DISP_REG_CONFIG_DSIO_SEL_IN, DSI1_SEL_IN_RDMA1 + DISP_REG_CONFIG_DSIO_SEL_IN, DSI1_SEL_IN_MASK, + DSI1_SEL_IN_RDMA1 }, { DDP_COMPONENT_RDMA1, DDP_COMPONENT_DSI2, - DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_DSI2 + DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_MASK, + RDMA1_SOUT_DSI2 }, { DDP_COMPONENT_RDMA1, DDP_COMPONENT_DSI2, - DISP_REG_CONFIG_DSIE_SEL_IN, DSI2_SEL_IN_RDMA1 + DISP_REG_CONFIG_DSIE_SEL_IN, DSI2_SEL_IN_MASK, + DSI2_SEL_IN_RDMA1 }, { DDP_COMPONENT_RDMA1, DDP_COMPONENT_DSI3, - DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_DSI3 + DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_MASK, + RDMA1_SOUT_DSI3 }, { DDP_COMPONENT_RDMA1, DDP_COMPONENT_DSI3, - DISP_REG_CONFIG_DSIO_SEL_IN, DSI3_SEL_IN_RDMA1 + DISP_REG_CONFIG_DSIO_SEL_IN, DSI3_SEL_IN_MASK, + DSI3_SEL_IN_RDMA1 }, { DDP_COMPONENT_RDMA2, DDP_COMPONENT_DPI0, - DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_DPI0 + DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_MASK, + RDMA2_SOUT_DPI0 }, { DDP_COMPONENT_RDMA2, DDP_COMPONENT_DPI0, - DISP_REG_CONFIG_DPI_SEL_IN, DPI0_SEL_IN_RDMA2 + DISP_REG_CONFIG_DPI_SEL_IN, DPI0_SEL_IN_MASK, + DPI0_SEL_IN_RDMA2 }, { DDP_COMPONENT_RDMA2, DDP_COMPONENT_DPI1, - DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_DPI1 + DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_MASK, + RDMA2_SOUT_DPI1 }, { DDP_COMPONENT_RDMA2, DDP_COMPONENT_DPI1, - DISP_REG_CONFIG_DPI_SEL_IN, DPI1_SEL_IN_RDMA2 + DISP_REG_CONFIG_DPI_SEL_IN, DPI1_SEL_IN_MASK, + DPI1_SEL_IN_RDMA2 }, { DDP_COMPONENT_RDMA2, DDP_COMPONENT_DSI0, - DISP_REG_CONFIG_DSIE_SEL_IN, DSI0_SEL_IN_RDMA2 + DISP_REG_CONFIG_DSIE_SEL_IN, DSI0_SEL_IN_MASK, + DSI0_SEL_IN_RDMA2 }, { DDP_COMPONENT_RDMA2, DDP_COMPONENT_DSI1, - DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_DSI1 + DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_MASK, + RDMA2_SOUT_DSI1 }, { DDP_COMPONENT_RDMA2, DDP_COMPONENT_DSI1, - DISP_REG_CONFIG_DSIO_SEL_IN, DSI1_SEL_IN_RDMA2 + DISP_REG_CONFIG_DSIO_SEL_IN, DSI1_SEL_IN_MASK, + DSI1_SEL_IN_RDMA2 }, { DDP_COMPONENT_RDMA2, DDP_COMPONENT_DSI2, - DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_DSI2 + DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_MASK, + RDMA2_SOUT_DSI2 }, { DDP_COMPONENT_RDMA2, DDP_COMPONENT_DSI2, - DISP_REG_CONFIG_DSIE_SEL_IN, DSI2_SEL_IN_RDMA2 + DISP_REG_CONFIG_DSIE_SEL_IN, DSI2_SEL_IN_MASK, + DSI2_SEL_IN_RDMA2 }, { DDP_COMPONENT_RDMA2, DDP_COMPONENT_DSI3, - DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_DSI3 + DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_MASK, + RDMA2_SOUT_DSI3 }, { DDP_COMPONENT_RDMA2, DDP_COMPONENT_DSI3, - DISP_REG_CONFIG_DSIO_SEL_IN, DSI3_SEL_IN_RDMA2 + DISP_REG_CONFIG_DSIO_SEL_IN, DSI3_SEL_IN_MASK, + DSI3_SEL_IN_RDMA2 } };
Hi, Frank:
Frank Wunderlich linux@fw-web.de 於 2021年7月28日 週三 上午1:41寫道:
From: CK Hu ck.hu@mediatek.com
SOUT has many bits and need to be cleared before set new value. Write only could do the clear, but for MOUT, it clears bits that should not be cleared. So use a mask to reset only the needed bits.
Reviewed-by: Chun-Kuang Hu chunkuang.hu@kernel.org
this fixes HDMI issues on MT7623/BPI-R2 since 5.13
Cc: stable@vger.kernel.org Fixes: 440147639ac7 ("soc: mediatek: mmsys: Use an array for setting the routing registers") Signed-off-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: CK Hu ck.hu@mediatek.com
code is taken from here (upstreamed without mask part) https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/2... basicly CK Hu's code so i set him as author
drivers/soc/mediatek/mtk-mmsys.c | 7 +- drivers/soc/mediatek/mtk-mmsys.h | 133 +++++++++++++++++++++---------- 2 files changed, 98 insertions(+), 42 deletions(-)
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c index 080660ef11bf..0f949896fd06 100644 --- a/drivers/soc/mediatek/mtk-mmsys.c +++ b/drivers/soc/mediatek/mtk-mmsys.c @@ -68,7 +68,9 @@ void mtk_mmsys_ddp_connect(struct device *dev,
for (i = 0; i < mmsys->data->num_routes; i++) if (cur == routes[i].from_comp && next == routes[i].to_comp) {
reg = readl_relaxed(mmsys->regs + routes[i].addr) | routes[i].val;
reg = readl_relaxed(mmsys->regs + routes[i].addr);
reg &= ~routes[i].mask;
reg |= routes[i].val; writel_relaxed(reg, mmsys->regs + routes[i].addr); }
} @@ -85,7 +87,8 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
for (i = 0; i < mmsys->data->num_routes; i++) if (cur == routes[i].from_comp && next == routes[i].to_comp) {
reg = readl_relaxed(mmsys->regs + routes[i].addr) & ~routes[i].val;
reg = readl_relaxed(mmsys->regs + routes[i].addr);
reg &= ~routes[i].mask; writel_relaxed(reg, mmsys->regs + routes[i].addr); }
} diff --git a/drivers/soc/mediatek/mtk-mmsys.h b/drivers/soc/mediatek/mtk-mmsys.h index a760a34e6eca..5f3e2bf0c40b 100644 --- a/drivers/soc/mediatek/mtk-mmsys.h +++ b/drivers/soc/mediatek/mtk-mmsys.h @@ -35,41 +35,54 @@ #define RDMA0_SOUT_DSI1 0x1 #define RDMA0_SOUT_DSI2 0x4 #define RDMA0_SOUT_DSI3 0x5 +#define RDMA0_SOUT_MASK 0x7 #define RDMA1_SOUT_DPI0 0x2 #define RDMA1_SOUT_DPI1 0x3 #define RDMA1_SOUT_DSI1 0x1 #define RDMA1_SOUT_DSI2 0x4 #define RDMA1_SOUT_DSI3 0x5 +#define RDMA1_SOUT_MASK 0x7 #define RDMA2_SOUT_DPI0 0x2 #define RDMA2_SOUT_DPI1 0x3 #define RDMA2_SOUT_DSI1 0x1 #define RDMA2_SOUT_DSI2 0x4 #define RDMA2_SOUT_DSI3 0x5 +#define RDMA2_SOUT_MASK 0x7 #define DPI0_SEL_IN_RDMA1 0x1 #define DPI0_SEL_IN_RDMA2 0x3 +#define DPI0_SEL_IN_MASK 0x3 #define DPI1_SEL_IN_RDMA1 (0x1 << 8) #define DPI1_SEL_IN_RDMA2 (0x3 << 8) +#define DPI1_SEL_IN_MASK (0x3 << 8) #define DSI0_SEL_IN_RDMA1 0x1 #define DSI0_SEL_IN_RDMA2 0x4 +#define DSI0_SEL_IN_MASK 0x7 #define DSI1_SEL_IN_RDMA1 0x1 #define DSI1_SEL_IN_RDMA2 0x4 +#define DSI1_SEL_IN_MASK 0x7 #define DSI2_SEL_IN_RDMA1 (0x1 << 16) #define DSI2_SEL_IN_RDMA2 (0x4 << 16) +#define DSI2_SEL_IN_MASK (0x7 << 16) #define DSI3_SEL_IN_RDMA1 (0x1 << 16) #define DSI3_SEL_IN_RDMA2 (0x4 << 16) +#define DSI3_SEL_IN_MASK (0x7 << 16) #define COLOR1_SEL_IN_OVL1 0x1
#define OVL_MOUT_EN_RDMA 0x1 #define BLS_TO_DSI_RDMA1_TO_DPI1 0x8 #define BLS_TO_DPI_RDMA1_TO_DSI 0x2 +#define BLS_RDMA1_DSI_DPI_MASK 0xf #define DSI_SEL_IN_BLS 0x0 #define DPI_SEL_IN_BLS 0x0 +#define DPI_SEL_IN_MASK 0x1 #define DSI_SEL_IN_RDMA 0x1 +#define DSI_SEL_IN_MASK 0x1
struct mtk_mmsys_routes { u32 from_comp; u32 to_comp; u32 addr;
u32 mask; u32 val;
};
@@ -91,124 +104,164 @@ struct mtk_mmsys_driver_data { static const struct mtk_mmsys_routes mmsys_default_routing_table[] = { { DDP_COMPONENT_BLS, DDP_COMPONENT_DSI0,
DISP_REG_CONFIG_OUT_SEL, BLS_TO_DSI_RDMA1_TO_DPI1
DISP_REG_CONFIG_OUT_SEL, BLS_RDMA1_DSI_DPI_MASK,
BLS_TO_DSI_RDMA1_TO_DPI1 }, { DDP_COMPONENT_BLS, DDP_COMPONENT_DSI0,
DISP_REG_CONFIG_DSI_SEL, DSI_SEL_IN_BLS
DISP_REG_CONFIG_DSI_SEL, DSI_SEL_IN_MASK,
DSI_SEL_IN_BLS }, { DDP_COMPONENT_BLS, DDP_COMPONENT_DPI0,
DISP_REG_CONFIG_OUT_SEL, BLS_TO_DPI_RDMA1_TO_DSI
DISP_REG_CONFIG_OUT_SEL, BLS_RDMA1_DSI_DPI_MASK,
BLS_TO_DPI_RDMA1_TO_DSI }, { DDP_COMPONENT_BLS, DDP_COMPONENT_DPI0,
DISP_REG_CONFIG_DSI_SEL, DSI_SEL_IN_RDMA
DISP_REG_CONFIG_DSI_SEL, DSI_SEL_IN_MASK,
DSI_SEL_IN_RDMA }, { DDP_COMPONENT_BLS, DDP_COMPONENT_DPI0,
DISP_REG_CONFIG_DPI_SEL, DPI_SEL_IN_BLS
DISP_REG_CONFIG_DPI_SEL, DPI_SEL_IN_MASK,
DPI_SEL_IN_BLS }, { DDP_COMPONENT_GAMMA, DDP_COMPONENT_RDMA1,
DISP_REG_CONFIG_DISP_GAMMA_MOUT_EN, GAMMA_MOUT_EN_RDMA1
DISP_REG_CONFIG_DISP_GAMMA_MOUT_EN, GAMMA_MOUT_EN_RDMA1,
GAMMA_MOUT_EN_RDMA1 }, { DDP_COMPONENT_OD0, DDP_COMPONENT_RDMA0,
DISP_REG_CONFIG_DISP_OD_MOUT_EN, OD_MOUT_EN_RDMA0
DISP_REG_CONFIG_DISP_OD_MOUT_EN, OD_MOUT_EN_RDMA0,
OD_MOUT_EN_RDMA0 }, { DDP_COMPONENT_OD1, DDP_COMPONENT_RDMA1,
DISP_REG_CONFIG_DISP_OD_MOUT_EN, OD1_MOUT_EN_RDMA1
DISP_REG_CONFIG_DISP_OD_MOUT_EN, OD1_MOUT_EN_RDMA1,
OD1_MOUT_EN_RDMA1 }, { DDP_COMPONENT_OVL0, DDP_COMPONENT_COLOR0,
DISP_REG_CONFIG_DISP_OVL0_MOUT_EN, OVL0_MOUT_EN_COLOR0
DISP_REG_CONFIG_DISP_OVL0_MOUT_EN, OVL0_MOUT_EN_COLOR0,
OVL0_MOUT_EN_COLOR0 }, { DDP_COMPONENT_OVL0, DDP_COMPONENT_COLOR0,
DISP_REG_CONFIG_DISP_COLOR0_SEL_IN, COLOR0_SEL_IN_OVL0
DISP_REG_CONFIG_DISP_COLOR0_SEL_IN, COLOR0_SEL_IN_OVL0,
COLOR0_SEL_IN_OVL0 }, { DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
DISP_REG_CONFIG_DISP_OVL_MOUT_EN, OVL_MOUT_EN_RDMA
DISP_REG_CONFIG_DISP_OVL_MOUT_EN, OVL_MOUT_EN_RDMA,
OVL_MOUT_EN_RDMA }, { DDP_COMPONENT_OVL1, DDP_COMPONENT_COLOR1,
DISP_REG_CONFIG_DISP_OVL1_MOUT_EN, OVL1_MOUT_EN_COLOR1
DISP_REG_CONFIG_DISP_OVL1_MOUT_EN, OVL1_MOUT_EN_COLOR1,
OVL1_MOUT_EN_COLOR1 }, { DDP_COMPONENT_OVL1, DDP_COMPONENT_COLOR1,
DISP_REG_CONFIG_DISP_COLOR1_SEL_IN, COLOR1_SEL_IN_OVL1
DISP_REG_CONFIG_DISP_COLOR1_SEL_IN, COLOR1_SEL_IN_OVL1,
COLOR1_SEL_IN_OVL1 }, { DDP_COMPONENT_RDMA0, DDP_COMPONENT_DPI0,
DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_DPI0
DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_MASK,
RDMA0_SOUT_DPI0 }, { DDP_COMPONENT_RDMA0, DDP_COMPONENT_DPI1,
DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_DPI1
DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_MASK,
RDMA0_SOUT_DPI1 }, { DDP_COMPONENT_RDMA0, DDP_COMPONENT_DSI1,
DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_DSI1
DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_MASK,
RDMA0_SOUT_DSI1 }, { DDP_COMPONENT_RDMA0, DDP_COMPONENT_DSI2,
DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_DSI2
DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_MASK,
RDMA0_SOUT_DSI2 }, { DDP_COMPONENT_RDMA0, DDP_COMPONENT_DSI3,
DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_DSI3
DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_MASK,
RDMA0_SOUT_DSI3 }, { DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI0,
DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_DPI0
DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_MASK,
RDMA1_SOUT_DPI0 }, { DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI0,
DISP_REG_CONFIG_DPI_SEL_IN, DPI0_SEL_IN_RDMA1
DISP_REG_CONFIG_DPI_SEL_IN, DPI0_SEL_IN_MASK,
DPI0_SEL_IN_RDMA1 }, { DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI1,
DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_DPI1
DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_MASK,
RDMA1_SOUT_DPI1 }, { DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI1,
DISP_REG_CONFIG_DPI_SEL_IN, DPI1_SEL_IN_RDMA1
DISP_REG_CONFIG_DPI_SEL_IN, DPI1_SEL_IN_MASK,
DPI1_SEL_IN_RDMA1 }, { DDP_COMPONENT_RDMA1, DDP_COMPONENT_DSI0,
DISP_REG_CONFIG_DSIE_SEL_IN, DSI0_SEL_IN_RDMA1
DISP_REG_CONFIG_DSIE_SEL_IN, DSI0_SEL_IN_MASK,
DSI0_SEL_IN_RDMA1 }, { DDP_COMPONENT_RDMA1, DDP_COMPONENT_DSI1,
DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_DSI1
DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_MASK,
RDMA1_SOUT_DSI1 }, { DDP_COMPONENT_RDMA1, DDP_COMPONENT_DSI1,
DISP_REG_CONFIG_DSIO_SEL_IN, DSI1_SEL_IN_RDMA1
DISP_REG_CONFIG_DSIO_SEL_IN, DSI1_SEL_IN_MASK,
DSI1_SEL_IN_RDMA1 }, { DDP_COMPONENT_RDMA1, DDP_COMPONENT_DSI2,
DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_DSI2
DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_MASK,
RDMA1_SOUT_DSI2 }, { DDP_COMPONENT_RDMA1, DDP_COMPONENT_DSI2,
DISP_REG_CONFIG_DSIE_SEL_IN, DSI2_SEL_IN_RDMA1
DISP_REG_CONFIG_DSIE_SEL_IN, DSI2_SEL_IN_MASK,
DSI2_SEL_IN_RDMA1 }, { DDP_COMPONENT_RDMA1, DDP_COMPONENT_DSI3,
DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_DSI3
DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_MASK,
RDMA1_SOUT_DSI3 }, { DDP_COMPONENT_RDMA1, DDP_COMPONENT_DSI3,
DISP_REG_CONFIG_DSIO_SEL_IN, DSI3_SEL_IN_RDMA1
DISP_REG_CONFIG_DSIO_SEL_IN, DSI3_SEL_IN_MASK,
DSI3_SEL_IN_RDMA1 }, { DDP_COMPONENT_RDMA2, DDP_COMPONENT_DPI0,
DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_DPI0
DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_MASK,
RDMA2_SOUT_DPI0 }, { DDP_COMPONENT_RDMA2, DDP_COMPONENT_DPI0,
DISP_REG_CONFIG_DPI_SEL_IN, DPI0_SEL_IN_RDMA2
DISP_REG_CONFIG_DPI_SEL_IN, DPI0_SEL_IN_MASK,
DPI0_SEL_IN_RDMA2 }, { DDP_COMPONENT_RDMA2, DDP_COMPONENT_DPI1,
DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_DPI1
DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_MASK,
RDMA2_SOUT_DPI1 }, { DDP_COMPONENT_RDMA2, DDP_COMPONENT_DPI1,
DISP_REG_CONFIG_DPI_SEL_IN, DPI1_SEL_IN_RDMA2
DISP_REG_CONFIG_DPI_SEL_IN, DPI1_SEL_IN_MASK,
DPI1_SEL_IN_RDMA2 }, { DDP_COMPONENT_RDMA2, DDP_COMPONENT_DSI0,
DISP_REG_CONFIG_DSIE_SEL_IN, DSI0_SEL_IN_RDMA2
DISP_REG_CONFIG_DSIE_SEL_IN, DSI0_SEL_IN_MASK,
DSI0_SEL_IN_RDMA2 }, { DDP_COMPONENT_RDMA2, DDP_COMPONENT_DSI1,
DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_DSI1
DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_MASK,
RDMA2_SOUT_DSI1 }, { DDP_COMPONENT_RDMA2, DDP_COMPONENT_DSI1,
DISP_REG_CONFIG_DSIO_SEL_IN, DSI1_SEL_IN_RDMA2
DISP_REG_CONFIG_DSIO_SEL_IN, DSI1_SEL_IN_MASK,
DSI1_SEL_IN_RDMA2 }, { DDP_COMPONENT_RDMA2, DDP_COMPONENT_DSI2,
DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_DSI2
DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_MASK,
RDMA2_SOUT_DSI2 }, { DDP_COMPONENT_RDMA2, DDP_COMPONENT_DSI2,
DISP_REG_CONFIG_DSIE_SEL_IN, DSI2_SEL_IN_RDMA2
DISP_REG_CONFIG_DSIE_SEL_IN, DSI2_SEL_IN_MASK,
DSI2_SEL_IN_RDMA2 }, { DDP_COMPONENT_RDMA2, DDP_COMPONENT_DSI3,
DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_DSI3
DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_MASK,
RDMA2_SOUT_DSI3 }, { DDP_COMPONENT_RDMA2, DDP_COMPONENT_DSI3,
DISP_REG_CONFIG_DSIO_SEL_IN, DSI3_SEL_IN_RDMA2
DISP_REG_CONFIG_DSIO_SEL_IN, DSI3_SEL_IN_MASK,
DSI3_SEL_IN_RDMA2 }
};
-- 2.25.1
Linux-mediatek mailing list Linux-mediatek@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-mediatek
On Wed, Jul 28, 2021 at 1:41 AM Frank Wunderlich linux@fw-web.de wrote:
From: CK Hu ck.hu@mediatek.com
SOUT has many bits and need to be cleared before set new value. Write only could do the clear, but for MOUT, it clears bits that should not be cleared. So use a mask to reset only the needed bits.
this fixes HDMI issues on MT7623/BPI-R2 since 5.13
Cc: stable@vger.kernel.org Fixes: 440147639ac7 ("soc: mediatek: mmsys: Use an array for setting the routing registers") Signed-off-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: CK Hu ck.hu@mediatek.com
code is taken from here (upstreamed without mask part) https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/2... basicly CK Hu's code so i set him as author
drivers/soc/mediatek/mtk-mmsys.c | 7 +- drivers/soc/mediatek/mtk-mmsys.h | 133 +++++++++++++++++++++---------- 2 files changed, 98 insertions(+), 42 deletions(-)
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c index 080660ef11bf..0f949896fd06 100644 --- a/drivers/soc/mediatek/mtk-mmsys.c +++ b/drivers/soc/mediatek/mtk-mmsys.c @@ -68,7 +68,9 @@ void mtk_mmsys_ddp_connect(struct device *dev,
for (i = 0; i < mmsys->data->num_routes; i++) if (cur == routes[i].from_comp && next == routes[i].to_comp) {
reg = readl_relaxed(mmsys->regs + routes[i].addr) | routes[i].val;
reg = readl_relaxed(mmsys->regs + routes[i].addr);
reg &= ~routes[i].mask;
reg |= routes[i].val; writel_relaxed(reg, mmsys->regs + routes[i].addr); }
} @@ -85,7 +87,8 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
for (i = 0; i < mmsys->data->num_routes; i++) if (cur == routes[i].from_comp && next == routes[i].to_comp) {
reg = readl_relaxed(mmsys->regs + routes[i].addr) & ~routes[i].val;
reg = readl_relaxed(mmsys->regs + routes[i].addr);
reg &= ~routes[i].mask;
This patch is breaking the mt8183 internal display. I think it's because ~routes[i].val; is removed? Also what should the routes[i].mask be if it's not set in mmsys_mt8183_routing_table?
writel_relaxed(reg, mmsys->regs + routes[i].addr); }
}
<snip>
Hi, Hsin-yi:
On Thu, 2021-07-29 at 11:15 +0800, Hsin-Yi Wang wrote:
On Wed, Jul 28, 2021 at 1:41 AM Frank Wunderlich linux@fw-web.de wrote:
From: CK Hu ck.hu@mediatek.com
SOUT has many bits and need to be cleared before set new value. Write only could do the clear, but for MOUT, it clears bits that should not be cleared. So use a mask to reset only the needed bits.
this fixes HDMI issues on MT7623/BPI-R2 since 5.13
Cc: stable@vger.kernel.org Fixes: 440147639ac7 ("soc: mediatek: mmsys: Use an array for setting the routing registers") Signed-off-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: CK Hu ck.hu@mediatek.com
code is taken from here (upstreamed without mask part) https://urldefense.com/v3/__https://chromium-review.googlesource.com/c/chrom... basicly CK Hu's code so i set him as author
drivers/soc/mediatek/mtk-mmsys.c | 7 +- drivers/soc/mediatek/mtk-mmsys.h | 133 +++++++++++++++++++++---------- 2 files changed, 98 insertions(+), 42 deletions(-)
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c index 080660ef11bf..0f949896fd06 100644 --- a/drivers/soc/mediatek/mtk-mmsys.c +++ b/drivers/soc/mediatek/mtk-mmsys.c @@ -68,7 +68,9 @@ void mtk_mmsys_ddp_connect(struct device *dev,
for (i = 0; i < mmsys->data->num_routes; i++) if (cur == routes[i].from_comp && next == routes[i].to_comp) {
reg = readl_relaxed(mmsys->regs + routes[i].addr) | routes[i].val;
reg = readl_relaxed(mmsys->regs + routes[i].addr);
reg &= ~routes[i].mask;
reg |= routes[i].val; writel_relaxed(reg, mmsys->regs + routes[i].addr); }
} @@ -85,7 +87,8 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
for (i = 0; i < mmsys->data->num_routes; i++) if (cur == routes[i].from_comp && next == routes[i].to_comp) {
reg = readl_relaxed(mmsys->regs + routes[i].addr) & ~routes[i].val;
reg = readl_relaxed(mmsys->regs + routes[i].addr);
reg &= ~routes[i].mask;
This patch is breaking the mt8183 internal display. I think it's because ~routes[i].val; is removed? Also what should the routes[i].mask be if it's not set in mmsys_mt8183_routing_table?
I'm not sure this problem is about MOUT or SOUT. But for MOUT, it's not necessary to set mask because the value is equal to mask. To make thins simple, the code could be
/* For MOUT, value is equal to mask, so mask is 0 and clear the value */ reg &= ~routes[i].mask & ~routes[i].val;
Regards, CK
writel_relaxed(reg, mmsys->regs + routes[i].addr); }
}
<snip>
Am 29. Juli 2021 05:15:23 MESZ schrieb Hsin-Yi Wang hsinyi@chromium.org:
This patch is breaking the mt8183 internal display. I think it's because ~routes[i].val; is removed? Also what should the routes[i].mask be if it's not set in mmsys_mt8183_routing_table?
writel_relaxed(reg, mmsys->regs +
routes[i].addr);
}
}
<snip>
The mask should reset the needed bits,maybe it needs to be adjusted for your ddp components...
Can you add some debugs inside loops in mtk_mmsys_ddp_connect and mtk_mmsys_ddp_disconnect (show read val,mask and final mask before write) to show differences before and after the patch?
regards Frank
On Thu, Jul 29, 2021 at 1:40 PM Frank Wunderlich linux@fw-web.de wrote:
Am 29. Juli 2021 05:15:23 MESZ schrieb Hsin-Yi Wang hsinyi@chromium.org:
This patch is breaking the mt8183 internal display. I think it's because ~routes[i].val; is removed? Also what should the routes[i].mask be if it's not set in mmsys_mt8183_routing_table?
writel_relaxed(reg, mmsys->regs +
routes[i].addr);
}
}
<snip>
The mask should reset the needed bits,maybe it needs to be adjusted for your ddp components...
Can you add some debugs inside loops in mtk_mmsys_ddp_connect and mtk_mmsys_ddp_disconnect (show read val,mask and final mask before write) to show differences before and after the patch?
struct mtk_mmsys_routes { u32 from_comp; u32 to_comp; u32 addr; + u32 mask; u32 val; }; mask is not the last element, and mmsys_mt8183_routing_table = { { DDP_COMPONENT_OVL0, DDP_COMPONENT_OVL_2L0, MT8183_DISP_OVL0_MOUT_EN, MT8183_OVL0_MOUT_EN_OVL0_2L } ... so the mask and val will be wrong. CK, do you know what mask we should set for mt8183? Or can we just set a dummy 0 mask.
regards Frank
Am 29. Juli 2021 07:47:03 MESZ schrieb Hsin-Yi Wang hsinyi@chromium.org:
On Thu, Jul 29, 2021 at 1:40 PM Frank Wunderlich linux@fw-web.de wrote:
struct mtk_mmsys_routes { u32 from_comp; u32 to_comp; u32 addr;
u32 mask; u32 val;
}; mask is not the last element, and mmsys_mt8183_routing_table = { { DDP_COMPONENT_OVL0, DDP_COMPONENT_OVL_2L0, MT8183_DISP_OVL0_MOUT_EN, MT8183_OVL0_MOUT_EN_OVL0_2L } ... so the mask and val will be wrong. CK, do you know what mask we should set for mt8183? Or can we just set a dummy 0 mask.
Ahhh...mt8183 has own mmsys-table and i had only changed the default one,so value is now missing because value is now the mask. I have used same order as CK to avoid confusion and make it easier to review. Afaik you could use same value as value to reset same bits...did this in default routing table too.
regards Frank
On Thu, Jul 29, 2021 at 1:54 PM Frank Wunderlich linux@fw-web.de wrote:
Am 29. Juli 2021 07:47:03 MESZ schrieb Hsin-Yi Wang hsinyi@chromium.org:
On Thu, Jul 29, 2021 at 1:40 PM Frank Wunderlich linux@fw-web.de wrote:
struct mtk_mmsys_routes { u32 from_comp; u32 to_comp; u32 addr;
u32 mask; u32 val;
}; mask is not the last element, and mmsys_mt8183_routing_table = { { DDP_COMPONENT_OVL0, DDP_COMPONENT_OVL_2L0, MT8183_DISP_OVL0_MOUT_EN, MT8183_OVL0_MOUT_EN_OVL0_2L } ... so the mask and val will be wrong. CK, do you know what mask we should set for mt8183? Or can we just set a dummy 0 mask.
Ahhh...mt8183 has own mmsys-table and i had only changed the default one,so value is now missing because value is now the mask. I have used same order as CK to avoid confusion and make it easier to review. Afaik you could use same value as value to reset same bits...did this in default routing table too.
Should I create another patch based on this or can you help update the mt8183 table in this patch?
Thanks
regards Frank
Am 29. Juli 2021 07:58:17 MESZ schrieb Hsin-Yi Wang hsinyi@chromium.org:
Should I create another patch based on this or can you help update the mt8183 table in this patch?
I prepared a patch for mt8183 and it is reported as working. I send out v2 with the patch squashed ok? It adds only val again to each element so i take the review-tag,ok?
regards Frank
On Thu, Jul 29, 2021 at 2:45 PM Frank Wunderlich linux@fw-web.de wrote:
Am 29. Juli 2021 07:58:17 MESZ schrieb Hsin-Yi Wang hsinyi@chromium.org:
Should I create another patch based on this or can you help update the mt8183 table in this patch?
I prepared a patch for mt8183 and it is reported as working. I send out v2 with the patch squashed ok? It adds only val again to each element so i take the review-tag,ok?
You can also add by review tag:
Reviewed-by: Hsin-Yi Wang hsinyi@chromium.org
Thanks
regards Frank
linux-stable-mirror@lists.linaro.org