From: Seokju Yoon Date: Tue, 3 May 2016 10:30:06 +0000 (+0900) Subject: bts: initialize bts driver for kernel 4.4 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=2db83573c9baf3518a89e4dc575449571170f9a1;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git bts: initialize bts driver for kernel 4.4 Change-Id: I7400da709f6b73d899f9379e45f3c9aacc14988b Signed-off-by: Seokju Yoon --- diff --git a/drivers/Kconfig b/drivers/Kconfig index 1d7af3c2ff27..f37c3bd57988 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -209,4 +209,5 @@ source "drivers/tee/Kconfig" source "drivers/mux/Kconfig" +source "drivers/bts/Kconfig" endmenu diff --git a/drivers/Makefile b/drivers/Makefile index 5f5ccdbad21a..7a89cd30e6ef 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -183,3 +183,5 @@ obj-$(CONFIG_FPGA) += fpga/ obj-$(CONFIG_FSI) += fsi/ obj-$(CONFIG_TEE) += tee/ obj-$(CONFIG_MULTIPLEXER) += mux/ + +obj-$(CONFIG_EXYNOS_BTS) += bts/ diff --git a/drivers/bts/Kconfig b/drivers/bts/Kconfig new file mode 100644 index 000000000000..5b4c3b095f63 --- /dev/null +++ b/drivers/bts/Kconfig @@ -0,0 +1,26 @@ +# +# 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 diff --git a/drivers/bts/Makefile b/drivers/bts/Makefile new file mode 100644 index 000000000000..028ec267b154 --- /dev/null +++ b/drivers/bts/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for BTS. +# + +obj-$(CONFIG_EXYNOS8890_BTS) += cal_bts8890.o bts-exynos8890.o diff --git a/drivers/bts/bts-exynos8890.c b/drivers/bts/bts-exynos8890.c new file mode 100644 index 000000000000..33c86b87630d --- /dev/null +++ b/drivers/bts/bts-exynos8890.c @@ -0,0 +1,1408 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#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); diff --git a/drivers/bts/cal_bts.c b/drivers/bts/cal_bts.c new file mode 100644 index 000000000000..fba7fbd41acf --- /dev/null +++ b/drivers/bts/cal_bts.c @@ -0,0 +1,332 @@ +/* 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); +} diff --git a/drivers/bts/cal_bts.h b/drivers/bts/cal_bts.h new file mode 100644 index 000000000000..8205444e55a0 --- /dev/null +++ b/drivers/bts/cal_bts.h @@ -0,0 +1,125 @@ +/* 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 + +#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 diff --git a/drivers/bts/cal_bts8890.c b/drivers/bts/cal_bts8890.c new file mode 100644 index 000000000000..3f1569fde798 --- /dev/null +++ b/drivers/bts/cal_bts8890.c @@ -0,0 +1,409 @@ +/* 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); +} diff --git a/drivers/bts/cal_bts8890.h b/drivers/bts/cal_bts8890.h new file mode 100644 index 000000000000..1dc637b9b4c6 --- /dev/null +++ b/drivers/bts/cal_bts8890.h @@ -0,0 +1,131 @@ +/* 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 + +#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 diff --git a/drivers/bts/regs-bts.h b/drivers/bts/regs-bts.h new file mode 100644 index 000000000000..f500da6e3a5f --- /dev/null +++ b/drivers/bts/regs-bts.h @@ -0,0 +1,212 @@ +#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 */