1d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim/* 2d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim * Copyright (C) 2011 Samsung Electronics Co.Ltd 3d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim * Authors: 4d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim * Inki Dae <inki.dae@samsung.com> 5d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim * Seung-Woo Kim <sw0312.kim@samsung.com> 6d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim * 7d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim * This program is free software; you can redistribute it and/or modify it 8d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim * under the terms of the GNU General Public License as published by the 9d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim * Free Software Foundation; either version 2 of the License, or (at your 10d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim * option) any later version. 11d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim * 12d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim */ 13d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 14d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include "drmP.h" 15d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 16d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include <linux/kernel.h> 17d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include <linux/wait.h> 18d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include <linux/module.h> 19d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include <linux/platform_device.h> 20d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include <linux/pm_runtime.h> 21d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 22d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include <drm/exynos_drm.h> 23d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 24d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include "exynos_drm_drv.h" 25d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include "exynos_drm_hdmi.h" 26d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 27d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#define to_context(dev) platform_get_drvdata(to_platform_device(dev)) 28d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#define to_subdrv(dev) to_context(dev) 29d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#define get_ctx_from_subdrv(subdrv) container_of(subdrv,\ 30d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct drm_hdmi_context, subdrv); 31d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 32d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim/* these callback points shoud be set by specific drivers. */ 33578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shimstatic struct exynos_hdmi_ops *hdmi_ops; 34578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shimstatic struct exynos_mixer_ops *mixer_ops; 35d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 36d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstruct drm_hdmi_context { 37d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct exynos_drm_subdrv subdrv; 38d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct exynos_drm_hdmi_context *hdmi_ctx; 39d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct exynos_drm_hdmi_context *mixer_ctx; 40d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}; 41d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 42578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shimvoid exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops) 43d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{ 44d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_DEBUG_KMS("%s\n", __FILE__); 45d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 46578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim if (ops) 47578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim hdmi_ops = ops; 48d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim} 49d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 50578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shimvoid exynos_mixer_ops_register(struct exynos_mixer_ops *ops) 51d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{ 52d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_DEBUG_KMS("%s\n", __FILE__); 53d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 54578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim if (ops) 55578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim mixer_ops = ops; 56d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim} 57d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 58d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic bool drm_hdmi_is_connected(struct device *dev) 59d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{ 60d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct drm_hdmi_context *ctx = to_context(dev); 61d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 62d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_DEBUG_KMS("%s\n", __FILE__); 63d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 64578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim if (hdmi_ops && hdmi_ops->is_connected) 65578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim return hdmi_ops->is_connected(ctx->hdmi_ctx->ctx); 66d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 67d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim return false; 68d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim} 69d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 70d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic int drm_hdmi_get_edid(struct device *dev, 71d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct drm_connector *connector, u8 *edid, int len) 72d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{ 73d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct drm_hdmi_context *ctx = to_context(dev); 74d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 75d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_DEBUG_KMS("%s\n", __FILE__); 76d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 77578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim if (hdmi_ops && hdmi_ops->get_edid) 78578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim return hdmi_ops->get_edid(ctx->hdmi_ctx->ctx, connector, edid, 79578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim len); 80d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 81d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim return 0; 82d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim} 83d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 84d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic int drm_hdmi_check_timing(struct device *dev, void *timing) 85d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{ 86d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct drm_hdmi_context *ctx = to_context(dev); 87d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 88d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_DEBUG_KMS("%s\n", __FILE__); 89d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 90578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim if (hdmi_ops && hdmi_ops->check_timing) 91578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim return hdmi_ops->check_timing(ctx->hdmi_ctx->ctx, timing); 92d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 93d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim return 0; 94d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim} 95d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 96d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic int drm_hdmi_power_on(struct device *dev, int mode) 97d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{ 98d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct drm_hdmi_context *ctx = to_context(dev); 99d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 100d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_DEBUG_KMS("%s\n", __FILE__); 101d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 102578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim if (hdmi_ops && hdmi_ops->power_on) 103578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim return hdmi_ops->power_on(ctx->hdmi_ctx->ctx, mode); 104d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 105d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim return 0; 106d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim} 107d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 108d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic struct exynos_drm_display_ops drm_hdmi_display_ops = { 109d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim .type = EXYNOS_DISPLAY_TYPE_HDMI, 110d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim .is_connected = drm_hdmi_is_connected, 111d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim .get_edid = drm_hdmi_get_edid, 112d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim .check_timing = drm_hdmi_check_timing, 113d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim .power_on = drm_hdmi_power_on, 114d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}; 115d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 116d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic int drm_hdmi_enable_vblank(struct device *subdrv_dev) 117d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{ 118d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct drm_hdmi_context *ctx = to_context(subdrv_dev); 119d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct exynos_drm_subdrv *subdrv = &ctx->subdrv; 120677e84c1b5c8533ea351a9556308071ca47a1eb2Joonyoung Shim struct exynos_drm_manager *manager = subdrv->manager; 121d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 122d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_DEBUG_KMS("%s\n", __FILE__); 123d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 124578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim if (mixer_ops && mixer_ops->enable_vblank) 125578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim return mixer_ops->enable_vblank(ctx->mixer_ctx->ctx, 126578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim manager->pipe); 127d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 128d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim return 0; 129d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim} 130d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 131d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void drm_hdmi_disable_vblank(struct device *subdrv_dev) 132d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{ 133d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct drm_hdmi_context *ctx = to_context(subdrv_dev); 134d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 135d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_DEBUG_KMS("%s\n", __FILE__); 136d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 137578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim if (mixer_ops && mixer_ops->disable_vblank) 138578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim return mixer_ops->disable_vblank(ctx->mixer_ctx->ctx); 139d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim} 140d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 1411de425b0bdbc457dbd4a012760da4a3f204d0ab3Inki Daestatic void drm_hdmi_mode_fixup(struct device *subdrv_dev, 1421de425b0bdbc457dbd4a012760da4a3f204d0ab3Inki Dae struct drm_connector *connector, 1431de425b0bdbc457dbd4a012760da4a3f204d0ab3Inki Dae struct drm_display_mode *mode, 1441de425b0bdbc457dbd4a012760da4a3f204d0ab3Inki Dae struct drm_display_mode *adjusted_mode) 1451de425b0bdbc457dbd4a012760da4a3f204d0ab3Inki Dae{ 1461de425b0bdbc457dbd4a012760da4a3f204d0ab3Inki Dae struct drm_hdmi_context *ctx = to_context(subdrv_dev); 1471de425b0bdbc457dbd4a012760da4a3f204d0ab3Inki Dae 1481de425b0bdbc457dbd4a012760da4a3f204d0ab3Inki Dae DRM_DEBUG_KMS("%s\n", __FILE__); 1491de425b0bdbc457dbd4a012760da4a3f204d0ab3Inki Dae 150578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim if (hdmi_ops && hdmi_ops->mode_fixup) 151578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim hdmi_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector, mode, 152578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim adjusted_mode); 1531de425b0bdbc457dbd4a012760da4a3f204d0ab3Inki Dae} 1541de425b0bdbc457dbd4a012760da4a3f204d0ab3Inki Dae 155d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode) 156d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{ 157d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct drm_hdmi_context *ctx = to_context(subdrv_dev); 158d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 159d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_DEBUG_KMS("%s\n", __FILE__); 160d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 161578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim if (hdmi_ops && hdmi_ops->mode_set) 162578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim hdmi_ops->mode_set(ctx->hdmi_ctx->ctx, mode); 163d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim} 164d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 1651de425b0bdbc457dbd4a012760da4a3f204d0ab3Inki Daestatic void drm_hdmi_get_max_resol(struct device *subdrv_dev, 1661de425b0bdbc457dbd4a012760da4a3f204d0ab3Inki Dae unsigned int *width, unsigned int *height) 1671de425b0bdbc457dbd4a012760da4a3f204d0ab3Inki Dae{ 1681de425b0bdbc457dbd4a012760da4a3f204d0ab3Inki Dae struct drm_hdmi_context *ctx = to_context(subdrv_dev); 1691de425b0bdbc457dbd4a012760da4a3f204d0ab3Inki Dae 1701de425b0bdbc457dbd4a012760da4a3f204d0ab3Inki Dae DRM_DEBUG_KMS("%s\n", __FILE__); 1711de425b0bdbc457dbd4a012760da4a3f204d0ab3Inki Dae 172578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim if (hdmi_ops && hdmi_ops->get_max_resol) 173578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim hdmi_ops->get_max_resol(ctx->hdmi_ctx->ctx, width, height); 1741de425b0bdbc457dbd4a012760da4a3f204d0ab3Inki Dae} 1751de425b0bdbc457dbd4a012760da4a3f204d0ab3Inki Dae 176d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void drm_hdmi_commit(struct device *subdrv_dev) 177d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{ 178d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct drm_hdmi_context *ctx = to_context(subdrv_dev); 179d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 180d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_DEBUG_KMS("%s\n", __FILE__); 181d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 182578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim if (hdmi_ops && hdmi_ops->commit) 183578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim hdmi_ops->commit(ctx->hdmi_ctx->ctx); 184d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim} 185d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 186d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void drm_hdmi_dpms(struct device *subdrv_dev, int mode) 187d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{ 188d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct drm_hdmi_context *ctx = to_context(subdrv_dev); 189d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 190d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_DEBUG_KMS("%s\n", __FILE__); 191d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 192d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim switch (mode) { 193d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim case DRM_MODE_DPMS_ON: 194d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim break; 195d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim case DRM_MODE_DPMS_STANDBY: 196d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim case DRM_MODE_DPMS_SUSPEND: 197d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim case DRM_MODE_DPMS_OFF: 198578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim if (hdmi_ops && hdmi_ops->disable) 199578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim hdmi_ops->disable(ctx->hdmi_ctx->ctx); 200d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim break; 201d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim default: 202d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_DEBUG_KMS("unkown dps mode: %d\n", mode); 203d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim break; 204d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim } 205d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim} 206d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 207d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic struct exynos_drm_manager_ops drm_hdmi_manager_ops = { 208d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim .dpms = drm_hdmi_dpms, 209d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim .enable_vblank = drm_hdmi_enable_vblank, 210d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim .disable_vblank = drm_hdmi_disable_vblank, 2111de425b0bdbc457dbd4a012760da4a3f204d0ab3Inki Dae .mode_fixup = drm_hdmi_mode_fixup, 212d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim .mode_set = drm_hdmi_mode_set, 2131de425b0bdbc457dbd4a012760da4a3f204d0ab3Inki Dae .get_max_resol = drm_hdmi_get_max_resol, 214d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim .commit = drm_hdmi_commit, 215d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}; 216d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 217d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void drm_mixer_mode_set(struct device *subdrv_dev, 218d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct exynos_drm_overlay *overlay) 219d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{ 220d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct drm_hdmi_context *ctx = to_context(subdrv_dev); 221d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 222d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_DEBUG_KMS("%s\n", __FILE__); 223d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 224578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim if (mixer_ops && mixer_ops->win_mode_set) 225578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim mixer_ops->win_mode_set(ctx->mixer_ctx->ctx, overlay); 226d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim} 227d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 228d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void drm_mixer_commit(struct device *subdrv_dev, int zpos) 229d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{ 230d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct drm_hdmi_context *ctx = to_context(subdrv_dev); 231d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 232d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_DEBUG_KMS("%s\n", __FILE__); 233d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 234578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim if (mixer_ops && mixer_ops->win_commit) 235578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim mixer_ops->win_commit(ctx->mixer_ctx->ctx, zpos); 236d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim} 237d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 238d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void drm_mixer_disable(struct device *subdrv_dev, int zpos) 239d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{ 240d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct drm_hdmi_context *ctx = to_context(subdrv_dev); 241d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 242d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_DEBUG_KMS("%s\n", __FILE__); 243d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 244578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim if (mixer_ops && mixer_ops->win_disable) 245578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim mixer_ops->win_disable(ctx->mixer_ctx->ctx, zpos); 246d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim} 247d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 248d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = { 249d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim .mode_set = drm_mixer_mode_set, 250d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim .commit = drm_mixer_commit, 251d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim .disable = drm_mixer_disable, 252d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}; 253d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 254677e84c1b5c8533ea351a9556308071ca47a1eb2Joonyoung Shimstatic struct exynos_drm_manager hdmi_manager = { 255677e84c1b5c8533ea351a9556308071ca47a1eb2Joonyoung Shim .pipe = -1, 256677e84c1b5c8533ea351a9556308071ca47a1eb2Joonyoung Shim .ops = &drm_hdmi_manager_ops, 257677e84c1b5c8533ea351a9556308071ca47a1eb2Joonyoung Shim .overlay_ops = &drm_hdmi_overlay_ops, 258677e84c1b5c8533ea351a9556308071ca47a1eb2Joonyoung Shim .display_ops = &drm_hdmi_display_ops, 259677e84c1b5c8533ea351a9556308071ca47a1eb2Joonyoung Shim}; 260d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 261d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic int hdmi_subdrv_probe(struct drm_device *drm_dev, 262d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct device *dev) 263d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{ 264d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct exynos_drm_subdrv *subdrv = to_subdrv(dev); 265d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct drm_hdmi_context *ctx; 266d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct platform_device *pdev = to_platform_device(dev); 267d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct exynos_drm_common_hdmi_pd *pd; 268d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 269d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_DEBUG_KMS("%s\n", __FILE__); 270d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 271d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim pd = pdev->dev.platform_data; 272d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 273d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim if (!pd) { 274d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_DEBUG_KMS("platform data is null.\n"); 275d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim return -EFAULT; 276d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim } 277d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 278d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim if (!pd->hdmi_dev) { 279d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_DEBUG_KMS("hdmi device is null.\n"); 280d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim return -EFAULT; 281d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim } 282d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 283d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim if (!pd->mixer_dev) { 284d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_DEBUG_KMS("mixer device is null.\n"); 285d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim return -EFAULT; 286d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim } 287d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 288d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim ctx = get_ctx_from_subdrv(subdrv); 289d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 290d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim ctx->hdmi_ctx = (struct exynos_drm_hdmi_context *) 291d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim to_context(pd->hdmi_dev); 292d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim if (!ctx->hdmi_ctx) { 293d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_DEBUG_KMS("hdmi context is null.\n"); 294132a5b915f41f88356662c14c6866550ce2a08b6Joonyoung Shim return -EFAULT; 295d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim } 296d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 297d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim ctx->hdmi_ctx->drm_dev = drm_dev; 298d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 299d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim ctx->mixer_ctx = (struct exynos_drm_hdmi_context *) 300d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim to_context(pd->mixer_dev); 301d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim if (!ctx->mixer_ctx) { 302d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_DEBUG_KMS("mixer context is null.\n"); 303132a5b915f41f88356662c14c6866550ce2a08b6Joonyoung Shim return -EFAULT; 304d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim } 305d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 306d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim ctx->mixer_ctx->drm_dev = drm_dev; 307d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 308d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim return 0; 309d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim} 310d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 311d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev) 312d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{ 313d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct device *dev = &pdev->dev; 314d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct exynos_drm_subdrv *subdrv; 315d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct drm_hdmi_context *ctx; 316d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 317d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_DEBUG_KMS("%s\n", __FILE__); 318d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 319d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 320d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim if (!ctx) { 321d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_LOG_KMS("failed to alloc common hdmi context.\n"); 322d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim return -ENOMEM; 323d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim } 324d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 325d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim subdrv = &ctx->subdrv; 326d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 327677e84c1b5c8533ea351a9556308071ca47a1eb2Joonyoung Shim subdrv->dev = dev; 328677e84c1b5c8533ea351a9556308071ca47a1eb2Joonyoung Shim subdrv->manager = &hdmi_manager; 329d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim subdrv->probe = hdmi_subdrv_probe; 330d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 331d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim platform_set_drvdata(pdev, subdrv); 332d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 333132a5b915f41f88356662c14c6866550ce2a08b6Joonyoung Shim exynos_drm_subdrv_register(subdrv); 334d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 335d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim return 0; 336d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim} 337d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 338d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic int hdmi_runtime_suspend(struct device *dev) 339d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{ 340d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_DEBUG_KMS("%s\n", __FILE__); 341d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 342d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim return 0; 343d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim} 344d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 345d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic int hdmi_runtime_resume(struct device *dev) 346d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{ 347d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_DEBUG_KMS("%s\n", __FILE__); 348d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 349d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim return 0; 350d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim} 351d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 352d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic const struct dev_pm_ops hdmi_pm_ops = { 353d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim .runtime_suspend = hdmi_runtime_suspend, 354d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim .runtime_resume = hdmi_runtime_resume, 355d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}; 356d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 357d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic int __devexit exynos_drm_hdmi_remove(struct platform_device *pdev) 358d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{ 359d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim struct drm_hdmi_context *ctx = platform_get_drvdata(pdev); 360d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 361d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim DRM_DEBUG_KMS("%s\n", __FILE__); 362d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 363d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim exynos_drm_subdrv_unregister(&ctx->subdrv); 364d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim kfree(ctx); 365d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 366d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim return 0; 367d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim} 368d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim 369132a5b915f41f88356662c14c6866550ce2a08b6Joonyoung Shimstruct platform_driver exynos_drm_common_hdmi_driver = { 370d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim .probe = exynos_drm_hdmi_probe, 371d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim .remove = __devexit_p(exynos_drm_hdmi_remove), 372d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim .driver = { 373d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim .name = "exynos-drm-hdmi", 374d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim .owner = THIS_MODULE, 375d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim .pm = &hdmi_pm_ops, 376d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim }, 377d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}; 378