summaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorIshan Mittal <imittal@nvidia.com>2017-06-08 06:31:42 -0400
committerIshan Mittal <imittal@nvidia.com>2017-06-08 06:31:42 -0400
commit5a24ffca4f583fc2d8b6d23cdd72297b3bb0c56d (patch)
treefa0ee36f270e4011ce4fb52945e4f28fdf240f8c /drivers/gpu
parentfabd083430a792135fb30ed3b25d9446a6df28e9 (diff)
parent5edcd552af63efd15d532a406fdef1b55f167bdd (diff)
Merge 't18x/dev-kernel' into nvidia
Bug 200295104 Change-Id: I2885095688e942ef860cdcc808af4288f9523ab9
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/tegra/Makefile.t18x11
-rw-r--r--drivers/gpu/drm/tegra/nvdec_t186.c63
-rw-r--r--drivers/gpu/drm/tegra/nvdec_t186.h27
-rw-r--r--drivers/gpu/drm/tegra/nvenc_t186.c47
-rw-r--r--drivers/gpu/drm/tegra/nvenc_t186.h27
-rw-r--r--drivers/gpu/drm/tegra/nvjpg_t186.c47
-rw-r--r--drivers/gpu/drm/tegra/nvjpg_t186.h27
-rw-r--r--drivers/gpu/drm/tegra/tsec_t186.c54
-rw-r--r--drivers/gpu/drm/tegra/tsec_t186.h28
-rw-r--r--drivers/gpu/drm/tegra/vic_t186.c48
-rw-r--r--drivers/gpu/drm/tegra/vic_t186.h27
-rw-r--r--drivers/gpu/host1x/Makefile.t18x8
-rw-r--r--drivers/gpu/host1x/dev_t186.c40
-rw-r--r--drivers/gpu/host1x/dev_t186.h34
-rw-r--r--drivers/gpu/host1x/hw/cdma_hw_t186.c340
-rw-r--r--drivers/gpu/host1x/hw/channel_hw_t186.c302
-rw-r--r--drivers/gpu/host1x/hw/debug_hw_t186.c288
-rw-r--r--drivers/gpu/host1x/hw/host1x05.c42
-rw-r--r--drivers/gpu/host1x/hw/host1x05.h24
-rw-r--r--drivers/gpu/host1x/hw/host1x05_hardware.h128
-rw-r--r--drivers/gpu/host1x/hw/hw_host1x05_channel.h169
-rw-r--r--drivers/gpu/host1x/hw/hw_host1x05_sync.h321
-rw-r--r--drivers/gpu/host1x/hw/hw_host1x05_uclass.h157
-rw-r--r--drivers/gpu/host1x/hw/intr_hw_t186.c247
-rw-r--r--drivers/gpu/host1x/hw/stremid_hw_t186.c95
-rw-r--r--drivers/gpu/host1x/hw/syncpt_hw_t186.c126
26 files changed, 2727 insertions, 0 deletions
diff --git a/drivers/gpu/drm/tegra/Makefile.t18x b/drivers/gpu/drm/tegra/Makefile.t18x
new file mode 100644
index 000000000..ee133616a
--- /dev/null
+++ b/drivers/gpu/drm/tegra/Makefile.t18x
@@ -0,0 +1,11 @@
1ccflags-y += -Idrivers/gpu/drm/tegra
2ccflags-y += -I../t18x/drivers/gpu/drm/tegra
3
4tegra-drm-t186-y = \
5 vic_t186.o \
6 nvenc_t186.o \
7 nvdec_t186.o \
8 nvjpg_t186.o \
9 tsec_t186.o
10
11obj-$(CONFIG_TEGRA_HOST1X) += tegra-drm-t186.o
diff --git a/drivers/gpu/drm/tegra/nvdec_t186.c b/drivers/gpu/drm/tegra/nvdec_t186.c
new file mode 100644
index 000000000..78d2235c1
--- /dev/null
+++ b/drivers/gpu/drm/tegra/nvdec_t186.c
@@ -0,0 +1,63 @@
1/*
2 * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "drm.h"
18#include "nvdec_t186.h"
19
20#include <linux/iommu.h>
21#include <soc/tegra/kfuse.h>
22
23static int nvdec_load_streamid_regs(struct tegra_drm_client *client)
24{
25 struct nvdec *nvdec = to_nvdec(client);
26 int streamid = -EINVAL;
27
28 streamid = iommu_get_hwid(nvdec->dev->archdata.iommu, nvdec->dev, 0);
29
30 if (streamid >= 0) {
31 nvdec_writel(nvdec, streamid, NVDEC_THI_STREAMID0);
32 nvdec_writel(nvdec, streamid, NVDEC_THI_STREAMID1);
33 }
34
35 return 0;
36}
37
38static int nvdec_finalize_poweron(struct tegra_drm_client *client)
39{
40 return tegra_kfuse_enable_sensing();
41}
42
43static int nvdec_prepare_poweroff(struct tegra_drm_client *client)
44{
45 tegra_kfuse_disable_sensing();
46 return 0;
47}
48
49static const struct tegra_drm_client_ops nvdec_t186_ops = {
50 .open_channel = nvdec_open_channel,
51 .close_channel = nvdec_close_channel,
52 .submit = tegra_drm_submit,
53 .load_regs = nvdec_load_streamid_regs,
54 .finalize_poweron = nvdec_finalize_poweron,
55 .prepare_poweroff = nvdec_prepare_poweroff,
56};
57
58const struct nvdec_config nvdec_t186_config = {
59 .ucode_name = "tegra18x/nvhost_nvdec030_ns.fw",
60 .ucode_name_bl = "tegra18x/nvhost_nvdec_bl030_prod.fw",
61 .ucode_name_ls = "tegra18x/nvhost_nvdec030_prod.fw",
62 .drm_client_ops = &nvdec_t186_ops,
63};
diff --git a/drivers/gpu/drm/tegra/nvdec_t186.h b/drivers/gpu/drm/tegra/nvdec_t186.h
new file mode 100644
index 000000000..8d57e1d59
--- /dev/null
+++ b/drivers/gpu/drm/tegra/nvdec_t186.h
@@ -0,0 +1,27 @@
1/*
2 * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef TEGRA_NVDEC_T186_H
18#define TEGRA_NVDEC_T186_H
19
20#include "nvdec.h"
21
22#define NVDEC_THI_STREAMID0 0x30
23#define NVDEC_THI_STREAMID1 0x34
24
25extern const struct nvdec_config nvdec_t186_config;
26
27#endif
diff --git a/drivers/gpu/drm/tegra/nvenc_t186.c b/drivers/gpu/drm/tegra/nvenc_t186.c
new file mode 100644
index 000000000..68cc6a7e5
--- /dev/null
+++ b/drivers/gpu/drm/tegra/nvenc_t186.c
@@ -0,0 +1,47 @@
1/*
2 * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "drm.h"
18#include "nvenc_t186.h"
19
20#include <linux/iommu.h>
21
22static int nvenc_load_streamid_regs(struct tegra_drm_client *client)
23{
24 struct nvenc *nvenc = to_nvenc(client);
25 int streamid = -EINVAL;
26
27 streamid = iommu_get_hwid(nvenc->dev->archdata.iommu, nvenc->dev, 0);
28
29 if (streamid >= 0) {
30 nvenc_writel(nvenc, streamid, NVENC_THI_STREAMID0);
31 nvenc_writel(nvenc, streamid, NVENC_THI_STREAMID1);
32 }
33
34 return 0;
35}
36
37static const struct tegra_drm_client_ops nvenc_t186_ops = {
38 .open_channel = nvenc_open_channel,
39 .close_channel = nvenc_close_channel,
40 .submit = tegra_drm_submit,
41 .load_regs = nvenc_load_streamid_regs,
42};
43
44const struct nvenc_config nvenc_t186_config = {
45 .ucode_name = "tegra18x/nvhost_nvenc061.fw",
46 .drm_client_ops = &nvenc_t186_ops,
47};
diff --git a/drivers/gpu/drm/tegra/nvenc_t186.h b/drivers/gpu/drm/tegra/nvenc_t186.h
new file mode 100644
index 000000000..1ae36ec16
--- /dev/null
+++ b/drivers/gpu/drm/tegra/nvenc_t186.h
@@ -0,0 +1,27 @@
1/*
2 * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef TEGRA_NVENC_T186_H
18#define TEGRA_NVENC_T186_H
19
20#include "nvenc.h"
21
22#define NVENC_THI_STREAMID0 0x30
23#define NVENC_THI_STREAMID1 0x34
24
25extern const struct nvenc_config nvenc_t186_config;
26
27#endif
diff --git a/drivers/gpu/drm/tegra/nvjpg_t186.c b/drivers/gpu/drm/tegra/nvjpg_t186.c
new file mode 100644
index 000000000..af262c589
--- /dev/null
+++ b/drivers/gpu/drm/tegra/nvjpg_t186.c
@@ -0,0 +1,47 @@
1/*
2 * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "drm.h"
18#include "nvjpg_t186.h"
19
20#include <linux/iommu.h>
21
22static int nvjpg_load_streamid_regs(struct tegra_drm_client *client)
23{
24 struct nvjpg *nvjpg = to_nvjpg(client);
25 int streamid = -EINVAL;
26
27 streamid = iommu_get_hwid(nvjpg->dev->archdata.iommu, nvjpg->dev, 0);
28
29 if (streamid >= 0) {
30 nvjpg_writel(nvjpg, streamid, NVJPG_THI_STREAMID0);
31 nvjpg_writel(nvjpg, streamid, NVJPG_THI_STREAMID1);
32 }
33
34 return 0;
35}
36
37static const struct tegra_drm_client_ops nvjpg_t186_ops = {
38 .open_channel = nvjpg_open_channel,
39 .close_channel = nvjpg_close_channel,
40 .submit = tegra_drm_submit,
41 .load_regs = nvjpg_load_streamid_regs,
42};
43
44const struct nvjpg_config nvjpg_t186_config = {
45 .ucode_name = "tegra18x/nvhost_nvjpg011.fw",
46 .drm_client_ops = &nvjpg_t186_ops,
47};
diff --git a/drivers/gpu/drm/tegra/nvjpg_t186.h b/drivers/gpu/drm/tegra/nvjpg_t186.h
new file mode 100644
index 000000000..a310e34c1
--- /dev/null
+++ b/drivers/gpu/drm/tegra/nvjpg_t186.h
@@ -0,0 +1,27 @@
1/*
2 * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef TEGRA_NVJPG_T186_H
18#define TEGRA_NVJPG_T186_H
19
20#include "nvjpg.h"
21
22#define NVJPG_THI_STREAMID0 0x30
23#define NVJPG_THI_STREAMID1 0x34
24
25extern const struct nvjpg_config nvjpg_t186_config;
26
27#endif
diff --git a/drivers/gpu/drm/tegra/tsec_t186.c b/drivers/gpu/drm/tegra/tsec_t186.c
new file mode 100644
index 000000000..5a47bbc28
--- /dev/null
+++ b/drivers/gpu/drm/tegra/tsec_t186.c
@@ -0,0 +1,54 @@
1/*
2 * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "drm.h"
18#include "tsec_t186.h"
19
20#include <linux/iommu.h>
21
22static int tsec_load_streamid_regs(struct tegra_drm_client *client)
23{
24 struct tsec *tsec = to_tsec(client);
25 int streamid = -EINVAL;
26
27 streamid = iommu_get_hwid(tsec->dev->archdata.iommu, tsec->dev, 0);
28
29 if (streamid >= 0) {
30 tsec_writel(tsec, streamid, TSEC_THI_STREAMID0);
31 tsec_writel(tsec, streamid, TSEC_THI_STREAMID1);
32 }
33
34 return 0;
35}
36
37static const struct tegra_drm_client_ops tsec_t186_ops = {
38 .open_channel = tsec_open_channel,
39 .close_channel = tsec_close_channel,
40 .submit = tegra_drm_submit,
41 .load_regs = tsec_load_streamid_regs,
42};
43
44const struct tsec_config tsec_t186_config = {
45 .ucode_name = "tegra18x/nvhost_tsec.fw",
46 .drm_client_ops = &tsec_t186_ops,
47 .class_id = HOST1X_CLASS_TSEC,
48};
49
50const struct tsec_config tsecb_t186_config = {
51 .ucode_name = "tegra18x/nvhost_tsec.fw",
52 .drm_client_ops = &tsec_t186_ops,
53 .class_id = HOST1X_CLASS_TSECB,
54};
diff --git a/drivers/gpu/drm/tegra/tsec_t186.h b/drivers/gpu/drm/tegra/tsec_t186.h
new file mode 100644
index 000000000..e78ea2cf8
--- /dev/null
+++ b/drivers/gpu/drm/tegra/tsec_t186.h
@@ -0,0 +1,28 @@
1/*
2 * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef TEGRA_TSEC_T186_H
18#define TEGRA_TSEC_T186_H
19
20#include "tsec.h"
21
22#define TSEC_THI_STREAMID0 0x30
23#define TSEC_THI_STREAMID1 0x34
24
25extern const struct tsec_config tsec_t186_config;
26extern const struct tsec_config tsecb_t186_config;
27
28#endif
diff --git a/drivers/gpu/drm/tegra/vic_t186.c b/drivers/gpu/drm/tegra/vic_t186.c
new file mode 100644
index 000000000..c6efe1e86
--- /dev/null
+++ b/drivers/gpu/drm/tegra/vic_t186.c
@@ -0,0 +1,48 @@
1/*
2 * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "drm.h"
18#include "vic_t186.h"
19
20#include <linux/iommu.h>
21
22static int vic_load_streamid_regs(struct tegra_drm_client *client)
23{
24 struct vic *vic = to_vic(client);
25 int streamid = -EINVAL;
26
27 streamid = iommu_get_hwid(vic->dev->archdata.iommu, vic->dev, 0);
28
29 if (streamid >= 0) {
30 vic_writel(vic, streamid, VIC_THI_STREAMID0);
31 vic_writel(vic, streamid, VIC_THI_STREAMID1);
32 }
33
34 return 0;
35}
36
37static const struct tegra_drm_client_ops vic_t186_ops = {
38 .open_channel = vic_open_channel,
39 .close_channel = vic_close_channel,
40 .is_addr_reg = vic_is_addr_reg,
41 .submit = tegra_drm_submit,
42 .load_regs = vic_load_streamid_regs,
43};
44
45const struct vic_config vic_t186_config = {
46 .ucode_name = "tegra18x/vic04_ucode.bin",
47 .drm_client_ops = &vic_t186_ops,
48};
diff --git a/drivers/gpu/drm/tegra/vic_t186.h b/drivers/gpu/drm/tegra/vic_t186.h
new file mode 100644
index 000000000..e819dd49d
--- /dev/null
+++ b/drivers/gpu/drm/tegra/vic_t186.h
@@ -0,0 +1,27 @@
1/*
2 * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef TEGRA_VIC_T186_H
18#define TEGRA_VIC_T186_H
19
20#include "vic.h"
21
22#define VIC_THI_STREAMID0 0x30
23#define VIC_THI_STREAMID1 0x34
24
25extern const struct vic_config vic_t186_config;
26
27#endif
diff --git a/drivers/gpu/host1x/Makefile.t18x b/drivers/gpu/host1x/Makefile.t18x
new file mode 100644
index 000000000..25d54f73a
--- /dev/null
+++ b/drivers/gpu/host1x/Makefile.t18x
@@ -0,0 +1,8 @@
1ccflags-y += -Idrivers/gpu/host1x
2ccflags-y += -I../t18x/drivers/gpu/host1x
3
4host1x-t186-y = \
5 dev_t186.o \
6 hw/host1x05.o
7
8obj-$(CONFIG_TEGRA_HOST1X) += host1x-t186.o
diff --git a/drivers/gpu/host1x/dev_t186.c b/drivers/gpu/host1x/dev_t186.c
new file mode 100644
index 000000000..d29a48c68
--- /dev/null
+++ b/drivers/gpu/host1x/dev_t186.c
@@ -0,0 +1,40 @@
1/*
2 * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "dev.h"
18#include "dev_t186.h"
19
20#include "hw/host1x05.h"
21
22struct host1x_info host1x05_info = {
23 .nb_channels = 63,
24 .nb_pts = 576,
25 .nb_mlocks = 24,
26 .nb_bases = 16,
27 .init = host1x05_init,
28 .sync_offset = 0x0,
29 .gather_filter_enabled = true,
30};
31
32void host1x_writel(struct host1x *host1x, u32 v, u32 r)
33{
34 writel(v, host1x->regs + r);
35}
36
37u32 host1x_readl(struct host1x *host1x, u32 r)
38{
39 return readl(host1x->regs + r);
40}
diff --git a/drivers/gpu/host1x/dev_t186.h b/drivers/gpu/host1x/dev_t186.h
new file mode 100644
index 000000000..be9726e88
--- /dev/null
+++ b/drivers/gpu/host1x/dev_t186.h
@@ -0,0 +1,34 @@
1/*
2 * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef HOST1X_DEV_T186_H
18#define HOST1X_DEV_T186_H
19
20#include "dev.h"
21
22extern struct host1x_info host1x05_info;
23
24void host1x_writel(struct host1x *host1x, u32 v, u32 r);
25u32 host1x_readl(struct host1x *host1x, u32 r);
26
27static inline void host1x_hw_sync_get_mutex_owner(struct host1x *host,
28 struct host1x_syncpt *sp,
29 unsigned int mutex_id, bool *cpu, bool *ch,
30 unsigned int *chid)
31{
32 host->syncpt_op->get_mutex_owner(sp, mutex_id, cpu, ch, chid);
33}
34#endif
diff --git a/drivers/gpu/host1x/hw/cdma_hw_t186.c b/drivers/gpu/host1x/hw/cdma_hw_t186.c
new file mode 100644
index 000000000..e903f3e8b
--- /dev/null
+++ b/drivers/gpu/host1x/hw/cdma_hw_t186.c
@@ -0,0 +1,340 @@
1/*
2 * Tegra host1x Command DMA
3 *
4 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/slab.h>
20#include <linux/scatterlist.h>
21#include <linux/dma-mapping.h>
22
23#include "cdma.h"
24#include "channel.h"
25#include "dev.h"
26#include "debug.h"
27
28/*
29 * Put the restart at the end of pushbuffer memory
30 */
31static void push_buffer_init(struct push_buffer *pb)
32{
33 *(u32 *)(pb->mapped + pb->size_bytes) = host1x_opcode_restart(0);
34}
35
36/*
37 * Increment timedout buffer's syncpt via CPU.
38 */
39static void cdma_timeout_handle(struct host1x_cdma *cdma, u32 getptr,
40 u32 nr_slots)
41{
42 struct host1x *host1x = cdma_to_host1x(cdma);
43 struct push_buffer *pb = &cdma->push_buffer;
44
45 /* NOP all the PB slots */
46 while (nr_slots--) {
47 u32 *p = (u32 *)(pb->mapped + getptr);
48 *(p++) = HOST1X_OPCODE_NOP;
49 *(p++) = HOST1X_OPCODE_NOP;
50 dev_dbg(host1x->dev, "%s: NOP at %pad+%#x\n", __func__,
51 &pb->phys, getptr);
52 getptr = (getptr + 8) & (pb->size_bytes - 1);
53 }
54 wmb();
55}
56
57/*
58 * Start channel DMA
59 */
60static void cdma_start(struct host1x_cdma *cdma)
61{
62 struct host1x_channel *ch = cdma_to_channel(cdma);
63
64 if (cdma->running)
65 return;
66
67 cdma->last_pos = cdma->push_buffer.pos;
68
69 host1x_ch_writel(ch, HOST1X_CHANNEL_DMACTRL_DMASTOP,
70 HOST1X_CHANNEL_DMACTRL);
71
72 /* set base, put and end pointer */
73 host1x_ch_writel(ch, cdma->push_buffer.phys, HOST1X_CHANNEL_DMASTART);
74 host1x_ch_writel(ch, cdma->push_buffer.pos, HOST1X_CHANNEL_DMAPUT);
75 host1x_ch_writel(ch, cdma->push_buffer.phys +
76 cdma->push_buffer.size_bytes + 4,
77 HOST1X_CHANNEL_DMAEND);
78
79 /* reset GET */
80 host1x_ch_writel(ch, HOST1X_CHANNEL_DMACTRL_DMASTOP |
81 HOST1X_CHANNEL_DMACTRL_DMAGETRST |
82 HOST1X_CHANNEL_DMACTRL_DMAINITGET,
83 HOST1X_CHANNEL_DMACTRL);
84
85 host1x_channel_enable_gather_filter(ch);
86
87 /* start the command DMA */
88 host1x_ch_writel(ch, 0, HOST1X_CHANNEL_DMACTRL);
89
90 cdma->running = true;
91}
92
93/*
94 * Similar to cdma_start(), but rather than starting from an idle
95 * state (where DMA GET is set to DMA PUT), on a timeout we restore
96 * DMA GET from an explicit value (so DMA may again be pending).
97 */
98static void cdma_timeout_restart(struct host1x_cdma *cdma, u32 getptr)
99{
100 struct host1x *host1x = cdma_to_host1x(cdma);
101 struct host1x_channel *ch = cdma_to_channel(cdma);
102
103 if (cdma->running)
104 return;
105
106 cdma->last_pos = cdma->push_buffer.pos;
107
108 host1x_ch_writel(ch, HOST1X_CHANNEL_DMACTRL_DMASTOP,
109 HOST1X_CHANNEL_DMACTRL);
110
111 /* set base, end pointer (all of memory) */
112 host1x_ch_writel(ch, cdma->push_buffer.phys, HOST1X_CHANNEL_DMASTART);
113 host1x_ch_writel(ch, cdma->push_buffer.phys +
114 cdma->push_buffer.size_bytes,
115 HOST1X_CHANNEL_DMAEND);
116
117 /* set GET, by loading the value in PUT (then reset GET) */
118 host1x_ch_writel(ch, getptr, HOST1X_CHANNEL_DMAPUT);
119 host1x_ch_writel(ch, HOST1X_CHANNEL_DMACTRL_DMASTOP |
120 HOST1X_CHANNEL_DMACTRL_DMAGETRST |
121 HOST1X_CHANNEL_DMACTRL_DMAINITGET,
122 HOST1X_CHANNEL_DMACTRL);
123
124 dev_dbg(host1x->dev,
125 "%s: DMA GET 0x%x, PUT HW 0x%x / shadow 0x%x\n", __func__,
126 host1x_ch_readl(ch, HOST1X_CHANNEL_DMAGET),
127 host1x_ch_readl(ch, HOST1X_CHANNEL_DMAPUT),
128 cdma->last_pos);
129
130 /* deassert GET reset and set PUT */
131 host1x_ch_writel(ch, HOST1X_CHANNEL_DMACTRL_DMASTOP,
132 HOST1X_CHANNEL_DMACTRL);
133 host1x_ch_writel(ch, cdma->push_buffer.pos, HOST1X_CHANNEL_DMAPUT);
134
135 host1x_channel_enable_gather_filter(ch);
136
137 /* start the command DMA */
138 host1x_ch_writel(ch, 0, HOST1X_CHANNEL_DMACTRL);
139
140 cdma->running = true;
141}
142
143/*
144 * Kick channel DMA into action by writing its PUT offset (if it has changed)
145 */
146static void cdma_flush(struct host1x_cdma *cdma)
147{
148 struct host1x_channel *ch = cdma_to_channel(cdma);
149
150 if (cdma->push_buffer.pos != cdma->last_pos) {
151 host1x_ch_writel(ch, cdma->push_buffer.pos,
152 HOST1X_CHANNEL_DMAPUT);
153 cdma->last_pos = cdma->push_buffer.pos;
154 }
155}
156
157static void cdma_stop(struct host1x_cdma *cdma)
158{
159 struct host1x_channel *ch = cdma_to_channel(cdma);
160
161 mutex_lock(&cdma->lock);
162 if (cdma->running) {
163 host1x_cdma_wait_locked(cdma, CDMA_EVENT_SYNC_QUEUE_EMPTY);
164 host1x_ch_writel(ch, HOST1X_CHANNEL_DMACTRL_DMASTOP,
165 HOST1X_CHANNEL_DMACTRL);
166 cdma->running = false;
167 }
168 mutex_unlock(&cdma->lock);
169}
170
171/*
172 * Stops both channel's command processor and CDMA immediately.
173 * Also, tears down the channel and resets corresponding module.
174 */
175static void cdma_freeze(struct host1x_cdma *cdma)
176{
177 struct host1x *host = cdma_to_host1x(cdma);
178 struct host1x_channel *ch = cdma_to_channel(cdma);
179 u32 cmdproc_stop;
180
181 if (cdma->torndown && !cdma->running) {
182 dev_warn(host->dev, "Already torn down\n");
183 return;
184 }
185
186 dev_dbg(host->dev, "freezing channel (id %d)\n", ch->id);
187
188 cmdproc_stop = host1x_ch_readl(ch, HOST1X_SYNC_CMDPROC_STOP);
189 cmdproc_stop |= BIT(0);
190 host1x_ch_writel(ch, cmdproc_stop, HOST1X_SYNC_CMDPROC_STOP);
191
192 dev_dbg(host->dev, "%s: DMA GET 0x%x, PUT HW 0x%x / shadow 0x%x\n",
193 __func__, host1x_ch_readl(ch, HOST1X_CHANNEL_DMAGET),
194 host1x_ch_readl(ch, HOST1X_CHANNEL_DMAPUT),
195 cdma->last_pos);
196
197 host1x_ch_writel(ch, HOST1X_CHANNEL_DMACTRL_DMASTOP,
198 HOST1X_CHANNEL_DMACTRL);
199
200 host1x_ch_writel(ch, BIT(0), HOST1X_SYNC_CH_TEARDOWN);
201
202 cdma->running = false;
203 cdma->torndown = true;
204}
205
206static void cdma_resume(struct host1x_cdma *cdma, u32 getptr)
207{
208 struct host1x *host1x = cdma_to_host1x(cdma);
209 struct host1x_channel *ch = cdma_to_channel(cdma);
210 u32 cmdproc_stop;
211
212 dev_dbg(host1x->dev,
213 "resuming channel (id %d, DMAGET restart = 0x%x)\n",
214 ch->id, getptr);
215
216 cmdproc_stop = host1x_ch_readl(ch, HOST1X_SYNC_CMDPROC_STOP);
217 cmdproc_stop &= ~(BIT(0));
218 host1x_ch_writel(ch, cmdproc_stop, HOST1X_SYNC_CMDPROC_STOP);
219
220 cdma->torndown = false;
221 cdma_timeout_restart(cdma, getptr);
222}
223
224/*
225 * If this timeout fires, it indicates the current sync_queue entry has
226 * exceeded its TTL and the userctx should be timed out and remaining
227 * submits already issued cleaned up (future submits return an error).
228 */
229static void cdma_timeout_handler(struct work_struct *work)
230{
231 struct host1x_cdma *cdma;
232 struct host1x *host1x;
233 struct host1x_channel *ch;
234 bool has_timedout = 0;
235
236 u32 prev_cmdproc, cmdproc_stop;
237
238 unsigned int i;
239
240 cdma = container_of(to_delayed_work(work), struct host1x_cdma,
241 timeout.wq);
242 host1x = cdma_to_host1x(cdma);
243 ch = cdma_to_channel(cdma);
244
245 host1x_debug_dump(cdma_to_host1x(cdma));
246
247 mutex_lock(&cdma->lock);
248
249 if (!cdma->timeout.client) {
250 dev_dbg(host1x->dev,
251 "cdma_timeout: expired, but has no clientid\n");
252 mutex_unlock(&cdma->lock);
253 return;
254 }
255
256 /* stop processing to get a clean snapshot */
257 prev_cmdproc = host1x_ch_readl(ch, HOST1X_SYNC_CMDPROC_STOP);
258 cmdproc_stop = prev_cmdproc | BIT(0);
259 host1x_ch_writel(ch, cmdproc_stop, HOST1X_SYNC_CMDPROC_STOP);
260
261 dev_dbg(host1x->dev, "cdma_timeout: cmdproc was 0x%x is 0x%x\n",
262 prev_cmdproc, cmdproc_stop);
263
264 for (i = 0; i < cdma->timeout.num_syncpts; ++i) {
265 u32 id = cdma->timeout.syncpts[i].id;
266 u32 end = cdma->timeout.syncpts[i].end;
267 struct host1x_syncpt *syncpt = host1x_syncpt_get(host1x, id);
268
269 host1x_syncpt_load(syncpt);
270
271 has_timedout = !host1x_syncpt_is_expired(syncpt, end);
272 if (has_timedout)
273 break;
274 }
275
276 /* has buffer actually completed? */
277 if (!has_timedout) {
278 dev_dbg(host1x->dev,
279 "cdma_timeout: expired, but buffer had completed\n");
280 /* restore */
281 cmdproc_stop = prev_cmdproc & ~(BIT(0));
282 host1x_ch_writel(ch, cmdproc_stop,
283 HOST1X_SYNC_CMDPROC_STOP);
284 mutex_unlock(&cdma->lock);
285 return;
286 }
287
288 for (i = 0; i < cdma->timeout.num_syncpts; ++i) {
289 u32 id = cdma->timeout.syncpts[i].id;
290 struct host1x_syncpt *syncpt = host1x_syncpt_get(host1x, id);
291 u32 syncpt_val = host1x_syncpt_read_min(syncpt);
292
293 dev_warn(host1x->dev, "%s: timeout: %d (%s), HW thresh %d, done %d\n",
294 __func__, syncpt->id, syncpt->name,
295 syncpt_val, syncpt_val);
296 }
297
298 /* stop HW, resetting channel/module */
299 host1x_hw_cdma_freeze(host1x, cdma);
300
301 host1x_cdma_update_sync_queue(cdma, ch->dev);
302 mutex_unlock(&cdma->lock);
303}
304
305/*
306 * Init timeout resources
307 */
308static int cdma_timeout_init(struct host1x_cdma *cdma)
309{
310 INIT_DELAYED_WORK(&cdma->timeout.wq, cdma_timeout_handler);
311 cdma->timeout.initialized = true;
312
313 return 0;
314}
315
316/*
317 * Clean up timeout resources
318 */
319static void cdma_timeout_destroy(struct host1x_cdma *cdma)
320{
321 if (cdma->timeout.initialized)
322 cancel_delayed_work(&cdma->timeout.wq);
323 cdma->timeout.initialized = false;
324}
325
326static const struct host1x_cdma_ops host1x_cdma_t186_ops = {
327 .start = cdma_start,
328 .stop = cdma_stop,
329 .flush = cdma_flush,
330
331 .timeout_init = cdma_timeout_init,
332 .timeout_destroy = cdma_timeout_destroy,
333 .freeze = cdma_freeze,
334 .resume = cdma_resume,
335 .timeout_handle = cdma_timeout_handle,
336};
337
338static const struct host1x_pushbuffer_ops host1x_pushbuffer_t186_ops = {
339 .init = push_buffer_init,
340};
diff --git a/drivers/gpu/host1x/hw/channel_hw_t186.c b/drivers/gpu/host1x/hw/channel_hw_t186.c
new file mode 100644
index 000000000..256368f29
--- /dev/null
+++ b/drivers/gpu/host1x/hw/channel_hw_t186.c
@@ -0,0 +1,302 @@
1/*
2 * Tegra host1x Channel
3 *
4 * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/host1x.h>
20#include <linux/slab.h>
21#include <linux/iommu.h>
22#include <linux/pm_runtime.h>
23
24#include <trace/events/host1x.h>
25
26#include "dev_t186.h"
27#include "channel.h"
28#include "intr.h"
29#include "job.h"
30
31#define TRACE_MAX_LENGTH 128U
32
33static void trace_write_gather(struct host1x_cdma *cdma, struct host1x_bo *bo,
34 u32 offset, u32 words)
35{
36 struct device *dev = cdma_to_channel(cdma)->dev;
37 void *mem = NULL;
38
39 if (host1x_debug_trace_cmdbuf)
40 mem = host1x_bo_mmap(bo);
41
42 if (mem) {
43 u32 i;
44 /*
45 * Write in batches of 128 as there seems to be a limit
46 * of how much you can output to ftrace at once.
47 */
48 for (i = 0; i < words; i += TRACE_MAX_LENGTH) {
49 u32 num_words = min(words - i, TRACE_MAX_LENGTH);
50 u32 next_offset = offset + i * sizeof(u32);
51
52 trace_host1x_cdma_push_gather(dev_name(dev), bo,
53 num_words,
54 next_offset,
55 mem);
56 }
57
58 host1x_bo_munmap(bo, mem);
59 }
60}
61
62static void channel_push_wait(struct host1x_channel *channel,
63 u32 id, u32 thresh)
64{
65 host1x_cdma_push(&channel->cdma,
66 host1x_opcode_setclass(HOST1X_CLASS_HOST1X,
67 HOST1X_UCLASS_LOAD_SYNCPT_PAYLOAD_32, 1),
68 thresh);
69 host1x_cdma_push(&channel->cdma,
70 host1x_opcode_setclass(HOST1X_CLASS_HOST1X,
71 HOST1X_UCLASS_WAIT_SYNCPT_32, 1),
72 id);
73}
74
75static inline void serialize(struct host1x_job *job)
76{
77 struct host1x_channel *ch = job->channel;
78 struct host1x *host = dev_get_drvdata(ch->dev->parent);
79 unsigned int i;
80
81 for (i = 0; i < job->num_syncpts; ++i) {
82 u32 syncpt_id = job->syncpts[i].id;
83 struct host1x_syncpt *syncpt =
84 host1x_syncpt_get(host, syncpt_id);
85
86 /*
87 * Force serialization by inserting a host wait for the
88 * previous job to finish before this one can commence.
89 */
90 channel_push_wait(ch, syncpt_id, host1x_syncpt_read_max(syncpt));
91 }
92}
93
94static void add_sync_waits(struct host1x_job *job)
95{
96 struct host1x *host = dev_get_drvdata(job->channel->dev->parent);
97 unsigned int i;
98
99 for (i = 0; i < job->num_gathers; i++) {
100 struct host1x_job_gather *g = &job->gathers[i];
101
102 if (g->pre_fence)
103 host1x_sync_fence_wait(g->pre_fence, host,
104 job->channel);
105 }
106}
107
108static void submit_gathers(struct host1x_job *job)
109{
110 struct host1x_cdma *cdma = &job->channel->cdma;
111 unsigned int i;
112 u32 cur_class = 0;
113
114 cur_class = HOST1X_CLASS_HOST1X;
115 host1x_cdma_push(cdma,
116 host1x_opcode_acquire_mlock(cur_class),
117 host1x_opcode_setclass(cur_class, 0, 0));
118
119 add_sync_waits(job);
120
121 for (i = 0; i < job->num_gathers; i++) {
122 struct host1x_job_gather *g = &job->gathers[i];
123 u32 op1 = host1x_opcode_gather(g->words);
124 u32 op2 = g->base + g->offset;
125
126 /* add a setclass for modules that require it */
127 if (cur_class != g->class_id) {
128 if (cur_class)
129 host1x_cdma_push(cdma,
130 HOST1X_OPCODE_NOP,
131 host1x_opcode_release_mlock(cur_class));
132
133 host1x_cdma_push(cdma,
134 host1x_opcode_acquire_mlock(g->class_id),
135 host1x_opcode_setclass(g->class_id, 0, 0));
136 cur_class = g->class_id;
137 }
138
139 trace_write_gather(cdma, g->bo, g->offset, op1 & 0xffff);
140 host1x_cdma_push(cdma, op1, op2);
141 }
142
143 if (job->serialize)
144 serialize(job);
145
146 if (cur_class)
147 host1x_cdma_push(cdma,
148 HOST1X_OPCODE_NOP,
149 host1x_opcode_release_mlock(cur_class));
150}
151
152static inline void synchronize_syncpt_base(struct host1x_job *job)
153{
154 struct host1x_channel *ch = job->channel;
155 struct host1x *host = dev_get_drvdata(ch->dev->parent);
156 unsigned int i;
157
158 for (i = 0; i < job->num_syncpts; ++i) {
159 u32 syncpt_id = job->syncpts[i].id;
160 struct host1x_syncpt *syncpt =
161 host1x_syncpt_get(host, syncpt_id);
162 u32 base_id, value;
163
164 if (!syncpt->base)
165 continue;
166
167 value = host1x_syncpt_read_max(syncpt);
168 base_id = syncpt->base->id;
169
170 host1x_cdma_push(&job->channel->cdma,
171 host1x_opcode_setclass(HOST1X_CLASS_HOST1X,
172 HOST1X_UCLASS_LOAD_SYNCPT_BASE, 1),
173 HOST1X_UCLASS_LOAD_SYNCPT_BASE_BASE_INDX_F(base_id) |
174 HOST1X_UCLASS_LOAD_SYNCPT_BASE_VALUE_F(value));
175 }
176}
177
178static int channel_submit(struct host1x_job *job)
179{
180 struct host1x_channel *ch = job->channel;
181 struct host1x_syncpt *syncpt;
182 u32 prev_max = 0;
183 int err;
184 struct host1x_waitlist *completed_waiter[job->num_syncpts];
185 struct host1x *host = dev_get_drvdata(ch->dev->parent);
186 unsigned int i;
187 int streamid = 0;
188
189 trace_host1x_channel_submit(dev_name(ch->dev),
190 job->num_gathers, job->num_relocs,
191 job->num_waitchk, job->syncpts[0].id,
192 job->syncpts[0].incrs);
193
194 /* before error checks, return current max */
195 syncpt = host1x_syncpt_get(host, job->syncpts[0].id);
196 prev_max = host1x_syncpt_read_max(syncpt);
197
198 /* keep device powered on */
199 for (i = 0; i < job->num_syncpts; ++i)
200 pm_runtime_get_sync(ch->dev);
201
202 /* get submit lock */
203 err = mutex_lock_interruptible(&ch->submitlock);
204 if (err)
205 goto error;
206
207 for (i = 0; i < job->num_syncpts; i++) {
208 completed_waiter[i] = kzalloc(sizeof(*completed_waiter[i]),
209 GFP_KERNEL);
210 if (!completed_waiter[i]) {
211 mutex_unlock(&ch->submitlock);
212 err = -ENOMEM;
213 goto error;
214 }
215 }
216
217 streamid = iommu_get_hwid(host->dev->archdata.iommu, host->dev, 0);
218 if (streamid >= 0)
219 host1x_ch_writel(ch, streamid, HOST1X_CHANNEL_SMMU_STREAMID);
220
221 /* begin a CDMA submit */
222 err = host1x_cdma_begin(&ch->cdma, job);
223 if (err) {
224 mutex_unlock(&ch->submitlock);
225 goto error;
226 }
227
228 /* Synchronize base register to allow using it for relative waiting */
229 synchronize_syncpt_base(job);
230
231 /* Increment syncpoint maximum values */
232 for (i = 0; i < job->num_syncpts; ++i) {
233 u32 id;
234 u32 incrs;
235
236 id = job->syncpts[i].id;
237 incrs = job->syncpts[i].incrs;
238 syncpt = host1x_syncpt_get(host, id);
239 job->syncpts[i].end = host1x_syncpt_incr_max(syncpt, incrs);
240 }
241
242 submit_gathers(job);
243
244 /* end CDMA submit & stash pinned hMems into sync queue */
245 host1x_cdma_end(&ch->cdma, job);
246
247 trace_host1x_channel_submitted(dev_name(ch->dev), prev_max,
248 job->syncpts[0].end);
249
250 /* schedule submit complete interrupts */
251 for (i = 0; i < job->num_syncpts; ++i) {
252 u32 syncpt_id = job->syncpts[i].id;
253 u32 syncpt_end = job->syncpts[i].end;
254
255 err = host1x_intr_add_action(host, syncpt_id, syncpt_end,
256 HOST1X_INTR_ACTION_SUBMIT_COMPLETE,
257 ch, completed_waiter[i], NULL);
258 completed_waiter[i] = NULL;
259 WARN(err, "Failed to set submit complete interrupt");
260 }
261
262 mutex_unlock(&ch->submitlock);
263
264 return 0;
265
266error:
267 for (i = 0; i < job->num_syncpts; i++)
268 kfree(completed_waiter[i]);
269 return err;
270}
271
272static int host1x_channel_init(struct host1x_channel *ch, struct host1x *dev,
273 unsigned int index)
274{
275 ch->id = index;
276 mutex_init(&ch->reflock);
277 mutex_init(&ch->submitlock);
278
279 ch->regs = dev->regs + (HOST1X_CHANNEL_CH_APERTURE_START +
280 index * HOST1X_CHANNEL_CH_APERTURE_SIZE);
281 return 0;
282}
283
284static void channel_enable_gather_filter(struct host1x_channel *ch)
285{
286 struct host1x *host = dev_get_drvdata(ch->dev->parent);
287 u32 val;
288
289 val = host1x_readl(host, HOST1X_CHANNEL_FILTER_GBUFFER
290 + BIT_WORD(ch->id) * sizeof(u32));
291
292 host1x_writel(host, val | BIT_MASK(ch->id),
293 HOST1X_CHANNEL_FILTER_GBUFFER
294 + BIT_WORD(ch->id) * sizeof(u32));
295}
296
297static const struct host1x_channel_ops host1x_channel_t186_ops = {
298 .init = host1x_channel_init,
299 .submit = channel_submit,
300 .push_wait = channel_push_wait,
301 .enable_gather_filter = channel_enable_gather_filter,
302};
diff --git a/drivers/gpu/host1x/hw/debug_hw_t186.c b/drivers/gpu/host1x/hw/debug_hw_t186.c
new file mode 100644
index 000000000..d6111668e
--- /dev/null
+++ b/drivers/gpu/host1x/hw/debug_hw_t186.c
@@ -0,0 +1,288 @@
1/*
2 * Copyright (C) 2010 Google, Inc.
3 * Author: Erik Gilling <konkers@android.com>
4 *
5 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#include "dev.h"
19#include "debug.h"
20#include "cdma.h"
21#include "channel.h"
22
23#define HOST1X_DEBUG_MAX_PAGE_OFFSET 102400
24
25enum {
26 HOST1X_OPCODE_SETCLASS = 0x00,
27 HOST1X_OPCODE_INCR = 0x01,
28 HOST1X_OPCODE_NONINCR = 0x02,
29 HOST1X_OPCODE_MASK = 0x03,
30 HOST1X_OPCODE_IMM = 0x04,
31 HOST1X_OPCODE_RESTART = 0x05,
32 HOST1X_OPCODE_GATHER = 0x06,
33 HOST1X_OPCODE_EXTEND = 0x0e,
34};
35
36enum {
37 HOST1X_OPCODE_EXTEND_ACQUIRE_MLOCK = 0x00,
38 HOST1X_OPCODE_EXTEND_RELEASE_MLOCK = 0x01,
39};
40
41static unsigned int show_channel_command(struct output *o, u32 val)
42{
43 unsigned mask;
44 unsigned subop;
45
46 switch (val >> 28) {
47 case HOST1X_OPCODE_SETCLASS:
48 mask = val & 0x3f;
49 if (mask) {
50 host1x_debug_output(o, "SETCL(class=%03x, offset=%03x, mask=%02x, [",
51 val >> 6 & 0x3ff,
52 val >> 16 & 0xfff, mask);
53 return hweight8(mask);
54 } else {
55 host1x_debug_output(o, "SETCL(class=%03x)\n",
56 val >> 6 & 0x3ff);
57 return 0;
58 }
59
60 case HOST1X_OPCODE_INCR:
61 host1x_debug_output(o, "INCR(offset=%03x, [",
62 val >> 16 & 0xfff);
63 return val & 0xffff;
64
65 case HOST1X_OPCODE_NONINCR:
66 host1x_debug_output(o, "NONINCR(offset=%03x, [",
67 val >> 16 & 0xfff);
68 return val & 0xffff;
69
70 case HOST1X_OPCODE_MASK:
71 mask = val & 0xffff;
72 host1x_debug_output(o, "MASK(offset=%03x, mask=%03x, [",
73 val >> 16 & 0xfff, mask);
74 return hweight16(mask);
75
76 case HOST1X_OPCODE_IMM:
77 host1x_debug_output(o, "IMM(offset=%03x, data=%03x)\n",
78 val >> 16 & 0xfff, val & 0xffff);
79 return 0;
80
81 case HOST1X_OPCODE_RESTART:
82 host1x_debug_output(o, "RESTART(offset=%08x)\n", val << 4);
83 return 0;
84
85 case HOST1X_OPCODE_GATHER:
86 host1x_debug_output(o, "GATHER(offset=%03x, insert=%d, type=%d, count=%04x, addr=[",
87 val >> 16 & 0xfff, val >> 15 & 0x1,
88 val >> 14 & 0x1, val & 0x3fff);
89 return 1;
90
91 case HOST1X_OPCODE_EXTEND:
92 subop = val >> 24 & 0xf;
93 if (subop == HOST1X_OPCODE_EXTEND_ACQUIRE_MLOCK)
94 host1x_debug_output(o, "ACQUIRE_MLOCK(index=%d)\n",
95 val & 0xff);
96 else if (subop == HOST1X_OPCODE_EXTEND_RELEASE_MLOCK)
97 host1x_debug_output(o, "RELEASE_MLOCK(index=%d)\n",
98 val & 0xff);
99 else
100 host1x_debug_output(o, "EXTEND_UNKNOWN(%08x)\n", val);
101 return 0;
102
103 default:
104 return 0;
105 }
106}
107
108static void show_gather(struct output *o, phys_addr_t phys_addr,
109 unsigned int words, struct host1x_cdma *cdma,
110 phys_addr_t pin_addr, u32 *map_addr)
111{
112 /* Map dmaget cursor to corresponding mem handle */
113 u32 offset = phys_addr - pin_addr;
114 unsigned int data_count = 0, i;
115
116 /*
117 * Sometimes we're given different hardware address to the same
118 * page - in these cases the offset will get an invalid number and
119 * we just have to bail out.
120 */
121 if (offset > HOST1X_DEBUG_MAX_PAGE_OFFSET) {
122 host1x_debug_output(o, "[address mismatch]\n");
123 return;
124 }
125
126 for (i = 0; i < words; i++) {
127 u32 addr = phys_addr + i * 4;
128 u32 val = *(map_addr + offset / 4 + i);
129
130 if (!data_count) {
131 host1x_debug_output(o, "%08x: %08x:", addr, val);
132 data_count = show_channel_command(o, val);
133 } else {
134 host1x_debug_output(o, "%08x%s", val,
135 data_count > 0 ? ", " : "])\n");
136 data_count--;
137 }
138 }
139}
140
141static void show_channel_gathers(struct output *o, struct host1x_cdma *cdma)
142{
143 struct host1x_job *job;
144
145 list_for_each_entry(job, &cdma->sync_queue, list) {
146 int i;
147 host1x_debug_output(o, "\n%p: JOB, syncpt_id=%d, syncpt_val=%d, first_get=%08x, timeout=%d num_slots=%d, num_handles=%d\n",
148 job,
149 (job->syncpts ? job->syncpts[0].id : 0),
150 (job->syncpts ? job->syncpts[0].end : 0),
151 job->first_get, job->timeout,
152 job->num_slots, job->num_unpins);
153
154 for (i = 0; i < job->num_gathers; i++) {
155 struct host1x_job_gather *g = &job->gathers[i];
156 u32 *mapped;
157
158 if (job->gather_copy_mapped)
159 mapped = (u32 *)job->gather_copy_mapped;
160 else
161 mapped = host1x_bo_mmap(g->bo);
162
163 if (!mapped) {
164 host1x_debug_output(o, "[could not mmap]\n");
165 continue;
166 }
167
168 host1x_debug_output(o, " GATHER at %pad+%#x, %d words\n",
169 &g->base, g->offset, g->words);
170
171 show_gather(o, g->base + g->offset, g->words, cdma,
172 g->base, mapped);
173
174 if (!job->gather_copy_mapped)
175 host1x_bo_munmap(g->bo, mapped);
176 }
177 }
178}
179
180static void host1x_debug_show_channel_cdma(struct host1x *host,
181 struct host1x_channel *ch,
182 struct output *o)
183{
184 struct host1x_cdma *cdma = &ch->cdma;
185 u32 val;
186
187 host1x_debug_output(o, "Host1x basic channel registers: \n");
188
189 val = host1x_ch_readl(ch, HOST1X_CHANNEL_FIFOSTAT);
190 host1x_debug_output(o, "CMDFIFO_STAT_0: %08x\n", val);
191 val = host1x_ch_readl(ch, HOST1X_CHANNEL_RDATA);
192 host1x_debug_output(o, "CMDFIFO_RDATA_0: %08x\n", val);
193 val = host1x_ch_readl(ch, HOST1X_CHANNEL_CMDP_OFFSET);
194 host1x_debug_output(o, "CMDP_OFFSET_0: %08x\n", val);
195 val = host1x_ch_readl(ch, HOST1X_CHANNEL_CMDP_CLASS);
196 host1x_debug_output(o, "CMDP_CLASS_0: %08x\n", val);
197 val = host1x_ch_readl(ch, HOST1X_CHANNEL_CMDP_CHANNELSTAT);
198 host1x_debug_output(o, "CHANNELSTAT_0: %08x\n", val);
199
200 show_channel_gathers(o, cdma);
201 host1x_debug_output(o, "\n");
202}
203
204static void host1x_debug_show_channel_fifo(struct host1x *host,
205 struct host1x_channel *ch,
206 struct output *o)
207{
208 u32 val, rd_ptr, wr_ptr, start, end, temp;
209 unsigned int data_count = 0;
210
211 host1x_debug_output(o, "%d: fifo:\n", ch->id);
212
213 temp = host1x_sync_readl(host, HOST1X_THOST_COMMON_ICG_EN_OVERRIDE_0);
214 host1x_sync_writel(host, 0x1, HOST1X_THOST_COMMON_ICG_EN_OVERRIDE_0);
215
216 val = host1x_ch_readl(ch, HOST1X_CHANNEL_FIFOSTAT);
217 host1x_debug_output(o, "FIFOSTAT %08x\n", val);
218 if (HOST1X_CHANNEL_FIFOSTAT_CFEMPTY_V(val)) {
219 host1x_debug_output(o, "[empty]\n");
220 return;
221 }
222
223 host1x_sync_writel(host, 0x0, HOST1X_SYNC_CFPEEK_CTRL);
224 host1x_sync_writel(host, HOST1X_SYNC_CFPEEK_CTRL_ENA_F(1) |
225 HOST1X_SYNC_CFPEEK_CTRL_CHANNR_F(ch->id),
226 HOST1X_SYNC_CFPEEK_CTRL);
227
228 val = host1x_sync_readl(host, HOST1X_SYNC_CFPEEK_PTRS);
229 rd_ptr = HOST1X_SYNC_CFPEEK_PTRS_CF_RD_PTR_V(val);
230 wr_ptr = HOST1X_SYNC_CFPEEK_PTRS_CF_WR_PTR_V(val);
231
232 val = host1x_sync_readl(host, HOST1X_SYNC_CF_SETUP(ch->id));
233 start = HOST1X_SYNC_CF_SETUP_BASE_V(val);
234 end = HOST1X_SYNC_CF_SETUP_LIMIT_V(val);
235
236 do {
237 host1x_sync_writel(host, 0x0, HOST1X_SYNC_CFPEEK_CTRL);
238 host1x_sync_writel(host, HOST1X_SYNC_CFPEEK_CTRL_ENA_F(1) |
239 HOST1X_SYNC_CFPEEK_CTRL_CHANNR_F(ch->id) |
240 HOST1X_SYNC_CFPEEK_CTRL_ADDR_F(rd_ptr),
241 HOST1X_SYNC_CFPEEK_CTRL);
242 val = host1x_sync_readl(host, HOST1X_SYNC_CFPEEK_READ);
243
244 if (!data_count) {
245 host1x_debug_output(o, "%08x:", val);
246 data_count = show_channel_command(o, val);
247 } else {
248 host1x_debug_output(o, "%08x%s", val,
249 data_count > 0 ? ", " : "])\n");
250 data_count--;
251 }
252
253 if (rd_ptr == end)
254 rd_ptr = start;
255 else
256 rd_ptr++;
257 } while (rd_ptr != wr_ptr);
258
259 if (data_count)
260 host1x_debug_output(o, ", ...])\n");
261 host1x_debug_output(o, "\n");
262
263 host1x_sync_writel(host, 0x0, HOST1X_SYNC_CFPEEK_CTRL);
264
265 host1x_sync_writel(host, temp, HOST1X_THOST_COMMON_ICG_EN_OVERRIDE_0);
266}
267
268static void host1x_debug_show_mlocks(struct host1x *host, struct output *o)
269{
270 int i;
271 unsigned int chid;
272 bool cpu, ch;
273
274 host1x_debug_output(o, "---- mlocks ----\n");
275 for (i = 0; i < host1x_syncpt_nb_mlocks(host); i++) {
276 host1x_hw_sync_get_mutex_owner(host, host->syncpt,
277 i, &cpu, &ch, &chid);
278 if (ch)
279 host1x_debug_output(o, "%d: locked by channel %d\n", i, chid);
280 }
281 host1x_debug_output(o, "\n");
282}
283
284static const struct host1x_debug_ops host1x_debug_t186_ops = {
285 .show_channel_cdma = host1x_debug_show_channel_cdma,
286 .show_channel_fifo = host1x_debug_show_channel_fifo,
287 .show_mlocks = host1x_debug_show_mlocks,
288};
diff --git a/drivers/gpu/host1x/hw/host1x05.c b/drivers/gpu/host1x/hw/host1x05.c
new file mode 100644
index 000000000..3a790bee4
--- /dev/null
+++ b/drivers/gpu/host1x/hw/host1x05.c
@@ -0,0 +1,42 @@
1/*
2 * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17/* include hw specification */
18#include "host1x05.h"
19#include "host1x05_hardware.h"
20
21/* include code */
22#include "cdma_hw_t186.c"
23#include "channel_hw_t186.c"
24#include "debug_hw_t186.c"
25#include "intr_hw_t186.c"
26#include "syncpt_hw_t186.c"
27#include "stremid_hw_t186.c"
28
29#include "dev.h"
30
31int host1x05_init(struct host1x *host)
32{
33 host->dev_op = &host1x_dev_t186_ops;
34 host->channel_op = &host1x_channel_t186_ops;
35 host->cdma_op = &host1x_cdma_t186_ops;
36 host->cdma_pb_op = &host1x_pushbuffer_t186_ops;
37 host->syncpt_op = &host1x_syncpt_t186_ops;
38 host->intr_op = &host1x_intr_t186_ops;
39 host->debug_op = &host1x_debug_t186_ops;
40
41 return 0;
42}
diff --git a/drivers/gpu/host1x/hw/host1x05.h b/drivers/gpu/host1x/hw/host1x05.h
new file mode 100644
index 000000000..e1b842146
--- /dev/null
+++ b/drivers/gpu/host1x/hw/host1x05.h
@@ -0,0 +1,24 @@
1/*
2 * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef HOST1X_HOST1X05_H
18#define HOST1X_HOST1X05_H
19
20struct host1x;
21
22int host1x05_init(struct host1x *host);
23
24#endif
diff --git a/drivers/gpu/host1x/hw/host1x05_hardware.h b/drivers/gpu/host1x/hw/host1x05_hardware.h
new file mode 100644
index 000000000..add00014e
--- /dev/null
+++ b/drivers/gpu/host1x/hw/host1x05_hardware.h
@@ -0,0 +1,128 @@
1/*
2 * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef __HOST1X_HOST1X05_HARDWARE_H
18#define __HOST1X_HOST1X05_HARDWARE_H
19
20#include <linux/types.h>
21#include <linux/bitops.h>
22
23#include "hw_host1x05_channel.h"
24#include "hw_host1x05_sync.h"
25#include "hw_host1x05_uclass.h"
26
27static inline u32 host1x_class_host_wait_syncpt(
28 unsigned indx, unsigned threshold)
29{
30 return host1x_uclass_wait_syncpt_indx_f(indx)
31 | host1x_uclass_wait_syncpt_thresh_f(threshold);
32}
33
34static inline u32 host1x_class_host_load_syncpt_base(
35 unsigned indx, unsigned threshold)
36{
37 return host1x_uclass_load_syncpt_base_base_indx_f(indx)
38 | host1x_uclass_load_syncpt_base_value_f(threshold);
39}
40
41static inline u32 host1x_class_host_wait_syncpt_base(
42 unsigned indx, unsigned base_indx, unsigned offset)
43{
44 return host1x_uclass_wait_syncpt_base_indx_f(indx)
45 | host1x_uclass_wait_syncpt_base_base_indx_f(base_indx)
46 | host1x_uclass_wait_syncpt_base_offset_f(offset);
47}
48
49static inline u32 host1x_class_host_incr_syncpt_base(
50 unsigned base_indx, unsigned offset)
51{
52 return host1x_uclass_incr_syncpt_base_base_indx_f(base_indx)
53 | host1x_uclass_incr_syncpt_base_offset_f(offset);
54}
55
56static inline u32 host1x_class_host_incr_syncpt(
57 unsigned cond, unsigned indx)
58{
59 return host1x_uclass_incr_syncpt_cond_f(cond)
60 | host1x_uclass_incr_syncpt_indx_f(indx);
61}
62
63/* cdma opcodes */
64static inline u32 host1x_opcode_setclass(
65 unsigned class_id, unsigned offset, unsigned mask)
66{
67 return (0 << 28) | (offset << 16) | (class_id << 6) | mask;
68}
69
70static inline u32 host1x_opcode_incr(unsigned offset, unsigned count)
71{
72 return (1 << 28) | (offset << 16) | count;
73}
74
75static inline u32 host1x_opcode_nonincr(unsigned offset, unsigned count)
76{
77 return (2 << 28) | (offset << 16) | count;
78}
79
80static inline u32 host1x_opcode_mask(unsigned offset, unsigned mask)
81{
82 return (3 << 28) | (offset << 16) | mask;
83}
84
85static inline u32 host1x_opcode_imm(unsigned offset, unsigned value)
86{
87 return (4 << 28) | (offset << 16) | value;
88}
89
90static inline u32 host1x_opcode_imm_incr_syncpt(unsigned cond, unsigned indx)
91{
92 return host1x_opcode_imm(host1x_uclass_incr_syncpt_r(),
93 host1x_class_host_incr_syncpt(cond, indx));
94}
95
96static inline u32 host1x_opcode_restart(unsigned address)
97{
98 return (5 << 28) | (address >> 4);
99}
100
101static inline u32 host1x_opcode_gather(unsigned count)
102{
103 return (6 << 28) | count;
104}
105
106static inline u32 host1x_opcode_gather_nonincr(unsigned offset, unsigned count)
107{
108 return (6 << 28) | (offset << 16) | BIT(15) | count;
109}
110
111static inline u32 host1x_opcode_gather_incr(unsigned offset, unsigned count)
112{
113 return (6 << 28) | (offset << 16) | BIT(15) | BIT(14) | count;
114}
115
116static inline u32 host1x_opcode_acquire_mlock(unsigned id)
117{
118 return (14 << 28) | id;
119}
120
121static inline u32 host1x_opcode_release_mlock(unsigned id)
122{
123 return (14 << 28) | (1 << 24) | id;
124}
125
126#define HOST1X_OPCODE_NOP host1x_opcode_nonincr(0, 0)
127
128#endif
diff --git a/drivers/gpu/host1x/hw/hw_host1x05_channel.h b/drivers/gpu/host1x/hw/hw_host1x05_channel.h
new file mode 100644
index 000000000..8c3499f91
--- /dev/null
+++ b/drivers/gpu/host1x/hw/hw_host1x05_channel.h
@@ -0,0 +1,169 @@
1/*
2 * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17
18 /*
19 * Function naming determines intended use:
20 *
21 * <x>_r(void) : Returns the offset for register <x>.
22 *
23 * <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
24 *
25 * <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
26 *
27 * <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
28 * and masked to place it at field <y> of register <x>. This value
29 * can be |'d with others to produce a full register value for
30 * register <x>.
31 *
32 * <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
33 * value can be ~'d and then &'d to clear the value of field <y> for
34 * register <x>.
35 *
36 * <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
37 * to place it at field <y> of register <x>. This value can be |'d
38 * with others to produce a full register value for <x>.
39 *
40 * <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
41 * <x> value 'r' after being shifted to place its LSB at bit 0.
42 * This value is suitable for direct comparison with other unshifted
43 * values appropriate for use in field <y> of register <x>.
44 *
45 * <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
46 * field <y> of register <x>. This value is suitable for direct
47 * comparison with unshifted values appropriate for use in field <y>
48 * of register <x>.
49 */
50
51#ifndef HOST1X_HW_HOST1X05_CHANNEL_H
52#define HOST1X_HW_HOST1X05_CHANNEL_H
53
54static inline u32 host1x_channel_ch_aperture_start_r(void)
55{
56 return 0x10000;
57}
58#define HOST1X_CHANNEL_CH_APERTURE_START \
59 host1x_channel_ch_aperture_start_r()
60static inline u32 host1x_channel_ch_aperture_size_r(void)
61{
62 return 0x100;
63}
64#define HOST1X_CHANNEL_CH_APERTURE_SIZE \
65 host1x_channel_ch_aperture_size_r()
66static inline u32 host1x_channel_fifostat_r(void)
67{
68 return 0x24;
69}
70#define HOST1X_CHANNEL_FIFOSTAT \
71 host1x_channel_fifostat_r()
72static inline u32 host1x_channel_fifostat_cfempty_v(u32 r)
73{
74 return (r >> 13) & 0x1;
75}
76#define HOST1X_CHANNEL_FIFOSTAT_CFEMPTY_V(r) \
77 host1x_channel_fifostat_cfempty_v(r)
78static inline u32 host1x_channel_rdata_r(void)
79{
80 return 0x28;
81}
82#define HOST1X_CHANNEL_RDATA \
83 host1x_channel_rdata_r()
84static inline u32 host1x_channel_cmdp_offset_r(void)
85{
86 return 0x30;
87}
88#define HOST1X_CHANNEL_CMDP_OFFSET \
89 host1x_channel_cmdp_offset_r()
90static inline u32 host1x_channel_cmdp_class_r(void)
91{
92 return 0x34;
93}
94#define HOST1X_CHANNEL_CMDP_CLASS \
95 host1x_channel_cmdp_class_r()
96static inline u32 host1x_channel_cmdp_channelstat_r(void)
97{
98 return 0x38;
99}
100#define HOST1X_CHANNEL_CMDP_CHANNELSTAT \
101 host1x_channel_cmdp_channelstat_r()
102static inline u32 host1x_channel_dmastart_r(void)
103{
104 return 0x0;
105}
106#define HOST1X_CHANNEL_DMASTART \
107 host1x_channel_dmastart_r()
108static inline u32 host1x_channel_dmaput_r(void)
109{
110 return 0x8;
111}
112#define HOST1X_CHANNEL_DMAPUT \
113 host1x_channel_dmaput_r()
114static inline u32 host1x_channel_dmaget_r(void)
115{
116 return 0x10;
117}
118#define HOST1X_CHANNEL_DMAGET \
119 host1x_channel_dmaget_r()
120static inline u32 host1x_channel_dmaend_r(void)
121{
122 return 0x18;
123}
124#define HOST1X_CHANNEL_DMAEND \
125 host1x_channel_dmaend_r()
126static inline u32 host1x_channel_dmactrl_r(void)
127{
128 return 0x20;
129}
130#define HOST1X_CHANNEL_DMACTRL \
131 host1x_channel_dmactrl_r()
132static inline u32 host1x_channel_dmactrl_dmastop(void)
133{
134 return 1 << 0;
135}
136#define HOST1X_CHANNEL_DMACTRL_DMASTOP \
137 host1x_channel_dmactrl_dmastop()
138static inline u32 host1x_channel_dmactrl_dmastop_v(u32 r)
139{
140 return (r >> 0) & 0x1;
141}
142#define HOST1X_CHANNEL_DMACTRL_DMASTOP_V(r) \
143 host1x_channel_dmactrl_dmastop_v(r)
144static inline u32 host1x_channel_dmactrl_dmagetrst(void)
145{
146 return 1 << 1;
147}
148#define HOST1X_CHANNEL_DMACTRL_DMAGETRST \
149 host1x_channel_dmactrl_dmagetrst()
150static inline u32 host1x_channel_dmactrl_dmainitget(void)
151{
152 return 1 << 2;
153}
154#define HOST1X_CHANNEL_DMACTRL_DMAINITGET \
155 host1x_channel_dmactrl_dmainitget()
156static inline u32 host1x_channel_smmu_streamid_r(void)
157{
158 return 0x84;
159}
160#define HOST1X_CHANNEL_SMMU_STREAMID \
161 host1x_channel_smmu_streamid_r()
162static inline u32 host1x_channel_filter_gbuffer_r(void)
163{
164 return 0x2020;
165}
166#define HOST1X_CHANNEL_FILTER_GBUFFER \
167 host1x_channel_filter_gbuffer_r()
168
169#endif
diff --git a/drivers/gpu/host1x/hw/hw_host1x05_sync.h b/drivers/gpu/host1x/hw/hw_host1x05_sync.h
new file mode 100644
index 000000000..55fe98859
--- /dev/null
+++ b/drivers/gpu/host1x/hw/hw_host1x05_sync.h
@@ -0,0 +1,321 @@
1/*
2 * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17
18 /*
19 * Function naming determines intended use:
20 *
21 * <x>_r(void) : Returns the offset for register <x>.
22 *
23 * <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
24 *
25 * <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
26 *
27 * <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
28 * and masked to place it at field <y> of register <x>. This value
29 * can be |'d with others to produce a full register value for
30 * register <x>.
31 *
32 * <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
33 * value can be ~'d and then &'d to clear the value of field <y> for
34 * register <x>.
35 *
36 * <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
37 * to place it at field <y> of register <x>. This value can be |'d
38 * with others to produce a full register value for <x>.
39 *
40 * <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
41 * <x> value 'r' after being shifted to place its LSB at bit 0.
42 * This value is suitable for direct comparison with other unshifted
43 * values appropriate for use in field <y> of register <x>.
44 *
45 * <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
46 * field <y> of register <x>. This value is suitable for direct
47 * comparison with unshifted values appropriate for use in field <y>
48 * of register <x>.
49 */
50
51#ifndef HOST1X_HW_HOST1X05_SYNC_H
52#define HOST1X_HW_HOST1X05_SYNC_H
53
54#define REGISTER_STRIDE 4
55
56static inline u32 host1x_sync_intstatus_r(void)
57{
58 return 0x1c;
59}
60#define HOST1X_SYNC_INTSTATUS \
61 host1x_sync_intstatus_r()
62static inline u32 host1x_sync_intmask_r(void)
63{
64 return 0x30;
65}
66#define HOST1X_SYNC_INTMASK \
67 host1x_sync_intmask_r()
68static inline u32 host1x_sync_intc0mask_r(void)
69{
70 return 0x4;
71}
72#define HOST1X_SYNC_INTC0MASK \
73 host1x_sync_intc0mask_r()
74static inline u32 host1x_sync_intgmask_r(void)
75{
76 return 0x44;
77}
78#define HOST1X_SYNC_INTGMASK \
79 host1x_sync_intgmask_r()
80static inline u32 host1x_sync_syncpt_intgmask_r(void)
81{
82 return 0x50;
83}
84#define HOST1X_SYNC_SYNCPT_INTGMASK \
85 host1x_sync_syncpt_intgmask_r()
86static inline u32 host1x_sync_intstatus_ip_read_int_v(u32 r)
87{
88 return (r >> 0) & 0x1;
89}
90#define HOST1X_SYNC_INTSTATUS_IP_READ_INT_V(r) \
91 host1x_sync_intstatus_ip_read_int_v(r)
92static inline u32 host1x_sync_intstatus_ip_write_int_v(u32 r)
93{
94 return (r >> 1) & 0x1;
95}
96#define HOST1X_SYNC_INTSTATUS_IP_WRITE_INT_V(r) \
97 host1x_sync_intstatus_ip_write_int_v(r)
98static inline u32 host1x_sync_intstatus_illegal_pb_access_v(u32 r)
99{
100 return (r >> 28) & 0x1;
101}
102#define HOST1X_SYNC_INTSTATUS_ILLEGAL_PB_ACCESS_V(r) \
103 host1x_sync_intstatus_illegal_pb_access_v(r)
104static inline u32 host1x_sync_illegal_syncpt_access_frm_pb_r(void)
105{
106 return 0x2270;
107}
108#define HOST1X_SYNC_ILLEGAL_SYNCPT_ACCESS_FRM_PB \
109 host1x_sync_illegal_syncpt_access_frm_pb_r()
110static inline u32 host1x_sync_illegal_syncpt_access_frm_pb_syncpt_v(u32 r)
111{
112 return (r >> 16) & 0x3ff;
113}
114#define HOST1X_SYNC_ILLEGAL_SYNCPT_ACCESS_FRM_PB_SYNCPT_V(r) \
115 host1x_sync_illegal_syncpt_access_frm_pb_syncpt_v(r)
116static inline u32 host1x_sync_illegal_syncpt_access_frm_pb_ch_v(u32 r)
117{
118 return (r >> 10) & 0x3f;
119}
120#define HOST1X_SYNC_ILLEGAL_SYNCPT_ACCESS_FRM_PB_CH_V(r) \
121 host1x_sync_illegal_syncpt_access_frm_pb_ch_v(r)
122static inline u32 host1x_sync_intstatus_illegal_client_access_v(u32 r)
123{
124 return (r >> 30) & 0x1;
125}
126#define HOST1X_SYNC_INTSTATUS_ILLEGAL_CLIENT_ACCESS_V(r) \
127 host1x_sync_intstatus_illegal_client_access_v(r)
128static inline u32 host1x_sync_illegal_syncpt_access_frm_client_r(void)
129{
130 return 0x2268;
131}
132#define HOST1X_SYNC_ILLEGAL_SYNCPT_ACCESS_FRM_CLIENT \
133 host1x_sync_illegal_syncpt_access_frm_client_r()
134static inline u32 host1x_sync_illegal_syncpt_access_frm_client_syncpt_v(u32 r)
135{
136 return (r >> 16) & 0x3ff;
137}
138#define HOST1X_SYNC_ILLEGAL_SYNCPT_ACCESS_FRM_CLIENT_SYNCPT_V(r) \
139 host1x_sync_illegal_syncpt_access_frm_client_syncpt_v(r)
140static inline u32 host1x_sync_illegal_syncpt_access_frm_client_ch_v(u32 r)
141{
142 return (r >> 10) & 0x3f;
143}
144#define HOST1X_SYNC_ILLEGAL_SYNCPT_ACCESS_FRM_CLIENT_CH_V(r) \
145 host1x_sync_illegal_syncpt_access_frm_client_ch_v(r)
146static inline u32 host1x_sync_syncpt_r(unsigned int id)
147{
148 return 0x18080 + id * REGISTER_STRIDE;
149}
150#define HOST1X_SYNC_SYNCPT(id) \
151 host1x_sync_syncpt_r(id)
152static inline u32 host1x_sync_syncpt_thresh_cpu0_int_status_r(unsigned int id)
153{
154 return 0x16464 + id * REGISTER_STRIDE;
155}
156#define HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(id) \
157 host1x_sync_syncpt_thresh_cpu0_int_status_r(id)
158static inline u32 host1x_sync_syncpt_thresh_int_disable_r(unsigned int id)
159{
160 return 0x16590 + id * REGISTER_STRIDE;
161}
162#define HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(id) \
163 host1x_sync_syncpt_thresh_int_disable_r(id)
164static inline u32 host1x_sync_syncpt_thresh_int_enable_cpu0_r(unsigned int id)
165{
166 return 0x1652c + id * REGISTER_STRIDE;
167}
168#define HOST1X_SYNC_SYNCPT_THRESH_INT_ENABLE_CPU0(id) \
169 host1x_sync_syncpt_thresh_int_enable_cpu0_r(id)
170static inline u32 host1x_sync_cf_setup_r(unsigned int channel)
171{
172 return 0x2588 + channel * REGISTER_STRIDE;
173}
174#define HOST1X_SYNC_CF_SETUP(channel) \
175 host1x_sync_cf_setup_r(channel)
176static inline u32 host1x_sync_cf_setup_base_v(u32 r)
177{
178 return (r >> 0) & 0xfff;
179}
180#define HOST1X_SYNC_CF_SETUP_BASE_V(r) \
181 host1x_sync_cf_setup_base_v(r)
182static inline u32 host1x_sync_cf_setup_limit_v(u32 r)
183{
184 return (r >> 16) & 0xfff;
185}
186#define HOST1X_SYNC_CF_SETUP_LIMIT_V(r) \
187 host1x_sync_cf_setup_limit_v(r)
188static inline u32 host1x_sync_cmdproc_stop_r(void)
189{
190 return 0x48;
191}
192#define HOST1X_SYNC_CMDPROC_STOP \
193 host1x_sync_cmdproc_stop_r()
194static inline u32 host1x_sync_ch_teardown_r(void)
195{
196 return 0x4c;
197}
198#define HOST1X_SYNC_CH_TEARDOWN \
199 host1x_sync_ch_teardown_r()
200static inline u32 host1x_sync_usec_clk_r(void)
201{
202 return 0x2244;
203}
204#define HOST1X_SYNC_USEC_CLK \
205 host1x_sync_usec_clk_r()
206static inline u32 host1x_sync_ctxsw_timeout_cfg_r(void)
207{
208 return 0x2248;
209}
210#define HOST1X_SYNC_CTXSW_TIMEOUT_CFG \
211 host1x_sync_ctxsw_timeout_cfg_r()
212static inline u32 host1x_sync_ip_busy_timeout_r(void)
213{
214 return 0x2250;
215}
216#define HOST1X_SYNC_IP_BUSY_TIMEOUT \
217 host1x_sync_ip_busy_timeout_r()
218static inline u32 host1x_sync_ip_read_timeout_addr_r(void)
219{
220 return 0x2254;
221}
222#define HOST1X_SYNC_IP_READ_TIMEOUT_ADDR \
223 host1x_sync_ip_read_timeout_addr_r()
224static inline u32 host1x_sync_ip_write_timeout_addr_r(void)
225{
226 return 0x225c;
227}
228#define HOST1X_SYNC_IP_WRITE_TIMEOUT_ADDR \
229 host1x_sync_ip_write_timeout_addr_r()
230static inline u32 host1x_sync_syncpt_int_thresh_r(unsigned int id)
231{
232 return 0x18a00 + id * REGISTER_STRIDE;
233}
234#define HOST1X_SYNC_SYNCPT_INT_THRESH(id) \
235 host1x_sync_syncpt_int_thresh_r(id)
236static inline u32 host1x_sync_syncpt_base_r(unsigned int id)
237{
238 return 0x18000 + id * REGISTER_STRIDE;
239}
240#define HOST1X_SYNC_SYNCPT_BASE(id) \
241 host1x_sync_syncpt_base_r(id)
242static inline u32 host1x_sync_syncpt_cpu_incr_r(unsigned int id)
243{
244 return 0x16400 + id * REGISTER_STRIDE;
245}
246#define HOST1X_SYNC_SYNCPT_CPU_INCR(id) \
247 host1x_sync_syncpt_cpu_incr_r(id)
248static inline u32 host1x_sync_cfpeek_ctrl_r(void)
249{
250 return 0x233c;
251}
252#define HOST1X_SYNC_CFPEEK_CTRL \
253 host1x_sync_cfpeek_ctrl_r()
254static inline u32 host1x_sync_cfpeek_ctrl_addr_f(u32 v)
255{
256 return (v & 0xfff) << 0;
257}
258#define HOST1X_SYNC_CFPEEK_CTRL_ADDR_F(v) \
259 host1x_sync_cfpeek_ctrl_addr_f(v)
260static inline u32 host1x_sync_cfpeek_ctrl_channr_f(u32 v)
261{
262 return (v & 0x3f) << 16;
263}
264#define HOST1X_SYNC_CFPEEK_CTRL_CHANNR_F(v) \
265 host1x_sync_cfpeek_ctrl_channr_f(v)
266static inline u32 host1x_sync_cfpeek_ctrl_ena_f(u32 v)
267{
268 return (v & 0x1) << 31;
269}
270#define HOST1X_SYNC_CFPEEK_CTRL_ENA_F(v) \
271 host1x_sync_cfpeek_ctrl_ena_f(v)
272static inline u32 host1x_sync_cfpeek_read_r(void)
273{
274 return 0x2340;
275}
276#define HOST1X_SYNC_CFPEEK_READ \
277 host1x_sync_cfpeek_read_r()
278static inline u32 host1x_sync_cfpeek_ptrs_r(void)
279{
280 return 0x2344;
281}
282#define HOST1X_SYNC_CFPEEK_PTRS \
283 host1x_sync_cfpeek_ptrs_r()
284static inline u32 host1x_sync_cfpeek_ptrs_cf_rd_ptr_v(u32 r)
285{
286 return (r >> 0) & 0xfff;
287}
288#define HOST1X_SYNC_CFPEEK_PTRS_CF_RD_PTR_V(r) \
289 host1x_sync_cfpeek_ptrs_cf_rd_ptr_v(r)
290static inline u32 host1x_sync_cfpeek_ptrs_cf_wr_ptr_v(u32 r)
291{
292 return (r >> 16) & 0xfff;
293}
294#define HOST1X_SYNC_CFPEEK_PTRS_CF_WR_PTR_V(r) \
295 host1x_sync_cfpeek_ptrs_cf_wr_ptr_v(r)
296static inline u32 host1x_sync_common_mlock_r(unsigned long id)
297{
298 return 0x2030 + id * REGISTER_STRIDE;
299}
300#define HOST1X_SYNC_COMMON_MLOCK \
301 host1x_sync_common_mlock_r()
302static inline u32 host1x_sync_common_mlock_ch_v(u32 r)
303{
304 return (r >> 2) & 0x3f;
305}
306#define HOST1X_SYNC_COMMON_MLOCK_CH_V(r) \
307 host1x_sync_common_mlock_ch_v(r)
308static inline u32 host1x_sync_common_mlock_locked_v(u32 r)
309{
310 return (r >> 0) & 0x1;
311}
312#define HOST1X_SYNC_COMMON_MLOCK_LOCKED_V(r) \
313 host1x_sync_common_mlock_locked_v(r)
314static inline u32 host1x_thost_common_icg_en_override_0_r(void)
315{
316 return 0x2aa8;
317}
318#define HOST1X_THOST_COMMON_ICG_EN_OVERRIDE_0 \
319 host1x_thost_common_icg_en_override_0_r()
320
321#endif
diff --git a/drivers/gpu/host1x/hw/hw_host1x05_uclass.h b/drivers/gpu/host1x/hw/hw_host1x05_uclass.h
new file mode 100644
index 000000000..01145f610
--- /dev/null
+++ b/drivers/gpu/host1x/hw/hw_host1x05_uclass.h
@@ -0,0 +1,157 @@
1/*
2 * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17
18 /*
19 * Function naming determines intended use:
20 *
21 * <x>_r(void) : Returns the offset for register <x>.
22 *
23 * <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
24 *
25 * <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
26 *
27 * <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
28 * and masked to place it at field <y> of register <x>. This value
29 * can be |'d with others to produce a full register value for
30 * register <x>.
31 *
32 * <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
33 * value can be ~'d and then &'d to clear the value of field <y> for
34 * register <x>.
35 *
36 * <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
37 * to place it at field <y> of register <x>. This value can be |'d
38 * with others to produce a full register value for <x>.
39 *
40 * <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
41 * <x> value 'r' after being shifted to place its LSB at bit 0.
42 * This value is suitable for direct comparison with other unshifted
43 * values appropriate for use in field <y> of register <x>.
44 *
45 * <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
46 * field <y> of register <x>. This value is suitable for direct
47 * comparison with unshifted values appropriate for use in field <y>
48 * of register <x>.
49 */
50
51#ifndef HOST1X_HW_HOST1X05_UCLASS_H
52#define HOST1X_HW_HOST1X05_UCLASS_H
53
54static inline u32 host1x_uclass_incr_syncpt_r(void)
55{
56 return 0x0;
57}
58#define HOST1X_UCLASS_INCR_SYNCPT \
59 host1x_uclass_incr_syncpt_r()
60static inline u32 host1x_uclass_incr_syncpt_cond_f(u32 v)
61{
62 return (v & 0xff) << 10;
63}
64#define HOST1X_UCLASS_INCR_SYNCPT_COND_F(v) \
65 host1x_uclass_incr_syncpt_cond_f(v)
66static inline u32 host1x_uclass_incr_syncpt_indx_f(u32 v)
67{
68 return (v & 0x3ff) << 0;
69}
70#define HOST1X_UCLASS_INCR_SYNCPT_INDX_F(v) \
71 host1x_uclass_incr_syncpt_indx_f(v)
72static inline u32 host1x_uclass_load_syncpt_payload_32_r(void)
73{
74 return 0x4e;
75}
76#define HOST1X_UCLASS_LOAD_SYNCPT_PAYLOAD_32 \
77 host1x_uclass_load_syncpt_payload_32_r()
78static inline u32 host1x_uclass_wait_syncpt_32_r(void)
79{
80 return 0x50;
81}
82#define HOST1X_UCLASS_WAIT_SYNCPT_32 \
83 host1x_uclass_wait_syncpt_32_r()
84static inline u32 host1x_uclass_wait_syncpt_r(void)
85{
86 return 0x8;
87}
88#define HOST1X_UCLASS_WAIT_SYNCPT \
89 host1x_uclass_wait_syncpt_r()
90static inline u32 host1x_uclass_wait_syncpt_indx_f(u32 v)
91{
92 return (v & 0xff) << 24;
93}
94#define HOST1X_UCLASS_WAIT_SYNCPT_INDX_F(v) \
95 host1x_uclass_wait_syncpt_indx_f(v)
96static inline u32 host1x_uclass_wait_syncpt_thresh_f(u32 v)
97{
98 return (v & 0xffffff) << 0;
99}
100#define HOST1X_UCLASS_WAIT_SYNCPT_THRESH_F(v) \
101 host1x_uclass_wait_syncpt_thresh_f(v)
102static inline u32 host1x_uclass_wait_syncpt_base_r(void)
103{
104 return 0x9;
105}
106#define HOST1X_UCLASS_WAIT_SYNCPT_BASE \
107 host1x_uclass_wait_syncpt_base_r()
108static inline u32 host1x_uclass_wait_syncpt_base_indx_f(u32 v)
109{
110 return (v & 0x3ff) << 22;
111}
112#define HOST1X_UCLASS_WAIT_SYNCPT_BASE_INDX_F(v) \
113 host1x_uclass_wait_syncpt_base_indx_f(v)
114static inline u32 host1x_uclass_wait_syncpt_base_base_indx_f(u32 v)
115{
116 return (v & 0x3f) << 16;
117}
118#define HOST1X_UCLASS_WAIT_SYNCPT_BASE_BASE_INDX_F(v) \
119 host1x_uclass_wait_syncpt_base_base_indx_f(v)
120static inline u32 host1x_uclass_wait_syncpt_base_offset_f(u32 v)
121{
122 return (v & 0xffff) << 0;
123}
124#define HOST1X_UCLASS_WAIT_SYNCPT_BASE_OFFSET_F(v) \
125 host1x_uclass_wait_syncpt_base_offset_f(v)
126static inline u32 host1x_uclass_load_syncpt_base_r(void)
127{
128 return 0xb;
129}
130#define HOST1X_UCLASS_LOAD_SYNCPT_BASE \
131 host1x_uclass_load_syncpt_base_r()
132static inline u32 host1x_uclass_load_syncpt_base_base_indx_f(u32 v)
133{
134 return (v & 0xff) << 24;
135}
136#define HOST1X_UCLASS_LOAD_SYNCPT_BASE_BASE_INDX_F(v) \
137 host1x_uclass_load_syncpt_base_base_indx_f(v)
138static inline u32 host1x_uclass_load_syncpt_base_value_f(u32 v)
139{
140 return (v & 0xffffff) << 0;
141}
142#define HOST1X_UCLASS_LOAD_SYNCPT_BASE_VALUE_F(v) \
143 host1x_uclass_load_syncpt_base_value_f(v)
144static inline u32 host1x_uclass_incr_syncpt_base_base_indx_f(u32 v)
145{
146 return (v & 0xff) << 24;
147}
148#define HOST1X_UCLASS_INCR_SYNCPT_BASE_BASE_INDX_F(v) \
149 host1x_uclass_incr_syncpt_base_base_indx_f(v)
150static inline u32 host1x_uclass_incr_syncpt_base_offset_f(u32 v)
151{
152 return (v & 0xffffff) << 0;
153}
154#define HOST1X_UCLASS_INCR_SYNCPT_BASE_OFFSET_F(v) \
155 host1x_uclass_incr_syncpt_base_offset_f(v)
156
157#endif
diff --git a/drivers/gpu/host1x/hw/intr_hw_t186.c b/drivers/gpu/host1x/hw/intr_hw_t186.c
new file mode 100644
index 000000000..48bd1150f
--- /dev/null
+++ b/drivers/gpu/host1x/hw/intr_hw_t186.c
@@ -0,0 +1,247 @@
1/*
2 * Tegra host1x Interrupt Management
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2016 NVIDIA Corporation. All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/interrupt.h>
21#include <linux/irq.h>
22#include <linux/io.h>
23
24#include "intr.h"
25#include "dev.h"
26
27
28static inline u32 bit_mask(u32 nr)
29{
30 return 1UL << (nr % 32);
31}
32static inline u32 bit_word(u32 nr)
33{
34 return nr / 32;
35}
36
37/*
38 * Sync point threshold interrupt service function
39 * Handles sync point threshold triggers, in interrupt context
40 */
41static void host1x_intr_syncpt_handle(struct host1x_syncpt *syncpt)
42{
43 unsigned int id = syncpt->id;
44 struct host1x *host = syncpt->host;
45
46 host1x_sync_writel(host, bit_mask(id),
47 HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(bit_word(id)));
48 host1x_sync_writel(host, bit_mask(id),
49 HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(bit_word(id)));
50
51 queue_work(host->intr_wq, &syncpt->intr.work);
52}
53
54static irqreturn_t syncpt_thresh_isr(int irq, void *dev_id)
55{
56 struct host1x *host = dev_id;
57 unsigned long reg;
58 int i, set_bit;
59
60 for (i = 0; i < DIV_ROUND_UP(host->info->nb_pts, 32); i++) {
61 reg = host1x_sync_readl(host,
62 HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(i));
63 for_each_set_bit(set_bit, &reg, 32) {
64 struct host1x_syncpt *syncpt;
65 int id = i * 32 + set_bit;
66
67 if (unlikely(id < 0 || id >= host->info->nb_pts)) {
68 dev_err(host->dev,
69 "%s(): unexptected syncpt id %d\n",
70 __func__, id);
71 goto out;
72 }
73 syncpt = host->syncpt + id;
74 host1x_intr_syncpt_handle(syncpt);
75 }
76 }
77out:
78 return IRQ_HANDLED;
79}
80
81static void _host1x_intr_disable_all_syncpt_intrs(struct host1x *host)
82{
83 u32 i;
84
85 for (i = 0; i < DIV_ROUND_UP(host->info->nb_pts, 32); ++i) {
86 host1x_sync_writel(host, 0xffffffffu,
87 HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(i));
88 host1x_sync_writel(host, 0xffffffffu,
89 HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(i));
90 }
91}
92
93static int _host1x_intr_init_host_sync(struct host1x *host, u32 cpm,
94 void (*syncpt_thresh_work)(struct work_struct *))
95{
96 int i, err;
97
98 host1x_hw_intr_disable_all_syncpt_intrs(host);
99
100 for (i = 0; i < host->info->nb_pts; i++)
101 INIT_WORK(&host->syncpt[i].intr.work, syncpt_thresh_work);
102
103 err = devm_request_irq(host->dev, host->intr_syncpt_irq,
104 syncpt_thresh_isr, IRQF_SHARED,
105 "host1x_syncpt", host);
106 if (IS_ERR_VALUE(err)) {
107 WARN_ON(1);
108 return err;
109 }
110
111 /* disable the ip_busy_timeout. this prevents write drops */
112 host1x_sync_writel(host, 0, HOST1X_SYNC_IP_BUSY_TIMEOUT);
113
114 /*
115 * increase the auto-ack timout to the maximum value. 2d will hang
116 * otherwise on Tegra2.
117 */
118 host1x_sync_writel(host, 0xff, HOST1X_SYNC_CTXSW_TIMEOUT_CFG);
119
120 /* update host clocks per usec */
121 host1x_sync_writel(host, cpm, HOST1X_SYNC_USEC_CLK);
122
123 return 0;
124}
125
126static void _host1x_intr_set_syncpt_threshold(struct host1x *host,
127 u32 id, u32 thresh)
128{
129 host1x_sync_writel(host, thresh, HOST1X_SYNC_SYNCPT_INT_THRESH(id));
130}
131
132static void _host1x_intr_enable_syncpt_intr(struct host1x *host, u32 id)
133{
134 host1x_sync_writel(host, bit_mask(id),
135 HOST1X_SYNC_SYNCPT_THRESH_INT_ENABLE_CPU0(bit_word(id)));
136}
137
138static void _host1x_intr_disable_syncpt_intr(struct host1x *host, u32 id)
139{
140 host1x_sync_writel(host, bit_mask(id),
141 HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(bit_word(id)));
142 host1x_sync_writel(host, bit_mask(id),
143 HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(bit_word(id)));
144}
145
146static int _host1x_free_syncpt_irq(struct host1x *host)
147{
148 devm_free_irq(host->dev, host->intr_syncpt_irq, host);
149 flush_workqueue(host->intr_wq);
150 return 0;
151}
152
153/**
154 * Host general interrupt service function
155 * Handles read / write failures
156 */
157static irqreturn_t general_isr(int irq, void *dev_id)
158{
159 struct host1x *host = dev_id;
160 u32 intstatus, addr;
161
162 /* Handle host1x interrupt in ISR */
163 intstatus = host1x_sync_readl(host, HOST1X_SYNC_INTSTATUS);
164
165 if (HOST1X_SYNC_INTSTATUS_IP_READ_INT_V(intstatus)) {
166 addr = host1x_sync_readl(host,
167 HOST1X_SYNC_IP_READ_TIMEOUT_ADDR);
168 pr_err("Host read timeout at address %x\n", addr);
169 }
170
171 if (HOST1X_SYNC_INTSTATUS_IP_WRITE_INT_V(intstatus)) {
172 addr = host1x_sync_readl(host,
173 HOST1X_SYNC_IP_WRITE_TIMEOUT_ADDR);
174 pr_err("Host write timeout at address %x\n", addr);
175 }
176
177 if (HOST1X_SYNC_INTSTATUS_ILLEGAL_PB_ACCESS_V(intstatus)) {
178 u32 stat = host1x_sync_readl(host, HOST1X_SYNC_ILLEGAL_SYNCPT_ACCESS_FRM_PB);
179 u32 ch = HOST1X_SYNC_ILLEGAL_SYNCPT_ACCESS_FRM_PB_CH_V(stat);
180 u32 id = HOST1X_SYNC_ILLEGAL_SYNCPT_ACCESS_FRM_PB_SYNCPT_V(stat);
181 pr_err("Host illegal syncpoint pb access (ch=%u, id=%u)\n", ch, id);
182 }
183
184 if (HOST1X_SYNC_INTSTATUS_ILLEGAL_CLIENT_ACCESS_V(intstatus)) {
185 u32 stat = host1x_sync_readl(host, HOST1X_SYNC_ILLEGAL_SYNCPT_ACCESS_FRM_CLIENT);
186 u32 ch = HOST1X_SYNC_ILLEGAL_SYNCPT_ACCESS_FRM_CLIENT_CH_V(stat);
187 u32 id = HOST1X_SYNC_ILLEGAL_SYNCPT_ACCESS_FRM_CLIENT_SYNCPT_V(stat);
188 pr_err("Host illegal syncpoint client access (ch=%u, id=%u)\n", ch, id);
189 }
190
191 host1x_sync_writel(host, intstatus, HOST1X_SYNC_INTSTATUS);
192
193 return IRQ_HANDLED;
194}
195
196static int _host1x_intr_request_host_general_irq(struct host1x *host)
197{
198 int err;
199
200 /* master disable for general (not syncpt) host interrupts */
201 host1x_sync_writel(host, 0, HOST1X_SYNC_INTC0MASK);
202 host1x_sync_writel(host, 0, HOST1X_SYNC_INTGMASK);
203 host1x_sync_writel(host, 0, HOST1X_SYNC_INTMASK);
204
205 err = devm_request_irq(host->dev, host->intr_general_irq,
206 general_isr, 0,
207 "host1x_general", host);
208 if (IS_ERR_VALUE(err)) {
209 WARN_ON(1);
210 return err;
211 }
212
213 /* enable host module interrupt to CPU0 */
214 host1x_sync_writel(host, BIT(0), HOST1X_SYNC_INTC0MASK);
215 host1x_sync_writel(host, BIT(0), HOST1X_SYNC_INTGMASK);
216 host1x_sync_writel(host, 0xff << 8, HOST1X_SYNC_SYNCPT_INTGMASK);
217
218 /* master enable for general (not syncpt) host interrupts
219 * (AXIREAD, AXIWRITE, Syncpoint protection */
220 host1x_sync_writel(host, BIT(0) | BIT(1) | BIT(28) | BIT(30),
221 HOST1X_SYNC_INTMASK);
222
223 return err;
224}
225
226static void _host1x_intr_free_host_general_irq(struct host1x *host)
227{
228 /* master disable for general (not syncpt) host interrupts */
229 host1x_sync_writel(host, 0, HOST1X_SYNC_INTMASK);
230 host1x_sync_writel(host, 0, HOST1X_SYNC_SYNCPT_INTGMASK);
231
232 devm_free_irq(host->dev, host->intr_general_irq, host);
233}
234
235static const struct host1x_intr_ops host1x_intr_t186_ops = {
236 /* Syncpt interrupts */
237 .init_host_sync = _host1x_intr_init_host_sync,
238 .set_syncpt_threshold = _host1x_intr_set_syncpt_threshold,
239 .enable_syncpt_intr = _host1x_intr_enable_syncpt_intr,
240 .disable_syncpt_intr = _host1x_intr_disable_syncpt_intr,
241 .disable_all_syncpt_intrs = _host1x_intr_disable_all_syncpt_intrs,
242 .free_syncpt_irq = _host1x_free_syncpt_irq,
243
244 /* Host general interrupts */
245 .request_host_general_irq = _host1x_intr_request_host_general_irq,
246 .free_host_general_irq = _host1x_intr_free_host_general_irq,
247};
diff --git a/drivers/gpu/host1x/hw/stremid_hw_t186.c b/drivers/gpu/host1x/hw/stremid_hw_t186.c
new file mode 100644
index 000000000..9f4c36852
--- /dev/null
+++ b/drivers/gpu/host1x/hw/stremid_hw_t186.c
@@ -0,0 +1,95 @@
1/*
2 * Copyright (c) 2016, NVIDIA Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17
18#include "dev_t186.h"
19
20struct host1x_streamid_mapping {
21 u32 host1x_offset;
22 u32 client_offset;
23 u32 client_limit;
24};
25
26static struct host1x_streamid_mapping __attribute__((__unused__))
27 t18x_host1x_streamid_mapping[] = {
28 /* HOST1X_THOST_COMMON_SE1_STRMID_0_OFFSET_BASE_0 */
29 { 0x00001ac8, 0x00000090, 0x00000090},
30 /* HOST1X_THOST_COMMON_SE2_STRMID_0_OFFSET_BASE_0 */
31 { 0x00001ad0, 0x00000090, 0x00000090},
32 /* HOST1X_THOST_COMMON_SE3_STRMID_0_OFFSET_BASE_0 */
33 { 0x00001ad8, 0x00000090, 0x00000090},
34 /* HOST1X_THOST_COMMON_SE4_STRMID_0_OFFSET_BASE_0 */
35 { 0x00001ae0, 0x00000090, 0x00000090},
36 /* HOST1X_THOST_COMMON_ISP_STRMID_0_OFFSET_BASE_0 */
37 { 0x00001ae8, 0x00000050, 0x00000050},
38 /* HOST1X_THOST_COMMON_VIC_STRMID_0_OFFSET_BASE_0 */
39 { 0x00001af0, 0x00000030, 0x00000034},
40 /* HOST1X_THOST_COMMON_NVENC_STRMID_0_OFFSET_BASE_0 */
41 { 0x00001af8, 0x00000030, 0x00000034},
42 /* HOST1X_THOST_COMMON_NVDEC_STRMID_0_OFFSET_BASE_0 */
43 { 0x00001b00, 0x00000030, 0x00000034},
44 /* HOST1X_THOST_COMMON_NVJPG_STRMID_0_OFFSET_BASE_0 */
45 { 0x00001b08, 0x00000030, 0x00000034},
46 /* HOST1X_THOST_COMMON_TSEC_STRMID_0_OFFSET_BASE_0 */
47 { 0x00001b10, 0x00000030, 0x00000034},
48 /* HOST1X_THOST_COMMON_TSECB_STRMID_0_OFFSET_BASE_0 */
49 { 0x00001b18, 0x00000030, 0x00000034},
50 /* HOST1X_THOST_COMMON_VI_STRMID_0_OFFSET_BASE_0 */
51 { 0x00001b80, 0x00010000, 0x00010000},
52 /* HOST1X_THOST_COMMON_VI_STRMID_1_OFFSET_BASE_0 */
53 { 0x00001b88, 0x00020000, 0x00020000},
54 /* HOST1X_THOST_COMMON_VI_STRMID_2_OFFSET_BASE_0 */
55 { 0x00001b90, 0x00030000, 0x00030000},
56 /* HOST1X_THOST_COMMON_VI_STRMID_3_OFFSET_BASE_0 */
57 { 0x00001b98, 0x00040000, 0x00040000},
58 /* HOST1X_THOST_COMMON_VI_STRMID_4_OFFSET_BASE_0 */
59 { 0x00001ba0, 0x00050000, 0x00050000},
60 /* HOST1X_THOST_COMMON_VI_STRMID_5_OFFSET_BASE_0 */
61 { 0x00001ba8, 0x00060000, 0x00060000},
62 /* HOST1X_THOST_COMMON_VI_STRMID_6_OFFSET_BASE_0 */
63 { 0x00001bb0, 0x00070000, 0x00070000},
64 /* HOST1X_THOST_COMMON_VI_STRMID_7_OFFSET_BASE_0 */
65 { 0x00001bb8, 0x00080000, 0x00080000},
66 /* HOST1X_THOST_COMMON_VI_STRMID_8_OFFSET_BASE_0 */
67 { 0x00001bc0, 0x00090000, 0x00090000},
68 /* HOST1X_THOST_COMMON_VI_STRMID_9_OFFSET_BASE_0 */
69 { 0x00001bc8, 0x000a0000, 0x000a0000},
70 /* HOST1X_THOST_COMMON_VI_STRMID_10_OFFSET_BASE_0 */
71 { 0x00001bd0, 0x000b0000, 0x000b0000},
72 /* HOST1X_THOST_COMMON_VI_STRMID_11_OFFSET_BASE_0 */
73 { 0x00001bd8, 0x000c0000, 0x000c0000},
74 {},
75};
76
77static int load_streamid_regs(struct host1x *host)
78{
79 struct host1x_streamid_mapping *map_regs = t18x_host1x_streamid_mapping;
80
81 while (map_regs->host1x_offset) {
82 host1x_writel(host, map_regs->client_offset,
83 map_regs->host1x_offset);
84 host1x_writel(host, map_regs->client_limit,
85 map_regs->host1x_offset + sizeof(u32));
86
87 map_regs++;
88 }
89
90 return 0;
91}
92
93static const struct host1x_dev_ops host1x_dev_t186_ops = {
94 .load_regs = load_streamid_regs,
95};
diff --git a/drivers/gpu/host1x/hw/syncpt_hw_t186.c b/drivers/gpu/host1x/hw/syncpt_hw_t186.c
new file mode 100644
index 000000000..9b196854a
--- /dev/null
+++ b/drivers/gpu/host1x/hw/syncpt_hw_t186.c
@@ -0,0 +1,126 @@
1/*
2 * Tegra host1x Syncpoints
3 *
4 * Copyright (c) 2016, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/io.h>
20
21#include "dev.h"
22#include "syncpt.h"
23
24/*
25 * Write the current syncpoint value back to hw.
26 */
27static void syncpt_restore(struct host1x_syncpt *sp)
28{
29 struct host1x *host = sp->host;
30 int min = host1x_syncpt_read_min(sp);
31 host1x_sync_writel(host, min, HOST1X_SYNC_SYNCPT(sp->id));
32}
33
34/*
35 * Write the current waitbase value back to hw.
36 */
37static void syncpt_restore_wait_base(struct host1x_syncpt *sp)
38{
39 struct host1x *host = sp->host;
40 host1x_sync_writel(host, sp->base_val,
41 HOST1X_SYNC_SYNCPT_BASE(sp->id));
42}
43
44/*
45 * Read waitbase value from hw.
46 */
47static void syncpt_read_wait_base(struct host1x_syncpt *sp)
48{
49 struct host1x *host = sp->host;
50 sp->base_val =
51 host1x_sync_readl(host, HOST1X_SYNC_SYNCPT_BASE(sp->id));
52}
53
54/*
55 * Updates the last value read from hardware.
56 */
57static u32 syncpt_load(struct host1x_syncpt *sp)
58{
59 struct host1x *host = sp->host;
60 u32 old, live;
61
62 /* Loop in case there's a race writing to min_val */
63 do {
64 old = host1x_syncpt_read_min(sp);
65 live = host1x_sync_readl(host, HOST1X_SYNC_SYNCPT(sp->id));
66 } while ((u32)atomic_cmpxchg(&sp->min_val, old, live) != old);
67
68 if (!host1x_syncpt_check_max(sp, live))
69 dev_err(host->dev, "%s failed: id=%u, min=%d, max=%d\n",
70 __func__, sp->id, host1x_syncpt_read_min(sp),
71 host1x_syncpt_read_max(sp));
72
73 return live;
74}
75
76/*
77 * Write a cpu syncpoint increment to the hardware, without touching
78 * the cache.
79 */
80static int syncpt_cpu_incr(struct host1x_syncpt *sp)
81{
82 struct host1x *host = sp->host;
83 u32 reg_offset = sp->id / 32;
84
85 if (!host1x_syncpt_client_managed(sp) &&
86 host1x_syncpt_idle(sp))
87 return -EINVAL;
88 host1x_sync_writel(host, BIT_MASK(sp->id),
89 HOST1X_SYNC_SYNCPT_CPU_INCR(reg_offset));
90 wmb();
91
92 return 0;
93}
94
95/* remove a wait pointed to by patch_addr */
96static int syncpt_patch_wait(struct host1x_syncpt *sp, void *patch_addr)
97{
98 u32 override = host1x_class_host_wait_syncpt(
99 HOST1X_SYNCPT_RESERVED, 0);
100
101 *((u32 *)patch_addr) = override;
102 return 0;
103}
104
105static void syncpt_get_mutex_owner(struct host1x_syncpt *sp,
106 unsigned int mutex_id, bool *cpu, bool *ch,
107 unsigned int *chid)
108{
109 struct host1x *host = sp->host;
110 u32 owner;
111
112 owner = host1x_sync_readl(host, host1x_sync_common_mlock_r(mutex_id));
113 *chid = HOST1X_SYNC_COMMON_MLOCK_CH_V(owner);
114 *ch = HOST1X_SYNC_COMMON_MLOCK_LOCKED_V(owner);
115 *cpu = false;
116}
117
118static const struct host1x_syncpt_ops host1x_syncpt_t186_ops = {
119 .restore = syncpt_restore,
120 .restore_wait_base = syncpt_restore_wait_base,
121 .load_wait_base = syncpt_read_wait_base,
122 .load = syncpt_load,
123 .cpu_incr = syncpt_cpu_incr,
124 .patch_wait = syncpt_patch_wait,
125 .get_mutex_owner = syncpt_get_mutex_owner,
126};