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_init(struct armada_private
*priv
, struct device
*dev
)
20 priv
->extclk
[0] = devm_clk_get(dev
, "ext_ref_clk_1");
22 if (IS_ERR(priv
->extclk
[0]) && PTR_ERR(priv
->extclk
[0]) == -ENOENT
)
23 priv
->extclk
[0] = ERR_PTR(-EPROBE_DEFER
);
25 return PTR_RET(priv
->extclk
[0]);
28 static int armada510_crtc_init(struct armada_crtc
*dcrtc
)
30 /* Lower the watermark so to eliminate jitter at higher bandwidths */
31 armada_updatel(0x20, (1 << 11) | 0xff, dcrtc
->base
+ LCD_CFG_RDREG4F
);
36 * Armada510 specific SCLK register selection.
37 * This gets called with sclk = NULL to test whether the mode is
38 * supportable, and again with sclk != NULL to set the clocks up for
39 * that. The former can return an error, but the latter is expected
42 * We currently are pretty rudimentary here, always selecting
43 * EXT_REF_CLK_1 for LCD0 and erroring LCD1. This needs improvement!
45 static int armada510_crtc_compute_clock(struct armada_crtc
*dcrtc
,
46 const struct drm_display_mode
*mode
, uint32_t *sclk
)
48 struct armada_private
*priv
= dcrtc
->crtc
.dev
->dev_private
;
49 struct clk
*clk
= priv
->extclk
[0];
58 if (dcrtc
->clk
!= clk
) {
59 ret
= clk_prepare_enable(clk
);
66 uint32_t rate
, ref
, div
;
68 rate
= mode
->clock
* 1000;
69 ref
= clk_round_rate(clk
, rate
);
70 div
= DIV_ROUND_UP(ref
, rate
);
74 clk_set_rate(clk
, ref
);
75 *sclk
= div
| SCLK_510_EXTCLK1
;
81 const struct armada_variant armada510_ops
= {
82 .has_spu_adv_reg
= true,
83 .spu_adv_reg
= ADV_HWC32ENABLE
| ADV_HWC32ARGB
| ADV_HWC32BLEND
,
84 .init
= armada510_init
,
85 .crtc_init
= armada510_crtc_init
,
86 .crtc_compute_clock
= armada510_crtc_compute_clock
,