2 * Copyright (C) 2012 Russell King
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
8 * Armada 510 (aka Dove) variant support
10 #include <linux/clk.h>
13 #include <drm/drm_crtc_helper.h>
14 #include "armada_crtc.h"
15 #include "armada_drm.h"
16 #include "armada_hw.h"
18 static int armada510_crtc_init(struct armada_crtc
*dcrtc
, struct device
*dev
)
22 clk
= devm_clk_get(dev
, "ext_ref_clk1");
24 return PTR_ERR(clk
) == -ENOENT
? -EPROBE_DEFER
: PTR_ERR(clk
);
26 dcrtc
->extclk
[0] = clk
;
28 /* Lower the watermark so to eliminate jitter at higher bandwidths */
29 armada_updatel(0x20, (1 << 11) | 0xff, dcrtc
->base
+ LCD_CFG_RDREG4F
);
35 * Armada510 specific SCLK register selection.
36 * This gets called with sclk = NULL to test whether the mode is
37 * supportable, and again with sclk != NULL to set the clocks up for
38 * that. The former can return an error, but the latter is expected
41 * We currently are pretty rudimentary here, always selecting
42 * EXT_REF_CLK_1 for LCD0 and erroring LCD1. This needs improvement!
44 static int armada510_crtc_compute_clock(struct armada_crtc
*dcrtc
,
45 const struct drm_display_mode
*mode
, uint32_t *sclk
)
47 struct clk
*clk
= dcrtc
->extclk
[0];
56 if (dcrtc
->clk
!= clk
) {
57 ret
= clk_prepare_enable(clk
);
64 uint32_t rate
, ref
, div
;
66 rate
= mode
->clock
* 1000;
67 ref
= clk_round_rate(clk
, rate
);
68 div
= DIV_ROUND_UP(ref
, rate
);
72 clk_set_rate(clk
, ref
);
73 *sclk
= div
| SCLK_510_EXTCLK1
;
79 const struct armada_variant armada510_ops
= {
80 .has_spu_adv_reg
= true,
81 .spu_adv_reg
= ADV_HWC32ENABLE
| ADV_HWC32ARGB
| ADV_HWC32BLEND
,
82 .init
= armada510_crtc_init
,
83 .compute_clock
= armada510_crtc_compute_clock
,