2222#define HW_REV 0x0
2323#define HW_INTR_STATUS 0x0010
2424
25+ #define UBWC_DEC_HW_VERSION 0x58
2526#define UBWC_STATIC 0x144
2627#define UBWC_CTRL_2 0x150
2728#define UBWC_PREDICTION_MODE 0x154
@@ -174,9 +175,63 @@ static int _msm_mdss_irq_domain_add(struct msm_mdss *msm_mdss)
174175 return 0 ;
175176}
176177
178+ #define UBWC_1_0 0x10000000
179+ #define UBWC_2_0 0x20000000
180+ #define UBWC_3_0 0x30000000
181+ #define UBWC_4_0 0x40000000
182+
183+ static void msm_mdss_setup_ubwc_dec_20 (struct msm_mdss * msm_mdss ,
184+ u32 ubwc_static )
185+ {
186+ writel_relaxed (ubwc_static , msm_mdss -> mmio + UBWC_STATIC );
187+ }
188+
189+ static void msm_mdss_setup_ubwc_dec_30 (struct msm_mdss * msm_mdss ,
190+ unsigned int ubwc_version ,
191+ u32 ubwc_swizzle ,
192+ u32 highest_bank_bit ,
193+ u32 macrotile_mode )
194+ {
195+ u32 value = (ubwc_swizzle & 0x1 ) |
196+ (highest_bank_bit & 0x3 ) << 4 |
197+ (macrotile_mode & 0x1 ) << 12 ;
198+
199+ if (ubwc_version == UBWC_3_0 )
200+ value |= BIT (10 );
201+
202+ if (ubwc_version == UBWC_1_0 )
203+ value |= BIT (8 );
204+
205+ writel_relaxed (value , msm_mdss -> mmio + UBWC_STATIC );
206+ }
207+
208+ static void msm_mdss_setup_ubwc_dec_40 (struct msm_mdss * msm_mdss ,
209+ unsigned int ubwc_version ,
210+ u32 ubwc_swizzle ,
211+ u32 ubwc_static ,
212+ u32 highest_bank_bit ,
213+ u32 macrotile_mode )
214+ {
215+ u32 value = (ubwc_swizzle & 0x7 ) |
216+ (ubwc_static & 0x1 ) << 3 |
217+ (highest_bank_bit & 0x7 ) << 4 |
218+ (macrotile_mode & 0x1 ) << 12 ;
219+
220+ writel_relaxed (value , msm_mdss -> mmio + UBWC_STATIC );
221+
222+ if (ubwc_version == UBWC_3_0 ) {
223+ writel_relaxed (1 , msm_mdss -> mmio + UBWC_CTRL_2 );
224+ writel_relaxed (0 , msm_mdss -> mmio + UBWC_PREDICTION_MODE );
225+ } else {
226+ writel_relaxed (2 , msm_mdss -> mmio + UBWC_CTRL_2 );
227+ writel_relaxed (1 , msm_mdss -> mmio + UBWC_PREDICTION_MODE );
228+ }
229+ }
230+
177231static int msm_mdss_enable (struct msm_mdss * msm_mdss )
178232{
179233 int ret ;
234+ u32 hw_rev ;
180235
181236 /*
182237 * Several components have AXI clocks that can only be turned on if
@@ -198,26 +253,35 @@ static int msm_mdss_enable(struct msm_mdss *msm_mdss)
198253 if (msm_mdss -> is_mdp5 )
199254 return 0 ;
200255
256+ hw_rev = readl_relaxed (msm_mdss -> mmio + HW_REV );
257+ dev_dbg (msm_mdss -> dev , "HW_REV: 0x%x\n" , hw_rev );
258+ dev_dbg (msm_mdss -> dev , "UBWC_DEC_HW_VERSION: 0x%x\n" ,
259+ readl_relaxed (msm_mdss -> mmio + UBWC_DEC_HW_VERSION ));
260+
201261 /*
202262 * ubwc config is part of the "mdss" region which is not accessible
203263 * from the rest of the driver. hardcode known configurations here
264+ *
265+ * Decoder version can be read from the UBWC_DEC_HW_VERSION reg,
266+ * UBWC_n and the rest of params comes from hw_catalog.
267+ * Unforunately this driver can not access hw catalog, so we have to
268+ * hardcode them here.
204269 */
205- switch (readl_relaxed ( msm_mdss -> mmio + HW_REV ) ) {
270+ switch (hw_rev ) {
206271 case DPU_HW_VER_500 :
207272 case DPU_HW_VER_501 :
208- writel_relaxed ( 0x420 , msm_mdss -> mmio + UBWC_STATIC );
273+ msm_mdss_setup_ubwc_dec_30 ( msm_mdss , UBWC_3_0 , 0 , 2 , 0 );
209274 break ;
210275 case DPU_HW_VER_600 :
211- /* TODO: 0x102e for LP_DDR4 */
212- writel_relaxed (0x103e , msm_mdss -> mmio + UBWC_STATIC );
213- writel_relaxed (2 , msm_mdss -> mmio + UBWC_CTRL_2 );
214- writel_relaxed (1 , msm_mdss -> mmio + UBWC_PREDICTION_MODE );
276+ /* TODO: highest_bank_bit = 2 for LP_DDR4 */
277+ msm_mdss_setup_ubwc_dec_40 (msm_mdss , UBWC_4_0 , 6 , 1 , 3 , 1 );
215278 break ;
216279 case DPU_HW_VER_620 :
217- writel_relaxed (0x1e , msm_mdss -> mmio + UBWC_STATIC );
280+ /* UBWC_2_0 */
281+ msm_mdss_setup_ubwc_dec_20 (msm_mdss , 0x1e );
218282 break ;
219283 case DPU_HW_VER_720 :
220- writel_relaxed ( 0x101e , msm_mdss -> mmio + UBWC_STATIC );
284+ msm_mdss_setup_ubwc_dec_40 ( msm_mdss , UBWC_3_0 , 6 , 1 , 1 , 1 );
221285 break ;
222286 }
223287
0 commit comments