linux/arch/powerpc/platforms/powernv/opal-lpc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * PowerNV LPC bus handling.
   4 *
   5 * Copyright 2013 IBM Corp.
   6 */
   7
   8#include <linux/kernel.h>
   9#include <linux/of.h>
  10#include <linux/bug.h>
  11#include <linux/io.h>
  12#include <linux/slab.h>
  13
  14#include <asm/machdep.h>
  15#include <asm/firmware.h>
  16#include <asm/opal.h>
  17#include <asm/prom.h>
  18#include <linux/uaccess.h>
  19#include <asm/debugfs.h>
  20#include <asm/isa-bridge.h>
  21
  22static int opal_lpc_chip_id = -1;
  23
  24static u8 opal_lpc_inb(unsigned long port)
  25{
  26        int64_t rc;
  27        __be32 data;
  28
  29        if (opal_lpc_chip_id < 0 || port > 0xffff)
  30                return 0xff;
  31        rc = opal_lpc_read(opal_lpc_chip_id, OPAL_LPC_IO, port, &data, 1);
  32        return rc ? 0xff : be32_to_cpu(data);
  33}
  34
  35static __le16 __opal_lpc_inw(unsigned long port)
  36{
  37        int64_t rc;
  38        __be32 data;
  39
  40        if (opal_lpc_chip_id < 0 || port > 0xfffe)
  41                return 0xffff;
  42        if (port & 1)
  43                return (__le16)opal_lpc_inb(port) << 8 | opal_lpc_inb(port + 1);
  44        rc = opal_lpc_read(opal_lpc_chip_id, OPAL_LPC_IO, port, &data, 2);
  45        return rc ? 0xffff : be32_to_cpu(data);
  46}
  47static u16 opal_lpc_inw(unsigned long port)
  48{
  49        return le16_to_cpu(__opal_lpc_inw(port));
  50}
  51
  52static __le32 __opal_lpc_inl(unsigned long port)
  53{
  54        int64_t rc;
  55        __be32 data;
  56
  57        if (opal_lpc_chip_id < 0 || port > 0xfffc)
  58                return 0xffffffff;
  59        if (port & 3)
  60                return (__le32)opal_lpc_inb(port    ) << 24 |
  61                       (__le32)opal_lpc_inb(port + 1) << 16 |
  62                       (__le32)opal_lpc_inb(port + 2) <<  8 |
  63                               opal_lpc_inb(port + 3);
  64        rc = opal_lpc_read(opal_lpc_chip_id, OPAL_LPC_IO, port, &data, 4);
  65        return rc ? 0xffffffff : be32_to_cpu(data);
  66}
  67
  68static u32 opal_lpc_inl(unsigned long port)
  69{
  70        return le32_to_cpu(__opal_lpc_inl(port));
  71}
  72
  73static void opal_lpc_outb(u8 val, unsigned long port)
  74{
  75        if (opal_lpc_chip_id < 0 || port > 0xffff)
  76                return;
  77        opal_lpc_write(opal_lpc_chip_id, OPAL_LPC_IO, port, val, 1);
  78}
  79
  80static void __opal_lpc_outw(__le16 val, unsigned long port)
  81{
  82        if (opal_lpc_chip_id < 0 || port > 0xfffe)
  83                return;
  84        if (port & 1) {
  85                opal_lpc_outb(val >> 8, port);
  86                opal_lpc_outb(val     , port + 1);
  87                return;
  88        }
  89        opal_lpc_write(opal_lpc_chip_id, OPAL_LPC_IO, port, val, 2);
  90}
  91
  92static void opal_lpc_outw(u16 val, unsigned long port)
  93{
  94        __opal_lpc_outw(cpu_to_le16(val), port);
  95}
  96
  97static void __opal_lpc_outl(__le32 val, unsigned long port)
  98{
  99        if (opal_lpc_chip_id < 0 || port > 0xfffc)
 100                return;
 101        if (port & 3) {
 102                opal_lpc_outb(val >> 24, port);
 103                opal_lpc_outb(val >> 16, port + 1);
 104                opal_lpc_outb(val >>  8, port + 2);
 105                opal_lpc_outb(val      , port + 3);
 106                return;
 107        }
 108        opal_lpc_write(opal_lpc_chip_id, OPAL_LPC_IO, port, val, 4);
 109}
 110
 111static void opal_lpc_outl(u32 val, unsigned long port)
 112{
 113        __opal_lpc_outl(cpu_to_le32(val), port);
 114}
 115
 116static void opal_lpc_insb(unsigned long p, void *b, unsigned long c)
 117{
 118        u8 *ptr = b;
 119
 120        while(c--)
 121                *(ptr++) = opal_lpc_inb(p);
 122}
 123
 124static void opal_lpc_insw(unsigned long p, void *b, unsigned long c)
 125{
 126        __le16 *ptr = b;
 127
 128        while(c--)
 129                *(ptr++) = __opal_lpc_inw(p);
 130}
 131
 132static void opal_lpc_insl(unsigned long p, void *b, unsigned long c)
 133{
 134        __le32 *ptr = b;
 135
 136        while(c--)
 137                *(ptr++) = __opal_lpc_inl(p);
 138}
 139
 140static void opal_lpc_outsb(unsigned long p, const void *b, unsigned long c)
 141{
 142        const u8 *ptr = b;
 143
 144        while(c--)
 145                opal_lpc_outb(*(ptr++), p);
 146}
 147
 148static void opal_lpc_outsw(unsigned long p, const void *b, unsigned long c)
 149{
 150        const __le16 *ptr = b;
 151
 152        while(c--)
 153                __opal_lpc_outw(*(ptr++), p);
 154}
 155
 156static void opal_lpc_outsl(unsigned long p, const void *b, unsigned long c)
 157{
 158        const __le32 *ptr = b;
 159
 160        while(c--)
 161                __opal_lpc_outl(*(ptr++), p);
 162}
 163
 164static const struct ppc_pci_io opal_lpc_io = {
 165        .inb    = opal_lpc_inb,
 166        .inw    = opal_lpc_inw,
 167        .inl    = opal_lpc_inl,
 168        .outb   = opal_lpc_outb,
 169        .outw   = opal_lpc_outw,
 170        .outl   = opal_lpc_outl,
 171        .insb   = opal_lpc_insb,
 172        .insw   = opal_lpc_insw,
 173        .insl   = opal_lpc_insl,
 174        .outsb  = opal_lpc_outsb,
 175        .outsw  = opal_lpc_outsw,
 176        .outsl  = opal_lpc_outsl,
 177};
 178
 179#ifdef CONFIG_DEBUG_FS
 180struct lpc_debugfs_entry {
 181        enum OpalLPCAddressType lpc_type;
 182};
 183
 184static ssize_t lpc_debug_read(struct file *filp, char __user *ubuf,
 185                              size_t count, loff_t *ppos)
 186{
 187        struct lpc_debugfs_entry *lpc = filp->private_data;
 188        u32 data, pos, len, todo;
 189        int rc;
 190
 191        if (!access_ok(ubuf, count))
 192                return -EFAULT;
 193
 194        todo = count;
 195        while (todo) {
 196                pos = *ppos;
 197
 198                /*
 199                 * Select access size based on count and alignment and
 200                 * access type. IO and MEM only support byte acceses,
 201                 * FW supports all 3.
 202                 */
 203                len = 1;
 204                if (lpc->lpc_type == OPAL_LPC_FW) {
 205                        if (todo > 3 && (pos & 3) == 0)
 206                                len = 4;
 207                        else if (todo > 1 && (pos & 1) == 0)
 208                                len = 2;
 209                }
 210                rc = opal_lpc_read(opal_lpc_chip_id, lpc->lpc_type, pos,
 211                                   &data, len);
 212                if (rc)
 213                        return -ENXIO;
 214
 215                /*
 216                 * Now there is some trickery with the data returned by OPAL
 217                 * as it's the desired data right justified in a 32-bit BE
 218                 * word.
 219                 *
 220                 * This is a very bad interface and I'm to blame for it :-(
 221                 *
 222                 * So we can't just apply a 32-bit swap to what comes from OPAL,
 223                 * because user space expects the *bytes* to be in their proper
 224                 * respective positions (ie, LPC position).
 225                 *
 226                 * So what we really want to do here is to shift data right
 227                 * appropriately on a LE kernel.
 228                 *
 229                 * IE. If the LPC transaction has bytes B0, B1, B2 and B3 in that
 230                 * order, we have in memory written to by OPAL at the "data"
 231                 * pointer:
 232                 *
 233                 *               Bytes:      OPAL "data"   LE "data"
 234                 *   32-bit:   B0 B1 B2 B3   B0B1B2B3      B3B2B1B0
 235                 *   16-bit:   B0 B1         0000B0B1      B1B00000
 236                 *    8-bit:   B0            000000B0      B0000000
 237                 *
 238                 * So a BE kernel will have the leftmost of the above in the MSB
 239                 * and rightmost in the LSB and can just then "cast" the u32 "data"
 240                 * down to the appropriate quantity and write it.
 241                 *
 242                 * However, an LE kernel can't. It doesn't need to swap because a
 243                 * load from data followed by a store to user are going to preserve
 244                 * the byte ordering which is the wire byte order which is what the
 245                 * user wants, but in order to "crop" to the right size, we need to
 246                 * shift right first.
 247                 */
 248                switch(len) {
 249                case 4:
 250                        rc = __put_user((u32)data, (u32 __user *)ubuf);
 251                        break;
 252                case 2:
 253#ifdef __LITTLE_ENDIAN__
 254                        data >>= 16;
 255#endif
 256                        rc = __put_user((u16)data, (u16 __user *)ubuf);
 257                        break;
 258                default:
 259#ifdef __LITTLE_ENDIAN__
 260                        data >>= 24;
 261#endif
 262                        rc = __put_user((u8)data, (u8 __user *)ubuf);
 263                        break;
 264                }
 265                if (rc)
 266                        return -EFAULT;
 267                *ppos += len;
 268                ubuf += len;
 269                todo -= len;
 270        }
 271
 272        return count;
 273}
 274
 275static ssize_t lpc_debug_write(struct file *filp, const char __user *ubuf,
 276                               size_t count, loff_t *ppos)
 277{
 278        struct lpc_debugfs_entry *lpc = filp->private_data;
 279        u32 data, pos, len, todo;
 280        int rc;
 281
 282        if (!access_ok(ubuf, count))
 283                return -EFAULT;
 284
 285        todo = count;
 286        while (todo) {
 287                pos = *ppos;
 288
 289                /*
 290                 * Select access size based on count and alignment and
 291                 * access type. IO and MEM only support byte acceses,
 292                 * FW supports all 3.
 293                 */
 294                len = 1;
 295                if (lpc->lpc_type == OPAL_LPC_FW) {
 296                        if (todo > 3 && (pos & 3) == 0)
 297                                len = 4;
 298                        else if (todo > 1 && (pos & 1) == 0)
 299                                len = 2;
 300                }
 301
 302                /*
 303                 * Similarly to the read case, we have some trickery here but
 304                 * it's different to handle. We need to pass the value to OPAL in
 305                 * a register whose layout depends on the access size. We want
 306                 * to reproduce the memory layout of the user, however we aren't
 307                 * doing a load from user and a store to another memory location
 308                 * which would achieve that. Here we pass the value to OPAL via
 309                 * a register which is expected to contain the "BE" interpretation
 310                 * of the byte sequence. IE: for a 32-bit access, byte 0 should be
 311                 * in the MSB. So here we *do* need to byteswap on LE.
 312                 *
 313                 *           User bytes:    LE "data"  OPAL "data"
 314                 *  32-bit:  B0 B1 B2 B3    B3B2B1B0   B0B1B2B3
 315                 *  16-bit:  B0 B1          0000B1B0   0000B0B1
 316                 *   8-bit:  B0             000000B0   000000B0
 317                 */
 318                switch(len) {
 319                case 4:
 320                        rc = __get_user(data, (u32 __user *)ubuf);
 321                        data = cpu_to_be32(data);
 322                        break;
 323                case 2:
 324                        rc = __get_user(data, (u16 __user *)ubuf);
 325                        data = cpu_to_be16(data);
 326                        break;
 327                default:
 328                        rc = __get_user(data, (u8 __user *)ubuf);
 329                        break;
 330                }
 331                if (rc)
 332                        return -EFAULT;
 333
 334                rc = opal_lpc_write(opal_lpc_chip_id, lpc->lpc_type, pos,
 335                                    data, len);
 336                if (rc)
 337                        return -ENXIO;
 338                *ppos += len;
 339                ubuf += len;
 340                todo -= len;
 341        }
 342
 343        return count;
 344}
 345
 346static const struct file_operations lpc_fops = {
 347        .read =         lpc_debug_read,
 348        .write =        lpc_debug_write,
 349        .open =         simple_open,
 350        .llseek =       default_llseek,
 351};
 352
 353static int opal_lpc_debugfs_create_type(struct dentry *folder,
 354                                        const char *fname,
 355                                        enum OpalLPCAddressType type)
 356{
 357        struct lpc_debugfs_entry *entry;
 358        entry = kzalloc(sizeof(*entry), GFP_KERNEL);
 359        if (!entry)
 360                return -ENOMEM;
 361        entry->lpc_type = type;
 362        debugfs_create_file(fname, 0600, folder, entry, &lpc_fops);
 363        return 0;
 364}
 365
 366static int opal_lpc_init_debugfs(void)
 367{
 368        struct dentry *root;
 369        int rc = 0;
 370
 371        if (opal_lpc_chip_id < 0)
 372                return -ENODEV;
 373
 374        root = debugfs_create_dir("lpc", powerpc_debugfs_root);
 375
 376        rc |= opal_lpc_debugfs_create_type(root, "io", OPAL_LPC_IO);
 377        rc |= opal_lpc_debugfs_create_type(root, "mem", OPAL_LPC_MEM);
 378        rc |= opal_lpc_debugfs_create_type(root, "fw", OPAL_LPC_FW);
 379        return rc;
 380}
 381machine_device_initcall(powernv, opal_lpc_init_debugfs);
 382#endif  /* CONFIG_DEBUG_FS */
 383
 384void __init opal_lpc_init(void)
 385{
 386        struct device_node *np;
 387
 388        /*
 389         * Look for a Power8 LPC bus tagged as "primary",
 390         * we currently support only one though the OPAL APIs
 391         * support any number.
 392         */
 393        for_each_compatible_node(np, NULL, "ibm,power8-lpc") {
 394                if (!of_device_is_available(np))
 395                        continue;
 396                if (!of_get_property(np, "primary", NULL))
 397                        continue;
 398                opal_lpc_chip_id = of_get_ibm_chip_id(np);
 399                break;
 400        }
 401        if (opal_lpc_chip_id < 0)
 402                return;
 403
 404        /* Does it support direct mapping ? */
 405        if (of_get_property(np, "ranges", NULL)) {
 406                pr_info("OPAL: Found memory mapped LPC bus on chip %d\n",
 407                        opal_lpc_chip_id);
 408                isa_bridge_init_non_pci(np);
 409        } else {
 410                pr_info("OPAL: Found non-mapped LPC bus on chip %d\n",
 411                        opal_lpc_chip_id);
 412
 413                /* Setup special IO ops */
 414                ppc_pci_io = opal_lpc_io;
 415                isa_io_special = true;
 416        }
 417}
 418