.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2009 Nokia Corporation |
---|
3 | 4 | * Author: Tomi Valkeinen <tomi.valkeinen@ti.com> |
---|
4 | 5 | * |
---|
5 | 6 | * Some code and ideas taken from drivers/video/omap/ driver |
---|
6 | 7 | * by Imre Deak. |
---|
7 | | - * |
---|
8 | | - * This program is free software; you can redistribute it and/or modify it |
---|
9 | | - * under the terms of the GNU General Public License version 2 as published by |
---|
10 | | - * the Free Software Foundation. |
---|
11 | | - * |
---|
12 | | - * This program is distributed in the hope that it will be useful, but WITHOUT |
---|
13 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
---|
14 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
---|
15 | | - * more details. |
---|
16 | | - * |
---|
17 | | - * You should have received a copy of the GNU General Public License along with |
---|
18 | | - * this program. If not, see <http://www.gnu.org/licenses/>. |
---|
19 | 8 | */ |
---|
20 | 9 | |
---|
21 | 10 | #define DSS_SUBSYS_NAME "DISPC" |
---|
.. | .. |
---|
125 | 114 | const unsigned int num_reg_fields; |
---|
126 | 115 | const enum omap_overlay_caps *overlay_caps; |
---|
127 | 116 | const u32 **supported_color_modes; |
---|
| 117 | + const u32 *supported_scaler_color_modes; |
---|
128 | 118 | unsigned int num_mgrs; |
---|
129 | 119 | unsigned int num_ovls; |
---|
130 | 120 | unsigned int buffer_size_unit; |
---|
.. | .. |
---|
195 | 185 | |
---|
196 | 186 | struct regmap *syscon_pol; |
---|
197 | 187 | u32 syscon_pol_offset; |
---|
198 | | - |
---|
199 | | - /* DISPC_CONTROL & DISPC_CONFIG lock*/ |
---|
200 | | - spinlock_t control_lock; |
---|
201 | 188 | }; |
---|
202 | 189 | |
---|
203 | 190 | enum omap_color_component { |
---|
.. | .. |
---|
379 | 366 | static u32 mgr_fld_read(struct dispc_device *dispc, enum omap_channel channel, |
---|
380 | 367 | enum mgr_reg_fields regfld) |
---|
381 | 368 | { |
---|
382 | | - const struct dispc_reg_field rfld = mgr_desc[channel].reg_desc[regfld]; |
---|
| 369 | + const struct dispc_reg_field *rfld = &mgr_desc[channel].reg_desc[regfld]; |
---|
383 | 370 | |
---|
384 | | - return REG_GET(dispc, rfld.reg, rfld.high, rfld.low); |
---|
| 371 | + return REG_GET(dispc, rfld->reg, rfld->high, rfld->low); |
---|
385 | 372 | } |
---|
386 | 373 | |
---|
387 | 374 | static void mgr_fld_write(struct dispc_device *dispc, enum omap_channel channel, |
---|
388 | 375 | enum mgr_reg_fields regfld, int val) |
---|
389 | 376 | { |
---|
390 | | - const struct dispc_reg_field rfld = mgr_desc[channel].reg_desc[regfld]; |
---|
391 | | - const bool need_lock = rfld.reg == DISPC_CONTROL || rfld.reg == DISPC_CONFIG; |
---|
392 | | - unsigned long flags; |
---|
| 377 | + const struct dispc_reg_field *rfld = &mgr_desc[channel].reg_desc[regfld]; |
---|
393 | 378 | |
---|
394 | | - if (need_lock) { |
---|
395 | | - spin_lock_irqsave(&dispc->control_lock, flags); |
---|
396 | | - REG_FLD_MOD(dispc, rfld.reg, val, rfld.high, rfld.low); |
---|
397 | | - spin_unlock_irqrestore(&dispc->control_lock, flags); |
---|
398 | | - } else { |
---|
399 | | - REG_FLD_MOD(dispc, rfld.reg, val, rfld.high, rfld.low); |
---|
400 | | - } |
---|
| 379 | + REG_FLD_MOD(dispc, rfld->reg, val, rfld->high, rfld->low); |
---|
401 | 380 | } |
---|
402 | 381 | |
---|
403 | 382 | static int dispc_get_num_ovls(struct dispc_device *dispc) |
---|
.. | .. |
---|
414 | 393 | enum dispc_feat_reg_field id, |
---|
415 | 394 | u8 *start, u8 *end) |
---|
416 | 395 | { |
---|
417 | | - if (id >= dispc->feat->num_reg_fields) |
---|
418 | | - BUG(); |
---|
| 396 | + BUG_ON(id >= dispc->feat->num_reg_fields); |
---|
419 | 397 | |
---|
420 | 398 | *start = dispc->feat->reg_fields[id].start; |
---|
421 | 399 | *end = dispc->feat->reg_fields[id].end; |
---|
.. | .. |
---|
1138 | 1116 | } |
---|
1139 | 1117 | |
---|
1140 | 1118 | REG_FLD_MOD(dispc, DISPC_OVL_ATTRIBUTES(plane), m, 4, 1); |
---|
1141 | | -} |
---|
1142 | | - |
---|
1143 | | -static bool format_is_yuv(u32 fourcc) |
---|
1144 | | -{ |
---|
1145 | | - switch (fourcc) { |
---|
1146 | | - case DRM_FORMAT_YUYV: |
---|
1147 | | - case DRM_FORMAT_UYVY: |
---|
1148 | | - case DRM_FORMAT_NV12: |
---|
1149 | | - return true; |
---|
1150 | | - default: |
---|
1151 | | - return false; |
---|
1152 | | - } |
---|
1153 | 1119 | } |
---|
1154 | 1120 | |
---|
1155 | 1121 | static void dispc_ovl_configure_burst_type(struct dispc_device *dispc, |
---|
.. | .. |
---|
1910 | 1876 | int scale_x = out_width != orig_width; |
---|
1911 | 1877 | int scale_y = out_height != orig_height; |
---|
1912 | 1878 | bool chroma_upscale = plane != OMAP_DSS_WB; |
---|
| 1879 | + const struct drm_format_info *info; |
---|
| 1880 | + |
---|
| 1881 | + info = drm_format_info(fourcc); |
---|
1913 | 1882 | |
---|
1914 | 1883 | if (!dispc_has_feature(dispc, FEAT_HANDLE_UV_SEPARATE)) |
---|
1915 | 1884 | return; |
---|
1916 | 1885 | |
---|
1917 | | - if (!format_is_yuv(fourcc)) { |
---|
| 1886 | + if (!info->is_yuv) { |
---|
1918 | 1887 | /* reset chroma resampling for RGB formats */ |
---|
1919 | 1888 | if (plane != OMAP_DSS_WB) |
---|
1920 | 1889 | REG_FLD_MOD(dispc, DISPC_OVL_ATTRIBUTES2(plane), |
---|
.. | .. |
---|
2530 | 2499 | if (width == out_width && height == out_height) |
---|
2531 | 2500 | return 0; |
---|
2532 | 2501 | |
---|
| 2502 | + if (dispc->feat->supported_scaler_color_modes) { |
---|
| 2503 | + const u32 *modes = dispc->feat->supported_scaler_color_modes; |
---|
| 2504 | + unsigned int i; |
---|
| 2505 | + |
---|
| 2506 | + for (i = 0; modes[i]; ++i) { |
---|
| 2507 | + if (modes[i] == fourcc) |
---|
| 2508 | + break; |
---|
| 2509 | + } |
---|
| 2510 | + |
---|
| 2511 | + if (modes[i] == 0) |
---|
| 2512 | + return -EINVAL; |
---|
| 2513 | + } |
---|
| 2514 | + |
---|
2533 | 2515 | if (plane == OMAP_DSS_WB) { |
---|
2534 | 2516 | switch (fourcc) { |
---|
2535 | 2517 | case DRM_FORMAT_NV12: |
---|
.. | .. |
---|
2624 | 2606 | unsigned int offset0, offset1; |
---|
2625 | 2607 | s32 row_inc; |
---|
2626 | 2608 | s32 pix_inc; |
---|
2627 | | - u16 frame_width, frame_height; |
---|
| 2609 | + u16 frame_width; |
---|
2628 | 2610 | unsigned int field_offset = 0; |
---|
2629 | 2611 | u16 in_height = height; |
---|
2630 | 2612 | u16 in_width = width; |
---|
.. | .. |
---|
2632 | 2614 | bool ilace = !!(vm->flags & DISPLAY_FLAGS_INTERLACED); |
---|
2633 | 2615 | unsigned long pclk = dispc_plane_pclk_rate(dispc, plane); |
---|
2634 | 2616 | unsigned long lclk = dispc_plane_lclk_rate(dispc, plane); |
---|
| 2617 | + const struct drm_format_info *info; |
---|
| 2618 | + |
---|
| 2619 | + info = drm_format_info(fourcc); |
---|
2635 | 2620 | |
---|
2636 | 2621 | /* when setting up WB, dispc_plane_pclk_rate() returns 0 */ |
---|
2637 | 2622 | if (plane == OMAP_DSS_WB) |
---|
.. | .. |
---|
2640 | 2625 | if (paddr == 0 && rotation_type != OMAP_DSS_ROT_TILER) |
---|
2641 | 2626 | return -EINVAL; |
---|
2642 | 2627 | |
---|
2643 | | - if (format_is_yuv(fourcc) && (in_width & 1)) { |
---|
| 2628 | + if (info->is_yuv && (in_width & 1)) { |
---|
2644 | 2629 | DSSERR("input width %d is not even for YUV format\n", in_width); |
---|
2645 | 2630 | return -EINVAL; |
---|
2646 | 2631 | } |
---|
.. | .. |
---|
2680 | 2665 | DSSDBG("predecimation %d x %x, new input size %d x %d\n", |
---|
2681 | 2666 | x_predecim, y_predecim, in_width, in_height); |
---|
2682 | 2667 | |
---|
2683 | | - if (format_is_yuv(fourcc) && (in_width & 1)) { |
---|
| 2668 | + if (info->is_yuv && (in_width & 1)) { |
---|
2684 | 2669 | DSSDBG("predecimated input width is not even for YUV format\n"); |
---|
2685 | 2670 | DSSDBG("adjusting input width %d -> %d\n", |
---|
2686 | 2671 | in_width, in_width & ~1); |
---|
.. | .. |
---|
2688 | 2673 | in_width &= ~1; |
---|
2689 | 2674 | } |
---|
2690 | 2675 | |
---|
2691 | | - if (format_is_yuv(fourcc)) |
---|
| 2676 | + if (info->is_yuv) |
---|
2692 | 2677 | cconv = 1; |
---|
2693 | 2678 | |
---|
2694 | 2679 | if (ilace && !fieldmode) { |
---|
.. | .. |
---|
2714 | 2699 | row_inc = 0; |
---|
2715 | 2700 | pix_inc = 0; |
---|
2716 | 2701 | |
---|
2717 | | - if (plane == OMAP_DSS_WB) { |
---|
| 2702 | + if (plane == OMAP_DSS_WB) |
---|
2718 | 2703 | frame_width = out_width; |
---|
2719 | | - frame_height = out_height; |
---|
2720 | | - } else { |
---|
| 2704 | + else |
---|
2721 | 2705 | frame_width = in_width; |
---|
2722 | | - frame_height = height; |
---|
2723 | | - } |
---|
2724 | 2706 | |
---|
2725 | 2707 | calc_offset(screen_width, frame_width, |
---|
2726 | 2708 | fourcc, fieldmode, field_offset, |
---|
.. | .. |
---|
2902 | 2884 | REG_FLD_MOD(dispc, DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 0, 0); |
---|
2903 | 2885 | |
---|
2904 | 2886 | return 0; |
---|
2905 | | -} |
---|
2906 | | - |
---|
2907 | | -static enum omap_dss_output_id |
---|
2908 | | -dispc_mgr_get_supported_outputs(struct dispc_device *dispc, |
---|
2909 | | - enum omap_channel channel) |
---|
2910 | | -{ |
---|
2911 | | - return dss_get_supported_outputs(dispc->dss, channel); |
---|
2912 | 2887 | } |
---|
2913 | 2888 | |
---|
2914 | 2889 | static void dispc_lcd_enable_signal_polarity(struct dispc_device *dispc, |
---|
.. | .. |
---|
3120 | 3095 | return pclk <= dispc->feat->max_tv_pclk; |
---|
3121 | 3096 | } |
---|
3122 | 3097 | |
---|
3123 | | -bool dispc_mgr_timings_ok(struct dispc_device *dispc, enum omap_channel channel, |
---|
3124 | | - const struct videomode *vm) |
---|
| 3098 | +static int dispc_mgr_check_timings(struct dispc_device *dispc, |
---|
| 3099 | + enum omap_channel channel, |
---|
| 3100 | + const struct videomode *vm) |
---|
3125 | 3101 | { |
---|
3126 | 3102 | if (!_dispc_mgr_size_ok(dispc, vm->hactive, vm->vactive)) |
---|
3127 | | - return false; |
---|
| 3103 | + return MODE_BAD; |
---|
3128 | 3104 | |
---|
3129 | 3105 | if (!_dispc_mgr_pclk_ok(dispc, channel, vm->pixelclock)) |
---|
3130 | | - return false; |
---|
| 3106 | + return MODE_BAD; |
---|
3131 | 3107 | |
---|
3132 | 3108 | if (dss_mgr_is_lcd(channel)) { |
---|
3133 | 3109 | /* TODO: OMAP4+ supports interlace for LCD outputs */ |
---|
3134 | 3110 | if (vm->flags & DISPLAY_FLAGS_INTERLACED) |
---|
3135 | | - return false; |
---|
| 3111 | + return MODE_BAD; |
---|
3136 | 3112 | |
---|
3137 | 3113 | if (!_dispc_lcd_timings_ok(dispc, vm->hsync_len, |
---|
3138 | 3114 | vm->hfront_porch, vm->hback_porch, |
---|
3139 | 3115 | vm->vsync_len, vm->vfront_porch, |
---|
3140 | 3116 | vm->vback_porch)) |
---|
3141 | | - return false; |
---|
| 3117 | + return MODE_BAD; |
---|
3142 | 3118 | } |
---|
3143 | 3119 | |
---|
3144 | | - return true; |
---|
| 3120 | + return MODE_OK; |
---|
3145 | 3121 | } |
---|
3146 | 3122 | |
---|
3147 | 3123 | static void _dispc_mgr_set_lcd_timings(struct dispc_device *dispc, |
---|
.. | .. |
---|
3161 | 3137 | dispc_write_reg(dispc, DISPC_TIMING_H(channel), timing_h); |
---|
3162 | 3138 | dispc_write_reg(dispc, DISPC_TIMING_V(channel), timing_v); |
---|
3163 | 3139 | |
---|
3164 | | - if (vm->flags & DISPLAY_FLAGS_VSYNC_HIGH) |
---|
3165 | | - vs = false; |
---|
3166 | | - else |
---|
3167 | | - vs = true; |
---|
3168 | | - |
---|
3169 | | - if (vm->flags & DISPLAY_FLAGS_HSYNC_HIGH) |
---|
3170 | | - hs = false; |
---|
3171 | | - else |
---|
3172 | | - hs = true; |
---|
3173 | | - |
---|
3174 | | - if (vm->flags & DISPLAY_FLAGS_DE_HIGH) |
---|
3175 | | - de = false; |
---|
3176 | | - else |
---|
3177 | | - de = true; |
---|
3178 | | - |
---|
3179 | | - if (vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE) |
---|
3180 | | - ipc = false; |
---|
3181 | | - else |
---|
3182 | | - ipc = true; |
---|
3183 | | - |
---|
3184 | | - /* always use the 'rf' setting */ |
---|
3185 | | - onoff = true; |
---|
3186 | | - |
---|
3187 | | - if (vm->flags & DISPLAY_FLAGS_SYNC_POSEDGE) |
---|
3188 | | - rf = true; |
---|
3189 | | - else |
---|
3190 | | - rf = false; |
---|
| 3140 | + vs = !!(vm->flags & DISPLAY_FLAGS_VSYNC_LOW); |
---|
| 3141 | + hs = !!(vm->flags & DISPLAY_FLAGS_HSYNC_LOW); |
---|
| 3142 | + de = !!(vm->flags & DISPLAY_FLAGS_DE_LOW); |
---|
| 3143 | + ipc = !!(vm->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE); |
---|
| 3144 | + onoff = true; /* always use the 'rf' setting */ |
---|
| 3145 | + rf = !!(vm->flags & DISPLAY_FLAGS_SYNC_POSEDGE); |
---|
3191 | 3146 | |
---|
3192 | 3147 | l = FLD_VAL(onoff, 17, 17) | |
---|
3193 | 3148 | FLD_VAL(rf, 16, 16) | |
---|
.. | .. |
---|
3243 | 3198 | |
---|
3244 | 3199 | DSSDBG("channel %d xres %u yres %u\n", channel, t.hactive, t.vactive); |
---|
3245 | 3200 | |
---|
3246 | | - if (!dispc_mgr_timings_ok(dispc, channel, &t)) { |
---|
| 3201 | + if (dispc_mgr_check_timings(dispc, channel, &t)) { |
---|
3247 | 3202 | BUG(); |
---|
3248 | 3203 | return; |
---|
3249 | 3204 | } |
---|
.. | .. |
---|
4251 | 4206 | DRM_FORMAT_RGBX8888), |
---|
4252 | 4207 | }; |
---|
4253 | 4208 | |
---|
| 4209 | +static const u32 omap3_dispc_supported_scaler_color_modes[] = { |
---|
| 4210 | + DRM_FORMAT_XRGB8888, DRM_FORMAT_RGB565, DRM_FORMAT_YUYV, |
---|
| 4211 | + DRM_FORMAT_UYVY, |
---|
| 4212 | + 0, |
---|
| 4213 | +}; |
---|
| 4214 | + |
---|
4254 | 4215 | static const struct dispc_features omap24xx_dispc_feats = { |
---|
4255 | 4216 | .sw_start = 5, |
---|
4256 | 4217 | .fp_start = 15, |
---|
.. | .. |
---|
4279 | 4240 | .num_reg_fields = ARRAY_SIZE(omap2_dispc_reg_fields), |
---|
4280 | 4241 | .overlay_caps = omap2_dispc_overlay_caps, |
---|
4281 | 4242 | .supported_color_modes = omap2_dispc_supported_color_modes, |
---|
| 4243 | + .supported_scaler_color_modes = COLOR_ARRAY(DRM_FORMAT_XRGB8888), |
---|
4282 | 4244 | .num_mgrs = 2, |
---|
4283 | 4245 | .num_ovls = 3, |
---|
4284 | 4246 | .buffer_size_unit = 1, |
---|
.. | .. |
---|
4313 | 4275 | .num_reg_fields = ARRAY_SIZE(omap3_dispc_reg_fields), |
---|
4314 | 4276 | .overlay_caps = omap3430_dispc_overlay_caps, |
---|
4315 | 4277 | .supported_color_modes = omap3_dispc_supported_color_modes, |
---|
| 4278 | + .supported_scaler_color_modes = omap3_dispc_supported_scaler_color_modes, |
---|
4316 | 4279 | .num_mgrs = 2, |
---|
4317 | 4280 | .num_ovls = 3, |
---|
4318 | 4281 | .buffer_size_unit = 1, |
---|
.. | .. |
---|
4347 | 4310 | .num_reg_fields = ARRAY_SIZE(omap3_dispc_reg_fields), |
---|
4348 | 4311 | .overlay_caps = omap3430_dispc_overlay_caps, |
---|
4349 | 4312 | .supported_color_modes = omap3_dispc_supported_color_modes, |
---|
| 4313 | + .supported_scaler_color_modes = omap3_dispc_supported_scaler_color_modes, |
---|
4350 | 4314 | .num_mgrs = 2, |
---|
4351 | 4315 | .num_ovls = 3, |
---|
4352 | 4316 | .buffer_size_unit = 1, |
---|
.. | .. |
---|
4381 | 4345 | .num_reg_fields = ARRAY_SIZE(omap3_dispc_reg_fields), |
---|
4382 | 4346 | .overlay_caps = omap3630_dispc_overlay_caps, |
---|
4383 | 4347 | .supported_color_modes = omap3_dispc_supported_color_modes, |
---|
| 4348 | + .supported_scaler_color_modes = omap3_dispc_supported_scaler_color_modes, |
---|
4384 | 4349 | .num_mgrs = 2, |
---|
4385 | 4350 | .num_ovls = 3, |
---|
4386 | 4351 | .buffer_size_unit = 1, |
---|
.. | .. |
---|
4415 | 4380 | .num_reg_fields = ARRAY_SIZE(omap3_dispc_reg_fields), |
---|
4416 | 4381 | .overlay_caps = omap3430_dispc_overlay_caps, |
---|
4417 | 4382 | .supported_color_modes = omap3_dispc_supported_color_modes, |
---|
| 4383 | + .supported_scaler_color_modes = omap3_dispc_supported_scaler_color_modes, |
---|
4418 | 4384 | .num_mgrs = 1, |
---|
4419 | 4385 | .num_ovls = 3, |
---|
4420 | 4386 | .buffer_size_unit = 1, |
---|
.. | .. |
---|
4635 | 4601 | i734_buf.size = i734.ovli.width * i734.ovli.height * |
---|
4636 | 4602 | color_mode_to_bpp(i734.ovli.fourcc) / 8; |
---|
4637 | 4603 | |
---|
4638 | | - i734_buf.vaddr = dma_alloc_writecombine(&dispc->pdev->dev, |
---|
4639 | | - i734_buf.size, &i734_buf.paddr, |
---|
4640 | | - GFP_KERNEL); |
---|
| 4604 | + i734_buf.vaddr = dma_alloc_wc(&dispc->pdev->dev, i734_buf.size, |
---|
| 4605 | + &i734_buf.paddr, GFP_KERNEL); |
---|
4641 | 4606 | if (!i734_buf.vaddr) { |
---|
4642 | | - dev_err(&dispc->pdev->dev, "%s: dma_alloc_writecombine failed\n", |
---|
| 4607 | + dev_err(&dispc->pdev->dev, "%s: dma_alloc_wc failed\n", |
---|
4643 | 4608 | __func__); |
---|
4644 | 4609 | return -ENOMEM; |
---|
4645 | 4610 | } |
---|
.. | .. |
---|
4652 | 4617 | if (!dispc->feat->has_gamma_i734_bug) |
---|
4653 | 4618 | return; |
---|
4654 | 4619 | |
---|
4655 | | - dma_free_writecombine(&dispc->pdev->dev, i734_buf.size, i734_buf.vaddr, |
---|
4656 | | - i734_buf.paddr); |
---|
| 4620 | + dma_free_wc(&dispc->pdev->dev, i734_buf.size, i734_buf.vaddr, |
---|
| 4621 | + i734_buf.paddr); |
---|
4657 | 4622 | } |
---|
4658 | 4623 | |
---|
4659 | 4624 | static void dispc_errata_i734_wa(struct dispc_device *dispc) |
---|
.. | .. |
---|
4740 | 4705 | .mgr_go_busy = dispc_mgr_go_busy, |
---|
4741 | 4706 | .mgr_go = dispc_mgr_go, |
---|
4742 | 4707 | .mgr_set_lcd_config = dispc_mgr_set_lcd_config, |
---|
| 4708 | + .mgr_check_timings = dispc_mgr_check_timings, |
---|
4743 | 4709 | .mgr_set_timings = dispc_mgr_set_timings, |
---|
4744 | 4710 | .mgr_setup = dispc_mgr_setup, |
---|
4745 | | - .mgr_get_supported_outputs = dispc_mgr_get_supported_outputs, |
---|
4746 | 4711 | .mgr_gamma_size = dispc_mgr_gamma_size, |
---|
4747 | 4712 | .mgr_set_gamma = dispc_mgr_set_gamma, |
---|
4748 | 4713 | |
---|
.. | .. |
---|
4794 | 4759 | dispc->pdev = pdev; |
---|
4795 | 4760 | platform_set_drvdata(pdev, dispc); |
---|
4796 | 4761 | dispc->dss = dss; |
---|
4797 | | - |
---|
4798 | | - spin_lock_init(&dispc->control_lock); |
---|
4799 | 4762 | |
---|
4800 | 4763 | /* |
---|
4801 | 4764 | * The OMAP3-based models can't be told apart using the compatible |
---|
.. | .. |
---|
4952 | 4915 | static const struct dev_pm_ops dispc_pm_ops = { |
---|
4953 | 4916 | .runtime_suspend = dispc_runtime_suspend, |
---|
4954 | 4917 | .runtime_resume = dispc_runtime_resume, |
---|
| 4918 | + SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) |
---|
4955 | 4919 | }; |
---|
4956 | 4920 | |
---|
4957 | 4921 | struct platform_driver omap_dispchw_driver = { |
---|