0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/clk.h>
0009 #include <linux/component.h>
0010 #include <linux/delay.h>
0011 #include <linux/mfd/syscon.h>
0012 #include <linux/module.h>
0013 #include <linux/mutex.h>
0014 #include <linux/of.h>
0015 #include <linux/of_address.h>
0016 #include <linux/of_graph.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/pm_runtime.h>
0019 #include <linux/regmap.h>
0020
0021 #include <video/of_videomode.h>
0022 #include <video/videomode.h>
0023
0024 #include <drm/drm_bridge.h>
0025 #include <drm/drm_encoder.h>
0026 #include <drm/drm_print.h>
0027
0028 #include "exynos_drm_drv.h"
0029 #include "exynos_drm_crtc.h"
0030
0031
0032 #define DSD_CFG_MUX 0x1004
0033 #define MIC0_RGB_MUX (1 << 0)
0034 #define MIC0_I80_MUX (1 << 1)
0035 #define MIC0_ON_MUX (1 << 5)
0036
0037
0038 #define MIC_OP 0x0
0039 #define MIC_IP_VER 0x0004
0040 #define MIC_V_TIMING_0 0x0008
0041 #define MIC_V_TIMING_1 0x000C
0042 #define MIC_IMG_SIZE 0x0010
0043 #define MIC_INPUT_TIMING_0 0x0014
0044 #define MIC_INPUT_TIMING_1 0x0018
0045 #define MIC_2D_OUTPUT_TIMING_0 0x001C
0046 #define MIC_2D_OUTPUT_TIMING_1 0x0020
0047 #define MIC_2D_OUTPUT_TIMING_2 0x0024
0048 #define MIC_3D_OUTPUT_TIMING_0 0x0028
0049 #define MIC_3D_OUTPUT_TIMING_1 0x002C
0050 #define MIC_3D_OUTPUT_TIMING_2 0x0030
0051 #define MIC_CORE_PARA_0 0x0034
0052 #define MIC_CORE_PARA_1 0x0038
0053 #define MIC_CTC_CTRL 0x0040
0054 #define MIC_RD_DATA 0x0044
0055
0056 #define MIC_UPD_REG (1 << 31)
0057 #define MIC_ON_REG (1 << 30)
0058 #define MIC_TD_ON_REG (1 << 29)
0059 #define MIC_BS_CHG_OUT (1 << 16)
0060 #define MIC_VIDEO_TYPE(x) (((x) & 0xf) << 12)
0061 #define MIC_PSR_EN (1 << 5)
0062 #define MIC_SW_RST (1 << 4)
0063 #define MIC_ALL_RST (1 << 3)
0064 #define MIC_CORE_VER_CONTROL (1 << 2)
0065 #define MIC_MODE_SEL_COMMAND_MODE (1 << 1)
0066 #define MIC_MODE_SEL_MASK (1 << 1)
0067 #define MIC_CORE_EN (1 << 0)
0068
0069 #define MIC_V_PULSE_WIDTH(x) (((x) & 0x3fff) << 16)
0070 #define MIC_V_PERIOD_LINE(x) ((x) & 0x3fff)
0071
0072 #define MIC_VBP_SIZE(x) (((x) & 0x3fff) << 16)
0073 #define MIC_VFP_SIZE(x) ((x) & 0x3fff)
0074
0075 #define MIC_IMG_V_SIZE(x) (((x) & 0x3fff) << 16)
0076 #define MIC_IMG_H_SIZE(x) ((x) & 0x3fff)
0077
0078 #define MIC_H_PULSE_WIDTH_IN(x) (((x) & 0x3fff) << 16)
0079 #define MIC_H_PERIOD_PIXEL_IN(x) ((x) & 0x3fff)
0080
0081 #define MIC_HBP_SIZE_IN(x) (((x) & 0x3fff) << 16)
0082 #define MIC_HFP_SIZE_IN(x) ((x) & 0x3fff)
0083
0084 #define MIC_H_PULSE_WIDTH_2D(x) (((x) & 0x3fff) << 16)
0085 #define MIC_H_PERIOD_PIXEL_2D(x) ((x) & 0x3fff)
0086
0087 #define MIC_HBP_SIZE_2D(x) (((x) & 0x3fff) << 16)
0088 #define MIC_HFP_SIZE_2D(x) ((x) & 0x3fff)
0089
0090 #define MIC_BS_SIZE_2D(x) ((x) & 0x3fff)
0091
0092 static const char *const clk_names[] = { "pclk_mic0", "sclk_rgb_vclk_to_mic0" };
0093 #define NUM_CLKS ARRAY_SIZE(clk_names)
0094 static DEFINE_MUTEX(mic_mutex);
0095
0096 struct exynos_mic {
0097 struct device *dev;
0098 void __iomem *reg;
0099 struct regmap *sysreg;
0100 struct clk *clks[NUM_CLKS];
0101
0102 bool i80_mode;
0103 struct videomode vm;
0104 struct drm_bridge bridge;
0105
0106 bool enabled;
0107 };
0108
0109 static void mic_set_path(struct exynos_mic *mic, bool enable)
0110 {
0111 int ret;
0112 unsigned int val;
0113
0114 ret = regmap_read(mic->sysreg, DSD_CFG_MUX, &val);
0115 if (ret) {
0116 DRM_DEV_ERROR(mic->dev,
0117 "mic: Failed to read system register\n");
0118 return;
0119 }
0120
0121 if (enable) {
0122 if (mic->i80_mode)
0123 val |= MIC0_I80_MUX;
0124 else
0125 val |= MIC0_RGB_MUX;
0126
0127 val |= MIC0_ON_MUX;
0128 } else
0129 val &= ~(MIC0_RGB_MUX | MIC0_I80_MUX | MIC0_ON_MUX);
0130
0131 ret = regmap_write(mic->sysreg, DSD_CFG_MUX, val);
0132 if (ret)
0133 DRM_DEV_ERROR(mic->dev,
0134 "mic: Failed to read system register\n");
0135 }
0136
0137 static int mic_sw_reset(struct exynos_mic *mic)
0138 {
0139 unsigned int retry = 100;
0140 int ret;
0141
0142 writel(MIC_SW_RST, mic->reg + MIC_OP);
0143
0144 while (retry-- > 0) {
0145 ret = readl(mic->reg + MIC_OP);
0146 if (!(ret & MIC_SW_RST))
0147 return 0;
0148
0149 udelay(10);
0150 }
0151
0152 return -ETIMEDOUT;
0153 }
0154
0155 static void mic_set_porch_timing(struct exynos_mic *mic)
0156 {
0157 struct videomode vm = mic->vm;
0158 u32 reg;
0159
0160 reg = MIC_V_PULSE_WIDTH(vm.vsync_len) +
0161 MIC_V_PERIOD_LINE(vm.vsync_len + vm.vactive +
0162 vm.vback_porch + vm.vfront_porch);
0163 writel(reg, mic->reg + MIC_V_TIMING_0);
0164
0165 reg = MIC_VBP_SIZE(vm.vback_porch) +
0166 MIC_VFP_SIZE(vm.vfront_porch);
0167 writel(reg, mic->reg + MIC_V_TIMING_1);
0168
0169 reg = MIC_V_PULSE_WIDTH(vm.hsync_len) +
0170 MIC_V_PERIOD_LINE(vm.hsync_len + vm.hactive +
0171 vm.hback_porch + vm.hfront_porch);
0172 writel(reg, mic->reg + MIC_INPUT_TIMING_0);
0173
0174 reg = MIC_VBP_SIZE(vm.hback_porch) +
0175 MIC_VFP_SIZE(vm.hfront_porch);
0176 writel(reg, mic->reg + MIC_INPUT_TIMING_1);
0177 }
0178
0179 static void mic_set_img_size(struct exynos_mic *mic)
0180 {
0181 struct videomode *vm = &mic->vm;
0182 u32 reg;
0183
0184 reg = MIC_IMG_H_SIZE(vm->hactive) +
0185 MIC_IMG_V_SIZE(vm->vactive);
0186
0187 writel(reg, mic->reg + MIC_IMG_SIZE);
0188 }
0189
0190 static void mic_set_output_timing(struct exynos_mic *mic)
0191 {
0192 struct videomode vm = mic->vm;
0193 u32 reg, bs_size_2d;
0194
0195 DRM_DEV_DEBUG(mic->dev, "w: %u, h: %u\n", vm.hactive, vm.vactive);
0196 bs_size_2d = ((vm.hactive >> 2) << 1) + (vm.vactive % 4);
0197 reg = MIC_BS_SIZE_2D(bs_size_2d);
0198 writel(reg, mic->reg + MIC_2D_OUTPUT_TIMING_2);
0199
0200 if (!mic->i80_mode) {
0201 reg = MIC_H_PULSE_WIDTH_2D(vm.hsync_len) +
0202 MIC_H_PERIOD_PIXEL_2D(vm.hsync_len + bs_size_2d +
0203 vm.hback_porch + vm.hfront_porch);
0204 writel(reg, mic->reg + MIC_2D_OUTPUT_TIMING_0);
0205
0206 reg = MIC_HBP_SIZE_2D(vm.hback_porch) +
0207 MIC_H_PERIOD_PIXEL_2D(vm.hfront_porch);
0208 writel(reg, mic->reg + MIC_2D_OUTPUT_TIMING_1);
0209 }
0210 }
0211
0212 static void mic_set_reg_on(struct exynos_mic *mic, bool enable)
0213 {
0214 u32 reg = readl(mic->reg + MIC_OP);
0215
0216 if (enable) {
0217 reg &= ~(MIC_MODE_SEL_MASK | MIC_CORE_VER_CONTROL | MIC_PSR_EN);
0218 reg |= (MIC_CORE_EN | MIC_BS_CHG_OUT | MIC_ON_REG);
0219
0220 reg &= ~MIC_MODE_SEL_COMMAND_MODE;
0221 if (mic->i80_mode)
0222 reg |= MIC_MODE_SEL_COMMAND_MODE;
0223 } else {
0224 reg &= ~MIC_CORE_EN;
0225 }
0226
0227 reg |= MIC_UPD_REG;
0228 writel(reg, mic->reg + MIC_OP);
0229 }
0230
0231 static void mic_post_disable(struct drm_bridge *bridge)
0232 {
0233 struct exynos_mic *mic = bridge->driver_private;
0234
0235 mutex_lock(&mic_mutex);
0236 if (!mic->enabled)
0237 goto already_disabled;
0238
0239 mic_set_path(mic, 0);
0240
0241 pm_runtime_put(mic->dev);
0242 mic->enabled = 0;
0243
0244 already_disabled:
0245 mutex_unlock(&mic_mutex);
0246 }
0247
0248 static void mic_mode_set(struct drm_bridge *bridge,
0249 const struct drm_display_mode *mode,
0250 const struct drm_display_mode *adjusted_mode)
0251 {
0252 struct exynos_mic *mic = bridge->driver_private;
0253
0254 mutex_lock(&mic_mutex);
0255 drm_display_mode_to_videomode(mode, &mic->vm);
0256 mic->i80_mode = to_exynos_crtc(bridge->encoder->crtc)->i80_mode;
0257 mutex_unlock(&mic_mutex);
0258 }
0259
0260 static void mic_pre_enable(struct drm_bridge *bridge)
0261 {
0262 struct exynos_mic *mic = bridge->driver_private;
0263 int ret;
0264
0265 mutex_lock(&mic_mutex);
0266 if (mic->enabled)
0267 goto unlock;
0268
0269 ret = pm_runtime_resume_and_get(mic->dev);
0270 if (ret < 0)
0271 goto unlock;
0272
0273 mic_set_path(mic, 1);
0274
0275 ret = mic_sw_reset(mic);
0276 if (ret) {
0277 DRM_DEV_ERROR(mic->dev, "Failed to reset\n");
0278 goto turn_off;
0279 }
0280
0281 if (!mic->i80_mode)
0282 mic_set_porch_timing(mic);
0283 mic_set_img_size(mic);
0284 mic_set_output_timing(mic);
0285 mic_set_reg_on(mic, 1);
0286 mic->enabled = 1;
0287 mutex_unlock(&mic_mutex);
0288
0289 return;
0290
0291 turn_off:
0292 pm_runtime_put(mic->dev);
0293 unlock:
0294 mutex_unlock(&mic_mutex);
0295 }
0296
0297 static const struct drm_bridge_funcs mic_bridge_funcs = {
0298 .post_disable = mic_post_disable,
0299 .mode_set = mic_mode_set,
0300 .pre_enable = mic_pre_enable,
0301 };
0302
0303 static int exynos_mic_bind(struct device *dev, struct device *master,
0304 void *data)
0305 {
0306 struct exynos_mic *mic = dev_get_drvdata(dev);
0307 struct drm_device *drm_dev = data;
0308 struct exynos_drm_crtc *crtc = exynos_drm_crtc_get_by_type(drm_dev,
0309 EXYNOS_DISPLAY_TYPE_LCD);
0310 struct drm_encoder *e, *encoder = NULL;
0311
0312 drm_for_each_encoder(e, drm_dev)
0313 if (e->possible_crtcs == drm_crtc_mask(&crtc->base))
0314 encoder = e;
0315 if (!encoder)
0316 return -ENODEV;
0317
0318 mic->bridge.driver_private = mic;
0319
0320 return drm_bridge_attach(encoder, &mic->bridge, NULL, 0);
0321 }
0322
0323 static void exynos_mic_unbind(struct device *dev, struct device *master,
0324 void *data)
0325 {
0326 struct exynos_mic *mic = dev_get_drvdata(dev);
0327
0328 mutex_lock(&mic_mutex);
0329 if (!mic->enabled)
0330 goto already_disabled;
0331
0332 pm_runtime_put(mic->dev);
0333
0334 already_disabled:
0335 mutex_unlock(&mic_mutex);
0336 }
0337
0338 static const struct component_ops exynos_mic_component_ops = {
0339 .bind = exynos_mic_bind,
0340 .unbind = exynos_mic_unbind,
0341 };
0342
0343 #ifdef CONFIG_PM
0344 static int exynos_mic_suspend(struct device *dev)
0345 {
0346 struct exynos_mic *mic = dev_get_drvdata(dev);
0347 int i;
0348
0349 for (i = NUM_CLKS - 1; i > -1; i--)
0350 clk_disable_unprepare(mic->clks[i]);
0351
0352 return 0;
0353 }
0354
0355 static int exynos_mic_resume(struct device *dev)
0356 {
0357 struct exynos_mic *mic = dev_get_drvdata(dev);
0358 int ret, i;
0359
0360 for (i = 0; i < NUM_CLKS; i++) {
0361 ret = clk_prepare_enable(mic->clks[i]);
0362 if (ret < 0) {
0363 DRM_DEV_ERROR(dev, "Failed to enable clock (%s)\n",
0364 clk_names[i]);
0365 while (--i > -1)
0366 clk_disable_unprepare(mic->clks[i]);
0367 return ret;
0368 }
0369 }
0370 return 0;
0371 }
0372 #endif
0373
0374 static const struct dev_pm_ops exynos_mic_pm_ops = {
0375 SET_RUNTIME_PM_OPS(exynos_mic_suspend, exynos_mic_resume, NULL)
0376 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
0377 pm_runtime_force_resume)
0378 };
0379
0380 static int exynos_mic_probe(struct platform_device *pdev)
0381 {
0382 struct device *dev = &pdev->dev;
0383 struct exynos_mic *mic;
0384 struct resource res;
0385 int ret, i;
0386
0387 mic = devm_kzalloc(dev, sizeof(*mic), GFP_KERNEL);
0388 if (!mic) {
0389 DRM_DEV_ERROR(dev,
0390 "mic: Failed to allocate memory for MIC object\n");
0391 ret = -ENOMEM;
0392 goto err;
0393 }
0394
0395 mic->dev = dev;
0396
0397 ret = of_address_to_resource(dev->of_node, 0, &res);
0398 if (ret) {
0399 DRM_DEV_ERROR(dev, "mic: Failed to get mem region for MIC\n");
0400 goto err;
0401 }
0402 mic->reg = devm_ioremap(dev, res.start, resource_size(&res));
0403 if (!mic->reg) {
0404 DRM_DEV_ERROR(dev, "mic: Failed to remap for MIC\n");
0405 ret = -ENOMEM;
0406 goto err;
0407 }
0408
0409 mic->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
0410 "samsung,disp-syscon");
0411 if (IS_ERR(mic->sysreg)) {
0412 DRM_DEV_ERROR(dev, "mic: Failed to get system register.\n");
0413 ret = PTR_ERR(mic->sysreg);
0414 goto err;
0415 }
0416
0417 for (i = 0; i < NUM_CLKS; i++) {
0418 mic->clks[i] = devm_clk_get(dev, clk_names[i]);
0419 if (IS_ERR(mic->clks[i])) {
0420 DRM_DEV_ERROR(dev, "mic: Failed to get clock (%s)\n",
0421 clk_names[i]);
0422 ret = PTR_ERR(mic->clks[i]);
0423 goto err;
0424 }
0425 }
0426
0427 platform_set_drvdata(pdev, mic);
0428
0429 mic->bridge.funcs = &mic_bridge_funcs;
0430 mic->bridge.of_node = dev->of_node;
0431
0432 drm_bridge_add(&mic->bridge);
0433
0434 pm_runtime_enable(dev);
0435
0436 ret = component_add(dev, &exynos_mic_component_ops);
0437 if (ret)
0438 goto err_pm;
0439
0440 DRM_DEV_DEBUG_KMS(dev, "MIC has been probed\n");
0441
0442 return 0;
0443
0444 err_pm:
0445 pm_runtime_disable(dev);
0446 err:
0447 return ret;
0448 }
0449
0450 static int exynos_mic_remove(struct platform_device *pdev)
0451 {
0452 struct exynos_mic *mic = platform_get_drvdata(pdev);
0453
0454 component_del(&pdev->dev, &exynos_mic_component_ops);
0455 pm_runtime_disable(&pdev->dev);
0456
0457 drm_bridge_remove(&mic->bridge);
0458
0459 return 0;
0460 }
0461
0462 static const struct of_device_id exynos_mic_of_match[] = {
0463 { .compatible = "samsung,exynos5433-mic" },
0464 { }
0465 };
0466 MODULE_DEVICE_TABLE(of, exynos_mic_of_match);
0467
0468 struct platform_driver mic_driver = {
0469 .probe = exynos_mic_probe,
0470 .remove = exynos_mic_remove,
0471 .driver = {
0472 .name = "exynos-mic",
0473 .pm = &exynos_mic_pm_ops,
0474 .owner = THIS_MODULE,
0475 .of_match_table = exynos_mic_of_match,
0476 },
0477 };