blob: 5750658a36f321f88dc2b115fe432471b7b72ace [file] [log] [blame]
Clarence Ipaac9f332016-08-31 15:46:35 -04001/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
Narendra Muppalla1b0b3352015-09-29 10:16:51 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
Alan Kwong5d324e42016-07-28 22:56:18 -040013#define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
14
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070015#include <drm/drm_crtc.h>
Clarence Ip4ce59322016-06-26 22:27:51 -040016#include <linux/debugfs.h>
17
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070018#include "msm_drv.h"
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -040019#include "msm_mmu.h"
Clarence Ip3649f8b2016-10-31 09:59:44 -040020
21#include "dsi_display.h"
22#include "dsi_drm.h"
23#include "sde_wb.h"
24
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070025#include "sde_kms.h"
Alan Kwongf5dd86c2016-08-09 18:08:17 -040026#include "sde_core_irq.h"
Clarence Ip4ce59322016-06-26 22:27:51 -040027#include "sde_formats.h"
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070028#include "sde_hw_mdss.h"
Clarence Ip4ce59322016-06-26 22:27:51 -040029#include "sde_hw_util.h"
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -040030#include "sde_hw_intf.h"
Alan Kwong5d324e42016-07-28 22:56:18 -040031#include "sde_hw_vbif.h"
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070032
Alan Kwong1a00e4d2016-07-18 09:42:30 -040033#define CREATE_TRACE_POINTS
34#include "sde_trace.h"
35
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -040036static const char * const iommu_ports[] = {
37 "mdp_0",
38};
39
Clarence Ip4ce59322016-06-26 22:27:51 -040040/**
41 * Controls size of event log buffer. Specified as a power of 2.
42 */
43#define SDE_EVTLOG_SIZE 1024
44
45/*
46 * To enable overall DRM driver logging
47 * # echo 0x2 > /sys/module/drm/parameters/debug
48 *
49 * To enable DRM driver h/w logging
50 * # echo <mask> > /sys/kernel/debug/dri/0/hw_log_mask
51 *
52 * See sde_hw_mdss.h for h/w logging mask definitions (search for SDE_DBG_MASK_)
53 */
54#define SDE_DEBUGFS_DIR "msm_sde"
55#define SDE_DEBUGFS_HWMASKNAME "hw_log_mask"
56
Clarence Ipdd395242016-09-09 10:47:17 -040057/**
58 * sdecustom - enable certain driver customizations for sde clients
59 * Enabling this modifies the standard DRM behavior slightly and assumes
60 * that the clients have specific knowledge about the modifications that
61 * are involved, so don't enable this unless you know what you're doing.
62 *
63 * Parts of the driver that are affected by this setting may be located by
64 * searching for invocations of the 'sde_is_custom_client()' function.
65 *
66 * This is disabled by default.
67 */
Clarence Ipb1b3c802016-10-03 16:49:38 -040068static bool sdecustom = true;
Clarence Ipdd395242016-09-09 10:47:17 -040069module_param(sdecustom, bool, 0400);
70MODULE_PARM_DESC(sdecustom, "Enable customizations for sde clients");
71
72bool sde_is_custom_client(void)
73{
74 return sdecustom;
75}
76
Clarence Ip4ce59322016-06-26 22:27:51 -040077static int sde_debugfs_show_regset32(struct seq_file *s, void *data)
78{
Clarence Ipaac9f332016-08-31 15:46:35 -040079 struct sde_debugfs_regset32 *regset;
80 struct sde_kms *sde_kms;
81 struct drm_device *dev;
82 struct msm_drm_private *priv;
Clarence Ip4ce59322016-06-26 22:27:51 -040083 void __iomem *base;
Clarence Ipaac9f332016-08-31 15:46:35 -040084 uint32_t i, addr;
Clarence Ip4ce59322016-06-26 22:27:51 -040085
Clarence Ipaac9f332016-08-31 15:46:35 -040086 if (!s || !s->private)
87 return 0;
Clarence Ip4ce59322016-06-26 22:27:51 -040088
Clarence Ipaac9f332016-08-31 15:46:35 -040089 regset = s->private;
90
91 sde_kms = regset->sde_kms;
92 if (!sde_kms || !sde_kms->mmio)
93 return 0;
94
95 dev = sde_kms->dev;
96 if (!dev)
97 return 0;
98
99 priv = dev->dev_private;
100 if (!priv)
101 return 0;
102
103 base = sde_kms->mmio + regset->offset;
104
105 /* insert padding spaces, if needed */
106 if (regset->offset & 0xF) {
107 seq_printf(s, "[%x]", regset->offset & ~0xF);
108 for (i = 0; i < (regset->offset & 0xF); i += 4)
109 seq_puts(s, " ");
110 }
111
112 if (sde_power_resource_enable(&priv->phandle,
113 sde_kms->core_client, true)) {
114 seq_puts(s, "failed to enable sde clocks\n");
115 return 0;
116 }
117
118 /* main register output */
119 for (i = 0; i < regset->blk_len; i += 4) {
120 addr = regset->offset + i;
121 if ((addr & 0xF) == 0x0)
122 seq_printf(s, i ? "\n[%x]" : "[%x]", addr);
123 seq_printf(s, " %08x", readl_relaxed(base + i));
124 }
125 seq_puts(s, "\n");
126 sde_power_resource_enable(&priv->phandle, sde_kms->core_client, false);
Clarence Ip4ce59322016-06-26 22:27:51 -0400127
128 return 0;
129}
130
131static int sde_debugfs_open_regset32(struct inode *inode, struct file *file)
132{
133 return single_open(file, sde_debugfs_show_regset32, inode->i_private);
134}
135
136static const struct file_operations sde_fops_regset32 = {
137 .open = sde_debugfs_open_regset32,
138 .read = seq_read,
139 .llseek = seq_lseek,
140 .release = single_release,
141};
142
143void sde_debugfs_setup_regset32(struct sde_debugfs_regset32 *regset,
Clarence Ipaac9f332016-08-31 15:46:35 -0400144 uint32_t offset, uint32_t length, struct sde_kms *sde_kms)
Clarence Ip4ce59322016-06-26 22:27:51 -0400145{
146 if (regset) {
147 regset->offset = offset;
148 regset->blk_len = length;
Clarence Ipaac9f332016-08-31 15:46:35 -0400149 regset->sde_kms = sde_kms;
Clarence Ip4ce59322016-06-26 22:27:51 -0400150 }
151}
152
153void *sde_debugfs_create_regset32(const char *name, umode_t mode,
154 void *parent, struct sde_debugfs_regset32 *regset)
155{
Clarence Ipaac9f332016-08-31 15:46:35 -0400156 if (!name || !regset || !regset->sde_kms || !regset->blk_len)
Clarence Ip4ce59322016-06-26 22:27:51 -0400157 return NULL;
158
159 /* make sure offset is a multiple of 4 */
160 regset->offset = round_down(regset->offset, 4);
161
162 return debugfs_create_file(name, mode, parent,
163 regset, &sde_fops_regset32);
164}
165
166void *sde_debugfs_get_root(struct sde_kms *sde_kms)
167{
168 return sde_kms ? sde_kms->debugfs_root : 0;
169}
170
171static int sde_debugfs_init(struct sde_kms *sde_kms)
172{
173 void *p;
174
175 p = sde_hw_util_get_log_mask_ptr();
176
177 if (!sde_kms || !p)
178 return -EINVAL;
179
180 if (sde_kms->dev && sde_kms->dev->primary)
181 sde_kms->debugfs_root = sde_kms->dev->primary->debugfs_root;
182 else
183 sde_kms->debugfs_root = debugfs_create_dir(SDE_DEBUGFS_DIR, 0);
184
185 /* allow debugfs_root to be NULL */
186 debugfs_create_x32(SDE_DEBUGFS_HWMASKNAME,
187 0644, sde_kms->debugfs_root, p);
188 return 0;
189}
190
191static void sde_debugfs_destroy(struct sde_kms *sde_kms)
192{
193 /* don't need to NULL check debugfs_root */
194 if (sde_kms) {
195 debugfs_remove_recursive(sde_kms->debugfs_root);
196 sde_kms->debugfs_root = 0;
197 }
198}
199
Alan Kwongf5dd86c2016-08-09 18:08:17 -0400200static int sde_kms_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
201{
Lloyd Atkinson5217336c2016-09-15 18:21:18 -0400202 struct sde_kms *sde_kms = to_sde_kms(kms);
203 struct drm_device *dev = sde_kms->dev;
204 struct msm_drm_private *priv = dev->dev_private;
205
206 sde_power_resource_enable(&priv->phandle, sde_kms->core_client, true);
207
Alan Kwongf5dd86c2016-08-09 18:08:17 -0400208 return sde_crtc_vblank(crtc, true);
209}
210
211static void sde_kms_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
212{
Lloyd Atkinson5217336c2016-09-15 18:21:18 -0400213 struct sde_kms *sde_kms = to_sde_kms(kms);
214 struct drm_device *dev = sde_kms->dev;
215 struct msm_drm_private *priv = dev->dev_private;
216
Alan Kwongf5dd86c2016-08-09 18:08:17 -0400217 sde_crtc_vblank(crtc, false);
Lloyd Atkinson5217336c2016-09-15 18:21:18 -0400218
219 sde_power_resource_enable(&priv->phandle, sde_kms->core_client, false);
Alan Kwongf5dd86c2016-08-09 18:08:17 -0400220}
221
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400222static void sde_prepare_commit(struct msm_kms *kms,
223 struct drm_atomic_state *state)
224{
Ben Chan78647cd2016-06-26 22:02:47 -0400225 struct sde_kms *sde_kms = to_sde_kms(kms);
Dhaval Patel3949f032016-06-20 16:24:33 -0700226 struct drm_device *dev = sde_kms->dev;
227 struct msm_drm_private *priv = dev->dev_private;
Clarence Ipa36c92e2016-07-26 14:33:46 -0400228
Dhaval Patel3949f032016-06-20 16:24:33 -0700229 sde_power_resource_enable(&priv->phandle, sde_kms->core_client, true);
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400230}
231
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400232static void sde_commit(struct msm_kms *kms, struct drm_atomic_state *old_state)
233{
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400234 struct sde_kms *sde_kms = to_sde_kms(kms);
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400235 struct drm_crtc *crtc;
236 struct drm_crtc_state *old_crtc_state;
237 int i;
238
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400239 MSM_EVT(sde_kms->dev, 0, 0);
240
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400241 for_each_crtc_in_state(old_state, crtc, old_crtc_state, i)
242 if (crtc->state->active)
243 sde_crtc_commit_kickoff(crtc);
244}
245
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400246static void sde_complete_commit(struct msm_kms *kms,
Clarence Ip0d0e96d2016-10-24 18:13:13 -0400247 struct drm_atomic_state *old_state)
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400248{
Ben Chan78647cd2016-06-26 22:02:47 -0400249 struct sde_kms *sde_kms = to_sde_kms(kms);
Dhaval Patel3949f032016-06-20 16:24:33 -0700250 struct drm_device *dev = sde_kms->dev;
251 struct msm_drm_private *priv = dev->dev_private;
Clarence Ip24f80662016-06-13 19:05:32 -0400252 struct drm_crtc *crtc;
Clarence Ip0d0e96d2016-10-24 18:13:13 -0400253 struct drm_crtc_state *old_crtc_state;
Clarence Ip24f80662016-06-13 19:05:32 -0400254 int i;
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400255
Clarence Ip0d0e96d2016-10-24 18:13:13 -0400256 for_each_crtc_in_state(old_state, crtc, old_crtc_state, i)
257 sde_crtc_complete_commit(crtc, old_crtc_state);
Dhaval Patel3949f032016-06-20 16:24:33 -0700258 sde_power_resource_enable(&priv->phandle, sde_kms->core_client, false);
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400259
260 MSM_EVT(sde_kms->dev, 0, 0);
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400261}
262
Lloyd Atkinsone7bcdd22016-08-11 10:53:37 -0400263static void sde_wait_for_commit_done(struct msm_kms *kms,
Abhijit Kulkarni40e38162016-06-26 22:12:09 -0400264 struct drm_crtc *crtc)
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400265{
Lloyd Atkinsone7bcdd22016-08-11 10:53:37 -0400266 struct drm_encoder *encoder;
267 struct drm_device *dev = crtc->dev;
268 int ret;
269
Alan Kwongf34ef982016-09-29 20:53:53 -0400270 if (!kms || !crtc || !crtc->state) {
271 SDE_ERROR("invalid params\n");
272 return;
273 }
274
275 if (!crtc->state->enable) {
276 SDE_DEBUG("[crtc:%d] not enable\n", crtc->base.id);
277 return;
278 }
279
280 if (!crtc->state->active) {
281 SDE_DEBUG("[crtc:%d] not active\n", crtc->base.id);
282 return;
283 }
284
Lloyd Atkinsone7bcdd22016-08-11 10:53:37 -0400285 /* ref count the vblank event and interrupts while we wait for it */
Alan Kwongbaa56352016-10-04 09:38:11 -0400286 if (sde_crtc_vblank(crtc, true))
Lloyd Atkinsone7bcdd22016-08-11 10:53:37 -0400287 return;
288
289 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
290 if (encoder->crtc != crtc)
291 continue;
292 /*
293 * Wait post-flush if necessary to delay before plane_cleanup
294 * For example, wait for vsync in case of video mode panels
295 * This should be a no-op for command mode panels
296 */
297 MSM_EVT(crtc->dev, crtc->base.id, 0);
298 ret = sde_encoder_wait_for_commit_done(encoder);
299 if (ret && ret != -EWOULDBLOCK) {
300 DRM_ERROR("wait for commit done returned %d\n", ret);
301 break;
302 }
303 }
304
305 /* release vblank event ref count */
Alan Kwongbaa56352016-10-04 09:38:11 -0400306 sde_crtc_vblank(crtc, false);
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400307}
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400308
Clarence Ip24f80662016-06-13 19:05:32 -0400309static void sde_kms_prepare_fence(struct msm_kms *kms,
Clarence Ip0d0e96d2016-10-24 18:13:13 -0400310 struct drm_atomic_state *old_state)
Clarence Ip24f80662016-06-13 19:05:32 -0400311{
312 struct drm_crtc *crtc;
Clarence Ip0d0e96d2016-10-24 18:13:13 -0400313 struct drm_crtc_state *old_crtc_state;
314 int i, rc;
Clarence Ip24f80662016-06-13 19:05:32 -0400315
Clarence Ip0d0e96d2016-10-24 18:13:13 -0400316 if (!kms || !old_state || !old_state->dev || !old_state->acquire_ctx) {
317 SDE_ERROR("invalid argument(s)\n");
318 return;
319 }
320
321retry:
322 /* attempt to acquire ww mutex for connection */
323 rc = drm_modeset_lock(&old_state->dev->mode_config.connection_mutex,
324 old_state->acquire_ctx);
325
326 if (rc == -EDEADLK) {
327 drm_modeset_backoff(old_state->acquire_ctx);
328 goto retry;
329 }
330
331 /* old_state actually contains updated crtc pointers */
332 for_each_crtc_in_state(old_state, crtc, old_crtc_state, i)
333 sde_crtc_prepare_commit(crtc, old_crtc_state);
Clarence Ip24f80662016-06-13 19:05:32 -0400334}
335
Clarence Ip3649f8b2016-10-31 09:59:44 -0400336/**
337 * _sde_kms_get_displays - query for underlying display handles and cache them
338 * @sde_kms: Pointer to sde kms structure
339 * Returns: Zero on success
340 */
341static int _sde_kms_get_displays(struct sde_kms *sde_kms)
342{
343 int rc = -ENOMEM;
344
345 if (!sde_kms) {
346 SDE_ERROR("invalid sde kms\n");
347 return -EINVAL;
348 }
349
350 /* dsi */
351 sde_kms->dsi_displays = NULL;
352 sde_kms->dsi_display_count = dsi_display_get_num_of_displays();
353 if (sde_kms->dsi_display_count) {
354 sde_kms->dsi_displays = kcalloc(sde_kms->dsi_display_count,
355 sizeof(void *),
356 GFP_KERNEL);
357 if (!sde_kms->dsi_displays) {
358 SDE_ERROR("failed to allocate dsi displays\n");
359 goto exit_deinit_dsi;
360 }
361 sde_kms->dsi_display_count =
362 dsi_display_get_active_displays(sde_kms->dsi_displays,
363 sde_kms->dsi_display_count);
364 }
365
366 /* wb */
367 sde_kms->wb_displays = NULL;
368 sde_kms->wb_display_count = sde_wb_get_num_of_displays();
369 if (sde_kms->wb_display_count) {
370 sde_kms->wb_displays = kcalloc(sde_kms->wb_display_count,
371 sizeof(void *),
372 GFP_KERNEL);
373 if (!sde_kms->wb_displays) {
374 SDE_ERROR("failed to allocate wb displays\n");
375 goto exit_deinit_wb;
376 }
377 sde_kms->wb_display_count =
378 wb_display_get_displays(sde_kms->wb_displays,
379 sde_kms->wb_display_count);
380 }
381 return 0;
382
383exit_deinit_wb:
384 kfree(sde_kms->wb_displays);
385 sde_kms->wb_display_count = 0;
386 sde_kms->wb_displays = NULL;
387
388exit_deinit_dsi:
389 kfree(sde_kms->dsi_displays);
390 sde_kms->dsi_display_count = 0;
391 sde_kms->dsi_displays = NULL;
392 return rc;
393}
394
395/**
396 * _sde_kms_release_displays - release cache of underlying display handles
397 * @sde_kms: Pointer to sde kms structure
398 */
399static void _sde_kms_release_displays(struct sde_kms *sde_kms)
400{
401 if (!sde_kms) {
402 SDE_ERROR("invalid sde kms\n");
403 return;
404 }
405
406 kfree(sde_kms->wb_displays);
407 sde_kms->wb_displays = NULL;
408 sde_kms->wb_display_count = 0;
409
410 kfree(sde_kms->dsi_displays);
411 sde_kms->dsi_displays = NULL;
412 sde_kms->dsi_display_count = 0;
413}
414
415/**
416 * _sde_kms_setup_displays - create encoders, bridges and connectors
417 * for underlying displays
418 * @dev: Pointer to drm device structure
419 * @priv: Pointer to private drm device data
420 * @sde_kms: Pointer to sde kms structure
421 * Returns: Zero on success
422 */
423static int _sde_kms_setup_displays(struct drm_device *dev,
424 struct msm_drm_private *priv,
425 struct sde_kms *sde_kms)
426{
427 static const struct sde_connector_ops dsi_ops = {
428 .post_init = dsi_conn_post_init,
429 .detect = dsi_conn_detect,
430 .get_modes = dsi_connector_get_modes,
431 .mode_valid = dsi_conn_mode_valid,
432 .get_info = dsi_display_get_info,
433 };
434 static const struct sde_connector_ops wb_ops = {
435 .post_init = sde_wb_connector_post_init,
436 .detect = sde_wb_connector_detect,
437 .get_modes = sde_wb_connector_get_modes,
438 .set_property = sde_wb_connector_set_property,
439 .get_info = sde_wb_get_info,
440 };
441 struct msm_display_info info;
442 struct drm_encoder *encoder;
443 void *display, *connector;
444 int i, max_encoders;
445 int rc = 0;
446
447 if (!dev || !priv || !sde_kms) {
448 SDE_ERROR("invalid argument(s)\n");
449 return -EINVAL;
450 }
451
452 max_encoders = sde_kms->dsi_display_count + sde_kms->wb_display_count;
453 if (max_encoders > ARRAY_SIZE(priv->encoders)) {
454 max_encoders = ARRAY_SIZE(priv->encoders);
455 SDE_ERROR("capping number of displays to %d", max_encoders);
456 }
457
458 /* dsi */
459 for (i = 0; i < sde_kms->dsi_display_count &&
460 priv->num_encoders < max_encoders; ++i) {
461 display = sde_kms->dsi_displays[i];
462 encoder = NULL;
463
464 memset(&info, 0x0, sizeof(info));
465 rc = dsi_display_get_info(&info, display);
466 if (rc) {
467 SDE_ERROR("dsi get_info %d failed\n", i);
468 continue;
469 }
470
471 encoder = sde_encoder_init(dev, &info);
472 if (IS_ERR_OR_NULL(encoder)) {
473 SDE_ERROR("encoder init failed for dsi %d\n", i);
474 continue;
475 }
476
477 rc = dsi_display_drm_bridge_init(display, encoder);
478 if (rc) {
479 SDE_ERROR("dsi bridge %d init failed, %d\n", i, rc);
480 sde_encoder_destroy(encoder);
481 continue;
482 }
483
484 connector = sde_connector_init(dev,
485 encoder,
486 0,
487 display,
488 &dsi_ops,
489 DRM_CONNECTOR_POLL_HPD,
490 DRM_MODE_CONNECTOR_DSI);
491 if (connector) {
492 priv->encoders[priv->num_encoders++] = encoder;
493 } else {
494 SDE_ERROR("dsi %d connector init failed\n", i);
495 dsi_display_drm_bridge_deinit(display);
496 sde_encoder_destroy(encoder);
497 }
498 }
499
500 /* wb */
501 for (i = 0; i < sde_kms->wb_display_count &&
502 priv->num_encoders < max_encoders; ++i) {
503 display = sde_kms->wb_displays[i];
504 encoder = NULL;
505
506 memset(&info, 0x0, sizeof(info));
507 rc = sde_wb_get_info(&info, display);
508 if (rc) {
509 SDE_ERROR("wb get_info %d failed\n", i);
510 continue;
511 }
512
513 encoder = sde_encoder_init(dev, &info);
514 if (IS_ERR_OR_NULL(encoder)) {
515 SDE_ERROR("encoder init failed for wb %d\n", i);
516 continue;
517 }
518
519 rc = sde_wb_drm_init(display, encoder);
520 if (rc) {
521 SDE_ERROR("wb bridge %d init failed, %d\n", i, rc);
522 sde_encoder_destroy(encoder);
523 continue;
524 }
525
526 connector = sde_connector_init(dev,
527 encoder,
528 0,
529 display,
530 &wb_ops,
531 DRM_CONNECTOR_POLL_HPD,
532 DRM_MODE_CONNECTOR_VIRTUAL);
533 if (connector) {
534 priv->encoders[priv->num_encoders++] = encoder;
535 } else {
536 SDE_ERROR("wb %d connector init failed\n", i);
537 sde_wb_drm_deinit(display);
538 sde_encoder_destroy(encoder);
539 }
540 }
541
542 return 0;
543}
544
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700545static int modeset_init(struct sde_kms *sde_kms)
546{
Clarence Ip2bbf7b32016-09-23 15:07:16 -0400547 struct drm_device *dev;
Dhaval Patel44f12472016-08-29 12:19:47 -0700548 struct drm_plane *primary_planes[MAX_PLANES], *plane;
549 struct drm_crtc *crtc;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700550
Clarence Ip2bbf7b32016-09-23 15:07:16 -0400551 struct msm_drm_private *priv;
552 struct sde_mdss_cfg *catalog;
Dhaval Patel44f12472016-08-29 12:19:47 -0700553
Clarence Ip2bbf7b32016-09-23 15:07:16 -0400554 int primary_planes_idx, i, ret;
555 int max_crtc_count, max_plane_count;
556
Clarence Ipdd395242016-09-09 10:47:17 -0400557 if (!sde_kms || !sde_kms->dev || !sde_kms->dev->dev) {
Clarence Ip2bbf7b32016-09-23 15:07:16 -0400558 SDE_ERROR("invalid sde_kms\n");
559 return -EINVAL;
560 }
561
562 dev = sde_kms->dev;
563 priv = dev->dev_private;
564 catalog = sde_kms->catalog;
565
Clarence Ip3649f8b2016-10-31 09:59:44 -0400566 /*
567 * Query for underlying display drivers, and create connectors,
568 * bridges and encoders for them.
569 */
570 if (!_sde_kms_get_displays(sde_kms))
571 (void)_sde_kms_setup_displays(dev, priv, sde_kms);
Clarence Ip2bbf7b32016-09-23 15:07:16 -0400572
573 max_crtc_count = min(catalog->mixer_count, priv->num_encoders);
574 max_plane_count = min_t(u32, catalog->sspp_count, MAX_PLANES);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700575
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700576 /* Create the planes */
Clarence Ip2bbf7b32016-09-23 15:07:16 -0400577 primary_planes_idx = 0;
578 for (i = 0; i < max_plane_count; i++) {
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700579 bool primary = true;
580
581 if (catalog->sspp[i].features & BIT(SDE_SSPP_CURSOR)
Clarence Ip2bbf7b32016-09-23 15:07:16 -0400582 || primary_planes_idx >= max_crtc_count)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700583 primary = false;
584
Clarence Ip2bbf7b32016-09-23 15:07:16 -0400585 plane = sde_plane_init(dev, catalog->sspp[i].id, primary,
586 (1UL << max_crtc_count) - 1);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700587 if (IS_ERR(plane)) {
Clarence Ip2bbf7b32016-09-23 15:07:16 -0400588 SDE_ERROR("sde_plane_init failed\n");
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700589 ret = PTR_ERR(plane);
590 goto fail;
591 }
592 priv->planes[priv->num_planes++] = plane;
593
594 if (primary)
595 primary_planes[primary_planes_idx++] = plane;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700596 }
597
Dhaval Patel44f12472016-08-29 12:19:47 -0700598 max_crtc_count = min(max_crtc_count, primary_planes_idx);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700599
Dhaval Patel44f12472016-08-29 12:19:47 -0700600 /* Create one CRTC per encoder */
601 for (i = 0; i < max_crtc_count; i++) {
Lloyd Atkinsonac933642016-09-14 11:52:00 -0400602 crtc = sde_crtc_init(dev, primary_planes[i]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700603 if (IS_ERR(crtc)) {
604 ret = PTR_ERR(crtc);
605 goto fail;
606 }
607 priv->crtcs[priv->num_crtcs++] = crtc;
608 }
609
Clarence Ipdd395242016-09-09 10:47:17 -0400610 if (sde_is_custom_client()) {
611 /* All CRTCs are compatible with all planes */
612 for (i = 0; i < priv->num_planes; i++)
613 priv->planes[i]->possible_crtcs =
614 (1 << priv->num_crtcs) - 1;
615 }
616
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400617 /* All CRTCs are compatible with all encoders */
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400618 for (i = 0; i < priv->num_encoders; i++)
619 priv->encoders[i]->possible_crtcs = (1 << priv->num_crtcs) - 1;
620
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700621 return 0;
622fail:
623 return ret;
624}
625
626static int sde_hw_init(struct msm_kms *kms)
627{
628 return 0;
629}
Alan Kwong5a3ac752016-10-16 01:02:35 -0400630
631static int sde_kms_postinit(struct msm_kms *kms)
632{
633 struct sde_kms *sde_kms = to_sde_kms(kms);
634 struct drm_device *dev;
635
636 if (!sde_kms || !sde_kms->dev || !sde_kms->dev->dev) {
637 SDE_ERROR("invalid sde_kms\n");
638 return -EINVAL;
639 }
640
641 dev = sde_kms->dev;
642
643 /*
644 * Allow vblank interrupt to be disabled by drm vblank timer.
645 */
646 dev->vblank_disable_allowed = true;
647
648 return 0;
649}
650
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700651static long sde_round_pixclk(struct msm_kms *kms, unsigned long rate,
652 struct drm_encoder *encoder)
653{
654 return rate;
655}
656
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700657static void sde_destroy(struct msm_kms *kms)
658{
Ben Chan78647cd2016-06-26 22:02:47 -0400659 struct sde_kms *sde_kms = to_sde_kms(kms);
Alan Kwong5d324e42016-07-28 22:56:18 -0400660 int i;
661
662 for (i = 0; i < sde_kms->catalog->vbif_count; i++) {
663 u32 vbif_idx = sde_kms->catalog->vbif[i].id;
664
665 if ((vbif_idx < VBIF_MAX) && sde_kms->hw_vbif[vbif_idx])
666 sde_hw_vbif_destroy(sde_kms->hw_vbif[vbif_idx]);
667 }
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700668
Clarence Ip3649f8b2016-10-31 09:59:44 -0400669 _sde_kms_release_displays(sde_kms);
Clarence Ip4ce59322016-06-26 22:27:51 -0400670 sde_debugfs_destroy(sde_kms);
Ben Chan78647cd2016-06-26 22:02:47 -0400671 sde_hw_intr_destroy(sde_kms->hw_intr);
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400672 sde_rm_destroy(&sde_kms->rm);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700673 kfree(sde_kms);
674}
675
Lloyd Atkinson5217336c2016-09-15 18:21:18 -0400676static void sde_kms_preclose(struct msm_kms *kms, struct drm_file *file)
677{
678 struct sde_kms *sde_kms = to_sde_kms(kms);
679 struct drm_device *dev = sde_kms->dev;
680 struct msm_drm_private *priv = dev->dev_private;
681 unsigned int i;
682
683 for (i = 0; i < priv->num_crtcs; i++)
684 sde_crtc_cancel_pending_flip(priv->crtcs[i], file);
685}
686
Ben Chan78647cd2016-06-26 22:02:47 -0400687static const struct msm_kms_funcs kms_funcs = {
688 .hw_init = sde_hw_init,
Alan Kwong5a3ac752016-10-16 01:02:35 -0400689 .postinit = sde_kms_postinit,
Ben Chan78647cd2016-06-26 22:02:47 -0400690 .irq_preinstall = sde_irq_preinstall,
691 .irq_postinstall = sde_irq_postinstall,
692 .irq_uninstall = sde_irq_uninstall,
693 .irq = sde_irq,
Lloyd Atkinson5217336c2016-09-15 18:21:18 -0400694 .preclose = sde_kms_preclose,
Clarence Ip24f80662016-06-13 19:05:32 -0400695 .prepare_fence = sde_kms_prepare_fence,
Ben Chan78647cd2016-06-26 22:02:47 -0400696 .prepare_commit = sde_prepare_commit,
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400697 .commit = sde_commit,
Ben Chan78647cd2016-06-26 22:02:47 -0400698 .complete_commit = sde_complete_commit,
Lloyd Atkinsone7bcdd22016-08-11 10:53:37 -0400699 .wait_for_crtc_commit_done = sde_wait_for_commit_done,
Alan Kwongf5dd86c2016-08-09 18:08:17 -0400700 .enable_vblank = sde_kms_enable_vblank,
701 .disable_vblank = sde_kms_disable_vblank,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400702 .check_modified_format = sde_format_check_modified_format,
Clarence Ip4ce59322016-06-26 22:27:51 -0400703 .get_format = sde_get_msm_format,
Ben Chan78647cd2016-06-26 22:02:47 -0400704 .round_pixclk = sde_round_pixclk,
Ben Chan78647cd2016-06-26 22:02:47 -0400705 .destroy = sde_destroy,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700706};
707
Dhaval Patel3949f032016-06-20 16:24:33 -0700708/* the caller api needs to turn on clock before calling it */
709static void core_hw_rev_init(struct sde_kms *sde_kms)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700710{
Dhaval Patel3949f032016-06-20 16:24:33 -0700711 sde_kms->core_rev = readl_relaxed(sde_kms->mmio + 0x0);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700712}
713
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400714int sde_mmu_init(struct sde_kms *sde_kms)
715{
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400716 struct msm_mmu *mmu;
717 int i, ret;
718
Alan Kwong112a84f2016-05-24 20:49:21 -0400719 for (i = 0; i < MSM_SMMU_DOMAIN_MAX; i++) {
720 mmu = msm_smmu_new(sde_kms->dev->dev, i);
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400721 if (IS_ERR(mmu)) {
722 ret = PTR_ERR(mmu);
Clarence Ip4ce59322016-06-26 22:27:51 -0400723 DRM_ERROR("failed to init iommu: %d\n", ret);
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400724 goto fail;
725 }
726
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400727 ret = mmu->funcs->attach(mmu, (const char **)iommu_ports,
728 ARRAY_SIZE(iommu_ports));
729 if (ret) {
Clarence Ip4ce59322016-06-26 22:27:51 -0400730 DRM_ERROR("failed to attach iommu: %d\n", ret);
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400731 mmu->funcs->destroy(mmu);
732 goto fail;
733 }
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400734
Alan Kwong112a84f2016-05-24 20:49:21 -0400735 sde_kms->mmu_id[i] = msm_register_mmu(sde_kms->dev, mmu);
736 if (sde_kms->mmu_id[i] < 0) {
737 ret = sde_kms->mmu_id[i];
738 DRM_ERROR("failed to register sde iommu: %d\n", ret);
739 mmu->funcs->detach(mmu, (const char **)iommu_ports,
740 ARRAY_SIZE(iommu_ports));
Alan Kwong112a84f2016-05-24 20:49:21 -0400741 goto fail;
742 }
743
744 sde_kms->mmu[i] = mmu;
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400745 }
746
747 return 0;
748fail:
749 return ret;
750
751}
752
Dhaval Patel3949f032016-06-20 16:24:33 -0700753struct sde_kms *sde_hw_setup(struct platform_device *pdev)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700754{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700755 struct sde_kms *sde_kms;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700756 int ret = 0;
757
Dhaval Patel3949f032016-06-20 16:24:33 -0700758 sde_kms = kzalloc(sizeof(*sde_kms), GFP_KERNEL);
759 if (!sde_kms)
760 return ERR_PTR(-ENOMEM);
761
762 sde_kms->mmio = msm_ioremap(pdev, "mdp_phys", "SDE");
763 if (IS_ERR(sde_kms->mmio)) {
764 SDE_ERROR("mdp register memory map failed\n");
765 ret = PTR_ERR(sde_kms->mmio);
766 goto err;
767 }
768 DRM_INFO("mapped mdp address space @%p\n", sde_kms->mmio);
769
770 sde_kms->vbif[VBIF_RT] = msm_ioremap(pdev, "vbif_phys", "VBIF");
771 if (IS_ERR(sde_kms->vbif[VBIF_RT])) {
772 SDE_ERROR("vbif register memory map failed\n");
773 ret = PTR_ERR(sde_kms->vbif[VBIF_RT]);
774 goto vbif_map_err;
Clarence Ip0e1da222016-07-06 17:10:37 -0400775 }
776
Dhaval Patel3949f032016-06-20 16:24:33 -0700777 sde_kms->vbif[VBIF_NRT] = msm_ioremap(pdev, "vbif_nrt_phys",
778 "VBIF_NRT");
779 if (IS_ERR(sde_kms->vbif[VBIF_NRT])) {
780 sde_kms->vbif[VBIF_NRT] = NULL;
781 SDE_DEBUG("VBIF NRT is not defined");
782 }
783
784 /* junk API - no error return for init api */
785 msm_kms_init(&sde_kms->base, &kms_funcs);
786 if (ret) {
787 SDE_ERROR("mdp/kms hw init failed\n");
788 goto kms_init_err;
789 }
790
791 SDE_DEBUG("sde hw setup successful\n");
792 return sde_kms;
793
794kms_init_err:
795 if (sde_kms->vbif[VBIF_NRT])
796 iounmap(sde_kms->vbif[VBIF_NRT]);
797 iounmap(sde_kms->vbif[VBIF_RT]);
798vbif_map_err:
799 iounmap(sde_kms->mmio);
800err:
801 kfree(sde_kms);
802 return ERR_PTR(ret);
803}
804
805static void sde_hw_destroy(struct sde_kms *sde_kms)
806{
807 if (sde_kms->vbif[VBIF_NRT])
808 iounmap(sde_kms->vbif[VBIF_NRT]);
809 iounmap(sde_kms->vbif[VBIF_RT]);
810 iounmap(sde_kms->mmio);
811 kfree(sde_kms);
812}
813
814struct msm_kms *sde_kms_init(struct drm_device *dev)
815{
816 struct msm_drm_private *priv;
817 struct sde_kms *sde_kms;
Alan Kwong5d324e42016-07-28 22:56:18 -0400818 int i;
Dhaval Patel3949f032016-06-20 16:24:33 -0700819 int rc;
820
821 if (!dev) {
822 SDE_ERROR("drm device node invalid\n");
823 rc = -EINVAL;
824 goto end;
825 }
826
827 priv = dev->dev_private;
828 sde_kms = sde_hw_setup(dev->platformdev);
829 if (IS_ERR_OR_NULL(sde_kms)) {
830 SDE_ERROR("sde hw setup failed\n");
831 rc = PTR_ERR(sde_kms);
832 goto end;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700833 }
834
835 sde_kms->dev = dev;
Dhaval Patel3949f032016-06-20 16:24:33 -0700836 priv->kms = &sde_kms->base;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700837
Dhaval Patel3949f032016-06-20 16:24:33 -0700838 sde_kms->core_client = sde_power_client_create(&priv->phandle, "core");
839 if (IS_ERR_OR_NULL(sde_kms->core_client)) {
840 SDE_ERROR("sde power client create failed\n");
841 rc = -EINVAL;
842 goto kms_destroy;
843 }
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700844
Dhaval Patel3949f032016-06-20 16:24:33 -0700845 rc = sde_power_resource_enable(&priv->phandle, sde_kms->core_client,
846 true);
847 if (rc) {
848 SDE_ERROR("resource enable failed\n");
849 goto clk_rate_err;
850 }
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400851
Dhaval Patel3949f032016-06-20 16:24:33 -0700852 core_hw_rev_init(sde_kms);
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400853
Dhaval Patelb271b842016-10-19 21:41:22 -0700854 pr_info("sde hardware revision:0x%x\n", sde_kms->core_rev);
855
Dhaval Patel8bf7ff32016-07-20 18:13:24 -0700856 sde_kms->catalog = sde_hw_catalog_init(dev, sde_kms->core_rev);
Dhaval Patel3949f032016-06-20 16:24:33 -0700857 if (IS_ERR_OR_NULL(sde_kms->catalog)) {
858 SDE_ERROR("catalog init failed\n");
859 rc = PTR_ERR(sde_kms->catalog);
860 goto catalog_err;
861 }
862
863 rc = sde_rm_init(&sde_kms->rm, sde_kms->catalog, sde_kms->mmio,
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400864 sde_kms->dev);
Dhaval Patel3949f032016-06-20 16:24:33 -0700865 if (rc)
866 goto catalog_err;
867
Alan Kwong5d324e42016-07-28 22:56:18 -0400868 for (i = 0; i < sde_kms->catalog->vbif_count; i++) {
869 u32 vbif_idx = sde_kms->catalog->vbif[i].id;
870
871 sde_kms->hw_vbif[i] = sde_hw_vbif_init(vbif_idx,
872 sde_kms->vbif[vbif_idx], sde_kms->catalog);
873 if (IS_ERR_OR_NULL(sde_kms->hw_vbif[vbif_idx])) {
874 SDE_ERROR("failed to init vbif %d\n", vbif_idx);
875 sde_kms->hw_vbif[vbif_idx] = NULL;
876 goto catalog_err;
877 }
878 }
879
880 sde_kms->hw_mdp = sde_rm_get_mdp(&sde_kms->rm);
881 if (IS_ERR_OR_NULL(sde_kms->hw_mdp)) {
882 SDE_ERROR("failed to get hw_mdp\n");
883 sde_kms->hw_mdp = NULL;
884 goto catalog_err;
885 }
886
Lloyd Atkinson5217336c2016-09-15 18:21:18 -0400887 sde_kms->hw_intr = sde_hw_intr_init(sde_kms->mmio, sde_kms->catalog);
888 if (IS_ERR_OR_NULL(sde_kms->hw_intr))
889 goto catalog_err;
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400890
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700891 /*
892 * Now we need to read the HW catalog and initialize resources such as
893 * clocks, regulators, GDSC/MMAGIC, ioremap the register ranges etc
894 */
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400895 sde_mmu_init(sde_kms);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700896
897 /*
Clarence Ip4ce59322016-06-26 22:27:51 -0400898 * NOTE: Calling sde_debugfs_init here so that the drm_minor device for
899 * 'primary' is already created.
900 */
901 sde_debugfs_init(sde_kms);
902 msm_evtlog_init(&priv->evtlog, SDE_EVTLOG_SIZE,
903 sde_debugfs_get_root(sde_kms));
Clarence Ip7f23b892016-06-01 10:30:34 -0400904 MSM_EVT(dev, 0, 0);
Clarence Ip4ce59322016-06-26 22:27:51 -0400905
906 /*
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700907 * modeset_init should create the DRM related objects i.e. CRTCs,
908 * planes, encoders, connectors and so forth
909 */
910 modeset_init(sde_kms);
911
912 dev->mode_config.min_width = 0;
913 dev->mode_config.min_height = 0;
914
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400915 /*
Dhaval Patel4e574842016-08-23 15:11:37 -0700916 * max crtc width is equal to the max mixer width * 2 and max height is
917 * is 4K
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400918 */
Dhaval Patele4a5dda2016-10-13 19:29:30 -0700919 dev->mode_config.max_width = sde_kms->catalog->max_mixer_width * 2;
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400920 dev->mode_config.max_height = 4096;
921
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400922 /*
923 * Support format modifiers for compression etc.
924 */
925 dev->mode_config.allow_fb_modifiers = true;
926
Lloyd Atkinson5217336c2016-09-15 18:21:18 -0400927 sde_power_resource_enable(&priv->phandle, sde_kms->core_client, false);
Ben Chan78647cd2016-06-26 22:02:47 -0400928
Dhaval Patel3949f032016-06-20 16:24:33 -0700929 return &sde_kms->base;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700930
Dhaval Patel3949f032016-06-20 16:24:33 -0700931catalog_err:
932 sde_power_resource_enable(&priv->phandle, sde_kms->core_client, false);
933clk_rate_err:
934 sde_power_client_destroy(&priv->phandle, sde_kms->core_client);
935kms_destroy:
936 sde_hw_destroy(sde_kms);
937end:
938 return ERR_PTR(rc);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700939}