2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation.
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
11 * Copyright (C) 2012 ARM Limited
14 #include <linux/err.h>
15 #include <linux/gpio.h>
17 #include <linux/leds.h>
18 #include <linux/of_address.h>
19 #include <linux/of_platform.h>
20 #include <linux/platform_device.h>
21 #include <linux/regulator/driver.h>
22 #include <linux/sched.h>
23 #include <linux/slab.h>
24 #include <linux/stat.h>
25 #include <linux/timer.h>
26 #include <linux/vexpress.h>
31 #define SYS_100HZ 0x024
32 #define SYS_FLAGS 0x030
33 #define SYS_FLAGSSET 0x030
34 #define SYS_FLAGSCLR 0x034
35 #define SYS_NVFLAGS 0x038
36 #define SYS_NVFLAGSSET 0x038
37 #define SYS_NVFLAGSCLR 0x03c
39 #define SYS_FLASH 0x04c
40 #define SYS_CFGSW 0x058
41 #define SYS_24MHZ 0x05c
42 #define SYS_MISC 0x060
44 #define SYS_PROCID0 0x084
45 #define SYS_PROCID1 0x088
46 #define SYS_CFGDATA 0x0a0
47 #define SYS_CFGCTRL 0x0a4
48 #define SYS_CFGSTAT 0x0a8
50 #define SYS_HBI_MASK 0xfff
51 #define SYS_ID_HBI_SHIFT 16
52 #define SYS_PROCIDx_HBI_SHIFT 0
54 #define SYS_LED_LED(n) (1 << (n))
56 #define SYS_MCI_CARDIN (1 << 0)
57 #define SYS_MCI_WPROT (1 << 1)
59 #define SYS_FLASH_WPn (1 << 0)
61 #define SYS_MISC_MASTERSITE (1 << 14)
63 #define SYS_CFGCTRL_START (1 << 31)
64 #define SYS_CFGCTRL_WRITE (1 << 30)
65 #define SYS_CFGCTRL_DCC(n) (((n) & 0xf) << 26)
66 #define SYS_CFGCTRL_FUNC(n) (((n) & 0x3f) << 20)
67 #define SYS_CFGCTRL_SITE(n) (((n) & 0x3) << 16)
68 #define SYS_CFGCTRL_POSITION(n) (((n) & 0xf) << 12)
69 #define SYS_CFGCTRL_DEVICE(n) (((n) & 0xfff) << 0)
71 #define SYS_CFGSTAT_ERR (1 << 1)
72 #define SYS_CFGSTAT_COMPLETE (1 << 0)
75 static void __iomem
*vexpress_sysreg_base
;
76 static struct device
*vexpress_sysreg_dev
;
77 static LIST_HEAD(vexpress_sysreg_config_funcs
);
78 static struct device
*vexpress_sysreg_config_bridge
;
81 static int vexpress_sysreg_get_master(void)
83 if (readl(vexpress_sysreg_base
+ SYS_MISC
) & SYS_MISC_MASTERSITE
)
84 return VEXPRESS_SITE_DB2
;
86 return VEXPRESS_SITE_DB1
;
89 void vexpress_flags_set(u32 data
)
91 writel(~0, vexpress_sysreg_base
+ SYS_FLAGSCLR
);
92 writel(data
, vexpress_sysreg_base
+ SYS_FLAGSSET
);
95 u32
vexpress_get_procid(int site
)
97 if (site
== VEXPRESS_SITE_MASTER
)
98 site
= vexpress_sysreg_get_master();
100 return readl(vexpress_sysreg_base
+ (site
== VEXPRESS_SITE_DB1
?
101 SYS_PROCID0
: SYS_PROCID1
));
104 u32
vexpress_get_hbi(int site
)
109 case VEXPRESS_SITE_MB
:
110 id
= readl(vexpress_sysreg_base
+ SYS_ID
);
111 return (id
>> SYS_ID_HBI_SHIFT
) & SYS_HBI_MASK
;
112 case VEXPRESS_SITE_MASTER
:
113 case VEXPRESS_SITE_DB1
:
114 case VEXPRESS_SITE_DB2
:
115 id
= vexpress_get_procid(site
);
116 return (id
>> SYS_PROCIDx_HBI_SHIFT
) & SYS_HBI_MASK
;
122 void __iomem
*vexpress_get_24mhz_clock_base(void)
124 return vexpress_sysreg_base
+ SYS_24MHZ
;
128 struct vexpress_sysreg_config_func
{
129 struct list_head list
;
130 struct regmap
*regmap
;
132 u32
template[0]; /* Keep this last */
135 static int vexpress_sysreg_config_exec(struct vexpress_sysreg_config_func
*func
,
136 int index
, bool write
, u32
*data
)
142 if (WARN_ON(!vexpress_sysreg_base
))
145 if (WARN_ON(index
> func
->num_templates
))
148 command
= readl(vexpress_sysreg_base
+ SYS_CFGCTRL
);
149 if (WARN_ON(command
& SYS_CFGCTRL_START
))
152 command
= func
->template[index
];
153 command
|= SYS_CFGCTRL_START
;
154 command
|= write
? SYS_CFGCTRL_WRITE
: 0;
156 /* Use a canary for reads */
160 dev_dbg(vexpress_sysreg_dev
, "command %x, data %x\n",
162 writel(*data
, vexpress_sysreg_base
+ SYS_CFGDATA
);
163 writel(0, vexpress_sysreg_base
+ SYS_CFGSTAT
);
164 writel(command
, vexpress_sysreg_base
+ SYS_CFGCTRL
);
167 /* The operation can take ages... Go to sleep, 100us initially */
171 set_current_state(TASK_INTERRUPTIBLE
);
172 schedule_timeout(usecs_to_jiffies(timeout
));
173 if (signal_pending(current
))
176 status
= readl(vexpress_sysreg_base
+ SYS_CFGSTAT
);
177 if (status
& SYS_CFGSTAT_ERR
)
182 } while (--tries
&& !(status
& SYS_CFGSTAT_COMPLETE
));
183 if (WARN_ON_ONCE(!tries
))
187 *data
= readl(vexpress_sysreg_base
+ SYS_CFGDATA
);
188 dev_dbg(vexpress_sysreg_dev
, "func %p, read data %x\n",
195 static int vexpress_sysreg_config_read(void *context
, unsigned int index
,
198 struct vexpress_sysreg_config_func
*func
= context
;
200 return vexpress_sysreg_config_exec(func
, index
, false, val
);
203 static int vexpress_sysreg_config_write(void *context
, unsigned int index
,
206 struct vexpress_sysreg_config_func
*func
= context
;
208 return vexpress_sysreg_config_exec(func
, index
, true, &val
);
211 struct regmap_config vexpress_sysreg_regmap_config
= {
212 .lock
= vexpress_config_lock
,
213 .unlock
= vexpress_config_unlock
,
216 .reg_read
= vexpress_sysreg_config_read
,
217 .reg_write
= vexpress_sysreg_config_write
,
218 .reg_format_endian
= REGMAP_ENDIAN_LITTLE
,
219 .val_format_endian
= REGMAP_ENDIAN_LITTLE
,
222 static struct regmap
*vexpress_sysreg_config_regmap_init(struct device
*dev
,
225 struct platform_device
*pdev
= to_platform_device(dev
);
226 struct vexpress_sysreg_config_func
*func
;
227 struct property
*prop
;
228 const __be32
*val
= NULL
;
229 __be32 energy_quirk
[4];
231 u32 site
, position
, dcc
;
236 err
= vexpress_config_get_topo(dev
->of_node
, &site
, &position
,
241 prop
= of_find_property(dev
->of_node
,
242 "arm,vexpress-sysreg,func", NULL
);
244 return ERR_PTR(-EINVAL
);
246 num
= prop
->length
/ sizeof(u32
) / 2;
249 if (pdev
->num_resources
!= 1 ||
250 pdev
->resource
[0].flags
!= IORESOURCE_BUS
)
251 return ERR_PTR(-EFAULT
);
253 site
= pdev
->resource
[0].start
;
254 if (site
== VEXPRESS_SITE_MASTER
)
255 site
= vexpress_sysreg_get_master();
262 * "arm,vexpress-energy" function used to be described
263 * by its first device only, now it requires both
265 if (num
== 1 && of_device_is_compatible(dev
->of_node
,
266 "arm,vexpress-energy")) {
268 energy_quirk
[0] = *val
;
269 energy_quirk
[2] = *val
++;
270 energy_quirk
[1] = *val
;
271 energy_quirk
[3] = cpu_to_be32(be32_to_cpup(val
) + 1);
275 func
= kzalloc(sizeof(*func
) + sizeof(*func
->template) * num
,
280 func
->num_templates
= num
;
282 for (i
= 0; i
< num
; i
++) {
283 u32 function
, device
;
286 function
= be32_to_cpup(val
++);
287 device
= be32_to_cpup(val
++);
289 function
= pdev
->resource
[0].end
;
293 dev_dbg(dev
, "func %p: %u/%u/%u/%u/%u\n",
294 func
, site
, position
, dcc
,
297 func
->template[i
] = SYS_CFGCTRL_DCC(dcc
);
298 func
->template[i
] |= SYS_CFGCTRL_SITE(site
);
299 func
->template[i
] |= SYS_CFGCTRL_POSITION(position
);
300 func
->template[i
] |= SYS_CFGCTRL_FUNC(function
);
301 func
->template[i
] |= SYS_CFGCTRL_DEVICE(device
);
304 vexpress_sysreg_regmap_config
.max_register
= num
- 1;
306 func
->regmap
= regmap_init(dev
, NULL
, func
,
307 &vexpress_sysreg_regmap_config
);
309 if (IS_ERR(func
->regmap
))
312 list_add(&func
->list
, &vexpress_sysreg_config_funcs
);
317 static void vexpress_sysreg_config_regmap_exit(struct regmap
*regmap
,
320 struct vexpress_sysreg_config_func
*func
, *tmp
;
324 list_for_each_entry_safe(func
, tmp
, &vexpress_sysreg_config_funcs
,
326 if (func
->regmap
== regmap
) {
327 list_del(&vexpress_sysreg_config_funcs
);
334 static struct vexpress_config_bridge_ops vexpress_sysreg_config_bridge_ops
= {
335 .regmap_init
= vexpress_sysreg_config_regmap_init
,
336 .regmap_exit
= vexpress_sysreg_config_regmap_exit
,
339 int vexpress_sysreg_config_device_register(struct platform_device
*pdev
)
341 pdev
->dev
.parent
= vexpress_sysreg_config_bridge
;
343 return platform_device_register(pdev
);
347 void __init
vexpress_sysreg_early_init(void __iomem
*base
)
349 vexpress_sysreg_base
= base
;
350 vexpress_config_set_master(vexpress_sysreg_get_master());
353 void __init
vexpress_sysreg_of_early_init(void)
355 struct device_node
*node
;
357 if (vexpress_sysreg_base
)
360 node
= of_find_compatible_node(NULL
, NULL
, "arm,vexpress-sysreg");
364 vexpress_sysreg_base
= of_iomap(node
, 0);
365 if (WARN_ON(!vexpress_sysreg_base
))
368 vexpress_config_set_master(vexpress_sysreg_get_master());
372 #ifdef CONFIG_GPIOLIB
374 #define VEXPRESS_SYSREG_GPIO(_name, _reg, _value) \
375 [VEXPRESS_GPIO_##_name] = { \
377 .value = _reg##_##_value, \
380 static struct vexpress_sysreg_gpio
{
383 } vexpress_sysreg_gpios
[] = {
384 VEXPRESS_SYSREG_GPIO(MMC_CARDIN
, SYS_MCI
, CARDIN
),
385 VEXPRESS_SYSREG_GPIO(MMC_WPROT
, SYS_MCI
, WPROT
),
386 VEXPRESS_SYSREG_GPIO(FLASH_WPn
, SYS_FLASH
, WPn
),
387 VEXPRESS_SYSREG_GPIO(LED0
, SYS_LED
, LED(0)),
388 VEXPRESS_SYSREG_GPIO(LED1
, SYS_LED
, LED(1)),
389 VEXPRESS_SYSREG_GPIO(LED2
, SYS_LED
, LED(2)),
390 VEXPRESS_SYSREG_GPIO(LED3
, SYS_LED
, LED(3)),
391 VEXPRESS_SYSREG_GPIO(LED4
, SYS_LED
, LED(4)),
392 VEXPRESS_SYSREG_GPIO(LED5
, SYS_LED
, LED(5)),
393 VEXPRESS_SYSREG_GPIO(LED6
, SYS_LED
, LED(6)),
394 VEXPRESS_SYSREG_GPIO(LED7
, SYS_LED
, LED(7)),
397 static int vexpress_sysreg_gpio_direction_input(struct gpio_chip
*chip
,
403 static int vexpress_sysreg_gpio_get(struct gpio_chip
*chip
,
406 struct vexpress_sysreg_gpio
*gpio
= &vexpress_sysreg_gpios
[offset
];
407 u32 reg_value
= readl(vexpress_sysreg_base
+ gpio
->reg
);
409 return !!(reg_value
& gpio
->value
);
412 static void vexpress_sysreg_gpio_set(struct gpio_chip
*chip
,
413 unsigned offset
, int value
)
415 struct vexpress_sysreg_gpio
*gpio
= &vexpress_sysreg_gpios
[offset
];
416 u32 reg_value
= readl(vexpress_sysreg_base
+ gpio
->reg
);
419 reg_value
|= gpio
->value
;
421 reg_value
&= ~gpio
->value
;
423 writel(reg_value
, vexpress_sysreg_base
+ gpio
->reg
);
426 static int vexpress_sysreg_gpio_direction_output(struct gpio_chip
*chip
,
427 unsigned offset
, int value
)
429 vexpress_sysreg_gpio_set(chip
, offset
, value
);
434 static struct gpio_chip vexpress_sysreg_gpio_chip
= {
435 .label
= "vexpress-sysreg",
436 .direction_input
= vexpress_sysreg_gpio_direction_input
,
437 .direction_output
= vexpress_sysreg_gpio_direction_output
,
438 .get
= vexpress_sysreg_gpio_get
,
439 .set
= vexpress_sysreg_gpio_set
,
440 .ngpio
= ARRAY_SIZE(vexpress_sysreg_gpios
),
445 #define VEXPRESS_SYSREG_GREEN_LED(_name, _default_trigger, _gpio) \
447 .name = "v2m:green:"_name, \
448 .default_trigger = _default_trigger, \
449 .gpio = VEXPRESS_GPIO_##_gpio, \
452 struct gpio_led vexpress_sysreg_leds
[] = {
453 VEXPRESS_SYSREG_GREEN_LED("user1", "heartbeat", LED0
),
454 VEXPRESS_SYSREG_GREEN_LED("user2", "mmc0", LED1
),
455 VEXPRESS_SYSREG_GREEN_LED("user3", "cpu0", LED2
),
456 VEXPRESS_SYSREG_GREEN_LED("user4", "cpu1", LED3
),
457 VEXPRESS_SYSREG_GREEN_LED("user5", "cpu2", LED4
),
458 VEXPRESS_SYSREG_GREEN_LED("user6", "cpu3", LED5
),
459 VEXPRESS_SYSREG_GREEN_LED("user7", "cpu4", LED6
),
460 VEXPRESS_SYSREG_GREEN_LED("user8", "cpu5", LED7
),
463 struct gpio_led_platform_data vexpress_sysreg_leds_pdata
= {
464 .num_leds
= ARRAY_SIZE(vexpress_sysreg_leds
),
465 .leds
= vexpress_sysreg_leds
,
471 static ssize_t
vexpress_sysreg_sys_id_show(struct device
*dev
,
472 struct device_attribute
*attr
, char *buf
)
474 return sprintf(buf
, "0x%08x\n", readl(vexpress_sysreg_base
+ SYS_ID
));
477 DEVICE_ATTR(sys_id
, S_IRUGO
, vexpress_sysreg_sys_id_show
, NULL
);
479 static int vexpress_sysreg_probe(struct platform_device
*pdev
)
482 struct resource
*res
= platform_get_resource(pdev
,
485 if (!devm_request_mem_region(&pdev
->dev
, res
->start
,
486 resource_size(res
), pdev
->name
)) {
487 dev_err(&pdev
->dev
, "Failed to request memory region!\n");
491 if (!vexpress_sysreg_base
)
492 vexpress_sysreg_base
= devm_ioremap(&pdev
->dev
, res
->start
,
495 if (!vexpress_sysreg_base
) {
496 dev_err(&pdev
->dev
, "Failed to obtain base address!\n");
500 vexpress_config_set_master(vexpress_sysreg_get_master());
501 vexpress_sysreg_dev
= &pdev
->dev
;
503 #ifdef CONFIG_GPIOLIB
504 vexpress_sysreg_gpio_chip
.dev
= &pdev
->dev
;
505 err
= gpiochip_add(&vexpress_sysreg_gpio_chip
);
507 dev_err(&pdev
->dev
, "Failed to register GPIO chip! (%d)\n",
512 platform_device_register_data(vexpress_sysreg_dev
, "leds-gpio",
513 PLATFORM_DEVID_AUTO
, &vexpress_sysreg_leds_pdata
,
514 sizeof(vexpress_sysreg_leds_pdata
));
517 vexpress_sysreg_config_bridge
= vexpress_config_bridge_register(
518 &pdev
->dev
, &vexpress_sysreg_config_bridge_ops
, NULL
);
519 WARN_ON(!vexpress_sysreg_config_bridge
);
521 device_create_file(vexpress_sysreg_dev
, &dev_attr_sys_id
);
526 static const struct of_device_id vexpress_sysreg_match
[] = {
527 { .compatible
= "arm,vexpress-sysreg", },
531 static struct platform_driver vexpress_sysreg_driver
= {
533 .name
= "vexpress-sysreg",
534 .of_match_table
= vexpress_sysreg_match
,
536 .probe
= vexpress_sysreg_probe
,
539 static int __init
vexpress_sysreg_init(void)
541 struct device_node
*node
;
543 /* Need the sysreg early, before any other device... */
544 for_each_matching_node(node
, vexpress_sysreg_match
)
545 of_platform_device_create(node
, NULL
, NULL
);
547 return platform_driver_register(&vexpress_sysreg_driver
);
549 core_initcall(vexpress_sysreg_init
);