aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2018-04-25 21:09:04 -0400
committerDave Airlie <airlied@redhat.com>2018-04-25 21:09:04 -0400
commit14cdea89459e71e38027aa4fb1099c29f4c53316 (patch)
tree6a0606e5f281a802e31fb9f6763c1d87f92ad1fa
parent8eb8ad52fbc99aa87f1c56db378ee910833ed780 (diff)
parent789d4c300e10eb2096ee83c3497118e67ccc951e (diff)
Merge tag 'drm-msm-fixes-2018-04-25' of git://people.freedesktop.org/~robclark/linux into drm-fixes
A few fixes for 4.17.. thanks to Sean for helping pull together some of the display related fixes while I was off in compute-land. * tag 'drm-msm-fixes-2018-04-25' of git://people.freedesktop.org/~robclark/linux: drm/msm: don't deref error pointer in the msm_fbdev_create error path drm/msm/dsi: use correct enum in dsi_get_cmd_fmt drm/msm: Fix possible null dereference on failure of get_pages() drm/msm: Add modifier to mdp_get_format arguments drm/msm: Mark the crtc->state->event consumed drm/msm/dsi: implement auto PHY timing calculator for 10nm PHY drm/msm/dsi: check video mode engine status before waiting drm/msm/dsi: check return value for video done waits
-rw-r--r--drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c1
-rw-r--r--drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c1
-rw-r--r--drivers/gpu/drm/msm/disp/mdp_format.c3
-rw-r--r--drivers/gpu/drm/msm/disp/mdp_kms.h2
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_host.c16
-rw-r--r--drivers/gpu/drm/msm/dsi/phy/dsi_phy.c109
-rw-r--r--drivers/gpu/drm/msm/dsi/phy/dsi_phy.h2
-rw-r--r--drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c28
-rw-r--r--drivers/gpu/drm/msm/msm_fb.c3
-rw-r--r--drivers/gpu/drm/msm/msm_fbdev.c11
-rw-r--r--drivers/gpu/drm/msm/msm_gem.c20
-rw-r--r--drivers/gpu/drm/msm/msm_kms.h5
12 files changed, 147 insertions, 54 deletions
diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
index 6e5e1aa54ce1..b001699297c4 100644
--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
@@ -351,6 +351,7 @@ static void mdp4_crtc_atomic_flush(struct drm_crtc *crtc,
351 351
352 spin_lock_irqsave(&dev->event_lock, flags); 352 spin_lock_irqsave(&dev->event_lock, flags);
353 mdp4_crtc->event = crtc->state->event; 353 mdp4_crtc->event = crtc->state->event;
354 crtc->state->event = NULL;
354 spin_unlock_irqrestore(&dev->event_lock, flags); 355 spin_unlock_irqrestore(&dev->event_lock, flags);
355 356
356 blend_setup(crtc); 357 blend_setup(crtc);
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
index 9893e43ba6c5..76b96081916f 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
@@ -708,6 +708,7 @@ static void mdp5_crtc_atomic_flush(struct drm_crtc *crtc,
708 708
709 spin_lock_irqsave(&dev->event_lock, flags); 709 spin_lock_irqsave(&dev->event_lock, flags);
710 mdp5_crtc->event = crtc->state->event; 710 mdp5_crtc->event = crtc->state->event;
711 crtc->state->event = NULL;
711 spin_unlock_irqrestore(&dev->event_lock, flags); 712 spin_unlock_irqrestore(&dev->event_lock, flags);
712 713
713 /* 714 /*
diff --git a/drivers/gpu/drm/msm/disp/mdp_format.c b/drivers/gpu/drm/msm/disp/mdp_format.c
index b4a8aa4490ee..005760bee708 100644
--- a/drivers/gpu/drm/msm/disp/mdp_format.c
+++ b/drivers/gpu/drm/msm/disp/mdp_format.c
@@ -171,7 +171,8 @@ uint32_t mdp_get_formats(uint32_t *pixel_formats, uint32_t max_formats,
171 return i; 171 return i;
172} 172}
173 173
174const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format) 174const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format,
175 uint64_t modifier)
175{ 176{
176 int i; 177 int i;
177 for (i = 0; i < ARRAY_SIZE(formats); i++) { 178 for (i = 0; i < ARRAY_SIZE(formats); i++) {
diff --git a/drivers/gpu/drm/msm/disp/mdp_kms.h b/drivers/gpu/drm/msm/disp/mdp_kms.h
index 1185487e7e5e..4fa8dbe4e165 100644
--- a/drivers/gpu/drm/msm/disp/mdp_kms.h
+++ b/drivers/gpu/drm/msm/disp/mdp_kms.h
@@ -98,7 +98,7 @@ struct mdp_format {
98#define MDP_FORMAT_IS_YUV(mdp_format) ((mdp_format)->is_yuv) 98#define MDP_FORMAT_IS_YUV(mdp_format) ((mdp_format)->is_yuv)
99 99
100uint32_t mdp_get_formats(uint32_t *formats, uint32_t max_formats, bool rgb_only); 100uint32_t mdp_get_formats(uint32_t *formats, uint32_t max_formats, bool rgb_only);
101const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format); 101const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format, uint64_t modifier);
102 102
103/* MDP capabilities */ 103/* MDP capabilities */
104#define MDP_CAP_SMP BIT(0) /* Shared Memory Pool */ 104#define MDP_CAP_SMP BIT(0) /* Shared Memory Pool */
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 7a03a9489708..8baba30d6c65 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -173,6 +173,7 @@ struct msm_dsi_host {
173 173
174 bool registered; 174 bool registered;
175 bool power_on; 175 bool power_on;
176 bool enabled;
176 int irq; 177 int irq;
177}; 178};
178 179
@@ -775,7 +776,7 @@ static inline enum dsi_cmd_dst_format dsi_get_cmd_fmt(
775 switch (mipi_fmt) { 776 switch (mipi_fmt) {
776 case MIPI_DSI_FMT_RGB888: return CMD_DST_FORMAT_RGB888; 777 case MIPI_DSI_FMT_RGB888: return CMD_DST_FORMAT_RGB888;
777 case MIPI_DSI_FMT_RGB666_PACKED: 778 case MIPI_DSI_FMT_RGB666_PACKED:
778 case MIPI_DSI_FMT_RGB666: return VID_DST_FORMAT_RGB666; 779 case MIPI_DSI_FMT_RGB666: return CMD_DST_FORMAT_RGB666;
779 case MIPI_DSI_FMT_RGB565: return CMD_DST_FORMAT_RGB565; 780 case MIPI_DSI_FMT_RGB565: return CMD_DST_FORMAT_RGB565;
780 default: return CMD_DST_FORMAT_RGB888; 781 default: return CMD_DST_FORMAT_RGB888;
781 } 782 }
@@ -986,13 +987,19 @@ static void dsi_set_tx_power_mode(int mode, struct msm_dsi_host *msm_host)
986 987
987static void dsi_wait4video_done(struct msm_dsi_host *msm_host) 988static void dsi_wait4video_done(struct msm_dsi_host *msm_host)
988{ 989{
990 u32 ret = 0;
991 struct device *dev = &msm_host->pdev->dev;
992
989 dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_VIDEO_DONE, 1); 993 dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_VIDEO_DONE, 1);
990 994
991 reinit_completion(&msm_host->video_comp); 995 reinit_completion(&msm_host->video_comp);
992 996
993 wait_for_completion_timeout(&msm_host->video_comp, 997 ret = wait_for_completion_timeout(&msm_host->video_comp,
994 msecs_to_jiffies(70)); 998 msecs_to_jiffies(70));
995 999
1000 if (ret <= 0)
1001 dev_err(dev, "wait for video done timed out\n");
1002
996 dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_VIDEO_DONE, 0); 1003 dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_VIDEO_DONE, 0);
997} 1004}
998 1005
@@ -1001,7 +1008,7 @@ static void dsi_wait4video_eng_busy(struct msm_dsi_host *msm_host)
1001 if (!(msm_host->mode_flags & MIPI_DSI_MODE_VIDEO)) 1008 if (!(msm_host->mode_flags & MIPI_DSI_MODE_VIDEO))
1002 return; 1009 return;
1003 1010
1004 if (msm_host->power_on) { 1011 if (msm_host->power_on && msm_host->enabled) {
1005 dsi_wait4video_done(msm_host); 1012 dsi_wait4video_done(msm_host);
1006 /* delay 4 ms to skip BLLP */ 1013 /* delay 4 ms to skip BLLP */
1007 usleep_range(2000, 4000); 1014 usleep_range(2000, 4000);
@@ -2203,7 +2210,7 @@ int msm_dsi_host_enable(struct mipi_dsi_host *host)
2203 * pm_runtime_put_autosuspend(&msm_host->pdev->dev); 2210 * pm_runtime_put_autosuspend(&msm_host->pdev->dev);
2204 * } 2211 * }
2205 */ 2212 */
2206 2213 msm_host->enabled = true;
2207 return 0; 2214 return 0;
2208} 2215}
2209 2216
@@ -2211,6 +2218,7 @@ int msm_dsi_host_disable(struct mipi_dsi_host *host)
2211{ 2218{
2212 struct msm_dsi_host *msm_host = to_msm_dsi_host(host); 2219 struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
2213 2220
2221 msm_host->enabled = false;
2214 dsi_op_mode_config(msm_host, 2222 dsi_op_mode_config(msm_host,
2215 !!(msm_host->mode_flags & MIPI_DSI_MODE_VIDEO), false); 2223 !!(msm_host->mode_flags & MIPI_DSI_MODE_VIDEO), false);
2216 2224
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
index 8e9d5c255820..9a9fa0c75a13 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
@@ -265,6 +265,115 @@ int msm_dsi_dphy_timing_calc_v2(struct msm_dsi_dphy_timing *timing,
265 return 0; 265 return 0;
266} 266}
267 267
268int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing,
269 struct msm_dsi_phy_clk_request *clk_req)
270{
271 const unsigned long bit_rate = clk_req->bitclk_rate;
272 const unsigned long esc_rate = clk_req->escclk_rate;
273 s32 ui, ui_x8, lpx;
274 s32 tmax, tmin;
275 s32 pcnt0 = 50;
276 s32 pcnt1 = 50;
277 s32 pcnt2 = 10;
278 s32 pcnt3 = 30;
279 s32 pcnt4 = 10;
280 s32 pcnt5 = 2;
281 s32 coeff = 1000; /* Precision, should avoid overflow */
282 s32 hb_en, hb_en_ckln;
283 s32 temp;
284
285 if (!bit_rate || !esc_rate)
286 return -EINVAL;
287
288 timing->hs_halfbyte_en = 0;
289 hb_en = 0;
290 timing->hs_halfbyte_en_ckln = 0;
291 hb_en_ckln = 0;
292
293 ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000);
294 ui_x8 = ui << 3;
295 lpx = mult_frac(NSEC_PER_MSEC, coeff, esc_rate / 1000);
296
297 temp = S_DIV_ROUND_UP(38 * coeff, ui_x8);
298 tmin = max_t(s32, temp, 0);
299 temp = (95 * coeff) / ui_x8;
300 tmax = max_t(s32, temp, 0);
301 timing->clk_prepare = linear_inter(tmax, tmin, pcnt0, 0, false);
302
303 temp = 300 * coeff - (timing->clk_prepare << 3) * ui;
304 tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1;
305 tmax = (tmin > 255) ? 511 : 255;
306 timing->clk_zero = linear_inter(tmax, tmin, pcnt5, 0, false);
307
308 tmin = DIV_ROUND_UP(60 * coeff + 3 * ui, ui_x8);
309 temp = 105 * coeff + 12 * ui - 20 * coeff;
310 tmax = (temp + 3 * ui) / ui_x8;
311 timing->clk_trail = linear_inter(tmax, tmin, pcnt3, 0, false);
312
313 temp = S_DIV_ROUND_UP(40 * coeff + 4 * ui, ui_x8);
314 tmin = max_t(s32, temp, 0);
315 temp = (85 * coeff + 6 * ui) / ui_x8;
316 tmax = max_t(s32, temp, 0);
317 timing->hs_prepare = linear_inter(tmax, tmin, pcnt1, 0, false);
318
319 temp = 145 * coeff + 10 * ui - (timing->hs_prepare << 3) * ui;
320 tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1;
321 tmax = 255;
322 timing->hs_zero = linear_inter(tmax, tmin, pcnt4, 0, false);
323
324 tmin = DIV_ROUND_UP(60 * coeff + 4 * ui, ui_x8) - 1;
325 temp = 105 * coeff + 12 * ui - 20 * coeff;
326 tmax = (temp / ui_x8) - 1;
327 timing->hs_trail = linear_inter(tmax, tmin, pcnt3, 0, false);
328
329 temp = 50 * coeff + ((hb_en << 2) - 8) * ui;
330 timing->hs_rqst = S_DIV_ROUND_UP(temp, ui_x8);
331
332 tmin = DIV_ROUND_UP(100 * coeff, ui_x8) - 1;
333 tmax = 255;
334 timing->hs_exit = linear_inter(tmax, tmin, pcnt2, 0, false);
335
336 temp = 50 * coeff + ((hb_en_ckln << 2) - 8) * ui;
337 timing->hs_rqst_ckln = S_DIV_ROUND_UP(temp, ui_x8);
338
339 temp = 60 * coeff + 52 * ui - 43 * ui;
340 tmin = DIV_ROUND_UP(temp, ui_x8) - 1;
341 tmax = 63;
342 timing->shared_timings.clk_post =
343 linear_inter(tmax, tmin, pcnt2, 0, false);
344
345 temp = 8 * ui + (timing->clk_prepare << 3) * ui;
346 temp += (((timing->clk_zero + 3) << 3) + 11) * ui;
347 temp += hb_en_ckln ? (((timing->hs_rqst_ckln << 3) + 4) * ui) :
348 (((timing->hs_rqst_ckln << 3) + 8) * ui);
349 tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1;
350 tmax = 63;
351 if (tmin > tmax) {
352 temp = linear_inter(tmax << 1, tmin, pcnt2, 0, false);
353 timing->shared_timings.clk_pre = temp >> 1;
354 timing->shared_timings.clk_pre_inc_by_2 = 1;
355 } else {
356 timing->shared_timings.clk_pre =
357 linear_inter(tmax, tmin, pcnt2, 0, false);
358 timing->shared_timings.clk_pre_inc_by_2 = 0;
359 }
360
361 timing->ta_go = 3;
362 timing->ta_sure = 0;
363 timing->ta_get = 4;
364
365 DBG("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
366 timing->shared_timings.clk_pre, timing->shared_timings.clk_post,
367 timing->shared_timings.clk_pre_inc_by_2, timing->clk_zero,
368 timing->clk_trail, timing->clk_prepare, timing->hs_exit,
369 timing->hs_zero, timing->hs_prepare, timing->hs_trail,
370 timing->hs_rqst, timing->hs_rqst_ckln, timing->hs_halfbyte_en,
371 timing->hs_halfbyte_en_ckln, timing->hs_prep_dly,
372 timing->hs_prep_dly_ckln);
373
374 return 0;
375}
376
268void msm_dsi_phy_set_src_pll(struct msm_dsi_phy *phy, int pll_id, u32 reg, 377void msm_dsi_phy_set_src_pll(struct msm_dsi_phy *phy, int pll_id, u32 reg,
269 u32 bit_mask) 378 u32 bit_mask)
270{ 379{
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
index c56268cbdb3d..a24ab80994a3 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
@@ -101,6 +101,8 @@ int msm_dsi_dphy_timing_calc(struct msm_dsi_dphy_timing *timing,
101 struct msm_dsi_phy_clk_request *clk_req); 101 struct msm_dsi_phy_clk_request *clk_req);
102int msm_dsi_dphy_timing_calc_v2(struct msm_dsi_dphy_timing *timing, 102int msm_dsi_dphy_timing_calc_v2(struct msm_dsi_dphy_timing *timing,
103 struct msm_dsi_phy_clk_request *clk_req); 103 struct msm_dsi_phy_clk_request *clk_req);
104int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing,
105 struct msm_dsi_phy_clk_request *clk_req);
104void msm_dsi_phy_set_src_pll(struct msm_dsi_phy *phy, int pll_id, u32 reg, 106void msm_dsi_phy_set_src_pll(struct msm_dsi_phy *phy, int pll_id, u32 reg,
105 u32 bit_mask); 107 u32 bit_mask);
106int msm_dsi_phy_init_common(struct msm_dsi_phy *phy); 108int msm_dsi_phy_init_common(struct msm_dsi_phy *phy);
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c
index 0af951aaeea1..b3fffc8dbb2a 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c
@@ -79,34 +79,6 @@ static void dsi_phy_hw_v3_0_lane_settings(struct msm_dsi_phy *phy)
79 dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_TX_DCTRL(3), 0x04); 79 dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_TX_DCTRL(3), 0x04);
80} 80}
81 81
82static int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing,
83 struct msm_dsi_phy_clk_request *clk_req)
84{
85 /*
86 * TODO: These params need to be computed, they're currently hardcoded
87 * for a 1440x2560@60Hz panel with a byteclk of 100.618 Mhz, and a
88 * default escape clock of 19.2 Mhz.
89 */
90
91 timing->hs_halfbyte_en = 0;
92 timing->clk_zero = 0x1c;
93 timing->clk_prepare = 0x07;
94 timing->clk_trail = 0x07;
95 timing->hs_exit = 0x23;
96 timing->hs_zero = 0x21;
97 timing->hs_prepare = 0x07;
98 timing->hs_trail = 0x07;
99 timing->hs_rqst = 0x05;
100 timing->ta_sure = 0x00;
101 timing->ta_go = 0x03;
102 timing->ta_get = 0x04;
103
104 timing->shared_timings.clk_pre = 0x2d;
105 timing->shared_timings.clk_post = 0x0d;
106
107 return 0;
108}
109
110static int dsi_10nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, 82static int dsi_10nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
111 struct msm_dsi_phy_clk_request *clk_req) 83 struct msm_dsi_phy_clk_request *clk_req)
112{ 84{
diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c
index 0e0c87252ab0..7a16242bf8bf 100644
--- a/drivers/gpu/drm/msm/msm_fb.c
+++ b/drivers/gpu/drm/msm/msm_fb.c
@@ -183,7 +183,8 @@ static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
183 hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format); 183 hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format);
184 vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format); 184 vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format);
185 185
186 format = kms->funcs->get_format(kms, mode_cmd->pixel_format); 186 format = kms->funcs->get_format(kms, mode_cmd->pixel_format,
187 mode_cmd->modifier[0]);
187 if (!format) { 188 if (!format) {
188 dev_err(dev->dev, "unsupported pixel format: %4.4s\n", 189 dev_err(dev->dev, "unsupported pixel format: %4.4s\n",
189 (char *)&mode_cmd->pixel_format); 190 (char *)&mode_cmd->pixel_format);
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c
index c178563fcd4d..456622b46335 100644
--- a/drivers/gpu/drm/msm/msm_fbdev.c
+++ b/drivers/gpu/drm/msm/msm_fbdev.c
@@ -92,8 +92,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
92 92
93 if (IS_ERR(fb)) { 93 if (IS_ERR(fb)) {
94 dev_err(dev->dev, "failed to allocate fb\n"); 94 dev_err(dev->dev, "failed to allocate fb\n");
95 ret = PTR_ERR(fb); 95 return PTR_ERR(fb);
96 goto fail;
97 } 96 }
98 97
99 bo = msm_framebuffer_bo(fb, 0); 98 bo = msm_framebuffer_bo(fb, 0);
@@ -151,13 +150,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
151 150
152fail_unlock: 151fail_unlock:
153 mutex_unlock(&dev->struct_mutex); 152 mutex_unlock(&dev->struct_mutex);
154fail: 153 drm_framebuffer_remove(fb);
155
156 if (ret) {
157 if (fb)
158 drm_framebuffer_remove(fb);
159 }
160
161 return ret; 154 return ret;
162} 155}
163 156
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 95196479f651..f583bb4222f9 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -132,17 +132,19 @@ static void put_pages(struct drm_gem_object *obj)
132 struct msm_gem_object *msm_obj = to_msm_bo(obj); 132 struct msm_gem_object *msm_obj = to_msm_bo(obj);
133 133
134 if (msm_obj->pages) { 134 if (msm_obj->pages) {
135 /* For non-cached buffers, ensure the new pages are clean 135 if (msm_obj->sgt) {
136 * because display controller, GPU, etc. are not coherent: 136 /* For non-cached buffers, ensure the new
137 */ 137 * pages are clean because display controller,
138 if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED)) 138 * GPU, etc. are not coherent:
139 dma_unmap_sg(obj->dev->dev, msm_obj->sgt->sgl, 139 */
140 msm_obj->sgt->nents, DMA_BIDIRECTIONAL); 140 if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
141 dma_unmap_sg(obj->dev->dev, msm_obj->sgt->sgl,
142 msm_obj->sgt->nents,
143 DMA_BIDIRECTIONAL);
141 144
142 if (msm_obj->sgt)
143 sg_free_table(msm_obj->sgt); 145 sg_free_table(msm_obj->sgt);
144 146 kfree(msm_obj->sgt);
145 kfree(msm_obj->sgt); 147 }
146 148
147 if (use_pages(obj)) 149 if (use_pages(obj))
148 drm_gem_put_pages(obj, msm_obj->pages, true, false); 150 drm_gem_put_pages(obj, msm_obj->pages, true, false);
diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
index 17d5824417ad..aaa329dc020e 100644
--- a/drivers/gpu/drm/msm/msm_kms.h
+++ b/drivers/gpu/drm/msm/msm_kms.h
@@ -48,8 +48,11 @@ struct msm_kms_funcs {
48 /* functions to wait for atomic commit completed on each CRTC */ 48 /* functions to wait for atomic commit completed on each CRTC */
49 void (*wait_for_crtc_commit_done)(struct msm_kms *kms, 49 void (*wait_for_crtc_commit_done)(struct msm_kms *kms,
50 struct drm_crtc *crtc); 50 struct drm_crtc *crtc);
51 /* get msm_format w/ optional format modifiers from drm_mode_fb_cmd2 */
52 const struct msm_format *(*get_format)(struct msm_kms *kms,
53 const uint32_t format,
54 const uint64_t modifiers);
51 /* misc: */ 55 /* misc: */
52 const struct msm_format *(*get_format)(struct msm_kms *kms, uint32_t format);
53 long (*round_pixclk)(struct msm_kms *kms, unsigned long rate, 56 long (*round_pixclk)(struct msm_kms *kms, unsigned long rate,
54 struct drm_encoder *encoder); 57 struct drm_encoder *encoder);
55 int (*set_split_display)(struct msm_kms *kms, 58 int (*set_split_display)(struct msm_kms *kms,