From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754027AbbJaNUv (ORCPT ); Sat, 31 Oct 2015 09:20:51 -0400 Received: from mail-db3on0060.outbound.protection.outlook.com ([157.55.234.60]:59984 "EHLO emea01-db3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751501AbbJaNUo (ORCPT ); Sat, 31 Oct 2015 09:20:44 -0400 Authentication-Results: spf=fail (sender IP is 212.179.42.66) smtp.mailfrom=ezchip.com; vger.kernel.org; dkim=none (message not signed) header.d=none;vger.kernel.org; dmarc=none action=none header.from=ezchip.com; From: Noam Camus To: CC: , , , , Noam Camus Subject: [PATCH v1 11/20] ARC: [plat-eznps] Add eznps platform Date: Sat, 31 Oct 2015 15:15:18 +0200 Message-ID: <1446297327-16298-12-git-send-email-noamc@ezchip.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1446297327-16298-1-git-send-email-noamc@ezchip.com> References: <1446297327-16298-1-git-send-email-noamc@ezchip.com> MIME-Version: 1.0 Content-Type: text/plain X-TM-AS-Product-Ver: SMEX-11.0.0.1191-8.000.1202-21912.007 X-TM-AS-Result: No--12.090100-8.000000-31 X-TM-AS-User-Approved-Sender: No X-TM-AS-User-Blocked-Sender: No X-EOPAttributedMessage: 0 X-Microsoft-Exchange-Diagnostics: 1;DB3FFO11OLC003;1:diydksibbpIIOtfCInOyeuIyXAAOzZxNiiFIeYo+uxX5G93UEbDBogcjGRqhwd3VEiz1gLs5QQcGJaL0kI1caIQmDD+ZI9kiUeGgO8fAD3WNEApD4mzfIlMxIMLGGj/FzxmO0QKuyX7JcEIdeIcFZtuQssTJogHjmEGynmg/lc2JlL8zT6q6DsOSdFdEGAnoU/tEE6GXmOn0Nx9t4+UpUTYN5v7+ZekYLEU/zxIRWzZpL2a701S2+Iobz+YJwYZV5R5TOmAdTxxJSCgkIPx1AYZToV2ac2McO9TkunXDH3wwAG12i8+JJQOE9HIlplUKNdyhsg7eDBMcr2WUa8MgVdveiWmeF08gcNaV71ekHsp7q2fs0LLC6JaYrCmZH9htfLqom+x8iuB0edNf8P9pSg== X-Forefront-Antispam-Report: CIP:212.179.42.66;CTRY:IL;IPV:NLI;EFV:NLI;SFV:NSPM;SFS:(10009020)(6009001)(2980300002)(1109001)(1110001)(339900001)(199003)(189002)(50986999)(49486002)(47776003)(5001970100001)(76176999)(5008740100001)(77096005)(87936001)(2950100001)(86362001)(85426001)(575784001)(107886002)(189998001)(2351001)(106466001)(50226001)(36756003)(6806005)(48376002)(5003940100001)(19580405001)(11100500001)(92566002)(110136002)(105606002)(33646002)(5007970100001)(4001430100002)(50466002)(104016004)(19580395003)(229853001)(2004002);DIR:OUT;SFP:1101;SCL:1;SRVR:AMSPR02MB184;H:ezex10.ezchip.com;FPR:;SPF:Fail;PTR:ezmail.ezchip.com;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;AMSPR02MB184;2:QSCx8MPdTPTqQ8HJFbTNKOl+S63BQmyWJON2md4jgEQzzWolVzhGUeA1UIKuufNWYRbYKCFScMyjTaB0sDY9iZgoS4kRFjBslD7RBDJLoL6MrSs53QKUXPqWyH39lttjR7I4VbKomfvJRnjSRf99hJyqOoCh0ku3xYsxWsjLRgA=;3:Ib8Gdr3FWpAJYlOGhpYdHlm4YJRLUdEoTkF6VIIrXTGn+wFKLoixe0fAhBRKsqd278QO01olAGgQk7JXw/N9wbxfgF8SDTBp5XCul4dyV2tDpHA6uE4h/RtyDtuhrv0WX8vVT/aAO19mUzVM7u4lk8UTn3pbM6q4XfGDaTiiLudXBAJA8Sfl/N1opWuMadmeHx/6Fp7kSxSqKXnWkeV5Dt7tw0kfbFjJ70vUq/D0OdM=;25:h+BXcq6DWJsfjZneSzyd1r+FndHQ5Cy9jUOmUwkfnZYoVBDY6A8bOHs6ExgRZ1mnt9pJALtW6rSPMvV9INsGjEmuET5gTDu8e+FZDZE4k4k60F3qcucSbcjapcilcrrEFNjtVUmQivOJLyQgzWAC3pnrLyiw9jfj0X0g56NuSWBRkLMJL1vJzE6GHW7/7a3ErvHIwKmOp+WOHnEjFPWlrZlKkqYZQ2D/kdo932ukY3ypJwKr2BUxLiNeA04FDKQQNW/r2kEH0p7FZCPPvjT2Vw==;20:I6zYY2DMIL4+UIembkVZDbAHyz8kpk/c4NIMyEr1ADP4UPsjnCUmhWjawqp9nmsznmRc/u2cbXaO6RIW1vbunV2gW+wEI2plGk0VLymEC89azCT8vWm5/eT+IBUIW8pIqRpofpLpO3BnOojntdfXI0exMq5MI/zTt6RLSfuHzUU= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:AMSPR02MB184; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(121898900299872); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(8121501046)(520078)(5005006)(10201501046)(3002001);SRVR:AMSPR02MB184;BCL:0;PCL:0;RULEID:;SRVR:AMSPR02MB184; X-Microsoft-Exchange-Diagnostics: 1;AMSPR02MB184;4:JPIwFUS9shiSWee5HIVRmaG0ndTfqHb9ULUUur5alzz/gJme/xDbhJ0FYAz2I8qxNu6zZhftrrlkxTWajYy/YYknCJbKn4eOo1dTC6Jbb5M9NGICQEBhba362mYixxTcJnVdhKPqlwZt57iPdEJE2ufRvv3bin6hcMJ7zCyYWqUaooBsAs9VcxuoYP79l96vYSkniEVe9pNTRXl50uAF4zl4ByRrYwtO0Q1YMX6XS40vOd96cInanPInyZK1q3gwbHTXptqIGN0qnhQT7bJF/eEXERXLFaj27xR77cJOyZh2hxWEBp6N+v/WJ/MFuLAuEkg/oTiyjExMsFOdah4qiNX2FYsw77mYRNEJtTHgGkpUoaKnjeXTq3XzfB4luGFV X-Forefront-PRVS: 07467C4D33 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;AMSPR02MB184;23:QE5/YTebwjLY4LUSb6CSolK/pS1PliZpI2FKH4Eanj?= =?us-ascii?Q?G8zKW/l9Ssj+r6XDjnRhsSBzJmgQ3ytULS6uZ5WLbP6BP0H3vnOVuoHWx+G6?= =?us-ascii?Q?EeEEOjl6VduJDeXTbzCEVMDaGR8ZTZuIb0daAmiWhu26l/dBhekBoo86p0k7?= =?us-ascii?Q?/x1URoTCTtAJXZatAsGpE98L2yMcVS846FlWoWvqDvMizadeGVEIiO8N++4A?= =?us-ascii?Q?Cbu4xVjH1IlPYn87otfuWCJAr+d/Jn42fiVjig74tsv/0bPM8d23LpRXfljz?= =?us-ascii?Q?q0BASyuUUkrka9gu6X5JuvhX1TdXxQIxy3o/Sz94eKwAWazcP1x1Nv9/eUhu?= =?us-ascii?Q?gQmIVt69zCRD0tAPWVtkwljgcC+7AgjcRiHseznqyvwk02fB+by8myeV/7sD?= =?us-ascii?Q?lcP96tpHiTdnr0NT2wopCDNtpRD6wduF2CufWuHyoC57pBhAFqh7SOim+RlX?= =?us-ascii?Q?AVSt5mEQHsL8aL+T+R40bIpIDo8zZaM+M4Lfcu1v+c3T62regEjpqfoeClxO?= =?us-ascii?Q?p8WENCK9MbGiNTh0xxdEXAyhU/i8F/OsYSfvJE2rDZnx+LnrtwbQohHp8wAQ?= =?us-ascii?Q?8jsX/d86XOCUl4X/elkuskOG7D4TGpnQToek2o3DAQgo6l5bOp9srfqjkfB7?= =?us-ascii?Q?5LLkF8rBzsAgEHUvIKAjpbM9faZLAbR84RDeMU3PBFnLc+TEE3dck8/s7LwS?= =?us-ascii?Q?xyohL73hPsrgskvI/ScrPMoEHLNbuLLKTBvfF38H8W+0L5BLnhnNFuvm9nGt?= =?us-ascii?Q?r+RBUAEWFZDL7seE9P2MP0DE5376UXfH5D1Xi0t6MPKQwF2o+oIjw+oebsLr?= =?us-ascii?Q?iDnlug/W+SrSuJCtLp4EdYcOksm5po1BGNBpqmMGYulsh+p1DJg/loBJJcAK?= =?us-ascii?Q?UgxUCeBlWEljEfw3jjgIyuOkEXO9/SuYCuKSrJK2sMB6MxVMz9501mPozH9O?= =?us-ascii?Q?3BiO3ts3VMVdKQ0k4VDH8vd1XkDqgBoMoNBxwqeEnN7e1PLNVmF97fxrHOeV?= =?us-ascii?Q?wL8lxXl6EIwd2aN5iJ0kdLEgGBpa7S6uzskG6/1MvH0qKzhwfs0/g7DIyyBc?= =?us-ascii?Q?lceNzV46L9y9jqgjb7opMd2boFh9TWJE+nviWcwW4FmyaTC5YK6SnX7e4XfT?= =?us-ascii?Q?qc6InBaMU=3D?= X-Microsoft-Exchange-Diagnostics: 1;AMSPR02MB184;5:JXLmGCXo2p80hf8j9/dNXcc69yPcPejDR9oDf3T7ZFTMOtiXI7TWUKklCKOz91F8xiNDRzaSD+cfnEmDDzNiOcxd6pPnwmhM/TAHlD518CeFISfJiABm8vuBcXT6YXE5XZJIGTCYxXvEqS7mvnGabQ==;24:3mPUQyNpKgUf0H7nQSN+vi6KhpzqJjBsQlhPQFK3pj8azR4u9sosQG42xbSw3XbWsZKjWLorVsb2dyPjT/dUGGICAnGlLe7vqEtoB99dEpw=;20:5B3nMSyxhWxeYr2WauG9hzIDUcpc8Ve+J5wFIhED2Hn7WThtU2bcprG/0piBU+gttf7KmmUNPy2q8SH4k6QZug== SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: ezchip.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 31 Oct 2015 13:20:39.3149 (UTC) X-MS-Exchange-CrossTenant-Id: 0fc16e0a-3cd3-4092-8b2f-0a42cff122c3 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=0fc16e0a-3cd3-4092-8b2f-0a42cff122c3;Ip=[212.179.42.66];Helo=[ezex10.ezchip.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AMSPR02MB184 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Noam Camus This platform include boards: Hardware Emulator (HE) Simulator based upon nSIM. Signed-off-by: Noam Camus --- MAINTAINERS | 6 + arch/arc/plat-eznps/Kconfig | 34 ++++ arch/arc/plat-eznps/Makefile | 7 + arch/arc/plat-eznps/entry.S | 76 +++++++++ arch/arc/plat-eznps/include/plat/ctop.h | 264 +++++++++++++++++++++++++++++++ arch/arc/plat-eznps/include/plat/mtm.h | 60 +++++++ arch/arc/plat-eznps/include/plat/smp.h | 27 +++ arch/arc/plat-eznps/mtm.c | 152 ++++++++++++++++++ arch/arc/plat-eznps/platform.c | 40 +++++ arch/arc/plat-eznps/smp.c | 160 +++++++++++++++++++ 10 files changed, 826 insertions(+), 0 deletions(-) create mode 100644 arch/arc/plat-eznps/Kconfig create mode 100644 arch/arc/plat-eznps/Makefile create mode 100644 arch/arc/plat-eznps/entry.S create mode 100644 arch/arc/plat-eznps/include/plat/ctop.h create mode 100644 arch/arc/plat-eznps/include/plat/mtm.h create mode 100644 arch/arc/plat-eznps/include/plat/smp.h create mode 100644 arch/arc/plat-eznps/mtm.c create mode 100644 arch/arc/plat-eznps/platform.c create mode 100644 arch/arc/plat-eznps/smp.c diff --git a/MAINTAINERS b/MAINTAINERS index 08adb4a..c63ca18 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4171,6 +4171,12 @@ S: Maintained F: drivers/video/fbdev/exynos/exynos_mipi* F: include/video/exynos_mipi* +EZchip NPS platform support +M: Noam Camus +S: Supported +F: arch/arc/plat-eznps +F: arch/arc/boot/dts/eznps.dts + F71805F HARDWARE MONITORING DRIVER M: Jean Delvare L: lm-sensors@lm-sensors.org diff --git a/arch/arc/plat-eznps/Kconfig b/arch/arc/plat-eznps/Kconfig new file mode 100644 index 0000000..510354f --- /dev/null +++ b/arch/arc/plat-eznps/Kconfig @@ -0,0 +1,34 @@ +# +# For a description of the syntax of this configuration file, +# see Documentation/kbuild/kconfig-language.txt. +# + +menuconfig ARC_PLAT_EZNPS + bool "\"EZchip\" ARC dev platform" + select ARC_HAS_COH_CACHES if SMP + select CPU_BIG_ENDIAN + select CLKSRC_OF + select EZCHIP_NPS_MANAGEMENT_ENET if ETHERNET + help + Support for EZchip development platforms, + based on ARC700 cores. + We handle few flavours: + - Hardware Emulator AKA HE which is FPGA based chasis + - Simulator based on MetaWare nSIM + - NPS400 chip based on ASIC + +config EZNPS_MTM_EXT + bool "ARC-EZchip MTM Extensions" + select CPUMASK_OFFSTACK + depends on ARC_PLAT_EZNPS && SMP + default y + help + Here we add new hierarchy for CPUs topology. + We got: + Core + Thread + At the new thread level each CPU represent one HW thread. + At highest hierarchy each core contain 16 threads, + any of them seem like CPU from Linux point of view. + All threads within same core share the execution unit of the + core and HW scheduler round robin between them. diff --git a/arch/arc/plat-eznps/Makefile b/arch/arc/plat-eznps/Makefile new file mode 100644 index 0000000..21091b1 --- /dev/null +++ b/arch/arc/plat-eznps/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for the linux kernel. +# + +obj-y := entry.o platform.o +obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_EZNPS_MTM_EXT) += mtm.o diff --git a/arch/arc/plat-eznps/entry.S b/arch/arc/plat-eznps/entry.S new file mode 100644 index 0000000..a3dec3e --- /dev/null +++ b/arch/arc/plat-eznps/entry.S @@ -0,0 +1,76 @@ +/******************************************************************************* + + EZNPS CPU startup Code + Copyright(c) 2012 EZchip Technologies. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + +*******************************************************************************/ +#include +#include +#include +#include + + .cpu A7 + + .section .text, "ax",@progbits + .align 1024 ; HW requierment for restart first PC + +ENTRY(res_service) +#ifdef CONFIG_EZNPS_MTM_EXT + ; For HW thread != 0 there is no work. + lr r3, [CTOP_AUX_THREAD_ID] + cmp r3, 0 + jne _stext +#endif + +#ifdef CONFIG_ARC_HAS_DCACHE + ; We do not have cache coherency mechanism, + ; so D$ need to be used very carefully. + ; Address space: + ; 0G-2G: We disable CONFIG_ARC_CACHE_PAGES. + ; 2G-3G: We disable D$ by setting this bit. + ; 3G-4G: D$ is disabled by architecture. + ; FMT are the huge pages for user application reside at 0-2G. + ; Only FMT left as one who can use D$ where each such page got + ; disable/enable bit for cachability. + ; Programmer will use FMT pages for private data so cache coherency + ; would not be a problem. + ; First thing we invalidate D$ + sr 1, [ARC_REG_DC_IVDC] + sr HW_COMPLY_KRN_NOT_D_CACHED, [CTOP_AUX_HW_COMPLY] +#endif + +#ifdef CONFIG_SMP + ; check for boot CPU + lr r3, [CTOP_AUX_GLOBAL_ID] + cmp r3, 0 + jeq _stext + + ; We set logical cpuid to be used by GET_CPUID + ; We do not use physical cpuid since we want ids to be continious when + ; it comes to cpus on the same quad cluster. + ; This is useful for applications that used shared resources of a quad + ; cluster such SRAMS. + lr r3, [CTOP_AUX_CORE_ID] + sr r3, [CTOP_AUX_LOGIC_CORE_ID] + lr r3, [CTOP_AUX_CLUSTER_ID] + ; Set logical is acheived by swap of 2 middle bits of cluster id (4 bit) + ; r3 is used since we use short instruction and we need q-class reg + .short CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST + .word CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM + sr r3, [CTOP_AUX_LOGIC_CLUSTER_ID] +#endif + + j _stext +END(res_service) diff --git a/arch/arc/plat-eznps/include/plat/ctop.h b/arch/arc/plat-eznps/include/plat/ctop.h new file mode 100644 index 0000000..b708f9f --- /dev/null +++ b/arch/arc/plat-eznps/include/plat/ctop.h @@ -0,0 +1,264 @@ +/* + * Copyright(c) 2015 EZchip Technologies. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + */ + +#ifndef _PLAT_EZNPS_CTOP_H +#define _PLAT_EZNPS_CTOP_H + +#define NPS_HOST_REG_BASE 0xF6000000 + +/* core auxiliary registers */ +#define CTOP_AUX_BASE 0xFFFFF800 +#define CTOP_AUX_GLOBAL_ID (CTOP_AUX_BASE + 0x000) +#define CTOP_AUX_CLUSTER_ID (CTOP_AUX_BASE + 0x004) +#define CTOP_AUX_CORE_ID (CTOP_AUX_BASE + 0x008) +#define CTOP_AUX_THREAD_ID (CTOP_AUX_BASE + 0x00C) +#define CTOP_AUX_LOGIC_GLOBAL_ID (CTOP_AUX_BASE + 0x010) +#define CTOP_AUX_LOGIC_CLUSTER_ID (CTOP_AUX_BASE + 0x014) +#define CTOP_AUX_LOGIC_CORE_ID (CTOP_AUX_BASE + 0x018) +#define CTOP_AUX_MT_CTRL (CTOP_AUX_BASE + 0x020) +#define CTOP_AUX_HW_COMPLY (CTOP_AUX_BASE + 0x024) +#define CTOP_AUX_LPC (CTOP_AUX_BASE + 0x030) +#define AUX_REG_TSI1 (CTOP_AUX_BASE + 0x050) +#define CTOP_AUX_EFLAGS (CTOP_AUX_BASE + 0x080) +#define CTOP_AUX_IACK (CTOP_AUX_BASE + 0x088) +#define CTOP_AUX_UDMC (CTOP_AUX_BASE + 0x300) + +/* EZchip core instructions */ +#define CTOP_INST_HWSCHD_OFF_R3 0x3b6f00bf +#define CTOP_INST_HWSCHD_OFF_R4 0x3c6f00bf +#define CTOP_INST_HWSCHD_RESTORE_R3 0x3e6f7083 +#define CTOP_INST_HWSCHD_RESTORE_R4 0x3e6f7103 +#define CTOP_INST_SCHD_RW 0x3e6f7004 +#define CTOP_INST_SCHD_RD 0x3e6f7084 +#define CTOP_INST_ASRI_0_R3 0x3b56003e +#define CTOP_INST_XEX_DI_R2_R2_R3 0x4a664c00 +#define CTOP_INST_EXC_DI_R2_R2_R3 0x4a664c01 +#define CTOP_INST_AADD_DI_R2_R2_R3 0x4a664c02 +#define CTOP_INST_AAND_DI_R2_R2_R3 0x4a664c04 +#define CTOP_INST_AOR_DI_R2_R2_R3 0x4a664c05 +#define CTOP_INST_AXOR_DI_R2_R2_R3 0x4a664c06 +#define CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST 0x5b60 +#define CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM 0x00010422 +#define CTOP_INST_RSPI_GIC_0_R12 0x3c56117e + +/* Do not use D$ for address in 2G-3G */ +#define HW_COMPLY_KRN_NOT_D_CACHED (1 << 28) + +#ifndef __ASSEMBLY__ +#define NPS_MSU_BLKID 0x018 +#define NPS_CRG_BLKID 0x480 +#define NPS_CRG_SYNC_BIT BIT(0) + +#define NPS_GIM_BLKID 0x5C0 +#define NPS_GIM_UART_LINE BIT(7) +#define NPS_GIM_DBG_LAN_TX_DONE_LINE BIT(10) +#define NPS_GIM_DBG_LAN_RX_RDY_LINE BIT(11) + +/* CPU global ID */ +struct global_id { + union { + struct { +#ifdef CONFIG_EZNPS_MTM_EXT + u32 __reserved:20, cluster:4, core:4, thread:4; +#else + u32 __reserved:24, cluster:4, core:4; +#endif + }; + u32 value; + }; +}; + +/* + * Convert logical to physical CPU IDs + * + * The conversion swap bits 1 and 2 of cluster id (out of 4 bits) + * Now quad of logical clusters id's are adjacent physicaly, + * like can be seen in following table. + * Cluster ids are in format: logical (physical) + * + * 3 | 5 (3) | 7 (7) || 13 (11) | 15 (15) + * 2 | 4 (2) | 6 (6) || 12 (10) | 14 (14) + * ============================================ + * 1 | 1 (1) | 3 (5) || 9 (9) | 11 (13) + * 0 | 0 (0) | 2 (4) || 8 (8) | 10 (12) + * -------------------------------------------- + * | 0 | 1 || 2 | 3 + */ +static inline int nps_cluster_logic_to_phys(int cluster) +{ + __asm__ __volatile__( + " mov r3,%0\n" + " .short %1\n" + " .word %2\n" + " mov %0,r3\n" + : "+r"(cluster) + : "i"(CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST), + "i"(CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM) + : "r3"); + + return cluster; +} + +#define NPS_CPU_TO_CLUSTER_NUM(cpu) \ + ({ struct global_id gid; gid.value = cpu; \ + nps_cluster_logic_to_phys(gid.cluster); }) + +struct nps_host_reg_address { + union { + struct { + u32 base:8, cl_x:4, cl_y:4, + blkid:6, reg:8, __reserved:2; + }; + u32 value; + }; +}; + +struct nps_host_reg_mtm_cfg { + union { + struct { + u32 gen:1, gdis:1, clk_gate_dis:1, asb:1, + __reserved:9, nat:3, ten:16; + }; + u32 value; + }; +}; + +struct nps_host_reg_mtm_cpu_cfg { + union { + struct { + u32 csa:22, dmsid:6, __reserved:3, cs:1; + }; + u32 value; + }; +}; + +struct nps_host_reg_thr_init { + union { + struct { + u32 str:1, __reserved:27, thr_id:4; + }; + u32 value; + }; +}; + +struct nps_host_reg_thr_init_sts { + union { + struct { + u32 bsy:1, err:1, __reserved:26, thr_id:4; + }; + u32 value; + }; +}; + +struct nps_host_reg_aux_udmc { + union { + struct { + u32 dcp:1, cme:1, __reserved:20, nat:3, + __reserved2:5, dcas:3; + }; + u32 value; + }; +}; + +struct nps_host_reg_aux_mt_ctrl { + union { + struct { + u32 mten:1, hsen:1, scd:1, sten:1, + __reserved:4, st_cnt:4, __reserved2:8, + hs_cnt:8, __reserved3:4; + }; + u32 value; + }; +}; + +struct nps_host_reg_aux_hw_comply { + union { + struct { + u32 me:1, le:1, te:1, knc:1, __reserved:28; + }; + u32 value; + }; +}; + +struct nps_host_reg_aux_lpc { + union { + struct { + u32 mep:1, __reserved:31; + }; + u32 value; + }; +}; + +struct nps_host_reg_address_non_cl { + union { + struct { + u32 base:7, blkid:11, reg:12, __reserved:2; + }; + u32 value; + }; +}; + +struct nps_host_reg_gim_p_int_dst { + union { + struct { + u32 int_out_en:1, __reserved1:4, + is:1, intm:2, __reserved2:4, + nid:4, __reserved3:4, cid:4, + __reserved4:4, tid:4; + }; + u32 value; + }; +}; + +static inline void *nps_host_reg_non_cl(u32 blkid, u32 reg) +{ + struct nps_host_reg_address_non_cl reg_address; + + reg_address.value = NPS_HOST_REG_BASE; + reg_address.blkid = blkid; + reg_address.reg = reg; + + return (void *)reg_address.value; +} + +static inline void *nps_host_reg(u32 cpu, u32 blkid, u32 reg) +{ + struct nps_host_reg_address reg_address; + u32 cl = NPS_CPU_TO_CLUSTER_NUM(cpu); + + reg_address.value = NPS_HOST_REG_BASE; + reg_address.cl_x = (cl >> 2) & 0x3; + reg_address.cl_y = cl & 0x3; + reg_address.blkid = blkid; + reg_address.reg = reg; + + return (void *)reg_address.value; +} + +/* CRG registers */ +#define REG_GEN_PURP_0 nps_host_reg_non_cl(NPS_CRG_BLKID, 0x1BF) + +/* GIM registers */ +#define REG_GIM_P_INT_EN_0 nps_host_reg_non_cl(NPS_GIM_BLKID, 0x100) +#define REG_GIM_P_INT_POL_0 nps_host_reg_non_cl(NPS_GIM_BLKID, 0x110) +#define REG_GIM_P_INT_SENS_0 nps_host_reg_non_cl(NPS_GIM_BLKID, 0x114) +#define REG_GIM_P_INT_BLK_0 nps_host_reg_non_cl(NPS_GIM_BLKID, 0x118) +#define REG_GIM_P_INT_DST_10 nps_host_reg_non_cl(NPS_GIM_BLKID, 0x13A) +#define REG_GIM_P_INT_DST_11 nps_host_reg_non_cl(NPS_GIM_BLKID, 0x13B) + +#endif /* __ASEMBLY__ */ + +#endif /* _PLAT_EZNPS_CTOP_H */ diff --git a/arch/arc/plat-eznps/include/plat/mtm.h b/arch/arc/plat-eznps/include/plat/mtm.h new file mode 100644 index 0000000..29b91b5 --- /dev/null +++ b/arch/arc/plat-eznps/include/plat/mtm.h @@ -0,0 +1,60 @@ +/* + * Copyright(c) 2015 EZchip Technologies. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + */ + +#ifndef _PLAT_EZNPS_MTM_H +#define _PLAT_EZNPS_MTM_H + +#include + +static inline void *nps_mtm_reg_addr(u32 cpu, u32 reg) +{ + struct global_id gid; + u32 core, blkid; + + gid.value = cpu; + core = gid.core; + blkid = (((core & 0x0C) << 2) | (core & 0x03)); + + return nps_host_reg(cpu, blkid, reg); +} + +#ifdef CONFIG_EZNPS_MTM_EXT +#define NPS_CPU_TO_THREAD_NUM(cpu) \ + ({ struct global_id gid; gid.value = cpu; gid.thread; }) + +/* MTM registers */ +#define MTM_CFG(cpu) nps_mtm_reg_addr(cpu, 0x81) +#define MTM_THR_INIT(cpu) nps_mtm_reg_addr(cpu, 0x92) +#define MTM_THR_INIT_STS(cpu) nps_mtm_reg_addr(cpu, 0x93) + +#define get_thread(map) map.thread +#define eznps_max_cpus 4096 +#define eznps_cpus_per_cluster 256 + +void mtm_enable_core(unsigned int cpu); +int mtm_enable_thread(int cpu); +#else /* !CONFIG_EZNPS_MTM_EXT */ + +#define get_thread(map) 0 +#define eznps_max_cpus 256 +#define eznps_cpus_per_cluster 16 +#define mtm_enable_core(cpu) +#define mtm_enable_thread(cpu) 1 +#define NPS_CPU_TO_THREAD_NUM(cpu) 0 + +#endif /* CONFIG_EZNPS_MTM_EXT */ + +#endif /* _PLAT_EZNPS_MTM_H */ diff --git a/arch/arc/plat-eznps/include/plat/smp.h b/arch/arc/plat-eznps/include/plat/smp.h new file mode 100644 index 0000000..7509443 --- /dev/null +++ b/arch/arc/plat-eznps/include/plat/smp.h @@ -0,0 +1,27 @@ +/* + * Copyright(c) 2015 EZchip Technologies. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + */ + +#ifndef __PLAT_EZNPS_SMP_H +#define __PLAT_EZNPS_SMP_H + +#ifdef CONFIG_SMP + +extern struct cpumask _cpu_possible_mask; +void eznps_smp_init_cpu(unsigned int cpu); + +#endif /* CONFIG_SMP */ + +#endif diff --git a/arch/arc/plat-eznps/mtm.c b/arch/arc/plat-eznps/mtm.c new file mode 100644 index 0000000..802c3c8 --- /dev/null +++ b/arch/arc/plat-eznps/mtm.c @@ -0,0 +1,152 @@ +/* + * Copyright(c) 2015 EZchip Technologies. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + */ + +#include +#include +#include +#include +#include + +#define MT_CTRL_HS_CNT 0xFF +#define MT_CTRL_ST_CNT 0xF +#define NPS_NUM_HW_THREADS 0x10 + +static void mtm_init_nat(int cpu) +{ + struct nps_host_reg_mtm_cfg mtm_cfg; + struct nps_host_reg_aux_udmc udmc; + int log_nat, nat = 0, i, t; + + /* Iterate core threads and update nat */ + for (i = 0, t = cpu; i < NPS_NUM_HW_THREADS; i++, t++) + nat += test_bit(t, cpumask_bits(cpu_possible_mask)); + + switch (nat) { + case 1: + log_nat = 0; + break; + case 2: + log_nat = 1; + break; + case 4: + log_nat = 2; + break; + case 8: + log_nat = 3; + break; + case 16: + log_nat = 4; + break; + default: + pr_warn("BUG: got non valid NAT %d!\n", nat); + log_nat = 0; + break; + } + + udmc.value = read_aux_reg(CTOP_AUX_UDMC); + udmc.nat = log_nat; + write_aux_reg(CTOP_AUX_UDMC, udmc.value); + + mtm_cfg.value = ioread32be(MTM_CFG(cpu)); + mtm_cfg.nat = log_nat; + iowrite32be(mtm_cfg.value, MTM_CFG(cpu)); +} + +static void mtm_init_thread(int cpu) +{ + int i, tries = 5; + struct nps_host_reg_thr_init thr_init; + struct nps_host_reg_thr_init_sts thr_init_sts; + + /* Set thread init register */ + thr_init.value = 0; + iowrite32be(thr_init.value, MTM_THR_INIT(cpu)); + thr_init.thr_id = NPS_CPU_TO_THREAD_NUM(cpu); + thr_init.str = 1; + iowrite32be(thr_init.value, MTM_THR_INIT(cpu)); + + /* Poll till thread init is done */ + for (i = 0; i < tries; i++) { + thr_init_sts.value = ioread32be(MTM_THR_INIT_STS(cpu)); + if (thr_init_sts.thr_id == thr_init.thr_id) { + if (thr_init_sts.bsy) + continue; + else if (thr_init_sts.err) + pr_warn("Failed to thread init cpu %u\n", cpu); + break; + } + + pr_warn("Wrong thread id in thread init for cpu %u\n", cpu); + break; + } + + if (i == tries) + pr_warn("Got thread init timeout for cpu %u\n", cpu); +} + +int mtm_enable_thread(int cpu) +{ + struct nps_host_reg_mtm_cfg mtm_cfg; + + if (NPS_CPU_TO_THREAD_NUM(cpu) == 0) + return 1; + + /* Enable thread in mtm */ + mtm_cfg.value = ioread32be(MTM_CFG(cpu)); + mtm_cfg.ten |= (1 << (NPS_CPU_TO_THREAD_NUM(cpu))); + iowrite32be(mtm_cfg.value, MTM_CFG(cpu)); + + return 0; +} + +void mtm_enable_core(unsigned int cpu) +{ + int i; + struct nps_host_reg_aux_mt_ctrl mt_ctrl; + struct nps_host_reg_mtm_cfg mtm_cfg; + + if (NPS_CPU_TO_THREAD_NUM(cpu) != 0) + return; + + /* Initialize Number of Active Threads */ + mtm_init_nat(cpu); + + /* Initialize mtm_cfg */ + mtm_cfg.value = ioread32be(MTM_CFG(cpu)); + mtm_cfg.ten = 1; + iowrite32be(mtm_cfg.value, MTM_CFG(cpu)); + + /* Initialize all other threads in core */ + for (i = 1; i < NPS_NUM_HW_THREADS; i++) + mtm_init_thread(cpu + i); + + + /* Enable HW schedule, stall counter, mtm */ + mt_ctrl.value = 0; + mt_ctrl.hsen = 1; + mt_ctrl.hs_cnt = MT_CTRL_HS_CNT; + mt_ctrl.sten = 1; + mt_ctrl.st_cnt = MT_CTRL_ST_CNT; + mt_ctrl.mten = 1; + write_aux_reg(CTOP_AUX_MT_CTRL, mt_ctrl.value); + + /* + * HW scheduling mechanism will start working + * Only after call to instruction "schd.rw". + * cpu_relax() calls "schd.rw" instruction. + */ + cpu_relax(); +} diff --git a/arch/arc/plat-eznps/platform.c b/arch/arc/plat-eznps/platform.c new file mode 100644 index 0000000..c84dfd9 --- /dev/null +++ b/arch/arc/plat-eznps/platform.c @@ -0,0 +1,40 @@ +/* + * Copyright(c) 2015 EZchip Technologies. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + */ + +#include +#include +#include +#include + +/*----------------------- Machine Descriptions ------------------------------ + * + * Machine description is simply a set of platform/board specific callbacks + * This is not directly related to DeviceTree based dynamic device creation, + * however as part of early device tree scan, we also select the right + * callback set, by matching the DT compatible name. + */ + +static const char *eznps_compat[] __initconst = { + "ezchip,arc-nps", + NULL, +}; + +MACHINE_START(NPS, "nps") + .dt_compat = eznps_compat, +#ifdef CONFIG_SMP + .init_cpu_smp = eznps_smp_init_cpu, /* for each CPU */ +#endif +MACHINE_END diff --git a/arch/arc/plat-eznps/smp.c b/arch/arc/plat-eznps/smp.c new file mode 100644 index 0000000..0f8b51a --- /dev/null +++ b/arch/arc/plat-eznps/smp.c @@ -0,0 +1,160 @@ +/* + * Copyright(c) 2015 EZchip Technologies. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + */ + +#include +#include +#include +#include +#include +#include +#include + +#define NPS_DEFAULT_MSID 0x34 +#define NPS_MTM_CPU_CFG 0x90 + +struct cpumask _cpu_possible_mask; +static char smp_cpuinfo_buf[128] = {"Extn [EZNPS-SMP]\t: On\n"}; + +/* Get cpu map from device tree */ +static int __init eznps_get_map(const char *name, struct cpumask *cpumask) +{ + unsigned long dt_root = of_get_flat_dt_root(); + const char *buf; + + buf = of_get_flat_dt_prop(dt_root, name, NULL); + if (!buf) + return 1; + + cpulist_parse(buf, cpumask); + + return 0; +} + +/* Update board cpu maps */ +static void __init eznps_init_cpumasks(void) +{ + struct cpumask cpumask; + + if (eznps_get_map("present-cpus", &cpumask)) { + pr_err("Failed to get present-cpus from dtb"); + return; + } + init_cpu_present(&cpumask); + + if (eznps_get_map("possible-cpus", &cpumask)) { + pr_err("Failed to get possible-cpus from dtb"); + return; + } + init_cpu_possible(&cpumask); +} + +static void eznps_init_core(unsigned int cpu) +{ + u32 sync_value; + struct nps_host_reg_aux_hw_comply hw_comply; + struct nps_host_reg_aux_lpc lpc; + + if (NPS_CPU_TO_THREAD_NUM(cpu) != 0) + return; + + hw_comply.value = read_aux_reg(CTOP_AUX_HW_COMPLY); + hw_comply.me = 1; + hw_comply.le = 1; + hw_comply.te = 1; + write_aux_reg(CTOP_AUX_HW_COMPLY, hw_comply.value); + + /* Enable MMU clock */ + lpc.mep = 1; + write_aux_reg(CTOP_AUX_LPC, lpc.value); + + /* Boot CPU only */ + if (!cpu) { + /* Write to general purpose register in CRG */ + sync_value = ioread32be(REG_GEN_PURP_0); + sync_value |= NPS_CRG_SYNC_BIT; + iowrite32be(sync_value, REG_GEN_PURP_0); + } +} + +/* + * Any SMP specific init any CPU does when it comes up. + * Here we setup the CPU to enable Inter-Processor-Interrupts + * Called for each CPU + * -Master : init_IRQ() + * -Other(s) : start_kernel_secondary() + */ +void eznps_smp_init_cpu(unsigned int cpu) +{ + unsigned int rc; + + rc = smp_ipi_irq_setup(cpu, IPI_IRQ); + if (rc) + panic("IPI IRQ %d reg failed on BOOT cpu\n", IPI_IRQ); + + eznps_init_core(cpu); + mtm_enable_core(cpu); +} + +/* + * Master kick starting another CPU + */ +static void eznps_smp_wakeup_cpu(int cpu, unsigned long pc) +{ + struct nps_host_reg_mtm_cpu_cfg cpu_cfg; + + if (mtm_enable_thread(cpu) == 0) + return; + + /* set PC, dmsid, and start CPU */ + cpu_cfg.value = pc; + cpu_cfg.dmsid = NPS_DEFAULT_MSID; + cpu_cfg.cs = 1; + iowrite32be(cpu_cfg.value, nps_mtm_reg_addr(cpu, NPS_MTM_CPU_CFG)); +} + +static void eznps_ipi_send(int cpu) +{ + struct global_id gid; + struct { + union { + struct { + u32 num:8, cluster:8, core:8, thread:8; + }; + u32 value; + }; + } ipi; + + gid.value = cpu; + ipi.thread = get_thread(gid); + ipi.core = gid.core; + ipi.cluster = nps_cluster_logic_to_phys(gid.cluster); + ipi.num = IPI_IRQ; + + __asm__ __volatile__( + " mov r3, %0\n" + " .word %1\n" + : + : "r"(ipi.value), "i"(CTOP_INST_ASRI_0_R3) + : "r3"); +} + +struct plat_smp_ops plat_smp_ops = { + .info = smp_cpuinfo_buf, + .init_early_smp = eznps_init_cpumasks, + .cpu_kick = eznps_smp_wakeup_cpu, + .ipi_send = eznps_ipi_send, +}; + -- 1.7.1