diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 264c83d261b32e775bb569bacf34f5f2548e3d69..f1dc6c8d77f15960eed78486833c74d185f219ad 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -116,17 +116,6 @@ config SYS_DCACHE_OFF
 	bool "Do not use Data Cache"
 	default n
 
-config ARC_CACHE_LINE_SHIFT
-	int "Cache Line Length (as power of 2)"
-	range 5 7
-	default "6"
-	depends on !SYS_DCACHE_OFF || !SYS_ICACHE_OFF
-	help
-	  Starting with ARC700 4.9, Cache line length is configurable,
-	  This option specifies "N", with Line-len = 2 power N
-	  So line lengths of 32, 64, 128 are specified by 5,6,7, respectively
-	  Linux only supports same line lengths for I and D caches.
-
 choice
 	prompt "Target select"
 	default TARGET_AXS101
diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h
index 432606a4335bd187a3884ee8c29b74a7dc2e8a9e..d26d9fb18d0e1b6573b2d8a8c3019ba7c59565ee 100644
--- a/arch/arc/include/asm/cache.h
+++ b/arch/arc/include/asm/cache.h
@@ -9,13 +9,13 @@
 
 #include <config.h>
 
-#ifdef CONFIG_ARC_CACHE_LINE_SHIFT
-#define CONFIG_SYS_CACHELINE_SIZE	(1 << CONFIG_ARC_CACHE_LINE_SHIFT)
-#define ARCH_DMA_MINALIGN		CONFIG_SYS_CACHELINE_SIZE
-#else
-/* Satisfy users of ARCH_DMA_MINALIGN */
-#define ARCH_DMA_MINALIGN		128
-#endif
+/*
+ * As of today we may handle any L1 cache line length right in software.
+ * For that essentially cache line length is a variable not constant.
+ * And to satisfy users of ARCH_DMA_MINALIGN we just use largest line length
+ * that may exist in either L1 or L2 (AKA SLC) caches on ARC.
+ */
+#define ARCH_DMA_MINALIGN	128
 
 #if defined(ARC_MMU_ABSENT)
 #define CONFIG_ARC_MMU_VER 0
diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c
index ed8e8e74e2a19a414a5aee265605815b1c91ea22..8089f9df1e2602fbde9cdaf7f5f931893f40ca4e 100644
--- a/arch/arc/lib/cache.c
+++ b/arch/arc/lib/cache.c
@@ -5,13 +5,12 @@
  */
 
 #include <config.h>
+#include <common.h>
 #include <linux/compiler.h>
 #include <linux/kernel.h>
 #include <asm/arcregs.h>
 #include <asm/cache.h>
 
-#define CACHE_LINE_MASK		(~(CONFIG_SYS_CACHELINE_SIZE - 1))
-
 /* Bit values in IC_CTRL */
 #define IC_CTRL_CACHE_DISABLE	(1 << 0)
 
@@ -26,12 +25,18 @@
 #define OP_FLUSH	0x2
 #define OP_INV_IC	0x3
 
-#ifdef CONFIG_ISA_ARCV2
 /*
  * By default that variable will fall into .bss section.
  * But .bss section is not relocated and so it will be initilized before
  * relocation but will be used after being zeroed.
  */
+int l1_line_sz __section(".data");
+int dcache_exists __section(".data");
+int icache_exists __section(".data");
+
+#define CACHE_LINE_MASK		(~(l1_line_sz - 1))
+
+#ifdef CONFIG_ISA_ARCV2
 int slc_line_sz __section(".data");
 int slc_exists __section(".data");
 
@@ -111,46 +116,87 @@ static inline void __slc_line_op(unsigned long paddr, unsigned long sz,
 #define __slc_line_op(paddr, sz, cacheop)
 #endif
 
-static inline int icache_exists(void)
+#ifdef CONFIG_ISA_ARCV2
+static void read_decode_cache_bcr_arcv2(void)
 {
-	/* Check if Instruction Cache is available */
-	if (read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK)
-		return 1;
-	else
-		return 0;
+	union {
+		struct {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+			unsigned int pad:24, way:2, lsz:2, sz:4;
+#else
+			unsigned int sz:4, lsz:2, way:2, pad:24;
+#endif
+		} fields;
+		unsigned int word;
+	} slc_cfg;
+
+	union {
+		struct {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+			unsigned int pad:24, ver:8;
+#else
+			unsigned int ver:8, pad:24;
+#endif
+		} fields;
+		unsigned int word;
+	} sbcr;
+
+	sbcr.word = read_aux_reg(ARC_BCR_SLC);
+	if (sbcr.fields.ver) {
+		slc_cfg.word = read_aux_reg(ARC_AUX_SLC_CONFIG);
+		slc_exists = 1;
+		slc_line_sz = (slc_cfg.fields.lsz == 0) ? 128 : 64;
+	}
 }
+#endif
 
-static inline int dcache_exists(void)
+void read_decode_cache_bcr(void)
 {
-	/* Check if Data Cache is available */
-	if (read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK)
-		return 1;
-	else
-		return 0;
+	int dc_line_sz = 0, ic_line_sz = 0;
+
+	union {
+		struct {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+			unsigned int pad:12, line_len:4, sz:4, config:4, ver:8;
+#else
+			unsigned int ver:8, config:4, sz:4, line_len:4, pad:12;
+#endif
+		} fields;
+		unsigned int word;
+	} ibcr, dbcr;
+
+	ibcr.word = read_aux_reg(ARC_BCR_IC_BUILD);
+	if (ibcr.fields.ver) {
+		icache_exists = 1;
+		l1_line_sz = ic_line_sz = 8 << ibcr.fields.line_len;
+		if (!ic_line_sz)
+			panic("Instruction exists but line length is 0\n");
+	}
+
+	dbcr.word = read_aux_reg(ARC_BCR_DC_BUILD);
+	if (dbcr.fields.ver){
+		dcache_exists = 1;
+		l1_line_sz = dc_line_sz = 16 << dbcr.fields.line_len;
+		if (!dc_line_sz)
+			panic("Data cache exists but line length is 0\n");
+	}
+
+	if (ic_line_sz && dc_line_sz && (ic_line_sz != dc_line_sz))
+		panic("Instruction and data cache line lengths differ\n");
 }
 
 void cache_init(void)
 {
+	read_decode_cache_bcr();
+
 #ifdef CONFIG_ISA_ARCV2
-	/* Check if System-Level Cache (SLC) is available */
-	if (read_aux_reg(ARC_BCR_SLC) & CACHE_VER_NUM_MASK) {
-#define LSIZE_OFFSET	4
-#define LSIZE_MASK	3
-		if (read_aux_reg(ARC_AUX_SLC_CONFIG) &
-		    (LSIZE_MASK << LSIZE_OFFSET))
-			slc_line_sz = 64;
-		else
-			slc_line_sz = 128;
-		slc_exists = 1;
-	} else {
-		slc_exists = 0;
-	}
+	read_decode_cache_bcr_arcv2();
 #endif
 }
 
 int icache_status(void)
 {
-	if (!icache_exists())
+	if (!icache_exists)
 		return 0;
 
 	if (read_aux_reg(ARC_AUX_IC_CTRL) & IC_CTRL_CACHE_DISABLE)
@@ -161,14 +207,14 @@ int icache_status(void)
 
 void icache_enable(void)
 {
-	if (icache_exists())
+	if (icache_exists)
 		write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) &
 			      ~IC_CTRL_CACHE_DISABLE);
 }
 
 void icache_disable(void)
 {
-	if (icache_exists())
+	if (icache_exists)
 		write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) |
 			      IC_CTRL_CACHE_DISABLE);
 }
@@ -190,7 +236,7 @@ void invalidate_icache_all(void)
 
 int dcache_status(void)
 {
-	if (!dcache_exists())
+	if (!dcache_exists)
 		return 0;
 
 	if (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_CACHE_DISABLE)
@@ -201,7 +247,7 @@ int dcache_status(void)
 
 void dcache_enable(void)
 {
-	if (!dcache_exists())
+	if (!dcache_exists)
 		return;
 
 	write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) &
@@ -210,7 +256,7 @@ void dcache_enable(void)
 
 void dcache_disable(void)
 {
-	if (!dcache_exists())
+	if (!dcache_exists)
 		return;
 
 	write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) |
@@ -246,14 +292,14 @@ static inline void __cache_line_loop(unsigned long paddr, unsigned long sz,
 	sz += paddr & ~CACHE_LINE_MASK;
 	paddr &= CACHE_LINE_MASK;
 
-	num_lines = DIV_ROUND_UP(sz, CONFIG_SYS_CACHELINE_SIZE);
+	num_lines = DIV_ROUND_UP(sz, l1_line_sz);
 
 	while (num_lines-- > 0) {
 #if (CONFIG_ARC_MMU_VER == 3)
 		write_aux_reg(aux_tag, paddr);
 #endif
 		write_aux_reg(aux_cmd, paddr);
-		paddr += CONFIG_SYS_CACHELINE_SIZE;
+		paddr += l1_line_sz;
 	}
 }
 
diff --git a/configs/axs101_defconfig b/configs/axs101_defconfig
index a541d9d17fcd50e1991c51e977103e4417a6cff4..b79dd3ce5db73f3cbfeceee5a53e5d774390c759 100644
--- a/configs/axs101_defconfig
+++ b/configs/axs101_defconfig
@@ -1,6 +1,5 @@
 CONFIG_ARC=y
 CONFIG_SYS_DCACHE_OFF=y
-CONFIG_ARC_CACHE_LINE_SHIFT=5
 CONFIG_DM_SERIAL=y
 CONFIG_SYS_CLK_FREQ=750000000
 CONFIG_SYS_TEXT_BASE=0x81000000
diff --git a/configs/tb100_defconfig b/configs/tb100_defconfig
index 27ea43ff97202741dce286bd45de4f1ac898e157..053b74ca3dacfc17aa311de3a98b744183385510 100644
--- a/configs/tb100_defconfig
+++ b/configs/tb100_defconfig
@@ -1,5 +1,4 @@
 CONFIG_ARC=y
-CONFIG_ARC_CACHE_LINE_SHIFT=5
 CONFIG_TARGET_TB100=y
 CONFIG_DM_SERIAL=y
 CONFIG_SYS_CLK_FREQ=500000000