linux/arch/mips/pic32/pic32mzda/config.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Purna Chandra Mandal, purna.mandal@microchip.com
   4 * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
   5 */
   6#include <linux/init.h>
   7#include <linux/io.h>
   8#include <linux/of_platform.h>
   9
  10#include <asm/mach-pic32/pic32.h>
  11
  12#include "pic32mzda.h"
  13
  14#define PIC32_CFGCON    0x0000
  15#define PIC32_DEVID     0x0020
  16#define PIC32_SYSKEY    0x0030
  17#define PIC32_CFGEBIA   0x00c0
  18#define PIC32_CFGEBIC   0x00d0
  19#define PIC32_CFGCON2   0x00f0
  20#define PIC32_RCON      0x1240
  21
  22static void __iomem *pic32_conf_base;
  23static DEFINE_SPINLOCK(config_lock);
  24static u32 pic32_reset_status;
  25
  26static u32 pic32_conf_get_reg_field(u32 offset, u32 rshift, u32 mask)
  27{
  28        u32 v;
  29
  30        v = readl(pic32_conf_base + offset);
  31        v >>= rshift;
  32        v &= mask;
  33
  34        return v;
  35}
  36
  37static u32 pic32_conf_modify_atomic(u32 offset, u32 mask, u32 set)
  38{
  39        u32 v;
  40        unsigned long flags;
  41
  42        spin_lock_irqsave(&config_lock, flags);
  43        v = readl(pic32_conf_base + offset);
  44        v &= ~mask;
  45        v |= (set & mask);
  46        writel(v, pic32_conf_base + offset);
  47        spin_unlock_irqrestore(&config_lock, flags);
  48
  49        return 0;
  50}
  51
  52int pic32_enable_lcd(void)
  53{
  54        return pic32_conf_modify_atomic(PIC32_CFGCON2, BIT(31), BIT(31));
  55}
  56
  57int pic32_disable_lcd(void)
  58{
  59        return pic32_conf_modify_atomic(PIC32_CFGCON2, BIT(31), 0);
  60}
  61
  62int pic32_set_lcd_mode(int mode)
  63{
  64        u32 mask = mode ? BIT(30) : 0;
  65
  66        return pic32_conf_modify_atomic(PIC32_CFGCON2, BIT(30), mask);
  67}
  68
  69int pic32_set_sdhci_adma_fifo_threshold(u32 rthrsh, u32 wthrsh)
  70{
  71        u32 clr, set;
  72
  73        clr = (0x3ff << 4) | (0x3ff << 16);
  74        set = (rthrsh << 4) | (wthrsh << 16);
  75        return pic32_conf_modify_atomic(PIC32_CFGCON2, clr, set);
  76}
  77
  78void pic32_syskey_unlock_debug(const char *func, const ulong line)
  79{
  80        void __iomem *syskey = pic32_conf_base + PIC32_SYSKEY;
  81
  82        pr_debug("%s: called from %s:%lu\n", __func__, func, line);
  83        writel(0x00000000, syskey);
  84        writel(0xAA996655, syskey);
  85        writel(0x556699AA, syskey);
  86}
  87
  88static u32 pic32_get_device_id(void)
  89{
  90        return pic32_conf_get_reg_field(PIC32_DEVID, 0, 0x0fffffff);
  91}
  92
  93static u32 pic32_get_device_version(void)
  94{
  95        return pic32_conf_get_reg_field(PIC32_DEVID, 28, 0xf);
  96}
  97
  98u32 pic32_get_boot_status(void)
  99{
 100        return pic32_reset_status;
 101}
 102EXPORT_SYMBOL(pic32_get_boot_status);
 103
 104void __init pic32_config_init(void)
 105{
 106        pic32_conf_base = ioremap(PIC32_BASE_CONFIG, 0x110);
 107        if (!pic32_conf_base)
 108                panic("pic32: config base not mapped");
 109
 110        /* Boot Status */
 111        pic32_reset_status = readl(pic32_conf_base + PIC32_RCON);
 112        writel(-1, PIC32_CLR(pic32_conf_base + PIC32_RCON));
 113
 114        /* Device Inforation */
 115        pr_info("Device Id: 0x%08x, Device Ver: 0x%04x\n",
 116                pic32_get_device_id(),
 117                pic32_get_device_version());
 118}
 119