mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-23 09:42:19 +03:00
Using this patch we are adding support for mttcan driver in oot kernel. JIRA ESLC-6885 Signed-off-by: Manish Bhardwaj <mbhardwaj@nvidia.com> Change-Id: I83a6d43aa99278a546778cf1700e2bd106ec42a9 Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2785360 Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
202 lines
5.1 KiB
C
202 lines
5.1 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
*/
|
|
|
|
#include "../include/m_ttcan.h"
|
|
|
|
/* TT Reference Message Config */
|
|
#define TTRMC_REF_PAYLOAD (0x1 << 31)
|
|
#define TTRMC_EXT_ID (0x1 << 30)
|
|
#define TTRMC_STD_ID_SHIFT 0x12
|
|
|
|
/* TT Operation Config */
|
|
|
|
#define TTOCF_MODE_0 0x3
|
|
#define TTOCF_MODE_1 0x2
|
|
#define TTCOF_MODE_2 0x1
|
|
#define TTOCF_EVT_TRIG 0x0
|
|
|
|
#define TTOCF_GAP 0x4
|
|
#define TTOCF_POTENTIAL_TM 0x8
|
|
#define TTOCF_LDSDL_SHIFT 0x5
|
|
#define TTOCF_IRTO_SHIFT 0x8
|
|
|
|
#define TTOCF_EXT_CLK_SYNC 0x8000
|
|
#define TTOCF_AWL_SHIFT 0x10
|
|
#define TTOCF_GBL_TIME_FLT (0x1 << 24)
|
|
#define TTOCF_CLK_CALIB (0x1 << 25)
|
|
#define TTOCF_EVT_POLARITY (0x1 << 26)
|
|
|
|
enum time_master_info {
|
|
TM_MASTER = 0,
|
|
TM_POTENTIAL,
|
|
TM_SLAVE,
|
|
};
|
|
|
|
inline void ttcan_clean_tt_intr(struct ttcan_controller *ttcan)
|
|
{
|
|
ttcan_write32(ttcan, ADR_MTTCAN_TTIR, 0xFFFFFFFF);
|
|
}
|
|
|
|
void ttcan_set_ref_mesg(struct ttcan_controller *ttcan,
|
|
u32 id, u32 rmps, u32 xtd)
|
|
{
|
|
u32 rid;
|
|
u32 ttrmc = (xtd << MTT_TTRMC_XTD_SHIFT) &
|
|
MTT_TTRMC_XTD_MASK;
|
|
ttrmc |= (rmps << MTT_TTRMC_RMPS_SHIFT) &
|
|
MTT_TTRMC_RMPS_MASK;
|
|
if (xtd)
|
|
rid = (id & 0x1FFFFFFF);
|
|
else
|
|
rid = ((id & 0x7FF) << TTRMC_STD_ID_SHIFT);
|
|
ttrmc |= (rid << MTT_TTRMC_RID_SHIFT) & MTT_TTRMC_RID_MASK;
|
|
|
|
ttcan_write32(ttcan, ADR_MTTCAN_TTRMC, ttrmc);
|
|
}
|
|
|
|
void ttcan_set_tt_config(struct ttcan_controller *ttcan, u32 evtp,
|
|
u32 ecc, u32 egtf, u32 awl, u32 eecs,
|
|
u32 irto, u32 ldsdl, u32 tm, u32 gen, u32 om)
|
|
{
|
|
u32 ttocf = 0;
|
|
|
|
ttocf = (evtp << MTT_TTOCF_EVTP_SHIFT) & MTT_TTOCF_EVTP_MASK;
|
|
ttocf |= (ecc << MTT_TTOCF_ECC_SHIFT) & MTT_TTOCF_ECC_MASK;
|
|
ttocf |= (egtf << MTT_TTOCF_EGTF_SHIFT) & MTT_TTOCF_EGTF_MASK;
|
|
ttocf |= (awl << MTT_TTOCF_AWL_SHIFT) & MTT_TTOCF_AWL_MASK;
|
|
ttocf |= (eecs << MTT_TTOCF_EECS_SHIFT) & MTT_TTOCF_EECS_MASK;
|
|
ttocf |= (irto << MTT_TTOCF_IRTO_SHIFT) & MTT_TTOCF_IRTO_MASK;
|
|
ttocf |= (ldsdl << MTT_TTOCF_LDSDL_SHIFT) &
|
|
MTT_TTOCF_LDSDL_MASK;
|
|
ttocf |= (tm << MTT_TTOCF_TM_SHIFT) & MTT_TTOCF_TM_MASK;
|
|
ttocf |= (gen << MTT_TTOCF_GEN_SHIFT) & MTT_TTOCF_GEN_MASK;
|
|
ttocf |= (om << MTT_TTOCF_OM_SHIFT) & MTT_TTOCF_OM_MASK;
|
|
|
|
ttcan_write32(ttcan, ADR_MTTCAN_TTOCF, ttocf);
|
|
}
|
|
|
|
inline u32 ttcan_get_ttocf(struct ttcan_controller *ttcan)
|
|
{
|
|
return ttcan_read32(ttcan, ADR_MTTCAN_TTOCF);
|
|
}
|
|
|
|
inline void ttcan_set_tttmc(struct ttcan_controller *ttcan, u32 value)
|
|
{
|
|
ttcan_write32(ttcan, ADR_MTTCAN_TTTMC, value);
|
|
}
|
|
|
|
inline u32 ttcan_get_tttmc(struct ttcan_controller *ttcan)
|
|
{
|
|
return ttcan_read32(ttcan, ADR_MTTCAN_TTTMC);
|
|
}
|
|
|
|
inline void ttcan_set_txbar(struct ttcan_controller *ttcan, u32 value)
|
|
{
|
|
ttcan_write32(ttcan, ADR_MTTCAN_TXBAR, value);
|
|
}
|
|
|
|
inline u32 ttcan_get_ttmlm(struct ttcan_controller *ttcan)
|
|
{
|
|
return ttcan_read32(ttcan, ADR_MTTCAN_TTMLM);
|
|
}
|
|
|
|
inline u32 ttcan_get_cccr(struct ttcan_controller *ttcan)
|
|
{
|
|
return ttcan_read32(ttcan, ADR_MTTCAN_CCCR);
|
|
}
|
|
|
|
inline u32 ttcan_get_ttost(struct ttcan_controller *ttcan)
|
|
{
|
|
return ttcan_read32(ttcan, ADR_MTTCAN_TTOST);
|
|
}
|
|
|
|
static bool validate_matrix_cyc_cnt(u32 cyc_num)
|
|
{
|
|
if (cyc_num && ((cyc_num + 1) & cyc_num))
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
int ttcan_set_matrix_limits(struct ttcan_controller *ttcan,
|
|
u32 entt, u32 txew, u32 css, u32 ccm)
|
|
{
|
|
u32 ttmlm = 0;
|
|
|
|
if (!validate_matrix_cyc_cnt(ccm) ||
|
|
(txew > 15) || (css > 2) || (entt > 4095)) {
|
|
pr_err("%s: Invalid parameters\n", __func__);
|
|
return -1;
|
|
}
|
|
ttmlm = (entt << MTT_TTMLM_ENTT_SHIFT) & MTT_TTMLM_ENTT_MASK;
|
|
ttmlm |= (txew << MTT_TTMLM_TXEW_SHIFT) & MTT_TTMLM_TXEW_MASK;
|
|
ttmlm |= (css << MTT_TTMLM_CSS_SHIFT) & MTT_TTMLM_CSS_MASK;
|
|
ttmlm |= (ccm << MTT_TTMLM_CCM_SHIFT) & MTT_TTMLM_CCM_MASK;
|
|
|
|
ttcan_write32(ttcan, ADR_MTTCAN_TTMLM, ttmlm);
|
|
|
|
return 0;
|
|
}
|
|
|
|
#define MTTCAN_TT_TIMEOUT 1000
|
|
int ttcan_set_tur_config(struct ttcan_controller *ttcan, u16 denominator,
|
|
u16 numerator, int local_timing_enable)
|
|
{
|
|
int timeout = MTTCAN_TT_TIMEOUT;
|
|
u32 turcf = ttcan_read32(ttcan, ADR_MTTCAN_TURCF);
|
|
|
|
if (!denominator && local_timing_enable) {
|
|
pr_err("%s: Invalid Denominator value\n", __func__);
|
|
return -1;
|
|
}
|
|
|
|
if (turcf & MTT_TURCF_ELT_MASK) {
|
|
turcf &= ~(MTT_TURCF_ELT_MASK);
|
|
ttcan_write32(ttcan, ADR_MTTCAN_TURCF, turcf);
|
|
}
|
|
|
|
if (!local_timing_enable)
|
|
return 0;
|
|
|
|
if (turcf & MTT_TURCF_ELT_MASK) {
|
|
while ((turcf & MTT_TURCF_ELT_MASK) && timeout) {
|
|
udelay(1);
|
|
timeout--;
|
|
turcf = ttcan_read32(ttcan, ADR_MTTCAN_TURCF);
|
|
}
|
|
if (!timeout) {
|
|
pr_err("%s: TURCF access is locked\n", __func__);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/* TBD: Take care when the DEN or NUM is programmed
|
|
* outside TT Conf mode
|
|
*/
|
|
|
|
turcf = (numerator << MTT_TURCF_NCL_SHIFT) & MTT_TURCF_NCL_MASK;
|
|
turcf |= (denominator << MTT_TURCF_DC_SHIFT) & MTT_TURCF_DC_MASK;
|
|
turcf |= MTT_TURCF_ELT_MASK;
|
|
|
|
ttcan_write32(ttcan, ADR_MTTCAN_TURCF, turcf);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void ttcan_set_trigger_mem_conf(struct ttcan_controller *ttcan)
|
|
{
|
|
u32 tttmc = 0;
|
|
u32 rel_start_addr = ttcan->mram_cfg[MRAM_TMC].off >> 2;
|
|
u8 elem_num = ttcan->mram_cfg[MRAM_TMC].num;
|
|
|
|
if (elem_num > 64)
|
|
elem_num = 64;
|
|
|
|
tttmc = (elem_num << MTT_TTTMC_TME_SHIFT) & MTT_TTTMC_TME_MASK;
|
|
tttmc |= (rel_start_addr << MTT_TTTMC_TMSA_SHIFT) &
|
|
MTT_TTTMC_TMSA_MASK;
|
|
|
|
ttcan_write32(ttcan, ADR_MTTCAN_TTTMC, tttmc);
|
|
}
|