Merge branch 'asoc-4.19' into asoc-4.20 Cirrus conflict
[muen/linux.git] / sound / soc / sh / rcar / dma.c
index d65ea7bc4dac2d2608cbcfbe3d3a4ebd915ad242..0bbc4b0ea2c6d65daf62cff46489bdc9bf20e3ec 100644 (file)
@@ -106,9 +106,9 @@ static int rsnd_dmaen_stop(struct rsnd_mod *mod,
        return 0;
 }
 
-static int rsnd_dmaen_nolock_stop(struct rsnd_mod *mod,
-                                  struct rsnd_dai_stream *io,
-                                  struct rsnd_priv *priv)
+static int rsnd_dmaen_cleanup(struct rsnd_mod *mod,
+                             struct rsnd_dai_stream *io,
+                             struct rsnd_priv *priv)
 {
        struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
        struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
@@ -116,7 +116,7 @@ static int rsnd_dmaen_nolock_stop(struct rsnd_mod *mod,
        /*
         * DMAEngine release uses mutex lock.
         * Thus, it shouldn't be called under spinlock.
-        * Let's call it under nolock_start
+        * Let's call it under prepare
         */
        if (dmaen->chan)
                dma_release_channel(dmaen->chan);
@@ -126,9 +126,9 @@ static int rsnd_dmaen_nolock_stop(struct rsnd_mod *mod,
        return 0;
 }
 
-static int rsnd_dmaen_nolock_start(struct rsnd_mod *mod,
-                           struct rsnd_dai_stream *io,
-                           struct rsnd_priv *priv)
+static int rsnd_dmaen_prepare(struct rsnd_mod *mod,
+                             struct rsnd_dai_stream *io,
+                             struct rsnd_priv *priv)
 {
        struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
        struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
@@ -142,7 +142,7 @@ static int rsnd_dmaen_nolock_start(struct rsnd_mod *mod,
        /*
         * DMAEngine request uses mutex lock.
         * Thus, it shouldn't be called under spinlock.
-        * Let's call it under nolock_start
+        * Let's call it under prepare
         */
        dmaen->chan = rsnd_dmaen_request_channel(io,
                                                 dma->mod_from,
@@ -291,8 +291,8 @@ static int rsnd_dmaen_pointer(struct rsnd_mod *mod,
 
 static struct rsnd_mod_ops rsnd_dmaen_ops = {
        .name   = "audmac",
-       .nolock_start = rsnd_dmaen_nolock_start,
-       .nolock_stop  = rsnd_dmaen_nolock_stop,
+       .prepare = rsnd_dmaen_prepare,
+       .cleanup = rsnd_dmaen_cleanup,
        .start  = rsnd_dmaen_start,
        .stop   = rsnd_dmaen_stop,
        .pointer= rsnd_dmaen_pointer,
@@ -302,16 +302,26 @@ static struct rsnd_mod_ops rsnd_dmaen_ops = {
  *             Audio DMAC peri peri
  */
 static const u8 gen2_id_table_ssiu[] = {
-       0x00, /* SSI00 */
-       0x04, /* SSI10 */
-       0x08, /* SSI20 */
-       0x0c, /* SSI3  */
-       0x0d, /* SSI4  */
-       0x0e, /* SSI5  */
-       0x0f, /* SSI6  */
-       0x10, /* SSI7  */
-       0x11, /* SSI8  */
-       0x12, /* SSI90 */
+       /* SSI00 ~ SSI07 */
+       0x00, 0x01, 0x02, 0x03, 0x39, 0x3a, 0x3b, 0x3c,
+       /* SSI10 ~ SSI17 */
+       0x04, 0x05, 0x06, 0x07, 0x3d, 0x3e, 0x3f, 0x40,
+       /* SSI20 ~ SSI27 */
+       0x08, 0x09, 0x0a, 0x0b, 0x41, 0x42, 0x43, 0x44,
+       /* SSI30 ~ SSI37 */
+       0x0c, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b,
+       /* SSI40 ~ SSI47 */
+       0x0d, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52,
+       /* SSI5 */
+       0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       /* SSI6 */
+       0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       /* SSI7 */
+       0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       /* SSI8 */
+       0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       /* SSI90 ~ SSI97 */
+       0x12, 0x13, 0x14, 0x15, 0x53, 0x54, 0x55, 0x56,
 };
 static const u8 gen2_id_table_scu[] = {
        0x2d, /* SCU_SRCI0 */
@@ -337,18 +347,23 @@ static u32 rsnd_dmapp_get_id(struct rsnd_dai_stream *io,
        struct rsnd_mod *src = rsnd_io_to_mod_src(io);
        struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
        const u8 *entry = NULL;
-       int id = rsnd_mod_id(mod);
+       int id = 255;
        int size = 0;
 
        if (mod == ssi) {
+               int busif = rsnd_ssi_get_busif(io);
+
                entry = gen2_id_table_ssiu;
                size = ARRAY_SIZE(gen2_id_table_ssiu);
+               id = (rsnd_mod_id(mod) * 8) + busif;
        } else if (mod == src) {
                entry = gen2_id_table_scu;
                size = ARRAY_SIZE(gen2_id_table_scu);
+               id = rsnd_mod_id(mod);
        } else if (mod == dvc) {
                entry = gen2_id_table_cmd;
                size = ARRAY_SIZE(gen2_id_table_cmd);
+               id = rsnd_mod_id(mod);
        }
 
        if ((!entry) || (size <= id)) {
@@ -382,7 +397,7 @@ static void rsnd_dmapp_write(struct rsnd_dma *dma, u32 data, u32 reg)
        struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
        struct device *dev = rsnd_priv_to_dev(priv);
 
-       dev_dbg(dev, "w %p : %08x\n", rsnd_dmapp_addr(dmac, dma, reg), data);
+       dev_dbg(dev, "w 0x%px : %08x\n", rsnd_dmapp_addr(dmac, dma, reg), data);
 
        iowrite32(data, rsnd_dmapp_addr(dmac, dma, reg));
 }
@@ -491,11 +506,11 @@ static struct rsnd_mod_ops rsnd_dmapp_ops = {
 #define RDMA_SSI_I_N(addr, i)  (addr ##_reg - 0x00300000 + (0x40 * i) + 0x8)
 #define RDMA_SSI_O_N(addr, i)  (addr ##_reg - 0x00300000 + (0x40 * i) + 0xc)
 
-#define RDMA_SSIU_I_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i))
-#define RDMA_SSIU_O_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i))
+#define RDMA_SSIU_I_N(addr, i, j) (addr ##_reg - 0x00441000 + (0x1000 * (i)) + (((j) / 4) * 0xA000) + (((j) % 4) * 0x400))
+#define RDMA_SSIU_O_N(addr, i, j) RDMA_SSIU_I_N(addr, i, j)
 
-#define RDMA_SSIU_I_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i))
-#define RDMA_SSIU_O_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i))
+#define RDMA_SSIU_I_P(addr, i, j) (addr ##_reg - 0x00141000 + (0x1000 * (i)) + (((j) / 4) * 0xA000) + (((j) % 4) * 0x400))
+#define RDMA_SSIU_O_P(addr, i, j) RDMA_SSIU_I_P(addr, i, j)
 
 #define RDMA_SRC_I_N(addr, i)  (addr ##_reg - 0x00500000 + (0x400 * i))
 #define RDMA_SRC_O_N(addr, i)  (addr ##_reg - 0x004fc000 + (0x400 * i))
@@ -521,6 +536,7 @@ rsnd_gen2_dma_addr(struct rsnd_dai_stream *io,
                      !!rsnd_io_to_mod_mix(io) ||
                      !!rsnd_io_to_mod_ctu(io);
        int id = rsnd_mod_id(mod);
+       int busif = rsnd_ssi_get_busif(io);
        struct dma_addr {
                dma_addr_t out_addr;
                dma_addr_t in_addr;
@@ -537,25 +553,35 @@ rsnd_gen2_dma_addr(struct rsnd_dai_stream *io,
                },
                /* SSI */
                /* Capture */
-               {{{ RDMA_SSI_O_N(ssi, id),      0 },
-                 { RDMA_SSIU_O_P(ssi, id),     0 },
-                 { RDMA_SSIU_O_P(ssi, id),     0 } },
+               {{{ RDMA_SSI_O_N(ssi, id),              0 },
+                 { RDMA_SSIU_O_P(ssi, id, busif),      0 },
+                 { RDMA_SSIU_O_P(ssi, id, busif),      0 } },
                 /* Playback */
-                {{ 0,                          RDMA_SSI_I_N(ssi, id) },
-                 { 0,                          RDMA_SSIU_I_P(ssi, id) },
-                 { 0,                          RDMA_SSIU_I_P(ssi, id) } }
+                {{ 0,                  RDMA_SSI_I_N(ssi, id) },
+                 { 0,                  RDMA_SSIU_I_P(ssi, id, busif) },
+                 { 0,                  RDMA_SSIU_I_P(ssi, id, busif) } }
                },
                /* SSIU */
                /* Capture */
-               {{{ RDMA_SSIU_O_N(ssi, id),     0 },
-                 { RDMA_SSIU_O_P(ssi, id),     0 },
-                 { RDMA_SSIU_O_P(ssi, id),     0 } },
+               {{{ RDMA_SSIU_O_N(ssi, id, busif),      0 },
+                 { RDMA_SSIU_O_P(ssi, id, busif),      0 },
+                 { RDMA_SSIU_O_P(ssi, id, busif),      0 } },
                 /* Playback */
-                {{ 0,                          RDMA_SSIU_I_N(ssi, id) },
-                 { 0,                          RDMA_SSIU_I_P(ssi, id) },
-                 { 0,                          RDMA_SSIU_I_P(ssi, id) } } },
+                {{ 0,                  RDMA_SSIU_I_N(ssi, id, busif) },
+                 { 0,                  RDMA_SSIU_I_P(ssi, id, busif) },
+                 { 0,                  RDMA_SSIU_I_P(ssi, id, busif) } } },
        };
 
+       /*
+        * FIXME
+        *
+        * We can't support SSI9-4/5/6/7, because its address is
+        * out of calculation rule
+        */
+       if ((id == 9) && (busif >= 4))
+               dev_err(dev, "This driver doesn't support SSI%d-%d, so far",
+                       id, busif);
+
        /* it shouldn't happen */
        if (use_cmd && !use_src)
                dev_err(dev, "DVC is selected without SRC\n");