Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * R-Car Display Unit Channels Pair
0004  *
0005  * Copyright (C) 2013-2015 Renesas Electronics Corporation
0006  *
0007  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
0008  */
0009 
0010 /*
0011  * The R8A7779 DU is split in per-CRTC resources (scan-out engine, blending
0012  * unit, timings generator, ...) and device-global resources (start/stop
0013  * control, planes, ...) shared between the two CRTCs.
0014  *
0015  * The R8A7790 introduced a third CRTC with its own set of global resources.
0016  * This would be modeled as two separate DU device instances if it wasn't for
0017  * a handful or resources that are shared between the three CRTCs (mostly
0018  * related to input and output routing). For this reason the R8A7790 DU must be
0019  * modeled as a single device with three CRTCs, two sets of "semi-global"
0020  * resources, and a few device-global resources.
0021  *
0022  * The rcar_du_group object is a driver specific object, without any real
0023  * counterpart in the DU documentation, that models those semi-global resources.
0024  */
0025 
0026 #include <linux/clk.h>
0027 #include <linux/io.h>
0028 
0029 #include "rcar_du_drv.h"
0030 #include "rcar_du_group.h"
0031 #include "rcar_du_regs.h"
0032 
0033 u32 rcar_du_group_read(struct rcar_du_group *rgrp, u32 reg)
0034 {
0035     return rcar_du_read(rgrp->dev, rgrp->mmio_offset + reg);
0036 }
0037 
0038 void rcar_du_group_write(struct rcar_du_group *rgrp, u32 reg, u32 data)
0039 {
0040     rcar_du_write(rgrp->dev, rgrp->mmio_offset + reg, data);
0041 }
0042 
0043 static void rcar_du_group_setup_pins(struct rcar_du_group *rgrp)
0044 {
0045     u32 defr6 = DEFR6_CODE;
0046 
0047     if (rgrp->channels_mask & BIT(0))
0048         defr6 |= DEFR6_ODPM02_DISP;
0049 
0050     if (rgrp->channels_mask & BIT(1))
0051         defr6 |= DEFR6_ODPM12_DISP;
0052 
0053     rcar_du_group_write(rgrp, DEFR6, defr6);
0054 }
0055 
0056 static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
0057 {
0058     struct rcar_du_device *rcdu = rgrp->dev;
0059     u32 defr8 = DEFR8_CODE;
0060 
0061     if (rcdu->info->gen < 3) {
0062         defr8 |= DEFR8_DEFE8;
0063 
0064         /*
0065          * On Gen2 the DEFR8 register for the first group also controls
0066          * RGB output routing to DPAD0 and VSPD1 routing to DU0/1/2 for
0067          * DU instances that support it.
0068          */
0069         if (rgrp->index == 0) {
0070             defr8 |= DEFR8_DRGBS_DU(rcdu->dpad0_source);
0071             if (rgrp->dev->vspd1_sink == 2)
0072                 defr8 |= DEFR8_VSCS;
0073         }
0074     } else {
0075         /*
0076          * On Gen3 VSPD routing can't be configured, and DPAD routing
0077          * is set in the group corresponding to the DPAD output (no Gen3
0078          * SoC has multiple DPAD sources belonging to separate groups).
0079          */
0080         if (rgrp->index == rcdu->dpad0_source / 2)
0081             defr8 |= DEFR8_DRGBS_DU(rcdu->dpad0_source);
0082     }
0083 
0084     rcar_du_group_write(rgrp, DEFR8, defr8);
0085 }
0086 
0087 static void rcar_du_group_setup_didsr(struct rcar_du_group *rgrp)
0088 {
0089     struct rcar_du_device *rcdu = rgrp->dev;
0090     struct rcar_du_crtc *rcrtc;
0091     unsigned int num_crtcs = 0;
0092     unsigned int i;
0093     u32 didsr;
0094 
0095     /*
0096      * Configure input dot clock routing with a hardcoded configuration. If
0097      * the DU channel can use the LVDS encoder output clock as the dot
0098      * clock, do so. Otherwise route DU_DOTCLKINn signal to DUn.
0099      *
0100      * Each channel can then select between the dot clock configured here
0101      * and the clock provided by the CPG through the ESCR register.
0102      */
0103     if (rcdu->info->gen < 3 && rgrp->index == 0) {
0104         /*
0105          * On Gen2 a single register in the first group controls dot
0106          * clock selection for all channels.
0107          */
0108         rcrtc = rcdu->crtcs;
0109         num_crtcs = rcdu->num_crtcs;
0110     } else if (rcdu->info->gen == 3 && rgrp->num_crtcs > 1) {
0111         /*
0112          * On Gen3 dot clocks are setup through per-group registers,
0113          * only available when the group has two channels.
0114          */
0115         rcrtc = &rcdu->crtcs[rgrp->index * 2];
0116         num_crtcs = rgrp->num_crtcs;
0117     }
0118 
0119     if (!num_crtcs)
0120         return;
0121 
0122     didsr = DIDSR_CODE;
0123     for (i = 0; i < num_crtcs; ++i, ++rcrtc) {
0124         if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index))
0125             didsr |= DIDSR_LDCS_LVDS0(i)
0126                   |  DIDSR_PDCS_CLK(i, 0);
0127         else if (rcdu->info->dsi_clk_mask & BIT(rcrtc->index))
0128             didsr |= DIDSR_LDCS_DSI(i);
0129         else
0130             didsr |= DIDSR_LDCS_DCLKIN(i)
0131                   |  DIDSR_PDCS_CLK(i, 0);
0132     }
0133 
0134     rcar_du_group_write(rgrp, DIDSR, didsr);
0135 }
0136 
0137 static void rcar_du_group_setup(struct rcar_du_group *rgrp)
0138 {
0139     struct rcar_du_device *rcdu = rgrp->dev;
0140     u32 defr7 = DEFR7_CODE;
0141 
0142     /* Enable extended features */
0143     rcar_du_group_write(rgrp, DEFR, DEFR_CODE | DEFR_DEFE);
0144     if (rcdu->info->gen < 3) {
0145         rcar_du_group_write(rgrp, DEFR2, DEFR2_CODE | DEFR2_DEFE2G);
0146         rcar_du_group_write(rgrp, DEFR3, DEFR3_CODE | DEFR3_DEFE3);
0147         rcar_du_group_write(rgrp, DEFR4, DEFR4_CODE);
0148     }
0149     rcar_du_group_write(rgrp, DEFR5, DEFR5_CODE | DEFR5_DEFE5);
0150 
0151     rcar_du_group_setup_pins(rgrp);
0152 
0153     /*
0154      * TODO: Handle routing of the DU output to CMM dynamically, as we
0155      * should bypass CMM completely when no color management feature is
0156      * used.
0157      */
0158     defr7 |= (rgrp->cmms_mask & BIT(1) ? DEFR7_CMME1 : 0) |
0159          (rgrp->cmms_mask & BIT(0) ? DEFR7_CMME0 : 0);
0160     rcar_du_group_write(rgrp, DEFR7, defr7);
0161 
0162     if (rcdu->info->gen >= 2) {
0163         rcar_du_group_setup_defr8(rgrp);
0164         rcar_du_group_setup_didsr(rgrp);
0165     }
0166 
0167     if (rcdu->info->gen >= 3)
0168         rcar_du_group_write(rgrp, DEFR10, DEFR10_CODE | DEFR10_DEFE10);
0169 
0170     /*
0171      * Use DS1PR and DS2PR to configure planes priorities and connects the
0172      * superposition 0 to DU0 pins. DU1 pins will be configured dynamically.
0173      */
0174     rcar_du_group_write(rgrp, DORCR, DORCR_PG1D_DS1 | DORCR_DPRS);
0175 
0176     /* Apply planes to CRTCs association. */
0177     mutex_lock(&rgrp->lock);
0178     rcar_du_group_write(rgrp, DPTSR, (rgrp->dptsr_planes << 16) |
0179                 rgrp->dptsr_planes);
0180     mutex_unlock(&rgrp->lock);
0181 }
0182 
0183 /*
0184  * rcar_du_group_get - Acquire a reference to the DU channels group
0185  *
0186  * Acquiring the first reference setups core registers. A reference must be held
0187  * before accessing any hardware registers.
0188  *
0189  * This function must be called with the DRM mode_config lock held.
0190  *
0191  * Return 0 in case of success or a negative error code otherwise.
0192  */
0193 int rcar_du_group_get(struct rcar_du_group *rgrp)
0194 {
0195     if (rgrp->use_count)
0196         goto done;
0197 
0198     rcar_du_group_setup(rgrp);
0199 
0200 done:
0201     rgrp->use_count++;
0202     return 0;
0203 }
0204 
0205 /*
0206  * rcar_du_group_put - Release a reference to the DU
0207  *
0208  * This function must be called with the DRM mode_config lock held.
0209  */
0210 void rcar_du_group_put(struct rcar_du_group *rgrp)
0211 {
0212     --rgrp->use_count;
0213 }
0214 
0215 static void __rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
0216 {
0217     struct rcar_du_device *rcdu = rgrp->dev;
0218 
0219     /*
0220      * Group start/stop is controlled by the DRES and DEN bits of DSYSR0
0221      * for the first group and DSYSR2 for the second group. On most DU
0222      * instances, this maps to the first CRTC of the group, and we can just
0223      * use rcar_du_crtc_dsysr_clr_set() to access the correct DSYSR. On
0224      * M3-N, however, DU2 doesn't exist, but DSYSR2 does. We thus need to
0225      * access the register directly using group read/write.
0226      */
0227     if (rcdu->info->channels_mask & BIT(rgrp->index * 2)) {
0228         struct rcar_du_crtc *rcrtc = &rgrp->dev->crtcs[rgrp->index * 2];
0229 
0230         rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_DRES | DSYSR_DEN,
0231                        start ? DSYSR_DEN : DSYSR_DRES);
0232     } else {
0233         rcar_du_group_write(rgrp, DSYSR,
0234                     start ? DSYSR_DEN : DSYSR_DRES);
0235     }
0236 }
0237 
0238 void rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
0239 {
0240     /*
0241      * Many of the configuration bits are only updated when the display
0242      * reset (DRES) bit in DSYSR is set to 1, disabling *both* CRTCs. Some
0243      * of those bits could be pre-configured, but others (especially the
0244      * bits related to plane assignment to display timing controllers) need
0245      * to be modified at runtime.
0246      *
0247      * Restart the display controller if a start is requested. Sorry for the
0248      * flicker. It should be possible to move most of the "DRES-update" bits
0249      * setup to driver initialization time and minimize the number of cases
0250      * when the display controller will have to be restarted.
0251      */
0252     if (start) {
0253         if (rgrp->used_crtcs++ != 0)
0254             __rcar_du_group_start_stop(rgrp, false);
0255         __rcar_du_group_start_stop(rgrp, true);
0256     } else {
0257         if (--rgrp->used_crtcs == 0)
0258             __rcar_du_group_start_stop(rgrp, false);
0259     }
0260 }
0261 
0262 void rcar_du_group_restart(struct rcar_du_group *rgrp)
0263 {
0264     rgrp->need_restart = false;
0265 
0266     __rcar_du_group_start_stop(rgrp, false);
0267     __rcar_du_group_start_stop(rgrp, true);
0268 }
0269 
0270 int rcar_du_set_dpad0_vsp1_routing(struct rcar_du_device *rcdu)
0271 {
0272     struct rcar_du_group *rgrp;
0273     struct rcar_du_crtc *crtc;
0274     unsigned int index;
0275     int ret;
0276 
0277     if (rcdu->info->gen < 2)
0278         return 0;
0279 
0280     /*
0281      * RGB output routing to DPAD0 and VSP1D routing to DU0/1/2 are
0282      * configured in the DEFR8 register of the first group on Gen2 and the
0283      * last group on Gen3. As this function can be called with the DU
0284      * channels of the corresponding CRTCs disabled, we need to enable the
0285      * group clock before accessing the register.
0286      */
0287     index = rcdu->info->gen < 3 ? 0 : DIV_ROUND_UP(rcdu->num_crtcs, 2) - 1;
0288     rgrp = &rcdu->groups[index];
0289     crtc = &rcdu->crtcs[index * 2];
0290 
0291     ret = clk_prepare_enable(crtc->clock);
0292     if (ret < 0)
0293         return ret;
0294 
0295     rcar_du_group_setup_defr8(rgrp);
0296 
0297     clk_disable_unprepare(crtc->clock);
0298 
0299     return 0;
0300 }
0301 
0302 static void rcar_du_group_set_dpad_levels(struct rcar_du_group *rgrp)
0303 {
0304     static const u32 doflr_values[2] = {
0305         DOFLR_HSYCFL0 | DOFLR_VSYCFL0 | DOFLR_ODDFL0 |
0306         DOFLR_DISPFL0 | DOFLR_CDEFL0  | DOFLR_RGBFL0,
0307         DOFLR_HSYCFL1 | DOFLR_VSYCFL1 | DOFLR_ODDFL1 |
0308         DOFLR_DISPFL1 | DOFLR_CDEFL1  | DOFLR_RGBFL1,
0309     };
0310     static const u32 dpad_mask = BIT(RCAR_DU_OUTPUT_DPAD1)
0311                    | BIT(RCAR_DU_OUTPUT_DPAD0);
0312     struct rcar_du_device *rcdu = rgrp->dev;
0313     u32 doflr = DOFLR_CODE;
0314     unsigned int i;
0315 
0316     if (rcdu->info->gen < 2)
0317         return;
0318 
0319     /*
0320      * The DPAD outputs can't be controlled directly. However, the parallel
0321      * output of the DU channels routed to DPAD can be set to fixed levels
0322      * through the DOFLR group register. Use this to turn the DPAD on or off
0323      * by driving fixed low-level signals at the output of any DU channel
0324      * not routed to a DPAD output. This doesn't affect the DU output
0325      * signals going to other outputs, such as the internal LVDS and HDMI
0326      * encoders.
0327      */
0328 
0329     for (i = 0; i < rgrp->num_crtcs; ++i) {
0330         struct rcar_du_crtc_state *rstate;
0331         struct rcar_du_crtc *rcrtc;
0332 
0333         rcrtc = &rcdu->crtcs[rgrp->index * 2 + i];
0334         rstate = to_rcar_crtc_state(rcrtc->crtc.state);
0335 
0336         if (!(rstate->outputs & dpad_mask))
0337             doflr |= doflr_values[i];
0338     }
0339 
0340     rcar_du_group_write(rgrp, DOFLR, doflr);
0341 }
0342 
0343 int rcar_du_group_set_routing(struct rcar_du_group *rgrp)
0344 {
0345     struct rcar_du_device *rcdu = rgrp->dev;
0346     u32 dorcr = rcar_du_group_read(rgrp, DORCR);
0347 
0348     dorcr &= ~(DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_MASK);
0349 
0350     /*
0351      * Set the DPAD1 pins sources. Select CRTC 0 if explicitly requested and
0352      * CRTC 1 in all other cases to avoid cloning CRTC 0 to DPAD0 and DPAD1
0353      * by default.
0354      */
0355     if (rcdu->dpad1_source == rgrp->index * 2)
0356         dorcr |= DORCR_PG2D_DS1;
0357     else
0358         dorcr |= DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_DS2;
0359 
0360     rcar_du_group_write(rgrp, DORCR, dorcr);
0361 
0362     rcar_du_group_set_dpad_levels(rgrp);
0363 
0364     return rcar_du_set_dpad0_vsp1_routing(rgrp->dev);
0365 }