Home | History | Annotate | Download | only in vc5
      1 /*
      2  * Copyright  2014-2017 Broadcom
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     21  * IN THE SOFTWARE.
     22  */
     23 
     24 /**
     25  * @file vc5_simulator_hw.c
     26  *
     27  * Implements the actual HW interaction betweeh the GL driver's VC5 simulator and the simulator.
     28  *
     29  * The register headers between V3D versions will have conflicting defines, so
     30  * all register interactions appear in this file and are compiled per V3D version
     31  * we support.
     32  */
     33 
     34 #ifdef USE_VC5_SIMULATOR
     35 
     36 #include "vc5_screen.h"
     37 #include "vc5_context.h"
     38 #include "vc5_simulator_wrapper.h"
     39 
     40 #define HW_REGISTER_RO(x) (x)
     41 #define HW_REGISTER_RW(x) (x)
     42 #if V3D_VERSION >= 41
     43 #include "libs/core/v3d/registers/4.1.34.0/v3d.h"
     44 #else
     45 #include "libs/core/v3d/registers/3.3.0.0/v3d.h"
     46 #endif
     47 
     48 #define V3D_WRITE(reg, val) v3d_hw_write_reg(v3d, reg, val)
     49 #define V3D_READ(reg) v3d_hw_read_reg(v3d, reg)
     50 
     51 static void
     52 vc5_flush_l3(struct v3d_hw *v3d)
     53 {
     54         if (!v3d_hw_has_gca(v3d))
     55                 return;
     56 
     57 #if V3D_VERSION < 40
     58         uint32_t gca_ctrl = V3D_READ(V3D_GCA_CACHE_CTRL);
     59 
     60         V3D_WRITE(V3D_GCA_CACHE_CTRL, gca_ctrl | V3D_GCA_CACHE_CTRL_FLUSH_SET);
     61         V3D_WRITE(V3D_GCA_CACHE_CTRL, gca_ctrl & ~V3D_GCA_CACHE_CTRL_FLUSH_SET);
     62 #endif
     63 }
     64 
     65 /* Invalidates the L2 cache.  This is a read-only cache. */
     66 static void
     67 vc5_flush_l2(struct v3d_hw *v3d)
     68 {
     69         V3D_WRITE(V3D_CTL_0_L2CACTL,
     70                   V3D_CTL_0_L2CACTL_L2CCLR_SET |
     71                   V3D_CTL_0_L2CACTL_L2CENA_SET);
     72 }
     73 
     74 /* Invalidates texture L2 cachelines */
     75 static void
     76 vc5_flush_l2t(struct v3d_hw *v3d)
     77 {
     78         V3D_WRITE(V3D_CTL_0_L2TFLSTA, 0);
     79         V3D_WRITE(V3D_CTL_0_L2TFLEND, ~0);
     80         V3D_WRITE(V3D_CTL_0_L2TCACTL,
     81                   V3D_CTL_0_L2TCACTL_L2TFLS_SET |
     82                   (0 << V3D_CTL_0_L2TCACTL_L2TFLM_LSB));
     83 }
     84 
     85 /* Invalidates the slice caches.  These are read-only caches. */
     86 static void
     87 vc5_flush_slices(struct v3d_hw *v3d)
     88 {
     89         V3D_WRITE(V3D_CTL_0_SLCACTL, ~0);
     90 }
     91 
     92 static void
     93 vc5_flush_caches(struct v3d_hw *v3d)
     94 {
     95         vc5_flush_l3(v3d);
     96         vc5_flush_l2(v3d);
     97         vc5_flush_l2t(v3d);
     98         vc5_flush_slices(v3d);
     99 }
    100 
    101 int
    102 v3dX(simulator_get_param_ioctl)(struct v3d_hw *v3d,
    103                                 struct drm_vc5_get_param *args)
    104 {
    105         static const uint32_t reg_map[] = {
    106                 [DRM_VC5_PARAM_V3D_UIFCFG] = V3D_HUB_CTL_UIFCFG,
    107                 [DRM_VC5_PARAM_V3D_HUB_IDENT1] = V3D_HUB_CTL_IDENT1,
    108                 [DRM_VC5_PARAM_V3D_HUB_IDENT2] = V3D_HUB_CTL_IDENT2,
    109                 [DRM_VC5_PARAM_V3D_HUB_IDENT3] = V3D_HUB_CTL_IDENT3,
    110                 [DRM_VC5_PARAM_V3D_CORE0_IDENT0] = V3D_CTL_0_IDENT0,
    111                 [DRM_VC5_PARAM_V3D_CORE0_IDENT1] = V3D_CTL_0_IDENT1,
    112                 [DRM_VC5_PARAM_V3D_CORE0_IDENT2] = V3D_CTL_0_IDENT2,
    113         };
    114 
    115         if (args->param < ARRAY_SIZE(reg_map) && reg_map[args->param]) {
    116                 args->value = V3D_READ(reg_map[args->param]);
    117                 return 0;
    118         }
    119 
    120         fprintf(stderr, "Unknown DRM_IOCTL_VC5_GET_PARAM(%lld)\n",
    121                 (long long)args->value);
    122         abort();
    123 }
    124 
    125 void
    126 v3dX(simulator_init_regs)(struct v3d_hw *v3d)
    127 {
    128 #if V3D_VERSION == 33
    129         /* Set OVRTMUOUT to match kernel behavior.
    130          *
    131          * This means that the texture sampler uniform configuration's tmu
    132          * output type field is used, instead of using the hardware default
    133          * behavior based on the texture type.  If you want the default
    134          * behavior, you can still put "2" in the indirect texture state's
    135          * output_type field.
    136          */
    137         V3D_WRITE(V3D_CTL_0_MISCCFG, V3D_CTL_1_MISCCFG_OVRTMUOUT_SET);
    138 #endif
    139 }
    140 
    141 void
    142 v3dX(simulator_flush)(struct v3d_hw *v3d, struct drm_vc5_submit_cl *submit,
    143                       uint32_t gmp_ofs)
    144 {
    145         /* Completely reset the GMP. */
    146         V3D_WRITE(V3D_GMP_0_CFG,
    147                   V3D_GMP_0_CFG_PROTENABLE_SET);
    148         V3D_WRITE(V3D_GMP_0_TABLE_ADDR, gmp_ofs);
    149         V3D_WRITE(V3D_GMP_0_CLEAR_LOAD, ~0);
    150         while (V3D_READ(V3D_GMP_0_STATUS) &
    151                V3D_GMP_0_STATUS_CFG_BUSY_SET) {
    152                 ;
    153         }
    154 
    155         vc5_flush_caches(v3d);
    156 
    157         if (submit->qma) {
    158                 V3D_WRITE(V3D_CLE_0_CT0QMA, submit->qma);
    159                 V3D_WRITE(V3D_CLE_0_CT0QMS, submit->qms);
    160         }
    161 #if V3D_VERSION >= 41
    162         if (submit->qts) {
    163                 V3D_WRITE(V3D_CLE_0_CT0QTS,
    164                           V3D_CLE_0_CT0QTS_CTQTSEN_SET |
    165                           submit->qts);
    166         }
    167 #endif
    168         V3D_WRITE(V3D_CLE_0_CT0QBA, submit->bcl_start);
    169         V3D_WRITE(V3D_CLE_0_CT0QEA, submit->bcl_end);
    170 
    171         /* Wait for bin to complete before firing render, as it seems the
    172          * simulator doesn't implement the semaphores.
    173          */
    174         while (V3D_READ(V3D_CLE_0_CT0CA) !=
    175                V3D_READ(V3D_CLE_0_CT0EA)) {
    176                 v3d_hw_tick(v3d);
    177         }
    178 
    179         V3D_WRITE(V3D_CLE_0_CT1QBA, submit->rcl_start);
    180         V3D_WRITE(V3D_CLE_0_CT1QEA, submit->rcl_end);
    181 
    182         while (V3D_READ(V3D_CLE_0_CT1CA) !=
    183                V3D_READ(V3D_CLE_0_CT1EA) ||
    184                V3D_READ(V3D_CLE_1_CT1CA) !=
    185                V3D_READ(V3D_CLE_1_CT1EA)) {
    186                 v3d_hw_tick(v3d);
    187         }
    188 }
    189 
    190 #endif /* USE_VC5_SIMULATOR */
    191