1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright 2016 Linaro Ltd. 4 * Copyright 2016 ZTE Corporation. 5 */ 6 7#include <linux/clk.h> 8#include <linux/component.h> 9#include <linux/module.h> 10#include <linux/of_address.h> 11#include <linux/platform_device.h> 12 13#include <video/videomode.h> 14 15#include <drm/drm_atomic_helper.h> 16#include <drm/drm_crtc.h> 17#include <drm/drm_fb_cma_helper.h> 18#include <drm/drm_fb_helper.h> 19#include <drm/drm_gem_cma_helper.h> 20#include <drm/drm_of.h> 21#include <drm/drm_plane_helper.h> 22#include <drm/drm_probe_helper.h> 23#include <drm/drm_vblank.h> 24 25#include "zx_common_regs.h" 26#include "zx_drm_drv.h" 27#include "zx_plane.h" 28#include "zx_vou.h" 29#include "zx_vou_regs.h" 30 31#define GL_NUM 2 32#define VL_NUM 3 33 34enum vou_chn_type { 35 VOU_CHN_MAIN, 36 VOU_CHN_AUX, 37}; 38 39struct zx_crtc_regs { 40 u32 fir_active; 41 u32 fir_htiming; 42 u32 fir_vtiming; 43 u32 sec_vtiming; 44 u32 timing_shift; 45 u32 timing_pi_shift; 46}; 47 48static const struct zx_crtc_regs main_crtc_regs = { 49 .fir_active = FIR_MAIN_ACTIVE, 50 .fir_htiming = FIR_MAIN_H_TIMING, 51 .fir_vtiming = FIR_MAIN_V_TIMING, 52 .sec_vtiming = SEC_MAIN_V_TIMING, 53 .timing_shift = TIMING_MAIN_SHIFT, 54 .timing_pi_shift = TIMING_MAIN_PI_SHIFT, 55}; 56 57static const struct zx_crtc_regs aux_crtc_regs = { 58 .fir_active = FIR_AUX_ACTIVE, 59 .fir_htiming = FIR_AUX_H_TIMING, 60 .fir_vtiming = FIR_AUX_V_TIMING, 61 .sec_vtiming = SEC_AUX_V_TIMING, 62 .timing_shift = TIMING_AUX_SHIFT, 63 .timing_pi_shift = TIMING_AUX_PI_SHIFT, 64}; 65 66struct zx_crtc_bits { 67 u32 polarity_mask; 68 u32 polarity_shift; 69 u32 int_frame_mask; 70 u32 tc_enable; 71 u32 sec_vactive_shift; 72 u32 sec_vactive_mask; 73 u32 interlace_select; 74 u32 pi_enable; 75 u32 div_vga_shift; 76 u32 div_pic_shift; 77 u32 div_tvenc_shift; 78 u32 div_hdmi_pnx_shift; 79 u32 div_hdmi_shift; 80 u32 div_inf_shift; 81 u32 div_layer_shift; 82}; 83 84static const struct zx_crtc_bits main_crtc_bits = { 85 .polarity_mask = MAIN_POL_MASK, 86 .polarity_shift = MAIN_POL_SHIFT, 87 .int_frame_mask = TIMING_INT_MAIN_FRAME, 88 .tc_enable = MAIN_TC_EN, 89 .sec_vactive_shift = SEC_VACT_MAIN_SHIFT, 90 .sec_vactive_mask = SEC_VACT_MAIN_MASK, 91 .interlace_select = MAIN_INTERLACE_SEL, 92 .pi_enable = MAIN_PI_EN, 93 .div_vga_shift = VGA_MAIN_DIV_SHIFT, 94 .div_pic_shift = PIC_MAIN_DIV_SHIFT, 95 .div_tvenc_shift = TVENC_MAIN_DIV_SHIFT, 96 .div_hdmi_pnx_shift = HDMI_MAIN_PNX_DIV_SHIFT, 97 .div_hdmi_shift = HDMI_MAIN_DIV_SHIFT, 98 .div_inf_shift = INF_MAIN_DIV_SHIFT, 99 .div_layer_shift = LAYER_MAIN_DIV_SHIFT, 100}; 101 102static const struct zx_crtc_bits aux_crtc_bits = { 103 .polarity_mask = AUX_POL_MASK, 104 .polarity_shift = AUX_POL_SHIFT, 105 .int_frame_mask = TIMING_INT_AUX_FRAME, 106 .tc_enable = AUX_TC_EN, 107 .sec_vactive_shift = SEC_VACT_AUX_SHIFT, 108 .sec_vactive_mask = SEC_VACT_AUX_MASK, 109 .interlace_select = AUX_INTERLACE_SEL, 110 .pi_enable = AUX_PI_EN, 111 .div_vga_shift = VGA_AUX_DIV_SHIFT, 112 .div_pic_shift = PIC_AUX_DIV_SHIFT, 113 .div_tvenc_shift = TVENC_AUX_DIV_SHIFT, 114 .div_hdmi_pnx_shift = HDMI_AUX_PNX_DIV_SHIFT, 115 .div_hdmi_shift = HDMI_AUX_DIV_SHIFT, 116 .div_inf_shift = INF_AUX_DIV_SHIFT, 117 .div_layer_shift = LAYER_AUX_DIV_SHIFT, 118}; 119 120struct zx_crtc { 121 struct drm_crtc crtc; 122 struct drm_plane *primary; 123 struct zx_vou_hw *vou; 124 void __iomem *chnreg; 125 void __iomem *chncsc; 126 void __iomem *dither; 127 const struct zx_crtc_regs *regs; 128 const struct zx_crtc_bits *bits; 129 enum vou_chn_type chn_type; 130 struct clk *pixclk; 131}; 132 133#define to_zx_crtc(x) container_of(x, struct zx_crtc, crtc) 134 135struct vou_layer_bits { 136 u32 enable; 137 u32 chnsel; 138 u32 clksel; 139}; 140 141static const struct vou_layer_bits zx_gl_bits[GL_NUM] = { 142 { 143 .enable = OSD_CTRL0_GL0_EN, 144 .chnsel = OSD_CTRL0_GL0_SEL, 145 .clksel = VOU_CLK_GL0_SEL, 146 }, { 147 .enable = OSD_CTRL0_GL1_EN, 148 .chnsel = OSD_CTRL0_GL1_SEL, 149 .clksel = VOU_CLK_GL1_SEL, 150 }, 151}; 152 153static const struct vou_layer_bits zx_vl_bits[VL_NUM] = { 154 { 155 .enable = OSD_CTRL0_VL0_EN, 156 .chnsel = OSD_CTRL0_VL0_SEL, 157 .clksel = VOU_CLK_VL0_SEL, 158 }, { 159 .enable = OSD_CTRL0_VL1_EN, 160 .chnsel = OSD_CTRL0_VL1_SEL, 161 .clksel = VOU_CLK_VL1_SEL, 162 }, { 163 .enable = OSD_CTRL0_VL2_EN, 164 .chnsel = OSD_CTRL0_VL2_SEL, 165 .clksel = VOU_CLK_VL2_SEL, 166 }, 167}; 168 169struct zx_vou_hw { 170 struct device *dev; 171 void __iomem *osd; 172 void __iomem *timing; 173 void __iomem *vouctl; 174 void __iomem *otfppu; 175 void __iomem *dtrc; 176 struct clk *axi_clk; 177 struct clk *ppu_clk; 178 struct clk *main_clk; 179 struct clk *aux_clk; 180 struct zx_crtc *main_crtc; 181 struct zx_crtc *aux_crtc; 182}; 183 184enum vou_inf_data_sel { 185 VOU_YUV444 = 0, 186 VOU_RGB_101010 = 1, 187 VOU_RGB_888 = 2, 188 VOU_RGB_666 = 3, 189}; 190 191struct vou_inf { 192 enum vou_inf_id id; 193 enum vou_inf_data_sel data_sel; 194 u32 clocks_en_bits; 195 u32 clocks_sel_bits; 196}; 197 198static struct vou_inf vou_infs[] = { 199 [VOU_HDMI] = { 200 .data_sel = VOU_YUV444, 201 .clocks_en_bits = BIT(24) | BIT(18) | BIT(6), 202 .clocks_sel_bits = BIT(13) | BIT(2), 203 }, 204 [VOU_TV_ENC] = { 205 .data_sel = VOU_YUV444, 206 .clocks_en_bits = BIT(15), 207 .clocks_sel_bits = BIT(11) | BIT(0), 208 }, 209 [VOU_VGA] = { 210 .data_sel = VOU_RGB_888, 211 .clocks_en_bits = BIT(1), 212 .clocks_sel_bits = BIT(10), 213 }, 214}; 215 216static inline struct zx_vou_hw *crtc_to_vou(struct drm_crtc *crtc) 217{ 218 struct zx_crtc *zcrtc = to_zx_crtc(crtc); 219 220 return zcrtc->vou; 221} 222 223void vou_inf_hdmi_audio_sel(struct drm_crtc *crtc, 224 enum vou_inf_hdmi_audio aud) 225{ 226 struct zx_crtc *zcrtc = to_zx_crtc(crtc); 227 struct zx_vou_hw *vou = zcrtc->vou; 228 229 zx_writel_mask(vou->vouctl + VOU_INF_HDMI_CTRL, VOU_HDMI_AUD_MASK, aud); 230} 231 232void vou_inf_enable(enum vou_inf_id id, struct drm_crtc *crtc) 233{ 234 struct zx_crtc *zcrtc = to_zx_crtc(crtc); 235 struct zx_vou_hw *vou = zcrtc->vou; 236 struct vou_inf *inf = &vou_infs[id]; 237 void __iomem *dither = zcrtc->dither; 238 void __iomem *csc = zcrtc->chncsc; 239 bool is_main = zcrtc->chn_type == VOU_CHN_MAIN; 240 u32 data_sel_shift = id << 1; 241 242 if (inf->data_sel != VOU_YUV444) { 243 /* Enable channel CSC for RGB output */ 244 zx_writel_mask(csc + CSC_CTRL0, CSC_COV_MODE_MASK, 245 CSC_BT709_IMAGE_YCBCR2RGB << CSC_COV_MODE_SHIFT); 246 zx_writel_mask(csc + CSC_CTRL0, CSC_WORK_ENABLE, 247 CSC_WORK_ENABLE); 248 249 /* Bypass Dither block for RGB output */ 250 zx_writel_mask(dither + OSD_DITHER_CTRL0, DITHER_BYSPASS, 251 DITHER_BYSPASS); 252 } else { 253 zx_writel_mask(csc + CSC_CTRL0, CSC_WORK_ENABLE, 0); 254 zx_writel_mask(dither + OSD_DITHER_CTRL0, DITHER_BYSPASS, 0); 255 } 256 257 /* Select data format */ 258 zx_writel_mask(vou->vouctl + VOU_INF_DATA_SEL, 0x3 << data_sel_shift, 259 inf->data_sel << data_sel_shift); 260 261 /* Select channel */ 262 zx_writel_mask(vou->vouctl + VOU_INF_CH_SEL, 0x1 << id, 263 zcrtc->chn_type << id); 264 265 /* Select interface clocks */ 266 zx_writel_mask(vou->vouctl + VOU_CLK_SEL, inf->clocks_sel_bits, 267 is_main ? 0 : inf->clocks_sel_bits); 268 269 /* Enable interface clocks */ 270 zx_writel_mask(vou->vouctl + VOU_CLK_EN, inf->clocks_en_bits, 271 inf->clocks_en_bits); 272 273 /* Enable the device */ 274 zx_writel_mask(vou->vouctl + VOU_INF_EN, 1 << id, 1 << id); 275} 276 277void vou_inf_disable(enum vou_inf_id id, struct drm_crtc *crtc) 278{ 279 struct zx_vou_hw *vou = crtc_to_vou(crtc); 280 struct vou_inf *inf = &vou_infs[id]; 281 282 /* Disable the device */ 283 zx_writel_mask(vou->vouctl + VOU_INF_EN, 1 << id, 0); 284 285 /* Disable interface clocks */ 286 zx_writel_mask(vou->vouctl + VOU_CLK_EN, inf->clocks_en_bits, 0); 287} 288 289void zx_vou_config_dividers(struct drm_crtc *crtc, 290 struct vou_div_config *configs, int num) 291{ 292 struct zx_crtc *zcrtc = to_zx_crtc(crtc); 293 struct zx_vou_hw *vou = zcrtc->vou; 294 const struct zx_crtc_bits *bits = zcrtc->bits; 295 int i; 296 297 /* Clear update flag bit */ 298 zx_writel_mask(vou->vouctl + VOU_DIV_PARA, DIV_PARA_UPDATE, 0); 299 300 for (i = 0; i < num; i++) { 301 struct vou_div_config *cfg = configs + i; 302 u32 reg, shift; 303 304 switch (cfg->id) { 305 case VOU_DIV_VGA: 306 reg = VOU_CLK_SEL; 307 shift = bits->div_vga_shift; 308 break; 309 case VOU_DIV_PIC: 310 reg = VOU_CLK_SEL; 311 shift = bits->div_pic_shift; 312 break; 313 case VOU_DIV_TVENC: 314 reg = VOU_DIV_PARA; 315 shift = bits->div_tvenc_shift; 316 break; 317 case VOU_DIV_HDMI_PNX: 318 reg = VOU_DIV_PARA; 319 shift = bits->div_hdmi_pnx_shift; 320 break; 321 case VOU_DIV_HDMI: 322 reg = VOU_DIV_PARA; 323 shift = bits->div_hdmi_shift; 324 break; 325 case VOU_DIV_INF: 326 reg = VOU_DIV_PARA; 327 shift = bits->div_inf_shift; 328 break; 329 case VOU_DIV_LAYER: 330 reg = VOU_DIV_PARA; 331 shift = bits->div_layer_shift; 332 break; 333 default: 334 continue; 335 } 336 337 /* Each divider occupies 3 bits */ 338 zx_writel_mask(vou->vouctl + reg, 0x7 << shift, 339 cfg->val << shift); 340 } 341 342 /* Set update flag bit to get dividers effected */ 343 zx_writel_mask(vou->vouctl + VOU_DIV_PARA, DIV_PARA_UPDATE, 344 DIV_PARA_UPDATE); 345} 346 347static inline void vou_chn_set_update(struct zx_crtc *zcrtc) 348{ 349 zx_writel(zcrtc->chnreg + CHN_UPDATE, 1); 350} 351 352static void zx_crtc_atomic_enable(struct drm_crtc *crtc, 353 struct drm_crtc_state *old_state) 354{ 355 struct drm_display_mode *mode = &crtc->state->adjusted_mode; 356 bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE; 357 struct zx_crtc *zcrtc = to_zx_crtc(crtc); 358 struct zx_vou_hw *vou = zcrtc->vou; 359 const struct zx_crtc_regs *regs = zcrtc->regs; 360 const struct zx_crtc_bits *bits = zcrtc->bits; 361 struct videomode vm; 362 u32 scan_mask; 363 u32 pol = 0; 364 u32 val; 365 int ret; 366 367 drm_display_mode_to_videomode(mode, &vm); 368 369 /* Set up timing parameters */ 370 val = V_ACTIVE((interlaced ? vm.vactive / 2 : vm.vactive) - 1); 371 val |= H_ACTIVE(vm.hactive - 1); 372 zx_writel(vou->timing + regs->fir_active, val); 373 374 val = SYNC_WIDE(vm.hsync_len - 1); 375 val |= BACK_PORCH(vm.hback_porch - 1); 376 val |= FRONT_PORCH(vm.hfront_porch - 1); 377 zx_writel(vou->timing + regs->fir_htiming, val); 378 379 val = SYNC_WIDE(vm.vsync_len - 1); 380 val |= BACK_PORCH(vm.vback_porch - 1); 381 val |= FRONT_PORCH(vm.vfront_porch - 1); 382 zx_writel(vou->timing + regs->fir_vtiming, val); 383 384 if (interlaced) { 385 u32 shift = bits->sec_vactive_shift; 386 u32 mask = bits->sec_vactive_mask; 387 388 val = zx_readl(vou->timing + SEC_V_ACTIVE); 389 val &= ~mask; 390 val |= ((vm.vactive / 2 - 1) << shift) & mask; 391 zx_writel(vou->timing + SEC_V_ACTIVE, val); 392 393 val = SYNC_WIDE(vm.vsync_len - 1); 394 /* 395 * The vback_porch for the second field needs to shift one on 396 * the value for the first field. 397 */ 398 val |= BACK_PORCH(vm.vback_porch); 399 val |= FRONT_PORCH(vm.vfront_porch - 1); 400 zx_writel(vou->timing + regs->sec_vtiming, val); 401 } 402 403 /* Set up polarities */ 404 if (vm.flags & DISPLAY_FLAGS_VSYNC_LOW) 405 pol |= 1 << POL_VSYNC_SHIFT; 406 if (vm.flags & DISPLAY_FLAGS_HSYNC_LOW) 407 pol |= 1 << POL_HSYNC_SHIFT; 408 409 zx_writel_mask(vou->timing + TIMING_CTRL, bits->polarity_mask, 410 pol << bits->polarity_shift); 411 412 /* Setup SHIFT register by following what ZTE BSP does */ 413 val = H_SHIFT_VAL; 414 if (interlaced) 415 val |= V_SHIFT_VAL << 16; 416 zx_writel(vou->timing + regs->timing_shift, val); 417 zx_writel(vou->timing + regs->timing_pi_shift, H_PI_SHIFT_VAL); 418 419 /* Progressive or interlace scan select */ 420 scan_mask = bits->interlace_select | bits->pi_enable; 421 zx_writel_mask(vou->timing + SCAN_CTRL, scan_mask, 422 interlaced ? scan_mask : 0); 423 424 /* Enable TIMING_CTRL */ 425 zx_writel_mask(vou->timing + TIMING_TC_ENABLE, bits->tc_enable, 426 bits->tc_enable); 427 428 /* Configure channel screen size */ 429 zx_writel_mask(zcrtc->chnreg + CHN_CTRL1, CHN_SCREEN_W_MASK, 430 vm.hactive << CHN_SCREEN_W_SHIFT); 431 zx_writel_mask(zcrtc->chnreg + CHN_CTRL1, CHN_SCREEN_H_MASK, 432 vm.vactive << CHN_SCREEN_H_SHIFT); 433 434 /* Configure channel interlace buffer control */ 435 zx_writel_mask(zcrtc->chnreg + CHN_INTERLACE_BUF_CTRL, CHN_INTERLACE_EN, 436 interlaced ? CHN_INTERLACE_EN : 0); 437 438 /* Update channel */ 439 vou_chn_set_update(zcrtc); 440 441 /* Enable channel */ 442 zx_writel_mask(zcrtc->chnreg + CHN_CTRL0, CHN_ENABLE, CHN_ENABLE); 443 444 drm_crtc_vblank_on(crtc); 445 446 ret = clk_set_rate(zcrtc->pixclk, mode->clock * 1000); 447 if (ret) { 448 DRM_DEV_ERROR(vou->dev, "failed to set pixclk rate: %d\n", ret); 449 return; 450 } 451 452 ret = clk_prepare_enable(zcrtc->pixclk); 453 if (ret) 454 DRM_DEV_ERROR(vou->dev, "failed to enable pixclk: %d\n", ret); 455} 456 457static void zx_crtc_atomic_disable(struct drm_crtc *crtc, 458 struct drm_crtc_state *old_state) 459{ 460 struct zx_crtc *zcrtc = to_zx_crtc(crtc); 461 const struct zx_crtc_bits *bits = zcrtc->bits; 462 struct zx_vou_hw *vou = zcrtc->vou; 463 464 clk_disable_unprepare(zcrtc->pixclk); 465 466 drm_crtc_vblank_off(crtc); 467 468 /* Disable channel */ 469 zx_writel_mask(zcrtc->chnreg + CHN_CTRL0, CHN_ENABLE, 0); 470 471 /* Disable TIMING_CTRL */ 472 zx_writel_mask(vou->timing + TIMING_TC_ENABLE, bits->tc_enable, 0); 473} 474 475static void zx_crtc_atomic_flush(struct drm_crtc *crtc, 476 struct drm_crtc_state *old_state) 477{ 478 struct drm_pending_vblank_event *event = crtc->state->event; 479 480 if (!event) 481 return; 482 483 crtc->state->event = NULL; 484 485 spin_lock_irq(&crtc->dev->event_lock); 486 if (drm_crtc_vblank_get(crtc) == 0) 487 drm_crtc_arm_vblank_event(crtc, event); 488 else 489 drm_crtc_send_vblank_event(crtc, event); 490 spin_unlock_irq(&crtc->dev->event_lock); 491} 492 493static const struct drm_crtc_helper_funcs zx_crtc_helper_funcs = { 494 .atomic_flush = zx_crtc_atomic_flush, 495 .atomic_enable = zx_crtc_atomic_enable, 496 .atomic_disable = zx_crtc_atomic_disable, 497}; 498 499static int zx_vou_enable_vblank(struct drm_crtc *crtc) 500{ 501 struct zx_crtc *zcrtc = to_zx_crtc(crtc); 502 struct zx_vou_hw *vou = crtc_to_vou(crtc); 503 u32 int_frame_mask = zcrtc->bits->int_frame_mask; 504 505 zx_writel_mask(vou->timing + TIMING_INT_CTRL, int_frame_mask, 506 int_frame_mask); 507 508 return 0; 509} 510 511static void zx_vou_disable_vblank(struct drm_crtc *crtc) 512{ 513 struct zx_crtc *zcrtc = to_zx_crtc(crtc); 514 struct zx_vou_hw *vou = crtc_to_vou(crtc); 515 516 zx_writel_mask(vou->timing + TIMING_INT_CTRL, 517 zcrtc->bits->int_frame_mask, 0); 518} 519 520static const struct drm_crtc_funcs zx_crtc_funcs = { 521 .destroy = drm_crtc_cleanup, 522 .set_config = drm_atomic_helper_set_config, 523 .page_flip = drm_atomic_helper_page_flip, 524 .reset = drm_atomic_helper_crtc_reset, 525 .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, 526 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, 527 .enable_vblank = zx_vou_enable_vblank, 528 .disable_vblank = zx_vou_disable_vblank, 529}; 530 531static int zx_crtc_init(struct drm_device *drm, struct zx_vou_hw *vou, 532 enum vou_chn_type chn_type) 533{ 534 struct device *dev = vou->dev; 535 struct zx_plane *zplane; 536 struct zx_crtc *zcrtc; 537 int ret; 538 539 zcrtc = devm_kzalloc(dev, sizeof(*zcrtc), GFP_KERNEL); 540 if (!zcrtc) 541 return -ENOMEM; 542 543 zcrtc->vou = vou; 544 zcrtc->chn_type = chn_type; 545 546 zplane = devm_kzalloc(dev, sizeof(*zplane), GFP_KERNEL); 547 if (!zplane) 548 return -ENOMEM; 549 550 zplane->dev = dev; 551 552 if (chn_type == VOU_CHN_MAIN) { 553 zplane->layer = vou->osd + MAIN_GL_OFFSET; 554 zplane->csc = vou->osd + MAIN_GL_CSC_OFFSET; 555 zplane->hbsc = vou->osd + MAIN_HBSC_OFFSET; 556 zplane->rsz = vou->otfppu + MAIN_RSZ_OFFSET; 557 zplane->bits = &zx_gl_bits[0]; 558 zcrtc->chnreg = vou->osd + OSD_MAIN_CHN; 559 zcrtc->chncsc = vou->osd + MAIN_CHN_CSC_OFFSET; 560 zcrtc->dither = vou->osd + MAIN_DITHER_OFFSET; 561 zcrtc->regs = &main_crtc_regs; 562 zcrtc->bits = &main_crtc_bits; 563 } else { 564 zplane->layer = vou->osd + AUX_GL_OFFSET; 565 zplane->csc = vou->osd + AUX_GL_CSC_OFFSET; 566 zplane->hbsc = vou->osd + AUX_HBSC_OFFSET; 567 zplane->rsz = vou->otfppu + AUX_RSZ_OFFSET; 568 zplane->bits = &zx_gl_bits[1]; 569 zcrtc->chnreg = vou->osd + OSD_AUX_CHN; 570 zcrtc->chncsc = vou->osd + AUX_CHN_CSC_OFFSET; 571 zcrtc->dither = vou->osd + AUX_DITHER_OFFSET; 572 zcrtc->regs = &aux_crtc_regs; 573 zcrtc->bits = &aux_crtc_bits; 574 } 575 576 zcrtc->pixclk = devm_clk_get(dev, (chn_type == VOU_CHN_MAIN) ? 577 "main_wclk" : "aux_wclk"); 578 if (IS_ERR(zcrtc->pixclk)) { 579 ret = PTR_ERR(zcrtc->pixclk); 580 DRM_DEV_ERROR(dev, "failed to get pix clk: %d\n", ret); 581 return ret; 582 } 583 584 ret = zx_plane_init(drm, zplane, DRM_PLANE_TYPE_PRIMARY); 585 if (ret) { 586 DRM_DEV_ERROR(dev, "failed to init primary plane: %d\n", ret); 587 return ret; 588 } 589 590 zcrtc->primary = &zplane->plane; 591 592 ret = drm_crtc_init_with_planes(drm, &zcrtc->crtc, zcrtc->primary, NULL, 593 &zx_crtc_funcs, NULL); 594 if (ret) { 595 DRM_DEV_ERROR(dev, "failed to init drm crtc: %d\n", ret); 596 return ret; 597 } 598 599 drm_crtc_helper_add(&zcrtc->crtc, &zx_crtc_helper_funcs); 600 601 if (chn_type == VOU_CHN_MAIN) 602 vou->main_crtc = zcrtc; 603 else 604 vou->aux_crtc = zcrtc; 605 606 return 0; 607} 608 609void zx_vou_layer_enable(struct drm_plane *plane) 610{ 611 struct zx_crtc *zcrtc = to_zx_crtc(plane->state->crtc); 612 struct zx_vou_hw *vou = zcrtc->vou; 613 struct zx_plane *zplane = to_zx_plane(plane); 614 const struct vou_layer_bits *bits = zplane->bits; 615 616 if (zcrtc->chn_type == VOU_CHN_MAIN) { 617 zx_writel_mask(vou->osd + OSD_CTRL0, bits->chnsel, 0); 618 zx_writel_mask(vou->vouctl + VOU_CLK_SEL, bits->clksel, 0); 619 } else { 620 zx_writel_mask(vou->osd + OSD_CTRL0, bits->chnsel, 621 bits->chnsel); 622 zx_writel_mask(vou->vouctl + VOU_CLK_SEL, bits->clksel, 623 bits->clksel); 624 } 625 626 zx_writel_mask(vou->osd + OSD_CTRL0, bits->enable, bits->enable); 627} 628 629void zx_vou_layer_disable(struct drm_plane *plane, 630 struct drm_plane_state *old_state) 631{ 632 struct zx_crtc *zcrtc = to_zx_crtc(old_state->crtc); 633 struct zx_vou_hw *vou = zcrtc->vou; 634 struct zx_plane *zplane = to_zx_plane(plane); 635 const struct vou_layer_bits *bits = zplane->bits; 636 637 zx_writel_mask(vou->osd + OSD_CTRL0, bits->enable, 0); 638} 639 640static void zx_overlay_init(struct drm_device *drm, struct zx_vou_hw *vou) 641{ 642 struct device *dev = vou->dev; 643 struct zx_plane *zplane; 644 int i; 645 int ret; 646 647 /* 648 * VL0 has some quirks on scaling support which need special handling. 649 * Let's leave it out for now. 650 */ 651 for (i = 1; i < VL_NUM; i++) { 652 zplane = devm_kzalloc(dev, sizeof(*zplane), GFP_KERNEL); 653 if (!zplane) { 654 DRM_DEV_ERROR(dev, "failed to allocate zplane %d\n", i); 655 return; 656 } 657 658 zplane->layer = vou->osd + OSD_VL_OFFSET(i); 659 zplane->hbsc = vou->osd + HBSC_VL_OFFSET(i); 660 zplane->rsz = vou->otfppu + RSZ_VL_OFFSET(i); 661 zplane->bits = &zx_vl_bits[i]; 662 663 ret = zx_plane_init(drm, zplane, DRM_PLANE_TYPE_OVERLAY); 664 if (ret) { 665 DRM_DEV_ERROR(dev, "failed to init overlay %d\n", i); 666 continue; 667 } 668 } 669} 670 671static inline void zx_osd_int_update(struct zx_crtc *zcrtc) 672{ 673 struct drm_crtc *crtc = &zcrtc->crtc; 674 struct drm_plane *plane; 675 676 vou_chn_set_update(zcrtc); 677 678 drm_for_each_plane_mask(plane, crtc->dev, crtc->state->plane_mask) 679 zx_plane_set_update(plane); 680} 681 682static irqreturn_t vou_irq_handler(int irq, void *dev_id) 683{ 684 struct zx_vou_hw *vou = dev_id; 685 u32 state; 686 687 /* Handle TIMING_CTRL frame interrupts */ 688 state = zx_readl(vou->timing + TIMING_INT_STATE); 689 zx_writel(vou->timing + TIMING_INT_STATE, state); 690 691 if (state & TIMING_INT_MAIN_FRAME) 692 drm_crtc_handle_vblank(&vou->main_crtc->crtc); 693 694 if (state & TIMING_INT_AUX_FRAME) 695 drm_crtc_handle_vblank(&vou->aux_crtc->crtc); 696 697 /* Handle OSD interrupts */ 698 state = zx_readl(vou->osd + OSD_INT_STA); 699 zx_writel(vou->osd + OSD_INT_CLRSTA, state); 700 701 if (state & OSD_INT_MAIN_UPT) 702 zx_osd_int_update(vou->main_crtc); 703 704 if (state & OSD_INT_AUX_UPT) 705 zx_osd_int_update(vou->aux_crtc); 706 707 if (state & OSD_INT_ERROR) 708 DRM_DEV_ERROR(vou->dev, "OSD ERROR: 0x%08x!\n", state); 709 710 return IRQ_HANDLED; 711} 712 713static void vou_dtrc_init(struct zx_vou_hw *vou) 714{ 715 /* Clear bit for bypass by ID */ 716 zx_writel_mask(vou->dtrc + DTRC_DETILE_CTRL, 717 TILE2RASTESCAN_BYPASS_MODE, 0); 718 719 /* Select ARIDR mode */ 720 zx_writel_mask(vou->dtrc + DTRC_DETILE_CTRL, DETILE_ARIDR_MODE_MASK, 721 DETILE_ARID_IN_ARIDR); 722 723 /* Bypass decompression for both frames */ 724 zx_writel_mask(vou->dtrc + DTRC_F0_CTRL, DTRC_DECOMPRESS_BYPASS, 725 DTRC_DECOMPRESS_BYPASS); 726 zx_writel_mask(vou->dtrc + DTRC_F1_CTRL, DTRC_DECOMPRESS_BYPASS, 727 DTRC_DECOMPRESS_BYPASS); 728 729 /* Set up ARID register */ 730 zx_writel(vou->dtrc + DTRC_ARID, DTRC_ARID3(0xf) | DTRC_ARID2(0xe) | 731 DTRC_ARID1(0xf) | DTRC_ARID0(0xe)); 732} 733 734static void vou_hw_init(struct zx_vou_hw *vou) 735{ 736 /* Release reset for all VOU modules */ 737 zx_writel(vou->vouctl + VOU_SOFT_RST, ~0); 738 739 /* Enable all VOU module clocks */ 740 zx_writel(vou->vouctl + VOU_CLK_EN, ~0); 741 742 /* Clear both OSD and TIMING_CTRL interrupt state */ 743 zx_writel(vou->osd + OSD_INT_CLRSTA, ~0); 744 zx_writel(vou->timing + TIMING_INT_STATE, ~0); 745 746 /* Enable OSD and TIMING_CTRL interrrupts */ 747 zx_writel(vou->osd + OSD_INT_MSK, OSD_INT_ENABLE); 748 zx_writel(vou->timing + TIMING_INT_CTRL, TIMING_INT_ENABLE); 749 750 /* Select GPC as input to gl/vl scaler as a sane default setting */ 751 zx_writel(vou->otfppu + OTFPPU_RSZ_DATA_SOURCE, 0x2a); 752 753 /* 754 * Needs to reset channel and layer logic per frame when frame starts 755 * to get VOU work properly. 756 */ 757 zx_writel_mask(vou->osd + OSD_RST_CLR, RST_PER_FRAME, RST_PER_FRAME); 758 759 vou_dtrc_init(vou); 760} 761 762static int zx_crtc_bind(struct device *dev, struct device *master, void *data) 763{ 764 struct platform_device *pdev = to_platform_device(dev); 765 struct drm_device *drm = data; 766 struct zx_vou_hw *vou; 767 struct resource *res; 768 int irq; 769 int ret; 770 771 vou = devm_kzalloc(dev, sizeof(*vou), GFP_KERNEL); 772 if (!vou) 773 return -ENOMEM; 774 775 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "osd"); 776 vou->osd = devm_ioremap_resource(dev, res); 777 if (IS_ERR(vou->osd)) { 778 ret = PTR_ERR(vou->osd); 779 DRM_DEV_ERROR(dev, "failed to remap osd region: %d\n", ret); 780 return ret; 781 } 782 783 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "timing_ctrl"); 784 vou->timing = devm_ioremap_resource(dev, res); 785 if (IS_ERR(vou->timing)) { 786 ret = PTR_ERR(vou->timing); 787 DRM_DEV_ERROR(dev, "failed to remap timing_ctrl region: %d\n", 788 ret); 789 return ret; 790 } 791 792 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dtrc"); 793 vou->dtrc = devm_ioremap_resource(dev, res); 794 if (IS_ERR(vou->dtrc)) { 795 ret = PTR_ERR(vou->dtrc); 796 DRM_DEV_ERROR(dev, "failed to remap dtrc region: %d\n", ret); 797 return ret; 798 } 799 800 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vou_ctrl"); 801 vou->vouctl = devm_ioremap_resource(dev, res); 802 if (IS_ERR(vou->vouctl)) { 803 ret = PTR_ERR(vou->vouctl); 804 DRM_DEV_ERROR(dev, "failed to remap vou_ctrl region: %d\n", 805 ret); 806 return ret; 807 } 808 809 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otfppu"); 810 vou->otfppu = devm_ioremap_resource(dev, res); 811 if (IS_ERR(vou->otfppu)) { 812 ret = PTR_ERR(vou->otfppu); 813 DRM_DEV_ERROR(dev, "failed to remap otfppu region: %d\n", ret); 814 return ret; 815 } 816 817 irq = platform_get_irq(pdev, 0); 818 if (irq < 0) 819 return irq; 820 821 vou->axi_clk = devm_clk_get(dev, "aclk"); 822 if (IS_ERR(vou->axi_clk)) { 823 ret = PTR_ERR(vou->axi_clk); 824 DRM_DEV_ERROR(dev, "failed to get axi_clk: %d\n", ret); 825 return ret; 826 } 827 828 vou->ppu_clk = devm_clk_get(dev, "ppu_wclk"); 829 if (IS_ERR(vou->ppu_clk)) { 830 ret = PTR_ERR(vou->ppu_clk); 831 DRM_DEV_ERROR(dev, "failed to get ppu_clk: %d\n", ret); 832 return ret; 833 } 834 835 ret = clk_prepare_enable(vou->axi_clk); 836 if (ret) { 837 DRM_DEV_ERROR(dev, "failed to enable axi_clk: %d\n", ret); 838 return ret; 839 } 840 841 clk_prepare_enable(vou->ppu_clk); 842 if (ret) { 843 DRM_DEV_ERROR(dev, "failed to enable ppu_clk: %d\n", ret); 844 goto disable_axi_clk; 845 } 846 847 vou->dev = dev; 848 dev_set_drvdata(dev, vou); 849 850 vou_hw_init(vou); 851 852 ret = devm_request_irq(dev, irq, vou_irq_handler, 0, "zx_vou", vou); 853 if (ret < 0) { 854 DRM_DEV_ERROR(dev, "failed to request vou irq: %d\n", ret); 855 goto disable_ppu_clk; 856 } 857 858 ret = zx_crtc_init(drm, vou, VOU_CHN_MAIN); 859 if (ret) { 860 DRM_DEV_ERROR(dev, "failed to init main channel crtc: %d\n", 861 ret); 862 goto disable_ppu_clk; 863 } 864 865 ret = zx_crtc_init(drm, vou, VOU_CHN_AUX); 866 if (ret) { 867 DRM_DEV_ERROR(dev, "failed to init aux channel crtc: %d\n", 868 ret); 869 goto disable_ppu_clk; 870 } 871 872 zx_overlay_init(drm, vou); 873 874 return 0; 875 876disable_ppu_clk: 877 clk_disable_unprepare(vou->ppu_clk); 878disable_axi_clk: 879 clk_disable_unprepare(vou->axi_clk); 880 return ret; 881} 882 883static void zx_crtc_unbind(struct device *dev, struct device *master, 884 void *data) 885{ 886 struct zx_vou_hw *vou = dev_get_drvdata(dev); 887 888 clk_disable_unprepare(vou->axi_clk); 889 clk_disable_unprepare(vou->ppu_clk); 890} 891 892static const struct component_ops zx_crtc_component_ops = { 893 .bind = zx_crtc_bind, 894 .unbind = zx_crtc_unbind, 895}; 896 897static int zx_crtc_probe(struct platform_device *pdev) 898{ 899 return component_add(&pdev->dev, &zx_crtc_component_ops); 900} 901 902static int zx_crtc_remove(struct platform_device *pdev) 903{ 904 component_del(&pdev->dev, &zx_crtc_component_ops); 905 return 0; 906} 907 908static const struct of_device_id zx_crtc_of_match[] = { 909 { .compatible = "zte,zx296718-dpc", }, 910 { /* end */ }, 911}; 912MODULE_DEVICE_TABLE(of, zx_crtc_of_match); 913 914struct platform_driver zx_crtc_driver = { 915 .probe = zx_crtc_probe, 916 .remove = zx_crtc_remove, 917 .driver = { 918 .name = "zx-crtc", 919 .of_match_table = zx_crtc_of_match, 920 }, 921}; 922