Merge remote-tracking branch 'origin/k1-dev' into k1-release

Change-Id: Ic932fc7f1d6112bda61ffcbe08dfa76eb785967d
This commit is contained in:
zhangmeng
2025-03-18 11:41:01 +08:00
20 changed files with 84918 additions and 84753 deletions

View File

@@ -12,6 +12,7 @@
#include <dt-bindings/dma/k1x-dmac.h>
#include <dt-bindings/thermal/thermal.h>
#include <dt-bindings/phy/phy.h>
#include <dt-bindings/input/input.h>
/ {
compatible = "spacemit,k1-x";
@@ -582,8 +583,9 @@
<0x0 0xc0000000 0x0 0x4280>,
<0x0 0xf0610000 0x0 0x20>,
<0x0 0xc0880000 0x0 0x2050>,
<0x0 0xc0888000 0x0 0x30>;
reg-names = "mpmu", "apmu", "apbc", "apbs", "ciu", "dciu", "ddrc", "apbc2", "rcpu", "rcpu2";
<0x0 0xc0888000 0x0 0x30>,
<0x0 0xc088c000 0x0 0x40>;
reg-names = "mpmu", "apmu", "apbc", "apbs", "ciu", "dciu", "ddrc", "apbc2", "rcpu", "rcpu2", "audpmu";
clocks = <&vctcxo_24>, <&vctcxo_3>, <&vctcxo_1>, <&pll1_2457p6_vco>,
<&clk_32k>;
clock-names = "vctcxo_24", "vctcxo_3", "vctcxo_1", "pll1_2457p6_vco",
@@ -986,8 +988,9 @@
<0 0xc0880000 0 0x200>;
ddr-remap-base = <0x30000000>;
esos-entry-point = <0x30300114>;
clocks = <&ccu CLK_AUDIO>;
clock-names = "core";
clocks = <&ccu CLK_AUDIO>, <&ccu CLK_AUDIO_APB>;
clock-names = "core", "apb";
apb-clk-rate = <122880000>;
resets = <&reset RESET_AUDIO_SYS>;
reset-names = "core_reset";
firmware-name = "esos.elf";
@@ -1850,7 +1853,6 @@
clocks = <&ccu CLK_RCPU_CAN>,<&ccu CLK_RCPU_CAN_BUS>;
clock-names = "per","ipg";
resets = <&reset RESET_RCPU_CAN>;
rcpu-can;
status = "disabled";
};
@@ -2531,6 +2533,19 @@
status = "disabled";
};
keypad: keypad@f0617000 {
compatible = "marvell,pxa27x-keypad";
reg = <0x0 0xf0617000 0x0 0x1000>,
<0x0 0xd428287c 0x0 0x4>;
interrupt-parent = <&intc>;
interrupts = <63>;
clocks = <&ccu CLK_SEC_KPC>;
clock-names = "kpc-clk";
resets = <&reset RESET_SEC_KPC>;
reset-names = "kpc-reset";
status = "disabled";
};
socinfo: socinfo@0 {
compatible = "spacemit,socinfo-k1x";
status = "disabled";

View File

@@ -11,7 +11,7 @@
#include "k1-x_opp_table.dtsi"
#include "k1-x_thermal_cooling.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
/ {
model = "spacemit k1-x LX-V10 board";
@@ -267,7 +267,19 @@
&i2c4 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c4_2>;
status = "disabled";
status = "okay";
hym8563: rtc@51 {
compatible = "haoyu,hym8563";
reg = <0x51>;
interrupt-parent = <&gpio>;
interrupts = <50 IRQ_TYPE_EDGE_FALLING>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_rtc>;
#clock-cells = <0>;
clock-output-names = "xin32k";
status = "okay";
};
};
&i2c7 {
@@ -562,6 +574,13 @@
K1X_PADCONF(GPIO_66, MUX_MODE0, (EDGE_FALL | PULL_DOWN | PAD_3V_DS2)) /* wifi edge detect */
>;
};
pinctrl_rtc: rtc_grp {
pinctrl-single,pins =<
K1X_PADCONF(GPIO_50, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_3V_DS2))
>;
};
};
&gpio{
@@ -618,7 +637,7 @@
spacemit,tx_delaycode = <0x5f>;
spacemit,rx_tuning_limit = <50>;
spacemit,sdh-freq = <204800000>;
status = "okay";
status = "disabled";
};
/* SDIO */

View File

@@ -116,7 +116,7 @@
};
chosen {
bootargs = "earlycon=sbi console=ttyS0,115200n8 loglevel=8 swiotlb=65536 rdinit=/init driver_async_probe=spacemit-hdmi-drv,i2c-spacemit-k1x,ri2c-spacemit-k1x,k1xccic,sdhci-spacemit,k1x-dwc-pcie,pxa2xx-uart";
bootargs = "earlycon=sbi console=ttyS0,115200n8 loglevel=8 swiotlb=65536 rdinit=/init driver_async_probe=spacemit-hdmi-drv,i2c-spacemit-k1x,ri2c-spacemit-k1x,k1xccic,sdhci-spacemit,k1x-dwc-pcie";
stdout-path = "serial0:115200n8";
};

View File

@@ -403,6 +403,52 @@
>;
};
pinctrl_keypad_0: keypad_0_grp {
pinctrl-single,pins = <
K1X_PADCONF(GPIO_123, MUX_MODE3, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)) /* keypad */
K1X_PADCONF(GPIO_124, MUX_MODE3, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2))
K1X_PADCONF(GPIO_125, MUX_MODE3, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2))
K1X_PADCONF(GPIO_126, MUX_MODE3, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2))
K1X_PADCONF(GPIO_127, MUX_MODE3, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2))
K1X_PADCONF(GPIO_77, MUX_MODE6, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2))
K1X_PADCONF(GPIO_78, MUX_MODE6, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2))
K1X_PADCONF(GPIO_79, MUX_MODE6, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2))
>;
};
pinctrl_keypad_1: keypad_1_grp {
pinctrl-single,pins = <
K1X_PADCONF(GPIO_118, MUX_MODE5, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)) /* keypad */
K1X_PADCONF(GPIO_119, MUX_MODE5, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2))
K1X_PADCONF(GPIO_120, MUX_MODE5, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2))
K1X_PADCONF(GPIO_121, MUX_MODE5, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2))
K1X_PADCONF(GPIO_122, MUX_MODE5, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2))
K1X_PADCONF(GPIO_48, MUX_MODE5, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2))
K1X_PADCONF(GPIO_49, MUX_MODE5, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2))
K1X_PADCONF(GPIO_50, MUX_MODE5, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2))
>;
};
pinctrl_direct_key_0: direct_key_0_grp {
pinctrl-single,pins = <
K1X_PADCONF(GPIO_63, MUX_MODE5, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) /* direct key */
K1X_PADCONF(GPIO_64, MUX_MODE5, (EDGE_NONE | PULL_UP | PAD_1V8_DS2))
K1X_PADCONF(GPIO_65, MUX_MODE5, (EDGE_NONE | PULL_UP | PAD_1V8_DS2))
K1X_PADCONF(GPIO_66, MUX_MODE5, (EDGE_NONE | PULL_UP | PAD_1V8_DS2))
K1X_PADCONF(GPIO_67, MUX_MODE5, (EDGE_NONE | PULL_UP | PAD_1V8_DS2))
>;
};
pinctrl_direct_key_1: direct_key_1_grp {
pinctrl-single,pins = <
K1X_PADCONF(GPIO_123, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) /* direct key */
K1X_PADCONF(GPIO_124, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2))
K1X_PADCONF(GPIO_125, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2))
K1X_PADCONF(GPIO_126, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2))
K1X_PADCONF(GPIO_127, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2))
>;
};
pinctrl_pwm0_0: pwm0_0_grp {
pinctrl-single,pins = <
K1X_PADCONF(MMC1_DAT3, MUX_MODE5, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) /* pwm0 */

View File

@@ -647,6 +647,7 @@ CONFIG_USB_USBNET=y
# CONFIG_USB_NET_AX88179_178A is not set
CONFIG_USB_NET_CDC_NCM=m
# CONFIG_USB_NET_NET1080 is not set
CONFIG_USB_NET_RNDIS_HOST=m
CONFIG_USB_NET_QMI_WWAN_F=m
CONFIG_USB_NET_QMI_WWAN=m
CONFIG_USB_NET_ASIX=m
@@ -676,6 +677,7 @@ CONFIG_AIC_IRQ_ACTIVE_RISING=y
CONFIG_AIC8800_WLAN_SUPPORT=m
CONFIG_INPUT_EVDEV=y
CONFIG_KEYBOARD_GPIO=y
CONFIG_KEYBOARD_PXA27x=y
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_GT9XX=y
@@ -925,6 +927,7 @@ CONFIG_USB_OTG=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_K1X=y
CONFIG_USB_ACM=m
CONFIG_USB_STORAGE=y
CONFIG_USB_UAS=y
CONFIG_USB_DWC3=y
@@ -1022,6 +1025,7 @@ CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_LEDS_TRIGGER_BACKLIGHT=y
CONFIG_LEDS_TRIGGER_NETDEV=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_HYM8563=y
CONFIG_RTC_DRV_SPT_PMIC=y
CONFIG_RTC_DRV_SA1100=y
CONFIG_DMADEVICES=y

View File

@@ -164,6 +164,7 @@ asmlinkage __visible __trap_section void do_trap_insn_illegal(struct pt_regs *re
bool handled;
#ifdef CONFIG_BIND_THREAD_TO_AICORES
u32 epc;
struct cpumask ai_affinity;
#endif
if (user_mode(regs)) {
@@ -175,10 +176,17 @@ asmlinkage __visible __trap_section void do_trap_insn_illegal(struct pt_regs *re
if ((epc & AI_OPCODE_MASK0) == AI_OPCODE_MATCH0 ||
(epc & AI_OPCODE_MASK1) == AI_OPCODE_MATCH1) {
local_irq_enable();
sched_setaffinity(current->pid, &ai_cpu_mask);
if(!sched_getaffinity(0, &ai_affinity)) {
cpumask_and(&ai_affinity, &ai_affinity, &ai_cpu_mask);
if(cpumask_weight(&ai_affinity) &&
!sched_setaffinity(0, &ai_affinity)) {
/* try to bind ai core successed */
local_irq_disable();
irqentry_exit_to_user_mode(regs);
return;
}
}
local_irq_disable();
irqentry_exit_to_user_mode(regs);
return;
}
#endif

View File

@@ -209,6 +209,10 @@ DEFINE_SPINLOCK(g_cru_lock);
#define RCPU2_PWM9_CLK_RST 0x24
/* end of RCPU2 register offset */
/* AUDPMU register offset */
#define AUDPMU_AUDIO_BUS_CLK_CTRL 0x38
/* end of AUDPMU register offset */
struct spacemit_k1x_clk k1x_clock_controller;
//apbs
@@ -1304,6 +1308,17 @@ static SPACEMIT_CCU_DIV_MUX_GATE(ruart1_clk, "ruart1_clk", ruart1_parent_names,
8, 11, 4, 2,
0x6, 0x6, 0x0,
0);
static SPACEMIT_CCU_DIV_FLAG(audio_apb_clk, "audio_apb_clk", "audio_clk",
BASE_TYPE_AUDPMU, AUDPMU_AUDIO_BUS_CLK_CTRL,
4, 3, CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_ALLOW_ZERO,
0);
static SPACEMIT_CCU_DIV_FLAG(audio_axi_clk, "audio_axi_clk", "audio_clk",
BASE_TYPE_AUDPMU, AUDPMU_AUDIO_BUS_CLK_CTRL,
0, 2, CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_ALLOW_ZERO,
0);
static struct clk_hw_onecell_data spacemit_k1x_hw_clks = {
.hws = {
[CLK_PLL2] = &pll2.common.hw,
@@ -1518,6 +1533,8 @@ static struct clk_hw_onecell_data spacemit_k1x_hw_clks = {
[CLK_RCPU2_PWM7] = &rpwm7_clk.common.hw,
[CLK_RCPU2_PWM8] = &rpwm8_clk.common.hw,
[CLK_RCPU2_PWM9] = &rpwm9_clk.common.hw,
[CLK_AUDIO_APB] = &audio_apb_clk.common.hw,
[CLK_AUDIO_AXI] = &audio_axi_clk.common.hw,
},
.num = CLK_MAX_NO,
};
@@ -1539,6 +1556,7 @@ static struct clk_hw_table bootup_enable_clk_table[] = {
{"pll2_d3", CLK_PLL2_D3},
{"apb_clk", CLK_APB},
{"pmua_aclk", CLK_PMUA_ACLK},
{"dma_clk", CLK_DMA},
};
void spacemit_clocks_enable(struct clk_hw_table *tbl, int tbl_size)
@@ -1615,6 +1633,9 @@ int ccu_common_init(struct clk_hw * hw, struct spacemit_k1x_clk *clk_info)
case BASE_TYPE_RCPU2:
common->base = clk_info->rcpu2_base;
break;
case BASE_TYPE_AUDPMU:
common->base = clk_info->audpmu_base;
break;
default:
common->base = clk_info->apbc_base;
break;
@@ -1739,6 +1760,12 @@ static void spacemit_k1x_ccu_probe(struct device_node *np)
pr_err("failed to map rcpu2 registers\n");
goto out;
}
clk_info->audpmu_base = of_iomap(np, 10);
if (!clk_info->audpmu_base) {
pr_err("failed to map audpmu registers\n");
goto out;
}
} else {
pr_err("not spacemit,k1x-clock\n");
goto out;

View File

@@ -22,6 +22,7 @@ enum ccu_base_type{
BASE_TYPE_APBC2 = 8,
BASE_TYPE_RCPU = 9,
BASE_TYPE_RCPU2 = 10,
BASE_TYPE_AUDPMU = 11,
};
enum {
@@ -63,6 +64,7 @@ struct spacemit_k1x_clk {
void __iomem *apbc2_base;
void __iomem *rcpu_base;
void __iomem *rcpu2_base;
void __iomem *audpmu_base;
};
struct clk_hw_table {

View File

@@ -278,7 +278,7 @@ unsigned long ccu_mix_calc_best_rate(struct clk_hw *hw, unsigned long rate, u32
struct ccu_div_config *div = mix->div? mix->div: NULL;
struct clk_hw *parent;
unsigned long parent_rate = 0, best_rate = 0;
u32 i, j, div_max;
u32 i, j, d, div_max;
for (i = 0; i < common->num_parents; i++) {
@@ -292,7 +292,18 @@ unsigned long ccu_mix_calc_best_rate(struct clk_hw *hw, unsigned long rate, u32
else
div_max = 1;
for(j = 1; j <= div_max; j++){
for (j = 1; j <= div_max; j++) {
if (div && div->flags & CLK_DIVIDER_POWER_OF_TWO) {
if (div->flags & CLK_DIVIDER_ALLOW_ZERO)
d = j - 1;
if (abs(parent_rate / BIT(d) - rate) < abs(best_rate - rate)) {
best_rate = DIV_ROUND_UP_ULL(parent_rate, BIT(d));
*mux_val = i;
*div_val = d;
}
continue;
}
if(abs(parent_rate/j - rate) < abs(best_rate - rate)){
best_rate = DIV_ROUND_UP_ULL(parent_rate, j);
*mux_val = i;

View File

@@ -157,6 +157,22 @@ struct ccu_mix {
} \
}
#define SPACEMIT_CCU_DIV_FLAG(_struct, _name, _parent, _base_type, _reg, \
_shift, _width, _div_flags, _flags) \
struct ccu_mix _struct = { \
.div = CCU_DIV_INIT(_shift, _width, NULL, _div_flags), \
.common = {\
.reg_ctrl = _reg, \
.base_type = _base_type, \
.name = _name, \
.num_parents = 1, \
.hw.init = CLK_HW_INIT(_name, \
_parent, \
&ccu_mix_ops, \
_flags | CLK_GET_RATE_NOCACHE), \
} \
}
#define SPACEMIT_CCU_GATE_FACTOR(_struct, _name, _parent, _base_type, _reg, \
_gate_mask, _val_enable, _val_disable, \
_div, _mul, _flags) \

View File

@@ -25,6 +25,7 @@
#include <linux/input/matrix_keypad.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/reset.h>
#include <linux/platform_data/keypad-pxa27x.h>
/*
@@ -86,6 +87,9 @@
#define KPAS_CP(n) ((n) & 0xf)
#define KPASMKP_MKC_MASK (0xff)
#ifdef CONFIG_SOC_SPACEMIT_K1X
#define KEYPAD_WAKE_CLEAR BIT(3)
#endif
#define keypad_readl(off) __raw_readl(keypad->mmio_base + (off))
#define keypad_writel(off, v) __raw_writel((v), keypad->mmio_base + (off))
@@ -97,8 +101,12 @@ struct pxa27x_keypad {
const struct pxa27x_keypad_platform_data *pdata;
struct clk *clk;
struct reset_control *resets;
struct input_dev *input_dev;
void __iomem *mmio_base;
#ifdef CONFIG_SOC_SPACEMIT_K1X
void __iomem *irq_base;
#endif
int irq;
@@ -576,7 +584,11 @@ static irqreturn_t pxa27x_keypad_irq_handler(int irq, void *dev_id)
{
struct pxa27x_keypad *keypad = dev_id;
unsigned long kpc = keypad_readl(KPC);
#ifdef CONFIG_SOC_SPCAEMIT_K1X
unsigned int irq_mask = readl(keypad->irq_base);
writel(irq_mask | KEYPAD_WAKE_CLEAR, keypad->irq_base);
#endif
clear_wakeup_event(keypad);
if (kpc & KPC_DI)
@@ -642,7 +654,8 @@ static int pxa27x_keypad_open(struct input_dev *dev)
{
struct pxa27x_keypad *keypad = input_get_drvdata(dev);
int ret;
/* Enable unit clock */
/* Enable unit clock&reset */
reset_control_deassert(keypad->resets);
ret = clk_prepare_enable(keypad->clk);
if (ret)
return ret;
@@ -656,8 +669,9 @@ static void pxa27x_keypad_close(struct input_dev *dev)
{
struct pxa27x_keypad *keypad = input_get_drvdata(dev);
/* Disable clock unit */
/* Disable clock&reset unit */
clk_disable_unprepare(keypad->clk);
reset_control_assert(keypad->resets);
}
static int pxa27x_keypad_suspend(struct device *dev)
@@ -743,13 +757,23 @@ static int pxa27x_keypad_probe(struct platform_device *pdev)
keypad->mmio_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(keypad->mmio_base))
return PTR_ERR(keypad->mmio_base);
#ifdef CONFIG_SOC_SPACEMIT_K1X
keypad->irq_base = devm_platform_ioremap_resource(pdev, 1);
if (IS_ERR(keypad->irq_base))
return PTR_ERR(keypad->irq_base);
#endif
keypad->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(keypad->clk)) {
dev_err(&pdev->dev, "failed to get keypad clock\n");
return PTR_ERR(keypad->clk);
}
keypad->resets = devm_reset_control_get_optional(&pdev->dev, NULL);
if(IS_ERR(keypad->resets)) {
dev_err(&pdev->dev, "failed to get keypad reset\n");
return PTR_ERR(keypad->resets);
}
input_dev->name = pdev->name;
input_dev->id.bustype = BUS_HOST;
input_dev->open = pxa27x_keypad_open;

View File

@@ -263,28 +263,8 @@ EXPORT_SYMBOL(plat_cam_v4l2_device_get);
int plat_cam_v4l2_device_put(struct v4l2_device *v4l2_dev)
{
#if 0
struct plat_cam_device *plat_cam_dev = to_plat_cam_dev(v4l2_dev);
struct platform_driver *plat_driver;
if (!v4l2_dev || !v4l2_dev->dev)
return -ENODEV;
plat_driver = to_platform_driver(v4l2_dev->dev->driver);
kref_put(&plat_cam_dev->ref, NULL);
if (kref_read(&plat_cam_dev->ref) == 1) {
plat_driver->remove = plat_cam_remove;
platform_driver_unregister(plat_driver);
kfree(plat_driver->driver.name);
kfree(plat_driver->driver.of_match_table);
kfree(plat_driver);
}
#else
if (g_dev)
kref_put(&g_dev->ref, NULL);
#endif
return 0;
}

View File

@@ -107,6 +107,9 @@ static int cam_sensor_power_set(struct cam_sensor_device *msnr_dev, u32 on)
if (!IS_ERR_OR_NULL(gpio_dvdden)) {
dvdd_powen_cnt++;
gpiod_direction_output(gpio_dvdden, 1);
msnr_dev->is_usedvdden = true;
cam_info("sensor%d dvdd_powen_cnt++, %d", msnr_dev->id, dvdd_powen_cnt);
}
if (!IS_ERR_OR_NULL(msnr_dev->afvdd)) {
regulator_set_voltage(msnr_dev->afvdd, 2800000, 2800000);
@@ -147,6 +150,9 @@ static int cam_sensor_power_set(struct cam_sensor_device *msnr_dev, u32 on)
dvdd_powen_cnt--;
if (dvdd_powen_cnt == 0)
gpiod_direction_output(gpio_dvdden, 0);
msnr_dev->is_usedvdden = false;
cam_info("sensor%d dvdd_powen_cnt--, %d", msnr_dev->id, dvdd_powen_cnt);
}
if (!IS_ERR_OR_NULL(msnr_dev->afvdd))
regulator_disable(msnr_dev->afvdd);
@@ -369,11 +375,14 @@ static int camsnr_set_gpio_enable(unsigned long arg, struct cam_sensor_device *m
if (enable) {
dvdd_powen_cnt++;
gpiod_direction_output(gpio_dvdden, enable);
msnr_dev->is_usedvdden = true;
} else {
dvdd_powen_cnt--;
if (dvdd_powen_cnt == 0)
gpiod_direction_output(gpio_dvdden, enable);
msnr_dev->is_usedvdden = false;
}
cam_info("sensor%d SENSOR_GPIO_DVDDEN, en:%d, dvdd_powen_cnt:%d", msnr_dev->id, enable, dvdd_powen_cnt);
}
break;
case SENSOR_GPIO_DCDCEN:
@@ -568,7 +577,7 @@ static int cam_sensor_write(struct cam_i2c_data *data,
}
ret = i2c_transfer(adapter, &msg, 1);
if (ret < 0) {
cam_err("%s: i2c transfer data fail", __func__);
cam_err("i2c transfer data fail, ret = %d", ret);
cam_sensor_i2c_dumpinfo(&msg, 1);
mutex_unlock(pcmd_mutex);
return ret;
@@ -1235,6 +1244,13 @@ static int camsnr_release(struct inode *inode, struct file *file)
clk_disable_unprepare(msnr_dev->mclk);
}
if (msnr_dev->is_usedvdden) {
msnr_dev->is_usedvdden = false;
dvdd_powen_cnt--;
if (dvdd_powen_cnt == 0)
gpiod_direction_output(gpio_dvdden, 0);
cam_info("sensor%d release, dvdd_powen_cnt:%d", msnr_dev->id, dvdd_powen_cnt);
}
if (msnr_dev->is_pinmulti && msnr_dev->req_pinmulti == true && use_pinmulti == true)
release_res_in_pinmulti_mode(msnr_dev);
@@ -1371,25 +1387,25 @@ static int camsnr_of_parse(struct cam_sensor_device *sensor)
sensor->afvdd = devm_regulator_get_exclusive(dev, "af_2v8");
if (IS_ERR(sensor->afvdd)) {
dev_warn(dev, "Failed to get regulator af_2v8\n");
cam_dbg("Failed to get regulator, guess sensor no need to control af_2v8\n");
sensor->afvdd = NULL;
}
sensor->avdd = devm_regulator_get_exclusive(dev, "avdd_2v8");
if (IS_ERR(sensor->avdd)) {
dev_warn(dev, "Failed to get regulator avdd_2v8\n");
cam_dbg("Failed to get regulator, guess sensor no need to control avdd_2v8\n");
sensor->avdd = NULL;
}
sensor->dovdd = devm_regulator_get_exclusive(dev, "dovdd_1v8");
if (IS_ERR(sensor->dovdd)) {
dev_warn(dev, "Failed to get regulator dovdd_1v8\n");
cam_dbg("Failed to get regulator, guess sensor no need to control dovdd_1v8\n");
sensor->dovdd = NULL;
}
sensor->dvdd = devm_regulator_get_exclusive(dev, "dvdd_1v2");
if (IS_ERR(sensor->dvdd)) {
dev_warn(dev, "Failed to get regulator dvdd_1v2\n");
cam_dbg("Failed to get regulator, guess sensor no need to control dvdd_1v2\n");
sensor->dvdd = NULL;
}
@@ -1406,6 +1422,7 @@ static int camsnr_of_parse(struct cam_sensor_device *sensor)
}
}
}
sensor->is_usedvdden = false;
sensor->dis_mclk = of_property_read_bool(of_node, "mclk-disable");
if (!sensor->dis_mclk) {
@@ -1431,6 +1448,7 @@ static int camsnr_of_parse(struct cam_sensor_device *sensor)
goto st_err;
}
} else {
cam_info("close soc mclk, guess sensor had mclk\n");
sensor->mclk = NULL;
}
/* pwdn-gpios */

View File

@@ -38,6 +38,7 @@ struct cam_sensor_device {
bool dis_mclk;
bool is_pinmulti;
bool req_pinmulti;
bool is_usedvdden;
struct pinctrl *pinctrl;
struct pinctrl_state *pinctrl_state;

View File

@@ -1174,9 +1174,7 @@ static int csi_subdev_video_s_stream(struct v4l2_subdev *sd, int enable)
else
csi2vc = CCIC_CSI2VC_VCDT;
if (enable) {
#ifndef CONFIG_SPACEMIT_XILINX_ZYNQMP
csi_subdev_core_s_power(sd, 1);
#endif
mipi_lane_num = csi->pad_fmts[CSI_PAD_IN].format.field & SPACEMIT_VI_PRI_DATA_MASK;
mipi_lane_num &= SPACEMIT_VI_MIPI_LANE_MASK;
cam_dbg("%s(%s) mipi lane num:%d", __func__, sc_subdev->name, mipi_lane_num);
@@ -4241,8 +4239,6 @@ static irqreturn_t fe_isp_dma_irq_handler(int irq, void *dev_id)
struct spm_camera_pipeline *sc_pipeline = NULL, *sc_pipelines[2] = {NULL, NULL};
struct media_pipeline *mpipe = NULL;
struct isp_pipeline_context *pipe_ctx = NULL;
struct fe_rawdump *rawdump = NULL;
struct media_pad *remote_pad = NULL;
struct frame_id *frame_id = NULL;
uint32_t frame_idx = 0;
struct spm_camera_vbuffer *pos = NULL;
@@ -4392,9 +4388,6 @@ static irqreturn_t fe_isp_dma_irq_handler(int irq, void *dev_id)
irq_status |= PIPE_ERR(1);
}
}
remote_pad = media_entity_remote_pad(&dma_ctx->vnode->pad);
BUG_ON(!remote_pad);
rawdump = media_entity_to_rawdump(remote_pad->entity);
if (irq_status) {
if (((irq_status & DMA_IRQ_START) && sc_pipeline && sc_pipeline->is_online_mode)
|| ((irq_status & DMA_IRQ_DONE) && sc_pipeline && !sc_pipeline->is_online_mode)) {
@@ -4468,14 +4461,6 @@ static irqreturn_t fe_isp_dma_irq_handler(int irq, void *dev_id)
pos->vb2_v4l2_buf.vb2_buf.timestamp = ktime_get_boottime_ns();
}
atomic_inc(&dma_ctx->busy_cnt);
if (rawdump && rawdump->rawdump_only) {
if (__spm_vdev_idle_list_empty(dma_ctx->vnode)) {
hw_isp_top_set_rdp_cfg_rdy(SC_BLOCK(isp_ctx->pipes[0]), rawdump->idx, 0);
hw_isp_top_set_rawdump_source(SC_BLOCK(isp_ctx->pipes[0]), rawdump->idx, INVALID_CH);
hw_isp_top_set_rdp_cfg_rdy(SC_BLOCK(isp_ctx->pipes[0]), rawdump->idx, 1);
pos->vb2_v4l2_buf.flags |= V4L2_BUF_FLAG_CLOSE_DOWN;
}
}
}
}
}

View File

@@ -31,16 +31,10 @@
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/kthread.h>
#include <uapi/linux/sched/types.h>
#include "flexcan.h"
#ifdef CONFIG_SOC_SPACEMIT_K1X
#include <linux/rpmsg.h>
#define STARTUP_MSG "startup"
#define IRQUP_MSG "irqon"
static unsigned long long private_data[1];
#define R_DRV_NAME "r_flexcan"
#endif
#define DRV_NAME "flexcan"
/* 8 for RX fifo and 2 error handling */
@@ -298,16 +292,7 @@ struct flexcan_regs {
);
};
#ifdef CONFIG_SOC_SPACEMIT_K1X
struct instance_data {
struct rpmsg_device *rpdev;
struct net_device *dev;
};
#endif
#ifndef CONFIG_SOC_SPACEMIT_K1X
static_assert(sizeof(struct flexcan_regs) == 0x4 * 18 + 0xfb8);
#endif
static const struct flexcan_devtype_data fsl_mcf5441x_devtype_data = {
.quirks = FLEXCAN_QUIRK_BROKEN_PERR_STATE |
@@ -1808,53 +1793,23 @@ static int flexcan_open(struct net_device *dev)
can_rx_offload_enable(&priv->offload);
#ifdef CONFIG_SOC_SPACEMIT_K1X
if(dev->irq != -1) {
err = request_irq(dev->irq, flexcan_irq, IRQF_SHARED, dev->name, dev);
if (dev->irq > 0) {
err = request_irq(dev->irq, flexcan_irq, IRQF_SHARED | IRQF_NO_THREAD, dev->name, dev);
if (err)
goto out_can_rx_offload_disable;
if (priv->devtype_data.quirks & FLEXCAN_QUIRK_NR_IRQ_3) {
err = request_irq(priv->irq_boff,
flexcan_irq, IRQF_SHARED, dev->name, dev);
flexcan_irq, IRQF_SHARED, dev->name, dev);
if (err)
goto out_free_irq;
err = request_irq(priv->irq_err,
flexcan_irq, IRQF_SHARED, dev->name, dev);
flexcan_irq, IRQF_SHARED, dev->name, dev);
if (err)
goto out_free_irq_boff;
}
} else {
struct instance_data *idata = (struct instance_data*)private_data[0];
struct rpmsg_device *rpdev;
int ret;
rpdev = idata->rpdev;
idata->dev = dev;
ret = rpmsg_send(rpdev->ept, STARTUP_MSG, strlen(STARTUP_MSG));
if (ret) {
dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret);
return ret;
}
}
#else
err = request_irq(dev->irq, flexcan_irq, IRQF_SHARED, dev->name, dev);
if (err)
goto out_can_rx_offload_disable;
if (priv->devtype_data.quirks & FLEXCAN_QUIRK_NR_IRQ_3) {
err = request_irq(priv->irq_boff,
flexcan_irq, IRQF_SHARED, dev->name, dev);
if (err)
goto out_free_irq;
err = request_irq(priv->irq_err,
flexcan_irq, IRQF_SHARED, dev->name, dev);
if (err)
goto out_free_irq_boff;
}
#endif
flexcan_chip_interrupts_enable(dev);
@@ -2133,19 +2088,12 @@ static const struct of_device_id flexcan_of_match[] = {
{ .compatible = "fsl,lx2160ar1-flexcan", .data = &fsl_lx2160a_r1_devtype_data, },
#ifdef CONFIG_SOC_SPACEMIT_K1X
{ .compatible = "spacemit,k1x-flexcan", .data = &spacemit_k1x_devtype_data, },
{ .compatible = "spacemit,k1x-r-flexcan", .data = &spacemit_k1x_devtype_data, },
#endif
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, flexcan_of_match);
#ifdef CONFIG_SOC_SPACEMIT_K1X
static const struct of_device_id r_flexcan_of_match[] = {
{ .compatible = "spacemit,k1x-r-flexcan", .data = &spacemit_k1x_devtype_data, },
{ },
};
MODULE_DEVICE_TABLE(of, r_flexcan_of_match);
#endif
static const struct platform_device_id flexcan_id_table[] = {
{
.name = "flexcan-mcf5441x",
@@ -2156,6 +2104,58 @@ static const struct platform_device_id flexcan_id_table[] = {
};
MODULE_DEVICE_TABLE(platform, flexcan_id_table);
static void flexcan_box_callback(struct mbox_client *cl, void *data)
{
struct net_device *dev;
struct flexcan_mox *mb = container_of(cl, struct flexcan_mox, client);
dev = dev_get_drvdata(cl->dev);
flexcan_irq(0, dev);
complete(&mb->mb_comp);
}
static int __process_theread(void *arg)
{
int ret;
char c = 'c';
struct mbox_client *cl = arg;
struct flexcan_mox *mb = container_of(cl, struct flexcan_mox, client);
struct sched_param param = {.sched_priority = 0 };
mb->kthread_running = true;
ret = sched_setscheduler(current, SCHED_FIFO, &param);
set_freezable();
do {
try_to_freeze();
ret = wait_for_completion_timeout(&mb->mb_comp, 10);
/* send message to the other hand */
if (ret)
mbox_send_message(mb->chan, &c);
} while (!kthread_should_stop());
mb->kthread_running = false;
return 0;
}
#define CAN_MBOX0_ID 0
static struct flexcan_mox flexcan_mbox[] = {
{
.name = "mcan0",
.box_id = CAN_MBOX0_ID,
.client = {
.rx_callback = flexcan_box_callback,
.tx_block = true,
},
},
};
static int flexcan_probe(struct platform_device *pdev)
{
const struct of_device_id *of_id;
@@ -2228,25 +2228,6 @@ static int flexcan_probe(struct platform_device *pdev)
return PTR_ERR(reset);
}
#ifdef CONFIG_SOC_SPACEMIT_K1X
if (!of_get_property(pdev->dev.of_node, "rcpu-can", NULL)) {
irq = platform_get_irq(pdev, 0);
if (irq <= 0)
return -ENODEV;
} else {
irq = -1;
of_id = of_match_device(r_flexcan_of_match, &pdev->dev);
if (of_id)
devtype_data = of_id->data;
else
return -ENODEV;
}
#else
irq = platform_get_irq(pdev, 0);
if (irq <= 0)
return -ENODEV;
#endif
regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(regs))
return PTR_ERR(regs);
@@ -2254,10 +2235,6 @@ static int flexcan_probe(struct platform_device *pdev)
of_id = of_match_device(flexcan_of_match, &pdev->dev);
if (of_id)
devtype_data = of_id->data;
else if (of_match_device(r_flexcan_of_match, &pdev->dev)) {
of_id = of_match_device(r_flexcan_of_match, &pdev->dev);
devtype_data = of_id->data;
}
else if (platform_get_device_id(pdev)->driver_data)
devtype_data = (struct flexcan_devtype_data *)
platform_get_device_id(pdev)->driver_data;
@@ -2294,6 +2271,7 @@ static int flexcan_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, dev);
SET_NETDEV_DEV(dev, &pdev->dev);
irq = platform_get_irq(pdev, 0);
dev->netdev_ops = &flexcan_netdev_ops;
dev->ethtool_ops = &flexcan_ethtool_ops;
dev->irq = irq;
@@ -2302,6 +2280,22 @@ static int flexcan_probe(struct platform_device *pdev)
priv = netdev_priv(dev);
priv->devtype_data = *devtype_data;
if (irq <= 0) {
/* request the mailbox driver */
priv->fmx = flexcan_mbox;
priv->fmx->client.dev = &pdev->dev;
priv->fmx->chan = mbox_request_channel_byname(&priv->fmx->client,
priv->fmx->name);
if (IS_ERR(priv->fmx->chan)) {
dev_err(&pdev->dev, "Failed to request mbox channel\n");
return -EINVAL;
}
init_completion(&priv->fmx->mb_comp);
priv->fmx->mb_thread = kthread_run(__process_theread, (void *)&flexcan_mbox->client,
priv->fmx->name);
}
if (of_property_read_bool(pdev->dev.of_node, "big-endian") ||
priv->devtype_data.quirks & FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN) {
priv->read = flexcan_read_be;
@@ -2528,78 +2522,6 @@ static struct platform_driver flexcan_driver = {
};
module_platform_driver(flexcan_driver);
#ifdef CONFIG_SOC_SPACEMIT_K1X
static struct platform_driver r_flexcan_driver = {
.driver = {
.name = R_DRV_NAME,
.pm = &flexcan_pm_ops,
.of_match_table = r_flexcan_of_match,
},
.probe = flexcan_probe,
.remove_new = flexcan_remove,
.id_table = flexcan_id_table,
};
static struct rpmsg_device_id rpmsg_driver_rcan_id_table[] = {
{ .name = "can-service", .driver_data = 0 },
{ },
};
MODULE_DEVICE_TABLE(rpmsg, rpmsg_driver_rcan_id_table);
static int rpmsg_rcan_client_cb(struct rpmsg_device *rpdev, void *data,
int len, void *priv, u32 src)
{
struct instance_data *idata = dev_get_drvdata(&rpdev->dev);
struct net_device *dev = idata->dev;
int ret;
flexcan_irq(0, (void*)dev);
ret = rpmsg_send(rpdev->ept, IRQUP_MSG, strlen(IRQUP_MSG));
if (ret) {
dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret);
return ret;
}
return 0;
}
static int rpmsg_rcan_client_probe(struct rpmsg_device *rpdev)
{
struct instance_data *idata;
dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
rpdev->src, rpdev->dst);
idata = devm_kzalloc(&rpdev->dev, sizeof(*idata), GFP_KERNEL);
if (!idata)
return -ENOMEM;
dev_set_drvdata(&rpdev->dev, idata);
idata->rpdev = rpdev;
private_data[0] = (unsigned long long)idata;
platform_driver_register(&r_flexcan_driver);
return 0;
}
static void rpmsg_rcan_client_remove(struct rpmsg_device *rpdev)
{
dev_info(&rpdev->dev, "rpmsg rcan client driver is removed\n");
platform_driver_unregister(&flexcan_driver);
}
static struct rpmsg_driver rpmsg_rcan_client = {
.drv.name = KBUILD_MODNAME,
.id_table = rpmsg_driver_rcan_id_table,
.probe = rpmsg_rcan_client_probe,
.callback = rpmsg_rcan_client_cb,
.remove = rpmsg_rcan_client_remove,
};
module_rpmsg_driver(rpmsg_rcan_client);
#endif
MODULE_AUTHOR("Sascha Hauer <kernel@pengutronix.de>, "
"Marc Kleine-Budde <kernel@pengutronix.de>");
MODULE_LICENSE("GPL v2");

View File

@@ -15,6 +15,9 @@
#define _FLEXCAN_H
#include <linux/can/rx-offload.h>
#include <linux/mailbox_controller.h>
#include <linux/mailbox_client.h>
#include <linux/sched.h>
/* FLEXCAN hardware feature flags
*
@@ -79,6 +82,16 @@ struct flexcan_stop_mode {
u8 req_bit;
};
struct flexcan_mox {
const char name[10];
struct mbox_chan *chan;
struct mbox_client client;
struct completion mb_comp;
struct task_struct *mb_thread;
bool kthread_running;
int box_id;
};
struct flexcan_priv {
struct can_priv can;
struct can_rx_offload offload;
@@ -113,6 +126,9 @@ struct flexcan_priv {
/* Read and Write APIs */
u32 (*read)(void __iomem *addr);
void (*write)(u32 val, void __iomem *addr);
/* can mailbox */
struct flexcan_mox *fmx;
};
extern const struct ethtool_ops flexcan_ethtool_ops;

File diff suppressed because it is too large Load Diff

View File

@@ -77,8 +77,9 @@ struct spacemit_mbox {
struct spacemit_rproc {
struct device *dev;
unsigned int apb_clk_rate, apb_clk_rate_default;
struct reset_control *core_rst;
struct clk *core_clk;
struct clk *core_clk, *apb_clk;
unsigned int ddr_remap_base;
void __iomem *base[MAX_MEM_BASE];
struct spacemit_mbox *mb;
@@ -144,6 +145,11 @@ static int spacemit_rproc_prepare(struct rproc *rproc)
/* enable the power-switch and the clk */
pm_runtime_get_sync(priv->dev);
priv->apb_clk_rate_default = clk_get_rate(priv->apb_clk);
/* set apb clk rate */
clk_set_rate(priv->apb_clk, priv->apb_clk_rate);
/* Register associated reserved memory regions */
of_phandle_iterator_init(&it, np, "memory-region", NULL, 0);
while (of_phandle_iterator_next(&it) == 0) {
@@ -438,6 +444,8 @@ static int rproc_platform_late(void)
/* wait the rcpu enter wfi */
mdelay(10);
clk_set_rate(srproc->apb_clk, srproc->apb_clk_rate_default);
genpd = pd_to_genpd(pdev->dev.pm_domain);
pdev->dev.power.wakeup_path = false;
@@ -467,7 +475,7 @@ static int rproc_platform_late(void)
/* close the clk & power-switch */
genpd->domain.ops.suspend_noirq(&pdev->dev);
return 0;
}
@@ -493,6 +501,9 @@ static void rproc_platfrom_wake(void)
/* enable the clk & power-switch */
genpd->domain.ops.resume_noirq(&pdev->dev);
/* set apb clk rate */
clk_set_rate(srproc->apb_clk, srproc->apb_clk_rate);
/* enable ipc2ap clk & reset--> rcpu side */
writel(0xff, srproc->base[BOOTC_MEM_BASE_OFFSET] + ESOS_AON_PER_CLK_RST_CTL_REG);
@@ -669,6 +680,22 @@ static int spacemit_rproc_probe(struct platform_device *pdev)
goto err_0;
}
priv->apb_clk = devm_clk_get(dev, "apb");
if (IS_ERR(priv->apb_clk)) {
ret = PTR_ERR(priv->apb_clk);
dev_err(dev, "failed to acquire rpoc apb clk\n");
ret = -EINVAL;
goto err_0;
}
/* get the apb clk rate */
ret = of_property_read_u32(np, "apb-clk-rate", &priv->apb_clk_rate);
if (ret) {
dev_err(dev, "failed to acquire rpoc apb clk rate\n");
ret = -EINVAL;
goto err_0;
}
/* get the ddr-remap base */
ret = of_property_read_u32(pdev->dev.of_node, "ddr-remap-base", &priv->ddr_remap_base);

View File

@@ -225,5 +225,8 @@
#define CLK_RCPU2_PWM8 210
#define CLK_RCPU2_PWM9 211
#define CLK_MAX_NO 212
#define CLK_AUDIO_APB 212
#define CLK_AUDIO_AXI 213
#define CLK_MAX_NO 214
#endif /* _DT_BINDINGS_CLK_SPACEMIT_K1X_H_ */