162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * Copyright (c) 2004 Topspin Communications.  All rights reserved.
362306a36Sopenharmony_ci * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
462306a36Sopenharmony_ci * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * This software is available to you under a choice of one of two
762306a36Sopenharmony_ci * licenses.  You may choose to be licensed under the terms of the GNU
862306a36Sopenharmony_ci * General Public License (GPL) Version 2, available from the file
962306a36Sopenharmony_ci * COPYING in the main directory of this source tree, or the
1062306a36Sopenharmony_ci * OpenIB.org BSD license below:
1162306a36Sopenharmony_ci *
1262306a36Sopenharmony_ci *     Redistribution and use in source and binary forms, with or
1362306a36Sopenharmony_ci *     without modification, are permitted provided that the following
1462306a36Sopenharmony_ci *     conditions are met:
1562306a36Sopenharmony_ci *
1662306a36Sopenharmony_ci *      - Redistributions of source code must retain the above
1762306a36Sopenharmony_ci *        copyright notice, this list of conditions and the following
1862306a36Sopenharmony_ci *        disclaimer.
1962306a36Sopenharmony_ci *
2062306a36Sopenharmony_ci *      - Redistributions in binary form must reproduce the above
2162306a36Sopenharmony_ci *        copyright notice, this list of conditions and the following
2262306a36Sopenharmony_ci *        disclaimer in the documentation and/or other materials
2362306a36Sopenharmony_ci *        provided with the distribution.
2462306a36Sopenharmony_ci *
2562306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2662306a36Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2762306a36Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
2862306a36Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
2962306a36Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
3062306a36Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
3162306a36Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3262306a36Sopenharmony_ci * SOFTWARE.
3362306a36Sopenharmony_ci */
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci#include <linux/types.h>
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci#define MTHCA_RD_DOORBELL      0x00
3862306a36Sopenharmony_ci#define MTHCA_SEND_DOORBELL    0x10
3962306a36Sopenharmony_ci#define MTHCA_RECEIVE_DOORBELL 0x18
4062306a36Sopenharmony_ci#define MTHCA_CQ_DOORBELL      0x20
4162306a36Sopenharmony_ci#define MTHCA_EQ_DOORBELL      0x28
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci#if BITS_PER_LONG == 64
4462306a36Sopenharmony_ci/*
4562306a36Sopenharmony_ci * Assume that we can just write a 64-bit doorbell atomically.  s390
4662306a36Sopenharmony_ci * actually doesn't have writeq() but S/390 systems don't even have
4762306a36Sopenharmony_ci * PCI so we won't worry about it.
4862306a36Sopenharmony_ci */
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci#define MTHCA_DECLARE_DOORBELL_LOCK(name)
5162306a36Sopenharmony_ci#define MTHCA_INIT_DOORBELL_LOCK(ptr)    do { } while (0)
5262306a36Sopenharmony_ci#define MTHCA_GET_DOORBELL_LOCK(ptr)      (NULL)
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_cistatic inline void mthca_write64_raw(__be64 val, void __iomem *dest)
5562306a36Sopenharmony_ci{
5662306a36Sopenharmony_ci	__raw_writeq((__force u64) val, dest);
5762306a36Sopenharmony_ci}
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_cistatic inline void mthca_write64(u32 hi, u32 lo, void __iomem *dest,
6062306a36Sopenharmony_ci				 spinlock_t *doorbell_lock)
6162306a36Sopenharmony_ci{
6262306a36Sopenharmony_ci	__raw_writeq((__force u64) cpu_to_be64((u64) hi << 32 | lo), dest);
6362306a36Sopenharmony_ci}
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_cistatic inline void mthca_write_db_rec(__be32 val[2], __be32 *db)
6662306a36Sopenharmony_ci{
6762306a36Sopenharmony_ci	*(u64 *) db = *(u64 *) val;
6862306a36Sopenharmony_ci}
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci#else
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci/*
7362306a36Sopenharmony_ci * Just fall back to a spinlock to protect the doorbell if
7462306a36Sopenharmony_ci * BITS_PER_LONG is 32 -- there's no portable way to do atomic 64-bit
7562306a36Sopenharmony_ci * MMIO writes.
7662306a36Sopenharmony_ci */
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci#define MTHCA_DECLARE_DOORBELL_LOCK(name) spinlock_t name;
7962306a36Sopenharmony_ci#define MTHCA_INIT_DOORBELL_LOCK(ptr)     spin_lock_init(ptr)
8062306a36Sopenharmony_ci#define MTHCA_GET_DOORBELL_LOCK(ptr)      (ptr)
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_cistatic inline void mthca_write64_raw(__be64 val, void __iomem *dest)
8362306a36Sopenharmony_ci{
8462306a36Sopenharmony_ci	__raw_writel(((__force u32 *) &val)[0], dest);
8562306a36Sopenharmony_ci	__raw_writel(((__force u32 *) &val)[1], dest + 4);
8662306a36Sopenharmony_ci}
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_cistatic inline void mthca_write64(u32 hi, u32 lo, void __iomem *dest,
8962306a36Sopenharmony_ci				 spinlock_t *doorbell_lock)
9062306a36Sopenharmony_ci{
9162306a36Sopenharmony_ci	unsigned long flags;
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci	hi = (__force u32) cpu_to_be32(hi);
9462306a36Sopenharmony_ci	lo = (__force u32) cpu_to_be32(lo);
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci	spin_lock_irqsave(doorbell_lock, flags);
9762306a36Sopenharmony_ci	__raw_writel(hi, dest);
9862306a36Sopenharmony_ci	__raw_writel(lo, dest + 4);
9962306a36Sopenharmony_ci	spin_unlock_irqrestore(doorbell_lock, flags);
10062306a36Sopenharmony_ci}
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_cistatic inline void mthca_write_db_rec(__be32 val[2], __be32 *db)
10362306a36Sopenharmony_ci{
10462306a36Sopenharmony_ci	db[0] = val[0];
10562306a36Sopenharmony_ci	wmb();
10662306a36Sopenharmony_ci	db[1] = val[1];
10762306a36Sopenharmony_ci}
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci#endif
110