Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (C) 2011 Samsung Electronics Co.Ltd
0004  * Authors:
0005  * Seung-Woo Kim <sw0312.kim@samsung.com>
0006  *  Inki Dae <inki.dae@samsung.com>
0007  *  Joonyoung Shim <jy0922.shim@samsung.com>
0008  *
0009  * Based on drivers/media/video/s5p-tv/hdmi_drv.c
0010  */
0011 
0012 #include <drm/exynos_drm.h>
0013 #include <linux/clk.h>
0014 #include <linux/component.h>
0015 #include <linux/delay.h>
0016 #include <linux/gpio/consumer.h>
0017 #include <linux/hdmi.h>
0018 #include <linux/i2c.h>
0019 #include <linux/interrupt.h>
0020 #include <linux/io.h>
0021 #include <linux/irq.h>
0022 #include <linux/kernel.h>
0023 #include <linux/mfd/syscon.h>
0024 #include <linux/of_address.h>
0025 #include <linux/of_device.h>
0026 #include <linux/of_graph.h>
0027 #include <linux/platform_device.h>
0028 #include <linux/pm_runtime.h>
0029 #include <linux/regmap.h>
0030 #include <linux/regulator/consumer.h>
0031 #include <linux/wait.h>
0032 
0033 #include <sound/hdmi-codec.h>
0034 #include <media/cec-notifier.h>
0035 
0036 #include <drm/drm_atomic_helper.h>
0037 #include <drm/drm_bridge.h>
0038 #include <drm/drm_edid.h>
0039 #include <drm/drm_print.h>
0040 #include <drm/drm_probe_helper.h>
0041 #include <drm/drm_simple_kms_helper.h>
0042 
0043 #include "exynos_drm_crtc.h"
0044 #include "regs-hdmi.h"
0045 
0046 #define HOTPLUG_DEBOUNCE_MS     1100
0047 
0048 enum hdmi_type {
0049     HDMI_TYPE13,
0050     HDMI_TYPE14,
0051     HDMI_TYPE_COUNT
0052 };
0053 
0054 #define HDMI_MAPPED_BASE 0xffff0000
0055 
0056 enum hdmi_mapped_regs {
0057     HDMI_PHY_STATUS = HDMI_MAPPED_BASE,
0058     HDMI_PHY_RSTOUT,
0059     HDMI_ACR_CON,
0060     HDMI_ACR_MCTS0,
0061     HDMI_ACR_CTS0,
0062     HDMI_ACR_N0
0063 };
0064 
0065 static const u32 hdmi_reg_map[][HDMI_TYPE_COUNT] = {
0066     { HDMI_V13_PHY_STATUS, HDMI_PHY_STATUS_0 },
0067     { HDMI_V13_PHY_RSTOUT, HDMI_V14_PHY_RSTOUT },
0068     { HDMI_V13_ACR_CON, HDMI_V14_ACR_CON },
0069     { HDMI_V13_ACR_MCTS0, HDMI_V14_ACR_MCTS0 },
0070     { HDMI_V13_ACR_CTS0, HDMI_V14_ACR_CTS0 },
0071     { HDMI_V13_ACR_N0, HDMI_V14_ACR_N0 },
0072 };
0073 
0074 static const char * const supply[] = {
0075     "vdd",
0076     "vdd_osc",
0077     "vdd_pll",
0078 };
0079 
0080 struct hdmiphy_config {
0081     int pixel_clock;
0082     u8 conf[32];
0083 };
0084 
0085 struct hdmiphy_configs {
0086     int count;
0087     const struct hdmiphy_config *data;
0088 };
0089 
0090 struct string_array_spec {
0091     int count;
0092     const char * const *data;
0093 };
0094 
0095 #define INIT_ARRAY_SPEC(a) { .count = ARRAY_SIZE(a), .data = a }
0096 
0097 struct hdmi_driver_data {
0098     unsigned int type;
0099     unsigned int is_apb_phy:1;
0100     unsigned int has_sysreg:1;
0101     struct hdmiphy_configs phy_confs;
0102     struct string_array_spec clk_gates;
0103     /*
0104      * Array of triplets (p_off, p_on, clock), where p_off and p_on are
0105      * required parents of clock when HDMI-PHY is respectively off or on.
0106      */
0107     struct string_array_spec clk_muxes;
0108 };
0109 
0110 struct hdmi_audio {
0111     struct platform_device      *pdev;
0112     struct hdmi_audio_infoframe infoframe;
0113     struct hdmi_codec_params    params;
0114     bool                mute;
0115 };
0116 
0117 struct hdmi_context {
0118     struct drm_encoder      encoder;
0119     struct device           *dev;
0120     struct drm_device       *drm_dev;
0121     struct drm_connector        connector;
0122     bool                dvi_mode;
0123     struct delayed_work     hotplug_work;
0124     struct cec_notifier     *notifier;
0125     const struct hdmi_driver_data   *drv_data;
0126 
0127     void __iomem            *regs;
0128     void __iomem            *regs_hdmiphy;
0129     struct i2c_client       *hdmiphy_port;
0130     struct i2c_adapter      *ddc_adpt;
0131     struct gpio_desc        *hpd_gpio;
0132     int             irq;
0133     struct regmap           *pmureg;
0134     struct regmap           *sysreg;
0135     struct clk          **clk_gates;
0136     struct clk          **clk_muxes;
0137     struct regulator_bulk_data  regul_bulk[ARRAY_SIZE(supply)];
0138     struct regulator        *reg_hdmi_en;
0139     struct exynos_drm_clk       phy_clk;
0140     struct drm_bridge       *bridge;
0141 
0142     /* mutex protecting subsequent fields below */
0143     struct mutex            mutex;
0144     struct hdmi_audio       audio;
0145     bool                powered;
0146 };
0147 
0148 static inline struct hdmi_context *encoder_to_hdmi(struct drm_encoder *e)
0149 {
0150     return container_of(e, struct hdmi_context, encoder);
0151 }
0152 
0153 static inline struct hdmi_context *connector_to_hdmi(struct drm_connector *c)
0154 {
0155     return container_of(c, struct hdmi_context, connector);
0156 }
0157 
0158 static const struct hdmiphy_config hdmiphy_v13_configs[] = {
0159     {
0160         .pixel_clock = 27000000,
0161         .conf = {
0162             0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
0163             0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
0164             0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
0165             0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x80,
0166         },
0167     },
0168     {
0169         .pixel_clock = 27027000,
0170         .conf = {
0171             0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
0172             0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
0173             0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
0174             0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x80,
0175         },
0176     },
0177     {
0178         .pixel_clock = 74176000,
0179         .conf = {
0180             0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
0181             0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
0182             0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
0183             0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x80,
0184         },
0185     },
0186     {
0187         .pixel_clock = 74250000,
0188         .conf = {
0189             0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
0190             0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
0191             0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
0192             0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x80,
0193         },
0194     },
0195     {
0196         .pixel_clock = 148500000,
0197         .conf = {
0198             0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
0199             0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
0200             0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
0201             0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x80,
0202         },
0203     },
0204 };
0205 
0206 static const struct hdmiphy_config hdmiphy_v14_configs[] = {
0207     {
0208         .pixel_clock = 25200000,
0209         .conf = {
0210             0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00, 0x08,
0211             0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80,
0212             0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
0213             0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
0214         },
0215     },
0216     {
0217         .pixel_clock = 27000000,
0218         .conf = {
0219             0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc, 0x20,
0220             0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac, 0x80,
0221             0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
0222             0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
0223         },
0224     },
0225     {
0226         .pixel_clock = 27027000,
0227         .conf = {
0228             0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
0229             0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
0230             0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
0231             0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
0232         },
0233     },
0234     {
0235         .pixel_clock = 36000000,
0236         .conf = {
0237             0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00, 0x08,
0238             0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
0239             0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
0240             0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
0241         },
0242     },
0243     {
0244         .pixel_clock = 40000000,
0245         .conf = {
0246             0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00, 0x08,
0247             0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac, 0x80,
0248             0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
0249             0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
0250         },
0251     },
0252     {
0253         .pixel_clock = 65000000,
0254         .conf = {
0255             0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a, 0x08,
0256             0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac, 0x80,
0257             0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
0258             0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
0259         },
0260     },
0261     {
0262         .pixel_clock = 71000000,
0263         .conf = {
0264             0x01, 0xd1, 0x3b, 0x35, 0x40, 0x0c, 0x04, 0x08,
0265             0x85, 0xa0, 0x63, 0xd9, 0x45, 0xa0, 0xac, 0x80,
0266             0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
0267             0x54, 0xad, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
0268         },
0269     },
0270     {
0271         .pixel_clock = 73250000,
0272         .conf = {
0273             0x01, 0xd1, 0x3d, 0x35, 0x40, 0x18, 0x02, 0x08,
0274             0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
0275             0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
0276             0x54, 0xa8, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
0277         },
0278     },
0279     {
0280         .pixel_clock = 74176000,
0281         .conf = {
0282             0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde, 0x08,
0283             0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80,
0284             0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
0285             0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
0286         },
0287     },
0288     {
0289         .pixel_clock = 74250000,
0290         .conf = {
0291             0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
0292             0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
0293             0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
0294             0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
0295         },
0296     },
0297     {
0298         .pixel_clock = 83500000,
0299         .conf = {
0300             0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb, 0x08,
0301             0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80,
0302             0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
0303             0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
0304         },
0305     },
0306     {
0307         .pixel_clock = 85500000,
0308         .conf = {
0309             0x01, 0xd1, 0x24, 0x11, 0x40, 0x40, 0xd0, 0x08,
0310             0x84, 0xa0, 0xd6, 0xd8, 0x45, 0xa0, 0xac, 0x80,
0311             0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
0312             0x54, 0x90, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
0313         },
0314     },
0315     {
0316         .pixel_clock = 106500000,
0317         .conf = {
0318             0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08,
0319             0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
0320             0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
0321             0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
0322         },
0323     },
0324     {
0325         .pixel_clock = 108000000,
0326         .conf = {
0327             0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00, 0x08,
0328             0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
0329             0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
0330             0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
0331         },
0332     },
0333     {
0334         .pixel_clock = 115500000,
0335         .conf = {
0336             0x01, 0xd1, 0x30, 0x12, 0x40, 0x40, 0x10, 0x08,
0337             0x80, 0x80, 0x21, 0xd9, 0x45, 0xa0, 0xac, 0x80,
0338             0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
0339             0x54, 0xaa, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
0340         },
0341     },
0342     {
0343         .pixel_clock = 119000000,
0344         .conf = {
0345             0x01, 0xd1, 0x32, 0x1a, 0x40, 0x30, 0xd8, 0x08,
0346             0x04, 0xa0, 0x2a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
0347             0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
0348             0x54, 0x9d, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
0349         },
0350     },
0351     {
0352         .pixel_clock = 146250000,
0353         .conf = {
0354             0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd, 0x08,
0355             0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
0356             0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
0357             0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
0358         },
0359     },
0360     {
0361         .pixel_clock = 148500000,
0362         .conf = {
0363             0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
0364             0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
0365             0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
0366             0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
0367         },
0368     },
0369 };
0370 
0371 static const struct hdmiphy_config hdmiphy_5420_configs[] = {
0372     {
0373         .pixel_clock = 25200000,
0374         .conf = {
0375             0x01, 0x52, 0x3F, 0x55, 0x40, 0x01, 0x00, 0xC8,
0376             0x82, 0xC8, 0xBD, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
0377             0x06, 0x80, 0x01, 0x84, 0x05, 0x02, 0x24, 0x66,
0378             0x54, 0xF4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
0379         },
0380     },
0381     {
0382         .pixel_clock = 27000000,
0383         .conf = {
0384             0x01, 0xD1, 0x22, 0x51, 0x40, 0x08, 0xFC, 0xE0,
0385             0x98, 0xE8, 0xCB, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
0386             0x06, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
0387             0x54, 0xE4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
0388         },
0389     },
0390     {
0391         .pixel_clock = 27027000,
0392         .conf = {
0393             0x01, 0xD1, 0x2D, 0x72, 0x40, 0x64, 0x12, 0xC8,
0394             0x43, 0xE8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
0395             0x26, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
0396             0x54, 0xE3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
0397         },
0398     },
0399     {
0400         .pixel_clock = 36000000,
0401         .conf = {
0402             0x01, 0x51, 0x2D, 0x55, 0x40, 0x40, 0x00, 0xC8,
0403             0x02, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
0404             0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
0405             0x54, 0xAB, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
0406         },
0407     },
0408     {
0409         .pixel_clock = 40000000,
0410         .conf = {
0411             0x01, 0xD1, 0x21, 0x31, 0x40, 0x3C, 0x28, 0xC8,
0412             0x87, 0xE8, 0xC8, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
0413             0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
0414             0x54, 0x9A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
0415         },
0416     },
0417     {
0418         .pixel_clock = 65000000,
0419         .conf = {
0420             0x01, 0xD1, 0x36, 0x34, 0x40, 0x0C, 0x04, 0xC8,
0421             0x82, 0xE8, 0x45, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
0422             0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
0423             0x54, 0xBD, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
0424         },
0425     },
0426     {
0427         .pixel_clock = 71000000,
0428         .conf = {
0429             0x01, 0xD1, 0x3B, 0x35, 0x40, 0x0C, 0x04, 0xC8,
0430             0x85, 0xE8, 0x63, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
0431             0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
0432             0x54, 0x57, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
0433         },
0434     },
0435     {
0436         .pixel_clock = 73250000,
0437         .conf = {
0438             0x01, 0xD1, 0x1F, 0x10, 0x40, 0x78, 0x8D, 0xC8,
0439             0x81, 0xE8, 0xB7, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
0440             0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
0441             0x54, 0xA8, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
0442         },
0443     },
0444     {
0445         .pixel_clock = 74176000,
0446         .conf = {
0447             0x01, 0xD1, 0x1F, 0x10, 0x40, 0x5B, 0xEF, 0xC8,
0448             0x81, 0xE8, 0xB9, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
0449             0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
0450             0x54, 0xA6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
0451         },
0452     },
0453     {
0454         .pixel_clock = 74250000,
0455         .conf = {
0456             0x01, 0xD1, 0x1F, 0x10, 0x40, 0x40, 0xF8, 0x08,
0457             0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
0458             0x26, 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x66,
0459             0x54, 0xA5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
0460         },
0461     },
0462     {
0463         .pixel_clock = 83500000,
0464         .conf = {
0465             0x01, 0xD1, 0x23, 0x11, 0x40, 0x0C, 0xFB, 0xC8,
0466             0x85, 0xE8, 0xD1, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
0467             0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
0468             0x54, 0x4A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
0469         },
0470     },
0471     {
0472         .pixel_clock = 88750000,
0473         .conf = {
0474             0x01, 0xD1, 0x25, 0x11, 0x40, 0x18, 0xFF, 0xC8,
0475             0x83, 0xE8, 0xDE, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
0476             0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
0477             0x54, 0x45, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
0478         },
0479     },
0480     {
0481         .pixel_clock = 106500000,
0482         .conf = {
0483             0x01, 0xD1, 0x2C, 0x12, 0x40, 0x0C, 0x09, 0xC8,
0484             0x84, 0xE8, 0x0A, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
0485             0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
0486             0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
0487         },
0488     },
0489     {
0490         .pixel_clock = 108000000,
0491         .conf = {
0492             0x01, 0x51, 0x2D, 0x15, 0x40, 0x01, 0x00, 0xC8,
0493             0x82, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
0494             0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
0495             0x54, 0xC7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
0496         },
0497     },
0498     {
0499         .pixel_clock = 115500000,
0500         .conf = {
0501             0x01, 0xD1, 0x30, 0x14, 0x40, 0x0C, 0x03, 0xC8,
0502             0x88, 0xE8, 0x21, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
0503             0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
0504             0x54, 0x6A, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
0505         },
0506     },
0507     {
0508         .pixel_clock = 146250000,
0509         .conf = {
0510             0x01, 0xD1, 0x3D, 0x15, 0x40, 0x18, 0xFD, 0xC8,
0511             0x83, 0xE8, 0x6E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
0512             0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
0513             0x54, 0x54, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
0514         },
0515     },
0516     {
0517         .pixel_clock = 148500000,
0518         .conf = {
0519             0x01, 0xD1, 0x1F, 0x00, 0x40, 0x40, 0xF8, 0x08,
0520             0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
0521             0x26, 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x66,
0522             0x54, 0x4B, 0x25, 0x03, 0x00, 0x80, 0x01, 0x80,
0523         },
0524     },
0525     {
0526         .pixel_clock = 154000000,
0527         .conf = {
0528             0x01, 0xD1, 0x20, 0x01, 0x40, 0x30, 0x08, 0xCC,
0529             0x8C, 0xE8, 0xC1, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
0530             0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x86,
0531             0x54, 0x3F, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
0532         },
0533     },
0534 };
0535 
0536 static const struct hdmiphy_config hdmiphy_5433_configs[] = {
0537     {
0538         .pixel_clock = 27000000,
0539         .conf = {
0540             0x01, 0x51, 0x2d, 0x75, 0x01, 0x00, 0x88, 0x02,
0541             0x72, 0x50, 0x44, 0x8c, 0x27, 0x00, 0x7c, 0xac,
0542             0xd6, 0x2b, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
0543             0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
0544         },
0545     },
0546     {
0547         .pixel_clock = 27027000,
0548         .conf = {
0549             0x01, 0x51, 0x2d, 0x72, 0x64, 0x09, 0x88, 0xc3,
0550             0x71, 0x50, 0x44, 0x8c, 0x27, 0x00, 0x7c, 0xac,
0551             0xd6, 0x2b, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
0552             0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
0553         },
0554     },
0555     {
0556         .pixel_clock = 40000000,
0557         .conf = {
0558             0x01, 0x51, 0x32, 0x55, 0x01, 0x00, 0x88, 0x02,
0559             0x4d, 0x50, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
0560             0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
0561             0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
0562         },
0563     },
0564     {
0565         .pixel_clock = 50000000,
0566         .conf = {
0567             0x01, 0x51, 0x34, 0x40, 0x64, 0x09, 0x88, 0xc3,
0568             0x3d, 0x50, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
0569             0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
0570             0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
0571         },
0572     },
0573     {
0574         .pixel_clock = 65000000,
0575         .conf = {
0576             0x01, 0x51, 0x36, 0x31, 0x40, 0x10, 0x04, 0xc6,
0577             0x2e, 0xe8, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
0578             0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
0579             0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
0580         },
0581     },
0582     {
0583         .pixel_clock = 74176000,
0584         .conf = {
0585             0x01, 0x51, 0x3E, 0x35, 0x5B, 0xDE, 0x88, 0x42,
0586             0x53, 0x51, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
0587             0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
0588             0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
0589         },
0590     },
0591     {
0592         .pixel_clock = 74250000,
0593         .conf = {
0594             0x01, 0x51, 0x3E, 0x35, 0x40, 0xF0, 0x88, 0xC2,
0595             0x52, 0x51, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
0596             0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
0597             0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
0598         },
0599     },
0600     {
0601         .pixel_clock = 108000000,
0602         .conf = {
0603             0x01, 0x51, 0x2d, 0x15, 0x01, 0x00, 0x88, 0x02,
0604             0x72, 0x52, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
0605             0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
0606             0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
0607         },
0608     },
0609     {
0610         .pixel_clock = 148500000,
0611         .conf = {
0612             0x01, 0x51, 0x1f, 0x00, 0x40, 0xf8, 0x88, 0xc1,
0613             0x52, 0x52, 0x24, 0x0c, 0x24, 0x0f, 0x7c, 0xa5,
0614             0xd4, 0x2b, 0x87, 0x00, 0x00, 0x04, 0x00, 0x30,
0615             0x08, 0x10, 0x01, 0x01, 0x48, 0x4a, 0x00, 0x40,
0616         },
0617     },
0618     {
0619         .pixel_clock = 297000000,
0620         .conf = {
0621             0x01, 0x51, 0x3E, 0x05, 0x40, 0xF0, 0x88, 0xC2,
0622             0x52, 0x53, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
0623             0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
0624             0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
0625         },
0626     },
0627 };
0628 
0629 static const char * const hdmi_clk_gates4[] = {
0630     "hdmi", "sclk_hdmi"
0631 };
0632 
0633 static const char * const hdmi_clk_muxes4[] = {
0634     "sclk_pixel", "sclk_hdmiphy", "mout_hdmi"
0635 };
0636 
0637 static const char * const hdmi_clk_gates5433[] = {
0638     "hdmi_pclk", "hdmi_i_pclk", "i_tmds_clk", "i_pixel_clk", "i_spdif_clk"
0639 };
0640 
0641 static const char * const hdmi_clk_muxes5433[] = {
0642     "oscclk", "tmds_clko", "tmds_clko_user",
0643     "oscclk", "pixel_clko", "pixel_clko_user"
0644 };
0645 
0646 static const struct hdmi_driver_data exynos4210_hdmi_driver_data = {
0647     .type       = HDMI_TYPE13,
0648     .phy_confs  = INIT_ARRAY_SPEC(hdmiphy_v13_configs),
0649     .clk_gates  = INIT_ARRAY_SPEC(hdmi_clk_gates4),
0650     .clk_muxes  = INIT_ARRAY_SPEC(hdmi_clk_muxes4),
0651 };
0652 
0653 static const struct hdmi_driver_data exynos4212_hdmi_driver_data = {
0654     .type       = HDMI_TYPE14,
0655     .phy_confs  = INIT_ARRAY_SPEC(hdmiphy_v14_configs),
0656     .clk_gates  = INIT_ARRAY_SPEC(hdmi_clk_gates4),
0657     .clk_muxes  = INIT_ARRAY_SPEC(hdmi_clk_muxes4),
0658 };
0659 
0660 static const struct hdmi_driver_data exynos5420_hdmi_driver_data = {
0661     .type       = HDMI_TYPE14,
0662     .is_apb_phy = 1,
0663     .phy_confs  = INIT_ARRAY_SPEC(hdmiphy_5420_configs),
0664     .clk_gates  = INIT_ARRAY_SPEC(hdmi_clk_gates4),
0665     .clk_muxes  = INIT_ARRAY_SPEC(hdmi_clk_muxes4),
0666 };
0667 
0668 static const struct hdmi_driver_data exynos5433_hdmi_driver_data = {
0669     .type       = HDMI_TYPE14,
0670     .is_apb_phy = 1,
0671     .has_sysreg     = 1,
0672     .phy_confs  = INIT_ARRAY_SPEC(hdmiphy_5433_configs),
0673     .clk_gates  = INIT_ARRAY_SPEC(hdmi_clk_gates5433),
0674     .clk_muxes  = INIT_ARRAY_SPEC(hdmi_clk_muxes5433),
0675 };
0676 
0677 static inline u32 hdmi_map_reg(struct hdmi_context *hdata, u32 reg_id)
0678 {
0679     if ((reg_id & 0xffff0000) == HDMI_MAPPED_BASE)
0680         return hdmi_reg_map[reg_id & 0xffff][hdata->drv_data->type];
0681     return reg_id;
0682 }
0683 
0684 static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id)
0685 {
0686     return readl(hdata->regs + hdmi_map_reg(hdata, reg_id));
0687 }
0688 
0689 static inline void hdmi_reg_writeb(struct hdmi_context *hdata,
0690                  u32 reg_id, u8 value)
0691 {
0692     writel(value, hdata->regs + hdmi_map_reg(hdata, reg_id));
0693 }
0694 
0695 static inline void hdmi_reg_writev(struct hdmi_context *hdata, u32 reg_id,
0696                    int bytes, u32 val)
0697 {
0698     reg_id = hdmi_map_reg(hdata, reg_id);
0699 
0700     while (--bytes >= 0) {
0701         writel(val & 0xff, hdata->regs + reg_id);
0702         val >>= 8;
0703         reg_id += 4;
0704     }
0705 }
0706 
0707 static inline void hdmi_reg_write_buf(struct hdmi_context *hdata, u32 reg_id,
0708                       u8 *buf, int size)
0709 {
0710     for (reg_id = hdmi_map_reg(hdata, reg_id); size; --size, reg_id += 4)
0711         writel(*buf++, hdata->regs + reg_id);
0712 }
0713 
0714 static inline void hdmi_reg_writemask(struct hdmi_context *hdata,
0715                  u32 reg_id, u32 value, u32 mask)
0716 {
0717     u32 old;
0718 
0719     reg_id = hdmi_map_reg(hdata, reg_id);
0720     old = readl(hdata->regs + reg_id);
0721     value = (value & mask) | (old & ~mask);
0722     writel(value, hdata->regs + reg_id);
0723 }
0724 
0725 static int hdmiphy_reg_write_buf(struct hdmi_context *hdata,
0726             u32 reg_offset, const u8 *buf, u32 len)
0727 {
0728     if ((reg_offset + len) > 32)
0729         return -EINVAL;
0730 
0731     if (hdata->hdmiphy_port) {
0732         int ret;
0733 
0734         ret = i2c_master_send(hdata->hdmiphy_port, buf, len);
0735         if (ret == len)
0736             return 0;
0737         return ret;
0738     } else {
0739         int i;
0740         for (i = 0; i < len; i++)
0741             writel(buf[i], hdata->regs_hdmiphy +
0742                 ((reg_offset + i)<<2));
0743         return 0;
0744     }
0745 }
0746 
0747 static int hdmi_clk_enable_gates(struct hdmi_context *hdata)
0748 {
0749     int i, ret;
0750 
0751     for (i = 0; i < hdata->drv_data->clk_gates.count; ++i) {
0752         ret = clk_prepare_enable(hdata->clk_gates[i]);
0753         if (!ret)
0754             continue;
0755 
0756         dev_err(hdata->dev, "Cannot enable clock '%s', %d\n",
0757             hdata->drv_data->clk_gates.data[i], ret);
0758         while (i--)
0759             clk_disable_unprepare(hdata->clk_gates[i]);
0760         return ret;
0761     }
0762 
0763     return 0;
0764 }
0765 
0766 static void hdmi_clk_disable_gates(struct hdmi_context *hdata)
0767 {
0768     int i = hdata->drv_data->clk_gates.count;
0769 
0770     while (i--)
0771         clk_disable_unprepare(hdata->clk_gates[i]);
0772 }
0773 
0774 static int hdmi_clk_set_parents(struct hdmi_context *hdata, bool to_phy)
0775 {
0776     struct device *dev = hdata->dev;
0777     int ret = 0;
0778     int i;
0779 
0780     for (i = 0; i < hdata->drv_data->clk_muxes.count; i += 3) {
0781         struct clk **c = &hdata->clk_muxes[i];
0782 
0783         ret = clk_set_parent(c[2], c[to_phy]);
0784         if (!ret)
0785             continue;
0786 
0787         dev_err(dev, "Cannot set clock parent of '%s' to '%s', %d\n",
0788             hdata->drv_data->clk_muxes.data[i + 2],
0789             hdata->drv_data->clk_muxes.data[i + to_phy], ret);
0790     }
0791 
0792     return ret;
0793 }
0794 
0795 static int hdmi_audio_infoframe_apply(struct hdmi_context *hdata)
0796 {
0797     struct hdmi_audio_infoframe *infoframe = &hdata->audio.infoframe;
0798     u8 buf[HDMI_INFOFRAME_SIZE(AUDIO)];
0799     int len;
0800 
0801     len = hdmi_audio_infoframe_pack(infoframe, buf, sizeof(buf));
0802     if (len < 0)
0803         return len;
0804 
0805     hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_EVERY_VSYNC);
0806     hdmi_reg_write_buf(hdata, HDMI_AUI_HEADER0, buf, len);
0807 
0808     return 0;
0809 }
0810 
0811 static void hdmi_reg_infoframes(struct hdmi_context *hdata)
0812 {
0813     struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
0814     union hdmi_infoframe frm;
0815     u8 buf[25];
0816     int ret;
0817 
0818     if (hdata->dvi_mode) {
0819         hdmi_reg_writeb(hdata, HDMI_AVI_CON,
0820                 HDMI_AVI_CON_DO_NOT_TRANSMIT);
0821         hdmi_reg_writeb(hdata, HDMI_VSI_CON,
0822                 HDMI_VSI_CON_DO_NOT_TRANSMIT);
0823         hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_NO_TRAN);
0824         return;
0825     }
0826 
0827     ret = drm_hdmi_avi_infoframe_from_display_mode(&frm.avi,
0828                                &hdata->connector, m);
0829     if (!ret)
0830         ret = hdmi_avi_infoframe_pack(&frm.avi, buf, sizeof(buf));
0831     if (ret > 0) {
0832         hdmi_reg_writeb(hdata, HDMI_AVI_CON, HDMI_AVI_CON_EVERY_VSYNC);
0833         hdmi_reg_write_buf(hdata, HDMI_AVI_HEADER0, buf, ret);
0834     } else {
0835         DRM_INFO("%s: invalid AVI infoframe (%d)\n", __func__, ret);
0836     }
0837 
0838     ret = drm_hdmi_vendor_infoframe_from_display_mode(&frm.vendor.hdmi,
0839                               &hdata->connector, m);
0840     if (!ret)
0841         ret = hdmi_vendor_infoframe_pack(&frm.vendor.hdmi, buf,
0842                 sizeof(buf));
0843     if (ret > 0) {
0844         hdmi_reg_writeb(hdata, HDMI_VSI_CON, HDMI_VSI_CON_EVERY_VSYNC);
0845         hdmi_reg_write_buf(hdata, HDMI_VSI_HEADER0, buf, 3);
0846         hdmi_reg_write_buf(hdata, HDMI_VSI_DATA(0), buf + 3, ret - 3);
0847     }
0848 
0849     hdmi_audio_infoframe_apply(hdata);
0850 }
0851 
0852 static enum drm_connector_status hdmi_detect(struct drm_connector *connector,
0853                 bool force)
0854 {
0855     struct hdmi_context *hdata = connector_to_hdmi(connector);
0856 
0857     if (gpiod_get_value(hdata->hpd_gpio))
0858         return connector_status_connected;
0859 
0860     cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID);
0861     return connector_status_disconnected;
0862 }
0863 
0864 static void hdmi_connector_destroy(struct drm_connector *connector)
0865 {
0866     struct hdmi_context *hdata = connector_to_hdmi(connector);
0867 
0868     cec_notifier_conn_unregister(hdata->notifier);
0869 
0870     drm_connector_unregister(connector);
0871     drm_connector_cleanup(connector);
0872 }
0873 
0874 static const struct drm_connector_funcs hdmi_connector_funcs = {
0875     .fill_modes = drm_helper_probe_single_connector_modes,
0876     .detect = hdmi_detect,
0877     .destroy = hdmi_connector_destroy,
0878     .reset = drm_atomic_helper_connector_reset,
0879     .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
0880     .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
0881 };
0882 
0883 static int hdmi_get_modes(struct drm_connector *connector)
0884 {
0885     struct hdmi_context *hdata = connector_to_hdmi(connector);
0886     struct edid *edid;
0887     int ret;
0888 
0889     if (!hdata->ddc_adpt)
0890         return -ENODEV;
0891 
0892     edid = drm_get_edid(connector, hdata->ddc_adpt);
0893     if (!edid)
0894         return -ENODEV;
0895 
0896     hdata->dvi_mode = !drm_detect_hdmi_monitor(edid);
0897     DRM_DEV_DEBUG_KMS(hdata->dev, "%s : width[%d] x height[%d]\n",
0898               (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"),
0899               edid->width_cm, edid->height_cm);
0900 
0901     drm_connector_update_edid_property(connector, edid);
0902     cec_notifier_set_phys_addr_from_edid(hdata->notifier, edid);
0903 
0904     ret = drm_add_edid_modes(connector, edid);
0905 
0906     kfree(edid);
0907 
0908     return ret;
0909 }
0910 
0911 static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
0912 {
0913     const struct hdmiphy_configs *confs = &hdata->drv_data->phy_confs;
0914     int i;
0915 
0916     for (i = 0; i < confs->count; i++)
0917         if (confs->data[i].pixel_clock == pixel_clock)
0918             return i;
0919 
0920     DRM_DEV_DEBUG_KMS(hdata->dev, "Could not find phy config for %d\n",
0921               pixel_clock);
0922     return -EINVAL;
0923 }
0924 
0925 static int hdmi_mode_valid(struct drm_connector *connector,
0926             struct drm_display_mode *mode)
0927 {
0928     struct hdmi_context *hdata = connector_to_hdmi(connector);
0929     int ret;
0930 
0931     DRM_DEV_DEBUG_KMS(hdata->dev,
0932               "xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
0933               mode->hdisplay, mode->vdisplay,
0934               drm_mode_vrefresh(mode),
0935               (mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
0936               false, mode->clock * 1000);
0937 
0938     ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
0939     if (ret < 0)
0940         return MODE_BAD;
0941 
0942     return MODE_OK;
0943 }
0944 
0945 static const struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
0946     .get_modes = hdmi_get_modes,
0947     .mode_valid = hdmi_mode_valid,
0948 };
0949 
0950 static int hdmi_create_connector(struct drm_encoder *encoder)
0951 {
0952     struct hdmi_context *hdata = encoder_to_hdmi(encoder);
0953     struct drm_connector *connector = &hdata->connector;
0954     struct cec_connector_info conn_info;
0955     int ret;
0956 
0957     connector->interlace_allowed = true;
0958     connector->polled = DRM_CONNECTOR_POLL_HPD;
0959 
0960     ret = drm_connector_init_with_ddc(hdata->drm_dev, connector,
0961                       &hdmi_connector_funcs,
0962                       DRM_MODE_CONNECTOR_HDMIA,
0963                       hdata->ddc_adpt);
0964     if (ret) {
0965         DRM_DEV_ERROR(hdata->dev,
0966                   "Failed to initialize connector with drm\n");
0967         return ret;
0968     }
0969 
0970     drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
0971     drm_connector_attach_encoder(connector, encoder);
0972 
0973     if (hdata->bridge)
0974         ret = drm_bridge_attach(encoder, hdata->bridge, NULL, 0);
0975 
0976     cec_fill_conn_info_from_drm(&conn_info, connector);
0977 
0978     hdata->notifier = cec_notifier_conn_register(hdata->dev, NULL,
0979                              &conn_info);
0980     if (!hdata->notifier) {
0981         ret = -ENOMEM;
0982         DRM_DEV_ERROR(hdata->dev, "Failed to allocate CEC notifier\n");
0983     }
0984 
0985     return ret;
0986 }
0987 
0988 static bool hdmi_mode_fixup(struct drm_encoder *encoder,
0989                 const struct drm_display_mode *mode,
0990                 struct drm_display_mode *adjusted_mode)
0991 {
0992     struct drm_device *dev = encoder->dev;
0993     struct drm_connector *connector;
0994     struct drm_display_mode *m;
0995     struct drm_connector_list_iter conn_iter;
0996     int mode_ok;
0997 
0998     drm_mode_set_crtcinfo(adjusted_mode, 0);
0999 
1000     drm_connector_list_iter_begin(dev, &conn_iter);
1001     drm_for_each_connector_iter(connector, &conn_iter) {
1002         if (connector->encoder == encoder)
1003             break;
1004     }
1005     if (connector)
1006         drm_connector_get(connector);
1007     drm_connector_list_iter_end(&conn_iter);
1008 
1009     if (!connector)
1010         return true;
1011 
1012     mode_ok = hdmi_mode_valid(connector, adjusted_mode);
1013 
1014     if (mode_ok == MODE_OK)
1015         goto cleanup;
1016 
1017     /*
1018      * Find the most suitable mode and copy it to adjusted_mode.
1019      */
1020     list_for_each_entry(m, &connector->modes, head) {
1021         mode_ok = hdmi_mode_valid(connector, m);
1022 
1023         if (mode_ok == MODE_OK) {
1024             DRM_INFO("desired mode doesn't exist so\n");
1025             DRM_INFO("use the most suitable mode among modes.\n");
1026 
1027             DRM_DEV_DEBUG_KMS(dev->dev,
1028                       "Adjusted Mode: [%d]x[%d] [%d]Hz\n",
1029                       m->hdisplay, m->vdisplay,
1030                       drm_mode_vrefresh(m));
1031 
1032             drm_mode_copy(adjusted_mode, m);
1033             break;
1034         }
1035     }
1036 
1037 cleanup:
1038     drm_connector_put(connector);
1039 
1040     return true;
1041 }
1042 
1043 static void hdmi_reg_acr(struct hdmi_context *hdata, u32 freq)
1044 {
1045     u32 n, cts;
1046 
1047     cts = (freq % 9) ? 27000 : 30000;
1048     n = 128 * freq / (27000000 / cts);
1049 
1050     hdmi_reg_writev(hdata, HDMI_ACR_N0, 3, n);
1051     hdmi_reg_writev(hdata, HDMI_ACR_MCTS0, 3, cts);
1052     hdmi_reg_writev(hdata, HDMI_ACR_CTS0, 3, cts);
1053     hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
1054 }
1055 
1056 static void hdmi_audio_config(struct hdmi_context *hdata)
1057 {
1058     u32 bit_ch = 1;
1059     u32 data_num, val;
1060     int i;
1061 
1062     switch (hdata->audio.params.sample_width) {
1063     case 20:
1064         data_num = 2;
1065         break;
1066     case 24:
1067         data_num = 3;
1068         break;
1069     default:
1070         data_num = 1;
1071         bit_ch = 0;
1072         break;
1073     }
1074 
1075     hdmi_reg_acr(hdata, hdata->audio.params.sample_rate);
1076 
1077     hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE
1078                 | HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE
1079                 | HDMI_I2S_MUX_ENABLE);
1080 
1081     hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN
1082             | HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN);
1083 
1084     hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN);
1085     hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS);
1086     hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN);
1087 
1088     val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01;
1089     hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val);
1090 
1091     /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1092     hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
1093             | HDMI_I2S_SEL_LRCK(6));
1094 
1095     hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(3)
1096             | HDMI_I2S_SEL_SDATA0(4));
1097 
1098     hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
1099             | HDMI_I2S_SEL_SDATA2(2));
1100 
1101     hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
1102 
1103     /* I2S_CON_1 & 2 */
1104     hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE
1105             | HDMI_I2S_L_CH_LOW_POL);
1106     hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE
1107             | HDMI_I2S_SET_BIT_CH(bit_ch)
1108             | HDMI_I2S_SET_SDATA_BIT(data_num)
1109             | HDMI_I2S_BASIC_FORMAT);
1110 
1111     /* Configuration of the audio channel status registers */
1112     for (i = 0; i < HDMI_I2S_CH_ST_MAXNUM; i++)
1113         hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST(i),
1114                 hdata->audio.params.iec.status[i]);
1115 
1116     hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD);
1117 }
1118 
1119 static void hdmi_audio_control(struct hdmi_context *hdata)
1120 {
1121     bool enable = !hdata->audio.mute;
1122 
1123     if (hdata->dvi_mode)
1124         return;
1125 
1126     hdmi_reg_writeb(hdata, HDMI_AUI_CON, enable ?
1127             HDMI_AVI_CON_EVERY_VSYNC : HDMI_AUI_CON_NO_TRAN);
1128     hdmi_reg_writemask(hdata, HDMI_CON_0, enable ?
1129             HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
1130 }
1131 
1132 static void hdmi_start(struct hdmi_context *hdata, bool start)
1133 {
1134     struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
1135     u32 val = start ? HDMI_TG_EN : 0;
1136 
1137     if (m->flags & DRM_MODE_FLAG_INTERLACE)
1138         val |= HDMI_FIELD_EN;
1139 
1140     hdmi_reg_writemask(hdata, HDMI_CON_0, val, HDMI_EN);
1141     hdmi_reg_writemask(hdata, HDMI_TG_CMD, val, HDMI_TG_EN | HDMI_FIELD_EN);
1142 }
1143 
1144 static void hdmi_conf_init(struct hdmi_context *hdata)
1145 {
1146     /* disable HPD interrupts from HDMI IP block, use GPIO instead */
1147     hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1148         HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1149 
1150     /* choose HDMI mode */
1151     hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1152         HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
1153     /* apply video pre-amble and guard band in HDMI mode only */
1154     hdmi_reg_writeb(hdata, HDMI_CON_2, 0);
1155     /* disable bluescreen */
1156     hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
1157 
1158     if (hdata->dvi_mode) {
1159         hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1160                 HDMI_MODE_DVI_EN, HDMI_MODE_MASK);
1161         hdmi_reg_writeb(hdata, HDMI_CON_2,
1162                 HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS);
1163     }
1164 
1165     if (hdata->drv_data->type == HDMI_TYPE13) {
1166         /* choose bluescreen (fecal) color */
1167         hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
1168         hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
1169         hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56);
1170 
1171         /* enable AVI packet every vsync, fixes purple line problem */
1172         hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02);
1173         /* force RGB, look to CEA-861-D, table 7 for more detail */
1174         hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5);
1175         hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5);
1176 
1177         hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02);
1178         hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1179         hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1180     } else {
1181         hdmi_reg_infoframes(hdata);
1182 
1183         /* enable AVI packet every vsync, fixes purple line problem */
1184         hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1185     }
1186 }
1187 
1188 static void hdmiphy_wait_for_pll(struct hdmi_context *hdata)
1189 {
1190     int tries;
1191 
1192     for (tries = 0; tries < 10; ++tries) {
1193         u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS);
1194 
1195         if (val & HDMI_PHY_STATUS_READY) {
1196             DRM_DEV_DEBUG_KMS(hdata->dev,
1197                       "PLL stabilized after %d tries\n",
1198                       tries);
1199             return;
1200         }
1201         usleep_range(10, 20);
1202     }
1203 
1204     DRM_DEV_ERROR(hdata->dev, "PLL could not reach steady state\n");
1205 }
1206 
1207 static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
1208 {
1209     struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
1210     unsigned int val;
1211 
1212     hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
1213     hdmi_reg_writev(hdata, HDMI_V13_H_V_LINE_0, 3,
1214             (m->htotal << 12) | m->vtotal);
1215 
1216     val = (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0;
1217     hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1, val);
1218 
1219     val = (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0;
1220     hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1, val);
1221 
1222     val = (m->hsync_start - m->hdisplay - 2);
1223     val |= ((m->hsync_end - m->hdisplay - 2) << 10);
1224     val |= ((m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0)<<20;
1225     hdmi_reg_writev(hdata, HDMI_V13_H_SYNC_GEN_0, 3, val);
1226 
1227     /*
1228      * Quirk requirement for exynos HDMI IP design,
1229      * 2 pixels less than the actual calculation for hsync_start
1230      * and end.
1231      */
1232 
1233     /* Following values & calculations differ for different type of modes */
1234     if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1235         val = ((m->vsync_end - m->vdisplay) / 2);
1236         val |= ((m->vsync_start - m->vdisplay) / 2) << 12;
1237         hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val);
1238 
1239         val = m->vtotal / 2;
1240         val |= ((m->vtotal - m->vdisplay) / 2) << 11;
1241         hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val);
1242 
1243         val = (m->vtotal +
1244             ((m->vsync_end - m->vsync_start) * 4) + 5) / 2;
1245         val |= m->vtotal << 11;
1246         hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_F_0, 3, val);
1247 
1248         val = ((m->vtotal / 2) + 7);
1249         val |= ((m->vtotal / 2) + 2) << 12;
1250         hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_2_0, 3, val);
1251 
1252         val = ((m->htotal / 2) + (m->hsync_start - m->hdisplay));
1253         val |= ((m->htotal / 2) +
1254             (m->hsync_start - m->hdisplay)) << 12;
1255         hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_3_0, 3, val);
1256 
1257         hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1258                 (m->vtotal - m->vdisplay) / 2);
1259         hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay / 2);
1260 
1261         hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2, 0x249);
1262     } else {
1263         val = m->vtotal;
1264         val |= (m->vtotal - m->vdisplay) << 11;
1265         hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val);
1266 
1267         hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_F_0, 3, 0);
1268 
1269         val = (m->vsync_end - m->vdisplay);
1270         val |= ((m->vsync_start - m->vdisplay) << 12);
1271         hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val);
1272 
1273         hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_2_0, 3, 0x1001);
1274         hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_3_0, 3, 0x1001);
1275         hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1276                 m->vtotal - m->vdisplay);
1277         hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
1278     }
1279 
1280     hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
1281     hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay);
1282     hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay);
1283     hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
1284 }
1285 
1286 static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
1287 {
1288     struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
1289     struct drm_display_mode *am =
1290                 &hdata->encoder.crtc->state->adjusted_mode;
1291     int hquirk = 0;
1292 
1293     /*
1294      * In case video mode coming from CRTC differs from requested one HDMI
1295      * sometimes is able to almost properly perform conversion - only
1296      * first line is distorted.
1297      */
1298     if ((m->vdisplay != am->vdisplay) &&
1299         (m->hdisplay == 1280 || m->hdisplay == 1024 || m->hdisplay == 1366))
1300         hquirk = 258;
1301 
1302     hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
1303     hdmi_reg_writev(hdata, HDMI_V_LINE_0, 2, m->vtotal);
1304     hdmi_reg_writev(hdata, HDMI_H_LINE_0, 2, m->htotal);
1305     hdmi_reg_writev(hdata, HDMI_HSYNC_POL, 1,
1306             (m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0);
1307     hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1,
1308             (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0);
1309     hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1,
1310             (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
1311 
1312     /*
1313      * Quirk requirement for exynos 5 HDMI IP design,
1314      * 2 pixels less than the actual calculation for hsync_start
1315      * and end.
1316      */
1317 
1318     /* Following values & calculations differ for different type of modes */
1319     if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1320         hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1321             (m->vsync_end - m->vdisplay) / 2);
1322         hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
1323             (m->vsync_start - m->vdisplay) / 2);
1324         hdmi_reg_writev(hdata, HDMI_V2_BLANK_0, 2, m->vtotal / 2);
1325         hdmi_reg_writev(hdata, HDMI_V1_BLANK_0, 2,
1326                 (m->vtotal - m->vdisplay) / 2);
1327         hdmi_reg_writev(hdata, HDMI_V_BLANK_F0_0, 2,
1328                 m->vtotal - m->vdisplay / 2);
1329         hdmi_reg_writev(hdata, HDMI_V_BLANK_F1_0, 2, m->vtotal);
1330         hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_2_0, 2,
1331                 (m->vtotal / 2) + 7);
1332         hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_1_0, 2,
1333                 (m->vtotal / 2) + 2);
1334         hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, 2,
1335             (m->htotal / 2) + (m->hsync_start - m->hdisplay));
1336         hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, 2,
1337             (m->htotal / 2) + (m->hsync_start - m->hdisplay));
1338         hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1339                 (m->vtotal - m->vdisplay) / 2);
1340         hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay / 2);
1341         hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2,
1342                 m->vtotal - m->vdisplay / 2);
1343         hdmi_reg_writev(hdata, HDMI_TG_VSYNC2_L, 2,
1344                 (m->vtotal / 2) + 1);
1345         hdmi_reg_writev(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, 2,
1346                 (m->vtotal / 2) + 1);
1347         hdmi_reg_writev(hdata, HDMI_TG_FIELD_BOT_HDMI_L, 2,
1348                 (m->vtotal / 2) + 1);
1349         hdmi_reg_writev(hdata, HDMI_TG_VACT_ST3_L, 2, 0x0);
1350         hdmi_reg_writev(hdata, HDMI_TG_VACT_ST4_L, 2, 0x0);
1351     } else {
1352         hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1353             m->vsync_end - m->vdisplay);
1354         hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
1355             m->vsync_start - m->vdisplay);
1356         hdmi_reg_writev(hdata, HDMI_V2_BLANK_0, 2, m->vtotal);
1357         hdmi_reg_writev(hdata, HDMI_V1_BLANK_0, 2,
1358                 m->vtotal - m->vdisplay);
1359         hdmi_reg_writev(hdata, HDMI_V_BLANK_F0_0, 2, 0xffff);
1360         hdmi_reg_writev(hdata, HDMI_V_BLANK_F1_0, 2, 0xffff);
1361         hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_2_0, 2, 0xffff);
1362         hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_1_0, 2, 0xffff);
1363         hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, 2, 0xffff);
1364         hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, 2, 0xffff);
1365         hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1366                 m->vtotal - m->vdisplay);
1367         hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
1368     }
1369 
1370     hdmi_reg_writev(hdata, HDMI_H_SYNC_START_0, 2,
1371             m->hsync_start - m->hdisplay - 2);
1372     hdmi_reg_writev(hdata, HDMI_H_SYNC_END_0, 2,
1373             m->hsync_end - m->hdisplay - 2);
1374     hdmi_reg_writev(hdata, HDMI_VACT_SPACE_1_0, 2, 0xffff);
1375     hdmi_reg_writev(hdata, HDMI_VACT_SPACE_2_0, 2, 0xffff);
1376     hdmi_reg_writev(hdata, HDMI_VACT_SPACE_3_0, 2, 0xffff);
1377     hdmi_reg_writev(hdata, HDMI_VACT_SPACE_4_0, 2, 0xffff);
1378     hdmi_reg_writev(hdata, HDMI_VACT_SPACE_5_0, 2, 0xffff);
1379     hdmi_reg_writev(hdata, HDMI_VACT_SPACE_6_0, 2, 0xffff);
1380     hdmi_reg_writev(hdata, HDMI_V_BLANK_F2_0, 2, 0xffff);
1381     hdmi_reg_writev(hdata, HDMI_V_BLANK_F3_0, 2, 0xffff);
1382     hdmi_reg_writev(hdata, HDMI_V_BLANK_F4_0, 2, 0xffff);
1383     hdmi_reg_writev(hdata, HDMI_V_BLANK_F5_0, 2, 0xffff);
1384     hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_3_0, 2, 0xffff);
1385     hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_4_0, 2, 0xffff);
1386     hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_5_0, 2, 0xffff);
1387     hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_6_0, 2, 0xffff);
1388     hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0, 2, 0xffff);
1389     hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0, 2, 0xffff);
1390     hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0, 2, 0xffff);
1391     hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, 2, 0xffff);
1392 
1393     hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
1394     hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2,
1395                     m->htotal - m->hdisplay - hquirk);
1396     hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay + hquirk);
1397     hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
1398     if (hdata->drv_data == &exynos5433_hdmi_driver_data)
1399         hdmi_reg_writeb(hdata, HDMI_TG_DECON_EN, 1);
1400 }
1401 
1402 static void hdmi_mode_apply(struct hdmi_context *hdata)
1403 {
1404     if (hdata->drv_data->type == HDMI_TYPE13)
1405         hdmi_v13_mode_apply(hdata);
1406     else
1407         hdmi_v14_mode_apply(hdata);
1408 
1409     hdmi_start(hdata, true);
1410 }
1411 
1412 static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1413 {
1414     hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, 0, 1);
1415     usleep_range(10000, 12000);
1416     hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, ~0, 1);
1417     usleep_range(10000, 12000);
1418     hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT);
1419     usleep_range(10000, 12000);
1420     hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, 0, HDMI_PHY_SW_RSTOUT);
1421     usleep_range(10000, 12000);
1422 }
1423 
1424 static void hdmiphy_enable_mode_set(struct hdmi_context *hdata, bool enable)
1425 {
1426     u8 v = enable ? HDMI_PHY_ENABLE_MODE_SET : HDMI_PHY_DISABLE_MODE_SET;
1427 
1428     if (hdata->drv_data == &exynos5433_hdmi_driver_data)
1429         writel(v, hdata->regs_hdmiphy + HDMIPHY5433_MODE_SET_DONE);
1430 }
1431 
1432 static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1433 {
1434     struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
1435     int ret;
1436     const u8 *phy_conf;
1437 
1438     ret = hdmi_find_phy_conf(hdata, m->clock * 1000);
1439     if (ret < 0) {
1440         DRM_DEV_ERROR(hdata->dev, "failed to find hdmiphy conf\n");
1441         return;
1442     }
1443     phy_conf = hdata->drv_data->phy_confs.data[ret].conf;
1444 
1445     hdmi_clk_set_parents(hdata, false);
1446 
1447     hdmiphy_conf_reset(hdata);
1448 
1449     hdmiphy_enable_mode_set(hdata, true);
1450     ret = hdmiphy_reg_write_buf(hdata, 0, phy_conf, 32);
1451     if (ret) {
1452         DRM_DEV_ERROR(hdata->dev, "failed to configure hdmiphy\n");
1453         return;
1454     }
1455     hdmiphy_enable_mode_set(hdata, false);
1456     hdmi_clk_set_parents(hdata, true);
1457     usleep_range(10000, 12000);
1458     hdmiphy_wait_for_pll(hdata);
1459 }
1460 
1461 /* Should be called with hdata->mutex mutex held */
1462 static void hdmi_conf_apply(struct hdmi_context *hdata)
1463 {
1464     hdmi_start(hdata, false);
1465     hdmi_conf_init(hdata);
1466     hdmi_audio_config(hdata);
1467     hdmi_mode_apply(hdata);
1468     hdmi_audio_control(hdata);
1469 }
1470 
1471 static void hdmi_set_refclk(struct hdmi_context *hdata, bool on)
1472 {
1473     if (!hdata->sysreg)
1474         return;
1475 
1476     regmap_update_bits(hdata->sysreg, EXYNOS5433_SYSREG_DISP_HDMI_PHY,
1477                SYSREG_HDMI_REFCLK_INT_CLK, on ? ~0 : 0);
1478 }
1479 
1480 /* Should be called with hdata->mutex mutex held. */
1481 static void hdmiphy_enable(struct hdmi_context *hdata)
1482 {
1483     int ret;
1484 
1485     if (hdata->powered)
1486         return;
1487 
1488     ret = pm_runtime_resume_and_get(hdata->dev);
1489     if (ret < 0) {
1490         dev_err(hdata->dev, "failed to enable HDMIPHY device.\n");
1491         return;
1492     }
1493 
1494     if (regulator_bulk_enable(ARRAY_SIZE(supply), hdata->regul_bulk))
1495         DRM_DEV_DEBUG_KMS(hdata->dev,
1496                   "failed to enable regulator bulk\n");
1497 
1498     regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1499             PMU_HDMI_PHY_ENABLE_BIT, 1);
1500 
1501     hdmi_set_refclk(hdata, true);
1502 
1503     hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0, HDMI_PHY_POWER_OFF_EN);
1504 
1505     hdmiphy_conf_apply(hdata);
1506 
1507     hdata->powered = true;
1508 }
1509 
1510 /* Should be called with hdata->mutex mutex held. */
1511 static void hdmiphy_disable(struct hdmi_context *hdata)
1512 {
1513     if (!hdata->powered)
1514         return;
1515 
1516     hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN);
1517 
1518     hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0, HDMI_PHY_POWER_OFF_EN);
1519 
1520     hdmi_set_refclk(hdata, false);
1521 
1522     regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1523             PMU_HDMI_PHY_ENABLE_BIT, 0);
1524 
1525     regulator_bulk_disable(ARRAY_SIZE(supply), hdata->regul_bulk);
1526 
1527     pm_runtime_put_sync(hdata->dev);
1528 
1529     hdata->powered = false;
1530 }
1531 
1532 static void hdmi_enable(struct drm_encoder *encoder)
1533 {
1534     struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1535 
1536     mutex_lock(&hdata->mutex);
1537 
1538     hdmiphy_enable(hdata);
1539     hdmi_conf_apply(hdata);
1540 
1541     mutex_unlock(&hdata->mutex);
1542 }
1543 
1544 static void hdmi_disable(struct drm_encoder *encoder)
1545 {
1546     struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1547 
1548     mutex_lock(&hdata->mutex);
1549 
1550     if (hdata->powered) {
1551         /*
1552          * The SFRs of VP and Mixer are updated by Vertical Sync of
1553          * Timing generator which is a part of HDMI so the sequence
1554          * to disable TV Subsystem should be as following,
1555          *  VP -> Mixer -> HDMI
1556          *
1557          * To achieve such sequence HDMI is disabled together with
1558          * HDMI PHY, via pipe clock callback.
1559          */
1560         mutex_unlock(&hdata->mutex);
1561         cancel_delayed_work(&hdata->hotplug_work);
1562         if (hdata->notifier)
1563             cec_notifier_phys_addr_invalidate(hdata->notifier);
1564         return;
1565     }
1566 
1567     mutex_unlock(&hdata->mutex);
1568 }
1569 
1570 static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = {
1571     .mode_fixup = hdmi_mode_fixup,
1572     .enable     = hdmi_enable,
1573     .disable    = hdmi_disable,
1574 };
1575 
1576 static void hdmi_audio_shutdown(struct device *dev, void *data)
1577 {
1578     struct hdmi_context *hdata = dev_get_drvdata(dev);
1579 
1580     mutex_lock(&hdata->mutex);
1581 
1582     hdata->audio.mute = true;
1583 
1584     if (hdata->powered)
1585         hdmi_audio_control(hdata);
1586 
1587     mutex_unlock(&hdata->mutex);
1588 }
1589 
1590 static int hdmi_audio_hw_params(struct device *dev, void *data,
1591                 struct hdmi_codec_daifmt *daifmt,
1592                 struct hdmi_codec_params *params)
1593 {
1594     struct hdmi_context *hdata = dev_get_drvdata(dev);
1595 
1596     if (daifmt->fmt != HDMI_I2S || daifmt->bit_clk_inv ||
1597         daifmt->frame_clk_inv || daifmt->bit_clk_provider ||
1598         daifmt->frame_clk_provider) {
1599         dev_err(dev, "%s: Bad flags %d %d %d %d\n", __func__,
1600             daifmt->bit_clk_inv, daifmt->frame_clk_inv,
1601             daifmt->bit_clk_provider,
1602             daifmt->frame_clk_provider);
1603         return -EINVAL;
1604     }
1605 
1606     mutex_lock(&hdata->mutex);
1607 
1608     hdata->audio.params = *params;
1609 
1610     if (hdata->powered) {
1611         hdmi_audio_config(hdata);
1612         hdmi_audio_infoframe_apply(hdata);
1613     }
1614 
1615     mutex_unlock(&hdata->mutex);
1616 
1617     return 0;
1618 }
1619 
1620 static int hdmi_audio_mute(struct device *dev, void *data,
1621                bool mute, int direction)
1622 {
1623     struct hdmi_context *hdata = dev_get_drvdata(dev);
1624 
1625     mutex_lock(&hdata->mutex);
1626 
1627     hdata->audio.mute = mute;
1628 
1629     if (hdata->powered)
1630         hdmi_audio_control(hdata);
1631 
1632     mutex_unlock(&hdata->mutex);
1633 
1634     return 0;
1635 }
1636 
1637 static int hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf,
1638                   size_t len)
1639 {
1640     struct hdmi_context *hdata = dev_get_drvdata(dev);
1641     struct drm_connector *connector = &hdata->connector;
1642 
1643     memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
1644 
1645     return 0;
1646 }
1647 
1648 static const struct hdmi_codec_ops audio_codec_ops = {
1649     .hw_params = hdmi_audio_hw_params,
1650     .audio_shutdown = hdmi_audio_shutdown,
1651     .mute_stream = hdmi_audio_mute,
1652     .get_eld = hdmi_audio_get_eld,
1653     .no_capture_mute = 1,
1654 };
1655 
1656 static int hdmi_register_audio_device(struct hdmi_context *hdata)
1657 {
1658     struct hdmi_codec_pdata codec_data = {
1659         .ops = &audio_codec_ops,
1660         .max_i2s_channels = 6,
1661         .i2s = 1,
1662     };
1663 
1664     hdata->audio.pdev = platform_device_register_data(
1665         hdata->dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO,
1666         &codec_data, sizeof(codec_data));
1667 
1668     return PTR_ERR_OR_ZERO(hdata->audio.pdev);
1669 }
1670 
1671 static void hdmi_hotplug_work_func(struct work_struct *work)
1672 {
1673     struct hdmi_context *hdata;
1674 
1675     hdata = container_of(work, struct hdmi_context, hotplug_work.work);
1676 
1677     if (hdata->drm_dev)
1678         drm_helper_hpd_irq_event(hdata->drm_dev);
1679 }
1680 
1681 static irqreturn_t hdmi_irq_thread(int irq, void *arg)
1682 {
1683     struct hdmi_context *hdata = arg;
1684 
1685     mod_delayed_work(system_wq, &hdata->hotplug_work,
1686             msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
1687 
1688     return IRQ_HANDLED;
1689 }
1690 
1691 static int hdmi_clks_get(struct hdmi_context *hdata,
1692              const struct string_array_spec *names,
1693              struct clk **clks)
1694 {
1695     struct device *dev = hdata->dev;
1696     int i;
1697 
1698     for (i = 0; i < names->count; ++i) {
1699         struct clk *clk = devm_clk_get(dev, names->data[i]);
1700 
1701         if (IS_ERR(clk)) {
1702             int ret = PTR_ERR(clk);
1703 
1704             dev_err(dev, "Cannot get clock %s, %d\n",
1705                 names->data[i], ret);
1706 
1707             return ret;
1708         }
1709 
1710         clks[i] = clk;
1711     }
1712 
1713     return 0;
1714 }
1715 
1716 static int hdmi_clk_init(struct hdmi_context *hdata)
1717 {
1718     const struct hdmi_driver_data *drv_data = hdata->drv_data;
1719     int count = drv_data->clk_gates.count + drv_data->clk_muxes.count;
1720     struct device *dev = hdata->dev;
1721     struct clk **clks;
1722     int ret;
1723 
1724     if (!count)
1725         return 0;
1726 
1727     clks = devm_kcalloc(dev, count, sizeof(*clks), GFP_KERNEL);
1728     if (!clks)
1729         return -ENOMEM;
1730 
1731     hdata->clk_gates = clks;
1732     hdata->clk_muxes = clks + drv_data->clk_gates.count;
1733 
1734     ret = hdmi_clks_get(hdata, &drv_data->clk_gates, hdata->clk_gates);
1735     if (ret)
1736         return ret;
1737 
1738     return hdmi_clks_get(hdata, &drv_data->clk_muxes, hdata->clk_muxes);
1739 }
1740 
1741 
1742 static void hdmiphy_clk_enable(struct exynos_drm_clk *clk, bool enable)
1743 {
1744     struct hdmi_context *hdata = container_of(clk, struct hdmi_context,
1745                           phy_clk);
1746     mutex_lock(&hdata->mutex);
1747 
1748     if (enable)
1749         hdmiphy_enable(hdata);
1750     else
1751         hdmiphy_disable(hdata);
1752 
1753     mutex_unlock(&hdata->mutex);
1754 }
1755 
1756 static int hdmi_bridge_init(struct hdmi_context *hdata)
1757 {
1758     struct device *dev = hdata->dev;
1759     struct device_node *ep, *np;
1760 
1761     ep = of_graph_get_endpoint_by_regs(dev->of_node, 1, -1);
1762     if (!ep)
1763         return 0;
1764 
1765     np = of_graph_get_remote_port_parent(ep);
1766     of_node_put(ep);
1767     if (!np) {
1768         DRM_DEV_ERROR(dev, "failed to get remote port parent");
1769         return -EINVAL;
1770     }
1771 
1772     hdata->bridge = of_drm_find_bridge(np);
1773     of_node_put(np);
1774 
1775     if (!hdata->bridge)
1776         return -EPROBE_DEFER;
1777 
1778     return 0;
1779 }
1780 
1781 static int hdmi_resources_init(struct hdmi_context *hdata)
1782 {
1783     struct device *dev = hdata->dev;
1784     int i, ret;
1785 
1786     DRM_DEV_DEBUG_KMS(dev, "HDMI resource init\n");
1787 
1788     hdata->hpd_gpio = devm_gpiod_get(dev, "hpd", GPIOD_IN);
1789     if (IS_ERR(hdata->hpd_gpio)) {
1790         DRM_DEV_ERROR(dev, "cannot get hpd gpio property\n");
1791         return PTR_ERR(hdata->hpd_gpio);
1792     }
1793 
1794     hdata->irq = gpiod_to_irq(hdata->hpd_gpio);
1795     if (hdata->irq < 0) {
1796         DRM_DEV_ERROR(dev, "failed to get GPIO irq\n");
1797         return  hdata->irq;
1798     }
1799 
1800     ret = hdmi_clk_init(hdata);
1801     if (ret)
1802         return ret;
1803 
1804     ret = hdmi_clk_set_parents(hdata, false);
1805     if (ret)
1806         return ret;
1807 
1808     for (i = 0; i < ARRAY_SIZE(supply); ++i)
1809         hdata->regul_bulk[i].supply = supply[i];
1810 
1811     ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), hdata->regul_bulk);
1812     if (ret)
1813         return dev_err_probe(dev, ret, "failed to get regulators\n");
1814 
1815     hdata->reg_hdmi_en = devm_regulator_get_optional(dev, "hdmi-en");
1816 
1817     if (PTR_ERR(hdata->reg_hdmi_en) != -ENODEV)
1818         if (IS_ERR(hdata->reg_hdmi_en))
1819             return PTR_ERR(hdata->reg_hdmi_en);
1820 
1821     return hdmi_bridge_init(hdata);
1822 }
1823 
1824 static const struct of_device_id hdmi_match_types[] = {
1825     {
1826         .compatible = "samsung,exynos4210-hdmi",
1827         .data = &exynos4210_hdmi_driver_data,
1828     }, {
1829         .compatible = "samsung,exynos4212-hdmi",
1830         .data = &exynos4212_hdmi_driver_data,
1831     }, {
1832         .compatible = "samsung,exynos5420-hdmi",
1833         .data = &exynos5420_hdmi_driver_data,
1834     }, {
1835         .compatible = "samsung,exynos5433-hdmi",
1836         .data = &exynos5433_hdmi_driver_data,
1837     }, {
1838         /* end node */
1839     }
1840 };
1841 MODULE_DEVICE_TABLE (of, hdmi_match_types);
1842 
1843 static int hdmi_bind(struct device *dev, struct device *master, void *data)
1844 {
1845     struct drm_device *drm_dev = data;
1846     struct hdmi_context *hdata = dev_get_drvdata(dev);
1847     struct drm_encoder *encoder = &hdata->encoder;
1848     struct exynos_drm_crtc *crtc;
1849     int ret;
1850 
1851     hdata->drm_dev = drm_dev;
1852 
1853     hdata->phy_clk.enable = hdmiphy_clk_enable;
1854 
1855     drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_TMDS);
1856 
1857     drm_encoder_helper_add(encoder, &exynos_hdmi_encoder_helper_funcs);
1858 
1859     ret = exynos_drm_set_possible_crtcs(encoder, EXYNOS_DISPLAY_TYPE_HDMI);
1860     if (ret < 0)
1861         return ret;
1862 
1863     crtc = exynos_drm_crtc_get_by_type(drm_dev, EXYNOS_DISPLAY_TYPE_HDMI);
1864     crtc->pipe_clk = &hdata->phy_clk;
1865 
1866     ret = hdmi_create_connector(encoder);
1867     if (ret) {
1868         DRM_DEV_ERROR(dev, "failed to create connector ret = %d\n",
1869                   ret);
1870         drm_encoder_cleanup(encoder);
1871         return ret;
1872     }
1873 
1874     return 0;
1875 }
1876 
1877 static void hdmi_unbind(struct device *dev, struct device *master, void *data)
1878 {
1879 }
1880 
1881 static const struct component_ops hdmi_component_ops = {
1882     .bind   = hdmi_bind,
1883     .unbind = hdmi_unbind,
1884 };
1885 
1886 static int hdmi_get_ddc_adapter(struct hdmi_context *hdata)
1887 {
1888     const char *compatible_str = "samsung,exynos4210-hdmiddc";
1889     struct device_node *np;
1890     struct i2c_adapter *adpt;
1891 
1892     np = of_find_compatible_node(NULL, NULL, compatible_str);
1893     if (np)
1894         np = of_get_next_parent(np);
1895     else
1896         np = of_parse_phandle(hdata->dev->of_node, "ddc", 0);
1897 
1898     if (!np) {
1899         DRM_DEV_ERROR(hdata->dev,
1900                   "Failed to find ddc node in device tree\n");
1901         return -ENODEV;
1902     }
1903 
1904     adpt = of_find_i2c_adapter_by_node(np);
1905     of_node_put(np);
1906 
1907     if (!adpt) {
1908         DRM_INFO("Failed to get ddc i2c adapter by node\n");
1909         return -EPROBE_DEFER;
1910     }
1911 
1912     hdata->ddc_adpt = adpt;
1913 
1914     return 0;
1915 }
1916 
1917 static int hdmi_get_phy_io(struct hdmi_context *hdata)
1918 {
1919     const char *compatible_str = "samsung,exynos4212-hdmiphy";
1920     struct device_node *np;
1921     int ret = 0;
1922 
1923     np = of_find_compatible_node(NULL, NULL, compatible_str);
1924     if (!np) {
1925         np = of_parse_phandle(hdata->dev->of_node, "phy", 0);
1926         if (!np) {
1927             DRM_DEV_ERROR(hdata->dev,
1928                       "Failed to find hdmiphy node in device tree\n");
1929             return -ENODEV;
1930         }
1931     }
1932 
1933     if (hdata->drv_data->is_apb_phy) {
1934         hdata->regs_hdmiphy = of_iomap(np, 0);
1935         if (!hdata->regs_hdmiphy) {
1936             DRM_DEV_ERROR(hdata->dev,
1937                       "failed to ioremap hdmi phy\n");
1938             ret = -ENOMEM;
1939             goto out;
1940         }
1941     } else {
1942         hdata->hdmiphy_port = of_find_i2c_device_by_node(np);
1943         if (!hdata->hdmiphy_port) {
1944             DRM_INFO("Failed to get hdmi phy i2c client\n");
1945             ret = -EPROBE_DEFER;
1946             goto out;
1947         }
1948     }
1949 
1950 out:
1951     of_node_put(np);
1952     return ret;
1953 }
1954 
1955 static int hdmi_probe(struct platform_device *pdev)
1956 {
1957     struct hdmi_audio_infoframe *audio_infoframe;
1958     struct device *dev = &pdev->dev;
1959     struct hdmi_context *hdata;
1960     int ret;
1961 
1962     hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);
1963     if (!hdata)
1964         return -ENOMEM;
1965 
1966     hdata->drv_data = of_device_get_match_data(dev);
1967 
1968     platform_set_drvdata(pdev, hdata);
1969 
1970     hdata->dev = dev;
1971 
1972     mutex_init(&hdata->mutex);
1973 
1974     ret = hdmi_resources_init(hdata);
1975     if (ret) {
1976         if (ret != -EPROBE_DEFER)
1977             DRM_DEV_ERROR(dev, "hdmi_resources_init failed\n");
1978         return ret;
1979     }
1980 
1981     hdata->regs = devm_platform_ioremap_resource(pdev, 0);
1982     if (IS_ERR(hdata->regs)) {
1983         ret = PTR_ERR(hdata->regs);
1984         return ret;
1985     }
1986 
1987     ret = hdmi_get_ddc_adapter(hdata);
1988     if (ret)
1989         return ret;
1990 
1991     ret = hdmi_get_phy_io(hdata);
1992     if (ret)
1993         goto err_ddc;
1994 
1995     INIT_DELAYED_WORK(&hdata->hotplug_work, hdmi_hotplug_work_func);
1996 
1997     ret = devm_request_threaded_irq(dev, hdata->irq, NULL,
1998             hdmi_irq_thread, IRQF_TRIGGER_RISING |
1999             IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
2000             "hdmi", hdata);
2001     if (ret) {
2002         DRM_DEV_ERROR(dev, "failed to register hdmi interrupt\n");
2003         goto err_hdmiphy;
2004     }
2005 
2006     hdata->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
2007             "samsung,syscon-phandle");
2008     if (IS_ERR(hdata->pmureg)) {
2009         DRM_DEV_ERROR(dev, "syscon regmap lookup failed.\n");
2010         ret = -EPROBE_DEFER;
2011         goto err_hdmiphy;
2012     }
2013 
2014     if (hdata->drv_data->has_sysreg) {
2015         hdata->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
2016                 "samsung,sysreg-phandle");
2017         if (IS_ERR(hdata->sysreg)) {
2018             DRM_DEV_ERROR(dev, "sysreg regmap lookup failed.\n");
2019             ret = -EPROBE_DEFER;
2020             goto err_hdmiphy;
2021         }
2022     }
2023 
2024     if (!IS_ERR(hdata->reg_hdmi_en)) {
2025         ret = regulator_enable(hdata->reg_hdmi_en);
2026         if (ret) {
2027             DRM_DEV_ERROR(dev,
2028                   "failed to enable hdmi-en regulator\n");
2029             goto err_hdmiphy;
2030         }
2031     }
2032 
2033     pm_runtime_enable(dev);
2034 
2035     audio_infoframe = &hdata->audio.infoframe;
2036     hdmi_audio_infoframe_init(audio_infoframe);
2037     audio_infoframe->coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
2038     audio_infoframe->sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
2039     audio_infoframe->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
2040     audio_infoframe->channels = 2;
2041 
2042     ret = hdmi_register_audio_device(hdata);
2043     if (ret)
2044         goto err_rpm_disable;
2045 
2046     ret = component_add(&pdev->dev, &hdmi_component_ops);
2047     if (ret)
2048         goto err_unregister_audio;
2049 
2050     return ret;
2051 
2052 err_unregister_audio:
2053     platform_device_unregister(hdata->audio.pdev);
2054 
2055 err_rpm_disable:
2056     pm_runtime_disable(dev);
2057     if (!IS_ERR(hdata->reg_hdmi_en))
2058         regulator_disable(hdata->reg_hdmi_en);
2059 err_hdmiphy:
2060     if (hdata->hdmiphy_port)
2061         put_device(&hdata->hdmiphy_port->dev);
2062     if (hdata->regs_hdmiphy)
2063         iounmap(hdata->regs_hdmiphy);
2064 err_ddc:
2065     put_device(&hdata->ddc_adpt->dev);
2066 
2067     return ret;
2068 }
2069 
2070 static int hdmi_remove(struct platform_device *pdev)
2071 {
2072     struct hdmi_context *hdata = platform_get_drvdata(pdev);
2073 
2074     cancel_delayed_work_sync(&hdata->hotplug_work);
2075 
2076     component_del(&pdev->dev, &hdmi_component_ops);
2077     platform_device_unregister(hdata->audio.pdev);
2078 
2079     pm_runtime_disable(&pdev->dev);
2080 
2081     if (!IS_ERR(hdata->reg_hdmi_en))
2082         regulator_disable(hdata->reg_hdmi_en);
2083 
2084     if (hdata->hdmiphy_port)
2085         put_device(&hdata->hdmiphy_port->dev);
2086 
2087     if (hdata->regs_hdmiphy)
2088         iounmap(hdata->regs_hdmiphy);
2089 
2090     put_device(&hdata->ddc_adpt->dev);
2091 
2092     mutex_destroy(&hdata->mutex);
2093 
2094     return 0;
2095 }
2096 
2097 static int __maybe_unused exynos_hdmi_suspend(struct device *dev)
2098 {
2099     struct hdmi_context *hdata = dev_get_drvdata(dev);
2100 
2101     hdmi_clk_disable_gates(hdata);
2102 
2103     return 0;
2104 }
2105 
2106 static int __maybe_unused exynos_hdmi_resume(struct device *dev)
2107 {
2108     struct hdmi_context *hdata = dev_get_drvdata(dev);
2109     int ret;
2110 
2111     ret = hdmi_clk_enable_gates(hdata);
2112     if (ret < 0)
2113         return ret;
2114 
2115     return 0;
2116 }
2117 
2118 static const struct dev_pm_ops exynos_hdmi_pm_ops = {
2119     SET_RUNTIME_PM_OPS(exynos_hdmi_suspend, exynos_hdmi_resume, NULL)
2120     SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
2121                 pm_runtime_force_resume)
2122 };
2123 
2124 struct platform_driver hdmi_driver = {
2125     .probe      = hdmi_probe,
2126     .remove     = hdmi_remove,
2127     .driver     = {
2128         .name   = "exynos-hdmi",
2129         .owner  = THIS_MODULE,
2130         .pm = &exynos_hdmi_pm_ops,
2131         .of_match_table = hdmi_match_types,
2132     },
2133 };