VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
d2912cb15bdda (Thomas Gleixner 2019-06-04 10:11:33 +0200   1) // SPDX-License-Identifier: GPL-2.0-only
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200   2) /*
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200   3)  * Qualcomm External Bus Interface 2 (EBI2) driver
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200   4)  * an older version of the Qualcomm Parallel Interface Controller (QPIC)
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200   5)  *
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200   6)  * Copyright (C) 2016 Linaro Ltd.
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200   7)  *
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200   8)  * Author: Linus Walleij <linus.walleij@linaro.org>
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200   9)  *
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  10)  * See the device tree bindings for this block for more details on the
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  11)  * hardware.
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  12)  */
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  13) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  14) #include <linux/module.h>
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  15) #include <linux/clk.h>
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  16) #include <linux/err.h>
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  17) #include <linux/io.h>
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  18) #include <linux/of.h>
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  19) #include <linux/of_platform.h>
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  20) #include <linux/init.h>
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  21) #include <linux/slab.h>
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  22) #include <linux/platform_device.h>
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  23) #include <linux/bitops.h>
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  24) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  25) /*
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  26)  * CS0, CS1, CS4 and CS5 are two bits wide, CS2 and CS3 are one bit.
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  27)  */
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  28) #define EBI2_CS0_ENABLE_MASK BIT(0)|BIT(1)
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  29) #define EBI2_CS1_ENABLE_MASK BIT(2)|BIT(3)
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  30) #define EBI2_CS2_ENABLE_MASK BIT(4)
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  31) #define EBI2_CS3_ENABLE_MASK BIT(5)
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  32) #define EBI2_CS4_ENABLE_MASK BIT(6)|BIT(7)
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  33) #define EBI2_CS5_ENABLE_MASK BIT(8)|BIT(9)
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  34) #define EBI2_CSN_MASK GENMASK(9, 0)
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  35) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  36) #define EBI2_XMEM_CFG 0x0000 /* Power management etc */
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  37) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  38) /*
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  39)  * SLOW CSn CFG
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  40)  *
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  41)  * Bits 31-28: RECOVERY recovery cycles (0 = 1, 1 = 2 etc) this is the time the
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  42)  *             memory continues to drive the data bus after OE is de-asserted.
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  43)  *             Inserted when reading one CS and switching to another CS or read
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  44)  *             followed by write on the same CS. Valid values 0 thru 15.
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  45)  * Bits 27-24: WR_HOLD write hold cycles, these are extra cycles inserted after
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  46)  *             every write minimum 1. The data out is driven from the time WE is
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  47)  *             asserted until CS is asserted. With a hold of 1, the CS stays
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  48)  *             active for 1 extra cycle etc. Valid values 0 thru 15.
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  49)  * Bits 23-16: WR_DELTA initial latency for write cycles inserted for the first
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  50)  *             write to a page or burst memory
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  51)  * Bits 15-8:  RD_DELTA initial latency for read cycles inserted for the first
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  52)  *             read to a page or burst memory
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  53)  * Bits 7-4:   WR_WAIT number of wait cycles for every write access, 0=1 cycle
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  54)  *             so 1 thru 16 cycles.
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  55)  * Bits 3-0:   RD_WAIT number of wait cycles for every read access, 0=1 cycle
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  56)  *             so 1 thru 16 cycles.
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  57)  */
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  58) #define EBI2_XMEM_CS0_SLOW_CFG 0x0008
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  59) #define EBI2_XMEM_CS1_SLOW_CFG 0x000C
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  60) #define EBI2_XMEM_CS2_SLOW_CFG 0x0010
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  61) #define EBI2_XMEM_CS3_SLOW_CFG 0x0014
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  62) #define EBI2_XMEM_CS4_SLOW_CFG 0x0018
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  63) #define EBI2_XMEM_CS5_SLOW_CFG 0x001C
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  64) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  65) #define EBI2_XMEM_RECOVERY_SHIFT	28
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  66) #define EBI2_XMEM_WR_HOLD_SHIFT		24
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  67) #define EBI2_XMEM_WR_DELTA_SHIFT	16
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  68) #define EBI2_XMEM_RD_DELTA_SHIFT	8
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  69) #define EBI2_XMEM_WR_WAIT_SHIFT		4
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  70) #define EBI2_XMEM_RD_WAIT_SHIFT		0
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  71) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  72) /*
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  73)  * FAST CSn CFG
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  74)  * Bits 31-28: ?
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  75)  * Bits 27-24: RD_HOLD: the length in cycles of the first segment of a read
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  76)  *             transfer. For a single read trandfer this will be the time
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  77)  *             from CS assertion to OE assertion.
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  78)  * Bits 18-24: ?
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  79)  * Bits 17-16: ADV_OE_RECOVERY, the number of cycles elapsed before an OE
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  80)  *             assertion, with respect to the cycle where ADV is asserted.
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  81)  *             2 means 2 cycles between ADV and OE. Values 0, 1, 2 or 3.
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  82)  * Bits 5:     ADDR_HOLD_ENA, The address is held for an extra cycle to meet
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  83)  *             hold time requirements with ADV assertion.
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  84)  *
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  85)  * The manual mentions "write precharge cycles" and "precharge cycles".
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  86)  * We have not been able to figure out which bit fields these correspond to
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  87)  * in the hardware, or what valid values exist. The current hypothesis is that
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  88)  * this is something just used on the FAST chip selects. There is also a "byte
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  89)  * device enable" flag somewhere for 8bit memories.
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  90)  */
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  91) #define EBI2_XMEM_CS0_FAST_CFG 0x0028
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  92) #define EBI2_XMEM_CS1_FAST_CFG 0x002C
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  93) #define EBI2_XMEM_CS2_FAST_CFG 0x0030
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  94) #define EBI2_XMEM_CS3_FAST_CFG 0x0034
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  95) #define EBI2_XMEM_CS4_FAST_CFG 0x0038
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  96) #define EBI2_XMEM_CS5_FAST_CFG 0x003C
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  97) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  98) #define EBI2_XMEM_RD_HOLD_SHIFT		24
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200  99) #define EBI2_XMEM_ADV_OE_RECOVERY_SHIFT	16
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 100) #define EBI2_XMEM_ADDR_HOLD_ENA_SHIFT	5
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 101) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 102) /**
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 103)  * struct cs_data - struct with info on a chipselect setting
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 104)  * @enable_mask: mask to enable the chipselect in the EBI2 config
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 105)  * @slow_cfg0: offset to XMEMC slow CS config
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 106)  * @fast_cfg1: offset to XMEMC fast CS config
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 107)  */
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 108) struct cs_data {
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 109) 	u32 enable_mask;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 110) 	u16 slow_cfg;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 111) 	u16 fast_cfg;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 112) };
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 113) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 114) static const struct cs_data cs_info[] = {
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 115) 	{
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 116) 		/* CS0 */
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 117) 		.enable_mask = EBI2_CS0_ENABLE_MASK,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 118) 		.slow_cfg = EBI2_XMEM_CS0_SLOW_CFG,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 119) 		.fast_cfg = EBI2_XMEM_CS0_FAST_CFG,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 120) 	},
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 121) 	{
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 122) 		/* CS1 */
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 123) 		.enable_mask = EBI2_CS1_ENABLE_MASK,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 124) 		.slow_cfg = EBI2_XMEM_CS1_SLOW_CFG,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 125) 		.fast_cfg = EBI2_XMEM_CS1_FAST_CFG,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 126) 	},
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 127) 	{
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 128) 		/* CS2 */
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 129) 		.enable_mask = EBI2_CS2_ENABLE_MASK,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 130) 		.slow_cfg = EBI2_XMEM_CS2_SLOW_CFG,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 131) 		.fast_cfg = EBI2_XMEM_CS2_FAST_CFG,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 132) 	},
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 133) 	{
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 134) 		/* CS3 */
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 135) 		.enable_mask = EBI2_CS3_ENABLE_MASK,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 136) 		.slow_cfg = EBI2_XMEM_CS3_SLOW_CFG,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 137) 		.fast_cfg = EBI2_XMEM_CS3_FAST_CFG,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 138) 	},
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 139) 	{
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 140) 		/* CS4 */
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 141) 		.enable_mask = EBI2_CS4_ENABLE_MASK,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 142) 		.slow_cfg = EBI2_XMEM_CS4_SLOW_CFG,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 143) 		.fast_cfg = EBI2_XMEM_CS4_FAST_CFG,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 144) 	},
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 145) 	{
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 146) 		/* CS5 */
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 147) 		.enable_mask = EBI2_CS5_ENABLE_MASK,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 148) 		.slow_cfg = EBI2_XMEM_CS5_SLOW_CFG,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 149) 		.fast_cfg = EBI2_XMEM_CS5_FAST_CFG,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 150) 	},
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 151) };
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 152) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 153) /**
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 154)  * struct ebi2_xmem_prop - describes an XMEM config property
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 155)  * @prop: the device tree binding name
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 156)  * @max: maximum value for the property
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 157)  * @slowreg: true if this property is in the SLOW CS config register
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 158)  * else it is assumed to be in the FAST config register
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 159)  * @shift: the bit field start in the SLOW or FAST register for this
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 160)  * property
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 161)  */
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 162) struct ebi2_xmem_prop {
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 163) 	const char *prop;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 164) 	u32 max;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 165) 	bool slowreg;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 166) 	u16 shift;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 167) };
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 168) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 169) static const struct ebi2_xmem_prop xmem_props[] = {
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 170) 	{
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 171) 		.prop = "qcom,xmem-recovery-cycles",
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 172) 		.max = 15,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 173) 		.slowreg = true,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 174) 		.shift = EBI2_XMEM_RECOVERY_SHIFT,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 175) 	},
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 176) 	{
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 177) 		.prop = "qcom,xmem-write-hold-cycles",
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 178) 		.max = 15,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 179) 		.slowreg = true,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 180) 		.shift = EBI2_XMEM_WR_HOLD_SHIFT,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 181) 	},
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 182) 	{
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 183) 		.prop = "qcom,xmem-write-delta-cycles",
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 184) 		.max = 255,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 185) 		.slowreg = true,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 186) 		.shift = EBI2_XMEM_WR_DELTA_SHIFT,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 187) 	},
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 188) 	{
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 189) 		.prop = "qcom,xmem-read-delta-cycles",
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 190) 		.max = 255,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 191) 		.slowreg = true,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 192) 		.shift = EBI2_XMEM_RD_DELTA_SHIFT,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 193) 	},
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 194) 	{
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 195) 		.prop = "qcom,xmem-write-wait-cycles",
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 196) 		.max = 15,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 197) 		.slowreg = true,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 198) 		.shift = EBI2_XMEM_WR_WAIT_SHIFT,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 199) 	},
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 200) 	{
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 201) 		.prop = "qcom,xmem-read-wait-cycles",
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 202) 		.max = 15,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 203) 		.slowreg = true,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 204) 		.shift = EBI2_XMEM_RD_WAIT_SHIFT,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 205) 	},
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 206) 	{
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 207) 		.prop = "qcom,xmem-address-hold-enable",
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 208) 		.max = 1, /* boolean prop */
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 209) 		.slowreg = false,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 210) 		.shift = EBI2_XMEM_ADDR_HOLD_ENA_SHIFT,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 211) 	},
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 212) 	{
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 213) 		.prop = "qcom,xmem-adv-to-oe-recovery-cycles",
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 214) 		.max = 3,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 215) 		.slowreg = false,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 216) 		.shift = EBI2_XMEM_ADV_OE_RECOVERY_SHIFT,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 217) 	},
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 218) 	{
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 219) 		.prop = "qcom,xmem-read-hold-cycles",
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 220) 		.max = 15,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 221) 		.slowreg = false,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 222) 		.shift = EBI2_XMEM_RD_HOLD_SHIFT,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 223) 	},
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 224) };
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 225) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 226) static void qcom_ebi2_setup_chipselect(struct device_node *np,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 227) 				       struct device *dev,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 228) 				       void __iomem *ebi2_base,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 229) 				       void __iomem *ebi2_xmem,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 230) 				       u32 csindex)
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 231) {
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 232) 	const struct cs_data *csd;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 233) 	u32 slowcfg, fastcfg;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 234) 	u32 val;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 235) 	int ret;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 236) 	int i;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 237) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 238) 	csd = &cs_info[csindex];
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 239) 	val = readl(ebi2_base);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 240) 	val |= csd->enable_mask;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 241) 	writel(val, ebi2_base);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 242) 	dev_dbg(dev, "enabled CS%u\n", csindex);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 243) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 244) 	/* Next set up the XMEMC */
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 245) 	slowcfg = 0;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 246) 	fastcfg = 0;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 247) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 248) 	for (i = 0; i < ARRAY_SIZE(xmem_props); i++) {
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 249) 		const struct ebi2_xmem_prop *xp = &xmem_props[i];
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 250) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 251) 		/* All are regular u32 values */
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 252) 		ret = of_property_read_u32(np, xp->prop, &val);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 253) 		if (ret) {
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 254) 			dev_dbg(dev, "could not read %s for CS%d\n",
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 255) 				xp->prop, csindex);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 256) 			continue;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 257) 		}
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 258) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 259) 		/* First check boolean props */
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 260) 		if (xp->max == 1 && val) {
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 261) 			if (xp->slowreg)
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 262) 				slowcfg |= BIT(xp->shift);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 263) 			else
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 264) 				fastcfg |= BIT(xp->shift);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 265) 			dev_dbg(dev, "set %s flag\n", xp->prop);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 266) 			continue;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 267) 		}
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 268) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 269) 		/* We're dealing with an u32 */
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 270) 		if (val > xp->max) {
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 271) 			dev_err(dev,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 272) 				"too high value for %s: %u, capped at %u\n",
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 273) 				xp->prop, val, xp->max);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 274) 			val = xp->max;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 275) 		}
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 276) 		if (xp->slowreg)
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 277) 			slowcfg |= (val << xp->shift);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 278) 		else
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 279) 			fastcfg |= (val << xp->shift);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 280) 		dev_dbg(dev, "set %s to %u\n", xp->prop, val);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 281) 	}
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 282) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 283) 	dev_info(dev, "CS%u: SLOW CFG 0x%08x, FAST CFG 0x%08x\n",
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 284) 		 csindex, slowcfg, fastcfg);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 285) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 286) 	if (slowcfg)
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 287) 		writel(slowcfg, ebi2_xmem + csd->slow_cfg);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 288) 	if (fastcfg)
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 289) 		writel(fastcfg, ebi2_xmem + csd->fast_cfg);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 290) }
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 291) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 292) static int qcom_ebi2_probe(struct platform_device *pdev)
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 293) {
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 294) 	struct device_node *np = pdev->dev.of_node;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 295) 	struct device_node *child;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 296) 	struct device *dev = &pdev->dev;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 297) 	struct resource *res;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 298) 	void __iomem *ebi2_base;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 299) 	void __iomem *ebi2_xmem;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 300) 	struct clk *ebi2xclk;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 301) 	struct clk *ebi2clk;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 302) 	bool have_children = false;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 303) 	u32 val;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 304) 	int ret;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 305) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 306) 	ebi2xclk = devm_clk_get(dev, "ebi2x");
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 307) 	if (IS_ERR(ebi2xclk))
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 308) 		return PTR_ERR(ebi2xclk);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 309) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 310) 	ret = clk_prepare_enable(ebi2xclk);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 311) 	if (ret) {
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 312) 		dev_err(dev, "could not enable EBI2X clk (%d)\n", ret);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 313) 		return ret;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 314) 	}
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 315) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 316) 	ebi2clk = devm_clk_get(dev, "ebi2");
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 317) 	if (IS_ERR(ebi2clk)) {
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 318) 		ret = PTR_ERR(ebi2clk);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 319) 		goto err_disable_2x_clk;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 320) 	}
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 321) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 322) 	ret = clk_prepare_enable(ebi2clk);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 323) 	if (ret) {
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 324) 		dev_err(dev, "could not enable EBI2 clk\n");
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 325) 		goto err_disable_2x_clk;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 326) 	}
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 327) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 328) 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 329) 	ebi2_base = devm_ioremap_resource(dev, res);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 330) 	if (IS_ERR(ebi2_base)) {
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 331) 		ret = PTR_ERR(ebi2_base);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 332) 		goto err_disable_clk;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 333) 	}
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 334) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 335) 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 336) 	ebi2_xmem = devm_ioremap_resource(dev, res);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 337) 	if (IS_ERR(ebi2_xmem)) {
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 338) 		ret = PTR_ERR(ebi2_xmem);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 339) 		goto err_disable_clk;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 340) 	}
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 341) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 342) 	/* Allegedly this turns the power save mode off */
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 343) 	writel(0UL, ebi2_xmem + EBI2_XMEM_CFG);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 344) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 345) 	/* Disable all chipselects */
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 346) 	val = readl(ebi2_base);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 347) 	val &= ~EBI2_CSN_MASK;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 348) 	writel(val, ebi2_base);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 349) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 350) 	/* Walk over the child nodes and see what chipselects we use */
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 351) 	for_each_available_child_of_node(np, child) {
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 352) 		u32 csindex;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 353) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 354) 		/* Figure out the chipselect */
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 355) 		ret = of_property_read_u32(child, "reg", &csindex);
ac6ad7c2a862d (Pan Bian        2021-01-21 03:49:07 -0800 356) 		if (ret) {
ac6ad7c2a862d (Pan Bian        2021-01-21 03:49:07 -0800 357) 			of_node_put(child);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 358) 			return ret;
ac6ad7c2a862d (Pan Bian        2021-01-21 03:49:07 -0800 359) 		}
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 360) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 361) 		if (csindex > 5) {
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 362) 			dev_err(dev,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 363) 				"invalid chipselect %u, we only support 0-5\n",
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 364) 				csindex);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 365) 			continue;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 366) 		}
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 367) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 368) 		qcom_ebi2_setup_chipselect(child,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 369) 					   dev,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 370) 					   ebi2_base,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 371) 					   ebi2_xmem,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 372) 					   csindex);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 373) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 374) 		/* We have at least one child */
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 375) 		have_children = true;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 376) 	}
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 377) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 378) 	if (have_children)
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 379) 		return of_platform_default_populate(np, NULL, dev);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 380) 	return 0;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 381) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 382) err_disable_clk:
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 383) 	clk_disable_unprepare(ebi2clk);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 384) err_disable_2x_clk:
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 385) 	clk_disable_unprepare(ebi2xclk);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 386) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 387) 	return ret;
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 388) }
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 389) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 390) static const struct of_device_id qcom_ebi2_of_match[] = {
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 391) 	{ .compatible = "qcom,msm8660-ebi2", },
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 392) 	{ .compatible = "qcom,apq8060-ebi2", },
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 393) 	{ }
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 394) };
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 395) 
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 396) static struct platform_driver qcom_ebi2_driver = {
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 397) 	.probe = qcom_ebi2_probe,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 398) 	.driver = {
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 399) 		.name = "qcom-ebi2",
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 400) 		.of_match_table = qcom_ebi2_of_match,
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 401) 	},
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 402) };
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 403) module_platform_driver(qcom_ebi2_driver);
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 404) MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 405) MODULE_DESCRIPTION("Qualcomm EBI2 driver");
335a127548081 (Linus Walleij   2016-07-08 00:11:02 +0200 406) MODULE_LICENSE("GPL");