Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion drivers/media/platform/rockchip/cif/capture.c
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,11 @@ static int rkcif_output_fmt_check(struct rkcif_stream *stream,
int ret = -EINVAL;

stream->rounding_bit = 0;
if (!input_fmt) {
v4l2_err(&stream->cifdev->v4l2_dev, "Input fmt is NULL\n");
return -EINVAL;
}

switch (input_fmt->mbus_code) {
case MEDIA_BUS_FMT_YUYV8_2X8:
case MEDIA_BUS_FMT_YVYU8_2X8:
Expand Down Expand Up @@ -982,7 +987,7 @@ const struct
cif_input_fmt *rkcif_get_input_fmt(struct rkcif_device *dev, struct v4l2_rect *rect,
u32 pad_id, struct csi_channel_info *csi_info)
{
struct v4l2_subdev_format fmt;
struct v4l2_subdev_format fmt = {0};
struct v4l2_subdev *sd = dev->terminal_sensor.sd;
struct rkmodule_channel_info ch_info = {0};
struct rkmodule_capture_info capture_info;
Expand Down Expand Up @@ -8805,6 +8810,11 @@ int rkcif_set_fmt(struct rkcif_stream *stream,
cif_fmt_in = rkcif_get_input_fmt(dev,
&input_rect, stream->id,
channel_info);
if (!cif_fmt_in) {
v4l2_err(&stream->cifdev->v4l2_dev,
"terminal sensor fmt invalid\n");
return -EINVAL;
}
stream->cif_fmt_in = cif_fmt_in;
} else {
v4l2_err(&stream->cifdev->v4l2_dev,
Expand Down
16 changes: 16 additions & 0 deletions drivers/mmc/core/block.c
Original file line number Diff line number Diff line change
Expand Up @@ -3010,6 +3010,11 @@ static void mmc_blk_remove_debugfs(struct mmc_card *card,

#endif /* CONFIG_DEBUG_FS */

#if IS_ENABLED(CONFIG_ROCKCHIP_MMC_VENDOR_STORAGE)
struct mmc_card *this_card;
EXPORT_SYMBOL(this_card);
#endif

static int mmc_blk_probe(struct mmc_card *card)
{
struct mmc_blk_data *md;
Expand Down Expand Up @@ -3040,6 +3045,11 @@ static int mmc_blk_probe(struct mmc_card *card)
if (ret)
goto out;

#if IS_ENABLED(CONFIG_ROCKCHIP_MMC_VENDOR_STORAGE)
if (mmc_card_mmc(card))
this_card = card;
#endif

/* Add two debugfs entries */
mmc_blk_add_debugfs(card, md);

Expand Down Expand Up @@ -3070,6 +3080,12 @@ static void mmc_blk_remove(struct mmc_card *card)
struct mmc_blk_data *md = dev_get_drvdata(&card->dev);

mmc_blk_remove_debugfs(card, md);

#if IS_ENABLED(CONFIG_ROCKCHIP_MMC_VENDOR_STORAGE)
if (mmc_card_mmc(card))
this_card = NULL;
#endif

mmc_blk_remove_parts(card, md);
pm_runtime_get_sync(&card->dev);
if (md->part_curr != md->part_type) {
Expand Down
3 changes: 3 additions & 0 deletions drivers/mmc/core/block.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
#define _MMC_CORE_BLOCK_H

struct mmc_queue;
struct mmc_card;
struct request;

extern struct mmc_card *this_card;

void mmc_blk_cqe_recovery(struct mmc_queue *mq);

enum mmc_issued;
Expand Down
1 change: 1 addition & 0 deletions drivers/mmc/host/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ obj-$(CONFIG_MMC_DW_HI3798CV200) += dw_mmc-hi3798cv200.o
obj-$(CONFIG_MMC_DW_K3) += dw_mmc-k3.o
obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o
obj-$(CONFIG_MMC_DW_ROCKCHIP) += dw_mmc-rockchip.o
obj-$(CONFIG_ROCKCHIP_MMC_VENDOR_STORAGE) += rk_sdmmc_ops.o
obj-$(CONFIG_MMC_DW_STARFIVE) += dw_mmc-starfive.o
obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o
obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o
Expand Down
208 changes: 208 additions & 0 deletions drivers/mmc/host/rk_sdmmc_ops.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
/*
* linux/drivers/mmchost/rkemmc_ops.c
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*/

#include <linux/mmc/core.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
#include <linux/slab.h>

#include <linux/scatterlist.h>
#include <linux/swap.h> /* For nr_free_buffer_pages() */
#include <linux/list.h>

#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include <linux/seq_file.h>
#include <linux/mutex.h>
#include <linux/miscdevice.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include "../core/block.h"
#include "../core/card.h"
#include "../core/core.h"
#include "../core/mmc_ops.h"
#include "rk_sdmmc_ops.h"

#define BLKSZ 512

enum emmc_area_type {
MMC_DATA_AREA_MAIN,
MMC_DATA_AREA_BOOT1,
MMC_DATA_AREA_BOOT2,
MMC_DATA_AREA_RPMB,
};

static int rk_emmc_set_areatype(enum emmc_area_type areatype)
{
int err;
u8 part_config;

part_config = this_card->ext_csd.part_config;
part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK;
part_config |= (u8)areatype;
err = mmc_switch(this_card, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_PART_CONFIG, part_config,
this_card->ext_csd.part_time);

return err;
}

/*
* Fill in the mmc_request structure given a set of transfer parameters.
*/
static void rk_emmc_prepare_mrq(struct mmc_request *mrq, struct scatterlist *sg,
unsigned sg_len, unsigned dev_addr, unsigned blocks, unsigned blksz, int write)
{
BUG_ON(!mrq || !mrq->cmd || !mrq->data || !mrq->stop);

if (blocks > 1) {
mrq->cmd->opcode = write ?
MMC_WRITE_MULTIPLE_BLOCK : MMC_READ_MULTIPLE_BLOCK;
} else {
mrq->cmd->opcode = write ?
MMC_WRITE_BLOCK : MMC_READ_SINGLE_BLOCK;
}

mrq->cmd->arg = dev_addr;
if (!mmc_card_blockaddr(this_card))
mrq->cmd->arg <<= 9;

mrq->cmd->flags = MMC_RSP_R1 | MMC_CMD_ADTC;

if (blocks == 1)
mrq->stop = NULL;
else {
mrq->stop->opcode = MMC_STOP_TRANSMISSION;
mrq->stop->arg = 0;
mrq->stop->flags = MMC_RSP_R1B | MMC_CMD_AC;
}

mrq->data->blksz = blksz;
mrq->data->blocks = blocks;
mrq->data->flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
mrq->data->sg = sg;
mrq->data->sg_len = sg_len;
mmc_set_data_timeout(mrq->data, this_card);
}

static int rk_emmc_busy(struct mmc_command *cmd)
{
return !(cmd->resp[0] & R1_READY_FOR_DATA) ||
(R1_CURRENT_STATE(cmd->resp[0]) == 7);
}

/*
* Wait for the card to finish the busy state
*/
static int rk_emmc_wait_busy(void)
{
int ret, busy;
struct mmc_command cmd = {0};

busy = 0;
do {
memset(&cmd, 0, sizeof(struct mmc_command));

cmd.opcode = MMC_SEND_STATUS;
cmd.arg = this_card->rca << 16;
cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;

ret = mmc_wait_for_cmd(this_card->host, &cmd, 0);
if (ret)
break;

if (!busy && rk_emmc_busy(&cmd)) {
busy = 1;
if (this_card->host->caps & MMC_CAP_WAIT_WHILE_BUSY)
pr_info("%s: Warning: Host did not "
"wait for busy state to end.\n",
mmc_hostname(this_card->host));
}
} while (rk_emmc_busy(&cmd));

return ret;
}

/*
* Transfer a single sector of kernel addressable data
*/
int rk_emmc_transfer(u8 *buffer, unsigned int addr, unsigned int datasz, int write)
{
int ret = 0;
enum emmc_area_type areatype;

struct mmc_request mrq = {0};
struct mmc_command cmd = {0};
struct mmc_command stop = {0};
struct mmc_data data = {0};

struct scatterlist sg;

if(!this_card)
return -EIO;

mrq.cmd = &cmd;
mrq.data = &data;
mrq.stop = &stop;

sg_init_one(&sg, buffer, datasz);

rk_emmc_prepare_mrq(&mrq, &sg, 1, addr, datasz / BLKSZ, BLKSZ, write);

pm_runtime_get_sync(&this_card->dev);
mmc_claim_host(this_card->host);

if (this_card->ext_csd.cmdq_en) {
ret = mmc_cmdq_disable(this_card);
if (ret)
goto exit;
}

areatype = (enum emmc_area_type)this_card->ext_csd.part_config
& EXT_CSD_PART_CONFIG_ACC_MASK;
if (areatype != MMC_DATA_AREA_MAIN) {
ret = rk_emmc_set_areatype(MMC_DATA_AREA_MAIN);
if (ret) {
pr_err("rk_emmc_set_areatype error!.\n");
goto exit;
}
}

mmc_wait_for_req(this_card->host, &mrq);

if (cmd.error){
ret = cmd.error;
goto exit;
}
if (data.error){
ret = data.error;
goto exit;
}

ret = rk_emmc_wait_busy();

if (areatype != MMC_DATA_AREA_MAIN) {
ret = rk_emmc_set_areatype(areatype);
if (ret)
pr_err("rk_emmc_set_areatype error!.\n");
}

exit:
if (this_card->reenable_cmdq && !this_card->ext_csd.cmdq_en)
mmc_cmdq_enable(this_card);

mmc_release_host(this_card->host);
pm_runtime_put(&this_card->dev);

return ret;
}
EXPORT_SYMBOL(rk_emmc_transfer);

MODULE_LICENSE("GPL");
11 changes: 11 additions & 0 deletions drivers/mmc/host/rk_sdmmc_ops.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2021 Rockchip Electronics Co., Ltd.
*/

#ifndef _RK_SDMMC_OPS_H_
#define _RK_SDMMC_OPS_H_

int rk_emmc_transfer(u8 *buffer, unsigned int addr, unsigned int datasz, int write);

#endif
2 changes: 2 additions & 0 deletions drivers/phy/rockchip/phy-rockchip-csi2-dphy.c
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,8 @@ static int csi2_dphy_get_set_fmt(struct v4l2_subdev *sd,
sensor = sd_to_sensor(dphy, sensor_sd);
if (!sensor)
return -ENODEV;
fmt->pad = 0;
fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE;
ret = v4l2_subdev_call(sensor_sd, pad, get_fmt, NULL, fmt);
if (!ret && fmt->pad == 0 && fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
sensor->format = fmt->format;
Expand Down
9 changes: 9 additions & 0 deletions drivers/soc/rockchip/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,15 @@ config ROCKCHIP_VENDOR_STORAGE
help
Say y here to enable rockchip vendor storage support.

config ROCKCHIP_MMC_VENDOR_STORAGE
tristate "Rockchip mmc vendor storage support"
depends on ROCKCHIP_VENDOR_STORAGE && MMC_BLOCK
help
Enable Rockchip vendor storage backed by an eMMC device. The driver
uses the MMC block card to read and write persistent vendor data and
exposes it through the Rockchip vendor storage interface. Select this
on systems that keep Rockchip vendor data in eMMC.

config ROCKCHIP_FLASH_VENDOR_STORAGE
tristate "Rockchip flash vendor storage support"
depends on ROCKCHIP_VENDOR_STORAGE && RK_FLASH
Expand Down
1 change: 1 addition & 0 deletions drivers/soc/rockchip/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ obj-$(CONFIG_ROCKCHIP_IOMUX) += iomux.o
obj-$(CONFIG_ROCKCHIP_DTPM) += dtpm.o
obj-$(CONFIG_ROCKCHIP_FIQ_DEBUGGER) += fiq_debugger/
obj-$(CONFIG_ROCKCHIP_VENDOR_STORAGE) += rk_vendor_storage.o
obj-$(CONFIG_ROCKCHIP_MMC_VENDOR_STORAGE) += sdmmc_vendor_storage.o
obj-$(CONFIG_ROCKCHIP_FLASH_VENDOR_STORAGE) += flash_vendor_storage.o
obj-$(CONFIG_ROCKCHIP_MTD_VENDOR_STORAGE) += mtd_vendor_storage.o
obj-$(CONFIG_ROCKCHIP_RAM_VENDOR_STORAGE) += ram_vendor_storage.o
Expand Down
Loading