Commit 7e1529d0 authored by forum_service's avatar forum_service Committed by carbon

linux-5.10: version release v4.1.0.3

0debf7abc [dma] When using DMA, if the DMA addr spans 128MB boundary   we have to split the DMA transfer into two so that each one     doesn't exceed the boundary.
4f7ed7449 Merge "[eth] change rxterm and vcm to link DianXin router" into v4.1.0
feb60bba5 Merge "[audio][lt9611]add drivers" into v4.1.0
a3dde371c [eth] change rxterm and vcm to link DianXin router
e615d3a43 [audio][lt9611]add drivers

Change-Id: If4fdcbc32df6aeaed04da0efbd23455376e2a53c
parent 1f388afc
extends: relaxed
rules:
line-length:
# 80 chars should be enough, but don't fail if a line is longer
max: 110
allow-non-breakable-words: true
level: warning
braces:
min-spaces-inside: 0
max-spaces-inside: 1
min-spaces-inside-empty: 0
max-spaces-inside-empty: 0
brackets:
min-spaces-inside: 0
max-spaces-inside: 1
min-spaces-inside-empty: 0
max-spaces-inside-empty: 0
colons: {max-spaces-before: 0, max-spaces-after: 1}
commas: {min-spaces-after: 1, max-spaces-after: 1}
comments:
require-starting-space: false
min-spaces-from-content: 1
comments-indentation: disable
document-start:
present: true
empty-lines:
max: 3
max-end: 1
empty-values:
forbid-in-block-mappings: true
forbid-in-flow-mappings: true
hyphens:
max-spaces-after: 1
indentation:
spaces: 2
indent-sequences: true
check-multi-line-strings: false
trailing-spaces: false
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_CSKY_ATOMIC_H
#define __ASM_CSKY_ATOMIC_H
#include <linux/version.h>
#include <asm/cmpxchg.h>
#include <asm/barrier.h>
#ifdef CONFIG_CPU_HAS_LDSTEX
#define __atomic_add_unless __atomic_add_unless
static inline int __atomic_add_unless(atomic_t *v, int a, int u)
{
unsigned long tmp, ret;
smp_mb();
asm volatile (
"1: ldex.w %0, (%3) \n"
" mov %1, %0 \n"
" cmpne %0, %4 \n"
" bf 2f \n"
" add %0, %2 \n"
" stex.w %0, (%3) \n"
" bez %0, 1b \n"
"2: \n"
: "=&r" (tmp), "=&r" (ret)
: "r" (a), "r"(&v->counter), "r"(u)
: "memory");
if (ret != u)
smp_mb();
return ret;
}
#define ATOMIC_OP(op, c_op) \
static inline void atomic_##op(int i, atomic_t *v) \
{ \
unsigned long tmp; \
\
asm volatile ( \
"1: ldex.w %0, (%2) \n" \
" " #op " %0, %1 \n" \
" stex.w %0, (%2) \n" \
" bez %0, 1b \n" \
: "=&r" (tmp) \
: "r" (i), "r"(&v->counter) \
: "memory"); \
}
#define ATOMIC_OP_RETURN(op, c_op) \
static inline int atomic_##op##_return(int i, atomic_t *v) \
{ \
unsigned long tmp, ret; \
\
smp_mb(); \
asm volatile ( \
"1: ldex.w %0, (%3) \n" \
" " #op " %0, %2 \n" \
" mov %1, %0 \n" \
" stex.w %0, (%3) \n" \
" bez %0, 1b \n" \
: "=&r" (tmp), "=&r" (ret) \
: "r" (i), "r"(&v->counter) \
: "memory"); \
smp_mb(); \
\
return ret; \
}
#define ATOMIC_FETCH_OP(op, c_op) \
static inline int atomic_fetch_##op(int i, atomic_t *v) \
{ \
unsigned long tmp, ret; \
\
smp_mb(); \
asm volatile ( \
"1: ldex.w %0, (%3) \n" \
" mov %1, %0 \n" \
" " #op " %0, %2 \n" \
" stex.w %0, (%3) \n" \
" bez %0, 1b \n" \
: "=&r" (tmp), "=&r" (ret) \
: "r" (i), "r"(&v->counter) \
: "memory"); \
smp_mb(); \
\
return ret; \
}
#else /* CONFIG_CPU_HAS_LDSTEX */
#include <linux/irqflags.h>
#define __atomic_add_unless __atomic_add_unless
static inline int __atomic_add_unless(atomic_t *v, int a, int u)
{
unsigned long tmp, ret, flags;
raw_local_irq_save(flags);
asm volatile (
" ldw %0, (%3) \n"
" mov %1, %0 \n"
" cmpne %0, %4 \n"
" bf 2f \n"
" add %0, %2 \n"
" stw %0, (%3) \n"
"2: \n"
: "=&r" (tmp), "=&r" (ret)
: "r" (a), "r"(&v->counter), "r"(u)
: "memory");
raw_local_irq_restore(flags);
return ret;
}
#define ATOMIC_OP(op, c_op) \
static inline void atomic_##op(int i, atomic_t *v) \
{ \
unsigned long tmp, flags; \
\
raw_local_irq_save(flags); \
\
asm volatile ( \
" ldw %0, (%2) \n" \
" " #op " %0, %1 \n" \
" stw %0, (%2) \n" \
: "=&r" (tmp) \
: "r" (i), "r"(&v->counter) \
: "memory"); \
\
raw_local_irq_restore(flags); \
}
#define ATOMIC_OP_RETURN(op, c_op) \
static inline int atomic_##op##_return(int i, atomic_t *v) \
{ \
unsigned long tmp, ret, flags; \
\
raw_local_irq_save(flags); \
\
asm volatile ( \
" ldw %0, (%3) \n" \
" " #op " %0, %2 \n" \
" stw %0, (%3) \n" \
" mov %1, %0 \n" \
: "=&r" (tmp), "=&r" (ret) \
: "r" (i), "r"(&v->counter) \
: "memory"); \
\
raw_local_irq_restore(flags); \
\
return ret; \
}
#define ATOMIC_FETCH_OP(op, c_op) \
static inline int atomic_fetch_##op(int i, atomic_t *v) \
{ \
unsigned long tmp, ret, flags; \
\
raw_local_irq_save(flags); \
\
asm volatile ( \
" ldw %0, (%3) \n" \
" mov %1, %0 \n" \
" " #op " %0, %2 \n" \
" stw %0, (%3) \n" \
: "=&r" (tmp), "=&r" (ret) \
: "r" (i), "r"(&v->counter) \
: "memory"); \
\
raw_local_irq_restore(flags); \
\
return ret; \
}
#endif /* CONFIG_CPU_HAS_LDSTEX */
#define atomic_add_return atomic_add_return
ATOMIC_OP_RETURN(add, +)
#define atomic_sub_return atomic_sub_return
ATOMIC_OP_RETURN(sub, -)
#define atomic_fetch_add atomic_fetch_add
ATOMIC_FETCH_OP(add, +)
#define atomic_fetch_sub atomic_fetch_sub
ATOMIC_FETCH_OP(sub, -)
#define atomic_fetch_and atomic_fetch_and
ATOMIC_FETCH_OP(and, &)
#define atomic_fetch_or atomic_fetch_or
ATOMIC_FETCH_OP(or, |)
#define atomic_fetch_xor atomic_fetch_xor
ATOMIC_FETCH_OP(xor, ^)
#define atomic_and atomic_and
ATOMIC_OP(and, &)
#define atomic_or atomic_or
ATOMIC_OP(or, |)
#define atomic_xor atomic_xor
ATOMIC_OP(xor, ^)
#undef ATOMIC_FETCH_OP
#undef ATOMIC_OP_RETURN
#undef ATOMIC_OP
#include <asm-generic/atomic.h>
#endif /* __ASM_CSKY_ATOMIC_H */
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0+
# Copyright 2020 Palmer Dabbelt <palmerdabbelt@google.com>
sed 's!\([0-9a-f]*\) T \([a-z0-9_]*\)\(@@LINUX_4.15\)*!.global \2\n.set \2,0x\1!' \
| grep '^\.'
...@@ -244,6 +244,7 @@ static void dwc_initialize(struct dw_dma_chan *dwc) ...@@ -244,6 +244,7 @@ static void dwc_initialize(struct dw_dma_chan *dwc)
channel_writeq(dwc, INTSTATUS_ENABLEREG, int_status_reg); channel_writeq(dwc, INTSTATUS_ENABLEREG, int_status_reg);
set_bit(DW_DMA_IS_INITIALIZED, &dwc->flags); set_bit(DW_DMA_IS_INITIALIZED, &dwc->flags);
dwc->status &= ~DWC_CH_INTSIG_DMA_TRA_DONE;
} }
/* Called with dwc->lock held and bh disabled */ /* Called with dwc->lock held and bh disabled */
...@@ -494,7 +495,7 @@ static void dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *des ...@@ -494,7 +495,7 @@ static void dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *des
spin_lock_irqsave(&dwc->lock, flags); spin_lock_irqsave(&dwc->lock, flags);
dma_cookie_complete(txd); dma_cookie_complete(txd);
dwc->status &= ~DWC_CH_INTSIG_DMA_TRA_DONE;
if (callback_required) if (callback_required)
dmaengine_desc_get_callback(txd, &cb); dmaengine_desc_get_callback(txd, &cb);
else else
...@@ -713,6 +714,7 @@ static int dwc_stop_cyclic_all(struct dw_dma_chan *dwc) ...@@ -713,6 +714,7 @@ static int dwc_stop_cyclic_all(struct dw_dma_chan *dwc)
spin_lock_irqsave(&dwc->lock, flags); spin_lock_irqsave(&dwc->lock, flags);
dma_cookie_complete(txd); dma_cookie_complete(txd);
dwc->status &= ~DWC_CH_INTSIG_DMA_TRA_DONE;
clear_bit(DW_DMA_IS_CYCLIC, &dwc->flags); clear_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
...@@ -1485,7 +1487,7 @@ static void dwc_free_chan_resources(struct dma_chan *chan) ...@@ -1485,7 +1487,7 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
/* Disable controller in case it was a last user */ /* Disable controller in case it was a last user */
dw->in_use &= ~dwc->mask; dw->in_use &= ~dwc->mask;
dwc->status &= ~DWC_CH_INTSIG_DMA_TRA_DONE;
if (!dw->in_use) if (!dw->in_use)
dw_dma_off(dw); dw_dma_off(dw);
...@@ -1541,18 +1543,21 @@ static void dw_dma_tasklet(unsigned long data) ...@@ -1541,18 +1543,21 @@ static void dw_dma_tasklet(unsigned long data)
ch_en = dma_readq(dw, CH_EN); ch_en = dma_readq(dw, CH_EN);
for (i = 0; i < dw->dma.chancnt; i++) { for (i = 0; i < dw->dma.chancnt; i++) {
dwc = &dw->chan[i]; dwc = &dw->chan[i];
if (test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) { if (test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) {
if ((ch_en >> i) & 0x1) if ((ch_en >> i) & 0x1)
dwc_handle_cyclic(dw, dwc); dwc_handle_cyclic(dw, dwc);
} else } else{
dwc_scan_descriptors(dw, dwc); if(dwc->status == DWC_CH_INTSIG_DMA_TRA_DONE)
dwc_scan_descriptors(dw, dwc);
}
//dwc_interrupts_set(dwc, true); //dwc_interrupts_set(dwc, true);
} }
} }
#endif #endif
static void dw_dma_off(struct dw_dma *dw) static void dw_dma_off(struct dw_dma *dw)
{ {
unsigned int i; unsigned int i;
...@@ -1601,7 +1606,7 @@ static void instead_of_tasklet(struct dw_dma *dw) ...@@ -1601,7 +1606,7 @@ static void instead_of_tasklet(struct dw_dma *dw)
static irqreturn_t dw_dma_interrupt(int irq, void *dev_id) static irqreturn_t dw_dma_interrupt(int irq, void *dev_id)
{ {
int i; int i;
u64 status, dwc_status; u64 status,dwc_status;
struct dw_dma *dw = dev_id; struct dw_dma *dw = dev_id;
struct dw_dma_chan *dwc; struct dw_dma_chan *dwc;
...@@ -1614,10 +1619,13 @@ static irqreturn_t dw_dma_interrupt(int irq, void *dev_id) ...@@ -1614,10 +1619,13 @@ static irqreturn_t dw_dma_interrupt(int irq, void *dev_id)
if (!status) if (!status)
return IRQ_NONE; return IRQ_NONE;
dma_writeq(dw, COMM_INTCLEAR, 0x10f); /* clear all common interrupts */ dma_writeq(dw, COMM_INTCLEAR, 0x10f); /* clear all common interrupts */
for (i = 0; i < dw->dma.chancnt; i++) { for (i = 0; i < dw->dma.chancnt; i++) {
dwc = &dw->chan[i]; dwc = &dw->chan[i];
dwc_status = channel_readq(dwc, INTSTATUS); dwc_status = channel_readq(dwc, INTSTATUS);
if(dwc_status == DWC_CH_INTSIG_DMA_TRA_DONE)
dwc->status = DWC_CH_INTSIG_DMA_TRA_DONE;
channel_writeq(dwc, INTCLEARREG, dwc_status); channel_writeq(dwc, INTCLEARREG, dwc_status);
//dwc_interrupts_set(dwc, false); //dwc_interrupts_set(dwc, false);
} }
......
...@@ -324,6 +324,7 @@ struct dw_dma_chan { ...@@ -324,6 +324,7 @@ struct dw_dma_chan {
/* these other elements are all protected by lock */ /* these other elements are all protected by lock */
unsigned long flags; unsigned long flags;
unsigned long status;
struct list_head active_list; struct list_head active_list;
struct list_head queue; struct list_head queue;
struct dw_cyclic_desc *cdesc; struct dw_cyclic_desc *cdesc;
......
...@@ -33,6 +33,10 @@ ...@@ -33,6 +33,10 @@
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
#include <linux/mmc/slot-gpio.h> #include <linux/mmc/slot-gpio.h>
#include <linux/ktime.h> #include <linux/ktime.h>
#include <linux/clk.h>
#include <linux/sizes.h>
#include <linux/dma-mapping.h>
#include <linux/kernel.h>
#include "../../core/card.h" #include "../../core/card.h"
#include "../sdhci-pltfm.h" #include "../sdhci-pltfm.h"
...@@ -62,6 +66,9 @@ ...@@ -62,6 +66,9 @@
__res & __mask; \ __res & __mask; \
}) })
#define BOUNDARY_OK(addr, len) \
((addr | (SZ_128M - 1)) == ((addr + len - 1) | (SZ_128M - 1)))
static struct proc_dir_entry *proc_cvi_dir; static struct proc_dir_entry *proc_cvi_dir;
static char *card_type[MAX_CARD_TYPE + 1] = { static char *card_type[MAX_CARD_TYPE + 1] = {
...@@ -1020,6 +1027,25 @@ static void sdhci_cv180x_sd_dump_vendor_regs(struct sdhci_host *host) ...@@ -1020,6 +1027,25 @@ static void sdhci_cv180x_sd_dump_vendor_regs(struct sdhci_host *host)
SDHCI_DUMP(": clk_sd0 %d MHz\n", FPLL_MHZ/4); SDHCI_DUMP(": clk_sd0 %d MHz\n", FPLL_MHZ/4);
} }
static void cvi_adma_write_desc(struct sdhci_host *host, void **desc,
dma_addr_t addr, int len, unsigned int cmd)
{
int tmplen, offset;
if (likely(!len || BOUNDARY_OK(addr, len))) {
sdhci_adma_write_desc(host, desc, addr, len, cmd);
return;
}
offset = addr & (SZ_128M - 1);
tmplen = SZ_128M - offset;
sdhci_adma_write_desc(host, desc, addr, tmplen, cmd);
addr += tmplen;
len -= tmplen;
sdhci_adma_write_desc(host, desc, addr, len, cmd);
}
static const struct sdhci_ops sdhci_cv180x_emmc_ops = { static const struct sdhci_ops sdhci_cv180x_emmc_ops = {
.reset = sdhci_cv180x_emmc_reset, .reset = sdhci_cv180x_emmc_reset,
.set_clock = sdhci_set_clock, .set_clock = sdhci_set_clock,
...@@ -1030,6 +1056,7 @@ static const struct sdhci_ops sdhci_cv180x_emmc_ops = { ...@@ -1030,6 +1056,7 @@ static const struct sdhci_ops sdhci_cv180x_emmc_ops = {
.platform_execute_tuning = sdhci_cv180x_general_execute_tuning, .platform_execute_tuning = sdhci_cv180x_general_execute_tuning,
.select_drive_strength = sdhci_cv180x_general_select_drive_strength, .select_drive_strength = sdhci_cv180x_general_select_drive_strength,
.dump_vendor_regs = sdhci_cv180x_emmc_dump_vendor_regs, .dump_vendor_regs = sdhci_cv180x_emmc_dump_vendor_regs,
.adma_write_desc = cvi_adma_write_desc,
}; };
static const struct sdhci_ops sdhci_cv180x_sd_ops = { static const struct sdhci_ops sdhci_cv180x_sd_ops = {
...@@ -1043,6 +1070,7 @@ static const struct sdhci_ops sdhci_cv180x_sd_ops = { ...@@ -1043,6 +1070,7 @@ static const struct sdhci_ops sdhci_cv180x_sd_ops = {
.platform_execute_tuning = sdhci_cv180x_general_execute_tuning, .platform_execute_tuning = sdhci_cv180x_general_execute_tuning,
.select_drive_strength = sdhci_cv180x_general_select_drive_strength, .select_drive_strength = sdhci_cv180x_general_select_drive_strength,
.dump_vendor_regs = sdhci_cv180x_sd_dump_vendor_regs, .dump_vendor_regs = sdhci_cv180x_sd_dump_vendor_regs,
.adma_write_desc = cvi_adma_write_desc,
}; };
static const struct sdhci_ops sdhci_cv180x_sdio_ops = { static const struct sdhci_ops sdhci_cv180x_sdio_ops = {
...@@ -1054,6 +1082,7 @@ static const struct sdhci_ops sdhci_cv180x_sdio_ops = { ...@@ -1054,6 +1082,7 @@ static const struct sdhci_ops sdhci_cv180x_sdio_ops = {
.set_uhs_signaling = sdhci_cvi_general_set_uhs_signaling, .set_uhs_signaling = sdhci_cvi_general_set_uhs_signaling,
.select_drive_strength = sdhci_cv180x_general_select_drive_strength, .select_drive_strength = sdhci_cv180x_general_select_drive_strength,
.platform_execute_tuning = sdhci_cv180x_general_execute_tuning, .platform_execute_tuning = sdhci_cv180x_general_execute_tuning,
.adma_write_desc = cvi_adma_write_desc,
}; };
static const struct sdhci_ops sdhci_cv180x_fpga_emmc_ops = { static const struct sdhci_ops sdhci_cv180x_fpga_emmc_ops = {
...@@ -1193,6 +1222,7 @@ static int sdhci_cvi_probe(struct platform_device *pdev) ...@@ -1193,6 +1222,7 @@ static int sdhci_cvi_probe(struct platform_device *pdev)
const struct sdhci_pltfm_data *pdata; const struct sdhci_pltfm_data *pdata;
int ret; int ret;
int gpio_cd = -EINVAL; int gpio_cd = -EINVAL;
u32 extra;
pr_info(DRIVER_NAME ":%s\n", __func__); pr_info(DRIVER_NAME ":%s\n", __func__);
...@@ -1258,6 +1288,13 @@ static int sdhci_cvi_probe(struct platform_device *pdev) ...@@ -1258,6 +1288,13 @@ static int sdhci_cvi_probe(struct platform_device *pdev)
} }
} }
} }
/*
* extra adma table cnt for cross 128M boundary handling.
*/
extra = DIV_ROUND_UP_ULL(dma_get_required_mask(&pdev->dev), SZ_128M);
if (extra > SDHCI_MAX_SEGS)
extra = SDHCI_MAX_SEGS;
host->adma_table_cnt += extra;
ret = sdhci_add_host(host); ret = sdhci_add_host(host);
if (ret) if (ret)
......
...@@ -33,6 +33,10 @@ ...@@ -33,6 +33,10 @@
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
#include <linux/mmc/slot-gpio.h> #include <linux/mmc/slot-gpio.h>
#include <linux/ktime.h> #include <linux/ktime.h>
#include <linux/clk.h>
#include <linux/sizes.h>
#include <linux/dma-mapping.h>
#include <linux/kernel.h>
#include "../../core/card.h" #include "../../core/card.h"
#include "../sdhci-pltfm.h" #include "../sdhci-pltfm.h"
...@@ -62,6 +66,9 @@ ...@@ -62,6 +66,9 @@
__res & __mask; \ __res & __mask; \
}) })
#define BOUNDARY_OK(addr, len) \
((addr | (SZ_128M - 1)) == ((addr + len - 1) | (SZ_128M - 1)))
static struct proc_dir_entry *proc_cvi_dir; static struct proc_dir_entry *proc_cvi_dir;
static char *card_type[MAX_CARD_TYPE + 1] = { static char *card_type[MAX_CARD_TYPE + 1] = {
...@@ -1032,6 +1039,25 @@ static void sdhci_cv181x_sd_dump_vendor_regs(struct sdhci_host *host) ...@@ -1032,6 +1039,25 @@ static void sdhci_cv181x_sd_dump_vendor_regs(struct sdhci_host *host)
} }
} }
static void cvi_adma_write_desc(struct sdhci_host *host, void **desc,
dma_addr_t addr, int len, unsigned int cmd)
{
int tmplen, offset;
if (likely(!len || BOUNDARY_OK(addr, len))) {
sdhci_adma_write_desc(host, desc, addr, len, cmd);
return;
}
offset = addr & (SZ_128M - 1);
tmplen = SZ_128M - offset;
sdhci_adma_write_desc(host, desc, addr, tmplen, cmd);
addr += tmplen;
len -= tmplen;
sdhci_adma_write_desc(host, desc, addr, len, cmd);
}
static const struct sdhci_ops sdhci_cv181x_emmc_ops = { static const struct sdhci_ops sdhci_cv181x_emmc_ops = {
.reset = sdhci_cv181x_emmc_reset, .reset = sdhci_cv181x_emmc_reset,
.set_clock = sdhci_set_clock, .set_clock = sdhci_set_clock,
...@@ -1042,6 +1068,7 @@ static const struct sdhci_ops sdhci_cv181x_emmc_ops = { ...@@ -1042,6 +1068,7 @@ static const struct sdhci_ops sdhci_cv181x_emmc_ops = {
.platform_execute_tuning = sdhci_cv181x_general_execute_tuning, .platform_execute_tuning = sdhci_cv181x_general_execute_tuning,
.select_drive_strength = sdhci_cv181x_general_select_drive_strength, .select_drive_strength = sdhci_cv181x_general_select_drive_strength,
.dump_vendor_regs = sdhci_cv181x_emmc_dump_vendor_regs, .dump_vendor_regs = sdhci_cv181x_emmc_dump_vendor_regs,
.adma_write_desc = cvi_adma_write_desc,
}; };
static const struct sdhci_ops sdhci_cv181x_sd_ops = { static const struct sdhci_ops sdhci_cv181x_sd_ops = {
...@@ -1055,6 +1082,7 @@ static const struct sdhci_ops sdhci_cv181x_sd_ops = { ...@@ -1055,6 +1082,7 @@ static const struct sdhci_ops sdhci_cv181x_sd_ops = {
.platform_execute_tuning = sdhci_cv181x_general_execute_tuning, .platform_execute_tuning = sdhci_cv181x_general_execute_tuning,
.select_drive_strength = sdhci_cv181x_general_select_drive_strength, .select_drive_strength = sdhci_cv181x_general_select_drive_strength,
.dump_vendor_regs = sdhci_cv181x_sd_dump_vendor_regs, .dump_vendor_regs = sdhci_cv181x_sd_dump_vendor_regs,
.adma_write_desc = cvi_adma_write_desc,
}; };
static const struct sdhci_ops sdhci_cv181x_sdio_ops = { static const struct sdhci_ops sdhci_cv181x_sdio_ops = {
...@@ -1066,6 +1094,7 @@ static const struct sdhci_ops sdhci_cv181x_sdio_ops = { ...@@ -1066,6 +1094,7 @@ static const struct sdhci_ops sdhci_cv181x_sdio_ops = {
.set_uhs_signaling = sdhci_cvi_general_set_uhs_signaling, .set_uhs_signaling = sdhci_cvi_general_set_uhs_signaling,
.select_drive_strength = sdhci_cv181x_general_select_drive_strength, .select_drive_strength = sdhci_cv181x_general_select_drive_strength,
.platform_execute_tuning = sdhci_cv181x_general_execute_tuning, .platform_execute_tuning = sdhci_cv181x_general_execute_tuning,
.adma_write_desc = cvi_adma_write_desc,
}; };
static const struct sdhci_ops sdhci_cv181x_fpga_emmc_ops = { static const struct sdhci_ops sdhci_cv181x_fpga_emmc_ops = {
...@@ -1203,8 +1232,10 @@ static int sdhci_cvi_probe(struct platform_device *pdev) ...@@ -1203,8 +1232,10 @@ static int sdhci_cvi_probe(struct platform_device *pdev)
struct sdhci_cvi_host *cvi_host; struct sdhci_cvi_host *cvi_host;
const struct of_device_id *match; const struct of_device_id *match;
const struct sdhci_pltfm_data *pdata; const struct sdhci_pltfm_data *pdata;
struct clk *clk_sd;
int ret; int ret;
int gpio_cd = -EINVAL; int gpio_cd = -EINVAL;
u32 extra;
pr_info(DRIVER_NAME ":%s\n", __func__); pr_info(DRIVER_NAME ":%s\n", __func__);
...@@ -1270,6 +1301,13 @@ static int sdhci_cvi_probe(struct platform_device *pdev) ...@@ -1270,6 +1301,13 @@ static int sdhci_cvi_probe(struct platform_device *pdev)
} }
} }
} }
/*
* extra adma table cnt for cross 128M boundary handling.
*/
extra = DIV_ROUND_UP_ULL(dma_get_required_mask(&pdev->dev), SZ_128M);
if (extra > SDHCI_MAX_SEGS)
extra = SDHCI_MAX_SEGS;
host->adma_table_cnt += extra;
ret = sdhci_add_host(host); ret = sdhci_add_host(host);
if (ret) if (ret)
......
// SPDX-License-Identifier: GPL-2.0-or-later
/* Driver for CVITEK PHYs */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/phy.h>
#include <linux/netdevice.h>
#include <linux/bitops.h>
#define CVI_INT_EVENTS \
(CVI_LNK_STS_CHG_INT_MSK | CVI_MGC_PKT_DET_INT_MSK)
static int cv182xa_phy_config_intr(struct phy_device *phydev)
{
return 0;
}
static int cv182xa_phy_ack_interrupt(struct phy_device *phydev)
{
return 0;
}
static int cv182xa_read_status(struct phy_device *phydev)
{
int err = genphy_read_status(phydev);
pr_debug("%s, speed=%d, duplex=%d, ", __func__, phydev->speed, phydev->duplex);
pr_debug("pasue=%d, asym_pause=%d, autoneg=%d ", phydev->pause, phydev->asym_pause, phydev->autoneg);
return err;
}
#if defined(CONFIG_CVITEK_PHY_UAPS)
/* Ultra Auto Power Saving mode */
static int cv182xa_phy_aps_enable(struct phy_device *phydev)
{
return 0;
}
#endif
static int cv182xa_phy_config_aneg(struct phy_device *phydev)
{
int ret;
#if defined(CONFIG_CVITEK_PHY_UAPS)
cv182xa_phy_aps_enable(phydev); /* if phy not work, disable this function for try */
#endif
ret = genphy_config_aneg(phydev);
if (ret < 0)
return ret;
return 0;
}
static int cv182xa_phy_config_init(struct phy_device *phydev)
{
return 0;
}
static struct phy_driver cv182xa_phy_driver[] = {
{
.phy_id = 0x00435649,
.phy_id_mask = 0xffffffff,
.name = "CVITEK CV182XA",
.config_init = cv182xa_phy_config_init,
.config_aneg = cv182xa_phy_config_aneg,
.read_status = cv182xa_read_status,
/* IRQ related */
.ack_interrupt = cv182xa_phy_ack_interrupt,
.config_intr = cv182xa_phy_config_intr,
.aneg_done = genphy_aneg_done,
.suspend = genphy_suspend,
.resume = genphy_resume,
.set_loopback = genphy_loopback,
} };
module_phy_driver(cv182xa_phy_driver);
MODULE_DESCRIPTION("CV182XA EPHY driver");
MODULE_AUTHOR("Ethan Chen");
MODULE_LICENSE("GPL");
static struct mdio_device_id __maybe_unused cv182xa_tbl[] = {
{ 0x00435649, 0xffffffff },
{ }
};
MODULE_DEVICE_TABLE(mdio, cv182xa_tbl);
...@@ -191,26 +191,27 @@ static int cv182xa_phy_config_init(struct phy_device *phydev) ...@@ -191,26 +191,27 @@ static int cv182xa_phy_config_init(struct phy_device *phydev)
// En TX_Rterm // En TX_Rterm
writel((0x0001 | readl(reg_ephy_base + 0x40)), reg_ephy_base + 0x40); writel((0x0001 | readl(reg_ephy_base + 0x40)), reg_ephy_base + 0x40);
//Change rx vcm
writel((0x820 |readl(reg_ephy_base + 0x4c)), reg_ephy_base + 0x4c);
// Link Pulse // Link Pulse
// Switch to MII-page10 // Switch to MII-page10
writel(0x0a00, reg_ephy_base + 0x7c); writel(0x0a00, reg_ephy_base + 0x7c);
#if 1
// Set Link Pulse // Set Link Pulse
// writel(0x3e00, reg_ephy_base + 0x40); writel(0x3e00, reg_ephy_base + 0x40);
// writel(0x7864, reg_ephy_base + 0x44); writel(0x7864, reg_ephy_base + 0x44);
// writel(0x6470, reg_ephy_base + 0x48); writel(0x6470, reg_ephy_base + 0x48);
// writel(0x5f62, reg_ephy_base + 0x4c); writel(0x5f62, reg_ephy_base + 0x4c);
// writel(0x5a5a, reg_ephy_base + 0x50); writel(0x5a5a, reg_ephy_base + 0x50);
// writel(0x5458, reg_ephy_base + 0x54); writel(0x5458, reg_ephy_base + 0x54);
// writel(0xb23a, reg_ephy_base + 0x58); writel(0xb23a, reg_ephy_base + 0x58);
// writel(0x94a0, reg_ephy_base + 0x5c); writel(0x94a0, reg_ephy_base + 0x5c);
// writel(0x9092, reg_ephy_base + 0x60); writel(0x9092, reg_ephy_base + 0x60);
// writel(0x8a8e, reg_ephy_base + 0x64); writel(0x8a8e, reg_ephy_base + 0x64);
// writel(0x8688, reg_ephy_base + 0x68); writel(0x8688, reg_ephy_base + 0x68);
// writel(0x8484, reg_ephy_base + 0x6c); writel(0x8484, reg_ephy_base + 0x6c);
// writel(0x0082, reg_ephy_base + 0x70); writel(0x0082, reg_ephy_base + 0x70);
#else
// from sean // from sean
// Fix err: the status is still linkup when removed the network cable. // Fix err: the status is still linkup when removed the network cable.
writel(0x2000, reg_ephy_base + 0x40); writel(0x2000, reg_ephy_base + 0x40);
...@@ -226,7 +227,7 @@ static int cv182xa_phy_config_init(struct phy_device *phydev) ...@@ -226,7 +227,7 @@ static int cv182xa_phy_config_init(struct phy_device *phydev)
writel(0x8283, reg_ephy_base + 0x68); writel(0x8283, reg_ephy_base + 0x68);
writel(0x8182, reg_ephy_base + 0x6c); writel(0x8182, reg_ephy_base + 0x6c);
writel(0x0081, reg_ephy_base + 0x70); writel(0x0081, reg_ephy_base + 0x70);
#endif
// TP_IDLE // TP_IDLE
// Switch to MII-page11 // Switch to MII-page11
writel(0x0b00, reg_ephy_base + 0x7c); writel(0x0b00, reg_ephy_base + 0x7c);
......
...@@ -31,7 +31,7 @@ else ...@@ -31,7 +31,7 @@ else
obj-$(CONFIG_SND_SOC_CV1835DAC) += cv1835dac.o obj-$(CONFIG_SND_SOC_CV1835DAC) += cv1835dac.o
endif endif
obj-$(CONFIG_SND_SOC_CV183x_DUMMY_CARD) += cv1835_dummy_codec.o #obj-$(CONFIG_SND_SOC_CV183x_DUMMY_CARD) += cv1835_dummy_codec.o
obj-$(CONFIG_SND_SOC_CV183x_DUMMY_CARD) += dummy_codec.o obj-$(CONFIG_SND_SOC_CV183x_DUMMY_CARD) += dummy_codec.o
obj-$(CONFIG_SND_SOC_CV182X_CV182XADC) += cv182x_cv182xadc.o obj-$(CONFIG_SND_SOC_CV182X_CV182XADC) += cv182x_cv182xadc.o
......
...@@ -592,8 +592,10 @@ static int cvi_i2s_hw_params(struct snd_pcm_substream *substream, ...@@ -592,8 +592,10 @@ static int cvi_i2s_hw_params(struct snd_pcm_substream *substream,
break; break;
} }
} else { } else {
if ((audio_clk == CVI_24576_MHZ) || (audio_clk == CVI_22579_MHZ)) if ((audio_clk == CVI_24576_MHZ) || (audio_clk == CVI_22579_MHZ)){
clk_ctrl1 |= MCLK_DIV(2); clk_ctrl1 |= MCLK_DIV(2);
mclk_div = 2;
}
else else
dev_err(dev->dev, "Get unexpected audio system clk=%d\n", audio_clk); dev_err(dev->dev, "Get unexpected audio system clk=%d\n", audio_clk);
} }
......
...@@ -22,23 +22,45 @@ static int cv1835_lt9611_hw_params(struct snd_pcm_substream *substream, ...@@ -22,23 +22,45 @@ static int cv1835_lt9611_hw_params(struct snd_pcm_substream *substream,
static int cv1835_lt9611_codec_init(struct snd_soc_pcm_runtime *rtd) static int cv1835_lt9611_codec_init(struct snd_soc_pcm_runtime *rtd)
{ {
// printk("%s\n", __func__); //printk(KERN_ERR "%s\n", __func__);
return 0; return 0;
} }
static struct snd_soc_ops cv1835_lt9611_ops = { static struct snd_soc_ops cv1835_lt9611_ops = {
.hw_params = cv1835_lt9611_hw_params, .hw_params = cv1835_lt9611_hw_params,
}; };
static struct snd_soc_dai_link_component lt9611_cpus = {
.name = "4120000.i2s",
.dai_name = "4120000.i2s",
};
static struct snd_soc_dai_link_component lt9611_codecs = {
.name = "dummy_codec",
.dai_name = "dummy_codec-aif",
};
static struct snd_soc_dai_link_component lt9611_platform = {
.name = "4120000.i2s",
.dai_name = "4120000.i2s",
};
static struct snd_soc_dai_link cv1835_lt9611_dai = { static struct snd_soc_dai_link cv1835_lt9611_dai = {
.name = "cv1835-lt9611", .name = "cv1835-lt9611",
.stream_name = "cv1835-lt9611", .stream_name = "cv1835-lt9611",
.codec_dai_name = "lt9611dai", .cpus = &lt9611_cpus,
.codec_name = "lt9611", .num_cpus = 1,
.codecs = &lt9611_codecs,
.num_codecs = 1,
.platforms = &lt9611_platform,
.num_platforms = 1,
.ops = &cv1835_lt9611_ops, .ops = &cv1835_lt9611_ops,
.init = cv1835_lt9611_codec_init, .init = cv1835_lt9611_codec_init,
.dai_fmt = SND_SOC_DAIFMT_I2S .dai_fmt = SND_SOC_DAIFMT_I2S
| SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_IB_NF
| SND_SOC_DAIFMT_CBS_CFS, | SND_SOC_DAIFMT_CBM_CFM,
}; };
static struct snd_soc_card cv1835_lt9611 = { static struct snd_soc_card cv1835_lt9611 = {
...@@ -59,6 +81,7 @@ static int cv1835_lt9611_probe(struct platform_device *pdev) ...@@ -59,6 +81,7 @@ static int cv1835_lt9611_probe(struct platform_device *pdev)
{ {
struct snd_soc_card *card; struct snd_soc_card *card;
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
int ret = 0;
//dev_dbg(&pdev->dev, "%s, dev name=%s\n", __func__, dev_name(&pdev->dev)); //dev_dbg(&pdev->dev, "%s, dev name=%s\n", __func__, dev_name(&pdev->dev));
// printk("%s, dev name=%s\n", __func__, dev_name(&pdev->dev)); // printk("%s, dev name=%s\n", __func__, dev_name(&pdev->dev));
...@@ -71,8 +94,8 @@ static int cv1835_lt9611_probe(struct platform_device *pdev) ...@@ -71,8 +94,8 @@ static int cv1835_lt9611_probe(struct platform_device *pdev)
of_property_read_string(np, "cvi,card_name", &card->name); of_property_read_string(np, "cvi,card_name", &card->name);
card->dev = &pdev->dev; card->dev = &pdev->dev;
of_property_read_string(np, "cvi,cpu_dai_name", &card->dai_link[0].cpu_dai_name); // of_property_read_string(np, "cvi,cpu_dai_name", &card->dai_link[0].cpu_dai_name);
of_property_read_string(np, "cvi,platform_name", &card->dai_link[0].platform_name); // of_property_read_string(np, "cvi,platform_name", &card->dai_link[0].platform_name);
platform_set_drvdata(pdev, card); platform_set_drvdata(pdev, card);
return devm_snd_soc_register_card(&pdev->dev, card); return devm_snd_soc_register_card(&pdev->dev, card);
......
...@@ -90,7 +90,7 @@ static int dummy_codec_remove(struct platform_device *dev) ...@@ -90,7 +90,7 @@ static int dummy_codec_remove(struct platform_device *dev)
static void dummy_codec_release(struct device *dev) static void dummy_codec_release(struct device *dev)
{ {
return 0; return;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment