drivers/intel/mipi_camera: Add camera power resource to SSDT
This change adds support function to parse entries in the devicetree to generate PowerResource entries for the MIPI camera. Change-Id: I31e198b50acf2c64035aff9cb054fbe3602dd83e Signed-off-by: Sugnan Prabhu S <sugnan.prabhu.s@intel.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/41624 Reviewed-by: Rizwan Qureshi <rizwan.qureshi@intel.com> Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
4f77f61d2d
commit
b087a940a2
|
@ -17,6 +17,7 @@
|
|||
#define DEFAULT_REMOTE_NAME "\\_SB.PCI0.CIO2"
|
||||
#define CIO2_PCI_DEV 0x14
|
||||
#define CIO2_PCI_FN 0x3
|
||||
#define POWER_RESOURCE_NAME "PRIC"
|
||||
|
||||
/*
|
||||
* This implementation assumes there is only 1 endpoint at each end of every data port. It also
|
||||
|
@ -435,6 +436,58 @@ static void camera_fill_vcm(const struct device *dev)
|
|||
acpi_dp_write(dsd);
|
||||
}
|
||||
|
||||
static void fill_power_res_sequence(struct drivers_intel_mipi_camera_config *config,
|
||||
struct operation_seq *seq)
|
||||
{
|
||||
unsigned int i;
|
||||
uint8_t index;
|
||||
uint8_t gpio_num;
|
||||
|
||||
for (i = 0; i < seq->ops_cnt; i++) {
|
||||
switch (seq->ops[i].type) {
|
||||
case IMGCLK:
|
||||
index = seq->ops[i].index;
|
||||
if (seq->ops[i].action == ENABLE) {
|
||||
acpigen_emit_namestring("MCON");
|
||||
acpigen_write_byte(config->clk_panel.clks[index].clknum);
|
||||
acpigen_write_byte(config->clk_panel.clks[index].freq);
|
||||
} else if (seq->ops[i].action == DISABLE) {
|
||||
acpigen_emit_namestring("MCOF");
|
||||
acpigen_write_byte(config->clk_panel.clks[index].clknum);
|
||||
} else {
|
||||
acpigen_write_debug_string("Unsupported clock action");
|
||||
printk(BIOS_ERR, "Unsupported clock action: %x\n",
|
||||
seq->ops[i].action);
|
||||
printk(BIOS_ERR, "OS camera driver will likely not work");
|
||||
}
|
||||
|
||||
break;
|
||||
case GPIO:
|
||||
index = seq->ops[i].index;
|
||||
gpio_num = config->gpio_panel.gpio[index].gpio_num;
|
||||
if (seq->ops[i].action == ENABLE) {
|
||||
acpigen_soc_set_tx_gpio(gpio_num);
|
||||
} else if (seq->ops[i].action == DISABLE) {
|
||||
acpigen_soc_clear_tx_gpio(gpio_num);
|
||||
} else {
|
||||
acpigen_write_debug_string("Unsupported GPIO action");
|
||||
printk(BIOS_ERR, "Unsupported GPIO action: %x\n",
|
||||
seq->ops[i].action);
|
||||
printk(BIOS_ERR, "OS camera driver will likely not work");
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
printk(BIOS_ERR, "Unsupported power operation: %x\n", seq->ops[i].type);
|
||||
printk(BIOS_ERR, "OS camera driver will likely not work");
|
||||
break;
|
||||
}
|
||||
|
||||
if (seq->ops[i].delay_ms)
|
||||
acpigen_write_sleep(seq->ops[i].delay_ms);
|
||||
}
|
||||
}
|
||||
|
||||
static void write_pci_camera_device(const struct device *dev)
|
||||
{
|
||||
struct drivers_intel_mipi_camera_config *config = dev->chip_info;
|
||||
|
@ -467,6 +520,40 @@ static void write_i2c_camera_device(const struct device *dev, const char *scope)
|
|||
|
||||
acpigen_write_device(acpi_device_name(dev));
|
||||
|
||||
/* add power resource */
|
||||
if (config->has_power_resource) {
|
||||
acpigen_write_power_res(POWER_RESOURCE_NAME, 0, 0, NULL, 0);
|
||||
acpigen_write_name_integer("STA", 0);
|
||||
acpigen_write_STA_ext("STA");
|
||||
|
||||
acpigen_write_method_serialized("_ON", 0);
|
||||
acpigen_write_if();
|
||||
acpigen_emit_byte(LEQUAL_OP);
|
||||
acpigen_emit_namestring("STA");
|
||||
acpigen_write_integer(0);
|
||||
|
||||
fill_power_res_sequence(config, &config->on_seq);
|
||||
|
||||
acpigen_write_store_op_to_namestr(1, "STA");
|
||||
acpigen_pop_len(); /* if */
|
||||
acpigen_pop_len(); /* _ON */
|
||||
|
||||
/* _OFF operations */
|
||||
acpigen_write_method_serialized("_OFF", 0);
|
||||
acpigen_write_if();
|
||||
acpigen_emit_byte(LEQUAL_OP);
|
||||
acpigen_emit_namestring("STA");
|
||||
acpigen_write_integer(1);
|
||||
|
||||
fill_power_res_sequence(config, &config->off_seq);
|
||||
|
||||
acpigen_write_store_op_to_namestr(0, "STA");
|
||||
acpigen_pop_len(); /* if */
|
||||
acpigen_pop_len(); /* _ON */
|
||||
|
||||
acpigen_pop_len(); /* Power Resource */
|
||||
}
|
||||
|
||||
if (config->device_type == INTEL_ACPI_CAMERA_SENSOR)
|
||||
acpigen_write_name_integer("_ADR", 0);
|
||||
|
||||
|
@ -519,6 +606,17 @@ static void write_camera_device_common(const struct device *dev)
|
|||
acpigen_write_name_integer("CAMD", config->device_type);
|
||||
}
|
||||
|
||||
if (config->pr0 || config->has_power_resource) {
|
||||
acpigen_write_name("_PR0");
|
||||
acpigen_write_package(1);
|
||||
if (config->pr0)
|
||||
acpigen_emit_namestring(config->pr0); /* External power resource */
|
||||
else
|
||||
acpigen_emit_namestring(POWER_RESOURCE_NAME);
|
||||
|
||||
acpigen_pop_len(); /* _PR0 */
|
||||
}
|
||||
|
||||
switch (config->device_type) {
|
||||
case INTEL_ACPI_CAMERA_CIO2:
|
||||
camera_fill_cio2(dev);
|
||||
|
|
|
@ -10,6 +10,18 @@
|
|||
#define MAX_PWDB_ENTRIES 12
|
||||
#define MAX_PORT_ENTRIES 4
|
||||
#define MAX_LINK_FREQ_ENTRIES 4
|
||||
#define MAX_CLK_CONFIGS 2
|
||||
#define MAX_GPIO_CONFIGS 4
|
||||
#define MAX_PWR_OPS 5
|
||||
|
||||
#define SEQ_OPS_CLK_ENABLE(ind, delay) \
|
||||
{ .type = IMGCLK, .index = (ind), .action = ENABLE, .delay_ms = (delay) }
|
||||
#define SEQ_OPS_CLK_DISABLE(ind, delay) \
|
||||
{ .type = IMGCLK, .index = (ind), .action = DISABLE, .delay_ms = (delay) }
|
||||
#define SEQ_OPS_GPIO_ENABLE(ind, delay) \
|
||||
{ .type = GPIO, .index = (ind), .action = ENABLE, .delay_ms = (delay) }
|
||||
#define SEQ_OPS_GPIO_DISABLE(ind, delay) \
|
||||
{ .type = GPIO, .index = (ind), .action = DISABLE, .delay_ms = (delay) }
|
||||
|
||||
enum camera_device_type {
|
||||
DEV_TYPE_SENSOR = 0,
|
||||
|
@ -57,6 +69,47 @@ enum intel_power_action_type {
|
|||
INTEL_ACPI_CAMERA_GPIO,
|
||||
};
|
||||
|
||||
enum ctrl_type {
|
||||
IMGCLK = 1,
|
||||
GPIO
|
||||
};
|
||||
|
||||
enum action_type {
|
||||
ENABLE = 1,
|
||||
DISABLE
|
||||
};
|
||||
|
||||
struct clk_config {
|
||||
/* IMGCLKOUT_x being used for a port */
|
||||
uint8_t clknum;
|
||||
/* frequency setting: 0:24Mhz, 1:19.2 Mhz */
|
||||
uint8_t freq;
|
||||
} __packed;
|
||||
|
||||
struct gpio_config {
|
||||
uint8_t gpio_num;
|
||||
} __packed;
|
||||
|
||||
struct clock_ctrl_panel {
|
||||
struct clk_config clks[MAX_CLK_CONFIGS];
|
||||
} __packed;
|
||||
|
||||
struct gpio_ctrl_panel {
|
||||
struct gpio_config gpio[MAX_GPIO_CONFIGS];
|
||||
} __packed;
|
||||
|
||||
struct operation_type {
|
||||
enum ctrl_type type;
|
||||
uint8_t index;
|
||||
enum action_type action;
|
||||
uint32_t delay_ms;
|
||||
} __packed;
|
||||
|
||||
struct operation_seq {
|
||||
struct operation_type ops[MAX_PWR_OPS];
|
||||
uint8_t ops_cnt;
|
||||
} __packed;
|
||||
|
||||
struct intel_ssdb {
|
||||
uint8_t version; /* Current version */
|
||||
uint8_t sensor_card_sku; /* CRD Board type */
|
||||
|
@ -122,6 +175,11 @@ struct intel_pwdb {
|
|||
} __packed;
|
||||
|
||||
struct drivers_intel_mipi_camera_config {
|
||||
struct clock_ctrl_panel clk_panel;
|
||||
struct gpio_ctrl_panel gpio_panel;
|
||||
struct operation_seq on_seq;
|
||||
struct operation_seq off_seq;
|
||||
|
||||
struct intel_ssdb ssdb;
|
||||
struct intel_pwdb pwdb[MAX_PWDB_ENTRIES];
|
||||
enum intel_camera_device_type device_type;
|
||||
|
@ -130,6 +188,7 @@ struct drivers_intel_mipi_camera_config {
|
|||
const char *acpi_name;
|
||||
const char *chip_name;
|
||||
unsigned int acpi_uid;
|
||||
const char *pr0;
|
||||
|
||||
/* Settings specific to CIO2 device */
|
||||
uint32_t cio2_num_ports;
|
||||
|
@ -163,6 +222,8 @@ struct drivers_intel_mipi_camera_config {
|
|||
|
||||
/* Settings specific to vcm */
|
||||
const char *vcm_compat;
|
||||
/* Does the device have a power resource entries */
|
||||
bool has_power_resource;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue