blob: 22de7afedf9c887d2be3e336127c43a76504c154 [file] [log] [blame]
/* Copyright Statement:
*
* This software/firmware and related documentation ("MediaTek Software") are
* protected under relevant copyright laws. The information contained herein
* is confidential and proprietary to MediaTek Inc. and/or its licensors.
* Without the prior written permission of MediaTek inc. and/or its licensors,
* any reproduction, modification, use or disclosure of MediaTek Software,
* and information contained herein, in whole or in part, shall be strictly prohibited.
*/
/* MediaTek Inc. (C) 2012. All rights reserved.
*
* BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
* THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
* CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
* SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
* STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
* CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
* The following software/firmware and/or related documentation ("MediaTek Software")
* have been modified by MediaTek Inc. All revisions are subject to any receiver's
* applicable license agreements with MediaTek Inc.
*/
#include <linux/io.h>
#include <asm/cacheflush.h>
#include <asm/uaccess.h>
/* #include <asm/system.h> */
#include "mtk_dramc.h"
//#include "x_hal_io.h"
/* #define DRAMC_DEBUG */
#ifndef DRAMC_DEBUG
#define DRAMC_LOG(fmt, ...)
#else
#define DRAMC_LOG(fmt, arg...) printk("%s:%d:"fmt, __FILE__, __LINE__,##arg);
#endif
/* #define TEST_AGENT */
#if 1
struct dramc_desc_t dramc_desc[DRAMC_MX_CHANNUM][DRAMC_MX_GRPNUM][DRAMC_MX_NUM_IN_AGRP] = DRAMC_AGENT_TABLE;
#else
struct dramc_desc_t dramc_desc[DRAMC_MX_CHANNUM][DRAMC_MX_GRPNUM][DRAMC_MX_NUM_IN_AGRP] =
{
/* /////////////////////////////////////////////////////////
define channel A releationship between group and name
///////////////////////////////////////////////////////// */
{
{
/* GRP 1 */
{0, "00_audio"},
{1, "01_demux/gcpu/ddi"},
{2, "02_vbi/3d/tve/dolby"},
{3, "03_xpscaler_ip/tddc"},
{4, "04_mib"},
{5, "05_b2r"},
{6, "06_cpu"},
{7, "07_scpos"},
{8, "08_vdec_vld"},
{9, "09_audio_dsp1"},
{10, "10_3d_gpu"},
{11, "11_2d_graph/jpgdec/osd/gfx_imgrsz/2d_graph_cmd/irt_dma/png"},
{12, "12_ethernet/demod_isdbt/ci_spi/rs232/usb2/usb3/usb3_d"},
{13, "13_osd"},
{14, "14_venc/vp8_encoder"},
{15, "15_test0/audio_dsp0"},
{-1, ""}
},
{
/* GRP 2 */
{16, "16_vdec_lat"},
{17, "17_mmu"},
{18, "18_memc"},
{19, "19_video_imgrsz0/video_imgrsz2"},
{20, "20_arm11"},
{21, "21_msdc/emmc/gdma"},
{22, "22_vdec_mc"},
{30, "30_agent_30"},
{-1, ""}
},
{
/* GRP 3 */
{23, "23_cpu_bim_read"},
{24, "24_demux/gcpu/ddi "},
{25, "25_nfi_dma/sfalsh_dma/lzhs/ci_spi"},
{26, "26_rs232"},
{27, "27_agent_27"},
{28, "28_agent_28"},
{29, "29_agent_29"},
{31, "31_agent_31"},
{-1, ""}
}
},
/* ///////////////////////////////////////////////////////////
define channel B releationship between group and name
///////////////////////////////////////////////////////// */
{
{
/* GRP 1 */
{0, "00_audio"},
{1, "01_demux/gcpu/ddi"},
{2, "02_vbi/3d/tve/dolby"},
{3, "03_xpscaler_ip/tddc"},
{4, "04_mib"},
{5, "05_b2r"},
{6, "06_cpu"},
{7, "07_scpos"},
{8, "08_vdec_vld"},
{9, "09_audio_dsp1"},
{10, "10_3d_gpu"},
{11, "11_2d_graph/jpgdec/osd/gfx_imgrsz/2d_graph_cmd/irt_dma/png"},
{12, "12_ethernet/demod_isdbt/ci_spi/rs232/usb2/usb3/usb3_d"},
{13, "13_osd"},
{14, "14_venc/vp8_encoder"},
{15, "15_test0/audio_dsp0"},
{-1, ""}
},
{
/* GRP 2 */
{16, "16_vdec_lat"},
{17, "17_mmu"},
{18, "18_memc"},
{19, "19_video_imgrsz0/video_imgrsz2"},
{20, "20_arm11"},
{21, "21_msdc/emmc/gdma"},
{22, "22_vdec_mc"},
{30, "30_agent_30"},
{-1, ""}
},
{
/* GRP 3 */
{23, "23_cpu_bim_read"},
{24, "24_demux/gcpu/ddi "},
{25, "25_nfi_dma/sfalsh_dma/lzhs/ci_spi"},
{26, "26_rs232"},
{27, "27_agent_27"},
{28, "28_agent_28"},
{29, "29_agent_29"},
{31, "31_agent_31"},
{-1, ""}
}
},
/* ///////////////////////////////////////////////////////////
define channel C releationship between group and name
/////////////////////////////////////////////////////////// */
{
{
/* GRP 1 */
{0, "00_audio"},
{1, "01_demux/gcpu/ddi"},
{2, "02_vbi/3d/tve/dolby"},
{3, "03_xpscaler_ip/tddc"},
{4, "04_mib"},
{5, "05_b2r"},
{6, "06_cpu"},
{7, "07_scpos"},
{8, "08_vdec_vld"},
{9, "09_audio_dsp1"},
{10, "10_3d_gpu"},
{11, "11_2d_graph/jpgdec/osd/gfx_imgrsz/2d_graph_cmd/irt_dma/png"},
{12, "12_ethernet/demod_isdbt/ci_spi/rs232/usb2/usb3/usb3_d"},
{13, "13_osd"},
{14, "14_venc/vp8_encoder"},
{15, "15_test0/audio_dsp0"},
{-1, ""}
},
{
/* GRP 2 */
{16, "16_vdec_lat"},
{17, "17_mmu"},
{18, "18_memc"},
{19, "19_video_imgrsz0/video_imgrsz2"},
{20, "20_arm11"},
{21, "21_msdc/emmc/gdma"},
{22, "22_vdec_mc"},
{30, "30_agent_30"},
{-1, ""}
},
{
/* GRP 3 */
{23, "23_cpu_bim_read"},
{24, "24_demux/gcpu/ddi "},
{25, "25_nfi_dma/sfalsh_dma/lzhs/ci_spi"},
{26, "26_rs232"},
{27, "27_agent_27"},
{28, "28_agent_28"},
{29, "29_agent_29"},
{31, "31_agent_31"},
{-1, ""}
}
}
};
#endif
static unsigned long dramc_base[DRAMC_MX_CHANNUM] =
{
MET_DRAMC0_BASE,
};
/*
force to 32 bit means current is 16 bit
not force to 32 bit means current is 32 bit
*/
static unsigned long dramc_ext32_off[DRAMC_MX_CHANNUM] =
{
DRAM_CHA_FORCE32,
};
static inline unsigned int dramc_reg_read(unsigned long addr)
{
#if 0
#ifdef CONFIG_64BIT
unsigned int value = 0;
value = HAL_READ32((void*)addr);
#else
unsigned int value = readl((void*)addr);
#endif
#endif
unsigned int value = readl((void*)addr);
mb();
return value;
}
static inline void dramc_reg_write(unsigned long addr, unsigned int value)
{
#if 0
/* make sure writel() be completed before outer_sync() */
#ifdef CONFIG_64BIT
HAL_WRITE32((void*)addr, value);
#else
writel(value, (void*)addr);
#endif
#endif
writel(value, (void*)addr);
mb();
}
#define DRAMC_SET_VALUE(target, value, shift, bit) \
do { \
volatile u32 temp = dramc_reg_read(target); \
u32 mask1 = (~(((0xFFFFFFFF >> (32 - bit))<< shift))); \
u32 mask2 = ((0xFFFFFFFF >> (32 - bit))<< shift); \
dramc_reg_write(target,(temp & mask1) | ((value << shift) & mask2)); \
} while (0)
void DRAMC_Init(int chan)
{
unsigned long base = dramc_base[chan];
volatile u32 temp_reg = 0;
DRAMC_LOG("%s chann: %d ext_32_value: %x ext_32bit: %d\n", __FUNCTION__, chan, dramc_ext32_off[chan], DRMAC_IS_FORCE32(dramc_ext32_off[chan]));
/* determine the number of dram for the corresponding dramc */
DRAMC_SET_VALUE(DRAMC_MON_BM(base), DRMAC_IS_FORCE32(dramc_ext32_off[chan]), DRAMC_BM_DMBW32B_SHIFT, 1);
/* disable all group */
DRAMC_SET_VALUE(DRAMC_MON_BM(base), 0, DRAMC_BM_GROUP1_ENABLE_SHIFT, 1);
DRAMC_SET_VALUE(DRAMC_MON_BM(base), 0, DRAMC_BM_GROUP2_ENABLE_SHIFT, 1);
DRAMC_SET_VALUE(DRAMC_MON_BM(base), 0, DRAMC_BM_GROUP3_ENABLE_SHIFT, 1);
DRAMC_SET_VALUE(DRAMC_MON_BM(base), 0, DRAMC_BM_FREEZE_SHIFT, 1);
temp_reg = dramc_reg_read(DRAMC_MON_BM(base));
DRAMC_LOG("%s MON_BM: %X\n", __FUNCTION__, temp_reg);
#ifdef TEST_AGENT
u32 reg;
reg = base + 0;
dramc_reg_write(reg, 0xC050EF00);
reg = base + 0x100;
if (0 == chan)
dramc_reg_write(reg, 0x3C553000);
else if (1 == chan)
dramc_reg_write(reg, 0x5FFD0000);
else if (2 == chan)
dramc_reg_write(reg, 0x85D20000);
reg = base + 0x104;
dramc_reg_write(reg, 0x8000);
reg = base + 0x118;
dramc_reg_write(reg, 0x0600110D);
dramc_reg_write(reg, 0x1600110D);
reg = base + 0x160;
temp_reg = dramc_reg_read(reg);
#endif
}
void DRAMC_MaxLtcyMode(int chan, int enable)
{
unsigned long base = dramc_base[chan];
if (1 == enable) {
DRAMC_SET_VALUE(DRAMC_MON_BM(base), 0, DRAMC_BM_PACNTEN, 1);
DRAMC_SET_VALUE(DRAMC_MON_BM(base), 1, DRAMC_BM_REQCNTEN, 1);
} else {
DRAMC_SET_VALUE(DRAMC_MON_BM(base), 0, DRAMC_BM_PACNTEN, 1);
DRAMC_SET_VALUE(DRAMC_MON_BM(base), 0, DRAMC_BM_REQCNTEN, 1);
}
}
void DRAMC_Enable(int chan, int group, int agent)
{
unsigned long base = dramc_base[chan];
volatile u32 temp_reg = 0;
/* disable all group */
switch (group) {
case 1:
DRAMC_SET_VALUE(DRAMC_MON_BM(base), agent, DRAMC_BM_GROUP1_AGENT_ID_SHIFT, DRAMC_BM_GROUP1_AGENT_ID_LEN);
DRAMC_SET_VALUE(DRAMC_MON_BM(base), 1, DRAMC_BM_GROUP1_ENABLE_SHIFT, 1);
break;
case 2:
DRAMC_SET_VALUE(DRAMC_MON_BM(base), agent, DRAMC_BM_GROUP2_AGENT_ID_SHIFT, DRAMC_BM_GROUP2_AGENT_ID_LEN);
DRAMC_SET_VALUE(DRAMC_MON_BM(base), 1, DRAMC_BM_GROUP2_ENABLE_SHIFT, 1);
break;
case 3:
DRAMC_SET_VALUE(DRAMC_MON_BM(base), agent, DRAMC_BM_GROUP3_AGENT_ID_SHIFT, DRAMC_BM_GROUP3_AGENT_ID_LEN);
DRAMC_SET_VALUE(DRAMC_MON_BM(base), 1, DRAMC_BM_GROUP3_ENABLE_SHIFT, 1);
break;
}
temp_reg = dramc_reg_read(DRAMC_MON_BM(base));
DRAMC_LOG("%s MON_BM: %X\n", __FUNCTION__, temp_reg);
}
void DRAMC_Disable(int chan)
{
unsigned long base = dramc_base[chan];
volatile u32 temp_reg = 0;
/* disable all group */
DRAMC_SET_VALUE(DRAMC_MON_BM(base), 0, DRAMC_BM_GROUP1_ENABLE_SHIFT, 1);
DRAMC_SET_VALUE(DRAMC_MON_BM(base), 0, DRAMC_BM_GROUP2_ENABLE_SHIFT, 1);
DRAMC_SET_VALUE(DRAMC_MON_BM(base), 0, DRAMC_BM_GROUP3_ENABLE_SHIFT, 1);
/* fire the BM function */
DRAMC_SET_VALUE(DRAMC_MON_BM(base), 0, DRAMC_BM_FREEZE_SHIFT, 1);
temp_reg = dramc_reg_read(DRAMC_MON_BM(base));
DRAMC_LOG("%s MON_BM: %X\n", __FUNCTION__, temp_reg);
}
void DRAMC_Freeze(int chan)
{
unsigned long base = dramc_base[chan];
volatile u32 temp_reg = dramc_reg_read(DRAMC_MON_BM(base));
/* Freeze the BM function */
DRAMC_SET_VALUE(DRAMC_MON_BM(base), 1, DRAMC_BM_FREEZE_SHIFT, 1);
temp_reg = dramc_reg_read(DRAMC_MON_BM(base));
DRAMC_LOG("%s MON_BM: %X\n", __FUNCTION__, temp_reg);
}
void DRAMC_ConfigTargetCount(int chan, u32 count)
{
unsigned long base = dramc_base[chan];
volatile u32 temp_reg = 0;
dramc_reg_write(DRAMC_MON_BMCYC(base), 0xFFFFFFFF);
temp_reg = dramc_reg_read(DRAMC_MON_BMCYC(base));
DRAMC_LOG("%s MON_BMCYC: %X\n", __FUNCTION__, temp_reg);
return;
}
u32 DRAMC_GetMaxLtcy(int chan)
{
unsigned long base = dramc_base[chan];
return dramc_reg_read(DRAMC_MON_ROBM4(base));
}
u32 DRAMC_GetDramcFreq(void)
{
unsigned long tcm_dramc_flags = 0;
tcm_dramc_flags = dramc_reg_read(TCM_DRAM_FLAGS_ADDR);
return TCMGET_DDR_CLK(tcm_dramc_flags);
}
u32 DRAMC_GetCycleCount(int chan, int group)
{
unsigned long base = dramc_base[chan];
switch (group) {
case 1:
return dramc_reg_read(DRAMC_MON_ROBM0(base));
case 2:
return dramc_reg_read(DRAMC_MON_ROBM1(base));
case 3:
return dramc_reg_read(DRAMC_MON_ROBM2(base));
}
return 0;
}
u32 DRAMC_GetTotalCycleCount(int chan)
{
unsigned long base = dramc_base[chan];
return dramc_reg_read(DRAMC_MON_ROBM3(base));
}
int DRAMC_CheckCntIsOverFlow(u32 count)
{
if (0xFFFFFFFF == count) {
return 1;
}
return 0;
}
void DRAMC_WriteMode(int chan, int enable)
{
unsigned long base = dramc_base[chan];
if (1 == enable) {
DRAMC_SET_VALUE(DRAMC_MON_BM(base), 1, DRAMC_BM_WREN_SHIFT, 1);
} else {
DRAMC_SET_VALUE(DRAMC_MON_BM(base), 0, DRAMC_BM_WREN_SHIFT, 1);
}
}
void DRAMC_ReadMode(int chan, int enable)
{
unsigned long base = dramc_base[chan];
if (1 == enable) {
DRAMC_SET_VALUE(DRAMC_MON_BM(base), 1, DRAMC_BM_RDEN_SHIFT, 1);
} else {
DRAMC_SET_VALUE(DRAMC_MON_BM(base), 0, DRAMC_BM_RDEN_SHIFT, 1);
}
}
unsigned int DRAMC_GetEfuseValue(void)
{
volatile u32 efuse_reg = 0;
efuse_reg = dramc_reg_read(DRAMC_EFUSE_BIT_ADDRESS);
return (efuse_reg & DRAMC_EFUSE_BIT_MASK);
}
void DRAMC_GetGroup1AgentCounter(int channel, unsigned int* counter)
{
unsigned long base = dramc_base[channel];
unsigned long agent_base = 0;
int i = 0;
agent_base = DRAMC_MON_AGENT_BASE(base);
for (i=0; i<DRAMC_MON_AGENT_NUM; i++) {
counter[i] = dramc_reg_read(agent_base + i*sizeof(int));
}
smp_rmb();
return ;
}
void DRAMC_GetGroup1Latency(int channel, unsigned int* latency)
{
unsigned long base = dramc_base[channel];
unsigned long lty_base = 0;
int i = 0;
lty_base = DRAMC_MON_LTY_AGENT_BASE(base);
for (i=0; i<DRAMC_MON_LTY_AGENT_NUM; i++) {
latency[i] = dramc_reg_read(lty_base + i*sizeof(int));
}
smp_rmb();
return ;
}
void DRAMC_GetGroup1MaxLatency(int channel, unsigned int* max_ltcy)
{
unsigned long base = dramc_base[channel];
unsigned long max_lty_base = 0;
unsigned int value = 0;
int i = 0;
/* max latency counter is 16 bit*/
max_lty_base = DRAMC_MON_MAX_LTY_AGENT_BASE(base);
for (i=0; i<DRAMC_MON_LTY_AGENT_NUM/sizeof(short); i++) {
value = dramc_reg_read(max_lty_base + i*sizeof(int));
max_ltcy[2*i] = value & 0x0000FFFF;
max_ltcy[2*i+1] = (value & 0xFFFF0000) >> 16;
}
smp_rmb();
return ;
}