@@ -38,22 +38,13 @@ static void rcar_lvds_write(struct rcar_du_lvdsenc *lvds, u32 reg, u32 data)
38
38
iowrite32 (data , lvds -> mmio + reg );
39
39
}
40
40
41
- static int rcar_du_lvdsenc_start (struct rcar_du_lvdsenc * lvds ,
42
- struct rcar_du_crtc * rcrtc )
41
+ static void rcar_du_lvdsenc_start_gen2 (struct rcar_du_lvdsenc * lvds ,
42
+ struct rcar_du_crtc * rcrtc )
43
43
{
44
44
const struct drm_display_mode * mode = & rcrtc -> crtc .mode ;
45
45
unsigned int freq = mode -> clock ;
46
46
u32 lvdcr0 ;
47
- u32 lvdhcr ;
48
47
u32 pllcr ;
49
- int ret ;
50
-
51
- if (lvds -> enabled )
52
- return 0 ;
53
-
54
- ret = clk_prepare_enable (lvds -> clock );
55
- if (ret < 0 )
56
- return ret ;
57
48
58
49
/* PLL clock configuration */
59
50
if (freq < 39000 )
@@ -67,26 +58,6 @@ static int rcar_du_lvdsenc_start(struct rcar_du_lvdsenc *lvds,
67
58
68
59
rcar_lvds_write (lvds , LVDPLLCR , pllcr );
69
60
70
- /* Hardcode the channels and control signals routing for now.
71
- *
72
- * HSYNC -> CTRL0
73
- * VSYNC -> CTRL1
74
- * DISP -> CTRL2
75
- * 0 -> CTRL3
76
- */
77
- rcar_lvds_write (lvds , LVDCTRCR , LVDCTRCR_CTR3SEL_ZERO |
78
- LVDCTRCR_CTR2SEL_DISP | LVDCTRCR_CTR1SEL_VSYNC |
79
- LVDCTRCR_CTR0SEL_HSYNC );
80
-
81
- if (rcar_du_needs (lvds -> dev , RCAR_DU_QUIRK_LVDS_LANES ))
82
- lvdhcr = LVDCHCR_CHSEL_CH (0 , 0 ) | LVDCHCR_CHSEL_CH (1 , 3 )
83
- | LVDCHCR_CHSEL_CH (2 , 2 ) | LVDCHCR_CHSEL_CH (3 , 1 );
84
- else
85
- lvdhcr = LVDCHCR_CHSEL_CH (0 , 0 ) | LVDCHCR_CHSEL_CH (1 , 1 )
86
- | LVDCHCR_CHSEL_CH (2 , 2 ) | LVDCHCR_CHSEL_CH (3 , 3 );
87
-
88
- rcar_lvds_write (lvds , LVDCHCR , lvdhcr );
89
-
90
61
/* Select the input, hardcode mode 0, enable LVDS operation and turn
91
62
* bias circuitry on.
92
63
*/
@@ -96,8 +67,10 @@ static int rcar_du_lvdsenc_start(struct rcar_du_lvdsenc *lvds,
96
67
rcar_lvds_write (lvds , LVDCR0 , lvdcr0 );
97
68
98
69
/* Turn all the channels on. */
99
- rcar_lvds_write (lvds , LVDCR1 , LVDCR1_CHSTBY (3 ) | LVDCR1_CHSTBY (2 ) |
100
- LVDCR1_CHSTBY (1 ) | LVDCR1_CHSTBY (0 ) | LVDCR1_CLKSTBY );
70
+ rcar_lvds_write (lvds , LVDCR1 ,
71
+ LVDCR1_CHSTBY_GEN2 (3 ) | LVDCR1_CHSTBY_GEN2 (2 ) |
72
+ LVDCR1_CHSTBY_GEN2 (1 ) | LVDCR1_CHSTBY_GEN2 (0 ) |
73
+ LVDCR1_CLKSTBY_GEN2 );
101
74
102
75
/* Turn the PLL on, wait for the startup delay, and turn the output
103
76
* on.
@@ -109,8 +82,90 @@ static int rcar_du_lvdsenc_start(struct rcar_du_lvdsenc *lvds,
109
82
110
83
lvdcr0 |= LVDCR0_LVRES ;
111
84
rcar_lvds_write (lvds , LVDCR0 , lvdcr0 );
85
+ }
86
+
87
+ static void rcar_du_lvdsenc_start_gen3 (struct rcar_du_lvdsenc * lvds ,
88
+ struct rcar_du_crtc * rcrtc )
89
+ {
90
+ const struct drm_display_mode * mode = & rcrtc -> crtc .mode ;
91
+ unsigned int freq = mode -> clock ;
92
+ u32 lvdcr0 ;
93
+ u32 pllcr ;
94
+
95
+ /* PLL clock configuration */
96
+ if (freq < 42000 )
97
+ pllcr = LVDPLLCR_PLLDIVCNT_42M ;
98
+ else if (freq < 85000 )
99
+ pllcr = LVDPLLCR_PLLDIVCNT_85M ;
100
+ else if (freq < 128000 )
101
+ pllcr = LVDPLLCR_PLLDIVCNT_128M ;
102
+ else
103
+ pllcr = LVDPLLCR_PLLDIVCNT_148M ;
104
+
105
+ rcar_lvds_write (lvds , LVDPLLCR , pllcr );
106
+
107
+ /* Turn the PLL on, set it to LVDS normal mode, wait for the startup
108
+ * delay and turn the output on.
109
+ */
110
+ lvdcr0 = LVDCR0_PLLON ;
111
+ rcar_lvds_write (lvds , LVDCR0 , lvdcr0 );
112
+
113
+ lvdcr0 |= LVDCR0_PWD ;
114
+ rcar_lvds_write (lvds , LVDCR0 , lvdcr0 );
115
+
116
+ usleep_range (100 , 150 );
117
+
118
+ lvdcr0 |= LVDCR0_LVRES ;
119
+ rcar_lvds_write (lvds , LVDCR0 , lvdcr0 );
120
+
121
+ /* Turn all the channels on. */
122
+ rcar_lvds_write (lvds , LVDCR1 ,
123
+ LVDCR1_CHSTBY_GEN3 (3 ) | LVDCR1_CHSTBY_GEN3 (2 ) |
124
+ LVDCR1_CHSTBY_GEN3 (1 ) | LVDCR1_CHSTBY_GEN3 (0 ) |
125
+ LVDCR1_CLKSTBY_GEN3 );
126
+ }
127
+
128
+ static int rcar_du_lvdsenc_start (struct rcar_du_lvdsenc * lvds ,
129
+ struct rcar_du_crtc * rcrtc )
130
+ {
131
+ u32 lvdhcr ;
132
+ int ret ;
133
+
134
+ if (lvds -> enabled )
135
+ return 0 ;
136
+
137
+ ret = clk_prepare_enable (lvds -> clock );
138
+ if (ret < 0 )
139
+ return ret ;
140
+
141
+ /* Hardcode the channels and control signals routing for now.
142
+ *
143
+ * HSYNC -> CTRL0
144
+ * VSYNC -> CTRL1
145
+ * DISP -> CTRL2
146
+ * 0 -> CTRL3
147
+ */
148
+ rcar_lvds_write (lvds , LVDCTRCR , LVDCTRCR_CTR3SEL_ZERO |
149
+ LVDCTRCR_CTR2SEL_DISP | LVDCTRCR_CTR1SEL_VSYNC |
150
+ LVDCTRCR_CTR0SEL_HSYNC );
151
+
152
+ if (rcar_du_needs (lvds -> dev , RCAR_DU_QUIRK_LVDS_LANES ))
153
+ lvdhcr = LVDCHCR_CHSEL_CH (0 , 0 ) | LVDCHCR_CHSEL_CH (1 , 3 )
154
+ | LVDCHCR_CHSEL_CH (2 , 2 ) | LVDCHCR_CHSEL_CH (3 , 1 );
155
+ else
156
+ lvdhcr = LVDCHCR_CHSEL_CH (0 , 0 ) | LVDCHCR_CHSEL_CH (1 , 1 )
157
+ | LVDCHCR_CHSEL_CH (2 , 2 ) | LVDCHCR_CHSEL_CH (3 , 3 );
158
+
159
+ rcar_lvds_write (lvds , LVDCHCR , lvdhcr );
160
+
161
+ /* Perform generation-specific initialization. */
162
+ if (lvds -> dev -> info -> gen < 3 )
163
+ rcar_du_lvdsenc_start_gen2 (lvds , rcrtc );
164
+ else
165
+ rcar_du_lvdsenc_start_gen3 (lvds , rcrtc );
112
166
113
167
lvds -> enabled = true;
168
+
114
169
return 0 ;
115
170
}
116
171
@@ -143,10 +198,16 @@ int rcar_du_lvdsenc_enable(struct rcar_du_lvdsenc *lvds, struct drm_crtc *crtc,
143
198
void rcar_du_lvdsenc_atomic_check (struct rcar_du_lvdsenc * lvds ,
144
199
struct drm_display_mode * mode )
145
200
{
146
- /* The internal LVDS encoder has a clock frequency operating range of
147
- * 30MHz to 150MHz. Clamp the clock accordingly.
201
+ struct rcar_du_device * rcdu = lvds -> dev ;
202
+
203
+ /* The internal LVDS encoder has a restricted clock frequency operating
204
+ * range (30MHz to 150MHz on Gen2, 25.175MHz to 148.5MHz on Gen3). Clamp
205
+ * the clock accordingly.
148
206
*/
149
- mode -> clock = clamp (mode -> clock , 30000 , 150000 );
207
+ if (rcdu -> info -> gen < 3 )
208
+ mode -> clock = clamp (mode -> clock , 30000 , 150000 );
209
+ else
210
+ mode -> clock = clamp (mode -> clock , 25175 , 148500 );
150
211
}
151
212
152
213
static int rcar_du_lvdsenc_get_resources (struct rcar_du_lvdsenc * lvds ,
0 commit comments