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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'drm-misc-next-2022-03-03' of git://anongit.freedesktop.org/drm/drm-misc into drm-next

drm-misc-next for v5.18:

UAPI Changes:

Cross-subsystem Changes:
- Improve performance of some fbdev ops, in some cases up to 6x faster.

Core Changes:
- Some small DP fixes.
- Find panels in subnodes of OF devices, and add of_get_drm_panel_display_mode
to retrieve mode.
- Add drm_object_property_get_default_value and use it for resetting
zpos in plane state reset, removing the need for individual drivers
to do it.
- Same for color encoding and color range props.
- Update panic handling todo doc.
- Add todo that format conversion helpers should be sped up similarly to fbdev ops.

Driver Changes:
- Add panel orientation property to simpledrm for quirked panels.
- Assorted small fixes to tiny/repaper, nouveau, stm, omap, ssd130x.
- Add crc support to stm/ltdc.
- Add MIPI DBI compatible SPI driver
- Assorted small fixes to tiny panels and bridge drivers.
- Add AST2600 support to aspeed.

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/48fabd78-ade9-f80b-c724-13726c7be69e@linux.intel.com

+1051 -572
+126
Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/display/panel/panel-mipi-dbi-spi.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: MIPI DBI SPI Panel 8 + 9 + maintainers: 10 + - Noralf Trønnes <noralf@tronnes.org> 11 + 12 + description: | 13 + This binding is for display panels using a MIPI DBI compatible controller 14 + in SPI mode. 15 + 16 + The MIPI Alliance Standard for Display Bus Interface defines the electrical 17 + and logical interfaces for display controllers historically used in mobile 18 + phones. The standard defines 4 display architecture types and this binding is 19 + for type 1 which has full frame memory. There are 3 interface types in the 20 + standard and type C is the serial interface. 21 + 22 + The standard defines the following interface signals for type C: 23 + - Power: 24 + - Vdd: Power supply for display module 25 + - Vddi: Logic level supply for interface signals 26 + Combined into one in this binding called: power-supply 27 + - Interface: 28 + - CSx: Chip select 29 + - SCL: Serial clock 30 + - Dout: Serial out 31 + - Din: Serial in 32 + - SDA: Bidrectional in/out 33 + - D/CX: Data/command selection, high=data, low=command 34 + Called dc-gpios in this binding. 35 + - RESX: Reset when low 36 + Called reset-gpios in this binding. 37 + 38 + The type C interface has 3 options: 39 + 40 + - Option 1: 9-bit mode and D/CX as the 9th bit 41 + | Command | the next command or following data | 42 + |<0><D7><D6><D5><D4><D3><D2><D1><D0>|<D/CX><D7><D6><D5><D4><D3><D2><D1><D0>| 43 + 44 + - Option 2: 16-bit mode and D/CX as a 9th bit 45 + | Command or data | 46 + |<X><X><X><X><X><X><X><D/CX><D7><D6><D5><D4><D3><D2><D1><D0>| 47 + 48 + - Option 3: 8-bit mode and D/CX as a separate interface line 49 + | Command or data | 50 + |<D7><D6><D5><D4><D3><D2><D1><D0>| 51 + 52 + The panel resolution is specified using the panel-timing node properties 53 + hactive (width) and vactive (height). The other mandatory panel-timing 54 + properties should be set to zero except clock-frequency which can be 55 + optionally set to inform about the actual pixel clock frequency. 56 + 57 + If the panel is wired to the controller at an offset specify this using 58 + hback-porch (x-offset) and vback-porch (y-offset). 59 + 60 + allOf: 61 + - $ref: panel-common.yaml# 62 + - $ref: /schemas/spi/spi-peripheral-props.yaml# 63 + 64 + properties: 65 + compatible: 66 + items: 67 + - enum: 68 + - sainsmart18 69 + - const: panel-mipi-dbi-spi 70 + 71 + write-only: 72 + type: boolean 73 + description: 74 + Controller is not readable (ie. Din (MISO on the SPI interface) is not 75 + wired up). 76 + 77 + dc-gpios: 78 + maxItems: 1 79 + description: | 80 + Controller data/command selection (D/CX) in 4-line SPI mode. 81 + If not set, the controller is in 3-line SPI mode. 82 + 83 + required: 84 + - compatible 85 + - reg 86 + - panel-timing 87 + 88 + unevaluatedProperties: false 89 + 90 + examples: 91 + - | 92 + #include <dt-bindings/gpio/gpio.h> 93 + 94 + spi { 95 + #address-cells = <1>; 96 + #size-cells = <0>; 97 + 98 + display@0{ 99 + compatible = "sainsmart18", "panel-mipi-dbi-spi"; 100 + reg = <0>; 101 + spi-max-frequency = <40000000>; 102 + 103 + dc-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>; 104 + reset-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>; 105 + write-only; 106 + 107 + backlight = <&backlight>; 108 + 109 + width-mm = <35>; 110 + height-mm = <28>; 111 + 112 + panel-timing { 113 + hactive = <160>; 114 + vactive = <128>; 115 + hback-porch = <0>; 116 + vback-porch = <0>; 117 + clock-frequency = <0>; 118 + hfront-porch = <0>; 119 + hsync-len = <0>; 120 + vfront-porch = <0>; 121 + vsync-len = <0>; 122 + }; 123 + }; 124 + }; 125 + 126 + ...
+36 -11
Documentation/gpu/todo.rst
··· 241 241 242 242 Level: Advanced 243 243 244 + Benchmark and optimize blitting and format-conversion function 245 + -------------------------------------------------------------- 246 + 247 + Drawing to dispay memory quickly is crucial for many applications' 248 + performance. 249 + 250 + On at least x86-64, sys_imageblit() is significantly slower than 251 + cfb_imageblit(), even though both use the same blitting algorithm and 252 + the latter is written for I/O memory. It turns out that cfb_imageblit() 253 + uses movl instructions, while sys_imageblit apparently does not. This 254 + seems to be a problem with gcc's optimizer. DRM's format-conversion 255 + helpers might be subject to similar issues. 256 + 257 + Benchmark and optimize fbdev's sys_() helpers and DRM's format-conversion 258 + helpers. In cases that can be further optimized, maybe implement a different 259 + algorithm. For micro-optimizations, use movl/movq instructions explicitly. 260 + That might possibly require architecture-specific helpers (e.g., storel() 261 + storeq()). 262 + 263 + Contact: Thomas Zimmermann <tzimmermann@suse.de> 264 + 265 + Level: Intermediate 244 266 245 267 drm_framebuffer_funcs and drm_mode_config_funcs.fb_create cleanup 246 268 ----------------------------------------------------------------- ··· 497 475 achieved by using an IPI to the local processor. 498 476 499 477 * There's a massive confusion of different panic handlers. DRM fbdev emulation 500 - helpers have one, but on top of that the fbcon code itself also has one. We 501 - need to make sure that they stop fighting over each another. 478 + helpers had their own (long removed), but on top of that the fbcon code itself 479 + also has one. We need to make sure that they stop fighting over each other. 480 + This is worked around by checking ``oops_in_progress`` at various entry points 481 + into the DRM fbdev emulation helpers. A much cleaner approach here would be to 482 + switch fbcon to the `threaded printk support 483 + <https://lwn.net/Articles/800946/>`_. 502 484 503 485 * ``drm_can_sleep()`` is a mess. It hides real bugs in normal operations and 504 486 isn't a full solution for panic paths. We need to make sure that it only ··· 514 488 even spinlocks (because NMI and hardirq can panic too). We need to either 515 489 make sure to not call such paths, or trylock everything. Really tricky. 516 490 517 - * For the above locking troubles reasons it's pretty much impossible to 518 - attempt a synchronous modeset from panic handlers. The only thing we could 519 - try to achive is an atomic ``set_base`` of the primary plane, and hope that 520 - it shows up. Everything else probably needs to be delayed to some worker or 521 - something else which happens later on. Otherwise it just kills the box 522 - harder, prevent the panic from going out on e.g. netconsole. 491 + * A clean solution would be an entirely separate panic output support in KMS, 492 + bypassing the current fbcon support. See `[PATCH v2 0/3] drm: Add panic handling 493 + <https://lore.kernel.org/dri-devel/20190311174218.51899-1-noralf@tronnes.org/>`_. 523 494 524 - * There's also proposal for a simplied DRM console instead of the full-blown 525 - fbcon and DRM fbdev emulation. Any kind of panic handling tricks should 526 - obviously work for both console, in case we ever get kmslog merged. 495 + * Encoding the actual oops and preceding dmesg in a QR might help with the 496 + dread "important stuff scrolled away" problem. See `[RFC][PATCH] Oops messages 497 + transfer using QR codes 498 + <https://lore.kernel.org/lkml/1446217392-11981-1-git-send-email-alexandru.murtaza@intel.com/>`_ 499 + for some example code that could be reused. 527 500 528 501 Contact: Daniel Vetter 529 502
+8
MAINTAINERS
··· 6112 6112 F: Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt 6113 6113 F: drivers/gpu/drm/tiny/mi0283qt.c 6114 6114 6115 + DRM DRIVER FOR MIPI DBI compatible panels 6116 + M: Noralf Trønnes <noralf@tronnes.org> 6117 + S: Maintained 6118 + W: https://github.com/notro/panel-mipi-dbi/wiki 6119 + T: git git://anongit.freedesktop.org/drm/drm-misc 6120 + F: Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml 6121 + F: drivers/gpu/drm/tiny/panel-mipi-dbi.c 6122 + 6115 6123 DRM DRIVER FOR MSM ADRENO GPU 6116 6124 M: Rob Clark <robdclark@gmail.com> 6117 6125 M: Sean Paul <sean@poorly.run>
+1
drivers/gpu/drm/aspeed/aspeed_gfx.h
··· 12 12 struct regmap *scu; 13 13 14 14 u32 dac_reg; 15 + u32 int_clr_reg; 15 16 u32 vga_scratch_reg; 16 17 u32 throd_val; 17 18 u32 scan_line_max;
+14 -1
drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
··· 61 61 62 62 struct aspeed_gfx_config { 63 63 u32 dac_reg; /* DAC register in SCU */ 64 + u32 int_clear_reg; /* Interrupt clear register */ 64 65 u32 vga_scratch_reg; /* VGA scratch register in SCU */ 65 66 u32 throd_val; /* Default Threshold Seting */ 66 67 u32 scan_line_max; /* Max memory size of one scan line */ ··· 69 68 70 69 static const struct aspeed_gfx_config ast2400_config = { 71 70 .dac_reg = 0x2c, 71 + .int_clear_reg = 0x60, 72 72 .vga_scratch_reg = 0x50, 73 73 .throd_val = CRT_THROD_LOW(0x1e) | CRT_THROD_HIGH(0x12), 74 74 .scan_line_max = 64, ··· 77 75 78 76 static const struct aspeed_gfx_config ast2500_config = { 79 77 .dac_reg = 0x2c, 78 + .int_clear_reg = 0x60, 80 79 .vga_scratch_reg = 0x50, 81 80 .throd_val = CRT_THROD_LOW(0x24) | CRT_THROD_HIGH(0x3c), 81 + .scan_line_max = 128, 82 + }; 83 + 84 + static const struct aspeed_gfx_config ast2600_config = { 85 + .dac_reg = 0xc0, 86 + .int_clear_reg = 0x68, 87 + .vga_scratch_reg = 0x50, 88 + .throd_val = CRT_THROD_LOW(0x50) | CRT_THROD_HIGH(0x70), 82 89 .scan_line_max = 128, 83 90 }; 84 91 85 92 static const struct of_device_id aspeed_gfx_match[] = { 86 93 { .compatible = "aspeed,ast2400-gfx", .data = &ast2400_config }, 87 94 { .compatible = "aspeed,ast2500-gfx", .data = &ast2500_config }, 95 + { .compatible = "aspeed,ast2600-gfx", .data = &ast2600_config }, 88 96 { }, 89 97 }; 90 98 MODULE_DEVICE_TABLE(of, aspeed_gfx_match); ··· 132 120 133 121 if (reg & CRT_CTRL_VERTICAL_INTR_STS) { 134 122 drm_crtc_handle_vblank(&priv->pipe.crtc); 135 - writel(reg, priv->base + CRT_CTRL1); 123 + writel(reg, priv->base + priv->int_clr_reg); 136 124 return IRQ_HANDLED; 137 125 } 138 126 ··· 160 148 config = match->data; 161 149 162 150 priv->dac_reg = config->dac_reg; 151 + priv->int_clr_reg = config->int_clear_reg; 163 152 priv->vga_scratch_reg = config->vga_scratch_reg; 164 153 priv->throd_val = config->throd_val; 165 154 priv->scan_line_max = config->scan_line_max;
+4 -2
drivers/gpu/drm/bridge/analogix/anx7625.c
··· 253 253 addrm = (address >> 8) & 0xFF; 254 254 addrh = (address >> 16) & 0xFF; 255 255 256 + if (!is_write) 257 + op &= ~DP_AUX_I2C_MOT; 256 258 cmd = DPCD_CMD(len, op); 257 259 258 260 /* Set command and length */ ··· 2738 2736 2739 2737 if (platform->hdcp_workqueue) { 2740 2738 cancel_delayed_work(&platform->hdcp_work); 2741 - flush_workqueue(platform->workqueue); 2742 - destroy_workqueue(platform->workqueue); 2739 + flush_workqueue(platform->hdcp_workqueue); 2740 + destroy_workqueue(platform->hdcp_workqueue); 2743 2741 } 2744 2742 2745 2743 if (!platform->pdata.low_power_mode)
+1
drivers/gpu/drm/bridge/cdns-dsi.c
··· 1284 1284 { .compatible = "cdns,dsi" }, 1285 1285 { }, 1286 1286 }; 1287 + MODULE_DEVICE_TABLE(of, cdns_dsi_of_match); 1287 1288 1288 1289 static struct platform_driver cdns_dsi_platform_driver = { 1289 1290 .probe = cdns_dsi_drm_probe,
+1 -6
drivers/gpu/drm/bridge/chipone-icn6211.c
··· 191 191 static int chipone_parse_dt(struct chipone *icn) 192 192 { 193 193 struct device *dev = icn->dev; 194 - struct drm_panel *panel; 195 194 int ret; 196 195 197 196 icn->vdd1 = devm_regulator_get_optional(dev, "vdd1"); ··· 226 227 return PTR_ERR(icn->enable_gpio); 227 228 } 228 229 229 - ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL); 230 - if (ret) 231 - return ret; 232 - 233 - icn->panel_bridge = devm_drm_panel_bridge_add(dev, panel); 230 + icn->panel_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0); 234 231 if (IS_ERR(icn->panel_bridge)) 235 232 return PTR_ERR(icn->panel_bridge); 236 233
+2 -2
drivers/gpu/drm/bridge/ite-it6505.c
··· 289 289 #define WORD_LENGTH_20BIT 2 290 290 #define WORD_LENGTH_24BIT 3 291 291 #define DEBUGFS_DIR_NAME "it6505-debugfs" 292 - #define READ_BUFFER_SIZE 200 292 + #define READ_BUFFER_SIZE 400 293 293 294 294 /* Vendor option */ 295 295 #define HDCP_DESIRED 1 ··· 3074 3074 struct it6505 *it6505 = file->private_data; 3075 3075 struct drm_display_mode *vid = &it6505->video_info; 3076 3076 u8 read_buf[READ_BUFFER_SIZE]; 3077 - u8 *str = read_buf, *end = read_buf + PAGE_SIZE; 3077 + u8 *str = read_buf, *end = read_buf + READ_BUFFER_SIZE; 3078 3078 ssize_t ret, count; 3079 3079 3080 3080 if (!it6505)
+5 -9
drivers/gpu/drm/bridge/nwl-dsi.c
··· 332 332 333 333 static int nwl_dsi_init_interrupts(struct nwl_dsi *dsi) 334 334 { 335 - u32 irq_enable; 336 - 337 - nwl_dsi_write(dsi, NWL_DSI_IRQ_MASK, 0xffffffff); 338 - nwl_dsi_write(dsi, NWL_DSI_IRQ_MASK2, 0x7); 339 - 340 - irq_enable = ~(u32)(NWL_DSI_TX_PKT_DONE_MASK | 341 - NWL_DSI_RX_PKT_HDR_RCVD_MASK | 342 - NWL_DSI_TX_FIFO_OVFLW_MASK | 343 - NWL_DSI_HS_TX_TIMEOUT_MASK); 335 + u32 irq_enable = ~(u32)(NWL_DSI_TX_PKT_DONE_MASK | 336 + NWL_DSI_RX_PKT_HDR_RCVD_MASK | 337 + NWL_DSI_TX_FIFO_OVFLW_MASK | 338 + NWL_DSI_HS_TX_TIMEOUT_MASK); 344 339 345 340 nwl_dsi_write(dsi, NWL_DSI_IRQ_MASK, irq_enable); 341 + nwl_dsi_write(dsi, NWL_DSI_IRQ_MASK2, 0x7); 346 342 347 343 return nwl_dsi_clear_error(dsi); 348 344 }
-10
drivers/gpu/drm/dp/drm_dp.c
··· 208 208 } 209 209 EXPORT_SYMBOL(drm_dp_128b132b_link_training_failed); 210 210 211 - u8 drm_dp_get_adjust_request_post_cursor(const u8 link_status[DP_LINK_STATUS_SIZE], 212 - unsigned int lane) 213 - { 214 - unsigned int offset = DP_ADJUST_REQUEST_POST_CURSOR2; 215 - u8 value = dp_link_status(link_status, offset); 216 - 217 - return (value >> (lane << 1)) & 0x3; 218 - } 219 - EXPORT_SYMBOL(drm_dp_get_adjust_request_post_cursor); 220 - 221 211 static int __8b10b_clock_recovery_delay_us(const struct drm_dp_aux *aux, u8 rd_interval) 222 212 { 223 213 if (rd_interval > 4)
+25
drivers/gpu/drm/drm_atomic_state_helper.c
··· 243 243 void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state, 244 244 struct drm_plane *plane) 245 245 { 246 + u64 val; 247 + 246 248 plane_state->plane = plane; 247 249 plane_state->rotation = DRM_MODE_ROTATE_0; 248 250 249 251 plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE; 250 252 plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI; 253 + 254 + if (plane->color_encoding_property) { 255 + if (!drm_object_property_get_default_value(&plane->base, 256 + plane->color_encoding_property, 257 + &val)) 258 + plane_state->color_encoding = val; 259 + } 260 + 261 + if (plane->color_range_property) { 262 + if (!drm_object_property_get_default_value(&plane->base, 263 + plane->color_range_property, 264 + &val)) 265 + plane_state->color_range = val; 266 + } 267 + 268 + if (plane->zpos_property) { 269 + if (!drm_object_property_get_default_value(&plane->base, 270 + plane->zpos_property, 271 + &val)) { 272 + plane_state->zpos = val; 273 + plane_state->normalized_zpos = val; 274 + } 275 + } 251 276 } 252 277 EXPORT_SYMBOL(__drm_atomic_helper_plane_state_reset); 253 278
+43 -10
drivers/gpu/drm/drm_mode_object.c
··· 297 297 } 298 298 EXPORT_SYMBOL(drm_object_property_set_value); 299 299 300 + static int __drm_object_property_get_prop_value(struct drm_mode_object *obj, 301 + struct drm_property *property, 302 + uint64_t *val) 303 + { 304 + int i; 305 + 306 + for (i = 0; i < obj->properties->count; i++) { 307 + if (obj->properties->properties[i] == property) { 308 + *val = obj->properties->values[i]; 309 + return 0; 310 + } 311 + } 312 + 313 + return -EINVAL; 314 + } 315 + 300 316 static int __drm_object_property_get_value(struct drm_mode_object *obj, 301 317 struct drm_property *property, 302 318 uint64_t *val) 303 319 { 304 - int i; 305 320 306 321 /* read-only properties bypass atomic mechanism and still store 307 322 * their value in obj->properties->values[].. mostly to avoid ··· 326 311 !(property->flags & DRM_MODE_PROP_IMMUTABLE)) 327 312 return drm_atomic_get_property(obj, property, val); 328 313 329 - for (i = 0; i < obj->properties->count; i++) { 330 - if (obj->properties->properties[i] == property) { 331 - *val = obj->properties->values[i]; 332 - return 0; 333 - } 334 - 335 - } 336 - 337 - return -EINVAL; 314 + return __drm_object_property_get_prop_value(obj, property, val); 338 315 } 339 316 340 317 /** ··· 354 347 return __drm_object_property_get_value(obj, property, val); 355 348 } 356 349 EXPORT_SYMBOL(drm_object_property_get_value); 350 + 351 + /** 352 + * drm_object_property_get_default_value - retrieve the default value of a 353 + * property when in atomic mode. 354 + * @obj: drm mode object to get property value from 355 + * @property: property to retrieve 356 + * @val: storage for the property value 357 + * 358 + * This function retrieves the default state of the given property as passed in 359 + * to drm_object_attach_property 360 + * 361 + * Only atomic drivers should call this function directly, as for non-atomic 362 + * drivers it will return the current value. 363 + * 364 + * Returns: 365 + * Zero on success, error code on failure. 366 + */ 367 + int drm_object_property_get_default_value(struct drm_mode_object *obj, 368 + struct drm_property *property, 369 + uint64_t *val) 370 + { 371 + WARN_ON(!drm_drv_uses_atomic_modeset(property->dev)); 372 + 373 + return __drm_object_property_get_prop_value(obj, property, val); 374 + } 375 + EXPORT_SYMBOL(drm_object_property_get_default_value); 357 376 358 377 /* helper for getconnector and getproperties ioctls */ 359 378 int drm_mode_object_get_properties(struct drm_mode_object *obj, bool atomic,
+50 -1
drivers/gpu/drm/drm_modes.c
··· 35 35 #include <linux/list_sort.h> 36 36 #include <linux/export.h> 37 37 38 + #include <video/of_display_timing.h> 38 39 #include <video/of_videomode.h> 39 40 #include <video/videomode.h> 40 41 ··· 128 127 * according to the hdisplay, vdisplay, vrefresh. 129 128 * It is based from the VESA(TM) Coordinated Video Timing Generator by 130 129 * Graham Loveridge April 9, 2003 available at 131 - * http://www.elo.utfsm.cl/~elo212/docs/CVTd6r1.xls 130 + * http://www.elo.utfsm.cl/~elo212/docs/CVTd6r1.xls 132 131 * 133 132 * And it is copied from xf86CVTmode in xserver/hw/xfree86/modes/xf86cvt.c. 134 133 * What I have done is to translate it by using integer calculation. ··· 728 727 return 0; 729 728 } 730 729 EXPORT_SYMBOL_GPL(of_get_drm_display_mode); 730 + 731 + /** 732 + * of_get_drm_panel_display_mode - get a panel-timing drm_display_mode from devicetree 733 + * @np: device_node with the panel-timing specification 734 + * @dmode: will be set to the return value 735 + * @bus_flags: information about pixelclk, sync and DE polarity 736 + * 737 + * The Device Tree properties width-mm and height-mm will be read and set on 738 + * the display mode if they are present. 739 + * 740 + * Returns: 741 + * Zero on success, negative error code on failure. 742 + */ 743 + int of_get_drm_panel_display_mode(struct device_node *np, 744 + struct drm_display_mode *dmode, u32 *bus_flags) 745 + { 746 + u32 width_mm = 0, height_mm = 0; 747 + struct display_timing timing; 748 + struct videomode vm; 749 + int ret; 750 + 751 + ret = of_get_display_timing(np, "panel-timing", &timing); 752 + if (ret) 753 + return ret; 754 + 755 + videomode_from_timing(&timing, &vm); 756 + 757 + memset(dmode, 0, sizeof(*dmode)); 758 + drm_display_mode_from_videomode(&vm, dmode); 759 + if (bus_flags) 760 + drm_bus_flags_from_videomode(&vm, bus_flags); 761 + 762 + ret = of_property_read_u32(np, "width-mm", &width_mm); 763 + if (ret && ret != -EINVAL) 764 + return ret; 765 + 766 + ret = of_property_read_u32(np, "height-mm", &height_mm); 767 + if (ret && ret != -EINVAL) 768 + return ret; 769 + 770 + dmode->width_mm = width_mm; 771 + dmode->height_mm = height_mm; 772 + 773 + drm_mode_debug_printmodeline(dmode); 774 + 775 + return 0; 776 + } 777 + EXPORT_SYMBOL_GPL(of_get_drm_panel_display_mode); 731 778 #endif /* CONFIG_OF */ 732 779 #endif /* CONFIG_VIDEOMODE_HELPERS */ 733 780
+17
drivers/gpu/drm/drm_of.c
··· 249 249 if (panel) 250 250 *panel = NULL; 251 251 252 + /** 253 + * Devices can also be child nodes when we also control that device 254 + * through the upstream device (ie, MIPI-DCS for a MIPI-DSI device). 255 + * 256 + * Lookup for a child node of the given parent that isn't either port 257 + * or ports. 258 + */ 259 + for_each_available_child_of_node(np, remote) { 260 + if (of_node_name_eq(remote, "port") || 261 + of_node_name_eq(remote, "ports")) 262 + continue; 263 + 264 + goto of_find_panel_or_bridge; 265 + } 266 + 252 267 /* 253 268 * of_graph_get_remote_node() produces a noisy error message if port 254 269 * node isn't found and the absence of the port is a legit case here, ··· 274 259 return -ENODEV; 275 260 276 261 remote = of_graph_get_remote_node(np, port, endpoint); 262 + 263 + of_find_panel_or_bridge: 277 264 if (!remote) 278 265 return -ENODEV; 279 266
+8 -8
drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
··· 48 48 static void mdp5_plane_install_properties(struct drm_plane *plane, 49 49 struct drm_mode_object *obj) 50 50 { 51 + unsigned int zpos; 52 + 51 53 drm_plane_create_rotation_property(plane, 52 54 DRM_MODE_ROTATE_0, 53 55 DRM_MODE_ROTATE_0 | ··· 61 59 BIT(DRM_MODE_BLEND_PIXEL_NONE) | 62 60 BIT(DRM_MODE_BLEND_PREMULTI) | 63 61 BIT(DRM_MODE_BLEND_COVERAGE)); 64 - drm_plane_create_zpos_property(plane, 1, 1, 255); 62 + 63 + if (plane->type == DRM_PLANE_TYPE_PRIMARY) 64 + zpos = STAGE_BASE; 65 + else 66 + zpos = STAGE0 + drm_plane_index(plane); 67 + drm_plane_create_zpos_property(plane, zpos, 1, 255); 65 68 } 66 69 67 70 static void ··· 98 91 99 92 kfree(to_mdp5_plane_state(plane->state)); 100 93 mdp5_state = kzalloc(sizeof(*mdp5_state), GFP_KERNEL); 101 - 102 - if (plane->type == DRM_PLANE_TYPE_PRIMARY) 103 - mdp5_state->base.zpos = STAGE_BASE; 104 - else 105 - mdp5_state->base.zpos = STAGE0 + drm_plane_index(plane); 106 - mdp5_state->base.normalized_zpos = mdp5_state->base.zpos; 107 - 108 94 __drm_atomic_helper_plane_reset(plane, &mdp5_state->base); 109 95 } 110 96
-2
drivers/gpu/drm/nouveau/dispnv50/wndw.c
··· 635 635 plane->funcs->atomic_destroy_state(plane, plane->state); 636 636 637 637 __drm_atomic_helper_plane_reset(plane, &asyw->state); 638 - plane->state->zpos = nv50_wndw_zpos_default(plane); 639 - plane->state->normalized_zpos = nv50_wndw_zpos_default(plane); 640 638 } 641 639 642 640 static void
-353
drivers/gpu/drm/nouveau/include/nvif/list.h
··· 1 - /* 2 - * Copyright © 2010 Intel Corporation 3 - * Copyright © 2010 Francisco Jerez <currojerez@riseup.net> 4 - * 5 - * Permission is hereby granted, free of charge, to any person obtaining a 6 - * copy of this software and associated documentation files (the "Software"), 7 - * to deal in the Software without restriction, including without limitation 8 - * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 - * and/or sell copies of the Software, and to permit persons to whom the 10 - * Software is furnished to do so, subject to the following conditions: 11 - * 12 - * The above copyright notice and this permission notice (including the next 13 - * paragraph) shall be included in all copies or substantial portions of the 14 - * Software. 15 - * 16 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 - * IN THE SOFTWARE. 23 - * 24 - */ 25 - 26 - /* Modified by Ben Skeggs <bskeggs@redhat.com> to match kernel list APIs */ 27 - 28 - #ifndef _XORG_LIST_H_ 29 - #define _XORG_LIST_H_ 30 - 31 - /** 32 - * @file Classic doubly-link circular list implementation. 33 - * For real usage examples of the linked list, see the file test/list.c 34 - * 35 - * Example: 36 - * We need to keep a list of struct foo in the parent struct bar, i.e. what 37 - * we want is something like this. 38 - * 39 - * struct bar { 40 - * ... 41 - * struct foo *list_of_foos; -----> struct foo {}, struct foo {}, struct foo{} 42 - * ... 43 - * } 44 - * 45 - * We need one list head in bar and a list element in all list_of_foos (both are of 46 - * data type 'struct list_head'). 47 - * 48 - * struct bar { 49 - * ... 50 - * struct list_head list_of_foos; 51 - * ... 52 - * } 53 - * 54 - * struct foo { 55 - * ... 56 - * struct list_head entry; 57 - * ... 58 - * } 59 - * 60 - * Now we initialize the list head: 61 - * 62 - * struct bar bar; 63 - * ... 64 - * INIT_LIST_HEAD(&bar.list_of_foos); 65 - * 66 - * Then we create the first element and add it to this list: 67 - * 68 - * struct foo *foo = malloc(...); 69 - * .... 70 - * list_add(&foo->entry, &bar.list_of_foos); 71 - * 72 - * Repeat the above for each element you want to add to the list. Deleting 73 - * works with the element itself. 74 - * list_del(&foo->entry); 75 - * free(foo); 76 - * 77 - * Note: calling list_del(&bar.list_of_foos) will set bar.list_of_foos to an empty 78 - * list again. 79 - * 80 - * Looping through the list requires a 'struct foo' as iterator and the 81 - * name of the field the subnodes use. 82 - * 83 - * struct foo *iterator; 84 - * list_for_each_entry(iterator, &bar.list_of_foos, entry) { 85 - * if (iterator->something == ...) 86 - * ... 87 - * } 88 - * 89 - * Note: You must not call list_del() on the iterator if you continue the 90 - * loop. You need to run the safe for-each loop instead: 91 - * 92 - * struct foo *iterator, *next; 93 - * list_for_each_entry_safe(iterator, next, &bar.list_of_foos, entry) { 94 - * if (...) 95 - * list_del(&iterator->entry); 96 - * } 97 - * 98 - */ 99 - 100 - /** 101 - * The linkage struct for list nodes. This struct must be part of your 102 - * to-be-linked struct. struct list_head is required for both the head of the 103 - * list and for each list node. 104 - * 105 - * Position and name of the struct list_head field is irrelevant. 106 - * There are no requirements that elements of a list are of the same type. 107 - * There are no requirements for a list head, any struct list_head can be a list 108 - * head. 109 - */ 110 - struct list_head { 111 - struct list_head *next, *prev; 112 - }; 113 - 114 - /** 115 - * Initialize the list as an empty list. 116 - * 117 - * Example: 118 - * INIT_LIST_HEAD(&bar->list_of_foos); 119 - * 120 - * @param The list to initialized. 121 - */ 122 - #define LIST_HEAD_INIT(name) { &(name), &(name) } 123 - 124 - #define LIST_HEAD(name) \ 125 - struct list_head name = LIST_HEAD_INIT(name) 126 - 127 - static inline void 128 - INIT_LIST_HEAD(struct list_head *list) 129 - { 130 - list->next = list->prev = list; 131 - } 132 - 133 - static inline void 134 - __list_add(struct list_head *entry, 135 - struct list_head *prev, struct list_head *next) 136 - { 137 - next->prev = entry; 138 - entry->next = next; 139 - entry->prev = prev; 140 - prev->next = entry; 141 - } 142 - 143 - /** 144 - * Insert a new element after the given list head. The new element does not 145 - * need to be initialised as empty list. 146 - * The list changes from: 147 - * head → some element → ... 148 - * to 149 - * head → new element → older element → ... 150 - * 151 - * Example: 152 - * struct foo *newfoo = malloc(...); 153 - * list_add(&newfoo->entry, &bar->list_of_foos); 154 - * 155 - * @param entry The new element to prepend to the list. 156 - * @param head The existing list. 157 - */ 158 - static inline void 159 - list_add(struct list_head *entry, struct list_head *head) 160 - { 161 - __list_add(entry, head, head->next); 162 - } 163 - 164 - /** 165 - * Append a new element to the end of the list given with this list head. 166 - * 167 - * The list changes from: 168 - * head → some element → ... → lastelement 169 - * to 170 - * head → some element → ... → lastelement → new element 171 - * 172 - * Example: 173 - * struct foo *newfoo = malloc(...); 174 - * list_add_tail(&newfoo->entry, &bar->list_of_foos); 175 - * 176 - * @param entry The new element to prepend to the list. 177 - * @param head The existing list. 178 - */ 179 - static inline void 180 - list_add_tail(struct list_head *entry, struct list_head *head) 181 - { 182 - __list_add(entry, head->prev, head); 183 - } 184 - 185 - static inline void 186 - __list_del(struct list_head *prev, struct list_head *next) 187 - { 188 - next->prev = prev; 189 - prev->next = next; 190 - } 191 - 192 - /** 193 - * Remove the element from the list it is in. Using this function will reset 194 - * the pointers to/from this element so it is removed from the list. It does 195 - * NOT free the element itself or manipulate it otherwise. 196 - * 197 - * Using list_del on a pure list head (like in the example at the top of 198 - * this file) will NOT remove the first element from 199 - * the list but rather reset the list as empty list. 200 - * 201 - * Example: 202 - * list_del(&foo->entry); 203 - * 204 - * @param entry The element to remove. 205 - */ 206 - static inline void 207 - list_del(struct list_head *entry) 208 - { 209 - __list_del(entry->prev, entry->next); 210 - } 211 - 212 - static inline void 213 - list_del_init(struct list_head *entry) 214 - { 215 - __list_del(entry->prev, entry->next); 216 - INIT_LIST_HEAD(entry); 217 - } 218 - 219 - static inline void list_move_tail(struct list_head *list, 220 - struct list_head *head) 221 - { 222 - __list_del(list->prev, list->next); 223 - list_add_tail(list, head); 224 - } 225 - 226 - /** 227 - * Check if the list is empty. 228 - * 229 - * Example: 230 - * list_empty(&bar->list_of_foos); 231 - * 232 - * @return True if the list contains one or more elements or False otherwise. 233 - */ 234 - static inline bool 235 - list_empty(struct list_head *head) 236 - { 237 - return head->next == head; 238 - } 239 - 240 - /** 241 - * Returns a pointer to the container of this list element. 242 - * 243 - * Example: 244 - * struct foo* f; 245 - * f = container_of(&foo->entry, struct foo, entry); 246 - * assert(f == foo); 247 - * 248 - * @param ptr Pointer to the struct list_head. 249 - * @param type Data type of the list element. 250 - * @param member Member name of the struct list_head field in the list element. 251 - * @return A pointer to the data struct containing the list head. 252 - */ 253 - #ifndef container_of 254 - #define container_of(ptr, type, member) \ 255 - (type *)((char *)(ptr) - (char *) &((type *)0)->member) 256 - #endif 257 - 258 - /** 259 - * Alias of container_of 260 - */ 261 - #define list_entry(ptr, type, member) \ 262 - container_of(ptr, type, member) 263 - 264 - /** 265 - * Retrieve the first list entry for the given list pointer. 266 - * 267 - * Example: 268 - * struct foo *first; 269 - * first = list_first_entry(&bar->list_of_foos, struct foo, list_of_foos); 270 - * 271 - * @param ptr The list head 272 - * @param type Data type of the list element to retrieve 273 - * @param member Member name of the struct list_head field in the list element. 274 - * @return A pointer to the first list element. 275 - */ 276 - #define list_first_entry(ptr, type, member) \ 277 - list_entry((ptr)->next, type, member) 278 - 279 - /** 280 - * Retrieve the last list entry for the given listpointer. 281 - * 282 - * Example: 283 - * struct foo *first; 284 - * first = list_last_entry(&bar->list_of_foos, struct foo, list_of_foos); 285 - * 286 - * @param ptr The list head 287 - * @param type Data type of the list element to retrieve 288 - * @param member Member name of the struct list_head field in the list element. 289 - * @return A pointer to the last list element. 290 - */ 291 - #define list_last_entry(ptr, type, member) \ 292 - list_entry((ptr)->prev, type, member) 293 - 294 - #define __container_of(ptr, sample, member) \ 295 - (void *)container_of((ptr), typeof(*(sample)), member) 296 - 297 - /** 298 - * Loop through the list given by head and set pos to struct in the list. 299 - * 300 - * Example: 301 - * struct foo *iterator; 302 - * list_for_each_entry(iterator, &bar->list_of_foos, entry) { 303 - * [modify iterator] 304 - * } 305 - * 306 - * This macro is not safe for node deletion. Use list_for_each_entry_safe 307 - * instead. 308 - * 309 - * @param pos Iterator variable of the type of the list elements. 310 - * @param head List head 311 - * @param member Member name of the struct list_head in the list elements. 312 - * 313 - */ 314 - #define list_for_each_entry(pos, head, member) \ 315 - for (pos = __container_of((head)->next, pos, member); \ 316 - &pos->member != (head); \ 317 - pos = __container_of(pos->member.next, pos, member)) 318 - 319 - /** 320 - * Loop through the list, keeping a backup pointer to the element. This 321 - * macro allows for the deletion of a list element while looping through the 322 - * list. 323 - * 324 - * See list_for_each_entry for more details. 325 - */ 326 - #define list_for_each_entry_safe(pos, tmp, head, member) \ 327 - for (pos = __container_of((head)->next, pos, member), \ 328 - tmp = __container_of(pos->member.next, pos, member); \ 329 - &pos->member != (head); \ 330 - pos = tmp, tmp = __container_of(pos->member.next, tmp, member)) 331 - 332 - 333 - #define list_for_each_entry_reverse(pos, head, member) \ 334 - for (pos = __container_of((head)->prev, pos, member); \ 335 - &pos->member != (head); \ 336 - pos = __container_of(pos->member.prev, pos, member)) 337 - 338 - #define list_for_each_entry_continue(pos, head, member) \ 339 - for (pos = __container_of(pos->member.next, pos, member); \ 340 - &pos->member != (head); \ 341 - pos = __container_of(pos->member.next, pos, member)) 342 - 343 - #define list_for_each_entry_continue_reverse(pos, head, member) \ 344 - for (pos = __container_of(pos->member.prev, pos, member); \ 345 - &pos->member != (head); \ 346 - pos = __container_of(pos->member.prev, pos, member)) 347 - 348 - #define list_for_each_entry_from(pos, head, member) \ 349 - for (; \ 350 - &pos->member != (head); \ 351 - pos = __container_of(pos->member.next, pos, member)) 352 - 353 - #endif
+11 -11
drivers/gpu/drm/omapdrm/omap_plane.c
··· 403 403 404 404 static void omap_plane_reset(struct drm_plane *plane) 405 405 { 406 - struct omap_plane *omap_plane = to_omap_plane(plane); 407 406 struct omap_plane_state *omap_state; 408 407 409 408 if (plane->state) ··· 413 414 return; 414 415 415 416 __drm_atomic_helper_plane_reset(plane, &omap_state->base); 416 - 417 - /* 418 - * Set the zpos default depending on whether we are a primary or overlay 419 - * plane. 420 - */ 421 - plane->state->zpos = plane->type == DRM_PLANE_TYPE_PRIMARY 422 - ? 0 : omap_plane->id; 423 - plane->state->color_encoding = DRM_COLOR_YCBCR_BT601; 424 - plane->state->color_range = DRM_COLOR_YCBCR_FULL_RANGE; 425 417 } 426 418 427 419 static struct drm_plane_state * ··· 523 533 unsigned int num_planes = dispc_get_num_ovls(priv->dispc); 524 534 struct drm_plane *plane; 525 535 struct omap_plane *omap_plane; 536 + unsigned int zpos; 526 537 int ret; 527 538 u32 nformats; 528 539 const u32 *formats; ··· 555 564 drm_plane_helper_add(plane, &omap_plane_helper_funcs); 556 565 557 566 omap_plane_install_properties(plane, &plane->base); 558 - drm_plane_create_zpos_property(plane, 0, 0, num_planes - 1); 567 + 568 + /* 569 + * Set the zpos default depending on whether we are a primary or overlay 570 + * plane. 571 + */ 572 + if (plane->type == DRM_PLANE_TYPE_PRIMARY) 573 + zpos = 0; 574 + else 575 + zpos = omap_plane->id; 576 + drm_plane_create_zpos_property(plane, zpos, 0, num_planes - 1); 559 577 drm_plane_create_alpha_property(plane); 560 578 drm_plane_create_blend_mode_property(plane, BIT(DRM_MODE_BLEND_PREMULTI) | 561 579 BIT(DRM_MODE_BLEND_COVERAGE));
+1
drivers/gpu/drm/panel/panel-simple.c
··· 3058 3058 3059 3059 static const struct panel_desc rocktech_rk101ii01d_ct = { 3060 3060 .modes = &rocktech_rk101ii01d_ct_mode, 3061 + .bpc = 8, 3061 3062 .num_modes = 1, 3062 3063 .size = { 3063 3064 .width = 217,
+1 -1
drivers/gpu/drm/panfrost/panfrost_drv.c
··· 562 562 563 563 pfdev->coherent = device_get_dma_attr(&pdev->dev) == DEV_DMA_COHERENT; 564 564 565 - /* Allocate and initialze the DRM device. */ 565 + /* Allocate and initialize the DRM device. */ 566 566 ddev = drm_dev_alloc(&panfrost_drm_driver, &pdev->dev); 567 567 if (IS_ERR(ddev)) 568 568 return PTR_ERR(ddev);
+1 -1
drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 1 + // SPDX-License-Identifier: GPL-2.0 2 2 /* Copyright (C) 2019 Arm Ltd. 3 3 * 4 4 * Based on msm_gem_freedreno.c:
+1 -1
drivers/gpu/drm/panfrost/panfrost_issues.h
··· 14 14 */ 15 15 enum panfrost_hw_issue { 16 16 /* Need way to guarantee that all previously-translated memory accesses 17 - * are commited */ 17 + * are committed */ 18 18 HW_ISSUE_6367, 19 19 20 20 /* On job complete with non-done the cache is not flushed */
+1 -1
drivers/gpu/drm/panfrost/panfrost_mmu.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + // SPDX-License-Identifier: GPL-2.0 2 2 /* Copyright 2019 Linaro, Ltd, Rob Herring <robh@kernel.org> */ 3 3 4 4 #include <drm/panfrost_drm.h>
+1 -1
drivers/gpu/drm/panfrost/panfrost_regs.h
··· 293 293 #define AS_FAULTADDRESS_LO(as) (MMU_AS(as) + 0x20) /* (RO) Fault Address for address space n, low word */ 294 294 #define AS_FAULTADDRESS_HI(as) (MMU_AS(as) + 0x24) /* (RO) Fault Address for address space n, high word */ 295 295 #define AS_STATUS(as) (MMU_AS(as) + 0x28) /* (RO) Status flags for address space n */ 296 - /* Additional Bifrost AS regsiters */ 296 + /* Additional Bifrost AS registers */ 297 297 #define AS_TRANSCFG_LO(as) (MMU_AS(as) + 0x30) /* (RW) Translation table configuration for address space n, low word */ 298 298 #define AS_TRANSCFG_HI(as) (MMU_AS(as) + 0x34) /* (RW) Translation table configuration for address space n, high word */ 299 299 #define AS_FAULTEXTRA_LO(as) (MMU_AS(as) + 0x38) /* (RO) Secondary fault address for address space n, low word */
-1
drivers/gpu/drm/rcar-du/rcar_du_plane.c
··· 704 704 state->hwindex = -1; 705 705 state->source = RCAR_DU_PLANE_MEMORY; 706 706 state->colorkey = RCAR_DU_COLORKEY_NONE; 707 - state->state.zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1; 708 707 } 709 708 710 709 static int rcar_du_plane_atomic_set_property(struct drm_plane *plane,
-1
drivers/gpu/drm/rcar-du/rcar_du_vsp.c
··· 353 353 return; 354 354 355 355 __drm_atomic_helper_plane_reset(plane, &state->state); 356 - state->state.zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1; 357 356 } 358 357 359 358 static const struct drm_plane_funcs rcar_du_vsp_plane_funcs = {
+1 -1
drivers/gpu/drm/solomon/ssd130x.c
··· 579 579 static int ssd130x_connector_get_modes(struct drm_connector *connector) 580 580 { 581 581 struct ssd130x_device *ssd130x = drm_to_ssd130x(connector->dev); 582 - struct drm_display_mode *mode = &ssd130x->mode; 582 + struct drm_display_mode *mode; 583 583 struct device *dev = ssd130x->dev; 584 584 585 585 mode = drm_mode_duplicate(connector->dev, &ssd130x->mode);
+1 -1
drivers/gpu/drm/sti/sti_cursor.c
··· 351 351 .update_plane = drm_atomic_helper_update_plane, 352 352 .disable_plane = drm_atomic_helper_disable_plane, 353 353 .destroy = drm_plane_cleanup, 354 - .reset = sti_plane_reset, 354 + .reset = drm_atomic_helper_plane_reset, 355 355 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 356 356 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 357 357 .late_register = sti_cursor_late_register,
+1 -1
drivers/gpu/drm/sti/sti_gdp.c
··· 905 905 .update_plane = drm_atomic_helper_update_plane, 906 906 .disable_plane = drm_atomic_helper_disable_plane, 907 907 .destroy = drm_plane_cleanup, 908 - .reset = sti_plane_reset, 908 + .reset = drm_atomic_helper_plane_reset, 909 909 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 910 910 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 911 911 .late_register = sti_gdp_late_register,
+1 -1
drivers/gpu/drm/sti/sti_hqvdp.c
··· 1283 1283 .update_plane = drm_atomic_helper_update_plane, 1284 1284 .disable_plane = drm_atomic_helper_disable_plane, 1285 1285 .destroy = drm_plane_cleanup, 1286 - .reset = sti_plane_reset, 1286 + .reset = drm_atomic_helper_plane_reset, 1287 1287 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 1288 1288 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 1289 1289 .late_register = sti_hqvdp_late_register,
-6
drivers/gpu/drm/sti/sti_plane.c
··· 112 112 return 0; 113 113 } 114 114 115 - void sti_plane_reset(struct drm_plane *plane) 116 - { 117 - drm_atomic_helper_plane_reset(plane); 118 - plane->state->zpos = sti_plane_get_default_zpos(plane->type); 119 - } 120 - 121 115 static void sti_plane_attach_zorder_property(struct drm_plane *drm_plane, 122 116 enum drm_plane_type type) 123 117 {
-1
drivers/gpu/drm/sti/sti_plane.h
··· 81 81 82 82 void sti_plane_init_property(struct sti_plane *plane, 83 83 enum drm_plane_type type); 84 - void sti_plane_reset(struct drm_plane *plane); 85 84 #endif
+103 -4
drivers/gpu/drm/stm/ltdc.c
··· 77 77 #define LTDC_CPSR 0x0044 /* Current Position Status */ 78 78 #define LTDC_CDSR 0x0048 /* Current Display Status */ 79 79 #define LTDC_EDCR 0x0060 /* External Display Control */ 80 + #define LTDC_CCRCR 0x007C /* Computed CRC value */ 80 81 #define LTDC_FUT 0x0090 /* Fifo underrun Threshold */ 81 82 82 83 /* Layer register offsets */ ··· 122 121 123 122 #define GCR_LTDCEN BIT(0) /* LTDC ENable */ 124 123 #define GCR_DEN BIT(16) /* Dither ENable */ 124 + #define GCR_CRCEN BIT(19) /* CRC ENable */ 125 125 #define GCR_PCPOL BIT(28) /* Pixel Clock POLarity-Inverted */ 126 126 #define GCR_DEPOL BIT(29) /* Data Enable POLarity-High */ 127 127 #define GCR_VSPOL BIT(30) /* Vertical Synchro POLarity-High */ ··· 228 226 #define BF2_1CA 0x005 /* 1 - Constant Alpha */ 229 227 230 228 #define NB_PF 8 /* Max nb of HW pixel format */ 229 + 230 + /* 231 + * Skip the first value and the second in case CRC was enabled during 232 + * the thread irq. This is to be sure CRC value is relevant for the 233 + * frame. 234 + */ 235 + #define CRC_SKIP_FRAMES 2 231 236 232 237 enum ltdc_pix_fmt { 233 238 PF_NONE, ··· 633 624 break; 634 625 default: 635 626 /* RGB or not a YCbCr supported format */ 636 - break; 627 + DRM_ERROR("Unsupported pixel format: %u\n", drm_pix_fmt); 628 + return; 637 629 } 638 630 639 631 /* Enable limited range */ ··· 674 664 ltdc_ycbcr2rgb_coeffs[enc][ran][1]); 675 665 } 676 666 667 + static inline void ltdc_irq_crc_handle(struct ltdc_device *ldev, 668 + struct drm_crtc *crtc) 669 + { 670 + u32 crc; 671 + int ret; 672 + 673 + if (ldev->crc_skip_count < CRC_SKIP_FRAMES) { 674 + ldev->crc_skip_count++; 675 + return; 676 + } 677 + 678 + /* Get the CRC of the frame */ 679 + ret = regmap_read(ldev->regmap, LTDC_CCRCR, &crc); 680 + if (ret) 681 + return; 682 + 683 + /* Report to DRM the CRC (hw dependent feature) */ 684 + drm_crtc_add_crc_entry(crtc, true, drm_crtc_accurate_vblank_count(crtc), &crc); 685 + } 686 + 677 687 static irqreturn_t ltdc_irq_thread(int irq, void *arg) 678 688 { 679 689 struct drm_device *ddev = arg; ··· 701 671 struct drm_crtc *crtc = drm_crtc_from_index(ddev, 0); 702 672 703 673 /* Line IRQ : trigger the vblank event */ 704 - if (ldev->irq_status & ISR_LIF) 674 + if (ldev->irq_status & ISR_LIF) { 705 675 drm_crtc_handle_vblank(crtc); 676 + 677 + /* Early return if CRC is not active */ 678 + if (ldev->crc_active) 679 + ltdc_irq_crc_handle(ldev, crtc); 680 + } 706 681 707 682 /* Save FIFO Underrun & Transfer Error status */ 708 683 mutex_lock(&ldev->err_lock); ··· 1114 1079 regmap_clear_bits(ldev->regmap, LTDC_IER, IER_LIE); 1115 1080 } 1116 1081 1082 + static int ltdc_crtc_set_crc_source(struct drm_crtc *crtc, const char *source) 1083 + { 1084 + struct ltdc_device *ldev = crtc_to_ltdc(crtc); 1085 + int ret; 1086 + 1087 + DRM_DEBUG_DRIVER("\n"); 1088 + 1089 + if (!crtc) 1090 + return -ENODEV; 1091 + 1092 + if (source && strcmp(source, "auto") == 0) { 1093 + ldev->crc_active = true; 1094 + ret = regmap_set_bits(ldev->regmap, LTDC_GCR, GCR_CRCEN); 1095 + } else if (!source) { 1096 + ldev->crc_active = false; 1097 + ret = regmap_clear_bits(ldev->regmap, LTDC_GCR, GCR_CRCEN); 1098 + } else { 1099 + ret = -EINVAL; 1100 + } 1101 + 1102 + ldev->crc_skip_count = 0; 1103 + return ret; 1104 + } 1105 + 1106 + static int ltdc_crtc_verify_crc_source(struct drm_crtc *crtc, 1107 + const char *source, size_t *values_cnt) 1108 + { 1109 + DRM_DEBUG_DRIVER("\n"); 1110 + 1111 + if (!crtc) 1112 + return -ENODEV; 1113 + 1114 + if (source && strcmp(source, "auto") != 0) { 1115 + DRM_DEBUG_DRIVER("Unknown CRC source %s for %s\n", 1116 + source, crtc->name); 1117 + return -EINVAL; 1118 + } 1119 + 1120 + *values_cnt = 1; 1121 + return 0; 1122 + } 1123 + 1117 1124 static const struct drm_crtc_funcs ltdc_crtc_funcs = { 1118 1125 .destroy = drm_crtc_cleanup, 1119 1126 .set_config = drm_atomic_helper_set_config, ··· 1166 1089 .enable_vblank = ltdc_crtc_enable_vblank, 1167 1090 .disable_vblank = ltdc_crtc_disable_vblank, 1168 1091 .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp, 1092 + }; 1093 + 1094 + static const struct drm_crtc_funcs ltdc_crtc_with_crc_support_funcs = { 1095 + .destroy = drm_crtc_cleanup, 1096 + .set_config = drm_atomic_helper_set_config, 1097 + .page_flip = drm_atomic_helper_page_flip, 1098 + .reset = drm_atomic_helper_crtc_reset, 1099 + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, 1100 + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, 1101 + .enable_vblank = ltdc_crtc_enable_vblank, 1102 + .disable_vblank = ltdc_crtc_disable_vblank, 1103 + .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp, 1104 + .set_crc_source = ltdc_crtc_set_crc_source, 1105 + .verify_crc_source = ltdc_crtc_verify_crc_source, 1169 1106 }; 1170 1107 1171 1108 /* ··· 1569 1478 1570 1479 drm_plane_create_zpos_immutable_property(primary, 0); 1571 1480 1572 - ret = drm_crtc_init_with_planes(ddev, crtc, primary, NULL, 1573 - &ltdc_crtc_funcs, NULL); 1481 + /* Init CRTC according to its hardware features */ 1482 + if (ldev->caps.crc) 1483 + ret = drm_crtc_init_with_planes(ddev, crtc, primary, NULL, 1484 + &ltdc_crtc_with_crc_support_funcs, NULL); 1485 + else 1486 + ret = drm_crtc_init_with_planes(ddev, crtc, primary, NULL, 1487 + &ltdc_crtc_funcs, NULL); 1574 1488 if (ret) { 1575 1489 DRM_ERROR("Can not initialize CRTC\n"); 1576 1490 goto cleanup; ··· 1725 1629 ldev->caps.ycbcr_input = false; 1726 1630 ldev->caps.ycbcr_output = false; 1727 1631 ldev->caps.plane_reg_shadow = false; 1632 + ldev->caps.crc = false; 1728 1633 break; 1729 1634 case HWVER_20101: 1730 1635 ldev->caps.layer_ofs = LAY_OFS_0; ··· 1740 1643 ldev->caps.ycbcr_input = false; 1741 1644 ldev->caps.ycbcr_output = false; 1742 1645 ldev->caps.plane_reg_shadow = false; 1646 + ldev->caps.crc = false; 1743 1647 break; 1744 1648 case HWVER_40100: 1745 1649 ldev->caps.layer_ofs = LAY_OFS_1; ··· 1755 1657 ldev->caps.ycbcr_input = true; 1756 1658 ldev->caps.ycbcr_output = true; 1757 1659 ldev->caps.plane_reg_shadow = true; 1660 + ldev->caps.crc = true; 1758 1661 break; 1759 1662 default: 1760 1663 return -ENODEV;
+3
drivers/gpu/drm/stm/ltdc.h
··· 27 27 bool ycbcr_input; /* ycbcr input converter supported */ 28 28 bool ycbcr_output; /* ycbcr output converter supported */ 29 29 bool plane_reg_shadow; /* plane shadow registers ability */ 30 + bool crc; /* cyclic redundancy check supported */ 30 31 }; 31 32 32 33 #define LTDC_MAX_LAYER 4 ··· 47 46 u32 irq_status; 48 47 struct fps_info plane_fpsi[LTDC_MAX_LAYER]; 49 48 struct drm_atomic_state *suspend_state; 49 + int crc_skip_count; 50 + bool crc_active; 50 51 }; 51 52 52 53 int ltdc_load(struct drm_device *ddev);
+7 -9
drivers/gpu/drm/sun4i/sun4i_layer.c
··· 18 18 19 19 static void sun4i_backend_layer_reset(struct drm_plane *plane) 20 20 { 21 - struct sun4i_layer *layer = plane_to_sun4i_layer(plane); 22 21 struct sun4i_layer_state *state; 23 22 24 23 if (plane->state) { ··· 30 31 } 31 32 32 33 state = kzalloc(sizeof(*state), GFP_KERNEL); 33 - if (state) { 34 + if (state) 34 35 __drm_atomic_helper_plane_reset(plane, &state->state); 35 - plane->state->zpos = layer->id; 36 - } 37 36 } 38 37 39 38 static struct drm_plane_state * ··· 189 192 190 193 static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm, 191 194 struct sun4i_backend *backend, 192 - enum drm_plane_type type) 195 + enum drm_plane_type type, 196 + unsigned int id) 193 197 { 194 198 const uint64_t *modifiers = sun4i_layer_modifiers; 195 199 const uint32_t *formats = sun4i_layer_formats; ··· 202 204 if (!layer) 203 205 return ERR_PTR(-ENOMEM); 204 206 207 + layer->id = id; 205 208 layer->backend = backend; 206 209 207 210 if (IS_ERR_OR_NULL(backend->frontend)) { ··· 225 226 &sun4i_backend_layer_helper_funcs); 226 227 227 228 drm_plane_create_alpha_property(&layer->plane); 228 - drm_plane_create_zpos_property(&layer->plane, 0, 0, 229 - SUN4I_BACKEND_NUM_LAYERS - 1); 229 + drm_plane_create_zpos_property(&layer->plane, layer->id, 230 + 0, SUN4I_BACKEND_NUM_LAYERS - 1); 230 231 231 232 return layer; 232 233 } ··· 248 249 enum drm_plane_type type = i ? DRM_PLANE_TYPE_OVERLAY : DRM_PLANE_TYPE_PRIMARY; 249 250 struct sun4i_layer *layer; 250 251 251 - layer = sun4i_layer_init_one(drm, backend, type); 252 + layer = sun4i_layer_init_one(drm, backend, type, i); 252 253 if (IS_ERR(layer)) { 253 254 dev_err(drm->dev, "Couldn't initialize %s plane\n", 254 255 i ? "overlay" : "primary"); 255 256 return ERR_CAST(layer); 256 257 } 257 258 258 - layer->id = i; 259 259 planes[i] = &layer->plane; 260 260 } 261 261
+10 -1
drivers/gpu/drm/tegra/dp.c
··· 549 549 { 550 550 struct drm_dp_link_train_set *adjust = &link->train.adjust; 551 551 unsigned int i; 552 + u8 post_cursor; 553 + int err; 554 + 555 + err = drm_dp_dpcd_read(link->aux, DP_ADJUST_REQUEST_POST_CURSOR2, 556 + &post_cursor, sizeof(post_cursor)); 557 + if (err < 0) { 558 + DRM_ERROR("failed to read post_cursor2: %d\n", err); 559 + post_cursor = 0; 560 + } 552 561 553 562 for (i = 0; i < link->lanes; i++) { 554 563 adjust->voltage_swing[i] = ··· 569 560 DP_TRAIN_PRE_EMPHASIS_SHIFT; 570 561 571 562 adjust->post_cursor[i] = 572 - drm_dp_get_adjust_request_post_cursor(status, i); 563 + (post_cursor >> (i << 1)) & 0x3; 573 564 } 574 565 } 575 566
+15
drivers/gpu/drm/tiny/Kconfig
··· 51 51 This is a KMS driver for projectors which use the GM12U320 chipset 52 52 for video transfer over USB2/3, such as the Acer C120 mini projector. 53 53 54 + config DRM_PANEL_MIPI_DBI 55 + tristate "DRM support for MIPI DBI compatible panels" 56 + depends on DRM && SPI 57 + select DRM_KMS_HELPER 58 + select DRM_GEM_CMA_HELPER 59 + select DRM_MIPI_DBI 60 + select BACKLIGHT_CLASS_DEVICE 61 + select VIDEOMODE_HELPERS 62 + help 63 + Say Y here if you want to enable support for MIPI DBI compatible 64 + panels. The controller command setup can be provided using a 65 + firmware file. For more information see 66 + https://github.com/notro/panel-mipi-dbi/wiki. 67 + To compile this driver as a module, choose M here. 68 + 54 69 config DRM_SIMPLEDRM 55 70 tristate "Simple framebuffer driver" 56 71 depends on DRM && MMU
+1
drivers/gpu/drm/tiny/Makefile
··· 4 4 obj-$(CONFIG_DRM_BOCHS) += bochs.o 5 5 obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus.o 6 6 obj-$(CONFIG_DRM_GM12U320) += gm12u320.o 7 + obj-$(CONFIG_DRM_PANEL_MIPI_DBI) += panel-mipi-dbi.o 7 8 obj-$(CONFIG_DRM_SIMPLEDRM) += simpledrm.o 8 9 obj-$(CONFIG_TINYDRM_HX8357D) += hx8357d.o 9 10 obj-$(CONFIG_TINYDRM_ILI9163) += ili9163.o
+398
drivers/gpu/drm/tiny/panel-mipi-dbi.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * DRM driver for MIPI DBI compatible display panels 4 + * 5 + * Copyright 2022 Noralf Trønnes 6 + */ 7 + 8 + #include <linux/backlight.h> 9 + #include <linux/delay.h> 10 + #include <linux/firmware.h> 11 + #include <linux/gpio/consumer.h> 12 + #include <linux/module.h> 13 + #include <linux/property.h> 14 + #include <linux/regulator/consumer.h> 15 + #include <linux/spi/spi.h> 16 + 17 + #include <drm/drm_atomic_helper.h> 18 + #include <drm/drm_drv.h> 19 + #include <drm/drm_fb_helper.h> 20 + #include <drm/drm_gem_atomic_helper.h> 21 + #include <drm/drm_gem_cma_helper.h> 22 + #include <drm/drm_managed.h> 23 + #include <drm/drm_mipi_dbi.h> 24 + #include <drm/drm_modes.h> 25 + #include <drm/drm_modeset_helper.h> 26 + 27 + #include <video/mipi_display.h> 28 + 29 + static const u8 panel_mipi_dbi_magic[15] = { 'M', 'I', 'P', 'I', ' ', 'D', 'B', 'I', 30 + 0, 0, 0, 0, 0, 0, 0 }; 31 + 32 + /* 33 + * The display controller configuration is stored in a firmware file. 34 + * The Device Tree 'compatible' property value with a '.bin' suffix is passed 35 + * to request_firmware() to fetch this file. 36 + */ 37 + struct panel_mipi_dbi_config { 38 + /* Magic string: panel_mipi_dbi_magic */ 39 + u8 magic[15]; 40 + 41 + /* Config file format version */ 42 + u8 file_format_version; 43 + 44 + /* 45 + * MIPI commands to execute when the display pipeline is enabled. 46 + * This is used to configure the display controller. 47 + * 48 + * The commands are stored in a byte array with the format: 49 + * command, num_parameters, [ parameter, ...], command, ... 50 + * 51 + * Some commands require a pause before the next command can be received. 52 + * Inserting a delay in the command sequence is done by using the NOP command with one 53 + * parameter: delay in miliseconds (the No Operation command is part of the MIPI Display 54 + * Command Set where it has no parameters). 55 + * 56 + * Example: 57 + * command 0x11 58 + * sleep 120ms 59 + * command 0xb1 parameters 0x01, 0x2c, 0x2d 60 + * command 0x29 61 + * 62 + * Byte sequence: 63 + * 0x11 0x00 64 + * 0x00 0x01 0x78 65 + * 0xb1 0x03 0x01 0x2c 0x2d 66 + * 0x29 0x00 67 + */ 68 + u8 commands[]; 69 + }; 70 + 71 + struct panel_mipi_dbi_commands { 72 + const u8 *buf; 73 + size_t len; 74 + }; 75 + 76 + static struct panel_mipi_dbi_commands * 77 + panel_mipi_dbi_check_commands(struct device *dev, const struct firmware *fw) 78 + { 79 + const struct panel_mipi_dbi_config *config = (struct panel_mipi_dbi_config *)fw->data; 80 + struct panel_mipi_dbi_commands *commands; 81 + size_t size = fw->size, commands_len; 82 + unsigned int i = 0; 83 + 84 + if (size < sizeof(*config) + 2) { /* At least 1 command */ 85 + dev_err(dev, "config: file size=%zu is too small\n", size); 86 + return ERR_PTR(-EINVAL); 87 + } 88 + 89 + if (memcmp(config->magic, panel_mipi_dbi_magic, sizeof(config->magic))) { 90 + dev_err(dev, "config: Bad magic: %15ph\n", config->magic); 91 + return ERR_PTR(-EINVAL); 92 + } 93 + 94 + if (config->file_format_version != 1) { 95 + dev_err(dev, "config: version=%u is not supported\n", config->file_format_version); 96 + return ERR_PTR(-EINVAL); 97 + } 98 + 99 + drm_dev_dbg(dev, DRM_UT_DRIVER, "size=%zu version=%u\n", size, config->file_format_version); 100 + 101 + commands_len = size - sizeof(*config); 102 + 103 + while ((i + 1) < commands_len) { 104 + u8 command = config->commands[i++]; 105 + u8 num_parameters = config->commands[i++]; 106 + const u8 *parameters = &config->commands[i]; 107 + 108 + i += num_parameters; 109 + if (i > commands_len) { 110 + dev_err(dev, "config: command=0x%02x num_parameters=%u overflows\n", 111 + command, num_parameters); 112 + return ERR_PTR(-EINVAL); 113 + } 114 + 115 + if (command == 0x00 && num_parameters == 1) 116 + drm_dev_dbg(dev, DRM_UT_DRIVER, "sleep %ums\n", parameters[0]); 117 + else 118 + drm_dev_dbg(dev, DRM_UT_DRIVER, "command %02x %*ph\n", 119 + command, num_parameters, parameters); 120 + } 121 + 122 + if (i != commands_len) { 123 + dev_err(dev, "config: malformed command array\n"); 124 + return ERR_PTR(-EINVAL); 125 + } 126 + 127 + commands = devm_kzalloc(dev, sizeof(*commands), GFP_KERNEL); 128 + if (!commands) 129 + return ERR_PTR(-ENOMEM); 130 + 131 + commands->len = commands_len; 132 + commands->buf = devm_kmemdup(dev, config->commands, commands->len, GFP_KERNEL); 133 + if (!commands->buf) 134 + return ERR_PTR(-ENOMEM); 135 + 136 + return commands; 137 + } 138 + 139 + static struct panel_mipi_dbi_commands *panel_mipi_dbi_commands_from_fw(struct device *dev) 140 + { 141 + struct panel_mipi_dbi_commands *commands; 142 + const struct firmware *fw; 143 + const char *compatible; 144 + char fw_name[40]; 145 + int ret; 146 + 147 + ret = of_property_read_string_index(dev->of_node, "compatible", 0, &compatible); 148 + if (ret) 149 + return ERR_PTR(ret); 150 + 151 + snprintf(fw_name, sizeof(fw_name), "%s.bin", compatible); 152 + ret = request_firmware(&fw, fw_name, dev); 153 + if (ret) { 154 + dev_err(dev, "No config file found for compatible '%s' (error=%d)\n", 155 + compatible, ret); 156 + 157 + return ERR_PTR(ret); 158 + } 159 + 160 + commands = panel_mipi_dbi_check_commands(dev, fw); 161 + release_firmware(fw); 162 + 163 + return commands; 164 + } 165 + 166 + static void panel_mipi_dbi_commands_execute(struct mipi_dbi *dbi, 167 + struct panel_mipi_dbi_commands *commands) 168 + { 169 + unsigned int i = 0; 170 + 171 + if (!commands) 172 + return; 173 + 174 + while (i < commands->len) { 175 + u8 command = commands->buf[i++]; 176 + u8 num_parameters = commands->buf[i++]; 177 + const u8 *parameters = &commands->buf[i]; 178 + 179 + if (command == 0x00 && num_parameters == 1) 180 + msleep(parameters[0]); 181 + else if (num_parameters) 182 + mipi_dbi_command_stackbuf(dbi, command, parameters, num_parameters); 183 + else 184 + mipi_dbi_command(dbi, command); 185 + 186 + i += num_parameters; 187 + } 188 + } 189 + 190 + static void panel_mipi_dbi_enable(struct drm_simple_display_pipe *pipe, 191 + struct drm_crtc_state *crtc_state, 192 + struct drm_plane_state *plane_state) 193 + { 194 + struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev); 195 + struct mipi_dbi *dbi = &dbidev->dbi; 196 + int ret, idx; 197 + 198 + if (!drm_dev_enter(pipe->crtc.dev, &idx)) 199 + return; 200 + 201 + drm_dbg(pipe->crtc.dev, "\n"); 202 + 203 + ret = mipi_dbi_poweron_conditional_reset(dbidev); 204 + if (ret < 0) 205 + goto out_exit; 206 + if (!ret) 207 + panel_mipi_dbi_commands_execute(dbi, dbidev->driver_private); 208 + 209 + mipi_dbi_enable_flush(dbidev, crtc_state, plane_state); 210 + out_exit: 211 + drm_dev_exit(idx); 212 + } 213 + 214 + static const struct drm_simple_display_pipe_funcs panel_mipi_dbi_pipe_funcs = { 215 + .enable = panel_mipi_dbi_enable, 216 + .disable = mipi_dbi_pipe_disable, 217 + .update = mipi_dbi_pipe_update, 218 + }; 219 + 220 + DEFINE_DRM_GEM_CMA_FOPS(panel_mipi_dbi_fops); 221 + 222 + static const struct drm_driver panel_mipi_dbi_driver = { 223 + .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, 224 + .fops = &panel_mipi_dbi_fops, 225 + DRM_GEM_CMA_DRIVER_OPS_VMAP, 226 + .debugfs_init = mipi_dbi_debugfs_init, 227 + .name = "panel-mipi-dbi", 228 + .desc = "MIPI DBI compatible display panel", 229 + .date = "20220103", 230 + .major = 1, 231 + .minor = 0, 232 + }; 233 + 234 + static int panel_mipi_dbi_get_mode(struct mipi_dbi_dev *dbidev, struct drm_display_mode *mode) 235 + { 236 + struct device *dev = dbidev->drm.dev; 237 + u16 hback_porch, vback_porch; 238 + int ret; 239 + 240 + ret = of_get_drm_panel_display_mode(dev->of_node, mode, NULL); 241 + if (ret) { 242 + dev_err(dev, "%pOF: failed to get panel-timing (error=%d)\n", dev->of_node, ret); 243 + return ret; 244 + } 245 + 246 + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 247 + 248 + hback_porch = mode->htotal - mode->hsync_end; 249 + vback_porch = mode->vtotal - mode->vsync_end; 250 + 251 + /* 252 + * Make sure width and height are set and that only back porch and 253 + * pixelclock are set in the other timing values. Also check that 254 + * width and height don't exceed the 16-bit value specified by MIPI DCS. 255 + */ 256 + if (!mode->hdisplay || !mode->vdisplay || mode->flags || 257 + mode->hsync_end > mode->hdisplay || (hback_porch + mode->hdisplay) > 0xffff || 258 + mode->vsync_end > mode->vdisplay || (vback_porch + mode->vdisplay) > 0xffff) { 259 + dev_err(dev, "%pOF: panel-timing out of bounds\n", dev->of_node); 260 + return -EINVAL; 261 + } 262 + 263 + /* The driver doesn't use the pixel clock but it is mandatory so fake one if not set */ 264 + if (!mode->clock) 265 + mode->clock = mode->htotal * mode->vtotal * 60 / 1000; 266 + 267 + dbidev->top_offset = vback_porch; 268 + dbidev->left_offset = hback_porch; 269 + 270 + return 0; 271 + } 272 + 273 + static int panel_mipi_dbi_spi_probe(struct spi_device *spi) 274 + { 275 + struct device *dev = &spi->dev; 276 + struct drm_display_mode mode; 277 + struct mipi_dbi_dev *dbidev; 278 + struct drm_device *drm; 279 + struct mipi_dbi *dbi; 280 + struct gpio_desc *dc; 281 + int ret; 282 + 283 + dbidev = devm_drm_dev_alloc(dev, &panel_mipi_dbi_driver, struct mipi_dbi_dev, drm); 284 + if (IS_ERR(dbidev)) 285 + return PTR_ERR(dbidev); 286 + 287 + dbi = &dbidev->dbi; 288 + drm = &dbidev->drm; 289 + 290 + ret = panel_mipi_dbi_get_mode(dbidev, &mode); 291 + if (ret) 292 + return ret; 293 + 294 + dbidev->regulator = devm_regulator_get(dev, "power"); 295 + if (IS_ERR(dbidev->regulator)) 296 + return dev_err_probe(dev, PTR_ERR(dbidev->regulator), 297 + "Failed to get regulator 'power'\n"); 298 + 299 + dbidev->backlight = devm_of_find_backlight(dev); 300 + if (IS_ERR(dbidev->backlight)) 301 + return dev_err_probe(dev, PTR_ERR(dbidev->backlight), "Failed to get backlight\n"); 302 + 303 + dbi->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); 304 + if (IS_ERR(dbi->reset)) 305 + return dev_err_probe(dev, PTR_ERR(dbi->reset), "Failed to get GPIO 'reset'\n"); 306 + 307 + dc = devm_gpiod_get_optional(dev, "dc", GPIOD_OUT_LOW); 308 + if (IS_ERR(dc)) 309 + return dev_err_probe(dev, PTR_ERR(dc), "Failed to get GPIO 'dc'\n"); 310 + 311 + ret = mipi_dbi_spi_init(spi, dbi, dc); 312 + if (ret) 313 + return ret; 314 + 315 + if (device_property_present(dev, "write-only")) 316 + dbi->read_commands = NULL; 317 + 318 + dbidev->driver_private = panel_mipi_dbi_commands_from_fw(dev); 319 + if (IS_ERR(dbidev->driver_private)) 320 + return PTR_ERR(dbidev->driver_private); 321 + 322 + ret = mipi_dbi_dev_init(dbidev, &panel_mipi_dbi_pipe_funcs, &mode, 0); 323 + if (ret) 324 + return ret; 325 + 326 + drm_mode_config_reset(drm); 327 + 328 + ret = drm_dev_register(drm, 0); 329 + if (ret) 330 + return ret; 331 + 332 + spi_set_drvdata(spi, drm); 333 + 334 + drm_fbdev_generic_setup(drm, 0); 335 + 336 + return 0; 337 + } 338 + 339 + static int panel_mipi_dbi_spi_remove(struct spi_device *spi) 340 + { 341 + struct drm_device *drm = spi_get_drvdata(spi); 342 + 343 + drm_dev_unplug(drm); 344 + drm_atomic_helper_shutdown(drm); 345 + 346 + return 0; 347 + } 348 + 349 + static void panel_mipi_dbi_spi_shutdown(struct spi_device *spi) 350 + { 351 + drm_atomic_helper_shutdown(spi_get_drvdata(spi)); 352 + } 353 + 354 + static int __maybe_unused panel_mipi_dbi_pm_suspend(struct device *dev) 355 + { 356 + return drm_mode_config_helper_suspend(dev_get_drvdata(dev)); 357 + } 358 + 359 + static int __maybe_unused panel_mipi_dbi_pm_resume(struct device *dev) 360 + { 361 + drm_mode_config_helper_resume(dev_get_drvdata(dev)); 362 + 363 + return 0; 364 + } 365 + 366 + static const struct dev_pm_ops panel_mipi_dbi_pm_ops = { 367 + SET_SYSTEM_SLEEP_PM_OPS(panel_mipi_dbi_pm_suspend, panel_mipi_dbi_pm_resume) 368 + }; 369 + 370 + static const struct of_device_id panel_mipi_dbi_spi_of_match[] = { 371 + { .compatible = "panel-mipi-dbi-spi" }, 372 + {}, 373 + }; 374 + MODULE_DEVICE_TABLE(of, panel_mipi_dbi_spi_of_match); 375 + 376 + static const struct spi_device_id panel_mipi_dbi_spi_id[] = { 377 + { "panel-mipi-dbi-spi", 0 }, 378 + { }, 379 + }; 380 + MODULE_DEVICE_TABLE(spi, panel_mipi_dbi_spi_id); 381 + 382 + static struct spi_driver panel_mipi_dbi_spi_driver = { 383 + .driver = { 384 + .name = "panel-mipi-dbi-spi", 385 + .owner = THIS_MODULE, 386 + .of_match_table = panel_mipi_dbi_spi_of_match, 387 + .pm = &panel_mipi_dbi_pm_ops, 388 + }, 389 + .id_table = panel_mipi_dbi_spi_id, 390 + .probe = panel_mipi_dbi_spi_probe, 391 + .remove = panel_mipi_dbi_spi_remove, 392 + .shutdown = panel_mipi_dbi_spi_shutdown, 393 + }; 394 + module_spi_driver(panel_mipi_dbi_spi_driver); 395 + 396 + MODULE_DESCRIPTION("MIPI DBI compatible display panel driver"); 397 + MODULE_AUTHOR("Noralf Trønnes"); 398 + MODULE_LICENSE("GPL");
+1 -23
drivers/gpu/drm/tiny/repaper.c
··· 508 508 epd->factored_stage_time = epd->stage_time * factor10x / 10; 509 509 } 510 510 511 - static void repaper_gray8_to_mono_reversed(u8 *buf, u32 width, u32 height) 512 - { 513 - u8 *gray8 = buf, *mono = buf; 514 - int y, xb, i; 515 - 516 - for (y = 0; y < height; y++) 517 - for (xb = 0; xb < width / 8; xb++) { 518 - u8 byte = 0x00; 519 - 520 - for (i = 0; i < 8; i++) { 521 - int x = xb * 8 + i; 522 - 523 - byte >>= 1; 524 - if (gray8[y * width + x] >> 7) 525 - byte |= BIT(7); 526 - } 527 - *mono++ = byte; 528 - } 529 - } 530 - 531 511 static int repaper_fb_dirty(struct drm_framebuffer *fb) 532 512 { 533 513 struct drm_gem_cma_object *cma_obj = drm_fb_cma_get_gem_obj(fb, 0); ··· 540 560 if (ret) 541 561 goto out_free; 542 562 543 - drm_fb_xrgb8888_to_gray8(buf, 0, cma_obj->vaddr, fb, &clip); 563 + drm_fb_xrgb8888_to_mono_reversed(buf, 0, cma_obj->vaddr, fb, &clip); 544 564 545 565 drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE); 546 - 547 - repaper_gray8_to_mono_reversed(buf, fb->width, fb->height); 548 566 549 567 if (epd->partial) { 550 568 repaper_frame_data_repeat(epd, buf, epd->current_frame,
+3
drivers/gpu/drm/tiny/simpledrm.c
··· 810 810 if (ret) 811 811 return ret; 812 812 drm_connector_helper_add(connector, &simpledrm_connector_helper_funcs); 813 + drm_connector_set_panel_orientation_with_quirk(connector, 814 + DRM_MODE_PANEL_ORIENTATION_UNKNOWN, 815 + mode->hdisplay, mode->vdisplay); 813 816 814 817 formats = simpledrm_device_formats(sdev, &nformats); 815 818
+13 -27
drivers/gpu/drm/v3d/v3d_sched.c
··· 392 392 hw_jobs_limit, job_hang_limit, 393 393 msecs_to_jiffies(hang_limit_ms), NULL, 394 394 NULL, "v3d_bin", v3d->drm.dev); 395 - if (ret) { 396 - dev_err(v3d->drm.dev, "Failed to create bin scheduler: %d.", ret); 395 + if (ret) 397 396 return ret; 398 - } 399 397 400 398 ret = drm_sched_init(&v3d->queue[V3D_RENDER].sched, 401 399 &v3d_render_sched_ops, 402 400 hw_jobs_limit, job_hang_limit, 403 401 msecs_to_jiffies(hang_limit_ms), NULL, 404 402 NULL, "v3d_render", v3d->drm.dev); 405 - if (ret) { 406 - dev_err(v3d->drm.dev, "Failed to create render scheduler: %d.", 407 - ret); 408 - v3d_sched_fini(v3d); 409 - return ret; 410 - } 403 + if (ret) 404 + goto fail; 411 405 412 406 ret = drm_sched_init(&v3d->queue[V3D_TFU].sched, 413 407 &v3d_tfu_sched_ops, 414 408 hw_jobs_limit, job_hang_limit, 415 409 msecs_to_jiffies(hang_limit_ms), NULL, 416 410 NULL, "v3d_tfu", v3d->drm.dev); 417 - if (ret) { 418 - dev_err(v3d->drm.dev, "Failed to create TFU scheduler: %d.", 419 - ret); 420 - v3d_sched_fini(v3d); 421 - return ret; 422 - } 411 + if (ret) 412 + goto fail; 423 413 424 414 if (v3d_has_csd(v3d)) { 425 415 ret = drm_sched_init(&v3d->queue[V3D_CSD].sched, ··· 417 427 hw_jobs_limit, job_hang_limit, 418 428 msecs_to_jiffies(hang_limit_ms), NULL, 419 429 NULL, "v3d_csd", v3d->drm.dev); 420 - if (ret) { 421 - dev_err(v3d->drm.dev, "Failed to create CSD scheduler: %d.", 422 - ret); 423 - v3d_sched_fini(v3d); 424 - return ret; 425 - } 430 + if (ret) 431 + goto fail; 426 432 427 433 ret = drm_sched_init(&v3d->queue[V3D_CACHE_CLEAN].sched, 428 434 &v3d_cache_clean_sched_ops, 429 435 hw_jobs_limit, job_hang_limit, 430 436 msecs_to_jiffies(hang_limit_ms), NULL, 431 437 NULL, "v3d_cache_clean", v3d->drm.dev); 432 - if (ret) { 433 - dev_err(v3d->drm.dev, "Failed to create CACHE_CLEAN scheduler: %d.", 434 - ret); 435 - v3d_sched_fini(v3d); 436 - return ret; 437 - } 438 + if (ret) 439 + goto fail; 438 440 } 439 441 440 442 return 0; 443 + 444 + fail: 445 + v3d_sched_fini(v3d); 446 + return ret; 441 447 } 442 448 443 449 void
+70 -37
drivers/video/fbdev/core/cfbimgblt.c
··· 16 16 * must be laid out exactly in the same format as the framebuffer. Yes I know 17 17 * their are cards with hardware that coverts images of various depths to the 18 18 * framebuffer depth. But not every card has this. All images must be rounded 19 - * up to the nearest byte. For example a bitmap 12 bits wide must be two 20 - * bytes width. 19 + * up to the nearest byte. For example a bitmap 12 bits wide must be two 20 + * bytes width. 21 21 * 22 - * Tony: 23 - * Incorporate mask tables similar to fbcon-cfb*.c in 2.4 API. This speeds 22 + * Tony: 23 + * Incorporate mask tables similar to fbcon-cfb*.c in 2.4 API. This speeds 24 24 * up the code significantly. 25 - * 25 + * 26 26 * Code for depths not multiples of BITS_PER_LONG is still kludgy, which is 27 - * still processed a bit at a time. 27 + * still processed a bit at a time. 28 28 * 29 29 * Also need to add code to deal with cards endians that are different than 30 30 * the native cpu endians. I also need to deal with MSB position in the word. ··· 72 72 #define FB_WRITEL fb_writel 73 73 #define FB_READL fb_readl 74 74 75 - static inline void color_imageblit(const struct fb_image *image, 76 - struct fb_info *p, u8 __iomem *dst1, 75 + static inline void color_imageblit(const struct fb_image *image, 76 + struct fb_info *p, u8 __iomem *dst1, 77 77 u32 start_index, 78 78 u32 pitch_index) 79 79 { ··· 92 92 dst = (u32 __iomem *) dst1; 93 93 shift = 0; 94 94 val = 0; 95 - 95 + 96 96 if (start_index) { 97 97 u32 start_mask = ~fb_shifted_pixels_mask_u32(p, 98 98 start_index, bswapmask); ··· 109 109 val |= FB_SHIFT_HIGH(p, color, shift ^ bswapmask); 110 110 if (shift >= null_bits) { 111 111 FB_WRITEL(val, dst++); 112 - 113 - val = (shift == null_bits) ? 0 : 112 + 113 + val = (shift == null_bits) ? 0 : 114 114 FB_SHIFT_LOW(p, color, 32 - shift); 115 115 } 116 116 shift += bpp; ··· 134 134 } 135 135 } 136 136 137 - static inline void slow_imageblit(const struct fb_image *image, struct fb_info *p, 137 + static inline void slow_imageblit(const struct fb_image *image, struct fb_info *p, 138 138 u8 __iomem *dst1, u32 fgcolor, 139 - u32 bgcolor, 139 + u32 bgcolor, 140 140 u32 start_index, 141 141 u32 pitch_index) 142 142 { ··· 172 172 l--; 173 173 color = (*s & (1 << l)) ? fgcolor : bgcolor; 174 174 val |= FB_SHIFT_HIGH(p, color, shift ^ bswapmask); 175 - 175 + 176 176 /* Did the bitshift spill bits to the next long? */ 177 177 if (shift >= null_bits) { 178 178 FB_WRITEL(val, dst++); ··· 191 191 192 192 FB_WRITEL((FB_READL(dst) & end_mask) | val, dst); 193 193 } 194 - 194 + 195 195 dst1 += pitch; 196 - src += spitch; 196 + src += spitch; 197 197 if (pitch_index) { 198 198 dst2 += pitch; 199 199 dst1 = (u8 __iomem *)((long __force)dst2 & ~(sizeof(u32) - 1)); 200 200 start_index += pitch_index; 201 201 start_index &= 32 - 1; 202 202 } 203 - 203 + 204 204 } 205 205 } 206 206 ··· 212 212 * fix->line_legth is divisible by 4; 213 213 * beginning and end of a scanline is dword aligned 214 214 */ 215 - static inline void fast_imageblit(const struct fb_image *image, struct fb_info *p, 216 - u8 __iomem *dst1, u32 fgcolor, 217 - u32 bgcolor) 215 + static inline void fast_imageblit(const struct fb_image *image, struct fb_info *p, 216 + u8 __iomem *dst1, u32 fgcolor, 217 + u32 bgcolor) 218 218 { 219 219 u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel; 220 220 u32 ppw = 32/bpp, spitch = (image->width + 7)/8; 221 - u32 bit_mask, end_mask, eorx, shift; 221 + u32 bit_mask, eorx; 222 222 const char *s = image->data, *src; 223 223 u32 __iomem *dst; 224 224 const u32 *tab = NULL; 225 + size_t tablen; 226 + u32 colortab[16]; 225 227 int i, j, k; 226 228 227 229 switch (bpp) { 228 230 case 8: 229 231 tab = fb_be_math(p) ? cfb_tab8_be : cfb_tab8_le; 232 + tablen = 16; 230 233 break; 231 234 case 16: 232 235 tab = fb_be_math(p) ? cfb_tab16_be : cfb_tab16_le; 236 + tablen = 4; 233 237 break; 234 238 case 32: 235 - default: 236 239 tab = cfb_tab32; 240 + tablen = 2; 237 241 break; 242 + default: 243 + return; 238 244 } 239 245 240 246 for (i = ppw-1; i--; ) { ··· 249 243 fgx |= fgcolor; 250 244 bgx |= bgcolor; 251 245 } 252 - 246 + 253 247 bit_mask = (1 << ppw) - 1; 254 248 eorx = fgx ^ bgx; 255 249 k = image->width/ppw; 256 250 251 + for (i = 0; i < tablen; ++i) 252 + colortab[i] = (tab[i] & eorx) ^ bgx; 253 + 257 254 for (i = image->height; i--; ) { 258 - dst = (u32 __iomem *) dst1, shift = 8; src = s; 259 - 260 - for (j = k; j--; ) { 261 - shift -= ppw; 262 - end_mask = tab[(*src >> shift) & bit_mask]; 263 - FB_WRITEL((end_mask & eorx)^bgx, dst++); 264 - if (!shift) { shift = 8; src++; } 255 + dst = (u32 __iomem *)dst1; 256 + src = s; 257 + 258 + switch (ppw) { 259 + case 4: /* 8 bpp */ 260 + for (j = k; j; j -= 2, ++src) { 261 + FB_WRITEL(colortab[(*src >> 4) & bit_mask], dst++); 262 + FB_WRITEL(colortab[(*src >> 0) & bit_mask], dst++); 263 + } 264 + break; 265 + case 2: /* 16 bpp */ 266 + for (j = k; j; j -= 4, ++src) { 267 + FB_WRITEL(colortab[(*src >> 6) & bit_mask], dst++); 268 + FB_WRITEL(colortab[(*src >> 4) & bit_mask], dst++); 269 + FB_WRITEL(colortab[(*src >> 2) & bit_mask], dst++); 270 + FB_WRITEL(colortab[(*src >> 0) & bit_mask], dst++); 271 + } 272 + break; 273 + case 1: /* 32 bpp */ 274 + for (j = k; j; j -= 8, ++src) { 275 + FB_WRITEL(colortab[(*src >> 7) & bit_mask], dst++); 276 + FB_WRITEL(colortab[(*src >> 6) & bit_mask], dst++); 277 + FB_WRITEL(colortab[(*src >> 5) & bit_mask], dst++); 278 + FB_WRITEL(colortab[(*src >> 4) & bit_mask], dst++); 279 + FB_WRITEL(colortab[(*src >> 3) & bit_mask], dst++); 280 + FB_WRITEL(colortab[(*src >> 2) & bit_mask], dst++); 281 + FB_WRITEL(colortab[(*src >> 1) & bit_mask], dst++); 282 + FB_WRITEL(colortab[(*src >> 0) & bit_mask], dst++); 283 + } 284 + break; 265 285 } 286 + 266 287 dst1 += p->fix.line_length; 267 288 s += spitch; 268 289 } 269 - } 270 - 290 + } 291 + 271 292 void cfb_imageblit(struct fb_info *p, const struct fb_image *image) 272 293 { 273 294 u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0; ··· 325 292 } else { 326 293 fgcolor = image->fg_color; 327 294 bgcolor = image->bg_color; 328 - } 329 - 330 - if (32 % bpp == 0 && !start_index && !pitch_index && 295 + } 296 + 297 + if (32 % bpp == 0 && !start_index && !pitch_index && 331 298 ((width & (32/bpp-1)) == 0) && 332 - bpp >= 8 && bpp <= 32) 299 + bpp >= 8 && bpp <= 32) 333 300 fast_imageblit(image, p, dst1, fgcolor, bgcolor); 334 - else 301 + else 335 302 slow_imageblit(image, p, dst1, fgcolor, bgcolor, 336 303 start_index, pitch_index); 337 304 } else
+3 -13
drivers/video/fbdev/core/sysfillrect.c
··· 50 50 51 51 /* Main chunk */ 52 52 n /= bits; 53 - while (n >= 8) { 54 - *dst++ = pat; 55 - *dst++ = pat; 56 - *dst++ = pat; 57 - *dst++ = pat; 58 - *dst++ = pat; 59 - *dst++ = pat; 60 - *dst++ = pat; 61 - *dst++ = pat; 62 - n -= 8; 63 - } 64 - while (n--) 65 - *dst++ = pat; 53 + memset_l(dst, pat, n); 54 + dst += n; 55 + 66 56 /* Trailing bits */ 67 57 if (last) 68 58 *dst = comp(pat, *dst, last);
+38 -11
drivers/video/fbdev/core/sysimgblt.c
··· 188 188 { 189 189 u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel; 190 190 u32 ppw = 32/bpp, spitch = (image->width + 7)/8; 191 - u32 bit_mask, end_mask, eorx, shift; 191 + u32 bit_mask, eorx; 192 192 const char *s = image->data, *src; 193 193 u32 *dst; 194 - const u32 *tab = NULL; 194 + const u32 *tab; 195 + size_t tablen; 196 + u32 colortab[16]; 195 197 int i, j, k; 196 198 197 199 switch (bpp) { 198 200 case 8: 199 201 tab = fb_be_math(p) ? cfb_tab8_be : cfb_tab8_le; 202 + tablen = 16; 200 203 break; 201 204 case 16: 202 205 tab = fb_be_math(p) ? cfb_tab16_be : cfb_tab16_le; 206 + tablen = 4; 203 207 break; 204 208 case 32: 205 - default: 206 209 tab = cfb_tab32; 210 + tablen = 2; 207 211 break; 212 + default: 213 + return; 208 214 } 209 215 210 216 for (i = ppw-1; i--; ) { ··· 224 218 eorx = fgx ^ bgx; 225 219 k = image->width/ppw; 226 220 221 + for (i = 0; i < tablen; ++i) 222 + colortab[i] = (tab[i] & eorx) ^ bgx; 223 + 227 224 for (i = image->height; i--; ) { 228 225 dst = dst1; 229 - shift = 8; 230 226 src = s; 231 227 232 - for (j = k; j--; ) { 233 - shift -= ppw; 234 - end_mask = tab[(*src >> shift) & bit_mask]; 235 - *dst++ = (end_mask & eorx) ^ bgx; 236 - if (!shift) { 237 - shift = 8; 238 - src++; 228 + switch (ppw) { 229 + case 4: /* 8 bpp */ 230 + for (j = k; j; j -= 2, ++src) { 231 + *dst++ = colortab[(*src >> 4) & bit_mask]; 232 + *dst++ = colortab[(*src >> 0) & bit_mask]; 239 233 } 234 + break; 235 + case 2: /* 16 bpp */ 236 + for (j = k; j; j -= 4, ++src) { 237 + *dst++ = colortab[(*src >> 6) & bit_mask]; 238 + *dst++ = colortab[(*src >> 4) & bit_mask]; 239 + *dst++ = colortab[(*src >> 2) & bit_mask]; 240 + *dst++ = colortab[(*src >> 0) & bit_mask]; 241 + } 242 + break; 243 + case 1: /* 32 bpp */ 244 + for (j = k; j; j -= 8, ++src) { 245 + *dst++ = colortab[(*src >> 7) & bit_mask]; 246 + *dst++ = colortab[(*src >> 6) & bit_mask]; 247 + *dst++ = colortab[(*src >> 5) & bit_mask]; 248 + *dst++ = colortab[(*src >> 4) & bit_mask]; 249 + *dst++ = colortab[(*src >> 3) & bit_mask]; 250 + *dst++ = colortab[(*src >> 2) & bit_mask]; 251 + *dst++ = colortab[(*src >> 1) & bit_mask]; 252 + *dst++ = colortab[(*src >> 0) & bit_mask]; 253 + } 254 + break; 240 255 } 241 256 dst1 += p->fix.line_length; 242 257 s += spitch;
+1 -3
include/drm/dp/drm_dp_helper.h
··· 456 456 #define DP_FEC_CAPABILITY_1 0x091 /* 2.0 */ 457 457 458 458 /* DP-HDMI2.1 PCON DSC ENCODER SUPPORT */ 459 - #define DP_PCON_DSC_ENCODER_CAP_SIZE 0xC /* 0x9E - 0x92 */ 459 + #define DP_PCON_DSC_ENCODER_CAP_SIZE 0xD /* 0x92 through 0x9E */ 460 460 #define DP_PCON_DSC_ENCODER 0x092 461 461 # define DP_PCON_DSC_ENCODER_SUPPORTED (1 << 0) 462 462 # define DP_PCON_DSC_PPS_ENC_OVERRIDE (1 << 1) ··· 1530 1530 int lane); 1531 1531 u8 drm_dp_get_adjust_tx_ffe_preset(const u8 link_status[DP_LINK_STATUS_SIZE], 1532 1532 int lane); 1533 - u8 drm_dp_get_adjust_request_post_cursor(const u8 link_status[DP_LINK_STATUS_SIZE], 1534 - unsigned int lane); 1535 1533 1536 1534 #define DP_BRANCH_OUI_HEADER_SIZE 0xc 1537 1535 #define DP_RECEIVER_CAP_SIZE 0xf
+8
include/drm/drm_mipi_dbi.h
··· 130 130 * @dbi: MIPI DBI interface 131 131 */ 132 132 struct mipi_dbi dbi; 133 + 134 + /** 135 + * @driver_private: Driver private data. 136 + * Necessary for drivers with private data since devm_drm_dev_alloc() 137 + * can't allocate structures that embed a structure which then again 138 + * embeds drm_device. 139 + */ 140 + void *driver_private; 133 141 }; 134 142 135 143 static inline struct mipi_dbi_dev *drm_to_mipi_dbi_dev(struct drm_device *drm)
+7
include/drm/drm_mode_object.h
··· 98 98 * Hence atomic drivers should not use drm_object_property_set_value() 99 99 * and drm_object_property_get_value() on mutable objects, i.e. those 100 100 * without the DRM_MODE_PROP_IMMUTABLE flag set. 101 + * 102 + * For atomic drivers the default value of properties is stored in this 103 + * array, so drm_object_property_get_default_value can be used to 104 + * retrieve it. 101 105 */ 102 106 uint64_t values[DRM_OBJECT_MAX_PROPERTY]; 103 107 }; ··· 130 126 int drm_object_property_get_value(struct drm_mode_object *obj, 131 127 struct drm_property *property, 132 128 uint64_t *value); 129 + int drm_object_property_get_default_value(struct drm_mode_object *obj, 130 + struct drm_property *property, 131 + uint64_t *val); 133 132 134 133 void drm_object_attach_property(struct drm_mode_object *obj, 135 134 struct drm_property *property,
+8
include/drm/drm_modes.h
··· 466 466 int of_get_drm_display_mode(struct device_node *np, 467 467 struct drm_display_mode *dmode, u32 *bus_flags, 468 468 int index); 469 + int of_get_drm_panel_display_mode(struct device_node *np, 470 + struct drm_display_mode *dmode, u32 *bus_flags); 469 471 #else 470 472 static inline int of_get_drm_display_mode(struct device_node *np, 471 473 struct drm_display_mode *dmode, 472 474 u32 *bus_flags, int index) 475 + { 476 + return -EINVAL; 477 + } 478 + 479 + static inline int of_get_drm_panel_display_mode(struct device_node *np, 480 + struct drm_display_mode *dmode, u32 *bus_flags) 473 481 { 474 482 return -EINVAL; 475 483 }