Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) STMicroelectronics SA 2014
0004  * Author: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics.
0005  */
0006 
0007 #include <linux/clk.h>
0008 #include <linux/component.h>
0009 #include <linux/io.h>
0010 #include <linux/mod_devicetable.h>
0011 #include <linux/module.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/seq_file.h>
0014 
0015 #include <drm/drm_atomic_helper.h>
0016 #include <drm/drm_bridge.h>
0017 #include <drm/drm_debugfs.h>
0018 #include <drm/drm_device.h>
0019 #include <drm/drm_file.h>
0020 #include <drm/drm_print.h>
0021 #include <drm/drm_probe_helper.h>
0022 
0023 /* HDformatter registers */
0024 #define HDA_ANA_CFG                     0x0000
0025 #define HDA_ANA_SCALE_CTRL_Y            0x0004
0026 #define HDA_ANA_SCALE_CTRL_CB           0x0008
0027 #define HDA_ANA_SCALE_CTRL_CR           0x000C
0028 #define HDA_ANA_ANC_CTRL                0x0010
0029 #define HDA_ANA_SRC_Y_CFG               0x0014
0030 #define HDA_COEFF_Y_PH1_TAP123          0x0018
0031 #define HDA_COEFF_Y_PH1_TAP456          0x001C
0032 #define HDA_COEFF_Y_PH2_TAP123          0x0020
0033 #define HDA_COEFF_Y_PH2_TAP456          0x0024
0034 #define HDA_COEFF_Y_PH3_TAP123          0x0028
0035 #define HDA_COEFF_Y_PH3_TAP456          0x002C
0036 #define HDA_COEFF_Y_PH4_TAP123          0x0030
0037 #define HDA_COEFF_Y_PH4_TAP456          0x0034
0038 #define HDA_ANA_SRC_C_CFG               0x0040
0039 #define HDA_COEFF_C_PH1_TAP123          0x0044
0040 #define HDA_COEFF_C_PH1_TAP456          0x0048
0041 #define HDA_COEFF_C_PH2_TAP123          0x004C
0042 #define HDA_COEFF_C_PH2_TAP456          0x0050
0043 #define HDA_COEFF_C_PH3_TAP123          0x0054
0044 #define HDA_COEFF_C_PH3_TAP456          0x0058
0045 #define HDA_COEFF_C_PH4_TAP123          0x005C
0046 #define HDA_COEFF_C_PH4_TAP456          0x0060
0047 #define HDA_SYNC_AWGI                   0x0300
0048 
0049 /* HDA_ANA_CFG */
0050 #define CFG_AWG_ASYNC_EN                BIT(0)
0051 #define CFG_AWG_ASYNC_HSYNC_MTD         BIT(1)
0052 #define CFG_AWG_ASYNC_VSYNC_MTD         BIT(2)
0053 #define CFG_AWG_SYNC_DEL                BIT(3)
0054 #define CFG_AWG_FLTR_MODE_SHIFT         4
0055 #define CFG_AWG_FLTR_MODE_MASK          (0xF << CFG_AWG_FLTR_MODE_SHIFT)
0056 #define CFG_AWG_FLTR_MODE_SD            (0 << CFG_AWG_FLTR_MODE_SHIFT)
0057 #define CFG_AWG_FLTR_MODE_ED            (1 << CFG_AWG_FLTR_MODE_SHIFT)
0058 #define CFG_AWG_FLTR_MODE_HD            (2 << CFG_AWG_FLTR_MODE_SHIFT)
0059 #define CFG_SYNC_ON_PBPR_MASK           BIT(8)
0060 #define CFG_PREFILTER_EN_MASK           BIT(9)
0061 #define CFG_PBPR_SYNC_OFF_SHIFT         16
0062 #define CFG_PBPR_SYNC_OFF_MASK          (0x7FF << CFG_PBPR_SYNC_OFF_SHIFT)
0063 #define CFG_PBPR_SYNC_OFF_VAL           0x117 /* Voltage dependent. stiH416 */
0064 
0065 /* Default scaling values */
0066 #define SCALE_CTRL_Y_DFLT               0x00C50256
0067 #define SCALE_CTRL_CB_DFLT              0x00DB0249
0068 #define SCALE_CTRL_CR_DFLT              0x00DB0249
0069 
0070 /* Video DACs control */
0071 #define DAC_CFG_HD_HZUVW_OFF_MASK       BIT(1)
0072 
0073 /* Upsampler values for the alternative 2X Filter */
0074 #define SAMPLER_COEF_NB                 8
0075 #define HDA_ANA_SRC_Y_CFG_ALT_2X        0x01130000
0076 static u32 coef_y_alt_2x[] = {
0077     0x00FE83FB, 0x1F900401, 0x00000000, 0x00000000,
0078     0x00F408F9, 0x055F7C25, 0x00000000, 0x00000000
0079 };
0080 
0081 #define HDA_ANA_SRC_C_CFG_ALT_2X        0x01750004
0082 static u32 coef_c_alt_2x[] = {
0083     0x001305F7, 0x05274BD0, 0x00000000, 0x00000000,
0084     0x0004907C, 0x09C80B9D, 0x00000000, 0x00000000
0085 };
0086 
0087 /* Upsampler values for the 4X Filter */
0088 #define HDA_ANA_SRC_Y_CFG_4X            0x01ED0005
0089 #define HDA_ANA_SRC_C_CFG_4X            0x01ED0004
0090 static u32 coef_yc_4x[] = {
0091     0x00FC827F, 0x008FE20B, 0x00F684FC, 0x050F7C24,
0092     0x00F4857C, 0x0A1F402E, 0x00FA027F, 0x0E076E1D
0093 };
0094 
0095 /* AWG instructions for some video modes */
0096 #define AWG_MAX_INST                    64
0097 
0098 /* 720p@50 */
0099 static u32 AWGi_720p_50[] = {
0100     0x00000971, 0x00000C26, 0x0000013B, 0x00000CDA,
0101     0x00000104, 0x00000E7E, 0x00000E7F, 0x0000013B,
0102     0x00000D8E, 0x00000104, 0x00001804, 0x00000971,
0103     0x00000C26, 0x0000003B, 0x00000FB4, 0x00000FB5,
0104     0x00000104, 0x00001AE8
0105 };
0106 
0107 #define NN_720p_50 ARRAY_SIZE(AWGi_720p_50)
0108 
0109 /* 720p@60 */
0110 static u32 AWGi_720p_60[] = {
0111     0x00000971, 0x00000C26, 0x0000013B, 0x00000CDA,
0112     0x00000104, 0x00000E7E, 0x00000E7F, 0x0000013B,
0113     0x00000C44, 0x00000104, 0x00001804, 0x00000971,
0114     0x00000C26, 0x0000003B, 0x00000F0F, 0x00000F10,
0115     0x00000104, 0x00001AE8
0116 };
0117 
0118 #define NN_720p_60 ARRAY_SIZE(AWGi_720p_60)
0119 
0120 /* 1080p@30 */
0121 static u32 AWGi_1080p_30[] = {
0122     0x00000971, 0x00000C2A, 0x0000013B, 0x00000C56,
0123     0x00000104, 0x00000FDC, 0x00000FDD, 0x0000013B,
0124     0x00000C2A, 0x00000104, 0x00001804, 0x00000971,
0125     0x00000C2A, 0x0000003B, 0x00000EBE, 0x00000EBF,
0126     0x00000EBF, 0x00000104, 0x00001A2F, 0x00001C4B,
0127     0x00001C52
0128 };
0129 
0130 #define NN_1080p_30 ARRAY_SIZE(AWGi_1080p_30)
0131 
0132 /* 1080p@25 */
0133 static u32 AWGi_1080p_25[] = {
0134     0x00000971, 0x00000C2A, 0x0000013B, 0x00000C56,
0135     0x00000104, 0x00000FDC, 0x00000FDD, 0x0000013B,
0136     0x00000DE2, 0x00000104, 0x00001804, 0x00000971,
0137     0x00000C2A, 0x0000003B, 0x00000F51, 0x00000F51,
0138     0x00000F52, 0x00000104, 0x00001A2F, 0x00001C4B,
0139     0x00001C52
0140 };
0141 
0142 #define NN_1080p_25 ARRAY_SIZE(AWGi_1080p_25)
0143 
0144 /* 1080p@24 */
0145 static u32 AWGi_1080p_24[] = {
0146     0x00000971, 0x00000C2A, 0x0000013B, 0x00000C56,
0147     0x00000104, 0x00000FDC, 0x00000FDD, 0x0000013B,
0148     0x00000E50, 0x00000104, 0x00001804, 0x00000971,
0149     0x00000C2A, 0x0000003B, 0x00000F76, 0x00000F76,
0150     0x00000F76, 0x00000104, 0x00001A2F, 0x00001C4B,
0151     0x00001C52
0152 };
0153 
0154 #define NN_1080p_24 ARRAY_SIZE(AWGi_1080p_24)
0155 
0156 /* 720x480p@60 */
0157 static u32 AWGi_720x480p_60[] = {
0158     0x00000904, 0x00000F18, 0x0000013B, 0x00001805,
0159     0x00000904, 0x00000C3D, 0x0000003B, 0x00001A06
0160 };
0161 
0162 #define NN_720x480p_60 ARRAY_SIZE(AWGi_720x480p_60)
0163 
0164 /* Video mode category */
0165 enum sti_hda_vid_cat {
0166     VID_SD,
0167     VID_ED,
0168     VID_HD_74M,
0169     VID_HD_148M
0170 };
0171 
0172 struct sti_hda_video_config {
0173     struct drm_display_mode mode;
0174     u32 *awg_instr;
0175     int nb_instr;
0176     enum sti_hda_vid_cat vid_cat;
0177 };
0178 
0179 /* HD analog supported modes
0180  * Interlaced modes may be added when supported by the whole display chain
0181  */
0182 static const struct sti_hda_video_config hda_supported_modes[] = {
0183     /* 1080p30 74.250Mhz */
0184     {{DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
0185            2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
0186            DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)},
0187      AWGi_1080p_30, NN_1080p_30, VID_HD_74M},
0188     /* 1080p30 74.176Mhz */
0189     {{DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74176, 1920, 2008,
0190            2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
0191            DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)},
0192      AWGi_1080p_30, NN_1080p_30, VID_HD_74M},
0193     /* 1080p24 74.250Mhz */
0194     {{DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2558,
0195            2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
0196            DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)},
0197      AWGi_1080p_24, NN_1080p_24, VID_HD_74M},
0198     /* 1080p24 74.176Mhz */
0199     {{DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74176, 1920, 2558,
0200            2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
0201            DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)},
0202      AWGi_1080p_24, NN_1080p_24, VID_HD_74M},
0203     /* 1080p25 74.250Mhz */
0204     {{DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
0205            2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
0206            DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)},
0207      AWGi_1080p_25, NN_1080p_25, VID_HD_74M},
0208     /* 720p60 74.250Mhz */
0209     {{DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
0210            1430, 1650, 0, 720, 725, 730, 750, 0,
0211            DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)},
0212      AWGi_720p_60, NN_720p_60, VID_HD_74M},
0213     /* 720p60 74.176Mhz */
0214     {{DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74176, 1280, 1390,
0215            1430, 1650, 0, 720, 725, 730, 750, 0,
0216            DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)},
0217      AWGi_720p_60, NN_720p_60, VID_HD_74M},
0218     /* 720p50 74.250Mhz */
0219     {{DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1720,
0220            1760, 1980, 0, 720, 725, 730, 750, 0,
0221            DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)},
0222      AWGi_720p_50, NN_720p_50, VID_HD_74M},
0223     /* 720x480p60 27.027Mhz */
0224     {{DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27027, 720, 736,
0225            798, 858, 0, 480, 489, 495, 525, 0,
0226            DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
0227      AWGi_720x480p_60, NN_720x480p_60, VID_ED},
0228     /* 720x480p60 27.000Mhz */
0229     {{DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,
0230            798, 858, 0, 480, 489, 495, 525, 0,
0231            DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
0232      AWGi_720x480p_60, NN_720x480p_60, VID_ED}
0233 };
0234 
0235 /*
0236  * STI hd analog structure
0237  *
0238  * @dev: driver device
0239  * @drm_dev: pointer to drm device
0240  * @mode: current display mode selected
0241  * @regs: HD analog register
0242  * @video_dacs_ctrl: video DACS control register
0243  * @enabled: true if HD analog is enabled else false
0244  */
0245 struct sti_hda {
0246     struct device dev;
0247     struct drm_device *drm_dev;
0248     struct drm_display_mode mode;
0249     void __iomem *regs;
0250     void __iomem *video_dacs_ctrl;
0251     struct clk *clk_pix;
0252     struct clk *clk_hddac;
0253     bool enabled;
0254 };
0255 
0256 struct sti_hda_connector {
0257     struct drm_connector drm_connector;
0258     struct drm_encoder *encoder;
0259     struct sti_hda *hda;
0260 };
0261 
0262 #define to_sti_hda_connector(x) \
0263     container_of(x, struct sti_hda_connector, drm_connector)
0264 
0265 static u32 hda_read(struct sti_hda *hda, int offset)
0266 {
0267     return readl(hda->regs + offset);
0268 }
0269 
0270 static void hda_write(struct sti_hda *hda, u32 val, int offset)
0271 {
0272     writel(val, hda->regs + offset);
0273 }
0274 
0275 /**
0276  * hda_get_mode_idx - Search for a video mode in the supported modes table
0277  *
0278  * @mode: mode being searched
0279  * @idx: index of the found mode
0280  *
0281  * Return true if mode is found
0282  */
0283 static bool hda_get_mode_idx(struct drm_display_mode mode, int *idx)
0284 {
0285     unsigned int i;
0286 
0287     for (i = 0; i < ARRAY_SIZE(hda_supported_modes); i++)
0288         if (drm_mode_equal(&hda_supported_modes[i].mode, &mode)) {
0289             *idx = i;
0290             return true;
0291         }
0292     return false;
0293 }
0294 
0295 /**
0296  * hda_enable_hd_dacs - Enable the HD DACS
0297  *
0298  * @hda: pointer to HD analog structure
0299  * @enable: true if HD DACS need to be enabled, else false
0300  */
0301 static void hda_enable_hd_dacs(struct sti_hda *hda, bool enable)
0302 {
0303     if (hda->video_dacs_ctrl) {
0304         u32 val;
0305 
0306         val = readl(hda->video_dacs_ctrl);
0307         if (enable)
0308             val &= ~DAC_CFG_HD_HZUVW_OFF_MASK;
0309         else
0310             val |= DAC_CFG_HD_HZUVW_OFF_MASK;
0311 
0312         writel(val, hda->video_dacs_ctrl);
0313     }
0314 }
0315 
0316 #define DBGFS_DUMP(reg) seq_printf(s, "\n  %-25s 0x%08X", #reg, \
0317                    readl(hda->regs + reg))
0318 
0319 static void hda_dbg_cfg(struct seq_file *s, int val)
0320 {
0321     seq_puts(s, "\tAWG ");
0322     seq_puts(s, val & CFG_AWG_ASYNC_EN ? "enabled" : "disabled");
0323 }
0324 
0325 static void hda_dbg_awg_microcode(struct seq_file *s, void __iomem *reg)
0326 {
0327     unsigned int i;
0328 
0329     seq_puts(s, "\n\n  HDA AWG microcode:");
0330     for (i = 0; i < AWG_MAX_INST; i++) {
0331         if (i % 8 == 0)
0332             seq_printf(s, "\n  %04X:", i);
0333         seq_printf(s, " %04X", readl(reg + i * 4));
0334     }
0335 }
0336 
0337 static void hda_dbg_video_dacs_ctrl(struct seq_file *s, void __iomem *reg)
0338 {
0339     u32 val = readl(reg);
0340 
0341     seq_printf(s, "\n\n  %-25s 0x%08X", "VIDEO_DACS_CONTROL", val);
0342     seq_puts(s, "\tHD DACs ");
0343     seq_puts(s, val & DAC_CFG_HD_HZUVW_OFF_MASK ? "disabled" : "enabled");
0344 }
0345 
0346 static int hda_dbg_show(struct seq_file *s, void *data)
0347 {
0348     struct drm_info_node *node = s->private;
0349     struct sti_hda *hda = (struct sti_hda *)node->info_ent->data;
0350 
0351     seq_printf(s, "HD Analog: (vaddr = 0x%p)", hda->regs);
0352     DBGFS_DUMP(HDA_ANA_CFG);
0353     hda_dbg_cfg(s, readl(hda->regs + HDA_ANA_CFG));
0354     DBGFS_DUMP(HDA_ANA_SCALE_CTRL_Y);
0355     DBGFS_DUMP(HDA_ANA_SCALE_CTRL_CB);
0356     DBGFS_DUMP(HDA_ANA_SCALE_CTRL_CR);
0357     DBGFS_DUMP(HDA_ANA_ANC_CTRL);
0358     DBGFS_DUMP(HDA_ANA_SRC_Y_CFG);
0359     DBGFS_DUMP(HDA_ANA_SRC_C_CFG);
0360     hda_dbg_awg_microcode(s, hda->regs + HDA_SYNC_AWGI);
0361     if (hda->video_dacs_ctrl)
0362         hda_dbg_video_dacs_ctrl(s, hda->video_dacs_ctrl);
0363     seq_putc(s, '\n');
0364     return 0;
0365 }
0366 
0367 static struct drm_info_list hda_debugfs_files[] = {
0368     { "hda", hda_dbg_show, 0, NULL },
0369 };
0370 
0371 static void hda_debugfs_init(struct sti_hda *hda, struct drm_minor *minor)
0372 {
0373     unsigned int i;
0374 
0375     for (i = 0; i < ARRAY_SIZE(hda_debugfs_files); i++)
0376         hda_debugfs_files[i].data = hda;
0377 
0378     drm_debugfs_create_files(hda_debugfs_files,
0379                  ARRAY_SIZE(hda_debugfs_files),
0380                  minor->debugfs_root, minor);
0381 }
0382 
0383 /**
0384  * sti_hda_configure_awg - Configure AWG, writing instructions
0385  *
0386  * @hda: pointer to HD analog structure
0387  * @awg_instr: pointer to AWG instructions table
0388  * @nb: nb of AWG instructions
0389  */
0390 static void sti_hda_configure_awg(struct sti_hda *hda, u32 *awg_instr, int nb)
0391 {
0392     unsigned int i;
0393 
0394     DRM_DEBUG_DRIVER("\n");
0395 
0396     for (i = 0; i < nb; i++)
0397         hda_write(hda, awg_instr[i], HDA_SYNC_AWGI + i * 4);
0398     for (i = nb; i < AWG_MAX_INST; i++)
0399         hda_write(hda, 0, HDA_SYNC_AWGI + i * 4);
0400 }
0401 
0402 static void sti_hda_disable(struct drm_bridge *bridge)
0403 {
0404     struct sti_hda *hda = bridge->driver_private;
0405     u32 val;
0406 
0407     if (!hda->enabled)
0408         return;
0409 
0410     DRM_DEBUG_DRIVER("\n");
0411 
0412     /* Disable HD DAC and AWG */
0413     val = hda_read(hda, HDA_ANA_CFG);
0414     val &= ~CFG_AWG_ASYNC_EN;
0415     hda_write(hda, val, HDA_ANA_CFG);
0416     hda_write(hda, 0, HDA_ANA_ANC_CTRL);
0417 
0418     hda_enable_hd_dacs(hda, false);
0419 
0420     /* Disable/unprepare hda clock */
0421     clk_disable_unprepare(hda->clk_hddac);
0422     clk_disable_unprepare(hda->clk_pix);
0423 
0424     hda->enabled = false;
0425 }
0426 
0427 static void sti_hda_pre_enable(struct drm_bridge *bridge)
0428 {
0429     struct sti_hda *hda = bridge->driver_private;
0430     u32 val, i, mode_idx;
0431     u32 src_filter_y, src_filter_c;
0432     u32 *coef_y, *coef_c;
0433     u32 filter_mode;
0434 
0435     DRM_DEBUG_DRIVER("\n");
0436 
0437     if (hda->enabled)
0438         return;
0439 
0440     /* Prepare/enable clocks */
0441     if (clk_prepare_enable(hda->clk_pix))
0442         DRM_ERROR("Failed to prepare/enable hda_pix clk\n");
0443     if (clk_prepare_enable(hda->clk_hddac))
0444         DRM_ERROR("Failed to prepare/enable hda_hddac clk\n");
0445 
0446     if (!hda_get_mode_idx(hda->mode, &mode_idx)) {
0447         DRM_ERROR("Undefined mode\n");
0448         return;
0449     }
0450 
0451     switch (hda_supported_modes[mode_idx].vid_cat) {
0452     case VID_HD_148M:
0453         DRM_ERROR("Beyond HD analog capabilities\n");
0454         return;
0455     case VID_HD_74M:
0456         /* HD use alternate 2x filter */
0457         filter_mode = CFG_AWG_FLTR_MODE_HD;
0458         src_filter_y = HDA_ANA_SRC_Y_CFG_ALT_2X;
0459         src_filter_c = HDA_ANA_SRC_C_CFG_ALT_2X;
0460         coef_y = coef_y_alt_2x;
0461         coef_c = coef_c_alt_2x;
0462         break;
0463     case VID_ED:
0464         /* ED uses 4x filter */
0465         filter_mode = CFG_AWG_FLTR_MODE_ED;
0466         src_filter_y = HDA_ANA_SRC_Y_CFG_4X;
0467         src_filter_c = HDA_ANA_SRC_C_CFG_4X;
0468         coef_y = coef_yc_4x;
0469         coef_c = coef_yc_4x;
0470         break;
0471     case VID_SD:
0472         DRM_ERROR("Not supported\n");
0473         return;
0474     default:
0475         DRM_ERROR("Undefined resolution\n");
0476         return;
0477     }
0478     DRM_DEBUG_DRIVER("Using HDA mode #%d\n", mode_idx);
0479 
0480     /* Enable HD Video DACs */
0481     hda_enable_hd_dacs(hda, true);
0482 
0483     /* Configure scaler */
0484     hda_write(hda, SCALE_CTRL_Y_DFLT, HDA_ANA_SCALE_CTRL_Y);
0485     hda_write(hda, SCALE_CTRL_CB_DFLT, HDA_ANA_SCALE_CTRL_CB);
0486     hda_write(hda, SCALE_CTRL_CR_DFLT, HDA_ANA_SCALE_CTRL_CR);
0487 
0488     /* Configure sampler */
0489     hda_write(hda , src_filter_y, HDA_ANA_SRC_Y_CFG);
0490     hda_write(hda, src_filter_c,  HDA_ANA_SRC_C_CFG);
0491     for (i = 0; i < SAMPLER_COEF_NB; i++) {
0492         hda_write(hda, coef_y[i], HDA_COEFF_Y_PH1_TAP123 + i * 4);
0493         hda_write(hda, coef_c[i], HDA_COEFF_C_PH1_TAP123 + i * 4);
0494     }
0495 
0496     /* Configure main HDFormatter */
0497     val = 0;
0498     val |= (hda->mode.flags & DRM_MODE_FLAG_INTERLACE) ?
0499         0 : CFG_AWG_ASYNC_VSYNC_MTD;
0500     val |= (CFG_PBPR_SYNC_OFF_VAL << CFG_PBPR_SYNC_OFF_SHIFT);
0501     val |= filter_mode;
0502     hda_write(hda, val, HDA_ANA_CFG);
0503 
0504     /* Configure AWG */
0505     sti_hda_configure_awg(hda, hda_supported_modes[mode_idx].awg_instr,
0506                   hda_supported_modes[mode_idx].nb_instr);
0507 
0508     /* Enable AWG */
0509     val = hda_read(hda, HDA_ANA_CFG);
0510     val |= CFG_AWG_ASYNC_EN;
0511     hda_write(hda, val, HDA_ANA_CFG);
0512 
0513     hda->enabled = true;
0514 }
0515 
0516 static void sti_hda_set_mode(struct drm_bridge *bridge,
0517                  const struct drm_display_mode *mode,
0518                  const struct drm_display_mode *adjusted_mode)
0519 {
0520     struct sti_hda *hda = bridge->driver_private;
0521     u32 mode_idx;
0522     int hddac_rate;
0523     int ret;
0524 
0525     DRM_DEBUG_DRIVER("\n");
0526 
0527     memcpy(&hda->mode, mode, sizeof(struct drm_display_mode));
0528 
0529     if (!hda_get_mode_idx(hda->mode, &mode_idx)) {
0530         DRM_ERROR("Undefined mode\n");
0531         return;
0532     }
0533 
0534     switch (hda_supported_modes[mode_idx].vid_cat) {
0535     case VID_HD_74M:
0536         /* HD use alternate 2x filter */
0537         hddac_rate = mode->clock * 1000 * 2;
0538         break;
0539     case VID_ED:
0540         /* ED uses 4x filter */
0541         hddac_rate = mode->clock * 1000 * 4;
0542         break;
0543     default:
0544         DRM_ERROR("Undefined mode\n");
0545         return;
0546     }
0547 
0548     /* HD DAC = 148.5Mhz or 108 Mhz */
0549     ret = clk_set_rate(hda->clk_hddac, hddac_rate);
0550     if (ret < 0)
0551         DRM_ERROR("Cannot set rate (%dHz) for hda_hddac clk\n",
0552               hddac_rate);
0553 
0554     /* HDformatter clock = compositor clock */
0555     ret = clk_set_rate(hda->clk_pix, mode->clock * 1000);
0556     if (ret < 0)
0557         DRM_ERROR("Cannot set rate (%dHz) for hda_pix clk\n",
0558               mode->clock * 1000);
0559 }
0560 
0561 static void sti_hda_bridge_nope(struct drm_bridge *bridge)
0562 {
0563     /* do nothing */
0564 }
0565 
0566 static const struct drm_bridge_funcs sti_hda_bridge_funcs = {
0567     .pre_enable = sti_hda_pre_enable,
0568     .enable = sti_hda_bridge_nope,
0569     .disable = sti_hda_disable,
0570     .post_disable = sti_hda_bridge_nope,
0571     .mode_set = sti_hda_set_mode,
0572 };
0573 
0574 static int sti_hda_connector_get_modes(struct drm_connector *connector)
0575 {
0576     unsigned int i;
0577     int count = 0;
0578     struct sti_hda_connector *hda_connector
0579         = to_sti_hda_connector(connector);
0580     struct sti_hda *hda = hda_connector->hda;
0581 
0582     DRM_DEBUG_DRIVER("\n");
0583 
0584     for (i = 0; i < ARRAY_SIZE(hda_supported_modes); i++) {
0585         struct drm_display_mode *mode =
0586             drm_mode_duplicate(hda->drm_dev,
0587                     &hda_supported_modes[i].mode);
0588         if (!mode)
0589             continue;
0590 
0591         /* the first mode is the preferred mode */
0592         if (i == 0)
0593             mode->type |= DRM_MODE_TYPE_PREFERRED;
0594 
0595         drm_mode_probed_add(connector, mode);
0596         count++;
0597     }
0598 
0599     return count;
0600 }
0601 
0602 #define CLK_TOLERANCE_HZ 50
0603 
0604 static int sti_hda_connector_mode_valid(struct drm_connector *connector,
0605                     struct drm_display_mode *mode)
0606 {
0607     int target = mode->clock * 1000;
0608     int target_min = target - CLK_TOLERANCE_HZ;
0609     int target_max = target + CLK_TOLERANCE_HZ;
0610     int result;
0611     int idx;
0612     struct sti_hda_connector *hda_connector
0613         = to_sti_hda_connector(connector);
0614     struct sti_hda *hda = hda_connector->hda;
0615 
0616     if (!hda_get_mode_idx(*mode, &idx)) {
0617         return MODE_BAD;
0618     } else {
0619         result = clk_round_rate(hda->clk_pix, target);
0620 
0621         DRM_DEBUG_DRIVER("target rate = %d => available rate = %d\n",
0622                  target, result);
0623 
0624         if ((result < target_min) || (result > target_max)) {
0625             DRM_DEBUG_DRIVER("hda pixclk=%d not supported\n",
0626                      target);
0627             return MODE_BAD;
0628         }
0629     }
0630 
0631     return MODE_OK;
0632 }
0633 
0634 static const
0635 struct drm_connector_helper_funcs sti_hda_connector_helper_funcs = {
0636     .get_modes = sti_hda_connector_get_modes,
0637     .mode_valid = sti_hda_connector_mode_valid,
0638 };
0639 
0640 static int sti_hda_late_register(struct drm_connector *connector)
0641 {
0642     struct sti_hda_connector *hda_connector
0643         = to_sti_hda_connector(connector);
0644     struct sti_hda *hda = hda_connector->hda;
0645 
0646     hda_debugfs_init(hda, hda->drm_dev->primary);
0647 
0648     return 0;
0649 }
0650 
0651 static const struct drm_connector_funcs sti_hda_connector_funcs = {
0652     .fill_modes = drm_helper_probe_single_connector_modes,
0653     .destroy = drm_connector_cleanup,
0654     .reset = drm_atomic_helper_connector_reset,
0655     .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
0656     .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
0657     .late_register = sti_hda_late_register,
0658 };
0659 
0660 static struct drm_encoder *sti_hda_find_encoder(struct drm_device *dev)
0661 {
0662     struct drm_encoder *encoder;
0663 
0664     list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
0665         if (encoder->encoder_type == DRM_MODE_ENCODER_DAC)
0666             return encoder;
0667     }
0668 
0669     return NULL;
0670 }
0671 
0672 static int sti_hda_bind(struct device *dev, struct device *master, void *data)
0673 {
0674     struct sti_hda *hda = dev_get_drvdata(dev);
0675     struct drm_device *drm_dev = data;
0676     struct drm_encoder *encoder;
0677     struct sti_hda_connector *connector;
0678     struct drm_connector *drm_connector;
0679     struct drm_bridge *bridge;
0680     int err;
0681 
0682     /* Set the drm device handle */
0683     hda->drm_dev = drm_dev;
0684 
0685     encoder = sti_hda_find_encoder(drm_dev);
0686     if (!encoder)
0687         return -ENOMEM;
0688 
0689     connector = devm_kzalloc(dev, sizeof(*connector), GFP_KERNEL);
0690     if (!connector)
0691         return -ENOMEM;
0692 
0693     connector->hda = hda;
0694 
0695         bridge = devm_kzalloc(dev, sizeof(*bridge), GFP_KERNEL);
0696     if (!bridge)
0697         return -ENOMEM;
0698 
0699     bridge->driver_private = hda;
0700     bridge->funcs = &sti_hda_bridge_funcs;
0701     drm_bridge_attach(encoder, bridge, NULL, 0);
0702 
0703     connector->encoder = encoder;
0704 
0705     drm_connector = (struct drm_connector *)connector;
0706 
0707     drm_connector->polled = DRM_CONNECTOR_POLL_HPD;
0708 
0709     drm_connector_init(drm_dev, drm_connector,
0710             &sti_hda_connector_funcs, DRM_MODE_CONNECTOR_Component);
0711     drm_connector_helper_add(drm_connector,
0712             &sti_hda_connector_helper_funcs);
0713 
0714     err = drm_connector_attach_encoder(drm_connector, encoder);
0715     if (err) {
0716         DRM_ERROR("Failed to attach a connector to a encoder\n");
0717         goto err_sysfs;
0718     }
0719 
0720     /* force to disable hd dacs at startup */
0721     hda_enable_hd_dacs(hda, false);
0722 
0723     return 0;
0724 
0725 err_sysfs:
0726     return -EINVAL;
0727 }
0728 
0729 static void sti_hda_unbind(struct device *dev,
0730         struct device *master, void *data)
0731 {
0732 }
0733 
0734 static const struct component_ops sti_hda_ops = {
0735     .bind = sti_hda_bind,
0736     .unbind = sti_hda_unbind,
0737 };
0738 
0739 static int sti_hda_probe(struct platform_device *pdev)
0740 {
0741     struct device *dev = &pdev->dev;
0742     struct sti_hda *hda;
0743     struct resource *res;
0744 
0745     DRM_INFO("%s\n", __func__);
0746 
0747     hda = devm_kzalloc(dev, sizeof(*hda), GFP_KERNEL);
0748     if (!hda)
0749         return -ENOMEM;
0750 
0751     hda->dev = pdev->dev;
0752 
0753     /* Get resources */
0754     res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hda-reg");
0755     if (!res) {
0756         DRM_ERROR("Invalid hda resource\n");
0757         return -ENOMEM;
0758     }
0759     hda->regs = devm_ioremap(dev, res->start, resource_size(res));
0760     if (!hda->regs)
0761         return -ENOMEM;
0762 
0763     res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
0764             "video-dacs-ctrl");
0765     if (res) {
0766         hda->video_dacs_ctrl = devm_ioremap(dev, res->start,
0767                 resource_size(res));
0768         if (!hda->video_dacs_ctrl)
0769             return -ENOMEM;
0770     } else {
0771         /* If no existing video-dacs-ctrl resource continue the probe */
0772         DRM_DEBUG_DRIVER("No video-dacs-ctrl resource\n");
0773         hda->video_dacs_ctrl = NULL;
0774     }
0775 
0776     /* Get clock resources */
0777     hda->clk_pix = devm_clk_get(dev, "pix");
0778     if (IS_ERR(hda->clk_pix)) {
0779         DRM_ERROR("Cannot get hda_pix clock\n");
0780         return PTR_ERR(hda->clk_pix);
0781     }
0782 
0783     hda->clk_hddac = devm_clk_get(dev, "hddac");
0784     if (IS_ERR(hda->clk_hddac)) {
0785         DRM_ERROR("Cannot get hda_hddac clock\n");
0786         return PTR_ERR(hda->clk_hddac);
0787     }
0788 
0789     platform_set_drvdata(pdev, hda);
0790 
0791     return component_add(&pdev->dev, &sti_hda_ops);
0792 }
0793 
0794 static int sti_hda_remove(struct platform_device *pdev)
0795 {
0796     component_del(&pdev->dev, &sti_hda_ops);
0797     return 0;
0798 }
0799 
0800 static const struct of_device_id hda_of_match[] = {
0801     { .compatible = "st,stih416-hda", },
0802     { .compatible = "st,stih407-hda", },
0803     { /* end node */ }
0804 };
0805 MODULE_DEVICE_TABLE(of, hda_of_match);
0806 
0807 struct platform_driver sti_hda_driver = {
0808     .driver = {
0809         .name = "sti-hda",
0810         .owner = THIS_MODULE,
0811         .of_match_table = hda_of_match,
0812     },
0813     .probe = sti_hda_probe,
0814     .remove = sti_hda_remove,
0815 };
0816 
0817 MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
0818 MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
0819 MODULE_LICENSE("GPL");