source "drivers/mux/Kconfig"
+source "drivers/bts/Kconfig"
endmenu
obj-$(CONFIG_FSI) += fsi/
obj-$(CONFIG_TEE) += tee/
obj-$(CONFIG_MULTIPLEXER) += mux/
+
+obj-$(CONFIG_EXYNOS_BTS) += bts/
--- /dev/null
+#
+# BTS driver configuration
+#
+
+menuconfig EXYNOS_BTS
+ bool "BTS driver support"
+ default y
+ help
+ Enable BTS (Bus traffic shaper) support
+
+if EXYNOS_BTS
+
+config EXYNOS8890_BTS
+ bool "Bus traffic shaper support"
+ default y
+ depends on SOC_EXYNOS8890
+ help
+ Enable BTS (Bus traffic shaper) support
+
+config EXYNOS8890_BTS_OPTIMIZATION
+ bool "Bus traffic shaper optimization mode"
+ default n
+ depends on EXYNOS8890_BTS
+ help
+ Enable BTS (Bus traffic shaper) optimized set
+endif
--- /dev/null
+#
+# Makefile for BTS.
+#
+
+obj-$(CONFIG_EXYNOS8890_BTS) += cal_bts8890.o bts-exynos8890.o
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/list.h>
+#include <linux/dma-mapping.h>
+#include <linux/pm_runtime.h>
+#include <linux/pm_qos.h>
+#include <linux/suspend.h>
+#include <linux/debugfs.h>
+
+#include <soc/samsung/exynos-pm.h>
+#include <soc/samsung/bts.h>
+#include "cal_bts8890.h"
+#include "regs-bts.h"
+
+#define VPP_MAX 9
+#define MIF_BLK_NUM 4
+#define TREX_SCI_NUM 2
+
+#define BTS_DISP (BTS_TREX_DISP0_0 | BTS_TREX_DISP0_1 | \
+ BTS_TREX_DISP1_0 | BTS_TREX_DISP1_1)
+#define BTS_MFC (BTS_TREX_MFC0 | BTS_TREX_MFC1)
+#define BTS_G3D (BTS_TREX_G3D0 | BTS_TREX_G3D1)
+#define BTS_RT (BTS_TREX_DISP0_0 | BTS_TREX_DISP0_1 | \
+ BTS_TREX_DISP1_0 | BTS_TREX_DISP1_1 | \
+ BTS_TREX_ISP0 | BTS_TREX_CAM0 | BTS_TREX_CP)
+
+#define update_rot_scen(a) (pr_state.rot_scen = a)
+#define update_g3d_scen(a) (pr_state.g3d_scen = a)
+#define update_urgent_scen(a) (pr_state.urg_scen = a)
+
+#ifdef BTS_DBGGEN
+#define BTS_DBG(x...) pr_err(x)
+#else
+#define BTS_DBG(x...) do {} while (0)
+#endif
+
+enum bts_index {
+ BTS_IDX_TREX_DISP0_0,
+ BTS_IDX_TREX_DISP0_1,
+ BTS_IDX_TREX_DISP1_0,
+ BTS_IDX_TREX_DISP1_1,
+ BTS_IDX_TREX_ISP0,
+ BTS_IDX_TREX_CAM0,
+ BTS_IDX_TREX_CAM1,
+ BTS_IDX_TREX_CP,
+ BTS_IDX_TREX_MFC0,
+ BTS_IDX_TREX_MFC1,
+ BTS_IDX_TREX_G3D0,
+ BTS_IDX_TREX_G3D1,
+ BTS_IDX_TREX_FSYS0,
+ BTS_IDX_TREX_FSYS1,
+ BTS_IDX_TREX_MSCL0,
+ BTS_IDX_TREX_MSCL1,
+ BTS_MAX,
+};
+
+#define BTS_TREX_DISP0_0 ((u64)1 << (u64)BTS_IDX_TREX_DISP0_0)
+#define BTS_TREX_DISP0_1 ((u64)1 << (u64)BTS_IDX_TREX_DISP0_1)
+#define BTS_TREX_DISP1_0 ((u64)1 << (u64)BTS_IDX_TREX_DISP1_0)
+#define BTS_TREX_DISP1_1 ((u64)1 << (u64)BTS_IDX_TREX_DISP1_1)
+#define BTS_TREX_ISP0 ((u64)1 << (u64)BTS_IDX_TREX_ISP0)
+#define BTS_TREX_CAM0 ((u64)1 << (u64)BTS_IDX_TREX_CAM0)
+#define BTS_TREX_CAM1 ((u64)1 << (u64)BTS_IDX_TREX_CAM1)
+#define BTS_TREX_CP ((u64)1 << (u64)BTS_IDX_TREX_CP)
+#define BTS_TREX_MFC0 ((u64)1 << (u64)BTS_IDX_TREX_MFC0)
+#define BTS_TREX_MFC1 ((u64)1 << (u64)BTS_IDX_TREX_MFC1)
+#define BTS_TREX_G3D0 ((u64)1 << (u64)BTS_IDX_TREX_G3D0)
+#define BTS_TREX_G3D1 ((u64)1 << (u64)BTS_IDX_TREX_G3D1)
+#define BTS_TREX_FSYS0 ((u64)1 << (u64)BTS_IDX_TREX_FSYS0)
+#define BTS_TREX_FSYS1 ((u64)1 << (u64)BTS_IDX_TREX_FSYS1)
+#define BTS_TREX_MSCL0 ((u64)1 << (u64)BTS_IDX_TREX_MSCL0)
+#define BTS_TREX_MSCL1 ((u64)1 << (u64)BTS_IDX_TREX_MSCL1)
+
+enum exynos_bts_scenario {
+ BS_DISABLE,
+ BS_DEFAULT,
+ BS_ROTATION,
+ BS_HIGHPERF,
+ BS_G3DFREQ,
+ BS_URGENTOFF,
+ BS_DEBUG,
+ BS_MAX,
+};
+
+enum exynos_bts_function {
+ BF_SETQOS,
+ BF_SETQOS_BW,
+ BF_SETQOS_MO,
+ BF_SETQOS_FBMBW,
+ BF_DISABLE,
+ BF_SETTREXQOS,
+ BF_SETTREXQOS_MO,
+ BF_SETTREXQOS_MO_RT,
+ BF_SETTREXQOS_MO_CP,
+ BF_SETTREXQOS_MO_CHANGE,
+ BF_SETTREXQOS_URGENT_OFF,
+ BF_SETTREXQOS_BW,
+ BF_SETTREXQOS_FBMBW,
+ BF_SETTREXDISABLE,
+ BF_NOP,
+};
+
+enum vpp_state {
+ VPP_BW,
+ VPP_ROT_BW,
+ VPP_STAT,
+};
+
+struct bts_table {
+ enum exynos_bts_function fn;
+ unsigned int priority;
+ unsigned int window;
+ unsigned int token;
+ unsigned int mo;
+ unsigned int fbm;
+ unsigned int mask;
+ unsigned int timeout;
+ unsigned int bypass_en;
+ unsigned int decval;
+ struct bts_info *next_bts;
+ int prev_scen;
+ int next_scen;
+};
+
+struct bts_info {
+ u64 id;
+ const char *name;
+ unsigned int pa_base;
+ void __iomem *va_base;
+ struct bts_table table[BS_MAX];
+ const char *pd_name;
+ bool on;
+ struct list_head list;
+ bool enable;
+ struct clk_info *ct_ptr;
+ enum exynos_bts_scenario cur_scen;
+ enum exynos_bts_scenario top_scen;
+};
+
+struct bts_scen_status {
+ bool rot_scen;
+ bool g3d_scen;
+ bool urg_scen;
+};
+
+struct bts_scenario {
+ const char *name;
+ u64 ip;
+ enum exynos_bts_scenario id;
+ struct bts_info *head;
+};
+
+struct bts_scen_status pr_state = {
+ .rot_scen = false,
+ .g3d_scen = false,
+ .urg_scen = false,
+};
+
+struct clk_info {
+ const char *clk_name;
+ struct clk *clk;
+ enum bts_index index;
+};
+
+static void __iomem *base_trex[TREX_SCI_NUM];
+
+static DEFINE_MUTEX(media_mutex);
+
+#ifdef CONFIG_EXYNOS8890_BTS_OPTIMIZATION
+static unsigned int prev_mo;
+static unsigned int vpp_rot[VPP_MAX];
+#else
+static unsigned int vpp_bw[VPP_STAT][VPP_MAX];
+static unsigned int cam_bw, sum_rot_bw, total_bw;
+static enum vpp_bw_type vpp_status[VPP_MAX];
+static unsigned int mif_freq, int_freq;
+#endif
+static struct pm_qos_request exynos8_mif_bts_qos;
+static struct pm_qos_request exynos8_int_bts_qos;
+static struct pm_qos_request exynos8_gpu_mif_bts_qos;
+static struct pm_qos_request exynos8_winlayer_mif_bts_qos;
+static struct srcu_notifier_head exynos_media_notifier;
+static struct clk_info clk_table[0];
+
+static int bts_trex_qosoff(void __iomem *base);
+static int bts_trex_qoson(void __iomem *base);
+
+static struct bts_info exynos8_bts[] = {
+ [BTS_IDX_TREX_DISP0_0] = {
+ .id = BTS_TREX_DISP0_0,
+ .name = "disp0_0",
+ .pd_name = "trex",
+ .pa_base = EXYNOS8890_PA_BTS_TREX_DISP0_0,
+ .table[BS_DEFAULT].fn = BF_SETTREXQOS_MO_RT,
+ .table[BS_DEFAULT].priority = 0x00000008,
+ .table[BS_DEFAULT].mo = 0x10,
+ .table[BS_DEFAULT].timeout = 0x40,
+ .table[BS_DEFAULT].bypass_en = 0,
+ .table[BS_ROTATION].fn = BF_SETTREXQOS_MO_RT,
+ .table[BS_ROTATION].priority = 0x00000008,
+ .table[BS_ROTATION].mo = 0x20,
+ .table[BS_ROTATION].timeout = 0x40,
+ .table[BS_ROTATION].bypass_en = 0,
+ .table[BS_DISABLE].fn = BF_SETTREXDISABLE,
+ .cur_scen = BS_DISABLE,
+ .on = false,
+ .enable = true,
+ },
+ [BTS_IDX_TREX_DISP0_1] = {
+ .id = BTS_TREX_DISP0_1,
+ .name = "disp0_1",
+ .pd_name = "trex",
+ .pa_base = EXYNOS8890_PA_BTS_TREX_DISP0_1,
+ .table[BS_DEFAULT].fn = BF_SETTREXQOS_MO_RT,
+ .table[BS_DEFAULT].priority = 0x00000008,
+ .table[BS_DEFAULT].mo = 0x10,
+ .table[BS_DEFAULT].timeout = 0x40,
+ .table[BS_DEFAULT].bypass_en = 0,
+ .table[BS_ROTATION].fn = BF_SETTREXQOS_MO_RT,
+ .table[BS_ROTATION].priority = 0x00000008,
+ .table[BS_ROTATION].mo = 0x20,
+ .table[BS_ROTATION].timeout = 0x40,
+ .table[BS_ROTATION].bypass_en = 0,
+ .table[BS_DISABLE].fn = BF_SETTREXDISABLE,
+ .cur_scen = BS_DISABLE,
+ .on = false,
+ .enable = true,
+ },
+ [BTS_IDX_TREX_DISP1_0] = {
+ .id = BTS_TREX_DISP1_0,
+ .name = "disp1_0",
+ .pd_name = "trex",
+ .pa_base = EXYNOS8890_PA_BTS_TREX_DISP1_0,
+ .table[BS_DEFAULT].fn = BF_SETTREXQOS_MO_RT,
+ .table[BS_DEFAULT].priority = 0x00000008,
+ .table[BS_DEFAULT].mo = 0x10,
+ .table[BS_DEFAULT].timeout = 0x40,
+ .table[BS_DEFAULT].bypass_en = 0,
+ .table[BS_ROTATION].fn = BF_SETTREXQOS_MO_RT,
+ .table[BS_ROTATION].priority = 0x00000008,
+ .table[BS_ROTATION].mo = 0x20,
+ .table[BS_ROTATION].timeout = 0x40,
+ .table[BS_ROTATION].bypass_en = 0,
+ .table[BS_DISABLE].fn = BF_SETTREXDISABLE,
+ .cur_scen = BS_DISABLE,
+ .on = false,
+ .enable = true,
+ },
+ [BTS_IDX_TREX_DISP1_1] = {
+ .id = BTS_TREX_DISP1_1,
+ .name = "disp1_1",
+ .pd_name = "trex",
+ .pa_base = EXYNOS8890_PA_BTS_TREX_DISP1_1,
+ .table[BS_DEFAULT].fn = BF_SETTREXQOS_MO_RT,
+ .table[BS_DEFAULT].priority = 0x00000008,
+ .table[BS_DEFAULT].mo = 0x10,
+ .table[BS_DEFAULT].timeout = 0x40,
+ .table[BS_DEFAULT].bypass_en = 0,
+ .table[BS_ROTATION].fn = BF_SETTREXQOS_MO_RT,
+ .table[BS_ROTATION].priority = 0x00000008,
+ .table[BS_ROTATION].mo = 0x20,
+ .table[BS_ROTATION].timeout = 0x40,
+ .table[BS_ROTATION].bypass_en = 0,
+ .table[BS_DISABLE].fn = BF_SETTREXDISABLE,
+ .cur_scen = BS_DISABLE,
+ .on = false,
+ .enable = true,
+ },
+ [BTS_IDX_TREX_ISP0] = {
+ .id = BTS_TREX_ISP0,
+ .name = "isp0",
+ .pd_name = "trex",
+ .pa_base = EXYNOS8890_PA_BTS_TREX_ISP0,
+ .table[BS_DEFAULT].fn = BF_SETTREXQOS_MO_RT,
+ .table[BS_DEFAULT].priority = 0x0000000A,
+ .table[BS_DEFAULT].mo = 0x10,
+ .table[BS_DEFAULT].timeout = 0x10,
+ .table[BS_DEFAULT].bypass_en = 0,
+ .table[BS_DISABLE].fn = BF_SETTREXDISABLE,
+ .cur_scen = BS_DISABLE,
+ .on = false,
+ .enable = true,
+ },
+ [BTS_IDX_TREX_CAM0] = {
+ .id = BTS_TREX_CAM0,
+ .name = "cam0",
+ .pd_name = "trex",
+ .pa_base = EXYNOS8890_PA_BTS_TREX_CAM0,
+ .table[BS_DEFAULT].fn = BF_SETTREXQOS_MO_RT,
+ .table[BS_DEFAULT].priority = 0x0000000A,
+ .table[BS_DEFAULT].mo = 0x10,
+ .table[BS_DEFAULT].timeout = 0x10,
+ .table[BS_DEFAULT].bypass_en = 0,
+ .table[BS_DISABLE].fn = BF_SETTREXDISABLE,
+ .cur_scen = BS_DISABLE,
+ .on = false,
+ .enable = true,
+ },
+ [BTS_IDX_TREX_CAM1] = {
+ .id = BTS_TREX_CAM1,
+ .name = "cam1",
+ .pd_name = "trex",
+ .pa_base = EXYNOS8890_PA_BTS_TREX_CAM1,
+ .table[BS_DEFAULT].fn = BF_SETTREXQOS_MO,
+ .table[BS_DEFAULT].priority = 0x0000000A,
+ .table[BS_DEFAULT].mo = 0x10,
+ .table[BS_DEFAULT].bypass_en = 0,
+ .table[BS_DISABLE].fn = BF_SETTREXDISABLE,
+ .cur_scen = BS_DISABLE,
+ .on = false,
+ .enable = true,
+ },
+ [BTS_IDX_TREX_CP] = {
+ .id = BTS_TREX_CP,
+ .name = "cp",
+ .pd_name = "trex",
+ .pa_base = EXYNOS8890_PA_BTS_TREX_CP,
+ .table[BS_DEFAULT].fn = BF_SETTREXQOS_MO_CP,
+ .table[BS_DEFAULT].priority = 0x0000000C,
+ .table[BS_DEFAULT].mo = 0x10,
+ .table[BS_DEFAULT].timeout = 0x10,
+ .table[BS_DEFAULT].bypass_en = 0,
+ .table[BS_URGENTOFF].fn = BF_SETTREXQOS_URGENT_OFF,
+ .table[BS_DISABLE].fn = BF_SETTREXDISABLE,
+ .cur_scen = BS_DISABLE,
+ .on = false,
+ .enable = true,
+ },
+ [BTS_IDX_TREX_MFC0] = {
+ .id = BTS_TREX_MFC0,
+ .name = "mfc0",
+ .pd_name = "trex",
+ .pa_base = EXYNOS8890_PA_BTS_TREX_MFC0,
+ .table[BS_DEFAULT].fn = BF_SETTREXQOS_MO,
+ .table[BS_DEFAULT].priority = 0x00000004,
+ .table[BS_DEFAULT].mo = 0x8,
+ .table[BS_DEFAULT].bypass_en = 0,
+ .table[BS_HIGHPERF].fn = BF_SETTREXQOS_MO_CHANGE,
+ .table[BS_HIGHPERF].mo = 0x400,
+ .table[BS_DISABLE].fn = BF_SETTREXDISABLE,
+ .cur_scen = BS_DISABLE,
+ .on = false,
+ .enable = true,
+ },
+ [BTS_IDX_TREX_MFC1] = {
+ .id = BTS_TREX_MFC1,
+ .name = "mfc1",
+ .pd_name = "trex",
+ .pa_base = EXYNOS8890_PA_BTS_TREX_MFC1,
+ .table[BS_DEFAULT].fn = BF_SETTREXQOS_MO,
+ .table[BS_DEFAULT].priority = 0x00000004,
+ .table[BS_DEFAULT].mo = 0x8,
+ .table[BS_DEFAULT].bypass_en = 0,
+ .table[BS_HIGHPERF].fn = BF_SETTREXQOS_MO_CHANGE,
+ .table[BS_HIGHPERF].mo = 0x400,
+ .table[BS_DISABLE].fn = BF_SETTREXDISABLE,
+ .cur_scen = BS_DISABLE,
+ .on = false,
+ .enable = true,
+ },
+ [BTS_IDX_TREX_G3D0] = {
+ .id = BTS_TREX_G3D0,
+ .name = "g3d0",
+ .pd_name = "trex",
+ .pa_base = EXYNOS8890_PA_BTS_TREX_G3D0,
+ .table[BS_DEFAULT].fn = BF_SETTREXQOS_MO,
+ .table[BS_DEFAULT].priority = 0x00000004,
+ .table[BS_DEFAULT].mo = 0x10,
+ .table[BS_DEFAULT].bypass_en = 0,
+ .table[BS_G3DFREQ].fn = BF_SETTREXQOS_MO_CHANGE,
+ .table[BS_G3DFREQ].mo = 0x20,
+ .table[BS_DISABLE].fn = BF_SETTREXDISABLE,
+ .cur_scen = BS_DISABLE,
+ .on = false,
+ .enable = true,
+ },
+ [BTS_IDX_TREX_G3D1] = {
+ .id = BTS_TREX_G3D1,
+ .name = "g3d1",
+ .pd_name = "trex",
+ .pa_base = EXYNOS8890_PA_BTS_TREX_G3D1,
+ .table[BS_DEFAULT].fn = BF_SETTREXQOS_MO,
+ .table[BS_DEFAULT].priority = 0x00000004,
+ .table[BS_DEFAULT].mo = 0x10,
+ .table[BS_DEFAULT].bypass_en = 0,
+ .table[BS_G3DFREQ].fn = BF_SETTREXQOS_MO_CHANGE,
+ .table[BS_G3DFREQ].mo = 0x20,
+ .table[BS_DISABLE].fn = BF_SETTREXDISABLE,
+ .cur_scen = BS_DISABLE,
+ .on = false,
+ .enable = true,
+ },
+ [BTS_IDX_TREX_FSYS0] = {
+ .id = BTS_TREX_FSYS0,
+ .name = "fsys0",
+ .pd_name = "trex",
+ .pa_base = EXYNOS8890_PA_BTS_TREX_FSYS0,
+ .table[BS_DEFAULT].fn = BF_SETTREXQOS_MO,
+ .table[BS_DEFAULT].priority = 0x00000004,
+ .table[BS_DEFAULT].mo = 0x4,
+ .table[BS_DEFAULT].bypass_en = 0,
+ .table[BS_DISABLE].fn = BF_SETTREXDISABLE,
+ .cur_scen = BS_DISABLE,
+ .on = false,
+ .enable = true,
+ },
+ [BTS_IDX_TREX_FSYS1] = {
+ .id = BTS_TREX_FSYS1,
+ .name = "fsys1",
+ .pd_name = "trex",
+ .pa_base = EXYNOS8890_PA_BTS_TREX_FSYS1,
+ .table[BS_DEFAULT].fn = BF_SETTREXQOS_MO,
+ .table[BS_DEFAULT].priority = 0x00000004,
+ .table[BS_DEFAULT].mo = 0x4,
+ .table[BS_DEFAULT].bypass_en = 0,
+ .table[BS_DISABLE].fn = BF_SETTREXDISABLE,
+ .cur_scen = BS_DISABLE,
+ .on = false,
+ .enable = true,
+ },
+ [BTS_IDX_TREX_MSCL0] = {
+ .id = BTS_TREX_MSCL0,
+ .name = "mscl0",
+ .pd_name = "trex",
+ .pa_base = EXYNOS8890_PA_BTS_TREX_MSCL0,
+ .table[BS_DEFAULT].fn = BF_SETTREXQOS_MO,
+ .table[BS_DEFAULT].priority = 0x00000004,
+ .table[BS_DEFAULT].mo = 0x4,
+ .table[BS_DEFAULT].bypass_en = 0,
+ .table[BS_DISABLE].fn = BF_SETTREXDISABLE,
+ .cur_scen = BS_DISABLE,
+ .on = false,
+ .enable = true,
+ },
+ [BTS_IDX_TREX_MSCL1] = {
+ .id = BTS_TREX_MSCL1,
+ .name = "mscl1",
+ .pd_name = "trex",
+ .pa_base = EXYNOS8890_PA_BTS_TREX_MSCL1,
+ .table[BS_DEFAULT].fn = BF_SETTREXQOS_MO,
+ .table[BS_DEFAULT].priority = 0x00000004,
+ .table[BS_DEFAULT].mo = 0x4,
+ .table[BS_DEFAULT].bypass_en = 0,
+ .table[BS_DISABLE].fn = BF_SETTREXDISABLE,
+ .cur_scen = BS_DISABLE,
+ .on = false,
+ .enable = true,
+ },
+};
+
+static struct bts_scenario bts_scen[] = {
+ [BS_DISABLE] = {
+ .name = "bts_disable",
+ .id = BS_DISABLE,
+ },
+ [BS_DEFAULT] = {
+ .name = "bts_default",
+ .id = BS_DEFAULT,
+ },
+ [BS_ROTATION] = {
+ .name = "bts_rotation",
+ .ip = BTS_DISP,
+ .id = BS_ROTATION,
+ },
+ [BS_HIGHPERF] = {
+ .name = "bts_mfchighperf",
+ .ip = BTS_MFC,
+ .id = BS_HIGHPERF,
+ },
+ [BS_G3DFREQ] = {
+ .name = "bts_g3dfreq",
+ .ip = BTS_G3D,
+ .id = BS_G3DFREQ,
+ },
+ [BS_URGENTOFF] = {
+ .name = "bts_urgentoff",
+ .ip = BTS_TREX_CP,
+ .id = BS_URGENTOFF,
+ },
+ [BS_DEBUG] = {
+ .name = "bts_dubugging_ip",
+ .id = BS_DEBUG,
+ },
+ [BS_MAX] = {
+ .name = "undefined"
+ }
+};
+
+static DEFINE_SPINLOCK(bts_lock);
+static LIST_HEAD(bts_list);
+
+static void is_bts_clk_enabled(struct bts_info *bts)
+{
+ struct clk_info *ptr;
+ enum bts_index btstable_index;
+
+ ptr = bts->ct_ptr;
+
+ if (ptr) {
+ btstable_index = ptr->index;
+ do {
+ if(!__clk_is_enabled(ptr->clk))
+ pr_err("[BTS] CLK is not enabled : %s in %s\n",
+ ptr->clk_name,
+ bts->name);
+ } while (++ptr < clk_table + ARRAY_SIZE(clk_table)
+ && ptr->index == btstable_index);
+ }
+}
+
+static void bts_clk_on(struct bts_info *bts)
+{
+ struct clk_info *ptr;
+ enum bts_index btstable_index;
+
+ ptr = bts->ct_ptr;
+
+ if (ptr) {
+ btstable_index = ptr->index;
+ do {
+ clk_enable(ptr->clk);
+ } while (++ptr < clk_table + ARRAY_SIZE(clk_table)
+ && ptr->index == btstable_index);
+ }
+}
+
+static void bts_clk_off(struct bts_info *bts)
+{
+ struct clk_info *ptr;
+ enum bts_index btstable_index;
+
+ ptr = bts->ct_ptr;
+ if (ptr) {
+ btstable_index = ptr->index;
+ do {
+ clk_disable(ptr->clk);
+ } while (++ptr < clk_table + ARRAY_SIZE(clk_table)
+ && ptr->index == btstable_index);
+ }
+}
+
+static void bts_set_ip_table(enum exynos_bts_scenario scen,
+ struct bts_info *bts)
+{
+ enum exynos_bts_function fn = bts->table[scen].fn;
+ int i;
+
+ is_bts_clk_enabled(bts);
+ BTS_DBG("[BTS] %s on:%d bts scen: [%s]->[%s]\n", bts->name, bts->on,
+ bts_scen[bts->cur_scen].name, bts_scen[scen].name);
+
+ switch (fn) {
+ case BF_SETTREXQOS:
+ bts_settrexqos(bts->va_base, bts->table[scen].priority, 0, 0);
+ break;
+ case BF_SETTREXQOS_MO_RT:
+ bts_settrexqos_mo_rt(bts->va_base, bts->table[scen].priority, bts->table[scen].mo,
+ 0, 0, bts->table[scen].timeout, bts->table[scen].bypass_en);
+ break;
+ case BF_SETTREXQOS_MO_CP:
+ bts_settrexqos_mo_cp(bts->va_base, bts->table[scen].priority, bts->table[scen].mo,
+ 0, 0, bts->table[scen].timeout, bts->table[scen].bypass_en);
+ bts_settrexqos_urgent_on(bts->va_base);
+ for (i = 0; i < (unsigned int)ARRAY_SIZE(base_trex); i++)
+ bts_trex_qoson(base_trex[i]);
+ break;
+ case BF_SETTREXQOS_MO:
+ bts_settrexqos_mo(bts->va_base, bts->table[scen].priority, bts->table[scen].mo, 0, 0);
+ break;
+ case BF_SETTREXQOS_MO_CHANGE:
+ bts_settrexqos_mo_change(bts->va_base, bts->table[scen].mo);
+ break;
+ case BF_SETTREXQOS_URGENT_OFF:
+ bts_settrexqos_urgent_off(bts->va_base);
+ for (i = 0; i < (unsigned int)ARRAY_SIZE(base_trex); i++)
+ bts_trex_qosoff(base_trex[i]);
+ break;
+ case BF_SETTREXQOS_BW:
+ bts_settrexqos_bw(bts->va_base, bts->table[scen].priority,
+ bts->table[scen].decval, 0, 0);
+ break;
+ case BF_SETTREXQOS_FBMBW:
+ bts_settrexqos_fbmbw(bts->va_base, bts->table[scen].priority, 0, 0);
+ break;
+ case BF_SETTREXDISABLE:
+ bts_trexdisable(bts->va_base, 0, 0);
+ break;
+ case BF_SETQOS:
+ bts_setqos(bts->va_base, bts->table[scen].priority, 0);
+ break;
+ case BF_SETQOS_BW:
+ bts_setqos_bw(bts->va_base, bts->table[scen].priority,
+ bts->table[scen].window, bts->table[scen].token, 0);
+ break;
+ case BF_SETQOS_MO:
+ bts_setqos_mo(bts->va_base, bts->table[scen].priority, bts->table[scen].mo, 0);
+ break;
+ case BF_SETQOS_FBMBW:
+ bts_setqos_fbmbw(bts->va_base, bts->table[scen].priority, bts->table[scen].window,
+ bts->table[scen].token, bts->table[scen].fbm, 0);
+ break;
+ case BF_DISABLE:
+ bts_disable(bts->va_base, 0);
+ break;
+ case BF_NOP:
+ break;
+ }
+
+ bts->cur_scen = scen;
+}
+
+static enum exynos_bts_scenario bts_get_scen(struct bts_info *bts)
+{
+ enum exynos_bts_scenario scen;
+
+ scen = BS_DEFAULT;
+
+ return scen;
+}
+
+
+static void bts_add_scen(enum exynos_bts_scenario scen, struct bts_info *bts)
+{
+ struct bts_info *first = bts;
+ int next = 0;
+ int prev = 0;
+
+ if (!bts)
+ return;
+
+ BTS_DBG("[bts %s] scen %s off\n",
+ bts->name, bts_scen[scen].name);
+
+ do {
+ if (bts->enable) {
+ if (bts->table[scen].next_scen == 0) {
+ if (scen >= bts->top_scen) {
+ bts->table[scen].prev_scen = bts->top_scen;
+ bts->table[bts->top_scen].next_scen = scen;
+ bts->top_scen = scen;
+ bts->table[scen].next_scen = -1;
+
+ if(bts->on)
+ bts_set_ip_table(bts->top_scen, bts);
+
+ } else {
+ for (prev = bts->top_scen; prev > scen; prev = bts->table[prev].prev_scen)
+ next = prev;
+
+ bts->table[scen].prev_scen = bts->table[next].prev_scen;
+ bts->table[scen].next_scen = bts->table[prev].next_scen;
+ bts->table[next].prev_scen = scen;
+ bts->table[prev].next_scen = scen;
+ }
+ }
+ }
+
+ bts = bts->table[scen].next_bts;
+
+ } while (bts && bts != first);
+}
+
+static void bts_del_scen(enum exynos_bts_scenario scen, struct bts_info *bts)
+{
+ struct bts_info *first = bts;
+ int next = 0;
+ int prev = 0;
+
+ if (!bts)
+ return;
+
+ BTS_DBG("[bts %s] scen %s off\n",
+ bts->name, bts_scen[scen].name);
+
+ do {
+ if (bts->enable) {
+ if (bts->table[scen].next_scen != 0) {
+ if (scen == bts->top_scen) {
+ prev = bts->table[scen].prev_scen;
+ bts->top_scen = prev;
+ bts->table[prev].next_scen = -1;
+ bts->table[scen].next_scen = 0;
+ bts->table[scen].prev_scen = 0;
+
+ if (bts->on)
+ bts_set_ip_table(prev, bts);
+ } else if (scen < bts->top_scen) {
+ prev = bts->table[scen].prev_scen;
+ next = bts->table[scen].next_scen;
+
+ bts->table[next].prev_scen = bts->table[scen].prev_scen;
+ bts->table[prev].next_scen = bts->table[scen].next_scen;
+
+ bts->table[scen].prev_scen = 0;
+ bts->table[scen].next_scen = 0;
+
+ } else {
+ BTS_DBG("%s scenario couldn't exist above top_scen\n", bts_scen[scen].name);
+ }
+ }
+
+ }
+
+ bts = bts->table[scen].next_bts;
+
+ } while (bts && bts != first);
+}
+
+void bts_scen_update(enum bts_scen_type type, unsigned int val)
+{
+ enum exynos_bts_scenario scen = BS_DEFAULT;
+ struct bts_info *bts = NULL;
+ bool on;
+ spin_lock(&bts_lock);
+
+ switch (type) {
+ case TYPE_ROTATION:
+ on = val ? true : false;
+ scen = BS_ROTATION;
+ bts = &exynos8_bts[BTS_IDX_TREX_DISP0_0];
+ BTS_DBG("[BTS] ROTATION: %s\n", bts_scen[scen].name);
+ update_rot_scen(val);
+ break;
+ case TYPE_HIGHPERF:
+ on = val ? true : false;
+ scen = BS_HIGHPERF;
+ bts = &exynos8_bts[BTS_IDX_TREX_MFC0];
+ BTS_DBG("[BTS] MFC PERF: %s\n", bts_scen[scen].name);
+ break;
+ case TYPE_G3D_FREQ:
+ on = val ? true : false;
+ scen = BS_G3DFREQ;
+ bts = &exynos8_bts[BTS_IDX_TREX_G3D0];
+ BTS_DBG("[BTS] G3D FREQ: %s\n", bts_scen[scen].name);
+ update_g3d_scen(val);
+ break;
+ case TYPE_URGENT_OFF:
+ on = val ? true : false;
+ scen = BS_URGENTOFF;
+ bts = &exynos8_bts[BTS_IDX_TREX_CP];
+ BTS_DBG("[BTS] URGENT: %s\n", bts_scen[scen].name);
+ update_urgent_scen(val);
+ break;
+ default:
+ spin_unlock(&bts_lock);
+ return;
+ break;
+ }
+
+ if (on)
+ bts_add_scen(scen, bts);
+ else
+ bts_del_scen(scen, bts);
+
+ spin_unlock(&bts_lock);
+}
+
+void bts_initialize(const char *pd_name, bool on)
+{
+ struct bts_info *bts;
+ enum exynos_bts_scenario scen = BS_DISABLE;
+
+ spin_lock(&bts_lock);
+
+ list_for_each_entry(bts, &bts_list, list) {
+ BTS_DBG("[BTS] %s on/off:%d->%d\n", bts->name, bts->on, on);
+
+ if (!bts->enable) {
+ bts->on = on;
+ continue;
+ }
+
+ scen = bts_get_scen(bts);
+ if (on) {
+ bts_add_scen(scen, bts);
+ if (!bts->on) {
+ bts->on = true;
+ bts_clk_on(bts);
+ }
+ bts_set_ip_table(bts->top_scen, bts);
+ } else {
+ if (bts->on) {
+ bts->on = false;
+ bts_clk_off(bts);
+ }
+ bts_del_scen(scen, bts);
+ }
+ }
+
+ spin_unlock(&bts_lock);
+}
+
+static void scen_chaining(enum exynos_bts_scenario scen)
+{
+ struct bts_info *prev = NULL;
+ struct bts_info *first = NULL;
+ struct bts_info *bts;
+
+ if (bts_scen[scen].ip) {
+ list_for_each_entry(bts, &bts_list, list) {
+ if (bts_scen[scen].ip & bts->id) {
+ if (!first)
+ first = bts;
+ if (prev)
+ prev->table[scen].next_bts = bts;
+
+ prev = bts;
+ }
+ }
+
+ if (prev)
+ prev->table[scen].next_bts = first;
+
+ bts_scen[scen].head = first;
+ }
+}
+
+static void bts_trex_init(void __iomem *base)
+{
+ __raw_writel(0x0B070000, base + SCI_CTRL);
+ __raw_writel(0x00200000, base + READ_QURGENT);
+ __raw_writel(0x00200000, base + WRITE_QURGENT);
+ __raw_writel(0x2A55A954, base + VC_NUM0);
+ __raw_writel(0x00000CA0, base + VC_NUM1);
+ __raw_writel(0x04040404, base + TH_IMM0);
+ __raw_writel(0x04040404, base + TH_IMM1);
+ __raw_writel(0x04040404, base + TH_IMM2);
+ __raw_writel(0x04040404, base + TH_IMM3);
+ __raw_writel(0x04040404, base + TH_IMM4);
+ __raw_writel(0x04040004, base + TH_IMM5);
+ __raw_writel(0x00040404, base + TH_IMM6);
+ __raw_writel(0x02020202, base + TH_HIGH0);
+ __raw_writel(0x02020202, base + TH_HIGH1);
+ __raw_writel(0x02020202, base + TH_HIGH2);
+ __raw_writel(0x02020202, base + TH_HIGH3);
+ __raw_writel(0x02020202, base + TH_HIGH4);
+ __raw_writel(0x02020002, base + TH_HIGH5);
+ __raw_writel(0x00020202, base + TH_HIGH6);
+
+ return;
+}
+
+static int bts_trex_qoson(void __iomem *base)
+{
+ __raw_writel(0x00200000, base + READ_QURGENT);
+ __raw_writel(0x00200000, base + WRITE_QURGENT);
+ __raw_writel(0x04040004, base + TH_IMM5);
+ __raw_writel(0x02020002, base + TH_HIGH5);
+
+ return 0;
+}
+
+static int bts_trex_qosoff(void __iomem *base)
+{
+ __raw_writel(0x00000000, base + READ_QURGENT);
+ __raw_writel(0x00000000, base + WRITE_QURGENT);
+ __raw_writel(0x04040404, base + TH_IMM5);
+ __raw_writel(0x02020202, base + TH_HIGH5);
+
+ return 0;
+}
+
+static int exynos_bts_notifier_event(struct notifier_block *this,
+ unsigned long event,
+ void *ptr)
+{
+ unsigned long i;
+
+ switch ((unsigned int)event) {
+ case PM_POST_SUSPEND:
+ for (i = 0; i < (unsigned int)ARRAY_SIZE(base_trex); i++)
+ bts_trex_init(base_trex[i]);
+ bts_initialize("trex", true);
+ return NOTIFY_OK;
+ break;
+ case PM_SUSPEND_PREPARE:
+ return NOTIFY_OK;
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block exynos_bts_notifier = {
+ .notifier_call = exynos_bts_notifier_event,
+};
+
+int bts_update_gpu_mif(unsigned int freq)
+{
+ int ret = 0;
+
+ if (pm_qos_request_active(&exynos8_gpu_mif_bts_qos))
+ pm_qos_update_request(&exynos8_gpu_mif_bts_qos, freq);
+
+ return ret;
+}
+
+#if defined(CONFIG_EXYNOS8890_BTS_OPTIMIZATION)
+unsigned int ip_sum_bw[IP_NUM];
+unsigned int ip_peak_bw[IP_NUM];
+
+void exynos_update_bw(enum bts_media_type ip_type,
+ unsigned int sum_bw, unsigned int peak_bw)
+{
+ unsigned int ip_sum, ip_peak;
+ unsigned int int_freq;
+ unsigned int mif_freq;
+ int i;
+
+ mutex_lock(&media_mutex);
+
+ switch (ip_type) {
+ case TYPE_VPP0:
+ case TYPE_VPP1:
+ case TYPE_VPP2:
+ case TYPE_VPP3:
+ case TYPE_VPP4:
+ case TYPE_VPP5:
+ case TYPE_VPP6:
+ case TYPE_VPP7:
+ case TYPE_VPP8:
+ ip_sum_bw[IP_VPP] = sum_bw;
+ ip_peak_bw[IP_VPP] = peak_bw;
+ break;
+ case TYPE_CAM:
+ ip_sum_bw[IP_CAM] = sum_bw;
+ ip_peak_bw[IP_CAM] = peak_bw;
+ break;
+ case TYPE_MFC:
+ ip_sum_bw[IP_MFC] = sum_bw;
+ ip_peak_bw[IP_MFC] = peak_bw;
+ break;
+ default:
+ pr_err("BTS : unsupported ip type - %u", ip_type);
+ break;
+ }
+
+ ip_sum = 0;
+ ip_peak = ip_peak_bw[0];
+ for (i = 0; i < IP_NUM; i++) {
+ ip_sum += ip_sum_bw[i];
+ if (ip_peak < ip_peak_bw[i])
+ ip_peak = ip_peak_bw[i];
+ }
+ BTS_DBG("[BTS BW]: TOTAL SUM: %u, PEAK: %u\n", ip_sum, ip_peak);
+
+ mif_freq = (ip_sum * 100000) / (MIF_UTIL * BUS_WIDTH);
+ int_freq = (ip_peak * 100000) / (INT_UTIL * BUS_WIDTH);
+
+ if (mif_freq < 4 * int_freq)
+ mif_freq = 4 * int_freq;
+ else
+ int_freq = mif_freq / 4;
+ BTS_DBG("[BTS FREQ]: MIF: %uMHz, INT: %uMHz\n", mif_freq, int_freq);
+
+ if (pm_qos_request_active(&exynos8_mif_bts_qos))
+ pm_qos_update_request(&exynos8_mif_bts_qos, mif_freq);
+ if (pm_qos_request_active(&exynos8_int_bts_qos))
+ pm_qos_update_request(&exynos8_int_bts_qos, int_freq);
+
+ mutex_unlock(&media_mutex);
+}
+
+struct bts_vpp_info *exynos_bw_calc(enum bts_media_type ip_type, struct bts_hw *hw)
+{
+ u64 s_ratio_h, s_ratio_v = 0;
+ u64 s_ratio = 0;
+ u8 df = 0;
+ u8 bpl = 0;
+ struct bts_vpp_info *vpp = to_bts_vpp(hw);
+
+ switch (ip_type) {
+ case TYPE_VPP0:
+ case TYPE_VPP1:
+ case TYPE_VPP2:
+ case TYPE_VPP3:
+ case TYPE_VPP4:
+ case TYPE_VPP5:
+ case TYPE_VPP6:
+ case TYPE_VPP7:
+ case TYPE_VPP8:
+ s_ratio_h = MULTI_FACTOR * vpp->src_w / vpp->dst_w;
+ s_ratio_v = MULTI_FACTOR * vpp->src_h / vpp->dst_h;
+
+ s_ratio = PIXEL_BUFFER * s_ratio_h * s_ratio_v
+ / (MULTI_FACTOR * MULTI_FACTOR);
+
+ bpl = vpp->bpp * 10 / 8;
+
+ if (vpp->bpp == 32)
+ df = 20;
+ else if (vpp->bpp == 12)
+ df = 36;
+ else if (vpp->bpp == 16)
+ df = 28;
+
+ vpp->cur_bw = vpp->src_h * vpp->src_w * bpl * s_ratio_h * s_ratio_v
+ * 72 / (MULTI_FACTOR * MULTI_FACTOR * 10)
+ / (MULTI_FACTOR * MULTI_FACTOR);
+
+ if (vpp->is_rotation)
+ vpp->peak_bw = (s_ratio + df * vpp->src_h) * bpl * PEAK_FACTOR
+ * (FPS * vpp->dst_h) / VBI_FACTOR
+ / 100 / MULTI_FACTOR;
+ else
+ vpp->peak_bw = (s_ratio + 4 * vpp->src_w + 1000) * bpl * PEAK_FACTOR
+ * (FPS * vpp->dst_h) / VBI_FACTOR
+ / 100 / MULTI_FACTOR;
+
+ BTS_DBG("%s[%i] cur_bw: %llu peak_bw: %llu\n", __func__, (int)ip_type, vpp->cur_bw, vpp->peak_bw);
+
+ break;
+ case TYPE_CAM:
+ case TYPE_MFC:
+ default:
+ pr_err("%s: BW calculation unsupported - %u", __func__, ip_type);
+ break;
+ }
+
+ return vpp;
+}
+
+void bts_ext_scenario_set(enum bts_media_type ip_type,
+ enum bts_scen_type scen_type, bool on)
+{
+ int i = 0;
+ unsigned int cur_mo;
+
+ switch (ip_type) {
+ case TYPE_VPP0:
+ case TYPE_VPP1:
+ case TYPE_VPP2:
+ case TYPE_VPP3:
+ case TYPE_VPP4:
+ case TYPE_VPP5:
+ case TYPE_VPP6:
+ case TYPE_VPP7:
+ case TYPE_VPP8:
+ if (scen_type == TYPE_ROTATION) {
+ if (on)
+ vpp_rot[ip_type - TYPE_VPP0] = 16;
+ else
+ vpp_rot[ip_type - TYPE_VPP0] = 8;
+
+ cur_mo = 8;
+ for (i = 0; i < VPP_MAX; i++) {
+ if (cur_mo < vpp_rot[i])
+ cur_mo = vpp_rot[i];
+ }
+
+ if (cur_mo == 16 && cur_mo != prev_mo) {
+ bts_scen_update(scen_type, 1);
+ prev_mo = 16;
+ } else if (cur_mo == prev_mo) {
+ return;
+ } else {
+ bts_scen_update(scen_type, 0);
+ prev_mo = 8;
+ }
+ }
+ break;
+
+ case TYPE_CAM:
+ if (scen_type == TYPE_URGENT_OFF) {
+ if (on)
+ bts_scen_update(scen_type, 1);
+ else
+ bts_scen_update(scen_type, 0);
+ }
+ break;
+ case TYPE_MFC:
+ if (scen_type == TYPE_HIGHPERF) {
+ if (on)
+ bts_scen_update(scen_type, 1);
+ else
+ bts_scen_update(scen_type, 0);
+ }
+ break;
+ case TYPE_G3D:
+ if (scen_type == TYPE_G3D_FREQ) {
+ if (on)
+ bts_scen_update(scen_type, 1);
+ else
+ bts_scen_update(scen_type, 0);
+ }
+ break;
+ default:
+ pr_err("BTS : unsupported rotation ip - %u", ip_type);
+ break;
+ }
+
+ return;
+}
+
+int bts_update_winlayer(unsigned int layers)
+{
+ unsigned int freq = 0;
+
+ switch (layers) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ freq = 0;
+ break;
+ case 5:
+ freq = 676000;
+ break;
+ case 6:
+ freq = 845000;
+ break;
+ case 7:
+ case 8:
+ freq = 1014000;
+ break;
+ default:
+ break;
+ }
+
+ if (pm_qos_request_active(&exynos8_winlayer_mif_bts_qos))
+ pm_qos_update_request(&exynos8_winlayer_mif_bts_qos, freq);
+
+ return 0;
+}
+
+#else /* BTS_OPTIMIZATION */
+
+void exynos_update_media_scenario(enum bts_media_type media_type,
+ unsigned int bw, int bw_type)
+{
+ unsigned int vpp_total_bw = 0;
+ unsigned int vpp_bus_bw[4];
+ unsigned int vpp_bus_max_bw;
+ int utilization;
+ int i;
+ int max_status = 0;
+ static unsigned int is_yuv;
+ static unsigned int prev_sum_rot_bw;
+ static unsigned int mif_ud_encoding, mif_ud_decoding;
+
+ mutex_lock(&media_mutex);
+
+ switch (media_type) {
+ case TYPE_VPP0:
+ case TYPE_VPP1:
+ case TYPE_VPP2:
+ case TYPE_VPP3:
+ case TYPE_VPP4:
+ case TYPE_VPP5:
+ case TYPE_VPP6:
+ case TYPE_VPP7:
+ case TYPE_VPP8:
+ vpp_bw[VPP_BW][media_type - TYPE_VPP0] = bw;
+ vpp_status[media_type - TYPE_VPP0] = bw_type;
+ if (bw_type)
+ vpp_bw[VPP_ROT_BW][media_type - TYPE_VPP0] = bw;
+ else
+ vpp_bw[VPP_ROT_BW][media_type - TYPE_VPP0] = 0;
+
+ /*
+ * VPP0(G0), VPP1(G1), VPP2(VG0), VPP3(VG1),
+ * VPP4(G2), VPP5(G3), VPP6(VGR0), VPP7(VGR1), VPP8(WB)
+ * vpp_bus_bw[0] = DISP0_0_BW = G0 + VG0;
+ * vpp_bus_bw[1] = DISP0_1_BW = G1 + VG1;
+ * vpp_bus_bw[2] = DISP1_0_BW = G2 + VGR0;
+ * vpp_bus_bw[3] = DISP1_1_BW = G3 + VGR1 + WB;
+ */
+ vpp_bus_bw[0] = vpp_bw[VPP_BW][0] + vpp_bw[VPP_BW][2];
+ vpp_bus_bw[1] = vpp_bw[VPP_BW][1] + vpp_bw[VPP_BW][3];
+ vpp_bus_bw[2] = vpp_bw[VPP_BW][4] + vpp_bw[VPP_BW][6];
+ vpp_bus_bw[3] = vpp_bw[VPP_BW][5] + vpp_bw[VPP_BW][7] + vpp_bw[VPP_BW][8];
+
+ /* sum VPP rotation BW for RT BW */
+ sum_rot_bw = 0;
+ for (i = 0; i < VPP_MAX; i++)
+ sum_rot_bw += vpp_bw[VPP_ROT_BW][i];
+
+ /* Such VPP max BW for INT PM QoS */
+ vpp_bus_max_bw = vpp_bus_bw[0];
+ for (i = 0; i < 4; i++) {
+ if (vpp_bus_max_bw < vpp_bus_bw[i])
+ vpp_bus_max_bw = vpp_bus_bw[i];
+ }
+
+ prev_sum_rot_bw = sum_rot_bw;
+ break;
+ case TYPE_CAM:
+ cam_bw = bw;
+ break;
+ case TYPE_YUV:
+ is_yuv = bw;
+ break;
+ case TYPE_UD_ENC:
+ mif_ud_encoding = bw;
+ break;
+ case TYPE_UD_DEC:
+ mif_ud_decoding = bw;
+ break;
+ default:
+ pr_err("BTS : unsupported media type - %u", media_type);
+ break;
+ }
+
+ for (i = 0; i < VPP_MAX; i++)
+ vpp_total_bw += vpp_bw[VPP_BW][i];
+
+ total_bw = vpp_total_bw + cam_bw;
+
+ int_freq = (total_bw * 100) / (INT_UTIL * BUS_WIDTH);
+ /* INT_L0 shared between camera and normal scenarioes */
+ if (int_freq > 468000)
+ int_freq = 690000;
+
+ if (pm_qos_request_active(&exynos8_int_bts_qos))
+ pm_qos_update_request(&exynos8_int_bts_qos, int_freq);
+
+ for (i = 0; i < VPP_MAX; i++) {
+ if (max_status < vpp_status[i])
+ max_status = vpp_status[i];
+ }
+
+ switch (max_status) {
+ case BW_FULLHD_ROT:
+ SIZE_FACTOR(total_bw);
+ case BW_ROT:
+ if (total_bw < 200000)
+ utilization = 7;
+ else if (total_bw < 500000)
+ utilization = 10;
+ else if (total_bw < 1600000)
+ utilization = 29;
+ else if (total_bw < 3000000)
+ utilization = 48;
+ else if (total_bw < 3500000)
+ utilization = 55;
+ else if (total_bw < 4000000)
+ utilization = 60;
+ else if (total_bw < 5000000)
+ utilization = 70;
+ else if (total_bw < 7000000)
+ utilization = 76;
+ else
+ utilization = 83;
+ break;
+ case BW_DEFAULT:
+ if (total_bw < (63000 * 2) * 8 * 4)
+ utilization = MIF_UTIL;
+ else
+ utilization = MIF_UTIL2;
+ break;
+ default:
+ pr_err("BTS : unsupported bandwidth type - %u", media_type);
+ break;
+ }
+
+ mif_freq = (total_bw * 100) / (utilization * BUS_WIDTH);
+
+ /* for MFC UHD en/decoding (TBD) */
+ if (mif_ud_encoding && mif_freq < MIF_ENCODING)
+ mif_freq = MIF_ENCODING;
+ if (mif_ud_decoding && mif_freq < MIF_DECODING)
+ mif_freq = MIF_DECODING;
+
+ BTS_DBG("[BTS BW] total: %u, vpp: %u, vpp_rot: %u, cam: %u, yuv: %u, ud_en: %u, ud_de:%u\n",
+ total_bw, vpp_total_bw, sum_rot_bw, cam_bw, is_yuv,
+ mif_ud_encoding, mif_ud_decoding);
+ /*
+ * VPP0(G0), VPP1(G1), VPP2(VG0), VPP3(VG1),
+ * VPP4(G2), VPP5(G3), VPP6(VGR0), VPP7(VGR1), VPP8(WB)
+ * vpp_bus_bw[0] = DISP0_0_BW = G0 + VG0;
+ * vpp_bus_bw[1] = DISP0_1_BW = G1 + VG1;
+ * vpp_bus_bw[2] = DISP1_0_BW = G2 + VGR0;
+ * vpp_bus_bw[3] = DISP1_1_BW = G3 + VGR1 + WB;
+ */
+ BTS_DBG("[BTS VPP] vpp0(G0) vpp1(G1) vpp2(VG0) vpp3(VG1) vpp4(G2) vpp5(G3) "
+ "vpp6(VGR0) vpp7(VGR1) vpp8(WB)\n");
+ BTS_DBG("[BTS VPP]");
+ for (i = 0; i < VPP_MAX; i++)
+ BTS_DBG(" vpp%d %u,", i, vpp_bw[VPP_BW][i]);
+ BTS_DBG("\n");
+ BTS_DBG("[BTS FREQ] MIF freq: %u, util: %u, INT freq: %u\n",
+ mif_freq, utilization, int_freq);
+
+ if (pm_qos_request_active(&exynos8_mif_bts_qos))
+ pm_qos_update_request(&exynos8_mif_bts_qos, mif_freq);
+
+ mutex_unlock(&media_mutex);
+}
+#endif /* BTS_OPT */
+
+static void __iomem *sci_base;
+void exynos_bts_scitoken_setting(bool on)
+{
+ if (on)
+ __raw_writel(0x10101117, sci_base + CMDTOKEN);
+ else
+ __raw_writel(0x10101127, sci_base + CMDTOKEN);
+}
+
+#ifdef CONFIG_CPU_IDLE
+static int exynos8_bts_lpa_event(struct notifier_block *nb,
+ unsigned long event, void *data)
+{
+ unsigned long i;
+
+ switch (event) {
+ case LPA_EXIT:
+ for (i = 0; i < (unsigned int)ARRAY_SIZE(base_trex); i++)
+ bts_trex_init(base_trex[i]);
+ bts_initialize("trex", true);
+ break;
+ case LPA_ENTER:
+ break;
+ default:
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block bts_lpa_nb = {
+ .notifier_call = exynos8_bts_lpa_event,
+};
+#endif
+
+static int __init exynos8_bts_init(void)
+{
+ signed long i;
+ int ret;
+ enum bts_index btstable_index = BTS_MAX - 1;
+
+ BTS_DBG("[BTS][%s] bts init\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(clk_table); i++) {
+ if (btstable_index != clk_table[i].index) {
+ btstable_index = clk_table[i].index;
+ exynos8_bts[btstable_index].ct_ptr = clk_table + i;
+ }
+ clk_table[i].clk = clk_get(NULL, clk_table[i].clk_name);
+
+ if (IS_ERR(clk_table[i].clk)){
+ BTS_DBG("failed to get bts clk %s\n",
+ clk_table[i].clk_name);
+ exynos8_bts[btstable_index].ct_ptr = NULL;
+ }
+ else {
+ ret = clk_prepare(clk_table[i].clk);
+ if (ret) {
+ pr_err("[BTS] failed to prepare bts clk %s\n",
+ clk_table[i].clk_name);
+ for (; i >= 0; i--)
+ clk_put(clk_table[i].clk);
+ return ret;
+ }
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(exynos8_bts); i++) {
+ exynos8_bts[i].va_base = ioremap(exynos8_bts[i].pa_base, SZ_16K);
+
+ list_add(&exynos8_bts[i].list, &bts_list);
+ }
+
+ base_trex[0] = ioremap(EXYNOS8_PA_TREX_CCORE0, SZ_4K);
+ base_trex[1] = ioremap(EXYNOS8_PA_TREX_CCORE1, SZ_4K);
+
+ for (i = BS_DEFAULT + 1; i < BS_MAX; i++)
+ scen_chaining(i);
+
+ for (i = 0; i < ARRAY_SIZE(base_trex); i++)
+ bts_trex_init(base_trex[i]);
+
+ bts_initialize("trex", true);
+
+ /* SCI Related settings */
+ sci_base = ioremap(EXYNOS8_PA_SCI, SZ_4K);
+ exynos_bts_scitoken_setting(false);
+
+ pm_qos_add_request(&exynos8_mif_bts_qos, PM_QOS_BUS_THROUGHPUT, 0);
+ pm_qos_add_request(&exynos8_int_bts_qos, PM_QOS_DEVICE_THROUGHPUT, 0);
+ pm_qos_add_request(&exynos8_gpu_mif_bts_qos, PM_QOS_BUS_THROUGHPUT, 0);
+ pm_qos_add_request(&exynos8_winlayer_mif_bts_qos, PM_QOS_BUS_THROUGHPUT, 0);
+
+ register_pm_notifier(&exynos_bts_notifier);
+
+ //bts_debugfs();
+
+ srcu_init_notifier_head(&exynos_media_notifier);
+#ifdef CONFIG_CPU_IDLE
+ exynos_pm_register_notifier(&bts_lpa_nb);
+#endif
+
+ return 0;
+}
+arch_initcall(exynos8_bts_init);
--- /dev/null
+/* arch/arm/mach-exynos/cal_bts.c
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS - BTS CAL code.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "cal_bts.h"
+
+void bts_setqos(addr_u32 base, unsigned int priority) //QOS : [RRRRWWWW]
+{
+ Outp32(base + BTS_RCON, 0x0);
+ Outp32(base + BTS_RCON, 0x0);
+ Outp32(base + BTS_WCON, 0x0);
+ Outp32(base + BTS_WCON, 0x0);
+
+ Outp32(base + BTS_PRIORITY, ((priority >> 16) & 0xFFFF));
+ Outp32(base + BTS_TOKENMAX, 0xFFDF);
+ Outp32(base + BTS_BWUPBOUND, 0x18);
+ Outp32(base + BTS_BWLOBOUND, 0x1);
+ Outp32(base + BTS_INITTKN, 0x8);
+
+ Outp32(base + BTS_PRIORITY + WOFFSET, (priority & 0xFFFF));
+ Outp32(base + BTS_TOKENMAX + WOFFSET, 0xFFDF);
+ Outp32(base + BTS_BWUPBOUND + WOFFSET, 0x18);
+ Outp32(base + BTS_BWLOBOUND + WOFFSET, 0x1);
+ Outp32(base + BTS_INITTKN + WOFFSET, 0x8);
+
+ Outp32(base + BTS_RCON, 0x1);
+ Outp32(base + BTS_WCON, 0x1);
+}
+
+void bts_setqos_bw(addr_u32 base, unsigned int priority,
+ unsigned int window, unsigned int token) //QOS : [RRRRWWWW]
+{
+ Outp32(base + BTS_RCON, 0x0);
+ Outp32(base + BTS_RCON, 0x0);
+ Outp32(base + BTS_WCON, 0x0);
+ Outp32(base + BTS_WCON, 0x0);
+
+ Outp32(base + BTS_PRIORITY, ((priority >> 16) & 0xFFFF));
+ Outp32(base + BTS_TOKENMAX, 0xFFDF);
+ Outp32(base + BTS_BWUPBOUND, 0x18);
+ Outp32(base + BTS_BWLOBOUND, 0x1);
+ Outp32(base + BTS_INITTKN, 0x8);
+ Outp32(base + BTS_DEMWIN, window);
+ Outp32(base + BTS_DEMTKN, token);
+ Outp32(base + BTS_DEFWIN, window);
+ Outp32(base + BTS_DEFTKN, token);
+ Outp32(base + BTS_PRMWIN, window);
+ Outp32(base + BTS_PRMTKN, token);
+ Outp32(base + BTS_FLEXIBLE, 0x0);
+
+ Outp32(base + BTS_PRIORITY + WOFFSET, (priority & 0xFFFF));
+ Outp32(base + BTS_TOKENMAX + WOFFSET, 0xFFDF);
+ Outp32(base + BTS_BWUPBOUND + WOFFSET, 0x18);
+ Outp32(base + BTS_BWLOBOUND + WOFFSET, 0x1);
+ Outp32(base + BTS_INITTKN + WOFFSET, 0x8);
+ Outp32(base + BTS_DEMWIN + WOFFSET, window);
+ Outp32(base + BTS_DEMTKN + WOFFSET, token);
+ Outp32(base + BTS_DEFWIN + WOFFSET, window);
+ Outp32(base + BTS_DEFTKN + WOFFSET, token);
+ Outp32(base + BTS_PRMWIN + WOFFSET, window);
+ Outp32(base + BTS_PRMTKN + WOFFSET, token);
+ Outp32(base + BTS_FLEXIBLE + WOFFSET, 0x0);
+
+ Outp32(base + BTS_RMODE, 0x1);
+ Outp32(base + BTS_WMODE, 0x1);
+ Outp32(base + BTS_RCON, 0x3);
+ Outp32(base + BTS_WCON, 0x3);
+}
+
+
+void bts_setqos_mo(addr_u32 base, unsigned int priority,
+ unsigned int rmo, unsigned int wmo) //QOS : [RRRRWWWW]
+{
+ Outp32(base + BTS_RCON, 0x0);
+ Outp32(base + BTS_RCON, 0x0);
+ Outp32(base + BTS_WCON, 0x0);
+ Outp32(base + BTS_WCON, 0x0);
+
+ Outp32(base + BTS_PRIORITY, ((priority >> 16) & 0xFFFF));
+ Outp32(base + BTS_PRIORITY + WOFFSET, (priority & 0xFFFF));
+
+ if(rmo < MAX_MO_LIMIT)
+ {
+ Outp32(base + BTS_MOUPBOUND, 0x7F - rmo);
+ Outp32(base + BTS_MOLOBOUND, rmo);
+ Outp32(base + BTS_FLEXIBLE, 0x0);
+ Outp32(base + BTS_RMODE, 0x2);
+ Outp32(base + BTS_RCON, 0x3);
+ }
+ else
+ {
+ Outp32(base + BTS_TOKENMAX, 0xFFDF);
+ Outp32(base + BTS_BWUPBOUND, 0x18);
+ Outp32(base + BTS_BWLOBOUND, 0x1);
+ Outp32(base + BTS_INITTKN, 0x8);
+ Outp32(base + BTS_RCON, 0x1);
+ }
+
+ if(wmo < MAX_MO_LIMIT)
+ {
+ Outp32(base + BTS_MOUPBOUND + WOFFSET, 0x7F - wmo);
+ Outp32(base + BTS_MOLOBOUND + WOFFSET, wmo);
+ Outp32(base + BTS_FLEXIBLE + WOFFSET, 0x0);
+ Outp32(base + BTS_WMODE, 0x2);
+ Outp32(base + BTS_WCON, 0x3);
+ }
+ else
+ {
+ Outp32(base + BTS_TOKENMAX + WOFFSET, 0xFFDF);
+ Outp32(base + BTS_BWUPBOUND + WOFFSET, 0x18);
+ Outp32(base + BTS_BWLOBOUND + WOFFSET, 0x1);
+ Outp32(base + BTS_INITTKN + WOFFSET, 0x8);
+ Outp32(base + BTS_WCON, 0x1);
+ }
+}
+
+void bts_setqos_fbmbw(addr_u32 base, unsigned int priority, unsigned int window,
+ unsigned int token, unsigned int fbm) //QOS : [RRRRWWWW]
+{
+ Outp32(base + BTS_RCON, 0x0);
+ Outp32(base + BTS_RCON, 0x0);
+ Outp32(base + BTS_WCON, 0x0);
+ Outp32(base + BTS_WCON, 0x0);
+
+ Outp32(base + BTS_PRIORITY, ((priority >> 16) & 0xFFFF));
+ Outp32(base + BTS_TOKENMAX, 0xFFDF);
+ Outp32(base + BTS_BWUPBOUND, 0x18);
+ Outp32(base + BTS_BWLOBOUND, 0x1);
+ Outp32(base + BTS_INITTKN, 0x8);
+ Outp32(base + BTS_DEMWIN, window);
+ Outp32(base + BTS_DEMTKN, token);
+ Outp32(base + BTS_DEFWIN, window);
+ Outp32(base + BTS_DEFTKN, token);
+ Outp32(base + BTS_PRMWIN, window);
+ Outp32(base + BTS_PRMTKN, token);
+ Outp32(base + BTS_FLEXIBLE, 0x2);
+
+ Outp32(base + BTS_PRIORITY + WOFFSET, (priority & 0xFFFF));
+ Outp32(base + BTS_TOKENMAX + WOFFSET, 0xFFDF);
+ Outp32(base + BTS_BWUPBOUND + WOFFSET, 0x18);
+ Outp32(base + BTS_BWLOBOUND + WOFFSET, 0x1);
+ Outp32(base + BTS_INITTKN + WOFFSET, 0x8);
+ Outp32(base + BTS_DEMWIN + WOFFSET, window);
+ Outp32(base + BTS_DEMTKN + WOFFSET, token);
+ Outp32(base + BTS_DEFWIN + WOFFSET, window);
+ Outp32(base + BTS_DEFTKN + WOFFSET, token);
+ Outp32(base + BTS_PRMWIN + WOFFSET, window);
+ Outp32(base + BTS_PRMTKN + WOFFSET, token);
+ Outp32(base + BTS_FLEXIBLE + WOFFSET, 0x1);
+
+ Outp32(base + BTS_RMODE, 0x1);
+ Outp32(base + BTS_WMODE, 0x1);
+
+ if(fbm == 1) {
+ Outp32(base + BTS_RCON, 0x7);
+ Outp32(base + BTS_WCON, 0x7);
+ } else {
+ Outp32(base + BTS_RCON, 0x3);
+ Outp32(base + BTS_WCON, 0x3);
+ }
+}
+
+void bts_disable(addr_u32 base)
+{
+ /* reset to default */
+ Outp32(base + BTS_RCON, 0x0);
+ Outp32(base + BTS_RCON, 0x0);
+ Outp32(base + BTS_WCON, 0x0);
+ Outp32(base + BTS_WCON, 0x0);
+
+ Outp32(base + BTS_RMODE, 0x1);
+ Outp32(base + BTS_WMODE, 0x1);
+
+ Outp32(base + BTS_PRIORITY, 0xA942);
+ Outp32(base + BTS_TOKENMAX, 0x0);
+ Outp32(base + BTS_BWUPBOUND, 0x3FFF);
+ Outp32(base + BTS_BWLOBOUND, 0x3FFF);
+ Outp32(base + BTS_INITTKN, 0x7FFF);
+ Outp32(base + BTS_DEMWIN, 0x7FFF);
+ Outp32(base + BTS_DEMTKN, 0x1FFF);
+ Outp32(base + BTS_DEFWIN, 0x7FFF);
+ Outp32(base + BTS_DEFTKN, 0x1FFF);
+ Outp32(base + BTS_PRMWIN, 0x7FFF);
+ Outp32(base + BTS_PRMTKN, 0x1FFF);
+ Outp32(base + BTS_MOUPBOUND, 0x1F);
+ Outp32(base + BTS_MOLOBOUND, 0x1F);
+ Outp32(base + BTS_FLEXIBLE, 0x0);
+
+ Outp32(base + BTS_PRIORITY + WOFFSET, 0xA942);
+ Outp32(base + BTS_TOKENMAX + WOFFSET, 0x0);
+ Outp32(base + BTS_BWUPBOUND + WOFFSET, 0x3FFF);
+ Outp32(base + BTS_BWLOBOUND + WOFFSET, 0x3FFF);
+ Outp32(base + BTS_INITTKN + WOFFSET, 0x7FFF);
+ Outp32(base + BTS_DEMWIN + WOFFSET, 0x7FFF);
+ Outp32(base + BTS_DEMTKN + WOFFSET, 0x1FFF);
+ Outp32(base + BTS_DEFWIN + WOFFSET, 0x7FFF);
+ Outp32(base + BTS_DEFTKN + WOFFSET, 0x1FFF);
+ Outp32(base + BTS_PRMWIN + WOFFSET, 0x7FFF);
+ Outp32(base + BTS_PRMTKN + WOFFSET, 0x1FFF);
+ Outp32(base + BTS_MOUPBOUND + WOFFSET, 0x1F);
+ Outp32(base + BTS_MOLOBOUND + WOFFSET, 0x1F);
+ Outp32(base + BTS_FLEXIBLE + WOFFSET, 0x0);
+}
+
+void bts_settrexqos(addr_u32 base, unsigned int priority)
+{
+ Outp32(base + TBTS_CON, 0x0);
+ Outp32(base + TBTS_RCON, 0x0);
+ Outp32(base + TBTS_WCON, 0x0);
+
+#if defined(CONFIG_SOC_EXYNOS7420_EVT_0)
+ Outp32(base + TBTS_QURGUPTH, 0xF);
+ Outp32(base + TBTS_QURGDOWNTH, 0xF);
+#endif
+ Outp32(base + TBTS_DEMQOS, priority & 0xF);
+ Outp32(base + TBTS_DEFQOS, priority & 0xF);
+ Outp32(base + TBTS_PRMQOS, priority & 0xF);
+
+ Outp32(base + TBTS_CON, 0x1);
+}
+
+void bts_settrexqos_mo(addr_u32 base, unsigned int priority, unsigned int mo)
+{
+ Outp32(base + TBTS_CON, 0x0);
+ Outp32(base + TBTS_RCON, 0x0);
+ Outp32(base + TBTS_WCON, 0x0);
+
+#if defined(CONFIG_SOC_EXYNOS7420_EVT_0)
+ Outp32(base + TBTS_QURGUPTH, 0xF);
+ Outp32(base + TBTS_QURGDOWNTH, 0xF);
+#endif
+ Outp32(base + TBTS_TKNUPBOUND, mo);
+ Outp32(base + TBTS_TKNLOBOUND, mo);
+
+ Outp32(base + TBTS_DEMTH, mo);
+ Outp32(base + TBTS_PRMTH, mo);
+
+ Outp32(base + TBTS_DEMQOS, priority & 0xF);
+ Outp32(base + TBTS_DEFQOS, priority & 0xF);
+ Outp32(base + TBTS_PRMQOS, priority & 0xF);
+
+ Outp32(base + TBTS_RCON, 0x11); // MO mode & Blocking on
+ Outp32(base + TBTS_WCON, 0x11);
+ Outp32(base + TBTS_CON, 0x1);
+}
+
+void bts_settrexqos_bw(addr_u32 base, unsigned int priority, unsigned int decval)
+{
+ Outp32(base + TBTS_CON, 0x0);
+ Outp32(base + TBTS_RCON, 0x0);
+ Outp32(base + TBTS_WCON, 0x0);
+
+#if defined(CONFIG_SOC_EXYNOS7420_EVT_0)
+ Outp32(base + TBTS_QURGUPTH, 0xF);
+ Outp32(base + TBTS_QURGDOWNTH, 0xF);
+#endif
+
+ Outp32(base + TBTS_TKNUPBOUND, 0x3FFF);
+ Outp32(base + TBTS_TKNLOBOUND, 0x3FF7);
+ Outp32(base + TBTS_RTKNINIT, 0x3FFF);
+ Outp32(base + TBTS_WTKNINIT, 0x3FFF);
+
+ Outp32(base + TBTS_DEMQOS, priority & 0xF);
+ Outp32(base + TBTS_DEFQOS, priority & 0xF);
+ Outp32(base + TBTS_PRMQOS, priority & 0xF);
+
+ Outp32(base + TBTS_RTKNDEC, decval);
+ Outp32(base + TBTS_WTKNDEC, decval);
+
+ Outp32(base + TBTS_RCON, 0x1); // Blocking on
+ Outp32(base + TBTS_WCON, 0x1);
+ Outp32(base + TBTS_CON, 0x1);
+
+}
+
+void bts_settrexqos_fbmbw(addr_u32 base, unsigned int priority)
+{
+ Outp32(base + TBTS_CON, 0x0);
+ Outp32(base + TBTS_RCON, 0x0);
+ Outp32(base + TBTS_WCON, 0x0);
+
+ Outp32(base + TBTS_DEMQOS, priority & 0xF);
+ Outp32(base + TBTS_DEFQOS, priority & 0xF);
+ Outp32(base + TBTS_PRMQOS, priority & 0xF);
+
+ Outp32(base + TBTS_RCON, 0x1); // Blocking on
+ Outp32(base + TBTS_WCON, 0x1);
+ Outp32(base + TBTS_CON, 0x1);
+}
+
+void bts_trexdisable(addr_u32 base)
+{
+ Outp32(base + TBTS_CON, 0x00010000);
+ Outp32(base + TBTS_RCON, 0x0);
+ Outp32(base + TBTS_WCON, 0x0);
+
+ Outp32(base + TBTS_TKNUPBOUND, 0x5FFF);
+ Outp32(base + TBTS_TKNLOBOUND, 0x1FFF);
+
+ Outp32(base + TBTS_DEMTH, 0x5FFF);
+ Outp32(base + TBTS_PRMTH, 0x1FFF);
+
+#if defined(CONFIG_SOC_EXYNOS7420_EVT_0)
+ Outp32(base + TBTS_DEMQOS, 0x9);
+ Outp32(base + TBTS_DEFQOS, 0x4);
+ Outp32(base + TBTS_PRMQOS, 0x2);
+#else
+ Outp32(base + TBTS_DEMQOS, 0x2);
+ Outp32(base + TBTS_DEFQOS, 0x4);
+ Outp32(base + TBTS_PRMQOS, 0x9);
+#endif
+
+ Outp32(base + TBTS_QURGUPTH, 0x8);
+ Outp32(base + TBTS_QURGDOWNTH, 0x8);
+ Outp32(base + TBTS_RTKNINIT, 0x3FFF);
+ Outp32(base + TBTS_WTKNINIT, 0x3FFF);
+ Outp32(base + TBTS_RTKNDEC, 0x0);
+ Outp32(base + TBTS_WTKNDEC, 0x0);
+}
+
+void bts_setnsp(addr_u32 base, unsigned int nsp)
+{
+ Outp32(base , nsp);
+}
--- /dev/null
+/* arch/arm/mach-exynos/cal_bts.h
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS - BTS CAL code.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __BTSCAL_H__
+#define __BTSCAL_H__
+
+#if defined(CONFIG_EXYNOS7420_BTS)
+#include <linux/io.h>
+
+#define Outp32(addr, data) (__raw_writel(data, addr))
+#define Inp32(addr) (__raw_readl(addr))
+typedef void __iomem *addr_u32;
+
+#else
+typedef unsigned long u32;
+typedef unsigned long addr_u32;
+#define Outp32(addr, data) (*(volatile unsigned int *)(addr) = (data))
+#define Inp32(addr) (*(volatile unsigned int *)(addr))
+
+#endif
+
+/* for BTS V2.1 Register */
+#define BTS_RCON 0x100
+#define BTS_RMODE 0x104
+#define BTS_WCON 0x180
+#define BTS_WMODE 0x184
+#define BTS_PRIORITY 0x200
+#define BTS_TOKENMAX 0x204
+#define BTS_BWUPBOUND 0x20C
+#define BTS_BWLOBOUND 0x210
+#define BTS_INITTKN 0x214
+#define BTS_RSTCLK 0x218
+#define BTS_RSTTKN 0x21C
+#define BTS_DEMWIN 0x220
+#define BTS_DEMTKN 0x224
+#define BTS_DEFWIN 0x228
+#define BTS_DEFTKN 0x22C
+#define BTS_PRMWIN 0x230
+#define BTS_PRMTKN 0x234
+#define BTS_MOUPBOUND 0x240
+#define BTS_MOLOBOUND 0x244
+#define BTS_FLEXIBLE 0x280
+#define BTS_POLARITY 0x284
+#define BTS_FBMGRP0ADRS 0x290
+#define BTS_FBMGRP0ADRE 0x294
+#define BTS_FBMGRP1ADRS 0x298
+#define BTS_FBMGRP1ADRE 0x29C
+#define BTS_FBMGRP2ADRS 0x2A0
+#define BTS_FBMGRP2ADRE 0x2A4
+#define BTS_FBMGRP3ADRS 0x2A8
+#define BTS_FBMGRP3ADRE 0x2AC
+#define BTS_FBMGRP4ADRS 0x2B0
+#define BTS_FBMGRP4ADRE 0x2B4
+#define BTS_EMERGENTRID 0x2C0
+#define BTS_EMERGENTWID 0x3C0
+#define BTS_RISINGTH 0x2C4
+#define BTS_FALLINGTH 0x2C8
+#define BTS_FALLINGMO 0x2CC
+#define BTS_MOCOUNTER 0x2F0
+#define BTS_STATUS 0x2F4
+#define BTS_BWMONLOW 0x2F8
+#define BTS_BWMONUP 0x2FC
+
+#define WOFFSET 0x100
+
+/* for TREX_BTS Register */
+#define TBTS_CON 0x000
+#define TBTS_TKNUPBOUND 0x010
+#define TBTS_TKNLOBOUND 0x014
+#define TBTS_LOADUP 0x020
+#define TBTS_LOADDOWN 0x024
+#define TBTS_TKNINC0 0x040
+#define TBTS_TKNINC1 0x044
+#define TBTS_TKNINC2 0x048
+#define TBTS_TKNINC3 0x04C
+#define TBTS_TKNINC4 0x050
+#define TBTS_TKNINC5 0x054
+#define TBTS_TKNINC6 0x058
+#define TBTS_TKNINC7 0x05C
+#define TBTS_DEMTH 0x070
+#define TBTS_PRMTH 0x074
+#define TBTS_DEMQOS 0x080
+#define TBTS_DEFQOS 0x084
+#define TBTS_PRMQOS 0x088
+#define TBTS_TIMEOUT 0x090
+#define TBTS_QURGUPTH 0x0D0
+#define TBTS_QURGDOWNTH 0x0D4
+#define TBTS_SELIDMASK 0x0E0
+#define TBTS_SELIDVAL 0x0E4
+#define TBTS_RCON 0x100
+#define TBTS_RTKNINIT 0x110
+#define TBTS_RTKNDEC 0x120
+#define TBTS_WCON 0x200
+#define TBTS_WTKNINIT 0x210
+#define TBTS_WTKNDEC 0x220
+#define TBTS_EMERGENTID 0x2014
+#define TBTS_MASK 0x2010
+
+#define MAX_MO_LIMIT 0x80
+
+void bts_setqos(addr_u32 base, unsigned int priority);
+void bts_setqos_bw(addr_u32 base, unsigned int priority,
+ unsigned int window, unsigned int token);
+void bts_setqos_mo(addr_u32 base, unsigned int priority,
+ unsigned int rmo, unsigned int wmo);
+void bts_setqos_fbmbw(addr_u32 base, unsigned int priority, unsigned int window,
+ unsigned int token, unsigned int fbm);
+void bts_disable(addr_u32 base);
+void bts_settrexqos(addr_u32 base, unsigned int priority);
+void bts_settrexqos_mo(addr_u32 base, unsigned int priority, unsigned int mo);
+void bts_settrexqos_bw(addr_u32 base, unsigned int priority, unsigned int decval);
+void bts_settrexqos_fbmbw(addr_u32 base, unsigned int priority);
+void bts_trexdisable(addr_u32 base);
+void bts_setnsp(addr_u32 base, unsigned int nsp);
+
+#endif
--- /dev/null
+/* arch/arm/mach-exynos/cal_bts.c
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS - BTS CAL code.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "cal_bts8890.h"
+
+void bts_setqos(addr_u32 base, unsigned int priority, unsigned int master_id) //QOS : [RRRRWWWW]
+{
+ Outp32(base + BTS_RCON, 0x0);
+ Outp32(base + BTS_RCON, 0x0);
+ Outp32(base + BTS_WCON, 0x0);
+ Outp32(base + BTS_WCON, 0x0);
+
+ Outp32(base + BTS_PRIORITY, ((priority >> 16) & 0xFFFF));
+ Outp32(base + BTS_TOKENMAX, 0xFFDF);
+ Outp32(base + BTS_BWUPBOUND, 0x18);
+ Outp32(base + BTS_BWLOBOUND, 0x1);
+ Outp32(base + BTS_INITTKN, 0x8);
+
+ Outp32(base + BTS_PRIORITY + WOFFSET, (priority & 0xFFFF));
+ Outp32(base + BTS_TOKENMAX + WOFFSET, 0xFFDF);
+ Outp32(base + BTS_BWUPBOUND + WOFFSET, 0x18);
+ Outp32(base + BTS_BWLOBOUND + WOFFSET, 0x1);
+ Outp32(base + BTS_INITTKN + WOFFSET, 0x8);
+
+ Outp32(base + BTS_EMERGENTRID, master_id);
+ Outp32(base + BTS_EMERGENTWID, master_id);
+ Outp32(base + BTS_RCON, 0x1);
+ Outp32(base + BTS_WCON, 0x1);
+}
+
+void bts_setqos_bw(addr_u32 base, unsigned int priority,
+ unsigned int window, unsigned int token, unsigned int master_id) //QOS : [RRRRWWWW]
+{
+ Outp32(base + BTS_RCON, 0x0);
+ Outp32(base + BTS_RCON, 0x0);
+ Outp32(base + BTS_WCON, 0x0);
+ Outp32(base + BTS_WCON, 0x0);
+
+ Outp32(base + BTS_PRIORITY, ((priority >> 16) & 0xFFFF));
+ Outp32(base + BTS_TOKENMAX, 0xFFDF);
+ Outp32(base + BTS_BWUPBOUND, 0x18);
+ Outp32(base + BTS_BWLOBOUND, 0x1);
+ Outp32(base + BTS_INITTKN, 0x8);
+ Outp32(base + BTS_DEMWIN, window);
+ Outp32(base + BTS_DEMTKN, token);
+ Outp32(base + BTS_DEFWIN, window);
+ Outp32(base + BTS_DEFTKN, token);
+ Outp32(base + BTS_PRMWIN, window);
+ Outp32(base + BTS_PRMTKN, token);
+ Outp32(base + BTS_FLEXIBLE, 0x0);
+
+ Outp32(base + BTS_PRIORITY + WOFFSET, (priority & 0xFFFF));
+ Outp32(base + BTS_TOKENMAX + WOFFSET, 0xFFDF);
+ Outp32(base + BTS_BWUPBOUND + WOFFSET, 0x18);
+ Outp32(base + BTS_BWLOBOUND + WOFFSET, 0x1);
+ Outp32(base + BTS_INITTKN + WOFFSET, 0x8);
+ Outp32(base + BTS_DEMWIN + WOFFSET, window);
+ Outp32(base + BTS_DEMTKN + WOFFSET, token);
+ Outp32(base + BTS_DEFWIN + WOFFSET, window);
+ Outp32(base + BTS_DEFTKN + WOFFSET, token);
+ Outp32(base + BTS_PRMWIN + WOFFSET, window);
+ Outp32(base + BTS_PRMTKN + WOFFSET, token);
+ Outp32(base + BTS_FLEXIBLE + WOFFSET, 0x0);
+
+ Outp32(base + BTS_RMODE, 0x1);
+ Outp32(base + BTS_WMODE, 0x1);
+ Outp32(base + BTS_EMERGENTRID, master_id);
+ Outp32(base + BTS_EMERGENTWID, master_id);
+ Outp32(base + BTS_RCON, 0x3);
+ Outp32(base + BTS_WCON, 0x3);
+}
+
+void bts_setqos_mo(addr_u32 base, unsigned int priority, unsigned int mo, unsigned int master_id) //QOS : [RRRRWWWW]
+{
+ Outp32(base + BTS_RCON, 0x0);
+ Outp32(base + BTS_RCON, 0x0);
+ Outp32(base + BTS_WCON, 0x0);
+ Outp32(base + BTS_WCON, 0x0);
+
+ Outp32(base + BTS_PRIORITY, ((priority >> 16) & 0xFFFF));
+ Outp32(base + BTS_MOUPBOUND, 0x7F - mo);
+ Outp32(base + BTS_MOLOBOUND, mo);
+ Outp32(base + BTS_FLEXIBLE, 0x0);
+
+ Outp32(base + BTS_PRIORITY + WOFFSET, (priority & 0xFFFF));
+ Outp32(base + BTS_MOUPBOUND + WOFFSET, 0x7F - mo);
+ Outp32(base + BTS_MOLOBOUND + WOFFSET, mo);
+ Outp32(base + BTS_FLEXIBLE + WOFFSET, 0x0);
+
+ Outp32(base + BTS_RMODE, 0x2);
+ Outp32(base + BTS_WMODE, 0x2);
+ Outp32(base + BTS_EMERGENTRID, master_id);
+ Outp32(base + BTS_EMERGENTWID, master_id);
+ Outp32(base + BTS_RCON, 0x3);
+ Outp32(base + BTS_WCON, 0x3);
+}
+
+void bts_setqos_fbmbw(addr_u32 base, unsigned int priority, unsigned int window,
+ unsigned int token, unsigned int fbm, unsigned int master_id) //QOS : [RRRRWWWW]
+{
+ Outp32(base + BTS_RCON, 0x0);
+ Outp32(base + BTS_RCON, 0x0);
+ Outp32(base + BTS_WCON, 0x0);
+ Outp32(base + BTS_WCON, 0x0);
+
+ Outp32(base + BTS_PRIORITY, ((priority >> 16) & 0xFFFF));
+ Outp32(base + BTS_TOKENMAX, 0xFFDF);
+ Outp32(base + BTS_BWUPBOUND, 0x18);
+ Outp32(base + BTS_BWLOBOUND, 0x1);
+ Outp32(base + BTS_INITTKN, 0x8);
+ Outp32(base + BTS_DEMWIN, window);
+ Outp32(base + BTS_DEMTKN, token);
+ Outp32(base + BTS_DEFWIN, window);
+ Outp32(base + BTS_DEFTKN, token);
+ Outp32(base + BTS_PRMWIN, window);
+ Outp32(base + BTS_PRMTKN, token);
+ Outp32(base + BTS_FLEXIBLE, 0x2);
+
+ Outp32(base + BTS_PRIORITY + WOFFSET, (priority & 0xFFFF));
+ Outp32(base + BTS_TOKENMAX + WOFFSET, 0xFFDF);
+ Outp32(base + BTS_BWUPBOUND + WOFFSET, 0x18);
+ Outp32(base + BTS_BWLOBOUND + WOFFSET, 0x1);
+ Outp32(base + BTS_INITTKN + WOFFSET, 0x8);
+ Outp32(base + BTS_DEMWIN + WOFFSET, window);
+ Outp32(base + BTS_DEMTKN + WOFFSET, token);
+ Outp32(base + BTS_DEFWIN + WOFFSET, window);
+ Outp32(base + BTS_DEFTKN + WOFFSET, token);
+ Outp32(base + BTS_PRMWIN + WOFFSET, window);
+ Outp32(base + BTS_PRMTKN + WOFFSET, token);
+ Outp32(base + BTS_FLEXIBLE + WOFFSET, 0x1);
+
+ Outp32(base + BTS_RMODE, 0x1);
+ Outp32(base + BTS_WMODE, 0x1);
+
+ Outp32(base + BTS_EMERGENTRID, master_id);
+ Outp32(base + BTS_EMERGENTWID, master_id);
+ if(fbm == 1) {
+ Outp32(base + BTS_RCON, 0x7);
+ Outp32(base + BTS_WCON, 0x7);
+ } else {
+ Outp32(base + BTS_RCON, 0x3);
+ Outp32(base + BTS_WCON, 0x3);
+ }
+}
+
+
+void bts_setemergentID(addr_u32 base, unsigned int master_id)
+{
+ Outp32(base + BTS_PRIORITY, 0x4444);
+ Outp32(base + BTS_PRIORITY + WOFFSET, 0x4444);
+
+ Outp32(base + BTS_EMERGENTRID, master_id);
+ Outp32(base + BTS_EMERGENTWID, master_id);
+}
+
+
+void bts_disable(addr_u32 base, unsigned int master_id)
+{
+ /* reset to default */
+ Outp32(base + BTS_RCON, 0x0);
+ Outp32(base + BTS_RCON, 0x0);
+ Outp32(base + BTS_WCON, 0x0);
+ Outp32(base + BTS_WCON, 0x0);
+
+ Outp32(base + BTS_RMODE, 0x1);
+ Outp32(base + BTS_WMODE, 0x1);
+
+ Outp32(base + BTS_PRIORITY, 0xA942);
+ Outp32(base + BTS_TOKENMAX, 0x0);
+ Outp32(base + BTS_BWUPBOUND, 0x3FFF);
+ Outp32(base + BTS_BWLOBOUND, 0x3FFF);
+ Outp32(base + BTS_INITTKN, 0x7FFF);
+ Outp32(base + BTS_DEMWIN, 0x7FFF);
+ Outp32(base + BTS_DEMTKN, 0x1FFF);
+ Outp32(base + BTS_DEFWIN, 0x7FFF);
+ Outp32(base + BTS_DEFTKN, 0x1FFF);
+ Outp32(base + BTS_PRMWIN, 0x7FFF);
+ Outp32(base + BTS_PRMTKN, 0x1FFF);
+ Outp32(base + BTS_MOUPBOUND, 0x1F);
+ Outp32(base + BTS_MOLOBOUND, 0x1F);
+ Outp32(base + BTS_FLEXIBLE, 0x0);
+
+ Outp32(base + BTS_PRIORITY + WOFFSET, 0xA942);
+ Outp32(base + BTS_TOKENMAX + WOFFSET, 0x0);
+ Outp32(base + BTS_BWUPBOUND + WOFFSET, 0x3FFF);
+ Outp32(base + BTS_BWLOBOUND + WOFFSET, 0x3FFF);
+ Outp32(base + BTS_INITTKN + WOFFSET, 0x7FFF);
+ Outp32(base + BTS_DEMWIN + WOFFSET, 0x7FFF);
+ Outp32(base + BTS_DEMTKN + WOFFSET, 0x1FFF);
+ Outp32(base + BTS_DEFWIN + WOFFSET, 0x7FFF);
+ Outp32(base + BTS_DEFTKN + WOFFSET, 0x1FFF);
+ Outp32(base + BTS_PRMWIN + WOFFSET, 0x7FFF);
+ Outp32(base + BTS_PRMTKN + WOFFSET, 0x1FFF);
+ Outp32(base + BTS_MOUPBOUND + WOFFSET, 0x1F);
+ Outp32(base + BTS_MOLOBOUND + WOFFSET, 0x1F);
+ Outp32(base + BTS_FLEXIBLE + WOFFSET, 0x0);
+ Outp32(base + BTS_EMERGENTRID, master_id);
+ Outp32(base + BTS_EMERGENTWID, master_id);
+}
+
+void bts_settrexqos(addr_u32 base, unsigned int priority, unsigned int master_id, unsigned int mask)
+{
+ Outp32(base + TBTS_CON, 0x0);
+ Outp32(base + TBTS_RCON, 0x0);
+ Outp32(base + TBTS_WCON, 0x0);
+
+ Outp32(base + TBTS_DEMQOS, priority & 0xF);
+ Outp32(base + TBTS_DEFQOS, priority & 0xF);
+ Outp32(base + TBTS_PRMQOS, priority & 0xF);
+
+ Outp32(base + TBTS_EMERGENTID, master_id);
+ Outp32(base + TBTS_MASK, mask);
+ Outp32(base + TBTS_CON, 0x1001);
+}
+
+void bts_settrexqos_mo(addr_u32 base, unsigned int priority, unsigned int mo, unsigned int master_id, unsigned int mask)
+{
+ Outp32(base + TBTS_CON, 0x0);
+ Outp32(base + TBTS_RCON, 0x0);
+ Outp32(base + TBTS_WCON, 0x0);
+
+ Outp32(base + TBTS_TKNUPBOUND, mo);
+ Outp32(base + TBTS_TKNLOBOUND, mo);
+
+ Outp32(base + TBTS_DEMTH, mo);
+ Outp32(base + TBTS_PRMTH, mo);
+
+ Outp32(base + TBTS_DEMQOS, priority & 0xF);
+ Outp32(base + TBTS_DEFQOS, priority & 0xF);
+ Outp32(base + TBTS_PRMQOS, priority & 0xF);
+
+ Outp32(base + TBTS_RCON, 0x11); // MO mode & Blocking on
+ Outp32(base + TBTS_WCON, 0x11);
+ Outp32(base + TBTS_EMERGENTID, master_id);
+ Outp32(base + TBTS_MASK, mask);
+ Outp32(base + TBTS_CON, 0x1001);
+}
+
+void bts_settrexqos_mo_rt(addr_u32 base, unsigned int priority, unsigned int mo, unsigned int master_id, unsigned int mask,
+ unsigned int time_out, unsigned int bypass_en)
+{
+ Outp32(base + TBTS_CON, 0x0);
+ Outp32(base + TBTS_RCON, 0x0);
+ Outp32(base + TBTS_WCON, 0x0);
+
+ Outp32(base + TBTS_TKNUPBOUND, mo);
+ Outp32(base + TBTS_TKNLOBOUND, mo);
+
+ Outp32(base + TBTS_DEMTH, mo);
+ Outp32(base + TBTS_PRMTH, mo);
+
+ Outp32(base + TBTS_DEMQOS, priority & 0xF);
+ Outp32(base + TBTS_DEFQOS, priority & 0xF);
+ Outp32(base + TBTS_PRMQOS, priority & 0xF);
+
+ Outp32(base + TBTS_TIMEOUT, time_out);
+
+ if(bypass_en) {
+ Outp32(base + TBTS_RCON, 0x111); // MO mode & Qos bypass
+ Outp32(base + TBTS_WCON, 0x111);
+ } else {
+ Outp32(base + TBTS_RCON, 0x11); // MO mode
+ Outp32(base + TBTS_WCON, 0x11);
+ }
+ Outp32(base + TBTS_EMERGENTID, master_id);
+ Outp32(base + TBTS_MASK, mask);
+ Outp32(base + TBTS_CON, 0x1001); // Time out, Urgent enable
+}
+
+void bts_settrexqos_mo_cp(addr_u32 base, unsigned int priority, unsigned int mo, unsigned int master_id, unsigned int mask,
+ unsigned int time_out, unsigned int bypass_en)
+{
+ Outp32(base + TBTS_CON, 0x0);
+ Outp32(base + TBTS_RCON, 0x0);
+ Outp32(base + TBTS_WCON, 0x0);
+
+ Outp32(base + TBTS_TKNUPBOUND, mo);
+ Outp32(base + TBTS_TKNLOBOUND, mo);
+
+ Outp32(base + TBTS_DEMTH, mo);
+ Outp32(base + TBTS_PRMTH, mo);
+
+ Outp32(base + TBTS_DEMQOS, priority & 0xF);
+ Outp32(base + TBTS_DEFQOS, priority & 0xF);
+ Outp32(base + TBTS_PRMQOS, priority & 0xF);
+
+ Outp32(base + TBTS_TIMEOUT, time_out);
+
+ if(bypass_en) {
+ Outp32(base + TBTS_RCON, 0x111); // MO mode & Qos bypass
+ Outp32(base + TBTS_WCON, 0x111);
+ } else {
+ Outp32(base + TBTS_RCON, 0x11); // MO mode
+ Outp32(base + TBTS_WCON, 0x11);
+ }
+ Outp32(base + TBTS_EMERGENTID, master_id);
+ Outp32(base + TBTS_MASK, mask);
+ Outp32(base + TBTS_CON, 0x101101); // Time out, Urgent enable
+}
+
+void bts_settrexqos_mo_change(addr_u32 base, unsigned int mo)
+{
+ Outp32(base + TBTS_RCON, 0x0);
+ Outp32(base + TBTS_WCON, 0x0);
+
+ Outp32(base + TBTS_TKNUPBOUND, mo);
+ Outp32(base + TBTS_TKNLOBOUND, mo);
+
+ Outp32(base + TBTS_DEMTH, mo);
+ Outp32(base + TBTS_PRMTH, mo);
+
+ Outp32(base + TBTS_RCON, 0x11); // MO mode & Blocking on
+ Outp32(base + TBTS_WCON, 0x11);
+}
+
+void bts_settrexqos_urgent_off(addr_u32 base)
+{
+ Outp32(base + TBTS_CON, 0x001001); // Time out, Urgent disable
+}
+void bts_settrexqos_urgent_on(addr_u32 base)
+{
+ Outp32(base + TBTS_CON, 0x101101); // Time out, Urgent enable
+}
+
+void bts_settrexqos_bw(addr_u32 base, unsigned int priority, unsigned int decval, unsigned int master_id, unsigned int mask)
+{
+ Outp32(base + TBTS_CON, 0x0);
+ Outp32(base + TBTS_RCON, 0x0);
+ Outp32(base + TBTS_WCON, 0x0);
+
+ Outp32(base + TBTS_TKNUPBOUND, 0x3FFF);
+ Outp32(base + TBTS_TKNLOBOUND, 0x3FF7);
+ Outp32(base + TBTS_RTKNINIT, 0x3FFF);
+ Outp32(base + TBTS_WTKNINIT, 0x3FFF);
+
+ Outp32(base + TBTS_DEMQOS, priority & 0xF);
+ Outp32(base + TBTS_DEFQOS, priority & 0xF);
+ Outp32(base + TBTS_PRMQOS, priority & 0xF);
+
+ Outp32(base + TBTS_RTKNDEC, decval);
+ Outp32(base + TBTS_WTKNDEC, decval);
+
+ Outp32(base + TBTS_RCON, 0x1); // Blocking on
+ Outp32(base + TBTS_WCON, 0x1);
+ Outp32(base + TBTS_EMERGENTID, master_id);
+ Outp32(base + TBTS_MASK, mask);
+ Outp32(base + TBTS_CON, 0x1001);
+
+}
+
+void bts_settrexqos_fbmbw(addr_u32 base, unsigned int priority, unsigned int master_id, unsigned int mask)
+{
+ Outp32(base + TBTS_CON, 0x0);
+ Outp32(base + TBTS_RCON, 0x0);
+ Outp32(base + TBTS_WCON, 0x0);
+
+ Outp32(base + TBTS_DEMQOS, priority & 0xF);
+ Outp32(base + TBTS_DEFQOS, priority & 0xF);
+ Outp32(base + TBTS_PRMQOS, priority & 0xF);
+
+ Outp32(base + TBTS_RCON, 0x1); // Blocking on
+ Outp32(base + TBTS_WCON, 0x1);
+ Outp32(base + TBTS_EMERGENTID, master_id);
+ Outp32(base + TBTS_MASK, mask);
+ Outp32(base + TBTS_CON, 0x1001);
+}
+
+
+void bts_trexdisable(addr_u32 base, unsigned int master_id, unsigned int mask)
+{
+ Outp32(base + TBTS_CON, 0x00010000);
+ Outp32(base + TBTS_RCON, 0x0);
+ Outp32(base + TBTS_WCON, 0x0);
+
+ Outp32(base + TBTS_TKNUPBOUND, 0x5FFF);
+ Outp32(base + TBTS_TKNLOBOUND, 0x1FFF);
+
+ Outp32(base + TBTS_DEMTH, 0x5FFF);
+ Outp32(base + TBTS_PRMTH, 0x1FFF);
+
+ Outp32(base + TBTS_DEMQOS, 0x2);
+ Outp32(base + TBTS_DEFQOS, 0x4);
+ Outp32(base + TBTS_PRMQOS, 0x9);
+
+ Outp32(base + TBTS_QURGUPTH, 0x8);
+ Outp32(base + TBTS_QURGDOWNTH, 0x8);
+ Outp32(base + TBTS_RTKNINIT, 0x3FFF);
+ Outp32(base + TBTS_WTKNINIT, 0x3FFF);
+ Outp32(base + TBTS_RTKNDEC, 0x0);
+ Outp32(base + TBTS_WTKNDEC, 0x0);
+ Outp32(base + TBTS_EMERGENTID, master_id);
+ Outp32(base + TBTS_MASK, mask);
+}
+
+
+
+void bts_setnsp(addr_u32 base, unsigned int nsp)
+{
+ Outp32(base , nsp);
+}
--- /dev/null
+/* arch/arm/mach-exynos/cal_bts.h
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS - BTS CAL code.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __BTSCAL_H__
+#define __BTSCAL_H__
+
+#if defined(CONFIG_EXYNOS8890_BTS)
+#include <linux/io.h>
+
+#define Outp32(addr, data) (__raw_writel(data, addr))
+#define Inp32(addr) (__raw_readl(addr))
+typedef void __iomem *addr_u32;
+
+#else
+typedef unsigned long u32;
+typedef unsigned long addr_u32;
+#define Outp32(addr, data) (*(volatile unsigned int *)(addr) = (data))
+#define Inp32(addr) (*(volatile unsigned int *)(addr))
+
+#endif
+
+/* for BTS V2.1 Register */
+#define BTS_RCON 0x100
+#define BTS_RMODE 0x104
+#define BTS_WCON 0x180
+#define BTS_WMODE 0x184
+#define BTS_PRIORITY 0x200
+#define BTS_TOKENMAX 0x204
+#define BTS_BWUPBOUND 0x20C
+#define BTS_BWLOBOUND 0x210
+#define BTS_INITTKN 0x214
+#define BTS_RSTCLK 0x218
+#define BTS_RSTTKN 0x21C
+#define BTS_DEMWIN 0x220
+#define BTS_DEMTKN 0x224
+#define BTS_DEFWIN 0x228
+#define BTS_DEFTKN 0x22C
+#define BTS_PRMWIN 0x230
+#define BTS_PRMTKN 0x234
+#define BTS_MOUPBOUND 0x240
+#define BTS_MOLOBOUND 0x244
+#define BTS_FLEXIBLE 0x280
+#define BTS_POLARITY 0x284
+#define BTS_FBMGRP0ADRS 0x290
+#define BTS_FBMGRP0ADRE 0x294
+#define BTS_FBMGRP1ADRS 0x298
+#define BTS_FBMGRP1ADRE 0x29C
+#define BTS_FBMGRP2ADRS 0x2A0
+#define BTS_FBMGRP2ADRE 0x2A4
+#define BTS_FBMGRP3ADRS 0x2A8
+#define BTS_FBMGRP3ADRE 0x2AC
+#define BTS_FBMGRP4ADRS 0x2B0
+#define BTS_FBMGRP4ADRE 0x2B4
+#define BTS_EMERGENTRID 0x2C0
+#define BTS_EMERGENTWID 0x3C0
+#define BTS_RISINGTH 0x2C4
+#define BTS_FALLINGTH 0x2C8
+#define BTS_FALLINGMO 0x2CC
+#define BTS_MOCOUNTER 0x2F0
+#define BTS_STATUS 0x2F4
+#define BTS_BWMONLOW 0x2F8
+#define BTS_BWMONUP 0x2FC
+
+#define WOFFSET 0x100
+
+/* for TREX_BTS Register */
+#define TBTS_CON 0x000
+#define TBTS_TKNUPBOUND 0x010
+#define TBTS_TKNLOBOUND 0x014
+#define TBTS_LOADUP 0x020
+#define TBTS_LOADDOWN 0x024
+#define TBTS_LOADBUSY 0x028
+#define TBTS_TKNINC0 0x040
+#define TBTS_TKNINC1 0x044
+#define TBTS_TKNINC2 0x048
+#define TBTS_TKNINC3 0x04C
+#define TBTS_TKNINC4 0x050
+#define TBTS_TKNINC5 0x054
+#define TBTS_TKNINC6 0x058
+#define TBTS_TKNINC7 0x05C
+#define TBTS_DEMTH 0x070
+#define TBTS_PRMTH 0x074
+#define TBTS_DEMQOS 0x080
+#define TBTS_DEFQOS 0x084
+#define TBTS_PRMQOS 0x088
+#define TBTS_TIMEOUT 0x090
+#define TBTS_QURGUPTH 0x0D0
+#define TBTS_QURGDOWNTH 0x0D4
+#define TBTS_SELIDMASK 0x0E0
+#define TBTS_SELIDVAL 0x0E4
+#define TBTS_RCON 0x100
+#define TBTS_RTKNINIT 0x110
+#define TBTS_RTKNDEC 0x120
+#define TBTS_WCON 0x200
+#define TBTS_WTKNINIT 0x210
+#define TBTS_WTKNDEC 0x220
+#define TBTS_EMERGENTID 0x2014
+#define TBTS_MASK 0x2010
+
+void bts_setqos(addr_u32 base, unsigned int priority, unsigned int master_id);
+void bts_setqos_bw(addr_u32 base, unsigned int priority,
+ unsigned int window, unsigned int token, unsigned int master_id);
+void bts_setqos_mo(addr_u32 base, unsigned int priority, unsigned int mo, unsigned int master_id);
+void bts_setqos_fbmbw(addr_u32 base, unsigned int priority, unsigned int window,
+ unsigned int token, unsigned int fbm, unsigned int master_id);
+void bts_setemergentID(addr_u32 base, unsigned int master_id);
+void bts_disable(addr_u32 base, unsigned int master_id);
+void bts_settrexqos(addr_u32 base, unsigned int priority, unsigned int master_id, unsigned int mask);
+void bts_settrexqos_mo(addr_u32 base, unsigned int priority, unsigned int mo, unsigned int master_id, unsigned int mask);
+void bts_settrexqos_mo_rt(addr_u32 base, unsigned int priority, unsigned int mo, unsigned int master_id, unsigned int mask,
+ unsigned int time_out, unsigned int bypass_en);
+void bts_settrexqos_mo_cp(addr_u32 base, unsigned int priority, unsigned int mo, unsigned int master_id, unsigned int mask,
+ unsigned int time_out, unsigned int bypass_en);
+void bts_settrexqos_mo_change(addr_u32 base, unsigned int mo);
+void bts_settrexqos_urgent_off(addr_u32 base);
+void bts_settrexqos_urgent_on(addr_u32 base);
+void bts_settrexqos_bw(addr_u32 base, unsigned int priority, unsigned int decval, unsigned int master_id, unsigned int mask);
+void bts_settrexqos_fbmbw(addr_u32 base, unsigned int priority, unsigned int master_id, unsigned int mask);
+void bts_trexdisable(addr_u32 base, unsigned int master_id, unsigned int mask);
+void bts_setnsp(addr_u32 base, unsigned int nsp);
+
+#endif
--- /dev/null
+#ifndef __ASM_ARCH_REGS_BTS_H
+#define __ASM_ARCH_REGS_BTS_H
+
+/* EXYNOS5433 BTS SFR base address */
+#define EXYNOS5433_PA_BTS_DECONM0 0x13A80000
+#define EXYNOS5433_PA_BTS_DECONM1 0x13A90000
+#define EXYNOS5433_PA_BTS_DECONM2 0x13AA0000
+#define EXYNOS5433_PA_BTS_DECONM3 0x13AB0000
+#define EXYNOS5433_PA_BTS_DECONM4 0x13AC0000
+#define EXYNOS5433_PA_BTS_DECONTV_M0 0x13B00000
+#define EXYNOS5433_PA_BTS_DECONTV_M1 0x13B10000
+#define EXYNOS5433_PA_BTS_DECONTV_M2 0x13B20000
+#define EXYNOS5433_PA_BTS_DECONTV_M3 0x13B30000
+#define EXYNOS5433_PA_BTS_FIMC_LITE0 0x12000000
+#define EXYNOS5433_PA_BTS_FIMC_LITE1 0x12010000
+#define EXYNOS5433_PA_BTS_FIMC_LITE2 0x14500000
+#define EXYNOS5433_PA_BTS_FIMC_LITE3 0x12020000
+#define EXYNOS5433_PA_BTS_3AA0 0x12030000
+#define EXYNOS5433_PA_BTS_3AA1 0x12040000
+#define EXYNOS5433_PA_BTS_GSCL0 0x13CC0000
+#define EXYNOS5433_PA_BTS_GSCL1 0x13CD0000
+#define EXYNOS5433_PA_BTS_GSCL2 0x13CE0000
+#define EXYNOS5433_PA_BTS_MFC0 0x15220000
+#define EXYNOS5433_PA_BTS_MFC1 0x15230000
+
+#define EXYNOS5433_PA_DREX0 0x10400000
+#define EXYNOS5433_PA_DREX1 0x10440000
+
+/* EXYNOS7420 BTS SFR base address */
+#define EXYNOS7420_PA_BTS_USBDRD30 0x10EA0000
+#define EXYNOS7420_PA_BTS_MODEMX 0x10E30000
+#define EXYNOS7420_PA_BTS_SDCARDX 0x10E20000
+#define EXYNOS7420_PA_BTS_WIFI1 0x15640000
+#define EXYNOS7420_PA_BTS_EMBEDDED 0x15620000
+#define EXYNOS7420_PA_BTS_M2M1 0x15090000
+#define EXYNOS7420_PA_BTS_M2M0 0x15080000
+#define EXYNOS7420_PA_BTS_JPEG0 0x15070000
+#define EXYNOS7420_PA_BTS_G2D 0x15180000
+#define EXYNOS7420_PA_BTS_G3D0 0x14A00000
+#define EXYNOS7420_PA_BTS_G3D1 0x14A20000
+#define EXYNOS7420_PA_BTS_SLIMSSS 0x111F0000
+#define EXYNOS7420_PA_BTS_SSS 0x111E0000
+#define EXYNOS7420_PA_BTS_SMDMA 0x111D0000
+#define EXYNOS7420_PA_BTS_MCOMP 0x111A0000
+
+
+
+#define EXYNOS7420_PA_BTS_DISP_RO_0 0x13A80000
+#define EXYNOS7420_PA_BTS_DISP_RO_1 0x13A90000
+#define EXYNOS7420_PA_BTS_DISP_RW_0 0x13AA0000
+#define EXYNOS7420_PA_BTS_DISP_RW_1 0x13AB0000
+#define EXYNOS7420_PA_BTS_VPP0 0x13E60000
+#define EXYNOS7420_PA_BTS_VPP1 0x13E70000
+#define EXYNOS7420_PA_BTS_VPP2 0x13E80000
+#define EXYNOS7420_PA_BTS_VPP3 0x13E90000
+#define EXYNOS7420_PA_BTS_TREX_FIMC_BNS_A 0x14400000
+#define EXYNOS7420_PA_BTS_TREX_FIMC_BNS_B 0x14410000
+#define EXYNOS7420_PA_BTS_TREX_FIMC_BNS_C 0x14500000
+#define EXYNOS7420_PA_BTS_TREX_FIMC_BNS_D 0x14420000
+#define EXYNOS7420_PA_BTS_TREX_3AA0 0x14430000
+#define EXYNOS7420_PA_BTS_TREX_3AA1 0x14440000
+#define EXYNOS7420_PA_BTS_TREX_ISPCPU 0x14540000
+#define EXYNOS7420_PA_BTS_TREX_VRA 0x14530000
+#define EXYNOS7420_PA_BTS_TREX_SCALER 0x14520000
+#define EXYNOS7420_PA_BTS_TREX_ISP1 0x14510000
+#define EXYNOS7420_PA_BTS_TREX_TPU 0x14610000
+#define EXYNOS7420_PA_BTS_TREX_ISP0 0x14600000
+#define EXYNOS7420_PA_BTS_MFC_0 0x15220000
+#define EXYNOS7420_PA_BTS_MFC_1 0x15230000
+#define EXYNOS7420_PA_BTS_BIG 0x10530000
+#define EXYNOS7420_PA_BTS_LITTLE 0x10540000
+
+#define EXYNOS7_PA_DREX0 0x10800000
+#define EXYNOS7_PA_DREX1 0x10900000
+#define EXYNOS7_PA_DREX2 0x10A00000
+#define EXYNOS7_PA_DREX3 0x10B00000
+#define EXYNOS7_PA_NSP 0x10550000
+#define EXYNOS7_PA_SYSREG 0x10050000
+
+#define EXYNOS7_TREX_ID_MASK 0x3F
+
+/* EXYNOS7420 BTS system register offet */
+#define FSYS0_QOS_VAL0 0x1038
+
+/* EXYNOS7420 BTS SFR offset*/
+#define READ_QOS_CONTROL 0x0100
+#define READ_QOS_MODE 0x0104
+#define READ_CHANNEL_PRIORITY 0x0200
+#define READ_TOKEN_MAX_VALUE 0x0204
+#define READ_BW_UPPER_BOUNDARY 0x020C
+#define READ_BW_LOWER_BOUNDARY 0x0210
+#define READ_INITIAL_TOKEN_VALUE 0x0214
+#define READ_DEMOTION_WINDOW 0x0220
+#define READ_DEMOTION_TOKEN 0x0224
+#define READ_DEFAULT_WINDOW 0x0228
+#define READ_DEFAULT_TOKEN 0x022C
+#define READ_PROMOTION_WINDOW 0X0230
+#define READ_PROMOTION_TOKEN 0x0234
+#define READ_ISSUE_CAPABILITY_UPPER_BOUNDARY 0x0240
+#define READ_ISSUE_CAPABILITY_LOWER_BOUNDARY 0x0244
+#define READ_FLEXIBLE_BLOCKING_CONTROL 0x0280
+#define READ_FLEXIBLE_BLOCKING_POLARITY 0x0284
+#define READ_MO 0x02F0
+
+#define WRITE_QOS_CONTROL 0x0180
+#define WRITE_QOS_MODE 0x0184
+#define WRITE_CHANNEL_PRIORITY 0x0300
+#define WRITE_TOKEN_MAX_VALUE 0x0304
+#define WRITE_BW_UPPER_BOUNDARY 0x030C
+#define WRITE_BW_LOWER_BOUNDARY 0x0310
+#define WRITE_INITIAL_TOKEN_VALUE 0x0314
+#define WRITE_DEMOTION_WINDOW 0x0320
+#define WRITE_DEMOTION_TOKEN 0x0324
+#define WRITE_DEFAULT_WINDOW 0x0328
+#define WRITE_DEFAULT_TOKEN 0x032C
+#define WRITE_PROMOTION_WINDOW 0X0330
+#define WRITE_PROMOTION_TOKEN 0x0334
+#define WRITE_ISSUE_CAPABILITY_UPPER_BOUNDARY 0x0340
+#define WRITE_ISSUE_CAPABILITY_LOWER_BOUNDARY 0x0344
+#define WRITE_FLEXIBLE_BLOCKING_CONTROL 0x0380
+#define WRITE_FLEXIBLE_BLOCKING_POLARITY 0x0384
+#define WRITE_MO 0x03F0
+
+#define FBM_MODESEL0 0x00
+#define FBM_MODESEL1 0x04
+#define FBM_MODESEL2 0x08
+#define FBM_THRESHOLD0 0x40
+#define FBM_THRESHOLD1 0x44
+#define FBM_THRESHOLD2 0x48
+#define FBM_OUTSEL0 0x80
+#define FBM_OUTSEL2 0x88
+#define FBM_OUTSEL20 0xD0
+
+#define TREX_QOS_CONTROL 0x0000
+#define TREX_DEMOTION_QOS_VALUE 0x0080
+#define TREX_DEFAULT_QOS_VALUE 0x0084
+#define TREX_PROMOTION_QOS_VALUE 0x0088
+#define TREX_QOS_THRESHOLD_FOR_EMERGENCY_RISING 0x00D0
+#define TREX_QOS_THRESHOLD_FOR_EMERGENCY_FALLING 0x00D4
+
+#define QOS_TIMEOUT_0x8 0xA0
+#define QOS_TIMEOUT_0xA 0xB0
+#define QOS_TIMEOUT_0xB 0xB8
+#define QOS_TIMEOUT_0xC 0xC0
+#define QOS_TIMEOUT_0xD 0xC8
+#define QOS_TIMEOUT_0xE 0xD0
+#define QOS_TIMEOUT_0xF 0xD8
+#define QOS_TIMEOUT_0x5 0x88
+#define QOS_TIMEOUT_0x4 0x80
+#define BRB_CON 0x100
+#define BRB_THRESHOLD 0x104
+#define NSP_CH0 0x0008
+#define NSP_CH1 0x0408
+#define NSP_CH2 0x0808
+#define NSP_CH3 0x0C08
+
+#define SYSREG_FSYS0 0x1064
+#define SYSREG_FSYS1 0x2664
+#define SYSREG_APM_R 0x1438
+#define SYSREG_APM_W 0x143C
+#define SYSREG_RTIC 0x1440
+#define SYSREG_PDMA_SECURE_R 0x144C
+#define SYSREG_PDMA_SECURE_W 0x1450
+#define SYSREG_AUD 0x0248
+
+/* Exynos8890 BTS */
+#define EXYNOS8890_PA_BTS_TREX_DISP0_0 0x11F30000
+#define EXYNOS8890_PA_BTS_TREX_DISP0_1 0x11F40000
+#define EXYNOS8890_PA_BTS_TREX_DISP1_0 0x11F50000
+#define EXYNOS8890_PA_BTS_TREX_DISP1_1 0x11F60000
+#define EXYNOS8890_PA_BTS_TREX_ISP0 0x11F20000
+#define EXYNOS8890_PA_BTS_TREX_CAM0 0x11F70000
+#define EXYNOS8890_PA_BTS_TREX_CAM1 0x11F10000
+#define EXYNOS8890_PA_BTS_TREX_CP 0x10730000
+#define EXYNOS8890_PA_BTS_TREX_MFC0 0x11D30000
+#define EXYNOS8890_PA_BTS_TREX_MFC1 0x11D40000
+#define EXYNOS8890_PA_BTS_TREX_G3D0 0x10680000
+#define EXYNOS8890_PA_BTS_TREX_G3D1 0x10690000
+#define EXYNOS8890_PA_BTS_TREX_FSYS0 0x11D00000
+#define EXYNOS8890_PA_BTS_TREX_FSYS1 0x11F00000
+#define EXYNOS8890_PA_BTS_TREX_MSCL0 0x11D10000
+#define EXYNOS8890_PA_BTS_TREX_MSCL1 0x11D20000
+
+#define EXYNOS8_PA_SYSREG 0x10050000
+
+#define EXYNOS8_PA_TREX_CCORE0 0x10704000
+#define EXYNOS8_PA_TREX_CCORE1 0x10714000
+
+#define EXYNOS8_PA_SCI 0x10500000
+#define CMDTOKEN 0x00EC
+
+#define SCI_CTRL 0x0000
+#define READ_QURGENT 0x0010
+#define WRITE_QURGENT 0x0030
+#define VC_NUM0 0x0050
+#define VC_NUM1 0x0054
+#define TH_IMM0 0x0100
+#define TH_IMM1 0x0104
+#define TH_IMM2 0x0108
+#define TH_IMM3 0x010C
+#define TH_IMM4 0x0110
+#define TH_IMM5 0x0114
+#define TH_IMM6 0x0118
+#define TH_HIGH0 0x0200
+#define TH_HIGH1 0x0204
+#define TH_HIGH2 0x0208
+#define TH_HIGH3 0x020C
+#define TH_HIGH4 0x0210
+#define TH_HIGH5 0x0214
+#define TH_HIGH6 0x0218
+
+#endif /* __ASM_ARCH_REGS_BTS_H */