| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) 2014 Red Hat |
|---|
| 3 | 4 | * Author: Rob Clark <robdclark@gmail.com> |
|---|
| 4 | 5 | * Author: Vinay Simha <vinaysimha@inforcecomputing.com> |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 7 | | - * under the terms of the GNU General Public License version 2 as published by |
|---|
| 8 | | - * the Free Software Foundation. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is distributed in the hope that it will be useful, but WITHOUT |
|---|
| 11 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 12 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 13 | | - * more details. |
|---|
| 14 | | - * |
|---|
| 15 | | - * You should have received a copy of the GNU General Public License along with |
|---|
| 16 | | - * this program. If not, see <http://www.gnu.org/licenses/>. |
|---|
| 17 | 6 | */ |
|---|
| 18 | 7 | |
|---|
| 8 | +#include <linux/delay.h> |
|---|
| 9 | + |
|---|
| 19 | 10 | #include <drm/drm_crtc.h> |
|---|
| 20 | | -#include <drm/drm_crtc_helper.h> |
|---|
| 11 | +#include <drm/drm_probe_helper.h> |
|---|
| 21 | 12 | |
|---|
| 22 | 13 | #include "mdp4_kms.h" |
|---|
| 23 | 14 | |
|---|
| .. | .. |
|---|
| 39 | 30 | return to_mdp4_kms(to_mdp_kms(priv->kms)); |
|---|
| 40 | 31 | } |
|---|
| 41 | 32 | |
|---|
| 42 | | -#ifdef DOWNSTREAM_CONFIG_MSM_BUS_SCALING |
|---|
| 43 | | -#include <mach/board.h> |
|---|
| 44 | | -static void bs_init(struct mdp4_lcdc_encoder *mdp4_lcdc_encoder) |
|---|
| 45 | | -{ |
|---|
| 46 | | - struct drm_device *dev = mdp4_lcdc_encoder->base.dev; |
|---|
| 47 | | - struct lcdc_platform_data *lcdc_pdata = mdp4_find_pdata("lvds.0"); |
|---|
| 48 | | - |
|---|
| 49 | | - if (!lcdc_pdata) { |
|---|
| 50 | | - dev_err(dev->dev, "could not find lvds pdata\n"); |
|---|
| 51 | | - return; |
|---|
| 52 | | - } |
|---|
| 53 | | - |
|---|
| 54 | | - if (lcdc_pdata->bus_scale_table) { |
|---|
| 55 | | - mdp4_lcdc_encoder->bsc = msm_bus_scale_register_client( |
|---|
| 56 | | - lcdc_pdata->bus_scale_table); |
|---|
| 57 | | - DBG("lvds : bus scale client: %08x", mdp4_lcdc_encoder->bsc); |
|---|
| 58 | | - } |
|---|
| 59 | | -} |
|---|
| 60 | | - |
|---|
| 61 | | -static void bs_fini(struct mdp4_lcdc_encoder *mdp4_lcdc_encoder) |
|---|
| 62 | | -{ |
|---|
| 63 | | - if (mdp4_lcdc_encoder->bsc) { |
|---|
| 64 | | - msm_bus_scale_unregister_client(mdp4_lcdc_encoder->bsc); |
|---|
| 65 | | - mdp4_lcdc_encoder->bsc = 0; |
|---|
| 66 | | - } |
|---|
| 67 | | -} |
|---|
| 68 | | - |
|---|
| 69 | | -static void bs_set(struct mdp4_lcdc_encoder *mdp4_lcdc_encoder, int idx) |
|---|
| 70 | | -{ |
|---|
| 71 | | - if (mdp4_lcdc_encoder->bsc) { |
|---|
| 72 | | - DBG("set bus scaling: %d", idx); |
|---|
| 73 | | - msm_bus_scale_client_update_request(mdp4_lcdc_encoder->bsc, idx); |
|---|
| 74 | | - } |
|---|
| 75 | | -} |
|---|
| 76 | | -#else |
|---|
| 77 | | -static void bs_init(struct mdp4_lcdc_encoder *mdp4_lcdc_encoder) {} |
|---|
| 78 | | -static void bs_fini(struct mdp4_lcdc_encoder *mdp4_lcdc_encoder) {} |
|---|
| 79 | | -static void bs_set(struct mdp4_lcdc_encoder *mdp4_lcdc_encoder, int idx) {} |
|---|
| 80 | | -#endif |
|---|
| 81 | | - |
|---|
| 82 | 33 | static void mdp4_lcdc_encoder_destroy(struct drm_encoder *encoder) |
|---|
| 83 | 34 | { |
|---|
| 84 | 35 | struct mdp4_lcdc_encoder *mdp4_lcdc_encoder = |
|---|
| 85 | 36 | to_mdp4_lcdc_encoder(encoder); |
|---|
| 86 | | - bs_fini(mdp4_lcdc_encoder); |
|---|
| 87 | 37 | drm_encoder_cleanup(encoder); |
|---|
| 88 | 38 | kfree(mdp4_lcdc_encoder); |
|---|
| 89 | 39 | } |
|---|
| .. | .. |
|---|
| 224 | 174 | break; |
|---|
| 225 | 175 | |
|---|
| 226 | 176 | default: |
|---|
| 227 | | - dev_err(dev->dev, "unknown bpp: %d\n", bpp); |
|---|
| 177 | + DRM_DEV_ERROR(dev->dev, "unknown bpp: %d\n", bpp); |
|---|
| 228 | 178 | return; |
|---|
| 229 | 179 | } |
|---|
| 230 | 180 | |
|---|
| .. | .. |
|---|
| 241 | 191 | MDP4_LCDC_LVDS_INTF_CTL_CH1_CLK_LANE_EN; |
|---|
| 242 | 192 | break; |
|---|
| 243 | 193 | default: |
|---|
| 244 | | - dev_err(dev->dev, "unknown # of channels: %d\n", nchan); |
|---|
| 194 | + DRM_DEV_ERROR(dev->dev, "unknown # of channels: %d\n", nchan); |
|---|
| 245 | 195 | return; |
|---|
| 246 | 196 | } |
|---|
| 247 | 197 | |
|---|
| .. | .. |
|---|
| 273 | 223 | |
|---|
| 274 | 224 | mode = adjusted_mode; |
|---|
| 275 | 225 | |
|---|
| 276 | | - DBG("set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", |
|---|
| 277 | | - mode->base.id, mode->name, |
|---|
| 278 | | - mode->vrefresh, mode->clock, |
|---|
| 279 | | - mode->hdisplay, mode->hsync_start, |
|---|
| 280 | | - mode->hsync_end, mode->htotal, |
|---|
| 281 | | - mode->vdisplay, mode->vsync_start, |
|---|
| 282 | | - mode->vsync_end, mode->vtotal, |
|---|
| 283 | | - mode->type, mode->flags); |
|---|
| 226 | + DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode)); |
|---|
| 284 | 227 | |
|---|
| 285 | 228 | mdp4_lcdc_encoder->pixclock = mode->clock * 1000; |
|---|
| 286 | 229 | |
|---|
| .. | .. |
|---|
| 361 | 304 | for (i = 0; i < ARRAY_SIZE(mdp4_lcdc_encoder->regs); i++) { |
|---|
| 362 | 305 | ret = regulator_disable(mdp4_lcdc_encoder->regs[i]); |
|---|
| 363 | 306 | if (ret) |
|---|
| 364 | | - dev_err(dev->dev, "failed to disable regulator: %d\n", ret); |
|---|
| 307 | + DRM_DEV_ERROR(dev->dev, "failed to disable regulator: %d\n", ret); |
|---|
| 365 | 308 | } |
|---|
| 366 | | - |
|---|
| 367 | | - bs_set(mdp4_lcdc_encoder, 0); |
|---|
| 368 | 309 | |
|---|
| 369 | 310 | mdp4_lcdc_encoder->enabled = false; |
|---|
| 370 | 311 | } |
|---|
| .. | .. |
|---|
| 377 | 318 | unsigned long pc = mdp4_lcdc_encoder->pixclock; |
|---|
| 378 | 319 | struct mdp4_kms *mdp4_kms = get_kms(encoder); |
|---|
| 379 | 320 | struct drm_panel *panel; |
|---|
| 321 | + uint32_t config; |
|---|
| 380 | 322 | int i, ret; |
|---|
| 381 | 323 | |
|---|
| 382 | 324 | if (WARN_ON(mdp4_lcdc_encoder->enabled)) |
|---|
| 383 | 325 | return; |
|---|
| 384 | 326 | |
|---|
| 385 | 327 | /* TODO: hard-coded for 18bpp: */ |
|---|
| 386 | | - mdp4_crtc_set_config(encoder->crtc, |
|---|
| 387 | | - MDP4_DMA_CONFIG_R_BPC(BPC6) | |
|---|
| 388 | | - MDP4_DMA_CONFIG_G_BPC(BPC6) | |
|---|
| 389 | | - MDP4_DMA_CONFIG_B_BPC(BPC6) | |
|---|
| 390 | | - MDP4_DMA_CONFIG_PACK_ALIGN_MSB | |
|---|
| 391 | | - MDP4_DMA_CONFIG_PACK(0x21) | |
|---|
| 392 | | - MDP4_DMA_CONFIG_DEFLKR_EN | |
|---|
| 393 | | - MDP4_DMA_CONFIG_DITHER_EN); |
|---|
| 394 | | - mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV, 0); |
|---|
| 328 | + config = |
|---|
| 329 | + MDP4_DMA_CONFIG_R_BPC(BPC6) | |
|---|
| 330 | + MDP4_DMA_CONFIG_G_BPC(BPC6) | |
|---|
| 331 | + MDP4_DMA_CONFIG_B_BPC(BPC6) | |
|---|
| 332 | + MDP4_DMA_CONFIG_PACK(0x21) | |
|---|
| 333 | + MDP4_DMA_CONFIG_DEFLKR_EN | |
|---|
| 334 | + MDP4_DMA_CONFIG_DITHER_EN; |
|---|
| 395 | 335 | |
|---|
| 396 | | - bs_set(mdp4_lcdc_encoder, 1); |
|---|
| 336 | + if (!of_property_read_bool(dev->dev->of_node, "qcom,lcdc-align-lsb")) |
|---|
| 337 | + config |= MDP4_DMA_CONFIG_PACK_ALIGN_MSB; |
|---|
| 338 | + |
|---|
| 339 | + mdp4_crtc_set_config(encoder->crtc, config); |
|---|
| 340 | + mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV, 0); |
|---|
| 397 | 341 | |
|---|
| 398 | 342 | for (i = 0; i < ARRAY_SIZE(mdp4_lcdc_encoder->regs); i++) { |
|---|
| 399 | 343 | ret = regulator_enable(mdp4_lcdc_encoder->regs[i]); |
|---|
| 400 | 344 | if (ret) |
|---|
| 401 | | - dev_err(dev->dev, "failed to enable regulator: %d\n", ret); |
|---|
| 345 | + DRM_DEV_ERROR(dev->dev, "failed to enable regulator: %d\n", ret); |
|---|
| 402 | 346 | } |
|---|
| 403 | 347 | |
|---|
| 404 | 348 | DBG("setting lcdc_clk=%lu", pc); |
|---|
| 405 | 349 | ret = clk_set_rate(mdp4_lcdc_encoder->lcdc_clk, pc); |
|---|
| 406 | 350 | if (ret) |
|---|
| 407 | | - dev_err(dev->dev, "failed to configure lcdc_clk: %d\n", ret); |
|---|
| 351 | + DRM_DEV_ERROR(dev->dev, "failed to configure lcdc_clk: %d\n", ret); |
|---|
| 408 | 352 | ret = clk_prepare_enable(mdp4_lcdc_encoder->lcdc_clk); |
|---|
| 409 | 353 | if (ret) |
|---|
| 410 | | - dev_err(dev->dev, "failed to enable lcdc_clk: %d\n", ret); |
|---|
| 354 | + DRM_DEV_ERROR(dev->dev, "failed to enable lcdc_clk: %d\n", ret); |
|---|
| 411 | 355 | |
|---|
| 412 | 356 | panel = of_drm_find_panel(mdp4_lcdc_encoder->panel_node); |
|---|
| 413 | 357 | if (!IS_ERR(panel)) { |
|---|
| .. | .. |
|---|
| 461 | 405 | /* TODO: do we need different pll in other cases? */ |
|---|
| 462 | 406 | mdp4_lcdc_encoder->lcdc_clk = mpd4_lvds_pll_init(dev); |
|---|
| 463 | 407 | if (IS_ERR(mdp4_lcdc_encoder->lcdc_clk)) { |
|---|
| 464 | | - dev_err(dev->dev, "failed to get lvds_clk\n"); |
|---|
| 408 | + DRM_DEV_ERROR(dev->dev, "failed to get lvds_clk\n"); |
|---|
| 465 | 409 | ret = PTR_ERR(mdp4_lcdc_encoder->lcdc_clk); |
|---|
| 466 | 410 | goto fail; |
|---|
| 467 | 411 | } |
|---|
| .. | .. |
|---|
| 470 | 414 | reg = devm_regulator_get(dev->dev, "lvds-vccs-3p3v"); |
|---|
| 471 | 415 | if (IS_ERR(reg)) { |
|---|
| 472 | 416 | ret = PTR_ERR(reg); |
|---|
| 473 | | - dev_err(dev->dev, "failed to get lvds-vccs-3p3v: %d\n", ret); |
|---|
| 417 | + DRM_DEV_ERROR(dev->dev, "failed to get lvds-vccs-3p3v: %d\n", ret); |
|---|
| 474 | 418 | goto fail; |
|---|
| 475 | 419 | } |
|---|
| 476 | 420 | mdp4_lcdc_encoder->regs[0] = reg; |
|---|
| .. | .. |
|---|
| 478 | 422 | reg = devm_regulator_get(dev->dev, "lvds-pll-vdda"); |
|---|
| 479 | 423 | if (IS_ERR(reg)) { |
|---|
| 480 | 424 | ret = PTR_ERR(reg); |
|---|
| 481 | | - dev_err(dev->dev, "failed to get lvds-pll-vdda: %d\n", ret); |
|---|
| 425 | + DRM_DEV_ERROR(dev->dev, "failed to get lvds-pll-vdda: %d\n", ret); |
|---|
| 482 | 426 | goto fail; |
|---|
| 483 | 427 | } |
|---|
| 484 | 428 | mdp4_lcdc_encoder->regs[1] = reg; |
|---|
| .. | .. |
|---|
| 486 | 430 | reg = devm_regulator_get(dev->dev, "lvds-vdda"); |
|---|
| 487 | 431 | if (IS_ERR(reg)) { |
|---|
| 488 | 432 | ret = PTR_ERR(reg); |
|---|
| 489 | | - dev_err(dev->dev, "failed to get lvds-vdda: %d\n", ret); |
|---|
| 433 | + DRM_DEV_ERROR(dev->dev, "failed to get lvds-vdda: %d\n", ret); |
|---|
| 490 | 434 | goto fail; |
|---|
| 491 | 435 | } |
|---|
| 492 | 436 | mdp4_lcdc_encoder->regs[2] = reg; |
|---|
| 493 | | - |
|---|
| 494 | | - bs_init(mdp4_lcdc_encoder); |
|---|
| 495 | 437 | |
|---|
| 496 | 438 | return encoder; |
|---|
| 497 | 439 | |
|---|