[PATCH v4 0/6] drm/rockchip: fixes and new features
This series patches are used for yuv image overlay display. Rockchip vop support NV11, NV16, NV24 yuv format, and can scale the image scale 1/8 to 8. Changes in v4: - rebase to top of drm-next, fix conflict - tiny fix on plane scale. Changes in v3: - make code more readable - fix some bugs Changes in v2: - Uv buffer not support odd offset, align it. - Fix error display when move yuv image. - Fix scale dest info. Mark Yao (6): drm/rockchip: vop: Fix virtual stride calculation drm/rockchip: vop: Fix window dest start point drm/rockchip: vop: Add yuv plane support drm/rockchip: vop: Default enable win2/3 area0 bit drm/rockchip: vop: restore vop registers when resume drm/rockchip: vop: support plane scale drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 269 ++- drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 88 + 2 files changed, 348 insertions(+), 9 deletions(-) -- 1.7.9.5
[PATCH v4 1/6] drm/rockchip: vop: Fix virtual stride calculation
vir_stride need number words of the virtual width, and fb->pitches save bytes_per_pixel, so just div 4 switch to stride. Signed-off-by: Mark Yao --- Changes in v4: None Changes in v3: Adviced by Tomasz Figa - use more suitable tile for this patch. Changes in v2: None drivers/gpu/drm/rockchip/rockchip_drm_vop.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 34b78e7..6b44731 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -667,7 +667,7 @@ static int vop_update_plane_event(struct drm_plane *plane, offset += (src.y1 >> 16) * fb->pitches[0]; yrgb_mst = rk_obj->dma_addr + offset; - y_vir_stride = fb->pitches[0] / (fb->bits_per_pixel >> 3); + y_vir_stride = fb->pitches[0] >> 2; /* * If this plane update changes the plane's framebuffer, (or more -- 1.7.9.5
[PATCH v4 2/6] drm/rockchip: vop: Fix window dest start point
Dest start point use crtc_x/y is wrong, crtc_x/y is not equal to dest.x1/y1 at plane scale. Signed-off-by: Mark Yao --- Changes in v4: None drivers/gpu/drm/rockchip/rockchip_drm_vop.c |6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 6b44731..da72de9 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -657,11 +657,9 @@ static int vop_update_plane_event(struct drm_plane *plane, actual_w = (src.x2 - src.x1) >> 16; actual_h = (src.y2 - src.y1) >> 16; - crtc_x = max(0, crtc_x); - crtc_y = max(0, crtc_y); - dsp_stx = crtc_x + crtc->mode.htotal - crtc->mode.hsync_start; - dsp_sty = crtc_y + crtc->mode.vtotal - crtc->mode.vsync_start; + dsp_stx = dest.x1 + crtc->mode.htotal - crtc->mode.hsync_start; + dsp_sty = dest.y1 + crtc->mode.vtotal - crtc->mode.vsync_start; offset = (src.x1 >> 16) * (fb->bits_per_pixel >> 3); offset += (src.y1 >> 16) * fb->pitches[0]; -- 1.7.9.5
[PATCH v4 3/6] drm/rockchip: vop: Add yuv plane support
vop support yuv with NV12, NV16 and NV24, only 2 plane yuv. Signed-off-by: Mark Yao --- Changes in v4: rebase to drm-next, fix conflict Changes in v3: Adviced by Tomasz Figa - separate dest calculate to another patch - fix src x1,x2 when do align, and remove unnecessary src.y1 align. Changes in v2: - Uv buffer not support odd offset, align it. - Fix error display when move yuv image. drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 56 ++- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index da72de9..c1264d5 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -393,6 +393,18 @@ static enum vop_data_format vop_convert_format(uint32_t format) } } +static bool is_yuv_support(uint32_t format) +{ + switch (format) { + case DRM_FORMAT_NV12: + case DRM_FORMAT_NV16: + case DRM_FORMAT_NV24: + return true; + default: + return false; + } +} + static bool is_alpha_support(uint32_t format) { switch (format) { @@ -598,17 +610,22 @@ static int vop_update_plane_event(struct drm_plane *plane, struct vop *vop = to_vop(crtc); struct drm_gem_object *obj; struct rockchip_gem_object *rk_obj; + struct drm_gem_object *uv_obj; + struct rockchip_gem_object *rk_uv_obj; unsigned long offset; unsigned int actual_w; unsigned int actual_h; unsigned int dsp_stx; unsigned int dsp_sty; unsigned int y_vir_stride; + unsigned int uv_vir_stride = 0; dma_addr_t yrgb_mst; + dma_addr_t uv_mst = 0; enum vop_data_format format; uint32_t val; bool is_alpha; bool rb_swap; + bool is_yuv; bool visible; int ret; struct drm_rect dest = { @@ -643,6 +660,8 @@ static int vop_update_plane_event(struct drm_plane *plane, is_alpha = is_alpha_support(fb->pixel_format); rb_swap = has_rb_swapped(fb->pixel_format); + is_yuv = is_yuv_support(fb->pixel_format); + format = vop_convert_format(fb->pixel_format); if (format < 0) return format; @@ -655,18 +674,47 @@ static int vop_update_plane_event(struct drm_plane *plane, rk_obj = to_rockchip_obj(obj); + if (is_yuv) { + /* +* Src.x1 can be odd when do clip, but yuv plane start point +* need align with 2 pixel. +*/ + val = (src.x1 >> 16) % 2; + src.x1 += val << 16; + src.x2 += val << 16; + } + actual_w = (src.x2 - src.x1) >> 16; actual_h = (src.y2 - src.y1) >> 16; dsp_stx = dest.x1 + crtc->mode.htotal - crtc->mode.hsync_start; dsp_sty = dest.y1 + crtc->mode.vtotal - crtc->mode.vsync_start; - offset = (src.x1 >> 16) * (fb->bits_per_pixel >> 3); + offset = (src.x1 >> 16) * drm_format_plane_cpp(fb->pixel_format, 0); offset += (src.y1 >> 16) * fb->pitches[0]; - yrgb_mst = rk_obj->dma_addr + offset; + yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0]; y_vir_stride = fb->pitches[0] >> 2; + if (is_yuv) { + int hsub = drm_format_horz_chroma_subsampling(fb->pixel_format); + int vsub = drm_format_vert_chroma_subsampling(fb->pixel_format); + int bpp = drm_format_plane_cpp(fb->pixel_format, 1); + + uv_obj = rockchip_fb_get_gem_obj(fb, 1); + if (!uv_obj) { + DRM_ERROR("fail to get uv object from framebuffer\n"); + return -EINVAL; + } + rk_uv_obj = to_rockchip_obj(uv_obj); + uv_vir_stride = fb->pitches[1] >> 2; + + offset = (src.x1 >> 16) * bpp / hsub; + offset += (src.y1 >> 16) * fb->pitches[1] / vsub; + + uv_mst = rk_uv_obj->dma_addr + offset + fb->offsets[1]; + } + /* * If this plane update changes the plane's framebuffer, (or more * precisely, if this update has a different framebuffer than the last @@ -702,6 +750,10 @@ static int vop_update_plane_event(struct drm_plane *plane, VOP_WIN_SET(vop, win, format, format); VOP_WIN_SET(vop, win, yrgb_vir, y_vir_stride); VOP_WIN_SET(vop, win, yrgb_mst, yrgb_mst); + if (is_yuv) { + VOP_WIN_SET(vop, win, uv_vir, uv_vir_stride); + VOP_WIN_SET(vop, win, uv_mst, uv_mst); + } val = (actual_h - 1) << 16; val |= (actual_w - 1) & 0x; VOP_WIN_SET(vop, win, act_info, val); -- 1.7.9.5
[PATCH v4 4/6] drm/rockchip: vop: Default enable win2/3 area0 bit
Win2/3 support multiple area function, but we haven't found a suitable way to use it yet, so let's just use them as other windows with only area 0 enabled. Signed-off-by: Mark Yao --- Changes in v4: None Changes in v3: Adviced by Tomasz Figa - fix patch comments. Changes in v2: None drivers/gpu/drm/rockchip/rockchip_drm_vop.c |6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index c1264d5..4a2923b 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -279,6 +279,12 @@ static const struct vop_reg_data vop_init_reg_table[] = { {DSP_CTRL0, 0x}, {WIN0_CTRL0, 0x0080}, {WIN1_CTRL0, 0x0080}, + /* TODO: Win2/3 support multiple area function, but we haven't found +* a suitable way to use it yet, so let's just use them as other windows +* with only area 0 enabled. +*/ + {WIN2_CTRL0, 0x0010}, + {WIN3_CTRL0, 0x0010}, }; /* -- 1.7.9.5
[PATCH v4 5/6] drm/rockchip: vop: restore vop registers when resume
The registers will be reset to default values when whole power domain off, so restore registers from regsbak. Signed-off-by: Mark Yao --- Changes in v4: None drivers/gpu/drm/rockchip/rockchip_drm_vop.c |1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 4a2923b..16b7d98 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -496,6 +496,7 @@ static void vop_enable(struct drm_crtc *crtc) goto err_disable_aclk; } + memcpy(vop->regs, vop->regsbak, vop->len); /* * At here, vop clock & iommu is enable, R/W vop regs would be safe. */ -- 1.7.9.5
[PATCH v4 6/6] drm/rockchip: vop: support plane scale
Win_full support 1/8 to 8 scale down/up engine, support all format scale. Signed-off-by: Mark Yao --- Changes in v4: Adviced by Tomasz Figa - calcaute min/max scale with readable macro. Changes in v3: Adviced by Tomasz Figa - remove unused code and unnecessary scale path. - use static inline funcion instead "#define", let gcc check the cast - move same call into helper, make code clean. Changes in v2: - Fix scale dest info. drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 198 ++- drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 88 2 files changed, 284 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 16b7d98..5d8ae5e 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -50,6 +50,8 @@ #define VOP_WIN_SET(x, win, name, v) \ REG_SET(x, win->base, win->phy->name, v, RELAXED) +#define VOP_SCL_SET(x, win, name, v) \ + REG_SET(x, win->base, win->phy->scl->name, v, RELAXED) #define VOP_CTRL_SET(x, name, v) \ REG_SET(x, 0, (x)->data->ctrl->name, v, NORMAL) @@ -164,7 +166,37 @@ struct vop_ctrl { struct vop_reg vpost_st_end; }; +struct vop_scl_regs { + struct vop_reg cbcr_vsd_mode; + struct vop_reg cbcr_vsu_mode; + struct vop_reg cbcr_hsd_mode; + struct vop_reg cbcr_ver_scl_mode; + struct vop_reg cbcr_hor_scl_mode; + struct vop_reg yrgb_vsd_mode; + struct vop_reg yrgb_vsu_mode; + struct vop_reg yrgb_hsd_mode; + struct vop_reg yrgb_ver_scl_mode; + struct vop_reg yrgb_hor_scl_mode; + struct vop_reg line_load_mode; + struct vop_reg cbcr_axi_gather_num; + struct vop_reg yrgb_axi_gather_num; + struct vop_reg vsd_cbcr_gt2; + struct vop_reg vsd_cbcr_gt4; + struct vop_reg vsd_yrgb_gt2; + struct vop_reg vsd_yrgb_gt4; + struct vop_reg bic_coe_sel; + struct vop_reg cbcr_axi_gather_en; + struct vop_reg yrgb_axi_gather_en; + + struct vop_reg lb_mode; + struct vop_reg scale_yrgb_x; + struct vop_reg scale_yrgb_y; + struct vop_reg scale_cbcr_x; + struct vop_reg scale_cbcr_y; +}; + struct vop_win_phy { + const struct vop_scl_regs *scl; const uint32_t *data_formats; uint32_t nformats; @@ -222,7 +254,36 @@ static const uint32_t formats_234[] = { DRM_FORMAT_BGR565, }; +static const struct vop_scl_regs win_full_scl = { + .cbcr_vsd_mode = VOP_REG(WIN0_CTRL1, 0x1, 31), + .cbcr_vsu_mode = VOP_REG(WIN0_CTRL1, 0x1, 30), + .cbcr_hsd_mode = VOP_REG(WIN0_CTRL1, 0x3, 28), + .cbcr_ver_scl_mode = VOP_REG(WIN0_CTRL1, 0x3, 26), + .cbcr_hor_scl_mode = VOP_REG(WIN0_CTRL1, 0x3, 24), + .yrgb_vsd_mode = VOP_REG(WIN0_CTRL1, 0x1, 23), + .yrgb_vsu_mode = VOP_REG(WIN0_CTRL1, 0x1, 22), + .yrgb_hsd_mode = VOP_REG(WIN0_CTRL1, 0x3, 20), + .yrgb_ver_scl_mode = VOP_REG(WIN0_CTRL1, 0x3, 18), + .yrgb_hor_scl_mode = VOP_REG(WIN0_CTRL1, 0x3, 16), + .line_load_mode = VOP_REG(WIN0_CTRL1, 0x1, 15), + .cbcr_axi_gather_num = VOP_REG(WIN0_CTRL1, 0x7, 12), + .yrgb_axi_gather_num = VOP_REG(WIN0_CTRL1, 0xf, 8), + .vsd_cbcr_gt2 = VOP_REG(WIN0_CTRL1, 0x1, 7), + .vsd_cbcr_gt4 = VOP_REG(WIN0_CTRL1, 0x1, 6), + .vsd_yrgb_gt2 = VOP_REG(WIN0_CTRL1, 0x1, 5), + .vsd_yrgb_gt4 = VOP_REG(WIN0_CTRL1, 0x1, 4), + .bic_coe_sel = VOP_REG(WIN0_CTRL1, 0x3, 2), + .cbcr_axi_gather_en = VOP_REG(WIN0_CTRL1, 0x1, 1), + .yrgb_axi_gather_en = VOP_REG(WIN0_CTRL1, 0x1, 0), + .lb_mode = VOP_REG(WIN0_CTRL0, 0x7, 5), + .scale_yrgb_x = VOP_REG(WIN0_SCL_FACTOR_YRGB, 0x, 0x0), + .scale_yrgb_y = VOP_REG(WIN0_SCL_FACTOR_YRGB, 0x, 16), + .scale_cbcr_x = VOP_REG(WIN0_SCL_FACTOR_CBR, 0x, 0x0), + .scale_cbcr_y = VOP_REG(WIN0_SCL_FACTOR_CBR, 0x, 16), +}; + static const struct vop_win_phy win01_data = { + .scl = &win_full_scl, .data_formats = formats_01, .nformats = ARRAY_SIZE(formats_01), .enable = VOP_REG(WIN0_CTRL0, 0x1, 0), @@ -422,6 +483,126 @@ static bool is_alpha_support(uint32_t format) } } +static uint16_t scl_vop_cal_scale(enum scale_mode mode, uint32_t src, + uint32_t dst, bool is_horizontal, + int vsu_mode, int *vskiplines) +{ + uint16_t val = 1 << SCL_FT_DEFAULT_FIXPOINT_SHIFT; + + if (is_horizontal) { + if (mode == SCALE_UP) + val = GET_SCL_FT_BIC(src, dst); + else if (mode == SCALE_DOWN) + val = GET_SCL_FT_BILI_DN(src, dst); + } else { + if (mode == SCALE_UP) { + if (vsu_mode == SCALE_UP_BIL) + val = GET_SCL_FT_BILI_UP(src, dst); + else +
[PATCH v12 4/6] arm/dts/ls1021a: Add DCU dts node
On Sat, Jul 25, 2015 at 11:27 AM, Shawn Guo wrote: > > On Fri, Jul 24, 2015 at 06:34:12PM +0800, Jianwei Wang wrote: > > Add DCU node, DCU is a display controller of Freescale > > named 2D-ACE. > > > > Signed-off-by: Alison Wang > > Signed-off-by: Xiubo Li > > Signed-off-by: Jianwei Wang > > For dts patches sent to me, please use prefix like "ARM: dts: ls1021a: > ..." in the subject. > > Shawn Okay, thanks. Jianwei > > > --- > > arch/arm/boot/dts/ls1021a.dtsi | 10 ++ > > 1 file changed, 10 insertions(+) > > > > diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi > > index c70bb27..6d6e3e2 100644 > > --- a/arch/arm/boot/dts/ls1021a.dtsi > > +++ b/arch/arm/boot/dts/ls1021a.dtsi > > @@ -383,6 +383,16 @@ > ><&platform_clk 1>; > > }; > > > > + dcu: dcu at 2ce { > > + compatible = "fsl,ls1021a-dcu"; > > + reg = <0x0 0x2ce 0x0 0x1>; > > + interrupts = ; > > + clocks = <&platform_clk 0>; > > + clock-names = "dcu"; > > + big-endian; > > + status = "disabled"; > > + }; > > + > > mdio0: mdio at 2d24000 { > > compatible = "gianfar"; > > device_type = "mdio"; > > -- > > 2.1.0.27.g96db324 > > > > > > ___ > > linux-arm-kernel mailing list > > linux-arm-kernel at lists.infradead.org > > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel > >
[PATCH 0/5] drm/i2c: adv7511: ADV7533 support
ADV7533 is a DSI to HDMI encoder chip. It's like ADV7511, but with an additional DSI RX block that takes in DSI video mode output. This series adds support for ADV7533. Unlike ADV7511 that's modelled as a drm i2c slave encoder, ADV7533 is a drm_bridge object. The bridge ops further create a HDMI type connector device for the chip's output. In order to pass DSI specific parameters to the host, the driver creates a dummy DSI device, which it registers to a DSI host as specified via DT. The first patch in the series is a minor fix, the rest add ADV7533 support. They depend on the series I posted sometime back: "drm/dsi: DSI for devices with different control bus" https://lkml.org/lkml/2015/6/30/42 Archit Taneja (4): drm/i2c: adv7511: Fix mutex deadlock when interrupts are disabled drm/i2c: adv7511: Refactor encoder slave functions drm/i2c: adv7511: Add drm_bridge/connector for ADV7533 drm/i2c: adv7511: Create mipi_dsi_device for ADV7533 Lars-Peter Clausen (1): drm/i2c: adv7511: Initial support for adv7533 drivers/gpu/drm/i2c/adv7511.c | 486 +- 1 file changed, 437 insertions(+), 49 deletions(-) -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
[PATCH 1/5] drm/i2c: adv7511: Fix mutex deadlock when interrupts are disabled
When the adv7511 i2c client doesn't have an interrupt line, we observe a deadlock on caused by trying to lock drm device's mode_config.mutex twice in the same context. Here is the sequence that causes it: ioctl DRM_IOCTL_MODE_GETCONNECTOR from userspace drm_mode_getconnector (acquires mode_config mutex) connector->fill_modes() drm_helper_probe_single_connector_modes connector_funcs->get_modes adv7511_encoder_get_modes adv7511_get_edid_block adv7511_irq_process drm_helper_hpd_irq_event (acquires mode_config mutex again) In adv7511_irq_process, don't call drm_helper_hpd_irq_event when not called from interrupt context. It doesn't serve any purpose there anyway. Signed-off-by: Archit Taneja --- drivers/gpu/drm/i2c/adv7511.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i2c/adv7511.c b/drivers/gpu/drm/i2c/adv7511.c index 2aaa3c8..cf5bb29 100644 --- a/drivers/gpu/drm/i2c/adv7511.c +++ b/drivers/gpu/drm/i2c/adv7511.c @@ -422,7 +422,7 @@ static bool adv7511_hpd(struct adv7511 *adv7511) return false; } -static int adv7511_irq_process(struct adv7511 *adv7511) +static int adv7511_irq_process(struct adv7511 *adv7511, bool process_hpd) { unsigned int irq0, irq1; int ret; @@ -438,7 +438,7 @@ static int adv7511_irq_process(struct adv7511 *adv7511) regmap_write(adv7511->regmap, ADV7511_REG_INT(0), irq0); regmap_write(adv7511->regmap, ADV7511_REG_INT(1), irq1); - if (irq0 & ADV7511_INT0_HDP && adv7511->encoder) + if (process_hpd && irq0 & ADV7511_INT0_HDP && adv7511->encoder) drm_helper_hpd_irq_event(adv7511->encoder->dev); if (irq0 & ADV7511_INT0_EDID_READY || irq1 & ADV7511_INT1_DDC_ERROR) { @@ -456,7 +456,7 @@ static irqreturn_t adv7511_irq_handler(int irq, void *devid) struct adv7511 *adv7511 = devid; int ret; - ret = adv7511_irq_process(adv7511); + ret = adv7511_irq_process(adv7511, true); return ret < 0 ? IRQ_NONE : IRQ_HANDLED; } @@ -473,7 +473,7 @@ static int adv7511_wait_for_edid(struct adv7511 *adv7511, int timeout) adv7511->edid_read, msecs_to_jiffies(timeout)); } else { for (; timeout > 0; timeout -= 25) { - ret = adv7511_irq_process(adv7511); + ret = adv7511_irq_process(adv7511, false); if (ret < 0) break; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
[PATCH 2/5] drm/i2c: adv7511: Initial support for adv7533
From: Lars-Peter Clausen ADV7533 is a DSI to HDMI encoder chip. It is a derivative of ADV7511, with additional blocks to translate input DSI data to parallel RGB data. Besides the ADV7511 i2c register map, it has additional registers that require to be configured to activate the DSI blocks. Use DT compatible strings to populate the adv7533 type enum. Add minimal register configurations belonging to the DSI/CEC register map. Signed-off-by: Lars-Peter Clausen Signed-off-by: Archit Taneja --- drivers/gpu/drm/i2c/adv7511.c | 155 +++--- 1 file changed, 131 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i2c/adv7511.c b/drivers/gpu/drm/i2c/adv7511.c index cf5bb29..63a3d20 100644 --- a/drivers/gpu/drm/i2c/adv7511.c +++ b/drivers/gpu/drm/i2c/adv7511.c @@ -20,12 +20,18 @@ #include "adv7511.h" +enum adv7511_type { + ADV7511, + ADV7533, +}; + struct adv7511 { struct i2c_client *i2c_main; struct i2c_client *i2c_edid; + struct i2c_client *i2c_cec; struct regmap *regmap; - struct regmap *packet_memory_regmap; + struct regmap *regmap_cec; enum drm_connector_status status; bool powered; @@ -46,6 +52,8 @@ struct adv7511 { struct edid *edid; struct gpio_desc *gpio_pd; + + enum adv7511_type type; }; static struct adv7511 *encoder_to_adv7511(struct drm_encoder *encoder) @@ -66,6 +74,23 @@ static const struct reg_default adv7511_fixed_registers[] = { { 0x55, 0x02 }, }; +/* ADI recommended values for proper operation. */ +static const struct reg_default adv7533_fixed_registers[] = { + { 0x16, 0x20 }, + { 0x9a, 0xe0 }, + { 0xba, 0x70 }, + { 0xde, 0x82 }, + { 0xe4, 0x40 }, + { 0xe5, 0x80 }, +}; + +static const struct reg_default adv7533_cec_fixed_registers[] = { + { 0x15, 0xd0 }, + { 0x17, 0xd0 }, + { 0x24, 0x20 }, + { 0x57, 0x11 }, +}; + /* - * Register access */ @@ -158,6 +183,15 @@ static const struct regmap_config adv7511_regmap_config = { .volatile_reg = adv7511_register_volatile, }; +static const struct regmap_config adv7533_cec_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + + .max_register = 0xff, + .cache_type = REGCACHE_RBTREE, +}; + + /* - * Hardware configuration */ @@ -358,6 +392,25 @@ static void adv7511_set_link_config(struct adv7511 *adv7511, adv7511->rgb = config->input_colorspace == HDMI_COLORSPACE_RGB; } +static void adv7511_dsi_receiver_dpms(struct adv7511 *adv7511) +{ + if (adv7511->type != ADV7533) + return; + + if (adv7511->powered) { + /* set number of dsi lanes (hardcoded to 4 for now) */ + regmap_write(adv7511->regmap_cec, 0x1c, 0x4 << 4); + /* disable internal timing generator */ + regmap_write(adv7511->regmap_cec, 0x27, 0x0b); + /* enable hdmi */ + regmap_write(adv7511->regmap_cec, 0x03, 0x89); + /* disable test mode */ + regmap_write(adv7511->regmap_cec, 0x55, 0x00); + } else { + regmap_write(adv7511->regmap_cec, 0x03, 0x0b); + } +} + static void adv7511_power_on(struct adv7511 *adv7511) { adv7511->current_edid_segment = -1; @@ -387,6 +440,8 @@ static void adv7511_power_on(struct adv7511 *adv7511) regcache_sync(adv7511->regmap); adv7511->powered = true; + + adv7511_dsi_receiver_dpms(adv7511); } static void adv7511_power_off(struct adv7511 *adv7511) @@ -398,6 +453,8 @@ static void adv7511_power_off(struct adv7511 *adv7511) regcache_mark_dirty(adv7511->regmap); adv7511->powered = false; + + adv7511_dsi_receiver_dpms(adv7511); } /* - @@ -567,6 +624,9 @@ static int adv7511_get_modes(struct drm_encoder *encoder, /* Reading the EDID only works if the device is powered */ if (!adv7511->powered) { + regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, + ADV7511_REG_POWER2_HDP_SRC_MASK, + ADV7511_REG_POWER2_HDP_SRC_NONE); regmap_write(adv7511->regmap, ADV7511_REG_INT(0), ADV7511_INT0_EDID_READY); regmap_write(adv7511->regmap, ADV7511_REG_INT(1), @@ -770,8 +830,6 @@ static int adv7511_parse_dt(struct device_node *np, const char *str; int ret; - memset(config, 0, sizeof(*config)); - of_property_read_u32(np, "adi,input-depth", &config->input_color_depth); if (config->input_color_depth != 8 && config->input_color_depth != 10 && config->input_color_depth != 12) @@ -853,6 +91
[PATCH 3/5] drm/i2c: adv7511: Refactor encoder slave functions
ADV7511 is represented as an i2c drm slave encoder device. ADV7533, on the other hand, is going be a normal i2c client device creating bridge and connector entities. Move the code in encoder slave functions to generate helpers that are agnostic to the drm object type. These helpers will later also be used by bridge and connecter helper functions. Signed-off-by: Archit Taneja --- drivers/gpu/drm/i2c/adv7511.c | 80 ++- 1 file changed, 57 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i2c/adv7511.c b/drivers/gpu/drm/i2c/adv7511.c index 63a3d20..46fb24d 100644 --- a/drivers/gpu/drm/i2c/adv7511.c +++ b/drivers/gpu/drm/i2c/adv7511.c @@ -612,13 +612,11 @@ static int adv7511_get_edid_block(void *data, u8 *buf, unsigned int block, } /* - - * Encoder operations + * ADV75xx helpers */ - -static int adv7511_get_modes(struct drm_encoder *encoder, -struct drm_connector *connector) +static int adv7511_get_modes(struct adv7511 *adv7511, + struct drm_connector *connector) { - struct adv7511 *adv7511 = encoder_to_adv7511(encoder); struct edid *edid; unsigned int count; @@ -656,21 +654,10 @@ static int adv7511_get_modes(struct drm_encoder *encoder, return count; } -static void adv7511_encoder_dpms(struct drm_encoder *encoder, int mode) -{ - struct adv7511 *adv7511 = encoder_to_adv7511(encoder); - - if (mode == DRM_MODE_DPMS_ON) - adv7511_power_on(adv7511); - else - adv7511_power_off(adv7511); -} - static enum drm_connector_status -adv7511_encoder_detect(struct drm_encoder *encoder, +adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector) { - struct adv7511 *adv7511 = encoder_to_adv7511(encoder); enum drm_connector_status status; unsigned int val; bool hpd; @@ -694,7 +681,7 @@ adv7511_encoder_detect(struct drm_encoder *encoder, if (status == connector_status_connected && hpd && adv7511->powered) { regcache_mark_dirty(adv7511->regmap); adv7511_power_on(adv7511); - adv7511_get_modes(encoder, connector); + adv7511_get_modes(adv7511, connector); if (adv7511->status == connector_status_connected) status = connector_status_disconnected; } else { @@ -708,8 +695,8 @@ adv7511_encoder_detect(struct drm_encoder *encoder, return status; } -static int adv7511_encoder_mode_valid(struct drm_encoder *encoder, - struct drm_display_mode *mode) +static int adv7511_mode_valid(struct adv7511 *adv7511, +const struct drm_display_mode *mode) { if (mode->clock > 165000) return MODE_CLOCK_HIGH; @@ -717,11 +704,10 @@ static int adv7511_encoder_mode_valid(struct drm_encoder *encoder, return MODE_OK; } -static void adv7511_encoder_mode_set(struct drm_encoder *encoder, +static void adv7511_mode_set(struct adv7511 *adv7511, struct drm_display_mode *mode, struct drm_display_mode *adj_mode) { - struct adv7511 *adv7511 = encoder_to_adv7511(encoder); unsigned int low_refresh_rate; unsigned int hsync_polarity = 0; unsigned int vsync_polarity = 0; @@ -812,12 +798,60 @@ static void adv7511_encoder_mode_set(struct drm_encoder *encoder, adv7511->f_tmds = mode->clock; } +/* - + * Encoder operations + */ + +static int adv7511_encoder_get_modes(struct drm_encoder *encoder, +struct drm_connector *connector) +{ + struct adv7511 *adv7511 = encoder_to_adv7511(encoder); + + return adv7511_get_modes(adv7511, connector); +} + +static void adv7511_encoder_dpms(struct drm_encoder *encoder, int mode) +{ + struct adv7511 *adv7511 = encoder_to_adv7511(encoder); + + if (mode == DRM_MODE_DPMS_ON) + adv7511_power_on(adv7511); + else + adv7511_power_off(adv7511); +} + +static enum drm_connector_status +adv7511_encoder_detect(struct drm_encoder *encoder, + struct drm_connector *connector) +{ + struct adv7511 *adv7511 = encoder_to_adv7511(encoder); + + return adv7511_detect(adv7511, connector); +} + +static int adv7511_encoder_mode_valid(struct drm_encoder *encoder, + struct drm_display_mode *mode) +{ + struct adv7511 *adv7511 = encoder_to_adv7511(encoder); + + return adv7511_mode_valid(adv7511, mode); +} + +static void adv7511_encoder_mode_set(struct drm_encoder *encoder, +struct drm_display_mode *mode, +
[PATCH 4/5] drm/i2c: adv7511: Add drm_bridge/connector for ADV7533
Create bridge and connector helper functions. These internally refer to the ADV75xx helper functions. The driver registers a drm_bridge object during probe. The bridge, in turn registers a HDMI connector when a user attaches the bridge. Therefore, when the device type is ADV7533, we create bridge and connector entities, and when it's ADV7511, we create a slave encoder as before. Since the i2c driver is still wrapped around by the drm_i2c_slave_encoder struct. We make sure the encoder_init op returns an error when the device type is ADV7533. Signed-off-by: Archit Taneja --- drivers/gpu/drm/i2c/adv7511.c | 155 ++ 1 file changed, 155 insertions(+) diff --git a/drivers/gpu/drm/i2c/adv7511.c b/drivers/gpu/drm/i2c/adv7511.c index 46fb24d..10642e1 100644 --- a/drivers/gpu/drm/i2c/adv7511.c +++ b/drivers/gpu/drm/i2c/adv7511.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include "adv7511.h" @@ -44,6 +46,9 @@ struct adv7511 { wait_queue_head_t wq; struct drm_encoder *encoder; + struct drm_connector connector; + struct drm_bridge bridge; + bool embedded_sync; enum adv7511_sync_polarity vsync_polarity; enum adv7511_sync_polarity hsync_polarity; @@ -855,6 +860,139 @@ static struct drm_encoder_slave_funcs adv7511_encoder_funcs = { }; /* - + * Bridge and connector functions + */ + +static struct adv7511 *connector_to_adv7511(struct drm_connector *connector) +{ + return container_of(connector, struct adv7511, connector); +} + +/* Connector helper functions */ +static int adv7533_connector_get_modes(struct drm_connector *connector) +{ + struct adv7511 *adv = connector_to_adv7511(connector); + + return adv7511_get_modes(adv, connector); +} + +static struct drm_encoder * +adv7533_connector_best_encoder(struct drm_connector *connector) +{ + struct adv7511 *adv = connector_to_adv7511(connector); + + return adv->bridge.encoder; +} + +static enum drm_mode_status +adv7533_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + struct adv7511 *adv = connector_to_adv7511(connector); + + return adv7511_mode_valid(adv, mode); +} + +static struct drm_connector_helper_funcs adv7533_connector_helper_funcs = { + .get_modes = adv7533_connector_get_modes, + .best_encoder = adv7533_connector_best_encoder, + .mode_valid = adv7533_connector_mode_valid, +}; + +static enum drm_connector_status +adv7533_connector_detect(struct drm_connector *connector, bool force) +{ + struct adv7511 *adv = connector_to_adv7511(connector); + + return adv7511_detect(adv, connector); +} + +static struct drm_connector_funcs adv7533_connector_funcs = { + .dpms = drm_helper_connector_dpms, + .fill_modes = drm_helper_probe_single_connector_modes, + .detect = adv7533_connector_detect, + .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, +}; + +/* Bridge funcs */ +static struct adv7511 *bridge_to_adv7511(struct drm_bridge *bridge) +{ + return container_of(bridge, struct adv7511, bridge); +} + +static void adv7533_bridge_pre_enable(struct drm_bridge *bridge) +{ + struct adv7511 *adv = bridge_to_adv7511(bridge); + + adv7511_power_on(adv); +} + +static void adv7533_bridge_post_disable(struct drm_bridge *bridge) +{ + struct adv7511 *adv = bridge_to_adv7511(bridge); + + adv7511_power_off(adv); +} + +static void adv7533_bridge_enable(struct drm_bridge *bridge) +{ +} + +static void adv7533_bridge_disable(struct drm_bridge *bridge) +{ +} + +static void adv7533_bridge_mode_set(struct drm_bridge *bridge, +struct drm_display_mode *mode, +struct drm_display_mode *adj_mode) +{ + struct adv7511 *adv = bridge_to_adv7511(bridge); + + adv7511_mode_set(adv, mode, adj_mode); +} + +static int adv7533_bridge_attach(struct drm_bridge *bridge) +{ + struct adv7511 *adv = bridge_to_adv7511(bridge); + int ret; + + adv->encoder = bridge->encoder; + + if (!bridge->encoder) { + DRM_ERROR("Parent encoder object not found"); + return -ENODEV; + } + + adv->connector.polled = DRM_CONNECTOR_POLL_HPD; + ret = drm_connector_init(bridge->dev, &adv->connector, + &adv7533_connector_funcs, DRM_MODE_CONNECTOR_HDMIA); + if (ret) { + DRM_ERROR("Failed to initialize connector with drm\n"); + return ret; + } + drm_connector_helper_add(&adv->connector, + &adv7533_connector_hel
[PATCH 5/5] drm/i2c: adv7511: Create mipi_dsi_device for ADV7533
In order to pass DSI specific parameters to the DSI host, we need the driver to create a mipi_dsi_device that attaches to the host. Use of_graph helpers to get the DSI host DT node. Create a dummy dsi device using this host. Finally, attach this device to the host. Populate few other DT parameters (number of data lanes etc) that are required for DSI RX to work correctly. Hardcode few other parameters (rgb, embedded_sync) for now. Signed-off-by: Archit Taneja --- drivers/gpu/drm/i2c/adv7511.c | 106 +++--- 1 file changed, 99 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i2c/adv7511.c b/drivers/gpu/drm/i2c/adv7511.c index 10642e1..ccb57a9 100644 --- a/drivers/gpu/drm/i2c/adv7511.c +++ b/drivers/gpu/drm/i2c/adv7511.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -19,6 +20,7 @@ #include #include #include +#include #include "adv7511.h" @@ -58,6 +60,11 @@ struct adv7511 { struct gpio_desc *gpio_pd; + /* ADV7533 DSI RX related params */ + struct device_node *host_node; + struct mipi_dsi_device *dsi; + u8 num_dsi_lanes; + enum adv7511_type type; }; @@ -403,8 +410,10 @@ static void adv7511_dsi_receiver_dpms(struct adv7511 *adv7511) return; if (adv7511->powered) { - /* set number of dsi lanes (hardcoded to 4 for now) */ - regmap_write(adv7511->regmap_cec, 0x1c, 0x4 << 4); + struct mipi_dsi_device *dsi = adv7511->dsi; + + /* set number of dsi lanes */ + regmap_write(adv7511->regmap_cec, 0x1c, dsi->lanes << 4); /* disable internal timing generator */ regmap_write(adv7511->regmap_cec, 0x27, 0x0b); /* enable hdmi */ @@ -954,6 +963,48 @@ static void adv7533_bridge_mode_set(struct drm_bridge *bridge, adv7511_mode_set(adv, mode, adj_mode); } +static int adv7533_attach_dsi(struct adv7511 *adv7511) +{ + struct device *dev = &adv7511->i2c_main->dev; + struct mipi_dsi_device *dsi; + struct mipi_dsi_host *host; + int ret; + + host = of_find_mipi_dsi_host_by_node(adv7511->host_node); + if (!host) { + dev_err(dev, "failed to find dsi host\n"); + return -EPROBE_DEFER; + } + + /* can adv7533 virtual channel be non-zero? */ + dsi = mipi_dsi_new_dummy(host, 0); + if (IS_ERR(dsi)) { + dev_err(dev, "failed to create dummy dsi device\n"); + ret = PTR_ERR(dsi); + goto err_dsi_device; + } + + adv7511->dsi = dsi; + + dsi->lanes = adv7511->num_dsi_lanes; + dsi->format = MIPI_DSI_FMT_RGB888; + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE + | MIPI_DSI_MODE_EOT_PACKET | MIPI_DSI_MODE_VIDEO_HSE; + + ret = mipi_dsi_attach(dsi); + if (ret < 0) { + dev_err(dev, "failed to attach dsi to host\n"); + goto err_dsi_attach; + } + + return 0; + +err_dsi_attach: + mipi_dsi_unregister_device(dsi); +err_dsi_device: + return ret; +} + static int adv7533_bridge_attach(struct drm_bridge *bridge) { struct adv7511 *adv = bridge_to_adv7511(bridge); @@ -980,6 +1031,8 @@ static int adv7533_bridge_attach(struct drm_bridge *bridge) drm_helper_hpd_irq_event(adv->connector.dev); + adv7533_attach_dsi(adv); + return ret; } @@ -1079,6 +1132,41 @@ static int adv7511_parse_dt(struct device_node *np, return 0; } +static int adv7533_parse_dt(struct device_node *np, struct adv7511 *adv7511) +{ + u32 num_lanes; + struct device_node *endpoint; + + of_property_read_u32(np, "adi,dsi-lanes", &num_lanes); + + if (num_lanes < 1 || num_lanes > 4) + return -EINVAL; + + adv7511->num_dsi_lanes = num_lanes; + + endpoint = of_graph_get_next_endpoint(np, NULL); + if (!endpoint) { + DRM_ERROR("adv dsi input endpoint not found\n"); + return -ENODEV; + } + + adv7511->host_node = of_graph_get_remote_port_parent(endpoint); + if (!adv7511->host_node) { + DRM_ERROR("dsi host node not found\n"); + of_node_put(endpoint); + return -ENODEV; + } + + of_node_put(endpoint); + of_node_put(adv7511->host_node); + + /* TODO: Check if these need to be parsed by DT or not */ + adv7511->rgb = true; + adv7511->embedded_sync = false; + + return 0; +} + static const int edid_i2c_addr = 0x7e; static const int packet_i2c_addr = 0x70; static const int cec_i2c_addr = 0x78; @@ -1121,11 +1209,12 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) memset(&link_config, 0, sizeof(link_config)); - if (adv7511->type == ADV7511) { + if (adv7511->type == ADV7511)
[Bug 91302] radeon.audio=1 causes issues with 7950
https://bugs.freedesktop.org/show_bug.cgi?id=91302 Christian König changed: What|Removed |Added Component|Driver/Radeon |DRM/Radeon Assignee|xorg-driver-ati at lists.x.org |dri-devel at lists.freedesktop ||.org Product|xorg|DRI QA Contact|xorg-team at lists.x.org | -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150727/c11fb130/attachment.html>
[Intel-gfx] [PATCH v2 12/25] i915: switch from acpi_os_ioremap to ioremap
On Fri, Jul 24, 2015 at 10:39:04PM -0400, Dan Williams wrote: > acpi_os_ioremap uses cached mappings, however it appears that i915 > wants to read dynamic platform state. Switch to ioremap() to prevent it > reading stale state from cache. > > Cc: Daniel Vetter > Cc: Jani Nikula > Cc: intel-gfx at lists.freedesktop.org > Cc: David Airlie > Cc: dri-devel at lists.freedesktop.org > Signed-off-by: Dan Williams > --- > drivers/gpu/drm/i915/intel_opregion.c |2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/intel_opregion.c > b/drivers/gpu/drm/i915/intel_opregion.c > index 481337436f72..16ba7c67410d 100644 > --- a/drivers/gpu/drm/i915/intel_opregion.c > +++ b/drivers/gpu/drm/i915/intel_opregion.c > @@ -863,7 +863,7 @@ int intel_opregion_setup(struct drm_device *dev) > INIT_WORK(&opregion->asle_work, asle_work); > #endif > > - base = acpi_os_ioremap(asls, OPREGION_SIZE); > + base = ioremap(asls, OPREGION_SIZE); OpRegion is cached memory shared with the firmware afaik, we probably want a memremap here and switch away from the ioread/write stuff. We have a similar confusion going on for the vbt parsing (which on anything but really old machines is also just normal memory). Same holds for gma500, which is just a copy of i915 for some special platforms. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
[Intel-gfx] [PATCH v1.1 2/5] drm/atomic: Make prepare_fb/cleanup_fb only take state, v2.
On Wed, Jul 22, 2015 at 09:23:27AM -0400, Rob Clark wrote: > On Thu, Jul 16, 2015 at 10:13 AM, Maarten Lankhorst > wrote: > > This removes the need to separately track fb changes i915. > > > > Changes since v1: > > - Add dri-devel to cc. > > - Fix a check in intel's prepare and cleanup fb to take rotation > > into account. > > > > Cc: dri-devel at lists.freedesktop.org > > Signed-off-by: Maarten Lankhorst > > Reviewed-by: Rob Clark Applied to drm-misc, thanks. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
[PATCH 3/5] drm/i2c: adv7511: Refactor encoder slave functions
Hi Archit, (CC'ing Boris Brezillon) Thank you for the patch. On Monday 27 July 2015 11:46:57 Archit Taneja wrote: > ADV7511 is represented as an i2c drm slave encoder device. ADV7533, on > the other hand, is going be a normal i2c client device creating bridge > and connector entities. Please, no. It's really time to stop piling hacks and fix the problem properly. There's no reason to have separate APIs for I2C slave encoders and DRM bridges. Those two APIs need to be merged, and then you'll find it much easier to implement ADV7533 support. Boris, I know you were experimenting with that, do you have anything to report ? > Move the code in encoder slave functions to generate helpers that are > agnostic to the drm object type. These helpers will later also be used > by bridge and connecter helper functions. > > Signed-off-by: Archit Taneja > --- > drivers/gpu/drm/i2c/adv7511.c | 80 +++ > 1 file changed, 57 insertions(+), 23 deletions(-) > > diff --git a/drivers/gpu/drm/i2c/adv7511.c b/drivers/gpu/drm/i2c/adv7511.c > index 63a3d20..46fb24d 100644 > --- a/drivers/gpu/drm/i2c/adv7511.c > +++ b/drivers/gpu/drm/i2c/adv7511.c > @@ -612,13 +612,11 @@ static int adv7511_get_edid_block(void *data, u8 *buf, > unsigned int block, } > > /* > --- > -- - * Encoder operations > + * ADV75xx helpers > */ > - > -static int adv7511_get_modes(struct drm_encoder *encoder, > - struct drm_connector *connector) > +static int adv7511_get_modes(struct adv7511 *adv7511, > + struct drm_connector *connector) > { > - struct adv7511 *adv7511 = encoder_to_adv7511(encoder); > struct edid *edid; > unsigned int count; > > @@ -656,21 +654,10 @@ static int adv7511_get_modes(struct drm_encoder > *encoder, return count; > } > > -static void adv7511_encoder_dpms(struct drm_encoder *encoder, int mode) > -{ > - struct adv7511 *adv7511 = encoder_to_adv7511(encoder); > - > - if (mode == DRM_MODE_DPMS_ON) > - adv7511_power_on(adv7511); > - else > - adv7511_power_off(adv7511); > -} > - > static enum drm_connector_status > -adv7511_encoder_detect(struct drm_encoder *encoder, > +adv7511_detect(struct adv7511 *adv7511, > struct drm_connector *connector) > { > - struct adv7511 *adv7511 = encoder_to_adv7511(encoder); > enum drm_connector_status status; > unsigned int val; > bool hpd; > @@ -694,7 +681,7 @@ adv7511_encoder_detect(struct drm_encoder *encoder, > if (status == connector_status_connected && hpd && adv7511->powered) { > regcache_mark_dirty(adv7511->regmap); > adv7511_power_on(adv7511); > - adv7511_get_modes(encoder, connector); > + adv7511_get_modes(adv7511, connector); > if (adv7511->status == connector_status_connected) > status = connector_status_disconnected; > } else { > @@ -708,8 +695,8 @@ adv7511_encoder_detect(struct drm_encoder *encoder, > return status; > } > > -static int adv7511_encoder_mode_valid(struct drm_encoder *encoder, > - struct drm_display_mode *mode) > +static int adv7511_mode_valid(struct adv7511 *adv7511, > + const struct drm_display_mode *mode) > { > if (mode->clock > 165000) > return MODE_CLOCK_HIGH; > @@ -717,11 +704,10 @@ static int adv7511_encoder_mode_valid(struct > drm_encoder *encoder, return MODE_OK; > } > > -static void adv7511_encoder_mode_set(struct drm_encoder *encoder, > +static void adv7511_mode_set(struct adv7511 *adv7511, >struct drm_display_mode *mode, >struct drm_display_mode *adj_mode) > { > - struct adv7511 *adv7511 = encoder_to_adv7511(encoder); > unsigned int low_refresh_rate; > unsigned int hsync_polarity = 0; > unsigned int vsync_polarity = 0; > @@ -812,12 +798,60 @@ static void adv7511_encoder_mode_set(struct > drm_encoder *encoder, adv7511->f_tmds = mode->clock; > } > > +/* > --- > -- + * Encoder operations > + */ > + > +static int adv7511_encoder_get_modes(struct drm_encoder *encoder, > + struct drm_connector *connector) > +{ > + struct adv7511 *adv7511 = encoder_to_adv7511(encoder); > + > + return adv7511_get_modes(adv7511, connector); > +} > + > +static void adv7511_encoder_dpms(struct drm_encoder *encoder, int mode) > +{ > + struct adv7511 *adv7511 = encoder_to_adv7511(encoder); > + > + if (mode == DRM_MODE_DPMS_ON) > + adv7511_power_on(adv7511); > + else > + adv7511_power_off(adv7511); > +} > + > +static enum drm_connector_status > +adv7511_encoder_detect(struct drm_encoder *encoder, > +
[PATCH 2/2] drm/i915: Switch a couple of BUG_ONs in the cmdparser over to DRM_ERROR
No need to break module and system loading due to a programming bug. Remove the BUG_ON and replace with a gentler DRM_ERROR_ON and error return. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_cmd_parser.c | 11 --- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index fd9abe6e0ab1..dcd096536119 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -738,11 +738,16 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *ring) default: DRM_ERROR("CMD: cmd_parser_init with unknown ring: %d\n", ring->id); - BUG(); + return -ENODEV; } - BUG_ON(!validate_cmds_sorted(ring, cmd_tables, cmd_table_count)); - BUG_ON(!validate_regs_sorted(ring)); + if (DRM_ERROR_ON(!validate_cmds_sorted(ring, cmd_tables, cmd_table_count), +"command parser table is not sorted - required for bisetion searching\n")) + return -ENODEV; + + if (DRM_ERROR_ON(!validate_regs_sorted(ring), +"register lists are not sorted - required for bisection searching\n")) + return -ENODEV; WARN_ON(!hash_empty(ring->cmd_hash)); -- 2.4.6
[PATCH 1/2] drm: Add DRM_ERROR_ON replacement for WARN_ON
i915 has a habit of using WARN_ON and spewing stacktraces into the kernel logs and beyond. For the majority of cases, we do not care about the stacktrace, we know precisely where and when the error occurs so hunting down the exact instance is not a concern, we only need the content of the error. Signed-off-by: Chris Wilson --- include/drm/drmP.h | 17 + 1 file changed, 17 insertions(+) diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 4717449d6aa9..b76af322d812 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -164,6 +164,23 @@ void drm_err(const char *format, ...); drm_err(fmt, ##__VA_ARGS__) /** + * Assertion-esque error output. + * + * \param cond condition on which to *fail* + * \param fmt printf() like format string. + * \param arg arguments + * + * This is similar to WARN_ON but only prints a DRM_ERROR rather than a whole + * stacktrace. + */ +#define DRM_ERROR_ON(cond, fmt, ...) ({ \ + bool __cond = !!(cond); \ + if (unlikely(__cond)) \ + drm_err("assertion failed, %s: " fmt, #cond, ##__VA_ARGS__); \ + unlikely(__cond); \ +}) + +/** * Rate limited error output. Like DRM_ERROR() but won't flood the log. * * \param fmt printf() like format string. -- 2.4.6
[PATCH] intel: wrap intel_bufmgr.h C code for C++ compilation/linking
On 07/03/2015 06:44 PM, Emil Velikov wrote: > On 01/07/15 12:37, Tapani Pälli wrote: >> (We need this include in porting changes for the OpenGL ES >> conformance suite.) >> >> Signed-off-by: Tapani Pälli >> --- >> intel/intel_bufmgr.h | 8 >> 1 file changed, 8 insertions(+) >> >> diff --git a/intel/intel_bufmgr.h b/intel/intel_bufmgr.h >> index 285919e..f061454 100644 >> --- a/intel/intel_bufmgr.h >> +++ b/intel/intel_bufmgr.h >> @@ -38,6 +38,10 @@ >> #include >> #include >> >> +#if defined(__cplusplus) || defined(c_plusplus) >> +extern "C" { >> +#endif >> + > Strongly in favour - I've been pondering on this for a very long time. > Just a question - is there a compiler that care about (something from > the last decade) that does not define __cplusplus but c_plusplus ? I don't know, this was just copy paste from other file. > Afaict the former is defined since (at least) the 1998 C++ standard, > while the latter is extremely rare, and mostly mentioned as decrecated. For me it is ok to drop c_plusplus, no strong opinion. > -Emil > // Tapani
[PATCH v3 0/2] RFC: Secure Memory Allocation Framework
Hi all, This thread doesn't get any feedback... What would be great is to know if this framework proposal fir with your platform needs. Maybe I haven't copy the good mailing lists so if you think there is better ones do not hesitate to forward. Regards, Benjamin 2015-07-10 14:28 GMT+02:00 Benjamin Gaignard : > version 3 changes: > - Remove ioctl for allocator selection instead provide the name of >the targeted allocator with allocation request. >Selecting allocator from userland isn't the prefered way of working >but is needed when the first user of the buffer is a software component. > - Fix issues in case of error while creating smaf handle. > - Fix module license. > - Update libsmaf and tests to care of the SMAF API evolution >https://git.linaro.org/people/benjamin.gaignard/libsmaf.git > > version 2 changes: > - Add one ioctl to allow allocator selection from userspace. >This is required for the uses case where the first user of >the buffer is a software IP which can't perform dma_buf attachement. > - Add name and ranking to allocator structure to be able to sort them. > - Create a tiny library to test SMAF: >https://git.linaro.org/people/benjamin.gaignard/libsmaf.git > - Fix one issue when try to secure buffer without secure module registered > > The outcome of the previous RFC about how do secure data path was the need > of a secure memory allocator (https://lkml.org/lkml/2015/5/5/551) > > SMAF goal is to provide a framework that allow allocating and securing > memory by using dma_buf. Each platform have it own way to perform those two > features so SMAF design allow to register helper modules to perform them. > > To be sure to select the best allocation method for devices SMAF implement > deferred allocation mechanism: memory allocation is only done when the first > device effectively required it. > Allocator modules have to implement a match() to let SMAF know if they are > compatibles with devices needs. > This patch set provide an example of allocator module which use > dma_{alloc/free/mmap}_attrs() and check if at least one device have > coherent_dma_mask set to DMA_BIT_MASK(32) in match function. > I have named smaf-cma.c like it is done for drm_gem_cma_helper.c even if > a better name could be found for this file. > > Secure modules are responsibles of granting and revoking devices access rights > on the memory. Secure module is also called to check if CPU map memory into > kernel and user address spaces. > An example of secure module implementation can be found here: > http://git.linaro.org/people/benjamin.gaignard/optee-sdp.git > This code isn't yet part of the patch set because it depends on generic TEE > which is still under discussion (https://lwn.net/Articles/644646/) > > For allocation part of SMAF code I get inspirated by Sumit Semwal work about > constraint aware allocator. > > Benjamin Gaignard (2): > create SMAF module > SMAF: add CMA allocator > > drivers/Kconfig| 2 + > drivers/Makefile | 1 + > drivers/smaf/Kconfig | 11 + > drivers/smaf/Makefile | 2 + > drivers/smaf/smaf-cma.c| 200 +++ > drivers/smaf/smaf-core.c | 735 > + > include/linux/smaf-allocator.h | 54 +++ > include/linux/smaf-secure.h| 62 > include/uapi/linux/smaf.h | 52 +++ > 9 files changed, 1119 insertions(+) > create mode 100644 drivers/smaf/Kconfig > create mode 100644 drivers/smaf/Makefile > create mode 100644 drivers/smaf/smaf-cma.c > create mode 100644 drivers/smaf/smaf-core.c > create mode 100644 include/linux/smaf-allocator.h > create mode 100644 include/linux/smaf-secure.h > create mode 100644 include/uapi/linux/smaf.h > > -- > 1.9.1 > -- Benjamin Gaignard Graphic Working Group Linaro.org â Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog
[PATCH v1.1 02/13] drm/atomic: Update legacy DPMS state during modesets, v2.
This is required for DPMS to work correctly, during a modeset the DPMS property should be turned off, unless the state is crtc is made active in which case it should be set to DPMS on. The legacy dpms handling performs its own dpms updates, so add a property to prevent updating the legacy dpms state and use it in the atomic dpms helpers and i915 suspend/resume. Changes since v1: - Set DPMS to off when a connector is removed from a crtc too. - Update the legacy dpms property too. - Add an exception for the legacy dpms paths, it updates its own state. - Add an exception for i915 suspend/resume, it should preserve dpms state. Cc: dri-devel at lists.freedesktop.org Signed-off-by: Maarten Lankhorst --- diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 5ec13c7cc832..f463f8ce8f4d 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -660,15 +660,33 @@ drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev, struct drm_crtc_state *old_crtc_state; int i; - /* clear out existing links */ + /* clear out existing links and update dpms */ for_each_connector_in_state(old_state, connector, old_conn_state, i) { - if (!connector->encoder) + if (connector->encoder) { + WARN_ON(!connector->encoder->crtc); + + connector->encoder->crtc = NULL; + connector->encoder = NULL; + } + + if (old_state->preserve_dpms) continue; - WARN_ON(!connector->encoder->crtc); + crtc = connector->state->crtc; - connector->encoder->crtc = NULL; - connector->encoder = NULL; + if ((!crtc && old_conn_state->crtc) || + (crtc && drm_atomic_crtc_needs_modeset(crtc->state))) { + struct drm_property *dpms_prop = + dev->mode_config.dpms_property; + int mode = DRM_MODE_DPMS_OFF; + + if (crtc && crtc->state->active) + mode = DRM_MODE_DPMS_ON; + + connector->dpms = mode; + drm_object_property_set_value(&connector->base, + dpms_prop, mode); + } } /* set new links */ @@ -2001,6 +2019,7 @@ void drm_atomic_helper_connector_dpms(struct drm_connector *connector, return; state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc); + state->preserve_dpms = true; retry: crtc_state = drm_atomic_get_crtc_state(state, crtc); if (IS_ERR(crtc_state)) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 28ff75bc9e04..4e49b6667ffa 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6246,7 +6246,7 @@ int intel_display_suspend(struct drm_device *dev) return -ENOMEM; state->acquire_ctx = ctx; - state->allow_modeset = true; + state->preserve_dpms = true; for_each_crtc(dev, crtc) { struct drm_crtc_state *crtc_state = @@ -6309,7 +6309,7 @@ int intel_crtc_control(struct drm_crtc *crtc, bool enable) return -ENOMEM; state->acquire_ctx = ctx; - state->allow_modeset = true; + state->preserve_dpms = true; pipe_config = intel_atomic_get_crtc_state(state, intel_crtc); if (IS_ERR(pipe_config)) { @@ -12358,16 +12358,9 @@ intel_modeset_update_state(struct drm_atomic_state *state) continue; if (crtc->state->active) { - struct drm_property *dpms_property = - dev->mode_config.dpms_property; - - connector->dpms = DRM_MODE_DPMS_ON; - drm_object_property_set_value(&connector->base, dpms_property, DRM_MODE_DPMS_ON); - intel_encoder = to_intel_encoder(connector->encoder); intel_encoder->connectors_active = true; - } else - connector->dpms = DRM_MODE_DPMS_OFF; + } } } @@ -15417,6 +15410,7 @@ void intel_display_resume(struct drm_device *dev) return; state->acquire_ctx = dev->mode_config.acquire_ctx; + state->preserve_dpms = true; /* preserve complete old state, including dpll */ intel_atomic_get_shared_dpll_state(state); diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 90a0ff70384a..64d49307c76d 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -937,6 +937,7 @@ struct drm_bridge { * @dev: parent DRM device * @allow_modeset: allow full modeset * @legacy_cursor_update: hint to enforce legacy cursor ioctl semanti
[Intel-gfx] [PATCH v1.1 2/5] drm/atomic: Make prepare_fb/cleanup_fb only take state, v2.
Op 27-07-15 om 09:53 schreef Daniel Vetter: > On Wed, Jul 22, 2015 at 09:23:27AM -0400, Rob Clark wrote: >> On Thu, Jul 16, 2015 at 10:13 AM, Maarten Lankhorst >> wrote: >>> This removes the need to separately track fb changes i915. >>> >>> Changes since v1: >>> - Add dri-devel to cc. >>> - Fix a check in intel's prepare and cleanup fb to take rotation >>> into account. >>> >>> Cc: dri-devel at lists.freedesktop.org >>> Signed-off-by: Maarten Lankhorst >> Reviewed-by: Rob Clark > Applied to drm-misc, thanks. > -Daniel This one needs i915 converted to atomic first, or dpms will fail. :(
[Intel-gfx] [PATCH v1.1 2/5] drm/atomic: Make prepare_fb/cleanup_fb only take state, v2.
On Mon, Jul 27, 2015 at 01:07:37PM +0200, Maarten Lankhorst wrote: > Op 27-07-15 om 09:53 schreef Daniel Vetter: > > On Wed, Jul 22, 2015 at 09:23:27AM -0400, Rob Clark wrote: > >> On Thu, Jul 16, 2015 at 10:13 AM, Maarten Lankhorst > >> wrote: > >>> This removes the need to separately track fb changes i915. > >>> > >>> Changes since v1: > >>> - Add dri-devel to cc. > >>> - Fix a check in intel's prepare and cleanup fb to take rotation > >>> into account. > >>> > >>> Cc: dri-devel at lists.freedesktop.org > >>> Signed-off-by: Maarten Lankhorst > >> Reviewed-by: Rob Clark > > Applied to drm-misc, thanks. > > -Daniel > This one needs i915 converted to atomic first, or dpms will fail. :( Yeah I dropped it again, since it also does some shuffling in i915 code. That should be done in a split-out patch so that this one here really only removes the fb parameter. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
[PATCH v1.1 02/13] drm/atomic: Update legacy DPMS state during modesets, v2.
On Mon, Jul 27, 2015 at 01:04:20PM +0200, Maarten Lankhorst wrote: > This is required for DPMS to work correctly, during a modeset > the DPMS property should be turned off, unless the state is > crtc is made active in which case it should be set to DPMS on. > > The legacy dpms handling performs its own dpms updates, so add a > property to prevent updating the legacy dpms state and use it > in the atomic dpms helpers and i915 suspend/resume. > > Changes since v1: > - Set DPMS to off when a connector is removed from a crtc too. > - Update the legacy dpms property too. > - Add an exception for the legacy dpms paths, it updates its own state. > - Add an exception for i915 suspend/resume, it should preserve dpms state. My idea behind updating the dpms prop was to not confuse legacy userspace. And legacy userspace always does an all-or-nothing dpms over all connectors anyway, so I don't think we need to go to any length to preserve that. If we'd need to we won't be able to move dpms from connector to the crtc anyway. Therefore I think preserve_dpms isn't needed and we can drop that one. -Daniel > > Cc: dri-devel at lists.freedesktop.org > Signed-off-by: Maarten Lankhorst > --- > diff --git a/drivers/gpu/drm/drm_atomic_helper.c > b/drivers/gpu/drm/drm_atomic_helper.c > index 5ec13c7cc832..f463f8ce8f4d 100644 > --- a/drivers/gpu/drm/drm_atomic_helper.c > +++ b/drivers/gpu/drm/drm_atomic_helper.c > @@ -660,15 +660,33 @@ drm_atomic_helper_update_legacy_modeset_state(struct > drm_device *dev, > struct drm_crtc_state *old_crtc_state; > int i; > > - /* clear out existing links */ > + /* clear out existing links and update dpms */ > for_each_connector_in_state(old_state, connector, old_conn_state, i) { > - if (!connector->encoder) > + if (connector->encoder) { > + WARN_ON(!connector->encoder->crtc); > + > + connector->encoder->crtc = NULL; > + connector->encoder = NULL; > + } > + > + if (old_state->preserve_dpms) > continue; > > - WARN_ON(!connector->encoder->crtc); > + crtc = connector->state->crtc; > > - connector->encoder->crtc = NULL; > - connector->encoder = NULL; > + if ((!crtc && old_conn_state->crtc) || > + (crtc && drm_atomic_crtc_needs_modeset(crtc->state))) { > + struct drm_property *dpms_prop = > + dev->mode_config.dpms_property; > + int mode = DRM_MODE_DPMS_OFF; > + > + if (crtc && crtc->state->active) > + mode = DRM_MODE_DPMS_ON; > + > + connector->dpms = mode; > + drm_object_property_set_value(&connector->base, > + dpms_prop, mode); > + } > } > > /* set new links */ > @@ -2001,6 +2019,7 @@ void drm_atomic_helper_connector_dpms(struct > drm_connector *connector, > return; > > state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc); > + state->preserve_dpms = true; > retry: > crtc_state = drm_atomic_get_crtc_state(state, crtc); > if (IS_ERR(crtc_state)) > diff --git a/drivers/gpu/drm/i915/intel_display.c > b/drivers/gpu/drm/i915/intel_display.c > index 28ff75bc9e04..4e49b6667ffa 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -6246,7 +6246,7 @@ int intel_display_suspend(struct drm_device *dev) > return -ENOMEM; > > state->acquire_ctx = ctx; > - state->allow_modeset = true; > + state->preserve_dpms = true; > > for_each_crtc(dev, crtc) { > struct drm_crtc_state *crtc_state = > @@ -6309,7 +6309,7 @@ int intel_crtc_control(struct drm_crtc *crtc, bool > enable) > return -ENOMEM; > > state->acquire_ctx = ctx; > - state->allow_modeset = true; > + state->preserve_dpms = true; > > pipe_config = intel_atomic_get_crtc_state(state, intel_crtc); > if (IS_ERR(pipe_config)) { > @@ -12358,16 +12358,9 @@ intel_modeset_update_state(struct drm_atomic_state > *state) > continue; > > if (crtc->state->active) { > - struct drm_property *dpms_property = > - dev->mode_config.dpms_property; > - > - connector->dpms = DRM_MODE_DPMS_ON; > - drm_object_property_set_value(&connector->base, > dpms_property, DRM_MODE_DPMS_ON); > - > intel_encoder = to_intel_encoder(connector->encoder); > intel_encoder->connectors_active = true; > - } else > - connector->dpms = DRM_MODE_DPMS_OFF; > + } > } > } > > @@ -15417,6 +15410,7 @@ void intel_display_resume(struct drm_dev
[PATCH v1.1 02/13] drm/atomic: Update legacy DPMS state during modesets, v2.
Op 27-07-15 om 13:16 schreef Daniel Vetter: > On Mon, Jul 27, 2015 at 01:04:20PM +0200, Maarten Lankhorst wrote: >> This is required for DPMS to work correctly, during a modeset >> the DPMS property should be turned off, unless the state is >> crtc is made active in which case it should be set to DPMS on. >> >> The legacy dpms handling performs its own dpms updates, so add a >> property to prevent updating the legacy dpms state and use it >> in the atomic dpms helpers and i915 suspend/resume. >> >> Changes since v1: >> - Set DPMS to off when a connector is removed from a crtc too. >> - Update the legacy dpms property too. >> - Add an exception for the legacy dpms paths, it updates its own state. >> - Add an exception for i915 suspend/resume, it should preserve dpms state. > My idea behind updating the dpms prop was to not confuse legacy userspace. > And legacy userspace always does an all-or-nothing dpms over all > connectors anyway, so I don't think we need to go to any length to > preserve that. If we'd need to we won't be able to move dpms from > connector to the crtc anyway. Therefore I think preserve_dpms isn't needed > and we can drop that one. > In that case I'll respin..
[PULL] topic/crc-pmic
On Thu, Jul 23, 2015 at 09:38:46AM +0200, Daniel Vetter wrote: [...] > On Thu, Jul 23, 2015 at 9:31 AM, Daniel Vetter > wrote: [...] > > Shobhit Kumar (8): [...] > > pwm: crc: Add Crystalcove (CRC) PWM driver Would you mind removing this from your branch? I ended up manually applying a couple of changes that I had requested but ended up not getting addressed. When you drop it, let me know so I can push my branch to -next and have it not collide with your tree immediately. I assume it's in a branch that feeds into linux-next? Thierry -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150727/53dbffe5/attachment.sig>
[PATCH 1/7] drm: Fix DP_TEST_COUNT_MASK
On Thu, Jul 23, 2015 at 04:34:58PM -0700, Rodrigo Vivi wrote: > By Vesa's DP 1.2 Spec this counter has 4 bits [3:0]. > > This mask is wrong since when the counter was introduced by myself > on commit ad9dc91b6e21266bfc6f466db4b95e10211f31ee > Author: Rodrigo Vivi > Date: Tue Sep 16 19:18:12 2014 -0400 > > drm/i915: Fix Sink CRC > > Signed-off-by: Rodrigo Vivi > --- > include/drm/drm_dp_helper.h | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h > index 2e86f64..94898f6 100644 > --- a/include/drm/drm_dp_helper.h > +++ b/include/drm/drm_dp_helper.h > @@ -420,7 +420,7 @@ > > #define DP_TEST_SINK_MISC0x246 > # define DP_TEST_CRC_SUPPORTED (1 << 5) > -# define DP_TEST_COUNT_MASK 0x7 > +# define DP_TEST_COUNT_MASK 0xf According to the specification this field should really be called DP_TEST_CRC_COUNT_MASK, because it counts the number of times that the TEST_CRC_* registers are updated. That could be a separate patch, though. Thierry -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150727/19f8722b/attachment.sig>
[PATCH v1.2 02/13] drm/atomic: Update legacy DPMS state during modesets, v3.
This is required for DPMS to work correctly, during a modeset the DPMS property should be turned off, unless the state is crtc is made active in which case it should be set to DPMS on. Changes since v1: - Set DPMS to off when a connector is removed from a crtc too. - Update the legacy dpms property too. - Add an exception for the legacy dpms paths, it updates its own state. Changes since v2: - Do not preserve dpms property. Cc: dri-devel at lists.freedesktop.org Signed-off-by: Maarten Lankhorst --- diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 57847ae8ce8c..0b475fae067d 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -660,15 +660,29 @@ drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev, struct drm_crtc_state *old_crtc_state; int i; - /* clear out existing links */ + /* clear out existing links and update dpms */ for_each_connector_in_state(old_state, connector, old_conn_state, i) { - if (!connector->encoder) - continue; + if (connector->encoder) { + WARN_ON(!connector->encoder->crtc); + + connector->encoder->crtc = NULL; + connector->encoder = NULL; + } - WARN_ON(!connector->encoder->crtc); + crtc = connector->state->crtc; + if ((!crtc && old_conn_state->crtc) || + (crtc && drm_atomic_crtc_needs_modeset(crtc->state))) { + struct drm_property *dpms_prop = + dev->mode_config.dpms_property; + int mode = DRM_MODE_DPMS_OFF; - connector->encoder->crtc = NULL; - connector->encoder = NULL; + if (crtc && crtc->state->active) + mode = DRM_MODE_DPMS_ON; + + connector->dpms = mode; + drm_object_property_set_value(&connector->base, + dpms_prop, mode); + } } /* set new links */ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 13a6608be689..43b0f17ad1fa 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12349,16 +12349,9 @@ intel_modeset_update_state(struct drm_atomic_state *state) continue; if (crtc->state->active) { - struct drm_property *dpms_property = - dev->mode_config.dpms_property; - - connector->dpms = DRM_MODE_DPMS_ON; - drm_object_property_set_value(&connector->base, dpms_property, DRM_MODE_DPMS_ON); - intel_encoder = to_intel_encoder(connector->encoder); intel_encoder->connectors_active = true; - } else - connector->dpms = DRM_MODE_DPMS_OFF; + } } }
[Intel-gfx] [PATCH v1.1 2/5] drm/atomic: Make prepare_fb/cleanup_fb only take state, v2.
Hey, Op 27-07-15 om 13:14 schreef Daniel Vetter: > On Mon, Jul 27, 2015 at 01:07:37PM +0200, Maarten Lankhorst wrote: >> Op 27-07-15 om 09:53 schreef Daniel Vetter: >>> On Wed, Jul 22, 2015 at 09:23:27AM -0400, Rob Clark wrote: On Thu, Jul 16, 2015 at 10:13 AM, Maarten Lankhorst wrote: > This removes the need to separately track fb changes i915. > > Changes since v1: > - Add dri-devel to cc. > - Fix a check in intel's prepare and cleanup fb to take rotation > into account. > > Cc: dri-devel at lists.freedesktop.org > Signed-off-by: Maarten Lankhorst Reviewed-by: Rob Clark >>> Applied to drm-misc, thanks. >>> -Daniel >> This one needs i915 converted to atomic first, or dpms will fail. :( > Yeah I dropped it again, since it also does some shuffling in i915 code. > That should be done in a split-out patch so that this one here really only > removes the fb parameter. > -Daniel The code shuffling is a consequence of removing the fb parameter and allowing NULL. If you want to separate it that's possible, but means returning early in prepare_plane_fb while a followup patch copes with a nil fb.
[PATCH 1/2] drm/i915: use error path
Use goto to handle the error path to avoid duplicating the same code. In the error path intel_dig_port is the last one to be released as it was the first one to be allocated and ideally the error path should be the reverse of the execution path. Signed-off-by: Sudip Mukherjee --- drivers/gpu/drm/i915/intel_dp.c | 23 ++- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f1b9f93..c084bca 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5864,10 +5864,8 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) return; intel_connector = intel_connector_alloc(); - if (!intel_connector) { - kfree(intel_dig_port); - return; - } + if (!intel_connector) + goto err_connector_alloc; intel_encoder = &intel_dig_port->base; encoder = &intel_encoder->base; @@ -5914,11 +5912,18 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) intel_dig_port->hpd_pulse = intel_dp_hpd_pulse; dev_priv->hotplug.irq_port[port] = intel_dig_port; - if (!intel_dp_init_connector(intel_dig_port, intel_connector)) { - drm_encoder_cleanup(encoder); - kfree(intel_dig_port); - kfree(intel_connector); - } + if (!intel_dp_init_connector(intel_dig_port, intel_connector)) + goto err_init_connector; + + return; + +err_init_connector: + drm_encoder_cleanup(encoder); + kfree(intel_connector); +err_connector_alloc: + kfree(intel_dig_port); + + return; } void intel_dp_mst_suspend(struct drm_device *dev) -- 1.9.1
[PATCH 2/2] drm/i915: check for return value
We were not checking the return value of drm_encoder_init() which can fail. And if it fails then we will be working with an uninitialized encoder. Signed-off-by: Sudip Mukherjee --- drivers/gpu/drm/i915/intel_dp.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c084bca..69946b7 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5870,8 +5870,9 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) intel_encoder = &intel_dig_port->base; encoder = &intel_encoder->base; - drm_encoder_init(dev, &intel_encoder->base, &intel_dp_enc_funcs, -DRM_MODE_ENCODER_TMDS); + if (drm_encoder_init(dev, &intel_encoder->base, &intel_dp_enc_funcs, +DRM_MODE_ENCODER_TMDS)) + goto err_encoder_init; intel_encoder->compute_config = intel_dp_compute_config; intel_encoder->disable = intel_disable_dp; @@ -5919,6 +5920,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) err_init_connector: drm_encoder_cleanup(encoder); +err_encoder_init: kfree(intel_connector); err_connector_alloc: kfree(intel_dig_port); -- 1.9.1
[PATCH] drm/atomic-helper: Add option to update planes only on active crtc
On Wed, Jul 22, 2015 at 06:02:27PM +0200, Daniel Vetter wrote: [...] > diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c > index c6276aebfec3..783edc242648 100644 > --- a/drivers/gpu/drm/tegra/drm.c > +++ b/drivers/gpu/drm/tegra/drm.c > @@ -56,7 +56,7 @@ static void tegra_atomic_complete(struct tegra_drm *tegra, >*/ > > drm_atomic_helper_commit_modeset_disables(drm, state); > - drm_atomic_helper_commit_planes(drm, state); > + drm_atomic_helper_commit_planes(drm, state, false); > drm_atomic_helper_commit_modeset_enables(drm, state); > > drm_atomic_helper_wait_for_vblanks(drm, state); I tried to give this a go with my ongoing DPMS work and I can't make this work. I think we'll need something more involved to fix this properly with runtime PM enabled drivers. The reason why this isn't working on Tegra is because with the rework done for DPMS, the CRTC will be put into reset in ->disable() and taken out of reset in ->enable() (eventually I suspect that it'd also be powergated in ->disable() and unpowergated in ->enable(), but that should have no further side-effects than the reset). There are two cases where this leads to problems, though as far as I can tell they are the same problem: with legacy fbdev enabled, the initial modeset works fine (though that's only because the mode is actually set twice due to the monitor pulsing HPD). If I then run modetest with the same mode set as fbdev, I also see planes updated properly. Now after I exit modetest it will do a modeset (it's what modetest does, no matter if the mode it did set matches fbdev, not sure if that's really desired) and that ends up with no primary plane being set. The second case where I've seen this happen is with legacy fbdev disabled. In that case, running modetest won't ever display the correct plane. I'm somewhat surprised that it even works, given that the CRTC to which the plane's registers belong is in reset and has clocks disabled at the time of the ->atomic_update() call. I suspect this could be related to the fact that we're accessing only plane registers, and they go through some sort of muxing machinery that may not underly the same clocking and reset restrictions as the other registers. Anyway, the result is that all of the changes done in ->atomic_update() will be lost when the CRTC is enabled, and therefore the only case where the drm_atomic_helper_commit_planes() call works is when the CRTC stays on (essentially what used to be ->mode_set_base()). Moreover, I'd say with active_only set to true, the core shouldn't even call ->atomic_update() for planes associated with the CRTC because at this point it's still off. drm_atomic_helper_commit_modeset_enables() is what will turn the CRTC on. So all in all, I think what we need is actually five steps: 1) disable all planes that will no longer be used in the new state 2) disable all CRTCs that will no longer be used in the new state 3) update all planes that have changed from old to new state 4) enable CRTCs that were not used in the old state but are enabled in the new state 5) enable all planes that were not used in the old state but are enabled in the new state 1) and 5) I think could be helpers that are called from drivers directly in their ->enable() functions. The downside of the above is that there are a bunch of cases where we'd need to be very careful to preserve atomicity across updates. For planes that are enabled on a CRTC that remains active between two states, they would need to be updated in the same ->atomic_begin()/->atomic_flush() sequence as planes that move or change framebuffer, otherwise the frames won't be perfect. Similarly I think we'd want a way to allow drivers to atomically enable updates. That is, enabling the output and setting the planes on them should be an atomic operation. Currently depending on how fast the mode is being set you could have a short period where the mode has been applied, but plane updates aren't visible yet. That would essentially mean that 1) & 2) as well as 4) & 5) in the above would need to be collapsed into single steps, at the end of which the CRTC hardware needs to commit all changes at once. I suspect that for most (all?) cases this may not even matter, though. If the CRTC is set up to scan out black if no planes are active, then this should not be noticable. Thierry -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150727/1cafa0aa/attachment.sig>
[PATCH] drm/atomic-helper: Add option to update planes only on active crtc
On Mon, Jul 27, 2015 at 02:44:31PM +0200, Thierry Reding wrote: > On Wed, Jul 22, 2015 at 06:02:27PM +0200, Daniel Vetter wrote: > [...] > > diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c > > index c6276aebfec3..783edc242648 100644 > > --- a/drivers/gpu/drm/tegra/drm.c > > +++ b/drivers/gpu/drm/tegra/drm.c > > @@ -56,7 +56,7 @@ static void tegra_atomic_complete(struct tegra_drm *tegra, > > */ > > > > drm_atomic_helper_commit_modeset_disables(drm, state); > > - drm_atomic_helper_commit_planes(drm, state); > > + drm_atomic_helper_commit_planes(drm, state, false); > > drm_atomic_helper_commit_modeset_enables(drm, state); > > > > drm_atomic_helper_wait_for_vblanks(drm, state); > > I tried to give this a go with my ongoing DPMS work and I can't make > this work. I think we'll need something more involved to fix this > properly with runtime PM enabled drivers. > > The reason why this isn't working on Tegra is because with the rework > done for DPMS, the CRTC will be put into reset in ->disable() and taken > out of reset in ->enable() (eventually I suspect that it'd also be > powergated in ->disable() and unpowergated in ->enable(), but that > should have no further side-effects than the reset). > > There are two cases where this leads to problems, though as far as I can > tell they are the same problem: with legacy fbdev enabled, the initial > modeset works fine (though that's only because the mode is actually set > twice due to the monitor pulsing HPD). If I then run modetest with the > same mode set as fbdev, I also see planes updated properly. Now after I > exit modetest it will do a modeset (it's what modetest does, no matter > if the mode it did set matches fbdev, not sure if that's really desired) > and that ends up with no primary plane being set. > > The second case where I've seen this happen is with legacy fbdev > disabled. In that case, running modetest won't ever display the correct > plane. I'm somewhat surprised that it even works, given that the CRTC to > which the plane's registers belong is in reset and has clocks disabled > at the time of the ->atomic_update() call. I suspect this could be > related to the fact that we're accessing only plane registers, and they > go through some sort of muxing machinery that may not underly the same > clocking and reset restrictions as the other registers. Anyway, the > result is that all of the changes done in ->atomic_update() will be lost > when the CRTC is enabled, and therefore the only case where the > drm_atomic_helper_commit_planes() call works is when the CRTC stays on > (essentially what used to be ->mode_set_base()). > > Moreover, I'd say with active_only set to true, the core shouldn't even > call ->atomic_update() for planes associated with the CRTC because at > this point it's still off. drm_atomic_helper_commit_modeset_enables() is > what will turn the CRTC on. > > So all in all, I think what we need is actually five steps: > > 1) disable all planes that will no longer be used in the new > state > 2) disable all CRTCs that will no longer be used in the new > state > 3) update all planes that have changed from old to new state > 4) enable CRTCs that were not used in the old state but are > enabled in the new state > 5) enable all planes that were not used in the old state but > are enabled in the new state > > 1) and 5) I think could be helpers that are called from drivers directly > in their ->enable() functions. > > The downside of the above is that there are a bunch of cases where we'd > need to be very careful to preserve atomicity across updates. For planes > that are enabled on a CRTC that remains active between two states, they > would need to be updated in the same ->atomic_begin()/->atomic_flush() > sequence as planes that move or change framebuffer, otherwise the frames > won't be perfect. > > Similarly I think we'd want a way to allow drivers to atomically enable > updates. That is, enabling the output and setting the planes on them > should be an atomic operation. Currently depending on how fast the mode > is being set you could have a short period where the mode has been > applied, but plane updates aren't visible yet. That would essentially > mean that 1) & 2) as well as 4) & 5) in the above would need to be > collapsed into single steps, at the end of which the CRTC hardware needs > to commit all changes at once. I suspect that for most (all?) cases this > may not even matter, though. If the CRTC is set up to scan out black if > no planes are active, then this should not be noticable. On i915 we do a slightly different sequence: 1) kill all the planes for crtcs which will be shut down in step 2). Those are all the ones for which needs_modeset is true. A helper to do this could be implemented using the plane_funcs->atomic_disable hook. To make this nicely atomic we should also wrap them with ->atomic_begin an
[PULL] topic/crc-pmic
On Mon, Jul 27, 2015 at 01:21:01PM +0200, Thierry Reding wrote: > On Thu, Jul 23, 2015 at 09:38:46AM +0200, Daniel Vetter wrote: > [...] > > On Thu, Jul 23, 2015 at 9:31 AM, Daniel Vetter > > wrote: > [...] > > > Shobhit Kumar (8): > [...] > > > pwm: crc: Add Crystalcove (CRC) PWM driver > > Would you mind removing this from your branch? I ended up manually > applying a couple of changes that I had requested but ended up not > getting addressed. > > When you drop it, let me know so I can push my branch to -next and > have it not collide with your tree immediately. I assume it's in a > branch that feeds into linux-next? Oops sorry I missed that there was still review pending. Unfortuntely Dave already pulled this into drm-next so it's baked in. I guess best would be to pull this into your pwm branch too and resolve the conflicts in the merge explicitly. Sorry about the mess I've caused here for you. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
[Bug 91302] radeon.audio=1 causes issues with 7950
https://bugs.freedesktop.org/show_bug.cgi?id=91302 Alex Deucher changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |DUPLICATE --- Comment #2 from Alex Deucher --- *** This bug has been marked as a duplicate of bug 91041 *** -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150727/19e95155/attachment.html>
[Bug 91041] Purple line is visible on left side of screen and the screen is blurry using HTMI output with AMD radeon
https://bugs.freedesktop.org/show_bug.cgi?id=91041 Alex Deucher changed: What|Removed |Added CC||maczqia+contrib at gmail.com --- Comment #13 from Alex Deucher --- *** Bug 91302 has been marked as a duplicate of this bug. *** -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150727/176a59b3/attachment.html>
[Bug 91041] Purple line is visible on left side of screen and the screen is blurry using HTMI output with AMD radeon
https://bugs.freedesktop.org/show_bug.cgi?id=91041 Alex Deucher changed: What|Removed |Added Attachment #117326|0 |1 is obsolete|| --- Comment #14 from Alex Deucher --- Created attachment 117395 --> https://bugs.freedesktop.org/attachment.cgi?id=117395&action=edit proper fix -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150727/e7ba2a01/attachment.html>
[PULL] topic/crc-pmic
On Mon, Jul 27, 2015 at 03:09:54PM +0200, Daniel Vetter wrote: > On Mon, Jul 27, 2015 at 01:21:01PM +0200, Thierry Reding wrote: > > On Thu, Jul 23, 2015 at 09:38:46AM +0200, Daniel Vetter wrote: > > [...] > > > On Thu, Jul 23, 2015 at 9:31 AM, Daniel Vetter > > ffwll.ch> wrote: > > [...] > > > > Shobhit Kumar (8): > > [...] > > > > pwm: crc: Add Crystalcove (CRC) PWM driver > > > > Would you mind removing this from your branch? I ended up manually > > applying a couple of changes that I had requested but ended up not > > getting addressed. > > > > When you drop it, let me know so I can push my branch to -next and > > have it not collide with your tree immediately. I assume it's in a > > branch that feeds into linux-next? > > Oops sorry I missed that there was still review pending. Unfortuntely Dave > already pulled this into drm-next so it's baked in. I guess best would be > to pull this into your pwm branch too and resolve the conflicts in the > merge explicitly. Sorry about the mess I've caused here for you. Oh well, nevermind. Thierry -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150727/559069db/attachment.sig>
[PATCH v1.2 02/13] drm/atomic: Update legacy DPMS state during modesets, v3.
On Mon, Jul 27, 2015 at 01:24:29PM +0200, Maarten Lankhorst wrote: > This is required for DPMS to work correctly, during a modeset > the DPMS property should be turned off, unless the state is > crtc is made active in which case it should be set to DPMS on. > > Changes since v1: > - Set DPMS to off when a connector is removed from a crtc too. > - Update the legacy dpms property too. > - Add an exception for the legacy dpms paths, it updates its own state. > Changes since v2: > - Do not preserve dpms property. > > Cc: dri-devel at lists.freedesktop.org > Signed-off-by: Maarten Lankhorst Yeah I think that's the one, applied to drm-misc. Thanks, Daniel > --- > diff --git a/drivers/gpu/drm/drm_atomic_helper.c > b/drivers/gpu/drm/drm_atomic_helper.c > index 57847ae8ce8c..0b475fae067d 100644 > --- a/drivers/gpu/drm/drm_atomic_helper.c > +++ b/drivers/gpu/drm/drm_atomic_helper.c > @@ -660,15 +660,29 @@ drm_atomic_helper_update_legacy_modeset_state(struct > drm_device *dev, > struct drm_crtc_state *old_crtc_state; > int i; > > - /* clear out existing links */ > + /* clear out existing links and update dpms */ > for_each_connector_in_state(old_state, connector, old_conn_state, i) { > - if (!connector->encoder) > - continue; > + if (connector->encoder) { > + WARN_ON(!connector->encoder->crtc); > + > + connector->encoder->crtc = NULL; > + connector->encoder = NULL; > + } > > - WARN_ON(!connector->encoder->crtc); > + crtc = connector->state->crtc; > + if ((!crtc && old_conn_state->crtc) || > + (crtc && drm_atomic_crtc_needs_modeset(crtc->state))) { > + struct drm_property *dpms_prop = > + dev->mode_config.dpms_property; > + int mode = DRM_MODE_DPMS_OFF; > > - connector->encoder->crtc = NULL; > - connector->encoder = NULL; > + if (crtc && crtc->state->active) > + mode = DRM_MODE_DPMS_ON; > + > + connector->dpms = mode; > + drm_object_property_set_value(&connector->base, > + dpms_prop, mode); > + } > } > > /* set new links */ > diff --git a/drivers/gpu/drm/i915/intel_display.c > b/drivers/gpu/drm/i915/intel_display.c > index 13a6608be689..43b0f17ad1fa 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -12349,16 +12349,9 @@ intel_modeset_update_state(struct drm_atomic_state > *state) > continue; > > if (crtc->state->active) { > - struct drm_property *dpms_property = > - dev->mode_config.dpms_property; > - > - connector->dpms = DRM_MODE_DPMS_ON; > - drm_object_property_set_value(&connector->base, > dpms_property, DRM_MODE_DPMS_ON); > - > intel_encoder = to_intel_encoder(connector->encoder); > intel_encoder->connectors_active = true; > - } else > - connector->dpms = DRM_MODE_DPMS_OFF; > + } > } > } > > -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
[Nouveau] [PATCH] nouveau: nv46: Change mc subdev oclass from nv44 to nv4c
Hi, On 24-07-15 04:32, Ben Skeggs wrote: > On 24 July 2015 at 01:20, Hans de Goede wrote: >> MSI interrupts appear to not work for nv46 based cards. Change the mc >> subdev oclass for these cards from nv44 to nv4c, the nv4c mc code is >> identical to the nv44 mc code except that it does not use msi >> (it does not define a msi_rearm callback). > I'm fine with this, but it'd be nice to check that the binary driver > doesn't/can't use MSI on these too (there might be an alternate method > we need to use). > > Would you be able to grab the latest proprietary driver that works on > nv4x, and do a mmiotrace of it? I've grabbed 304.125 > You *might* need to use "modprobe > nvidia NVreg_EnableMSI=1", because at some point NVIDIA didn't use it > by default anywhere. You're right I needed to specify NVreg_EnableMSI=1, with that set /proc/interrupts shows that MSI is used. Here is an of running glxgears with the binary driver using msi interrupts mmiotrace: https://fedorapeople.org/~jwrdegoede/nvidia-bin-nv46-msi-on-glxgears.mmiotrace.gz AFAIK there are some nouveau tools to parse this a bit, right ? I'm going to call it a day for today, if you can give me some pointers what to do with the mmiotrace to find a potential fix for the msi issues, that would be appreciated. BTW I had to build my own kernel with mmiotrace enabled in Kconfig, as this is disabled in the Fedora kernels by default. Do you know if there is a good reason to have this disabled by default, or should I ask the Fedora kernel maintainers to enable it by default ? Slightly offtopic: I decided to be bold and try gnome-shell on the nv46 with msi disabled, which sofar was a guaranteed way to freeze the system, and it now works somewhat (latest kernel, ddx and mesa). I see something which shows horizontal lines which are small parts from my desktop background, and things change significantly when I switch to the overview mode. But other then that the display is completely wrong, it looks a bit like a framebuffer pitch problem, but then different. I think it is likely some tiling problem or some such. Note that metacity + glxgears works, this only shows with gnome-shell, any hints where to start looking wrt debugging this? Or should I first try to run piglet and see if some tests there point out the culprit? Regards, Hans > > Thanks, > Ben. > >> BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=90435 >> Signed-off-by: Hans de Goede >> --- >> drivers/gpu/drm/nouveau/nvkm/engine/device/nv40.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/nv40.c >> b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv40.c >> index c630136..b4ad791 100644 >> --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/nv40.c >> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv40.c >> @@ -265,7 +265,7 @@ nv40_identify(struct nvkm_device *device) >> device->oclass[NVDEV_SUBDEV_CLK] = &nv40_clk_oclass; >> device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; >> device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; >> - device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass; >> + device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass; >> device->oclass[NVDEV_SUBDEV_BUS] = nv31_bus_oclass; >> device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; >> device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; >> -- >> 2.4.3 >> >> ___ >> Nouveau mailing list >> Nouveau at lists.freedesktop.org >> http://lists.freedesktop.org/mailman/listinfo/nouveau
[Nouveau] [PATCH] nouveau: nv46: Change mc subdev oclass from nv44 to nv4c
On Mon, Jul 27, 2015 at 11:52 AM, Hans de Goede wrote: > https://fedorapeople.org/~jwrdegoede/nvidia-bin-nv46-msi-on-glxgears.mmiotrace.gz > > AFAIK there are some nouveau tools to parse this a bit, right ? I'm going > to call it a day for today, if you can give me some pointers what to do with > the > mmiotrace to find a potential fix for the msi issues, that would be > appreciated. rnn/demmio -l foo-mmiotrace.gz Enjoy :)
[PATCH v2] drm/msm: Enable clocks during enable/disable_vblank() callbacks
AHB clock should be enabled before accessing registers during enable/disable_vblank(). Since these 2 callbacks are called in atomic context while clk_prepare may cause thread sleep, a work is scheduled to control vblanks. v2: fixup spinlock initialization Signed-off-by: Hai Li --- drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c | 9 drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c | 9 drivers/gpu/drm/msm/msm_drv.c | 74 - drivers/gpu/drm/msm/msm_drv.h | 8 4 files changed, 98 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c index 7369ee7f..64d24fc 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c @@ -86,13 +86,22 @@ irqreturn_t mdp4_irq(struct msm_kms *kms) int mdp4_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc) { + struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms)); + + mdp4_enable(mdp4_kms); mdp_update_vblank_mask(to_mdp_kms(kms), mdp4_crtc_vblank(crtc), true); + mdp4_disable(mdp4_kms); + return 0; } void mdp4_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc) { + struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms)); + + mdp4_enable(mdp4_kms); mdp_update_vblank_mask(to_mdp_kms(kms), mdp4_crtc_vblank(crtc), false); + mdp4_disable(mdp4_kms); } diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c index 33bd4c6..2a578f2 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c @@ -112,15 +112,24 @@ irqreturn_t mdp5_irq(struct msm_kms *kms) int mdp5_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc) { + struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); + + mdp5_enable(mdp5_kms); mdp_update_vblank_mask(to_mdp_kms(kms), mdp5_crtc_vblank(crtc), true); + mdp5_disable(mdp5_kms); + return 0; } void mdp5_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc) { + struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); + + mdp5_enable(mdp5_kms); mdp_update_vblank_mask(to_mdp_kms(kms), mdp5_crtc_vblank(crtc), false); + mdp5_disable(mdp5_kms); } /* diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index b7ef56e..0c47c2d 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -116,6 +116,65 @@ u32 msm_readl(const void __iomem *addr) return val; } +struct vblank_event { + struct list_head node; + int crtc_id; + bool enable; +}; + +static void vblank_ctrl_worker(struct work_struct *work) +{ + struct msm_vblank_ctrl *vbl_ctrl = container_of(work, + struct msm_vblank_ctrl, work); + struct msm_drm_private *priv = container_of(vbl_ctrl, + struct msm_drm_private, vblank_ctrl); + struct msm_kms *kms = priv->kms; + struct vblank_event *vbl_ev, *tmp; + unsigned long flags; + + spin_lock_irqsave(&vbl_ctrl->lock, flags); + list_for_each_entry_safe(vbl_ev, tmp, &vbl_ctrl->event_list, node) { + list_del(&vbl_ev->node); + spin_unlock_irqrestore(&vbl_ctrl->lock, flags); + + if (vbl_ev->enable) + kms->funcs->enable_vblank(kms, + priv->crtcs[vbl_ev->crtc_id]); + else + kms->funcs->disable_vblank(kms, + priv->crtcs[vbl_ev->crtc_id]); + + kfree(vbl_ev); + + spin_lock_irqsave(&vbl_ctrl->lock, flags); + } + + spin_unlock_irqrestore(&vbl_ctrl->lock, flags); +} + +static int vblank_ctrl_queue_work(struct msm_drm_private *priv, + int crtc_id, bool enable) +{ + struct msm_vblank_ctrl *vbl_ctrl = &priv->vblank_ctrl; + struct vblank_event *vbl_ev; + unsigned long flags; + + vbl_ev = kzalloc(sizeof(*vbl_ev), GFP_ATOMIC); + if (!vbl_ev) + return -ENOMEM; + + vbl_ev->crtc_id = crtc_id; + vbl_ev->enable = enable; + + spin_lock_irqsave(&vbl_ctrl->lock, flags); + list_add_tail(&vbl_ev->node, &vbl_ctrl->event_list); + spin_unlock_irqrestore(&vbl_ctrl->lock, flags); + + queue_work(priv->wq, &vbl_ctrl->work); + + return 0; +} + /* * DRM operations: */ @@ -125,6 +184,14 @@ static int msm_unload(struct drm_device *dev) struct msm_drm_private *priv = dev->dev_private; struct msm_kms *kms = priv->kms; struct msm_gpu *gpu = priv->gpu; + struct msm_vblank_ctrl *vbl_ctrl = &priv->vblank_ctrl; + struct vblank_event *vbl_ev, *tmp; +
[PATCH] drm: Fix TEST_CRC_COUNT mask name.
Thierry has noticed that this name was inconsistent with spec. This was wrong since I had introduced with commit ad9dc91b6e21 ("drm/i915: Fix Sink CRC") Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/intel_dp.c | 2 +- include/drm/drm_dp_helper.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index e99ec7a..82bf0a7 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4003,7 +4003,7 @@ static int intel_dp_sink_crc_start(struct intel_dp *intel_dp) if (!(buf & DP_TEST_CRC_SUPPORTED)) return -ENOTTY; - intel_dp->sink_crc.last_count = buf & DP_TEST_COUNT_MASK; + intel_dp->sink_crc.last_count = buf & DP_TEST_CRC_COUNT_MASK; if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK, &buf) < 0) return -EIO; diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 94898f6..f0ff13a 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -420,7 +420,7 @@ #define DP_TEST_SINK_MISC 0x246 # define DP_TEST_CRC_SUPPORTED (1 << 5) -# define DP_TEST_COUNT_MASK0xf +# define DP_TEST_CRC_COUNT_MASK0xf #define DP_TEST_RESPONSE 0x260 # define DP_TEST_ACK (1 << 0) -- 1.9.3
[Bug 91041] Purple line is visible on left side of screen and the screen is blurry using HTMI output with AMD radeon
https://bugs.freedesktop.org/show_bug.cgi?id=91041 --- Comment #15 from Maxqia --- Tested Patch, Seems to be working -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150727/d4e26739/attachment.html>
[Bug 91253] Regression: Can't boot on 4.0.5 and later but can boot on 4.0.4 (on iMac)
https://bugs.freedesktop.org/show_bug.cgi?id=91253 --- Comment #5 from Richard Bradfield --- I believe that the patch proposed in 91041 [1,2] will resolve this. This bug seems to be caused by an early attempt to access the afmt property of the encoder before it has been initialised. The audio detection rework in [2] looks like it should avoid this corner case. Andreas, can you try the patch linked as [2]? [1] https://bugs.freedesktop.org/show_bug.cgi?id=91041 [2] https://bugs.freedesktop.org/attachment.cgi?id=117395 -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150727/1770202a/attachment.html>
[Bug 91480] Dead Island: Crash loading Act 3 possible shader issue
https://bugs.freedesktop.org/show_bug.cgi?id=91480 Bug ID: 91480 Summary: Dead Island: Crash loading Act 3 possible shader issue Product: Mesa Version: 10.6 Hardware: Other OS: All Status: NEW Severity: normal Priority: medium Component: Drivers/Gallium/r600 Assignee: dri-devel at lists.freedesktop.org Reporter: sa at whiz.se QA Contact: dri-devel at lists.freedesktop.org Created attachment 117408 --> https://bugs.freedesktop.org/attachment.cgi?id=117408&action=edit backtrace with 10.5.9 I'm getting a reproducible crash in the game Dead Island when loading act 3. Sometimes this is a straight segfault, sometimes the game pops up a warning "An unknown error occured while compiling shaders." I'm attaching a backtrace of the segfault from Mesa 10.5.9, I still get the error with 10.6.3. This might be a shader issue, I get this warning in the game log: /media/Data/perforce/di/releases/di_master_steambox/src/engine/ropengl/ROpenGL_Shader.cpp(471) : Condition: 0 && "Cannot compile GL shader!" LLOG: 0:35(12): warning: extension `GL_ATI_draw_buffers' unsupported in fragment shader 0:209(3): error: syntax error, unexpected '=' ERRR: Assertion failed! /media/Data/perforce/di/releases/di_master_steambox/src/engine/ropengl/ROpenGL_Shader.cpp(678) : Condition: 0 && "Compilation of shader failed!" ERRR: [CPShader] cannot create pixel shader LLOG: binlen: 0; format: 0; program: 48828 LLOG: FAILED TO LOAD BINARY!!! Loading from sources.TOTAL TIME: 247398.718750ms I'm attaching the failing shader. I'm failing this against r600g as that's where the backtrace points, but this is probably a general shader issue. Probably not the same as #85564 as I have played through half the game with just a few hiccups. Side note: this title might be a good candidate for some sort of cache. Loading times are more than a minute and it seems to be spending most of that time compiling. -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150727/3d60e5d7/attachment.html>
[Bug 91480] Dead Island: Crash loading Act 3 possible shader issue
https://bugs.freedesktop.org/show_bug.cgi?id=91480 --- Comment #1 from Sven Arvidsson --- Created attachment 117409 --> https://bugs.freedesktop.org/attachment.cgi?id=117409&action=edit failing shader -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150727/dda7aec6/attachment.html>
[Bug 91480] Dead Island: Crash loading Act 3 possible shader issue
https://bugs.freedesktop.org/show_bug.cgi?id=91480 --- Comment #2 from Ilia Mirkin --- FWIW I can't reproduce the segfault by running through glsl_compiler. I do, however, get a 0:35(1): error: #extension directive is not allowed in the middle of a shader But that should be work-around-able with a driconf setting (or by running the game with allow_glsl_extension_directive_midshader=1 in the environment). When I move the #extension line up, no complaints (other than the unknown GL_ATI_draw_buffers thing), nothing in valgrind either. Perhaps you can capture an apitrace of the issue? -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150727/9f8d15b7/attachment.html>
[PATCH 1/2] drm/doc: Add hflip/vflip property descriptions in msm
Add plane properties hflip/vflip which are used in MDP driver to flip the input horizontally/vertically. Signed-off-by: Jilai Wang --- Documentation/DocBook/drm.tmpl | 18 -- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index d9f5613..bef6d34 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -3501,8 +3501,8 @@ void intel_crt_init(struct drm_device *dev) TBD - msm - Generic + msm + Generic "premultiplied" ENUM { "false", "true" } @@ -3523,6 +3523,20 @@ void intel_crt_init(struct drm_device *dev) Plane property to set plane's z position during blending + + "hflip" + ENUM + { "off", "on" } + Plane + property to flip the input horizontally + + + "vflip" + ENUM + { "off", "on" } + Plane + property to flip the input vertically + -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH 2/2] drm/msm/mdp5: Add hflip/vflip support to MDP5 planes
MDP5 SSPPs can flip the input source horizontally or vertically. This change is to support this feature by adding vflip/hflip properties to MDP5 planes. Signed-off-by: Jilai Wang --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 2 ++ drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 25 + drivers/gpu/drm/msm/msm_drv.h | 2 ++ 3 files changed, 29 insertions(+) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h index 8542b30..93545ec 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h @@ -74,6 +74,8 @@ struct mdp5_plane_state { uint8_t premultiplied; uint8_t zpos; uint8_t alpha; + uint8_t hflip; + uint8_t vflip; /* assigned by crtc blender */ enum mdp_mixer_stage_id stage; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index 1fbb17d..edd20025 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -88,6 +88,16 @@ static const struct drm_prop_enum_list premultiplied_prop_enum_list[] = { { 1, "true" }, }; +static const struct drm_prop_enum_list hflip_prop_enum_list[] = { + { 0, "off" }, + { 1, "on" }, +}; + +static const struct drm_prop_enum_list vflip_prop_enum_list[] = { + { 0, "off" }, + { 1, "on" }, +}; + /* helper to install properties which are common to planes and crtcs */ void mdp5_plane_install_properties(struct drm_plane *plane, struct drm_mode_object *obj) @@ -95,6 +105,7 @@ void mdp5_plane_install_properties(struct drm_plane *plane, struct drm_device *dev = plane->dev; struct msm_drm_private *dev_priv = dev->dev_private; struct drm_property *prop; + struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); #define INSTALL_PROPERTY(name, NAME, init_val, fnc, ...) do { \ prop = dev_priv->plane_property[PLANE_PROP_##NAME]; \ @@ -125,6 +136,11 @@ void mdp5_plane_install_properties(struct drm_plane *plane, INSTALL_RANGE_PROPERTY(alpha, ALPHA, 0, 255, 255); INSTALL_ENUM_PROPERTY(premultiplied, PREMULTIPLIED, 0); + if (mdp5_plane->caps & MDP_PIPE_CAP_HFLIP) + INSTALL_ENUM_PROPERTY(hflip, HFLIP, 0); + if (mdp5_plane->caps & MDP_PIPE_CAP_VFLIP) + INSTALL_ENUM_PROPERTY(vflip, VFLIP, 0); + #undef INSTALL_RANGE_PROPERTY #undef INSTALL_ENUM_PROPERTY #undef INSTALL_PROPERTY @@ -152,6 +168,8 @@ static int mdp5_plane_atomic_set_property(struct drm_plane *plane, SET_PROPERTY(zpos, ZPOS, uint8_t); SET_PROPERTY(alpha, ALPHA, uint8_t); SET_PROPERTY(premultiplied, PREMULTIPLIED, uint8_t); + SET_PROPERTY(hflip, HFLIP, uint8_t); + SET_PROPERTY(vflip, VFLIP, uint8_t); dev_err(dev->dev, "Invalid property\n"); ret = -EINVAL; @@ -189,6 +207,8 @@ static int mdp5_plane_atomic_get_property(struct drm_plane *plane, GET_PROPERTY(zpos, ZPOS, uint8_t); GET_PROPERTY(alpha, ALPHA, uint8_t); GET_PROPERTY(premultiplied, PREMULTIPLIED, uint8_t); + GET_PROPERTY(hflip, HFLIP, uint8_t); + GET_PROPERTY(vflip, VFLIP, uint8_t); dev_err(dev->dev, "Invalid property\n"); ret = -EINVAL; @@ -210,6 +230,8 @@ static void mdp5_plane_reset(struct drm_plane *plane) /* assign default blend parameters */ mdp5_state->alpha = 255; mdp5_state->premultiplied = 0; + mdp5_state->hflip = 0; + mdp5_state->vflip = 0; if (plane->type == DRM_PLANE_TYPE_PRIMARY) mdp5_state->zpos = STAGE_BASE; @@ -565,6 +587,7 @@ static int mdp5_plane_mode_set(struct drm_plane *plane, uint32_t src_w, uint32_t src_h) { struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); + struct mdp5_plane_state *pstate = to_mdp5_plane_state(plane->state); struct mdp5_kms *mdp5_kms = get_kms(plane); struct device *dev = mdp5_kms->dev->dev; enum mdp5_pipe pipe = mdp5_plane->pipe; @@ -675,6 +698,8 @@ static int mdp5_plane_mode_set(struct drm_plane *plane, MDP5_PIPE_SRC_UNPACK_ELEM3(format->unpack[3])); mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_OP_MODE(pipe), + (pstate->hflip ? MDP5_PIPE_SRC_OP_MODE_FLIP_LR : 0) | + (pstate->vflip ? MDP5_PIPE_SRC_OP_MODE_FLIP_UD : 0) | MDP5_PIPE_SRC_OP_MODE_BWC(BWC_LOSSLESS)); /* not using secure mode: */ diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index bd64a82..e047fec 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -68,6 +68,8 @@ enum msm_mdp_plane_property { PLANE_PROP_ZPOS, PLANE_PROP_ALPHA, PLANE_PROP_PREMULTIPLIED, + PLANE_PROP_HFLIP, + PLANE_PROP_VFLIP, PLANE_PROP_MAX_NUM }; -- The Qualcomm Inno
[PATCH V5 3/7] mm: Introduce VM_LOCKONFAULT
On Fri, Jul 24, 2015 at 05:28:41PM -0400, Eric B Munson wrote: > The cost of faulting in all memory to be locked can be very high when > working with large mappings. If only portions of the mapping will be > used this can incur a high penalty for locking. > > For the example of a large file, this is the usage pattern for a large > statical language model (probably applies to other statical or graphical > models as well). For the security example, any application transacting > in data that cannot be swapped out (credit card data, medical records, > etc). > > This patch introduces the ability to request that pages are not > pre-faulted, but are placed on the unevictable LRU when they are finally > faulted in. The VM_LOCKONFAULT flag will be used together with > VM_LOCKED and has no effect when set without VM_LOCKED. Setting the > VM_LOCKONFAULT flag for a VMA will cause pages faulted into that VMA to > be added to the unevictable LRU when they are faulted or if they are > already present, but will not cause any missing pages to be faulted in. > > Exposing this new lock state means that we cannot overload the meaning > of the FOLL_POPULATE flag any longer. Prior to this patch it was used > to mean that the VMA for a fault was locked. This means we need the > new FOLL_MLOCK flag to communicate the locked state of a VMA. > FOLL_POPULATE will now only control if the VMA should be populated and > in the case of VM_LOCKONFAULT, it will not be set. > > Signed-off-by: Eric B Munson > Cc: Michal Hocko > Cc: Vlastimil Babka > Cc: Jonathan Corbet > Cc: "Kirill A. Shutemov" > Cc: linux-kernel at vger.kernel.org > Cc: dri-devel at lists.freedesktop.org > Cc: linux-mm at kvack.org > Cc: linux-api at vger.kernel.org > --- > drivers/gpu/drm/drm_vm.c | 8 +++- > fs/proc/task_mmu.c | 1 + > include/linux/mm.h | 2 ++ > kernel/fork.c| 2 +- > mm/debug.c | 1 + > mm/gup.c | 10 -- > mm/huge_memory.c | 2 +- > mm/hugetlb.c | 4 ++-- > mm/mlock.c | 2 +- > mm/mmap.c| 2 +- > mm/rmap.c| 4 ++-- > 11 files changed, 27 insertions(+), 11 deletions(-) > > diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c > index aab49ee..103a5f6 100644 > --- a/drivers/gpu/drm/drm_vm.c > +++ b/drivers/gpu/drm/drm_vm.c > @@ -699,9 +699,15 @@ int drm_vma_info(struct seq_file *m, void *data) > (void *)(unsigned long)virt_to_phys(high_memory)); > > list_for_each_entry(pt, &dev->vmalist, head) { > + char lock_flag = '-'; > + > vma = pt->vma; > if (!vma) > continue; > + if (vma->vm_flags & VM_LOCKONFAULT) > + lock_flag = 'f'; > + else if (vma->vm_flags & VM_LOCKED) > + lock_flag = 'l'; > seq_printf(m, > "\n%5d 0x%pK-0x%pK %c%c%c%c%c%c 0x%08lx000", > pt->pid, > @@ -710,7 +716,7 @@ int drm_vma_info(struct seq_file *m, void *data) > vma->vm_flags & VM_WRITE ? 'w' : '-', > vma->vm_flags & VM_EXEC ? 'x' : '-', > vma->vm_flags & VM_MAYSHARE ? 's' : 'p', > -vma->vm_flags & VM_LOCKED ? 'l' : '-', > +lock_flag, > vma->vm_flags & VM_IO ? 'i' : '-', > vma->vm_pgoff); > > diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c > index ca1e091..38d69fc 100644 > --- a/fs/proc/task_mmu.c > +++ b/fs/proc/task_mmu.c > @@ -579,6 +579,7 @@ static void show_smap_vma_flags(struct seq_file *m, > struct vm_area_struct *vma) > #ifdef CONFIG_X86_INTEL_MPX > [ilog2(VM_MPX)] = "mp", > #endif > + [ilog2(VM_LOCKONFAULT)] = "lf", > [ilog2(VM_LOCKED)] = "lo", > [ilog2(VM_IO)] = "io", > [ilog2(VM_SEQ_READ)]= "sr", > diff --git a/include/linux/mm.h b/include/linux/mm.h > index 2e872f9..c2f3551 100644 > --- a/include/linux/mm.h > +++ b/include/linux/mm.h > @@ -127,6 +127,7 @@ extern unsigned int kobjsize(const void *objp); > #define VM_PFNMAP0x0400 /* Page-ranges managed without "struct > page", just pure PFN */ > #define VM_DENYWRITE 0x0800 /* ETXTBSY on write attempts.. */ > > +#define VM_LOCKONFAULT 0x1000 /* Lock the pages covered when > they are faulted in */ > #define VM_LOCKED0x2000 > #define VM_IO 0x4000 /* Memory mapped I/O or similar */ > > @@ -2043,6 +2044,7 @@ static inline struct page *follow_page(struct > vm_area_struct *vma, > #define FOLL_NUMA0x200 /* force NUMA hinting page fault */ > #define FOLL_MIGRATION 0x400 /* wait for page to replace migration > entry */ > #define FOLL_TRIED 0x800 /* a retry, previous pass started an IO */ > +#def
[PATCH 2/4] mm/compaction: enable mobile-page migration
On 07/13/2015 10:35 AM, Gioh Kim wrote: > From: Gioh Kim > > Add framework to register callback functions and check page mobility. > There are some modes for page isolation so that isolate interface > has arguments of page address and isolation mode while putback > interface has only page address as argument. Note that unlike what subject suggest, this doesn't really enable mobile-page migration inside compaction, since that only happens with patch 3. This might theoretically affect some cherry-pick backports that don't care about balloon pages. I can imagine that can easily happen in the world of mobile devices? It would thus be somewhat cleaner if this patch was complete in that sense. > Signed-off-by: Gioh Kim > Acked-by: Rafael Aquini > --- > fs/proc/page.c | 3 ++ > include/linux/compaction.h | 80 > ++ > include/linux/fs.h | 2 + > include/linux/page-flags.h | 19 > include/uapi/linux/kernel-page-flags.h | 1 + > 5 files changed, 105 insertions(+) > > diff --git a/fs/proc/page.c b/fs/proc/page.c > index 7eee2d8..a4f5a00 100644 > --- a/fs/proc/page.c > +++ b/fs/proc/page.c > @@ -146,6 +146,9 @@ u64 stable_page_flags(struct page *page) > if (PageBalloon(page)) > u |= 1 << KPF_BALLOON; > > + if (PageMobile(page)) > + u |= 1 << KPF_MOBILE; PageMovable() would probably be as good a name and correspond to MIGRATE_MOVABLE somewhat, unlike a completely new term. Whatever driver starts to using this should probably change allocation flags to allocate MIGRATE_MOVABLE, so that it works fine with what fragmentation avoidance expects. Guess I should have said that earlier, but can you still reconsider? > + > u |= kpf_copy_bit(k, KPF_LOCKED,PG_locked); > > u |= kpf_copy_bit(k, KPF_SLAB, PG_slab); > diff --git a/include/linux/compaction.h b/include/linux/compaction.h > index aa8f61c..f693072 100644 > --- a/include/linux/compaction.h > +++ b/include/linux/compaction.h > @@ -1,6 +1,9 @@ > #ifndef _LINUX_COMPACTION_H > #define _LINUX_COMPACTION_H > > +#include > +#include > + > /* Return values for compact_zone() and try_to_compact_pages() */ > /* compaction didn't start as it was deferred due to past failures */ > #define COMPACT_DEFERRED0 > @@ -51,6 +54,70 @@ extern void compaction_defer_reset(struct zone *zone, int > order, > bool alloc_success); > extern bool compaction_restarting(struct zone *zone, int order); > > +static inline bool mobile_page(struct page *page) > +{ > + return page->mapping && (PageMobile(page) || PageBalloon(page)); > +} I would put this definition to linux/page-flags.h and rename it to page_mobile (or better page_movable()), which is more common ordering. > + > +static inline bool isolate_mobilepage(struct page *page, isolate_mode_t mode) Does this have to be in compaction.h? The only user is compaction.c so probably move it there, and if there ever is another module using this in the future, we can move it to a more appropriate place and declare it in e.g. mm/internal.h. > +{ > + bool ret = false; > + > + /* > + * Avoid burning cycles with pages that are yet under __free_pages(), > + * or just got freed under us. > + * > + * In case we 'win' a race for a mobile page being freed under us and > + * raise its refcount preventing __free_pages() from doing its job > + * the put_page() at the end of this block will take care of > + * release this page, thus avoiding a nasty leakage. > + */ > + if (unlikely(!get_page_unless_zero(page))) > + goto out; > + > + /* > + * As mobile pages are not isolated from LRU lists, concurrent > + * compaction threads can race against page migration functions > + * as well as race against the releasing a page. > + * > + * In order to avoid having an already isolated mobile page > + * being (wrongly) re-isolated while it is under migration, > + * or to avoid attempting to isolate pages being released, > + * lets be sure we have the page lock > + * before proceeding with the mobile page isolation steps. > + */ > + if (unlikely(!trylock_page(page))) > + goto out_putpage; > + > + if (!(mobile_page(page) && page->mapping->a_ops->isolatepage)) > + goto out_not_isolated; > + ret = page->mapping->a_ops->isolatepage(page, mode); > + if (!ret) > + goto out_not_isolated; > + unlock_page(page); > + return ret; > + > +out_not_isolated: > + unlock_page(page); > +out_putpage: > + put_page(page); > +out: > + return ret; > +} > + > +static inline void putback_mobilepage(struct page *page) Likewise, this could go to migrate.c. Or maybe together with isolate_mobilepage() if you don't want to split them. > +{ > + /* > + * 'lock_p
[PATCH] drm/msm: add calls to prepare and unprepare panel
Prepare the panel before it's enabled and un-prepare after disable, this will make sure that the regulators are switched on and off correctly. Tested it on APQ8064 based IFC6410 with panel. Signed-off-by: Srinivas Kandagatla --- drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c index c048433..4cd6e72 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c @@ -346,8 +346,10 @@ static void mdp4_lcdc_encoder_disable(struct drm_encoder *encoder) mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 0); - if (panel) + if (panel) { drm_panel_disable(panel); + drm_panel_unprepare(panel); + } /* * Wait for a vsync so we know the ENABLE=0 latched before @@ -412,8 +414,10 @@ static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder) if (ret) dev_err(dev->dev, "failed to enable lcdc_clk: %d\n", ret); - if (panel) + if (panel) { + drm_panel_prepare(panel); drm_panel_enable(panel); + } setup_phy(encoder); -- 1.9.1
[PATCH 2/4] mm/compaction: enable mobile-page migration
On Mon, Jul 27, 2015 at 4:55 PM, Vlastimil Babka wrote: > On 07/13/2015 10:35 AM, Gioh Kim wrote: >> >> From: Gioh Kim >> >> Add framework to register callback functions and check page mobility. >> There are some modes for page isolation so that isolate interface >> has arguments of page address and isolation mode while putback >> interface has only page address as argument. > > > Note that unlike what subject suggest, this doesn't really enable > mobile-page migration inside compaction, since that only happens with patch > 3. This might theoretically affect some cherry-pick backports that don't > care about balloon pages. I can imagine that can easily happen in the world > of mobile devices? > It would thus be somewhat cleaner if this patch was complete in that sense. > >> Signed-off-by: Gioh Kim >> Acked-by: Rafael Aquini >> --- >> fs/proc/page.c | 3 ++ >> include/linux/compaction.h | 80 >> ++ >> include/linux/fs.h | 2 + >> include/linux/page-flags.h | 19 >> include/uapi/linux/kernel-page-flags.h | 1 + >> 5 files changed, 105 insertions(+) >> >> diff --git a/fs/proc/page.c b/fs/proc/page.c >> index 7eee2d8..a4f5a00 100644 >> --- a/fs/proc/page.c >> +++ b/fs/proc/page.c >> @@ -146,6 +146,9 @@ u64 stable_page_flags(struct page *page) >> if (PageBalloon(page)) >> u |= 1 << KPF_BALLOON; >> >> + if (PageMobile(page)) >> + u |= 1 << KPF_MOBILE; > > > PageMovable() would probably be as good a name and correspond to > MIGRATE_MOVABLE somewhat, unlike a completely new term. Whatever driver > starts to using this should probably change allocation flags to allocate > MIGRATE_MOVABLE, so that it works fine with what fragmentation avoidance > expects. Guess I should have said that earlier, but can you still > reconsider? Well, I've suggested to name it "mobile" because there's already a lot of things called "movable". Mobile pages are special subset of movable pages: they are non-lru pages and define their own rules of moving in address space operations. Also there's a little pun: I guess main user will zram which is used mostly in embedded/mobile devices. > >> + >> u |= kpf_copy_bit(k, KPF_LOCKED,PG_locked); >> >> u |= kpf_copy_bit(k, KPF_SLAB, PG_slab); >> diff --git a/include/linux/compaction.h b/include/linux/compaction.h >> index aa8f61c..f693072 100644 >> --- a/include/linux/compaction.h >> +++ b/include/linux/compaction.h >> @@ -1,6 +1,9 @@ >> #ifndef _LINUX_COMPACTION_H >> #define _LINUX_COMPACTION_H >> >> +#include >> +#include >> + >> /* Return values for compact_zone() and try_to_compact_pages() */ >> /* compaction didn't start as it was deferred due to past failures */ >> #define COMPACT_DEFERRED 0 >> @@ -51,6 +54,70 @@ extern void compaction_defer_reset(struct zone *zone, >> int order, >> bool alloc_success); >> extern bool compaction_restarting(struct zone *zone, int order); >> >> +static inline bool mobile_page(struct page *page) >> +{ >> + return page->mapping && (PageMobile(page) || PageBalloon(page)); >> +} > > > I would put this definition to linux/page-flags.h and rename it to > page_mobile (or better page_movable()), which is more common ordering. > >> + >> +static inline bool isolate_mobilepage(struct page *page, isolate_mode_t >> mode) > > > Does this have to be in compaction.h? The only user is compaction.c so > probably move it there, and if there ever is another module using this in > the future, we can move it to a more appropriate place and declare it in > e.g. mm/internal.h. > > >> +{ >> + bool ret = false; >> + >> + /* >> +* Avoid burning cycles with pages that are yet under >> __free_pages(), >> +* or just got freed under us. >> +* >> +* In case we 'win' a race for a mobile page being freed under us >> and >> +* raise its refcount preventing __free_pages() from doing its job >> +* the put_page() at the end of this block will take care of >> +* release this page, thus avoiding a nasty leakage. >> +*/ >> + if (unlikely(!get_page_unless_zero(page))) >> + goto out; >> + >> + /* >> +* As mobile pages are not isolated from LRU lists, concurrent >> +* compaction threads can race against page migration functions >> +* as well as race against the releasing a page. >> +* >> +* In order to avoid having an already isolated mobile page >> +* being (wrongly) re-isolated while it is under migration, >> +* or to avoid attempting to isolate pages being released, >> +* lets be sure we have the page lock >> +* before proceeding with the mobile page isolation steps. >> +*/ >> + if (unlikely(!trylock_page(page))) >> + goto out_putpage; >> + >> +
[PATCH 4/4] mm: remove direct calling of migration
On 07/13/2015 10:35 AM, Gioh Kim wrote: > From: Gioh Kim > > Migration is completely generalized so that migrating mobile page > is processed with lru-pages in move_to_new_page. > > Signed-off-by: Gioh Kim > Acked-by: Rafael Aquini Why not just fold this to Patch 3? You already modify this hunk there, and prior to patch 3, the hunk was balloon-pages specific. You made it look generic only to remove it, which is unneeded code churn and I don't think it adds anything wrt e.g. bisectability. > --- > mm/migrate.c | 15 --- > 1 file changed, 15 deletions(-) > > diff --git a/mm/migrate.c b/mm/migrate.c > index 53f0081d..e6644ac 100644 > --- a/mm/migrate.c > +++ b/mm/migrate.c > @@ -844,21 +844,6 @@ static int __unmap_and_move(struct page *page, struct > page *newpage, > } > } > > - if (unlikely(mobile_page(page))) { > - /* > - * A mobile page does not need any special attention from > - * physical to virtual reverse mapping procedures. > - * Skip any attempt to unmap PTEs or to remap swap cache, > - * in order to avoid burning cycles at rmap level, and perform > - * the page migration right away (proteced by page lock). > - */ > - lock_page(newpage); > - rc = page->mapping->a_ops->migratepage(page->mapping, > -newpage, page, mode); > - unlock_page(newpage); > - goto out_unlock; > - } > - > /* >* Corner case handling: >* 1. When a new swap-cache page is read into, it is added to the LRU >
[PATCH 2/5] drm/i2c: adv7511: Initial support for adv7533
On Sun 26 Jul 23:16 PDT 2015, Archit Taneja wrote: > From: Lars-Peter Clausen > [..] > diff --git a/drivers/gpu/drm/i2c/adv7511.c b/drivers/gpu/drm/i2c/adv7511.c [..] > > +static const struct of_device_id adv7511_of_ids[] = { > + { .compatible = "adi,adv7511", .data = (void *) ADV7511 }, > + { .compatible = "adi,adv7511w", .data = (void *) ADV7511 }, > + { .compatible = "adi,adv7513", .data = (void *) ADV7511 }, > + { .compatible = "adi,adv7533", .data = (void *) ADV7533 }, > + { } > +}; > +MODULE_DEVICE_TABLE(of, adv7511_of_ids); Please leave this at the bottom. > + > static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id > *id) > { > struct adv7511_link_config link_config; > @@ -871,9 +938,22 @@ static int adv7511_probe(struct i2c_client *i2c, const > struct i2c_device_id *id) > adv7511->powered = false; > adv7511->status = connector_status_disconnected; > > - ret = adv7511_parse_dt(dev->of_node, &link_config); > - if (ret) > - return ret; > + if (dev->of_node) { > + const struct of_device_id *of_id; > + > + of_id = of_match_node(adv7511_of_ids, dev->of_node); If you use of_device_get_match_data() instead you don't need to move the of_device_id table. > + adv7511->type = (enum adv7511_type) of_id->data; > + } else { > + adv7511->type = id->driver_data; > + } > + [..] > > static const struct i2c_device_id adv7511_i2c_ids[] = { > - { "adv7511", 0 }, > - { "adv7511w", 0 }, > - { "adv7513", 0 }, > + { "adv7511", ADV7511 }, > + { "adv7511w", ADV7511 }, > + { "adv7513", ADV7511 }, > + { "adv7533", ADV7533 }, > { } > }; > MODULE_DEVICE_TABLE(i2c, adv7511_i2c_ids); > > -static const struct of_device_id adv7511_of_ids[] = { > - { .compatible = "adi,adv7511", }, > - { .compatible = "adi,adv7511w", }, > - { .compatible = "adi,adv7513", }, > - { } > -}; > -MODULE_DEVICE_TABLE(of, adv7511_of_ids); > - Regards, Bjorn
[PATCH v3] gpu/drm: kill off set_irq_flags usage
set_irq_flags is ARM specific with custom flags which have genirq equivalents. Convert drivers to use the genirq interfaces directly, so we can kill off set_irq_flags. The translation of flags is as follows: IRQF_VALID -> !IRQ_NOREQUEST IRQF_PROBE -> !IRQ_NOPROBE IRQF_NOAUTOEN -> IRQ_NOAUTOEN For IRQs managed by an irqdomain, the irqdomain core code handles clearing and setting IRQ_NOREQUEST already, so there is no need to do this in .map() functions and we can simply remove the set_irq_flags calls. Some users also modify IRQ_NOPROBE and this has been maintained although it is not clear that is really needed. There appears to be a great deal of blind copy and paste of this code. Signed-off-by: Rob Herring Cc: David Airlie Cc: dri-devel at lists.freedesktop.org --- Thomas asked that this be merged thru subsystem trees instead of arm-soc, so please apply this to your tree. Rob drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c | 1 - drivers/gpu/ipu-v3/ipu-common.c | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c index 33bd4c6..9a6a747 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c @@ -165,7 +165,6 @@ static int mdp5_hw_irqdomain_map(struct irq_domain *d, irq_set_chip_and_handler(irq, &mdp5_hw_irq_chip, handle_level_irq); irq_set_chip_data(irq, mdp5_kms); - set_irq_flags(irq, IRQF_VALID); return 0; } diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index 00f2058..4ac9e05 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c @@ -1099,8 +1099,7 @@ static int ipu_irq_init(struct ipu_soc *ipu) } ret = irq_alloc_domain_generic_chips(ipu->domain, 32, 1, "IPU", -handle_level_irq, 0, -IRQF_VALID, 0); +handle_level_irq, 0, 0, 0); if (ret < 0) { dev_err(ipu->dev, "failed to alloc generic irq chips\n"); irq_domain_remove(ipu->domain); -- 2.1.0