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-2020-01-07' of git://anongit.freedesktop.org/drm/drm-misc into drm-next

drm-misc-next for v5.6:

UAPI Changes:
- Allow overriding number of bootup penguins in fbcon using fbcon=logo-count:n.

Cross-subsystem Changes:
- fbdev fixes for mmp, and make it work with CONFIG_COMPILE_TEST.
- Use devm_platform_ioremap_resource in fbdev drivers.
- Various small fbdev fixes.

Core Changes:
- Support scanline alignment for dumb buffers.
- Add atomic_check() hook to bridge ops, to support bus format negotiation.
- Add gem_create_object() to vram helpers.

Driver Changes:
- Rockchip: Add support for PX30.
- Use generic fbdev code and dumb helpers in hisilicon/hibmc.
- Add support for Leadtek LTK500HD1829 panel, and xinpeng XPP055C272.
- Clock fixes for atmel-hlcdc.
- Various smaller fixes to all drivers.

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

From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/8eff1e3f-ef0a-2dd9-9a14-6273b1d6f963@linux.intel.com

+2477 -775
+49
Documentation/devicetree/bindings/display/panel/leadtek,ltk500hd1829.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/leadtek,ltk500hd1829.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Leadtek LTK500HD1829 5.0in 720x1280 DSI panel 8 + 9 + maintainers: 10 + - Heiko Stuebner <heiko.stuebner@theobroma-systems.com> 11 + 12 + allOf: 13 + - $ref: panel-common.yaml# 14 + 15 + properties: 16 + compatible: 17 + const: leadtek,ltk500hd1829 18 + reg: true 19 + backlight: true 20 + reset-gpios: true 21 + iovcc-supply: 22 + description: regulator that supplies the iovcc voltage 23 + vcc-supply: 24 + description: regulator that supplies the vcc voltage 25 + 26 + required: 27 + - compatible 28 + - reg 29 + - backlight 30 + - iovcc-supply 31 + - vcc-supply 32 + 33 + additionalProperties: false 34 + 35 + examples: 36 + - | 37 + dsi@ff450000 { 38 + #address-cells = <1>; 39 + #size-cells = <0>; 40 + panel@0 { 41 + compatible = "leadtek,ltk500hd1829"; 42 + reg = <0>; 43 + backlight = <&backlight>; 44 + iovcc-supply = <&vcc_1v8>; 45 + vcc-supply = <&vcc_2v8>; 46 + }; 47 + }; 48 + 49 + ...
+49
Documentation/devicetree/bindings/display/panel/xinpeng,xpp055c272.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/xinpeng,xpp055c272.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Xinpeng XPP055C272 5.5in 720x1280 DSI panel 8 + 9 + maintainers: 10 + - Heiko Stuebner <heiko.stuebner@theobroma-systems.com> 11 + 12 + allOf: 13 + - $ref: panel-common.yaml# 14 + 15 + properties: 16 + compatible: 17 + const: xinpeng,xpp055c272 18 + reg: true 19 + backlight: true 20 + reset-gpios: true 21 + iovcc-supply: 22 + description: regulator that supplies the iovcc voltage 23 + vci-supply: 24 + description: regulator that supplies the vci voltage 25 + 26 + required: 27 + - compatible 28 + - reg 29 + - backlight 30 + - iovcc-supply 31 + - vci-supply 32 + 33 + additionalProperties: false 34 + 35 + examples: 36 + - | 37 + dsi@ff450000 { 38 + #address-cells = <1>; 39 + #size-cells = <0>; 40 + panel@0 { 41 + compatible = "xinpeng,xpp055c272"; 42 + reg = <0>; 43 + backlight = <&backlight>; 44 + iovcc-supply = <&vcc_1v8>; 45 + vci-supply = <&vcc3v3_lcd>; 46 + }; 47 + }; 48 + 49 + ...
+4
Documentation/devicetree/bindings/display/rockchip/rockchip-lvds.txt
··· 4 4 Required properties: 5 5 - compatible: matching the soc type, one of 6 6 - "rockchip,rk3288-lvds"; 7 + - "rockchip,px30-lvds"; 7 8 8 9 - reg: physical base address of the controller and length 9 10 of memory mapped region. ··· 18 17 19 18 - rockchip,grf: phandle to the general register files syscon 20 19 - rockchip,output: "rgb", "lvds" or "duallvds", This describes the output interface 20 + 21 + - phys: LVDS/DSI DPHY (px30 only) 22 + - phy-names: name of the PHY, must be "dphy" (px30 only) 21 23 22 24 Optional properties: 23 25 - pinctrl-names: must contain a "lcdc" entry.
+4
Documentation/devicetree/bindings/vendor-prefixes.yaml
··· 513 513 description: Lantiq Semiconductor 514 514 "^lattice,.*": 515 515 description: Lattice Semiconductor 516 + "^leadtek,.*": 517 + description: Shenzhen Leadtek Technology Co., Ltd. 516 518 "^leez,.*": 517 519 description: Leez 518 520 "^lego,.*": ··· 1058 1056 description: Extreme Engineering Solutions (X-ES) 1059 1057 "^xillybus,.*": 1060 1058 description: Xillybus Ltd. 1059 + "^xinpeng,.*": 1060 + description: Shenzhen Xinpeng Technology Co., Ltd 1061 1061 "^xlnx,.*": 1062 1062 description: Xilinx 1063 1063 "^xunlong,.*":
+9 -4
Documentation/fb/fbcon.rst
··· 127 127 is typically located on the same video card. Thus, the consoles that 128 128 are controlled by the VGA console will be garbled. 129 129 130 - 4. fbcon=rotate:<n> 130 + 5. fbcon=rotate:<n> 131 131 132 132 This option changes the orientation angle of the console display. The 133 133 value 'n' accepts the following: ··· 152 152 Actually, the underlying fb driver is totally ignorant of console 153 153 rotation. 154 154 155 - 5. fbcon=margin:<color> 155 + 6. fbcon=margin:<color> 156 156 157 157 This option specifies the color of the margins. The margins are the 158 158 leftover area at the right and the bottom of the screen that are not 159 159 used by text. By default, this area will be black. The 'color' value 160 160 is an integer number that depends on the framebuffer driver being used. 161 161 162 - 6. fbcon=nodefer 162 + 7. fbcon=nodefer 163 163 164 164 If the kernel is compiled with deferred fbcon takeover support, normally 165 165 the framebuffer contents, left in place by the firmware/bootloader, will 166 166 be preserved until there actually is some text is output to the console. 167 167 This option causes fbcon to bind immediately to the fbdev device. 168 168 169 - 7. fbcon=logo-pos:<location> 169 + 8. fbcon=logo-pos:<location> 170 170 171 171 The only possible 'location' is 'center' (without quotes), and when 172 172 given, the bootup logo is moved from the default top-left corner 173 173 location to the center of the framebuffer. If more than one logo is 174 174 displayed due to multiple CPUs, the collected line of logos is moved 175 175 as a whole. 176 + 177 + 9. fbcon=logo-count:<n> 178 + 179 + The value 'n' overrides the number of bootup logos. 0 disables the 180 + logo, and -1 gives the default which is the number of online CPUs. 176 181 177 182 C. Attaching, Detaching and Unloading 178 183
+1 -2
drivers/gpu/drm/ast/ast_mode.c
··· 1144 1144 size = roundup(AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE, PAGE_SIZE); 1145 1145 1146 1146 for (i = 0; i < ARRAY_SIZE(ast->cursor.gbo); ++i) { 1147 - gbo = drm_gem_vram_create(dev, &dev->vram_mm->bdev, 1148 - size, 0, false); 1147 + gbo = drm_gem_vram_create(dev, size, 0); 1149 1148 if (IS_ERR(gbo)) { 1150 1149 ret = PTR_ERR(gbo); 1151 1150 goto err_drm_gem_vram_put;
+12 -6
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
··· 73 73 unsigned long prate; 74 74 unsigned int mask = ATMEL_HLCDC_CLKDIV_MASK | ATMEL_HLCDC_CLKPOL; 75 75 unsigned int cfg = 0; 76 - int div; 76 + int div, ret; 77 + 78 + ret = clk_prepare_enable(crtc->dc->hlcdc->sys_clk); 79 + if (ret) 80 + return; 77 81 78 82 vm.vfront_porch = adj->crtc_vsync_start - adj->crtc_vdisplay; 79 83 vm.vback_porch = adj->crtc_vtotal - adj->crtc_vsync_end; ··· 99 95 (adj->crtc_hdisplay - 1) | 100 96 ((adj->crtc_vdisplay - 1) << 16)); 101 97 98 + prate = clk_get_rate(crtc->dc->hlcdc->sys_clk); 99 + mode_rate = adj->crtc_clock * 1000; 102 100 if (!crtc->dc->desc->fixed_clksrc) { 101 + prate *= 2; 103 102 cfg |= ATMEL_HLCDC_CLKSEL; 104 103 mask |= ATMEL_HLCDC_CLKSEL; 105 104 } 106 - 107 - prate = 2 * clk_get_rate(crtc->dc->hlcdc->sys_clk); 108 - mode_rate = adj->crtc_clock * 1000; 109 105 110 106 div = DIV_ROUND_UP(prate, mode_rate); 111 107 if (div < 2) { ··· 121 117 int div_low = prate / mode_rate; 122 118 123 119 if (div_low >= 2 && 124 - ((prate / div_low - mode_rate) < 125 - 10 * (mode_rate - prate / div))) 120 + (10 * (prate / div_low - mode_rate) < 121 + (mode_rate - prate / div))) 126 122 /* 127 123 * At least 10 times better when using a higher 128 124 * frequency than requested, instead of a lower. ··· 151 147 ATMEL_HLCDC_VSPSU | ATMEL_HLCDC_VSPHO | 152 148 ATMEL_HLCDC_GUARDTIME_MASK | ATMEL_HLCDC_MODE_MASK, 153 149 cfg); 150 + 151 + clk_disable_unprepare(crtc->dc->hlcdc->sys_clk); 154 152 } 155 153 156 154 static enum drm_mode_status
+1 -18
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
··· 721 721 dc->hlcdc = dev_get_drvdata(dev->dev->parent); 722 722 dev->dev_private = dc; 723 723 724 - if (dc->desc->fixed_clksrc) { 725 - ret = clk_prepare_enable(dc->hlcdc->sys_clk); 726 - if (ret) { 727 - dev_err(dev->dev, "failed to enable sys_clk\n"); 728 - goto err_destroy_wq; 729 - } 730 - } 731 - 732 724 ret = clk_prepare_enable(dc->hlcdc->periph_clk); 733 725 if (ret) { 734 726 dev_err(dev->dev, "failed to enable periph_clk\n"); 735 - goto err_sys_clk_disable; 727 + goto err_destroy_wq; 736 728 } 737 729 738 730 pm_runtime_enable(dev->dev); ··· 760 768 err_periph_clk_disable: 761 769 pm_runtime_disable(dev->dev); 762 770 clk_disable_unprepare(dc->hlcdc->periph_clk); 763 - err_sys_clk_disable: 764 - if (dc->desc->fixed_clksrc) 765 - clk_disable_unprepare(dc->hlcdc->sys_clk); 766 771 767 772 err_destroy_wq: 768 773 destroy_workqueue(dc->wq); ··· 784 795 785 796 pm_runtime_disable(dev->dev); 786 797 clk_disable_unprepare(dc->hlcdc->periph_clk); 787 - if (dc->desc->fixed_clksrc) 788 - clk_disable_unprepare(dc->hlcdc->sys_clk); 789 798 destroy_workqueue(dc->wq); 790 799 } 791 800 ··· 897 910 regmap_read(regmap, ATMEL_HLCDC_IMR, &dc->suspend.imr); 898 911 regmap_write(regmap, ATMEL_HLCDC_IDR, dc->suspend.imr); 899 912 clk_disable_unprepare(dc->hlcdc->periph_clk); 900 - if (dc->desc->fixed_clksrc) 901 - clk_disable_unprepare(dc->hlcdc->sys_clk); 902 913 903 914 return 0; 904 915 } ··· 906 921 struct drm_device *drm_dev = dev_get_drvdata(dev); 907 922 struct atmel_hlcdc_dc *dc = drm_dev->dev_private; 908 923 909 - if (dc->desc->fixed_clksrc) 910 - clk_prepare_enable(dc->hlcdc->sys_clk); 911 924 clk_prepare_enable(dc->hlcdc->periph_clk); 912 925 regmap_write(dc->hlcdc->regmap, ATMEL_HLCDC_IER, dc->suspend.imr); 913 926
+24 -17
drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
··· 1289 1289 return conn_state->crtc; 1290 1290 } 1291 1291 1292 - static void analogix_dp_bridge_atomic_pre_enable(struct drm_bridge *bridge, 1293 - struct drm_atomic_state *state) 1292 + static void 1293 + analogix_dp_bridge_atomic_pre_enable(struct drm_bridge *bridge, 1294 + struct drm_bridge_state *old_bridge_state) 1294 1295 { 1296 + struct drm_atomic_state *old_state = old_bridge_state->base.state; 1295 1297 struct analogix_dp_device *dp = bridge->driver_private; 1296 1298 struct drm_crtc *crtc; 1297 1299 struct drm_crtc_state *old_crtc_state; 1298 1300 int ret; 1299 1301 1300 - crtc = analogix_dp_get_new_crtc(dp, state); 1302 + crtc = analogix_dp_get_new_crtc(dp, old_state); 1301 1303 if (!crtc) 1302 1304 return; 1303 1305 1304 - old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc); 1306 + old_crtc_state = drm_atomic_get_old_crtc_state(old_state, crtc); 1305 1307 /* Don't touch the panel if we're coming back from PSR */ 1306 1308 if (old_crtc_state && old_crtc_state->self_refresh_active) 1307 1309 return; ··· 1368 1366 return ret; 1369 1367 } 1370 1368 1371 - static void analogix_dp_bridge_atomic_enable(struct drm_bridge *bridge, 1372 - struct drm_atomic_state *state) 1369 + static void 1370 + analogix_dp_bridge_atomic_enable(struct drm_bridge *bridge, 1371 + struct drm_bridge_state *old_bridge_state) 1373 1372 { 1373 + struct drm_atomic_state *old_state = old_bridge_state->base.state; 1374 1374 struct analogix_dp_device *dp = bridge->driver_private; 1375 1375 struct drm_crtc *crtc; 1376 1376 struct drm_crtc_state *old_crtc_state; 1377 1377 int timeout_loop = 0; 1378 1378 int ret; 1379 1379 1380 - crtc = analogix_dp_get_new_crtc(dp, state); 1380 + crtc = analogix_dp_get_new_crtc(dp, old_state); 1381 1381 if (!crtc) 1382 1382 return; 1383 1383 1384 - old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc); 1384 + old_crtc_state = drm_atomic_get_old_crtc_state(old_state, crtc); 1385 1385 /* Not a full enable, just disable PSR and continue */ 1386 1386 if (old_crtc_state && old_crtc_state->self_refresh_active) { 1387 1387 ret = analogix_dp_disable_psr(dp); ··· 1444 1440 dp->dpms_mode = DRM_MODE_DPMS_OFF; 1445 1441 } 1446 1442 1447 - static void analogix_dp_bridge_atomic_disable(struct drm_bridge *bridge, 1448 - struct drm_atomic_state *state) 1443 + static void 1444 + analogix_dp_bridge_atomic_disable(struct drm_bridge *bridge, 1445 + struct drm_bridge_state *old_bridge_state) 1449 1446 { 1447 + struct drm_atomic_state *old_state = old_bridge_state->base.state; 1450 1448 struct analogix_dp_device *dp = bridge->driver_private; 1451 1449 struct drm_crtc *crtc; 1452 1450 struct drm_crtc_state *new_crtc_state = NULL; 1453 1451 1454 - crtc = analogix_dp_get_new_crtc(dp, state); 1452 + crtc = analogix_dp_get_new_crtc(dp, old_state); 1455 1453 if (!crtc) 1456 1454 goto out; 1457 1455 1458 - new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 1456 + new_crtc_state = drm_atomic_get_new_crtc_state(old_state, crtc); 1459 1457 if (!new_crtc_state) 1460 1458 goto out; 1461 1459 ··· 1469 1463 analogix_dp_bridge_disable(bridge); 1470 1464 } 1471 1465 1472 - static 1473 - void analogix_dp_bridge_atomic_post_disable(struct drm_bridge *bridge, 1474 - struct drm_atomic_state *state) 1466 + static void 1467 + analogix_dp_bridge_atomic_post_disable(struct drm_bridge *bridge, 1468 + struct drm_bridge_state *old_bridge_state) 1475 1469 { 1470 + struct drm_atomic_state *old_state = old_bridge_state->base.state; 1476 1471 struct analogix_dp_device *dp = bridge->driver_private; 1477 1472 struct drm_crtc *crtc; 1478 1473 struct drm_crtc_state *new_crtc_state; 1479 1474 int ret; 1480 1475 1481 - crtc = analogix_dp_get_new_crtc(dp, state); 1476 + crtc = analogix_dp_get_new_crtc(dp, old_state); 1482 1477 if (!crtc) 1483 1478 return; 1484 1479 1485 - new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 1480 + new_crtc_state = drm_atomic_get_new_crtc_state(old_state, crtc); 1486 1481 if (!new_crtc_state || !new_crtc_state->self_refresh_active) 1487 1482 return; 1488 1483
+2 -4
drivers/gpu/drm/bridge/cdns-dsi.c
··· 512 512 struct cdns_dsi_output *output = &dsi->output; 513 513 unsigned int tmp; 514 514 bool sync_pulse = false; 515 - int bpp, nlanes; 515 + int bpp; 516 516 517 517 memset(dsi_cfg, 0, sizeof(*dsi_cfg)); 518 518 ··· 520 520 sync_pulse = true; 521 521 522 522 bpp = mipi_dsi_pixel_format_to_bpp(output->dev->format); 523 - nlanes = output->dev->lanes; 524 523 525 524 if (mode_valid_check) 526 525 tmp = mode->htotal - ··· 784 785 unsigned long tx_byte_period; 785 786 struct cdns_dsi_cfg dsi_cfg; 786 787 u32 tmp, reg_wakeup, div; 787 - int bpp, nlanes; 788 + int nlanes; 788 789 789 790 if (WARN_ON(pm_runtime_get_sync(dsi->base.dev) < 0)) 790 791 return; 791 792 792 793 mode = &bridge->encoder->crtc->state->adjusted_mode; 793 - bpp = mipi_dsi_pixel_format_to_bpp(output->dev->format); 794 794 nlanes = output->dev->lanes; 795 795 796 796 WARN_ON_ONCE(cdns_dsi_check_conf(dsi, mode, &dsi_cfg, false));
+1 -1
drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
··· 291 291 return IRQ_HANDLED; 292 292 } 293 293 294 - static struct snd_pcm_hardware dw_hdmi_hw = { 294 + static const struct snd_pcm_hardware dw_hdmi_hw = { 295 295 .info = SNDRV_PCM_INFO_INTERLEAVED | 296 296 SNDRV_PCM_INFO_BLOCK_TRANSFER | 297 297 SNDRV_PCM_INFO_MMAP |
+39
drivers/gpu/drm/drm_atomic.c
··· 30 30 31 31 #include <drm/drm_atomic.h> 32 32 #include <drm/drm_atomic_uapi.h> 33 + #include <drm/drm_bridge.h> 33 34 #include <drm/drm_debugfs.h> 34 35 #include <drm/drm_device.h> 35 36 #include <drm/drm_drv.h> ··· 1017 1016 if (connector->funcs->atomic_print_state) 1018 1017 connector->funcs->atomic_print_state(p, state); 1019 1018 } 1019 + 1020 + /** 1021 + * drm_atomic_add_encoder_bridges - add bridges attached to an encoder 1022 + * @state: atomic state 1023 + * @encoder: DRM encoder 1024 + * 1025 + * This function adds all bridges attached to @encoder. This is needed to add 1026 + * bridge states to @state and make them available when 1027 + * &bridge_funcs.atomic_{check,pre_enable,enable,disable_post_disable}() are 1028 + * called 1029 + * 1030 + * Returns: 1031 + * 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK 1032 + * then the w/w mutex code has detected a deadlock and the entire atomic 1033 + * sequence must be restarted. All other errors are fatal. 1034 + */ 1035 + int 1036 + drm_atomic_add_encoder_bridges(struct drm_atomic_state *state, 1037 + struct drm_encoder *encoder) 1038 + { 1039 + struct drm_bridge_state *bridge_state; 1040 + struct drm_bridge *bridge; 1041 + 1042 + if (!encoder) 1043 + return 0; 1044 + 1045 + DRM_DEBUG_ATOMIC("Adding all bridges for [encoder:%d:%s] to %p\n", 1046 + encoder->base.id, encoder->name, state); 1047 + 1048 + drm_for_each_bridge_in_chain(encoder, bridge) { 1049 + bridge_state = drm_atomic_get_bridge_state(state, bridge); 1050 + if (IS_ERR(bridge_state)) 1051 + return PTR_ERR(bridge_state); 1052 + } 1053 + 1054 + return 0; 1055 + } 1056 + EXPORT_SYMBOL(drm_atomic_add_encoder_bridges); 1020 1057 1021 1058 /** 1022 1059 * drm_atomic_add_affected_connectors - add connectors for CRTC
+26 -6
drivers/gpu/drm/drm_atomic_helper.c
··· 437 437 funcs = encoder->helper_private; 438 438 439 439 bridge = drm_bridge_chain_get_first_bridge(encoder); 440 - ret = drm_bridge_chain_mode_fixup(bridge, 441 - &new_crtc_state->mode, 442 - &new_crtc_state->adjusted_mode); 443 - if (!ret) { 444 - DRM_DEBUG_ATOMIC("Bridge fixup failed\n"); 445 - return -EINVAL; 440 + ret = drm_atomic_bridge_chain_check(bridge, 441 + new_crtc_state, 442 + new_conn_state); 443 + if (ret) { 444 + DRM_DEBUG_ATOMIC("Bridge atomic check failed\n"); 445 + return ret; 446 446 } 447 447 448 448 if (funcs && funcs->atomic_check) { ··· 726 726 727 727 if (funcs->atomic_check) 728 728 ret = funcs->atomic_check(connector, state); 729 + if (ret) 730 + return ret; 731 + } 732 + 733 + /* 734 + * Iterate over all connectors again, and add all affected bridges to 735 + * the state. 736 + */ 737 + for_each_oldnew_connector_in_state(state, connector, 738 + old_connector_state, 739 + new_connector_state, i) { 740 + struct drm_encoder *encoder; 741 + 742 + encoder = old_connector_state->best_encoder; 743 + ret = drm_atomic_add_encoder_bridges(state, encoder); 744 + if (ret) 745 + return ret; 746 + 747 + encoder = new_connector_state->best_encoder; 748 + ret = drm_atomic_add_encoder_bridges(state, encoder); 729 749 if (ret) 730 750 return ret; 731 751 }
+509 -18
drivers/gpu/drm/drm_bridge.c
··· 25 25 #include <linux/module.h> 26 26 #include <linux/mutex.h> 27 27 28 + #include <drm/drm_atomic_state_helper.h> 28 29 #include <drm/drm_bridge.h> 29 30 #include <drm/drm_encoder.h> 30 31 ··· 90 89 } 91 90 EXPORT_SYMBOL(drm_bridge_remove); 92 91 92 + static struct drm_bridge_state * 93 + drm_atomic_default_bridge_duplicate_state(struct drm_bridge *bridge) 94 + { 95 + struct drm_bridge_state *new; 96 + 97 + if (WARN_ON(!bridge->base.state)) 98 + return NULL; 99 + 100 + new = kzalloc(sizeof(*new), GFP_KERNEL); 101 + if (new) 102 + __drm_atomic_helper_bridge_duplicate_state(bridge, new); 103 + 104 + return new; 105 + } 106 + 107 + static struct drm_private_state * 108 + drm_bridge_atomic_duplicate_priv_state(struct drm_private_obj *obj) 109 + { 110 + struct drm_bridge *bridge = drm_priv_to_bridge(obj); 111 + struct drm_bridge_state *state; 112 + 113 + if (bridge->funcs->atomic_duplicate_state) 114 + state = bridge->funcs->atomic_duplicate_state(bridge); 115 + else 116 + state = drm_atomic_default_bridge_duplicate_state(bridge); 117 + 118 + return state ? &state->base : NULL; 119 + } 120 + 121 + static void 122 + drm_atomic_default_bridge_destroy_state(struct drm_bridge *bridge, 123 + struct drm_bridge_state *state) 124 + { 125 + /* Just a simple kfree() for now */ 126 + kfree(state); 127 + } 128 + 129 + static void 130 + drm_bridge_atomic_destroy_priv_state(struct drm_private_obj *obj, 131 + struct drm_private_state *s) 132 + { 133 + struct drm_bridge_state *state = drm_priv_to_bridge_state(s); 134 + struct drm_bridge *bridge = drm_priv_to_bridge(obj); 135 + 136 + if (bridge->funcs->atomic_destroy_state) 137 + bridge->funcs->atomic_destroy_state(bridge, state); 138 + else 139 + drm_atomic_default_bridge_destroy_state(bridge, state); 140 + } 141 + 142 + static const struct drm_private_state_funcs drm_bridge_priv_state_funcs = { 143 + .atomic_duplicate_state = drm_bridge_atomic_duplicate_priv_state, 144 + .atomic_destroy_state = drm_bridge_atomic_destroy_priv_state, 145 + }; 146 + 147 + static struct drm_bridge_state * 148 + drm_atomic_default_bridge_reset(struct drm_bridge *bridge) 149 + { 150 + struct drm_bridge_state *bridge_state; 151 + 152 + bridge_state = kzalloc(sizeof(*bridge_state), GFP_KERNEL); 153 + if (!bridge_state) 154 + return ERR_PTR(-ENOMEM); 155 + 156 + __drm_atomic_helper_bridge_reset(bridge, bridge_state); 157 + return bridge_state; 158 + } 159 + 93 160 /** 94 161 * drm_bridge_attach - attach the bridge to an encoder's chain 95 162 * ··· 183 114 int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge, 184 115 struct drm_bridge *previous) 185 116 { 117 + struct drm_bridge_state *state; 186 118 int ret; 187 119 188 120 if (!encoder || !bridge) ··· 205 135 206 136 if (bridge->funcs->attach) { 207 137 ret = bridge->funcs->attach(bridge); 208 - if (ret < 0) { 209 - list_del(&bridge->chain_node); 210 - bridge->dev = NULL; 211 - bridge->encoder = NULL; 212 - return ret; 213 - } 138 + if (ret < 0) 139 + goto err_reset_bridge; 214 140 } 215 141 142 + if (bridge->funcs->atomic_reset) 143 + state = bridge->funcs->atomic_reset(bridge); 144 + else 145 + state = drm_atomic_default_bridge_reset(bridge); 146 + 147 + if (IS_ERR(state)) { 148 + ret = PTR_ERR(state); 149 + goto err_detach_bridge; 150 + } 151 + 152 + drm_atomic_private_obj_init(bridge->dev, &bridge->base, 153 + &state->base, 154 + &drm_bridge_priv_state_funcs); 155 + 216 156 return 0; 157 + 158 + err_detach_bridge: 159 + if (bridge->funcs->detach) 160 + bridge->funcs->detach(bridge); 161 + 162 + err_reset_bridge: 163 + bridge->dev = NULL; 164 + bridge->encoder = NULL; 165 + list_del(&bridge->chain_node); 166 + return ret; 217 167 } 218 168 EXPORT_SYMBOL(drm_bridge_attach); 219 169 ··· 244 154 245 155 if (WARN_ON(!bridge->dev)) 246 156 return; 157 + 158 + drm_atomic_private_obj_fini(&bridge->base); 247 159 248 160 if (bridge->funcs->detach) 249 161 bridge->funcs->detach(bridge); ··· 501 409 502 410 encoder = bridge->encoder; 503 411 list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { 504 - if (iter->funcs->atomic_disable) 505 - iter->funcs->atomic_disable(iter, old_state); 506 - else if (iter->funcs->disable) 412 + if (iter->funcs->atomic_disable) { 413 + struct drm_bridge_state *old_bridge_state; 414 + 415 + old_bridge_state = 416 + drm_atomic_get_old_bridge_state(old_state, 417 + iter); 418 + if (WARN_ON(!old_bridge_state)) 419 + return; 420 + 421 + iter->funcs->atomic_disable(iter, old_bridge_state); 422 + } else if (iter->funcs->disable) { 507 423 iter->funcs->disable(iter); 424 + } 508 425 509 426 if (iter == bridge) 510 427 break; ··· 544 443 545 444 encoder = bridge->encoder; 546 445 list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) { 547 - if (bridge->funcs->atomic_post_disable) 548 - bridge->funcs->atomic_post_disable(bridge, old_state); 549 - else if (bridge->funcs->post_disable) 446 + if (bridge->funcs->atomic_post_disable) { 447 + struct drm_bridge_state *old_bridge_state; 448 + 449 + old_bridge_state = 450 + drm_atomic_get_old_bridge_state(old_state, 451 + bridge); 452 + if (WARN_ON(!old_bridge_state)) 453 + return; 454 + 455 + bridge->funcs->atomic_post_disable(bridge, 456 + old_bridge_state); 457 + } else if (bridge->funcs->post_disable) { 550 458 bridge->funcs->post_disable(bridge); 459 + } 551 460 } 552 461 } 553 462 EXPORT_SYMBOL(drm_atomic_bridge_chain_post_disable); ··· 586 475 587 476 encoder = bridge->encoder; 588 477 list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { 589 - if (iter->funcs->atomic_pre_enable) 590 - iter->funcs->atomic_pre_enable(iter, old_state); 591 - else if (iter->funcs->pre_enable) 478 + if (iter->funcs->atomic_pre_enable) { 479 + struct drm_bridge_state *old_bridge_state; 480 + 481 + old_bridge_state = 482 + drm_atomic_get_old_bridge_state(old_state, 483 + iter); 484 + if (WARN_ON(!old_bridge_state)) 485 + return; 486 + 487 + iter->funcs->atomic_pre_enable(iter, old_bridge_state); 488 + } else if (iter->funcs->pre_enable) { 592 489 iter->funcs->pre_enable(iter); 490 + } 593 491 594 492 if (iter == bridge) 595 493 break; ··· 628 508 629 509 encoder = bridge->encoder; 630 510 list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) { 631 - if (bridge->funcs->atomic_enable) 632 - bridge->funcs->atomic_enable(bridge, old_state); 633 - else if (bridge->funcs->enable) 511 + if (bridge->funcs->atomic_enable) { 512 + struct drm_bridge_state *old_bridge_state; 513 + 514 + old_bridge_state = 515 + drm_atomic_get_old_bridge_state(old_state, 516 + bridge); 517 + if (WARN_ON(!old_bridge_state)) 518 + return; 519 + 520 + bridge->funcs->atomic_enable(bridge, old_bridge_state); 521 + } else if (bridge->funcs->enable) { 634 522 bridge->funcs->enable(bridge); 523 + } 635 524 } 636 525 } 637 526 EXPORT_SYMBOL(drm_atomic_bridge_chain_enable); 527 + 528 + static int drm_atomic_bridge_check(struct drm_bridge *bridge, 529 + struct drm_crtc_state *crtc_state, 530 + struct drm_connector_state *conn_state) 531 + { 532 + if (bridge->funcs->atomic_check) { 533 + struct drm_bridge_state *bridge_state; 534 + int ret; 535 + 536 + bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state, 537 + bridge); 538 + if (WARN_ON(!bridge_state)) 539 + return -EINVAL; 540 + 541 + ret = bridge->funcs->atomic_check(bridge, bridge_state, 542 + crtc_state, conn_state); 543 + if (ret) 544 + return ret; 545 + } else if (bridge->funcs->mode_fixup) { 546 + if (!bridge->funcs->mode_fixup(bridge, &crtc_state->mode, 547 + &crtc_state->adjusted_mode)) 548 + return -EINVAL; 549 + } 550 + 551 + return 0; 552 + } 553 + 554 + /** 555 + * drm_atomic_helper_bridge_propagate_bus_fmt() - Propagate output format to 556 + * the input end of a bridge 557 + * @bridge: bridge control structure 558 + * @bridge_state: new bridge state 559 + * @crtc_state: new CRTC state 560 + * @conn_state: new connector state 561 + * @output_fmt: tested output bus format 562 + * @num_input_fmts: will contain the size of the returned array 563 + * 564 + * This helper is a pluggable implementation of the 565 + * &drm_bridge_funcs.atomic_get_input_bus_fmts operation for bridges that don't 566 + * modify the bus configuration between their input and their output. It 567 + * returns an array of input formats with a single element set to @output_fmt. 568 + * 569 + * RETURNS: 570 + * a valid format array of size @num_input_fmts, or NULL if the allocation 571 + * failed 572 + */ 573 + u32 * 574 + drm_atomic_helper_bridge_propagate_bus_fmt(struct drm_bridge *bridge, 575 + struct drm_bridge_state *bridge_state, 576 + struct drm_crtc_state *crtc_state, 577 + struct drm_connector_state *conn_state, 578 + u32 output_fmt, 579 + unsigned int *num_input_fmts) 580 + { 581 + u32 *input_fmts; 582 + 583 + input_fmts = kzalloc(sizeof(*input_fmts), GFP_KERNEL); 584 + if (!input_fmts) { 585 + *num_input_fmts = 0; 586 + return NULL; 587 + } 588 + 589 + *num_input_fmts = 1; 590 + input_fmts[0] = output_fmt; 591 + return input_fmts; 592 + } 593 + EXPORT_SYMBOL(drm_atomic_helper_bridge_propagate_bus_fmt); 594 + 595 + static int select_bus_fmt_recursive(struct drm_bridge *first_bridge, 596 + struct drm_bridge *cur_bridge, 597 + struct drm_crtc_state *crtc_state, 598 + struct drm_connector_state *conn_state, 599 + u32 out_bus_fmt) 600 + { 601 + struct drm_bridge_state *cur_state; 602 + unsigned int num_in_bus_fmts, i; 603 + struct drm_bridge *prev_bridge; 604 + u32 *in_bus_fmts; 605 + int ret; 606 + 607 + prev_bridge = drm_bridge_get_prev_bridge(cur_bridge); 608 + cur_state = drm_atomic_get_new_bridge_state(crtc_state->state, 609 + cur_bridge); 610 + if (WARN_ON(!cur_state)) 611 + return -EINVAL; 612 + 613 + /* 614 + * If bus format negotiation is not supported by this bridge, let's 615 + * pass MEDIA_BUS_FMT_FIXED to the previous bridge in the chain and 616 + * hope that it can handle this situation gracefully (by providing 617 + * appropriate default values). 618 + */ 619 + if (!cur_bridge->funcs->atomic_get_input_bus_fmts) { 620 + if (cur_bridge != first_bridge) { 621 + ret = select_bus_fmt_recursive(first_bridge, 622 + prev_bridge, crtc_state, 623 + conn_state, 624 + MEDIA_BUS_FMT_FIXED); 625 + if (ret) 626 + return ret; 627 + } 628 + 629 + cur_state->input_bus_cfg.format = MEDIA_BUS_FMT_FIXED; 630 + cur_state->output_bus_cfg.format = out_bus_fmt; 631 + return 0; 632 + } 633 + 634 + in_bus_fmts = cur_bridge->funcs->atomic_get_input_bus_fmts(cur_bridge, 635 + cur_state, 636 + crtc_state, 637 + conn_state, 638 + out_bus_fmt, 639 + &num_in_bus_fmts); 640 + if (!num_in_bus_fmts) 641 + return -ENOTSUPP; 642 + else if (!in_bus_fmts) 643 + return -ENOMEM; 644 + 645 + if (first_bridge == cur_bridge) { 646 + cur_state->input_bus_cfg.format = in_bus_fmts[0]; 647 + cur_state->output_bus_cfg.format = out_bus_fmt; 648 + kfree(in_bus_fmts); 649 + return 0; 650 + } 651 + 652 + for (i = 0; i < num_in_bus_fmts; i++) { 653 + ret = select_bus_fmt_recursive(first_bridge, prev_bridge, 654 + crtc_state, conn_state, 655 + in_bus_fmts[i]); 656 + if (ret != -ENOTSUPP) 657 + break; 658 + } 659 + 660 + if (!ret) { 661 + cur_state->input_bus_cfg.format = in_bus_fmts[i]; 662 + cur_state->output_bus_cfg.format = out_bus_fmt; 663 + } 664 + 665 + kfree(in_bus_fmts); 666 + return ret; 667 + } 668 + 669 + /* 670 + * This function is called by &drm_atomic_bridge_chain_check() just before 671 + * calling &drm_bridge_funcs.atomic_check() on all elements of the chain. 672 + * It performs bus format negotiation between bridge elements. The negotiation 673 + * happens in reverse order, starting from the last element in the chain up to 674 + * @bridge. 675 + * 676 + * Negotiation starts by retrieving supported output bus formats on the last 677 + * bridge element and testing them one by one. The test is recursive, meaning 678 + * that for each tested output format, the whole chain will be walked backward, 679 + * and each element will have to choose an input bus format that can be 680 + * transcoded to the requested output format. When a bridge element does not 681 + * support transcoding into a specific output format -ENOTSUPP is returned and 682 + * the next bridge element will have to try a different format. If none of the 683 + * combinations worked, -ENOTSUPP is returned and the atomic modeset will fail. 684 + * 685 + * This implementation is relying on 686 + * &drm_bridge_funcs.atomic_get_output_bus_fmts() and 687 + * &drm_bridge_funcs.atomic_get_input_bus_fmts() to gather supported 688 + * input/output formats. 689 + * 690 + * When &drm_bridge_funcs.atomic_get_output_bus_fmts() is not implemented by 691 + * the last element of the chain, &drm_atomic_bridge_chain_select_bus_fmts() 692 + * tries a single format: &drm_connector.display_info.bus_formats[0] if 693 + * available, MEDIA_BUS_FMT_FIXED otherwise. 694 + * 695 + * When &drm_bridge_funcs.atomic_get_input_bus_fmts() is not implemented, 696 + * &drm_atomic_bridge_chain_select_bus_fmts() skips the negotiation on the 697 + * bridge element that lacks this hook and asks the previous element in the 698 + * chain to try MEDIA_BUS_FMT_FIXED. It's up to bridge drivers to decide what 699 + * to do in that case (fail if they want to enforce bus format negotiation, or 700 + * provide a reasonable default if they need to support pipelines where not 701 + * all elements support bus format negotiation). 702 + */ 703 + static int 704 + drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge, 705 + struct drm_crtc_state *crtc_state, 706 + struct drm_connector_state *conn_state) 707 + { 708 + struct drm_connector *conn = conn_state->connector; 709 + struct drm_encoder *encoder = bridge->encoder; 710 + struct drm_bridge_state *last_bridge_state; 711 + unsigned int i, num_out_bus_fmts; 712 + struct drm_bridge *last_bridge; 713 + u32 *out_bus_fmts; 714 + int ret = 0; 715 + 716 + last_bridge = list_last_entry(&encoder->bridge_chain, 717 + struct drm_bridge, chain_node); 718 + last_bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state, 719 + last_bridge); 720 + if (WARN_ON(!last_bridge_state)) 721 + return -EINVAL; 722 + 723 + if (last_bridge->funcs->atomic_get_output_bus_fmts) { 724 + const struct drm_bridge_funcs *funcs = last_bridge->funcs; 725 + 726 + out_bus_fmts = funcs->atomic_get_output_bus_fmts(last_bridge, 727 + last_bridge_state, 728 + crtc_state, 729 + conn_state, 730 + &num_out_bus_fmts); 731 + if (!num_out_bus_fmts) 732 + return -ENOTSUPP; 733 + else if (!out_bus_fmts) 734 + return -ENOMEM; 735 + } else { 736 + num_out_bus_fmts = 1; 737 + out_bus_fmts = kmalloc(sizeof(*out_bus_fmts), GFP_KERNEL); 738 + if (!out_bus_fmts) 739 + return -ENOMEM; 740 + 741 + if (conn->display_info.num_bus_formats && 742 + conn->display_info.bus_formats) 743 + out_bus_fmts[0] = conn->display_info.bus_formats[0]; 744 + else 745 + out_bus_fmts[0] = MEDIA_BUS_FMT_FIXED; 746 + } 747 + 748 + for (i = 0; i < num_out_bus_fmts; i++) { 749 + ret = select_bus_fmt_recursive(bridge, last_bridge, crtc_state, 750 + conn_state, out_bus_fmts[i]); 751 + if (ret != -ENOTSUPP) 752 + break; 753 + } 754 + 755 + kfree(out_bus_fmts); 756 + 757 + return ret; 758 + } 759 + 760 + static void 761 + drm_atomic_bridge_propagate_bus_flags(struct drm_bridge *bridge, 762 + struct drm_connector *conn, 763 + struct drm_atomic_state *state) 764 + { 765 + struct drm_bridge_state *bridge_state, *next_bridge_state; 766 + struct drm_bridge *next_bridge; 767 + u32 output_flags; 768 + 769 + bridge_state = drm_atomic_get_new_bridge_state(state, bridge); 770 + next_bridge = drm_bridge_get_next_bridge(bridge); 771 + 772 + /* 773 + * Let's try to apply the most common case here, that is, propagate 774 + * display_info flags for the last bridge, and propagate the input 775 + * flags of the next bridge element to the output end of the current 776 + * bridge when the bridge is not the last one. 777 + * There are exceptions to this rule, like when signal inversion is 778 + * happening at the board level, but that's something drivers can deal 779 + * with from their &drm_bridge_funcs.atomic_check() implementation by 780 + * simply overriding the flags value we've set here. 781 + */ 782 + if (!next_bridge) { 783 + output_flags = conn->display_info.bus_flags; 784 + } else { 785 + next_bridge_state = drm_atomic_get_new_bridge_state(state, 786 + next_bridge); 787 + output_flags = next_bridge_state->input_bus_cfg.flags; 788 + } 789 + 790 + bridge_state->output_bus_cfg.flags = output_flags; 791 + 792 + /* 793 + * Propage the output flags to the input end of the bridge. Again, it's 794 + * not necessarily what all bridges want, but that's what most of them 795 + * do, and by doing that by default we avoid forcing drivers to 796 + * duplicate the "dummy propagation" logic. 797 + */ 798 + bridge_state->input_bus_cfg.flags = output_flags; 799 + } 800 + 801 + /** 802 + * drm_atomic_bridge_chain_check() - Do an atomic check on the bridge chain 803 + * @bridge: bridge control structure 804 + * @crtc_state: new CRTC state 805 + * @conn_state: new connector state 806 + * 807 + * First trigger a bus format negotiation before calling 808 + * &drm_bridge_funcs.atomic_check() (falls back on 809 + * &drm_bridge_funcs.mode_fixup()) op for all the bridges in the encoder chain, 810 + * starting from the last bridge to the first. These are called before calling 811 + * &drm_encoder_helper_funcs.atomic_check() 812 + * 813 + * RETURNS: 814 + * 0 on success, a negative error code on failure 815 + */ 816 + int drm_atomic_bridge_chain_check(struct drm_bridge *bridge, 817 + struct drm_crtc_state *crtc_state, 818 + struct drm_connector_state *conn_state) 819 + { 820 + struct drm_connector *conn = conn_state->connector; 821 + struct drm_encoder *encoder = bridge->encoder; 822 + struct drm_bridge *iter; 823 + int ret; 824 + 825 + ret = drm_atomic_bridge_chain_select_bus_fmts(bridge, crtc_state, 826 + conn_state); 827 + if (ret) 828 + return ret; 829 + 830 + list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { 831 + int ret; 832 + 833 + /* 834 + * Bus flags are propagated by default. If a bridge needs to 835 + * tweak the input bus flags for any reason, it should happen 836 + * in its &drm_bridge_funcs.atomic_check() implementation such 837 + * that preceding bridges in the chain can propagate the new 838 + * bus flags. 839 + */ 840 + drm_atomic_bridge_propagate_bus_flags(iter, conn, 841 + crtc_state->state); 842 + 843 + ret = drm_atomic_bridge_check(iter, crtc_state, conn_state); 844 + if (ret) 845 + return ret; 846 + 847 + if (iter == bridge) 848 + break; 849 + } 850 + 851 + return 0; 852 + } 853 + EXPORT_SYMBOL(drm_atomic_bridge_chain_check); 854 + 855 + /** 856 + * __drm_atomic_helper_bridge_reset() - Initialize a bridge state to its 857 + * default 858 + * @bridge: the bridge this state is refers to 859 + * @state: bridge state to initialize 860 + * 861 + * Initialize the bridge state to default values. This is meant to be* called 862 + * by the bridge &drm_plane_funcs.reset hook for bridges that subclass the 863 + * bridge state. 864 + */ 865 + void __drm_atomic_helper_bridge_reset(struct drm_bridge *bridge, 866 + struct drm_bridge_state *state) 867 + { 868 + memset(state, 0, sizeof(*state)); 869 + state->bridge = bridge; 870 + } 871 + EXPORT_SYMBOL(__drm_atomic_helper_bridge_reset); 872 + 873 + /** 874 + * __drm_atomic_helper_bridge_duplicate_state() - Copy atomic bridge state 875 + * @bridge: bridge object 876 + * @state: atomic bridge state 877 + * 878 + * Copies atomic state from a bridge's current state and resets inferred values. 879 + * This is useful for drivers that subclass the bridge state. 880 + */ 881 + void __drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge, 882 + struct drm_bridge_state *state) 883 + { 884 + __drm_atomic_helper_private_obj_duplicate_state(&bridge->base, 885 + &state->base); 886 + state->bridge = bridge; 887 + } 888 + EXPORT_SYMBOL(__drm_atomic_helper_bridge_duplicate_state); 638 889 639 890 #ifdef CONFIG_OF 640 891 /**
+32 -21
drivers/gpu/drm/drm_gem_vram_helper.c
··· 2 2 3 3 #include <drm/drm_debugfs.h> 4 4 #include <drm/drm_device.h> 5 + #include <drm/drm_drv.h> 5 6 #include <drm/drm_file.h> 6 7 #include <drm/drm_framebuffer.h> 7 8 #include <drm/drm_gem_ttm_helper.h> ··· 93 92 } 94 93 95 94 static int drm_gem_vram_init(struct drm_device *dev, 96 - struct ttm_bo_device *bdev, 97 95 struct drm_gem_vram_object *gbo, 98 - size_t size, unsigned long pg_align, 99 - bool interruptible) 96 + size_t size, unsigned long pg_align) 100 97 { 98 + struct drm_vram_mm *vmm = dev->vram_mm; 99 + struct ttm_bo_device *bdev; 101 100 int ret; 102 101 size_t acc_size; 102 + 103 + if (WARN_ONCE(!vmm, "VRAM MM not initialized")) 104 + return -EINVAL; 105 + bdev = &vmm->bdev; 103 106 104 107 gbo->bo.base.funcs = &drm_gem_vram_object_funcs; 105 108 ··· 117 112 drm_gem_vram_placement(gbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM); 118 113 119 114 ret = ttm_bo_init(bdev, &gbo->bo, size, ttm_bo_type_device, 120 - &gbo->placement, pg_align, interruptible, acc_size, 115 + &gbo->placement, pg_align, false, acc_size, 121 116 NULL, NULL, ttm_buffer_object_destroy); 122 117 if (ret) 123 118 goto err_drm_gem_object_release; ··· 132 127 /** 133 128 * drm_gem_vram_create() - Creates a VRAM-backed GEM object 134 129 * @dev: the DRM device 135 - * @bdev: the TTM BO device backing the object 136 130 * @size: the buffer size in bytes 137 131 * @pg_align: the buffer's alignment in multiples of the page size 138 - * @interruptible: sleep interruptible if waiting for memory 139 132 * 140 133 * Returns: 141 134 * A new instance of &struct drm_gem_vram_object on success, or 142 135 * an ERR_PTR()-encoded error code otherwise. 143 136 */ 144 137 struct drm_gem_vram_object *drm_gem_vram_create(struct drm_device *dev, 145 - struct ttm_bo_device *bdev, 146 138 size_t size, 147 - unsigned long pg_align, 148 - bool interruptible) 139 + unsigned long pg_align) 149 140 { 150 141 struct drm_gem_vram_object *gbo; 151 142 int ret; 152 143 153 - gbo = kzalloc(sizeof(*gbo), GFP_KERNEL); 154 - if (!gbo) 155 - return ERR_PTR(-ENOMEM); 144 + if (dev->driver->gem_create_object) { 145 + struct drm_gem_object *gem = 146 + dev->driver->gem_create_object(dev, size); 147 + if (!gem) 148 + return ERR_PTR(-ENOMEM); 149 + gbo = drm_gem_vram_of_gem(gem); 150 + } else { 151 + gbo = kzalloc(sizeof(*gbo), GFP_KERNEL); 152 + if (!gbo) 153 + return ERR_PTR(-ENOMEM); 154 + } 156 155 157 - ret = drm_gem_vram_init(dev, bdev, gbo, size, pg_align, interruptible); 156 + ret = drm_gem_vram_init(dev, gbo, size, pg_align); 158 157 if (ret < 0) 159 158 goto err_kfree; 160 159 ··· 492 483 Helper for implementing &struct drm_driver.dumb_create 493 484 * @file: the DRM file 494 485 * @dev: the DRM device 495 - * @bdev: the TTM BO device managing the buffer object 496 486 * @pg_align: the buffer's alignment in multiples of the page size 497 - * @interruptible: sleep interruptible if waiting for memory 487 + * @pitch_align: the scanline's alignment in powers of 2 498 488 * @args: the arguments as provided to \ 499 489 &struct drm_driver.dumb_create 500 490 * ··· 508 500 */ 509 501 int drm_gem_vram_fill_create_dumb(struct drm_file *file, 510 502 struct drm_device *dev, 511 - struct ttm_bo_device *bdev, 512 503 unsigned long pg_align, 513 - bool interruptible, 504 + unsigned long pitch_align, 514 505 struct drm_mode_create_dumb *args) 515 506 { 516 507 size_t pitch, size; ··· 517 510 int ret; 518 511 u32 handle; 519 512 520 - pitch = args->width * ((args->bpp + 7) / 8); 513 + pitch = args->width * DIV_ROUND_UP(args->bpp, 8); 514 + if (pitch_align) { 515 + if (WARN_ON_ONCE(!is_power_of_2(pitch_align))) 516 + return -EINVAL; 517 + pitch = ALIGN(pitch, pitch_align); 518 + } 521 519 size = pitch * args->height; 522 520 523 521 size = roundup(size, PAGE_SIZE); 524 522 if (!size) 525 523 return -EINVAL; 526 524 527 - gbo = drm_gem_vram_create(dev, bdev, size, pg_align, interruptible); 525 + gbo = drm_gem_vram_create(dev, size, pg_align); 528 526 if (IS_ERR(gbo)) 529 527 return PTR_ERR(gbo); 530 528 ··· 624 612 if (WARN_ONCE(!dev->vram_mm, "VRAM MM not initialized")) 625 613 return -EINVAL; 626 614 627 - return drm_gem_vram_fill_create_dumb(file, dev, &dev->vram_mm->bdev, 0, 628 - false, args); 615 + return drm_gem_vram_fill_create_dumb(file, dev, 0, 0, args); 629 616 } 630 617 EXPORT_SYMBOL(drm_gem_vram_driver_dumb_create); 631 618
+2 -2
drivers/gpu/drm/drm_mipi_dbi.c
··· 367 367 memset(dbidev->tx_buf, 0, len); 368 368 369 369 mipi_dbi_command(dbi, MIPI_DCS_SET_COLUMN_ADDRESS, 0, 0, 370 - (width >> 8) & 0xFF, (width - 1) & 0xFF); 370 + ((width - 1) >> 8) & 0xFF, (width - 1) & 0xFF); 371 371 mipi_dbi_command(dbi, MIPI_DCS_SET_PAGE_ADDRESS, 0, 0, 372 - (height >> 8) & 0xFF, (height - 1) & 0xFF); 372 + ((height - 1) >> 8) & 0xFF, (height - 1) & 0xFF); 373 373 mipi_dbi_command_buf(dbi, MIPI_DCS_WRITE_MEMORY_START, 374 374 (u8 *)dbidev->tx_buf, len); 375 375
+1 -1
drivers/gpu/drm/hisilicon/hibmc/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 - hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o hibmc_drm_fbdev.o hibmc_ttm.o 2 + hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o hibmc_ttm.o 3 3 4 4 obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc-drm.o
+1 -3
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
··· 99 99 s64 gpu_addr = 0; 100 100 unsigned int line_l; 101 101 struct hibmc_drm_private *priv = plane->dev->dev_private; 102 - struct hibmc_framebuffer *hibmc_fb; 103 102 struct drm_gem_vram_object *gbo; 104 103 105 104 if (!state->fb) 106 105 return; 107 106 108 - hibmc_fb = to_hibmc_framebuffer(state->fb); 109 - gbo = drm_gem_vram_of_gem(hibmc_fb->obj); 107 + gbo = drm_gem_vram_of_gem(state->fb->obj[0]); 110 108 111 109 gpu_addr = drm_gem_vram_offset(gbo); 112 110 if (WARN_ON_ONCE(gpu_addr < 0))
+3 -3
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
··· 17 17 18 18 #include <drm/drm_atomic_helper.h> 19 19 #include <drm/drm_drv.h> 20 + #include <drm/drm_fb_helper.h> 20 21 #include <drm/drm_gem_vram_helper.h> 21 22 #include <drm/drm_irq.h> 22 23 #include <drm/drm_print.h> ··· 55 54 .desc = "hibmc drm driver", 56 55 .major = 1, 57 56 .minor = 0, 57 + .debugfs_init = drm_vram_mm_debugfs_init, 58 58 .dumb_create = hibmc_dumb_create, 59 59 .dumb_map_offset = drm_gem_vram_driver_dumb_mmap_offset, 60 60 .gem_prime_mmap = drm_gem_prime_mmap, ··· 249 247 { 250 248 struct hibmc_drm_private *priv = dev->dev_private; 251 249 252 - hibmc_fbdev_fini(priv); 253 - 254 250 drm_atomic_helper_shutdown(dev); 255 251 256 252 if (dev->irq_enabled) ··· 307 307 /* reset all the states of crtc/plane/encoder/connector */ 308 308 drm_mode_config_reset(dev); 309 309 310 - ret = hibmc_fbdev_init(priv); 310 + ret = drm_fbdev_generic_setup(dev, 16); 311 311 if (ret) { 312 312 DRM_ERROR("failed to initialize fbdev: %d\n", ret); 313 313 goto err;
-26
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
··· 18 18 #include <drm/drm_framebuffer.h> 19 19 20 20 struct drm_device; 21 - struct drm_gem_object; 22 - 23 - struct hibmc_framebuffer { 24 - struct drm_framebuffer fb; 25 - struct drm_gem_object *obj; 26 - }; 27 - 28 - struct hibmc_fbdev { 29 - struct drm_fb_helper helper; /* must be first */ 30 - struct hibmc_framebuffer *fb; 31 - int size; 32 - }; 33 21 34 22 struct hibmc_drm_private { 35 23 /* hw */ ··· 30 42 /* drm */ 31 43 struct drm_device *dev; 32 44 bool mode_config_initialized; 33 - 34 - /* fbdev */ 35 - struct hibmc_fbdev *fbdev; 36 45 }; 37 - 38 - #define to_hibmc_framebuffer(x) container_of(x, struct hibmc_framebuffer, fb) 39 46 40 47 void hibmc_set_power_mode(struct hibmc_drm_private *priv, 41 48 unsigned int power_mode); ··· 39 56 40 57 int hibmc_de_init(struct hibmc_drm_private *priv); 41 58 int hibmc_vdac_init(struct hibmc_drm_private *priv); 42 - int hibmc_fbdev_init(struct hibmc_drm_private *priv); 43 - void hibmc_fbdev_fini(struct hibmc_drm_private *priv); 44 - 45 - int hibmc_gem_create(struct drm_device *dev, u32 size, bool iskernel, 46 - struct drm_gem_object **obj); 47 - struct hibmc_framebuffer * 48 - hibmc_framebuffer_init(struct drm_device *dev, 49 - const struct drm_mode_fb_cmd2 *mode_cmd, 50 - struct drm_gem_object *obj); 51 59 52 60 int hibmc_mm_init(struct hibmc_drm_private *hibmc); 53 61 void hibmc_mm_fini(struct hibmc_drm_private *hibmc);
-240
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-or-later 2 - /* Hisilicon Hibmc SoC drm driver 3 - * 4 - * Based on the bochs drm driver. 5 - * 6 - * Copyright (c) 2016 Huawei Limited. 7 - * 8 - * Author: 9 - * Rongrong Zou <zourongrong@huawei.com> 10 - * Rongrong Zou <zourongrong@gmail.com> 11 - * Jianhua Li <lijianhua@huawei.com> 12 - */ 13 - 14 - #include <drm/drm_crtc.h> 15 - #include <drm/drm_fb_helper.h> 16 - #include <drm/drm_fourcc.h> 17 - #include <drm/drm_gem_vram_helper.h> 18 - #include <drm/drm_probe_helper.h> 19 - 20 - #include "hibmc_drm_drv.h" 21 - 22 - static int hibmcfb_create_object( 23 - struct hibmc_drm_private *priv, 24 - const struct drm_mode_fb_cmd2 *mode_cmd, 25 - struct drm_gem_object **gobj_p) 26 - { 27 - struct drm_gem_object *gobj; 28 - struct drm_device *dev = priv->dev; 29 - u32 size; 30 - int ret = 0; 31 - 32 - size = mode_cmd->pitches[0] * mode_cmd->height; 33 - ret = hibmc_gem_create(dev, size, true, &gobj); 34 - if (ret) 35 - return ret; 36 - 37 - *gobj_p = gobj; 38 - return ret; 39 - } 40 - 41 - static const struct fb_ops hibmc_drm_fb_ops = { 42 - .owner = THIS_MODULE, 43 - .fb_check_var = drm_fb_helper_check_var, 44 - .fb_set_par = drm_fb_helper_set_par, 45 - .fb_fillrect = drm_fb_helper_sys_fillrect, 46 - .fb_copyarea = drm_fb_helper_sys_copyarea, 47 - .fb_imageblit = drm_fb_helper_sys_imageblit, 48 - .fb_pan_display = drm_fb_helper_pan_display, 49 - .fb_blank = drm_fb_helper_blank, 50 - .fb_setcmap = drm_fb_helper_setcmap, 51 - }; 52 - 53 - static int hibmc_drm_fb_create(struct drm_fb_helper *helper, 54 - struct drm_fb_helper_surface_size *sizes) 55 - { 56 - struct hibmc_fbdev *hi_fbdev = 57 - container_of(helper, struct hibmc_fbdev, helper); 58 - struct hibmc_drm_private *priv = helper->dev->dev_private; 59 - struct fb_info *info; 60 - struct drm_mode_fb_cmd2 mode_cmd; 61 - struct drm_gem_object *gobj = NULL; 62 - int ret = 0; 63 - size_t size; 64 - unsigned int bytes_per_pixel; 65 - struct drm_gem_vram_object *gbo = NULL; 66 - void *base; 67 - 68 - DRM_DEBUG_DRIVER("surface width(%d), height(%d) and bpp(%d)\n", 69 - sizes->surface_width, sizes->surface_height, 70 - sizes->surface_bpp); 71 - 72 - bytes_per_pixel = DIV_ROUND_UP(sizes->surface_bpp, 8); 73 - 74 - mode_cmd.width = sizes->surface_width; 75 - mode_cmd.height = sizes->surface_height; 76 - mode_cmd.pitches[0] = mode_cmd.width * bytes_per_pixel; 77 - mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, 78 - sizes->surface_depth); 79 - 80 - size = PAGE_ALIGN(mode_cmd.pitches[0] * mode_cmd.height); 81 - 82 - ret = hibmcfb_create_object(priv, &mode_cmd, &gobj); 83 - if (ret) { 84 - DRM_ERROR("failed to create fbcon backing object: %d\n", ret); 85 - return -ENOMEM; 86 - } 87 - 88 - gbo = drm_gem_vram_of_gem(gobj); 89 - 90 - ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM); 91 - if (ret) { 92 - DRM_ERROR("failed to pin fbcon: %d\n", ret); 93 - goto out_unref_gem; 94 - } 95 - 96 - base = drm_gem_vram_kmap(gbo, true, NULL); 97 - if (IS_ERR(base)) { 98 - ret = PTR_ERR(base); 99 - DRM_ERROR("failed to kmap fbcon: %d\n", ret); 100 - goto out_unpin_bo; 101 - } 102 - 103 - info = drm_fb_helper_alloc_fbi(helper); 104 - if (IS_ERR(info)) { 105 - ret = PTR_ERR(info); 106 - DRM_ERROR("failed to allocate fbi: %d\n", ret); 107 - goto out_release_fbi; 108 - } 109 - 110 - hi_fbdev->fb = hibmc_framebuffer_init(priv->dev, &mode_cmd, gobj); 111 - if (IS_ERR(hi_fbdev->fb)) { 112 - ret = PTR_ERR(hi_fbdev->fb); 113 - hi_fbdev->fb = NULL; 114 - DRM_ERROR("failed to initialize framebuffer: %d\n", ret); 115 - goto out_release_fbi; 116 - } 117 - 118 - priv->fbdev->size = size; 119 - hi_fbdev->helper.fb = &hi_fbdev->fb->fb; 120 - 121 - info->fbops = &hibmc_drm_fb_ops; 122 - 123 - drm_fb_helper_fill_info(info, &priv->fbdev->helper, sizes); 124 - 125 - info->screen_base = base; 126 - info->screen_size = size; 127 - 128 - info->fix.smem_start = gbo->bo.mem.bus.offset + gbo->bo.mem.bus.base; 129 - info->fix.smem_len = size; 130 - return 0; 131 - 132 - out_release_fbi: 133 - drm_gem_vram_kunmap(gbo); 134 - out_unpin_bo: 135 - drm_gem_vram_unpin(gbo); 136 - out_unref_gem: 137 - drm_gem_object_put_unlocked(gobj); 138 - 139 - return ret; 140 - } 141 - 142 - static void hibmc_fbdev_destroy(struct hibmc_fbdev *fbdev) 143 - { 144 - struct hibmc_framebuffer *gfb = fbdev->fb; 145 - struct drm_fb_helper *fbh = &fbdev->helper; 146 - 147 - drm_fb_helper_unregister_fbi(fbh); 148 - 149 - drm_fb_helper_fini(fbh); 150 - 151 - if (gfb) 152 - drm_framebuffer_put(&gfb->fb); 153 - } 154 - 155 - static const struct drm_fb_helper_funcs hibmc_fbdev_helper_funcs = { 156 - .fb_probe = hibmc_drm_fb_create, 157 - }; 158 - 159 - int hibmc_fbdev_init(struct hibmc_drm_private *priv) 160 - { 161 - int ret; 162 - struct fb_var_screeninfo *var; 163 - struct fb_fix_screeninfo *fix; 164 - struct hibmc_fbdev *hifbdev; 165 - 166 - hifbdev = devm_kzalloc(priv->dev->dev, sizeof(*hifbdev), GFP_KERNEL); 167 - if (!hifbdev) { 168 - DRM_ERROR("failed to allocate hibmc_fbdev\n"); 169 - return -ENOMEM; 170 - } 171 - 172 - priv->fbdev = hifbdev; 173 - drm_fb_helper_prepare(priv->dev, &hifbdev->helper, 174 - &hibmc_fbdev_helper_funcs); 175 - 176 - /* Now just one crtc and one channel */ 177 - ret = drm_fb_helper_init(priv->dev, &hifbdev->helper, 1); 178 - if (ret) { 179 - DRM_ERROR("failed to initialize fb helper: %d\n", ret); 180 - return ret; 181 - } 182 - 183 - ret = drm_fb_helper_single_add_all_connectors(&hifbdev->helper); 184 - if (ret) { 185 - DRM_ERROR("failed to add all connectors: %d\n", ret); 186 - goto fini; 187 - } 188 - 189 - ret = drm_fb_helper_initial_config(&hifbdev->helper, 16); 190 - if (ret) { 191 - DRM_ERROR("failed to setup initial conn config: %d\n", ret); 192 - goto fini; 193 - } 194 - 195 - var = &hifbdev->helper.fbdev->var; 196 - fix = &hifbdev->helper.fbdev->fix; 197 - 198 - DRM_DEBUG_DRIVER("Member of info->var is :\n" 199 - "xres=%d\n" 200 - "yres=%d\n" 201 - "xres_virtual=%d\n" 202 - "yres_virtual=%d\n" 203 - "xoffset=%d\n" 204 - "yoffset=%d\n" 205 - "bits_per_pixel=%d\n" 206 - "...\n", var->xres, var->yres, var->xres_virtual, 207 - var->yres_virtual, var->xoffset, var->yoffset, 208 - var->bits_per_pixel); 209 - DRM_DEBUG_DRIVER("Member of info->fix is :\n" 210 - "smem_start=%lx\n" 211 - "smem_len=%d\n" 212 - "type=%d\n" 213 - "type_aux=%d\n" 214 - "visual=%d\n" 215 - "xpanstep=%d\n" 216 - "ypanstep=%d\n" 217 - "ywrapstep=%d\n" 218 - "line_length=%d\n" 219 - "accel=%d\n" 220 - "capabilities=%d\n" 221 - "...\n", fix->smem_start, fix->smem_len, fix->type, 222 - fix->type_aux, fix->visual, fix->xpanstep, 223 - fix->ypanstep, fix->ywrapstep, fix->line_length, 224 - fix->accel, fix->capabilities); 225 - 226 - return 0; 227 - 228 - fini: 229 - drm_fb_helper_fini(&hifbdev->helper); 230 - return ret; 231 - } 232 - 233 - void hibmc_fbdev_fini(struct hibmc_drm_private *priv) 234 - { 235 - if (!priv->fbdev) 236 - return; 237 - 238 - hibmc_fbdev_destroy(priv->fbdev); 239 - priv->fbdev = NULL; 240 - }
+3 -113
drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c
··· 15 15 16 16 #include <drm/drm_atomic_helper.h> 17 17 #include <drm/drm_gem.h> 18 + #include <drm/drm_gem_framebuffer_helper.h> 18 19 #include <drm/drm_gem_vram_helper.h> 19 20 #include <drm/drm_print.h> 20 21 ··· 47 46 drm_vram_helper_release_mm(hibmc->dev); 48 47 } 49 48 50 - int hibmc_gem_create(struct drm_device *dev, u32 size, bool iskernel, 51 - struct drm_gem_object **obj) 52 - { 53 - struct drm_gem_vram_object *gbo; 54 - int ret; 55 - 56 - *obj = NULL; 57 - 58 - size = roundup(size, PAGE_SIZE); 59 - if (size == 0) 60 - return -EINVAL; 61 - 62 - gbo = drm_gem_vram_create(dev, &dev->vram_mm->bdev, size, 0, false); 63 - if (IS_ERR(gbo)) { 64 - ret = PTR_ERR(gbo); 65 - if (ret != -ERESTARTSYS) 66 - DRM_ERROR("failed to allocate GEM object: %d\n", ret); 67 - return ret; 68 - } 69 - *obj = &gbo->bo.base; 70 - return 0; 71 - } 72 - 73 49 int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev, 74 50 struct drm_mode_create_dumb *args) 75 51 { 76 - struct drm_gem_object *gobj; 77 - u32 handle; 78 - int ret; 79 - 80 - args->pitch = ALIGN(args->width * DIV_ROUND_UP(args->bpp, 8), 16); 81 - args->size = args->pitch * args->height; 82 - 83 - ret = hibmc_gem_create(dev, args->size, false, 84 - &gobj); 85 - if (ret) { 86 - DRM_ERROR("failed to create GEM object: %d\n", ret); 87 - return ret; 88 - } 89 - 90 - ret = drm_gem_handle_create(file, gobj, &handle); 91 - drm_gem_object_put_unlocked(gobj); 92 - if (ret) { 93 - DRM_ERROR("failed to unreference GEM object: %d\n", ret); 94 - return ret; 95 - } 96 - 97 - args->handle = handle; 98 - return 0; 99 - } 100 - 101 - static void hibmc_user_framebuffer_destroy(struct drm_framebuffer *fb) 102 - { 103 - struct hibmc_framebuffer *hibmc_fb = to_hibmc_framebuffer(fb); 104 - 105 - drm_gem_object_put_unlocked(hibmc_fb->obj); 106 - drm_framebuffer_cleanup(fb); 107 - kfree(hibmc_fb); 108 - } 109 - 110 - static const struct drm_framebuffer_funcs hibmc_fb_funcs = { 111 - .destroy = hibmc_user_framebuffer_destroy, 112 - }; 113 - 114 - struct hibmc_framebuffer * 115 - hibmc_framebuffer_init(struct drm_device *dev, 116 - const struct drm_mode_fb_cmd2 *mode_cmd, 117 - struct drm_gem_object *obj) 118 - { 119 - struct hibmc_framebuffer *hibmc_fb; 120 - int ret; 121 - 122 - hibmc_fb = kzalloc(sizeof(*hibmc_fb), GFP_KERNEL); 123 - if (!hibmc_fb) { 124 - DRM_ERROR("failed to allocate hibmc_fb\n"); 125 - return ERR_PTR(-ENOMEM); 126 - } 127 - 128 - drm_helper_mode_fill_fb_struct(dev, &hibmc_fb->fb, mode_cmd); 129 - hibmc_fb->obj = obj; 130 - ret = drm_framebuffer_init(dev, &hibmc_fb->fb, &hibmc_fb_funcs); 131 - if (ret) { 132 - DRM_ERROR("drm_framebuffer_init failed: %d\n", ret); 133 - kfree(hibmc_fb); 134 - return ERR_PTR(ret); 135 - } 136 - 137 - return hibmc_fb; 138 - } 139 - 140 - static struct drm_framebuffer * 141 - hibmc_user_framebuffer_create(struct drm_device *dev, 142 - struct drm_file *filp, 143 - const struct drm_mode_fb_cmd2 *mode_cmd) 144 - { 145 - struct drm_gem_object *obj; 146 - struct hibmc_framebuffer *hibmc_fb; 147 - 148 - DRM_DEBUG_DRIVER("%dx%d, format %c%c%c%c\n", 149 - mode_cmd->width, mode_cmd->height, 150 - (mode_cmd->pixel_format) & 0xff, 151 - (mode_cmd->pixel_format >> 8) & 0xff, 152 - (mode_cmd->pixel_format >> 16) & 0xff, 153 - (mode_cmd->pixel_format >> 24) & 0xff); 154 - 155 - obj = drm_gem_object_lookup(filp, mode_cmd->handles[0]); 156 - if (!obj) 157 - return ERR_PTR(-ENOENT); 158 - 159 - hibmc_fb = hibmc_framebuffer_init(dev, mode_cmd, obj); 160 - if (IS_ERR(hibmc_fb)) { 161 - drm_gem_object_put_unlocked(obj); 162 - return ERR_PTR((long)hibmc_fb); 163 - } 164 - return &hibmc_fb->fb; 52 + return drm_gem_vram_fill_create_dumb(file, dev, 0, 16, args); 165 53 } 166 54 167 55 const struct drm_mode_config_funcs hibmc_mode_funcs = { 168 56 .atomic_check = drm_atomic_helper_check, 169 57 .atomic_commit = drm_atomic_helper_commit, 170 - .fb_create = hibmc_user_framebuffer_create, 58 + .fb_create = drm_gem_fb_create, 171 59 };
+1 -1
drivers/gpu/drm/meson/meson_crtc.c
··· 413 413 MESON_CANVAS_WRAP_NONE, 414 414 MESON_CANVAS_BLKMODE_LINEAR, 415 415 MESON_CANVAS_ENDIAN_SWAP64); 416 - }; 416 + } 417 417 418 418 writel_relaxed(priv->viu.vd1_if0_gen_reg, 419 419 priv->io_base + meson_crtc->viu_offset +
+1 -1
drivers/gpu/drm/meson/meson_plane.c
··· 237 237 /* For ARGB, use the pixel's alpha */ 238 238 priv->viu.osd1_ctrl_stat2 &= ~OSD_REPLACE_EN; 239 239 break; 240 - }; 240 + } 241 241 242 242 /* Default scaler parameters */ 243 243 vsc_bot_rcv_num = 0;
+1 -2
drivers/gpu/drm/mgag200/mgag200_cursor.c
··· 208 208 return -ENOMEM; 209 209 210 210 for (i = 0; i < ncursors; ++i) { 211 - gbo = drm_gem_vram_create(dev, &dev->vram_mm->bdev, 212 - size, 0, false); 211 + gbo = drm_gem_vram_create(dev, size, 0); 213 212 if (IS_ERR(gbo)) { 214 213 ret = PTR_ERR(gbo); 215 214 goto err_drm_gem_vram_put;
+15 -2
drivers/gpu/drm/mgag200/mgag200_drv.c
··· 27 27 MODULE_PARM_DESC(modeset, "Disable/Enable modesetting"); 28 28 module_param_named(modeset, mgag200_modeset, int, 0400); 29 29 30 + int mgag200_hw_bug_no_startadd = -1; 31 + MODULE_PARM_DESC(modeset, "HW does not interpret scanout-buffer start address correctly"); 32 + module_param_named(hw_bug_no_startadd, mgag200_hw_bug_no_startadd, int, 0400); 33 + 30 34 static struct drm_driver driver; 31 35 32 36 static const struct pci_device_id pciidlist[] = { ··· 101 97 102 98 static bool mgag200_pin_bo_at_0(const struct mga_device *mdev) 103 99 { 100 + if (mgag200_hw_bug_no_startadd > 0) { 101 + DRM_WARN_ONCE("Option hw_bug_no_startradd is enabled. Please " 102 + "report the output of 'lspci -vvnn' to " 103 + "<dri-devel@lists.freedesktop.org> if this " 104 + "option is required to make mgag200 work " 105 + "correctly on your system.\n"); 106 + return true; 107 + } else if (!mgag200_hw_bug_no_startadd) { 108 + return false; 109 + } 104 110 return mdev->flags & MGAG200_FLAG_HW_BUG_NO_STARTADD; 105 111 } 106 112 ··· 134 120 if (mgag200_pin_bo_at_0(mdev)) 135 121 pg_align = PFN_UP(mdev->mc.vram_size); 136 122 137 - return drm_gem_vram_fill_create_dumb(file, dev, &dev->vram_mm->bdev, 138 - pg_align, false, args); 123 + return drm_gem_vram_fill_create_dumb(file, dev, pg_align, 0, args); 139 124 } 140 125 141 126 static struct drm_driver driver = {
+21
drivers/gpu/drm/panel/Kconfig
··· 109 109 24 bit RGB per pixel. It provides a MIPI DSI interface to 110 110 the host and has a built-in LED backlight. 111 111 112 + config DRM_PANEL_LEADTEK_LTK500HD1829 113 + tristate "Leadtek LTK500HD1829 panel" 114 + depends on OF 115 + depends on DRM_MIPI_DSI 116 + depends on BACKLIGHT_CLASS_DEVICE 117 + help 118 + Say Y here if you want to enable support for Kingdisplay kd097d04 119 + TFT-LCD modules. The panel has a 1536x2048 resolution and uses 120 + 24 bit RGB per pixel. It provides a MIPI DSI interface to 121 + the host and has a built-in LED backlight. 122 + 112 123 config DRM_PANEL_SAMSUNG_LD9040 113 124 tristate "Samsung LD9040 RGB/SPI panel" 114 125 depends on OF && SPI ··· 377 366 help 378 367 Say Y here if you want to enable support for Truly NT35597 WQXGA Dual DSI 379 368 Video Mode panel 369 + 370 + config DRM_PANEL_XINPENG_XPP055C272 371 + tristate "Xinpeng XPP055C272 panel driver" 372 + depends on OF 373 + depends on DRM_MIPI_DSI 374 + depends on BACKLIGHT_CLASS_DEVICE 375 + help 376 + Say Y here if you want to enable support for the Xinpeng 377 + XPP055C272 controller for 720x1280 LCD panels with MIPI/RGB/SPI 378 + system interfaces. 380 379 endmenu
+2
drivers/gpu/drm/panel/Makefile
··· 9 9 obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o 10 10 obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o 11 11 obj-$(CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04) += panel-kingdisplay-kd097d04.o 12 + obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829) += panel-leadtek-ltk500hd1829.o 12 13 obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o 13 14 obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o 14 15 obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o ··· 40 39 obj-$(CONFIG_DRM_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o 41 40 obj-$(CONFIG_DRM_PANEL_TPO_TPG110) += panel-tpo-tpg110.o 42 41 obj-$(CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA) += panel-truly-nt35597.o 42 + obj-$(CONFIG_DRM_PANEL_XINPENG_XPP055C272) += panel-xinpeng-xpp055c272.o
+531
drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Copyright (c) 2019 Theobroma Systems Design und Consulting GmbH 4 + * 5 + * base on panel-kingdisplay-kd097d04.c 6 + * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd 7 + */ 8 + 9 + #include <linux/backlight.h> 10 + #include <linux/delay.h> 11 + #include <linux/gpio/consumer.h> 12 + #include <linux/module.h> 13 + #include <linux/of.h> 14 + #include <linux/regulator/consumer.h> 15 + 16 + #include <video/mipi_display.h> 17 + 18 + #include <drm/drm_crtc.h> 19 + #include <drm/drm_device.h> 20 + #include <drm/drm_mipi_dsi.h> 21 + #include <drm/drm_modes.h> 22 + #include <drm/drm_panel.h> 23 + #include <drm/drm_print.h> 24 + 25 + struct ltk500hd1829 { 26 + struct device *dev; 27 + struct drm_panel panel; 28 + struct gpio_desc *reset_gpio; 29 + struct regulator *vcc; 30 + struct regulator *iovcc; 31 + bool prepared; 32 + }; 33 + 34 + struct ltk500hd1829_cmd { 35 + char cmd; 36 + char data; 37 + }; 38 + 39 + /* 40 + * There is no description in the Reference Manual about these commands. 41 + * We received them from the vendor, so just use them as is. 42 + */ 43 + static const struct ltk500hd1829_cmd init_code[] = { 44 + { 0xE0, 0x00 }, 45 + { 0xE1, 0x93 }, 46 + { 0xE2, 0x65 }, 47 + { 0xE3, 0xF8 }, 48 + { 0x80, 0x03 }, 49 + { 0xE0, 0x04 }, 50 + { 0x2D, 0x03 }, 51 + { 0xE0, 0x01 }, 52 + { 0x00, 0x00 }, 53 + { 0x01, 0xB6 }, 54 + { 0x03, 0x00 }, 55 + { 0x04, 0xC5 }, 56 + { 0x17, 0x00 }, 57 + { 0x18, 0xBF }, 58 + { 0x19, 0x01 }, 59 + { 0x1A, 0x00 }, 60 + { 0x1B, 0xBF }, 61 + { 0x1C, 0x01 }, 62 + { 0x1F, 0x7C }, 63 + { 0x20, 0x26 }, 64 + { 0x21, 0x26 }, 65 + { 0x22, 0x4E }, 66 + { 0x37, 0x09 }, 67 + { 0x38, 0x04 }, 68 + { 0x39, 0x08 }, 69 + { 0x3A, 0x1F }, 70 + { 0x3B, 0x1F }, 71 + { 0x3C, 0x78 }, 72 + { 0x3D, 0xFF }, 73 + { 0x3E, 0xFF }, 74 + { 0x3F, 0x00 }, 75 + { 0x40, 0x04 }, 76 + { 0x41, 0xA0 }, 77 + { 0x43, 0x0F }, 78 + { 0x44, 0x0A }, 79 + { 0x45, 0x24 }, 80 + { 0x55, 0x01 }, 81 + { 0x56, 0x01 }, 82 + { 0x57, 0xA5 }, 83 + { 0x58, 0x0A }, 84 + { 0x59, 0x4A }, 85 + { 0x5A, 0x38 }, 86 + { 0x5B, 0x10 }, 87 + { 0x5C, 0x19 }, 88 + { 0x5D, 0x7C }, 89 + { 0x5E, 0x64 }, 90 + { 0x5F, 0x54 }, 91 + { 0x60, 0x48 }, 92 + { 0x61, 0x44 }, 93 + { 0x62, 0x35 }, 94 + { 0x63, 0x3A }, 95 + { 0x64, 0x24 }, 96 + { 0x65, 0x3B }, 97 + { 0x66, 0x39 }, 98 + { 0x67, 0x37 }, 99 + { 0x68, 0x56 }, 100 + { 0x69, 0x41 }, 101 + { 0x6A, 0x47 }, 102 + { 0x6B, 0x2F }, 103 + { 0x6C, 0x23 }, 104 + { 0x6D, 0x13 }, 105 + { 0x6E, 0x02 }, 106 + { 0x6F, 0x08 }, 107 + { 0x70, 0x7C }, 108 + { 0x71, 0x64 }, 109 + { 0x72, 0x54 }, 110 + { 0x73, 0x48 }, 111 + { 0x74, 0x44 }, 112 + { 0x75, 0x35 }, 113 + { 0x76, 0x3A }, 114 + { 0x77, 0x22 }, 115 + { 0x78, 0x3B }, 116 + { 0x79, 0x39 }, 117 + { 0x7A, 0x38 }, 118 + { 0x7B, 0x52 }, 119 + { 0x7C, 0x41 }, 120 + { 0x7D, 0x47 }, 121 + { 0x7E, 0x2F }, 122 + { 0x7F, 0x23 }, 123 + { 0x80, 0x13 }, 124 + { 0x81, 0x02 }, 125 + { 0x82, 0x08 }, 126 + { 0xE0, 0x02 }, 127 + { 0x00, 0x57 }, 128 + { 0x01, 0x77 }, 129 + { 0x02, 0x44 }, 130 + { 0x03, 0x46 }, 131 + { 0x04, 0x48 }, 132 + { 0x05, 0x4A }, 133 + { 0x06, 0x4C }, 134 + { 0x07, 0x4E }, 135 + { 0x08, 0x50 }, 136 + { 0x09, 0x55 }, 137 + { 0x0A, 0x52 }, 138 + { 0x0B, 0x55 }, 139 + { 0x0C, 0x55 }, 140 + { 0x0D, 0x55 }, 141 + { 0x0E, 0x55 }, 142 + { 0x0F, 0x55 }, 143 + { 0x10, 0x55 }, 144 + { 0x11, 0x55 }, 145 + { 0x12, 0x55 }, 146 + { 0x13, 0x40 }, 147 + { 0x14, 0x55 }, 148 + { 0x15, 0x55 }, 149 + { 0x16, 0x57 }, 150 + { 0x17, 0x77 }, 151 + { 0x18, 0x45 }, 152 + { 0x19, 0x47 }, 153 + { 0x1A, 0x49 }, 154 + { 0x1B, 0x4B }, 155 + { 0x1C, 0x4D }, 156 + { 0x1D, 0x4F }, 157 + { 0x1E, 0x51 }, 158 + { 0x1F, 0x55 }, 159 + { 0x20, 0x53 }, 160 + { 0x21, 0x55 }, 161 + { 0x22, 0x55 }, 162 + { 0x23, 0x55 }, 163 + { 0x24, 0x55 }, 164 + { 0x25, 0x55 }, 165 + { 0x26, 0x55 }, 166 + { 0x27, 0x55 }, 167 + { 0x28, 0x55 }, 168 + { 0x29, 0x41 }, 169 + { 0x2A, 0x55 }, 170 + { 0x2B, 0x55 }, 171 + { 0x2C, 0x57 }, 172 + { 0x2D, 0x77 }, 173 + { 0x2E, 0x4F }, 174 + { 0x2F, 0x4D }, 175 + { 0x30, 0x4B }, 176 + { 0x31, 0x49 }, 177 + { 0x32, 0x47 }, 178 + { 0x33, 0x45 }, 179 + { 0x34, 0x41 }, 180 + { 0x35, 0x55 }, 181 + { 0x36, 0x53 }, 182 + { 0x37, 0x55 }, 183 + { 0x38, 0x55 }, 184 + { 0x39, 0x55 }, 185 + { 0x3A, 0x55 }, 186 + { 0x3B, 0x55 }, 187 + { 0x3C, 0x55 }, 188 + { 0x3D, 0x55 }, 189 + { 0x3E, 0x55 }, 190 + { 0x3F, 0x51 }, 191 + { 0x40, 0x55 }, 192 + { 0x41, 0x55 }, 193 + { 0x42, 0x57 }, 194 + { 0x43, 0x77 }, 195 + { 0x44, 0x4E }, 196 + { 0x45, 0x4C }, 197 + { 0x46, 0x4A }, 198 + { 0x47, 0x48 }, 199 + { 0x48, 0x46 }, 200 + { 0x49, 0x44 }, 201 + { 0x4A, 0x40 }, 202 + { 0x4B, 0x55 }, 203 + { 0x4C, 0x52 }, 204 + { 0x4D, 0x55 }, 205 + { 0x4E, 0x55 }, 206 + { 0x4F, 0x55 }, 207 + { 0x50, 0x55 }, 208 + { 0x51, 0x55 }, 209 + { 0x52, 0x55 }, 210 + { 0x53, 0x55 }, 211 + { 0x54, 0x55 }, 212 + { 0x55, 0x50 }, 213 + { 0x56, 0x55 }, 214 + { 0x57, 0x55 }, 215 + { 0x58, 0x40 }, 216 + { 0x59, 0x00 }, 217 + { 0x5A, 0x00 }, 218 + { 0x5B, 0x10 }, 219 + { 0x5C, 0x09 }, 220 + { 0x5D, 0x30 }, 221 + { 0x5E, 0x01 }, 222 + { 0x5F, 0x02 }, 223 + { 0x60, 0x30 }, 224 + { 0x61, 0x03 }, 225 + { 0x62, 0x04 }, 226 + { 0x63, 0x06 }, 227 + { 0x64, 0x6A }, 228 + { 0x65, 0x75 }, 229 + { 0x66, 0x0F }, 230 + { 0x67, 0xB3 }, 231 + { 0x68, 0x0B }, 232 + { 0x69, 0x06 }, 233 + { 0x6A, 0x6A }, 234 + { 0x6B, 0x10 }, 235 + { 0x6C, 0x00 }, 236 + { 0x6D, 0x04 }, 237 + { 0x6E, 0x04 }, 238 + { 0x6F, 0x88 }, 239 + { 0x70, 0x00 }, 240 + { 0x71, 0x00 }, 241 + { 0x72, 0x06 }, 242 + { 0x73, 0x7B }, 243 + { 0x74, 0x00 }, 244 + { 0x75, 0xBC }, 245 + { 0x76, 0x00 }, 246 + { 0x77, 0x05 }, 247 + { 0x78, 0x2E }, 248 + { 0x79, 0x00 }, 249 + { 0x7A, 0x00 }, 250 + { 0x7B, 0x00 }, 251 + { 0x7C, 0x00 }, 252 + { 0x7D, 0x03 }, 253 + { 0x7E, 0x7B }, 254 + { 0xE0, 0x04 }, 255 + { 0x09, 0x10 }, 256 + { 0x2B, 0x2B }, 257 + { 0x2E, 0x44 }, 258 + { 0xE0, 0x00 }, 259 + { 0xE6, 0x02 }, 260 + { 0xE7, 0x02 }, 261 + { 0x35, 0x00 }, 262 + }; 263 + 264 + static inline 265 + struct ltk500hd1829 *panel_to_ltk500hd1829(struct drm_panel *panel) 266 + { 267 + return container_of(panel, struct ltk500hd1829, panel); 268 + } 269 + 270 + static int ltk500hd1829_unprepare(struct drm_panel *panel) 271 + { 272 + struct ltk500hd1829 *ctx = panel_to_ltk500hd1829(panel); 273 + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 274 + int ret; 275 + 276 + if (!ctx->prepared) 277 + return 0; 278 + 279 + ret = mipi_dsi_dcs_set_display_off(dsi); 280 + if (ret < 0) 281 + DRM_DEV_ERROR(panel->dev, "failed to set display off: %d\n", 282 + ret); 283 + 284 + ret = mipi_dsi_dcs_enter_sleep_mode(dsi); 285 + if (ret < 0) { 286 + DRM_DEV_ERROR(panel->dev, "failed to enter sleep mode: %d\n", 287 + ret); 288 + } 289 + 290 + /* 120ms to enter sleep mode */ 291 + msleep(120); 292 + 293 + regulator_disable(ctx->iovcc); 294 + regulator_disable(ctx->vcc); 295 + 296 + ctx->prepared = false; 297 + 298 + return 0; 299 + } 300 + 301 + static int ltk500hd1829_prepare(struct drm_panel *panel) 302 + { 303 + struct ltk500hd1829 *ctx = panel_to_ltk500hd1829(panel); 304 + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 305 + unsigned int i; 306 + int ret; 307 + 308 + if (ctx->prepared) 309 + return 0; 310 + 311 + ret = regulator_enable(ctx->vcc); 312 + if (ret < 0) { 313 + DRM_DEV_ERROR(ctx->dev, 314 + "Failed to enable vci supply: %d\n", ret); 315 + return ret; 316 + } 317 + ret = regulator_enable(ctx->iovcc); 318 + if (ret < 0) { 319 + DRM_DEV_ERROR(ctx->dev, 320 + "Failed to enable iovcc supply: %d\n", ret); 321 + goto disable_vcc; 322 + } 323 + 324 + gpiod_set_value_cansleep(ctx->reset_gpio, 1); 325 + /* tRW: 10us */ 326 + usleep_range(10, 20); 327 + gpiod_set_value_cansleep(ctx->reset_gpio, 0); 328 + 329 + /* tRT: >= 5ms */ 330 + usleep_range(5000, 6000); 331 + 332 + for (i = 0; i < ARRAY_SIZE(init_code); i++) { 333 + ret = mipi_dsi_generic_write(dsi, &init_code[i], 334 + sizeof(struct ltk500hd1829_cmd)); 335 + if (ret < 0) { 336 + DRM_DEV_ERROR(panel->dev, 337 + "failed to write init cmds: %d\n", ret); 338 + goto disable_iovcc; 339 + } 340 + } 341 + 342 + ret = mipi_dsi_dcs_exit_sleep_mode(dsi); 343 + if (ret < 0) { 344 + DRM_DEV_ERROR(panel->dev, "failed to exit sleep mode: %d\n", 345 + ret); 346 + goto disable_iovcc; 347 + } 348 + 349 + /* 120ms to exit sleep mode */ 350 + msleep(120); 351 + 352 + ret = mipi_dsi_dcs_set_display_on(dsi); 353 + if (ret < 0) { 354 + DRM_DEV_ERROR(panel->dev, "failed to set display on: %d\n", 355 + ret); 356 + goto disable_iovcc; 357 + } 358 + 359 + ctx->prepared = true; 360 + 361 + return 0; 362 + 363 + disable_iovcc: 364 + regulator_disable(ctx->iovcc); 365 + disable_vcc: 366 + regulator_disable(ctx->vcc); 367 + return ret; 368 + } 369 + 370 + static const struct drm_display_mode default_mode = { 371 + .hdisplay = 720, 372 + .hsync_start = 720 + 50, 373 + .hsync_end = 720 + 50 + 50, 374 + .htotal = 720 + 50 + 50 + 50, 375 + .vdisplay = 1280, 376 + .vsync_start = 1280 + 30, 377 + .vsync_end = 1280 + 30 + 4, 378 + .vtotal = 1280 + 30 + 4 + 12, 379 + .vrefresh = 60, 380 + .clock = 41600, 381 + .width_mm = 62, 382 + .height_mm = 110, 383 + }; 384 + 385 + static int ltk500hd1829_get_modes(struct drm_panel *panel, 386 + struct drm_connector *connector) 387 + { 388 + struct ltk500hd1829 *ctx = panel_to_ltk500hd1829(panel); 389 + struct drm_display_mode *mode; 390 + 391 + mode = drm_mode_duplicate(connector->dev, &default_mode); 392 + if (!mode) { 393 + DRM_DEV_ERROR(ctx->dev, "failed to add mode %ux%ux@%u\n", 394 + default_mode.hdisplay, default_mode.vdisplay, 395 + default_mode.vrefresh); 396 + return -ENOMEM; 397 + } 398 + 399 + drm_mode_set_name(mode); 400 + 401 + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 402 + connector->display_info.width_mm = mode->width_mm; 403 + connector->display_info.height_mm = mode->height_mm; 404 + drm_mode_probed_add(connector, mode); 405 + 406 + return 1; 407 + } 408 + 409 + static const struct drm_panel_funcs ltk500hd1829_funcs = { 410 + .unprepare = ltk500hd1829_unprepare, 411 + .prepare = ltk500hd1829_prepare, 412 + .get_modes = ltk500hd1829_get_modes, 413 + }; 414 + 415 + static int ltk500hd1829_probe(struct mipi_dsi_device *dsi) 416 + { 417 + struct ltk500hd1829 *ctx; 418 + struct device *dev = &dsi->dev; 419 + int ret; 420 + 421 + ctx = devm_kzalloc(&dsi->dev, sizeof(*ctx), GFP_KERNEL); 422 + if (!ctx) 423 + return -ENOMEM; 424 + 425 + ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); 426 + if (IS_ERR(ctx->reset_gpio)) { 427 + DRM_DEV_ERROR(dev, "cannot get reset gpio\n"); 428 + return PTR_ERR(ctx->reset_gpio); 429 + } 430 + 431 + ctx->vcc = devm_regulator_get(dev, "vcc"); 432 + if (IS_ERR(ctx->vcc)) { 433 + ret = PTR_ERR(ctx->vcc); 434 + if (ret != -EPROBE_DEFER) 435 + DRM_DEV_ERROR(dev, 436 + "Failed to request vcc regulator: %d\n", 437 + ret); 438 + return ret; 439 + } 440 + 441 + ctx->iovcc = devm_regulator_get(dev, "iovcc"); 442 + if (IS_ERR(ctx->iovcc)) { 443 + ret = PTR_ERR(ctx->iovcc); 444 + if (ret != -EPROBE_DEFER) 445 + DRM_DEV_ERROR(dev, 446 + "Failed to request iovcc regulator: %d\n", 447 + ret); 448 + return ret; 449 + } 450 + 451 + mipi_dsi_set_drvdata(dsi, ctx); 452 + 453 + ctx->dev = dev; 454 + 455 + dsi->lanes = 4; 456 + dsi->format = MIPI_DSI_FMT_RGB888; 457 + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | 458 + MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET; 459 + 460 + drm_panel_init(&ctx->panel, &dsi->dev, &ltk500hd1829_funcs, 461 + DRM_MODE_CONNECTOR_DSI); 462 + 463 + ret = drm_panel_of_backlight(&ctx->panel); 464 + if (ret) 465 + return ret; 466 + 467 + drm_panel_add(&ctx->panel); 468 + 469 + ret = mipi_dsi_attach(dsi); 470 + if (ret < 0) { 471 + DRM_DEV_ERROR(dev, "mipi_dsi_attach failed: %d\n", ret); 472 + drm_panel_remove(&ctx->panel); 473 + return ret; 474 + } 475 + 476 + return 0; 477 + } 478 + 479 + static void ltk500hd1829_shutdown(struct mipi_dsi_device *dsi) 480 + { 481 + struct ltk500hd1829 *ctx = mipi_dsi_get_drvdata(dsi); 482 + int ret; 483 + 484 + ret = drm_panel_unprepare(&ctx->panel); 485 + if (ret < 0) 486 + DRM_DEV_ERROR(&dsi->dev, "Failed to unprepare panel: %d\n", 487 + ret); 488 + 489 + ret = drm_panel_disable(&ctx->panel); 490 + if (ret < 0) 491 + DRM_DEV_ERROR(&dsi->dev, "Failed to disable panel: %d\n", 492 + ret); 493 + } 494 + 495 + static int ltk500hd1829_remove(struct mipi_dsi_device *dsi) 496 + { 497 + struct ltk500hd1829 *ctx = mipi_dsi_get_drvdata(dsi); 498 + int ret; 499 + 500 + ltk500hd1829_shutdown(dsi); 501 + 502 + ret = mipi_dsi_detach(dsi); 503 + if (ret < 0) 504 + DRM_DEV_ERROR(&dsi->dev, "failed to detach from DSI host: %d\n", 505 + ret); 506 + 507 + drm_panel_remove(&ctx->panel); 508 + 509 + return 0; 510 + } 511 + 512 + static const struct of_device_id ltk500hd1829_of_match[] = { 513 + { .compatible = "leadtek,ltk500hd1829", }, 514 + { /* sentinel */ } 515 + }; 516 + MODULE_DEVICE_TABLE(of, ltk500hd1829_of_match); 517 + 518 + static struct mipi_dsi_driver ltk500hd1829_driver = { 519 + .driver = { 520 + .name = "panel-leadtek-ltk500hd1829", 521 + .of_match_table = ltk500hd1829_of_match, 522 + }, 523 + .probe = ltk500hd1829_probe, 524 + .remove = ltk500hd1829_remove, 525 + .shutdown = ltk500hd1829_shutdown, 526 + }; 527 + module_mipi_dsi_driver(ltk500hd1829_driver); 528 + 529 + MODULE_AUTHOR("Heiko Stuebner <heiko.stuebner@theobroma-systems.com>"); 530 + MODULE_DESCRIPTION("Leadtek LTK500HD1829 panel driver"); 531 + MODULE_LICENSE("GPL v2");
+398
drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Xinpeng xpp055c272 5.5" MIPI-DSI panel driver 4 + * Copyright (C) 2019 Theobroma Systems Design und Consulting GmbH 5 + * 6 + * based on 7 + * 8 + * Rockteck jh057n00900 5.5" MIPI-DSI panel driver 9 + * Copyright (C) Purism SPC 2019 10 + */ 11 + 12 + #include <drm/drm_mipi_dsi.h> 13 + #include <drm/drm_modes.h> 14 + #include <drm/drm_panel.h> 15 + #include <drm/drm_print.h> 16 + 17 + #include <video/display_timing.h> 18 + #include <video/mipi_display.h> 19 + 20 + #include <linux/delay.h> 21 + #include <linux/gpio/consumer.h> 22 + #include <linux/media-bus-format.h> 23 + #include <linux/module.h> 24 + #include <linux/of.h> 25 + #include <linux/regulator/consumer.h> 26 + 27 + /* Manufacturer specific Commands send via DSI */ 28 + #define XPP055C272_CMD_ALL_PIXEL_OFF 0x22 29 + #define XPP055C272_CMD_ALL_PIXEL_ON 0x23 30 + #define XPP055C272_CMD_SETDISP 0xb2 31 + #define XPP055C272_CMD_SETRGBIF 0xb3 32 + #define XPP055C272_CMD_SETCYC 0xb4 33 + #define XPP055C272_CMD_SETBGP 0xb5 34 + #define XPP055C272_CMD_SETVCOM 0xb6 35 + #define XPP055C272_CMD_SETOTP 0xb7 36 + #define XPP055C272_CMD_SETPOWER_EXT 0xb8 37 + #define XPP055C272_CMD_SETEXTC 0xb9 38 + #define XPP055C272_CMD_SETMIPI 0xbA 39 + #define XPP055C272_CMD_SETVDC 0xbc 40 + #define XPP055C272_CMD_SETPCR 0xbf 41 + #define XPP055C272_CMD_SETSCR 0xc0 42 + #define XPP055C272_CMD_SETPOWER 0xc1 43 + #define XPP055C272_CMD_SETECO 0xc6 44 + #define XPP055C272_CMD_SETPANEL 0xcc 45 + #define XPP055C272_CMD_SETGAMMA 0xe0 46 + #define XPP055C272_CMD_SETEQ 0xe3 47 + #define XPP055C272_CMD_SETGIP1 0xe9 48 + #define XPP055C272_CMD_SETGIP2 0xea 49 + 50 + struct xpp055c272 { 51 + struct device *dev; 52 + struct drm_panel panel; 53 + struct gpio_desc *reset_gpio; 54 + struct regulator *vci; 55 + struct regulator *iovcc; 56 + bool prepared; 57 + }; 58 + 59 + static inline struct xpp055c272 *panel_to_xpp055c272(struct drm_panel *panel) 60 + { 61 + return container_of(panel, struct xpp055c272, panel); 62 + } 63 + 64 + #define dsi_generic_write_seq(dsi, cmd, seq...) do { \ 65 + static const u8 d[] = { seq }; \ 66 + int ret; \ 67 + ret = mipi_dsi_dcs_write(dsi, cmd, d, ARRAY_SIZE(d)); \ 68 + if (ret < 0) \ 69 + return ret; \ 70 + } while (0) 71 + 72 + static int xpp055c272_init_sequence(struct xpp055c272 *ctx) 73 + { 74 + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 75 + struct device *dev = ctx->dev; 76 + 77 + /* 78 + * Init sequence was supplied by the panel vendor without much 79 + * documentation. 80 + */ 81 + dsi_generic_write_seq(dsi, XPP055C272_CMD_SETEXTC, 0xf1, 0x12, 0x83); 82 + dsi_generic_write_seq(dsi, XPP055C272_CMD_SETMIPI, 83 + 0x33, 0x81, 0x05, 0xf9, 0x0e, 0x0e, 0x00, 0x00, 84 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x25, 85 + 0x00, 0x91, 0x0a, 0x00, 0x00, 0x02, 0x4f, 0x01, 86 + 0x00, 0x00, 0x37); 87 + dsi_generic_write_seq(dsi, XPP055C272_CMD_SETPOWER_EXT, 0x25); 88 + dsi_generic_write_seq(dsi, XPP055C272_CMD_SETPCR, 0x02, 0x11, 0x00); 89 + dsi_generic_write_seq(dsi, XPP055C272_CMD_SETRGBIF, 90 + 0x0c, 0x10, 0x0a, 0x50, 0x03, 0xff, 0x00, 0x00, 91 + 0x00, 0x00); 92 + dsi_generic_write_seq(dsi, XPP055C272_CMD_SETSCR, 93 + 0x73, 0x73, 0x50, 0x50, 0x00, 0x00, 0x08, 0x70, 94 + 0x00); 95 + dsi_generic_write_seq(dsi, XPP055C272_CMD_SETVDC, 0x46); 96 + dsi_generic_write_seq(dsi, XPP055C272_CMD_SETPANEL, 0x0b); 97 + dsi_generic_write_seq(dsi, XPP055C272_CMD_SETCYC, 0x80); 98 + dsi_generic_write_seq(dsi, XPP055C272_CMD_SETDISP, 0xc8, 0x12, 0x30); 99 + dsi_generic_write_seq(dsi, XPP055C272_CMD_SETEQ, 100 + 0x07, 0x07, 0x0B, 0x0B, 0x03, 0x0B, 0x00, 0x00, 101 + 0x00, 0x00, 0xFF, 0x00, 0xC0, 0x10); 102 + dsi_generic_write_seq(dsi, XPP055C272_CMD_SETPOWER, 103 + 0x53, 0x00, 0x1e, 0x1e, 0x77, 0xe1, 0xcc, 0xdd, 104 + 0x67, 0x77, 0x33, 0x33); 105 + dsi_generic_write_seq(dsi, XPP055C272_CMD_SETECO, 0x00, 0x00, 0xff, 106 + 0xff, 0x01, 0xff); 107 + dsi_generic_write_seq(dsi, XPP055C272_CMD_SETBGP, 0x09, 0x09); 108 + msleep(20); 109 + 110 + dsi_generic_write_seq(dsi, XPP055C272_CMD_SETVCOM, 0x87, 0x95); 111 + dsi_generic_write_seq(dsi, XPP055C272_CMD_SETGIP1, 112 + 0xc2, 0x10, 0x05, 0x05, 0x10, 0x05, 0xa0, 0x12, 113 + 0x31, 0x23, 0x3f, 0x81, 0x0a, 0xa0, 0x37, 0x18, 114 + 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 115 + 0x01, 0x00, 0x00, 0x00, 0x48, 0xf8, 0x86, 0x42, 116 + 0x08, 0x88, 0x88, 0x80, 0x88, 0x88, 0x88, 0x58, 117 + 0xf8, 0x87, 0x53, 0x18, 0x88, 0x88, 0x81, 0x88, 118 + 0x88, 0x88, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 119 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 120 + dsi_generic_write_seq(dsi, XPP055C272_CMD_SETGIP2, 121 + 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 122 + 0x00, 0x00, 0x00, 0x00, 0x1f, 0x88, 0x81, 0x35, 123 + 0x78, 0x88, 0x88, 0x85, 0x88, 0x88, 0x88, 0x0f, 124 + 0x88, 0x80, 0x24, 0x68, 0x88, 0x88, 0x84, 0x88, 125 + 0x88, 0x88, 0x23, 0x10, 0x00, 0x00, 0x1c, 0x00, 126 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 127 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x05, 128 + 0xa0, 0x00, 0x00, 0x00, 0x00); 129 + dsi_generic_write_seq(dsi, XPP055C272_CMD_SETGAMMA, 130 + 0x00, 0x06, 0x08, 0x2a, 0x31, 0x3f, 0x38, 0x36, 131 + 0x07, 0x0c, 0x0d, 0x11, 0x13, 0x12, 0x13, 0x11, 132 + 0x18, 0x00, 0x06, 0x08, 0x2a, 0x31, 0x3f, 0x38, 133 + 0x36, 0x07, 0x0c, 0x0d, 0x11, 0x13, 0x12, 0x13, 134 + 0x11, 0x18); 135 + 136 + msleep(60); 137 + 138 + DRM_DEV_DEBUG_DRIVER(dev, "Panel init sequence done\n"); 139 + return 0; 140 + } 141 + 142 + static int xpp055c272_unprepare(struct drm_panel *panel) 143 + { 144 + struct xpp055c272 *ctx = panel_to_xpp055c272(panel); 145 + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 146 + int ret; 147 + 148 + if (!ctx->prepared) 149 + return 0; 150 + 151 + ret = mipi_dsi_dcs_set_display_off(dsi); 152 + if (ret < 0) 153 + DRM_DEV_ERROR(ctx->dev, "failed to set display off: %d\n", 154 + ret); 155 + 156 + mipi_dsi_dcs_enter_sleep_mode(dsi); 157 + if (ret < 0) { 158 + DRM_DEV_ERROR(ctx->dev, "failed to enter sleep mode: %d\n", 159 + ret); 160 + return ret; 161 + } 162 + 163 + regulator_disable(ctx->iovcc); 164 + regulator_disable(ctx->vci); 165 + 166 + ctx->prepared = false; 167 + 168 + return 0; 169 + } 170 + 171 + static int xpp055c272_prepare(struct drm_panel *panel) 172 + { 173 + struct xpp055c272 *ctx = panel_to_xpp055c272(panel); 174 + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 175 + int ret; 176 + 177 + if (ctx->prepared) 178 + return 0; 179 + 180 + DRM_DEV_DEBUG_DRIVER(ctx->dev, "Resetting the panel\n"); 181 + ret = regulator_enable(ctx->vci); 182 + if (ret < 0) { 183 + DRM_DEV_ERROR(ctx->dev, 184 + "Failed to enable vci supply: %d\n", ret); 185 + return ret; 186 + } 187 + ret = regulator_enable(ctx->iovcc); 188 + if (ret < 0) { 189 + DRM_DEV_ERROR(ctx->dev, 190 + "Failed to enable iovcc supply: %d\n", ret); 191 + goto disable_vci; 192 + } 193 + 194 + gpiod_set_value_cansleep(ctx->reset_gpio, 1); 195 + /* T6: 10us */ 196 + usleep_range(10, 20); 197 + gpiod_set_value_cansleep(ctx->reset_gpio, 0); 198 + 199 + /* T8: 20ms */ 200 + msleep(20); 201 + 202 + ret = xpp055c272_init_sequence(ctx); 203 + if (ret < 0) { 204 + DRM_DEV_ERROR(ctx->dev, "Panel init sequence failed: %d\n", 205 + ret); 206 + goto disable_iovcc; 207 + } 208 + 209 + ret = mipi_dsi_dcs_exit_sleep_mode(dsi); 210 + if (ret < 0) { 211 + DRM_DEV_ERROR(ctx->dev, "Failed to exit sleep mode: %d\n", ret); 212 + goto disable_iovcc; 213 + } 214 + 215 + /* T9: 120ms */ 216 + msleep(120); 217 + 218 + ret = mipi_dsi_dcs_set_display_on(dsi); 219 + if (ret < 0) { 220 + DRM_DEV_ERROR(ctx->dev, "Failed to set display on: %d\n", ret); 221 + goto disable_iovcc; 222 + } 223 + 224 + msleep(50); 225 + 226 + ctx->prepared = true; 227 + 228 + return 0; 229 + 230 + disable_iovcc: 231 + regulator_disable(ctx->iovcc); 232 + disable_vci: 233 + regulator_disable(ctx->vci); 234 + return ret; 235 + } 236 + 237 + static const struct drm_display_mode default_mode = { 238 + .hdisplay = 720, 239 + .hsync_start = 720 + 40, 240 + .hsync_end = 720 + 40 + 10, 241 + .htotal = 720 + 40 + 10 + 40, 242 + .vdisplay = 1280, 243 + .vsync_start = 1280 + 22, 244 + .vsync_end = 1280 + 22 + 4, 245 + .vtotal = 1280 + 22 + 4 + 11, 246 + .vrefresh = 60, 247 + .clock = 64000, 248 + .width_mm = 68, 249 + .height_mm = 121, 250 + }; 251 + 252 + static int xpp055c272_get_modes(struct drm_panel *panel, 253 + struct drm_connector *connector) 254 + { 255 + struct xpp055c272 *ctx = panel_to_xpp055c272(panel); 256 + struct drm_display_mode *mode; 257 + 258 + mode = drm_mode_duplicate(connector->dev, &default_mode); 259 + if (!mode) { 260 + DRM_DEV_ERROR(ctx->dev, "Failed to add mode %ux%u@%u\n", 261 + default_mode.hdisplay, default_mode.vdisplay, 262 + default_mode.vrefresh); 263 + return -ENOMEM; 264 + } 265 + 266 + drm_mode_set_name(mode); 267 + 268 + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 269 + connector->display_info.width_mm = mode->width_mm; 270 + connector->display_info.height_mm = mode->height_mm; 271 + drm_mode_probed_add(connector, mode); 272 + 273 + return 1; 274 + } 275 + 276 + static const struct drm_panel_funcs xpp055c272_funcs = { 277 + .unprepare = xpp055c272_unprepare, 278 + .prepare = xpp055c272_prepare, 279 + .get_modes = xpp055c272_get_modes, 280 + }; 281 + 282 + static int xpp055c272_probe(struct mipi_dsi_device *dsi) 283 + { 284 + struct device *dev = &dsi->dev; 285 + struct xpp055c272 *ctx; 286 + int ret; 287 + 288 + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); 289 + if (!ctx) 290 + return -ENOMEM; 291 + 292 + ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); 293 + if (IS_ERR(ctx->reset_gpio)) { 294 + DRM_DEV_ERROR(dev, "cannot get reset gpio\n"); 295 + return PTR_ERR(ctx->reset_gpio); 296 + } 297 + 298 + ctx->vci = devm_regulator_get(dev, "vci"); 299 + if (IS_ERR(ctx->vci)) { 300 + ret = PTR_ERR(ctx->vci); 301 + if (ret != -EPROBE_DEFER) 302 + DRM_DEV_ERROR(dev, 303 + "Failed to request vci regulator: %d\n", 304 + ret); 305 + return ret; 306 + } 307 + 308 + ctx->iovcc = devm_regulator_get(dev, "iovcc"); 309 + if (IS_ERR(ctx->iovcc)) { 310 + ret = PTR_ERR(ctx->iovcc); 311 + if (ret != -EPROBE_DEFER) 312 + DRM_DEV_ERROR(dev, 313 + "Failed to request iovcc regulator: %d\n", 314 + ret); 315 + return ret; 316 + } 317 + 318 + mipi_dsi_set_drvdata(dsi, ctx); 319 + 320 + ctx->dev = dev; 321 + 322 + dsi->lanes = 4; 323 + dsi->format = MIPI_DSI_FMT_RGB888; 324 + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | 325 + MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET; 326 + 327 + drm_panel_init(&ctx->panel, &dsi->dev, &xpp055c272_funcs, 328 + DRM_MODE_CONNECTOR_DSI); 329 + 330 + ret = drm_panel_of_backlight(&ctx->panel); 331 + if (ret) 332 + return ret; 333 + 334 + drm_panel_add(&ctx->panel); 335 + 336 + ret = mipi_dsi_attach(dsi); 337 + if (ret < 0) { 338 + DRM_DEV_ERROR(dev, "mipi_dsi_attach failed: %d\n", ret); 339 + drm_panel_remove(&ctx->panel); 340 + return ret; 341 + } 342 + 343 + return 0; 344 + } 345 + 346 + static void xpp055c272_shutdown(struct mipi_dsi_device *dsi) 347 + { 348 + struct xpp055c272 *ctx = mipi_dsi_get_drvdata(dsi); 349 + int ret; 350 + 351 + ret = drm_panel_unprepare(&ctx->panel); 352 + if (ret < 0) 353 + DRM_DEV_ERROR(&dsi->dev, "Failed to unprepare panel: %d\n", 354 + ret); 355 + 356 + ret = drm_panel_disable(&ctx->panel); 357 + if (ret < 0) 358 + DRM_DEV_ERROR(&dsi->dev, "Failed to disable panel: %d\n", 359 + ret); 360 + } 361 + 362 + static int xpp055c272_remove(struct mipi_dsi_device *dsi) 363 + { 364 + struct xpp055c272 *ctx = mipi_dsi_get_drvdata(dsi); 365 + int ret; 366 + 367 + xpp055c272_shutdown(dsi); 368 + 369 + ret = mipi_dsi_detach(dsi); 370 + if (ret < 0) 371 + DRM_DEV_ERROR(&dsi->dev, "Failed to detach from DSI host: %d\n", 372 + ret); 373 + 374 + drm_panel_remove(&ctx->panel); 375 + 376 + return 0; 377 + } 378 + 379 + static const struct of_device_id xpp055c272_of_match[] = { 380 + { .compatible = "xinpeng,xpp055c272" }, 381 + { /* sentinel */ } 382 + }; 383 + MODULE_DEVICE_TABLE(of, xpp055c272_of_match); 384 + 385 + static struct mipi_dsi_driver xpp055c272_driver = { 386 + .driver = { 387 + .name = "panel-xinpeng-xpp055c272", 388 + .of_match_table = xpp055c272_of_match, 389 + }, 390 + .probe = xpp055c272_probe, 391 + .remove = xpp055c272_remove, 392 + .shutdown = xpp055c272_shutdown, 393 + }; 394 + module_mipi_dsi_driver(xpp055c272_driver); 395 + 396 + MODULE_AUTHOR("Heiko Stuebner <heiko.stuebner@theobroma-systems.com>"); 397 + MODULE_DESCRIPTION("DRM driver for Xinpeng xpp055c272 MIPI DSI panel"); 398 + MODULE_LICENSE("GPL v2");
+5 -3
drivers/gpu/drm/rcar-du/rcar_lvds.c
··· 590 590 } 591 591 592 592 static void rcar_lvds_atomic_enable(struct drm_bridge *bridge, 593 - struct drm_atomic_state *state) 593 + struct drm_bridge_state *old_bridge_state) 594 594 { 595 + struct drm_atomic_state *state = old_bridge_state->base.state; 595 596 struct drm_connector *connector; 596 597 struct drm_crtc *crtc; 597 598 ··· 604 603 } 605 604 606 605 static void rcar_lvds_atomic_disable(struct drm_bridge *bridge, 607 - struct drm_atomic_state *state) 606 + struct drm_bridge_state *old_bridge_state) 608 607 { 609 608 struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge); 610 609 ··· 619 618 620 619 /* Disable the companion LVDS encoder in dual-link mode. */ 621 620 if (lvds->link_type != RCAR_LVDS_SINGLE_LINK && lvds->companion) 622 - lvds->companion->funcs->atomic_disable(lvds->companion, state); 621 + lvds->companion->funcs->atomic_disable(lvds->companion, 622 + old_bridge_state); 623 623 624 624 clk_disable_unprepare(lvds->clocks.mod); 625 625 }
+3
drivers/gpu/drm/rockchip/rk3066_hdmi.c
··· 641 641 if (msgs->addr == DDC_ADDR) 642 642 hdmi->i2c->ddc_addr = msgs->buf[0]; 643 643 644 + /* Set edid fifo first address. */ 645 + hdmi_writeb(hdmi, HDMI_EDID_FIFO_ADDR, 0x00); 646 + 644 647 /* Set edid word address 0x00/0x80. */ 645 648 hdmi_writeb(hdmi, HDMI_EDID_WORD_ADDR, hdmi->i2c->ddc_addr); 646 649
+357 -181
drivers/gpu/drm/rockchip/rockchip_lvds.c
··· 10 10 #include <linux/component.h> 11 11 #include <linux/mfd/syscon.h> 12 12 #include <linux/of_graph.h> 13 + #include <linux/phy/phy.h> 13 14 #include <linux/pinctrl/devinfo.h> 14 15 #include <linux/platform_device.h> 15 16 #include <linux/pm_runtime.h> ··· 32 31 #define DISPLAY_OUTPUT_LVDS 1 33 32 #define DISPLAY_OUTPUT_DUAL_LVDS 2 34 33 34 + struct rockchip_lvds; 35 + 35 36 #define connector_to_lvds(c) \ 36 37 container_of(c, struct rockchip_lvds, connector) 37 38 ··· 42 39 43 40 /** 44 41 * rockchip_lvds_soc_data - rockchip lvds Soc private data 45 - * @ch1_offset: lvds channel 1 registe offset 46 - * grf_soc_con6: general registe offset for LVDS contrl 47 - * grf_soc_con7: general registe offset for LVDS contrl 48 - * has_vop_sel: to indicate whether need to choose from different VOP. 42 + * @probe: LVDS platform probe function 43 + * @helper_funcs: LVDS connector helper functions 49 44 */ 50 45 struct rockchip_lvds_soc_data { 51 - u32 ch1_offset; 52 - int grf_soc_con6; 53 - int grf_soc_con7; 54 - bool has_vop_sel; 46 + int (*probe)(struct platform_device *pdev, struct rockchip_lvds *lvds); 47 + const struct drm_encoder_helper_funcs *helper_funcs; 55 48 }; 56 49 57 50 struct rockchip_lvds { ··· 55 56 void __iomem *regs; 56 57 struct regmap *grf; 57 58 struct clk *pclk; 59 + struct phy *dphy; 58 60 const struct rockchip_lvds_soc_data *soc_data; 59 61 int output; /* rgb lvds or dual lvds output */ 60 62 int format; /* vesa or jeida format */ ··· 67 67 struct dev_pin_info *pins; 68 68 }; 69 69 70 - static inline void lvds_writel(struct rockchip_lvds *lvds, u32 offset, u32 val) 70 + static inline void rk3288_writel(struct rockchip_lvds *lvds, u32 offset, 71 + u32 val) 71 72 { 72 73 writel_relaxed(val, lvds->regs + offset); 73 74 if (lvds->output == DISPLAY_OUTPUT_LVDS) 74 75 return; 75 - writel_relaxed(val, lvds->regs + offset + lvds->soc_data->ch1_offset); 76 + writel_relaxed(val, lvds->regs + offset + RK3288_LVDS_CH1_OFFSET); 76 77 } 77 78 78 - static inline int lvds_name_to_format(const char *s) 79 + static inline int rockchip_lvds_name_to_format(const char *s) 79 80 { 80 81 if (strncmp(s, "jeida-18", 8) == 0) 81 82 return LVDS_JEIDA_18; ··· 88 87 return -EINVAL; 89 88 } 90 89 91 - static inline int lvds_name_to_output(const char *s) 90 + static inline int rockchip_lvds_name_to_output(const char *s) 92 91 { 93 92 if (strncmp(s, "rgb", 3) == 0) 94 93 return DISPLAY_OUTPUT_RGB; ··· 98 97 return DISPLAY_OUTPUT_DUAL_LVDS; 99 98 100 99 return -EINVAL; 101 - } 102 - 103 - static int rockchip_lvds_poweron(struct rockchip_lvds *lvds) 104 - { 105 - int ret; 106 - u32 val; 107 - 108 - ret = clk_enable(lvds->pclk); 109 - if (ret < 0) { 110 - DRM_DEV_ERROR(lvds->dev, "failed to enable lvds pclk %d\n", ret); 111 - return ret; 112 - } 113 - ret = pm_runtime_get_sync(lvds->dev); 114 - if (ret < 0) { 115 - DRM_DEV_ERROR(lvds->dev, "failed to get pm runtime: %d\n", ret); 116 - clk_disable(lvds->pclk); 117 - return ret; 118 - } 119 - val = RK3288_LVDS_CH0_REG0_LANE4_EN | RK3288_LVDS_CH0_REG0_LANE3_EN | 120 - RK3288_LVDS_CH0_REG0_LANE2_EN | RK3288_LVDS_CH0_REG0_LANE1_EN | 121 - RK3288_LVDS_CH0_REG0_LANE0_EN; 122 - if (lvds->output == DISPLAY_OUTPUT_RGB) { 123 - val |= RK3288_LVDS_CH0_REG0_TTL_EN | 124 - RK3288_LVDS_CH0_REG0_LANECK_EN; 125 - lvds_writel(lvds, RK3288_LVDS_CH0_REG0, val); 126 - lvds_writel(lvds, RK3288_LVDS_CH0_REG2, 127 - RK3288_LVDS_PLL_FBDIV_REG2(0x46)); 128 - lvds_writel(lvds, RK3288_LVDS_CH0_REG4, 129 - RK3288_LVDS_CH0_REG4_LANECK_TTL_MODE | 130 - RK3288_LVDS_CH0_REG4_LANE4_TTL_MODE | 131 - RK3288_LVDS_CH0_REG4_LANE3_TTL_MODE | 132 - RK3288_LVDS_CH0_REG4_LANE2_TTL_MODE | 133 - RK3288_LVDS_CH0_REG4_LANE1_TTL_MODE | 134 - RK3288_LVDS_CH0_REG4_LANE0_TTL_MODE); 135 - lvds_writel(lvds, RK3288_LVDS_CH0_REG5, 136 - RK3288_LVDS_CH0_REG5_LANECK_TTL_DATA | 137 - RK3288_LVDS_CH0_REG5_LANE4_TTL_DATA | 138 - RK3288_LVDS_CH0_REG5_LANE3_TTL_DATA | 139 - RK3288_LVDS_CH0_REG5_LANE2_TTL_DATA | 140 - RK3288_LVDS_CH0_REG5_LANE1_TTL_DATA | 141 - RK3288_LVDS_CH0_REG5_LANE0_TTL_DATA); 142 - } else { 143 - val |= RK3288_LVDS_CH0_REG0_LVDS_EN | 144 - RK3288_LVDS_CH0_REG0_LANECK_EN; 145 - lvds_writel(lvds, RK3288_LVDS_CH0_REG0, val); 146 - lvds_writel(lvds, RK3288_LVDS_CH0_REG1, 147 - RK3288_LVDS_CH0_REG1_LANECK_BIAS | 148 - RK3288_LVDS_CH0_REG1_LANE4_BIAS | 149 - RK3288_LVDS_CH0_REG1_LANE3_BIAS | 150 - RK3288_LVDS_CH0_REG1_LANE2_BIAS | 151 - RK3288_LVDS_CH0_REG1_LANE1_BIAS | 152 - RK3288_LVDS_CH0_REG1_LANE0_BIAS); 153 - lvds_writel(lvds, RK3288_LVDS_CH0_REG2, 154 - RK3288_LVDS_CH0_REG2_RESERVE_ON | 155 - RK3288_LVDS_CH0_REG2_LANECK_LVDS_MODE | 156 - RK3288_LVDS_CH0_REG2_LANE4_LVDS_MODE | 157 - RK3288_LVDS_CH0_REG2_LANE3_LVDS_MODE | 158 - RK3288_LVDS_CH0_REG2_LANE2_LVDS_MODE | 159 - RK3288_LVDS_CH0_REG2_LANE1_LVDS_MODE | 160 - RK3288_LVDS_CH0_REG2_LANE0_LVDS_MODE | 161 - RK3288_LVDS_PLL_FBDIV_REG2(0x46)); 162 - lvds_writel(lvds, RK3288_LVDS_CH0_REG4, 0x00); 163 - lvds_writel(lvds, RK3288_LVDS_CH0_REG5, 0x00); 164 - } 165 - lvds_writel(lvds, RK3288_LVDS_CH0_REG3, RK3288_LVDS_PLL_FBDIV_REG3(0x46)); 166 - lvds_writel(lvds, RK3288_LVDS_CH0_REGD, RK3288_LVDS_PLL_PREDIV_REGD(0x0a)); 167 - lvds_writel(lvds, RK3288_LVDS_CH0_REG20, RK3288_LVDS_CH0_REG20_LSB); 168 - 169 - lvds_writel(lvds, RK3288_LVDS_CFG_REGC, RK3288_LVDS_CFG_REGC_PLL_ENABLE); 170 - lvds_writel(lvds, RK3288_LVDS_CFG_REG21, RK3288_LVDS_CFG_REG21_TX_ENABLE); 171 - 172 - return 0; 173 - } 174 - 175 - static void rockchip_lvds_poweroff(struct rockchip_lvds *lvds) 176 - { 177 - int ret; 178 - u32 val; 179 - 180 - lvds_writel(lvds, RK3288_LVDS_CFG_REG21, RK3288_LVDS_CFG_REG21_TX_ENABLE); 181 - lvds_writel(lvds, RK3288_LVDS_CFG_REGC, RK3288_LVDS_CFG_REGC_PLL_ENABLE); 182 - val = LVDS_DUAL | LVDS_TTL_EN | LVDS_CH0_EN | LVDS_CH1_EN | LVDS_PWRDN; 183 - val |= val << 16; 184 - ret = regmap_write(lvds->grf, lvds->soc_data->grf_soc_con7, val); 185 - if (ret != 0) 186 - DRM_DEV_ERROR(lvds->dev, "Could not write to GRF: %d\n", ret); 187 - 188 - pm_runtime_put(lvds->dev); 189 - clk_disable(lvds->pclk); 190 100 } 191 101 192 102 static const struct drm_connector_funcs rockchip_lvds_connector_funcs = { ··· 121 209 .get_modes = rockchip_lvds_connector_get_modes, 122 210 }; 123 211 124 - static void rockchip_lvds_grf_config(struct drm_encoder *encoder, 125 - struct drm_display_mode *mode) 212 + static int 213 + rockchip_lvds_encoder_atomic_check(struct drm_encoder *encoder, 214 + struct drm_crtc_state *crtc_state, 215 + struct drm_connector_state *conn_state) 216 + { 217 + struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); 218 + 219 + s->output_mode = ROCKCHIP_OUT_MODE_P888; 220 + s->output_type = DRM_MODE_CONNECTOR_LVDS; 221 + 222 + return 0; 223 + } 224 + 225 + static int rk3288_lvds_poweron(struct rockchip_lvds *lvds) 226 + { 227 + int ret; 228 + u32 val; 229 + 230 + ret = clk_enable(lvds->pclk); 231 + if (ret < 0) { 232 + DRM_DEV_ERROR(lvds->dev, "failed to enable lvds pclk %d\n", ret); 233 + return ret; 234 + } 235 + ret = pm_runtime_get_sync(lvds->dev); 236 + if (ret < 0) { 237 + DRM_DEV_ERROR(lvds->dev, "failed to get pm runtime: %d\n", ret); 238 + clk_disable(lvds->pclk); 239 + return ret; 240 + } 241 + val = RK3288_LVDS_CH0_REG0_LANE4_EN | RK3288_LVDS_CH0_REG0_LANE3_EN | 242 + RK3288_LVDS_CH0_REG0_LANE2_EN | RK3288_LVDS_CH0_REG0_LANE1_EN | 243 + RK3288_LVDS_CH0_REG0_LANE0_EN; 244 + if (lvds->output == DISPLAY_OUTPUT_RGB) { 245 + val |= RK3288_LVDS_CH0_REG0_TTL_EN | 246 + RK3288_LVDS_CH0_REG0_LANECK_EN; 247 + rk3288_writel(lvds, RK3288_LVDS_CH0_REG0, val); 248 + rk3288_writel(lvds, RK3288_LVDS_CH0_REG2, 249 + RK3288_LVDS_PLL_FBDIV_REG2(0x46)); 250 + rk3288_writel(lvds, RK3288_LVDS_CH0_REG4, 251 + RK3288_LVDS_CH0_REG4_LANECK_TTL_MODE | 252 + RK3288_LVDS_CH0_REG4_LANE4_TTL_MODE | 253 + RK3288_LVDS_CH0_REG4_LANE3_TTL_MODE | 254 + RK3288_LVDS_CH0_REG4_LANE2_TTL_MODE | 255 + RK3288_LVDS_CH0_REG4_LANE1_TTL_MODE | 256 + RK3288_LVDS_CH0_REG4_LANE0_TTL_MODE); 257 + rk3288_writel(lvds, RK3288_LVDS_CH0_REG5, 258 + RK3288_LVDS_CH0_REG5_LANECK_TTL_DATA | 259 + RK3288_LVDS_CH0_REG5_LANE4_TTL_DATA | 260 + RK3288_LVDS_CH0_REG5_LANE3_TTL_DATA | 261 + RK3288_LVDS_CH0_REG5_LANE2_TTL_DATA | 262 + RK3288_LVDS_CH0_REG5_LANE1_TTL_DATA | 263 + RK3288_LVDS_CH0_REG5_LANE0_TTL_DATA); 264 + } else { 265 + val |= RK3288_LVDS_CH0_REG0_LVDS_EN | 266 + RK3288_LVDS_CH0_REG0_LANECK_EN; 267 + rk3288_writel(lvds, RK3288_LVDS_CH0_REG0, val); 268 + rk3288_writel(lvds, RK3288_LVDS_CH0_REG1, 269 + RK3288_LVDS_CH0_REG1_LANECK_BIAS | 270 + RK3288_LVDS_CH0_REG1_LANE4_BIAS | 271 + RK3288_LVDS_CH0_REG1_LANE3_BIAS | 272 + RK3288_LVDS_CH0_REG1_LANE2_BIAS | 273 + RK3288_LVDS_CH0_REG1_LANE1_BIAS | 274 + RK3288_LVDS_CH0_REG1_LANE0_BIAS); 275 + rk3288_writel(lvds, RK3288_LVDS_CH0_REG2, 276 + RK3288_LVDS_CH0_REG2_RESERVE_ON | 277 + RK3288_LVDS_CH0_REG2_LANECK_LVDS_MODE | 278 + RK3288_LVDS_CH0_REG2_LANE4_LVDS_MODE | 279 + RK3288_LVDS_CH0_REG2_LANE3_LVDS_MODE | 280 + RK3288_LVDS_CH0_REG2_LANE2_LVDS_MODE | 281 + RK3288_LVDS_CH0_REG2_LANE1_LVDS_MODE | 282 + RK3288_LVDS_CH0_REG2_LANE0_LVDS_MODE | 283 + RK3288_LVDS_PLL_FBDIV_REG2(0x46)); 284 + rk3288_writel(lvds, RK3288_LVDS_CH0_REG4, 0x00); 285 + rk3288_writel(lvds, RK3288_LVDS_CH0_REG5, 0x00); 286 + } 287 + rk3288_writel(lvds, RK3288_LVDS_CH0_REG3, 288 + RK3288_LVDS_PLL_FBDIV_REG3(0x46)); 289 + rk3288_writel(lvds, RK3288_LVDS_CH0_REGD, 290 + RK3288_LVDS_PLL_PREDIV_REGD(0x0a)); 291 + rk3288_writel(lvds, RK3288_LVDS_CH0_REG20, 292 + RK3288_LVDS_CH0_REG20_LSB); 293 + 294 + rk3288_writel(lvds, RK3288_LVDS_CFG_REGC, 295 + RK3288_LVDS_CFG_REGC_PLL_ENABLE); 296 + rk3288_writel(lvds, RK3288_LVDS_CFG_REG21, 297 + RK3288_LVDS_CFG_REG21_TX_ENABLE); 298 + 299 + return 0; 300 + } 301 + 302 + static void rk3288_lvds_poweroff(struct rockchip_lvds *lvds) 303 + { 304 + int ret; 305 + u32 val; 306 + 307 + rk3288_writel(lvds, RK3288_LVDS_CFG_REG21, 308 + RK3288_LVDS_CFG_REG21_TX_ENABLE); 309 + rk3288_writel(lvds, RK3288_LVDS_CFG_REGC, 310 + RK3288_LVDS_CFG_REGC_PLL_ENABLE); 311 + val = LVDS_DUAL | LVDS_TTL_EN | LVDS_CH0_EN | LVDS_CH1_EN | LVDS_PWRDN; 312 + val |= val << 16; 313 + ret = regmap_write(lvds->grf, RK3288_LVDS_GRF_SOC_CON7, val); 314 + if (ret != 0) 315 + DRM_DEV_ERROR(lvds->dev, "Could not write to GRF: %d\n", ret); 316 + 317 + pm_runtime_put(lvds->dev); 318 + clk_disable(lvds->pclk); 319 + } 320 + 321 + static int rk3288_lvds_grf_config(struct drm_encoder *encoder, 322 + struct drm_display_mode *mode) 126 323 { 127 324 struct rockchip_lvds *lvds = encoder_to_lvds(encoder); 128 325 u8 pin_hsync = (mode->flags & DRM_MODE_FLAG_PHSYNC) ? 1 : 0; ··· 255 234 256 235 val |= (pin_dclk << 8) | (pin_hsync << 9); 257 236 val |= (0xffff << 16); 258 - ret = regmap_write(lvds->grf, lvds->soc_data->grf_soc_con7, val); 259 - if (ret != 0) { 237 + ret = regmap_write(lvds->grf, RK3288_LVDS_GRF_SOC_CON7, val); 238 + if (ret) 260 239 DRM_DEV_ERROR(lvds->dev, "Could not write to GRF: %d\n", ret); 261 - return; 262 - } 240 + 241 + return ret; 263 242 } 264 243 265 - static int rockchip_lvds_set_vop_source(struct rockchip_lvds *lvds, 266 - struct drm_encoder *encoder) 244 + static int rk3288_lvds_set_vop_source(struct rockchip_lvds *lvds, 245 + struct drm_encoder *encoder) 267 246 { 268 247 u32 val; 269 248 int ret; 270 - 271 - if (!lvds->soc_data->has_vop_sel) 272 - return 0; 273 249 274 250 ret = drm_of_encoder_active_endpoint_id(lvds->dev->of_node, encoder); 275 251 if (ret < 0) ··· 276 258 if (ret) 277 259 val |= RK3288_LVDS_SOC_CON6_SEL_VOP_LIT; 278 260 279 - ret = regmap_write(lvds->grf, lvds->soc_data->grf_soc_con6, val); 261 + ret = regmap_write(lvds->grf, RK3288_LVDS_GRF_SOC_CON6, val); 280 262 if (ret < 0) 281 263 return ret; 282 264 283 265 return 0; 284 266 } 285 267 286 - static int 287 - rockchip_lvds_encoder_atomic_check(struct drm_encoder *encoder, 288 - struct drm_crtc_state *crtc_state, 289 - struct drm_connector_state *conn_state) 290 - { 291 - struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); 292 - 293 - s->output_mode = ROCKCHIP_OUT_MODE_P888; 294 - s->output_type = DRM_MODE_CONNECTOR_LVDS; 295 - 296 - return 0; 297 - } 298 - 299 - static void rockchip_lvds_encoder_enable(struct drm_encoder *encoder) 268 + static void rk3288_lvds_encoder_enable(struct drm_encoder *encoder) 300 269 { 301 270 struct rockchip_lvds *lvds = encoder_to_lvds(encoder); 302 271 struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; 303 272 int ret; 304 273 305 274 drm_panel_prepare(lvds->panel); 306 - ret = rockchip_lvds_poweron(lvds); 275 + 276 + ret = rk3288_lvds_poweron(lvds); 307 277 if (ret < 0) { 308 - DRM_DEV_ERROR(lvds->dev, "failed to power on lvds: %d\n", ret); 278 + DRM_DEV_ERROR(lvds->dev, "failed to power on LVDS: %d\n", ret); 309 279 drm_panel_unprepare(lvds->panel); 280 + return; 310 281 } 311 - rockchip_lvds_grf_config(encoder, mode); 312 - rockchip_lvds_set_vop_source(lvds, encoder); 282 + 283 + ret = rk3288_lvds_grf_config(encoder, mode); 284 + if (ret) { 285 + DRM_DEV_ERROR(lvds->dev, "failed to configure LVDS: %d\n", ret); 286 + drm_panel_unprepare(lvds->panel); 287 + return; 288 + } 289 + 290 + ret = rk3288_lvds_set_vop_source(lvds, encoder); 291 + if (ret) { 292 + DRM_DEV_ERROR(lvds->dev, "failed to set VOP source: %d\n", ret); 293 + drm_panel_unprepare(lvds->panel); 294 + return; 295 + } 296 + 313 297 drm_panel_enable(lvds->panel); 314 298 } 315 299 316 - static void rockchip_lvds_encoder_disable(struct drm_encoder *encoder) 300 + static void rk3288_lvds_encoder_disable(struct drm_encoder *encoder) 317 301 { 318 302 struct rockchip_lvds *lvds = encoder_to_lvds(encoder); 319 303 320 304 drm_panel_disable(lvds->panel); 321 - rockchip_lvds_poweroff(lvds); 305 + rk3288_lvds_poweroff(lvds); 306 + drm_panel_unprepare(lvds->panel); 307 + } 308 + 309 + static int px30_lvds_poweron(struct rockchip_lvds *lvds) 310 + { 311 + int ret; 312 + 313 + ret = pm_runtime_get_sync(lvds->dev); 314 + if (ret < 0) { 315 + DRM_DEV_ERROR(lvds->dev, "failed to get pm runtime: %d\n", ret); 316 + return ret; 317 + } 318 + 319 + /* Enable LVDS mode */ 320 + return regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1, 321 + PX30_LVDS_MODE_EN(1) | PX30_LVDS_P2S_EN(1), 322 + PX30_LVDS_MODE_EN(1) | PX30_LVDS_P2S_EN(1)); 323 + } 324 + 325 + static void px30_lvds_poweroff(struct rockchip_lvds *lvds) 326 + { 327 + regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1, 328 + PX30_LVDS_MODE_EN(1) | PX30_LVDS_P2S_EN(1), 329 + PX30_LVDS_MODE_EN(0) | PX30_LVDS_P2S_EN(0)); 330 + 331 + pm_runtime_put(lvds->dev); 332 + } 333 + 334 + static int px30_lvds_grf_config(struct drm_encoder *encoder, 335 + struct drm_display_mode *mode) 336 + { 337 + struct rockchip_lvds *lvds = encoder_to_lvds(encoder); 338 + 339 + if (lvds->output != DISPLAY_OUTPUT_LVDS) { 340 + DRM_DEV_ERROR(lvds->dev, "Unsupported display output %d\n", 341 + lvds->output); 342 + return -EINVAL; 343 + } 344 + 345 + /* Set format */ 346 + return regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1, 347 + PX30_LVDS_FORMAT(lvds->format), 348 + PX30_LVDS_FORMAT(lvds->format)); 349 + } 350 + 351 + static int px30_lvds_set_vop_source(struct rockchip_lvds *lvds, 352 + struct drm_encoder *encoder) 353 + { 354 + int vop; 355 + 356 + vop = drm_of_encoder_active_endpoint_id(lvds->dev->of_node, encoder); 357 + if (vop < 0) 358 + return vop; 359 + 360 + return regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1, 361 + PX30_LVDS_VOP_SEL(1), 362 + PX30_LVDS_VOP_SEL(vop)); 363 + } 364 + 365 + static void px30_lvds_encoder_enable(struct drm_encoder *encoder) 366 + { 367 + struct rockchip_lvds *lvds = encoder_to_lvds(encoder); 368 + struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; 369 + int ret; 370 + 371 + drm_panel_prepare(lvds->panel); 372 + 373 + ret = px30_lvds_poweron(lvds); 374 + if (ret) { 375 + DRM_DEV_ERROR(lvds->dev, "failed to power on LVDS: %d\n", ret); 376 + drm_panel_unprepare(lvds->panel); 377 + return; 378 + } 379 + 380 + ret = px30_lvds_grf_config(encoder, mode); 381 + if (ret) { 382 + DRM_DEV_ERROR(lvds->dev, "failed to configure LVDS: %d\n", ret); 383 + drm_panel_unprepare(lvds->panel); 384 + return; 385 + } 386 + 387 + ret = px30_lvds_set_vop_source(lvds, encoder); 388 + if (ret) { 389 + DRM_DEV_ERROR(lvds->dev, "failed to set VOP source: %d\n", ret); 390 + drm_panel_unprepare(lvds->panel); 391 + return; 392 + } 393 + 394 + drm_panel_enable(lvds->panel); 395 + } 396 + 397 + static void px30_lvds_encoder_disable(struct drm_encoder *encoder) 398 + { 399 + struct rockchip_lvds *lvds = encoder_to_lvds(encoder); 400 + 401 + drm_panel_disable(lvds->panel); 402 + px30_lvds_poweroff(lvds); 322 403 drm_panel_unprepare(lvds->panel); 323 404 } 324 405 325 406 static const 326 - struct drm_encoder_helper_funcs rockchip_lvds_encoder_helper_funcs = { 327 - .enable = rockchip_lvds_encoder_enable, 328 - .disable = rockchip_lvds_encoder_disable, 407 + struct drm_encoder_helper_funcs rk3288_lvds_encoder_helper_funcs = { 408 + .enable = rk3288_lvds_encoder_enable, 409 + .disable = rk3288_lvds_encoder_disable, 410 + .atomic_check = rockchip_lvds_encoder_atomic_check, 411 + }; 412 + 413 + static const 414 + struct drm_encoder_helper_funcs px30_lvds_encoder_helper_funcs = { 415 + .enable = px30_lvds_encoder_enable, 416 + .disable = px30_lvds_encoder_disable, 329 417 .atomic_check = rockchip_lvds_encoder_atomic_check, 330 418 }; 331 419 ··· 439 315 .destroy = drm_encoder_cleanup, 440 316 }; 441 317 318 + static int rk3288_lvds_probe(struct platform_device *pdev, 319 + struct rockchip_lvds *lvds) 320 + { 321 + struct resource *res; 322 + int ret; 323 + 324 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 325 + lvds->regs = devm_ioremap_resource(lvds->dev, res); 326 + if (IS_ERR(lvds->regs)) 327 + return PTR_ERR(lvds->regs); 328 + 329 + lvds->pclk = devm_clk_get(lvds->dev, "pclk_lvds"); 330 + if (IS_ERR(lvds->pclk)) { 331 + DRM_DEV_ERROR(lvds->dev, "could not get pclk_lvds\n"); 332 + return PTR_ERR(lvds->pclk); 333 + } 334 + 335 + lvds->pins = devm_kzalloc(lvds->dev, sizeof(*lvds->pins), 336 + GFP_KERNEL); 337 + if (!lvds->pins) 338 + return -ENOMEM; 339 + 340 + lvds->pins->p = devm_pinctrl_get(lvds->dev); 341 + if (IS_ERR(lvds->pins->p)) { 342 + DRM_DEV_ERROR(lvds->dev, "no pinctrl handle\n"); 343 + devm_kfree(lvds->dev, lvds->pins); 344 + lvds->pins = NULL; 345 + } else { 346 + lvds->pins->default_state = 347 + pinctrl_lookup_state(lvds->pins->p, "lcdc"); 348 + if (IS_ERR(lvds->pins->default_state)) { 349 + DRM_DEV_ERROR(lvds->dev, "no default pinctrl state\n"); 350 + devm_kfree(lvds->dev, lvds->pins); 351 + lvds->pins = NULL; 352 + } 353 + } 354 + 355 + ret = clk_prepare(lvds->pclk); 356 + if (ret < 0) { 357 + DRM_DEV_ERROR(lvds->dev, "failed to prepare pclk_lvds\n"); 358 + return ret; 359 + } 360 + 361 + return 0; 362 + } 363 + 364 + static int px30_lvds_probe(struct platform_device *pdev, 365 + struct rockchip_lvds *lvds) 366 + { 367 + int ret; 368 + 369 + /* MSB */ 370 + ret = regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1, 371 + PX30_LVDS_MSBSEL(1), 372 + PX30_LVDS_MSBSEL(1)); 373 + if (ret) 374 + return ret; 375 + 376 + /* PHY */ 377 + lvds->dphy = devm_phy_get(&pdev->dev, "dphy"); 378 + if (IS_ERR(lvds->dphy)) 379 + return PTR_ERR(lvds->dphy); 380 + 381 + phy_init(lvds->dphy); 382 + if (ret) 383 + return ret; 384 + 385 + phy_set_mode(lvds->dphy, PHY_MODE_LVDS); 386 + if (ret) 387 + return ret; 388 + 389 + return phy_power_on(lvds->dphy); 390 + } 391 + 442 392 static const struct rockchip_lvds_soc_data rk3288_lvds_data = { 443 - .ch1_offset = 0x100, 444 - .grf_soc_con6 = 0x025c, 445 - .grf_soc_con7 = 0x0260, 446 - .has_vop_sel = true, 393 + .probe = rk3288_lvds_probe, 394 + .helper_funcs = &rk3288_lvds_encoder_helper_funcs, 395 + }; 396 + 397 + static const struct rockchip_lvds_soc_data px30_lvds_data = { 398 + .probe = px30_lvds_probe, 399 + .helper_funcs = &px30_lvds_encoder_helper_funcs, 447 400 }; 448 401 449 402 static const struct of_device_id rockchip_lvds_dt_ids[] = { 450 403 { 451 404 .compatible = "rockchip,rk3288-lvds", 452 405 .data = &rk3288_lvds_data 406 + }, 407 + { 408 + .compatible = "rockchip,px30-lvds", 409 + .data = &px30_lvds_data 453 410 }, 454 411 {} 455 412 }; ··· 583 378 /* default set it as output rgb */ 584 379 lvds->output = DISPLAY_OUTPUT_RGB; 585 380 else 586 - lvds->output = lvds_name_to_output(name); 381 + lvds->output = rockchip_lvds_name_to_output(name); 587 382 588 383 if (lvds->output < 0) { 589 384 DRM_DEV_ERROR(dev, "invalid output type [%s]\n", name); ··· 595 390 /* default set it as format vesa 18 */ 596 391 lvds->format = LVDS_VESA_18; 597 392 else 598 - lvds->format = lvds_name_to_format(name); 393 + lvds->format = rockchip_lvds_name_to_format(name); 599 394 600 395 if (lvds->format < 0) { 601 396 DRM_DEV_ERROR(dev, "invalid data-mapping format [%s]\n", name); ··· 615 410 goto err_put_remote; 616 411 } 617 412 618 - drm_encoder_helper_add(encoder, &rockchip_lvds_encoder_helper_funcs); 413 + drm_encoder_helper_add(encoder, lvds->soc_data->helper_funcs); 619 414 620 415 if (lvds->panel) { 621 416 connector = &lvds->connector; ··· 676 471 void *data) 677 472 { 678 473 struct rockchip_lvds *lvds = dev_get_drvdata(dev); 474 + const struct drm_encoder_helper_funcs *encoder_funcs; 679 475 680 - rockchip_lvds_encoder_disable(&lvds->encoder); 476 + encoder_funcs = lvds->soc_data->helper_funcs; 477 + encoder_funcs->disable(&lvds->encoder); 681 478 if (lvds->panel) 682 479 drm_panel_detach(lvds->panel); 683 480 pm_runtime_disable(dev); ··· 697 490 struct device *dev = &pdev->dev; 698 491 struct rockchip_lvds *lvds; 699 492 const struct of_device_id *match; 700 - struct resource *res; 701 493 int ret; 702 494 703 495 if (!dev->of_node) ··· 712 506 return -ENODEV; 713 507 lvds->soc_data = match->data; 714 508 715 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 716 - lvds->regs = devm_ioremap_resource(&pdev->dev, res); 717 - if (IS_ERR(lvds->regs)) 718 - return PTR_ERR(lvds->regs); 719 - 720 - lvds->pclk = devm_clk_get(&pdev->dev, "pclk_lvds"); 721 - if (IS_ERR(lvds->pclk)) { 722 - DRM_DEV_ERROR(dev, "could not get pclk_lvds\n"); 723 - return PTR_ERR(lvds->pclk); 724 - } 725 - 726 - lvds->pins = devm_kzalloc(lvds->dev, sizeof(*lvds->pins), 727 - GFP_KERNEL); 728 - if (!lvds->pins) 729 - return -ENOMEM; 730 - 731 - lvds->pins->p = devm_pinctrl_get(lvds->dev); 732 - if (IS_ERR(lvds->pins->p)) { 733 - DRM_DEV_ERROR(dev, "no pinctrl handle\n"); 734 - devm_kfree(lvds->dev, lvds->pins); 735 - lvds->pins = NULL; 736 - } else { 737 - lvds->pins->default_state = 738 - pinctrl_lookup_state(lvds->pins->p, "lcdc"); 739 - if (IS_ERR(lvds->pins->default_state)) { 740 - DRM_DEV_ERROR(dev, "no default pinctrl state\n"); 741 - devm_kfree(lvds->dev, lvds->pins); 742 - lvds->pins = NULL; 743 - } 744 - } 745 - 746 509 lvds->grf = syscon_regmap_lookup_by_phandle(dev->of_node, 747 510 "rockchip,grf"); 748 511 if (IS_ERR(lvds->grf)) { ··· 719 544 return PTR_ERR(lvds->grf); 720 545 } 721 546 722 - dev_set_drvdata(dev, lvds); 723 - 724 - ret = clk_prepare(lvds->pclk); 725 - if (ret < 0) { 726 - DRM_DEV_ERROR(dev, "failed to prepare pclk_lvds\n"); 547 + ret = lvds->soc_data->probe(pdev, lvds); 548 + if (ret) { 549 + DRM_DEV_ERROR(dev, "Platform initialization failed\n"); 727 550 return ret; 728 551 } 552 + 553 + dev_set_drvdata(dev, lvds); 554 + 729 555 ret = component_add(&pdev->dev, &rockchip_lvds_component_ops); 730 556 if (ret < 0) { 731 557 DRM_DEV_ERROR(dev, "failed to add component\n");
+18 -1
drivers/gpu/drm/rockchip/rockchip_lvds.h
··· 70 70 #define RK3288_LVDS_CFG_REG21 0x84 71 71 #define RK3288_LVDS_CFG_REG21_TX_ENABLE 0x92 72 72 #define RK3288_LVDS_CFG_REG21_TX_DISABLE 0x00 73 - #define RK3288_LVDS_CH1_OFFSET 0x100 73 + #define RK3288_LVDS_CH1_OFFSET 0x100 74 + 75 + #define RK3288_LVDS_GRF_SOC_CON6 0x025C 76 + #define RK3288_LVDS_GRF_SOC_CON7 0x0260 74 77 75 78 /* fbdiv value is split over 2 registers, with bit8 in reg2 */ 76 79 #define RK3288_LVDS_PLL_FBDIV_REG2(_fbd) \ ··· 105 102 #define LVDS_JEIDA_24 1 106 103 #define LVDS_VESA_18 2 107 104 #define LVDS_JEIDA_18 3 105 + 106 + #define HIWORD_UPDATE(v, h, l) ((GENMASK(h, l) << 16) | ((v) << (l))) 107 + 108 + #define PX30_LVDS_GRF_PD_VO_CON0 0x434 109 + #define PX30_LVDS_TIE_CLKS(val) HIWORD_UPDATE(val, 8, 8) 110 + #define PX30_LVDS_INVERT_CLKS(val) HIWORD_UPDATE(val, 9, 9) 111 + #define PX30_LVDS_INVERT_DCLK(val) HIWORD_UPDATE(val, 5, 5) 112 + 113 + #define PX30_LVDS_GRF_PD_VO_CON1 0x438 114 + #define PX30_LVDS_FORMAT(val) HIWORD_UPDATE(val, 14, 13) 115 + #define PX30_LVDS_MODE_EN(val) HIWORD_UPDATE(val, 12, 12) 116 + #define PX30_LVDS_MSBSEL(val) HIWORD_UPDATE(val, 11, 11) 117 + #define PX30_LVDS_P2S_EN(val) HIWORD_UPDATE(val, 6, 6) 118 + #define PX30_LVDS_VOP_SEL(val) HIWORD_UPDATE(val, 1, 1) 108 119 109 120 #endif /* _ROCKCHIP_LVDS_ */
-12
drivers/video/fbdev/68328fb.c
··· 405 405 406 406 int __init mc68x328fb_setup(char *options) 407 407 { 408 - #if 0 409 - char *this_opt; 410 - #endif 411 - 412 408 if (!options || !*options) 413 409 return 1; 414 - #if 0 415 - while ((this_opt = strsep(&options, ",")) != NULL) { 416 - if (!*this_opt) 417 - continue; 418 - if (!strncmp(this_opt, "disable", 7)) 419 - mc68x328fb_enable = 0; 420 - } 421 - #endif 422 410 return 1; 423 411 } 424 412
+7
drivers/video/fbdev/core/fbcon.c
··· 536 536 fb_center_logo = true; 537 537 continue; 538 538 } 539 + 540 + if (!strncmp(options, "logo-count:", 11)) { 541 + options += 11; 542 + if (*options) 543 + fb_logo_count = simple_strtol(options, &options, 0); 544 + continue; 545 + } 539 546 } 540 547 return 1; 541 548 }
+9 -4
drivers/video/fbdev/core/fbmem.c
··· 54 54 EXPORT_SYMBOL(num_registered_fb); 55 55 56 56 bool fb_center_logo __read_mostly; 57 - EXPORT_SYMBOL(fb_center_logo); 57 + 58 + int fb_logo_count __read_mostly = -1; 58 59 59 60 static struct fb_info *get_fb_info(unsigned int idx) 60 61 { ··· 621 620 memset(&fb_logo, 0, sizeof(struct logo_data)); 622 621 623 622 if (info->flags & FBINFO_MISC_TILEBLITTING || 624 - info->fbops->owner) 623 + info->fbops->owner || !fb_logo_count) 625 624 return 0; 626 625 627 626 if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) { ··· 687 686 688 687 int fb_show_logo(struct fb_info *info, int rotate) 689 688 { 689 + unsigned int count; 690 690 int y; 691 691 692 - y = fb_show_logo_line(info, rotate, fb_logo.logo, 0, 693 - num_online_cpus()); 692 + if (!fb_logo_count) 693 + return 0; 694 + 695 + count = fb_logo_count < 0 ? num_online_cpus() : fb_logo_count; 696 + y = fb_show_logo_line(info, rotate, fb_logo.logo, 0, count); 694 697 y = fb_show_extra_logos(info, y, rotate); 695 698 696 699 return y;
+2
drivers/video/fbdev/fsl-diu-fb.c
··· 1287 1287 dev_warn(info->dev, 1288 1288 "MFB_SET_PIXFMT value of 0x%08x is deprecated.\n", 1289 1289 MFB_SET_PIXFMT_OLD); 1290 + /* fall through */ 1290 1291 case MFB_SET_PIXFMT: 1291 1292 if (copy_from_user(&pix_fmt, buf, sizeof(pix_fmt))) 1292 1293 return -EFAULT; ··· 1297 1296 dev_warn(info->dev, 1298 1297 "MFB_GET_PIXFMT value of 0x%08x is deprecated.\n", 1299 1298 MFB_GET_PIXFMT_OLD); 1299 + /* fall through */ 1300 1300 case MFB_GET_PIXFMT: 1301 1301 pix_fmt = ad->pix_fmt; 1302 1302 if (copy_to_user(buf, &pix_fmt, sizeof(pix_fmt)))
+4 -1
drivers/video/fbdev/matrox/matroxfb_misc.c
··· 673 673 if (bd->pins[115] & 4) { 674 674 minfo->values.reg.mctlwtst_core = minfo->values.reg.mctlwtst; 675 675 } else { 676 - u_int32_t wtst_xlat[] = { 0, 1, 5, 6, 7, 5, 2, 3 }; 676 + static const u8 wtst_xlat[] = { 677 + 0, 1, 5, 6, 7, 5, 2, 3 678 + }; 679 + 677 680 minfo->values.reg.mctlwtst_core = (minfo->values.reg.mctlwtst & ~7) | 678 681 wtst_xlat[minfo->values.reg.mctlwtst & 7]; 679 682 }
+1 -1
drivers/video/fbdev/mmp/Kconfig
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 menuconfig MMP_DISP 3 3 tristate "Marvell MMP Display Subsystem support" 4 - depends on CPU_PXA910 || CPU_MMP2 4 + depends on CPU_PXA910 || CPU_MMP2 || COMPILE_TEST 5 5 help 6 6 Marvell Display Subsystem support. 7 7
-4
drivers/video/fbdev/mmp/fb/Kconfig
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 - if MMP_DISP 3 - 4 2 config MMP_FB 5 3 tristate "fb driver for Marvell MMP Display Subsystem" 6 4 depends on FB ··· 8 10 default y 9 11 help 10 12 fb driver for Marvell MMP Display Subsystem 11 - 12 - endif
+1 -1
drivers/video/fbdev/mmp/fb/mmpfb.c
··· 522 522 info->var.bits_per_pixel / 8; 523 523 info->fbops = &mmpfb_ops; 524 524 info->pseudo_palette = fbi->pseudo_palette; 525 - info->screen_base = fbi->fb_start; 525 + info->screen_buffer = fbi->fb_start; 526 526 info->screen_size = fbi->fb_size; 527 527 528 528 /* For FB framework: Allocate color map and Register framebuffer*/
+2 -5
drivers/video/fbdev/mmp/hw/Kconfig
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 - if MMP_DISP 3 - 4 2 config MMP_DISP_CONTROLLER 5 3 bool "mmp display controller hw support" 6 - depends on CPU_PXA910 || CPU_MMP2 4 + depends on HAVE_CLK && HAS_IOMEM 5 + depends on CPU_PXA910 || CPU_MMP2 || COMPILE_TEST 7 6 help 8 7 Marvell MMP display hw controller support 9 8 this controller is used on Marvell PXA910 and ··· 15 16 help 16 17 Marvell MMP display hw controller spi port support 17 18 will register as a spi master for panel usage 18 - 19 - endif
+31 -22
drivers/video/fbdev/mmp/hw/mmp_ctrl.c
··· 136 136 mutex_lock(&overlay->access_ok); 137 137 138 138 if (overlay_is_vid(overlay)) { 139 - writel_relaxed(win->pitch[0], &regs->v_pitch_yc); 140 - writel_relaxed(win->pitch[2] << 16 | 141 - win->pitch[1], &regs->v_pitch_uv); 139 + writel_relaxed(win->pitch[0], 140 + (void __iomem *)&regs->v_pitch_yc); 141 + writel_relaxed(win->pitch[2] << 16 | win->pitch[1], 142 + (void __iomem *)&regs->v_pitch_uv); 142 143 143 - writel_relaxed((win->ysrc << 16) | win->xsrc, &regs->v_size); 144 - writel_relaxed((win->ydst << 16) | win->xdst, &regs->v_size_z); 145 - writel_relaxed(win->ypos << 16 | win->xpos, &regs->v_start); 144 + writel_relaxed((win->ysrc << 16) | win->xsrc, 145 + (void __iomem *)&regs->v_size); 146 + writel_relaxed((win->ydst << 16) | win->xdst, 147 + (void __iomem *)&regs->v_size_z); 148 + writel_relaxed(win->ypos << 16 | win->xpos, 149 + (void __iomem *)&regs->v_start); 146 150 } else { 147 - writel_relaxed(win->pitch[0], &regs->g_pitch); 151 + writel_relaxed(win->pitch[0], (void __iomem *)&regs->g_pitch); 148 152 149 - writel_relaxed((win->ysrc << 16) | win->xsrc, &regs->g_size); 150 - writel_relaxed((win->ydst << 16) | win->xdst, &regs->g_size_z); 151 - writel_relaxed(win->ypos << 16 | win->xpos, &regs->g_start); 153 + writel_relaxed((win->ysrc << 16) | win->xsrc, 154 + (void __iomem *)&regs->g_size); 155 + writel_relaxed((win->ydst << 16) | win->xdst, 156 + (void __iomem *)&regs->g_size_z); 157 + writel_relaxed(win->ypos << 16 | win->xpos, 158 + (void __iomem *)&regs->g_start); 152 159 } 153 160 154 161 dmafetch_set_fmt(overlay); ··· 240 233 memcpy(&overlay->addr, addr, sizeof(struct mmp_addr)); 241 234 242 235 if (overlay_is_vid(overlay)) { 243 - writel_relaxed(addr->phys[0], &regs->v_y0); 244 - writel_relaxed(addr->phys[1], &regs->v_u0); 245 - writel_relaxed(addr->phys[2], &regs->v_v0); 236 + writel_relaxed(addr->phys[0], (void __iomem *)&regs->v_y0); 237 + writel_relaxed(addr->phys[1], (void __iomem *)&regs->v_u0); 238 + writel_relaxed(addr->phys[2], (void __iomem *)&regs->v_v0); 246 239 } else 247 - writel_relaxed(addr->phys[0], &regs->g_0); 240 + writel_relaxed(addr->phys[0], (void __iomem *)&regs->g_0); 248 241 249 242 return overlay->addr.phys[0]; 250 243 } ··· 275 268 tmp |= dsi_rbswap & CFG_INTFRBSWAP_MASK; 276 269 writel_relaxed(tmp, ctrl_regs(path) + intf_rbswap_ctrl(path->id)); 277 270 278 - writel_relaxed((mode->yres << 16) | mode->xres, &regs->screen_active); 271 + writel_relaxed((mode->yres << 16) | mode->xres, 272 + (void __iomem *)&regs->screen_active); 279 273 writel_relaxed((mode->left_margin << 16) | mode->right_margin, 280 - &regs->screen_h_porch); 274 + (void __iomem *)&regs->screen_h_porch); 281 275 writel_relaxed((mode->upper_margin << 16) | mode->lower_margin, 282 - &regs->screen_v_porch); 276 + (void __iomem *)&regs->screen_v_porch); 283 277 total_x = mode->xres + mode->left_margin + mode->right_margin + 284 278 mode->hsync_len; 285 279 total_y = mode->yres + mode->upper_margin + mode->lower_margin + 286 280 mode->vsync_len; 287 - writel_relaxed((total_y << 16) | total_x, &regs->screen_size); 281 + writel_relaxed((total_y << 16) | total_x, 282 + (void __iomem *)&regs->screen_size); 288 283 289 284 /* vsync ctrl */ 290 285 if (path->output_type == PATH_OUT_DSI) ··· 294 285 else 295 286 vsync_ctrl = ((mode->xres + mode->right_margin) << 16) 296 287 | (mode->xres + mode->right_margin); 297 - writel_relaxed(vsync_ctrl, &regs->vsync_ctrl); 288 + writel_relaxed(vsync_ctrl, (void __iomem *)&regs->vsync_ctrl); 298 289 299 290 /* set pixclock div */ 300 291 sclk_src = clk_get_rate(path_to_ctrl(path)->clk); ··· 375 366 writel_relaxed(dma_ctrl1, ctrl_regs(path) + dma_ctrl(1, path->id)); 376 367 377 368 /* Configure default register values */ 378 - writel_relaxed(0x00000000, &regs->blank_color); 379 - writel_relaxed(0x00000000, &regs->g_1); 380 - writel_relaxed(0x00000000, &regs->g_start); 369 + writel_relaxed(0x00000000, (void __iomem *)&regs->blank_color); 370 + writel_relaxed(0x00000000, (void __iomem *)&regs->g_1); 371 + writel_relaxed(0x00000000, (void __iomem *)&regs->g_start); 381 372 382 373 /* 383 374 * 1.enable multiple burst request in DMA AXI
+5 -5
drivers/video/fbdev/mmp/hw/mmp_ctrl.h
··· 1393 1393 /* platform related, get from config */ 1394 1394 const char *name; 1395 1395 int irq; 1396 - void *reg_base; 1396 + void __iomem *reg_base; 1397 1397 struct clk *clk; 1398 1398 1399 1399 /* sys info */ ··· 1429 1429 return path_to_ctrl(overlay->path); 1430 1430 } 1431 1431 1432 - static inline void *ctrl_regs(struct mmp_path *path) 1432 + static inline void __iomem *ctrl_regs(struct mmp_path *path) 1433 1433 { 1434 1434 return path_to_ctrl(path)->reg_base; 1435 1435 } ··· 1438 1438 static inline struct lcd_regs *path_regs(struct mmp_path *path) 1439 1439 { 1440 1440 if (path->id == PATH_PN) 1441 - return (struct lcd_regs *)(ctrl_regs(path) + 0xc0); 1441 + return (struct lcd_regs __force *)(ctrl_regs(path) + 0xc0); 1442 1442 else if (path->id == PATH_TV) 1443 - return (struct lcd_regs *)ctrl_regs(path); 1443 + return (struct lcd_regs __force *)ctrl_regs(path); 1444 1444 else if (path->id == PATH_P2) 1445 - return (struct lcd_regs *)(ctrl_regs(path) + 0x200); 1445 + return (struct lcd_regs __force *)(ctrl_regs(path) + 0x200); 1446 1446 else { 1447 1447 dev_err(path->dev, "path id %d invalid\n", path->id); 1448 1448 BUG_ON(1);
+3 -3
drivers/video/fbdev/mmp/hw/mmp_spi.c
··· 31 31 { 32 32 int timeout = 100000, isr, ret = 0; 33 33 u32 tmp; 34 - void *reg_base = 34 + void __iomem *reg_base = (void __iomem *) 35 35 *(void **)spi_master_get_devdata(spi->master); 36 36 37 37 /* clear ISR */ ··· 80 80 81 81 static int lcd_spi_setup(struct spi_device *spi) 82 82 { 83 - void *reg_base = 83 + void __iomem *reg_base = (void __iomem *) 84 84 *(void **)spi_master_get_devdata(spi->master); 85 85 u32 tmp; 86 86 ··· 146 146 return -ENOMEM; 147 147 } 148 148 p_regbase = spi_master_get_devdata(master); 149 - *p_regbase = ctrl->reg_base; 149 + *p_regbase = (void __force *)ctrl->reg_base; 150 150 151 151 /* set bus num to 5 to avoid conflict with other spi hosts */ 152 152 master->bus_num = 5;
+1 -8
drivers/video/fbdev/ocfb.c
··· 297 297 { 298 298 int ret = 0; 299 299 struct ocfb_dev *fbdev; 300 - struct resource *res; 301 300 int fbsize; 302 301 303 302 fbdev = devm_kzalloc(&pdev->dev, sizeof(*fbdev), GFP_KERNEL); ··· 318 319 ocfb_init_var(fbdev); 319 320 ocfb_init_fix(fbdev); 320 321 321 - /* Request I/O resource */ 322 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 323 - if (!res) { 324 - dev_err(&pdev->dev, "I/O resource request failed\n"); 325 - return -ENXIO; 326 - } 327 - fbdev->regs = devm_ioremap_resource(&pdev->dev, res); 322 + fbdev->regs = devm_platform_ioremap_resource(pdev, 0); 328 323 if (IS_ERR(fbdev->regs)) 329 324 return PTR_ERR(fbdev->regs); 330 325
+3 -3
drivers/video/fbdev/omap2/omapfb/dss/dispc.c
··· 1635 1635 { 1636 1636 int scale_x = out_width != orig_width; 1637 1637 int scale_y = out_height != orig_height; 1638 - bool chroma_upscale = plane != OMAP_DSS_WB ? true : false; 1638 + bool chroma_upscale = plane != OMAP_DSS_WB; 1639 1639 1640 1640 if (!dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) 1641 1641 return; ··· 3100 3100 unsigned long pclk) 3101 3101 { 3102 3102 if (dss_mgr_is_lcd(channel)) 3103 - return pclk <= dispc.feat->max_lcd_pclk ? true : false; 3103 + return pclk <= dispc.feat->max_lcd_pclk; 3104 3104 else 3105 - return pclk <= dispc.feat->max_tv_pclk ? true : false; 3105 + return pclk <= dispc.feat->max_tv_pclk; 3106 3106 } 3107 3107 3108 3108 bool dispc_mgr_timings_ok(enum omap_channel channel,
+1 -3
drivers/video/fbdev/omap2/omapfb/vrfb.c
··· 339 339 int i; 340 340 341 341 /* first resource is the register res, the rest are vrfb contexts */ 342 - 343 - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 344 - vrfb_base = devm_ioremap_resource(&pdev->dev, mem); 342 + vrfb_base = devm_platform_ioremap_resource(pdev, 0); 345 343 if (IS_ERR(vrfb_base)) 346 344 return PTR_ERR(vrfb_base); 347 345
+3 -3
drivers/video/fbdev/pxa168fb.c
··· 766 766 failed_free_clk: 767 767 clk_disable_unprepare(fbi->clk); 768 768 failed_free_fbmem: 769 - dma_free_coherent(fbi->dev, info->fix.smem_len, 770 - info->screen_base, fbi->fb_start_dma); 769 + dma_free_wc(fbi->dev, info->fix.smem_len, 770 + info->screen_base, fbi->fb_start_dma); 771 771 failed_free_info: 772 772 kfree(info); 773 773 ··· 801 801 802 802 irq = platform_get_irq(pdev, 0); 803 803 804 - dma_free_wc(fbi->dev, PAGE_ALIGN(info->fix.smem_len), 804 + dma_free_wc(fbi->dev, info->fix.smem_len, 805 805 info->screen_base, info->fix.smem_start); 806 806 807 807 clk_disable_unprepare(fbi->clk);
+1 -9
drivers/video/fbdev/pxafb.c
··· 2237 2237 { 2238 2238 struct pxafb_info *fbi; 2239 2239 struct pxafb_mach_info *inf, *pdata; 2240 - struct resource *r; 2241 2240 int i, irq, ret; 2242 2241 2243 2242 dev_dbg(&dev->dev, "pxafb_probe\n"); ··· 2302 2303 fbi->lcd_supply = NULL; 2303 2304 } 2304 2305 2305 - r = platform_get_resource(dev, IORESOURCE_MEM, 0); 2306 - if (r == NULL) { 2307 - dev_err(&dev->dev, "no I/O memory resource defined\n"); 2308 - ret = -ENODEV; 2309 - goto failed; 2310 - } 2311 - 2312 - fbi->mmio_base = devm_ioremap_resource(&dev->dev, r); 2306 + fbi->mmio_base = devm_platform_ioremap_resource(dev, 0); 2313 2307 if (IS_ERR(fbi->mmio_base)) { 2314 2308 dev_err(&dev->dev, "failed to get I/O memory\n"); 2315 2309 ret = -EBUSY;
+1 -2
drivers/video/fbdev/s3c-fb.c
··· 1411 1411 1412 1412 pm_runtime_enable(sfb->dev); 1413 1413 1414 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1415 - sfb->regs = devm_ioremap_resource(dev, res); 1414 + sfb->regs = devm_platform_ioremap_resource(pdev, 0); 1416 1415 if (IS_ERR(sfb->regs)) { 1417 1416 ret = PTR_ERR(sfb->regs); 1418 1417 goto err_lcd_clk;
+1 -3
drivers/video/fbdev/sa1100fb.c
··· 1143 1143 static int sa1100fb_probe(struct platform_device *pdev) 1144 1144 { 1145 1145 struct sa1100fb_info *fbi; 1146 - struct resource *res; 1147 1146 int ret, irq; 1148 1147 1149 1148 if (!dev_get_platdata(&pdev->dev)) { ··· 1158 1159 if (!fbi) 1159 1160 return -ENOMEM; 1160 1161 1161 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1162 - fbi->base = devm_ioremap_resource(&pdev->dev, res); 1162 + fbi->base = devm_platform_ioremap_resource(pdev, 0); 1163 1163 if (IS_ERR(fbi->base)) 1164 1164 return PTR_ERR(fbi->base); 1165 1165
+3
include/drm/drm_atomic.h
··· 670 670 } 671 671 672 672 int __must_check 673 + drm_atomic_add_encoder_bridges(struct drm_atomic_state *state, 674 + struct drm_encoder *encoder); 675 + int __must_check 673 676 drm_atomic_add_affected_connectors(struct drm_atomic_state *state, 674 677 struct drm_crtc *crtc); 675 678 int __must_check
+270 -5
include/drm/drm_bridge.h
··· 25 25 26 26 #include <linux/list.h> 27 27 #include <linux/ctype.h> 28 + 29 + #include <drm/drm_atomic.h> 28 30 #include <drm/drm_encoder.h> 29 31 #include <drm/drm_mode_object.h> 30 32 #include <drm/drm_modes.h> ··· 34 32 struct drm_bridge; 35 33 struct drm_bridge_timings; 36 34 struct drm_panel; 35 + 36 + /** 37 + * struct drm_bus_cfg - bus configuration 38 + * 39 + * This structure stores the configuration of a physical bus between two 40 + * components in an output pipeline, usually between two bridges, an encoder 41 + * and a bridge, or a bridge and a connector. 42 + * 43 + * The bus configuration is stored in &drm_bridge_state separately for the 44 + * input and output buses, as seen from the point of view of each bridge. The 45 + * bus configuration of a bridge output is usually identical to the 46 + * configuration of the next bridge's input, but may differ if the signals are 47 + * modified between the two bridges, for instance by an inverter on the board. 48 + * The input and output configurations of a bridge may differ if the bridge 49 + * modifies the signals internally, for instance by performing format 50 + * conversion, or modifying signals polarities. 51 + */ 52 + struct drm_bus_cfg { 53 + /** 54 + * @format: format used on this bus (one of the MEDIA_BUS_FMT_* format) 55 + * 56 + * This field should not be directly modified by drivers 57 + * (&drm_atomic_bridge_chain_select_bus_fmts() takes care of the bus 58 + * format negotiation). 59 + */ 60 + u32 format; 61 + 62 + /** 63 + * @flags: DRM_BUS_* flags used on this bus 64 + */ 65 + u32 flags; 66 + }; 67 + 68 + /** 69 + * struct drm_bridge_state - Atomic bridge state object 70 + * @base: inherit from &drm_private_state 71 + * @bridge: the bridge this state refers to 72 + */ 73 + struct drm_bridge_state { 74 + struct drm_private_state base; 75 + 76 + struct drm_bridge *bridge; 77 + 78 + /** 79 + * @input_bus_cfg: input bus configuration 80 + */ 81 + struct drm_bus_cfg input_bus_cfg; 82 + 83 + /** 84 + * @output_bus_cfg: input bus configuration 85 + */ 86 + struct drm_bus_cfg output_bus_cfg; 87 + }; 88 + 89 + static inline struct drm_bridge_state * 90 + drm_priv_to_bridge_state(struct drm_private_state *priv) 91 + { 92 + return container_of(priv, struct drm_bridge_state, base); 93 + } 37 94 38 95 /** 39 96 * struct drm_bridge_funcs - drm_bridge control functions ··· 170 109 * this function passes all other callbacks must succeed for this 171 110 * configuration. 172 111 * 173 - * The @mode_fixup callback is optional. 112 + * The mode_fixup callback is optional. &drm_bridge_funcs.mode_fixup() 113 + * is not called when &drm_bridge_funcs.atomic_check() is implemented, 114 + * so only one of them should be provided. 174 115 * 175 116 * NOTE: 176 117 * ··· 326 263 * The @atomic_pre_enable callback is optional. 327 264 */ 328 265 void (*atomic_pre_enable)(struct drm_bridge *bridge, 329 - struct drm_atomic_state *old_state); 266 + struct drm_bridge_state *old_bridge_state); 330 267 331 268 /** 332 269 * @atomic_enable: ··· 351 288 * The @atomic_enable callback is optional. 352 289 */ 353 290 void (*atomic_enable)(struct drm_bridge *bridge, 354 - struct drm_atomic_state *old_state); 291 + struct drm_bridge_state *old_bridge_state); 355 292 /** 356 293 * @atomic_disable: 357 294 * ··· 374 311 * The @atomic_disable callback is optional. 375 312 */ 376 313 void (*atomic_disable)(struct drm_bridge *bridge, 377 - struct drm_atomic_state *old_state); 314 + struct drm_bridge_state *old_bridge_state); 378 315 379 316 /** 380 317 * @atomic_post_disable: ··· 400 337 * The @atomic_post_disable callback is optional. 401 338 */ 402 339 void (*atomic_post_disable)(struct drm_bridge *bridge, 403 - struct drm_atomic_state *old_state); 340 + struct drm_bridge_state *old_bridge_state); 341 + 342 + /** 343 + * @atomic_duplicate_state: 344 + * 345 + * Duplicate the current bridge state object (which is guaranteed to be 346 + * non-NULL). 347 + * 348 + * The atomic_duplicate_state() is optional. When not implemented the 349 + * core allocates a drm_bridge_state object and calls 350 + * &__drm_atomic_helper_bridge_duplicate_state() to initialize it. 351 + * 352 + * RETURNS: 353 + * A valid drm_bridge_state object or NULL if the allocation fails. 354 + */ 355 + struct drm_bridge_state *(*atomic_duplicate_state)(struct drm_bridge *bridge); 356 + 357 + /** 358 + * @atomic_destroy_state: 359 + * 360 + * Destroy a bridge state object previously allocated by 361 + * &drm_bridge_funcs.atomic_duplicate_state(). 362 + * 363 + * The atomic_destroy_state hook is optional. When not implemented the 364 + * core calls kfree() on the state. 365 + */ 366 + void (*atomic_destroy_state)(struct drm_bridge *bridge, 367 + struct drm_bridge_state *state); 368 + 369 + /** 370 + * @atomic_get_output_bus_fmts: 371 + * 372 + * Return the supported bus formats on the output end of a bridge. 373 + * The returned array must be allocated with kmalloc() and will be 374 + * freed by the caller. If the allocation fails, NULL should be 375 + * returned. num_output_fmts must be set to the returned array size. 376 + * Formats listed in the returned array should be listed in decreasing 377 + * preference order (the core will try all formats until it finds one 378 + * that works). 379 + * 380 + * This method is only called on the last element of the bridge chain 381 + * as part of the bus format negotiation process that happens in 382 + * &drm_atomic_bridge_chain_select_bus_fmts(). 383 + * This method is optional. When not implemented, the core will 384 + * fall back to &drm_connector.display_info.bus_formats[0] if 385 + * &drm_connector.display_info.num_bus_formats > 0, 386 + * or to MEDIA_BUS_FMT_FIXED otherwise. 387 + */ 388 + u32 *(*atomic_get_output_bus_fmts)(struct drm_bridge *bridge, 389 + struct drm_bridge_state *bridge_state, 390 + struct drm_crtc_state *crtc_state, 391 + struct drm_connector_state *conn_state, 392 + unsigned int *num_output_fmts); 393 + 394 + /** 395 + * @atomic_get_input_bus_fmts: 396 + * 397 + * Return the supported bus formats on the input end of a bridge for 398 + * a specific output bus format. 399 + * 400 + * The returned array must be allocated with kmalloc() and will be 401 + * freed by the caller. If the allocation fails, NULL should be 402 + * returned. num_output_fmts must be set to the returned array size. 403 + * Formats listed in the returned array should be listed in decreasing 404 + * preference order (the core will try all formats until it finds one 405 + * that works). When the format is not supported NULL should be 406 + * returned and *num_output_fmts should be set to 0. 407 + * 408 + * This method is called on all elements of the bridge chain as part of 409 + * the bus format negotiation process that happens in 410 + * &drm_atomic_bridge_chain_select_bus_fmts(). 411 + * This method is optional. When not implemented, the core will bypass 412 + * bus format negotiation on this element of the bridge without 413 + * failing, and the previous element in the chain will be passed 414 + * MEDIA_BUS_FMT_FIXED as its output bus format. 415 + * 416 + * Bridge drivers that need to support being linked to bridges that are 417 + * not supporting bus format negotiation should handle the 418 + * output_fmt == MEDIA_BUS_FMT_FIXED case appropriately, by selecting a 419 + * sensible default value or extracting this information from somewhere 420 + * else (FW property, &drm_display_mode, &drm_display_info, ...) 421 + * 422 + * Note: Even if input format selection on the first bridge has no 423 + * impact on the negotiation process (bus format negotiation stops once 424 + * we reach the first element of the chain), drivers are expected to 425 + * return accurate input formats as the input format may be used to 426 + * configure the CRTC output appropriately. 427 + */ 428 + u32 *(*atomic_get_input_bus_fmts)(struct drm_bridge *bridge, 429 + struct drm_bridge_state *bridge_state, 430 + struct drm_crtc_state *crtc_state, 431 + struct drm_connector_state *conn_state, 432 + u32 output_fmt, 433 + unsigned int *num_input_fmts); 434 + 435 + /** 436 + * @atomic_check: 437 + * 438 + * This method is responsible for checking bridge state correctness. 439 + * It can also check the state of the surrounding components in chain 440 + * to make sure the whole pipeline can work properly. 441 + * 442 + * &drm_bridge_funcs.atomic_check() hooks are called in reverse 443 + * order (from the last to the first bridge). 444 + * 445 + * This method is optional. &drm_bridge_funcs.mode_fixup() is not 446 + * called when &drm_bridge_funcs.atomic_check() is implemented, so only 447 + * one of them should be provided. 448 + * 449 + * If drivers need to tweak &drm_bridge_state.input_bus_cfg.flags or 450 + * &drm_bridge_state.output_bus_cfg.flags it should should happen in 451 + * this function. By default the &drm_bridge_state.output_bus_cfg.flags 452 + * field is set to the next bridge 453 + * &drm_bridge_state.input_bus_cfg.flags value or 454 + * &drm_connector.display_info.bus_flags if the bridge is the last 455 + * element in the chain. 456 + * 457 + * RETURNS: 458 + * zero if the check passed, a negative error code otherwise. 459 + */ 460 + int (*atomic_check)(struct drm_bridge *bridge, 461 + struct drm_bridge_state *bridge_state, 462 + struct drm_crtc_state *crtc_state, 463 + struct drm_connector_state *conn_state); 464 + 465 + /** 466 + * @atomic_reset: 467 + * 468 + * Reset the bridge to a predefined state (or retrieve its current 469 + * state) and return a &drm_bridge_state object matching this state. 470 + * This function is called at attach time. 471 + * 472 + * The atomic_reset hook is optional. When not implemented the core 473 + * allocates a new state and calls &__drm_atomic_helper_bridge_reset(). 474 + * 475 + * RETURNS: 476 + * A valid drm_bridge_state object in case of success, an ERR_PTR() 477 + * giving the reason of the failure otherwise. 478 + */ 479 + struct drm_bridge_state *(*atomic_reset)(struct drm_bridge *bridge); 404 480 }; 405 481 406 482 /** ··· 582 380 * struct drm_bridge - central DRM bridge control structure 583 381 */ 584 382 struct drm_bridge { 383 + /** @base: inherit from &drm_private_object */ 384 + struct drm_private_obj base; 585 385 /** @dev: DRM device this bridge belongs to */ 586 386 struct drm_device *dev; 587 387 /** @encoder: encoder to which this bridge is connected */ ··· 607 403 /** @driver_private: pointer to the bridge driver's internal context */ 608 404 void *driver_private; 609 405 }; 406 + 407 + static inline struct drm_bridge * 408 + drm_priv_to_bridge(struct drm_private_obj *priv) 409 + { 410 + return container_of(priv, struct drm_bridge, base); 411 + } 610 412 611 413 void drm_bridge_add(struct drm_bridge *bridge); 612 414 void drm_bridge_remove(struct drm_bridge *bridge); ··· 692 482 void drm_bridge_chain_pre_enable(struct drm_bridge *bridge); 693 483 void drm_bridge_chain_enable(struct drm_bridge *bridge); 694 484 485 + int drm_atomic_bridge_chain_check(struct drm_bridge *bridge, 486 + struct drm_crtc_state *crtc_state, 487 + struct drm_connector_state *conn_state); 695 488 void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge, 696 489 struct drm_atomic_state *state); 697 490 void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge, ··· 703 490 struct drm_atomic_state *state); 704 491 void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge, 705 492 struct drm_atomic_state *state); 493 + 494 + u32 * 495 + drm_atomic_helper_bridge_propagate_bus_fmt(struct drm_bridge *bridge, 496 + struct drm_bridge_state *bridge_state, 497 + struct drm_crtc_state *crtc_state, 498 + struct drm_connector_state *conn_state, 499 + u32 output_fmt, 500 + unsigned int *num_input_fmts); 501 + 502 + void __drm_atomic_helper_bridge_reset(struct drm_bridge *bridge, 503 + struct drm_bridge_state *state); 504 + void __drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge, 505 + struct drm_bridge_state *new); 506 + 507 + static inline struct drm_bridge_state * 508 + drm_atomic_get_bridge_state(struct drm_atomic_state *state, 509 + struct drm_bridge *bridge) 510 + { 511 + struct drm_private_state *obj_state; 512 + 513 + obj_state = drm_atomic_get_private_obj_state(state, &bridge->base); 514 + if (IS_ERR(obj_state)) 515 + return ERR_CAST(obj_state); 516 + 517 + return drm_priv_to_bridge_state(obj_state); 518 + } 519 + 520 + static inline struct drm_bridge_state * 521 + drm_atomic_get_old_bridge_state(struct drm_atomic_state *state, 522 + struct drm_bridge *bridge) 523 + { 524 + struct drm_private_state *obj_state; 525 + 526 + obj_state = drm_atomic_get_old_private_obj_state(state, &bridge->base); 527 + if (!obj_state) 528 + return NULL; 529 + 530 + return drm_priv_to_bridge_state(obj_state); 531 + } 532 + 533 + static inline struct drm_bridge_state * 534 + drm_atomic_get_new_bridge_state(struct drm_atomic_state *state, 535 + struct drm_bridge *bridge) 536 + { 537 + struct drm_private_state *obj_state; 538 + 539 + obj_state = drm_atomic_get_new_private_obj_state(state, &bridge->base); 540 + if (!obj_state) 541 + return NULL; 542 + 543 + return drm_priv_to_bridge_state(obj_state); 544 + } 706 545 707 546 #ifdef CONFIG_DRM_PANEL_BRIDGE 708 547 struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel);
+2 -5
include/drm/drm_gem_vram_helper.h
··· 93 93 } 94 94 95 95 struct drm_gem_vram_object *drm_gem_vram_create(struct drm_device *dev, 96 - struct ttm_bo_device *bdev, 97 96 size_t size, 98 - unsigned long pg_align, 99 - bool interruptible); 97 + unsigned long pg_align); 100 98 void drm_gem_vram_put(struct drm_gem_vram_object *gbo); 101 99 u64 drm_gem_vram_mmap_offset(struct drm_gem_vram_object *gbo); 102 100 s64 drm_gem_vram_offset(struct drm_gem_vram_object *gbo); ··· 108 110 109 111 int drm_gem_vram_fill_create_dumb(struct drm_file *file, 110 112 struct drm_device *dev, 111 - struct ttm_bo_device *bdev, 112 113 unsigned long pg_align, 113 - bool interruptible, 114 + unsigned long pitch_align, 114 115 struct drm_mode_create_dumb *args); 115 116 116 117 /*
+1
include/linux/fb.h
··· 625 625 extern struct fb_info *registered_fb[FB_MAX]; 626 626 extern int num_registered_fb; 627 627 extern bool fb_center_logo; 628 + extern int fb_logo_count; 628 629 extern struct class *fb_class; 629 630 630 631 #define for_each_registered_fb(i) \