Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'imx-drm-next-2016-07-14' of git://git.pengutronix.de/git/pza/linux into drm-next

imx-drm updates

- atomic mode setting conversion
- replace DMFC FIFO allocation mechanism with a fixed allocation
that is good enough for all cases
- support for external bridges connected to parallel-display
- improved error handling in imx-ldb, imx-tve, and parallel-display
- some code cleanup in imx-tve

* tag 'imx-drm-next-2016-07-14' of git://git.pengutronix.de/git/pza/linux:
drm/imx: parallel-display: add bridge support
drm/imx: parallel-display: check return code from of_get_drm_display_mode()
gpu: ipu-v3: ipu-dc: don't bug out on invalid bus_format
drm/imx: imx-tve: fix the error message
drm/imx: imx-tve: remove unneeded 'or' operation
drm/imx: imx-tve: check the value returned by regulator_set_voltage()
drm/imx: imx-ldb: check return code on panel attach
drm/imx: turn remaining container_of macros into inline functions
drm/imx: store internal bus configuration in crtc state
drm/imx: remove empty mode_set encoder callbacks
drm/imx: atomic phase 3 step 3: Advertise DRIVER_ATOMIC
drm/imx: atomic phase 3 step 2: Legacy callback fixups
drm/bridge: dw-hdmi: Remove the legacy drm_connector_funcs structure
drm/imx: atomic phase 3 step 1: Use atomic configuration
drm/imx: Remove encoders' ->prepare callbacks
drm/imx: atomic phase 2 step 2: Track plane_state->fb correctly in ->page_flip
drm/imx: atomic phase 2 step 1: Wire up state ->reset, ->duplicate and ->destroy
drm/imx: atomic phase 1: Use transitional atomic CRTC and plane helpers
gpu: ipu-v3: ipu-dmfc: Use static DMFC FIFO allocation mechanism
drm/imx: ipuv3 plane: Check different types of plane separately

+803 -1063
+3 -16
drivers/gpu/drm/bridge/dw-hdmi.c
··· 1495 1495 } 1496 1496 1497 1497 static const struct drm_connector_funcs dw_hdmi_connector_funcs = { 1498 - .dpms = drm_helper_connector_dpms, 1499 - .fill_modes = drm_helper_probe_single_connector_modes, 1500 - .detect = dw_hdmi_connector_detect, 1501 - .destroy = dw_hdmi_connector_destroy, 1502 - .force = dw_hdmi_connector_force, 1503 - }; 1504 - 1505 - static const struct drm_connector_funcs dw_hdmi_atomic_connector_funcs = { 1506 1498 .dpms = drm_atomic_helper_connector_dpms, 1507 1499 .fill_modes = drm_helper_probe_single_connector_modes, 1508 1500 .detect = dw_hdmi_connector_detect, ··· 1626 1634 drm_connector_helper_add(&hdmi->connector, 1627 1635 &dw_hdmi_connector_helper_funcs); 1628 1636 1629 - if (drm_core_check_feature(drm, DRIVER_ATOMIC)) 1630 - drm_connector_init(drm, &hdmi->connector, 1631 - &dw_hdmi_atomic_connector_funcs, 1632 - DRM_MODE_CONNECTOR_HDMIA); 1633 - else 1634 - drm_connector_init(drm, &hdmi->connector, 1635 - &dw_hdmi_connector_funcs, 1636 - DRM_MODE_CONNECTOR_HDMIA); 1637 + drm_connector_init(drm, &hdmi->connector, 1638 + &dw_hdmi_connector_funcs, 1639 + DRM_MODE_CONNECTOR_HDMIA); 1637 1640 1638 1641 drm_mode_connector_attach_encoder(&hdmi->connector, encoder); 1639 1642
+19 -13
drivers/gpu/drm/imx/dw_hdmi-imx.c
··· 28 28 struct regmap *regmap; 29 29 }; 30 30 31 + static inline struct imx_hdmi *enc_to_imx_hdmi(struct drm_encoder *e) 32 + { 33 + return container_of(e, struct imx_hdmi, encoder); 34 + } 35 + 31 36 static const struct dw_hdmi_mpll_config imx_mpll_cfg[] = { 32 37 { 33 38 45250000, { ··· 114 109 { 115 110 } 116 111 117 - static void dw_hdmi_imx_encoder_mode_set(struct drm_encoder *encoder, 118 - struct drm_display_mode *mode, 119 - struct drm_display_mode *adj_mode) 112 + static void dw_hdmi_imx_encoder_enable(struct drm_encoder *encoder) 120 113 { 121 - } 122 - 123 - static void dw_hdmi_imx_encoder_commit(struct drm_encoder *encoder) 124 - { 125 - struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder); 114 + struct imx_hdmi *hdmi = enc_to_imx_hdmi(encoder); 126 115 int mux = drm_of_encoder_active_port_id(hdmi->dev->of_node, encoder); 127 116 128 117 regmap_update_bits(hdmi->regmap, IOMUXC_GPR3, ··· 124 125 mux << IMX6Q_GPR3_HDMI_MUX_CTL_SHIFT); 125 126 } 126 127 127 - static void dw_hdmi_imx_encoder_prepare(struct drm_encoder *encoder) 128 + static int dw_hdmi_imx_atomic_check(struct drm_encoder *encoder, 129 + struct drm_crtc_state *crtc_state, 130 + struct drm_connector_state *conn_state) 128 131 { 129 - imx_drm_set_bus_format(encoder, MEDIA_BUS_FMT_RGB888_1X24); 132 + struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc_state); 133 + 134 + imx_crtc_state->bus_format = MEDIA_BUS_FMT_RGB888_1X24; 135 + imx_crtc_state->di_hsync_pin = 2; 136 + imx_crtc_state->di_vsync_pin = 3; 137 + 138 + return 0; 130 139 } 131 140 132 141 static const struct drm_encoder_helper_funcs dw_hdmi_imx_encoder_helper_funcs = { 133 - .mode_set = dw_hdmi_imx_encoder_mode_set, 134 - .prepare = dw_hdmi_imx_encoder_prepare, 135 - .commit = dw_hdmi_imx_encoder_commit, 142 + .enable = dw_hdmi_imx_encoder_enable, 136 143 .disable = dw_hdmi_imx_encoder_disable, 144 + .atomic_check = dw_hdmi_imx_atomic_check, 137 145 }; 138 146 139 147 static const struct drm_encoder_funcs dw_hdmi_imx_encoder_funcs = {
+78 -42
drivers/gpu/drm/imx/imx-drm-core.c
··· 15 15 */ 16 16 #include <linux/component.h> 17 17 #include <linux/device.h> 18 + #include <linux/dma-buf.h> 18 19 #include <linux/fb.h> 19 20 #include <linux/module.h> 20 21 #include <linux/platform_device.h> 22 + #include <linux/reservation.h> 21 23 #include <drm/drmP.h> 24 + #include <drm/drm_atomic.h> 25 + #include <drm/drm_atomic_helper.h> 22 26 #include <drm/drm_fb_helper.h> 23 27 #include <drm/drm_crtc_helper.h> 24 28 #include <drm/drm_gem_cma_helper.h> ··· 45 41 struct imx_drm_crtc *crtc[MAX_CRTC]; 46 42 unsigned int pipes; 47 43 struct drm_fbdev_cma *fbhelper; 44 + struct drm_atomic_state *state; 48 45 }; 49 46 50 47 struct imx_drm_crtc { ··· 89 84 90 85 return 0; 91 86 } 92 - 93 - static struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc) 94 - { 95 - struct imx_drm_device *imxdrm = crtc->dev->dev_private; 96 - unsigned i; 97 - 98 - for (i = 0; i < MAX_CRTC; i++) 99 - if (imxdrm->crtc[i] && imxdrm->crtc[i]->crtc == crtc) 100 - return imxdrm->crtc[i]; 101 - 102 - return NULL; 103 - } 104 - 105 - int imx_drm_set_bus_config(struct drm_encoder *encoder, u32 bus_format, 106 - int hsync_pin, int vsync_pin, u32 bus_flags) 107 - { 108 - struct imx_drm_crtc_helper_funcs *helper; 109 - struct imx_drm_crtc *imx_crtc; 110 - 111 - imx_crtc = imx_drm_find_crtc(encoder->crtc); 112 - if (!imx_crtc) 113 - return -EINVAL; 114 - 115 - helper = &imx_crtc->imx_drm_helper_funcs; 116 - if (helper->set_interface_pix_fmt) 117 - return helper->set_interface_pix_fmt(encoder->crtc, 118 - bus_format, hsync_pin, vsync_pin, 119 - bus_flags); 120 - return 0; 121 - } 122 - EXPORT_SYMBOL_GPL(imx_drm_set_bus_config); 123 - 124 - int imx_drm_set_bus_format(struct drm_encoder *encoder, u32 bus_format) 125 - { 126 - return imx_drm_set_bus_config(encoder, bus_format, 2, 3, 127 - DRM_BUS_FLAG_DE_HIGH | 128 - DRM_BUS_FLAG_PIXDATA_NEGEDGE); 129 - } 130 - EXPORT_SYMBOL_GPL(imx_drm_set_bus_format); 131 87 132 88 int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc) 133 89 { ··· 174 208 static const struct drm_mode_config_funcs imx_drm_mode_config_funcs = { 175 209 .fb_create = drm_fb_cma_create, 176 210 .output_poll_changed = imx_drm_output_poll_changed, 211 + .atomic_check = drm_atomic_helper_check, 212 + .atomic_commit = drm_atomic_helper_commit, 213 + }; 214 + 215 + static void imx_drm_atomic_commit_tail(struct drm_atomic_state *state) 216 + { 217 + struct drm_device *dev = state->dev; 218 + struct drm_crtc *crtc; 219 + struct drm_crtc_state *crtc_state; 220 + struct drm_plane_state *plane_state; 221 + struct drm_gem_cma_object *cma_obj; 222 + struct fence *excl; 223 + unsigned shared_count; 224 + struct fence **shared; 225 + unsigned int i, j; 226 + int ret; 227 + 228 + /* Wait for fences. */ 229 + for_each_crtc_in_state(state, crtc, crtc_state, i) { 230 + plane_state = crtc->primary->state; 231 + if (plane_state->fb) { 232 + cma_obj = drm_fb_cma_get_gem_obj(plane_state->fb, 0); 233 + if (cma_obj->base.dma_buf) { 234 + ret = reservation_object_get_fences_rcu( 235 + cma_obj->base.dma_buf->resv, &excl, 236 + &shared_count, &shared); 237 + if (unlikely(ret)) 238 + DRM_ERROR("failed to get fences " 239 + "for buffer\n"); 240 + 241 + if (excl) { 242 + fence_wait(excl, false); 243 + fence_put(excl); 244 + } 245 + for (j = 0; j < shared_count; i++) { 246 + fence_wait(shared[j], false); 247 + fence_put(shared[j]); 248 + } 249 + } 250 + } 251 + } 252 + 253 + drm_atomic_helper_commit_modeset_disables(dev, state); 254 + 255 + drm_atomic_helper_commit_planes(dev, state, true); 256 + 257 + drm_atomic_helper_commit_modeset_enables(dev, state); 258 + 259 + drm_atomic_helper_commit_hw_done(state); 260 + 261 + drm_atomic_helper_wait_for_vblanks(dev, state); 262 + 263 + drm_atomic_helper_cleanup_planes(dev, state); 264 + } 265 + 266 + static struct drm_mode_config_helper_funcs imx_drm_mode_config_helpers = { 267 + .atomic_commit_tail = imx_drm_atomic_commit_tail, 177 268 }; 178 269 179 270 /* ··· 272 249 drm->mode_config.max_width = 4096; 273 250 drm->mode_config.max_height = 4096; 274 251 drm->mode_config.funcs = &imx_drm_mode_config_funcs; 252 + drm->mode_config.helper_private = &imx_drm_mode_config_helpers; 275 253 276 254 drm_mode_config_init(drm); 277 255 ··· 303 279 } 304 280 } 305 281 282 + drm_mode_config_reset(drm); 283 + 306 284 /* 307 285 * All components are now initialised, so setup the fb helper. 308 286 * The fb helper takes copies of key hardware information, so the ··· 315 289 dev_warn(drm->dev, "Invalid legacyfb_depth. Defaulting to 16bpp\n"); 316 290 legacyfb_depth = 16; 317 291 } 318 - drm_helper_disable_unused_functions(drm); 319 292 imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth, 320 293 drm->mode_config.num_crtc, MAX_CRTC); 321 294 if (IS_ERR(imxdrm->fbhelper)) { ··· 428 403 }; 429 404 430 405 static struct drm_driver imx_drm_driver = { 431 - .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME, 406 + .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | 407 + DRIVER_ATOMIC, 432 408 .load = imx_drm_driver_load, 433 409 .unload = imx_drm_driver_unload, 434 410 .lastclose = imx_drm_driver_lastclose, ··· 517 491 static int imx_drm_suspend(struct device *dev) 518 492 { 519 493 struct drm_device *drm_dev = dev_get_drvdata(dev); 494 + struct imx_drm_device *imxdrm; 520 495 521 496 /* The drm_dev is NULL before .load hook is called */ 522 497 if (drm_dev == NULL) ··· 525 498 526 499 drm_kms_helper_poll_disable(drm_dev); 527 500 501 + imxdrm = drm_dev->dev_private; 502 + imxdrm->state = drm_atomic_helper_suspend(drm_dev); 503 + if (IS_ERR(imxdrm->state)) { 504 + drm_kms_helper_poll_enable(drm_dev); 505 + return PTR_ERR(imxdrm->state); 506 + } 507 + 528 508 return 0; 529 509 } 530 510 531 511 static int imx_drm_resume(struct device *dev) 532 512 { 533 513 struct drm_device *drm_dev = dev_get_drvdata(dev); 514 + struct imx_drm_device *imx_drm; 534 515 535 516 if (drm_dev == NULL) 536 517 return 0; 537 518 538 - drm_helper_resume_force_mode(drm_dev); 519 + imx_drm = drm_dev->dev_private; 520 + drm_atomic_helper_resume(drm_dev, imx_drm->state); 539 521 drm_kms_helper_poll_enable(drm_dev); 540 522 541 523 return 0;
+13 -8
drivers/gpu/drm/imx/imx-drm.h
··· 15 15 16 16 unsigned int imx_drm_crtc_id(struct imx_drm_crtc *crtc); 17 17 18 + struct imx_crtc_state { 19 + struct drm_crtc_state base; 20 + u32 bus_format; 21 + u32 bus_flags; 22 + int di_hsync_pin; 23 + int di_vsync_pin; 24 + }; 25 + 26 + static inline struct imx_crtc_state *to_imx_crtc_state(struct drm_crtc_state *s) 27 + { 28 + return container_of(s, struct imx_crtc_state, base); 29 + } 30 + 18 31 struct imx_drm_crtc_helper_funcs { 19 32 int (*enable_vblank)(struct drm_crtc *crtc); 20 33 void (*disable_vblank)(struct drm_crtc *crtc); 21 - int (*set_interface_pix_fmt)(struct drm_crtc *crtc, 22 - u32 bus_format, int hsync_pin, int vsync_pin, 23 - u32 bus_flags); 24 34 const struct drm_crtc_helper_funcs *crtc_helper_funcs; 25 35 const struct drm_crtc_funcs *crtc_funcs; 26 36 }; ··· 51 41 void imx_drm_mode_config_init(struct drm_device *drm); 52 42 53 43 struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb); 54 - 55 - int imx_drm_set_bus_config(struct drm_encoder *encoder, u32 bus_format, 56 - int hsync_pin, int vsync_pin, u32 bus_flags); 57 - int imx_drm_set_bus_format(struct drm_encoder *encoder, 58 - u32 bus_format); 59 44 60 45 int imx_drm_encoder_parse_of(struct drm_device *drm, 61 46 struct drm_encoder *encoder, struct device_node *np);
+122 -70
drivers/gpu/drm/imx/imx-ldb.c
··· 17 17 #include <linux/clk.h> 18 18 #include <linux/component.h> 19 19 #include <drm/drmP.h> 20 + #include <drm/drm_atomic.h> 21 + #include <drm/drm_atomic_helper.h> 20 22 #include <drm/drm_fb_helper.h> 21 23 #include <drm/drm_crtc_helper.h> 22 24 #include <drm/drm_of.h> ··· 51 49 #define LDB_DI1_VS_POL_ACT_LOW (1 << 10) 52 50 #define LDB_BGREF_RMODE_INT (1 << 15) 53 51 54 - #define con_to_imx_ldb_ch(x) container_of(x, struct imx_ldb_channel, connector) 55 - #define enc_to_imx_ldb_ch(x) container_of(x, struct imx_ldb_channel, encoder) 56 - 57 52 struct imx_ldb; 58 53 59 54 struct imx_ldb_channel { ··· 65 66 int edid_len; 66 67 struct drm_display_mode mode; 67 68 int mode_valid; 68 - int bus_format; 69 + u32 bus_format; 69 70 }; 71 + 72 + static inline struct imx_ldb_channel *con_to_imx_ldb_ch(struct drm_connector *c) 73 + { 74 + return container_of(c, struct imx_ldb_channel, connector); 75 + } 76 + 77 + static inline struct imx_ldb_channel *enc_to_imx_ldb_ch(struct drm_encoder *e) 78 + { 79 + return container_of(e, struct imx_ldb_channel, encoder); 80 + } 70 81 71 82 struct bus_mux { 72 83 int reg; ··· 102 93 return connector_status_connected; 103 94 } 104 95 96 + static void imx_ldb_ch_set_bus_format(struct imx_ldb_channel *imx_ldb_ch, 97 + u32 bus_format) 98 + { 99 + struct imx_ldb *ldb = imx_ldb_ch->ldb; 100 + int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; 101 + 102 + switch (bus_format) { 103 + case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: 104 + break; 105 + case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: 106 + if (imx_ldb_ch->chno == 0 || dual) 107 + ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24; 108 + if (imx_ldb_ch->chno == 1 || dual) 109 + ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24; 110 + break; 111 + case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: 112 + if (imx_ldb_ch->chno == 0 || dual) 113 + ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24 | 114 + LDB_BIT_MAP_CH0_JEIDA; 115 + if (imx_ldb_ch->chno == 1 || dual) 116 + ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24 | 117 + LDB_BIT_MAP_CH1_JEIDA; 118 + break; 119 + } 120 + } 121 + 105 122 static int imx_ldb_connector_get_modes(struct drm_connector *connector) 106 123 { 107 124 struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector); ··· 135 100 136 101 if (imx_ldb_ch->panel && imx_ldb_ch->panel->funcs && 137 102 imx_ldb_ch->panel->funcs->get_modes) { 138 - struct drm_display_info *di = &connector->display_info; 139 - 140 103 num_modes = imx_ldb_ch->panel->funcs->get_modes(imx_ldb_ch->panel); 141 - if (!imx_ldb_ch->bus_format && di->num_bus_formats) 142 - imx_ldb_ch->bus_format = di->bus_formats[0]; 143 104 if (num_modes > 0) 144 105 return num_modes; 145 106 } ··· 172 141 return &imx_ldb_ch->encoder; 173 142 } 174 143 175 - static void imx_ldb_encoder_dpms(struct drm_encoder *encoder, int mode) 176 - { 177 - } 178 - 179 144 static void imx_ldb_set_clock(struct imx_ldb *ldb, int mux, int chno, 180 145 unsigned long serial_clk, unsigned long di_clk) 181 146 { ··· 200 173 chno); 201 174 } 202 175 203 - static void imx_ldb_encoder_prepare(struct drm_encoder *encoder) 204 - { 205 - struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); 206 - struct imx_ldb *ldb = imx_ldb_ch->ldb; 207 - int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; 208 - u32 bus_format; 209 - 210 - switch (imx_ldb_ch->bus_format) { 211 - default: 212 - dev_warn(ldb->dev, 213 - "could not determine data mapping, default to 18-bit \"spwg\"\n"); 214 - /* fallthrough */ 215 - case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: 216 - bus_format = MEDIA_BUS_FMT_RGB666_1X18; 217 - break; 218 - case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: 219 - bus_format = MEDIA_BUS_FMT_RGB888_1X24; 220 - if (imx_ldb_ch->chno == 0 || dual) 221 - ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24; 222 - if (imx_ldb_ch->chno == 1 || dual) 223 - ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24; 224 - break; 225 - case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: 226 - bus_format = MEDIA_BUS_FMT_RGB888_1X24; 227 - if (imx_ldb_ch->chno == 0 || dual) 228 - ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24 | 229 - LDB_BIT_MAP_CH0_JEIDA; 230 - if (imx_ldb_ch->chno == 1 || dual) 231 - ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24 | 232 - LDB_BIT_MAP_CH1_JEIDA; 233 - break; 234 - } 235 - 236 - imx_drm_set_bus_format(encoder, bus_format); 237 - } 238 - 239 - static void imx_ldb_encoder_commit(struct drm_encoder *encoder) 176 + static void imx_ldb_encoder_enable(struct drm_encoder *encoder) 240 177 { 241 178 struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); 242 179 struct imx_ldb *ldb = imx_ldb_ch->ldb; ··· 210 219 drm_panel_prepare(imx_ldb_ch->panel); 211 220 212 221 if (dual) { 222 + clk_set_parent(ldb->clk_sel[mux], ldb->clk[0]); 223 + clk_set_parent(ldb->clk_sel[mux], ldb->clk[1]); 224 + 213 225 clk_prepare_enable(ldb->clk[0]); 214 226 clk_prepare_enable(ldb->clk[1]); 227 + } else { 228 + clk_set_parent(ldb->clk_sel[mux], ldb->clk[imx_ldb_ch->chno]); 215 229 } 216 230 217 231 if (imx_ldb_ch == &ldb->channel[0] || dual) { ··· 261 265 unsigned long serial_clk; 262 266 unsigned long di_clk = mode->clock * 1000; 263 267 int mux = drm_of_encoder_active_port_id(imx_ldb_ch->child, encoder); 268 + u32 bus_format = imx_ldb_ch->bus_format; 264 269 265 270 if (mode->clock > 170000) { 266 271 dev_warn(ldb->dev, ··· 283 286 } 284 287 285 288 /* FIXME - assumes straight connections DI0 --> CH0, DI1 --> CH1 */ 286 - if (imx_ldb_ch == &ldb->channel[0]) { 289 + if (imx_ldb_ch == &ldb->channel[0] || dual) { 287 290 if (mode->flags & DRM_MODE_FLAG_NVSYNC) 288 291 ldb->ldb_ctrl |= LDB_DI0_VS_POL_ACT_LOW; 289 292 else if (mode->flags & DRM_MODE_FLAG_PVSYNC) 290 293 ldb->ldb_ctrl &= ~LDB_DI0_VS_POL_ACT_LOW; 291 294 } 292 - if (imx_ldb_ch == &ldb->channel[1]) { 295 + if (imx_ldb_ch == &ldb->channel[1] || dual) { 293 296 if (mode->flags & DRM_MODE_FLAG_NVSYNC) 294 297 ldb->ldb_ctrl |= LDB_DI1_VS_POL_ACT_LOW; 295 298 else if (mode->flags & DRM_MODE_FLAG_PVSYNC) 296 299 ldb->ldb_ctrl &= ~LDB_DI1_VS_POL_ACT_LOW; 297 300 } 301 + 302 + if (!bus_format) { 303 + struct drm_connector_state *conn_state; 304 + struct drm_connector *connector; 305 + int i; 306 + 307 + for_each_connector_in_state(encoder->crtc->state->state, 308 + connector, conn_state, i) { 309 + struct drm_display_info *di = &connector->display_info; 310 + 311 + if (conn_state->crtc == encoder->crtc && 312 + di->num_bus_formats) { 313 + bus_format = di->bus_formats[0]; 314 + break; 315 + } 316 + } 317 + } 318 + imx_ldb_ch_set_bus_format(imx_ldb_ch, bus_format); 298 319 } 299 320 300 321 static void imx_ldb_encoder_disable(struct drm_encoder *encoder) ··· 372 357 drm_panel_unprepare(imx_ldb_ch->panel); 373 358 } 374 359 360 + static int imx_ldb_encoder_atomic_check(struct drm_encoder *encoder, 361 + struct drm_crtc_state *crtc_state, 362 + struct drm_connector_state *conn_state) 363 + { 364 + struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc_state); 365 + struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); 366 + struct drm_display_info *di = &conn_state->connector->display_info; 367 + u32 bus_format = imx_ldb_ch->bus_format; 368 + 369 + /* Bus format description in DT overrides connector display info. */ 370 + if (!bus_format && di->num_bus_formats) 371 + bus_format = di->bus_formats[0]; 372 + switch (bus_format) { 373 + case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: 374 + imx_crtc_state->bus_format = MEDIA_BUS_FMT_RGB666_1X18; 375 + break; 376 + case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: 377 + case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: 378 + imx_crtc_state->bus_format = MEDIA_BUS_FMT_RGB888_1X24; 379 + break; 380 + default: 381 + return -EINVAL; 382 + } 383 + 384 + imx_crtc_state->di_hsync_pin = 2; 385 + imx_crtc_state->di_vsync_pin = 3; 386 + 387 + return 0; 388 + } 389 + 390 + 375 391 static const struct drm_connector_funcs imx_ldb_connector_funcs = { 376 - .dpms = drm_helper_connector_dpms, 392 + .dpms = drm_atomic_helper_connector_dpms, 377 393 .fill_modes = drm_helper_probe_single_connector_modes, 378 394 .detect = imx_ldb_connector_detect, 379 395 .destroy = imx_drm_connector_destroy, 396 + .reset = drm_atomic_helper_connector_reset, 397 + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 398 + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 380 399 }; 381 400 382 401 static const struct drm_connector_helper_funcs imx_ldb_connector_helper_funcs = { ··· 423 374 }; 424 375 425 376 static const struct drm_encoder_helper_funcs imx_ldb_encoder_helper_funcs = { 426 - .dpms = imx_ldb_encoder_dpms, 427 - .prepare = imx_ldb_encoder_prepare, 428 - .commit = imx_ldb_encoder_commit, 429 377 .mode_set = imx_ldb_encoder_mode_set, 378 + .enable = imx_ldb_encoder_enable, 430 379 .disable = imx_ldb_encoder_disable, 380 + .atomic_check = imx_ldb_encoder_atomic_check, 431 381 }; 432 382 433 383 static int imx_ldb_get_clk(struct imx_ldb *ldb, int chno) ··· 448 400 struct imx_ldb_channel *imx_ldb_ch) 449 401 { 450 402 struct imx_ldb *ldb = imx_ldb_ch->ldb; 403 + struct drm_encoder *encoder = &imx_ldb_ch->encoder; 451 404 int ret; 452 405 453 - ret = imx_drm_encoder_parse_of(drm, &imx_ldb_ch->encoder, 454 - imx_ldb_ch->child); 406 + ret = imx_drm_encoder_parse_of(drm, encoder, imx_ldb_ch->child); 455 407 if (ret) 456 408 return ret; 457 409 ··· 465 417 return ret; 466 418 } 467 419 468 - drm_encoder_helper_add(&imx_ldb_ch->encoder, 469 - &imx_ldb_encoder_helper_funcs); 470 - drm_encoder_init(drm, &imx_ldb_ch->encoder, &imx_ldb_encoder_funcs, 420 + drm_encoder_helper_add(encoder, &imx_ldb_encoder_helper_funcs); 421 + drm_encoder_init(drm, encoder, &imx_ldb_encoder_funcs, 471 422 DRM_MODE_ENCODER_LVDS, NULL); 472 423 473 424 drm_connector_helper_add(&imx_ldb_ch->connector, ··· 474 427 drm_connector_init(drm, &imx_ldb_ch->connector, 475 428 &imx_ldb_connector_funcs, DRM_MODE_CONNECTOR_LVDS); 476 429 477 - if (imx_ldb_ch->panel) 478 - drm_panel_attach(imx_ldb_ch->panel, &imx_ldb_ch->connector); 430 + if (imx_ldb_ch->panel) { 431 + ret = drm_panel_attach(imx_ldb_ch->panel, 432 + &imx_ldb_ch->connector); 433 + if (ret) 434 + return ret; 435 + } 479 436 480 - drm_mode_connector_attach_encoder(&imx_ldb_ch->connector, 481 - &imx_ldb_ch->encoder); 437 + drm_mode_connector_attach_encoder(&imx_ldb_ch->connector, encoder); 482 438 483 439 return 0; 484 440 } ··· 610 560 struct imx_ldb_channel *channel; 611 561 struct device_node *ddc_node; 612 562 struct device_node *ep; 563 + int bus_format; 613 564 614 565 ret = of_property_read_u32(child, "reg", &i); 615 566 if (ret || i < 0 || i > 1) ··· 683 632 } 684 633 } 685 634 686 - channel->bus_format = of_get_bus_format(dev, child); 687 - if (channel->bus_format == -EINVAL) { 635 + bus_format = of_get_bus_format(dev, child); 636 + if (bus_format == -EINVAL) { 688 637 /* 689 638 * If no bus format was specified in the device tree, 690 639 * we can still get it from the connected panel later. 691 640 */ 692 641 if (channel->panel && channel->panel->funcs && 693 642 channel->panel->funcs->get_modes) 694 - channel->bus_format = 0; 643 + bus_format = 0; 695 644 } 696 - if (channel->bus_format < 0) { 645 + if (bus_format < 0) { 697 646 dev_err(dev, "could not determine data mapping: %d\n", 698 - channel->bus_format); 699 - return channel->bus_format; 647 + bus_format); 648 + return bus_format; 700 649 } 650 + channel->bus_format = bus_format; 701 651 702 652 ret = imx_ldb_register(drm, channel); 703 653 if (ret)
+47 -50
drivers/gpu/drm/imx/imx-tve.c
··· 23 23 #include <linux/spinlock.h> 24 24 #include <linux/videodev2.h> 25 25 #include <drm/drmP.h> 26 + #include <drm/drm_atomic_helper.h> 26 27 #include <drm/drm_fb_helper.h> 27 28 #include <drm/drm_crtc_helper.h> 28 29 #include <video/imx-ipu-v3.h> ··· 98 97 /* TVE_TST_MODE_REG */ 99 98 #define TVE_TVDAC_TEST_MODE_MASK (0x7 << 0) 100 99 101 - #define con_to_tve(x) container_of(x, struct imx_tve, connector) 102 - #define enc_to_tve(x) container_of(x, struct imx_tve, encoder) 103 - 104 100 enum { 105 101 TVE_MODE_TVOUT, 106 102 TVE_MODE_VGA, ··· 110 112 spinlock_t lock; /* register lock */ 111 113 bool enabled; 112 114 int mode; 115 + int di_hsync_pin; 116 + int di_vsync_pin; 113 117 114 118 struct regmap *regmap; 115 119 struct regulator *dac_reg; ··· 120 120 struct clk *di_sel_clk; 121 121 struct clk_hw clk_hw_di; 122 122 struct clk *di_clk; 123 - int vsync_pin; 124 - int hsync_pin; 125 123 }; 124 + 125 + static inline struct imx_tve *con_to_tve(struct drm_connector *c) 126 + { 127 + return container_of(c, struct imx_tve, connector); 128 + } 129 + 130 + static inline struct imx_tve *enc_to_tve(struct drm_encoder *e) 131 + { 132 + return container_of(e, struct imx_tve, encoder); 133 + } 126 134 127 135 static void tve_lock(void *__tve) 128 136 __acquires(&tve->lock) ··· 156 148 tve->enabled = true; 157 149 clk_prepare_enable(tve->clk); 158 150 ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG, 159 - TVE_IPU_CLK_EN | TVE_EN, 160 - TVE_IPU_CLK_EN | TVE_EN); 151 + TVE_EN, TVE_EN); 161 152 } 162 153 163 154 /* clear interrupt status register */ ··· 179 172 if (tve->enabled) { 180 173 tve->enabled = false; 181 174 ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG, 182 - TVE_IPU_CLK_EN | TVE_EN, 0); 175 + TVE_EN, 0); 183 176 clk_disable_unprepare(tve->clk); 184 177 } 185 178 } ··· 282 275 return &tve->encoder; 283 276 } 284 277 285 - static void imx_tve_encoder_dpms(struct drm_encoder *encoder, int mode) 286 - { 287 - struct imx_tve *tve = enc_to_tve(encoder); 288 - int ret; 289 - 290 - ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG, 291 - TVE_TV_OUT_MODE_MASK, TVE_TV_OUT_DISABLE); 292 - if (ret < 0) 293 - dev_err(tve->dev, "failed to disable TVOUT: %d\n", ret); 294 - } 295 - 296 - static void imx_tve_encoder_prepare(struct drm_encoder *encoder) 297 - { 298 - struct imx_tve *tve = enc_to_tve(encoder); 299 - 300 - tve_disable(tve); 301 - 302 - switch (tve->mode) { 303 - case TVE_MODE_VGA: 304 - imx_drm_set_bus_config(encoder, MEDIA_BUS_FMT_GBR888_1X24, 305 - tve->hsync_pin, tve->vsync_pin, 306 - DRM_BUS_FLAG_DE_HIGH | 307 - DRM_BUS_FLAG_PIXDATA_NEGEDGE); 308 - break; 309 - case TVE_MODE_TVOUT: 310 - imx_drm_set_bus_format(encoder, MEDIA_BUS_FMT_YUV8_1X24); 311 - break; 312 - } 313 - } 314 - 315 278 static void imx_tve_encoder_mode_set(struct drm_encoder *encoder, 316 279 struct drm_display_mode *orig_mode, 317 280 struct drm_display_mode *mode) ··· 310 333 ret); 311 334 } 312 335 336 + regmap_update_bits(tve->regmap, TVE_COM_CONF_REG, 337 + TVE_IPU_CLK_EN, TVE_IPU_CLK_EN); 338 + 313 339 if (tve->mode == TVE_MODE_VGA) 314 340 ret = tve_setup_vga(tve); 315 341 else ··· 321 341 dev_err(tve->dev, "failed to set configuration: %d\n", ret); 322 342 } 323 343 324 - static void imx_tve_encoder_commit(struct drm_encoder *encoder) 344 + static void imx_tve_encoder_enable(struct drm_encoder *encoder) 325 345 { 326 346 struct imx_tve *tve = enc_to_tve(encoder); 327 347 ··· 335 355 tve_disable(tve); 336 356 } 337 357 358 + static int imx_tve_atomic_check(struct drm_encoder *encoder, 359 + struct drm_crtc_state *crtc_state, 360 + struct drm_connector_state *conn_state) 361 + { 362 + struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc_state); 363 + struct imx_tve *tve = enc_to_tve(encoder); 364 + 365 + imx_crtc_state->bus_format = MEDIA_BUS_FMT_GBR888_1X24; 366 + imx_crtc_state->di_hsync_pin = tve->di_hsync_pin; 367 + imx_crtc_state->di_vsync_pin = tve->di_vsync_pin; 368 + 369 + return 0; 370 + } 371 + 338 372 static const struct drm_connector_funcs imx_tve_connector_funcs = { 339 - .dpms = drm_helper_connector_dpms, 373 + .dpms = drm_atomic_helper_connector_dpms, 340 374 .fill_modes = drm_helper_probe_single_connector_modes, 341 375 .detect = imx_tve_connector_detect, 342 376 .destroy = imx_drm_connector_destroy, 377 + .reset = drm_atomic_helper_connector_reset, 378 + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 379 + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 343 380 }; 344 381 345 382 static const struct drm_connector_helper_funcs imx_tve_connector_helper_funcs = { ··· 370 373 }; 371 374 372 375 static const struct drm_encoder_helper_funcs imx_tve_encoder_helper_funcs = { 373 - .dpms = imx_tve_encoder_dpms, 374 - .prepare = imx_tve_encoder_prepare, 375 376 .mode_set = imx_tve_encoder_mode_set, 376 - .commit = imx_tve_encoder_commit, 377 + .enable = imx_tve_encoder_enable, 377 378 .disable = imx_tve_encoder_disable, 379 + .atomic_check = imx_tve_atomic_check, 378 380 }; 379 381 380 382 static irqreturn_t imx_tve_irq_handler(int irq, void *data) ··· 491 495 encoder_type = tve->mode == TVE_MODE_VGA ? 492 496 DRM_MODE_ENCODER_DAC : DRM_MODE_ENCODER_TVDAC; 493 497 494 - ret = imx_drm_encoder_parse_of(drm, &tve->encoder, 495 - tve->dev->of_node); 498 + ret = imx_drm_encoder_parse_of(drm, &tve->encoder, tve->dev->of_node); 496 499 if (ret) 497 500 return ret; 498 501 ··· 582 587 583 588 if (tve->mode == TVE_MODE_VGA) { 584 589 ret = of_property_read_u32(np, "fsl,hsync-pin", 585 - &tve->hsync_pin); 590 + &tve->di_hsync_pin); 586 591 587 592 if (ret < 0) { 588 - dev_err(dev, "failed to get vsync pin\n"); 593 + dev_err(dev, "failed to get hsync pin\n"); 589 594 return ret; 590 595 } 591 596 592 - ret |= of_property_read_u32(np, "fsl,vsync-pin", 593 - &tve->vsync_pin); 597 + ret = of_property_read_u32(np, "fsl,vsync-pin", 598 + &tve->di_vsync_pin); 594 599 595 600 if (ret < 0) { 596 601 dev_err(dev, "failed to get vsync pin\n"); ··· 628 633 629 634 tve->dac_reg = devm_regulator_get(dev, "dac"); 630 635 if (!IS_ERR(tve->dac_reg)) { 631 - regulator_set_voltage(tve->dac_reg, 2750000, 2750000); 636 + ret = regulator_set_voltage(tve->dac_reg, 2750000, 2750000); 637 + if (ret) 638 + return ret; 632 639 ret = regulator_enable(tve->dac_reg); 633 640 if (ret) 634 641 return ret;
+148 -288
drivers/gpu/drm/imx/ipuv3-crtc.c
··· 18 18 #include <linux/device.h> 19 19 #include <linux/platform_device.h> 20 20 #include <drm/drmP.h> 21 + #include <drm/drm_atomic.h> 22 + #include <drm/drm_atomic_helper.h> 21 23 #include <drm/drm_crtc_helper.h> 22 24 #include <linux/fb.h> 23 25 #include <linux/clk.h> 24 26 #include <linux/errno.h> 25 - #include <linux/reservation.h> 26 - #include <linux/dma-buf.h> 27 27 #include <drm/drm_gem_cma_helper.h> 28 28 #include <drm/drm_fb_cma_helper.h> 29 29 ··· 32 32 #include "ipuv3-plane.h" 33 33 34 34 #define DRIVER_DESC "i.MX IPUv3 Graphics" 35 - 36 - enum ipu_flip_status { 37 - IPU_FLIP_NONE, 38 - IPU_FLIP_PENDING, 39 - IPU_FLIP_SUBMITTED, 40 - }; 41 - 42 - struct ipu_flip_work { 43 - struct work_struct unref_work; 44 - struct drm_gem_object *bo; 45 - struct drm_pending_vblank_event *page_flip_event; 46 - struct work_struct fence_work; 47 - struct ipu_crtc *crtc; 48 - struct fence *excl; 49 - unsigned shared_count; 50 - struct fence **shared; 51 - }; 52 35 53 36 struct ipu_crtc { 54 37 struct device *dev; ··· 43 60 44 61 struct ipu_dc *dc; 45 62 struct ipu_di *di; 46 - int enabled; 47 - enum ipu_flip_status flip_state; 48 - struct workqueue_struct *flip_queue; 49 - struct ipu_flip_work *flip_work; 50 63 int irq; 51 - u32 bus_format; 52 - u32 bus_flags; 53 - int di_hsync_pin; 54 - int di_vsync_pin; 55 64 }; 56 65 57 - #define to_ipu_crtc(x) container_of(x, struct ipu_crtc, base) 58 - 59 - static void ipu_fb_enable(struct ipu_crtc *ipu_crtc) 66 + static inline struct ipu_crtc *to_ipu_crtc(struct drm_crtc *crtc) 60 67 { 61 - struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); 68 + return container_of(crtc, struct ipu_crtc, base); 69 + } 62 70 63 - if (ipu_crtc->enabled) 64 - return; 71 + static void ipu_crtc_enable(struct drm_crtc *crtc) 72 + { 73 + struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); 74 + struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); 65 75 66 76 ipu_dc_enable(ipu); 67 - ipu_plane_enable(ipu_crtc->plane[0]); 68 - /* Start DC channel and DI after IDMAC */ 69 77 ipu_dc_enable_channel(ipu_crtc->dc); 70 78 ipu_di_enable(ipu_crtc->di); 71 - drm_crtc_vblank_on(&ipu_crtc->base); 72 - 73 - ipu_crtc->enabled = 1; 74 79 } 75 80 76 - static void ipu_fb_disable(struct ipu_crtc *ipu_crtc) 81 + static void ipu_crtc_disable(struct drm_crtc *crtc) 77 82 { 83 + struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); 78 84 struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); 79 85 80 - if (!ipu_crtc->enabled) 81 - return; 82 - 83 - /* Stop DC channel and DI before IDMAC */ 84 86 ipu_dc_disable_channel(ipu_crtc->dc); 85 87 ipu_di_disable(ipu_crtc->di); 86 - ipu_plane_disable(ipu_crtc->plane[0]); 87 88 ipu_dc_disable(ipu); 88 - drm_crtc_vblank_off(&ipu_crtc->base); 89 89 90 - ipu_crtc->enabled = 0; 90 + spin_lock_irq(&crtc->dev->event_lock); 91 + if (crtc->state->event) { 92 + drm_crtc_send_vblank_event(crtc, crtc->state->event); 93 + crtc->state->event = NULL; 94 + } 95 + spin_unlock_irq(&crtc->dev->event_lock); 91 96 } 92 97 93 - static void ipu_crtc_dpms(struct drm_crtc *crtc, int mode) 98 + static void imx_drm_crtc_reset(struct drm_crtc *crtc) 94 99 { 95 - struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); 100 + struct imx_crtc_state *state; 96 101 97 - dev_dbg(ipu_crtc->dev, "%s mode: %d\n", __func__, mode); 102 + if (crtc->state) { 103 + if (crtc->state->mode_blob) 104 + drm_property_unreference_blob(crtc->state->mode_blob); 98 105 99 - switch (mode) { 100 - case DRM_MODE_DPMS_ON: 101 - ipu_fb_enable(ipu_crtc); 102 - break; 103 - case DRM_MODE_DPMS_STANDBY: 104 - case DRM_MODE_DPMS_SUSPEND: 105 - case DRM_MODE_DPMS_OFF: 106 - ipu_fb_disable(ipu_crtc); 107 - break; 108 - } 109 - } 110 - 111 - static void ipu_flip_unref_work_func(struct work_struct *__work) 112 - { 113 - struct ipu_flip_work *work = 114 - container_of(__work, struct ipu_flip_work, unref_work); 115 - 116 - drm_gem_object_unreference_unlocked(work->bo); 117 - kfree(work); 118 - } 119 - 120 - static void ipu_flip_fence_work_func(struct work_struct *__work) 121 - { 122 - struct ipu_flip_work *work = 123 - container_of(__work, struct ipu_flip_work, fence_work); 124 - int i; 125 - 126 - /* wait for all fences attached to the FB obj to signal */ 127 - if (work->excl) { 128 - fence_wait(work->excl, false); 129 - fence_put(work->excl); 130 - } 131 - for (i = 0; i < work->shared_count; i++) { 132 - fence_wait(work->shared[i], false); 133 - fence_put(work->shared[i]); 134 - } 135 - 136 - work->crtc->flip_state = IPU_FLIP_SUBMITTED; 137 - } 138 - 139 - static int ipu_page_flip(struct drm_crtc *crtc, 140 - struct drm_framebuffer *fb, 141 - struct drm_pending_vblank_event *event, 142 - uint32_t page_flip_flags) 143 - { 144 - struct drm_gem_cma_object *cma_obj = drm_fb_cma_get_gem_obj(fb, 0); 145 - struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); 146 - struct ipu_flip_work *flip_work; 147 - int ret; 148 - 149 - if (ipu_crtc->flip_state != IPU_FLIP_NONE) 150 - return -EBUSY; 151 - 152 - ret = imx_drm_crtc_vblank_get(ipu_crtc->imx_crtc); 153 - if (ret) { 154 - dev_dbg(ipu_crtc->dev, "failed to acquire vblank counter\n"); 155 - list_del(&event->base.link); 156 - 157 - return ret; 158 - } 159 - 160 - flip_work = kzalloc(sizeof *flip_work, GFP_KERNEL); 161 - if (!flip_work) { 162 - ret = -ENOMEM; 163 - goto put_vblank; 164 - } 165 - INIT_WORK(&flip_work->unref_work, ipu_flip_unref_work_func); 166 - flip_work->page_flip_event = event; 167 - 168 - /* get BO backing the old framebuffer and take a reference */ 169 - flip_work->bo = &drm_fb_cma_get_gem_obj(crtc->primary->fb, 0)->base; 170 - drm_gem_object_reference(flip_work->bo); 171 - 172 - ipu_crtc->flip_work = flip_work; 173 - /* 174 - * If the object has a DMABUF attached, we need to wait on its fences 175 - * if there are any. 176 - */ 177 - if (cma_obj->base.dma_buf) { 178 - INIT_WORK(&flip_work->fence_work, ipu_flip_fence_work_func); 179 - flip_work->crtc = ipu_crtc; 180 - 181 - ret = reservation_object_get_fences_rcu( 182 - cma_obj->base.dma_buf->resv, &flip_work->excl, 183 - &flip_work->shared_count, &flip_work->shared); 184 - 185 - if (unlikely(ret)) { 186 - DRM_ERROR("failed to get fences for buffer\n"); 187 - goto free_flip_work; 188 - } 189 - 190 - /* No need to queue the worker if the are no fences */ 191 - if (!flip_work->excl && !flip_work->shared_count) { 192 - ipu_crtc->flip_state = IPU_FLIP_SUBMITTED; 193 - } else { 194 - ipu_crtc->flip_state = IPU_FLIP_PENDING; 195 - queue_work(ipu_crtc->flip_queue, 196 - &flip_work->fence_work); 197 - } 106 + state = to_imx_crtc_state(crtc->state); 107 + memset(state, 0, sizeof(*state)); 198 108 } else { 199 - ipu_crtc->flip_state = IPU_FLIP_SUBMITTED; 109 + state = kzalloc(sizeof(*state), GFP_KERNEL); 110 + if (!state) 111 + return; 112 + crtc->state = &state->base; 200 113 } 201 114 202 - return 0; 115 + state->base.crtc = crtc; 116 + } 203 117 204 - free_flip_work: 205 - drm_gem_object_unreference_unlocked(flip_work->bo); 206 - kfree(flip_work); 207 - ipu_crtc->flip_work = NULL; 208 - put_vblank: 209 - imx_drm_crtc_vblank_put(ipu_crtc->imx_crtc); 118 + static struct drm_crtc_state *imx_drm_crtc_duplicate_state(struct drm_crtc *crtc) 119 + { 120 + struct imx_crtc_state *state; 210 121 211 - return ret; 122 + state = kzalloc(sizeof(*state), GFP_KERNEL); 123 + if (!state) 124 + return NULL; 125 + 126 + __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base); 127 + 128 + WARN_ON(state->base.crtc != crtc); 129 + state->base.crtc = crtc; 130 + 131 + return &state->base; 132 + } 133 + 134 + static void imx_drm_crtc_destroy_state(struct drm_crtc *crtc, 135 + struct drm_crtc_state *state) 136 + { 137 + __drm_atomic_helper_crtc_destroy_state(state); 138 + kfree(to_imx_crtc_state(state)); 212 139 } 213 140 214 141 static const struct drm_crtc_funcs ipu_crtc_funcs = { 215 - .set_config = drm_crtc_helper_set_config, 142 + .set_config = drm_atomic_helper_set_config, 216 143 .destroy = drm_crtc_cleanup, 217 - .page_flip = ipu_page_flip, 144 + .page_flip = drm_atomic_helper_page_flip, 145 + .reset = imx_drm_crtc_reset, 146 + .atomic_duplicate_state = imx_drm_crtc_duplicate_state, 147 + .atomic_destroy_state = imx_drm_crtc_destroy_state, 218 148 }; 219 - 220 - static int ipu_crtc_mode_set(struct drm_crtc *crtc, 221 - struct drm_display_mode *orig_mode, 222 - struct drm_display_mode *mode, 223 - int x, int y, 224 - struct drm_framebuffer *old_fb) 225 - { 226 - struct drm_device *dev = crtc->dev; 227 - struct drm_encoder *encoder; 228 - struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); 229 - struct ipu_di_signal_cfg sig_cfg = {}; 230 - unsigned long encoder_types = 0; 231 - int ret; 232 - 233 - dev_dbg(ipu_crtc->dev, "%s: mode->hdisplay: %d\n", __func__, 234 - mode->hdisplay); 235 - dev_dbg(ipu_crtc->dev, "%s: mode->vdisplay: %d\n", __func__, 236 - mode->vdisplay); 237 - 238 - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) 239 - if (encoder->crtc == crtc) 240 - encoder_types |= BIT(encoder->encoder_type); 241 - 242 - dev_dbg(ipu_crtc->dev, "%s: attached to encoder types 0x%lx\n", 243 - __func__, encoder_types); 244 - 245 - /* 246 - * If we have DAC or LDB, then we need the IPU DI clock to be 247 - * the same as the LDB DI clock. For TVDAC, derive the IPU DI 248 - * clock from 27 MHz TVE_DI clock, but allow to divide it. 249 - */ 250 - if (encoder_types & (BIT(DRM_MODE_ENCODER_DAC) | 251 - BIT(DRM_MODE_ENCODER_LVDS))) 252 - sig_cfg.clkflags = IPU_DI_CLKMODE_SYNC | IPU_DI_CLKMODE_EXT; 253 - else if (encoder_types & BIT(DRM_MODE_ENCODER_TVDAC)) 254 - sig_cfg.clkflags = IPU_DI_CLKMODE_EXT; 255 - else 256 - sig_cfg.clkflags = 0; 257 - 258 - sig_cfg.enable_pol = !(ipu_crtc->bus_flags & DRM_BUS_FLAG_DE_LOW); 259 - /* Default to driving pixel data on negative clock edges */ 260 - sig_cfg.clk_pol = !!(ipu_crtc->bus_flags & 261 - DRM_BUS_FLAG_PIXDATA_POSEDGE); 262 - sig_cfg.bus_format = ipu_crtc->bus_format; 263 - sig_cfg.v_to_h_sync = 0; 264 - sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin; 265 - sig_cfg.vsync_pin = ipu_crtc->di_vsync_pin; 266 - 267 - drm_display_mode_to_videomode(mode, &sig_cfg.mode); 268 - 269 - ret = ipu_dc_init_sync(ipu_crtc->dc, ipu_crtc->di, 270 - mode->flags & DRM_MODE_FLAG_INTERLACE, 271 - ipu_crtc->bus_format, mode->hdisplay); 272 - if (ret) { 273 - dev_err(ipu_crtc->dev, 274 - "initializing display controller failed with %d\n", 275 - ret); 276 - return ret; 277 - } 278 - 279 - ret = ipu_di_init_sync_panel(ipu_crtc->di, &sig_cfg); 280 - if (ret) { 281 - dev_err(ipu_crtc->dev, 282 - "initializing panel failed with %d\n", ret); 283 - return ret; 284 - } 285 - 286 - return ipu_plane_mode_set(ipu_crtc->plane[0], crtc, mode, 287 - crtc->primary->fb, 288 - 0, 0, mode->hdisplay, mode->vdisplay, 289 - x, y, mode->hdisplay, mode->vdisplay, 290 - mode->flags & DRM_MODE_FLAG_INTERLACE); 291 - } 292 - 293 - static void ipu_crtc_handle_pageflip(struct ipu_crtc *ipu_crtc) 294 - { 295 - unsigned long flags; 296 - struct drm_device *drm = ipu_crtc->base.dev; 297 - struct ipu_flip_work *work = ipu_crtc->flip_work; 298 - 299 - spin_lock_irqsave(&drm->event_lock, flags); 300 - if (work->page_flip_event) 301 - drm_crtc_send_vblank_event(&ipu_crtc->base, 302 - work->page_flip_event); 303 - imx_drm_crtc_vblank_put(ipu_crtc->imx_crtc); 304 - spin_unlock_irqrestore(&drm->event_lock, flags); 305 - } 306 149 307 150 static irqreturn_t ipu_irq_handler(int irq, void *dev_id) 308 151 { 309 152 struct ipu_crtc *ipu_crtc = dev_id; 310 153 311 154 imx_drm_handle_vblank(ipu_crtc->imx_crtc); 312 - 313 - if (ipu_crtc->flip_state == IPU_FLIP_SUBMITTED) { 314 - struct ipu_plane *plane = ipu_crtc->plane[0]; 315 - 316 - ipu_plane_set_base(plane, ipu_crtc->base.primary->fb, 317 - plane->x, plane->y); 318 - ipu_crtc_handle_pageflip(ipu_crtc); 319 - queue_work(ipu_crtc->flip_queue, 320 - &ipu_crtc->flip_work->unref_work); 321 - ipu_crtc->flip_state = IPU_FLIP_NONE; 322 - } 323 155 324 156 return IRQ_HANDLED; 325 157 } ··· 153 355 if (ret) 154 356 return false; 155 357 358 + if ((vm.vsync_len == 0) || (vm.hsync_len == 0)) 359 + return false; 360 + 156 361 drm_display_mode_from_videomode(&vm, adjusted_mode); 157 362 158 363 return true; 159 364 } 160 365 161 - static void ipu_crtc_prepare(struct drm_crtc *crtc) 366 + static int ipu_crtc_atomic_check(struct drm_crtc *crtc, 367 + struct drm_crtc_state *state) 162 368 { 163 - struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); 369 + u32 primary_plane_mask = 1 << drm_plane_index(crtc->primary); 164 370 165 - ipu_fb_disable(ipu_crtc); 371 + if (state->active && (primary_plane_mask & state->plane_mask) == 0) 372 + return -EINVAL; 373 + 374 + return 0; 166 375 } 167 376 168 - static void ipu_crtc_commit(struct drm_crtc *crtc) 377 + static void ipu_crtc_atomic_begin(struct drm_crtc *crtc, 378 + struct drm_crtc_state *old_crtc_state) 169 379 { 170 - struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); 380 + spin_lock_irq(&crtc->dev->event_lock); 381 + if (crtc->state->event) { 382 + WARN_ON(drm_crtc_vblank_get(crtc)); 383 + drm_crtc_arm_vblank_event(crtc, crtc->state->event); 384 + crtc->state->event = NULL; 385 + } 386 + spin_unlock_irq(&crtc->dev->event_lock); 387 + } 171 388 172 - ipu_fb_enable(ipu_crtc); 389 + static void ipu_crtc_mode_set_nofb(struct drm_crtc *crtc) 390 + { 391 + struct drm_device *dev = crtc->dev; 392 + struct drm_encoder *encoder; 393 + struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); 394 + struct drm_display_mode *mode = &crtc->state->adjusted_mode; 395 + struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc->state); 396 + struct ipu_di_signal_cfg sig_cfg = {}; 397 + unsigned long encoder_types = 0; 398 + 399 + dev_dbg(ipu_crtc->dev, "%s: mode->hdisplay: %d\n", __func__, 400 + mode->hdisplay); 401 + dev_dbg(ipu_crtc->dev, "%s: mode->vdisplay: %d\n", __func__, 402 + mode->vdisplay); 403 + 404 + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 405 + if (encoder->crtc == crtc) 406 + encoder_types |= BIT(encoder->encoder_type); 407 + } 408 + 409 + dev_dbg(ipu_crtc->dev, "%s: attached to encoder types 0x%lx\n", 410 + __func__, encoder_types); 411 + 412 + /* 413 + * If we have DAC or LDB, then we need the IPU DI clock to be 414 + * the same as the LDB DI clock. For TVDAC, derive the IPU DI 415 + * clock from 27 MHz TVE_DI clock, but allow to divide it. 416 + */ 417 + if (encoder_types & (BIT(DRM_MODE_ENCODER_DAC) | 418 + BIT(DRM_MODE_ENCODER_LVDS))) 419 + sig_cfg.clkflags = IPU_DI_CLKMODE_SYNC | IPU_DI_CLKMODE_EXT; 420 + else if (encoder_types & BIT(DRM_MODE_ENCODER_TVDAC)) 421 + sig_cfg.clkflags = IPU_DI_CLKMODE_EXT; 422 + else 423 + sig_cfg.clkflags = 0; 424 + 425 + sig_cfg.enable_pol = !(imx_crtc_state->bus_flags & DRM_BUS_FLAG_DE_LOW); 426 + /* Default to driving pixel data on negative clock edges */ 427 + sig_cfg.clk_pol = !!(imx_crtc_state->bus_flags & 428 + DRM_BUS_FLAG_PIXDATA_POSEDGE); 429 + sig_cfg.bus_format = imx_crtc_state->bus_format; 430 + sig_cfg.v_to_h_sync = 0; 431 + sig_cfg.hsync_pin = imx_crtc_state->di_hsync_pin; 432 + sig_cfg.vsync_pin = imx_crtc_state->di_vsync_pin; 433 + 434 + drm_display_mode_to_videomode(mode, &sig_cfg.mode); 435 + 436 + ipu_dc_init_sync(ipu_crtc->dc, ipu_crtc->di, 437 + mode->flags & DRM_MODE_FLAG_INTERLACE, 438 + imx_crtc_state->bus_format, mode->hdisplay); 439 + ipu_di_init_sync_panel(ipu_crtc->di, &sig_cfg); 173 440 } 174 441 175 442 static const struct drm_crtc_helper_funcs ipu_helper_funcs = { 176 - .dpms = ipu_crtc_dpms, 177 443 .mode_fixup = ipu_crtc_mode_fixup, 178 - .mode_set = ipu_crtc_mode_set, 179 - .prepare = ipu_crtc_prepare, 180 - .commit = ipu_crtc_commit, 444 + .mode_set_nofb = ipu_crtc_mode_set_nofb, 445 + .atomic_check = ipu_crtc_atomic_check, 446 + .atomic_begin = ipu_crtc_atomic_begin, 447 + .disable = ipu_crtc_disable, 448 + .enable = ipu_crtc_enable, 181 449 }; 182 450 183 451 static int ipu_enable_vblank(struct drm_crtc *crtc) ··· 262 398 disable_irq_nosync(ipu_crtc->irq); 263 399 } 264 400 265 - static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, 266 - u32 bus_format, int hsync_pin, int vsync_pin, u32 bus_flags) 267 - { 268 - struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); 269 - 270 - ipu_crtc->bus_format = bus_format; 271 - ipu_crtc->bus_flags = bus_flags; 272 - ipu_crtc->di_hsync_pin = hsync_pin; 273 - ipu_crtc->di_vsync_pin = vsync_pin; 274 - 275 - return 0; 276 - } 277 - 278 401 static const struct imx_drm_crtc_helper_funcs ipu_crtc_helper_funcs = { 279 402 .enable_vblank = ipu_enable_vblank, 280 403 .disable_vblank = ipu_disable_vblank, 281 - .set_interface_pix_fmt = ipu_set_interface_pix_fmt, 282 404 .crtc_funcs = &ipu_crtc_funcs, 283 405 .crtc_helper_funcs = &ipu_helper_funcs, 284 406 }; ··· 346 496 IPU_DP_FLOW_SYNC_FG, 347 497 drm_crtc_mask(&ipu_crtc->base), 348 498 DRM_PLANE_TYPE_OVERLAY); 349 - if (IS_ERR(ipu_crtc->plane[1])) 499 + if (IS_ERR(ipu_crtc->plane[1])) { 350 500 ipu_crtc->plane[1] = NULL; 501 + } else { 502 + ret = ipu_plane_get_resources(ipu_crtc->plane[1]); 503 + if (ret) { 504 + dev_err(ipu_crtc->dev, "getting plane 1 " 505 + "resources failed with %d.\n", ret); 506 + goto err_put_plane0_res; 507 + } 508 + } 351 509 } 352 510 353 511 ipu_crtc->irq = ipu_plane_irq(ipu_crtc->plane[0]); ··· 363 505 "imx_drm", ipu_crtc); 364 506 if (ret < 0) { 365 507 dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret); 366 - goto err_put_plane_res; 508 + goto err_put_plane1_res; 367 509 } 368 510 /* Only enable IRQ when we actually need it to trigger work. */ 369 511 disable_irq(ipu_crtc->irq); 370 512 371 - ipu_crtc->flip_queue = create_singlethread_workqueue("ipu-crtc-flip"); 372 - 373 513 return 0; 374 514 375 - err_put_plane_res: 515 + err_put_plane1_res: 516 + if (ipu_crtc->plane[1]) 517 + ipu_plane_put_resources(ipu_crtc->plane[1]); 518 + err_put_plane0_res: 376 519 ipu_plane_put_resources(ipu_crtc->plane[0]); 377 520 err_remove_crtc: 378 521 imx_drm_remove_crtc(ipu_crtc->imx_crtc); ··· 412 553 413 554 imx_drm_remove_crtc(ipu_crtc->imx_crtc); 414 555 415 - destroy_workqueue(ipu_crtc->flip_queue); 416 - ipu_plane_put_resources(ipu_crtc->plane[0]); 417 556 ipu_put_resources(ipu_crtc); 557 + if (ipu_crtc->plane[1]) 558 + ipu_plane_put_resources(ipu_crtc->plane[1]); 559 + ipu_plane_put_resources(ipu_crtc->plane[0]); 418 560 } 419 561 420 562 static const struct component_ops ipu_crtc_ops = {
+267 -287
drivers/gpu/drm/imx/ipuv3-plane.c
··· 14 14 */ 15 15 16 16 #include <drm/drmP.h> 17 + #include <drm/drm_atomic.h> 18 + #include <drm/drm_atomic_helper.h> 17 19 #include <drm/drm_fb_cma_helper.h> 18 20 #include <drm/drm_gem_cma_helper.h> 21 + #include <drm/drm_plane_helper.h> 19 22 20 23 #include "video/imx-ipu-v3.h" 21 24 #include "ipuv3-plane.h" 22 25 23 - #define to_ipu_plane(x) container_of(x, struct ipu_plane, base) 26 + static inline struct ipu_plane *to_ipu_plane(struct drm_plane *p) 27 + { 28 + return container_of(p, struct ipu_plane, base); 29 + } 24 30 25 31 static const uint32_t ipu_plane_formats[] = { 26 32 DRM_FORMAT_ARGB1555, ··· 59 53 IPU_IRQ_EOF); 60 54 } 61 55 62 - static int calc_vref(struct drm_display_mode *mode) 56 + static inline unsigned long 57 + drm_plane_state_to_eba(struct drm_plane_state *state) 63 58 { 64 - unsigned long htotal, vtotal; 59 + struct drm_framebuffer *fb = state->fb; 60 + struct drm_gem_cma_object *cma_obj; 65 61 66 - htotal = mode->htotal; 67 - vtotal = mode->vtotal; 62 + cma_obj = drm_fb_cma_get_gem_obj(fb, 0); 63 + BUG_ON(!cma_obj); 68 64 69 - if (!htotal || !vtotal) 70 - return 60; 71 - 72 - return DIV_ROUND_UP(mode->clock * 1000, vtotal * htotal); 65 + return cma_obj->paddr + fb->offsets[0] + 66 + fb->pitches[0] * (state->src_y >> 16) + 67 + (fb->bits_per_pixel >> 3) * (state->src_x >> 16); 73 68 } 74 69 75 - static inline int calc_bandwidth(int width, int height, unsigned int vref) 70 + static inline unsigned long 71 + drm_plane_state_to_ubo(struct drm_plane_state *state) 76 72 { 77 - return width * height * vref; 73 + struct drm_framebuffer *fb = state->fb; 74 + struct drm_gem_cma_object *cma_obj; 75 + unsigned long eba = drm_plane_state_to_eba(state); 76 + 77 + cma_obj = drm_fb_cma_get_gem_obj(fb, 1); 78 + BUG_ON(!cma_obj); 79 + 80 + return cma_obj->paddr + fb->offsets[1] + 81 + fb->pitches[1] * (state->src_y >> 16) / 2 + 82 + (state->src_x >> 16) / 2 - eba; 78 83 } 79 84 80 - int ipu_plane_set_base(struct ipu_plane *ipu_plane, struct drm_framebuffer *fb, 81 - int x, int y) 85 + static inline unsigned long 86 + drm_plane_state_to_vbo(struct drm_plane_state *state) 82 87 { 83 - struct drm_gem_cma_object *cma_obj[3]; 88 + struct drm_framebuffer *fb = state->fb; 89 + struct drm_gem_cma_object *cma_obj; 90 + unsigned long eba = drm_plane_state_to_eba(state); 91 + 92 + cma_obj = drm_fb_cma_get_gem_obj(fb, 2); 93 + BUG_ON(!cma_obj); 94 + 95 + return cma_obj->paddr + fb->offsets[2] + 96 + fb->pitches[2] * (state->src_y >> 16) / 2 + 97 + (state->src_x >> 16) / 2 - eba; 98 + } 99 + 100 + static void ipu_plane_atomic_set_base(struct ipu_plane *ipu_plane, 101 + struct drm_plane_state *old_state) 102 + { 103 + struct drm_plane *plane = &ipu_plane->base; 104 + struct drm_plane_state *state = plane->state; 105 + struct drm_framebuffer *fb = state->fb; 84 106 unsigned long eba, ubo, vbo; 85 - int active, i; 107 + int active; 86 108 87 - for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) { 88 - cma_obj[i] = drm_fb_cma_get_gem_obj(fb, i); 89 - if (!cma_obj[i]) { 90 - DRM_DEBUG_KMS("plane %d entry is null.\n", i); 91 - return -EFAULT; 92 - } 93 - } 94 - 95 - eba = cma_obj[0]->paddr + fb->offsets[0] + 96 - fb->pitches[0] * y + (fb->bits_per_pixel >> 3) * x; 97 - 98 - if (eba & 0x7) { 99 - DRM_DEBUG_KMS("base address must be a multiple of 8.\n"); 100 - return -EINVAL; 101 - } 102 - 103 - if (fb->pitches[0] < 1 || fb->pitches[0] > 16384) { 104 - DRM_DEBUG_KMS("pitches out of range.\n"); 105 - return -EINVAL; 106 - } 107 - 108 - if (ipu_plane->enabled && fb->pitches[0] != ipu_plane->stride[0]) { 109 - DRM_DEBUG_KMS("pitches must not change while plane is enabled.\n"); 110 - return -EINVAL; 111 - } 112 - 113 - ipu_plane->stride[0] = fb->pitches[0]; 109 + eba = drm_plane_state_to_eba(state); 114 110 115 111 switch (fb->pixel_format) { 116 112 case DRM_FORMAT_YUV420: 117 113 case DRM_FORMAT_YVU420: 114 + if (old_state->fb) 115 + break; 116 + 118 117 /* 119 118 * Multiplanar formats have to meet the following restrictions: 120 119 * - The (up to) three plane addresses are EBA, EBA+UBO, EBA+VBO ··· 128 117 * - Only EBA may be changed while scanout is active 129 118 * - The strides of U and V planes must be identical. 130 119 */ 131 - ubo = cma_obj[1]->paddr + fb->offsets[1] + 132 - fb->pitches[1] * y / 2 + x / 2 - eba; 133 - vbo = cma_obj[2]->paddr + fb->offsets[2] + 134 - fb->pitches[2] * y / 2 + x / 2 - eba; 120 + ubo = drm_plane_state_to_ubo(state); 121 + vbo = drm_plane_state_to_vbo(state); 135 122 136 - if ((ubo & 0x7) || (vbo & 0x7)) { 137 - DRM_DEBUG_KMS("U/V buffer offsets must be a multiple of 8.\n"); 138 - return -EINVAL; 139 - } 140 - 141 - if ((ubo > 0xfffff8) || (vbo > 0xfffff8)) { 142 - DRM_DEBUG_KMS("U/V buffer offsets must be positive and not larger than 0xfffff8.\n"); 143 - return -EINVAL; 144 - } 145 - 146 - if (ipu_plane->enabled && ((ipu_plane->u_offset != ubo) || 147 - (ipu_plane->v_offset != vbo))) { 148 - DRM_DEBUG_KMS("U/V buffer offsets must not change while plane is enabled.\n"); 149 - return -EINVAL; 150 - } 151 - 152 - if (fb->pitches[1] != fb->pitches[2]) { 153 - DRM_DEBUG_KMS("U/V pitches must be identical.\n"); 154 - return -EINVAL; 155 - } 156 - 157 - if (fb->pitches[1] < 1 || fb->pitches[1] > 16384) { 158 - DRM_DEBUG_KMS("U/V pitches out of range.\n"); 159 - return -EINVAL; 160 - } 161 - 162 - if (ipu_plane->enabled && 163 - (ipu_plane->stride[1] != fb->pitches[1])) { 164 - DRM_DEBUG_KMS("U/V pitches must not change while plane is enabled.\n"); 165 - return -EINVAL; 166 - } 167 - 168 - ipu_plane->u_offset = ubo; 169 - ipu_plane->v_offset = vbo; 170 - ipu_plane->stride[1] = fb->pitches[1]; 123 + if (fb->pixel_format == DRM_FORMAT_YUV420) 124 + ipu_cpmem_set_yuv_planar_full(ipu_plane->ipu_ch, 125 + fb->pitches[1], ubo, vbo); 126 + else 127 + ipu_cpmem_set_yuv_planar_full(ipu_plane->ipu_ch, 128 + fb->pitches[1], vbo, ubo); 171 129 172 130 dev_dbg(ipu_plane->base.dev->dev, 173 - "phys = %pad %pad %pad, x = %d, y = %d", 174 - &cma_obj[0]->paddr, &cma_obj[1]->paddr, 175 - &cma_obj[2]->paddr, x, y); 131 + "phy = %lu %lu %lu, x = %d, y = %d", eba, ubo, vbo, 132 + state->src_x >> 16, state->src_y >> 16); 176 133 break; 177 134 default: 178 - dev_dbg(ipu_plane->base.dev->dev, "phys = %pad, x = %d, y = %d", 179 - &cma_obj[0]->paddr, x, y); 135 + dev_dbg(ipu_plane->base.dev->dev, "phys = %lu, x = %d, y = %d", 136 + eba, state->src_x >> 16, state->src_y >> 16); 137 + 180 138 break; 181 139 } 182 140 183 - if (ipu_plane->enabled) { 141 + if (old_state->fb) { 184 142 active = ipu_idmac_get_current_buffer(ipu_plane->ipu_ch); 185 143 ipu_cpmem_set_buffer(ipu_plane->ipu_ch, !active, eba); 186 144 ipu_idmac_select_buffer(ipu_plane->ipu_ch, !active); ··· 157 177 ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 0, eba); 158 178 ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 1, eba); 159 179 } 160 - 161 - /* cache offsets for subsequent pageflips */ 162 - ipu_plane->x = x; 163 - ipu_plane->y = y; 164 - 165 - return 0; 166 - } 167 - 168 - int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc, 169 - struct drm_display_mode *mode, 170 - struct drm_framebuffer *fb, int crtc_x, int crtc_y, 171 - unsigned int crtc_w, unsigned int crtc_h, 172 - uint32_t src_x, uint32_t src_y, 173 - uint32_t src_w, uint32_t src_h, bool interlaced) 174 - { 175 - struct device *dev = ipu_plane->base.dev->dev; 176 - int ret; 177 - 178 - /* no scaling */ 179 - if (src_w != crtc_w || src_h != crtc_h) 180 - return -EINVAL; 181 - 182 - /* clip to crtc bounds */ 183 - if (crtc_x < 0) { 184 - if (-crtc_x > crtc_w) 185 - return -EINVAL; 186 - src_x += -crtc_x; 187 - src_w -= -crtc_x; 188 - crtc_w -= -crtc_x; 189 - crtc_x = 0; 190 - } 191 - if (crtc_y < 0) { 192 - if (-crtc_y > crtc_h) 193 - return -EINVAL; 194 - src_y += -crtc_y; 195 - src_h -= -crtc_y; 196 - crtc_h -= -crtc_y; 197 - crtc_y = 0; 198 - } 199 - if (crtc_x + crtc_w > mode->hdisplay) { 200 - if (crtc_x > mode->hdisplay) 201 - return -EINVAL; 202 - crtc_w = mode->hdisplay - crtc_x; 203 - src_w = crtc_w; 204 - } 205 - if (crtc_y + crtc_h > mode->vdisplay) { 206 - if (crtc_y > mode->vdisplay) 207 - return -EINVAL; 208 - crtc_h = mode->vdisplay - crtc_y; 209 - src_h = crtc_h; 210 - } 211 - /* full plane minimum width is 13 pixels */ 212 - if (crtc_w < 13 && (ipu_plane->dp_flow != IPU_DP_FLOW_SYNC_FG)) 213 - return -EINVAL; 214 - if (crtc_h < 2) 215 - return -EINVAL; 216 - 217 - /* 218 - * since we cannot touch active IDMAC channels, we do not support 219 - * resizing the enabled plane or changing its format 220 - */ 221 - if (ipu_plane->enabled) { 222 - if (src_w != ipu_plane->w || src_h != ipu_plane->h || 223 - fb->pixel_format != ipu_plane->base.fb->pixel_format) 224 - return -EINVAL; 225 - 226 - return ipu_plane_set_base(ipu_plane, fb, src_x, src_y); 227 - } 228 - 229 - switch (ipu_plane->dp_flow) { 230 - case IPU_DP_FLOW_SYNC_BG: 231 - ret = ipu_dp_setup_channel(ipu_plane->dp, 232 - IPUV3_COLORSPACE_RGB, 233 - IPUV3_COLORSPACE_RGB); 234 - if (ret) { 235 - dev_err(dev, 236 - "initializing display processor failed with %d\n", 237 - ret); 238 - return ret; 239 - } 240 - ipu_dp_set_global_alpha(ipu_plane->dp, true, 0, true); 241 - break; 242 - case IPU_DP_FLOW_SYNC_FG: 243 - ipu_dp_setup_channel(ipu_plane->dp, 244 - ipu_drm_fourcc_to_colorspace(fb->pixel_format), 245 - IPUV3_COLORSPACE_UNKNOWN); 246 - ipu_dp_set_window_pos(ipu_plane->dp, crtc_x, crtc_y); 247 - /* Enable local alpha on partial plane */ 248 - switch (fb->pixel_format) { 249 - case DRM_FORMAT_ARGB1555: 250 - case DRM_FORMAT_ABGR1555: 251 - case DRM_FORMAT_RGBA5551: 252 - case DRM_FORMAT_BGRA5551: 253 - case DRM_FORMAT_ARGB4444: 254 - case DRM_FORMAT_ARGB8888: 255 - case DRM_FORMAT_ABGR8888: 256 - case DRM_FORMAT_RGBA8888: 257 - case DRM_FORMAT_BGRA8888: 258 - ipu_dp_set_global_alpha(ipu_plane->dp, false, 0, false); 259 - break; 260 - default: 261 - break; 262 - } 263 - } 264 - 265 - ret = ipu_dmfc_alloc_bandwidth(ipu_plane->dmfc, 266 - calc_bandwidth(crtc_w, crtc_h, 267 - calc_vref(mode)), 64); 268 - if (ret) { 269 - dev_err(dev, "allocating dmfc bandwidth failed with %d\n", ret); 270 - return ret; 271 - } 272 - 273 - ipu_dmfc_config_wait4eot(ipu_plane->dmfc, crtc_w); 274 - 275 - ipu_cpmem_zero(ipu_plane->ipu_ch); 276 - ipu_cpmem_set_resolution(ipu_plane->ipu_ch, src_w, src_h); 277 - ret = ipu_cpmem_set_fmt(ipu_plane->ipu_ch, fb->pixel_format); 278 - if (ret < 0) { 279 - dev_err(dev, "unsupported pixel format 0x%08x\n", 280 - fb->pixel_format); 281 - return ret; 282 - } 283 - ipu_cpmem_set_high_priority(ipu_plane->ipu_ch); 284 - ipu_idmac_set_double_buffer(ipu_plane->ipu_ch, 1); 285 - ipu_cpmem_set_stride(ipu_plane->ipu_ch, fb->pitches[0]); 286 - 287 - ret = ipu_plane_set_base(ipu_plane, fb, src_x, src_y); 288 - if (ret < 0) 289 - return ret; 290 - if (interlaced) 291 - ipu_cpmem_interlaced_scan(ipu_plane->ipu_ch, fb->pitches[0]); 292 - 293 - if (fb->pixel_format == DRM_FORMAT_YUV420) { 294 - ipu_cpmem_set_yuv_planar_full(ipu_plane->ipu_ch, 295 - ipu_plane->stride[1], 296 - ipu_plane->u_offset, 297 - ipu_plane->v_offset); 298 - } else if (fb->pixel_format == DRM_FORMAT_YVU420) { 299 - ipu_cpmem_set_yuv_planar_full(ipu_plane->ipu_ch, 300 - ipu_plane->stride[1], 301 - ipu_plane->v_offset, 302 - ipu_plane->u_offset); 303 - } 304 - 305 - ipu_plane->w = src_w; 306 - ipu_plane->h = src_h; 307 - 308 - return 0; 309 180 } 310 181 311 182 void ipu_plane_put_resources(struct ipu_plane *ipu_plane) ··· 203 372 return ret; 204 373 } 205 374 206 - void ipu_plane_enable(struct ipu_plane *ipu_plane) 375 + static void ipu_plane_enable(struct ipu_plane *ipu_plane) 207 376 { 208 377 if (ipu_plane->dp) 209 378 ipu_dp_enable(ipu_plane->ipu); ··· 211 380 ipu_idmac_enable_channel(ipu_plane->ipu_ch); 212 381 if (ipu_plane->dp) 213 382 ipu_dp_enable_channel(ipu_plane->dp); 214 - 215 - ipu_plane->enabled = true; 216 383 } 217 384 218 - void ipu_plane_disable(struct ipu_plane *ipu_plane) 385 + static void ipu_plane_disable(struct ipu_plane *ipu_plane) 219 386 { 220 - ipu_plane->enabled = false; 221 - 222 387 ipu_idmac_wait_busy(ipu_plane->ipu_ch, 50); 223 388 224 389 if (ipu_plane->dp) ··· 225 398 ipu_dp_disable(ipu_plane->ipu); 226 399 } 227 400 228 - /* 229 - * drm_plane API 230 - */ 231 - 232 - static int ipu_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, 233 - struct drm_framebuffer *fb, int crtc_x, int crtc_y, 234 - unsigned int crtc_w, unsigned int crtc_h, 235 - uint32_t src_x, uint32_t src_y, 236 - uint32_t src_w, uint32_t src_h) 237 - { 238 - struct ipu_plane *ipu_plane = to_ipu_plane(plane); 239 - int ret = 0; 240 - 241 - DRM_DEBUG_KMS("plane - %p\n", plane); 242 - 243 - if (!ipu_plane->enabled) 244 - ret = ipu_plane_get_resources(ipu_plane); 245 - if (ret < 0) 246 - return ret; 247 - 248 - ret = ipu_plane_mode_set(ipu_plane, crtc, &crtc->hwmode, fb, 249 - crtc_x, crtc_y, crtc_w, crtc_h, 250 - src_x >> 16, src_y >> 16, src_w >> 16, src_h >> 16, 251 - false); 252 - if (ret < 0) { 253 - ipu_plane_put_resources(ipu_plane); 254 - return ret; 255 - } 256 - 257 - if (crtc != plane->crtc) 258 - dev_dbg(plane->dev->dev, "crtc change: %p -> %p\n", 259 - plane->crtc, crtc); 260 - 261 - if (!ipu_plane->enabled) 262 - ipu_plane_enable(ipu_plane); 263 - 264 - return 0; 265 - } 266 - 267 401 static int ipu_disable_plane(struct drm_plane *plane) 268 402 { 269 403 struct ipu_plane *ipu_plane = to_ipu_plane(plane); 270 404 271 405 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 272 406 273 - if (ipu_plane->enabled) 274 - ipu_plane_disable(ipu_plane); 275 - 276 - ipu_plane_put_resources(ipu_plane); 407 + ipu_plane_disable(ipu_plane); 277 408 278 409 return 0; 279 410 } ··· 248 463 } 249 464 250 465 static const struct drm_plane_funcs ipu_plane_funcs = { 251 - .update_plane = ipu_update_plane, 252 - .disable_plane = ipu_disable_plane, 466 + .update_plane = drm_atomic_helper_update_plane, 467 + .disable_plane = drm_atomic_helper_disable_plane, 253 468 .destroy = ipu_plane_destroy, 469 + .reset = drm_atomic_helper_plane_reset, 470 + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 471 + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 472 + }; 473 + 474 + static int ipu_plane_atomic_check(struct drm_plane *plane, 475 + struct drm_plane_state *state) 476 + { 477 + struct drm_plane_state *old_state = plane->state; 478 + struct drm_crtc_state *crtc_state; 479 + struct device *dev = plane->dev->dev; 480 + struct drm_framebuffer *fb = state->fb; 481 + struct drm_framebuffer *old_fb = old_state->fb; 482 + unsigned long eba, ubo, vbo, old_ubo, old_vbo; 483 + 484 + /* Ok to disable */ 485 + if (!fb) 486 + return 0; 487 + 488 + if (!state->crtc) 489 + return -EINVAL; 490 + 491 + crtc_state = 492 + drm_atomic_get_existing_crtc_state(state->state, state->crtc); 493 + if (WARN_ON(!crtc_state)) 494 + return -EINVAL; 495 + 496 + /* CRTC should be enabled */ 497 + if (!crtc_state->enable) 498 + return -EINVAL; 499 + 500 + /* no scaling */ 501 + if (state->src_w >> 16 != state->crtc_w || 502 + state->src_h >> 16 != state->crtc_h) 503 + return -EINVAL; 504 + 505 + switch (plane->type) { 506 + case DRM_PLANE_TYPE_PRIMARY: 507 + /* full plane doesn't support partial off screen */ 508 + if (state->crtc_x || state->crtc_y || 509 + state->crtc_w != crtc_state->adjusted_mode.hdisplay || 510 + state->crtc_h != crtc_state->adjusted_mode.vdisplay) 511 + return -EINVAL; 512 + 513 + /* full plane minimum width is 13 pixels */ 514 + if (state->crtc_w < 13) 515 + return -EINVAL; 516 + break; 517 + case DRM_PLANE_TYPE_OVERLAY: 518 + if (state->crtc_x < 0 || state->crtc_y < 0) 519 + return -EINVAL; 520 + 521 + if (state->crtc_x + state->crtc_w > 522 + crtc_state->adjusted_mode.hdisplay) 523 + return -EINVAL; 524 + if (state->crtc_y + state->crtc_h > 525 + crtc_state->adjusted_mode.vdisplay) 526 + return -EINVAL; 527 + break; 528 + default: 529 + dev_warn(dev, "Unsupported plane type\n"); 530 + return -EINVAL; 531 + } 532 + 533 + if (state->crtc_h < 2) 534 + return -EINVAL; 535 + 536 + /* 537 + * since we cannot touch active IDMAC channels, we do not support 538 + * resizing the enabled plane or changing its format 539 + */ 540 + if (old_fb && (state->src_w != old_state->src_w || 541 + state->src_h != old_state->src_h || 542 + fb->pixel_format != old_fb->pixel_format)) 543 + return -EINVAL; 544 + 545 + eba = drm_plane_state_to_eba(state); 546 + 547 + if (eba & 0x7) 548 + return -EINVAL; 549 + 550 + if (fb->pitches[0] < 1 || fb->pitches[0] > 16384) 551 + return -EINVAL; 552 + 553 + if (old_fb && fb->pitches[0] != old_fb->pitches[0]) 554 + return -EINVAL; 555 + 556 + switch (fb->pixel_format) { 557 + case DRM_FORMAT_YUV420: 558 + case DRM_FORMAT_YVU420: 559 + /* 560 + * Multiplanar formats have to meet the following restrictions: 561 + * - The (up to) three plane addresses are EBA, EBA+UBO, EBA+VBO 562 + * - EBA, UBO and VBO are a multiple of 8 563 + * - UBO and VBO are unsigned and not larger than 0xfffff8 564 + * - Only EBA may be changed while scanout is active 565 + * - The strides of U and V planes must be identical. 566 + */ 567 + ubo = drm_plane_state_to_ubo(state); 568 + vbo = drm_plane_state_to_vbo(state); 569 + 570 + if ((ubo & 0x7) || (vbo & 0x7)) 571 + return -EINVAL; 572 + 573 + if ((ubo > 0xfffff8) || (vbo > 0xfffff8)) 574 + return -EINVAL; 575 + 576 + if (old_fb) { 577 + old_ubo = drm_plane_state_to_ubo(old_state); 578 + old_vbo = drm_plane_state_to_vbo(old_state); 579 + if (ubo != old_ubo || vbo != old_vbo) 580 + return -EINVAL; 581 + } 582 + 583 + if (fb->pitches[1] != fb->pitches[2]) 584 + return -EINVAL; 585 + 586 + if (fb->pitches[1] < 1 || fb->pitches[1] > 16384) 587 + return -EINVAL; 588 + 589 + if (old_fb && old_fb->pitches[1] != fb->pitches[1]) 590 + return -EINVAL; 591 + } 592 + 593 + return 0; 594 + } 595 + 596 + static void ipu_plane_atomic_disable(struct drm_plane *plane, 597 + struct drm_plane_state *old_state) 598 + { 599 + ipu_disable_plane(plane); 600 + } 601 + 602 + static void ipu_plane_atomic_update(struct drm_plane *plane, 603 + struct drm_plane_state *old_state) 604 + { 605 + struct ipu_plane *ipu_plane = to_ipu_plane(plane); 606 + struct drm_plane_state *state = plane->state; 607 + enum ipu_color_space ics; 608 + 609 + if (old_state->fb) { 610 + ipu_plane_atomic_set_base(ipu_plane, old_state); 611 + return; 612 + } 613 + 614 + switch (ipu_plane->dp_flow) { 615 + case IPU_DP_FLOW_SYNC_BG: 616 + ipu_dp_setup_channel(ipu_plane->dp, 617 + IPUV3_COLORSPACE_RGB, 618 + IPUV3_COLORSPACE_RGB); 619 + ipu_dp_set_global_alpha(ipu_plane->dp, true, 0, true); 620 + break; 621 + case IPU_DP_FLOW_SYNC_FG: 622 + ics = ipu_drm_fourcc_to_colorspace(state->fb->pixel_format); 623 + ipu_dp_setup_channel(ipu_plane->dp, ics, 624 + IPUV3_COLORSPACE_UNKNOWN); 625 + ipu_dp_set_window_pos(ipu_plane->dp, state->crtc_x, 626 + state->crtc_y); 627 + /* Enable local alpha on partial plane */ 628 + switch (state->fb->pixel_format) { 629 + case DRM_FORMAT_ARGB1555: 630 + case DRM_FORMAT_ABGR1555: 631 + case DRM_FORMAT_RGBA5551: 632 + case DRM_FORMAT_BGRA5551: 633 + case DRM_FORMAT_ARGB4444: 634 + case DRM_FORMAT_ARGB8888: 635 + case DRM_FORMAT_ABGR8888: 636 + case DRM_FORMAT_RGBA8888: 637 + case DRM_FORMAT_BGRA8888: 638 + ipu_dp_set_global_alpha(ipu_plane->dp, false, 0, false); 639 + break; 640 + default: 641 + break; 642 + } 643 + } 644 + 645 + ipu_dmfc_config_wait4eot(ipu_plane->dmfc, state->crtc_w); 646 + 647 + ipu_cpmem_zero(ipu_plane->ipu_ch); 648 + ipu_cpmem_set_resolution(ipu_plane->ipu_ch, state->src_w >> 16, 649 + state->src_h >> 16); 650 + ipu_cpmem_set_fmt(ipu_plane->ipu_ch, state->fb->pixel_format); 651 + ipu_cpmem_set_high_priority(ipu_plane->ipu_ch); 652 + ipu_idmac_set_double_buffer(ipu_plane->ipu_ch, 1); 653 + ipu_cpmem_set_stride(ipu_plane->ipu_ch, state->fb->pitches[0]); 654 + ipu_plane_atomic_set_base(ipu_plane, old_state); 655 + ipu_plane_enable(ipu_plane); 656 + } 657 + 658 + static const struct drm_plane_helper_funcs ipu_plane_helper_funcs = { 659 + .atomic_check = ipu_plane_atomic_check, 660 + .atomic_disable = ipu_plane_atomic_disable, 661 + .atomic_update = ipu_plane_atomic_update, 254 662 }; 255 663 256 664 struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu, ··· 475 497 kfree(ipu_plane); 476 498 return ERR_PTR(ret); 477 499 } 500 + 501 + drm_plane_helper_add(&ipu_plane->base, &ipu_plane_helper_funcs); 478 502 479 503 return ipu_plane; 480 504 }
-16
drivers/gpu/drm/imx/ipuv3-plane.h
··· 23 23 24 24 int dma; 25 25 int dp_flow; 26 - 27 - int x; 28 - int y; 29 - int w; 30 - int h; 31 - 32 - unsigned int u_offset; 33 - unsigned int v_offset; 34 - unsigned int stride[2]; 35 - 36 - bool enabled; 37 26 }; 38 27 39 28 struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu, ··· 36 47 unsigned int crtc_w, unsigned int crtc_h, 37 48 uint32_t src_x, uint32_t src_y, uint32_t src_w, 38 49 uint32_t src_h, bool interlaced); 39 - 40 - void ipu_plane_enable(struct ipu_plane *plane); 41 - void ipu_plane_disable(struct ipu_plane *plane); 42 - int ipu_plane_set_base(struct ipu_plane *plane, struct drm_framebuffer *fb, 43 - int x, int y); 44 50 45 51 int ipu_plane_get_resources(struct ipu_plane *plane); 46 52 void ipu_plane_put_resources(struct ipu_plane *plane);
+96 -55
drivers/gpu/drm/imx/parallel-display.c
··· 16 16 #include <linux/component.h> 17 17 #include <linux/module.h> 18 18 #include <drm/drmP.h> 19 + #include <drm/drm_atomic_helper.h> 19 20 #include <drm/drm_fb_helper.h> 20 21 #include <drm/drm_crtc_helper.h> 21 22 #include <drm/drm_panel.h> ··· 25 24 #include <linux/of_graph.h> 26 25 27 26 #include "imx-drm.h" 28 - 29 - #define con_to_imxpd(x) container_of(x, struct imx_parallel_display, connector) 30 - #define enc_to_imxpd(x) container_of(x, struct imx_parallel_display, encoder) 31 27 32 28 struct imx_parallel_display { 33 29 struct drm_connector connector; ··· 35 37 u32 bus_format; 36 38 struct drm_display_mode mode; 37 39 struct drm_panel *panel; 40 + struct drm_bridge *bridge; 38 41 }; 42 + 43 + static inline struct imx_parallel_display *con_to_imxpd(struct drm_connector *c) 44 + { 45 + return container_of(c, struct imx_parallel_display, connector); 46 + } 47 + 48 + static inline struct imx_parallel_display *enc_to_imxpd(struct drm_encoder *e) 49 + { 50 + return container_of(e, struct imx_parallel_display, encoder); 51 + } 39 52 40 53 static enum drm_connector_status imx_pd_connector_detect( 41 54 struct drm_connector *connector, bool force) ··· 62 53 63 54 if (imxpd->panel && imxpd->panel->funcs && 64 55 imxpd->panel->funcs->get_modes) { 65 - struct drm_display_info *di = &connector->display_info; 66 - 67 56 num_modes = imxpd->panel->funcs->get_modes(imxpd->panel); 68 - if (!imxpd->bus_format && di->num_bus_formats) 69 - imxpd->bus_format = di->bus_formats[0]; 70 57 if (num_modes > 0) 71 58 return num_modes; 72 59 } ··· 74 69 75 70 if (np) { 76 71 struct drm_display_mode *mode = drm_mode_create(connector->dev); 72 + int ret; 77 73 78 74 if (!mode) 79 75 return -EINVAL; 80 - of_get_drm_display_mode(np, &imxpd->mode, OF_USE_NATIVE_MODE); 76 + 77 + ret = of_get_drm_display_mode(np, &imxpd->mode, 78 + OF_USE_NATIVE_MODE); 79 + if (ret) 80 + return ret; 81 + 81 82 drm_mode_copy(mode, &imxpd->mode); 82 83 mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, 83 84 drm_mode_probed_add(connector, mode); ··· 101 90 return &imxpd->encoder; 102 91 } 103 92 104 - static void imx_pd_encoder_dpms(struct drm_encoder *encoder, int mode) 105 - { 106 - struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); 107 - 108 - if (mode != DRM_MODE_DPMS_ON) 109 - drm_panel_disable(imxpd->panel); 110 - else 111 - drm_panel_enable(imxpd->panel); 112 - } 113 - 114 - static void imx_pd_encoder_prepare(struct drm_encoder *encoder) 115 - { 116 - struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); 117 - imx_drm_set_bus_config(encoder, imxpd->bus_format, 2, 3, 118 - imxpd->connector.display_info.bus_flags); 119 - } 120 - 121 - static void imx_pd_encoder_commit(struct drm_encoder *encoder) 93 + static void imx_pd_encoder_enable(struct drm_encoder *encoder) 122 94 { 123 95 struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); 124 96 125 97 drm_panel_prepare(imxpd->panel); 126 98 drm_panel_enable(imxpd->panel); 127 - } 128 - 129 - static void imx_pd_encoder_mode_set(struct drm_encoder *encoder, 130 - struct drm_display_mode *orig_mode, 131 - struct drm_display_mode *mode) 132 - { 133 99 } 134 100 135 101 static void imx_pd_encoder_disable(struct drm_encoder *encoder) ··· 117 129 drm_panel_unprepare(imxpd->panel); 118 130 } 119 131 132 + static int imx_pd_encoder_atomic_check(struct drm_encoder *encoder, 133 + struct drm_crtc_state *crtc_state, 134 + struct drm_connector_state *conn_state) 135 + { 136 + struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc_state); 137 + struct drm_display_info *di = &conn_state->connector->display_info; 138 + struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); 139 + 140 + imx_crtc_state->bus_flags = di->bus_flags; 141 + if (!imxpd->bus_format && di->num_bus_formats) 142 + imx_crtc_state->bus_format = di->bus_formats[0]; 143 + else 144 + imx_crtc_state->bus_format = imxpd->bus_format; 145 + imx_crtc_state->di_hsync_pin = 2; 146 + imx_crtc_state->di_vsync_pin = 3; 147 + 148 + return 0; 149 + } 150 + 120 151 static const struct drm_connector_funcs imx_pd_connector_funcs = { 121 - .dpms = drm_helper_connector_dpms, 152 + .dpms = drm_atomic_helper_connector_dpms, 122 153 .fill_modes = drm_helper_probe_single_connector_modes, 123 154 .detect = imx_pd_connector_detect, 124 155 .destroy = imx_drm_connector_destroy, 156 + .reset = drm_atomic_helper_connector_reset, 157 + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 158 + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 125 159 }; 126 160 127 161 static const struct drm_connector_helper_funcs imx_pd_connector_helper_funcs = { ··· 156 146 }; 157 147 158 148 static const struct drm_encoder_helper_funcs imx_pd_encoder_helper_funcs = { 159 - .dpms = imx_pd_encoder_dpms, 160 - .prepare = imx_pd_encoder_prepare, 161 - .commit = imx_pd_encoder_commit, 162 - .mode_set = imx_pd_encoder_mode_set, 149 + .enable = imx_pd_encoder_enable, 163 150 .disable = imx_pd_encoder_disable, 151 + .atomic_check = imx_pd_encoder_atomic_check, 164 152 }; 165 153 166 154 static int imx_pd_register(struct drm_device *drm, 167 155 struct imx_parallel_display *imxpd) 168 156 { 157 + struct drm_encoder *encoder = &imxpd->encoder; 169 158 int ret; 170 159 171 - ret = imx_drm_encoder_parse_of(drm, &imxpd->encoder, 172 - imxpd->dev->of_node); 160 + ret = imx_drm_encoder_parse_of(drm, encoder, imxpd->dev->of_node); 173 161 if (ret) 174 162 return ret; 175 163 ··· 178 170 */ 179 171 imxpd->connector.dpms = DRM_MODE_DPMS_OFF; 180 172 181 - drm_encoder_helper_add(&imxpd->encoder, &imx_pd_encoder_helper_funcs); 182 - drm_encoder_init(drm, &imxpd->encoder, &imx_pd_encoder_funcs, 173 + drm_encoder_helper_add(encoder, &imx_pd_encoder_helper_funcs); 174 + drm_encoder_init(drm, encoder, &imx_pd_encoder_funcs, 183 175 DRM_MODE_ENCODER_NONE, NULL); 184 176 185 - drm_connector_helper_add(&imxpd->connector, 186 - &imx_pd_connector_helper_funcs); 187 - drm_connector_init(drm, &imxpd->connector, &imx_pd_connector_funcs, 188 - DRM_MODE_CONNECTOR_VGA); 177 + if (!imxpd->bridge) { 178 + drm_connector_helper_add(&imxpd->connector, 179 + &imx_pd_connector_helper_funcs); 180 + drm_connector_init(drm, &imxpd->connector, 181 + &imx_pd_connector_funcs, 182 + DRM_MODE_CONNECTOR_VGA); 183 + } 189 184 190 185 if (imxpd->panel) 191 186 drm_panel_attach(imxpd->panel, &imxpd->connector); 192 187 193 - drm_mode_connector_attach_encoder(&imxpd->connector, &imxpd->encoder); 188 + if (imxpd->bridge) { 189 + imxpd->bridge->encoder = encoder; 190 + encoder->bridge = imxpd->bridge; 191 + ret = drm_bridge_attach(drm, imxpd->bridge); 192 + if (ret < 0) { 193 + dev_err(imxpd->dev, "failed to attach bridge: %d\n", 194 + ret); 195 + return ret; 196 + } 197 + } else { 198 + drm_mode_connector_attach_encoder(&imxpd->connector, encoder); 199 + } 194 200 195 201 return 0; 196 202 } ··· 217 195 const u8 *edidp; 218 196 struct imx_parallel_display *imxpd; 219 197 int ret; 198 + u32 bus_format = 0; 220 199 const char *fmt; 221 200 222 201 imxpd = devm_kzalloc(dev, sizeof(*imxpd), GFP_KERNEL); ··· 231 208 ret = of_property_read_string(np, "interface-pix-fmt", &fmt); 232 209 if (!ret) { 233 210 if (!strcmp(fmt, "rgb24")) 234 - imxpd->bus_format = MEDIA_BUS_FMT_RGB888_1X24; 211 + bus_format = MEDIA_BUS_FMT_RGB888_1X24; 235 212 else if (!strcmp(fmt, "rgb565")) 236 - imxpd->bus_format = MEDIA_BUS_FMT_RGB565_1X16; 213 + bus_format = MEDIA_BUS_FMT_RGB565_1X16; 237 214 else if (!strcmp(fmt, "bgr666")) 238 - imxpd->bus_format = MEDIA_BUS_FMT_RGB666_1X18; 215 + bus_format = MEDIA_BUS_FMT_RGB666_1X18; 239 216 else if (!strcmp(fmt, "lvds666")) 240 - imxpd->bus_format = MEDIA_BUS_FMT_RGB666_1X24_CPADHI; 217 + bus_format = MEDIA_BUS_FMT_RGB666_1X24_CPADHI; 241 218 } 219 + imxpd->bus_format = bus_format; 242 220 243 221 /* port@1 is the output port */ 244 222 ep = of_graph_get_endpoint_by_regs(np, 1, -1); ··· 247 223 struct device_node *remote; 248 224 249 225 remote = of_graph_get_remote_port_parent(ep); 250 - of_node_put(ep); 251 - if (remote) { 252 - imxpd->panel = of_drm_find_panel(remote); 253 - of_node_put(remote); 226 + if (!remote) { 227 + dev_warn(dev, "endpoint %s not connected\n", 228 + ep->full_name); 229 + of_node_put(ep); 230 + return -ENODEV; 254 231 } 255 - if (!imxpd->panel) 232 + of_node_put(ep); 233 + 234 + imxpd->panel = of_drm_find_panel(remote); 235 + if (imxpd->panel) { 236 + dev_dbg(dev, "found panel %s\n", remote->full_name); 237 + } else { 238 + imxpd->bridge = of_drm_find_bridge(remote); 239 + if (imxpd->bridge) 240 + dev_dbg(dev, "found bridge %s\n", 241 + remote->full_name); 242 + } 243 + if (!imxpd->panel && !imxpd->bridge) { 244 + dev_dbg(dev, "waiting for panel or bridge %s\n", 245 + remote->full_name); 246 + of_node_put(remote); 256 247 return -EPROBE_DEFER; 248 + } 249 + of_node_put(remote); 257 250 } 258 251 259 252 imxpd->dev = dev;
+3 -6
drivers/gpu/ipu-v3/ipu-dc.c
··· 150 150 static int ipu_bus_format_to_map(u32 fmt) 151 151 { 152 152 switch (fmt) { 153 + default: 154 + WARN_ON(1); 155 + /* fall-through */ 153 156 case MEDIA_BUS_FMT_RGB888_1X24: 154 157 return IPU_DC_MAP_RGB24; 155 158 case MEDIA_BUS_FMT_RGB565_1X16: ··· 165 162 return IPU_DC_MAP_LVDS666; 166 163 case MEDIA_BUS_FMT_BGR888_1X24: 167 164 return IPU_DC_MAP_BGR24; 168 - default: 169 - return -EINVAL; 170 165 } 171 166 } 172 167 ··· 179 178 dc->di = ipu_di_get_num(di); 180 179 181 180 map = ipu_bus_format_to_map(bus_format); 182 - if (map < 0) { 183 - dev_dbg(priv->dev, "IPU_DISP: No MAP\n"); 184 - return map; 185 - } 186 181 187 182 /* 188 183 * In interlaced mode we need more counters to create the asymmetric
-3
drivers/gpu/ipu-v3/ipu-di.c
··· 572 572 dev_dbg(di->ipu->dev, "disp %d: panel size = %d x %d\n", 573 573 di->id, sig->mode.hactive, sig->mode.vactive); 574 574 575 - if ((sig->mode.vsync_len == 0) || (sig->mode.hsync_len == 0)) 576 - return -EINVAL; 577 - 578 575 dev_dbg(di->ipu->dev, "Clocks: IPU %luHz DI %luHz Needed %luHz\n", 579 576 clk_get_rate(di->clk_ipu), 580 577 clk_get_rate(di->clk_di),
+7 -206
drivers/gpu/ipu-v3/ipu-dmfc.c
··· 45 45 #define DMFC_DP_CHAN_6B_24 16 46 46 #define DMFC_DP_CHAN_6F_29 24 47 47 48 - #define DMFC_FIFO_SIZE_64 (3 << 3) 49 - #define DMFC_FIFO_SIZE_128 (2 << 3) 50 - #define DMFC_FIFO_SIZE_256 (1 << 3) 51 - #define DMFC_FIFO_SIZE_512 (0 << 3) 52 - 53 - #define DMFC_SEGMENT(x) ((x & 0x7) << 0) 54 - #define DMFC_BURSTSIZE_128 (0 << 6) 55 - #define DMFC_BURSTSIZE_64 (1 << 6) 56 - #define DMFC_BURSTSIZE_32 (2 << 6) 57 - #define DMFC_BURSTSIZE_16 (3 << 6) 58 - 59 48 struct dmfc_channel_data { 60 49 int ipu_channel; 61 50 unsigned long channel_reg; ··· 93 104 94 105 struct dmfc_channel { 95 106 unsigned slots; 96 - unsigned slotmask; 97 - unsigned segment; 98 - int burstsize; 99 107 struct ipu_soc *ipu; 100 108 struct ipu_dmfc_priv *priv; 101 109 const struct dmfc_channel_data *data; ··· 103 117 struct device *dev; 104 118 struct dmfc_channel channels[DMFC_NUM_CHANNELS]; 105 119 struct mutex mutex; 106 - unsigned long bandwidth_per_slot; 107 120 void __iomem *base; 108 121 int use_count; 109 122 }; ··· 157 172 } 158 173 EXPORT_SYMBOL_GPL(ipu_dmfc_disable_channel); 159 174 160 - static int ipu_dmfc_setup_channel(struct dmfc_channel *dmfc, int slots, 161 - int segment, int burstsize) 162 - { 163 - struct ipu_dmfc_priv *priv = dmfc->priv; 164 - u32 val, field; 165 - 166 - dev_dbg(priv->dev, 167 - "dmfc: using %d slots starting from segment %d for IPU channel %d\n", 168 - slots, segment, dmfc->data->ipu_channel); 169 - 170 - switch (slots) { 171 - case 1: 172 - field = DMFC_FIFO_SIZE_64; 173 - break; 174 - case 2: 175 - field = DMFC_FIFO_SIZE_128; 176 - break; 177 - case 4: 178 - field = DMFC_FIFO_SIZE_256; 179 - break; 180 - case 8: 181 - field = DMFC_FIFO_SIZE_512; 182 - break; 183 - default: 184 - return -EINVAL; 185 - } 186 - 187 - switch (burstsize) { 188 - case 16: 189 - field |= DMFC_BURSTSIZE_16; 190 - break; 191 - case 32: 192 - field |= DMFC_BURSTSIZE_32; 193 - break; 194 - case 64: 195 - field |= DMFC_BURSTSIZE_64; 196 - break; 197 - case 128: 198 - field |= DMFC_BURSTSIZE_128; 199 - break; 200 - } 201 - 202 - field |= DMFC_SEGMENT(segment); 203 - 204 - val = readl(priv->base + dmfc->data->channel_reg); 205 - 206 - val &= ~(0xff << dmfc->data->shift); 207 - val |= field << dmfc->data->shift; 208 - 209 - writel(val, priv->base + dmfc->data->channel_reg); 210 - 211 - dmfc->slots = slots; 212 - dmfc->segment = segment; 213 - dmfc->burstsize = burstsize; 214 - dmfc->slotmask = ((1 << slots) - 1) << segment; 215 - 216 - return 0; 217 - } 218 - 219 - static int dmfc_bandwidth_to_slots(struct ipu_dmfc_priv *priv, 220 - unsigned long bandwidth) 221 - { 222 - int slots = 1; 223 - 224 - while (slots * priv->bandwidth_per_slot < bandwidth) 225 - slots *= 2; 226 - 227 - return slots; 228 - } 229 - 230 - static int dmfc_find_slots(struct ipu_dmfc_priv *priv, int slots) 231 - { 232 - unsigned slotmask_need, slotmask_used = 0; 233 - int i, segment = 0; 234 - 235 - slotmask_need = (1 << slots) - 1; 236 - 237 - for (i = 0; i < DMFC_NUM_CHANNELS; i++) 238 - slotmask_used |= priv->channels[i].slotmask; 239 - 240 - while (slotmask_need <= 0xff) { 241 - if (!(slotmask_used & slotmask_need)) 242 - return segment; 243 - 244 - slotmask_need <<= 1; 245 - segment++; 246 - } 247 - 248 - return -EBUSY; 249 - } 250 - 251 - void ipu_dmfc_free_bandwidth(struct dmfc_channel *dmfc) 252 - { 253 - struct ipu_dmfc_priv *priv = dmfc->priv; 254 - int i; 255 - 256 - dev_dbg(priv->dev, "dmfc: freeing %d slots starting from segment %d\n", 257 - dmfc->slots, dmfc->segment); 258 - 259 - mutex_lock(&priv->mutex); 260 - 261 - if (!dmfc->slots) 262 - goto out; 263 - 264 - dmfc->slotmask = 0; 265 - dmfc->slots = 0; 266 - dmfc->segment = 0; 267 - 268 - for (i = 0; i < DMFC_NUM_CHANNELS; i++) 269 - priv->channels[i].slotmask = 0; 270 - 271 - for (i = 0; i < DMFC_NUM_CHANNELS; i++) { 272 - if (priv->channels[i].slots > 0) { 273 - priv->channels[i].segment = 274 - dmfc_find_slots(priv, priv->channels[i].slots); 275 - priv->channels[i].slotmask = 276 - ((1 << priv->channels[i].slots) - 1) << 277 - priv->channels[i].segment; 278 - } 279 - } 280 - 281 - for (i = 0; i < DMFC_NUM_CHANNELS; i++) { 282 - if (priv->channels[i].slots > 0) 283 - ipu_dmfc_setup_channel(&priv->channels[i], 284 - priv->channels[i].slots, 285 - priv->channels[i].segment, 286 - priv->channels[i].burstsize); 287 - } 288 - out: 289 - mutex_unlock(&priv->mutex); 290 - } 291 - EXPORT_SYMBOL_GPL(ipu_dmfc_free_bandwidth); 292 - 293 - int ipu_dmfc_alloc_bandwidth(struct dmfc_channel *dmfc, 294 - unsigned long bandwidth_pixel_per_second, int burstsize) 295 - { 296 - struct ipu_dmfc_priv *priv = dmfc->priv; 297 - int slots = dmfc_bandwidth_to_slots(priv, bandwidth_pixel_per_second); 298 - int segment = -1, ret = 0; 299 - 300 - dev_dbg(priv->dev, "dmfc: trying to allocate %ldMpixel/s for IPU channel %d\n", 301 - bandwidth_pixel_per_second / 1000000, 302 - dmfc->data->ipu_channel); 303 - 304 - ipu_dmfc_free_bandwidth(dmfc); 305 - 306 - mutex_lock(&priv->mutex); 307 - 308 - if (slots > 8) { 309 - ret = -EBUSY; 310 - goto out; 311 - } 312 - 313 - /* For the MEM_BG channel, first try to allocate twice the slots */ 314 - if (dmfc->data->ipu_channel == IPUV3_CHANNEL_MEM_BG_SYNC) 315 - segment = dmfc_find_slots(priv, slots * 2); 316 - else if (slots < 2) 317 - /* Always allocate at least 128*4 bytes (2 slots) */ 318 - slots = 2; 319 - 320 - if (segment >= 0) 321 - slots *= 2; 322 - else 323 - segment = dmfc_find_slots(priv, slots); 324 - if (segment < 0) { 325 - ret = -EBUSY; 326 - goto out; 327 - } 328 - 329 - ipu_dmfc_setup_channel(dmfc, slots, segment, burstsize); 330 - 331 - out: 332 - mutex_unlock(&priv->mutex); 333 - 334 - return ret; 335 - } 336 - EXPORT_SYMBOL_GPL(ipu_dmfc_alloc_bandwidth); 337 - 338 175 void ipu_dmfc_config_wait4eot(struct dmfc_channel *dmfc, int width) 339 176 { 340 177 struct ipu_dmfc_priv *priv = dmfc->priv; ··· 191 384 192 385 void ipu_dmfc_put(struct dmfc_channel *dmfc) 193 386 { 194 - ipu_dmfc_free_bandwidth(dmfc); 195 387 } 196 388 EXPORT_SYMBOL_GPL(ipu_dmfc_put); 197 389 ··· 218 412 priv->channels[i].priv = priv; 219 413 priv->channels[i].ipu = ipu; 220 414 priv->channels[i].data = &dmfcdata[i]; 415 + 416 + if (dmfcdata[i].ipu_channel == IPUV3_CHANNEL_MEM_BG_SYNC || 417 + dmfcdata[i].ipu_channel == IPUV3_CHANNEL_MEM_FG_SYNC || 418 + dmfcdata[i].ipu_channel == IPUV3_CHANNEL_MEM_DC_SYNC) 419 + priv->channels[i].slots = 2; 221 420 } 222 421 223 - writel(0x0, priv->base + DMFC_WR_CHAN); 224 - writel(0x0, priv->base + DMFC_DP_CHAN); 225 - 226 - /* 227 - * We have a total bandwidth of clkrate * 4pixel divided 228 - * into 8 slots. 229 - */ 230 - priv->bandwidth_per_slot = clk_get_rate(ipu_clk) * 4 / 8; 231 - 232 - dev_dbg(dev, "dmfc: 8 slots with %ldMpixel/s bandwidth each\n", 233 - priv->bandwidth_per_slot / 1000000); 234 - 422 + writel(0x00000050, priv->base + DMFC_WR_CHAN); 423 + writel(0x00005654, priv->base + DMFC_DP_CHAN); 235 424 writel(0x202020f6, priv->base + DMFC_WR_CHAN_DEF); 236 425 writel(0x2020f6f6, priv->base + DMFC_DP_CHAN_DEF); 237 426 writel(0x00000003, priv->base + DMFC_GENERAL1);
-3
include/video/imx-ipu-v3.h
··· 235 235 struct dmfc_channel; 236 236 int ipu_dmfc_enable_channel(struct dmfc_channel *dmfc); 237 237 void ipu_dmfc_disable_channel(struct dmfc_channel *dmfc); 238 - int ipu_dmfc_alloc_bandwidth(struct dmfc_channel *dmfc, 239 - unsigned long bandwidth_mbs, int burstsize); 240 - void ipu_dmfc_free_bandwidth(struct dmfc_channel *dmfc); 241 238 void ipu_dmfc_config_wait4eot(struct dmfc_channel *dmfc, int width); 242 239 struct dmfc_channel *ipu_dmfc_get(struct ipu_soc *ipu, int ipuv3_channel); 243 240 void ipu_dmfc_put(struct dmfc_channel *dmfc);