1 /* 2 * Copyright (C) 2015 Samsung Electronics Co.Ltd 3 * Authors: 4 * Hyungwon Hwang <human.hwang@samsung.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundationr 9 */ 10 11 #include <linux/platform_device.h> 12 #include <video/of_videomode.h> 13 #include <linux/of_address.h> 14 #include <video/videomode.h> 15 #include <linux/module.h> 16 #include <linux/delay.h> 17 #include <linux/mutex.h> 18 #include <linux/of.h> 19 #include <linux/of_graph.h> 20 #include <linux/clk.h> 21 #include <linux/component.h> 22 #include <linux/pm_runtime.h> 23 #include <drm/drmP.h> 24 #include <linux/mfd/syscon.h> 25 #include <linux/regmap.h> 26 27 /* Sysreg registers for MIC */ 28 #define DSD_CFG_MUX 0x1004 29 #define MIC0_RGB_MUX (1 << 0) 30 #define MIC0_I80_MUX (1 << 1) 31 #define MIC0_ON_MUX (1 << 5) 32 33 /* MIC registers */ 34 #define MIC_OP 0x0 35 #define MIC_IP_VER 0x0004 36 #define MIC_V_TIMING_0 0x0008 37 #define MIC_V_TIMING_1 0x000C 38 #define MIC_IMG_SIZE 0x0010 39 #define MIC_INPUT_TIMING_0 0x0014 40 #define MIC_INPUT_TIMING_1 0x0018 41 #define MIC_2D_OUTPUT_TIMING_0 0x001C 42 #define MIC_2D_OUTPUT_TIMING_1 0x0020 43 #define MIC_2D_OUTPUT_TIMING_2 0x0024 44 #define MIC_3D_OUTPUT_TIMING_0 0x0028 45 #define MIC_3D_OUTPUT_TIMING_1 0x002C 46 #define MIC_3D_OUTPUT_TIMING_2 0x0030 47 #define MIC_CORE_PARA_0 0x0034 48 #define MIC_CORE_PARA_1 0x0038 49 #define MIC_CTC_CTRL 0x0040 50 #define MIC_RD_DATA 0x0044 51 52 #define MIC_UPD_REG (1 << 31) 53 #define MIC_ON_REG (1 << 30) 54 #define MIC_TD_ON_REG (1 << 29) 55 #define MIC_BS_CHG_OUT (1 << 16) 56 #define MIC_VIDEO_TYPE(x) (((x) & 0xf) << 12) 57 #define MIC_PSR_EN (1 << 5) 58 #define MIC_SW_RST (1 << 4) 59 #define MIC_ALL_RST (1 << 3) 60 #define MIC_CORE_VER_CONTROL (1 << 2) 61 #define MIC_MODE_SEL_COMMAND_MODE (1 << 1) 62 #define MIC_MODE_SEL_MASK (1 << 1) 63 #define MIC_CORE_EN (1 << 0) 64 65 #define MIC_V_PULSE_WIDTH(x) (((x) & 0x3fff) << 16) 66 #define MIC_V_PERIOD_LINE(x) ((x) & 0x3fff) 67 68 #define MIC_VBP_SIZE(x) (((x) & 0x3fff) << 16) 69 #define MIC_VFP_SIZE(x) ((x) & 0x3fff) 70 71 #define MIC_IMG_V_SIZE(x) (((x) & 0x3fff) << 16) 72 #define MIC_IMG_H_SIZE(x) ((x) & 0x3fff) 73 74 #define MIC_H_PULSE_WIDTH_IN(x) (((x) & 0x3fff) << 16) 75 #define MIC_H_PERIOD_PIXEL_IN(x) ((x) & 0x3fff) 76 77 #define MIC_HBP_SIZE_IN(x) (((x) & 0x3fff) << 16) 78 #define MIC_HFP_SIZE_IN(x) ((x) & 0x3fff) 79 80 #define MIC_H_PULSE_WIDTH_2D(x) (((x) & 0x3fff) << 16) 81 #define MIC_H_PERIOD_PIXEL_2D(x) ((x) & 0x3fff) 82 83 #define MIC_HBP_SIZE_2D(x) (((x) & 0x3fff) << 16) 84 #define MIC_HFP_SIZE_2D(x) ((x) & 0x3fff) 85 86 #define MIC_BS_SIZE_2D(x) ((x) & 0x3fff) 87 88 enum { 89 ENDPOINT_DECON_NODE, 90 ENDPOINT_DSI_NODE, 91 NUM_ENDPOINTS 92 }; 93 94 static char *clk_names[] = { "pclk_mic0", "sclk_rgb_vclk_to_mic0" }; 95 #define NUM_CLKS ARRAY_SIZE(clk_names) 96 static DEFINE_MUTEX(mic_mutex); 97 98 struct exynos_mic { 99 struct device *dev; 100 void __iomem *reg; 101 struct regmap *sysreg; 102 struct clk *clks[NUM_CLKS]; 103 104 bool i80_mode; 105 struct videomode vm; 106 struct drm_encoder *encoder; 107 struct drm_bridge bridge; 108 109 bool enabled; 110 }; 111 112 static void mic_set_path(struct exynos_mic *mic, bool enable) 113 { 114 int ret; 115 unsigned int val; 116 117 ret = regmap_read(mic->sysreg, DSD_CFG_MUX, &val); 118 if (ret) { 119 DRM_ERROR("mic: Failed to read system register\n"); 120 return; 121 } 122 123 if (enable) { 124 if (mic->i80_mode) 125 val |= MIC0_I80_MUX; 126 else 127 val |= MIC0_RGB_MUX; 128 129 val |= MIC0_ON_MUX; 130 } else 131 val &= ~(MIC0_RGB_MUX | MIC0_I80_MUX | MIC0_ON_MUX); 132 133 ret = regmap_write(mic->sysreg, DSD_CFG_MUX, val); 134 if (ret) 135 DRM_ERROR("mic: Failed to read system register\n"); 136 } 137 138 static int mic_sw_reset(struct exynos_mic *mic) 139 { 140 unsigned int retry = 100; 141 int ret; 142 143 writel(MIC_SW_RST, mic->reg + MIC_OP); 144 145 while (retry-- > 0) { 146 ret = readl(mic->reg + MIC_OP); 147 if (!(ret & MIC_SW_RST)) 148 return 0; 149 150 udelay(10); 151 } 152 153 return -ETIMEDOUT; 154 } 155 156 static void mic_set_porch_timing(struct exynos_mic *mic) 157 { 158 struct videomode vm = mic->vm; 159 u32 reg; 160 161 reg = MIC_V_PULSE_WIDTH(vm.vsync_len) + 162 MIC_V_PERIOD_LINE(vm.vsync_len + vm.vactive + 163 vm.vback_porch + vm.vfront_porch); 164 writel(reg, mic->reg + MIC_V_TIMING_0); 165 166 reg = MIC_VBP_SIZE(vm.vback_porch) + 167 MIC_VFP_SIZE(vm.vfront_porch); 168 writel(reg, mic->reg + MIC_V_TIMING_1); 169 170 reg = MIC_V_PULSE_WIDTH(vm.hsync_len) + 171 MIC_V_PERIOD_LINE(vm.hsync_len + vm.hactive + 172 vm.hback_porch + vm.hfront_porch); 173 writel(reg, mic->reg + MIC_INPUT_TIMING_0); 174 175 reg = MIC_VBP_SIZE(vm.hback_porch) + 176 MIC_VFP_SIZE(vm.hfront_porch); 177 writel(reg, mic->reg + MIC_INPUT_TIMING_1); 178 } 179 180 static void mic_set_img_size(struct exynos_mic *mic) 181 { 182 struct videomode *vm = &mic->vm; 183 u32 reg; 184 185 reg = MIC_IMG_H_SIZE(vm->hactive) + 186 MIC_IMG_V_SIZE(vm->vactive); 187 188 writel(reg, mic->reg + MIC_IMG_SIZE); 189 } 190 191 static void mic_set_output_timing(struct exynos_mic *mic) 192 { 193 struct videomode vm = mic->vm; 194 u32 reg, bs_size_2d; 195 196 DRM_DEBUG("w: %u, h: %u\n", vm.hactive, vm.vactive); 197 bs_size_2d = ((vm.hactive >> 2) << 1) + (vm.vactive % 4); 198 reg = MIC_BS_SIZE_2D(bs_size_2d); 199 writel(reg, mic->reg + MIC_2D_OUTPUT_TIMING_2); 200 201 if (!mic->i80_mode) { 202 reg = MIC_H_PULSE_WIDTH_2D(vm.hsync_len) + 203 MIC_H_PERIOD_PIXEL_2D(vm.hsync_len + bs_size_2d + 204 vm.hback_porch + vm.hfront_porch); 205 writel(reg, mic->reg + MIC_2D_OUTPUT_TIMING_0); 206 207 reg = MIC_HBP_SIZE_2D(vm.hback_porch) + 208 MIC_H_PERIOD_PIXEL_2D(vm.hfront_porch); 209 writel(reg, mic->reg + MIC_2D_OUTPUT_TIMING_1); 210 } 211 } 212 213 static void mic_set_reg_on(struct exynos_mic *mic, bool enable) 214 { 215 u32 reg = readl(mic->reg + MIC_OP); 216 217 if (enable) { 218 reg &= ~(MIC_MODE_SEL_MASK | MIC_CORE_VER_CONTROL | MIC_PSR_EN); 219 reg |= (MIC_CORE_EN | MIC_BS_CHG_OUT | MIC_ON_REG); 220 221 reg &= ~MIC_MODE_SEL_COMMAND_MODE; 222 if (mic->i80_mode) 223 reg |= MIC_MODE_SEL_COMMAND_MODE; 224 } else { 225 reg &= ~MIC_CORE_EN; 226 } 227 228 reg |= MIC_UPD_REG; 229 writel(reg, mic->reg + MIC_OP); 230 } 231 232 static struct device_node *get_remote_node(struct device_node *from, int reg) 233 { 234 struct device_node *endpoint = NULL, *remote_node = NULL; 235 236 endpoint = of_graph_get_endpoint_by_regs(from, reg, -1); 237 if (!endpoint) { 238 DRM_ERROR("mic: Failed to find remote port from %s", 239 from->full_name); 240 goto exit; 241 } 242 243 remote_node = of_graph_get_remote_port_parent(endpoint); 244 if (!remote_node) { 245 DRM_ERROR("mic: Failed to find remote port parent from %s", 246 from->full_name); 247 goto exit; 248 } 249 250 exit: 251 of_node_put(endpoint); 252 return remote_node; 253 } 254 255 static int parse_dt(struct exynos_mic *mic) 256 { 257 int ret = 0, i, j; 258 struct device_node *remote_node; 259 struct device_node *nodes[3]; 260 261 /* 262 * The order of endpoints does matter. 263 * The first node must be for decon and the second one must be for dsi. 264 */ 265 for (i = 0, j = 0; i < NUM_ENDPOINTS; i++) { 266 remote_node = get_remote_node(mic->dev->of_node, i); 267 if (!remote_node) { 268 ret = -EPIPE; 269 goto exit; 270 } 271 nodes[j++] = remote_node; 272 273 if (i == ENDPOINT_DECON_NODE && 274 of_get_child_by_name(remote_node, "i80-if-timings")) 275 mic->i80_mode = 1; 276 } 277 278 exit: 279 while (--j > -1) 280 of_node_put(nodes[j]); 281 282 return ret; 283 } 284 285 static void mic_disable(struct drm_bridge *bridge) { } 286 287 static void mic_post_disable(struct drm_bridge *bridge) 288 { 289 struct exynos_mic *mic = bridge->driver_private; 290 291 mutex_lock(&mic_mutex); 292 if (!mic->enabled) 293 goto already_disabled; 294 295 mic_set_path(mic, 0); 296 297 pm_runtime_put(mic->dev); 298 mic->enabled = 0; 299 300 already_disabled: 301 mutex_unlock(&mic_mutex); 302 } 303 304 static void mic_mode_set(struct drm_bridge *bridge, 305 struct drm_display_mode *mode, 306 struct drm_display_mode *adjusted_mode) 307 { 308 struct exynos_mic *mic = bridge->driver_private; 309 310 mutex_lock(&mic_mutex); 311 drm_display_mode_to_videomode(mode, &mic->vm); 312 mutex_unlock(&mic_mutex); 313 } 314 315 static void mic_pre_enable(struct drm_bridge *bridge) 316 { 317 struct exynos_mic *mic = bridge->driver_private; 318 int ret; 319 320 mutex_lock(&mic_mutex); 321 if (mic->enabled) 322 goto unlock; 323 324 ret = pm_runtime_get_sync(mic->dev); 325 if (ret < 0) 326 goto unlock; 327 328 mic_set_path(mic, 1); 329 330 ret = mic_sw_reset(mic); 331 if (ret) { 332 DRM_ERROR("Failed to reset\n"); 333 goto turn_off; 334 } 335 336 if (!mic->i80_mode) 337 mic_set_porch_timing(mic); 338 mic_set_img_size(mic); 339 mic_set_output_timing(mic); 340 mic_set_reg_on(mic, 1); 341 mic->enabled = 1; 342 mutex_unlock(&mic_mutex); 343 344 return; 345 346 turn_off: 347 pm_runtime_put(mic->dev); 348 unlock: 349 mutex_unlock(&mic_mutex); 350 } 351 352 static void mic_enable(struct drm_bridge *bridge) { } 353 354 static const struct drm_bridge_funcs mic_bridge_funcs = { 355 .disable = mic_disable, 356 .post_disable = mic_post_disable, 357 .mode_set = mic_mode_set, 358 .pre_enable = mic_pre_enable, 359 .enable = mic_enable, 360 }; 361 362 static int exynos_mic_bind(struct device *dev, struct device *master, 363 void *data) 364 { 365 struct exynos_mic *mic = dev_get_drvdata(dev); 366 int ret; 367 368 mic->bridge.funcs = &mic_bridge_funcs; 369 mic->bridge.of_node = dev->of_node; 370 mic->bridge.driver_private = mic; 371 ret = drm_bridge_add(&mic->bridge); 372 if (ret) 373 DRM_ERROR("mic: Failed to add MIC to the global bridge list\n"); 374 375 return ret; 376 } 377 378 static void exynos_mic_unbind(struct device *dev, struct device *master, 379 void *data) 380 { 381 struct exynos_mic *mic = dev_get_drvdata(dev); 382 383 mutex_lock(&mic_mutex); 384 if (!mic->enabled) 385 goto already_disabled; 386 387 pm_runtime_put(mic->dev); 388 389 already_disabled: 390 mutex_unlock(&mic_mutex); 391 392 drm_bridge_remove(&mic->bridge); 393 } 394 395 static const struct component_ops exynos_mic_component_ops = { 396 .bind = exynos_mic_bind, 397 .unbind = exynos_mic_unbind, 398 }; 399 400 #ifdef CONFIG_PM 401 static int exynos_mic_suspend(struct device *dev) 402 { 403 struct exynos_mic *mic = dev_get_drvdata(dev); 404 int i; 405 406 for (i = NUM_CLKS - 1; i > -1; i--) 407 clk_disable_unprepare(mic->clks[i]); 408 409 return 0; 410 } 411 412 static int exynos_mic_resume(struct device *dev) 413 { 414 struct exynos_mic *mic = dev_get_drvdata(dev); 415 int ret, i; 416 417 for (i = 0; i < NUM_CLKS; i++) { 418 ret = clk_prepare_enable(mic->clks[i]); 419 if (ret < 0) { 420 DRM_ERROR("Failed to enable clock (%s)\n", 421 clk_names[i]); 422 while (--i > -1) 423 clk_disable_unprepare(mic->clks[i]); 424 return ret; 425 } 426 } 427 return 0; 428 } 429 #endif 430 431 static const struct dev_pm_ops exynos_mic_pm_ops = { 432 SET_RUNTIME_PM_OPS(exynos_mic_suspend, exynos_mic_resume, NULL) 433 }; 434 435 static int exynos_mic_probe(struct platform_device *pdev) 436 { 437 struct device *dev = &pdev->dev; 438 struct exynos_mic *mic; 439 struct resource res; 440 int ret, i; 441 442 mic = devm_kzalloc(dev, sizeof(*mic), GFP_KERNEL); 443 if (!mic) { 444 DRM_ERROR("mic: Failed to allocate memory for MIC object\n"); 445 ret = -ENOMEM; 446 goto err; 447 } 448 449 mic->dev = dev; 450 451 ret = parse_dt(mic); 452 if (ret) 453 goto err; 454 455 ret = of_address_to_resource(dev->of_node, 0, &res); 456 if (ret) { 457 DRM_ERROR("mic: Failed to get mem region for MIC\n"); 458 goto err; 459 } 460 mic->reg = devm_ioremap(dev, res.start, resource_size(&res)); 461 if (!mic->reg) { 462 DRM_ERROR("mic: Failed to remap for MIC\n"); 463 ret = -ENOMEM; 464 goto err; 465 } 466 467 mic->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node, 468 "samsung,disp-syscon"); 469 if (IS_ERR(mic->sysreg)) { 470 DRM_ERROR("mic: Failed to get system register.\n"); 471 ret = PTR_ERR(mic->sysreg); 472 goto err; 473 } 474 475 for (i = 0; i < NUM_CLKS; i++) { 476 mic->clks[i] = devm_clk_get(dev, clk_names[i]); 477 if (IS_ERR(mic->clks[i])) { 478 DRM_ERROR("mic: Failed to get clock (%s)\n", 479 clk_names[i]); 480 ret = PTR_ERR(mic->clks[i]); 481 goto err; 482 } 483 } 484 485 platform_set_drvdata(pdev, mic); 486 487 pm_runtime_enable(dev); 488 489 ret = component_add(dev, &exynos_mic_component_ops); 490 if (ret) 491 goto err_pm; 492 493 DRM_DEBUG_KMS("MIC has been probed\n"); 494 495 return 0; 496 497 err_pm: 498 pm_runtime_disable(dev); 499 err: 500 return ret; 501 } 502 503 static int exynos_mic_remove(struct platform_device *pdev) 504 { 505 component_del(&pdev->dev, &exynos_mic_component_ops); 506 pm_runtime_disable(&pdev->dev); 507 return 0; 508 } 509 510 static const struct of_device_id exynos_mic_of_match[] = { 511 { .compatible = "samsung,exynos5433-mic" }, 512 { } 513 }; 514 MODULE_DEVICE_TABLE(of, exynos_mic_of_match); 515 516 struct platform_driver mic_driver = { 517 .probe = exynos_mic_probe, 518 .remove = exynos_mic_remove, 519 .driver = { 520 .name = "exynos-mic", 521 .pm = &exynos_mic_pm_ops, 522 .owner = THIS_MODULE, 523 .of_match_table = exynos_mic_of_match, 524 }, 525 }; 526